Server IP : 213.176.29.180  /  Your IP : 3.22.71.149
Web Server : Apache
System : Linux 213.176.29.180.hostiran.name 4.18.0-553.22.1.el8_10.x86_64 #1 SMP Tue Sep 24 05:16:59 EDT 2024 x86_64
User : webtaragh ( 1001)
PHP Version : 8.3.14
Disable Function : NONE
MySQL : OFF  |  cURL : ON  |  WGET : ON  |  Perl : ON  |  Python : ON
Directory (0750) :  /home/webtaragh/public_html/

[  Home  ][  C0mmand  ][  Upload File  ]

Current File : /home/webtaragh/public_html/symfony.zip
PKϤ$Z�D	�KKpolyfill-php81/README.mdnu�[���Symfony Polyfill / Php81
========================

This component provides features added to PHP 8.1 core:

- [`array_is_list`](https://php.net/array_is_list)
- [`enum_exists`](https://php.net/enum-exists)
- [`MYSQLI_REFRESH_REPLICA`](https://php.net/mysqli.constants#constantmysqli-refresh-replica) constant
- [`ReturnTypeWillChange`](https://wiki.php.net/rfc/internal_method_return_types)

More information can be found in the
[main Polyfill README](https://github.com/symfony/polyfill/blob/main/README.md).

License
=======

This library is released under the [MIT license](LICENSE).
PKϤ$Z�]��7polyfill-php81/Resources/stubs/ReturnTypeWillChange.phpnu�[���<?php

if (\PHP_VERSION_ID < 80100) {
    #[Attribute(Attribute::TARGET_METHOD)]
    final class ReturnTypeWillChange
    {
        public function __construct()
        {
        }
    }
}
PKϤ$Z<P��polyfill-php81/bootstrap.phpnu�[���<?php

/*
 * This file is part of the Symfony package.
 *
 * (c) Fabien Potencier <fabien@symfony.com>
 *
 * For the full copyright and license information, please view the LICENSE
 * file that was distributed with this source code.
 */

use Symfony\Polyfill\Php81 as p;

if (\PHP_VERSION_ID >= 80100) {
    return;
}

if (defined('MYSQLI_REFRESH_SLAVE') && !defined('MYSQLI_REFRESH_REPLICA')) {
    define('MYSQLI_REFRESH_REPLICA', 64);
}

if (!function_exists('array_is_list')) {
    function array_is_list(array $array): bool { return p\Php81::array_is_list($array); }
}

if (!function_exists('enum_exists')) {
    function enum_exists(string $enum, bool $autoload = true): bool { return $autoload && class_exists($enum) && false; }
}
PKϤ$Z�ߐp$$polyfill-php81/LICENSEnu�[���Copyright (c) 2021 Fabien Potencier

Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is furnished
to do so, subject to the following conditions:

The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.

THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
THE SOFTWARE.
PKϤ$Z��$��polyfill-php81/Php81.phpnu�[���<?php

/*
 * This file is part of the Symfony package.
 *
 * (c) Fabien Potencier <fabien@symfony.com>
 *
 * For the full copyright and license information, please view the LICENSE
 * file that was distributed with this source code.
 */

namespace Symfony\Polyfill\Php81;

/**
 * @author Nicolas Grekas <p@tchwork.com>
 *
 * @internal
 */
final class Php81
{
    public static function array_is_list(array $array): bool
    {
        if ([] === $array || $array === array_values($array)) {
            return true;
        }

        $nextKey = -1;

        foreach ($array as $k => $v) {
            if ($k !== ++$nextKey) {
                return false;
            }
        }

        return true;
    }
}
PKϤ$Z�&���t�tpolyfill-intl-idn/Idn.phpnu�[���<?php

/*
 * This file is part of the Symfony package.
 *
 * (c) Fabien Potencier <fabien@symfony.com> and Trevor Rowbotham <trevor.rowbotham@pm.me>
 *
 * For the full copyright and license information, please view the LICENSE
 * file that was distributed with this source code.
 */

namespace Symfony\Polyfill\Intl\Idn;

use Exception;
use Normalizer;
use Symfony\Polyfill\Intl\Idn\Resources\unidata\DisallowedRanges;
use Symfony\Polyfill\Intl\Idn\Resources\unidata\Regex;

/**
 * @see https://www.unicode.org/reports/tr46/
 *
 * @internal
 */
final class Idn
{
    const ERROR_EMPTY_LABEL = 1;
    const ERROR_LABEL_TOO_LONG = 2;
    const ERROR_DOMAIN_NAME_TOO_LONG = 4;
    const ERROR_LEADING_HYPHEN = 8;
    const ERROR_TRAILING_HYPHEN = 0x10;
    const ERROR_HYPHEN_3_4 = 0x20;
    const ERROR_LEADING_COMBINING_MARK = 0x40;
    const ERROR_DISALLOWED = 0x80;
    const ERROR_PUNYCODE = 0x100;
    const ERROR_LABEL_HAS_DOT = 0x200;
    const ERROR_INVALID_ACE_LABEL = 0x400;
    const ERROR_BIDI = 0x800;
    const ERROR_CONTEXTJ = 0x1000;
    const ERROR_CONTEXTO_PUNCTUATION = 0x2000;
    const ERROR_CONTEXTO_DIGITS = 0x4000;

    const INTL_IDNA_VARIANT_2003 = 0;
    const INTL_IDNA_VARIANT_UTS46 = 1;

    const MAX_DOMAIN_SIZE = 253;
    const MAX_LABEL_SIZE = 63;

    const BASE = 36;
    const TMIN = 1;
    const TMAX = 26;
    const SKEW = 38;
    const DAMP = 700;
    const INITIAL_BIAS = 72;
    const INITIAL_N = 128;
    const DELIMITER = '-';
    const MAX_INT = 2147483647;

    /**
     * Contains the numeric value of a basic code point (for use in representing integers) in the
     * range 0 to BASE-1, or -1 if b is does not represent a value.
     *
     * @var array<int, int>
     */
    private static $basicToDigit = array(
        -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
        -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,

        -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
        26, 27, 28, 29, 30, 31, 32, 33, 34, 35, -1, -1, -1, -1, -1, -1,

        -1,  0,  1,  2,  3,  4,  5,  6,  7,  8,  9, 10, 11, 12, 13, 14,
        15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, -1, -1, -1, -1, -1,

        -1,  0,  1,  2,  3,  4,  5,  6,  7,  8,  9, 10, 11, 12, 13, 14,
        15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, -1, -1, -1, -1, -1,

        -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
        -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,

        -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
        -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,

        -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
        -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,

        -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
        -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
    );

    /**
     * @var array<int, int>
     */
    private static $virama;

    /**
     * @var array<int, string>
     */
    private static $mapped;

    /**
     * @var array<int, bool>
     */
    private static $ignored;

    /**
     * @var array<int, string>
     */
    private static $deviation;

    /**
     * @var array<int, bool>
     */
    private static $disallowed;

    /**
     * @var array<int, string>
     */
    private static $disallowed_STD3_mapped;

    /**
     * @var array<int, bool>
     */
    private static $disallowed_STD3_valid;

    /**
     * @var bool
     */
    private static $mappingTableLoaded = false;

    /**
     * @see https://www.unicode.org/reports/tr46/#ToASCII
     *
     * @param string $domainName
     * @param int    $options
     * @param int    $variant
     * @param array  $idna_info
     *
     * @return string|false
     */
    public static function idn_to_ascii($domainName, $options = IDNA_DEFAULT, $variant = self::INTL_IDNA_VARIANT_UTS46, &$idna_info = array())
    {
        if (\PHP_VERSION_ID >= 70200 && self::INTL_IDNA_VARIANT_2003 === $variant) {
            @trigger_error('idn_to_ascii(): INTL_IDNA_VARIANT_2003 is deprecated', E_USER_DEPRECATED);
        }

        $options = array(
            'CheckHyphens' => true,
            'CheckBidi' => self::INTL_IDNA_VARIANT_2003 === $variant || 0 !== ($options & \IDNA_CHECK_BIDI),
            'CheckJoiners' => self::INTL_IDNA_VARIANT_UTS46 === $variant && 0 !== ($options & \IDNA_CHECK_CONTEXTJ),
            'UseSTD3ASCIIRules' => 0 !== ($options & \IDNA_USE_STD3_RULES),
            'Transitional_Processing' => self::INTL_IDNA_VARIANT_2003 === $variant || 0 === ($options & \IDNA_NONTRANSITIONAL_TO_ASCII),
            'VerifyDnsLength' => true,
        );
        $info = new Info();
        $labels = self::process((string) $domainName, $options, $info);

        foreach ($labels as $i => $label) {
            // Only convert labels to punycode that contain non-ASCII code points
            if (1 === preg_match('/[^\x00-\x7F]/', $label)) {
                try {
                    $label = 'xn--'.self::punycodeEncode($label);
                } catch (Exception $e) {
                    $info->errors |= self::ERROR_PUNYCODE;
                }

                $labels[$i] = $label;
            }
        }

        if ($options['VerifyDnsLength']) {
            self::validateDomainAndLabelLength($labels, $info);
        }

        $idna_info = array(
            'result' => implode('.', $labels),
            'isTransitionalDifferent' => $info->transitionalDifferent,
            'errors' => $info->errors,
        );

        return 0 === $info->errors ? $idna_info['result'] : false;
    }

    /**
     * @see https://www.unicode.org/reports/tr46/#ToUnicode
     *
     * @param string $domainName
     * @param int    $options
     * @param int    $variant
     * @param array  $idna_info
     *
     * @return string|false
     */
    public static function idn_to_utf8($domainName, $options = IDNA_DEFAULT, $variant = self::INTL_IDNA_VARIANT_UTS46, &$idna_info = array())
    {
        if (\PHP_VERSION_ID >= 70200 && self::INTL_IDNA_VARIANT_2003 === $variant) {
            @trigger_error('idn_to_utf8(): INTL_IDNA_VARIANT_2003 is deprecated', E_USER_DEPRECATED);
        }

        $info = new Info();
        $labels = self::process((string) $domainName, array(
            'CheckHyphens' => true,
            'CheckBidi' => self::INTL_IDNA_VARIANT_2003 === $variant || 0 !== ($options & \IDNA_CHECK_BIDI),
            'CheckJoiners' => self::INTL_IDNA_VARIANT_UTS46 === $variant && 0 !== ($options & \IDNA_CHECK_CONTEXTJ),
            'UseSTD3ASCIIRules' => 0 !== ($options & \IDNA_USE_STD3_RULES),
            'Transitional_Processing' => self::INTL_IDNA_VARIANT_2003 === $variant || 0 === ($options & \IDNA_NONTRANSITIONAL_TO_UNICODE),
        ), $info);
        $idna_info = array(
            'result' => implode('.', $labels),
            'isTransitionalDifferent' => $info->transitionalDifferent,
            'errors' => $info->errors,
        );

        return 0 === $info->errors ? $idna_info['result'] : false;
    }

    /**
     * @param string $label
     *
     * @return bool
     */
    private static function isValidContextJ(array $codePoints, $label)
    {
        if (!isset(self::$virama)) {
            self::$virama = require __DIR__.\DIRECTORY_SEPARATOR.'Resources'.\DIRECTORY_SEPARATOR.'unidata'.\DIRECTORY_SEPARATOR.'virama.php';
        }

        $offset = 0;

        foreach ($codePoints as $i => $codePoint) {
            if (0x200C !== $codePoint && 0x200D !== $codePoint) {
                continue;
            }

            if (!isset($codePoints[$i - 1])) {
                return false;
            }

            // If Canonical_Combining_Class(Before(cp)) .eq. Virama Then True;
            if (isset(self::$virama[$codePoints[$i - 1]])) {
                continue;
            }

            // If RegExpMatch((Joining_Type:{L,D})(Joining_Type:T)*\u200C(Joining_Type:T)*(Joining_Type:{R,D})) Then
            // True;
            // Generated RegExp = ([Joining_Type:{L,D}][Joining_Type:T]*\u200C[Joining_Type:T]*)[Joining_Type:{R,D}]
            if (0x200C === $codePoint && 1 === preg_match(Regex::ZWNJ, $label, $matches, PREG_OFFSET_CAPTURE, $offset)) {
                $offset += \strlen($matches[1][0]);

                continue;
            }

            return false;
        }

        return true;
    }

    /**
     * @see https://www.unicode.org/reports/tr46/#ProcessingStepMap
     *
     * @param string              $input
     * @param array<string, bool> $options
     *
     * @return string
     */
    private static function mapCodePoints($input, array $options, Info $info)
    {
        $str = '';
        $useSTD3ASCIIRules = $options['UseSTD3ASCIIRules'];
        $transitional = $options['Transitional_Processing'];

        foreach (self::utf8Decode($input) as $codePoint) {
            $data = self::lookupCodePointStatus($codePoint, $useSTD3ASCIIRules);

            switch ($data['status']) {
                case 'disallowed':
                    $info->errors |= self::ERROR_DISALLOWED;

                    // no break.

                case 'valid':
                    $str .= mb_chr($codePoint, 'utf-8');

                    break;

                case 'ignored':
                    // Do nothing.
                    break;

                case 'mapped':
                    $str .= $data['mapping'];

                    break;

                case 'deviation':
                    $info->transitionalDifferent = true;
                    $str .= ($transitional ? $data['mapping'] : mb_chr($codePoint, 'utf-8'));

                    break;
            }
        }

        return $str;
    }

    /**
     * @see https://www.unicode.org/reports/tr46/#Processing
     *
     * @param string              $domain
     * @param array<string, bool> $options
     *
     * @return array<int, string>
     */
    private static function process($domain, array $options, Info $info)
    {
        // If VerifyDnsLength is not set, we are doing ToUnicode otherwise we are doing ToASCII and
        // we need to respect the VerifyDnsLength option.
        $checkForEmptyLabels = !isset($options['VerifyDnsLength']) || $options['VerifyDnsLength'];

        if ($checkForEmptyLabels && '' === $domain) {
            $info->errors |= self::ERROR_EMPTY_LABEL;

            return array($domain);
        }

        // Step 1. Map each code point in the domain name string
        $domain = self::mapCodePoints($domain, $options, $info);

        // Step 2. Normalize the domain name string to Unicode Normalization Form C.
        if (!Normalizer::isNormalized($domain, Normalizer::FORM_C)) {
            $domain = Normalizer::normalize($domain, Normalizer::FORM_C);
        }

        // Step 3. Break the string into labels at U+002E (.) FULL STOP.
        $labels = explode('.', $domain);
        $lastLabelIndex = \count($labels) - 1;

        // Step 4. Convert and validate each label in the domain name string.
        foreach ($labels as $i => $label) {
            $validationOptions = $options;

            if ('xn--' === substr($label, 0, 4)) {
                try {
                    $label = self::punycodeDecode(substr($label, 4));
                } catch (Exception $e) {
                    $info->errors |= self::ERROR_PUNYCODE;

                    continue;
                }

                $validationOptions['Transitional_Processing'] = false;
                $labels[$i] = $label;
            }

            self::validateLabel($label, $info, $validationOptions, $i > 0 && $i === $lastLabelIndex);
        }

        if ($info->bidiDomain && !$info->validBidiDomain) {
            $info->errors |= self::ERROR_BIDI;
        }

        // Any input domain name string that does not record an error has been successfully
        // processed according to this specification. Conversely, if an input domain_name string
        // causes an error, then the processing of the input domain_name string fails. Determining
        // what to do with error input is up to the caller, and not in the scope of this document.
        return $labels;
    }

    /**
     * @see https://tools.ietf.org/html/rfc5893#section-2
     *
     * @param string $label
     */
    private static function validateBidiLabel($label, Info $info)
    {
        if (1 === preg_match(Regex::RTL_LABEL, $label)) {
            $info->bidiDomain = true;

            // Step 1. The first character must be a character with Bidi property L, R, or AL.
            // If it has the R or AL property, it is an RTL label
            if (1 !== preg_match(Regex::BIDI_STEP_1_RTL, $label)) {
                $info->validBidiDomain = false;

                return;
            }

            // Step 2. In an RTL label, only characters with the Bidi properties R, AL, AN, EN, ES,
            // CS, ET, ON, BN, or NSM are allowed.
            if (1 === preg_match(Regex::BIDI_STEP_2, $label)) {
                $info->validBidiDomain = false;

                return;
            }

            // Step 3. In an RTL label, the end of the label must be a character with Bidi property
            // R, AL, EN, or AN, followed by zero or more characters with Bidi property NSM.
            if (1 !== preg_match(Regex::BIDI_STEP_3, $label)) {
                $info->validBidiDomain = false;

                return;
            }

            // Step 4. In an RTL label, if an EN is present, no AN may be present, and vice versa.
            if (1 === preg_match(Regex::BIDI_STEP_4_AN, $label) && 1 === preg_match(Regex::BIDI_STEP_4_EN, $label)) {
                $info->validBidiDomain = false;

                return;
            }

            return;
        }

        // We are a LTR label
        // Step 1. The first character must be a character with Bidi property L, R, or AL.
        // If it has the L property, it is an LTR label.
        if (1 !== preg_match(Regex::BIDI_STEP_1_LTR, $label)) {
            $info->validBidiDomain = false;

            return;
        }

        // Step 5. In an LTR label, only characters with the Bidi properties L, EN,
        // ES, CS, ET, ON, BN, or NSM are allowed.
        if (1 === preg_match(Regex::BIDI_STEP_5, $label)) {
            $info->validBidiDomain = false;

            return;
        }

        // Step 6.In an LTR label, the end of the label must be a character with Bidi property L or
        // EN, followed by zero or more characters with Bidi property NSM.
        if (1 !== preg_match(Regex::BIDI_STEP_6, $label)) {
            $info->validBidiDomain = false;

            return;
        }
    }

    /**
     * @param array<int, string> $labels
     */
    private static function validateDomainAndLabelLength(array $labels, Info $info)
    {
        $maxDomainSize = self::MAX_DOMAIN_SIZE;
        $length = \count($labels);

        // Number of "." delimiters.
        $domainLength = $length - 1;

        // If the last label is empty and it is not the first label, then it is the root label.
        // Increase the max size by 1, making it 254, to account for the root label's "."
        // delimiter. This also means we don't need to check the last label's length for being too
        // long.
        if ($length > 1 && '' === $labels[$length - 1]) {
            ++$maxDomainSize;
            --$length;
        }

        for ($i = 0; $i < $length; ++$i) {
            $bytes = \strlen($labels[$i]);
            $domainLength += $bytes;

            if ($bytes > self::MAX_LABEL_SIZE) {
                $info->errors |= self::ERROR_LABEL_TOO_LONG;
            }
        }

        if ($domainLength > $maxDomainSize) {
            $info->errors |= self::ERROR_DOMAIN_NAME_TOO_LONG;
        }
    }

    /**
     * @see https://www.unicode.org/reports/tr46/#Validity_Criteria
     *
     * @param string              $label
     * @param array<string, bool> $options
     * @param bool                $canBeEmpty
     */
    private static function validateLabel($label, Info $info, array $options, $canBeEmpty)
    {
        if ('' === $label) {
            if (!$canBeEmpty && (!isset($options['VerifyDnsLength']) || $options['VerifyDnsLength'])) {
                $info->errors |= self::ERROR_EMPTY_LABEL;
            }

            return;
        }

        // Step 1. The label must be in Unicode Normalization Form C.
        if (!Normalizer::isNormalized($label, Normalizer::FORM_C)) {
            $info->errors |= self::ERROR_INVALID_ACE_LABEL;
        }

        $codePoints = self::utf8Decode($label);

        if ($options['CheckHyphens']) {
            // Step 2. If CheckHyphens, the label must not contain a U+002D HYPHEN-MINUS character
            // in both the thrid and fourth positions.
            if (isset($codePoints[2], $codePoints[3]) && 0x002D === $codePoints[2] && 0x002D === $codePoints[3]) {
                $info->errors |= self::ERROR_HYPHEN_3_4;
            }

            // Step 3. If CheckHyphens, the label must neither begin nor end with a U+002D
            // HYPHEN-MINUS character.
            if ('-' === substr($label, 0, 1)) {
                $info->errors |= self::ERROR_LEADING_HYPHEN;
            }

            if ('-' === substr($label, -1, 1)) {
                $info->errors |= self::ERROR_TRAILING_HYPHEN;
            }
        }

        // Step 4. The label must not contain a U+002E (.) FULL STOP.
        if (false !== strpos($label, '.')) {
            $info->errors |= self::ERROR_LABEL_HAS_DOT;
        }

        // Step 5. The label must not begin with a combining mark, that is: General_Category=Mark.
        if (1 === preg_match(Regex::COMBINING_MARK, $label)) {
            $info->errors |= self::ERROR_LEADING_COMBINING_MARK;
        }

        // Step 6. Each code point in the label must only have certain status values according to
        // Section 5, IDNA Mapping Table:
        $transitional = $options['Transitional_Processing'];
        $useSTD3ASCIIRules = $options['UseSTD3ASCIIRules'];

        foreach ($codePoints as $codePoint) {
            $data = self::lookupCodePointStatus($codePoint, $useSTD3ASCIIRules);
            $status = $data['status'];

            if ('valid' === $status || (!$transitional && 'deviation' === $status)) {
                continue;
            }

            $info->errors |= self::ERROR_DISALLOWED;

            break;
        }

        // Step 7. If CheckJoiners, the label must satisify the ContextJ rules from Appendix A, in
        // The Unicode Code Points and Internationalized Domain Names for Applications (IDNA)
        // [IDNA2008].
        if ($options['CheckJoiners'] && !self::isValidContextJ($codePoints, $label)) {
            $info->errors |= self::ERROR_CONTEXTJ;
        }

        // Step 8. If CheckBidi, and if the domain name is a  Bidi domain name, then the label must
        // satisfy all six of the numbered conditions in [IDNA2008] RFC 5893, Section 2.
        if ($options['CheckBidi'] && (!$info->bidiDomain || $info->validBidiDomain)) {
            self::validateBidiLabel($label, $info);
        }
    }

    /**
     * @see https://tools.ietf.org/html/rfc3492#section-6.2
     *
     * @param string $input
     *
     * @return string
     */
    private static function punycodeDecode($input)
    {
        $n = self::INITIAL_N;
        $out = 0;
        $i = 0;
        $bias = self::INITIAL_BIAS;
        $lastDelimIndex = strrpos($input, self::DELIMITER);
        $b = false === $lastDelimIndex ? 0 : $lastDelimIndex;
        $inputLength = \strlen($input);
        $output = array();
        $bytes = array_map('ord', str_split($input));

        for ($j = 0; $j < $b; ++$j) {
            if ($bytes[$j] > 0x7F) {
                throw new Exception('Invalid input');
            }

            $output[$out++] = $input[$j];
        }

        if ($b > 0) {
            ++$b;
        }

        for ($in = $b; $in < $inputLength; ++$out) {
            $oldi = $i;
            $w = 1;

            for ($k = self::BASE; /* no condition */; $k += self::BASE) {
                if ($in >= $inputLength) {
                    throw new Exception('Invalid input');
                }

                $digit = self::$basicToDigit[$bytes[$in++] & 0xFF];

                if ($digit < 0) {
                    throw new Exception('Invalid input');
                }

                if ($digit > intdiv(self::MAX_INT - $i, $w)) {
                    throw new Exception('Integer overflow');
                }

                $i += $digit * $w;

                if ($k <= $bias) {
                    $t = self::TMIN;
                } elseif ($k >= $bias + self::TMAX) {
                    $t = self::TMAX;
                } else {
                    $t = $k - $bias;
                }

                if ($digit < $t) {
                    break;
                }

                $baseMinusT = self::BASE - $t;

                if ($w > intdiv(self::MAX_INT, $baseMinusT)) {
                    throw new Exception('Integer overflow');
                }

                $w *= $baseMinusT;
            }

            $outPlusOne = $out + 1;
            $bias = self::adaptBias($i - $oldi, $outPlusOne, 0 === $oldi);

            if (intdiv($i, $outPlusOne) > self::MAX_INT - $n) {
                throw new Exception('Integer overflow');
            }

            $n += intdiv($i, $outPlusOne);
            $i %= $outPlusOne;
            array_splice($output, $i++, 0, array(mb_chr($n, 'utf-8')));
        }

        return implode('', $output);
    }

    /**
     * @see https://tools.ietf.org/html/rfc3492#section-6.3
     *
     * @param string $input
     *
     * @return string
     */
    private static function punycodeEncode($input)
    {
        $n = self::INITIAL_N;
        $delta = 0;
        $out = 0;
        $bias = self::INITIAL_BIAS;
        $inputLength = 0;
        $output = '';
        $iter = self::utf8Decode($input);

        foreach ($iter as $codePoint) {
            ++$inputLength;

            if ($codePoint < 0x80) {
                $output .= \chr($codePoint);
                ++$out;
            }
        }

        $h = $out;
        $b = $out;

        if ($b > 0) {
            $output .= self::DELIMITER;
            ++$out;
        }

        while ($h < $inputLength) {
            $m = self::MAX_INT;

            foreach ($iter as $codePoint) {
                if ($codePoint >= $n && $codePoint < $m) {
                    $m = $codePoint;
                }
            }

            if ($m - $n > intdiv(self::MAX_INT - $delta, $h + 1)) {
                throw new Exception('Integer overflow');
            }

            $delta += ($m - $n) * ($h + 1);
            $n = $m;

            foreach ($iter as $codePoint) {
                if ($codePoint < $n && 0 === ++$delta) {
                    throw new Exception('Integer overflow');
                } elseif ($codePoint === $n) {
                    $q = $delta;

                    for ($k = self::BASE; /* no condition */; $k += self::BASE) {
                        if ($k <= $bias) {
                            $t = self::TMIN;
                        } elseif ($k >= $bias + self::TMAX) {
                            $t = self::TMAX;
                        } else {
                            $t = $k - $bias;
                        }

                        if ($q < $t) {
                            break;
                        }

                        $qMinusT = $q - $t;
                        $baseMinusT = self::BASE - $t;
                        $output .= self::encodeDigit($t + ($qMinusT) % ($baseMinusT), false);
                        ++$out;
                        $q = intdiv($qMinusT, $baseMinusT);
                    }

                    $output .= self::encodeDigit($q, false);
                    ++$out;
                    $bias = self::adaptBias($delta, $h + 1, $h === $b);
                    $delta = 0;
                    ++$h;
                }
            }

            ++$delta;
            ++$n;
        }

        return $output;
    }

    /**
     * @see https://tools.ietf.org/html/rfc3492#section-6.1
     *
     * @param int  $delta
     * @param int  $numPoints
     * @param bool $firstTime
     *
     * @return int
     */
    private static function adaptBias($delta, $numPoints, $firstTime)
    {
        // xxx >> 1 is a faster way of doing intdiv(xxx, 2)
        $delta = $firstTime ? intdiv($delta, self::DAMP) : $delta >> 1;
        $delta += intdiv($delta, $numPoints);
        $k = 0;

        while ($delta > ((self::BASE - self::TMIN) * self::TMAX) >> 1) {
            $delta = intdiv($delta, self::BASE - self::TMIN);
            $k += self::BASE;
        }

        return $k + intdiv((self::BASE - self::TMIN + 1) * $delta, $delta + self::SKEW);
    }

    /**
     * @param int  $d
     * @param bool $flag
     *
     * @return string
     */
    private static function encodeDigit($d, $flag)
    {
        return \chr($d + 22 + 75 * ($d < 26 ? 1 : 0) - (($flag ? 1 : 0) << 5));
    }

    /**
     * Takes a UTF-8 encoded string and converts it into a series of integer code points. Any
     * invalid byte sequences will be replaced by a U+FFFD replacement code point.
     *
     * @see https://encoding.spec.whatwg.org/#utf-8-decoder
     *
     * @param string $input
     *
     * @return array<int, int>
     */
    private static function utf8Decode($input)
    {
        $bytesSeen = 0;
        $bytesNeeded = 0;
        $lowerBoundary = 0x80;
        $upperBoundary = 0xBF;
        $codePoint = 0;
        $codePoints = array();
        $length = \strlen($input);

        for ($i = 0; $i < $length; ++$i) {
            $byte = \ord($input[$i]);

            if (0 === $bytesNeeded) {
                if ($byte >= 0x00 && $byte <= 0x7F) {
                    $codePoints[] = $byte;

                    continue;
                }

                if ($byte >= 0xC2 && $byte <= 0xDF) {
                    $bytesNeeded = 1;
                    $codePoint = $byte & 0x1F;
                } elseif ($byte >= 0xE0 && $byte <= 0xEF) {
                    if (0xE0 === $byte) {
                        $lowerBoundary = 0xA0;
                    } elseif (0xED === $byte) {
                        $upperBoundary = 0x9F;
                    }

                    $bytesNeeded = 2;
                    $codePoint = $byte & 0xF;
                } elseif ($byte >= 0xF0 && $byte <= 0xF4) {
                    if (0xF0 === $byte) {
                        $lowerBoundary = 0x90;
                    } elseif (0xF4 === $byte) {
                        $upperBoundary = 0x8F;
                    }

                    $bytesNeeded = 3;
                    $codePoint = $byte & 0x7;
                } else {
                    $codePoints[] = 0xFFFD;
                }

                continue;
            }

            if ($byte < $lowerBoundary || $byte > $upperBoundary) {
                $codePoint = 0;
                $bytesNeeded = 0;
                $bytesSeen = 0;
                $lowerBoundary = 0x80;
                $upperBoundary = 0xBF;
                --$i;
                $codePoints[] = 0xFFFD;

                continue;
            }

            $lowerBoundary = 0x80;
            $upperBoundary = 0xBF;
            $codePoint = ($codePoint << 6) | ($byte & 0x3F);

            if (++$bytesSeen !== $bytesNeeded) {
                continue;
            }

            $codePoints[] = $codePoint;
            $codePoint = 0;
            $bytesNeeded = 0;
            $bytesSeen = 0;
        }

        // String unexpectedly ended, so append a U+FFFD code point.
        if (0 !== $bytesNeeded) {
            $codePoints[] = 0xFFFD;
        }

        return $codePoints;
    }

    /**
     * @param int  $codePoint
     * @param bool $useSTD3ASCIIRules
     *
     * @return array{status: string, mapping?: string}
     */
    private static function lookupCodePointStatus($codePoint, $useSTD3ASCIIRules)
    {
        if (!self::$mappingTableLoaded) {
            self::$mappingTableLoaded = true;
            self::$mapped = require __DIR__.'/Resources/unidata/mapped.php';
            self::$ignored = require __DIR__.'/Resources/unidata/ignored.php';
            self::$deviation = require __DIR__.'/Resources/unidata/deviation.php';
            self::$disallowed = require __DIR__.'/Resources/unidata/disallowed.php';
            self::$disallowed_STD3_mapped = require __DIR__.'/Resources/unidata/disallowed_STD3_mapped.php';
            self::$disallowed_STD3_valid = require __DIR__.'/Resources/unidata/disallowed_STD3_valid.php';
        }

        if (isset(self::$mapped[$codePoint])) {
            return array('status' => 'mapped', 'mapping' => self::$mapped[$codePoint]);
        }

        if (isset(self::$ignored[$codePoint])) {
            return array('status' => 'ignored');
        }

        if (isset(self::$deviation[$codePoint])) {
            return array('status' => 'deviation', 'mapping' => self::$deviation[$codePoint]);
        }

        if (isset(self::$disallowed[$codePoint]) || DisallowedRanges::inRange($codePoint)) {
            return array('status' => 'disallowed');
        }

        $isDisallowedMapped = isset(self::$disallowed_STD3_mapped[$codePoint]);

        if ($isDisallowedMapped || isset(self::$disallowed_STD3_valid[$codePoint])) {
            $status = 'disallowed';

            if (!$useSTD3ASCIIRules) {
                $status = $isDisallowedMapped ? 'mapped' : 'valid';
            }

            if ($isDisallowedMapped) {
                return array('status' => $status, 'mapping' => self::$disallowed_STD3_mapped[$codePoint]);
            }

            return array('status' => $status);
        }

        return array('status' => 'valid');
    }
}
PKϤ$Z&u�{��polyfill-intl-idn/Info.phpnu�[���<?php

/*
 * This file is part of the Symfony package.
 *
 * (c) Fabien Potencier <fabien@symfony.com> and Trevor Rowbotham <trevor.rowbotham@pm.me>
 *
 * For the full copyright and license information, please view the LICENSE
 * file that was distributed with this source code.
 */

namespace Symfony\Polyfill\Intl\Idn;

/**
 * @internal
 */
class Info
{
    public $bidiDomain = false;
    public $errors = 0;
    public $validBidiDomain = true;
    public $transitionalDifferent = false;
}
PKϤ$Z��J5��polyfill-intl-idn/README.mdnu�[���Symfony Polyfill / Intl: Idn
============================

This component provides [`idn_to_ascii`](https://php.net/idn-to-ascii) and [`idn_to_utf8`](https://php.net/idn-to-utf8) functions to users who run php versions without the [Intl](https://php.net/intl) extension.

More information can be found in the
[main Polyfill README](https://github.com/symfony/polyfill/blob/master/README.md).

License
=======

This library is released under the [MIT license](LICENSE).
PKϤ$ZɨU�
�
�-polyfill-intl-idn/Resources/unidata/Regex.phpnu�[���<?php

namespace Symfony\Polyfill\Intl\Idn\Resources\unidata;

/**
 * @internal
 */
final class Regex
{
    const COMBINING_MARK = '/^[\x{0300}-\x{036F}\x{0483}-\x{0487}\x{0488}-\x{0489}\x{0591}-\x{05BD}\x{05BF}\x{05C1}-\x{05C2}\x{05C4}-\x{05C5}\x{05C7}\x{0610}-\x{061A}\x{064B}-\x{065F}\x{0670}\x{06D6}-\x{06DC}\x{06DF}-\x{06E4}\x{06E7}-\x{06E8}\x{06EA}-\x{06ED}\x{0711}\x{0730}-\x{074A}\x{07A6}-\x{07B0}\x{07EB}-\x{07F3}\x{07FD}\x{0816}-\x{0819}\x{081B}-\x{0823}\x{0825}-\x{0827}\x{0829}-\x{082D}\x{0859}-\x{085B}\x{08D3}-\x{08E1}\x{08E3}-\x{0902}\x{0903}\x{093A}\x{093B}\x{093C}\x{093E}-\x{0940}\x{0941}-\x{0948}\x{0949}-\x{094C}\x{094D}\x{094E}-\x{094F}\x{0951}-\x{0957}\x{0962}-\x{0963}\x{0981}\x{0982}-\x{0983}\x{09BC}\x{09BE}-\x{09C0}\x{09C1}-\x{09C4}\x{09C7}-\x{09C8}\x{09CB}-\x{09CC}\x{09CD}\x{09D7}\x{09E2}-\x{09E3}\x{09FE}\x{0A01}-\x{0A02}\x{0A03}\x{0A3C}\x{0A3E}-\x{0A40}\x{0A41}-\x{0A42}\x{0A47}-\x{0A48}\x{0A4B}-\x{0A4D}\x{0A51}\x{0A70}-\x{0A71}\x{0A75}\x{0A81}-\x{0A82}\x{0A83}\x{0ABC}\x{0ABE}-\x{0AC0}\x{0AC1}-\x{0AC5}\x{0AC7}-\x{0AC8}\x{0AC9}\x{0ACB}-\x{0ACC}\x{0ACD}\x{0AE2}-\x{0AE3}\x{0AFA}-\x{0AFF}\x{0B01}\x{0B02}-\x{0B03}\x{0B3C}\x{0B3E}\x{0B3F}\x{0B40}\x{0B41}-\x{0B44}\x{0B47}-\x{0B48}\x{0B4B}-\x{0B4C}\x{0B4D}\x{0B55}-\x{0B56}\x{0B57}\x{0B62}-\x{0B63}\x{0B82}\x{0BBE}-\x{0BBF}\x{0BC0}\x{0BC1}-\x{0BC2}\x{0BC6}-\x{0BC8}\x{0BCA}-\x{0BCC}\x{0BCD}\x{0BD7}\x{0C00}\x{0C01}-\x{0C03}\x{0C04}\x{0C3E}-\x{0C40}\x{0C41}-\x{0C44}\x{0C46}-\x{0C48}\x{0C4A}-\x{0C4D}\x{0C55}-\x{0C56}\x{0C62}-\x{0C63}\x{0C81}\x{0C82}-\x{0C83}\x{0CBC}\x{0CBE}\x{0CBF}\x{0CC0}-\x{0CC4}\x{0CC6}\x{0CC7}-\x{0CC8}\x{0CCA}-\x{0CCB}\x{0CCC}-\x{0CCD}\x{0CD5}-\x{0CD6}\x{0CE2}-\x{0CE3}\x{0D00}-\x{0D01}\x{0D02}-\x{0D03}\x{0D3B}-\x{0D3C}\x{0D3E}-\x{0D40}\x{0D41}-\x{0D44}\x{0D46}-\x{0D48}\x{0D4A}-\x{0D4C}\x{0D4D}\x{0D57}\x{0D62}-\x{0D63}\x{0D81}\x{0D82}-\x{0D83}\x{0DCA}\x{0DCF}-\x{0DD1}\x{0DD2}-\x{0DD4}\x{0DD6}\x{0DD8}-\x{0DDF}\x{0DF2}-\x{0DF3}\x{0E31}\x{0E34}-\x{0E3A}\x{0E47}-\x{0E4E}\x{0EB1}\x{0EB4}-\x{0EBC}\x{0EC8}-\x{0ECD}\x{0F18}-\x{0F19}\x{0F35}\x{0F37}\x{0F39}\x{0F3E}-\x{0F3F}\x{0F71}-\x{0F7E}\x{0F7F}\x{0F80}-\x{0F84}\x{0F86}-\x{0F87}\x{0F8D}-\x{0F97}\x{0F99}-\x{0FBC}\x{0FC6}\x{102B}-\x{102C}\x{102D}-\x{1030}\x{1031}\x{1032}-\x{1037}\x{1038}\x{1039}-\x{103A}\x{103B}-\x{103C}\x{103D}-\x{103E}\x{1056}-\x{1057}\x{1058}-\x{1059}\x{105E}-\x{1060}\x{1062}-\x{1064}\x{1067}-\x{106D}\x{1071}-\x{1074}\x{1082}\x{1083}-\x{1084}\x{1085}-\x{1086}\x{1087}-\x{108C}\x{108D}\x{108F}\x{109A}-\x{109C}\x{109D}\x{135D}-\x{135F}\x{1712}-\x{1714}\x{1732}-\x{1734}\x{1752}-\x{1753}\x{1772}-\x{1773}\x{17B4}-\x{17B5}\x{17B6}\x{17B7}-\x{17BD}\x{17BE}-\x{17C5}\x{17C6}\x{17C7}-\x{17C8}\x{17C9}-\x{17D3}\x{17DD}\x{180B}-\x{180D}\x{1885}-\x{1886}\x{18A9}\x{1920}-\x{1922}\x{1923}-\x{1926}\x{1927}-\x{1928}\x{1929}-\x{192B}\x{1930}-\x{1931}\x{1932}\x{1933}-\x{1938}\x{1939}-\x{193B}\x{1A17}-\x{1A18}\x{1A19}-\x{1A1A}\x{1A1B}\x{1A55}\x{1A56}\x{1A57}\x{1A58}-\x{1A5E}\x{1A60}\x{1A61}\x{1A62}\x{1A63}-\x{1A64}\x{1A65}-\x{1A6C}\x{1A6D}-\x{1A72}\x{1A73}-\x{1A7C}\x{1A7F}\x{1AB0}-\x{1ABD}\x{1ABE}\x{1ABF}-\x{1AC0}\x{1B00}-\x{1B03}\x{1B04}\x{1B34}\x{1B35}\x{1B36}-\x{1B3A}\x{1B3B}\x{1B3C}\x{1B3D}-\x{1B41}\x{1B42}\x{1B43}-\x{1B44}\x{1B6B}-\x{1B73}\x{1B80}-\x{1B81}\x{1B82}\x{1BA1}\x{1BA2}-\x{1BA5}\x{1BA6}-\x{1BA7}\x{1BA8}-\x{1BA9}\x{1BAA}\x{1BAB}-\x{1BAD}\x{1BE6}\x{1BE7}\x{1BE8}-\x{1BE9}\x{1BEA}-\x{1BEC}\x{1BED}\x{1BEE}\x{1BEF}-\x{1BF1}\x{1BF2}-\x{1BF3}\x{1C24}-\x{1C2B}\x{1C2C}-\x{1C33}\x{1C34}-\x{1C35}\x{1C36}-\x{1C37}\x{1CD0}-\x{1CD2}\x{1CD4}-\x{1CE0}\x{1CE1}\x{1CE2}-\x{1CE8}\x{1CED}\x{1CF4}\x{1CF7}\x{1CF8}-\x{1CF9}\x{1DC0}-\x{1DF9}\x{1DFB}-\x{1DFF}\x{20D0}-\x{20DC}\x{20DD}-\x{20E0}\x{20E1}\x{20E2}-\x{20E4}\x{20E5}-\x{20F0}\x{2CEF}-\x{2CF1}\x{2D7F}\x{2DE0}-\x{2DFF}\x{302A}-\x{302D}\x{302E}-\x{302F}\x{3099}-\x{309A}\x{A66F}\x{A670}-\x{A672}\x{A674}-\x{A67D}\x{A69E}-\x{A69F}\x{A6F0}-\x{A6F1}\x{A802}\x{A806}\x{A80B}\x{A823}-\x{A824}\x{A825}-\x{A826}\x{A827}\x{A82C}\x{A880}-\x{A881}\x{A8B4}-\x{A8C3}\x{A8C4}-\x{A8C5}\x{A8E0}-\x{A8F1}\x{A8FF}\x{A926}-\x{A92D}\x{A947}-\x{A951}\x{A952}-\x{A953}\x{A980}-\x{A982}\x{A983}\x{A9B3}\x{A9B4}-\x{A9B5}\x{A9B6}-\x{A9B9}\x{A9BA}-\x{A9BB}\x{A9BC}-\x{A9BD}\x{A9BE}-\x{A9C0}\x{A9E5}\x{AA29}-\x{AA2E}\x{AA2F}-\x{AA30}\x{AA31}-\x{AA32}\x{AA33}-\x{AA34}\x{AA35}-\x{AA36}\x{AA43}\x{AA4C}\x{AA4D}\x{AA7B}\x{AA7C}\x{AA7D}\x{AAB0}\x{AAB2}-\x{AAB4}\x{AAB7}-\x{AAB8}\x{AABE}-\x{AABF}\x{AAC1}\x{AAEB}\x{AAEC}-\x{AAED}\x{AAEE}-\x{AAEF}\x{AAF5}\x{AAF6}\x{ABE3}-\x{ABE4}\x{ABE5}\x{ABE6}-\x{ABE7}\x{ABE8}\x{ABE9}-\x{ABEA}\x{ABEC}\x{ABED}\x{FB1E}\x{FE00}-\x{FE0F}\x{FE20}-\x{FE2F}\x{101FD}\x{102E0}\x{10376}-\x{1037A}\x{10A01}-\x{10A03}\x{10A05}-\x{10A06}\x{10A0C}-\x{10A0F}\x{10A38}-\x{10A3A}\x{10A3F}\x{10AE5}-\x{10AE6}\x{10D24}-\x{10D27}\x{10EAB}-\x{10EAC}\x{10F46}-\x{10F50}\x{11000}\x{11001}\x{11002}\x{11038}-\x{11046}\x{1107F}-\x{11081}\x{11082}\x{110B0}-\x{110B2}\x{110B3}-\x{110B6}\x{110B7}-\x{110B8}\x{110B9}-\x{110BA}\x{11100}-\x{11102}\x{11127}-\x{1112B}\x{1112C}\x{1112D}-\x{11134}\x{11145}-\x{11146}\x{11173}\x{11180}-\x{11181}\x{11182}\x{111B3}-\x{111B5}\x{111B6}-\x{111BE}\x{111BF}-\x{111C0}\x{111C9}-\x{111CC}\x{111CE}\x{111CF}\x{1122C}-\x{1122E}\x{1122F}-\x{11231}\x{11232}-\x{11233}\x{11234}\x{11235}\x{11236}-\x{11237}\x{1123E}\x{112DF}\x{112E0}-\x{112E2}\x{112E3}-\x{112EA}\x{11300}-\x{11301}\x{11302}-\x{11303}\x{1133B}-\x{1133C}\x{1133E}-\x{1133F}\x{11340}\x{11341}-\x{11344}\x{11347}-\x{11348}\x{1134B}-\x{1134D}\x{11357}\x{11362}-\x{11363}\x{11366}-\x{1136C}\x{11370}-\x{11374}\x{11435}-\x{11437}\x{11438}-\x{1143F}\x{11440}-\x{11441}\x{11442}-\x{11444}\x{11445}\x{11446}\x{1145E}\x{114B0}-\x{114B2}\x{114B3}-\x{114B8}\x{114B9}\x{114BA}\x{114BB}-\x{114BE}\x{114BF}-\x{114C0}\x{114C1}\x{114C2}-\x{114C3}\x{115AF}-\x{115B1}\x{115B2}-\x{115B5}\x{115B8}-\x{115BB}\x{115BC}-\x{115BD}\x{115BE}\x{115BF}-\x{115C0}\x{115DC}-\x{115DD}\x{11630}-\x{11632}\x{11633}-\x{1163A}\x{1163B}-\x{1163C}\x{1163D}\x{1163E}\x{1163F}-\x{11640}\x{116AB}\x{116AC}\x{116AD}\x{116AE}-\x{116AF}\x{116B0}-\x{116B5}\x{116B6}\x{116B7}\x{1171D}-\x{1171F}\x{11720}-\x{11721}\x{11722}-\x{11725}\x{11726}\x{11727}-\x{1172B}\x{1182C}-\x{1182E}\x{1182F}-\x{11837}\x{11838}\x{11839}-\x{1183A}\x{11930}-\x{11935}\x{11937}-\x{11938}\x{1193B}-\x{1193C}\x{1193D}\x{1193E}\x{11940}\x{11942}\x{11943}\x{119D1}-\x{119D3}\x{119D4}-\x{119D7}\x{119DA}-\x{119DB}\x{119DC}-\x{119DF}\x{119E0}\x{119E4}\x{11A01}-\x{11A0A}\x{11A33}-\x{11A38}\x{11A39}\x{11A3B}-\x{11A3E}\x{11A47}\x{11A51}-\x{11A56}\x{11A57}-\x{11A58}\x{11A59}-\x{11A5B}\x{11A8A}-\x{11A96}\x{11A97}\x{11A98}-\x{11A99}\x{11C2F}\x{11C30}-\x{11C36}\x{11C38}-\x{11C3D}\x{11C3E}\x{11C3F}\x{11C92}-\x{11CA7}\x{11CA9}\x{11CAA}-\x{11CB0}\x{11CB1}\x{11CB2}-\x{11CB3}\x{11CB4}\x{11CB5}-\x{11CB6}\x{11D31}-\x{11D36}\x{11D3A}\x{11D3C}-\x{11D3D}\x{11D3F}-\x{11D45}\x{11D47}\x{11D8A}-\x{11D8E}\x{11D90}-\x{11D91}\x{11D93}-\x{11D94}\x{11D95}\x{11D96}\x{11D97}\x{11EF3}-\x{11EF4}\x{11EF5}-\x{11EF6}\x{16AF0}-\x{16AF4}\x{16B30}-\x{16B36}\x{16F4F}\x{16F51}-\x{16F87}\x{16F8F}-\x{16F92}\x{16FE4}\x{16FF0}-\x{16FF1}\x{1BC9D}-\x{1BC9E}\x{1D165}-\x{1D166}\x{1D167}-\x{1D169}\x{1D16D}-\x{1D172}\x{1D17B}-\x{1D182}\x{1D185}-\x{1D18B}\x{1D1AA}-\x{1D1AD}\x{1D242}-\x{1D244}\x{1DA00}-\x{1DA36}\x{1DA3B}-\x{1DA6C}\x{1DA75}\x{1DA84}\x{1DA9B}-\x{1DA9F}\x{1DAA1}-\x{1DAAF}\x{1E000}-\x{1E006}\x{1E008}-\x{1E018}\x{1E01B}-\x{1E021}\x{1E023}-\x{1E024}\x{1E026}-\x{1E02A}\x{1E130}-\x{1E136}\x{1E2EC}-\x{1E2EF}\x{1E8D0}-\x{1E8D6}\x{1E944}-\x{1E94A}\x{E0100}-\x{E01EF}]/u';

    const RTL_LABEL = '/[\x{0590}\x{05BE}\x{05C0}\x{05C3}\x{05C6}\x{05C8}-\x{05CF}\x{05D0}-\x{05EA}\x{05EB}-\x{05EE}\x{05EF}-\x{05F2}\x{05F3}-\x{05F4}\x{05F5}-\x{05FF}\x{0600}-\x{0605}\x{0608}\x{060B}\x{060D}\x{061B}\x{061C}\x{061D}\x{061E}-\x{061F}\x{0620}-\x{063F}\x{0640}\x{0641}-\x{064A}\x{0660}-\x{0669}\x{066B}-\x{066C}\x{066D}\x{066E}-\x{066F}\x{0671}-\x{06D3}\x{06D4}\x{06D5}\x{06DD}\x{06E5}-\x{06E6}\x{06EE}-\x{06EF}\x{06FA}-\x{06FC}\x{06FD}-\x{06FE}\x{06FF}\x{0700}-\x{070D}\x{070E}\x{070F}\x{0710}\x{0712}-\x{072F}\x{074B}-\x{074C}\x{074D}-\x{07A5}\x{07B1}\x{07B2}-\x{07BF}\x{07C0}-\x{07C9}\x{07CA}-\x{07EA}\x{07F4}-\x{07F5}\x{07FA}\x{07FB}-\x{07FC}\x{07FE}-\x{07FF}\x{0800}-\x{0815}\x{081A}\x{0824}\x{0828}\x{082E}-\x{082F}\x{0830}-\x{083E}\x{083F}\x{0840}-\x{0858}\x{085C}-\x{085D}\x{085E}\x{085F}\x{0860}-\x{086A}\x{086B}-\x{086F}\x{0870}-\x{089F}\x{08A0}-\x{08B4}\x{08B5}\x{08B6}-\x{08C7}\x{08C8}-\x{08D2}\x{08E2}\x{200F}\x{FB1D}\x{FB1F}-\x{FB28}\x{FB2A}-\x{FB36}\x{FB37}\x{FB38}-\x{FB3C}\x{FB3D}\x{FB3E}\x{FB3F}\x{FB40}-\x{FB41}\x{FB42}\x{FB43}-\x{FB44}\x{FB45}\x{FB46}-\x{FB4F}\x{FB50}-\x{FBB1}\x{FBB2}-\x{FBC1}\x{FBC2}-\x{FBD2}\x{FBD3}-\x{FD3D}\x{FD40}-\x{FD4F}\x{FD50}-\x{FD8F}\x{FD90}-\x{FD91}\x{FD92}-\x{FDC7}\x{FDC8}-\x{FDCF}\x{FDF0}-\x{FDFB}\x{FDFC}\x{FDFE}-\x{FDFF}\x{FE70}-\x{FE74}\x{FE75}\x{FE76}-\x{FEFC}\x{FEFD}-\x{FEFE}\x{10800}-\x{10805}\x{10806}-\x{10807}\x{10808}\x{10809}\x{1080A}-\x{10835}\x{10836}\x{10837}-\x{10838}\x{10839}-\x{1083B}\x{1083C}\x{1083D}-\x{1083E}\x{1083F}-\x{10855}\x{10856}\x{10857}\x{10858}-\x{1085F}\x{10860}-\x{10876}\x{10877}-\x{10878}\x{10879}-\x{1087F}\x{10880}-\x{1089E}\x{1089F}-\x{108A6}\x{108A7}-\x{108AF}\x{108B0}-\x{108DF}\x{108E0}-\x{108F2}\x{108F3}\x{108F4}-\x{108F5}\x{108F6}-\x{108FA}\x{108FB}-\x{108FF}\x{10900}-\x{10915}\x{10916}-\x{1091B}\x{1091C}-\x{1091E}\x{10920}-\x{10939}\x{1093A}-\x{1093E}\x{1093F}\x{10940}-\x{1097F}\x{10980}-\x{109B7}\x{109B8}-\x{109BB}\x{109BC}-\x{109BD}\x{109BE}-\x{109BF}\x{109C0}-\x{109CF}\x{109D0}-\x{109D1}\x{109D2}-\x{109FF}\x{10A00}\x{10A04}\x{10A07}-\x{10A0B}\x{10A10}-\x{10A13}\x{10A14}\x{10A15}-\x{10A17}\x{10A18}\x{10A19}-\x{10A35}\x{10A36}-\x{10A37}\x{10A3B}-\x{10A3E}\x{10A40}-\x{10A48}\x{10A49}-\x{10A4F}\x{10A50}-\x{10A58}\x{10A59}-\x{10A5F}\x{10A60}-\x{10A7C}\x{10A7D}-\x{10A7E}\x{10A7F}\x{10A80}-\x{10A9C}\x{10A9D}-\x{10A9F}\x{10AA0}-\x{10ABF}\x{10AC0}-\x{10AC7}\x{10AC8}\x{10AC9}-\x{10AE4}\x{10AE7}-\x{10AEA}\x{10AEB}-\x{10AEF}\x{10AF0}-\x{10AF6}\x{10AF7}-\x{10AFF}\x{10B00}-\x{10B35}\x{10B36}-\x{10B38}\x{10B40}-\x{10B55}\x{10B56}-\x{10B57}\x{10B58}-\x{10B5F}\x{10B60}-\x{10B72}\x{10B73}-\x{10B77}\x{10B78}-\x{10B7F}\x{10B80}-\x{10B91}\x{10B92}-\x{10B98}\x{10B99}-\x{10B9C}\x{10B9D}-\x{10BA8}\x{10BA9}-\x{10BAF}\x{10BB0}-\x{10BFF}\x{10C00}-\x{10C48}\x{10C49}-\x{10C7F}\x{10C80}-\x{10CB2}\x{10CB3}-\x{10CBF}\x{10CC0}-\x{10CF2}\x{10CF3}-\x{10CF9}\x{10CFA}-\x{10CFF}\x{10D00}-\x{10D23}\x{10D28}-\x{10D2F}\x{10D30}-\x{10D39}\x{10D3A}-\x{10D3F}\x{10D40}-\x{10E5F}\x{10E60}-\x{10E7E}\x{10E7F}\x{10E80}-\x{10EA9}\x{10EAA}\x{10EAD}\x{10EAE}-\x{10EAF}\x{10EB0}-\x{10EB1}\x{10EB2}-\x{10EFF}\x{10F00}-\x{10F1C}\x{10F1D}-\x{10F26}\x{10F27}\x{10F28}-\x{10F2F}\x{10F30}-\x{10F45}\x{10F51}-\x{10F54}\x{10F55}-\x{10F59}\x{10F5A}-\x{10F6F}\x{10F70}-\x{10FAF}\x{10FB0}-\x{10FC4}\x{10FC5}-\x{10FCB}\x{10FCC}-\x{10FDF}\x{10FE0}-\x{10FF6}\x{10FF7}-\x{10FFF}\x{1E800}-\x{1E8C4}\x{1E8C5}-\x{1E8C6}\x{1E8C7}-\x{1E8CF}\x{1E8D7}-\x{1E8FF}\x{1E900}-\x{1E943}\x{1E94B}\x{1E94C}-\x{1E94F}\x{1E950}-\x{1E959}\x{1E95A}-\x{1E95D}\x{1E95E}-\x{1E95F}\x{1E960}-\x{1EC6F}\x{1EC70}\x{1EC71}-\x{1ECAB}\x{1ECAC}\x{1ECAD}-\x{1ECAF}\x{1ECB0}\x{1ECB1}-\x{1ECB4}\x{1ECB5}-\x{1ECBF}\x{1ECC0}-\x{1ECFF}\x{1ED00}\x{1ED01}-\x{1ED2D}\x{1ED2E}\x{1ED2F}-\x{1ED3D}\x{1ED3E}-\x{1ED4F}\x{1ED50}-\x{1EDFF}\x{1EE00}-\x{1EE03}\x{1EE04}\x{1EE05}-\x{1EE1F}\x{1EE20}\x{1EE21}-\x{1EE22}\x{1EE23}\x{1EE24}\x{1EE25}-\x{1EE26}\x{1EE27}\x{1EE28}\x{1EE29}-\x{1EE32}\x{1EE33}\x{1EE34}-\x{1EE37}\x{1EE38}\x{1EE39}\x{1EE3A}\x{1EE3B}\x{1EE3C}-\x{1EE41}\x{1EE42}\x{1EE43}-\x{1EE46}\x{1EE47}\x{1EE48}\x{1EE49}\x{1EE4A}\x{1EE4B}\x{1EE4C}\x{1EE4D}-\x{1EE4F}\x{1EE50}\x{1EE51}-\x{1EE52}\x{1EE53}\x{1EE54}\x{1EE55}-\x{1EE56}\x{1EE57}\x{1EE58}\x{1EE59}\x{1EE5A}\x{1EE5B}\x{1EE5C}\x{1EE5D}\x{1EE5E}\x{1EE5F}\x{1EE60}\x{1EE61}-\x{1EE62}\x{1EE63}\x{1EE64}\x{1EE65}-\x{1EE66}\x{1EE67}-\x{1EE6A}\x{1EE6B}\x{1EE6C}-\x{1EE72}\x{1EE73}\x{1EE74}-\x{1EE77}\x{1EE78}\x{1EE79}-\x{1EE7C}\x{1EE7D}\x{1EE7E}\x{1EE7F}\x{1EE80}-\x{1EE89}\x{1EE8A}\x{1EE8B}-\x{1EE9B}\x{1EE9C}-\x{1EEA0}\x{1EEA1}-\x{1EEA3}\x{1EEA4}\x{1EEA5}-\x{1EEA9}\x{1EEAA}\x{1EEAB}-\x{1EEBB}\x{1EEBC}-\x{1EEEF}\x{1EEF2}-\x{1EEFF}\x{1EF00}-\x{1EFFF}]/u';

    const BIDI_STEP_1_LTR = '/^[^\x{0000}-\x{0008}\x{0009}\x{000A}\x{000B}\x{000C}\x{000D}\x{000E}-\x{001B}\x{001C}-\x{001E}\x{001F}\x{0020}\x{0021}-\x{0022}\x{0023}\x{0024}\x{0025}\x{0026}-\x{0027}\x{0028}\x{0029}\x{002A}\x{002B}\x{002C}\x{002D}\x{002E}-\x{002F}\x{0030}-\x{0039}\x{003A}\x{003B}\x{003C}-\x{003E}\x{003F}-\x{0040}\x{005B}\x{005C}\x{005D}\x{005E}\x{005F}\x{0060}\x{007B}\x{007C}\x{007D}\x{007E}\x{007F}-\x{0084}\x{0085}\x{0086}-\x{009F}\x{00A0}\x{00A1}\x{00A2}-\x{00A5}\x{00A6}\x{00A7}\x{00A8}\x{00A9}\x{00AB}\x{00AC}\x{00AD}\x{00AE}\x{00AF}\x{00B0}\x{00B1}\x{00B2}-\x{00B3}\x{00B4}\x{00B6}-\x{00B7}\x{00B8}\x{00B9}\x{00BB}\x{00BC}-\x{00BE}\x{00BF}\x{00D7}\x{00F7}\x{02B9}-\x{02BA}\x{02C2}-\x{02C5}\x{02C6}-\x{02CF}\x{02D2}-\x{02DF}\x{02E5}-\x{02EB}\x{02EC}\x{02ED}\x{02EF}-\x{02FF}\x{0300}-\x{036F}\x{0374}\x{0375}\x{037E}\x{0384}-\x{0385}\x{0387}\x{03F6}\x{0483}-\x{0487}\x{0488}-\x{0489}\x{058A}\x{058D}-\x{058E}\x{058F}\x{0590}\x{0591}-\x{05BD}\x{05BE}\x{05BF}\x{05C0}\x{05C1}-\x{05C2}\x{05C3}\x{05C4}-\x{05C5}\x{05C6}\x{05C7}\x{05C8}-\x{05CF}\x{05D0}-\x{05EA}\x{05EB}-\x{05EE}\x{05EF}-\x{05F2}\x{05F3}-\x{05F4}\x{05F5}-\x{05FF}\x{0600}-\x{0605}\x{0606}-\x{0607}\x{0608}\x{0609}-\x{060A}\x{060B}\x{060C}\x{060D}\x{060E}-\x{060F}\x{0610}-\x{061A}\x{061B}\x{061C}\x{061D}\x{061E}-\x{061F}\x{0620}-\x{063F}\x{0640}\x{0641}-\x{064A}\x{064B}-\x{065F}\x{0660}-\x{0669}\x{066A}\x{066B}-\x{066C}\x{066D}\x{066E}-\x{066F}\x{0670}\x{0671}-\x{06D3}\x{06D4}\x{06D5}\x{06D6}-\x{06DC}\x{06DD}\x{06DE}\x{06DF}-\x{06E4}\x{06E5}-\x{06E6}\x{06E7}-\x{06E8}\x{06E9}\x{06EA}-\x{06ED}\x{06EE}-\x{06EF}\x{06F0}-\x{06F9}\x{06FA}-\x{06FC}\x{06FD}-\x{06FE}\x{06FF}\x{0700}-\x{070D}\x{070E}\x{070F}\x{0710}\x{0711}\x{0712}-\x{072F}\x{0730}-\x{074A}\x{074B}-\x{074C}\x{074D}-\x{07A5}\x{07A6}-\x{07B0}\x{07B1}\x{07B2}-\x{07BF}\x{07C0}-\x{07C9}\x{07CA}-\x{07EA}\x{07EB}-\x{07F3}\x{07F4}-\x{07F5}\x{07F6}\x{07F7}-\x{07F9}\x{07FA}\x{07FB}-\x{07FC}\x{07FD}\x{07FE}-\x{07FF}\x{0800}-\x{0815}\x{0816}-\x{0819}\x{081A}\x{081B}-\x{0823}\x{0824}\x{0825}-\x{0827}\x{0828}\x{0829}-\x{082D}\x{082E}-\x{082F}\x{0830}-\x{083E}\x{083F}\x{0840}-\x{0858}\x{0859}-\x{085B}\x{085C}-\x{085D}\x{085E}\x{085F}\x{0860}-\x{086A}\x{086B}-\x{086F}\x{0870}-\x{089F}\x{08A0}-\x{08B4}\x{08B5}\x{08B6}-\x{08C7}\x{08C8}-\x{08D2}\x{08D3}-\x{08E1}\x{08E2}\x{08E3}-\x{0902}\x{093A}\x{093C}\x{0941}-\x{0948}\x{094D}\x{0951}-\x{0957}\x{0962}-\x{0963}\x{0981}\x{09BC}\x{09C1}-\x{09C4}\x{09CD}\x{09E2}-\x{09E3}\x{09F2}-\x{09F3}\x{09FB}\x{09FE}\x{0A01}-\x{0A02}\x{0A3C}\x{0A41}-\x{0A42}\x{0A47}-\x{0A48}\x{0A4B}-\x{0A4D}\x{0A51}\x{0A70}-\x{0A71}\x{0A75}\x{0A81}-\x{0A82}\x{0ABC}\x{0AC1}-\x{0AC5}\x{0AC7}-\x{0AC8}\x{0ACD}\x{0AE2}-\x{0AE3}\x{0AF1}\x{0AFA}-\x{0AFF}\x{0B01}\x{0B3C}\x{0B3F}\x{0B41}-\x{0B44}\x{0B4D}\x{0B55}-\x{0B56}\x{0B62}-\x{0B63}\x{0B82}\x{0BC0}\x{0BCD}\x{0BF3}-\x{0BF8}\x{0BF9}\x{0BFA}\x{0C00}\x{0C04}\x{0C3E}-\x{0C40}\x{0C46}-\x{0C48}\x{0C4A}-\x{0C4D}\x{0C55}-\x{0C56}\x{0C62}-\x{0C63}\x{0C78}-\x{0C7E}\x{0C81}\x{0CBC}\x{0CCC}-\x{0CCD}\x{0CE2}-\x{0CE3}\x{0D00}-\x{0D01}\x{0D3B}-\x{0D3C}\x{0D41}-\x{0D44}\x{0D4D}\x{0D62}-\x{0D63}\x{0D81}\x{0DCA}\x{0DD2}-\x{0DD4}\x{0DD6}\x{0E31}\x{0E34}-\x{0E3A}\x{0E3F}\x{0E47}-\x{0E4E}\x{0EB1}\x{0EB4}-\x{0EBC}\x{0EC8}-\x{0ECD}\x{0F18}-\x{0F19}\x{0F35}\x{0F37}\x{0F39}\x{0F3A}\x{0F3B}\x{0F3C}\x{0F3D}\x{0F71}-\x{0F7E}\x{0F80}-\x{0F84}\x{0F86}-\x{0F87}\x{0F8D}-\x{0F97}\x{0F99}-\x{0FBC}\x{0FC6}\x{102D}-\x{1030}\x{1032}-\x{1037}\x{1039}-\x{103A}\x{103D}-\x{103E}\x{1058}-\x{1059}\x{105E}-\x{1060}\x{1071}-\x{1074}\x{1082}\x{1085}-\x{1086}\x{108D}\x{109D}\x{135D}-\x{135F}\x{1390}-\x{1399}\x{1400}\x{1680}\x{169B}\x{169C}\x{1712}-\x{1714}\x{1732}-\x{1734}\x{1752}-\x{1753}\x{1772}-\x{1773}\x{17B4}-\x{17B5}\x{17B7}-\x{17BD}\x{17C6}\x{17C9}-\x{17D3}\x{17DB}\x{17DD}\x{17F0}-\x{17F9}\x{1800}-\x{1805}\x{1806}\x{1807}-\x{180A}\x{180B}-\x{180D}\x{180E}\x{1885}-\x{1886}\x{18A9}\x{1920}-\x{1922}\x{1927}-\x{1928}\x{1932}\x{1939}-\x{193B}\x{1940}\x{1944}-\x{1945}\x{19DE}-\x{19FF}\x{1A17}-\x{1A18}\x{1A1B}\x{1A56}\x{1A58}-\x{1A5E}\x{1A60}\x{1A62}\x{1A65}-\x{1A6C}\x{1A73}-\x{1A7C}\x{1A7F}\x{1AB0}-\x{1ABD}\x{1ABE}\x{1ABF}-\x{1AC0}\x{1B00}-\x{1B03}\x{1B34}\x{1B36}-\x{1B3A}\x{1B3C}\x{1B42}\x{1B6B}-\x{1B73}\x{1B80}-\x{1B81}\x{1BA2}-\x{1BA5}\x{1BA8}-\x{1BA9}\x{1BAB}-\x{1BAD}\x{1BE6}\x{1BE8}-\x{1BE9}\x{1BED}\x{1BEF}-\x{1BF1}\x{1C2C}-\x{1C33}\x{1C36}-\x{1C37}\x{1CD0}-\x{1CD2}\x{1CD4}-\x{1CE0}\x{1CE2}-\x{1CE8}\x{1CED}\x{1CF4}\x{1CF8}-\x{1CF9}\x{1DC0}-\x{1DF9}\x{1DFB}-\x{1DFF}\x{1FBD}\x{1FBF}-\x{1FC1}\x{1FCD}-\x{1FCF}\x{1FDD}-\x{1FDF}\x{1FED}-\x{1FEF}\x{1FFD}-\x{1FFE}\x{2000}-\x{200A}\x{200B}-\x{200D}\x{200F}\x{2010}-\x{2015}\x{2016}-\x{2017}\x{2018}\x{2019}\x{201A}\x{201B}-\x{201C}\x{201D}\x{201E}\x{201F}\x{2020}-\x{2027}\x{2028}\x{2029}\x{202A}\x{202B}\x{202C}\x{202D}\x{202E}\x{202F}\x{2030}-\x{2034}\x{2035}-\x{2038}\x{2039}\x{203A}\x{203B}-\x{203E}\x{203F}-\x{2040}\x{2041}-\x{2043}\x{2044}\x{2045}\x{2046}\x{2047}-\x{2051}\x{2052}\x{2053}\x{2054}\x{2055}-\x{205E}\x{205F}\x{2060}-\x{2064}\x{2065}\x{2066}\x{2067}\x{2068}\x{2069}\x{206A}-\x{206F}\x{2070}\x{2074}-\x{2079}\x{207A}-\x{207B}\x{207C}\x{207D}\x{207E}\x{2080}-\x{2089}\x{208A}-\x{208B}\x{208C}\x{208D}\x{208E}\x{20A0}-\x{20BF}\x{20C0}-\x{20CF}\x{20D0}-\x{20DC}\x{20DD}-\x{20E0}\x{20E1}\x{20E2}-\x{20E4}\x{20E5}-\x{20F0}\x{2100}-\x{2101}\x{2103}-\x{2106}\x{2108}-\x{2109}\x{2114}\x{2116}-\x{2117}\x{2118}\x{211E}-\x{2123}\x{2125}\x{2127}\x{2129}\x{212E}\x{213A}-\x{213B}\x{2140}-\x{2144}\x{214A}\x{214B}\x{214C}-\x{214D}\x{2150}-\x{215F}\x{2189}\x{218A}-\x{218B}\x{2190}-\x{2194}\x{2195}-\x{2199}\x{219A}-\x{219B}\x{219C}-\x{219F}\x{21A0}\x{21A1}-\x{21A2}\x{21A3}\x{21A4}-\x{21A5}\x{21A6}\x{21A7}-\x{21AD}\x{21AE}\x{21AF}-\x{21CD}\x{21CE}-\x{21CF}\x{21D0}-\x{21D1}\x{21D2}\x{21D3}\x{21D4}\x{21D5}-\x{21F3}\x{21F4}-\x{2211}\x{2212}\x{2213}\x{2214}-\x{22FF}\x{2300}-\x{2307}\x{2308}\x{2309}\x{230A}\x{230B}\x{230C}-\x{231F}\x{2320}-\x{2321}\x{2322}-\x{2328}\x{2329}\x{232A}\x{232B}-\x{2335}\x{237B}\x{237C}\x{237D}-\x{2394}\x{2396}-\x{239A}\x{239B}-\x{23B3}\x{23B4}-\x{23DB}\x{23DC}-\x{23E1}\x{23E2}-\x{2426}\x{2440}-\x{244A}\x{2460}-\x{2487}\x{2488}-\x{249B}\x{24EA}-\x{24FF}\x{2500}-\x{25B6}\x{25B7}\x{25B8}-\x{25C0}\x{25C1}\x{25C2}-\x{25F7}\x{25F8}-\x{25FF}\x{2600}-\x{266E}\x{266F}\x{2670}-\x{26AB}\x{26AD}-\x{2767}\x{2768}\x{2769}\x{276A}\x{276B}\x{276C}\x{276D}\x{276E}\x{276F}\x{2770}\x{2771}\x{2772}\x{2773}\x{2774}\x{2775}\x{2776}-\x{2793}\x{2794}-\x{27BF}\x{27C0}-\x{27C4}\x{27C5}\x{27C6}\x{27C7}-\x{27E5}\x{27E6}\x{27E7}\x{27E8}\x{27E9}\x{27EA}\x{27EB}\x{27EC}\x{27ED}\x{27EE}\x{27EF}\x{27F0}-\x{27FF}\x{2900}-\x{2982}\x{2983}\x{2984}\x{2985}\x{2986}\x{2987}\x{2988}\x{2989}\x{298A}\x{298B}\x{298C}\x{298D}\x{298E}\x{298F}\x{2990}\x{2991}\x{2992}\x{2993}\x{2994}\x{2995}\x{2996}\x{2997}\x{2998}\x{2999}-\x{29D7}\x{29D8}\x{29D9}\x{29DA}\x{29DB}\x{29DC}-\x{29FB}\x{29FC}\x{29FD}\x{29FE}-\x{2AFF}\x{2B00}-\x{2B2F}\x{2B30}-\x{2B44}\x{2B45}-\x{2B46}\x{2B47}-\x{2B4C}\x{2B4D}-\x{2B73}\x{2B76}-\x{2B95}\x{2B97}-\x{2BFF}\x{2CE5}-\x{2CEA}\x{2CEF}-\x{2CF1}\x{2CF9}-\x{2CFC}\x{2CFD}\x{2CFE}-\x{2CFF}\x{2D7F}\x{2DE0}-\x{2DFF}\x{2E00}-\x{2E01}\x{2E02}\x{2E03}\x{2E04}\x{2E05}\x{2E06}-\x{2E08}\x{2E09}\x{2E0A}\x{2E0B}\x{2E0C}\x{2E0D}\x{2E0E}-\x{2E16}\x{2E17}\x{2E18}-\x{2E19}\x{2E1A}\x{2E1B}\x{2E1C}\x{2E1D}\x{2E1E}-\x{2E1F}\x{2E20}\x{2E21}\x{2E22}\x{2E23}\x{2E24}\x{2E25}\x{2E26}\x{2E27}\x{2E28}\x{2E29}\x{2E2A}-\x{2E2E}\x{2E2F}\x{2E30}-\x{2E39}\x{2E3A}-\x{2E3B}\x{2E3C}-\x{2E3F}\x{2E40}\x{2E41}\x{2E42}\x{2E43}-\x{2E4F}\x{2E50}-\x{2E51}\x{2E52}\x{2E80}-\x{2E99}\x{2E9B}-\x{2EF3}\x{2F00}-\x{2FD5}\x{2FF0}-\x{2FFB}\x{3000}\x{3001}-\x{3003}\x{3004}\x{3008}\x{3009}\x{300A}\x{300B}\x{300C}\x{300D}\x{300E}\x{300F}\x{3010}\x{3011}\x{3012}-\x{3013}\x{3014}\x{3015}\x{3016}\x{3017}\x{3018}\x{3019}\x{301A}\x{301B}\x{301C}\x{301D}\x{301E}-\x{301F}\x{3020}\x{302A}-\x{302D}\x{3030}\x{3036}-\x{3037}\x{303D}\x{303E}-\x{303F}\x{3099}-\x{309A}\x{309B}-\x{309C}\x{30A0}\x{30FB}\x{31C0}-\x{31E3}\x{321D}-\x{321E}\x{3250}\x{3251}-\x{325F}\x{327C}-\x{327E}\x{32B1}-\x{32BF}\x{32CC}-\x{32CF}\x{3377}-\x{337A}\x{33DE}-\x{33DF}\x{33FF}\x{4DC0}-\x{4DFF}\x{A490}-\x{A4C6}\x{A60D}-\x{A60F}\x{A66F}\x{A670}-\x{A672}\x{A673}\x{A674}-\x{A67D}\x{A67E}\x{A67F}\x{A69E}-\x{A69F}\x{A6F0}-\x{A6F1}\x{A700}-\x{A716}\x{A717}-\x{A71F}\x{A720}-\x{A721}\x{A788}\x{A802}\x{A806}\x{A80B}\x{A825}-\x{A826}\x{A828}-\x{A82B}\x{A82C}\x{A838}\x{A839}\x{A874}-\x{A877}\x{A8C4}-\x{A8C5}\x{A8E0}-\x{A8F1}\x{A8FF}\x{A926}-\x{A92D}\x{A947}-\x{A951}\x{A980}-\x{A982}\x{A9B3}\x{A9B6}-\x{A9B9}\x{A9BC}-\x{A9BD}\x{A9E5}\x{AA29}-\x{AA2E}\x{AA31}-\x{AA32}\x{AA35}-\x{AA36}\x{AA43}\x{AA4C}\x{AA7C}\x{AAB0}\x{AAB2}-\x{AAB4}\x{AAB7}-\x{AAB8}\x{AABE}-\x{AABF}\x{AAC1}\x{AAEC}-\x{AAED}\x{AAF6}\x{AB6A}-\x{AB6B}\x{ABE5}\x{ABE8}\x{ABED}\x{FB1D}\x{FB1E}\x{FB1F}-\x{FB28}\x{FB29}\x{FB2A}-\x{FB36}\x{FB37}\x{FB38}-\x{FB3C}\x{FB3D}\x{FB3E}\x{FB3F}\x{FB40}-\x{FB41}\x{FB42}\x{FB43}-\x{FB44}\x{FB45}\x{FB46}-\x{FB4F}\x{FB50}-\x{FBB1}\x{FBB2}-\x{FBC1}\x{FBC2}-\x{FBD2}\x{FBD3}-\x{FD3D}\x{FD3E}\x{FD3F}\x{FD40}-\x{FD4F}\x{FD50}-\x{FD8F}\x{FD90}-\x{FD91}\x{FD92}-\x{FDC7}\x{FDC8}-\x{FDCF}\x{FDD0}-\x{FDEF}\x{FDF0}-\x{FDFB}\x{FDFC}\x{FDFD}\x{FDFE}-\x{FDFF}\x{FE00}-\x{FE0F}\x{FE10}-\x{FE16}\x{FE17}\x{FE18}\x{FE19}\x{FE20}-\x{FE2F}\x{FE30}\x{FE31}-\x{FE32}\x{FE33}-\x{FE34}\x{FE35}\x{FE36}\x{FE37}\x{FE38}\x{FE39}\x{FE3A}\x{FE3B}\x{FE3C}\x{FE3D}\x{FE3E}\x{FE3F}\x{FE40}\x{FE41}\x{FE42}\x{FE43}\x{FE44}\x{FE45}-\x{FE46}\x{FE47}\x{FE48}\x{FE49}-\x{FE4C}\x{FE4D}-\x{FE4F}\x{FE50}\x{FE51}\x{FE52}\x{FE54}\x{FE55}\x{FE56}-\x{FE57}\x{FE58}\x{FE59}\x{FE5A}\x{FE5B}\x{FE5C}\x{FE5D}\x{FE5E}\x{FE5F}\x{FE60}-\x{FE61}\x{FE62}\x{FE63}\x{FE64}-\x{FE66}\x{FE68}\x{FE69}\x{FE6A}\x{FE6B}\x{FE70}-\x{FE74}\x{FE75}\x{FE76}-\x{FEFC}\x{FEFD}-\x{FEFE}\x{FEFF}\x{FF01}-\x{FF02}\x{FF03}\x{FF04}\x{FF05}\x{FF06}-\x{FF07}\x{FF08}\x{FF09}\x{FF0A}\x{FF0B}\x{FF0C}\x{FF0D}\x{FF0E}-\x{FF0F}\x{FF10}-\x{FF19}\x{FF1A}\x{FF1B}\x{FF1C}-\x{FF1E}\x{FF1F}-\x{FF20}\x{FF3B}\x{FF3C}\x{FF3D}\x{FF3E}\x{FF3F}\x{FF40}\x{FF5B}\x{FF5C}\x{FF5D}\x{FF5E}\x{FF5F}\x{FF60}\x{FF61}\x{FF62}\x{FF63}\x{FF64}-\x{FF65}\x{FFE0}-\x{FFE1}\x{FFE2}\x{FFE3}\x{FFE4}\x{FFE5}-\x{FFE6}\x{FFE8}\x{FFE9}-\x{FFEC}\x{FFED}-\x{FFEE}\x{FFF0}-\x{FFF8}\x{FFF9}-\x{FFFB}\x{FFFC}-\x{FFFD}\x{FFFE}-\x{FFFF}\x{10101}\x{10140}-\x{10174}\x{10175}-\x{10178}\x{10179}-\x{10189}\x{1018A}-\x{1018B}\x{1018C}\x{10190}-\x{1019C}\x{101A0}\x{101FD}\x{102E0}\x{102E1}-\x{102FB}\x{10376}-\x{1037A}\x{10800}-\x{10805}\x{10806}-\x{10807}\x{10808}\x{10809}\x{1080A}-\x{10835}\x{10836}\x{10837}-\x{10838}\x{10839}-\x{1083B}\x{1083C}\x{1083D}-\x{1083E}\x{1083F}-\x{10855}\x{10856}\x{10857}\x{10858}-\x{1085F}\x{10860}-\x{10876}\x{10877}-\x{10878}\x{10879}-\x{1087F}\x{10880}-\x{1089E}\x{1089F}-\x{108A6}\x{108A7}-\x{108AF}\x{108B0}-\x{108DF}\x{108E0}-\x{108F2}\x{108F3}\x{108F4}-\x{108F5}\x{108F6}-\x{108FA}\x{108FB}-\x{108FF}\x{10900}-\x{10915}\x{10916}-\x{1091B}\x{1091C}-\x{1091E}\x{1091F}\x{10920}-\x{10939}\x{1093A}-\x{1093E}\x{1093F}\x{10940}-\x{1097F}\x{10980}-\x{109B7}\x{109B8}-\x{109BB}\x{109BC}-\x{109BD}\x{109BE}-\x{109BF}\x{109C0}-\x{109CF}\x{109D0}-\x{109D1}\x{109D2}-\x{109FF}\x{10A00}\x{10A01}-\x{10A03}\x{10A04}\x{10A05}-\x{10A06}\x{10A07}-\x{10A0B}\x{10A0C}-\x{10A0F}\x{10A10}-\x{10A13}\x{10A14}\x{10A15}-\x{10A17}\x{10A18}\x{10A19}-\x{10A35}\x{10A36}-\x{10A37}\x{10A38}-\x{10A3A}\x{10A3B}-\x{10A3E}\x{10A3F}\x{10A40}-\x{10A48}\x{10A49}-\x{10A4F}\x{10A50}-\x{10A58}\x{10A59}-\x{10A5F}\x{10A60}-\x{10A7C}\x{10A7D}-\x{10A7E}\x{10A7F}\x{10A80}-\x{10A9C}\x{10A9D}-\x{10A9F}\x{10AA0}-\x{10ABF}\x{10AC0}-\x{10AC7}\x{10AC8}\x{10AC9}-\x{10AE4}\x{10AE5}-\x{10AE6}\x{10AE7}-\x{10AEA}\x{10AEB}-\x{10AEF}\x{10AF0}-\x{10AF6}\x{10AF7}-\x{10AFF}\x{10B00}-\x{10B35}\x{10B36}-\x{10B38}\x{10B39}-\x{10B3F}\x{10B40}-\x{10B55}\x{10B56}-\x{10B57}\x{10B58}-\x{10B5F}\x{10B60}-\x{10B72}\x{10B73}-\x{10B77}\x{10B78}-\x{10B7F}\x{10B80}-\x{10B91}\x{10B92}-\x{10B98}\x{10B99}-\x{10B9C}\x{10B9D}-\x{10BA8}\x{10BA9}-\x{10BAF}\x{10BB0}-\x{10BFF}\x{10C00}-\x{10C48}\x{10C49}-\x{10C7F}\x{10C80}-\x{10CB2}\x{10CB3}-\x{10CBF}\x{10CC0}-\x{10CF2}\x{10CF3}-\x{10CF9}\x{10CFA}-\x{10CFF}\x{10D00}-\x{10D23}\x{10D24}-\x{10D27}\x{10D28}-\x{10D2F}\x{10D30}-\x{10D39}\x{10D3A}-\x{10D3F}\x{10D40}-\x{10E5F}\x{10E60}-\x{10E7E}\x{10E7F}\x{10E80}-\x{10EA9}\x{10EAA}\x{10EAB}-\x{10EAC}\x{10EAD}\x{10EAE}-\x{10EAF}\x{10EB0}-\x{10EB1}\x{10EB2}-\x{10EFF}\x{10F00}-\x{10F1C}\x{10F1D}-\x{10F26}\x{10F27}\x{10F28}-\x{10F2F}\x{10F30}-\x{10F45}\x{10F46}-\x{10F50}\x{10F51}-\x{10F54}\x{10F55}-\x{10F59}\x{10F5A}-\x{10F6F}\x{10F70}-\x{10FAF}\x{10FB0}-\x{10FC4}\x{10FC5}-\x{10FCB}\x{10FCC}-\x{10FDF}\x{10FE0}-\x{10FF6}\x{10FF7}-\x{10FFF}\x{11001}\x{11038}-\x{11046}\x{11052}-\x{11065}\x{1107F}-\x{11081}\x{110B3}-\x{110B6}\x{110B9}-\x{110BA}\x{11100}-\x{11102}\x{11127}-\x{1112B}\x{1112D}-\x{11134}\x{11173}\x{11180}-\x{11181}\x{111B6}-\x{111BE}\x{111C9}-\x{111CC}\x{111CF}\x{1122F}-\x{11231}\x{11234}\x{11236}-\x{11237}\x{1123E}\x{112DF}\x{112E3}-\x{112EA}\x{11300}-\x{11301}\x{1133B}-\x{1133C}\x{11340}\x{11366}-\x{1136C}\x{11370}-\x{11374}\x{11438}-\x{1143F}\x{11442}-\x{11444}\x{11446}\x{1145E}\x{114B3}-\x{114B8}\x{114BA}\x{114BF}-\x{114C0}\x{114C2}-\x{114C3}\x{115B2}-\x{115B5}\x{115BC}-\x{115BD}\x{115BF}-\x{115C0}\x{115DC}-\x{115DD}\x{11633}-\x{1163A}\x{1163D}\x{1163F}-\x{11640}\x{11660}-\x{1166C}\x{116AB}\x{116AD}\x{116B0}-\x{116B5}\x{116B7}\x{1171D}-\x{1171F}\x{11722}-\x{11725}\x{11727}-\x{1172B}\x{1182F}-\x{11837}\x{11839}-\x{1183A}\x{1193B}-\x{1193C}\x{1193E}\x{11943}\x{119D4}-\x{119D7}\x{119DA}-\x{119DB}\x{119E0}\x{11A01}-\x{11A06}\x{11A09}-\x{11A0A}\x{11A33}-\x{11A38}\x{11A3B}-\x{11A3E}\x{11A47}\x{11A51}-\x{11A56}\x{11A59}-\x{11A5B}\x{11A8A}-\x{11A96}\x{11A98}-\x{11A99}\x{11C30}-\x{11C36}\x{11C38}-\x{11C3D}\x{11C92}-\x{11CA7}\x{11CAA}-\x{11CB0}\x{11CB2}-\x{11CB3}\x{11CB5}-\x{11CB6}\x{11D31}-\x{11D36}\x{11D3A}\x{11D3C}-\x{11D3D}\x{11D3F}-\x{11D45}\x{11D47}\x{11D90}-\x{11D91}\x{11D95}\x{11D97}\x{11EF3}-\x{11EF4}\x{11FD5}-\x{11FDC}\x{11FDD}-\x{11FE0}\x{11FE1}-\x{11FF1}\x{16AF0}-\x{16AF4}\x{16B30}-\x{16B36}\x{16F4F}\x{16F8F}-\x{16F92}\x{16FE2}\x{16FE4}\x{1BC9D}-\x{1BC9E}\x{1BCA0}-\x{1BCA3}\x{1D167}-\x{1D169}\x{1D173}-\x{1D17A}\x{1D17B}-\x{1D182}\x{1D185}-\x{1D18B}\x{1D1AA}-\x{1D1AD}\x{1D200}-\x{1D241}\x{1D242}-\x{1D244}\x{1D245}\x{1D300}-\x{1D356}\x{1D6DB}\x{1D715}\x{1D74F}\x{1D789}\x{1D7C3}\x{1D7CE}-\x{1D7FF}\x{1DA00}-\x{1DA36}\x{1DA3B}-\x{1DA6C}\x{1DA75}\x{1DA84}\x{1DA9B}-\x{1DA9F}\x{1DAA1}-\x{1DAAF}\x{1E000}-\x{1E006}\x{1E008}-\x{1E018}\x{1E01B}-\x{1E021}\x{1E023}-\x{1E024}\x{1E026}-\x{1E02A}\x{1E130}-\x{1E136}\x{1E2EC}-\x{1E2EF}\x{1E2FF}\x{1E800}-\x{1E8C4}\x{1E8C5}-\x{1E8C6}\x{1E8C7}-\x{1E8CF}\x{1E8D0}-\x{1E8D6}\x{1E8D7}-\x{1E8FF}\x{1E900}-\x{1E943}\x{1E944}-\x{1E94A}\x{1E94B}\x{1E94C}-\x{1E94F}\x{1E950}-\x{1E959}\x{1E95A}-\x{1E95D}\x{1E95E}-\x{1E95F}\x{1E960}-\x{1EC6F}\x{1EC70}\x{1EC71}-\x{1ECAB}\x{1ECAC}\x{1ECAD}-\x{1ECAF}\x{1ECB0}\x{1ECB1}-\x{1ECB4}\x{1ECB5}-\x{1ECBF}\x{1ECC0}-\x{1ECFF}\x{1ED00}\x{1ED01}-\x{1ED2D}\x{1ED2E}\x{1ED2F}-\x{1ED3D}\x{1ED3E}-\x{1ED4F}\x{1ED50}-\x{1EDFF}\x{1EE00}-\x{1EE03}\x{1EE04}\x{1EE05}-\x{1EE1F}\x{1EE20}\x{1EE21}-\x{1EE22}\x{1EE23}\x{1EE24}\x{1EE25}-\x{1EE26}\x{1EE27}\x{1EE28}\x{1EE29}-\x{1EE32}\x{1EE33}\x{1EE34}-\x{1EE37}\x{1EE38}\x{1EE39}\x{1EE3A}\x{1EE3B}\x{1EE3C}-\x{1EE41}\x{1EE42}\x{1EE43}-\x{1EE46}\x{1EE47}\x{1EE48}\x{1EE49}\x{1EE4A}\x{1EE4B}\x{1EE4C}\x{1EE4D}-\x{1EE4F}\x{1EE50}\x{1EE51}-\x{1EE52}\x{1EE53}\x{1EE54}\x{1EE55}-\x{1EE56}\x{1EE57}\x{1EE58}\x{1EE59}\x{1EE5A}\x{1EE5B}\x{1EE5C}\x{1EE5D}\x{1EE5E}\x{1EE5F}\x{1EE60}\x{1EE61}-\x{1EE62}\x{1EE63}\x{1EE64}\x{1EE65}-\x{1EE66}\x{1EE67}-\x{1EE6A}\x{1EE6B}\x{1EE6C}-\x{1EE72}\x{1EE73}\x{1EE74}-\x{1EE77}\x{1EE78}\x{1EE79}-\x{1EE7C}\x{1EE7D}\x{1EE7E}\x{1EE7F}\x{1EE80}-\x{1EE89}\x{1EE8A}\x{1EE8B}-\x{1EE9B}\x{1EE9C}-\x{1EEA0}\x{1EEA1}-\x{1EEA3}\x{1EEA4}\x{1EEA5}-\x{1EEA9}\x{1EEAA}\x{1EEAB}-\x{1EEBB}\x{1EEBC}-\x{1EEEF}\x{1EEF0}-\x{1EEF1}\x{1EEF2}-\x{1EEFF}\x{1EF00}-\x{1EFFF}\x{1F000}-\x{1F02B}\x{1F030}-\x{1F093}\x{1F0A0}-\x{1F0AE}\x{1F0B1}-\x{1F0BF}\x{1F0C1}-\x{1F0CF}\x{1F0D1}-\x{1F0F5}\x{1F100}-\x{1F10A}\x{1F10B}-\x{1F10C}\x{1F10D}-\x{1F10F}\x{1F12F}\x{1F16A}-\x{1F16F}\x{1F1AD}\x{1F260}-\x{1F265}\x{1F300}-\x{1F3FA}\x{1F3FB}-\x{1F3FF}\x{1F400}-\x{1F6D7}\x{1F6E0}-\x{1F6EC}\x{1F6F0}-\x{1F6FC}\x{1F700}-\x{1F773}\x{1F780}-\x{1F7D8}\x{1F7E0}-\x{1F7EB}\x{1F800}-\x{1F80B}\x{1F810}-\x{1F847}\x{1F850}-\x{1F859}\x{1F860}-\x{1F887}\x{1F890}-\x{1F8AD}\x{1F8B0}-\x{1F8B1}\x{1F900}-\x{1F978}\x{1F97A}-\x{1F9CB}\x{1F9CD}-\x{1FA53}\x{1FA60}-\x{1FA6D}\x{1FA70}-\x{1FA74}\x{1FA78}-\x{1FA7A}\x{1FA80}-\x{1FA86}\x{1FA90}-\x{1FAA8}\x{1FAB0}-\x{1FAB6}\x{1FAC0}-\x{1FAC2}\x{1FAD0}-\x{1FAD6}\x{1FB00}-\x{1FB92}\x{1FB94}-\x{1FBCA}\x{1FBF0}-\x{1FBF9}\x{1FFFE}-\x{1FFFF}\x{2FFFE}-\x{2FFFF}\x{3FFFE}-\x{3FFFF}\x{4FFFE}-\x{4FFFF}\x{5FFFE}-\x{5FFFF}\x{6FFFE}-\x{6FFFF}\x{7FFFE}-\x{7FFFF}\x{8FFFE}-\x{8FFFF}\x{9FFFE}-\x{9FFFF}\x{AFFFE}-\x{AFFFF}\x{BFFFE}-\x{BFFFF}\x{CFFFE}-\x{CFFFF}\x{DFFFE}-\x{E0000}\x{E0001}\x{E0002}-\x{E001F}\x{E0020}-\x{E007F}\x{E0080}-\x{E00FF}\x{E0100}-\x{E01EF}\x{E01F0}-\x{E0FFF}\x{EFFFE}-\x{EFFFF}\x{FFFFE}-\x{FFFFF}\x{10FFFE}-\x{10FFFF}]/u';
    const BIDI_STEP_1_RTL = '/^[\x{0590}\x{05BE}\x{05C0}\x{05C3}\x{05C6}\x{05C8}-\x{05CF}\x{05D0}-\x{05EA}\x{05EB}-\x{05EE}\x{05EF}-\x{05F2}\x{05F3}-\x{05F4}\x{05F5}-\x{05FF}\x{0608}\x{060B}\x{060D}\x{061B}\x{061C}\x{061D}\x{061E}-\x{061F}\x{0620}-\x{063F}\x{0640}\x{0641}-\x{064A}\x{066D}\x{066E}-\x{066F}\x{0671}-\x{06D3}\x{06D4}\x{06D5}\x{06E5}-\x{06E6}\x{06EE}-\x{06EF}\x{06FA}-\x{06FC}\x{06FD}-\x{06FE}\x{06FF}\x{0700}-\x{070D}\x{070E}\x{070F}\x{0710}\x{0712}-\x{072F}\x{074B}-\x{074C}\x{074D}-\x{07A5}\x{07B1}\x{07B2}-\x{07BF}\x{07C0}-\x{07C9}\x{07CA}-\x{07EA}\x{07F4}-\x{07F5}\x{07FA}\x{07FB}-\x{07FC}\x{07FE}-\x{07FF}\x{0800}-\x{0815}\x{081A}\x{0824}\x{0828}\x{082E}-\x{082F}\x{0830}-\x{083E}\x{083F}\x{0840}-\x{0858}\x{085C}-\x{085D}\x{085E}\x{085F}\x{0860}-\x{086A}\x{086B}-\x{086F}\x{0870}-\x{089F}\x{08A0}-\x{08B4}\x{08B5}\x{08B6}-\x{08C7}\x{08C8}-\x{08D2}\x{200F}\x{FB1D}\x{FB1F}-\x{FB28}\x{FB2A}-\x{FB36}\x{FB37}\x{FB38}-\x{FB3C}\x{FB3D}\x{FB3E}\x{FB3F}\x{FB40}-\x{FB41}\x{FB42}\x{FB43}-\x{FB44}\x{FB45}\x{FB46}-\x{FB4F}\x{FB50}-\x{FBB1}\x{FBB2}-\x{FBC1}\x{FBC2}-\x{FBD2}\x{FBD3}-\x{FD3D}\x{FD40}-\x{FD4F}\x{FD50}-\x{FD8F}\x{FD90}-\x{FD91}\x{FD92}-\x{FDC7}\x{FDC8}-\x{FDCF}\x{FDF0}-\x{FDFB}\x{FDFC}\x{FDFE}-\x{FDFF}\x{FE70}-\x{FE74}\x{FE75}\x{FE76}-\x{FEFC}\x{FEFD}-\x{FEFE}\x{10800}-\x{10805}\x{10806}-\x{10807}\x{10808}\x{10809}\x{1080A}-\x{10835}\x{10836}\x{10837}-\x{10838}\x{10839}-\x{1083B}\x{1083C}\x{1083D}-\x{1083E}\x{1083F}-\x{10855}\x{10856}\x{10857}\x{10858}-\x{1085F}\x{10860}-\x{10876}\x{10877}-\x{10878}\x{10879}-\x{1087F}\x{10880}-\x{1089E}\x{1089F}-\x{108A6}\x{108A7}-\x{108AF}\x{108B0}-\x{108DF}\x{108E0}-\x{108F2}\x{108F3}\x{108F4}-\x{108F5}\x{108F6}-\x{108FA}\x{108FB}-\x{108FF}\x{10900}-\x{10915}\x{10916}-\x{1091B}\x{1091C}-\x{1091E}\x{10920}-\x{10939}\x{1093A}-\x{1093E}\x{1093F}\x{10940}-\x{1097F}\x{10980}-\x{109B7}\x{109B8}-\x{109BB}\x{109BC}-\x{109BD}\x{109BE}-\x{109BF}\x{109C0}-\x{109CF}\x{109D0}-\x{109D1}\x{109D2}-\x{109FF}\x{10A00}\x{10A04}\x{10A07}-\x{10A0B}\x{10A10}-\x{10A13}\x{10A14}\x{10A15}-\x{10A17}\x{10A18}\x{10A19}-\x{10A35}\x{10A36}-\x{10A37}\x{10A3B}-\x{10A3E}\x{10A40}-\x{10A48}\x{10A49}-\x{10A4F}\x{10A50}-\x{10A58}\x{10A59}-\x{10A5F}\x{10A60}-\x{10A7C}\x{10A7D}-\x{10A7E}\x{10A7F}\x{10A80}-\x{10A9C}\x{10A9D}-\x{10A9F}\x{10AA0}-\x{10ABF}\x{10AC0}-\x{10AC7}\x{10AC8}\x{10AC9}-\x{10AE4}\x{10AE7}-\x{10AEA}\x{10AEB}-\x{10AEF}\x{10AF0}-\x{10AF6}\x{10AF7}-\x{10AFF}\x{10B00}-\x{10B35}\x{10B36}-\x{10B38}\x{10B40}-\x{10B55}\x{10B56}-\x{10B57}\x{10B58}-\x{10B5F}\x{10B60}-\x{10B72}\x{10B73}-\x{10B77}\x{10B78}-\x{10B7F}\x{10B80}-\x{10B91}\x{10B92}-\x{10B98}\x{10B99}-\x{10B9C}\x{10B9D}-\x{10BA8}\x{10BA9}-\x{10BAF}\x{10BB0}-\x{10BFF}\x{10C00}-\x{10C48}\x{10C49}-\x{10C7F}\x{10C80}-\x{10CB2}\x{10CB3}-\x{10CBF}\x{10CC0}-\x{10CF2}\x{10CF3}-\x{10CF9}\x{10CFA}-\x{10CFF}\x{10D00}-\x{10D23}\x{10D28}-\x{10D2F}\x{10D3A}-\x{10D3F}\x{10D40}-\x{10E5F}\x{10E7F}\x{10E80}-\x{10EA9}\x{10EAA}\x{10EAD}\x{10EAE}-\x{10EAF}\x{10EB0}-\x{10EB1}\x{10EB2}-\x{10EFF}\x{10F00}-\x{10F1C}\x{10F1D}-\x{10F26}\x{10F27}\x{10F28}-\x{10F2F}\x{10F30}-\x{10F45}\x{10F51}-\x{10F54}\x{10F55}-\x{10F59}\x{10F5A}-\x{10F6F}\x{10F70}-\x{10FAF}\x{10FB0}-\x{10FC4}\x{10FC5}-\x{10FCB}\x{10FCC}-\x{10FDF}\x{10FE0}-\x{10FF6}\x{10FF7}-\x{10FFF}\x{1E800}-\x{1E8C4}\x{1E8C5}-\x{1E8C6}\x{1E8C7}-\x{1E8CF}\x{1E8D7}-\x{1E8FF}\x{1E900}-\x{1E943}\x{1E94B}\x{1E94C}-\x{1E94F}\x{1E950}-\x{1E959}\x{1E95A}-\x{1E95D}\x{1E95E}-\x{1E95F}\x{1E960}-\x{1EC6F}\x{1EC70}\x{1EC71}-\x{1ECAB}\x{1ECAC}\x{1ECAD}-\x{1ECAF}\x{1ECB0}\x{1ECB1}-\x{1ECB4}\x{1ECB5}-\x{1ECBF}\x{1ECC0}-\x{1ECFF}\x{1ED00}\x{1ED01}-\x{1ED2D}\x{1ED2E}\x{1ED2F}-\x{1ED3D}\x{1ED3E}-\x{1ED4F}\x{1ED50}-\x{1EDFF}\x{1EE00}-\x{1EE03}\x{1EE04}\x{1EE05}-\x{1EE1F}\x{1EE20}\x{1EE21}-\x{1EE22}\x{1EE23}\x{1EE24}\x{1EE25}-\x{1EE26}\x{1EE27}\x{1EE28}\x{1EE29}-\x{1EE32}\x{1EE33}\x{1EE34}-\x{1EE37}\x{1EE38}\x{1EE39}\x{1EE3A}\x{1EE3B}\x{1EE3C}-\x{1EE41}\x{1EE42}\x{1EE43}-\x{1EE46}\x{1EE47}\x{1EE48}\x{1EE49}\x{1EE4A}\x{1EE4B}\x{1EE4C}\x{1EE4D}-\x{1EE4F}\x{1EE50}\x{1EE51}-\x{1EE52}\x{1EE53}\x{1EE54}\x{1EE55}-\x{1EE56}\x{1EE57}\x{1EE58}\x{1EE59}\x{1EE5A}\x{1EE5B}\x{1EE5C}\x{1EE5D}\x{1EE5E}\x{1EE5F}\x{1EE60}\x{1EE61}-\x{1EE62}\x{1EE63}\x{1EE64}\x{1EE65}-\x{1EE66}\x{1EE67}-\x{1EE6A}\x{1EE6B}\x{1EE6C}-\x{1EE72}\x{1EE73}\x{1EE74}-\x{1EE77}\x{1EE78}\x{1EE79}-\x{1EE7C}\x{1EE7D}\x{1EE7E}\x{1EE7F}\x{1EE80}-\x{1EE89}\x{1EE8A}\x{1EE8B}-\x{1EE9B}\x{1EE9C}-\x{1EEA0}\x{1EEA1}-\x{1EEA3}\x{1EEA4}\x{1EEA5}-\x{1EEA9}\x{1EEAA}\x{1EEAB}-\x{1EEBB}\x{1EEBC}-\x{1EEEF}\x{1EEF2}-\x{1EEFF}\x{1EF00}-\x{1EFFF}]/u';
    const BIDI_STEP_2 = '/[^\x{0000}-\x{0008}\x{000E}-\x{001B}\x{0021}-\x{0022}\x{0023}\x{0024}\x{0025}\x{0026}-\x{0027}\x{0028}\x{0029}\x{002A}\x{002B}\x{002C}\x{002D}\x{002E}-\x{002F}\x{0030}-\x{0039}\x{003A}\x{003B}\x{003C}-\x{003E}\x{003F}-\x{0040}\x{005B}\x{005C}\x{005D}\x{005E}\x{005F}\x{0060}\x{007B}\x{007C}\x{007D}\x{007E}\x{007F}-\x{0084}\x{0086}-\x{009F}\x{00A0}\x{00A1}\x{00A2}-\x{00A5}\x{00A6}\x{00A7}\x{00A8}\x{00A9}\x{00AB}\x{00AC}\x{00AD}\x{00AE}\x{00AF}\x{00B0}\x{00B1}\x{00B2}-\x{00B3}\x{00B4}\x{00B6}-\x{00B7}\x{00B8}\x{00B9}\x{00BB}\x{00BC}-\x{00BE}\x{00BF}\x{00D7}\x{00F7}\x{02B9}-\x{02BA}\x{02C2}-\x{02C5}\x{02C6}-\x{02CF}\x{02D2}-\x{02DF}\x{02E5}-\x{02EB}\x{02EC}\x{02ED}\x{02EF}-\x{02FF}\x{0300}-\x{036F}\x{0374}\x{0375}\x{037E}\x{0384}-\x{0385}\x{0387}\x{03F6}\x{0483}-\x{0487}\x{0488}-\x{0489}\x{058A}\x{058D}-\x{058E}\x{058F}\x{0590}\x{0591}-\x{05BD}\x{05BE}\x{05BF}\x{05C0}\x{05C1}-\x{05C2}\x{05C3}\x{05C4}-\x{05C5}\x{05C6}\x{05C7}\x{05C8}-\x{05CF}\x{05D0}-\x{05EA}\x{05EB}-\x{05EE}\x{05EF}-\x{05F2}\x{05F3}-\x{05F4}\x{05F5}-\x{05FF}\x{0600}-\x{0605}\x{0606}-\x{0607}\x{0608}\x{0609}-\x{060A}\x{060B}\x{060C}\x{060D}\x{060E}-\x{060F}\x{0610}-\x{061A}\x{061B}\x{061C}\x{061D}\x{061E}-\x{061F}\x{0620}-\x{063F}\x{0640}\x{0641}-\x{064A}\x{064B}-\x{065F}\x{0660}-\x{0669}\x{066A}\x{066B}-\x{066C}\x{066D}\x{066E}-\x{066F}\x{0670}\x{0671}-\x{06D3}\x{06D4}\x{06D5}\x{06D6}-\x{06DC}\x{06DD}\x{06DE}\x{06DF}-\x{06E4}\x{06E5}-\x{06E6}\x{06E7}-\x{06E8}\x{06E9}\x{06EA}-\x{06ED}\x{06EE}-\x{06EF}\x{06F0}-\x{06F9}\x{06FA}-\x{06FC}\x{06FD}-\x{06FE}\x{06FF}\x{0700}-\x{070D}\x{070E}\x{070F}\x{0710}\x{0711}\x{0712}-\x{072F}\x{0730}-\x{074A}\x{074B}-\x{074C}\x{074D}-\x{07A5}\x{07A6}-\x{07B0}\x{07B1}\x{07B2}-\x{07BF}\x{07C0}-\x{07C9}\x{07CA}-\x{07EA}\x{07EB}-\x{07F3}\x{07F4}-\x{07F5}\x{07F6}\x{07F7}-\x{07F9}\x{07FA}\x{07FB}-\x{07FC}\x{07FD}\x{07FE}-\x{07FF}\x{0800}-\x{0815}\x{0816}-\x{0819}\x{081A}\x{081B}-\x{0823}\x{0824}\x{0825}-\x{0827}\x{0828}\x{0829}-\x{082D}\x{082E}-\x{082F}\x{0830}-\x{083E}\x{083F}\x{0840}-\x{0858}\x{0859}-\x{085B}\x{085C}-\x{085D}\x{085E}\x{085F}\x{0860}-\x{086A}\x{086B}-\x{086F}\x{0870}-\x{089F}\x{08A0}-\x{08B4}\x{08B5}\x{08B6}-\x{08C7}\x{08C8}-\x{08D2}\x{08D3}-\x{08E1}\x{08E2}\x{08E3}-\x{0902}\x{093A}\x{093C}\x{0941}-\x{0948}\x{094D}\x{0951}-\x{0957}\x{0962}-\x{0963}\x{0981}\x{09BC}\x{09C1}-\x{09C4}\x{09CD}\x{09E2}-\x{09E3}\x{09F2}-\x{09F3}\x{09FB}\x{09FE}\x{0A01}-\x{0A02}\x{0A3C}\x{0A41}-\x{0A42}\x{0A47}-\x{0A48}\x{0A4B}-\x{0A4D}\x{0A51}\x{0A70}-\x{0A71}\x{0A75}\x{0A81}-\x{0A82}\x{0ABC}\x{0AC1}-\x{0AC5}\x{0AC7}-\x{0AC8}\x{0ACD}\x{0AE2}-\x{0AE3}\x{0AF1}\x{0AFA}-\x{0AFF}\x{0B01}\x{0B3C}\x{0B3F}\x{0B41}-\x{0B44}\x{0B4D}\x{0B55}-\x{0B56}\x{0B62}-\x{0B63}\x{0B82}\x{0BC0}\x{0BCD}\x{0BF3}-\x{0BF8}\x{0BF9}\x{0BFA}\x{0C00}\x{0C04}\x{0C3E}-\x{0C40}\x{0C46}-\x{0C48}\x{0C4A}-\x{0C4D}\x{0C55}-\x{0C56}\x{0C62}-\x{0C63}\x{0C78}-\x{0C7E}\x{0C81}\x{0CBC}\x{0CCC}-\x{0CCD}\x{0CE2}-\x{0CE3}\x{0D00}-\x{0D01}\x{0D3B}-\x{0D3C}\x{0D41}-\x{0D44}\x{0D4D}\x{0D62}-\x{0D63}\x{0D81}\x{0DCA}\x{0DD2}-\x{0DD4}\x{0DD6}\x{0E31}\x{0E34}-\x{0E3A}\x{0E3F}\x{0E47}-\x{0E4E}\x{0EB1}\x{0EB4}-\x{0EBC}\x{0EC8}-\x{0ECD}\x{0F18}-\x{0F19}\x{0F35}\x{0F37}\x{0F39}\x{0F3A}\x{0F3B}\x{0F3C}\x{0F3D}\x{0F71}-\x{0F7E}\x{0F80}-\x{0F84}\x{0F86}-\x{0F87}\x{0F8D}-\x{0F97}\x{0F99}-\x{0FBC}\x{0FC6}\x{102D}-\x{1030}\x{1032}-\x{1037}\x{1039}-\x{103A}\x{103D}-\x{103E}\x{1058}-\x{1059}\x{105E}-\x{1060}\x{1071}-\x{1074}\x{1082}\x{1085}-\x{1086}\x{108D}\x{109D}\x{135D}-\x{135F}\x{1390}-\x{1399}\x{1400}\x{169B}\x{169C}\x{1712}-\x{1714}\x{1732}-\x{1734}\x{1752}-\x{1753}\x{1772}-\x{1773}\x{17B4}-\x{17B5}\x{17B7}-\x{17BD}\x{17C6}\x{17C9}-\x{17D3}\x{17DB}\x{17DD}\x{17F0}-\x{17F9}\x{1800}-\x{1805}\x{1806}\x{1807}-\x{180A}\x{180B}-\x{180D}\x{180E}\x{1885}-\x{1886}\x{18A9}\x{1920}-\x{1922}\x{1927}-\x{1928}\x{1932}\x{1939}-\x{193B}\x{1940}\x{1944}-\x{1945}\x{19DE}-\x{19FF}\x{1A17}-\x{1A18}\x{1A1B}\x{1A56}\x{1A58}-\x{1A5E}\x{1A60}\x{1A62}\x{1A65}-\x{1A6C}\x{1A73}-\x{1A7C}\x{1A7F}\x{1AB0}-\x{1ABD}\x{1ABE}\x{1ABF}-\x{1AC0}\x{1B00}-\x{1B03}\x{1B34}\x{1B36}-\x{1B3A}\x{1B3C}\x{1B42}\x{1B6B}-\x{1B73}\x{1B80}-\x{1B81}\x{1BA2}-\x{1BA5}\x{1BA8}-\x{1BA9}\x{1BAB}-\x{1BAD}\x{1BE6}\x{1BE8}-\x{1BE9}\x{1BED}\x{1BEF}-\x{1BF1}\x{1C2C}-\x{1C33}\x{1C36}-\x{1C37}\x{1CD0}-\x{1CD2}\x{1CD4}-\x{1CE0}\x{1CE2}-\x{1CE8}\x{1CED}\x{1CF4}\x{1CF8}-\x{1CF9}\x{1DC0}-\x{1DF9}\x{1DFB}-\x{1DFF}\x{1FBD}\x{1FBF}-\x{1FC1}\x{1FCD}-\x{1FCF}\x{1FDD}-\x{1FDF}\x{1FED}-\x{1FEF}\x{1FFD}-\x{1FFE}\x{200B}-\x{200D}\x{200F}\x{2010}-\x{2015}\x{2016}-\x{2017}\x{2018}\x{2019}\x{201A}\x{201B}-\x{201C}\x{201D}\x{201E}\x{201F}\x{2020}-\x{2027}\x{202F}\x{2030}-\x{2034}\x{2035}-\x{2038}\x{2039}\x{203A}\x{203B}-\x{203E}\x{203F}-\x{2040}\x{2041}-\x{2043}\x{2044}\x{2045}\x{2046}\x{2047}-\x{2051}\x{2052}\x{2053}\x{2054}\x{2055}-\x{205E}\x{2060}-\x{2064}\x{2065}\x{206A}-\x{206F}\x{2070}\x{2074}-\x{2079}\x{207A}-\x{207B}\x{207C}\x{207D}\x{207E}\x{2080}-\x{2089}\x{208A}-\x{208B}\x{208C}\x{208D}\x{208E}\x{20A0}-\x{20BF}\x{20C0}-\x{20CF}\x{20D0}-\x{20DC}\x{20DD}-\x{20E0}\x{20E1}\x{20E2}-\x{20E4}\x{20E5}-\x{20F0}\x{2100}-\x{2101}\x{2103}-\x{2106}\x{2108}-\x{2109}\x{2114}\x{2116}-\x{2117}\x{2118}\x{211E}-\x{2123}\x{2125}\x{2127}\x{2129}\x{212E}\x{213A}-\x{213B}\x{2140}-\x{2144}\x{214A}\x{214B}\x{214C}-\x{214D}\x{2150}-\x{215F}\x{2189}\x{218A}-\x{218B}\x{2190}-\x{2194}\x{2195}-\x{2199}\x{219A}-\x{219B}\x{219C}-\x{219F}\x{21A0}\x{21A1}-\x{21A2}\x{21A3}\x{21A4}-\x{21A5}\x{21A6}\x{21A7}-\x{21AD}\x{21AE}\x{21AF}-\x{21CD}\x{21CE}-\x{21CF}\x{21D0}-\x{21D1}\x{21D2}\x{21D3}\x{21D4}\x{21D5}-\x{21F3}\x{21F4}-\x{2211}\x{2212}\x{2213}\x{2214}-\x{22FF}\x{2300}-\x{2307}\x{2308}\x{2309}\x{230A}\x{230B}\x{230C}-\x{231F}\x{2320}-\x{2321}\x{2322}-\x{2328}\x{2329}\x{232A}\x{232B}-\x{2335}\x{237B}\x{237C}\x{237D}-\x{2394}\x{2396}-\x{239A}\x{239B}-\x{23B3}\x{23B4}-\x{23DB}\x{23DC}-\x{23E1}\x{23E2}-\x{2426}\x{2440}-\x{244A}\x{2460}-\x{2487}\x{2488}-\x{249B}\x{24EA}-\x{24FF}\x{2500}-\x{25B6}\x{25B7}\x{25B8}-\x{25C0}\x{25C1}\x{25C2}-\x{25F7}\x{25F8}-\x{25FF}\x{2600}-\x{266E}\x{266F}\x{2670}-\x{26AB}\x{26AD}-\x{2767}\x{2768}\x{2769}\x{276A}\x{276B}\x{276C}\x{276D}\x{276E}\x{276F}\x{2770}\x{2771}\x{2772}\x{2773}\x{2774}\x{2775}\x{2776}-\x{2793}\x{2794}-\x{27BF}\x{27C0}-\x{27C4}\x{27C5}\x{27C6}\x{27C7}-\x{27E5}\x{27E6}\x{27E7}\x{27E8}\x{27E9}\x{27EA}\x{27EB}\x{27EC}\x{27ED}\x{27EE}\x{27EF}\x{27F0}-\x{27FF}\x{2900}-\x{2982}\x{2983}\x{2984}\x{2985}\x{2986}\x{2987}\x{2988}\x{2989}\x{298A}\x{298B}\x{298C}\x{298D}\x{298E}\x{298F}\x{2990}\x{2991}\x{2992}\x{2993}\x{2994}\x{2995}\x{2996}\x{2997}\x{2998}\x{2999}-\x{29D7}\x{29D8}\x{29D9}\x{29DA}\x{29DB}\x{29DC}-\x{29FB}\x{29FC}\x{29FD}\x{29FE}-\x{2AFF}\x{2B00}-\x{2B2F}\x{2B30}-\x{2B44}\x{2B45}-\x{2B46}\x{2B47}-\x{2B4C}\x{2B4D}-\x{2B73}\x{2B76}-\x{2B95}\x{2B97}-\x{2BFF}\x{2CE5}-\x{2CEA}\x{2CEF}-\x{2CF1}\x{2CF9}-\x{2CFC}\x{2CFD}\x{2CFE}-\x{2CFF}\x{2D7F}\x{2DE0}-\x{2DFF}\x{2E00}-\x{2E01}\x{2E02}\x{2E03}\x{2E04}\x{2E05}\x{2E06}-\x{2E08}\x{2E09}\x{2E0A}\x{2E0B}\x{2E0C}\x{2E0D}\x{2E0E}-\x{2E16}\x{2E17}\x{2E18}-\x{2E19}\x{2E1A}\x{2E1B}\x{2E1C}\x{2E1D}\x{2E1E}-\x{2E1F}\x{2E20}\x{2E21}\x{2E22}\x{2E23}\x{2E24}\x{2E25}\x{2E26}\x{2E27}\x{2E28}\x{2E29}\x{2E2A}-\x{2E2E}\x{2E2F}\x{2E30}-\x{2E39}\x{2E3A}-\x{2E3B}\x{2E3C}-\x{2E3F}\x{2E40}\x{2E41}\x{2E42}\x{2E43}-\x{2E4F}\x{2E50}-\x{2E51}\x{2E52}\x{2E80}-\x{2E99}\x{2E9B}-\x{2EF3}\x{2F00}-\x{2FD5}\x{2FF0}-\x{2FFB}\x{3001}-\x{3003}\x{3004}\x{3008}\x{3009}\x{300A}\x{300B}\x{300C}\x{300D}\x{300E}\x{300F}\x{3010}\x{3011}\x{3012}-\x{3013}\x{3014}\x{3015}\x{3016}\x{3017}\x{3018}\x{3019}\x{301A}\x{301B}\x{301C}\x{301D}\x{301E}-\x{301F}\x{3020}\x{302A}-\x{302D}\x{3030}\x{3036}-\x{3037}\x{303D}\x{303E}-\x{303F}\x{3099}-\x{309A}\x{309B}-\x{309C}\x{30A0}\x{30FB}\x{31C0}-\x{31E3}\x{321D}-\x{321E}\x{3250}\x{3251}-\x{325F}\x{327C}-\x{327E}\x{32B1}-\x{32BF}\x{32CC}-\x{32CF}\x{3377}-\x{337A}\x{33DE}-\x{33DF}\x{33FF}\x{4DC0}-\x{4DFF}\x{A490}-\x{A4C6}\x{A60D}-\x{A60F}\x{A66F}\x{A670}-\x{A672}\x{A673}\x{A674}-\x{A67D}\x{A67E}\x{A67F}\x{A69E}-\x{A69F}\x{A6F0}-\x{A6F1}\x{A700}-\x{A716}\x{A717}-\x{A71F}\x{A720}-\x{A721}\x{A788}\x{A802}\x{A806}\x{A80B}\x{A825}-\x{A826}\x{A828}-\x{A82B}\x{A82C}\x{A838}\x{A839}\x{A874}-\x{A877}\x{A8C4}-\x{A8C5}\x{A8E0}-\x{A8F1}\x{A8FF}\x{A926}-\x{A92D}\x{A947}-\x{A951}\x{A980}-\x{A982}\x{A9B3}\x{A9B6}-\x{A9B9}\x{A9BC}-\x{A9BD}\x{A9E5}\x{AA29}-\x{AA2E}\x{AA31}-\x{AA32}\x{AA35}-\x{AA36}\x{AA43}\x{AA4C}\x{AA7C}\x{AAB0}\x{AAB2}-\x{AAB4}\x{AAB7}-\x{AAB8}\x{AABE}-\x{AABF}\x{AAC1}\x{AAEC}-\x{AAED}\x{AAF6}\x{AB6A}-\x{AB6B}\x{ABE5}\x{ABE8}\x{ABED}\x{FB1D}\x{FB1E}\x{FB1F}-\x{FB28}\x{FB29}\x{FB2A}-\x{FB36}\x{FB37}\x{FB38}-\x{FB3C}\x{FB3D}\x{FB3E}\x{FB3F}\x{FB40}-\x{FB41}\x{FB42}\x{FB43}-\x{FB44}\x{FB45}\x{FB46}-\x{FB4F}\x{FB50}-\x{FBB1}\x{FBB2}-\x{FBC1}\x{FBC2}-\x{FBD2}\x{FBD3}-\x{FD3D}\x{FD3E}\x{FD3F}\x{FD40}-\x{FD4F}\x{FD50}-\x{FD8F}\x{FD90}-\x{FD91}\x{FD92}-\x{FDC7}\x{FDC8}-\x{FDCF}\x{FDD0}-\x{FDEF}\x{FDF0}-\x{FDFB}\x{FDFC}\x{FDFD}\x{FDFE}-\x{FDFF}\x{FE00}-\x{FE0F}\x{FE10}-\x{FE16}\x{FE17}\x{FE18}\x{FE19}\x{FE20}-\x{FE2F}\x{FE30}\x{FE31}-\x{FE32}\x{FE33}-\x{FE34}\x{FE35}\x{FE36}\x{FE37}\x{FE38}\x{FE39}\x{FE3A}\x{FE3B}\x{FE3C}\x{FE3D}\x{FE3E}\x{FE3F}\x{FE40}\x{FE41}\x{FE42}\x{FE43}\x{FE44}\x{FE45}-\x{FE46}\x{FE47}\x{FE48}\x{FE49}-\x{FE4C}\x{FE4D}-\x{FE4F}\x{FE50}\x{FE51}\x{FE52}\x{FE54}\x{FE55}\x{FE56}-\x{FE57}\x{FE58}\x{FE59}\x{FE5A}\x{FE5B}\x{FE5C}\x{FE5D}\x{FE5E}\x{FE5F}\x{FE60}-\x{FE61}\x{FE62}\x{FE63}\x{FE64}-\x{FE66}\x{FE68}\x{FE69}\x{FE6A}\x{FE6B}\x{FE70}-\x{FE74}\x{FE75}\x{FE76}-\x{FEFC}\x{FEFD}-\x{FEFE}\x{FEFF}\x{FF01}-\x{FF02}\x{FF03}\x{FF04}\x{FF05}\x{FF06}-\x{FF07}\x{FF08}\x{FF09}\x{FF0A}\x{FF0B}\x{FF0C}\x{FF0D}\x{FF0E}-\x{FF0F}\x{FF10}-\x{FF19}\x{FF1A}\x{FF1B}\x{FF1C}-\x{FF1E}\x{FF1F}-\x{FF20}\x{FF3B}\x{FF3C}\x{FF3D}\x{FF3E}\x{FF3F}\x{FF40}\x{FF5B}\x{FF5C}\x{FF5D}\x{FF5E}\x{FF5F}\x{FF60}\x{FF61}\x{FF62}\x{FF63}\x{FF64}-\x{FF65}\x{FFE0}-\x{FFE1}\x{FFE2}\x{FFE3}\x{FFE4}\x{FFE5}-\x{FFE6}\x{FFE8}\x{FFE9}-\x{FFEC}\x{FFED}-\x{FFEE}\x{FFF0}-\x{FFF8}\x{FFF9}-\x{FFFB}\x{FFFC}-\x{FFFD}\x{FFFE}-\x{FFFF}\x{10101}\x{10140}-\x{10174}\x{10175}-\x{10178}\x{10179}-\x{10189}\x{1018A}-\x{1018B}\x{1018C}\x{10190}-\x{1019C}\x{101A0}\x{101FD}\x{102E0}\x{102E1}-\x{102FB}\x{10376}-\x{1037A}\x{10800}-\x{10805}\x{10806}-\x{10807}\x{10808}\x{10809}\x{1080A}-\x{10835}\x{10836}\x{10837}-\x{10838}\x{10839}-\x{1083B}\x{1083C}\x{1083D}-\x{1083E}\x{1083F}-\x{10855}\x{10856}\x{10857}\x{10858}-\x{1085F}\x{10860}-\x{10876}\x{10877}-\x{10878}\x{10879}-\x{1087F}\x{10880}-\x{1089E}\x{1089F}-\x{108A6}\x{108A7}-\x{108AF}\x{108B0}-\x{108DF}\x{108E0}-\x{108F2}\x{108F3}\x{108F4}-\x{108F5}\x{108F6}-\x{108FA}\x{108FB}-\x{108FF}\x{10900}-\x{10915}\x{10916}-\x{1091B}\x{1091C}-\x{1091E}\x{1091F}\x{10920}-\x{10939}\x{1093A}-\x{1093E}\x{1093F}\x{10940}-\x{1097F}\x{10980}-\x{109B7}\x{109B8}-\x{109BB}\x{109BC}-\x{109BD}\x{109BE}-\x{109BF}\x{109C0}-\x{109CF}\x{109D0}-\x{109D1}\x{109D2}-\x{109FF}\x{10A00}\x{10A01}-\x{10A03}\x{10A04}\x{10A05}-\x{10A06}\x{10A07}-\x{10A0B}\x{10A0C}-\x{10A0F}\x{10A10}-\x{10A13}\x{10A14}\x{10A15}-\x{10A17}\x{10A18}\x{10A19}-\x{10A35}\x{10A36}-\x{10A37}\x{10A38}-\x{10A3A}\x{10A3B}-\x{10A3E}\x{10A3F}\x{10A40}-\x{10A48}\x{10A49}-\x{10A4F}\x{10A50}-\x{10A58}\x{10A59}-\x{10A5F}\x{10A60}-\x{10A7C}\x{10A7D}-\x{10A7E}\x{10A7F}\x{10A80}-\x{10A9C}\x{10A9D}-\x{10A9F}\x{10AA0}-\x{10ABF}\x{10AC0}-\x{10AC7}\x{10AC8}\x{10AC9}-\x{10AE4}\x{10AE5}-\x{10AE6}\x{10AE7}-\x{10AEA}\x{10AEB}-\x{10AEF}\x{10AF0}-\x{10AF6}\x{10AF7}-\x{10AFF}\x{10B00}-\x{10B35}\x{10B36}-\x{10B38}\x{10B39}-\x{10B3F}\x{10B40}-\x{10B55}\x{10B56}-\x{10B57}\x{10B58}-\x{10B5F}\x{10B60}-\x{10B72}\x{10B73}-\x{10B77}\x{10B78}-\x{10B7F}\x{10B80}-\x{10B91}\x{10B92}-\x{10B98}\x{10B99}-\x{10B9C}\x{10B9D}-\x{10BA8}\x{10BA9}-\x{10BAF}\x{10BB0}-\x{10BFF}\x{10C00}-\x{10C48}\x{10C49}-\x{10C7F}\x{10C80}-\x{10CB2}\x{10CB3}-\x{10CBF}\x{10CC0}-\x{10CF2}\x{10CF3}-\x{10CF9}\x{10CFA}-\x{10CFF}\x{10D00}-\x{10D23}\x{10D24}-\x{10D27}\x{10D28}-\x{10D2F}\x{10D30}-\x{10D39}\x{10D3A}-\x{10D3F}\x{10D40}-\x{10E5F}\x{10E60}-\x{10E7E}\x{10E7F}\x{10E80}-\x{10EA9}\x{10EAA}\x{10EAB}-\x{10EAC}\x{10EAD}\x{10EAE}-\x{10EAF}\x{10EB0}-\x{10EB1}\x{10EB2}-\x{10EFF}\x{10F00}-\x{10F1C}\x{10F1D}-\x{10F26}\x{10F27}\x{10F28}-\x{10F2F}\x{10F30}-\x{10F45}\x{10F46}-\x{10F50}\x{10F51}-\x{10F54}\x{10F55}-\x{10F59}\x{10F5A}-\x{10F6F}\x{10F70}-\x{10FAF}\x{10FB0}-\x{10FC4}\x{10FC5}-\x{10FCB}\x{10FCC}-\x{10FDF}\x{10FE0}-\x{10FF6}\x{10FF7}-\x{10FFF}\x{11001}\x{11038}-\x{11046}\x{11052}-\x{11065}\x{1107F}-\x{11081}\x{110B3}-\x{110B6}\x{110B9}-\x{110BA}\x{11100}-\x{11102}\x{11127}-\x{1112B}\x{1112D}-\x{11134}\x{11173}\x{11180}-\x{11181}\x{111B6}-\x{111BE}\x{111C9}-\x{111CC}\x{111CF}\x{1122F}-\x{11231}\x{11234}\x{11236}-\x{11237}\x{1123E}\x{112DF}\x{112E3}-\x{112EA}\x{11300}-\x{11301}\x{1133B}-\x{1133C}\x{11340}\x{11366}-\x{1136C}\x{11370}-\x{11374}\x{11438}-\x{1143F}\x{11442}-\x{11444}\x{11446}\x{1145E}\x{114B3}-\x{114B8}\x{114BA}\x{114BF}-\x{114C0}\x{114C2}-\x{114C3}\x{115B2}-\x{115B5}\x{115BC}-\x{115BD}\x{115BF}-\x{115C0}\x{115DC}-\x{115DD}\x{11633}-\x{1163A}\x{1163D}\x{1163F}-\x{11640}\x{11660}-\x{1166C}\x{116AB}\x{116AD}\x{116B0}-\x{116B5}\x{116B7}\x{1171D}-\x{1171F}\x{11722}-\x{11725}\x{11727}-\x{1172B}\x{1182F}-\x{11837}\x{11839}-\x{1183A}\x{1193B}-\x{1193C}\x{1193E}\x{11943}\x{119D4}-\x{119D7}\x{119DA}-\x{119DB}\x{119E0}\x{11A01}-\x{11A06}\x{11A09}-\x{11A0A}\x{11A33}-\x{11A38}\x{11A3B}-\x{11A3E}\x{11A47}\x{11A51}-\x{11A56}\x{11A59}-\x{11A5B}\x{11A8A}-\x{11A96}\x{11A98}-\x{11A99}\x{11C30}-\x{11C36}\x{11C38}-\x{11C3D}\x{11C92}-\x{11CA7}\x{11CAA}-\x{11CB0}\x{11CB2}-\x{11CB3}\x{11CB5}-\x{11CB6}\x{11D31}-\x{11D36}\x{11D3A}\x{11D3C}-\x{11D3D}\x{11D3F}-\x{11D45}\x{11D47}\x{11D90}-\x{11D91}\x{11D95}\x{11D97}\x{11EF3}-\x{11EF4}\x{11FD5}-\x{11FDC}\x{11FDD}-\x{11FE0}\x{11FE1}-\x{11FF1}\x{16AF0}-\x{16AF4}\x{16B30}-\x{16B36}\x{16F4F}\x{16F8F}-\x{16F92}\x{16FE2}\x{16FE4}\x{1BC9D}-\x{1BC9E}\x{1BCA0}-\x{1BCA3}\x{1D167}-\x{1D169}\x{1D173}-\x{1D17A}\x{1D17B}-\x{1D182}\x{1D185}-\x{1D18B}\x{1D1AA}-\x{1D1AD}\x{1D200}-\x{1D241}\x{1D242}-\x{1D244}\x{1D245}\x{1D300}-\x{1D356}\x{1D6DB}\x{1D715}\x{1D74F}\x{1D789}\x{1D7C3}\x{1D7CE}-\x{1D7FF}\x{1DA00}-\x{1DA36}\x{1DA3B}-\x{1DA6C}\x{1DA75}\x{1DA84}\x{1DA9B}-\x{1DA9F}\x{1DAA1}-\x{1DAAF}\x{1E000}-\x{1E006}\x{1E008}-\x{1E018}\x{1E01B}-\x{1E021}\x{1E023}-\x{1E024}\x{1E026}-\x{1E02A}\x{1E130}-\x{1E136}\x{1E2EC}-\x{1E2EF}\x{1E2FF}\x{1E800}-\x{1E8C4}\x{1E8C5}-\x{1E8C6}\x{1E8C7}-\x{1E8CF}\x{1E8D0}-\x{1E8D6}\x{1E8D7}-\x{1E8FF}\x{1E900}-\x{1E943}\x{1E944}-\x{1E94A}\x{1E94B}\x{1E94C}-\x{1E94F}\x{1E950}-\x{1E959}\x{1E95A}-\x{1E95D}\x{1E95E}-\x{1E95F}\x{1E960}-\x{1EC6F}\x{1EC70}\x{1EC71}-\x{1ECAB}\x{1ECAC}\x{1ECAD}-\x{1ECAF}\x{1ECB0}\x{1ECB1}-\x{1ECB4}\x{1ECB5}-\x{1ECBF}\x{1ECC0}-\x{1ECFF}\x{1ED00}\x{1ED01}-\x{1ED2D}\x{1ED2E}\x{1ED2F}-\x{1ED3D}\x{1ED3E}-\x{1ED4F}\x{1ED50}-\x{1EDFF}\x{1EE00}-\x{1EE03}\x{1EE04}\x{1EE05}-\x{1EE1F}\x{1EE20}\x{1EE21}-\x{1EE22}\x{1EE23}\x{1EE24}\x{1EE25}-\x{1EE26}\x{1EE27}\x{1EE28}\x{1EE29}-\x{1EE32}\x{1EE33}\x{1EE34}-\x{1EE37}\x{1EE38}\x{1EE39}\x{1EE3A}\x{1EE3B}\x{1EE3C}-\x{1EE41}\x{1EE42}\x{1EE43}-\x{1EE46}\x{1EE47}\x{1EE48}\x{1EE49}\x{1EE4A}\x{1EE4B}\x{1EE4C}\x{1EE4D}-\x{1EE4F}\x{1EE50}\x{1EE51}-\x{1EE52}\x{1EE53}\x{1EE54}\x{1EE55}-\x{1EE56}\x{1EE57}\x{1EE58}\x{1EE59}\x{1EE5A}\x{1EE5B}\x{1EE5C}\x{1EE5D}\x{1EE5E}\x{1EE5F}\x{1EE60}\x{1EE61}-\x{1EE62}\x{1EE63}\x{1EE64}\x{1EE65}-\x{1EE66}\x{1EE67}-\x{1EE6A}\x{1EE6B}\x{1EE6C}-\x{1EE72}\x{1EE73}\x{1EE74}-\x{1EE77}\x{1EE78}\x{1EE79}-\x{1EE7C}\x{1EE7D}\x{1EE7E}\x{1EE7F}\x{1EE80}-\x{1EE89}\x{1EE8A}\x{1EE8B}-\x{1EE9B}\x{1EE9C}-\x{1EEA0}\x{1EEA1}-\x{1EEA3}\x{1EEA4}\x{1EEA5}-\x{1EEA9}\x{1EEAA}\x{1EEAB}-\x{1EEBB}\x{1EEBC}-\x{1EEEF}\x{1EEF0}-\x{1EEF1}\x{1EEF2}-\x{1EEFF}\x{1EF00}-\x{1EFFF}\x{1F000}-\x{1F02B}\x{1F030}-\x{1F093}\x{1F0A0}-\x{1F0AE}\x{1F0B1}-\x{1F0BF}\x{1F0C1}-\x{1F0CF}\x{1F0D1}-\x{1F0F5}\x{1F100}-\x{1F10A}\x{1F10B}-\x{1F10C}\x{1F10D}-\x{1F10F}\x{1F12F}\x{1F16A}-\x{1F16F}\x{1F1AD}\x{1F260}-\x{1F265}\x{1F300}-\x{1F3FA}\x{1F3FB}-\x{1F3FF}\x{1F400}-\x{1F6D7}\x{1F6E0}-\x{1F6EC}\x{1F6F0}-\x{1F6FC}\x{1F700}-\x{1F773}\x{1F780}-\x{1F7D8}\x{1F7E0}-\x{1F7EB}\x{1F800}-\x{1F80B}\x{1F810}-\x{1F847}\x{1F850}-\x{1F859}\x{1F860}-\x{1F887}\x{1F890}-\x{1F8AD}\x{1F8B0}-\x{1F8B1}\x{1F900}-\x{1F978}\x{1F97A}-\x{1F9CB}\x{1F9CD}-\x{1FA53}\x{1FA60}-\x{1FA6D}\x{1FA70}-\x{1FA74}\x{1FA78}-\x{1FA7A}\x{1FA80}-\x{1FA86}\x{1FA90}-\x{1FAA8}\x{1FAB0}-\x{1FAB6}\x{1FAC0}-\x{1FAC2}\x{1FAD0}-\x{1FAD6}\x{1FB00}-\x{1FB92}\x{1FB94}-\x{1FBCA}\x{1FBF0}-\x{1FBF9}\x{1FFFE}-\x{1FFFF}\x{2FFFE}-\x{2FFFF}\x{3FFFE}-\x{3FFFF}\x{4FFFE}-\x{4FFFF}\x{5FFFE}-\x{5FFFF}\x{6FFFE}-\x{6FFFF}\x{7FFFE}-\x{7FFFF}\x{8FFFE}-\x{8FFFF}\x{9FFFE}-\x{9FFFF}\x{AFFFE}-\x{AFFFF}\x{BFFFE}-\x{BFFFF}\x{CFFFE}-\x{CFFFF}\x{DFFFE}-\x{E0000}\x{E0001}\x{E0002}-\x{E001F}\x{E0020}-\x{E007F}\x{E0080}-\x{E00FF}\x{E0100}-\x{E01EF}\x{E01F0}-\x{E0FFF}\x{EFFFE}-\x{EFFFF}\x{FFFFE}-\x{FFFFF}\x{10FFFE}-\x{10FFFF}]/u';
    const BIDI_STEP_3 = '/[\x{0030}-\x{0039}\x{00B2}-\x{00B3}\x{00B9}\x{0590}\x{05BE}\x{05C0}\x{05C3}\x{05C6}\x{05C8}-\x{05CF}\x{05D0}-\x{05EA}\x{05EB}-\x{05EE}\x{05EF}-\x{05F2}\x{05F3}-\x{05F4}\x{05F5}-\x{05FF}\x{0600}-\x{0605}\x{0608}\x{060B}\x{060D}\x{061B}\x{061C}\x{061D}\x{061E}-\x{061F}\x{0620}-\x{063F}\x{0640}\x{0641}-\x{064A}\x{0660}-\x{0669}\x{066B}-\x{066C}\x{066D}\x{066E}-\x{066F}\x{0671}-\x{06D3}\x{06D4}\x{06D5}\x{06DD}\x{06E5}-\x{06E6}\x{06EE}-\x{06EF}\x{06F0}-\x{06F9}\x{06FA}-\x{06FC}\x{06FD}-\x{06FE}\x{06FF}\x{0700}-\x{070D}\x{070E}\x{070F}\x{0710}\x{0712}-\x{072F}\x{074B}-\x{074C}\x{074D}-\x{07A5}\x{07B1}\x{07B2}-\x{07BF}\x{07C0}-\x{07C9}\x{07CA}-\x{07EA}\x{07F4}-\x{07F5}\x{07FA}\x{07FB}-\x{07FC}\x{07FE}-\x{07FF}\x{0800}-\x{0815}\x{081A}\x{0824}\x{0828}\x{082E}-\x{082F}\x{0830}-\x{083E}\x{083F}\x{0840}-\x{0858}\x{085C}-\x{085D}\x{085E}\x{085F}\x{0860}-\x{086A}\x{086B}-\x{086F}\x{0870}-\x{089F}\x{08A0}-\x{08B4}\x{08B5}\x{08B6}-\x{08C7}\x{08C8}-\x{08D2}\x{08E2}\x{200F}\x{2070}\x{2074}-\x{2079}\x{2080}-\x{2089}\x{2488}-\x{249B}\x{FB1D}\x{FB1F}-\x{FB28}\x{FB2A}-\x{FB36}\x{FB37}\x{FB38}-\x{FB3C}\x{FB3D}\x{FB3E}\x{FB3F}\x{FB40}-\x{FB41}\x{FB42}\x{FB43}-\x{FB44}\x{FB45}\x{FB46}-\x{FB4F}\x{FB50}-\x{FBB1}\x{FBB2}-\x{FBC1}\x{FBC2}-\x{FBD2}\x{FBD3}-\x{FD3D}\x{FD40}-\x{FD4F}\x{FD50}-\x{FD8F}\x{FD90}-\x{FD91}\x{FD92}-\x{FDC7}\x{FDC8}-\x{FDCF}\x{FDF0}-\x{FDFB}\x{FDFC}\x{FDFE}-\x{FDFF}\x{FE70}-\x{FE74}\x{FE75}\x{FE76}-\x{FEFC}\x{FEFD}-\x{FEFE}\x{FF10}-\x{FF19}\x{102E1}-\x{102FB}\x{10800}-\x{10805}\x{10806}-\x{10807}\x{10808}\x{10809}\x{1080A}-\x{10835}\x{10836}\x{10837}-\x{10838}\x{10839}-\x{1083B}\x{1083C}\x{1083D}-\x{1083E}\x{1083F}-\x{10855}\x{10856}\x{10857}\x{10858}-\x{1085F}\x{10860}-\x{10876}\x{10877}-\x{10878}\x{10879}-\x{1087F}\x{10880}-\x{1089E}\x{1089F}-\x{108A6}\x{108A7}-\x{108AF}\x{108B0}-\x{108DF}\x{108E0}-\x{108F2}\x{108F3}\x{108F4}-\x{108F5}\x{108F6}-\x{108FA}\x{108FB}-\x{108FF}\x{10900}-\x{10915}\x{10916}-\x{1091B}\x{1091C}-\x{1091E}\x{10920}-\x{10939}\x{1093A}-\x{1093E}\x{1093F}\x{10940}-\x{1097F}\x{10980}-\x{109B7}\x{109B8}-\x{109BB}\x{109BC}-\x{109BD}\x{109BE}-\x{109BF}\x{109C0}-\x{109CF}\x{109D0}-\x{109D1}\x{109D2}-\x{109FF}\x{10A00}\x{10A04}\x{10A07}-\x{10A0B}\x{10A10}-\x{10A13}\x{10A14}\x{10A15}-\x{10A17}\x{10A18}\x{10A19}-\x{10A35}\x{10A36}-\x{10A37}\x{10A3B}-\x{10A3E}\x{10A40}-\x{10A48}\x{10A49}-\x{10A4F}\x{10A50}-\x{10A58}\x{10A59}-\x{10A5F}\x{10A60}-\x{10A7C}\x{10A7D}-\x{10A7E}\x{10A7F}\x{10A80}-\x{10A9C}\x{10A9D}-\x{10A9F}\x{10AA0}-\x{10ABF}\x{10AC0}-\x{10AC7}\x{10AC8}\x{10AC9}-\x{10AE4}\x{10AE7}-\x{10AEA}\x{10AEB}-\x{10AEF}\x{10AF0}-\x{10AF6}\x{10AF7}-\x{10AFF}\x{10B00}-\x{10B35}\x{10B36}-\x{10B38}\x{10B40}-\x{10B55}\x{10B56}-\x{10B57}\x{10B58}-\x{10B5F}\x{10B60}-\x{10B72}\x{10B73}-\x{10B77}\x{10B78}-\x{10B7F}\x{10B80}-\x{10B91}\x{10B92}-\x{10B98}\x{10B99}-\x{10B9C}\x{10B9D}-\x{10BA8}\x{10BA9}-\x{10BAF}\x{10BB0}-\x{10BFF}\x{10C00}-\x{10C48}\x{10C49}-\x{10C7F}\x{10C80}-\x{10CB2}\x{10CB3}-\x{10CBF}\x{10CC0}-\x{10CF2}\x{10CF3}-\x{10CF9}\x{10CFA}-\x{10CFF}\x{10D00}-\x{10D23}\x{10D28}-\x{10D2F}\x{10D30}-\x{10D39}\x{10D3A}-\x{10D3F}\x{10D40}-\x{10E5F}\x{10E60}-\x{10E7E}\x{10E7F}\x{10E80}-\x{10EA9}\x{10EAA}\x{10EAD}\x{10EAE}-\x{10EAF}\x{10EB0}-\x{10EB1}\x{10EB2}-\x{10EFF}\x{10F00}-\x{10F1C}\x{10F1D}-\x{10F26}\x{10F27}\x{10F28}-\x{10F2F}\x{10F30}-\x{10F45}\x{10F51}-\x{10F54}\x{10F55}-\x{10F59}\x{10F5A}-\x{10F6F}\x{10F70}-\x{10FAF}\x{10FB0}-\x{10FC4}\x{10FC5}-\x{10FCB}\x{10FCC}-\x{10FDF}\x{10FE0}-\x{10FF6}\x{10FF7}-\x{10FFF}\x{1D7CE}-\x{1D7FF}\x{1E800}-\x{1E8C4}\x{1E8C5}-\x{1E8C6}\x{1E8C7}-\x{1E8CF}\x{1E8D7}-\x{1E8FF}\x{1E900}-\x{1E943}\x{1E94B}\x{1E94C}-\x{1E94F}\x{1E950}-\x{1E959}\x{1E95A}-\x{1E95D}\x{1E95E}-\x{1E95F}\x{1E960}-\x{1EC6F}\x{1EC70}\x{1EC71}-\x{1ECAB}\x{1ECAC}\x{1ECAD}-\x{1ECAF}\x{1ECB0}\x{1ECB1}-\x{1ECB4}\x{1ECB5}-\x{1ECBF}\x{1ECC0}-\x{1ECFF}\x{1ED00}\x{1ED01}-\x{1ED2D}\x{1ED2E}\x{1ED2F}-\x{1ED3D}\x{1ED3E}-\x{1ED4F}\x{1ED50}-\x{1EDFF}\x{1EE00}-\x{1EE03}\x{1EE04}\x{1EE05}-\x{1EE1F}\x{1EE20}\x{1EE21}-\x{1EE22}\x{1EE23}\x{1EE24}\x{1EE25}-\x{1EE26}\x{1EE27}\x{1EE28}\x{1EE29}-\x{1EE32}\x{1EE33}\x{1EE34}-\x{1EE37}\x{1EE38}\x{1EE39}\x{1EE3A}\x{1EE3B}\x{1EE3C}-\x{1EE41}\x{1EE42}\x{1EE43}-\x{1EE46}\x{1EE47}\x{1EE48}\x{1EE49}\x{1EE4A}\x{1EE4B}\x{1EE4C}\x{1EE4D}-\x{1EE4F}\x{1EE50}\x{1EE51}-\x{1EE52}\x{1EE53}\x{1EE54}\x{1EE55}-\x{1EE56}\x{1EE57}\x{1EE58}\x{1EE59}\x{1EE5A}\x{1EE5B}\x{1EE5C}\x{1EE5D}\x{1EE5E}\x{1EE5F}\x{1EE60}\x{1EE61}-\x{1EE62}\x{1EE63}\x{1EE64}\x{1EE65}-\x{1EE66}\x{1EE67}-\x{1EE6A}\x{1EE6B}\x{1EE6C}-\x{1EE72}\x{1EE73}\x{1EE74}-\x{1EE77}\x{1EE78}\x{1EE79}-\x{1EE7C}\x{1EE7D}\x{1EE7E}\x{1EE7F}\x{1EE80}-\x{1EE89}\x{1EE8A}\x{1EE8B}-\x{1EE9B}\x{1EE9C}-\x{1EEA0}\x{1EEA1}-\x{1EEA3}\x{1EEA4}\x{1EEA5}-\x{1EEA9}\x{1EEAA}\x{1EEAB}-\x{1EEBB}\x{1EEBC}-\x{1EEEF}\x{1EEF2}-\x{1EEFF}\x{1EF00}-\x{1EFFF}\x{1F100}-\x{1F10A}\x{1FBF0}-\x{1FBF9}][\x{0300}-\x{036F}\x{0483}-\x{0487}\x{0488}-\x{0489}\x{0591}-\x{05BD}\x{05BF}\x{05C1}-\x{05C2}\x{05C4}-\x{05C5}\x{05C7}\x{0610}-\x{061A}\x{064B}-\x{065F}\x{0670}\x{06D6}-\x{06DC}\x{06DF}-\x{06E4}\x{06E7}-\x{06E8}\x{06EA}-\x{06ED}\x{0711}\x{0730}-\x{074A}\x{07A6}-\x{07B0}\x{07EB}-\x{07F3}\x{07FD}\x{0816}-\x{0819}\x{081B}-\x{0823}\x{0825}-\x{0827}\x{0829}-\x{082D}\x{0859}-\x{085B}\x{08D3}-\x{08E1}\x{08E3}-\x{0902}\x{093A}\x{093C}\x{0941}-\x{0948}\x{094D}\x{0951}-\x{0957}\x{0962}-\x{0963}\x{0981}\x{09BC}\x{09C1}-\x{09C4}\x{09CD}\x{09E2}-\x{09E3}\x{09FE}\x{0A01}-\x{0A02}\x{0A3C}\x{0A41}-\x{0A42}\x{0A47}-\x{0A48}\x{0A4B}-\x{0A4D}\x{0A51}\x{0A70}-\x{0A71}\x{0A75}\x{0A81}-\x{0A82}\x{0ABC}\x{0AC1}-\x{0AC5}\x{0AC7}-\x{0AC8}\x{0ACD}\x{0AE2}-\x{0AE3}\x{0AFA}-\x{0AFF}\x{0B01}\x{0B3C}\x{0B3F}\x{0B41}-\x{0B44}\x{0B4D}\x{0B55}-\x{0B56}\x{0B62}-\x{0B63}\x{0B82}\x{0BC0}\x{0BCD}\x{0C00}\x{0C04}\x{0C3E}-\x{0C40}\x{0C46}-\x{0C48}\x{0C4A}-\x{0C4D}\x{0C55}-\x{0C56}\x{0C62}-\x{0C63}\x{0C81}\x{0CBC}\x{0CCC}-\x{0CCD}\x{0CE2}-\x{0CE3}\x{0D00}-\x{0D01}\x{0D3B}-\x{0D3C}\x{0D41}-\x{0D44}\x{0D4D}\x{0D62}-\x{0D63}\x{0D81}\x{0DCA}\x{0DD2}-\x{0DD4}\x{0DD6}\x{0E31}\x{0E34}-\x{0E3A}\x{0E47}-\x{0E4E}\x{0EB1}\x{0EB4}-\x{0EBC}\x{0EC8}-\x{0ECD}\x{0F18}-\x{0F19}\x{0F35}\x{0F37}\x{0F39}\x{0F71}-\x{0F7E}\x{0F80}-\x{0F84}\x{0F86}-\x{0F87}\x{0F8D}-\x{0F97}\x{0F99}-\x{0FBC}\x{0FC6}\x{102D}-\x{1030}\x{1032}-\x{1037}\x{1039}-\x{103A}\x{103D}-\x{103E}\x{1058}-\x{1059}\x{105E}-\x{1060}\x{1071}-\x{1074}\x{1082}\x{1085}-\x{1086}\x{108D}\x{109D}\x{135D}-\x{135F}\x{1712}-\x{1714}\x{1732}-\x{1734}\x{1752}-\x{1753}\x{1772}-\x{1773}\x{17B4}-\x{17B5}\x{17B7}-\x{17BD}\x{17C6}\x{17C9}-\x{17D3}\x{17DD}\x{180B}-\x{180D}\x{1885}-\x{1886}\x{18A9}\x{1920}-\x{1922}\x{1927}-\x{1928}\x{1932}\x{1939}-\x{193B}\x{1A17}-\x{1A18}\x{1A1B}\x{1A56}\x{1A58}-\x{1A5E}\x{1A60}\x{1A62}\x{1A65}-\x{1A6C}\x{1A73}-\x{1A7C}\x{1A7F}\x{1AB0}-\x{1ABD}\x{1ABE}\x{1ABF}-\x{1AC0}\x{1B00}-\x{1B03}\x{1B34}\x{1B36}-\x{1B3A}\x{1B3C}\x{1B42}\x{1B6B}-\x{1B73}\x{1B80}-\x{1B81}\x{1BA2}-\x{1BA5}\x{1BA8}-\x{1BA9}\x{1BAB}-\x{1BAD}\x{1BE6}\x{1BE8}-\x{1BE9}\x{1BED}\x{1BEF}-\x{1BF1}\x{1C2C}-\x{1C33}\x{1C36}-\x{1C37}\x{1CD0}-\x{1CD2}\x{1CD4}-\x{1CE0}\x{1CE2}-\x{1CE8}\x{1CED}\x{1CF4}\x{1CF8}-\x{1CF9}\x{1DC0}-\x{1DF9}\x{1DFB}-\x{1DFF}\x{20D0}-\x{20DC}\x{20DD}-\x{20E0}\x{20E1}\x{20E2}-\x{20E4}\x{20E5}-\x{20F0}\x{2CEF}-\x{2CF1}\x{2D7F}\x{2DE0}-\x{2DFF}\x{302A}-\x{302D}\x{3099}-\x{309A}\x{A66F}\x{A670}-\x{A672}\x{A674}-\x{A67D}\x{A69E}-\x{A69F}\x{A6F0}-\x{A6F1}\x{A802}\x{A806}\x{A80B}\x{A825}-\x{A826}\x{A82C}\x{A8C4}-\x{A8C5}\x{A8E0}-\x{A8F1}\x{A8FF}\x{A926}-\x{A92D}\x{A947}-\x{A951}\x{A980}-\x{A982}\x{A9B3}\x{A9B6}-\x{A9B9}\x{A9BC}-\x{A9BD}\x{A9E5}\x{AA29}-\x{AA2E}\x{AA31}-\x{AA32}\x{AA35}-\x{AA36}\x{AA43}\x{AA4C}\x{AA7C}\x{AAB0}\x{AAB2}-\x{AAB4}\x{AAB7}-\x{AAB8}\x{AABE}-\x{AABF}\x{AAC1}\x{AAEC}-\x{AAED}\x{AAF6}\x{ABE5}\x{ABE8}\x{ABED}\x{FB1E}\x{FE00}-\x{FE0F}\x{FE20}-\x{FE2F}\x{101FD}\x{102E0}\x{10376}-\x{1037A}\x{10A01}-\x{10A03}\x{10A05}-\x{10A06}\x{10A0C}-\x{10A0F}\x{10A38}-\x{10A3A}\x{10A3F}\x{10AE5}-\x{10AE6}\x{10D24}-\x{10D27}\x{10EAB}-\x{10EAC}\x{10F46}-\x{10F50}\x{11001}\x{11038}-\x{11046}\x{1107F}-\x{11081}\x{110B3}-\x{110B6}\x{110B9}-\x{110BA}\x{11100}-\x{11102}\x{11127}-\x{1112B}\x{1112D}-\x{11134}\x{11173}\x{11180}-\x{11181}\x{111B6}-\x{111BE}\x{111C9}-\x{111CC}\x{111CF}\x{1122F}-\x{11231}\x{11234}\x{11236}-\x{11237}\x{1123E}\x{112DF}\x{112E3}-\x{112EA}\x{11300}-\x{11301}\x{1133B}-\x{1133C}\x{11340}\x{11366}-\x{1136C}\x{11370}-\x{11374}\x{11438}-\x{1143F}\x{11442}-\x{11444}\x{11446}\x{1145E}\x{114B3}-\x{114B8}\x{114BA}\x{114BF}-\x{114C0}\x{114C2}-\x{114C3}\x{115B2}-\x{115B5}\x{115BC}-\x{115BD}\x{115BF}-\x{115C0}\x{115DC}-\x{115DD}\x{11633}-\x{1163A}\x{1163D}\x{1163F}-\x{11640}\x{116AB}\x{116AD}\x{116B0}-\x{116B5}\x{116B7}\x{1171D}-\x{1171F}\x{11722}-\x{11725}\x{11727}-\x{1172B}\x{1182F}-\x{11837}\x{11839}-\x{1183A}\x{1193B}-\x{1193C}\x{1193E}\x{11943}\x{119D4}-\x{119D7}\x{119DA}-\x{119DB}\x{119E0}\x{11A01}-\x{11A06}\x{11A09}-\x{11A0A}\x{11A33}-\x{11A38}\x{11A3B}-\x{11A3E}\x{11A47}\x{11A51}-\x{11A56}\x{11A59}-\x{11A5B}\x{11A8A}-\x{11A96}\x{11A98}-\x{11A99}\x{11C30}-\x{11C36}\x{11C38}-\x{11C3D}\x{11C92}-\x{11CA7}\x{11CAA}-\x{11CB0}\x{11CB2}-\x{11CB3}\x{11CB5}-\x{11CB6}\x{11D31}-\x{11D36}\x{11D3A}\x{11D3C}-\x{11D3D}\x{11D3F}-\x{11D45}\x{11D47}\x{11D90}-\x{11D91}\x{11D95}\x{11D97}\x{11EF3}-\x{11EF4}\x{16AF0}-\x{16AF4}\x{16B30}-\x{16B36}\x{16F4F}\x{16F8F}-\x{16F92}\x{16FE4}\x{1BC9D}-\x{1BC9E}\x{1D167}-\x{1D169}\x{1D17B}-\x{1D182}\x{1D185}-\x{1D18B}\x{1D1AA}-\x{1D1AD}\x{1D242}-\x{1D244}\x{1DA00}-\x{1DA36}\x{1DA3B}-\x{1DA6C}\x{1DA75}\x{1DA84}\x{1DA9B}-\x{1DA9F}\x{1DAA1}-\x{1DAAF}\x{1E000}-\x{1E006}\x{1E008}-\x{1E018}\x{1E01B}-\x{1E021}\x{1E023}-\x{1E024}\x{1E026}-\x{1E02A}\x{1E130}-\x{1E136}\x{1E2EC}-\x{1E2EF}\x{1E8D0}-\x{1E8D6}\x{1E944}-\x{1E94A}\x{E0100}-\x{E01EF}]*$/u';
    const BIDI_STEP_4_AN = '/[\x{0600}-\x{0605}\x{0660}-\x{0669}\x{066B}-\x{066C}\x{06DD}\x{08E2}\x{10D30}-\x{10D39}\x{10E60}-\x{10E7E}]/u';
    const BIDI_STEP_4_EN = '/[\x{0030}-\x{0039}\x{00B2}-\x{00B3}\x{00B9}\x{06F0}-\x{06F9}\x{2070}\x{2074}-\x{2079}\x{2080}-\x{2089}\x{2488}-\x{249B}\x{FF10}-\x{FF19}\x{102E1}-\x{102FB}\x{1D7CE}-\x{1D7FF}\x{1F100}-\x{1F10A}\x{1FBF0}-\x{1FBF9}]/u';
    const BIDI_STEP_5 = '/[\x{0009}\x{000A}\x{000B}\x{000C}\x{000D}\x{001C}-\x{001E}\x{001F}\x{0020}\x{0085}\x{0590}\x{05BE}\x{05C0}\x{05C3}\x{05C6}\x{05C8}-\x{05CF}\x{05D0}-\x{05EA}\x{05EB}-\x{05EE}\x{05EF}-\x{05F2}\x{05F3}-\x{05F4}\x{05F5}-\x{05FF}\x{0600}-\x{0605}\x{0608}\x{060B}\x{060D}\x{061B}\x{061C}\x{061D}\x{061E}-\x{061F}\x{0620}-\x{063F}\x{0640}\x{0641}-\x{064A}\x{0660}-\x{0669}\x{066B}-\x{066C}\x{066D}\x{066E}-\x{066F}\x{0671}-\x{06D3}\x{06D4}\x{06D5}\x{06DD}\x{06E5}-\x{06E6}\x{06EE}-\x{06EF}\x{06FA}-\x{06FC}\x{06FD}-\x{06FE}\x{06FF}\x{0700}-\x{070D}\x{070E}\x{070F}\x{0710}\x{0712}-\x{072F}\x{074B}-\x{074C}\x{074D}-\x{07A5}\x{07B1}\x{07B2}-\x{07BF}\x{07C0}-\x{07C9}\x{07CA}-\x{07EA}\x{07F4}-\x{07F5}\x{07FA}\x{07FB}-\x{07FC}\x{07FE}-\x{07FF}\x{0800}-\x{0815}\x{081A}\x{0824}\x{0828}\x{082E}-\x{082F}\x{0830}-\x{083E}\x{083F}\x{0840}-\x{0858}\x{085C}-\x{085D}\x{085E}\x{085F}\x{0860}-\x{086A}\x{086B}-\x{086F}\x{0870}-\x{089F}\x{08A0}-\x{08B4}\x{08B5}\x{08B6}-\x{08C7}\x{08C8}-\x{08D2}\x{08E2}\x{1680}\x{2000}-\x{200A}\x{200F}\x{2028}\x{2029}\x{202A}\x{202B}\x{202C}\x{202D}\x{202E}\x{205F}\x{2066}\x{2067}\x{2068}\x{2069}\x{3000}\x{FB1D}\x{FB1F}-\x{FB28}\x{FB2A}-\x{FB36}\x{FB37}\x{FB38}-\x{FB3C}\x{FB3D}\x{FB3E}\x{FB3F}\x{FB40}-\x{FB41}\x{FB42}\x{FB43}-\x{FB44}\x{FB45}\x{FB46}-\x{FB4F}\x{FB50}-\x{FBB1}\x{FBB2}-\x{FBC1}\x{FBC2}-\x{FBD2}\x{FBD3}-\x{FD3D}\x{FD40}-\x{FD4F}\x{FD50}-\x{FD8F}\x{FD90}-\x{FD91}\x{FD92}-\x{FDC7}\x{FDC8}-\x{FDCF}\x{FDF0}-\x{FDFB}\x{FDFC}\x{FDFE}-\x{FDFF}\x{FE70}-\x{FE74}\x{FE75}\x{FE76}-\x{FEFC}\x{FEFD}-\x{FEFE}\x{10800}-\x{10805}\x{10806}-\x{10807}\x{10808}\x{10809}\x{1080A}-\x{10835}\x{10836}\x{10837}-\x{10838}\x{10839}-\x{1083B}\x{1083C}\x{1083D}-\x{1083E}\x{1083F}-\x{10855}\x{10856}\x{10857}\x{10858}-\x{1085F}\x{10860}-\x{10876}\x{10877}-\x{10878}\x{10879}-\x{1087F}\x{10880}-\x{1089E}\x{1089F}-\x{108A6}\x{108A7}-\x{108AF}\x{108B0}-\x{108DF}\x{108E0}-\x{108F2}\x{108F3}\x{108F4}-\x{108F5}\x{108F6}-\x{108FA}\x{108FB}-\x{108FF}\x{10900}-\x{10915}\x{10916}-\x{1091B}\x{1091C}-\x{1091E}\x{10920}-\x{10939}\x{1093A}-\x{1093E}\x{1093F}\x{10940}-\x{1097F}\x{10980}-\x{109B7}\x{109B8}-\x{109BB}\x{109BC}-\x{109BD}\x{109BE}-\x{109BF}\x{109C0}-\x{109CF}\x{109D0}-\x{109D1}\x{109D2}-\x{109FF}\x{10A00}\x{10A04}\x{10A07}-\x{10A0B}\x{10A10}-\x{10A13}\x{10A14}\x{10A15}-\x{10A17}\x{10A18}\x{10A19}-\x{10A35}\x{10A36}-\x{10A37}\x{10A3B}-\x{10A3E}\x{10A40}-\x{10A48}\x{10A49}-\x{10A4F}\x{10A50}-\x{10A58}\x{10A59}-\x{10A5F}\x{10A60}-\x{10A7C}\x{10A7D}-\x{10A7E}\x{10A7F}\x{10A80}-\x{10A9C}\x{10A9D}-\x{10A9F}\x{10AA0}-\x{10ABF}\x{10AC0}-\x{10AC7}\x{10AC8}\x{10AC9}-\x{10AE4}\x{10AE7}-\x{10AEA}\x{10AEB}-\x{10AEF}\x{10AF0}-\x{10AF6}\x{10AF7}-\x{10AFF}\x{10B00}-\x{10B35}\x{10B36}-\x{10B38}\x{10B40}-\x{10B55}\x{10B56}-\x{10B57}\x{10B58}-\x{10B5F}\x{10B60}-\x{10B72}\x{10B73}-\x{10B77}\x{10B78}-\x{10B7F}\x{10B80}-\x{10B91}\x{10B92}-\x{10B98}\x{10B99}-\x{10B9C}\x{10B9D}-\x{10BA8}\x{10BA9}-\x{10BAF}\x{10BB0}-\x{10BFF}\x{10C00}-\x{10C48}\x{10C49}-\x{10C7F}\x{10C80}-\x{10CB2}\x{10CB3}-\x{10CBF}\x{10CC0}-\x{10CF2}\x{10CF3}-\x{10CF9}\x{10CFA}-\x{10CFF}\x{10D00}-\x{10D23}\x{10D28}-\x{10D2F}\x{10D30}-\x{10D39}\x{10D3A}-\x{10D3F}\x{10D40}-\x{10E5F}\x{10E60}-\x{10E7E}\x{10E7F}\x{10E80}-\x{10EA9}\x{10EAA}\x{10EAD}\x{10EAE}-\x{10EAF}\x{10EB0}-\x{10EB1}\x{10EB2}-\x{10EFF}\x{10F00}-\x{10F1C}\x{10F1D}-\x{10F26}\x{10F27}\x{10F28}-\x{10F2F}\x{10F30}-\x{10F45}\x{10F51}-\x{10F54}\x{10F55}-\x{10F59}\x{10F5A}-\x{10F6F}\x{10F70}-\x{10FAF}\x{10FB0}-\x{10FC4}\x{10FC5}-\x{10FCB}\x{10FCC}-\x{10FDF}\x{10FE0}-\x{10FF6}\x{10FF7}-\x{10FFF}\x{1E800}-\x{1E8C4}\x{1E8C5}-\x{1E8C6}\x{1E8C7}-\x{1E8CF}\x{1E8D7}-\x{1E8FF}\x{1E900}-\x{1E943}\x{1E94B}\x{1E94C}-\x{1E94F}\x{1E950}-\x{1E959}\x{1E95A}-\x{1E95D}\x{1E95E}-\x{1E95F}\x{1E960}-\x{1EC6F}\x{1EC70}\x{1EC71}-\x{1ECAB}\x{1ECAC}\x{1ECAD}-\x{1ECAF}\x{1ECB0}\x{1ECB1}-\x{1ECB4}\x{1ECB5}-\x{1ECBF}\x{1ECC0}-\x{1ECFF}\x{1ED00}\x{1ED01}-\x{1ED2D}\x{1ED2E}\x{1ED2F}-\x{1ED3D}\x{1ED3E}-\x{1ED4F}\x{1ED50}-\x{1EDFF}\x{1EE00}-\x{1EE03}\x{1EE04}\x{1EE05}-\x{1EE1F}\x{1EE20}\x{1EE21}-\x{1EE22}\x{1EE23}\x{1EE24}\x{1EE25}-\x{1EE26}\x{1EE27}\x{1EE28}\x{1EE29}-\x{1EE32}\x{1EE33}\x{1EE34}-\x{1EE37}\x{1EE38}\x{1EE39}\x{1EE3A}\x{1EE3B}\x{1EE3C}-\x{1EE41}\x{1EE42}\x{1EE43}-\x{1EE46}\x{1EE47}\x{1EE48}\x{1EE49}\x{1EE4A}\x{1EE4B}\x{1EE4C}\x{1EE4D}-\x{1EE4F}\x{1EE50}\x{1EE51}-\x{1EE52}\x{1EE53}\x{1EE54}\x{1EE55}-\x{1EE56}\x{1EE57}\x{1EE58}\x{1EE59}\x{1EE5A}\x{1EE5B}\x{1EE5C}\x{1EE5D}\x{1EE5E}\x{1EE5F}\x{1EE60}\x{1EE61}-\x{1EE62}\x{1EE63}\x{1EE64}\x{1EE65}-\x{1EE66}\x{1EE67}-\x{1EE6A}\x{1EE6B}\x{1EE6C}-\x{1EE72}\x{1EE73}\x{1EE74}-\x{1EE77}\x{1EE78}\x{1EE79}-\x{1EE7C}\x{1EE7D}\x{1EE7E}\x{1EE7F}\x{1EE80}-\x{1EE89}\x{1EE8A}\x{1EE8B}-\x{1EE9B}\x{1EE9C}-\x{1EEA0}\x{1EEA1}-\x{1EEA3}\x{1EEA4}\x{1EEA5}-\x{1EEA9}\x{1EEAA}\x{1EEAB}-\x{1EEBB}\x{1EEBC}-\x{1EEEF}\x{1EEF2}-\x{1EEFF}\x{1EF00}-\x{1EFFF}]/u';
    const BIDI_STEP_6 = '/[^\x{0000}-\x{0008}\x{0009}\x{000A}\x{000B}\x{000C}\x{000D}\x{000E}-\x{001B}\x{001C}-\x{001E}\x{001F}\x{0020}\x{0021}-\x{0022}\x{0023}\x{0024}\x{0025}\x{0026}-\x{0027}\x{0028}\x{0029}\x{002A}\x{002B}\x{002C}\x{002D}\x{002E}-\x{002F}\x{003A}\x{003B}\x{003C}-\x{003E}\x{003F}-\x{0040}\x{005B}\x{005C}\x{005D}\x{005E}\x{005F}\x{0060}\x{007B}\x{007C}\x{007D}\x{007E}\x{007F}-\x{0084}\x{0085}\x{0086}-\x{009F}\x{00A0}\x{00A1}\x{00A2}-\x{00A5}\x{00A6}\x{00A7}\x{00A8}\x{00A9}\x{00AB}\x{00AC}\x{00AD}\x{00AE}\x{00AF}\x{00B0}\x{00B1}\x{00B4}\x{00B6}-\x{00B7}\x{00B8}\x{00BB}\x{00BC}-\x{00BE}\x{00BF}\x{00D7}\x{00F7}\x{02B9}-\x{02BA}\x{02C2}-\x{02C5}\x{02C6}-\x{02CF}\x{02D2}-\x{02DF}\x{02E5}-\x{02EB}\x{02EC}\x{02ED}\x{02EF}-\x{02FF}\x{0300}-\x{036F}\x{0374}\x{0375}\x{037E}\x{0384}-\x{0385}\x{0387}\x{03F6}\x{0483}-\x{0487}\x{0488}-\x{0489}\x{058A}\x{058D}-\x{058E}\x{058F}\x{0590}\x{0591}-\x{05BD}\x{05BE}\x{05BF}\x{05C0}\x{05C1}-\x{05C2}\x{05C3}\x{05C4}-\x{05C5}\x{05C6}\x{05C7}\x{05C8}-\x{05CF}\x{05D0}-\x{05EA}\x{05EB}-\x{05EE}\x{05EF}-\x{05F2}\x{05F3}-\x{05F4}\x{05F5}-\x{05FF}\x{0600}-\x{0605}\x{0606}-\x{0607}\x{0608}\x{0609}-\x{060A}\x{060B}\x{060C}\x{060D}\x{060E}-\x{060F}\x{0610}-\x{061A}\x{061B}\x{061C}\x{061D}\x{061E}-\x{061F}\x{0620}-\x{063F}\x{0640}\x{0641}-\x{064A}\x{064B}-\x{065F}\x{0660}-\x{0669}\x{066A}\x{066B}-\x{066C}\x{066D}\x{066E}-\x{066F}\x{0670}\x{0671}-\x{06D3}\x{06D4}\x{06D5}\x{06D6}-\x{06DC}\x{06DD}\x{06DE}\x{06DF}-\x{06E4}\x{06E5}-\x{06E6}\x{06E7}-\x{06E8}\x{06E9}\x{06EA}-\x{06ED}\x{06EE}-\x{06EF}\x{06FA}-\x{06FC}\x{06FD}-\x{06FE}\x{06FF}\x{0700}-\x{070D}\x{070E}\x{070F}\x{0710}\x{0711}\x{0712}-\x{072F}\x{0730}-\x{074A}\x{074B}-\x{074C}\x{074D}-\x{07A5}\x{07A6}-\x{07B0}\x{07B1}\x{07B2}-\x{07BF}\x{07C0}-\x{07C9}\x{07CA}-\x{07EA}\x{07EB}-\x{07F3}\x{07F4}-\x{07F5}\x{07F6}\x{07F7}-\x{07F9}\x{07FA}\x{07FB}-\x{07FC}\x{07FD}\x{07FE}-\x{07FF}\x{0800}-\x{0815}\x{0816}-\x{0819}\x{081A}\x{081B}-\x{0823}\x{0824}\x{0825}-\x{0827}\x{0828}\x{0829}-\x{082D}\x{082E}-\x{082F}\x{0830}-\x{083E}\x{083F}\x{0840}-\x{0858}\x{0859}-\x{085B}\x{085C}-\x{085D}\x{085E}\x{085F}\x{0860}-\x{086A}\x{086B}-\x{086F}\x{0870}-\x{089F}\x{08A0}-\x{08B4}\x{08B5}\x{08B6}-\x{08C7}\x{08C8}-\x{08D2}\x{08D3}-\x{08E1}\x{08E2}\x{08E3}-\x{0902}\x{093A}\x{093C}\x{0941}-\x{0948}\x{094D}\x{0951}-\x{0957}\x{0962}-\x{0963}\x{0981}\x{09BC}\x{09C1}-\x{09C4}\x{09CD}\x{09E2}-\x{09E3}\x{09F2}-\x{09F3}\x{09FB}\x{09FE}\x{0A01}-\x{0A02}\x{0A3C}\x{0A41}-\x{0A42}\x{0A47}-\x{0A48}\x{0A4B}-\x{0A4D}\x{0A51}\x{0A70}-\x{0A71}\x{0A75}\x{0A81}-\x{0A82}\x{0ABC}\x{0AC1}-\x{0AC5}\x{0AC7}-\x{0AC8}\x{0ACD}\x{0AE2}-\x{0AE3}\x{0AF1}\x{0AFA}-\x{0AFF}\x{0B01}\x{0B3C}\x{0B3F}\x{0B41}-\x{0B44}\x{0B4D}\x{0B55}-\x{0B56}\x{0B62}-\x{0B63}\x{0B82}\x{0BC0}\x{0BCD}\x{0BF3}-\x{0BF8}\x{0BF9}\x{0BFA}\x{0C00}\x{0C04}\x{0C3E}-\x{0C40}\x{0C46}-\x{0C48}\x{0C4A}-\x{0C4D}\x{0C55}-\x{0C56}\x{0C62}-\x{0C63}\x{0C78}-\x{0C7E}\x{0C81}\x{0CBC}\x{0CCC}-\x{0CCD}\x{0CE2}-\x{0CE3}\x{0D00}-\x{0D01}\x{0D3B}-\x{0D3C}\x{0D41}-\x{0D44}\x{0D4D}\x{0D62}-\x{0D63}\x{0D81}\x{0DCA}\x{0DD2}-\x{0DD4}\x{0DD6}\x{0E31}\x{0E34}-\x{0E3A}\x{0E3F}\x{0E47}-\x{0E4E}\x{0EB1}\x{0EB4}-\x{0EBC}\x{0EC8}-\x{0ECD}\x{0F18}-\x{0F19}\x{0F35}\x{0F37}\x{0F39}\x{0F3A}\x{0F3B}\x{0F3C}\x{0F3D}\x{0F71}-\x{0F7E}\x{0F80}-\x{0F84}\x{0F86}-\x{0F87}\x{0F8D}-\x{0F97}\x{0F99}-\x{0FBC}\x{0FC6}\x{102D}-\x{1030}\x{1032}-\x{1037}\x{1039}-\x{103A}\x{103D}-\x{103E}\x{1058}-\x{1059}\x{105E}-\x{1060}\x{1071}-\x{1074}\x{1082}\x{1085}-\x{1086}\x{108D}\x{109D}\x{135D}-\x{135F}\x{1390}-\x{1399}\x{1400}\x{1680}\x{169B}\x{169C}\x{1712}-\x{1714}\x{1732}-\x{1734}\x{1752}-\x{1753}\x{1772}-\x{1773}\x{17B4}-\x{17B5}\x{17B7}-\x{17BD}\x{17C6}\x{17C9}-\x{17D3}\x{17DB}\x{17DD}\x{17F0}-\x{17F9}\x{1800}-\x{1805}\x{1806}\x{1807}-\x{180A}\x{180B}-\x{180D}\x{180E}\x{1885}-\x{1886}\x{18A9}\x{1920}-\x{1922}\x{1927}-\x{1928}\x{1932}\x{1939}-\x{193B}\x{1940}\x{1944}-\x{1945}\x{19DE}-\x{19FF}\x{1A17}-\x{1A18}\x{1A1B}\x{1A56}\x{1A58}-\x{1A5E}\x{1A60}\x{1A62}\x{1A65}-\x{1A6C}\x{1A73}-\x{1A7C}\x{1A7F}\x{1AB0}-\x{1ABD}\x{1ABE}\x{1ABF}-\x{1AC0}\x{1B00}-\x{1B03}\x{1B34}\x{1B36}-\x{1B3A}\x{1B3C}\x{1B42}\x{1B6B}-\x{1B73}\x{1B80}-\x{1B81}\x{1BA2}-\x{1BA5}\x{1BA8}-\x{1BA9}\x{1BAB}-\x{1BAD}\x{1BE6}\x{1BE8}-\x{1BE9}\x{1BED}\x{1BEF}-\x{1BF1}\x{1C2C}-\x{1C33}\x{1C36}-\x{1C37}\x{1CD0}-\x{1CD2}\x{1CD4}-\x{1CE0}\x{1CE2}-\x{1CE8}\x{1CED}\x{1CF4}\x{1CF8}-\x{1CF9}\x{1DC0}-\x{1DF9}\x{1DFB}-\x{1DFF}\x{1FBD}\x{1FBF}-\x{1FC1}\x{1FCD}-\x{1FCF}\x{1FDD}-\x{1FDF}\x{1FED}-\x{1FEF}\x{1FFD}-\x{1FFE}\x{2000}-\x{200A}\x{200B}-\x{200D}\x{200F}\x{2010}-\x{2015}\x{2016}-\x{2017}\x{2018}\x{2019}\x{201A}\x{201B}-\x{201C}\x{201D}\x{201E}\x{201F}\x{2020}-\x{2027}\x{2028}\x{2029}\x{202A}\x{202B}\x{202C}\x{202D}\x{202E}\x{202F}\x{2030}-\x{2034}\x{2035}-\x{2038}\x{2039}\x{203A}\x{203B}-\x{203E}\x{203F}-\x{2040}\x{2041}-\x{2043}\x{2044}\x{2045}\x{2046}\x{2047}-\x{2051}\x{2052}\x{2053}\x{2054}\x{2055}-\x{205E}\x{205F}\x{2060}-\x{2064}\x{2065}\x{2066}\x{2067}\x{2068}\x{2069}\x{206A}-\x{206F}\x{207A}-\x{207B}\x{207C}\x{207D}\x{207E}\x{208A}-\x{208B}\x{208C}\x{208D}\x{208E}\x{20A0}-\x{20BF}\x{20C0}-\x{20CF}\x{20D0}-\x{20DC}\x{20DD}-\x{20E0}\x{20E1}\x{20E2}-\x{20E4}\x{20E5}-\x{20F0}\x{2100}-\x{2101}\x{2103}-\x{2106}\x{2108}-\x{2109}\x{2114}\x{2116}-\x{2117}\x{2118}\x{211E}-\x{2123}\x{2125}\x{2127}\x{2129}\x{212E}\x{213A}-\x{213B}\x{2140}-\x{2144}\x{214A}\x{214B}\x{214C}-\x{214D}\x{2150}-\x{215F}\x{2189}\x{218A}-\x{218B}\x{2190}-\x{2194}\x{2195}-\x{2199}\x{219A}-\x{219B}\x{219C}-\x{219F}\x{21A0}\x{21A1}-\x{21A2}\x{21A3}\x{21A4}-\x{21A5}\x{21A6}\x{21A7}-\x{21AD}\x{21AE}\x{21AF}-\x{21CD}\x{21CE}-\x{21CF}\x{21D0}-\x{21D1}\x{21D2}\x{21D3}\x{21D4}\x{21D5}-\x{21F3}\x{21F4}-\x{2211}\x{2212}\x{2213}\x{2214}-\x{22FF}\x{2300}-\x{2307}\x{2308}\x{2309}\x{230A}\x{230B}\x{230C}-\x{231F}\x{2320}-\x{2321}\x{2322}-\x{2328}\x{2329}\x{232A}\x{232B}-\x{2335}\x{237B}\x{237C}\x{237D}-\x{2394}\x{2396}-\x{239A}\x{239B}-\x{23B3}\x{23B4}-\x{23DB}\x{23DC}-\x{23E1}\x{23E2}-\x{2426}\x{2440}-\x{244A}\x{2460}-\x{2487}\x{24EA}-\x{24FF}\x{2500}-\x{25B6}\x{25B7}\x{25B8}-\x{25C0}\x{25C1}\x{25C2}-\x{25F7}\x{25F8}-\x{25FF}\x{2600}-\x{266E}\x{266F}\x{2670}-\x{26AB}\x{26AD}-\x{2767}\x{2768}\x{2769}\x{276A}\x{276B}\x{276C}\x{276D}\x{276E}\x{276F}\x{2770}\x{2771}\x{2772}\x{2773}\x{2774}\x{2775}\x{2776}-\x{2793}\x{2794}-\x{27BF}\x{27C0}-\x{27C4}\x{27C5}\x{27C6}\x{27C7}-\x{27E5}\x{27E6}\x{27E7}\x{27E8}\x{27E9}\x{27EA}\x{27EB}\x{27EC}\x{27ED}\x{27EE}\x{27EF}\x{27F0}-\x{27FF}\x{2900}-\x{2982}\x{2983}\x{2984}\x{2985}\x{2986}\x{2987}\x{2988}\x{2989}\x{298A}\x{298B}\x{298C}\x{298D}\x{298E}\x{298F}\x{2990}\x{2991}\x{2992}\x{2993}\x{2994}\x{2995}\x{2996}\x{2997}\x{2998}\x{2999}-\x{29D7}\x{29D8}\x{29D9}\x{29DA}\x{29DB}\x{29DC}-\x{29FB}\x{29FC}\x{29FD}\x{29FE}-\x{2AFF}\x{2B00}-\x{2B2F}\x{2B30}-\x{2B44}\x{2B45}-\x{2B46}\x{2B47}-\x{2B4C}\x{2B4D}-\x{2B73}\x{2B76}-\x{2B95}\x{2B97}-\x{2BFF}\x{2CE5}-\x{2CEA}\x{2CEF}-\x{2CF1}\x{2CF9}-\x{2CFC}\x{2CFD}\x{2CFE}-\x{2CFF}\x{2D7F}\x{2DE0}-\x{2DFF}\x{2E00}-\x{2E01}\x{2E02}\x{2E03}\x{2E04}\x{2E05}\x{2E06}-\x{2E08}\x{2E09}\x{2E0A}\x{2E0B}\x{2E0C}\x{2E0D}\x{2E0E}-\x{2E16}\x{2E17}\x{2E18}-\x{2E19}\x{2E1A}\x{2E1B}\x{2E1C}\x{2E1D}\x{2E1E}-\x{2E1F}\x{2E20}\x{2E21}\x{2E22}\x{2E23}\x{2E24}\x{2E25}\x{2E26}\x{2E27}\x{2E28}\x{2E29}\x{2E2A}-\x{2E2E}\x{2E2F}\x{2E30}-\x{2E39}\x{2E3A}-\x{2E3B}\x{2E3C}-\x{2E3F}\x{2E40}\x{2E41}\x{2E42}\x{2E43}-\x{2E4F}\x{2E50}-\x{2E51}\x{2E52}\x{2E80}-\x{2E99}\x{2E9B}-\x{2EF3}\x{2F00}-\x{2FD5}\x{2FF0}-\x{2FFB}\x{3000}\x{3001}-\x{3003}\x{3004}\x{3008}\x{3009}\x{300A}\x{300B}\x{300C}\x{300D}\x{300E}\x{300F}\x{3010}\x{3011}\x{3012}-\x{3013}\x{3014}\x{3015}\x{3016}\x{3017}\x{3018}\x{3019}\x{301A}\x{301B}\x{301C}\x{301D}\x{301E}-\x{301F}\x{3020}\x{302A}-\x{302D}\x{3030}\x{3036}-\x{3037}\x{303D}\x{303E}-\x{303F}\x{3099}-\x{309A}\x{309B}-\x{309C}\x{30A0}\x{30FB}\x{31C0}-\x{31E3}\x{321D}-\x{321E}\x{3250}\x{3251}-\x{325F}\x{327C}-\x{327E}\x{32B1}-\x{32BF}\x{32CC}-\x{32CF}\x{3377}-\x{337A}\x{33DE}-\x{33DF}\x{33FF}\x{4DC0}-\x{4DFF}\x{A490}-\x{A4C6}\x{A60D}-\x{A60F}\x{A66F}\x{A670}-\x{A672}\x{A673}\x{A674}-\x{A67D}\x{A67E}\x{A67F}\x{A69E}-\x{A69F}\x{A6F0}-\x{A6F1}\x{A700}-\x{A716}\x{A717}-\x{A71F}\x{A720}-\x{A721}\x{A788}\x{A802}\x{A806}\x{A80B}\x{A825}-\x{A826}\x{A828}-\x{A82B}\x{A82C}\x{A838}\x{A839}\x{A874}-\x{A877}\x{A8C4}-\x{A8C5}\x{A8E0}-\x{A8F1}\x{A8FF}\x{A926}-\x{A92D}\x{A947}-\x{A951}\x{A980}-\x{A982}\x{A9B3}\x{A9B6}-\x{A9B9}\x{A9BC}-\x{A9BD}\x{A9E5}\x{AA29}-\x{AA2E}\x{AA31}-\x{AA32}\x{AA35}-\x{AA36}\x{AA43}\x{AA4C}\x{AA7C}\x{AAB0}\x{AAB2}-\x{AAB4}\x{AAB7}-\x{AAB8}\x{AABE}-\x{AABF}\x{AAC1}\x{AAEC}-\x{AAED}\x{AAF6}\x{AB6A}-\x{AB6B}\x{ABE5}\x{ABE8}\x{ABED}\x{FB1D}\x{FB1E}\x{FB1F}-\x{FB28}\x{FB29}\x{FB2A}-\x{FB36}\x{FB37}\x{FB38}-\x{FB3C}\x{FB3D}\x{FB3E}\x{FB3F}\x{FB40}-\x{FB41}\x{FB42}\x{FB43}-\x{FB44}\x{FB45}\x{FB46}-\x{FB4F}\x{FB50}-\x{FBB1}\x{FBB2}-\x{FBC1}\x{FBC2}-\x{FBD2}\x{FBD3}-\x{FD3D}\x{FD3E}\x{FD3F}\x{FD40}-\x{FD4F}\x{FD50}-\x{FD8F}\x{FD90}-\x{FD91}\x{FD92}-\x{FDC7}\x{FDC8}-\x{FDCF}\x{FDD0}-\x{FDEF}\x{FDF0}-\x{FDFB}\x{FDFC}\x{FDFD}\x{FDFE}-\x{FDFF}\x{FE00}-\x{FE0F}\x{FE10}-\x{FE16}\x{FE17}\x{FE18}\x{FE19}\x{FE20}-\x{FE2F}\x{FE30}\x{FE31}-\x{FE32}\x{FE33}-\x{FE34}\x{FE35}\x{FE36}\x{FE37}\x{FE38}\x{FE39}\x{FE3A}\x{FE3B}\x{FE3C}\x{FE3D}\x{FE3E}\x{FE3F}\x{FE40}\x{FE41}\x{FE42}\x{FE43}\x{FE44}\x{FE45}-\x{FE46}\x{FE47}\x{FE48}\x{FE49}-\x{FE4C}\x{FE4D}-\x{FE4F}\x{FE50}\x{FE51}\x{FE52}\x{FE54}\x{FE55}\x{FE56}-\x{FE57}\x{FE58}\x{FE59}\x{FE5A}\x{FE5B}\x{FE5C}\x{FE5D}\x{FE5E}\x{FE5F}\x{FE60}-\x{FE61}\x{FE62}\x{FE63}\x{FE64}-\x{FE66}\x{FE68}\x{FE69}\x{FE6A}\x{FE6B}\x{FE70}-\x{FE74}\x{FE75}\x{FE76}-\x{FEFC}\x{FEFD}-\x{FEFE}\x{FEFF}\x{FF01}-\x{FF02}\x{FF03}\x{FF04}\x{FF05}\x{FF06}-\x{FF07}\x{FF08}\x{FF09}\x{FF0A}\x{FF0B}\x{FF0C}\x{FF0D}\x{FF0E}-\x{FF0F}\x{FF1A}\x{FF1B}\x{FF1C}-\x{FF1E}\x{FF1F}-\x{FF20}\x{FF3B}\x{FF3C}\x{FF3D}\x{FF3E}\x{FF3F}\x{FF40}\x{FF5B}\x{FF5C}\x{FF5D}\x{FF5E}\x{FF5F}\x{FF60}\x{FF61}\x{FF62}\x{FF63}\x{FF64}-\x{FF65}\x{FFE0}-\x{FFE1}\x{FFE2}\x{FFE3}\x{FFE4}\x{FFE5}-\x{FFE6}\x{FFE8}\x{FFE9}-\x{FFEC}\x{FFED}-\x{FFEE}\x{FFF0}-\x{FFF8}\x{FFF9}-\x{FFFB}\x{FFFC}-\x{FFFD}\x{FFFE}-\x{FFFF}\x{10101}\x{10140}-\x{10174}\x{10175}-\x{10178}\x{10179}-\x{10189}\x{1018A}-\x{1018B}\x{1018C}\x{10190}-\x{1019C}\x{101A0}\x{101FD}\x{102E0}\x{10376}-\x{1037A}\x{10800}-\x{10805}\x{10806}-\x{10807}\x{10808}\x{10809}\x{1080A}-\x{10835}\x{10836}\x{10837}-\x{10838}\x{10839}-\x{1083B}\x{1083C}\x{1083D}-\x{1083E}\x{1083F}-\x{10855}\x{10856}\x{10857}\x{10858}-\x{1085F}\x{10860}-\x{10876}\x{10877}-\x{10878}\x{10879}-\x{1087F}\x{10880}-\x{1089E}\x{1089F}-\x{108A6}\x{108A7}-\x{108AF}\x{108B0}-\x{108DF}\x{108E0}-\x{108F2}\x{108F3}\x{108F4}-\x{108F5}\x{108F6}-\x{108FA}\x{108FB}-\x{108FF}\x{10900}-\x{10915}\x{10916}-\x{1091B}\x{1091C}-\x{1091E}\x{1091F}\x{10920}-\x{10939}\x{1093A}-\x{1093E}\x{1093F}\x{10940}-\x{1097F}\x{10980}-\x{109B7}\x{109B8}-\x{109BB}\x{109BC}-\x{109BD}\x{109BE}-\x{109BF}\x{109C0}-\x{109CF}\x{109D0}-\x{109D1}\x{109D2}-\x{109FF}\x{10A00}\x{10A01}-\x{10A03}\x{10A04}\x{10A05}-\x{10A06}\x{10A07}-\x{10A0B}\x{10A0C}-\x{10A0F}\x{10A10}-\x{10A13}\x{10A14}\x{10A15}-\x{10A17}\x{10A18}\x{10A19}-\x{10A35}\x{10A36}-\x{10A37}\x{10A38}-\x{10A3A}\x{10A3B}-\x{10A3E}\x{10A3F}\x{10A40}-\x{10A48}\x{10A49}-\x{10A4F}\x{10A50}-\x{10A58}\x{10A59}-\x{10A5F}\x{10A60}-\x{10A7C}\x{10A7D}-\x{10A7E}\x{10A7F}\x{10A80}-\x{10A9C}\x{10A9D}-\x{10A9F}\x{10AA0}-\x{10ABF}\x{10AC0}-\x{10AC7}\x{10AC8}\x{10AC9}-\x{10AE4}\x{10AE5}-\x{10AE6}\x{10AE7}-\x{10AEA}\x{10AEB}-\x{10AEF}\x{10AF0}-\x{10AF6}\x{10AF7}-\x{10AFF}\x{10B00}-\x{10B35}\x{10B36}-\x{10B38}\x{10B39}-\x{10B3F}\x{10B40}-\x{10B55}\x{10B56}-\x{10B57}\x{10B58}-\x{10B5F}\x{10B60}-\x{10B72}\x{10B73}-\x{10B77}\x{10B78}-\x{10B7F}\x{10B80}-\x{10B91}\x{10B92}-\x{10B98}\x{10B99}-\x{10B9C}\x{10B9D}-\x{10BA8}\x{10BA9}-\x{10BAF}\x{10BB0}-\x{10BFF}\x{10C00}-\x{10C48}\x{10C49}-\x{10C7F}\x{10C80}-\x{10CB2}\x{10CB3}-\x{10CBF}\x{10CC0}-\x{10CF2}\x{10CF3}-\x{10CF9}\x{10CFA}-\x{10CFF}\x{10D00}-\x{10D23}\x{10D24}-\x{10D27}\x{10D28}-\x{10D2F}\x{10D30}-\x{10D39}\x{10D3A}-\x{10D3F}\x{10D40}-\x{10E5F}\x{10E60}-\x{10E7E}\x{10E7F}\x{10E80}-\x{10EA9}\x{10EAA}\x{10EAB}-\x{10EAC}\x{10EAD}\x{10EAE}-\x{10EAF}\x{10EB0}-\x{10EB1}\x{10EB2}-\x{10EFF}\x{10F00}-\x{10F1C}\x{10F1D}-\x{10F26}\x{10F27}\x{10F28}-\x{10F2F}\x{10F30}-\x{10F45}\x{10F46}-\x{10F50}\x{10F51}-\x{10F54}\x{10F55}-\x{10F59}\x{10F5A}-\x{10F6F}\x{10F70}-\x{10FAF}\x{10FB0}-\x{10FC4}\x{10FC5}-\x{10FCB}\x{10FCC}-\x{10FDF}\x{10FE0}-\x{10FF6}\x{10FF7}-\x{10FFF}\x{11001}\x{11038}-\x{11046}\x{11052}-\x{11065}\x{1107F}-\x{11081}\x{110B3}-\x{110B6}\x{110B9}-\x{110BA}\x{11100}-\x{11102}\x{11127}-\x{1112B}\x{1112D}-\x{11134}\x{11173}\x{11180}-\x{11181}\x{111B6}-\x{111BE}\x{111C9}-\x{111CC}\x{111CF}\x{1122F}-\x{11231}\x{11234}\x{11236}-\x{11237}\x{1123E}\x{112DF}\x{112E3}-\x{112EA}\x{11300}-\x{11301}\x{1133B}-\x{1133C}\x{11340}\x{11366}-\x{1136C}\x{11370}-\x{11374}\x{11438}-\x{1143F}\x{11442}-\x{11444}\x{11446}\x{1145E}\x{114B3}-\x{114B8}\x{114BA}\x{114BF}-\x{114C0}\x{114C2}-\x{114C3}\x{115B2}-\x{115B5}\x{115BC}-\x{115BD}\x{115BF}-\x{115C0}\x{115DC}-\x{115DD}\x{11633}-\x{1163A}\x{1163D}\x{1163F}-\x{11640}\x{11660}-\x{1166C}\x{116AB}\x{116AD}\x{116B0}-\x{116B5}\x{116B7}\x{1171D}-\x{1171F}\x{11722}-\x{11725}\x{11727}-\x{1172B}\x{1182F}-\x{11837}\x{11839}-\x{1183A}\x{1193B}-\x{1193C}\x{1193E}\x{11943}\x{119D4}-\x{119D7}\x{119DA}-\x{119DB}\x{119E0}\x{11A01}-\x{11A06}\x{11A09}-\x{11A0A}\x{11A33}-\x{11A38}\x{11A3B}-\x{11A3E}\x{11A47}\x{11A51}-\x{11A56}\x{11A59}-\x{11A5B}\x{11A8A}-\x{11A96}\x{11A98}-\x{11A99}\x{11C30}-\x{11C36}\x{11C38}-\x{11C3D}\x{11C92}-\x{11CA7}\x{11CAA}-\x{11CB0}\x{11CB2}-\x{11CB3}\x{11CB5}-\x{11CB6}\x{11D31}-\x{11D36}\x{11D3A}\x{11D3C}-\x{11D3D}\x{11D3F}-\x{11D45}\x{11D47}\x{11D90}-\x{11D91}\x{11D95}\x{11D97}\x{11EF3}-\x{11EF4}\x{11FD5}-\x{11FDC}\x{11FDD}-\x{11FE0}\x{11FE1}-\x{11FF1}\x{16AF0}-\x{16AF4}\x{16B30}-\x{16B36}\x{16F4F}\x{16F8F}-\x{16F92}\x{16FE2}\x{16FE4}\x{1BC9D}-\x{1BC9E}\x{1BCA0}-\x{1BCA3}\x{1D167}-\x{1D169}\x{1D173}-\x{1D17A}\x{1D17B}-\x{1D182}\x{1D185}-\x{1D18B}\x{1D1AA}-\x{1D1AD}\x{1D200}-\x{1D241}\x{1D242}-\x{1D244}\x{1D245}\x{1D300}-\x{1D356}\x{1D6DB}\x{1D715}\x{1D74F}\x{1D789}\x{1D7C3}\x{1DA00}-\x{1DA36}\x{1DA3B}-\x{1DA6C}\x{1DA75}\x{1DA84}\x{1DA9B}-\x{1DA9F}\x{1DAA1}-\x{1DAAF}\x{1E000}-\x{1E006}\x{1E008}-\x{1E018}\x{1E01B}-\x{1E021}\x{1E023}-\x{1E024}\x{1E026}-\x{1E02A}\x{1E130}-\x{1E136}\x{1E2EC}-\x{1E2EF}\x{1E2FF}\x{1E800}-\x{1E8C4}\x{1E8C5}-\x{1E8C6}\x{1E8C7}-\x{1E8CF}\x{1E8D0}-\x{1E8D6}\x{1E8D7}-\x{1E8FF}\x{1E900}-\x{1E943}\x{1E944}-\x{1E94A}\x{1E94B}\x{1E94C}-\x{1E94F}\x{1E950}-\x{1E959}\x{1E95A}-\x{1E95D}\x{1E95E}-\x{1E95F}\x{1E960}-\x{1EC6F}\x{1EC70}\x{1EC71}-\x{1ECAB}\x{1ECAC}\x{1ECAD}-\x{1ECAF}\x{1ECB0}\x{1ECB1}-\x{1ECB4}\x{1ECB5}-\x{1ECBF}\x{1ECC0}-\x{1ECFF}\x{1ED00}\x{1ED01}-\x{1ED2D}\x{1ED2E}\x{1ED2F}-\x{1ED3D}\x{1ED3E}-\x{1ED4F}\x{1ED50}-\x{1EDFF}\x{1EE00}-\x{1EE03}\x{1EE04}\x{1EE05}-\x{1EE1F}\x{1EE20}\x{1EE21}-\x{1EE22}\x{1EE23}\x{1EE24}\x{1EE25}-\x{1EE26}\x{1EE27}\x{1EE28}\x{1EE29}-\x{1EE32}\x{1EE33}\x{1EE34}-\x{1EE37}\x{1EE38}\x{1EE39}\x{1EE3A}\x{1EE3B}\x{1EE3C}-\x{1EE41}\x{1EE42}\x{1EE43}-\x{1EE46}\x{1EE47}\x{1EE48}\x{1EE49}\x{1EE4A}\x{1EE4B}\x{1EE4C}\x{1EE4D}-\x{1EE4F}\x{1EE50}\x{1EE51}-\x{1EE52}\x{1EE53}\x{1EE54}\x{1EE55}-\x{1EE56}\x{1EE57}\x{1EE58}\x{1EE59}\x{1EE5A}\x{1EE5B}\x{1EE5C}\x{1EE5D}\x{1EE5E}\x{1EE5F}\x{1EE60}\x{1EE61}-\x{1EE62}\x{1EE63}\x{1EE64}\x{1EE65}-\x{1EE66}\x{1EE67}-\x{1EE6A}\x{1EE6B}\x{1EE6C}-\x{1EE72}\x{1EE73}\x{1EE74}-\x{1EE77}\x{1EE78}\x{1EE79}-\x{1EE7C}\x{1EE7D}\x{1EE7E}\x{1EE7F}\x{1EE80}-\x{1EE89}\x{1EE8A}\x{1EE8B}-\x{1EE9B}\x{1EE9C}-\x{1EEA0}\x{1EEA1}-\x{1EEA3}\x{1EEA4}\x{1EEA5}-\x{1EEA9}\x{1EEAA}\x{1EEAB}-\x{1EEBB}\x{1EEBC}-\x{1EEEF}\x{1EEF0}-\x{1EEF1}\x{1EEF2}-\x{1EEFF}\x{1EF00}-\x{1EFFF}\x{1F000}-\x{1F02B}\x{1F030}-\x{1F093}\x{1F0A0}-\x{1F0AE}\x{1F0B1}-\x{1F0BF}\x{1F0C1}-\x{1F0CF}\x{1F0D1}-\x{1F0F5}\x{1F10B}-\x{1F10C}\x{1F10D}-\x{1F10F}\x{1F12F}\x{1F16A}-\x{1F16F}\x{1F1AD}\x{1F260}-\x{1F265}\x{1F300}-\x{1F3FA}\x{1F3FB}-\x{1F3FF}\x{1F400}-\x{1F6D7}\x{1F6E0}-\x{1F6EC}\x{1F6F0}-\x{1F6FC}\x{1F700}-\x{1F773}\x{1F780}-\x{1F7D8}\x{1F7E0}-\x{1F7EB}\x{1F800}-\x{1F80B}\x{1F810}-\x{1F847}\x{1F850}-\x{1F859}\x{1F860}-\x{1F887}\x{1F890}-\x{1F8AD}\x{1F8B0}-\x{1F8B1}\x{1F900}-\x{1F978}\x{1F97A}-\x{1F9CB}\x{1F9CD}-\x{1FA53}\x{1FA60}-\x{1FA6D}\x{1FA70}-\x{1FA74}\x{1FA78}-\x{1FA7A}\x{1FA80}-\x{1FA86}\x{1FA90}-\x{1FAA8}\x{1FAB0}-\x{1FAB6}\x{1FAC0}-\x{1FAC2}\x{1FAD0}-\x{1FAD6}\x{1FB00}-\x{1FB92}\x{1FB94}-\x{1FBCA}\x{1FFFE}-\x{1FFFF}\x{2FFFE}-\x{2FFFF}\x{3FFFE}-\x{3FFFF}\x{4FFFE}-\x{4FFFF}\x{5FFFE}-\x{5FFFF}\x{6FFFE}-\x{6FFFF}\x{7FFFE}-\x{7FFFF}\x{8FFFE}-\x{8FFFF}\x{9FFFE}-\x{9FFFF}\x{AFFFE}-\x{AFFFF}\x{BFFFE}-\x{BFFFF}\x{CFFFE}-\x{CFFFF}\x{DFFFE}-\x{E0000}\x{E0001}\x{E0002}-\x{E001F}\x{E0020}-\x{E007F}\x{E0080}-\x{E00FF}\x{E0100}-\x{E01EF}\x{E01F0}-\x{E0FFF}\x{EFFFE}-\x{EFFFF}\x{FFFFE}-\x{FFFFF}\x{10FFFE}-\x{10FFFF}][\x{0300}-\x{036F}\x{0483}-\x{0487}\x{0488}-\x{0489}\x{0591}-\x{05BD}\x{05BF}\x{05C1}-\x{05C2}\x{05C4}-\x{05C5}\x{05C7}\x{0610}-\x{061A}\x{064B}-\x{065F}\x{0670}\x{06D6}-\x{06DC}\x{06DF}-\x{06E4}\x{06E7}-\x{06E8}\x{06EA}-\x{06ED}\x{0711}\x{0730}-\x{074A}\x{07A6}-\x{07B0}\x{07EB}-\x{07F3}\x{07FD}\x{0816}-\x{0819}\x{081B}-\x{0823}\x{0825}-\x{0827}\x{0829}-\x{082D}\x{0859}-\x{085B}\x{08D3}-\x{08E1}\x{08E3}-\x{0902}\x{093A}\x{093C}\x{0941}-\x{0948}\x{094D}\x{0951}-\x{0957}\x{0962}-\x{0963}\x{0981}\x{09BC}\x{09C1}-\x{09C4}\x{09CD}\x{09E2}-\x{09E3}\x{09FE}\x{0A01}-\x{0A02}\x{0A3C}\x{0A41}-\x{0A42}\x{0A47}-\x{0A48}\x{0A4B}-\x{0A4D}\x{0A51}\x{0A70}-\x{0A71}\x{0A75}\x{0A81}-\x{0A82}\x{0ABC}\x{0AC1}-\x{0AC5}\x{0AC7}-\x{0AC8}\x{0ACD}\x{0AE2}-\x{0AE3}\x{0AFA}-\x{0AFF}\x{0B01}\x{0B3C}\x{0B3F}\x{0B41}-\x{0B44}\x{0B4D}\x{0B55}-\x{0B56}\x{0B62}-\x{0B63}\x{0B82}\x{0BC0}\x{0BCD}\x{0C00}\x{0C04}\x{0C3E}-\x{0C40}\x{0C46}-\x{0C48}\x{0C4A}-\x{0C4D}\x{0C55}-\x{0C56}\x{0C62}-\x{0C63}\x{0C81}\x{0CBC}\x{0CCC}-\x{0CCD}\x{0CE2}-\x{0CE3}\x{0D00}-\x{0D01}\x{0D3B}-\x{0D3C}\x{0D41}-\x{0D44}\x{0D4D}\x{0D62}-\x{0D63}\x{0D81}\x{0DCA}\x{0DD2}-\x{0DD4}\x{0DD6}\x{0E31}\x{0E34}-\x{0E3A}\x{0E47}-\x{0E4E}\x{0EB1}\x{0EB4}-\x{0EBC}\x{0EC8}-\x{0ECD}\x{0F18}-\x{0F19}\x{0F35}\x{0F37}\x{0F39}\x{0F71}-\x{0F7E}\x{0F80}-\x{0F84}\x{0F86}-\x{0F87}\x{0F8D}-\x{0F97}\x{0F99}-\x{0FBC}\x{0FC6}\x{102D}-\x{1030}\x{1032}-\x{1037}\x{1039}-\x{103A}\x{103D}-\x{103E}\x{1058}-\x{1059}\x{105E}-\x{1060}\x{1071}-\x{1074}\x{1082}\x{1085}-\x{1086}\x{108D}\x{109D}\x{135D}-\x{135F}\x{1712}-\x{1714}\x{1732}-\x{1734}\x{1752}-\x{1753}\x{1772}-\x{1773}\x{17B4}-\x{17B5}\x{17B7}-\x{17BD}\x{17C6}\x{17C9}-\x{17D3}\x{17DD}\x{180B}-\x{180D}\x{1885}-\x{1886}\x{18A9}\x{1920}-\x{1922}\x{1927}-\x{1928}\x{1932}\x{1939}-\x{193B}\x{1A17}-\x{1A18}\x{1A1B}\x{1A56}\x{1A58}-\x{1A5E}\x{1A60}\x{1A62}\x{1A65}-\x{1A6C}\x{1A73}-\x{1A7C}\x{1A7F}\x{1AB0}-\x{1ABD}\x{1ABE}\x{1ABF}-\x{1AC0}\x{1B00}-\x{1B03}\x{1B34}\x{1B36}-\x{1B3A}\x{1B3C}\x{1B42}\x{1B6B}-\x{1B73}\x{1B80}-\x{1B81}\x{1BA2}-\x{1BA5}\x{1BA8}-\x{1BA9}\x{1BAB}-\x{1BAD}\x{1BE6}\x{1BE8}-\x{1BE9}\x{1BED}\x{1BEF}-\x{1BF1}\x{1C2C}-\x{1C33}\x{1C36}-\x{1C37}\x{1CD0}-\x{1CD2}\x{1CD4}-\x{1CE0}\x{1CE2}-\x{1CE8}\x{1CED}\x{1CF4}\x{1CF8}-\x{1CF9}\x{1DC0}-\x{1DF9}\x{1DFB}-\x{1DFF}\x{20D0}-\x{20DC}\x{20DD}-\x{20E0}\x{20E1}\x{20E2}-\x{20E4}\x{20E5}-\x{20F0}\x{2CEF}-\x{2CF1}\x{2D7F}\x{2DE0}-\x{2DFF}\x{302A}-\x{302D}\x{3099}-\x{309A}\x{A66F}\x{A670}-\x{A672}\x{A674}-\x{A67D}\x{A69E}-\x{A69F}\x{A6F0}-\x{A6F1}\x{A802}\x{A806}\x{A80B}\x{A825}-\x{A826}\x{A82C}\x{A8C4}-\x{A8C5}\x{A8E0}-\x{A8F1}\x{A8FF}\x{A926}-\x{A92D}\x{A947}-\x{A951}\x{A980}-\x{A982}\x{A9B3}\x{A9B6}-\x{A9B9}\x{A9BC}-\x{A9BD}\x{A9E5}\x{AA29}-\x{AA2E}\x{AA31}-\x{AA32}\x{AA35}-\x{AA36}\x{AA43}\x{AA4C}\x{AA7C}\x{AAB0}\x{AAB2}-\x{AAB4}\x{AAB7}-\x{AAB8}\x{AABE}-\x{AABF}\x{AAC1}\x{AAEC}-\x{AAED}\x{AAF6}\x{ABE5}\x{ABE8}\x{ABED}\x{FB1E}\x{FE00}-\x{FE0F}\x{FE20}-\x{FE2F}\x{101FD}\x{102E0}\x{10376}-\x{1037A}\x{10A01}-\x{10A03}\x{10A05}-\x{10A06}\x{10A0C}-\x{10A0F}\x{10A38}-\x{10A3A}\x{10A3F}\x{10AE5}-\x{10AE6}\x{10D24}-\x{10D27}\x{10EAB}-\x{10EAC}\x{10F46}-\x{10F50}\x{11001}\x{11038}-\x{11046}\x{1107F}-\x{11081}\x{110B3}-\x{110B6}\x{110B9}-\x{110BA}\x{11100}-\x{11102}\x{11127}-\x{1112B}\x{1112D}-\x{11134}\x{11173}\x{11180}-\x{11181}\x{111B6}-\x{111BE}\x{111C9}-\x{111CC}\x{111CF}\x{1122F}-\x{11231}\x{11234}\x{11236}-\x{11237}\x{1123E}\x{112DF}\x{112E3}-\x{112EA}\x{11300}-\x{11301}\x{1133B}-\x{1133C}\x{11340}\x{11366}-\x{1136C}\x{11370}-\x{11374}\x{11438}-\x{1143F}\x{11442}-\x{11444}\x{11446}\x{1145E}\x{114B3}-\x{114B8}\x{114BA}\x{114BF}-\x{114C0}\x{114C2}-\x{114C3}\x{115B2}-\x{115B5}\x{115BC}-\x{115BD}\x{115BF}-\x{115C0}\x{115DC}-\x{115DD}\x{11633}-\x{1163A}\x{1163D}\x{1163F}-\x{11640}\x{116AB}\x{116AD}\x{116B0}-\x{116B5}\x{116B7}\x{1171D}-\x{1171F}\x{11722}-\x{11725}\x{11727}-\x{1172B}\x{1182F}-\x{11837}\x{11839}-\x{1183A}\x{1193B}-\x{1193C}\x{1193E}\x{11943}\x{119D4}-\x{119D7}\x{119DA}-\x{119DB}\x{119E0}\x{11A01}-\x{11A06}\x{11A09}-\x{11A0A}\x{11A33}-\x{11A38}\x{11A3B}-\x{11A3E}\x{11A47}\x{11A51}-\x{11A56}\x{11A59}-\x{11A5B}\x{11A8A}-\x{11A96}\x{11A98}-\x{11A99}\x{11C30}-\x{11C36}\x{11C38}-\x{11C3D}\x{11C92}-\x{11CA7}\x{11CAA}-\x{11CB0}\x{11CB2}-\x{11CB3}\x{11CB5}-\x{11CB6}\x{11D31}-\x{11D36}\x{11D3A}\x{11D3C}-\x{11D3D}\x{11D3F}-\x{11D45}\x{11D47}\x{11D90}-\x{11D91}\x{11D95}\x{11D97}\x{11EF3}-\x{11EF4}\x{16AF0}-\x{16AF4}\x{16B30}-\x{16B36}\x{16F4F}\x{16F8F}-\x{16F92}\x{16FE4}\x{1BC9D}-\x{1BC9E}\x{1D167}-\x{1D169}\x{1D17B}-\x{1D182}\x{1D185}-\x{1D18B}\x{1D1AA}-\x{1D1AD}\x{1D242}-\x{1D244}\x{1DA00}-\x{1DA36}\x{1DA3B}-\x{1DA6C}\x{1DA75}\x{1DA84}\x{1DA9B}-\x{1DA9F}\x{1DAA1}-\x{1DAAF}\x{1E000}-\x{1E006}\x{1E008}-\x{1E018}\x{1E01B}-\x{1E021}\x{1E023}-\x{1E024}\x{1E026}-\x{1E02A}\x{1E130}-\x{1E136}\x{1E2EC}-\x{1E2EF}\x{1E8D0}-\x{1E8D6}\x{1E944}-\x{1E94A}\x{E0100}-\x{E01EF}]*$/u';

    const ZWNJ = '/([\x{A872}\x{10ACD}\x{10AD7}\x{10D00}\x{10FCB}\x{0620}\x{0626}\x{0628}\x{062A}-\x{062E}\x{0633}-\x{063F}\x{0641}-\x{0647}\x{0649}-\x{064A}\x{066E}-\x{066F}\x{0678}-\x{0687}\x{069A}-\x{06BF}\x{06C1}-\x{06C2}\x{06CC}\x{06CE}\x{06D0}-\x{06D1}\x{06FA}-\x{06FC}\x{06FF}\x{0712}-\x{0714}\x{071A}-\x{071D}\x{071F}-\x{0727}\x{0729}\x{072B}\x{072D}-\x{072E}\x{074E}-\x{0758}\x{075C}-\x{076A}\x{076D}-\x{0770}\x{0772}\x{0775}-\x{0777}\x{077A}-\x{077F}\x{07CA}-\x{07EA}\x{0841}-\x{0845}\x{0848}\x{084A}-\x{0853}\x{0855}\x{0860}\x{0862}-\x{0865}\x{0868}\x{08A0}-\x{08A9}\x{08AF}-\x{08B0}\x{08B3}-\x{08B4}\x{08B6}-\x{08B8}\x{08BA}-\x{08C7}\x{1807}\x{1820}-\x{1842}\x{1843}\x{1844}-\x{1878}\x{1887}-\x{18A8}\x{18AA}\x{A840}-\x{A871}\x{10AC0}-\x{10AC4}\x{10AD3}-\x{10AD6}\x{10AD8}-\x{10ADC}\x{10ADE}-\x{10AE0}\x{10AEB}-\x{10AEE}\x{10B80}\x{10B82}\x{10B86}-\x{10B88}\x{10B8A}-\x{10B8B}\x{10B8D}\x{10B90}\x{10BAD}-\x{10BAE}\x{10D01}-\x{10D21}\x{10D23}\x{10F30}-\x{10F32}\x{10F34}-\x{10F44}\x{10F51}-\x{10F53}\x{10FB0}\x{10FB2}-\x{10FB3}\x{10FB8}\x{10FBB}-\x{10FBC}\x{10FBE}-\x{10FBF}\x{10FC1}\x{10FC4}\x{10FCA}\x{1E900}-\x{1E943}][\x{00AD}\x{0300}-\x{036F}\x{0483}-\x{0487}\x{0488}-\x{0489}\x{0591}-\x{05BD}\x{05BF}\x{05C1}-\x{05C2}\x{05C4}-\x{05C5}\x{05C7}\x{0610}-\x{061A}\x{061C}\x{064B}-\x{065F}\x{0670}\x{06D6}-\x{06DC}\x{06DF}-\x{06E4}\x{06E7}-\x{06E8}\x{06EA}-\x{06ED}\x{070F}\x{0711}\x{0730}-\x{074A}\x{07A6}-\x{07B0}\x{07EB}-\x{07F3}\x{07FD}\x{0816}-\x{0819}\x{081B}-\x{0823}\x{0825}-\x{0827}\x{0829}-\x{082D}\x{0859}-\x{085B}\x{08D3}-\x{08E1}\x{08E3}-\x{0902}\x{093A}\x{093C}\x{0941}-\x{0948}\x{094D}\x{0951}-\x{0957}\x{0962}-\x{0963}\x{0981}\x{09BC}\x{09C1}-\x{09C4}\x{09CD}\x{09E2}-\x{09E3}\x{09FE}\x{0A01}-\x{0A02}\x{0A3C}\x{0A41}-\x{0A42}\x{0A47}-\x{0A48}\x{0A4B}-\x{0A4D}\x{0A51}\x{0A70}-\x{0A71}\x{0A75}\x{0A81}-\x{0A82}\x{0ABC}\x{0AC1}-\x{0AC5}\x{0AC7}-\x{0AC8}\x{0ACD}\x{0AE2}-\x{0AE3}\x{0AFA}-\x{0AFF}\x{0B01}\x{0B3C}\x{0B3F}\x{0B41}-\x{0B44}\x{0B4D}\x{0B55}-\x{0B56}\x{0B62}-\x{0B63}\x{0B82}\x{0BC0}\x{0BCD}\x{0C00}\x{0C04}\x{0C3E}-\x{0C40}\x{0C46}-\x{0C48}\x{0C4A}-\x{0C4D}\x{0C55}-\x{0C56}\x{0C62}-\x{0C63}\x{0C81}\x{0CBC}\x{0CBF}\x{0CC6}\x{0CCC}-\x{0CCD}\x{0CE2}-\x{0CE3}\x{0D00}-\x{0D01}\x{0D3B}-\x{0D3C}\x{0D41}-\x{0D44}\x{0D4D}\x{0D62}-\x{0D63}\x{0D81}\x{0DCA}\x{0DD2}-\x{0DD4}\x{0DD6}\x{0E31}\x{0E34}-\x{0E3A}\x{0E47}-\x{0E4E}\x{0EB1}\x{0EB4}-\x{0EBC}\x{0EC8}-\x{0ECD}\x{0F18}-\x{0F19}\x{0F35}\x{0F37}\x{0F39}\x{0F71}-\x{0F7E}\x{0F80}-\x{0F84}\x{0F86}-\x{0F87}\x{0F8D}-\x{0F97}\x{0F99}-\x{0FBC}\x{0FC6}\x{102D}-\x{1030}\x{1032}-\x{1037}\x{1039}-\x{103A}\x{103D}-\x{103E}\x{1058}-\x{1059}\x{105E}-\x{1060}\x{1071}-\x{1074}\x{1082}\x{1085}-\x{1086}\x{108D}\x{109D}\x{135D}-\x{135F}\x{1712}-\x{1714}\x{1732}-\x{1734}\x{1752}-\x{1753}\x{1772}-\x{1773}\x{17B4}-\x{17B5}\x{17B7}-\x{17BD}\x{17C6}\x{17C9}-\x{17D3}\x{17DD}\x{180B}-\x{180D}\x{1885}-\x{1886}\x{18A9}\x{1920}-\x{1922}\x{1927}-\x{1928}\x{1932}\x{1939}-\x{193B}\x{1A17}-\x{1A18}\x{1A1B}\x{1A56}\x{1A58}-\x{1A5E}\x{1A60}\x{1A62}\x{1A65}-\x{1A6C}\x{1A73}-\x{1A7C}\x{1A7F}\x{1AB0}-\x{1ABD}\x{1ABE}\x{1ABF}-\x{1AC0}\x{1B00}-\x{1B03}\x{1B34}\x{1B36}-\x{1B3A}\x{1B3C}\x{1B42}\x{1B6B}-\x{1B73}\x{1B80}-\x{1B81}\x{1BA2}-\x{1BA5}\x{1BA8}-\x{1BA9}\x{1BAB}-\x{1BAD}\x{1BE6}\x{1BE8}-\x{1BE9}\x{1BED}\x{1BEF}-\x{1BF1}\x{1C2C}-\x{1C33}\x{1C36}-\x{1C37}\x{1CD0}-\x{1CD2}\x{1CD4}-\x{1CE0}\x{1CE2}-\x{1CE8}\x{1CED}\x{1CF4}\x{1CF8}-\x{1CF9}\x{1DC0}-\x{1DF9}\x{1DFB}-\x{1DFF}\x{200B}\x{200E}-\x{200F}\x{202A}-\x{202E}\x{2060}-\x{2064}\x{206A}-\x{206F}\x{20D0}-\x{20DC}\x{20DD}-\x{20E0}\x{20E1}\x{20E2}-\x{20E4}\x{20E5}-\x{20F0}\x{2CEF}-\x{2CF1}\x{2D7F}\x{2DE0}-\x{2DFF}\x{302A}-\x{302D}\x{3099}-\x{309A}\x{A66F}\x{A670}-\x{A672}\x{A674}-\x{A67D}\x{A69E}-\x{A69F}\x{A6F0}-\x{A6F1}\x{A802}\x{A806}\x{A80B}\x{A825}-\x{A826}\x{A82C}\x{A8C4}-\x{A8C5}\x{A8E0}-\x{A8F1}\x{A8FF}\x{A926}-\x{A92D}\x{A947}-\x{A951}\x{A980}-\x{A982}\x{A9B3}\x{A9B6}-\x{A9B9}\x{A9BC}-\x{A9BD}\x{A9E5}\x{AA29}-\x{AA2E}\x{AA31}-\x{AA32}\x{AA35}-\x{AA36}\x{AA43}\x{AA4C}\x{AA7C}\x{AAB0}\x{AAB2}-\x{AAB4}\x{AAB7}-\x{AAB8}\x{AABE}-\x{AABF}\x{AAC1}\x{AAEC}-\x{AAED}\x{AAF6}\x{ABE5}\x{ABE8}\x{ABED}\x{FB1E}\x{FE00}-\x{FE0F}\x{FE20}-\x{FE2F}\x{FEFF}\x{FFF9}-\x{FFFB}\x{101FD}\x{102E0}\x{10376}-\x{1037A}\x{10A01}-\x{10A03}\x{10A05}-\x{10A06}\x{10A0C}-\x{10A0F}\x{10A38}-\x{10A3A}\x{10A3F}\x{10AE5}-\x{10AE6}\x{10D24}-\x{10D27}\x{10EAB}-\x{10EAC}\x{10F46}-\x{10F50}\x{11001}\x{11038}-\x{11046}\x{1107F}-\x{11081}\x{110B3}-\x{110B6}\x{110B9}-\x{110BA}\x{11100}-\x{11102}\x{11127}-\x{1112B}\x{1112D}-\x{11134}\x{11173}\x{11180}-\x{11181}\x{111B6}-\x{111BE}\x{111C9}-\x{111CC}\x{111CF}\x{1122F}-\x{11231}\x{11234}\x{11236}-\x{11237}\x{1123E}\x{112DF}\x{112E3}-\x{112EA}\x{11300}-\x{11301}\x{1133B}-\x{1133C}\x{11340}\x{11366}-\x{1136C}\x{11370}-\x{11374}\x{11438}-\x{1143F}\x{11442}-\x{11444}\x{11446}\x{1145E}\x{114B3}-\x{114B8}\x{114BA}\x{114BF}-\x{114C0}\x{114C2}-\x{114C3}\x{115B2}-\x{115B5}\x{115BC}-\x{115BD}\x{115BF}-\x{115C0}\x{115DC}-\x{115DD}\x{11633}-\x{1163A}\x{1163D}\x{1163F}-\x{11640}\x{116AB}\x{116AD}\x{116B0}-\x{116B5}\x{116B7}\x{1171D}-\x{1171F}\x{11722}-\x{11725}\x{11727}-\x{1172B}\x{1182F}-\x{11837}\x{11839}-\x{1183A}\x{1193B}-\x{1193C}\x{1193E}\x{11943}\x{119D4}-\x{119D7}\x{119DA}-\x{119DB}\x{119E0}\x{11A01}-\x{11A0A}\x{11A33}-\x{11A38}\x{11A3B}-\x{11A3E}\x{11A47}\x{11A51}-\x{11A56}\x{11A59}-\x{11A5B}\x{11A8A}-\x{11A96}\x{11A98}-\x{11A99}\x{11C30}-\x{11C36}\x{11C38}-\x{11C3D}\x{11C3F}\x{11C92}-\x{11CA7}\x{11CAA}-\x{11CB0}\x{11CB2}-\x{11CB3}\x{11CB5}-\x{11CB6}\x{11D31}-\x{11D36}\x{11D3A}\x{11D3C}-\x{11D3D}\x{11D3F}-\x{11D45}\x{11D47}\x{11D90}-\x{11D91}\x{11D95}\x{11D97}\x{11EF3}-\x{11EF4}\x{13430}-\x{13438}\x{16AF0}-\x{16AF4}\x{16B30}-\x{16B36}\x{16F4F}\x{16F8F}-\x{16F92}\x{16FE4}\x{1BC9D}-\x{1BC9E}\x{1BCA0}-\x{1BCA3}\x{1D167}-\x{1D169}\x{1D173}-\x{1D17A}\x{1D17B}-\x{1D182}\x{1D185}-\x{1D18B}\x{1D1AA}-\x{1D1AD}\x{1D242}-\x{1D244}\x{1DA00}-\x{1DA36}\x{1DA3B}-\x{1DA6C}\x{1DA75}\x{1DA84}\x{1DA9B}-\x{1DA9F}\x{1DAA1}-\x{1DAAF}\x{1E000}-\x{1E006}\x{1E008}-\x{1E018}\x{1E01B}-\x{1E021}\x{1E023}-\x{1E024}\x{1E026}-\x{1E02A}\x{1E130}-\x{1E136}\x{1E2EC}-\x{1E2EF}\x{1E8D0}-\x{1E8D6}\x{1E944}-\x{1E94A}\x{1E94B}\x{E0001}\x{E0020}-\x{E007F}\x{E0100}-\x{E01EF}]*\x{200C}[\x{00AD}\x{0300}-\x{036F}\x{0483}-\x{0487}\x{0488}-\x{0489}\x{0591}-\x{05BD}\x{05BF}\x{05C1}-\x{05C2}\x{05C4}-\x{05C5}\x{05C7}\x{0610}-\x{061A}\x{061C}\x{064B}-\x{065F}\x{0670}\x{06D6}-\x{06DC}\x{06DF}-\x{06E4}\x{06E7}-\x{06E8}\x{06EA}-\x{06ED}\x{070F}\x{0711}\x{0730}-\x{074A}\x{07A6}-\x{07B0}\x{07EB}-\x{07F3}\x{07FD}\x{0816}-\x{0819}\x{081B}-\x{0823}\x{0825}-\x{0827}\x{0829}-\x{082D}\x{0859}-\x{085B}\x{08D3}-\x{08E1}\x{08E3}-\x{0902}\x{093A}\x{093C}\x{0941}-\x{0948}\x{094D}\x{0951}-\x{0957}\x{0962}-\x{0963}\x{0981}\x{09BC}\x{09C1}-\x{09C4}\x{09CD}\x{09E2}-\x{09E3}\x{09FE}\x{0A01}-\x{0A02}\x{0A3C}\x{0A41}-\x{0A42}\x{0A47}-\x{0A48}\x{0A4B}-\x{0A4D}\x{0A51}\x{0A70}-\x{0A71}\x{0A75}\x{0A81}-\x{0A82}\x{0ABC}\x{0AC1}-\x{0AC5}\x{0AC7}-\x{0AC8}\x{0ACD}\x{0AE2}-\x{0AE3}\x{0AFA}-\x{0AFF}\x{0B01}\x{0B3C}\x{0B3F}\x{0B41}-\x{0B44}\x{0B4D}\x{0B55}-\x{0B56}\x{0B62}-\x{0B63}\x{0B82}\x{0BC0}\x{0BCD}\x{0C00}\x{0C04}\x{0C3E}-\x{0C40}\x{0C46}-\x{0C48}\x{0C4A}-\x{0C4D}\x{0C55}-\x{0C56}\x{0C62}-\x{0C63}\x{0C81}\x{0CBC}\x{0CBF}\x{0CC6}\x{0CCC}-\x{0CCD}\x{0CE2}-\x{0CE3}\x{0D00}-\x{0D01}\x{0D3B}-\x{0D3C}\x{0D41}-\x{0D44}\x{0D4D}\x{0D62}-\x{0D63}\x{0D81}\x{0DCA}\x{0DD2}-\x{0DD4}\x{0DD6}\x{0E31}\x{0E34}-\x{0E3A}\x{0E47}-\x{0E4E}\x{0EB1}\x{0EB4}-\x{0EBC}\x{0EC8}-\x{0ECD}\x{0F18}-\x{0F19}\x{0F35}\x{0F37}\x{0F39}\x{0F71}-\x{0F7E}\x{0F80}-\x{0F84}\x{0F86}-\x{0F87}\x{0F8D}-\x{0F97}\x{0F99}-\x{0FBC}\x{0FC6}\x{102D}-\x{1030}\x{1032}-\x{1037}\x{1039}-\x{103A}\x{103D}-\x{103E}\x{1058}-\x{1059}\x{105E}-\x{1060}\x{1071}-\x{1074}\x{1082}\x{1085}-\x{1086}\x{108D}\x{109D}\x{135D}-\x{135F}\x{1712}-\x{1714}\x{1732}-\x{1734}\x{1752}-\x{1753}\x{1772}-\x{1773}\x{17B4}-\x{17B5}\x{17B7}-\x{17BD}\x{17C6}\x{17C9}-\x{17D3}\x{17DD}\x{180B}-\x{180D}\x{1885}-\x{1886}\x{18A9}\x{1920}-\x{1922}\x{1927}-\x{1928}\x{1932}\x{1939}-\x{193B}\x{1A17}-\x{1A18}\x{1A1B}\x{1A56}\x{1A58}-\x{1A5E}\x{1A60}\x{1A62}\x{1A65}-\x{1A6C}\x{1A73}-\x{1A7C}\x{1A7F}\x{1AB0}-\x{1ABD}\x{1ABE}\x{1ABF}-\x{1AC0}\x{1B00}-\x{1B03}\x{1B34}\x{1B36}-\x{1B3A}\x{1B3C}\x{1B42}\x{1B6B}-\x{1B73}\x{1B80}-\x{1B81}\x{1BA2}-\x{1BA5}\x{1BA8}-\x{1BA9}\x{1BAB}-\x{1BAD}\x{1BE6}\x{1BE8}-\x{1BE9}\x{1BED}\x{1BEF}-\x{1BF1}\x{1C2C}-\x{1C33}\x{1C36}-\x{1C37}\x{1CD0}-\x{1CD2}\x{1CD4}-\x{1CE0}\x{1CE2}-\x{1CE8}\x{1CED}\x{1CF4}\x{1CF8}-\x{1CF9}\x{1DC0}-\x{1DF9}\x{1DFB}-\x{1DFF}\x{200B}\x{200E}-\x{200F}\x{202A}-\x{202E}\x{2060}-\x{2064}\x{206A}-\x{206F}\x{20D0}-\x{20DC}\x{20DD}-\x{20E0}\x{20E1}\x{20E2}-\x{20E4}\x{20E5}-\x{20F0}\x{2CEF}-\x{2CF1}\x{2D7F}\x{2DE0}-\x{2DFF}\x{302A}-\x{302D}\x{3099}-\x{309A}\x{A66F}\x{A670}-\x{A672}\x{A674}-\x{A67D}\x{A69E}-\x{A69F}\x{A6F0}-\x{A6F1}\x{A802}\x{A806}\x{A80B}\x{A825}-\x{A826}\x{A82C}\x{A8C4}-\x{A8C5}\x{A8E0}-\x{A8F1}\x{A8FF}\x{A926}-\x{A92D}\x{A947}-\x{A951}\x{A980}-\x{A982}\x{A9B3}\x{A9B6}-\x{A9B9}\x{A9BC}-\x{A9BD}\x{A9E5}\x{AA29}-\x{AA2E}\x{AA31}-\x{AA32}\x{AA35}-\x{AA36}\x{AA43}\x{AA4C}\x{AA7C}\x{AAB0}\x{AAB2}-\x{AAB4}\x{AAB7}-\x{AAB8}\x{AABE}-\x{AABF}\x{AAC1}\x{AAEC}-\x{AAED}\x{AAF6}\x{ABE5}\x{ABE8}\x{ABED}\x{FB1E}\x{FE00}-\x{FE0F}\x{FE20}-\x{FE2F}\x{FEFF}\x{FFF9}-\x{FFFB}\x{101FD}\x{102E0}\x{10376}-\x{1037A}\x{10A01}-\x{10A03}\x{10A05}-\x{10A06}\x{10A0C}-\x{10A0F}\x{10A38}-\x{10A3A}\x{10A3F}\x{10AE5}-\x{10AE6}\x{10D24}-\x{10D27}\x{10EAB}-\x{10EAC}\x{10F46}-\x{10F50}\x{11001}\x{11038}-\x{11046}\x{1107F}-\x{11081}\x{110B3}-\x{110B6}\x{110B9}-\x{110BA}\x{11100}-\x{11102}\x{11127}-\x{1112B}\x{1112D}-\x{11134}\x{11173}\x{11180}-\x{11181}\x{111B6}-\x{111BE}\x{111C9}-\x{111CC}\x{111CF}\x{1122F}-\x{11231}\x{11234}\x{11236}-\x{11237}\x{1123E}\x{112DF}\x{112E3}-\x{112EA}\x{11300}-\x{11301}\x{1133B}-\x{1133C}\x{11340}\x{11366}-\x{1136C}\x{11370}-\x{11374}\x{11438}-\x{1143F}\x{11442}-\x{11444}\x{11446}\x{1145E}\x{114B3}-\x{114B8}\x{114BA}\x{114BF}-\x{114C0}\x{114C2}-\x{114C3}\x{115B2}-\x{115B5}\x{115BC}-\x{115BD}\x{115BF}-\x{115C0}\x{115DC}-\x{115DD}\x{11633}-\x{1163A}\x{1163D}\x{1163F}-\x{11640}\x{116AB}\x{116AD}\x{116B0}-\x{116B5}\x{116B7}\x{1171D}-\x{1171F}\x{11722}-\x{11725}\x{11727}-\x{1172B}\x{1182F}-\x{11837}\x{11839}-\x{1183A}\x{1193B}-\x{1193C}\x{1193E}\x{11943}\x{119D4}-\x{119D7}\x{119DA}-\x{119DB}\x{119E0}\x{11A01}-\x{11A0A}\x{11A33}-\x{11A38}\x{11A3B}-\x{11A3E}\x{11A47}\x{11A51}-\x{11A56}\x{11A59}-\x{11A5B}\x{11A8A}-\x{11A96}\x{11A98}-\x{11A99}\x{11C30}-\x{11C36}\x{11C38}-\x{11C3D}\x{11C3F}\x{11C92}-\x{11CA7}\x{11CAA}-\x{11CB0}\x{11CB2}-\x{11CB3}\x{11CB5}-\x{11CB6}\x{11D31}-\x{11D36}\x{11D3A}\x{11D3C}-\x{11D3D}\x{11D3F}-\x{11D45}\x{11D47}\x{11D90}-\x{11D91}\x{11D95}\x{11D97}\x{11EF3}-\x{11EF4}\x{13430}-\x{13438}\x{16AF0}-\x{16AF4}\x{16B30}-\x{16B36}\x{16F4F}\x{16F8F}-\x{16F92}\x{16FE4}\x{1BC9D}-\x{1BC9E}\x{1BCA0}-\x{1BCA3}\x{1D167}-\x{1D169}\x{1D173}-\x{1D17A}\x{1D17B}-\x{1D182}\x{1D185}-\x{1D18B}\x{1D1AA}-\x{1D1AD}\x{1D242}-\x{1D244}\x{1DA00}-\x{1DA36}\x{1DA3B}-\x{1DA6C}\x{1DA75}\x{1DA84}\x{1DA9B}-\x{1DA9F}\x{1DAA1}-\x{1DAAF}\x{1E000}-\x{1E006}\x{1E008}-\x{1E018}\x{1E01B}-\x{1E021}\x{1E023}-\x{1E024}\x{1E026}-\x{1E02A}\x{1E130}-\x{1E136}\x{1E2EC}-\x{1E2EF}\x{1E8D0}-\x{1E8D6}\x{1E944}-\x{1E94A}\x{1E94B}\x{E0001}\x{E0020}-\x{E007F}\x{E0100}-\x{E01EF}]*)[\x{0622}-\x{0625}\x{0627}\x{0629}\x{062F}-\x{0632}\x{0648}\x{0671}-\x{0673}\x{0675}-\x{0677}\x{0688}-\x{0699}\x{06C0}\x{06C3}-\x{06CB}\x{06CD}\x{06CF}\x{06D2}-\x{06D3}\x{06D5}\x{06EE}-\x{06EF}\x{0710}\x{0715}-\x{0719}\x{071E}\x{0728}\x{072A}\x{072C}\x{072F}\x{074D}\x{0759}-\x{075B}\x{076B}-\x{076C}\x{0771}\x{0773}-\x{0774}\x{0778}-\x{0779}\x{0840}\x{0846}-\x{0847}\x{0849}\x{0854}\x{0856}-\x{0858}\x{0867}\x{0869}-\x{086A}\x{08AA}-\x{08AC}\x{08AE}\x{08B1}-\x{08B2}\x{08B9}\x{10AC5}\x{10AC7}\x{10AC9}-\x{10ACA}\x{10ACE}-\x{10AD2}\x{10ADD}\x{10AE1}\x{10AE4}\x{10AEF}\x{10B81}\x{10B83}-\x{10B85}\x{10B89}\x{10B8C}\x{10B8E}-\x{10B8F}\x{10B91}\x{10BA9}-\x{10BAC}\x{10D22}\x{10F33}\x{10F54}\x{10FB4}-\x{10FB6}\x{10FB9}-\x{10FBA}\x{10FBD}\x{10FC2}-\x{10FC3}\x{10FC9}\x{0620}\x{0626}\x{0628}\x{062A}-\x{062E}\x{0633}-\x{063F}\x{0641}-\x{0647}\x{0649}-\x{064A}\x{066E}-\x{066F}\x{0678}-\x{0687}\x{069A}-\x{06BF}\x{06C1}-\x{06C2}\x{06CC}\x{06CE}\x{06D0}-\x{06D1}\x{06FA}-\x{06FC}\x{06FF}\x{0712}-\x{0714}\x{071A}-\x{071D}\x{071F}-\x{0727}\x{0729}\x{072B}\x{072D}-\x{072E}\x{074E}-\x{0758}\x{075C}-\x{076A}\x{076D}-\x{0770}\x{0772}\x{0775}-\x{0777}\x{077A}-\x{077F}\x{07CA}-\x{07EA}\x{0841}-\x{0845}\x{0848}\x{084A}-\x{0853}\x{0855}\x{0860}\x{0862}-\x{0865}\x{0868}\x{08A0}-\x{08A9}\x{08AF}-\x{08B0}\x{08B3}-\x{08B4}\x{08B6}-\x{08B8}\x{08BA}-\x{08C7}\x{1807}\x{1820}-\x{1842}\x{1843}\x{1844}-\x{1878}\x{1887}-\x{18A8}\x{18AA}\x{A840}-\x{A871}\x{10AC0}-\x{10AC4}\x{10AD3}-\x{10AD6}\x{10AD8}-\x{10ADC}\x{10ADE}-\x{10AE0}\x{10AEB}-\x{10AEE}\x{10B80}\x{10B82}\x{10B86}-\x{10B88}\x{10B8A}-\x{10B8B}\x{10B8D}\x{10B90}\x{10BAD}-\x{10BAE}\x{10D01}-\x{10D21}\x{10D23}\x{10F30}-\x{10F32}\x{10F34}-\x{10F44}\x{10F51}-\x{10F53}\x{10FB0}\x{10FB2}-\x{10FB3}\x{10FB8}\x{10FBB}-\x{10FBC}\x{10FBE}-\x{10FBF}\x{10FC1}\x{10FC4}\x{10FCA}\x{1E900}-\x{1E943}]/u';
}
PKϤ$ZH�}SS1polyfill-intl-idn/Resources/unidata/deviation.phpnu�[���<?php

return array (
  223 => 'ss',
  962 => 'σ',
  8204 => '',
  8205 => '',
);
PKϤ$Z�N��""8polyfill-intl-idn/Resources/unidata/DisallowedRanges.phpnu�[���<?php

namespace Symfony\Polyfill\Intl\Idn\Resources\unidata;

/**
 * @internal
 */
final class DisallowedRanges
{
    /**
     * @param int $codePoint
     *
     * @return bool
     */
    public static function inRange($codePoint)
    {
        if ($codePoint >= 128 && $codePoint <= 159) {
            return true;
        }

        if ($codePoint >= 2155 && $codePoint <= 2207) {
            return true;
        }

        if ($codePoint >= 3676 && $codePoint <= 3712) {
            return true;
        }

        if ($codePoint >= 3808 && $codePoint <= 3839) {
            return true;
        }

        if ($codePoint >= 4059 && $codePoint <= 4095) {
            return true;
        }

        if ($codePoint >= 4256 && $codePoint <= 4293) {
            return true;
        }

        if ($codePoint >= 6849 && $codePoint <= 6911) {
            return true;
        }

        if ($codePoint >= 11859 && $codePoint <= 11903) {
            return true;
        }

        if ($codePoint >= 42955 && $codePoint <= 42996) {
            return true;
        }

        if ($codePoint >= 55296 && $codePoint <= 57343) {
            return true;
        }

        if ($codePoint >= 57344 && $codePoint <= 63743) {
            return true;
        }

        if ($codePoint >= 64218 && $codePoint <= 64255) {
            return true;
        }

        if ($codePoint >= 64976 && $codePoint <= 65007) {
            return true;
        }

        if ($codePoint >= 65630 && $codePoint <= 65663) {
            return true;
        }

        if ($codePoint >= 65953 && $codePoint <= 65999) {
            return true;
        }

        if ($codePoint >= 66046 && $codePoint <= 66175) {
            return true;
        }

        if ($codePoint >= 66518 && $codePoint <= 66559) {
            return true;
        }

        if ($codePoint >= 66928 && $codePoint <= 67071) {
            return true;
        }

        if ($codePoint >= 67432 && $codePoint <= 67583) {
            return true;
        }

        if ($codePoint >= 67760 && $codePoint <= 67807) {
            return true;
        }

        if ($codePoint >= 67904 && $codePoint <= 67967) {
            return true;
        }

        if ($codePoint >= 68256 && $codePoint <= 68287) {
            return true;
        }

        if ($codePoint >= 68528 && $codePoint <= 68607) {
            return true;
        }

        if ($codePoint >= 68681 && $codePoint <= 68735) {
            return true;
        }

        if ($codePoint >= 68922 && $codePoint <= 69215) {
            return true;
        }

        if ($codePoint >= 69298 && $codePoint <= 69375) {
            return true;
        }

        if ($codePoint >= 69466 && $codePoint <= 69551) {
            return true;
        }

        if ($codePoint >= 70207 && $codePoint <= 70271) {
            return true;
        }

        if ($codePoint >= 70517 && $codePoint <= 70655) {
            return true;
        }

        if ($codePoint >= 70874 && $codePoint <= 71039) {
            return true;
        }

        if ($codePoint >= 71134 && $codePoint <= 71167) {
            return true;
        }

        if ($codePoint >= 71370 && $codePoint <= 71423) {
            return true;
        }

        if ($codePoint >= 71488 && $codePoint <= 71679) {
            return true;
        }

        if ($codePoint >= 71740 && $codePoint <= 71839) {
            return true;
        }

        if ($codePoint >= 72026 && $codePoint <= 72095) {
            return true;
        }

        if ($codePoint >= 72441 && $codePoint <= 72703) {
            return true;
        }

        if ($codePoint >= 72887 && $codePoint <= 72959) {
            return true;
        }

        if ($codePoint >= 73130 && $codePoint <= 73439) {
            return true;
        }

        if ($codePoint >= 73465 && $codePoint <= 73647) {
            return true;
        }

        if ($codePoint >= 74650 && $codePoint <= 74751) {
            return true;
        }

        if ($codePoint >= 75076 && $codePoint <= 77823) {
            return true;
        }

        if ($codePoint >= 78905 && $codePoint <= 82943) {
            return true;
        }

        if ($codePoint >= 83527 && $codePoint <= 92159) {
            return true;
        }

        if ($codePoint >= 92784 && $codePoint <= 92879) {
            return true;
        }

        if ($codePoint >= 93072 && $codePoint <= 93759) {
            return true;
        }

        if ($codePoint >= 93851 && $codePoint <= 93951) {
            return true;
        }

        if ($codePoint >= 94112 && $codePoint <= 94175) {
            return true;
        }

        if ($codePoint >= 101590 && $codePoint <= 101631) {
            return true;
        }

        if ($codePoint >= 101641 && $codePoint <= 110591) {
            return true;
        }

        if ($codePoint >= 110879 && $codePoint <= 110927) {
            return true;
        }

        if ($codePoint >= 111356 && $codePoint <= 113663) {
            return true;
        }

        if ($codePoint >= 113828 && $codePoint <= 118783) {
            return true;
        }

        if ($codePoint >= 119366 && $codePoint <= 119519) {
            return true;
        }

        if ($codePoint >= 119673 && $codePoint <= 119807) {
            return true;
        }

        if ($codePoint >= 121520 && $codePoint <= 122879) {
            return true;
        }

        if ($codePoint >= 122923 && $codePoint <= 123135) {
            return true;
        }

        if ($codePoint >= 123216 && $codePoint <= 123583) {
            return true;
        }

        if ($codePoint >= 123648 && $codePoint <= 124927) {
            return true;
        }

        if ($codePoint >= 125143 && $codePoint <= 125183) {
            return true;
        }

        if ($codePoint >= 125280 && $codePoint <= 126064) {
            return true;
        }

        if ($codePoint >= 126133 && $codePoint <= 126208) {
            return true;
        }

        if ($codePoint >= 126270 && $codePoint <= 126463) {
            return true;
        }

        if ($codePoint >= 126652 && $codePoint <= 126703) {
            return true;
        }

        if ($codePoint >= 126706 && $codePoint <= 126975) {
            return true;
        }

        if ($codePoint >= 127406 && $codePoint <= 127461) {
            return true;
        }

        if ($codePoint >= 127590 && $codePoint <= 127743) {
            return true;
        }

        if ($codePoint >= 129202 && $codePoint <= 129279) {
            return true;
        }

        if ($codePoint >= 129751 && $codePoint <= 129791) {
            return true;
        }

        if ($codePoint >= 129995 && $codePoint <= 130031) {
            return true;
        }

        if ($codePoint >= 130042 && $codePoint <= 131069) {
            return true;
        }

        if ($codePoint >= 173790 && $codePoint <= 173823) {
            return true;
        }

        if ($codePoint >= 191457 && $codePoint <= 194559) {
            return true;
        }

        if ($codePoint >= 195102 && $codePoint <= 196605) {
            return true;
        }

        if ($codePoint >= 201547 && $codePoint <= 262141) {
            return true;
        }

        if ($codePoint >= 262144 && $codePoint <= 327677) {
            return true;
        }

        if ($codePoint >= 327680 && $codePoint <= 393213) {
            return true;
        }

        if ($codePoint >= 393216 && $codePoint <= 458749) {
            return true;
        }

        if ($codePoint >= 458752 && $codePoint <= 524285) {
            return true;
        }

        if ($codePoint >= 524288 && $codePoint <= 589821) {
            return true;
        }

        if ($codePoint >= 589824 && $codePoint <= 655357) {
            return true;
        }

        if ($codePoint >= 655360 && $codePoint <= 720893) {
            return true;
        }

        if ($codePoint >= 720896 && $codePoint <= 786429) {
            return true;
        }

        if ($codePoint >= 786432 && $codePoint <= 851965) {
            return true;
        }

        if ($codePoint >= 851968 && $codePoint <= 917501) {
            return true;
        }

        if ($codePoint >= 917536 && $codePoint <= 917631) {
            return true;
        }

        if ($codePoint >= 917632 && $codePoint <= 917759) {
            return true;
        }

        if ($codePoint >= 918000 && $codePoint <= 983037) {
            return true;
        }

        if ($codePoint >= 983040 && $codePoint <= 1048573) {
            return true;
        }

        if ($codePoint >= 1048576 && $codePoint <= 1114109) {
            return true;
        }

        return false;
    }
}
PKϤ$Z�u

��=polyfill-intl-idn/Resources/unidata/disallowed_STD3_valid.phpnu�[���<?php

return array (
  0 => true,
  1 => true,
  2 => true,
  3 => true,
  4 => true,
  5 => true,
  6 => true,
  7 => true,
  8 => true,
  9 => true,
  10 => true,
  11 => true,
  12 => true,
  13 => true,
  14 => true,
  15 => true,
  16 => true,
  17 => true,
  18 => true,
  19 => true,
  20 => true,
  21 => true,
  22 => true,
  23 => true,
  24 => true,
  25 => true,
  26 => true,
  27 => true,
  28 => true,
  29 => true,
  30 => true,
  31 => true,
  32 => true,
  33 => true,
  34 => true,
  35 => true,
  36 => true,
  37 => true,
  38 => true,
  39 => true,
  40 => true,
  41 => true,
  42 => true,
  43 => true,
  44 => true,
  47 => true,
  58 => true,
  59 => true,
  60 => true,
  61 => true,
  62 => true,
  63 => true,
  64 => true,
  91 => true,
  92 => true,
  93 => true,
  94 => true,
  95 => true,
  96 => true,
  123 => true,
  124 => true,
  125 => true,
  126 => true,
  127 => true,
  8800 => true,
  8814 => true,
  8815 => true,
);
PKϤ$Z�P�̭̭2polyfill-intl-idn/Resources/unidata/disallowed.phpnu�[���<?php

return array (
  888 => true,
  889 => true,
  896 => true,
  897 => true,
  898 => true,
  899 => true,
  907 => true,
  909 => true,
  930 => true,
  1216 => true,
  1328 => true,
  1367 => true,
  1368 => true,
  1419 => true,
  1420 => true,
  1424 => true,
  1480 => true,
  1481 => true,
  1482 => true,
  1483 => true,
  1484 => true,
  1485 => true,
  1486 => true,
  1487 => true,
  1515 => true,
  1516 => true,
  1517 => true,
  1518 => true,
  1525 => true,
  1526 => true,
  1527 => true,
  1528 => true,
  1529 => true,
  1530 => true,
  1531 => true,
  1532 => true,
  1533 => true,
  1534 => true,
  1535 => true,
  1536 => true,
  1537 => true,
  1538 => true,
  1539 => true,
  1540 => true,
  1541 => true,
  1564 => true,
  1565 => true,
  1757 => true,
  1806 => true,
  1807 => true,
  1867 => true,
  1868 => true,
  1970 => true,
  1971 => true,
  1972 => true,
  1973 => true,
  1974 => true,
  1975 => true,
  1976 => true,
  1977 => true,
  1978 => true,
  1979 => true,
  1980 => true,
  1981 => true,
  1982 => true,
  1983 => true,
  2043 => true,
  2044 => true,
  2094 => true,
  2095 => true,
  2111 => true,
  2140 => true,
  2141 => true,
  2143 => true,
  2229 => true,
  2248 => true,
  2249 => true,
  2250 => true,
  2251 => true,
  2252 => true,
  2253 => true,
  2254 => true,
  2255 => true,
  2256 => true,
  2257 => true,
  2258 => true,
  2274 => true,
  2436 => true,
  2445 => true,
  2446 => true,
  2449 => true,
  2450 => true,
  2473 => true,
  2481 => true,
  2483 => true,
  2484 => true,
  2485 => true,
  2490 => true,
  2491 => true,
  2501 => true,
  2502 => true,
  2505 => true,
  2506 => true,
  2511 => true,
  2512 => true,
  2513 => true,
  2514 => true,
  2515 => true,
  2516 => true,
  2517 => true,
  2518 => true,
  2520 => true,
  2521 => true,
  2522 => true,
  2523 => true,
  2526 => true,
  2532 => true,
  2533 => true,
  2559 => true,
  2560 => true,
  2564 => true,
  2571 => true,
  2572 => true,
  2573 => true,
  2574 => true,
  2577 => true,
  2578 => true,
  2601 => true,
  2609 => true,
  2612 => true,
  2615 => true,
  2618 => true,
  2619 => true,
  2621 => true,
  2627 => true,
  2628 => true,
  2629 => true,
  2630 => true,
  2633 => true,
  2634 => true,
  2638 => true,
  2639 => true,
  2640 => true,
  2642 => true,
  2643 => true,
  2644 => true,
  2645 => true,
  2646 => true,
  2647 => true,
  2648 => true,
  2653 => true,
  2655 => true,
  2656 => true,
  2657 => true,
  2658 => true,
  2659 => true,
  2660 => true,
  2661 => true,
  2679 => true,
  2680 => true,
  2681 => true,
  2682 => true,
  2683 => true,
  2684 => true,
  2685 => true,
  2686 => true,
  2687 => true,
  2688 => true,
  2692 => true,
  2702 => true,
  2706 => true,
  2729 => true,
  2737 => true,
  2740 => true,
  2746 => true,
  2747 => true,
  2758 => true,
  2762 => true,
  2766 => true,
  2767 => true,
  2769 => true,
  2770 => true,
  2771 => true,
  2772 => true,
  2773 => true,
  2774 => true,
  2775 => true,
  2776 => true,
  2777 => true,
  2778 => true,
  2779 => true,
  2780 => true,
  2781 => true,
  2782 => true,
  2783 => true,
  2788 => true,
  2789 => true,
  2802 => true,
  2803 => true,
  2804 => true,
  2805 => true,
  2806 => true,
  2807 => true,
  2808 => true,
  2816 => true,
  2820 => true,
  2829 => true,
  2830 => true,
  2833 => true,
  2834 => true,
  2857 => true,
  2865 => true,
  2868 => true,
  2874 => true,
  2875 => true,
  2885 => true,
  2886 => true,
  2889 => true,
  2890 => true,
  2894 => true,
  2895 => true,
  2896 => true,
  2897 => true,
  2898 => true,
  2899 => true,
  2900 => true,
  2904 => true,
  2905 => true,
  2906 => true,
  2907 => true,
  2910 => true,
  2916 => true,
  2917 => true,
  2936 => true,
  2937 => true,
  2938 => true,
  2939 => true,
  2940 => true,
  2941 => true,
  2942 => true,
  2943 => true,
  2944 => true,
  2945 => true,
  2948 => true,
  2955 => true,
  2956 => true,
  2957 => true,
  2961 => true,
  2966 => true,
  2967 => true,
  2968 => true,
  2971 => true,
  2973 => true,
  2976 => true,
  2977 => true,
  2978 => true,
  2981 => true,
  2982 => true,
  2983 => true,
  2987 => true,
  2988 => true,
  2989 => true,
  3002 => true,
  3003 => true,
  3004 => true,
  3005 => true,
  3011 => true,
  3012 => true,
  3013 => true,
  3017 => true,
  3022 => true,
  3023 => true,
  3025 => true,
  3026 => true,
  3027 => true,
  3028 => true,
  3029 => true,
  3030 => true,
  3032 => true,
  3033 => true,
  3034 => true,
  3035 => true,
  3036 => true,
  3037 => true,
  3038 => true,
  3039 => true,
  3040 => true,
  3041 => true,
  3042 => true,
  3043 => true,
  3044 => true,
  3045 => true,
  3067 => true,
  3068 => true,
  3069 => true,
  3070 => true,
  3071 => true,
  3085 => true,
  3089 => true,
  3113 => true,
  3130 => true,
  3131 => true,
  3132 => true,
  3141 => true,
  3145 => true,
  3150 => true,
  3151 => true,
  3152 => true,
  3153 => true,
  3154 => true,
  3155 => true,
  3156 => true,
  3159 => true,
  3163 => true,
  3164 => true,
  3165 => true,
  3166 => true,
  3167 => true,
  3172 => true,
  3173 => true,
  3184 => true,
  3185 => true,
  3186 => true,
  3187 => true,
  3188 => true,
  3189 => true,
  3190 => true,
  3213 => true,
  3217 => true,
  3241 => true,
  3252 => true,
  3258 => true,
  3259 => true,
  3269 => true,
  3273 => true,
  3278 => true,
  3279 => true,
  3280 => true,
  3281 => true,
  3282 => true,
  3283 => true,
  3284 => true,
  3287 => true,
  3288 => true,
  3289 => true,
  3290 => true,
  3291 => true,
  3292 => true,
  3293 => true,
  3295 => true,
  3300 => true,
  3301 => true,
  3312 => true,
  3315 => true,
  3316 => true,
  3317 => true,
  3318 => true,
  3319 => true,
  3320 => true,
  3321 => true,
  3322 => true,
  3323 => true,
  3324 => true,
  3325 => true,
  3326 => true,
  3327 => true,
  3341 => true,
  3345 => true,
  3397 => true,
  3401 => true,
  3408 => true,
  3409 => true,
  3410 => true,
  3411 => true,
  3428 => true,
  3429 => true,
  3456 => true,
  3460 => true,
  3479 => true,
  3480 => true,
  3481 => true,
  3506 => true,
  3516 => true,
  3518 => true,
  3519 => true,
  3527 => true,
  3528 => true,
  3529 => true,
  3531 => true,
  3532 => true,
  3533 => true,
  3534 => true,
  3541 => true,
  3543 => true,
  3552 => true,
  3553 => true,
  3554 => true,
  3555 => true,
  3556 => true,
  3557 => true,
  3568 => true,
  3569 => true,
  3573 => true,
  3574 => true,
  3575 => true,
  3576 => true,
  3577 => true,
  3578 => true,
  3579 => true,
  3580 => true,
  3581 => true,
  3582 => true,
  3583 => true,
  3584 => true,
  3643 => true,
  3644 => true,
  3645 => true,
  3646 => true,
  3715 => true,
  3717 => true,
  3723 => true,
  3748 => true,
  3750 => true,
  3774 => true,
  3775 => true,
  3781 => true,
  3783 => true,
  3790 => true,
  3791 => true,
  3802 => true,
  3803 => true,
  3912 => true,
  3949 => true,
  3950 => true,
  3951 => true,
  3952 => true,
  3992 => true,
  4029 => true,
  4045 => true,
  4294 => true,
  4296 => true,
  4297 => true,
  4298 => true,
  4299 => true,
  4300 => true,
  4302 => true,
  4303 => true,
  4447 => true,
  4448 => true,
  4681 => true,
  4686 => true,
  4687 => true,
  4695 => true,
  4697 => true,
  4702 => true,
  4703 => true,
  4745 => true,
  4750 => true,
  4751 => true,
  4785 => true,
  4790 => true,
  4791 => true,
  4799 => true,
  4801 => true,
  4806 => true,
  4807 => true,
  4823 => true,
  4881 => true,
  4886 => true,
  4887 => true,
  4955 => true,
  4956 => true,
  4989 => true,
  4990 => true,
  4991 => true,
  5018 => true,
  5019 => true,
  5020 => true,
  5021 => true,
  5022 => true,
  5023 => true,
  5110 => true,
  5111 => true,
  5118 => true,
  5119 => true,
  5760 => true,
  5789 => true,
  5790 => true,
  5791 => true,
  5881 => true,
  5882 => true,
  5883 => true,
  5884 => true,
  5885 => true,
  5886 => true,
  5887 => true,
  5901 => true,
  5909 => true,
  5910 => true,
  5911 => true,
  5912 => true,
  5913 => true,
  5914 => true,
  5915 => true,
  5916 => true,
  5917 => true,
  5918 => true,
  5919 => true,
  5943 => true,
  5944 => true,
  5945 => true,
  5946 => true,
  5947 => true,
  5948 => true,
  5949 => true,
  5950 => true,
  5951 => true,
  5972 => true,
  5973 => true,
  5974 => true,
  5975 => true,
  5976 => true,
  5977 => true,
  5978 => true,
  5979 => true,
  5980 => true,
  5981 => true,
  5982 => true,
  5983 => true,
  5997 => true,
  6001 => true,
  6004 => true,
  6005 => true,
  6006 => true,
  6007 => true,
  6008 => true,
  6009 => true,
  6010 => true,
  6011 => true,
  6012 => true,
  6013 => true,
  6014 => true,
  6015 => true,
  6068 => true,
  6069 => true,
  6110 => true,
  6111 => true,
  6122 => true,
  6123 => true,
  6124 => true,
  6125 => true,
  6126 => true,
  6127 => true,
  6138 => true,
  6139 => true,
  6140 => true,
  6141 => true,
  6142 => true,
  6143 => true,
  6150 => true,
  6158 => true,
  6159 => true,
  6170 => true,
  6171 => true,
  6172 => true,
  6173 => true,
  6174 => true,
  6175 => true,
  6265 => true,
  6266 => true,
  6267 => true,
  6268 => true,
  6269 => true,
  6270 => true,
  6271 => true,
  6315 => true,
  6316 => true,
  6317 => true,
  6318 => true,
  6319 => true,
  6390 => true,
  6391 => true,
  6392 => true,
  6393 => true,
  6394 => true,
  6395 => true,
  6396 => true,
  6397 => true,
  6398 => true,
  6399 => true,
  6431 => true,
  6444 => true,
  6445 => true,
  6446 => true,
  6447 => true,
  6460 => true,
  6461 => true,
  6462 => true,
  6463 => true,
  6465 => true,
  6466 => true,
  6467 => true,
  6510 => true,
  6511 => true,
  6517 => true,
  6518 => true,
  6519 => true,
  6520 => true,
  6521 => true,
  6522 => true,
  6523 => true,
  6524 => true,
  6525 => true,
  6526 => true,
  6527 => true,
  6572 => true,
  6573 => true,
  6574 => true,
  6575 => true,
  6602 => true,
  6603 => true,
  6604 => true,
  6605 => true,
  6606 => true,
  6607 => true,
  6619 => true,
  6620 => true,
  6621 => true,
  6684 => true,
  6685 => true,
  6751 => true,
  6781 => true,
  6782 => true,
  6794 => true,
  6795 => true,
  6796 => true,
  6797 => true,
  6798 => true,
  6799 => true,
  6810 => true,
  6811 => true,
  6812 => true,
  6813 => true,
  6814 => true,
  6815 => true,
  6830 => true,
  6831 => true,
  6988 => true,
  6989 => true,
  6990 => true,
  6991 => true,
  7037 => true,
  7038 => true,
  7039 => true,
  7156 => true,
  7157 => true,
  7158 => true,
  7159 => true,
  7160 => true,
  7161 => true,
  7162 => true,
  7163 => true,
  7224 => true,
  7225 => true,
  7226 => true,
  7242 => true,
  7243 => true,
  7244 => true,
  7305 => true,
  7306 => true,
  7307 => true,
  7308 => true,
  7309 => true,
  7310 => true,
  7311 => true,
  7355 => true,
  7356 => true,
  7368 => true,
  7369 => true,
  7370 => true,
  7371 => true,
  7372 => true,
  7373 => true,
  7374 => true,
  7375 => true,
  7419 => true,
  7420 => true,
  7421 => true,
  7422 => true,
  7423 => true,
  7674 => true,
  7958 => true,
  7959 => true,
  7966 => true,
  7967 => true,
  8006 => true,
  8007 => true,
  8014 => true,
  8015 => true,
  8024 => true,
  8026 => true,
  8028 => true,
  8030 => true,
  8062 => true,
  8063 => true,
  8117 => true,
  8133 => true,
  8148 => true,
  8149 => true,
  8156 => true,
  8176 => true,
  8177 => true,
  8181 => true,
  8191 => true,
  8206 => true,
  8207 => true,
  8228 => true,
  8229 => true,
  8230 => true,
  8232 => true,
  8233 => true,
  8234 => true,
  8235 => true,
  8236 => true,
  8237 => true,
  8238 => true,
  8289 => true,
  8290 => true,
  8291 => true,
  8293 => true,
  8294 => true,
  8295 => true,
  8296 => true,
  8297 => true,
  8298 => true,
  8299 => true,
  8300 => true,
  8301 => true,
  8302 => true,
  8303 => true,
  8306 => true,
  8307 => true,
  8335 => true,
  8349 => true,
  8350 => true,
  8351 => true,
  8384 => true,
  8385 => true,
  8386 => true,
  8387 => true,
  8388 => true,
  8389 => true,
  8390 => true,
  8391 => true,
  8392 => true,
  8393 => true,
  8394 => true,
  8395 => true,
  8396 => true,
  8397 => true,
  8398 => true,
  8399 => true,
  8433 => true,
  8434 => true,
  8435 => true,
  8436 => true,
  8437 => true,
  8438 => true,
  8439 => true,
  8440 => true,
  8441 => true,
  8442 => true,
  8443 => true,
  8444 => true,
  8445 => true,
  8446 => true,
  8447 => true,
  8498 => true,
  8579 => true,
  8588 => true,
  8589 => true,
  8590 => true,
  8591 => true,
  9255 => true,
  9256 => true,
  9257 => true,
  9258 => true,
  9259 => true,
  9260 => true,
  9261 => true,
  9262 => true,
  9263 => true,
  9264 => true,
  9265 => true,
  9266 => true,
  9267 => true,
  9268 => true,
  9269 => true,
  9270 => true,
  9271 => true,
  9272 => true,
  9273 => true,
  9274 => true,
  9275 => true,
  9276 => true,
  9277 => true,
  9278 => true,
  9279 => true,
  9291 => true,
  9292 => true,
  9293 => true,
  9294 => true,
  9295 => true,
  9296 => true,
  9297 => true,
  9298 => true,
  9299 => true,
  9300 => true,
  9301 => true,
  9302 => true,
  9303 => true,
  9304 => true,
  9305 => true,
  9306 => true,
  9307 => true,
  9308 => true,
  9309 => true,
  9310 => true,
  9311 => true,
  9352 => true,
  9353 => true,
  9354 => true,
  9355 => true,
  9356 => true,
  9357 => true,
  9358 => true,
  9359 => true,
  9360 => true,
  9361 => true,
  9362 => true,
  9363 => true,
  9364 => true,
  9365 => true,
  9366 => true,
  9367 => true,
  9368 => true,
  9369 => true,
  9370 => true,
  9371 => true,
  11124 => true,
  11125 => true,
  11158 => true,
  11311 => true,
  11359 => true,
  11508 => true,
  11509 => true,
  11510 => true,
  11511 => true,
  11512 => true,
  11558 => true,
  11560 => true,
  11561 => true,
  11562 => true,
  11563 => true,
  11564 => true,
  11566 => true,
  11567 => true,
  11624 => true,
  11625 => true,
  11626 => true,
  11627 => true,
  11628 => true,
  11629 => true,
  11630 => true,
  11633 => true,
  11634 => true,
  11635 => true,
  11636 => true,
  11637 => true,
  11638 => true,
  11639 => true,
  11640 => true,
  11641 => true,
  11642 => true,
  11643 => true,
  11644 => true,
  11645 => true,
  11646 => true,
  11671 => true,
  11672 => true,
  11673 => true,
  11674 => true,
  11675 => true,
  11676 => true,
  11677 => true,
  11678 => true,
  11679 => true,
  11687 => true,
  11695 => true,
  11703 => true,
  11711 => true,
  11719 => true,
  11727 => true,
  11735 => true,
  11743 => true,
  11930 => true,
  12020 => true,
  12021 => true,
  12022 => true,
  12023 => true,
  12024 => true,
  12025 => true,
  12026 => true,
  12027 => true,
  12028 => true,
  12029 => true,
  12030 => true,
  12031 => true,
  12246 => true,
  12247 => true,
  12248 => true,
  12249 => true,
  12250 => true,
  12251 => true,
  12252 => true,
  12253 => true,
  12254 => true,
  12255 => true,
  12256 => true,
  12257 => true,
  12258 => true,
  12259 => true,
  12260 => true,
  12261 => true,
  12262 => true,
  12263 => true,
  12264 => true,
  12265 => true,
  12266 => true,
  12267 => true,
  12268 => true,
  12269 => true,
  12270 => true,
  12271 => true,
  12272 => true,
  12273 => true,
  12274 => true,
  12275 => true,
  12276 => true,
  12277 => true,
  12278 => true,
  12279 => true,
  12280 => true,
  12281 => true,
  12282 => true,
  12283 => true,
  12284 => true,
  12285 => true,
  12286 => true,
  12287 => true,
  12352 => true,
  12439 => true,
  12440 => true,
  12544 => true,
  12545 => true,
  12546 => true,
  12547 => true,
  12548 => true,
  12592 => true,
  12644 => true,
  12687 => true,
  12772 => true,
  12773 => true,
  12774 => true,
  12775 => true,
  12776 => true,
  12777 => true,
  12778 => true,
  12779 => true,
  12780 => true,
  12781 => true,
  12782 => true,
  12783 => true,
  12831 => true,
  13250 => true,
  13255 => true,
  13272 => true,
  40957 => true,
  40958 => true,
  40959 => true,
  42125 => true,
  42126 => true,
  42127 => true,
  42183 => true,
  42184 => true,
  42185 => true,
  42186 => true,
  42187 => true,
  42188 => true,
  42189 => true,
  42190 => true,
  42191 => true,
  42540 => true,
  42541 => true,
  42542 => true,
  42543 => true,
  42544 => true,
  42545 => true,
  42546 => true,
  42547 => true,
  42548 => true,
  42549 => true,
  42550 => true,
  42551 => true,
  42552 => true,
  42553 => true,
  42554 => true,
  42555 => true,
  42556 => true,
  42557 => true,
  42558 => true,
  42559 => true,
  42744 => true,
  42745 => true,
  42746 => true,
  42747 => true,
  42748 => true,
  42749 => true,
  42750 => true,
  42751 => true,
  42944 => true,
  42945 => true,
  43053 => true,
  43054 => true,
  43055 => true,
  43066 => true,
  43067 => true,
  43068 => true,
  43069 => true,
  43070 => true,
  43071 => true,
  43128 => true,
  43129 => true,
  43130 => true,
  43131 => true,
  43132 => true,
  43133 => true,
  43134 => true,
  43135 => true,
  43206 => true,
  43207 => true,
  43208 => true,
  43209 => true,
  43210 => true,
  43211 => true,
  43212 => true,
  43213 => true,
  43226 => true,
  43227 => true,
  43228 => true,
  43229 => true,
  43230 => true,
  43231 => true,
  43348 => true,
  43349 => true,
  43350 => true,
  43351 => true,
  43352 => true,
  43353 => true,
  43354 => true,
  43355 => true,
  43356 => true,
  43357 => true,
  43358 => true,
  43389 => true,
  43390 => true,
  43391 => true,
  43470 => true,
  43482 => true,
  43483 => true,
  43484 => true,
  43485 => true,
  43519 => true,
  43575 => true,
  43576 => true,
  43577 => true,
  43578 => true,
  43579 => true,
  43580 => true,
  43581 => true,
  43582 => true,
  43583 => true,
  43598 => true,
  43599 => true,
  43610 => true,
  43611 => true,
  43715 => true,
  43716 => true,
  43717 => true,
  43718 => true,
  43719 => true,
  43720 => true,
  43721 => true,
  43722 => true,
  43723 => true,
  43724 => true,
  43725 => true,
  43726 => true,
  43727 => true,
  43728 => true,
  43729 => true,
  43730 => true,
  43731 => true,
  43732 => true,
  43733 => true,
  43734 => true,
  43735 => true,
  43736 => true,
  43737 => true,
  43738 => true,
  43767 => true,
  43768 => true,
  43769 => true,
  43770 => true,
  43771 => true,
  43772 => true,
  43773 => true,
  43774 => true,
  43775 => true,
  43776 => true,
  43783 => true,
  43784 => true,
  43791 => true,
  43792 => true,
  43799 => true,
  43800 => true,
  43801 => true,
  43802 => true,
  43803 => true,
  43804 => true,
  43805 => true,
  43806 => true,
  43807 => true,
  43815 => true,
  43823 => true,
  43884 => true,
  43885 => true,
  43886 => true,
  43887 => true,
  44014 => true,
  44015 => true,
  44026 => true,
  44027 => true,
  44028 => true,
  44029 => true,
  44030 => true,
  44031 => true,
  55204 => true,
  55205 => true,
  55206 => true,
  55207 => true,
  55208 => true,
  55209 => true,
  55210 => true,
  55211 => true,
  55212 => true,
  55213 => true,
  55214 => true,
  55215 => true,
  55239 => true,
  55240 => true,
  55241 => true,
  55242 => true,
  55292 => true,
  55293 => true,
  55294 => true,
  55295 => true,
  64110 => true,
  64111 => true,
  64263 => true,
  64264 => true,
  64265 => true,
  64266 => true,
  64267 => true,
  64268 => true,
  64269 => true,
  64270 => true,
  64271 => true,
  64272 => true,
  64273 => true,
  64274 => true,
  64280 => true,
  64281 => true,
  64282 => true,
  64283 => true,
  64284 => true,
  64311 => true,
  64317 => true,
  64319 => true,
  64322 => true,
  64325 => true,
  64450 => true,
  64451 => true,
  64452 => true,
  64453 => true,
  64454 => true,
  64455 => true,
  64456 => true,
  64457 => true,
  64458 => true,
  64459 => true,
  64460 => true,
  64461 => true,
  64462 => true,
  64463 => true,
  64464 => true,
  64465 => true,
  64466 => true,
  64832 => true,
  64833 => true,
  64834 => true,
  64835 => true,
  64836 => true,
  64837 => true,
  64838 => true,
  64839 => true,
  64840 => true,
  64841 => true,
  64842 => true,
  64843 => true,
  64844 => true,
  64845 => true,
  64846 => true,
  64847 => true,
  64912 => true,
  64913 => true,
  64968 => true,
  64969 => true,
  64970 => true,
  64971 => true,
  64972 => true,
  64973 => true,
  64974 => true,
  64975 => true,
  65022 => true,
  65023 => true,
  65042 => true,
  65049 => true,
  65050 => true,
  65051 => true,
  65052 => true,
  65053 => true,
  65054 => true,
  65055 => true,
  65072 => true,
  65106 => true,
  65107 => true,
  65127 => true,
  65132 => true,
  65133 => true,
  65134 => true,
  65135 => true,
  65141 => true,
  65277 => true,
  65278 => true,
  65280 => true,
  65440 => true,
  65471 => true,
  65472 => true,
  65473 => true,
  65480 => true,
  65481 => true,
  65488 => true,
  65489 => true,
  65496 => true,
  65497 => true,
  65501 => true,
  65502 => true,
  65503 => true,
  65511 => true,
  65519 => true,
  65520 => true,
  65521 => true,
  65522 => true,
  65523 => true,
  65524 => true,
  65525 => true,
  65526 => true,
  65527 => true,
  65528 => true,
  65529 => true,
  65530 => true,
  65531 => true,
  65532 => true,
  65533 => true,
  65534 => true,
  65535 => true,
  65548 => true,
  65575 => true,
  65595 => true,
  65598 => true,
  65614 => true,
  65615 => true,
  65787 => true,
  65788 => true,
  65789 => true,
  65790 => true,
  65791 => true,
  65795 => true,
  65796 => true,
  65797 => true,
  65798 => true,
  65844 => true,
  65845 => true,
  65846 => true,
  65935 => true,
  65949 => true,
  65950 => true,
  65951 => true,
  66205 => true,
  66206 => true,
  66207 => true,
  66257 => true,
  66258 => true,
  66259 => true,
  66260 => true,
  66261 => true,
  66262 => true,
  66263 => true,
  66264 => true,
  66265 => true,
  66266 => true,
  66267 => true,
  66268 => true,
  66269 => true,
  66270 => true,
  66271 => true,
  66300 => true,
  66301 => true,
  66302 => true,
  66303 => true,
  66340 => true,
  66341 => true,
  66342 => true,
  66343 => true,
  66344 => true,
  66345 => true,
  66346 => true,
  66347 => true,
  66348 => true,
  66379 => true,
  66380 => true,
  66381 => true,
  66382 => true,
  66383 => true,
  66427 => true,
  66428 => true,
  66429 => true,
  66430 => true,
  66431 => true,
  66462 => true,
  66500 => true,
  66501 => true,
  66502 => true,
  66503 => true,
  66718 => true,
  66719 => true,
  66730 => true,
  66731 => true,
  66732 => true,
  66733 => true,
  66734 => true,
  66735 => true,
  66772 => true,
  66773 => true,
  66774 => true,
  66775 => true,
  66812 => true,
  66813 => true,
  66814 => true,
  66815 => true,
  66856 => true,
  66857 => true,
  66858 => true,
  66859 => true,
  66860 => true,
  66861 => true,
  66862 => true,
  66863 => true,
  66916 => true,
  66917 => true,
  66918 => true,
  66919 => true,
  66920 => true,
  66921 => true,
  66922 => true,
  66923 => true,
  66924 => true,
  66925 => true,
  66926 => true,
  67383 => true,
  67384 => true,
  67385 => true,
  67386 => true,
  67387 => true,
  67388 => true,
  67389 => true,
  67390 => true,
  67391 => true,
  67414 => true,
  67415 => true,
  67416 => true,
  67417 => true,
  67418 => true,
  67419 => true,
  67420 => true,
  67421 => true,
  67422 => true,
  67423 => true,
  67590 => true,
  67591 => true,
  67593 => true,
  67638 => true,
  67641 => true,
  67642 => true,
  67643 => true,
  67645 => true,
  67646 => true,
  67670 => true,
  67743 => true,
  67744 => true,
  67745 => true,
  67746 => true,
  67747 => true,
  67748 => true,
  67749 => true,
  67750 => true,
  67827 => true,
  67830 => true,
  67831 => true,
  67832 => true,
  67833 => true,
  67834 => true,
  67868 => true,
  67869 => true,
  67870 => true,
  67898 => true,
  67899 => true,
  67900 => true,
  67901 => true,
  67902 => true,
  68024 => true,
  68025 => true,
  68026 => true,
  68027 => true,
  68048 => true,
  68049 => true,
  68100 => true,
  68103 => true,
  68104 => true,
  68105 => true,
  68106 => true,
  68107 => true,
  68116 => true,
  68120 => true,
  68150 => true,
  68151 => true,
  68155 => true,
  68156 => true,
  68157 => true,
  68158 => true,
  68169 => true,
  68170 => true,
  68171 => true,
  68172 => true,
  68173 => true,
  68174 => true,
  68175 => true,
  68185 => true,
  68186 => true,
  68187 => true,
  68188 => true,
  68189 => true,
  68190 => true,
  68191 => true,
  68327 => true,
  68328 => true,
  68329 => true,
  68330 => true,
  68343 => true,
  68344 => true,
  68345 => true,
  68346 => true,
  68347 => true,
  68348 => true,
  68349 => true,
  68350 => true,
  68351 => true,
  68406 => true,
  68407 => true,
  68408 => true,
  68438 => true,
  68439 => true,
  68467 => true,
  68468 => true,
  68469 => true,
  68470 => true,
  68471 => true,
  68498 => true,
  68499 => true,
  68500 => true,
  68501 => true,
  68502 => true,
  68503 => true,
  68504 => true,
  68509 => true,
  68510 => true,
  68511 => true,
  68512 => true,
  68513 => true,
  68514 => true,
  68515 => true,
  68516 => true,
  68517 => true,
  68518 => true,
  68519 => true,
  68520 => true,
  68787 => true,
  68788 => true,
  68789 => true,
  68790 => true,
  68791 => true,
  68792 => true,
  68793 => true,
  68794 => true,
  68795 => true,
  68796 => true,
  68797 => true,
  68798 => true,
  68799 => true,
  68851 => true,
  68852 => true,
  68853 => true,
  68854 => true,
  68855 => true,
  68856 => true,
  68857 => true,
  68904 => true,
  68905 => true,
  68906 => true,
  68907 => true,
  68908 => true,
  68909 => true,
  68910 => true,
  68911 => true,
  69247 => true,
  69290 => true,
  69294 => true,
  69295 => true,
  69416 => true,
  69417 => true,
  69418 => true,
  69419 => true,
  69420 => true,
  69421 => true,
  69422 => true,
  69423 => true,
  69580 => true,
  69581 => true,
  69582 => true,
  69583 => true,
  69584 => true,
  69585 => true,
  69586 => true,
  69587 => true,
  69588 => true,
  69589 => true,
  69590 => true,
  69591 => true,
  69592 => true,
  69593 => true,
  69594 => true,
  69595 => true,
  69596 => true,
  69597 => true,
  69598 => true,
  69599 => true,
  69623 => true,
  69624 => true,
  69625 => true,
  69626 => true,
  69627 => true,
  69628 => true,
  69629 => true,
  69630 => true,
  69631 => true,
  69710 => true,
  69711 => true,
  69712 => true,
  69713 => true,
  69744 => true,
  69745 => true,
  69746 => true,
  69747 => true,
  69748 => true,
  69749 => true,
  69750 => true,
  69751 => true,
  69752 => true,
  69753 => true,
  69754 => true,
  69755 => true,
  69756 => true,
  69757 => true,
  69758 => true,
  69821 => true,
  69826 => true,
  69827 => true,
  69828 => true,
  69829 => true,
  69830 => true,
  69831 => true,
  69832 => true,
  69833 => true,
  69834 => true,
  69835 => true,
  69836 => true,
  69837 => true,
  69838 => true,
  69839 => true,
  69865 => true,
  69866 => true,
  69867 => true,
  69868 => true,
  69869 => true,
  69870 => true,
  69871 => true,
  69882 => true,
  69883 => true,
  69884 => true,
  69885 => true,
  69886 => true,
  69887 => true,
  69941 => true,
  69960 => true,
  69961 => true,
  69962 => true,
  69963 => true,
  69964 => true,
  69965 => true,
  69966 => true,
  69967 => true,
  70007 => true,
  70008 => true,
  70009 => true,
  70010 => true,
  70011 => true,
  70012 => true,
  70013 => true,
  70014 => true,
  70015 => true,
  70112 => true,
  70133 => true,
  70134 => true,
  70135 => true,
  70136 => true,
  70137 => true,
  70138 => true,
  70139 => true,
  70140 => true,
  70141 => true,
  70142 => true,
  70143 => true,
  70162 => true,
  70279 => true,
  70281 => true,
  70286 => true,
  70302 => true,
  70314 => true,
  70315 => true,
  70316 => true,
  70317 => true,
  70318 => true,
  70319 => true,
  70379 => true,
  70380 => true,
  70381 => true,
  70382 => true,
  70383 => true,
  70394 => true,
  70395 => true,
  70396 => true,
  70397 => true,
  70398 => true,
  70399 => true,
  70404 => true,
  70413 => true,
  70414 => true,
  70417 => true,
  70418 => true,
  70441 => true,
  70449 => true,
  70452 => true,
  70458 => true,
  70469 => true,
  70470 => true,
  70473 => true,
  70474 => true,
  70478 => true,
  70479 => true,
  70481 => true,
  70482 => true,
  70483 => true,
  70484 => true,
  70485 => true,
  70486 => true,
  70488 => true,
  70489 => true,
  70490 => true,
  70491 => true,
  70492 => true,
  70500 => true,
  70501 => true,
  70509 => true,
  70510 => true,
  70511 => true,
  70748 => true,
  70754 => true,
  70755 => true,
  70756 => true,
  70757 => true,
  70758 => true,
  70759 => true,
  70760 => true,
  70761 => true,
  70762 => true,
  70763 => true,
  70764 => true,
  70765 => true,
  70766 => true,
  70767 => true,
  70768 => true,
  70769 => true,
  70770 => true,
  70771 => true,
  70772 => true,
  70773 => true,
  70774 => true,
  70775 => true,
  70776 => true,
  70777 => true,
  70778 => true,
  70779 => true,
  70780 => true,
  70781 => true,
  70782 => true,
  70783 => true,
  70856 => true,
  70857 => true,
  70858 => true,
  70859 => true,
  70860 => true,
  70861 => true,
  70862 => true,
  70863 => true,
  71094 => true,
  71095 => true,
  71237 => true,
  71238 => true,
  71239 => true,
  71240 => true,
  71241 => true,
  71242 => true,
  71243 => true,
  71244 => true,
  71245 => true,
  71246 => true,
  71247 => true,
  71258 => true,
  71259 => true,
  71260 => true,
  71261 => true,
  71262 => true,
  71263 => true,
  71277 => true,
  71278 => true,
  71279 => true,
  71280 => true,
  71281 => true,
  71282 => true,
  71283 => true,
  71284 => true,
  71285 => true,
  71286 => true,
  71287 => true,
  71288 => true,
  71289 => true,
  71290 => true,
  71291 => true,
  71292 => true,
  71293 => true,
  71294 => true,
  71295 => true,
  71353 => true,
  71354 => true,
  71355 => true,
  71356 => true,
  71357 => true,
  71358 => true,
  71359 => true,
  71451 => true,
  71452 => true,
  71468 => true,
  71469 => true,
  71470 => true,
  71471 => true,
  71923 => true,
  71924 => true,
  71925 => true,
  71926 => true,
  71927 => true,
  71928 => true,
  71929 => true,
  71930 => true,
  71931 => true,
  71932 => true,
  71933 => true,
  71934 => true,
  71943 => true,
  71944 => true,
  71946 => true,
  71947 => true,
  71956 => true,
  71959 => true,
  71990 => true,
  71993 => true,
  71994 => true,
  72007 => true,
  72008 => true,
  72009 => true,
  72010 => true,
  72011 => true,
  72012 => true,
  72013 => true,
  72014 => true,
  72015 => true,
  72104 => true,
  72105 => true,
  72152 => true,
  72153 => true,
  72165 => true,
  72166 => true,
  72167 => true,
  72168 => true,
  72169 => true,
  72170 => true,
  72171 => true,
  72172 => true,
  72173 => true,
  72174 => true,
  72175 => true,
  72176 => true,
  72177 => true,
  72178 => true,
  72179 => true,
  72180 => true,
  72181 => true,
  72182 => true,
  72183 => true,
  72184 => true,
  72185 => true,
  72186 => true,
  72187 => true,
  72188 => true,
  72189 => true,
  72190 => true,
  72191 => true,
  72264 => true,
  72265 => true,
  72266 => true,
  72267 => true,
  72268 => true,
  72269 => true,
  72270 => true,
  72271 => true,
  72355 => true,
  72356 => true,
  72357 => true,
  72358 => true,
  72359 => true,
  72360 => true,
  72361 => true,
  72362 => true,
  72363 => true,
  72364 => true,
  72365 => true,
  72366 => true,
  72367 => true,
  72368 => true,
  72369 => true,
  72370 => true,
  72371 => true,
  72372 => true,
  72373 => true,
  72374 => true,
  72375 => true,
  72376 => true,
  72377 => true,
  72378 => true,
  72379 => true,
  72380 => true,
  72381 => true,
  72382 => true,
  72383 => true,
  72713 => true,
  72759 => true,
  72774 => true,
  72775 => true,
  72776 => true,
  72777 => true,
  72778 => true,
  72779 => true,
  72780 => true,
  72781 => true,
  72782 => true,
  72783 => true,
  72813 => true,
  72814 => true,
  72815 => true,
  72848 => true,
  72849 => true,
  72872 => true,
  72967 => true,
  72970 => true,
  73015 => true,
  73016 => true,
  73017 => true,
  73019 => true,
  73022 => true,
  73032 => true,
  73033 => true,
  73034 => true,
  73035 => true,
  73036 => true,
  73037 => true,
  73038 => true,
  73039 => true,
  73050 => true,
  73051 => true,
  73052 => true,
  73053 => true,
  73054 => true,
  73055 => true,
  73062 => true,
  73065 => true,
  73103 => true,
  73106 => true,
  73113 => true,
  73114 => true,
  73115 => true,
  73116 => true,
  73117 => true,
  73118 => true,
  73119 => true,
  73649 => true,
  73650 => true,
  73651 => true,
  73652 => true,
  73653 => true,
  73654 => true,
  73655 => true,
  73656 => true,
  73657 => true,
  73658 => true,
  73659 => true,
  73660 => true,
  73661 => true,
  73662 => true,
  73663 => true,
  73714 => true,
  73715 => true,
  73716 => true,
  73717 => true,
  73718 => true,
  73719 => true,
  73720 => true,
  73721 => true,
  73722 => true,
  73723 => true,
  73724 => true,
  73725 => true,
  73726 => true,
  74863 => true,
  74869 => true,
  74870 => true,
  74871 => true,
  74872 => true,
  74873 => true,
  74874 => true,
  74875 => true,
  74876 => true,
  74877 => true,
  74878 => true,
  74879 => true,
  78895 => true,
  78896 => true,
  78897 => true,
  78898 => true,
  78899 => true,
  78900 => true,
  78901 => true,
  78902 => true,
  78903 => true,
  78904 => true,
  92729 => true,
  92730 => true,
  92731 => true,
  92732 => true,
  92733 => true,
  92734 => true,
  92735 => true,
  92767 => true,
  92778 => true,
  92779 => true,
  92780 => true,
  92781 => true,
  92910 => true,
  92911 => true,
  92918 => true,
  92919 => true,
  92920 => true,
  92921 => true,
  92922 => true,
  92923 => true,
  92924 => true,
  92925 => true,
  92926 => true,
  92927 => true,
  92998 => true,
  92999 => true,
  93000 => true,
  93001 => true,
  93002 => true,
  93003 => true,
  93004 => true,
  93005 => true,
  93006 => true,
  93007 => true,
  93018 => true,
  93026 => true,
  93048 => true,
  93049 => true,
  93050 => true,
  93051 => true,
  93052 => true,
  94027 => true,
  94028 => true,
  94029 => true,
  94030 => true,
  94088 => true,
  94089 => true,
  94090 => true,
  94091 => true,
  94092 => true,
  94093 => true,
  94094 => true,
  94181 => true,
  94182 => true,
  94183 => true,
  94184 => true,
  94185 => true,
  94186 => true,
  94187 => true,
  94188 => true,
  94189 => true,
  94190 => true,
  94191 => true,
  94194 => true,
  94195 => true,
  94196 => true,
  94197 => true,
  94198 => true,
  94199 => true,
  94200 => true,
  94201 => true,
  94202 => true,
  94203 => true,
  94204 => true,
  94205 => true,
  94206 => true,
  94207 => true,
  100344 => true,
  100345 => true,
  100346 => true,
  100347 => true,
  100348 => true,
  100349 => true,
  100350 => true,
  100351 => true,
  110931 => true,
  110932 => true,
  110933 => true,
  110934 => true,
  110935 => true,
  110936 => true,
  110937 => true,
  110938 => true,
  110939 => true,
  110940 => true,
  110941 => true,
  110942 => true,
  110943 => true,
  110944 => true,
  110945 => true,
  110946 => true,
  110947 => true,
  110952 => true,
  110953 => true,
  110954 => true,
  110955 => true,
  110956 => true,
  110957 => true,
  110958 => true,
  110959 => true,
  113771 => true,
  113772 => true,
  113773 => true,
  113774 => true,
  113775 => true,
  113789 => true,
  113790 => true,
  113791 => true,
  113801 => true,
  113802 => true,
  113803 => true,
  113804 => true,
  113805 => true,
  113806 => true,
  113807 => true,
  113818 => true,
  113819 => true,
  119030 => true,
  119031 => true,
  119032 => true,
  119033 => true,
  119034 => true,
  119035 => true,
  119036 => true,
  119037 => true,
  119038 => true,
  119039 => true,
  119079 => true,
  119080 => true,
  119155 => true,
  119156 => true,
  119157 => true,
  119158 => true,
  119159 => true,
  119160 => true,
  119161 => true,
  119162 => true,
  119273 => true,
  119274 => true,
  119275 => true,
  119276 => true,
  119277 => true,
  119278 => true,
  119279 => true,
  119280 => true,
  119281 => true,
  119282 => true,
  119283 => true,
  119284 => true,
  119285 => true,
  119286 => true,
  119287 => true,
  119288 => true,
  119289 => true,
  119290 => true,
  119291 => true,
  119292 => true,
  119293 => true,
  119294 => true,
  119295 => true,
  119540 => true,
  119541 => true,
  119542 => true,
  119543 => true,
  119544 => true,
  119545 => true,
  119546 => true,
  119547 => true,
  119548 => true,
  119549 => true,
  119550 => true,
  119551 => true,
  119639 => true,
  119640 => true,
  119641 => true,
  119642 => true,
  119643 => true,
  119644 => true,
  119645 => true,
  119646 => true,
  119647 => true,
  119893 => true,
  119965 => true,
  119968 => true,
  119969 => true,
  119971 => true,
  119972 => true,
  119975 => true,
  119976 => true,
  119981 => true,
  119994 => true,
  119996 => true,
  120004 => true,
  120070 => true,
  120075 => true,
  120076 => true,
  120085 => true,
  120093 => true,
  120122 => true,
  120127 => true,
  120133 => true,
  120135 => true,
  120136 => true,
  120137 => true,
  120145 => true,
  120486 => true,
  120487 => true,
  120780 => true,
  120781 => true,
  121484 => true,
  121485 => true,
  121486 => true,
  121487 => true,
  121488 => true,
  121489 => true,
  121490 => true,
  121491 => true,
  121492 => true,
  121493 => true,
  121494 => true,
  121495 => true,
  121496 => true,
  121497 => true,
  121498 => true,
  121504 => true,
  122887 => true,
  122905 => true,
  122906 => true,
  122914 => true,
  122917 => true,
  123181 => true,
  123182 => true,
  123183 => true,
  123198 => true,
  123199 => true,
  123210 => true,
  123211 => true,
  123212 => true,
  123213 => true,
  123642 => true,
  123643 => true,
  123644 => true,
  123645 => true,
  123646 => true,
  125125 => true,
  125126 => true,
  125260 => true,
  125261 => true,
  125262 => true,
  125263 => true,
  125274 => true,
  125275 => true,
  125276 => true,
  125277 => true,
  126468 => true,
  126496 => true,
  126499 => true,
  126501 => true,
  126502 => true,
  126504 => true,
  126515 => true,
  126520 => true,
  126522 => true,
  126524 => true,
  126525 => true,
  126526 => true,
  126527 => true,
  126528 => true,
  126529 => true,
  126531 => true,
  126532 => true,
  126533 => true,
  126534 => true,
  126536 => true,
  126538 => true,
  126540 => true,
  126544 => true,
  126547 => true,
  126549 => true,
  126550 => true,
  126552 => true,
  126554 => true,
  126556 => true,
  126558 => true,
  126560 => true,
  126563 => true,
  126565 => true,
  126566 => true,
  126571 => true,
  126579 => true,
  126584 => true,
  126589 => true,
  126591 => true,
  126602 => true,
  126620 => true,
  126621 => true,
  126622 => true,
  126623 => true,
  126624 => true,
  126628 => true,
  126634 => true,
  127020 => true,
  127021 => true,
  127022 => true,
  127023 => true,
  127124 => true,
  127125 => true,
  127126 => true,
  127127 => true,
  127128 => true,
  127129 => true,
  127130 => true,
  127131 => true,
  127132 => true,
  127133 => true,
  127134 => true,
  127135 => true,
  127151 => true,
  127152 => true,
  127168 => true,
  127184 => true,
  127222 => true,
  127223 => true,
  127224 => true,
  127225 => true,
  127226 => true,
  127227 => true,
  127228 => true,
  127229 => true,
  127230 => true,
  127231 => true,
  127232 => true,
  127491 => true,
  127492 => true,
  127493 => true,
  127494 => true,
  127495 => true,
  127496 => true,
  127497 => true,
  127498 => true,
  127499 => true,
  127500 => true,
  127501 => true,
  127502 => true,
  127503 => true,
  127548 => true,
  127549 => true,
  127550 => true,
  127551 => true,
  127561 => true,
  127562 => true,
  127563 => true,
  127564 => true,
  127565 => true,
  127566 => true,
  127567 => true,
  127570 => true,
  127571 => true,
  127572 => true,
  127573 => true,
  127574 => true,
  127575 => true,
  127576 => true,
  127577 => true,
  127578 => true,
  127579 => true,
  127580 => true,
  127581 => true,
  127582 => true,
  127583 => true,
  128728 => true,
  128729 => true,
  128730 => true,
  128731 => true,
  128732 => true,
  128733 => true,
  128734 => true,
  128735 => true,
  128749 => true,
  128750 => true,
  128751 => true,
  128765 => true,
  128766 => true,
  128767 => true,
  128884 => true,
  128885 => true,
  128886 => true,
  128887 => true,
  128888 => true,
  128889 => true,
  128890 => true,
  128891 => true,
  128892 => true,
  128893 => true,
  128894 => true,
  128895 => true,
  128985 => true,
  128986 => true,
  128987 => true,
  128988 => true,
  128989 => true,
  128990 => true,
  128991 => true,
  129004 => true,
  129005 => true,
  129006 => true,
  129007 => true,
  129008 => true,
  129009 => true,
  129010 => true,
  129011 => true,
  129012 => true,
  129013 => true,
  129014 => true,
  129015 => true,
  129016 => true,
  129017 => true,
  129018 => true,
  129019 => true,
  129020 => true,
  129021 => true,
  129022 => true,
  129023 => true,
  129036 => true,
  129037 => true,
  129038 => true,
  129039 => true,
  129096 => true,
  129097 => true,
  129098 => true,
  129099 => true,
  129100 => true,
  129101 => true,
  129102 => true,
  129103 => true,
  129114 => true,
  129115 => true,
  129116 => true,
  129117 => true,
  129118 => true,
  129119 => true,
  129160 => true,
  129161 => true,
  129162 => true,
  129163 => true,
  129164 => true,
  129165 => true,
  129166 => true,
  129167 => true,
  129198 => true,
  129199 => true,
  129401 => true,
  129484 => true,
  129620 => true,
  129621 => true,
  129622 => true,
  129623 => true,
  129624 => true,
  129625 => true,
  129626 => true,
  129627 => true,
  129628 => true,
  129629 => true,
  129630 => true,
  129631 => true,
  129646 => true,
  129647 => true,
  129653 => true,
  129654 => true,
  129655 => true,
  129659 => true,
  129660 => true,
  129661 => true,
  129662 => true,
  129663 => true,
  129671 => true,
  129672 => true,
  129673 => true,
  129674 => true,
  129675 => true,
  129676 => true,
  129677 => true,
  129678 => true,
  129679 => true,
  129705 => true,
  129706 => true,
  129707 => true,
  129708 => true,
  129709 => true,
  129710 => true,
  129711 => true,
  129719 => true,
  129720 => true,
  129721 => true,
  129722 => true,
  129723 => true,
  129724 => true,
  129725 => true,
  129726 => true,
  129727 => true,
  129731 => true,
  129732 => true,
  129733 => true,
  129734 => true,
  129735 => true,
  129736 => true,
  129737 => true,
  129738 => true,
  129739 => true,
  129740 => true,
  129741 => true,
  129742 => true,
  129743 => true,
  129939 => true,
  131070 => true,
  131071 => true,
  177973 => true,
  177974 => true,
  177975 => true,
  177976 => true,
  177977 => true,
  177978 => true,
  177979 => true,
  177980 => true,
  177981 => true,
  177982 => true,
  177983 => true,
  178206 => true,
  178207 => true,
  183970 => true,
  183971 => true,
  183972 => true,
  183973 => true,
  183974 => true,
  183975 => true,
  183976 => true,
  183977 => true,
  183978 => true,
  183979 => true,
  183980 => true,
  183981 => true,
  183982 => true,
  183983 => true,
  194664 => true,
  194676 => true,
  194847 => true,
  194911 => true,
  195007 => true,
  196606 => true,
  196607 => true,
  262142 => true,
  262143 => true,
  327678 => true,
  327679 => true,
  393214 => true,
  393215 => true,
  458750 => true,
  458751 => true,
  524286 => true,
  524287 => true,
  589822 => true,
  589823 => true,
  655358 => true,
  655359 => true,
  720894 => true,
  720895 => true,
  786430 => true,
  786431 => true,
  851966 => true,
  851967 => true,
  917502 => true,
  917503 => true,
  917504 => true,
  917505 => true,
  917506 => true,
  917507 => true,
  917508 => true,
  917509 => true,
  917510 => true,
  917511 => true,
  917512 => true,
  917513 => true,
  917514 => true,
  917515 => true,
  917516 => true,
  917517 => true,
  917518 => true,
  917519 => true,
  917520 => true,
  917521 => true,
  917522 => true,
  917523 => true,
  917524 => true,
  917525 => true,
  917526 => true,
  917527 => true,
  917528 => true,
  917529 => true,
  917530 => true,
  917531 => true,
  917532 => true,
  917533 => true,
  917534 => true,
  917535 => true,
  983038 => true,
  983039 => true,
  1048574 => true,
  1048575 => true,
  1114110 => true,
  1114111 => true,
);
PKϤ$Z����UU.polyfill-intl-idn/Resources/unidata/virama.phpnu�[���<?php

return array (
  2381 => 9,
  2509 => 9,
  2637 => 9,
  2765 => 9,
  2893 => 9,
  3021 => 9,
  3149 => 9,
  3277 => 9,
  3387 => 9,
  3388 => 9,
  3405 => 9,
  3530 => 9,
  3642 => 9,
  3770 => 9,
  3972 => 9,
  4153 => 9,
  4154 => 9,
  5908 => 9,
  5940 => 9,
  6098 => 9,
  6752 => 9,
  6980 => 9,
  7082 => 9,
  7083 => 9,
  7154 => 9,
  7155 => 9,
  11647 => 9,
  43014 => 9,
  43052 => 9,
  43204 => 9,
  43347 => 9,
  43456 => 9,
  43766 => 9,
  44013 => 9,
  68159 => 9,
  69702 => 9,
  69759 => 9,
  69817 => 9,
  69939 => 9,
  69940 => 9,
  70080 => 9,
  70197 => 9,
  70378 => 9,
  70477 => 9,
  70722 => 9,
  70850 => 9,
  71103 => 9,
  71231 => 9,
  71350 => 9,
  71467 => 9,
  71737 => 9,
  71997 => 9,
  71998 => 9,
  72160 => 9,
  72244 => 9,
  72263 => 9,
  72345 => 9,
  72767 => 9,
  73028 => 9,
  73029 => 9,
  73111 => 9,
);
PKϤ$Z�d�BB>polyfill-intl-idn/Resources/unidata/disallowed_STD3_mapped.phpnu�[���<?php

return array (
  160 => ' ',
  168 => ' ̈',
  175 => ' ̄',
  180 => ' ́',
  184 => ' ̧',
  728 => ' ̆',
  729 => ' ̇',
  730 => ' ̊',
  731 => ' ̨',
  732 => ' ̃',
  733 => ' ̋',
  890 => ' ι',
  894 => ';',
  900 => ' ́',
  901 => ' ̈́',
  8125 => ' ̓',
  8127 => ' ̓',
  8128 => ' ͂',
  8129 => ' ̈͂',
  8141 => ' ̓̀',
  8142 => ' ̓́',
  8143 => ' ̓͂',
  8157 => ' ̔̀',
  8158 => ' ̔́',
  8159 => ' ̔͂',
  8173 => ' ̈̀',
  8174 => ' ̈́',
  8175 => '`',
  8189 => ' ́',
  8190 => ' ̔',
  8192 => ' ',
  8193 => ' ',
  8194 => ' ',
  8195 => ' ',
  8196 => ' ',
  8197 => ' ',
  8198 => ' ',
  8199 => ' ',
  8200 => ' ',
  8201 => ' ',
  8202 => ' ',
  8215 => ' ̳',
  8239 => ' ',
  8252 => '!!',
  8254 => ' ̅',
  8263 => '??',
  8264 => '?!',
  8265 => '!?',
  8287 => ' ',
  8314 => '+',
  8316 => '=',
  8317 => '(',
  8318 => ')',
  8330 => '+',
  8332 => '=',
  8333 => '(',
  8334 => ')',
  8448 => 'a/c',
  8449 => 'a/s',
  8453 => 'c/o',
  8454 => 'c/u',
  9332 => '(1)',
  9333 => '(2)',
  9334 => '(3)',
  9335 => '(4)',
  9336 => '(5)',
  9337 => '(6)',
  9338 => '(7)',
  9339 => '(8)',
  9340 => '(9)',
  9341 => '(10)',
  9342 => '(11)',
  9343 => '(12)',
  9344 => '(13)',
  9345 => '(14)',
  9346 => '(15)',
  9347 => '(16)',
  9348 => '(17)',
  9349 => '(18)',
  9350 => '(19)',
  9351 => '(20)',
  9372 => '(a)',
  9373 => '(b)',
  9374 => '(c)',
  9375 => '(d)',
  9376 => '(e)',
  9377 => '(f)',
  9378 => '(g)',
  9379 => '(h)',
  9380 => '(i)',
  9381 => '(j)',
  9382 => '(k)',
  9383 => '(l)',
  9384 => '(m)',
  9385 => '(n)',
  9386 => '(o)',
  9387 => '(p)',
  9388 => '(q)',
  9389 => '(r)',
  9390 => '(s)',
  9391 => '(t)',
  9392 => '(u)',
  9393 => '(v)',
  9394 => '(w)',
  9395 => '(x)',
  9396 => '(y)',
  9397 => '(z)',
  10868 => '::=',
  10869 => '==',
  10870 => '===',
  12288 => ' ',
  12443 => ' ゙',
  12444 => ' ゚',
  12800 => '(ᄀ)',
  12801 => '(ᄂ)',
  12802 => '(ᄃ)',
  12803 => '(ᄅ)',
  12804 => '(ᄆ)',
  12805 => '(ᄇ)',
  12806 => '(ᄉ)',
  12807 => '(ᄋ)',
  12808 => '(ᄌ)',
  12809 => '(ᄎ)',
  12810 => '(ᄏ)',
  12811 => '(ᄐ)',
  12812 => '(ᄑ)',
  12813 => '(ᄒ)',
  12814 => '(가)',
  12815 => '(나)',
  12816 => '(다)',
  12817 => '(라)',
  12818 => '(마)',
  12819 => '(바)',
  12820 => '(사)',
  12821 => '(아)',
  12822 => '(자)',
  12823 => '(차)',
  12824 => '(카)',
  12825 => '(타)',
  12826 => '(파)',
  12827 => '(하)',
  12828 => '(주)',
  12829 => '(오전)',
  12830 => '(오후)',
  12832 => '(一)',
  12833 => '(二)',
  12834 => '(三)',
  12835 => '(四)',
  12836 => '(五)',
  12837 => '(六)',
  12838 => '(七)',
  12839 => '(八)',
  12840 => '(九)',
  12841 => '(十)',
  12842 => '(月)',
  12843 => '(火)',
  12844 => '(水)',
  12845 => '(木)',
  12846 => '(金)',
  12847 => '(土)',
  12848 => '(日)',
  12849 => '(株)',
  12850 => '(有)',
  12851 => '(社)',
  12852 => '(名)',
  12853 => '(特)',
  12854 => '(財)',
  12855 => '(祝)',
  12856 => '(労)',
  12857 => '(代)',
  12858 => '(呼)',
  12859 => '(学)',
  12860 => '(監)',
  12861 => '(企)',
  12862 => '(資)',
  12863 => '(協)',
  12864 => '(祭)',
  12865 => '(休)',
  12866 => '(自)',
  12867 => '(至)',
  64297 => '+',
  64606 => ' ٌّ',
  64607 => ' ٍّ',
  64608 => ' َّ',
  64609 => ' ُّ',
  64610 => ' ِّ',
  64611 => ' ّٰ',
  65018 => 'صلى الله عليه وسلم',
  65019 => 'جل جلاله',
  65040 => ',',
  65043 => ':',
  65044 => ';',
  65045 => '!',
  65046 => '?',
  65075 => '_',
  65076 => '_',
  65077 => '(',
  65078 => ')',
  65079 => '{',
  65080 => '}',
  65095 => '[',
  65096 => ']',
  65097 => ' ̅',
  65098 => ' ̅',
  65099 => ' ̅',
  65100 => ' ̅',
  65101 => '_',
  65102 => '_',
  65103 => '_',
  65104 => ',',
  65108 => ';',
  65109 => ':',
  65110 => '?',
  65111 => '!',
  65113 => '(',
  65114 => ')',
  65115 => '{',
  65116 => '}',
  65119 => '#',
  65120 => '&',
  65121 => '*',
  65122 => '+',
  65124 => '<',
  65125 => '>',
  65126 => '=',
  65128 => '\\',
  65129 => '$',
  65130 => '%',
  65131 => '@',
  65136 => ' ً',
  65138 => ' ٌ',
  65140 => ' ٍ',
  65142 => ' َ',
  65144 => ' ُ',
  65146 => ' ِ',
  65148 => ' ّ',
  65150 => ' ْ',
  65281 => '!',
  65282 => '"',
  65283 => '#',
  65284 => '$',
  65285 => '%',
  65286 => '&',
  65287 => '\'',
  65288 => '(',
  65289 => ')',
  65290 => '*',
  65291 => '+',
  65292 => ',',
  65295 => '/',
  65306 => ':',
  65307 => ';',
  65308 => '<',
  65309 => '=',
  65310 => '>',
  65311 => '?',
  65312 => '@',
  65339 => '[',
  65340 => '\\',
  65341 => ']',
  65342 => '^',
  65343 => '_',
  65344 => '`',
  65371 => '{',
  65372 => '|',
  65373 => '}',
  65374 => '~',
  65507 => ' ̄',
  127233 => '0,',
  127234 => '1,',
  127235 => '2,',
  127236 => '3,',
  127237 => '4,',
  127238 => '5,',
  127239 => '6,',
  127240 => '7,',
  127241 => '8,',
  127242 => '9,',
  127248 => '(a)',
  127249 => '(b)',
  127250 => '(c)',
  127251 => '(d)',
  127252 => '(e)',
  127253 => '(f)',
  127254 => '(g)',
  127255 => '(h)',
  127256 => '(i)',
  127257 => '(j)',
  127258 => '(k)',
  127259 => '(l)',
  127260 => '(m)',
  127261 => '(n)',
  127262 => '(o)',
  127263 => '(p)',
  127264 => '(q)',
  127265 => '(r)',
  127266 => '(s)',
  127267 => '(t)',
  127268 => '(u)',
  127269 => '(v)',
  127270 => '(w)',
  127271 => '(x)',
  127272 => '(y)',
  127273 => '(z)',
);
PKϤ$Z͎��K�K�.polyfill-intl-idn/Resources/unidata/mapped.phpnu�[���<?php

return array (
  65 => 'a',
  66 => 'b',
  67 => 'c',
  68 => 'd',
  69 => 'e',
  70 => 'f',
  71 => 'g',
  72 => 'h',
  73 => 'i',
  74 => 'j',
  75 => 'k',
  76 => 'l',
  77 => 'm',
  78 => 'n',
  79 => 'o',
  80 => 'p',
  81 => 'q',
  82 => 'r',
  83 => 's',
  84 => 't',
  85 => 'u',
  86 => 'v',
  87 => 'w',
  88 => 'x',
  89 => 'y',
  90 => 'z',
  170 => 'a',
  178 => '2',
  179 => '3',
  181 => 'μ',
  185 => '1',
  186 => 'o',
  188 => '1⁄4',
  189 => '1⁄2',
  190 => '3⁄4',
  192 => 'à',
  193 => 'á',
  194 => 'â',
  195 => 'ã',
  196 => 'ä',
  197 => 'å',
  198 => 'æ',
  199 => 'ç',
  200 => 'è',
  201 => 'é',
  202 => 'ê',
  203 => 'ë',
  204 => 'ì',
  205 => 'í',
  206 => 'î',
  207 => 'ï',
  208 => 'ð',
  209 => 'ñ',
  210 => 'ò',
  211 => 'ó',
  212 => 'ô',
  213 => 'õ',
  214 => 'ö',
  216 => 'ø',
  217 => 'ù',
  218 => 'ú',
  219 => 'û',
  220 => 'ü',
  221 => 'ý',
  222 => 'þ',
  256 => 'ā',
  258 => 'ă',
  260 => 'ą',
  262 => 'ć',
  264 => 'ĉ',
  266 => 'ċ',
  268 => 'č',
  270 => 'ď',
  272 => 'đ',
  274 => 'ē',
  276 => 'ĕ',
  278 => 'ė',
  280 => 'ę',
  282 => 'ě',
  284 => 'ĝ',
  286 => 'ğ',
  288 => 'ġ',
  290 => 'ģ',
  292 => 'ĥ',
  294 => 'ħ',
  296 => 'ĩ',
  298 => 'ī',
  300 => 'ĭ',
  302 => 'į',
  304 => 'i̇',
  306 => 'ij',
  307 => 'ij',
  308 => 'ĵ',
  310 => 'ķ',
  313 => 'ĺ',
  315 => 'ļ',
  317 => 'ľ',
  319 => 'l·',
  320 => 'l·',
  321 => 'ł',
  323 => 'ń',
  325 => 'ņ',
  327 => 'ň',
  329 => 'ʼn',
  330 => 'ŋ',
  332 => 'ō',
  334 => 'ŏ',
  336 => 'ő',
  338 => 'œ',
  340 => 'ŕ',
  342 => 'ŗ',
  344 => 'ř',
  346 => 'ś',
  348 => 'ŝ',
  350 => 'ş',
  352 => 'š',
  354 => 'ţ',
  356 => 'ť',
  358 => 'ŧ',
  360 => 'ũ',
  362 => 'ū',
  364 => 'ŭ',
  366 => 'ů',
  368 => 'ű',
  370 => 'ų',
  372 => 'ŵ',
  374 => 'ŷ',
  376 => 'ÿ',
  377 => 'ź',
  379 => 'ż',
  381 => 'ž',
  383 => 's',
  385 => 'ɓ',
  386 => 'ƃ',
  388 => 'ƅ',
  390 => 'ɔ',
  391 => 'ƈ',
  393 => 'ɖ',
  394 => 'ɗ',
  395 => 'ƌ',
  398 => 'ǝ',
  399 => 'ə',
  400 => 'ɛ',
  401 => 'ƒ',
  403 => 'ɠ',
  404 => 'ɣ',
  406 => 'ɩ',
  407 => 'ɨ',
  408 => 'ƙ',
  412 => 'ɯ',
  413 => 'ɲ',
  415 => 'ɵ',
  416 => 'ơ',
  418 => 'ƣ',
  420 => 'ƥ',
  422 => 'ʀ',
  423 => 'ƨ',
  425 => 'ʃ',
  428 => 'ƭ',
  430 => 'ʈ',
  431 => 'ư',
  433 => 'ʊ',
  434 => 'ʋ',
  435 => 'ƴ',
  437 => 'ƶ',
  439 => 'ʒ',
  440 => 'ƹ',
  444 => 'ƽ',
  452 => 'dž',
  453 => 'dž',
  454 => 'dž',
  455 => 'lj',
  456 => 'lj',
  457 => 'lj',
  458 => 'nj',
  459 => 'nj',
  460 => 'nj',
  461 => 'ǎ',
  463 => 'ǐ',
  465 => 'ǒ',
  467 => 'ǔ',
  469 => 'ǖ',
  471 => 'ǘ',
  473 => 'ǚ',
  475 => 'ǜ',
  478 => 'ǟ',
  480 => 'ǡ',
  482 => 'ǣ',
  484 => 'ǥ',
  486 => 'ǧ',
  488 => 'ǩ',
  490 => 'ǫ',
  492 => 'ǭ',
  494 => 'ǯ',
  497 => 'dz',
  498 => 'dz',
  499 => 'dz',
  500 => 'ǵ',
  502 => 'ƕ',
  503 => 'ƿ',
  504 => 'ǹ',
  506 => 'ǻ',
  508 => 'ǽ',
  510 => 'ǿ',
  512 => 'ȁ',
  514 => 'ȃ',
  516 => 'ȅ',
  518 => 'ȇ',
  520 => 'ȉ',
  522 => 'ȋ',
  524 => 'ȍ',
  526 => 'ȏ',
  528 => 'ȑ',
  530 => 'ȓ',
  532 => 'ȕ',
  534 => 'ȗ',
  536 => 'ș',
  538 => 'ț',
  540 => 'ȝ',
  542 => 'ȟ',
  544 => 'ƞ',
  546 => 'ȣ',
  548 => 'ȥ',
  550 => 'ȧ',
  552 => 'ȩ',
  554 => 'ȫ',
  556 => 'ȭ',
  558 => 'ȯ',
  560 => 'ȱ',
  562 => 'ȳ',
  570 => 'ⱥ',
  571 => 'ȼ',
  573 => 'ƚ',
  574 => 'ⱦ',
  577 => 'ɂ',
  579 => 'ƀ',
  580 => 'ʉ',
  581 => 'ʌ',
  582 => 'ɇ',
  584 => 'ɉ',
  586 => 'ɋ',
  588 => 'ɍ',
  590 => 'ɏ',
  688 => 'h',
  689 => 'ɦ',
  690 => 'j',
  691 => 'r',
  692 => 'ɹ',
  693 => 'ɻ',
  694 => 'ʁ',
  695 => 'w',
  696 => 'y',
  736 => 'ɣ',
  737 => 'l',
  738 => 's',
  739 => 'x',
  740 => 'ʕ',
  832 => '̀',
  833 => '́',
  835 => '̓',
  836 => '̈́',
  837 => 'ι',
  880 => 'ͱ',
  882 => 'ͳ',
  884 => 'ʹ',
  886 => 'ͷ',
  895 => 'ϳ',
  902 => 'ά',
  903 => '·',
  904 => 'έ',
  905 => 'ή',
  906 => 'ί',
  908 => 'ό',
  910 => 'ύ',
  911 => 'ώ',
  913 => 'α',
  914 => 'β',
  915 => 'γ',
  916 => 'δ',
  917 => 'ε',
  918 => 'ζ',
  919 => 'η',
  920 => 'θ',
  921 => 'ι',
  922 => 'κ',
  923 => 'λ',
  924 => 'μ',
  925 => 'ν',
  926 => 'ξ',
  927 => 'ο',
  928 => 'π',
  929 => 'ρ',
  931 => 'σ',
  932 => 'τ',
  933 => 'υ',
  934 => 'φ',
  935 => 'χ',
  936 => 'ψ',
  937 => 'ω',
  938 => 'ϊ',
  939 => 'ϋ',
  975 => 'ϗ',
  976 => 'β',
  977 => 'θ',
  978 => 'υ',
  979 => 'ύ',
  980 => 'ϋ',
  981 => 'φ',
  982 => 'π',
  984 => 'ϙ',
  986 => 'ϛ',
  988 => 'ϝ',
  990 => 'ϟ',
  992 => 'ϡ',
  994 => 'ϣ',
  996 => 'ϥ',
  998 => 'ϧ',
  1000 => 'ϩ',
  1002 => 'ϫ',
  1004 => 'ϭ',
  1006 => 'ϯ',
  1008 => 'κ',
  1009 => 'ρ',
  1010 => 'σ',
  1012 => 'θ',
  1013 => 'ε',
  1015 => 'ϸ',
  1017 => 'σ',
  1018 => 'ϻ',
  1021 => 'ͻ',
  1022 => 'ͼ',
  1023 => 'ͽ',
  1024 => 'ѐ',
  1025 => 'ё',
  1026 => 'ђ',
  1027 => 'ѓ',
  1028 => 'є',
  1029 => 'ѕ',
  1030 => 'і',
  1031 => 'ї',
  1032 => 'ј',
  1033 => 'љ',
  1034 => 'њ',
  1035 => 'ћ',
  1036 => 'ќ',
  1037 => 'ѝ',
  1038 => 'ў',
  1039 => 'џ',
  1040 => 'а',
  1041 => 'б',
  1042 => 'в',
  1043 => 'г',
  1044 => 'д',
  1045 => 'е',
  1046 => 'ж',
  1047 => 'з',
  1048 => 'и',
  1049 => 'й',
  1050 => 'к',
  1051 => 'л',
  1052 => 'м',
  1053 => 'н',
  1054 => 'о',
  1055 => 'п',
  1056 => 'р',
  1057 => 'с',
  1058 => 'т',
  1059 => 'у',
  1060 => 'ф',
  1061 => 'х',
  1062 => 'ц',
  1063 => 'ч',
  1064 => 'ш',
  1065 => 'щ',
  1066 => 'ъ',
  1067 => 'ы',
  1068 => 'ь',
  1069 => 'э',
  1070 => 'ю',
  1071 => 'я',
  1120 => 'ѡ',
  1122 => 'ѣ',
  1124 => 'ѥ',
  1126 => 'ѧ',
  1128 => 'ѩ',
  1130 => 'ѫ',
  1132 => 'ѭ',
  1134 => 'ѯ',
  1136 => 'ѱ',
  1138 => 'ѳ',
  1140 => 'ѵ',
  1142 => 'ѷ',
  1144 => 'ѹ',
  1146 => 'ѻ',
  1148 => 'ѽ',
  1150 => 'ѿ',
  1152 => 'ҁ',
  1162 => 'ҋ',
  1164 => 'ҍ',
  1166 => 'ҏ',
  1168 => 'ґ',
  1170 => 'ғ',
  1172 => 'ҕ',
  1174 => 'җ',
  1176 => 'ҙ',
  1178 => 'қ',
  1180 => 'ҝ',
  1182 => 'ҟ',
  1184 => 'ҡ',
  1186 => 'ң',
  1188 => 'ҥ',
  1190 => 'ҧ',
  1192 => 'ҩ',
  1194 => 'ҫ',
  1196 => 'ҭ',
  1198 => 'ү',
  1200 => 'ұ',
  1202 => 'ҳ',
  1204 => 'ҵ',
  1206 => 'ҷ',
  1208 => 'ҹ',
  1210 => 'һ',
  1212 => 'ҽ',
  1214 => 'ҿ',
  1217 => 'ӂ',
  1219 => 'ӄ',
  1221 => 'ӆ',
  1223 => 'ӈ',
  1225 => 'ӊ',
  1227 => 'ӌ',
  1229 => 'ӎ',
  1232 => 'ӑ',
  1234 => 'ӓ',
  1236 => 'ӕ',
  1238 => 'ӗ',
  1240 => 'ә',
  1242 => 'ӛ',
  1244 => 'ӝ',
  1246 => 'ӟ',
  1248 => 'ӡ',
  1250 => 'ӣ',
  1252 => 'ӥ',
  1254 => 'ӧ',
  1256 => 'ө',
  1258 => 'ӫ',
  1260 => 'ӭ',
  1262 => 'ӯ',
  1264 => 'ӱ',
  1266 => 'ӳ',
  1268 => 'ӵ',
  1270 => 'ӷ',
  1272 => 'ӹ',
  1274 => 'ӻ',
  1276 => 'ӽ',
  1278 => 'ӿ',
  1280 => 'ԁ',
  1282 => 'ԃ',
  1284 => 'ԅ',
  1286 => 'ԇ',
  1288 => 'ԉ',
  1290 => 'ԋ',
  1292 => 'ԍ',
  1294 => 'ԏ',
  1296 => 'ԑ',
  1298 => 'ԓ',
  1300 => 'ԕ',
  1302 => 'ԗ',
  1304 => 'ԙ',
  1306 => 'ԛ',
  1308 => 'ԝ',
  1310 => 'ԟ',
  1312 => 'ԡ',
  1314 => 'ԣ',
  1316 => 'ԥ',
  1318 => 'ԧ',
  1320 => 'ԩ',
  1322 => 'ԫ',
  1324 => 'ԭ',
  1326 => 'ԯ',
  1329 => 'ա',
  1330 => 'բ',
  1331 => 'գ',
  1332 => 'դ',
  1333 => 'ե',
  1334 => 'զ',
  1335 => 'է',
  1336 => 'ը',
  1337 => 'թ',
  1338 => 'ժ',
  1339 => 'ի',
  1340 => 'լ',
  1341 => 'խ',
  1342 => 'ծ',
  1343 => 'կ',
  1344 => 'հ',
  1345 => 'ձ',
  1346 => 'ղ',
  1347 => 'ճ',
  1348 => 'մ',
  1349 => 'յ',
  1350 => 'ն',
  1351 => 'շ',
  1352 => 'ո',
  1353 => 'չ',
  1354 => 'պ',
  1355 => 'ջ',
  1356 => 'ռ',
  1357 => 'ս',
  1358 => 'վ',
  1359 => 'տ',
  1360 => 'ր',
  1361 => 'ց',
  1362 => 'ւ',
  1363 => 'փ',
  1364 => 'ք',
  1365 => 'օ',
  1366 => 'ֆ',
  1415 => 'եւ',
  1653 => 'اٴ',
  1654 => 'وٴ',
  1655 => 'ۇٴ',
  1656 => 'يٴ',
  2392 => 'क़',
  2393 => 'ख़',
  2394 => 'ग़',
  2395 => 'ज़',
  2396 => 'ड़',
  2397 => 'ढ़',
  2398 => 'फ़',
  2399 => 'य़',
  2524 => 'ড়',
  2525 => 'ঢ়',
  2527 => 'য়',
  2611 => 'ਲ਼',
  2614 => 'ਸ਼',
  2649 => 'ਖ਼',
  2650 => 'ਗ਼',
  2651 => 'ਜ਼',
  2654 => 'ਫ਼',
  2908 => 'ଡ଼',
  2909 => 'ଢ଼',
  3635 => 'ํา',
  3763 => 'ໍາ',
  3804 => 'ຫນ',
  3805 => 'ຫມ',
  3852 => '་',
  3907 => 'གྷ',
  3917 => 'ཌྷ',
  3922 => 'དྷ',
  3927 => 'བྷ',
  3932 => 'ཛྷ',
  3945 => 'ཀྵ',
  3955 => 'ཱི',
  3957 => 'ཱུ',
  3958 => 'ྲྀ',
  3959 => 'ྲཱྀ',
  3960 => 'ླྀ',
  3961 => 'ླཱྀ',
  3969 => 'ཱྀ',
  3987 => 'ྒྷ',
  3997 => 'ྜྷ',
  4002 => 'ྡྷ',
  4007 => 'ྦྷ',
  4012 => 'ྫྷ',
  4025 => 'ྐྵ',
  4295 => 'ⴧ',
  4301 => 'ⴭ',
  4348 => 'ნ',
  5112 => 'Ᏸ',
  5113 => 'Ᏹ',
  5114 => 'Ᏺ',
  5115 => 'Ᏻ',
  5116 => 'Ᏼ',
  5117 => 'Ᏽ',
  7296 => 'в',
  7297 => 'д',
  7298 => 'о',
  7299 => 'с',
  7300 => 'т',
  7301 => 'т',
  7302 => 'ъ',
  7303 => 'ѣ',
  7304 => 'ꙋ',
  7312 => 'ა',
  7313 => 'ბ',
  7314 => 'გ',
  7315 => 'დ',
  7316 => 'ე',
  7317 => 'ვ',
  7318 => 'ზ',
  7319 => 'თ',
  7320 => 'ი',
  7321 => 'კ',
  7322 => 'ლ',
  7323 => 'მ',
  7324 => 'ნ',
  7325 => 'ო',
  7326 => 'პ',
  7327 => 'ჟ',
  7328 => 'რ',
  7329 => 'ს',
  7330 => 'ტ',
  7331 => 'უ',
  7332 => 'ფ',
  7333 => 'ქ',
  7334 => 'ღ',
  7335 => 'ყ',
  7336 => 'შ',
  7337 => 'ჩ',
  7338 => 'ც',
  7339 => 'ძ',
  7340 => 'წ',
  7341 => 'ჭ',
  7342 => 'ხ',
  7343 => 'ჯ',
  7344 => 'ჰ',
  7345 => 'ჱ',
  7346 => 'ჲ',
  7347 => 'ჳ',
  7348 => 'ჴ',
  7349 => 'ჵ',
  7350 => 'ჶ',
  7351 => 'ჷ',
  7352 => 'ჸ',
  7353 => 'ჹ',
  7354 => 'ჺ',
  7357 => 'ჽ',
  7358 => 'ჾ',
  7359 => 'ჿ',
  7468 => 'a',
  7469 => 'æ',
  7470 => 'b',
  7472 => 'd',
  7473 => 'e',
  7474 => 'ǝ',
  7475 => 'g',
  7476 => 'h',
  7477 => 'i',
  7478 => 'j',
  7479 => 'k',
  7480 => 'l',
  7481 => 'm',
  7482 => 'n',
  7484 => 'o',
  7485 => 'ȣ',
  7486 => 'p',
  7487 => 'r',
  7488 => 't',
  7489 => 'u',
  7490 => 'w',
  7491 => 'a',
  7492 => 'ɐ',
  7493 => 'ɑ',
  7494 => 'ᴂ',
  7495 => 'b',
  7496 => 'd',
  7497 => 'e',
  7498 => 'ə',
  7499 => 'ɛ',
  7500 => 'ɜ',
  7501 => 'g',
  7503 => 'k',
  7504 => 'm',
  7505 => 'ŋ',
  7506 => 'o',
  7507 => 'ɔ',
  7508 => 'ᴖ',
  7509 => 'ᴗ',
  7510 => 'p',
  7511 => 't',
  7512 => 'u',
  7513 => 'ᴝ',
  7514 => 'ɯ',
  7515 => 'v',
  7516 => 'ᴥ',
  7517 => 'β',
  7518 => 'γ',
  7519 => 'δ',
  7520 => 'φ',
  7521 => 'χ',
  7522 => 'i',
  7523 => 'r',
  7524 => 'u',
  7525 => 'v',
  7526 => 'β',
  7527 => 'γ',
  7528 => 'ρ',
  7529 => 'φ',
  7530 => 'χ',
  7544 => 'н',
  7579 => 'ɒ',
  7580 => 'c',
  7581 => 'ɕ',
  7582 => 'ð',
  7583 => 'ɜ',
  7584 => 'f',
  7585 => 'ɟ',
  7586 => 'ɡ',
  7587 => 'ɥ',
  7588 => 'ɨ',
  7589 => 'ɩ',
  7590 => 'ɪ',
  7591 => 'ᵻ',
  7592 => 'ʝ',
  7593 => 'ɭ',
  7594 => 'ᶅ',
  7595 => 'ʟ',
  7596 => 'ɱ',
  7597 => 'ɰ',
  7598 => 'ɲ',
  7599 => 'ɳ',
  7600 => 'ɴ',
  7601 => 'ɵ',
  7602 => 'ɸ',
  7603 => 'ʂ',
  7604 => 'ʃ',
  7605 => 'ƫ',
  7606 => 'ʉ',
  7607 => 'ʊ',
  7608 => 'ᴜ',
  7609 => 'ʋ',
  7610 => 'ʌ',
  7611 => 'z',
  7612 => 'ʐ',
  7613 => 'ʑ',
  7614 => 'ʒ',
  7615 => 'θ',
  7680 => 'ḁ',
  7682 => 'ḃ',
  7684 => 'ḅ',
  7686 => 'ḇ',
  7688 => 'ḉ',
  7690 => 'ḋ',
  7692 => 'ḍ',
  7694 => 'ḏ',
  7696 => 'ḑ',
  7698 => 'ḓ',
  7700 => 'ḕ',
  7702 => 'ḗ',
  7704 => 'ḙ',
  7706 => 'ḛ',
  7708 => 'ḝ',
  7710 => 'ḟ',
  7712 => 'ḡ',
  7714 => 'ḣ',
  7716 => 'ḥ',
  7718 => 'ḧ',
  7720 => 'ḩ',
  7722 => 'ḫ',
  7724 => 'ḭ',
  7726 => 'ḯ',
  7728 => 'ḱ',
  7730 => 'ḳ',
  7732 => 'ḵ',
  7734 => 'ḷ',
  7736 => 'ḹ',
  7738 => 'ḻ',
  7740 => 'ḽ',
  7742 => 'ḿ',
  7744 => 'ṁ',
  7746 => 'ṃ',
  7748 => 'ṅ',
  7750 => 'ṇ',
  7752 => 'ṉ',
  7754 => 'ṋ',
  7756 => 'ṍ',
  7758 => 'ṏ',
  7760 => 'ṑ',
  7762 => 'ṓ',
  7764 => 'ṕ',
  7766 => 'ṗ',
  7768 => 'ṙ',
  7770 => 'ṛ',
  7772 => 'ṝ',
  7774 => 'ṟ',
  7776 => 'ṡ',
  7778 => 'ṣ',
  7780 => 'ṥ',
  7782 => 'ṧ',
  7784 => 'ṩ',
  7786 => 'ṫ',
  7788 => 'ṭ',
  7790 => 'ṯ',
  7792 => 'ṱ',
  7794 => 'ṳ',
  7796 => 'ṵ',
  7798 => 'ṷ',
  7800 => 'ṹ',
  7802 => 'ṻ',
  7804 => 'ṽ',
  7806 => 'ṿ',
  7808 => 'ẁ',
  7810 => 'ẃ',
  7812 => 'ẅ',
  7814 => 'ẇ',
  7816 => 'ẉ',
  7818 => 'ẋ',
  7820 => 'ẍ',
  7822 => 'ẏ',
  7824 => 'ẑ',
  7826 => 'ẓ',
  7828 => 'ẕ',
  7834 => 'aʾ',
  7835 => 'ṡ',
  7838 => 'ss',
  7840 => 'ạ',
  7842 => 'ả',
  7844 => 'ấ',
  7846 => 'ầ',
  7848 => 'ẩ',
  7850 => 'ẫ',
  7852 => 'ậ',
  7854 => 'ắ',
  7856 => 'ằ',
  7858 => 'ẳ',
  7860 => 'ẵ',
  7862 => 'ặ',
  7864 => 'ẹ',
  7866 => 'ẻ',
  7868 => 'ẽ',
  7870 => 'ế',
  7872 => 'ề',
  7874 => 'ể',
  7876 => 'ễ',
  7878 => 'ệ',
  7880 => 'ỉ',
  7882 => 'ị',
  7884 => 'ọ',
  7886 => 'ỏ',
  7888 => 'ố',
  7890 => 'ồ',
  7892 => 'ổ',
  7894 => 'ỗ',
  7896 => 'ộ',
  7898 => 'ớ',
  7900 => 'ờ',
  7902 => 'ở',
  7904 => 'ỡ',
  7906 => 'ợ',
  7908 => 'ụ',
  7910 => 'ủ',
  7912 => 'ứ',
  7914 => 'ừ',
  7916 => 'ử',
  7918 => 'ữ',
  7920 => 'ự',
  7922 => 'ỳ',
  7924 => 'ỵ',
  7926 => 'ỷ',
  7928 => 'ỹ',
  7930 => 'ỻ',
  7932 => 'ỽ',
  7934 => 'ỿ',
  7944 => 'ἀ',
  7945 => 'ἁ',
  7946 => 'ἂ',
  7947 => 'ἃ',
  7948 => 'ἄ',
  7949 => 'ἅ',
  7950 => 'ἆ',
  7951 => 'ἇ',
  7960 => 'ἐ',
  7961 => 'ἑ',
  7962 => 'ἒ',
  7963 => 'ἓ',
  7964 => 'ἔ',
  7965 => 'ἕ',
  7976 => 'ἠ',
  7977 => 'ἡ',
  7978 => 'ἢ',
  7979 => 'ἣ',
  7980 => 'ἤ',
  7981 => 'ἥ',
  7982 => 'ἦ',
  7983 => 'ἧ',
  7992 => 'ἰ',
  7993 => 'ἱ',
  7994 => 'ἲ',
  7995 => 'ἳ',
  7996 => 'ἴ',
  7997 => 'ἵ',
  7998 => 'ἶ',
  7999 => 'ἷ',
  8008 => 'ὀ',
  8009 => 'ὁ',
  8010 => 'ὂ',
  8011 => 'ὃ',
  8012 => 'ὄ',
  8013 => 'ὅ',
  8025 => 'ὑ',
  8027 => 'ὓ',
  8029 => 'ὕ',
  8031 => 'ὗ',
  8040 => 'ὠ',
  8041 => 'ὡ',
  8042 => 'ὢ',
  8043 => 'ὣ',
  8044 => 'ὤ',
  8045 => 'ὥ',
  8046 => 'ὦ',
  8047 => 'ὧ',
  8049 => 'ά',
  8051 => 'έ',
  8053 => 'ή',
  8055 => 'ί',
  8057 => 'ό',
  8059 => 'ύ',
  8061 => 'ώ',
  8064 => 'ἀι',
  8065 => 'ἁι',
  8066 => 'ἂι',
  8067 => 'ἃι',
  8068 => 'ἄι',
  8069 => 'ἅι',
  8070 => 'ἆι',
  8071 => 'ἇι',
  8072 => 'ἀι',
  8073 => 'ἁι',
  8074 => 'ἂι',
  8075 => 'ἃι',
  8076 => 'ἄι',
  8077 => 'ἅι',
  8078 => 'ἆι',
  8079 => 'ἇι',
  8080 => 'ἠι',
  8081 => 'ἡι',
  8082 => 'ἢι',
  8083 => 'ἣι',
  8084 => 'ἤι',
  8085 => 'ἥι',
  8086 => 'ἦι',
  8087 => 'ἧι',
  8088 => 'ἠι',
  8089 => 'ἡι',
  8090 => 'ἢι',
  8091 => 'ἣι',
  8092 => 'ἤι',
  8093 => 'ἥι',
  8094 => 'ἦι',
  8095 => 'ἧι',
  8096 => 'ὠι',
  8097 => 'ὡι',
  8098 => 'ὢι',
  8099 => 'ὣι',
  8100 => 'ὤι',
  8101 => 'ὥι',
  8102 => 'ὦι',
  8103 => 'ὧι',
  8104 => 'ὠι',
  8105 => 'ὡι',
  8106 => 'ὢι',
  8107 => 'ὣι',
  8108 => 'ὤι',
  8109 => 'ὥι',
  8110 => 'ὦι',
  8111 => 'ὧι',
  8114 => 'ὰι',
  8115 => 'αι',
  8116 => 'άι',
  8119 => 'ᾶι',
  8120 => 'ᾰ',
  8121 => 'ᾱ',
  8122 => 'ὰ',
  8123 => 'ά',
  8124 => 'αι',
  8126 => 'ι',
  8130 => 'ὴι',
  8131 => 'ηι',
  8132 => 'ήι',
  8135 => 'ῆι',
  8136 => 'ὲ',
  8137 => 'έ',
  8138 => 'ὴ',
  8139 => 'ή',
  8140 => 'ηι',
  8147 => 'ΐ',
  8152 => 'ῐ',
  8153 => 'ῑ',
  8154 => 'ὶ',
  8155 => 'ί',
  8163 => 'ΰ',
  8168 => 'ῠ',
  8169 => 'ῡ',
  8170 => 'ὺ',
  8171 => 'ύ',
  8172 => 'ῥ',
  8178 => 'ὼι',
  8179 => 'ωι',
  8180 => 'ώι',
  8183 => 'ῶι',
  8184 => 'ὸ',
  8185 => 'ό',
  8186 => 'ὼ',
  8187 => 'ώ',
  8188 => 'ωι',
  8209 => '‐',
  8243 => '′′',
  8244 => '′′′',
  8246 => '‵‵',
  8247 => '‵‵‵',
  8279 => '′′′′',
  8304 => '0',
  8305 => 'i',
  8308 => '4',
  8309 => '5',
  8310 => '6',
  8311 => '7',
  8312 => '8',
  8313 => '9',
  8315 => '−',
  8319 => 'n',
  8320 => '0',
  8321 => '1',
  8322 => '2',
  8323 => '3',
  8324 => '4',
  8325 => '5',
  8326 => '6',
  8327 => '7',
  8328 => '8',
  8329 => '9',
  8331 => '−',
  8336 => 'a',
  8337 => 'e',
  8338 => 'o',
  8339 => 'x',
  8340 => 'ə',
  8341 => 'h',
  8342 => 'k',
  8343 => 'l',
  8344 => 'm',
  8345 => 'n',
  8346 => 'p',
  8347 => 's',
  8348 => 't',
  8360 => 'rs',
  8450 => 'c',
  8451 => '°c',
  8455 => 'ɛ',
  8457 => '°f',
  8458 => 'g',
  8459 => 'h',
  8460 => 'h',
  8461 => 'h',
  8462 => 'h',
  8463 => 'ħ',
  8464 => 'i',
  8465 => 'i',
  8466 => 'l',
  8467 => 'l',
  8469 => 'n',
  8470 => 'no',
  8473 => 'p',
  8474 => 'q',
  8475 => 'r',
  8476 => 'r',
  8477 => 'r',
  8480 => 'sm',
  8481 => 'tel',
  8482 => 'tm',
  8484 => 'z',
  8486 => 'ω',
  8488 => 'z',
  8490 => 'k',
  8491 => 'å',
  8492 => 'b',
  8493 => 'c',
  8495 => 'e',
  8496 => 'e',
  8497 => 'f',
  8499 => 'm',
  8500 => 'o',
  8501 => 'א',
  8502 => 'ב',
  8503 => 'ג',
  8504 => 'ד',
  8505 => 'i',
  8507 => 'fax',
  8508 => 'π',
  8509 => 'γ',
  8510 => 'γ',
  8511 => 'π',
  8512 => '∑',
  8517 => 'd',
  8518 => 'd',
  8519 => 'e',
  8520 => 'i',
  8521 => 'j',
  8528 => '1⁄7',
  8529 => '1⁄9',
  8530 => '1⁄10',
  8531 => '1⁄3',
  8532 => '2⁄3',
  8533 => '1⁄5',
  8534 => '2⁄5',
  8535 => '3⁄5',
  8536 => '4⁄5',
  8537 => '1⁄6',
  8538 => '5⁄6',
  8539 => '1⁄8',
  8540 => '3⁄8',
  8541 => '5⁄8',
  8542 => '7⁄8',
  8543 => '1⁄',
  8544 => 'i',
  8545 => 'ii',
  8546 => 'iii',
  8547 => 'iv',
  8548 => 'v',
  8549 => 'vi',
  8550 => 'vii',
  8551 => 'viii',
  8552 => 'ix',
  8553 => 'x',
  8554 => 'xi',
  8555 => 'xii',
  8556 => 'l',
  8557 => 'c',
  8558 => 'd',
  8559 => 'm',
  8560 => 'i',
  8561 => 'ii',
  8562 => 'iii',
  8563 => 'iv',
  8564 => 'v',
  8565 => 'vi',
  8566 => 'vii',
  8567 => 'viii',
  8568 => 'ix',
  8569 => 'x',
  8570 => 'xi',
  8571 => 'xii',
  8572 => 'l',
  8573 => 'c',
  8574 => 'd',
  8575 => 'm',
  8585 => '0⁄3',
  8748 => '∫∫',
  8749 => '∫∫∫',
  8751 => '∮∮',
  8752 => '∮∮∮',
  9001 => '〈',
  9002 => '〉',
  9312 => '1',
  9313 => '2',
  9314 => '3',
  9315 => '4',
  9316 => '5',
  9317 => '6',
  9318 => '7',
  9319 => '8',
  9320 => '9',
  9321 => '10',
  9322 => '11',
  9323 => '12',
  9324 => '13',
  9325 => '14',
  9326 => '15',
  9327 => '16',
  9328 => '17',
  9329 => '18',
  9330 => '19',
  9331 => '20',
  9398 => 'a',
  9399 => 'b',
  9400 => 'c',
  9401 => 'd',
  9402 => 'e',
  9403 => 'f',
  9404 => 'g',
  9405 => 'h',
  9406 => 'i',
  9407 => 'j',
  9408 => 'k',
  9409 => 'l',
  9410 => 'm',
  9411 => 'n',
  9412 => 'o',
  9413 => 'p',
  9414 => 'q',
  9415 => 'r',
  9416 => 's',
  9417 => 't',
  9418 => 'u',
  9419 => 'v',
  9420 => 'w',
  9421 => 'x',
  9422 => 'y',
  9423 => 'z',
  9424 => 'a',
  9425 => 'b',
  9426 => 'c',
  9427 => 'd',
  9428 => 'e',
  9429 => 'f',
  9430 => 'g',
  9431 => 'h',
  9432 => 'i',
  9433 => 'j',
  9434 => 'k',
  9435 => 'l',
  9436 => 'm',
  9437 => 'n',
  9438 => 'o',
  9439 => 'p',
  9440 => 'q',
  9441 => 'r',
  9442 => 's',
  9443 => 't',
  9444 => 'u',
  9445 => 'v',
  9446 => 'w',
  9447 => 'x',
  9448 => 'y',
  9449 => 'z',
  9450 => '0',
  10764 => '∫∫∫∫',
  10972 => '⫝̸',
  11264 => 'ⰰ',
  11265 => 'ⰱ',
  11266 => 'ⰲ',
  11267 => 'ⰳ',
  11268 => 'ⰴ',
  11269 => 'ⰵ',
  11270 => 'ⰶ',
  11271 => 'ⰷ',
  11272 => 'ⰸ',
  11273 => 'ⰹ',
  11274 => 'ⰺ',
  11275 => 'ⰻ',
  11276 => 'ⰼ',
  11277 => 'ⰽ',
  11278 => 'ⰾ',
  11279 => 'ⰿ',
  11280 => 'ⱀ',
  11281 => 'ⱁ',
  11282 => 'ⱂ',
  11283 => 'ⱃ',
  11284 => 'ⱄ',
  11285 => 'ⱅ',
  11286 => 'ⱆ',
  11287 => 'ⱇ',
  11288 => 'ⱈ',
  11289 => 'ⱉ',
  11290 => 'ⱊ',
  11291 => 'ⱋ',
  11292 => 'ⱌ',
  11293 => 'ⱍ',
  11294 => 'ⱎ',
  11295 => 'ⱏ',
  11296 => 'ⱐ',
  11297 => 'ⱑ',
  11298 => 'ⱒ',
  11299 => 'ⱓ',
  11300 => 'ⱔ',
  11301 => 'ⱕ',
  11302 => 'ⱖ',
  11303 => 'ⱗ',
  11304 => 'ⱘ',
  11305 => 'ⱙ',
  11306 => 'ⱚ',
  11307 => 'ⱛ',
  11308 => 'ⱜ',
  11309 => 'ⱝ',
  11310 => 'ⱞ',
  11360 => 'ⱡ',
  11362 => 'ɫ',
  11363 => 'ᵽ',
  11364 => 'ɽ',
  11367 => 'ⱨ',
  11369 => 'ⱪ',
  11371 => 'ⱬ',
  11373 => 'ɑ',
  11374 => 'ɱ',
  11375 => 'ɐ',
  11376 => 'ɒ',
  11378 => 'ⱳ',
  11381 => 'ⱶ',
  11388 => 'j',
  11389 => 'v',
  11390 => 'ȿ',
  11391 => 'ɀ',
  11392 => 'ⲁ',
  11394 => 'ⲃ',
  11396 => 'ⲅ',
  11398 => 'ⲇ',
  11400 => 'ⲉ',
  11402 => 'ⲋ',
  11404 => 'ⲍ',
  11406 => 'ⲏ',
  11408 => 'ⲑ',
  11410 => 'ⲓ',
  11412 => 'ⲕ',
  11414 => 'ⲗ',
  11416 => 'ⲙ',
  11418 => 'ⲛ',
  11420 => 'ⲝ',
  11422 => 'ⲟ',
  11424 => 'ⲡ',
  11426 => 'ⲣ',
  11428 => 'ⲥ',
  11430 => 'ⲧ',
  11432 => 'ⲩ',
  11434 => 'ⲫ',
  11436 => 'ⲭ',
  11438 => 'ⲯ',
  11440 => 'ⲱ',
  11442 => 'ⲳ',
  11444 => 'ⲵ',
  11446 => 'ⲷ',
  11448 => 'ⲹ',
  11450 => 'ⲻ',
  11452 => 'ⲽ',
  11454 => 'ⲿ',
  11456 => 'ⳁ',
  11458 => 'ⳃ',
  11460 => 'ⳅ',
  11462 => 'ⳇ',
  11464 => 'ⳉ',
  11466 => 'ⳋ',
  11468 => 'ⳍ',
  11470 => 'ⳏ',
  11472 => 'ⳑ',
  11474 => 'ⳓ',
  11476 => 'ⳕ',
  11478 => 'ⳗ',
  11480 => 'ⳙ',
  11482 => 'ⳛ',
  11484 => 'ⳝ',
  11486 => 'ⳟ',
  11488 => 'ⳡ',
  11490 => 'ⳣ',
  11499 => 'ⳬ',
  11501 => 'ⳮ',
  11506 => 'ⳳ',
  11631 => 'ⵡ',
  11935 => '母',
  12019 => '龟',
  12032 => '一',
  12033 => '丨',
  12034 => '丶',
  12035 => '丿',
  12036 => '乙',
  12037 => '亅',
  12038 => '二',
  12039 => '亠',
  12040 => '人',
  12041 => '儿',
  12042 => '入',
  12043 => '八',
  12044 => '冂',
  12045 => '冖',
  12046 => '冫',
  12047 => '几',
  12048 => '凵',
  12049 => '刀',
  12050 => '力',
  12051 => '勹',
  12052 => '匕',
  12053 => '匚',
  12054 => '匸',
  12055 => '十',
  12056 => '卜',
  12057 => '卩',
  12058 => '厂',
  12059 => '厶',
  12060 => '又',
  12061 => '口',
  12062 => '囗',
  12063 => '土',
  12064 => '士',
  12065 => '夂',
  12066 => '夊',
  12067 => '夕',
  12068 => '大',
  12069 => '女',
  12070 => '子',
  12071 => '宀',
  12072 => '寸',
  12073 => '小',
  12074 => '尢',
  12075 => '尸',
  12076 => '屮',
  12077 => '山',
  12078 => '巛',
  12079 => '工',
  12080 => '己',
  12081 => '巾',
  12082 => '干',
  12083 => '幺',
  12084 => '广',
  12085 => '廴',
  12086 => '廾',
  12087 => '弋',
  12088 => '弓',
  12089 => '彐',
  12090 => '彡',
  12091 => '彳',
  12092 => '心',
  12093 => '戈',
  12094 => '戶',
  12095 => '手',
  12096 => '支',
  12097 => '攴',
  12098 => '文',
  12099 => '斗',
  12100 => '斤',
  12101 => '方',
  12102 => '无',
  12103 => '日',
  12104 => '曰',
  12105 => '月',
  12106 => '木',
  12107 => '欠',
  12108 => '止',
  12109 => '歹',
  12110 => '殳',
  12111 => '毋',
  12112 => '比',
  12113 => '毛',
  12114 => '氏',
  12115 => '气',
  12116 => '水',
  12117 => '火',
  12118 => '爪',
  12119 => '父',
  12120 => '爻',
  12121 => '爿',
  12122 => '片',
  12123 => '牙',
  12124 => '牛',
  12125 => '犬',
  12126 => '玄',
  12127 => '玉',
  12128 => '瓜',
  12129 => '瓦',
  12130 => '甘',
  12131 => '生',
  12132 => '用',
  12133 => '田',
  12134 => '疋',
  12135 => '疒',
  12136 => '癶',
  12137 => '白',
  12138 => '皮',
  12139 => '皿',
  12140 => '目',
  12141 => '矛',
  12142 => '矢',
  12143 => '石',
  12144 => '示',
  12145 => '禸',
  12146 => '禾',
  12147 => '穴',
  12148 => '立',
  12149 => '竹',
  12150 => '米',
  12151 => '糸',
  12152 => '缶',
  12153 => '网',
  12154 => '羊',
  12155 => '羽',
  12156 => '老',
  12157 => '而',
  12158 => '耒',
  12159 => '耳',
  12160 => '聿',
  12161 => '肉',
  12162 => '臣',
  12163 => '自',
  12164 => '至',
  12165 => '臼',
  12166 => '舌',
  12167 => '舛',
  12168 => '舟',
  12169 => '艮',
  12170 => '色',
  12171 => '艸',
  12172 => '虍',
  12173 => '虫',
  12174 => '血',
  12175 => '行',
  12176 => '衣',
  12177 => '襾',
  12178 => '見',
  12179 => '角',
  12180 => '言',
  12181 => '谷',
  12182 => '豆',
  12183 => '豕',
  12184 => '豸',
  12185 => '貝',
  12186 => '赤',
  12187 => '走',
  12188 => '足',
  12189 => '身',
  12190 => '車',
  12191 => '辛',
  12192 => '辰',
  12193 => '辵',
  12194 => '邑',
  12195 => '酉',
  12196 => '釆',
  12197 => '里',
  12198 => '金',
  12199 => '長',
  12200 => '門',
  12201 => '阜',
  12202 => '隶',
  12203 => '隹',
  12204 => '雨',
  12205 => '靑',
  12206 => '非',
  12207 => '面',
  12208 => '革',
  12209 => '韋',
  12210 => '韭',
  12211 => '音',
  12212 => '頁',
  12213 => '風',
  12214 => '飛',
  12215 => '食',
  12216 => '首',
  12217 => '香',
  12218 => '馬',
  12219 => '骨',
  12220 => '高',
  12221 => '髟',
  12222 => '鬥',
  12223 => '鬯',
  12224 => '鬲',
  12225 => '鬼',
  12226 => '魚',
  12227 => '鳥',
  12228 => '鹵',
  12229 => '鹿',
  12230 => '麥',
  12231 => '麻',
  12232 => '黃',
  12233 => '黍',
  12234 => '黑',
  12235 => '黹',
  12236 => '黽',
  12237 => '鼎',
  12238 => '鼓',
  12239 => '鼠',
  12240 => '鼻',
  12241 => '齊',
  12242 => '齒',
  12243 => '龍',
  12244 => '龜',
  12245 => '龠',
  12290 => '.',
  12342 => '〒',
  12344 => '十',
  12345 => '卄',
  12346 => '卅',
  12447 => 'より',
  12543 => 'コト',
  12593 => 'ᄀ',
  12594 => 'ᄁ',
  12595 => 'ᆪ',
  12596 => 'ᄂ',
  12597 => 'ᆬ',
  12598 => 'ᆭ',
  12599 => 'ᄃ',
  12600 => 'ᄄ',
  12601 => 'ᄅ',
  12602 => 'ᆰ',
  12603 => 'ᆱ',
  12604 => 'ᆲ',
  12605 => 'ᆳ',
  12606 => 'ᆴ',
  12607 => 'ᆵ',
  12608 => 'ᄚ',
  12609 => 'ᄆ',
  12610 => 'ᄇ',
  12611 => 'ᄈ',
  12612 => 'ᄡ',
  12613 => 'ᄉ',
  12614 => 'ᄊ',
  12615 => 'ᄋ',
  12616 => 'ᄌ',
  12617 => 'ᄍ',
  12618 => 'ᄎ',
  12619 => 'ᄏ',
  12620 => 'ᄐ',
  12621 => 'ᄑ',
  12622 => 'ᄒ',
  12623 => 'ᅡ',
  12624 => 'ᅢ',
  12625 => 'ᅣ',
  12626 => 'ᅤ',
  12627 => 'ᅥ',
  12628 => 'ᅦ',
  12629 => 'ᅧ',
  12630 => 'ᅨ',
  12631 => 'ᅩ',
  12632 => 'ᅪ',
  12633 => 'ᅫ',
  12634 => 'ᅬ',
  12635 => 'ᅭ',
  12636 => 'ᅮ',
  12637 => 'ᅯ',
  12638 => 'ᅰ',
  12639 => 'ᅱ',
  12640 => 'ᅲ',
  12641 => 'ᅳ',
  12642 => 'ᅴ',
  12643 => 'ᅵ',
  12645 => 'ᄔ',
  12646 => 'ᄕ',
  12647 => 'ᇇ',
  12648 => 'ᇈ',
  12649 => 'ᇌ',
  12650 => 'ᇎ',
  12651 => 'ᇓ',
  12652 => 'ᇗ',
  12653 => 'ᇙ',
  12654 => 'ᄜ',
  12655 => 'ᇝ',
  12656 => 'ᇟ',
  12657 => 'ᄝ',
  12658 => 'ᄞ',
  12659 => 'ᄠ',
  12660 => 'ᄢ',
  12661 => 'ᄣ',
  12662 => 'ᄧ',
  12663 => 'ᄩ',
  12664 => 'ᄫ',
  12665 => 'ᄬ',
  12666 => 'ᄭ',
  12667 => 'ᄮ',
  12668 => 'ᄯ',
  12669 => 'ᄲ',
  12670 => 'ᄶ',
  12671 => 'ᅀ',
  12672 => 'ᅇ',
  12673 => 'ᅌ',
  12674 => 'ᇱ',
  12675 => 'ᇲ',
  12676 => 'ᅗ',
  12677 => 'ᅘ',
  12678 => 'ᅙ',
  12679 => 'ᆄ',
  12680 => 'ᆅ',
  12681 => 'ᆈ',
  12682 => 'ᆑ',
  12683 => 'ᆒ',
  12684 => 'ᆔ',
  12685 => 'ᆞ',
  12686 => 'ᆡ',
  12690 => '一',
  12691 => '二',
  12692 => '三',
  12693 => '四',
  12694 => '上',
  12695 => '中',
  12696 => '下',
  12697 => '甲',
  12698 => '乙',
  12699 => '丙',
  12700 => '丁',
  12701 => '天',
  12702 => '地',
  12703 => '人',
  12868 => '問',
  12869 => '幼',
  12870 => '文',
  12871 => '箏',
  12880 => 'pte',
  12881 => '21',
  12882 => '22',
  12883 => '23',
  12884 => '24',
  12885 => '25',
  12886 => '26',
  12887 => '27',
  12888 => '28',
  12889 => '29',
  12890 => '30',
  12891 => '31',
  12892 => '32',
  12893 => '33',
  12894 => '34',
  12895 => '35',
  12896 => 'ᄀ',
  12897 => 'ᄂ',
  12898 => 'ᄃ',
  12899 => 'ᄅ',
  12900 => 'ᄆ',
  12901 => 'ᄇ',
  12902 => 'ᄉ',
  12903 => 'ᄋ',
  12904 => 'ᄌ',
  12905 => 'ᄎ',
  12906 => 'ᄏ',
  12907 => 'ᄐ',
  12908 => 'ᄑ',
  12909 => 'ᄒ',
  12910 => '가',
  12911 => '나',
  12912 => '다',
  12913 => '라',
  12914 => '마',
  12915 => '바',
  12916 => '사',
  12917 => '아',
  12918 => '자',
  12919 => '차',
  12920 => '카',
  12921 => '타',
  12922 => '파',
  12923 => '하',
  12924 => '참고',
  12925 => '주의',
  12926 => '우',
  12928 => '一',
  12929 => '二',
  12930 => '三',
  12931 => '四',
  12932 => '五',
  12933 => '六',
  12934 => '七',
  12935 => '八',
  12936 => '九',
  12937 => '十',
  12938 => '月',
  12939 => '火',
  12940 => '水',
  12941 => '木',
  12942 => '金',
  12943 => '土',
  12944 => '日',
  12945 => '株',
  12946 => '有',
  12947 => '社',
  12948 => '名',
  12949 => '特',
  12950 => '財',
  12951 => '祝',
  12952 => '労',
  12953 => '秘',
  12954 => '男',
  12955 => '女',
  12956 => '適',
  12957 => '優',
  12958 => '印',
  12959 => '注',
  12960 => '項',
  12961 => '休',
  12962 => '写',
  12963 => '正',
  12964 => '上',
  12965 => '中',
  12966 => '下',
  12967 => '左',
  12968 => '右',
  12969 => '医',
  12970 => '宗',
  12971 => '学',
  12972 => '監',
  12973 => '企',
  12974 => '資',
  12975 => '協',
  12976 => '夜',
  12977 => '36',
  12978 => '37',
  12979 => '38',
  12980 => '39',
  12981 => '40',
  12982 => '41',
  12983 => '42',
  12984 => '43',
  12985 => '44',
  12986 => '45',
  12987 => '46',
  12988 => '47',
  12989 => '48',
  12990 => '49',
  12991 => '50',
  12992 => '1月',
  12993 => '2月',
  12994 => '3月',
  12995 => '4月',
  12996 => '5月',
  12997 => '6月',
  12998 => '7月',
  12999 => '8月',
  13000 => '9月',
  13001 => '10月',
  13002 => '11月',
  13003 => '12月',
  13004 => 'hg',
  13005 => 'erg',
  13006 => 'ev',
  13007 => 'ltd',
  13008 => 'ア',
  13009 => 'イ',
  13010 => 'ウ',
  13011 => 'エ',
  13012 => 'オ',
  13013 => 'カ',
  13014 => 'キ',
  13015 => 'ク',
  13016 => 'ケ',
  13017 => 'コ',
  13018 => 'サ',
  13019 => 'シ',
  13020 => 'ス',
  13021 => 'セ',
  13022 => 'ソ',
  13023 => 'タ',
  13024 => 'チ',
  13025 => 'ツ',
  13026 => 'テ',
  13027 => 'ト',
  13028 => 'ナ',
  13029 => 'ニ',
  13030 => 'ヌ',
  13031 => 'ネ',
  13032 => 'ノ',
  13033 => 'ハ',
  13034 => 'ヒ',
  13035 => 'フ',
  13036 => 'ヘ',
  13037 => 'ホ',
  13038 => 'マ',
  13039 => 'ミ',
  13040 => 'ム',
  13041 => 'メ',
  13042 => 'モ',
  13043 => 'ヤ',
  13044 => 'ユ',
  13045 => 'ヨ',
  13046 => 'ラ',
  13047 => 'リ',
  13048 => 'ル',
  13049 => 'レ',
  13050 => 'ロ',
  13051 => 'ワ',
  13052 => 'ヰ',
  13053 => 'ヱ',
  13054 => 'ヲ',
  13055 => '令和',
  13056 => 'アパート',
  13057 => 'アルファ',
  13058 => 'アンペア',
  13059 => 'アール',
  13060 => 'イニング',
  13061 => 'インチ',
  13062 => 'ウォン',
  13063 => 'エスクード',
  13064 => 'エーカー',
  13065 => 'オンス',
  13066 => 'オーム',
  13067 => 'カイリ',
  13068 => 'カラット',
  13069 => 'カロリー',
  13070 => 'ガロン',
  13071 => 'ガンマ',
  13072 => 'ギガ',
  13073 => 'ギニー',
  13074 => 'キュリー',
  13075 => 'ギルダー',
  13076 => 'キロ',
  13077 => 'キログラム',
  13078 => 'キロメートル',
  13079 => 'キロワット',
  13080 => 'グラム',
  13081 => 'グラムトン',
  13082 => 'クルゼイロ',
  13083 => 'クローネ',
  13084 => 'ケース',
  13085 => 'コルナ',
  13086 => 'コーポ',
  13087 => 'サイクル',
  13088 => 'サンチーム',
  13089 => 'シリング',
  13090 => 'センチ',
  13091 => 'セント',
  13092 => 'ダース',
  13093 => 'デシ',
  13094 => 'ドル',
  13095 => 'トン',
  13096 => 'ナノ',
  13097 => 'ノット',
  13098 => 'ハイツ',
  13099 => 'パーセント',
  13100 => 'パーツ',
  13101 => 'バーレル',
  13102 => 'ピアストル',
  13103 => 'ピクル',
  13104 => 'ピコ',
  13105 => 'ビル',
  13106 => 'ファラッド',
  13107 => 'フィート',
  13108 => 'ブッシェル',
  13109 => 'フラン',
  13110 => 'ヘクタール',
  13111 => 'ペソ',
  13112 => 'ペニヒ',
  13113 => 'ヘルツ',
  13114 => 'ペンス',
  13115 => 'ページ',
  13116 => 'ベータ',
  13117 => 'ポイント',
  13118 => 'ボルト',
  13119 => 'ホン',
  13120 => 'ポンド',
  13121 => 'ホール',
  13122 => 'ホーン',
  13123 => 'マイクロ',
  13124 => 'マイル',
  13125 => 'マッハ',
  13126 => 'マルク',
  13127 => 'マンション',
  13128 => 'ミクロン',
  13129 => 'ミリ',
  13130 => 'ミリバール',
  13131 => 'メガ',
  13132 => 'メガトン',
  13133 => 'メートル',
  13134 => 'ヤード',
  13135 => 'ヤール',
  13136 => 'ユアン',
  13137 => 'リットル',
  13138 => 'リラ',
  13139 => 'ルピー',
  13140 => 'ルーブル',
  13141 => 'レム',
  13142 => 'レントゲン',
  13143 => 'ワット',
  13144 => '0点',
  13145 => '1点',
  13146 => '2点',
  13147 => '3点',
  13148 => '4点',
  13149 => '5点',
  13150 => '6点',
  13151 => '7点',
  13152 => '8点',
  13153 => '9点',
  13154 => '10点',
  13155 => '11点',
  13156 => '12点',
  13157 => '13点',
  13158 => '14点',
  13159 => '15点',
  13160 => '16点',
  13161 => '17点',
  13162 => '18点',
  13163 => '19点',
  13164 => '20点',
  13165 => '21点',
  13166 => '22点',
  13167 => '23点',
  13168 => '24点',
  13169 => 'hpa',
  13170 => 'da',
  13171 => 'au',
  13172 => 'bar',
  13173 => 'ov',
  13174 => 'pc',
  13175 => 'dm',
  13176 => 'dm2',
  13177 => 'dm3',
  13178 => 'iu',
  13179 => '平成',
  13180 => '昭和',
  13181 => '大正',
  13182 => '明治',
  13183 => '株式会社',
  13184 => 'pa',
  13185 => 'na',
  13186 => 'μa',
  13187 => 'ma',
  13188 => 'ka',
  13189 => 'kb',
  13190 => 'mb',
  13191 => 'gb',
  13192 => 'cal',
  13193 => 'kcal',
  13194 => 'pf',
  13195 => 'nf',
  13196 => 'μf',
  13197 => 'μg',
  13198 => 'mg',
  13199 => 'kg',
  13200 => 'hz',
  13201 => 'khz',
  13202 => 'mhz',
  13203 => 'ghz',
  13204 => 'thz',
  13205 => 'μl',
  13206 => 'ml',
  13207 => 'dl',
  13208 => 'kl',
  13209 => 'fm',
  13210 => 'nm',
  13211 => 'μm',
  13212 => 'mm',
  13213 => 'cm',
  13214 => 'km',
  13215 => 'mm2',
  13216 => 'cm2',
  13217 => 'm2',
  13218 => 'km2',
  13219 => 'mm3',
  13220 => 'cm3',
  13221 => 'm3',
  13222 => 'km3',
  13223 => 'm∕s',
  13224 => 'm∕s2',
  13225 => 'pa',
  13226 => 'kpa',
  13227 => 'mpa',
  13228 => 'gpa',
  13229 => 'rad',
  13230 => 'rad∕s',
  13231 => 'rad∕s2',
  13232 => 'ps',
  13233 => 'ns',
  13234 => 'μs',
  13235 => 'ms',
  13236 => 'pv',
  13237 => 'nv',
  13238 => 'μv',
  13239 => 'mv',
  13240 => 'kv',
  13241 => 'mv',
  13242 => 'pw',
  13243 => 'nw',
  13244 => 'μw',
  13245 => 'mw',
  13246 => 'kw',
  13247 => 'mw',
  13248 => 'kω',
  13249 => 'mω',
  13251 => 'bq',
  13252 => 'cc',
  13253 => 'cd',
  13254 => 'c∕kg',
  13256 => 'db',
  13257 => 'gy',
  13258 => 'ha',
  13259 => 'hp',
  13260 => 'in',
  13261 => 'kk',
  13262 => 'km',
  13263 => 'kt',
  13264 => 'lm',
  13265 => 'ln',
  13266 => 'log',
  13267 => 'lx',
  13268 => 'mb',
  13269 => 'mil',
  13270 => 'mol',
  13271 => 'ph',
  13273 => 'ppm',
  13274 => 'pr',
  13275 => 'sr',
  13276 => 'sv',
  13277 => 'wb',
  13278 => 'v∕m',
  13279 => 'a∕m',
  13280 => '1日',
  13281 => '2日',
  13282 => '3日',
  13283 => '4日',
  13284 => '5日',
  13285 => '6日',
  13286 => '7日',
  13287 => '8日',
  13288 => '9日',
  13289 => '10日',
  13290 => '11日',
  13291 => '12日',
  13292 => '13日',
  13293 => '14日',
  13294 => '15日',
  13295 => '16日',
  13296 => '17日',
  13297 => '18日',
  13298 => '19日',
  13299 => '20日',
  13300 => '21日',
  13301 => '22日',
  13302 => '23日',
  13303 => '24日',
  13304 => '25日',
  13305 => '26日',
  13306 => '27日',
  13307 => '28日',
  13308 => '29日',
  13309 => '30日',
  13310 => '31日',
  13311 => 'gal',
  42560 => 'ꙁ',
  42562 => 'ꙃ',
  42564 => 'ꙅ',
  42566 => 'ꙇ',
  42568 => 'ꙉ',
  42570 => 'ꙋ',
  42572 => 'ꙍ',
  42574 => 'ꙏ',
  42576 => 'ꙑ',
  42578 => 'ꙓ',
  42580 => 'ꙕ',
  42582 => 'ꙗ',
  42584 => 'ꙙ',
  42586 => 'ꙛ',
  42588 => 'ꙝ',
  42590 => 'ꙟ',
  42592 => 'ꙡ',
  42594 => 'ꙣ',
  42596 => 'ꙥ',
  42598 => 'ꙧ',
  42600 => 'ꙩ',
  42602 => 'ꙫ',
  42604 => 'ꙭ',
  42624 => 'ꚁ',
  42626 => 'ꚃ',
  42628 => 'ꚅ',
  42630 => 'ꚇ',
  42632 => 'ꚉ',
  42634 => 'ꚋ',
  42636 => 'ꚍ',
  42638 => 'ꚏ',
  42640 => 'ꚑ',
  42642 => 'ꚓ',
  42644 => 'ꚕ',
  42646 => 'ꚗ',
  42648 => 'ꚙ',
  42650 => 'ꚛ',
  42652 => 'ъ',
  42653 => 'ь',
  42786 => 'ꜣ',
  42788 => 'ꜥ',
  42790 => 'ꜧ',
  42792 => 'ꜩ',
  42794 => 'ꜫ',
  42796 => 'ꜭ',
  42798 => 'ꜯ',
  42802 => 'ꜳ',
  42804 => 'ꜵ',
  42806 => 'ꜷ',
  42808 => 'ꜹ',
  42810 => 'ꜻ',
  42812 => 'ꜽ',
  42814 => 'ꜿ',
  42816 => 'ꝁ',
  42818 => 'ꝃ',
  42820 => 'ꝅ',
  42822 => 'ꝇ',
  42824 => 'ꝉ',
  42826 => 'ꝋ',
  42828 => 'ꝍ',
  42830 => 'ꝏ',
  42832 => 'ꝑ',
  42834 => 'ꝓ',
  42836 => 'ꝕ',
  42838 => 'ꝗ',
  42840 => 'ꝙ',
  42842 => 'ꝛ',
  42844 => 'ꝝ',
  42846 => 'ꝟ',
  42848 => 'ꝡ',
  42850 => 'ꝣ',
  42852 => 'ꝥ',
  42854 => 'ꝧ',
  42856 => 'ꝩ',
  42858 => 'ꝫ',
  42860 => 'ꝭ',
  42862 => 'ꝯ',
  42864 => 'ꝯ',
  42873 => 'ꝺ',
  42875 => 'ꝼ',
  42877 => 'ᵹ',
  42878 => 'ꝿ',
  42880 => 'ꞁ',
  42882 => 'ꞃ',
  42884 => 'ꞅ',
  42886 => 'ꞇ',
  42891 => 'ꞌ',
  42893 => 'ɥ',
  42896 => 'ꞑ',
  42898 => 'ꞓ',
  42902 => 'ꞗ',
  42904 => 'ꞙ',
  42906 => 'ꞛ',
  42908 => 'ꞝ',
  42910 => 'ꞟ',
  42912 => 'ꞡ',
  42914 => 'ꞣ',
  42916 => 'ꞥ',
  42918 => 'ꞧ',
  42920 => 'ꞩ',
  42922 => 'ɦ',
  42923 => 'ɜ',
  42924 => 'ɡ',
  42925 => 'ɬ',
  42926 => 'ɪ',
  42928 => 'ʞ',
  42929 => 'ʇ',
  42930 => 'ʝ',
  42931 => 'ꭓ',
  42932 => 'ꞵ',
  42934 => 'ꞷ',
  42936 => 'ꞹ',
  42938 => 'ꞻ',
  42940 => 'ꞽ',
  42942 => 'ꞿ',
  42946 => 'ꟃ',
  42948 => 'ꞔ',
  42949 => 'ʂ',
  42950 => 'ᶎ',
  42951 => 'ꟈ',
  42953 => 'ꟊ',
  42997 => 'ꟶ',
  43000 => 'ħ',
  43001 => 'œ',
  43868 => 'ꜧ',
  43869 => 'ꬷ',
  43870 => 'ɫ',
  43871 => 'ꭒ',
  43881 => 'ʍ',
  43888 => 'Ꭰ',
  43889 => 'Ꭱ',
  43890 => 'Ꭲ',
  43891 => 'Ꭳ',
  43892 => 'Ꭴ',
  43893 => 'Ꭵ',
  43894 => 'Ꭶ',
  43895 => 'Ꭷ',
  43896 => 'Ꭸ',
  43897 => 'Ꭹ',
  43898 => 'Ꭺ',
  43899 => 'Ꭻ',
  43900 => 'Ꭼ',
  43901 => 'Ꭽ',
  43902 => 'Ꭾ',
  43903 => 'Ꭿ',
  43904 => 'Ꮀ',
  43905 => 'Ꮁ',
  43906 => 'Ꮂ',
  43907 => 'Ꮃ',
  43908 => 'Ꮄ',
  43909 => 'Ꮅ',
  43910 => 'Ꮆ',
  43911 => 'Ꮇ',
  43912 => 'Ꮈ',
  43913 => 'Ꮉ',
  43914 => 'Ꮊ',
  43915 => 'Ꮋ',
  43916 => 'Ꮌ',
  43917 => 'Ꮍ',
  43918 => 'Ꮎ',
  43919 => 'Ꮏ',
  43920 => 'Ꮐ',
  43921 => 'Ꮑ',
  43922 => 'Ꮒ',
  43923 => 'Ꮓ',
  43924 => 'Ꮔ',
  43925 => 'Ꮕ',
  43926 => 'Ꮖ',
  43927 => 'Ꮗ',
  43928 => 'Ꮘ',
  43929 => 'Ꮙ',
  43930 => 'Ꮚ',
  43931 => 'Ꮛ',
  43932 => 'Ꮜ',
  43933 => 'Ꮝ',
  43934 => 'Ꮞ',
  43935 => 'Ꮟ',
  43936 => 'Ꮠ',
  43937 => 'Ꮡ',
  43938 => 'Ꮢ',
  43939 => 'Ꮣ',
  43940 => 'Ꮤ',
  43941 => 'Ꮥ',
  43942 => 'Ꮦ',
  43943 => 'Ꮧ',
  43944 => 'Ꮨ',
  43945 => 'Ꮩ',
  43946 => 'Ꮪ',
  43947 => 'Ꮫ',
  43948 => 'Ꮬ',
  43949 => 'Ꮭ',
  43950 => 'Ꮮ',
  43951 => 'Ꮯ',
  43952 => 'Ꮰ',
  43953 => 'Ꮱ',
  43954 => 'Ꮲ',
  43955 => 'Ꮳ',
  43956 => 'Ꮴ',
  43957 => 'Ꮵ',
  43958 => 'Ꮶ',
  43959 => 'Ꮷ',
  43960 => 'Ꮸ',
  43961 => 'Ꮹ',
  43962 => 'Ꮺ',
  43963 => 'Ꮻ',
  43964 => 'Ꮼ',
  43965 => 'Ꮽ',
  43966 => 'Ꮾ',
  43967 => 'Ꮿ',
  63744 => '豈',
  63745 => '更',
  63746 => '車',
  63747 => '賈',
  63748 => '滑',
  63749 => '串',
  63750 => '句',
  63751 => '龜',
  63752 => '龜',
  63753 => '契',
  63754 => '金',
  63755 => '喇',
  63756 => '奈',
  63757 => '懶',
  63758 => '癩',
  63759 => '羅',
  63760 => '蘿',
  63761 => '螺',
  63762 => '裸',
  63763 => '邏',
  63764 => '樂',
  63765 => '洛',
  63766 => '烙',
  63767 => '珞',
  63768 => '落',
  63769 => '酪',
  63770 => '駱',
  63771 => '亂',
  63772 => '卵',
  63773 => '欄',
  63774 => '爛',
  63775 => '蘭',
  63776 => '鸞',
  63777 => '嵐',
  63778 => '濫',
  63779 => '藍',
  63780 => '襤',
  63781 => '拉',
  63782 => '臘',
  63783 => '蠟',
  63784 => '廊',
  63785 => '朗',
  63786 => '浪',
  63787 => '狼',
  63788 => '郎',
  63789 => '來',
  63790 => '冷',
  63791 => '勞',
  63792 => '擄',
  63793 => '櫓',
  63794 => '爐',
  63795 => '盧',
  63796 => '老',
  63797 => '蘆',
  63798 => '虜',
  63799 => '路',
  63800 => '露',
  63801 => '魯',
  63802 => '鷺',
  63803 => '碌',
  63804 => '祿',
  63805 => '綠',
  63806 => '菉',
  63807 => '錄',
  63808 => '鹿',
  63809 => '論',
  63810 => '壟',
  63811 => '弄',
  63812 => '籠',
  63813 => '聾',
  63814 => '牢',
  63815 => '磊',
  63816 => '賂',
  63817 => '雷',
  63818 => '壘',
  63819 => '屢',
  63820 => '樓',
  63821 => '淚',
  63822 => '漏',
  63823 => '累',
  63824 => '縷',
  63825 => '陋',
  63826 => '勒',
  63827 => '肋',
  63828 => '凜',
  63829 => '凌',
  63830 => '稜',
  63831 => '綾',
  63832 => '菱',
  63833 => '陵',
  63834 => '讀',
  63835 => '拏',
  63836 => '樂',
  63837 => '諾',
  63838 => '丹',
  63839 => '寧',
  63840 => '怒',
  63841 => '率',
  63842 => '異',
  63843 => '北',
  63844 => '磻',
  63845 => '便',
  63846 => '復',
  63847 => '不',
  63848 => '泌',
  63849 => '數',
  63850 => '索',
  63851 => '參',
  63852 => '塞',
  63853 => '省',
  63854 => '葉',
  63855 => '說',
  63856 => '殺',
  63857 => '辰',
  63858 => '沈',
  63859 => '拾',
  63860 => '若',
  63861 => '掠',
  63862 => '略',
  63863 => '亮',
  63864 => '兩',
  63865 => '凉',
  63866 => '梁',
  63867 => '糧',
  63868 => '良',
  63869 => '諒',
  63870 => '量',
  63871 => '勵',
  63872 => '呂',
  63873 => '女',
  63874 => '廬',
  63875 => '旅',
  63876 => '濾',
  63877 => '礪',
  63878 => '閭',
  63879 => '驪',
  63880 => '麗',
  63881 => '黎',
  63882 => '力',
  63883 => '曆',
  63884 => '歷',
  63885 => '轢',
  63886 => '年',
  63887 => '憐',
  63888 => '戀',
  63889 => '撚',
  63890 => '漣',
  63891 => '煉',
  63892 => '璉',
  63893 => '秊',
  63894 => '練',
  63895 => '聯',
  63896 => '輦',
  63897 => '蓮',
  63898 => '連',
  63899 => '鍊',
  63900 => '列',
  63901 => '劣',
  63902 => '咽',
  63903 => '烈',
  63904 => '裂',
  63905 => '說',
  63906 => '廉',
  63907 => '念',
  63908 => '捻',
  63909 => '殮',
  63910 => '簾',
  63911 => '獵',
  63912 => '令',
  63913 => '囹',
  63914 => '寧',
  63915 => '嶺',
  63916 => '怜',
  63917 => '玲',
  63918 => '瑩',
  63919 => '羚',
  63920 => '聆',
  63921 => '鈴',
  63922 => '零',
  63923 => '靈',
  63924 => '領',
  63925 => '例',
  63926 => '禮',
  63927 => '醴',
  63928 => '隸',
  63929 => '惡',
  63930 => '了',
  63931 => '僚',
  63932 => '寮',
  63933 => '尿',
  63934 => '料',
  63935 => '樂',
  63936 => '燎',
  63937 => '療',
  63938 => '蓼',
  63939 => '遼',
  63940 => '龍',
  63941 => '暈',
  63942 => '阮',
  63943 => '劉',
  63944 => '杻',
  63945 => '柳',
  63946 => '流',
  63947 => '溜',
  63948 => '琉',
  63949 => '留',
  63950 => '硫',
  63951 => '紐',
  63952 => '類',
  63953 => '六',
  63954 => '戮',
  63955 => '陸',
  63956 => '倫',
  63957 => '崙',
  63958 => '淪',
  63959 => '輪',
  63960 => '律',
  63961 => '慄',
  63962 => '栗',
  63963 => '率',
  63964 => '隆',
  63965 => '利',
  63966 => '吏',
  63967 => '履',
  63968 => '易',
  63969 => '李',
  63970 => '梨',
  63971 => '泥',
  63972 => '理',
  63973 => '痢',
  63974 => '罹',
  63975 => '裏',
  63976 => '裡',
  63977 => '里',
  63978 => '離',
  63979 => '匿',
  63980 => '溺',
  63981 => '吝',
  63982 => '燐',
  63983 => '璘',
  63984 => '藺',
  63985 => '隣',
  63986 => '鱗',
  63987 => '麟',
  63988 => '林',
  63989 => '淋',
  63990 => '臨',
  63991 => '立',
  63992 => '笠',
  63993 => '粒',
  63994 => '狀',
  63995 => '炙',
  63996 => '識',
  63997 => '什',
  63998 => '茶',
  63999 => '刺',
  64000 => '切',
  64001 => '度',
  64002 => '拓',
  64003 => '糖',
  64004 => '宅',
  64005 => '洞',
  64006 => '暴',
  64007 => '輻',
  64008 => '行',
  64009 => '降',
  64010 => '見',
  64011 => '廓',
  64012 => '兀',
  64013 => '嗀',
  64016 => '塚',
  64018 => '晴',
  64021 => '凞',
  64022 => '猪',
  64023 => '益',
  64024 => '礼',
  64025 => '神',
  64026 => '祥',
  64027 => '福',
  64028 => '靖',
  64029 => '精',
  64030 => '羽',
  64032 => '蘒',
  64034 => '諸',
  64037 => '逸',
  64038 => '都',
  64042 => '飯',
  64043 => '飼',
  64044 => '館',
  64045 => '鶴',
  64046 => '郞',
  64047 => '隷',
  64048 => '侮',
  64049 => '僧',
  64050 => '免',
  64051 => '勉',
  64052 => '勤',
  64053 => '卑',
  64054 => '喝',
  64055 => '嘆',
  64056 => '器',
  64057 => '塀',
  64058 => '墨',
  64059 => '層',
  64060 => '屮',
  64061 => '悔',
  64062 => '慨',
  64063 => '憎',
  64064 => '懲',
  64065 => '敏',
  64066 => '既',
  64067 => '暑',
  64068 => '梅',
  64069 => '海',
  64070 => '渚',
  64071 => '漢',
  64072 => '煮',
  64073 => '爫',
  64074 => '琢',
  64075 => '碑',
  64076 => '社',
  64077 => '祉',
  64078 => '祈',
  64079 => '祐',
  64080 => '祖',
  64081 => '祝',
  64082 => '禍',
  64083 => '禎',
  64084 => '穀',
  64085 => '突',
  64086 => '節',
  64087 => '練',
  64088 => '縉',
  64089 => '繁',
  64090 => '署',
  64091 => '者',
  64092 => '臭',
  64093 => '艹',
  64094 => '艹',
  64095 => '著',
  64096 => '褐',
  64097 => '視',
  64098 => '謁',
  64099 => '謹',
  64100 => '賓',
  64101 => '贈',
  64102 => '辶',
  64103 => '逸',
  64104 => '難',
  64105 => '響',
  64106 => '頻',
  64107 => '恵',
  64108 => '𤋮',
  64109 => '舘',
  64112 => '並',
  64113 => '况',
  64114 => '全',
  64115 => '侀',
  64116 => '充',
  64117 => '冀',
  64118 => '勇',
  64119 => '勺',
  64120 => '喝',
  64121 => '啕',
  64122 => '喙',
  64123 => '嗢',
  64124 => '塚',
  64125 => '墳',
  64126 => '奄',
  64127 => '奔',
  64128 => '婢',
  64129 => '嬨',
  64130 => '廒',
  64131 => '廙',
  64132 => '彩',
  64133 => '徭',
  64134 => '惘',
  64135 => '慎',
  64136 => '愈',
  64137 => '憎',
  64138 => '慠',
  64139 => '懲',
  64140 => '戴',
  64141 => '揄',
  64142 => '搜',
  64143 => '摒',
  64144 => '敖',
  64145 => '晴',
  64146 => '朗',
  64147 => '望',
  64148 => '杖',
  64149 => '歹',
  64150 => '殺',
  64151 => '流',
  64152 => '滛',
  64153 => '滋',
  64154 => '漢',
  64155 => '瀞',
  64156 => '煮',
  64157 => '瞧',
  64158 => '爵',
  64159 => '犯',
  64160 => '猪',
  64161 => '瑱',
  64162 => '甆',
  64163 => '画',
  64164 => '瘝',
  64165 => '瘟',
  64166 => '益',
  64167 => '盛',
  64168 => '直',
  64169 => '睊',
  64170 => '着',
  64171 => '磌',
  64172 => '窱',
  64173 => '節',
  64174 => '类',
  64175 => '絛',
  64176 => '練',
  64177 => '缾',
  64178 => '者',
  64179 => '荒',
  64180 => '華',
  64181 => '蝹',
  64182 => '襁',
  64183 => '覆',
  64184 => '視',
  64185 => '調',
  64186 => '諸',
  64187 => '請',
  64188 => '謁',
  64189 => '諾',
  64190 => '諭',
  64191 => '謹',
  64192 => '變',
  64193 => '贈',
  64194 => '輸',
  64195 => '遲',
  64196 => '醙',
  64197 => '鉶',
  64198 => '陼',
  64199 => '難',
  64200 => '靖',
  64201 => '韛',
  64202 => '響',
  64203 => '頋',
  64204 => '頻',
  64205 => '鬒',
  64206 => '龜',
  64207 => '𢡊',
  64208 => '𢡄',
  64209 => '𣏕',
  64210 => '㮝',
  64211 => '䀘',
  64212 => '䀹',
  64213 => '𥉉',
  64214 => '𥳐',
  64215 => '𧻓',
  64216 => '齃',
  64217 => '龎',
  64256 => 'ff',
  64257 => 'fi',
  64258 => 'fl',
  64259 => 'ffi',
  64260 => 'ffl',
  64261 => 'st',
  64262 => 'st',
  64275 => 'մն',
  64276 => 'մե',
  64277 => 'մի',
  64278 => 'վն',
  64279 => 'մխ',
  64285 => 'יִ',
  64287 => 'ײַ',
  64288 => 'ע',
  64289 => 'א',
  64290 => 'ד',
  64291 => 'ה',
  64292 => 'כ',
  64293 => 'ל',
  64294 => 'ם',
  64295 => 'ר',
  64296 => 'ת',
  64298 => 'שׁ',
  64299 => 'שׂ',
  64300 => 'שּׁ',
  64301 => 'שּׂ',
  64302 => 'אַ',
  64303 => 'אָ',
  64304 => 'אּ',
  64305 => 'בּ',
  64306 => 'גּ',
  64307 => 'דּ',
  64308 => 'הּ',
  64309 => 'וּ',
  64310 => 'זּ',
  64312 => 'טּ',
  64313 => 'יּ',
  64314 => 'ךּ',
  64315 => 'כּ',
  64316 => 'לּ',
  64318 => 'מּ',
  64320 => 'נּ',
  64321 => 'סּ',
  64323 => 'ףּ',
  64324 => 'פּ',
  64326 => 'צּ',
  64327 => 'קּ',
  64328 => 'רּ',
  64329 => 'שּ',
  64330 => 'תּ',
  64331 => 'וֹ',
  64332 => 'בֿ',
  64333 => 'כֿ',
  64334 => 'פֿ',
  64335 => 'אל',
  64336 => 'ٱ',
  64337 => 'ٱ',
  64338 => 'ٻ',
  64339 => 'ٻ',
  64340 => 'ٻ',
  64341 => 'ٻ',
  64342 => 'پ',
  64343 => 'پ',
  64344 => 'پ',
  64345 => 'پ',
  64346 => 'ڀ',
  64347 => 'ڀ',
  64348 => 'ڀ',
  64349 => 'ڀ',
  64350 => 'ٺ',
  64351 => 'ٺ',
  64352 => 'ٺ',
  64353 => 'ٺ',
  64354 => 'ٿ',
  64355 => 'ٿ',
  64356 => 'ٿ',
  64357 => 'ٿ',
  64358 => 'ٹ',
  64359 => 'ٹ',
  64360 => 'ٹ',
  64361 => 'ٹ',
  64362 => 'ڤ',
  64363 => 'ڤ',
  64364 => 'ڤ',
  64365 => 'ڤ',
  64366 => 'ڦ',
  64367 => 'ڦ',
  64368 => 'ڦ',
  64369 => 'ڦ',
  64370 => 'ڄ',
  64371 => 'ڄ',
  64372 => 'ڄ',
  64373 => 'ڄ',
  64374 => 'ڃ',
  64375 => 'ڃ',
  64376 => 'ڃ',
  64377 => 'ڃ',
  64378 => 'چ',
  64379 => 'چ',
  64380 => 'چ',
  64381 => 'چ',
  64382 => 'ڇ',
  64383 => 'ڇ',
  64384 => 'ڇ',
  64385 => 'ڇ',
  64386 => 'ڍ',
  64387 => 'ڍ',
  64388 => 'ڌ',
  64389 => 'ڌ',
  64390 => 'ڎ',
  64391 => 'ڎ',
  64392 => 'ڈ',
  64393 => 'ڈ',
  64394 => 'ژ',
  64395 => 'ژ',
  64396 => 'ڑ',
  64397 => 'ڑ',
  64398 => 'ک',
  64399 => 'ک',
  64400 => 'ک',
  64401 => 'ک',
  64402 => 'گ',
  64403 => 'گ',
  64404 => 'گ',
  64405 => 'گ',
  64406 => 'ڳ',
  64407 => 'ڳ',
  64408 => 'ڳ',
  64409 => 'ڳ',
  64410 => 'ڱ',
  64411 => 'ڱ',
  64412 => 'ڱ',
  64413 => 'ڱ',
  64414 => 'ں',
  64415 => 'ں',
  64416 => 'ڻ',
  64417 => 'ڻ',
  64418 => 'ڻ',
  64419 => 'ڻ',
  64420 => 'ۀ',
  64421 => 'ۀ',
  64422 => 'ہ',
  64423 => 'ہ',
  64424 => 'ہ',
  64425 => 'ہ',
  64426 => 'ھ',
  64427 => 'ھ',
  64428 => 'ھ',
  64429 => 'ھ',
  64430 => 'ے',
  64431 => 'ے',
  64432 => 'ۓ',
  64433 => 'ۓ',
  64467 => 'ڭ',
  64468 => 'ڭ',
  64469 => 'ڭ',
  64470 => 'ڭ',
  64471 => 'ۇ',
  64472 => 'ۇ',
  64473 => 'ۆ',
  64474 => 'ۆ',
  64475 => 'ۈ',
  64476 => 'ۈ',
  64477 => 'ۇٴ',
  64478 => 'ۋ',
  64479 => 'ۋ',
  64480 => 'ۅ',
  64481 => 'ۅ',
  64482 => 'ۉ',
  64483 => 'ۉ',
  64484 => 'ې',
  64485 => 'ې',
  64486 => 'ې',
  64487 => 'ې',
  64488 => 'ى',
  64489 => 'ى',
  64490 => 'ئا',
  64491 => 'ئا',
  64492 => 'ئە',
  64493 => 'ئە',
  64494 => 'ئو',
  64495 => 'ئو',
  64496 => 'ئۇ',
  64497 => 'ئۇ',
  64498 => 'ئۆ',
  64499 => 'ئۆ',
  64500 => 'ئۈ',
  64501 => 'ئۈ',
  64502 => 'ئې',
  64503 => 'ئې',
  64504 => 'ئې',
  64505 => 'ئى',
  64506 => 'ئى',
  64507 => 'ئى',
  64508 => 'ی',
  64509 => 'ی',
  64510 => 'ی',
  64511 => 'ی',
  64512 => 'ئج',
  64513 => 'ئح',
  64514 => 'ئم',
  64515 => 'ئى',
  64516 => 'ئي',
  64517 => 'بج',
  64518 => 'بح',
  64519 => 'بخ',
  64520 => 'بم',
  64521 => 'بى',
  64522 => 'بي',
  64523 => 'تج',
  64524 => 'تح',
  64525 => 'تخ',
  64526 => 'تم',
  64527 => 'تى',
  64528 => 'تي',
  64529 => 'ثج',
  64530 => 'ثم',
  64531 => 'ثى',
  64532 => 'ثي',
  64533 => 'جح',
  64534 => 'جم',
  64535 => 'حج',
  64536 => 'حم',
  64537 => 'خج',
  64538 => 'خح',
  64539 => 'خم',
  64540 => 'سج',
  64541 => 'سح',
  64542 => 'سخ',
  64543 => 'سم',
  64544 => 'صح',
  64545 => 'صم',
  64546 => 'ضج',
  64547 => 'ضح',
  64548 => 'ضخ',
  64549 => 'ضم',
  64550 => 'طح',
  64551 => 'طم',
  64552 => 'ظم',
  64553 => 'عج',
  64554 => 'عم',
  64555 => 'غج',
  64556 => 'غم',
  64557 => 'فج',
  64558 => 'فح',
  64559 => 'فخ',
  64560 => 'فم',
  64561 => 'فى',
  64562 => 'في',
  64563 => 'قح',
  64564 => 'قم',
  64565 => 'قى',
  64566 => 'قي',
  64567 => 'كا',
  64568 => 'كج',
  64569 => 'كح',
  64570 => 'كخ',
  64571 => 'كل',
  64572 => 'كم',
  64573 => 'كى',
  64574 => 'كي',
  64575 => 'لج',
  64576 => 'لح',
  64577 => 'لخ',
  64578 => 'لم',
  64579 => 'لى',
  64580 => 'لي',
  64581 => 'مج',
  64582 => 'مح',
  64583 => 'مخ',
  64584 => 'مم',
  64585 => 'مى',
  64586 => 'مي',
  64587 => 'نج',
  64588 => 'نح',
  64589 => 'نخ',
  64590 => 'نم',
  64591 => 'نى',
  64592 => 'ني',
  64593 => 'هج',
  64594 => 'هم',
  64595 => 'هى',
  64596 => 'هي',
  64597 => 'يج',
  64598 => 'يح',
  64599 => 'يخ',
  64600 => 'يم',
  64601 => 'يى',
  64602 => 'يي',
  64603 => 'ذٰ',
  64604 => 'رٰ',
  64605 => 'ىٰ',
  64612 => 'ئر',
  64613 => 'ئز',
  64614 => 'ئم',
  64615 => 'ئن',
  64616 => 'ئى',
  64617 => 'ئي',
  64618 => 'بر',
  64619 => 'بز',
  64620 => 'بم',
  64621 => 'بن',
  64622 => 'بى',
  64623 => 'بي',
  64624 => 'تر',
  64625 => 'تز',
  64626 => 'تم',
  64627 => 'تن',
  64628 => 'تى',
  64629 => 'تي',
  64630 => 'ثر',
  64631 => 'ثز',
  64632 => 'ثم',
  64633 => 'ثن',
  64634 => 'ثى',
  64635 => 'ثي',
  64636 => 'فى',
  64637 => 'في',
  64638 => 'قى',
  64639 => 'قي',
  64640 => 'كا',
  64641 => 'كل',
  64642 => 'كم',
  64643 => 'كى',
  64644 => 'كي',
  64645 => 'لم',
  64646 => 'لى',
  64647 => 'لي',
  64648 => 'ما',
  64649 => 'مم',
  64650 => 'نر',
  64651 => 'نز',
  64652 => 'نم',
  64653 => 'نن',
  64654 => 'نى',
  64655 => 'ني',
  64656 => 'ىٰ',
  64657 => 'ير',
  64658 => 'يز',
  64659 => 'يم',
  64660 => 'ين',
  64661 => 'يى',
  64662 => 'يي',
  64663 => 'ئج',
  64664 => 'ئح',
  64665 => 'ئخ',
  64666 => 'ئم',
  64667 => 'ئه',
  64668 => 'بج',
  64669 => 'بح',
  64670 => 'بخ',
  64671 => 'بم',
  64672 => 'به',
  64673 => 'تج',
  64674 => 'تح',
  64675 => 'تخ',
  64676 => 'تم',
  64677 => 'ته',
  64678 => 'ثم',
  64679 => 'جح',
  64680 => 'جم',
  64681 => 'حج',
  64682 => 'حم',
  64683 => 'خج',
  64684 => 'خم',
  64685 => 'سج',
  64686 => 'سح',
  64687 => 'سخ',
  64688 => 'سم',
  64689 => 'صح',
  64690 => 'صخ',
  64691 => 'صم',
  64692 => 'ضج',
  64693 => 'ضح',
  64694 => 'ضخ',
  64695 => 'ضم',
  64696 => 'طح',
  64697 => 'ظم',
  64698 => 'عج',
  64699 => 'عم',
  64700 => 'غج',
  64701 => 'غم',
  64702 => 'فج',
  64703 => 'فح',
  64704 => 'فخ',
  64705 => 'فم',
  64706 => 'قح',
  64707 => 'قم',
  64708 => 'كج',
  64709 => 'كح',
  64710 => 'كخ',
  64711 => 'كل',
  64712 => 'كم',
  64713 => 'لج',
  64714 => 'لح',
  64715 => 'لخ',
  64716 => 'لم',
  64717 => 'له',
  64718 => 'مج',
  64719 => 'مح',
  64720 => 'مخ',
  64721 => 'مم',
  64722 => 'نج',
  64723 => 'نح',
  64724 => 'نخ',
  64725 => 'نم',
  64726 => 'نه',
  64727 => 'هج',
  64728 => 'هم',
  64729 => 'هٰ',
  64730 => 'يج',
  64731 => 'يح',
  64732 => 'يخ',
  64733 => 'يم',
  64734 => 'يه',
  64735 => 'ئم',
  64736 => 'ئه',
  64737 => 'بم',
  64738 => 'به',
  64739 => 'تم',
  64740 => 'ته',
  64741 => 'ثم',
  64742 => 'ثه',
  64743 => 'سم',
  64744 => 'سه',
  64745 => 'شم',
  64746 => 'شه',
  64747 => 'كل',
  64748 => 'كم',
  64749 => 'لم',
  64750 => 'نم',
  64751 => 'نه',
  64752 => 'يم',
  64753 => 'يه',
  64754 => 'ـَّ',
  64755 => 'ـُّ',
  64756 => 'ـِّ',
  64757 => 'طى',
  64758 => 'طي',
  64759 => 'عى',
  64760 => 'عي',
  64761 => 'غى',
  64762 => 'غي',
  64763 => 'سى',
  64764 => 'سي',
  64765 => 'شى',
  64766 => 'شي',
  64767 => 'حى',
  64768 => 'حي',
  64769 => 'جى',
  64770 => 'جي',
  64771 => 'خى',
  64772 => 'خي',
  64773 => 'صى',
  64774 => 'صي',
  64775 => 'ضى',
  64776 => 'ضي',
  64777 => 'شج',
  64778 => 'شح',
  64779 => 'شخ',
  64780 => 'شم',
  64781 => 'شر',
  64782 => 'سر',
  64783 => 'صر',
  64784 => 'ضر',
  64785 => 'طى',
  64786 => 'طي',
  64787 => 'عى',
  64788 => 'عي',
  64789 => 'غى',
  64790 => 'غي',
  64791 => 'سى',
  64792 => 'سي',
  64793 => 'شى',
  64794 => 'شي',
  64795 => 'حى',
  64796 => 'حي',
  64797 => 'جى',
  64798 => 'جي',
  64799 => 'خى',
  64800 => 'خي',
  64801 => 'صى',
  64802 => 'صي',
  64803 => 'ضى',
  64804 => 'ضي',
  64805 => 'شج',
  64806 => 'شح',
  64807 => 'شخ',
  64808 => 'شم',
  64809 => 'شر',
  64810 => 'سر',
  64811 => 'صر',
  64812 => 'ضر',
  64813 => 'شج',
  64814 => 'شح',
  64815 => 'شخ',
  64816 => 'شم',
  64817 => 'سه',
  64818 => 'شه',
  64819 => 'طم',
  64820 => 'سج',
  64821 => 'سح',
  64822 => 'سخ',
  64823 => 'شج',
  64824 => 'شح',
  64825 => 'شخ',
  64826 => 'طم',
  64827 => 'ظم',
  64828 => 'اً',
  64829 => 'اً',
  64848 => 'تجم',
  64849 => 'تحج',
  64850 => 'تحج',
  64851 => 'تحم',
  64852 => 'تخم',
  64853 => 'تمج',
  64854 => 'تمح',
  64855 => 'تمخ',
  64856 => 'جمح',
  64857 => 'جمح',
  64858 => 'حمي',
  64859 => 'حمى',
  64860 => 'سحج',
  64861 => 'سجح',
  64862 => 'سجى',
  64863 => 'سمح',
  64864 => 'سمح',
  64865 => 'سمج',
  64866 => 'سمم',
  64867 => 'سمم',
  64868 => 'صحح',
  64869 => 'صحح',
  64870 => 'صمم',
  64871 => 'شحم',
  64872 => 'شحم',
  64873 => 'شجي',
  64874 => 'شمخ',
  64875 => 'شمخ',
  64876 => 'شمم',
  64877 => 'شمم',
  64878 => 'ضحى',
  64879 => 'ضخم',
  64880 => 'ضخم',
  64881 => 'طمح',
  64882 => 'طمح',
  64883 => 'طمم',
  64884 => 'طمي',
  64885 => 'عجم',
  64886 => 'عمم',
  64887 => 'عمم',
  64888 => 'عمى',
  64889 => 'غمم',
  64890 => 'غمي',
  64891 => 'غمى',
  64892 => 'فخم',
  64893 => 'فخم',
  64894 => 'قمح',
  64895 => 'قمم',
  64896 => 'لحم',
  64897 => 'لحي',
  64898 => 'لحى',
  64899 => 'لجج',
  64900 => 'لجج',
  64901 => 'لخم',
  64902 => 'لخم',
  64903 => 'لمح',
  64904 => 'لمح',
  64905 => 'محج',
  64906 => 'محم',
  64907 => 'محي',
  64908 => 'مجح',
  64909 => 'مجم',
  64910 => 'مخج',
  64911 => 'مخم',
  64914 => 'مجخ',
  64915 => 'همج',
  64916 => 'همم',
  64917 => 'نحم',
  64918 => 'نحى',
  64919 => 'نجم',
  64920 => 'نجم',
  64921 => 'نجى',
  64922 => 'نمي',
  64923 => 'نمى',
  64924 => 'يمم',
  64925 => 'يمم',
  64926 => 'بخي',
  64927 => 'تجي',
  64928 => 'تجى',
  64929 => 'تخي',
  64930 => 'تخى',
  64931 => 'تمي',
  64932 => 'تمى',
  64933 => 'جمي',
  64934 => 'جحى',
  64935 => 'جمى',
  64936 => 'سخى',
  64937 => 'صحي',
  64938 => 'شحي',
  64939 => 'ضحي',
  64940 => 'لجي',
  64941 => 'لمي',
  64942 => 'يحي',
  64943 => 'يجي',
  64944 => 'يمي',
  64945 => 'ممي',
  64946 => 'قمي',
  64947 => 'نحي',
  64948 => 'قمح',
  64949 => 'لحم',
  64950 => 'عمي',
  64951 => 'كمي',
  64952 => 'نجح',
  64953 => 'مخي',
  64954 => 'لجم',
  64955 => 'كمم',
  64956 => 'لجم',
  64957 => 'نجح',
  64958 => 'جحي',
  64959 => 'حجي',
  64960 => 'مجي',
  64961 => 'فمي',
  64962 => 'بحي',
  64963 => 'كمم',
  64964 => 'عجم',
  64965 => 'صمم',
  64966 => 'سخي',
  64967 => 'نجي',
  65008 => 'صلے',
  65009 => 'قلے',
  65010 => 'الله',
  65011 => 'اكبر',
  65012 => 'محمد',
  65013 => 'صلعم',
  65014 => 'رسول',
  65015 => 'عليه',
  65016 => 'وسلم',
  65017 => 'صلى',
  65020 => 'ریال',
  65041 => '、',
  65047 => '〖',
  65048 => '〗',
  65073 => '—',
  65074 => '–',
  65081 => '〔',
  65082 => '〕',
  65083 => '【',
  65084 => '】',
  65085 => '《',
  65086 => '》',
  65087 => '〈',
  65088 => '〉',
  65089 => '「',
  65090 => '」',
  65091 => '『',
  65092 => '』',
  65105 => '、',
  65112 => '—',
  65117 => '〔',
  65118 => '〕',
  65123 => '-',
  65137 => 'ـً',
  65143 => 'ـَ',
  65145 => 'ـُ',
  65147 => 'ـِ',
  65149 => 'ـّ',
  65151 => 'ـْ',
  65152 => 'ء',
  65153 => 'آ',
  65154 => 'آ',
  65155 => 'أ',
  65156 => 'أ',
  65157 => 'ؤ',
  65158 => 'ؤ',
  65159 => 'إ',
  65160 => 'إ',
  65161 => 'ئ',
  65162 => 'ئ',
  65163 => 'ئ',
  65164 => 'ئ',
  65165 => 'ا',
  65166 => 'ا',
  65167 => 'ب',
  65168 => 'ب',
  65169 => 'ب',
  65170 => 'ب',
  65171 => 'ة',
  65172 => 'ة',
  65173 => 'ت',
  65174 => 'ت',
  65175 => 'ت',
  65176 => 'ت',
  65177 => 'ث',
  65178 => 'ث',
  65179 => 'ث',
  65180 => 'ث',
  65181 => 'ج',
  65182 => 'ج',
  65183 => 'ج',
  65184 => 'ج',
  65185 => 'ح',
  65186 => 'ح',
  65187 => 'ح',
  65188 => 'ح',
  65189 => 'خ',
  65190 => 'خ',
  65191 => 'خ',
  65192 => 'خ',
  65193 => 'د',
  65194 => 'د',
  65195 => 'ذ',
  65196 => 'ذ',
  65197 => 'ر',
  65198 => 'ر',
  65199 => 'ز',
  65200 => 'ز',
  65201 => 'س',
  65202 => 'س',
  65203 => 'س',
  65204 => 'س',
  65205 => 'ش',
  65206 => 'ش',
  65207 => 'ش',
  65208 => 'ش',
  65209 => 'ص',
  65210 => 'ص',
  65211 => 'ص',
  65212 => 'ص',
  65213 => 'ض',
  65214 => 'ض',
  65215 => 'ض',
  65216 => 'ض',
  65217 => 'ط',
  65218 => 'ط',
  65219 => 'ط',
  65220 => 'ط',
  65221 => 'ظ',
  65222 => 'ظ',
  65223 => 'ظ',
  65224 => 'ظ',
  65225 => 'ع',
  65226 => 'ع',
  65227 => 'ع',
  65228 => 'ع',
  65229 => 'غ',
  65230 => 'غ',
  65231 => 'غ',
  65232 => 'غ',
  65233 => 'ف',
  65234 => 'ف',
  65235 => 'ف',
  65236 => 'ف',
  65237 => 'ق',
  65238 => 'ق',
  65239 => 'ق',
  65240 => 'ق',
  65241 => 'ك',
  65242 => 'ك',
  65243 => 'ك',
  65244 => 'ك',
  65245 => 'ل',
  65246 => 'ل',
  65247 => 'ل',
  65248 => 'ل',
  65249 => 'م',
  65250 => 'م',
  65251 => 'م',
  65252 => 'م',
  65253 => 'ن',
  65254 => 'ن',
  65255 => 'ن',
  65256 => 'ن',
  65257 => 'ه',
  65258 => 'ه',
  65259 => 'ه',
  65260 => 'ه',
  65261 => 'و',
  65262 => 'و',
  65263 => 'ى',
  65264 => 'ى',
  65265 => 'ي',
  65266 => 'ي',
  65267 => 'ي',
  65268 => 'ي',
  65269 => 'لآ',
  65270 => 'لآ',
  65271 => 'لأ',
  65272 => 'لأ',
  65273 => 'لإ',
  65274 => 'لإ',
  65275 => 'لا',
  65276 => 'لا',
  65293 => '-',
  65294 => '.',
  65296 => '0',
  65297 => '1',
  65298 => '2',
  65299 => '3',
  65300 => '4',
  65301 => '5',
  65302 => '6',
  65303 => '7',
  65304 => '8',
  65305 => '9',
  65313 => 'a',
  65314 => 'b',
  65315 => 'c',
  65316 => 'd',
  65317 => 'e',
  65318 => 'f',
  65319 => 'g',
  65320 => 'h',
  65321 => 'i',
  65322 => 'j',
  65323 => 'k',
  65324 => 'l',
  65325 => 'm',
  65326 => 'n',
  65327 => 'o',
  65328 => 'p',
  65329 => 'q',
  65330 => 'r',
  65331 => 's',
  65332 => 't',
  65333 => 'u',
  65334 => 'v',
  65335 => 'w',
  65336 => 'x',
  65337 => 'y',
  65338 => 'z',
  65345 => 'a',
  65346 => 'b',
  65347 => 'c',
  65348 => 'd',
  65349 => 'e',
  65350 => 'f',
  65351 => 'g',
  65352 => 'h',
  65353 => 'i',
  65354 => 'j',
  65355 => 'k',
  65356 => 'l',
  65357 => 'm',
  65358 => 'n',
  65359 => 'o',
  65360 => 'p',
  65361 => 'q',
  65362 => 'r',
  65363 => 's',
  65364 => 't',
  65365 => 'u',
  65366 => 'v',
  65367 => 'w',
  65368 => 'x',
  65369 => 'y',
  65370 => 'z',
  65375 => '⦅',
  65376 => '⦆',
  65377 => '.',
  65378 => '「',
  65379 => '」',
  65380 => '、',
  65381 => '・',
  65382 => 'ヲ',
  65383 => 'ァ',
  65384 => 'ィ',
  65385 => 'ゥ',
  65386 => 'ェ',
  65387 => 'ォ',
  65388 => 'ャ',
  65389 => 'ュ',
  65390 => 'ョ',
  65391 => 'ッ',
  65392 => 'ー',
  65393 => 'ア',
  65394 => 'イ',
  65395 => 'ウ',
  65396 => 'エ',
  65397 => 'オ',
  65398 => 'カ',
  65399 => 'キ',
  65400 => 'ク',
  65401 => 'ケ',
  65402 => 'コ',
  65403 => 'サ',
  65404 => 'シ',
  65405 => 'ス',
  65406 => 'セ',
  65407 => 'ソ',
  65408 => 'タ',
  65409 => 'チ',
  65410 => 'ツ',
  65411 => 'テ',
  65412 => 'ト',
  65413 => 'ナ',
  65414 => 'ニ',
  65415 => 'ヌ',
  65416 => 'ネ',
  65417 => 'ノ',
  65418 => 'ハ',
  65419 => 'ヒ',
  65420 => 'フ',
  65421 => 'ヘ',
  65422 => 'ホ',
  65423 => 'マ',
  65424 => 'ミ',
  65425 => 'ム',
  65426 => 'メ',
  65427 => 'モ',
  65428 => 'ヤ',
  65429 => 'ユ',
  65430 => 'ヨ',
  65431 => 'ラ',
  65432 => 'リ',
  65433 => 'ル',
  65434 => 'レ',
  65435 => 'ロ',
  65436 => 'ワ',
  65437 => 'ン',
  65438 => '゙',
  65439 => '゚',
  65441 => 'ᄀ',
  65442 => 'ᄁ',
  65443 => 'ᆪ',
  65444 => 'ᄂ',
  65445 => 'ᆬ',
  65446 => 'ᆭ',
  65447 => 'ᄃ',
  65448 => 'ᄄ',
  65449 => 'ᄅ',
  65450 => 'ᆰ',
  65451 => 'ᆱ',
  65452 => 'ᆲ',
  65453 => 'ᆳ',
  65454 => 'ᆴ',
  65455 => 'ᆵ',
  65456 => 'ᄚ',
  65457 => 'ᄆ',
  65458 => 'ᄇ',
  65459 => 'ᄈ',
  65460 => 'ᄡ',
  65461 => 'ᄉ',
  65462 => 'ᄊ',
  65463 => 'ᄋ',
  65464 => 'ᄌ',
  65465 => 'ᄍ',
  65466 => 'ᄎ',
  65467 => 'ᄏ',
  65468 => 'ᄐ',
  65469 => 'ᄑ',
  65470 => 'ᄒ',
  65474 => 'ᅡ',
  65475 => 'ᅢ',
  65476 => 'ᅣ',
  65477 => 'ᅤ',
  65478 => 'ᅥ',
  65479 => 'ᅦ',
  65482 => 'ᅧ',
  65483 => 'ᅨ',
  65484 => 'ᅩ',
  65485 => 'ᅪ',
  65486 => 'ᅫ',
  65487 => 'ᅬ',
  65490 => 'ᅭ',
  65491 => 'ᅮ',
  65492 => 'ᅯ',
  65493 => 'ᅰ',
  65494 => 'ᅱ',
  65495 => 'ᅲ',
  65498 => 'ᅳ',
  65499 => 'ᅴ',
  65500 => 'ᅵ',
  65504 => '¢',
  65505 => '£',
  65506 => '¬',
  65508 => '¦',
  65509 => '¥',
  65510 => '₩',
  65512 => '│',
  65513 => '←',
  65514 => '↑',
  65515 => '→',
  65516 => '↓',
  65517 => '■',
  65518 => '○',
  66560 => '𐐨',
  66561 => '𐐩',
  66562 => '𐐪',
  66563 => '𐐫',
  66564 => '𐐬',
  66565 => '𐐭',
  66566 => '𐐮',
  66567 => '𐐯',
  66568 => '𐐰',
  66569 => '𐐱',
  66570 => '𐐲',
  66571 => '𐐳',
  66572 => '𐐴',
  66573 => '𐐵',
  66574 => '𐐶',
  66575 => '𐐷',
  66576 => '𐐸',
  66577 => '𐐹',
  66578 => '𐐺',
  66579 => '𐐻',
  66580 => '𐐼',
  66581 => '𐐽',
  66582 => '𐐾',
  66583 => '𐐿',
  66584 => '𐑀',
  66585 => '𐑁',
  66586 => '𐑂',
  66587 => '𐑃',
  66588 => '𐑄',
  66589 => '𐑅',
  66590 => '𐑆',
  66591 => '𐑇',
  66592 => '𐑈',
  66593 => '𐑉',
  66594 => '𐑊',
  66595 => '𐑋',
  66596 => '𐑌',
  66597 => '𐑍',
  66598 => '𐑎',
  66599 => '𐑏',
  66736 => '𐓘',
  66737 => '𐓙',
  66738 => '𐓚',
  66739 => '𐓛',
  66740 => '𐓜',
  66741 => '𐓝',
  66742 => '𐓞',
  66743 => '𐓟',
  66744 => '𐓠',
  66745 => '𐓡',
  66746 => '𐓢',
  66747 => '𐓣',
  66748 => '𐓤',
  66749 => '𐓥',
  66750 => '𐓦',
  66751 => '𐓧',
  66752 => '𐓨',
  66753 => '𐓩',
  66754 => '𐓪',
  66755 => '𐓫',
  66756 => '𐓬',
  66757 => '𐓭',
  66758 => '𐓮',
  66759 => '𐓯',
  66760 => '𐓰',
  66761 => '𐓱',
  66762 => '𐓲',
  66763 => '𐓳',
  66764 => '𐓴',
  66765 => '𐓵',
  66766 => '𐓶',
  66767 => '𐓷',
  66768 => '𐓸',
  66769 => '𐓹',
  66770 => '𐓺',
  66771 => '𐓻',
  68736 => '𐳀',
  68737 => '𐳁',
  68738 => '𐳂',
  68739 => '𐳃',
  68740 => '𐳄',
  68741 => '𐳅',
  68742 => '𐳆',
  68743 => '𐳇',
  68744 => '𐳈',
  68745 => '𐳉',
  68746 => '𐳊',
  68747 => '𐳋',
  68748 => '𐳌',
  68749 => '𐳍',
  68750 => '𐳎',
  68751 => '𐳏',
  68752 => '𐳐',
  68753 => '𐳑',
  68754 => '𐳒',
  68755 => '𐳓',
  68756 => '𐳔',
  68757 => '𐳕',
  68758 => '𐳖',
  68759 => '𐳗',
  68760 => '𐳘',
  68761 => '𐳙',
  68762 => '𐳚',
  68763 => '𐳛',
  68764 => '𐳜',
  68765 => '𐳝',
  68766 => '𐳞',
  68767 => '𐳟',
  68768 => '𐳠',
  68769 => '𐳡',
  68770 => '𐳢',
  68771 => '𐳣',
  68772 => '𐳤',
  68773 => '𐳥',
  68774 => '𐳦',
  68775 => '𐳧',
  68776 => '𐳨',
  68777 => '𐳩',
  68778 => '𐳪',
  68779 => '𐳫',
  68780 => '𐳬',
  68781 => '𐳭',
  68782 => '𐳮',
  68783 => '𐳯',
  68784 => '𐳰',
  68785 => '𐳱',
  68786 => '𐳲',
  71840 => '𑣀',
  71841 => '𑣁',
  71842 => '𑣂',
  71843 => '𑣃',
  71844 => '𑣄',
  71845 => '𑣅',
  71846 => '𑣆',
  71847 => '𑣇',
  71848 => '𑣈',
  71849 => '𑣉',
  71850 => '𑣊',
  71851 => '𑣋',
  71852 => '𑣌',
  71853 => '𑣍',
  71854 => '𑣎',
  71855 => '𑣏',
  71856 => '𑣐',
  71857 => '𑣑',
  71858 => '𑣒',
  71859 => '𑣓',
  71860 => '𑣔',
  71861 => '𑣕',
  71862 => '𑣖',
  71863 => '𑣗',
  71864 => '𑣘',
  71865 => '𑣙',
  71866 => '𑣚',
  71867 => '𑣛',
  71868 => '𑣜',
  71869 => '𑣝',
  71870 => '𑣞',
  71871 => '𑣟',
  93760 => '𖹠',
  93761 => '𖹡',
  93762 => '𖹢',
  93763 => '𖹣',
  93764 => '𖹤',
  93765 => '𖹥',
  93766 => '𖹦',
  93767 => '𖹧',
  93768 => '𖹨',
  93769 => '𖹩',
  93770 => '𖹪',
  93771 => '𖹫',
  93772 => '𖹬',
  93773 => '𖹭',
  93774 => '𖹮',
  93775 => '𖹯',
  93776 => '𖹰',
  93777 => '𖹱',
  93778 => '𖹲',
  93779 => '𖹳',
  93780 => '𖹴',
  93781 => '𖹵',
  93782 => '𖹶',
  93783 => '𖹷',
  93784 => '𖹸',
  93785 => '𖹹',
  93786 => '𖹺',
  93787 => '𖹻',
  93788 => '𖹼',
  93789 => '𖹽',
  93790 => '𖹾',
  93791 => '𖹿',
  119134 => '𝅗𝅥',
  119135 => '𝅘𝅥',
  119136 => '𝅘𝅥𝅮',
  119137 => '𝅘𝅥𝅯',
  119138 => '𝅘𝅥𝅰',
  119139 => '𝅘𝅥𝅱',
  119140 => '𝅘𝅥𝅲',
  119227 => '𝆹𝅥',
  119228 => '𝆺𝅥',
  119229 => '𝆹𝅥𝅮',
  119230 => '𝆺𝅥𝅮',
  119231 => '𝆹𝅥𝅯',
  119232 => '𝆺𝅥𝅯',
  119808 => 'a',
  119809 => 'b',
  119810 => 'c',
  119811 => 'd',
  119812 => 'e',
  119813 => 'f',
  119814 => 'g',
  119815 => 'h',
  119816 => 'i',
  119817 => 'j',
  119818 => 'k',
  119819 => 'l',
  119820 => 'm',
  119821 => 'n',
  119822 => 'o',
  119823 => 'p',
  119824 => 'q',
  119825 => 'r',
  119826 => 's',
  119827 => 't',
  119828 => 'u',
  119829 => 'v',
  119830 => 'w',
  119831 => 'x',
  119832 => 'y',
  119833 => 'z',
  119834 => 'a',
  119835 => 'b',
  119836 => 'c',
  119837 => 'd',
  119838 => 'e',
  119839 => 'f',
  119840 => 'g',
  119841 => 'h',
  119842 => 'i',
  119843 => 'j',
  119844 => 'k',
  119845 => 'l',
  119846 => 'm',
  119847 => 'n',
  119848 => 'o',
  119849 => 'p',
  119850 => 'q',
  119851 => 'r',
  119852 => 's',
  119853 => 't',
  119854 => 'u',
  119855 => 'v',
  119856 => 'w',
  119857 => 'x',
  119858 => 'y',
  119859 => 'z',
  119860 => 'a',
  119861 => 'b',
  119862 => 'c',
  119863 => 'd',
  119864 => 'e',
  119865 => 'f',
  119866 => 'g',
  119867 => 'h',
  119868 => 'i',
  119869 => 'j',
  119870 => 'k',
  119871 => 'l',
  119872 => 'm',
  119873 => 'n',
  119874 => 'o',
  119875 => 'p',
  119876 => 'q',
  119877 => 'r',
  119878 => 's',
  119879 => 't',
  119880 => 'u',
  119881 => 'v',
  119882 => 'w',
  119883 => 'x',
  119884 => 'y',
  119885 => 'z',
  119886 => 'a',
  119887 => 'b',
  119888 => 'c',
  119889 => 'd',
  119890 => 'e',
  119891 => 'f',
  119892 => 'g',
  119894 => 'i',
  119895 => 'j',
  119896 => 'k',
  119897 => 'l',
  119898 => 'm',
  119899 => 'n',
  119900 => 'o',
  119901 => 'p',
  119902 => 'q',
  119903 => 'r',
  119904 => 's',
  119905 => 't',
  119906 => 'u',
  119907 => 'v',
  119908 => 'w',
  119909 => 'x',
  119910 => 'y',
  119911 => 'z',
  119912 => 'a',
  119913 => 'b',
  119914 => 'c',
  119915 => 'd',
  119916 => 'e',
  119917 => 'f',
  119918 => 'g',
  119919 => 'h',
  119920 => 'i',
  119921 => 'j',
  119922 => 'k',
  119923 => 'l',
  119924 => 'm',
  119925 => 'n',
  119926 => 'o',
  119927 => 'p',
  119928 => 'q',
  119929 => 'r',
  119930 => 's',
  119931 => 't',
  119932 => 'u',
  119933 => 'v',
  119934 => 'w',
  119935 => 'x',
  119936 => 'y',
  119937 => 'z',
  119938 => 'a',
  119939 => 'b',
  119940 => 'c',
  119941 => 'd',
  119942 => 'e',
  119943 => 'f',
  119944 => 'g',
  119945 => 'h',
  119946 => 'i',
  119947 => 'j',
  119948 => 'k',
  119949 => 'l',
  119950 => 'm',
  119951 => 'n',
  119952 => 'o',
  119953 => 'p',
  119954 => 'q',
  119955 => 'r',
  119956 => 's',
  119957 => 't',
  119958 => 'u',
  119959 => 'v',
  119960 => 'w',
  119961 => 'x',
  119962 => 'y',
  119963 => 'z',
  119964 => 'a',
  119966 => 'c',
  119967 => 'd',
  119970 => 'g',
  119973 => 'j',
  119974 => 'k',
  119977 => 'n',
  119978 => 'o',
  119979 => 'p',
  119980 => 'q',
  119982 => 's',
  119983 => 't',
  119984 => 'u',
  119985 => 'v',
  119986 => 'w',
  119987 => 'x',
  119988 => 'y',
  119989 => 'z',
  119990 => 'a',
  119991 => 'b',
  119992 => 'c',
  119993 => 'd',
  119995 => 'f',
  119997 => 'h',
  119998 => 'i',
  119999 => 'j',
  120000 => 'k',
  120001 => 'l',
  120002 => 'm',
  120003 => 'n',
  120005 => 'p',
  120006 => 'q',
  120007 => 'r',
  120008 => 's',
  120009 => 't',
  120010 => 'u',
  120011 => 'v',
  120012 => 'w',
  120013 => 'x',
  120014 => 'y',
  120015 => 'z',
  120016 => 'a',
  120017 => 'b',
  120018 => 'c',
  120019 => 'd',
  120020 => 'e',
  120021 => 'f',
  120022 => 'g',
  120023 => 'h',
  120024 => 'i',
  120025 => 'j',
  120026 => 'k',
  120027 => 'l',
  120028 => 'm',
  120029 => 'n',
  120030 => 'o',
  120031 => 'p',
  120032 => 'q',
  120033 => 'r',
  120034 => 's',
  120035 => 't',
  120036 => 'u',
  120037 => 'v',
  120038 => 'w',
  120039 => 'x',
  120040 => 'y',
  120041 => 'z',
  120042 => 'a',
  120043 => 'b',
  120044 => 'c',
  120045 => 'd',
  120046 => 'e',
  120047 => 'f',
  120048 => 'g',
  120049 => 'h',
  120050 => 'i',
  120051 => 'j',
  120052 => 'k',
  120053 => 'l',
  120054 => 'm',
  120055 => 'n',
  120056 => 'o',
  120057 => 'p',
  120058 => 'q',
  120059 => 'r',
  120060 => 's',
  120061 => 't',
  120062 => 'u',
  120063 => 'v',
  120064 => 'w',
  120065 => 'x',
  120066 => 'y',
  120067 => 'z',
  120068 => 'a',
  120069 => 'b',
  120071 => 'd',
  120072 => 'e',
  120073 => 'f',
  120074 => 'g',
  120077 => 'j',
  120078 => 'k',
  120079 => 'l',
  120080 => 'm',
  120081 => 'n',
  120082 => 'o',
  120083 => 'p',
  120084 => 'q',
  120086 => 's',
  120087 => 't',
  120088 => 'u',
  120089 => 'v',
  120090 => 'w',
  120091 => 'x',
  120092 => 'y',
  120094 => 'a',
  120095 => 'b',
  120096 => 'c',
  120097 => 'd',
  120098 => 'e',
  120099 => 'f',
  120100 => 'g',
  120101 => 'h',
  120102 => 'i',
  120103 => 'j',
  120104 => 'k',
  120105 => 'l',
  120106 => 'm',
  120107 => 'n',
  120108 => 'o',
  120109 => 'p',
  120110 => 'q',
  120111 => 'r',
  120112 => 's',
  120113 => 't',
  120114 => 'u',
  120115 => 'v',
  120116 => 'w',
  120117 => 'x',
  120118 => 'y',
  120119 => 'z',
  120120 => 'a',
  120121 => 'b',
  120123 => 'd',
  120124 => 'e',
  120125 => 'f',
  120126 => 'g',
  120128 => 'i',
  120129 => 'j',
  120130 => 'k',
  120131 => 'l',
  120132 => 'm',
  120134 => 'o',
  120138 => 's',
  120139 => 't',
  120140 => 'u',
  120141 => 'v',
  120142 => 'w',
  120143 => 'x',
  120144 => 'y',
  120146 => 'a',
  120147 => 'b',
  120148 => 'c',
  120149 => 'd',
  120150 => 'e',
  120151 => 'f',
  120152 => 'g',
  120153 => 'h',
  120154 => 'i',
  120155 => 'j',
  120156 => 'k',
  120157 => 'l',
  120158 => 'm',
  120159 => 'n',
  120160 => 'o',
  120161 => 'p',
  120162 => 'q',
  120163 => 'r',
  120164 => 's',
  120165 => 't',
  120166 => 'u',
  120167 => 'v',
  120168 => 'w',
  120169 => 'x',
  120170 => 'y',
  120171 => 'z',
  120172 => 'a',
  120173 => 'b',
  120174 => 'c',
  120175 => 'd',
  120176 => 'e',
  120177 => 'f',
  120178 => 'g',
  120179 => 'h',
  120180 => 'i',
  120181 => 'j',
  120182 => 'k',
  120183 => 'l',
  120184 => 'm',
  120185 => 'n',
  120186 => 'o',
  120187 => 'p',
  120188 => 'q',
  120189 => 'r',
  120190 => 's',
  120191 => 't',
  120192 => 'u',
  120193 => 'v',
  120194 => 'w',
  120195 => 'x',
  120196 => 'y',
  120197 => 'z',
  120198 => 'a',
  120199 => 'b',
  120200 => 'c',
  120201 => 'd',
  120202 => 'e',
  120203 => 'f',
  120204 => 'g',
  120205 => 'h',
  120206 => 'i',
  120207 => 'j',
  120208 => 'k',
  120209 => 'l',
  120210 => 'm',
  120211 => 'n',
  120212 => 'o',
  120213 => 'p',
  120214 => 'q',
  120215 => 'r',
  120216 => 's',
  120217 => 't',
  120218 => 'u',
  120219 => 'v',
  120220 => 'w',
  120221 => 'x',
  120222 => 'y',
  120223 => 'z',
  120224 => 'a',
  120225 => 'b',
  120226 => 'c',
  120227 => 'd',
  120228 => 'e',
  120229 => 'f',
  120230 => 'g',
  120231 => 'h',
  120232 => 'i',
  120233 => 'j',
  120234 => 'k',
  120235 => 'l',
  120236 => 'm',
  120237 => 'n',
  120238 => 'o',
  120239 => 'p',
  120240 => 'q',
  120241 => 'r',
  120242 => 's',
  120243 => 't',
  120244 => 'u',
  120245 => 'v',
  120246 => 'w',
  120247 => 'x',
  120248 => 'y',
  120249 => 'z',
  120250 => 'a',
  120251 => 'b',
  120252 => 'c',
  120253 => 'd',
  120254 => 'e',
  120255 => 'f',
  120256 => 'g',
  120257 => 'h',
  120258 => 'i',
  120259 => 'j',
  120260 => 'k',
  120261 => 'l',
  120262 => 'm',
  120263 => 'n',
  120264 => 'o',
  120265 => 'p',
  120266 => 'q',
  120267 => 'r',
  120268 => 's',
  120269 => 't',
  120270 => 'u',
  120271 => 'v',
  120272 => 'w',
  120273 => 'x',
  120274 => 'y',
  120275 => 'z',
  120276 => 'a',
  120277 => 'b',
  120278 => 'c',
  120279 => 'd',
  120280 => 'e',
  120281 => 'f',
  120282 => 'g',
  120283 => 'h',
  120284 => 'i',
  120285 => 'j',
  120286 => 'k',
  120287 => 'l',
  120288 => 'm',
  120289 => 'n',
  120290 => 'o',
  120291 => 'p',
  120292 => 'q',
  120293 => 'r',
  120294 => 's',
  120295 => 't',
  120296 => 'u',
  120297 => 'v',
  120298 => 'w',
  120299 => 'x',
  120300 => 'y',
  120301 => 'z',
  120302 => 'a',
  120303 => 'b',
  120304 => 'c',
  120305 => 'd',
  120306 => 'e',
  120307 => 'f',
  120308 => 'g',
  120309 => 'h',
  120310 => 'i',
  120311 => 'j',
  120312 => 'k',
  120313 => 'l',
  120314 => 'm',
  120315 => 'n',
  120316 => 'o',
  120317 => 'p',
  120318 => 'q',
  120319 => 'r',
  120320 => 's',
  120321 => 't',
  120322 => 'u',
  120323 => 'v',
  120324 => 'w',
  120325 => 'x',
  120326 => 'y',
  120327 => 'z',
  120328 => 'a',
  120329 => 'b',
  120330 => 'c',
  120331 => 'd',
  120332 => 'e',
  120333 => 'f',
  120334 => 'g',
  120335 => 'h',
  120336 => 'i',
  120337 => 'j',
  120338 => 'k',
  120339 => 'l',
  120340 => 'm',
  120341 => 'n',
  120342 => 'o',
  120343 => 'p',
  120344 => 'q',
  120345 => 'r',
  120346 => 's',
  120347 => 't',
  120348 => 'u',
  120349 => 'v',
  120350 => 'w',
  120351 => 'x',
  120352 => 'y',
  120353 => 'z',
  120354 => 'a',
  120355 => 'b',
  120356 => 'c',
  120357 => 'd',
  120358 => 'e',
  120359 => 'f',
  120360 => 'g',
  120361 => 'h',
  120362 => 'i',
  120363 => 'j',
  120364 => 'k',
  120365 => 'l',
  120366 => 'm',
  120367 => 'n',
  120368 => 'o',
  120369 => 'p',
  120370 => 'q',
  120371 => 'r',
  120372 => 's',
  120373 => 't',
  120374 => 'u',
  120375 => 'v',
  120376 => 'w',
  120377 => 'x',
  120378 => 'y',
  120379 => 'z',
  120380 => 'a',
  120381 => 'b',
  120382 => 'c',
  120383 => 'd',
  120384 => 'e',
  120385 => 'f',
  120386 => 'g',
  120387 => 'h',
  120388 => 'i',
  120389 => 'j',
  120390 => 'k',
  120391 => 'l',
  120392 => 'm',
  120393 => 'n',
  120394 => 'o',
  120395 => 'p',
  120396 => 'q',
  120397 => 'r',
  120398 => 's',
  120399 => 't',
  120400 => 'u',
  120401 => 'v',
  120402 => 'w',
  120403 => 'x',
  120404 => 'y',
  120405 => 'z',
  120406 => 'a',
  120407 => 'b',
  120408 => 'c',
  120409 => 'd',
  120410 => 'e',
  120411 => 'f',
  120412 => 'g',
  120413 => 'h',
  120414 => 'i',
  120415 => 'j',
  120416 => 'k',
  120417 => 'l',
  120418 => 'm',
  120419 => 'n',
  120420 => 'o',
  120421 => 'p',
  120422 => 'q',
  120423 => 'r',
  120424 => 's',
  120425 => 't',
  120426 => 'u',
  120427 => 'v',
  120428 => 'w',
  120429 => 'x',
  120430 => 'y',
  120431 => 'z',
  120432 => 'a',
  120433 => 'b',
  120434 => 'c',
  120435 => 'd',
  120436 => 'e',
  120437 => 'f',
  120438 => 'g',
  120439 => 'h',
  120440 => 'i',
  120441 => 'j',
  120442 => 'k',
  120443 => 'l',
  120444 => 'm',
  120445 => 'n',
  120446 => 'o',
  120447 => 'p',
  120448 => 'q',
  120449 => 'r',
  120450 => 's',
  120451 => 't',
  120452 => 'u',
  120453 => 'v',
  120454 => 'w',
  120455 => 'x',
  120456 => 'y',
  120457 => 'z',
  120458 => 'a',
  120459 => 'b',
  120460 => 'c',
  120461 => 'd',
  120462 => 'e',
  120463 => 'f',
  120464 => 'g',
  120465 => 'h',
  120466 => 'i',
  120467 => 'j',
  120468 => 'k',
  120469 => 'l',
  120470 => 'm',
  120471 => 'n',
  120472 => 'o',
  120473 => 'p',
  120474 => 'q',
  120475 => 'r',
  120476 => 's',
  120477 => 't',
  120478 => 'u',
  120479 => 'v',
  120480 => 'w',
  120481 => 'x',
  120482 => 'y',
  120483 => 'z',
  120484 => 'ı',
  120485 => 'ȷ',
  120488 => 'α',
  120489 => 'β',
  120490 => 'γ',
  120491 => 'δ',
  120492 => 'ε',
  120493 => 'ζ',
  120494 => 'η',
  120495 => 'θ',
  120496 => 'ι',
  120497 => 'κ',
  120498 => 'λ',
  120499 => 'μ',
  120500 => 'ν',
  120501 => 'ξ',
  120502 => 'ο',
  120503 => 'π',
  120504 => 'ρ',
  120505 => 'θ',
  120506 => 'σ',
  120507 => 'τ',
  120508 => 'υ',
  120509 => 'φ',
  120510 => 'χ',
  120511 => 'ψ',
  120512 => 'ω',
  120513 => '∇',
  120514 => 'α',
  120515 => 'β',
  120516 => 'γ',
  120517 => 'δ',
  120518 => 'ε',
  120519 => 'ζ',
  120520 => 'η',
  120521 => 'θ',
  120522 => 'ι',
  120523 => 'κ',
  120524 => 'λ',
  120525 => 'μ',
  120526 => 'ν',
  120527 => 'ξ',
  120528 => 'ο',
  120529 => 'π',
  120530 => 'ρ',
  120531 => 'σ',
  120532 => 'σ',
  120533 => 'τ',
  120534 => 'υ',
  120535 => 'φ',
  120536 => 'χ',
  120537 => 'ψ',
  120538 => 'ω',
  120539 => '∂',
  120540 => 'ε',
  120541 => 'θ',
  120542 => 'κ',
  120543 => 'φ',
  120544 => 'ρ',
  120545 => 'π',
  120546 => 'α',
  120547 => 'β',
  120548 => 'γ',
  120549 => 'δ',
  120550 => 'ε',
  120551 => 'ζ',
  120552 => 'η',
  120553 => 'θ',
  120554 => 'ι',
  120555 => 'κ',
  120556 => 'λ',
  120557 => 'μ',
  120558 => 'ν',
  120559 => 'ξ',
  120560 => 'ο',
  120561 => 'π',
  120562 => 'ρ',
  120563 => 'θ',
  120564 => 'σ',
  120565 => 'τ',
  120566 => 'υ',
  120567 => 'φ',
  120568 => 'χ',
  120569 => 'ψ',
  120570 => 'ω',
  120571 => '∇',
  120572 => 'α',
  120573 => 'β',
  120574 => 'γ',
  120575 => 'δ',
  120576 => 'ε',
  120577 => 'ζ',
  120578 => 'η',
  120579 => 'θ',
  120580 => 'ι',
  120581 => 'κ',
  120582 => 'λ',
  120583 => 'μ',
  120584 => 'ν',
  120585 => 'ξ',
  120586 => 'ο',
  120587 => 'π',
  120588 => 'ρ',
  120589 => 'σ',
  120590 => 'σ',
  120591 => 'τ',
  120592 => 'υ',
  120593 => 'φ',
  120594 => 'χ',
  120595 => 'ψ',
  120596 => 'ω',
  120597 => '∂',
  120598 => 'ε',
  120599 => 'θ',
  120600 => 'κ',
  120601 => 'φ',
  120602 => 'ρ',
  120603 => 'π',
  120604 => 'α',
  120605 => 'β',
  120606 => 'γ',
  120607 => 'δ',
  120608 => 'ε',
  120609 => 'ζ',
  120610 => 'η',
  120611 => 'θ',
  120612 => 'ι',
  120613 => 'κ',
  120614 => 'λ',
  120615 => 'μ',
  120616 => 'ν',
  120617 => 'ξ',
  120618 => 'ο',
  120619 => 'π',
  120620 => 'ρ',
  120621 => 'θ',
  120622 => 'σ',
  120623 => 'τ',
  120624 => 'υ',
  120625 => 'φ',
  120626 => 'χ',
  120627 => 'ψ',
  120628 => 'ω',
  120629 => '∇',
  120630 => 'α',
  120631 => 'β',
  120632 => 'γ',
  120633 => 'δ',
  120634 => 'ε',
  120635 => 'ζ',
  120636 => 'η',
  120637 => 'θ',
  120638 => 'ι',
  120639 => 'κ',
  120640 => 'λ',
  120641 => 'μ',
  120642 => 'ν',
  120643 => 'ξ',
  120644 => 'ο',
  120645 => 'π',
  120646 => 'ρ',
  120647 => 'σ',
  120648 => 'σ',
  120649 => 'τ',
  120650 => 'υ',
  120651 => 'φ',
  120652 => 'χ',
  120653 => 'ψ',
  120654 => 'ω',
  120655 => '∂',
  120656 => 'ε',
  120657 => 'θ',
  120658 => 'κ',
  120659 => 'φ',
  120660 => 'ρ',
  120661 => 'π',
  120662 => 'α',
  120663 => 'β',
  120664 => 'γ',
  120665 => 'δ',
  120666 => 'ε',
  120667 => 'ζ',
  120668 => 'η',
  120669 => 'θ',
  120670 => 'ι',
  120671 => 'κ',
  120672 => 'λ',
  120673 => 'μ',
  120674 => 'ν',
  120675 => 'ξ',
  120676 => 'ο',
  120677 => 'π',
  120678 => 'ρ',
  120679 => 'θ',
  120680 => 'σ',
  120681 => 'τ',
  120682 => 'υ',
  120683 => 'φ',
  120684 => 'χ',
  120685 => 'ψ',
  120686 => 'ω',
  120687 => '∇',
  120688 => 'α',
  120689 => 'β',
  120690 => 'γ',
  120691 => 'δ',
  120692 => 'ε',
  120693 => 'ζ',
  120694 => 'η',
  120695 => 'θ',
  120696 => 'ι',
  120697 => 'κ',
  120698 => 'λ',
  120699 => 'μ',
  120700 => 'ν',
  120701 => 'ξ',
  120702 => 'ο',
  120703 => 'π',
  120704 => 'ρ',
  120705 => 'σ',
  120706 => 'σ',
  120707 => 'τ',
  120708 => 'υ',
  120709 => 'φ',
  120710 => 'χ',
  120711 => 'ψ',
  120712 => 'ω',
  120713 => '∂',
  120714 => 'ε',
  120715 => 'θ',
  120716 => 'κ',
  120717 => 'φ',
  120718 => 'ρ',
  120719 => 'π',
  120720 => 'α',
  120721 => 'β',
  120722 => 'γ',
  120723 => 'δ',
  120724 => 'ε',
  120725 => 'ζ',
  120726 => 'η',
  120727 => 'θ',
  120728 => 'ι',
  120729 => 'κ',
  120730 => 'λ',
  120731 => 'μ',
  120732 => 'ν',
  120733 => 'ξ',
  120734 => 'ο',
  120735 => 'π',
  120736 => 'ρ',
  120737 => 'θ',
  120738 => 'σ',
  120739 => 'τ',
  120740 => 'υ',
  120741 => 'φ',
  120742 => 'χ',
  120743 => 'ψ',
  120744 => 'ω',
  120745 => '∇',
  120746 => 'α',
  120747 => 'β',
  120748 => 'γ',
  120749 => 'δ',
  120750 => 'ε',
  120751 => 'ζ',
  120752 => 'η',
  120753 => 'θ',
  120754 => 'ι',
  120755 => 'κ',
  120756 => 'λ',
  120757 => 'μ',
  120758 => 'ν',
  120759 => 'ξ',
  120760 => 'ο',
  120761 => 'π',
  120762 => 'ρ',
  120763 => 'σ',
  120764 => 'σ',
  120765 => 'τ',
  120766 => 'υ',
  120767 => 'φ',
  120768 => 'χ',
  120769 => 'ψ',
  120770 => 'ω',
  120771 => '∂',
  120772 => 'ε',
  120773 => 'θ',
  120774 => 'κ',
  120775 => 'φ',
  120776 => 'ρ',
  120777 => 'π',
  120778 => 'ϝ',
  120779 => 'ϝ',
  120782 => '0',
  120783 => '1',
  120784 => '2',
  120785 => '3',
  120786 => '4',
  120787 => '5',
  120788 => '6',
  120789 => '7',
  120790 => '8',
  120791 => '9',
  120792 => '0',
  120793 => '1',
  120794 => '2',
  120795 => '3',
  120796 => '4',
  120797 => '5',
  120798 => '6',
  120799 => '7',
  120800 => '8',
  120801 => '9',
  120802 => '0',
  120803 => '1',
  120804 => '2',
  120805 => '3',
  120806 => '4',
  120807 => '5',
  120808 => '6',
  120809 => '7',
  120810 => '8',
  120811 => '9',
  120812 => '0',
  120813 => '1',
  120814 => '2',
  120815 => '3',
  120816 => '4',
  120817 => '5',
  120818 => '6',
  120819 => '7',
  120820 => '8',
  120821 => '9',
  120822 => '0',
  120823 => '1',
  120824 => '2',
  120825 => '3',
  120826 => '4',
  120827 => '5',
  120828 => '6',
  120829 => '7',
  120830 => '8',
  120831 => '9',
  125184 => '𞤢',
  125185 => '𞤣',
  125186 => '𞤤',
  125187 => '𞤥',
  125188 => '𞤦',
  125189 => '𞤧',
  125190 => '𞤨',
  125191 => '𞤩',
  125192 => '𞤪',
  125193 => '𞤫',
  125194 => '𞤬',
  125195 => '𞤭',
  125196 => '𞤮',
  125197 => '𞤯',
  125198 => '𞤰',
  125199 => '𞤱',
  125200 => '𞤲',
  125201 => '𞤳',
  125202 => '𞤴',
  125203 => '𞤵',
  125204 => '𞤶',
  125205 => '𞤷',
  125206 => '𞤸',
  125207 => '𞤹',
  125208 => '𞤺',
  125209 => '𞤻',
  125210 => '𞤼',
  125211 => '𞤽',
  125212 => '𞤾',
  125213 => '𞤿',
  125214 => '𞥀',
  125215 => '𞥁',
  125216 => '𞥂',
  125217 => '𞥃',
  126464 => 'ا',
  126465 => 'ب',
  126466 => 'ج',
  126467 => 'د',
  126469 => 'و',
  126470 => 'ز',
  126471 => 'ح',
  126472 => 'ط',
  126473 => 'ي',
  126474 => 'ك',
  126475 => 'ل',
  126476 => 'م',
  126477 => 'ن',
  126478 => 'س',
  126479 => 'ع',
  126480 => 'ف',
  126481 => 'ص',
  126482 => 'ق',
  126483 => 'ر',
  126484 => 'ش',
  126485 => 'ت',
  126486 => 'ث',
  126487 => 'خ',
  126488 => 'ذ',
  126489 => 'ض',
  126490 => 'ظ',
  126491 => 'غ',
  126492 => 'ٮ',
  126493 => 'ں',
  126494 => 'ڡ',
  126495 => 'ٯ',
  126497 => 'ب',
  126498 => 'ج',
  126500 => 'ه',
  126503 => 'ح',
  126505 => 'ي',
  126506 => 'ك',
  126507 => 'ل',
  126508 => 'م',
  126509 => 'ن',
  126510 => 'س',
  126511 => 'ع',
  126512 => 'ف',
  126513 => 'ص',
  126514 => 'ق',
  126516 => 'ش',
  126517 => 'ت',
  126518 => 'ث',
  126519 => 'خ',
  126521 => 'ض',
  126523 => 'غ',
  126530 => 'ج',
  126535 => 'ح',
  126537 => 'ي',
  126539 => 'ل',
  126541 => 'ن',
  126542 => 'س',
  126543 => 'ع',
  126545 => 'ص',
  126546 => 'ق',
  126548 => 'ش',
  126551 => 'خ',
  126553 => 'ض',
  126555 => 'غ',
  126557 => 'ں',
  126559 => 'ٯ',
  126561 => 'ب',
  126562 => 'ج',
  126564 => 'ه',
  126567 => 'ح',
  126568 => 'ط',
  126569 => 'ي',
  126570 => 'ك',
  126572 => 'م',
  126573 => 'ن',
  126574 => 'س',
  126575 => 'ع',
  126576 => 'ف',
  126577 => 'ص',
  126578 => 'ق',
  126580 => 'ش',
  126581 => 'ت',
  126582 => 'ث',
  126583 => 'خ',
  126585 => 'ض',
  126586 => 'ظ',
  126587 => 'غ',
  126588 => 'ٮ',
  126590 => 'ڡ',
  126592 => 'ا',
  126593 => 'ب',
  126594 => 'ج',
  126595 => 'د',
  126596 => 'ه',
  126597 => 'و',
  126598 => 'ز',
  126599 => 'ح',
  126600 => 'ط',
  126601 => 'ي',
  126603 => 'ل',
  126604 => 'م',
  126605 => 'ن',
  126606 => 'س',
  126607 => 'ع',
  126608 => 'ف',
  126609 => 'ص',
  126610 => 'ق',
  126611 => 'ر',
  126612 => 'ش',
  126613 => 'ت',
  126614 => 'ث',
  126615 => 'خ',
  126616 => 'ذ',
  126617 => 'ض',
  126618 => 'ظ',
  126619 => 'غ',
  126625 => 'ب',
  126626 => 'ج',
  126627 => 'د',
  126629 => 'و',
  126630 => 'ز',
  126631 => 'ح',
  126632 => 'ط',
  126633 => 'ي',
  126635 => 'ل',
  126636 => 'م',
  126637 => 'ن',
  126638 => 'س',
  126639 => 'ع',
  126640 => 'ف',
  126641 => 'ص',
  126642 => 'ق',
  126643 => 'ر',
  126644 => 'ش',
  126645 => 'ت',
  126646 => 'ث',
  126647 => 'خ',
  126648 => 'ذ',
  126649 => 'ض',
  126650 => 'ظ',
  126651 => 'غ',
  127274 => '〔s〕',
  127275 => 'c',
  127276 => 'r',
  127277 => 'cd',
  127278 => 'wz',
  127280 => 'a',
  127281 => 'b',
  127282 => 'c',
  127283 => 'd',
  127284 => 'e',
  127285 => 'f',
  127286 => 'g',
  127287 => 'h',
  127288 => 'i',
  127289 => 'j',
  127290 => 'k',
  127291 => 'l',
  127292 => 'm',
  127293 => 'n',
  127294 => 'o',
  127295 => 'p',
  127296 => 'q',
  127297 => 'r',
  127298 => 's',
  127299 => 't',
  127300 => 'u',
  127301 => 'v',
  127302 => 'w',
  127303 => 'x',
  127304 => 'y',
  127305 => 'z',
  127306 => 'hv',
  127307 => 'mv',
  127308 => 'sd',
  127309 => 'ss',
  127310 => 'ppv',
  127311 => 'wc',
  127338 => 'mc',
  127339 => 'md',
  127340 => 'mr',
  127376 => 'dj',
  127488 => 'ほか',
  127489 => 'ココ',
  127490 => 'サ',
  127504 => '手',
  127505 => '字',
  127506 => '双',
  127507 => 'デ',
  127508 => '二',
  127509 => '多',
  127510 => '解',
  127511 => '天',
  127512 => '交',
  127513 => '映',
  127514 => '無',
  127515 => '料',
  127516 => '前',
  127517 => '後',
  127518 => '再',
  127519 => '新',
  127520 => '初',
  127521 => '終',
  127522 => '生',
  127523 => '販',
  127524 => '声',
  127525 => '吹',
  127526 => '演',
  127527 => '投',
  127528 => '捕',
  127529 => '一',
  127530 => '三',
  127531 => '遊',
  127532 => '左',
  127533 => '中',
  127534 => '右',
  127535 => '指',
  127536 => '走',
  127537 => '打',
  127538 => '禁',
  127539 => '空',
  127540 => '合',
  127541 => '満',
  127542 => '有',
  127543 => '月',
  127544 => '申',
  127545 => '割',
  127546 => '営',
  127547 => '配',
  127552 => '〔本〕',
  127553 => '〔三〕',
  127554 => '〔二〕',
  127555 => '〔安〕',
  127556 => '〔点〕',
  127557 => '〔打〕',
  127558 => '〔盗〕',
  127559 => '〔勝〕',
  127560 => '〔敗〕',
  127568 => '得',
  127569 => '可',
  130032 => '0',
  130033 => '1',
  130034 => '2',
  130035 => '3',
  130036 => '4',
  130037 => '5',
  130038 => '6',
  130039 => '7',
  130040 => '8',
  130041 => '9',
  194560 => '丽',
  194561 => '丸',
  194562 => '乁',
  194563 => '𠄢',
  194564 => '你',
  194565 => '侮',
  194566 => '侻',
  194567 => '倂',
  194568 => '偺',
  194569 => '備',
  194570 => '僧',
  194571 => '像',
  194572 => '㒞',
  194573 => '𠘺',
  194574 => '免',
  194575 => '兔',
  194576 => '兤',
  194577 => '具',
  194578 => '𠔜',
  194579 => '㒹',
  194580 => '內',
  194581 => '再',
  194582 => '𠕋',
  194583 => '冗',
  194584 => '冤',
  194585 => '仌',
  194586 => '冬',
  194587 => '况',
  194588 => '𩇟',
  194589 => '凵',
  194590 => '刃',
  194591 => '㓟',
  194592 => '刻',
  194593 => '剆',
  194594 => '割',
  194595 => '剷',
  194596 => '㔕',
  194597 => '勇',
  194598 => '勉',
  194599 => '勤',
  194600 => '勺',
  194601 => '包',
  194602 => '匆',
  194603 => '北',
  194604 => '卉',
  194605 => '卑',
  194606 => '博',
  194607 => '即',
  194608 => '卽',
  194609 => '卿',
  194610 => '卿',
  194611 => '卿',
  194612 => '𠨬',
  194613 => '灰',
  194614 => '及',
  194615 => '叟',
  194616 => '𠭣',
  194617 => '叫',
  194618 => '叱',
  194619 => '吆',
  194620 => '咞',
  194621 => '吸',
  194622 => '呈',
  194623 => '周',
  194624 => '咢',
  194625 => '哶',
  194626 => '唐',
  194627 => '啓',
  194628 => '啣',
  194629 => '善',
  194630 => '善',
  194631 => '喙',
  194632 => '喫',
  194633 => '喳',
  194634 => '嗂',
  194635 => '圖',
  194636 => '嘆',
  194637 => '圗',
  194638 => '噑',
  194639 => '噴',
  194640 => '切',
  194641 => '壮',
  194642 => '城',
  194643 => '埴',
  194644 => '堍',
  194645 => '型',
  194646 => '堲',
  194647 => '報',
  194648 => '墬',
  194649 => '𡓤',
  194650 => '売',
  194651 => '壷',
  194652 => '夆',
  194653 => '多',
  194654 => '夢',
  194655 => '奢',
  194656 => '𡚨',
  194657 => '𡛪',
  194658 => '姬',
  194659 => '娛',
  194660 => '娧',
  194661 => '姘',
  194662 => '婦',
  194663 => '㛮',
  194665 => '嬈',
  194666 => '嬾',
  194667 => '嬾',
  194668 => '𡧈',
  194669 => '寃',
  194670 => '寘',
  194671 => '寧',
  194672 => '寳',
  194673 => '𡬘',
  194674 => '寿',
  194675 => '将',
  194677 => '尢',
  194678 => '㞁',
  194679 => '屠',
  194680 => '屮',
  194681 => '峀',
  194682 => '岍',
  194683 => '𡷤',
  194684 => '嵃',
  194685 => '𡷦',
  194686 => '嵮',
  194687 => '嵫',
  194688 => '嵼',
  194689 => '巡',
  194690 => '巢',
  194691 => '㠯',
  194692 => '巽',
  194693 => '帨',
  194694 => '帽',
  194695 => '幩',
  194696 => '㡢',
  194697 => '𢆃',
  194698 => '㡼',
  194699 => '庰',
  194700 => '庳',
  194701 => '庶',
  194702 => '廊',
  194703 => '𪎒',
  194704 => '廾',
  194705 => '𢌱',
  194706 => '𢌱',
  194707 => '舁',
  194708 => '弢',
  194709 => '弢',
  194710 => '㣇',
  194711 => '𣊸',
  194712 => '𦇚',
  194713 => '形',
  194714 => '彫',
  194715 => '㣣',
  194716 => '徚',
  194717 => '忍',
  194718 => '志',
  194719 => '忹',
  194720 => '悁',
  194721 => '㤺',
  194722 => '㤜',
  194723 => '悔',
  194724 => '𢛔',
  194725 => '惇',
  194726 => '慈',
  194727 => '慌',
  194728 => '慎',
  194729 => '慌',
  194730 => '慺',
  194731 => '憎',
  194732 => '憲',
  194733 => '憤',
  194734 => '憯',
  194735 => '懞',
  194736 => '懲',
  194737 => '懶',
  194738 => '成',
  194739 => '戛',
  194740 => '扝',
  194741 => '抱',
  194742 => '拔',
  194743 => '捐',
  194744 => '𢬌',
  194745 => '挽',
  194746 => '拼',
  194747 => '捨',
  194748 => '掃',
  194749 => '揤',
  194750 => '𢯱',
  194751 => '搢',
  194752 => '揅',
  194753 => '掩',
  194754 => '㨮',
  194755 => '摩',
  194756 => '摾',
  194757 => '撝',
  194758 => '摷',
  194759 => '㩬',
  194760 => '敏',
  194761 => '敬',
  194762 => '𣀊',
  194763 => '旣',
  194764 => '書',
  194765 => '晉',
  194766 => '㬙',
  194767 => '暑',
  194768 => '㬈',
  194769 => '㫤',
  194770 => '冒',
  194771 => '冕',
  194772 => '最',
  194773 => '暜',
  194774 => '肭',
  194775 => '䏙',
  194776 => '朗',
  194777 => '望',
  194778 => '朡',
  194779 => '杞',
  194780 => '杓',
  194781 => '𣏃',
  194782 => '㭉',
  194783 => '柺',
  194784 => '枅',
  194785 => '桒',
  194786 => '梅',
  194787 => '𣑭',
  194788 => '梎',
  194789 => '栟',
  194790 => '椔',
  194791 => '㮝',
  194792 => '楂',
  194793 => '榣',
  194794 => '槪',
  194795 => '檨',
  194796 => '𣚣',
  194797 => '櫛',
  194798 => '㰘',
  194799 => '次',
  194800 => '𣢧',
  194801 => '歔',
  194802 => '㱎',
  194803 => '歲',
  194804 => '殟',
  194805 => '殺',
  194806 => '殻',
  194807 => '𣪍',
  194808 => '𡴋',
  194809 => '𣫺',
  194810 => '汎',
  194811 => '𣲼',
  194812 => '沿',
  194813 => '泍',
  194814 => '汧',
  194815 => '洖',
  194816 => '派',
  194817 => '海',
  194818 => '流',
  194819 => '浩',
  194820 => '浸',
  194821 => '涅',
  194822 => '𣴞',
  194823 => '洴',
  194824 => '港',
  194825 => '湮',
  194826 => '㴳',
  194827 => '滋',
  194828 => '滇',
  194829 => '𣻑',
  194830 => '淹',
  194831 => '潮',
  194832 => '𣽞',
  194833 => '𣾎',
  194834 => '濆',
  194835 => '瀹',
  194836 => '瀞',
  194837 => '瀛',
  194838 => '㶖',
  194839 => '灊',
  194840 => '災',
  194841 => '灷',
  194842 => '炭',
  194843 => '𠔥',
  194844 => '煅',
  194845 => '𤉣',
  194846 => '熜',
  194848 => '爨',
  194849 => '爵',
  194850 => '牐',
  194851 => '𤘈',
  194852 => '犀',
  194853 => '犕',
  194854 => '𤜵',
  194855 => '𤠔',
  194856 => '獺',
  194857 => '王',
  194858 => '㺬',
  194859 => '玥',
  194860 => '㺸',
  194861 => '㺸',
  194862 => '瑇',
  194863 => '瑜',
  194864 => '瑱',
  194865 => '璅',
  194866 => '瓊',
  194867 => '㼛',
  194868 => '甤',
  194869 => '𤰶',
  194870 => '甾',
  194871 => '𤲒',
  194872 => '異',
  194873 => '𢆟',
  194874 => '瘐',
  194875 => '𤾡',
  194876 => '𤾸',
  194877 => '𥁄',
  194878 => '㿼',
  194879 => '䀈',
  194880 => '直',
  194881 => '𥃳',
  194882 => '𥃲',
  194883 => '𥄙',
  194884 => '𥄳',
  194885 => '眞',
  194886 => '真',
  194887 => '真',
  194888 => '睊',
  194889 => '䀹',
  194890 => '瞋',
  194891 => '䁆',
  194892 => '䂖',
  194893 => '𥐝',
  194894 => '硎',
  194895 => '碌',
  194896 => '磌',
  194897 => '䃣',
  194898 => '𥘦',
  194899 => '祖',
  194900 => '𥚚',
  194901 => '𥛅',
  194902 => '福',
  194903 => '秫',
  194904 => '䄯',
  194905 => '穀',
  194906 => '穊',
  194907 => '穏',
  194908 => '𥥼',
  194909 => '𥪧',
  194910 => '𥪧',
  194912 => '䈂',
  194913 => '𥮫',
  194914 => '篆',
  194915 => '築',
  194916 => '䈧',
  194917 => '𥲀',
  194918 => '糒',
  194919 => '䊠',
  194920 => '糨',
  194921 => '糣',
  194922 => '紀',
  194923 => '𥾆',
  194924 => '絣',
  194925 => '䌁',
  194926 => '緇',
  194927 => '縂',
  194928 => '繅',
  194929 => '䌴',
  194930 => '𦈨',
  194931 => '𦉇',
  194932 => '䍙',
  194933 => '𦋙',
  194934 => '罺',
  194935 => '𦌾',
  194936 => '羕',
  194937 => '翺',
  194938 => '者',
  194939 => '𦓚',
  194940 => '𦔣',
  194941 => '聠',
  194942 => '𦖨',
  194943 => '聰',
  194944 => '𣍟',
  194945 => '䏕',
  194946 => '育',
  194947 => '脃',
  194948 => '䐋',
  194949 => '脾',
  194950 => '媵',
  194951 => '𦞧',
  194952 => '𦞵',
  194953 => '𣎓',
  194954 => '𣎜',
  194955 => '舁',
  194956 => '舄',
  194957 => '辞',
  194958 => '䑫',
  194959 => '芑',
  194960 => '芋',
  194961 => '芝',
  194962 => '劳',
  194963 => '花',
  194964 => '芳',
  194965 => '芽',
  194966 => '苦',
  194967 => '𦬼',
  194968 => '若',
  194969 => '茝',
  194970 => '荣',
  194971 => '莭',
  194972 => '茣',
  194973 => '莽',
  194974 => '菧',
  194975 => '著',
  194976 => '荓',
  194977 => '菊',
  194978 => '菌',
  194979 => '菜',
  194980 => '𦰶',
  194981 => '𦵫',
  194982 => '𦳕',
  194983 => '䔫',
  194984 => '蓱',
  194985 => '蓳',
  194986 => '蔖',
  194987 => '𧏊',
  194988 => '蕤',
  194989 => '𦼬',
  194990 => '䕝',
  194991 => '䕡',
  194992 => '𦾱',
  194993 => '𧃒',
  194994 => '䕫',
  194995 => '虐',
  194996 => '虜',
  194997 => '虧',
  194998 => '虩',
  194999 => '蚩',
  195000 => '蚈',
  195001 => '蜎',
  195002 => '蛢',
  195003 => '蝹',
  195004 => '蜨',
  195005 => '蝫',
  195006 => '螆',
  195008 => '蟡',
  195009 => '蠁',
  195010 => '䗹',
  195011 => '衠',
  195012 => '衣',
  195013 => '𧙧',
  195014 => '裗',
  195015 => '裞',
  195016 => '䘵',
  195017 => '裺',
  195018 => '㒻',
  195019 => '𧢮',
  195020 => '𧥦',
  195021 => '䚾',
  195022 => '䛇',
  195023 => '誠',
  195024 => '諭',
  195025 => '變',
  195026 => '豕',
  195027 => '𧲨',
  195028 => '貫',
  195029 => '賁',
  195030 => '贛',
  195031 => '起',
  195032 => '𧼯',
  195033 => '𠠄',
  195034 => '跋',
  195035 => '趼',
  195036 => '跰',
  195037 => '𠣞',
  195038 => '軔',
  195039 => '輸',
  195040 => '𨗒',
  195041 => '𨗭',
  195042 => '邔',
  195043 => '郱',
  195044 => '鄑',
  195045 => '𨜮',
  195046 => '鄛',
  195047 => '鈸',
  195048 => '鋗',
  195049 => '鋘',
  195050 => '鉼',
  195051 => '鏹',
  195052 => '鐕',
  195053 => '𨯺',
  195054 => '開',
  195055 => '䦕',
  195056 => '閷',
  195057 => '𨵷',
  195058 => '䧦',
  195059 => '雃',
  195060 => '嶲',
  195061 => '霣',
  195062 => '𩅅',
  195063 => '𩈚',
  195064 => '䩮',
  195065 => '䩶',
  195066 => '韠',
  195067 => '𩐊',
  195068 => '䪲',
  195069 => '𩒖',
  195070 => '頋',
  195071 => '頋',
  195072 => '頩',
  195073 => '𩖶',
  195074 => '飢',
  195075 => '䬳',
  195076 => '餩',
  195077 => '馧',
  195078 => '駂',
  195079 => '駾',
  195080 => '䯎',
  195081 => '𩬰',
  195082 => '鬒',
  195083 => '鱀',
  195084 => '鳽',
  195085 => '䳎',
  195086 => '䳭',
  195087 => '鵧',
  195088 => '𪃎',
  195089 => '䳸',
  195090 => '𪄅',
  195091 => '𪈎',
  195092 => '𪊑',
  195093 => '麻',
  195094 => '䵖',
  195095 => '黹',
  195096 => '黾',
  195097 => '鼅',
  195098 => '鼏',
  195099 => '鼖',
  195100 => '鼻',
  195101 => '𪘀',
);
PKϤ$Z]�P*��/polyfill-intl-idn/Resources/unidata/ignored.phpnu�[���<?php

return array (
  173 => true,
  847 => true,
  6155 => true,
  6156 => true,
  6157 => true,
  8203 => true,
  8288 => true,
  8292 => true,
  65024 => true,
  65025 => true,
  65026 => true,
  65027 => true,
  65028 => true,
  65029 => true,
  65030 => true,
  65031 => true,
  65032 => true,
  65033 => true,
  65034 => true,
  65035 => true,
  65036 => true,
  65037 => true,
  65038 => true,
  65039 => true,
  65279 => true,
  113824 => true,
  113825 => true,
  113826 => true,
  113827 => true,
  917760 => true,
  917761 => true,
  917762 => true,
  917763 => true,
  917764 => true,
  917765 => true,
  917766 => true,
  917767 => true,
  917768 => true,
  917769 => true,
  917770 => true,
  917771 => true,
  917772 => true,
  917773 => true,
  917774 => true,
  917775 => true,
  917776 => true,
  917777 => true,
  917778 => true,
  917779 => true,
  917780 => true,
  917781 => true,
  917782 => true,
  917783 => true,
  917784 => true,
  917785 => true,
  917786 => true,
  917787 => true,
  917788 => true,
  917789 => true,
  917790 => true,
  917791 => true,
  917792 => true,
  917793 => true,
  917794 => true,
  917795 => true,
  917796 => true,
  917797 => true,
  917798 => true,
  917799 => true,
  917800 => true,
  917801 => true,
  917802 => true,
  917803 => true,
  917804 => true,
  917805 => true,
  917806 => true,
  917807 => true,
  917808 => true,
  917809 => true,
  917810 => true,
  917811 => true,
  917812 => true,
  917813 => true,
  917814 => true,
  917815 => true,
  917816 => true,
  917817 => true,
  917818 => true,
  917819 => true,
  917820 => true,
  917821 => true,
  917822 => true,
  917823 => true,
  917824 => true,
  917825 => true,
  917826 => true,
  917827 => true,
  917828 => true,
  917829 => true,
  917830 => true,
  917831 => true,
  917832 => true,
  917833 => true,
  917834 => true,
  917835 => true,
  917836 => true,
  917837 => true,
  917838 => true,
  917839 => true,
  917840 => true,
  917841 => true,
  917842 => true,
  917843 => true,
  917844 => true,
  917845 => true,
  917846 => true,
  917847 => true,
  917848 => true,
  917849 => true,
  917850 => true,
  917851 => true,
  917852 => true,
  917853 => true,
  917854 => true,
  917855 => true,
  917856 => true,
  917857 => true,
  917858 => true,
  917859 => true,
  917860 => true,
  917861 => true,
  917862 => true,
  917863 => true,
  917864 => true,
  917865 => true,
  917866 => true,
  917867 => true,
  917868 => true,
  917869 => true,
  917870 => true,
  917871 => true,
  917872 => true,
  917873 => true,
  917874 => true,
  917875 => true,
  917876 => true,
  917877 => true,
  917878 => true,
  917879 => true,
  917880 => true,
  917881 => true,
  917882 => true,
  917883 => true,
  917884 => true,
  917885 => true,
  917886 => true,
  917887 => true,
  917888 => true,
  917889 => true,
  917890 => true,
  917891 => true,
  917892 => true,
  917893 => true,
  917894 => true,
  917895 => true,
  917896 => true,
  917897 => true,
  917898 => true,
  917899 => true,
  917900 => true,
  917901 => true,
  917902 => true,
  917903 => true,
  917904 => true,
  917905 => true,
  917906 => true,
  917907 => true,
  917908 => true,
  917909 => true,
  917910 => true,
  917911 => true,
  917912 => true,
  917913 => true,
  917914 => true,
  917915 => true,
  917916 => true,
  917917 => true,
  917918 => true,
  917919 => true,
  917920 => true,
  917921 => true,
  917922 => true,
  917923 => true,
  917924 => true,
  917925 => true,
  917926 => true,
  917927 => true,
  917928 => true,
  917929 => true,
  917930 => true,
  917931 => true,
  917932 => true,
  917933 => true,
  917934 => true,
  917935 => true,
  917936 => true,
  917937 => true,
  917938 => true,
  917939 => true,
  917940 => true,
  917941 => true,
  917942 => true,
  917943 => true,
  917944 => true,
  917945 => true,
  917946 => true,
  917947 => true,
  917948 => true,
  917949 => true,
  917950 => true,
  917951 => true,
  917952 => true,
  917953 => true,
  917954 => true,
  917955 => true,
  917956 => true,
  917957 => true,
  917958 => true,
  917959 => true,
  917960 => true,
  917961 => true,
  917962 => true,
  917963 => true,
  917964 => true,
  917965 => true,
  917966 => true,
  917967 => true,
  917968 => true,
  917969 => true,
  917970 => true,
  917971 => true,
  917972 => true,
  917973 => true,
  917974 => true,
  917975 => true,
  917976 => true,
  917977 => true,
  917978 => true,
  917979 => true,
  917980 => true,
  917981 => true,
  917982 => true,
  917983 => true,
  917984 => true,
  917985 => true,
  917986 => true,
  917987 => true,
  917988 => true,
  917989 => true,
  917990 => true,
  917991 => true,
  917992 => true,
  917993 => true,
  917994 => true,
  917995 => true,
  917996 => true,
  917997 => true,
  917998 => true,
  917999 => true,
);
PKϤ$Z �E�polyfill-intl-idn/bootstrap.phpnu�[���<?php

/*
 * This file is part of the Symfony package.
 *
 * (c) Fabien Potencier <fabien@symfony.com>
 *
 * For the full copyright and license information, please view the LICENSE
 * file that was distributed with this source code.
 */

use Symfony\Polyfill\Intl\Idn as p;

if (extension_loaded('intl')) {
    return;
}

if (!defined('U_IDNA_PROHIBITED_ERROR')) {
    define('U_IDNA_PROHIBITED_ERROR', 66560);
}
if (!defined('U_IDNA_ERROR_START')) {
    define('U_IDNA_ERROR_START', 66560);
}
if (!defined('U_IDNA_UNASSIGNED_ERROR')) {
    define('U_IDNA_UNASSIGNED_ERROR', 66561);
}
if (!defined('U_IDNA_CHECK_BIDI_ERROR')) {
    define('U_IDNA_CHECK_BIDI_ERROR', 66562);
}
if (!defined('U_IDNA_STD3_ASCII_RULES_ERROR')) {
    define('U_IDNA_STD3_ASCII_RULES_ERROR', 66563);
}
if (!defined('U_IDNA_ACE_PREFIX_ERROR')) {
    define('U_IDNA_ACE_PREFIX_ERROR', 66564);
}
if (!defined('U_IDNA_VERIFICATION_ERROR')) {
    define('U_IDNA_VERIFICATION_ERROR', 66565);
}
if (!defined('U_IDNA_LABEL_TOO_LONG_ERROR')) {
    define('U_IDNA_LABEL_TOO_LONG_ERROR', 66566);
}
if (!defined('U_IDNA_ZERO_LENGTH_LABEL_ERROR')) {
    define('U_IDNA_ZERO_LENGTH_LABEL_ERROR', 66567);
}
if (!defined('U_IDNA_DOMAIN_NAME_TOO_LONG_ERROR')) {
    define('U_IDNA_DOMAIN_NAME_TOO_LONG_ERROR', 66568);
}
if (!defined('U_IDNA_ERROR_LIMIT')) {
    define('U_IDNA_ERROR_LIMIT', 66569);
}
if (!defined('U_STRINGPREP_PROHIBITED_ERROR')) {
    define('U_STRINGPREP_PROHIBITED_ERROR', 66560);
}
if (!defined('U_STRINGPREP_UNASSIGNED_ERROR')) {
    define('U_STRINGPREP_UNASSIGNED_ERROR', 66561);
}
if (!defined('U_STRINGPREP_CHECK_BIDI_ERROR')) {
    define('U_STRINGPREP_CHECK_BIDI_ERROR', 66562);
}
if (!defined('IDNA_DEFAULT')) {
    define('IDNA_DEFAULT', 0);
}
if (!defined('IDNA_ALLOW_UNASSIGNED')) {
    define('IDNA_ALLOW_UNASSIGNED', 1);
}
if (!defined('IDNA_USE_STD3_RULES')) {
    define('IDNA_USE_STD3_RULES', 2);
}
if (!defined('IDNA_CHECK_BIDI')) {
    define('IDNA_CHECK_BIDI', 4);
}
if (!defined('IDNA_CHECK_CONTEXTJ')) {
    define('IDNA_CHECK_CONTEXTJ', 8);
}
if (!defined('IDNA_NONTRANSITIONAL_TO_ASCII')) {
    define('IDNA_NONTRANSITIONAL_TO_ASCII', 16);
}
if (!defined('IDNA_NONTRANSITIONAL_TO_UNICODE')) {
    define('IDNA_NONTRANSITIONAL_TO_UNICODE', 32);
}
if (!defined('INTL_IDNA_VARIANT_2003')) {
    define('INTL_IDNA_VARIANT_2003', 0);
}
if (!defined('INTL_IDNA_VARIANT_UTS46')) {
    define('INTL_IDNA_VARIANT_UTS46', 1);
}
if (!defined('IDNA_ERROR_EMPTY_LABEL')) {
    define('IDNA_ERROR_EMPTY_LABEL', 1);
}
if (!defined('IDNA_ERROR_LABEL_TOO_LONG')) {
    define('IDNA_ERROR_LABEL_TOO_LONG', 2);
}
if (!defined('IDNA_ERROR_DOMAIN_NAME_TOO_LONG')) {
    define('IDNA_ERROR_DOMAIN_NAME_TOO_LONG', 4);
}
if (!defined('IDNA_ERROR_LEADING_HYPHEN')) {
    define('IDNA_ERROR_LEADING_HYPHEN', 8);
}
if (!defined('IDNA_ERROR_TRAILING_HYPHEN')) {
    define('IDNA_ERROR_TRAILING_HYPHEN', 16);
}
if (!defined('IDNA_ERROR_HYPHEN_3_4')) {
    define('IDNA_ERROR_HYPHEN_3_4', 32);
}
if (!defined('IDNA_ERROR_LEADING_COMBINING_MARK')) {
    define('IDNA_ERROR_LEADING_COMBINING_MARK', 64);
}
if (!defined('IDNA_ERROR_DISALLOWED')) {
    define('IDNA_ERROR_DISALLOWED', 128);
}
if (!defined('IDNA_ERROR_PUNYCODE')) {
    define('IDNA_ERROR_PUNYCODE', 256);
}
if (!defined('IDNA_ERROR_LABEL_HAS_DOT')) {
    define('IDNA_ERROR_LABEL_HAS_DOT', 512);
}
if (!defined('IDNA_ERROR_INVALID_ACE_LABEL')) {
    define('IDNA_ERROR_INVALID_ACE_LABEL', 1024);
}
if (!defined('IDNA_ERROR_BIDI')) {
    define('IDNA_ERROR_BIDI', 2048);
}
if (!defined('IDNA_ERROR_CONTEXTJ')) {
    define('IDNA_ERROR_CONTEXTJ', 4096);
}

if (PHP_VERSION_ID < 70400) {
    if (!function_exists('idn_to_ascii')) {
        function idn_to_ascii($domain, $options = IDNA_DEFAULT, $variant = INTL_IDNA_VARIANT_2003, &$idna_info = array()) { return p\Idn::idn_to_ascii($domain, $options, $variant, $idna_info); }
    }
    if (!function_exists('idn_to_utf8')) {
        function idn_to_utf8($domain, $options = IDNA_DEFAULT, $variant = INTL_IDNA_VARIANT_2003, &$idna_info = array()) { return p\Idn::idn_to_utf8($domain, $options, $variant, $idna_info); }
    }
} else {
    if (!function_exists('idn_to_ascii')) {
        function idn_to_ascii($domain, $options = IDNA_DEFAULT, $variant = INTL_IDNA_VARIANT_UTS46, &$idna_info = array()) { return p\Idn::idn_to_ascii($domain, $options, $variant, $idna_info); }
    }
    if (!function_exists('idn_to_utf8')) {
        function idn_to_utf8($domain, $options = IDNA_DEFAULT, $variant = INTL_IDNA_VARIANT_UTS46, &$idna_info = array()) { return p\Idn::idn_to_utf8($domain, $options, $variant, $idna_info); }
    }
}
PKϤ$Z�nWWpolyfill-intl-idn/LICENSEnu�[���Copyright (c) 2018-2019 Fabien Potencier and Trevor Rowbotham <trevor.rowbotham@pm.me>

Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is furnished
to do so, subject to the following conditions:

The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.

THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
THE SOFTWARE.
PKϤ$Z.&c���*cache-contracts/TagAwareCacheInterface.phpnu�[���<?php

/*
 * This file is part of the Symfony package.
 *
 * (c) Fabien Potencier <fabien@symfony.com>
 *
 * For the full copyright and license information, please view the LICENSE
 * file that was distributed with this source code.
 */

namespace Symfony\Contracts\Cache;

use Psr\Cache\InvalidArgumentException;

/**
 * Allows invalidating cached items using tags.
 *
 * @author Nicolas Grekas <p@tchwork.com>
 */
interface TagAwareCacheInterface extends CacheInterface
{
    /**
     * Invalidates cached items using tags.
     *
     * When implemented on a PSR-6 pool, invalidation should not apply
     * to deferred items. Instead, they should be committed as usual.
     * This allows replacing old tagged values by new ones without
     * race conditions.
     *
     * @param string[] $tags An array of tags to invalidate
     *
     * @return bool True on success
     *
     * @throws InvalidArgumentException When $tags is not valid
     */
    public function invalidateTags(array $tags);
}
PKϤ$Z�j���!cache-contracts/ItemInterface.phpnu�[���<?php

/*
 * This file is part of the Symfony package.
 *
 * (c) Fabien Potencier <fabien@symfony.com>
 *
 * For the full copyright and license information, please view the LICENSE
 * file that was distributed with this source code.
 */

namespace Symfony\Contracts\Cache;

use Psr\Cache\CacheException;
use Psr\Cache\CacheItemInterface;
use Psr\Cache\InvalidArgumentException;

/**
 * Augments PSR-6's CacheItemInterface with support for tags and metadata.
 *
 * @author Nicolas Grekas <p@tchwork.com>
 */
interface ItemInterface extends CacheItemInterface
{
    /**
     * References the Unix timestamp stating when the item will expire.
     */
    public const METADATA_EXPIRY = 'expiry';

    /**
     * References the time the item took to be created, in milliseconds.
     */
    public const METADATA_CTIME = 'ctime';

    /**
     * References the list of tags that were assigned to the item, as string[].
     */
    public const METADATA_TAGS = 'tags';

    /**
     * Reserved characters that cannot be used in a key or tag.
     */
    public const RESERVED_CHARACTERS = '{}()/\@:';

    /**
     * Adds a tag to a cache item.
     *
     * Tags are strings that follow the same validation rules as keys.
     *
     * @param string|string[] $tags A tag or array of tags
     *
     * @return $this
     *
     * @throws InvalidArgumentException When $tag is not valid
     * @throws CacheException           When the item comes from a pool that is not tag-aware
     */
    public function tag($tags): self;

    /**
     * Returns a list of metadata info that were saved alongside with the cached value.
     *
     * See ItemInterface::METADATA_* consts for keys potentially found in the returned array.
     */
    public function getMetadata(): array;
}
PKϤ$Z�Z#HHcache-contracts/README.mdnu�[���Symfony Cache Contracts
=======================

A set of abstractions extracted out of the Symfony components.

Can be used to build on semantics that the Symfony components proved useful - and
that already have battle tested implementations.

See https://github.com/symfony/contracts/blob/main/README.md for more information.
PKϤ$Z��msY	Y	"cache-contracts/CacheInterface.phpnu�[���<?php

/*
 * This file is part of the Symfony package.
 *
 * (c) Fabien Potencier <fabien@symfony.com>
 *
 * For the full copyright and license information, please view the LICENSE
 * file that was distributed with this source code.
 */

namespace Symfony\Contracts\Cache;

use Psr\Cache\CacheItemInterface;
use Psr\Cache\InvalidArgumentException;

/**
 * Covers most simple to advanced caching needs.
 *
 * @author Nicolas Grekas <p@tchwork.com>
 */
interface CacheInterface
{
    /**
     * Fetches a value from the pool or computes it if not found.
     *
     * On cache misses, a callback is called that should return the missing value.
     * This callback is given a PSR-6 CacheItemInterface instance corresponding to the
     * requested key, that could be used e.g. for expiration control. It could also
     * be an ItemInterface instance when its additional features are needed.
     *
     * @param string                     $key       The key of the item to retrieve from the cache
     * @param callable|CallbackInterface $callback  Should return the computed value for the given key/item
     * @param float|null                 $beta      A float that, as it grows, controls the likeliness of triggering
     *                                              early expiration. 0 disables it, INF forces immediate expiration.
     *                                              The default (or providing null) is implementation dependent but should
     *                                              typically be 1.0, which should provide optimal stampede protection.
     *                                              See https://en.wikipedia.org/wiki/Cache_stampede#Probabilistic_early_expiration
     * @param array                      &$metadata The metadata of the cached item {@see ItemInterface::getMetadata()}
     *
     * @return mixed
     *
     * @throws InvalidArgumentException When $key is not valid or when $beta is negative
     */
    public function get(string $key, callable $callback, float $beta = null, array &$metadata = null);

    /**
     * Removes an item from the pool.
     *
     * @param string $key The key to delete
     *
     * @throws InvalidArgumentException When $key is not valid
     *
     * @return bool True if the item was successfully removed, false if there was any error
     */
    public function delete(string $key): bool;
}
PKϤ$Z���

cache-contracts/CacheTrait.phpnu�[���<?php

/*
 * This file is part of the Symfony package.
 *
 * (c) Fabien Potencier <fabien@symfony.com>
 *
 * For the full copyright and license information, please view the LICENSE
 * file that was distributed with this source code.
 */

namespace Symfony\Contracts\Cache;

use Psr\Cache\CacheItemPoolInterface;
use Psr\Cache\InvalidArgumentException;
use Psr\Log\LoggerInterface;

// Help opcache.preload discover always-needed symbols
class_exists(InvalidArgumentException::class);

/**
 * An implementation of CacheInterface for PSR-6 CacheItemPoolInterface classes.
 *
 * @author Nicolas Grekas <p@tchwork.com>
 */
trait CacheTrait
{
    /**
     * {@inheritdoc}
     *
     * @return mixed
     */
    public function get(string $key, callable $callback, float $beta = null, array &$metadata = null)
    {
        return $this->doGet($this, $key, $callback, $beta, $metadata);
    }

    /**
     * {@inheritdoc}
     */
    public function delete(string $key): bool
    {
        return $this->deleteItem($key);
    }

    private function doGet(CacheItemPoolInterface $pool, string $key, callable $callback, ?float $beta, array &$metadata = null, LoggerInterface $logger = null)
    {
        if (0 > $beta = $beta ?? 1.0) {
            throw new class(sprintf('Argument "$beta" provided to "%s::get()" must be a positive number, %f given.', static::class, $beta)) extends \InvalidArgumentException implements InvalidArgumentException { };
        }

        $item = $pool->getItem($key);
        $recompute = !$item->isHit() || \INF === $beta;
        $metadata = $item instanceof ItemInterface ? $item->getMetadata() : [];

        if (!$recompute && $metadata) {
            $expiry = $metadata[ItemInterface::METADATA_EXPIRY] ?? false;
            $ctime = $metadata[ItemInterface::METADATA_CTIME] ?? false;

            if ($recompute = $ctime && $expiry && $expiry <= ($now = microtime(true)) - $ctime / 1000 * $beta * log(random_int(1, \PHP_INT_MAX) / \PHP_INT_MAX)) {
                // force applying defaultLifetime to expiry
                $item->expiresAt(null);
                $logger && $logger->info('Item "{key}" elected for early recomputation {delta}s before its expiration', [
                    'key' => $key,
                    'delta' => sprintf('%.1f', $expiry - $now),
                ]);
            }
        }

        if ($recompute) {
            $save = true;
            $item->set($callback($item, $save));
            if ($save) {
                $pool->save($item);
            }
        }

        return $item->get();
    }
}
PKϤ$Zh{#��cache-contracts/CHANGELOG.mdnu�[���CHANGELOG
=========

The changelog is maintained for all Symfony contracts at the following URL:
https://github.com/symfony/contracts/blob/main/CHANGELOG.md
PKϤ$Z5�))cache-contracts/LICENSEnu�[���Copyright (c) 2018-2022 Fabien Potencier

Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is furnished
to do so, subject to the following conditions:

The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.

THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
THE SOFTWARE.
PKϤ$Z5s��++%cache-contracts/CallbackInterface.phpnu�[���<?php

/*
 * This file is part of the Symfony package.
 *
 * (c) Fabien Potencier <fabien@symfony.com>
 *
 * For the full copyright and license information, please view the LICENSE
 * file that was distributed with this source code.
 */

namespace Symfony\Contracts\Cache;

use Psr\Cache\CacheItemInterface;

/**
 * Computes and returns the cached value of an item.
 *
 * @author Nicolas Grekas <p@tchwork.com>
 */
interface CallbackInterface
{
    /**
     * @param CacheItemInterface|ItemInterface $item  The item to compute the value for
     * @param bool                             &$save Should be set to false when the value should not be saved in the pool
     *
     * @return mixed The computed value for the passed item
     */
    public function __invoke(CacheItemInterface $item, bool &$save);
}
PKϤ$Z}�9�polyfill-php72/Php72.phpnu�[���<?php

/*
 * This file is part of the Symfony package.
 *
 * (c) Fabien Potencier <fabien@symfony.com>
 *
 * For the full copyright and license information, please view the LICENSE
 * file that was distributed with this source code.
 */

namespace Symfony\Polyfill\Php72;

/**
 * @author Nicolas Grekas <p@tchwork.com>
 * @author Dariusz Rumiński <dariusz.ruminski@gmail.com>
 *
 * @internal
 */
final class Php72
{
    private static $hashMask;

    public static function utf8_encode($s)
    {
        $s .= $s;
        $len = \strlen($s);

        for ($i = $len >> 1, $j = 0; $i < $len; ++$i, ++$j) {
            switch (true) {
                case $s[$i] < "\x80": $s[$j] = $s[$i]; break;
                case $s[$i] < "\xC0": $s[$j] = "\xC2"; $s[++$j] = $s[$i]; break;
                default: $s[$j] = "\xC3"; $s[++$j] = \chr(\ord($s[$i]) - 64); break;
            }
        }

        return substr($s, 0, $j);
    }

    public static function utf8_decode($s)
    {
        $s = (string) $s;
        $len = \strlen($s);

        for ($i = 0, $j = 0; $i < $len; ++$i, ++$j) {
            switch ($s[$i] & "\xF0") {
                case "\xC0":
                case "\xD0":
                    $c = (\ord($s[$i] & "\x1F") << 6) | \ord($s[++$i] & "\x3F");
                    $s[$j] = $c < 256 ? \chr($c) : '?';
                    break;

                case "\xF0":
                    ++$i;
                    // no break

                case "\xE0":
                    $s[$j] = '?';
                    $i += 2;
                    break;

                default:
                    $s[$j] = $s[$i];
            }
        }

        return substr($s, 0, $j);
    }

    public static function php_os_family()
    {
        if ('\\' === \DIRECTORY_SEPARATOR) {
            return 'Windows';
        }

        $map = array(
            'Darwin' => 'Darwin',
            'DragonFly' => 'BSD',
            'FreeBSD' => 'BSD',
            'NetBSD' => 'BSD',
            'OpenBSD' => 'BSD',
            'Linux' => 'Linux',
            'SunOS' => 'Solaris',
        );

        return isset($map[PHP_OS]) ? $map[PHP_OS] : 'Unknown';
    }

    public static function spl_object_id($object)
    {
        if (null === self::$hashMask) {
            self::initHashMask();
        }
        if (null === $hash = spl_object_hash($object)) {
            return;
        }

        // On 32-bit systems, PHP_INT_SIZE is 4,
        return self::$hashMask ^ hexdec(substr($hash, 16 - (\PHP_INT_SIZE * 2 - 1), (\PHP_INT_SIZE * 2 - 1)));
    }

    public static function sapi_windows_vt100_support($stream, $enable = null)
    {
        if (!\is_resource($stream)) {
            trigger_error('sapi_windows_vt100_support() expects parameter 1 to be resource, '.\gettype($stream).' given', E_USER_WARNING);

            return false;
        }

        $meta = stream_get_meta_data($stream);

        if ('STDIO' !== $meta['stream_type']) {
            trigger_error('sapi_windows_vt100_support() was not able to analyze the specified stream', E_USER_WARNING);

            return false;
        }

        // We cannot actually disable vt100 support if it is set
        if (false === $enable || !self::stream_isatty($stream)) {
            return false;
        }

        // The native function does not apply to stdin
        $meta = array_map('strtolower', $meta);
        $stdin = 'php://stdin' === $meta['uri'] || 'php://fd/0' === $meta['uri'];

        return !$stdin
            && (false !== getenv('ANSICON')
            || 'ON' === getenv('ConEmuANSI')
            || 'xterm' === getenv('TERM')
            || 'Hyper' === getenv('TERM_PROGRAM'));
    }

    public static function stream_isatty($stream)
    {
        if (!\is_resource($stream)) {
            trigger_error('stream_isatty() expects parameter 1 to be resource, '.\gettype($stream).' given', E_USER_WARNING);

            return false;
        }

        if ('\\' === \DIRECTORY_SEPARATOR) {
            $stat = @fstat($stream);
            // Check if formatted mode is S_IFCHR
            return $stat ? 0020000 === ($stat['mode'] & 0170000) : false;
        }

        return \function_exists('posix_isatty') && @posix_isatty($stream);
    }

    private static function initHashMask()
    {
        $obj = (object) array();
        self::$hashMask = -1;

        // check if we are nested in an output buffering handler to prevent a fatal error with ob_start() below
        $obFuncs = array('ob_clean', 'ob_end_clean', 'ob_flush', 'ob_end_flush', 'ob_get_contents', 'ob_get_flush');
        foreach (debug_backtrace(\PHP_VERSION_ID >= 50400 ? DEBUG_BACKTRACE_IGNORE_ARGS : false) as $frame) {
            if (isset($frame['function'][0]) && !isset($frame['class']) && 'o' === $frame['function'][0] && \in_array($frame['function'], $obFuncs)) {
                $frame['line'] = 0;
                break;
            }
        }
        if (!empty($frame['line'])) {
            ob_start();
            debug_zval_dump($obj);
            self::$hashMask = (int) substr(ob_get_clean(), 17);
        }

        self::$hashMask ^= hexdec(substr(spl_object_hash($obj), 16 - (\PHP_INT_SIZE * 2 - 1), (\PHP_INT_SIZE * 2 - 1)));
    }

    public static function mb_chr($code, $encoding = null)
    {
        if (0x80 > $code %= 0x200000) {
            $s = \chr($code);
        } elseif (0x800 > $code) {
            $s = \chr(0xC0 | $code >> 6).\chr(0x80 | $code & 0x3F);
        } elseif (0x10000 > $code) {
            $s = \chr(0xE0 | $code >> 12).\chr(0x80 | $code >> 6 & 0x3F).\chr(0x80 | $code & 0x3F);
        } else {
            $s = \chr(0xF0 | $code >> 18).\chr(0x80 | $code >> 12 & 0x3F).\chr(0x80 | $code >> 6 & 0x3F).\chr(0x80 | $code & 0x3F);
        }

        if ('UTF-8' !== $encoding) {
            $s = mb_convert_encoding($s, $encoding, 'UTF-8');
        }

        return $s;
    }

    public static function mb_ord($s, $encoding = null)
    {
        if (null == $encoding) {
            $s = mb_convert_encoding($s, 'UTF-8');
        } elseif ('UTF-8' !== $encoding) {
            $s = mb_convert_encoding($s, 'UTF-8', $encoding);
        }

        if (1 === \strlen($s)) {
            return \ord($s);
        }

        $code = ($s = unpack('C*', substr($s, 0, 4))) ? $s[1] : 0;
        if (0xF0 <= $code) {
            return (($code - 0xF0) << 18) + (($s[2] - 0x80) << 12) + (($s[3] - 0x80) << 6) + $s[4] - 0x80;
        }
        if (0xE0 <= $code) {
            return (($code - 0xE0) << 12) + (($s[2] - 0x80) << 6) + $s[3] - 0x80;
        }
        if (0xC0 <= $code) {
            return (($code - 0xC0) << 6) + $s[2] - 0x80;
        }

        return $code;
    }
}
PKϤ$Z�!>iipolyfill-php72/README.mdnu�[���Symfony Polyfill / Php72
========================

This component provides functions added to PHP 7.2 core:

- [`spl_object_id`](https://php.net/spl_object_id)
- [`stream_isatty`](https://php.net/stream_isatty)

On Windows only:

- [`sapi_windows_vt100_support`](https://php.net/sapi_windows_vt100_support)

Moved to core since 7.2 (was in the optional XML extension earlier):

- [`utf8_encode`](https://php.net/utf8_encode)
- [`utf8_decode`](https://php.net/utf8_decode)

Also, it provides constants added to PHP 7.2:
- [`PHP_FLOAT_*`](https://php.net/reserved.constants#constant.php-float-dig)
- [`PHP_OS_FAMILY`](https://php.net/reserved.constants#constant.php-os-family)

More information can be found in the
[main Polyfill README](https://github.com/symfony/polyfill/blob/master/README.md).

License
=======

This library is released under the [MIT license](LICENSE).
PKϤ$Z�LR�polyfill-php72/bootstrap.phpnu�[���<?php

/*
 * This file is part of the Symfony package.
 *
 * (c) Fabien Potencier <fabien@symfony.com>
 *
 * For the full copyright and license information, please view the LICENSE
 * file that was distributed with this source code.
 */

use Symfony\Polyfill\Php72 as p;

if (PHP_VERSION_ID >= 70200) {
    return;
}

if (!defined('PHP_FLOAT_DIG')) {
    define('PHP_FLOAT_DIG', 15);
}
if (!defined('PHP_FLOAT_EPSILON')) {
    define('PHP_FLOAT_EPSILON', 2.2204460492503E-16);
}
if (!defined('PHP_FLOAT_MIN')) {
    define('PHP_FLOAT_MIN', 2.2250738585072E-308);
}
if (!defined('PHP_FLOAT_MAX')) {
    define('PHP_FLOAT_MAX', 1.7976931348623157E+308);
}
if (!defined('PHP_OS_FAMILY')) {
    define('PHP_OS_FAMILY', p\Php72::php_os_family());
}

if ('\\' === DIRECTORY_SEPARATOR && !function_exists('sapi_windows_vt100_support')) {
    function sapi_windows_vt100_support($stream, $enable = null) { return p\Php72::sapi_windows_vt100_support($stream, $enable); }
}
if (!function_exists('stream_isatty')) {
    function stream_isatty($stream) { return p\Php72::stream_isatty($stream); }
}
if (!function_exists('utf8_encode')) {
    function utf8_encode($s) { return p\Php72::utf8_encode($s); }
}
if (!function_exists('utf8_decode')) {
    function utf8_decode($s) { return p\Php72::utf8_decode($s); }
}
if (!function_exists('spl_object_id')) {
    function spl_object_id($s) { return p\Php72::spl_object_id($s); }
}
if (!function_exists('mb_ord')) {
    function mb_ord($s, $enc = null) { return p\Php72::mb_ord($s, $enc); }
}
if (!function_exists('mb_chr')) {
    function mb_chr($code, $enc = null) { return p\Php72::mb_chr($code, $enc); }
}
if (!function_exists('mb_scrub')) {
    function mb_scrub($s, $enc = null) { $enc = null === $enc ? mb_internal_encoding() : $enc; return mb_convert_encoding($s, $enc, $enc); }
}
PKϤ$Z�\�))polyfill-php72/LICENSEnu�[���Copyright (c) 2015-2019 Fabien Potencier

Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is furnished
to do so, subject to the following conditions:

The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.

THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
THE SOFTWARE.
PKϤ$Z/��nggpolyfill-php73/Php73.phpnu�[���<?php

/*
 * This file is part of the Symfony package.
 *
 * (c) Fabien Potencier <fabien@symfony.com>
 *
 * For the full copyright and license information, please view the LICENSE
 * file that was distributed with this source code.
 */

namespace Symfony\Polyfill\Php73;

/**
 * @author Gabriel Caruso <carusogabriel34@gmail.com>
 * @author Ion Bazan <ion.bazan@gmail.com>
 *
 * @internal
 */
final class Php73
{
    public static $startAt = 1533462603;

    /**
     * @param bool $asNum
     *
     * @return array|float|int
     */
    public static function hrtime($asNum = false)
    {
        $ns = microtime(false);
        $s = substr($ns, 11) - self::$startAt;
        $ns = 1E9 * (float) $ns;

        if ($asNum) {
            $ns += $s * 1E9;

            return \PHP_INT_SIZE === 4 ? $ns : (int) $ns;
        }

        return array($s, (int) $ns);
    }
}
PKϤ$Z	�c11polyfill-php73/README.mdnu�[���Symfony Polyfill / Php73
========================

This component provides functions added to PHP 7.3 core:

- [`array_key_first`](https://php.net/array_key_first)
- [`array_key_last`](https://php.net/array_key_last)
- [`hrtime`](https://php.net/function.hrtime)
- [`is_countable`](https://php.net/is_countable)
- [`JsonException`](https://php.net/JsonException)

More information can be found in the
[main Polyfill README](https://github.com/symfony/polyfill/blob/master/README.md).

License
=======

This library is released under the [MIT license](LICENSE).
PKϤ$Z<F�0polyfill-php73/Resources/stubs/JsonException.phpnu�[���<?php

/*
 * This file is part of the Symfony package.
 *
 * (c) Fabien Potencier <fabien@symfony.com>
 *
 * For the full copyright and license information, please view the LICENSE
 * file that was distributed with this source code.
 */

class JsonException extends Exception
{
}
PKϤ$Z?y����polyfill-php73/bootstrap.phpnu�[���<?php

/*
 * This file is part of the Symfony package.
 *
 * (c) Fabien Potencier <fabien@symfony.com>
 *
 * For the full copyright and license information, please view the LICENSE
 * file that was distributed with this source code.
 */

use Symfony\Polyfill\Php73 as p;

if (PHP_VERSION_ID >= 70300) {
    return;
}

if (!function_exists('is_countable')) {
    function is_countable($var) { return is_array($var) || $var instanceof Countable || $var instanceof ResourceBundle || $var instanceof SimpleXmlElement; }
}
if (!function_exists('hrtime')) {
    require_once __DIR__.'/Php73.php';
    p\Php73::$startAt = (int) microtime(true);
    function hrtime($asNum = false) { return p\Php73::hrtime($asNum); }
}
if (!function_exists('array_key_first')) {
    function array_key_first(array $array) { foreach ($array as $key => $value) { return $key; } }
}
if (!function_exists('array_key_last')) {
    function array_key_last(array $array) { end($array); return key($array); }
}
PKϤ$Z�`e0))polyfill-php73/LICENSEnu�[���Copyright (c) 2018-2019 Fabien Potencier

Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is furnished
to do so, subject to the following conditions:

The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.

THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
THE SOFTWARE.
PKϤ$Z��#O,service-contracts/ServiceSubscriberTrait.phpnu�[���<?php

/*
 * This file is part of the Symfony package.
 *
 * (c) Fabien Potencier <fabien@symfony.com>
 *
 * For the full copyright and license information, please view the LICENSE
 * file that was distributed with this source code.
 */

namespace Symfony\Contracts\Service;

use Psr\Container\ContainerInterface;

/**
 * Implementation of ServiceSubscriberInterface that determines subscribed services from
 * private method return types. Service ids are available as "ClassName::methodName".
 *
 * @author Kevin Bond <kevinbond@gmail.com>
 */
trait ServiceSubscriberTrait
{
    /** @var ContainerInterface */
    protected $container;

    public static function getSubscribedServices(): array
    {
        static $services;

        if (null !== $services) {
            return $services;
        }

        $services = \is_callable(['parent', __FUNCTION__]) ? parent::getSubscribedServices() : [];

        foreach ((new \ReflectionClass(self::class))->getMethods() as $method) {
            if ($method->isStatic() || $method->isAbstract() || $method->isGenerator() || $method->isInternal() || $method->getNumberOfRequiredParameters()) {
                continue;
            }

            if (self::class === $method->getDeclaringClass()->name && ($returnType = $method->getReturnType()) && !$returnType->isBuiltin()) {
                $services[self::class.'::'.$method->name] = '?'.($returnType instanceof \ReflectionNamedType ? $returnType->getName() : $type);
            }
        }

        return $services;
    }

    /**
     * @required
     */
    public function setContainer(ContainerInterface $container)
    {
        $this->container = $container;

        if (\is_callable(['parent', __FUNCTION__])) {
            return parent::setContainer($container);
        }

        return null;
    }
}
PKϤ$Z�v���$service-contracts/ResetInterface.phpnu�[���<?php

/*
 * This file is part of the Symfony package.
 *
 * (c) Fabien Potencier <fabien@symfony.com>
 *
 * For the full copyright and license information, please view the LICENSE
 * file that was distributed with this source code.
 */

namespace Symfony\Contracts\Service;

/**
 * Provides a way to reset an object to its initial state.
 *
 * When calling the "reset()" method on an object, it should be put back to its
 * initial state. This usually means clearing any internal buffers and forwarding
 * the call to internal dependencies. All properties of the object should be put
 * back to the same state it had when it was first ready to use.
 *
 * This method could be called, for example, to recycle objects that are used as
 * services, so that they can be used to handle several requests in the same
 * process loop (note that we advise making your services stateless instead of
 * implementing this interface when possible.)
 */
interface ResetInterface
{
    public function reset();
}
PKϤ$Z�!��OO-service-contracts/Test/ServiceLocatorTest.phpnu�[���<?php

/*
 * This file is part of the Symfony package.
 *
 * (c) Fabien Potencier <fabien@symfony.com>
 *
 * For the full copyright and license information, please view the LICENSE
 * file that was distributed with this source code.
 */

namespace Symfony\Contracts\Service\Test;

use PHPUnit\Framework\TestCase;
use Psr\Container\ContainerInterface;
use Symfony\Contracts\Service\ServiceLocatorTrait;

abstract class ServiceLocatorTest extends TestCase
{
    protected function getServiceLocator(array $factories)
    {
        return new class($factories) implements ContainerInterface {
            use ServiceLocatorTrait;
        };
    }

    public function testHas()
    {
        $locator = $this->getServiceLocator([
            'foo' => function () { return 'bar'; },
            'bar' => function () { return 'baz'; },
            function () { return 'dummy'; },
        ]);

        $this->assertTrue($locator->has('foo'));
        $this->assertTrue($locator->has('bar'));
        $this->assertFalse($locator->has('dummy'));
    }

    public function testGet()
    {
        $locator = $this->getServiceLocator([
            'foo' => function () { return 'bar'; },
            'bar' => function () { return 'baz'; },
        ]);

        $this->assertSame('bar', $locator->get('foo'));
        $this->assertSame('baz', $locator->get('bar'));
    }

    public function testGetDoesNotMemoize()
    {
        $i = 0;
        $locator = $this->getServiceLocator([
            'foo' => function () use (&$i) {
                ++$i;

                return 'bar';
            },
        ]);

        $this->assertSame('bar', $locator->get('foo'));
        $this->assertSame('bar', $locator->get('foo'));
        $this->assertSame(2, $i);
    }

    public function testThrowsOnUndefinedInternalService()
    {
        if (!$this->getExpectedException()) {
            $this->expectException('Psr\Container\NotFoundExceptionInterface');
            $this->expectExceptionMessage('The service "foo" has a dependency on a non-existent service "bar". This locator only knows about the "foo" service.');
        }
        $locator = $this->getServiceLocator([
            'foo' => function () use (&$locator) { return $locator->get('bar'); },
        ]);

        $locator->get('foo');
    }

    public function testThrowsOnCircularReference()
    {
        $this->expectException('Psr\Container\ContainerExceptionInterface');
        $this->expectExceptionMessage('Circular reference detected for service "bar", path: "bar -> baz -> bar".');
        $locator = $this->getServiceLocator([
            'foo' => function () use (&$locator) { return $locator->get('bar'); },
            'bar' => function () use (&$locator) { return $locator->get('baz'); },
            'baz' => function () use (&$locator) { return $locator->get('bar'); },
        ]);

        $locator->get('foo');
    }
}
PKϤ$Z��MNNservice-contracts/README.mdnu�[���Symfony Service Contracts
=========================

A set of abstractions extracted out of the Symfony components.

Can be used to build on semantics that the Symfony components proved useful - and
that already have battle tested implementations.

See https://github.com/symfony/contracts/blob/master/README.md for more information.
PKϤ$Z�mXº�.service-contracts/ServiceProviderInterface.phpnu�[���<?php

/*
 * This file is part of the Symfony package.
 *
 * (c) Fabien Potencier <fabien@symfony.com>
 *
 * For the full copyright and license information, please view the LICENSE
 * file that was distributed with this source code.
 */

namespace Symfony\Contracts\Service;

use Psr\Container\ContainerInterface;

/**
 * A ServiceProviderInterface exposes the identifiers and the types of services provided by a container.
 *
 * @author Nicolas Grekas <p@tchwork.com>
 * @author Mateusz Sip <mateusz.sip@gmail.com>
 */
interface ServiceProviderInterface extends ContainerInterface
{
    /**
     * Returns an associative array of service types keyed by the identifiers provided by the current container.
     *
     * Examples:
     *
     *  * ['logger' => 'Psr\Log\LoggerInterface'] means the object provides a service named "logger" that implements Psr\Log\LoggerInterface
     *  * ['foo' => '?'] means the container provides service name "foo" of unspecified type
     *  * ['bar' => '?Bar\Baz'] means the container provides a service "bar" of type Bar\Baz|null
     *
     * @return string[] The provided service types, keyed by service names
     */
    public function getProvidedServices(): array;
}
PKϤ$ZSR����0service-contracts/ServiceSubscriberInterface.phpnu�[���<?php

/*
 * This file is part of the Symfony package.
 *
 * (c) Fabien Potencier <fabien@symfony.com>
 *
 * For the full copyright and license information, please view the LICENSE
 * file that was distributed with this source code.
 */

namespace Symfony\Contracts\Service;

/**
 * A ServiceSubscriber exposes its dependencies via the static {@link getSubscribedServices} method.
 *
 * The getSubscribedServices method returns an array of service types required by such instances,
 * optionally keyed by the service names used internally. Service types that start with an interrogation
 * mark "?" are optional, while the other ones are mandatory service dependencies.
 *
 * The injected service locators SHOULD NOT allow access to any other services not specified by the method.
 *
 * It is expected that ServiceSubscriber instances consume PSR-11-based service locators internally.
 * This interface does not dictate any injection method for these service locators, although constructor
 * injection is recommended.
 *
 * @author Nicolas Grekas <p@tchwork.com>
 */
interface ServiceSubscriberInterface
{
    /**
     * Returns an array of service types required by such instances, optionally keyed by the service names used internally.
     *
     * For mandatory dependencies:
     *
     *  * ['logger' => 'Psr\Log\LoggerInterface'] means the objects use the "logger" name
     *    internally to fetch a service which must implement Psr\Log\LoggerInterface.
     *  * ['loggers' => 'Psr\Log\LoggerInterface[]'] means the objects use the "loggers" name
     *    internally to fetch an iterable of Psr\Log\LoggerInterface instances.
     *  * ['Psr\Log\LoggerInterface'] is a shortcut for
     *  * ['Psr\Log\LoggerInterface' => 'Psr\Log\LoggerInterface']
     *
     * otherwise:
     *
     *  * ['logger' => '?Psr\Log\LoggerInterface'] denotes an optional dependency
     *  * ['loggers' => '?Psr\Log\LoggerInterface[]'] denotes an optional iterable dependency
     *  * ['?Psr\Log\LoggerInterface'] is a shortcut for
     *  * ['Psr\Log\LoggerInterface' => '?Psr\Log\LoggerInterface']
     *
     * @return array The required service types, optionally keyed by service names
     */
    public static function getSubscribedServices();
}
PKϤ$Z�'�e��)service-contracts/ServiceLocatorTrait.phpnu�[���<?php

/*
 * This file is part of the Symfony package.
 *
 * (c) Fabien Potencier <fabien@symfony.com>
 *
 * For the full copyright and license information, please view the LICENSE
 * file that was distributed with this source code.
 */

namespace Symfony\Contracts\Service;

use Psr\Container\ContainerExceptionInterface;
use Psr\Container\NotFoundExceptionInterface;

// Help opcache.preload discover always-needed symbols
class_exists(ContainerExceptionInterface::class);
class_exists(NotFoundExceptionInterface::class);

/**
 * A trait to help implement ServiceProviderInterface.
 *
 * @author Robin Chalas <robin.chalas@gmail.com>
 * @author Nicolas Grekas <p@tchwork.com>
 */
trait ServiceLocatorTrait
{
    private $factories;
    private $loading = [];
    private $providedTypes;

    /**
     * @param callable[] $factories
     */
    public function __construct(array $factories)
    {
        $this->factories = $factories;
    }

    /**
     * {@inheritdoc}
     *
     * @return bool
     */
    public function has($id)
    {
        return isset($this->factories[$id]);
    }

    /**
     * {@inheritdoc}
     */
    public function get($id)
    {
        if (!isset($this->factories[$id])) {
            throw $this->createNotFoundException($id);
        }

        if (isset($this->loading[$id])) {
            $ids = array_values($this->loading);
            $ids = \array_slice($this->loading, array_search($id, $ids));
            $ids[] = $id;

            throw $this->createCircularReferenceException($id, $ids);
        }

        $this->loading[$id] = $id;
        try {
            return $this->factories[$id]($this);
        } finally {
            unset($this->loading[$id]);
        }
    }

    /**
     * {@inheritdoc}
     */
    public function getProvidedServices(): array
    {
        if (null === $this->providedTypes) {
            $this->providedTypes = [];

            foreach ($this->factories as $name => $factory) {
                if (!\is_callable($factory)) {
                    $this->providedTypes[$name] = '?';
                } else {
                    $type = (new \ReflectionFunction($factory))->getReturnType();

                    $this->providedTypes[$name] = $type ? ($type->allowsNull() ? '?' : '').($type instanceof \ReflectionNamedType ? $type->getName() : $type) : '?';
                }
            }
        }

        return $this->providedTypes;
    }

    private function createNotFoundException(string $id): NotFoundExceptionInterface
    {
        if (!$alternatives = array_keys($this->factories)) {
            $message = 'is empty...';
        } else {
            $last = array_pop($alternatives);
            if ($alternatives) {
                $message = sprintf('only knows about the "%s" and "%s" services.', implode('", "', $alternatives), $last);
            } else {
                $message = sprintf('only knows about the "%s" service.', $last);
            }
        }

        if ($this->loading) {
            $message = sprintf('The service "%s" has a dependency on a non-existent service "%s". This locator %s', end($this->loading), $id, $message);
        } else {
            $message = sprintf('Service "%s" not found: the current service locator %s', $id, $message);
        }

        return new class($message) extends \InvalidArgumentException implements NotFoundExceptionInterface {
        };
    }

    private function createCircularReferenceException(string $id, array $path): ContainerExceptionInterface
    {
        return new class(sprintf('Circular reference detected for service "%s", path: "%s".', $id, implode(' -> ', $path))) extends \RuntimeException implements ContainerExceptionInterface {
        };
    }
}
PKϤ$Z��� ��(service-contracts/Attribute/Required.phpnu�[���<?php

/*
 * This file is part of the Symfony package.
 *
 * (c) Fabien Potencier <fabien@symfony.com>
 *
 * For the full copyright and license information, please view the LICENSE
 * file that was distributed with this source code.
 */

namespace Symfony\Contracts\Service\Attribute;

use Attribute;

/**
 * A required dependency.
 *
 * This attribute indicates that a property holds a required dependency. The annotated property or method should be
 * considered during the instantiation process of the containing class.
 *
 * @author Alexander M. Turek <me@derrabus.de>
 */
#[Attribute(Attribute::TARGET_METHOD | Attribute::TARGET_PROPERTY)]
final class Required
{
}
PKϤ$Z�����service-contracts/CHANGELOG.mdnu�[���CHANGELOG
=========

The changelog is maintained for all Symfony contracts at the following URL:
https://github.com/symfony/contracts/blob/master/CHANGELOG.md
PKϤ$Zi8�z))service-contracts/LICENSEnu�[���Copyright (c) 2018-2020 Fabien Potencier

Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is furnished
to do so, subject to the following conditions:

The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.

THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
THE SOFTWARE.
PKϤ$Z�8��var-exporter/README.mdnu�[���VarExporter Component
=====================

The VarExporter component allows exporting any serializable PHP data structure to
plain PHP code. While doing so, it preserves all the semantics associated with
the serialization mechanism of PHP (`__wakeup`, `__sleep`, `Serializable`,
`__serialize`, `__unserialize`).

It also provides an instantiator that allows creating and populating objects
without calling their constructor nor any other methods.

The reason to use this component *vs* `serialize()` or
[igbinary](https://github.com/igbinary/igbinary) is performance: thanks to
OPcache, the resulting code is significantly faster and more memory efficient
than using `unserialize()` or `igbinary_unserialize()`.

Unlike `var_export()`, this works on any serializable PHP value.

It also provides a few improvements over `var_export()`/`serialize()`:

 * the output is PSR-2 compatible;
 * the output can be re-indented without messing up with `\r` or `\n` in the data
 * missing classes throw a `ClassNotFoundException` instead of being unserialized to
   `PHP_Incomplete_Class` objects;
 * references involving `SplObjectStorage`, `ArrayObject` or `ArrayIterator`
   instances are preserved;
 * `Reflection*`, `IteratorIterator` and `RecursiveIteratorIterator` classes
   throw an exception when being serialized (their unserialized version is broken
   anyway, see https://bugs.php.net/76737).

Resources
---------

 * [Documentation](https://symfony.com/doc/current/components/var_exporter.html)
 * [Contributing](https://symfony.com/doc/current/contributing/index.html)
 * [Report issues](https://github.com/symfony/symfony/issues) and
   [send Pull Requests](https://github.com/symfony/symfony/pulls)
   in the [main Symfony repository](https://github.com/symfony/symfony)
PKϤ$Z�'/IVV-var-exporter/Exception/ExceptionInterface.phpnu�[���<?php

/*
 * This file is part of the Symfony package.
 *
 * (c) Fabien Potencier <fabien@symfony.com>
 *
 * For the full copyright and license information, please view the LICENSE
 * file that was distributed with this source code.
 */

namespace Symfony\Component\VarExporter\Exception;

interface ExceptionInterface extends \Throwable
{
}
PKϤ$Zs��..7var-exporter/Exception/NotInstantiableTypeException.phpnu�[���<?php

/*
 * This file is part of the Symfony package.
 *
 * (c) Fabien Potencier <fabien@symfony.com>
 *
 * For the full copyright and license information, please view the LICENSE
 * file that was distributed with this source code.
 */

namespace Symfony\Component\VarExporter\Exception;

class NotInstantiableTypeException extends \Exception implements ExceptionInterface
{
    public function __construct(string $type, \Throwable $previous = null)
    {
        parent::__construct(sprintf('Type "%s" is not instantiable.', $type), 0, $previous);
    }
}
PKϤ$Z�v_!!1var-exporter/Exception/ClassNotFoundException.phpnu�[���<?php

/*
 * This file is part of the Symfony package.
 *
 * (c) Fabien Potencier <fabien@symfony.com>
 *
 * For the full copyright and license information, please view the LICENSE
 * file that was distributed with this source code.
 */

namespace Symfony\Component\VarExporter\Exception;

class ClassNotFoundException extends \Exception implements ExceptionInterface
{
    public function __construct(string $class, \Throwable $previous = null)
    {
        parent::__construct(sprintf('Class "%s" not found.', $class), 0, $previous);
    }
}
PKϤ$Z��^��� var-exporter/Internal/Values.phpnu�[���<?php

/*
 * This file is part of the Symfony package.
 *
 * (c) Fabien Potencier <fabien@symfony.com>
 *
 * For the full copyright and license information, please view the LICENSE
 * file that was distributed with this source code.
 */

namespace Symfony\Component\VarExporter\Internal;

/**
 * @author Nicolas Grekas <p@tchwork.com>
 *
 * @internal
 */
class Values
{
    public $values;

    public function __construct(array $values)
    {
        $this->values = $values;
    }
}
PKϤ$Z���>>"var-exporter/Internal/Registry.phpnu�[���<?php

/*
 * This file is part of the Symfony package.
 *
 * (c) Fabien Potencier <fabien@symfony.com>
 *
 * For the full copyright and license information, please view the LICENSE
 * file that was distributed with this source code.
 */

namespace Symfony\Component\VarExporter\Internal;

use Symfony\Component\VarExporter\Exception\ClassNotFoundException;
use Symfony\Component\VarExporter\Exception\NotInstantiableTypeException;

/**
 * @author Nicolas Grekas <p@tchwork.com>
 *
 * @internal
 */
class Registry
{
    public static $reflectors = [];
    public static $prototypes = [];
    public static $factories = [];
    public static $cloneable = [];
    public static $instantiableWithoutConstructor = [];

    public $classes = [];

    public function __construct(array $classes)
    {
        $this->classes = $classes;
    }

    public static function unserialize($objects, $serializables)
    {
        $unserializeCallback = ini_set('unserialize_callback_func', __CLASS__.'::getClassReflector');

        try {
            foreach ($serializables as $k => $v) {
                $objects[$k] = unserialize($v);
            }
        } finally {
            ini_set('unserialize_callback_func', $unserializeCallback);
        }

        return $objects;
    }

    public static function p($class)
    {
        self::getClassReflector($class, true, true);

        return self::$prototypes[$class];
    }

    public static function f($class)
    {
        $reflector = self::$reflectors[$class] ?? self::getClassReflector($class, true, false);

        return self::$factories[$class] = \Closure::fromCallable([$reflector, 'newInstanceWithoutConstructor']);
    }

    public static function getClassReflector($class, $instantiableWithoutConstructor = false, $cloneable = null)
    {
        if (!($isClass = class_exists($class)) && !interface_exists($class, false) && !trait_exists($class, false)) {
            throw new ClassNotFoundException($class);
        }
        $reflector = new \ReflectionClass($class);

        if ($instantiableWithoutConstructor) {
            $proto = $reflector->newInstanceWithoutConstructor();
        } elseif (!$isClass || $reflector->isAbstract()) {
            throw new NotInstantiableTypeException($class);
        } elseif ($reflector->name !== $class) {
            $reflector = self::$reflectors[$name = $reflector->name] ?? self::getClassReflector($name, false, $cloneable);
            self::$cloneable[$class] = self::$cloneable[$name];
            self::$instantiableWithoutConstructor[$class] = self::$instantiableWithoutConstructor[$name];
            self::$prototypes[$class] = self::$prototypes[$name];

            return self::$reflectors[$class] = $reflector;
        } else {
            try {
                $proto = $reflector->newInstanceWithoutConstructor();
                $instantiableWithoutConstructor = true;
            } catch (\ReflectionException $e) {
                $proto = $reflector->implementsInterface('Serializable') && !method_exists($class, '__unserialize') ? 'C:' : 'O:';
                if ('C:' === $proto && !$reflector->getMethod('unserialize')->isInternal()) {
                    $proto = null;
                } else {
                    try {
                        $proto = @unserialize($proto.\strlen($class).':"'.$class.'":0:{}');
                    } catch (\Exception $e) {
                        if (__FILE__ !== $e->getFile()) {
                            throw $e;
                        }
                        throw new NotInstantiableTypeException($class, $e);
                    }
                    if (false === $proto) {
                        throw new NotInstantiableTypeException($class);
                    }
                }
            }
            if (null !== $proto && !$proto instanceof \Throwable && !$proto instanceof \Serializable && !method_exists($class, '__sleep') && (\PHP_VERSION_ID < 70400 || !method_exists($class, '__serialize'))) {
                try {
                    serialize($proto);
                } catch (\Exception $e) {
                    throw new NotInstantiableTypeException($class, $e);
                }
            }
        }

        if (null === $cloneable) {
            if (($proto instanceof \Reflector || $proto instanceof \ReflectionGenerator || $proto instanceof \ReflectionType || $proto instanceof \IteratorIterator || $proto instanceof \RecursiveIteratorIterator) && (!$proto instanceof \Serializable && !method_exists($proto, '__wakeup') && (\PHP_VERSION_ID < 70400 || !method_exists($class, '__unserialize')))) {
                throw new NotInstantiableTypeException($class);
            }

            $cloneable = $reflector->isCloneable() && !$reflector->hasMethod('__clone');
        }

        self::$cloneable[$class] = $cloneable;
        self::$instantiableWithoutConstructor[$class] = $instantiableWithoutConstructor;
        self::$prototypes[$class] = $proto;

        if ($proto instanceof \Throwable) {
            static $setTrace;

            if (null === $setTrace) {
                $setTrace = [
                    new \ReflectionProperty(\Error::class, 'trace'),
                    new \ReflectionProperty(\Exception::class, 'trace'),
                ];
                $setTrace[0]->setAccessible(true);
                $setTrace[1]->setAccessible(true);
                $setTrace[0] = \Closure::fromCallable([$setTrace[0], 'setValue']);
                $setTrace[1] = \Closure::fromCallable([$setTrace[1], 'setValue']);
            }

            $setTrace[$proto instanceof \Exception]($proto, []);
        }

        return self::$reflectors[$class] = $reflector;
    }
}
PKϤ$Z��..#var-exporter/Internal/Reference.phpnu�[���<?php

/*
 * This file is part of the Symfony package.
 *
 * (c) Fabien Potencier <fabien@symfony.com>
 *
 * For the full copyright and license information, please view the LICENSE
 * file that was distributed with this source code.
 */

namespace Symfony\Component\VarExporter\Internal;

/**
 * @author Nicolas Grekas <p@tchwork.com>
 *
 * @internal
 */
class Reference
{
    public $id;
    public $value;
    public $count = 0;

    public function __construct(int $id, $value = null)
    {
        $this->id = $id;
        $this->value = $value;
    }
}
PKϤ$Z�*��>�>"var-exporter/Internal/Exporter.phpnu�[���<?php

/*
 * This file is part of the Symfony package.
 *
 * (c) Fabien Potencier <fabien@symfony.com>
 *
 * For the full copyright and license information, please view the LICENSE
 * file that was distributed with this source code.
 */

namespace Symfony\Component\VarExporter\Internal;

use Symfony\Component\VarExporter\Exception\NotInstantiableTypeException;

/**
 * @author Nicolas Grekas <p@tchwork.com>
 *
 * @internal
 */
class Exporter
{
    /**
     * Prepares an array of values for VarExporter.
     *
     * For performance this method is public and has no type-hints.
     *
     * @param array             &$values
     * @param \SplObjectStorage $objectsPool
     * @param array             &$refsPool
     * @param int               &$objectsCount
     * @param bool              &$valuesAreStatic
     *
     * @throws NotInstantiableTypeException When a value cannot be serialized
     */
    public static function prepare($values, $objectsPool, &$refsPool, &$objectsCount, &$valuesAreStatic): array
    {
        $refs = $values;
        foreach ($values as $k => $value) {
            if (\is_resource($value)) {
                throw new NotInstantiableTypeException(get_resource_type($value).' resource');
            }
            $refs[$k] = $objectsPool;

            if ($isRef = !$valueIsStatic = $values[$k] !== $objectsPool) {
                $values[$k] = &$value; // Break hard references to make $values completely
                unset($value);         // independent from the original structure
                $refs[$k] = $value = $values[$k];
                if ($value instanceof Reference && 0 > $value->id) {
                    $valuesAreStatic = false;
                    ++$value->count;
                    continue;
                }
                $refsPool[] = [&$refs[$k], $value, &$value];
                $refs[$k] = $values[$k] = new Reference(-\count($refsPool), $value);
            }

            if (\is_array($value)) {
                if ($value) {
                    $value = self::prepare($value, $objectsPool, $refsPool, $objectsCount, $valueIsStatic);
                }
                goto handle_value;
            } elseif (!\is_object($value) || $value instanceof \UnitEnum) {
                goto handle_value;
            }

            $valueIsStatic = false;
            if (isset($objectsPool[$value])) {
                ++$objectsCount;
                $value = new Reference($objectsPool[$value][0]);
                goto handle_value;
            }

            $class = \get_class($value);
            $reflector = Registry::$reflectors[$class] ?? Registry::getClassReflector($class);

            if ($reflector->hasMethod('__serialize')) {
                if (!$reflector->getMethod('__serialize')->isPublic()) {
                    throw new \Error(sprintf('Call to %s method "%s::__serialize()".', $reflector->getMethod('__serialize')->isProtected() ? 'protected' : 'private', $class));
                }

                if (!\is_array($properties = $value->__serialize())) {
                    throw new \TypeError($class.'::__serialize() must return an array');
                }

                goto prepare_value;
            }

            $properties = [];
            $sleep = null;
            $proto = Registry::$prototypes[$class];

            if (($value instanceof \ArrayIterator || $value instanceof \ArrayObject) && null !== $proto) {
                // ArrayIterator and ArrayObject need special care because their "flags"
                // option changes the behavior of the (array) casting operator.
                [$arrayValue, $properties] = self::getArrayObjectProperties($value, $proto);

                // populates Registry::$prototypes[$class] with a new instance
                Registry::getClassReflector($class, Registry::$instantiableWithoutConstructor[$class], Registry::$cloneable[$class]);
            } elseif ($value instanceof \SplObjectStorage && Registry::$cloneable[$class] && null !== $proto) {
                // By implementing Serializable, SplObjectStorage breaks
                // internal references; let's deal with it on our own.
                foreach (clone $value as $v) {
                    $properties[] = $v;
                    $properties[] = $value[$v];
                }
                $properties = ['SplObjectStorage' => ["\0" => $properties]];
                $arrayValue = (array) $value;
            } elseif ($value instanceof \Serializable
                || $value instanceof \__PHP_Incomplete_Class
                || \PHP_VERSION_ID < 80200 && $value instanceof \DatePeriod
            ) {
                ++$objectsCount;
                $objectsPool[$value] = [$id = \count($objectsPool), serialize($value), [], 0];
                $value = new Reference($id);
                goto handle_value;
            } else {
                if (method_exists($class, '__sleep')) {
                    if (!\is_array($sleep = $value->__sleep())) {
                        trigger_error('serialize(): __sleep should return an array only containing the names of instance-variables to serialize', \E_USER_NOTICE);
                        $value = null;
                        goto handle_value;
                    }
                    $sleep = array_flip($sleep);
                }

                $arrayValue = (array) $value;
            }

            $proto = (array) $proto;

            foreach ($arrayValue as $name => $v) {
                $i = 0;
                $n = (string) $name;
                if ('' === $n || "\0" !== $n[0]) {
                    $c = \PHP_VERSION_ID >= 80100 && $reflector->hasProperty($n) && ($p = $reflector->getProperty($n))->isReadOnly() ? $p->class : 'stdClass';
                } elseif ('*' === $n[1]) {
                    $n = substr($n, 3);
                    $c = $reflector->getProperty($n)->class;
                    if ('Error' === $c) {
                        $c = 'TypeError';
                    } elseif ('Exception' === $c) {
                        $c = 'ErrorException';
                    }
                } else {
                    $i = strpos($n, "\0", 2);
                    $c = substr($n, 1, $i - 1);
                    $n = substr($n, 1 + $i);
                }
                if (null !== $sleep) {
                    if (!isset($sleep[$n]) || ($i && $c !== $class)) {
                        continue;
                    }
                    $sleep[$n] = false;
                }
                if (!\array_key_exists($name, $proto) || $proto[$name] !== $v || "\x00Error\x00trace" === $name || "\x00Exception\x00trace" === $name) {
                    $properties[$c][$n] = $v;
                }
            }
            if ($sleep) {
                foreach ($sleep as $n => $v) {
                    if (false !== $v) {
                        trigger_error(sprintf('serialize(): "%s" returned as member variable from __sleep() but does not exist', $n), \E_USER_NOTICE);
                    }
                }
            }

            prepare_value:
            $objectsPool[$value] = [$id = \count($objectsPool)];
            $properties = self::prepare($properties, $objectsPool, $refsPool, $objectsCount, $valueIsStatic);
            ++$objectsCount;
            $objectsPool[$value] = [$id, $class, $properties, method_exists($class, '__unserialize') ? -$objectsCount : (method_exists($class, '__wakeup') ? $objectsCount : 0)];

            $value = new Reference($id);

            handle_value:
            if ($isRef) {
                unset($value); // Break the hard reference created above
            } elseif (!$valueIsStatic) {
                $values[$k] = $value;
            }
            $valuesAreStatic = $valueIsStatic && $valuesAreStatic;
        }

        return $values;
    }

    public static function export($value, string $indent = '')
    {
        switch (true) {
            case \is_int($value) || \is_float($value): return var_export($value, true);
            case [] === $value: return '[]';
            case false === $value: return 'false';
            case true === $value: return 'true';
            case null === $value: return 'null';
            case '' === $value: return "''";
            case $value instanceof \UnitEnum: return ltrim(var_export($value, true), '\\');
        }

        if ($value instanceof Reference) {
            if (0 <= $value->id) {
                return '$o['.$value->id.']';
            }
            if (!$value->count) {
                return self::export($value->value, $indent);
            }
            $value = -$value->id;

            return '&$r['.$value.']';
        }
        $subIndent = $indent.'    ';

        if (\is_string($value)) {
            $code = sprintf("'%s'", addcslashes($value, "'\\"));

            $code = preg_replace_callback("/((?:[\\0\\r\\n]|\u{202A}|\u{202B}|\u{202D}|\u{202E}|\u{2066}|\u{2067}|\u{2068}|\u{202C}|\u{2069})++)(.)/", function ($m) use ($subIndent) {
                $m[1] = sprintf('\'."%s".\'', str_replace(
                    ["\0", "\r", "\n", "\u{202A}", "\u{202B}", "\u{202D}", "\u{202E}", "\u{2066}", "\u{2067}", "\u{2068}", "\u{202C}", "\u{2069}", '\n\\'],
                    ['\0', '\r', '\n', '\u{202A}', '\u{202B}', '\u{202D}', '\u{202E}', '\u{2066}', '\u{2067}', '\u{2068}', '\u{202C}', '\u{2069}', '\n"'."\n".$subIndent.'."\\'],
                    $m[1]
                ));

                if ("'" === $m[2]) {
                    return substr($m[1], 0, -2);
                }

                if ('n".\'' === substr($m[1], -4)) {
                    return substr_replace($m[1], "\n".$subIndent.".'".$m[2], -2);
                }

                return $m[1].$m[2];
            }, $code, -1, $count);

            if ($count && str_starts_with($code, "''.")) {
                $code = substr($code, 3);
            }

            return $code;
        }

        if (\is_array($value)) {
            $j = -1;
            $code = '';
            foreach ($value as $k => $v) {
                $code .= $subIndent;
                if (!\is_int($k) || 1 !== $k - $j) {
                    $code .= self::export($k, $subIndent).' => ';
                }
                if (\is_int($k) && $k > $j) {
                    $j = $k;
                }
                $code .= self::export($v, $subIndent).",\n";
            }

            return "[\n".$code.$indent.']';
        }

        if ($value instanceof Values) {
            $code = $subIndent."\$r = [],\n";
            foreach ($value->values as $k => $v) {
                $code .= $subIndent.'$r['.$k.'] = '.self::export($v, $subIndent).",\n";
            }

            return "[\n".$code.$indent.']';
        }

        if ($value instanceof Registry) {
            return self::exportRegistry($value, $indent, $subIndent);
        }

        if ($value instanceof Hydrator) {
            return self::exportHydrator($value, $indent, $subIndent);
        }

        throw new \UnexpectedValueException(sprintf('Cannot export value of type "%s".', get_debug_type($value)));
    }

    private static function exportRegistry(Registry $value, string $indent, string $subIndent): string
    {
        $code = '';
        $serializables = [];
        $seen = [];
        $prototypesAccess = 0;
        $factoriesAccess = 0;
        $r = '\\'.Registry::class;
        $j = -1;

        foreach ($value->classes as $k => $class) {
            if (':' === ($class[1] ?? null)) {
                $serializables[$k] = $class;
                continue;
            }
            if (!Registry::$instantiableWithoutConstructor[$class]) {
                if (is_subclass_of($class, 'Serializable') && !method_exists($class, '__unserialize')) {
                    $serializables[$k] = 'C:'.\strlen($class).':"'.$class.'":0:{}';
                } else {
                    $serializables[$k] = 'O:'.\strlen($class).':"'.$class.'":0:{}';
                }
                if (is_subclass_of($class, 'Throwable')) {
                    $eol = is_subclass_of($class, 'Error') ? "\0Error\0" : "\0Exception\0";
                    $serializables[$k] = substr_replace($serializables[$k], '1:{s:'.(5 + \strlen($eol)).':"'.$eol.'trace";a:0:{}}', -4);
                }
                continue;
            }
            $code .= $subIndent.(1 !== $k - $j ? $k.' => ' : '');
            $j = $k;
            $eol = ",\n";
            $c = '['.self::export($class).']';

            if ($seen[$class] ?? false) {
                if (Registry::$cloneable[$class]) {
                    ++$prototypesAccess;
                    $code .= 'clone $p'.$c;
                } else {
                    ++$factoriesAccess;
                    $code .= '$f'.$c.'()';
                }
            } else {
                $seen[$class] = true;
                if (Registry::$cloneable[$class]) {
                    $code .= 'clone ('.($prototypesAccess++ ? '$p' : '($p = &'.$r.'::$prototypes)').$c.' ?? '.$r.'::p';
                } else {
                    $code .= '('.($factoriesAccess++ ? '$f' : '($f = &'.$r.'::$factories)').$c.' ?? '.$r.'::f';
                    $eol = '()'.$eol;
                }
                $code .= '('.substr($c, 1, -1).'))';
            }
            $code .= $eol;
        }

        if (1 === $prototypesAccess) {
            $code = str_replace('($p = &'.$r.'::$prototypes)', $r.'::$prototypes', $code);
        }
        if (1 === $factoriesAccess) {
            $code = str_replace('($f = &'.$r.'::$factories)', $r.'::$factories', $code);
        }
        if ('' !== $code) {
            $code = "\n".$code.$indent;
        }

        if ($serializables) {
            $code = $r.'::unserialize(['.$code.'], '.self::export($serializables, $indent).')';
        } else {
            $code = '['.$code.']';
        }

        return '$o = '.$code;
    }

    private static function exportHydrator(Hydrator $value, string $indent, string $subIndent): string
    {
        $code = '';
        foreach ($value->properties as $class => $properties) {
            $code .= $subIndent.'    '.self::export($class).' => '.self::export($properties, $subIndent.'    ').",\n";
        }

        $code = [
            self::export($value->registry, $subIndent),
            self::export($value->values, $subIndent),
            '' !== $code ? "[\n".$code.$subIndent.']' : '[]',
            self::export($value->value, $subIndent),
            self::export($value->wakeups, $subIndent),
        ];

        return '\\'.\get_class($value)."::hydrate(\n".$subIndent.implode(",\n".$subIndent, $code)."\n".$indent.')';
    }

    /**
     * @param \ArrayIterator|\ArrayObject $value
     * @param \ArrayIterator|\ArrayObject $proto
     */
    private static function getArrayObjectProperties($value, $proto): array
    {
        $reflector = $value instanceof \ArrayIterator ? 'ArrayIterator' : 'ArrayObject';
        $reflector = Registry::$reflectors[$reflector] ?? Registry::getClassReflector($reflector);

        $properties = [
            $arrayValue = (array) $value,
            $reflector->getMethod('getFlags')->invoke($value),
            $value instanceof \ArrayObject ? $reflector->getMethod('getIteratorClass')->invoke($value) : 'ArrayIterator',
        ];

        $reflector = $reflector->getMethod('setFlags');
        $reflector->invoke($proto, \ArrayObject::STD_PROP_LIST);

        if ($properties[1] & \ArrayObject::STD_PROP_LIST) {
            $reflector->invoke($value, 0);
            $properties[0] = (array) $value;
        } else {
            $reflector->invoke($value, \ArrayObject::STD_PROP_LIST);
            $arrayValue = (array) $value;
        }
        $reflector->invoke($value, $properties[1]);

        if ([[], 0, 'ArrayIterator'] === $properties) {
            $properties = [];
        } else {
            if ('ArrayIterator' === $properties[2]) {
                unset($properties[2]);
            }
            $properties = [$reflector->class => ["\0" => $properties]];
        }

        return [$arrayValue, $properties];
    }
}
PKϤ$Z���V88"var-exporter/Internal/Hydrator.phpnu�[���<?php

/*
 * This file is part of the Symfony package.
 *
 * (c) Fabien Potencier <fabien@symfony.com>
 *
 * For the full copyright and license information, please view the LICENSE
 * file that was distributed with this source code.
 */

namespace Symfony\Component\VarExporter\Internal;

use Symfony\Component\VarExporter\Exception\ClassNotFoundException;

/**
 * @author Nicolas Grekas <p@tchwork.com>
 *
 * @internal
 */
class Hydrator
{
    public static $hydrators = [];

    public $registry;
    public $values;
    public $properties;
    public $value;
    public $wakeups;

    public function __construct(?Registry $registry, ?Values $values, array $properties, $value, array $wakeups)
    {
        $this->registry = $registry;
        $this->values = $values;
        $this->properties = $properties;
        $this->value = $value;
        $this->wakeups = $wakeups;
    }

    public static function hydrate($objects, $values, $properties, $value, $wakeups)
    {
        foreach ($properties as $class => $vars) {
            (self::$hydrators[$class] ?? self::getHydrator($class))($vars, $objects);
        }
        foreach ($wakeups as $k => $v) {
            if (\is_array($v)) {
                $objects[-$k]->__unserialize($v);
            } else {
                $objects[$v]->__wakeup();
            }
        }

        return $value;
    }

    public static function getHydrator($class)
    {
        switch ($class) {
            case 'stdClass':
                return self::$hydrators[$class] = static function ($properties, $objects) {
                    foreach ($properties as $name => $values) {
                        foreach ($values as $i => $v) {
                            $objects[$i]->$name = $v;
                        }
                    }
                };

            case 'ErrorException':
                return self::$hydrators[$class] = (self::$hydrators['stdClass'] ?? self::getHydrator('stdClass'))->bindTo(null, new class() extends \ErrorException {
                });

            case 'TypeError':
                return self::$hydrators[$class] = (self::$hydrators['stdClass'] ?? self::getHydrator('stdClass'))->bindTo(null, new class() extends \Error {
                });

            case 'SplObjectStorage':
                return self::$hydrators[$class] = static function ($properties, $objects) {
                    foreach ($properties as $name => $values) {
                        if ("\0" === $name) {
                            foreach ($values as $i => $v) {
                                for ($j = 0; $j < \count($v); ++$j) {
                                    $objects[$i]->attach($v[$j], $v[++$j]);
                                }
                            }
                            continue;
                        }
                        foreach ($values as $i => $v) {
                            $objects[$i]->$name = $v;
                        }
                    }
                };
        }

        if (!class_exists($class) && !interface_exists($class, false) && !trait_exists($class, false)) {
            throw new ClassNotFoundException($class);
        }
        $classReflector = new \ReflectionClass($class);

        switch ($class) {
            case 'ArrayIterator':
            case 'ArrayObject':
                $constructor = \Closure::fromCallable([$classReflector->getConstructor(), 'invokeArgs']);

                return self::$hydrators[$class] = static function ($properties, $objects) use ($constructor) {
                    foreach ($properties as $name => $values) {
                        if ("\0" !== $name) {
                            foreach ($values as $i => $v) {
                                $objects[$i]->$name = $v;
                            }
                        }
                    }
                    foreach ($properties["\0"] ?? [] as $i => $v) {
                        $constructor($objects[$i], $v);
                    }
                };
        }

        if (!$classReflector->isInternal()) {
            return self::$hydrators[$class] = (self::$hydrators['stdClass'] ?? self::getHydrator('stdClass'))->bindTo(null, $class);
        }

        if ($classReflector->name !== $class) {
            return self::$hydrators[$classReflector->name] ?? self::getHydrator($classReflector->name);
        }

        $propertySetters = [];
        foreach ($classReflector->getProperties() as $propertyReflector) {
            if (!$propertyReflector->isStatic()) {
                $propertyReflector->setAccessible(true);
                $propertySetters[$propertyReflector->name] = \Closure::fromCallable([$propertyReflector, 'setValue']);
            }
        }

        if (!$propertySetters) {
            return self::$hydrators[$class] = self::$hydrators['stdClass'] ?? self::getHydrator('stdClass');
        }

        return self::$hydrators[$class] = static function ($properties, $objects) use ($propertySetters) {
            foreach ($properties as $name => $values) {
                if ($setValue = $propertySetters[$name] ?? null) {
                    foreach ($values as $i => $v) {
                        $setValue($objects[$i], $v);
                    }
                    continue;
                }
                foreach ($values as $i => $v) {
                    $objects[$i]->$name = $v;
                }
            }
        };
    }
}
PKϤ$Z���var-exporter/CHANGELOG.mdnu�[���CHANGELOG
=========

5.1.0
-----

 * added argument `array &$foundClasses` to `VarExporter::export()` to ease with preloading exported values

4.2.0
-----

 * added the component
PKϤ$Z5�))var-exporter/LICENSEnu�[���Copyright (c) 2018-2022 Fabien Potencier

Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is furnished
to do so, subject to the following conditions:

The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.

THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
THE SOFTWARE.
PKϤ$ZZ�~J77var-exporter/VarExporter.phpnu�[���<?php

/*
 * This file is part of the Symfony package.
 *
 * (c) Fabien Potencier <fabien@symfony.com>
 *
 * For the full copyright and license information, please view the LICENSE
 * file that was distributed with this source code.
 */

namespace Symfony\Component\VarExporter;

use Symfony\Component\VarExporter\Exception\ExceptionInterface;
use Symfony\Component\VarExporter\Internal\Exporter;
use Symfony\Component\VarExporter\Internal\Hydrator;
use Symfony\Component\VarExporter\Internal\Registry;
use Symfony\Component\VarExporter\Internal\Values;

/**
 * Exports serializable PHP values to PHP code.
 *
 * VarExporter allows serializing PHP data structures to plain PHP code (like var_export())
 * while preserving all the semantics associated with serialize() (unlike var_export()).
 *
 * By leveraging OPcache, the generated PHP code is faster than doing the same with unserialize().
 *
 * @author Nicolas Grekas <p@tchwork.com>
 */
final class VarExporter
{
    /**
     * Exports a serializable PHP value to PHP code.
     *
     * @param mixed $value          The value to export
     * @param bool  &$isStaticValue Set to true after execution if the provided value is static, false otherwise
     * @param bool  &$classes       Classes found in the value are added to this list as both keys and values
     *
     * @throws ExceptionInterface When the provided value cannot be serialized
     */
    public static function export($value, bool &$isStaticValue = null, array &$foundClasses = []): string
    {
        $isStaticValue = true;

        if (!\is_object($value) && !(\is_array($value) && $value) && !\is_resource($value) || $value instanceof \UnitEnum) {
            return Exporter::export($value);
        }

        $objectsPool = new \SplObjectStorage();
        $refsPool = [];
        $objectsCount = 0;

        try {
            $value = Exporter::prepare([$value], $objectsPool, $refsPool, $objectsCount, $isStaticValue)[0];
        } finally {
            $references = [];
            foreach ($refsPool as $i => $v) {
                if ($v[0]->count) {
                    $references[1 + $i] = $v[2];
                }
                $v[0] = $v[1];
            }
        }

        if ($isStaticValue) {
            return Exporter::export($value);
        }

        $classes = [];
        $values = [];
        $states = [];
        foreach ($objectsPool as $i => $v) {
            [, $class, $values[], $wakeup] = $objectsPool[$v];
            $foundClasses[$class] = $classes[] = $class;

            if (0 < $wakeup) {
                $states[$wakeup] = $i;
            } elseif (0 > $wakeup) {
                $states[-$wakeup] = [$i, array_pop($values)];
                $values[] = [];
            }
        }
        ksort($states);

        $wakeups = [null];
        foreach ($states as $k => $v) {
            if (\is_array($v)) {
                $wakeups[-$v[0]] = $v[1];
            } else {
                $wakeups[] = $v;
            }
        }

        if (null === $wakeups[0]) {
            unset($wakeups[0]);
        }

        $properties = [];
        foreach ($values as $i => $vars) {
            foreach ($vars as $class => $values) {
                foreach ($values as $name => $v) {
                    $properties[$class][$name][$i] = $v;
                }
            }
        }

        if ($classes || $references) {
            $value = new Hydrator(new Registry($classes), $references ? new Values($references) : null, $properties, $value, $wakeups);
        } else {
            $isStaticValue = true;
        }

        return Exporter::export($value);
    }
}
PKϤ$ZAi@s^^var-exporter/Instantiator.phpnu�[���<?php

/*
 * This file is part of the Symfony package.
 *
 * (c) Fabien Potencier <fabien@symfony.com>
 *
 * For the full copyright and license information, please view the LICENSE
 * file that was distributed with this source code.
 */

namespace Symfony\Component\VarExporter;

use Symfony\Component\VarExporter\Exception\ExceptionInterface;
use Symfony\Component\VarExporter\Exception\NotInstantiableTypeException;
use Symfony\Component\VarExporter\Internal\Hydrator;
use Symfony\Component\VarExporter\Internal\Registry;

/**
 * A utility class to create objects without calling their constructor.
 *
 * @author Nicolas Grekas <p@tchwork.com>
 */
final class Instantiator
{
    /**
     * Creates an object and sets its properties without calling its constructor nor any other methods.
     *
     * For example:
     *
     *     // creates an empty instance of Foo
     *     Instantiator::instantiate(Foo::class);
     *
     *     // creates a Foo instance and sets one of its properties
     *     Instantiator::instantiate(Foo::class, ['propertyName' => $propertyValue]);
     *
     *     // creates a Foo instance and sets a private property defined on its parent Bar class
     *     Instantiator::instantiate(Foo::class, [], [
     *         Bar::class => ['privateBarProperty' => $propertyValue],
     *     ]);
     *
     * Instances of ArrayObject, ArrayIterator and SplObjectStorage can be created
     * by using the special "\0" property name to define their internal value:
     *
     *     // creates an SplObjectStorage where $info1 is attached to $obj1, etc.
     *     Instantiator::instantiate(SplObjectStorage::class, ["\0" => [$obj1, $info1, $obj2, $info2...]]);
     *
     *     // creates an ArrayObject populated with $inputArray
     *     Instantiator::instantiate(ArrayObject::class, ["\0" => [$inputArray]]);
     *
     * @param string $class             The class of the instance to create
     * @param array  $properties        The properties to set on the instance
     * @param array  $privateProperties The private properties to set on the instance,
     *                                  keyed by their declaring class
     *
     * @throws ExceptionInterface When the instance cannot be created
     */
    public static function instantiate(string $class, array $properties = [], array $privateProperties = []): object
    {
        $reflector = Registry::$reflectors[$class] ?? Registry::getClassReflector($class);

        if (Registry::$cloneable[$class]) {
            $wrappedInstance = [clone Registry::$prototypes[$class]];
        } elseif (Registry::$instantiableWithoutConstructor[$class]) {
            $wrappedInstance = [$reflector->newInstanceWithoutConstructor()];
        } elseif (null === Registry::$prototypes[$class]) {
            throw new NotInstantiableTypeException($class);
        } elseif ($reflector->implementsInterface('Serializable') && (\PHP_VERSION_ID < 70400 || !method_exists($class, '__unserialize'))) {
            $wrappedInstance = [unserialize('C:'.\strlen($class).':"'.$class.'":0:{}')];
        } else {
            $wrappedInstance = [unserialize('O:'.\strlen($class).':"'.$class.'":0:{}')];
        }

        if ($properties) {
            $privateProperties[$class] = isset($privateProperties[$class]) ? $properties + $privateProperties[$class] : $properties;
        }

        foreach ($privateProperties as $class => $properties) {
            if (!$properties) {
                continue;
            }
            foreach ($properties as $name => $value) {
                // because they're also used for "unserialization", hydrators
                // deal with array of instances, so we need to wrap values
                $properties[$name] = [$value];
            }
            (Hydrator::$hydrators[$class] ?? Hydrator::getHydrator($class))($properties, $wrappedInstance);
        }

        return $wrappedInstance[0];
    }
}
PKϤ$Zo��d�N�Nstring/AbstractString.phpnu�[���<?php

/*
 * This file is part of the Symfony package.
 *
 * (c) Fabien Potencier <fabien@symfony.com>
 *
 * For the full copyright and license information, please view the LICENSE
 * file that was distributed with this source code.
 */

namespace Symfony\Component\String;

use Symfony\Component\String\Exception\ExceptionInterface;
use Symfony\Component\String\Exception\InvalidArgumentException;
use Symfony\Component\String\Exception\RuntimeException;

/**
 * Represents a string of abstract characters.
 *
 * Unicode defines 3 types of "characters" (bytes, code points and grapheme clusters).
 * This class is the abstract type to use as a type-hint when the logic you want to
 * implement doesn't care about the exact variant it deals with.
 *
 * @author Nicolas Grekas <p@tchwork.com>
 * @author Hugo Hamon <hugohamon@neuf.fr>
 *
 * @throws ExceptionInterface
 */
abstract class AbstractString implements \Stringable, \JsonSerializable
{
    public const PREG_PATTERN_ORDER = \PREG_PATTERN_ORDER;
    public const PREG_SET_ORDER = \PREG_SET_ORDER;
    public const PREG_OFFSET_CAPTURE = \PREG_OFFSET_CAPTURE;
    public const PREG_UNMATCHED_AS_NULL = \PREG_UNMATCHED_AS_NULL;

    public const PREG_SPLIT = 0;
    public const PREG_SPLIT_NO_EMPTY = \PREG_SPLIT_NO_EMPTY;
    public const PREG_SPLIT_DELIM_CAPTURE = \PREG_SPLIT_DELIM_CAPTURE;
    public const PREG_SPLIT_OFFSET_CAPTURE = \PREG_SPLIT_OFFSET_CAPTURE;

    protected $string = '';
    protected $ignoreCase = false;

    abstract public function __construct(string $string = '');

    /**
     * Unwraps instances of AbstractString back to strings.
     *
     * @return string[]|array
     */
    public static function unwrap(array $values): array
    {
        foreach ($values as $k => $v) {
            if ($v instanceof self) {
                $values[$k] = $v->__toString();
            } elseif (\is_array($v) && $values[$k] !== $v = static::unwrap($v)) {
                $values[$k] = $v;
            }
        }

        return $values;
    }

    /**
     * Wraps (and normalizes) strings in instances of AbstractString.
     *
     * @return static[]|array
     */
    public static function wrap(array $values): array
    {
        $i = 0;
        $keys = null;

        foreach ($values as $k => $v) {
            if (\is_string($k) && '' !== $k && $k !== $j = (string) new static($k)) {
                $keys = $keys ?? array_keys($values);
                $keys[$i] = $j;
            }

            if (\is_string($v)) {
                $values[$k] = new static($v);
            } elseif (\is_array($v) && $values[$k] !== $v = static::wrap($v)) {
                $values[$k] = $v;
            }

            ++$i;
        }

        return null !== $keys ? array_combine($keys, $values) : $values;
    }

    /**
     * @param string|string[] $needle
     *
     * @return static
     */
    public function after($needle, bool $includeNeedle = false, int $offset = 0): self
    {
        $str = clone $this;
        $i = \PHP_INT_MAX;

        foreach ((array) $needle as $n) {
            $n = (string) $n;
            $j = $this->indexOf($n, $offset);

            if (null !== $j && $j < $i) {
                $i = $j;
                $str->string = $n;
            }
        }

        if (\PHP_INT_MAX === $i) {
            return $str;
        }

        if (!$includeNeedle) {
            $i += $str->length();
        }

        return $this->slice($i);
    }

    /**
     * @param string|string[] $needle
     *
     * @return static
     */
    public function afterLast($needle, bool $includeNeedle = false, int $offset = 0): self
    {
        $str = clone $this;
        $i = null;

        foreach ((array) $needle as $n) {
            $n = (string) $n;
            $j = $this->indexOfLast($n, $offset);

            if (null !== $j && $j >= $i) {
                $i = $offset = $j;
                $str->string = $n;
            }
        }

        if (null === $i) {
            return $str;
        }

        if (!$includeNeedle) {
            $i += $str->length();
        }

        return $this->slice($i);
    }

    /**
     * @return static
     */
    abstract public function append(string ...$suffix): self;

    /**
     * @param string|string[] $needle
     *
     * @return static
     */
    public function before($needle, bool $includeNeedle = false, int $offset = 0): self
    {
        $str = clone $this;
        $i = \PHP_INT_MAX;

        foreach ((array) $needle as $n) {
            $n = (string) $n;
            $j = $this->indexOf($n, $offset);

            if (null !== $j && $j < $i) {
                $i = $j;
                $str->string = $n;
            }
        }

        if (\PHP_INT_MAX === $i) {
            return $str;
        }

        if ($includeNeedle) {
            $i += $str->length();
        }

        return $this->slice(0, $i);
    }

    /**
     * @param string|string[] $needle
     *
     * @return static
     */
    public function beforeLast($needle, bool $includeNeedle = false, int $offset = 0): self
    {
        $str = clone $this;
        $i = null;

        foreach ((array) $needle as $n) {
            $n = (string) $n;
            $j = $this->indexOfLast($n, $offset);

            if (null !== $j && $j >= $i) {
                $i = $offset = $j;
                $str->string = $n;
            }
        }

        if (null === $i) {
            return $str;
        }

        if ($includeNeedle) {
            $i += $str->length();
        }

        return $this->slice(0, $i);
    }

    /**
     * @return int[]
     */
    public function bytesAt(int $offset): array
    {
        $str = $this->slice($offset, 1);

        return '' === $str->string ? [] : array_values(unpack('C*', $str->string));
    }

    /**
     * @return static
     */
    abstract public function camel(): self;

    /**
     * @return static[]
     */
    abstract public function chunk(int $length = 1): array;

    /**
     * @return static
     */
    public function collapseWhitespace(): self
    {
        $str = clone $this;
        $str->string = trim(preg_replace('/(?:\s{2,}+|[^\S ])/', ' ', $str->string));

        return $str;
    }

    /**
     * @param string|string[] $needle
     */
    public function containsAny($needle): bool
    {
        return null !== $this->indexOf($needle);
    }

    /**
     * @param string|string[] $suffix
     */
    public function endsWith($suffix): bool
    {
        if (!\is_array($suffix) && !$suffix instanceof \Traversable) {
            throw new \TypeError(sprintf('Method "%s()" must be overridden by class "%s" to deal with non-iterable values.', __FUNCTION__, static::class));
        }

        foreach ($suffix as $s) {
            if ($this->endsWith((string) $s)) {
                return true;
            }
        }

        return false;
    }

    /**
     * @return static
     */
    public function ensureEnd(string $suffix): self
    {
        if (!$this->endsWith($suffix)) {
            return $this->append($suffix);
        }

        $suffix = preg_quote($suffix);
        $regex = '{('.$suffix.')(?:'.$suffix.')++$}D';

        return $this->replaceMatches($regex.($this->ignoreCase ? 'i' : ''), '$1');
    }

    /**
     * @return static
     */
    public function ensureStart(string $prefix): self
    {
        $prefix = new static($prefix);

        if (!$this->startsWith($prefix)) {
            return $this->prepend($prefix);
        }

        $str = clone $this;
        $i = $prefixLen = $prefix->length();

        while ($this->indexOf($prefix, $i) === $i) {
            $str = $str->slice($prefixLen);
            $i += $prefixLen;
        }

        return $str;
    }

    /**
     * @param string|string[] $string
     */
    public function equalsTo($string): bool
    {
        if (!\is_array($string) && !$string instanceof \Traversable) {
            throw new \TypeError(sprintf('Method "%s()" must be overridden by class "%s" to deal with non-iterable values.', __FUNCTION__, static::class));
        }

        foreach ($string as $s) {
            if ($this->equalsTo((string) $s)) {
                return true;
            }
        }

        return false;
    }

    /**
     * @return static
     */
    abstract public function folded(): self;

    /**
     * @return static
     */
    public function ignoreCase(): self
    {
        $str = clone $this;
        $str->ignoreCase = true;

        return $str;
    }

    /**
     * @param string|string[] $needle
     */
    public function indexOf($needle, int $offset = 0): ?int
    {
        if (!\is_array($needle) && !$needle instanceof \Traversable) {
            throw new \TypeError(sprintf('Method "%s()" must be overridden by class "%s" to deal with non-iterable values.', __FUNCTION__, static::class));
        }

        $i = \PHP_INT_MAX;

        foreach ($needle as $n) {
            $j = $this->indexOf((string) $n, $offset);

            if (null !== $j && $j < $i) {
                $i = $j;
            }
        }

        return \PHP_INT_MAX === $i ? null : $i;
    }

    /**
     * @param string|string[] $needle
     */
    public function indexOfLast($needle, int $offset = 0): ?int
    {
        if (!\is_array($needle) && !$needle instanceof \Traversable) {
            throw new \TypeError(sprintf('Method "%s()" must be overridden by class "%s" to deal with non-iterable values.', __FUNCTION__, static::class));
        }

        $i = null;

        foreach ($needle as $n) {
            $j = $this->indexOfLast((string) $n, $offset);

            if (null !== $j && $j >= $i) {
                $i = $offset = $j;
            }
        }

        return $i;
    }

    public function isEmpty(): bool
    {
        return '' === $this->string;
    }

    /**
     * @return static
     */
    abstract public function join(array $strings, string $lastGlue = null): self;

    public function jsonSerialize(): string
    {
        return $this->string;
    }

    abstract public function length(): int;

    /**
     * @return static
     */
    abstract public function lower(): self;

    /**
     * Matches the string using a regular expression.
     *
     * Pass PREG_PATTERN_ORDER or PREG_SET_ORDER as $flags to get all occurrences matching the regular expression.
     *
     * @return array All matches in a multi-dimensional array ordered according to flags
     */
    abstract public function match(string $regexp, int $flags = 0, int $offset = 0): array;

    /**
     * @return static
     */
    abstract public function padBoth(int $length, string $padStr = ' '): self;

    /**
     * @return static
     */
    abstract public function padEnd(int $length, string $padStr = ' '): self;

    /**
     * @return static
     */
    abstract public function padStart(int $length, string $padStr = ' '): self;

    /**
     * @return static
     */
    abstract public function prepend(string ...$prefix): self;

    /**
     * @return static
     */
    public function repeat(int $multiplier): self
    {
        if (0 > $multiplier) {
            throw new InvalidArgumentException(sprintf('Multiplier must be positive, %d given.', $multiplier));
        }

        $str = clone $this;
        $str->string = str_repeat($str->string, $multiplier);

        return $str;
    }

    /**
     * @return static
     */
    abstract public function replace(string $from, string $to): self;

    /**
     * @param string|callable $to
     *
     * @return static
     */
    abstract public function replaceMatches(string $fromRegexp, $to): self;

    /**
     * @return static
     */
    abstract public function reverse(): self;

    /**
     * @return static
     */
    abstract public function slice(int $start = 0, int $length = null): self;

    /**
     * @return static
     */
    abstract public function snake(): self;

    /**
     * @return static
     */
    abstract public function splice(string $replacement, int $start = 0, int $length = null): self;

    /**
     * @return static[]
     */
    public function split(string $delimiter, int $limit = null, int $flags = null): array
    {
        if (null === $flags) {
            throw new \TypeError('Split behavior when $flags is null must be implemented by child classes.');
        }

        if ($this->ignoreCase) {
            $delimiter .= 'i';
        }

        set_error_handler(static function ($t, $m) { throw new InvalidArgumentException($m); });

        try {
            if (false === $chunks = preg_split($delimiter, $this->string, $limit, $flags)) {
                $lastError = preg_last_error();

                foreach (get_defined_constants(true)['pcre'] as $k => $v) {
                    if ($lastError === $v && '_ERROR' === substr($k, -6)) {
                        throw new RuntimeException('Splitting failed with '.$k.'.');
                    }
                }

                throw new RuntimeException('Splitting failed with unknown error code.');
            }
        } finally {
            restore_error_handler();
        }

        $str = clone $this;

        if (self::PREG_SPLIT_OFFSET_CAPTURE & $flags) {
            foreach ($chunks as &$chunk) {
                $str->string = $chunk[0];
                $chunk[0] = clone $str;
            }
        } else {
            foreach ($chunks as &$chunk) {
                $str->string = $chunk;
                $chunk = clone $str;
            }
        }

        return $chunks;
    }

    /**
     * @param string|string[] $prefix
     */
    public function startsWith($prefix): bool
    {
        if (!\is_array($prefix) && !$prefix instanceof \Traversable) {
            throw new \TypeError(sprintf('Method "%s()" must be overridden by class "%s" to deal with non-iterable values.', __FUNCTION__, static::class));
        }

        foreach ($prefix as $prefix) {
            if ($this->startsWith((string) $prefix)) {
                return true;
            }
        }

        return false;
    }

    /**
     * @return static
     */
    abstract public function title(bool $allWords = false): self;

    public function toByteString(string $toEncoding = null): ByteString
    {
        $b = new ByteString();

        $toEncoding = \in_array($toEncoding, ['utf8', 'utf-8', 'UTF8'], true) ? 'UTF-8' : $toEncoding;

        if (null === $toEncoding || $toEncoding === $fromEncoding = $this instanceof AbstractUnicodeString || preg_match('//u', $b->string) ? 'UTF-8' : 'Windows-1252') {
            $b->string = $this->string;

            return $b;
        }

        set_error_handler(static function ($t, $m) { throw new InvalidArgumentException($m); });

        try {
            try {
                $b->string = mb_convert_encoding($this->string, $toEncoding, 'UTF-8');
            } catch (InvalidArgumentException $e) {
                if (!\function_exists('iconv')) {
                    throw $e;
                }

                $b->string = iconv('UTF-8', $toEncoding, $this->string);
            }
        } finally {
            restore_error_handler();
        }

        return $b;
    }

    public function toCodePointString(): CodePointString
    {
        return new CodePointString($this->string);
    }

    public function toString(): string
    {
        return $this->string;
    }

    public function toUnicodeString(): UnicodeString
    {
        return new UnicodeString($this->string);
    }

    /**
     * @return static
     */
    abstract public function trim(string $chars = " \t\n\r\0\x0B\x0C\u{A0}\u{FEFF}"): self;

    /**
     * @return static
     */
    abstract public function trimEnd(string $chars = " \t\n\r\0\x0B\x0C\u{A0}\u{FEFF}"): self;

    /**
     * @param string|string[] $prefix
     *
     * @return static
     */
    public function trimPrefix($prefix): self
    {
        if (\is_array($prefix) || $prefix instanceof \Traversable) {
            foreach ($prefix as $s) {
                $t = $this->trimPrefix($s);

                if ($t->string !== $this->string) {
                    return $t;
                }
            }

            return clone $this;
        }

        $str = clone $this;

        if ($prefix instanceof self) {
            $prefix = $prefix->string;
        } else {
            $prefix = (string) $prefix;
        }

        if ('' !== $prefix && \strlen($this->string) >= \strlen($prefix) && 0 === substr_compare($this->string, $prefix, 0, \strlen($prefix), $this->ignoreCase)) {
            $str->string = substr($this->string, \strlen($prefix));
        }

        return $str;
    }

    /**
     * @return static
     */
    abstract public function trimStart(string $chars = " \t\n\r\0\x0B\x0C\u{A0}\u{FEFF}"): self;

    /**
     * @param string|string[] $suffix
     *
     * @return static
     */
    public function trimSuffix($suffix): self
    {
        if (\is_array($suffix) || $suffix instanceof \Traversable) {
            foreach ($suffix as $s) {
                $t = $this->trimSuffix($s);

                if ($t->string !== $this->string) {
                    return $t;
                }
            }

            return clone $this;
        }

        $str = clone $this;

        if ($suffix instanceof self) {
            $suffix = $suffix->string;
        } else {
            $suffix = (string) $suffix;
        }

        if ('' !== $suffix && \strlen($this->string) >= \strlen($suffix) && 0 === substr_compare($this->string, $suffix, -\strlen($suffix), null, $this->ignoreCase)) {
            $str->string = substr($this->string, 0, -\strlen($suffix));
        }

        return $str;
    }

    /**
     * @return static
     */
    public function truncate(int $length, string $ellipsis = '', bool $cut = true): self
    {
        $stringLength = $this->length();

        if ($stringLength <= $length) {
            return clone $this;
        }

        $ellipsisLength = '' !== $ellipsis ? (new static($ellipsis))->length() : 0;

        if ($length < $ellipsisLength) {
            $ellipsisLength = 0;
        }

        if (!$cut) {
            if (null === $length = $this->indexOf([' ', "\r", "\n", "\t"], ($length ?: 1) - 1)) {
                return clone $this;
            }

            $length += $ellipsisLength;
        }

        $str = $this->slice(0, $length - $ellipsisLength);

        return $ellipsisLength ? $str->trimEnd()->append($ellipsis) : $str;
    }

    /**
     * @return static
     */
    abstract public function upper(): self;

    /**
     * Returns the printable length on a terminal.
     */
    abstract public function width(bool $ignoreAnsiDecoration = true): int;

    /**
     * @return static
     */
    public function wordwrap(int $width = 75, string $break = "\n", bool $cut = false): self
    {
        $lines = '' !== $break ? $this->split($break) : [clone $this];
        $chars = [];
        $mask = '';

        if (1 === \count($lines) && '' === $lines[0]->string) {
            return $lines[0];
        }

        foreach ($lines as $i => $line) {
            if ($i) {
                $chars[] = $break;
                $mask .= '#';
            }

            foreach ($line->chunk() as $char) {
                $chars[] = $char->string;
                $mask .= ' ' === $char->string ? ' ' : '?';
            }
        }

        $string = '';
        $j = 0;
        $b = $i = -1;
        $mask = wordwrap($mask, $width, '#', $cut);

        while (false !== $b = strpos($mask, '#', $b + 1)) {
            for (++$i; $i < $b; ++$i) {
                $string .= $chars[$j];
                unset($chars[$j++]);
            }

            if ($break === $chars[$j] || ' ' === $chars[$j]) {
                unset($chars[$j++]);
            }

            $string .= $break;
        }

        $str = clone $this;
        $str->string = $string.implode('', $chars);

        return $str;
    }

    public function __sleep(): array
    {
        return ['string'];
    }

    public function __clone()
    {
        $this->ignoreCase = false;
    }

    public function __toString(): string
    {
        return $this->string;
    }
}
PKϤ$ZW�;e�<�<%string/Inflector/EnglishInflector.phpnu�[���<?php

/*
 * This file is part of the Symfony package.
 *
 * (c) Fabien Potencier <fabien@symfony.com>
 *
 * For the full copyright and license information, please view the LICENSE
 * file that was distributed with this source code.
 */

namespace Symfony\Component\String\Inflector;

final class EnglishInflector implements InflectorInterface
{
    /**
     * Map English plural to singular suffixes.
     *
     * @see http://english-zone.com/spelling/plurals.html
     */
    private const PLURAL_MAP = [
        // First entry: plural suffix, reversed
        // Second entry: length of plural suffix
        // Third entry: Whether the suffix may succeed a vocal
        // Fourth entry: Whether the suffix may succeed a consonant
        // Fifth entry: singular suffix, normal

        // bacteria (bacterium), criteria (criterion), phenomena (phenomenon)
        ['a', 1, true, true, ['on', 'um']],

        // nebulae (nebula)
        ['ea', 2, true, true, 'a'],

        // services (service)
        ['secivres', 8, true, true, 'service'],

        // mice (mouse), lice (louse)
        ['eci', 3, false, true, 'ouse'],

        // geese (goose)
        ['esee', 4, false, true, 'oose'],

        // fungi (fungus), alumni (alumnus), syllabi (syllabus), radii (radius)
        ['i', 1, true, true, 'us'],

        // men (man), women (woman)
        ['nem', 3, true, true, 'man'],

        // children (child)
        ['nerdlihc', 8, true, true, 'child'],

        // oxen (ox)
        ['nexo', 4, false, false, 'ox'],

        // indices (index), appendices (appendix), prices (price)
        ['seci', 4, false, true, ['ex', 'ix', 'ice']],

        // selfies (selfie)
        ['seifles', 7, true, true, 'selfie'],

        // zombies (zombie)
        ['seibmoz', 7, true, true, 'zombie'],

        // movies (movie)
        ['seivom', 6, true, true, 'movie'],

        // conspectuses (conspectus), prospectuses (prospectus)
        ['sesutcep', 8, true, true, 'pectus'],

        // feet (foot)
        ['teef', 4, true, true, 'foot'],

        // geese (goose)
        ['eseeg', 5, true, true, 'goose'],

        // teeth (tooth)
        ['hteet', 5, true, true, 'tooth'],

        // news (news)
        ['swen', 4, true, true, 'news'],

        // series (series)
        ['seires', 6, true, true, 'series'],

        // babies (baby)
        ['sei', 3, false, true, 'y'],

        // accesses (access), addresses (address), kisses (kiss)
        ['sess', 4, true, false, 'ss'],

        // analyses (analysis), ellipses (ellipsis), fungi (fungus),
        // neuroses (neurosis), theses (thesis), emphases (emphasis),
        // oases (oasis), crises (crisis), houses (house), bases (base),
        // atlases (atlas)
        ['ses', 3, true, true, ['s', 'se', 'sis']],

        // objectives (objective), alternative (alternatives)
        ['sevit', 5, true, true, 'tive'],

        // drives (drive)
        ['sevird', 6, false, true, 'drive'],

        // lives (life), wives (wife)
        ['sevi', 4, false, true, 'ife'],

        // moves (move)
        ['sevom', 5, true, true, 'move'],

        // hooves (hoof), dwarves (dwarf), elves (elf), leaves (leaf), caves (cave), staves (staff)
        ['sev', 3, true, true, ['f', 've', 'ff']],

        // axes (axis), axes (ax), axes (axe)
        ['sexa', 4, false, false, ['ax', 'axe', 'axis']],

        // indexes (index), matrixes (matrix)
        ['sex', 3, true, false, 'x'],

        // quizzes (quiz)
        ['sezz', 4, true, false, 'z'],

        // bureaus (bureau)
        ['suae', 4, false, true, 'eau'],

        // fees (fee), trees (tree), employees (employee)
        ['see', 3, true, true, 'ee'],

        // edges (edge)
        ['segd', 4, true, true, 'dge'],

        // roses (rose), garages (garage), cassettes (cassette),
        // waltzes (waltz), heroes (hero), bushes (bush), arches (arch),
        // shoes (shoe)
        ['se', 2, true, true, ['', 'e']],

        // tags (tag)
        ['s', 1, true, true, ''],

        // chateaux (chateau)
        ['xuae', 4, false, true, 'eau'],

        // people (person)
        ['elpoep', 6, true, true, 'person'],
    ];

    /**
     * Map English singular to plural suffixes.
     *
     * @see http://english-zone.com/spelling/plurals.html
     */
    private const SINGULAR_MAP = [
        // First entry: singular suffix, reversed
        // Second entry: length of singular suffix
        // Third entry: Whether the suffix may succeed a vocal
        // Fourth entry: Whether the suffix may succeed a consonant
        // Fifth entry: plural suffix, normal

        // criterion (criteria)
        ['airetirc', 8, false, false, 'criterion'],

        // nebulae (nebula)
        ['aluben', 6, false, false, 'nebulae'],

        // children (child)
        ['dlihc', 5, true, true, 'children'],

        // prices (price)
        ['eci', 3, false, true, 'ices'],

        // services (service)
        ['ecivres', 7, true, true, 'services'],

        // lives (life), wives (wife)
        ['efi', 3, false, true, 'ives'],

        // selfies (selfie)
        ['eifles', 6, true, true, 'selfies'],

        // movies (movie)
        ['eivom', 5, true, true, 'movies'],

        // lice (louse)
        ['esuol', 5, false, true, 'lice'],

        // mice (mouse)
        ['esuom', 5, false, true, 'mice'],

        // geese (goose)
        ['esoo', 4, false, true, 'eese'],

        // houses (house), bases (base)
        ['es', 2, true, true, 'ses'],

        // geese (goose)
        ['esoog', 5, true, true, 'geese'],

        // caves (cave)
        ['ev', 2, true, true, 'ves'],

        // drives (drive)
        ['evird', 5, false, true, 'drives'],

        // objectives (objective), alternative (alternatives)
        ['evit', 4, true, true, 'tives'],

        // moves (move)
        ['evom', 4, true, true, 'moves'],

        // staves (staff)
        ['ffats', 5, true, true, 'staves'],

        // hooves (hoof), dwarves (dwarf), elves (elf), leaves (leaf)
        ['ff', 2, true, true, 'ffs'],

        // hooves (hoof), dwarves (dwarf), elves (elf), leaves (leaf)
        ['f', 1, true, true, ['fs', 'ves']],

        // arches (arch)
        ['hc', 2, true, true, 'ches'],

        // bushes (bush)
        ['hs', 2, true, true, 'shes'],

        // teeth (tooth)
        ['htoot', 5, true, true, 'teeth'],

        // bacteria (bacterium), criteria (criterion), phenomena (phenomenon)
        ['mu', 2, true, true, 'a'],

        // men (man), women (woman)
        ['nam', 3, true, true, 'men'],

        // people (person)
        ['nosrep', 6, true, true, ['persons', 'people']],

        // bacteria (bacterium), criteria (criterion), phenomena (phenomenon)
        ['noi', 3, true, true, 'ions'],

        // coupon (coupons)
        ['nop', 3, true, true, 'pons'],

        // seasons (season), treasons (treason), poisons (poison), lessons (lesson)
        ['nos', 3, true, true, 'sons'],

        // bacteria (bacterium), criteria (criterion), phenomena (phenomenon)
        ['no', 2, true, true, 'a'],

        // echoes (echo)
        ['ohce', 4, true, true, 'echoes'],

        // heroes (hero)
        ['oreh', 4, true, true, 'heroes'],

        // atlases (atlas)
        ['salta', 5, true, true, 'atlases'],

        // irises (iris)
        ['siri', 4, true, true, 'irises'],

        // analyses (analysis), ellipses (ellipsis), neuroses (neurosis)
        // theses (thesis), emphases (emphasis), oases (oasis),
        // crises (crisis)
        ['sis', 3, true, true, 'ses'],

        // accesses (access), addresses (address), kisses (kiss)
        ['ss', 2, true, false, 'sses'],

        // syllabi (syllabus)
        ['suballys', 8, true, true, 'syllabi'],

        // buses (bus)
        ['sub', 3, true, true, 'buses'],

        // circuses (circus)
        ['suc', 3, true, true, 'cuses'],

        // conspectuses (conspectus), prospectuses (prospectus)
        ['sutcep', 6, true, true, 'pectuses'],

        // fungi (fungus), alumni (alumnus), syllabi (syllabus), radii (radius)
        ['su', 2, true, true, 'i'],

        // news (news)
        ['swen', 4, true, true, 'news'],

        // feet (foot)
        ['toof', 4, true, true, 'feet'],

        // chateaux (chateau), bureaus (bureau)
        ['uae', 3, false, true, ['eaus', 'eaux']],

        // oxen (ox)
        ['xo', 2, false, false, 'oxen'],

        // hoaxes (hoax)
        ['xaoh', 4, true, false, 'hoaxes'],

        // indices (index)
        ['xedni', 5, false, true, ['indicies', 'indexes']],

        // boxes (box)
        ['xo', 2, false, true, 'oxes'],

        // indexes (index), matrixes (matrix)
        ['x', 1, true, false, ['cies', 'xes']],

        // appendices (appendix)
        ['xi', 2, false, true, 'ices'],

        // babies (baby)
        ['y', 1, false, true, 'ies'],

        // quizzes (quiz)
        ['ziuq', 4, true, false, 'quizzes'],

        // waltzes (waltz)
        ['z', 1, true, true, 'zes'],
    ];

    /**
     * A list of words which should not be inflected, reversed.
     */
    private const UNINFLECTED = [
        '',

        // data
        'atad',

        // deer
        'reed',

        // feedback
        'kcabdeef',

        // fish
        'hsif',

        // info
        'ofni',

        // moose
        'esoom',

        // series
        'seires',

        // sheep
        'peehs',

        // species
        'seiceps',
    ];

    /**
     * {@inheritdoc}
     */
    public function singularize(string $plural): array
    {
        $pluralRev = strrev($plural);
        $lowerPluralRev = strtolower($pluralRev);
        $pluralLength = \strlen($lowerPluralRev);

        // Check if the word is one which is not inflected, return early if so
        if (\in_array($lowerPluralRev, self::UNINFLECTED, true)) {
            return [$plural];
        }

        // The outer loop iterates over the entries of the plural table
        // The inner loop $j iterates over the characters of the plural suffix
        // in the plural table to compare them with the characters of the actual
        // given plural suffix
        foreach (self::PLURAL_MAP as $map) {
            $suffix = $map[0];
            $suffixLength = $map[1];
            $j = 0;

            // Compare characters in the plural table and of the suffix of the
            // given plural one by one
            while ($suffix[$j] === $lowerPluralRev[$j]) {
                // Let $j point to the next character
                ++$j;

                // Successfully compared the last character
                // Add an entry with the singular suffix to the singular array
                if ($j === $suffixLength) {
                    // Is there any character preceding the suffix in the plural string?
                    if ($j < $pluralLength) {
                        $nextIsVocal = false !== strpos('aeiou', $lowerPluralRev[$j]);

                        if (!$map[2] && $nextIsVocal) {
                            // suffix may not succeed a vocal but next char is one
                            break;
                        }

                        if (!$map[3] && !$nextIsVocal) {
                            // suffix may not succeed a consonant but next char is one
                            break;
                        }
                    }

                    $newBase = substr($plural, 0, $pluralLength - $suffixLength);
                    $newSuffix = $map[4];

                    // Check whether the first character in the plural suffix
                    // is uppercased. If yes, uppercase the first character in
                    // the singular suffix too
                    $firstUpper = ctype_upper($pluralRev[$j - 1]);

                    if (\is_array($newSuffix)) {
                        $singulars = [];

                        foreach ($newSuffix as $newSuffixEntry) {
                            $singulars[] = $newBase.($firstUpper ? ucfirst($newSuffixEntry) : $newSuffixEntry);
                        }

                        return $singulars;
                    }

                    return [$newBase.($firstUpper ? ucfirst($newSuffix) : $newSuffix)];
                }

                // Suffix is longer than word
                if ($j === $pluralLength) {
                    break;
                }
            }
        }

        // Assume that plural and singular is identical
        return [$plural];
    }

    /**
     * {@inheritdoc}
     */
    public function pluralize(string $singular): array
    {
        $singularRev = strrev($singular);
        $lowerSingularRev = strtolower($singularRev);
        $singularLength = \strlen($lowerSingularRev);

        // Check if the word is one which is not inflected, return early if so
        if (\in_array($lowerSingularRev, self::UNINFLECTED, true)) {
            return [$singular];
        }

        // The outer loop iterates over the entries of the singular table
        // The inner loop $j iterates over the characters of the singular suffix
        // in the singular table to compare them with the characters of the actual
        // given singular suffix
        foreach (self::SINGULAR_MAP as $map) {
            $suffix = $map[0];
            $suffixLength = $map[1];
            $j = 0;

            // Compare characters in the singular table and of the suffix of the
            // given plural one by one

            while ($suffix[$j] === $lowerSingularRev[$j]) {
                // Let $j point to the next character
                ++$j;

                // Successfully compared the last character
                // Add an entry with the plural suffix to the plural array
                if ($j === $suffixLength) {
                    // Is there any character preceding the suffix in the plural string?
                    if ($j < $singularLength) {
                        $nextIsVocal = false !== strpos('aeiou', $lowerSingularRev[$j]);

                        if (!$map[2] && $nextIsVocal) {
                            // suffix may not succeed a vocal but next char is one
                            break;
                        }

                        if (!$map[3] && !$nextIsVocal) {
                            // suffix may not succeed a consonant but next char is one
                            break;
                        }
                    }

                    $newBase = substr($singular, 0, $singularLength - $suffixLength);
                    $newSuffix = $map[4];

                    // Check whether the first character in the singular suffix
                    // is uppercased. If yes, uppercase the first character in
                    // the singular suffix too
                    $firstUpper = ctype_upper($singularRev[$j - 1]);

                    if (\is_array($newSuffix)) {
                        $plurals = [];

                        foreach ($newSuffix as $newSuffixEntry) {
                            $plurals[] = $newBase.($firstUpper ? ucfirst($newSuffixEntry) : $newSuffixEntry);
                        }

                        return $plurals;
                    }

                    return [$newBase.($firstUpper ? ucfirst($newSuffix) : $newSuffix)];
                }

                // Suffix is longer than word
                if ($j === $singularLength) {
                    break;
                }
            }
        }

        // Assume that plural is singular with a trailing `s`
        return [$singular.'s'];
    }
}
PKϤ$Z!9�a��$string/Inflector/FrenchInflector.phpnu�[���<?php

/*
 * This file is part of the Symfony package.
 *
 * (c) Fabien Potencier <fabien@symfony.com>
 *
 * For the full copyright and license information, please view the LICENSE
 * file that was distributed with this source code.
 */

namespace Symfony\Component\String\Inflector;

/**
 * French inflector.
 *
 * This class does only inflect nouns; not adjectives nor composed words like "soixante-dix".
 */
final class FrenchInflector implements InflectorInterface
{
    /**
     * A list of all rules for pluralise.
     *
     * @see https://la-conjugaison.nouvelobs.com/regles/grammaire/le-pluriel-des-noms-121.php
     */
    private const PLURALIZE_REGEXP = [
        // First entry: regexp
        // Second entry: replacement

        // Words finishing with "s", "x" or "z" are invariables
        // Les mots finissant par "s", "x" ou "z" sont invariables
        ['/(s|x|z)$/i', '\1'],

        // Words finishing with "eau" are pluralized with a "x"
        // Les mots finissant par "eau" prennent tous un "x" au pluriel
        ['/(eau)$/i', '\1x'],

        // Words finishing with "au" are pluralized with a "x" excepted "landau"
        // Les mots finissant par "au" prennent un "x" au pluriel sauf "landau"
        ['/^(landau)$/i', '\1s'],
        ['/(au)$/i', '\1x'],

        // Words finishing with "eu" are pluralized with a "x" excepted "pneu", "bleu", "émeu"
        // Les mots finissant en "eu" prennent un "x" au pluriel sauf "pneu", "bleu", "émeu"
        ['/^(pneu|bleu|émeu)$/i', '\1s'],
        ['/(eu)$/i', '\1x'],

        // Words finishing with "al" are pluralized with a "aux" excepted
        // Les mots finissant en "al" se terminent en "aux" sauf
        ['/^(bal|carnaval|caracal|chacal|choral|corral|étal|festival|récital|val)$/i', '\1s'],
        ['/al$/i', '\1aux'],

        // Aspirail, bail, corail, émail, fermail, soupirail, travail, vantail et vitrail font leur pluriel en -aux
        ['/^(aspir|b|cor|ém|ferm|soupir|trav|vant|vitr)ail$/i', '\1aux'],

        // Bijou, caillou, chou, genou, hibou, joujou et pou qui prennent un x au pluriel
        ['/^(bij|caill|ch|gen|hib|jouj|p)ou$/i', '\1oux'],

        // Invariable words
        ['/^(cinquante|soixante|mille)$/i', '\1'],

        // French titles
        ['/^(mon|ma)(sieur|dame|demoiselle|seigneur)$/', 'mes\2s'],
        ['/^(Mon|Ma)(sieur|dame|demoiselle|seigneur)$/', 'Mes\2s'],
    ];

    /**
     * A list of all rules for singularize.
     */
    private const SINGULARIZE_REGEXP = [
        // First entry: regexp
        // Second entry: replacement

        // Aspirail, bail, corail, émail, fermail, soupirail, travail, vantail et vitrail font leur pluriel en -aux
        ['/((aspir|b|cor|ém|ferm|soupir|trav|vant|vitr))aux$/i', '\1ail'],

        // Words finishing with "eau" are pluralized with a "x"
        // Les mots finissant par "eau" prennent tous un "x" au pluriel
        ['/(eau)x$/i', '\1'],

        // Words finishing with "al" are pluralized with a "aux" expected
        // Les mots finissant en "al" se terminent en "aux" sauf
        ['/(amir|anim|arsen|boc|can|capit|capor|chev|crist|génér|hopit|hôpit|idé|journ|littor|loc|m|mét|minér|princip|radic|termin)aux$/i', '\1al'],

        // Words finishing with "au" are pluralized with a "x" excepted "landau"
        // Les mots finissant par "au" prennent un "x" au pluriel sauf "landau"
        ['/(au)x$/i', '\1'],

        // Words finishing with "eu" are pluralized with a "x" excepted "pneu", "bleu", "émeu"
        // Les mots finissant en "eu" prennent un "x" au pluriel sauf "pneu", "bleu", "émeu"
        ['/(eu)x$/i', '\1'],

        //  Words finishing with "ou" are pluralized with a "s" excepted bijou, caillou, chou, genou, hibou, joujou, pou
        // Les mots finissant par "ou" prennent un "s" sauf bijou, caillou, chou, genou, hibou, joujou, pou
        ['/(bij|caill|ch|gen|hib|jouj|p)oux$/i', '\1ou'],

        // French titles
        ['/^mes(dame|demoiselle)s$/', 'ma\1'],
        ['/^Mes(dame|demoiselle)s$/', 'Ma\1'],
        ['/^mes(sieur|seigneur)s$/', 'mon\1'],
        ['/^Mes(sieur|seigneur)s$/', 'Mon\1'],

        //Default rule
        ['/s$/i', ''],
    ];

    /**
     * A list of words which should not be inflected.
     * This list is only used by singularize.
     */
    private const UNINFLECTED = '/^(abcès|accès|abus|albatros|anchois|anglais|autobus|bois|brebis|carquois|cas|chas|colis|concours|corps|cours|cyprès|décès|devis|discours|dos|embarras|engrais|entrelacs|excès|fils|fois|gâchis|gars|glas|héros|intrus|jars|jus|kermès|lacis|legs|lilas|marais|mars|matelas|mépris|mets|mois|mors|obus|os|palais|paradis|parcours|pardessus|pays|plusieurs|poids|pois|pouls|printemps|processus|progrès|puits|pus|rabais|radis|recors|recours|refus|relais|remords|remous|rictus|rhinocéros|repas|rubis|sans|sas|secours|sens|souris|succès|talus|tapis|tas|taudis|temps|tiers|univers|velours|verglas|vernis|virus)$/i';

    /**
     * {@inheritdoc}
     */
    public function singularize(string $plural): array
    {
        if ($this->isInflectedWord($plural)) {
            return [$plural];
        }

        foreach (self::SINGULARIZE_REGEXP as $rule) {
            [$regexp, $replace] = $rule;

            if (1 === preg_match($regexp, $plural)) {
                return [preg_replace($regexp, $replace, $plural)];
            }
        }

        return [$plural];
    }

    /**
     * {@inheritdoc}
     */
    public function pluralize(string $singular): array
    {
        if ($this->isInflectedWord($singular)) {
            return [$singular];
        }

        foreach (self::PLURALIZE_REGEXP as $rule) {
            [$regexp, $replace] = $rule;

            if (1 === preg_match($regexp, $singular)) {
                return [preg_replace($regexp, $replace, $singular)];
            }
        }

        return [$singular.'s'];
    }

    private function isInflectedWord(string $word): bool
    {
        return 1 === preg_match(self::UNINFLECTED, $word);
    }
}
PKϤ$ZQ�ccCC'string/Inflector/InflectorInterface.phpnu�[���<?php

/*
 * This file is part of the Symfony package.
 *
 * (c) Fabien Potencier <fabien@symfony.com>
 *
 * For the full copyright and license information, please view the LICENSE
 * file that was distributed with this source code.
 */

namespace Symfony\Component\String\Inflector;

interface InflectorInterface
{
    /**
     * Returns the singular forms of a string.
     *
     * If the method can't determine the form with certainty, several possible singulars are returned.
     *
     * @return string[]
     */
    public function singularize(string $plural): array;

    /**
     * Returns the plural forms of a string.
     *
     * If the method can't determine the form with certainty, several possible plurals are returned.
     *
     * @return string[]
     */
    public function pluralize(string $singular): array;
}
PKϤ$Z"�O���#string/Slugger/SluggerInterface.phpnu�[���<?php

/*
 * This file is part of the Symfony package.
 *
 * (c) Fabien Potencier <fabien@symfony.com>
 *
 * For the full copyright and license information, please view the LICENSE
 * file that was distributed with this source code.
 */

namespace Symfony\Component\String\Slugger;

use Symfony\Component\String\AbstractUnicodeString;

/**
 * Creates a URL-friendly slug from a given string.
 *
 * @author Titouan Galopin <galopintitouan@gmail.com>
 */
interface SluggerInterface
{
    /**
     * Creates a slug for the given string and locale, using appropriate transliteration when needed.
     */
    public function slug(string $string, string $separator = '-', string $locale = null): AbstractUnicodeString;
}
PKϤ$Ze����string/Slugger/AsciiSlugger.phpnu�[���<?php

/*
 * This file is part of the Symfony package.
 *
 * (c) Fabien Potencier <fabien@symfony.com>
 *
 * For the full copyright and license information, please view the LICENSE
 * file that was distributed with this source code.
 */

namespace Symfony\Component\String\Slugger;

use Symfony\Component\String\AbstractUnicodeString;
use Symfony\Component\String\UnicodeString;
use Symfony\Contracts\Translation\LocaleAwareInterface;

if (!interface_exists(LocaleAwareInterface::class)) {
    throw new \LogicException('You cannot use the "Symfony\Component\String\Slugger\AsciiSlugger" as the "symfony/translation-contracts" package is not installed. Try running "composer require symfony/translation-contracts".');
}

/**
 * @author Titouan Galopin <galopintitouan@gmail.com>
 */
class AsciiSlugger implements SluggerInterface, LocaleAwareInterface
{
    private const LOCALE_TO_TRANSLITERATOR_ID = [
        'am' => 'Amharic-Latin',
        'ar' => 'Arabic-Latin',
        'az' => 'Azerbaijani-Latin',
        'be' => 'Belarusian-Latin',
        'bg' => 'Bulgarian-Latin',
        'bn' => 'Bengali-Latin',
        'de' => 'de-ASCII',
        'el' => 'Greek-Latin',
        'fa' => 'Persian-Latin',
        'he' => 'Hebrew-Latin',
        'hy' => 'Armenian-Latin',
        'ka' => 'Georgian-Latin',
        'kk' => 'Kazakh-Latin',
        'ky' => 'Kirghiz-Latin',
        'ko' => 'Korean-Latin',
        'mk' => 'Macedonian-Latin',
        'mn' => 'Mongolian-Latin',
        'or' => 'Oriya-Latin',
        'ps' => 'Pashto-Latin',
        'ru' => 'Russian-Latin',
        'sr' => 'Serbian-Latin',
        'sr_Cyrl' => 'Serbian-Latin',
        'th' => 'Thai-Latin',
        'tk' => 'Turkmen-Latin',
        'uk' => 'Ukrainian-Latin',
        'uz' => 'Uzbek-Latin',
        'zh' => 'Han-Latin',
    ];

    private $defaultLocale;
    private $symbolsMap = [
        'en' => ['@' => 'at', '&' => 'and'],
    ];

    /**
     * Cache of transliterators per locale.
     *
     * @var \Transliterator[]
     */
    private $transliterators = [];

    /**
     * @param array|\Closure|null $symbolsMap
     */
    public function __construct(string $defaultLocale = null, $symbolsMap = null)
    {
        if (null !== $symbolsMap && !\is_array($symbolsMap) && !$symbolsMap instanceof \Closure) {
            throw new \TypeError(sprintf('Argument 2 passed to "%s()" must be array, Closure or null, "%s" given.', __METHOD__, \gettype($symbolsMap)));
        }

        $this->defaultLocale = $defaultLocale;
        $this->symbolsMap = $symbolsMap ?? $this->symbolsMap;
    }

    /**
     * {@inheritdoc}
     */
    public function setLocale($locale)
    {
        $this->defaultLocale = $locale;
    }

    /**
     * {@inheritdoc}
     */
    public function getLocale()
    {
        return $this->defaultLocale;
    }

    /**
     * {@inheritdoc}
     */
    public function slug(string $string, string $separator = '-', string $locale = null): AbstractUnicodeString
    {
        $locale = $locale ?? $this->defaultLocale;

        $transliterator = [];
        if ($locale && ('de' === $locale || 0 === strpos($locale, 'de_'))) {
            // Use the shortcut for German in UnicodeString::ascii() if possible (faster and no requirement on intl)
            $transliterator = ['de-ASCII'];
        } elseif (\function_exists('transliterator_transliterate') && $locale) {
            $transliterator = (array) $this->createTransliterator($locale);
        }

        if ($this->symbolsMap instanceof \Closure) {
            // If the symbols map is passed as a closure, there is no need to fallback to the parent locale
            // as the closure can just provide substitutions for all locales of interest.
            $symbolsMap = $this->symbolsMap;
            array_unshift($transliterator, static function ($s) use ($symbolsMap, $locale) {
                return $symbolsMap($s, $locale);
            });
        }

        $unicodeString = (new UnicodeString($string))->ascii($transliterator);

        if (\is_array($this->symbolsMap)) {
            $map = null;
            if (isset($this->symbolsMap[$locale])) {
                $map = $this->symbolsMap[$locale];
            } else {
                $parent = self::getParentLocale($locale);
                if ($parent && isset($this->symbolsMap[$parent])) {
                    $map = $this->symbolsMap[$parent];
                }
            }
            if ($map) {
                foreach ($map as $char => $replace) {
                    $unicodeString = $unicodeString->replace($char, ' '.$replace.' ');
                }
            }
        }

        return $unicodeString
            ->replaceMatches('/[^A-Za-z0-9]++/', $separator)
            ->trim($separator)
        ;
    }

    private function createTransliterator(string $locale): ?\Transliterator
    {
        if (\array_key_exists($locale, $this->transliterators)) {
            return $this->transliterators[$locale];
        }

        // Exact locale supported, cache and return
        if ($id = self::LOCALE_TO_TRANSLITERATOR_ID[$locale] ?? null) {
            return $this->transliterators[$locale] = \Transliterator::create($id.'/BGN') ?? \Transliterator::create($id);
        }

        // Locale not supported and no parent, fallback to any-latin
        if (!$parent = self::getParentLocale($locale)) {
            return $this->transliterators[$locale] = null;
        }

        // Try to use the parent locale (ie. try "de" for "de_AT") and cache both locales
        if ($id = self::LOCALE_TO_TRANSLITERATOR_ID[$parent] ?? null) {
            $transliterator = \Transliterator::create($id.'/BGN') ?? \Transliterator::create($id);
        }

        return $this->transliterators[$locale] = $this->transliterators[$parent] = $transliterator ?? null;
    }

    private static function getParentLocale(?string $locale): ?string
    {
        if (!$locale) {
            return null;
        }
        if (false === $str = strrchr($locale, '_')) {
            // no parent locale
            return null;
        }

        return substr($locale, 0, -\strlen($str));
    }
}
PKϤ$Z�L��++string/README.mdnu�[���String Component
================

The String component provides an object-oriented API to strings and deals
with bytes, UTF-8 code points and grapheme clusters in a unified way.

Resources
---------

 * [Documentation](https://symfony.com/doc/current/components/string.html)
 * [Contributing](https://symfony.com/doc/current/contributing/index.html)
 * [Report issues](https://github.com/symfony/symfony/issues) and
   [send Pull Requests](https://github.com/symfony/symfony/pulls)
   in the [main Symfony repository](https://github.com/symfony/symfony)
PKϤ$Z�M̿k�k string/AbstractUnicodeString.phpnu�[���<?php

/*
 * This file is part of the Symfony package.
 *
 * (c) Fabien Potencier <fabien@symfony.com>
 *
 * For the full copyright and license information, please view the LICENSE
 * file that was distributed with this source code.
 */

namespace Symfony\Component\String;

use Symfony\Component\String\Exception\ExceptionInterface;
use Symfony\Component\String\Exception\InvalidArgumentException;
use Symfony\Component\String\Exception\RuntimeException;

/**
 * Represents a string of abstract Unicode characters.
 *
 * Unicode defines 3 types of "characters" (bytes, code points and grapheme clusters).
 * This class is the abstract type to use as a type-hint when the logic you want to
 * implement is Unicode-aware but doesn't care about code points vs grapheme clusters.
 *
 * @author Nicolas Grekas <p@tchwork.com>
 *
 * @throws ExceptionInterface
 */
abstract class AbstractUnicodeString extends AbstractString
{
    public const NFC = \Normalizer::NFC;
    public const NFD = \Normalizer::NFD;
    public const NFKC = \Normalizer::NFKC;
    public const NFKD = \Normalizer::NFKD;

    // all ASCII letters sorted by typical frequency of occurrence
    private const ASCII = "\x20\x65\x69\x61\x73\x6E\x74\x72\x6F\x6C\x75\x64\x5D\x5B\x63\x6D\x70\x27\x0A\x67\x7C\x68\x76\x2E\x66\x62\x2C\x3A\x3D\x2D\x71\x31\x30\x43\x32\x2A\x79\x78\x29\x28\x4C\x39\x41\x53\x2F\x50\x22\x45\x6A\x4D\x49\x6B\x33\x3E\x35\x54\x3C\x44\x34\x7D\x42\x7B\x38\x46\x77\x52\x36\x37\x55\x47\x4E\x3B\x4A\x7A\x56\x23\x48\x4F\x57\x5F\x26\x21\x4B\x3F\x58\x51\x25\x59\x5C\x09\x5A\x2B\x7E\x5E\x24\x40\x60\x7F\x00\x01\x02\x03\x04\x05\x06\x07\x08\x0B\x0C\x0D\x0E\x0F\x10\x11\x12\x13\x14\x15\x16\x17\x18\x19\x1A\x1B\x1C\x1D\x1E\x1F";

    // the subset of folded case mappings that is not in lower case mappings
    private const FOLD_FROM = ['İ', 'µ', 'ſ', "\xCD\x85", 'ς', 'ϐ', 'ϑ', 'ϕ', 'ϖ', 'ϰ', 'ϱ', 'ϵ', 'ẛ', "\xE1\xBE\xBE", 'ß', 'İ', 'ʼn', 'ǰ', 'ΐ', 'ΰ', 'և', 'ẖ', 'ẗ', 'ẘ', 'ẙ', 'ẚ', 'ẞ', 'ὐ', 'ὒ', 'ὔ', 'ὖ', 'ᾀ', 'ᾁ', 'ᾂ', 'ᾃ', 'ᾄ', 'ᾅ', 'ᾆ', 'ᾇ', 'ᾈ', 'ᾉ', 'ᾊ', 'ᾋ', 'ᾌ', 'ᾍ', 'ᾎ', 'ᾏ', 'ᾐ', 'ᾑ', 'ᾒ', 'ᾓ', 'ᾔ', 'ᾕ', 'ᾖ', 'ᾗ', 'ᾘ', 'ᾙ', 'ᾚ', 'ᾛ', 'ᾜ', 'ᾝ', 'ᾞ', 'ᾟ', 'ᾠ', 'ᾡ', 'ᾢ', 'ᾣ', 'ᾤ', 'ᾥ', 'ᾦ', 'ᾧ', 'ᾨ', 'ᾩ', 'ᾪ', 'ᾫ', 'ᾬ', 'ᾭ', 'ᾮ', 'ᾯ', 'ᾲ', 'ᾳ', 'ᾴ', 'ᾶ', 'ᾷ', 'ᾼ', 'ῂ', 'ῃ', 'ῄ', 'ῆ', 'ῇ', 'ῌ', 'ῒ', 'ΐ', 'ῖ', 'ῗ', 'ῢ', 'ΰ', 'ῤ', 'ῦ', 'ῧ', 'ῲ', 'ῳ', 'ῴ', 'ῶ', 'ῷ', 'ῼ', 'ff', 'fi', 'fl', 'ffi', 'ffl', 'ſt', 'st', 'ﬓ', 'ﬔ', 'ﬕ', 'ﬖ', 'ﬗ'];
    private const FOLD_TO = ['i̇', 'μ', 's', 'ι', 'σ', 'β', 'θ', 'φ', 'π', 'κ', 'ρ', 'ε', 'ṡ', 'ι', 'ss', 'i̇', 'ʼn', 'ǰ', 'ΐ', 'ΰ', 'եւ', 'ẖ', 'ẗ', 'ẘ', 'ẙ', 'aʾ', 'ss', 'ὐ', 'ὒ', 'ὔ', 'ὖ', 'ἀι', 'ἁι', 'ἂι', 'ἃι', 'ἄι', 'ἅι', 'ἆι', 'ἇι', 'ἀι', 'ἁι', 'ἂι', 'ἃι', 'ἄι', 'ἅι', 'ἆι', 'ἇι', 'ἠι', 'ἡι', 'ἢι', 'ἣι', 'ἤι', 'ἥι', 'ἦι', 'ἧι', 'ἠι', 'ἡι', 'ἢι', 'ἣι', 'ἤι', 'ἥι', 'ἦι', 'ἧι', 'ὠι', 'ὡι', 'ὢι', 'ὣι', 'ὤι', 'ὥι', 'ὦι', 'ὧι', 'ὠι', 'ὡι', 'ὢι', 'ὣι', 'ὤι', 'ὥι', 'ὦι', 'ὧι', 'ὰι', 'αι', 'άι', 'ᾶ', 'ᾶι', 'αι', 'ὴι', 'ηι', 'ήι', 'ῆ', 'ῆι', 'ηι', 'ῒ', 'ΐ', 'ῖ', 'ῗ', 'ῢ', 'ΰ', 'ῤ', 'ῦ', 'ῧ', 'ὼι', 'ωι', 'ώι', 'ῶ', 'ῶι', 'ωι', 'ff', 'fi', 'fl', 'ffi', 'ffl', 'st', 'st', 'մն', 'մե', 'մի', 'վն', 'մխ'];

    // the subset of upper case mappings that map one code point to many code points
    private const UPPER_FROM = ['ß', 'ff', 'fi', 'fl', 'ffi', 'ffl', 'ſt', 'st', 'և', 'ﬓ', 'ﬔ', 'ﬕ', 'ﬖ', 'ﬗ', 'ʼn', 'ΐ', 'ΰ', 'ǰ', 'ẖ', 'ẗ', 'ẘ', 'ẙ', 'ẚ', 'ὐ', 'ὒ', 'ὔ', 'ὖ', 'ᾶ', 'ῆ', 'ῒ', 'ΐ', 'ῖ', 'ῗ', 'ῢ', 'ΰ', 'ῤ', 'ῦ', 'ῧ', 'ῶ'];
    private const UPPER_TO = ['SS', 'FF', 'FI', 'FL', 'FFI', 'FFL', 'ST', 'ST', 'ԵՒ', 'ՄՆ', 'ՄԵ', 'ՄԻ', 'ՎՆ', 'ՄԽ', 'ʼN', 'Ϊ́', 'Ϋ́', 'J̌', 'H̱', 'T̈', 'W̊', 'Y̊', 'Aʾ', 'Υ̓', 'Υ̓̀', 'Υ̓́', 'Υ̓͂', 'Α͂', 'Η͂', 'Ϊ̀', 'Ϊ́', 'Ι͂', 'Ϊ͂', 'Ϋ̀', 'Ϋ́', 'Ρ̓', 'Υ͂', 'Ϋ͂', 'Ω͂'];

    // the subset of https://github.com/unicode-org/cldr/blob/master/common/transforms/Latin-ASCII.xml that is not in NFKD
    private const TRANSLIT_FROM = ['Æ', 'Ð', 'Ø', 'Þ', 'ß', 'æ', 'ð', 'ø', 'þ', 'Đ', 'đ', 'Ħ', 'ħ', 'ı', 'ĸ', 'Ŀ', 'ŀ', 'Ł', 'ł', 'ʼn', 'Ŋ', 'ŋ', 'Œ', 'œ', 'Ŧ', 'ŧ', 'ƀ', 'Ɓ', 'Ƃ', 'ƃ', 'Ƈ', 'ƈ', 'Ɖ', 'Ɗ', 'Ƌ', 'ƌ', 'Ɛ', 'Ƒ', 'ƒ', 'Ɠ', 'ƕ', 'Ɩ', 'Ɨ', 'Ƙ', 'ƙ', 'ƚ', 'Ɲ', 'ƞ', 'Ƣ', 'ƣ', 'Ƥ', 'ƥ', 'ƫ', 'Ƭ', 'ƭ', 'Ʈ', 'Ʋ', 'Ƴ', 'ƴ', 'Ƶ', 'ƶ', 'DŽ', 'Dž', 'dž', 'Ǥ', 'ǥ', 'ȡ', 'Ȥ', 'ȥ', 'ȴ', 'ȵ', 'ȶ', 'ȷ', 'ȸ', 'ȹ', 'Ⱥ', 'Ȼ', 'ȼ', 'Ƚ', 'Ⱦ', 'ȿ', 'ɀ', 'Ƀ', 'Ʉ', 'Ɇ', 'ɇ', 'Ɉ', 'ɉ', 'Ɍ', 'ɍ', 'Ɏ', 'ɏ', 'ɓ', 'ɕ', 'ɖ', 'ɗ', 'ɛ', 'ɟ', 'ɠ', 'ɡ', 'ɢ', 'ɦ', 'ɧ', 'ɨ', 'ɪ', 'ɫ', 'ɬ', 'ɭ', 'ɱ', 'ɲ', 'ɳ', 'ɴ', 'ɶ', 'ɼ', 'ɽ', 'ɾ', 'ʀ', 'ʂ', 'ʈ', 'ʉ', 'ʋ', 'ʏ', 'ʐ', 'ʑ', 'ʙ', 'ʛ', 'ʜ', 'ʝ', 'ʟ', 'ʠ', 'ʣ', 'ʥ', 'ʦ', 'ʪ', 'ʫ', 'ᴀ', 'ᴁ', 'ᴃ', 'ᴄ', 'ᴅ', 'ᴆ', 'ᴇ', 'ᴊ', 'ᴋ', 'ᴌ', 'ᴍ', 'ᴏ', 'ᴘ', 'ᴛ', 'ᴜ', 'ᴠ', 'ᴡ', 'ᴢ', 'ᵫ', 'ᵬ', 'ᵭ', 'ᵮ', 'ᵯ', 'ᵰ', 'ᵱ', 'ᵲ', 'ᵳ', 'ᵴ', 'ᵵ', 'ᵶ', 'ᵺ', 'ᵻ', 'ᵽ', 'ᵾ', 'ᶀ', 'ᶁ', 'ᶂ', 'ᶃ', 'ᶄ', 'ᶅ', 'ᶆ', 'ᶇ', 'ᶈ', 'ᶉ', 'ᶊ', 'ᶌ', 'ᶍ', 'ᶎ', 'ᶏ', 'ᶑ', 'ᶒ', 'ᶓ', 'ᶖ', 'ᶙ', 'ẚ', 'ẜ', 'ẝ', 'ẞ', 'Ỻ', 'ỻ', 'Ỽ', 'ỽ', 'Ỿ', 'ỿ', '©', '®', '₠', '₢', '₣', '₤', '₧', '₺', '₹', 'ℌ', '℞', '㎧', '㎮', '㏆', '㏗', '㏞', '㏟', '¼', '½', '¾', '⅓', '⅔', '⅕', '⅖', '⅗', '⅘', '⅙', '⅚', '⅛', '⅜', '⅝', '⅞', '⅟', '〇', '‘', '’', '‚', '‛', '“', '”', '„', '‟', '′', '″', '〝', '〞', '«', '»', '‹', '›', '‐', '‑', '‒', '–', '—', '―', '︱', '︲', '﹘', '‖', '⁄', '⁅', '⁆', '⁎', '、', '。', '〈', '〉', '《', '》', '〔', '〕', '〘', '〙', '〚', '〛', '︑', '︒', '︹', '︺', '︽', '︾', '︿', '﹀', '﹑', '﹝', '﹞', '⦅', '⦆', '。', '、', '×', '÷', '−', '∕', '∖', '∣', '∥', '≪', '≫', '⦅', '⦆'];
    private const TRANSLIT_TO = ['AE', 'D', 'O', 'TH', 'ss', 'ae', 'd', 'o', 'th', 'D', 'd', 'H', 'h', 'i', 'q', 'L', 'l', 'L', 'l', '\'n', 'N', 'n', 'OE', 'oe', 'T', 't', 'b', 'B', 'B', 'b', 'C', 'c', 'D', 'D', 'D', 'd', 'E', 'F', 'f', 'G', 'hv', 'I', 'I', 'K', 'k', 'l', 'N', 'n', 'OI', 'oi', 'P', 'p', 't', 'T', 't', 'T', 'V', 'Y', 'y', 'Z', 'z', 'DZ', 'Dz', 'dz', 'G', 'g', 'd', 'Z', 'z', 'l', 'n', 't', 'j', 'db', 'qp', 'A', 'C', 'c', 'L', 'T', 's', 'z', 'B', 'U', 'E', 'e', 'J', 'j', 'R', 'r', 'Y', 'y', 'b', 'c', 'd', 'd', 'e', 'j', 'g', 'g', 'G', 'h', 'h', 'i', 'I', 'l', 'l', 'l', 'm', 'n', 'n', 'N', 'OE', 'r', 'r', 'r', 'R', 's', 't', 'u', 'v', 'Y', 'z', 'z', 'B', 'G', 'H', 'j', 'L', 'q', 'dz', 'dz', 'ts', 'ls', 'lz', 'A', 'AE', 'B', 'C', 'D', 'D', 'E', 'J', 'K', 'L', 'M', 'O', 'P', 'T', 'U', 'V', 'W', 'Z', 'ue', 'b', 'd', 'f', 'm', 'n', 'p', 'r', 'r', 's', 't', 'z', 'th', 'I', 'p', 'U', 'b', 'd', 'f', 'g', 'k', 'l', 'm', 'n', 'p', 'r', 's', 'v', 'x', 'z', 'a', 'd', 'e', 'e', 'i', 'u', 'a', 's', 's', 'SS', 'LL', 'll', 'V', 'v', 'Y', 'y', '(C)', '(R)', 'CE', 'Cr', 'Fr.', 'L.', 'Pts', 'TL', 'Rs', 'x', 'Rx', 'm/s', 'rad/s', 'C/kg', 'pH', 'V/m', 'A/m', ' 1/4', ' 1/2', ' 3/4', ' 1/3', ' 2/3', ' 1/5', ' 2/5', ' 3/5', ' 4/5', ' 1/6', ' 5/6', ' 1/8', ' 3/8', ' 5/8', ' 7/8', ' 1/', '0', '\'', '\'', ',', '\'', '"', '"', ',,', '"', '\'', '"', '"', '"', '<<', '>>', '<', '>', '-', '-', '-', '-', '-', '-', '-', '-', '-', '||', '/', '[', ']', '*', ',', '.', '<', '>', '<<', '>>', '[', ']', '[', ']', '[', ']', ',', '.', '[', ']', '<<', '>>', '<', '>', ',', '[', ']', '((', '))', '.', ',', '*', '/', '-', '/', '\\', '|', '||', '<<', '>>', '((', '))'];

    private static $transliterators = [];
    private static $tableZero;
    private static $tableWide;

    /**
     * @return static
     */
    public static function fromCodePoints(int ...$codes): self
    {
        $string = '';

        foreach ($codes as $code) {
            if (0x80 > $code %= 0x200000) {
                $string .= \chr($code);
            } elseif (0x800 > $code) {
                $string .= \chr(0xC0 | $code >> 6).\chr(0x80 | $code & 0x3F);
            } elseif (0x10000 > $code) {
                $string .= \chr(0xE0 | $code >> 12).\chr(0x80 | $code >> 6 & 0x3F).\chr(0x80 | $code & 0x3F);
            } else {
                $string .= \chr(0xF0 | $code >> 18).\chr(0x80 | $code >> 12 & 0x3F).\chr(0x80 | $code >> 6 & 0x3F).\chr(0x80 | $code & 0x3F);
            }
        }

        return new static($string);
    }

    /**
     * Generic UTF-8 to ASCII transliteration.
     *
     * Install the intl extension for best results.
     *
     * @param string[]|\Transliterator[]|\Closure[] $rules See "*-Latin" rules from Transliterator::listIDs()
     */
    public function ascii(array $rules = []): self
    {
        $str = clone $this;
        $s = $str->string;
        $str->string = '';

        array_unshift($rules, 'nfd');
        $rules[] = 'latin-ascii';

        if (\function_exists('transliterator_transliterate')) {
            $rules[] = 'any-latin/bgn';
        }

        $rules[] = 'nfkd';
        $rules[] = '[:nonspacing mark:] remove';

        while (\strlen($s) - 1 > $i = strspn($s, self::ASCII)) {
            if (0 < --$i) {
                $str->string .= substr($s, 0, $i);
                $s = substr($s, $i);
            }

            if (!$rule = array_shift($rules)) {
                $rules = []; // An empty rule interrupts the next ones
            }

            if ($rule instanceof \Transliterator) {
                $s = $rule->transliterate($s);
            } elseif ($rule instanceof \Closure) {
                $s = $rule($s);
            } elseif ($rule) {
                if ('nfd' === $rule = strtolower($rule)) {
                    normalizer_is_normalized($s, self::NFD) ?: $s = normalizer_normalize($s, self::NFD);
                } elseif ('nfkd' === $rule) {
                    normalizer_is_normalized($s, self::NFKD) ?: $s = normalizer_normalize($s, self::NFKD);
                } elseif ('[:nonspacing mark:] remove' === $rule) {
                    $s = preg_replace('/\p{Mn}++/u', '', $s);
                } elseif ('latin-ascii' === $rule) {
                    $s = str_replace(self::TRANSLIT_FROM, self::TRANSLIT_TO, $s);
                } elseif ('de-ascii' === $rule) {
                    $s = preg_replace("/([AUO])\u{0308}(?=\p{Ll})/u", '$1e', $s);
                    $s = str_replace(["a\u{0308}", "o\u{0308}", "u\u{0308}", "A\u{0308}", "O\u{0308}", "U\u{0308}"], ['ae', 'oe', 'ue', 'AE', 'OE', 'UE'], $s);
                } elseif (\function_exists('transliterator_transliterate')) {
                    if (null === $transliterator = self::$transliterators[$rule] ?? self::$transliterators[$rule] = \Transliterator::create($rule)) {
                        if ('any-latin/bgn' === $rule) {
                            $rule = 'any-latin';
                            $transliterator = self::$transliterators[$rule] ?? self::$transliterators[$rule] = \Transliterator::create($rule);
                        }

                        if (null === $transliterator) {
                            throw new InvalidArgumentException(sprintf('Unknown transliteration rule "%s".', $rule));
                        }

                        self::$transliterators['any-latin/bgn'] = $transliterator;
                    }

                    $s = $transliterator->transliterate($s);
                }
            } elseif (!\function_exists('iconv')) {
                $s = preg_replace('/[^\x00-\x7F]/u', '?', $s);
            } else {
                $s = @preg_replace_callback('/[^\x00-\x7F]/u', static function ($c) {
                    $c = (string) iconv('UTF-8', 'ASCII//TRANSLIT', $c[0]);

                    if ('' === $c && '' === iconv('UTF-8', 'ASCII//TRANSLIT', '²')) {
                        throw new \LogicException(sprintf('"%s" requires a translit-able iconv implementation, try installing "gnu-libiconv" if you\'re using Alpine Linux.', static::class));
                    }

                    return 1 < \strlen($c) ? ltrim($c, '\'`"^~') : ('' !== $c ? $c : '?');
                }, $s);
            }
        }

        $str->string .= $s;

        return $str;
    }

    public function camel(): parent
    {
        $str = clone $this;
        $str->string = str_replace(' ', '', preg_replace_callback('/\b./u', static function ($m) use (&$i) {
            return 1 === ++$i ? ('İ' === $m[0] ? 'i̇' : mb_strtolower($m[0], 'UTF-8')) : mb_convert_case($m[0], \MB_CASE_TITLE, 'UTF-8');
        }, preg_replace('/[^\pL0-9]++/u', ' ', $this->string)));

        return $str;
    }

    /**
     * @return int[]
     */
    public function codePointsAt(int $offset): array
    {
        $str = $this->slice($offset, 1);

        if ('' === $str->string) {
            return [];
        }

        $codePoints = [];

        foreach (preg_split('//u', $str->string, -1, \PREG_SPLIT_NO_EMPTY) as $c) {
            $codePoints[] = mb_ord($c, 'UTF-8');
        }

        return $codePoints;
    }

    public function folded(bool $compat = true): parent
    {
        $str = clone $this;

        if (!$compat || \PHP_VERSION_ID < 70300 || !\defined('Normalizer::NFKC_CF')) {
            $str->string = normalizer_normalize($str->string, $compat ? \Normalizer::NFKC : \Normalizer::NFC);
            $str->string = mb_strtolower(str_replace(self::FOLD_FROM, self::FOLD_TO, $this->string), 'UTF-8');
        } else {
            $str->string = normalizer_normalize($str->string, \Normalizer::NFKC_CF);
        }

        return $str;
    }

    public function join(array $strings, string $lastGlue = null): parent
    {
        $str = clone $this;

        $tail = null !== $lastGlue && 1 < \count($strings) ? $lastGlue.array_pop($strings) : '';
        $str->string = implode($this->string, $strings).$tail;

        if (!preg_match('//u', $str->string)) {
            throw new InvalidArgumentException('Invalid UTF-8 string.');
        }

        return $str;
    }

    public function lower(): parent
    {
        $str = clone $this;
        $str->string = mb_strtolower(str_replace('İ', 'i̇', $str->string), 'UTF-8');

        return $str;
    }

    public function match(string $regexp, int $flags = 0, int $offset = 0): array
    {
        $match = ((\PREG_PATTERN_ORDER | \PREG_SET_ORDER) & $flags) ? 'preg_match_all' : 'preg_match';

        if ($this->ignoreCase) {
            $regexp .= 'i';
        }

        set_error_handler(static function ($t, $m) { throw new InvalidArgumentException($m); });

        try {
            if (false === $match($regexp.'u', $this->string, $matches, $flags | \PREG_UNMATCHED_AS_NULL, $offset)) {
                $lastError = preg_last_error();

                foreach (get_defined_constants(true)['pcre'] as $k => $v) {
                    if ($lastError === $v && '_ERROR' === substr($k, -6)) {
                        throw new RuntimeException('Matching failed with '.$k.'.');
                    }
                }

                throw new RuntimeException('Matching failed with unknown error code.');
            }
        } finally {
            restore_error_handler();
        }

        return $matches;
    }

    /**
     * @return static
     */
    public function normalize(int $form = self::NFC): self
    {
        if (!\in_array($form, [self::NFC, self::NFD, self::NFKC, self::NFKD])) {
            throw new InvalidArgumentException('Unsupported normalization form.');
        }

        $str = clone $this;
        normalizer_is_normalized($str->string, $form) ?: $str->string = normalizer_normalize($str->string, $form);

        return $str;
    }

    public function padBoth(int $length, string $padStr = ' '): parent
    {
        if ('' === $padStr || !preg_match('//u', $padStr)) {
            throw new InvalidArgumentException('Invalid UTF-8 string.');
        }

        $pad = clone $this;
        $pad->string = $padStr;

        return $this->pad($length, $pad, \STR_PAD_BOTH);
    }

    public function padEnd(int $length, string $padStr = ' '): parent
    {
        if ('' === $padStr || !preg_match('//u', $padStr)) {
            throw new InvalidArgumentException('Invalid UTF-8 string.');
        }

        $pad = clone $this;
        $pad->string = $padStr;

        return $this->pad($length, $pad, \STR_PAD_RIGHT);
    }

    public function padStart(int $length, string $padStr = ' '): parent
    {
        if ('' === $padStr || !preg_match('//u', $padStr)) {
            throw new InvalidArgumentException('Invalid UTF-8 string.');
        }

        $pad = clone $this;
        $pad->string = $padStr;

        return $this->pad($length, $pad, \STR_PAD_LEFT);
    }

    public function replaceMatches(string $fromRegexp, $to): parent
    {
        if ($this->ignoreCase) {
            $fromRegexp .= 'i';
        }

        if (\is_array($to) || $to instanceof \Closure) {
            if (!\is_callable($to)) {
                throw new \TypeError(sprintf('Argument 2 passed to "%s::replaceMatches()" must be callable, array given.', static::class));
            }

            $replace = 'preg_replace_callback';
            $to = static function (array $m) use ($to): string {
                $to = $to($m);

                if ('' !== $to && (!\is_string($to) || !preg_match('//u', $to))) {
                    throw new InvalidArgumentException('Replace callback must return a valid UTF-8 string.');
                }

                return $to;
            };
        } elseif ('' !== $to && !preg_match('//u', $to)) {
            throw new InvalidArgumentException('Invalid UTF-8 string.');
        } else {
            $replace = 'preg_replace';
        }

        set_error_handler(static function ($t, $m) { throw new InvalidArgumentException($m); });

        try {
            if (null === $string = $replace($fromRegexp.'u', $to, $this->string)) {
                $lastError = preg_last_error();

                foreach (get_defined_constants(true)['pcre'] as $k => $v) {
                    if ($lastError === $v && '_ERROR' === substr($k, -6)) {
                        throw new RuntimeException('Matching failed with '.$k.'.');
                    }
                }

                throw new RuntimeException('Matching failed with unknown error code.');
            }
        } finally {
            restore_error_handler();
        }

        $str = clone $this;
        $str->string = $string;

        return $str;
    }

    public function reverse(): parent
    {
        $str = clone $this;
        $str->string = implode('', array_reverse(preg_split('/(\X)/u', $str->string, -1, \PREG_SPLIT_DELIM_CAPTURE | \PREG_SPLIT_NO_EMPTY)));

        return $str;
    }

    public function snake(): parent
    {
        $str = $this->camel()->title();
        $str->string = mb_strtolower(preg_replace(['/(\p{Lu}+)(\p{Lu}\p{Ll})/u', '/([\p{Ll}0-9])(\p{Lu})/u'], '\1_\2', $str->string), 'UTF-8');

        return $str;
    }

    public function title(bool $allWords = false): parent
    {
        $str = clone $this;

        $limit = $allWords ? -1 : 1;

        $str->string = preg_replace_callback('/\b./u', static function (array $m): string {
            return mb_convert_case($m[0], \MB_CASE_TITLE, 'UTF-8');
        }, $str->string, $limit);

        return $str;
    }

    public function trim(string $chars = " \t\n\r\0\x0B\x0C\u{A0}\u{FEFF}"): parent
    {
        if (" \t\n\r\0\x0B\x0C\u{A0}\u{FEFF}" !== $chars && !preg_match('//u', $chars)) {
            throw new InvalidArgumentException('Invalid UTF-8 chars.');
        }
        $chars = preg_quote($chars);

        $str = clone $this;
        $str->string = preg_replace("{^[$chars]++|[$chars]++$}uD", '', $str->string);

        return $str;
    }

    public function trimEnd(string $chars = " \t\n\r\0\x0B\x0C\u{A0}\u{FEFF}"): parent
    {
        if (" \t\n\r\0\x0B\x0C\u{A0}\u{FEFF}" !== $chars && !preg_match('//u', $chars)) {
            throw new InvalidArgumentException('Invalid UTF-8 chars.');
        }
        $chars = preg_quote($chars);

        $str = clone $this;
        $str->string = preg_replace("{[$chars]++$}uD", '', $str->string);

        return $str;
    }

    public function trimPrefix($prefix): parent
    {
        if (!$this->ignoreCase) {
            return parent::trimPrefix($prefix);
        }

        $str = clone $this;

        if ($prefix instanceof \Traversable) {
            $prefix = iterator_to_array($prefix, false);
        } elseif ($prefix instanceof parent) {
            $prefix = $prefix->string;
        }

        $prefix = implode('|', array_map('preg_quote', (array) $prefix));
        $str->string = preg_replace("{^(?:$prefix)}iuD", '', $this->string);

        return $str;
    }

    public function trimStart(string $chars = " \t\n\r\0\x0B\x0C\u{A0}\u{FEFF}"): parent
    {
        if (" \t\n\r\0\x0B\x0C\u{A0}\u{FEFF}" !== $chars && !preg_match('//u', $chars)) {
            throw new InvalidArgumentException('Invalid UTF-8 chars.');
        }
        $chars = preg_quote($chars);

        $str = clone $this;
        $str->string = preg_replace("{^[$chars]++}uD", '', $str->string);

        return $str;
    }

    public function trimSuffix($suffix): parent
    {
        if (!$this->ignoreCase) {
            return parent::trimSuffix($suffix);
        }

        $str = clone $this;

        if ($suffix instanceof \Traversable) {
            $suffix = iterator_to_array($suffix, false);
        } elseif ($suffix instanceof parent) {
            $suffix = $suffix->string;
        }

        $suffix = implode('|', array_map('preg_quote', (array) $suffix));
        $str->string = preg_replace("{(?:$suffix)$}iuD", '', $this->string);

        return $str;
    }

    public function upper(): parent
    {
        $str = clone $this;
        $str->string = mb_strtoupper($str->string, 'UTF-8');

        if (\PHP_VERSION_ID < 70300) {
            $str->string = str_replace(self::UPPER_FROM, self::UPPER_TO, $str->string);
        }

        return $str;
    }

    public function width(bool $ignoreAnsiDecoration = true): int
    {
        $width = 0;
        $s = str_replace(["\x00", "\x05", "\x07"], '', $this->string);

        if (false !== strpos($s, "\r")) {
            $s = str_replace(["\r\n", "\r"], "\n", $s);
        }

        if (!$ignoreAnsiDecoration) {
            $s = preg_replace('/[\p{Cc}\x7F]++/u', '', $s);
        }

        foreach (explode("\n", $s) as $s) {
            if ($ignoreAnsiDecoration) {
                $s = preg_replace('/(?:\x1B(?:
                    \[ [\x30-\x3F]*+ [\x20-\x2F]*+ [\x40-\x7E]
                    | [P\]X^_] .*? \x1B\\\\
                    | [\x41-\x7E]
                )|[\p{Cc}\x7F]++)/xu', '', $s);
            }

            // Non printable characters have been dropped, so wcswidth cannot logically return -1.
            $width += $this->wcswidth($s);
        }

        return $width;
    }

    /**
     * @return static
     */
    private function pad(int $len, self $pad, int $type): parent
    {
        $sLen = $this->length();

        if ($len <= $sLen) {
            return clone $this;
        }

        $padLen = $pad->length();
        $freeLen = $len - $sLen;
        $len = $freeLen % $padLen;

        switch ($type) {
            case \STR_PAD_RIGHT:
                return $this->append(str_repeat($pad->string, intdiv($freeLen, $padLen)).($len ? $pad->slice(0, $len) : ''));

            case \STR_PAD_LEFT:
                return $this->prepend(str_repeat($pad->string, intdiv($freeLen, $padLen)).($len ? $pad->slice(0, $len) : ''));

            case \STR_PAD_BOTH:
                $freeLen /= 2;

                $rightLen = ceil($freeLen);
                $len = $rightLen % $padLen;
                $str = $this->append(str_repeat($pad->string, intdiv($rightLen, $padLen)).($len ? $pad->slice(0, $len) : ''));

                $leftLen = floor($freeLen);
                $len = $leftLen % $padLen;

                return $str->prepend(str_repeat($pad->string, intdiv($leftLen, $padLen)).($len ? $pad->slice(0, $len) : ''));

            default:
                throw new InvalidArgumentException('Invalid padding type.');
        }
    }

    /**
     * Based on https://github.com/jquast/wcwidth, a Python implementation of https://www.cl.cam.ac.uk/~mgk25/ucs/wcwidth.c.
     */
    private function wcswidth(string $string): int
    {
        $width = 0;

        foreach (preg_split('//u', $string, -1, \PREG_SPLIT_NO_EMPTY) as $c) {
            $codePoint = mb_ord($c, 'UTF-8');

            if (0 === $codePoint // NULL
                || 0x034F === $codePoint // COMBINING GRAPHEME JOINER
                || (0x200B <= $codePoint && 0x200F >= $codePoint) // ZERO WIDTH SPACE to RIGHT-TO-LEFT MARK
                || 0x2028 === $codePoint // LINE SEPARATOR
                || 0x2029 === $codePoint // PARAGRAPH SEPARATOR
                || (0x202A <= $codePoint && 0x202E >= $codePoint) // LEFT-TO-RIGHT EMBEDDING to RIGHT-TO-LEFT OVERRIDE
                || (0x2060 <= $codePoint && 0x2063 >= $codePoint) // WORD JOINER to INVISIBLE SEPARATOR
            ) {
                continue;
            }

            // Non printable characters
            if (32 > $codePoint // C0 control characters
                || (0x07F <= $codePoint && 0x0A0 > $codePoint) // C1 control characters and DEL
            ) {
                return -1;
            }

            if (null === self::$tableZero) {
                self::$tableZero = require __DIR__.'/Resources/data/wcswidth_table_zero.php';
            }

            if ($codePoint >= self::$tableZero[0][0] && $codePoint <= self::$tableZero[$ubound = \count(self::$tableZero) - 1][1]) {
                $lbound = 0;
                while ($ubound >= $lbound) {
                    $mid = floor(($lbound + $ubound) / 2);

                    if ($codePoint > self::$tableZero[$mid][1]) {
                        $lbound = $mid + 1;
                    } elseif ($codePoint < self::$tableZero[$mid][0]) {
                        $ubound = $mid - 1;
                    } else {
                        continue 2;
                    }
                }
            }

            if (null === self::$tableWide) {
                self::$tableWide = require __DIR__.'/Resources/data/wcswidth_table_wide.php';
            }

            if ($codePoint >= self::$tableWide[0][0] && $codePoint <= self::$tableWide[$ubound = \count(self::$tableWide) - 1][1]) {
                $lbound = 0;
                while ($ubound >= $lbound) {
                    $mid = floor(($lbound + $ubound) / 2);

                    if ($codePoint > self::$tableWide[$mid][1]) {
                        $lbound = $mid + 1;
                    } elseif ($codePoint < self::$tableWide[$mid][0]) {
                        $ubound = $mid - 1;
                    } else {
                        $width += 2;

                        continue 2;
                    }
                }
            }

            ++$width;
        }

        return $width;
    }
}
PKϤ$Zj8��C2C2string/UnicodeString.phpnu�[���<?php

/*
 * This file is part of the Symfony package.
 *
 * (c) Fabien Potencier <fabien@symfony.com>
 *
 * For the full copyright and license information, please view the LICENSE
 * file that was distributed with this source code.
 */

namespace Symfony\Component\String;

use Symfony\Component\String\Exception\ExceptionInterface;
use Symfony\Component\String\Exception\InvalidArgumentException;

/**
 * Represents a string of Unicode grapheme clusters encoded as UTF-8.
 *
 * A letter followed by combining characters (accents typically) form what Unicode defines
 * as a grapheme cluster: a character as humans mean it in written texts. This class knows
 * about the concept and won't split a letter apart from its combining accents. It also
 * ensures all string comparisons happen on their canonically-composed representation,
 * ignoring e.g. the order in which accents are listed when a letter has many of them.
 *
 * @see https://unicode.org/reports/tr15/
 *
 * @author Nicolas Grekas <p@tchwork.com>
 * @author Hugo Hamon <hugohamon@neuf.fr>
 *
 * @throws ExceptionInterface
 */
class UnicodeString extends AbstractUnicodeString
{
    public function __construct(string $string = '')
    {
        $this->string = normalizer_is_normalized($string) ? $string : normalizer_normalize($string);

        if (false === $this->string) {
            throw new InvalidArgumentException('Invalid UTF-8 string.');
        }
    }

    public function append(string ...$suffix): AbstractString
    {
        $str = clone $this;
        $str->string = $this->string.(1 >= \count($suffix) ? ($suffix[0] ?? '') : implode('', $suffix));
        normalizer_is_normalized($str->string) ?: $str->string = normalizer_normalize($str->string);

        if (false === $str->string) {
            throw new InvalidArgumentException('Invalid UTF-8 string.');
        }

        return $str;
    }

    public function chunk(int $length = 1): array
    {
        if (1 > $length) {
            throw new InvalidArgumentException('The chunk length must be greater than zero.');
        }

        if ('' === $this->string) {
            return [];
        }

        $rx = '/(';
        while (65535 < $length) {
            $rx .= '\X{65535}';
            $length -= 65535;
        }
        $rx .= '\X{'.$length.'})/u';

        $str = clone $this;
        $chunks = [];

        foreach (preg_split($rx, $this->string, -1, \PREG_SPLIT_DELIM_CAPTURE | \PREG_SPLIT_NO_EMPTY) as $chunk) {
            $str->string = $chunk;
            $chunks[] = clone $str;
        }

        return $chunks;
    }

    public function endsWith($suffix): bool
    {
        if ($suffix instanceof AbstractString) {
            $suffix = $suffix->string;
        } elseif (\is_array($suffix) || $suffix instanceof \Traversable) {
            return parent::endsWith($suffix);
        } else {
            $suffix = (string) $suffix;
        }

        $form = null === $this->ignoreCase ? \Normalizer::NFD : \Normalizer::NFC;
        normalizer_is_normalized($suffix, $form) ?: $suffix = normalizer_normalize($suffix, $form);

        if ('' === $suffix || false === $suffix) {
            return false;
        }

        if ($this->ignoreCase) {
            return 0 === mb_stripos(grapheme_extract($this->string, \strlen($suffix), \GRAPHEME_EXTR_MAXBYTES, \strlen($this->string) - \strlen($suffix)), $suffix, 0, 'UTF-8');
        }

        return $suffix === grapheme_extract($this->string, \strlen($suffix), \GRAPHEME_EXTR_MAXBYTES, \strlen($this->string) - \strlen($suffix));
    }

    public function equalsTo($string): bool
    {
        if ($string instanceof AbstractString) {
            $string = $string->string;
        } elseif (\is_array($string) || $string instanceof \Traversable) {
            return parent::equalsTo($string);
        } else {
            $string = (string) $string;
        }

        $form = null === $this->ignoreCase ? \Normalizer::NFD : \Normalizer::NFC;
        normalizer_is_normalized($string, $form) ?: $string = normalizer_normalize($string, $form);

        if ('' !== $string && false !== $string && $this->ignoreCase) {
            return \strlen($string) === \strlen($this->string) && 0 === mb_stripos($this->string, $string, 0, 'UTF-8');
        }

        return $string === $this->string;
    }

    public function indexOf($needle, int $offset = 0): ?int
    {
        if ($needle instanceof AbstractString) {
            $needle = $needle->string;
        } elseif (\is_array($needle) || $needle instanceof \Traversable) {
            return parent::indexOf($needle, $offset);
        } else {
            $needle = (string) $needle;
        }

        $form = null === $this->ignoreCase ? \Normalizer::NFD : \Normalizer::NFC;
        normalizer_is_normalized($needle, $form) ?: $needle = normalizer_normalize($needle, $form);

        if ('' === $needle || false === $needle) {
            return null;
        }

        try {
            $i = $this->ignoreCase ? grapheme_stripos($this->string, $needle, $offset) : grapheme_strpos($this->string, $needle, $offset);
        } catch (\ValueError $e) {
            return null;
        }

        return false === $i ? null : $i;
    }

    public function indexOfLast($needle, int $offset = 0): ?int
    {
        if ($needle instanceof AbstractString) {
            $needle = $needle->string;
        } elseif (\is_array($needle) || $needle instanceof \Traversable) {
            return parent::indexOfLast($needle, $offset);
        } else {
            $needle = (string) $needle;
        }

        $form = null === $this->ignoreCase ? \Normalizer::NFD : \Normalizer::NFC;
        normalizer_is_normalized($needle, $form) ?: $needle = normalizer_normalize($needle, $form);

        if ('' === $needle || false === $needle) {
            return null;
        }

        $string = $this->string;

        if (0 > $offset) {
            // workaround https://bugs.php.net/74264
            if (0 > $offset += grapheme_strlen($needle)) {
                $string = grapheme_substr($string, 0, $offset);
            }
            $offset = 0;
        }

        $i = $this->ignoreCase ? grapheme_strripos($string, $needle, $offset) : grapheme_strrpos($string, $needle, $offset);

        return false === $i ? null : $i;
    }

    public function join(array $strings, string $lastGlue = null): AbstractString
    {
        $str = parent::join($strings, $lastGlue);
        normalizer_is_normalized($str->string) ?: $str->string = normalizer_normalize($str->string);

        return $str;
    }

    public function length(): int
    {
        return grapheme_strlen($this->string);
    }

    /**
     * @return static
     */
    public function normalize(int $form = self::NFC): parent
    {
        $str = clone $this;

        if (\in_array($form, [self::NFC, self::NFKC], true)) {
            normalizer_is_normalized($str->string, $form) ?: $str->string = normalizer_normalize($str->string, $form);
        } elseif (!\in_array($form, [self::NFD, self::NFKD], true)) {
            throw new InvalidArgumentException('Unsupported normalization form.');
        } elseif (!normalizer_is_normalized($str->string, $form)) {
            $str->string = normalizer_normalize($str->string, $form);
            $str->ignoreCase = null;
        }

        return $str;
    }

    public function prepend(string ...$prefix): AbstractString
    {
        $str = clone $this;
        $str->string = (1 >= \count($prefix) ? ($prefix[0] ?? '') : implode('', $prefix)).$this->string;
        normalizer_is_normalized($str->string) ?: $str->string = normalizer_normalize($str->string);

        if (false === $str->string) {
            throw new InvalidArgumentException('Invalid UTF-8 string.');
        }

        return $str;
    }

    public function replace(string $from, string $to): AbstractString
    {
        $str = clone $this;
        normalizer_is_normalized($from) ?: $from = normalizer_normalize($from);

        if ('' !== $from && false !== $from) {
            $tail = $str->string;
            $result = '';
            $indexOf = $this->ignoreCase ? 'grapheme_stripos' : 'grapheme_strpos';

            while ('' !== $tail && false !== $i = $indexOf($tail, $from)) {
                $slice = grapheme_substr($tail, 0, $i);
                $result .= $slice.$to;
                $tail = substr($tail, \strlen($slice) + \strlen($from));
            }

            $str->string = $result.$tail;
            normalizer_is_normalized($str->string) ?: $str->string = normalizer_normalize($str->string);

            if (false === $str->string) {
                throw new InvalidArgumentException('Invalid UTF-8 string.');
            }
        }

        return $str;
    }

    public function replaceMatches(string $fromRegexp, $to): AbstractString
    {
        $str = parent::replaceMatches($fromRegexp, $to);
        normalizer_is_normalized($str->string) ?: $str->string = normalizer_normalize($str->string);

        return $str;
    }

    public function slice(int $start = 0, int $length = null): AbstractString
    {
        $str = clone $this;

        if (\PHP_VERSION_ID < 80000 && 0 > $start && grapheme_strlen($this->string) < -$start) {
            $start = 0;
        }
        $str->string = (string) grapheme_substr($this->string, $start, $length ?? 2147483647);

        return $str;
    }

    public function splice(string $replacement, int $start = 0, int $length = null): AbstractString
    {
        $str = clone $this;

        if (\PHP_VERSION_ID < 80000 && 0 > $start && grapheme_strlen($this->string) < -$start) {
            $start = 0;
        }
        $start = $start ? \strlen(grapheme_substr($this->string, 0, $start)) : 0;
        $length = $length ? \strlen(grapheme_substr($this->string, $start, $length ?? 2147483647)) : $length;
        $str->string = substr_replace($this->string, $replacement, $start, $length ?? 2147483647);
        normalizer_is_normalized($str->string) ?: $str->string = normalizer_normalize($str->string);

        if (false === $str->string) {
            throw new InvalidArgumentException('Invalid UTF-8 string.');
        }

        return $str;
    }

    public function split(string $delimiter, int $limit = null, int $flags = null): array
    {
        if (1 > $limit = $limit ?? 2147483647) {
            throw new InvalidArgumentException('Split limit must be a positive integer.');
        }

        if ('' === $delimiter) {
            throw new InvalidArgumentException('Split delimiter is empty.');
        }

        if (null !== $flags) {
            return parent::split($delimiter.'u', $limit, $flags);
        }

        normalizer_is_normalized($delimiter) ?: $delimiter = normalizer_normalize($delimiter);

        if (false === $delimiter) {
            throw new InvalidArgumentException('Split delimiter is not a valid UTF-8 string.');
        }

        $str = clone $this;
        $tail = $this->string;
        $chunks = [];
        $indexOf = $this->ignoreCase ? 'grapheme_stripos' : 'grapheme_strpos';

        while (1 < $limit && false !== $i = $indexOf($tail, $delimiter)) {
            $str->string = grapheme_substr($tail, 0, $i);
            $chunks[] = clone $str;
            $tail = substr($tail, \strlen($str->string) + \strlen($delimiter));
            --$limit;
        }

        $str->string = $tail;
        $chunks[] = clone $str;

        return $chunks;
    }

    public function startsWith($prefix): bool
    {
        if ($prefix instanceof AbstractString) {
            $prefix = $prefix->string;
        } elseif (\is_array($prefix) || $prefix instanceof \Traversable) {
            return parent::startsWith($prefix);
        } else {
            $prefix = (string) $prefix;
        }

        $form = null === $this->ignoreCase ? \Normalizer::NFD : \Normalizer::NFC;
        normalizer_is_normalized($prefix, $form) ?: $prefix = normalizer_normalize($prefix, $form);

        if ('' === $prefix || false === $prefix) {
            return false;
        }

        if ($this->ignoreCase) {
            return 0 === mb_stripos(grapheme_extract($this->string, \strlen($prefix), \GRAPHEME_EXTR_MAXBYTES), $prefix, 0, 'UTF-8');
        }

        return $prefix === grapheme_extract($this->string, \strlen($prefix), \GRAPHEME_EXTR_MAXBYTES);
    }

    public function __wakeup()
    {
        if (!\is_string($this->string)) {
            throw new \BadMethodCallException('Cannot unserialize '.__CLASS__);
        }

        normalizer_is_normalized($this->string) ?: $this->string = normalizer_normalize($this->string);
    }

    public function __clone()
    {
        if (null === $this->ignoreCase) {
            normalizer_is_normalized($this->string) ?: $this->string = normalizer_normalize($this->string);
        }

        $this->ignoreCase = false;
    }
}
PKϤ$Z�5�$�8�8-string/Resources/data/wcswidth_table_zero.phpnu�[���<?php

/*
 * This file has been auto-generated by the Symfony String Component for internal use.
 *
 * Unicode version: 14.0.0
 * Date: 2021-09-17T09:20:30+02:00
 */

return [
    [
        768,
        879,
    ],
    [
        1155,
        1159,
    ],
    [
        1160,
        1161,
    ],
    [
        1425,
        1469,
    ],
    [
        1471,
        1471,
    ],
    [
        1473,
        1474,
    ],
    [
        1476,
        1477,
    ],
    [
        1479,
        1479,
    ],
    [
        1552,
        1562,
    ],
    [
        1611,
        1631,
    ],
    [
        1648,
        1648,
    ],
    [
        1750,
        1756,
    ],
    [
        1759,
        1764,
    ],
    [
        1767,
        1768,
    ],
    [
        1770,
        1773,
    ],
    [
        1809,
        1809,
    ],
    [
        1840,
        1866,
    ],
    [
        1958,
        1968,
    ],
    [
        2027,
        2035,
    ],
    [
        2045,
        2045,
    ],
    [
        2070,
        2073,
    ],
    [
        2075,
        2083,
    ],
    [
        2085,
        2087,
    ],
    [
        2089,
        2093,
    ],
    [
        2137,
        2139,
    ],
    [
        2200,
        2207,
    ],
    [
        2250,
        2273,
    ],
    [
        2275,
        2306,
    ],
    [
        2362,
        2362,
    ],
    [
        2364,
        2364,
    ],
    [
        2369,
        2376,
    ],
    [
        2381,
        2381,
    ],
    [
        2385,
        2391,
    ],
    [
        2402,
        2403,
    ],
    [
        2433,
        2433,
    ],
    [
        2492,
        2492,
    ],
    [
        2497,
        2500,
    ],
    [
        2509,
        2509,
    ],
    [
        2530,
        2531,
    ],
    [
        2558,
        2558,
    ],
    [
        2561,
        2562,
    ],
    [
        2620,
        2620,
    ],
    [
        2625,
        2626,
    ],
    [
        2631,
        2632,
    ],
    [
        2635,
        2637,
    ],
    [
        2641,
        2641,
    ],
    [
        2672,
        2673,
    ],
    [
        2677,
        2677,
    ],
    [
        2689,
        2690,
    ],
    [
        2748,
        2748,
    ],
    [
        2753,
        2757,
    ],
    [
        2759,
        2760,
    ],
    [
        2765,
        2765,
    ],
    [
        2786,
        2787,
    ],
    [
        2810,
        2815,
    ],
    [
        2817,
        2817,
    ],
    [
        2876,
        2876,
    ],
    [
        2879,
        2879,
    ],
    [
        2881,
        2884,
    ],
    [
        2893,
        2893,
    ],
    [
        2901,
        2902,
    ],
    [
        2914,
        2915,
    ],
    [
        2946,
        2946,
    ],
    [
        3008,
        3008,
    ],
    [
        3021,
        3021,
    ],
    [
        3072,
        3072,
    ],
    [
        3076,
        3076,
    ],
    [
        3132,
        3132,
    ],
    [
        3134,
        3136,
    ],
    [
        3142,
        3144,
    ],
    [
        3146,
        3149,
    ],
    [
        3157,
        3158,
    ],
    [
        3170,
        3171,
    ],
    [
        3201,
        3201,
    ],
    [
        3260,
        3260,
    ],
    [
        3263,
        3263,
    ],
    [
        3270,
        3270,
    ],
    [
        3276,
        3277,
    ],
    [
        3298,
        3299,
    ],
    [
        3328,
        3329,
    ],
    [
        3387,
        3388,
    ],
    [
        3393,
        3396,
    ],
    [
        3405,
        3405,
    ],
    [
        3426,
        3427,
    ],
    [
        3457,
        3457,
    ],
    [
        3530,
        3530,
    ],
    [
        3538,
        3540,
    ],
    [
        3542,
        3542,
    ],
    [
        3633,
        3633,
    ],
    [
        3636,
        3642,
    ],
    [
        3655,
        3662,
    ],
    [
        3761,
        3761,
    ],
    [
        3764,
        3772,
    ],
    [
        3784,
        3789,
    ],
    [
        3864,
        3865,
    ],
    [
        3893,
        3893,
    ],
    [
        3895,
        3895,
    ],
    [
        3897,
        3897,
    ],
    [
        3953,
        3966,
    ],
    [
        3968,
        3972,
    ],
    [
        3974,
        3975,
    ],
    [
        3981,
        3991,
    ],
    [
        3993,
        4028,
    ],
    [
        4038,
        4038,
    ],
    [
        4141,
        4144,
    ],
    [
        4146,
        4151,
    ],
    [
        4153,
        4154,
    ],
    [
        4157,
        4158,
    ],
    [
        4184,
        4185,
    ],
    [
        4190,
        4192,
    ],
    [
        4209,
        4212,
    ],
    [
        4226,
        4226,
    ],
    [
        4229,
        4230,
    ],
    [
        4237,
        4237,
    ],
    [
        4253,
        4253,
    ],
    [
        4957,
        4959,
    ],
    [
        5906,
        5908,
    ],
    [
        5938,
        5939,
    ],
    [
        5970,
        5971,
    ],
    [
        6002,
        6003,
    ],
    [
        6068,
        6069,
    ],
    [
        6071,
        6077,
    ],
    [
        6086,
        6086,
    ],
    [
        6089,
        6099,
    ],
    [
        6109,
        6109,
    ],
    [
        6155,
        6157,
    ],
    [
        6159,
        6159,
    ],
    [
        6277,
        6278,
    ],
    [
        6313,
        6313,
    ],
    [
        6432,
        6434,
    ],
    [
        6439,
        6440,
    ],
    [
        6450,
        6450,
    ],
    [
        6457,
        6459,
    ],
    [
        6679,
        6680,
    ],
    [
        6683,
        6683,
    ],
    [
        6742,
        6742,
    ],
    [
        6744,
        6750,
    ],
    [
        6752,
        6752,
    ],
    [
        6754,
        6754,
    ],
    [
        6757,
        6764,
    ],
    [
        6771,
        6780,
    ],
    [
        6783,
        6783,
    ],
    [
        6832,
        6845,
    ],
    [
        6846,
        6846,
    ],
    [
        6847,
        6862,
    ],
    [
        6912,
        6915,
    ],
    [
        6964,
        6964,
    ],
    [
        6966,
        6970,
    ],
    [
        6972,
        6972,
    ],
    [
        6978,
        6978,
    ],
    [
        7019,
        7027,
    ],
    [
        7040,
        7041,
    ],
    [
        7074,
        7077,
    ],
    [
        7080,
        7081,
    ],
    [
        7083,
        7085,
    ],
    [
        7142,
        7142,
    ],
    [
        7144,
        7145,
    ],
    [
        7149,
        7149,
    ],
    [
        7151,
        7153,
    ],
    [
        7212,
        7219,
    ],
    [
        7222,
        7223,
    ],
    [
        7376,
        7378,
    ],
    [
        7380,
        7392,
    ],
    [
        7394,
        7400,
    ],
    [
        7405,
        7405,
    ],
    [
        7412,
        7412,
    ],
    [
        7416,
        7417,
    ],
    [
        7616,
        7679,
    ],
    [
        8400,
        8412,
    ],
    [
        8413,
        8416,
    ],
    [
        8417,
        8417,
    ],
    [
        8418,
        8420,
    ],
    [
        8421,
        8432,
    ],
    [
        11503,
        11505,
    ],
    [
        11647,
        11647,
    ],
    [
        11744,
        11775,
    ],
    [
        12330,
        12333,
    ],
    [
        12441,
        12442,
    ],
    [
        42607,
        42607,
    ],
    [
        42608,
        42610,
    ],
    [
        42612,
        42621,
    ],
    [
        42654,
        42655,
    ],
    [
        42736,
        42737,
    ],
    [
        43010,
        43010,
    ],
    [
        43014,
        43014,
    ],
    [
        43019,
        43019,
    ],
    [
        43045,
        43046,
    ],
    [
        43052,
        43052,
    ],
    [
        43204,
        43205,
    ],
    [
        43232,
        43249,
    ],
    [
        43263,
        43263,
    ],
    [
        43302,
        43309,
    ],
    [
        43335,
        43345,
    ],
    [
        43392,
        43394,
    ],
    [
        43443,
        43443,
    ],
    [
        43446,
        43449,
    ],
    [
        43452,
        43453,
    ],
    [
        43493,
        43493,
    ],
    [
        43561,
        43566,
    ],
    [
        43569,
        43570,
    ],
    [
        43573,
        43574,
    ],
    [
        43587,
        43587,
    ],
    [
        43596,
        43596,
    ],
    [
        43644,
        43644,
    ],
    [
        43696,
        43696,
    ],
    [
        43698,
        43700,
    ],
    [
        43703,
        43704,
    ],
    [
        43710,
        43711,
    ],
    [
        43713,
        43713,
    ],
    [
        43756,
        43757,
    ],
    [
        43766,
        43766,
    ],
    [
        44005,
        44005,
    ],
    [
        44008,
        44008,
    ],
    [
        44013,
        44013,
    ],
    [
        64286,
        64286,
    ],
    [
        65024,
        65039,
    ],
    [
        65056,
        65071,
    ],
    [
        66045,
        66045,
    ],
    [
        66272,
        66272,
    ],
    [
        66422,
        66426,
    ],
    [
        68097,
        68099,
    ],
    [
        68101,
        68102,
    ],
    [
        68108,
        68111,
    ],
    [
        68152,
        68154,
    ],
    [
        68159,
        68159,
    ],
    [
        68325,
        68326,
    ],
    [
        68900,
        68903,
    ],
    [
        69291,
        69292,
    ],
    [
        69446,
        69456,
    ],
    [
        69506,
        69509,
    ],
    [
        69633,
        69633,
    ],
    [
        69688,
        69702,
    ],
    [
        69744,
        69744,
    ],
    [
        69747,
        69748,
    ],
    [
        69759,
        69761,
    ],
    [
        69811,
        69814,
    ],
    [
        69817,
        69818,
    ],
    [
        69826,
        69826,
    ],
    [
        69888,
        69890,
    ],
    [
        69927,
        69931,
    ],
    [
        69933,
        69940,
    ],
    [
        70003,
        70003,
    ],
    [
        70016,
        70017,
    ],
    [
        70070,
        70078,
    ],
    [
        70089,
        70092,
    ],
    [
        70095,
        70095,
    ],
    [
        70191,
        70193,
    ],
    [
        70196,
        70196,
    ],
    [
        70198,
        70199,
    ],
    [
        70206,
        70206,
    ],
    [
        70367,
        70367,
    ],
    [
        70371,
        70378,
    ],
    [
        70400,
        70401,
    ],
    [
        70459,
        70460,
    ],
    [
        70464,
        70464,
    ],
    [
        70502,
        70508,
    ],
    [
        70512,
        70516,
    ],
    [
        70712,
        70719,
    ],
    [
        70722,
        70724,
    ],
    [
        70726,
        70726,
    ],
    [
        70750,
        70750,
    ],
    [
        70835,
        70840,
    ],
    [
        70842,
        70842,
    ],
    [
        70847,
        70848,
    ],
    [
        70850,
        70851,
    ],
    [
        71090,
        71093,
    ],
    [
        71100,
        71101,
    ],
    [
        71103,
        71104,
    ],
    [
        71132,
        71133,
    ],
    [
        71219,
        71226,
    ],
    [
        71229,
        71229,
    ],
    [
        71231,
        71232,
    ],
    [
        71339,
        71339,
    ],
    [
        71341,
        71341,
    ],
    [
        71344,
        71349,
    ],
    [
        71351,
        71351,
    ],
    [
        71453,
        71455,
    ],
    [
        71458,
        71461,
    ],
    [
        71463,
        71467,
    ],
    [
        71727,
        71735,
    ],
    [
        71737,
        71738,
    ],
    [
        71995,
        71996,
    ],
    [
        71998,
        71998,
    ],
    [
        72003,
        72003,
    ],
    [
        72148,
        72151,
    ],
    [
        72154,
        72155,
    ],
    [
        72160,
        72160,
    ],
    [
        72193,
        72202,
    ],
    [
        72243,
        72248,
    ],
    [
        72251,
        72254,
    ],
    [
        72263,
        72263,
    ],
    [
        72273,
        72278,
    ],
    [
        72281,
        72283,
    ],
    [
        72330,
        72342,
    ],
    [
        72344,
        72345,
    ],
    [
        72752,
        72758,
    ],
    [
        72760,
        72765,
    ],
    [
        72767,
        72767,
    ],
    [
        72850,
        72871,
    ],
    [
        72874,
        72880,
    ],
    [
        72882,
        72883,
    ],
    [
        72885,
        72886,
    ],
    [
        73009,
        73014,
    ],
    [
        73018,
        73018,
    ],
    [
        73020,
        73021,
    ],
    [
        73023,
        73029,
    ],
    [
        73031,
        73031,
    ],
    [
        73104,
        73105,
    ],
    [
        73109,
        73109,
    ],
    [
        73111,
        73111,
    ],
    [
        73459,
        73460,
    ],
    [
        92912,
        92916,
    ],
    [
        92976,
        92982,
    ],
    [
        94031,
        94031,
    ],
    [
        94095,
        94098,
    ],
    [
        94180,
        94180,
    ],
    [
        113821,
        113822,
    ],
    [
        118528,
        118573,
    ],
    [
        118576,
        118598,
    ],
    [
        119143,
        119145,
    ],
    [
        119163,
        119170,
    ],
    [
        119173,
        119179,
    ],
    [
        119210,
        119213,
    ],
    [
        119362,
        119364,
    ],
    [
        121344,
        121398,
    ],
    [
        121403,
        121452,
    ],
    [
        121461,
        121461,
    ],
    [
        121476,
        121476,
    ],
    [
        121499,
        121503,
    ],
    [
        121505,
        121519,
    ],
    [
        122880,
        122886,
    ],
    [
        122888,
        122904,
    ],
    [
        122907,
        122913,
    ],
    [
        122915,
        122916,
    ],
    [
        122918,
        122922,
    ],
    [
        123184,
        123190,
    ],
    [
        123566,
        123566,
    ],
    [
        123628,
        123631,
    ],
    [
        125136,
        125142,
    ],
    [
        125252,
        125258,
    ],
    [
        917760,
        917999,
    ],
];
PKϤ$Zܰ�O0O0-string/Resources/data/wcswidth_table_wide.phpnu�[���<?php

/*
 * This file has been auto-generated by the Symfony String Component for internal use.
 *
 * Unicode version: 14.0.0
 * Date: 2021-09-17T09:20:30+02:00
 */

return [
    [
        4352,
        4447,
    ],
    [
        8986,
        8987,
    ],
    [
        9001,
        9001,
    ],
    [
        9002,
        9002,
    ],
    [
        9193,
        9196,
    ],
    [
        9200,
        9200,
    ],
    [
        9203,
        9203,
    ],
    [
        9725,
        9726,
    ],
    [
        9748,
        9749,
    ],
    [
        9800,
        9811,
    ],
    [
        9855,
        9855,
    ],
    [
        9875,
        9875,
    ],
    [
        9889,
        9889,
    ],
    [
        9898,
        9899,
    ],
    [
        9917,
        9918,
    ],
    [
        9924,
        9925,
    ],
    [
        9934,
        9934,
    ],
    [
        9940,
        9940,
    ],
    [
        9962,
        9962,
    ],
    [
        9970,
        9971,
    ],
    [
        9973,
        9973,
    ],
    [
        9978,
        9978,
    ],
    [
        9981,
        9981,
    ],
    [
        9989,
        9989,
    ],
    [
        9994,
        9995,
    ],
    [
        10024,
        10024,
    ],
    [
        10060,
        10060,
    ],
    [
        10062,
        10062,
    ],
    [
        10067,
        10069,
    ],
    [
        10071,
        10071,
    ],
    [
        10133,
        10135,
    ],
    [
        10160,
        10160,
    ],
    [
        10175,
        10175,
    ],
    [
        11035,
        11036,
    ],
    [
        11088,
        11088,
    ],
    [
        11093,
        11093,
    ],
    [
        11904,
        11929,
    ],
    [
        11931,
        12019,
    ],
    [
        12032,
        12245,
    ],
    [
        12272,
        12283,
    ],
    [
        12288,
        12288,
    ],
    [
        12289,
        12291,
    ],
    [
        12292,
        12292,
    ],
    [
        12293,
        12293,
    ],
    [
        12294,
        12294,
    ],
    [
        12295,
        12295,
    ],
    [
        12296,
        12296,
    ],
    [
        12297,
        12297,
    ],
    [
        12298,
        12298,
    ],
    [
        12299,
        12299,
    ],
    [
        12300,
        12300,
    ],
    [
        12301,
        12301,
    ],
    [
        12302,
        12302,
    ],
    [
        12303,
        12303,
    ],
    [
        12304,
        12304,
    ],
    [
        12305,
        12305,
    ],
    [
        12306,
        12307,
    ],
    [
        12308,
        12308,
    ],
    [
        12309,
        12309,
    ],
    [
        12310,
        12310,
    ],
    [
        12311,
        12311,
    ],
    [
        12312,
        12312,
    ],
    [
        12313,
        12313,
    ],
    [
        12314,
        12314,
    ],
    [
        12315,
        12315,
    ],
    [
        12316,
        12316,
    ],
    [
        12317,
        12317,
    ],
    [
        12318,
        12319,
    ],
    [
        12320,
        12320,
    ],
    [
        12321,
        12329,
    ],
    [
        12330,
        12333,
    ],
    [
        12334,
        12335,
    ],
    [
        12336,
        12336,
    ],
    [
        12337,
        12341,
    ],
    [
        12342,
        12343,
    ],
    [
        12344,
        12346,
    ],
    [
        12347,
        12347,
    ],
    [
        12348,
        12348,
    ],
    [
        12349,
        12349,
    ],
    [
        12350,
        12350,
    ],
    [
        12353,
        12438,
    ],
    [
        12441,
        12442,
    ],
    [
        12443,
        12444,
    ],
    [
        12445,
        12446,
    ],
    [
        12447,
        12447,
    ],
    [
        12448,
        12448,
    ],
    [
        12449,
        12538,
    ],
    [
        12539,
        12539,
    ],
    [
        12540,
        12542,
    ],
    [
        12543,
        12543,
    ],
    [
        12549,
        12591,
    ],
    [
        12593,
        12686,
    ],
    [
        12688,
        12689,
    ],
    [
        12690,
        12693,
    ],
    [
        12694,
        12703,
    ],
    [
        12704,
        12735,
    ],
    [
        12736,
        12771,
    ],
    [
        12784,
        12799,
    ],
    [
        12800,
        12830,
    ],
    [
        12832,
        12841,
    ],
    [
        12842,
        12871,
    ],
    [
        12880,
        12880,
    ],
    [
        12881,
        12895,
    ],
    [
        12896,
        12927,
    ],
    [
        12928,
        12937,
    ],
    [
        12938,
        12976,
    ],
    [
        12977,
        12991,
    ],
    [
        12992,
        13055,
    ],
    [
        13056,
        13311,
    ],
    [
        13312,
        19903,
    ],
    [
        19968,
        40959,
    ],
    [
        40960,
        40980,
    ],
    [
        40981,
        40981,
    ],
    [
        40982,
        42124,
    ],
    [
        42128,
        42182,
    ],
    [
        43360,
        43388,
    ],
    [
        44032,
        55203,
    ],
    [
        63744,
        64109,
    ],
    [
        64110,
        64111,
    ],
    [
        64112,
        64217,
    ],
    [
        64218,
        64255,
    ],
    [
        65040,
        65046,
    ],
    [
        65047,
        65047,
    ],
    [
        65048,
        65048,
    ],
    [
        65049,
        65049,
    ],
    [
        65072,
        65072,
    ],
    [
        65073,
        65074,
    ],
    [
        65075,
        65076,
    ],
    [
        65077,
        65077,
    ],
    [
        65078,
        65078,
    ],
    [
        65079,
        65079,
    ],
    [
        65080,
        65080,
    ],
    [
        65081,
        65081,
    ],
    [
        65082,
        65082,
    ],
    [
        65083,
        65083,
    ],
    [
        65084,
        65084,
    ],
    [
        65085,
        65085,
    ],
    [
        65086,
        65086,
    ],
    [
        65087,
        65087,
    ],
    [
        65088,
        65088,
    ],
    [
        65089,
        65089,
    ],
    [
        65090,
        65090,
    ],
    [
        65091,
        65091,
    ],
    [
        65092,
        65092,
    ],
    [
        65093,
        65094,
    ],
    [
        65095,
        65095,
    ],
    [
        65096,
        65096,
    ],
    [
        65097,
        65100,
    ],
    [
        65101,
        65103,
    ],
    [
        65104,
        65106,
    ],
    [
        65108,
        65111,
    ],
    [
        65112,
        65112,
    ],
    [
        65113,
        65113,
    ],
    [
        65114,
        65114,
    ],
    [
        65115,
        65115,
    ],
    [
        65116,
        65116,
    ],
    [
        65117,
        65117,
    ],
    [
        65118,
        65118,
    ],
    [
        65119,
        65121,
    ],
    [
        65122,
        65122,
    ],
    [
        65123,
        65123,
    ],
    [
        65124,
        65126,
    ],
    [
        65128,
        65128,
    ],
    [
        65129,
        65129,
    ],
    [
        65130,
        65131,
    ],
    [
        65281,
        65283,
    ],
    [
        65284,
        65284,
    ],
    [
        65285,
        65287,
    ],
    [
        65288,
        65288,
    ],
    [
        65289,
        65289,
    ],
    [
        65290,
        65290,
    ],
    [
        65291,
        65291,
    ],
    [
        65292,
        65292,
    ],
    [
        65293,
        65293,
    ],
    [
        65294,
        65295,
    ],
    [
        65296,
        65305,
    ],
    [
        65306,
        65307,
    ],
    [
        65308,
        65310,
    ],
    [
        65311,
        65312,
    ],
    [
        65313,
        65338,
    ],
    [
        65339,
        65339,
    ],
    [
        65340,
        65340,
    ],
    [
        65341,
        65341,
    ],
    [
        65342,
        65342,
    ],
    [
        65343,
        65343,
    ],
    [
        65344,
        65344,
    ],
    [
        65345,
        65370,
    ],
    [
        65371,
        65371,
    ],
    [
        65372,
        65372,
    ],
    [
        65373,
        65373,
    ],
    [
        65374,
        65374,
    ],
    [
        65375,
        65375,
    ],
    [
        65376,
        65376,
    ],
    [
        65504,
        65505,
    ],
    [
        65506,
        65506,
    ],
    [
        65507,
        65507,
    ],
    [
        65508,
        65508,
    ],
    [
        65509,
        65510,
    ],
    [
        94176,
        94177,
    ],
    [
        94178,
        94178,
    ],
    [
        94179,
        94179,
    ],
    [
        94180,
        94180,
    ],
    [
        94192,
        94193,
    ],
    [
        94208,
        100343,
    ],
    [
        100352,
        101119,
    ],
    [
        101120,
        101589,
    ],
    [
        101632,
        101640,
    ],
    [
        110576,
        110579,
    ],
    [
        110581,
        110587,
    ],
    [
        110589,
        110590,
    ],
    [
        110592,
        110847,
    ],
    [
        110848,
        110882,
    ],
    [
        110928,
        110930,
    ],
    [
        110948,
        110951,
    ],
    [
        110960,
        111355,
    ],
    [
        126980,
        126980,
    ],
    [
        127183,
        127183,
    ],
    [
        127374,
        127374,
    ],
    [
        127377,
        127386,
    ],
    [
        127488,
        127490,
    ],
    [
        127504,
        127547,
    ],
    [
        127552,
        127560,
    ],
    [
        127568,
        127569,
    ],
    [
        127584,
        127589,
    ],
    [
        127744,
        127776,
    ],
    [
        127789,
        127797,
    ],
    [
        127799,
        127868,
    ],
    [
        127870,
        127891,
    ],
    [
        127904,
        127946,
    ],
    [
        127951,
        127955,
    ],
    [
        127968,
        127984,
    ],
    [
        127988,
        127988,
    ],
    [
        127992,
        127994,
    ],
    [
        127995,
        127999,
    ],
    [
        128000,
        128062,
    ],
    [
        128064,
        128064,
    ],
    [
        128066,
        128252,
    ],
    [
        128255,
        128317,
    ],
    [
        128331,
        128334,
    ],
    [
        128336,
        128359,
    ],
    [
        128378,
        128378,
    ],
    [
        128405,
        128406,
    ],
    [
        128420,
        128420,
    ],
    [
        128507,
        128511,
    ],
    [
        128512,
        128591,
    ],
    [
        128640,
        128709,
    ],
    [
        128716,
        128716,
    ],
    [
        128720,
        128722,
    ],
    [
        128725,
        128727,
    ],
    [
        128733,
        128735,
    ],
    [
        128747,
        128748,
    ],
    [
        128756,
        128764,
    ],
    [
        128992,
        129003,
    ],
    [
        129008,
        129008,
    ],
    [
        129292,
        129338,
    ],
    [
        129340,
        129349,
    ],
    [
        129351,
        129535,
    ],
    [
        129648,
        129652,
    ],
    [
        129656,
        129660,
    ],
    [
        129664,
        129670,
    ],
    [
        129680,
        129708,
    ],
    [
        129712,
        129722,
    ],
    [
        129728,
        129733,
    ],
    [
        129744,
        129753,
    ],
    [
        129760,
        129767,
    ],
    [
        129776,
        129782,
    ],
    [
        131072,
        173791,
    ],
    [
        173792,
        173823,
    ],
    [
        173824,
        177976,
    ],
    [
        177977,
        177983,
    ],
    [
        177984,
        178205,
    ],
    [
        178206,
        178207,
    ],
    [
        178208,
        183969,
    ],
    [
        183970,
        183983,
    ],
    [
        183984,
        191456,
    ],
    [
        191457,
        194559,
    ],
    [
        194560,
        195101,
    ],
    [
        195102,
        195103,
    ],
    [
        195104,
        196605,
    ],
    [
        196608,
        201546,
    ],
    [
        201547,
        262141,
    ],
];
PKϤ$Z�ې]]string/Resources/functions.phpnu�[���<?php

/*
 * This file is part of the Symfony package.
 *
 * (c) Fabien Potencier <fabien@symfony.com>
 *
 * For the full copyright and license information, please view the LICENSE
 * file that was distributed with this source code.
 */

namespace Symfony\Component\String;

if (!\function_exists(u::class)) {
    function u(?string $string = ''): UnicodeString
    {
        return new UnicodeString($string ?? '');
    }
}

if (!\function_exists(b::class)) {
    function b(?string $string = ''): ByteString
    {
        return new ByteString($string ?? '');
    }
}

if (!\function_exists(s::class)) {
    /**
     * @return UnicodeString|ByteString
     */
    function s(?string $string = ''): AbstractString
    {
        $string = $string ?? '';

        return preg_match('//u', $string) ? new UnicodeString($string) : new ByteString($string);
    }
}
PKϤ$Z�I!))string/LazyString.phpnu�[���<?php

/*
 * This file is part of the Symfony package.
 *
 * (c) Fabien Potencier <fabien@symfony.com>
 *
 * For the full copyright and license information, please view the LICENSE
 * file that was distributed with this source code.
 */

namespace Symfony\Component\String;

/**
 * A string whose value is computed lazily by a callback.
 *
 * @author Nicolas Grekas <p@tchwork.com>
 */
class LazyString implements \Stringable, \JsonSerializable
{
    private $value;

    /**
     * @param callable|array $callback A callable or a [Closure, method] lazy-callable
     *
     * @return static
     */
    public static function fromCallable($callback, ...$arguments): self
    {
        if (!\is_callable($callback) && !(\is_array($callback) && isset($callback[0]) && $callback[0] instanceof \Closure && 2 >= \count($callback))) {
            throw new \TypeError(sprintf('Argument 1 passed to "%s()" must be a callable or a [Closure, method] lazy-callable, "%s" given.', __METHOD__, get_debug_type($callback)));
        }

        $lazyString = new static();
        $lazyString->value = static function () use (&$callback, &$arguments, &$value): string {
            if (null !== $arguments) {
                if (!\is_callable($callback)) {
                    $callback[0] = $callback[0]();
                    $callback[1] = $callback[1] ?? '__invoke';
                }
                $value = $callback(...$arguments);
                $callback = self::getPrettyName($callback);
                $arguments = null;
            }

            return $value ?? '';
        };

        return $lazyString;
    }

    /**
     * @param string|int|float|bool|\Stringable $value
     *
     * @return static
     */
    public static function fromStringable($value): self
    {
        if (!self::isStringable($value)) {
            throw new \TypeError(sprintf('Argument 1 passed to "%s()" must be a scalar or a stringable object, "%s" given.', __METHOD__, get_debug_type($value)));
        }

        if (\is_object($value)) {
            return static::fromCallable([$value, '__toString']);
        }

        $lazyString = new static();
        $lazyString->value = (string) $value;

        return $lazyString;
    }

    /**
     * Tells whether the provided value can be cast to string.
     */
    final public static function isStringable($value): bool
    {
        return \is_string($value) || $value instanceof self || (\is_object($value) ? method_exists($value, '__toString') : is_scalar($value));
    }

    /**
     * Casts scalars and stringable objects to strings.
     *
     * @param object|string|int|float|bool $value
     *
     * @throws \TypeError When the provided value is not stringable
     */
    final public static function resolve($value): string
    {
        return $value;
    }

    /**
     * @return string
     */
    public function __toString()
    {
        if (\is_string($this->value)) {
            return $this->value;
        }

        try {
            return $this->value = ($this->value)();
        } catch (\Throwable $e) {
            if (\TypeError::class === \get_class($e) && __FILE__ === $e->getFile()) {
                $type = explode(', ', $e->getMessage());
                $type = substr(array_pop($type), 0, -\strlen(' returned'));
                $r = new \ReflectionFunction($this->value);
                $callback = $r->getStaticVariables()['callback'];

                $e = new \TypeError(sprintf('Return value of %s() passed to %s::fromCallable() must be of the type string, %s returned.', $callback, static::class, $type));
            }

            if (\PHP_VERSION_ID < 70400) {
                // leverage the ErrorHandler component with graceful fallback when it's not available
                return trigger_error($e, \E_USER_ERROR);
            }

            throw $e;
        }
    }

    public function __sleep(): array
    {
        $this->__toString();

        return ['value'];
    }

    public function jsonSerialize(): string
    {
        return $this->__toString();
    }

    private function __construct()
    {
    }

    private static function getPrettyName(callable $callback): string
    {
        if (\is_string($callback)) {
            return $callback;
        }

        if (\is_array($callback)) {
            $class = \is_object($callback[0]) ? get_debug_type($callback[0]) : $callback[0];
            $method = $callback[1];
        } elseif ($callback instanceof \Closure) {
            $r = new \ReflectionFunction($callback);

            if (false !== strpos($r->name, '{closure}') || !$class = $r->getClosureScopeClass()) {
                return $r->name;
            }

            $class = $class->name;
            $method = $r->name;
        } else {
            $class = get_debug_type($callback);
            $method = '__invoke';
        }

        return $class.'::'.$method;
    }
}
PKϤ$Z$���QQ'string/Exception/ExceptionInterface.phpnu�[���<?php

/*
 * This file is part of the Symfony package.
 *
 * (c) Fabien Potencier <fabien@symfony.com>
 *
 * For the full copyright and license information, please view the LICENSE
 * file that was distributed with this source code.
 */

namespace Symfony\Component\String\Exception;

interface ExceptionInterface extends \Throwable
{
}
PKϤ$Ze�����-string/Exception/InvalidArgumentException.phpnu�[���<?php

/*
 * This file is part of the Symfony package.
 *
 * (c) Fabien Potencier <fabien@symfony.com>
 *
 * For the full copyright and license information, please view the LICENSE
 * file that was distributed with this source code.
 */

namespace Symfony\Component\String\Exception;

class InvalidArgumentException extends \InvalidArgumentException implements ExceptionInterface
{
}
PKϤ$Z��0�pp%string/Exception/RuntimeException.phpnu�[���<?php

/*
 * This file is part of the Symfony package.
 *
 * (c) Fabien Potencier <fabien@symfony.com>
 *
 * For the full copyright and license information, please view the LICENSE
 * file that was distributed with this source code.
 */

namespace Symfony\Component\String\Exception;

class RuntimeException extends \RuntimeException implements ExceptionInterface
{
}
PKϤ$Z���DDstring/CHANGELOG.mdnu�[���CHANGELOG
=========

5.4
---

 * Add `trimSuffix()` and `trimPrefix()` methods

5.3
---

 * Made `AsciiSlugger` fallback to parent locale's symbolsMap

5.2.0
-----

 * added a `FrenchInflector` class

5.1.0
-----

 * added the `AbstractString::reverse()` method
 * made `AbstractString::width()` follow POSIX.1-2001
 * added `LazyString` which provides memoizing stringable objects
 * The component is not marked as `@experimental` anymore
 * added the `s()` helper method to get either an `UnicodeString` or `ByteString` instance,
   depending of the input string UTF-8 compliancy
 * added `$cut` parameter to `Symfony\Component\String\AbstractString::truncate()`
 * added `AbstractString::containsAny()`
 * allow passing a string of custom characters to `ByteString::fromRandom()`

5.0.0
-----

 * added the component as experimental
PKϤ$Z�M-��;�;string/ByteString.phpnu�[���<?php

/*
 * This file is part of the Symfony package.
 *
 * (c) Fabien Potencier <fabien@symfony.com>
 *
 * For the full copyright and license information, please view the LICENSE
 * file that was distributed with this source code.
 */

namespace Symfony\Component\String;

use Symfony\Component\String\Exception\ExceptionInterface;
use Symfony\Component\String\Exception\InvalidArgumentException;
use Symfony\Component\String\Exception\RuntimeException;

/**
 * Represents a binary-safe string of bytes.
 *
 * @author Nicolas Grekas <p@tchwork.com>
 * @author Hugo Hamon <hugohamon@neuf.fr>
 *
 * @throws ExceptionInterface
 */
class ByteString extends AbstractString
{
    private const ALPHABET_ALPHANUMERIC = '123456789ABCDEFGHJKLMNPQRSTUVWXYZabcdefghijkmnopqrstuvwxyz';

    public function __construct(string $string = '')
    {
        $this->string = $string;
    }

    /*
     * The following method was derived from code of the Hack Standard Library (v4.40 - 2020-05-03)
     *
     * https://github.com/hhvm/hsl/blob/80a42c02f036f72a42f0415e80d6b847f4bf62d5/src/random/private.php#L16
     *
     * Code subject to the MIT license (https://github.com/hhvm/hsl/blob/master/LICENSE).
     *
     * Copyright (c) 2004-2020, Facebook, Inc. (https://www.facebook.com/)
     */

    public static function fromRandom(int $length = 16, string $alphabet = null): self
    {
        if ($length <= 0) {
            throw new InvalidArgumentException(sprintf('A strictly positive length is expected, "%d" given.', $length));
        }

        $alphabet = $alphabet ?? self::ALPHABET_ALPHANUMERIC;
        $alphabetSize = \strlen($alphabet);
        $bits = (int) ceil(log($alphabetSize, 2.0));
        if ($bits <= 0 || $bits > 56) {
            throw new InvalidArgumentException('The length of the alphabet must in the [2^1, 2^56] range.');
        }

        $ret = '';
        while ($length > 0) {
            $urandomLength = (int) ceil(2 * $length * $bits / 8.0);
            $data = random_bytes($urandomLength);
            $unpackedData = 0;
            $unpackedBits = 0;
            for ($i = 0; $i < $urandomLength && $length > 0; ++$i) {
                // Unpack 8 bits
                $unpackedData = ($unpackedData << 8) | \ord($data[$i]);
                $unpackedBits += 8;

                // While we have enough bits to select a character from the alphabet, keep
                // consuming the random data
                for (; $unpackedBits >= $bits && $length > 0; $unpackedBits -= $bits) {
                    $index = ($unpackedData & ((1 << $bits) - 1));
                    $unpackedData >>= $bits;
                    // Unfortunately, the alphabet size is not necessarily a power of two.
                    // Worst case, it is 2^k + 1, which means we need (k+1) bits and we
                    // have around a 50% chance of missing as k gets larger
                    if ($index < $alphabetSize) {
                        $ret .= $alphabet[$index];
                        --$length;
                    }
                }
            }
        }

        return new static($ret);
    }

    public function bytesAt(int $offset): array
    {
        $str = $this->string[$offset] ?? '';

        return '' === $str ? [] : [\ord($str)];
    }

    public function append(string ...$suffix): parent
    {
        $str = clone $this;
        $str->string .= 1 >= \count($suffix) ? ($suffix[0] ?? '') : implode('', $suffix);

        return $str;
    }

    public function camel(): parent
    {
        $str = clone $this;
        $str->string = lcfirst(str_replace(' ', '', ucwords(preg_replace('/[^a-zA-Z0-9\x7f-\xff]++/', ' ', $this->string))));

        return $str;
    }

    public function chunk(int $length = 1): array
    {
        if (1 > $length) {
            throw new InvalidArgumentException('The chunk length must be greater than zero.');
        }

        if ('' === $this->string) {
            return [];
        }

        $str = clone $this;
        $chunks = [];

        foreach (str_split($this->string, $length) as $chunk) {
            $str->string = $chunk;
            $chunks[] = clone $str;
        }

        return $chunks;
    }

    public function endsWith($suffix): bool
    {
        if ($suffix instanceof parent) {
            $suffix = $suffix->string;
        } elseif (\is_array($suffix) || $suffix instanceof \Traversable) {
            return parent::endsWith($suffix);
        } else {
            $suffix = (string) $suffix;
        }

        return '' !== $suffix && \strlen($this->string) >= \strlen($suffix) && 0 === substr_compare($this->string, $suffix, -\strlen($suffix), null, $this->ignoreCase);
    }

    public function equalsTo($string): bool
    {
        if ($string instanceof parent) {
            $string = $string->string;
        } elseif (\is_array($string) || $string instanceof \Traversable) {
            return parent::equalsTo($string);
        } else {
            $string = (string) $string;
        }

        if ('' !== $string && $this->ignoreCase) {
            return 0 === strcasecmp($string, $this->string);
        }

        return $string === $this->string;
    }

    public function folded(): parent
    {
        $str = clone $this;
        $str->string = strtolower($str->string);

        return $str;
    }

    public function indexOf($needle, int $offset = 0): ?int
    {
        if ($needle instanceof parent) {
            $needle = $needle->string;
        } elseif (\is_array($needle) || $needle instanceof \Traversable) {
            return parent::indexOf($needle, $offset);
        } else {
            $needle = (string) $needle;
        }

        if ('' === $needle) {
            return null;
        }

        $i = $this->ignoreCase ? stripos($this->string, $needle, $offset) : strpos($this->string, $needle, $offset);

        return false === $i ? null : $i;
    }

    public function indexOfLast($needle, int $offset = 0): ?int
    {
        if ($needle instanceof parent) {
            $needle = $needle->string;
        } elseif (\is_array($needle) || $needle instanceof \Traversable) {
            return parent::indexOfLast($needle, $offset);
        } else {
            $needle = (string) $needle;
        }

        if ('' === $needle) {
            return null;
        }

        $i = $this->ignoreCase ? strripos($this->string, $needle, $offset) : strrpos($this->string, $needle, $offset);

        return false === $i ? null : $i;
    }

    public function isUtf8(): bool
    {
        return '' === $this->string || preg_match('//u', $this->string);
    }

    public function join(array $strings, string $lastGlue = null): parent
    {
        $str = clone $this;

        $tail = null !== $lastGlue && 1 < \count($strings) ? $lastGlue.array_pop($strings) : '';
        $str->string = implode($this->string, $strings).$tail;

        return $str;
    }

    public function length(): int
    {
        return \strlen($this->string);
    }

    public function lower(): parent
    {
        $str = clone $this;
        $str->string = strtolower($str->string);

        return $str;
    }

    public function match(string $regexp, int $flags = 0, int $offset = 0): array
    {
        $match = ((\PREG_PATTERN_ORDER | \PREG_SET_ORDER) & $flags) ? 'preg_match_all' : 'preg_match';

        if ($this->ignoreCase) {
            $regexp .= 'i';
        }

        set_error_handler(static function ($t, $m) { throw new InvalidArgumentException($m); });

        try {
            if (false === $match($regexp, $this->string, $matches, $flags | \PREG_UNMATCHED_AS_NULL, $offset)) {
                $lastError = preg_last_error();

                foreach (get_defined_constants(true)['pcre'] as $k => $v) {
                    if ($lastError === $v && '_ERROR' === substr($k, -6)) {
                        throw new RuntimeException('Matching failed with '.$k.'.');
                    }
                }

                throw new RuntimeException('Matching failed with unknown error code.');
            }
        } finally {
            restore_error_handler();
        }

        return $matches;
    }

    public function padBoth(int $length, string $padStr = ' '): parent
    {
        $str = clone $this;
        $str->string = str_pad($this->string, $length, $padStr, \STR_PAD_BOTH);

        return $str;
    }

    public function padEnd(int $length, string $padStr = ' '): parent
    {
        $str = clone $this;
        $str->string = str_pad($this->string, $length, $padStr, \STR_PAD_RIGHT);

        return $str;
    }

    public function padStart(int $length, string $padStr = ' '): parent
    {
        $str = clone $this;
        $str->string = str_pad($this->string, $length, $padStr, \STR_PAD_LEFT);

        return $str;
    }

    public function prepend(string ...$prefix): parent
    {
        $str = clone $this;
        $str->string = (1 >= \count($prefix) ? ($prefix[0] ?? '') : implode('', $prefix)).$str->string;

        return $str;
    }

    public function replace(string $from, string $to): parent
    {
        $str = clone $this;

        if ('' !== $from) {
            $str->string = $this->ignoreCase ? str_ireplace($from, $to, $this->string) : str_replace($from, $to, $this->string);
        }

        return $str;
    }

    public function replaceMatches(string $fromRegexp, $to): parent
    {
        if ($this->ignoreCase) {
            $fromRegexp .= 'i';
        }

        if (\is_array($to)) {
            if (!\is_callable($to)) {
                throw new \TypeError(sprintf('Argument 2 passed to "%s::replaceMatches()" must be callable, array given.', static::class));
            }

            $replace = 'preg_replace_callback';
        } else {
            $replace = $to instanceof \Closure ? 'preg_replace_callback' : 'preg_replace';
        }

        set_error_handler(static function ($t, $m) { throw new InvalidArgumentException($m); });

        try {
            if (null === $string = $replace($fromRegexp, $to, $this->string)) {
                $lastError = preg_last_error();

                foreach (get_defined_constants(true)['pcre'] as $k => $v) {
                    if ($lastError === $v && '_ERROR' === substr($k, -6)) {
                        throw new RuntimeException('Matching failed with '.$k.'.');
                    }
                }

                throw new RuntimeException('Matching failed with unknown error code.');
            }
        } finally {
            restore_error_handler();
        }

        $str = clone $this;
        $str->string = $string;

        return $str;
    }

    public function reverse(): parent
    {
        $str = clone $this;
        $str->string = strrev($str->string);

        return $str;
    }

    public function slice(int $start = 0, int $length = null): parent
    {
        $str = clone $this;
        $str->string = (string) substr($this->string, $start, $length ?? \PHP_INT_MAX);

        return $str;
    }

    public function snake(): parent
    {
        $str = $this->camel()->title();
        $str->string = strtolower(preg_replace(['/([A-Z]+)([A-Z][a-z])/', '/([a-z\d])([A-Z])/'], '\1_\2', $str->string));

        return $str;
    }

    public function splice(string $replacement, int $start = 0, int $length = null): parent
    {
        $str = clone $this;
        $str->string = substr_replace($this->string, $replacement, $start, $length ?? \PHP_INT_MAX);

        return $str;
    }

    public function split(string $delimiter, int $limit = null, int $flags = null): array
    {
        if (1 > $limit = $limit ?? \PHP_INT_MAX) {
            throw new InvalidArgumentException('Split limit must be a positive integer.');
        }

        if ('' === $delimiter) {
            throw new InvalidArgumentException('Split delimiter is empty.');
        }

        if (null !== $flags) {
            return parent::split($delimiter, $limit, $flags);
        }

        $str = clone $this;
        $chunks = $this->ignoreCase
            ? preg_split('{'.preg_quote($delimiter).'}iD', $this->string, $limit)
            : explode($delimiter, $this->string, $limit);

        foreach ($chunks as &$chunk) {
            $str->string = $chunk;
            $chunk = clone $str;
        }

        return $chunks;
    }

    public function startsWith($prefix): bool
    {
        if ($prefix instanceof parent) {
            $prefix = $prefix->string;
        } elseif (!\is_string($prefix)) {
            return parent::startsWith($prefix);
        }

        return '' !== $prefix && 0 === ($this->ignoreCase ? strncasecmp($this->string, $prefix, \strlen($prefix)) : strncmp($this->string, $prefix, \strlen($prefix)));
    }

    public function title(bool $allWords = false): parent
    {
        $str = clone $this;
        $str->string = $allWords ? ucwords($str->string) : ucfirst($str->string);

        return $str;
    }

    public function toUnicodeString(string $fromEncoding = null): UnicodeString
    {
        return new UnicodeString($this->toCodePointString($fromEncoding)->string);
    }

    public function toCodePointString(string $fromEncoding = null): CodePointString
    {
        $u = new CodePointString();

        if (\in_array($fromEncoding, [null, 'utf8', 'utf-8', 'UTF8', 'UTF-8'], true) && preg_match('//u', $this->string)) {
            $u->string = $this->string;

            return $u;
        }

        set_error_handler(static function ($t, $m) { throw new InvalidArgumentException($m); });

        try {
            try {
                $validEncoding = false !== mb_detect_encoding($this->string, $fromEncoding ?? 'Windows-1252', true);
            } catch (InvalidArgumentException $e) {
                if (!\function_exists('iconv')) {
                    throw $e;
                }

                $u->string = iconv($fromEncoding ?? 'Windows-1252', 'UTF-8', $this->string);

                return $u;
            }
        } finally {
            restore_error_handler();
        }

        if (!$validEncoding) {
            throw new InvalidArgumentException(sprintf('Invalid "%s" string.', $fromEncoding ?? 'Windows-1252'));
        }

        $u->string = mb_convert_encoding($this->string, 'UTF-8', $fromEncoding ?? 'Windows-1252');

        return $u;
    }

    public function trim(string $chars = " \t\n\r\0\x0B\x0C"): parent
    {
        $str = clone $this;
        $str->string = trim($str->string, $chars);

        return $str;
    }

    public function trimEnd(string $chars = " \t\n\r\0\x0B\x0C"): parent
    {
        $str = clone $this;
        $str->string = rtrim($str->string, $chars);

        return $str;
    }

    public function trimStart(string $chars = " \t\n\r\0\x0B\x0C"): parent
    {
        $str = clone $this;
        $str->string = ltrim($str->string, $chars);

        return $str;
    }

    public function upper(): parent
    {
        $str = clone $this;
        $str->string = strtoupper($str->string);

        return $str;
    }

    public function width(bool $ignoreAnsiDecoration = true): int
    {
        $string = preg_match('//u', $this->string) ? $this->string : preg_replace('/[\x80-\xFF]/', '?', $this->string);

        return (new CodePointString($string))->width($ignoreAnsiDecoration);
    }
}
PKϤ$Z=��))string/LICENSEnu�[���Copyright (c) 2019-2022 Fabien Potencier

Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is furnished
to do so, subject to the following conditions:

The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.

THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
THE SOFTWARE.
PKϤ$Zn^t{{string/CodePointString.phpnu�[���<?php

/*
 * This file is part of the Symfony package.
 *
 * (c) Fabien Potencier <fabien@symfony.com>
 *
 * For the full copyright and license information, please view the LICENSE
 * file that was distributed with this source code.
 */

namespace Symfony\Component\String;

use Symfony\Component\String\Exception\ExceptionInterface;
use Symfony\Component\String\Exception\InvalidArgumentException;

/**
 * Represents a string of Unicode code points encoded as UTF-8.
 *
 * @author Nicolas Grekas <p@tchwork.com>
 * @author Hugo Hamon <hugohamon@neuf.fr>
 *
 * @throws ExceptionInterface
 */
class CodePointString extends AbstractUnicodeString
{
    public function __construct(string $string = '')
    {
        if ('' !== $string && !preg_match('//u', $string)) {
            throw new InvalidArgumentException('Invalid UTF-8 string.');
        }

        $this->string = $string;
    }

    public function append(string ...$suffix): AbstractString
    {
        $str = clone $this;
        $str->string .= 1 >= \count($suffix) ? ($suffix[0] ?? '') : implode('', $suffix);

        if (!preg_match('//u', $str->string)) {
            throw new InvalidArgumentException('Invalid UTF-8 string.');
        }

        return $str;
    }

    public function chunk(int $length = 1): array
    {
        if (1 > $length) {
            throw new InvalidArgumentException('The chunk length must be greater than zero.');
        }

        if ('' === $this->string) {
            return [];
        }

        $rx = '/(';
        while (65535 < $length) {
            $rx .= '.{65535}';
            $length -= 65535;
        }
        $rx .= '.{'.$length.'})/us';

        $str = clone $this;
        $chunks = [];

        foreach (preg_split($rx, $this->string, -1, \PREG_SPLIT_DELIM_CAPTURE | \PREG_SPLIT_NO_EMPTY) as $chunk) {
            $str->string = $chunk;
            $chunks[] = clone $str;
        }

        return $chunks;
    }

    public function codePointsAt(int $offset): array
    {
        $str = $offset ? $this->slice($offset, 1) : $this;

        return '' === $str->string ? [] : [mb_ord($str->string, 'UTF-8')];
    }

    public function endsWith($suffix): bool
    {
        if ($suffix instanceof AbstractString) {
            $suffix = $suffix->string;
        } elseif (\is_array($suffix) || $suffix instanceof \Traversable) {
            return parent::endsWith($suffix);
        } else {
            $suffix = (string) $suffix;
        }

        if ('' === $suffix || !preg_match('//u', $suffix)) {
            return false;
        }

        if ($this->ignoreCase) {
            return preg_match('{'.preg_quote($suffix).'$}iuD', $this->string);
        }

        return \strlen($this->string) >= \strlen($suffix) && 0 === substr_compare($this->string, $suffix, -\strlen($suffix));
    }

    public function equalsTo($string): bool
    {
        if ($string instanceof AbstractString) {
            $string = $string->string;
        } elseif (\is_array($string) || $string instanceof \Traversable) {
            return parent::equalsTo($string);
        } else {
            $string = (string) $string;
        }

        if ('' !== $string && $this->ignoreCase) {
            return \strlen($string) === \strlen($this->string) && 0 === mb_stripos($this->string, $string, 0, 'UTF-8');
        }

        return $string === $this->string;
    }

    public function indexOf($needle, int $offset = 0): ?int
    {
        if ($needle instanceof AbstractString) {
            $needle = $needle->string;
        } elseif (\is_array($needle) || $needle instanceof \Traversable) {
            return parent::indexOf($needle, $offset);
        } else {
            $needle = (string) $needle;
        }

        if ('' === $needle) {
            return null;
        }

        $i = $this->ignoreCase ? mb_stripos($this->string, $needle, $offset, 'UTF-8') : mb_strpos($this->string, $needle, $offset, 'UTF-8');

        return false === $i ? null : $i;
    }

    public function indexOfLast($needle, int $offset = 0): ?int
    {
        if ($needle instanceof AbstractString) {
            $needle = $needle->string;
        } elseif (\is_array($needle) || $needle instanceof \Traversable) {
            return parent::indexOfLast($needle, $offset);
        } else {
            $needle = (string) $needle;
        }

        if ('' === $needle) {
            return null;
        }

        $i = $this->ignoreCase ? mb_strripos($this->string, $needle, $offset, 'UTF-8') : mb_strrpos($this->string, $needle, $offset, 'UTF-8');

        return false === $i ? null : $i;
    }

    public function length(): int
    {
        return mb_strlen($this->string, 'UTF-8');
    }

    public function prepend(string ...$prefix): AbstractString
    {
        $str = clone $this;
        $str->string = (1 >= \count($prefix) ? ($prefix[0] ?? '') : implode('', $prefix)).$this->string;

        if (!preg_match('//u', $str->string)) {
            throw new InvalidArgumentException('Invalid UTF-8 string.');
        }

        return $str;
    }

    public function replace(string $from, string $to): AbstractString
    {
        $str = clone $this;

        if ('' === $from || !preg_match('//u', $from)) {
            return $str;
        }

        if ('' !== $to && !preg_match('//u', $to)) {
            throw new InvalidArgumentException('Invalid UTF-8 string.');
        }

        if ($this->ignoreCase) {
            $str->string = implode($to, preg_split('{'.preg_quote($from).'}iuD', $this->string));
        } else {
            $str->string = str_replace($from, $to, $this->string);
        }

        return $str;
    }

    public function slice(int $start = 0, int $length = null): AbstractString
    {
        $str = clone $this;
        $str->string = mb_substr($this->string, $start, $length, 'UTF-8');

        return $str;
    }

    public function splice(string $replacement, int $start = 0, int $length = null): AbstractString
    {
        if (!preg_match('//u', $replacement)) {
            throw new InvalidArgumentException('Invalid UTF-8 string.');
        }

        $str = clone $this;
        $start = $start ? \strlen(mb_substr($this->string, 0, $start, 'UTF-8')) : 0;
        $length = $length ? \strlen(mb_substr($this->string, $start, $length, 'UTF-8')) : $length;
        $str->string = substr_replace($this->string, $replacement, $start, $length ?? \PHP_INT_MAX);

        return $str;
    }

    public function split(string $delimiter, int $limit = null, int $flags = null): array
    {
        if (1 > $limit = $limit ?? \PHP_INT_MAX) {
            throw new InvalidArgumentException('Split limit must be a positive integer.');
        }

        if ('' === $delimiter) {
            throw new InvalidArgumentException('Split delimiter is empty.');
        }

        if (null !== $flags) {
            return parent::split($delimiter.'u', $limit, $flags);
        }

        if (!preg_match('//u', $delimiter)) {
            throw new InvalidArgumentException('Split delimiter is not a valid UTF-8 string.');
        }

        $str = clone $this;
        $chunks = $this->ignoreCase
            ? preg_split('{'.preg_quote($delimiter).'}iuD', $this->string, $limit)
            : explode($delimiter, $this->string, $limit);

        foreach ($chunks as &$chunk) {
            $str->string = $chunk;
            $chunk = clone $str;
        }

        return $chunks;
    }

    public function startsWith($prefix): bool
    {
        if ($prefix instanceof AbstractString) {
            $prefix = $prefix->string;
        } elseif (\is_array($prefix) || $prefix instanceof \Traversable) {
            return parent::startsWith($prefix);
        } else {
            $prefix = (string) $prefix;
        }

        if ('' === $prefix || !preg_match('//u', $prefix)) {
            return false;
        }

        if ($this->ignoreCase) {
            return 0 === mb_stripos($this->string, $prefix, 0, 'UTF-8');
        }

        return 0 === strncmp($this->string, $prefix, \strlen($prefix));
    }
}
PKϤ$ZUp�zzyaml/Inline.phpnu�[���<?php

/*
 * This file is part of the Symfony package.
 *
 * (c) Fabien Potencier <fabien@symfony.com>
 *
 * For the full copyright and license information, please view the LICENSE
 * file that was distributed with this source code.
 */

namespace Symfony\Component\Yaml;

use Symfony\Component\Yaml\Exception\DumpException;
use Symfony\Component\Yaml\Exception\ParseException;
use Symfony\Component\Yaml\Tag\TaggedValue;

/**
 * Inline implements a YAML parser/dumper for the YAML inline syntax.
 *
 * @author Fabien Potencier <fabien@symfony.com>
 *
 * @internal
 */
class Inline
{
    const REGEX_QUOTED_STRING = '(?:"([^"\\\\]*+(?:\\\\.[^"\\\\]*+)*+)"|\'([^\']*+(?:\'\'[^\']*+)*+)\')';

    public static $parsedLineNumber = -1;
    public static $parsedFilename;

    private static $exceptionOnInvalidType = false;
    private static $objectSupport = false;
    private static $objectForMap = false;
    private static $constantSupport = false;

    public static function initialize(int $flags, int $parsedLineNumber = null, string $parsedFilename = null)
    {
        self::$exceptionOnInvalidType = (bool) (Yaml::PARSE_EXCEPTION_ON_INVALID_TYPE & $flags);
        self::$objectSupport = (bool) (Yaml::PARSE_OBJECT & $flags);
        self::$objectForMap = (bool) (Yaml::PARSE_OBJECT_FOR_MAP & $flags);
        self::$constantSupport = (bool) (Yaml::PARSE_CONSTANT & $flags);
        self::$parsedFilename = $parsedFilename;

        if (null !== $parsedLineNumber) {
            self::$parsedLineNumber = $parsedLineNumber;
        }
    }

    /**
     * Converts a YAML string to a PHP value.
     *
     * @param string $value      A YAML string
     * @param int    $flags      A bit field of PARSE_* constants to customize the YAML parser behavior
     * @param array  $references Mapping of variable names to values
     *
     * @return mixed A PHP value
     *
     * @throws ParseException
     */
    public static function parse(string $value = null, int $flags = 0, array $references = [])
    {
        self::initialize($flags);

        $value = trim($value);

        if ('' === $value) {
            return '';
        }

        if (2 /* MB_OVERLOAD_STRING */ & (int) ini_get('mbstring.func_overload')) {
            $mbEncoding = mb_internal_encoding();
            mb_internal_encoding('ASCII');
        }

        try {
            $i = 0;
            $tag = self::parseTag($value, $i, $flags);
            switch ($value[$i]) {
                case '[':
                    $result = self::parseSequence($value, $flags, $i, $references);
                    ++$i;
                    break;
                case '{':
                    $result = self::parseMapping($value, $flags, $i, $references);
                    ++$i;
                    break;
                default:
                    $result = self::parseScalar($value, $flags, null, $i, null === $tag, $references);
            }

            // some comments are allowed at the end
            if (preg_replace('/\s+#.*$/A', '', substr($value, $i))) {
                throw new ParseException(sprintf('Unexpected characters near "%s".', substr($value, $i)), self::$parsedLineNumber + 1, $value, self::$parsedFilename);
            }

            if (null !== $tag && '' !== $tag) {
                return new TaggedValue($tag, $result);
            }

            return $result;
        } finally {
            if (isset($mbEncoding)) {
                mb_internal_encoding($mbEncoding);
            }
        }
    }

    /**
     * Dumps a given PHP variable to a YAML string.
     *
     * @param mixed $value The PHP variable to convert
     * @param int   $flags A bit field of Yaml::DUMP_* constants to customize the dumped YAML string
     *
     * @return string The YAML string representing the PHP value
     *
     * @throws DumpException When trying to dump PHP resource
     */
    public static function dump($value, int $flags = 0): string
    {
        switch (true) {
            case \is_resource($value):
                if (Yaml::DUMP_EXCEPTION_ON_INVALID_TYPE & $flags) {
                    throw new DumpException(sprintf('Unable to dump PHP resources in a YAML file ("%s").', get_resource_type($value)));
                }

                return self::dumpNull($flags);
            case $value instanceof \DateTimeInterface:
                return $value->format('c');
            case \is_object($value):
                if ($value instanceof TaggedValue) {
                    return '!'.$value->getTag().' '.self::dump($value->getValue(), $flags);
                }

                if (Yaml::DUMP_OBJECT & $flags) {
                    return '!php/object '.self::dump(serialize($value));
                }

                if (Yaml::DUMP_OBJECT_AS_MAP & $flags && ($value instanceof \stdClass || $value instanceof \ArrayObject)) {
                    $output = [];

                    foreach ($value as $key => $val) {
                        $output[] = sprintf('%s: %s', self::dump($key, $flags), self::dump($val, $flags));
                    }

                    return sprintf('{ %s }', implode(', ', $output));
                }

                if (Yaml::DUMP_EXCEPTION_ON_INVALID_TYPE & $flags) {
                    throw new DumpException('Object support when dumping a YAML file has been disabled.');
                }

                return self::dumpNull($flags);
            case \is_array($value):
                return self::dumpArray($value, $flags);
            case null === $value:
                return self::dumpNull($flags);
            case true === $value:
                return 'true';
            case false === $value:
                return 'false';
            case ctype_digit($value):
                return \is_string($value) ? "'$value'" : (int) $value;
            case is_numeric($value):
                $locale = setlocale(LC_NUMERIC, 0);
                if (false !== $locale) {
                    setlocale(LC_NUMERIC, 'C');
                }
                if (\is_float($value)) {
                    $repr = (string) $value;
                    if (is_infinite($value)) {
                        $repr = str_ireplace('INF', '.Inf', $repr);
                    } elseif (floor($value) == $value && $repr == $value) {
                        // Preserve float data type since storing a whole number will result in integer value.
                        $repr = '!!float '.$repr;
                    }
                } else {
                    $repr = \is_string($value) ? "'$value'" : (string) $value;
                }
                if (false !== $locale) {
                    setlocale(LC_NUMERIC, $locale);
                }

                return $repr;
            case '' == $value:
                return "''";
            case self::isBinaryString($value):
                return '!!binary '.base64_encode($value);
            case Escaper::requiresDoubleQuoting($value):
                return Escaper::escapeWithDoubleQuotes($value);
            case Escaper::requiresSingleQuoting($value):
            case Parser::preg_match('{^[0-9]+[_0-9]*$}', $value):
            case Parser::preg_match(self::getHexRegex(), $value):
            case Parser::preg_match(self::getTimestampRegex(), $value):
                return Escaper::escapeWithSingleQuotes($value);
            default:
                return $value;
        }
    }

    /**
     * Check if given array is hash or just normal indexed array.
     *
     * @param array|\ArrayObject|\stdClass $value The PHP array or array-like object to check
     *
     * @return bool true if value is hash array, false otherwise
     */
    public static function isHash($value): bool
    {
        if ($value instanceof \stdClass || $value instanceof \ArrayObject) {
            return true;
        }

        $expectedKey = 0;

        foreach ($value as $key => $val) {
            if ($key !== $expectedKey++) {
                return true;
            }
        }

        return false;
    }

    /**
     * Dumps a PHP array to a YAML string.
     *
     * @param array $value The PHP array to dump
     * @param int   $flags A bit field of Yaml::DUMP_* constants to customize the dumped YAML string
     *
     * @return string The YAML string representing the PHP array
     */
    private static function dumpArray(array $value, int $flags): string
    {
        // array
        if (($value || Yaml::DUMP_EMPTY_ARRAY_AS_SEQUENCE & $flags) && !self::isHash($value)) {
            $output = [];
            foreach ($value as $val) {
                $output[] = self::dump($val, $flags);
            }

            return sprintf('[%s]', implode(', ', $output));
        }

        // hash
        $output = [];
        foreach ($value as $key => $val) {
            $output[] = sprintf('%s: %s', self::dump($key, $flags), self::dump($val, $flags));
        }

        return sprintf('{ %s }', implode(', ', $output));
    }

    private static function dumpNull(int $flags): string
    {
        if (Yaml::DUMP_NULL_AS_TILDE & $flags) {
            return '~';
        }

        return 'null';
    }

    /**
     * Parses a YAML scalar.
     *
     * @return mixed
     *
     * @throws ParseException When malformed inline YAML string is parsed
     */
    public static function parseScalar(string $scalar, int $flags = 0, array $delimiters = null, int &$i = 0, bool $evaluate = true, array $references = [])
    {
        if (\in_array($scalar[$i], ['"', "'"])) {
            // quoted scalar
            $output = self::parseQuotedScalar($scalar, $i);

            if (null !== $delimiters) {
                $tmp = ltrim(substr($scalar, $i), " \n");
                if ('' === $tmp) {
                    throw new ParseException(sprintf('Unexpected end of line, expected one of "%s".', implode('', $delimiters)), self::$parsedLineNumber + 1, $scalar, self::$parsedFilename);
                }
                if (!\in_array($tmp[0], $delimiters)) {
                    throw new ParseException(sprintf('Unexpected characters (%s).', substr($scalar, $i)), self::$parsedLineNumber + 1, $scalar, self::$parsedFilename);
                }
            }
        } else {
            // "normal" string
            if (!$delimiters) {
                $output = substr($scalar, $i);
                $i += \strlen($output);

                // remove comments
                if (Parser::preg_match('/[ \t]+#/', $output, $match, PREG_OFFSET_CAPTURE)) {
                    $output = substr($output, 0, $match[0][1]);
                }
            } elseif (Parser::preg_match('/^(.*?)('.implode('|', $delimiters).')/', substr($scalar, $i), $match)) {
                $output = $match[1];
                $i += \strlen($output);
                $output = trim($output);
            } else {
                throw new ParseException(sprintf('Malformed inline YAML string: "%s".', $scalar), self::$parsedLineNumber + 1, null, self::$parsedFilename);
            }

            // a non-quoted string cannot start with @ or ` (reserved) nor with a scalar indicator (| or >)
            if ($output && ('@' === $output[0] || '`' === $output[0] || '|' === $output[0] || '>' === $output[0] || '%' === $output[0])) {
                throw new ParseException(sprintf('The reserved indicator "%s" cannot start a plain scalar; you need to quote the scalar.', $output[0]), self::$parsedLineNumber + 1, $output, self::$parsedFilename);
            }

            if ($evaluate) {
                $output = self::evaluateScalar($output, $flags, $references);
            }
        }

        return $output;
    }

    /**
     * Parses a YAML quoted scalar.
     *
     * @throws ParseException When malformed inline YAML string is parsed
     */
    private static function parseQuotedScalar(string $scalar, int &$i): string
    {
        if (!Parser::preg_match('/'.self::REGEX_QUOTED_STRING.'/Au', substr($scalar, $i), $match)) {
            throw new ParseException(sprintf('Malformed inline YAML string: "%s".', substr($scalar, $i)), self::$parsedLineNumber + 1, $scalar, self::$parsedFilename);
        }

        $output = substr($match[0], 1, \strlen($match[0]) - 2);

        $unescaper = new Unescaper();
        if ('"' == $scalar[$i]) {
            $output = $unescaper->unescapeDoubleQuotedString($output);
        } else {
            $output = $unescaper->unescapeSingleQuotedString($output);
        }

        $i += \strlen($match[0]);

        return $output;
    }

    /**
     * Parses a YAML sequence.
     *
     * @throws ParseException When malformed inline YAML string is parsed
     */
    private static function parseSequence(string $sequence, int $flags, int &$i = 0, array $references = []): array
    {
        $output = [];
        $len = \strlen($sequence);
        ++$i;

        // [foo, bar, ...]
        while ($i < $len) {
            if (']' === $sequence[$i]) {
                return $output;
            }
            if (',' === $sequence[$i] || ' ' === $sequence[$i]) {
                ++$i;

                continue;
            }

            $tag = self::parseTag($sequence, $i, $flags);
            switch ($sequence[$i]) {
                case '[':
                    // nested sequence
                    $value = self::parseSequence($sequence, $flags, $i, $references);
                    break;
                case '{':
                    // nested mapping
                    $value = self::parseMapping($sequence, $flags, $i, $references);
                    break;
                default:
                    $isQuoted = \in_array($sequence[$i], ['"', "'"]);
                    $value = self::parseScalar($sequence, $flags, [',', ']'], $i, null === $tag, $references);

                    // the value can be an array if a reference has been resolved to an array var
                    if (\is_string($value) && !$isQuoted && false !== strpos($value, ': ')) {
                        // embedded mapping?
                        try {
                            $pos = 0;
                            $value = self::parseMapping('{'.$value.'}', $flags, $pos, $references);
                        } catch (\InvalidArgumentException $e) {
                            // no, it's not
                        }
                    }

                    --$i;
            }

            if (null !== $tag && '' !== $tag) {
                $value = new TaggedValue($tag, $value);
            }

            $output[] = $value;

            ++$i;
        }

        throw new ParseException(sprintf('Malformed inline YAML string: "%s".', $sequence), self::$parsedLineNumber + 1, null, self::$parsedFilename);
    }

    /**
     * Parses a YAML mapping.
     *
     * @return array|\stdClass
     *
     * @throws ParseException When malformed inline YAML string is parsed
     */
    private static function parseMapping(string $mapping, int $flags, int &$i = 0, array $references = [])
    {
        $output = [];
        $len = \strlen($mapping);
        ++$i;
        $allowOverwrite = false;

        // {foo: bar, bar:foo, ...}
        while ($i < $len) {
            switch ($mapping[$i]) {
                case ' ':
                case ',':
                case "\n":
                    ++$i;
                    continue 2;
                case '}':
                    if (self::$objectForMap) {
                        return (object) $output;
                    }

                    return $output;
            }

            // key
            $offsetBeforeKeyParsing = $i;
            $isKeyQuoted = \in_array($mapping[$i], ['"', "'"], true);
            $key = self::parseScalar($mapping, $flags, [':', ' '], $i, false, []);

            if ($offsetBeforeKeyParsing === $i) {
                throw new ParseException('Missing mapping key.', self::$parsedLineNumber + 1, $mapping);
            }

            if ('!php/const' === $key) {
                $key .= ' '.self::parseScalar($mapping, $flags, [':'], $i, false, []);
                $key = self::evaluateScalar($key, $flags);
            }

            if (false === $i = strpos($mapping, ':', $i)) {
                break;
            }

            if (!$isKeyQuoted) {
                $evaluatedKey = self::evaluateScalar($key, $flags, $references);

                if ('' !== $key && $evaluatedKey !== $key && !\is_string($evaluatedKey) && !\is_int($evaluatedKey)) {
                    throw new ParseException('Implicit casting of incompatible mapping keys to strings is not supported. Quote your evaluable mapping keys instead.', self::$parsedLineNumber + 1, $mapping);
                }
            }

            if (!$isKeyQuoted && (!isset($mapping[$i + 1]) || !\in_array($mapping[$i + 1], [' ', ',', '[', ']', '{', '}', "\n"], true))) {
                throw new ParseException('Colons must be followed by a space or an indication character (i.e. " ", ",", "[", "]", "{", "}").', self::$parsedLineNumber + 1, $mapping);
            }

            if ('<<' === $key) {
                $allowOverwrite = true;
            }

            while ($i < $len) {
                if (':' === $mapping[$i] || ' ' === $mapping[$i] || "\n" === $mapping[$i]) {
                    ++$i;

                    continue;
                }

                $tag = self::parseTag($mapping, $i, $flags);
                switch ($mapping[$i]) {
                    case '[':
                        // nested sequence
                        $value = self::parseSequence($mapping, $flags, $i, $references);
                        // Spec: Keys MUST be unique; first one wins.
                        // Parser cannot abort this mapping earlier, since lines
                        // are processed sequentially.
                        // But overwriting is allowed when a merge node is used in current block.
                        if ('<<' === $key) {
                            foreach ($value as $parsedValue) {
                                $output += $parsedValue;
                            }
                        } elseif ($allowOverwrite || !isset($output[$key])) {
                            if (null !== $tag) {
                                $output[$key] = new TaggedValue($tag, $value);
                            } else {
                                $output[$key] = $value;
                            }
                        } elseif (isset($output[$key])) {
                            throw new ParseException(sprintf('Duplicate key "%s" detected.', $key), self::$parsedLineNumber + 1, $mapping);
                        }
                        break;
                    case '{':
                        // nested mapping
                        $value = self::parseMapping($mapping, $flags, $i, $references);
                        // Spec: Keys MUST be unique; first one wins.
                        // Parser cannot abort this mapping earlier, since lines
                        // are processed sequentially.
                        // But overwriting is allowed when a merge node is used in current block.
                        if ('<<' === $key) {
                            $output += $value;
                        } elseif ($allowOverwrite || !isset($output[$key])) {
                            if (null !== $tag) {
                                $output[$key] = new TaggedValue($tag, $value);
                            } else {
                                $output[$key] = $value;
                            }
                        } elseif (isset($output[$key])) {
                            throw new ParseException(sprintf('Duplicate key "%s" detected.', $key), self::$parsedLineNumber + 1, $mapping);
                        }
                        break;
                    default:
                        $value = self::parseScalar($mapping, $flags, [',', '}', "\n"], $i, null === $tag, $references);
                        // Spec: Keys MUST be unique; first one wins.
                        // Parser cannot abort this mapping earlier, since lines
                        // are processed sequentially.
                        // But overwriting is allowed when a merge node is used in current block.
                        if ('<<' === $key) {
                            $output += $value;
                        } elseif ($allowOverwrite || !isset($output[$key])) {
                            if (null !== $tag) {
                                $output[$key] = new TaggedValue($tag, $value);
                            } else {
                                $output[$key] = $value;
                            }
                        } elseif (isset($output[$key])) {
                            throw new ParseException(sprintf('Duplicate key "%s" detected.', $key), self::$parsedLineNumber + 1, $mapping);
                        }
                        --$i;
                }
                ++$i;

                continue 2;
            }
        }

        throw new ParseException(sprintf('Malformed inline YAML string: "%s".', $mapping), self::$parsedLineNumber + 1, null, self::$parsedFilename);
    }

    /**
     * Evaluates scalars and replaces magic values.
     *
     * @return mixed The evaluated YAML string
     *
     * @throws ParseException when object parsing support was disabled and the parser detected a PHP object or when a reference could not be resolved
     */
    private static function evaluateScalar(string $scalar, int $flags, array $references = [])
    {
        $scalar = trim($scalar);
        $scalarLower = strtolower($scalar);

        if (0 === strpos($scalar, '*')) {
            if (false !== $pos = strpos($scalar, '#')) {
                $value = substr($scalar, 1, $pos - 2);
            } else {
                $value = substr($scalar, 1);
            }

            // an unquoted *
            if (false === $value || '' === $value) {
                throw new ParseException('A reference must contain at least one character.', self::$parsedLineNumber + 1, $value, self::$parsedFilename);
            }

            if (!\array_key_exists($value, $references)) {
                throw new ParseException(sprintf('Reference "%s" does not exist.', $value), self::$parsedLineNumber + 1, $value, self::$parsedFilename);
            }

            return $references[$value];
        }

        switch (true) {
            case 'null' === $scalarLower:
            case '' === $scalar:
            case '~' === $scalar:
                return null;
            case 'true' === $scalarLower:
                return true;
            case 'false' === $scalarLower:
                return false;
            case '!' === $scalar[0]:
                switch (true) {
                    case 0 === strpos($scalar, '!!str '):
                        return (string) substr($scalar, 6);
                    case 0 === strpos($scalar, '! '):
                        return substr($scalar, 2);
                    case 0 === strpos($scalar, '!php/object'):
                        if (self::$objectSupport) {
                            if (!isset($scalar[12])) {
                                return false;
                            }

                            return unserialize(self::parseScalar(substr($scalar, 12)));
                        }

                        if (self::$exceptionOnInvalidType) {
                            throw new ParseException('Object support when parsing a YAML file has been disabled.', self::$parsedLineNumber + 1, $scalar, self::$parsedFilename);
                        }

                        return null;
                    case 0 === strpos($scalar, '!php/const'):
                        if (self::$constantSupport) {
                            if (!isset($scalar[11])) {
                                return '';
                            }

                            $i = 0;
                            if (\defined($const = self::parseScalar(substr($scalar, 11), 0, null, $i, false))) {
                                return \constant($const);
                            }

                            throw new ParseException(sprintf('The constant "%s" is not defined.', $const), self::$parsedLineNumber + 1, $scalar, self::$parsedFilename);
                        }
                        if (self::$exceptionOnInvalidType) {
                            throw new ParseException(sprintf('The string "%s" could not be parsed as a constant. Did you forget to pass the "Yaml::PARSE_CONSTANT" flag to the parser?', $scalar), self::$parsedLineNumber + 1, $scalar, self::$parsedFilename);
                        }

                        return null;
                    case 0 === strpos($scalar, '!!float '):
                        return (float) substr($scalar, 8);
                    case 0 === strpos($scalar, '!!binary '):
                        return self::evaluateBinaryScalar(substr($scalar, 9));
                    default:
                        throw new ParseException(sprintf('The string "%s" could not be parsed as it uses an unsupported built-in tag.', $scalar), self::$parsedLineNumber, $scalar, self::$parsedFilename);
                }

            // Optimize for returning strings.
            // no break
            case '+' === $scalar[0] || '-' === $scalar[0] || '.' === $scalar[0] || is_numeric($scalar[0]):
                if (Parser::preg_match('{^[+-]?[0-9][0-9_]*$}', $scalar)) {
                    $scalar = str_replace('_', '', (string) $scalar);
                }

                switch (true) {
                    case ctype_digit($scalar):
                        $raw = $scalar;
                        $cast = (int) $scalar;

                        return '0' == $scalar[0] ? octdec($scalar) : (((string) $raw == (string) $cast) ? $cast : $raw);
                    case '-' === $scalar[0] && ctype_digit(substr($scalar, 1)):
                        $raw = $scalar;
                        $cast = (int) $scalar;

                        return '0' == $scalar[1] ? -octdec(substr($scalar, 1)) : (($raw === (string) $cast) ? $cast : $raw);
                    case is_numeric($scalar):
                    case Parser::preg_match(self::getHexRegex(), $scalar):
                        $scalar = str_replace('_', '', $scalar);

                        return '0x' === $scalar[0].$scalar[1] ? hexdec($scalar) : (float) $scalar;
                    case '.inf' === $scalarLower:
                    case '.nan' === $scalarLower:
                        return -log(0);
                    case '-.inf' === $scalarLower:
                        return log(0);
                    case Parser::preg_match('/^(-|\+)?[0-9][0-9_]*(\.[0-9_]+)?$/', $scalar):
                        return (float) str_replace('_', '', $scalar);
                    case Parser::preg_match(self::getTimestampRegex(), $scalar):
                        if (Yaml::PARSE_DATETIME & $flags) {
                            // When no timezone is provided in the parsed date, YAML spec says we must assume UTC.
                            return new \DateTime($scalar, new \DateTimeZone('UTC'));
                        }

                        $timeZone = date_default_timezone_get();
                        date_default_timezone_set('UTC');
                        $time = strtotime($scalar);
                        date_default_timezone_set($timeZone);

                        return $time;
                }
        }

        return (string) $scalar;
    }

    private static function parseTag(string $value, int &$i, int $flags): ?string
    {
        if ('!' !== $value[$i]) {
            return null;
        }

        $tagLength = strcspn($value, " \t\n[]{},", $i + 1);
        $tag = substr($value, $i + 1, $tagLength);

        $nextOffset = $i + $tagLength + 1;
        $nextOffset += strspn($value, ' ', $nextOffset);

        if ('' === $tag && (!isset($value[$nextOffset]) || \in_array($value[$nextOffset], [']', '}', ','], true))) {
            throw new ParseException(sprintf('Using the unquoted scalar value "!" is not supported. You must quote it.', $value), self::$parsedLineNumber + 1, $value, self::$parsedFilename);
        }

        // Is followed by a scalar and is a built-in tag
        if ('' !== $tag && (!isset($value[$nextOffset]) || !\in_array($value[$nextOffset], ['[', '{'], true)) && ('!' === $tag[0] || 'str' === $tag || 'php/const' === $tag || 'php/object' === $tag)) {
            // Manage in {@link self::evaluateScalar()}
            return null;
        }

        $i = $nextOffset;

        // Built-in tags
        if ('' !== $tag && '!' === $tag[0]) {
            throw new ParseException(sprintf('The built-in tag "!%s" is not implemented.', $tag), self::$parsedLineNumber + 1, $value, self::$parsedFilename);
        }

        if ('' !== $tag && !isset($value[$i])) {
            throw new ParseException(sprintf('Missing value for tag "%s".', $tag), self::$parsedLineNumber + 1, $value, self::$parsedFilename);
        }

        if ('' === $tag || Yaml::PARSE_CUSTOM_TAGS & $flags) {
            return $tag;
        }

        throw new ParseException(sprintf('Tags support is not enabled. Enable the "Yaml::PARSE_CUSTOM_TAGS" flag to use "!%s".', $tag), self::$parsedLineNumber + 1, $value, self::$parsedFilename);
    }

    public static function evaluateBinaryScalar(string $scalar): string
    {
        $parsedBinaryData = self::parseScalar(preg_replace('/\s/', '', $scalar));

        if (0 !== (\strlen($parsedBinaryData) % 4)) {
            throw new ParseException(sprintf('The normalized base64 encoded data (data without whitespace characters) length must be a multiple of four (%d bytes given).', \strlen($parsedBinaryData)), self::$parsedLineNumber + 1, $scalar, self::$parsedFilename);
        }

        if (!Parser::preg_match('#^[A-Z0-9+/]+={0,2}$#i', $parsedBinaryData)) {
            throw new ParseException(sprintf('The base64 encoded data (%s) contains invalid characters.', $parsedBinaryData), self::$parsedLineNumber + 1, $scalar, self::$parsedFilename);
        }

        return base64_decode($parsedBinaryData, true);
    }

    private static function isBinaryString(string $value): bool
    {
        return !preg_match('//u', $value) || preg_match('/[^\x00\x07-\x0d\x1B\x20-\xff]/', $value);
    }

    /**
     * Gets a regex that matches a YAML date.
     *
     * @return string The regular expression
     *
     * @see http://www.yaml.org/spec/1.2/spec.html#id2761573
     */
    private static function getTimestampRegex(): string
    {
        return <<<EOF
        ~^
        (?P<year>[0-9][0-9][0-9][0-9])
        -(?P<month>[0-9][0-9]?)
        -(?P<day>[0-9][0-9]?)
        (?:(?:[Tt]|[ \t]+)
        (?P<hour>[0-9][0-9]?)
        :(?P<minute>[0-9][0-9])
        :(?P<second>[0-9][0-9])
        (?:\.(?P<fraction>[0-9]*))?
        (?:[ \t]*(?P<tz>Z|(?P<tz_sign>[-+])(?P<tz_hour>[0-9][0-9]?)
        (?::(?P<tz_minute>[0-9][0-9]))?))?)?
        $~x
EOF;
    }

    /**
     * Gets a regex that matches a YAML number in hexadecimal notation.
     */
    private static function getHexRegex(): string
    {
        return '~^0x[0-9a-f_]++$~i';
    }
}
PKϤ$Z��6MM!yaml/Tests/ParseExceptionTest.phpnu�[���<?php

/*
 * This file is part of the Symfony package.
 *
 * (c) Fabien Potencier <fabien@symfony.com>
 *
 * For the full copyright and license information, please view the LICENSE
 * file that was distributed with this source code.
 */

namespace Symfony\Component\Yaml\Tests;

use Symfony\Component\Yaml\Exception\ParseException;

class ParseExceptionTest extends \PHPUnit_Framework_TestCase
{
    public function testGetMessage()
    {
        $exception = new ParseException('Error message', 42, 'foo: bar', '/var/www/app/config.yml');
        if (PHP_VERSION_ID >= 50400) {
            $message = 'Error message in "/var/www/app/config.yml" at line 42 (near "foo: bar")';
        } else {
            $message = 'Error message in "\\/var\\/www\\/app\\/config.yml" at line 42 (near "foo: bar")';
        }

        $this->assertEquals($message, $exception->getMessage());
    }

    public function testGetMessageWithUnicodeInFilename()
    {
        $exception = new ParseException('Error message', 42, 'foo: bar', 'äöü.yml');
        if (PHP_VERSION_ID >= 50400) {
            $message = 'Error message in "äöü.yml" at line 42 (near "foo: bar")';
        } else {
            $message = 'Error message in "\u00e4\u00f6\u00fc.yml" at line 42 (near "foo: bar")';
        }

        $this->assertEquals($message, $exception->getMessage());
    }
}
PKϤ$Z�ĥ�CLCLyaml/Tests/InlineTest.phpnu�[���<?php

/*
 * This file is part of the Symfony package.
 *
 * (c) Fabien Potencier <fabien@symfony.com>
 *
 * For the full copyright and license information, please view the LICENSE
 * file that was distributed with this source code.
 */

namespace Symfony\Component\Yaml\Tests;

use Symfony\Component\Yaml\Inline;

class InlineTest extends \PHPUnit_Framework_TestCase
{
    /**
     * @dataProvider getTestsForParse
     */
    public function testParse($yaml, $value)
    {
        $this->assertSame($value, Inline::parse($yaml), sprintf('::parse() converts an inline YAML to a PHP structure (%s)', $yaml));
    }

    /**
     * @dataProvider getTestsForParseWithMapObjects
     */
    public function testParseWithMapObjects($yaml, $value)
    {
        $actual = Inline::parse($yaml, false, false, true);

        $this->assertSame(serialize($value), serialize($actual));
    }

    /**
     * @dataProvider getTestsForDump
     */
    public function testDump($yaml, $value)
    {
        $this->assertEquals($yaml, Inline::dump($value), sprintf('::dump() converts a PHP structure to an inline YAML (%s)', $yaml));

        $this->assertSame($value, Inline::parse(Inline::dump($value)), 'check consistency');
    }

    public function testDumpNumericValueWithLocale()
    {
        $locale = setlocale(LC_NUMERIC, 0);
        if (false === $locale) {
            $this->markTestSkipped('Your platform does not support locales.');
        }

        try {
            $requiredLocales = array('fr_FR.UTF-8', 'fr_FR.UTF8', 'fr_FR.utf-8', 'fr_FR.utf8', 'French_France.1252');
            if (false === setlocale(LC_NUMERIC, $requiredLocales)) {
                $this->markTestSkipped('Could not set any of required locales: '.implode(', ', $requiredLocales));
            }

            $this->assertEquals('1.2', Inline::dump(1.2));
            $this->assertContains('fr', strtolower(setlocale(LC_NUMERIC, 0)));
            setlocale(LC_NUMERIC, $locale);
        } catch (\Exception $e) {
            setlocale(LC_NUMERIC, $locale);
            throw $e;
        }
    }

    public function testHashStringsResemblingExponentialNumericsShouldNotBeChangedToINF()
    {
        $value = '686e444';

        $this->assertSame($value, Inline::parse(Inline::dump($value)));
    }

    /**
     * @group legacy
     * throws \Symfony\Component\Yaml\Exception\ParseException in 3.0
     */
    public function testParseScalarWithNonEscapedBlackslashShouldThrowException()
    {
        $this->assertSame('Foo\Var', Inline::parse('"Foo\Var"'));
    }

    /**
     * @expectedException \Symfony\Component\Yaml\Exception\ParseException
     */
    public function testParseScalarWithNonEscapedBlackslashAtTheEndShouldThrowException()
    {
        Inline::parse('"Foo\\"');
    }

    /**
     * @expectedException \Symfony\Component\Yaml\Exception\ParseException
     */
    public function testParseScalarWithIncorrectlyQuotedStringShouldThrowException()
    {
        $value = "'don't do somthin' like that'";
        Inline::parse($value);
    }

    /**
     * @expectedException \Symfony\Component\Yaml\Exception\ParseException
     */
    public function testParseScalarWithIncorrectlyDoubleQuotedStringShouldThrowException()
    {
        $value = '"don"t do somthin" like that"';
        Inline::parse($value);
    }

    /**
     * @expectedException \Symfony\Component\Yaml\Exception\ParseException
     */
    public function testParseInvalidMappingKeyShouldThrowException()
    {
        $value = '{ "foo " bar": "bar" }';
        Inline::parse($value);
    }

    /**
     * @expectedException \Symfony\Component\Yaml\Exception\ParseException
     */
    public function testParseInvalidMappingShouldThrowException()
    {
        Inline::parse('[foo] bar');
    }

    /**
     * @expectedException \Symfony\Component\Yaml\Exception\ParseException
     */
    public function testParseInvalidSequenceShouldThrowException()
    {
        Inline::parse('{ foo: bar } bar');
    }

    public function testParseScalarWithCorrectlyQuotedStringShouldReturnString()
    {
        $value = "'don''t do somthin'' like that'";
        $expect = "don't do somthin' like that";

        $this->assertSame($expect, Inline::parseScalar($value));
    }

    /**
     * @dataProvider getDataForParseReferences
     */
    public function testParseReferences($yaml, $expected)
    {
        $this->assertSame($expected, Inline::parse($yaml, false, false, false, array('var' => 'var-value')));
    }

    public function getDataForParseReferences()
    {
        return array(
            'scalar' => array('*var', 'var-value'),
            'list' => array('[ *var ]', array('var-value')),
            'list-in-list' => array('[[ *var ]]', array(array('var-value'))),
            'map-in-list' => array('[ { key: *var } ]', array(array('key' => 'var-value'))),
            'embedded-mapping-in-list' => array('[ key: *var ]', array(array('key' => 'var-value'))),
            'map' => array('{ key: *var }', array('key' => 'var-value')),
            'list-in-map' => array('{ key: [*var] }', array('key' => array('var-value'))),
            'map-in-map' => array('{ foo: { bar: *var } }', array('foo' => array('bar' => 'var-value'))),
        );
    }

    public function testParseMapReferenceInSequence()
    {
        $foo = array(
            'a' => 'Steve',
            'b' => 'Clark',
            'c' => 'Brian',
        );
        $this->assertSame(array($foo), Inline::parse('[*foo]', false, false, false, array('foo' => $foo)));
    }

    /**
     * @expectedException \Symfony\Component\Yaml\Exception\ParseException
     * @expectedExceptionMessage A reference must contain at least one character.
     */
    public function testParseUnquotedAsterisk()
    {
        Inline::parse('{ foo: * }');
    }

    /**
     * @expectedException \Symfony\Component\Yaml\Exception\ParseException
     * @expectedExceptionMessage A reference must contain at least one character.
     */
    public function testParseUnquotedAsteriskFollowedByAComment()
    {
        Inline::parse('{ foo: * #foo }');
    }

    /**
     * @group legacy
     * @dataProvider getReservedIndicators
     * throws \Symfony\Component\Yaml\Exception\ParseException in 3.0
     */
    public function testParseUnquotedScalarStartingWithReservedIndicator($indicator)
    {
        Inline::parse(sprintf('{ foo: %sfoo }', $indicator));
    }

    public function getReservedIndicators()
    {
        return array(array('@'), array('`'));
    }

    /**
     * @group legacy
     * @dataProvider getScalarIndicators
     * throws \Symfony\Component\Yaml\Exception\ParseException in 3.0
     */
    public function testParseUnquotedScalarStartingWithScalarIndicator($indicator)
    {
        Inline::parse(sprintf('{ foo: %sfoo }', $indicator));
    }

    public function getScalarIndicators()
    {
        return array(array('|'), array('>'));
    }

    /**
     * @dataProvider getDataForIsHash
     */
    public function testIsHash($array, $expected)
    {
        $this->assertSame($expected, Inline::isHash($array));
    }

    public function getDataForIsHash()
    {
        return array(
            array(array(), false),
            array(array(1, 2, 3), false),
            array(array(2 => 1, 1 => 2, 0 => 3), true),
            array(array('foo' => 1, 'bar' => 2), true),
        );
    }

    public function getTestsForParse()
    {
        return array(
            array('', ''),
            array('null', null),
            array('false', false),
            array('true', true),
            array('12', 12),
            array('-12', -12),
            array('"quoted string"', 'quoted string'),
            array("'quoted string'", 'quoted string'),
            array('12.30e+02', 12.30e+02),
            array('0x4D2', 0x4D2),
            array('02333', 02333),
            array('.Inf', -log(0)),
            array('-.Inf', log(0)),
            array("'686e444'", '686e444'),
            array('686e444', 646e444),
            array('123456789123456789123456789123456789', '123456789123456789123456789123456789'),
            array('"foo\r\nbar"', "foo\r\nbar"),
            array("'foo#bar'", 'foo#bar'),
            array("'foo # bar'", 'foo # bar'),
            array("'#cfcfcf'", '#cfcfcf'),
            array('::form_base.html.twig', '::form_base.html.twig'),

            // Pre-YAML-1.2 booleans
            array("'y'", 'y'),
            array("'n'", 'n'),
            array("'yes'", 'yes'),
            array("'no'", 'no'),
            array("'on'", 'on'),
            array("'off'", 'off'),

            array('2007-10-30', gmmktime(0, 0, 0, 10, 30, 2007)),
            array('2007-10-30T02:59:43Z', gmmktime(2, 59, 43, 10, 30, 2007)),
            array('2007-10-30 02:59:43 Z', gmmktime(2, 59, 43, 10, 30, 2007)),
            array('1960-10-30 02:59:43 Z', gmmktime(2, 59, 43, 10, 30, 1960)),
            array('1730-10-30T02:59:43Z', gmmktime(2, 59, 43, 10, 30, 1730)),

            array('"a \\"string\\" with \'quoted strings inside\'"', 'a "string" with \'quoted strings inside\''),
            array("'a \"string\" with ''quoted strings inside'''", 'a "string" with \'quoted strings inside\''),

            // sequences
            // urls are no key value mapping. see #3609. Valid yaml "key: value" mappings require a space after the colon
            array('[foo, http://urls.are/no/mappings, false, null, 12]', array('foo', 'http://urls.are/no/mappings', false, null, 12)),
            array('[  foo  ,   bar , false  ,  null     ,  12  ]', array('foo', 'bar', false, null, 12)),
            array('[\'foo,bar\', \'foo bar\']', array('foo,bar', 'foo bar')),

            // mappings
            array('{foo:bar,bar:foo,false:false,null:null,integer:12}', array('foo' => 'bar', 'bar' => 'foo', 'false' => false, 'null' => null, 'integer' => 12)),
            array('{ foo  : bar, bar : foo,  false  :   false,  null  :   null,  integer :  12  }', array('foo' => 'bar', 'bar' => 'foo', 'false' => false, 'null' => null, 'integer' => 12)),
            array('{foo: \'bar\', bar: \'foo: bar\'}', array('foo' => 'bar', 'bar' => 'foo: bar')),
            array('{\'foo\': \'bar\', "bar": \'foo: bar\'}', array('foo' => 'bar', 'bar' => 'foo: bar')),
            array('{\'foo\'\'\': \'bar\', "bar\"": \'foo: bar\'}', array('foo\'' => 'bar', 'bar"' => 'foo: bar')),
            array('{\'foo: \': \'bar\', "bar: ": \'foo: bar\'}', array('foo: ' => 'bar', 'bar: ' => 'foo: bar')),

            // nested sequences and mappings
            array('[foo, [bar, foo]]', array('foo', array('bar', 'foo'))),
            array('[foo, {bar: foo}]', array('foo', array('bar' => 'foo'))),
            array('{ foo: {bar: foo} }', array('foo' => array('bar' => 'foo'))),
            array('{ foo: [bar, foo] }', array('foo' => array('bar', 'foo'))),

            array('[  foo, [  bar, foo  ]  ]', array('foo', array('bar', 'foo'))),

            array('[{ foo: {bar: foo} }]', array(array('foo' => array('bar' => 'foo')))),

            array('[foo, [bar, [foo, [bar, foo]], foo]]', array('foo', array('bar', array('foo', array('bar', 'foo')), 'foo'))),

            array('[foo, {bar: foo, foo: [foo, {bar: foo}]}, [foo, {bar: foo}]]', array('foo', array('bar' => 'foo', 'foo' => array('foo', array('bar' => 'foo'))), array('foo', array('bar' => 'foo')))),

            array('[foo, bar: { foo: bar }]', array('foo', '1' => array('bar' => array('foo' => 'bar')))),
            array('[foo, \'@foo.baz\', { \'%foo%\': \'foo is %foo%\', bar: \'%foo%\' }, true, \'@service_container\']', array('foo', '@foo.baz', array('%foo%' => 'foo is %foo%', 'bar' => '%foo%'), true, '@service_container')),
        );
    }

    public function getTestsForParseWithMapObjects()
    {
        return array(
            array('', ''),
            array('null', null),
            array('false', false),
            array('true', true),
            array('12', 12),
            array('-12', -12),
            array('"quoted string"', 'quoted string'),
            array("'quoted string'", 'quoted string'),
            array('12.30e+02', 12.30e+02),
            array('0x4D2', 0x4D2),
            array('02333', 02333),
            array('.Inf', -log(0)),
            array('-.Inf', log(0)),
            array("'686e444'", '686e444'),
            array('686e444', 646e444),
            array('123456789123456789123456789123456789', '123456789123456789123456789123456789'),
            array('"foo\r\nbar"', "foo\r\nbar"),
            array("'foo#bar'", 'foo#bar'),
            array("'foo # bar'", 'foo # bar'),
            array("'#cfcfcf'", '#cfcfcf'),
            array('::form_base.html.twig', '::form_base.html.twig'),

            array('2007-10-30', gmmktime(0, 0, 0, 10, 30, 2007)),
            array('2007-10-30T02:59:43Z', gmmktime(2, 59, 43, 10, 30, 2007)),
            array('2007-10-30 02:59:43 Z', gmmktime(2, 59, 43, 10, 30, 2007)),
            array('1960-10-30 02:59:43 Z', gmmktime(2, 59, 43, 10, 30, 1960)),
            array('1730-10-30T02:59:43Z', gmmktime(2, 59, 43, 10, 30, 1730)),

            array('"a \\"string\\" with \'quoted strings inside\'"', 'a "string" with \'quoted strings inside\''),
            array("'a \"string\" with ''quoted strings inside'''", 'a "string" with \'quoted strings inside\''),

            // sequences
            // urls are no key value mapping. see #3609. Valid yaml "key: value" mappings require a space after the colon
            array('[foo, http://urls.are/no/mappings, false, null, 12]', array('foo', 'http://urls.are/no/mappings', false, null, 12)),
            array('[  foo  ,   bar , false  ,  null     ,  12  ]', array('foo', 'bar', false, null, 12)),
            array('[\'foo,bar\', \'foo bar\']', array('foo,bar', 'foo bar')),

            // mappings
            array('{foo:bar,bar:foo,false:false,null:null,integer:12}', (object) array('foo' => 'bar', 'bar' => 'foo', 'false' => false, 'null' => null, 'integer' => 12)),
            array('{ foo  : bar, bar : foo,  false  :   false,  null  :   null,  integer :  12  }', (object) array('foo' => 'bar', 'bar' => 'foo', 'false' => false, 'null' => null, 'integer' => 12)),
            array('{foo: \'bar\', bar: \'foo: bar\'}', (object) array('foo' => 'bar', 'bar' => 'foo: bar')),
            array('{\'foo\': \'bar\', "bar": \'foo: bar\'}', (object) array('foo' => 'bar', 'bar' => 'foo: bar')),
            array('{\'foo\'\'\': \'bar\', "bar\"": \'foo: bar\'}', (object) array('foo\'' => 'bar', 'bar"' => 'foo: bar')),
            array('{\'foo: \': \'bar\', "bar: ": \'foo: bar\'}', (object) array('foo: ' => 'bar', 'bar: ' => 'foo: bar')),

            // nested sequences and mappings
            array('[foo, [bar, foo]]', array('foo', array('bar', 'foo'))),
            array('[foo, {bar: foo}]', array('foo', (object) array('bar' => 'foo'))),
            array('{ foo: {bar: foo} }', (object) array('foo' => (object) array('bar' => 'foo'))),
            array('{ foo: [bar, foo] }', (object) array('foo' => array('bar', 'foo'))),

            array('[  foo, [  bar, foo  ]  ]', array('foo', array('bar', 'foo'))),

            array('[{ foo: {bar: foo} }]', array((object) array('foo' => (object) array('bar' => 'foo')))),

            array('[foo, [bar, [foo, [bar, foo]], foo]]', array('foo', array('bar', array('foo', array('bar', 'foo')), 'foo'))),

            array('[foo, {bar: foo, foo: [foo, {bar: foo}]}, [foo, {bar: foo}]]', array('foo', (object) array('bar' => 'foo', 'foo' => array('foo', (object) array('bar' => 'foo'))), array('foo', (object) array('bar' => 'foo')))),

            array('[foo, bar: { foo: bar }]', array('foo', '1' => (object) array('bar' => (object) array('foo' => 'bar')))),
            array('[foo, \'@foo.baz\', { \'%foo%\': \'foo is %foo%\', bar: \'%foo%\' }, true, \'@service_container\']', array('foo', '@foo.baz', (object) array('%foo%' => 'foo is %foo%', 'bar' => '%foo%'), true, '@service_container')),

            array('{}', new \stdClass()),
            array('{ foo  : bar, bar : {}  }', (object) array('foo' => 'bar', 'bar' => new \stdClass())),
            array('{ foo  : [], bar : {}  }', (object) array('foo' => array(), 'bar' => new \stdClass())),
            array('{foo: \'bar\', bar: {} }', (object) array('foo' => 'bar', 'bar' => new \stdClass())),
            array('{\'foo\': \'bar\', "bar": {}}', (object) array('foo' => 'bar', 'bar' => new \stdClass())),
            array('{\'foo\': \'bar\', "bar": \'{}\'}', (object) array('foo' => 'bar', 'bar' => '{}')),

            array('[foo, [{}, {}]]', array('foo', array(new \stdClass(), new \stdClass()))),
            array('[foo, [[], {}]]', array('foo', array(array(), new \stdClass()))),
            array('[foo, [[{}, {}], {}]]', array('foo', array(array(new \stdClass(), new \stdClass()), new \stdClass()))),
            array('[foo, {bar: {}}]', array('foo', '1' => (object) array('bar' => new \stdClass()))),
        );
    }

    public function getTestsForDump()
    {
        return array(
            array('null', null),
            array('false', false),
            array('true', true),
            array('12', 12),
            array("'quoted string'", 'quoted string'),
            array('!!float 1230', 12.30e+02),
            array('1234', 0x4D2),
            array('1243', 02333),
            array('.Inf', -log(0)),
            array('-.Inf', log(0)),
            array("'686e444'", '686e444'),
            array('"foo\r\nbar"', "foo\r\nbar"),
            array("'foo#bar'", 'foo#bar'),
            array("'foo # bar'", 'foo # bar'),
            array("'#cfcfcf'", '#cfcfcf'),

            array("'a \"string\" with ''quoted strings inside'''", 'a "string" with \'quoted strings inside\''),

            array("'-dash'", '-dash'),
            array("'-'", '-'),

            // Pre-YAML-1.2 booleans
            array("'y'", 'y'),
            array("'n'", 'n'),
            array("'yes'", 'yes'),
            array("'no'", 'no'),
            array("'on'", 'on'),
            array("'off'", 'off'),

            // sequences
            array('[foo, bar, false, null, 12]', array('foo', 'bar', false, null, 12)),
            array('[\'foo,bar\', \'foo bar\']', array('foo,bar', 'foo bar')),

            // mappings
            array('{ foo: bar, bar: foo, \'false\': false, \'null\': null, integer: 12 }', array('foo' => 'bar', 'bar' => 'foo', 'false' => false, 'null' => null, 'integer' => 12)),
            array('{ foo: bar, bar: \'foo: bar\' }', array('foo' => 'bar', 'bar' => 'foo: bar')),

            // nested sequences and mappings
            array('[foo, [bar, foo]]', array('foo', array('bar', 'foo'))),

            array('[foo, [bar, [foo, [bar, foo]], foo]]', array('foo', array('bar', array('foo', array('bar', 'foo')), 'foo'))),

            array('{ foo: { bar: foo } }', array('foo' => array('bar' => 'foo'))),

            array('[foo, { bar: foo }]', array('foo', array('bar' => 'foo'))),

            array('[foo, { bar: foo, foo: [foo, { bar: foo }] }, [foo, { bar: foo }]]', array('foo', array('bar' => 'foo', 'foo' => array('foo', array('bar' => 'foo'))), array('foo', array('bar' => 'foo')))),

            array('[foo, \'@foo.baz\', { \'%foo%\': \'foo is %foo%\', bar: \'%foo%\' }, true, \'@service_container\']', array('foo', '@foo.baz', array('%foo%' => 'foo is %foo%', 'bar' => '%foo%'), true, '@service_container')),

            array('{ foo: { bar: { 1: 2, baz: 3 } } }', array('foo' => array('bar' => array(1 => 2, 'baz' => 3)))),
        );
    }
}
PKϤ$Z�p<�yaml/Tests/YamlTest.phpnu�[���<?php

/*
 * This file is part of the Symfony package.
 *
 * (c) Fabien Potencier <fabien@symfony.com>
 *
 * For the full copyright and license information, please view the LICENSE
 * file that was distributed with this source code.
 */

namespace Symfony\Component\Yaml\Tests;

use Symfony\Component\Yaml\Yaml;

class YamlTest extends \PHPUnit_Framework_TestCase
{
    public function testParseAndDump()
    {
        $data = array('lorem' => 'ipsum', 'dolor' => 'sit');
        $yml = Yaml::dump($data);
        $parsed = Yaml::parse($yml);
        $this->assertEquals($data, $parsed);
    }

    /**
     * @group legacy
     */
    public function testLegacyParseFromFile()
    {
        $filename = __DIR__.'/Fixtures/index.yml';
        $contents = file_get_contents($filename);
        $parsedByFilename = Yaml::parse($filename);
        $parsedByContents = Yaml::parse($contents);
        $this->assertEquals($parsedByFilename, $parsedByContents);
    }

    /**
     * @expectedException \InvalidArgumentException
     * @expectedExceptionMessage The indentation must be greater than zero
     */
    public function testZeroIndentationThrowsException()
    {
        Yaml::dump(array('lorem' => 'ipsum', 'dolor' => 'sit'), 2, 0);
    }

    /**
     * @expectedException \InvalidArgumentException
     * @expectedExceptionMessage The indentation must be greater than zero
     */
    public function testNegativeIndentationThrowsException()
    {
        Yaml::dump(array('lorem' => 'ipsum', 'dolor' => 'sit'), 2, -4);
    }
}
PKϤ$ZoL�33%yaml/Tests/Fixtures/YtsBasicTests.ymlnu�[���--- %YAML:1.0
test: Simple Sequence
brief: |
    You can specify a list in YAML by placing each
    member of the list on a new line with an opening
    dash. These lists are called sequences.
yaml: |
    - apple
    - banana
    - carrot
php: |
    array('apple', 'banana', 'carrot')
---
test: Sequence With Item Being Null In The Middle
brief: |
    You can specify a list in YAML by placing each
    member of the list on a new line with an opening
    dash. These lists are called sequences.
yaml: |
    - apple
    -
    - carrot
php: |
    array('apple', null, 'carrot')
---
test: Sequence With Last Item Being Null
brief: |
    You can specify a list in YAML by placing each
    member of the list on a new line with an opening
    dash. These lists are called sequences.
yaml: |
    - apple
    - banana
    -
php: |
    array('apple', 'banana', null)
---
test: Nested Sequences
brief: |
    You can include a sequence within another
    sequence by giving the sequence an empty
    dash, followed by an indented list.
yaml: |
    -
     - foo
     - bar
     - baz
php: |
    array(array('foo', 'bar', 'baz'))
---
test: Mixed Sequences
brief: |
    Sequences can contain any YAML data,
    including strings and other sequences.
yaml: |
    - apple
    -
     - foo
     - bar
     - x123
    - banana
    - carrot
php: |
    array('apple', array('foo', 'bar', 'x123'), 'banana', 'carrot')
---
test: Deeply Nested Sequences
brief: |
    Sequences can be nested even deeper, with each
    level of indentation representing a level of
    depth.
yaml: |
    -
     -
      - uno
      - dos
php: |
    array(array(array('uno', 'dos')))
---
test: Simple Mapping
brief: |
    You can add a keyed list (also known as a dictionary or
    hash) to your document by placing each member of the
    list on a new line, with a colon separating the key
    from its value.  In YAML, this type of list is called
    a mapping.
yaml: |
    foo: whatever
    bar: stuff
php: |
    array('foo' => 'whatever', 'bar' => 'stuff')
---
test: Sequence in a Mapping
brief: |
    A value in a mapping can be a sequence.
yaml: |
    foo: whatever
    bar:
     - uno
     - dos
php: |
    array('foo' => 'whatever', 'bar' => array('uno', 'dos'))
---
test: Nested Mappings
brief: |
    A value in a mapping can be another mapping.
yaml: |
    foo: whatever
    bar:
     fruit: apple
     name: steve
     sport: baseball
php: |
    array(
      'foo' => 'whatever',
      'bar' => array(
         'fruit' => 'apple',
         'name' => 'steve',
         'sport' => 'baseball'
       )
    )
---
test: Mixed Mapping
brief: |
    A mapping can contain any assortment
    of mappings and sequences as values.
yaml: |
    foo: whatever
    bar:
     -
       fruit: apple
       name: steve
       sport: baseball
     - more
     -
       python: rocks
       perl: papers
       ruby: scissorses
php: |
    array(
      'foo' => 'whatever',
      'bar' => array(
        array(
            'fruit' => 'apple',
            'name' => 'steve',
            'sport' => 'baseball'
        ),
        'more',
        array(
            'python' => 'rocks',
            'perl' => 'papers',
            'ruby' => 'scissorses'
        )
      )
    )
---
test: Mapping-in-Sequence Shortcut
todo: true
brief: |
     If you are adding a mapping to a sequence, you
     can place the mapping on the same line as the
     dash as a shortcut.
yaml: |
     - work on YAML.py:
        - work on Store
php: |
    array(array('work on YAML.py' => array('work on Store')))
---
test: Sequence-in-Mapping Shortcut
todo: true
brief: |
     The dash in a sequence counts as indentation, so
     you can add a sequence inside of a mapping without
     needing spaces as indentation.
yaml: |
     allow:
     - 'localhost'
     - '%.sourceforge.net'
     - '%.freepan.org'
php: |
     array('allow' => array('localhost', '%.sourceforge.net', '%.freepan.org'))
---
todo: true
test: Merge key
brief: |
     A merge key ('<<') can be used in a mapping to insert other mappings.  If
     the value associated with the merge key is a mapping, each of its key/value
     pairs is inserted into the current mapping.
yaml: |
     mapping:
       name: Joe
       job: Accountant
       <<:
         age: 38
php: |
     array(
       'mapping' =>
       array(
         'name' => 'Joe',
         'job' => 'Accountant',
         'age' => 38
       )
     )
PKϤ$Z�5�R[[&yaml/Tests/Fixtures/YtsAnchorAlias.ymlnu�[���--- %YAML:1.0
test: Simple Alias Example
brief: >
    If you need to refer to the same item of data twice,
    you can give that item an alias.  The alias is a plain
    string, starting with an ampersand.  The item may then
    be referred to by the alias throughout your document
    by using an asterisk before the name of the alias.
    This is called an anchor.
yaml: |
    - &showell Steve
    - Clark
    - Brian
    - Oren
    - *showell
php: |
    array('Steve', 'Clark', 'Brian', 'Oren', 'Steve')

---
test: Alias of a Mapping
brief: >
    An alias can be used on any item of data, including
    sequences, mappings, and other complex data types.
yaml: |
    - &hello
        Meat: pork
        Starch: potato
    - banana
    - *hello
php: |
    array(array('Meat'=>'pork', 'Starch'=>'potato'), 'banana', array('Meat'=>'pork', 'Starch'=>'potato'))
PKϤ$Z�<�!yaml/Tests/Fixtures/sfObjects.ymlnu�[���--- %YAML:1.0
test: Objects
brief: >
    Comments at the end of a line
yaml: |
    ex1: "foo # bar"
    ex2: "foo # bar" # comment
    ex3: 'foo # bar' # comment
    ex4: foo # comment
php: |
    array('ex1' => 'foo # bar', 'ex2' => 'foo # bar', 'ex3' => 'foo # bar', 'ex4' => 'foo')
PKϤ$Z�a9qr�r�0yaml/Tests/Fixtures/YtsSpecificationExamples.ymlnu�[���--- %YAML:1.0
test: Sequence of scalars
spec: 2.1
yaml: |
  - Mark McGwire
  - Sammy Sosa
  - Ken Griffey
php: |
  array('Mark McGwire', 'Sammy Sosa', 'Ken Griffey')
---
test: Mapping of scalars to scalars
spec: 2.2
yaml: |
  hr:  65
  avg: 0.278
  rbi: 147
php: |
  array('hr' => 65, 'avg' => 0.278, 'rbi' => 147)
---
test: Mapping of scalars to sequences
spec: 2.3
yaml: |
    american:
       - Boston Red Sox
       - Detroit Tigers
       - New York Yankees
    national:
       - New York Mets
       - Chicago Cubs
       - Atlanta Braves
php: |
    array('american' =>
        array( 'Boston Red Sox', 'Detroit Tigers',
          'New York Yankees' ),
      'national' =>
        array( 'New York Mets', 'Chicago Cubs',
          'Atlanta Braves' )
    )
---
test: Sequence of mappings
spec: 2.4
yaml: |
    -
      name: Mark McGwire
      hr:   65
      avg:  0.278
    -
      name: Sammy Sosa
      hr:   63
      avg:  0.288
php: |
    array(
      array('name' => 'Mark McGwire', 'hr' => 65, 'avg' => 0.278),
      array('name' => 'Sammy Sosa', 'hr' => 63, 'avg' => 0.288)
    )
---
test: Legacy A5
todo: true
spec: legacy_A5
yaml: |
    ?
        - New York Yankees
        - Atlanta Braves
    :
      - 2001-07-02
      - 2001-08-12
      - 2001-08-14
    ?
        - Detroit Tigers
        - Chicago Cubs
    :
      - 2001-07-23
perl-busted: >
    YAML.pm will be able to emulate this behavior soon. In this regard
    it may be somewhat more correct than Python's native behaviour which
    can only use tuples as mapping keys. PyYAML will also need to figure
    out some clever way to roundtrip structured keys.
python: |
    [
    {
        ('New York Yankees', 'Atlanta Braves'):
            [yaml.timestamp('2001-07-02'),
             yaml.timestamp('2001-08-12'),
             yaml.timestamp('2001-08-14')],
        ('Detroit Tigers', 'Chicago Cubs'):
        [yaml.timestamp('2001-07-23')]
    }
    ]
ruby: |
    {
      [ 'New York Yankees', 'Atlanta Braves' ] =>
        [ Date.new( 2001, 7, 2 ), Date.new( 2001, 8, 12 ), Date.new( 2001, 8, 14 ) ],
      [ 'Detroit Tigers', 'Chicago Cubs' ] =>
        [ Date.new( 2001, 7, 23 ) ]
    }
syck: |
  struct test_node seq1[] = {
      { T_STR, 0, "New York Yankees" },
      { T_STR, 0, "Atlanta Braves" },
      end_node
  };
  struct test_node seq2[] = {
      { T_STR, 0, "2001-07-02" },
      { T_STR, 0, "2001-08-12" },
      { T_STR, 0, "2001-08-14" },
      end_node
  };
  struct test_node seq3[] = {
      { T_STR, 0, "Detroit Tigers" },
      { T_STR, 0, "Chicago Cubs" },
      end_node
  };
  struct test_node seq4[] = {
      { T_STR, 0, "2001-07-23" },
      end_node
  };
  struct test_node map[] = {
      { T_SEQ, 0, 0, seq1 },
      { T_SEQ, 0, 0, seq2 },
      { T_SEQ, 0, 0, seq3 },
      { T_SEQ, 0, 0, seq4 },
      end_node
  };
  struct test_node stream[] = {
      { T_MAP, 0, 0, map },
      end_node
  };

---
test: Sequence of sequences
spec: 2.5
yaml: |
  - [ name         , hr , avg   ]
  - [ Mark McGwire , 65 , 0.278 ]
  - [ Sammy Sosa   , 63 , 0.288 ]
php: |
  array(
    array( 'name', 'hr', 'avg' ),
    array( 'Mark McGwire', 65, 0.278 ),
    array( 'Sammy Sosa', 63, 0.288 )
  )
---
test: Mapping of mappings
todo: true
spec: 2.6
yaml: |
  Mark McGwire: {hr: 65, avg: 0.278}
  Sammy Sosa: {
      hr: 63,
      avg: 0.288
    }
php: |
  array(
    'Mark McGwire' =>
      array( 'hr' => 65, 'avg' => 0.278 ),
    'Sammy Sosa' =>
      array( 'hr' => 63, 'avg' => 0.288 )
  )
---
test: Two documents in a stream each with a leading comment
todo: true
spec: 2.7
yaml: |
  # Ranking of 1998 home runs
  ---
  - Mark McGwire
  - Sammy Sosa
  - Ken Griffey

  # Team ranking
  ---
  - Chicago Cubs
  - St Louis Cardinals
ruby: |
  y = YAML::Stream.new
  y.add( [ 'Mark McGwire', 'Sammy Sosa', 'Ken Griffey' ] )
  y.add( [ 'Chicago Cubs', 'St Louis Cardinals' ] )
documents: 2

---
test: Play by play feed from a game
todo: true
spec: 2.8
yaml: |
  ---
  time: 20:03:20
  player: Sammy Sosa
  action: strike (miss)
  ...
  ---
  time: 20:03:47
  player: Sammy Sosa
  action: grand slam
  ...
perl: |
  [ 'Mark McGwire', 'Sammy Sosa', 'Ken Griffey' ]
documents: 2

---
test: Single document with two comments
spec: 2.9
yaml: |
  hr: # 1998 hr ranking
    - Mark McGwire
    - Sammy Sosa
  rbi:
    # 1998 rbi ranking
    - Sammy Sosa
    - Ken Griffey
php: |
  array(
    'hr' => array( 'Mark McGwire', 'Sammy Sosa' ),
    'rbi' => array( 'Sammy Sosa', 'Ken Griffey' )
  )
---
test: Node for Sammy Sosa appears twice in this document
spec: 2.10
yaml: |
   ---
   hr:
      - Mark McGwire
      # Following node labeled SS
      - &SS Sammy Sosa
   rbi:
      - *SS # Subsequent occurrence
      - Ken Griffey
php: |
   array(
      'hr' =>
         array('Mark McGwire', 'Sammy Sosa'),
      'rbi' =>
         array('Sammy Sosa', 'Ken Griffey')
   )
---
test: Mapping between sequences
todo: true
spec: 2.11
yaml: |
   ? # PLAY SCHEDULE
     - Detroit Tigers
     - Chicago Cubs
   :
     - 2001-07-23

   ? [ New York Yankees,
       Atlanta Braves ]
   : [ 2001-07-02, 2001-08-12,
       2001-08-14 ]
ruby: |
   {
      [ 'Detroit Tigers', 'Chicago Cubs' ] => [ Date.new( 2001, 7, 23 ) ],
      [ 'New York Yankees', 'Atlanta Braves' ] => [ Date.new( 2001, 7, 2 ), Date.new( 2001, 8, 12 ), Date.new( 2001, 8, 14 ) ]
   }
syck: |
  struct test_node seq1[] = {
      { T_STR, 0, "New York Yankees" },
      { T_STR, 0, "Atlanta Braves" },
      end_node
  };
  struct test_node seq2[] = {
      { T_STR, 0, "2001-07-02" },
      { T_STR, 0, "2001-08-12" },
      { T_STR, 0, "2001-08-14" },
      end_node
  };
  struct test_node seq3[] = {
      { T_STR, 0, "Detroit Tigers" },
      { T_STR, 0, "Chicago Cubs" },
      end_node
  };
  struct test_node seq4[] = {
      { T_STR, 0, "2001-07-23" },
      end_node
  };
  struct test_node map[] = {
      { T_SEQ, 0, 0, seq3 },
      { T_SEQ, 0, 0, seq4 },
      { T_SEQ, 0, 0, seq1 },
      { T_SEQ, 0, 0, seq2 },
      end_node
  };
  struct test_node stream[] = {
      { T_MAP, 0, 0, map },
      end_node
  };

---
test: Sequence key shortcut
spec: 2.12
yaml: |
  ---
  # products purchased
  - item    : Super Hoop
    quantity: 1
  - item    : Basketball
    quantity: 4
  - item    : Big Shoes
    quantity: 1
php: |
  array (
    array (
      'item' => 'Super Hoop',
      'quantity' => 1,
    ),
    array (
      'item' => 'Basketball',
      'quantity' => 4,
    ),
    array (
      'item' => 'Big Shoes',
      'quantity' => 1,
    )
  )
perl: |
  [
     { item => 'Super Hoop', quantity => 1 },
     { item => 'Basketball', quantity => 4 },
     { item => 'Big Shoes',  quantity => 1 }
  ]

ruby: |
  [
     { 'item' => 'Super Hoop', 'quantity' => 1 },
     { 'item' => 'Basketball', 'quantity' => 4 },
     { 'item' => 'Big Shoes', 'quantity' => 1 }
  ]
python: |
  [
       { 'item': 'Super Hoop', 'quantity': 1 },
       { 'item': 'Basketball', 'quantity': 4 },
       { 'item': 'Big Shoes',  'quantity': 1 }
  ]
syck: |
  struct test_node map1[] = {
      { T_STR, 0, "item" },
          { T_STR, 0, "Super Hoop" },
      { T_STR, 0, "quantity" },
          { T_STR, 0, "1" },
      end_node
  };
  struct test_node map2[] = {
      { T_STR, 0, "item" },
          { T_STR, 0, "Basketball" },
      { T_STR, 0, "quantity" },
          { T_STR, 0, "4" },
      end_node
  };
  struct test_node map3[] = {
      { T_STR, 0, "item" },
          { T_STR, 0, "Big Shoes" },
      { T_STR, 0, "quantity" },
          { T_STR, 0, "1" },
      end_node
  };
  struct test_node seq[] = {
      { T_MAP, 0, 0, map1 },
      { T_MAP, 0, 0, map2 },
      { T_MAP, 0, 0, map3 },
      end_node
  };
  struct test_node stream[] = {
      { T_SEQ, 0, 0, seq },
      end_node
  };


---
test: Literal perserves newlines
todo: true
spec: 2.13
yaml: |
  # ASCII Art
  --- |
    \//||\/||
    // ||  ||_
perl: |
  "\\//||\\/||\n// ||  ||_\n"
ruby: |
  "\\//||\\/||\n// ||  ||_\n"
python: |
    [
        flushLeft(
        """
        \//||\/||
        // ||  ||_
        """
        )
    ]
syck: |
  struct test_node stream[] = {
      { T_STR, 0, "\\//||\\/||\n// ||  ||_\n" },
      end_node
  };

---
test: Folded treats newlines as a space
todo: true
spec: 2.14
yaml: |
  ---
    Mark McGwire's
    year was crippled
    by a knee injury.
perl: |
  "Mark McGwire's year was crippled by a knee injury."
ruby: |
  "Mark McGwire's year was crippled by a knee injury."
python: |
    [ "Mark McGwire's year was crippled by a knee injury." ]
syck: |
  struct test_node stream[] = {
      { T_STR, 0, "Mark McGwire's year was crippled by a knee injury." },
      end_node
  };

---
test: Newlines preserved for indented and blank lines
todo: true
spec: 2.15
yaml: |
  --- >
   Sammy Sosa completed another
   fine season with great stats.

     63 Home Runs
     0.288 Batting Average

   What a year!
perl: |
  "Sammy Sosa completed another fine season with great stats.\n\n  63 Home Runs\n  0.288 Batting Average\n\nWhat a year!\n"
ruby: |
  "Sammy Sosa completed another fine season with great stats.\n\n  63 Home Runs\n  0.288 Batting Average\n\nWhat a year!\n"
python: |
    [
        flushLeft(
        """
        Sammy Sosa completed another fine season with great stats.

          63 Home Runs
          0.288 Batting Average

        What a year!
        """
        )
    ]
syck: |
  struct test_node stream[] = {
      { T_STR, 0, "Sammy Sosa completed another fine season with great stats.\n\n  63 Home Runs\n  0.288 Batting Average\n\nWhat a year!\n" },
      end_node
  };


---
test: Indentation determines scope
spec: 2.16
yaml: |
  name: Mark McGwire
  accomplishment: >
     Mark set a major league
     home run record in 1998.
  stats: |
     65 Home Runs
     0.278 Batting Average
php: |
  array(
    'name' => 'Mark McGwire',
    'accomplishment' => "Mark set a major league home run record in 1998.\n",
    'stats' => "65 Home Runs\n0.278 Batting Average\n"
  )
---
test: Quoted scalars
todo: true
spec: 2.17
yaml: |
  unicode: "Sosa did fine.\u263A"
  control: "\b1998\t1999\t2000\n"
  hexesc:  "\x0D\x0A is \r\n"

  single: '"Howdy!" he cried.'
  quoted: ' # not a ''comment''.'
  tie-fighter: '|\-*-/|'
ruby: |
  {
    "tie-fighter" => "|\\-*-/|",
    "control"=>"\0101998\t1999\t2000\n",
    "unicode"=>"Sosa did fine." + ["263A".hex ].pack('U*'),
    "quoted"=>" # not a 'comment'.",
    "single"=>"\"Howdy!\" he cried.",
    "hexesc"=>"\r\n is \r\n"
  }
---
test: Multiline flow scalars
todo: true
spec: 2.18
yaml: |
  plain:
    This unquoted scalar
    spans many lines.

  quoted: "So does this
    quoted scalar.\n"
ruby: |
  {
    'plain' => 'This unquoted scalar spans many lines.',
    'quoted' => "So does this quoted scalar.\n"
  }
---
test: Integers
spec: 2.19
yaml: |
  canonical: 12345
  decimal: +12,345
  octal: 014
  hexadecimal: 0xC
php: |
  array(
    'canonical' => 12345,
    'decimal' => 12345.0,
    'octal' => 014,
    'hexadecimal' => 0xC
  )
---
# FIX: spec shows parens around -inf and NaN
test: Floating point
spec: 2.20
yaml: |
  canonical: 1.23015e+3
  exponential: 12.3015e+02
  fixed: 1,230.15
  negative infinity: -.inf
  not a number: .NaN
  float as whole number: !!float 1
php: |
  array(
    'canonical' => 1230.15,
    'exponential' => 1230.15,
    'fixed' => 1230.15,
    'negative infinity' => log(0),
    'not a number' => -log(0),
    'float as whole number' => (float) 1
  )
---
test: Miscellaneous
spec: 2.21
yaml: |
  null: ~
  true: true
  false: false
  string: '12345'
php: |
  array(
    '' => null,
    1 => true,
    0 => false,
    'string' => '12345'
  )
---
test: Timestamps
todo: true
spec: 2.22
yaml: |
  canonical: 2001-12-15T02:59:43.1Z
  iso8601:  2001-12-14t21:59:43.10-05:00
  spaced:  2001-12-14 21:59:43.10 -05:00
  date:   2002-12-14 # Time is noon UTC
php: |
  array(
    'canonical' => YAML::mktime( 2001, 12, 15, 2, 59, 43, 0.10 ),
    'iso8601' => YAML::mktime( 2001, 12, 14, 21, 59, 43, 0.10, "-05:00" ),
    'spaced' => YAML::mktime( 2001, 12, 14, 21, 59, 43, 0.10, "-05:00" ),
    'date' => Date.new( 2002, 12, 14 )
  )
---
test: legacy Timestamps test
todo: true
spec: legacy D4
yaml: |
    canonical: 2001-12-15T02:59:43.00Z
    iso8601:  2001-02-28t21:59:43.00-05:00
    spaced:  2001-12-14 21:59:43.00 -05:00
    date:   2002-12-14
php: |
   array(
     'canonical' => Time::utc( 2001, 12, 15, 2, 59, 43, 0 ),
     'iso8601' => YAML::mktime( 2001, 2, 28, 21, 59, 43, 0, "-05:00" ),
     'spaced' => YAML::mktime( 2001, 12, 14, 21, 59, 43, 0, "-05:00" ),
     'date' => Date.new( 2002, 12, 14 )
   )
---
test: Various explicit families
todo: true
spec: 2.23
yaml: |
  not-date: !str 2002-04-28
  picture: !binary |
   R0lGODlhDAAMAIQAAP//9/X
   17unp5WZmZgAAAOfn515eXv
   Pz7Y6OjuDg4J+fn5OTk6enp
   56enmleECcgggoBADs=

  application specific tag: !!something |
   The semantics of the tag
   above may be different for
   different documents.

ruby-setup: |
  YAML.add_private_type( "something" ) do |type, val|
    "SOMETHING: #{val}"
  end
ruby: |
  {
    'not-date' => '2002-04-28',
    'picture' => "GIF89a\f\000\f\000\204\000\000\377\377\367\365\365\356\351\351\345fff\000\000\000\347\347\347^^^\363\363\355\216\216\216\340\340\340\237\237\237\223\223\223\247\247\247\236\236\236i^\020' \202\n\001\000;",
    'application specific tag' => "SOMETHING: The semantics of the tag\nabove may be different for\ndifferent documents.\n"
  }
---
test: Application specific family
todo: true
spec: 2.24
yaml: |
  # Establish a tag prefix
  --- !clarkevans.com,2002/graph/^shape
    # Use the prefix: shorthand for
    # !clarkevans.com,2002/graph/circle
  - !^circle
    center: &ORIGIN {x: 73, 'y': 129}
    radius: 7
  - !^line # !clarkevans.com,2002/graph/line
    start: *ORIGIN
    finish: { x: 89, 'y': 102 }
  - !^label
    start: *ORIGIN
    color: 0xFFEEBB
    value: Pretty vector drawing.
ruby-setup: |
  YAML.add_domain_type( "clarkevans.com,2002", 'graph/shape' ) { |type, val|
    if Array === val
      val << "Shape Container"
      val
    else
      raise YAML::Error, "Invalid graph of class #{ val.class }: " + val.inspect
    end
  }
  one_shape_proc = Proc.new { |type, val|
    scheme, domain, type = type.split( /:/, 3 )
    if val.is_a? ::Hash
      val['TYPE'] = "Shape: #{type}"
      val
    else
      raise YAML::Error, "Invalid graph of class #{ val.class }: " + val.inspect
    end
  }
  YAML.add_domain_type( "clarkevans.com,2002", 'graph/circle', &one_shape_proc )
  YAML.add_domain_type( "clarkevans.com,2002", 'graph/line', &one_shape_proc )
  YAML.add_domain_type( "clarkevans.com,2002", 'graph/label', &one_shape_proc )
ruby: |
  [
    {
      "radius" => 7,
      "center"=>
      {
        "x" => 73,
        "y" => 129
      },
      "TYPE" => "Shape: graph/circle"
    }, {
      "finish" =>
      {
        "x" => 89,
        "y" => 102
      },
      "TYPE" => "Shape: graph/line",
      "start" =>
      {
        "x" => 73,
        "y" => 129
      }
    }, {
      "TYPE" => "Shape: graph/label",
      "value" => "Pretty vector drawing.",
      "start" =>
      {
        "x" => 73,
        "y" => 129
      },
      "color" => 16772795
    },
    "Shape Container"
  ]
# ---
# test: Unordered set
# spec: 2.25
# yaml: |
#   # sets are represented as a
#   # mapping where each key is
#   # associated with the empty string
#   --- !set
#   ? Mark McGwire
#   ? Sammy Sosa
#   ? Ken Griff
---
test: Ordered mappings
todo: true
spec: 2.26
yaml: |
  # ordered maps are represented as
  # a sequence of mappings, with
  # each mapping having one key
  --- !omap
  - Mark McGwire: 65
  - Sammy Sosa: 63
  - Ken Griffy: 58
ruby: |
  YAML::Omap[
    'Mark McGwire', 65,
    'Sammy Sosa', 63,
    'Ken Griffy', 58
  ]
---
test: Invoice
dump_skip: true
spec: 2.27
yaml: |
  --- !clarkevans.com,2002/^invoice
  invoice: 34843
  date   : 2001-01-23
  bill-to: &id001
      given  : Chris
      family : Dumars
      address:
          lines: |
              458 Walkman Dr.
              Suite #292
          city    : Royal Oak
          state   : MI
          postal  : 48046
  ship-to: *id001
  product:
      -
        sku         : BL394D
        quantity    : 4
        description : Basketball
        price       : 450.00
      -
        sku         : BL4438H
        quantity    : 1
        description : Super Hoop
        price       : 2392.00
  tax  : 251.42
  total: 4443.52
  comments: >
    Late afternoon is best.
    Backup contact is Nancy
    Billsmer @ 338-4338.
php: |
  array(
     'invoice' => 34843, 'date' => gmmktime(0, 0, 0, 1, 23, 2001),
     'bill-to' =>
      array( 'given' => 'Chris', 'family' => 'Dumars', 'address' => array( 'lines' => "458 Walkman Dr.\nSuite #292\n", 'city' => 'Royal Oak', 'state' => 'MI', 'postal' => 48046 ) )
     , 'ship-to' =>
      array( 'given' => 'Chris', 'family' => 'Dumars', 'address' => array( 'lines' => "458 Walkman Dr.\nSuite #292\n", 'city' => 'Royal Oak', 'state' => 'MI', 'postal' => 48046 ) )
     , 'product' =>
       array(
        array( 'sku' => 'BL394D', 'quantity' => 4, 'description' => 'Basketball', 'price' => 450.00 ),
        array( 'sku' => 'BL4438H', 'quantity' => 1, 'description' => 'Super Hoop', 'price' => 2392.00 )
      ),
     'tax' => 251.42, 'total' => 4443.52,
     'comments' => "Late afternoon is best. Backup contact is Nancy Billsmer @ 338-4338.\n"
  )
---
test: Log file
todo: true
spec: 2.28
yaml: |
  ---
  Time: 2001-11-23 15:01:42 -05:00
  User: ed
  Warning: >
    This is an error message
    for the log file
  ---
  Time: 2001-11-23 15:02:31 -05:00
  User: ed
  Warning: >
    A slightly different error
    message.
  ---
  Date: 2001-11-23 15:03:17 -05:00
  User: ed
  Fatal: >
    Unknown variable "bar"
  Stack:
    - file: TopClass.py
      line: 23
      code: |
        x = MoreObject("345\n")
    - file: MoreClass.py
      line: 58
      code: |-
        foo = bar
ruby: |
  y = YAML::Stream.new
  y.add( { 'Time' => YAML::mktime( 2001, 11, 23, 15, 01, 42, 00, "-05:00" ),
           'User' => 'ed', 'Warning' => "This is an error message for the log file\n" } )
  y.add( { 'Time' => YAML::mktime( 2001, 11, 23, 15, 02, 31, 00, "-05:00" ),
           'User' => 'ed', 'Warning' => "A slightly different error message.\n" } )
  y.add( { 'Date' => YAML::mktime( 2001, 11, 23, 15, 03, 17, 00, "-05:00" ),
           'User' => 'ed', 'Fatal' => "Unknown variable \"bar\"\n",
           'Stack' => [
           { 'file' => 'TopClass.py', 'line' => 23, 'code' => "x = MoreObject(\"345\\n\")\n" },
           { 'file' => 'MoreClass.py', 'line' => 58, 'code' => "foo = bar" } ] } )
documents: 3

---
test: Throwaway comments
yaml: |
   ### These are four throwaway comment  ###

   ### lines (the second line is empty). ###
   this: |   # Comments may trail lines.
      contains three lines of text.
      The third one starts with a
      # character. This isn't a comment.

   # These are three throwaway comment
   # lines (the first line is empty).
php: |
   array(
     'this' => "contains three lines of text.\nThe third one starts with a\n# character. This isn't a comment.\n"
   )
---
test: Document with a single value
todo: true
yaml: |
   --- >
   This YAML stream contains a single text value.
   The next stream is a log file - a sequence of
   log entries. Adding an entry to the log is a
   simple matter of appending it at the end.
ruby: |
   "This YAML stream contains a single text value. The next stream is a log file - a sequence of log entries. Adding an entry to the log is a simple matter of appending it at the end.\n"
---
test: Document stream
todo: true
yaml: |
   ---
   at: 2001-08-12 09:25:00.00 Z
   type: GET
   HTTP: '1.0'
   url: '/index.html'
   ---
   at: 2001-08-12 09:25:10.00 Z
   type: GET
   HTTP: '1.0'
   url: '/toc.html'
ruby: |
   y = YAML::Stream.new
   y.add( {
      'at' => Time::utc( 2001, 8, 12, 9, 25, 00 ),
      'type' => 'GET',
      'HTTP' => '1.0',
      'url' => '/index.html'
   } )
   y.add( {
      'at' => Time::utc( 2001, 8, 12, 9, 25, 10 ),
      'type' => 'GET',
      'HTTP' => '1.0',
      'url' => '/toc.html'
   } )
documents: 2

---
test: Top level mapping
yaml: |
   # This stream is an example of a top-level mapping.
   invoice : 34843
   date    : 2001-01-23
   total   : 4443.52
php: |
   array(
      'invoice' => 34843,
      'date' => gmmktime(0, 0, 0, 1, 23, 2001),
      'total' => 4443.52
   )
---
test: Single-line documents
todo: true
yaml: |
  # The following is a sequence of three documents.
  # The first contains an empty mapping, the second
  # an empty sequence, and the last an empty string.
  --- {}
  --- [ ]
  --- ''
ruby: |
  y = YAML::Stream.new
  y.add( {} )
  y.add( [] )
  y.add( '' )
documents: 3

---
test: Document with pause
todo: true
yaml: |
  # A communication channel based on a YAML stream.
  ---
  sent at: 2002-06-06 11:46:25.10 Z
  payload: Whatever
  # Receiver can process this as soon as the following is sent:
  ...
  # Even if the next message is sent long after:
  ---
  sent at: 2002-06-06 12:05:53.47 Z
  payload: Whatever
  ...
ruby: |
  y = YAML::Stream.new
  y.add(
    { 'sent at' => YAML::mktime( 2002, 6, 6, 11, 46, 25, 0.10 ),
      'payload' => 'Whatever' }
  )
  y.add(
    { "payload" => "Whatever", "sent at" => YAML::mktime( 2002, 6, 6, 12, 5, 53, 0.47 ) }
  )
documents: 2

---
test: Explicit typing
yaml: |
   integer: 12
   also int: ! "12"
   string: !str 12
php: |
   array( 'integer' => 12, 'also int' => 12, 'string' => '12' )
---
test: Private types
todo: true
yaml: |
  # Both examples below make use of the 'x-private:ball'
  # type family URI, but with different semantics.
  ---
  pool: !!ball
    number: 8
    color: black
  ---
  bearing: !!ball
    material: steel
ruby: |
  y = YAML::Stream.new
  y.add( { 'pool' =>
    YAML::PrivateType.new( 'ball',
      { 'number' => 8, 'color' => 'black' } ) }
  )
  y.add( { 'bearing' =>
    YAML::PrivateType.new( 'ball',
      { 'material' => 'steel' } ) }
  )
documents: 2

---
test: Type family under yaml.org
yaml: |
  # The URI is 'tag:yaml.org,2002:str'
  - !str a Unicode string
php: |
  array( 'a Unicode string' )
---
test: Type family under perl.yaml.org
todo: true
yaml: |
  # The URI is 'tag:perl.yaml.org,2002:Text::Tabs'
  - !perl/Text::Tabs {}
ruby: |
  [ YAML::DomainType.new( 'perl.yaml.org,2002', 'Text::Tabs', {} ) ]
---
test: Type family under clarkevans.com
todo: true
yaml: |
  # The URI is 'tag:clarkevans.com,2003-02:timesheet'
  - !clarkevans.com,2003-02/timesheet {}
ruby: |
  [ YAML::DomainType.new( 'clarkevans.com,2003-02', 'timesheet', {} ) ]
---
test: URI Escaping
todo: true
yaml: |
  same:
    - !domain.tld,2002/type\x30 value
    - !domain.tld,2002/type0 value
  different: # As far as the YAML parser is concerned
    - !domain.tld,2002/type%30 value
    - !domain.tld,2002/type0 value
ruby-setup: |
  YAML.add_domain_type( "domain.tld,2002", "type0" ) { |type, val|
    "ONE: #{val}"
  }
  YAML.add_domain_type( "domain.tld,2002", "type%30" ) { |type, val|
    "TWO: #{val}"
  }
ruby: |
  { 'same' => [ 'ONE: value', 'ONE: value' ], 'different' => [ 'TWO: value', 'ONE: value' ] }
---
test: URI Prefixing
todo: true
yaml: |
  # 'tag:domain.tld,2002:invoice' is some type family.
  invoice: !domain.tld,2002/^invoice
    # 'seq' is shorthand for 'tag:yaml.org,2002:seq'.
    # This does not effect '^customer' below
    # because it is does not specify a prefix.
    customers: !seq
      # '^customer' is shorthand for the full
      # notation 'tag:domain.tld,2002:customer'.
      - !^customer
        given : Chris
        family : Dumars
ruby-setup: |
  YAML.add_domain_type( "domain.tld,2002", /(invoice|customer)/ ) { |type, val|
    if val.is_a? ::Hash
      scheme, domain, type = type.split( /:/, 3 )
      val['type'] = "domain #{type}"
      val
    else
      raise YAML::Error, "Not a Hash in domain.tld/invoice: " + val.inspect
    end
  }
ruby: |
  { "invoice"=> { "customers"=> [ { "given"=>"Chris", "type"=>"domain customer", "family"=>"Dumars" } ], "type"=>"domain invoice" } }

---
test: Overriding anchors
yaml: |
  anchor : &A001 This scalar has an anchor.
  override : &A001 >
   The alias node below is a
   repeated use of this value.
  alias : *A001
php: |
  array( 'anchor' => 'This scalar has an anchor.',
    'override' => "The alias node below is a repeated use of this value.\n",
    'alias' => "The alias node below is a repeated use of this value.\n" )
---
test: Flow and block formatting
todo: true
yaml: |
  empty: []
  flow: [ one, two, three # May span lines,
           , four,           # indentation is
             five ]          # mostly ignored.
  block:
   - First item in top sequence
   -
    - Subordinate sequence entry
   - >
     A folded sequence entry
   - Sixth item in top sequence
ruby: |
  { 'empty' => [], 'flow' => [ 'one', 'two', 'three', 'four', 'five' ],
    'block' => [ 'First item in top sequence', [ 'Subordinate sequence entry' ],
    "A folded sequence entry\n", 'Sixth item in top sequence' ] }
---
test: Complete mapping test
todo: true
yaml: |
 empty: {}
 flow: { one: 1, two: 2 }
 spanning: { one: 1,
    two: 2 }
 block:
  first : First entry
  second:
   key: Subordinate mapping
  third:
   - Subordinate sequence
   - { }
   - Previous mapping is empty.
   - A key: value pair in a sequence.
     A second: key:value pair.
   - The previous entry is equal to the following one.
   -
     A key: value pair in a sequence.
     A second: key:value pair.
  !float 12 : This key is a float.
  ? >
   ?
  : This key had to be protected.
  "\a" : This key had to be escaped.
  ? >
   This is a
   multi-line
   folded key
  : Whose value is
    also multi-line.
  ? this also works as a key
  : with a value at the next line.
  ?
   - This key
   - is a sequence
  :
   - With a sequence value.
  ?
   This: key
   is a: mapping
  :
   with a: mapping value.
ruby: |
  { 'empty' => {}, 'flow' => { 'one' => 1, 'two' => 2 },
    'spanning' => { 'one' => 1, 'two' => 2 },
    'block' => { 'first' => 'First entry', 'second' =>
    { 'key' => 'Subordinate mapping' }, 'third' =>
      [ 'Subordinate sequence', {}, 'Previous mapping is empty.',
        { 'A key' => 'value pair in a sequence.', 'A second' => 'key:value pair.' },
        'The previous entry is equal to the following one.',
        { 'A key' => 'value pair in a sequence.', 'A second' => 'key:value pair.' } ],
    12.0 => 'This key is a float.', "?\n" => 'This key had to be protected.',
    "\a" => 'This key had to be escaped.',
    "This is a multi-line folded key\n" => "Whose value is also multi-line.",
    'this also works as a key' => 'with a value at the next line.',
    [ 'This key', 'is a sequence' ] => [ 'With a sequence value.' ] } }
  # Couldn't recreate map exactly, so we'll do a detailed check to be sure it's entact
  obj_y['block'].keys.each { |k|
    if Hash === k
      v = obj_y['block'][k]
      if k['This'] == 'key' and k['is a'] == 'mapping' and v['with a'] == 'mapping value.'
         obj_r['block'][k] = v
      end
    end
  }
---
test: Literal explicit indentation
yaml: |
   # Explicit indentation must
   # be given in all the three
   # following cases.
   leading spaces: |2
         This value starts with four spaces.

   leading line break: |2

     This value starts with a line break.

   leading comment indicator: |2
     # first line starts with a
     # character.

   # Explicit indentation may
   # also be given when it is
   # not required.
   redundant: |2
     This value is indented 2 spaces.
php: |
   array(
      'leading spaces' => "    This value starts with four spaces.\n",
      'leading line break' => "\nThis value starts with a line break.\n",
      'leading comment indicator' => "# first line starts with a\n# character.\n",
      'redundant' => "This value is indented 2 spaces.\n"
   )
---
test: Chomping and keep modifiers
yaml: |
    clipped: |
        This has one newline.

    same as "clipped" above: "This has one newline.\n"

    stripped: |-
        This has no newline.

    same as "stripped" above: "This has no newline."

    kept: |+
        This has two newlines.

    same as "kept" above: "This has two newlines.\n\n"
php: |
    array(
      'clipped' => "This has one newline.\n",
      'same as "clipped" above' => "This has one newline.\n",
      'stripped' => 'This has no newline.',
      'same as "stripped" above' => 'This has no newline.',
      'kept' => "This has two newlines.\n\n",
      'same as "kept" above' => "This has two newlines.\n\n"
    )
---
test: Literal combinations
todo: true
yaml: |
   empty: |

   literal: |
    The \ ' " characters may be
    freely used. Leading white
       space is significant.

    Line breaks are significant.
    Thus this value contains one
    empty line and ends with a
    single line break, but does
    not start with one.

   is equal to: "The \\ ' \" characters may \
    be\nfreely used. Leading white\n   space \
    is significant.\n\nLine breaks are \
    significant.\nThus this value contains \
    one\nempty line and ends with a\nsingle \
    line break, but does\nnot start with one.\n"

   # Comments may follow a block
   # scalar value. They must be
   # less indented.

   # Modifiers may be combined in any order.
   indented and chomped: |2-
       This has no newline.

   also written as: |-2
       This has no newline.

   both are equal to: "  This has no newline."
php: |
   array(
     'empty' => '',
     'literal' => "The \\ ' \" characters may be\nfreely used. Leading white\n   space " +
       "is significant.\n\nLine breaks are significant.\nThus this value contains one\n" +
       "empty line and ends with a\nsingle line break, but does\nnot start with one.\n",
     'is equal to' => "The \\ ' \" characters may be\nfreely used. Leading white\n   space " +
       "is significant.\n\nLine breaks are significant.\nThus this value contains one\n" +
       "empty line and ends with a\nsingle line break, but does\nnot start with one.\n",
     'indented and chomped' => '  This has no newline.',
     'also written as' => '  This has no newline.',
     'both are equal to' => '  This has no newline.'
   )
---
test: Folded combinations
todo: true
yaml: |
   empty: >

   one paragraph: >
    Line feeds are converted
    to spaces, so this value
    contains no line breaks
    except for the final one.

   multiple paragraphs: >2

     An empty line, either
     at the start or in
     the value:

     Is interpreted as a
     line break. Thus this
     value contains three
     line breaks.

   indented text: >
       This is a folded
       paragraph followed
       by a list:
        * first entry
        * second entry
       Followed by another
       folded paragraph,
       another list:

        * first entry

        * second entry

       And a final folded
       paragraph.

   above is equal to: |
       This is a folded paragraph followed by a list:
        * first entry
        * second entry
       Followed by another folded paragraph, another list:

        * first entry

        * second entry

       And a final folded paragraph.

   # Explicit comments may follow
   # but must be less indented.
php: |
   array(
     'empty' => '',
     'one paragraph' => 'Line feeds are converted to spaces, so this value'.
       " contains no line breaks except for the final one.\n",
     'multiple paragraphs' => "\nAn empty line, either at the start or in the value:\n".
       "Is interpreted as a line break. Thus this value contains three line breaks.\n",
     'indented text' => "This is a folded paragraph followed by a list:\n".
       " * first entry\n * second entry\nFollowed by another folded paragraph, ".
       "another list:\n\n * first entry\n\n * second entry\n\nAnd a final folded paragraph.\n",
     'above is equal to' => "This is a folded paragraph followed by a list:\n".
       " * first entry\n * second entry\nFollowed by another folded paragraph, ".
       "another list:\n\n * first entry\n\n * second entry\n\nAnd a final folded paragraph.\n"
   )
---
test: Single quotes
todo: true
yaml: |
   empty: ''
   second: '! : \ etc. can be used freely.'
   third: 'a single quote '' must be escaped.'
   span: 'this contains
         six spaces

         and one
         line break'
   is same as: "this contains six spaces\nand one line break"
php: |
   array(
     'empty' => '',
     'second' => '! : \\ etc. can be used freely.',
     'third' => "a single quote ' must be escaped.",
     'span' => "this contains six spaces\nand one line break",
     'is same as' => "this contains six spaces\nand one line break"
   )
---
test: Double quotes
todo: true
yaml: |
   empty: ""
   second: "! : etc. can be used freely."
   third: "a \" or a \\ must be escaped."
   fourth: "this value ends with an LF.\n"
   span: "this contains
     four  \
         spaces"
   is equal to: "this contains four  spaces"
php: |
   array(
     'empty' => '',
     'second' => '! : etc. can be used freely.',
     'third' => 'a " or a \\ must be escaped.',
     'fourth' => "this value ends with an LF.\n",
     'span' => "this contains four  spaces",
     'is equal to' => "this contains four  spaces"
   )
---
test: Unquoted strings
todo: true
yaml: |
   first: There is no unquoted empty string.

   second: 12          ## This is an integer.

   third: !str 12      ## This is a string.

   span: this contains
         six spaces

         and one
         line break

   indicators: this has no comments.
               #:foo and bar# are
               both text.

   flow: [ can span
              lines, # comment
              like
              this ]

   note: { one-line keys: but multi-line values }

php: |
   array(
     'first' => 'There is no unquoted empty string.',
     'second' => 12,
     'third' => '12',
     'span' => "this contains six spaces\nand one line break",
     'indicators' => "this has no comments. #:foo and bar# are both text.",
     'flow' => [ 'can span lines', 'like this' ],
     'note' => { 'one-line keys' => 'but multi-line values' }
   )
---
test: Spanning sequences
todo: true
yaml: |
   # The following are equal seqs
   # with different identities.
   flow: [ one, two ]
   spanning: [ one,
        two ]
   block:
     - one
     - two
php: |
   array(
     'flow' => [ 'one', 'two' ],
     'spanning' => [ 'one', 'two' ],
     'block' => [ 'one', 'two' ]
   )
---
test: Flow mappings
yaml: |
   # The following are equal maps
   # with different identities.
   flow: { one: 1, two: 2 }
   block:
       one: 1
       two: 2
php: |
   array(
     'flow' => array( 'one' => 1, 'two' => 2 ),
     'block' => array( 'one' => 1, 'two' => 2 )
   )
---
test: Representations of 12
todo: true
yaml: |
   - 12 # An integer
   # The following scalars
   # are loaded to the
   # string value '1' '2'.
   - !str 12
   - '12'
   - "12"
   - "\
     1\
     2\
     "
   # Strings containing paths and regexps can be unquoted:
   - /foo/bar
   - d:/foo/bar
   - foo/bar
   - /a.*b/
php: |
   array( 12, '12', '12', '12', '12', '/foo/bar', 'd:/foo/bar', 'foo/bar', '/a.*b/' )
---
test: "Null"
todo: true
yaml: |
   canonical: ~

   english: null

   # This sequence has five
   # entries, two with values.
   sparse:
     - ~
     - 2nd entry
     - Null
     - 4th entry
     -

   four: This mapping has five keys,
         only two with values.

php: |
   array (
     'canonical' => null,
     'english' => null,
     'sparse' => array( null, '2nd entry', null, '4th entry', null ]),
     'four' => 'This mapping has five keys, only two with values.'
   )
---
test: Omap
todo: true
yaml: |
   # Explicitly typed dictionary.
   Bestiary: !omap
     - aardvark: African pig-like ant eater. Ugly.
     - anteater: South-American ant eater. Two species.
     - anaconda: South-American constrictor snake. Scary.
     # Etc.
ruby: |
   {
     'Bestiary' => YAML::Omap[
       'aardvark', 'African pig-like ant eater. Ugly.',
       'anteater', 'South-American ant eater. Two species.',
       'anaconda', 'South-American constrictor snake. Scary.'
     ]
   }

---
test: Pairs
todo: true
yaml: |
  # Explicitly typed pairs.
  tasks: !pairs
    - meeting: with team.
    - meeting: with boss.
    - break: lunch.
    - meeting: with client.
ruby: |
  {
    'tasks' => YAML::Pairs[
      'meeting', 'with team.',
      'meeting', 'with boss.',
      'break', 'lunch.',
      'meeting', 'with client.'
    ]
  }

---
test: Set
todo: true
yaml: |
  # Explicitly typed set.
  baseball players: !set
    Mark McGwire:
    Sammy Sosa:
    Ken Griffey:
ruby: |
  {
    'baseball players' => YAML::Set[
      'Mark McGwire', nil,
      'Sammy Sosa', nil,
      'Ken Griffey', nil
    ]
  }

---
test: Boolean
yaml: |
   false: used as key
   logical:  true
   answer: false
php: |
   array(
     false => 'used as key',
     'logical' => true,
     'answer' => false
   )
---
test: Integer
yaml: |
   canonical: 12345
   decimal: +12,345
   octal: 014
   hexadecimal: 0xC
php: |
   array(
     'canonical' => 12345,
     'decimal' => 12345.0,
     'octal' => 12,
     'hexadecimal' => 12
   )
---
test: Float
yaml: |
   canonical: 1.23015e+3
   exponential: 12.3015e+02
   fixed: 1,230.15
   negative infinity: -.inf
   not a number: .NaN
php: |
  array(
    'canonical' => 1230.15,
    'exponential' => 1230.15,
    'fixed' => 1230.15,
    'negative infinity' => log(0),
    'not a number' => -log(0)
  )
---
test: Timestamp
todo: true
yaml: |
   canonical:       2001-12-15T02:59:43.1Z
   valid iso8601:   2001-12-14t21:59:43.10-05:00
   space separated: 2001-12-14 21:59:43.10 -05:00
   date (noon UTC): 2002-12-14
ruby: |
   array(
     'canonical' => YAML::mktime( 2001, 12, 15, 2, 59, 43, 0.10 ),
     'valid iso8601' => YAML::mktime( 2001, 12, 14, 21, 59, 43, 0.10, "-05:00" ),
     'space separated' => YAML::mktime( 2001, 12, 14, 21, 59, 43, 0.10, "-05:00" ),
     'date (noon UTC)' => Date.new( 2002, 12, 14 )
   )
---
test: Binary
todo: true
yaml: |
   canonical: !binary "\
    R0lGODlhDAAMAIQAAP//9/X17unp5WZmZgAAAOfn515eXvPz7Y6OjuDg4J+fn5\
    OTk6enp56enmlpaWNjY6Ojo4SEhP/++f/++f/++f/++f/++f/++f/++f/++f/+\
    +f/++f/++f/++f/++f/++SH+Dk1hZGUgd2l0aCBHSU1QACwAAAAADAAMAAAFLC\
    AgjoEwnuNAFOhpEMTRiggcz4BNJHrv/zCFcLiwMWYNG84BwwEeECcgggoBADs="
   base64: !binary |
    R0lGODlhDAAMAIQAAP//9/X17unp5WZmZgAAAOfn515eXvPz7Y6OjuDg4J+fn5
    OTk6enp56enmlpaWNjY6Ojo4SEhP/++f/++f/++f/++f/++f/++f/++f/++f/+
    +f/++f/++f/++f/++f/++SH+Dk1hZGUgd2l0aCBHSU1QACwAAAAADAAMAAAFLC
    AgjoEwnuNAFOhpEMTRiggcz4BNJHrv/zCFcLiwMWYNG84BwwEeECcgggoBADs=
   description: >
    The binary value above is a tiny arrow
    encoded as a gif image.
ruby-setup: |
   arrow_gif = "GIF89a\f\000\f\000\204\000\000\377\377\367\365\365\356\351\351\345fff\000\000\000\347\347\347^^^\363\363\355\216\216\216\340\340\340\237\237\237\223\223\223\247\247\247\236\236\236iiiccc\243\243\243\204\204\204\377\376\371\377\376\371\377\376\371\377\376\371\377\376\371\377\376\371\377\376\371\377\376\371\377\376\371\377\376\371\377\376\371\377\376\371\377\376\371\377\376\371!\376\016Made with GIMP\000,\000\000\000\000\f\000\f\000\000\005,  \216\2010\236\343@\024\350i\020\304\321\212\010\034\317\200M$z\357\3770\205p\270\2601f\r\e\316\001\303\001\036\020' \202\n\001\000;"
ruby: |
   {
     'canonical' => arrow_gif,
     'base64' => arrow_gif,
     'description' => "The binary value above is a tiny arrow encoded as a gif image.\n"
   }

---
test: Merge key
todo: true
yaml: |
  ---
  - &CENTER { x: 1, y: 2 }
  - &LEFT { x: 0, y: 2 }
  - &BIG { r: 10 }
  - &SMALL { r: 1 }

  # All the following maps are equal:

  - # Explicit keys
    x: 1
    y: 2
    r: 10
    label: center/big

  - # Merge one map
    << : *CENTER
    r: 10
    label: center/big

  - # Merge multiple maps
    << : [ *CENTER, *BIG ]
    label: center/big

  - # Override
    << : [ *BIG, *LEFT, *SMALL ]
    x: 1
    label: center/big

ruby-setup: |
  center = { 'x' => 1, 'y' => 2 }
  left = { 'x' => 0, 'y' => 2 }
  big = { 'r' => 10 }
  small = { 'r' => 1 }
  node1 = { 'x' => 1, 'y' => 2, 'r' => 10, 'label' => 'center/big' }
  node2 = center.dup
  node2.update( { 'r' => 10, 'label' => 'center/big' } )
  node3 = big.dup
  node3.update( center )
  node3.update( { 'label' => 'center/big' } )
  node4 = small.dup
  node4.update( left )
  node4.update( big )
  node4.update( { 'x' => 1, 'label' => 'center/big' } )

ruby: |
  [
    center, left, big, small, node1, node2, node3, node4
  ]

---
test: Default key
todo: true
yaml: |
   ---     # Old schema
   link with:
     - library1.dll
     - library2.dll
   ---     # New schema
   link with:
     - = : library1.dll
       version: 1.2
     - = : library2.dll
       version: 2.3
ruby: |
   y = YAML::Stream.new
   y.add( { 'link with' => [ 'library1.dll', 'library2.dll' ] } )
   obj_h = Hash[ 'version' => 1.2 ]
   obj_h.default = 'library1.dll'
   obj_h2 = Hash[ 'version' => 2.3 ]
   obj_h2.default = 'library2.dll'
   y.add( { 'link with' => [ obj_h, obj_h2 ] } )
documents: 2

---
test: Special keys
todo: true
yaml: |
   "!": These three keys
   "&": had to be quoted
   "=": and are normal strings.
   # NOTE: the following node should NOT be serialized this way.
   encoded node :
    !special '!' : '!type'
    !special|canonical '&' : 12
    = : value
   # The proper way to serialize the above node is as follows:
   node : !!type &12 value
ruby: |
   { '!' => 'These three keys', '&' => 'had to be quoted',
     '=' => 'and are normal strings.',
     'encoded node' => YAML::PrivateType.new( 'type', 'value' ),
     'node' => YAML::PrivateType.new( 'type', 'value' ) }
PKϤ$ZB4����(yaml/Tests/Fixtures/YtsTypeTransfers.ymlnu�[���--- %YAML:1.0
test: Strings
brief: >
    Any group of characters beginning with an
    alphabetic or numeric character is a string,
    unless it belongs to one of the groups below
    (such as an Integer or Time).
yaml: |
    String
php: |
    'String'
---
test: String characters
brief: >
    A string can contain any alphabetic or
    numeric character, along with many
    punctuation characters, including the
    period, dash, space, quotes, exclamation, and
    question mark.
yaml: |
    - What's Yaml?
    - It's for writing data structures in plain text.
    - And?
    - And what? That's not good enough for you?
    - No, I mean, "And what about Yaml?"
    - Oh, oh yeah. Uh.. Yaml for Ruby.
php: |
    array(
      "What's Yaml?",
      "It's for writing data structures in plain text.",
      "And?",
      "And what? That's not good enough for you?",
      "No, I mean, \"And what about Yaml?\"",
      "Oh, oh yeah. Uh.. Yaml for Ruby."
    )
---
test: Indicators in Strings
brief: >
    Be careful using indicators in strings.  In particular,
    the comma, colon, and pound sign must be used carefully.
yaml: |
    the colon followed by space is an indicator: but is a string:right here
    same for the pound sign: here we have it#in a string
    the comma can, honestly, be used in most cases: [ but not in, inline collections ]
php: |
    array(
      'the colon followed by space is an indicator' => 'but is a string:right here',
      'same for the pound sign' => 'here we have it#in a string',
      'the comma can, honestly, be used in most cases' => array('but not in', 'inline collections')
    )
---
test: Forcing Strings
brief: >
    Any YAML type can be forced into a string using the
    explicit !str method.
yaml: |
    date string: !str 2001-08-01
    number string: !str 192
php: |
    array(
      'date string' => '2001-08-01',
      'number string' => '192'
    )
---
test: Single-quoted Strings
brief: >
    You can also enclose your strings within single quotes,
    which allows use of slashes, colons, and other indicators
    freely.  Inside single quotes, you can represent a single
    quote in your string by using two single quotes next to
    each other.
yaml: |
    all my favorite symbols: '#:!/%.)'
    a few i hate: '&(*'
    why do i hate them?: 'it''s very hard to explain'
    entities: '&pound; me'
php: |
    array(
      'all my favorite symbols' => '#:!/%.)',
      'a few i hate' => '&(*',
      'why do i hate them?' => 'it\'s very hard to explain',
      'entities' => '&pound; me'
    )
---
test: Double-quoted Strings
brief: >
    Enclosing strings in double quotes allows you
    to use escapings to represent ASCII and
    Unicode characters.
yaml: |
    i know where i want my line breaks: "one here\nand another here\n"
php: |
    array(
      'i know where i want my line breaks' => "one here\nand another here\n"
    )
---
test: Multi-line Quoted Strings
todo: true
brief: >
    Both single- and double-quoted strings may be
    carried on to new lines in your YAML document.
    They must be indented a step and indentation
    is interpreted as a single space.
yaml: |
    i want a long string: "so i'm going to
      let it go on and on to other lines
      until i end it with a quote."
php: |
    array('i want a long string' => "so i'm going to ".
         "let it go on and on to other lines ".
         "until i end it with a quote."
    )

---
test: Plain scalars
todo: true
brief: >
    Unquoted strings may also span multiple lines, if they
    are free of YAML space indicators and indented.
yaml: |
    - My little toe is broken in two places;
    - I'm crazy to have skied this way;
    - I'm not the craziest he's seen, since there was always the German guy
      who skied for 3 hours on a broken shin bone (just below the kneecap);
    - Nevertheless, second place is respectable, and he doesn't
      recommend going for the record;
    - He's going to put my foot in plaster for a month;
    - This would impair my skiing ability somewhat for the
      duration, as can be imagined.
php: |
    array(
      "My little toe is broken in two places;",
      "I'm crazy to have skied this way;",
      "I'm not the craziest he's seen, since there was always ".
         "the German guy who skied for 3 hours on a broken shin ".
         "bone (just below the kneecap);",
      "Nevertheless, second place is respectable, and he doesn't ".
         "recommend going for the record;",
      "He's going to put my foot in plaster for a month;",
      "This would impair my skiing ability somewhat for the duration, ".
         "as can be imagined."
    )
---
test: 'Null'
brief: >
    You can use the tilde '~' character for a null value.
yaml: |
    name: Mr. Show
    hosted by: Bob and David
    date of next season: ~
php: |
    array(
      'name' => 'Mr. Show',
      'hosted by' => 'Bob and David',
      'date of next season' => null
    )
---
test: Boolean
brief: >
    You can use 'true' and 'false' for Boolean values.
yaml: |
    Is Gus a Liar?: true
    Do I rely on Gus for Sustenance?: false
php: |
    array(
      'Is Gus a Liar?' => true,
      'Do I rely on Gus for Sustenance?' => false
    )
---
test: Integers
dump_skip: true
brief: >
    An integer is a series of numbers, optionally
    starting with a positive or negative sign.  Integers
    may also contain commas for readability.
yaml: |
    zero: 0
    simple: 12
    one-thousand: 1,000
    negative one-thousand: -1,000
php: |
    array(
      'zero' => 0,
      'simple' => 12,
      'one-thousand' => 1000.0,
      'negative one-thousand' => -1000.0
    )
---
test: Integers as Map Keys
brief: >
    An integer can be used a dictionary key.
yaml: |
    1: one
    2: two
    3: three
php: |
    array(
        1 => 'one',
        2 => 'two',
        3 => 'three'
    )
---
test: Floats
dump_skip: true
brief: >
     Floats are represented by numbers with decimals,
     allowing for scientific notation, as well as
     positive and negative infinity and "not a number."
yaml: |
     a simple float: 2.00
     larger float: 1,000.09
     scientific notation: 1.00009e+3
php: |
     array(
       'a simple float' => 2.0,
       'larger float' => 1000.09,
       'scientific notation' => 1000.09
     )
---
test: Time
todo: true
brief: >
    You can represent timestamps by using
    ISO8601 format, or a variation which
    allows spaces between the date, time and
    time zone.
yaml: |
    iso8601: 2001-12-14t21:59:43.10-05:00
    space separated: 2001-12-14 21:59:43.10 -05:00
php: |
    array(
      'iso8601' => mktime( 2001, 12, 14, 21, 59, 43, 0.10, "-05:00" ),
      'space separated' => mktime( 2001, 12, 14, 21, 59, 43, 0.10, "-05:00" )
    )
---
test: Date
todo: true
brief: >
    A date can be represented by its year,
    month and day in ISO8601 order.
yaml: |
    1976-07-31
php: |
    date( 1976, 7, 31 )
PKϤ$Z�c����,yaml/Tests/Fixtures/YtsDocumentSeparator.ymlnu�[���--- %YAML:1.0
test: Trailing Document Separator
todo: true
brief: >
    You can separate YAML documents
    with a string of three dashes.
yaml: |
    - foo: 1
      bar: 2
    ---
    more: stuff
python: |
    [
        [ { 'foo': 1, 'bar': 2 } ],
        { 'more': 'stuff' }
    ]
ruby: |
    [ { 'foo' => 1, 'bar' => 2 } ]

---
test: Leading Document Separator
todo: true
brief: >
    You can explicitly give an opening
    document separator to your YAML stream.
yaml: |
    ---
    - foo: 1
      bar: 2
    ---
    more: stuff
python: |
    [
        [ {'foo': 1, 'bar': 2}],
        {'more': 'stuff'}
    ]
ruby: |
    [ { 'foo' => 1, 'bar' => 2 } ]

---
test: YAML Header
todo: true
brief: >
    The opening separator can contain directives
    to the YAML parser, such as the version
    number.
yaml: |
    --- %YAML:1.0
    foo: 1
    bar: 2
php: |
    array('foo' => 1, 'bar' => 2)
documents: 1

---
test: Red Herring Document Separator
brief: >
    Separators included in blocks or strings
    are treated as blocks or strings, as the
    document separator should have no indentation
    preceding it.
yaml: |
    foo: |
        ---
php: |
    array('foo' => "---\n")

---
test: Multiple Document Separators in Block
brief: >
    This technique allows you to embed other YAML
    documents within literal blocks.
yaml: |
    foo: |
        ---
        foo: bar
        ---
        yo: baz
    bar: |
        fooness
php: |
    array(
       'foo' => "---\nfoo: bar\n---\nyo: baz\n",
       'bar' => "fooness\n"
    )
PKϤ$ZO�_}��"yaml/Tests/Fixtures/sfComments.ymlnu�[���--- %YAML:1.0
test: Comments at the end of a line
brief: >
    Comments at the end of a line
yaml: |
    ex1: "foo # bar"
    ex2: "foo # bar" # comment
    ex3: 'foo # bar' # comment
    ex4: foo # comment
    ex5: foo	#	comment with tab before  
    ex6: foo#foo # comment here
    ex7: foo 	# ignore me # and me
php: |
    array('ex1' => 'foo # bar', 'ex2' => 'foo # bar', 'ex3' => 'foo # bar', 'ex4' => 'foo', 'ex5' => 'foo', 'ex6' => 'foo#foo', 'ex7' => 'foo')
---
test: Comments in the middle
brief: >
  Comments in the middle
yaml: |
    foo:
    # some comment
    # some comment
      bar: foo
    # some comment
    # some comment
php: |
    array('foo' => array('bar' => 'foo'))
---
test: Comments on a hash line
brief: >
  Comments on a hash line
yaml: |
    foo:   # a comment
      foo: bar # a comment
php: |
    array('foo' => array('foo' => 'bar'))
---
test: 'Value starting with a #'
brief: >
  'Value starting with a #'
yaml: |
    foo:   '#bar'
php: |
    array('foo' => '#bar')
---
test: Document starting with a comment and a separator
brief: >
  Commenting before document start is allowed
yaml: |
    # document comment
    ---
    foo: bar # a comment
php: |
    array('foo' => 'bar')
---
test: Comment containing a colon on a hash line
brief: >
    Comment containing a colon on a scalar line
yaml: 'foo # comment: this is also part of the comment'
php: |
    'foo'
---
test: 'Hash key containing a #'
brief: >
    'Hash key containing a #'
yaml: 'foo#bar: baz'
php: |
    array('foo#bar' => 'baz')
---
test: 'Hash key ending with a space and a #'
brief: >
    'Hash key ending with a space and a #'
yaml: |
    'foo #': baz
php: |
    array('foo #' => 'baz')
PKϤ$ZZ��"yaml/Tests/Fixtures/embededPhp.ymlnu�[���value: <?php echo 1 + 2 + 3 ?>
PKϤ$ZZ{k�XX*yaml/Tests/Fixtures/YtsFlowCollections.ymlnu�[���---
test: Simple Inline Array
brief: >
    Sequences can be contained on a
    single line, using the inline syntax.
    Separate each entry with commas and
    enclose in square brackets.
yaml: |
    seq: [ a, b, c ]
php: |
    array('seq' => array('a', 'b', 'c'))
---
test: Simple Inline Hash
brief: >
    Mapping can also be contained on
    a single line, using the inline
    syntax.  Each key-value pair is
    separated by a colon, with a comma
    between each entry in the mapping.
    Enclose with curly braces.
yaml: |
    hash: { name: Steve, foo: bar }
php: |
    array('hash' => array('name' => 'Steve', 'foo' => 'bar'))
---
test: Multi-line Inline Collections
todo: true
brief: >
    Both inline sequences and inline mappings
    can span multiple lines, provided that you
    indent the additional lines.
yaml: |
    languages: [ Ruby,
                 Perl,
                 Python ]
    websites: { YAML: yaml.org,
                Ruby: ruby-lang.org,
                Python: python.org,
                Perl: use.perl.org }
php: |
    array(
      'languages' => array('Ruby', 'Perl', 'Python'),
      'websites' => array(
        'YAML' => 'yaml.org',
        'Ruby' => 'ruby-lang.org',
        'Python' => 'python.org',
        'Perl' => 'use.perl.org'
      )
    )
---
test: Commas in Values (not in the spec!)
todo: true
brief: >
    List items in collections are delimited by commas, but
    there must be a space after each comma.  This allows you
    to add numbers without quoting.
yaml: |
    attendances: [ 45,123, 70,000, 17,222 ]
php: |
    array('attendances' => array(45123, 70000, 17222))
PKϤ$Zz����"yaml/Tests/Fixtures/sfMergeKey.ymlnu�[���--- %YAML:1.0
test: Simple In Place Substitution
brief: >
    If you want to reuse an entire alias, only overwriting what is different
    you can use a << in place substitution. This is not part of the official
    YAML spec, but a widely implemented extension. See the following URL for
    details: http://yaml.org/type/merge.html
yaml: |
    foo: &foo
        a: Steve
        b: Clark
        c: Brian
    bar:
        a: before
        d: other
        <<: *foo
        b: new
        x: Oren
        c:
            foo: bar
            foo: ignore
            bar: foo
    duplicate:
        foo: bar
        foo: ignore
    foo2: &foo2
        a: Ballmer
    ding: &dong [ fi, fei, fo, fam]
    check:
        <<:
            - *foo
            - *dong
        isit: tested
    head:
        <<: [ *foo , *dong , *foo2 ]
    taz: &taz
        a: Steve
        w:
            p: 1234
    nested:
        <<: *taz
        d: Doug
        w: &nestedref
            p: 12345
        z:
            <<: *nestedref
php: |
    array(
        'foo' => array('a' => 'Steve', 'b' => 'Clark', 'c' => 'Brian'),
        'bar' => array('a' => 'before', 'd' => 'other', 'b' => 'new', 'c' => array('foo' => 'bar', 'bar' => 'foo'), 'x' => 'Oren'),
        'duplicate' => array('foo' => 'bar'),
        'foo2' => array('a' => 'Ballmer'),
        'ding' => array('fi', 'fei', 'fo', 'fam'),
        'check' => array('a' => 'Steve', 'b' => 'Clark', 'c' => 'Brian', 'fi', 'fei', 'fo', 'fam', 'isit' => 'tested'),
        'head' => array('a' => 'Steve', 'b' => 'Clark', 'c' => 'Brian', 'fi', 'fei', 'fo', 'fam'),
        'taz' => array('a' => 'Steve', 'w' => array('p' => 1234)),
        'nested' => array('a' => 'Steve', 'w' => array('p' => 12345), 'd' => 'Doug', 'z' => array('p' => 12345))
    )
PKϤ$Z*��,��)yaml/Tests/Fixtures/escapedCharacters.ymlnu�[���test: outside double quotes
yaml: |
    \0 \ \a \b \n
php: |
    "\\0 \\ \\a \\b \\n"
---
test: null
yaml: |
    "\0"
php: |
    "\x00"
---
test: bell
yaml: |
    "\a"
php: |
    "\x07"
---
test: backspace
yaml: |
    "\b"
php: |
    "\x08"
---
test: horizontal tab (1)
yaml: |
    "\t"
php: |
    "\x09"
---
test: horizontal tab (2)
yaml: |
    "\	"
php: |
    "\x09"
---
test: line feed
yaml: |
    "\n"
php: |
    "\x0a"
---
test: vertical tab
yaml: |
    "\v"
php: |
    "\x0b"
---
test: form feed
yaml: |
    "\f"
php: |
    "\x0c"
---
test: carriage return
yaml: |
    "\r"
php: |
    "\x0d"
---
test: escape
yaml: |
    "\e"
php: |
   "\x1b"
---
test: space
yaml: |
    "\ "
php: |
    "\x20"
---
test: slash
yaml: |
    "\/"
php: |
    "\x2f"
---
test: backslash
yaml: |
    "\\"
php: |
    "\\"
---
test: Unicode next line
yaml: |
    "\N"
php: |
    "\xc2\x85"
---
test: Unicode non-breaking space
yaml: |
    "\_"
php: |
    "\xc2\xa0"
---
test: Unicode line separator
yaml: |
    "\L"
php: |
    "\xe2\x80\xa8"
---
test: Unicode paragraph separator
yaml: |
    "\P"
php: |
    "\xe2\x80\xa9"
---
test: Escaped 8-bit Unicode
yaml: |
    "\x42"
php: |
    "B"
---
test: Escaped 16-bit Unicode
yaml: |
    "\u20ac"
php: |
    "\xe2\x82\xac"
---
test: Escaped 32-bit Unicode
yaml: |
    "\U00000043"
php: |
    "C"
---
test: Example 5.13 Escaped Characters
note: |
    Currently throws an error parsing first line. Maybe Symfony Yaml doesn't support
    continuation of string across multiple lines? Keeping test here but disabled.
todo: true
yaml: |
    "Fun with \\
    \" \a \b \e \f \
    \n \r \t \v \0 \
    \  \_ \N \L \P \
    \x41 \u0041 \U00000041"
php: |
    "Fun with \x5C\n\x22 \x07 \x08 \x1B \x0C\n\x0A \x0D \x09 \x0B \x00\n\x20 \xA0 \x85 \xe2\x80\xa8 \xe2\x80\xa9\nA A A"
---
test: Double quotes with a line feed
yaml: |
   { double: "some value\n \"some quoted string\" and 'some single quotes one'" }
php: |
    array(
        'double' => "some value\n \"some quoted string\" and 'some single quotes one'"
    )
---
test: Backslashes
yaml: |
    { single: 'foo\Var', no-quotes: foo\Var, double: "foo\\Var" }
php: |
    array(
        'single' => 'foo\Var', 'no-quotes' => 'foo\Var', 'double' => 'foo\Var'
    )
PKϤ$Zګغzz(yaml/Tests/Fixtures/YtsFoldedScalars.ymlnu�[���--- %YAML:1.0
test: Single ending newline
brief: >
    A pipe character, followed by an indented
    block of text is treated as a literal
    block, in which newlines are preserved
    throughout the block, including the final
    newline.
yaml: |
    ---
    this: |
        Foo
        Bar
php: |
    array('this' => "Foo\nBar\n")
---
test: The '+' indicator
brief: >
    The '+' indicator says to keep newlines at the end of text
    blocks.
yaml: |
    normal: |
      extra new lines not kept

    preserving: |+
      extra new lines are kept


    dummy: value
php: |
    array(
        'normal' => "extra new lines not kept\n",
        'preserving' => "extra new lines are kept\n\n\n",
        'dummy' => 'value'
    )
---
test: Three trailing newlines in literals
brief: >
    To give you more control over how space
    is preserved in text blocks, YAML has
    the keep '+' and chomp '-' indicators.
    The keep indicator will preserve all
    ending newlines, while the chomp indicator
    will strip all ending newlines.
yaml: |
    clipped: |
        This has one newline.



    same as "clipped" above: "This has one newline.\n"

    stripped: |-
        This has no newline.



    same as "stripped" above: "This has no newline."

    kept: |+
        This has four newlines.



    same as "kept" above: "This has four newlines.\n\n\n\n"
php: |
    array(
      'clipped' => "This has one newline.\n",
      'same as "clipped" above' => "This has one newline.\n",
      'stripped' => 'This has no newline.',
      'same as "stripped" above' => 'This has no newline.',
      'kept' => "This has four newlines.\n\n\n\n",
      'same as "kept" above' => "This has four newlines.\n\n\n\n"
    )
---
test: Extra trailing newlines with spaces
todo: true
brief: >
    Normally, only a single newline is kept
    from the end of a literal block, unless the
    keep '+' character is used in combination
    with the pipe.  The following example
    will preserve all ending whitespace
    since the last line of both literal blocks
    contains spaces which extend past the indentation
    level.
yaml: |
    ---
    this: |
        Foo


    kept: |+
        Foo


php: |
    array('this' => "Foo\n\n  \n",
      'kept' => "Foo\n\n  \n" )

---
test: Folded Block in a Sequence
brief: >
    A greater-then character, followed by an indented
    block of text is treated as a folded block, in
    which lines of text separated by a single newline
    are concatenated as a single line.
yaml: |
    ---
    - apple
    - banana
    - >
        can't you see
        the beauty of yaml?
        hmm
    - dog
php: |
    array(
        'apple',
        'banana',
        "can't you see the beauty of yaml? hmm\n",
        'dog'
    )
---
test: Folded Block as a Mapping Value
brief: >
    Both literal and folded blocks can be
    used in collections, as values in a
    sequence or a mapping.
yaml: |
    ---
    quote: >
        Mark McGwire's
        year was crippled
        by a knee injury.
    source: espn
php: |
    array(
        'quote' => "Mark McGwire's year was crippled by a knee injury.\n",
        'source' => 'espn'
    )
---
test: Three trailing newlines in folded blocks
brief: >
    The keep and chomp indicators can also
    be applied to folded blocks.
yaml: |
    clipped: >
        This has one newline.



    same as "clipped" above: "This has one newline.\n"

    stripped: >-
        This has no newline.



    same as "stripped" above: "This has no newline."

    kept: >+
        This has four newlines.



    same as "kept" above: "This has four newlines.\n\n\n\n"
php: |
    array(
      'clipped' => "This has one newline.\n",
      'same as "clipped" above' => "This has one newline.\n",
      'stripped' => 'This has no newline.',
      'same as "stripped" above' => 'This has no newline.',
      'kept' => "This has four newlines.\n\n\n\n",
      'same as "kept" above' => "This has four newlines.\n\n\n\n"
    )
PKϤ$Z��UU!yaml/Tests/Fixtures/sfCompact.ymlnu�[���--- %YAML:1.0
test: Compact notation
brief: |
    Compact notation for sets of mappings with single element
yaml: |
  ---
  # products purchased
  - item    : Super Hoop
  - item    : Basketball
    quantity: 1
  - item:
      name: Big Shoes
      nick: Biggies
    quantity: 1
php: |
  array (
    array (
      'item' => 'Super Hoop',
    ),
    array (
      'item' => 'Basketball',
      'quantity' => 1,
    ),
    array (
      'item' => array(
        'name' => 'Big Shoes',
        'nick' => 'Biggies'
      ),
      'quantity' => 1
    )
  )
---
test: Compact notation combined with inline notation
brief: |
    Combinations of compact and inline notation are allowed
yaml: |
  ---
  items:
    - { item: Super Hoop, quantity: 1 }
    - [ Basketball, Big Shoes ]
php: |
  array (
    'items' => array (
      array (
        'item' => 'Super Hoop',
        'quantity' => 1,
      ),
      array (
        'Basketball',
        'Big Shoes'
      )
    )
  )
--- %YAML:1.0
test: Compact notation
brief: |
    Compact notation for sets of mappings with single element
yaml: |
  ---
  # products purchased
  - item    : Super Hoop
  - item    : Basketball
    quantity: 1
  - item:
      name: Big Shoes
      nick: Biggies
    quantity: 1
php: |
  array (
    array (
      'item' => 'Super Hoop',
    ),
    array (
      'item' => 'Basketball',
      'quantity' => 1,
    ),
    array (
      'item' => array(
        'name' => 'Big Shoes',
        'nick' => 'Biggies'
      ),
      'quantity' => 1
    )
  )
---
test: Compact notation combined with inline notation
brief: |
    Combinations of compact and inline notation are allowed
yaml: |
  ---
  items:
    - { item: Super Hoop, quantity: 1 }
    - [ Basketball, Big Shoes ]
php: |
  array (
    'items' => array (
      array (
        'item' => 'Super Hoop',
        'quantity' => 1,
      ),
      array (
        'Basketball',
        'Big Shoes'
      )
    )
  )
--- %YAML:1.0
test: Compact notation
brief: |
    Compact notation for sets of mappings with single element
yaml: |
  ---
  # products purchased
  - item    : Super Hoop
  - item    : Basketball
    quantity: 1
  - item:
      name: Big Shoes
      nick: Biggies
    quantity: 1
php: |
  array (
    array (
      'item' => 'Super Hoop',
    ),
    array (
      'item' => 'Basketball',
      'quantity' => 1,
    ),
    array (
      'item' => array(
        'name' => 'Big Shoes',
        'nick' => 'Biggies'
      ),
      'quantity' => 1
    )
  )
---
test: Compact notation combined with inline notation
brief: |
    Combinations of compact and inline notation are allowed
yaml: |
  ---
  items:
    - { item: Super Hoop, quantity: 1 }
    - [ Basketball, Big Shoes ]
php: |
  array (
    'items' => array (
      array (
        'item' => 'Super Hoop',
        'quantity' => 1,
      ),
      array (
        'Basketball',
        'Big Shoes'
      )
    )
  )
PKϤ$Z//L¹	�	yaml/Tests/Fixtures/sfTests.ymlnu�[���--- %YAML:1.0
test: Multiple quoted string on one line
brief: >
    Multiple quoted string on one line
yaml: |
    stripped_title: { name: "foo bar", help: "bar foo" }
php: |
    array('stripped_title' => array('name' => 'foo bar', 'help' => 'bar foo'))
---
test: Empty sequence
yaml: |
    foo: [ ]
php: |
    array('foo' => array())
---
test: Empty value
yaml: |
    foo:
php: |
    array('foo' => null)
---
test: Inline string parsing
brief: >
    Inline string parsing
yaml: |
    test: ['complex: string', 'another [string]']
php: |
    array('test' => array('complex: string', 'another [string]'))
---
test: Boolean
brief: >
    Boolean
yaml: |
    - false
    - true
    - null
    - ~
    - 'false'
    - 'true'
    - 'null'
    - '~'
php: |
    array(
      false,
      true,
      null,
      null,
      'false',
      'true',
      'null',
      '~',
    )
---
test: Empty lines in literal blocks
brief: >
  Empty lines in literal blocks
yaml: |
  foo:
    bar: |
      foo


        
      bar
php: |
  array('foo' => array('bar' => "foo\n\n\n  \nbar\n"))
---
test: Empty lines in folded blocks
brief: >
  Empty lines in folded blocks
yaml: |
  foo:
    bar: >

      foo

      
      bar
php: |
  array('foo' => array('bar' => "\nfoo\n\nbar\n"))
---
test: IP addresses
brief: >
  IP addresses
yaml: |
  foo: 10.0.0.2
php: |
  array('foo' => '10.0.0.2')
---
test: A sequence with an embedded mapping
brief: >
  A sequence with an embedded mapping
yaml: |
  - foo
  - bar: { bar: foo }
php: |
  array('foo', array('bar' => array('bar' => 'foo')))
---
test: A sequence with an unordered array
brief: >
  A sequence with an unordered array
yaml: |
  1: foo
  0: bar
php: |
  array(1 => 'foo', 0 => 'bar')
---
test: Octal
brief: as in spec example 2.19, octal value is converted
yaml: |
  foo: 0123
php: |
  array('foo' => 83)
---
test: Octal strings
brief: Octal notation in a string must remain a string
yaml: |
  foo: "0123"
php: |
  array('foo' => '0123')
---
test: Octal strings
brief: Octal notation in a string must remain a string
yaml: |
  foo: '0123'
php: |
  array('foo' => '0123')
---
test: Octal strings
brief: Octal notation in a string must remain a string
yaml: |
  foo: |
    0123
php: |
  array('foo' => "0123\n")
---
test: Document as a simple hash
brief: Document as a simple hash
yaml: |
  { foo: bar }
php: |
  array('foo' => 'bar')
---
test: Document as a simple array
brief: Document as a simple array
yaml: |
  [ foo, bar ]
php: |
  array('foo', 'bar')
PKϤ$Z���88yaml/Tests/Fixtures/index.ymlnu�[���- escapedCharacters
- sfComments
- sfCompact
- sfTests
- sfObjects
- sfMergeKey
- sfQuotes
- YtsAnchorAlias
- YtsBasicTests
- YtsBlockMapping
- YtsDocumentSeparator
- YtsErrorTests
- YtsFlowCollections
- YtsFoldedScalars
- YtsNullsAndEmpties
- YtsSpecificationExamples
- YtsTypeTransfers
- unindentedCollections
PKϤ$Z+=��� yaml/Tests/Fixtures/sfQuotes.ymlnu�[���--- %YAML:1.0
test: Some characters at the beginning of a string must be escaped
brief: >
    Some characters at the beginning of a string must be escaped
yaml: |
    foo: '| bar'
php: |
    array('foo' => '| bar')
---
test: A key can be a quoted string
brief: >
  A key can be a quoted string
yaml: |
    "foo1": bar
    'foo2': bar
    "foo \" bar": bar
    'foo '' bar': bar
    'foo3: ': bar
    "foo4: ": bar
    foo5: { "foo \" bar: ": bar, 'foo '' bar: ': bar }
php: |
    array(
      'foo1' => 'bar',
      'foo2' => 'bar',
      'foo " bar' => 'bar',
      'foo \' bar' => 'bar',
      'foo3: ' => 'bar',
      'foo4: ' => 'bar',
      'foo5' => array(
        'foo " bar: ' => 'bar',
        'foo \' bar: ' => 'bar',
      ),
    )
PKϤ$Z�+/N-yaml/Tests/Fixtures/unindentedCollections.ymlnu�[���--- %YAML:1.0
test: Unindented collection
brief: >
    Unindented collection
yaml: |
    collection:
    - item1
    - item2
    - item3
php: |
    array('collection' => array('item1', 'item2', 'item3'))
---
test: Nested unindented collection (two levels)
brief: >
    Nested unindented collection
yaml: |
    collection:
        key:
        - a
        - b
        - c
php: |
    array('collection' => array('key' => array('a', 'b', 'c')))
---
test: Nested unindented collection (three levels)
brief: >
    Nested unindented collection
yaml: |
    collection:
        key:
            subkey:
            - one
            - two
            - three
php: |
    array('collection' => array('key' => array('subkey' => array('one', 'two', 'three'))))
---
test: Key/value after unindented collection (1)
brief: >
    Key/value after unindented collection (1)
yaml: |
    collection:
        key:
        - a
        - b
        - c
    foo: bar
php: |
    array('collection' => array('key' => array('a', 'b', 'c')), 'foo' => 'bar')
---
test: Key/value after unindented collection (at the same level)
brief: >
    Key/value after unindented collection
yaml: |
    collection:
        key:
        - a
        - b
        - c
        foo: bar
php: |
    array('collection' => array('key' => array('a', 'b', 'c'), 'foo' => 'bar'))
---
test: Shortcut Key after unindented collection
brief: >
    Key/value after unindented collection
yaml: |
    collection:
    - key: foo
      foo: bar
php: |
    array('collection' => array(array('key' => 'foo', 'foo' => 'bar')))
---
test: Shortcut Key after unindented collection with custom spaces
brief: >
    Key/value after unindented collection
yaml: |
    collection:
    -  key: foo
       foo: bar
php: |
    array('collection' => array(array('key' => 'foo', 'foo' => 'bar')))
PKϤ$Z�����'yaml/Tests/Fixtures/YtsBlockMapping.ymlnu�[���---
test: One Element Mapping
brief: |
    A mapping with one key/value pair
yaml: |
    foo: bar
php: |
    array('foo' => 'bar')
---
test: Multi Element Mapping
brief: |
    More than one key/value pair
yaml: |
    red: baron
    white: walls
    blue: berries
php: |
    array(
     'red' => 'baron',
     'white' => 'walls',
     'blue' => 'berries',
    )
---
test: Values aligned
brief: |
    Often times human editors of documents will align the values even
    though YAML emitters generally don't.
yaml: |
    red:   baron
    white: walls
    blue:  berries
php: |
    array(
     'red' => 'baron',
     'white' => 'walls',
     'blue' => 'berries',
    )
---
test: Colons aligned
brief: |
    Spaces can come before the ': ' key/value separator.
yaml: |
    red   : baron
    white : walls
    blue  : berries
php: |
    array(
     'red' => 'baron',
     'white' => 'walls',
     'blue' => 'berries',
    )
PKϤ$Z�>;���*yaml/Tests/Fixtures/YtsNullsAndEmpties.ymlnu�[���--- %YAML:1.0
test: Empty Sequence
brief: >
    You can represent the empty sequence
    with an empty inline sequence.
yaml: |
    empty: []
php: |
    array('empty' => array())
---
test: Empty Mapping
brief: >
    You can represent the empty mapping
    with an empty inline mapping.
yaml: |
    empty: {}
php: |
    array('empty' => array())
---
test: Empty Sequence as Entire Document
yaml: |
    []
php: |
    array()
---
test: Empty Mapping as Entire Document
yaml: |
    {}
php: |
    array()
---
test: Null as Document
yaml: |
    ~
php: |
    null
---
test: Empty String
brief: >
    You can represent an empty string
    with a pair of quotes.
yaml: |
    ''
php: |
    ''
PKϤ$Zt��rqq%yaml/Tests/Fixtures/YtsErrorTests.ymlnu�[���---
test: Missing value for hash item
todo: true
brief: |
    Third item in this hash doesn't have a value
yaml: |
    okay: value
    also okay: ~
    causes error because no value specified
    last key: value okay here too
python-error: causes error because no value specified

---
test: Not indenting enough
brief: |
    There was a bug in PyYaml where it was off by one
    in the indentation check.  It was allowing the YAML
    below.
# This is actually valid YAML now. Someone should tell showell.
yaml: |
    foo:
    firstline: 1
    secondline: 2
php: |
  array('foo' => null, 'firstline' => 1, 'secondline' => 2)
PKϤ$Z�ԧ��yaml/Tests/DumperTest.phpnu�[���<?php

/*
 * This file is part of the Symfony package.
 *
 * (c) Fabien Potencier <fabien@symfony.com>
 *
 * For the full copyright and license information, please view the LICENSE
 * file that was distributed with this source code.
 */

namespace Symfony\Component\Yaml\Tests;

use Symfony\Component\Yaml\Parser;
use Symfony\Component\Yaml\Dumper;

class DumperTest extends \PHPUnit_Framework_TestCase
{
    protected $parser;
    protected $dumper;
    protected $path;

    protected $array = array(
        '' => 'bar',
        'foo' => '#bar',
        'foo\'bar' => array(),
        'bar' => array(1, 'foo'),
        'foobar' => array(
            'foo' => 'bar',
            'bar' => array(1, 'foo'),
            'foobar' => array(
                'foo' => 'bar',
                'bar' => array(1, 'foo'),
            ),
        ),
    );

    protected function setUp()
    {
        $this->parser = new Parser();
        $this->dumper = new Dumper();
        $this->path = __DIR__.'/Fixtures';
    }

    protected function tearDown()
    {
        $this->parser = null;
        $this->dumper = null;
        $this->path = null;
        $this->array = null;
    }

    public function testSetIndentation()
    {
        $this->dumper->setIndentation(7);

        $expected = <<<'EOF'
'': bar
foo: '#bar'
'foo''bar': {  }
bar:
       - 1
       - foo
foobar:
       foo: bar
       bar:
              - 1
              - foo
       foobar:
              foo: bar
              bar:
                     - 1
                     - foo

EOF;
        $this->assertEquals($expected, $this->dumper->dump($this->array, 4, 0));
    }

    public function testSpecifications()
    {
        $files = $this->parser->parse(file_get_contents($this->path.'/index.yml'));
        foreach ($files as $file) {
            $yamls = file_get_contents($this->path.'/'.$file.'.yml');

            // split YAMLs documents
            foreach (preg_split('/^---( %YAML\:1\.0)?/m', $yamls) as $yaml) {
                if (!$yaml) {
                    continue;
                }

                $test = $this->parser->parse($yaml);
                if (isset($test['dump_skip']) && $test['dump_skip']) {
                    continue;
                } elseif (isset($test['todo']) && $test['todo']) {
                    // TODO
                } else {
                    eval('$expected = '.trim($test['php']).';');
                    $this->assertSame($expected, $this->parser->parse($this->dumper->dump($expected, 10)), $test['test']);
                }
            }
        }
    }

    public function testInlineLevel()
    {
        $expected = <<<'EOF'
{ '': bar, foo: '#bar', 'foo''bar': {  }, bar: [1, foo], foobar: { foo: bar, bar: [1, foo], foobar: { foo: bar, bar: [1, foo] } } }
EOF;
        $this->assertEquals($expected, $this->dumper->dump($this->array, -10), '->dump() takes an inline level argument');
        $this->assertEquals($expected, $this->dumper->dump($this->array, 0), '->dump() takes an inline level argument');

        $expected = <<<'EOF'
'': bar
foo: '#bar'
'foo''bar': {  }
bar: [1, foo]
foobar: { foo: bar, bar: [1, foo], foobar: { foo: bar, bar: [1, foo] } }

EOF;
        $this->assertEquals($expected, $this->dumper->dump($this->array, 1), '->dump() takes an inline level argument');

        $expected = <<<'EOF'
'': bar
foo: '#bar'
'foo''bar': {  }
bar:
    - 1
    - foo
foobar:
    foo: bar
    bar: [1, foo]
    foobar: { foo: bar, bar: [1, foo] }

EOF;
        $this->assertEquals($expected, $this->dumper->dump($this->array, 2), '->dump() takes an inline level argument');

        $expected = <<<'EOF'
'': bar
foo: '#bar'
'foo''bar': {  }
bar:
    - 1
    - foo
foobar:
    foo: bar
    bar:
        - 1
        - foo
    foobar:
        foo: bar
        bar: [1, foo]

EOF;
        $this->assertEquals($expected, $this->dumper->dump($this->array, 3), '->dump() takes an inline level argument');

        $expected = <<<'EOF'
'': bar
foo: '#bar'
'foo''bar': {  }
bar:
    - 1
    - foo
foobar:
    foo: bar
    bar:
        - 1
        - foo
    foobar:
        foo: bar
        bar:
            - 1
            - foo

EOF;
        $this->assertEquals($expected, $this->dumper->dump($this->array, 4), '->dump() takes an inline level argument');
        $this->assertEquals($expected, $this->dumper->dump($this->array, 10), '->dump() takes an inline level argument');
    }

    public function testObjectSupportEnabled()
    {
        $dump = $this->dumper->dump(array('foo' => new A(), 'bar' => 1), 0, 0, false, true);

        $this->assertEquals('{ foo: !php/object:O:30:"Symfony\Component\Yaml\Tests\A":1:{s:1:"a";s:3:"foo";}, bar: 1 }', $dump, '->dump() is able to dump objects');
    }

    public function testObjectSupportDisabledButNoExceptions()
    {
        $dump = $this->dumper->dump(array('foo' => new A(), 'bar' => 1));

        $this->assertEquals('{ foo: null, bar: 1 }', $dump, '->dump() does not dump objects when disabled');
    }

    /**
     * @expectedException \Symfony\Component\Yaml\Exception\DumpException
     */
    public function testObjectSupportDisabledWithExceptions()
    {
        $this->dumper->dump(array('foo' => new A(), 'bar' => 1), 0, 0, true, false);
    }

    /**
     * @dataProvider getEscapeSequences
     */
    public function testEscapedEscapeSequencesInQuotedScalar($input, $expected)
    {
        $this->assertEquals($expected, $this->dumper->dump($input));
    }

    public function getEscapeSequences()
    {
        return array(
            'null' => array("\t\\0", '"\t\\\\0"'),
            'bell' => array("\t\\a", '"\t\\\\a"'),
            'backspace' => array("\t\\b", '"\t\\\\b"'),
            'horizontal-tab' => array("\t\\t", '"\t\\\\t"'),
            'line-feed' => array("\t\\n", '"\t\\\\n"'),
            'vertical-tab' => array("\t\\v", '"\t\\\\v"'),
            'form-feed' => array("\t\\f", '"\t\\\\f"'),
            'carriage-return' => array("\t\\r", '"\t\\\\r"'),
            'escape' => array("\t\\e", '"\t\\\\e"'),
            'space' => array("\t\\ ", '"\t\\\\ "'),
            'double-quote' => array("\t\\\"", '"\t\\\\\\""'),
            'slash' => array("\t\\/", '"\t\\\\/"'),
            'backslash' => array("\t\\\\", '"\t\\\\\\\\"'),
            'next-line' => array("\t\\N", '"\t\\\\N"'),
            'non-breaking-space' => array("\t\\�", '"\t\\\\�"'),
            'line-separator' => array("\t\\L", '"\t\\\\L"'),
            'paragraph-separator' => array("\t\\P", '"\t\\\\P"'),
        );
    }

    /**
     * @expectedException \InvalidArgumentException
     * @expectedExceptionMessage The indentation must be greater than zero
     */
    public function testZeroIndentationThrowsException()
    {
        $this->dumper->setIndentation(0);
    }

    /**
     * @expectedException \InvalidArgumentException
     * @expectedExceptionMessage The indentation must be greater than zero
     */
    public function testNegativeIndentationThrowsException()
    {
        $this->dumper->setIndentation(-4);
    }
}

class A
{
    public $a = 'foo';
}
PKϤ$Z�Z%
_
_yaml/Tests/ParserTest.phpnu�[���<?php

/*
 * This file is part of the Symfony package.
 *
 * (c) Fabien Potencier <fabien@symfony.com>
 *
 * For the full copyright and license information, please view the LICENSE
 * file that was distributed with this source code.
 */

namespace Symfony\Component\Yaml\Tests;

use Symfony\Component\Yaml\Yaml;
use Symfony\Component\Yaml\Parser;

class ParserTest extends \PHPUnit_Framework_TestCase
{
    protected $parser;

    protected function setUp()
    {
        $this->parser = new Parser();
    }

    protected function tearDown()
    {
        $this->parser = null;
    }

    /**
     * @dataProvider getDataFormSpecifications
     */
    public function testSpecifications($file, $expected, $yaml, $comment)
    {
        $this->assertEquals($expected, var_export($this->parser->parse($yaml), true), $comment);
    }

    public function getDataFormSpecifications()
    {
        $parser = new Parser();
        $path = __DIR__.'/Fixtures';

        $tests = array();
        $files = $parser->parse(file_get_contents($path.'/index.yml'));
        foreach ($files as $file) {
            $yamls = file_get_contents($path.'/'.$file.'.yml');

            // split YAMLs documents
            foreach (preg_split('/^---( %YAML\:1\.0)?/m', $yamls) as $yaml) {
                if (!$yaml) {
                    continue;
                }

                $test = $parser->parse($yaml);
                if (isset($test['todo']) && $test['todo']) {
                    // TODO
                } else {
                    eval('$expected = '.trim($test['php']).';');

                    $tests[] = array($file, var_export($expected, true), $test['yaml'], $test['test']);
                }
            }
        }

        return $tests;
    }

    public function testTabsInYaml()
    {
        // test tabs in YAML
        $yamls = array(
            "foo:\n	bar",
            "foo:\n 	bar",
            "foo:\n	 bar",
            "foo:\n 	 bar",
        );

        foreach ($yamls as $yaml) {
            try {
                $content = $this->parser->parse($yaml);

                $this->fail('YAML files must not contain tabs');
            } catch (\Exception $e) {
                $this->assertInstanceOf('\Exception', $e, 'YAML files must not contain tabs');
                $this->assertEquals('A YAML file cannot contain tabs as indentation at line 2 (near "'.strpbrk($yaml, "\t").'").', $e->getMessage(), 'YAML files must not contain tabs');
            }
        }
    }

    public function testEndOfTheDocumentMarker()
    {
        $yaml = <<<'EOF'
--- %YAML:1.0
foo
...
EOF;

        $this->assertEquals('foo', $this->parser->parse($yaml));
    }

    public function getBlockChompingTests()
    {
        $tests = array();

        $yaml = <<<'EOF'
foo: |-
    one
    two
bar: |-
    one
    two

EOF;
        $expected = array(
            'foo' => "one\ntwo",
            'bar' => "one\ntwo",
        );
        $tests['Literal block chomping strip with single trailing newline'] = array($expected, $yaml);

        $yaml = <<<'EOF'
foo: |-
    one
    two

bar: |-
    one
    two


EOF;
        $expected = array(
            'foo' => "one\ntwo",
            'bar' => "one\ntwo",
        );
        $tests['Literal block chomping strip with multiple trailing newlines'] = array($expected, $yaml);

        $yaml = <<<'EOF'
{}


EOF;
        $expected = array();
        $tests['Literal block chomping strip with multiple trailing newlines after a 1-liner'] = array($expected, $yaml);

        $yaml = <<<'EOF'
foo: |-
    one
    two
bar: |-
    one
    two
EOF;
        $expected = array(
            'foo' => "one\ntwo",
            'bar' => "one\ntwo",
        );
        $tests['Literal block chomping strip without trailing newline'] = array($expected, $yaml);

        $yaml = <<<'EOF'
foo: |
    one
    two
bar: |
    one
    two

EOF;
        $expected = array(
            'foo' => "one\ntwo\n",
            'bar' => "one\ntwo\n",
        );
        $tests['Literal block chomping clip with single trailing newline'] = array($expected, $yaml);

        $yaml = <<<'EOF'
foo: |
    one
    two

bar: |
    one
    two


EOF;
        $expected = array(
            'foo' => "one\ntwo\n",
            'bar' => "one\ntwo\n",
        );
        $tests['Literal block chomping clip with multiple trailing newlines'] = array($expected, $yaml);

        $yaml = <<<'EOF'
foo: |
    one
    two
bar: |
    one
    two
EOF;
        $expected = array(
            'foo' => "one\ntwo\n",
            'bar' => "one\ntwo",
        );
        $tests['Literal block chomping clip without trailing newline'] = array($expected, $yaml);

        $yaml = <<<'EOF'
foo: |+
    one
    two
bar: |+
    one
    two

EOF;
        $expected = array(
            'foo' => "one\ntwo\n",
            'bar' => "one\ntwo\n",
        );
        $tests['Literal block chomping keep with single trailing newline'] = array($expected, $yaml);

        $yaml = <<<'EOF'
foo: |+
    one
    two

bar: |+
    one
    two


EOF;
        $expected = array(
            'foo' => "one\ntwo\n\n",
            'bar' => "one\ntwo\n\n",
        );
        $tests['Literal block chomping keep with multiple trailing newlines'] = array($expected, $yaml);

        $yaml = <<<'EOF'
foo: |+
    one
    two
bar: |+
    one
    two
EOF;
        $expected = array(
            'foo' => "one\ntwo\n",
            'bar' => "one\ntwo",
        );
        $tests['Literal block chomping keep without trailing newline'] = array($expected, $yaml);

        $yaml = <<<'EOF'
foo: >-
    one
    two
bar: >-
    one
    two

EOF;
        $expected = array(
            'foo' => 'one two',
            'bar' => 'one two',
        );
        $tests['Folded block chomping strip with single trailing newline'] = array($expected, $yaml);

        $yaml = <<<'EOF'
foo: >-
    one
    two

bar: >-
    one
    two


EOF;
        $expected = array(
            'foo' => 'one two',
            'bar' => 'one two',
        );
        $tests['Folded block chomping strip with multiple trailing newlines'] = array($expected, $yaml);

        $yaml = <<<'EOF'
foo: >-
    one
    two
bar: >-
    one
    two
EOF;
        $expected = array(
            'foo' => 'one two',
            'bar' => 'one two',
        );
        $tests['Folded block chomping strip without trailing newline'] = array($expected, $yaml);

        $yaml = <<<'EOF'
foo: >
    one
    two
bar: >
    one
    two

EOF;
        $expected = array(
            'foo' => "one two\n",
            'bar' => "one two\n",
        );
        $tests['Folded block chomping clip with single trailing newline'] = array($expected, $yaml);

        $yaml = <<<'EOF'
foo: >
    one
    two

bar: >
    one
    two


EOF;
        $expected = array(
            'foo' => "one two\n",
            'bar' => "one two\n",
        );
        $tests['Folded block chomping clip with multiple trailing newlines'] = array($expected, $yaml);

        $yaml = <<<'EOF'
foo: >
    one
    two
bar: >
    one
    two
EOF;
        $expected = array(
            'foo' => "one two\n",
            'bar' => 'one two',
        );
        $tests['Folded block chomping clip without trailing newline'] = array($expected, $yaml);

        $yaml = <<<'EOF'
foo: >+
    one
    two
bar: >+
    one
    two

EOF;
        $expected = array(
            'foo' => "one two\n",
            'bar' => "one two\n",
        );
        $tests['Folded block chomping keep with single trailing newline'] = array($expected, $yaml);

        $yaml = <<<'EOF'
foo: >+
    one
    two

bar: >+
    one
    two


EOF;
        $expected = array(
            'foo' => "one two\n\n",
            'bar' => "one two\n\n",
        );
        $tests['Folded block chomping keep with multiple trailing newlines'] = array($expected, $yaml);

        $yaml = <<<'EOF'
foo: >+
    one
    two
bar: >+
    one
    two
EOF;
        $expected = array(
            'foo' => "one two\n",
            'bar' => 'one two',
        );
        $tests['Folded block chomping keep without trailing newline'] = array($expected, $yaml);

        return $tests;
    }

    /**
     * @dataProvider getBlockChompingTests
     */
    public function testBlockChomping($expected, $yaml)
    {
        $this->assertSame($expected, $this->parser->parse($yaml));
    }

    /**
     * Regression test for issue #7989.
     *
     * @see https://github.com/symfony/symfony/issues/7989
     */
    public function testBlockLiteralWithLeadingNewlines()
    {
        $yaml = <<<'EOF'
foo: |-


    bar

EOF;
        $expected = array(
            'foo' => "\n\nbar",
        );

        $this->assertSame($expected, $this->parser->parse($yaml));
    }

    public function testObjectSupportEnabled()
    {
        $input = <<<EOF
foo: !!php/object:O:30:"Symfony\Component\Yaml\Tests\B":1:{s:1:"b";s:3:"foo";}
bar: 1
EOF;
        $this->assertEquals(array('foo' => new B(), 'bar' => 1), $this->parser->parse($input, false, true), '->parse() is able to parse objects');

        $input = <<<EOF
foo: !php/object:O:30:"Symfony\Component\Yaml\Tests\B":1:{s:1:"b";s:3:"foo";}
bar: 1
EOF;
        $this->assertEquals(array('foo' => new B(), 'bar' => 1), $this->parser->parse($input, false, true), '->parse() is able to parse objects');
    }

    /**
     * @dataProvider invalidDumpedObjectProvider
     */
    public function testObjectSupportDisabledButNoExceptions($input)
    {
        $this->assertEquals(array('foo' => null, 'bar' => 1), $this->parser->parse($input), '->parse() does not parse objects');
    }

    /**
     * @dataProvider getObjectForMapTests
     */
    public function testObjectForMap($yaml, $expected)
    {
        $this->assertEquals($expected, $this->parser->parse($yaml, false, false, true));
    }

    public function getObjectForMapTests()
    {
        $tests = array();

        $yaml = <<<EOF
foo:
    fiz: [cat]
EOF;
        $expected = new \stdClass();
        $expected->foo = new \stdClass();
        $expected->foo->fiz = array('cat');
        $tests['mapping'] = array($yaml, $expected);

        $yaml = '{ "foo": "bar", "fiz": "cat" }';
        $expected = new \stdClass();
        $expected->foo = 'bar';
        $expected->fiz = 'cat';
        $tests['inline-mapping'] = array($yaml, $expected);

        $yaml = "foo: bar\nbaz: foobar";
        $expected = new \stdClass();
        $expected->foo = 'bar';
        $expected->baz = 'foobar';
        $tests['object-for-map-is-applied-after-parsing'] = array($yaml, $expected);

        $yaml = <<<EOT
array:
  - key: one
  - key: two
EOT;
        $expected = new \stdClass();
        $expected->array = array();
        $expected->array[0] = new \stdClass();
        $expected->array[0]->key = 'one';
        $expected->array[1] = new \stdClass();
        $expected->array[1]->key = 'two';
        $tests['nest-map-and-sequence'] = array($yaml, $expected);

        $yaml = <<<YAML
map:
  1: one
  2: two
YAML;
        $expected = new \stdClass();
        $expected->map = new \stdClass();
        $expected->map->{1} = 'one';
        $expected->map->{2} = 'two';
        $tests['numeric-keys'] = array($yaml, $expected);

        $yaml = <<<YAML
map:
  0: one
  1: two
YAML;
        $expected = new \stdClass();
        $expected->map = new \stdClass();
        $expected->map->{0} = 'one';
        $expected->map->{1} = 'two';
        $tests['zero-indexed-numeric-keys'] = array($yaml, $expected);

        return $tests;
    }

    /**
     * @dataProvider invalidDumpedObjectProvider
     * @expectedException \Symfony\Component\Yaml\Exception\ParseException
     */
    public function testObjectsSupportDisabledWithExceptions($yaml)
    {
        $this->parser->parse($yaml, true, false);
    }

    public function invalidDumpedObjectProvider()
    {
        $yamlTag = <<<EOF
foo: !!php/object:O:30:"Symfony\Tests\Component\Yaml\B":1:{s:1:"b";s:3:"foo";}
bar: 1
EOF;
        $localTag = <<<EOF
foo: !php/object:O:30:"Symfony\Tests\Component\Yaml\B":1:{s:1:"b";s:3:"foo";}
bar: 1
EOF;

        return array(
            'yaml-tag' => array($yamlTag),
            'local-tag' => array($localTag),
        );
    }

    /**
     * @requires extension iconv
     */
    public function testNonUtf8Exception()
    {
        $yamls = array(
            iconv('UTF-8', 'ISO-8859-1', "foo: 'äöüß'"),
            iconv('UTF-8', 'ISO-8859-15', "euro: '€'"),
            iconv('UTF-8', 'CP1252', "cp1252: '©ÉÇáñ'"),
        );

        foreach ($yamls as $yaml) {
            try {
                $this->parser->parse($yaml);

                $this->fail('charsets other than UTF-8 are rejected.');
            } catch (\Exception $e) {
                $this->assertInstanceOf('Symfony\Component\Yaml\Exception\ParseException', $e, 'charsets other than UTF-8 are rejected.');
            }
        }
    }

    /**
     * @expectedException \Symfony\Component\Yaml\Exception\ParseException
     */
    public function testUnindentedCollectionException()
    {
        $yaml = <<<'EOF'

collection:
-item1
-item2
-item3

EOF;

        $this->parser->parse($yaml);
    }

    /**
     * @expectedException \Symfony\Component\Yaml\Exception\ParseException
     */
    public function testShortcutKeyUnindentedCollectionException()
    {
        $yaml = <<<'EOF'

collection:
-  key: foo
  foo: bar

EOF;

        $this->parser->parse($yaml);
    }

    /**
     * @expectedException \Symfony\Component\Yaml\Exception\ParseException
     * @expectedExceptionMessageRegExp /^Multiple documents are not supported.+/
     */
    public function testMultipleDocumentsNotSupportedException()
    {
        Yaml::parse(<<<'EOL'
# Ranking of 1998 home runs
---
- Mark McGwire
- Sammy Sosa
- Ken Griffey

# Team ranking
---
- Chicago Cubs
- St Louis Cardinals
EOL
        );
    }

    /**
     * @expectedException \Symfony\Component\Yaml\Exception\ParseException
     */
    public function testSequenceInAMapping()
    {
        Yaml::parse(<<<'EOF'
yaml:
  hash: me
  - array stuff
EOF
        );
    }

    public function testSequenceInMappingStartedBySingleDashLine()
    {
        $yaml = <<<EOT
a:
-
  b:
  -
    bar: baz
- foo
d: e
EOT;
        $expected = array(
            'a' => array(
                array(
                    'b' => array(
                        array(
                            'bar' => 'baz',
                        ),
                    ),
                ),
                'foo',
            ),
            'd' => 'e',
        );

        $this->assertSame($expected, $this->parser->parse($yaml));
    }

    /**
     * @expectedException \Symfony\Component\Yaml\Exception\ParseException
     */
    public function testMappingInASequence()
    {
        Yaml::parse(<<<'EOF'
yaml:
  - array stuff
  hash: me
EOF
        );
    }

    /**
     * @expectedException \Symfony\Component\Yaml\Exception\ParseException
     * @expectedExceptionMessage missing colon
     */
    public function testScalarInSequence()
    {
        Yaml::parse(<<<EOF
foo:
    - bar
"missing colon"
    foo: bar
EOF
        );
    }

    /**
     * > It is an error for two equal keys to appear in the same mapping node.
     * > In such a case the YAML processor may continue, ignoring the second
     * > `key: value` pair and issuing an appropriate warning. This strategy
     * > preserves a consistent information model for one-pass and random access
     * > applications.
     *
     * @see http://yaml.org/spec/1.2/spec.html#id2759572
     * @see http://yaml.org/spec/1.1/#id932806
     */
    public function testMappingDuplicateKeyBlock()
    {
        $input = <<<EOD
parent:
    child: first
    child: duplicate
parent:
    child: duplicate
    child: duplicate
EOD;
        $expected = array(
            'parent' => array(
                'child' => 'first',
            ),
        );
        $this->assertSame($expected, Yaml::parse($input));
    }

    public function testMappingDuplicateKeyFlow()
    {
        $input = <<<EOD
parent: { child: first, child: duplicate }
parent: { child: duplicate, child: duplicate }
EOD;
        $expected = array(
            'parent' => array(
                'child' => 'first',
            ),
        );
        $this->assertSame($expected, Yaml::parse($input));
    }

    public function testEmptyValue()
    {
        $input = <<<'EOF'
hash:
EOF;

        $this->assertEquals(array('hash' => null), Yaml::parse($input));
    }

    public function testCommentAtTheRootIndent()
    {
        $this->assertEquals(array(
            'services' => array(
                'app.foo_service' => array(
                    'class' => 'Foo',
                ),
                'app/bar_service' => array(
                    'class' => 'Bar',
                ),
            ),
        ), Yaml::parse(<<<'EOF'
# comment 1
services:
# comment 2
    # comment 3
    app.foo_service:
        class: Foo
# comment 4
    # comment 5
    app/bar_service:
        class: Bar
EOF
        ));
    }

    public function testStringBlockWithComments()
    {
        $this->assertEquals(array('content' => <<<'EOT'
# comment 1
header

    # comment 2
    <body>
        <h1>title</h1>
    </body>

footer # comment3
EOT
        ), Yaml::parse(<<<'EOF'
content: |
    # comment 1
    header

        # comment 2
        <body>
            <h1>title</h1>
        </body>

    footer # comment3
EOF
        ));
    }

    public function testFoldedStringBlockWithComments()
    {
        $this->assertEquals(array(array('content' => <<<'EOT'
# comment 1
header

    # comment 2
    <body>
        <h1>title</h1>
    </body>

footer # comment3
EOT
        )), Yaml::parse(<<<'EOF'
-
    content: |
        # comment 1
        header

            # comment 2
            <body>
                <h1>title</h1>
            </body>

        footer # comment3
EOF
        ));
    }

    public function testNestedFoldedStringBlockWithComments()
    {
        $this->assertEquals(array(array(
            'title' => 'some title',
            'content' => <<<'EOT'
# comment 1
header

    # comment 2
    <body>
        <h1>title</h1>
    </body>

footer # comment3
EOT
        )), Yaml::parse(<<<'EOF'
-
    title: some title
    content: |
        # comment 1
        header

            # comment 2
            <body>
                <h1>title</h1>
            </body>

        footer # comment3
EOF
        ));
    }

    public function testReferenceResolvingInInlineStrings()
    {
        $this->assertEquals(array(
            'var' => 'var-value',
            'scalar' => 'var-value',
            'list' => array('var-value'),
            'list_in_list' => array(array('var-value')),
            'map_in_list' => array(array('key' => 'var-value')),
            'embedded_mapping' => array(array('key' => 'var-value')),
            'map' => array('key' => 'var-value'),
            'list_in_map' => array('key' => array('var-value')),
            'map_in_map' => array('foo' => array('bar' => 'var-value')),
        ), Yaml::parse(<<<'EOF'
var:  &var var-value
scalar: *var
list: [ *var ]
list_in_list: [[ *var ]]
map_in_list: [ { key: *var } ]
embedded_mapping: [ key: *var ]
map: { key: *var }
list_in_map: { key: [*var] }
map_in_map: { foo: { bar: *var } }
EOF
        ));
    }

    public function testYamlDirective()
    {
        $yaml = <<<'EOF'
%YAML 1.2
---
foo: 1
bar: 2
EOF;
        $this->assertEquals(array('foo' => 1, 'bar' => 2), $this->parser->parse($yaml));
    }

    public function testFloatKeys()
    {
        $yaml = <<<'EOF'
foo:
    1.2: "bar"
    1.3: "baz"
EOF;

        $expected = array(
            'foo' => array(
                '1.2' => 'bar',
                '1.3' => 'baz',
            ),
        );

        $this->assertEquals($expected, $this->parser->parse($yaml));
    }

    /**
     * @group legacy
     * throw ParseException in Symfony 3.0
     */
    public function testColonInMappingValueException()
    {
        $yaml = <<<EOF
foo: bar: baz
EOF;

        $deprecations = array();
        set_error_handler(function ($type, $msg) use (&$deprecations) {
            if (E_USER_DEPRECATED !== $type) {
                restore_error_handler();

                return call_user_func_array('PHPUnit_Util_ErrorHandler::handleError', func_get_args());
            }

            $deprecations[] = $msg;
        });

        $this->parser->parse($yaml);

        restore_error_handler();

        $this->assertCount(1, $deprecations);
        $this->assertContains('Using a colon in the unquoted mapping value "bar: baz" in line 1 is deprecated since Symfony 2.8 and will throw a ParseException in 3.0.', $deprecations[0]);
    }

    public function testColonInMappingValueExceptionNotTriggeredByColonInComment()
    {
        $yaml = <<<EOT
foo:
    bar: foobar # Note: a comment after a colon
EOT;

        $this->assertSame(array('foo' => array('bar' => 'foobar')), $this->parser->parse($yaml));
    }

    /**
     * @dataProvider getCommentLikeStringInScalarBlockData
     */
    public function testCommentLikeStringsAreNotStrippedInBlockScalars($yaml, $expectedParserResult)
    {
        $this->assertSame($expectedParserResult, $this->parser->parse($yaml));
    }

    public function getCommentLikeStringInScalarBlockData()
    {
        $tests = array();

        $yaml = <<<'EOT'
pages:
    -
        title: some title
        content: |
            # comment 1
            header

                # comment 2
                <body>
                    <h1>title</h1>
                </body>

            footer # comment3
EOT;
        $expected = array(
            'pages' => array(
                array(
                    'title' => 'some title',
                    'content' => <<<'EOT'
# comment 1
header

    # comment 2
    <body>
        <h1>title</h1>
    </body>

footer # comment3
EOT
                    ,
                ),
            ),
        );
        $tests[] = array($yaml, $expected);

        $yaml = <<<'EOT'
test: |
    foo
    # bar
    baz
collection:
    - one: |
        foo
        # bar
        baz
    - two: |
        foo
        # bar
        baz
EOT;
        $expected = array(
            'test' => <<<'EOT'
foo
# bar
baz

EOT
            ,
            'collection' => array(
                array(
                    'one' => <<<'EOT'
foo
# bar
baz

EOT
                    ,
                ),
                array(
                    'two' => <<<'EOT'
foo
# bar
baz
EOT
                    ,
                ),
            ),
        );
        $tests[] = array($yaml, $expected);

        $yaml = <<<EOT
foo:
  bar:
    scalar-block: >
      line1
      line2>
  baz:
# comment
    foobar: ~
EOT;
        $expected = array(
            'foo' => array(
                'bar' => array(
                    'scalar-block' => "line1 line2>\n",
                ),
                'baz' => array(
                    'foobar' => null,
                ),
            ),
        );
        $tests[] = array($yaml, $expected);

        $yaml = <<<'EOT'
a:
    b: hello
#    c: |
#        first row
#        second row
    d: hello
EOT;
        $expected = array(
            'a' => array(
                'b' => 'hello',
                'd' => 'hello',
            ),
        );
        $tests[] = array($yaml, $expected);

        return $tests;
    }

    public function testBlankLinesAreParsedAsNewLinesInFoldedBlocks()
    {
        $yaml = <<<EOT
test: >
    <h2>A heading</h2>

    <ul>
    <li>a list</li>
    <li>may be a good example</li>
    </ul>
EOT;

        $this->assertSame(
            array(
                'test' => <<<EOT
<h2>A heading</h2>
<ul> <li>a list</li> <li>may be a good example</li> </ul>
EOT
                ,
            ),
            $this->parser->parse($yaml)
        );
    }

    public function testAdditionallyIndentedLinesAreParsedAsNewLinesInFoldedBlocks()
    {
        $yaml = <<<EOT
test: >
    <h2>A heading</h2>

    <ul>
      <li>a list</li>
      <li>may be a good example</li>
    </ul>
EOT;

        $this->assertSame(
            array(
                'test' => <<<EOT
<h2>A heading</h2>
<ul>
  <li>a list</li>
  <li>may be a good example</li>
</ul>
EOT
                ,
            ),
            $this->parser->parse($yaml)
        );
    }
}

class B
{
    public $b = 'foo';
}
PKϤ$Z�n�����yaml/Parser.phpnu�[���<?php

/*
 * This file is part of the Symfony package.
 *
 * (c) Fabien Potencier <fabien@symfony.com>
 *
 * For the full copyright and license information, please view the LICENSE
 * file that was distributed with this source code.
 */

namespace Symfony\Component\Yaml;

use Symfony\Component\Yaml\Exception\ParseException;
use Symfony\Component\Yaml\Tag\TaggedValue;

/**
 * Parser parses YAML strings to convert them to PHP arrays.
 *
 * @author Fabien Potencier <fabien@symfony.com>
 *
 * @final
 */
class Parser
{
    const TAG_PATTERN = '(?P<tag>![\w!.\/:-]+)';
    const BLOCK_SCALAR_HEADER_PATTERN = '(?P<separator>\||>)(?P<modifiers>\+|\-|\d+|\+\d+|\-\d+|\d+\+|\d+\-)?(?P<comments> +#.*)?';

    private $filename;
    private $offset = 0;
    private $totalNumberOfLines;
    private $lines = [];
    private $currentLineNb = -1;
    private $currentLine = '';
    private $refs = [];
    private $skippedLineNumbers = [];
    private $locallySkippedLineNumbers = [];
    private $refsBeingParsed = [];

    /**
     * Parses a YAML file into a PHP value.
     *
     * @param string $filename The path to the YAML file to be parsed
     * @param int    $flags    A bit field of PARSE_* constants to customize the YAML parser behavior
     *
     * @return mixed The YAML converted to a PHP value
     *
     * @throws ParseException If the file could not be read or the YAML is not valid
     */
    public function parseFile(string $filename, int $flags = 0)
    {
        if (!is_file($filename)) {
            throw new ParseException(sprintf('File "%s" does not exist.', $filename));
        }

        if (!is_readable($filename)) {
            throw new ParseException(sprintf('File "%s" cannot be read.', $filename));
        }

        $this->filename = $filename;

        try {
            return $this->parse(file_get_contents($filename), $flags);
        } finally {
            $this->filename = null;
        }
    }

    /**
     * Parses a YAML string to a PHP value.
     *
     * @param string $value A YAML string
     * @param int    $flags A bit field of PARSE_* constants to customize the YAML parser behavior
     *
     * @return mixed A PHP value
     *
     * @throws ParseException If the YAML is not valid
     */
    public function parse(string $value, int $flags = 0)
    {
        if (false === preg_match('//u', $value)) {
            throw new ParseException('The YAML value does not appear to be valid UTF-8.', -1, null, $this->filename);
        }

        $this->refs = [];

        $mbEncoding = null;

        if (2 /* MB_OVERLOAD_STRING */ & (int) ini_get('mbstring.func_overload')) {
            $mbEncoding = mb_internal_encoding();
            mb_internal_encoding('UTF-8');
        }

        try {
            $data = $this->doParse($value, $flags);
        } finally {
            if (null !== $mbEncoding) {
                mb_internal_encoding($mbEncoding);
            }
            $this->lines = [];
            $this->currentLine = '';
            $this->refs = [];
            $this->skippedLineNumbers = [];
            $this->locallySkippedLineNumbers = [];
        }

        return $data;
    }

    private function doParse(string $value, int $flags)
    {
        $this->currentLineNb = -1;
        $this->currentLine = '';
        $value = $this->cleanup($value);
        $this->lines = explode("\n", $value);
        $this->locallySkippedLineNumbers = [];

        if (null === $this->totalNumberOfLines) {
            $this->totalNumberOfLines = \count($this->lines);
        }

        if (!$this->moveToNextLine()) {
            return null;
        }

        $data = [];
        $context = null;
        $allowOverwrite = false;

        while ($this->isCurrentLineEmpty()) {
            if (!$this->moveToNextLine()) {
                return null;
            }
        }

        // Resolves the tag and returns if end of the document
        if (null !== ($tag = $this->getLineTag($this->currentLine, $flags, false)) && !$this->moveToNextLine()) {
            return new TaggedValue($tag, '');
        }

        do {
            if ($this->isCurrentLineEmpty()) {
                continue;
            }

            // tab?
            if ("\t" === $this->currentLine[0]) {
                throw new ParseException('A YAML file cannot contain tabs as indentation.', $this->getRealCurrentLineNb() + 1, $this->currentLine, $this->filename);
            }

            Inline::initialize($flags, $this->getRealCurrentLineNb(), $this->filename);

            $isRef = $mergeNode = false;
            if ('-' === $this->currentLine[0] && self::preg_match('#^\-((?P<leadspaces>\s+)(?P<value>.+))?$#u', rtrim($this->currentLine), $values)) {
                if ($context && 'mapping' == $context) {
                    throw new ParseException('You cannot define a sequence item when in a mapping.', $this->getRealCurrentLineNb() + 1, $this->currentLine, $this->filename);
                }
                $context = 'sequence';

                if (isset($values['value']) && '&' === $values['value'][0] && self::preg_match('#^&(?P<ref>[^ ]+) *(?P<value>.*)#u', $values['value'], $matches)) {
                    $isRef = $matches['ref'];
                    $this->refsBeingParsed[] = $isRef;
                    $values['value'] = $matches['value'];
                }

                if (isset($values['value'][1]) && '?' === $values['value'][0] && ' ' === $values['value'][1]) {
                    throw new ParseException('Complex mappings are not supported.', $this->getRealCurrentLineNb() + 1, $this->currentLine);
                }

                // array
                if (!isset($values['value']) || '' == trim($values['value'], ' ') || 0 === strpos(ltrim($values['value'], ' '), '#')) {
                    $data[] = $this->parseBlock($this->getRealCurrentLineNb() + 1, $this->getNextEmbedBlock(null, true) ?? '', $flags);
                } elseif (null !== $subTag = $this->getLineTag(ltrim($values['value'], ' '), $flags)) {
                    $data[] = new TaggedValue(
                        $subTag,
                        $this->parseBlock($this->getRealCurrentLineNb() + 1, $this->getNextEmbedBlock(null, true), $flags)
                    );
                } else {
                    if (isset($values['leadspaces'])
                        && self::preg_match('#^(?P<key>'.Inline::REGEX_QUOTED_STRING.'|[^ \'"\{\[].*?) *\:(\s+(?P<value>.+?))?\s*$#u', $this->trimTag($values['value']), $matches)
                    ) {
                        // this is a compact notation element, add to next block and parse
                        $block = $values['value'];
                        if ($this->isNextLineIndented()) {
                            $block .= "\n".$this->getNextEmbedBlock($this->getCurrentLineIndentation() + \strlen($values['leadspaces']) + 1);
                        }

                        $data[] = $this->parseBlock($this->getRealCurrentLineNb(), $block, $flags);
                    } else {
                        $data[] = $this->parseValue($values['value'], $flags, $context);
                    }
                }
                if ($isRef) {
                    $this->refs[$isRef] = end($data);
                    array_pop($this->refsBeingParsed);
                }
            } elseif (
                self::preg_match('#^(?P<key>(?:![^\s]++\s++)?(?:'.Inline::REGEX_QUOTED_STRING.'|(?:!?!php/const:)?[^ \'"\[\{!].*?)) *\:(\s++(?P<value>.+))?$#u', rtrim($this->currentLine), $values)
                && (false === strpos($values['key'], ' #') || \in_array($values['key'][0], ['"', "'"]))
            ) {
                if ($context && 'sequence' == $context) {
                    throw new ParseException('You cannot define a mapping item when in a sequence.', $this->currentLineNb + 1, $this->currentLine, $this->filename);
                }
                $context = 'mapping';

                try {
                    $key = Inline::parseScalar($values['key']);
                } catch (ParseException $e) {
                    $e->setParsedLine($this->getRealCurrentLineNb() + 1);
                    $e->setSnippet($this->currentLine);

                    throw $e;
                }

                if (!\is_string($key) && !\is_int($key)) {
                    throw new ParseException(sprintf('%s keys are not supported. Quote your evaluable mapping keys instead.', is_numeric($key) ? 'Numeric' : 'Non-string'), $this->getRealCurrentLineNb() + 1, $this->currentLine);
                }

                // Convert float keys to strings, to avoid being converted to integers by PHP
                if (\is_float($key)) {
                    $key = (string) $key;
                }

                if ('<<' === $key && (!isset($values['value']) || '&' !== $values['value'][0] || !self::preg_match('#^&(?P<ref>[^ ]+)#u', $values['value'], $refMatches))) {
                    $mergeNode = true;
                    $allowOverwrite = true;
                    if (isset($values['value'][0]) && '*' === $values['value'][0]) {
                        $refName = substr(rtrim($values['value']), 1);
                        if (!\array_key_exists($refName, $this->refs)) {
                            if (false !== $pos = array_search($refName, $this->refsBeingParsed, true)) {
                                throw new ParseException(sprintf('Circular reference [%s, %s] detected for reference "%s".', implode(', ', \array_slice($this->refsBeingParsed, $pos)), $refName, $refName), $this->currentLineNb + 1, $this->currentLine, $this->filename);
                            }

                            throw new ParseException(sprintf('Reference "%s" does not exist.', $refName), $this->getRealCurrentLineNb() + 1, $this->currentLine, $this->filename);
                        }

                        $refValue = $this->refs[$refName];

                        if (Yaml::PARSE_OBJECT_FOR_MAP & $flags && $refValue instanceof \stdClass) {
                            $refValue = (array) $refValue;
                        }

                        if (!\is_array($refValue)) {
                            throw new ParseException('YAML merge keys used with a scalar value instead of an array.', $this->getRealCurrentLineNb() + 1, $this->currentLine, $this->filename);
                        }

                        $data += $refValue; // array union
                    } else {
                        if (isset($values['value']) && '' !== $values['value']) {
                            $value = $values['value'];
                        } else {
                            $value = $this->getNextEmbedBlock();
                        }
                        $parsed = $this->parseBlock($this->getRealCurrentLineNb() + 1, $value, $flags);

                        if (Yaml::PARSE_OBJECT_FOR_MAP & $flags && $parsed instanceof \stdClass) {
                            $parsed = (array) $parsed;
                        }

                        if (!\is_array($parsed)) {
                            throw new ParseException('YAML merge keys used with a scalar value instead of an array.', $this->getRealCurrentLineNb() + 1, $this->currentLine, $this->filename);
                        }

                        if (isset($parsed[0])) {
                            // If the value associated with the merge key is a sequence, then this sequence is expected to contain mapping nodes
                            // and each of these nodes is merged in turn according to its order in the sequence. Keys in mapping nodes earlier
                            // in the sequence override keys specified in later mapping nodes.
                            foreach ($parsed as $parsedItem) {
                                if (Yaml::PARSE_OBJECT_FOR_MAP & $flags && $parsedItem instanceof \stdClass) {
                                    $parsedItem = (array) $parsedItem;
                                }

                                if (!\is_array($parsedItem)) {
                                    throw new ParseException('Merge items must be arrays.', $this->getRealCurrentLineNb() + 1, $parsedItem, $this->filename);
                                }

                                $data += $parsedItem; // array union
                            }
                        } else {
                            // If the value associated with the key is a single mapping node, each of its key/value pairs is inserted into the
                            // current mapping, unless the key already exists in it.
                            $data += $parsed; // array union
                        }
                    }
                } elseif ('<<' !== $key && isset($values['value']) && '&' === $values['value'][0] && self::preg_match('#^&(?P<ref>[^ ]++) *+(?P<value>.*)#u', $values['value'], $matches)) {
                    $isRef = $matches['ref'];
                    $this->refsBeingParsed[] = $isRef;
                    $values['value'] = $matches['value'];
                }

                $subTag = null;
                if ($mergeNode) {
                    // Merge keys
                } elseif (!isset($values['value']) || '' === $values['value'] || 0 === strpos($values['value'], '#') || (null !== $subTag = $this->getLineTag($values['value'], $flags)) || '<<' === $key) {
                    // hash
                    // if next line is less indented or equal, then it means that the current value is null
                    if (!$this->isNextLineIndented() && !$this->isNextLineUnIndentedCollection()) {
                        // Spec: Keys MUST be unique; first one wins.
                        // But overwriting is allowed when a merge node is used in current block.
                        if ($allowOverwrite || !isset($data[$key])) {
                            if (null !== $subTag) {
                                $data[$key] = new TaggedValue($subTag, '');
                            } else {
                                $data[$key] = null;
                            }
                        } else {
                            throw new ParseException(sprintf('Duplicate key "%s" detected.', $key), $this->getRealCurrentLineNb() + 1, $this->currentLine);
                        }
                    } else {
                        // remember the parsed line number here in case we need it to provide some contexts in error messages below
                        $realCurrentLineNbKey = $this->getRealCurrentLineNb();
                        $value = $this->parseBlock($this->getRealCurrentLineNb() + 1, $this->getNextEmbedBlock(), $flags);
                        if ('<<' === $key) {
                            $this->refs[$refMatches['ref']] = $value;

                            if (Yaml::PARSE_OBJECT_FOR_MAP & $flags && $value instanceof \stdClass) {
                                $value = (array) $value;
                            }

                            $data += $value;
                        } elseif ($allowOverwrite || !isset($data[$key])) {
                            // Spec: Keys MUST be unique; first one wins.
                            // But overwriting is allowed when a merge node is used in current block.
                            if (null !== $subTag) {
                                $data[$key] = new TaggedValue($subTag, $value);
                            } else {
                                $data[$key] = $value;
                            }
                        } else {
                            throw new ParseException(sprintf('Duplicate key "%s" detected.', $key), $realCurrentLineNbKey + 1, $this->currentLine);
                        }
                    }
                } else {
                    $value = $this->parseValue(rtrim($values['value']), $flags, $context);
                    // Spec: Keys MUST be unique; first one wins.
                    // But overwriting is allowed when a merge node is used in current block.
                    if ($allowOverwrite || !isset($data[$key])) {
                        $data[$key] = $value;
                    } else {
                        throw new ParseException(sprintf('Duplicate key "%s" detected.', $key), $this->getRealCurrentLineNb() + 1, $this->currentLine);
                    }
                }
                if ($isRef) {
                    $this->refs[$isRef] = $data[$key];
                    array_pop($this->refsBeingParsed);
                }
            } elseif ('"' === $this->currentLine[0] || "'" === $this->currentLine[0]) {
                if (null !== $context) {
                    throw new ParseException('Unable to parse.', $this->getRealCurrentLineNb() + 1, $this->currentLine, $this->filename);
                }

                try {
                    return Inline::parse($this->parseQuotedString($this->currentLine), $flags, $this->refs);
                } catch (ParseException $e) {
                    $e->setParsedLine($this->getRealCurrentLineNb() + 1);
                    $e->setSnippet($this->currentLine);

                    throw $e;
                }
            } elseif ('{' === $this->currentLine[0]) {
                if (null !== $context) {
                    throw new ParseException('Unable to parse.', $this->getRealCurrentLineNb() + 1, $this->currentLine, $this->filename);
                }

                try {
                    $parsedMapping = Inline::parse($this->lexInlineMapping($this->currentLine), $flags, $this->refs);

                    while ($this->moveToNextLine()) {
                        if (!$this->isCurrentLineEmpty()) {
                            throw new ParseException('Unable to parse.', $this->getRealCurrentLineNb() + 1, $this->currentLine, $this->filename);
                        }
                    }

                    return $parsedMapping;
                } catch (ParseException $e) {
                    $e->setParsedLine($this->getRealCurrentLineNb() + 1);
                    $e->setSnippet($this->currentLine);

                    throw $e;
                }
            } elseif ('[' === $this->currentLine[0]) {
                if (null !== $context) {
                    throw new ParseException('Unable to parse.', $this->getRealCurrentLineNb() + 1, $this->currentLine, $this->filename);
                }

                try {
                    $parsedSequence = Inline::parse($this->lexInlineSequence($this->currentLine), $flags, $this->refs);

                    while ($this->moveToNextLine()) {
                        if (!$this->isCurrentLineEmpty()) {
                            throw new ParseException('Unable to parse.', $this->getRealCurrentLineNb() + 1, $this->currentLine, $this->filename);
                        }
                    }

                    return $parsedSequence;
                } catch (ParseException $e) {
                    $e->setParsedLine($this->getRealCurrentLineNb() + 1);
                    $e->setSnippet($this->currentLine);

                    throw $e;
                }
            } else {
                // multiple documents are not supported
                if ('---' === $this->currentLine) {
                    throw new ParseException('Multiple documents are not supported.', $this->currentLineNb + 1, $this->currentLine, $this->filename);
                }

                if ($deprecatedUsage = (isset($this->currentLine[1]) && '?' === $this->currentLine[0] && ' ' === $this->currentLine[1])) {
                    throw new ParseException('Complex mappings are not supported.', $this->getRealCurrentLineNb() + 1, $this->currentLine);
                }

                // 1-liner optionally followed by newline(s)
                if (\is_string($value) && $this->lines[0] === trim($value)) {
                    try {
                        $value = Inline::parse($this->lines[0], $flags, $this->refs);
                    } catch (ParseException $e) {
                        $e->setParsedLine($this->getRealCurrentLineNb() + 1);
                        $e->setSnippet($this->currentLine);

                        throw $e;
                    }

                    return $value;
                }

                // try to parse the value as a multi-line string as a last resort
                if (0 === $this->currentLineNb) {
                    $previousLineWasNewline = false;
                    $previousLineWasTerminatedWithBackslash = false;
                    $value = '';

                    foreach ($this->lines as $line) {
                        if ('' !== ltrim($line) && '#' === ltrim($line)[0]) {
                            continue;
                        }
                        // If the indentation is not consistent at offset 0, it is to be considered as a ParseError
                        if (0 === $this->offset && !$deprecatedUsage && isset($line[0]) && ' ' === $line[0]) {
                            throw new ParseException('Unable to parse.', $this->getRealCurrentLineNb() + 1, $this->currentLine, $this->filename);
                        }

                        if (false !== strpos($line, ': ')) {
                            throw new ParseException('Mapping values are not allowed in multi-line blocks.', $this->getRealCurrentLineNb() + 1, $this->currentLine, $this->filename);
                        }

                        if ('' === trim($line)) {
                            $value .= "\n";
                        } elseif (!$previousLineWasNewline && !$previousLineWasTerminatedWithBackslash) {
                            $value .= ' ';
                        }

                        if ('' !== trim($line) && '\\' === substr($line, -1)) {
                            $value .= ltrim(substr($line, 0, -1));
                        } elseif ('' !== trim($line)) {
                            $value .= trim($line);
                        }

                        if ('' === trim($line)) {
                            $previousLineWasNewline = true;
                            $previousLineWasTerminatedWithBackslash = false;
                        } elseif ('\\' === substr($line, -1)) {
                            $previousLineWasNewline = false;
                            $previousLineWasTerminatedWithBackslash = true;
                        } else {
                            $previousLineWasNewline = false;
                            $previousLineWasTerminatedWithBackslash = false;
                        }
                    }

                    try {
                        return Inline::parse(trim($value));
                    } catch (ParseException $e) {
                        // fall-through to the ParseException thrown below
                    }
                }

                throw new ParseException('Unable to parse.', $this->getRealCurrentLineNb() + 1, $this->currentLine, $this->filename);
            }
        } while ($this->moveToNextLine());

        if (null !== $tag) {
            $data = new TaggedValue($tag, $data);
        }

        if (Yaml::PARSE_OBJECT_FOR_MAP & $flags && !\is_object($data) && 'mapping' === $context) {
            $object = new \stdClass();

            foreach ($data as $key => $value) {
                $object->$key = $value;
            }

            $data = $object;
        }

        return empty($data) ? null : $data;
    }

    private function parseBlock(int $offset, string $yaml, int $flags)
    {
        $skippedLineNumbers = $this->skippedLineNumbers;

        foreach ($this->locallySkippedLineNumbers as $lineNumber) {
            if ($lineNumber < $offset) {
                continue;
            }

            $skippedLineNumbers[] = $lineNumber;
        }

        $parser = new self();
        $parser->offset = $offset;
        $parser->totalNumberOfLines = $this->totalNumberOfLines;
        $parser->skippedLineNumbers = $skippedLineNumbers;
        $parser->refs = &$this->refs;
        $parser->refsBeingParsed = $this->refsBeingParsed;

        return $parser->doParse($yaml, $flags);
    }

    /**
     * Returns the current line number (takes the offset into account).
     *
     * @internal
     *
     * @return int The current line number
     */
    public function getRealCurrentLineNb(): int
    {
        $realCurrentLineNumber = $this->currentLineNb + $this->offset;

        foreach ($this->skippedLineNumbers as $skippedLineNumber) {
            if ($skippedLineNumber > $realCurrentLineNumber) {
                break;
            }

            ++$realCurrentLineNumber;
        }

        return $realCurrentLineNumber;
    }

    /**
     * Returns the current line indentation.
     *
     * @return int The current line indentation
     */
    private function getCurrentLineIndentation(): int
    {
        return \strlen($this->currentLine) - \strlen(ltrim($this->currentLine, ' '));
    }

    /**
     * Returns the next embed block of YAML.
     *
     * @param int|null $indentation The indent level at which the block is to be read, or null for default
     * @param bool     $inSequence  True if the enclosing data structure is a sequence
     *
     * @return string A YAML string
     *
     * @throws ParseException When indentation problem are detected
     */
    private function getNextEmbedBlock(int $indentation = null, bool $inSequence = false): string
    {
        $oldLineIndentation = $this->getCurrentLineIndentation();

        if (!$this->moveToNextLine()) {
            return '';
        }

        if (null === $indentation) {
            $newIndent = null;
            $movements = 0;

            do {
                $EOF = false;

                // empty and comment-like lines do not influence the indentation depth
                if ($this->isCurrentLineEmpty() || $this->isCurrentLineComment()) {
                    $EOF = !$this->moveToNextLine();

                    if (!$EOF) {
                        ++$movements;
                    }
                } else {
                    $newIndent = $this->getCurrentLineIndentation();
                }
            } while (!$EOF && null === $newIndent);

            for ($i = 0; $i < $movements; ++$i) {
                $this->moveToPreviousLine();
            }

            $unindentedEmbedBlock = $this->isStringUnIndentedCollectionItem();

            if (!$this->isCurrentLineEmpty() && 0 === $newIndent && !$unindentedEmbedBlock) {
                throw new ParseException('Indentation problem.', $this->getRealCurrentLineNb() + 1, $this->currentLine, $this->filename);
            }
        } else {
            $newIndent = $indentation;
        }

        $data = [];
        if ($this->getCurrentLineIndentation() >= $newIndent) {
            $data[] = substr($this->currentLine, $newIndent);
        } elseif ($this->isCurrentLineEmpty() || $this->isCurrentLineComment()) {
            $data[] = $this->currentLine;
        } else {
            $this->moveToPreviousLine();

            return '';
        }

        if ($inSequence && $oldLineIndentation === $newIndent && isset($data[0][0]) && '-' === $data[0][0]) {
            // the previous line contained a dash but no item content, this line is a sequence item with the same indentation
            // and therefore no nested list or mapping
            $this->moveToPreviousLine();

            return '';
        }

        $isItUnindentedCollection = $this->isStringUnIndentedCollectionItem();

        while ($this->moveToNextLine()) {
            $indent = $this->getCurrentLineIndentation();

            if ($isItUnindentedCollection && !$this->isCurrentLineEmpty() && !$this->isStringUnIndentedCollectionItem() && $newIndent === $indent) {
                $this->moveToPreviousLine();
                break;
            }

            if ($this->isCurrentLineBlank()) {
                $data[] = substr($this->currentLine, $newIndent);
                continue;
            }

            if ($indent >= $newIndent) {
                $data[] = substr($this->currentLine, $newIndent);
            } elseif ($this->isCurrentLineComment()) {
                $data[] = $this->currentLine;
            } elseif (0 == $indent) {
                $this->moveToPreviousLine();

                break;
            } else {
                throw new ParseException('Indentation problem.', $this->getRealCurrentLineNb() + 1, $this->currentLine, $this->filename);
            }
        }

        return implode("\n", $data);
    }

    /**
     * Moves the parser to the next line.
     */
    private function moveToNextLine(): bool
    {
        if ($this->currentLineNb >= \count($this->lines) - 1) {
            return false;
        }

        $this->currentLine = $this->lines[++$this->currentLineNb];

        return true;
    }

    /**
     * Moves the parser to the previous line.
     */
    private function moveToPreviousLine(): bool
    {
        if ($this->currentLineNb < 1) {
            return false;
        }

        $this->currentLine = $this->lines[--$this->currentLineNb];

        return true;
    }

    /**
     * Parses a YAML value.
     *
     * @param string $value   A YAML value
     * @param int    $flags   A bit field of PARSE_* constants to customize the YAML parser behavior
     * @param string $context The parser context (either sequence or mapping)
     *
     * @return mixed A PHP value
     *
     * @throws ParseException When reference does not exist
     */
    private function parseValue(string $value, int $flags, string $context)
    {
        if (0 === strpos($value, '*')) {
            if (false !== $pos = strpos($value, '#')) {
                $value = substr($value, 1, $pos - 2);
            } else {
                $value = substr($value, 1);
            }

            if (!\array_key_exists($value, $this->refs)) {
                if (false !== $pos = array_search($value, $this->refsBeingParsed, true)) {
                    throw new ParseException(sprintf('Circular reference [%s, %s] detected for reference "%s".', implode(', ', \array_slice($this->refsBeingParsed, $pos)), $value, $value), $this->currentLineNb + 1, $this->currentLine, $this->filename);
                }

                throw new ParseException(sprintf('Reference "%s" does not exist.', $value), $this->currentLineNb + 1, $this->currentLine, $this->filename);
            }

            return $this->refs[$value];
        }

        if (\in_array($value[0], ['!', '|', '>'], true) && self::preg_match('/^(?:'.self::TAG_PATTERN.' +)?'.self::BLOCK_SCALAR_HEADER_PATTERN.'$/', $value, $matches)) {
            $modifiers = isset($matches['modifiers']) ? $matches['modifiers'] : '';

            $data = $this->parseBlockScalar($matches['separator'], preg_replace('#\d+#', '', $modifiers), (int) abs((int) $modifiers));

            if ('' !== $matches['tag'] && '!' !== $matches['tag']) {
                if ('!!binary' === $matches['tag']) {
                    return Inline::evaluateBinaryScalar($data);
                }

                return new TaggedValue(substr($matches['tag'], 1), $data);
            }

            return $data;
        }

        try {
            if ('' !== $value && '{' === $value[0]) {
                return Inline::parse($this->lexInlineMapping($value), $flags, $this->refs);
            } elseif ('' !== $value && '[' === $value[0]) {
                return Inline::parse($this->lexInlineSequence($value), $flags, $this->refs);
            }

            $quotation = '' !== $value && ('"' === $value[0] || "'" === $value[0]) ? $value[0] : null;

            // do not take following lines into account when the current line is a quoted single line value
            if (null !== $quotation && self::preg_match('/^'.$quotation.'.*'.$quotation.'(\s*#.*)?$/', $value)) {
                return Inline::parse($value, $flags, $this->refs);
            }

            $lines = [];

            while ($this->moveToNextLine()) {
                // unquoted strings end before the first unindented line
                if (null === $quotation && 0 === $this->getCurrentLineIndentation()) {
                    $this->moveToPreviousLine();

                    break;
                }

                $lines[] = trim($this->currentLine);

                // quoted string values end with a line that is terminated with the quotation character
                if ('' !== $this->currentLine && substr($this->currentLine, -1) === $quotation) {
                    break;
                }
            }

            for ($i = 0, $linesCount = \count($lines), $previousLineBlank = false; $i < $linesCount; ++$i) {
                if ('' === $lines[$i]) {
                    $value .= "\n";
                    $previousLineBlank = true;
                } elseif ($previousLineBlank) {
                    $value .= $lines[$i];
                    $previousLineBlank = false;
                } else {
                    $value .= ' '.$lines[$i];
                    $previousLineBlank = false;
                }
            }

            Inline::$parsedLineNumber = $this->getRealCurrentLineNb();

            $parsedValue = Inline::parse($value, $flags, $this->refs);

            if ('mapping' === $context && \is_string($parsedValue) && '"' !== $value[0] && "'" !== $value[0] && '[' !== $value[0] && '{' !== $value[0] && '!' !== $value[0] && false !== strpos($parsedValue, ': ')) {
                throw new ParseException('A colon cannot be used in an unquoted mapping value.', $this->getRealCurrentLineNb() + 1, $value, $this->filename);
            }

            return $parsedValue;
        } catch (ParseException $e) {
            $e->setParsedLine($this->getRealCurrentLineNb() + 1);
            $e->setSnippet($this->currentLine);

            throw $e;
        }
    }

    /**
     * Parses a block scalar.
     *
     * @param string $style       The style indicator that was used to begin this block scalar (| or >)
     * @param string $chomping    The chomping indicator that was used to begin this block scalar (+ or -)
     * @param int    $indentation The indentation indicator that was used to begin this block scalar
     */
    private function parseBlockScalar(string $style, string $chomping = '', int $indentation = 0): string
    {
        $notEOF = $this->moveToNextLine();
        if (!$notEOF) {
            return '';
        }

        $isCurrentLineBlank = $this->isCurrentLineBlank();
        $blockLines = [];

        // leading blank lines are consumed before determining indentation
        while ($notEOF && $isCurrentLineBlank) {
            // newline only if not EOF
            if ($notEOF = $this->moveToNextLine()) {
                $blockLines[] = '';
                $isCurrentLineBlank = $this->isCurrentLineBlank();
            }
        }

        // determine indentation if not specified
        if (0 === $indentation) {
            $currentLineLength = \strlen($this->currentLine);

            for ($i = 0; $i < $currentLineLength && ' ' === $this->currentLine[$i]; ++$i) {
                ++$indentation;
            }
        }

        if ($indentation > 0) {
            $pattern = sprintf('/^ {%d}(.*)$/', $indentation);

            while (
                $notEOF && (
                    $isCurrentLineBlank ||
                    self::preg_match($pattern, $this->currentLine, $matches)
                )
            ) {
                if ($isCurrentLineBlank && \strlen($this->currentLine) > $indentation) {
                    $blockLines[] = substr($this->currentLine, $indentation);
                } elseif ($isCurrentLineBlank) {
                    $blockLines[] = '';
                } else {
                    $blockLines[] = $matches[1];
                }

                // newline only if not EOF
                if ($notEOF = $this->moveToNextLine()) {
                    $isCurrentLineBlank = $this->isCurrentLineBlank();
                }
            }
        } elseif ($notEOF) {
            $blockLines[] = '';
        }

        if ($notEOF) {
            $blockLines[] = '';
            $this->moveToPreviousLine();
        } elseif (!$notEOF && !$this->isCurrentLineLastLineInDocument()) {
            $blockLines[] = '';
        }

        // folded style
        if ('>' === $style) {
            $text = '';
            $previousLineIndented = false;
            $previousLineBlank = false;

            for ($i = 0, $blockLinesCount = \count($blockLines); $i < $blockLinesCount; ++$i) {
                if ('' === $blockLines[$i]) {
                    $text .= "\n";
                    $previousLineIndented = false;
                    $previousLineBlank = true;
                } elseif (' ' === $blockLines[$i][0]) {
                    $text .= "\n".$blockLines[$i];
                    $previousLineIndented = true;
                    $previousLineBlank = false;
                } elseif ($previousLineIndented) {
                    $text .= "\n".$blockLines[$i];
                    $previousLineIndented = false;
                    $previousLineBlank = false;
                } elseif ($previousLineBlank || 0 === $i) {
                    $text .= $blockLines[$i];
                    $previousLineIndented = false;
                    $previousLineBlank = false;
                } else {
                    $text .= ' '.$blockLines[$i];
                    $previousLineIndented = false;
                    $previousLineBlank = false;
                }
            }
        } else {
            $text = implode("\n", $blockLines);
        }

        // deal with trailing newlines
        if ('' === $chomping) {
            $text = preg_replace('/\n+$/', "\n", $text);
        } elseif ('-' === $chomping) {
            $text = preg_replace('/\n+$/', '', $text);
        }

        return $text;
    }

    /**
     * Returns true if the next line is indented.
     *
     * @return bool Returns true if the next line is indented, false otherwise
     */
    private function isNextLineIndented(): bool
    {
        $currentIndentation = $this->getCurrentLineIndentation();
        $movements = 0;

        do {
            $EOF = !$this->moveToNextLine();

            if (!$EOF) {
                ++$movements;
            }
        } while (!$EOF && ($this->isCurrentLineEmpty() || $this->isCurrentLineComment()));

        if ($EOF) {
            return false;
        }

        $ret = $this->getCurrentLineIndentation() > $currentIndentation;

        for ($i = 0; $i < $movements; ++$i) {
            $this->moveToPreviousLine();
        }

        return $ret;
    }

    /**
     * Returns true if the current line is blank or if it is a comment line.
     *
     * @return bool Returns true if the current line is empty or if it is a comment line, false otherwise
     */
    private function isCurrentLineEmpty(): bool
    {
        return $this->isCurrentLineBlank() || $this->isCurrentLineComment();
    }

    /**
     * Returns true if the current line is blank.
     *
     * @return bool Returns true if the current line is blank, false otherwise
     */
    private function isCurrentLineBlank(): bool
    {
        return '' == trim($this->currentLine, ' ');
    }

    /**
     * Returns true if the current line is a comment line.
     *
     * @return bool Returns true if the current line is a comment line, false otherwise
     */
    private function isCurrentLineComment(): bool
    {
        //checking explicitly the first char of the trim is faster than loops or strpos
        $ltrimmedLine = ltrim($this->currentLine, ' ');

        return '' !== $ltrimmedLine && '#' === $ltrimmedLine[0];
    }

    private function isCurrentLineLastLineInDocument(): bool
    {
        return ($this->offset + $this->currentLineNb) >= ($this->totalNumberOfLines - 1);
    }

    /**
     * Cleanups a YAML string to be parsed.
     *
     * @param string $value The input YAML string
     *
     * @return string A cleaned up YAML string
     */
    private function cleanup(string $value): string
    {
        $value = str_replace(["\r\n", "\r"], "\n", $value);

        // strip YAML header
        $count = 0;
        $value = preg_replace('#^\%YAML[: ][\d\.]+.*\n#u', '', $value, -1, $count);
        $this->offset += $count;

        // remove leading comments
        $trimmedValue = preg_replace('#^(\#.*?\n)+#s', '', $value, -1, $count);
        if (1 === $count) {
            // items have been removed, update the offset
            $this->offset += substr_count($value, "\n") - substr_count($trimmedValue, "\n");
            $value = $trimmedValue;
        }

        // remove start of the document marker (---)
        $trimmedValue = preg_replace('#^\-\-\-.*?\n#s', '', $value, -1, $count);
        if (1 === $count) {
            // items have been removed, update the offset
            $this->offset += substr_count($value, "\n") - substr_count($trimmedValue, "\n");
            $value = $trimmedValue;

            // remove end of the document marker (...)
            $value = preg_replace('#\.\.\.\s*$#', '', $value);
        }

        return $value;
    }

    /**
     * Returns true if the next line starts unindented collection.
     *
     * @return bool Returns true if the next line starts unindented collection, false otherwise
     */
    private function isNextLineUnIndentedCollection(): bool
    {
        $currentIndentation = $this->getCurrentLineIndentation();
        $movements = 0;

        do {
            $EOF = !$this->moveToNextLine();

            if (!$EOF) {
                ++$movements;
            }
        } while (!$EOF && ($this->isCurrentLineEmpty() || $this->isCurrentLineComment()));

        if ($EOF) {
            return false;
        }

        $ret = $this->getCurrentLineIndentation() === $currentIndentation && $this->isStringUnIndentedCollectionItem();

        for ($i = 0; $i < $movements; ++$i) {
            $this->moveToPreviousLine();
        }

        return $ret;
    }

    /**
     * Returns true if the string is un-indented collection item.
     *
     * @return bool Returns true if the string is un-indented collection item, false otherwise
     */
    private function isStringUnIndentedCollectionItem(): bool
    {
        return '-' === rtrim($this->currentLine) || 0 === strpos($this->currentLine, '- ');
    }

    /**
     * A local wrapper for "preg_match" which will throw a ParseException if there
     * is an internal error in the PCRE engine.
     *
     * This avoids us needing to check for "false" every time PCRE is used
     * in the YAML engine
     *
     * @throws ParseException on a PCRE internal error
     *
     * @see preg_last_error()
     *
     * @internal
     */
    public static function preg_match(string $pattern, string $subject, array &$matches = null, int $flags = 0, int $offset = 0): int
    {
        if (false === $ret = preg_match($pattern, $subject, $matches, $flags, $offset)) {
            switch (preg_last_error()) {
                case PREG_INTERNAL_ERROR:
                    $error = 'Internal PCRE error.';
                    break;
                case PREG_BACKTRACK_LIMIT_ERROR:
                    $error = 'pcre.backtrack_limit reached.';
                    break;
                case PREG_RECURSION_LIMIT_ERROR:
                    $error = 'pcre.recursion_limit reached.';
                    break;
                case PREG_BAD_UTF8_ERROR:
                    $error = 'Malformed UTF-8 data.';
                    break;
                case PREG_BAD_UTF8_OFFSET_ERROR:
                    $error = 'Offset doesn\'t correspond to the begin of a valid UTF-8 code point.';
                    break;
                default:
                    $error = 'Error.';
            }

            throw new ParseException($error);
        }

        return $ret;
    }

    /**
     * Trim the tag on top of the value.
     *
     * Prevent values such as "!foo {quz: bar}" to be considered as
     * a mapping block.
     */
    private function trimTag(string $value): string
    {
        if ('!' === $value[0]) {
            return ltrim(substr($value, 1, strcspn($value, " \r\n", 1)), ' ');
        }

        return $value;
    }

    private function getLineTag(string $value, int $flags, bool $nextLineCheck = true): ?string
    {
        if ('' === $value || '!' !== $value[0] || 1 !== self::preg_match('/^'.self::TAG_PATTERN.' *( +#.*)?$/', $value, $matches)) {
            return null;
        }

        if ($nextLineCheck && !$this->isNextLineIndented()) {
            return null;
        }

        $tag = substr($matches['tag'], 1);

        // Built-in tags
        if ($tag && '!' === $tag[0]) {
            throw new ParseException(sprintf('The built-in tag "!%s" is not implemented.', $tag), $this->getRealCurrentLineNb() + 1, $value, $this->filename);
        }

        if (Yaml::PARSE_CUSTOM_TAGS & $flags) {
            return $tag;
        }

        throw new ParseException(sprintf('Tags support is not enabled. You must use the flag "Yaml::PARSE_CUSTOM_TAGS" to use "%s".', $matches['tag']), $this->getRealCurrentLineNb() + 1, $value, $this->filename);
    }

    private function parseQuotedString(string $yaml): ?string
    {
        if ('' === $yaml || ('"' !== $yaml[0] && "'" !== $yaml[0])) {
            throw new \InvalidArgumentException(sprintf('"%s" is not a quoted string.', $yaml));
        }

        $lines = [$yaml];

        while ($this->moveToNextLine()) {
            $lines[] = $this->currentLine;

            if (!$this->isCurrentLineEmpty() && $yaml[0] === $this->currentLine[-1]) {
                break;
            }
        }

        $value = '';

        for ($i = 0, $linesCount = \count($lines), $previousLineWasNewline = false, $previousLineWasTerminatedWithBackslash = false; $i < $linesCount; ++$i) {
            if ('' === trim($lines[$i])) {
                $value .= "\n";
            } elseif (!$previousLineWasNewline && !$previousLineWasTerminatedWithBackslash) {
                $value .= ' ';
            }

            if ('' !== trim($lines[$i]) && '\\' === substr($lines[$i], -1)) {
                $value .= ltrim(substr($lines[$i], 0, -1));
            } elseif ('' !== trim($lines[$i])) {
                $value .= trim($lines[$i]);
            }

            if ('' === trim($lines[$i])) {
                $previousLineWasNewline = true;
                $previousLineWasTerminatedWithBackslash = false;
            } elseif ('\\' === substr($lines[$i], -1)) {
                $previousLineWasNewline = false;
                $previousLineWasTerminatedWithBackslash = true;
            } else {
                $previousLineWasNewline = false;
                $previousLineWasTerminatedWithBackslash = false;
            }
        }

        return $value;

        for ($i = 1; isset($yaml[$i]) && $quotation !== $yaml[$i]; ++$i) {
        }

        // quoted single line string
        if (isset($yaml[$i]) && $quotation === $yaml[$i]) {
            return $yaml;
        }

        $lines = [$yaml];

        while ($this->moveToNextLine()) {
            for ($i = 1; isset($this->currentLine[$i]) && $quotation !== $this->currentLine[$i]; ++$i) {
            }

            $lines[] = trim($this->currentLine);

            if (isset($this->currentLine[$i]) && $quotation === $this->currentLine[$i]) {
                break;
            }
        }
    }

    private function lexInlineMapping(string $yaml): string
    {
        if ('' === $yaml || '{' !== $yaml[0]) {
            throw new \InvalidArgumentException(sprintf('"%s" is not a sequence.', $yaml));
        }

        for ($i = 1; isset($yaml[$i]) && '}' !== $yaml[$i]; ++$i) {
        }

        if (isset($yaml[$i]) && '}' === $yaml[$i]) {
            return $yaml;
        }

        $lines = [$yaml];

        while ($this->moveToNextLine()) {
            $lines[] = $this->currentLine;
        }

        return implode("\n", $lines);
    }

    private function lexInlineSequence(string $yaml): string
    {
        if ('' === $yaml || '[' !== $yaml[0]) {
            throw new \InvalidArgumentException(sprintf('"%s" is not a sequence.', $yaml));
        }

        for ($i = 1; isset($yaml[$i]) && ']' !== $yaml[$i]; ++$i) {
        }

        if (isset($yaml[$i]) && ']' === $yaml[$i]) {
            return $yaml;
        }

        $value = $yaml;

        while ($this->moveToNextLine()) {
            for ($i = 1; isset($this->currentLine[$i]) && ']' !== $this->currentLine[$i]; ++$i) {
            }

            $value .= trim($this->currentLine);

            if (isset($this->currentLine[$i]) && ']' === $this->currentLine[$i]) {
                break;
            }
        }

        return $value;
    }
}
PKϤ$Zn��%��yaml/Tag/TaggedValue.phpnu�[���<?php

/*
 * This file is part of the Symfony package.
 *
 * (c) Fabien Potencier <fabien@symfony.com>
 *
 * For the full copyright and license information, please view the LICENSE
 * file that was distributed with this source code.
 */

namespace Symfony\Component\Yaml\Tag;

/**
 * @author Nicolas Grekas <p@tchwork.com>
 * @author Guilhem N. <egetick@gmail.com>
 */
final class TaggedValue
{
    private $tag;
    private $value;

    public function __construct(string $tag, $value)
    {
        $this->tag = $tag;
        $this->value = $value;
    }

    public function getTag(): string
    {
        return $this->tag;
    }

    public function getValue()
    {
        return $this->value;
    }
}
PKϤ$Z԰�""yaml/Unescaper.phpnu�[���<?php

/*
 * This file is part of the Symfony package.
 *
 * (c) Fabien Potencier <fabien@symfony.com>
 *
 * For the full copyright and license information, please view the LICENSE
 * file that was distributed with this source code.
 */

namespace Symfony\Component\Yaml;

use Symfony\Component\Yaml\Exception\ParseException;

/**
 * Unescaper encapsulates unescaping rules for single and double-quoted
 * YAML strings.
 *
 * @author Matthew Lewinski <matthew@lewinski.org>
 *
 * @internal
 */
class Unescaper
{
    /**
     * Regex fragment that matches an escaped character in a double quoted string.
     */
    const REGEX_ESCAPED_CHARACTER = '\\\\(x[0-9a-fA-F]{2}|u[0-9a-fA-F]{4}|U[0-9a-fA-F]{8}|.)';

    /**
     * Unescapes a single quoted string.
     *
     * @param string $value A single quoted string
     *
     * @return string The unescaped string
     */
    public function unescapeSingleQuotedString(string $value): string
    {
        return str_replace('\'\'', '\'', $value);
    }

    /**
     * Unescapes a double quoted string.
     *
     * @param string $value A double quoted string
     *
     * @return string The unescaped string
     */
    public function unescapeDoubleQuotedString(string $value): string
    {
        $callback = function ($match) {
            return $this->unescapeCharacter($match[0]);
        };

        // evaluate the string
        return preg_replace_callback('/'.self::REGEX_ESCAPED_CHARACTER.'/u', $callback, $value);
    }

    /**
     * Unescapes a character that was found in a double-quoted string.
     *
     * @param string $value An escaped character
     *
     * @return string The unescaped character
     */
    private function unescapeCharacter(string $value): string
    {
        switch ($value[1]) {
            case '0':
                return "\x0";
            case 'a':
                return "\x7";
            case 'b':
                return "\x8";
            case 't':
                return "\t";
            case "\t":
                return "\t";
            case 'n':
                return "\n";
            case 'v':
                return "\xB";
            case 'f':
                return "\xC";
            case 'r':
                return "\r";
            case 'e':
                return "\x1B";
            case ' ':
                return ' ';
            case '"':
                return '"';
            case '/':
                return '/';
            case '\\':
                return '\\';
            case 'N':
                // U+0085 NEXT LINE
                return "\xC2\x85";
            case '_':
                // U+00A0 NO-BREAK SPACE
                return "\xC2\xA0";
            case 'L':
                // U+2028 LINE SEPARATOR
                return "\xE2\x80\xA8";
            case 'P':
                // U+2029 PARAGRAPH SEPARATOR
                return "\xE2\x80\xA9";
            case 'x':
                return self::utf8chr(hexdec(substr($value, 2, 2)));
            case 'u':
                return self::utf8chr(hexdec(substr($value, 2, 4)));
            case 'U':
                return self::utf8chr(hexdec(substr($value, 2, 8)));
            default:
                throw new ParseException(sprintf('Found unknown escape character "%s".', $value));
        }
    }

    /**
     * Get the UTF-8 character for the given code point.
     */
    private static function utf8chr(int $c): string
    {
        if (0x80 > $c %= 0x200000) {
            return \chr($c);
        }
        if (0x800 > $c) {
            return \chr(0xC0 | $c >> 6).\chr(0x80 | $c & 0x3F);
        }
        if (0x10000 > $c) {
            return \chr(0xE0 | $c >> 12).\chr(0x80 | $c >> 6 & 0x3F).\chr(0x80 | $c & 0x3F);
        }

        return \chr(0xF0 | $c >> 18).\chr(0x80 | $c >> 12 & 0x3F).\chr(0x80 | $c >> 6 & 0x3F).\chr(0x80 | $c & 0x3F);
    }
}
PKϤ$Z���HRRyaml/Dumper.phpnu�[���<?php

/*
 * This file is part of the Symfony package.
 *
 * (c) Fabien Potencier <fabien@symfony.com>
 *
 * For the full copyright and license information, please view the LICENSE
 * file that was distributed with this source code.
 */

namespace Symfony\Component\Yaml;

use Symfony\Component\Yaml\Tag\TaggedValue;

/**
 * Dumper dumps PHP variables to YAML strings.
 *
 * @author Fabien Potencier <fabien@symfony.com>
 *
 * @final
 */
class Dumper
{
    /**
     * The amount of spaces to use for indentation of nested nodes.
     *
     * @var int
     */
    protected $indentation;

    public function __construct(int $indentation = 4)
    {
        if ($indentation < 1) {
            throw new \InvalidArgumentException('The indentation must be greater than zero.');
        }

        $this->indentation = $indentation;
    }

    /**
     * Dumps a PHP value to YAML.
     *
     * @param mixed $input  The PHP value
     * @param int   $inline The level where you switch to inline YAML
     * @param int   $indent The level of indentation (used internally)
     * @param int   $flags  A bit field of Yaml::DUMP_* constants to customize the dumped YAML string
     *
     * @return string The YAML representation of the PHP value
     */
    public function dump($input, int $inline = 0, int $indent = 0, int $flags = 0): string
    {
        $output = '';
        $prefix = $indent ? str_repeat(' ', $indent) : '';
        $dumpObjectAsInlineMap = true;

        if (Yaml::DUMP_OBJECT_AS_MAP & $flags && ($input instanceof \ArrayObject || $input instanceof \stdClass)) {
            $dumpObjectAsInlineMap = empty((array) $input);
        }

        if ($inline <= 0 || (!\is_array($input) && !$input instanceof TaggedValue && $dumpObjectAsInlineMap) || empty($input)) {
            $output .= $prefix.Inline::dump($input, $flags);
        } else {
            $dumpAsMap = Inline::isHash($input);

            foreach ($input as $key => $value) {
                if ($inline >= 1 && Yaml::DUMP_MULTI_LINE_LITERAL_BLOCK & $flags && \is_string($value) && false !== strpos($value, "\n") && false === strpos($value, "\r")) {
                    // If the first line starts with a space character, the spec requires a blockIndicationIndicator
                    // http://www.yaml.org/spec/1.2/spec.html#id2793979
                    $blockIndentationIndicator = (' ' === substr($value, 0, 1)) ? (string) $this->indentation : '';
                    $output .= sprintf("%s%s%s |%s\n", $prefix, $dumpAsMap ? Inline::dump($key, $flags).':' : '-', '', $blockIndentationIndicator);

                    foreach (explode("\n", $value) as $row) {
                        $output .= sprintf("%s%s%s\n", $prefix, str_repeat(' ', $this->indentation), $row);
                    }

                    continue;
                }

                if ($value instanceof TaggedValue) {
                    $output .= sprintf('%s%s !%s', $prefix, $dumpAsMap ? Inline::dump($key, $flags).':' : '-', $value->getTag());

                    if ($inline >= 1 && Yaml::DUMP_MULTI_LINE_LITERAL_BLOCK & $flags && \is_string($value->getValue()) && false !== strpos($value->getValue(), "\n") && false === strpos($value->getValue(), "\r\n")) {
                        // If the first line starts with a space character, the spec requires a blockIndicationIndicator
                        // http://www.yaml.org/spec/1.2/spec.html#id2793979
                        $blockIndentationIndicator = (' ' === substr($value->getValue(), 0, 1)) ? (string) $this->indentation : '';
                        $output .= sprintf(" |%s\n", $blockIndentationIndicator);

                        foreach (explode("\n", $value->getValue()) as $row) {
                            $output .= sprintf("%s%s%s\n", $prefix, str_repeat(' ', $this->indentation), $row);
                        }

                        continue;
                    }

                    if ($inline - 1 <= 0 || null === $value->getValue() || is_scalar($value->getValue())) {
                        $output .= ' '.$this->dump($value->getValue(), $inline - 1, 0, $flags)."\n";
                    } else {
                        $output .= "\n";
                        $output .= $this->dump($value->getValue(), $inline - 1, $dumpAsMap ? $indent + $this->indentation : $indent + 2, $flags);
                    }

                    continue;
                }

                $dumpObjectAsInlineMap = true;

                if (Yaml::DUMP_OBJECT_AS_MAP & $flags && ($value instanceof \ArrayObject || $value instanceof \stdClass)) {
                    $dumpObjectAsInlineMap = empty((array) $value);
                }

                $willBeInlined = $inline - 1 <= 0 || !\is_array($value) && $dumpObjectAsInlineMap || empty($value);

                $output .= sprintf('%s%s%s%s',
                    $prefix,
                    $dumpAsMap ? Inline::dump($key, $flags).':' : '-',
                    $willBeInlined ? ' ' : "\n",
                    $this->dump($value, $inline - 1, $willBeInlined ? 0 : $indent + $this->indentation, $flags)
                ).($willBeInlined ? "\n" : '');
            }
        }

        return $output;
    }
}
PKϤ$ZX3� � yaml/Command/LintCommand.phpnu�[���<?php

/*
 * This file is part of the Symfony package.
 *
 * (c) Fabien Potencier <fabien@symfony.com>
 *
 * For the full copyright and license information, please view the LICENSE
 * file that was distributed with this source code.
 */

namespace Symfony\Component\Yaml\Command;

use Symfony\Component\Console\Command\Command;
use Symfony\Component\Console\Exception\InvalidArgumentException;
use Symfony\Component\Console\Exception\RuntimeException;
use Symfony\Component\Console\Input\InputArgument;
use Symfony\Component\Console\Input\InputInterface;
use Symfony\Component\Console\Input\InputOption;
use Symfony\Component\Console\Output\OutputInterface;
use Symfony\Component\Console\Style\SymfonyStyle;
use Symfony\Component\Yaml\Exception\ParseException;
use Symfony\Component\Yaml\Parser;
use Symfony\Component\Yaml\Yaml;

/**
 * Validates YAML files syntax and outputs encountered errors.
 *
 * @author Grégoire Pineau <lyrixx@lyrixx.info>
 * @author Robin Chalas <robin.chalas@gmail.com>
 */
class LintCommand extends Command
{
    protected static $defaultName = 'lint:yaml';

    private $parser;
    private $format;
    private $displayCorrectFiles;
    private $directoryIteratorProvider;
    private $isReadableProvider;

    public function __construct(string $name = null, callable $directoryIteratorProvider = null, callable $isReadableProvider = null)
    {
        parent::__construct($name);

        $this->directoryIteratorProvider = $directoryIteratorProvider;
        $this->isReadableProvider = $isReadableProvider;
    }

    /**
     * {@inheritdoc}
     */
    protected function configure()
    {
        $this
            ->setDescription('Lints a file and outputs encountered errors')
            ->addArgument('filename', InputArgument::IS_ARRAY, 'A file, a directory or "-" for reading from STDIN')
            ->addOption('format', null, InputOption::VALUE_REQUIRED, 'The output format', 'txt')
            ->addOption('parse-tags', null, InputOption::VALUE_NONE, 'Parse custom tags')
            ->setHelp(<<<EOF
The <info>%command.name%</info> command lints a YAML file and outputs to STDOUT
the first encountered syntax error.

You can validates YAML contents passed from STDIN:

  <info>cat filename | php %command.full_name% -</info>

You can also validate the syntax of a file:

  <info>php %command.full_name% filename</info>

Or of a whole directory:

  <info>php %command.full_name% dirname</info>
  <info>php %command.full_name% dirname --format=json</info>

EOF
            )
        ;
    }

    protected function execute(InputInterface $input, OutputInterface $output)
    {
        $io = new SymfonyStyle($input, $output);
        $filenames = (array) $input->getArgument('filename');
        $this->format = $input->getOption('format');
        $this->displayCorrectFiles = $output->isVerbose();
        $flags = $input->getOption('parse-tags') ? Yaml::PARSE_CUSTOM_TAGS : 0;

        if (['-'] === $filenames) {
            return $this->display($io, [$this->validate(file_get_contents('php://stdin'), $flags)]);
        }

        if (!$filenames) {
            throw new RuntimeException('Please provide a filename or pipe file content to STDIN.');
        }

        $filesInfo = [];
        foreach ($filenames as $filename) {
            if (!$this->isReadable($filename)) {
                throw new RuntimeException(sprintf('File or directory "%s" is not readable.', $filename));
            }

            foreach ($this->getFiles($filename) as $file) {
                $filesInfo[] = $this->validate(file_get_contents($file), $flags, $file);
            }
        }

        return $this->display($io, $filesInfo);
    }

    private function validate(string $content, int $flags, string $file = null)
    {
        $prevErrorHandler = set_error_handler(function ($level, $message, $file, $line) use (&$prevErrorHandler) {
            if (E_USER_DEPRECATED === $level) {
                throw new ParseException($message, $this->getParser()->getRealCurrentLineNb() + 1);
            }

            return $prevErrorHandler ? $prevErrorHandler($level, $message, $file, $line) : false;
        });

        try {
            $this->getParser()->parse($content, Yaml::PARSE_CONSTANT | $flags);
        } catch (ParseException $e) {
            return ['file' => $file, 'line' => $e->getParsedLine(), 'valid' => false, 'message' => $e->getMessage()];
        } finally {
            restore_error_handler();
        }

        return ['file' => $file, 'valid' => true];
    }

    private function display(SymfonyStyle $io, array $files): int
    {
        switch ($this->format) {
            case 'txt':
                return $this->displayTxt($io, $files);
            case 'json':
                return $this->displayJson($io, $files);
            default:
                throw new InvalidArgumentException(sprintf('The format "%s" is not supported.', $this->format));
        }
    }

    private function displayTxt(SymfonyStyle $io, array $filesInfo): int
    {
        $countFiles = \count($filesInfo);
        $erroredFiles = 0;
        $suggestTagOption = false;

        foreach ($filesInfo as $info) {
            if ($info['valid'] && $this->displayCorrectFiles) {
                $io->comment('<info>OK</info>'.($info['file'] ? sprintf(' in %s', $info['file']) : ''));
            } elseif (!$info['valid']) {
                ++$erroredFiles;
                $io->text('<error> ERROR </error>'.($info['file'] ? sprintf(' in %s', $info['file']) : ''));
                $io->text(sprintf('<error> >> %s</error>', $info['message']));

                if (false !== strpos($info['message'], 'PARSE_CUSTOM_TAGS')) {
                    $suggestTagOption = true;
                }
            }
        }

        if (0 === $erroredFiles) {
            $io->success(sprintf('All %d YAML files contain valid syntax.', $countFiles));
        } else {
            $io->warning(sprintf('%d YAML files have valid syntax and %d contain errors.%s', $countFiles - $erroredFiles, $erroredFiles, $suggestTagOption ? ' Use the --parse-tags option if you want parse custom tags.' : ''));
        }

        return min($erroredFiles, 1);
    }

    private function displayJson(SymfonyStyle $io, array $filesInfo): int
    {
        $errors = 0;

        array_walk($filesInfo, function (&$v) use (&$errors) {
            $v['file'] = (string) $v['file'];
            if (!$v['valid']) {
                ++$errors;
            }

            if (isset($v['message']) && false !== strpos($v['message'], 'PARSE_CUSTOM_TAGS')) {
                $v['message'] .= ' Use the --parse-tags option if you want parse custom tags.';
            }
        });

        $io->writeln(json_encode($filesInfo, JSON_PRETTY_PRINT | JSON_UNESCAPED_SLASHES));

        return min($errors, 1);
    }

    private function getFiles(string $fileOrDirectory): iterable
    {
        if (is_file($fileOrDirectory)) {
            yield new \SplFileInfo($fileOrDirectory);

            return;
        }

        foreach ($this->getDirectoryIterator($fileOrDirectory) as $file) {
            if (!\in_array($file->getExtension(), ['yml', 'yaml'])) {
                continue;
            }

            yield $file;
        }
    }

    private function getParser(): Parser
    {
        if (!$this->parser) {
            $this->parser = new Parser();
        }

        return $this->parser;
    }

    private function getDirectoryIterator(string $directory): iterable
    {
        $default = function ($directory) {
            return new \RecursiveIteratorIterator(
                new \RecursiveDirectoryIterator($directory, \FilesystemIterator::SKIP_DOTS | \FilesystemIterator::FOLLOW_SYMLINKS),
                \RecursiveIteratorIterator::LEAVES_ONLY
            );
        };

        if (null !== $this->directoryIteratorProvider) {
            return ($this->directoryIteratorProvider)($directory, $default);
        }

        return $default($directory);
    }

    private function isReadable(string $fileOrDirectory): bool
    {
        $default = function ($fileOrDirectory) {
            return is_readable($fileOrDirectory);
        };

        if (null !== $this->isReadableProvider) {
            return ($this->isReadableProvider)($fileOrDirectory, $default);
        }

        return $default($fileOrDirectory);
    }
}
PKϤ$Z�p����yaml/README.mdnu�[���Yaml Component
==============

The Yaml component loads and dumps YAML files.

Resources
---------

  * [Documentation](https://symfony.com/doc/current/components/yaml.html)
  * [Contributing](https://symfony.com/doc/current/contributing/index.html)
  * [Report issues](https://github.com/symfony/symfony/issues) and
    [send Pull Requests](https://github.com/symfony/symfony/pulls)
    in the [main Symfony repository](https://github.com/symfony/symfony)
PKϤ$Z�ʭ��yaml/Escaper.phpnu�[���<?php

/*
 * This file is part of the Symfony package.
 *
 * (c) Fabien Potencier <fabien@symfony.com>
 *
 * For the full copyright and license information, please view the LICENSE
 * file that was distributed with this source code.
 */

namespace Symfony\Component\Yaml;

/**
 * Escaper encapsulates escaping rules for single and double-quoted
 * YAML strings.
 *
 * @author Matthew Lewinski <matthew@lewinski.org>
 *
 * @internal
 */
class Escaper
{
    // Characters that would cause a dumped string to require double quoting.
    const REGEX_CHARACTER_TO_ESCAPE = "[\\x00-\\x1f]|\x7f|\xc2\x85|\xc2\xa0|\xe2\x80\xa8|\xe2\x80\xa9";

    // Mapping arrays for escaping a double quoted string. The backslash is
    // first to ensure proper escaping because str_replace operates iteratively
    // on the input arrays. This ordering of the characters avoids the use of strtr,
    // which performs more slowly.
    private static $escapees = ['\\', '\\\\', '\\"', '"',
                                     "\x00",  "\x01",  "\x02",  "\x03",  "\x04",  "\x05",  "\x06",  "\x07",
                                     "\x08",  "\x09",  "\x0a",  "\x0b",  "\x0c",  "\x0d",  "\x0e",  "\x0f",
                                     "\x10",  "\x11",  "\x12",  "\x13",  "\x14",  "\x15",  "\x16",  "\x17",
                                     "\x18",  "\x19",  "\x1a",  "\x1b",  "\x1c",  "\x1d",  "\x1e",  "\x1f",
                                     "\x7f",
                                     "\xc2\x85", "\xc2\xa0", "\xe2\x80\xa8", "\xe2\x80\xa9",
                               ];
    private static $escaped = ['\\\\', '\\"', '\\\\', '\\"',
                                     '\\0',   '\\x01', '\\x02', '\\x03', '\\x04', '\\x05', '\\x06', '\\a',
                                     '\\b',   '\\t',   '\\n',   '\\v',   '\\f',   '\\r',   '\\x0e', '\\x0f',
                                     '\\x10', '\\x11', '\\x12', '\\x13', '\\x14', '\\x15', '\\x16', '\\x17',
                                     '\\x18', '\\x19', '\\x1a', '\\e',   '\\x1c', '\\x1d', '\\x1e', '\\x1f',
                                     '\\x7f',
                                     '\\N', '\\_', '\\L', '\\P',
                              ];

    /**
     * Determines if a PHP value would require double quoting in YAML.
     *
     * @param string $value A PHP value
     *
     * @return bool True if the value would require double quotes
     */
    public static function requiresDoubleQuoting(string $value): bool
    {
        return 0 < preg_match('/'.self::REGEX_CHARACTER_TO_ESCAPE.'/u', $value);
    }

    /**
     * Escapes and surrounds a PHP value with double quotes.
     *
     * @param string $value A PHP value
     *
     * @return string The quoted, escaped string
     */
    public static function escapeWithDoubleQuotes(string $value): string
    {
        return sprintf('"%s"', str_replace(self::$escapees, self::$escaped, $value));
    }

    /**
     * Determines if a PHP value would require single quoting in YAML.
     *
     * @param string $value A PHP value
     *
     * @return bool True if the value would require single quotes
     */
    public static function requiresSingleQuoting(string $value): bool
    {
        // Determines if a PHP value is entirely composed of a value that would
        // require single quoting in YAML.
        if (\in_array(strtolower($value), ['null', '~', 'true', 'false', 'y', 'n', 'yes', 'no', 'on', 'off'])) {
            return true;
        }

        // Determines if the PHP value contains any single characters that would
        // cause it to require single quoting in YAML.
        return 0 < preg_match('/[ \s \' " \: \{ \} \[ \] , & \* \# \?] | \A[ \- ? | < > = ! % @ ` ]/x', $value);
    }

    /**
     * Escapes and surrounds a PHP value with single quotes.
     *
     * @param string $value A PHP value
     *
     * @return string The quoted, escaped string
     */
    public static function escapeWithSingleQuotes(string $value): string
    {
        return sprintf("'%s'", str_replace('\'', '\'\'', $value));
    }
}
PKϤ$Z�t�J��!yaml/Exception/ParseException.phpnu�[���<?php

/*
 * This file is part of the Symfony package.
 *
 * (c) Fabien Potencier <fabien@symfony.com>
 *
 * For the full copyright and license information, please view the LICENSE
 * file that was distributed with this source code.
 */

namespace Symfony\Component\Yaml\Exception;

/**
 * Exception class thrown when an error occurs during parsing.
 *
 * @author Fabien Potencier <fabien@symfony.com>
 */
class ParseException extends RuntimeException
{
    private $parsedFile;
    private $parsedLine;
    private $snippet;
    private $rawMessage;

    /**
     * @param string          $message    The error message
     * @param int             $parsedLine The line where the error occurred
     * @param string|null     $snippet    The snippet of code near the problem
     * @param string|null     $parsedFile The file name where the error occurred
     * @param \Exception|null $previous   The previous exception
     */
    public function __construct(string $message, int $parsedLine = -1, string $snippet = null, string $parsedFile = null, \Throwable $previous = null)
    {
        $this->parsedFile = $parsedFile;
        $this->parsedLine = $parsedLine;
        $this->snippet = $snippet;
        $this->rawMessage = $message;

        $this->updateRepr();

        parent::__construct($this->message, 0, $previous);
    }

    /**
     * Gets the snippet of code near the error.
     *
     * @return string The snippet of code
     */
    public function getSnippet()
    {
        return $this->snippet;
    }

    /**
     * Sets the snippet of code near the error.
     */
    public function setSnippet(string $snippet)
    {
        $this->snippet = $snippet;

        $this->updateRepr();
    }

    /**
     * Gets the filename where the error occurred.
     *
     * This method returns null if a string is parsed.
     *
     * @return string The filename
     */
    public function getParsedFile()
    {
        return $this->parsedFile;
    }

    /**
     * Sets the filename where the error occurred.
     */
    public function setParsedFile(string $parsedFile)
    {
        $this->parsedFile = $parsedFile;

        $this->updateRepr();
    }

    /**
     * Gets the line where the error occurred.
     *
     * @return int The file line
     */
    public function getParsedLine()
    {
        return $this->parsedLine;
    }

    /**
     * Sets the line where the error occurred.
     */
    public function setParsedLine(int $parsedLine)
    {
        $this->parsedLine = $parsedLine;

        $this->updateRepr();
    }

    private function updateRepr()
    {
        $this->message = $this->rawMessage;

        $dot = false;
        if ('.' === substr($this->message, -1)) {
            $this->message = substr($this->message, 0, -1);
            $dot = true;
        }

        if (null !== $this->parsedFile) {
            $this->message .= sprintf(' in %s', json_encode($this->parsedFile, JSON_UNESCAPED_SLASHES | JSON_UNESCAPED_UNICODE));
        }

        if ($this->parsedLine >= 0) {
            $this->message .= sprintf(' at line %d', $this->parsedLine);
        }

        if ($this->snippet) {
            $this->message .= sprintf(' (near "%s")', $this->snippet);
        }

        if ($dot) {
            $this->message .= '.';
        }
    }
}
PKϤ$Z��� yaml/Exception/DumpException.phpnu�[���<?php

/*
 * This file is part of the Symfony package.
 *
 * (c) Fabien Potencier <fabien@symfony.com>
 *
 * For the full copyright and license information, please view the LICENSE
 * file that was distributed with this source code.
 */

namespace Symfony\Component\Yaml\Exception;

/**
 * Exception class thrown when an error occurs during dumping.
 *
 * @author Fabien Potencier <fabien@symfony.com>
 */
class DumpException extends RuntimeException
{
}
PKϤ$ZB9���%yaml/Exception/ExceptionInterface.phpnu�[���<?php

/*
 * This file is part of the Symfony package.
 *
 * (c) Fabien Potencier <fabien@symfony.com>
 *
 * For the full copyright and license information, please view the LICENSE
 * file that was distributed with this source code.
 */

namespace Symfony\Component\Yaml\Exception;

/**
 * Exception interface for all exceptions thrown by the component.
 *
 * @author Fabien Potencier <fabien@symfony.com>
 */
interface ExceptionInterface extends \Throwable
{
}
PKϤ$Z�_q���#yaml/Exception/RuntimeException.phpnu�[���<?php

/*
 * This file is part of the Symfony package.
 *
 * (c) Fabien Potencier <fabien@symfony.com>
 *
 * For the full copyright and license information, please view the LICENSE
 * file that was distributed with this source code.
 */

namespace Symfony\Component\Yaml\Exception;

/**
 * Exception class thrown when an error occurs during parsing.
 *
 * @author Romain Neutron <imprec@gmail.com>
 */
class RuntimeException extends \RuntimeException implements ExceptionInterface
{
}
PKϤ$Z-z���yaml/CHANGELOG.mdnu�[���CHANGELOG
=========

5.0.0
-----

 * Removed support for mappings inside multi-line strings.
 * removed support for implicit STDIN usage in the `lint:yaml` command, use `lint:yaml -` (append a dash) instead to make it explicit.

4.4.0
-----

 * Added support for parsing the inline notation spanning multiple lines.
 * Added support to dump `null` as `~` by using the `Yaml::DUMP_NULL_AS_TILDE` flag.
 * deprecated accepting STDIN implicitly when using the `lint:yaml` command, use `lint:yaml -` (append a dash) instead to make it explicit.

4.3.0
-----

 * Using a mapping inside a multi-line string is deprecated and will throw a `ParseException` in 5.0.

4.2.0
-----

 * added support for multiple files or directories in `LintCommand`

4.0.0
-----

 * The behavior of the non-specific tag `!` is changed and now forces
   non-evaluating your values.
 * complex mappings will throw a `ParseException`
 * support for the comma as a group separator for floats has been dropped, use
   the underscore instead
 * support for the `!!php/object` tag has been dropped, use the `!php/object`
   tag instead
 * duplicate mapping keys throw a `ParseException`
 * non-string mapping keys throw a `ParseException`, use the `Yaml::PARSE_KEYS_AS_STRINGS`
   flag to cast them to strings
 * `%` at the beginning of an unquoted string throw a `ParseException`
 * mappings with a colon (`:`) that is not followed by a whitespace throw a
   `ParseException`
 * the `Dumper::setIndentation()` method has been removed
 * being able to pass boolean options to the `Yaml::parse()`, `Yaml::dump()`,
   `Parser::parse()`, and `Dumper::dump()` methods to configure the behavior of
   the parser and dumper is no longer supported, pass bitmask flags instead
 * the constructor arguments of the `Parser` class have been removed
 * the `Inline` class is internal and no longer part of the BC promise
 * removed support for the `!str` tag, use the `!!str` tag instead
 * added support for tagged scalars.

   ```yml
   Yaml::parse('!foo bar', Yaml::PARSE_CUSTOM_TAGS);
   // returns TaggedValue('foo', 'bar');
   ```

3.4.0
-----

 * added support for parsing YAML files using the `Yaml::parseFile()` or `Parser::parseFile()` method

 * the `Dumper`, `Parser`, and `Yaml` classes are marked as final

 * Deprecated the `!php/object:` tag which will be replaced by the
   `!php/object` tag (without the colon) in 4.0.

 * Deprecated the `!php/const:` tag which will be replaced by the
   `!php/const` tag (without the colon) in 4.0.

 * Support for the `!str` tag is deprecated, use the `!!str` tag instead.

 * Deprecated using the non-specific tag `!` as its behavior will change in 4.0.
   It will force non-evaluating your values in 4.0. Use plain integers or `!!float` instead.

3.3.0
-----

 * Starting an unquoted string with a question mark followed by a space is
   deprecated and will throw a `ParseException` in Symfony 4.0.

 * Deprecated support for implicitly parsing non-string mapping keys as strings.
   Mapping keys that are no strings will lead to a `ParseException` in Symfony
   4.0. Use quotes to opt-in for keys to be parsed as strings.

   Before:

   ```php
   $yaml = <<<YAML
   null: null key
   true: boolean true
   2.0: float key
   YAML;

   Yaml::parse($yaml);
   ```

   After:

   ```php

   $yaml = <<<YAML
   "null": null key
   "true": boolean true
   "2.0": float key
   YAML;

   Yaml::parse($yaml);
   ```

 * Omitted mapping values will be parsed as `null`.

 * Omitting the key of a mapping is deprecated and will throw a `ParseException` in Symfony 4.0.

 * Added support for dumping empty PHP arrays as YAML sequences:

   ```php
   Yaml::dump([], 0, 0, Yaml::DUMP_EMPTY_ARRAY_AS_SEQUENCE);
   ```

3.2.0
-----

 * Mappings with a colon (`:`) that is not followed by a whitespace are deprecated
   when the mapping key is not quoted and will lead to a `ParseException` in
   Symfony 4.0 (e.g. `foo:bar` must be `foo: bar`).

 * Added support for parsing PHP constants:

   ```php
   Yaml::parse('!php/const:PHP_INT_MAX', Yaml::PARSE_CONSTANT);
   ```

 * Support for silently ignoring duplicate mapping keys in YAML has been
   deprecated and will lead to a `ParseException` in Symfony 4.0.

3.1.0
-----

 * Added support to dump `stdClass` and `ArrayAccess` objects as YAML mappings
   through the `Yaml::DUMP_OBJECT_AS_MAP` flag.

 * Strings that are not UTF-8 encoded will be dumped as base64 encoded binary
   data.

 * Added support for dumping multi line strings as literal blocks.

 * Added support for parsing base64 encoded binary data when they are tagged
   with the `!!binary` tag.

 * Added support for parsing timestamps as `\DateTime` objects:

   ```php
   Yaml::parse('2001-12-15 21:59:43.10 -5', Yaml::PARSE_DATETIME);
   ```

 * `\DateTime` and `\DateTimeImmutable` objects are dumped as YAML timestamps.

 * Deprecated usage of `%` at the beginning of an unquoted string.

 * Added support for customizing the YAML parser behavior through an optional bit field:

   ```php
   Yaml::parse('{ "foo": "bar", "fiz": "cat" }', Yaml::PARSE_EXCEPTION_ON_INVALID_TYPE | Yaml::PARSE_OBJECT | Yaml::PARSE_OBJECT_FOR_MAP);
   ```

 * Added support for customizing the dumped YAML string through an optional bit field:

   ```php
   Yaml::dump(['foo' => new A(), 'bar' => 1], 0, 0, Yaml::DUMP_EXCEPTION_ON_INVALID_TYPE | Yaml::DUMP_OBJECT);
   ```

3.0.0
-----

 * Yaml::parse() now throws an exception when a blackslash is not escaped
   in double-quoted strings

2.8.0
-----

 * Deprecated usage of a colon in an unquoted mapping value
 * Deprecated usage of @, \`, | and > at the beginning of an unquoted string
 * When surrounding strings with double-quotes, you must now escape `\` characters. Not
   escaping those characters (when surrounded by double-quotes) is deprecated.

   Before:

   ```yml
   class: "Foo\Var"
   ```

   After:

   ```yml
   class: "Foo\\Var"
   ```

2.1.0
-----

 * Yaml::parse() does not evaluate loaded files as PHP files by default
   anymore (call Yaml::enablePhpParsing() to get back the old behavior)
PKϤ$Z=��))yaml/LICENSEnu�[���Copyright (c) 2004-2020 Fabien Potencier

Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is furnished
to do so, subject to the following conditions:

The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.

THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
THE SOFTWARE.
PKϤ$Z3JU��
yaml/Yaml.phpnu�[���<?php

/*
 * This file is part of the Symfony package.
 *
 * (c) Fabien Potencier <fabien@symfony.com>
 *
 * For the full copyright and license information, please view the LICENSE
 * file that was distributed with this source code.
 */

namespace Symfony\Component\Yaml;

use Symfony\Component\Yaml\Exception\ParseException;

/**
 * Yaml offers convenience methods to load and dump YAML.
 *
 * @author Fabien Potencier <fabien@symfony.com>
 *
 * @final
 */
class Yaml
{
    const DUMP_OBJECT = 1;
    const PARSE_EXCEPTION_ON_INVALID_TYPE = 2;
    const PARSE_OBJECT = 4;
    const PARSE_OBJECT_FOR_MAP = 8;
    const DUMP_EXCEPTION_ON_INVALID_TYPE = 16;
    const PARSE_DATETIME = 32;
    const DUMP_OBJECT_AS_MAP = 64;
    const DUMP_MULTI_LINE_LITERAL_BLOCK = 128;
    const PARSE_CONSTANT = 256;
    const PARSE_CUSTOM_TAGS = 512;
    const DUMP_EMPTY_ARRAY_AS_SEQUENCE = 1024;
    const DUMP_NULL_AS_TILDE = 2048;

    /**
     * Parses a YAML file into a PHP value.
     *
     * Usage:
     *
     *     $array = Yaml::parseFile('config.yml');
     *     print_r($array);
     *
     * @param string $filename The path to the YAML file to be parsed
     * @param int    $flags    A bit field of PARSE_* constants to customize the YAML parser behavior
     *
     * @return mixed The YAML converted to a PHP value
     *
     * @throws ParseException If the file could not be read or the YAML is not valid
     */
    public static function parseFile(string $filename, int $flags = 0)
    {
        $yaml = new Parser();

        return $yaml->parseFile($filename, $flags);
    }

    /**
     * Parses YAML into a PHP value.
     *
     *  Usage:
     *  <code>
     *   $array = Yaml::parse(file_get_contents('config.yml'));
     *   print_r($array);
     *  </code>
     *
     * @param string $input A string containing YAML
     * @param int    $flags A bit field of PARSE_* constants to customize the YAML parser behavior
     *
     * @return mixed The YAML converted to a PHP value
     *
     * @throws ParseException If the YAML is not valid
     */
    public static function parse(string $input, int $flags = 0)
    {
        $yaml = new Parser();

        return $yaml->parse($input, $flags);
    }

    /**
     * Dumps a PHP value to a YAML string.
     *
     * The dump method, when supplied with an array, will do its best
     * to convert the array into friendly YAML.
     *
     * @param mixed $input  The PHP value
     * @param int   $inline The level where you switch to inline YAML
     * @param int   $indent The amount of spaces to use for indentation of nested nodes
     * @param int   $flags  A bit field of DUMP_* constants to customize the dumped YAML string
     *
     * @return string A YAML string representing the original PHP value
     */
    public static function dump($input, int $inline = 2, int $indent = 4, int $flags = 0): string
    {
        $yaml = new Dumper($indent);

        return $yaml->dump($input, $inline, 0, $flags);
    }
}
PKϤ$Z!e�*config/Tests/Definition/ScalarNodeTest.phpnu�[���<?php

/*
 * This file is part of the Symfony package.
 *
 * (c) Fabien Potencier <fabien@symfony.com>
 *
 * For the full copyright and license information, please view the LICENSE
 * file that was distributed with this source code.
 */

namespace Symfony\Component\Config\Tests\Definition;

use PHPUnit\Framework\TestCase;
use Symfony\Component\Config\Definition\ScalarNode;

class ScalarNodeTest extends TestCase
{
    /**
     * @dataProvider getValidValues
     */
    public function testNormalize($value)
    {
        $node = new ScalarNode('test');
        $this->assertSame($value, $node->normalize($value));
    }

    public function getValidValues()
    {
        return array(
            array(false),
            array(true),
            array(null),
            array(''),
            array('foo'),
            array(0),
            array(1),
            array(0.0),
            array(0.1),
        );
    }

    /**
     * @dataProvider getInvalidValues
     * @expectedException \Symfony\Component\Config\Definition\Exception\InvalidTypeException
     */
    public function testNormalizeThrowsExceptionOnInvalidValues($value)
    {
        $node = new ScalarNode('test');
        $node->normalize($value);
    }

    public function getInvalidValues()
    {
        return array(
            array(array()),
            array(array('foo' => 'bar')),
            array(new \stdClass()),
        );
    }

    public function testNormalizeThrowsExceptionWithoutHint()
    {
        $node = new ScalarNode('test');

        if (method_exists($this, 'expectException')) {
            $this->expectException('Symfony\Component\Config\Definition\Exception\InvalidTypeException');
            $this->expectExceptionMessage('Invalid type for path "test". Expected scalar, but got array.');
        } else {
            $this->setExpectedException('Symfony\Component\Config\Definition\Exception\InvalidTypeException', 'Invalid type for path "test". Expected scalar, but got array.');
        }

        $node->normalize(array());
    }

    public function testNormalizeThrowsExceptionWithErrorMessage()
    {
        $node = new ScalarNode('test');
        $node->setInfo('"the test value"');

        if (method_exists($this, 'expectException')) {
            $this->expectException('Symfony\Component\Config\Definition\Exception\InvalidTypeException');
            $this->expectExceptionMessage("Invalid type for path \"test\". Expected scalar, but got array.\nHint: \"the test value\"");
        } else {
            $this->setExpectedException('Symfony\Component\Config\Definition\Exception\InvalidTypeException', "Invalid type for path \"test\". Expected scalar, but got array.\nHint: \"the test value\"");
        }

        $node->normalize(array());
    }

    /**
     * @dataProvider getValidNonEmptyValues
     *
     * @param mixed $value
     */
    public function testValidNonEmptyValues($value)
    {
        $node = new ScalarNode('test');
        $node->setAllowEmptyValue(false);

        $this->assertSame($value, $node->finalize($value));
    }

    public function getValidNonEmptyValues()
    {
        return array(
            array(false),
            array(true),
            array('foo'),
            array(0),
            array(1),
            array(0.0),
            array(0.1),
        );
    }

    /**
     * @dataProvider getEmptyValues
     * @expectedException \Symfony\Component\Config\Definition\Exception\InvalidConfigurationException
     *
     * @param mixed $value
     */
    public function testNotAllowedEmptyValuesThrowException($value)
    {
        $node = new ScalarNode('test');
        $node->setAllowEmptyValue(false);
        $node->finalize($value);
    }

    public function getEmptyValues()
    {
        return array(
            array(null),
            array(''),
        );
    }
}
PKϤ$Z�{5,��:config/Tests/Definition/Builder/EnumNodeDefinitionTest.phpnu�[���<?php

/*
 * This file is part of the Symfony package.
 *
 * (c) Fabien Potencier <fabien@symfony.com>
 *
 * For the full copyright and license information, please view the LICENSE
 * file that was distributed with this source code.
 */

namespace Symfony\Component\Config\Tests\Definition\Builder;

use PHPUnit\Framework\TestCase;
use Symfony\Component\Config\Definition\Builder\EnumNodeDefinition;

class EnumNodeDefinitionTest extends TestCase
{
    public function testWithOneValue()
    {
        $def = new EnumNodeDefinition('foo');
        $def->values(array('foo'));

        $node = $def->getNode();
        $this->assertEquals(array('foo'), $node->getValues());
    }

    public function testWithOneDistinctValue()
    {
        $def = new EnumNodeDefinition('foo');
        $def->values(array('foo', 'foo'));

        $node = $def->getNode();
        $this->assertEquals(array('foo'), $node->getValues());
    }

    /**
     * @expectedException \RuntimeException
     * @expectedExceptionMessage You must call ->values() on enum nodes.
     */
    public function testNoValuesPassed()
    {
        $def = new EnumNodeDefinition('foo');
        $def->getNode();
    }

    /**
     * @expectedException \InvalidArgumentException
     * @expectedExceptionMessage ->values() must be called with at least one value.
     */
    public function testWithNoValues()
    {
        $def = new EnumNodeDefinition('foo');
        $def->values(array());
    }

    public function testGetNode()
    {
        $def = new EnumNodeDefinition('foo');
        $def->values(array('foo', 'bar'));

        $node = $def->getNode();
        $this->assertEquals(array('foo', 'bar'), $node->getValues());
    }
}
PKϤ$Z��Y11=config/Tests/Definition/Builder/BooleanNodeDefinitionTest.phpnu�[���<?php

/*
 * This file is part of the Symfony package.
 *
 * (c) Fabien Potencier <fabien@symfony.com>
 *
 * For the full copyright and license information, please view the LICENSE
 * file that was distributed with this source code.
 */

namespace Symfony\Component\Config\Tests\Definition\Builder;

use PHPUnit\Framework\TestCase;
use Symfony\Component\Config\Definition\Builder\BooleanNodeDefinition;

class BooleanNodeDefinitionTest extends TestCase
{
    /**
     * @expectedException \Symfony\Component\Config\Definition\Exception\InvalidDefinitionException
     * @expectedExceptionMessage ->cannotBeEmpty() is not applicable to BooleanNodeDefinition.
     */
    public function testCannotBeEmptyThrowsAnException()
    {
        $def = new BooleanNodeDefinition('foo');
        $def->cannotBeEmpty();
    }
}
PKϤ$ZB�z�
�
=config/Tests/Definition/Builder/NumericNodeDefinitionTest.phpnu�[���<?php

/*
 * This file is part of the Symfony package.
 *
 * (c) Fabien Potencier <fabien@symfony.com>
 *
 * For the full copyright and license information, please view the LICENSE
 * file that was distributed with this source code.
 */

namespace Symfony\Component\Config\Tests\Definition\Builder;

use PHPUnit\Framework\TestCase;
use Symfony\Component\Config\Definition\Builder\IntegerNodeDefinition as NumericNodeDefinition;
use Symfony\Component\Config\Definition\Builder\IntegerNodeDefinition;
use Symfony\Component\Config\Definition\Builder\FloatNodeDefinition;

class NumericNodeDefinitionTest extends TestCase
{
    /**
     * @expectedException \InvalidArgumentException
     * @expectedExceptionMessage You cannot define a min(4) as you already have a max(3)
     */
    public function testIncoherentMinAssertion()
    {
        $def = new NumericNodeDefinition('foo');
        $def->max(3)->min(4);
    }

    /**
     * @expectedException \InvalidArgumentException
     * @expectedExceptionMessage You cannot define a max(2) as you already have a min(3)
     */
    public function testIncoherentMaxAssertion()
    {
        $node = new NumericNodeDefinition('foo');
        $node->min(3)->max(2);
    }

    /**
     * @expectedException \Symfony\Component\Config\Definition\Exception\InvalidConfigurationException
     * @expectedExceptionMessage The value 4 is too small for path "foo". Should be greater than or equal to 5
     */
    public function testIntegerMinAssertion()
    {
        $def = new IntegerNodeDefinition('foo');
        $def->min(5)->getNode()->finalize(4);
    }

    /**
     * @expectedException \Symfony\Component\Config\Definition\Exception\InvalidConfigurationException
     * @expectedExceptionMessage The value 4 is too big for path "foo". Should be less than or equal to 3
     */
    public function testIntegerMaxAssertion()
    {
        $def = new IntegerNodeDefinition('foo');
        $def->max(3)->getNode()->finalize(4);
    }

    public function testIntegerValidMinMaxAssertion()
    {
        $def = new IntegerNodeDefinition('foo');
        $node = $def->min(3)->max(7)->getNode();
        $this->assertEquals(4, $node->finalize(4));
    }

    /**
     * @expectedException \Symfony\Component\Config\Definition\Exception\InvalidConfigurationException
     * @expectedExceptionMessage The value 400 is too small for path "foo". Should be greater than or equal to 500
     */
    public function testFloatMinAssertion()
    {
        $def = new FloatNodeDefinition('foo');
        $def->min(5E2)->getNode()->finalize(4e2);
    }

    /**
     * @expectedException \Symfony\Component\Config\Definition\Exception\InvalidConfigurationException
     * @expectedExceptionMessage The value 4.3 is too big for path "foo". Should be less than or equal to 0.3
     */
    public function testFloatMaxAssertion()
    {
        $def = new FloatNodeDefinition('foo');
        $def->max(0.3)->getNode()->finalize(4.3);
    }

    public function testFloatValidMinMaxAssertion()
    {
        $def = new FloatNodeDefinition('foo');
        $node = $def->min(3.0)->max(7e2)->getNode();
        $this->assertEquals(4.5, $node->finalize(4.5));
    }

    /**
     * @expectedException \Symfony\Component\Config\Definition\Exception\InvalidDefinitionException
     * @expectedExceptionMessage ->cannotBeEmpty() is not applicable to NumericNodeDefinition.
     */
    public function testCannotBeEmptyThrowsAnException()
    {
        $def = new NumericNodeDefinition('foo');
        $def->cannotBeEmpty();
    }
}
PKϤ$Z�,��!�!;config/Tests/Definition/Builder/ArrayNodeDefinitionTest.phpnu�[���<?php

/*
 * This file is part of the Symfony package.
 *
 * (c) Fabien Potencier <fabien@symfony.com>
 *
 * For the full copyright and license information, please view the LICENSE
 * file that was distributed with this source code.
 */

namespace Symfony\Component\Config\Tests\Definition\Builder;

use PHPUnit\Framework\TestCase;
use Symfony\Component\Config\Definition\Builder\ArrayNodeDefinition;
use Symfony\Component\Config\Definition\Processor;
use Symfony\Component\Config\Definition\Builder\ScalarNodeDefinition;
use Symfony\Component\Config\Definition\Exception\InvalidDefinitionException;

class ArrayNodeDefinitionTest extends TestCase
{
    public function testAppendingSomeNode()
    {
        $parent = new ArrayNodeDefinition('root');
        $child = new ScalarNodeDefinition('child');

        $parent
            ->children()
                ->scalarNode('foo')->end()
                ->scalarNode('bar')->end()
            ->end()
            ->append($child);

        $this->assertCount(3, $this->getField($parent, 'children'));
        $this->assertTrue(in_array($child, $this->getField($parent, 'children')));
    }

    /**
     * @expectedException \Symfony\Component\Config\Definition\Exception\InvalidDefinitionException
     * @dataProvider providePrototypeNodeSpecificCalls
     */
    public function testPrototypeNodeSpecificOption($method, $args)
    {
        $node = new ArrayNodeDefinition('root');

        call_user_func_array(array($node, $method), $args);

        $node->getNode();
    }

    public function providePrototypeNodeSpecificCalls()
    {
        return array(
            array('defaultValue', array(array())),
            array('addDefaultChildrenIfNoneSet', array()),
            array('requiresAtLeastOneElement', array()),
            array('useAttributeAsKey', array('foo')),
        );
    }

    /**
     * @expectedException \Symfony\Component\Config\Definition\Exception\InvalidDefinitionException
     */
    public function testConcreteNodeSpecificOption()
    {
        $node = new ArrayNodeDefinition('root');
        $node
            ->addDefaultsIfNotSet()
            ->prototype('array')
        ;
        $node->getNode();
    }

    /**
     * @expectedException \Symfony\Component\Config\Definition\Exception\InvalidDefinitionException
     */
    public function testPrototypeNodesCantHaveADefaultValueWhenUsingDefaultChildren()
    {
        $node = new ArrayNodeDefinition('root');
        $node
            ->defaultValue(array())
            ->addDefaultChildrenIfNoneSet('foo')
            ->prototype('array')
        ;
        $node->getNode();
    }

    public function testPrototypedArrayNodeDefaultWhenUsingDefaultChildren()
    {
        $node = new ArrayNodeDefinition('root');
        $node
            ->addDefaultChildrenIfNoneSet()
            ->prototype('array')
        ;
        $tree = $node->getNode();
        $this->assertEquals(array(array()), $tree->getDefaultValue());
    }

    /**
     * @dataProvider providePrototypedArrayNodeDefaults
     */
    public function testPrototypedArrayNodeDefault($args, $shouldThrowWhenUsingAttrAsKey, $shouldThrowWhenNotUsingAttrAsKey, $defaults)
    {
        $node = new ArrayNodeDefinition('root');
        $node
            ->addDefaultChildrenIfNoneSet($args)
            ->prototype('array')
        ;

        try {
            $tree = $node->getNode();
            $this->assertFalse($shouldThrowWhenNotUsingAttrAsKey);
            $this->assertEquals($defaults, $tree->getDefaultValue());
        } catch (InvalidDefinitionException $e) {
            $this->assertTrue($shouldThrowWhenNotUsingAttrAsKey);
        }

        $node = new ArrayNodeDefinition('root');
        $node
            ->useAttributeAsKey('attr')
            ->addDefaultChildrenIfNoneSet($args)
            ->prototype('array')
        ;

        try {
            $tree = $node->getNode();
            $this->assertFalse($shouldThrowWhenUsingAttrAsKey);
            $this->assertEquals($defaults, $tree->getDefaultValue());
        } catch (InvalidDefinitionException $e) {
            $this->assertTrue($shouldThrowWhenUsingAttrAsKey);
        }
    }

    public function providePrototypedArrayNodeDefaults()
    {
        return array(
            array(null, true, false, array(array())),
            array(2, true, false, array(array(), array())),
            array('2', false, true, array('2' => array())),
            array('foo', false, true, array('foo' => array())),
            array(array('foo'), false, true, array('foo' => array())),
            array(array('foo', 'bar'), false, true, array('foo' => array(), 'bar' => array())),
        );
    }

    public function testNestedPrototypedArrayNodes()
    {
        $nodeDefinition = new ArrayNodeDefinition('root');
        $nodeDefinition
            ->addDefaultChildrenIfNoneSet()
            ->prototype('array')
                  ->prototype('array')
        ;
        $node = $nodeDefinition->getNode();

        $this->assertInstanceOf('Symfony\Component\Config\Definition\PrototypedArrayNode', $node);
        $this->assertInstanceOf('Symfony\Component\Config\Definition\PrototypedArrayNode', $node->getPrototype());
    }

    public function testEnabledNodeDefaults()
    {
        $node = new ArrayNodeDefinition('root');
        $node
            ->canBeEnabled()
            ->children()
                ->scalarNode('foo')->defaultValue('bar')->end()
        ;

        $this->assertEquals(array('enabled' => false, 'foo' => 'bar'), $node->getNode()->getDefaultValue());
    }

    /**
     * @dataProvider getEnableableNodeFixtures
     */
    public function testTrueEnableEnabledNode($expected, $config, $message)
    {
        $processor = new Processor();
        $node = new ArrayNodeDefinition('root');
        $node
            ->canBeEnabled()
            ->children()
                ->scalarNode('foo')->defaultValue('bar')->end()
        ;

        $this->assertEquals(
            $expected,
            $processor->process($node->getNode(), $config),
            $message
        );
    }

    public function testCanBeDisabled()
    {
        $node = new ArrayNodeDefinition('root');
        $node->canBeDisabled();

        $this->assertTrue($this->getField($node, 'addDefaults'));
        $this->assertEquals(array('enabled' => false), $this->getField($node, 'falseEquivalent'));
        $this->assertEquals(array('enabled' => true), $this->getField($node, 'trueEquivalent'));
        $this->assertEquals(array('enabled' => true), $this->getField($node, 'nullEquivalent'));

        $nodeChildren = $this->getField($node, 'children');
        $this->assertArrayHasKey('enabled', $nodeChildren);

        $enabledNode = $nodeChildren['enabled'];
        $this->assertTrue($this->getField($enabledNode, 'default'));
        $this->assertTrue($this->getField($enabledNode, 'defaultValue'));
    }

    public function testIgnoreExtraKeys()
    {
        $node = new ArrayNodeDefinition('root');

        $this->assertFalse($this->getField($node, 'ignoreExtraKeys'));

        $result = $node->ignoreExtraKeys();

        $this->assertEquals($node, $result);
        $this->assertTrue($this->getField($node, 'ignoreExtraKeys'));
    }

    public function testNormalizeKeys()
    {
        $node = new ArrayNodeDefinition('root');

        $this->assertTrue($this->getField($node, 'normalizeKeys'));

        $result = $node->normalizeKeys(false);

        $this->assertEquals($node, $result);
        $this->assertFalse($this->getField($node, 'normalizeKeys'));
    }

    public function getEnableableNodeFixtures()
    {
        return array(
            array(array('enabled' => true, 'foo' => 'bar'), array(true), 'true enables an enableable node'),
            array(array('enabled' => true, 'foo' => 'bar'), array(null), 'null enables an enableable node'),
            array(array('enabled' => true, 'foo' => 'bar'), array(array('enabled' => true)), 'An enableable node can be enabled'),
            array(array('enabled' => true, 'foo' => 'baz'), array(array('foo' => 'baz')), 'any configuration enables an enableable node'),
            array(array('enabled' => false, 'foo' => 'baz'), array(array('foo' => 'baz', 'enabled' => false)), 'An enableable node can be disabled'),
            array(array('enabled' => false, 'foo' => 'bar'), array(false), 'false disables an enableable node'),
        );
    }

    protected function getField($object, $field)
    {
        $reflection = new \ReflectionProperty($object, $field);
        $reflection->setAccessible(true);

        return $reflection->getValue($object);
    }
}
PKϤ$Z�#�<3config/Tests/Definition/Builder/ExprBuilderTest.phpnu�[���<?php

/*
 * This file is part of the Symfony package.
 *
 * (c) Fabien Potencier <fabien@symfony.com>
 *
 * For the full copyright and license information, please view the LICENSE
 * file that was distributed with this source code.
 */

namespace Symfony\Component\Config\Tests\Definition\Builder;

use PHPUnit\Framework\TestCase;
use Symfony\Component\Config\Definition\Builder\TreeBuilder;

class ExprBuilderTest extends TestCase
{
    public function testAlwaysExpression()
    {
        $test = $this->getTestBuilder()
            ->always($this->returnClosure('new_value'))
        ->end();

        $this->assertFinalizedValueIs('new_value', $test);
    }

    public function testIfTrueExpression()
    {
        $test = $this->getTestBuilder()
            ->ifTrue()
            ->then($this->returnClosure('new_value'))
        ->end();
        $this->assertFinalizedValueIs('new_value', $test, array('key' => true));

        $test = $this->getTestBuilder()
            ->ifTrue(function ($v) { return true; })
            ->then($this->returnClosure('new_value'))
        ->end();
        $this->assertFinalizedValueIs('new_value', $test);

        $test = $this->getTestBuilder()
            ->ifTrue(function ($v) { return false; })
            ->then($this->returnClosure('new_value'))
        ->end();
        $this->assertFinalizedValueIs('value', $test);
    }

    public function testIfStringExpression()
    {
        $test = $this->getTestBuilder()
            ->ifString()
            ->then($this->returnClosure('new_value'))
        ->end();
        $this->assertFinalizedValueIs('new_value', $test);

        $test = $this->getTestBuilder()
            ->ifString()
            ->then($this->returnClosure('new_value'))
        ->end();
        $this->assertFinalizedValueIs(45, $test, array('key' => 45));
    }

    public function testIfNullExpression()
    {
        $test = $this->getTestBuilder()
            ->ifNull()
            ->then($this->returnClosure('new_value'))
        ->end();
        $this->assertFinalizedValueIs('new_value', $test, array('key' => null));

        $test = $this->getTestBuilder()
            ->ifNull()
            ->then($this->returnClosure('new_value'))
        ->end();
        $this->assertFinalizedValueIs('value', $test);
    }

    public function testIfEmptyExpression()
    {
        $test = $this->getTestBuilder()
            ->ifEmpty()
            ->then($this->returnClosure('new_value'))
        ->end();
        $this->assertFinalizedValueIs('new_value', $test, array('key' => array()));

        $test = $this->getTestBuilder()
            ->ifEmpty()
            ->then($this->returnClosure('new_value'))
        ->end();
        $this->assertFinalizedValueIs('value', $test);
    }

    public function testIfArrayExpression()
    {
        $test = $this->getTestBuilder()
            ->ifArray()
            ->then($this->returnClosure('new_value'))
        ->end();
        $this->assertFinalizedValueIs('new_value', $test, array('key' => array()));

        $test = $this->getTestBuilder()
            ->ifArray()
            ->then($this->returnClosure('new_value'))
        ->end();
        $this->assertFinalizedValueIs('value', $test);
    }

    public function testIfInArrayExpression()
    {
        $test = $this->getTestBuilder()
            ->ifInArray(array('foo', 'bar', 'value'))
            ->then($this->returnClosure('new_value'))
        ->end();
        $this->assertFinalizedValueIs('new_value', $test);

        $test = $this->getTestBuilder()
            ->ifInArray(array('foo', 'bar'))
            ->then($this->returnClosure('new_value'))
        ->end();
        $this->assertFinalizedValueIs('value', $test);
    }

    public function testIfNotInArrayExpression()
    {
        $test = $this->getTestBuilder()
            ->ifNotInArray(array('foo', 'bar'))
            ->then($this->returnClosure('new_value'))
        ->end();
        $this->assertFinalizedValueIs('new_value', $test);

        $test = $this->getTestBuilder()
            ->ifNotInArray(array('foo', 'bar', 'value_from_config'))
            ->then($this->returnClosure('new_value'))
        ->end();
        $this->assertFinalizedValueIs('new_value', $test);
    }

    public function testThenEmptyArrayExpression()
    {
        $test = $this->getTestBuilder()
            ->ifString()
            ->thenEmptyArray()
        ->end();
        $this->assertFinalizedValueIs(array(), $test);
    }

    /**
     * @expectedException \Symfony\Component\Config\Definition\Exception\InvalidConfigurationException
     */
    public function testThenInvalid()
    {
        $test = $this->getTestBuilder()
            ->ifString()
            ->thenInvalid('Invalid value')
        ->end();
        $this->finalizeTestBuilder($test);
    }

    public function testThenUnsetExpression()
    {
        $test = $this->getTestBuilder()
            ->ifString()
            ->thenUnset()
        ->end();
        $this->assertEquals(array(), $this->finalizeTestBuilder($test));
    }

    /**
     * @expectedException \RuntimeException
     * @expectedExceptionMessage You must specify an if part.
     */
    public function testEndIfPartNotSpecified()
    {
        $this->getTestBuilder()->end();
    }

    /**
     * @expectedException \RuntimeException
     * @expectedExceptionMessage You must specify a then part.
     */
    public function testEndThenPartNotSpecified()
    {
        $builder = $this->getTestBuilder();
        $builder->ifPart = 'test';
        $builder->end();
    }

    /**
     * Create a test treebuilder with a variable node, and init the validation.
     *
     * @return TreeBuilder
     */
    protected function getTestBuilder()
    {
        $builder = new TreeBuilder();

        return $builder
            ->root('test')
            ->children()
            ->variableNode('key')
            ->validate()
        ;
    }

    /**
     * Close the validation process and finalize with the given config.
     *
     * @param TreeBuilder $testBuilder The tree builder to finalize
     * @param array       $config      The config you want to use for the finalization, if nothing provided
     *                                 a simple array('key'=>'value') will be used
     *
     * @return array The finalized config values
     */
    protected function finalizeTestBuilder($testBuilder, $config = null)
    {
        return $testBuilder
            ->end()
            ->end()
            ->end()
            ->buildTree()
            ->finalize(null === $config ? array('key' => 'value') : $config)
        ;
    }

    /**
     * Return a closure that will return the given value.
     *
     * @param mixed $val The value that the closure must return
     *
     * @return \Closure
     */
    protected function returnClosure($val)
    {
        return function ($v) use ($val) {
            return $val;
        };
    }

    /**
     * Assert that the given test builder, will return the given value.
     *
     * @param mixed       $value       The value to test
     * @param TreeBuilder $treeBuilder The tree builder to finalize
     * @param mixed       $config      The config values that new to be finalized
     */
    protected function assertFinalizedValueIs($value, $treeBuilder, $config = null)
    {
        $this->assertEquals(array('key' => $value), $this->finalizeTestBuilder($treeBuilder, $config));
    }
}
PKϤ$Z4�}}3config/Tests/Definition/Builder/TreeBuilderTest.phpnu�[���<?php

/*
 * This file is part of the Symfony package.
 *
 * (c) Fabien Potencier <fabien@symfony.com>
 *
 * For the full copyright and license information, please view the LICENSE
 * file that was distributed with this source code.
 */

namespace Symfony\Component\Config\Tests\Definition\Builder;

use PHPUnit\Framework\TestCase;
use Symfony\Component\Config\Tests\Definition\Builder\NodeBuilder as CustomNodeBuilder;
use Symfony\Component\Config\Definition\Builder\TreeBuilder;

require __DIR__.'/../../Fixtures/Builder/NodeBuilder.php';
require __DIR__.'/../../Fixtures/Builder/BarNodeDefinition.php';
require __DIR__.'/../../Fixtures/Builder/VariableNodeDefinition.php';

class TreeBuilderTest extends TestCase
{
    public function testUsingACustomNodeBuilder()
    {
        $builder = new TreeBuilder();
        $root = $builder->root('custom', 'array', new CustomNodeBuilder());

        $nodeBuilder = $root->children();

        $this->assertInstanceOf('Symfony\Component\Config\Tests\Definition\Builder\NodeBuilder', $nodeBuilder);

        $nodeBuilder = $nodeBuilder->arrayNode('deeper')->children();

        $this->assertInstanceOf('Symfony\Component\Config\Tests\Definition\Builder\NodeBuilder', $nodeBuilder);
    }

    public function testOverrideABuiltInNodeType()
    {
        $builder = new TreeBuilder();
        $root = $builder->root('override', 'array', new CustomNodeBuilder());

        $definition = $root->children()->variableNode('variable');

        $this->assertInstanceOf('Symfony\Component\Config\Tests\Definition\Builder\VariableNodeDefinition', $definition);
    }

    public function testAddANodeType()
    {
        $builder = new TreeBuilder();
        $root = $builder->root('override', 'array', new CustomNodeBuilder());

        $definition = $root->children()->barNode('variable');

        $this->assertInstanceOf('Symfony\Component\Config\Tests\Definition\Builder\BarNodeDefinition', $definition);
    }

    public function testCreateABuiltInNodeTypeWithACustomNodeBuilder()
    {
        $builder = new TreeBuilder();
        $root = $builder->root('builtin', 'array', new CustomNodeBuilder());

        $definition = $root->children()->booleanNode('boolean');

        $this->assertInstanceOf('Symfony\Component\Config\Definition\Builder\BooleanNodeDefinition', $definition);
    }

    public function testPrototypedArrayNodeUseTheCustomNodeBuilder()
    {
        $builder = new TreeBuilder();
        $root = $builder->root('override', 'array', new CustomNodeBuilder());

        $root->prototype('bar')->end();

        $this->assertInstanceOf('Symfony\Component\Config\Tests\Fixtures\BarNode', $root->getNode(true)->getPrototype());
    }

    public function testAnExtendedNodeBuilderGetsPropagatedToTheChildren()
    {
        $builder = new TreeBuilder();

        $builder->root('propagation')
            ->children()
                ->setNodeClass('extended', 'Symfony\Component\Config\Definition\Builder\BooleanNodeDefinition')
                ->node('foo', 'extended')->end()
                ->arrayNode('child')
                    ->children()
                        ->node('foo', 'extended')
                    ->end()
                ->end()
            ->end()
        ->end();

        $node = $builder->buildTree();
        $children = $node->getChildren();

        $this->assertInstanceOf('Symfony\Component\Config\Definition\BooleanNode', $children['foo']);

        $childChildren = $children['child']->getChildren();

        $this->assertInstanceOf('Symfony\Component\Config\Definition\BooleanNode', $childChildren['foo']);
    }

    public function testDefinitionInfoGetsTransferredToNode()
    {
        $builder = new TreeBuilder();

        $builder->root('test')->info('root info')
            ->children()
                ->node('child', 'variable')->info('child info')->defaultValue('default')
            ->end()
        ->end();

        $tree = $builder->buildTree();
        $children = $tree->getChildren();

        $this->assertEquals('root info', $tree->getInfo());
        $this->assertEquals('child info', $children['child']->getInfo());
    }

    public function testDefinitionExampleGetsTransferredToNode()
    {
        $builder = new TreeBuilder();

        $builder->root('test')
            ->example(array('key' => 'value'))
            ->children()
                ->node('child', 'variable')->info('child info')->defaultValue('default')->example('example')
            ->end()
        ->end();

        $tree = $builder->buildTree();
        $children = $tree->getChildren();

        $this->assertInternalType('array', $tree->getExample());
        $this->assertEquals('example', $children['child']->getExample());
    }
}
PKϤ$Z�,�1�
�
3config/Tests/Definition/Builder/NodeBuilderTest.phpnu�[���<?php

/*
 * This file is part of the Symfony package.
 *
 * (c) Fabien Potencier <fabien@symfony.com>
 *
 * For the full copyright and license information, please view the LICENSE
 * file that was distributed with this source code.
 */

namespace Symfony\Component\Config\Tests\Definition\Builder;

use PHPUnit\Framework\TestCase;
use Symfony\Component\Config\Definition\Builder\NodeBuilder as BaseNodeBuilder;
use Symfony\Component\Config\Definition\Builder\VariableNodeDefinition as BaseVariableNodeDefinition;

class NodeBuilderTest extends TestCase
{
    /**
     * @expectedException \RuntimeException
     */
    public function testThrowsAnExceptionWhenTryingToCreateANonRegisteredNodeType()
    {
        $builder = new BaseNodeBuilder();
        $builder->node('', 'foobar');
    }

    /**
     * @expectedException \RuntimeException
     */
    public function testThrowsAnExceptionWhenTheNodeClassIsNotFound()
    {
        $builder = new BaseNodeBuilder();
        $builder
            ->setNodeClass('noclasstype', '\\foo\\bar\\noclass')
            ->node('', 'noclasstype');
    }

    public function testAddingANewNodeType()
    {
        $class = __NAMESPACE__.'\\SomeNodeDefinition';

        $builder = new BaseNodeBuilder();
        $node = $builder
            ->setNodeClass('newtype', $class)
            ->node('', 'newtype');

        $this->assertInstanceOf($class, $node);
    }

    public function testOverridingAnExistingNodeType()
    {
        $class = __NAMESPACE__.'\\SomeNodeDefinition';

        $builder = new BaseNodeBuilder();
        $node = $builder
            ->setNodeClass('variable', $class)
            ->node('', 'variable');

        $this->assertInstanceOf($class, $node);
    }

    public function testNodeTypesAreNotCaseSensitive()
    {
        $builder = new BaseNodeBuilder();

        $node1 = $builder->node('', 'VaRiAbLe');
        $node2 = $builder->node('', 'variable');

        $this->assertInstanceOf(get_class($node1), $node2);

        $builder->setNodeClass('CuStOm', __NAMESPACE__.'\\SomeNodeDefinition');

        $node1 = $builder->node('', 'CUSTOM');
        $node2 = $builder->node('', 'custom');

        $this->assertInstanceOf(get_class($node1), $node2);
    }

    public function testNumericNodeCreation()
    {
        $builder = new BaseNodeBuilder();

        $node = $builder->integerNode('foo')->min(3)->max(5);
        $this->assertInstanceOf('Symfony\Component\Config\Definition\Builder\IntegerNodeDefinition', $node);

        $node = $builder->floatNode('bar')->min(3.0)->max(5.0);
        $this->assertInstanceOf('Symfony\Component\Config\Definition\Builder\FloatNodeDefinition', $node);
    }
}

class SomeNodeDefinition extends BaseVariableNodeDefinition
{
}
PKϤ$Z��t�-config/Tests/Definition/NormalizationTest.phpnu�[���<?php

/*
 * This file is part of the Symfony package.
 *
 * (c) Fabien Potencier <fabien@symfony.com>
 *
 * For the full copyright and license information, please view the LICENSE
 * file that was distributed with this source code.
 */

namespace Symfony\Component\Config\Tests\Definition;

use PHPUnit\Framework\TestCase;
use Symfony\Component\Config\Definition\NodeInterface;
use Symfony\Component\Config\Definition\Builder\TreeBuilder;

class NormalizationTest extends TestCase
{
    /**
     * @dataProvider getEncoderTests
     */
    public function testNormalizeEncoders($denormalized)
    {
        $tb = new TreeBuilder();
        $tree = $tb
            ->root('root_name', 'array')
                ->fixXmlConfig('encoder')
                ->children()
                    ->node('encoders', 'array')
                        ->useAttributeAsKey('class')
                        ->prototype('array')
                            ->beforeNormalization()->ifString()->then(function ($v) { return array('algorithm' => $v); })->end()
                            ->children()
                                ->node('algorithm', 'scalar')->end()
                            ->end()
                        ->end()
                    ->end()
                ->end()
            ->end()
            ->buildTree()
        ;

        $normalized = array(
            'encoders' => array(
                'foo' => array('algorithm' => 'plaintext'),
            ),
        );

        $this->assertNormalized($tree, $denormalized, $normalized);
    }

    public function getEncoderTests()
    {
        $configs = array();

        // XML
        $configs[] = array(
            'encoder' => array(
                array('class' => 'foo', 'algorithm' => 'plaintext'),
            ),
        );

        // XML when only one element of this type
        $configs[] = array(
            'encoder' => array('class' => 'foo', 'algorithm' => 'plaintext'),
        );

        // YAML/PHP
        $configs[] = array(
            'encoders' => array(
                array('class' => 'foo', 'algorithm' => 'plaintext'),
            ),
        );

        // YAML/PHP
        $configs[] = array(
            'encoders' => array(
                'foo' => 'plaintext',
            ),
        );

        // YAML/PHP
        $configs[] = array(
            'encoders' => array(
                'foo' => array('algorithm' => 'plaintext'),
            ),
        );

        return array_map(function ($v) {
            return array($v);
        }, $configs);
    }

    /**
     * @dataProvider getAnonymousKeysTests
     */
    public function testAnonymousKeysArray($denormalized)
    {
        $tb = new TreeBuilder();
        $tree = $tb
            ->root('root', 'array')
                ->children()
                    ->node('logout', 'array')
                        ->fixXmlConfig('handler')
                        ->children()
                            ->node('handlers', 'array')
                                ->prototype('scalar')->end()
                            ->end()
                        ->end()
                    ->end()
                ->end()
            ->end()
            ->buildTree()
        ;

        $normalized = array('logout' => array('handlers' => array('a', 'b', 'c')));

        $this->assertNormalized($tree, $denormalized, $normalized);
    }

    public function getAnonymousKeysTests()
    {
        $configs = array();

        $configs[] = array(
            'logout' => array(
                'handlers' => array('a', 'b', 'c'),
            ),
        );

        $configs[] = array(
            'logout' => array(
                'handler' => array('a', 'b', 'c'),
            ),
        );

        return array_map(function ($v) { return array($v); }, $configs);
    }

    /**
     * @dataProvider getNumericKeysTests
     */
    public function testNumericKeysAsAttributes($denormalized)
    {
        $normalized = array(
            'thing' => array(42 => array('foo', 'bar'), 1337 => array('baz', 'qux')),
        );

        $this->assertNormalized($this->getNumericKeysTestTree(), $denormalized, $normalized);
    }

    public function getNumericKeysTests()
    {
        $configs = array();

        $configs[] = array(
            'thing' => array(
                42 => array('foo', 'bar'), 1337 => array('baz', 'qux'),
            ),
        );

        $configs[] = array(
            'thing' => array(
                array('foo', 'bar', 'id' => 42), array('baz', 'qux', 'id' => 1337),
            ),
        );

        return array_map(function ($v) { return array($v); }, $configs);
    }

    /**
     * @expectedException \Symfony\Component\Config\Definition\Exception\InvalidConfigurationException
     * @expectedExceptionMessage The attribute "id" must be set for path "root.thing".
     */
    public function testNonAssociativeArrayThrowsExceptionIfAttributeNotSet()
    {
        $denormalized = array(
            'thing' => array(
                array('foo', 'bar'), array('baz', 'qux'),
            ),
        );

        $this->assertNormalized($this->getNumericKeysTestTree(), $denormalized, array());
    }

    public function testAssociativeArrayPreserveKeys()
    {
        $tb = new TreeBuilder();
        $tree = $tb
            ->root('root', 'array')
                ->prototype('array')
                    ->children()
                        ->node('foo', 'scalar')->end()
                    ->end()
                ->end()
            ->end()
            ->buildTree()
        ;

        $data = array('first' => array('foo' => 'bar'));

        $this->assertNormalized($tree, $data, $data);
    }

    public static function assertNormalized(NodeInterface $tree, $denormalized, $normalized)
    {
        self::assertSame($normalized, $tree->normalize($denormalized));
    }

    private function getNumericKeysTestTree()
    {
        $tb = new TreeBuilder();
        $tree = $tb
            ->root('root', 'array')
                ->children()
                    ->node('thing', 'array')
                        ->useAttributeAsKey('id')
                        ->prototype('array')
                            ->prototype('scalar')->end()
                        ->end()
                    ->end()
                ->end()
            ->end()
            ->buildTree()
        ;

        return $tree;
    }
}
PKϤ$Z5��r��+config/Tests/Definition/BooleanNodeTest.phpnu�[���<?php

/*
 * This file is part of the Symfony package.
 *
 * (c) Fabien Potencier <fabien@symfony.com>
 *
 * For the full copyright and license information, please view the LICENSE
 * file that was distributed with this source code.
 */

namespace Symfony\Component\Config\Tests\Definition;

use PHPUnit\Framework\TestCase;
use Symfony\Component\Config\Definition\BooleanNode;

class BooleanNodeTest extends TestCase
{
    /**
     * @dataProvider getValidValues
     */
    public function testNormalize($value)
    {
        $node = new BooleanNode('test');
        $this->assertSame($value, $node->normalize($value));
    }

    /**
     * @dataProvider getValidValues
     *
     * @param bool $value
     */
    public function testValidNonEmptyValues($value)
    {
        $node = new BooleanNode('test');
        $node->setAllowEmptyValue(false);

        $this->assertSame($value, $node->finalize($value));
    }

    public function getValidValues()
    {
        return array(
            array(false),
            array(true),
        );
    }

    /**
     * @dataProvider getInvalidValues
     * @expectedException \Symfony\Component\Config\Definition\Exception\InvalidTypeException
     */
    public function testNormalizeThrowsExceptionOnInvalidValues($value)
    {
        $node = new BooleanNode('test');
        $node->normalize($value);
    }

    public function getInvalidValues()
    {
        return array(
            array(null),
            array(''),
            array('foo'),
            array(0),
            array(1),
            array(0.0),
            array(0.1),
            array(array()),
            array(array('foo' => 'bar')),
            array(new \stdClass()),
        );
    }
}
PKϤ$Zbv�8��)config/Tests/Definition/ArrayNodeTest.phpnu�[���<?php

/*
 * This file is part of the Symfony package.
 *
 * (c) Fabien Potencier <fabien@symfony.com>
 *
 * For the full copyright and license information, please view the LICENSE
 * file that was distributed with this source code.
 */

namespace Symfony\Component\Config\Tests\Definition;

use PHPUnit\Framework\TestCase;
use Symfony\Component\Config\Definition\ArrayNode;
use Symfony\Component\Config\Definition\Exception\InvalidConfigurationException;
use Symfony\Component\Config\Definition\ScalarNode;

class ArrayNodeTest extends TestCase
{
    /**
     * @expectedException \Symfony\Component\Config\Definition\Exception\InvalidTypeException
     */
    public function testNormalizeThrowsExceptionWhenFalseIsNotAllowed()
    {
        $node = new ArrayNode('root');
        $node->normalize(false);
    }

    /**
     * @expectedException        \Symfony\Component\Config\Definition\Exception\InvalidConfigurationException
     * @expectedExceptionMessage Unrecognized option "foo" under "root"
     */
    public function testExceptionThrownOnUnrecognizedChild()
    {
        $node = new ArrayNode('root');
        $node->normalize(array('foo' => 'bar'));
    }

    public function ignoreAndRemoveMatrixProvider()
    {
        $unrecognizedOptionException = new InvalidConfigurationException('Unrecognized option "foo" under "root"');

        return array(
            array(true, true, array(), 'no exception is thrown for an unrecognized child if the ignoreExtraKeys option is set to true'),
            array(true, false, array('foo' => 'bar'), 'extra keys are not removed when ignoreExtraKeys second option is set to false'),
            array(false, true, $unrecognizedOptionException),
            array(false, false, $unrecognizedOptionException),
        );
    }

    /**
     * @dataProvider ignoreAndRemoveMatrixProvider
     */
    public function testIgnoreAndRemoveBehaviors($ignore, $remove, $expected, $message = '')
    {
        if ($expected instanceof \Exception) {
            if (method_exists($this, 'expectException')) {
                $this->expectException(get_class($expected));
                $this->expectExceptionMessage($expected->getMessage());
            } else {
                $this->setExpectedException(get_class($expected), $expected->getMessage());
            }
        }
        $node = new ArrayNode('root');
        $node->setIgnoreExtraKeys($ignore, $remove);
        $result = $node->normalize(array('foo' => 'bar'));
        $this->assertSame($expected, $result, $message);
    }

    /**
     * @dataProvider getPreNormalizationTests
     */
    public function testPreNormalize($denormalized, $normalized)
    {
        $node = new ArrayNode('foo');

        $r = new \ReflectionMethod($node, 'preNormalize');
        $r->setAccessible(true);

        $this->assertSame($normalized, $r->invoke($node, $denormalized));
    }

    public function getPreNormalizationTests()
    {
        return array(
            array(
                array('foo-bar' => 'foo'),
                array('foo_bar' => 'foo'),
            ),
            array(
                array('foo-bar_moo' => 'foo'),
                array('foo-bar_moo' => 'foo'),
            ),
            array(
                array('anything-with-dash-and-no-underscore' => 'first', 'no_dash' => 'second'),
                array('anything_with_dash_and_no_underscore' => 'first', 'no_dash' => 'second'),
            ),
            array(
                array('foo-bar' => null, 'foo_bar' => 'foo'),
                array('foo-bar' => null, 'foo_bar' => 'foo'),
            ),
        );
    }

    /**
     * @dataProvider getZeroNamedNodeExamplesData
     */
    public function testNodeNameCanBeZero($denormalized, $normalized)
    {
        $zeroNode = new ArrayNode(0);
        $zeroNode->addChild(new ScalarNode('name'));
        $fiveNode = new ArrayNode(5);
        $fiveNode->addChild(new ScalarNode(0));
        $fiveNode->addChild(new ScalarNode('new_key'));
        $rootNode = new ArrayNode('root');
        $rootNode->addChild($zeroNode);
        $rootNode->addChild($fiveNode);
        $rootNode->addChild(new ScalarNode('string_key'));
        $r = new \ReflectionMethod($rootNode, 'normalizeValue');
        $r->setAccessible(true);

        $this->assertSame($normalized, $r->invoke($rootNode, $denormalized));
    }

    public function getZeroNamedNodeExamplesData()
    {
        return array(
            array(
                array(
                    0 => array(
                        'name' => 'something',
                    ),
                    5 => array(
                        0 => 'this won\'t work too',
                        'new_key' => 'some other value',
                    ),
                    'string_key' => 'just value',
                ),
                array(
                    0 => array(
                        'name' => 'something',
                    ),
                    5 => array(
                        0 => 'this won\'t work too',
                        'new_key' => 'some other value',
                    ),
                    'string_key' => 'just value',
                ),
            ),
        );
    }

    /**
     * @dataProvider getPreNormalizedNormalizedOrderedData
     */
    public function testChildrenOrderIsMaintainedOnNormalizeValue($prenormalized, $normalized)
    {
        $scalar1 = new ScalarNode('1');
        $scalar2 = new ScalarNode('2');
        $scalar3 = new ScalarNode('3');
        $node = new ArrayNode('foo');
        $node->addChild($scalar1);
        $node->addChild($scalar3);
        $node->addChild($scalar2);

        $r = new \ReflectionMethod($node, 'normalizeValue');
        $r->setAccessible(true);

        $this->assertSame($normalized, $r->invoke($node, $prenormalized));
    }

    public function getPreNormalizedNormalizedOrderedData()
    {
        return array(
            array(
                array('2' => 'two', '1' => 'one', '3' => 'three'),
                array('2' => 'two', '1' => 'one', '3' => 'three'),
            ),
        );
    }

    /**
     * @expectedException \InvalidArgumentException
     * @expectedExceptionMessage Child nodes must be named.
     */
    public function testAddChildEmptyName()
    {
        $node = new ArrayNode('root');

        $childNode = new ArrayNode('');
        $node->addChild($childNode);
    }

    /**
     * @expectedException \InvalidArgumentException
     * @expectedExceptionMessage A child node named "foo" already exists.
     */
    public function testAddChildNameAlreadyExists()
    {
        $node = new ArrayNode('root');

        $childNode = new ArrayNode('foo');
        $node->addChild($childNode);

        $childNodeWithSameName = new ArrayNode('foo');
        $node->addChild($childNodeWithSameName);
    }

    /**
     * @expectedException \RuntimeException
     * @expectedExceptionMessage The node at path "foo" has no default value.
     */
    public function testGetDefaultValueWithoutDefaultValue()
    {
        $node = new ArrayNode('foo');
        $node->getDefaultValue();
    }
}
PKϤ$Zz�3�
�
9config/Tests/Definition/Dumper/XmlReferenceDumperTest.phpnu�[���<?php

/*
 * This file is part of the Symfony package.
 *
 * (c) Fabien Potencier <fabien@symfony.com>
 *
 * For the full copyright and license information, please view the LICENSE
 * file that was distributed with this source code.
 */

namespace Symfony\Component\Config\Tests\Definition\Dumper;

use PHPUnit\Framework\TestCase;
use Symfony\Component\Config\Definition\Dumper\XmlReferenceDumper;
use Symfony\Component\Config\Tests\Fixtures\Configuration\ExampleConfiguration;

class XmlReferenceDumperTest extends TestCase
{
    public function testDumper()
    {
        $configuration = new ExampleConfiguration();

        $dumper = new XmlReferenceDumper();
        $this->assertEquals($this->getConfigurationAsString(), $dumper->dump($configuration));
    }

    public function testNamespaceDumper()
    {
        $configuration = new ExampleConfiguration();

        $dumper = new XmlReferenceDumper();
        $this->assertEquals(str_replace('http://example.org/schema/dic/acme_root', 'http://symfony.com/schema/dic/symfony', $this->getConfigurationAsString()), $dumper->dump($configuration, 'http://symfony.com/schema/dic/symfony'));
    }

    private function getConfigurationAsString()
    {
        return str_replace("\n", PHP_EOL, <<<'EOL'
<!-- Namespace: http://example.org/schema/dic/acme_root -->
<!-- scalar-required: Required -->
<!-- enum-with-default: One of "this"; "that" -->
<!-- enum: One of "this"; "that" -->
<config
    boolean="true"
    scalar-empty=""
    scalar-null="null"
    scalar-true="true"
    scalar-false="false"
    scalar-default="default"
    scalar-array-empty=""
    scalar-array-defaults="elem1,elem2"
    scalar-required=""
    node-with-a-looong-name=""
    enum-with-default="this"
    enum=""
>

    <!-- some info -->
    <!--
        child3: this is a long
                multi-line info text
                which should be indented;
                Example: example setting
    -->
    <array
        child1=""
        child2=""
        child3=""
    />

    <!-- prototype -->
    <scalar-prototyped>scalar value</scalar-prototyped>

    <!-- prototype: Parameter name -->
    <parameter name="parameter name">scalar value</parameter>

    <!-- prototype -->
    <connection
        user=""
        pass=""
    />

    <!-- prototype -->
    <cms-page page="cms page page">

        <!-- prototype -->
        <!-- title: Required -->
        <!-- path: Required -->
        <page
            locale="page locale"
            title=""
            path=""
        />

    </cms-page>

    <!-- prototype -->
    <pipou name="pipou name">

        <!-- prototype -->
        <name didou="" />

    </pipou>

</config>

EOL
        );
    }
}
PKϤ$Z����%%:config/Tests/Definition/Dumper/YamlReferenceDumperTest.phpnu�[���<?php

/*
 * This file is part of the Symfony package.
 *
 * (c) Fabien Potencier <fabien@symfony.com>
 *
 * For the full copyright and license information, please view the LICENSE
 * file that was distributed with this source code.
 */

namespace Symfony\Component\Config\Tests\Definition\Dumper;

use PHPUnit\Framework\TestCase;
use Symfony\Component\Config\Definition\Dumper\YamlReferenceDumper;
use Symfony\Component\Config\Tests\Fixtures\Configuration\ExampleConfiguration;

class YamlReferenceDumperTest extends TestCase
{
    public function testDumper()
    {
        $configuration = new ExampleConfiguration();

        $dumper = new YamlReferenceDumper();

        $this->assertEquals($this->getConfigurationAsString(), $dumper->dump($configuration));
    }

    private function getConfigurationAsString()
    {
        return <<<'EOL'
acme_root:
    boolean:              true
    scalar_empty:         ~
    scalar_null:          null
    scalar_true:          true
    scalar_false:         false
    scalar_default:       default
    scalar_array_empty:   []
    scalar_array_defaults:

        # Defaults:
        - elem1
        - elem2
    scalar_required:      ~ # Required
    node_with_a_looong_name: ~
    enum_with_default:    this # One of "this"; "that"
    enum:                 ~ # One of "this"; "that"

    # some info
    array:
        child1:               ~
        child2:               ~

        # this is a long
        # multi-line info text
        # which should be indented
        child3:               ~ # Example: example setting
    scalar_prototyped:    []
    parameters:

        # Prototype: Parameter name
        name:                 ~
    connections:

        # Prototype
        -
            user:                 ~
            pass:                 ~
    cms_pages:

        # Prototype
        page:

            # Prototype
            locale:
                title:                ~ # Required
                path:                 ~ # Required
    pipou:

        # Prototype
        name:                 []

EOL;
    }
}
PKϤ$Z����LL%config/Tests/Definition/MergeTest.phpnu�[���<?php

/*
 * This file is part of the Symfony package.
 *
 * (c) Fabien Potencier <fabien@symfony.com>
 *
 * For the full copyright and license information, please view the LICENSE
 * file that was distributed with this source code.
 */

namespace Symfony\Component\Config\Tests\Definition;

use PHPUnit\Framework\TestCase;
use Symfony\Component\Config\Definition\Builder\TreeBuilder;

class MergeTest extends TestCase
{
    /**
     * @expectedException \Symfony\Component\Config\Definition\Exception\ForbiddenOverwriteException
     */
    public function testForbiddenOverwrite()
    {
        $tb = new TreeBuilder();
        $tree = $tb
            ->root('root', 'array')
                ->children()
                    ->node('foo', 'scalar')
                        ->cannotBeOverwritten()
                    ->end()
                ->end()
            ->end()
            ->buildTree()
        ;

        $a = array(
            'foo' => 'bar',
        );

        $b = array(
            'foo' => 'moo',
        );

        $tree->merge($a, $b);
    }

    public function testUnsetKey()
    {
        $tb = new TreeBuilder();
        $tree = $tb
            ->root('root', 'array')
                ->children()
                    ->node('foo', 'scalar')->end()
                    ->node('bar', 'scalar')->end()
                    ->node('unsettable', 'array')
                        ->canBeUnset()
                        ->children()
                            ->node('foo', 'scalar')->end()
                            ->node('bar', 'scalar')->end()
                        ->end()
                    ->end()
                    ->node('unsetted', 'array')
                        ->canBeUnset()
                        ->prototype('scalar')->end()
                    ->end()
                ->end()
            ->end()
            ->buildTree()
        ;

        $a = array(
            'foo' => 'bar',
            'unsettable' => array(
                'foo' => 'a',
                'bar' => 'b',
            ),
            'unsetted' => false,
        );

        $b = array(
            'foo' => 'moo',
            'bar' => 'b',
            'unsettable' => false,
            'unsetted' => array('a', 'b'),
        );

        $this->assertEquals(array(
            'foo' => 'moo',
            'bar' => 'b',
            'unsettable' => false,
            'unsetted' => array('a', 'b'),
        ), $tree->merge($a, $b));
    }

    /**
     * @expectedException \Symfony\Component\Config\Definition\Exception\InvalidConfigurationException
     */
    public function testDoesNotAllowNewKeysInSubsequentConfigs()
    {
        $tb = new TreeBuilder();
        $tree = $tb
            ->root('config', 'array')
                ->children()
                    ->node('test', 'array')
                        ->disallowNewKeysInSubsequentConfigs()
                        ->useAttributeAsKey('key')
                        ->prototype('array')
                            ->children()
                                ->node('value', 'scalar')->end()
                            ->end()
                        ->end()
                    ->end()
                ->end()
            ->end()
            ->buildTree();

        $a = array(
            'test' => array(
                'a' => array('value' => 'foo'),
            ),
        );

        $b = array(
            'test' => array(
                'b' => array('value' => 'foo'),
            ),
        );

        $tree->merge($a, $b);
    }

    public function testPerformsNoDeepMerging()
    {
        $tb = new TreeBuilder();

        $tree = $tb
            ->root('config', 'array')
                ->children()
                    ->node('no_deep_merging', 'array')
                        ->performNoDeepMerging()
                        ->children()
                            ->node('foo', 'scalar')->end()
                            ->node('bar', 'scalar')->end()
                        ->end()
                    ->end()
                ->end()
            ->end()
            ->buildTree()
        ;

        $a = array(
            'no_deep_merging' => array(
                'foo' => 'a',
                'bar' => 'b',
            ),
        );

        $b = array(
            'no_deep_merging' => array(
                'c' => 'd',
            ),
        );

        $this->assertEquals(array(
            'no_deep_merging' => array(
                'c' => 'd',
            ),
        ), $tree->merge($a, $b));
    }

    public function testPrototypeWithoutAKeyAttribute()
    {
        $tb = new TreeBuilder();

        $tree = $tb
            ->root('config', 'array')
                ->children()
                    ->arrayNode('append_elements')
                        ->prototype('scalar')->end()
                    ->end()
                ->end()
            ->end()
            ->buildTree()
        ;

        $a = array(
            'append_elements' => array('a', 'b'),
        );

        $b = array(
            'append_elements' => array('c', 'd'),
        );

        $this->assertEquals(array('append_elements' => array('a', 'b', 'c', 'd')), $tree->merge($a, $b));
    }
}
PKϤ$Z=a��-�-3config/Tests/Definition/PrototypedArrayNodeTest.phpnu�[���<?php

/*
 * This file is part of the Symfony package.
 *
 * (c) Fabien Potencier <fabien@symfony.com>
 *
 * For the full copyright and license information, please view the LICENSE
 * file that was distributed with this source code.
 */

namespace Symfony\Component\Config\Tests\Definition;

use PHPUnit\Framework\TestCase;
use Symfony\Component\Config\Definition\PrototypedArrayNode;
use Symfony\Component\Config\Definition\ArrayNode;
use Symfony\Component\Config\Definition\ScalarNode;
use Symfony\Component\Config\Definition\VariableNode;

class PrototypedArrayNodeTest extends TestCase
{
    public function testGetDefaultValueReturnsAnEmptyArrayForPrototypes()
    {
        $node = new PrototypedArrayNode('root');
        $prototype = new ArrayNode(null, $node);
        $node->setPrototype($prototype);
        $this->assertEmpty($node->getDefaultValue());
    }

    public function testGetDefaultValueReturnsDefaultValueForPrototypes()
    {
        $node = new PrototypedArrayNode('root');
        $prototype = new ArrayNode(null, $node);
        $node->setPrototype($prototype);
        $node->setDefaultValue(array('test'));
        $this->assertEquals(array('test'), $node->getDefaultValue());
    }

    // a remapped key (e.g. "mapping" -> "mappings") should be unset after being used
    public function testRemappedKeysAreUnset()
    {
        $node = new ArrayNode('root');
        $mappingsNode = new PrototypedArrayNode('mappings');
        $node->addChild($mappingsNode);

        // each item under mappings is just a scalar
        $prototype = new ScalarNode(null, $mappingsNode);
        $mappingsNode->setPrototype($prototype);

        $remappings = array();
        $remappings[] = array('mapping', 'mappings');
        $node->setXmlRemappings($remappings);

        $normalized = $node->normalize(array('mapping' => array('foo', 'bar')));
        $this->assertEquals(array('mappings' => array('foo', 'bar')), $normalized);
    }

    /**
     * Tests that when a key attribute is mapped, that key is removed from the array.
     *
     *     <things>
     *         <option id="option1" value="foo">
     *         <option id="option2" value="bar">
     *     </things>
     *
     * The above should finally be mapped to an array that looks like this
     * (because "id" is the key attribute).
     *
     *     array(
     *         'things' => array(
     *             'option1' => 'foo',
     *             'option2' => 'bar',
     *         )
     *     )
     */
    public function testMappedAttributeKeyIsRemoved()
    {
        $node = new PrototypedArrayNode('root');
        $node->setKeyAttribute('id', true);

        // each item under the root is an array, with one scalar item
        $prototype = new ArrayNode(null, $node);
        $prototype->addChild(new ScalarNode('foo'));
        $node->setPrototype($prototype);

        $children = array();
        $children[] = array('id' => 'item_name', 'foo' => 'bar');
        $normalized = $node->normalize($children);

        $expected = array();
        $expected['item_name'] = array('foo' => 'bar');
        $this->assertEquals($expected, $normalized);
    }

    /**
     * Tests the opposite of the testMappedAttributeKeyIsRemoved because
     * the removal can be toggled with an option.
     */
    public function testMappedAttributeKeyNotRemoved()
    {
        $node = new PrototypedArrayNode('root');
        $node->setKeyAttribute('id', false);

        // each item under the root is an array, with two scalar items
        $prototype = new ArrayNode(null, $node);
        $prototype->addChild(new ScalarNode('foo'));
        $prototype->addChild(new ScalarNode('id')); // the key attribute will remain
        $node->setPrototype($prototype);

        $children = array();
        $children[] = array('id' => 'item_name', 'foo' => 'bar');
        $normalized = $node->normalize($children);

        $expected = array();
        $expected['item_name'] = array('id' => 'item_name', 'foo' => 'bar');
        $this->assertEquals($expected, $normalized);
    }

    public function testAddDefaultChildren()
    {
        $node = $this->getPrototypeNodeWithDefaultChildren();
        $node->setAddChildrenIfNoneSet();
        $this->assertTrue($node->hasDefaultValue());
        $this->assertEquals(array(array('foo' => 'bar')), $node->getDefaultValue());

        $node = $this->getPrototypeNodeWithDefaultChildren();
        $node->setKeyAttribute('foobar');
        $node->setAddChildrenIfNoneSet();
        $this->assertTrue($node->hasDefaultValue());
        $this->assertEquals(array('defaults' => array('foo' => 'bar')), $node->getDefaultValue());

        $node = $this->getPrototypeNodeWithDefaultChildren();
        $node->setKeyAttribute('foobar');
        $node->setAddChildrenIfNoneSet('defaultkey');
        $this->assertTrue($node->hasDefaultValue());
        $this->assertEquals(array('defaultkey' => array('foo' => 'bar')), $node->getDefaultValue());

        $node = $this->getPrototypeNodeWithDefaultChildren();
        $node->setKeyAttribute('foobar');
        $node->setAddChildrenIfNoneSet(array('defaultkey'));
        $this->assertTrue($node->hasDefaultValue());
        $this->assertEquals(array('defaultkey' => array('foo' => 'bar')), $node->getDefaultValue());

        $node = $this->getPrototypeNodeWithDefaultChildren();
        $node->setKeyAttribute('foobar');
        $node->setAddChildrenIfNoneSet(array('dk1', 'dk2'));
        $this->assertTrue($node->hasDefaultValue());
        $this->assertEquals(array('dk1' => array('foo' => 'bar'), 'dk2' => array('foo' => 'bar')), $node->getDefaultValue());

        $node = $this->getPrototypeNodeWithDefaultChildren();
        $node->setAddChildrenIfNoneSet(array(5, 6));
        $this->assertTrue($node->hasDefaultValue());
        $this->assertEquals(array(0 => array('foo' => 'bar'), 1 => array('foo' => 'bar')), $node->getDefaultValue());

        $node = $this->getPrototypeNodeWithDefaultChildren();
        $node->setAddChildrenIfNoneSet(2);
        $this->assertTrue($node->hasDefaultValue());
        $this->assertEquals(array(array('foo' => 'bar'), array('foo' => 'bar')), $node->getDefaultValue());
    }

    public function testDefaultChildrenWinsOverDefaultValue()
    {
        $node = $this->getPrototypeNodeWithDefaultChildren();
        $node->setAddChildrenIfNoneSet();
        $node->setDefaultValue(array('bar' => 'foo'));
        $this->assertTrue($node->hasDefaultValue());
        $this->assertEquals(array(array('foo' => 'bar')), $node->getDefaultValue());
    }

    protected function getPrototypeNodeWithDefaultChildren()
    {
        $node = new PrototypedArrayNode('root');
        $prototype = new ArrayNode(null, $node);
        $child = new ScalarNode('foo');
        $child->setDefaultValue('bar');
        $prototype->addChild($child);
        $prototype->setAddIfNotSet(true);
        $node->setPrototype($prototype);

        return $node;
    }

    /**
     * Tests that when a key attribute is mapped, that key is removed from the array.
     * And if only 'value' element is left in the array, it will replace its wrapper array.
     *
     *     <things>
     *         <option id="option1" value="value1">
     *     </things>
     *
     * The above should finally be mapped to an array that looks like this
     * (because "id" is the key attribute).
     *
     *     array(
     *         'things' => array(
     *             'option1' => 'value1'
     *         )
     *     )
     *
     * It's also possible to mix 'value-only' and 'non-value-only' elements in the array.
     *
     * <things>
     *     <option id="option1" value="value1">
     *     <option id="option2" value="value2" foo="foo2">
     * </things>
     *
     * The above should finally be mapped to an array as follows
     *
     * array(
     *     'things' => array(
     *         'option1' => 'value1',
     *         'option2' => array(
     *             'value' => 'value2',
     *             'foo' => 'foo2'
     *         )
     *     )
     * )
     *
     * The 'value' element can also be ArrayNode:
     *
     * <things>
     *     <option id="option1">
     *         <value>
     *            <foo>foo1</foo>
     *            <bar>bar1</bar>
     *         </value>
     *     </option>
     * </things>
     *
     * The above should be finally be mapped to an array as follows
     *
     * array(
     *     'things' => array(
     *         'option1' => array(
     *             'foo' => 'foo1',
     *             'bar' => 'bar1'
     *         )
     *     )
     * )
     *
     * If using VariableNode for value node, it's also possible to mix different types of value nodes:
     *
     * <things>
     *     <option id="option1">
     *         <value>
     *            <foo>foo1</foo>
     *            <bar>bar1</bar>
     *         </value>
     *     </option>
     *     <option id="option2" value="value2">
     * </things>
     *
     * The above should be finally mapped to an array as follows
     *
     * array(
     *     'things' => array(
     *         'option1' => array(
     *             'foo' => 'foo1',
     *             'bar' => 'bar1'
     *         ),
     *         'option2' => 'value2'
     *     )
     * )
     *
     *
     * @dataProvider getDataForKeyRemovedLeftValueOnly
     */
    public function testMappedAttributeKeyIsRemovedLeftValueOnly($value, $children, $expected)
    {
        $node = new PrototypedArrayNode('root');
        $node->setKeyAttribute('id', true);

        // each item under the root is an array, with one scalar item
        $prototype = new ArrayNode(null, $node);
        $prototype->addChild(new ScalarNode('id'));
        $prototype->addChild(new ScalarNode('foo'));
        $prototype->addChild($value);
        $node->setPrototype($prototype);

        $normalized = $node->normalize($children);
        $this->assertEquals($expected, $normalized);
    }

    public function getDataForKeyRemovedLeftValueOnly()
    {
        $scalarValue = new ScalarNode('value');

        $arrayValue = new ArrayNode('value');
        $arrayValue->addChild(new ScalarNode('foo'));
        $arrayValue->addChild(new ScalarNode('bar'));

        $variableValue = new VariableNode('value');

        return array(
           array(
               $scalarValue,
               array(
                   array('id' => 'option1', 'value' => 'value1'),
               ),
               array('option1' => 'value1'),
           ),

           array(
               $scalarValue,
               array(
                   array('id' => 'option1', 'value' => 'value1'),
                   array('id' => 'option2', 'value' => 'value2', 'foo' => 'foo2'),
               ),
               array(
                   'option1' => 'value1',
                   'option2' => array('value' => 'value2', 'foo' => 'foo2'),
               ),
           ),

           array(
               $arrayValue,
               array(
                   array(
                       'id' => 'option1',
                       'value' => array('foo' => 'foo1', 'bar' => 'bar1'),
                   ),
               ),
               array(
                   'option1' => array('foo' => 'foo1', 'bar' => 'bar1'),
               ),
           ),

           array($variableValue,
               array(
                   array(
                       'id' => 'option1', 'value' => array('foo' => 'foo1', 'bar' => 'bar1'),
                   ),
                   array('id' => 'option2', 'value' => 'value2'),
               ),
               array(
                   'option1' => array('foo' => 'foo1', 'bar' => 'bar1'),
                   'option2' => 'value2',
               ),
           ),
        );
    }
}
PKϤ$Z�__,config/Tests/Definition/FinalizationTest.phpnu�[���<?php

/*
 * This file is part of the Symfony package.
 *
 * (c) Fabien Potencier <fabien@symfony.com>
 *
 * For the full copyright and license information, please view the LICENSE
 * file that was distributed with this source code.
 */

namespace Symfony\Component\Config\Tests\Definition;

use PHPUnit\Framework\TestCase;
use Symfony\Component\Config\Definition\Builder\TreeBuilder;
use Symfony\Component\Config\Definition\Processor;
use Symfony\Component\Config\Definition\NodeInterface;

class FinalizationTest extends TestCase
{
    public function testUnsetKeyWithDeepHierarchy()
    {
        $tb = new TreeBuilder();
        $tree = $tb
            ->root('config', 'array')
                ->children()
                    ->node('level1', 'array')
                        ->canBeUnset()
                        ->children()
                            ->node('level2', 'array')
                                ->canBeUnset()
                                ->children()
                                    ->node('somevalue', 'scalar')->end()
                                    ->node('anothervalue', 'scalar')->end()
                                ->end()
                            ->end()
                            ->node('level1_scalar', 'scalar')->end()
                        ->end()
                    ->end()
                ->end()
            ->end()
            ->buildTree()
        ;

        $a = array(
            'level1' => array(
                'level2' => array(
                    'somevalue' => 'foo',
                    'anothervalue' => 'bar',
                ),
                'level1_scalar' => 'foo',
            ),
        );

        $b = array(
            'level1' => array(
                'level2' => false,
            ),
        );

        $this->assertEquals(array(
            'level1' => array(
                'level1_scalar' => 'foo',
            ),
        ), $this->process($tree, array($a, $b)));
    }

    protected function process(NodeInterface $tree, array $configs)
    {
        $processor = new Processor();

        return $processor->process($tree, $configs);
    }
}
PKϤ$Z^�;LL(config/Tests/Definition/EnumNodeTest.phpnu�[���<?php

/*
 * This file is part of the Symfony package.
 *
 * (c) Fabien Potencier <fabien@symfony.com>
 *
 * For the full copyright and license information, please view the LICENSE
 * file that was distributed with this source code.
 */

namespace Symfony\Component\Config\Tests\Definition;

use PHPUnit\Framework\TestCase;
use Symfony\Component\Config\Definition\EnumNode;

class EnumNodeTest extends TestCase
{
    public function testFinalizeValue()
    {
        $node = new EnumNode('foo', null, array('foo', 'bar'));
        $this->assertSame('foo', $node->finalize('foo'));
    }

    /**
     * @expectedException \InvalidArgumentException
     * @expectedExceptionMessage $values must contain at least one element.
     */
    public function testConstructionWithNoValues()
    {
        new EnumNode('foo', null, array());
    }

    public function testConstructionWithOneValue()
    {
        $node = new EnumNode('foo', null, array('foo'));
        $this->assertSame('foo', $node->finalize('foo'));
    }

    public function testConstructionWithOneDistinctValue()
    {
        $node = new EnumNode('foo', null, array('foo', 'foo'));
        $this->assertSame('foo', $node->finalize('foo'));
    }

    /**
     * @expectedException \Symfony\Component\Config\Definition\Exception\InvalidConfigurationException
     * @expectedExceptionMessage The value "foobar" is not allowed for path "foo". Permissible values: "foo", "bar"
     */
    public function testFinalizeWithInvalidValue()
    {
        $node = new EnumNode('foo', null, array('foo', 'bar'));
        $node->finalize('foobar');
    }
}
PKϤ$Zep���+config/Tests/Definition/IntegerNodeTest.phpnu�[���<?php

/*
 * This file is part of the Symfony package.
 *
 * (c) Fabien Potencier <fabien@symfony.com>
 *
 * For the full copyright and license information, please view the LICENSE
 * file that was distributed with this source code.
 */

namespace Symfony\Component\Config\Tests\Definition;

use PHPUnit\Framework\TestCase;
use Symfony\Component\Config\Definition\IntegerNode;

class IntegerNodeTest extends TestCase
{
    /**
     * @dataProvider getValidValues
     */
    public function testNormalize($value)
    {
        $node = new IntegerNode('test');
        $this->assertSame($value, $node->normalize($value));
    }

    /**
     * @dataProvider getValidValues
     *
     * @param int $value
     */
    public function testValidNonEmptyValues($value)
    {
        $node = new IntegerNode('test');
        $node->setAllowEmptyValue(false);

        $this->assertSame($value, $node->finalize($value));
    }

    public function getValidValues()
    {
        return array(
            array(1798),
            array(-678),
            array(0),
        );
    }

    /**
     * @dataProvider getInvalidValues
     * @expectedException \Symfony\Component\Config\Definition\Exception\InvalidTypeException
     */
    public function testNormalizeThrowsExceptionOnInvalidValues($value)
    {
        $node = new IntegerNode('test');
        $node->normalize($value);
    }

    public function getInvalidValues()
    {
        return array(
            array(null),
            array(''),
            array('foo'),
            array(true),
            array(false),
            array(0.0),
            array(0.1),
            array(array()),
            array(array('foo' => 'bar')),
            array(new \stdClass()),
        );
    }
}
PKϤ$Z�BN@@@)config/Tests/Definition/FloatNodeTest.phpnu�[���<?php

/*
 * This file is part of the Symfony package.
 *
 * (c) Fabien Potencier <fabien@symfony.com>
 *
 * For the full copyright and license information, please view the LICENSE
 * file that was distributed with this source code.
 */

namespace Symfony\Component\Config\Tests\Definition;

use PHPUnit\Framework\TestCase;
use Symfony\Component\Config\Definition\FloatNode;

class FloatNodeTest extends TestCase
{
    /**
     * @dataProvider getValidValues
     */
    public function testNormalize($value)
    {
        $node = new FloatNode('test');
        $this->assertSame($value, $node->normalize($value));
    }

    /**
     * @dataProvider getValidValues
     *
     * @param int $value
     */
    public function testValidNonEmptyValues($value)
    {
        $node = new FloatNode('test');
        $node->setAllowEmptyValue(false);

        $this->assertSame($value, $node->finalize($value));
    }

    public function getValidValues()
    {
        return array(
            array(1798.0),
            array(-678.987),
            array(12.56E45),
            array(0.0),
            // Integer are accepted too, they will be cast
            array(17),
            array(-10),
            array(0),
        );
    }

    /**
     * @dataProvider getInvalidValues
     * @expectedException \Symfony\Component\Config\Definition\Exception\InvalidTypeException
     */
    public function testNormalizeThrowsExceptionOnInvalidValues($value)
    {
        $node = new FloatNode('test');
        $node->normalize($value);
    }

    public function getInvalidValues()
    {
        return array(
            array(null),
            array(''),
            array('foo'),
            array(true),
            array(false),
            array(array()),
            array(array('foo' => 'bar')),
            array(new \stdClass()),
        );
    }
}
PKϤ$Z�+���"config/Tests/Loader/LoaderTest.phpnu�[���<?php

/*
 * This file is part of the Symfony package.
 *
 * (c) Fabien Potencier <fabien@symfony.com>
 *
 * For the full copyright and license information, please view the LICENSE
 * file that was distributed with this source code.
 */

namespace Symfony\Component\Config\Tests\Loader;

use PHPUnit\Framework\TestCase;
use Symfony\Component\Config\Loader\Loader;

class LoaderTest extends TestCase
{
    public function testGetSetResolver()
    {
        $resolver = $this->getMockBuilder('Symfony\Component\Config\Loader\LoaderResolverInterface')->getMock();

        $loader = new ProjectLoader1();
        $loader->setResolver($resolver);

        $this->assertSame($resolver, $loader->getResolver(), '->setResolver() sets the resolver loader');
    }

    public function testResolve()
    {
        $resolvedLoader = $this->getMockBuilder('Symfony\Component\Config\Loader\LoaderInterface')->getMock();

        $resolver = $this->getMockBuilder('Symfony\Component\Config\Loader\LoaderResolverInterface')->getMock();
        $resolver->expects($this->once())
            ->method('resolve')
            ->with('foo.xml')
            ->will($this->returnValue($resolvedLoader));

        $loader = new ProjectLoader1();
        $loader->setResolver($resolver);

        $this->assertSame($loader, $loader->resolve('foo.foo'), '->resolve() finds a loader');
        $this->assertSame($resolvedLoader, $loader->resolve('foo.xml'), '->resolve() finds a loader');
    }

    /**
     * @expectedException \Symfony\Component\Config\Exception\FileLoaderLoadException
     */
    public function testResolveWhenResolverCannotFindLoader()
    {
        $resolver = $this->getMockBuilder('Symfony\Component\Config\Loader\LoaderResolverInterface')->getMock();
        $resolver->expects($this->once())
            ->method('resolve')
            ->with('FOOBAR')
            ->will($this->returnValue(false));

        $loader = new ProjectLoader1();
        $loader->setResolver($resolver);

        $loader->resolve('FOOBAR');
    }

    public function testImport()
    {
        $resolvedLoader = $this->getMockBuilder('Symfony\Component\Config\Loader\LoaderInterface')->getMock();
        $resolvedLoader->expects($this->once())
            ->method('load')
            ->with('foo')
            ->will($this->returnValue('yes'));

        $resolver = $this->getMockBuilder('Symfony\Component\Config\Loader\LoaderResolverInterface')->getMock();
        $resolver->expects($this->once())
            ->method('resolve')
            ->with('foo')
            ->will($this->returnValue($resolvedLoader));

        $loader = new ProjectLoader1();
        $loader->setResolver($resolver);

        $this->assertEquals('yes', $loader->import('foo'));
    }

    public function testImportWithType()
    {
        $resolvedLoader = $this->getMockBuilder('Symfony\Component\Config\Loader\LoaderInterface')->getMock();
        $resolvedLoader->expects($this->once())
            ->method('load')
            ->with('foo', 'bar')
            ->will($this->returnValue('yes'));

        $resolver = $this->getMockBuilder('Symfony\Component\Config\Loader\LoaderResolverInterface')->getMock();
        $resolver->expects($this->once())
            ->method('resolve')
            ->with('foo', 'bar')
            ->will($this->returnValue($resolvedLoader));

        $loader = new ProjectLoader1();
        $loader->setResolver($resolver);

        $this->assertEquals('yes', $loader->import('foo', 'bar'));
    }
}

class ProjectLoader1 extends Loader
{
    public function load($resource, $type = null)
    {
    }

    public function supports($resource, $type = null)
    {
        return is_string($resource) && 'foo' === pathinfo($resource, PATHINFO_EXTENSION);
    }

    public function getType()
    {
    }
}
PKϤ$Zhӈ�``,config/Tests/Loader/DelegatingLoaderTest.phpnu�[���<?php

/*
 * This file is part of the Symfony package.
 *
 * (c) Fabien Potencier <fabien@symfony.com>
 *
 * For the full copyright and license information, please view the LICENSE
 * file that was distributed with this source code.
 */

namespace Symfony\Component\Config\Tests\Loader;

use PHPUnit\Framework\TestCase;
use Symfony\Component\Config\Loader\LoaderResolver;
use Symfony\Component\Config\Loader\DelegatingLoader;

class DelegatingLoaderTest extends TestCase
{
    public function testConstructor()
    {
        $loader = new DelegatingLoader($resolver = new LoaderResolver());
        $this->assertTrue(true, '__construct() takes a loader resolver as its first argument');
    }

    public function testGetSetResolver()
    {
        $resolver = new LoaderResolver();
        $loader = new DelegatingLoader($resolver);
        $this->assertSame($resolver, $loader->getResolver(), '->getResolver() gets the resolver loader');
        $loader->setResolver($resolver = new LoaderResolver());
        $this->assertSame($resolver, $loader->getResolver(), '->setResolver() sets the resolver loader');
    }

    public function testSupports()
    {
        $loader1 = $this->getMockBuilder('Symfony\Component\Config\Loader\LoaderInterface')->getMock();
        $loader1->expects($this->once())->method('supports')->will($this->returnValue(true));
        $loader = new DelegatingLoader(new LoaderResolver(array($loader1)));
        $this->assertTrue($loader->supports('foo.xml'), '->supports() returns true if the resource is loadable');

        $loader1 = $this->getMockBuilder('Symfony\Component\Config\Loader\LoaderInterface')->getMock();
        $loader1->expects($this->once())->method('supports')->will($this->returnValue(false));
        $loader = new DelegatingLoader(new LoaderResolver(array($loader1)));
        $this->assertFalse($loader->supports('foo.foo'), '->supports() returns false if the resource is not loadable');
    }

    public function testLoad()
    {
        $loader = $this->getMockBuilder('Symfony\Component\Config\Loader\LoaderInterface')->getMock();
        $loader->expects($this->once())->method('supports')->will($this->returnValue(true));
        $loader->expects($this->once())->method('load');
        $resolver = new LoaderResolver(array($loader));
        $loader = new DelegatingLoader($resolver);

        $loader->load('foo');
    }

    /**
     * @expectedException \Symfony\Component\Config\Exception\FileLoaderLoadException
     */
    public function testLoadThrowsAnExceptionIfTheResourceCannotBeLoaded()
    {
        $loader = $this->getMockBuilder('Symfony\Component\Config\Loader\LoaderInterface')->getMock();
        $loader->expects($this->once())->method('supports')->will($this->returnValue(false));
        $resolver = new LoaderResolver(array($loader));
        $loader = new DelegatingLoader($resolver);

        $loader->load('foo');
    }
}
PKϤ$Z�sܶ&config/Tests/Loader/FileLoaderTest.phpnu�[���<?php

/*
 * This file is part of the Symfony package.
 *
 * (c) Fabien Potencier <fabien@symfony.com>
 *
 * For the full copyright and license information, please view the LICENSE
 * file that was distributed with this source code.
 */

namespace Symfony\Component\Config\Tests\Loader;

use PHPUnit\Framework\TestCase;
use Symfony\Component\Config\Loader\FileLoader;
use Symfony\Component\Config\Loader\LoaderResolver;

class FileLoaderTest extends TestCase
{
    public function testImportWithFileLocatorDelegation()
    {
        $locatorMock = $this->getMockBuilder('Symfony\Component\Config\FileLocatorInterface')->getMock();

        $locatorMockForAdditionalLoader = $this->getMockBuilder('Symfony\Component\Config\FileLocatorInterface')->getMock();
        $locatorMockForAdditionalLoader->expects($this->any())->method('locate')->will($this->onConsecutiveCalls(
                array('path/to/file1'),                    // Default
                array('path/to/file1', 'path/to/file2'),   // First is imported
                array('path/to/file1', 'path/to/file2'),   // Second is imported
                array('path/to/file1'),                    // Exception
                array('path/to/file1', 'path/to/file2')    // Exception
                ));

        $fileLoader = new TestFileLoader($locatorMock);
        $fileLoader->setSupports(false);
        $fileLoader->setCurrentDir('.');

        $additionalLoader = new TestFileLoader($locatorMockForAdditionalLoader);
        $additionalLoader->setCurrentDir('.');

        $fileLoader->setResolver($loaderResolver = new LoaderResolver(array($fileLoader, $additionalLoader)));

        // Default case
        $this->assertSame('path/to/file1', $fileLoader->import('my_resource'));

        // Check first file is imported if not already loading
        $this->assertSame('path/to/file1', $fileLoader->import('my_resource'));

        // Check second file is imported if first is already loading
        $fileLoader->addLoading('path/to/file1');
        $this->assertSame('path/to/file2', $fileLoader->import('my_resource'));

        // Check exception throws if first (and only available) file is already loading
        try {
            $fileLoader->import('my_resource');
            $this->fail('->import() throws a FileLoaderImportCircularReferenceException if the resource is already loading');
        } catch (\Exception $e) {
            $this->assertInstanceOf('Symfony\Component\Config\Exception\FileLoaderImportCircularReferenceException', $e, '->import() throws a FileLoaderImportCircularReferenceException if the resource is already loading');
        }

        // Check exception throws if all files are already loading
        try {
            $fileLoader->addLoading('path/to/file2');
            $fileLoader->import('my_resource');
            $this->fail('->import() throws a FileLoaderImportCircularReferenceException if the resource is already loading');
        } catch (\Exception $e) {
            $this->assertInstanceOf('Symfony\Component\Config\Exception\FileLoaderImportCircularReferenceException', $e, '->import() throws a FileLoaderImportCircularReferenceException if the resource is already loading');
        }
    }
}

class TestFileLoader extends FileLoader
{
    private $supports = true;

    public function load($resource, $type = null)
    {
        return $resource;
    }

    public function supports($resource, $type = null)
    {
        return $this->supports;
    }

    public function addLoading($resource)
    {
        self::$loading[$resource] = true;
    }

    public function removeLoading($resource)
    {
        unset(self::$loading[$resource]);
    }

    public function clearLoading()
    {
        self::$loading = array();
    }

    public function setSupports($supports)
    {
        $this->supports = $supports;
    }
}
PKϤ$Z���*config/Tests/Loader/LoaderResolverTest.phpnu�[���<?php

/*
 * This file is part of the Symfony package.
 *
 * (c) Fabien Potencier <fabien@symfony.com>
 *
 * For the full copyright and license information, please view the LICENSE
 * file that was distributed with this source code.
 */

namespace Symfony\Component\Config\Tests\Loader;

use PHPUnit\Framework\TestCase;
use Symfony\Component\Config\Loader\LoaderResolver;

class LoaderResolverTest extends TestCase
{
    public function testConstructor()
    {
        $resolver = new LoaderResolver(array(
            $loader = $this->getMockBuilder('Symfony\Component\Config\Loader\LoaderInterface')->getMock(),
        ));

        $this->assertEquals(array($loader), $resolver->getLoaders(), '__construct() takes an array of loaders as its first argument');
    }

    public function testResolve()
    {
        $loader = $this->getMockBuilder('Symfony\Component\Config\Loader\LoaderInterface')->getMock();
        $resolver = new LoaderResolver(array($loader));
        $this->assertFalse($resolver->resolve('foo.foo'), '->resolve() returns false if no loader is able to load the resource');

        $loader = $this->getMockBuilder('Symfony\Component\Config\Loader\LoaderInterface')->getMock();
        $loader->expects($this->once())->method('supports')->will($this->returnValue(true));
        $resolver = new LoaderResolver(array($loader));
        $this->assertEquals($loader, $resolver->resolve(function () {}), '->resolve() returns the loader for the given resource');
    }

    public function testLoaders()
    {
        $resolver = new LoaderResolver();
        $resolver->addLoader($loader = $this->getMockBuilder('Symfony\Component\Config\Loader\LoaderInterface')->getMock());

        $this->assertEquals(array($loader), $resolver->getLoaders(), 'addLoader() adds a loader');
    }
}
PKϤ$Zf���'config/Tests/ConfigCacheFactoryTest.phpnu�[���<?php

/*
 * This file is part of the Symfony package.
 *
 * (c) Fabien Potencier <fabien@symfony.com>
 *
 * For the full copyright and license information, please view the LICENSE
 * file that was distributed with this source code.
 */

namespace Symfony\Component\Config\Tests;

use PHPUnit\Framework\TestCase;
use Symfony\Component\Config\ConfigCacheFactory;

class ConfigCacheFactoryTest extends TestCase
{
    /**
     * @expectedException \InvalidArgumentException
     * @expectedExceptionMessage Invalid type for callback argument. Expected callable, but got "object".
     */
    public function testCachWithInvalidCallback()
    {
        $cacheFactory = new ConfigCacheFactory(true);

        $cacheFactory->cache('file', new \stdClass());
    }
}
PKϤ$Z�H�]��"config/Tests/Util/XmlUtilsTest.phpnu�[���<?php

/*
 * This file is part of the Symfony package.
 *
 * (c) Fabien Potencier <fabien@symfony.com>
 *
 * For the full copyright and license information, please view the LICENSE
 * file that was distributed with this source code.
 */

namespace Symfony\Component\Config\Tests\Util;

use PHPUnit\Framework\TestCase;
use Symfony\Component\Config\Util\XmlUtils;

class XmlUtilsTest extends TestCase
{
    public function testLoadFile()
    {
        $fixtures = __DIR__.'/../Fixtures/Util/';

        try {
            XmlUtils::loadFile($fixtures.'invalid.xml');
            $this->fail();
        } catch (\InvalidArgumentException $e) {
            $this->assertContains('ERROR 77', $e->getMessage());
        }

        try {
            XmlUtils::loadFile($fixtures.'document_type.xml');
            $this->fail();
        } catch (\InvalidArgumentException $e) {
            $this->assertContains('Document types are not allowed', $e->getMessage());
        }

        try {
            XmlUtils::loadFile($fixtures.'invalid_schema.xml', $fixtures.'schema.xsd');
            $this->fail();
        } catch (\InvalidArgumentException $e) {
            $this->assertContains('ERROR 1845', $e->getMessage());
        }

        try {
            XmlUtils::loadFile($fixtures.'invalid_schema.xml', 'invalid_callback_or_file');
            $this->fail();
        } catch (\InvalidArgumentException $e) {
            $this->assertContains('XSD file or callable', $e->getMessage());
        }

        $mock = $this->getMockBuilder(__NAMESPACE__.'\Validator')->getMock();
        $mock->expects($this->exactly(2))->method('validate')->will($this->onConsecutiveCalls(false, true));

        try {
            XmlUtils::loadFile($fixtures.'valid.xml', array($mock, 'validate'));
            $this->fail();
        } catch (\InvalidArgumentException $e) {
            $this->assertContains('is not valid', $e->getMessage());
        }

        $this->assertInstanceOf('DOMDocument', XmlUtils::loadFile($fixtures.'valid.xml', array($mock, 'validate')));
        $this->assertSame(array(), libxml_get_errors());
    }

    public function testLoadFileWithInternalErrorsEnabled()
    {
        $internalErrors = libxml_use_internal_errors(true);

        $this->assertSame(array(), libxml_get_errors());
        $this->assertInstanceOf('DOMDocument', XmlUtils::loadFile(__DIR__.'/../Fixtures/Util/invalid_schema.xml'));
        $this->assertSame(array(), libxml_get_errors());

        libxml_clear_errors();
        libxml_use_internal_errors($internalErrors);
    }

    /**
     * @dataProvider getDataForConvertDomToArray
     */
    public function testConvertDomToArray($expected, $xml, $root = false, $checkPrefix = true)
    {
        $dom = new \DOMDocument();
        $dom->loadXML($root ? $xml : '<root>'.$xml.'</root>');

        $this->assertSame($expected, XmlUtils::convertDomElementToArray($dom->documentElement, $checkPrefix));
    }

    public function getDataForConvertDomToArray()
    {
        return array(
            array(null, ''),
            array('bar', 'bar'),
            array(array('bar' => 'foobar'), '<foo bar="foobar" />', true),
            array(array('foo' => null), '<foo />'),
            array(array('foo' => 'bar'), '<foo>bar</foo>'),
            array(array('foo' => array('foo' => 'bar')), '<foo foo="bar"/>'),
            array(array('foo' => array('foo' => 0)), '<foo><foo>0</foo></foo>'),
            array(array('foo' => array('foo' => 'bar')), '<foo><foo>bar</foo></foo>'),
            array(array('foo' => array('foo' => 'bar', 'value' => 'text')), '<foo foo="bar">text</foo>'),
            array(array('foo' => array('attr' => 'bar', 'foo' => 'text')), '<foo attr="bar"><foo>text</foo></foo>'),
            array(array('foo' => array('bar', 'text')), '<foo>bar</foo><foo>text</foo>'),
            array(array('foo' => array(array('foo' => 'bar'), array('foo' => 'text'))), '<foo foo="bar"/><foo foo="text" />'),
            array(array('foo' => array('foo' => array('bar', 'text'))), '<foo foo="bar"><foo>text</foo></foo>'),
            array(array('foo' => 'bar'), '<foo><!-- Comment -->bar</foo>'),
            array(array('foo' => 'text'), '<foo xmlns:h="http://www.example.org/bar" h:bar="bar">text</foo>'),
            array(array('foo' => array('bar' => 'bar', 'value' => 'text')), '<foo xmlns:h="http://www.example.org/bar" h:bar="bar">text</foo>', false, false),
            array(array('attr' => 1, 'b' => 'hello'), '<foo:a xmlns:foo="http://www.example.org/foo" xmlns:h="http://www.example.org/bar" attr="1" h:bar="bar"><foo:b>hello</foo:b><h:c>2</h:c></foo:a>', true),
        );
    }

    /**
     * @dataProvider getDataForPhpize
     */
    public function testPhpize($expected, $value)
    {
        $this->assertSame($expected, XmlUtils::phpize($value));
    }

    public function getDataForPhpize()
    {
        return array(
            array('', ''),
            array(null, 'null'),
            array(true, 'true'),
            array(false, 'false'),
            array(null, 'Null'),
            array(true, 'True'),
            array(false, 'False'),
            array(0, '0'),
            array(1, '1'),
            array(-1, '-1'),
            array(0777, '0777'),
            array(255, '0xFF'),
            array(100.0, '1e2'),
            array(-120.0, '-1.2E2'),
            array(-10100.1, '-10100.1'),
            array('-10,100.1', '-10,100.1'),
            array('1234 5678 9101 1121 3141', '1234 5678 9101 1121 3141'),
            array('1,2,3,4', '1,2,3,4'),
            array('11,22,33,44', '11,22,33,44'),
            array('11,222,333,4', '11,222,333,4'),
            array('1,222,333,444', '1,222,333,444'),
            array('11,222,333,444', '11,222,333,444'),
            array('111,222,333,444', '111,222,333,444'),
            array('1111,2222,3333,4444,5555', '1111,2222,3333,4444,5555'),
            array('foo', 'foo'),
            array(6, '0b0110'),
        );
    }

    public function testLoadEmptyXmlFile()
    {
        $file = __DIR__.'/../Fixtures/foo.xml';

        if (method_exists($this, 'expectException')) {
            $this->expectException('InvalidArgumentException');
            $this->expectExceptionMessage(sprintf('File %s does not contain valid XML, it is empty.', $file));
        } else {
            $this->setExpectedException('InvalidArgumentException', sprintf('File %s does not contain valid XML, it is empty.', $file));
        }

        XmlUtils::loadFile($file);
    }

    // test for issue https://github.com/symfony/symfony/issues/9731
    public function testLoadWrongEmptyXMLWithErrorHandler()
    {
        $originalDisableEntities = libxml_disable_entity_loader(false);
        $errorReporting = error_reporting(-1);

        set_error_handler(function ($errno, $errstr) {
            throw new \Exception($errstr, $errno);
        });

        $file = __DIR__.'/../Fixtures/foo.xml';
        try {
            try {
                XmlUtils::loadFile($file);
                $this->fail('An exception should have been raised');
            } catch (\InvalidArgumentException $e) {
                $this->assertEquals(sprintf('File %s does not contain valid XML, it is empty.', $file), $e->getMessage());
            }
        } finally {
            restore_error_handler();
            error_reporting($errorReporting);
        }

        $disableEntities = libxml_disable_entity_loader(true);
        libxml_disable_entity_loader($disableEntities);

        libxml_disable_entity_loader($originalDisableEntities);

        $this->assertFalse($disableEntities);

        // should not throw an exception
        XmlUtils::loadFile(__DIR__.'/../Fixtures/Util/valid.xml', __DIR__.'/../Fixtures/Util/schema.xsd');
    }
}

interface Validator
{
    public function validate();
}
PKϤ$Z"XB���/config/Tests/ResourceCheckerConfigCacheTest.phpnu�[���<?php

/*
 * This file is part of the Symfony package.
 *
 * (c) Fabien Potencier <fabien@symfony.com>
 *
 * For the full copyright and license information, please view the LICENSE
 * file that was distributed with this source code.
 */

namespace Symfony\Component\Config\Tests;

use PHPUnit\Framework\TestCase;
use Symfony\Component\Config\Tests\Resource\ResourceStub;
use Symfony\Component\Config\Resource\FileResource;
use Symfony\Component\Config\ResourceCheckerConfigCache;

class ResourceCheckerConfigCacheTest extends TestCase
{
    private $cacheFile = null;

    protected function setUp()
    {
        $this->cacheFile = tempnam(sys_get_temp_dir(), 'config_');
    }

    protected function tearDown()
    {
        $files = array($this->cacheFile, "{$this->cacheFile}.meta");

        foreach ($files as $file) {
            if (file_exists($file)) {
                unlink($file);
            }
        }
    }

    public function testGetPath()
    {
        $cache = new ResourceCheckerConfigCache($this->cacheFile);

        $this->assertSame($this->cacheFile, $cache->getPath());
    }

    public function testCacheIsNotFreshIfEmpty()
    {
        $checker = $this->getMockBuilder('\Symfony\Component\Config\ResourceCheckerInterface')->getMock()
            ->expects($this->never())->method('supports');

        /* If there is nothing in the cache, it needs to be filled (and thus it's not fresh).
            It does not matter if you provide checkers or not. */

        unlink($this->cacheFile); // remove tempnam() side effect
        $cache = new ResourceCheckerConfigCache($this->cacheFile, array($checker));

        $this->assertFalse($cache->isFresh());
    }

    public function testCacheIsFreshIfNocheckerProvided()
    {
        /* For example in prod mode, you may choose not to run any checkers
           at all. In that case, the cache should always be considered fresh. */
        $cache = new ResourceCheckerConfigCache($this->cacheFile);
        $this->assertTrue($cache->isFresh());
    }

    public function testResourcesWithoutcheckersAreIgnoredAndConsideredFresh()
    {
        /* As in the previous test, but this time we have a resource. */
        $cache = new ResourceCheckerConfigCache($this->cacheFile);
        $cache->write('', array(new ResourceStub()));

        $this->assertTrue($cache->isFresh()); // no (matching) ResourceChecker passed
    }

    public function testIsFreshWithchecker()
    {
        $checker = $this->getMockBuilder('\Symfony\Component\Config\ResourceCheckerInterface')->getMock();

        $checker->expects($this->once())
                  ->method('supports')
                  ->willReturn(true);

        $checker->expects($this->once())
                  ->method('isFresh')
                  ->willReturn(true);

        $cache = new ResourceCheckerConfigCache($this->cacheFile, array($checker));
        $cache->write('', array(new ResourceStub()));

        $this->assertTrue($cache->isFresh());
    }

    public function testIsNotFreshWithchecker()
    {
        $checker = $this->getMockBuilder('\Symfony\Component\Config\ResourceCheckerInterface')->getMock();

        $checker->expects($this->once())
                  ->method('supports')
                  ->willReturn(true);

        $checker->expects($this->once())
                  ->method('isFresh')
                  ->willReturn(false);

        $cache = new ResourceCheckerConfigCache($this->cacheFile, array($checker));
        $cache->write('', array(new ResourceStub()));

        $this->assertFalse($cache->isFresh());
    }

    public function testCacheIsNotFreshWhenUnserializeFails()
    {
        $checker = $this->getMockBuilder('\Symfony\Component\Config\ResourceCheckerInterface')->getMock();
        $cache = new ResourceCheckerConfigCache($this->cacheFile, array($checker));
        $cache->write('foo', array(new FileResource(__FILE__)));

        $metaFile = "{$this->cacheFile}.meta";
        file_put_contents($metaFile, str_replace('FileResource', 'ClassNotHere', file_get_contents($metaFile)));

        $this->assertFalse($cache->isFresh());
    }

    public function testCacheKeepsContent()
    {
        $cache = new ResourceCheckerConfigCache($this->cacheFile);
        $cache->write('FOOBAR');

        $this->assertSame('FOOBAR', file_get_contents($cache->getPath()));
    }

    public function testCacheIsNotFreshIfNotExistsMetaFile()
    {
        $checker = $this->getMockBuilder('\Symfony\Component\Config\ResourceCheckerInterface')->getMock();
        $cache = new ResourceCheckerConfigCache($this->cacheFile, array($checker));
        $cache->write('foo', array(new FileResource(__FILE__)));

        $metaFile = "{$this->cacheFile}.meta";
        unlink($metaFile);

        $this->assertFalse($cache->isFresh());
    }
}
PKϤ$Z��_��3config/Tests/Resource/FileExistenceResourceTest.phpnu�[���<?php

/*
 * This file is part of the Symfony package.
 *
 * (c) Fabien Potencier <fabien@symfony.com>
 *
 * For the full copyright and license information, please view the LICENSE
 * file that was distributed with this source code.
 */

namespace Symfony\Component\Config\Tests\Resource;

use PHPUnit\Framework\TestCase;
use Symfony\Component\Config\Resource\FileExistenceResource;

class FileExistenceResourceTest extends TestCase
{
    protected $resource;
    protected $file;
    protected $time;

    protected function setUp()
    {
        $this->file = realpath(sys_get_temp_dir()).'/tmp.xml';
        $this->time = time();
        $this->resource = new FileExistenceResource($this->file);
    }

    protected function tearDown()
    {
        if (file_exists($this->file)) {
            unlink($this->file);
        }
    }

    public function testToString()
    {
        $this->assertSame($this->file, (string) $this->resource);
    }

    public function testGetResource()
    {
        $this->assertSame($this->file, $this->resource->getResource(), '->getResource() returns the path to the resource');
    }

    public function testIsFreshWithExistingResource()
    {
        touch($this->file, $this->time);
        $serialized = serialize(new FileExistenceResource($this->file));

        $resource = unserialize($serialized);
        $this->assertTrue($resource->isFresh($this->time), '->isFresh() returns true if the resource is still present');

        unlink($this->file);
        $resource = unserialize($serialized);
        $this->assertFalse($resource->isFresh($this->time), '->isFresh() returns false if the resource has been deleted');
    }

    public function testIsFreshWithAbsentResource()
    {
        $serialized = serialize(new FileExistenceResource($this->file));

        $resource = unserialize($serialized);
        $this->assertTrue($resource->isFresh($this->time), '->isFresh() returns true if the resource is still absent');

        touch($this->file, $this->time);
        $resource = unserialize($serialized);
        $this->assertFalse($resource->isFresh($this->time), '->isFresh() returns false if the resource has been created');
    }
}
PKϤ$Z;��A

*config/Tests/Resource/FileResourceTest.phpnu�[���<?php

/*
 * This file is part of the Symfony package.
 *
 * (c) Fabien Potencier <fabien@symfony.com>
 *
 * For the full copyright and license information, please view the LICENSE
 * file that was distributed with this source code.
 */

namespace Symfony\Component\Config\Tests\Resource;

use PHPUnit\Framework\TestCase;
use Symfony\Component\Config\Resource\FileResource;

class FileResourceTest extends TestCase
{
    protected $resource;
    protected $file;
    protected $time;

    protected function setUp()
    {
        $this->file = sys_get_temp_dir().'/tmp.xml';
        $this->time = time();
        touch($this->file, $this->time);
        $this->resource = new FileResource($this->file);
    }

    protected function tearDown()
    {
        if (!file_exists($this->file)) {
            return;
        }

        unlink($this->file);
    }

    public function testGetResource()
    {
        $this->assertSame(realpath($this->file), $this->resource->getResource(), '->getResource() returns the path to the resource');
    }

    public function testGetResourceWithScheme()
    {
        $resource = new FileResource('file://'.$this->file);
        $this->assertSame('file://'.$this->file, $resource->getResource(), '->getResource() returns the path to the schemed resource');
    }

    public function testToString()
    {
        $this->assertSame(realpath($this->file), (string) $this->resource);
    }

    /**
     * @expectedException \InvalidArgumentException
     * @expectedExceptionMessageRegExp /The file ".*" does not exist./
     */
    public function testResourceDoesNotExist()
    {
        $resource = new FileResource('/____foo/foobar'.mt_rand(1, 999999));
    }

    public function testIsFresh()
    {
        $this->assertTrue($this->resource->isFresh($this->time), '->isFresh() returns true if the resource has not changed in same second');
        $this->assertTrue($this->resource->isFresh($this->time + 10), '->isFresh() returns true if the resource has not changed');
        $this->assertFalse($this->resource->isFresh($this->time - 86400), '->isFresh() returns false if the resource has been updated');
    }

    public function testIsFreshForDeletedResources()
    {
        unlink($this->file);

        $this->assertFalse($this->resource->isFresh($this->time), '->isFresh() returns false if the resource does not exist');
    }

    public function testSerializeUnserialize()
    {
        $unserialized = unserialize(serialize($this->resource));

        $this->assertSame(realpath($this->file), $this->resource->getResource());
    }
}
PKϤ$Z*�#��&config/Tests/Resource/ResourceStub.phpnu�[���<?php

/*
 * This file is part of the Symfony package.
 *
 * (c) Fabien Potencier <fabien@symfony.com>
 *
 * For the full copyright and license information, please view the LICENSE
 * file that was distributed with this source code.
 */

namespace Symfony\Component\Config\Tests\Resource;

use Symfony\Component\Config\Resource\SelfCheckingResourceInterface;

class ResourceStub implements SelfCheckingResourceInterface
{
    private $fresh = true;

    public function setFresh($isFresh)
    {
        $this->fresh = $isFresh;
    }

    public function __toString()
    {
        return 'stub';
    }

    public function isFresh($timestamp)
    {
        return $this->fresh;
    }
}
PKϤ$Z��PP4config/Tests/Resource/ClassExistenceResourceTest.phpnu�[���<?php

/*
 * This file is part of the Symfony package.
 *
 * (c) Fabien Potencier <fabien@symfony.com>
 *
 * For the full copyright and license information, please view the LICENSE
 * file that was distributed with this source code.
 */

namespace Symfony\Component\Config\Tests\Resource;

use PHPUnit\Framework\TestCase;
use Symfony\Component\Config\Resource\ClassExistenceResource;

class ClassExistenceResourceTest extends TestCase
{
    public function testToString()
    {
        $res = new ClassExistenceResource('BarClass');
        $this->assertSame('BarClass', (string) $res);
    }

    public function testGetResource()
    {
        $res = new ClassExistenceResource('BarClass');
        $this->assertSame('BarClass', $res->getResource());
    }

    public function testIsFreshWhenClassDoesNotExist()
    {
        $res = new ClassExistenceResource('Symfony\Component\Config\Tests\Fixtures\BarClass');

        $this->assertTrue($res->isFresh(time()));

        eval(<<<EOF
namespace Symfony\Component\Config\Tests\Fixtures;

class BarClass
{
}
EOF
        );

        $this->assertFalse($res->isFresh(time()));
    }

    public function testIsFreshWhenClassExists()
    {
        $res = new ClassExistenceResource('Symfony\Component\Config\Tests\Resource\ClassExistenceResourceTest');

        $this->assertTrue($res->isFresh(time()));
    }
}
PKϤ$Z��W��/config/Tests/Resource/DirectoryResourceTest.phpnu�[���<?php

/*
 * This file is part of the Symfony package.
 *
 * (c) Fabien Potencier <fabien@symfony.com>
 *
 * For the full copyright and license information, please view the LICENSE
 * file that was distributed with this source code.
 */

namespace Symfony\Component\Config\Tests\Resource;

use PHPUnit\Framework\TestCase;
use Symfony\Component\Config\Resource\DirectoryResource;

class DirectoryResourceTest extends TestCase
{
    protected $directory;

    protected function setUp()
    {
        $this->directory = sys_get_temp_dir().DIRECTORY_SEPARATOR.'symfonyDirectoryIterator';
        if (!file_exists($this->directory)) {
            mkdir($this->directory);
        }
        touch($this->directory.'/tmp.xml');
    }

    protected function tearDown()
    {
        if (!is_dir($this->directory)) {
            return;
        }
        $this->removeDirectory($this->directory);
    }

    protected function removeDirectory($directory)
    {
        $iterator = new \RecursiveIteratorIterator(new \RecursiveDirectoryIterator($directory), \RecursiveIteratorIterator::CHILD_FIRST);
        foreach ($iterator as $path) {
            if (preg_match('#[/\\\\]\.\.?$#', $path->__toString())) {
                continue;
            }
            if ($path->isDir()) {
                rmdir($path->__toString());
            } else {
                unlink($path->__toString());
            }
        }
        rmdir($directory);
    }

    public function testGetResource()
    {
        $resource = new DirectoryResource($this->directory);
        $this->assertSame(realpath($this->directory), $resource->getResource(), '->getResource() returns the path to the resource');
    }

    public function testGetPattern()
    {
        $resource = new DirectoryResource($this->directory, 'bar');
        $this->assertEquals('bar', $resource->getPattern());
    }

    /**
     * @expectedException \InvalidArgumentException
     * @expectedExceptionMessageRegExp /The directory ".*" does not exist./
     */
    public function testResourceDoesNotExist()
    {
        $resource = new DirectoryResource('/____foo/foobar'.mt_rand(1, 999999));
    }

    public function testIsFresh()
    {
        $resource = new DirectoryResource($this->directory);
        $this->assertTrue($resource->isFresh(time() + 10), '->isFresh() returns true if the resource has not changed');
        $this->assertFalse($resource->isFresh(time() - 86400), '->isFresh() returns false if the resource has been updated');
    }

    public function testIsFreshForDeletedResources()
    {
        $resource = new DirectoryResource($this->directory);
        $this->removeDirectory($this->directory);

        $this->assertFalse($resource->isFresh(time()), '->isFresh() returns false if the resource does not exist');
    }

    public function testIsFreshUpdateFile()
    {
        $resource = new DirectoryResource($this->directory);
        touch($this->directory.'/tmp.xml', time() + 20);
        $this->assertFalse($resource->isFresh(time() + 10), '->isFresh() returns false if an existing file is modified');
    }

    public function testIsFreshNewFile()
    {
        $resource = new DirectoryResource($this->directory);
        touch($this->directory.'/new.xml', time() + 20);
        $this->assertFalse($resource->isFresh(time() + 10), '->isFresh() returns false if a new file is added');
    }

    public function testIsFreshNewFileWithDifferentPattern()
    {
        $resource = new DirectoryResource($this->directory, '/.xml$/');
        touch($this->directory.'/new.yaml', time() + 20);
        $this->assertTrue($resource->isFresh(time() + 10), '->isFresh() returns true if a new file with a non-matching pattern is added');
    }

    public function testIsFreshDeleteFile()
    {
        $resource = new DirectoryResource($this->directory);
        $time = time();
        sleep(1);
        unlink($this->directory.'/tmp.xml');
        $this->assertFalse($resource->isFresh($time), '->isFresh() returns false if an existing file is removed');
    }

    public function testIsFreshDeleteDirectory()
    {
        $resource = new DirectoryResource($this->directory);
        $this->removeDirectory($this->directory);
        $this->assertFalse($resource->isFresh(time()), '->isFresh() returns false if the whole resource is removed');
    }

    public function testIsFreshCreateFileInSubdirectory()
    {
        $subdirectory = $this->directory.'/subdirectory';
        mkdir($subdirectory);

        $resource = new DirectoryResource($this->directory);
        $this->assertTrue($resource->isFresh(time() + 10), '->isFresh() returns true if an unmodified subdirectory exists');

        touch($subdirectory.'/newfile.xml', time() + 20);
        $this->assertFalse($resource->isFresh(time() + 10), '->isFresh() returns false if a new file in a subdirectory is added');
    }

    public function testIsFreshModifySubdirectory()
    {
        $resource = new DirectoryResource($this->directory);

        $subdirectory = $this->directory.'/subdirectory';
        mkdir($subdirectory);
        touch($subdirectory, time() + 20);

        $this->assertFalse($resource->isFresh(time() + 10), '->isFresh() returns false if a subdirectory is modified (e.g. a file gets deleted)');
    }

    public function testFilterRegexListNoMatch()
    {
        $resource = new DirectoryResource($this->directory, '/\.(foo|xml)$/');

        touch($this->directory.'/new.bar', time() + 20);
        $this->assertTrue($resource->isFresh(time() + 10), '->isFresh() returns true if a new file not matching the filter regex is created');
    }

    public function testFilterRegexListMatch()
    {
        $resource = new DirectoryResource($this->directory, '/\.(foo|xml)$/');

        touch($this->directory.'/new.xml', time() + 20);
        $this->assertFalse($resource->isFresh(time() + 10), '->isFresh() returns false if an new file matching the filter regex is created ');
    }

    public function testSerializeUnserialize()
    {
        $resource = new DirectoryResource($this->directory, '/\.(foo|xml)$/');

        $unserialized = unserialize(serialize($resource));

        $this->assertSame(realpath($this->directory), $resource->getResource());
        $this->assertSame('/\.(foo|xml)$/', $resource->getPattern());
    }

    public function testResourcesWithDifferentPatternsAreDifferent()
    {
        $resourceA = new DirectoryResource($this->directory, '/.xml$/');
        $resourceB = new DirectoryResource($this->directory, '/.yaml$/');

        $this->assertEquals(2, count(array_unique(array($resourceA, $resourceB))));
    }
}
PKϤ$Zconfig/Tests/Fixtures/foo.xmlnu�[���PKϤ$Z!U��zz!config/Tests/Fixtures/BarNode.phpnu�[���<?php

/*
 * This file is part of the Symfony package.
 *
 * (c) Fabien Potencier <fabien@symfony.com>
 *
 * For the full copyright and license information, please view the LICENSE
 * file that was distributed with this source code.
 */

namespace Symfony\Component\Config\Tests\Fixtures;

use Symfony\Component\Config\Definition\ArrayNode;

class BarNode extends ArrayNode
{
}
PKϤ$Z�?�..3config/Tests/Fixtures/Builder/BarNodeDefinition.phpnu�[���<?php

/*
 * This file is part of the Symfony package.
 *
 * (c) Fabien Potencier <fabien@symfony.com>
 *
 * For the full copyright and license information, please view the LICENSE
 * file that was distributed with this source code.
 */

namespace Symfony\Component\Config\Tests\Definition\Builder;

use Symfony\Component\Config\Definition\Builder\NodeDefinition;
use Symfony\Component\Config\Tests\Fixtures\BarNode;

class BarNodeDefinition extends NodeDefinition
{
    protected function createNode()
    {
        return new BarNode($this->name);
    }
}
PKϤ$Z��@��8config/Tests/Fixtures/Builder/VariableNodeDefinition.phpnu�[���<?php

/*
 * This file is part of the Symfony package.
 *
 * (c) Fabien Potencier <fabien@symfony.com>
 *
 * For the full copyright and license information, please view the LICENSE
 * file that was distributed with this source code.
 */

namespace Symfony\Component\Config\Tests\Definition\Builder;

use Symfony\Component\Config\Definition\Builder\VariableNodeDefinition as BaseVariableNodeDefinition;

class VariableNodeDefinition extends BaseVariableNodeDefinition
{
}
PKϤ$Z�u�;ss-config/Tests/Fixtures/Builder/NodeBuilder.phpnu�[���<?php

/*
 * This file is part of the Symfony package.
 *
 * (c) Fabien Potencier <fabien@symfony.com>
 *
 * For the full copyright and license information, please view the LICENSE
 * file that was distributed with this source code.
 */

namespace Symfony\Component\Config\Tests\Definition\Builder;

use Symfony\Component\Config\Definition\Builder\NodeBuilder as BaseNodeBuilder;

class NodeBuilder extends BaseNodeBuilder
{
    public function barNode($name)
    {
        return $this->node($name, 'bar');
    }

    protected function getNodeClass($type)
    {
        switch ($type) {
            case 'variable':
                return __NAMESPACE__.'\\'.ucfirst($type).'NodeDefinition';
            case 'bar':
                return __NAMESPACE__.'\\'.ucfirst($type).'NodeDefinition';
            default:
                return parent::getNodeClass($type);
        }
    }
}
PKϤ$Z�&�%config/Tests/Fixtures/Util/schema.xsdnu�[���<?xml version="1.0" encoding="UTF-8"?>

<xsd:schema xmlns="http://example.com/schema"
    xmlns:xsd="http://www.w3.org/2001/XMLSchema"
    targetNamespace="http://example.com/schema"
    elementFormDefault="qualified">

  <xsd:element name="root" />
</xsd:schema>
PKϤ$Z\�XX$config/Tests/Fixtures/Util/valid.xmlnu�[���<?xml version="1.0" encoding="UTF-8"?>
<root xmlns="http://example.com/schema">
</root>
PKϤ$Zc=���,config/Tests/Fixtures/Util/document_type.xmlnu�[���<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE scan [<!ENTITY test SYSTEM "php://filter/read=convert.base64-encode/resource={{ resource }}">]>
<scan></scan>
PKϤ$Z�b�..&config/Tests/Fixtures/Util/invalid.xmlnu�[���<?xml version="1.0" encoding="UTF-8"?>
<root>
PKϤ$ZGɩ�SS-config/Tests/Fixtures/Util/invalid_schema.xmlnu�[���<?xml version="1.0" encoding="UTF-8"?>
<root2 xmlns="http://example.com/schema" />
PKϤ$Z�Qø�<config/Tests/Fixtures/Configuration/ExampleConfiguration.phpnu�[���<?php

/*
 * This file is part of the Symfony package.
 *
 * (c) Fabien Potencier <fabien@symfony.com>
 *
 * For the full copyright and license information, please view the LICENSE
 * file that was distributed with this source code.
 */

namespace Symfony\Component\Config\Tests\Fixtures\Configuration;

use Symfony\Component\Config\Definition\Builder\TreeBuilder;
use Symfony\Component\Config\Definition\ConfigurationInterface;

class ExampleConfiguration implements ConfigurationInterface
{
    public function getConfigTreeBuilder()
    {
        $treeBuilder = new TreeBuilder();
        $rootNode = $treeBuilder->root('acme_root');

        $rootNode
            ->fixXmlConfig('parameter')
            ->fixXmlConfig('connection')
            ->fixXmlConfig('cms_page')
            ->children()
                ->booleanNode('boolean')->defaultTrue()->end()
                ->scalarNode('scalar_empty')->end()
                ->scalarNode('scalar_null')->defaultNull()->end()
                ->scalarNode('scalar_true')->defaultTrue()->end()
                ->scalarNode('scalar_false')->defaultFalse()->end()
                ->scalarNode('scalar_default')->defaultValue('default')->end()
                ->scalarNode('scalar_array_empty')->defaultValue(array())->end()
                ->scalarNode('scalar_array_defaults')->defaultValue(array('elem1', 'elem2'))->end()
                ->scalarNode('scalar_required')->isRequired()->end()
                ->scalarNode('node_with_a_looong_name')->end()
                ->enumNode('enum_with_default')->values(array('this', 'that'))->defaultValue('this')->end()
                ->enumNode('enum')->values(array('this', 'that'))->end()
                ->arrayNode('array')
                    ->info('some info')
                    ->canBeUnset()
                    ->children()
                        ->scalarNode('child1')->end()
                        ->scalarNode('child2')->end()
                        ->scalarNode('child3')
                            ->info(
                                "this is a long\n".
                                "multi-line info text\n".
                                'which should be indented'
                            )
                            ->example('example setting')
                        ->end()
                    ->end()
                ->end()
                ->arrayNode('scalar_prototyped')
                    ->prototype('scalar')->end()
                ->end()
                ->arrayNode('parameters')
                    ->useAttributeAsKey('name')
                    ->prototype('scalar')->info('Parameter name')->end()
                ->end()
                ->arrayNode('connections')
                    ->prototype('array')
                        ->children()
                            ->scalarNode('user')->end()
                            ->scalarNode('pass')->end()
                        ->end()
                    ->end()
                ->end()
                ->arrayNode('cms_pages')
                    ->useAttributeAsKey('page')
                    ->prototype('array')
                        ->useAttributeAsKey('locale')
                        ->prototype('array')
                            ->children()
                                ->scalarNode('title')->isRequired()->end()
                                ->scalarNode('path')->isRequired()->end()
                            ->end()
                        ->end()
                    ->end()
                ->end()
                ->arrayNode('pipou')
                    ->useAttributeAsKey('name')
                    ->prototype('array')
                        ->prototype('array')
                            ->children()
                                ->scalarNode('didou')
                                ->end()
                            ->end()
                        ->end()
                    ->end()
                ->end()
            ->end()
        ;

        return $treeBuilder;
    }
}
PKϤ$Z#config/Tests/Fixtures/Again/foo.xmlnu�[���PKϤ$Z@��� config/Tests/FileLocatorTest.phpnu�[���<?php

/*
 * This file is part of the Symfony package.
 *
 * (c) Fabien Potencier <fabien@symfony.com>
 *
 * For the full copyright and license information, please view the LICENSE
 * file that was distributed with this source code.
 */

namespace Symfony\Component\Config\Tests;

use PHPUnit\Framework\TestCase;
use Symfony\Component\Config\FileLocator;

class FileLocatorTest extends TestCase
{
    /**
     * @dataProvider getIsAbsolutePathTests
     */
    public function testIsAbsolutePath($path)
    {
        $loader = new FileLocator(array());
        $r = new \ReflectionObject($loader);
        $m = $r->getMethod('isAbsolutePath');
        $m->setAccessible(true);

        $this->assertTrue($m->invoke($loader, $path), '->isAbsolutePath() returns true for an absolute path');
    }

    public function getIsAbsolutePathTests()
    {
        return array(
            array('/foo.xml'),
            array('c:\\\\foo.xml'),
            array('c:/foo.xml'),
            array('\\server\\foo.xml'),
            array('https://server/foo.xml'),
            array('phar://server/foo.xml'),
        );
    }

    public function testLocate()
    {
        $loader = new FileLocator(__DIR__.'/Fixtures');

        $this->assertEquals(
            __DIR__.DIRECTORY_SEPARATOR.'FileLocatorTest.php',
            $loader->locate('FileLocatorTest.php', __DIR__),
            '->locate() returns the absolute filename if the file exists in the given path'
        );

        $this->assertEquals(
            __DIR__.'/Fixtures'.DIRECTORY_SEPARATOR.'foo.xml',
            $loader->locate('foo.xml', __DIR__),
            '->locate() returns the absolute filename if the file exists in one of the paths given in the constructor'
        );

        $this->assertEquals(
            __DIR__.'/Fixtures'.DIRECTORY_SEPARATOR.'foo.xml',
            $loader->locate(__DIR__.'/Fixtures'.DIRECTORY_SEPARATOR.'foo.xml', __DIR__),
            '->locate() returns the absolute filename if the file exists in one of the paths given in the constructor'
        );

        $loader = new FileLocator(array(__DIR__.'/Fixtures', __DIR__.'/Fixtures/Again'));

        $this->assertEquals(
            array(__DIR__.'/Fixtures'.DIRECTORY_SEPARATOR.'foo.xml', __DIR__.'/Fixtures/Again'.DIRECTORY_SEPARATOR.'foo.xml'),
            $loader->locate('foo.xml', __DIR__, false),
            '->locate() returns an array of absolute filenames'
        );

        $this->assertEquals(
            array(__DIR__.'/Fixtures'.DIRECTORY_SEPARATOR.'foo.xml', __DIR__.'/Fixtures/Again'.DIRECTORY_SEPARATOR.'foo.xml'),
            $loader->locate('foo.xml', __DIR__.'/Fixtures', false),
            '->locate() returns an array of absolute filenames'
        );

        $loader = new FileLocator(__DIR__.'/Fixtures/Again');

        $this->assertEquals(
            array(__DIR__.'/Fixtures'.DIRECTORY_SEPARATOR.'foo.xml', __DIR__.'/Fixtures/Again'.DIRECTORY_SEPARATOR.'foo.xml'),
            $loader->locate('foo.xml', __DIR__.'/Fixtures', false),
            '->locate() returns an array of absolute filenames'
        );
    }

    /**
     * @expectedException \Symfony\Component\Config\Exception\FileLocatorFileNotFoundException
     * @expectedExceptionMessage The file "foobar.xml" does not exist
     */
    public function testLocateThrowsAnExceptionIfTheFileDoesNotExists()
    {
        $loader = new FileLocator(array(__DIR__.'/Fixtures'));

        $loader->locate('foobar.xml', __DIR__);
    }

    /**
     * @expectedException \Symfony\Component\Config\Exception\FileLocatorFileNotFoundException
     */
    public function testLocateThrowsAnExceptionIfTheFileDoesNotExistsInAbsolutePath()
    {
        $loader = new FileLocator(array(__DIR__.'/Fixtures'));

        $loader->locate(__DIR__.'/Fixtures/foobar.xml', __DIR__);
    }

    /**
     * @expectedException \InvalidArgumentException
     * @expectedExceptionMessage An empty file name is not valid to be located.
     */
    public function testLocateEmpty()
    {
        $loader = new FileLocator(array(__DIR__.'/Fixtures'));

        $loader->locate(null, __DIR__);
    }
}
PKϤ$Z�>�u))6config/Tests/Exception/FileLoaderLoadExceptionTest.phpnu�[���<?php

/*
 * This file is part of the Symfony package.
 *
 * (c) Fabien Potencier <fabien@symfony.com>
 *
 * For the full copyright and license information, please view the LICENSE
 * file that was distributed with this source code.
 */

namespace Symfony\Component\Config\Tests\Exception;

use PHPUnit\Framework\TestCase;
use Symfony\Component\Config\Exception\FileLoaderLoadException;

class FileLoaderLoadExceptionTest extends TestCase
{
    public function testMessageCannotLoadResource()
    {
        $exception = new FileLoaderLoadException('resource', null);
        $this->assertEquals('Cannot load resource "resource".', $exception->getMessage());
    }

    public function testMessageCannotImportResourceFromSource()
    {
        $exception = new FileLoaderLoadException('resource', 'sourceResource');
        $this->assertEquals('Cannot import resource "resource" from "sourceResource".', $exception->getMessage());
    }

    public function testMessageCannotImportBundleResource()
    {
        $exception = new FileLoaderLoadException('@resource', 'sourceResource');
        $this->assertEquals(
            'Cannot import resource "@resource" from "sourceResource". '.
            'Make sure the "resource" bundle is correctly registered and loaded in the application kernel class. '.
            'If the bundle is registered, make sure the bundle path "@resource" is not empty.',
            $exception->getMessage()
        );
    }

    public function testMessageHasPreviousErrorWithDotAndUnableToLoad()
    {
        $exception = new FileLoaderLoadException(
            'resource',
            null,
            null,
            new \Exception('There was a previous error with an ending dot.')
        );
        $this->assertEquals(
            'There was a previous error with an ending dot in resource (which is loaded in resource "resource").',
            $exception->getMessage()
        );
    }

    public function testMessageHasPreviousErrorWithoutDotAndUnableToLoad()
    {
        $exception = new FileLoaderLoadException(
            'resource',
            null,
            null,
            new \Exception('There was a previous error with no ending dot')
        );
        $this->assertEquals(
            'There was a previous error with no ending dot in resource (which is loaded in resource "resource").',
            $exception->getMessage()
        );
    }

    public function testMessageHasPreviousErrorAndUnableToLoadBundle()
    {
        $exception = new FileLoaderLoadException(
            '@resource',
            null,
            null,
            new \Exception('There was a previous error with an ending dot.')
        );
        $this->assertEquals(
            'There was a previous error with an ending dot in @resource '.
            '(which is loaded in resource "@resource"). '.
            'Make sure the "resource" bundle is correctly registered and loaded in the application kernel class. '.
            'If the bundle is registered, make sure the bundle path "@resource" is not empty.',
            $exception->getMessage()
        );
    }
}
PKϤ$Z�6M�	�	 config/Tests/ConfigCacheTest.phpnu�[���<?php

/*
 * This file is part of the Symfony package.
 *
 * (c) Fabien Potencier <fabien@symfony.com>
 *
 * For the full copyright and license information, please view the LICENSE
 * file that was distributed with this source code.
 */

namespace Symfony\Component\Config\Tests;

use PHPUnit\Framework\TestCase;
use Symfony\Component\Config\ConfigCache;
use Symfony\Component\Config\Tests\Resource\ResourceStub;

class ConfigCacheTest extends TestCase
{
    private $cacheFile = null;

    protected function setUp()
    {
        $this->cacheFile = tempnam(sys_get_temp_dir(), 'config_');
    }

    protected function tearDown()
    {
        $files = array($this->cacheFile, $this->cacheFile.'.meta');

        foreach ($files as $file) {
            if (file_exists($file)) {
                unlink($file);
            }
        }
    }

    /**
     * @dataProvider debugModes
     */
    public function testCacheIsNotValidIfNothingHasBeenCached($debug)
    {
        unlink($this->cacheFile); // remove tempnam() side effect
        $cache = new ConfigCache($this->cacheFile, $debug);

        $this->assertFalse($cache->isFresh());
    }

    public function testIsAlwaysFreshInProduction()
    {
        $staleResource = new ResourceStub();
        $staleResource->setFresh(false);

        $cache = new ConfigCache($this->cacheFile, false);
        $cache->write('', array($staleResource));

        $this->assertTrue($cache->isFresh());
    }

    /**
     * @dataProvider debugModes
     */
    public function testIsFreshWhenNoResourceProvided($debug)
    {
        $cache = new ConfigCache($this->cacheFile, $debug);
        $cache->write('', array());
        $this->assertTrue($cache->isFresh());
    }

    public function testFreshResourceInDebug()
    {
        $freshResource = new ResourceStub();
        $freshResource->setFresh(true);

        $cache = new ConfigCache($this->cacheFile, true);
        $cache->write('', array($freshResource));

        $this->assertTrue($cache->isFresh());
    }

    public function testStaleResourceInDebug()
    {
        $staleResource = new ResourceStub();
        $staleResource->setFresh(false);

        $cache = new ConfigCache($this->cacheFile, true);
        $cache->write('', array($staleResource));

        $this->assertFalse($cache->isFresh());
    }

    public function debugModes()
    {
        return array(
            array(true),
            array(false),
        );
    }
}
PKϤ$Z���ss!config/Definition/NumericNode.phpnu�[���<?php

/*
 * This file is part of the Symfony package.
 *
 * (c) Fabien Potencier <fabien@symfony.com>
 *
 * For the full copyright and license information, please view the LICENSE
 * file that was distributed with this source code.
 */

namespace Symfony\Component\Config\Definition;

use Symfony\Component\Config\Definition\Exception\InvalidConfigurationException;

/**
 * This node represents a numeric value in the config tree.
 *
 * @author David Jeanmonod <david.jeanmonod@gmail.com>
 */
class NumericNode extends ScalarNode
{
    protected $min;
    protected $max;

    /**
     * @param int|float|null $min
     * @param int|float|null $max
     */
    public function __construct(?string $name, NodeInterface $parent = null, $min = null, $max = null, string $pathSeparator = BaseNode::DEFAULT_PATH_SEPARATOR)
    {
        parent::__construct($name, $parent, $pathSeparator);
        $this->min = $min;
        $this->max = $max;
    }

    /**
     * {@inheritdoc}
     */
    protected function finalizeValue($value)
    {
        $value = parent::finalizeValue($value);

        $errorMsg = null;
        if (isset($this->min) && $value < $this->min) {
            $errorMsg = sprintf('The value %s is too small for path "%s". Should be greater than or equal to %s', $value, $this->getPath(), $this->min);
        }
        if (isset($this->max) && $value > $this->max) {
            $errorMsg = sprintf('The value %s is too big for path "%s". Should be less than or equal to %s', $value, $this->getPath(), $this->max);
        }
        if (isset($errorMsg)) {
            $ex = new InvalidConfigurationException($errorMsg);
            $ex->setPath($this->getPath());
            throw $ex;
        }

        return $value;
    }

    /**
     * {@inheritdoc}
     */
    protected function isValueEmpty($value)
    {
        // a numeric value cannot be empty
        return false;
    }
}
PKϤ$Z�bB,B,)config/Definition/PrototypedArrayNode.phpnu�[���<?php

/*
 * This file is part of the Symfony package.
 *
 * (c) Fabien Potencier <fabien@symfony.com>
 *
 * For the full copyright and license information, please view the LICENSE
 * file that was distributed with this source code.
 */

namespace Symfony\Component\Config\Definition;

use Symfony\Component\Config\Definition\Exception\DuplicateKeyException;
use Symfony\Component\Config\Definition\Exception\Exception;
use Symfony\Component\Config\Definition\Exception\InvalidConfigurationException;
use Symfony\Component\Config\Definition\Exception\UnsetKeyException;

/**
 * Represents a prototyped Array node in the config tree.
 *
 * @author Johannes M. Schmitt <schmittjoh@gmail.com>
 */
class PrototypedArrayNode extends ArrayNode
{
    protected $prototype;
    protected $keyAttribute;
    protected $removeKeyAttribute = false;
    protected $minNumberOfElements = 0;
    protected $defaultValue = [];
    protected $defaultChildren;
    /**
     * @var NodeInterface[] An array of the prototypes of the simplified value children
     */
    private $valuePrototypes = [];

    /**
     * Sets the minimum number of elements that a prototype based node must
     * contain. By default this is zero, meaning no elements.
     */
    public function setMinNumberOfElements(int $number)
    {
        $this->minNumberOfElements = $number;
    }

    /**
     * Sets the attribute which value is to be used as key.
     *
     * This is useful when you have an indexed array that should be an
     * associative array. You can select an item from within the array
     * to be the key of the particular item. For example, if "id" is the
     * "key", then:
     *
     *     [
     *         ['id' => 'my_name', 'foo' => 'bar'],
     *     ];
     *
     *  becomes
     *
     *      [
     *          'my_name' => ['foo' => 'bar'],
     *      ];
     *
     * If you'd like "'id' => 'my_name'" to still be present in the resulting
     * array, then you can set the second argument of this method to false.
     *
     * @param string $attribute The name of the attribute which value is to be used as a key
     * @param bool   $remove    Whether or not to remove the key
     */
    public function setKeyAttribute(string $attribute, bool $remove = true)
    {
        $this->keyAttribute = $attribute;
        $this->removeKeyAttribute = $remove;
    }

    /**
     * Retrieves the name of the attribute which value should be used as key.
     *
     * @return string|null
     */
    public function getKeyAttribute()
    {
        return $this->keyAttribute;
    }

    /**
     * Sets the default value of this node.
     */
    public function setDefaultValue(array $value)
    {
        $this->defaultValue = $value;
    }

    /**
     * {@inheritdoc}
     */
    public function hasDefaultValue()
    {
        return true;
    }

    /**
     * Adds default children when none are set.
     *
     * @param int|string|array|null $children The number of children|The child name|The children names to be added
     */
    public function setAddChildrenIfNoneSet($children = ['defaults'])
    {
        if (null === $children) {
            $this->defaultChildren = ['defaults'];
        } else {
            $this->defaultChildren = \is_int($children) && $children > 0 ? range(1, $children) : (array) $children;
        }
    }

    /**
     * {@inheritdoc}
     *
     * The default value could be either explicited or derived from the prototype
     * default value.
     */
    public function getDefaultValue()
    {
        if (null !== $this->defaultChildren) {
            $default = $this->prototype->hasDefaultValue() ? $this->prototype->getDefaultValue() : [];
            $defaults = [];
            foreach (array_values($this->defaultChildren) as $i => $name) {
                $defaults[null === $this->keyAttribute ? $i : $name] = $default;
            }

            return $defaults;
        }

        return $this->defaultValue;
    }

    /**
     * Sets the node prototype.
     */
    public function setPrototype(PrototypeNodeInterface $node)
    {
        $this->prototype = $node;
    }

    /**
     * Retrieves the prototype.
     *
     * @return PrototypeNodeInterface
     */
    public function getPrototype()
    {
        return $this->prototype;
    }

    /**
     * Disable adding concrete children for prototyped nodes.
     *
     * @throws Exception
     */
    public function addChild(NodeInterface $node)
    {
        throw new Exception('A prototyped array node cannot have concrete children.');
    }

    /**
     * {@inheritdoc}
     */
    protected function finalizeValue($value)
    {
        if (false === $value) {
            throw new UnsetKeyException(sprintf('Unsetting key for path "%s", value: %s.', $this->getPath(), json_encode($value)));
        }

        foreach ($value as $k => $v) {
            $prototype = $this->getPrototypeForChild($k);
            try {
                $value[$k] = $prototype->finalize($v);
            } catch (UnsetKeyException $e) {
                unset($value[$k]);
            }
        }

        if (\count($value) < $this->minNumberOfElements) {
            $ex = new InvalidConfigurationException(sprintf('The path "%s" should have at least %d element(s) defined.', $this->getPath(), $this->minNumberOfElements));
            $ex->setPath($this->getPath());

            throw $ex;
        }

        return $value;
    }

    /**
     * {@inheritdoc}
     *
     * @throws DuplicateKeyException
     */
    protected function normalizeValue($value)
    {
        if (false === $value) {
            return $value;
        }

        $value = $this->remapXml($value);

        $isList = array_is_list($value);
        $normalized = [];
        foreach ($value as $k => $v) {
            if (null !== $this->keyAttribute && \is_array($v)) {
                if (!isset($v[$this->keyAttribute]) && \is_int($k) && $isList) {
                    $ex = new InvalidConfigurationException(sprintf('The attribute "%s" must be set for path "%s".', $this->keyAttribute, $this->getPath()));
                    $ex->setPath($this->getPath());

                    throw $ex;
                } elseif (isset($v[$this->keyAttribute])) {
                    $k = $v[$this->keyAttribute];

                    if (\is_float($k)) {
                        $k = var_export($k, true);
                    }

                    // remove the key attribute when required
                    if ($this->removeKeyAttribute) {
                        unset($v[$this->keyAttribute]);
                    }

                    // if only "value" is left
                    if (array_keys($v) === ['value']) {
                        $v = $v['value'];
                        if ($this->prototype instanceof ArrayNode && ($children = $this->prototype->getChildren()) && \array_key_exists('value', $children)) {
                            $valuePrototype = current($this->valuePrototypes) ?: clone $children['value'];
                            $valuePrototype->parent = $this;
                            $originalClosures = $this->prototype->normalizationClosures;
                            if (\is_array($originalClosures)) {
                                $valuePrototypeClosures = $valuePrototype->normalizationClosures;
                                $valuePrototype->normalizationClosures = \is_array($valuePrototypeClosures) ? array_merge($originalClosures, $valuePrototypeClosures) : $originalClosures;
                            }
                            $this->valuePrototypes[$k] = $valuePrototype;
                        }
                    }
                }

                if (\array_key_exists($k, $normalized)) {
                    $ex = new DuplicateKeyException(sprintf('Duplicate key "%s" for path "%s".', $k, $this->getPath()));
                    $ex->setPath($this->getPath());

                    throw $ex;
                }
            }

            $prototype = $this->getPrototypeForChild($k);
            if (null !== $this->keyAttribute || !$isList) {
                $normalized[$k] = $prototype->normalize($v);
            } else {
                $normalized[] = $prototype->normalize($v);
            }
        }

        return $normalized;
    }

    /**
     * {@inheritdoc}
     */
    protected function mergeValues($leftSide, $rightSide)
    {
        if (false === $rightSide) {
            // if this is still false after the last config has been merged the
            // finalization pass will take care of removing this key entirely
            return false;
        }

        if (false === $leftSide || !$this->performDeepMerging) {
            return $rightSide;
        }

        $isList = array_is_list($rightSide);
        foreach ($rightSide as $k => $v) {
            // prototype, and key is irrelevant there are no named keys, append the element
            if (null === $this->keyAttribute && $isList) {
                $leftSide[] = $v;
                continue;
            }

            // no conflict
            if (!\array_key_exists($k, $leftSide)) {
                if (!$this->allowNewKeys) {
                    $ex = new InvalidConfigurationException(sprintf('You are not allowed to define new elements for path "%s". Please define all elements for this path in one config file.', $this->getPath()));
                    $ex->setPath($this->getPath());

                    throw $ex;
                }

                $leftSide[$k] = $v;
                continue;
            }

            $prototype = $this->getPrototypeForChild($k);
            $leftSide[$k] = $prototype->merge($leftSide[$k], $v);
        }

        return $leftSide;
    }

    /**
     * Returns a prototype for the child node that is associated to $key in the value array.
     * For general child nodes, this will be $this->prototype.
     * But if $this->removeKeyAttribute is true and there are only two keys in the child node:
     * one is same as this->keyAttribute and the other is 'value', then the prototype will be different.
     *
     * For example, assume $this->keyAttribute is 'name' and the value array is as follows:
     *
     *     [
     *         [
     *             'name' => 'name001',
     *             'value' => 'value001'
     *         ]
     *     ]
     *
     * Now, the key is 0 and the child node is:
     *
     *     [
     *        'name' => 'name001',
     *        'value' => 'value001'
     *     ]
     *
     * When normalizing the value array, the 'name' element will removed from the child node
     * and its value becomes the new key of the child node:
     *
     *     [
     *         'name001' => ['value' => 'value001']
     *     ]
     *
     * Now only 'value' element is left in the child node which can be further simplified into a string:
     *
     *     ['name001' => 'value001']
     *
     * Now, the key becomes 'name001' and the child node becomes 'value001' and
     * the prototype of child node 'name001' should be a ScalarNode instead of an ArrayNode instance.
     *
     * @return mixed
     */
    private function getPrototypeForChild(string $key)
    {
        $prototype = $this->valuePrototypes[$key] ?? $this->prototype;
        $prototype->setName($key);

        return $prototype;
    }
}
PKϤ$Z��@@config/Definition/BaseNode.phpnu�[���<?php

/*
 * This file is part of the Symfony package.
 *
 * (c) Fabien Potencier <fabien@symfony.com>
 *
 * For the full copyright and license information, please view the LICENSE
 * file that was distributed with this source code.
 */

namespace Symfony\Component\Config\Definition;

use Symfony\Component\Config\Definition\Exception\Exception;
use Symfony\Component\Config\Definition\Exception\ForbiddenOverwriteException;
use Symfony\Component\Config\Definition\Exception\InvalidConfigurationException;
use Symfony\Component\Config\Definition\Exception\InvalidTypeException;
use Symfony\Component\Config\Definition\Exception\UnsetKeyException;

/**
 * The base node class.
 *
 * @author Johannes M. Schmitt <schmittjoh@gmail.com>
 */
abstract class BaseNode implements NodeInterface
{
    public const DEFAULT_PATH_SEPARATOR = '.';

    private static $placeholderUniquePrefixes = [];
    private static $placeholders = [];

    protected $name;
    protected $parent;
    protected $normalizationClosures = [];
    protected $finalValidationClosures = [];
    protected $allowOverwrite = true;
    protected $required = false;
    protected $deprecation = [];
    protected $equivalentValues = [];
    protected $attributes = [];
    protected $pathSeparator;

    private $handlingPlaceholder;

    /**
     * @throws \InvalidArgumentException if the name contains a period
     */
    public function __construct(?string $name, NodeInterface $parent = null, string $pathSeparator = self::DEFAULT_PATH_SEPARATOR)
    {
        if (str_contains($name = (string) $name, $pathSeparator)) {
            throw new \InvalidArgumentException('The name must not contain ".'.$pathSeparator.'".');
        }

        $this->name = $name;
        $this->parent = $parent;
        $this->pathSeparator = $pathSeparator;
    }

    /**
     * Register possible (dummy) values for a dynamic placeholder value.
     *
     * Matching configuration values will be processed with a provided value, one by one. After a provided value is
     * successfully processed the configuration value is returned as is, thus preserving the placeholder.
     *
     * @internal
     */
    public static function setPlaceholder(string $placeholder, array $values): void
    {
        if (!$values) {
            throw new \InvalidArgumentException('At least one value must be provided.');
        }

        self::$placeholders[$placeholder] = $values;
    }

    /**
     * Adds a common prefix for dynamic placeholder values.
     *
     * Matching configuration values will be skipped from being processed and are returned as is, thus preserving the
     * placeholder. An exact match provided by {@see setPlaceholder()} might take precedence.
     *
     * @internal
     */
    public static function setPlaceholderUniquePrefix(string $prefix): void
    {
        self::$placeholderUniquePrefixes[] = $prefix;
    }

    /**
     * Resets all current placeholders available.
     *
     * @internal
     */
    public static function resetPlaceholders(): void
    {
        self::$placeholderUniquePrefixes = [];
        self::$placeholders = [];
    }

    public function setAttribute(string $key, $value)
    {
        $this->attributes[$key] = $value;
    }

    /**
     * @return mixed
     */
    public function getAttribute(string $key, $default = null)
    {
        return $this->attributes[$key] ?? $default;
    }

    /**
     * @return bool
     */
    public function hasAttribute(string $key)
    {
        return isset($this->attributes[$key]);
    }

    /**
     * @return array
     */
    public function getAttributes()
    {
        return $this->attributes;
    }

    public function setAttributes(array $attributes)
    {
        $this->attributes = $attributes;
    }

    public function removeAttribute(string $key)
    {
        unset($this->attributes[$key]);
    }

    /**
     * Sets an info message.
     */
    public function setInfo(string $info)
    {
        $this->setAttribute('info', $info);
    }

    /**
     * Returns info message.
     *
     * @return string|null
     */
    public function getInfo()
    {
        return $this->getAttribute('info');
    }

    /**
     * Sets the example configuration for this node.
     *
     * @param string|array $example
     */
    public function setExample($example)
    {
        $this->setAttribute('example', $example);
    }

    /**
     * Retrieves the example configuration for this node.
     *
     * @return string|array|null
     */
    public function getExample()
    {
        return $this->getAttribute('example');
    }

    /**
     * Adds an equivalent value.
     *
     * @param mixed $originalValue
     * @param mixed $equivalentValue
     */
    public function addEquivalentValue($originalValue, $equivalentValue)
    {
        $this->equivalentValues[] = [$originalValue, $equivalentValue];
    }

    /**
     * Set this node as required.
     */
    public function setRequired(bool $boolean)
    {
        $this->required = $boolean;
    }

    /**
     * Sets this node as deprecated.
     *
     * @param string $package The name of the composer package that is triggering the deprecation
     * @param string $version The version of the package that introduced the deprecation
     * @param string $message the deprecation message to use
     *
     * You can use %node% and %path% placeholders in your message to display,
     * respectively, the node name and its complete path
     */
    public function setDeprecated(?string $package/*, string $version, string $message = 'The child node "%node%" at path "%path%" is deprecated.' */)
    {
        $args = \func_get_args();

        if (\func_num_args() < 2) {
            trigger_deprecation('symfony/config', '5.1', 'The signature of method "%s()" requires 3 arguments: "string $package, string $version, string $message", not defining them is deprecated.', __METHOD__);

            if (!isset($args[0])) {
                trigger_deprecation('symfony/config', '5.1', 'Passing a null message to un-deprecate a node is deprecated.');

                $this->deprecation = [];

                return;
            }

            $message = (string) $args[0];
            $package = $version = '';
        } else {
            $package = (string) $args[0];
            $version = (string) $args[1];
            $message = (string) ($args[2] ?? 'The child node "%node%" at path "%path%" is deprecated.');
        }

        $this->deprecation = [
            'package' => $package,
            'version' => $version,
            'message' => $message,
        ];
    }

    /**
     * Sets if this node can be overridden.
     */
    public function setAllowOverwrite(bool $allow)
    {
        $this->allowOverwrite = $allow;
    }

    /**
     * Sets the closures used for normalization.
     *
     * @param \Closure[] $closures An array of Closures used for normalization
     */
    public function setNormalizationClosures(array $closures)
    {
        $this->normalizationClosures = $closures;
    }

    /**
     * Sets the closures used for final validation.
     *
     * @param \Closure[] $closures An array of Closures used for final validation
     */
    public function setFinalValidationClosures(array $closures)
    {
        $this->finalValidationClosures = $closures;
    }

    /**
     * {@inheritdoc}
     */
    public function isRequired()
    {
        return $this->required;
    }

    /**
     * Checks if this node is deprecated.
     *
     * @return bool
     */
    public function isDeprecated()
    {
        return (bool) $this->deprecation;
    }

    /**
     * Returns the deprecated message.
     *
     * @param string $node the configuration node name
     * @param string $path the path of the node
     *
     * @return string
     *
     * @deprecated since Symfony 5.1, use "getDeprecation()" instead.
     */
    public function getDeprecationMessage(string $node, string $path)
    {
        trigger_deprecation('symfony/config', '5.1', 'The "%s()" method is deprecated, use "getDeprecation()" instead.', __METHOD__);

        return $this->getDeprecation($node, $path)['message'];
    }

    /**
     * @param string $node The configuration node name
     * @param string $path The path of the node
     */
    public function getDeprecation(string $node, string $path): array
    {
        return [
            'package' => $this->deprecation['package'] ?? '',
            'version' => $this->deprecation['version'] ?? '',
            'message' => strtr($this->deprecation['message'] ?? '', ['%node%' => $node, '%path%' => $path]),
        ];
    }

    /**
     * {@inheritdoc}
     */
    public function getName()
    {
        return $this->name;
    }

    /**
     * {@inheritdoc}
     */
    public function getPath()
    {
        if (null !== $this->parent) {
            return $this->parent->getPath().$this->pathSeparator.$this->name;
        }

        return $this->name;
    }

    /**
     * {@inheritdoc}
     */
    final public function merge($leftSide, $rightSide)
    {
        if (!$this->allowOverwrite) {
            throw new ForbiddenOverwriteException(sprintf('Configuration path "%s" cannot be overwritten. You have to define all options for this path, and any of its sub-paths in one configuration section.', $this->getPath()));
        }

        if ($leftSide !== $leftPlaceholders = self::resolvePlaceholderValue($leftSide)) {
            foreach ($leftPlaceholders as $leftPlaceholder) {
                $this->handlingPlaceholder = $leftSide;
                try {
                    $this->merge($leftPlaceholder, $rightSide);
                } finally {
                    $this->handlingPlaceholder = null;
                }
            }

            return $rightSide;
        }

        if ($rightSide !== $rightPlaceholders = self::resolvePlaceholderValue($rightSide)) {
            foreach ($rightPlaceholders as $rightPlaceholder) {
                $this->handlingPlaceholder = $rightSide;
                try {
                    $this->merge($leftSide, $rightPlaceholder);
                } finally {
                    $this->handlingPlaceholder = null;
                }
            }

            return $rightSide;
        }

        $this->doValidateType($leftSide);
        $this->doValidateType($rightSide);

        return $this->mergeValues($leftSide, $rightSide);
    }

    /**
     * {@inheritdoc}
     */
    final public function normalize($value)
    {
        $value = $this->preNormalize($value);

        // run custom normalization closures
        foreach ($this->normalizationClosures as $closure) {
            $value = $closure($value);
        }

        // resolve placeholder value
        if ($value !== $placeholders = self::resolvePlaceholderValue($value)) {
            foreach ($placeholders as $placeholder) {
                $this->handlingPlaceholder = $value;
                try {
                    $this->normalize($placeholder);
                } finally {
                    $this->handlingPlaceholder = null;
                }
            }

            return $value;
        }

        // replace value with their equivalent
        foreach ($this->equivalentValues as $data) {
            if ($data[0] === $value) {
                $value = $data[1];
            }
        }

        // validate type
        $this->doValidateType($value);

        // normalize value
        return $this->normalizeValue($value);
    }

    /**
     * Normalizes the value before any other normalization is applied.
     *
     * @param mixed $value
     *
     * @return mixed
     */
    protected function preNormalize($value)
    {
        return $value;
    }

    /**
     * Returns parent node for this node.
     *
     * @return NodeInterface|null
     */
    public function getParent()
    {
        return $this->parent;
    }

    /**
     * {@inheritdoc}
     */
    final public function finalize($value)
    {
        if ($value !== $placeholders = self::resolvePlaceholderValue($value)) {
            foreach ($placeholders as $placeholder) {
                $this->handlingPlaceholder = $value;
                try {
                    $this->finalize($placeholder);
                } finally {
                    $this->handlingPlaceholder = null;
                }
            }

            return $value;
        }

        $this->doValidateType($value);

        $value = $this->finalizeValue($value);

        // Perform validation on the final value if a closure has been set.
        // The closure is also allowed to return another value.
        foreach ($this->finalValidationClosures as $closure) {
            try {
                $value = $closure($value);
            } catch (Exception $e) {
                if ($e instanceof UnsetKeyException && null !== $this->handlingPlaceholder) {
                    continue;
                }

                throw $e;
            } catch (\Exception $e) {
                throw new InvalidConfigurationException(sprintf('Invalid configuration for path "%s": ', $this->getPath()).$e->getMessage(), $e->getCode(), $e);
            }
        }

        return $value;
    }

    /**
     * Validates the type of a Node.
     *
     * @param mixed $value The value to validate
     *
     * @throws InvalidTypeException when the value is invalid
     */
    abstract protected function validateType($value);

    /**
     * Normalizes the value.
     *
     * @param mixed $value The value to normalize
     *
     * @return mixed
     */
    abstract protected function normalizeValue($value);

    /**
     * Merges two values together.
     *
     * @param mixed $leftSide
     * @param mixed $rightSide
     *
     * @return mixed
     */
    abstract protected function mergeValues($leftSide, $rightSide);

    /**
     * Finalizes a value.
     *
     * @param mixed $value The value to finalize
     *
     * @return mixed
     */
    abstract protected function finalizeValue($value);

    /**
     * Tests if placeholder values are allowed for this node.
     */
    protected function allowPlaceholders(): bool
    {
        return true;
    }

    /**
     * Tests if a placeholder is being handled currently.
     */
    protected function isHandlingPlaceholder(): bool
    {
        return null !== $this->handlingPlaceholder;
    }

    /**
     * Gets allowed dynamic types for this node.
     */
    protected function getValidPlaceholderTypes(): array
    {
        return [];
    }

    private static function resolvePlaceholderValue($value)
    {
        if (\is_string($value)) {
            if (isset(self::$placeholders[$value])) {
                return self::$placeholders[$value];
            }

            foreach (self::$placeholderUniquePrefixes as $placeholderUniquePrefix) {
                if (str_starts_with($value, $placeholderUniquePrefix)) {
                    return [];
                }
            }
        }

        return $value;
    }

    private function doValidateType($value): void
    {
        if (null !== $this->handlingPlaceholder && !$this->allowPlaceholders()) {
            $e = new InvalidTypeException(sprintf('A dynamic value is not compatible with a "%s" node type at path "%s".', static::class, $this->getPath()));
            $e->setPath($this->getPath());

            throw $e;
        }

        if (null === $this->handlingPlaceholder || null === $value) {
            $this->validateType($value);

            return;
        }

        $knownTypes = array_keys(self::$placeholders[$this->handlingPlaceholder]);
        $validTypes = $this->getValidPlaceholderTypes();

        if ($validTypes && array_diff($knownTypes, $validTypes)) {
            $e = new InvalidTypeException(sprintf(
                'Invalid type for path "%s". Expected %s, but got %s.',
                $this->getPath(),
                1 === \count($validTypes) ? '"'.reset($validTypes).'"' : 'one of "'.implode('", "', $validTypes).'"',
                1 === \count($knownTypes) ? '"'.reset($knownTypes).'"' : 'one of "'.implode('", "', $knownTypes).'"'
            ));
            if ($hint = $this->getInfo()) {
                $e->addHint($hint);
            }
            $e->setPath($this->getPath());

            throw $e;
        }

        $this->validateType($value);
    }
}
PKϤ$Z�uee,config/Definition/ConfigurationInterface.phpnu�[���<?php

/*
 * This file is part of the Symfony package.
 *
 * (c) Fabien Potencier <fabien@symfony.com>
 *
 * For the full copyright and license information, please view the LICENSE
 * file that was distributed with this source code.
 */

namespace Symfony\Component\Config\Definition;

use Symfony\Component\Config\Definition\Builder\TreeBuilder;

/**
 * Configuration interface.
 *
 * @author Victor Berchet <victor@suumit.com>
 */
interface ConfigurationInterface
{
    /**
     * Generates the configuration tree builder.
     *
     * @return TreeBuilder
     */
    public function getConfigTreeBuilder();
}
PKϤ$Zo�`���)config/Definition/Builder/ExprBuilder.phpnu�[���<?php

/*
 * This file is part of the Symfony package.
 *
 * (c) Fabien Potencier <fabien@symfony.com>
 *
 * For the full copyright and license information, please view the LICENSE
 * file that was distributed with this source code.
 */

namespace Symfony\Component\Config\Definition\Builder;

use Symfony\Component\Config\Definition\Exception\UnsetKeyException;

/**
 * This class builds an if expression.
 *
 * @author Johannes M. Schmitt <schmittjoh@gmail.com>
 * @author Christophe Coevoet <stof@notk.org>
 */
class ExprBuilder
{
    protected $node;
    public $ifPart;
    public $thenPart;

    public function __construct(NodeDefinition $node)
    {
        $this->node = $node;
    }

    /**
     * Marks the expression as being always used.
     *
     * @return $this
     */
    public function always(\Closure $then = null)
    {
        $this->ifPart = function () { return true; };

        if (null !== $then) {
            $this->thenPart = $then;
        }

        return $this;
    }

    /**
     * Sets a closure to use as tests.
     *
     * The default one tests if the value is true.
     *
     * @return $this
     */
    public function ifTrue(\Closure $closure = null)
    {
        if (null === $closure) {
            $closure = function ($v) { return true === $v; };
        }

        $this->ifPart = $closure;

        return $this;
    }

    /**
     * Tests if the value is a string.
     *
     * @return $this
     */
    public function ifString()
    {
        $this->ifPart = function ($v) { return \is_string($v); };

        return $this;
    }

    /**
     * Tests if the value is null.
     *
     * @return $this
     */
    public function ifNull()
    {
        $this->ifPart = function ($v) { return null === $v; };

        return $this;
    }

    /**
     * Tests if the value is empty.
     *
     * @return $this
     */
    public function ifEmpty()
    {
        $this->ifPart = function ($v) { return empty($v); };

        return $this;
    }

    /**
     * Tests if the value is an array.
     *
     * @return $this
     */
    public function ifArray()
    {
        $this->ifPart = function ($v) { return \is_array($v); };

        return $this;
    }

    /**
     * Tests if the value is in an array.
     *
     * @return $this
     */
    public function ifInArray(array $array)
    {
        $this->ifPart = function ($v) use ($array) { return \in_array($v, $array, true); };

        return $this;
    }

    /**
     * Tests if the value is not in an array.
     *
     * @return $this
     */
    public function ifNotInArray(array $array)
    {
        $this->ifPart = function ($v) use ($array) { return !\in_array($v, $array, true); };

        return $this;
    }

    /**
     * Transforms variables of any type into an array.
     *
     * @return $this
     */
    public function castToArray()
    {
        $this->ifPart = function ($v) { return !\is_array($v); };
        $this->thenPart = function ($v) { return [$v]; };

        return $this;
    }

    /**
     * Sets the closure to run if the test pass.
     *
     * @return $this
     */
    public function then(\Closure $closure)
    {
        $this->thenPart = $closure;

        return $this;
    }

    /**
     * Sets a closure returning an empty array.
     *
     * @return $this
     */
    public function thenEmptyArray()
    {
        $this->thenPart = function () { return []; };

        return $this;
    }

    /**
     * Sets a closure marking the value as invalid at processing time.
     *
     * if you want to add the value of the node in your message just use a %s placeholder.
     *
     * @return $this
     *
     * @throws \InvalidArgumentException
     */
    public function thenInvalid(string $message)
    {
        $this->thenPart = function ($v) use ($message) { throw new \InvalidArgumentException(sprintf($message, json_encode($v))); };

        return $this;
    }

    /**
     * Sets a closure unsetting this key of the array at processing time.
     *
     * @return $this
     *
     * @throws UnsetKeyException
     */
    public function thenUnset()
    {
        $this->thenPart = function () { throw new UnsetKeyException('Unsetting key.'); };

        return $this;
    }

    /**
     * Returns the related node.
     *
     * @return NodeDefinition|ArrayNodeDefinition|VariableNodeDefinition
     *
     * @throws \RuntimeException
     */
    public function end()
    {
        if (null === $this->ifPart) {
            throw new \RuntimeException('You must specify an if part.');
        }
        if (null === $this->thenPart) {
            throw new \RuntimeException('You must specify a then part.');
        }

        return $this->node;
    }

    /**
     * Builds the expressions.
     *
     * @param ExprBuilder[] $expressions An array of ExprBuilder instances to build
     *
     * @return array
     */
    public static function buildExpressions(array $expressions)
    {
        foreach ($expressions as $k => $expr) {
            if ($expr instanceof self) {
                $if = $expr->ifPart;
                $then = $expr->thenPart;
                $expressions[$k] = function ($v) use ($if, $then) {
                    return $if($v) ? $then($v) : $v;
                };
            }
        }

        return $expressions;
    }
}
PKϤ$Z�.�1config/Definition/Builder/FloatNodeDefinition.phpnu�[���<?php

/*
 * This file is part of the Symfony package.
 *
 * (c) Fabien Potencier <fabien@symfony.com>
 *
 * For the full copyright and license information, please view the LICENSE
 * file that was distributed with this source code.
 */

namespace Symfony\Component\Config\Definition\Builder;

use Symfony\Component\Config\Definition\FloatNode;

/**
 * This class provides a fluent interface for defining a float node.
 *
 * @author Jeanmonod David <david.jeanmonod@gmail.com>
 */
class FloatNodeDefinition extends NumericNodeDefinition
{
    /**
     * Instantiates a Node.
     *
     * @return FloatNode
     */
    protected function instantiateNode()
    {
        return new FloatNode($this->name, $this->parent, $this->min, $this->max, $this->pathSeparator);
    }
}
PKϤ$ZCP

3config/Definition/Builder/BooleanNodeDefinition.phpnu�[���<?php

/*
 * This file is part of the Symfony package.
 *
 * (c) Fabien Potencier <fabien@symfony.com>
 *
 * For the full copyright and license information, please view the LICENSE
 * file that was distributed with this source code.
 */

namespace Symfony\Component\Config\Definition\Builder;

use Symfony\Component\Config\Definition\BooleanNode;
use Symfony\Component\Config\Definition\Exception\InvalidDefinitionException;

/**
 * This class provides a fluent interface for defining a node.
 *
 * @author Johannes M. Schmitt <schmittjoh@gmail.com>
 */
class BooleanNodeDefinition extends ScalarNodeDefinition
{
    /**
     * {@inheritdoc}
     */
    public function __construct(?string $name, NodeParentInterface $parent = null)
    {
        parent::__construct($name, $parent);

        $this->nullEquivalent = true;
    }

    /**
     * Instantiate a Node.
     *
     * @return BooleanNode
     */
    protected function instantiateNode()
    {
        return new BooleanNode($this->name, $this->parent, $this->pathSeparator);
    }

    /**
     * {@inheritdoc}
     *
     * @throws InvalidDefinitionException
     */
    public function cannotBeEmpty()
    {
        throw new InvalidDefinitionException('->cannotBeEmpty() is not applicable to BooleanNodeDefinition.');
    }
}
PKϤ$Z����*config/Definition/Builder/MergeBuilder.phpnu�[���<?php

/*
 * This file is part of the Symfony package.
 *
 * (c) Fabien Potencier <fabien@symfony.com>
 *
 * For the full copyright and license information, please view the LICENSE
 * file that was distributed with this source code.
 */

namespace Symfony\Component\Config\Definition\Builder;

/**
 * This class builds merge conditions.
 *
 * @author Johannes M. Schmitt <schmittjoh@gmail.com>
 */
class MergeBuilder
{
    protected $node;
    public $allowFalse = false;
    public $allowOverwrite = true;

    public function __construct(NodeDefinition $node)
    {
        $this->node = $node;
    }

    /**
     * Sets whether the node can be unset.
     *
     * @return $this
     */
    public function allowUnset(bool $allow = true)
    {
        $this->allowFalse = $allow;

        return $this;
    }

    /**
     * Sets whether the node can be overwritten.
     *
     * @return $this
     */
    public function denyOverwrite(bool $deny = true)
    {
        $this->allowOverwrite = !$deny;

        return $this;
    }

    /**
     * Returns the related node.
     *
     * @return NodeDefinition|ArrayNodeDefinition|VariableNodeDefinition
     */
    public function end()
    {
        return $this->node;
    }
}
PKϤ$Z�,���0config/Definition/Builder/EnumNodeDefinition.phpnu�[���<?php

/*
 * This file is part of the Symfony package.
 *
 * (c) Fabien Potencier <fabien@symfony.com>
 *
 * For the full copyright and license information, please view the LICENSE
 * file that was distributed with this source code.
 */

namespace Symfony\Component\Config\Definition\Builder;

use Symfony\Component\Config\Definition\EnumNode;

/**
 * Enum Node Definition.
 *
 * @author Johannes M. Schmitt <schmittjoh@gmail.com>
 */
class EnumNodeDefinition extends ScalarNodeDefinition
{
    private $values;

    /**
     * @return $this
     */
    public function values(array $values)
    {
        $values = array_unique($values);

        if (empty($values)) {
            throw new \InvalidArgumentException('->values() must be called with at least one value.');
        }

        $this->values = $values;

        return $this;
    }

    /**
     * Instantiate a Node.
     *
     * @return EnumNode
     *
     * @throws \RuntimeException
     */
    protected function instantiateNode()
    {
        if (null === $this->values) {
            throw new \RuntimeException('You must call ->values() on enum nodes.');
        }

        return new EnumNode($this->name, $this->parent, $this->values, $this->pathSeparator);
    }
}
PKϤ$ZH]>Ԙ�;config/Definition/Builder/ParentNodeDefinitionInterface.phpnu�[���<?php

/*
 * This file is part of the Symfony package.
 *
 * (c) Fabien Potencier <fabien@symfony.com>
 *
 * For the full copyright and license information, please view the LICENSE
 * file that was distributed with this source code.
 */

namespace Symfony\Component\Config\Definition\Builder;

/**
 * An interface that must be implemented by nodes which can have children.
 *
 * @author Victor Berchet <victor@suumit.com>
 */
interface ParentNodeDefinitionInterface extends BuilderAwareInterface
{
    /**
     * Returns a builder to add children nodes.
     *
     * @return NodeBuilder
     */
    public function children();

    /**
     * Appends a node definition.
     *
     * Usage:
     *
     *     $node = $parentNode
     *         ->children()
     *             ->scalarNode('foo')->end()
     *             ->scalarNode('baz')->end()
     *             ->append($this->getBarNodeDefinition())
     *         ->end()
     *     ;
     *
     * @return $this
     */
    public function append(NodeDefinition $node);

    /**
     * Gets the child node definitions.
     *
     * @return NodeDefinition[]
     */
    public function getChildNodeDefinitions();
}
PKϤ$ZرV�"�",config/Definition/Builder/NodeDefinition.phpnu�[���<?php

/*
 * This file is part of the Symfony package.
 *
 * (c) Fabien Potencier <fabien@symfony.com>
 *
 * For the full copyright and license information, please view the LICENSE
 * file that was distributed with this source code.
 */

namespace Symfony\Component\Config\Definition\Builder;

use Symfony\Component\Config\Definition\BaseNode;
use Symfony\Component\Config\Definition\Exception\InvalidDefinitionException;
use Symfony\Component\Config\Definition\NodeInterface;

/**
 * This class provides a fluent interface for defining a node.
 *
 * @author Johannes M. Schmitt <schmittjoh@gmail.com>
 */
abstract class NodeDefinition implements NodeParentInterface
{
    protected $name;
    protected $normalization;
    protected $validation;
    protected $defaultValue;
    protected $default = false;
    protected $required = false;
    protected $deprecation = [];
    protected $merge;
    protected $allowEmptyValue = true;
    protected $nullEquivalent;
    protected $trueEquivalent = true;
    protected $falseEquivalent = false;
    protected $pathSeparator = BaseNode::DEFAULT_PATH_SEPARATOR;
    protected $parent;
    protected $attributes = [];

    public function __construct(?string $name, NodeParentInterface $parent = null)
    {
        $this->parent = $parent;
        $this->name = $name;
    }

    /**
     * Sets the parent node.
     *
     * @return $this
     */
    public function setParent(NodeParentInterface $parent)
    {
        $this->parent = $parent;

        return $this;
    }

    /**
     * Sets info message.
     *
     * @return $this
     */
    public function info(string $info)
    {
        return $this->attribute('info', $info);
    }

    /**
     * Sets example configuration.
     *
     * @param string|array $example
     *
     * @return $this
     */
    public function example($example)
    {
        return $this->attribute('example', $example);
    }

    /**
     * Sets an attribute on the node.
     *
     * @param mixed $value
     *
     * @return $this
     */
    public function attribute(string $key, $value)
    {
        $this->attributes[$key] = $value;

        return $this;
    }

    /**
     * Returns the parent node.
     *
     * @return NodeParentInterface|NodeBuilder|NodeDefinition|ArrayNodeDefinition|VariableNodeDefinition|null
     */
    public function end()
    {
        return $this->parent;
    }

    /**
     * Creates the node.
     *
     * @return NodeInterface
     */
    public function getNode(bool $forceRootNode = false)
    {
        if ($forceRootNode) {
            $this->parent = null;
        }

        if (null !== $this->normalization) {
            $this->normalization->before = ExprBuilder::buildExpressions($this->normalization->before);
        }

        if (null !== $this->validation) {
            $this->validation->rules = ExprBuilder::buildExpressions($this->validation->rules);
        }

        $node = $this->createNode();
        if ($node instanceof BaseNode) {
            $node->setAttributes($this->attributes);
        }

        return $node;
    }

    /**
     * Sets the default value.
     *
     * @param mixed $value The default value
     *
     * @return $this
     */
    public function defaultValue($value)
    {
        $this->default = true;
        $this->defaultValue = $value;

        return $this;
    }

    /**
     * Sets the node as required.
     *
     * @return $this
     */
    public function isRequired()
    {
        $this->required = true;

        return $this;
    }

    /**
     * Sets the node as deprecated.
     *
     * @param string $package The name of the composer package that is triggering the deprecation
     * @param string $version The version of the package that introduced the deprecation
     * @param string $message the deprecation message to use
     *
     * You can use %node% and %path% placeholders in your message to display,
     * respectively, the node name and its complete path
     *
     * @return $this
     */
    public function setDeprecated(/* string $package, string $version, string $message = 'The child node "%node%" at path "%path%" is deprecated.' */)
    {
        $args = \func_get_args();

        if (\func_num_args() < 2) {
            trigger_deprecation('symfony/config', '5.1', 'The signature of method "%s()" requires 3 arguments: "string $package, string $version, string $message", not defining them is deprecated.', __METHOD__);

            $message = $args[0] ?? 'The child node "%node%" at path "%path%" is deprecated.';
            $package = $version = '';
        } else {
            $package = (string) $args[0];
            $version = (string) $args[1];
            $message = (string) ($args[2] ?? 'The child node "%node%" at path "%path%" is deprecated.');
        }

        $this->deprecation = [
            'package' => $package,
            'version' => $version,
            'message' => $message,
        ];

        return $this;
    }

    /**
     * Sets the equivalent value used when the node contains null.
     *
     * @param mixed $value
     *
     * @return $this
     */
    public function treatNullLike($value)
    {
        $this->nullEquivalent = $value;

        return $this;
    }

    /**
     * Sets the equivalent value used when the node contains true.
     *
     * @param mixed $value
     *
     * @return $this
     */
    public function treatTrueLike($value)
    {
        $this->trueEquivalent = $value;

        return $this;
    }

    /**
     * Sets the equivalent value used when the node contains false.
     *
     * @param mixed $value
     *
     * @return $this
     */
    public function treatFalseLike($value)
    {
        $this->falseEquivalent = $value;

        return $this;
    }

    /**
     * Sets null as the default value.
     *
     * @return $this
     */
    public function defaultNull()
    {
        return $this->defaultValue(null);
    }

    /**
     * Sets true as the default value.
     *
     * @return $this
     */
    public function defaultTrue()
    {
        return $this->defaultValue(true);
    }

    /**
     * Sets false as the default value.
     *
     * @return $this
     */
    public function defaultFalse()
    {
        return $this->defaultValue(false);
    }

    /**
     * Sets an expression to run before the normalization.
     *
     * @return ExprBuilder
     */
    public function beforeNormalization()
    {
        return $this->normalization()->before();
    }

    /**
     * Denies the node value being empty.
     *
     * @return $this
     */
    public function cannotBeEmpty()
    {
        $this->allowEmptyValue = false;

        return $this;
    }

    /**
     * Sets an expression to run for the validation.
     *
     * The expression receives the value of the node and must return it. It can
     * modify it.
     * An exception should be thrown when the node is not valid.
     *
     * @return ExprBuilder
     */
    public function validate()
    {
        return $this->validation()->rule();
    }

    /**
     * Sets whether the node can be overwritten.
     *
     * @return $this
     */
    public function cannotBeOverwritten(bool $deny = true)
    {
        $this->merge()->denyOverwrite($deny);

        return $this;
    }

    /**
     * Gets the builder for validation rules.
     *
     * @return ValidationBuilder
     */
    protected function validation()
    {
        if (null === $this->validation) {
            $this->validation = new ValidationBuilder($this);
        }

        return $this->validation;
    }

    /**
     * Gets the builder for merging rules.
     *
     * @return MergeBuilder
     */
    protected function merge()
    {
        if (null === $this->merge) {
            $this->merge = new MergeBuilder($this);
        }

        return $this->merge;
    }

    /**
     * Gets the builder for normalization rules.
     *
     * @return NormalizationBuilder
     */
    protected function normalization()
    {
        if (null === $this->normalization) {
            $this->normalization = new NormalizationBuilder($this);
        }

        return $this->normalization;
    }

    /**
     * Instantiate and configure the node according to this definition.
     *
     * @return NodeInterface
     *
     * @throws InvalidDefinitionException When the definition is invalid
     */
    abstract protected function createNode();

    /**
     * Set PathSeparator to use.
     *
     * @return $this
     */
    public function setPathSeparator(string $separator)
    {
        if ($this instanceof ParentNodeDefinitionInterface) {
            foreach ($this->getChildNodeDefinitions() as $child) {
                $child->setPathSeparator($separator);
            }
        }

        $this->pathSeparator = $separator;

        return $this;
    }
}
PKϤ$Z�i����/config/Definition/Builder/ValidationBuilder.phpnu�[���<?php

/*
 * This file is part of the Symfony package.
 *
 * (c) Fabien Potencier <fabien@symfony.com>
 *
 * For the full copyright and license information, please view the LICENSE
 * file that was distributed with this source code.
 */

namespace Symfony\Component\Config\Definition\Builder;

/**
 * This class builds validation conditions.
 *
 * @author Christophe Coevoet <stof@notk.org>
 */
class ValidationBuilder
{
    protected $node;
    public $rules = [];

    public function __construct(NodeDefinition $node)
    {
        $this->node = $node;
    }

    /**
     * Registers a closure to run as normalization or an expression builder to build it if null is provided.
     *
     * @return ExprBuilder|$this
     */
    public function rule(\Closure $closure = null)
    {
        if (null !== $closure) {
            $this->rules[] = $closure;

            return $this;
        }

        return $this->rules[] = new ExprBuilder($this->node);
    }
}
PKϤ$Z�.ΦC?C?1config/Definition/Builder/ArrayNodeDefinition.phpnu�[���<?php

/*
 * This file is part of the Symfony package.
 *
 * (c) Fabien Potencier <fabien@symfony.com>
 *
 * For the full copyright and license information, please view the LICENSE
 * file that was distributed with this source code.
 */

namespace Symfony\Component\Config\Definition\Builder;

use Symfony\Component\Config\Definition\ArrayNode;
use Symfony\Component\Config\Definition\Exception\InvalidDefinitionException;
use Symfony\Component\Config\Definition\PrototypedArrayNode;

/**
 * This class provides a fluent interface for defining an array node.
 *
 * @author Johannes M. Schmitt <schmittjoh@gmail.com>
 */
class ArrayNodeDefinition extends NodeDefinition implements ParentNodeDefinitionInterface
{
    protected $performDeepMerging = true;
    protected $ignoreExtraKeys = false;
    protected $removeExtraKeys = true;
    protected $children = [];
    protected $prototype;
    protected $atLeastOne = false;
    protected $allowNewKeys = true;
    protected $key;
    protected $removeKeyItem;
    protected $addDefaults = false;
    protected $addDefaultChildren = false;
    protected $nodeBuilder;
    protected $normalizeKeys = true;

    /**
     * {@inheritdoc}
     */
    public function __construct(?string $name, NodeParentInterface $parent = null)
    {
        parent::__construct($name, $parent);

        $this->nullEquivalent = [];
        $this->trueEquivalent = [];
    }

    /**
     * {@inheritdoc}
     */
    public function setBuilder(NodeBuilder $builder)
    {
        $this->nodeBuilder = $builder;
    }

    /**
     * {@inheritdoc}
     */
    public function children()
    {
        return $this->getNodeBuilder();
    }

    /**
     * Sets a prototype for child nodes.
     *
     * @return NodeDefinition
     */
    public function prototype(string $type)
    {
        return $this->prototype = $this->getNodeBuilder()->node(null, $type)->setParent($this);
    }

    /**
     * @return VariableNodeDefinition
     */
    public function variablePrototype()
    {
        return $this->prototype('variable');
    }

    /**
     * @return ScalarNodeDefinition
     */
    public function scalarPrototype()
    {
        return $this->prototype('scalar');
    }

    /**
     * @return BooleanNodeDefinition
     */
    public function booleanPrototype()
    {
        return $this->prototype('boolean');
    }

    /**
     * @return IntegerNodeDefinition
     */
    public function integerPrototype()
    {
        return $this->prototype('integer');
    }

    /**
     * @return FloatNodeDefinition
     */
    public function floatPrototype()
    {
        return $this->prototype('float');
    }

    /**
     * @return ArrayNodeDefinition
     */
    public function arrayPrototype()
    {
        return $this->prototype('array');
    }

    /**
     * @return EnumNodeDefinition
     */
    public function enumPrototype()
    {
        return $this->prototype('enum');
    }

    /**
     * Adds the default value if the node is not set in the configuration.
     *
     * This method is applicable to concrete nodes only (not to prototype nodes).
     * If this function has been called and the node is not set during the finalization
     * phase, it's default value will be derived from its children default values.
     *
     * @return $this
     */
    public function addDefaultsIfNotSet()
    {
        $this->addDefaults = true;

        return $this;
    }

    /**
     * Adds children with a default value when none are defined.
     *
     * This method is applicable to prototype nodes only.
     *
     * @param int|string|array|null $children The number of children|The child name|The children names to be added
     *
     * @return $this
     */
    public function addDefaultChildrenIfNoneSet($children = null)
    {
        $this->addDefaultChildren = $children;

        return $this;
    }

    /**
     * Requires the node to have at least one element.
     *
     * This method is applicable to prototype nodes only.
     *
     * @return $this
     */
    public function requiresAtLeastOneElement()
    {
        $this->atLeastOne = true;

        return $this;
    }

    /**
     * Disallows adding news keys in a subsequent configuration.
     *
     * If used all keys have to be defined in the same configuration file.
     *
     * @return $this
     */
    public function disallowNewKeysInSubsequentConfigs()
    {
        $this->allowNewKeys = false;

        return $this;
    }

    /**
     * Sets a normalization rule for XML configurations.
     *
     * @param string      $singular The key to remap
     * @param string|null $plural   The plural of the key for irregular plurals
     *
     * @return $this
     */
    public function fixXmlConfig(string $singular, string $plural = null)
    {
        $this->normalization()->remap($singular, $plural);

        return $this;
    }

    /**
     * Sets the attribute which value is to be used as key.
     *
     * This is useful when you have an indexed array that should be an
     * associative array. You can select an item from within the array
     * to be the key of the particular item. For example, if "id" is the
     * "key", then:
     *
     *     [
     *         ['id' => 'my_name', 'foo' => 'bar'],
     *     ];
     *
     *   becomes
     *
     *     [
     *         'my_name' => ['foo' => 'bar'],
     *     ];
     *
     * If you'd like "'id' => 'my_name'" to still be present in the resulting
     * array, then you can set the second argument of this method to false.
     *
     * This method is applicable to prototype nodes only.
     *
     * @param string $name          The name of the key
     * @param bool   $removeKeyItem Whether or not the key item should be removed
     *
     * @return $this
     */
    public function useAttributeAsKey(string $name, bool $removeKeyItem = true)
    {
        $this->key = $name;
        $this->removeKeyItem = $removeKeyItem;

        return $this;
    }

    /**
     * Sets whether the node can be unset.
     *
     * @return $this
     */
    public function canBeUnset(bool $allow = true)
    {
        $this->merge()->allowUnset($allow);

        return $this;
    }

    /**
     * Adds an "enabled" boolean to enable the current section.
     *
     * By default, the section is disabled. If any configuration is specified then
     * the node will be automatically enabled:
     *
     * enableableArrayNode: {enabled: true, ...}   # The config is enabled & default values get overridden
     * enableableArrayNode: ~                      # The config is enabled & use the default values
     * enableableArrayNode: true                   # The config is enabled & use the default values
     * enableableArrayNode: {other: value, ...}    # The config is enabled & default values get overridden
     * enableableArrayNode: {enabled: false, ...}  # The config is disabled
     * enableableArrayNode: false                  # The config is disabled
     *
     * @return $this
     */
    public function canBeEnabled()
    {
        $this
            ->addDefaultsIfNotSet()
            ->treatFalseLike(['enabled' => false])
            ->treatTrueLike(['enabled' => true])
            ->treatNullLike(['enabled' => true])
            ->beforeNormalization()
                ->ifArray()
                ->then(function (array $v) {
                    $v['enabled'] = $v['enabled'] ?? true;

                    return $v;
                })
            ->end()
            ->children()
                ->booleanNode('enabled')
                    ->defaultFalse()
        ;

        return $this;
    }

    /**
     * Adds an "enabled" boolean to enable the current section.
     *
     * By default, the section is enabled.
     *
     * @return $this
     */
    public function canBeDisabled()
    {
        $this
            ->addDefaultsIfNotSet()
            ->treatFalseLike(['enabled' => false])
            ->treatTrueLike(['enabled' => true])
            ->treatNullLike(['enabled' => true])
            ->children()
                ->booleanNode('enabled')
                    ->defaultTrue()
        ;

        return $this;
    }

    /**
     * Disables the deep merging of the node.
     *
     * @return $this
     */
    public function performNoDeepMerging()
    {
        $this->performDeepMerging = false;

        return $this;
    }

    /**
     * Allows extra config keys to be specified under an array without
     * throwing an exception.
     *
     * Those config values are ignored and removed from the resulting
     * array. This should be used only in special cases where you want
     * to send an entire configuration array through a special tree that
     * processes only part of the array.
     *
     * @param bool $remove Whether to remove the extra keys
     *
     * @return $this
     */
    public function ignoreExtraKeys(bool $remove = true)
    {
        $this->ignoreExtraKeys = true;
        $this->removeExtraKeys = $remove;

        return $this;
    }

    /**
     * Sets whether to enable key normalization.
     *
     * @return $this
     */
    public function normalizeKeys(bool $bool)
    {
        $this->normalizeKeys = $bool;

        return $this;
    }

    /**
     * {@inheritdoc}
     */
    public function append(NodeDefinition $node)
    {
        $this->children[$node->name] = $node->setParent($this);

        return $this;
    }

    /**
     * Returns a node builder to be used to add children and prototype.
     *
     * @return NodeBuilder
     */
    protected function getNodeBuilder()
    {
        if (null === $this->nodeBuilder) {
            $this->nodeBuilder = new NodeBuilder();
        }

        return $this->nodeBuilder->setParent($this);
    }

    /**
     * {@inheritdoc}
     */
    protected function createNode()
    {
        if (null === $this->prototype) {
            $node = new ArrayNode($this->name, $this->parent, $this->pathSeparator);

            $this->validateConcreteNode($node);

            $node->setAddIfNotSet($this->addDefaults);

            foreach ($this->children as $child) {
                $child->parent = $node;
                $node->addChild($child->getNode());
            }
        } else {
            $node = new PrototypedArrayNode($this->name, $this->parent, $this->pathSeparator);

            $this->validatePrototypeNode($node);

            if (null !== $this->key) {
                $node->setKeyAttribute($this->key, $this->removeKeyItem);
            }

            if (true === $this->atLeastOne || false === $this->allowEmptyValue) {
                $node->setMinNumberOfElements(1);
            }

            if ($this->default) {
                if (!\is_array($this->defaultValue)) {
                    throw new \InvalidArgumentException(sprintf('%s: the default value of an array node has to be an array.', $node->getPath()));
                }

                $node->setDefaultValue($this->defaultValue);
            }

            if (false !== $this->addDefaultChildren) {
                $node->setAddChildrenIfNoneSet($this->addDefaultChildren);
                if ($this->prototype instanceof static && null === $this->prototype->prototype) {
                    $this->prototype->addDefaultsIfNotSet();
                }
            }

            $this->prototype->parent = $node;
            $node->setPrototype($this->prototype->getNode());
        }

        $node->setAllowNewKeys($this->allowNewKeys);
        $node->addEquivalentValue(null, $this->nullEquivalent);
        $node->addEquivalentValue(true, $this->trueEquivalent);
        $node->addEquivalentValue(false, $this->falseEquivalent);
        $node->setPerformDeepMerging($this->performDeepMerging);
        $node->setRequired($this->required);
        $node->setIgnoreExtraKeys($this->ignoreExtraKeys, $this->removeExtraKeys);
        $node->setNormalizeKeys($this->normalizeKeys);

        if ($this->deprecation) {
            $node->setDeprecated($this->deprecation['package'], $this->deprecation['version'], $this->deprecation['message']);
        }

        if (null !== $this->normalization) {
            $node->setNormalizationClosures($this->normalization->before);
            $node->setXmlRemappings($this->normalization->remappings);
        }

        if (null !== $this->merge) {
            $node->setAllowOverwrite($this->merge->allowOverwrite);
            $node->setAllowFalse($this->merge->allowFalse);
        }

        if (null !== $this->validation) {
            $node->setFinalValidationClosures($this->validation->rules);
        }

        return $node;
    }

    /**
     * Validate the configuration of a concrete node.
     *
     * @throws InvalidDefinitionException
     */
    protected function validateConcreteNode(ArrayNode $node)
    {
        $path = $node->getPath();

        if (null !== $this->key) {
            throw new InvalidDefinitionException(sprintf('->useAttributeAsKey() is not applicable to concrete nodes at path "%s".', $path));
        }

        if (false === $this->allowEmptyValue) {
            throw new InvalidDefinitionException(sprintf('->cannotBeEmpty() is not applicable to concrete nodes at path "%s".', $path));
        }

        if (true === $this->atLeastOne) {
            throw new InvalidDefinitionException(sprintf('->requiresAtLeastOneElement() is not applicable to concrete nodes at path "%s".', $path));
        }

        if ($this->default) {
            throw new InvalidDefinitionException(sprintf('->defaultValue() is not applicable to concrete nodes at path "%s".', $path));
        }

        if (false !== $this->addDefaultChildren) {
            throw new InvalidDefinitionException(sprintf('->addDefaultChildrenIfNoneSet() is not applicable to concrete nodes at path "%s".', $path));
        }
    }

    /**
     * Validate the configuration of a prototype node.
     *
     * @throws InvalidDefinitionException
     */
    protected function validatePrototypeNode(PrototypedArrayNode $node)
    {
        $path = $node->getPath();

        if ($this->addDefaults) {
            throw new InvalidDefinitionException(sprintf('->addDefaultsIfNotSet() is not applicable to prototype nodes at path "%s".', $path));
        }

        if (false !== $this->addDefaultChildren) {
            if ($this->default) {
                throw new InvalidDefinitionException(sprintf('A default value and default children might not be used together at path "%s".', $path));
            }

            if (null !== $this->key && (null === $this->addDefaultChildren || \is_int($this->addDefaultChildren) && $this->addDefaultChildren > 0)) {
                throw new InvalidDefinitionException(sprintf('->addDefaultChildrenIfNoneSet() should set default children names as ->useAttributeAsKey() is used at path "%s".', $path));
            }

            if (null === $this->key && (\is_string($this->addDefaultChildren) || \is_array($this->addDefaultChildren))) {
                throw new InvalidDefinitionException(sprintf('->addDefaultChildrenIfNoneSet() might not set default children names as ->useAttributeAsKey() is not used at path "%s".', $path));
            }
        }
    }

    /**
     * @return NodeDefinition[]
     */
    public function getChildNodeDefinitions()
    {
        return $this->children;
    }

    /**
     * Finds a node defined by the given $nodePath.
     *
     * @param string $nodePath The path of the node to find. e.g "doctrine.orm.mappings"
     */
    public function find(string $nodePath): NodeDefinition
    {
        $firstPathSegment = (false === $pathSeparatorPos = strpos($nodePath, $this->pathSeparator))
            ? $nodePath
            : substr($nodePath, 0, $pathSeparatorPos);

        if (null === $node = ($this->children[$firstPathSegment] ?? null)) {
            throw new \RuntimeException(sprintf('Node with name "%s" does not exist in the current node "%s".', $firstPathSegment, $this->name));
        }

        if (false === $pathSeparatorPos) {
            return $node;
        }

        return $node->find(substr($nodePath, $pathSeparatorPos + \strlen($this->pathSeparator)));
    }
}
PKϤ$ZK�p�)config/Definition/Builder/TreeBuilder.phpnu�[���<?php

/*
 * This file is part of the Symfony package.
 *
 * (c) Fabien Potencier <fabien@symfony.com>
 *
 * For the full copyright and license information, please view the LICENSE
 * file that was distributed with this source code.
 */

namespace Symfony\Component\Config\Definition\Builder;

use Symfony\Component\Config\Definition\NodeInterface;

/**
 * This is the entry class for building a config tree.
 *
 * @author Johannes M. Schmitt <schmittjoh@gmail.com>
 */
class TreeBuilder implements NodeParentInterface
{
    protected $tree;
    protected $root;

    public function __construct(string $name, string $type = 'array', NodeBuilder $builder = null)
    {
        $builder = $builder ?? new NodeBuilder();
        $this->root = $builder->node($name, $type)->setParent($this);
    }

    /**
     * @return NodeDefinition|ArrayNodeDefinition The root node (as an ArrayNodeDefinition when the type is 'array')
     */
    public function getRootNode(): NodeDefinition
    {
        return $this->root;
    }

    /**
     * Builds the tree.
     *
     * @return NodeInterface
     *
     * @throws \RuntimeException
     */
    public function buildTree()
    {
        if (null !== $this->tree) {
            return $this->tree;
        }

        return $this->tree = $this->root->getNode(true);
    }

    public function setPathSeparator(string $separator)
    {
        // unset last built as changing path separator changes all nodes
        $this->tree = null;

        $this->root->setPathSeparator($separator);
    }
}
PKϤ$ZB��}CC3config/Definition/Builder/BuilderAwareInterface.phpnu�[���<?php

/*
 * This file is part of the Symfony package.
 *
 * (c) Fabien Potencier <fabien@symfony.com>
 *
 * For the full copyright and license information, please view the LICENSE
 * file that was distributed with this source code.
 */

namespace Symfony\Component\Config\Definition\Builder;

/**
 * An interface that can be implemented by nodes which build other nodes.
 *
 * @author Roland Franssen <franssen.roland@gmail.com>
 */
interface BuilderAwareInterface
{
    /**
     * Sets a custom children builder.
     */
    public function setBuilder(NodeBuilder $builder);
}
PKϤ$Z#��994config/Definition/Builder/VariableNodeDefinition.phpnu�[���<?php

/*
 * This file is part of the Symfony package.
 *
 * (c) Fabien Potencier <fabien@symfony.com>
 *
 * For the full copyright and license information, please view the LICENSE
 * file that was distributed with this source code.
 */

namespace Symfony\Component\Config\Definition\Builder;

use Symfony\Component\Config\Definition\VariableNode;

/**
 * This class provides a fluent interface for defining a node.
 *
 * @author Johannes M. Schmitt <schmittjoh@gmail.com>
 */
class VariableNodeDefinition extends NodeDefinition
{
    /**
     * Instantiate a Node.
     *
     * @return VariableNode
     */
    protected function instantiateNode()
    {
        return new VariableNode($this->name, $this->parent, $this->pathSeparator);
    }

    /**
     * {@inheritdoc}
     */
    protected function createNode()
    {
        $node = $this->instantiateNode();

        if (null !== $this->normalization) {
            $node->setNormalizationClosures($this->normalization->before);
        }

        if (null !== $this->merge) {
            $node->setAllowOverwrite($this->merge->allowOverwrite);
        }

        if (true === $this->default) {
            $node->setDefaultValue($this->defaultValue);
        }

        $node->setAllowEmptyValue($this->allowEmptyValue);
        $node->addEquivalentValue(null, $this->nullEquivalent);
        $node->addEquivalentValue(true, $this->trueEquivalent);
        $node->addEquivalentValue(false, $this->falseEquivalent);
        $node->setRequired($this->required);

        if ($this->deprecation) {
            $node->setDeprecated($this->deprecation['package'], $this->deprecation['version'], $this->deprecation['message']);
        }

        if (null !== $this->validation) {
            $node->setFinalValidationClosures($this->validation->rules);
        }

        return $node;
    }
}
PKϤ$Z��)config/Definition/Builder/NodeBuilder.phpnu�[���<?php

/*
 * This file is part of the Symfony package.
 *
 * (c) Fabien Potencier <fabien@symfony.com>
 *
 * For the full copyright and license information, please view the LICENSE
 * file that was distributed with this source code.
 */

namespace Symfony\Component\Config\Definition\Builder;

/**
 * This class provides a fluent interface for building a node.
 *
 * @author Johannes M. Schmitt <schmittjoh@gmail.com>
 */
class NodeBuilder implements NodeParentInterface
{
    protected $parent;
    protected $nodeMapping;

    public function __construct()
    {
        $this->nodeMapping = [
            'variable' => VariableNodeDefinition::class,
            'scalar' => ScalarNodeDefinition::class,
            'boolean' => BooleanNodeDefinition::class,
            'integer' => IntegerNodeDefinition::class,
            'float' => FloatNodeDefinition::class,
            'array' => ArrayNodeDefinition::class,
            'enum' => EnumNodeDefinition::class,
        ];
    }

    /**
     * Set the parent node.
     *
     * @return $this
     */
    public function setParent(ParentNodeDefinitionInterface $parent = null)
    {
        $this->parent = $parent;

        return $this;
    }

    /**
     * Creates a child array node.
     *
     * @return ArrayNodeDefinition
     */
    public function arrayNode(string $name)
    {
        return $this->node($name, 'array');
    }

    /**
     * Creates a child scalar node.
     *
     * @return ScalarNodeDefinition
     */
    public function scalarNode(string $name)
    {
        return $this->node($name, 'scalar');
    }

    /**
     * Creates a child Boolean node.
     *
     * @return BooleanNodeDefinition
     */
    public function booleanNode(string $name)
    {
        return $this->node($name, 'boolean');
    }

    /**
     * Creates a child integer node.
     *
     * @return IntegerNodeDefinition
     */
    public function integerNode(string $name)
    {
        return $this->node($name, 'integer');
    }

    /**
     * Creates a child float node.
     *
     * @return FloatNodeDefinition
     */
    public function floatNode(string $name)
    {
        return $this->node($name, 'float');
    }

    /**
     * Creates a child EnumNode.
     *
     * @return EnumNodeDefinition
     */
    public function enumNode(string $name)
    {
        return $this->node($name, 'enum');
    }

    /**
     * Creates a child variable node.
     *
     * @return VariableNodeDefinition
     */
    public function variableNode(string $name)
    {
        return $this->node($name, 'variable');
    }

    /**
     * Returns the parent node.
     *
     * @return NodeDefinition&ParentNodeDefinitionInterface
     */
    public function end()
    {
        return $this->parent;
    }

    /**
     * Creates a child node.
     *
     * @return NodeDefinition
     *
     * @throws \RuntimeException When the node type is not registered
     * @throws \RuntimeException When the node class is not found
     */
    public function node(?string $name, string $type)
    {
        $class = $this->getNodeClass($type);

        $node = new $class($name);

        $this->append($node);

        return $node;
    }

    /**
     * Appends a node definition.
     *
     * Usage:
     *
     *     $node = new ArrayNodeDefinition('name')
     *         ->children()
     *             ->scalarNode('foo')->end()
     *             ->scalarNode('baz')->end()
     *             ->append($this->getBarNodeDefinition())
     *         ->end()
     *     ;
     *
     * @return $this
     */
    public function append(NodeDefinition $node)
    {
        if ($node instanceof BuilderAwareInterface) {
            $builder = clone $this;
            $builder->setParent(null);
            $node->setBuilder($builder);
        }

        if (null !== $this->parent) {
            $this->parent->append($node);
            // Make this builder the node parent to allow for a fluid interface
            $node->setParent($this);
        }

        return $this;
    }

    /**
     * Adds or overrides a node Type.
     *
     * @param string $type  The name of the type
     * @param string $class The fully qualified name the node definition class
     *
     * @return $this
     */
    public function setNodeClass(string $type, string $class)
    {
        $this->nodeMapping[strtolower($type)] = $class;

        return $this;
    }

    /**
     * Returns the class name of the node definition.
     *
     * @return string
     *
     * @throws \RuntimeException When the node type is not registered
     * @throws \RuntimeException When the node class is not found
     */
    protected function getNodeClass(string $type)
    {
        $type = strtolower($type);

        if (!isset($this->nodeMapping[$type])) {
            throw new \RuntimeException(sprintf('The node type "%s" is not registered.', $type));
        }

        $class = $this->nodeMapping[$type];

        if (!class_exists($class)) {
            throw new \RuntimeException(sprintf('The node class "%s" does not exist.', $class));
        }

        return $class;
    }
}
PKϤ$ZY��ӿ�1config/Definition/Builder/NodeParentInterface.phpnu�[���<?php

/*
 * This file is part of the Symfony package.
 *
 * (c) Fabien Potencier <fabien@symfony.com>
 *
 * For the full copyright and license information, please view the LICENSE
 * file that was distributed with this source code.
 */

namespace Symfony\Component\Config\Definition\Builder;

/**
 * An interface that must be implemented by all node parents.
 *
 * @author Victor Berchet <victor@suumit.com>
 */
interface NodeParentInterface
{
}
PKϤ$Z/@-��2config/Definition/Builder/NormalizationBuilder.phpnu�[���<?php

/*
 * This file is part of the Symfony package.
 *
 * (c) Fabien Potencier <fabien@symfony.com>
 *
 * For the full copyright and license information, please view the LICENSE
 * file that was distributed with this source code.
 */

namespace Symfony\Component\Config\Definition\Builder;

/**
 * This class builds normalization conditions.
 *
 * @author Johannes M. Schmitt <schmittjoh@gmail.com>
 */
class NormalizationBuilder
{
    protected $node;
    public $before = [];
    public $remappings = [];

    public function __construct(NodeDefinition $node)
    {
        $this->node = $node;
    }

    /**
     * Registers a key to remap to its plural form.
     *
     * @param string      $key    The key to remap
     * @param string|null $plural The plural of the key in case of irregular plural
     *
     * @return $this
     */
    public function remap(string $key, string $plural = null)
    {
        $this->remappings[] = [$key, null === $plural ? $key.'s' : $plural];

        return $this;
    }

    /**
     * Registers a closure to run before the normalization or an expression builder to build it if null is provided.
     *
     * @return ExprBuilder|$this
     */
    public function before(\Closure $closure = null)
    {
        if (null !== $closure) {
            $this->before[] = $closure;

            return $this;
        }

        return $this->before[] = new ExprBuilder($this->node);
    }
}
PKϤ$Z6�l���3config/Definition/Builder/NumericNodeDefinition.phpnu�[���<?php

/*
 * This file is part of the Symfony package.
 *
 * (c) Fabien Potencier <fabien@symfony.com>
 *
 * For the full copyright and license information, please view the LICENSE
 * file that was distributed with this source code.
 */

namespace Symfony\Component\Config\Definition\Builder;

use Symfony\Component\Config\Definition\Exception\InvalidDefinitionException;

/**
 * Abstract class that contains common code of integer and float node definitions.
 *
 * @author David Jeanmonod <david.jeanmonod@gmail.com>
 */
abstract class NumericNodeDefinition extends ScalarNodeDefinition
{
    protected $min;
    protected $max;

    /**
     * Ensures that the value is smaller than the given reference.
     *
     * @param int|float $max
     *
     * @return $this
     *
     * @throws \InvalidArgumentException when the constraint is inconsistent
     */
    public function max($max)
    {
        if (isset($this->min) && $this->min > $max) {
            throw new \InvalidArgumentException(sprintf('You cannot define a max(%s) as you already have a min(%s).', $max, $this->min));
        }
        $this->max = $max;

        return $this;
    }

    /**
     * Ensures that the value is bigger than the given reference.
     *
     * @param int|float $min
     *
     * @return $this
     *
     * @throws \InvalidArgumentException when the constraint is inconsistent
     */
    public function min($min)
    {
        if (isset($this->max) && $this->max < $min) {
            throw new \InvalidArgumentException(sprintf('You cannot define a min(%s) as you already have a max(%s).', $min, $this->max));
        }
        $this->min = $min;

        return $this;
    }

    /**
     * {@inheritdoc}
     *
     * @throws InvalidDefinitionException
     */
    public function cannotBeEmpty()
    {
        throw new InvalidDefinitionException('->cannotBeEmpty() is not applicable to NumericNodeDefinition.');
    }
}
PKϤ$Z�f3config/Definition/Builder/IntegerNodeDefinition.phpnu�[���<?php

/*
 * This file is part of the Symfony package.
 *
 * (c) Fabien Potencier <fabien@symfony.com>
 *
 * For the full copyright and license information, please view the LICENSE
 * file that was distributed with this source code.
 */

namespace Symfony\Component\Config\Definition\Builder;

use Symfony\Component\Config\Definition\IntegerNode;

/**
 * This class provides a fluent interface for defining an integer node.
 *
 * @author Jeanmonod David <david.jeanmonod@gmail.com>
 */
class IntegerNodeDefinition extends NumericNodeDefinition
{
    /**
     * Instantiates a Node.
     *
     * @return IntegerNode
     */
    protected function instantiateNode()
    {
        return new IntegerNode($this->name, $this->parent, $this->min, $this->max, $this->pathSeparator);
    }
}
PKϤ$Z�_e���2config/Definition/Builder/ScalarNodeDefinition.phpnu�[���<?php

/*
 * This file is part of the Symfony package.
 *
 * (c) Fabien Potencier <fabien@symfony.com>
 *
 * For the full copyright and license information, please view the LICENSE
 * file that was distributed with this source code.
 */

namespace Symfony\Component\Config\Definition\Builder;

use Symfony\Component\Config\Definition\ScalarNode;

/**
 * This class provides a fluent interface for defining a node.
 *
 * @author Johannes M. Schmitt <schmittjoh@gmail.com>
 */
class ScalarNodeDefinition extends VariableNodeDefinition
{
    /**
     * Instantiate a Node.
     *
     * @return ScalarNode
     */
    protected function instantiateNode()
    {
        return new ScalarNode($this->name, $this->parent, $this->pathSeparator);
    }
}
PKϤ$Z�x��
�
"config/Definition/VariableNode.phpnu�[���<?php

/*
 * This file is part of the Symfony package.
 *
 * (c) Fabien Potencier <fabien@symfony.com>
 *
 * For the full copyright and license information, please view the LICENSE
 * file that was distributed with this source code.
 */

namespace Symfony\Component\Config\Definition;

use Symfony\Component\Config\Definition\Exception\InvalidConfigurationException;

/**
 * This node represents a value of variable type in the config tree.
 *
 * This node is intended for values of arbitrary type.
 * Any PHP type is accepted as a value.
 *
 * @author Jeremy Mikola <jmikola@gmail.com>
 */
class VariableNode extends BaseNode implements PrototypeNodeInterface
{
    protected $defaultValueSet = false;
    protected $defaultValue;
    protected $allowEmptyValue = true;

    public function setDefaultValue($value)
    {
        $this->defaultValueSet = true;
        $this->defaultValue = $value;
    }

    /**
     * {@inheritdoc}
     */
    public function hasDefaultValue()
    {
        return $this->defaultValueSet;
    }

    /**
     * {@inheritdoc}
     */
    public function getDefaultValue()
    {
        $v = $this->defaultValue;

        return $v instanceof \Closure ? $v() : $v;
    }

    /**
     * Sets if this node is allowed to have an empty value.
     *
     * @param bool $boolean True if this entity will accept empty values
     */
    public function setAllowEmptyValue(bool $boolean)
    {
        $this->allowEmptyValue = $boolean;
    }

    /**
     * {@inheritdoc}
     */
    public function setName(string $name)
    {
        $this->name = $name;
    }

    /**
     * {@inheritdoc}
     */
    protected function validateType($value)
    {
    }

    /**
     * {@inheritdoc}
     */
    protected function finalizeValue($value)
    {
        // deny environment variables only when using custom validators
        // this avoids ever passing an empty value to final validation closures
        if (!$this->allowEmptyValue && $this->isHandlingPlaceholder() && $this->finalValidationClosures) {
            $e = new InvalidConfigurationException(sprintf('The path "%s" cannot contain an environment variable when empty values are not allowed by definition and are validated.', $this->getPath()));
            if ($hint = $this->getInfo()) {
                $e->addHint($hint);
            }
            $e->setPath($this->getPath());

            throw $e;
        }

        if (!$this->allowEmptyValue && $this->isValueEmpty($value)) {
            $ex = new InvalidConfigurationException(sprintf('The path "%s" cannot contain an empty value, but got %s.', $this->getPath(), json_encode($value)));
            if ($hint = $this->getInfo()) {
                $ex->addHint($hint);
            }
            $ex->setPath($this->getPath());

            throw $ex;
        }

        return $value;
    }

    /**
     * {@inheritdoc}
     */
    protected function normalizeValue($value)
    {
        return $value;
    }

    /**
     * {@inheritdoc}
     */
    protected function mergeValues($leftSide, $rightSide)
    {
        return $rightSide;
    }

    /**
     * Evaluates if the given value is to be treated as empty.
     *
     * By default, PHP's empty() function is used to test for emptiness. This
     * method may be overridden by subtypes to better match their understanding
     * of empty data.
     *
     * @param mixed $value
     *
     * @return bool
     *
     * @see finalizeValue()
     */
    protected function isValueEmpty($value)
    {
        return empty($value);
    }
}
PKϤ$ZD����config/Definition/EnumNode.phpnu�[���<?php

/*
 * This file is part of the Symfony package.
 *
 * (c) Fabien Potencier <fabien@symfony.com>
 *
 * For the full copyright and license information, please view the LICENSE
 * file that was distributed with this source code.
 */

namespace Symfony\Component\Config\Definition;

use Symfony\Component\Config\Definition\Exception\InvalidConfigurationException;

/**
 * Node which only allows a finite set of values.
 *
 * @author Johannes M. Schmitt <schmittjoh@gmail.com>
 */
class EnumNode extends ScalarNode
{
    private $values;

    public function __construct(?string $name, NodeInterface $parent = null, array $values = [], string $pathSeparator = BaseNode::DEFAULT_PATH_SEPARATOR)
    {
        $values = array_unique($values);
        if (empty($values)) {
            throw new \InvalidArgumentException('$values must contain at least one element.');
        }

        parent::__construct($name, $parent, $pathSeparator);
        $this->values = $values;
    }

    public function getValues()
    {
        return $this->values;
    }

    /**
     * {@inheritdoc}
     */
    protected function finalizeValue($value)
    {
        $value = parent::finalizeValue($value);

        if (!\in_array($value, $this->values, true)) {
            $ex = new InvalidConfigurationException(sprintf('The value %s is not allowed for path "%s". Permissible values: %s', json_encode($value), $this->getPath(), implode(', ', array_map('json_encode', $this->values))));
            $ex->setPath($this->getPath());

            throw $ex;
        }

        return $value;
    }

    /**
     * {@inheritdoc}
     */
    protected function allowPlaceholders(): bool
    {
        return false;
    }
}
PKϤ$Z��nlq(q(/config/Definition/Dumper/XmlReferenceDumper.phpnu�[���<?php

/*
 * This file is part of the Symfony package.
 *
 * (c) Fabien Potencier <fabien@symfony.com>
 *
 * For the full copyright and license information, please view the LICENSE
 * file that was distributed with this source code.
 */

namespace Symfony\Component\Config\Definition\Dumper;

use Symfony\Component\Config\Definition\ArrayNode;
use Symfony\Component\Config\Definition\BaseNode;
use Symfony\Component\Config\Definition\ConfigurationInterface;
use Symfony\Component\Config\Definition\EnumNode;
use Symfony\Component\Config\Definition\NodeInterface;
use Symfony\Component\Config\Definition\PrototypedArrayNode;

/**
 * Dumps an XML reference configuration for the given configuration/node instance.
 *
 * @author Wouter J <waldio.webdesign@gmail.com>
 */
class XmlReferenceDumper
{
    private $reference;

    public function dump(ConfigurationInterface $configuration, string $namespace = null)
    {
        return $this->dumpNode($configuration->getConfigTreeBuilder()->buildTree(), $namespace);
    }

    public function dumpNode(NodeInterface $node, string $namespace = null)
    {
        $this->reference = '';
        $this->writeNode($node, 0, true, $namespace);
        $ref = $this->reference;
        $this->reference = null;

        return $ref;
    }

    private function writeNode(NodeInterface $node, int $depth = 0, bool $root = false, string $namespace = null)
    {
        $rootName = ($root ? 'config' : $node->getName());
        $rootNamespace = ($namespace ?: ($root ? 'http://example.org/schema/dic/'.$node->getName() : null));

        // xml remapping
        if ($node->getParent()) {
            $remapping = array_filter($node->getParent()->getXmlRemappings(), function (array $mapping) use ($rootName) {
                return $rootName === $mapping[1];
            });

            if (\count($remapping)) {
                [$singular] = current($remapping);
                $rootName = $singular;
            }
        }
        $rootName = str_replace('_', '-', $rootName);

        $rootAttributes = [];
        $rootAttributeComments = [];
        $rootChildren = [];
        $rootComments = [];

        if ($node instanceof ArrayNode) {
            $children = $node->getChildren();

            // comments about the root node
            if ($rootInfo = $node->getInfo()) {
                $rootComments[] = $rootInfo;
            }

            if ($rootNamespace) {
                $rootComments[] = 'Namespace: '.$rootNamespace;
            }

            // render prototyped nodes
            if ($node instanceof PrototypedArrayNode) {
                $prototype = $node->getPrototype();

                $info = 'prototype';
                if (null !== $prototype->getInfo()) {
                    $info .= ': '.$prototype->getInfo();
                }
                array_unshift($rootComments, $info);

                if ($key = $node->getKeyAttribute()) {
                    $rootAttributes[$key] = str_replace('-', ' ', $rootName).' '.$key;
                }

                if ($prototype instanceof PrototypedArrayNode) {
                    $prototype->setName($key ?? '');
                    $children = [$key => $prototype];
                } elseif ($prototype instanceof ArrayNode) {
                    $children = $prototype->getChildren();
                } else {
                    if ($prototype->hasDefaultValue()) {
                        $prototypeValue = $prototype->getDefaultValue();
                    } else {
                        switch (\get_class($prototype)) {
                            case 'Symfony\Component\Config\Definition\ScalarNode':
                                $prototypeValue = 'scalar value';
                                break;

                            case 'Symfony\Component\Config\Definition\FloatNode':
                            case 'Symfony\Component\Config\Definition\IntegerNode':
                                $prototypeValue = 'numeric value';
                                break;

                            case 'Symfony\Component\Config\Definition\BooleanNode':
                                $prototypeValue = 'true|false';
                                break;

                            case 'Symfony\Component\Config\Definition\EnumNode':
                                $prototypeValue = implode('|', array_map('json_encode', $prototype->getValues()));
                                break;

                            default:
                                $prototypeValue = 'value';
                        }
                    }
                }
            }

            // get attributes and elements
            foreach ($children as $child) {
                if ($child instanceof ArrayNode) {
                    // get elements
                    $rootChildren[] = $child;

                    continue;
                }

                // get attributes

                // metadata
                $name = str_replace('_', '-', $child->getName());
                $value = '%%%%not_defined%%%%'; // use a string which isn't used in the normal world

                // comments
                $comments = [];
                if ($child instanceof BaseNode && $info = $child->getInfo()) {
                    $comments[] = $info;
                }

                if ($child instanceof BaseNode && $example = $child->getExample()) {
                    $comments[] = 'Example: '.$example;
                }

                if ($child->isRequired()) {
                    $comments[] = 'Required';
                }

                if ($child instanceof BaseNode && $child->isDeprecated()) {
                    $deprecation = $child->getDeprecation($child->getName(), $node->getPath());
                    $comments[] = sprintf('Deprecated (%s)', ($deprecation['package'] || $deprecation['version'] ? "Since {$deprecation['package']} {$deprecation['version']}: " : '').$deprecation['message']);
                }

                if ($child instanceof EnumNode) {
                    $comments[] = 'One of '.implode('; ', array_map('json_encode', $child->getValues()));
                }

                if (\count($comments)) {
                    $rootAttributeComments[$name] = implode(";\n", $comments);
                }

                // default values
                if ($child->hasDefaultValue()) {
                    $value = $child->getDefaultValue();
                }

                // append attribute
                $rootAttributes[$name] = $value;
            }
        }

        // render comments

        // root node comment
        if (\count($rootComments)) {
            foreach ($rootComments as $comment) {
                $this->writeLine('<!-- '.$comment.' -->', $depth);
            }
        }

        // attribute comments
        if (\count($rootAttributeComments)) {
            foreach ($rootAttributeComments as $attrName => $comment) {
                $commentDepth = $depth + 4 + \strlen($attrName) + 2;
                $commentLines = explode("\n", $comment);
                $multiline = (\count($commentLines) > 1);
                $comment = implode(\PHP_EOL.str_repeat(' ', $commentDepth), $commentLines);

                if ($multiline) {
                    $this->writeLine('<!--', $depth);
                    $this->writeLine($attrName.': '.$comment, $depth + 4);
                    $this->writeLine('-->', $depth);
                } else {
                    $this->writeLine('<!-- '.$attrName.': '.$comment.' -->', $depth);
                }
            }
        }

        // render start tag + attributes
        $rootIsVariablePrototype = isset($prototypeValue);
        $rootIsEmptyTag = (0 === \count($rootChildren) && !$rootIsVariablePrototype);
        $rootOpenTag = '<'.$rootName;
        if (1 >= ($attributesCount = \count($rootAttributes))) {
            if (1 === $attributesCount) {
                $rootOpenTag .= sprintf(' %s="%s"', current(array_keys($rootAttributes)), $this->writeValue(current($rootAttributes)));
            }

            $rootOpenTag .= $rootIsEmptyTag ? ' />' : '>';

            if ($rootIsVariablePrototype) {
                $rootOpenTag .= $prototypeValue.'</'.$rootName.'>';
            }

            $this->writeLine($rootOpenTag, $depth);
        } else {
            $this->writeLine($rootOpenTag, $depth);

            $i = 1;

            foreach ($rootAttributes as $attrName => $attrValue) {
                $attr = sprintf('%s="%s"', $attrName, $this->writeValue($attrValue));

                $this->writeLine($attr, $depth + 4);

                if ($attributesCount === $i++) {
                    $this->writeLine($rootIsEmptyTag ? '/>' : '>', $depth);

                    if ($rootIsVariablePrototype) {
                        $rootOpenTag .= $prototypeValue.'</'.$rootName.'>';
                    }
                }
            }
        }

        // render children tags
        foreach ($rootChildren as $child) {
            $this->writeLine('');
            $this->writeNode($child, $depth + 4);
        }

        // render end tag
        if (!$rootIsEmptyTag && !$rootIsVariablePrototype) {
            $this->writeLine('');

            $rootEndTag = '</'.$rootName.'>';
            $this->writeLine($rootEndTag, $depth);
        }
    }

    /**
     * Outputs a single config reference line.
     */
    private function writeLine(string $text, int $indent = 0)
    {
        $indent = \strlen($text) + $indent;
        $format = '%'.$indent.'s';

        $this->reference .= sprintf($format, $text).\PHP_EOL;
    }

    /**
     * Renders the string conversion of the value.
     *
     * @param mixed $value
     */
    private function writeValue($value): string
    {
        if ('%%%%not_defined%%%%' === $value) {
            return '';
        }

        if (\is_string($value) || is_numeric($value)) {
            return $value;
        }

        if (false === $value) {
            return 'false';
        }

        if (true === $value) {
            return 'true';
        }

        if (null === $value) {
            return 'null';
        }

        if (empty($value)) {
            return '';
        }

        if (\is_array($value)) {
            return implode(',', $value);
        }

        return '';
    }
}
PKϤ$Z�^ZƘ � 0config/Definition/Dumper/YamlReferenceDumper.phpnu�[���<?php

/*
 * This file is part of the Symfony package.
 *
 * (c) Fabien Potencier <fabien@symfony.com>
 *
 * For the full copyright and license information, please view the LICENSE
 * file that was distributed with this source code.
 */

namespace Symfony\Component\Config\Definition\Dumper;

use Symfony\Component\Config\Definition\ArrayNode;
use Symfony\Component\Config\Definition\BaseNode;
use Symfony\Component\Config\Definition\ConfigurationInterface;
use Symfony\Component\Config\Definition\EnumNode;
use Symfony\Component\Config\Definition\NodeInterface;
use Symfony\Component\Config\Definition\PrototypedArrayNode;
use Symfony\Component\Config\Definition\ScalarNode;
use Symfony\Component\Config\Definition\VariableNode;
use Symfony\Component\Yaml\Inline;

/**
 * Dumps a Yaml reference configuration for the given configuration/node instance.
 *
 * @author Kevin Bond <kevinbond@gmail.com>
 */
class YamlReferenceDumper
{
    private $reference;

    public function dump(ConfigurationInterface $configuration)
    {
        return $this->dumpNode($configuration->getConfigTreeBuilder()->buildTree());
    }

    public function dumpAtPath(ConfigurationInterface $configuration, string $path)
    {
        $rootNode = $node = $configuration->getConfigTreeBuilder()->buildTree();

        foreach (explode('.', $path) as $step) {
            if (!$node instanceof ArrayNode) {
                throw new \UnexpectedValueException(sprintf('Unable to find node at path "%s.%s".', $rootNode->getName(), $path));
            }

            /** @var NodeInterface[] $children */
            $children = $node instanceof PrototypedArrayNode ? $this->getPrototypeChildren($node) : $node->getChildren();

            foreach ($children as $child) {
                if ($child->getName() === $step) {
                    $node = $child;

                    continue 2;
                }
            }

            throw new \UnexpectedValueException(sprintf('Unable to find node at path "%s.%s".', $rootNode->getName(), $path));
        }

        return $this->dumpNode($node);
    }

    public function dumpNode(NodeInterface $node)
    {
        $this->reference = '';
        $this->writeNode($node);
        $ref = $this->reference;
        $this->reference = null;

        return $ref;
    }

    private function writeNode(NodeInterface $node, NodeInterface $parentNode = null, int $depth = 0, bool $prototypedArray = false)
    {
        $comments = [];
        $default = '';
        $defaultArray = null;
        $children = null;
        $example = null;
        if ($node instanceof BaseNode) {
            $example = $node->getExample();
        }

        // defaults
        if ($node instanceof ArrayNode) {
            $children = $node->getChildren();

            if ($node instanceof PrototypedArrayNode) {
                $children = $this->getPrototypeChildren($node);
            }

            if (!$children) {
                if ($node->hasDefaultValue() && \count($defaultArray = $node->getDefaultValue())) {
                    $default = '';
                } elseif (!\is_array($example)) {
                    $default = '[]';
                }
            }
        } elseif ($node instanceof EnumNode) {
            $comments[] = 'One of '.implode('; ', array_map('json_encode', $node->getValues()));
            $default = $node->hasDefaultValue() ? Inline::dump($node->getDefaultValue()) : '~';
        } elseif (VariableNode::class === \get_class($node) && \is_array($example)) {
            // If there is an array example, we are sure we dont need to print a default value
            $default = '';
        } else {
            $default = '~';

            if ($node->hasDefaultValue()) {
                $default = $node->getDefaultValue();

                if (\is_array($default)) {
                    if (\count($defaultArray = $node->getDefaultValue())) {
                        $default = '';
                    } elseif (!\is_array($example)) {
                        $default = '[]';
                    }
                } else {
                    $default = Inline::dump($default);
                }
            }
        }

        // required?
        if ($node->isRequired()) {
            $comments[] = 'Required';
        }

        // deprecated?
        if ($node instanceof BaseNode && $node->isDeprecated()) {
            $deprecation = $node->getDeprecation($node->getName(), $parentNode ? $parentNode->getPath() : $node->getPath());
            $comments[] = sprintf('Deprecated (%s)', ($deprecation['package'] || $deprecation['version'] ? "Since {$deprecation['package']} {$deprecation['version']}: " : '').$deprecation['message']);
        }

        // example
        if ($example && !\is_array($example)) {
            $comments[] = 'Example: '.Inline::dump($example);
        }

        $default = '' != (string) $default ? ' '.$default : '';
        $comments = \count($comments) ? '# '.implode(', ', $comments) : '';

        $key = $prototypedArray ? '-' : $node->getName().':';
        $text = rtrim(sprintf('%-21s%s %s', $key, $default, $comments), ' ');

        if ($node instanceof BaseNode && $info = $node->getInfo()) {
            $this->writeLine('');
            // indenting multi-line info
            $info = str_replace("\n", sprintf("\n%".($depth * 4).'s# ', ' '), $info);
            $this->writeLine('# '.$info, $depth * 4);
        }

        $this->writeLine($text, $depth * 4);

        // output defaults
        if ($defaultArray) {
            $this->writeLine('');

            $message = \count($defaultArray) > 1 ? 'Defaults' : 'Default';

            $this->writeLine('# '.$message.':', $depth * 4 + 4);

            $this->writeArray($defaultArray, $depth + 1);
        }

        if (\is_array($example)) {
            $this->writeLine('');

            $message = \count($example) > 1 ? 'Examples' : 'Example';

            $this->writeLine('# '.$message.':', $depth * 4 + 4);

            $this->writeArray(array_map([Inline::class, 'dump'], $example), $depth + 1);
        }

        if ($children) {
            foreach ($children as $childNode) {
                $this->writeNode($childNode, $node, $depth + 1, $node instanceof PrototypedArrayNode && !$node->getKeyAttribute());
            }
        }
    }

    /**
     * Outputs a single config reference line.
     */
    private function writeLine(string $text, int $indent = 0)
    {
        $indent = \strlen($text) + $indent;
        $format = '%'.$indent.'s';

        $this->reference .= sprintf($format, $text)."\n";
    }

    private function writeArray(array $array, int $depth)
    {
        $isIndexed = array_values($array) === $array;

        foreach ($array as $key => $value) {
            if (\is_array($value)) {
                $val = '';
            } else {
                $val = $value;
            }

            if ($isIndexed) {
                $this->writeLine('- '.$val, $depth * 4);
            } else {
                $this->writeLine(sprintf('%-20s %s', $key.':', $val), $depth * 4);
            }

            if (\is_array($value)) {
                $this->writeArray($value, $depth + 1);
            }
        }
    }

    private function getPrototypeChildren(PrototypedArrayNode $node): array
    {
        $prototype = $node->getPrototype();
        $key = $node->getKeyAttribute();

        // Do not expand prototype if it isn't an array node nor uses attribute as key
        if (!$key && !$prototype instanceof ArrayNode) {
            return $node->getChildren();
        }

        if ($prototype instanceof ArrayNode) {
            $keyNode = new ArrayNode($key, $node);
            $children = $prototype->getChildren();

            if ($prototype instanceof PrototypedArrayNode && $prototype->getKeyAttribute()) {
                $children = $this->getPrototypeChildren($prototype);
            }

            // add children
            foreach ($children as $childNode) {
                $keyNode->addChild($childNode);
            }
        } else {
            $keyNode = new ScalarNode($key, $node);
        }

        $info = 'Prototype';
        if (null !== $prototype->getInfo()) {
            $info .= ': '.$prototype->getInfo();
        }
        $keyNode->setInfo($info);

        return [$key => $keyNode];
    }
}
PKϤ$Zh�v��!config/Definition/BooleanNode.phpnu�[���<?php

/*
 * This file is part of the Symfony package.
 *
 * (c) Fabien Potencier <fabien@symfony.com>
 *
 * For the full copyright and license information, please view the LICENSE
 * file that was distributed with this source code.
 */

namespace Symfony\Component\Config\Definition;

use Symfony\Component\Config\Definition\Exception\InvalidTypeException;

/**
 * This node represents a Boolean value in the config tree.
 *
 * @author Johannes M. Schmitt <schmittjoh@gmail.com>
 */
class BooleanNode extends ScalarNode
{
    /**
     * {@inheritdoc}
     */
    protected function validateType($value)
    {
        if (!\is_bool($value)) {
            $ex = new InvalidTypeException(sprintf('Invalid type for path "%s". Expected "bool", but got "%s".', $this->getPath(), get_debug_type($value)));
            if ($hint = $this->getInfo()) {
                $ex->addHint($hint);
            }
            $ex->setPath($this->getPath());

            throw $ex;
        }
    }

    /**
     * {@inheritdoc}
     */
    protected function isValueEmpty($value)
    {
        // a boolean value cannot be empty
        return false;
    }

    /**
     * {@inheritdoc}
     */
    protected function getValidPlaceholderTypes(): array
    {
        return ['bool'];
    }
}
PKϤ$Zzԉ��� config/Definition/ScalarNode.phpnu�[���<?php

/*
 * This file is part of the Symfony package.
 *
 * (c) Fabien Potencier <fabien@symfony.com>
 *
 * For the full copyright and license information, please view the LICENSE
 * file that was distributed with this source code.
 */

namespace Symfony\Component\Config\Definition;

use Symfony\Component\Config\Definition\Exception\InvalidTypeException;

/**
 * This node represents a scalar value in the config tree.
 *
 * The following values are considered scalars:
 *   * booleans
 *   * strings
 *   * null
 *   * integers
 *   * floats
 *
 * @author Johannes M. Schmitt <schmittjoh@gmail.com>
 */
class ScalarNode extends VariableNode
{
    /**
     * {@inheritdoc}
     */
    protected function validateType($value)
    {
        if (!is_scalar($value) && null !== $value) {
            $ex = new InvalidTypeException(sprintf('Invalid type for path "%s". Expected "scalar", but got "%s".', $this->getPath(), get_debug_type($value)));
            if ($hint = $this->getInfo()) {
                $ex->addHint($hint);
            }
            $ex->setPath($this->getPath());

            throw $ex;
        }
    }

    /**
     * {@inheritdoc}
     */
    protected function isValueEmpty($value)
    {
        // assume environment variables are never empty (which in practice is likely to be true during runtime)
        // not doing so breaks many configs that are valid today
        if ($this->isHandlingPlaceholder()) {
            return false;
        }

        return null === $value || '' === $value;
    }

    /**
     * {@inheritdoc}
     */
    protected function getValidPlaceholderTypes(): array
    {
        return ['bool', 'int', 'float', 'string'];
    }
}
PKϤ$ZP,EeV	V	#config/Definition/NodeInterface.phpnu�[���<?php

/*
 * This file is part of the Symfony package.
 *
 * (c) Fabien Potencier <fabien@symfony.com>
 *
 * For the full copyright and license information, please view the LICENSE
 * file that was distributed with this source code.
 */

namespace Symfony\Component\Config\Definition;

use Symfony\Component\Config\Definition\Exception\ForbiddenOverwriteException;
use Symfony\Component\Config\Definition\Exception\InvalidConfigurationException;
use Symfony\Component\Config\Definition\Exception\InvalidTypeException;

/**
 * Common Interface among all nodes.
 *
 * In most cases, it is better to inherit from BaseNode instead of implementing
 * this interface yourself.
 *
 * @author Johannes M. Schmitt <schmittjoh@gmail.com>
 */
interface NodeInterface
{
    /**
     * Returns the name of the node.
     *
     * @return string
     */
    public function getName();

    /**
     * Returns the path of the node.
     *
     * @return string
     */
    public function getPath();

    /**
     * Returns true when the node is required.
     *
     * @return bool
     */
    public function isRequired();

    /**
     * Returns true when the node has a default value.
     *
     * @return bool
     */
    public function hasDefaultValue();

    /**
     * Returns the default value of the node.
     *
     * @return mixed
     *
     * @throws \RuntimeException if the node has no default value
     */
    public function getDefaultValue();

    /**
     * Normalizes a value.
     *
     * @param mixed $value The value to normalize
     *
     * @return mixed
     *
     * @throws InvalidTypeException if the value type is invalid
     */
    public function normalize($value);

    /**
     * Merges two values together.
     *
     * @param mixed $leftSide
     * @param mixed $rightSide
     *
     * @return mixed
     *
     * @throws ForbiddenOverwriteException if the configuration path cannot be overwritten
     * @throws InvalidTypeException        if the value type is invalid
     */
    public function merge($leftSide, $rightSide);

    /**
     * Finalizes a value.
     *
     * @param mixed $value The value to finalize
     *
     * @return mixed
     *
     * @throws InvalidTypeException          if the value type is invalid
     * @throws InvalidConfigurationException if the value is invalid configuration
     */
    public function finalize($value);
}
PKϤ$Z����config/Definition/FloatNode.phpnu�[���<?php

/*
 * This file is part of the Symfony package.
 *
 * (c) Fabien Potencier <fabien@symfony.com>
 *
 * For the full copyright and license information, please view the LICENSE
 * file that was distributed with this source code.
 */

namespace Symfony\Component\Config\Definition;

use Symfony\Component\Config\Definition\Exception\InvalidTypeException;

/**
 * This node represents a float value in the config tree.
 *
 * @author Jeanmonod David <david.jeanmonod@gmail.com>
 */
class FloatNode extends NumericNode
{
    /**
     * {@inheritdoc}
     */
    protected function validateType($value)
    {
        // Integers are also accepted, we just cast them
        if (\is_int($value)) {
            $value = (float) $value;
        }

        if (!\is_float($value)) {
            $ex = new InvalidTypeException(sprintf('Invalid type for path "%s". Expected "float", but got "%s".', $this->getPath(), get_debug_type($value)));
            if ($hint = $this->getInfo()) {
                $ex->addHint($hint);
            }
            $ex->setPath($this->getPath());

            throw $ex;
        }
    }

    /**
     * {@inheritdoc}
     */
    protected function getValidPlaceholderTypes(): array
    {
        return ['float'];
    }
}
PKϤ$Z�� t.t.config/Definition/ArrayNode.phpnu�[���<?php

/*
 * This file is part of the Symfony package.
 *
 * (c) Fabien Potencier <fabien@symfony.com>
 *
 * For the full copyright and license information, please view the LICENSE
 * file that was distributed with this source code.
 */

namespace Symfony\Component\Config\Definition;

use Symfony\Component\Config\Definition\Exception\InvalidConfigurationException;
use Symfony\Component\Config\Definition\Exception\InvalidTypeException;
use Symfony\Component\Config\Definition\Exception\UnsetKeyException;

/**
 * Represents an Array node in the config tree.
 *
 * @author Johannes M. Schmitt <schmittjoh@gmail.com>
 */
class ArrayNode extends BaseNode implements PrototypeNodeInterface
{
    protected $xmlRemappings = [];
    protected $children = [];
    protected $allowFalse = false;
    protected $allowNewKeys = true;
    protected $addIfNotSet = false;
    protected $performDeepMerging = true;
    protected $ignoreExtraKeys = false;
    protected $removeExtraKeys = true;
    protected $normalizeKeys = true;

    public function setNormalizeKeys(bool $normalizeKeys)
    {
        $this->normalizeKeys = $normalizeKeys;
    }

    /**
     * {@inheritdoc}
     *
     * Namely, you mostly have foo_bar in YAML while you have foo-bar in XML.
     * After running this method, all keys are normalized to foo_bar.
     *
     * If you have a mixed key like foo-bar_moo, it will not be altered.
     * The key will also not be altered if the target key already exists.
     */
    protected function preNormalize($value)
    {
        if (!$this->normalizeKeys || !\is_array($value)) {
            return $value;
        }

        $normalized = [];

        foreach ($value as $k => $v) {
            if (str_contains($k, '-') && !str_contains($k, '_') && !\array_key_exists($normalizedKey = str_replace('-', '_', $k), $value)) {
                $normalized[$normalizedKey] = $v;
            } else {
                $normalized[$k] = $v;
            }
        }

        return $normalized;
    }

    /**
     * Retrieves the children of this node.
     *
     * @return array<string, NodeInterface>
     */
    public function getChildren()
    {
        return $this->children;
    }

    /**
     * Sets the xml remappings that should be performed.
     *
     * @param array $remappings An array of the form [[string, string]]
     */
    public function setXmlRemappings(array $remappings)
    {
        $this->xmlRemappings = $remappings;
    }

    /**
     * Gets the xml remappings that should be performed.
     *
     * @return array an array of the form [[string, string]]
     */
    public function getXmlRemappings()
    {
        return $this->xmlRemappings;
    }

    /**
     * Sets whether to add default values for this array if it has not been
     * defined in any of the configuration files.
     */
    public function setAddIfNotSet(bool $boolean)
    {
        $this->addIfNotSet = $boolean;
    }

    /**
     * Sets whether false is allowed as value indicating that the array should be unset.
     */
    public function setAllowFalse(bool $allow)
    {
        $this->allowFalse = $allow;
    }

    /**
     * Sets whether new keys can be defined in subsequent configurations.
     */
    public function setAllowNewKeys(bool $allow)
    {
        $this->allowNewKeys = $allow;
    }

    /**
     * Sets if deep merging should occur.
     */
    public function setPerformDeepMerging(bool $boolean)
    {
        $this->performDeepMerging = $boolean;
    }

    /**
     * Whether extra keys should just be ignored without an exception.
     *
     * @param bool $boolean To allow extra keys
     * @param bool $remove  To remove extra keys
     */
    public function setIgnoreExtraKeys(bool $boolean, bool $remove = true)
    {
        $this->ignoreExtraKeys = $boolean;
        $this->removeExtraKeys = $this->ignoreExtraKeys && $remove;
    }

    /**
     * Returns true when extra keys should be ignored without an exception.
     */
    public function shouldIgnoreExtraKeys(): bool
    {
        return $this->ignoreExtraKeys;
    }

    /**
     * {@inheritdoc}
     */
    public function setName(string $name)
    {
        $this->name = $name;
    }

    /**
     * {@inheritdoc}
     */
    public function hasDefaultValue()
    {
        return $this->addIfNotSet;
    }

    /**
     * {@inheritdoc}
     */
    public function getDefaultValue()
    {
        if (!$this->hasDefaultValue()) {
            throw new \RuntimeException(sprintf('The node at path "%s" has no default value.', $this->getPath()));
        }

        $defaults = [];
        foreach ($this->children as $name => $child) {
            if ($child->hasDefaultValue()) {
                $defaults[$name] = $child->getDefaultValue();
            }
        }

        return $defaults;
    }

    /**
     * Adds a child node.
     *
     * @throws \InvalidArgumentException when the child node has no name
     * @throws \InvalidArgumentException when the child node's name is not unique
     */
    public function addChild(NodeInterface $node)
    {
        $name = $node->getName();
        if ('' === $name) {
            throw new \InvalidArgumentException('Child nodes must be named.');
        }
        if (isset($this->children[$name])) {
            throw new \InvalidArgumentException(sprintf('A child node named "%s" already exists.', $name));
        }

        $this->children[$name] = $node;
    }

    /**
     * {@inheritdoc}
     *
     * @throws UnsetKeyException
     * @throws InvalidConfigurationException if the node doesn't have enough children
     */
    protected function finalizeValue($value)
    {
        if (false === $value) {
            throw new UnsetKeyException(sprintf('Unsetting key for path "%s", value: %s.', $this->getPath(), json_encode($value)));
        }

        foreach ($this->children as $name => $child) {
            if (!\array_key_exists($name, $value)) {
                if ($child->isRequired()) {
                    $message = sprintf('The child config "%s" under "%s" must be configured', $name, $this->getPath());
                    if ($child->getInfo()) {
                        $message .= sprintf(': %s', $child->getInfo());
                    } else {
                        $message .= '.';
                    }
                    $ex = new InvalidConfigurationException($message);
                    $ex->setPath($this->getPath());

                    throw $ex;
                }

                if ($child->hasDefaultValue()) {
                    $value[$name] = $child->getDefaultValue();
                }

                continue;
            }

            if ($child->isDeprecated()) {
                $deprecation = $child->getDeprecation($name, $this->getPath());
                trigger_deprecation($deprecation['package'], $deprecation['version'], $deprecation['message']);
            }

            try {
                $value[$name] = $child->finalize($value[$name]);
            } catch (UnsetKeyException $e) {
                unset($value[$name]);
            }
        }

        return $value;
    }

    /**
     * {@inheritdoc}
     */
    protected function validateType($value)
    {
        if (!\is_array($value) && (!$this->allowFalse || false !== $value)) {
            $ex = new InvalidTypeException(sprintf('Invalid type for path "%s". Expected "array", but got "%s"', $this->getPath(), get_debug_type($value)));
            if ($hint = $this->getInfo()) {
                $ex->addHint($hint);
            }
            $ex->setPath($this->getPath());

            throw $ex;
        }
    }

    /**
     * {@inheritdoc}
     *
     * @throws InvalidConfigurationException
     */
    protected function normalizeValue($value)
    {
        if (false === $value) {
            return $value;
        }

        $value = $this->remapXml($value);

        $normalized = [];
        foreach ($value as $name => $val) {
            if (isset($this->children[$name])) {
                try {
                    $normalized[$name] = $this->children[$name]->normalize($val);
                } catch (UnsetKeyException $e) {
                }
                unset($value[$name]);
            } elseif (!$this->removeExtraKeys) {
                $normalized[$name] = $val;
            }
        }

        // if extra fields are present, throw exception
        if (\count($value) && !$this->ignoreExtraKeys) {
            $proposals = array_keys($this->children);
            sort($proposals);
            $guesses = [];

            foreach (array_keys($value) as $subject) {
                $minScore = \INF;
                foreach ($proposals as $proposal) {
                    $distance = levenshtein($subject, $proposal);
                    if ($distance <= $minScore && $distance < 3) {
                        $guesses[$proposal] = $distance;
                        $minScore = $distance;
                    }
                }
            }

            $msg = sprintf('Unrecognized option%s "%s" under "%s"', 1 === \count($value) ? '' : 's', implode(', ', array_keys($value)), $this->getPath());

            if (\count($guesses)) {
                asort($guesses);
                $msg .= sprintf('. Did you mean "%s"?', implode('", "', array_keys($guesses)));
            } else {
                $msg .= sprintf('. Available option%s %s "%s".', 1 === \count($proposals) ? '' : 's', 1 === \count($proposals) ? 'is' : 'are', implode('", "', $proposals));
            }

            $ex = new InvalidConfigurationException($msg);
            $ex->setPath($this->getPath());

            throw $ex;
        }

        return $normalized;
    }

    /**
     * Remaps multiple singular values to a single plural value.
     *
     * @return array
     */
    protected function remapXml(array $value)
    {
        foreach ($this->xmlRemappings as [$singular, $plural]) {
            if (!isset($value[$singular])) {
                continue;
            }

            $value[$plural] = Processor::normalizeConfig($value, $singular, $plural);
            unset($value[$singular]);
        }

        return $value;
    }

    /**
     * {@inheritdoc}
     *
     * @throws InvalidConfigurationException
     * @throws \RuntimeException
     */
    protected function mergeValues($leftSide, $rightSide)
    {
        if (false === $rightSide) {
            // if this is still false after the last config has been merged the
            // finalization pass will take care of removing this key entirely
            return false;
        }

        if (false === $leftSide || !$this->performDeepMerging) {
            return $rightSide;
        }

        foreach ($rightSide as $k => $v) {
            // no conflict
            if (!\array_key_exists($k, $leftSide)) {
                if (!$this->allowNewKeys) {
                    $ex = new InvalidConfigurationException(sprintf('You are not allowed to define new elements for path "%s". Please define all elements for this path in one config file. If you are trying to overwrite an element, make sure you redefine it with the same name.', $this->getPath()));
                    $ex->setPath($this->getPath());

                    throw $ex;
                }

                $leftSide[$k] = $v;
                continue;
            }

            if (!isset($this->children[$k])) {
                if (!$this->ignoreExtraKeys || $this->removeExtraKeys) {
                    throw new \RuntimeException('merge() expects a normalized config array.');
                }

                $leftSide[$k] = $v;
                continue;
            }

            $leftSide[$k] = $this->children[$k]->merge($leftSide[$k], $v);
        }

        return $leftSide;
    }

    /**
     * {@inheritdoc}
     */
    protected function allowPlaceholders(): bool
    {
        return false;
    }
}
PKϤ$Z��7�

config/Definition/Processor.phpnu�[���<?php

/*
 * This file is part of the Symfony package.
 *
 * (c) Fabien Potencier <fabien@symfony.com>
 *
 * For the full copyright and license information, please view the LICENSE
 * file that was distributed with this source code.
 */

namespace Symfony\Component\Config\Definition;

/**
 * This class is the entry point for config normalization/merging/finalization.
 *
 * @author Johannes M. Schmitt <schmittjoh@gmail.com>
 *
 * @final
 */
class Processor
{
    /**
     * Processes an array of configurations.
     *
     * @param array $configs An array of configuration items to process
     */
    public function process(NodeInterface $configTree, array $configs): array
    {
        $currentConfig = [];
        foreach ($configs as $config) {
            $config = $configTree->normalize($config);
            $currentConfig = $configTree->merge($currentConfig, $config);
        }

        return $configTree->finalize($currentConfig);
    }

    /**
     * Processes an array of configurations.
     *
     * @param array $configs An array of configuration items to process
     */
    public function processConfiguration(ConfigurationInterface $configuration, array $configs): array
    {
        return $this->process($configuration->getConfigTreeBuilder()->buildTree(), $configs);
    }

    /**
     * Normalizes a configuration entry.
     *
     * This method returns a normalize configuration array for a given key
     * to remove the differences due to the original format (YAML and XML mainly).
     *
     * Here is an example.
     *
     * The configuration in XML:
     *
     * <twig:extension>twig.extension.foo</twig:extension>
     * <twig:extension>twig.extension.bar</twig:extension>
     *
     * And the same configuration in YAML:
     *
     * extensions: ['twig.extension.foo', 'twig.extension.bar']
     *
     * @param array  $config A config array
     * @param string $key    The key to normalize
     * @param string $plural The plural form of the key if it is irregular
     */
    public static function normalizeConfig(array $config, string $key, string $plural = null): array
    {
        if (null === $plural) {
            $plural = $key.'s';
        }

        if (isset($config[$plural])) {
            return $config[$plural];
        }

        if (isset($config[$key])) {
            if (\is_string($config[$key]) || !\is_int(key($config[$key]))) {
                // only one
                return [$config[$key]];
            }

            return $config[$key];
        }

        return [];
    }
}
PKϤ$Z�p��>>=config/Definition/Exception/InvalidConfigurationException.phpnu�[���<?php

/*
 * This file is part of the Symfony package.
 *
 * (c) Fabien Potencier <fabien@symfony.com>
 *
 * For the full copyright and license information, please view the LICENSE
 * file that was distributed with this source code.
 */

namespace Symfony\Component\Config\Definition\Exception;

/**
 * A very general exception which can be thrown whenever non of the more specific
 * exceptions is suitable.
 *
 * @author Johannes M. Schmitt <schmittjoh@gmail.com>
 */
class InvalidConfigurationException extends Exception
{
    private $path;
    private $containsHints = false;

    public function setPath(string $path)
    {
        $this->path = $path;
    }

    public function getPath()
    {
        return $this->path;
    }

    /**
     * Adds extra information that is suffixed to the original exception message.
     */
    public function addHint(string $hint)
    {
        if (!$this->containsHints) {
            $this->message .= "\nHint: ".$hint;
            $this->containsHints = true;
        } else {
            $this->message .= ', '.$hint;
        }
    }
}
PKϤ$Z�po:��)config/Definition/Exception/Exception.phpnu�[���<?php

/*
 * This file is part of the Symfony package.
 *
 * (c) Fabien Potencier <fabien@symfony.com>
 *
 * For the full copyright and license information, please view the LICENSE
 * file that was distributed with this source code.
 */

namespace Symfony\Component\Config\Definition\Exception;

/**
 * Base exception for all configuration exceptions.
 *
 * @author Johannes M. Schmitt <schmittjoh@gmail.com>
 */
class Exception extends \RuntimeException
{
}
PKϤ$Z]F4���:config/Definition/Exception/InvalidDefinitionException.phpnu�[���<?php

/*
 * This file is part of the Symfony package.
 *
 * (c) Fabien Potencier <fabien@symfony.com>
 *
 * For the full copyright and license information, please view the LICENSE
 * file that was distributed with this source code.
 */

namespace Symfony\Component\Config\Definition\Exception;

/**
 * Thrown when an error is detected in a node Definition.
 *
 * @author Victor Berchet <victor.berchet@suumit.com>
 */
class InvalidDefinitionException extends Exception
{
}
PKϤ$Z��@��4config/Definition/Exception/InvalidTypeException.phpnu�[���<?php

/*
 * This file is part of the Symfony package.
 *
 * (c) Fabien Potencier <fabien@symfony.com>
 *
 * For the full copyright and license information, please view the LICENSE
 * file that was distributed with this source code.
 */

namespace Symfony\Component\Config\Definition\Exception;

/**
 * This exception is thrown if an invalid type is encountered.
 *
 * @author Johannes M. Schmitt <schmittjoh@gmail.com>
 */
class InvalidTypeException extends InvalidConfigurationException
{
}
PKϤ$Z�|�EE5config/Definition/Exception/DuplicateKeyException.phpnu�[���<?php

/*
 * This file is part of the Symfony package.
 *
 * (c) Fabien Potencier <fabien@symfony.com>
 *
 * For the full copyright and license information, please view the LICENSE
 * file that was distributed with this source code.
 */

namespace Symfony\Component\Config\Definition\Exception;

/**
 * This exception is thrown whenever the key of an array is not unique. This can
 * only be the case if the configuration is coming from an XML file.
 *
 * @author Johannes M. Schmitt <schmittjoh@gmail.com>
 */
class DuplicateKeyException extends InvalidConfigurationException
{
}
PKϤ$Z�:2&QQ;config/Definition/Exception/ForbiddenOverwriteException.phpnu�[���<?php

/*
 * This file is part of the Symfony package.
 *
 * (c) Fabien Potencier <fabien@symfony.com>
 *
 * For the full copyright and license information, please view the LICENSE
 * file that was distributed with this source code.
 */

namespace Symfony\Component\Config\Definition\Exception;

/**
 * This exception is thrown when a configuration path is overwritten from a
 * subsequent configuration file, but the entry node specifically forbids this.
 *
 * @author Johannes M. Schmitt <schmittjoh@gmail.com>
 */
class ForbiddenOverwriteException extends InvalidConfigurationException
{
}
PKϤ$Z����1config/Definition/Exception/UnsetKeyException.phpnu�[���<?php

/*
 * This file is part of the Symfony package.
 *
 * (c) Fabien Potencier <fabien@symfony.com>
 *
 * For the full copyright and license information, please view the LICENSE
 * file that was distributed with this source code.
 */

namespace Symfony\Component\Config\Definition\Exception;

/**
 * This exception is usually not encountered by the end-user, but only used
 * internally to signal the parent scope to unset a key.
 *
 * @author Johannes M. Schmitt <schmittjoh@gmail.com>
 */
class UnsetKeyException extends Exception
{
}
PKϤ$Z��M�GG,config/Definition/PrototypeNodeInterface.phpnu�[���<?php

/*
 * This file is part of the Symfony package.
 *
 * (c) Fabien Potencier <fabien@symfony.com>
 *
 * For the full copyright and license information, please view the LICENSE
 * file that was distributed with this source code.
 */

namespace Symfony\Component\Config\Definition;

/**
 * This interface must be implemented by nodes which can be used as prototypes.
 *
 * @author Johannes M. Schmitt <schmittjoh@gmail.com>
 */
interface PrototypeNodeInterface extends NodeInterface
{
    /**
     * Sets the name of the node.
     */
    public function setName(string $name);
}
PKϤ$Z;	�YY!config/Definition/IntegerNode.phpnu�[���<?php

/*
 * This file is part of the Symfony package.
 *
 * (c) Fabien Potencier <fabien@symfony.com>
 *
 * For the full copyright and license information, please view the LICENSE
 * file that was distributed with this source code.
 */

namespace Symfony\Component\Config\Definition;

use Symfony\Component\Config\Definition\Exception\InvalidTypeException;

/**
 * This node represents an integer value in the config tree.
 *
 * @author Jeanmonod David <david.jeanmonod@gmail.com>
 */
class IntegerNode extends NumericNode
{
    /**
     * {@inheritdoc}
     */
    protected function validateType($value)
    {
        if (!\is_int($value)) {
            $ex = new InvalidTypeException(sprintf('Invalid type for path "%s". Expected "int", but got "%s".', $this->getPath(), get_debug_type($value)));
            if ($hint = $this->getInfo()) {
                $ex->addHint($hint);
            }
            $ex->setPath($this->getPath());

            throw $ex;
        }
    }

    /**
     * {@inheritdoc}
     */
    protected function getValidPlaceholderTypes(): array
    {
        return ['int'];
    }
}
PKϤ$Z���ww!config/Loader/LoaderInterface.phpnu�[���<?php

/*
 * This file is part of the Symfony package.
 *
 * (c) Fabien Potencier <fabien@symfony.com>
 *
 * For the full copyright and license information, please view the LICENSE
 * file that was distributed with this source code.
 */

namespace Symfony\Component\Config\Loader;

/**
 * LoaderInterface is the interface implemented by all loader classes.
 *
 * @author Fabien Potencier <fabien@symfony.com>
 */
interface LoaderInterface
{
    /**
     * Loads a resource.
     *
     * @param mixed $resource The resource
     *
     * @return mixed
     *
     * @throws \Exception If something went wrong
     */
    public function load($resource, string $type = null);

    /**
     * Returns whether this class supports the given resource.
     *
     * @param mixed $resource A resource
     *
     * @return bool
     */
    public function supports($resource, string $type = null);

    /**
     * Gets the loader resolver.
     *
     * @return LoaderResolverInterface
     */
    public function getResolver();

    /**
     * Sets the loader resolver.
     */
    public function setResolver(LoaderResolverInterface $resolver);
}
PKϤ$Z{>�c"config/Loader/DelegatingLoader.phpnu�[���<?php

/*
 * This file is part of the Symfony package.
 *
 * (c) Fabien Potencier <fabien@symfony.com>
 *
 * For the full copyright and license information, please view the LICENSE
 * file that was distributed with this source code.
 */

namespace Symfony\Component\Config\Loader;

use Symfony\Component\Config\Exception\LoaderLoadException;

/**
 * DelegatingLoader delegates loading to other loaders using a loader resolver.
 *
 * This loader acts as an array of LoaderInterface objects - each having
 * a chance to load a given resource (handled by the resolver)
 *
 * @author Fabien Potencier <fabien@symfony.com>
 */
class DelegatingLoader extends Loader
{
    public function __construct(LoaderResolverInterface $resolver)
    {
        $this->resolver = $resolver;
    }

    /**
     * {@inheritdoc}
     */
    public function load($resource, string $type = null)
    {
        if (false === $loader = $this->resolver->resolve($resource, $type)) {
            throw new LoaderLoadException($resource, null, 0, null, $type);
        }

        return $loader->load($resource, $type);
    }

    /**
     * {@inheritdoc}
     */
    public function supports($resource, string $type = null)
    {
        return false !== $this->resolver->resolve($resource, $type);
    }
}
PKϤ$Z1�.��)config/Loader/LoaderResolverInterface.phpnu�[���<?php

/*
 * This file is part of the Symfony package.
 *
 * (c) Fabien Potencier <fabien@symfony.com>
 *
 * For the full copyright and license information, please view the LICENSE
 * file that was distributed with this source code.
 */

namespace Symfony\Component\Config\Loader;

/**
 * LoaderResolverInterface selects a loader for a given resource.
 *
 * @author Fabien Potencier <fabien@symfony.com>
 */
interface LoaderResolverInterface
{
    /**
     * Returns a loader able to load the resource.
     *
     * @param mixed       $resource A resource
     * @param string|null $type     The resource type or null if unknown
     *
     * @return LoaderInterface|false
     */
    public function resolve($resource, string $type = null);
}
PKϤ$Z�'�� config/Loader/LoaderResolver.phpnu�[���<?php

/*
 * This file is part of the Symfony package.
 *
 * (c) Fabien Potencier <fabien@symfony.com>
 *
 * For the full copyright and license information, please view the LICENSE
 * file that was distributed with this source code.
 */

namespace Symfony\Component\Config\Loader;

/**
 * LoaderResolver selects a loader for a given resource.
 *
 * A resource can be anything (e.g. a full path to a config file or a Closure).
 * Each loader determines whether it can load a resource and how.
 *
 * @author Fabien Potencier <fabien@symfony.com>
 */
class LoaderResolver implements LoaderResolverInterface
{
    /**
     * @var LoaderInterface[] An array of LoaderInterface objects
     */
    private $loaders = [];

    /**
     * @param LoaderInterface[] $loaders An array of loaders
     */
    public function __construct(array $loaders = [])
    {
        foreach ($loaders as $loader) {
            $this->addLoader($loader);
        }
    }

    /**
     * {@inheritdoc}
     */
    public function resolve($resource, string $type = null)
    {
        foreach ($this->loaders as $loader) {
            if ($loader->supports($resource, $type)) {
                return $loader;
            }
        }

        return false;
    }

    public function addLoader(LoaderInterface $loader)
    {
        $this->loaders[] = $loader;
        $loader->setResolver($this);
    }

    /**
     * Returns the registered loaders.
     *
     * @return LoaderInterface[]
     */
    public function getLoaders()
    {
        return $this->loaders;
    }
}
PKϤ$Z�@9b�� config/Loader/GlobFileLoader.phpnu�[���<?php

/*
 * This file is part of the Symfony package.
 *
 * (c) Fabien Potencier <fabien@symfony.com>
 *
 * For the full copyright and license information, please view the LICENSE
 * file that was distributed with this source code.
 */

namespace Symfony\Component\Config\Loader;

/**
 * GlobFileLoader loads files from a glob pattern.
 *
 * @author Fabien Potencier <fabien@symfony.com>
 */
class GlobFileLoader extends FileLoader
{
    /**
     * {@inheritdoc}
     */
    public function load($resource, string $type = null)
    {
        return $this->import($resource);
    }

    /**
     * {@inheritdoc}
     */
    public function supports($resource, string $type = null)
    {
        return 'glob' === $type;
    }
}
PKϤ$ZK_�%%config/Loader/FileLoader.phpnu�[���<?php

/*
 * This file is part of the Symfony package.
 *
 * (c) Fabien Potencier <fabien@symfony.com>
 *
 * For the full copyright and license information, please view the LICENSE
 * file that was distributed with this source code.
 */

namespace Symfony\Component\Config\Loader;

use Symfony\Component\Config\Exception\FileLoaderImportCircularReferenceException;
use Symfony\Component\Config\Exception\FileLocatorFileNotFoundException;
use Symfony\Component\Config\Exception\LoaderLoadException;
use Symfony\Component\Config\FileLocatorInterface;
use Symfony\Component\Config\Resource\FileExistenceResource;
use Symfony\Component\Config\Resource\GlobResource;

/**
 * FileLoader is the abstract class used by all built-in loaders that are file based.
 *
 * @author Fabien Potencier <fabien@symfony.com>
 */
abstract class FileLoader extends Loader
{
    protected static $loading = [];

    protected $locator;

    private $currentDir;

    public function __construct(FileLocatorInterface $locator, string $env = null)
    {
        $this->locator = $locator;
        parent::__construct($env);
    }

    /**
     * Sets the current directory.
     */
    public function setCurrentDir(string $dir)
    {
        $this->currentDir = $dir;
    }

    /**
     * Returns the file locator used by this loader.
     *
     * @return FileLocatorInterface
     */
    public function getLocator()
    {
        return $this->locator;
    }

    /**
     * Imports a resource.
     *
     * @param mixed                $resource       A Resource
     * @param string|null          $type           The resource type or null if unknown
     * @param bool                 $ignoreErrors   Whether to ignore import errors or not
     * @param string|null          $sourceResource The original resource importing the new resource
     * @param string|string[]|null $exclude        Glob patterns to exclude from the import
     *
     * @return mixed
     *
     * @throws LoaderLoadException
     * @throws FileLoaderImportCircularReferenceException
     * @throws FileLocatorFileNotFoundException
     */
    public function import($resource, string $type = null, bool $ignoreErrors = false, string $sourceResource = null, $exclude = null)
    {
        if (\is_string($resource) && \strlen($resource) !== ($i = strcspn($resource, '*?{[')) && !str_contains($resource, "\n")) {
            $excluded = [];
            foreach ((array) $exclude as $pattern) {
                foreach ($this->glob($pattern, true, $_, false, true) as $path => $info) {
                    // normalize Windows slashes and remove trailing slashes
                    $excluded[rtrim(str_replace('\\', '/', $path), '/')] = true;
                }
            }

            $ret = [];
            $isSubpath = 0 !== $i && str_contains(substr($resource, 0, $i), '/');
            foreach ($this->glob($resource, false, $_, $ignoreErrors || !$isSubpath, false, $excluded) as $path => $info) {
                if (null !== $res = $this->doImport($path, 'glob' === $type ? null : $type, $ignoreErrors, $sourceResource)) {
                    $ret[] = $res;
                }
                $isSubpath = true;
            }

            if ($isSubpath) {
                return isset($ret[1]) ? $ret : ($ret[0] ?? null);
            }
        }

        return $this->doImport($resource, $type, $ignoreErrors, $sourceResource);
    }

    /**
     * @internal
     */
    protected function glob(string $pattern, bool $recursive, &$resource = null, bool $ignoreErrors = false, bool $forExclusion = false, array $excluded = [])
    {
        if (\strlen($pattern) === $i = strcspn($pattern, '*?{[')) {
            $prefix = $pattern;
            $pattern = '';
        } elseif (0 === $i || !str_contains(substr($pattern, 0, $i), '/')) {
            $prefix = '.';
            $pattern = '/'.$pattern;
        } else {
            $prefix = \dirname(substr($pattern, 0, 1 + $i));
            $pattern = substr($pattern, \strlen($prefix));
        }

        try {
            $prefix = $this->locator->locate($prefix, $this->currentDir, true);
        } catch (FileLocatorFileNotFoundException $e) {
            if (!$ignoreErrors) {
                throw $e;
            }

            $resource = [];
            foreach ($e->getPaths() as $path) {
                $resource[] = new FileExistenceResource($path);
            }

            return;
        }
        $resource = new GlobResource($prefix, $pattern, $recursive, $forExclusion, $excluded);

        yield from $resource;
    }

    private function doImport($resource, string $type = null, bool $ignoreErrors = false, string $sourceResource = null)
    {
        try {
            $loader = $this->resolve($resource, $type);

            if ($loader instanceof self && null !== $this->currentDir) {
                $resource = $loader->getLocator()->locate($resource, $this->currentDir, false);
            }

            $resources = \is_array($resource) ? $resource : [$resource];
            for ($i = 0; $i < $resourcesCount = \count($resources); ++$i) {
                if (isset(self::$loading[$resources[$i]])) {
                    if ($i == $resourcesCount - 1) {
                        throw new FileLoaderImportCircularReferenceException(array_keys(self::$loading));
                    }
                } else {
                    $resource = $resources[$i];
                    break;
                }
            }
            self::$loading[$resource] = true;

            try {
                $ret = $loader->load($resource, $type);
            } finally {
                unset(self::$loading[$resource]);
            }

            return $ret;
        } catch (FileLoaderImportCircularReferenceException $e) {
            throw $e;
        } catch (\Exception $e) {
            if (!$ignoreErrors) {
                // prevent embedded imports from nesting multiple exceptions
                if ($e instanceof LoaderLoadException) {
                    throw $e;
                }

                throw new LoaderLoadException($resource, $sourceResource, 0, $e, $type);
            }
        }

        return null;
    }
}
PKϤ$Z-�c��config/Loader/Loader.phpnu�[���<?php

/*
 * This file is part of the Symfony package.
 *
 * (c) Fabien Potencier <fabien@symfony.com>
 *
 * For the full copyright and license information, please view the LICENSE
 * file that was distributed with this source code.
 */

namespace Symfony\Component\Config\Loader;

use Symfony\Component\Config\Exception\LoaderLoadException;

/**
 * Loader is the abstract class used by all built-in loaders.
 *
 * @author Fabien Potencier <fabien@symfony.com>
 */
abstract class Loader implements LoaderInterface
{
    protected $resolver;
    protected $env;

    public function __construct(string $env = null)
    {
        $this->env = $env;
    }

    /**
     * {@inheritdoc}
     */
    public function getResolver()
    {
        return $this->resolver;
    }

    /**
     * {@inheritdoc}
     */
    public function setResolver(LoaderResolverInterface $resolver)
    {
        $this->resolver = $resolver;
    }

    /**
     * Imports a resource.
     *
     * @param mixed       $resource A resource
     * @param string|null $type     The resource type or null if unknown
     *
     * @return mixed
     */
    public function import($resource, string $type = null)
    {
        return $this->resolve($resource, $type)->load($resource, $type);
    }

    /**
     * Finds a loader able to load an imported resource.
     *
     * @param mixed       $resource A resource
     * @param string|null $type     The resource type or null if unknown
     *
     * @return LoaderInterface
     *
     * @throws LoaderLoadException If no loader is found
     */
    public function resolve($resource, string $type = null)
    {
        if ($this->supports($resource, $type)) {
            return $this;
        }

        $loader = null === $this->resolver ? false : $this->resolver->resolve($resource, $type);

        if (false === $loader) {
            throw new LoaderLoadException($resource, null, 0, null, $type);
        }

        return $loader;
    }
}
PKϤ$Z�h�YY#config/Loader/ParamConfigurator.phpnu�[���<?php

/*
 * This file is part of the Symfony package.
 *
 * (c) Fabien Potencier <fabien@symfony.com>
 *
 * For the full copyright and license information, please view the LICENSE
 * file that was distributed with this source code.
 */

namespace Symfony\Component\Config\Loader;

/**
 * Placeholder for a parameter.
 *
 * @author Tobias Nyholm <tobias.nyholm@gmail.com>
 */
class ParamConfigurator
{
    private $name;

    public function __construct(string $name)
    {
        $this->name = $name;
    }

    public function __toString(): string
    {
        return '%'.$this->name.'%';
    }
}
PKϤ$Z�$c��)config/Builder/ConfigBuilderInterface.phpnu�[���<?php

/*
 * This file is part of the Symfony package.
 *
 * (c) Fabien Potencier <fabien@symfony.com>
 *
 * For the full copyright and license information, please view the LICENSE
 * file that was distributed with this source code.
 */

namespace Symfony\Component\Config\Builder;

/**
 * A ConfigBuilder provides helper methods to build a large complex array.
 *
 * @author Tobias Nyholm <tobias.nyholm@gmail.com>
 */
interface ConfigBuilderInterface
{
    /**
     * Gets all configuration represented as an array.
     */
    public function toArray(): array;

    /**
     * Gets the alias for the extension which config we are building.
     */
    public function getExtensionAlias(): string;
}
PKϤ$Z��Ƕttconfig/Builder/Method.phpnu�[���<?php

/*
 * This file is part of the Symfony package.
 *
 * (c) Fabien Potencier <fabien@symfony.com>
 *
 * For the full copyright and license information, please view the LICENSE
 * file that was distributed with this source code.
 */

namespace Symfony\Component\Config\Builder;

/**
 * Represents a method when building classes.
 *
 * @internal
 *
 * @author Tobias Nyholm <tobias.nyholm@gmail.com>
 */
class Method
{
    private $content;

    public function __construct(string $content)
    {
        $this->content = $content;
    }

    public function getContent(): string
    {
        return $this->content;
    }
}
PKϤ$Z�w�H�H)config/Builder/ConfigBuilderGenerator.phpnu�[���<?php

/*
 * This file is part of the Symfony package.
 *
 * (c) Fabien Potencier <fabien@symfony.com>
 *
 * For the full copyright and license information, please view the LICENSE
 * file that was distributed with this source code.
 */

namespace Symfony\Component\Config\Builder;

use Symfony\Component\Config\Definition\ArrayNode;
use Symfony\Component\Config\Definition\BooleanNode;
use Symfony\Component\Config\Definition\ConfigurationInterface;
use Symfony\Component\Config\Definition\EnumNode;
use Symfony\Component\Config\Definition\Exception\InvalidConfigurationException;
use Symfony\Component\Config\Definition\FloatNode;
use Symfony\Component\Config\Definition\IntegerNode;
use Symfony\Component\Config\Definition\NodeInterface;
use Symfony\Component\Config\Definition\PrototypedArrayNode;
use Symfony\Component\Config\Definition\ScalarNode;
use Symfony\Component\Config\Definition\VariableNode;
use Symfony\Component\Config\Loader\ParamConfigurator;

/**
 * Generate ConfigBuilders to help create valid config.
 *
 * @author Tobias Nyholm <tobias.nyholm@gmail.com>
 */
class ConfigBuilderGenerator implements ConfigBuilderGeneratorInterface
{
    /**
     * @var ClassBuilder[]
     */
    private $classes;
    private $outputDir;

    public function __construct(string $outputDir)
    {
        $this->outputDir = $outputDir;
    }

    /**
     * @return \Closure that will return the root config class
     */
    public function build(ConfigurationInterface $configuration): \Closure
    {
        $this->classes = [];

        $rootNode = $configuration->getConfigTreeBuilder()->buildTree();
        $rootClass = new ClassBuilder('Symfony\\Config', $rootNode->getName());

        $path = $this->getFullPath($rootClass);
        if (!is_file($path)) {
            // Generate the class if the file not exists
            $this->classes[] = $rootClass;
            $this->buildNode($rootNode, $rootClass, $this->getSubNamespace($rootClass));
            $rootClass->addImplements(ConfigBuilderInterface::class);
            $rootClass->addMethod('getExtensionAlias', '
public function NAME(): string
{
    return \'ALIAS\';
}', ['ALIAS' => $rootNode->getPath()]);

            $this->writeClasses();
        }

        $loader = \Closure::fromCallable(function () use ($path, $rootClass) {
            require_once $path;
            $className = $rootClass->getFqcn();

            return new $className();
        });

        return $loader;
    }

    private function getFullPath(ClassBuilder $class): string
    {
        $directory = $this->outputDir.\DIRECTORY_SEPARATOR.$class->getDirectory();
        if (!is_dir($directory)) {
            @mkdir($directory, 0777, true);
        }

        return $directory.\DIRECTORY_SEPARATOR.$class->getFilename();
    }

    private function writeClasses(): void
    {
        foreach ($this->classes as $class) {
            $this->buildConstructor($class);
            $this->buildToArray($class);
            if ($class->getProperties()) {
                $class->addProperty('_usedProperties', null, '[]');
            }
            $this->buildSetExtraKey($class);

            file_put_contents($this->getFullPath($class), $class->build());
        }

        $this->classes = [];
    }

    private function buildNode(NodeInterface $node, ClassBuilder $class, string $namespace): void
    {
        if (!$node instanceof ArrayNode) {
            throw new \LogicException('The node was expected to be an ArrayNode. This Configuration includes an edge case not supported yet.');
        }

        foreach ($node->getChildren() as $child) {
            switch (true) {
                case $child instanceof ScalarNode:
                    $this->handleScalarNode($child, $class);
                    break;
                case $child instanceof PrototypedArrayNode:
                    $this->handlePrototypedArrayNode($child, $class, $namespace);
                    break;
                case $child instanceof VariableNode:
                    $this->handleVariableNode($child, $class);
                    break;
                case $child instanceof ArrayNode:
                    $this->handleArrayNode($child, $class, $namespace);
                    break;
                default:
                    throw new \RuntimeException(sprintf('Unknown node "%s".', \get_class($child)));
            }
        }
    }

    private function handleArrayNode(ArrayNode $node, ClassBuilder $class, string $namespace): void
    {
        $childClass = new ClassBuilder($namespace, $node->getName());
        $childClass->setAllowExtraKeys($node->shouldIgnoreExtraKeys());
        $class->addRequire($childClass);
        $this->classes[] = $childClass;

        $hasNormalizationClosures = $this->hasNormalizationClosures($node);
        $property = $class->addProperty(
            $node->getName(),
            $this->getType($childClass->getFqcn(), $hasNormalizationClosures)
        );
        $body = $hasNormalizationClosures ? '
/**
 * @return CLASS|$this
 */
public function NAME($value = [])
{
    if (!\is_array($value)) {
        $this->_usedProperties[\'PROPERTY\'] = true;
        $this->PROPERTY = $value;

        return $this;
    }

    if (!$this->PROPERTY instanceof CLASS) {
        $this->_usedProperties[\'PROPERTY\'] = true;
        $this->PROPERTY = new CLASS($value);
    } elseif (0 < \func_num_args()) {
        throw new InvalidConfigurationException(\'The node created by "NAME()" has already been initialized. You cannot pass values the second time you call NAME().\');
    }

    return $this->PROPERTY;
}' : '
public function NAME(array $value = []): CLASS
{
    if (null === $this->PROPERTY) {
        $this->_usedProperties[\'PROPERTY\'] = true;
        $this->PROPERTY = new CLASS($value);
    } elseif (0 < \func_num_args()) {
        throw new InvalidConfigurationException(\'The node created by "NAME()" has already been initialized. You cannot pass values the second time you call NAME().\');
    }

    return $this->PROPERTY;
}';
        $class->addUse(InvalidConfigurationException::class);
        $class->addMethod($node->getName(), $body, ['PROPERTY' => $property->getName(), 'CLASS' => $childClass->getFqcn()]);

        $this->buildNode($node, $childClass, $this->getSubNamespace($childClass));
    }

    private function handleVariableNode(VariableNode $node, ClassBuilder $class): void
    {
        $comment = $this->getComment($node);
        $property = $class->addProperty($node->getName());
        $class->addUse(ParamConfigurator::class);

        $body = '
/**
COMMENT * @return $this
 */
public function NAME($valueDEFAULT): self
{
    $this->_usedProperties[\'PROPERTY\'] = true;
    $this->PROPERTY = $value;

    return $this;
}';
        $class->addMethod($node->getName(), $body, ['PROPERTY' => $property->getName(), 'COMMENT' => $comment, 'DEFAULT' => $node->hasDefaultValue() ? ' = '.var_export($node->getDefaultValue(), true) : '']);
    }

    private function handlePrototypedArrayNode(PrototypedArrayNode $node, ClassBuilder $class, string $namespace): void
    {
        $name = $this->getSingularName($node);
        $prototype = $node->getPrototype();
        $methodName = $name;

        $parameterType = $this->getParameterType($prototype);
        if (null !== $parameterType || $prototype instanceof ScalarNode) {
            $class->addUse(ParamConfigurator::class);
            $property = $class->addProperty($node->getName());
            if (null === $key = $node->getKeyAttribute()) {
                // This is an array of values; don't use singular name
                $body = '
/**
 * @param ParamConfigurator|list<TYPE|ParamConfigurator> $value
 * @return $this
 */
public function NAME($value): self
{
    $this->_usedProperties[\'PROPERTY\'] = true;
    $this->PROPERTY = $value;

    return $this;
}';

                $class->addMethod($node->getName(), $body, ['PROPERTY' => $property->getName(), 'TYPE' => '' === $parameterType ? 'mixed' : $parameterType]);
            } else {
                $body = '
/**
 * @param ParamConfigurator|TYPE $value
 * @return $this
 */
public function NAME(string $VAR, $VALUE): self
{
    $this->_usedProperties[\'PROPERTY\'] = true;
    $this->PROPERTY[$VAR] = $VALUE;

    return $this;
}';

                $class->addMethod($methodName, $body, ['PROPERTY' => $property->getName(), 'TYPE' => '' === $parameterType ? 'mixed' : $parameterType, 'VAR' => '' === $key ? 'key' : $key, 'VALUE' => 'value' === $key ? 'data' : 'value']);
            }

            return;
        }

        $childClass = new ClassBuilder($namespace, $name);
        if ($prototype instanceof ArrayNode) {
            $childClass->setAllowExtraKeys($prototype->shouldIgnoreExtraKeys());
        }
        $class->addRequire($childClass);
        $this->classes[] = $childClass;

        $hasNormalizationClosures = $this->hasNormalizationClosures($node) || $this->hasNormalizationClosures($prototype);
        $property = $class->addProperty(
            $node->getName(),
            $this->getType($childClass->getFqcn().'[]', $hasNormalizationClosures)
        );

        if (null === $key = $node->getKeyAttribute()) {
            $body = $hasNormalizationClosures ? '
/**
 * @return CLASS|$this
 */
public function NAME($value = [])
{
    $this->_usedProperties[\'PROPERTY\'] = true;
    if (!\is_array($value)) {
        $this->PROPERTY[] = $value;

        return $this;
    }

    return $this->PROPERTY[] = new CLASS($value);
}' : '
public function NAME(array $value = []): CLASS
{
    $this->_usedProperties[\'PROPERTY\'] = true;

    return $this->PROPERTY[] = new CLASS($value);
}';
            $class->addMethod($methodName, $body, ['PROPERTY' => $property->getName(), 'CLASS' => $childClass->getFqcn()]);
        } else {
            $body = $hasNormalizationClosures ? '
/**
 * @return CLASS|$this
 */
public function NAME(string $VAR, $VALUE = [])
{
    if (!\is_array($VALUE)) {
        $this->_usedProperties[\'PROPERTY\'] = true;
        $this->PROPERTY[$VAR] = $VALUE;

        return $this;
    }

    if (!isset($this->PROPERTY[$VAR]) || !$this->PROPERTY[$VAR] instanceof CLASS) {
        $this->_usedProperties[\'PROPERTY\'] = true;
        $this->PROPERTY[$VAR] = new CLASS($VALUE);
    } elseif (1 < \func_num_args()) {
        throw new InvalidConfigurationException(\'The node created by "NAME()" has already been initialized. You cannot pass values the second time you call NAME().\');
    }

    return $this->PROPERTY[$VAR];
}' : '
public function NAME(string $VAR, array $VALUE = []): CLASS
{
    if (!isset($this->PROPERTY[$VAR])) {
        $this->_usedProperties[\'PROPERTY\'] = true;
        $this->PROPERTY[$VAR] = new CLASS($VALUE);
    } elseif (1 < \func_num_args()) {
        throw new InvalidConfigurationException(\'The node created by "NAME()" has already been initialized. You cannot pass values the second time you call NAME().\');
    }

    return $this->PROPERTY[$VAR];
}';
            $class->addUse(InvalidConfigurationException::class);
            $class->addMethod($methodName, $body, ['PROPERTY' => $property->getName(), 'CLASS' => $childClass->getFqcn(), 'VAR' => '' === $key ? 'key' : $key, 'VALUE' => 'value' === $key ? 'data' : 'value']);
        }

        $this->buildNode($prototype, $childClass, $namespace.'\\'.$childClass->getName());
    }

    private function handleScalarNode(ScalarNode $node, ClassBuilder $class): void
    {
        $comment = $this->getComment($node);
        $property = $class->addProperty($node->getName());
        $class->addUse(ParamConfigurator::class);

        $body = '
/**
COMMENT * @return $this
 */
public function NAME($value): self
{
    $this->_usedProperties[\'PROPERTY\'] = true;
    $this->PROPERTY = $value;

    return $this;
}';

        $class->addMethod($node->getName(), $body, ['PROPERTY' => $property->getName(), 'COMMENT' => $comment]);
    }

    private function getParameterType(NodeInterface $node): ?string
    {
        if ($node instanceof BooleanNode) {
            return 'bool';
        }

        if ($node instanceof IntegerNode) {
            return 'int';
        }

        if ($node instanceof FloatNode) {
            return 'float';
        }

        if ($node instanceof EnumNode) {
            return '';
        }

        if ($node instanceof PrototypedArrayNode && $node->getPrototype() instanceof ScalarNode) {
            // This is just an array of variables
            return 'array';
        }

        if ($node instanceof VariableNode) {
            // mixed
            return '';
        }

        return null;
    }

    private function getComment(VariableNode $node): string
    {
        $comment = '';
        if ('' !== $info = (string) $node->getInfo()) {
            $comment .= ' * '.$info."\n";
        }

        foreach ((array) ($node->getExample() ?? []) as $example) {
            $comment .= ' * @example '.$example."\n";
        }

        if ('' !== $default = $node->getDefaultValue()) {
            $comment .= ' * @default '.(null === $default ? 'null' : var_export($default, true))."\n";
        }

        if ($node instanceof EnumNode) {
            $comment .= sprintf(' * @param ParamConfigurator|%s $value', implode('|', array_map(function ($a) {
                return var_export($a, true);
            }, $node->getValues())))."\n";
        } else {
            $parameterType = $this->getParameterType($node);
            if (null === $parameterType || '' === $parameterType) {
                $parameterType = 'mixed';
            }
            $comment .= ' * @param ParamConfigurator|'.$parameterType.' $value'."\n";
        }

        if ($node->isDeprecated()) {
            $comment .= ' * @deprecated '.$node->getDeprecation($node->getName(), $node->getParent()->getName())['message']."\n";
        }

        return $comment;
    }

    /**
     * Pick a good singular name.
     */
    private function getSingularName(PrototypedArrayNode $node): string
    {
        $name = $node->getName();
        if ('s' !== substr($name, -1)) {
            return $name;
        }

        $parent = $node->getParent();
        $mappings = $parent instanceof ArrayNode ? $parent->getXmlRemappings() : [];
        foreach ($mappings as $map) {
            if ($map[1] === $name) {
                $name = $map[0];
                break;
            }
        }

        return $name;
    }

    private function buildToArray(ClassBuilder $class): void
    {
        $body = '$output = [];';
        foreach ($class->getProperties() as $p) {
            $code = '$this->PROPERTY';
            if (null !== $p->getType()) {
                if ($p->isArray()) {
                    $code = $p->areScalarsAllowed()
                        ? 'array_map(function ($v) { return $v instanceof CLASS ? $v->toArray() : $v; }, $this->PROPERTY)'
                        : 'array_map(function ($v) { return $v->toArray(); }, $this->PROPERTY)'
                    ;
                } else {
                    $code = $p->areScalarsAllowed()
                        ? '$this->PROPERTY instanceof CLASS ? $this->PROPERTY->toArray() : $this->PROPERTY'
                        : '$this->PROPERTY->toArray()'
                    ;
                }
            }

            $body .= strtr('
    if (isset($this->_usedProperties[\'PROPERTY\'])) {
        $output[\'ORG_NAME\'] = '.$code.';
    }', ['PROPERTY' => $p->getName(), 'ORG_NAME' => $p->getOriginalName(), 'CLASS' => $p->getType()]);
        }

        $extraKeys = $class->shouldAllowExtraKeys() ? ' + $this->_extraKeys' : '';

        $class->addMethod('toArray', '
public function NAME(): array
{
    '.$body.'

    return $output'.$extraKeys.';
}');
    }

    private function buildConstructor(ClassBuilder $class): void
    {
        $body = '';
        foreach ($class->getProperties() as $p) {
            $code = '$value[\'ORG_NAME\']';
            if (null !== $p->getType()) {
                if ($p->isArray()) {
                    $code = $p->areScalarsAllowed()
                        ? 'array_map(function ($v) { return \is_array($v) ? new '.$p->getType().'($v) : $v; }, $value[\'ORG_NAME\'])'
                        : 'array_map(function ($v) { return new '.$p->getType().'($v); }, $value[\'ORG_NAME\'])'
                    ;
                } else {
                    $code = $p->areScalarsAllowed()
                        ? '\is_array($value[\'ORG_NAME\']) ? new '.$p->getType().'($value[\'ORG_NAME\']) : $value[\'ORG_NAME\']'
                        : 'new '.$p->getType().'($value[\'ORG_NAME\'])'
                    ;
                }
            }

            $body .= strtr('
    if (array_key_exists(\'ORG_NAME\', $value)) {
        $this->_usedProperties[\'PROPERTY\'] = true;
        $this->PROPERTY = '.$code.';
        unset($value[\'ORG_NAME\']);
    }
', ['PROPERTY' => $p->getName(), 'ORG_NAME' => $p->getOriginalName()]);
        }

        if ($class->shouldAllowExtraKeys()) {
            $body .= '
    $this->_extraKeys = $value;
';
        } else {
            $body .= '
    if ([] !== $value) {
        throw new InvalidConfigurationException(sprintf(\'The following keys are not supported by "%s": \', __CLASS__).implode(\', \', array_keys($value)));
    }';

            $class->addUse(InvalidConfigurationException::class);
        }

        $class->addMethod('__construct', '
public function __construct(array $value = [])
{'.$body.'
}');
    }

    private function buildSetExtraKey(ClassBuilder $class): void
    {
        if (!$class->shouldAllowExtraKeys()) {
            return;
        }

        $class->addUse(ParamConfigurator::class);

        $class->addProperty('_extraKeys');

        $class->addMethod('set', '
/**
 * @param ParamConfigurator|mixed $value
 * @return $this
 */
public function NAME(string $key, $value): self
{
    $this->_extraKeys[$key] = $value;

    return $this;
}');
    }

    private function getSubNamespace(ClassBuilder $rootClass): string
    {
        return sprintf('%s\\%s', $rootClass->getNamespace(), substr($rootClass->getName(), 0, -6));
    }

    private function hasNormalizationClosures(NodeInterface $node): bool
    {
        try {
            $r = new \ReflectionProperty($node, 'normalizationClosures');
        } catch (\ReflectionException $e) {
            return false;
        }
        $r->setAccessible(true);

        return [] !== $r->getValue($node);
    }

    private function getType(string $classType, bool $hasNormalizationClosures): string
    {
        return $classType.($hasNormalizationClosures ? '|scalar' : '');
    }
}
PKϤ$Z;��-��config/Builder/Property.phpnu�[���<?php

/*
 * This file is part of the Symfony package.
 *
 * (c) Fabien Potencier <fabien@symfony.com>
 *
 * For the full copyright and license information, please view the LICENSE
 * file that was distributed with this source code.
 */

namespace Symfony\Component\Config\Builder;

/**
 * Represents a property when building classes.
 *
 * @internal
 *
 * @author Tobias Nyholm <tobias.nyholm@gmail.com>
 */
class Property
{
    private $name;
    private $originalName;
    private $array = false;
    private $scalarsAllowed = false;
    private $type = null;
    private $content;

    public function __construct(string $originalName, string $name)
    {
        $this->name = $name;
        $this->originalName = $originalName;
    }

    public function getName(): string
    {
        return $this->name;
    }

    public function getOriginalName(): string
    {
        return $this->originalName;
    }

    public function setType(string $type): void
    {
        $this->array = false;
        $this->type = $type;

        if ('|scalar' === substr($type, -7)) {
            $this->scalarsAllowed = true;
            $this->type = $type = substr($type, 0, -7);
        }

        if ('[]' === substr($type, -2)) {
            $this->array = true;
            $this->type = substr($type, 0, -2);
        }
    }

    public function getType(): ?string
    {
        return $this->type;
    }

    public function getContent(): ?string
    {
        return $this->content;
    }

    public function setContent(string $content): void
    {
        $this->content = $content;
    }

    public function isArray(): bool
    {
        return $this->array;
    }

    public function areScalarsAllowed(): bool
    {
        return $this->scalarsAllowed;
    }
}
PKϤ$Z�_&8��2config/Builder/ConfigBuilderGeneratorInterface.phpnu�[���<?php

/*
 * This file is part of the Symfony package.
 *
 * (c) Fabien Potencier <fabien@symfony.com>
 *
 * For the full copyright and license information, please view the LICENSE
 * file that was distributed with this source code.
 */

namespace Symfony\Component\Config\Builder;

use Symfony\Component\Config\Definition\ConfigurationInterface;

/**
 * Generates ConfigBuilders to help create valid config.
 *
 * @author Tobias Nyholm <tobias.nyholm@gmail.com>
 */
interface ConfigBuilderGeneratorInterface
{
    /**
     * @return \Closure that will return the root config class
     */
    public function build(ConfigurationInterface $configuration): \Closure;
}
PKϤ$Z�0{G^^config/Builder/ClassBuilder.phpnu�[���<?php

/*
 * This file is part of the Symfony package.
 *
 * (c) Fabien Potencier <fabien@symfony.com>
 *
 * For the full copyright and license information, please view the LICENSE
 * file that was distributed with this source code.
 */

namespace Symfony\Component\Config\Builder;

/**
 * Build PHP classes to generate config.
 *
 * @internal
 *
 * @author Tobias Nyholm <tobias.nyholm@gmail.com>
 */
class ClassBuilder
{
    /** @var string */
    private $namespace;

    /** @var string */
    private $name;

    /** @var Property[] */
    private $properties = [];

    /** @var Method[] */
    private $methods = [];
    private $require = [];
    private $use = [];
    private $implements = [];
    private $allowExtraKeys = false;

    public function __construct(string $namespace, string $name)
    {
        $this->namespace = $namespace;
        $this->name = ucfirst($this->camelCase($name)).'Config';
    }

    public function getDirectory(): string
    {
        return str_replace('\\', \DIRECTORY_SEPARATOR, $this->namespace);
    }

    public function getFilename(): string
    {
        return $this->name.'.php';
    }

    public function build(): string
    {
        $rootPath = explode(\DIRECTORY_SEPARATOR, $this->getDirectory());
        $require = '';
        foreach ($this->require as $class) {
            // figure out relative path.
            $path = explode(\DIRECTORY_SEPARATOR, $class->getDirectory());
            $path[] = $class->getFilename();
            foreach ($rootPath as $key => $value) {
                if ($path[$key] !== $value) {
                    break;
                }
                unset($path[$key]);
            }
            $require .= sprintf('require_once __DIR__.\DIRECTORY_SEPARATOR.\'%s\';', implode('\'.\DIRECTORY_SEPARATOR.\'', $path))."\n";
        }
        $use = $require ? "\n" : '';
        foreach (array_keys($this->use) as $statement) {
            $use .= sprintf('use %s;', $statement)."\n";
        }

        $implements = [] === $this->implements ? '' : 'implements '.implode(', ', $this->implements);
        $body = '';
        foreach ($this->properties as $property) {
            $body .= '    '.$property->getContent()."\n";
        }
        foreach ($this->methods as $method) {
            $lines = explode("\n", $method->getContent());
            foreach ($lines as $line) {
                $body .= ($line ? '    '.$line : '')."\n";
            }
        }

        $content = strtr('<?php

namespace NAMESPACE;

REQUIREUSE
/**
 * This class is automatically generated to help in creating a config.
 */
class CLASS IMPLEMENTS
{
BODY
}
', ['NAMESPACE' => $this->namespace, 'REQUIRE' => $require, 'USE' => $use, 'CLASS' => $this->getName(), 'IMPLEMENTS' => $implements, 'BODY' => $body]);

        return $content;
    }

    public function addRequire(self $class): void
    {
        $this->require[] = $class;
    }

    public function addUse(string $class): void
    {
        $this->use[$class] = true;
    }

    public function addImplements(string $interface): void
    {
        $this->implements[] = '\\'.ltrim($interface, '\\');
    }

    public function addMethod(string $name, string $body, array $params = []): void
    {
        $this->methods[] = new Method(strtr($body, ['NAME' => $this->camelCase($name)] + $params));
    }

    public function addProperty(string $name, string $classType = null, string $defaultValue = null): Property
    {
        $property = new Property($name, '_' !== $name[0] ? $this->camelCase($name) : $name);
        if (null !== $classType) {
            $property->setType($classType);
        }
        $this->properties[] = $property;
        $defaultValue = null !== $defaultValue ? sprintf(' = %s', $defaultValue) : '';
        $property->setContent(sprintf('private $%s%s;', $property->getName(), $defaultValue));

        return $property;
    }

    public function getProperties(): array
    {
        return $this->properties;
    }

    private function camelCase(string $input): string
    {
        $output = lcfirst(str_replace(' ', '', ucwords(str_replace('_', ' ', $input))));

        return preg_replace('#\W#', '', $output);
    }

    public function getName(): string
    {
        return $this->name;
    }

    public function getNamespace(): string
    {
        return $this->namespace;
    }

    public function getFqcn(): string
    {
        return '\\'.$this->namespace.'\\'.$this->name;
    }

    public function setAllowExtraKeys(bool $allowExtraKeys): void
    {
        $this->allowExtraKeys = $allowExtraKeys;
    }

    public function shouldAllowExtraKeys(): bool
    {
        return $this->allowExtraKeys;
    }
}
PKϤ$Z��e1��&config/ConfigCacheFactoryInterface.phpnu�[���<?php

/*
 * This file is part of the Symfony package.
 *
 * (c) Fabien Potencier <fabien@symfony.com>
 *
 * For the full copyright and license information, please view the LICENSE
 * file that was distributed with this source code.
 */

namespace Symfony\Component\Config;

/**
 * Interface for a ConfigCache factory. This factory creates
 * an instance of ConfigCacheInterface and initializes the
 * cache if necessary.
 *
 * @author Matthias Pigulla <mp@webfactory.de>
 */
interface ConfigCacheFactoryInterface
{
    /**
     * Creates a cache instance and (re-)initializes it if necessary.
     *
     * @param string   $file     The absolute cache file path
     * @param callable $callable The callable to be executed when the cache needs to be filled (i. e. is not fresh). The cache will be passed as the only parameter to this callback
     *
     * @return ConfigCacheInterface
     */
    public function cache(string $file, callable $callable);
}
PKϤ$Z%�&�&config/Util/XmlUtils.phpnu�[���<?php

/*
 * This file is part of the Symfony package.
 *
 * (c) Fabien Potencier <fabien@symfony.com>
 *
 * For the full copyright and license information, please view the LICENSE
 * file that was distributed with this source code.
 */

namespace Symfony\Component\Config\Util;

use Symfony\Component\Config\Util\Exception\InvalidXmlException;
use Symfony\Component\Config\Util\Exception\XmlParsingException;

/**
 * XMLUtils is a bunch of utility methods to XML operations.
 *
 * This class contains static methods only and is not meant to be instantiated.
 *
 * @author Fabien Potencier <fabien@symfony.com>
 * @author Martin Hasoň <martin.hason@gmail.com>
 * @author Ole Rößner <ole@roessner.it>
 */
class XmlUtils
{
    /**
     * This class should not be instantiated.
     */
    private function __construct()
    {
    }

    /**
     * Parses an XML string.
     *
     * @param string               $content          An XML string
     * @param string|callable|null $schemaOrCallable An XSD schema file path, a callable, or null to disable validation
     *
     * @return \DOMDocument
     *
     * @throws XmlParsingException When parsing of XML file returns error
     * @throws InvalidXmlException When parsing of XML with schema or callable produces any errors unrelated to the XML parsing itself
     * @throws \RuntimeException   When DOM extension is missing
     */
    public static function parse(string $content, $schemaOrCallable = null)
    {
        if (!\extension_loaded('dom')) {
            throw new \LogicException('Extension DOM is required.');
        }

        $internalErrors = libxml_use_internal_errors(true);
        if (\LIBXML_VERSION < 20900) {
            $disableEntities = libxml_disable_entity_loader(true);
        }
        libxml_clear_errors();

        $dom = new \DOMDocument();
        $dom->validateOnParse = true;
        if (!$dom->loadXML($content, \LIBXML_NONET | (\defined('LIBXML_COMPACT') ? \LIBXML_COMPACT : 0))) {
            if (\LIBXML_VERSION < 20900) {
                libxml_disable_entity_loader($disableEntities);
            }

            throw new XmlParsingException(implode("\n", static::getXmlErrors($internalErrors)));
        }

        $dom->normalizeDocument();

        libxml_use_internal_errors($internalErrors);
        if (\LIBXML_VERSION < 20900) {
            libxml_disable_entity_loader($disableEntities);
        }

        foreach ($dom->childNodes as $child) {
            if (\XML_DOCUMENT_TYPE_NODE === $child->nodeType) {
                throw new XmlParsingException('Document types are not allowed.');
            }
        }

        if (null !== $schemaOrCallable) {
            $internalErrors = libxml_use_internal_errors(true);
            libxml_clear_errors();

            $e = null;
            if (\is_callable($schemaOrCallable)) {
                try {
                    $valid = $schemaOrCallable($dom, $internalErrors);
                } catch (\Exception $e) {
                    $valid = false;
                }
            } elseif (!\is_array($schemaOrCallable) && is_file((string) $schemaOrCallable)) {
                $schemaSource = file_get_contents((string) $schemaOrCallable);
                $valid = @$dom->schemaValidateSource($schemaSource);
            } else {
                libxml_use_internal_errors($internalErrors);

                throw new XmlParsingException('The schemaOrCallable argument has to be a valid path to XSD file or callable.');
            }

            if (!$valid) {
                $messages = static::getXmlErrors($internalErrors);
                if (empty($messages)) {
                    throw new InvalidXmlException('The XML is not valid.', 0, $e);
                }
                throw new XmlParsingException(implode("\n", $messages), 0, $e);
            }
        }

        libxml_clear_errors();
        libxml_use_internal_errors($internalErrors);

        return $dom;
    }

    /**
     * Loads an XML file.
     *
     * @param string               $file             An XML file path
     * @param string|callable|null $schemaOrCallable An XSD schema file path, a callable, or null to disable validation
     *
     * @return \DOMDocument
     *
     * @throws \InvalidArgumentException When loading of XML file returns error
     * @throws XmlParsingException       When XML parsing returns any errors
     * @throws \RuntimeException         When DOM extension is missing
     */
    public static function loadFile(string $file, $schemaOrCallable = null)
    {
        if (!is_file($file)) {
            throw new \InvalidArgumentException(sprintf('Resource "%s" is not a file.', $file));
        }

        if (!is_readable($file)) {
            throw new \InvalidArgumentException(sprintf('File "%s" is not readable.', $file));
        }

        $content = @file_get_contents($file);

        if ('' === trim($content)) {
            throw new \InvalidArgumentException(sprintf('File "%s" does not contain valid XML, it is empty.', $file));
        }

        try {
            return static::parse($content, $schemaOrCallable);
        } catch (InvalidXmlException $e) {
            throw new XmlParsingException(sprintf('The XML file "%s" is not valid.', $file), 0, $e->getPrevious());
        }
    }

    /**
     * Converts a \DOMElement object to a PHP array.
     *
     * The following rules applies during the conversion:
     *
     *  * Each tag is converted to a key value or an array
     *    if there is more than one "value"
     *
     *  * The content of a tag is set under a "value" key (<foo>bar</foo>)
     *    if the tag also has some nested tags
     *
     *  * The attributes are converted to keys (<foo foo="bar"/>)
     *
     *  * The nested-tags are converted to keys (<foo><foo>bar</foo></foo>)
     *
     * @param \DOMElement $element     A \DOMElement instance
     * @param bool        $checkPrefix Check prefix in an element or an attribute name
     *
     * @return mixed
     */
    public static function convertDomElementToArray(\DOMElement $element, bool $checkPrefix = true)
    {
        $prefix = (string) $element->prefix;
        $empty = true;
        $config = [];
        foreach ($element->attributes as $name => $node) {
            if ($checkPrefix && !\in_array((string) $node->prefix, ['', $prefix], true)) {
                continue;
            }
            $config[$name] = static::phpize($node->value);
            $empty = false;
        }

        $nodeValue = false;
        foreach ($element->childNodes as $node) {
            if ($node instanceof \DOMText) {
                if ('' !== trim($node->nodeValue)) {
                    $nodeValue = trim($node->nodeValue);
                    $empty = false;
                }
            } elseif ($checkPrefix && $prefix != (string) $node->prefix) {
                continue;
            } elseif (!$node instanceof \DOMComment) {
                $value = static::convertDomElementToArray($node, $checkPrefix);

                $key = $node->localName;
                if (isset($config[$key])) {
                    if (!\is_array($config[$key]) || !\is_int(key($config[$key]))) {
                        $config[$key] = [$config[$key]];
                    }
                    $config[$key][] = $value;
                } else {
                    $config[$key] = $value;
                }

                $empty = false;
            }
        }

        if (false !== $nodeValue) {
            $value = static::phpize($nodeValue);
            if (\count($config)) {
                $config['value'] = $value;
            } else {
                $config = $value;
            }
        }

        return !$empty ? $config : null;
    }

    /**
     * Converts an xml value to a PHP type.
     *
     * @param mixed $value
     *
     * @return mixed
     */
    public static function phpize($value)
    {
        $value = (string) $value;
        $lowercaseValue = strtolower($value);

        switch (true) {
            case 'null' === $lowercaseValue:
                return null;
            case ctype_digit($value):
            case isset($value[1]) && '-' === $value[0] && ctype_digit(substr($value, 1)):
                $raw = $value;
                $cast = (int) $value;

                return self::isOctal($value) ? \intval($value, 8) : (($raw === (string) $cast) ? $cast : $raw);
            case 'true' === $lowercaseValue:
                return true;
            case 'false' === $lowercaseValue:
                return false;
            case isset($value[1]) && '0b' == $value[0].$value[1] && preg_match('/^0b[01]*$/', $value):
                return bindec($value);
            case is_numeric($value):
                return '0x' === $value[0].$value[1] ? hexdec($value) : (float) $value;
            case preg_match('/^0x[0-9a-f]++$/i', $value):
                return hexdec($value);
            case preg_match('/^[+-]?[0-9]+(\.[0-9]+)?$/', $value):
                return (float) $value;
            default:
                return $value;
        }
    }

    protected static function getXmlErrors(bool $internalErrors)
    {
        $errors = [];
        foreach (libxml_get_errors() as $error) {
            $errors[] = sprintf('[%s %s] %s (in %s - line %d, column %d)',
                \LIBXML_ERR_WARNING == $error->level ? 'WARNING' : 'ERROR',
                $error->code,
                trim($error->message),
                $error->file ?: 'n/a',
                $error->line,
                $error->column
            );
        }

        libxml_clear_errors();
        libxml_use_internal_errors($internalErrors);

        return $errors;
    }

    private static function isOctal(string $str): bool
    {
        if ('-' === $str[0]) {
            $str = substr($str, 1);
        }

        return $str === '0'.decoct(\intval($str, 8));
    }
}
PKϤ$Z��_���-config/Util/Exception/XmlParsingException.phpnu�[���<?php

/*
 * This file is part of the Symfony package.
 *
 * (c) Fabien Potencier <fabien@symfony.com>
 *
 * For the full copyright and license information, please view the LICENSE
 * file that was distributed with this source code.
 */

namespace Symfony\Component\Config\Util\Exception;

/**
 * Exception class for when XML cannot be parsed properly.
 *
 * @author Ole Rößner <ole@roessner.it>
 */
class XmlParsingException extends \InvalidArgumentException
{
}
PKϤ$ZCh&&-config/Util/Exception/InvalidXmlException.phpnu�[���<?php

/*
 * This file is part of the Symfony package.
 *
 * (c) Fabien Potencier <fabien@symfony.com>
 *
 * For the full copyright and license information, please view the LICENSE
 * file that was distributed with this source code.
 */

namespace Symfony\Component\Config\Util\Exception;

/**
 * Exception class for when XML parsing with an XSD schema file path or a callable validator produces errors unrelated
 * to the actual XML parsing.
 *
 * @author Ole Rößner <ole@roessner.it>
 */
class InvalidXmlException extends XmlParsingException
{
}
PKϤ$ZrX31config/Resource/SelfCheckingResourceInterface.phpnu�[���<?php

/*
 * This file is part of the Symfony package.
 *
 * (c) Fabien Potencier <fabien@symfony.com>
 *
 * For the full copyright and license information, please view the LICENSE
 * file that was distributed with this source code.
 */

namespace Symfony\Component\Config\Resource;

/**
 * Interface for Resources that can check for freshness autonomously,
 * without special support from external services.
 *
 * @author Matthias Pigulla <mp@webfactory.de>
 */
interface SelfCheckingResourceInterface extends ResourceInterface
{
    /**
     * Returns true if the resource has not been updated since the given timestamp.
     *
     * @param int $timestamp The last time the resource was loaded
     *
     * @return bool
     */
    public function isFresh(int $timestamp);
}
PKϤ$Z����
�
%config/Resource/DirectoryResource.phpnu�[���<?php

/*
 * This file is part of the Symfony package.
 *
 * (c) Fabien Potencier <fabien@symfony.com>
 *
 * For the full copyright and license information, please view the LICENSE
 * file that was distributed with this source code.
 */

namespace Symfony\Component\Config\Resource;

/**
 * DirectoryResource represents a resources stored in a subdirectory tree.
 *
 * @author Fabien Potencier <fabien@symfony.com>
 *
 * @final
 */
class DirectoryResource implements SelfCheckingResourceInterface
{
    private $resource;
    private $pattern;

    /**
     * @param string      $resource The file path to the resource
     * @param string|null $pattern  A pattern to restrict monitored files
     *
     * @throws \InvalidArgumentException
     */
    public function __construct(string $resource, string $pattern = null)
    {
        $this->resource = realpath($resource) ?: (file_exists($resource) ? $resource : false);
        $this->pattern = $pattern;

        if (false === $this->resource || !is_dir($this->resource)) {
            throw new \InvalidArgumentException(sprintf('The directory "%s" does not exist.', $resource));
        }
    }

    public function __toString(): string
    {
        return md5(serialize([$this->resource, $this->pattern]));
    }

    public function getResource(): string
    {
        return $this->resource;
    }

    public function getPattern(): ?string
    {
        return $this->pattern;
    }

    /**
     * {@inheritdoc}
     */
    public function isFresh(int $timestamp): bool
    {
        if (!is_dir($this->resource)) {
            return false;
        }

        if ($timestamp < filemtime($this->resource)) {
            return false;
        }

        foreach (new \RecursiveIteratorIterator(new \RecursiveDirectoryIterator($this->resource), \RecursiveIteratorIterator::SELF_FIRST) as $file) {
            // if regex filtering is enabled only check matching files
            if ($this->pattern && $file->isFile() && !preg_match($this->pattern, $file->getBasename())) {
                continue;
            }

            // always monitor directories for changes, except the .. entries
            // (otherwise deleted files wouldn't get detected)
            if ($file->isDir() && str_ends_with($file, '/..')) {
                continue;
            }

            // for broken links
            try {
                $fileMTime = $file->getMTime();
            } catch (\RuntimeException $e) {
                continue;
            }

            // early return if a file's mtime exceeds the passed timestamp
            if ($timestamp < $fileMTime) {
                return false;
            }
        }

        return true;
    }
}
PKϤ$Z�N1��%config/Resource/ResourceInterface.phpnu�[���<?php

/*
 * This file is part of the Symfony package.
 *
 * (c) Fabien Potencier <fabien@symfony.com>
 *
 * For the full copyright and license information, please view the LICENSE
 * file that was distributed with this source code.
 */

namespace Symfony\Component\Config\Resource;

/**
 * ResourceInterface is the interface that must be implemented by all Resource classes.
 *
 * @author Fabien Potencier <fabien@symfony.com>
 */
interface ResourceInterface
{
    /**
     * Returns a string representation of the Resource.
     *
     * This method is necessary to allow for resource de-duplication, for example by means
     * of array_unique(). The string returned need not have a particular meaning, but has
     * to be identical for different ResourceInterface instances referring to the same
     * resource; and it should be unlikely to collide with that of other, unrelated
     * resource instances.
     */
    public function __toString();
}
PKϤ$ZU�j config/Resource/GlobResource.phpnu�[���<?php

/*
 * This file is part of the Symfony package.
 *
 * (c) Fabien Potencier <fabien@symfony.com>
 *
 * For the full copyright and license information, please view the LICENSE
 * file that was distributed with this source code.
 */

namespace Symfony\Component\Config\Resource;

use Symfony\Component\Finder\Finder;
use Symfony\Component\Finder\Glob;

/**
 * GlobResource represents a set of resources stored on the filesystem.
 *
 * Only existence/removal is tracked (not mtimes.)
 *
 * @author Nicolas Grekas <p@tchwork.com>
 *
 * @final
 *
 * @implements \IteratorAggregate<string, \SplFileInfo>
 */
class GlobResource implements \IteratorAggregate, SelfCheckingResourceInterface
{
    private $prefix;
    private $pattern;
    private $recursive;
    private $hash;
    private $forExclusion;
    private $excludedPrefixes;
    private $globBrace;

    /**
     * @param string $prefix    A directory prefix
     * @param string $pattern   A glob pattern
     * @param bool   $recursive Whether directories should be scanned recursively or not
     *
     * @throws \InvalidArgumentException
     */
    public function __construct(string $prefix, string $pattern, bool $recursive, bool $forExclusion = false, array $excludedPrefixes = [])
    {
        ksort($excludedPrefixes);
        $this->prefix = realpath($prefix) ?: (file_exists($prefix) ? $prefix : false);
        $this->pattern = $pattern;
        $this->recursive = $recursive;
        $this->forExclusion = $forExclusion;
        $this->excludedPrefixes = $excludedPrefixes;
        $this->globBrace = \defined('GLOB_BRACE') ? \GLOB_BRACE : 0;

        if (false === $this->prefix) {
            throw new \InvalidArgumentException(sprintf('The path "%s" does not exist.', $prefix));
        }
    }

    public function getPrefix(): string
    {
        return $this->prefix;
    }

    public function __toString(): string
    {
        return 'glob.'.$this->prefix.(int) $this->recursive.$this->pattern.(int) $this->forExclusion.implode("\0", $this->excludedPrefixes);
    }

    /**
     * {@inheritdoc}
     */
    public function isFresh(int $timestamp): bool
    {
        $hash = $this->computeHash();

        if (null === $this->hash) {
            $this->hash = $hash;
        }

        return $this->hash === $hash;
    }

    /**
     * @internal
     */
    public function __sleep(): array
    {
        if (null === $this->hash) {
            $this->hash = $this->computeHash();
        }

        return ['prefix', 'pattern', 'recursive', 'hash', 'forExclusion', 'excludedPrefixes'];
    }

    /**
     * @internal
     */
    public function __wakeup(): void
    {
        $this->globBrace = \defined('GLOB_BRACE') ? \GLOB_BRACE : 0;
    }

    public function getIterator(): \Traversable
    {
        if (!file_exists($this->prefix) || (!$this->recursive && '' === $this->pattern)) {
            return;
        }
        $prefix = str_replace('\\', '/', $this->prefix);
        $paths = null;

        if ('' === $this->pattern && is_file($prefix)) {
            $paths = [$this->prefix];
        } elseif (!str_starts_with($this->prefix, 'phar://') && !str_contains($this->pattern, '/**/')) {
            if ($this->globBrace || !str_contains($this->pattern, '{')) {
                $paths = glob($this->prefix.$this->pattern, \GLOB_NOSORT | $this->globBrace);
            } elseif (!str_contains($this->pattern, '\\') || !preg_match('/\\\\[,{}]/', $this->pattern)) {
                foreach ($this->expandGlob($this->pattern) as $p) {
                    $paths[] = glob($this->prefix.$p, \GLOB_NOSORT);
                }
                $paths = array_merge(...$paths);
            }
        }

        if (null !== $paths) {
            natsort($paths);
            foreach ($paths as $path) {
                if ($this->excludedPrefixes) {
                    $normalizedPath = str_replace('\\', '/', $path);
                    do {
                        if (isset($this->excludedPrefixes[$dirPath = $normalizedPath])) {
                            continue 2;
                        }
                    } while ($prefix !== $dirPath && $dirPath !== $normalizedPath = \dirname($dirPath));
                }

                if (is_file($path)) {
                    yield $path => new \SplFileInfo($path);
                }
                if (!is_dir($path)) {
                    continue;
                }
                if ($this->forExclusion) {
                    yield $path => new \SplFileInfo($path);
                    continue;
                }
                if (!$this->recursive || isset($this->excludedPrefixes[str_replace('\\', '/', $path)])) {
                    continue;
                }
                $files = iterator_to_array(new \RecursiveIteratorIterator(
                    new \RecursiveCallbackFilterIterator(
                        new \RecursiveDirectoryIterator($path, \FilesystemIterator::SKIP_DOTS | \FilesystemIterator::FOLLOW_SYMLINKS),
                        function (\SplFileInfo $file, $path) {
                            return !isset($this->excludedPrefixes[str_replace('\\', '/', $path)]) && '.' !== $file->getBasename()[0];
                        }
                    ),
                    \RecursiveIteratorIterator::LEAVES_ONLY
                ));
                uksort($files, 'strnatcmp');

                foreach ($files as $path => $info) {
                    if ($info->isFile()) {
                        yield $path => $info;
                    }
                }
            }

            return;
        }

        if (!class_exists(Finder::class)) {
            throw new \LogicException(sprintf('Extended glob pattern "%s" cannot be used as the Finder component is not installed.', $this->pattern));
        }

        if (is_file($prefix = $this->prefix)) {
            $prefix = \dirname($prefix);
            $pattern = basename($prefix).$this->pattern;
        } else {
            $pattern = $this->pattern;
        }

        $finder = new Finder();
        $regex = Glob::toRegex($pattern);
        if ($this->recursive) {
            $regex = substr_replace($regex, '(/|$)', -2, 1);
        }

        $prefixLen = \strlen($prefix);
        foreach ($finder->followLinks()->sortByName()->in($prefix) as $path => $info) {
            $normalizedPath = str_replace('\\', '/', $path);
            if (!preg_match($regex, substr($normalizedPath, $prefixLen)) || !$info->isFile()) {
                continue;
            }
            if ($this->excludedPrefixes) {
                do {
                    if (isset($this->excludedPrefixes[$dirPath = $normalizedPath])) {
                        continue 2;
                    }
                } while ($prefix !== $dirPath && $dirPath !== $normalizedPath = \dirname($dirPath));
            }

            yield $path => $info;
        }
    }

    private function computeHash(): string
    {
        $hash = hash_init('md5');

        foreach ($this->getIterator() as $path => $info) {
            hash_update($hash, $path."\n");
        }

        return hash_final($hash);
    }

    private function expandGlob(string $pattern): array
    {
        $segments = preg_split('/\{([^{}]*+)\}/', $pattern, -1, \PREG_SPLIT_DELIM_CAPTURE);
        $paths = [$segments[0]];
        $patterns = [];

        for ($i = 1; $i < \count($segments); $i += 2) {
            $patterns = [];

            foreach (explode(',', $segments[$i]) as $s) {
                foreach ($paths as $p) {
                    $patterns[] = $p.$s.$segments[1 + $i];
                }
            }

            $paths = $patterns;
        }

        $j = 0;
        foreach ($patterns as $i => $p) {
            if (str_contains($p, '{')) {
                $p = $this->expandGlob($p);
                array_splice($paths, $i + $j, 1, $p);
                $j += \count($p) - 1;
            }
        }

        return $paths;
    }
}
PKϤ$Z���>$>$+config/Resource/ReflectionClassResource.phpnu�[���<?php

/*
 * This file is part of the Symfony package.
 *
 * (c) Fabien Potencier <fabien@symfony.com>
 *
 * For the full copyright and license information, please view the LICENSE
 * file that was distributed with this source code.
 */

namespace Symfony\Component\Config\Resource;

use Symfony\Component\EventDispatcher\EventSubscriberInterface;
use Symfony\Component\Messenger\Handler\MessageSubscriberInterface;
use Symfony\Contracts\Service\ServiceSubscriberInterface;

/**
 * @author Nicolas Grekas <p@tchwork.com>
 *
 * @final
 */
class ReflectionClassResource implements SelfCheckingResourceInterface
{
    private $files = [];
    private $className;
    private $classReflector;
    private $excludedVendors = [];
    private $hash;

    public function __construct(\ReflectionClass $classReflector, array $excludedVendors = [])
    {
        $this->className = $classReflector->name;
        $this->classReflector = $classReflector;
        $this->excludedVendors = $excludedVendors;
    }

    /**
     * {@inheritdoc}
     */
    public function isFresh(int $timestamp): bool
    {
        if (null === $this->hash) {
            $this->hash = $this->computeHash();
            $this->loadFiles($this->classReflector);
        }

        foreach ($this->files as $file => $v) {
            if (false === $filemtime = @filemtime($file)) {
                return false;
            }

            if ($filemtime > $timestamp) {
                return $this->hash === $this->computeHash();
            }
        }

        return true;
    }

    public function __toString(): string
    {
        return 'reflection.'.$this->className;
    }

    /**
     * @internal
     */
    public function __sleep(): array
    {
        if (null === $this->hash) {
            $this->hash = $this->computeHash();
            $this->loadFiles($this->classReflector);
        }

        return ['files', 'className', 'hash'];
    }

    private function loadFiles(\ReflectionClass $class)
    {
        foreach ($class->getInterfaces() as $v) {
            $this->loadFiles($v);
        }
        do {
            $file = $class->getFileName();
            if (false !== $file && is_file($file)) {
                foreach ($this->excludedVendors as $vendor) {
                    if (str_starts_with($file, $vendor) && false !== strpbrk(substr($file, \strlen($vendor), 1), '/'.\DIRECTORY_SEPARATOR)) {
                        $file = false;
                        break;
                    }
                }
                if ($file) {
                    $this->files[$file] = null;
                }
            }
            foreach ($class->getTraits() as $v) {
                $this->loadFiles($v);
            }
        } while ($class = $class->getParentClass());
    }

    private function computeHash(): string
    {
        if (null === $this->classReflector) {
            try {
                $this->classReflector = new \ReflectionClass($this->className);
            } catch (\ReflectionException $e) {
                // the class does not exist anymore
                return false;
            }
        }
        $hash = hash_init('md5');

        foreach ($this->generateSignature($this->classReflector) as $info) {
            hash_update($hash, $info);
        }

        return hash_final($hash);
    }

    private function generateSignature(\ReflectionClass $class): iterable
    {
        if (\PHP_VERSION_ID >= 80000) {
            $attributes = [];
            foreach ($class->getAttributes() as $a) {
                $attributes[] = [$a->getName(), \PHP_VERSION_ID >= 80100 ? (string) $a : $a->getArguments()];
            }
            yield print_r($attributes, true);
            $attributes = [];
        }

        yield $class->getDocComment();
        yield (int) $class->isFinal();
        yield (int) $class->isAbstract();

        if ($class->isTrait()) {
            yield print_r(class_uses($class->name), true);
        } else {
            yield print_r(class_parents($class->name), true);
            yield print_r(class_implements($class->name), true);
            yield print_r($class->getConstants(), true);
        }

        if (!$class->isInterface()) {
            $defaults = $class->getDefaultProperties();

            foreach ($class->getProperties(\ReflectionProperty::IS_PUBLIC | \ReflectionProperty::IS_PROTECTED) as $p) {
                if (\PHP_VERSION_ID >= 80000) {
                    foreach ($p->getAttributes() as $a) {
                        $attributes[] = [$a->getName(), \PHP_VERSION_ID >= 80100 ? (string) $a : $a->getArguments()];
                    }
                    yield print_r($attributes, true);
                    $attributes = [];
                }

                yield $p->getDocComment();
                yield $p->isDefault() ? '<default>' : '';
                yield $p->isPublic() ? 'public' : 'protected';
                yield $p->isStatic() ? 'static' : '';
                yield '$'.$p->name;
                yield print_r(isset($defaults[$p->name]) && !\is_object($defaults[$p->name]) ? $defaults[$p->name] : null, true);
            }
        }

        $defined = \Closure::bind(static function ($c) { return \defined($c); }, null, $class->name);

        foreach ($class->getMethods(\ReflectionMethod::IS_PUBLIC | \ReflectionMethod::IS_PROTECTED) as $m) {
            if (\PHP_VERSION_ID >= 80000) {
                foreach ($m->getAttributes() as $a) {
                    $attributes[] = [$a->getName(), \PHP_VERSION_ID >= 80100 ? (string) $a : $a->getArguments()];
                }
                yield print_r($attributes, true);
                $attributes = [];
            }

            $defaults = [];
            $parametersWithUndefinedConstants = [];
            foreach ($m->getParameters() as $p) {
                if (\PHP_VERSION_ID >= 80000) {
                    foreach ($p->getAttributes() as $a) {
                        $attributes[] = [$a->getName(), \PHP_VERSION_ID >= 80100 ? (string) $a : $a->getArguments()];
                    }
                    yield print_r($attributes, true);
                    $attributes = [];
                }

                if (!$p->isDefaultValueAvailable()) {
                    $defaults[$p->name] = null;

                    continue;
                }

                if (\PHP_VERSION_ID >= 80100) {
                    $defaults[$p->name] = (string) $p;

                    continue;
                }

                if (!$p->isDefaultValueConstant() || $defined($p->getDefaultValueConstantName())) {
                    $defaults[$p->name] = $p->getDefaultValue();

                    continue;
                }

                $defaults[$p->name] = $p->getDefaultValueConstantName();
                $parametersWithUndefinedConstants[$p->name] = true;
            }

            if (!$parametersWithUndefinedConstants) {
                yield preg_replace('/^  @@.*/m', '', $m);
            } else {
                $t = $m->getReturnType();
                $stack = [
                    $m->getDocComment(),
                    $m->getName(),
                    $m->isAbstract(),
                    $m->isFinal(),
                    $m->isStatic(),
                    $m->isPublic(),
                    $m->isPrivate(),
                    $m->isProtected(),
                    $m->returnsReference(),
                    $t instanceof \ReflectionNamedType ? ((string) $t->allowsNull()).$t->getName() : (string) $t,
                ];

                foreach ($m->getParameters() as $p) {
                    if (!isset($parametersWithUndefinedConstants[$p->name])) {
                        $stack[] = (string) $p;
                    } else {
                        $t = $p->getType();
                        $stack[] = $p->isOptional();
                        $stack[] = $t instanceof \ReflectionNamedType ? ((string) $t->allowsNull()).$t->getName() : (string) $t;
                        $stack[] = $p->isPassedByReference();
                        $stack[] = $p->isVariadic();
                        $stack[] = $p->getName();
                    }
                }

                yield implode(',', $stack);
            }

            yield print_r($defaults, true);
        }

        if ($class->isAbstract() || $class->isInterface() || $class->isTrait()) {
            return;
        }

        if (interface_exists(EventSubscriberInterface::class, false) && $class->isSubclassOf(EventSubscriberInterface::class)) {
            yield EventSubscriberInterface::class;
            yield print_r($class->name::getSubscribedEvents(), true);
        }

        if (interface_exists(MessageSubscriberInterface::class, false) && $class->isSubclassOf(MessageSubscriberInterface::class)) {
            yield MessageSubscriberInterface::class;
            foreach ($class->name::getHandledMessages() as $key => $value) {
                yield $key.print_r($value, true);
            }
        }

        if (interface_exists(ServiceSubscriberInterface::class, false) && $class->isSubclassOf(ServiceSubscriberInterface::class)) {
            yield ServiceSubscriberInterface::class;
            yield print_r($class->name::getSubscribedServices(), true);
        }
    }
}
PKϤ$Z��``/config/Resource/SelfCheckingResourceChecker.phpnu�[���<?php

/*
 * This file is part of the Symfony package.
 *
 * (c) Fabien Potencier <fabien@symfony.com>
 *
 * For the full copyright and license information, please view the LICENSE
 * file that was distributed with this source code.
 */

namespace Symfony\Component\Config\Resource;

use Symfony\Component\Config\ResourceCheckerInterface;

/**
 * Resource checker for instances of SelfCheckingResourceInterface.
 *
 * As these resources perform the actual check themselves, we can provide
 * this class as a standard way of validating them.
 *
 * @author Matthias Pigulla <mp@webfactory.de>
 */
class SelfCheckingResourceChecker implements ResourceCheckerInterface
{
    // Common shared cache, because this checker can be used in different
    // situations. For example, when using the full stack framework, the router
    // and the container have their own cache. But they may check the very same
    // resources
    private static $cache = [];

    public function supports(ResourceInterface $metadata)
    {
        return $metadata instanceof SelfCheckingResourceInterface;
    }

    /**
     * @param SelfCheckingResourceInterface $resource
     */
    public function isFresh(ResourceInterface $resource, int $timestamp)
    {
        $key = "$resource:$timestamp";

        return self::$cache[$key] ?? self::$cache[$key] = $resource->isFresh($timestamp);
    }
}
PKϤ$ZdΌ
��*config/Resource/ClassExistenceResource.phpnu�[���<?php

/*
 * This file is part of the Symfony package.
 *
 * (c) Fabien Potencier <fabien@symfony.com>
 *
 * For the full copyright and license information, please view the LICENSE
 * file that was distributed with this source code.
 */

namespace Symfony\Component\Config\Resource;

/**
 * ClassExistenceResource represents a class existence.
 * Freshness is only evaluated against resource existence.
 *
 * The resource must be a fully-qualified class name.
 *
 * @author Fabien Potencier <fabien@symfony.com>
 *
 * @final
 */
class ClassExistenceResource implements SelfCheckingResourceInterface
{
    private $resource;
    private $exists;

    private static $autoloadLevel = 0;
    private static $autoloadedClass;
    private static $existsCache = [];

    /**
     * @param string    $resource The fully-qualified class name
     * @param bool|null $exists   Boolean when the existency check has already been done
     */
    public function __construct(string $resource, bool $exists = null)
    {
        $this->resource = $resource;
        if (null !== $exists) {
            $this->exists = [$exists, null];
        }
    }

    public function __toString(): string
    {
        return $this->resource;
    }

    public function getResource(): string
    {
        return $this->resource;
    }

    /**
     * {@inheritdoc}
     *
     * @throws \ReflectionException when a parent class/interface/trait is not found
     */
    public function isFresh(int $timestamp): bool
    {
        $loaded = class_exists($this->resource, false) || interface_exists($this->resource, false) || trait_exists($this->resource, false);

        if (null !== $exists = &self::$existsCache[$this->resource]) {
            if ($loaded) {
                $exists = [true, null];
            } elseif (0 >= $timestamp && !$exists[0] && null !== $exists[1]) {
                throw new \ReflectionException($exists[1]);
            }
        } elseif ([false, null] === $exists = [$loaded, null]) {
            if (!self::$autoloadLevel++) {
                spl_autoload_register(__CLASS__.'::throwOnRequiredClass');
            }
            $autoloadedClass = self::$autoloadedClass;
            self::$autoloadedClass = ltrim($this->resource, '\\');

            try {
                $exists[0] = class_exists($this->resource) || interface_exists($this->resource, false) || trait_exists($this->resource, false);
            } catch (\Exception $e) {
                $exists[1] = $e->getMessage();

                try {
                    self::throwOnRequiredClass($this->resource, $e);
                } catch (\ReflectionException $e) {
                    if (0 >= $timestamp) {
                        throw $e;
                    }
                }
            } catch (\Throwable $e) {
                $exists[1] = $e->getMessage();

                throw $e;
            } finally {
                self::$autoloadedClass = $autoloadedClass;
                if (!--self::$autoloadLevel) {
                    spl_autoload_unregister(__CLASS__.'::throwOnRequiredClass');
                }
            }
        }

        if (null === $this->exists) {
            $this->exists = $exists;
        }

        return $this->exists[0] xor !$exists[0];
    }

    /**
     * @internal
     */
    public function __sleep(): array
    {
        if (null === $this->exists) {
            $this->isFresh(0);
        }

        return ['resource', 'exists'];
    }

    /**
     * @internal
     */
    public function __wakeup()
    {
        if (\is_bool($this->exists)) {
            $this->exists = [$this->exists, null];
        }
    }

    /**
     * Throws a reflection exception when the passed class does not exist but is required.
     *
     * A class is considered "not required" when it's loaded as part of a "class_exists" or similar check.
     *
     * This function can be used as an autoload function to throw a reflection
     * exception if the class was not found by previous autoload functions.
     *
     * A previous exception can be passed. In this case, the class is considered as being
     * required totally, so if it doesn't exist, a reflection exception is always thrown.
     * If it exists, the previous exception is rethrown.
     *
     * @throws \ReflectionException
     *
     * @internal
     */
    public static function throwOnRequiredClass(string $class, \Exception $previous = null)
    {
        // If the passed class is the resource being checked, we shouldn't throw.
        if (null === $previous && self::$autoloadedClass === $class) {
            return;
        }

        if (class_exists($class, false) || interface_exists($class, false) || trait_exists($class, false)) {
            if (null !== $previous) {
                throw $previous;
            }

            return;
        }

        if ($previous instanceof \ReflectionException) {
            throw $previous;
        }

        $message = sprintf('Class "%s" not found.', $class);

        if (self::$autoloadedClass !== $class) {
            $message = substr_replace($message, sprintf(' while loading "%s"', self::$autoloadedClass), -1, 0);
        }

        if (null !== $previous) {
            $message = $previous->getMessage();
        }

        $e = new \ReflectionException($message, 0, $previous);

        if (null !== $previous) {
            throw $e;
        }

        $trace = debug_backtrace();
        $autoloadFrame = [
            'function' => 'spl_autoload_call',
            'args' => [$class],
        ];

        if (\PHP_VERSION_ID >= 80000 && isset($trace[1])) {
            $callerFrame = $trace[1];
            $i = 2;
        } elseif (false !== $i = array_search($autoloadFrame, $trace, true)) {
            $callerFrame = $trace[++$i];
        } else {
            throw $e;
        }

        if (isset($callerFrame['function']) && !isset($callerFrame['class'])) {
            switch ($callerFrame['function']) {
                case 'get_class_methods':
                case 'get_class_vars':
                case 'get_parent_class':
                case 'is_a':
                case 'is_subclass_of':
                case 'class_exists':
                case 'class_implements':
                case 'class_parents':
                case 'trait_exists':
                case 'defined':
                case 'interface_exists':
                case 'method_exists':
                case 'property_exists':
                case 'is_callable':
                    return;
            }

            $props = [
                'file' => $callerFrame['file'] ?? null,
                'line' => $callerFrame['line'] ?? null,
                'trace' => \array_slice($trace, 1 + $i),
            ];

            foreach ($props as $p => $v) {
                if (null !== $v) {
                    $r = new \ReflectionProperty(\Exception::class, $p);
                    $r->setAccessible(true);
                    $r->setValue($e, $v);
                }
            }
        }

        throw $e;
    }
}
PKϤ$Zo��00$config/Resource/ComposerResource.phpnu�[���<?php

/*
 * This file is part of the Symfony package.
 *
 * (c) Fabien Potencier <fabien@symfony.com>
 *
 * For the full copyright and license information, please view the LICENSE
 * file that was distributed with this source code.
 */

namespace Symfony\Component\Config\Resource;

/**
 * ComposerResource tracks the PHP version and Composer dependencies.
 *
 * @author Nicolas Grekas <p@tchwork.com>
 *
 * @final
 */
class ComposerResource implements SelfCheckingResourceInterface
{
    private $vendors;

    private static $runtimeVendors;

    public function __construct()
    {
        self::refresh();
        $this->vendors = self::$runtimeVendors;
    }

    public function getVendors(): array
    {
        return array_keys($this->vendors);
    }

    public function __toString(): string
    {
        return __CLASS__;
    }

    /**
     * {@inheritdoc}
     */
    public function isFresh(int $timestamp): bool
    {
        self::refresh();

        return array_values(self::$runtimeVendors) === array_values($this->vendors);
    }

    private static function refresh()
    {
        self::$runtimeVendors = [];

        foreach (get_declared_classes() as $class) {
            if ('C' === $class[0] && str_starts_with($class, 'ComposerAutoloaderInit')) {
                $r = new \ReflectionClass($class);
                $v = \dirname($r->getFileName(), 2);
                if (is_file($v.'/composer/installed.json')) {
                    self::$runtimeVendors[$v] = @filemtime($v.'/composer/installed.json');
                }
            }
        }
    }
}
PKϤ$ZԎ|�� config/Resource/FileResource.phpnu�[���<?php

/*
 * This file is part of the Symfony package.
 *
 * (c) Fabien Potencier <fabien@symfony.com>
 *
 * For the full copyright and license information, please view the LICENSE
 * file that was distributed with this source code.
 */

namespace Symfony\Component\Config\Resource;

/**
 * FileResource represents a resource stored on the filesystem.
 *
 * The resource can be a file or a directory.
 *
 * @author Fabien Potencier <fabien@symfony.com>
 *
 * @final
 */
class FileResource implements SelfCheckingResourceInterface
{
    /**
     * @var string|false
     */
    private $resource;

    /**
     * @param string $resource The file path to the resource
     *
     * @throws \InvalidArgumentException
     */
    public function __construct(string $resource)
    {
        $this->resource = realpath($resource) ?: (file_exists($resource) ? $resource : false);

        if (false === $this->resource) {
            throw new \InvalidArgumentException(sprintf('The file "%s" does not exist.', $resource));
        }
    }

    public function __toString(): string
    {
        return $this->resource;
    }

    /**
     * Returns the canonicalized, absolute path to the resource.
     */
    public function getResource(): string
    {
        return $this->resource;
    }

    /**
     * {@inheritdoc}
     */
    public function isFresh(int $timestamp): bool
    {
        return false !== ($filemtime = @filemtime($this->resource)) && $filemtime <= $timestamp;
    }
}
PKϤ$Z��1���)config/Resource/FileExistenceResource.phpnu�[���<?php

/*
 * This file is part of the Symfony package.
 *
 * (c) Fabien Potencier <fabien@symfony.com>
 *
 * For the full copyright and license information, please view the LICENSE
 * file that was distributed with this source code.
 */

namespace Symfony\Component\Config\Resource;

/**
 * FileExistenceResource represents a resource stored on the filesystem.
 * Freshness is only evaluated against resource creation or deletion.
 *
 * The resource can be a file or a directory.
 *
 * @author Charles-Henri Bruyand <charleshenri.bruyand@gmail.com>
 *
 * @final
 */
class FileExistenceResource implements SelfCheckingResourceInterface
{
    private $resource;

    private $exists;

    /**
     * @param string $resource The file path to the resource
     */
    public function __construct(string $resource)
    {
        $this->resource = $resource;
        $this->exists = file_exists($resource);
    }

    public function __toString(): string
    {
        return $this->resource;
    }

    public function getResource(): string
    {
        return $this->resource;
    }

    /**
     * {@inheritdoc}
     */
    public function isFresh(int $timestamp): bool
    {
        return file_exists($this->resource) === $this->exists;
    }
}
PKϤ$ZR�b.config/ConfigCacheInterface.phpnu�[���<?php

/*
 * This file is part of the Symfony package.
 *
 * (c) Fabien Potencier <fabien@symfony.com>
 *
 * For the full copyright and license information, please view the LICENSE
 * file that was distributed with this source code.
 */

namespace Symfony\Component\Config;

use Symfony\Component\Config\Resource\ResourceInterface;

/**
 * Interface for ConfigCache.
 *
 * @author Matthias Pigulla <mp@webfactory.de>
 */
interface ConfigCacheInterface
{
    /**
     * Gets the cache file path.
     *
     * @return string
     */
    public function getPath();

    /**
     * Checks if the cache is still fresh.
     *
     * This check should take the metadata passed to the write() method into consideration.
     *
     * @return bool
     */
    public function isFresh();

    /**
     * Writes the given content into the cache file. Metadata will be stored
     * independently and can be used to check cache freshness at a later time.
     *
     * @param string                   $content  The content to write into the cache
     * @param ResourceInterface[]|null $metadata An array of ResourceInterface instances
     *
     * @throws \RuntimeException When the cache file cannot be written
     */
    public function write(string $content, array $metadata = null);
}
PKϤ$Z��TTconfig/README.mdnu�[���Config Component
================

The Config component helps find, load, combine, autofill and validate
configuration values of any kind, whatever their source may be (YAML, XML, INI
files, or for instance a database).

Resources
---------

 * [Documentation](https://symfony.com/doc/current/components/config.html)
 * [Contributing](https://symfony.com/doc/current/contributing/index.html)
 * [Report issues](https://github.com/symfony/symfony/issues) and
   [send Pull Requests](https://github.com/symfony/symfony/pulls)
   in the [main Symfony repository](https://github.com/symfony/symfony)
PKϤ$ZT�&�//,config/ResourceCheckerConfigCacheFactory.phpnu�[���<?php

/*
 * This file is part of the Symfony package.
 *
 * (c) Fabien Potencier <fabien@symfony.com>
 *
 * For the full copyright and license information, please view the LICENSE
 * file that was distributed with this source code.
 */

namespace Symfony\Component\Config;

/**
 * A ConfigCacheFactory implementation that validates the
 * cache with an arbitrary set of ResourceCheckers.
 *
 * @author Matthias Pigulla <mp@webfactory.de>
 */
class ResourceCheckerConfigCacheFactory implements ConfigCacheFactoryInterface
{
    private $resourceCheckers = [];

    /**
     * @param iterable<int, ResourceCheckerInterface> $resourceCheckers
     */
    public function __construct(iterable $resourceCheckers = [])
    {
        $this->resourceCheckers = $resourceCheckers;
    }

    /**
     * {@inheritdoc}
     */
    public function cache(string $file, callable $callable)
    {
        $cache = new ResourceCheckerConfigCache($file, $this->resourceCheckers);
        if (!$cache->isFresh()) {
            $callable($cache);
        }

        return $cache;
    }
}
PKϤ$Z=y�&config/ConfigCache.phpnu�[���<?php

/*
 * This file is part of the Symfony package.
 *
 * (c) Fabien Potencier <fabien@symfony.com>
 *
 * For the full copyright and license information, please view the LICENSE
 * file that was distributed with this source code.
 */

namespace Symfony\Component\Config;

use Symfony\Component\Config\Resource\SelfCheckingResourceChecker;

/**
 * ConfigCache caches arbitrary content in files on disk.
 *
 * When in debug mode, those metadata resources that implement
 * \Symfony\Component\Config\Resource\SelfCheckingResourceInterface will
 * be used to check cache freshness.
 *
 * @author Fabien Potencier <fabien@symfony.com>
 * @author Matthias Pigulla <mp@webfactory.de>
 */
class ConfigCache extends ResourceCheckerConfigCache
{
    private $debug;

    /**
     * @param string $file  The absolute cache path
     * @param bool   $debug Whether debugging is enabled or not
     */
    public function __construct(string $file, bool $debug)
    {
        $this->debug = $debug;

        $checkers = [];
        if (true === $this->debug) {
            $checkers = [new SelfCheckingResourceChecker()];
        }

        parent::__construct($file, $checkers);
    }

    /**
     * Checks if the cache is still fresh.
     *
     * This implementation always returns true when debug is off and the
     * cache file exists.
     *
     * @return bool
     */
    public function isFresh()
    {
        if (!$this->debug && is_file($this->getPath())) {
            return true;
        }

        return parent::isFresh();
    }
}
PKϤ$Z�u1LL(config/Exception/LoaderLoadException.phpnu�[���<?php

/*
 * This file is part of the Symfony package.
 *
 * (c) Fabien Potencier <fabien@symfony.com>
 *
 * For the full copyright and license information, please view the LICENSE
 * file that was distributed with this source code.
 */

namespace Symfony\Component\Config\Exception;

/**
 * Exception class for when a resource cannot be loaded or imported.
 *
 * @author Ryan Weaver <ryan@thatsquality.com>
 */
class LoaderLoadException extends \Exception
{
    /**
     * @param string          $resource       The resource that could not be imported
     * @param string|null     $sourceResource The original resource importing the new resource
     * @param int|null        $code           The error code
     * @param \Throwable|null $previous       A previous exception
     * @param string|null     $type           The type of resource
     */
    public function __construct(string $resource, string $sourceResource = null, ?int $code = 0, \Throwable $previous = null, string $type = null)
    {
        if (null === $code) {
            trigger_deprecation('symfony/config', '5.3', 'Passing null as $code to "%s()" is deprecated, pass 0 instead.', __METHOD__);

            $code = 0;
        }

        $message = '';
        if ($previous) {
            // Include the previous exception, to help the user see what might be the underlying cause

            // Trim the trailing period of the previous message. We only want 1 period remove so no rtrim...
            if ('.' === substr($previous->getMessage(), -1)) {
                $trimmedMessage = substr($previous->getMessage(), 0, -1);
                $message .= sprintf('%s', $trimmedMessage).' in ';
            } else {
                $message .= sprintf('%s', $previous->getMessage()).' in ';
            }
            $message .= $resource.' ';

            // show tweaked trace to complete the human readable sentence
            if (null === $sourceResource) {
                $message .= sprintf('(which is loaded in resource "%s")', $resource);
            } else {
                $message .= sprintf('(which is being imported from "%s")', $sourceResource);
            }
            $message .= '.';

        // if there's no previous message, present it the default way
        } elseif (null === $sourceResource) {
            $message .= sprintf('Cannot load resource "%s".', $resource);
        } else {
            $message .= sprintf('Cannot import resource "%s" from "%s".', $resource, $sourceResource);
        }

        // Is the resource located inside a bundle?
        if ('@' === $resource[0]) {
            $parts = explode(\DIRECTORY_SEPARATOR, $resource);
            $bundle = substr($parts[0], 1);
            $message .= sprintf(' Make sure the "%s" bundle is correctly registered and loaded in the application kernel class.', $bundle);
            $message .= sprintf(' If the bundle is registered, make sure the bundle path "%s" is not empty.', $resource);
        } elseif (null !== $type) {
            // maybe there is no loader for this specific type
            if ('annotation' === $type) {
                $message .= ' Make sure to use PHP 8+ or that annotations are installed and enabled.';
            } else {
                $message .= sprintf(' Make sure there is a loader supporting the "%s" type.', $type);
            }
        }

        parent::__construct($message, $code, $previous);
    }

    protected function varToString($var)
    {
        if (\is_object($var)) {
            return sprintf('Object(%s)', \get_class($var));
        }

        if (\is_array($var)) {
            $a = [];
            foreach ($var as $k => $v) {
                $a[] = sprintf('%s => %s', $k, $this->varToString($v));
            }

            return sprintf('Array(%s)', implode(', ', $a));
        }

        if (\is_resource($var)) {
            return sprintf('Resource(%s)', get_resource_type($var));
        }

        if (null === $var) {
            return 'null';
        }

        if (false === $var) {
            return 'false';
        }

        if (true === $var) {
            return 'true';
        }

        return (string) $var;
    }
}
PKϤ$Z����
�
,config/Exception/FileLoaderLoadException.phpnu�[���<?php

/*
 * This file is part of the Symfony package.
 *
 * (c) Fabien Potencier <fabien@symfony.com>
 *
 * For the full copyright and license information, please view the LICENSE
 * file that was distributed with this source code.
 */

namespace Symfony\Component\Config\Exception;

/**
 * Exception class for when a resource cannot be loaded or imported.
 *
 * @author Ryan Weaver <ryan@thatsquality.com>
 */
class FileLoaderLoadException extends \Exception
{
    /**
     * @param string     $resource       The resource that could not be imported
     * @param string     $sourceResource The original resource importing the new resource
     * @param int        $code           The error code
     * @param \Exception $previous       A previous exception
     */
    public function __construct($resource, $sourceResource = null, $code = null, $previous = null)
    {
        $message = '';
        if ($previous) {
            // Include the previous exception, to help the user see what might be the underlying cause

            // Trim the trailing period of the previous message. We only want 1 period remove so no rtrim...
            if ('.' === substr($previous->getMessage(), -1)) {
                $trimmedMessage = substr($previous->getMessage(), 0, -1);
                $message .= sprintf('%s', $trimmedMessage).' in ';
            } else {
                $message .= sprintf('%s', $previous->getMessage()).' in ';
            }
            $message .= $resource.' ';

            // show tweaked trace to complete the human readable sentence
            if (null === $sourceResource) {
                $message .= sprintf('(which is loaded in resource "%s")', $this->varToString($resource));
            } else {
                $message .= sprintf('(which is being imported from "%s")', $this->varToString($sourceResource));
            }
            $message .= '.';

        // if there's no previous message, present it the default way
        } elseif (null === $sourceResource) {
            $message .= sprintf('Cannot load resource "%s".', $this->varToString($resource));
        } else {
            $message .= sprintf('Cannot import resource "%s" from "%s".', $this->varToString($resource), $this->varToString($sourceResource));
        }

        // Is the resource located inside a bundle?
        if ('@' === $resource[0]) {
            $parts = explode(DIRECTORY_SEPARATOR, $resource);
            $bundle = substr($parts[0], 1);
            $message .= sprintf(' Make sure the "%s" bundle is correctly registered and loaded in the application kernel class.', $bundle);
            $message .= sprintf(' If the bundle is registered, make sure the bundle path "%s" is not empty.', $resource);
        }

        parent::__construct($message, $code, $previous);
    }

    protected function varToString($var)
    {
        if (is_object($var)) {
            return sprintf('Object(%s)', get_class($var));
        }

        if (is_array($var)) {
            $a = array();
            foreach ($var as $k => $v) {
                $a[] = sprintf('%s => %s', $k, $this->varToString($v));
            }

            return sprintf('Array(%s)', implode(', ', $a));
        }

        if (is_resource($var)) {
            return sprintf('Resource(%s)', get_resource_type($var));
        }

        if (null === $var) {
            return 'null';
        }

        if (false === $var) {
            return 'false';
        }

        if (true === $var) {
            return 'true';
        }

        return (string) $var;
    }
}
PKϤ$Z3	��5config/Exception/FileLocatorFileNotFoundException.phpnu�[���<?php

/*
 * This file is part of the Symfony package.
 *
 * (c) Fabien Potencier <fabien@symfony.com>
 *
 * For the full copyright and license information, please view the LICENSE
 * file that was distributed with this source code.
 */

namespace Symfony\Component\Config\Exception;

/**
 * File locator exception if a file does not exist.
 *
 * @author Leo Feyer <https://github.com/leofeyer>
 */
class FileLocatorFileNotFoundException extends \InvalidArgumentException
{
    private $paths;

    public function __construct(string $message = '', int $code = 0, \Throwable $previous = null, array $paths = [])
    {
        parent::__construct($message, $code, $previous);

        $this->paths = $paths;
    }

    public function getPaths()
    {
        return $this->paths;
    }
}
PKϤ$Z4z��?config/Exception/FileLoaderImportCircularReferenceException.phpnu�[���<?php

/*
 * This file is part of the Symfony package.
 *
 * (c) Fabien Potencier <fabien@symfony.com>
 *
 * For the full copyright and license information, please view the LICENSE
 * file that was distributed with this source code.
 */

namespace Symfony\Component\Config\Exception;

/**
 * Exception class for when a circular reference is detected when importing resources.
 *
 * @author Fabien Potencier <fabien@symfony.com>
 */
class FileLoaderImportCircularReferenceException extends LoaderLoadException
{
    public function __construct(array $resources, ?int $code = 0, \Throwable $previous = null)
    {
        if (null === $code) {
            trigger_deprecation('symfony/config', '5.3', 'Passing null as $code to "%s()" is deprecated, pass 0 instead.', __METHOD__);

            $code = 0;
        }

        $message = sprintf('Circular reference detected in "%s" ("%s" > "%s").', $this->varToString($resources[0]), implode('" > "', $resources), $resources[0]);

        \Exception::__construct($message, $code, $previous);
    }
}
PKϤ$ZJXN�!!config/FileLocatorInterface.phpnu�[���<?php

/*
 * This file is part of the Symfony package.
 *
 * (c) Fabien Potencier <fabien@symfony.com>
 *
 * For the full copyright and license information, please view the LICENSE
 * file that was distributed with this source code.
 */

namespace Symfony\Component\Config;

use Symfony\Component\Config\Exception\FileLocatorFileNotFoundException;

/**
 * @author Fabien Potencier <fabien@symfony.com>
 */
interface FileLocatorInterface
{
    /**
     * Returns a full path for a given file name.
     *
     * @param string      $name        The file name to locate
     * @param string|null $currentPath The current path
     * @param bool        $first       Whether to return the first occurrence or an array of filenames
     *
     * @return string|array The full path to the file or an array of file paths
     *
     * @throws \InvalidArgumentException        If $name is empty
     * @throws FileLocatorFileNotFoundException If a file is not found
     */
    public function locate(string $name, string $currentPath = null, bool $first = true);
}
PKϤ$ZQyȋ�config/CHANGELOG.mdnu�[���CHANGELOG
=========

5.3.0
-----

 * Add support for generating `ConfigBuilder` for extensions

5.1.0
-----

 * updated the signature of method `NodeDefinition::setDeprecated()` to `NodeDefinition::setDeprecation(string $package, string $version, string $message)`
 * updated the signature of method `BaseNode::setDeprecated()` to `BaseNode::setDeprecation(string $package, string $version, string $message)`
 * deprecated passing a null message to `BaseNode::setDeprecated()` to un-deprecate a node
 * deprecated `BaseNode::getDeprecationMessage()`, use `BaseNode::getDeprecation()` instead

5.0.0
-----

 * Dropped support for constructing a `TreeBuilder` without passing root node information.
 * Removed the `root()` method in `TreeBuilder`, pass the root node information to the constructor instead
 * Added method `getChildNodeDefinitions()` to ParentNodeDefinitionInterface
 * Removed `FileLoaderLoadException`, use `LoaderLoadException` instead

4.4.0
-----

 * added a way to exclude patterns of resources from being imported by the `import()` method

4.3.0
-----

 * deprecated using environment variables with `cannotBeEmpty()` if the value is validated with `validate()`
 * made `Resource\*` classes final and not implement `Serializable` anymore
 * deprecated the `root()` method in `TreeBuilder`, pass the root node information to the constructor instead

4.2.0
-----

 * deprecated constructing a `TreeBuilder` without passing root node information
 * renamed `FileLoaderLoadException` to `LoaderLoadException`

4.1.0
-----

 * added `setPathSeparator` method to `NodeBuilder` class
 * added third `$pathSeparator` constructor argument to `BaseNode`
 * the `Processor` class has been made final

4.0.0
-----

 * removed `ConfigCachePass`

3.4.0
-----

 * added `setDeprecated()` method to indicate a deprecated node
 * added `XmlUtils::parse()` method to parse an XML string
 * deprecated `ConfigCachePass`

3.3.0
-----

 * added `ReflectionClassResource` class
 * added second `$exists` constructor argument to `ClassExistenceResource`
 * made `ClassExistenceResource` work with interfaces and traits
 * added `ConfigCachePass` (originally in FrameworkBundle)
 * added `castToArray()` helper to turn any config value into an array

3.0.0
-----

 * removed `ReferenceDumper` class
 * removed the `ResourceInterface::isFresh()` method
 * removed `BCResourceInterfaceChecker` class
 * removed `ResourceInterface::getResource()` method

2.8.0
-----

The edge case of defining just one value for nodes of type Enum is now allowed:

```php
$rootNode
    ->children()
        ->enumNode('variable')
            ->values(['value'])
        ->end()
    ->end()
;
```

Before: `InvalidArgumentException` (variable must contain at least two
distinct elements).
After: the code will work as expected and it will restrict the values of the
`variable` option to just `value`.

 * deprecated the `ResourceInterface::isFresh()` method. If you implement custom resource types and they
   can be validated that way, make them implement the new `SelfCheckingResourceInterface`.
 * deprecated the getResource() method in ResourceInterface. You can still call this method
   on concrete classes implementing the interface, but it does not make sense at the interface
   level as you need to know about the particular type of resource at hand to understand the
   semantics of the returned value.

2.7.0
-----

 * added `ConfigCacheInterface`, `ConfigCacheFactoryInterface` and a basic `ConfigCacheFactory`
   implementation to delegate creation of ConfigCache instances

2.2.0
-----

 * added `ArrayNodeDefinition::canBeEnabled()` and `ArrayNodeDefinition::canBeDisabled()`
   to ease configuration when some sections are respectively disabled / enabled
   by default.
 * added a `normalizeKeys()` method for array nodes (to avoid key normalization)
 * added numerical type handling for config definitions
 * added convenience methods for optional configuration sections to `ArrayNodeDefinition`
 * added a utils class for XML manipulations

2.1.0
-----

 * added a way to add documentation on configuration
 * implemented `Serializable` on resources
 * `LoaderResolverInterface` is now used instead of `LoaderResolver` for type
   hinting
PKϤ$Za�x))config/LICENSEnu�[���Copyright (c) 2004-2022 Fabien Potencier

Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is furnished
to do so, subject to the following conditions:

The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.

THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
THE SOFTWARE.
PKϤ$ZC{H ��%config/ResourceCheckerConfigCache.phpnu�[���<?php

/*
 * This file is part of the Symfony package.
 *
 * (c) Fabien Potencier <fabien@symfony.com>
 *
 * For the full copyright and license information, please view the LICENSE
 * file that was distributed with this source code.
 */

namespace Symfony\Component\Config;

use Symfony\Component\Config\Resource\ResourceInterface;
use Symfony\Component\Filesystem\Exception\IOException;
use Symfony\Component\Filesystem\Filesystem;

/**
 * ResourceCheckerConfigCache uses instances of ResourceCheckerInterface
 * to check whether cached data is still fresh.
 *
 * @author Matthias Pigulla <mp@webfactory.de>
 */
class ResourceCheckerConfigCache implements ConfigCacheInterface
{
    /**
     * @var string
     */
    private $file;

    /**
     * @var iterable<mixed, ResourceCheckerInterface>
     */
    private $resourceCheckers;

    /**
     * @param string                                    $file             The absolute cache path
     * @param iterable<mixed, ResourceCheckerInterface> $resourceCheckers The ResourceCheckers to use for the freshness check
     */
    public function __construct(string $file, iterable $resourceCheckers = [])
    {
        $this->file = $file;
        $this->resourceCheckers = $resourceCheckers;
    }

    /**
     * {@inheritdoc}
     */
    public function getPath()
    {
        return $this->file;
    }

    /**
     * Checks if the cache is still fresh.
     *
     * This implementation will make a decision solely based on the ResourceCheckers
     * passed in the constructor.
     *
     * The first ResourceChecker that supports a given resource is considered authoritative.
     * Resources with no matching ResourceChecker will silently be ignored and considered fresh.
     *
     * @return bool
     */
    public function isFresh()
    {
        if (!is_file($this->file)) {
            return false;
        }

        if ($this->resourceCheckers instanceof \Traversable && !$this->resourceCheckers instanceof \Countable) {
            $this->resourceCheckers = iterator_to_array($this->resourceCheckers);
        }

        if (!\count($this->resourceCheckers)) {
            return true; // shortcut - if we don't have any checkers we don't need to bother with the meta file at all
        }

        $metadata = $this->getMetaFile();

        if (!is_file($metadata)) {
            return false;
        }

        $meta = $this->safelyUnserialize($metadata);

        if (false === $meta) {
            return false;
        }

        $time = filemtime($this->file);

        foreach ($meta as $resource) {
            foreach ($this->resourceCheckers as $checker) {
                if (!$checker->supports($resource)) {
                    continue; // next checker
                }
                if ($checker->isFresh($resource, $time)) {
                    break; // no need to further check this resource
                }

                return false; // cache is stale
            }
            // no suitable checker found, ignore this resource
        }

        return true;
    }

    /**
     * Writes cache.
     *
     * @param string              $content  The content to write in the cache
     * @param ResourceInterface[] $metadata An array of metadata
     *
     * @throws \RuntimeException When cache file can't be written
     */
    public function write(string $content, array $metadata = null)
    {
        $mode = 0666;
        $umask = umask();
        $filesystem = new Filesystem();
        $filesystem->dumpFile($this->file, $content);
        try {
            $filesystem->chmod($this->file, $mode, $umask);
        } catch (IOException $e) {
            // discard chmod failure (some filesystem may not support it)
        }

        if (null !== $metadata) {
            $filesystem->dumpFile($this->getMetaFile(), serialize($metadata));
            try {
                $filesystem->chmod($this->getMetaFile(), $mode, $umask);
            } catch (IOException $e) {
                // discard chmod failure (some filesystem may not support it)
            }
        }

        if (\function_exists('opcache_invalidate') && filter_var(ini_get('opcache.enable'), \FILTER_VALIDATE_BOOLEAN)) {
            @opcache_invalidate($this->file, true);
        }
    }

    /**
     * Gets the meta file path.
     */
    private function getMetaFile(): string
    {
        return $this->file.'.meta';
    }

    private function safelyUnserialize(string $file)
    {
        $meta = false;
        $content = file_get_contents($file);
        $signalingException = new \UnexpectedValueException();
        $prevUnserializeHandler = ini_set('unserialize_callback_func', self::class.'::handleUnserializeCallback');
        $prevErrorHandler = set_error_handler(function ($type, $msg, $file, $line, $context = []) use (&$prevErrorHandler, $signalingException) {
            if (__FILE__ === $file) {
                throw $signalingException;
            }

            return $prevErrorHandler ? $prevErrorHandler($type, $msg, $file, $line, $context) : false;
        });

        try {
            $meta = unserialize($content);
        } catch (\Throwable $e) {
            if ($e !== $signalingException) {
                throw $e;
            }
        } finally {
            restore_error_handler();
            ini_set('unserialize_callback_func', $prevUnserializeHandler);
        }

        return $meta;
    }

    /**
     * @internal
     */
    public static function handleUnserializeCallback(string $class)
    {
        trigger_error('Class not found: '.$class);
    }
}
PKϤ$Z9t6QQconfig/ConfigCacheFactory.phpnu�[���<?php

/*
 * This file is part of the Symfony package.
 *
 * (c) Fabien Potencier <fabien@symfony.com>
 *
 * For the full copyright and license information, please view the LICENSE
 * file that was distributed with this source code.
 */

namespace Symfony\Component\Config;

/**
 * Basic implementation of ConfigCacheFactoryInterface that
 * creates an instance of the default ConfigCache.
 *
 * This factory and/or cache <em>do not</em> support cache validation
 * by means of ResourceChecker instances (that is, service-based).
 *
 * @author Matthias Pigulla <mp@webfactory.de>
 */
class ConfigCacheFactory implements ConfigCacheFactoryInterface
{
    private $debug;

    /**
     * @param bool $debug The debug flag to pass to ConfigCache
     */
    public function __construct(bool $debug)
    {
        $this->debug = $debug;
    }

    /**
     * {@inheritdoc}
     */
    public function cache(string $file, callable $callback)
    {
        $cache = new ConfigCache($file, $this->debug);
        if (!$cache->isFresh()) {
            $callback($cache);
        }

        return $cache;
    }
}
PKϤ$ZXѥ;�	�	config/FileLocator.phpnu�[���<?php

/*
 * This file is part of the Symfony package.
 *
 * (c) Fabien Potencier <fabien@symfony.com>
 *
 * For the full copyright and license information, please view the LICENSE
 * file that was distributed with this source code.
 */

namespace Symfony\Component\Config;

use Symfony\Component\Config\Exception\FileLocatorFileNotFoundException;

/**
 * FileLocator uses an array of pre-defined paths to find files.
 *
 * @author Fabien Potencier <fabien@symfony.com>
 */
class FileLocator implements FileLocatorInterface
{
    protected $paths;

    /**
     * @param string|string[] $paths A path or an array of paths where to look for resources
     */
    public function __construct($paths = [])
    {
        $this->paths = (array) $paths;
    }

    /**
     * {@inheritdoc}
     */
    public function locate(string $name, string $currentPath = null, bool $first = true)
    {
        if ('' === $name) {
            throw new \InvalidArgumentException('An empty file name is not valid to be located.');
        }

        if ($this->isAbsolutePath($name)) {
            if (!file_exists($name)) {
                throw new FileLocatorFileNotFoundException(sprintf('The file "%s" does not exist.', $name), 0, null, [$name]);
            }

            return $name;
        }

        $paths = $this->paths;

        if (null !== $currentPath) {
            array_unshift($paths, $currentPath);
        }

        $paths = array_unique($paths);
        $filepaths = $notfound = [];

        foreach ($paths as $path) {
            if (@file_exists($file = $path.\DIRECTORY_SEPARATOR.$name)) {
                if (true === $first) {
                    return $file;
                }
                $filepaths[] = $file;
            } else {
                $notfound[] = $file;
            }
        }

        if (!$filepaths) {
            throw new FileLocatorFileNotFoundException(sprintf('The file "%s" does not exist (in: "%s").', $name, implode('", "', $paths)), 0, null, $notfound);
        }

        return $filepaths;
    }

    /**
     * Returns whether the file path is an absolute path.
     */
    private function isAbsolutePath(string $file): bool
    {
        if ('/' === $file[0] || '\\' === $file[0]
            || (\strlen($file) > 3 && ctype_alpha($file[0])
                && ':' === $file[1]
                && ('\\' === $file[2] || '/' === $file[2])
            )
            || null !== parse_url($file, \PHP_URL_SCHEME)
        ) {
            return true;
        }

        return false;
    }
}
PKϤ$Zι7��#config/ResourceCheckerInterface.phpnu�[���<?php

/*
 * This file is part of the Symfony package.
 *
 * (c) Fabien Potencier <fabien@symfony.com>
 *
 * For the full copyright and license information, please view the LICENSE
 * file that was distributed with this source code.
 */

namespace Symfony\Component\Config;

use Symfony\Component\Config\Resource\ResourceInterface;

/**
 * Interface for ResourceCheckers.
 *
 * When a ResourceCheckerConfigCache instance is checked for freshness, all its associated
 * metadata resources are passed to ResourceCheckers. The ResourceCheckers
 * can then inspect the resources and decide whether the cache can be considered
 * fresh or not.
 *
 * @author Matthias Pigulla <mp@webfactory.de>
 * @author Benjamin Klotz <bk@webfactory.de>
 */
interface ResourceCheckerInterface
{
    /**
     * Queries the ResourceChecker whether it can validate a given
     * resource or not.
     *
     * @return bool
     */
    public function supports(ResourceInterface $metadata);

    /**
     * Validates the resource.
     *
     * @param int $timestamp The timestamp at which the cache associated with this resource was created
     *
     * @return bool
     */
    public function isFresh(ResourceInterface $resource, int $timestamp);
}
PKϤ$Z���"polyfill-intl-normalizer/README.mdnu�[���Symfony Polyfill / Intl: Normalizer
===================================

This component provides a fallback implementation for the
[`Normalizer`](https://php.net/Normalizer) class provided
by the [Intl](https://php.net/intl) extension.

More information can be found in the
[main Polyfill README](https://github.com/symfony/polyfill/blob/master/README.md).

License
=======

This library is released under the [MIT license](LICENSE).
PKϤ$Z�ݮ�QQ7polyfill-intl-normalizer/Resources/stubs/Normalizer.phpnu�[���<?php

class Normalizer extends Symfony\Polyfill\Intl\Normalizer\Normalizer
{
    /**
     * @deprecated since ICU 56 and removed in PHP 8
     */
    const NONE = 1;
    const FORM_D = 2;
    const FORM_KD = 3;
    const FORM_C = 4;
    const FORM_KC = 5;
    const NFD = 2;
    const NFKD = 3;
    const NFC = 4;
    const NFKC = 5;
}
PKϤ$Zc�,�ooIpolyfill-intl-normalizer/Resources/unidata/compatibilityDecomposition.phpnu�[���<?php

return array (
  ' ' => ' ',
  '¨' => ' ̈',
  'ª' => 'a',
  '¯' => ' ̄',
  '²' => '2',
  '³' => '3',
  '´' => ' ́',
  'µ' => 'μ',
  '¸' => ' ̧',
  '¹' => '1',
  'º' => 'o',
  '¼' => '1⁄4',
  '½' => '1⁄2',
  '¾' => '3⁄4',
  'IJ' => 'IJ',
  'ij' => 'ij',
  'Ŀ' => 'L·',
  'ŀ' => 'l·',
  'ʼn' => 'ʼn',
  'ſ' => 's',
  'DŽ' => 'DŽ',
  'Dž' => 'Dž',
  'dž' => 'dž',
  'LJ' => 'LJ',
  'Lj' => 'Lj',
  'lj' => 'lj',
  'NJ' => 'NJ',
  'Nj' => 'Nj',
  'nj' => 'nj',
  'DZ' => 'DZ',
  'Dz' => 'Dz',
  'dz' => 'dz',
  'ʰ' => 'h',
  'ʱ' => 'ɦ',
  'ʲ' => 'j',
  'ʳ' => 'r',
  'ʴ' => 'ɹ',
  'ʵ' => 'ɻ',
  'ʶ' => 'ʁ',
  'ʷ' => 'w',
  'ʸ' => 'y',
  '˘' => ' ̆',
  '˙' => ' ̇',
  '˚' => ' ̊',
  '˛' => ' ̨',
  '˜' => ' ̃',
  '˝' => ' ̋',
  'ˠ' => 'ɣ',
  'ˡ' => 'l',
  'ˢ' => 's',
  'ˣ' => 'x',
  'ˤ' => 'ʕ',
  'ͺ' => ' ͅ',
  '΄' => ' ́',
  '΅' => ' ̈́',
  'ϐ' => 'β',
  'ϑ' => 'θ',
  'ϒ' => 'Υ',
  'ϓ' => 'Ύ',
  'ϔ' => 'Ϋ',
  'ϕ' => 'φ',
  'ϖ' => 'π',
  'ϰ' => 'κ',
  'ϱ' => 'ρ',
  'ϲ' => 'ς',
  'ϴ' => 'Θ',
  'ϵ' => 'ε',
  'Ϲ' => 'Σ',
  'և' => 'եւ',
  'ٵ' => 'اٴ',
  'ٶ' => 'وٴ',
  'ٷ' => 'ۇٴ',
  'ٸ' => 'يٴ',
  'ำ' => 'ํา',
  'ຳ' => 'ໍາ',
  'ໜ' => 'ຫນ',
  'ໝ' => 'ຫມ',
  '༌' => '་',
  'ཷ' => 'ྲཱྀ',
  'ཹ' => 'ླཱྀ',
  'ჼ' => 'ნ',
  'ᴬ' => 'A',
  'ᴭ' => 'Æ',
  'ᴮ' => 'B',
  'ᴰ' => 'D',
  'ᴱ' => 'E',
  'ᴲ' => 'Ǝ',
  'ᴳ' => 'G',
  'ᴴ' => 'H',
  'ᴵ' => 'I',
  'ᴶ' => 'J',
  'ᴷ' => 'K',
  'ᴸ' => 'L',
  'ᴹ' => 'M',
  'ᴺ' => 'N',
  'ᴼ' => 'O',
  'ᴽ' => 'Ȣ',
  'ᴾ' => 'P',
  'ᴿ' => 'R',
  'ᵀ' => 'T',
  'ᵁ' => 'U',
  'ᵂ' => 'W',
  'ᵃ' => 'a',
  'ᵄ' => 'ɐ',
  'ᵅ' => 'ɑ',
  'ᵆ' => 'ᴂ',
  'ᵇ' => 'b',
  'ᵈ' => 'd',
  'ᵉ' => 'e',
  'ᵊ' => 'ə',
  'ᵋ' => 'ɛ',
  'ᵌ' => 'ɜ',
  'ᵍ' => 'g',
  'ᵏ' => 'k',
  'ᵐ' => 'm',
  'ᵑ' => 'ŋ',
  'ᵒ' => 'o',
  'ᵓ' => 'ɔ',
  'ᵔ' => 'ᴖ',
  'ᵕ' => 'ᴗ',
  'ᵖ' => 'p',
  'ᵗ' => 't',
  'ᵘ' => 'u',
  'ᵙ' => 'ᴝ',
  'ᵚ' => 'ɯ',
  'ᵛ' => 'v',
  'ᵜ' => 'ᴥ',
  'ᵝ' => 'β',
  'ᵞ' => 'γ',
  'ᵟ' => 'δ',
  'ᵠ' => 'φ',
  'ᵡ' => 'χ',
  'ᵢ' => 'i',
  'ᵣ' => 'r',
  'ᵤ' => 'u',
  'ᵥ' => 'v',
  'ᵦ' => 'β',
  'ᵧ' => 'γ',
  'ᵨ' => 'ρ',
  'ᵩ' => 'φ',
  'ᵪ' => 'χ',
  'ᵸ' => 'н',
  'ᶛ' => 'ɒ',
  'ᶜ' => 'c',
  'ᶝ' => 'ɕ',
  'ᶞ' => 'ð',
  'ᶟ' => 'ɜ',
  'ᶠ' => 'f',
  'ᶡ' => 'ɟ',
  'ᶢ' => 'ɡ',
  'ᶣ' => 'ɥ',
  'ᶤ' => 'ɨ',
  'ᶥ' => 'ɩ',
  'ᶦ' => 'ɪ',
  'ᶧ' => 'ᵻ',
  'ᶨ' => 'ʝ',
  'ᶩ' => 'ɭ',
  'ᶪ' => 'ᶅ',
  'ᶫ' => 'ʟ',
  'ᶬ' => 'ɱ',
  'ᶭ' => 'ɰ',
  'ᶮ' => 'ɲ',
  'ᶯ' => 'ɳ',
  'ᶰ' => 'ɴ',
  'ᶱ' => 'ɵ',
  'ᶲ' => 'ɸ',
  'ᶳ' => 'ʂ',
  'ᶴ' => 'ʃ',
  'ᶵ' => 'ƫ',
  'ᶶ' => 'ʉ',
  'ᶷ' => 'ʊ',
  'ᶸ' => 'ᴜ',
  'ᶹ' => 'ʋ',
  'ᶺ' => 'ʌ',
  'ᶻ' => 'z',
  'ᶼ' => 'ʐ',
  'ᶽ' => 'ʑ',
  'ᶾ' => 'ʒ',
  'ᶿ' => 'θ',
  'ẚ' => 'aʾ',
  'ẛ' => 'ṡ',
  '᾽' => ' ̓',
  '᾿' => ' ̓',
  '῀' => ' ͂',
  '῁' => ' ̈͂',
  '῍' => ' ̓̀',
  '῎' => ' ̓́',
  '῏' => ' ̓͂',
  '῝' => ' ̔̀',
  '῞' => ' ̔́',
  '῟' => ' ̔͂',
  '῭' => ' ̈̀',
  '΅' => ' ̈́',
  '´' => ' ́',
  '῾' => ' ̔',
  ' ' => ' ',
  ' ' => ' ',
  ' ' => ' ',
  ' ' => ' ',
  ' ' => ' ',
  ' ' => ' ',
  ' ' => ' ',
  ' ' => ' ',
  ' ' => ' ',
  ' ' => ' ',
  ' ' => ' ',
  '‑' => '‐',
  '‗' => ' ̳',
  '․' => '.',
  '‥' => '..',
  '…' => '...',
  ' ' => ' ',
  '″' => '′′',
  '‴' => '′′′',
  '‶' => '‵‵',
  '‷' => '‵‵‵',
  '‼' => '!!',
  '‾' => ' ̅',
  '⁇' => '??',
  '⁈' => '?!',
  '⁉' => '!?',
  '⁗' => '′′′′',
  ' ' => ' ',
  '⁰' => '0',
  'ⁱ' => 'i',
  '⁴' => '4',
  '⁵' => '5',
  '⁶' => '6',
  '⁷' => '7',
  '⁸' => '8',
  '⁹' => '9',
  '⁺' => '+',
  '⁻' => '−',
  '⁼' => '=',
  '⁽' => '(',
  '⁾' => ')',
  'ⁿ' => 'n',
  '₀' => '0',
  '₁' => '1',
  '₂' => '2',
  '₃' => '3',
  '₄' => '4',
  '₅' => '5',
  '₆' => '6',
  '₇' => '7',
  '₈' => '8',
  '₉' => '9',
  '₊' => '+',
  '₋' => '−',
  '₌' => '=',
  '₍' => '(',
  '₎' => ')',
  'ₐ' => 'a',
  'ₑ' => 'e',
  'ₒ' => 'o',
  'ₓ' => 'x',
  'ₔ' => 'ə',
  'ₕ' => 'h',
  'ₖ' => 'k',
  'ₗ' => 'l',
  'ₘ' => 'm',
  'ₙ' => 'n',
  'ₚ' => 'p',
  'ₛ' => 's',
  'ₜ' => 't',
  '₨' => 'Rs',
  '℀' => 'a/c',
  '℁' => 'a/s',
  'ℂ' => 'C',
  '℃' => '°C',
  '℅' => 'c/o',
  '℆' => 'c/u',
  'ℇ' => 'Ɛ',
  '℉' => '°F',
  'ℊ' => 'g',
  'ℋ' => 'H',
  'ℌ' => 'H',
  'ℍ' => 'H',
  'ℎ' => 'h',
  'ℏ' => 'ħ',
  'ℐ' => 'I',
  'ℑ' => 'I',
  'ℒ' => 'L',
  'ℓ' => 'l',
  'ℕ' => 'N',
  '№' => 'No',
  'ℙ' => 'P',
  'ℚ' => 'Q',
  'ℛ' => 'R',
  'ℜ' => 'R',
  'ℝ' => 'R',
  '℠' => 'SM',
  '℡' => 'TEL',
  '™' => 'TM',
  'ℤ' => 'Z',
  'ℨ' => 'Z',
  'ℬ' => 'B',
  'ℭ' => 'C',
  'ℯ' => 'e',
  'ℰ' => 'E',
  'ℱ' => 'F',
  'ℳ' => 'M',
  'ℴ' => 'o',
  'ℵ' => 'א',
  'ℶ' => 'ב',
  'ℷ' => 'ג',
  'ℸ' => 'ד',
  'ℹ' => 'i',
  '℻' => 'FAX',
  'ℼ' => 'π',
  'ℽ' => 'γ',
  'ℾ' => 'Γ',
  'ℿ' => 'Π',
  '⅀' => '∑',
  'ⅅ' => 'D',
  'ⅆ' => 'd',
  'ⅇ' => 'e',
  'ⅈ' => 'i',
  'ⅉ' => 'j',
  '⅐' => '1⁄7',
  '⅑' => '1⁄9',
  '⅒' => '1⁄10',
  '⅓' => '1⁄3',
  '⅔' => '2⁄3',
  '⅕' => '1⁄5',
  '⅖' => '2⁄5',
  '⅗' => '3⁄5',
  '⅘' => '4⁄5',
  '⅙' => '1⁄6',
  '⅚' => '5⁄6',
  '⅛' => '1⁄8',
  '⅜' => '3⁄8',
  '⅝' => '5⁄8',
  '⅞' => '7⁄8',
  '⅟' => '1⁄',
  'Ⅰ' => 'I',
  'Ⅱ' => 'II',
  'Ⅲ' => 'III',
  'Ⅳ' => 'IV',
  'Ⅴ' => 'V',
  'Ⅵ' => 'VI',
  'Ⅶ' => 'VII',
  'Ⅷ' => 'VIII',
  'Ⅸ' => 'IX',
  'Ⅹ' => 'X',
  'Ⅺ' => 'XI',
  'Ⅻ' => 'XII',
  'Ⅼ' => 'L',
  'Ⅽ' => 'C',
  'Ⅾ' => 'D',
  'Ⅿ' => 'M',
  'ⅰ' => 'i',
  'ⅱ' => 'ii',
  'ⅲ' => 'iii',
  'ⅳ' => 'iv',
  'ⅴ' => 'v',
  'ⅵ' => 'vi',
  'ⅶ' => 'vii',
  'ⅷ' => 'viii',
  'ⅸ' => 'ix',
  'ⅹ' => 'x',
  'ⅺ' => 'xi',
  'ⅻ' => 'xii',
  'ⅼ' => 'l',
  'ⅽ' => 'c',
  'ⅾ' => 'd',
  'ⅿ' => 'm',
  '↉' => '0⁄3',
  '∬' => '∫∫',
  '∭' => '∫∫∫',
  '∯' => '∮∮',
  '∰' => '∮∮∮',
  '①' => '1',
  '②' => '2',
  '③' => '3',
  '④' => '4',
  '⑤' => '5',
  '⑥' => '6',
  '⑦' => '7',
  '⑧' => '8',
  '⑨' => '9',
  '⑩' => '10',
  '⑪' => '11',
  '⑫' => '12',
  '⑬' => '13',
  '⑭' => '14',
  '⑮' => '15',
  '⑯' => '16',
  '⑰' => '17',
  '⑱' => '18',
  '⑲' => '19',
  '⑳' => '20',
  '⑴' => '(1)',
  '⑵' => '(2)',
  '⑶' => '(3)',
  '⑷' => '(4)',
  '⑸' => '(5)',
  '⑹' => '(6)',
  '⑺' => '(7)',
  '⑻' => '(8)',
  '⑼' => '(9)',
  '⑽' => '(10)',
  '⑾' => '(11)',
  '⑿' => '(12)',
  '⒀' => '(13)',
  '⒁' => '(14)',
  '⒂' => '(15)',
  '⒃' => '(16)',
  '⒄' => '(17)',
  '⒅' => '(18)',
  '⒆' => '(19)',
  '⒇' => '(20)',
  '⒈' => '1.',
  '⒉' => '2.',
  '⒊' => '3.',
  '⒋' => '4.',
  '⒌' => '5.',
  '⒍' => '6.',
  '⒎' => '7.',
  '⒏' => '8.',
  '⒐' => '9.',
  '⒑' => '10.',
  '⒒' => '11.',
  '⒓' => '12.',
  '⒔' => '13.',
  '⒕' => '14.',
  '⒖' => '15.',
  '⒗' => '16.',
  '⒘' => '17.',
  '⒙' => '18.',
  '⒚' => '19.',
  '⒛' => '20.',
  '⒜' => '(a)',
  '⒝' => '(b)',
  '⒞' => '(c)',
  '⒟' => '(d)',
  '⒠' => '(e)',
  '⒡' => '(f)',
  '⒢' => '(g)',
  '⒣' => '(h)',
  '⒤' => '(i)',
  '⒥' => '(j)',
  '⒦' => '(k)',
  '⒧' => '(l)',
  '⒨' => '(m)',
  '⒩' => '(n)',
  '⒪' => '(o)',
  '⒫' => '(p)',
  '⒬' => '(q)',
  '⒭' => '(r)',
  '⒮' => '(s)',
  '⒯' => '(t)',
  '⒰' => '(u)',
  '⒱' => '(v)',
  '⒲' => '(w)',
  '⒳' => '(x)',
  '⒴' => '(y)',
  '⒵' => '(z)',
  'Ⓐ' => 'A',
  'Ⓑ' => 'B',
  'Ⓒ' => 'C',
  'Ⓓ' => 'D',
  'Ⓔ' => 'E',
  'Ⓕ' => 'F',
  'Ⓖ' => 'G',
  'Ⓗ' => 'H',
  'Ⓘ' => 'I',
  'Ⓙ' => 'J',
  'Ⓚ' => 'K',
  'Ⓛ' => 'L',
  'Ⓜ' => 'M',
  'Ⓝ' => 'N',
  'Ⓞ' => 'O',
  'Ⓟ' => 'P',
  'Ⓠ' => 'Q',
  'Ⓡ' => 'R',
  'Ⓢ' => 'S',
  'Ⓣ' => 'T',
  'Ⓤ' => 'U',
  'Ⓥ' => 'V',
  'Ⓦ' => 'W',
  'Ⓧ' => 'X',
  'Ⓨ' => 'Y',
  'Ⓩ' => 'Z',
  'ⓐ' => 'a',
  'ⓑ' => 'b',
  'ⓒ' => 'c',
  'ⓓ' => 'd',
  'ⓔ' => 'e',
  'ⓕ' => 'f',
  'ⓖ' => 'g',
  'ⓗ' => 'h',
  'ⓘ' => 'i',
  'ⓙ' => 'j',
  'ⓚ' => 'k',
  'ⓛ' => 'l',
  'ⓜ' => 'm',
  'ⓝ' => 'n',
  'ⓞ' => 'o',
  'ⓟ' => 'p',
  'ⓠ' => 'q',
  'ⓡ' => 'r',
  'ⓢ' => 's',
  'ⓣ' => 't',
  'ⓤ' => 'u',
  'ⓥ' => 'v',
  'ⓦ' => 'w',
  'ⓧ' => 'x',
  'ⓨ' => 'y',
  'ⓩ' => 'z',
  '⓪' => '0',
  '⨌' => '∫∫∫∫',
  '⩴' => '::=',
  '⩵' => '==',
  '⩶' => '===',
  'ⱼ' => 'j',
  'ⱽ' => 'V',
  'ⵯ' => 'ⵡ',
  '⺟' => '母',
  '⻳' => '龟',
  '⼀' => '一',
  '⼁' => '丨',
  '⼂' => '丶',
  '⼃' => '丿',
  '⼄' => '乙',
  '⼅' => '亅',
  '⼆' => '二',
  '⼇' => '亠',
  '⼈' => '人',
  '⼉' => '儿',
  '⼊' => '入',
  '⼋' => '八',
  '⼌' => '冂',
  '⼍' => '冖',
  '⼎' => '冫',
  '⼏' => '几',
  '⼐' => '凵',
  '⼑' => '刀',
  '⼒' => '力',
  '⼓' => '勹',
  '⼔' => '匕',
  '⼕' => '匚',
  '⼖' => '匸',
  '⼗' => '十',
  '⼘' => '卜',
  '⼙' => '卩',
  '⼚' => '厂',
  '⼛' => '厶',
  '⼜' => '又',
  '⼝' => '口',
  '⼞' => '囗',
  '⼟' => '土',
  '⼠' => '士',
  '⼡' => '夂',
  '⼢' => '夊',
  '⼣' => '夕',
  '⼤' => '大',
  '⼥' => '女',
  '⼦' => '子',
  '⼧' => '宀',
  '⼨' => '寸',
  '⼩' => '小',
  '⼪' => '尢',
  '⼫' => '尸',
  '⼬' => '屮',
  '⼭' => '山',
  '⼮' => '巛',
  '⼯' => '工',
  '⼰' => '己',
  '⼱' => '巾',
  '⼲' => '干',
  '⼳' => '幺',
  '⼴' => '广',
  '⼵' => '廴',
  '⼶' => '廾',
  '⼷' => '弋',
  '⼸' => '弓',
  '⼹' => '彐',
  '⼺' => '彡',
  '⼻' => '彳',
  '⼼' => '心',
  '⼽' => '戈',
  '⼾' => '戶',
  '⼿' => '手',
  '⽀' => '支',
  '⽁' => '攴',
  '⽂' => '文',
  '⽃' => '斗',
  '⽄' => '斤',
  '⽅' => '方',
  '⽆' => '无',
  '⽇' => '日',
  '⽈' => '曰',
  '⽉' => '月',
  '⽊' => '木',
  '⽋' => '欠',
  '⽌' => '止',
  '⽍' => '歹',
  '⽎' => '殳',
  '⽏' => '毋',
  '⽐' => '比',
  '⽑' => '毛',
  '⽒' => '氏',
  '⽓' => '气',
  '⽔' => '水',
  '⽕' => '火',
  '⽖' => '爪',
  '⽗' => '父',
  '⽘' => '爻',
  '⽙' => '爿',
  '⽚' => '片',
  '⽛' => '牙',
  '⽜' => '牛',
  '⽝' => '犬',
  '⽞' => '玄',
  '⽟' => '玉',
  '⽠' => '瓜',
  '⽡' => '瓦',
  '⽢' => '甘',
  '⽣' => '生',
  '⽤' => '用',
  '⽥' => '田',
  '⽦' => '疋',
  '⽧' => '疒',
  '⽨' => '癶',
  '⽩' => '白',
  '⽪' => '皮',
  '⽫' => '皿',
  '⽬' => '目',
  '⽭' => '矛',
  '⽮' => '矢',
  '⽯' => '石',
  '⽰' => '示',
  '⽱' => '禸',
  '⽲' => '禾',
  '⽳' => '穴',
  '⽴' => '立',
  '⽵' => '竹',
  '⽶' => '米',
  '⽷' => '糸',
  '⽸' => '缶',
  '⽹' => '网',
  '⽺' => '羊',
  '⽻' => '羽',
  '⽼' => '老',
  '⽽' => '而',
  '⽾' => '耒',
  '⽿' => '耳',
  '⾀' => '聿',
  '⾁' => '肉',
  '⾂' => '臣',
  '⾃' => '自',
  '⾄' => '至',
  '⾅' => '臼',
  '⾆' => '舌',
  '⾇' => '舛',
  '⾈' => '舟',
  '⾉' => '艮',
  '⾊' => '色',
  '⾋' => '艸',
  '⾌' => '虍',
  '⾍' => '虫',
  '⾎' => '血',
  '⾏' => '行',
  '⾐' => '衣',
  '⾑' => '襾',
  '⾒' => '見',
  '⾓' => '角',
  '⾔' => '言',
  '⾕' => '谷',
  '⾖' => '豆',
  '⾗' => '豕',
  '⾘' => '豸',
  '⾙' => '貝',
  '⾚' => '赤',
  '⾛' => '走',
  '⾜' => '足',
  '⾝' => '身',
  '⾞' => '車',
  '⾟' => '辛',
  '⾠' => '辰',
  '⾡' => '辵',
  '⾢' => '邑',
  '⾣' => '酉',
  '⾤' => '釆',
  '⾥' => '里',
  '⾦' => '金',
  '⾧' => '長',
  '⾨' => '門',
  '⾩' => '阜',
  '⾪' => '隶',
  '⾫' => '隹',
  '⾬' => '雨',
  '⾭' => '靑',
  '⾮' => '非',
  '⾯' => '面',
  '⾰' => '革',
  '⾱' => '韋',
  '⾲' => '韭',
  '⾳' => '音',
  '⾴' => '頁',
  '⾵' => '風',
  '⾶' => '飛',
  '⾷' => '食',
  '⾸' => '首',
  '⾹' => '香',
  '⾺' => '馬',
  '⾻' => '骨',
  '⾼' => '高',
  '⾽' => '髟',
  '⾾' => '鬥',
  '⾿' => '鬯',
  '⿀' => '鬲',
  '⿁' => '鬼',
  '⿂' => '魚',
  '⿃' => '鳥',
  '⿄' => '鹵',
  '⿅' => '鹿',
  '⿆' => '麥',
  '⿇' => '麻',
  '⿈' => '黃',
  '⿉' => '黍',
  '⿊' => '黑',
  '⿋' => '黹',
  '⿌' => '黽',
  '⿍' => '鼎',
  '⿎' => '鼓',
  '⿏' => '鼠',
  '⿐' => '鼻',
  '⿑' => '齊',
  '⿒' => '齒',
  '⿓' => '龍',
  '⿔' => '龜',
  '⿕' => '龠',
  ' ' => ' ',
  '〶' => '〒',
  '〸' => '十',
  '〹' => '卄',
  '〺' => '卅',
  '゛' => ' ゙',
  '゜' => ' ゚',
  'ゟ' => 'より',
  'ヿ' => 'コト',
  'ㄱ' => 'ᄀ',
  'ㄲ' => 'ᄁ',
  'ㄳ' => 'ᆪ',
  'ㄴ' => 'ᄂ',
  'ㄵ' => 'ᆬ',
  'ㄶ' => 'ᆭ',
  'ㄷ' => 'ᄃ',
  'ㄸ' => 'ᄄ',
  'ㄹ' => 'ᄅ',
  'ㄺ' => 'ᆰ',
  'ㄻ' => 'ᆱ',
  'ㄼ' => 'ᆲ',
  'ㄽ' => 'ᆳ',
  'ㄾ' => 'ᆴ',
  'ㄿ' => 'ᆵ',
  'ㅀ' => 'ᄚ',
  'ㅁ' => 'ᄆ',
  'ㅂ' => 'ᄇ',
  'ㅃ' => 'ᄈ',
  'ㅄ' => 'ᄡ',
  'ㅅ' => 'ᄉ',
  'ㅆ' => 'ᄊ',
  'ㅇ' => 'ᄋ',
  'ㅈ' => 'ᄌ',
  'ㅉ' => 'ᄍ',
  'ㅊ' => 'ᄎ',
  'ㅋ' => 'ᄏ',
  'ㅌ' => 'ᄐ',
  'ㅍ' => 'ᄑ',
  'ㅎ' => 'ᄒ',
  'ㅏ' => 'ᅡ',
  'ㅐ' => 'ᅢ',
  'ㅑ' => 'ᅣ',
  'ㅒ' => 'ᅤ',
  'ㅓ' => 'ᅥ',
  'ㅔ' => 'ᅦ',
  'ㅕ' => 'ᅧ',
  'ㅖ' => 'ᅨ',
  'ㅗ' => 'ᅩ',
  'ㅘ' => 'ᅪ',
  'ㅙ' => 'ᅫ',
  'ㅚ' => 'ᅬ',
  'ㅛ' => 'ᅭ',
  'ㅜ' => 'ᅮ',
  'ㅝ' => 'ᅯ',
  'ㅞ' => 'ᅰ',
  'ㅟ' => 'ᅱ',
  'ㅠ' => 'ᅲ',
  'ㅡ' => 'ᅳ',
  'ㅢ' => 'ᅴ',
  'ㅣ' => 'ᅵ',
  'ㅤ' => 'ᅠ',
  'ㅥ' => 'ᄔ',
  'ㅦ' => 'ᄕ',
  'ㅧ' => 'ᇇ',
  'ㅨ' => 'ᇈ',
  'ㅩ' => 'ᇌ',
  'ㅪ' => 'ᇎ',
  'ㅫ' => 'ᇓ',
  'ㅬ' => 'ᇗ',
  'ㅭ' => 'ᇙ',
  'ㅮ' => 'ᄜ',
  'ㅯ' => 'ᇝ',
  'ㅰ' => 'ᇟ',
  'ㅱ' => 'ᄝ',
  'ㅲ' => 'ᄞ',
  'ㅳ' => 'ᄠ',
  'ㅴ' => 'ᄢ',
  'ㅵ' => 'ᄣ',
  'ㅶ' => 'ᄧ',
  'ㅷ' => 'ᄩ',
  'ㅸ' => 'ᄫ',
  'ㅹ' => 'ᄬ',
  'ㅺ' => 'ᄭ',
  'ㅻ' => 'ᄮ',
  'ㅼ' => 'ᄯ',
  'ㅽ' => 'ᄲ',
  'ㅾ' => 'ᄶ',
  'ㅿ' => 'ᅀ',
  'ㆀ' => 'ᅇ',
  'ㆁ' => 'ᅌ',
  'ㆂ' => 'ᇱ',
  'ㆃ' => 'ᇲ',
  'ㆄ' => 'ᅗ',
  'ㆅ' => 'ᅘ',
  'ㆆ' => 'ᅙ',
  'ㆇ' => 'ᆄ',
  'ㆈ' => 'ᆅ',
  'ㆉ' => 'ᆈ',
  'ㆊ' => 'ᆑ',
  'ㆋ' => 'ᆒ',
  'ㆌ' => 'ᆔ',
  'ㆍ' => 'ᆞ',
  'ㆎ' => 'ᆡ',
  '㆒' => '一',
  '㆓' => '二',
  '㆔' => '三',
  '㆕' => '四',
  '㆖' => '上',
  '㆗' => '中',
  '㆘' => '下',
  '㆙' => '甲',
  '㆚' => '乙',
  '㆛' => '丙',
  '㆜' => '丁',
  '㆝' => '天',
  '㆞' => '地',
  '㆟' => '人',
  '㈀' => '(ᄀ)',
  '㈁' => '(ᄂ)',
  '㈂' => '(ᄃ)',
  '㈃' => '(ᄅ)',
  '㈄' => '(ᄆ)',
  '㈅' => '(ᄇ)',
  '㈆' => '(ᄉ)',
  '㈇' => '(ᄋ)',
  '㈈' => '(ᄌ)',
  '㈉' => '(ᄎ)',
  '㈊' => '(ᄏ)',
  '㈋' => '(ᄐ)',
  '㈌' => '(ᄑ)',
  '㈍' => '(ᄒ)',
  '㈎' => '(가)',
  '㈏' => '(나)',
  '㈐' => '(다)',
  '㈑' => '(라)',
  '㈒' => '(마)',
  '㈓' => '(바)',
  '㈔' => '(사)',
  '㈕' => '(아)',
  '㈖' => '(자)',
  '㈗' => '(차)',
  '㈘' => '(카)',
  '㈙' => '(타)',
  '㈚' => '(파)',
  '㈛' => '(하)',
  '㈜' => '(주)',
  '㈝' => '(오전)',
  '㈞' => '(오후)',
  '㈠' => '(一)',
  '㈡' => '(二)',
  '㈢' => '(三)',
  '㈣' => '(四)',
  '㈤' => '(五)',
  '㈥' => '(六)',
  '㈦' => '(七)',
  '㈧' => '(八)',
  '㈨' => '(九)',
  '㈩' => '(十)',
  '㈪' => '(月)',
  '㈫' => '(火)',
  '㈬' => '(水)',
  '㈭' => '(木)',
  '㈮' => '(金)',
  '㈯' => '(土)',
  '㈰' => '(日)',
  '㈱' => '(株)',
  '㈲' => '(有)',
  '㈳' => '(社)',
  '㈴' => '(名)',
  '㈵' => '(特)',
  '㈶' => '(財)',
  '㈷' => '(祝)',
  '㈸' => '(労)',
  '㈹' => '(代)',
  '㈺' => '(呼)',
  '㈻' => '(学)',
  '㈼' => '(監)',
  '㈽' => '(企)',
  '㈾' => '(資)',
  '㈿' => '(協)',
  '㉀' => '(祭)',
  '㉁' => '(休)',
  '㉂' => '(自)',
  '㉃' => '(至)',
  '㉄' => '問',
  '㉅' => '幼',
  '㉆' => '文',
  '㉇' => '箏',
  '㉐' => 'PTE',
  '㉑' => '21',
  '㉒' => '22',
  '㉓' => '23',
  '㉔' => '24',
  '㉕' => '25',
  '㉖' => '26',
  '㉗' => '27',
  '㉘' => '28',
  '㉙' => '29',
  '㉚' => '30',
  '㉛' => '31',
  '㉜' => '32',
  '㉝' => '33',
  '㉞' => '34',
  '㉟' => '35',
  '㉠' => 'ᄀ',
  '㉡' => 'ᄂ',
  '㉢' => 'ᄃ',
  '㉣' => 'ᄅ',
  '㉤' => 'ᄆ',
  '㉥' => 'ᄇ',
  '㉦' => 'ᄉ',
  '㉧' => 'ᄋ',
  '㉨' => 'ᄌ',
  '㉩' => 'ᄎ',
  '㉪' => 'ᄏ',
  '㉫' => 'ᄐ',
  '㉬' => 'ᄑ',
  '㉭' => 'ᄒ',
  '㉮' => '가',
  '㉯' => '나',
  '㉰' => '다',
  '㉱' => '라',
  '㉲' => '마',
  '㉳' => '바',
  '㉴' => '사',
  '㉵' => '아',
  '㉶' => '자',
  '㉷' => '차',
  '㉸' => '카',
  '㉹' => '타',
  '㉺' => '파',
  '㉻' => '하',
  '㉼' => '참고',
  '㉽' => '주의',
  '㉾' => '우',
  '㊀' => '一',
  '㊁' => '二',
  '㊂' => '三',
  '㊃' => '四',
  '㊄' => '五',
  '㊅' => '六',
  '㊆' => '七',
  '㊇' => '八',
  '㊈' => '九',
  '㊉' => '十',
  '㊊' => '月',
  '㊋' => '火',
  '㊌' => '水',
  '㊍' => '木',
  '㊎' => '金',
  '㊏' => '土',
  '㊐' => '日',
  '㊑' => '株',
  '㊒' => '有',
  '㊓' => '社',
  '㊔' => '名',
  '㊕' => '特',
  '㊖' => '財',
  '㊗' => '祝',
  '㊘' => '労',
  '㊙' => '秘',
  '㊚' => '男',
  '㊛' => '女',
  '㊜' => '適',
  '㊝' => '優',
  '㊞' => '印',
  '㊟' => '注',
  '㊠' => '項',
  '㊡' => '休',
  '㊢' => '写',
  '㊣' => '正',
  '㊤' => '上',
  '㊥' => '中',
  '㊦' => '下',
  '㊧' => '左',
  '㊨' => '右',
  '㊩' => '医',
  '㊪' => '宗',
  '㊫' => '学',
  '㊬' => '監',
  '㊭' => '企',
  '㊮' => '資',
  '㊯' => '協',
  '㊰' => '夜',
  '㊱' => '36',
  '㊲' => '37',
  '㊳' => '38',
  '㊴' => '39',
  '㊵' => '40',
  '㊶' => '41',
  '㊷' => '42',
  '㊸' => '43',
  '㊹' => '44',
  '㊺' => '45',
  '㊻' => '46',
  '㊼' => '47',
  '㊽' => '48',
  '㊾' => '49',
  '㊿' => '50',
  '㋀' => '1月',
  '㋁' => '2月',
  '㋂' => '3月',
  '㋃' => '4月',
  '㋄' => '5月',
  '㋅' => '6月',
  '㋆' => '7月',
  '㋇' => '8月',
  '㋈' => '9月',
  '㋉' => '10月',
  '㋊' => '11月',
  '㋋' => '12月',
  '㋌' => 'Hg',
  '㋍' => 'erg',
  '㋎' => 'eV',
  '㋏' => 'LTD',
  '㋐' => 'ア',
  '㋑' => 'イ',
  '㋒' => 'ウ',
  '㋓' => 'エ',
  '㋔' => 'オ',
  '㋕' => 'カ',
  '㋖' => 'キ',
  '㋗' => 'ク',
  '㋘' => 'ケ',
  '㋙' => 'コ',
  '㋚' => 'サ',
  '㋛' => 'シ',
  '㋜' => 'ス',
  '㋝' => 'セ',
  '㋞' => 'ソ',
  '㋟' => 'タ',
  '㋠' => 'チ',
  '㋡' => 'ツ',
  '㋢' => 'テ',
  '㋣' => 'ト',
  '㋤' => 'ナ',
  '㋥' => 'ニ',
  '㋦' => 'ヌ',
  '㋧' => 'ネ',
  '㋨' => 'ノ',
  '㋩' => 'ハ',
  '㋪' => 'ヒ',
  '㋫' => 'フ',
  '㋬' => 'ヘ',
  '㋭' => 'ホ',
  '㋮' => 'マ',
  '㋯' => 'ミ',
  '㋰' => 'ム',
  '㋱' => 'メ',
  '㋲' => 'モ',
  '㋳' => 'ヤ',
  '㋴' => 'ユ',
  '㋵' => 'ヨ',
  '㋶' => 'ラ',
  '㋷' => 'リ',
  '㋸' => 'ル',
  '㋹' => 'レ',
  '㋺' => 'ロ',
  '㋻' => 'ワ',
  '㋼' => 'ヰ',
  '㋽' => 'ヱ',
  '㋾' => 'ヲ',
  '㋿' => '令和',
  '㌀' => 'アパート',
  '㌁' => 'アルファ',
  '㌂' => 'アンペア',
  '㌃' => 'アール',
  '㌄' => 'イニング',
  '㌅' => 'インチ',
  '㌆' => 'ウォン',
  '㌇' => 'エスクード',
  '㌈' => 'エーカー',
  '㌉' => 'オンス',
  '㌊' => 'オーム',
  '㌋' => 'カイリ',
  '㌌' => 'カラット',
  '㌍' => 'カロリー',
  '㌎' => 'ガロン',
  '㌏' => 'ガンマ',
  '㌐' => 'ギガ',
  '㌑' => 'ギニー',
  '㌒' => 'キュリー',
  '㌓' => 'ギルダー',
  '㌔' => 'キロ',
  '㌕' => 'キログラム',
  '㌖' => 'キロメートル',
  '㌗' => 'キロワット',
  '㌘' => 'グラム',
  '㌙' => 'グラムトン',
  '㌚' => 'クルゼイロ',
  '㌛' => 'クローネ',
  '㌜' => 'ケース',
  '㌝' => 'コルナ',
  '㌞' => 'コーポ',
  '㌟' => 'サイクル',
  '㌠' => 'サンチーム',
  '㌡' => 'シリング',
  '㌢' => 'センチ',
  '㌣' => 'セント',
  '㌤' => 'ダース',
  '㌥' => 'デシ',
  '㌦' => 'ドル',
  '㌧' => 'トン',
  '㌨' => 'ナノ',
  '㌩' => 'ノット',
  '㌪' => 'ハイツ',
  '㌫' => 'パーセント',
  '㌬' => 'パーツ',
  '㌭' => 'バーレル',
  '㌮' => 'ピアストル',
  '㌯' => 'ピクル',
  '㌰' => 'ピコ',
  '㌱' => 'ビル',
  '㌲' => 'ファラッド',
  '㌳' => 'フィート',
  '㌴' => 'ブッシェル',
  '㌵' => 'フラン',
  '㌶' => 'ヘクタール',
  '㌷' => 'ペソ',
  '㌸' => 'ペニヒ',
  '㌹' => 'ヘルツ',
  '㌺' => 'ペンス',
  '㌻' => 'ページ',
  '㌼' => 'ベータ',
  '㌽' => 'ポイント',
  '㌾' => 'ボルト',
  '㌿' => 'ホン',
  '㍀' => 'ポンド',
  '㍁' => 'ホール',
  '㍂' => 'ホーン',
  '㍃' => 'マイクロ',
  '㍄' => 'マイル',
  '㍅' => 'マッハ',
  '㍆' => 'マルク',
  '㍇' => 'マンション',
  '㍈' => 'ミクロン',
  '㍉' => 'ミリ',
  '㍊' => 'ミリバール',
  '㍋' => 'メガ',
  '㍌' => 'メガトン',
  '㍍' => 'メートル',
  '㍎' => 'ヤード',
  '㍏' => 'ヤール',
  '㍐' => 'ユアン',
  '㍑' => 'リットル',
  '㍒' => 'リラ',
  '㍓' => 'ルピー',
  '㍔' => 'ルーブル',
  '㍕' => 'レム',
  '㍖' => 'レントゲン',
  '㍗' => 'ワット',
  '㍘' => '0点',
  '㍙' => '1点',
  '㍚' => '2点',
  '㍛' => '3点',
  '㍜' => '4点',
  '㍝' => '5点',
  '㍞' => '6点',
  '㍟' => '7点',
  '㍠' => '8点',
  '㍡' => '9点',
  '㍢' => '10点',
  '㍣' => '11点',
  '㍤' => '12点',
  '㍥' => '13点',
  '㍦' => '14点',
  '㍧' => '15点',
  '㍨' => '16点',
  '㍩' => '17点',
  '㍪' => '18点',
  '㍫' => '19点',
  '㍬' => '20点',
  '㍭' => '21点',
  '㍮' => '22点',
  '㍯' => '23点',
  '㍰' => '24点',
  '㍱' => 'hPa',
  '㍲' => 'da',
  '㍳' => 'AU',
  '㍴' => 'bar',
  '㍵' => 'oV',
  '㍶' => 'pc',
  '㍷' => 'dm',
  '㍸' => 'dm2',
  '㍹' => 'dm3',
  '㍺' => 'IU',
  '㍻' => '平成',
  '㍼' => '昭和',
  '㍽' => '大正',
  '㍾' => '明治',
  '㍿' => '株式会社',
  '㎀' => 'pA',
  '㎁' => 'nA',
  '㎂' => 'μA',
  '㎃' => 'mA',
  '㎄' => 'kA',
  '㎅' => 'KB',
  '㎆' => 'MB',
  '㎇' => 'GB',
  '㎈' => 'cal',
  '㎉' => 'kcal',
  '㎊' => 'pF',
  '㎋' => 'nF',
  '㎌' => 'μF',
  '㎍' => 'μg',
  '㎎' => 'mg',
  '㎏' => 'kg',
  '㎐' => 'Hz',
  '㎑' => 'kHz',
  '㎒' => 'MHz',
  '㎓' => 'GHz',
  '㎔' => 'THz',
  '㎕' => 'μl',
  '㎖' => 'ml',
  '㎗' => 'dl',
  '㎘' => 'kl',
  '㎙' => 'fm',
  '㎚' => 'nm',
  '㎛' => 'μm',
  '㎜' => 'mm',
  '㎝' => 'cm',
  '㎞' => 'km',
  '㎟' => 'mm2',
  '㎠' => 'cm2',
  '㎡' => 'm2',
  '㎢' => 'km2',
  '㎣' => 'mm3',
  '㎤' => 'cm3',
  '㎥' => 'm3',
  '㎦' => 'km3',
  '㎧' => 'm∕s',
  '㎨' => 'm∕s2',
  '㎩' => 'Pa',
  '㎪' => 'kPa',
  '㎫' => 'MPa',
  '㎬' => 'GPa',
  '㎭' => 'rad',
  '㎮' => 'rad∕s',
  '㎯' => 'rad∕s2',
  '㎰' => 'ps',
  '㎱' => 'ns',
  '㎲' => 'μs',
  '㎳' => 'ms',
  '㎴' => 'pV',
  '㎵' => 'nV',
  '㎶' => 'μV',
  '㎷' => 'mV',
  '㎸' => 'kV',
  '㎹' => 'MV',
  '㎺' => 'pW',
  '㎻' => 'nW',
  '㎼' => 'μW',
  '㎽' => 'mW',
  '㎾' => 'kW',
  '㎿' => 'MW',
  '㏀' => 'kΩ',
  '㏁' => 'MΩ',
  '㏂' => 'a.m.',
  '㏃' => 'Bq',
  '㏄' => 'cc',
  '㏅' => 'cd',
  '㏆' => 'C∕kg',
  '㏇' => 'Co.',
  '㏈' => 'dB',
  '㏉' => 'Gy',
  '㏊' => 'ha',
  '㏋' => 'HP',
  '㏌' => 'in',
  '㏍' => 'KK',
  '㏎' => 'KM',
  '㏏' => 'kt',
  '㏐' => 'lm',
  '㏑' => 'ln',
  '㏒' => 'log',
  '㏓' => 'lx',
  '㏔' => 'mb',
  '㏕' => 'mil',
  '㏖' => 'mol',
  '㏗' => 'PH',
  '㏘' => 'p.m.',
  '㏙' => 'PPM',
  '㏚' => 'PR',
  '㏛' => 'sr',
  '㏜' => 'Sv',
  '㏝' => 'Wb',
  '㏞' => 'V∕m',
  '㏟' => 'A∕m',
  '㏠' => '1日',
  '㏡' => '2日',
  '㏢' => '3日',
  '㏣' => '4日',
  '㏤' => '5日',
  '㏥' => '6日',
  '㏦' => '7日',
  '㏧' => '8日',
  '㏨' => '9日',
  '㏩' => '10日',
  '㏪' => '11日',
  '㏫' => '12日',
  '㏬' => '13日',
  '㏭' => '14日',
  '㏮' => '15日',
  '㏯' => '16日',
  '㏰' => '17日',
  '㏱' => '18日',
  '㏲' => '19日',
  '㏳' => '20日',
  '㏴' => '21日',
  '㏵' => '22日',
  '㏶' => '23日',
  '㏷' => '24日',
  '㏸' => '25日',
  '㏹' => '26日',
  '㏺' => '27日',
  '㏻' => '28日',
  '㏼' => '29日',
  '㏽' => '30日',
  '㏾' => '31日',
  '㏿' => 'gal',
  'ꚜ' => 'ъ',
  'ꚝ' => 'ь',
  'ꝰ' => 'ꝯ',
  'ꟸ' => 'Ħ',
  'ꟹ' => 'œ',
  'ꭜ' => 'ꜧ',
  'ꭝ' => 'ꬷ',
  'ꭞ' => 'ɫ',
  'ꭟ' => 'ꭒ',
  'ꭩ' => 'ʍ',
  'ff' => 'ff',
  'fi' => 'fi',
  'fl' => 'fl',
  'ffi' => 'ffi',
  'ffl' => 'ffl',
  'ſt' => 'st',
  'st' => 'st',
  'ﬓ' => 'մն',
  'ﬔ' => 'մե',
  'ﬕ' => 'մի',
  'ﬖ' => 'վն',
  'ﬗ' => 'մխ',
  'ﬠ' => 'ע',
  'ﬡ' => 'א',
  'ﬢ' => 'ד',
  'ﬣ' => 'ה',
  'ﬤ' => 'כ',
  'ﬥ' => 'ל',
  'ﬦ' => 'ם',
  'ﬧ' => 'ר',
  'ﬨ' => 'ת',
  '﬩' => '+',
  'ﭏ' => 'אל',
  'ﭐ' => 'ٱ',
  'ﭑ' => 'ٱ',
  'ﭒ' => 'ٻ',
  'ﭓ' => 'ٻ',
  'ﭔ' => 'ٻ',
  'ﭕ' => 'ٻ',
  'ﭖ' => 'پ',
  'ﭗ' => 'پ',
  'ﭘ' => 'پ',
  'ﭙ' => 'پ',
  'ﭚ' => 'ڀ',
  'ﭛ' => 'ڀ',
  'ﭜ' => 'ڀ',
  'ﭝ' => 'ڀ',
  'ﭞ' => 'ٺ',
  'ﭟ' => 'ٺ',
  'ﭠ' => 'ٺ',
  'ﭡ' => 'ٺ',
  'ﭢ' => 'ٿ',
  'ﭣ' => 'ٿ',
  'ﭤ' => 'ٿ',
  'ﭥ' => 'ٿ',
  'ﭦ' => 'ٹ',
  'ﭧ' => 'ٹ',
  'ﭨ' => 'ٹ',
  'ﭩ' => 'ٹ',
  'ﭪ' => 'ڤ',
  'ﭫ' => 'ڤ',
  'ﭬ' => 'ڤ',
  'ﭭ' => 'ڤ',
  'ﭮ' => 'ڦ',
  'ﭯ' => 'ڦ',
  'ﭰ' => 'ڦ',
  'ﭱ' => 'ڦ',
  'ﭲ' => 'ڄ',
  'ﭳ' => 'ڄ',
  'ﭴ' => 'ڄ',
  'ﭵ' => 'ڄ',
  'ﭶ' => 'ڃ',
  'ﭷ' => 'ڃ',
  'ﭸ' => 'ڃ',
  'ﭹ' => 'ڃ',
  'ﭺ' => 'چ',
  'ﭻ' => 'چ',
  'ﭼ' => 'چ',
  'ﭽ' => 'چ',
  'ﭾ' => 'ڇ',
  'ﭿ' => 'ڇ',
  'ﮀ' => 'ڇ',
  'ﮁ' => 'ڇ',
  'ﮂ' => 'ڍ',
  'ﮃ' => 'ڍ',
  'ﮄ' => 'ڌ',
  'ﮅ' => 'ڌ',
  'ﮆ' => 'ڎ',
  'ﮇ' => 'ڎ',
  'ﮈ' => 'ڈ',
  'ﮉ' => 'ڈ',
  'ﮊ' => 'ژ',
  'ﮋ' => 'ژ',
  'ﮌ' => 'ڑ',
  'ﮍ' => 'ڑ',
  'ﮎ' => 'ک',
  'ﮏ' => 'ک',
  'ﮐ' => 'ک',
  'ﮑ' => 'ک',
  'ﮒ' => 'گ',
  'ﮓ' => 'گ',
  'ﮔ' => 'گ',
  'ﮕ' => 'گ',
  'ﮖ' => 'ڳ',
  'ﮗ' => 'ڳ',
  'ﮘ' => 'ڳ',
  'ﮙ' => 'ڳ',
  'ﮚ' => 'ڱ',
  'ﮛ' => 'ڱ',
  'ﮜ' => 'ڱ',
  'ﮝ' => 'ڱ',
  'ﮞ' => 'ں',
  'ﮟ' => 'ں',
  'ﮠ' => 'ڻ',
  'ﮡ' => 'ڻ',
  'ﮢ' => 'ڻ',
  'ﮣ' => 'ڻ',
  'ﮤ' => 'ۀ',
  'ﮥ' => 'ۀ',
  'ﮦ' => 'ہ',
  'ﮧ' => 'ہ',
  'ﮨ' => 'ہ',
  'ﮩ' => 'ہ',
  'ﮪ' => 'ھ',
  'ﮫ' => 'ھ',
  'ﮬ' => 'ھ',
  'ﮭ' => 'ھ',
  'ﮮ' => 'ے',
  'ﮯ' => 'ے',
  'ﮰ' => 'ۓ',
  'ﮱ' => 'ۓ',
  'ﯓ' => 'ڭ',
  'ﯔ' => 'ڭ',
  'ﯕ' => 'ڭ',
  'ﯖ' => 'ڭ',
  'ﯗ' => 'ۇ',
  'ﯘ' => 'ۇ',
  'ﯙ' => 'ۆ',
  'ﯚ' => 'ۆ',
  'ﯛ' => 'ۈ',
  'ﯜ' => 'ۈ',
  'ﯝ' => 'ۇٴ',
  'ﯞ' => 'ۋ',
  'ﯟ' => 'ۋ',
  'ﯠ' => 'ۅ',
  'ﯡ' => 'ۅ',
  'ﯢ' => 'ۉ',
  'ﯣ' => 'ۉ',
  'ﯤ' => 'ې',
  'ﯥ' => 'ې',
  'ﯦ' => 'ې',
  'ﯧ' => 'ې',
  'ﯨ' => 'ى',
  'ﯩ' => 'ى',
  'ﯪ' => 'ئا',
  'ﯫ' => 'ئا',
  'ﯬ' => 'ئە',
  'ﯭ' => 'ئە',
  'ﯮ' => 'ئو',
  'ﯯ' => 'ئو',
  'ﯰ' => 'ئۇ',
  'ﯱ' => 'ئۇ',
  'ﯲ' => 'ئۆ',
  'ﯳ' => 'ئۆ',
  'ﯴ' => 'ئۈ',
  'ﯵ' => 'ئۈ',
  'ﯶ' => 'ئې',
  'ﯷ' => 'ئې',
  'ﯸ' => 'ئې',
  'ﯹ' => 'ئى',
  'ﯺ' => 'ئى',
  'ﯻ' => 'ئى',
  'ﯼ' => 'ی',
  'ﯽ' => 'ی',
  'ﯾ' => 'ی',
  'ﯿ' => 'ی',
  'ﰀ' => 'ئج',
  'ﰁ' => 'ئح',
  'ﰂ' => 'ئم',
  'ﰃ' => 'ئى',
  'ﰄ' => 'ئي',
  'ﰅ' => 'بج',
  'ﰆ' => 'بح',
  'ﰇ' => 'بخ',
  'ﰈ' => 'بم',
  'ﰉ' => 'بى',
  'ﰊ' => 'بي',
  'ﰋ' => 'تج',
  'ﰌ' => 'تح',
  'ﰍ' => 'تخ',
  'ﰎ' => 'تم',
  'ﰏ' => 'تى',
  'ﰐ' => 'تي',
  'ﰑ' => 'ثج',
  'ﰒ' => 'ثم',
  'ﰓ' => 'ثى',
  'ﰔ' => 'ثي',
  'ﰕ' => 'جح',
  'ﰖ' => 'جم',
  'ﰗ' => 'حج',
  'ﰘ' => 'حم',
  'ﰙ' => 'خج',
  'ﰚ' => 'خح',
  'ﰛ' => 'خم',
  'ﰜ' => 'سج',
  'ﰝ' => 'سح',
  'ﰞ' => 'سخ',
  'ﰟ' => 'سم',
  'ﰠ' => 'صح',
  'ﰡ' => 'صم',
  'ﰢ' => 'ضج',
  'ﰣ' => 'ضح',
  'ﰤ' => 'ضخ',
  'ﰥ' => 'ضم',
  'ﰦ' => 'طح',
  'ﰧ' => 'طم',
  'ﰨ' => 'ظم',
  'ﰩ' => 'عج',
  'ﰪ' => 'عم',
  'ﰫ' => 'غج',
  'ﰬ' => 'غم',
  'ﰭ' => 'فج',
  'ﰮ' => 'فح',
  'ﰯ' => 'فخ',
  'ﰰ' => 'فم',
  'ﰱ' => 'فى',
  'ﰲ' => 'في',
  'ﰳ' => 'قح',
  'ﰴ' => 'قم',
  'ﰵ' => 'قى',
  'ﰶ' => 'قي',
  'ﰷ' => 'كا',
  'ﰸ' => 'كج',
  'ﰹ' => 'كح',
  'ﰺ' => 'كخ',
  'ﰻ' => 'كل',
  'ﰼ' => 'كم',
  'ﰽ' => 'كى',
  'ﰾ' => 'كي',
  'ﰿ' => 'لج',
  'ﱀ' => 'لح',
  'ﱁ' => 'لخ',
  'ﱂ' => 'لم',
  'ﱃ' => 'لى',
  'ﱄ' => 'لي',
  'ﱅ' => 'مج',
  'ﱆ' => 'مح',
  'ﱇ' => 'مخ',
  'ﱈ' => 'مم',
  'ﱉ' => 'مى',
  'ﱊ' => 'مي',
  'ﱋ' => 'نج',
  'ﱌ' => 'نح',
  'ﱍ' => 'نخ',
  'ﱎ' => 'نم',
  'ﱏ' => 'نى',
  'ﱐ' => 'ني',
  'ﱑ' => 'هج',
  'ﱒ' => 'هم',
  'ﱓ' => 'هى',
  'ﱔ' => 'هي',
  'ﱕ' => 'يج',
  'ﱖ' => 'يح',
  'ﱗ' => 'يخ',
  'ﱘ' => 'يم',
  'ﱙ' => 'يى',
  'ﱚ' => 'يي',
  'ﱛ' => 'ذٰ',
  'ﱜ' => 'رٰ',
  'ﱝ' => 'ىٰ',
  'ﱞ' => ' ٌّ',
  'ﱟ' => ' ٍّ',
  'ﱠ' => ' َّ',
  'ﱡ' => ' ُّ',
  'ﱢ' => ' ِّ',
  'ﱣ' => ' ّٰ',
  'ﱤ' => 'ئر',
  'ﱥ' => 'ئز',
  'ﱦ' => 'ئم',
  'ﱧ' => 'ئن',
  'ﱨ' => 'ئى',
  'ﱩ' => 'ئي',
  'ﱪ' => 'بر',
  'ﱫ' => 'بز',
  'ﱬ' => 'بم',
  'ﱭ' => 'بن',
  'ﱮ' => 'بى',
  'ﱯ' => 'بي',
  'ﱰ' => 'تر',
  'ﱱ' => 'تز',
  'ﱲ' => 'تم',
  'ﱳ' => 'تن',
  'ﱴ' => 'تى',
  'ﱵ' => 'تي',
  'ﱶ' => 'ثر',
  'ﱷ' => 'ثز',
  'ﱸ' => 'ثم',
  'ﱹ' => 'ثن',
  'ﱺ' => 'ثى',
  'ﱻ' => 'ثي',
  'ﱼ' => 'فى',
  'ﱽ' => 'في',
  'ﱾ' => 'قى',
  'ﱿ' => 'قي',
  'ﲀ' => 'كا',
  'ﲁ' => 'كل',
  'ﲂ' => 'كم',
  'ﲃ' => 'كى',
  'ﲄ' => 'كي',
  'ﲅ' => 'لم',
  'ﲆ' => 'لى',
  'ﲇ' => 'لي',
  'ﲈ' => 'ما',
  'ﲉ' => 'مم',
  'ﲊ' => 'نر',
  'ﲋ' => 'نز',
  'ﲌ' => 'نم',
  'ﲍ' => 'نن',
  'ﲎ' => 'نى',
  'ﲏ' => 'ني',
  'ﲐ' => 'ىٰ',
  'ﲑ' => 'ير',
  'ﲒ' => 'يز',
  'ﲓ' => 'يم',
  'ﲔ' => 'ين',
  'ﲕ' => 'يى',
  'ﲖ' => 'يي',
  'ﲗ' => 'ئج',
  'ﲘ' => 'ئح',
  'ﲙ' => 'ئخ',
  'ﲚ' => 'ئم',
  'ﲛ' => 'ئه',
  'ﲜ' => 'بج',
  'ﲝ' => 'بح',
  'ﲞ' => 'بخ',
  'ﲟ' => 'بم',
  'ﲠ' => 'به',
  'ﲡ' => 'تج',
  'ﲢ' => 'تح',
  'ﲣ' => 'تخ',
  'ﲤ' => 'تم',
  'ﲥ' => 'ته',
  'ﲦ' => 'ثم',
  'ﲧ' => 'جح',
  'ﲨ' => 'جم',
  'ﲩ' => 'حج',
  'ﲪ' => 'حم',
  'ﲫ' => 'خج',
  'ﲬ' => 'خم',
  'ﲭ' => 'سج',
  'ﲮ' => 'سح',
  'ﲯ' => 'سخ',
  'ﲰ' => 'سم',
  'ﲱ' => 'صح',
  'ﲲ' => 'صخ',
  'ﲳ' => 'صم',
  'ﲴ' => 'ضج',
  'ﲵ' => 'ضح',
  'ﲶ' => 'ضخ',
  'ﲷ' => 'ضم',
  'ﲸ' => 'طح',
  'ﲹ' => 'ظم',
  'ﲺ' => 'عج',
  'ﲻ' => 'عم',
  'ﲼ' => 'غج',
  'ﲽ' => 'غم',
  'ﲾ' => 'فج',
  'ﲿ' => 'فح',
  'ﳀ' => 'فخ',
  'ﳁ' => 'فم',
  'ﳂ' => 'قح',
  'ﳃ' => 'قم',
  'ﳄ' => 'كج',
  'ﳅ' => 'كح',
  'ﳆ' => 'كخ',
  'ﳇ' => 'كل',
  'ﳈ' => 'كم',
  'ﳉ' => 'لج',
  'ﳊ' => 'لح',
  'ﳋ' => 'لخ',
  'ﳌ' => 'لم',
  'ﳍ' => 'له',
  'ﳎ' => 'مج',
  'ﳏ' => 'مح',
  'ﳐ' => 'مخ',
  'ﳑ' => 'مم',
  'ﳒ' => 'نج',
  'ﳓ' => 'نح',
  'ﳔ' => 'نخ',
  'ﳕ' => 'نم',
  'ﳖ' => 'نه',
  'ﳗ' => 'هج',
  'ﳘ' => 'هم',
  'ﳙ' => 'هٰ',
  'ﳚ' => 'يج',
  'ﳛ' => 'يح',
  'ﳜ' => 'يخ',
  'ﳝ' => 'يم',
  'ﳞ' => 'يه',
  'ﳟ' => 'ئم',
  'ﳠ' => 'ئه',
  'ﳡ' => 'بم',
  'ﳢ' => 'به',
  'ﳣ' => 'تم',
  'ﳤ' => 'ته',
  'ﳥ' => 'ثم',
  'ﳦ' => 'ثه',
  'ﳧ' => 'سم',
  'ﳨ' => 'سه',
  'ﳩ' => 'شم',
  'ﳪ' => 'شه',
  'ﳫ' => 'كل',
  'ﳬ' => 'كم',
  'ﳭ' => 'لم',
  'ﳮ' => 'نم',
  'ﳯ' => 'نه',
  'ﳰ' => 'يم',
  'ﳱ' => 'يه',
  'ﳲ' => 'ـَّ',
  'ﳳ' => 'ـُّ',
  'ﳴ' => 'ـِّ',
  'ﳵ' => 'طى',
  'ﳶ' => 'طي',
  'ﳷ' => 'عى',
  'ﳸ' => 'عي',
  'ﳹ' => 'غى',
  'ﳺ' => 'غي',
  'ﳻ' => 'سى',
  'ﳼ' => 'سي',
  'ﳽ' => 'شى',
  'ﳾ' => 'شي',
  'ﳿ' => 'حى',
  'ﴀ' => 'حي',
  'ﴁ' => 'جى',
  'ﴂ' => 'جي',
  'ﴃ' => 'خى',
  'ﴄ' => 'خي',
  'ﴅ' => 'صى',
  'ﴆ' => 'صي',
  'ﴇ' => 'ضى',
  'ﴈ' => 'ضي',
  'ﴉ' => 'شج',
  'ﴊ' => 'شح',
  'ﴋ' => 'شخ',
  'ﴌ' => 'شم',
  'ﴍ' => 'شر',
  'ﴎ' => 'سر',
  'ﴏ' => 'صر',
  'ﴐ' => 'ضر',
  'ﴑ' => 'طى',
  'ﴒ' => 'طي',
  'ﴓ' => 'عى',
  'ﴔ' => 'عي',
  'ﴕ' => 'غى',
  'ﴖ' => 'غي',
  'ﴗ' => 'سى',
  'ﴘ' => 'سي',
  'ﴙ' => 'شى',
  'ﴚ' => 'شي',
  'ﴛ' => 'حى',
  'ﴜ' => 'حي',
  'ﴝ' => 'جى',
  'ﴞ' => 'جي',
  'ﴟ' => 'خى',
  'ﴠ' => 'خي',
  'ﴡ' => 'صى',
  'ﴢ' => 'صي',
  'ﴣ' => 'ضى',
  'ﴤ' => 'ضي',
  'ﴥ' => 'شج',
  'ﴦ' => 'شح',
  'ﴧ' => 'شخ',
  'ﴨ' => 'شم',
  'ﴩ' => 'شر',
  'ﴪ' => 'سر',
  'ﴫ' => 'صر',
  'ﴬ' => 'ضر',
  'ﴭ' => 'شج',
  'ﴮ' => 'شح',
  'ﴯ' => 'شخ',
  'ﴰ' => 'شم',
  'ﴱ' => 'سه',
  'ﴲ' => 'شه',
  'ﴳ' => 'طم',
  'ﴴ' => 'سج',
  'ﴵ' => 'سح',
  'ﴶ' => 'سخ',
  'ﴷ' => 'شج',
  'ﴸ' => 'شح',
  'ﴹ' => 'شخ',
  'ﴺ' => 'طم',
  'ﴻ' => 'ظم',
  'ﴼ' => 'اً',
  'ﴽ' => 'اً',
  'ﵐ' => 'تجم',
  'ﵑ' => 'تحج',
  'ﵒ' => 'تحج',
  'ﵓ' => 'تحم',
  'ﵔ' => 'تخم',
  'ﵕ' => 'تمج',
  'ﵖ' => 'تمح',
  'ﵗ' => 'تمخ',
  'ﵘ' => 'جمح',
  'ﵙ' => 'جمح',
  'ﵚ' => 'حمي',
  'ﵛ' => 'حمى',
  'ﵜ' => 'سحج',
  'ﵝ' => 'سجح',
  'ﵞ' => 'سجى',
  'ﵟ' => 'سمح',
  'ﵠ' => 'سمح',
  'ﵡ' => 'سمج',
  'ﵢ' => 'سمم',
  'ﵣ' => 'سمم',
  'ﵤ' => 'صحح',
  'ﵥ' => 'صحح',
  'ﵦ' => 'صمم',
  'ﵧ' => 'شحم',
  'ﵨ' => 'شحم',
  'ﵩ' => 'شجي',
  'ﵪ' => 'شمخ',
  'ﵫ' => 'شمخ',
  'ﵬ' => 'شمم',
  'ﵭ' => 'شمم',
  'ﵮ' => 'ضحى',
  'ﵯ' => 'ضخم',
  'ﵰ' => 'ضخم',
  'ﵱ' => 'طمح',
  'ﵲ' => 'طمح',
  'ﵳ' => 'طمم',
  'ﵴ' => 'طمي',
  'ﵵ' => 'عجم',
  'ﵶ' => 'عمم',
  'ﵷ' => 'عمم',
  'ﵸ' => 'عمى',
  'ﵹ' => 'غمم',
  'ﵺ' => 'غمي',
  'ﵻ' => 'غمى',
  'ﵼ' => 'فخم',
  'ﵽ' => 'فخم',
  'ﵾ' => 'قمح',
  'ﵿ' => 'قمم',
  'ﶀ' => 'لحم',
  'ﶁ' => 'لحي',
  'ﶂ' => 'لحى',
  'ﶃ' => 'لجج',
  'ﶄ' => 'لجج',
  'ﶅ' => 'لخم',
  'ﶆ' => 'لخم',
  'ﶇ' => 'لمح',
  'ﶈ' => 'لمح',
  'ﶉ' => 'محج',
  'ﶊ' => 'محم',
  'ﶋ' => 'محي',
  'ﶌ' => 'مجح',
  'ﶍ' => 'مجم',
  'ﶎ' => 'مخج',
  'ﶏ' => 'مخم',
  'ﶒ' => 'مجخ',
  'ﶓ' => 'همج',
  'ﶔ' => 'همم',
  'ﶕ' => 'نحم',
  'ﶖ' => 'نحى',
  'ﶗ' => 'نجم',
  'ﶘ' => 'نجم',
  'ﶙ' => 'نجى',
  'ﶚ' => 'نمي',
  'ﶛ' => 'نمى',
  'ﶜ' => 'يمم',
  'ﶝ' => 'يمم',
  'ﶞ' => 'بخي',
  'ﶟ' => 'تجي',
  'ﶠ' => 'تجى',
  'ﶡ' => 'تخي',
  'ﶢ' => 'تخى',
  'ﶣ' => 'تمي',
  'ﶤ' => 'تمى',
  'ﶥ' => 'جمي',
  'ﶦ' => 'جحى',
  'ﶧ' => 'جمى',
  'ﶨ' => 'سخى',
  'ﶩ' => 'صحي',
  'ﶪ' => 'شحي',
  'ﶫ' => 'ضحي',
  'ﶬ' => 'لجي',
  'ﶭ' => 'لمي',
  'ﶮ' => 'يحي',
  'ﶯ' => 'يجي',
  'ﶰ' => 'يمي',
  'ﶱ' => 'ممي',
  'ﶲ' => 'قمي',
  'ﶳ' => 'نحي',
  'ﶴ' => 'قمح',
  'ﶵ' => 'لحم',
  'ﶶ' => 'عمي',
  'ﶷ' => 'كمي',
  'ﶸ' => 'نجح',
  'ﶹ' => 'مخي',
  'ﶺ' => 'لجم',
  'ﶻ' => 'كمم',
  'ﶼ' => 'لجم',
  'ﶽ' => 'نجح',
  'ﶾ' => 'جحي',
  'ﶿ' => 'حجي',
  'ﷀ' => 'مجي',
  'ﷁ' => 'فمي',
  'ﷂ' => 'بحي',
  'ﷃ' => 'كمم',
  'ﷄ' => 'عجم',
  'ﷅ' => 'صمم',
  'ﷆ' => 'سخي',
  'ﷇ' => 'نجي',
  'ﷰ' => 'صلے',
  'ﷱ' => 'قلے',
  'ﷲ' => 'الله',
  'ﷳ' => 'اكبر',
  'ﷴ' => 'محمد',
  'ﷵ' => 'صلعم',
  'ﷶ' => 'رسول',
  'ﷷ' => 'عليه',
  'ﷸ' => 'وسلم',
  'ﷹ' => 'صلى',
  'ﷺ' => 'صلى الله عليه وسلم',
  'ﷻ' => 'جل جلاله',
  '﷼' => 'ریال',
  '︐' => ',',
  '︑' => '、',
  '︒' => '。',
  '︓' => ':',
  '︔' => ';',
  '︕' => '!',
  '︖' => '?',
  '︗' => '〖',
  '︘' => '〗',
  '︙' => '...',
  '︰' => '..',
  '︱' => '—',
  '︲' => '–',
  '︳' => '_',
  '︴' => '_',
  '︵' => '(',
  '︶' => ')',
  '︷' => '{',
  '︸' => '}',
  '︹' => '〔',
  '︺' => '〕',
  '︻' => '【',
  '︼' => '】',
  '︽' => '《',
  '︾' => '》',
  '︿' => '〈',
  '﹀' => '〉',
  '﹁' => '「',
  '﹂' => '」',
  '﹃' => '『',
  '﹄' => '』',
  '﹇' => '[',
  '﹈' => ']',
  '﹉' => ' ̅',
  '﹊' => ' ̅',
  '﹋' => ' ̅',
  '﹌' => ' ̅',
  '﹍' => '_',
  '﹎' => '_',
  '﹏' => '_',
  '﹐' => ',',
  '﹑' => '、',
  '﹒' => '.',
  '﹔' => ';',
  '﹕' => ':',
  '﹖' => '?',
  '﹗' => '!',
  '﹘' => '—',
  '﹙' => '(',
  '﹚' => ')',
  '﹛' => '{',
  '﹜' => '}',
  '﹝' => '〔',
  '﹞' => '〕',
  '﹟' => '#',
  '﹠' => '&',
  '﹡' => '*',
  '﹢' => '+',
  '﹣' => '-',
  '﹤' => '<',
  '﹥' => '>',
  '﹦' => '=',
  '﹨' => '\\',
  '﹩' => '$',
  '﹪' => '%',
  '﹫' => '@',
  'ﹰ' => ' ً',
  'ﹱ' => 'ـً',
  'ﹲ' => ' ٌ',
  'ﹴ' => ' ٍ',
  'ﹶ' => ' َ',
  'ﹷ' => 'ـَ',
  'ﹸ' => ' ُ',
  'ﹹ' => 'ـُ',
  'ﹺ' => ' ِ',
  'ﹻ' => 'ـِ',
  'ﹼ' => ' ّ',
  'ﹽ' => 'ـّ',
  'ﹾ' => ' ْ',
  'ﹿ' => 'ـْ',
  'ﺀ' => 'ء',
  'ﺁ' => 'آ',
  'ﺂ' => 'آ',
  'ﺃ' => 'أ',
  'ﺄ' => 'أ',
  'ﺅ' => 'ؤ',
  'ﺆ' => 'ؤ',
  'ﺇ' => 'إ',
  'ﺈ' => 'إ',
  'ﺉ' => 'ئ',
  'ﺊ' => 'ئ',
  'ﺋ' => 'ئ',
  'ﺌ' => 'ئ',
  'ﺍ' => 'ا',
  'ﺎ' => 'ا',
  'ﺏ' => 'ب',
  'ﺐ' => 'ب',
  'ﺑ' => 'ب',
  'ﺒ' => 'ب',
  'ﺓ' => 'ة',
  'ﺔ' => 'ة',
  'ﺕ' => 'ت',
  'ﺖ' => 'ت',
  'ﺗ' => 'ت',
  'ﺘ' => 'ت',
  'ﺙ' => 'ث',
  'ﺚ' => 'ث',
  'ﺛ' => 'ث',
  'ﺜ' => 'ث',
  'ﺝ' => 'ج',
  'ﺞ' => 'ج',
  'ﺟ' => 'ج',
  'ﺠ' => 'ج',
  'ﺡ' => 'ح',
  'ﺢ' => 'ح',
  'ﺣ' => 'ح',
  'ﺤ' => 'ح',
  'ﺥ' => 'خ',
  'ﺦ' => 'خ',
  'ﺧ' => 'خ',
  'ﺨ' => 'خ',
  'ﺩ' => 'د',
  'ﺪ' => 'د',
  'ﺫ' => 'ذ',
  'ﺬ' => 'ذ',
  'ﺭ' => 'ر',
  'ﺮ' => 'ر',
  'ﺯ' => 'ز',
  'ﺰ' => 'ز',
  'ﺱ' => 'س',
  'ﺲ' => 'س',
  'ﺳ' => 'س',
  'ﺴ' => 'س',
  'ﺵ' => 'ش',
  'ﺶ' => 'ش',
  'ﺷ' => 'ش',
  'ﺸ' => 'ش',
  'ﺹ' => 'ص',
  'ﺺ' => 'ص',
  'ﺻ' => 'ص',
  'ﺼ' => 'ص',
  'ﺽ' => 'ض',
  'ﺾ' => 'ض',
  'ﺿ' => 'ض',
  'ﻀ' => 'ض',
  'ﻁ' => 'ط',
  'ﻂ' => 'ط',
  'ﻃ' => 'ط',
  'ﻄ' => 'ط',
  'ﻅ' => 'ظ',
  'ﻆ' => 'ظ',
  'ﻇ' => 'ظ',
  'ﻈ' => 'ظ',
  'ﻉ' => 'ع',
  'ﻊ' => 'ع',
  'ﻋ' => 'ع',
  'ﻌ' => 'ع',
  'ﻍ' => 'غ',
  'ﻎ' => 'غ',
  'ﻏ' => 'غ',
  'ﻐ' => 'غ',
  'ﻑ' => 'ف',
  'ﻒ' => 'ف',
  'ﻓ' => 'ف',
  'ﻔ' => 'ف',
  'ﻕ' => 'ق',
  'ﻖ' => 'ق',
  'ﻗ' => 'ق',
  'ﻘ' => 'ق',
  'ﻙ' => 'ك',
  'ﻚ' => 'ك',
  'ﻛ' => 'ك',
  'ﻜ' => 'ك',
  'ﻝ' => 'ل',
  'ﻞ' => 'ل',
  'ﻟ' => 'ل',
  'ﻠ' => 'ل',
  'ﻡ' => 'م',
  'ﻢ' => 'م',
  'ﻣ' => 'م',
  'ﻤ' => 'م',
  'ﻥ' => 'ن',
  'ﻦ' => 'ن',
  'ﻧ' => 'ن',
  'ﻨ' => 'ن',
  'ﻩ' => 'ه',
  'ﻪ' => 'ه',
  'ﻫ' => 'ه',
  'ﻬ' => 'ه',
  'ﻭ' => 'و',
  'ﻮ' => 'و',
  'ﻯ' => 'ى',
  'ﻰ' => 'ى',
  'ﻱ' => 'ي',
  'ﻲ' => 'ي',
  'ﻳ' => 'ي',
  'ﻴ' => 'ي',
  'ﻵ' => 'لآ',
  'ﻶ' => 'لآ',
  'ﻷ' => 'لأ',
  'ﻸ' => 'لأ',
  'ﻹ' => 'لإ',
  'ﻺ' => 'لإ',
  'ﻻ' => 'لا',
  'ﻼ' => 'لا',
  '!' => '!',
  '"' => '"',
  '#' => '#',
  '$' => '$',
  '%' => '%',
  '&' => '&',
  ''' => '\'',
  '(' => '(',
  ')' => ')',
  '*' => '*',
  '+' => '+',
  ',' => ',',
  '-' => '-',
  '.' => '.',
  '/' => '/',
  '0' => '0',
  '1' => '1',
  '2' => '2',
  '3' => '3',
  '4' => '4',
  '5' => '5',
  '6' => '6',
  '7' => '7',
  '8' => '8',
  '9' => '9',
  ':' => ':',
  ';' => ';',
  '<' => '<',
  '=' => '=',
  '>' => '>',
  '?' => '?',
  '@' => '@',
  'A' => 'A',
  'B' => 'B',
  'C' => 'C',
  'D' => 'D',
  'E' => 'E',
  'F' => 'F',
  'G' => 'G',
  'H' => 'H',
  'I' => 'I',
  'J' => 'J',
  'K' => 'K',
  'L' => 'L',
  'M' => 'M',
  'N' => 'N',
  'O' => 'O',
  'P' => 'P',
  'Q' => 'Q',
  'R' => 'R',
  'S' => 'S',
  'T' => 'T',
  'U' => 'U',
  'V' => 'V',
  'W' => 'W',
  'X' => 'X',
  'Y' => 'Y',
  'Z' => 'Z',
  '[' => '[',
  '\' => '\\',
  ']' => ']',
  '^' => '^',
  '_' => '_',
  '`' => '`',
  'a' => 'a',
  'b' => 'b',
  'c' => 'c',
  'd' => 'd',
  'e' => 'e',
  'f' => 'f',
  'g' => 'g',
  'h' => 'h',
  'i' => 'i',
  'j' => 'j',
  'k' => 'k',
  'l' => 'l',
  'm' => 'm',
  'n' => 'n',
  'o' => 'o',
  'p' => 'p',
  'q' => 'q',
  'r' => 'r',
  's' => 's',
  't' => 't',
  'u' => 'u',
  'v' => 'v',
  'w' => 'w',
  'x' => 'x',
  'y' => 'y',
  'z' => 'z',
  '{' => '{',
  '|' => '|',
  '}' => '}',
  '~' => '~',
  '⦅' => '⦅',
  '⦆' => '⦆',
  '。' => '。',
  '「' => '「',
  '」' => '」',
  '、' => '、',
  '・' => '・',
  'ヲ' => 'ヲ',
  'ァ' => 'ァ',
  'ィ' => 'ィ',
  'ゥ' => 'ゥ',
  'ェ' => 'ェ',
  'ォ' => 'ォ',
  'ャ' => 'ャ',
  'ュ' => 'ュ',
  'ョ' => 'ョ',
  'ッ' => 'ッ',
  'ー' => 'ー',
  'ア' => 'ア',
  'イ' => 'イ',
  'ウ' => 'ウ',
  'エ' => 'エ',
  'オ' => 'オ',
  'カ' => 'カ',
  'キ' => 'キ',
  'ク' => 'ク',
  'ケ' => 'ケ',
  'コ' => 'コ',
  'サ' => 'サ',
  'シ' => 'シ',
  'ス' => 'ス',
  'セ' => 'セ',
  'ソ' => 'ソ',
  'タ' => 'タ',
  'チ' => 'チ',
  'ツ' => 'ツ',
  'テ' => 'テ',
  'ト' => 'ト',
  'ナ' => 'ナ',
  'ニ' => 'ニ',
  'ヌ' => 'ヌ',
  'ネ' => 'ネ',
  'ノ' => 'ノ',
  'ハ' => 'ハ',
  'ヒ' => 'ヒ',
  'フ' => 'フ',
  'ヘ' => 'ヘ',
  'ホ' => 'ホ',
  'マ' => 'マ',
  'ミ' => 'ミ',
  'ム' => 'ム',
  'メ' => 'メ',
  'モ' => 'モ',
  'ヤ' => 'ヤ',
  'ユ' => 'ユ',
  'ヨ' => 'ヨ',
  'ラ' => 'ラ',
  'リ' => 'リ',
  'ル' => 'ル',
  'レ' => 'レ',
  'ロ' => 'ロ',
  'ワ' => 'ワ',
  'ン' => 'ン',
  '゙' => '゙',
  '゚' => '゚',
  'ᅠ' => 'ᅠ',
  'ᄀ' => 'ᄀ',
  'ᄁ' => 'ᄁ',
  'ᆪ' => 'ᆪ',
  'ᄂ' => 'ᄂ',
  'ᆬ' => 'ᆬ',
  'ᆭ' => 'ᆭ',
  'ᄃ' => 'ᄃ',
  'ᄄ' => 'ᄄ',
  'ᄅ' => 'ᄅ',
  'ᆰ' => 'ᆰ',
  'ᆱ' => 'ᆱ',
  'ᆲ' => 'ᆲ',
  'ᆳ' => 'ᆳ',
  'ᆴ' => 'ᆴ',
  'ᆵ' => 'ᆵ',
  'ᄚ' => 'ᄚ',
  'ᄆ' => 'ᄆ',
  'ᄇ' => 'ᄇ',
  'ᄈ' => 'ᄈ',
  'ᄡ' => 'ᄡ',
  'ᄉ' => 'ᄉ',
  'ᄊ' => 'ᄊ',
  'ᄋ' => 'ᄋ',
  'ᄌ' => 'ᄌ',
  'ᄍ' => 'ᄍ',
  'ᄎ' => 'ᄎ',
  'ᄏ' => 'ᄏ',
  'ᄐ' => 'ᄐ',
  'ᄑ' => 'ᄑ',
  'ᄒ' => 'ᄒ',
  'ᅡ' => 'ᅡ',
  'ᅢ' => 'ᅢ',
  'ᅣ' => 'ᅣ',
  'ᅤ' => 'ᅤ',
  'ᅥ' => 'ᅥ',
  'ᅦ' => 'ᅦ',
  'ᅧ' => 'ᅧ',
  'ᅨ' => 'ᅨ',
  'ᅩ' => 'ᅩ',
  'ᅪ' => 'ᅪ',
  'ᅫ' => 'ᅫ',
  'ᅬ' => 'ᅬ',
  'ᅭ' => 'ᅭ',
  'ᅮ' => 'ᅮ',
  'ᅯ' => 'ᅯ',
  'ᅰ' => 'ᅰ',
  'ᅱ' => 'ᅱ',
  'ᅲ' => 'ᅲ',
  'ᅳ' => 'ᅳ',
  'ᅴ' => 'ᅴ',
  'ᅵ' => 'ᅵ',
  '¢' => '¢',
  '£' => '£',
  '¬' => '¬',
  ' ̄' => ' ̄',
  '¦' => '¦',
  '¥' => '¥',
  '₩' => '₩',
  '│' => '│',
  '←' => '←',
  '↑' => '↑',
  '→' => '→',
  '↓' => '↓',
  '■' => '■',
  '○' => '○',
  '𝐀' => 'A',
  '𝐁' => 'B',
  '𝐂' => 'C',
  '𝐃' => 'D',
  '𝐄' => 'E',
  '𝐅' => 'F',
  '𝐆' => 'G',
  '𝐇' => 'H',
  '𝐈' => 'I',
  '𝐉' => 'J',
  '𝐊' => 'K',
  '𝐋' => 'L',
  '𝐌' => 'M',
  '𝐍' => 'N',
  '𝐎' => 'O',
  '𝐏' => 'P',
  '𝐐' => 'Q',
  '𝐑' => 'R',
  '𝐒' => 'S',
  '𝐓' => 'T',
  '𝐔' => 'U',
  '𝐕' => 'V',
  '𝐖' => 'W',
  '𝐗' => 'X',
  '𝐘' => 'Y',
  '𝐙' => 'Z',
  '𝐚' => 'a',
  '𝐛' => 'b',
  '𝐜' => 'c',
  '𝐝' => 'd',
  '𝐞' => 'e',
  '𝐟' => 'f',
  '𝐠' => 'g',
  '𝐡' => 'h',
  '𝐢' => 'i',
  '𝐣' => 'j',
  '𝐤' => 'k',
  '𝐥' => 'l',
  '𝐦' => 'm',
  '𝐧' => 'n',
  '𝐨' => 'o',
  '𝐩' => 'p',
  '𝐪' => 'q',
  '𝐫' => 'r',
  '𝐬' => 's',
  '𝐭' => 't',
  '𝐮' => 'u',
  '𝐯' => 'v',
  '𝐰' => 'w',
  '𝐱' => 'x',
  '𝐲' => 'y',
  '𝐳' => 'z',
  '𝐴' => 'A',
  '𝐵' => 'B',
  '𝐶' => 'C',
  '𝐷' => 'D',
  '𝐸' => 'E',
  '𝐹' => 'F',
  '𝐺' => 'G',
  '𝐻' => 'H',
  '𝐼' => 'I',
  '𝐽' => 'J',
  '𝐾' => 'K',
  '𝐿' => 'L',
  '𝑀' => 'M',
  '𝑁' => 'N',
  '𝑂' => 'O',
  '𝑃' => 'P',
  '𝑄' => 'Q',
  '𝑅' => 'R',
  '𝑆' => 'S',
  '𝑇' => 'T',
  '𝑈' => 'U',
  '𝑉' => 'V',
  '𝑊' => 'W',
  '𝑋' => 'X',
  '𝑌' => 'Y',
  '𝑍' => 'Z',
  '𝑎' => 'a',
  '𝑏' => 'b',
  '𝑐' => 'c',
  '𝑑' => 'd',
  '𝑒' => 'e',
  '𝑓' => 'f',
  '𝑔' => 'g',
  '𝑖' => 'i',
  '𝑗' => 'j',
  '𝑘' => 'k',
  '𝑙' => 'l',
  '𝑚' => 'm',
  '𝑛' => 'n',
  '𝑜' => 'o',
  '𝑝' => 'p',
  '𝑞' => 'q',
  '𝑟' => 'r',
  '𝑠' => 's',
  '𝑡' => 't',
  '𝑢' => 'u',
  '𝑣' => 'v',
  '𝑤' => 'w',
  '𝑥' => 'x',
  '𝑦' => 'y',
  '𝑧' => 'z',
  '𝑨' => 'A',
  '𝑩' => 'B',
  '𝑪' => 'C',
  '𝑫' => 'D',
  '𝑬' => 'E',
  '𝑭' => 'F',
  '𝑮' => 'G',
  '𝑯' => 'H',
  '𝑰' => 'I',
  '𝑱' => 'J',
  '𝑲' => 'K',
  '𝑳' => 'L',
  '𝑴' => 'M',
  '𝑵' => 'N',
  '𝑶' => 'O',
  '𝑷' => 'P',
  '𝑸' => 'Q',
  '𝑹' => 'R',
  '𝑺' => 'S',
  '𝑻' => 'T',
  '𝑼' => 'U',
  '𝑽' => 'V',
  '𝑾' => 'W',
  '𝑿' => 'X',
  '𝒀' => 'Y',
  '𝒁' => 'Z',
  '𝒂' => 'a',
  '𝒃' => 'b',
  '𝒄' => 'c',
  '𝒅' => 'd',
  '𝒆' => 'e',
  '𝒇' => 'f',
  '𝒈' => 'g',
  '𝒉' => 'h',
  '𝒊' => 'i',
  '𝒋' => 'j',
  '𝒌' => 'k',
  '𝒍' => 'l',
  '𝒎' => 'm',
  '𝒏' => 'n',
  '𝒐' => 'o',
  '𝒑' => 'p',
  '𝒒' => 'q',
  '𝒓' => 'r',
  '𝒔' => 's',
  '𝒕' => 't',
  '𝒖' => 'u',
  '𝒗' => 'v',
  '𝒘' => 'w',
  '𝒙' => 'x',
  '𝒚' => 'y',
  '𝒛' => 'z',
  '𝒜' => 'A',
  '𝒞' => 'C',
  '𝒟' => 'D',
  '𝒢' => 'G',
  '𝒥' => 'J',
  '𝒦' => 'K',
  '𝒩' => 'N',
  '𝒪' => 'O',
  '𝒫' => 'P',
  '𝒬' => 'Q',
  '𝒮' => 'S',
  '𝒯' => 'T',
  '𝒰' => 'U',
  '𝒱' => 'V',
  '𝒲' => 'W',
  '𝒳' => 'X',
  '𝒴' => 'Y',
  '𝒵' => 'Z',
  '𝒶' => 'a',
  '𝒷' => 'b',
  '𝒸' => 'c',
  '𝒹' => 'd',
  '𝒻' => 'f',
  '𝒽' => 'h',
  '𝒾' => 'i',
  '𝒿' => 'j',
  '𝓀' => 'k',
  '𝓁' => 'l',
  '𝓂' => 'm',
  '𝓃' => 'n',
  '𝓅' => 'p',
  '𝓆' => 'q',
  '𝓇' => 'r',
  '𝓈' => 's',
  '𝓉' => 't',
  '𝓊' => 'u',
  '𝓋' => 'v',
  '𝓌' => 'w',
  '𝓍' => 'x',
  '𝓎' => 'y',
  '𝓏' => 'z',
  '𝓐' => 'A',
  '𝓑' => 'B',
  '𝓒' => 'C',
  '𝓓' => 'D',
  '𝓔' => 'E',
  '𝓕' => 'F',
  '𝓖' => 'G',
  '𝓗' => 'H',
  '𝓘' => 'I',
  '𝓙' => 'J',
  '𝓚' => 'K',
  '𝓛' => 'L',
  '𝓜' => 'M',
  '𝓝' => 'N',
  '𝓞' => 'O',
  '𝓟' => 'P',
  '𝓠' => 'Q',
  '𝓡' => 'R',
  '𝓢' => 'S',
  '𝓣' => 'T',
  '𝓤' => 'U',
  '𝓥' => 'V',
  '𝓦' => 'W',
  '𝓧' => 'X',
  '𝓨' => 'Y',
  '𝓩' => 'Z',
  '𝓪' => 'a',
  '𝓫' => 'b',
  '𝓬' => 'c',
  '𝓭' => 'd',
  '𝓮' => 'e',
  '𝓯' => 'f',
  '𝓰' => 'g',
  '𝓱' => 'h',
  '𝓲' => 'i',
  '𝓳' => 'j',
  '𝓴' => 'k',
  '𝓵' => 'l',
  '𝓶' => 'm',
  '𝓷' => 'n',
  '𝓸' => 'o',
  '𝓹' => 'p',
  '𝓺' => 'q',
  '𝓻' => 'r',
  '𝓼' => 's',
  '𝓽' => 't',
  '𝓾' => 'u',
  '𝓿' => 'v',
  '𝔀' => 'w',
  '𝔁' => 'x',
  '𝔂' => 'y',
  '𝔃' => 'z',
  '𝔄' => 'A',
  '𝔅' => 'B',
  '𝔇' => 'D',
  '𝔈' => 'E',
  '𝔉' => 'F',
  '𝔊' => 'G',
  '𝔍' => 'J',
  '𝔎' => 'K',
  '𝔏' => 'L',
  '𝔐' => 'M',
  '𝔑' => 'N',
  '𝔒' => 'O',
  '𝔓' => 'P',
  '𝔔' => 'Q',
  '𝔖' => 'S',
  '𝔗' => 'T',
  '𝔘' => 'U',
  '𝔙' => 'V',
  '𝔚' => 'W',
  '𝔛' => 'X',
  '𝔜' => 'Y',
  '𝔞' => 'a',
  '𝔟' => 'b',
  '𝔠' => 'c',
  '𝔡' => 'd',
  '𝔢' => 'e',
  '𝔣' => 'f',
  '𝔤' => 'g',
  '𝔥' => 'h',
  '𝔦' => 'i',
  '𝔧' => 'j',
  '𝔨' => 'k',
  '𝔩' => 'l',
  '𝔪' => 'm',
  '𝔫' => 'n',
  '𝔬' => 'o',
  '𝔭' => 'p',
  '𝔮' => 'q',
  '𝔯' => 'r',
  '𝔰' => 's',
  '𝔱' => 't',
  '𝔲' => 'u',
  '𝔳' => 'v',
  '𝔴' => 'w',
  '𝔵' => 'x',
  '𝔶' => 'y',
  '𝔷' => 'z',
  '𝔸' => 'A',
  '𝔹' => 'B',
  '𝔻' => 'D',
  '𝔼' => 'E',
  '𝔽' => 'F',
  '𝔾' => 'G',
  '𝕀' => 'I',
  '𝕁' => 'J',
  '𝕂' => 'K',
  '𝕃' => 'L',
  '𝕄' => 'M',
  '𝕆' => 'O',
  '𝕊' => 'S',
  '𝕋' => 'T',
  '𝕌' => 'U',
  '𝕍' => 'V',
  '𝕎' => 'W',
  '𝕏' => 'X',
  '𝕐' => 'Y',
  '𝕒' => 'a',
  '𝕓' => 'b',
  '𝕔' => 'c',
  '𝕕' => 'd',
  '𝕖' => 'e',
  '𝕗' => 'f',
  '𝕘' => 'g',
  '𝕙' => 'h',
  '𝕚' => 'i',
  '𝕛' => 'j',
  '𝕜' => 'k',
  '𝕝' => 'l',
  '𝕞' => 'm',
  '𝕟' => 'n',
  '𝕠' => 'o',
  '𝕡' => 'p',
  '𝕢' => 'q',
  '𝕣' => 'r',
  '𝕤' => 's',
  '𝕥' => 't',
  '𝕦' => 'u',
  '𝕧' => 'v',
  '𝕨' => 'w',
  '𝕩' => 'x',
  '𝕪' => 'y',
  '𝕫' => 'z',
  '𝕬' => 'A',
  '𝕭' => 'B',
  '𝕮' => 'C',
  '𝕯' => 'D',
  '𝕰' => 'E',
  '𝕱' => 'F',
  '𝕲' => 'G',
  '𝕳' => 'H',
  '𝕴' => 'I',
  '𝕵' => 'J',
  '𝕶' => 'K',
  '𝕷' => 'L',
  '𝕸' => 'M',
  '𝕹' => 'N',
  '𝕺' => 'O',
  '𝕻' => 'P',
  '𝕼' => 'Q',
  '𝕽' => 'R',
  '𝕾' => 'S',
  '𝕿' => 'T',
  '𝖀' => 'U',
  '𝖁' => 'V',
  '𝖂' => 'W',
  '𝖃' => 'X',
  '𝖄' => 'Y',
  '𝖅' => 'Z',
  '𝖆' => 'a',
  '𝖇' => 'b',
  '𝖈' => 'c',
  '𝖉' => 'd',
  '𝖊' => 'e',
  '𝖋' => 'f',
  '𝖌' => 'g',
  '𝖍' => 'h',
  '𝖎' => 'i',
  '𝖏' => 'j',
  '𝖐' => 'k',
  '𝖑' => 'l',
  '𝖒' => 'm',
  '𝖓' => 'n',
  '𝖔' => 'o',
  '𝖕' => 'p',
  '𝖖' => 'q',
  '𝖗' => 'r',
  '𝖘' => 's',
  '𝖙' => 't',
  '𝖚' => 'u',
  '𝖛' => 'v',
  '𝖜' => 'w',
  '𝖝' => 'x',
  '𝖞' => 'y',
  '𝖟' => 'z',
  '𝖠' => 'A',
  '𝖡' => 'B',
  '𝖢' => 'C',
  '𝖣' => 'D',
  '𝖤' => 'E',
  '𝖥' => 'F',
  '𝖦' => 'G',
  '𝖧' => 'H',
  '𝖨' => 'I',
  '𝖩' => 'J',
  '𝖪' => 'K',
  '𝖫' => 'L',
  '𝖬' => 'M',
  '𝖭' => 'N',
  '𝖮' => 'O',
  '𝖯' => 'P',
  '𝖰' => 'Q',
  '𝖱' => 'R',
  '𝖲' => 'S',
  '𝖳' => 'T',
  '𝖴' => 'U',
  '𝖵' => 'V',
  '𝖶' => 'W',
  '𝖷' => 'X',
  '𝖸' => 'Y',
  '𝖹' => 'Z',
  '𝖺' => 'a',
  '𝖻' => 'b',
  '𝖼' => 'c',
  '𝖽' => 'd',
  '𝖾' => 'e',
  '𝖿' => 'f',
  '𝗀' => 'g',
  '𝗁' => 'h',
  '𝗂' => 'i',
  '𝗃' => 'j',
  '𝗄' => 'k',
  '𝗅' => 'l',
  '𝗆' => 'm',
  '𝗇' => 'n',
  '𝗈' => 'o',
  '𝗉' => 'p',
  '𝗊' => 'q',
  '𝗋' => 'r',
  '𝗌' => 's',
  '𝗍' => 't',
  '𝗎' => 'u',
  '𝗏' => 'v',
  '𝗐' => 'w',
  '𝗑' => 'x',
  '𝗒' => 'y',
  '𝗓' => 'z',
  '𝗔' => 'A',
  '𝗕' => 'B',
  '𝗖' => 'C',
  '𝗗' => 'D',
  '𝗘' => 'E',
  '𝗙' => 'F',
  '𝗚' => 'G',
  '𝗛' => 'H',
  '𝗜' => 'I',
  '𝗝' => 'J',
  '𝗞' => 'K',
  '𝗟' => 'L',
  '𝗠' => 'M',
  '𝗡' => 'N',
  '𝗢' => 'O',
  '𝗣' => 'P',
  '𝗤' => 'Q',
  '𝗥' => 'R',
  '𝗦' => 'S',
  '𝗧' => 'T',
  '𝗨' => 'U',
  '𝗩' => 'V',
  '𝗪' => 'W',
  '𝗫' => 'X',
  '𝗬' => 'Y',
  '𝗭' => 'Z',
  '𝗮' => 'a',
  '𝗯' => 'b',
  '𝗰' => 'c',
  '𝗱' => 'd',
  '𝗲' => 'e',
  '𝗳' => 'f',
  '𝗴' => 'g',
  '𝗵' => 'h',
  '𝗶' => 'i',
  '𝗷' => 'j',
  '𝗸' => 'k',
  '𝗹' => 'l',
  '𝗺' => 'm',
  '𝗻' => 'n',
  '𝗼' => 'o',
  '𝗽' => 'p',
  '𝗾' => 'q',
  '𝗿' => 'r',
  '𝘀' => 's',
  '𝘁' => 't',
  '𝘂' => 'u',
  '𝘃' => 'v',
  '𝘄' => 'w',
  '𝘅' => 'x',
  '𝘆' => 'y',
  '𝘇' => 'z',
  '𝘈' => 'A',
  '𝘉' => 'B',
  '𝘊' => 'C',
  '𝘋' => 'D',
  '𝘌' => 'E',
  '𝘍' => 'F',
  '𝘎' => 'G',
  '𝘏' => 'H',
  '𝘐' => 'I',
  '𝘑' => 'J',
  '𝘒' => 'K',
  '𝘓' => 'L',
  '𝘔' => 'M',
  '𝘕' => 'N',
  '𝘖' => 'O',
  '𝘗' => 'P',
  '𝘘' => 'Q',
  '𝘙' => 'R',
  '𝘚' => 'S',
  '𝘛' => 'T',
  '𝘜' => 'U',
  '𝘝' => 'V',
  '𝘞' => 'W',
  '𝘟' => 'X',
  '𝘠' => 'Y',
  '𝘡' => 'Z',
  '𝘢' => 'a',
  '𝘣' => 'b',
  '𝘤' => 'c',
  '𝘥' => 'd',
  '𝘦' => 'e',
  '𝘧' => 'f',
  '𝘨' => 'g',
  '𝘩' => 'h',
  '𝘪' => 'i',
  '𝘫' => 'j',
  '𝘬' => 'k',
  '𝘭' => 'l',
  '𝘮' => 'm',
  '𝘯' => 'n',
  '𝘰' => 'o',
  '𝘱' => 'p',
  '𝘲' => 'q',
  '𝘳' => 'r',
  '𝘴' => 's',
  '𝘵' => 't',
  '𝘶' => 'u',
  '𝘷' => 'v',
  '𝘸' => 'w',
  '𝘹' => 'x',
  '𝘺' => 'y',
  '𝘻' => 'z',
  '𝘼' => 'A',
  '𝘽' => 'B',
  '𝘾' => 'C',
  '𝘿' => 'D',
  '𝙀' => 'E',
  '𝙁' => 'F',
  '𝙂' => 'G',
  '𝙃' => 'H',
  '𝙄' => 'I',
  '𝙅' => 'J',
  '𝙆' => 'K',
  '𝙇' => 'L',
  '𝙈' => 'M',
  '𝙉' => 'N',
  '𝙊' => 'O',
  '𝙋' => 'P',
  '𝙌' => 'Q',
  '𝙍' => 'R',
  '𝙎' => 'S',
  '𝙏' => 'T',
  '𝙐' => 'U',
  '𝙑' => 'V',
  '𝙒' => 'W',
  '𝙓' => 'X',
  '𝙔' => 'Y',
  '𝙕' => 'Z',
  '𝙖' => 'a',
  '𝙗' => 'b',
  '𝙘' => 'c',
  '𝙙' => 'd',
  '𝙚' => 'e',
  '𝙛' => 'f',
  '𝙜' => 'g',
  '𝙝' => 'h',
  '𝙞' => 'i',
  '𝙟' => 'j',
  '𝙠' => 'k',
  '𝙡' => 'l',
  '𝙢' => 'm',
  '𝙣' => 'n',
  '𝙤' => 'o',
  '𝙥' => 'p',
  '𝙦' => 'q',
  '𝙧' => 'r',
  '𝙨' => 's',
  '𝙩' => 't',
  '𝙪' => 'u',
  '𝙫' => 'v',
  '𝙬' => 'w',
  '𝙭' => 'x',
  '𝙮' => 'y',
  '𝙯' => 'z',
  '𝙰' => 'A',
  '𝙱' => 'B',
  '𝙲' => 'C',
  '𝙳' => 'D',
  '𝙴' => 'E',
  '𝙵' => 'F',
  '𝙶' => 'G',
  '𝙷' => 'H',
  '𝙸' => 'I',
  '𝙹' => 'J',
  '𝙺' => 'K',
  '𝙻' => 'L',
  '𝙼' => 'M',
  '𝙽' => 'N',
  '𝙾' => 'O',
  '𝙿' => 'P',
  '𝚀' => 'Q',
  '𝚁' => 'R',
  '𝚂' => 'S',
  '𝚃' => 'T',
  '𝚄' => 'U',
  '𝚅' => 'V',
  '𝚆' => 'W',
  '𝚇' => 'X',
  '𝚈' => 'Y',
  '𝚉' => 'Z',
  '𝚊' => 'a',
  '𝚋' => 'b',
  '𝚌' => 'c',
  '𝚍' => 'd',
  '𝚎' => 'e',
  '𝚏' => 'f',
  '𝚐' => 'g',
  '𝚑' => 'h',
  '𝚒' => 'i',
  '𝚓' => 'j',
  '𝚔' => 'k',
  '𝚕' => 'l',
  '𝚖' => 'm',
  '𝚗' => 'n',
  '𝚘' => 'o',
  '𝚙' => 'p',
  '𝚚' => 'q',
  '𝚛' => 'r',
  '𝚜' => 's',
  '𝚝' => 't',
  '𝚞' => 'u',
  '𝚟' => 'v',
  '𝚠' => 'w',
  '𝚡' => 'x',
  '𝚢' => 'y',
  '𝚣' => 'z',
  '𝚤' => 'ı',
  '𝚥' => 'ȷ',
  '𝚨' => 'Α',
  '𝚩' => 'Β',
  '𝚪' => 'Γ',
  '𝚫' => 'Δ',
  '𝚬' => 'Ε',
  '𝚭' => 'Ζ',
  '𝚮' => 'Η',
  '𝚯' => 'Θ',
  '𝚰' => 'Ι',
  '𝚱' => 'Κ',
  '𝚲' => 'Λ',
  '𝚳' => 'Μ',
  '𝚴' => 'Ν',
  '𝚵' => 'Ξ',
  '𝚶' => 'Ο',
  '𝚷' => 'Π',
  '𝚸' => 'Ρ',
  '𝚹' => 'Θ',
  '𝚺' => 'Σ',
  '𝚻' => 'Τ',
  '𝚼' => 'Υ',
  '𝚽' => 'Φ',
  '𝚾' => 'Χ',
  '𝚿' => 'Ψ',
  '𝛀' => 'Ω',
  '𝛁' => '∇',
  '𝛂' => 'α',
  '𝛃' => 'β',
  '𝛄' => 'γ',
  '𝛅' => 'δ',
  '𝛆' => 'ε',
  '𝛇' => 'ζ',
  '𝛈' => 'η',
  '𝛉' => 'θ',
  '𝛊' => 'ι',
  '𝛋' => 'κ',
  '𝛌' => 'λ',
  '𝛍' => 'μ',
  '𝛎' => 'ν',
  '𝛏' => 'ξ',
  '𝛐' => 'ο',
  '𝛑' => 'π',
  '𝛒' => 'ρ',
  '𝛓' => 'ς',
  '𝛔' => 'σ',
  '𝛕' => 'τ',
  '𝛖' => 'υ',
  '𝛗' => 'φ',
  '𝛘' => 'χ',
  '𝛙' => 'ψ',
  '𝛚' => 'ω',
  '𝛛' => '∂',
  '𝛜' => 'ε',
  '𝛝' => 'θ',
  '𝛞' => 'κ',
  '𝛟' => 'φ',
  '𝛠' => 'ρ',
  '𝛡' => 'π',
  '𝛢' => 'Α',
  '𝛣' => 'Β',
  '𝛤' => 'Γ',
  '𝛥' => 'Δ',
  '𝛦' => 'Ε',
  '𝛧' => 'Ζ',
  '𝛨' => 'Η',
  '𝛩' => 'Θ',
  '𝛪' => 'Ι',
  '𝛫' => 'Κ',
  '𝛬' => 'Λ',
  '𝛭' => 'Μ',
  '𝛮' => 'Ν',
  '𝛯' => 'Ξ',
  '𝛰' => 'Ο',
  '𝛱' => 'Π',
  '𝛲' => 'Ρ',
  '𝛳' => 'Θ',
  '𝛴' => 'Σ',
  '𝛵' => 'Τ',
  '𝛶' => 'Υ',
  '𝛷' => 'Φ',
  '𝛸' => 'Χ',
  '𝛹' => 'Ψ',
  '𝛺' => 'Ω',
  '𝛻' => '∇',
  '𝛼' => 'α',
  '𝛽' => 'β',
  '𝛾' => 'γ',
  '𝛿' => 'δ',
  '𝜀' => 'ε',
  '𝜁' => 'ζ',
  '𝜂' => 'η',
  '𝜃' => 'θ',
  '𝜄' => 'ι',
  '𝜅' => 'κ',
  '𝜆' => 'λ',
  '𝜇' => 'μ',
  '𝜈' => 'ν',
  '𝜉' => 'ξ',
  '𝜊' => 'ο',
  '𝜋' => 'π',
  '𝜌' => 'ρ',
  '𝜍' => 'ς',
  '𝜎' => 'σ',
  '𝜏' => 'τ',
  '𝜐' => 'υ',
  '𝜑' => 'φ',
  '𝜒' => 'χ',
  '𝜓' => 'ψ',
  '𝜔' => 'ω',
  '𝜕' => '∂',
  '𝜖' => 'ε',
  '𝜗' => 'θ',
  '𝜘' => 'κ',
  '𝜙' => 'φ',
  '𝜚' => 'ρ',
  '𝜛' => 'π',
  '𝜜' => 'Α',
  '𝜝' => 'Β',
  '𝜞' => 'Γ',
  '𝜟' => 'Δ',
  '𝜠' => 'Ε',
  '𝜡' => 'Ζ',
  '𝜢' => 'Η',
  '𝜣' => 'Θ',
  '𝜤' => 'Ι',
  '𝜥' => 'Κ',
  '𝜦' => 'Λ',
  '𝜧' => 'Μ',
  '𝜨' => 'Ν',
  '𝜩' => 'Ξ',
  '𝜪' => 'Ο',
  '𝜫' => 'Π',
  '𝜬' => 'Ρ',
  '𝜭' => 'Θ',
  '𝜮' => 'Σ',
  '𝜯' => 'Τ',
  '𝜰' => 'Υ',
  '𝜱' => 'Φ',
  '𝜲' => 'Χ',
  '𝜳' => 'Ψ',
  '𝜴' => 'Ω',
  '𝜵' => '∇',
  '𝜶' => 'α',
  '𝜷' => 'β',
  '𝜸' => 'γ',
  '𝜹' => 'δ',
  '𝜺' => 'ε',
  '𝜻' => 'ζ',
  '𝜼' => 'η',
  '𝜽' => 'θ',
  '𝜾' => 'ι',
  '𝜿' => 'κ',
  '𝝀' => 'λ',
  '𝝁' => 'μ',
  '𝝂' => 'ν',
  '𝝃' => 'ξ',
  '𝝄' => 'ο',
  '𝝅' => 'π',
  '𝝆' => 'ρ',
  '𝝇' => 'ς',
  '𝝈' => 'σ',
  '𝝉' => 'τ',
  '𝝊' => 'υ',
  '𝝋' => 'φ',
  '𝝌' => 'χ',
  '𝝍' => 'ψ',
  '𝝎' => 'ω',
  '𝝏' => '∂',
  '𝝐' => 'ε',
  '𝝑' => 'θ',
  '𝝒' => 'κ',
  '𝝓' => 'φ',
  '𝝔' => 'ρ',
  '𝝕' => 'π',
  '𝝖' => 'Α',
  '𝝗' => 'Β',
  '𝝘' => 'Γ',
  '𝝙' => 'Δ',
  '𝝚' => 'Ε',
  '𝝛' => 'Ζ',
  '𝝜' => 'Η',
  '𝝝' => 'Θ',
  '𝝞' => 'Ι',
  '𝝟' => 'Κ',
  '𝝠' => 'Λ',
  '𝝡' => 'Μ',
  '𝝢' => 'Ν',
  '𝝣' => 'Ξ',
  '𝝤' => 'Ο',
  '𝝥' => 'Π',
  '𝝦' => 'Ρ',
  '𝝧' => 'Θ',
  '𝝨' => 'Σ',
  '𝝩' => 'Τ',
  '𝝪' => 'Υ',
  '𝝫' => 'Φ',
  '𝝬' => 'Χ',
  '𝝭' => 'Ψ',
  '𝝮' => 'Ω',
  '𝝯' => '∇',
  '𝝰' => 'α',
  '𝝱' => 'β',
  '𝝲' => 'γ',
  '𝝳' => 'δ',
  '𝝴' => 'ε',
  '𝝵' => 'ζ',
  '𝝶' => 'η',
  '𝝷' => 'θ',
  '𝝸' => 'ι',
  '𝝹' => 'κ',
  '𝝺' => 'λ',
  '𝝻' => 'μ',
  '𝝼' => 'ν',
  '𝝽' => 'ξ',
  '𝝾' => 'ο',
  '𝝿' => 'π',
  '𝞀' => 'ρ',
  '𝞁' => 'ς',
  '𝞂' => 'σ',
  '𝞃' => 'τ',
  '𝞄' => 'υ',
  '𝞅' => 'φ',
  '𝞆' => 'χ',
  '𝞇' => 'ψ',
  '𝞈' => 'ω',
  '𝞉' => '∂',
  '𝞊' => 'ε',
  '𝞋' => 'θ',
  '𝞌' => 'κ',
  '𝞍' => 'φ',
  '𝞎' => 'ρ',
  '𝞏' => 'π',
  '𝞐' => 'Α',
  '𝞑' => 'Β',
  '𝞒' => 'Γ',
  '𝞓' => 'Δ',
  '𝞔' => 'Ε',
  '𝞕' => 'Ζ',
  '𝞖' => 'Η',
  '𝞗' => 'Θ',
  '𝞘' => 'Ι',
  '𝞙' => 'Κ',
  '𝞚' => 'Λ',
  '𝞛' => 'Μ',
  '𝞜' => 'Ν',
  '𝞝' => 'Ξ',
  '𝞞' => 'Ο',
  '𝞟' => 'Π',
  '𝞠' => 'Ρ',
  '𝞡' => 'Θ',
  '𝞢' => 'Σ',
  '𝞣' => 'Τ',
  '𝞤' => 'Υ',
  '𝞥' => 'Φ',
  '𝞦' => 'Χ',
  '𝞧' => 'Ψ',
  '𝞨' => 'Ω',
  '𝞩' => '∇',
  '𝞪' => 'α',
  '𝞫' => 'β',
  '𝞬' => 'γ',
  '𝞭' => 'δ',
  '𝞮' => 'ε',
  '𝞯' => 'ζ',
  '𝞰' => 'η',
  '𝞱' => 'θ',
  '𝞲' => 'ι',
  '𝞳' => 'κ',
  '𝞴' => 'λ',
  '𝞵' => 'μ',
  '𝞶' => 'ν',
  '𝞷' => 'ξ',
  '𝞸' => 'ο',
  '𝞹' => 'π',
  '𝞺' => 'ρ',
  '𝞻' => 'ς',
  '𝞼' => 'σ',
  '𝞽' => 'τ',
  '𝞾' => 'υ',
  '𝞿' => 'φ',
  '𝟀' => 'χ',
  '𝟁' => 'ψ',
  '𝟂' => 'ω',
  '𝟃' => '∂',
  '𝟄' => 'ε',
  '𝟅' => 'θ',
  '𝟆' => 'κ',
  '𝟇' => 'φ',
  '𝟈' => 'ρ',
  '𝟉' => 'π',
  '𝟊' => 'Ϝ',
  '𝟋' => 'ϝ',
  '𝟎' => '0',
  '𝟏' => '1',
  '𝟐' => '2',
  '𝟑' => '3',
  '𝟒' => '4',
  '𝟓' => '5',
  '𝟔' => '6',
  '𝟕' => '7',
  '𝟖' => '8',
  '𝟗' => '9',
  '𝟘' => '0',
  '𝟙' => '1',
  '𝟚' => '2',
  '𝟛' => '3',
  '𝟜' => '4',
  '𝟝' => '5',
  '𝟞' => '6',
  '𝟟' => '7',
  '𝟠' => '8',
  '𝟡' => '9',
  '𝟢' => '0',
  '𝟣' => '1',
  '𝟤' => '2',
  '𝟥' => '3',
  '𝟦' => '4',
  '𝟧' => '5',
  '𝟨' => '6',
  '𝟩' => '7',
  '𝟪' => '8',
  '𝟫' => '9',
  '𝟬' => '0',
  '𝟭' => '1',
  '𝟮' => '2',
  '𝟯' => '3',
  '𝟰' => '4',
  '𝟱' => '5',
  '𝟲' => '6',
  '𝟳' => '7',
  '𝟴' => '8',
  '𝟵' => '9',
  '𝟶' => '0',
  '𝟷' => '1',
  '𝟸' => '2',
  '𝟹' => '3',
  '𝟺' => '4',
  '𝟻' => '5',
  '𝟼' => '6',
  '𝟽' => '7',
  '𝟾' => '8',
  '𝟿' => '9',
  '𞸀' => 'ا',
  '𞸁' => 'ب',
  '𞸂' => 'ج',
  '𞸃' => 'د',
  '𞸅' => 'و',
  '𞸆' => 'ز',
  '𞸇' => 'ح',
  '𞸈' => 'ط',
  '𞸉' => 'ي',
  '𞸊' => 'ك',
  '𞸋' => 'ل',
  '𞸌' => 'م',
  '𞸍' => 'ن',
  '𞸎' => 'س',
  '𞸏' => 'ع',
  '𞸐' => 'ف',
  '𞸑' => 'ص',
  '𞸒' => 'ق',
  '𞸓' => 'ر',
  '𞸔' => 'ش',
  '𞸕' => 'ت',
  '𞸖' => 'ث',
  '𞸗' => 'خ',
  '𞸘' => 'ذ',
  '𞸙' => 'ض',
  '𞸚' => 'ظ',
  '𞸛' => 'غ',
  '𞸜' => 'ٮ',
  '𞸝' => 'ں',
  '𞸞' => 'ڡ',
  '𞸟' => 'ٯ',
  '𞸡' => 'ب',
  '𞸢' => 'ج',
  '𞸤' => 'ه',
  '𞸧' => 'ح',
  '𞸩' => 'ي',
  '𞸪' => 'ك',
  '𞸫' => 'ل',
  '𞸬' => 'م',
  '𞸭' => 'ن',
  '𞸮' => 'س',
  '𞸯' => 'ع',
  '𞸰' => 'ف',
  '𞸱' => 'ص',
  '𞸲' => 'ق',
  '𞸴' => 'ش',
  '𞸵' => 'ت',
  '𞸶' => 'ث',
  '𞸷' => 'خ',
  '𞸹' => 'ض',
  '𞸻' => 'غ',
  '𞹂' => 'ج',
  '𞹇' => 'ح',
  '𞹉' => 'ي',
  '𞹋' => 'ل',
  '𞹍' => 'ن',
  '𞹎' => 'س',
  '𞹏' => 'ع',
  '𞹑' => 'ص',
  '𞹒' => 'ق',
  '𞹔' => 'ش',
  '𞹗' => 'خ',
  '𞹙' => 'ض',
  '𞹛' => 'غ',
  '𞹝' => 'ں',
  '𞹟' => 'ٯ',
  '𞹡' => 'ب',
  '𞹢' => 'ج',
  '𞹤' => 'ه',
  '𞹧' => 'ح',
  '𞹨' => 'ط',
  '𞹩' => 'ي',
  '𞹪' => 'ك',
  '𞹬' => 'م',
  '𞹭' => 'ن',
  '𞹮' => 'س',
  '𞹯' => 'ع',
  '𞹰' => 'ف',
  '𞹱' => 'ص',
  '𞹲' => 'ق',
  '𞹴' => 'ش',
  '𞹵' => 'ت',
  '𞹶' => 'ث',
  '𞹷' => 'خ',
  '𞹹' => 'ض',
  '𞹺' => 'ظ',
  '𞹻' => 'غ',
  '𞹼' => 'ٮ',
  '𞹾' => 'ڡ',
  '𞺀' => 'ا',
  '𞺁' => 'ب',
  '𞺂' => 'ج',
  '𞺃' => 'د',
  '𞺄' => 'ه',
  '𞺅' => 'و',
  '𞺆' => 'ز',
  '𞺇' => 'ح',
  '𞺈' => 'ط',
  '𞺉' => 'ي',
  '𞺋' => 'ل',
  '𞺌' => 'م',
  '𞺍' => 'ن',
  '𞺎' => 'س',
  '𞺏' => 'ع',
  '𞺐' => 'ف',
  '𞺑' => 'ص',
  '𞺒' => 'ق',
  '𞺓' => 'ر',
  '𞺔' => 'ش',
  '𞺕' => 'ت',
  '𞺖' => 'ث',
  '𞺗' => 'خ',
  '𞺘' => 'ذ',
  '𞺙' => 'ض',
  '𞺚' => 'ظ',
  '𞺛' => 'غ',
  '𞺡' => 'ب',
  '𞺢' => 'ج',
  '𞺣' => 'د',
  '𞺥' => 'و',
  '𞺦' => 'ز',
  '𞺧' => 'ح',
  '𞺨' => 'ط',
  '𞺩' => 'ي',
  '𞺫' => 'ل',
  '𞺬' => 'م',
  '𞺭' => 'ن',
  '𞺮' => 'س',
  '𞺯' => 'ع',
  '𞺰' => 'ف',
  '𞺱' => 'ص',
  '𞺲' => 'ق',
  '𞺳' => 'ر',
  '𞺴' => 'ش',
  '𞺵' => 'ت',
  '𞺶' => 'ث',
  '𞺷' => 'خ',
  '𞺸' => 'ذ',
  '𞺹' => 'ض',
  '𞺺' => 'ظ',
  '𞺻' => 'غ',
  '🄀' => '0.',
  '🄁' => '0,',
  '🄂' => '1,',
  '🄃' => '2,',
  '🄄' => '3,',
  '🄅' => '4,',
  '🄆' => '5,',
  '🄇' => '6,',
  '🄈' => '7,',
  '🄉' => '8,',
  '🄊' => '9,',
  '🄐' => '(A)',
  '🄑' => '(B)',
  '🄒' => '(C)',
  '🄓' => '(D)',
  '🄔' => '(E)',
  '🄕' => '(F)',
  '🄖' => '(G)',
  '🄗' => '(H)',
  '🄘' => '(I)',
  '🄙' => '(J)',
  '🄚' => '(K)',
  '🄛' => '(L)',
  '🄜' => '(M)',
  '🄝' => '(N)',
  '🄞' => '(O)',
  '🄟' => '(P)',
  '🄠' => '(Q)',
  '🄡' => '(R)',
  '🄢' => '(S)',
  '🄣' => '(T)',
  '🄤' => '(U)',
  '🄥' => '(V)',
  '🄦' => '(W)',
  '🄧' => '(X)',
  '🄨' => '(Y)',
  '🄩' => '(Z)',
  '🄪' => '〔S〕',
  '🄫' => 'C',
  '🄬' => 'R',
  '🄭' => 'CD',
  '🄮' => 'WZ',
  '🄰' => 'A',
  '🄱' => 'B',
  '🄲' => 'C',
  '🄳' => 'D',
  '🄴' => 'E',
  '🄵' => 'F',
  '🄶' => 'G',
  '🄷' => 'H',
  '🄸' => 'I',
  '🄹' => 'J',
  '🄺' => 'K',
  '🄻' => 'L',
  '🄼' => 'M',
  '🄽' => 'N',
  '🄾' => 'O',
  '🄿' => 'P',
  '🅀' => 'Q',
  '🅁' => 'R',
  '🅂' => 'S',
  '🅃' => 'T',
  '🅄' => 'U',
  '🅅' => 'V',
  '🅆' => 'W',
  '🅇' => 'X',
  '🅈' => 'Y',
  '🅉' => 'Z',
  '🅊' => 'HV',
  '🅋' => 'MV',
  '🅌' => 'SD',
  '🅍' => 'SS',
  '🅎' => 'PPV',
  '🅏' => 'WC',
  '🅪' => 'MC',
  '🅫' => 'MD',
  '🅬' => 'MR',
  '🆐' => 'DJ',
  '🈀' => 'ほか',
  '🈁' => 'ココ',
  '🈂' => 'サ',
  '🈐' => '手',
  '🈑' => '字',
  '🈒' => '双',
  '🈓' => 'デ',
  '🈔' => '二',
  '🈕' => '多',
  '🈖' => '解',
  '🈗' => '天',
  '🈘' => '交',
  '🈙' => '映',
  '🈚' => '無',
  '🈛' => '料',
  '🈜' => '前',
  '🈝' => '後',
  '🈞' => '再',
  '🈟' => '新',
  '🈠' => '初',
  '🈡' => '終',
  '🈢' => '生',
  '🈣' => '販',
  '🈤' => '声',
  '🈥' => '吹',
  '🈦' => '演',
  '🈧' => '投',
  '🈨' => '捕',
  '🈩' => '一',
  '🈪' => '三',
  '🈫' => '遊',
  '🈬' => '左',
  '🈭' => '中',
  '🈮' => '右',
  '🈯' => '指',
  '🈰' => '走',
  '🈱' => '打',
  '🈲' => '禁',
  '🈳' => '空',
  '🈴' => '合',
  '🈵' => '満',
  '🈶' => '有',
  '🈷' => '月',
  '🈸' => '申',
  '🈹' => '割',
  '🈺' => '営',
  '🈻' => '配',
  '🉀' => '〔本〕',
  '🉁' => '〔三〕',
  '🉂' => '〔二〕',
  '🉃' => '〔安〕',
  '🉄' => '〔点〕',
  '🉅' => '〔打〕',
  '🉆' => '〔盗〕',
  '🉇' => '〔勝〕',
  '🉈' => '〔敗〕',
  '🉐' => '得',
  '🉑' => '可',
  '🯰' => '0',
  '🯱' => '1',
  '🯲' => '2',
  '🯳' => '3',
  '🯴' => '4',
  '🯵' => '5',
  '🯶' => '6',
  '🯷' => '7',
  '🯸' => '8',
  '🯹' => '9',
);
PKϤ$Z'�C��D�DCpolyfill-intl-normalizer/Resources/unidata/canonicalComposition.phpnu�[���<?php

return array (
  'À' => 'À',
  'Á' => 'Á',
  'Â' => 'Â',
  'Ã' => 'Ã',
  'Ä' => 'Ä',
  'Å' => 'Å',
  'Ç' => 'Ç',
  'È' => 'È',
  'É' => 'É',
  'Ê' => 'Ê',
  'Ë' => 'Ë',
  'Ì' => 'Ì',
  'Í' => 'Í',
  'Î' => 'Î',
  'Ï' => 'Ï',
  'Ñ' => 'Ñ',
  'Ò' => 'Ò',
  'Ó' => 'Ó',
  'Ô' => 'Ô',
  'Õ' => 'Õ',
  'Ö' => 'Ö',
  'Ù' => 'Ù',
  'Ú' => 'Ú',
  'Û' => 'Û',
  'Ü' => 'Ü',
  'Ý' => 'Ý',
  'à' => 'à',
  'á' => 'á',
  'â' => 'â',
  'ã' => 'ã',
  'ä' => 'ä',
  'å' => 'å',
  'ç' => 'ç',
  'è' => 'è',
  'é' => 'é',
  'ê' => 'ê',
  'ë' => 'ë',
  'ì' => 'ì',
  'í' => 'í',
  'î' => 'î',
  'ï' => 'ï',
  'ñ' => 'ñ',
  'ò' => 'ò',
  'ó' => 'ó',
  'ô' => 'ô',
  'õ' => 'õ',
  'ö' => 'ö',
  'ù' => 'ù',
  'ú' => 'ú',
  'û' => 'û',
  'ü' => 'ü',
  'ý' => 'ý',
  'ÿ' => 'ÿ',
  'Ā' => 'Ā',
  'ā' => 'ā',
  'Ă' => 'Ă',
  'ă' => 'ă',
  'Ą' => 'Ą',
  'ą' => 'ą',
  'Ć' => 'Ć',
  'ć' => 'ć',
  'Ĉ' => 'Ĉ',
  'ĉ' => 'ĉ',
  'Ċ' => 'Ċ',
  'ċ' => 'ċ',
  'Č' => 'Č',
  'č' => 'č',
  'Ď' => 'Ď',
  'ď' => 'ď',
  'Ē' => 'Ē',
  'ē' => 'ē',
  'Ĕ' => 'Ĕ',
  'ĕ' => 'ĕ',
  'Ė' => 'Ė',
  'ė' => 'ė',
  'Ę' => 'Ę',
  'ę' => 'ę',
  'Ě' => 'Ě',
  'ě' => 'ě',
  'Ĝ' => 'Ĝ',
  'ĝ' => 'ĝ',
  'Ğ' => 'Ğ',
  'ğ' => 'ğ',
  'Ġ' => 'Ġ',
  'ġ' => 'ġ',
  'Ģ' => 'Ģ',
  'ģ' => 'ģ',
  'Ĥ' => 'Ĥ',
  'ĥ' => 'ĥ',
  'Ĩ' => 'Ĩ',
  'ĩ' => 'ĩ',
  'Ī' => 'Ī',
  'ī' => 'ī',
  'Ĭ' => 'Ĭ',
  'ĭ' => 'ĭ',
  'Į' => 'Į',
  'į' => 'į',
  'İ' => 'İ',
  'Ĵ' => 'Ĵ',
  'ĵ' => 'ĵ',
  'Ķ' => 'Ķ',
  'ķ' => 'ķ',
  'Ĺ' => 'Ĺ',
  'ĺ' => 'ĺ',
  'Ļ' => 'Ļ',
  'ļ' => 'ļ',
  'Ľ' => 'Ľ',
  'ľ' => 'ľ',
  'Ń' => 'Ń',
  'ń' => 'ń',
  'Ņ' => 'Ņ',
  'ņ' => 'ņ',
  'Ň' => 'Ň',
  'ň' => 'ň',
  'Ō' => 'Ō',
  'ō' => 'ō',
  'Ŏ' => 'Ŏ',
  'ŏ' => 'ŏ',
  'Ő' => 'Ő',
  'ő' => 'ő',
  'Ŕ' => 'Ŕ',
  'ŕ' => 'ŕ',
  'Ŗ' => 'Ŗ',
  'ŗ' => 'ŗ',
  'Ř' => 'Ř',
  'ř' => 'ř',
  'Ś' => 'Ś',
  'ś' => 'ś',
  'Ŝ' => 'Ŝ',
  'ŝ' => 'ŝ',
  'Ş' => 'Ş',
  'ş' => 'ş',
  'Š' => 'Š',
  'š' => 'š',
  'Ţ' => 'Ţ',
  'ţ' => 'ţ',
  'Ť' => 'Ť',
  'ť' => 'ť',
  'Ũ' => 'Ũ',
  'ũ' => 'ũ',
  'Ū' => 'Ū',
  'ū' => 'ū',
  'Ŭ' => 'Ŭ',
  'ŭ' => 'ŭ',
  'Ů' => 'Ů',
  'ů' => 'ů',
  'Ű' => 'Ű',
  'ű' => 'ű',
  'Ų' => 'Ų',
  'ų' => 'ų',
  'Ŵ' => 'Ŵ',
  'ŵ' => 'ŵ',
  'Ŷ' => 'Ŷ',
  'ŷ' => 'ŷ',
  'Ÿ' => 'Ÿ',
  'Ź' => 'Ź',
  'ź' => 'ź',
  'Ż' => 'Ż',
  'ż' => 'ż',
  'Ž' => 'Ž',
  'ž' => 'ž',
  'Ơ' => 'Ơ',
  'ơ' => 'ơ',
  'Ư' => 'Ư',
  'ư' => 'ư',
  'Ǎ' => 'Ǎ',
  'ǎ' => 'ǎ',
  'Ǐ' => 'Ǐ',
  'ǐ' => 'ǐ',
  'Ǒ' => 'Ǒ',
  'ǒ' => 'ǒ',
  'Ǔ' => 'Ǔ',
  'ǔ' => 'ǔ',
  'Ǖ' => 'Ǖ',
  'ǖ' => 'ǖ',
  'Ǘ' => 'Ǘ',
  'ǘ' => 'ǘ',
  'Ǚ' => 'Ǚ',
  'ǚ' => 'ǚ',
  'Ǜ' => 'Ǜ',
  'ǜ' => 'ǜ',
  'Ǟ' => 'Ǟ',
  'ǟ' => 'ǟ',
  'Ǡ' => 'Ǡ',
  'ǡ' => 'ǡ',
  'Ǣ' => 'Ǣ',
  'ǣ' => 'ǣ',
  'Ǧ' => 'Ǧ',
  'ǧ' => 'ǧ',
  'Ǩ' => 'Ǩ',
  'ǩ' => 'ǩ',
  'Ǫ' => 'Ǫ',
  'ǫ' => 'ǫ',
  'Ǭ' => 'Ǭ',
  'ǭ' => 'ǭ',
  'Ǯ' => 'Ǯ',
  'ǯ' => 'ǯ',
  'ǰ' => 'ǰ',
  'Ǵ' => 'Ǵ',
  'ǵ' => 'ǵ',
  'Ǹ' => 'Ǹ',
  'ǹ' => 'ǹ',
  'Ǻ' => 'Ǻ',
  'ǻ' => 'ǻ',
  'Ǽ' => 'Ǽ',
  'ǽ' => 'ǽ',
  'Ǿ' => 'Ǿ',
  'ǿ' => 'ǿ',
  'Ȁ' => 'Ȁ',
  'ȁ' => 'ȁ',
  'Ȃ' => 'Ȃ',
  'ȃ' => 'ȃ',
  'Ȅ' => 'Ȅ',
  'ȅ' => 'ȅ',
  'Ȇ' => 'Ȇ',
  'ȇ' => 'ȇ',
  'Ȉ' => 'Ȉ',
  'ȉ' => 'ȉ',
  'Ȋ' => 'Ȋ',
  'ȋ' => 'ȋ',
  'Ȍ' => 'Ȍ',
  'ȍ' => 'ȍ',
  'Ȏ' => 'Ȏ',
  'ȏ' => 'ȏ',
  'Ȑ' => 'Ȑ',
  'ȑ' => 'ȑ',
  'Ȓ' => 'Ȓ',
  'ȓ' => 'ȓ',
  'Ȕ' => 'Ȕ',
  'ȕ' => 'ȕ',
  'Ȗ' => 'Ȗ',
  'ȗ' => 'ȗ',
  'Ș' => 'Ș',
  'ș' => 'ș',
  'Ț' => 'Ț',
  'ț' => 'ț',
  'Ȟ' => 'Ȟ',
  'ȟ' => 'ȟ',
  'Ȧ' => 'Ȧ',
  'ȧ' => 'ȧ',
  'Ȩ' => 'Ȩ',
  'ȩ' => 'ȩ',
  'Ȫ' => 'Ȫ',
  'ȫ' => 'ȫ',
  'Ȭ' => 'Ȭ',
  'ȭ' => 'ȭ',
  'Ȯ' => 'Ȯ',
  'ȯ' => 'ȯ',
  'Ȱ' => 'Ȱ',
  'ȱ' => 'ȱ',
  'Ȳ' => 'Ȳ',
  'ȳ' => 'ȳ',
  '΅' => '΅',
  'Ά' => 'Ά',
  'Έ' => 'Έ',
  'Ή' => 'Ή',
  'Ί' => 'Ί',
  'Ό' => 'Ό',
  'Ύ' => 'Ύ',
  'Ώ' => 'Ώ',
  'ΐ' => 'ΐ',
  'Ϊ' => 'Ϊ',
  'Ϋ' => 'Ϋ',
  'ά' => 'ά',
  'έ' => 'έ',
  'ή' => 'ή',
  'ί' => 'ί',
  'ΰ' => 'ΰ',
  'ϊ' => 'ϊ',
  'ϋ' => 'ϋ',
  'ό' => 'ό',
  'ύ' => 'ύ',
  'ώ' => 'ώ',
  'ϓ' => 'ϓ',
  'ϔ' => 'ϔ',
  'Ѐ' => 'Ѐ',
  'Ё' => 'Ё',
  'Ѓ' => 'Ѓ',
  'Ї' => 'Ї',
  'Ќ' => 'Ќ',
  'Ѝ' => 'Ѝ',
  'Ў' => 'Ў',
  'Й' => 'Й',
  'й' => 'й',
  'ѐ' => 'ѐ',
  'ё' => 'ё',
  'ѓ' => 'ѓ',
  'ї' => 'ї',
  'ќ' => 'ќ',
  'ѝ' => 'ѝ',
  'ў' => 'ў',
  'Ѷ' => 'Ѷ',
  'ѷ' => 'ѷ',
  'Ӂ' => 'Ӂ',
  'ӂ' => 'ӂ',
  'Ӑ' => 'Ӑ',
  'ӑ' => 'ӑ',
  'Ӓ' => 'Ӓ',
  'ӓ' => 'ӓ',
  'Ӗ' => 'Ӗ',
  'ӗ' => 'ӗ',
  'Ӛ' => 'Ӛ',
  'ӛ' => 'ӛ',
  'Ӝ' => 'Ӝ',
  'ӝ' => 'ӝ',
  'Ӟ' => 'Ӟ',
  'ӟ' => 'ӟ',
  'Ӣ' => 'Ӣ',
  'ӣ' => 'ӣ',
  'Ӥ' => 'Ӥ',
  'ӥ' => 'ӥ',
  'Ӧ' => 'Ӧ',
  'ӧ' => 'ӧ',
  'Ӫ' => 'Ӫ',
  'ӫ' => 'ӫ',
  'Ӭ' => 'Ӭ',
  'ӭ' => 'ӭ',
  'Ӯ' => 'Ӯ',
  'ӯ' => 'ӯ',
  'Ӱ' => 'Ӱ',
  'ӱ' => 'ӱ',
  'Ӳ' => 'Ӳ',
  'ӳ' => 'ӳ',
  'Ӵ' => 'Ӵ',
  'ӵ' => 'ӵ',
  'Ӹ' => 'Ӹ',
  'ӹ' => 'ӹ',
  'آ' => 'آ',
  'أ' => 'أ',
  'ؤ' => 'ؤ',
  'إ' => 'إ',
  'ئ' => 'ئ',
  'ۀ' => 'ۀ',
  'ۂ' => 'ۂ',
  'ۓ' => 'ۓ',
  'ऩ' => 'ऩ',
  'ऱ' => 'ऱ',
  'ऴ' => 'ऴ',
  'ো' => 'ো',
  'ৌ' => 'ৌ',
  'ୈ' => 'ୈ',
  'ୋ' => 'ୋ',
  'ୌ' => 'ୌ',
  'ஔ' => 'ஔ',
  'ொ' => 'ொ',
  'ோ' => 'ோ',
  'ௌ' => 'ௌ',
  'ై' => 'ై',
  'ೀ' => 'ೀ',
  'ೇ' => 'ೇ',
  'ೈ' => 'ೈ',
  'ೊ' => 'ೊ',
  'ೋ' => 'ೋ',
  'ൊ' => 'ൊ',
  'ോ' => 'ോ',
  'ൌ' => 'ൌ',
  'ේ' => 'ේ',
  'ො' => 'ො',
  'ෝ' => 'ෝ',
  'ෞ' => 'ෞ',
  'ဦ' => 'ဦ',
  'ᬆ' => 'ᬆ',
  'ᬈ' => 'ᬈ',
  'ᬊ' => 'ᬊ',
  'ᬌ' => 'ᬌ',
  'ᬎ' => 'ᬎ',
  'ᬒ' => 'ᬒ',
  'ᬻ' => 'ᬻ',
  'ᬽ' => 'ᬽ',
  'ᭀ' => 'ᭀ',
  'ᭁ' => 'ᭁ',
  'ᭃ' => 'ᭃ',
  'Ḁ' => 'Ḁ',
  'ḁ' => 'ḁ',
  'Ḃ' => 'Ḃ',
  'ḃ' => 'ḃ',
  'Ḅ' => 'Ḅ',
  'ḅ' => 'ḅ',
  'Ḇ' => 'Ḇ',
  'ḇ' => 'ḇ',
  'Ḉ' => 'Ḉ',
  'ḉ' => 'ḉ',
  'Ḋ' => 'Ḋ',
  'ḋ' => 'ḋ',
  'Ḍ' => 'Ḍ',
  'ḍ' => 'ḍ',
  'Ḏ' => 'Ḏ',
  'ḏ' => 'ḏ',
  'Ḑ' => 'Ḑ',
  'ḑ' => 'ḑ',
  'Ḓ' => 'Ḓ',
  'ḓ' => 'ḓ',
  'Ḕ' => 'Ḕ',
  'ḕ' => 'ḕ',
  'Ḗ' => 'Ḗ',
  'ḗ' => 'ḗ',
  'Ḙ' => 'Ḙ',
  'ḙ' => 'ḙ',
  'Ḛ' => 'Ḛ',
  'ḛ' => 'ḛ',
  'Ḝ' => 'Ḝ',
  'ḝ' => 'ḝ',
  'Ḟ' => 'Ḟ',
  'ḟ' => 'ḟ',
  'Ḡ' => 'Ḡ',
  'ḡ' => 'ḡ',
  'Ḣ' => 'Ḣ',
  'ḣ' => 'ḣ',
  'Ḥ' => 'Ḥ',
  'ḥ' => 'ḥ',
  'Ḧ' => 'Ḧ',
  'ḧ' => 'ḧ',
  'Ḩ' => 'Ḩ',
  'ḩ' => 'ḩ',
  'Ḫ' => 'Ḫ',
  'ḫ' => 'ḫ',
  'Ḭ' => 'Ḭ',
  'ḭ' => 'ḭ',
  'Ḯ' => 'Ḯ',
  'ḯ' => 'ḯ',
  'Ḱ' => 'Ḱ',
  'ḱ' => 'ḱ',
  'Ḳ' => 'Ḳ',
  'ḳ' => 'ḳ',
  'Ḵ' => 'Ḵ',
  'ḵ' => 'ḵ',
  'Ḷ' => 'Ḷ',
  'ḷ' => 'ḷ',
  'Ḹ' => 'Ḹ',
  'ḹ' => 'ḹ',
  'Ḻ' => 'Ḻ',
  'ḻ' => 'ḻ',
  'Ḽ' => 'Ḽ',
  'ḽ' => 'ḽ',
  'Ḿ' => 'Ḿ',
  'ḿ' => 'ḿ',
  'Ṁ' => 'Ṁ',
  'ṁ' => 'ṁ',
  'Ṃ' => 'Ṃ',
  'ṃ' => 'ṃ',
  'Ṅ' => 'Ṅ',
  'ṅ' => 'ṅ',
  'Ṇ' => 'Ṇ',
  'ṇ' => 'ṇ',
  'Ṉ' => 'Ṉ',
  'ṉ' => 'ṉ',
  'Ṋ' => 'Ṋ',
  'ṋ' => 'ṋ',
  'Ṍ' => 'Ṍ',
  'ṍ' => 'ṍ',
  'Ṏ' => 'Ṏ',
  'ṏ' => 'ṏ',
  'Ṑ' => 'Ṑ',
  'ṑ' => 'ṑ',
  'Ṓ' => 'Ṓ',
  'ṓ' => 'ṓ',
  'Ṕ' => 'Ṕ',
  'ṕ' => 'ṕ',
  'Ṗ' => 'Ṗ',
  'ṗ' => 'ṗ',
  'Ṙ' => 'Ṙ',
  'ṙ' => 'ṙ',
  'Ṛ' => 'Ṛ',
  'ṛ' => 'ṛ',
  'Ṝ' => 'Ṝ',
  'ṝ' => 'ṝ',
  'Ṟ' => 'Ṟ',
  'ṟ' => 'ṟ',
  'Ṡ' => 'Ṡ',
  'ṡ' => 'ṡ',
  'Ṣ' => 'Ṣ',
  'ṣ' => 'ṣ',
  'Ṥ' => 'Ṥ',
  'ṥ' => 'ṥ',
  'Ṧ' => 'Ṧ',
  'ṧ' => 'ṧ',
  'Ṩ' => 'Ṩ',
  'ṩ' => 'ṩ',
  'Ṫ' => 'Ṫ',
  'ṫ' => 'ṫ',
  'Ṭ' => 'Ṭ',
  'ṭ' => 'ṭ',
  'Ṯ' => 'Ṯ',
  'ṯ' => 'ṯ',
  'Ṱ' => 'Ṱ',
  'ṱ' => 'ṱ',
  'Ṳ' => 'Ṳ',
  'ṳ' => 'ṳ',
  'Ṵ' => 'Ṵ',
  'ṵ' => 'ṵ',
  'Ṷ' => 'Ṷ',
  'ṷ' => 'ṷ',
  'Ṹ' => 'Ṹ',
  'ṹ' => 'ṹ',
  'Ṻ' => 'Ṻ',
  'ṻ' => 'ṻ',
  'Ṽ' => 'Ṽ',
  'ṽ' => 'ṽ',
  'Ṿ' => 'Ṿ',
  'ṿ' => 'ṿ',
  'Ẁ' => 'Ẁ',
  'ẁ' => 'ẁ',
  'Ẃ' => 'Ẃ',
  'ẃ' => 'ẃ',
  'Ẅ' => 'Ẅ',
  'ẅ' => 'ẅ',
  'Ẇ' => 'Ẇ',
  'ẇ' => 'ẇ',
  'Ẉ' => 'Ẉ',
  'ẉ' => 'ẉ',
  'Ẋ' => 'Ẋ',
  'ẋ' => 'ẋ',
  'Ẍ' => 'Ẍ',
  'ẍ' => 'ẍ',
  'Ẏ' => 'Ẏ',
  'ẏ' => 'ẏ',
  'Ẑ' => 'Ẑ',
  'ẑ' => 'ẑ',
  'Ẓ' => 'Ẓ',
  'ẓ' => 'ẓ',
  'Ẕ' => 'Ẕ',
  'ẕ' => 'ẕ',
  'ẖ' => 'ẖ',
  'ẗ' => 'ẗ',
  'ẘ' => 'ẘ',
  'ẙ' => 'ẙ',
  'ẛ' => 'ẛ',
  'Ạ' => 'Ạ',
  'ạ' => 'ạ',
  'Ả' => 'Ả',
  'ả' => 'ả',
  'Ấ' => 'Ấ',
  'ấ' => 'ấ',
  'Ầ' => 'Ầ',
  'ầ' => 'ầ',
  'Ẩ' => 'Ẩ',
  'ẩ' => 'ẩ',
  'Ẫ' => 'Ẫ',
  'ẫ' => 'ẫ',
  'Ậ' => 'Ậ',
  'ậ' => 'ậ',
  'Ắ' => 'Ắ',
  'ắ' => 'ắ',
  'Ằ' => 'Ằ',
  'ằ' => 'ằ',
  'Ẳ' => 'Ẳ',
  'ẳ' => 'ẳ',
  'Ẵ' => 'Ẵ',
  'ẵ' => 'ẵ',
  'Ặ' => 'Ặ',
  'ặ' => 'ặ',
  'Ẹ' => 'Ẹ',
  'ẹ' => 'ẹ',
  'Ẻ' => 'Ẻ',
  'ẻ' => 'ẻ',
  'Ẽ' => 'Ẽ',
  'ẽ' => 'ẽ',
  'Ế' => 'Ế',
  'ế' => 'ế',
  'Ề' => 'Ề',
  'ề' => 'ề',
  'Ể' => 'Ể',
  'ể' => 'ể',
  'Ễ' => 'Ễ',
  'ễ' => 'ễ',
  'Ệ' => 'Ệ',
  'ệ' => 'ệ',
  'Ỉ' => 'Ỉ',
  'ỉ' => 'ỉ',
  'Ị' => 'Ị',
  'ị' => 'ị',
  'Ọ' => 'Ọ',
  'ọ' => 'ọ',
  'Ỏ' => 'Ỏ',
  'ỏ' => 'ỏ',
  'Ố' => 'Ố',
  'ố' => 'ố',
  'Ồ' => 'Ồ',
  'ồ' => 'ồ',
  'Ổ' => 'Ổ',
  'ổ' => 'ổ',
  'Ỗ' => 'Ỗ',
  'ỗ' => 'ỗ',
  'Ộ' => 'Ộ',
  'ộ' => 'ộ',
  'Ớ' => 'Ớ',
  'ớ' => 'ớ',
  'Ờ' => 'Ờ',
  'ờ' => 'ờ',
  'Ở' => 'Ở',
  'ở' => 'ở',
  'Ỡ' => 'Ỡ',
  'ỡ' => 'ỡ',
  'Ợ' => 'Ợ',
  'ợ' => 'ợ',
  'Ụ' => 'Ụ',
  'ụ' => 'ụ',
  'Ủ' => 'Ủ',
  'ủ' => 'ủ',
  'Ứ' => 'Ứ',
  'ứ' => 'ứ',
  'Ừ' => 'Ừ',
  'ừ' => 'ừ',
  'Ử' => 'Ử',
  'ử' => 'ử',
  'Ữ' => 'Ữ',
  'ữ' => 'ữ',
  'Ự' => 'Ự',
  'ự' => 'ự',
  'Ỳ' => 'Ỳ',
  'ỳ' => 'ỳ',
  'Ỵ' => 'Ỵ',
  'ỵ' => 'ỵ',
  'Ỷ' => 'Ỷ',
  'ỷ' => 'ỷ',
  'Ỹ' => 'Ỹ',
  'ỹ' => 'ỹ',
  'ἀ' => 'ἀ',
  'ἁ' => 'ἁ',
  'ἂ' => 'ἂ',
  'ἃ' => 'ἃ',
  'ἄ' => 'ἄ',
  'ἅ' => 'ἅ',
  'ἆ' => 'ἆ',
  'ἇ' => 'ἇ',
  'Ἀ' => 'Ἀ',
  'Ἁ' => 'Ἁ',
  'Ἂ' => 'Ἂ',
  'Ἃ' => 'Ἃ',
  'Ἄ' => 'Ἄ',
  'Ἅ' => 'Ἅ',
  'Ἆ' => 'Ἆ',
  'Ἇ' => 'Ἇ',
  'ἐ' => 'ἐ',
  'ἑ' => 'ἑ',
  'ἒ' => 'ἒ',
  'ἓ' => 'ἓ',
  'ἔ' => 'ἔ',
  'ἕ' => 'ἕ',
  'Ἐ' => 'Ἐ',
  'Ἑ' => 'Ἑ',
  'Ἒ' => 'Ἒ',
  'Ἓ' => 'Ἓ',
  'Ἔ' => 'Ἔ',
  'Ἕ' => 'Ἕ',
  'ἠ' => 'ἠ',
  'ἡ' => 'ἡ',
  'ἢ' => 'ἢ',
  'ἣ' => 'ἣ',
  'ἤ' => 'ἤ',
  'ἥ' => 'ἥ',
  'ἦ' => 'ἦ',
  'ἧ' => 'ἧ',
  'Ἠ' => 'Ἠ',
  'Ἡ' => 'Ἡ',
  'Ἢ' => 'Ἢ',
  'Ἣ' => 'Ἣ',
  'Ἤ' => 'Ἤ',
  'Ἥ' => 'Ἥ',
  'Ἦ' => 'Ἦ',
  'Ἧ' => 'Ἧ',
  'ἰ' => 'ἰ',
  'ἱ' => 'ἱ',
  'ἲ' => 'ἲ',
  'ἳ' => 'ἳ',
  'ἴ' => 'ἴ',
  'ἵ' => 'ἵ',
  'ἶ' => 'ἶ',
  'ἷ' => 'ἷ',
  'Ἰ' => 'Ἰ',
  'Ἱ' => 'Ἱ',
  'Ἲ' => 'Ἲ',
  'Ἳ' => 'Ἳ',
  'Ἴ' => 'Ἴ',
  'Ἵ' => 'Ἵ',
  'Ἶ' => 'Ἶ',
  'Ἷ' => 'Ἷ',
  'ὀ' => 'ὀ',
  'ὁ' => 'ὁ',
  'ὂ' => 'ὂ',
  'ὃ' => 'ὃ',
  'ὄ' => 'ὄ',
  'ὅ' => 'ὅ',
  'Ὀ' => 'Ὀ',
  'Ὁ' => 'Ὁ',
  'Ὂ' => 'Ὂ',
  'Ὃ' => 'Ὃ',
  'Ὄ' => 'Ὄ',
  'Ὅ' => 'Ὅ',
  'ὐ' => 'ὐ',
  'ὑ' => 'ὑ',
  'ὒ' => 'ὒ',
  'ὓ' => 'ὓ',
  'ὔ' => 'ὔ',
  'ὕ' => 'ὕ',
  'ὖ' => 'ὖ',
  'ὗ' => 'ὗ',
  'Ὑ' => 'Ὑ',
  'Ὓ' => 'Ὓ',
  'Ὕ' => 'Ὕ',
  'Ὗ' => 'Ὗ',
  'ὠ' => 'ὠ',
  'ὡ' => 'ὡ',
  'ὢ' => 'ὢ',
  'ὣ' => 'ὣ',
  'ὤ' => 'ὤ',
  'ὥ' => 'ὥ',
  'ὦ' => 'ὦ',
  'ὧ' => 'ὧ',
  'Ὠ' => 'Ὠ',
  'Ὡ' => 'Ὡ',
  'Ὢ' => 'Ὢ',
  'Ὣ' => 'Ὣ',
  'Ὤ' => 'Ὤ',
  'Ὥ' => 'Ὥ',
  'Ὦ' => 'Ὦ',
  'Ὧ' => 'Ὧ',
  'ὰ' => 'ὰ',
  'ὲ' => 'ὲ',
  'ὴ' => 'ὴ',
  'ὶ' => 'ὶ',
  'ὸ' => 'ὸ',
  'ὺ' => 'ὺ',
  'ὼ' => 'ὼ',
  'ᾀ' => 'ᾀ',
  'ᾁ' => 'ᾁ',
  'ᾂ' => 'ᾂ',
  'ᾃ' => 'ᾃ',
  'ᾄ' => 'ᾄ',
  'ᾅ' => 'ᾅ',
  'ᾆ' => 'ᾆ',
  'ᾇ' => 'ᾇ',
  'ᾈ' => 'ᾈ',
  'ᾉ' => 'ᾉ',
  'ᾊ' => 'ᾊ',
  'ᾋ' => 'ᾋ',
  'ᾌ' => 'ᾌ',
  'ᾍ' => 'ᾍ',
  'ᾎ' => 'ᾎ',
  'ᾏ' => 'ᾏ',
  'ᾐ' => 'ᾐ',
  'ᾑ' => 'ᾑ',
  'ᾒ' => 'ᾒ',
  'ᾓ' => 'ᾓ',
  'ᾔ' => 'ᾔ',
  'ᾕ' => 'ᾕ',
  'ᾖ' => 'ᾖ',
  'ᾗ' => 'ᾗ',
  'ᾘ' => 'ᾘ',
  'ᾙ' => 'ᾙ',
  'ᾚ' => 'ᾚ',
  'ᾛ' => 'ᾛ',
  'ᾜ' => 'ᾜ',
  'ᾝ' => 'ᾝ',
  'ᾞ' => 'ᾞ',
  'ᾟ' => 'ᾟ',
  'ᾠ' => 'ᾠ',
  'ᾡ' => 'ᾡ',
  'ᾢ' => 'ᾢ',
  'ᾣ' => 'ᾣ',
  'ᾤ' => 'ᾤ',
  'ᾥ' => 'ᾥ',
  'ᾦ' => 'ᾦ',
  'ᾧ' => 'ᾧ',
  'ᾨ' => 'ᾨ',
  'ᾩ' => 'ᾩ',
  'ᾪ' => 'ᾪ',
  'ᾫ' => 'ᾫ',
  'ᾬ' => 'ᾬ',
  'ᾭ' => 'ᾭ',
  'ᾮ' => 'ᾮ',
  'ᾯ' => 'ᾯ',
  'ᾰ' => 'ᾰ',
  'ᾱ' => 'ᾱ',
  'ᾲ' => 'ᾲ',
  'ᾳ' => 'ᾳ',
  'ᾴ' => 'ᾴ',
  'ᾶ' => 'ᾶ',
  'ᾷ' => 'ᾷ',
  'Ᾰ' => 'Ᾰ',
  'Ᾱ' => 'Ᾱ',
  'Ὰ' => 'Ὰ',
  'ᾼ' => 'ᾼ',
  '῁' => '῁',
  'ῂ' => 'ῂ',
  'ῃ' => 'ῃ',
  'ῄ' => 'ῄ',
  'ῆ' => 'ῆ',
  'ῇ' => 'ῇ',
  'Ὲ' => 'Ὲ',
  'Ὴ' => 'Ὴ',
  'ῌ' => 'ῌ',
  '῍' => '῍',
  '῎' => '῎',
  '῏' => '῏',
  'ῐ' => 'ῐ',
  'ῑ' => 'ῑ',
  'ῒ' => 'ῒ',
  'ῖ' => 'ῖ',
  'ῗ' => 'ῗ',
  'Ῐ' => 'Ῐ',
  'Ῑ' => 'Ῑ',
  'Ὶ' => 'Ὶ',
  '῝' => '῝',
  '῞' => '῞',
  '῟' => '῟',
  'ῠ' => 'ῠ',
  'ῡ' => 'ῡ',
  'ῢ' => 'ῢ',
  'ῤ' => 'ῤ',
  'ῥ' => 'ῥ',
  'ῦ' => 'ῦ',
  'ῧ' => 'ῧ',
  'Ῠ' => 'Ῠ',
  'Ῡ' => 'Ῡ',
  'Ὺ' => 'Ὺ',
  'Ῥ' => 'Ῥ',
  '῭' => '῭',
  'ῲ' => 'ῲ',
  'ῳ' => 'ῳ',
  'ῴ' => 'ῴ',
  'ῶ' => 'ῶ',
  'ῷ' => 'ῷ',
  'Ὸ' => 'Ὸ',
  'Ὼ' => 'Ὼ',
  'ῼ' => 'ῼ',
  '↚' => '↚',
  '↛' => '↛',
  '↮' => '↮',
  '⇍' => '⇍',
  '⇎' => '⇎',
  '⇏' => '⇏',
  '∄' => '∄',
  '∉' => '∉',
  '∌' => '∌',
  '∤' => '∤',
  '∦' => '∦',
  '≁' => '≁',
  '≄' => '≄',
  '≇' => '≇',
  '≉' => '≉',
  '≠' => '≠',
  '≢' => '≢',
  '≭' => '≭',
  '≮' => '≮',
  '≯' => '≯',
  '≰' => '≰',
  '≱' => '≱',
  '≴' => '≴',
  '≵' => '≵',
  '≸' => '≸',
  '≹' => '≹',
  '⊀' => '⊀',
  '⊁' => '⊁',
  '⊄' => '⊄',
  '⊅' => '⊅',
  '⊈' => '⊈',
  '⊉' => '⊉',
  '⊬' => '⊬',
  '⊭' => '⊭',
  '⊮' => '⊮',
  '⊯' => '⊯',
  '⋠' => '⋠',
  '⋡' => '⋡',
  '⋢' => '⋢',
  '⋣' => '⋣',
  '⋪' => '⋪',
  '⋫' => '⋫',
  '⋬' => '⋬',
  '⋭' => '⋭',
  'が' => 'が',
  'ぎ' => 'ぎ',
  'ぐ' => 'ぐ',
  'げ' => 'げ',
  'ご' => 'ご',
  'ざ' => 'ざ',
  'じ' => 'じ',
  'ず' => 'ず',
  'ぜ' => 'ぜ',
  'ぞ' => 'ぞ',
  'だ' => 'だ',
  'ぢ' => 'ぢ',
  'づ' => 'づ',
  'で' => 'で',
  'ど' => 'ど',
  'ば' => 'ば',
  'ぱ' => 'ぱ',
  'び' => 'び',
  'ぴ' => 'ぴ',
  'ぶ' => 'ぶ',
  'ぷ' => 'ぷ',
  'べ' => 'べ',
  'ぺ' => 'ぺ',
  'ぼ' => 'ぼ',
  'ぽ' => 'ぽ',
  'ゔ' => 'ゔ',
  'ゞ' => 'ゞ',
  'ガ' => 'ガ',
  'ギ' => 'ギ',
  'グ' => 'グ',
  'ゲ' => 'ゲ',
  'ゴ' => 'ゴ',
  'ザ' => 'ザ',
  'ジ' => 'ジ',
  'ズ' => 'ズ',
  'ゼ' => 'ゼ',
  'ゾ' => 'ゾ',
  'ダ' => 'ダ',
  'ヂ' => 'ヂ',
  'ヅ' => 'ヅ',
  'デ' => 'デ',
  'ド' => 'ド',
  'バ' => 'バ',
  'パ' => 'パ',
  'ビ' => 'ビ',
  'ピ' => 'ピ',
  'ブ' => 'ブ',
  'プ' => 'プ',
  'ベ' => 'ベ',
  'ペ' => 'ペ',
  'ボ' => 'ボ',
  'ポ' => 'ポ',
  'ヴ' => 'ヴ',
  'ヷ' => 'ヷ',
  'ヸ' => 'ヸ',
  'ヹ' => 'ヹ',
  'ヺ' => 'ヺ',
  'ヾ' => 'ヾ',
  '𑂚' => '𑂚',
  '𑂜' => '𑂜',
  '𑂫' => '𑂫',
  '𑄮' => '𑄮',
  '𑄯' => '𑄯',
  '𑍋' => '𑍋',
  '𑍌' => '𑍌',
  '𑒻' => '𑒻',
  '𑒼' => '𑒼',
  '𑒾' => '𑒾',
  '𑖺' => '𑖺',
  '𑖻' => '𑖻',
  '𑤸' => '𑤸',
);
PKϤ$Z�je�{�{�Epolyfill-intl-normalizer/Resources/unidata/canonicalDecomposition.phpnu�[���<?php

return array (
  'À' => 'À',
  'Á' => 'Á',
  'Â' => 'Â',
  'Ã' => 'Ã',
  'Ä' => 'Ä',
  'Å' => 'Å',
  'Ç' => 'Ç',
  'È' => 'È',
  'É' => 'É',
  'Ê' => 'Ê',
  'Ë' => 'Ë',
  'Ì' => 'Ì',
  'Í' => 'Í',
  'Î' => 'Î',
  'Ï' => 'Ï',
  'Ñ' => 'Ñ',
  'Ò' => 'Ò',
  'Ó' => 'Ó',
  'Ô' => 'Ô',
  'Õ' => 'Õ',
  'Ö' => 'Ö',
  'Ù' => 'Ù',
  'Ú' => 'Ú',
  'Û' => 'Û',
  'Ü' => 'Ü',
  'Ý' => 'Ý',
  'à' => 'à',
  'á' => 'á',
  'â' => 'â',
  'ã' => 'ã',
  'ä' => 'ä',
  'å' => 'å',
  'ç' => 'ç',
  'è' => 'è',
  'é' => 'é',
  'ê' => 'ê',
  'ë' => 'ë',
  'ì' => 'ì',
  'í' => 'í',
  'î' => 'î',
  'ï' => 'ï',
  'ñ' => 'ñ',
  'ò' => 'ò',
  'ó' => 'ó',
  'ô' => 'ô',
  'õ' => 'õ',
  'ö' => 'ö',
  'ù' => 'ù',
  'ú' => 'ú',
  'û' => 'û',
  'ü' => 'ü',
  'ý' => 'ý',
  'ÿ' => 'ÿ',
  'Ā' => 'Ā',
  'ā' => 'ā',
  'Ă' => 'Ă',
  'ă' => 'ă',
  'Ą' => 'Ą',
  'ą' => 'ą',
  'Ć' => 'Ć',
  'ć' => 'ć',
  'Ĉ' => 'Ĉ',
  'ĉ' => 'ĉ',
  'Ċ' => 'Ċ',
  'ċ' => 'ċ',
  'Č' => 'Č',
  'č' => 'č',
  'Ď' => 'Ď',
  'ď' => 'ď',
  'Ē' => 'Ē',
  'ē' => 'ē',
  'Ĕ' => 'Ĕ',
  'ĕ' => 'ĕ',
  'Ė' => 'Ė',
  'ė' => 'ė',
  'Ę' => 'Ę',
  'ę' => 'ę',
  'Ě' => 'Ě',
  'ě' => 'ě',
  'Ĝ' => 'Ĝ',
  'ĝ' => 'ĝ',
  'Ğ' => 'Ğ',
  'ğ' => 'ğ',
  'Ġ' => 'Ġ',
  'ġ' => 'ġ',
  'Ģ' => 'Ģ',
  'ģ' => 'ģ',
  'Ĥ' => 'Ĥ',
  'ĥ' => 'ĥ',
  'Ĩ' => 'Ĩ',
  'ĩ' => 'ĩ',
  'Ī' => 'Ī',
  'ī' => 'ī',
  'Ĭ' => 'Ĭ',
  'ĭ' => 'ĭ',
  'Į' => 'Į',
  'į' => 'į',
  'İ' => 'İ',
  'Ĵ' => 'Ĵ',
  'ĵ' => 'ĵ',
  'Ķ' => 'Ķ',
  'ķ' => 'ķ',
  'Ĺ' => 'Ĺ',
  'ĺ' => 'ĺ',
  'Ļ' => 'Ļ',
  'ļ' => 'ļ',
  'Ľ' => 'Ľ',
  'ľ' => 'ľ',
  'Ń' => 'Ń',
  'ń' => 'ń',
  'Ņ' => 'Ņ',
  'ņ' => 'ņ',
  'Ň' => 'Ň',
  'ň' => 'ň',
  'Ō' => 'Ō',
  'ō' => 'ō',
  'Ŏ' => 'Ŏ',
  'ŏ' => 'ŏ',
  'Ő' => 'Ő',
  'ő' => 'ő',
  'Ŕ' => 'Ŕ',
  'ŕ' => 'ŕ',
  'Ŗ' => 'Ŗ',
  'ŗ' => 'ŗ',
  'Ř' => 'Ř',
  'ř' => 'ř',
  'Ś' => 'Ś',
  'ś' => 'ś',
  'Ŝ' => 'Ŝ',
  'ŝ' => 'ŝ',
  'Ş' => 'Ş',
  'ş' => 'ş',
  'Š' => 'Š',
  'š' => 'š',
  'Ţ' => 'Ţ',
  'ţ' => 'ţ',
  'Ť' => 'Ť',
  'ť' => 'ť',
  'Ũ' => 'Ũ',
  'ũ' => 'ũ',
  'Ū' => 'Ū',
  'ū' => 'ū',
  'Ŭ' => 'Ŭ',
  'ŭ' => 'ŭ',
  'Ů' => 'Ů',
  'ů' => 'ů',
  'Ű' => 'Ű',
  'ű' => 'ű',
  'Ų' => 'Ų',
  'ų' => 'ų',
  'Ŵ' => 'Ŵ',
  'ŵ' => 'ŵ',
  'Ŷ' => 'Ŷ',
  'ŷ' => 'ŷ',
  'Ÿ' => 'Ÿ',
  'Ź' => 'Ź',
  'ź' => 'ź',
  'Ż' => 'Ż',
  'ż' => 'ż',
  'Ž' => 'Ž',
  'ž' => 'ž',
  'Ơ' => 'Ơ',
  'ơ' => 'ơ',
  'Ư' => 'Ư',
  'ư' => 'ư',
  'Ǎ' => 'Ǎ',
  'ǎ' => 'ǎ',
  'Ǐ' => 'Ǐ',
  'ǐ' => 'ǐ',
  'Ǒ' => 'Ǒ',
  'ǒ' => 'ǒ',
  'Ǔ' => 'Ǔ',
  'ǔ' => 'ǔ',
  'Ǖ' => 'Ǖ',
  'ǖ' => 'ǖ',
  'Ǘ' => 'Ǘ',
  'ǘ' => 'ǘ',
  'Ǚ' => 'Ǚ',
  'ǚ' => 'ǚ',
  'Ǜ' => 'Ǜ',
  'ǜ' => 'ǜ',
  'Ǟ' => 'Ǟ',
  'ǟ' => 'ǟ',
  'Ǡ' => 'Ǡ',
  'ǡ' => 'ǡ',
  'Ǣ' => 'Ǣ',
  'ǣ' => 'ǣ',
  'Ǧ' => 'Ǧ',
  'ǧ' => 'ǧ',
  'Ǩ' => 'Ǩ',
  'ǩ' => 'ǩ',
  'Ǫ' => 'Ǫ',
  'ǫ' => 'ǫ',
  'Ǭ' => 'Ǭ',
  'ǭ' => 'ǭ',
  'Ǯ' => 'Ǯ',
  'ǯ' => 'ǯ',
  'ǰ' => 'ǰ',
  'Ǵ' => 'Ǵ',
  'ǵ' => 'ǵ',
  'Ǹ' => 'Ǹ',
  'ǹ' => 'ǹ',
  'Ǻ' => 'Ǻ',
  'ǻ' => 'ǻ',
  'Ǽ' => 'Ǽ',
  'ǽ' => 'ǽ',
  'Ǿ' => 'Ǿ',
  'ǿ' => 'ǿ',
  'Ȁ' => 'Ȁ',
  'ȁ' => 'ȁ',
  'Ȃ' => 'Ȃ',
  'ȃ' => 'ȃ',
  'Ȅ' => 'Ȅ',
  'ȅ' => 'ȅ',
  'Ȇ' => 'Ȇ',
  'ȇ' => 'ȇ',
  'Ȉ' => 'Ȉ',
  'ȉ' => 'ȉ',
  'Ȋ' => 'Ȋ',
  'ȋ' => 'ȋ',
  'Ȍ' => 'Ȍ',
  'ȍ' => 'ȍ',
  'Ȏ' => 'Ȏ',
  'ȏ' => 'ȏ',
  'Ȑ' => 'Ȑ',
  'ȑ' => 'ȑ',
  'Ȓ' => 'Ȓ',
  'ȓ' => 'ȓ',
  'Ȕ' => 'Ȕ',
  'ȕ' => 'ȕ',
  'Ȗ' => 'Ȗ',
  'ȗ' => 'ȗ',
  'Ș' => 'Ș',
  'ș' => 'ș',
  'Ț' => 'Ț',
  'ț' => 'ț',
  'Ȟ' => 'Ȟ',
  'ȟ' => 'ȟ',
  'Ȧ' => 'Ȧ',
  'ȧ' => 'ȧ',
  'Ȩ' => 'Ȩ',
  'ȩ' => 'ȩ',
  'Ȫ' => 'Ȫ',
  'ȫ' => 'ȫ',
  'Ȭ' => 'Ȭ',
  'ȭ' => 'ȭ',
  'Ȯ' => 'Ȯ',
  'ȯ' => 'ȯ',
  'Ȱ' => 'Ȱ',
  'ȱ' => 'ȱ',
  'Ȳ' => 'Ȳ',
  'ȳ' => 'ȳ',
  '̀' => '̀',
  '́' => '́',
  '̓' => '̓',
  '̈́' => '̈́',
  'ʹ' => 'ʹ',
  ';' => ';',
  '΅' => '΅',
  'Ά' => 'Ά',
  '·' => '·',
  'Έ' => 'Έ',
  'Ή' => 'Ή',
  'Ί' => 'Ί',
  'Ό' => 'Ό',
  'Ύ' => 'Ύ',
  'Ώ' => 'Ώ',
  'ΐ' => 'ΐ',
  'Ϊ' => 'Ϊ',
  'Ϋ' => 'Ϋ',
  'ά' => 'ά',
  'έ' => 'έ',
  'ή' => 'ή',
  'ί' => 'ί',
  'ΰ' => 'ΰ',
  'ϊ' => 'ϊ',
  'ϋ' => 'ϋ',
  'ό' => 'ό',
  'ύ' => 'ύ',
  'ώ' => 'ώ',
  'ϓ' => 'ϓ',
  'ϔ' => 'ϔ',
  'Ѐ' => 'Ѐ',
  'Ё' => 'Ё',
  'Ѓ' => 'Ѓ',
  'Ї' => 'Ї',
  'Ќ' => 'Ќ',
  'Ѝ' => 'Ѝ',
  'Ў' => 'Ў',
  'Й' => 'Й',
  'й' => 'й',
  'ѐ' => 'ѐ',
  'ё' => 'ё',
  'ѓ' => 'ѓ',
  'ї' => 'ї',
  'ќ' => 'ќ',
  'ѝ' => 'ѝ',
  'ў' => 'ў',
  'Ѷ' => 'Ѷ',
  'ѷ' => 'ѷ',
  'Ӂ' => 'Ӂ',
  'ӂ' => 'ӂ',
  'Ӑ' => 'Ӑ',
  'ӑ' => 'ӑ',
  'Ӓ' => 'Ӓ',
  'ӓ' => 'ӓ',
  'Ӗ' => 'Ӗ',
  'ӗ' => 'ӗ',
  'Ӛ' => 'Ӛ',
  'ӛ' => 'ӛ',
  'Ӝ' => 'Ӝ',
  'ӝ' => 'ӝ',
  'Ӟ' => 'Ӟ',
  'ӟ' => 'ӟ',
  'Ӣ' => 'Ӣ',
  'ӣ' => 'ӣ',
  'Ӥ' => 'Ӥ',
  'ӥ' => 'ӥ',
  'Ӧ' => 'Ӧ',
  'ӧ' => 'ӧ',
  'Ӫ' => 'Ӫ',
  'ӫ' => 'ӫ',
  'Ӭ' => 'Ӭ',
  'ӭ' => 'ӭ',
  'Ӯ' => 'Ӯ',
  'ӯ' => 'ӯ',
  'Ӱ' => 'Ӱ',
  'ӱ' => 'ӱ',
  'Ӳ' => 'Ӳ',
  'ӳ' => 'ӳ',
  'Ӵ' => 'Ӵ',
  'ӵ' => 'ӵ',
  'Ӹ' => 'Ӹ',
  'ӹ' => 'ӹ',
  'آ' => 'آ',
  'أ' => 'أ',
  'ؤ' => 'ؤ',
  'إ' => 'إ',
  'ئ' => 'ئ',
  'ۀ' => 'ۀ',
  'ۂ' => 'ۂ',
  'ۓ' => 'ۓ',
  'ऩ' => 'ऩ',
  'ऱ' => 'ऱ',
  'ऴ' => 'ऴ',
  'क़' => 'क़',
  'ख़' => 'ख़',
  'ग़' => 'ग़',
  'ज़' => 'ज़',
  'ड़' => 'ड़',
  'ढ़' => 'ढ़',
  'फ़' => 'फ़',
  'य़' => 'य़',
  'ো' => 'ো',
  'ৌ' => 'ৌ',
  'ড়' => 'ড়',
  'ঢ়' => 'ঢ়',
  'য়' => 'য়',
  'ਲ਼' => 'ਲ਼',
  'ਸ਼' => 'ਸ਼',
  'ਖ਼' => 'ਖ਼',
  'ਗ਼' => 'ਗ਼',
  'ਜ਼' => 'ਜ਼',
  'ਫ਼' => 'ਫ਼',
  'ୈ' => 'ୈ',
  'ୋ' => 'ୋ',
  'ୌ' => 'ୌ',
  'ଡ଼' => 'ଡ଼',
  'ଢ଼' => 'ଢ଼',
  'ஔ' => 'ஔ',
  'ொ' => 'ொ',
  'ோ' => 'ோ',
  'ௌ' => 'ௌ',
  'ై' => 'ై',
  'ೀ' => 'ೀ',
  'ೇ' => 'ೇ',
  'ೈ' => 'ೈ',
  'ೊ' => 'ೊ',
  'ೋ' => 'ೋ',
  'ൊ' => 'ൊ',
  'ോ' => 'ോ',
  'ൌ' => 'ൌ',
  'ේ' => 'ේ',
  'ො' => 'ො',
  'ෝ' => 'ෝ',
  'ෞ' => 'ෞ',
  'གྷ' => 'གྷ',
  'ཌྷ' => 'ཌྷ',
  'དྷ' => 'དྷ',
  'བྷ' => 'བྷ',
  'ཛྷ' => 'ཛྷ',
  'ཀྵ' => 'ཀྵ',
  'ཱི' => 'ཱི',
  'ཱུ' => 'ཱུ',
  'ྲྀ' => 'ྲྀ',
  'ླྀ' => 'ླྀ',
  'ཱྀ' => 'ཱྀ',
  'ྒྷ' => 'ྒྷ',
  'ྜྷ' => 'ྜྷ',
  'ྡྷ' => 'ྡྷ',
  'ྦྷ' => 'ྦྷ',
  'ྫྷ' => 'ྫྷ',
  'ྐྵ' => 'ྐྵ',
  'ဦ' => 'ဦ',
  'ᬆ' => 'ᬆ',
  'ᬈ' => 'ᬈ',
  'ᬊ' => 'ᬊ',
  'ᬌ' => 'ᬌ',
  'ᬎ' => 'ᬎ',
  'ᬒ' => 'ᬒ',
  'ᬻ' => 'ᬻ',
  'ᬽ' => 'ᬽ',
  'ᭀ' => 'ᭀ',
  'ᭁ' => 'ᭁ',
  'ᭃ' => 'ᭃ',
  'Ḁ' => 'Ḁ',
  'ḁ' => 'ḁ',
  'Ḃ' => 'Ḃ',
  'ḃ' => 'ḃ',
  'Ḅ' => 'Ḅ',
  'ḅ' => 'ḅ',
  'Ḇ' => 'Ḇ',
  'ḇ' => 'ḇ',
  'Ḉ' => 'Ḉ',
  'ḉ' => 'ḉ',
  'Ḋ' => 'Ḋ',
  'ḋ' => 'ḋ',
  'Ḍ' => 'Ḍ',
  'ḍ' => 'ḍ',
  'Ḏ' => 'Ḏ',
  'ḏ' => 'ḏ',
  'Ḑ' => 'Ḑ',
  'ḑ' => 'ḑ',
  'Ḓ' => 'Ḓ',
  'ḓ' => 'ḓ',
  'Ḕ' => 'Ḕ',
  'ḕ' => 'ḕ',
  'Ḗ' => 'Ḗ',
  'ḗ' => 'ḗ',
  'Ḙ' => 'Ḙ',
  'ḙ' => 'ḙ',
  'Ḛ' => 'Ḛ',
  'ḛ' => 'ḛ',
  'Ḝ' => 'Ḝ',
  'ḝ' => 'ḝ',
  'Ḟ' => 'Ḟ',
  'ḟ' => 'ḟ',
  'Ḡ' => 'Ḡ',
  'ḡ' => 'ḡ',
  'Ḣ' => 'Ḣ',
  'ḣ' => 'ḣ',
  'Ḥ' => 'Ḥ',
  'ḥ' => 'ḥ',
  'Ḧ' => 'Ḧ',
  'ḧ' => 'ḧ',
  'Ḩ' => 'Ḩ',
  'ḩ' => 'ḩ',
  'Ḫ' => 'Ḫ',
  'ḫ' => 'ḫ',
  'Ḭ' => 'Ḭ',
  'ḭ' => 'ḭ',
  'Ḯ' => 'Ḯ',
  'ḯ' => 'ḯ',
  'Ḱ' => 'Ḱ',
  'ḱ' => 'ḱ',
  'Ḳ' => 'Ḳ',
  'ḳ' => 'ḳ',
  'Ḵ' => 'Ḵ',
  'ḵ' => 'ḵ',
  'Ḷ' => 'Ḷ',
  'ḷ' => 'ḷ',
  'Ḹ' => 'Ḹ',
  'ḹ' => 'ḹ',
  'Ḻ' => 'Ḻ',
  'ḻ' => 'ḻ',
  'Ḽ' => 'Ḽ',
  'ḽ' => 'ḽ',
  'Ḿ' => 'Ḿ',
  'ḿ' => 'ḿ',
  'Ṁ' => 'Ṁ',
  'ṁ' => 'ṁ',
  'Ṃ' => 'Ṃ',
  'ṃ' => 'ṃ',
  'Ṅ' => 'Ṅ',
  'ṅ' => 'ṅ',
  'Ṇ' => 'Ṇ',
  'ṇ' => 'ṇ',
  'Ṉ' => 'Ṉ',
  'ṉ' => 'ṉ',
  'Ṋ' => 'Ṋ',
  'ṋ' => 'ṋ',
  'Ṍ' => 'Ṍ',
  'ṍ' => 'ṍ',
  'Ṏ' => 'Ṏ',
  'ṏ' => 'ṏ',
  'Ṑ' => 'Ṑ',
  'ṑ' => 'ṑ',
  'Ṓ' => 'Ṓ',
  'ṓ' => 'ṓ',
  'Ṕ' => 'Ṕ',
  'ṕ' => 'ṕ',
  'Ṗ' => 'Ṗ',
  'ṗ' => 'ṗ',
  'Ṙ' => 'Ṙ',
  'ṙ' => 'ṙ',
  'Ṛ' => 'Ṛ',
  'ṛ' => 'ṛ',
  'Ṝ' => 'Ṝ',
  'ṝ' => 'ṝ',
  'Ṟ' => 'Ṟ',
  'ṟ' => 'ṟ',
  'Ṡ' => 'Ṡ',
  'ṡ' => 'ṡ',
  'Ṣ' => 'Ṣ',
  'ṣ' => 'ṣ',
  'Ṥ' => 'Ṥ',
  'ṥ' => 'ṥ',
  'Ṧ' => 'Ṧ',
  'ṧ' => 'ṧ',
  'Ṩ' => 'Ṩ',
  'ṩ' => 'ṩ',
  'Ṫ' => 'Ṫ',
  'ṫ' => 'ṫ',
  'Ṭ' => 'Ṭ',
  'ṭ' => 'ṭ',
  'Ṯ' => 'Ṯ',
  'ṯ' => 'ṯ',
  'Ṱ' => 'Ṱ',
  'ṱ' => 'ṱ',
  'Ṳ' => 'Ṳ',
  'ṳ' => 'ṳ',
  'Ṵ' => 'Ṵ',
  'ṵ' => 'ṵ',
  'Ṷ' => 'Ṷ',
  'ṷ' => 'ṷ',
  'Ṹ' => 'Ṹ',
  'ṹ' => 'ṹ',
  'Ṻ' => 'Ṻ',
  'ṻ' => 'ṻ',
  'Ṽ' => 'Ṽ',
  'ṽ' => 'ṽ',
  'Ṿ' => 'Ṿ',
  'ṿ' => 'ṿ',
  'Ẁ' => 'Ẁ',
  'ẁ' => 'ẁ',
  'Ẃ' => 'Ẃ',
  'ẃ' => 'ẃ',
  'Ẅ' => 'Ẅ',
  'ẅ' => 'ẅ',
  'Ẇ' => 'Ẇ',
  'ẇ' => 'ẇ',
  'Ẉ' => 'Ẉ',
  'ẉ' => 'ẉ',
  'Ẋ' => 'Ẋ',
  'ẋ' => 'ẋ',
  'Ẍ' => 'Ẍ',
  'ẍ' => 'ẍ',
  'Ẏ' => 'Ẏ',
  'ẏ' => 'ẏ',
  'Ẑ' => 'Ẑ',
  'ẑ' => 'ẑ',
  'Ẓ' => 'Ẓ',
  'ẓ' => 'ẓ',
  'Ẕ' => 'Ẕ',
  'ẕ' => 'ẕ',
  'ẖ' => 'ẖ',
  'ẗ' => 'ẗ',
  'ẘ' => 'ẘ',
  'ẙ' => 'ẙ',
  'ẛ' => 'ẛ',
  'Ạ' => 'Ạ',
  'ạ' => 'ạ',
  'Ả' => 'Ả',
  'ả' => 'ả',
  'Ấ' => 'Ấ',
  'ấ' => 'ấ',
  'Ầ' => 'Ầ',
  'ầ' => 'ầ',
  'Ẩ' => 'Ẩ',
  'ẩ' => 'ẩ',
  'Ẫ' => 'Ẫ',
  'ẫ' => 'ẫ',
  'Ậ' => 'Ậ',
  'ậ' => 'ậ',
  'Ắ' => 'Ắ',
  'ắ' => 'ắ',
  'Ằ' => 'Ằ',
  'ằ' => 'ằ',
  'Ẳ' => 'Ẳ',
  'ẳ' => 'ẳ',
  'Ẵ' => 'Ẵ',
  'ẵ' => 'ẵ',
  'Ặ' => 'Ặ',
  'ặ' => 'ặ',
  'Ẹ' => 'Ẹ',
  'ẹ' => 'ẹ',
  'Ẻ' => 'Ẻ',
  'ẻ' => 'ẻ',
  'Ẽ' => 'Ẽ',
  'ẽ' => 'ẽ',
  'Ế' => 'Ế',
  'ế' => 'ế',
  'Ề' => 'Ề',
  'ề' => 'ề',
  'Ể' => 'Ể',
  'ể' => 'ể',
  'Ễ' => 'Ễ',
  'ễ' => 'ễ',
  'Ệ' => 'Ệ',
  'ệ' => 'ệ',
  'Ỉ' => 'Ỉ',
  'ỉ' => 'ỉ',
  'Ị' => 'Ị',
  'ị' => 'ị',
  'Ọ' => 'Ọ',
  'ọ' => 'ọ',
  'Ỏ' => 'Ỏ',
  'ỏ' => 'ỏ',
  'Ố' => 'Ố',
  'ố' => 'ố',
  'Ồ' => 'Ồ',
  'ồ' => 'ồ',
  'Ổ' => 'Ổ',
  'ổ' => 'ổ',
  'Ỗ' => 'Ỗ',
  'ỗ' => 'ỗ',
  'Ộ' => 'Ộ',
  'ộ' => 'ộ',
  'Ớ' => 'Ớ',
  'ớ' => 'ớ',
  'Ờ' => 'Ờ',
  'ờ' => 'ờ',
  'Ở' => 'Ở',
  'ở' => 'ở',
  'Ỡ' => 'Ỡ',
  'ỡ' => 'ỡ',
  'Ợ' => 'Ợ',
  'ợ' => 'ợ',
  'Ụ' => 'Ụ',
  'ụ' => 'ụ',
  'Ủ' => 'Ủ',
  'ủ' => 'ủ',
  'Ứ' => 'Ứ',
  'ứ' => 'ứ',
  'Ừ' => 'Ừ',
  'ừ' => 'ừ',
  'Ử' => 'Ử',
  'ử' => 'ử',
  'Ữ' => 'Ữ',
  'ữ' => 'ữ',
  'Ự' => 'Ự',
  'ự' => 'ự',
  'Ỳ' => 'Ỳ',
  'ỳ' => 'ỳ',
  'Ỵ' => 'Ỵ',
  'ỵ' => 'ỵ',
  'Ỷ' => 'Ỷ',
  'ỷ' => 'ỷ',
  'Ỹ' => 'Ỹ',
  'ỹ' => 'ỹ',
  'ἀ' => 'ἀ',
  'ἁ' => 'ἁ',
  'ἂ' => 'ἂ',
  'ἃ' => 'ἃ',
  'ἄ' => 'ἄ',
  'ἅ' => 'ἅ',
  'ἆ' => 'ἆ',
  'ἇ' => 'ἇ',
  'Ἀ' => 'Ἀ',
  'Ἁ' => 'Ἁ',
  'Ἂ' => 'Ἂ',
  'Ἃ' => 'Ἃ',
  'Ἄ' => 'Ἄ',
  'Ἅ' => 'Ἅ',
  'Ἆ' => 'Ἆ',
  'Ἇ' => 'Ἇ',
  'ἐ' => 'ἐ',
  'ἑ' => 'ἑ',
  'ἒ' => 'ἒ',
  'ἓ' => 'ἓ',
  'ἔ' => 'ἔ',
  'ἕ' => 'ἕ',
  'Ἐ' => 'Ἐ',
  'Ἑ' => 'Ἑ',
  'Ἒ' => 'Ἒ',
  'Ἓ' => 'Ἓ',
  'Ἔ' => 'Ἔ',
  'Ἕ' => 'Ἕ',
  'ἠ' => 'ἠ',
  'ἡ' => 'ἡ',
  'ἢ' => 'ἢ',
  'ἣ' => 'ἣ',
  'ἤ' => 'ἤ',
  'ἥ' => 'ἥ',
  'ἦ' => 'ἦ',
  'ἧ' => 'ἧ',
  'Ἠ' => 'Ἠ',
  'Ἡ' => 'Ἡ',
  'Ἢ' => 'Ἢ',
  'Ἣ' => 'Ἣ',
  'Ἤ' => 'Ἤ',
  'Ἥ' => 'Ἥ',
  'Ἦ' => 'Ἦ',
  'Ἧ' => 'Ἧ',
  'ἰ' => 'ἰ',
  'ἱ' => 'ἱ',
  'ἲ' => 'ἲ',
  'ἳ' => 'ἳ',
  'ἴ' => 'ἴ',
  'ἵ' => 'ἵ',
  'ἶ' => 'ἶ',
  'ἷ' => 'ἷ',
  'Ἰ' => 'Ἰ',
  'Ἱ' => 'Ἱ',
  'Ἲ' => 'Ἲ',
  'Ἳ' => 'Ἳ',
  'Ἴ' => 'Ἴ',
  'Ἵ' => 'Ἵ',
  'Ἶ' => 'Ἶ',
  'Ἷ' => 'Ἷ',
  'ὀ' => 'ὀ',
  'ὁ' => 'ὁ',
  'ὂ' => 'ὂ',
  'ὃ' => 'ὃ',
  'ὄ' => 'ὄ',
  'ὅ' => 'ὅ',
  'Ὀ' => 'Ὀ',
  'Ὁ' => 'Ὁ',
  'Ὂ' => 'Ὂ',
  'Ὃ' => 'Ὃ',
  'Ὄ' => 'Ὄ',
  'Ὅ' => 'Ὅ',
  'ὐ' => 'ὐ',
  'ὑ' => 'ὑ',
  'ὒ' => 'ὒ',
  'ὓ' => 'ὓ',
  'ὔ' => 'ὔ',
  'ὕ' => 'ὕ',
  'ὖ' => 'ὖ',
  'ὗ' => 'ὗ',
  'Ὑ' => 'Ὑ',
  'Ὓ' => 'Ὓ',
  'Ὕ' => 'Ὕ',
  'Ὗ' => 'Ὗ',
  'ὠ' => 'ὠ',
  'ὡ' => 'ὡ',
  'ὢ' => 'ὢ',
  'ὣ' => 'ὣ',
  'ὤ' => 'ὤ',
  'ὥ' => 'ὥ',
  'ὦ' => 'ὦ',
  'ὧ' => 'ὧ',
  'Ὠ' => 'Ὠ',
  'Ὡ' => 'Ὡ',
  'Ὢ' => 'Ὢ',
  'Ὣ' => 'Ὣ',
  'Ὤ' => 'Ὤ',
  'Ὥ' => 'Ὥ',
  'Ὦ' => 'Ὦ',
  'Ὧ' => 'Ὧ',
  'ὰ' => 'ὰ',
  'ά' => 'ά',
  'ὲ' => 'ὲ',
  'έ' => 'έ',
  'ὴ' => 'ὴ',
  'ή' => 'ή',
  'ὶ' => 'ὶ',
  'ί' => 'ί',
  'ὸ' => 'ὸ',
  'ό' => 'ό',
  'ὺ' => 'ὺ',
  'ύ' => 'ύ',
  'ὼ' => 'ὼ',
  'ώ' => 'ώ',
  'ᾀ' => 'ᾀ',
  'ᾁ' => 'ᾁ',
  'ᾂ' => 'ᾂ',
  'ᾃ' => 'ᾃ',
  'ᾄ' => 'ᾄ',
  'ᾅ' => 'ᾅ',
  'ᾆ' => 'ᾆ',
  'ᾇ' => 'ᾇ',
  'ᾈ' => 'ᾈ',
  'ᾉ' => 'ᾉ',
  'ᾊ' => 'ᾊ',
  'ᾋ' => 'ᾋ',
  'ᾌ' => 'ᾌ',
  'ᾍ' => 'ᾍ',
  'ᾎ' => 'ᾎ',
  'ᾏ' => 'ᾏ',
  'ᾐ' => 'ᾐ',
  'ᾑ' => 'ᾑ',
  'ᾒ' => 'ᾒ',
  'ᾓ' => 'ᾓ',
  'ᾔ' => 'ᾔ',
  'ᾕ' => 'ᾕ',
  'ᾖ' => 'ᾖ',
  'ᾗ' => 'ᾗ',
  'ᾘ' => 'ᾘ',
  'ᾙ' => 'ᾙ',
  'ᾚ' => 'ᾚ',
  'ᾛ' => 'ᾛ',
  'ᾜ' => 'ᾜ',
  'ᾝ' => 'ᾝ',
  'ᾞ' => 'ᾞ',
  'ᾟ' => 'ᾟ',
  'ᾠ' => 'ᾠ',
  'ᾡ' => 'ᾡ',
  'ᾢ' => 'ᾢ',
  'ᾣ' => 'ᾣ',
  'ᾤ' => 'ᾤ',
  'ᾥ' => 'ᾥ',
  'ᾦ' => 'ᾦ',
  'ᾧ' => 'ᾧ',
  'ᾨ' => 'ᾨ',
  'ᾩ' => 'ᾩ',
  'ᾪ' => 'ᾪ',
  'ᾫ' => 'ᾫ',
  'ᾬ' => 'ᾬ',
  'ᾭ' => 'ᾭ',
  'ᾮ' => 'ᾮ',
  'ᾯ' => 'ᾯ',
  'ᾰ' => 'ᾰ',
  'ᾱ' => 'ᾱ',
  'ᾲ' => 'ᾲ',
  'ᾳ' => 'ᾳ',
  'ᾴ' => 'ᾴ',
  'ᾶ' => 'ᾶ',
  'ᾷ' => 'ᾷ',
  'Ᾰ' => 'Ᾰ',
  'Ᾱ' => 'Ᾱ',
  'Ὰ' => 'Ὰ',
  'Ά' => 'Ά',
  'ᾼ' => 'ᾼ',
  'ι' => 'ι',
  '῁' => '῁',
  'ῂ' => 'ῂ',
  'ῃ' => 'ῃ',
  'ῄ' => 'ῄ',
  'ῆ' => 'ῆ',
  'ῇ' => 'ῇ',
  'Ὲ' => 'Ὲ',
  'Έ' => 'Έ',
  'Ὴ' => 'Ὴ',
  'Ή' => 'Ή',
  'ῌ' => 'ῌ',
  '῍' => '῍',
  '῎' => '῎',
  '῏' => '῏',
  'ῐ' => 'ῐ',
  'ῑ' => 'ῑ',
  'ῒ' => 'ῒ',
  'ΐ' => 'ΐ',
  'ῖ' => 'ῖ',
  'ῗ' => 'ῗ',
  'Ῐ' => 'Ῐ',
  'Ῑ' => 'Ῑ',
  'Ὶ' => 'Ὶ',
  'Ί' => 'Ί',
  '῝' => '῝',
  '῞' => '῞',
  '῟' => '῟',
  'ῠ' => 'ῠ',
  'ῡ' => 'ῡ',
  'ῢ' => 'ῢ',
  'ΰ' => 'ΰ',
  'ῤ' => 'ῤ',
  'ῥ' => 'ῥ',
  'ῦ' => 'ῦ',
  'ῧ' => 'ῧ',
  'Ῠ' => 'Ῠ',
  'Ῡ' => 'Ῡ',
  'Ὺ' => 'Ὺ',
  'Ύ' => 'Ύ',
  'Ῥ' => 'Ῥ',
  '῭' => '῭',
  '΅' => '΅',
  '`' => '`',
  'ῲ' => 'ῲ',
  'ῳ' => 'ῳ',
  'ῴ' => 'ῴ',
  'ῶ' => 'ῶ',
  'ῷ' => 'ῷ',
  'Ὸ' => 'Ὸ',
  'Ό' => 'Ό',
  'Ὼ' => 'Ὼ',
  'Ώ' => 'Ώ',
  'ῼ' => 'ῼ',
  '´' => '´',
  ' ' => ' ',
  ' ' => ' ',
  'Ω' => 'Ω',
  'K' => 'K',
  'Å' => 'Å',
  '↚' => '↚',
  '↛' => '↛',
  '↮' => '↮',
  '⇍' => '⇍',
  '⇎' => '⇎',
  '⇏' => '⇏',
  '∄' => '∄',
  '∉' => '∉',
  '∌' => '∌',
  '∤' => '∤',
  '∦' => '∦',
  '≁' => '≁',
  '≄' => '≄',
  '≇' => '≇',
  '≉' => '≉',
  '≠' => '≠',
  '≢' => '≢',
  '≭' => '≭',
  '≮' => '≮',
  '≯' => '≯',
  '≰' => '≰',
  '≱' => '≱',
  '≴' => '≴',
  '≵' => '≵',
  '≸' => '≸',
  '≹' => '≹',
  '⊀' => '⊀',
  '⊁' => '⊁',
  '⊄' => '⊄',
  '⊅' => '⊅',
  '⊈' => '⊈',
  '⊉' => '⊉',
  '⊬' => '⊬',
  '⊭' => '⊭',
  '⊮' => '⊮',
  '⊯' => '⊯',
  '⋠' => '⋠',
  '⋡' => '⋡',
  '⋢' => '⋢',
  '⋣' => '⋣',
  '⋪' => '⋪',
  '⋫' => '⋫',
  '⋬' => '⋬',
  '⋭' => '⋭',
  '〈' => '〈',
  '〉' => '〉',
  '⫝̸' => '⫝̸',
  'が' => 'が',
  'ぎ' => 'ぎ',
  'ぐ' => 'ぐ',
  'げ' => 'げ',
  'ご' => 'ご',
  'ざ' => 'ざ',
  'じ' => 'じ',
  'ず' => 'ず',
  'ぜ' => 'ぜ',
  'ぞ' => 'ぞ',
  'だ' => 'だ',
  'ぢ' => 'ぢ',
  'づ' => 'づ',
  'で' => 'で',
  'ど' => 'ど',
  'ば' => 'ば',
  'ぱ' => 'ぱ',
  'び' => 'び',
  'ぴ' => 'ぴ',
  'ぶ' => 'ぶ',
  'ぷ' => 'ぷ',
  'べ' => 'べ',
  'ぺ' => 'ぺ',
  'ぼ' => 'ぼ',
  'ぽ' => 'ぽ',
  'ゔ' => 'ゔ',
  'ゞ' => 'ゞ',
  'ガ' => 'ガ',
  'ギ' => 'ギ',
  'グ' => 'グ',
  'ゲ' => 'ゲ',
  'ゴ' => 'ゴ',
  'ザ' => 'ザ',
  'ジ' => 'ジ',
  'ズ' => 'ズ',
  'ゼ' => 'ゼ',
  'ゾ' => 'ゾ',
  'ダ' => 'ダ',
  'ヂ' => 'ヂ',
  'ヅ' => 'ヅ',
  'デ' => 'デ',
  'ド' => 'ド',
  'バ' => 'バ',
  'パ' => 'パ',
  'ビ' => 'ビ',
  'ピ' => 'ピ',
  'ブ' => 'ブ',
  'プ' => 'プ',
  'ベ' => 'ベ',
  'ペ' => 'ペ',
  'ボ' => 'ボ',
  'ポ' => 'ポ',
  'ヴ' => 'ヴ',
  'ヷ' => 'ヷ',
  'ヸ' => 'ヸ',
  'ヹ' => 'ヹ',
  'ヺ' => 'ヺ',
  'ヾ' => 'ヾ',
  '豈' => '豈',
  '更' => '更',
  '車' => '車',
  '賈' => '賈',
  '滑' => '滑',
  '串' => '串',
  '句' => '句',
  '龜' => '龜',
  '龜' => '龜',
  '契' => '契',
  '金' => '金',
  '喇' => '喇',
  '奈' => '奈',
  '懶' => '懶',
  '癩' => '癩',
  '羅' => '羅',
  '蘿' => '蘿',
  '螺' => '螺',
  '裸' => '裸',
  '邏' => '邏',
  '樂' => '樂',
  '洛' => '洛',
  '烙' => '烙',
  '珞' => '珞',
  '落' => '落',
  '酪' => '酪',
  '駱' => '駱',
  '亂' => '亂',
  '卵' => '卵',
  '欄' => '欄',
  '爛' => '爛',
  '蘭' => '蘭',
  '鸞' => '鸞',
  '嵐' => '嵐',
  '濫' => '濫',
  '藍' => '藍',
  '襤' => '襤',
  '拉' => '拉',
  '臘' => '臘',
  '蠟' => '蠟',
  '廊' => '廊',
  '朗' => '朗',
  '浪' => '浪',
  '狼' => '狼',
  '郎' => '郎',
  '來' => '來',
  '冷' => '冷',
  '勞' => '勞',
  '擄' => '擄',
  '櫓' => '櫓',
  '爐' => '爐',
  '盧' => '盧',
  '老' => '老',
  '蘆' => '蘆',
  '虜' => '虜',
  '路' => '路',
  '露' => '露',
  '魯' => '魯',
  '鷺' => '鷺',
  '碌' => '碌',
  '祿' => '祿',
  '綠' => '綠',
  '菉' => '菉',
  '錄' => '錄',
  '鹿' => '鹿',
  '論' => '論',
  '壟' => '壟',
  '弄' => '弄',
  '籠' => '籠',
  '聾' => '聾',
  '牢' => '牢',
  '磊' => '磊',
  '賂' => '賂',
  '雷' => '雷',
  '壘' => '壘',
  '屢' => '屢',
  '樓' => '樓',
  '淚' => '淚',
  '漏' => '漏',
  '累' => '累',
  '縷' => '縷',
  '陋' => '陋',
  '勒' => '勒',
  '肋' => '肋',
  '凜' => '凜',
  '凌' => '凌',
  '稜' => '稜',
  '綾' => '綾',
  '菱' => '菱',
  '陵' => '陵',
  '讀' => '讀',
  '拏' => '拏',
  '樂' => '樂',
  '諾' => '諾',
  '丹' => '丹',
  '寧' => '寧',
  '怒' => '怒',
  '率' => '率',
  '異' => '異',
  '北' => '北',
  '磻' => '磻',
  '便' => '便',
  '復' => '復',
  '不' => '不',
  '泌' => '泌',
  '數' => '數',
  '索' => '索',
  '參' => '參',
  '塞' => '塞',
  '省' => '省',
  '葉' => '葉',
  '說' => '說',
  '殺' => '殺',
  '辰' => '辰',
  '沈' => '沈',
  '拾' => '拾',
  '若' => '若',
  '掠' => '掠',
  '略' => '略',
  '亮' => '亮',
  '兩' => '兩',
  '凉' => '凉',
  '梁' => '梁',
  '糧' => '糧',
  '良' => '良',
  '諒' => '諒',
  '量' => '量',
  '勵' => '勵',
  '呂' => '呂',
  '女' => '女',
  '廬' => '廬',
  '旅' => '旅',
  '濾' => '濾',
  '礪' => '礪',
  '閭' => '閭',
  '驪' => '驪',
  '麗' => '麗',
  '黎' => '黎',
  '力' => '力',
  '曆' => '曆',
  '歷' => '歷',
  '轢' => '轢',
  '年' => '年',
  '憐' => '憐',
  '戀' => '戀',
  '撚' => '撚',
  '漣' => '漣',
  '煉' => '煉',
  '璉' => '璉',
  '秊' => '秊',
  '練' => '練',
  '聯' => '聯',
  '輦' => '輦',
  '蓮' => '蓮',
  '連' => '連',
  '鍊' => '鍊',
  '列' => '列',
  '劣' => '劣',
  '咽' => '咽',
  '烈' => '烈',
  '裂' => '裂',
  '說' => '說',
  '廉' => '廉',
  '念' => '念',
  '捻' => '捻',
  '殮' => '殮',
  '簾' => '簾',
  '獵' => '獵',
  '令' => '令',
  '囹' => '囹',
  '寧' => '寧',
  '嶺' => '嶺',
  '怜' => '怜',
  '玲' => '玲',
  '瑩' => '瑩',
  '羚' => '羚',
  '聆' => '聆',
  '鈴' => '鈴',
  '零' => '零',
  '靈' => '靈',
  '領' => '領',
  '例' => '例',
  '禮' => '禮',
  '醴' => '醴',
  '隸' => '隸',
  '惡' => '惡',
  '了' => '了',
  '僚' => '僚',
  '寮' => '寮',
  '尿' => '尿',
  '料' => '料',
  '樂' => '樂',
  '燎' => '燎',
  '療' => '療',
  '蓼' => '蓼',
  '遼' => '遼',
  '龍' => '龍',
  '暈' => '暈',
  '阮' => '阮',
  '劉' => '劉',
  '杻' => '杻',
  '柳' => '柳',
  '流' => '流',
  '溜' => '溜',
  '琉' => '琉',
  '留' => '留',
  '硫' => '硫',
  '紐' => '紐',
  '類' => '類',
  '六' => '六',
  '戮' => '戮',
  '陸' => '陸',
  '倫' => '倫',
  '崙' => '崙',
  '淪' => '淪',
  '輪' => '輪',
  '律' => '律',
  '慄' => '慄',
  '栗' => '栗',
  '率' => '率',
  '隆' => '隆',
  '利' => '利',
  '吏' => '吏',
  '履' => '履',
  '易' => '易',
  '李' => '李',
  '梨' => '梨',
  '泥' => '泥',
  '理' => '理',
  '痢' => '痢',
  '罹' => '罹',
  '裏' => '裏',
  '裡' => '裡',
  '里' => '里',
  '離' => '離',
  '匿' => '匿',
  '溺' => '溺',
  '吝' => '吝',
  '燐' => '燐',
  '璘' => '璘',
  '藺' => '藺',
  '隣' => '隣',
  '鱗' => '鱗',
  '麟' => '麟',
  '林' => '林',
  '淋' => '淋',
  '臨' => '臨',
  '立' => '立',
  '笠' => '笠',
  '粒' => '粒',
  '狀' => '狀',
  '炙' => '炙',
  '識' => '識',
  '什' => '什',
  '茶' => '茶',
  '刺' => '刺',
  '切' => '切',
  '度' => '度',
  '拓' => '拓',
  '糖' => '糖',
  '宅' => '宅',
  '洞' => '洞',
  '暴' => '暴',
  '輻' => '輻',
  '行' => '行',
  '降' => '降',
  '見' => '見',
  '廓' => '廓',
  '兀' => '兀',
  '嗀' => '嗀',
  '塚' => '塚',
  '晴' => '晴',
  '凞' => '凞',
  '猪' => '猪',
  '益' => '益',
  '礼' => '礼',
  '神' => '神',
  '祥' => '祥',
  '福' => '福',
  '靖' => '靖',
  '精' => '精',
  '羽' => '羽',
  '蘒' => '蘒',
  '諸' => '諸',
  '逸' => '逸',
  '都' => '都',
  '飯' => '飯',
  '飼' => '飼',
  '館' => '館',
  '鶴' => '鶴',
  '郞' => '郞',
  '隷' => '隷',
  '侮' => '侮',
  '僧' => '僧',
  '免' => '免',
  '勉' => '勉',
  '勤' => '勤',
  '卑' => '卑',
  '喝' => '喝',
  '嘆' => '嘆',
  '器' => '器',
  '塀' => '塀',
  '墨' => '墨',
  '層' => '層',
  '屮' => '屮',
  '悔' => '悔',
  '慨' => '慨',
  '憎' => '憎',
  '懲' => '懲',
  '敏' => '敏',
  '既' => '既',
  '暑' => '暑',
  '梅' => '梅',
  '海' => '海',
  '渚' => '渚',
  '漢' => '漢',
  '煮' => '煮',
  '爫' => '爫',
  '琢' => '琢',
  '碑' => '碑',
  '社' => '社',
  '祉' => '祉',
  '祈' => '祈',
  '祐' => '祐',
  '祖' => '祖',
  '祝' => '祝',
  '禍' => '禍',
  '禎' => '禎',
  '穀' => '穀',
  '突' => '突',
  '節' => '節',
  '練' => '練',
  '縉' => '縉',
  '繁' => '繁',
  '署' => '署',
  '者' => '者',
  '臭' => '臭',
  '艹' => '艹',
  '艹' => '艹',
  '著' => '著',
  '褐' => '褐',
  '視' => '視',
  '謁' => '謁',
  '謹' => '謹',
  '賓' => '賓',
  '贈' => '贈',
  '辶' => '辶',
  '逸' => '逸',
  '難' => '難',
  '響' => '響',
  '頻' => '頻',
  '恵' => '恵',
  '𤋮' => '𤋮',
  '舘' => '舘',
  '並' => '並',
  '况' => '况',
  '全' => '全',
  '侀' => '侀',
  '充' => '充',
  '冀' => '冀',
  '勇' => '勇',
  '勺' => '勺',
  '喝' => '喝',
  '啕' => '啕',
  '喙' => '喙',
  '嗢' => '嗢',
  '塚' => '塚',
  '墳' => '墳',
  '奄' => '奄',
  '奔' => '奔',
  '婢' => '婢',
  '嬨' => '嬨',
  '廒' => '廒',
  '廙' => '廙',
  '彩' => '彩',
  '徭' => '徭',
  '惘' => '惘',
  '慎' => '慎',
  '愈' => '愈',
  '憎' => '憎',
  '慠' => '慠',
  '懲' => '懲',
  '戴' => '戴',
  '揄' => '揄',
  '搜' => '搜',
  '摒' => '摒',
  '敖' => '敖',
  '晴' => '晴',
  '朗' => '朗',
  '望' => '望',
  '杖' => '杖',
  '歹' => '歹',
  '殺' => '殺',
  '流' => '流',
  '滛' => '滛',
  '滋' => '滋',
  '漢' => '漢',
  '瀞' => '瀞',
  '煮' => '煮',
  '瞧' => '瞧',
  '爵' => '爵',
  '犯' => '犯',
  '猪' => '猪',
  '瑱' => '瑱',
  '甆' => '甆',
  '画' => '画',
  '瘝' => '瘝',
  '瘟' => '瘟',
  '益' => '益',
  '盛' => '盛',
  '直' => '直',
  '睊' => '睊',
  '着' => '着',
  '磌' => '磌',
  '窱' => '窱',
  '節' => '節',
  '类' => '类',
  '絛' => '絛',
  '練' => '練',
  '缾' => '缾',
  '者' => '者',
  '荒' => '荒',
  '華' => '華',
  '蝹' => '蝹',
  '襁' => '襁',
  '覆' => '覆',
  '視' => '視',
  '調' => '調',
  '諸' => '諸',
  '請' => '請',
  '謁' => '謁',
  '諾' => '諾',
  '諭' => '諭',
  '謹' => '謹',
  '變' => '變',
  '贈' => '贈',
  '輸' => '輸',
  '遲' => '遲',
  '醙' => '醙',
  '鉶' => '鉶',
  '陼' => '陼',
  '難' => '難',
  '靖' => '靖',
  '韛' => '韛',
  '響' => '響',
  '頋' => '頋',
  '頻' => '頻',
  '鬒' => '鬒',
  '龜' => '龜',
  '𢡊' => '𢡊',
  '𢡄' => '𢡄',
  '𣏕' => '𣏕',
  '㮝' => '㮝',
  '䀘' => '䀘',
  '䀹' => '䀹',
  '𥉉' => '𥉉',
  '𥳐' => '𥳐',
  '𧻓' => '𧻓',
  '齃' => '齃',
  '龎' => '龎',
  'יִ' => 'יִ',
  'ײַ' => 'ײַ',
  'שׁ' => 'שׁ',
  'שׂ' => 'שׂ',
  'שּׁ' => 'שּׁ',
  'שּׂ' => 'שּׂ',
  'אַ' => 'אַ',
  'אָ' => 'אָ',
  'אּ' => 'אּ',
  'בּ' => 'בּ',
  'גּ' => 'גּ',
  'דּ' => 'דּ',
  'הּ' => 'הּ',
  'וּ' => 'וּ',
  'זּ' => 'זּ',
  'טּ' => 'טּ',
  'יּ' => 'יּ',
  'ךּ' => 'ךּ',
  'כּ' => 'כּ',
  'לּ' => 'לּ',
  'מּ' => 'מּ',
  'נּ' => 'נּ',
  'סּ' => 'סּ',
  'ףּ' => 'ףּ',
  'פּ' => 'פּ',
  'צּ' => 'צּ',
  'קּ' => 'קּ',
  'רּ' => 'רּ',
  'שּ' => 'שּ',
  'תּ' => 'תּ',
  'וֹ' => 'וֹ',
  'בֿ' => 'בֿ',
  'כֿ' => 'כֿ',
  'פֿ' => 'פֿ',
  '𑂚' => '𑂚',
  '𑂜' => '𑂜',
  '𑂫' => '𑂫',
  '𑄮' => '𑄮',
  '𑄯' => '𑄯',
  '𑍋' => '𑍋',
  '𑍌' => '𑍌',
  '𑒻' => '𑒻',
  '𑒼' => '𑒼',
  '𑒾' => '𑒾',
  '𑖺' => '𑖺',
  '𑖻' => '𑖻',
  '𑤸' => '𑤸',
  '𝅗𝅥' => '𝅗𝅥',
  '𝅘𝅥' => '𝅘𝅥',
  '𝅘𝅥𝅮' => '𝅘𝅥𝅮',
  '𝅘𝅥𝅯' => '𝅘𝅥𝅯',
  '𝅘𝅥𝅰' => '𝅘𝅥𝅰',
  '𝅘𝅥𝅱' => '𝅘𝅥𝅱',
  '𝅘𝅥𝅲' => '𝅘𝅥𝅲',
  '𝆹𝅥' => '𝆹𝅥',
  '𝆺𝅥' => '𝆺𝅥',
  '𝆹𝅥𝅮' => '𝆹𝅥𝅮',
  '𝆺𝅥𝅮' => '𝆺𝅥𝅮',
  '𝆹𝅥𝅯' => '𝆹𝅥𝅯',
  '𝆺𝅥𝅯' => '𝆺𝅥𝅯',
  '丽' => '丽',
  '丸' => '丸',
  '乁' => '乁',
  '𠄢' => '𠄢',
  '你' => '你',
  '侮' => '侮',
  '侻' => '侻',
  '倂' => '倂',
  '偺' => '偺',
  '備' => '備',
  '僧' => '僧',
  '像' => '像',
  '㒞' => '㒞',
  '𠘺' => '𠘺',
  '免' => '免',
  '兔' => '兔',
  '兤' => '兤',
  '具' => '具',
  '𠔜' => '𠔜',
  '㒹' => '㒹',
  '內' => '內',
  '再' => '再',
  '𠕋' => '𠕋',
  '冗' => '冗',
  '冤' => '冤',
  '仌' => '仌',
  '冬' => '冬',
  '况' => '况',
  '𩇟' => '𩇟',
  '凵' => '凵',
  '刃' => '刃',
  '㓟' => '㓟',
  '刻' => '刻',
  '剆' => '剆',
  '割' => '割',
  '剷' => '剷',
  '㔕' => '㔕',
  '勇' => '勇',
  '勉' => '勉',
  '勤' => '勤',
  '勺' => '勺',
  '包' => '包',
  '匆' => '匆',
  '北' => '北',
  '卉' => '卉',
  '卑' => '卑',
  '博' => '博',
  '即' => '即',
  '卽' => '卽',
  '卿' => '卿',
  '卿' => '卿',
  '卿' => '卿',
  '𠨬' => '𠨬',
  '灰' => '灰',
  '及' => '及',
  '叟' => '叟',
  '𠭣' => '𠭣',
  '叫' => '叫',
  '叱' => '叱',
  '吆' => '吆',
  '咞' => '咞',
  '吸' => '吸',
  '呈' => '呈',
  '周' => '周',
  '咢' => '咢',
  '哶' => '哶',
  '唐' => '唐',
  '啓' => '啓',
  '啣' => '啣',
  '善' => '善',
  '善' => '善',
  '喙' => '喙',
  '喫' => '喫',
  '喳' => '喳',
  '嗂' => '嗂',
  '圖' => '圖',
  '嘆' => '嘆',
  '圗' => '圗',
  '噑' => '噑',
  '噴' => '噴',
  '切' => '切',
  '壮' => '壮',
  '城' => '城',
  '埴' => '埴',
  '堍' => '堍',
  '型' => '型',
  '堲' => '堲',
  '報' => '報',
  '墬' => '墬',
  '𡓤' => '𡓤',
  '売' => '売',
  '壷' => '壷',
  '夆' => '夆',
  '多' => '多',
  '夢' => '夢',
  '奢' => '奢',
  '𡚨' => '𡚨',
  '𡛪' => '𡛪',
  '姬' => '姬',
  '娛' => '娛',
  '娧' => '娧',
  '姘' => '姘',
  '婦' => '婦',
  '㛮' => '㛮',
  '㛼' => '㛼',
  '嬈' => '嬈',
  '嬾' => '嬾',
  '嬾' => '嬾',
  '𡧈' => '𡧈',
  '寃' => '寃',
  '寘' => '寘',
  '寧' => '寧',
  '寳' => '寳',
  '𡬘' => '𡬘',
  '寿' => '寿',
  '将' => '将',
  '当' => '当',
  '尢' => '尢',
  '㞁' => '㞁',
  '屠' => '屠',
  '屮' => '屮',
  '峀' => '峀',
  '岍' => '岍',
  '𡷤' => '𡷤',
  '嵃' => '嵃',
  '𡷦' => '𡷦',
  '嵮' => '嵮',
  '嵫' => '嵫',
  '嵼' => '嵼',
  '巡' => '巡',
  '巢' => '巢',
  '㠯' => '㠯',
  '巽' => '巽',
  '帨' => '帨',
  '帽' => '帽',
  '幩' => '幩',
  '㡢' => '㡢',
  '𢆃' => '𢆃',
  '㡼' => '㡼',
  '庰' => '庰',
  '庳' => '庳',
  '庶' => '庶',
  '廊' => '廊',
  '𪎒' => '𪎒',
  '廾' => '廾',
  '𢌱' => '𢌱',
  '𢌱' => '𢌱',
  '舁' => '舁',
  '弢' => '弢',
  '弢' => '弢',
  '㣇' => '㣇',
  '𣊸' => '𣊸',
  '𦇚' => '𦇚',
  '形' => '形',
  '彫' => '彫',
  '㣣' => '㣣',
  '徚' => '徚',
  '忍' => '忍',
  '志' => '志',
  '忹' => '忹',
  '悁' => '悁',
  '㤺' => '㤺',
  '㤜' => '㤜',
  '悔' => '悔',
  '𢛔' => '𢛔',
  '惇' => '惇',
  '慈' => '慈',
  '慌' => '慌',
  '慎' => '慎',
  '慌' => '慌',
  '慺' => '慺',
  '憎' => '憎',
  '憲' => '憲',
  '憤' => '憤',
  '憯' => '憯',
  '懞' => '懞',
  '懲' => '懲',
  '懶' => '懶',
  '成' => '成',
  '戛' => '戛',
  '扝' => '扝',
  '抱' => '抱',
  '拔' => '拔',
  '捐' => '捐',
  '𢬌' => '𢬌',
  '挽' => '挽',
  '拼' => '拼',
  '捨' => '捨',
  '掃' => '掃',
  '揤' => '揤',
  '𢯱' => '𢯱',
  '搢' => '搢',
  '揅' => '揅',
  '掩' => '掩',
  '㨮' => '㨮',
  '摩' => '摩',
  '摾' => '摾',
  '撝' => '撝',
  '摷' => '摷',
  '㩬' => '㩬',
  '敏' => '敏',
  '敬' => '敬',
  '𣀊' => '𣀊',
  '旣' => '旣',
  '書' => '書',
  '晉' => '晉',
  '㬙' => '㬙',
  '暑' => '暑',
  '㬈' => '㬈',
  '㫤' => '㫤',
  '冒' => '冒',
  '冕' => '冕',
  '最' => '最',
  '暜' => '暜',
  '肭' => '肭',
  '䏙' => '䏙',
  '朗' => '朗',
  '望' => '望',
  '朡' => '朡',
  '杞' => '杞',
  '杓' => '杓',
  '𣏃' => '𣏃',
  '㭉' => '㭉',
  '柺' => '柺',
  '枅' => '枅',
  '桒' => '桒',
  '梅' => '梅',
  '𣑭' => '𣑭',
  '梎' => '梎',
  '栟' => '栟',
  '椔' => '椔',
  '㮝' => '㮝',
  '楂' => '楂',
  '榣' => '榣',
  '槪' => '槪',
  '檨' => '檨',
  '𣚣' => '𣚣',
  '櫛' => '櫛',
  '㰘' => '㰘',
  '次' => '次',
  '𣢧' => '𣢧',
  '歔' => '歔',
  '㱎' => '㱎',
  '歲' => '歲',
  '殟' => '殟',
  '殺' => '殺',
  '殻' => '殻',
  '𣪍' => '𣪍',
  '𡴋' => '𡴋',
  '𣫺' => '𣫺',
  '汎' => '汎',
  '𣲼' => '𣲼',
  '沿' => '沿',
  '泍' => '泍',
  '汧' => '汧',
  '洖' => '洖',
  '派' => '派',
  '海' => '海',
  '流' => '流',
  '浩' => '浩',
  '浸' => '浸',
  '涅' => '涅',
  '𣴞' => '𣴞',
  '洴' => '洴',
  '港' => '港',
  '湮' => '湮',
  '㴳' => '㴳',
  '滋' => '滋',
  '滇' => '滇',
  '𣻑' => '𣻑',
  '淹' => '淹',
  '潮' => '潮',
  '𣽞' => '𣽞',
  '𣾎' => '𣾎',
  '濆' => '濆',
  '瀹' => '瀹',
  '瀞' => '瀞',
  '瀛' => '瀛',
  '㶖' => '㶖',
  '灊' => '灊',
  '災' => '災',
  '灷' => '灷',
  '炭' => '炭',
  '𠔥' => '𠔥',
  '煅' => '煅',
  '𤉣' => '𤉣',
  '熜' => '熜',
  '𤎫' => '𤎫',
  '爨' => '爨',
  '爵' => '爵',
  '牐' => '牐',
  '𤘈' => '𤘈',
  '犀' => '犀',
  '犕' => '犕',
  '𤜵' => '𤜵',
  '𤠔' => '𤠔',
  '獺' => '獺',
  '王' => '王',
  '㺬' => '㺬',
  '玥' => '玥',
  '㺸' => '㺸',
  '㺸' => '㺸',
  '瑇' => '瑇',
  '瑜' => '瑜',
  '瑱' => '瑱',
  '璅' => '璅',
  '瓊' => '瓊',
  '㼛' => '㼛',
  '甤' => '甤',
  '𤰶' => '𤰶',
  '甾' => '甾',
  '𤲒' => '𤲒',
  '異' => '異',
  '𢆟' => '𢆟',
  '瘐' => '瘐',
  '𤾡' => '𤾡',
  '𤾸' => '𤾸',
  '𥁄' => '𥁄',
  '㿼' => '㿼',
  '䀈' => '䀈',
  '直' => '直',
  '𥃳' => '𥃳',
  '𥃲' => '𥃲',
  '𥄙' => '𥄙',
  '𥄳' => '𥄳',
  '眞' => '眞',
  '真' => '真',
  '真' => '真',
  '睊' => '睊',
  '䀹' => '䀹',
  '瞋' => '瞋',
  '䁆' => '䁆',
  '䂖' => '䂖',
  '𥐝' => '𥐝',
  '硎' => '硎',
  '碌' => '碌',
  '磌' => '磌',
  '䃣' => '䃣',
  '𥘦' => '𥘦',
  '祖' => '祖',
  '𥚚' => '𥚚',
  '𥛅' => '𥛅',
  '福' => '福',
  '秫' => '秫',
  '䄯' => '䄯',
  '穀' => '穀',
  '穊' => '穊',
  '穏' => '穏',
  '𥥼' => '𥥼',
  '𥪧' => '𥪧',
  '𥪧' => '𥪧',
  '竮' => '竮',
  '䈂' => '䈂',
  '𥮫' => '𥮫',
  '篆' => '篆',
  '築' => '築',
  '䈧' => '䈧',
  '𥲀' => '𥲀',
  '糒' => '糒',
  '䊠' => '䊠',
  '糨' => '糨',
  '糣' => '糣',
  '紀' => '紀',
  '𥾆' => '𥾆',
  '絣' => '絣',
  '䌁' => '䌁',
  '緇' => '緇',
  '縂' => '縂',
  '繅' => '繅',
  '䌴' => '䌴',
  '𦈨' => '𦈨',
  '𦉇' => '𦉇',
  '䍙' => '䍙',
  '𦋙' => '𦋙',
  '罺' => '罺',
  '𦌾' => '𦌾',
  '羕' => '羕',
  '翺' => '翺',
  '者' => '者',
  '𦓚' => '𦓚',
  '𦔣' => '𦔣',
  '聠' => '聠',
  '𦖨' => '𦖨',
  '聰' => '聰',
  '𣍟' => '𣍟',
  '䏕' => '䏕',
  '育' => '育',
  '脃' => '脃',
  '䐋' => '䐋',
  '脾' => '脾',
  '媵' => '媵',
  '𦞧' => '𦞧',
  '𦞵' => '𦞵',
  '𣎓' => '𣎓',
  '𣎜' => '𣎜',
  '舁' => '舁',
  '舄' => '舄',
  '辞' => '辞',
  '䑫' => '䑫',
  '芑' => '芑',
  '芋' => '芋',
  '芝' => '芝',
  '劳' => '劳',
  '花' => '花',
  '芳' => '芳',
  '芽' => '芽',
  '苦' => '苦',
  '𦬼' => '𦬼',
  '若' => '若',
  '茝' => '茝',
  '荣' => '荣',
  '莭' => '莭',
  '茣' => '茣',
  '莽' => '莽',
  '菧' => '菧',
  '著' => '著',
  '荓' => '荓',
  '菊' => '菊',
  '菌' => '菌',
  '菜' => '菜',
  '𦰶' => '𦰶',
  '𦵫' => '𦵫',
  '𦳕' => '𦳕',
  '䔫' => '䔫',
  '蓱' => '蓱',
  '蓳' => '蓳',
  '蔖' => '蔖',
  '𧏊' => '𧏊',
  '蕤' => '蕤',
  '𦼬' => '𦼬',
  '䕝' => '䕝',
  '䕡' => '䕡',
  '𦾱' => '𦾱',
  '𧃒' => '𧃒',
  '䕫' => '䕫',
  '虐' => '虐',
  '虜' => '虜',
  '虧' => '虧',
  '虩' => '虩',
  '蚩' => '蚩',
  '蚈' => '蚈',
  '蜎' => '蜎',
  '蛢' => '蛢',
  '蝹' => '蝹',
  '蜨' => '蜨',
  '蝫' => '蝫',
  '螆' => '螆',
  '䗗' => '䗗',
  '蟡' => '蟡',
  '蠁' => '蠁',
  '䗹' => '䗹',
  '衠' => '衠',
  '衣' => '衣',
  '𧙧' => '𧙧',
  '裗' => '裗',
  '裞' => '裞',
  '䘵' => '䘵',
  '裺' => '裺',
  '㒻' => '㒻',
  '𧢮' => '𧢮',
  '𧥦' => '𧥦',
  '䚾' => '䚾',
  '䛇' => '䛇',
  '誠' => '誠',
  '諭' => '諭',
  '變' => '變',
  '豕' => '豕',
  '𧲨' => '𧲨',
  '貫' => '貫',
  '賁' => '賁',
  '贛' => '贛',
  '起' => '起',
  '𧼯' => '𧼯',
  '𠠄' => '𠠄',
  '跋' => '跋',
  '趼' => '趼',
  '跰' => '跰',
  '𠣞' => '𠣞',
  '軔' => '軔',
  '輸' => '輸',
  '𨗒' => '𨗒',
  '𨗭' => '𨗭',
  '邔' => '邔',
  '郱' => '郱',
  '鄑' => '鄑',
  '𨜮' => '𨜮',
  '鄛' => '鄛',
  '鈸' => '鈸',
  '鋗' => '鋗',
  '鋘' => '鋘',
  '鉼' => '鉼',
  '鏹' => '鏹',
  '鐕' => '鐕',
  '𨯺' => '𨯺',
  '開' => '開',
  '䦕' => '䦕',
  '閷' => '閷',
  '𨵷' => '𨵷',
  '䧦' => '䧦',
  '雃' => '雃',
  '嶲' => '嶲',
  '霣' => '霣',
  '𩅅' => '𩅅',
  '𩈚' => '𩈚',
  '䩮' => '䩮',
  '䩶' => '䩶',
  '韠' => '韠',
  '𩐊' => '𩐊',
  '䪲' => '䪲',
  '𩒖' => '𩒖',
  '頋' => '頋',
  '頋' => '頋',
  '頩' => '頩',
  '𩖶' => '𩖶',
  '飢' => '飢',
  '䬳' => '䬳',
  '餩' => '餩',
  '馧' => '馧',
  '駂' => '駂',
  '駾' => '駾',
  '䯎' => '䯎',
  '𩬰' => '𩬰',
  '鬒' => '鬒',
  '鱀' => '鱀',
  '鳽' => '鳽',
  '䳎' => '䳎',
  '䳭' => '䳭',
  '鵧' => '鵧',
  '𪃎' => '𪃎',
  '䳸' => '䳸',
  '𪄅' => '𪄅',
  '𪈎' => '𪈎',
  '𪊑' => '𪊑',
  '麻' => '麻',
  '䵖' => '䵖',
  '黹' => '黹',
  '黾' => '黾',
  '鼅' => '鼅',
  '鼏' => '鼏',
  '鼖' => '鼖',
  '鼻' => '鼻',
  '𪘀' => '𪘀',
);
PKϤ$Z���D5D5=polyfill-intl-normalizer/Resources/unidata/combiningClass.phpnu�[���<?php

return array (
  '̀' => 230,
  '́' => 230,
  '̂' => 230,
  '̃' => 230,
  '̄' => 230,
  '̅' => 230,
  '̆' => 230,
  '̇' => 230,
  '̈' => 230,
  '̉' => 230,
  '̊' => 230,
  '̋' => 230,
  '̌' => 230,
  '̍' => 230,
  '̎' => 230,
  '̏' => 230,
  '̐' => 230,
  '̑' => 230,
  '̒' => 230,
  '̓' => 230,
  '̔' => 230,
  '̕' => 232,
  '̖' => 220,
  '̗' => 220,
  '̘' => 220,
  '̙' => 220,
  '̚' => 232,
  '̛' => 216,
  '̜' => 220,
  '̝' => 220,
  '̞' => 220,
  '̟' => 220,
  '̠' => 220,
  '̡' => 202,
  '̢' => 202,
  '̣' => 220,
  '̤' => 220,
  '̥' => 220,
  '̦' => 220,
  '̧' => 202,
  '̨' => 202,
  '̩' => 220,
  '̪' => 220,
  '̫' => 220,
  '̬' => 220,
  '̭' => 220,
  '̮' => 220,
  '̯' => 220,
  '̰' => 220,
  '̱' => 220,
  '̲' => 220,
  '̳' => 220,
  '̴' => 1,
  '̵' => 1,
  '̶' => 1,
  '̷' => 1,
  '̸' => 1,
  '̹' => 220,
  '̺' => 220,
  '̻' => 220,
  '̼' => 220,
  '̽' => 230,
  '̾' => 230,
  '̿' => 230,
  '̀' => 230,
  '́' => 230,
  '͂' => 230,
  '̓' => 230,
  '̈́' => 230,
  'ͅ' => 240,
  '͆' => 230,
  '͇' => 220,
  '͈' => 220,
  '͉' => 220,
  '͊' => 230,
  '͋' => 230,
  '͌' => 230,
  '͍' => 220,
  '͎' => 220,
  '͐' => 230,
  '͑' => 230,
  '͒' => 230,
  '͓' => 220,
  '͔' => 220,
  '͕' => 220,
  '͖' => 220,
  '͗' => 230,
  '͘' => 232,
  '͙' => 220,
  '͚' => 220,
  '͛' => 230,
  '͜' => 233,
  '͝' => 234,
  '͞' => 234,
  '͟' => 233,
  '͠' => 234,
  '͡' => 234,
  '͢' => 233,
  'ͣ' => 230,
  'ͤ' => 230,
  'ͥ' => 230,
  'ͦ' => 230,
  'ͧ' => 230,
  'ͨ' => 230,
  'ͩ' => 230,
  'ͪ' => 230,
  'ͫ' => 230,
  'ͬ' => 230,
  'ͭ' => 230,
  'ͮ' => 230,
  'ͯ' => 230,
  '҃' => 230,
  '҄' => 230,
  '҅' => 230,
  '҆' => 230,
  '҇' => 230,
  '֑' => 220,
  '֒' => 230,
  '֓' => 230,
  '֔' => 230,
  '֕' => 230,
  '֖' => 220,
  '֗' => 230,
  '֘' => 230,
  '֙' => 230,
  '֚' => 222,
  '֛' => 220,
  '֜' => 230,
  '֝' => 230,
  '֞' => 230,
  '֟' => 230,
  '֠' => 230,
  '֡' => 230,
  '֢' => 220,
  '֣' => 220,
  '֤' => 220,
  '֥' => 220,
  '֦' => 220,
  '֧' => 220,
  '֨' => 230,
  '֩' => 230,
  '֪' => 220,
  '֫' => 230,
  '֬' => 230,
  '֭' => 222,
  '֮' => 228,
  '֯' => 230,
  'ְ' => 10,
  'ֱ' => 11,
  'ֲ' => 12,
  'ֳ' => 13,
  'ִ' => 14,
  'ֵ' => 15,
  'ֶ' => 16,
  'ַ' => 17,
  'ָ' => 18,
  'ֹ' => 19,
  'ֺ' => 19,
  'ֻ' => 20,
  'ּ' => 21,
  'ֽ' => 22,
  'ֿ' => 23,
  'ׁ' => 24,
  'ׂ' => 25,
  'ׄ' => 230,
  'ׅ' => 220,
  'ׇ' => 18,
  'ؐ' => 230,
  'ؑ' => 230,
  'ؒ' => 230,
  'ؓ' => 230,
  'ؔ' => 230,
  'ؕ' => 230,
  'ؖ' => 230,
  'ؗ' => 230,
  'ؘ' => 30,
  'ؙ' => 31,
  'ؚ' => 32,
  'ً' => 27,
  'ٌ' => 28,
  'ٍ' => 29,
  'َ' => 30,
  'ُ' => 31,
  'ِ' => 32,
  'ّ' => 33,
  'ْ' => 34,
  'ٓ' => 230,
  'ٔ' => 230,
  'ٕ' => 220,
  'ٖ' => 220,
  'ٗ' => 230,
  '٘' => 230,
  'ٙ' => 230,
  'ٚ' => 230,
  'ٛ' => 230,
  'ٜ' => 220,
  'ٝ' => 230,
  'ٞ' => 230,
  'ٟ' => 220,
  'ٰ' => 35,
  'ۖ' => 230,
  'ۗ' => 230,
  'ۘ' => 230,
  'ۙ' => 230,
  'ۚ' => 230,
  'ۛ' => 230,
  'ۜ' => 230,
  '۟' => 230,
  '۠' => 230,
  'ۡ' => 230,
  'ۢ' => 230,
  'ۣ' => 220,
  'ۤ' => 230,
  'ۧ' => 230,
  'ۨ' => 230,
  '۪' => 220,
  '۫' => 230,
  '۬' => 230,
  'ۭ' => 220,
  'ܑ' => 36,
  'ܰ' => 230,
  'ܱ' => 220,
  'ܲ' => 230,
  'ܳ' => 230,
  'ܴ' => 220,
  'ܵ' => 230,
  'ܶ' => 230,
  'ܷ' => 220,
  'ܸ' => 220,
  'ܹ' => 220,
  'ܺ' => 230,
  'ܻ' => 220,
  'ܼ' => 220,
  'ܽ' => 230,
  'ܾ' => 220,
  'ܿ' => 230,
  '݀' => 230,
  '݁' => 230,
  '݂' => 220,
  '݃' => 230,
  '݄' => 220,
  '݅' => 230,
  '݆' => 220,
  '݇' => 230,
  '݈' => 220,
  '݉' => 230,
  '݊' => 230,
  '߫' => 230,
  '߬' => 230,
  '߭' => 230,
  '߮' => 230,
  '߯' => 230,
  '߰' => 230,
  '߱' => 230,
  '߲' => 220,
  '߳' => 230,
  '߽' => 220,
  'ࠖ' => 230,
  'ࠗ' => 230,
  '࠘' => 230,
  '࠙' => 230,
  'ࠛ' => 230,
  'ࠜ' => 230,
  'ࠝ' => 230,
  'ࠞ' => 230,
  'ࠟ' => 230,
  'ࠠ' => 230,
  'ࠡ' => 230,
  'ࠢ' => 230,
  'ࠣ' => 230,
  'ࠥ' => 230,
  'ࠦ' => 230,
  'ࠧ' => 230,
  'ࠩ' => 230,
  'ࠪ' => 230,
  'ࠫ' => 230,
  'ࠬ' => 230,
  '࠭' => 230,
  '࡙' => 220,
  '࡚' => 220,
  '࡛' => 220,
  '࣓' => 220,
  'ࣔ' => 230,
  'ࣕ' => 230,
  'ࣖ' => 230,
  'ࣗ' => 230,
  'ࣘ' => 230,
  'ࣙ' => 230,
  'ࣚ' => 230,
  'ࣛ' => 230,
  'ࣜ' => 230,
  'ࣝ' => 230,
  'ࣞ' => 230,
  'ࣟ' => 230,
  '࣠' => 230,
  '࣡' => 230,
  'ࣣ' => 220,
  'ࣤ' => 230,
  'ࣥ' => 230,
  'ࣦ' => 220,
  'ࣧ' => 230,
  'ࣨ' => 230,
  'ࣩ' => 220,
  '࣪' => 230,
  '࣫' => 230,
  '࣬' => 230,
  '࣭' => 220,
  '࣮' => 220,
  '࣯' => 220,
  'ࣰ' => 27,
  'ࣱ' => 28,
  'ࣲ' => 29,
  'ࣳ' => 230,
  'ࣴ' => 230,
  'ࣵ' => 230,
  'ࣶ' => 220,
  'ࣷ' => 230,
  'ࣸ' => 230,
  'ࣹ' => 220,
  'ࣺ' => 220,
  'ࣻ' => 230,
  'ࣼ' => 230,
  'ࣽ' => 230,
  'ࣾ' => 230,
  'ࣿ' => 230,
  '़' => 7,
  '्' => 9,
  '॑' => 230,
  '॒' => 220,
  '॓' => 230,
  '॔' => 230,
  '়' => 7,
  '্' => 9,
  '৾' => 230,
  '਼' => 7,
  '੍' => 9,
  '઼' => 7,
  '્' => 9,
  '଼' => 7,
  '୍' => 9,
  '்' => 9,
  '్' => 9,
  'ౕ' => 84,
  'ౖ' => 91,
  '಼' => 7,
  '್' => 9,
  '഻' => 9,
  '഼' => 9,
  '്' => 9,
  '්' => 9,
  'ุ' => 103,
  'ู' => 103,
  'ฺ' => 9,
  '่' => 107,
  '้' => 107,
  '๊' => 107,
  '๋' => 107,
  'ຸ' => 118,
  'ູ' => 118,
  '຺' => 9,
  '່' => 122,
  '້' => 122,
  '໊' => 122,
  '໋' => 122,
  '༘' => 220,
  '༙' => 220,
  '༵' => 220,
  '༷' => 220,
  '༹' => 216,
  'ཱ' => 129,
  'ི' => 130,
  'ུ' => 132,
  'ེ' => 130,
  'ཻ' => 130,
  'ོ' => 130,
  'ཽ' => 130,
  'ྀ' => 130,
  'ྂ' => 230,
  'ྃ' => 230,
  '྄' => 9,
  '྆' => 230,
  '྇' => 230,
  '࿆' => 220,
  '့' => 7,
  '္' => 9,
  '်' => 9,
  'ႍ' => 220,
  '፝' => 230,
  '፞' => 230,
  '፟' => 230,
  '᜔' => 9,
  '᜴' => 9,
  '្' => 9,
  '៝' => 230,
  'ᢩ' => 228,
  '᤹' => 222,
  '᤺' => 230,
  '᤻' => 220,
  'ᨗ' => 230,
  'ᨘ' => 220,
  '᩠' => 9,
  '᩵' => 230,
  '᩶' => 230,
  '᩷' => 230,
  '᩸' => 230,
  '᩹' => 230,
  '᩺' => 230,
  '᩻' => 230,
  '᩼' => 230,
  '᩿' => 220,
  '᪰' => 230,
  '᪱' => 230,
  '᪲' => 230,
  '᪳' => 230,
  '᪴' => 230,
  '᪵' => 220,
  '᪶' => 220,
  '᪷' => 220,
  '᪸' => 220,
  '᪹' => 220,
  '᪺' => 220,
  '᪻' => 230,
  '᪼' => 230,
  '᪽' => 220,
  'ᪿ' => 220,
  'ᫀ' => 220,
  '᬴' => 7,
  '᭄' => 9,
  '᭫' => 230,
  '᭬' => 220,
  '᭭' => 230,
  '᭮' => 230,
  '᭯' => 230,
  '᭰' => 230,
  '᭱' => 230,
  '᭲' => 230,
  '᭳' => 230,
  '᮪' => 9,
  '᮫' => 9,
  '᯦' => 7,
  '᯲' => 9,
  '᯳' => 9,
  '᰷' => 7,
  '᳐' => 230,
  '᳑' => 230,
  '᳒' => 230,
  '᳔' => 1,
  '᳕' => 220,
  '᳖' => 220,
  '᳗' => 220,
  '᳘' => 220,
  '᳙' => 220,
  '᳚' => 230,
  '᳛' => 230,
  '᳜' => 220,
  '᳝' => 220,
  '᳞' => 220,
  '᳟' => 220,
  '᳠' => 230,
  '᳢' => 1,
  '᳣' => 1,
  '᳤' => 1,
  '᳥' => 1,
  '᳦' => 1,
  '᳧' => 1,
  '᳨' => 1,
  '᳭' => 220,
  '᳴' => 230,
  '᳸' => 230,
  '᳹' => 230,
  '᷀' => 230,
  '᷁' => 230,
  '᷂' => 220,
  '᷃' => 230,
  '᷄' => 230,
  '᷅' => 230,
  '᷆' => 230,
  '᷇' => 230,
  '᷈' => 230,
  '᷉' => 230,
  '᷊' => 220,
  '᷋' => 230,
  '᷌' => 230,
  '᷍' => 234,
  '᷎' => 214,
  '᷏' => 220,
  '᷐' => 202,
  '᷑' => 230,
  '᷒' => 230,
  'ᷓ' => 230,
  'ᷔ' => 230,
  'ᷕ' => 230,
  'ᷖ' => 230,
  'ᷗ' => 230,
  'ᷘ' => 230,
  'ᷙ' => 230,
  'ᷚ' => 230,
  'ᷛ' => 230,
  'ᷜ' => 230,
  'ᷝ' => 230,
  'ᷞ' => 230,
  'ᷟ' => 230,
  'ᷠ' => 230,
  'ᷡ' => 230,
  'ᷢ' => 230,
  'ᷣ' => 230,
  'ᷤ' => 230,
  'ᷥ' => 230,
  'ᷦ' => 230,
  'ᷧ' => 230,
  'ᷨ' => 230,
  'ᷩ' => 230,
  'ᷪ' => 230,
  'ᷫ' => 230,
  'ᷬ' => 230,
  'ᷭ' => 230,
  'ᷮ' => 230,
  'ᷯ' => 230,
  'ᷰ' => 230,
  'ᷱ' => 230,
  'ᷲ' => 230,
  'ᷳ' => 230,
  'ᷴ' => 230,
  '᷵' => 230,
  '᷶' => 232,
  '᷷' => 228,
  '᷸' => 228,
  '᷹' => 220,
  '᷻' => 230,
  '᷼' => 233,
  '᷽' => 220,
  '᷾' => 230,
  '᷿' => 220,
  '⃐' => 230,
  '⃑' => 230,
  '⃒' => 1,
  '⃓' => 1,
  '⃔' => 230,
  '⃕' => 230,
  '⃖' => 230,
  '⃗' => 230,
  '⃘' => 1,
  '⃙' => 1,
  '⃚' => 1,
  '⃛' => 230,
  '⃜' => 230,
  '⃡' => 230,
  '⃥' => 1,
  '⃦' => 1,
  '⃧' => 230,
  '⃨' => 220,
  '⃩' => 230,
  '⃪' => 1,
  '⃫' => 1,
  '⃬' => 220,
  '⃭' => 220,
  '⃮' => 220,
  '⃯' => 220,
  '⃰' => 230,
  '⳯' => 230,
  '⳰' => 230,
  '⳱' => 230,
  '⵿' => 9,
  'ⷠ' => 230,
  'ⷡ' => 230,
  'ⷢ' => 230,
  'ⷣ' => 230,
  'ⷤ' => 230,
  'ⷥ' => 230,
  'ⷦ' => 230,
  'ⷧ' => 230,
  'ⷨ' => 230,
  'ⷩ' => 230,
  'ⷪ' => 230,
  'ⷫ' => 230,
  'ⷬ' => 230,
  'ⷭ' => 230,
  'ⷮ' => 230,
  'ⷯ' => 230,
  'ⷰ' => 230,
  'ⷱ' => 230,
  'ⷲ' => 230,
  'ⷳ' => 230,
  'ⷴ' => 230,
  'ⷵ' => 230,
  'ⷶ' => 230,
  'ⷷ' => 230,
  'ⷸ' => 230,
  'ⷹ' => 230,
  'ⷺ' => 230,
  'ⷻ' => 230,
  'ⷼ' => 230,
  'ⷽ' => 230,
  'ⷾ' => 230,
  'ⷿ' => 230,
  '〪' => 218,
  '〫' => 228,
  '〬' => 232,
  '〭' => 222,
  '〮' => 224,
  '〯' => 224,
  '゙' => 8,
  '゚' => 8,
  '꙯' => 230,
  'ꙴ' => 230,
  'ꙵ' => 230,
  'ꙶ' => 230,
  'ꙷ' => 230,
  'ꙸ' => 230,
  'ꙹ' => 230,
  'ꙺ' => 230,
  'ꙻ' => 230,
  '꙼' => 230,
  '꙽' => 230,
  'ꚞ' => 230,
  'ꚟ' => 230,
  '꛰' => 230,
  '꛱' => 230,
  '꠆' => 9,
  '꠬' => 9,
  '꣄' => 9,
  '꣠' => 230,
  '꣡' => 230,
  '꣢' => 230,
  '꣣' => 230,
  '꣤' => 230,
  '꣥' => 230,
  '꣦' => 230,
  '꣧' => 230,
  '꣨' => 230,
  '꣩' => 230,
  '꣪' => 230,
  '꣫' => 230,
  '꣬' => 230,
  '꣭' => 230,
  '꣮' => 230,
  '꣯' => 230,
  '꣰' => 230,
  '꣱' => 230,
  '꤫' => 220,
  '꤬' => 220,
  '꤭' => 220,
  '꥓' => 9,
  '꦳' => 7,
  '꧀' => 9,
  'ꪰ' => 230,
  'ꪲ' => 230,
  'ꪳ' => 230,
  'ꪴ' => 220,
  'ꪷ' => 230,
  'ꪸ' => 230,
  'ꪾ' => 230,
  '꪿' => 230,
  '꫁' => 230,
  '꫶' => 9,
  '꯭' => 9,
  'ﬞ' => 26,
  '︠' => 230,
  '︡' => 230,
  '︢' => 230,
  '︣' => 230,
  '︤' => 230,
  '︥' => 230,
  '︦' => 230,
  '︧' => 220,
  '︨' => 220,
  '︩' => 220,
  '︪' => 220,
  '︫' => 220,
  '︬' => 220,
  '︭' => 220,
  '︮' => 230,
  '︯' => 230,
  '𐇽' => 220,
  '𐋠' => 220,
  '𐍶' => 230,
  '𐍷' => 230,
  '𐍸' => 230,
  '𐍹' => 230,
  '𐍺' => 230,
  '𐨍' => 220,
  '𐨏' => 230,
  '𐨸' => 230,
  '𐨹' => 1,
  '𐨺' => 220,
  '𐨿' => 9,
  '𐫥' => 230,
  '𐫦' => 220,
  '𐴤' => 230,
  '𐴥' => 230,
  '𐴦' => 230,
  '𐴧' => 230,
  '𐺫' => 230,
  '𐺬' => 230,
  '𐽆' => 220,
  '𐽇' => 220,
  '𐽈' => 230,
  '𐽉' => 230,
  '𐽊' => 230,
  '𐽋' => 220,
  '𐽌' => 230,
  '𐽍' => 220,
  '𐽎' => 220,
  '𐽏' => 220,
  '𐽐' => 220,
  '𑁆' => 9,
  '𑁿' => 9,
  '𑂹' => 9,
  '𑂺' => 7,
  '𑄀' => 230,
  '𑄁' => 230,
  '𑄂' => 230,
  '𑄳' => 9,
  '𑄴' => 9,
  '𑅳' => 7,
  '𑇀' => 9,
  '𑇊' => 7,
  '𑈵' => 9,
  '𑈶' => 7,
  '𑋩' => 7,
  '𑋪' => 9,
  '𑌻' => 7,
  '𑌼' => 7,
  '𑍍' => 9,
  '𑍦' => 230,
  '𑍧' => 230,
  '𑍨' => 230,
  '𑍩' => 230,
  '𑍪' => 230,
  '𑍫' => 230,
  '𑍬' => 230,
  '𑍰' => 230,
  '𑍱' => 230,
  '𑍲' => 230,
  '𑍳' => 230,
  '𑍴' => 230,
  '𑑂' => 9,
  '𑑆' => 7,
  '𑑞' => 230,
  '𑓂' => 9,
  '𑓃' => 7,
  '𑖿' => 9,
  '𑗀' => 7,
  '𑘿' => 9,
  '𑚶' => 9,
  '𑚷' => 7,
  '𑜫' => 9,
  '𑠹' => 9,
  '𑠺' => 7,
  '𑤽' => 9,
  '𑤾' => 9,
  '𑥃' => 7,
  '𑧠' => 9,
  '𑨴' => 9,
  '𑩇' => 9,
  '𑪙' => 9,
  '𑰿' => 9,
  '𑵂' => 7,
  '𑵄' => 9,
  '𑵅' => 9,
  '𑶗' => 9,
  '𖫰' => 1,
  '𖫱' => 1,
  '𖫲' => 1,
  '𖫳' => 1,
  '𖫴' => 1,
  '𖬰' => 230,
  '𖬱' => 230,
  '𖬲' => 230,
  '𖬳' => 230,
  '𖬴' => 230,
  '𖬵' => 230,
  '𖬶' => 230,
  '𖿰' => 6,
  '𖿱' => 6,
  '𛲞' => 1,
  '𝅥' => 216,
  '𝅦' => 216,
  '𝅧' => 1,
  '𝅨' => 1,
  '𝅩' => 1,
  '𝅭' => 226,
  '𝅮' => 216,
  '𝅯' => 216,
  '𝅰' => 216,
  '𝅱' => 216,
  '𝅲' => 216,
  '𝅻' => 220,
  '𝅼' => 220,
  '𝅽' => 220,
  '𝅾' => 220,
  '𝅿' => 220,
  '𝆀' => 220,
  '𝆁' => 220,
  '𝆂' => 220,
  '𝆅' => 230,
  '𝆆' => 230,
  '𝆇' => 230,
  '𝆈' => 230,
  '𝆉' => 230,
  '𝆊' => 220,
  '𝆋' => 220,
  '𝆪' => 230,
  '𝆫' => 230,
  '𝆬' => 230,
  '𝆭' => 230,
  '𝉂' => 230,
  '𝉃' => 230,
  '𝉄' => 230,
  '𞀀' => 230,
  '𞀁' => 230,
  '𞀂' => 230,
  '𞀃' => 230,
  '𞀄' => 230,
  '𞀅' => 230,
  '𞀆' => 230,
  '𞀈' => 230,
  '𞀉' => 230,
  '𞀊' => 230,
  '𞀋' => 230,
  '𞀌' => 230,
  '𞀍' => 230,
  '𞀎' => 230,
  '𞀏' => 230,
  '𞀐' => 230,
  '𞀑' => 230,
  '𞀒' => 230,
  '𞀓' => 230,
  '𞀔' => 230,
  '𞀕' => 230,
  '𞀖' => 230,
  '𞀗' => 230,
  '𞀘' => 230,
  '𞀛' => 230,
  '𞀜' => 230,
  '𞀝' => 230,
  '𞀞' => 230,
  '𞀟' => 230,
  '𞀠' => 230,
  '𞀡' => 230,
  '𞀣' => 230,
  '𞀤' => 230,
  '𞀦' => 230,
  '𞀧' => 230,
  '𞀨' => 230,
  '𞀩' => 230,
  '𞀪' => 230,
  '𞄰' => 230,
  '𞄱' => 230,
  '𞄲' => 230,
  '𞄳' => 230,
  '𞄴' => 230,
  '𞄵' => 230,
  '𞄶' => 230,
  '𞋬' => 230,
  '𞋭' => 230,
  '𞋮' => 230,
  '𞋯' => 230,
  '𞣐' => 220,
  '𞣑' => 220,
  '𞣒' => 220,
  '𞣓' => 220,
  '𞣔' => 220,
  '𞣕' => 220,
  '𞣖' => 220,
  '𞥄' => 230,
  '𞥅' => 230,
  '𞥆' => 230,
  '𞥇' => 230,
  '𞥈' => 230,
  '𞥉' => 230,
  '𞥊' => 7,
);
PKϤ$Z�Kwii&polyfill-intl-normalizer/bootstrap.phpnu�[���<?php

/*
 * This file is part of the Symfony package.
 *
 * (c) Fabien Potencier <fabien@symfony.com>
 *
 * For the full copyright and license information, please view the LICENSE
 * file that was distributed with this source code.
 */

use Symfony\Polyfill\Intl\Normalizer as p;

if (!function_exists('normalizer_is_normalized')) {
    function normalizer_is_normalized($s, $form = p\Normalizer::NFC) { return p\Normalizer::isNormalized($s, $form); }
}
if (!function_exists('normalizer_normalize')) {
    function normalizer_normalize($s, $form = p\Normalizer::NFC) { return p\Normalizer::normalize($s, $form); }
}
PKϤ$Z�\�)) polyfill-intl-normalizer/LICENSEnu�[���Copyright (c) 2015-2019 Fabien Potencier

Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is furnished
to do so, subject to the following conditions:

The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.

THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
THE SOFTWARE.
PKϤ$Z�e�"�$�$'polyfill-intl-normalizer/Normalizer.phpnu�[���<?php

/*
 * This file is part of the Symfony package.
 *
 * (c) Fabien Potencier <fabien@symfony.com>
 *
 * For the full copyright and license information, please view the LICENSE
 * file that was distributed with this source code.
 */

namespace Symfony\Polyfill\Intl\Normalizer;

/**
 * Normalizer is a PHP fallback implementation of the Normalizer class provided by the intl extension.
 *
 * It has been validated with Unicode 6.3 Normalization Conformance Test.
 * See http://www.unicode.org/reports/tr15/ for detailed info about Unicode normalizations.
 *
 * @author Nicolas Grekas <p@tchwork.com>
 *
 * @internal
 */
class Normalizer
{
    const FORM_D = \Normalizer::FORM_D;
    const FORM_KD = \Normalizer::FORM_KD;
    const FORM_C = \Normalizer::FORM_C;
    const FORM_KC = \Normalizer::FORM_KC;
    const NFD = \Normalizer::NFD;
    const NFKD = \Normalizer::NFKD;
    const NFC = \Normalizer::NFC;
    const NFKC = \Normalizer::NFKC;

    private static $C;
    private static $D;
    private static $KD;
    private static $cC;
    private static $ulenMask = array("\xC0" => 2, "\xD0" => 2, "\xE0" => 3, "\xF0" => 4);
    private static $ASCII = "\x20\x65\x69\x61\x73\x6E\x74\x72\x6F\x6C\x75\x64\x5D\x5B\x63\x6D\x70\x27\x0A\x67\x7C\x68\x76\x2E\x66\x62\x2C\x3A\x3D\x2D\x71\x31\x30\x43\x32\x2A\x79\x78\x29\x28\x4C\x39\x41\x53\x2F\x50\x22\x45\x6A\x4D\x49\x6B\x33\x3E\x35\x54\x3C\x44\x34\x7D\x42\x7B\x38\x46\x77\x52\x36\x37\x55\x47\x4E\x3B\x4A\x7A\x56\x23\x48\x4F\x57\x5F\x26\x21\x4B\x3F\x58\x51\x25\x59\x5C\x09\x5A\x2B\x7E\x5E\x24\x40\x60\x7F\x00\x01\x02\x03\x04\x05\x06\x07\x08\x0B\x0C\x0D\x0E\x0F\x10\x11\x12\x13\x14\x15\x16\x17\x18\x19\x1A\x1B\x1C\x1D\x1E\x1F";

    public static function isNormalized($s, $form = self::NFC)
    {
        if (!\in_array($form, array(self::NFD, self::NFKD, self::NFC, self::NFKC))) {
            return false;
        }
        $s = (string) $s;
        if (!isset($s[strspn($s, self::$ASCII)])) {
            return true;
        }
        if (self::NFC == $form && preg_match('//u', $s) && !preg_match('/[^\x00-\x{2FF}]/u', $s)) {
            return true;
        }

        return self::normalize($s, $form) === $s;
    }

    public static function normalize($s, $form = self::NFC)
    {
        $s = (string) $s;
        if (!preg_match('//u', $s)) {
            return false;
        }

        switch ($form) {
            case self::NFC: $C = true; $K = false; break;
            case self::NFD: $C = false; $K = false; break;
            case self::NFKC: $C = true; $K = true; break;
            case self::NFKD: $C = false; $K = true; break;
            default:
                if (\defined('Normalizer::NONE') && \Normalizer::NONE == $form) {
                    return $s;
                }

                return false;
        }

        if ('' === $s) {
            return '';
        }

        if ($K && null === self::$KD) {
            self::$KD = self::getData('compatibilityDecomposition');
        }

        if (null === self::$D) {
            self::$D = self::getData('canonicalDecomposition');
            self::$cC = self::getData('combiningClass');
        }

        if (null !== $mbEncoding = (2 /* MB_OVERLOAD_STRING */ & (int) ini_get('mbstring.func_overload')) ? mb_internal_encoding() : null) {
            mb_internal_encoding('8bit');
        }

        $r = self::decompose($s, $K);

        if ($C) {
            if (null === self::$C) {
                self::$C = self::getData('canonicalComposition');
            }

            $r = self::recompose($r);
        }
        if (null !== $mbEncoding) {
            mb_internal_encoding($mbEncoding);
        }

        return $r;
    }

    private static function recompose($s)
    {
        $ASCII = self::$ASCII;
        $compMap = self::$C;
        $combClass = self::$cC;
        $ulenMask = self::$ulenMask;

        $result = $tail = '';

        $i = $s[0] < "\x80" ? 1 : $ulenMask[$s[0] & "\xF0"];
        $len = \strlen($s);

        $lastUchr = substr($s, 0, $i);
        $lastUcls = isset($combClass[$lastUchr]) ? 256 : 0;

        while ($i < $len) {
            if ($s[$i] < "\x80") {
                // ASCII chars

                if ($tail) {
                    $lastUchr .= $tail;
                    $tail = '';
                }

                if ($j = strspn($s, $ASCII, $i + 1)) {
                    $lastUchr .= substr($s, $i, $j);
                    $i += $j;
                }

                $result .= $lastUchr;
                $lastUchr = $s[$i];
                $lastUcls = 0;
                ++$i;
                continue;
            }

            $ulen = $ulenMask[$s[$i] & "\xF0"];
            $uchr = substr($s, $i, $ulen);

            if ($lastUchr < "\xE1\x84\x80" || "\xE1\x84\x92" < $lastUchr
                || $uchr < "\xE1\x85\xA1" || "\xE1\x85\xB5" < $uchr
                || $lastUcls) {
                // Table lookup and combining chars composition

                $ucls = isset($combClass[$uchr]) ? $combClass[$uchr] : 0;

                if (isset($compMap[$lastUchr.$uchr]) && (!$lastUcls || $lastUcls < $ucls)) {
                    $lastUchr = $compMap[$lastUchr.$uchr];
                } elseif ($lastUcls = $ucls) {
                    $tail .= $uchr;
                } else {
                    if ($tail) {
                        $lastUchr .= $tail;
                        $tail = '';
                    }

                    $result .= $lastUchr;
                    $lastUchr = $uchr;
                }
            } else {
                // Hangul chars

                $L = \ord($lastUchr[2]) - 0x80;
                $V = \ord($uchr[2]) - 0xA1;
                $T = 0;

                $uchr = substr($s, $i + $ulen, 3);

                if ("\xE1\x86\xA7" <= $uchr && $uchr <= "\xE1\x87\x82") {
                    $T = \ord($uchr[2]) - 0xA7;
                    0 > $T && $T += 0x40;
                    $ulen += 3;
                }

                $L = 0xAC00 + ($L * 21 + $V) * 28 + $T;
                $lastUchr = \chr(0xE0 | $L >> 12).\chr(0x80 | $L >> 6 & 0x3F).\chr(0x80 | $L & 0x3F);
            }

            $i += $ulen;
        }

        return $result.$lastUchr.$tail;
    }

    private static function decompose($s, $c)
    {
        $result = '';

        $ASCII = self::$ASCII;
        $decompMap = self::$D;
        $combClass = self::$cC;
        $ulenMask = self::$ulenMask;
        if ($c) {
            $compatMap = self::$KD;
        }

        $c = array();
        $i = 0;
        $len = \strlen($s);

        while ($i < $len) {
            if ($s[$i] < "\x80") {
                // ASCII chars

                if ($c) {
                    ksort($c);
                    $result .= implode('', $c);
                    $c = array();
                }

                $j = 1 + strspn($s, $ASCII, $i + 1);
                $result .= substr($s, $i, $j);
                $i += $j;
                continue;
            }

            $ulen = $ulenMask[$s[$i] & "\xF0"];
            $uchr = substr($s, $i, $ulen);
            $i += $ulen;

            if ($uchr < "\xEA\xB0\x80" || "\xED\x9E\xA3" < $uchr) {
                // Table lookup

                if ($uchr !== $j = isset($compatMap[$uchr]) ? $compatMap[$uchr] : (isset($decompMap[$uchr]) ? $decompMap[$uchr] : $uchr)) {
                    $uchr = $j;

                    $j = \strlen($uchr);
                    $ulen = $uchr[0] < "\x80" ? 1 : $ulenMask[$uchr[0] & "\xF0"];

                    if ($ulen != $j) {
                        // Put trailing chars in $s

                        $j -= $ulen;
                        $i -= $j;

                        if (0 > $i) {
                            $s = str_repeat(' ', -$i).$s;
                            $len -= $i;
                            $i = 0;
                        }

                        while ($j--) {
                            $s[$i + $j] = $uchr[$ulen + $j];
                        }

                        $uchr = substr($uchr, 0, $ulen);
                    }
                }
                if (isset($combClass[$uchr])) {
                    // Combining chars, for sorting

                    if (!isset($c[$combClass[$uchr]])) {
                        $c[$combClass[$uchr]] = '';
                    }
                    $c[$combClass[$uchr]] .= $uchr;
                    continue;
                }
            } else {
                // Hangul chars

                $uchr = unpack('C*', $uchr);
                $j = (($uchr[1] - 224) << 12) + (($uchr[2] - 128) << 6) + $uchr[3] - 0xAC80;

                $uchr = "\xE1\x84".\chr(0x80 + (int) ($j / 588))
                       ."\xE1\x85".\chr(0xA1 + (int) (($j % 588) / 28));

                if ($j %= 28) {
                    $uchr .= $j < 25
                        ? ("\xE1\x86".\chr(0xA7 + $j))
                        : ("\xE1\x87".\chr(0x67 + $j));
                }
            }
            if ($c) {
                ksort($c);
                $result .= implode('', $c);
                $c = array();
            }

            $result .= $uchr;
        }

        if ($c) {
            ksort($c);
            $result .= implode('', $c);
        }

        return $result;
    }

    private static function getData($file)
    {
        if (file_exists($file = __DIR__.'/Resources/unidata/'.$file.'.php')) {
            return require $file;
        }

        return false;
    }
}
PKϤ$Zj���``polyfill-ctype/README.mdnu�[���Symfony Polyfill / Ctype
========================

This component provides `ctype_*` functions to users who run php versions without the ctype extension.

More information can be found in the
[main Polyfill README](https://github.com/symfony/polyfill/blob/master/README.md).

License
=======

This library is released under the [MIT license](LICENSE).
PKϤ$Z\��}}polyfill-ctype/Ctype.phpnu�[���<?php

/*
 * This file is part of the Symfony package.
 *
 * (c) Fabien Potencier <fabien@symfony.com>
 *
 * For the full copyright and license information, please view the LICENSE
 * file that was distributed with this source code.
 */

namespace Symfony\Polyfill\Ctype;

/**
 * Ctype implementation through regex.
 *
 * @internal
 *
 * @author Gert de Pagter <BackEndTea@gmail.com>
 */
final class Ctype
{
    /**
     * Returns TRUE if every character in text is either a letter or a digit, FALSE otherwise.
     *
     * @see https://php.net/ctype-alnum
     *
     * @param string|int $text
     *
     * @return bool
     */
    public static function ctype_alnum($text)
    {
        $text = self::convert_int_to_char_for_ctype($text);

        return \is_string($text) && '' !== $text && !preg_match('/[^A-Za-z0-9]/', $text);
    }

    /**
     * Returns TRUE if every character in text is a letter, FALSE otherwise.
     *
     * @see https://php.net/ctype-alpha
     *
     * @param string|int $text
     *
     * @return bool
     */
    public static function ctype_alpha($text)
    {
        $text = self::convert_int_to_char_for_ctype($text);

        return \is_string($text) && '' !== $text && !preg_match('/[^A-Za-z]/', $text);
    }

    /**
     * Returns TRUE if every character in text is a control character from the current locale, FALSE otherwise.
     *
     * @see https://php.net/ctype-cntrl
     *
     * @param string|int $text
     *
     * @return bool
     */
    public static function ctype_cntrl($text)
    {
        $text = self::convert_int_to_char_for_ctype($text);

        return \is_string($text) && '' !== $text && !preg_match('/[^\x00-\x1f\x7f]/', $text);
    }

    /**
     * Returns TRUE if every character in the string text is a decimal digit, FALSE otherwise.
     *
     * @see https://php.net/ctype-digit
     *
     * @param string|int $text
     *
     * @return bool
     */
    public static function ctype_digit($text)
    {
        $text = self::convert_int_to_char_for_ctype($text);

        return \is_string($text) && '' !== $text && !preg_match('/[^0-9]/', $text);
    }

    /**
     * Returns TRUE if every character in text is printable and actually creates visible output (no white space), FALSE otherwise.
     *
     * @see https://php.net/ctype-graph
     *
     * @param string|int $text
     *
     * @return bool
     */
    public static function ctype_graph($text)
    {
        $text = self::convert_int_to_char_for_ctype($text);

        return \is_string($text) && '' !== $text && !preg_match('/[^!-~]/', $text);
    }

    /**
     * Returns TRUE if every character in text is a lowercase letter.
     *
     * @see https://php.net/ctype-lower
     *
     * @param string|int $text
     *
     * @return bool
     */
    public static function ctype_lower($text)
    {
        $text = self::convert_int_to_char_for_ctype($text);

        return \is_string($text) && '' !== $text && !preg_match('/[^a-z]/', $text);
    }

    /**
     * Returns TRUE if every character in text will actually create output (including blanks). Returns FALSE if text contains control characters or characters that do not have any output or control function at all.
     *
     * @see https://php.net/ctype-print
     *
     * @param string|int $text
     *
     * @return bool
     */
    public static function ctype_print($text)
    {
        $text = self::convert_int_to_char_for_ctype($text);

        return \is_string($text) && '' !== $text && !preg_match('/[^ -~]/', $text);
    }

    /**
     * Returns TRUE if every character in text is printable, but neither letter, digit or blank, FALSE otherwise.
     *
     * @see https://php.net/ctype-punct
     *
     * @param string|int $text
     *
     * @return bool
     */
    public static function ctype_punct($text)
    {
        $text = self::convert_int_to_char_for_ctype($text);

        return \is_string($text) && '' !== $text && !preg_match('/[^!-\/\:-@\[-`\{-~]/', $text);
    }

    /**
     * Returns TRUE if every character in text creates some sort of white space, FALSE otherwise. Besides the blank character this also includes tab, vertical tab, line feed, carriage return and form feed characters.
     *
     * @see https://php.net/ctype-space
     *
     * @param string|int $text
     *
     * @return bool
     */
    public static function ctype_space($text)
    {
        $text = self::convert_int_to_char_for_ctype($text);

        return \is_string($text) && '' !== $text && !preg_match('/[^\s]/', $text);
    }

    /**
     * Returns TRUE if every character in text is an uppercase letter.
     *
     * @see https://php.net/ctype-upper
     *
     * @param string|int $text
     *
     * @return bool
     */
    public static function ctype_upper($text)
    {
        $text = self::convert_int_to_char_for_ctype($text);

        return \is_string($text) && '' !== $text && !preg_match('/[^A-Z]/', $text);
    }

    /**
     * Returns TRUE if every character in text is a hexadecimal 'digit', that is a decimal digit or a character from [A-Fa-f] , FALSE otherwise.
     *
     * @see https://php.net/ctype-xdigit
     *
     * @param string|int $text
     *
     * @return bool
     */
    public static function ctype_xdigit($text)
    {
        $text = self::convert_int_to_char_for_ctype($text);

        return \is_string($text) && '' !== $text && !preg_match('/[^A-Fa-f0-9]/', $text);
    }

    /**
     * Converts integers to their char versions according to normal ctype behaviour, if needed.
     *
     * If an integer between -128 and 255 inclusive is provided,
     * it is interpreted as the ASCII value of a single character
     * (negative values have 256 added in order to allow characters in the Extended ASCII range).
     * Any other integer is interpreted as a string containing the decimal digits of the integer.
     *
     * @param string|int $int
     *
     * @return mixed
     */
    private static function convert_int_to_char_for_ctype($int)
    {
        if (!\is_int($int)) {
            return $int;
        }

        if ($int < -128 || $int > 255) {
            return (string) $int;
        }

        if ($int < 0) {
            $int += 256;
        }

        return \chr($int);
    }
}
PKϤ$Z-�����polyfill-ctype/bootstrap.phpnu�[���<?php

/*
 * This file is part of the Symfony package.
 *
 * (c) Fabien Potencier <fabien@symfony.com>
 *
 * For the full copyright and license information, please view the LICENSE
 * file that was distributed with this source code.
 */

use Symfony\Polyfill\Ctype as p;

if (!function_exists('ctype_alnum')) {
    function ctype_alnum($text) { return p\Ctype::ctype_alnum($text); }
}
if (!function_exists('ctype_alpha')) {
    function ctype_alpha($text) { return p\Ctype::ctype_alpha($text); }
}
if (!function_exists('ctype_cntrl')) {
    function ctype_cntrl($text) { return p\Ctype::ctype_cntrl($text); }
}
if (!function_exists('ctype_digit')) {
    function ctype_digit($text) { return p\Ctype::ctype_digit($text); }
}
if (!function_exists('ctype_graph')) {
    function ctype_graph($text) { return p\Ctype::ctype_graph($text); }
}
if (!function_exists('ctype_lower')) {
    function ctype_lower($text) { return p\Ctype::ctype_lower($text); }
}
if (!function_exists('ctype_print')) {
    function ctype_print($text) { return p\Ctype::ctype_print($text); }
}
if (!function_exists('ctype_punct')) {
    function ctype_punct($text) { return p\Ctype::ctype_punct($text); }
}
if (!function_exists('ctype_space')) {
    function ctype_space($text) { return p\Ctype::ctype_space($text); }
}
if (!function_exists('ctype_upper')) {
    function ctype_upper($text) { return p\Ctype::ctype_upper($text); }
}
if (!function_exists('ctype_xdigit')) {
    function ctype_xdigit($text) { return p\Ctype::ctype_xdigit($text); }
}
PKϤ$Z�`e0))polyfill-ctype/LICENSEnu�[���Copyright (c) 2018-2019 Fabien Potencier

Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is furnished
to do so, subject to the following conditions:

The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.

THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
THE SOFTWARE.
PKϤ$Z�6�GGpolyfill-php55/Php55.phpnu�[���<?php

/*
 * This file is part of the Symfony package.
 *
 * (c) Fabien Potencier <fabien@symfony.com>
 *
 * For the full copyright and license information, please view the LICENSE
 * file that was distributed with this source code.
 */

namespace Symfony\Polyfill\Php55;

/**
 * @internal
 */
final class Php55
{
    public static function boolval($val)
    {
        return (bool) $val;
    }

    public static function json_last_error_msg()
    {
        switch (json_last_error()) {
            case JSON_ERROR_NONE: return 'No error';
            case JSON_ERROR_DEPTH: return 'Maximum stack depth exceeded';
            case JSON_ERROR_STATE_MISMATCH: return 'State mismatch (invalid or malformed JSON)';
            case JSON_ERROR_CTRL_CHAR: return 'Control character error, possibly incorrectly encoded';
            case JSON_ERROR_SYNTAX: return 'Syntax error';
            case JSON_ERROR_UTF8: return 'Malformed UTF-8 characters, possibly incorrectly encoded';
            default: return 'Unknown error';
        }
    }

    /**
     * @author Sebastiaan Stok <s.stok@rollerscapes.net>
     */
    public static function hash_pbkdf2($algorithm, $password, $salt, $iterations, $length = 0, $rawOutput = false)
    {
        // Number of blocks needed to create the derived key
        $blocks = ceil($length / strlen(hash($algorithm, null, true)));
        $digest = '';

        for ($i = 1; $i <= $blocks; ++$i) {
            $ib = $block = hash_hmac($algorithm, $salt.pack('N', $i), $password, true);

            // Iterations
            for ($j = 1; $j < $iterations; ++$j) {
                $ib ^= ($block = hash_hmac($algorithm, $block, $password, true));
            }

            $digest .= $ib;
        }

        if (!$rawOutput) {
            $digest = bin2hex($digest);
        }

        return substr($digest, 0, $length);
    }
}
PKϤ$Z~`��#polyfill-php55/Php55ArrayColumn.phpnu�[���<?php

/*
 *   Copyright (c) 2013 Ben Ramsey <http://benramsey.com>
 *
 *   Permission is hereby granted, free of charge, to any person obtaining a
 *   copy of this software and associated documentation files (the "Software"),
 *   to deal in the Software without restriction, including without limitation
 *   the rights to use, copy, modify, merge, publish, distribute, sublicense,
 *   and/or sell copies of the Software, and to permit persons to whom the
 *   Software is furnished to do so, subject to the following conditions:
 *
 *   The above copyright notice and this permission notice shall be included in
 *   all copies or substantial portions of the Software.
 *
 *   THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
 *   IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
 *   FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
 *   AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
 *   LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
 *   FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
 *   DEALINGS IN THE SOFTWARE.
 */

namespace Symfony\Polyfill\Php55;

/**
 * @internal
 */
final class Php55ArrayColumn
{
    public static function array_column(array $input, $columnKey, $indexKey = null)
    {
        $output = array();

        foreach ($input as $row) {
            $key = $value = null;
            $keySet = $valueSet = false;

            if ($indexKey !== null && array_key_exists($indexKey, $row)) {
                $keySet = true;
                $key = (string) $row[$indexKey];
            }

            if ($columnKey === null) {
                $valueSet = true;
                $value = $row;
            } elseif (is_array($row) && array_key_exists($columnKey, $row)) {
                $valueSet = true;
                $value = $row[$columnKey];
            }

            if ($valueSet) {
                if ($keySet) {
                    $output[$key] = $value;
                } else {
                    $output[] = $value;
                }
            }
        }

        return $output;
    }
}
PKϤ$Z9��rrpolyfill-php55/README.mdnu�[���Symfony Polyfill / Php55
========================

This component provides functions unavailable in releases prior to PHP 5.5:

- [`boolval`](http://php.net/boolval)
- [`json_last_error_msg`](http://php.net/json_last_error_msg)
- [`array_column`](http://php.net/array_column)
- [`hash_pbkdf2`](http://php.net/hash_pbkdf2)
- `password_*` functions (from [ircmaxell/password_compat](https://github.com/ircmaxell/password_compat))

More information can be found in the
[main Polyfill README](https://github.com/symfony/polyfill/blob/master/README.md).

License
=======

This library is released under the [MIT license](LICENSE).
PKϤ$Z��/���polyfill-php55/bootstrap.phpnu�[���<?php

/*
 * This file is part of the Symfony package.
 *
 * (c) Fabien Potencier <fabien@symfony.com>
 *
 * For the full copyright and license information, please view the LICENSE
 * file that was distributed with this source code.
 */

use Symfony\Polyfill\Php55 as p;

if (PHP_VERSION_ID < 50500) {
    if (!function_exists('boolval')) {
        function boolval($val) { return p\Php55::boolval($val); }
    }
    if (!function_exists('json_last_error_msg')) {
        function json_last_error_msg() { return p\Php55::json_last_error_msg(); }
    }
    if (!function_exists('array_column')) {
        function array_column($array, $columnKey, $indexKey = null) { return p\Php55ArrayColumn::array_column($array, $columnKey, $indexKey); }
    }
    if (!function_exists('hash_pbkdf2')) {
        function hash_pbkdf2($algorithm, $password, $salt, $iterations, $length = 0, $rawOutput = false) { return p\Php55::hash_pbkdf2($algorithm, $password, $salt, $iterations, $length, $rawOutput); }
    }
}
PKϤ$Z�*L))polyfill-php55/LICENSEnu�[���Copyright (c) 2014-2016 Fabien Potencier

Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is furnished
to do so, subject to the following conditions:

The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.

THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
THE SOFTWARE.
PKϤ$Z��o�	�	�#filesystem/Tests/FilesystemTest.phpnu�[���<?php

/*
 * This file is part of the Symfony package.
 *
 * (c) Fabien Potencier <fabien@symfony.com>
 *
 * For the full copyright and license information, please view the LICENSE
 * file that was distributed with this source code.
 */

namespace Symfony\Component\Filesystem\Tests;

/**
 * Test class for Filesystem.
 */
class FilesystemTest extends FilesystemTestCase
{
    public function testCopyCreatesNewFile()
    {
        $sourceFilePath = $this->workspace.DIRECTORY_SEPARATOR.'copy_source_file';
        $targetFilePath = $this->workspace.DIRECTORY_SEPARATOR.'copy_target_file';

        file_put_contents($sourceFilePath, 'SOURCE FILE');

        $this->filesystem->copy($sourceFilePath, $targetFilePath);

        $this->assertFileExists($targetFilePath);
        $this->assertEquals('SOURCE FILE', file_get_contents($targetFilePath));
    }

    /**
     * @expectedException \Symfony\Component\Filesystem\Exception\IOException
     */
    public function testCopyFails()
    {
        $sourceFilePath = $this->workspace.DIRECTORY_SEPARATOR.'copy_source_file';
        $targetFilePath = $this->workspace.DIRECTORY_SEPARATOR.'copy_target_file';

        $this->filesystem->copy($sourceFilePath, $targetFilePath);
    }

    /**
     * @expectedException \Symfony\Component\Filesystem\Exception\IOException
     */
    public function testCopyUnreadableFileFails()
    {
        // skip test on Windows; PHP can't easily set file as unreadable on Windows
        if ('\\' === DIRECTORY_SEPARATOR) {
            $this->markTestSkipped('This test cannot run on Windows.');
        }

        $sourceFilePath = $this->workspace.DIRECTORY_SEPARATOR.'copy_source_file';
        $targetFilePath = $this->workspace.DIRECTORY_SEPARATOR.'copy_target_file';

        file_put_contents($sourceFilePath, 'SOURCE FILE');

        // make sure target cannot be read
        $this->filesystem->chmod($sourceFilePath, 0222);

        $this->filesystem->copy($sourceFilePath, $targetFilePath);
    }

    public function testCopyOverridesExistingFileIfModified()
    {
        $sourceFilePath = $this->workspace.DIRECTORY_SEPARATOR.'copy_source_file';
        $targetFilePath = $this->workspace.DIRECTORY_SEPARATOR.'copy_target_file';

        file_put_contents($sourceFilePath, 'SOURCE FILE');
        file_put_contents($targetFilePath, 'TARGET FILE');
        touch($targetFilePath, time() - 1000);

        $this->filesystem->copy($sourceFilePath, $targetFilePath);

        $this->assertFileExists($targetFilePath);
        $this->assertEquals('SOURCE FILE', file_get_contents($targetFilePath));
    }

    public function testCopyDoesNotOverrideExistingFileByDefault()
    {
        $sourceFilePath = $this->workspace.DIRECTORY_SEPARATOR.'copy_source_file';
        $targetFilePath = $this->workspace.DIRECTORY_SEPARATOR.'copy_target_file';

        file_put_contents($sourceFilePath, 'SOURCE FILE');
        file_put_contents($targetFilePath, 'TARGET FILE');

        // make sure both files have the same modification time
        $modificationTime = time() - 1000;
        touch($sourceFilePath, $modificationTime);
        touch($targetFilePath, $modificationTime);

        $this->filesystem->copy($sourceFilePath, $targetFilePath);

        $this->assertFileExists($targetFilePath);
        $this->assertEquals('TARGET FILE', file_get_contents($targetFilePath));
    }

    public function testCopyOverridesExistingFileIfForced()
    {
        $sourceFilePath = $this->workspace.DIRECTORY_SEPARATOR.'copy_source_file';
        $targetFilePath = $this->workspace.DIRECTORY_SEPARATOR.'copy_target_file';

        file_put_contents($sourceFilePath, 'SOURCE FILE');
        file_put_contents($targetFilePath, 'TARGET FILE');

        // make sure both files have the same modification time
        $modificationTime = time() - 1000;
        touch($sourceFilePath, $modificationTime);
        touch($targetFilePath, $modificationTime);

        $this->filesystem->copy($sourceFilePath, $targetFilePath, true);

        $this->assertFileExists($targetFilePath);
        $this->assertEquals('SOURCE FILE', file_get_contents($targetFilePath));
    }

    /**
     * @expectedException \Symfony\Component\Filesystem\Exception\IOException
     */
    public function testCopyWithOverrideWithReadOnlyTargetFails()
    {
        // skip test on Windows; PHP can't easily set file as unwritable on Windows
        if ('\\' === DIRECTORY_SEPARATOR) {
            $this->markTestSkipped('This test cannot run on Windows.');
        }

        $sourceFilePath = $this->workspace.DIRECTORY_SEPARATOR.'copy_source_file';
        $targetFilePath = $this->workspace.DIRECTORY_SEPARATOR.'copy_target_file';

        file_put_contents($sourceFilePath, 'SOURCE FILE');
        file_put_contents($targetFilePath, 'TARGET FILE');

        // make sure both files have the same modification time
        $modificationTime = time() - 1000;
        touch($sourceFilePath, $modificationTime);
        touch($targetFilePath, $modificationTime);

        // make sure target is read-only
        $this->filesystem->chmod($targetFilePath, 0444);

        $this->filesystem->copy($sourceFilePath, $targetFilePath, true);
    }

    public function testCopyCreatesTargetDirectoryIfItDoesNotExist()
    {
        $sourceFilePath = $this->workspace.DIRECTORY_SEPARATOR.'copy_source_file';
        $targetFileDirectory = $this->workspace.DIRECTORY_SEPARATOR.'directory';
        $targetFilePath = $targetFileDirectory.DIRECTORY_SEPARATOR.'copy_target_file';

        file_put_contents($sourceFilePath, 'SOURCE FILE');

        $this->filesystem->copy($sourceFilePath, $targetFilePath);

        $this->assertTrue(is_dir($targetFileDirectory));
        $this->assertFileExists($targetFilePath);
        $this->assertEquals('SOURCE FILE', file_get_contents($targetFilePath));
    }

    /**
     * @group network
     */
    public function testCopyForOriginUrlsAndExistingLocalFileDefaultsToCopy()
    {
        $sourceFilePath = 'http://symfony.com/images/common/logo/logo_symfony_header.png';
        $targetFilePath = $this->workspace.DIRECTORY_SEPARATOR.'copy_target_file';

        file_put_contents($targetFilePath, 'TARGET FILE');

        $this->filesystem->copy($sourceFilePath, $targetFilePath, false);

        $this->assertFileExists($targetFilePath);
        $this->assertEquals(file_get_contents($sourceFilePath), file_get_contents($targetFilePath));
    }

    public function testMkdirCreatesDirectoriesRecursively()
    {
        $directory = $this->workspace
            .DIRECTORY_SEPARATOR.'directory'
            .DIRECTORY_SEPARATOR.'sub_directory';

        $this->filesystem->mkdir($directory);

        $this->assertTrue(is_dir($directory));
    }

    public function testMkdirCreatesDirectoriesFromArray()
    {
        $basePath = $this->workspace.DIRECTORY_SEPARATOR;
        $directories = array(
            $basePath.'1', $basePath.'2', $basePath.'3',
        );

        $this->filesystem->mkdir($directories);

        $this->assertTrue(is_dir($basePath.'1'));
        $this->assertTrue(is_dir($basePath.'2'));
        $this->assertTrue(is_dir($basePath.'3'));
    }

    public function testMkdirCreatesDirectoriesFromTraversableObject()
    {
        $basePath = $this->workspace.DIRECTORY_SEPARATOR;
        $directories = new \ArrayObject(array(
            $basePath.'1', $basePath.'2', $basePath.'3',
        ));

        $this->filesystem->mkdir($directories);

        $this->assertTrue(is_dir($basePath.'1'));
        $this->assertTrue(is_dir($basePath.'2'));
        $this->assertTrue(is_dir($basePath.'3'));
    }

    /**
     * @expectedException \Symfony\Component\Filesystem\Exception\IOException
     */
    public function testMkdirCreatesDirectoriesFails()
    {
        $basePath = $this->workspace.DIRECTORY_SEPARATOR;
        $dir = $basePath.'2';

        file_put_contents($dir, '');

        $this->filesystem->mkdir($dir);
    }

    public function testTouchCreatesEmptyFile()
    {
        $file = $this->workspace.DIRECTORY_SEPARATOR.'1';

        $this->filesystem->touch($file);

        $this->assertFileExists($file);
    }

    /**
     * @expectedException \Symfony\Component\Filesystem\Exception\IOException
     */
    public function testTouchFails()
    {
        $file = $this->workspace.DIRECTORY_SEPARATOR.'1'.DIRECTORY_SEPARATOR.'2';

        $this->filesystem->touch($file);
    }

    public function testTouchCreatesEmptyFilesFromArray()
    {
        $basePath = $this->workspace.DIRECTORY_SEPARATOR;
        $files = array(
            $basePath.'1', $basePath.'2', $basePath.'3',
        );

        $this->filesystem->touch($files);

        $this->assertFileExists($basePath.'1');
        $this->assertFileExists($basePath.'2');
        $this->assertFileExists($basePath.'3');
    }

    public function testTouchCreatesEmptyFilesFromTraversableObject()
    {
        $basePath = $this->workspace.DIRECTORY_SEPARATOR;
        $files = new \ArrayObject(array(
            $basePath.'1', $basePath.'2', $basePath.'3',
        ));

        $this->filesystem->touch($files);

        $this->assertFileExists($basePath.'1');
        $this->assertFileExists($basePath.'2');
        $this->assertFileExists($basePath.'3');
    }

    public function testRemoveCleansFilesAndDirectoriesIteratively()
    {
        $basePath = $this->workspace.DIRECTORY_SEPARATOR.'directory'.DIRECTORY_SEPARATOR;

        mkdir($basePath);
        mkdir($basePath.'dir');
        touch($basePath.'file');

        $this->filesystem->remove($basePath);

        $this->assertFileNotExists($basePath);
    }

    public function testRemoveCleansArrayOfFilesAndDirectories()
    {
        $basePath = $this->workspace.DIRECTORY_SEPARATOR;

        mkdir($basePath.'dir');
        touch($basePath.'file');

        $files = array(
            $basePath.'dir', $basePath.'file',
        );

        $this->filesystem->remove($files);

        $this->assertFileNotExists($basePath.'dir');
        $this->assertFileNotExists($basePath.'file');
    }

    public function testRemoveCleansTraversableObjectOfFilesAndDirectories()
    {
        $basePath = $this->workspace.DIRECTORY_SEPARATOR;

        mkdir($basePath.'dir');
        touch($basePath.'file');

        $files = new \ArrayObject(array(
            $basePath.'dir', $basePath.'file',
        ));

        $this->filesystem->remove($files);

        $this->assertFileNotExists($basePath.'dir');
        $this->assertFileNotExists($basePath.'file');
    }

    public function testRemoveIgnoresNonExistingFiles()
    {
        $basePath = $this->workspace.DIRECTORY_SEPARATOR;

        mkdir($basePath.'dir');

        $files = array(
            $basePath.'dir', $basePath.'file',
        );

        $this->filesystem->remove($files);

        $this->assertFileNotExists($basePath.'dir');
    }

    public function testRemoveCleansInvalidLinks()
    {
        $this->markAsSkippedIfSymlinkIsMissing();

        $basePath = $this->workspace.DIRECTORY_SEPARATOR.'directory'.DIRECTORY_SEPARATOR;

        mkdir($basePath);
        mkdir($basePath.'dir');
        // create symlink to nonexistent file
        @symlink($basePath.'file', $basePath.'file-link');

        // create symlink to dir using trailing forward slash
        $this->filesystem->symlink($basePath.'dir/', $basePath.'dir-link');
        $this->assertTrue(is_dir($basePath.'dir-link'));

        // create symlink to nonexistent dir
        rmdir($basePath.'dir');
        $this->assertFalse('\\' === DIRECTORY_SEPARATOR ? @readlink($basePath.'dir-link') : is_dir($basePath.'dir-link'));

        $this->filesystem->remove($basePath);

        $this->assertFileNotExists($basePath);
    }

    public function testFilesExists()
    {
        $basePath = $this->workspace.DIRECTORY_SEPARATOR.'directory'.DIRECTORY_SEPARATOR;

        mkdir($basePath);
        touch($basePath.'file1');
        mkdir($basePath.'folder');

        $this->assertTrue($this->filesystem->exists($basePath.'file1'));
        $this->assertTrue($this->filesystem->exists($basePath.'folder'));
    }

    /**
     * @expectedException \Symfony\Component\Filesystem\Exception\IOException
     */
    public function testFilesExistsFails()
    {
        if ('\\' !== DIRECTORY_SEPARATOR) {
            $this->markTestSkipped('Test covers edge case on Windows only.');
        }

        $basePath = $this->workspace.'\\directory\\';

        $oldPath = getcwd();
        mkdir($basePath);
        chdir($basePath);
        $file = str_repeat('T', 259 - strlen($basePath));
        $path = $basePath.$file;
        exec('TYPE NUL >>'.$file); // equivalent of touch, we can not use the php touch() here because it suffers from the same limitation
        $this->longPathNamesWindows[] = $path; // save this so we can clean up later
        chdir($oldPath);
        $this->filesystem->exists($path);
    }

    public function testFilesExistsTraversableObjectOfFilesAndDirectories()
    {
        $basePath = $this->workspace.DIRECTORY_SEPARATOR;

        mkdir($basePath.'dir');
        touch($basePath.'file');

        $files = new \ArrayObject(array(
            $basePath.'dir', $basePath.'file',
        ));

        $this->assertTrue($this->filesystem->exists($files));
    }

    public function testFilesNotExistsTraversableObjectOfFilesAndDirectories()
    {
        $basePath = $this->workspace.DIRECTORY_SEPARATOR;

        mkdir($basePath.'dir');
        touch($basePath.'file');
        touch($basePath.'file2');

        $files = new \ArrayObject(array(
            $basePath.'dir', $basePath.'file', $basePath.'file2',
        ));

        unlink($basePath.'file');

        $this->assertFalse($this->filesystem->exists($files));
    }

    public function testInvalidFileNotExists()
    {
        $basePath = $this->workspace.DIRECTORY_SEPARATOR.'directory'.DIRECTORY_SEPARATOR;

        $this->assertFalse($this->filesystem->exists($basePath.time()));
    }

    public function testChmodChangesFileMode()
    {
        $this->markAsSkippedIfChmodIsMissing();

        $dir = $this->workspace.DIRECTORY_SEPARATOR.'dir';
        mkdir($dir);
        $file = $dir.DIRECTORY_SEPARATOR.'file';
        touch($file);

        $this->filesystem->chmod($file, 0400);
        $this->filesystem->chmod($dir, 0753);

        $this->assertFilePermissions(753, $dir);
        $this->assertFilePermissions(400, $file);
    }

    public function testChmodWithWrongModLeavesPreviousPermissionsUntouched()
    {
        $this->markAsSkippedIfChmodIsMissing();

        if (defined('HHVM_VERSION')) {
            $this->markTestSkipped('chmod() changes permissions even when passing invalid modes on HHVM');
        }

        $dir = $this->workspace.DIRECTORY_SEPARATOR.'file';
        touch($dir);

        $permissions = fileperms($dir);

        $this->filesystem->chmod($dir, 'Wrongmode');

        $this->assertSame($permissions, fileperms($dir));
    }

    public function testChmodRecursive()
    {
        $this->markAsSkippedIfChmodIsMissing();

        $dir = $this->workspace.DIRECTORY_SEPARATOR.'dir';
        mkdir($dir);
        $file = $dir.DIRECTORY_SEPARATOR.'file';
        touch($file);

        $this->filesystem->chmod($file, 0400, 0000, true);
        $this->filesystem->chmod($dir, 0753, 0000, true);

        $this->assertFilePermissions(753, $dir);
        $this->assertFilePermissions(753, $file);
    }

    public function testChmodAppliesUmask()
    {
        $this->markAsSkippedIfChmodIsMissing();

        $file = $this->workspace.DIRECTORY_SEPARATOR.'file';
        touch($file);

        $this->filesystem->chmod($file, 0770, 0022);
        $this->assertFilePermissions(750, $file);
    }

    public function testChmodChangesModeOfArrayOfFiles()
    {
        $this->markAsSkippedIfChmodIsMissing();

        $directory = $this->workspace.DIRECTORY_SEPARATOR.'directory';
        $file = $this->workspace.DIRECTORY_SEPARATOR.'file';
        $files = array($directory, $file);

        mkdir($directory);
        touch($file);

        $this->filesystem->chmod($files, 0753);

        $this->assertFilePermissions(753, $file);
        $this->assertFilePermissions(753, $directory);
    }

    public function testChmodChangesModeOfTraversableFileObject()
    {
        $this->markAsSkippedIfChmodIsMissing();

        $directory = $this->workspace.DIRECTORY_SEPARATOR.'directory';
        $file = $this->workspace.DIRECTORY_SEPARATOR.'file';
        $files = new \ArrayObject(array($directory, $file));

        mkdir($directory);
        touch($file);

        $this->filesystem->chmod($files, 0753);

        $this->assertFilePermissions(753, $file);
        $this->assertFilePermissions(753, $directory);
    }

    public function testChmodChangesZeroModeOnSubdirectoriesOnRecursive()
    {
        $this->markAsSkippedIfChmodIsMissing();

        $directory = $this->workspace.DIRECTORY_SEPARATOR.'directory';
        $subdirectory = $directory.DIRECTORY_SEPARATOR.'subdirectory';

        mkdir($directory);
        mkdir($subdirectory);
        chmod($subdirectory, 0000);

        $this->filesystem->chmod($directory, 0753, 0000, true);

        $this->assertFilePermissions(753, $subdirectory);
    }

    public function testChown()
    {
        $this->markAsSkippedIfPosixIsMissing();

        $dir = $this->workspace.DIRECTORY_SEPARATOR.'dir';
        mkdir($dir);

        $owner = $this->getFileOwner($dir);
        $this->filesystem->chown($dir, $owner);

        $this->assertSame($owner, $this->getFileOwner($dir));
    }

    public function testChownRecursive()
    {
        $this->markAsSkippedIfPosixIsMissing();

        $dir = $this->workspace.DIRECTORY_SEPARATOR.'dir';
        mkdir($dir);
        $file = $dir.DIRECTORY_SEPARATOR.'file';
        touch($file);

        $owner = $this->getFileOwner($dir);
        $this->filesystem->chown($dir, $owner, true);

        $this->assertSame($owner, $this->getFileOwner($file));
    }

    public function testChownSymlink()
    {
        $this->markAsSkippedIfSymlinkIsMissing();

        $file = $this->workspace.DIRECTORY_SEPARATOR.'file';
        $link = $this->workspace.DIRECTORY_SEPARATOR.'link';

        touch($file);

        $this->filesystem->symlink($file, $link);

        $owner = $this->getFileOwner($link);
        $this->filesystem->chown($link, $owner);

        $this->assertSame($owner, $this->getFileOwner($link));
    }

    public function testChownLink()
    {
        $this->markAsSkippedIfLinkIsMissing();

        $file = $this->workspace.DIRECTORY_SEPARATOR.'file';
        $link = $this->workspace.DIRECTORY_SEPARATOR.'link';

        touch($file);

        $this->filesystem->hardlink($file, $link);

        $owner = $this->getFileOwner($link);
        $this->filesystem->chown($link, $owner);

        $this->assertSame($owner, $this->getFileOwner($link));
    }

    /**
     * @expectedException \Symfony\Component\Filesystem\Exception\IOException
     */
    public function testChownSymlinkFails()
    {
        $this->markAsSkippedIfSymlinkIsMissing();

        $file = $this->workspace.DIRECTORY_SEPARATOR.'file';
        $link = $this->workspace.DIRECTORY_SEPARATOR.'link';

        touch($file);

        $this->filesystem->symlink($file, $link);

        $this->filesystem->chown($link, 'user'.time().mt_rand(1000, 9999));
    }

    /**
     * @expectedException \Symfony\Component\Filesystem\Exception\IOException
     */
    public function testChownLinkFails()
    {
        $this->markAsSkippedIfLinkIsMissing();

        $file = $this->workspace.DIRECTORY_SEPARATOR.'file';
        $link = $this->workspace.DIRECTORY_SEPARATOR.'link';

        touch($file);

        $this->filesystem->hardlink($file, $link);

        $this->filesystem->chown($link, 'user'.time().mt_rand(1000, 9999));
    }

    /**
     * @expectedException \Symfony\Component\Filesystem\Exception\IOException
     */
    public function testChownFail()
    {
        $this->markAsSkippedIfPosixIsMissing();

        $dir = $this->workspace.DIRECTORY_SEPARATOR.'dir';
        mkdir($dir);

        $this->filesystem->chown($dir, 'user'.time().mt_rand(1000, 9999));
    }

    public function testChgrp()
    {
        $this->markAsSkippedIfPosixIsMissing();

        $dir = $this->workspace.DIRECTORY_SEPARATOR.'dir';
        mkdir($dir);

        $group = $this->getFileGroup($dir);
        $this->filesystem->chgrp($dir, $group);

        $this->assertSame($group, $this->getFileGroup($dir));
    }

    public function testChgrpRecursive()
    {
        $this->markAsSkippedIfPosixIsMissing();

        $dir = $this->workspace.DIRECTORY_SEPARATOR.'dir';
        mkdir($dir);
        $file = $dir.DIRECTORY_SEPARATOR.'file';
        touch($file);

        $group = $this->getFileGroup($dir);
        $this->filesystem->chgrp($dir, $group, true);

        $this->assertSame($group, $this->getFileGroup($file));
    }

    public function testChgrpSymlink()
    {
        $this->markAsSkippedIfSymlinkIsMissing();

        $file = $this->workspace.DIRECTORY_SEPARATOR.'file';
        $link = $this->workspace.DIRECTORY_SEPARATOR.'link';

        touch($file);

        $this->filesystem->symlink($file, $link);

        $group = $this->getFileGroup($link);
        $this->filesystem->chgrp($link, $group);

        $this->assertSame($group, $this->getFileGroup($link));
    }

    public function testChgrpLink()
    {
        $this->markAsSkippedIfLinkIsMissing();

        $file = $this->workspace.DIRECTORY_SEPARATOR.'file';
        $link = $this->workspace.DIRECTORY_SEPARATOR.'link';

        touch($file);

        $this->filesystem->hardlink($file, $link);

        $group = $this->getFileGroup($link);
        $this->filesystem->chgrp($link, $group);

        $this->assertSame($group, $this->getFileGroup($link));
    }

    /**
     * @expectedException \Symfony\Component\Filesystem\Exception\IOException
     */
    public function testChgrpSymlinkFails()
    {
        $this->markAsSkippedIfSymlinkIsMissing();

        $file = $this->workspace.DIRECTORY_SEPARATOR.'file';
        $link = $this->workspace.DIRECTORY_SEPARATOR.'link';

        touch($file);

        $this->filesystem->symlink($file, $link);

        $this->filesystem->chgrp($link, 'user'.time().mt_rand(1000, 9999));
    }

    /**
     * @expectedException \Symfony\Component\Filesystem\Exception\IOException
     */
    public function testChgrpLinkFails()
    {
        $this->markAsSkippedIfLinkIsMissing();

        $file = $this->workspace.DIRECTORY_SEPARATOR.'file';
        $link = $this->workspace.DIRECTORY_SEPARATOR.'link';

        touch($file);

        $this->filesystem->hardlink($file, $link);

        $this->filesystem->chgrp($link, 'user'.time().mt_rand(1000, 9999));
    }

    /**
     * @expectedException \Symfony\Component\Filesystem\Exception\IOException
     */
    public function testChgrpFail()
    {
        $this->markAsSkippedIfPosixIsMissing();

        $dir = $this->workspace.DIRECTORY_SEPARATOR.'dir';
        mkdir($dir);

        $this->filesystem->chgrp($dir, 'user'.time().mt_rand(1000, 9999));
    }

    public function testRename()
    {
        $file = $this->workspace.DIRECTORY_SEPARATOR.'file';
        $newPath = $this->workspace.DIRECTORY_SEPARATOR.'new_file';
        touch($file);

        $this->filesystem->rename($file, $newPath);

        $this->assertFileNotExists($file);
        $this->assertFileExists($newPath);
    }

    /**
     * @expectedException \Symfony\Component\Filesystem\Exception\IOException
     */
    public function testRenameThrowsExceptionIfTargetAlreadyExists()
    {
        $file = $this->workspace.DIRECTORY_SEPARATOR.'file';
        $newPath = $this->workspace.DIRECTORY_SEPARATOR.'new_file';

        touch($file);
        touch($newPath);

        $this->filesystem->rename($file, $newPath);
    }

    public function testRenameOverwritesTheTargetIfItAlreadyExists()
    {
        $file = $this->workspace.DIRECTORY_SEPARATOR.'file';
        $newPath = $this->workspace.DIRECTORY_SEPARATOR.'new_file';

        touch($file);
        touch($newPath);

        $this->filesystem->rename($file, $newPath, true);

        $this->assertFileNotExists($file);
        $this->assertFileExists($newPath);
    }

    /**
     * @expectedException \Symfony\Component\Filesystem\Exception\IOException
     */
    public function testRenameThrowsExceptionOnError()
    {
        $file = $this->workspace.DIRECTORY_SEPARATOR.uniqid('fs_test_', true);
        $newPath = $this->workspace.DIRECTORY_SEPARATOR.'new_file';

        $this->filesystem->rename($file, $newPath);
    }

    public function testSymlink()
    {
        if ('\\' === DIRECTORY_SEPARATOR) {
            $this->markTestSkipped('Windows does not support creating "broken" symlinks');
        }

        $file = $this->workspace.DIRECTORY_SEPARATOR.'file';
        $link = $this->workspace.DIRECTORY_SEPARATOR.'link';

        // $file does not exists right now: creating "broken" links is a wanted feature
        $this->filesystem->symlink($file, $link);

        $this->assertTrue(is_link($link));

        // Create the linked file AFTER creating the link
        touch($file);

        $this->assertEquals($file, readlink($link));
    }

    /**
     * @depends testSymlink
     */
    public function testRemoveSymlink()
    {
        $this->markAsSkippedIfSymlinkIsMissing();

        $link = $this->workspace.DIRECTORY_SEPARATOR.'link';

        $this->filesystem->remove($link);

        $this->assertTrue(!is_link($link));
        $this->assertTrue(!is_file($link));
        $this->assertTrue(!is_dir($link));
    }

    public function testSymlinkIsOverwrittenIfPointsToDifferentTarget()
    {
        $this->markAsSkippedIfSymlinkIsMissing();

        $file = $this->workspace.DIRECTORY_SEPARATOR.'file';
        $link = $this->workspace.DIRECTORY_SEPARATOR.'link';

        touch($file);
        symlink($this->workspace, $link);

        $this->filesystem->symlink($file, $link);

        $this->assertTrue(is_link($link));
        $this->assertEquals($file, readlink($link));
    }

    public function testSymlinkIsNotOverwrittenIfAlreadyCreated()
    {
        $this->markAsSkippedIfSymlinkIsMissing();

        $file = $this->workspace.DIRECTORY_SEPARATOR.'file';
        $link = $this->workspace.DIRECTORY_SEPARATOR.'link';

        touch($file);
        symlink($file, $link);

        $this->filesystem->symlink($file, $link);

        $this->assertTrue(is_link($link));
        $this->assertEquals($file, readlink($link));
    }

    public function testSymlinkCreatesTargetDirectoryIfItDoesNotExist()
    {
        $this->markAsSkippedIfSymlinkIsMissing();

        $file = $this->workspace.DIRECTORY_SEPARATOR.'file';
        $link1 = $this->workspace.DIRECTORY_SEPARATOR.'dir'.DIRECTORY_SEPARATOR.'link';
        $link2 = $this->workspace.DIRECTORY_SEPARATOR.'dir'.DIRECTORY_SEPARATOR.'subdir'.DIRECTORY_SEPARATOR.'link';

        touch($file);

        $this->filesystem->symlink($file, $link1);
        $this->filesystem->symlink($file, $link2);

        $this->assertTrue(is_link($link1));
        $this->assertEquals($file, readlink($link1));
        $this->assertTrue(is_link($link2));
        $this->assertEquals($file, readlink($link2));
    }

    public function testLink()
    {
        $this->markAsSkippedIfLinkIsMissing();

        $file = $this->workspace.DIRECTORY_SEPARATOR.'file';
        $link = $this->workspace.DIRECTORY_SEPARATOR.'link';

        touch($file);
        $this->filesystem->hardlink($file, $link);

        $this->assertTrue(is_file($link));
        $this->assertEquals(fileinode($file), fileinode($link));
    }

    /**
     * @depends testLink
     */
    public function testRemoveLink()
    {
        $this->markAsSkippedIfLinkIsMissing();

        $link = $this->workspace.DIRECTORY_SEPARATOR.'link';

        $this->filesystem->remove($link);

        $this->assertTrue(!is_file($link));
    }

    public function testLinkIsOverwrittenIfPointsToDifferentTarget()
    {
        $this->markAsSkippedIfLinkIsMissing();

        $file = $this->workspace.DIRECTORY_SEPARATOR.'file';
        $file2 = $this->workspace.DIRECTORY_SEPARATOR.'file2';
        $link = $this->workspace.DIRECTORY_SEPARATOR.'link';

        touch($file);
        touch($file2);
        link($file2, $link);

        $this->filesystem->hardlink($file, $link);

        $this->assertTrue(is_file($link));
        $this->assertEquals(fileinode($file), fileinode($link));
    }

    public function testLinkIsNotOverwrittenIfAlreadyCreated()
    {
        $this->markAsSkippedIfLinkIsMissing();

        $file = $this->workspace.DIRECTORY_SEPARATOR.'file';
        $link = $this->workspace.DIRECTORY_SEPARATOR.'link';

        touch($file);
        link($file, $link);

        $this->filesystem->hardlink($file, $link);

        $this->assertTrue(is_file($link));
        $this->assertEquals(fileinode($file), fileinode($link));
    }

    public function testLinkWithSeveralTargets()
    {
        $this->markAsSkippedIfLinkIsMissing();

        $file = $this->workspace.DIRECTORY_SEPARATOR.'file';
        $link1 = $this->workspace.DIRECTORY_SEPARATOR.'link';
        $link2 = $this->workspace.DIRECTORY_SEPARATOR.'link2';

        touch($file);

        $this->filesystem->hardlink($file, array($link1, $link2));

        $this->assertTrue(is_file($link1));
        $this->assertEquals(fileinode($file), fileinode($link1));
        $this->assertTrue(is_file($link2));
        $this->assertEquals(fileinode($file), fileinode($link2));
    }

    public function testLinkWithSameTarget()
    {
        $this->markAsSkippedIfLinkIsMissing();

        $file = $this->workspace.DIRECTORY_SEPARATOR.'file';
        $link = $this->workspace.DIRECTORY_SEPARATOR.'link';

        touch($file);

        // practically same as testLinkIsNotOverwrittenIfAlreadyCreated
        $this->filesystem->hardlink($file, array($link, $link));

        $this->assertTrue(is_file($link));
        $this->assertEquals(fileinode($file), fileinode($link));
    }

    public function testReadRelativeLink()
    {
        $this->markAsSkippedIfSymlinkIsMissing();

        if ('\\' === DIRECTORY_SEPARATOR) {
            $this->markTestSkipped('Relative symbolic links are not supported on Windows');
        }

        $file = $this->workspace.'/file';
        $link1 = $this->workspace.'/dir/link';
        $link2 = $this->workspace.'/dir/link2';
        touch($file);

        $this->filesystem->symlink('../file', $link1);
        $this->filesystem->symlink('link', $link2);

        $this->assertEquals($this->normalize('../file'), $this->filesystem->readlink($link1));
        $this->assertEquals('link', $this->filesystem->readlink($link2));
        $this->assertEquals($file, $this->filesystem->readlink($link1, true));
        $this->assertEquals($file, $this->filesystem->readlink($link2, true));
        $this->assertEquals($file, $this->filesystem->readlink($file, true));
    }

    public function testReadAbsoluteLink()
    {
        $this->markAsSkippedIfSymlinkIsMissing();

        $file = $this->normalize($this->workspace.'/file');
        $link1 = $this->normalize($this->workspace.'/dir/link');
        $link2 = $this->normalize($this->workspace.'/dir/link2');
        touch($file);

        $this->filesystem->symlink($file, $link1);
        $this->filesystem->symlink($link1, $link2);

        $this->assertEquals($file, $this->filesystem->readlink($link1));
        $this->assertEquals($link1, $this->filesystem->readlink($link2));
        $this->assertEquals($file, $this->filesystem->readlink($link1, true));
        $this->assertEquals($file, $this->filesystem->readlink($link2, true));
        $this->assertEquals($file, $this->filesystem->readlink($file, true));
    }

    public function testReadBrokenLink()
    {
        $this->markAsSkippedIfSymlinkIsMissing();

        if ('\\' === DIRECTORY_SEPARATOR) {
            $this->markTestSkipped('Windows does not support creating "broken" symlinks');
        }

        $file = $this->workspace.'/file';
        $link = $this->workspace.'/link';

        $this->filesystem->symlink($file, $link);

        $this->assertEquals($file, $this->filesystem->readlink($link));
        $this->assertNull($this->filesystem->readlink($link, true));

        touch($file);
        $this->assertEquals($file, $this->filesystem->readlink($link, true));
    }

    public function testReadLinkDefaultPathDoesNotExist()
    {
        $this->assertNull($this->filesystem->readlink($this->normalize($this->workspace.'/invalid')));
    }

    public function testReadLinkDefaultPathNotLink()
    {
        $file = $this->normalize($this->workspace.'/file');
        touch($file);

        $this->assertNull($this->filesystem->readlink($file));
    }

    public function testReadLinkCanonicalizePath()
    {
        $this->markAsSkippedIfSymlinkIsMissing();

        $file = $this->normalize($this->workspace.'/file');
        mkdir($this->normalize($this->workspace.'/dir'));
        touch($file);

        $this->assertEquals($file, $this->filesystem->readlink($this->normalize($this->workspace.'/dir/../file'), true));
    }

    public function testReadLinkCanonicalizedPathDoesNotExist()
    {
        $this->assertNull($this->filesystem->readlink($this->normalize($this->workspace.'invalid'), true));
    }

    /**
     * @dataProvider providePathsForMakePathRelative
     */
    public function testMakePathRelative($endPath, $startPath, $expectedPath)
    {
        $path = $this->filesystem->makePathRelative($endPath, $startPath);

        $this->assertEquals($expectedPath, $path);
    }

    /**
     * @return array
     */
    public function providePathsForMakePathRelative()
    {
        $paths = array(
            array('/var/lib/symfony/src/Symfony/', '/var/lib/symfony/src/Symfony/Component', '../'),
            array('/var/lib/symfony/src/Symfony/', '/var/lib/symfony/src/Symfony/Component/', '../'),
            array('/var/lib/symfony/src/Symfony', '/var/lib/symfony/src/Symfony/Component', '../'),
            array('/var/lib/symfony/src/Symfony', '/var/lib/symfony/src/Symfony/Component/', '../'),
            array('var/lib/symfony/', 'var/lib/symfony/src/Symfony/Component', '../../../'),
            array('/usr/lib/symfony/', '/var/lib/symfony/src/Symfony/Component', '../../../../../../usr/lib/symfony/'),
            array('/var/lib/symfony/src/Symfony/', '/var/lib/symfony/', 'src/Symfony/'),
            array('/aa/bb', '/aa/bb', './'),
            array('/aa/bb', '/aa/bb/', './'),
            array('/aa/bb/', '/aa/bb', './'),
            array('/aa/bb/', '/aa/bb/', './'),
            array('/aa/bb/cc', '/aa/bb/cc/dd', '../'),
            array('/aa/bb/cc', '/aa/bb/cc/dd/', '../'),
            array('/aa/bb/cc/', '/aa/bb/cc/dd', '../'),
            array('/aa/bb/cc/', '/aa/bb/cc/dd/', '../'),
            array('/aa/bb/cc', '/aa', 'bb/cc/'),
            array('/aa/bb/cc', '/aa/', 'bb/cc/'),
            array('/aa/bb/cc/', '/aa', 'bb/cc/'),
            array('/aa/bb/cc/', '/aa/', 'bb/cc/'),
            array('/a/aab/bb', '/a/aa', '../aab/bb/'),
            array('/a/aab/bb', '/a/aa/', '../aab/bb/'),
            array('/a/aab/bb/', '/a/aa', '../aab/bb/'),
            array('/a/aab/bb/', '/a/aa/', '../aab/bb/'),
            array('/a/aab/bb/', '/', 'a/aab/bb/'),
            array('/a/aab/bb/', '/b/aab', '../../a/aab/bb/'),
            array('/aab/bb', '/aa', '../aab/bb/'),
            array('/aab', '/aa', '../aab/'),
            array('/aa/bb/cc', '/aa/dd/..', 'bb/cc/'),
            array('/aa/../bb/cc', '/aa/dd/..', '../bb/cc/'),
            array('/aa/bb/../../cc', '/aa/../dd/..', 'cc/'),
            array('/../aa/bb/cc', '/aa/dd/..', 'bb/cc/'),
            array('/../../aa/../bb/cc', '/aa/dd/..', '../bb/cc/'),
            array('C:/aa/bb/cc', 'C:/aa/dd/..', 'bb/cc/'),
            array('c:/aa/../bb/cc', 'c:/aa/dd/..', '../bb/cc/'),
            array('C:/aa/bb/../../cc', 'C:/aa/../dd/..', 'cc/'),
            array('C:/../aa/bb/cc', 'C:/aa/dd/..', 'bb/cc/'),
            array('C:/../../aa/../bb/cc', 'C:/aa/dd/..', '../bb/cc/'),
        );

        if ('\\' === DIRECTORY_SEPARATOR) {
            $paths[] = array('c:\var\lib/symfony/src/Symfony/', 'c:/var/lib/symfony/', 'src/Symfony/');
        }

        return $paths;
    }

    public function testMirrorCopiesFilesAndDirectoriesRecursively()
    {
        $sourcePath = $this->workspace.DIRECTORY_SEPARATOR.'source'.DIRECTORY_SEPARATOR;
        $directory = $sourcePath.'directory'.DIRECTORY_SEPARATOR;
        $file1 = $directory.'file1';
        $file2 = $sourcePath.'file2';

        mkdir($sourcePath);
        mkdir($directory);
        file_put_contents($file1, 'FILE1');
        file_put_contents($file2, 'FILE2');

        $targetPath = $this->workspace.DIRECTORY_SEPARATOR.'target'.DIRECTORY_SEPARATOR;

        $this->filesystem->mirror($sourcePath, $targetPath);

        $this->assertTrue(is_dir($targetPath));
        $this->assertTrue(is_dir($targetPath.'directory'));
        $this->assertFileEquals($file1, $targetPath.'directory'.DIRECTORY_SEPARATOR.'file1');
        $this->assertFileEquals($file2, $targetPath.'file2');

        $this->filesystem->remove($file1);

        $this->filesystem->mirror($sourcePath, $targetPath, null, array('delete' => false));
        $this->assertTrue($this->filesystem->exists($targetPath.'directory'.DIRECTORY_SEPARATOR.'file1'));

        $this->filesystem->mirror($sourcePath, $targetPath, null, array('delete' => true));
        $this->assertFalse($this->filesystem->exists($targetPath.'directory'.DIRECTORY_SEPARATOR.'file1'));

        file_put_contents($file1, 'FILE1');

        $this->filesystem->mirror($sourcePath, $targetPath, null, array('delete' => true));
        $this->assertTrue($this->filesystem->exists($targetPath.'directory'.DIRECTORY_SEPARATOR.'file1'));

        $this->filesystem->remove($directory);
        $this->filesystem->mirror($sourcePath, $targetPath, null, array('delete' => true));
        $this->assertFalse($this->filesystem->exists($targetPath.'directory'));
        $this->assertFalse($this->filesystem->exists($targetPath.'directory'.DIRECTORY_SEPARATOR.'file1'));
    }

    public function testMirrorCreatesEmptyDirectory()
    {
        $sourcePath = $this->workspace.DIRECTORY_SEPARATOR.'source'.DIRECTORY_SEPARATOR;

        mkdir($sourcePath);

        $targetPath = $this->workspace.DIRECTORY_SEPARATOR.'target'.DIRECTORY_SEPARATOR;

        $this->filesystem->mirror($sourcePath, $targetPath);

        $this->assertTrue(is_dir($targetPath));

        $this->filesystem->remove($sourcePath);
    }

    public function testMirrorCopiesLinks()
    {
        $this->markAsSkippedIfSymlinkIsMissing();

        $sourcePath = $this->workspace.DIRECTORY_SEPARATOR.'source'.DIRECTORY_SEPARATOR;

        mkdir($sourcePath);
        file_put_contents($sourcePath.'file1', 'FILE1');
        symlink($sourcePath.'file1', $sourcePath.'link1');

        $targetPath = $this->workspace.DIRECTORY_SEPARATOR.'target'.DIRECTORY_SEPARATOR;

        $this->filesystem->mirror($sourcePath, $targetPath);

        $this->assertTrue(is_dir($targetPath));
        $this->assertFileEquals($sourcePath.'file1', $targetPath.'link1');
        $this->assertTrue(is_link($targetPath.DIRECTORY_SEPARATOR.'link1'));
    }

    public function testMirrorCopiesLinkedDirectoryContents()
    {
        $this->markAsSkippedIfSymlinkIsMissing(true);

        $sourcePath = $this->workspace.DIRECTORY_SEPARATOR.'source'.DIRECTORY_SEPARATOR;

        mkdir($sourcePath.'nested/', 0777, true);
        file_put_contents($sourcePath.'/nested/file1.txt', 'FILE1');
        // Note: We symlink directory, not file
        symlink($sourcePath.'nested', $sourcePath.'link1');

        $targetPath = $this->workspace.DIRECTORY_SEPARATOR.'target'.DIRECTORY_SEPARATOR;

        $this->filesystem->mirror($sourcePath, $targetPath);

        $this->assertTrue(is_dir($targetPath));
        $this->assertFileEquals($sourcePath.'/nested/file1.txt', $targetPath.'link1/file1.txt');
        $this->assertTrue(is_link($targetPath.DIRECTORY_SEPARATOR.'link1'));
    }

    public function testMirrorCopiesRelativeLinkedContents()
    {
        $this->markAsSkippedIfSymlinkIsMissing(true);

        $sourcePath = $this->workspace.DIRECTORY_SEPARATOR.'source'.DIRECTORY_SEPARATOR;
        $oldPath = getcwd();

        mkdir($sourcePath.'nested/', 0777, true);
        file_put_contents($sourcePath.'/nested/file1.txt', 'FILE1');
        // Note: Create relative symlink
        chdir($sourcePath);
        symlink('nested', 'link1');

        chdir($oldPath);

        $targetPath = $this->workspace.DIRECTORY_SEPARATOR.'target'.DIRECTORY_SEPARATOR;

        $this->filesystem->mirror($sourcePath, $targetPath);

        $this->assertTrue(is_dir($targetPath));
        $this->assertFileEquals($sourcePath.'/nested/file1.txt', $targetPath.'link1/file1.txt');
        $this->assertTrue(is_link($targetPath.DIRECTORY_SEPARATOR.'link1'));
        $this->assertEquals('\\' === DIRECTORY_SEPARATOR ? realpath($sourcePath.'\nested') : 'nested', readlink($targetPath.DIRECTORY_SEPARATOR.'link1'));
    }

    /**
     * @dataProvider providePathsForIsAbsolutePath
     */
    public function testIsAbsolutePath($path, $expectedResult)
    {
        $result = $this->filesystem->isAbsolutePath($path);

        $this->assertEquals($expectedResult, $result);
    }

    /**
     * @return array
     */
    public function providePathsForIsAbsolutePath()
    {
        return array(
            array('/var/lib', true),
            array('c:\\\\var\\lib', true),
            array('\\var\\lib', true),
            array('var/lib', false),
            array('../var/lib', false),
            array('', false),
            array(null, false),
        );
    }

    public function testTempnam()
    {
        $dirname = $this->workspace;

        $filename = $this->filesystem->tempnam($dirname, 'foo');

        $this->assertFileExists($filename);
    }

    public function testTempnamWithFileScheme()
    {
        $scheme = 'file://';
        $dirname = $scheme.$this->workspace;

        $filename = $this->filesystem->tempnam($dirname, 'foo');

        $this->assertStringStartsWith($scheme, $filename);
        $this->assertFileExists($filename);
    }

    public function testTempnamWithMockScheme()
    {
        stream_wrapper_register('mock', 'Symfony\Component\Filesystem\Tests\Fixtures\MockStream\MockStream');

        $scheme = 'mock://';
        $dirname = $scheme.$this->workspace;

        $filename = $this->filesystem->tempnam($dirname, 'foo');

        $this->assertStringStartsWith($scheme, $filename);
        $this->assertFileExists($filename);
    }

    /**
     * @expectedException \Symfony\Component\Filesystem\Exception\IOException
     */
    public function testTempnamWithZlibSchemeFails()
    {
        $scheme = 'compress.zlib://';
        $dirname = $scheme.$this->workspace;

        // The compress.zlib:// stream does not support mode x: creates the file, errors "failed to open stream: operation failed" and returns false
        $this->filesystem->tempnam($dirname, 'bar');
    }

    public function testTempnamWithPHPTempSchemeFails()
    {
        $scheme = 'php://temp';
        $dirname = $scheme;

        $filename = $this->filesystem->tempnam($dirname, 'bar');

        $this->assertStringStartsWith($scheme, $filename);

        // The php://temp stream deletes the file after close
        $this->assertFileNotExists($filename);
    }

    /**
     * @expectedException \Symfony\Component\Filesystem\Exception\IOException
     */
    public function testTempnamWithPharSchemeFails()
    {
        // Skip test if Phar disabled phar.readonly must be 0 in php.ini
        if (!\Phar::canWrite()) {
            $this->markTestSkipped('This test cannot run when phar.readonly is 1.');
        }

        $scheme = 'phar://';
        $dirname = $scheme.$this->workspace;
        $pharname = 'foo.phar';

        new \Phar($this->workspace.'/'.$pharname, 0, $pharname);
        // The phar:// stream does not support mode x: fails to create file, errors "failed to open stream: phar error: "$filename" is not a file in phar "$pharname"" and returns false
        $this->filesystem->tempnam($dirname, $pharname.'/bar');
    }

    /**
     * @expectedException \Symfony\Component\Filesystem\Exception\IOException
     */
    public function testTempnamWithHTTPSchemeFails()
    {
        $scheme = 'http://';
        $dirname = $scheme.$this->workspace;

        // The http:// scheme is read-only
        $this->filesystem->tempnam($dirname, 'bar');
    }

    public function testTempnamOnUnwritableFallsBackToSysTmp()
    {
        $scheme = 'file://';
        $dirname = $scheme.$this->workspace.DIRECTORY_SEPARATOR.'does_not_exist';

        $filename = $this->filesystem->tempnam($dirname, 'bar');
        $realTempDir = realpath(sys_get_temp_dir());
        $this->assertStringStartsWith(rtrim($scheme.$realTempDir, DIRECTORY_SEPARATOR), $filename);
        $this->assertFileExists($filename);

        // Tear down
        @unlink($filename);
    }

    public function testDumpFile()
    {
        $filename = $this->workspace.DIRECTORY_SEPARATOR.'foo'.DIRECTORY_SEPARATOR.'baz.txt';

        // skip mode check on Windows
        if ('\\' !== DIRECTORY_SEPARATOR) {
            $oldMask = umask(0002);
        }

        $this->filesystem->dumpFile($filename, 'bar');
        $this->assertFileExists($filename);
        $this->assertSame('bar', file_get_contents($filename));

        // skip mode check on Windows
        if ('\\' !== DIRECTORY_SEPARATOR) {
            $this->assertFilePermissions(664, $filename);
            umask($oldMask);
        }
    }

    public function testDumpFileOverwritesAnExistingFile()
    {
        $filename = $this->workspace.DIRECTORY_SEPARATOR.'foo.txt';
        file_put_contents($filename, 'FOO BAR');

        $this->filesystem->dumpFile($filename, 'bar');

        $this->assertFileExists($filename);
        $this->assertSame('bar', file_get_contents($filename));
    }

    public function testDumpFileWithFileScheme()
    {
        if (defined('HHVM_VERSION')) {
            $this->markTestSkipped('HHVM does not handle the file:// scheme correctly');
        }

        $scheme = 'file://';
        $filename = $scheme.$this->workspace.DIRECTORY_SEPARATOR.'foo'.DIRECTORY_SEPARATOR.'baz.txt';

        $this->filesystem->dumpFile($filename, 'bar');

        $this->assertFileExists($filename);
        $this->assertSame('bar', file_get_contents($filename));
    }

    public function testDumpFileWithZlibScheme()
    {
        $scheme = 'compress.zlib://';
        $filename = $this->workspace.DIRECTORY_SEPARATOR.'foo'.DIRECTORY_SEPARATOR.'baz.txt';

        $this->filesystem->dumpFile($filename, 'bar');

        // Zlib stat uses file:// wrapper so remove scheme
        $this->assertFileExists(str_replace($scheme, '', $filename));
        $this->assertSame('bar', file_get_contents($filename));
    }

    public function testAppendToFile()
    {
        $filename = $this->workspace.DIRECTORY_SEPARATOR.'foo'.DIRECTORY_SEPARATOR.'bar.txt';

        // skip mode check on Windows
        if ('\\' !== DIRECTORY_SEPARATOR) {
            $oldMask = umask(0002);
        }

        $this->filesystem->dumpFile($filename, 'foo');

        $this->filesystem->appendToFile($filename, 'bar');

        $this->assertFileExists($filename);
        $this->assertSame('foobar', file_get_contents($filename));

        // skip mode check on Windows
        if ('\\' !== DIRECTORY_SEPARATOR) {
            $this->assertFilePermissions(664, $filename, 'The written file should keep the same permissions as before.');
            umask($oldMask);
        }
    }

    public function testAppendToFileWithScheme()
    {
        if (defined('HHVM_VERSION')) {
            $this->markTestSkipped('HHVM does not handle the file:// scheme correctly');
        }

        $scheme = 'file://';
        $filename = $scheme.$this->workspace.DIRECTORY_SEPARATOR.'foo'.DIRECTORY_SEPARATOR.'baz.txt';
        $this->filesystem->dumpFile($filename, 'foo');

        $this->filesystem->appendToFile($filename, 'bar');

        $this->assertFileExists($filename);
        $this->assertSame('foobar', file_get_contents($filename));
    }

    public function testAppendToFileWithZlibScheme()
    {
        $scheme = 'compress.zlib://';
        $filename = $this->workspace.DIRECTORY_SEPARATOR.'foo'.DIRECTORY_SEPARATOR.'baz.txt';
        $this->filesystem->dumpFile($filename, 'foo');

        // Zlib stat uses file:// wrapper so remove it
        $this->assertSame('foo', file_get_contents(str_replace($scheme, '', $filename)));

        $this->filesystem->appendToFile($filename, 'bar');

        $this->assertFileExists($filename);
        $this->assertSame('foobar', file_get_contents($filename));
    }

    public function testAppendToFileCreateTheFileIfNotExists()
    {
        $filename = $this->workspace.DIRECTORY_SEPARATOR.'foo'.DIRECTORY_SEPARATOR.'bar.txt';

        // skip mode check on Windows
        if ('\\' !== DIRECTORY_SEPARATOR) {
            $oldMask = umask(0002);
        }

        $this->filesystem->appendToFile($filename, 'bar');

        // skip mode check on Windows
        if ('\\' !== DIRECTORY_SEPARATOR) {
            $this->assertFilePermissions(664, $filename);
            umask($oldMask);
        }

        $this->assertFileExists($filename);
        $this->assertSame('bar', file_get_contents($filename));
    }

    public function testDumpKeepsExistingPermissionsWhenOverwritingAnExistingFile()
    {
        $this->markAsSkippedIfChmodIsMissing();

        $filename = $this->workspace.DIRECTORY_SEPARATOR.'foo.txt';
        file_put_contents($filename, 'FOO BAR');
        chmod($filename, 0745);

        $this->filesystem->dumpFile($filename, 'bar', null);

        $this->assertFilePermissions(745, $filename);
    }

    public function testCopyShouldKeepExecutionPermission()
    {
        $this->markAsSkippedIfChmodIsMissing();

        $sourceFilePath = $this->workspace.DIRECTORY_SEPARATOR.'copy_source_file';
        $targetFilePath = $this->workspace.DIRECTORY_SEPARATOR.'copy_target_file';

        file_put_contents($sourceFilePath, 'SOURCE FILE');
        chmod($sourceFilePath, 0745);

        $this->filesystem->copy($sourceFilePath, $targetFilePath);

        $this->assertFilePermissions(767, $targetFilePath);
    }

    /**
     * Normalize the given path (transform each blackslash into a real directory separator).
     *
     * @param string $path
     *
     * @return string
     */
    private function normalize($path)
    {
        return str_replace('/', DIRECTORY_SEPARATOR, $path);
    }
}
PKϤ$Z'œ ��3filesystem/Tests/Fixtures/MockStream/MockStream.phpnu�[���<?php

/*
 * This file is part of the Symfony package.
 *
 * (c) Fabien Potencier <fabien@symfony.com>
 *
 * For the full copyright and license information, please view the LICENSE
 * file that was distributed with this source code.
 */

namespace Symfony\Component\Filesystem\Tests\Fixtures\MockStream;

/**
 * Mock stream class to be used with stream_wrapper_register.
 * stream_wrapper_register('mock', 'Symfony\Component\Filesystem\Tests\Fixtures\MockStream\MockStream').
 */
class MockStream
{
    /**
     * Opens file or URL.
     *
     * @param string $path        Specifies the URL that was passed to the original function
     * @param string $mode        The mode used to open the file, as detailed for fopen()
     * @param int    $options     Holds additional flags set by the streams API
     * @param string $opened_path If the path is opened successfully, and STREAM_USE_PATH is set in options,
     *                            opened_path should be set to the full path of the file/resource that was actually opened
     *
     * @return bool
     */
    public function stream_open($path, $mode, $options, &$opened_path)
    {
        return true;
    }

    /**
     * @param string $path  The file path or URL to stat
     * @param array  $flags Holds additional flags set by the streams API
     *
     * @return array File stats
     */
    public function url_stat($path, $flags)
    {
        return array();
    }
}
PKϤ$Z����'filesystem/Tests/FilesystemTestCase.phpnu�[���<?php

/*
 * This file is part of the Symfony package.
 *
 * (c) Fabien Potencier <fabien@symfony.com>
 *
 * For the full copyright and license information, please view the LICENSE
 * file that was distributed with this source code.
 */

namespace Symfony\Component\Filesystem\Tests;

use PHPUnit\Framework\TestCase;
use Symfony\Component\Filesystem\Filesystem;

class FilesystemTestCase extends TestCase
{
    private $umask;

    protected $longPathNamesWindows = array();

    /**
     * @var \Symfony\Component\Filesystem\Filesystem
     */
    protected $filesystem = null;

    /**
     * @var string
     */
    protected $workspace = null;

    /**
     * @var null|bool Flag for hard links on Windows
     */
    private static $linkOnWindows = null;

    /**
     * @var null|bool Flag for symbolic links on Windows
     */
    private static $symlinkOnWindows = null;

    public static function setUpBeforeClass()
    {
        if ('\\' === DIRECTORY_SEPARATOR) {
            self::$linkOnWindows = true;
            $originFile = tempnam(sys_get_temp_dir(), 'li');
            $targetFile = tempnam(sys_get_temp_dir(), 'li');
            if (true !== @link($originFile, $targetFile)) {
                $report = error_get_last();
                if (is_array($report) && false !== strpos($report['message'], 'error code(1314)')) {
                    self::$linkOnWindows = false;
                }
            } else {
                @unlink($targetFile);
            }

            self::$symlinkOnWindows = true;
            $originDir = tempnam(sys_get_temp_dir(), 'sl');
            $targetDir = tempnam(sys_get_temp_dir(), 'sl');
            if (true !== @symlink($originDir, $targetDir)) {
                $report = error_get_last();
                if (is_array($report) && false !== strpos($report['message'], 'error code(1314)')) {
                    self::$symlinkOnWindows = false;
                }
            } else {
                @unlink($targetDir);
            }
        }
    }

    protected function setUp()
    {
        $this->umask = umask(0);
        $this->filesystem = new Filesystem();
        $this->workspace = sys_get_temp_dir().'/'.microtime(true).'.'.mt_rand();
        mkdir($this->workspace, 0777, true);
        $this->workspace = realpath($this->workspace);
    }

    protected function tearDown()
    {
        if (!empty($this->longPathNamesWindows)) {
            foreach ($this->longPathNamesWindows as $path) {
                exec('DEL '.$path);
            }
            $this->longPathNamesWindows = array();
        }

        $this->filesystem->remove($this->workspace);
        umask($this->umask);
    }

    /**
     * @param int    $expectedFilePerms expected file permissions as three digits (i.e. 755)
     * @param string $filePath
     */
    protected function assertFilePermissions($expectedFilePerms, $filePath)
    {
        $actualFilePerms = (int) substr(sprintf('%o', fileperms($filePath)), -3);
        $this->assertEquals(
            $expectedFilePerms,
            $actualFilePerms,
            sprintf('File permissions for %s must be %s. Actual %s', $filePath, $expectedFilePerms, $actualFilePerms)
        );
    }

    protected function getFileOwner($filepath)
    {
        $this->markAsSkippedIfPosixIsMissing();

        $infos = stat($filepath);
        if ($datas = posix_getpwuid($infos['uid'])) {
            return $datas['name'];
        }
    }

    protected function getFileGroup($filepath)
    {
        $this->markAsSkippedIfPosixIsMissing();

        $infos = stat($filepath);
        if ($datas = posix_getgrgid($infos['gid'])) {
            return $datas['name'];
        }

        $this->markTestSkipped('Unable to retrieve file group name');
    }

    protected function markAsSkippedIfLinkIsMissing()
    {
        if (!function_exists('link')) {
            $this->markTestSkipped('link is not supported');
        }

        if ('\\' === DIRECTORY_SEPARATOR && false === self::$linkOnWindows) {
            $this->markTestSkipped('link requires "Create hard links" privilege on windows');
        }
    }

    protected function markAsSkippedIfSymlinkIsMissing($relative = false)
    {
        if ('\\' === DIRECTORY_SEPARATOR && false === self::$symlinkOnWindows) {
            $this->markTestSkipped('symlink requires "Create symbolic links" privilege on Windows');
        }

        // https://bugs.php.net/bug.php?id=69473
        if ($relative && '\\' === DIRECTORY_SEPARATOR && 1 === PHP_ZTS) {
            $this->markTestSkipped('symlink does not support relative paths on thread safe Windows PHP versions');
        }
    }

    protected function markAsSkippedIfChmodIsMissing()
    {
        if ('\\' === DIRECTORY_SEPARATOR) {
            $this->markTestSkipped('chmod is not supported on Windows');
        }
    }

    protected function markAsSkippedIfPosixIsMissing()
    {
        if (!function_exists('posix_isatty')) {
            $this->markTestSkipped('Function posix_isatty is required.');
        }
    }
}
PKϤ$Z�%`�@@$filesystem/Tests/LockHandlerTest.phpnu�[���<?php

/*
 * This file is part of the Symfony package.
 *
 * (c) Fabien Potencier <fabien@symfony.com>
 *
 * For the full copyright and license information, please view the LICENSE
 * file that was distributed with this source code.
 */

namespace Symfony\Component\Filesystem\Tests;

use PHPUnit\Framework\TestCase;
use Symfony\Component\Filesystem\Exception\IOException;
use Symfony\Component\Filesystem\Filesystem;
use Symfony\Component\Filesystem\LockHandler;

class LockHandlerTest extends TestCase
{
    /**
     * @expectedException \Symfony\Component\Filesystem\Exception\IOException
     * @expectedExceptionMessage Failed to create "/a/b/c/d/e": mkdir(): Permission denied.
     */
    public function testConstructWhenRepositoryDoesNotExist()
    {
        if (!getenv('USER') || 'root' === getenv('USER')) {
            $this->markTestSkipped('This test will fail if run under superuser');
        }
        new LockHandler('lock', '/a/b/c/d/e');
    }

    /**
     * @expectedException \Symfony\Component\Filesystem\Exception\IOException
     * @expectedExceptionMessage The directory "/" is not writable.
     */
    public function testConstructWhenRepositoryIsNotWriteable()
    {
        if (!getenv('USER') || 'root' === getenv('USER')) {
            $this->markTestSkipped('This test will fail if run under superuser');
        }
        new LockHandler('lock', '/');
    }

    public function testErrorHandlingInLockIfLockPathBecomesUnwritable()
    {
        // skip test on Windows; PHP can't easily set file as unreadable on Windows
        if ('\\' === DIRECTORY_SEPARATOR) {
            $this->markTestSkipped('This test cannot run on Windows.');
        }

        $lockPath = sys_get_temp_dir().'/'.uniqid('', true);
        $e = null;
        $wrongMessage = null;

        try {
            mkdir($lockPath);

            $lockHandler = new LockHandler('lock', $lockPath);

            chmod($lockPath, 0444);

            $lockHandler->lock();
        } catch (IOException $e) {
            if (false === strpos($e->getMessage(), 'Permission denied')) {
                $wrongMessage = $e->getMessage();
            } else {
                $this->addToAssertionCount(1);
            }
        } catch (\Exception $e) {
        } catch (\Throwable $e) {
        }

        if (is_dir($lockPath)) {
            $fs = new Filesystem();
            $fs->remove($lockPath);
        }

        $this->assertInstanceOf('Symfony\Component\Filesystem\Exception\IOException', $e, sprintf('Expected IOException to be thrown, got %s instead.', get_class($e)));
        $this->assertNull($wrongMessage, sprintf('Expected exception message to contain "Permission denied", got "%s" instead.', $wrongMessage));
    }

    public function testConstructSanitizeName()
    {
        $lock = new LockHandler('<?php echo "% hello word ! %" ?>');

        $file = sprintf('%s/sf.-php-echo-hello-word-.4b3d9d0d27ddef3a78a64685dda3a963e478659a9e5240feaf7b4173a8f28d5f.lock', sys_get_temp_dir());
        // ensure the file does not exist before the lock
        @unlink($file);

        $lock->lock();

        $this->assertFileExists($file);

        $lock->release();
    }

    public function testLockRelease()
    {
        $name = 'symfony-test-filesystem.lock';

        $l1 = new LockHandler($name);
        $l2 = new LockHandler($name);

        $this->assertTrue($l1->lock());
        $this->assertFalse($l2->lock());

        $l1->release();

        $this->assertTrue($l2->lock());
        $l2->release();
    }

    public function testLockTwice()
    {
        $name = 'symfony-test-filesystem.lock';

        $lockHandler = new LockHandler($name);

        $this->assertTrue($lockHandler->lock());
        $this->assertTrue($lockHandler->lock());

        $lockHandler->release();
    }

    public function testLockIsReleased()
    {
        $name = 'symfony-test-filesystem.lock';

        $l1 = new LockHandler($name);
        $l2 = new LockHandler($name);

        $this->assertTrue($l1->lock());
        $this->assertFalse($l2->lock());

        $l1 = null;

        $this->assertTrue($l2->lock());
        $l2->release();
    }
}
PKϤ$Z`9|��"filesystem/Tests/ExceptionTest.phpnu�[���<?php

/*
 * This file is part of the Symfony package.
 *
 * (c) Fabien Potencier <fabien@symfony.com>
 *
 * For the full copyright and license information, please view the LICENSE
 * file that was distributed with this source code.
 */

namespace Symfony\Component\Filesystem\Tests;

use PHPUnit\Framework\TestCase;
use Symfony\Component\Filesystem\Exception\IOException;
use Symfony\Component\Filesystem\Exception\FileNotFoundException;

/**
 * Test class for Filesystem.
 */
class ExceptionTest extends TestCase
{
    public function testGetPath()
    {
        $e = new IOException('', 0, null, '/foo');
        $this->assertEquals('/foo', $e->getPath(), 'The pass should be returned.');
    }

    public function testGeneratedMessage()
    {
        $e = new FileNotFoundException(null, 0, null, '/foo');
        $this->assertEquals('/foo', $e->getPath());
        $this->assertEquals('File "/foo" could not be found.', $e->getMessage(), 'A message should be generated.');
    }

    public function testGeneratedMessageWithoutPath()
    {
        $e = new FileNotFoundException();
        $this->assertEquals('File could not be found.', $e->getMessage(), 'A message should be generated.');
    }

    public function testCustomMessage()
    {
        $e = new FileNotFoundException('bar', 0, null, '/foo');
        $this->assertEquals('bar', $e->getMessage(), 'A custom message should be possible still.');
    }
}
PKϤ$Z�|�7

filesystem/LockHandler.phpnu�[���<?php

/*
 * This file is part of the Symfony package.
 *
 * (c) Fabien Potencier <fabien@symfony.com>
 *
 * For the full copyright and license information, please view the LICENSE
 * file that was distributed with this source code.
 */

namespace Symfony\Component\Filesystem;

use Symfony\Component\Filesystem\Exception\IOException;

/**
 * LockHandler class provides a simple abstraction to lock anything by means of
 * a file lock.
 *
 * A locked file is created based on the lock name when calling lock(). Other
 * lock handlers will not be able to lock the same name until it is released
 * (explicitly by calling release() or implicitly when the instance holding the
 * lock is destroyed).
 *
 * @author Grégoire Pineau <lyrixx@lyrixx.info>
 * @author Romain Neutron <imprec@gmail.com>
 * @author Nicolas Grekas <p@tchwork.com>
 */
class LockHandler
{
    private $file;
    private $handle;

    /**
     * @param string      $name     The lock name
     * @param string|null $lockPath The directory to store the lock. Default values will use temporary directory
     *
     * @throws IOException If the lock directory could not be created or is not writable
     */
    public function __construct($name, $lockPath = null)
    {
        $lockPath = $lockPath ?: sys_get_temp_dir();

        if (!is_dir($lockPath)) {
            $fs = new Filesystem();
            $fs->mkdir($lockPath);
        }

        if (!is_writable($lockPath)) {
            throw new IOException(sprintf('The directory "%s" is not writable.', $lockPath), 0, null, $lockPath);
        }

        $this->file = sprintf('%s/sf.%s.%s.lock', $lockPath, preg_replace('/[^a-z0-9\._-]+/i', '-', $name), hash('sha256', $name));
    }

    /**
     * Lock the resource.
     *
     * @param bool $blocking wait until the lock is released
     *
     * @return bool Returns true if the lock was acquired, false otherwise
     *
     * @throws IOException If the lock file could not be created or opened
     */
    public function lock($blocking = false)
    {
        if ($this->handle) {
            return true;
        }

        $error = null;

        // Silence error reporting
        set_error_handler(function ($errno, $msg) use (&$error) {
            $error = $msg;
        });

        if (!$this->handle = fopen($this->file, 'r')) {
            if ($this->handle = fopen($this->file, 'x')) {
                chmod($this->file, 0444);
            } elseif (!$this->handle = fopen($this->file, 'r')) {
                usleep(100); // Give some time for chmod() to complete
                $this->handle = fopen($this->file, 'r');
            }
        }
        restore_error_handler();

        if (!$this->handle) {
            throw new IOException($error, 0, null, $this->file);
        }

        // On Windows, even if PHP doc says the contrary, LOCK_NB works, see
        // https://bugs.php.net/54129
        if (!flock($this->handle, LOCK_EX | ($blocking ? 0 : LOCK_NB))) {
            fclose($this->handle);
            $this->handle = null;

            return false;
        }

        return true;
    }

    /**
     * Release the resource.
     */
    public function release()
    {
        if ($this->handle) {
            flock($this->handle, LOCK_UN | LOCK_NB);
            fclose($this->handle);
            $this->handle = null;
        }
    }
}
PKϤ$Z��-J��filesystem/README.mdnu�[���Filesystem Component
====================

The Filesystem component provides basic utilities for the filesystem.

Resources
---------

  * [Documentation](https://symfony.com/doc/current/components/filesystem.html)
  * [Contributing](https://symfony.com/doc/current/contributing/index.html)
  * [Report issues](https://github.com/symfony/symfony/issues) and
    [send Pull Requests](https://github.com/symfony/symfony/pulls)
    in the [main Symfony repository](https://github.com/symfony/symfony)
PKϤ$Z���jmjmfilesystem/Filesystem.phpnu�[���<?php

/*
 * This file is part of the Symfony package.
 *
 * (c) Fabien Potencier <fabien@symfony.com>
 *
 * For the full copyright and license information, please view the LICENSE
 * file that was distributed with this source code.
 */

namespace Symfony\Component\Filesystem;

use Symfony\Component\Filesystem\Exception\FileNotFoundException;
use Symfony\Component\Filesystem\Exception\InvalidArgumentException;
use Symfony\Component\Filesystem\Exception\IOException;

/**
 * Provides basic utility to manipulate the file system.
 *
 * @author Fabien Potencier <fabien@symfony.com>
 */
class Filesystem
{
    private static $lastError;

    /**
     * Copies a file.
     *
     * If the target file is older than the origin file, it's always overwritten.
     * If the target file is newer, it is overwritten only when the
     * $overwriteNewerFiles option is set to true.
     *
     * @throws FileNotFoundException When originFile doesn't exist
     * @throws IOException           When copy fails
     */
    public function copy(string $originFile, string $targetFile, bool $overwriteNewerFiles = false)
    {
        $originIsLocal = stream_is_local($originFile) || 0 === stripos($originFile, 'file://');
        if ($originIsLocal && !is_file($originFile)) {
            throw new FileNotFoundException(sprintf('Failed to copy "%s" because file does not exist.', $originFile), 0, null, $originFile);
        }

        $this->mkdir(\dirname($targetFile));

        $doCopy = true;
        if (!$overwriteNewerFiles && null === parse_url($originFile, PHP_URL_HOST) && is_file($targetFile)) {
            $doCopy = filemtime($originFile) > filemtime($targetFile);
        }

        if ($doCopy) {
            // https://bugs.php.net/64634
            if (false === $source = @fopen($originFile, 'r')) {
                throw new IOException(sprintf('Failed to copy "%s" to "%s" because source file could not be opened for reading.', $originFile, $targetFile), 0, null, $originFile);
            }

            // Stream context created to allow files overwrite when using FTP stream wrapper - disabled by default
            if (false === $target = @fopen($targetFile, 'w', null, stream_context_create(['ftp' => ['overwrite' => true]]))) {
                throw new IOException(sprintf('Failed to copy "%s" to "%s" because target file could not be opened for writing.', $originFile, $targetFile), 0, null, $originFile);
            }

            $bytesCopied = stream_copy_to_stream($source, $target);
            fclose($source);
            fclose($target);
            unset($source, $target);

            if (!is_file($targetFile)) {
                throw new IOException(sprintf('Failed to copy "%s" to "%s".', $originFile, $targetFile), 0, null, $originFile);
            }

            if ($originIsLocal) {
                // Like `cp`, preserve executable permission bits
                @chmod($targetFile, fileperms($targetFile) | (fileperms($originFile) & 0111));

                if ($bytesCopied !== $bytesOrigin = filesize($originFile)) {
                    throw new IOException(sprintf('Failed to copy the whole content of "%s" to "%s" (%g of %g bytes copied).', $originFile, $targetFile, $bytesCopied, $bytesOrigin), 0, null, $originFile);
                }
            }
        }
    }

    /**
     * Creates a directory recursively.
     *
     * @param string|iterable $dirs The directory path
     *
     * @throws IOException On any directory creation failure
     */
    public function mkdir($dirs, int $mode = 0777)
    {
        foreach ($this->toIterable($dirs) as $dir) {
            if (is_dir($dir)) {
                continue;
            }

            if (!self::box('mkdir', $dir, $mode, true)) {
                if (!is_dir($dir)) {
                    // The directory was not created by a concurrent process. Let's throw an exception with a developer friendly error message if we have one
                    if (self::$lastError) {
                        throw new IOException(sprintf('Failed to create "%s": '.self::$lastError, $dir), 0, null, $dir);
                    }
                    throw new IOException(sprintf('Failed to create "%s".', $dir), 0, null, $dir);
                }
            }
        }
    }

    /**
     * Checks the existence of files or directories.
     *
     * @param string|iterable $files A filename, an array of files, or a \Traversable instance to check
     *
     * @return bool true if the file exists, false otherwise
     */
    public function exists($files)
    {
        $maxPathLength = PHP_MAXPATHLEN - 2;

        foreach ($this->toIterable($files) as $file) {
            if (\strlen($file) > $maxPathLength) {
                throw new IOException(sprintf('Could not check if file exist because path length exceeds %d characters.', $maxPathLength), 0, null, $file);
            }

            if (!file_exists($file)) {
                return false;
            }
        }

        return true;
    }

    /**
     * Sets access and modification time of file.
     *
     * @param string|iterable $files A filename, an array of files, or a \Traversable instance to create
     * @param int|null        $time  The touch time as a Unix timestamp, if not supplied the current system time is used
     * @param int|null        $atime The access time as a Unix timestamp, if not supplied the current system time is used
     *
     * @throws IOException When touch fails
     */
    public function touch($files, int $time = null, int $atime = null)
    {
        foreach ($this->toIterable($files) as $file) {
            $touch = $time ? @touch($file, $time, $atime) : @touch($file);
            if (true !== $touch) {
                throw new IOException(sprintf('Failed to touch "%s".', $file), 0, null, $file);
            }
        }
    }

    /**
     * Removes files or directories.
     *
     * @param string|iterable $files A filename, an array of files, or a \Traversable instance to remove
     *
     * @throws IOException When removal fails
     */
    public function remove($files)
    {
        if ($files instanceof \Traversable) {
            $files = iterator_to_array($files, false);
        } elseif (!\is_array($files)) {
            $files = [$files];
        }
        $files = array_reverse($files);
        foreach ($files as $file) {
            if (is_link($file)) {
                // See https://bugs.php.net/52176
                if (!(self::box('unlink', $file) || '\\' !== \DIRECTORY_SEPARATOR || self::box('rmdir', $file)) && file_exists($file)) {
                    throw new IOException(sprintf('Failed to remove symlink "%s": '.self::$lastError, $file));
                }
            } elseif (is_dir($file)) {
                $this->remove(new \FilesystemIterator($file, \FilesystemIterator::CURRENT_AS_PATHNAME | \FilesystemIterator::SKIP_DOTS));

                if (!self::box('rmdir', $file) && file_exists($file)) {
                    throw new IOException(sprintf('Failed to remove directory "%s": '.self::$lastError, $file));
                }
            } elseif (!self::box('unlink', $file) && file_exists($file)) {
                throw new IOException(sprintf('Failed to remove file "%s": '.self::$lastError, $file));
            }
        }
    }

    /**
     * Change mode for an array of files or directories.
     *
     * @param string|iterable $files     A filename, an array of files, or a \Traversable instance to change mode
     * @param int             $mode      The new mode (octal)
     * @param int             $umask     The mode mask (octal)
     * @param bool            $recursive Whether change the mod recursively or not
     *
     * @throws IOException When the change fails
     */
    public function chmod($files, int $mode, int $umask = 0000, bool $recursive = false)
    {
        foreach ($this->toIterable($files) as $file) {
            if (true !== @chmod($file, $mode & ~$umask)) {
                throw new IOException(sprintf('Failed to chmod file "%s".', $file), 0, null, $file);
            }
            if ($recursive && is_dir($file) && !is_link($file)) {
                $this->chmod(new \FilesystemIterator($file), $mode, $umask, true);
            }
        }
    }

    /**
     * Change the owner of an array of files or directories.
     *
     * @param string|iterable $files     A filename, an array of files, or a \Traversable instance to change owner
     * @param string|int      $user      A user name or number
     * @param bool            $recursive Whether change the owner recursively or not
     *
     * @throws IOException When the change fails
     */
    public function chown($files, $user, bool $recursive = false)
    {
        foreach ($this->toIterable($files) as $file) {
            if ($recursive && is_dir($file) && !is_link($file)) {
                $this->chown(new \FilesystemIterator($file), $user, true);
            }
            if (is_link($file) && \function_exists('lchown')) {
                if (true !== @lchown($file, $user)) {
                    throw new IOException(sprintf('Failed to chown file "%s".', $file), 0, null, $file);
                }
            } else {
                if (true !== @chown($file, $user)) {
                    throw new IOException(sprintf('Failed to chown file "%s".', $file), 0, null, $file);
                }
            }
        }
    }

    /**
     * Change the group of an array of files or directories.
     *
     * @param string|iterable $files     A filename, an array of files, or a \Traversable instance to change group
     * @param string|int      $group     A group name or number
     * @param bool            $recursive Whether change the group recursively or not
     *
     * @throws IOException When the change fails
     */
    public function chgrp($files, $group, bool $recursive = false)
    {
        foreach ($this->toIterable($files) as $file) {
            if ($recursive && is_dir($file) && !is_link($file)) {
                $this->chgrp(new \FilesystemIterator($file), $group, true);
            }
            if (is_link($file) && \function_exists('lchgrp')) {
                if (true !== @lchgrp($file, $group)) {
                    throw new IOException(sprintf('Failed to chgrp file "%s".', $file), 0, null, $file);
                }
            } else {
                if (true !== @chgrp($file, $group)) {
                    throw new IOException(sprintf('Failed to chgrp file "%s".', $file), 0, null, $file);
                }
            }
        }
    }

    /**
     * Renames a file or a directory.
     *
     * @throws IOException When target file or directory already exists
     * @throws IOException When origin cannot be renamed
     */
    public function rename(string $origin, string $target, bool $overwrite = false)
    {
        // we check that target does not exist
        if (!$overwrite && $this->isReadable($target)) {
            throw new IOException(sprintf('Cannot rename because the target "%s" already exists.', $target), 0, null, $target);
        }

        if (true !== @rename($origin, $target)) {
            if (is_dir($origin)) {
                // See https://bugs.php.net/54097 & https://php.net/rename#113943
                $this->mirror($origin, $target, null, ['override' => $overwrite, 'delete' => $overwrite]);
                $this->remove($origin);

                return;
            }
            throw new IOException(sprintf('Cannot rename "%s" to "%s".', $origin, $target), 0, null, $target);
        }
    }

    /**
     * Tells whether a file exists and is readable.
     *
     * @throws IOException When windows path is longer than 258 characters
     */
    private function isReadable(string $filename): bool
    {
        $maxPathLength = PHP_MAXPATHLEN - 2;

        if (\strlen($filename) > $maxPathLength) {
            throw new IOException(sprintf('Could not check if file is readable because path length exceeds %d characters.', $maxPathLength), 0, null, $filename);
        }

        return is_readable($filename);
    }

    /**
     * Creates a symbolic link or copy a directory.
     *
     * @throws IOException When symlink fails
     */
    public function symlink(string $originDir, string $targetDir, bool $copyOnWindows = false)
    {
        if ('\\' === \DIRECTORY_SEPARATOR) {
            $originDir = strtr($originDir, '/', '\\');
            $targetDir = strtr($targetDir, '/', '\\');

            if ($copyOnWindows) {
                $this->mirror($originDir, $targetDir);

                return;
            }
        }

        $this->mkdir(\dirname($targetDir));

        if (is_link($targetDir)) {
            if (readlink($targetDir) === $originDir) {
                return;
            }
            $this->remove($targetDir);
        }

        if (!self::box('symlink', $originDir, $targetDir)) {
            $this->linkException($originDir, $targetDir, 'symbolic');
        }
    }

    /**
     * Creates a hard link, or several hard links to a file.
     *
     * @param string|string[] $targetFiles The target file(s)
     *
     * @throws FileNotFoundException When original file is missing or not a file
     * @throws IOException           When link fails, including if link already exists
     */
    public function hardlink(string $originFile, $targetFiles)
    {
        if (!$this->exists($originFile)) {
            throw new FileNotFoundException(null, 0, null, $originFile);
        }

        if (!is_file($originFile)) {
            throw new FileNotFoundException(sprintf('Origin file "%s" is not a file.', $originFile));
        }

        foreach ($this->toIterable($targetFiles) as $targetFile) {
            if (is_file($targetFile)) {
                if (fileinode($originFile) === fileinode($targetFile)) {
                    continue;
                }
                $this->remove($targetFile);
            }

            if (!self::box('link', $originFile, $targetFile)) {
                $this->linkException($originFile, $targetFile, 'hard');
            }
        }
    }

    /**
     * @param string $linkType Name of the link type, typically 'symbolic' or 'hard'
     */
    private function linkException(string $origin, string $target, string $linkType)
    {
        if (self::$lastError) {
            if ('\\' === \DIRECTORY_SEPARATOR && false !== strpos(self::$lastError, 'error code(1314)')) {
                throw new IOException(sprintf('Unable to create "%s" link due to error code 1314: \'A required privilege is not held by the client\'. Do you have the required Administrator-rights?', $linkType), 0, null, $target);
            }
        }
        throw new IOException(sprintf('Failed to create "%s" link from "%s" to "%s".', $linkType, $origin, $target), 0, null, $target);
    }

    /**
     * Resolves links in paths.
     *
     * With $canonicalize = false (default)
     *      - if $path does not exist or is not a link, returns null
     *      - if $path is a link, returns the next direct target of the link without considering the existence of the target
     *
     * With $canonicalize = true
     *      - if $path does not exist, returns null
     *      - if $path exists, returns its absolute fully resolved final version
     *
     * @return string|null
     */
    public function readlink(string $path, bool $canonicalize = false)
    {
        if (!$canonicalize && !is_link($path)) {
            return null;
        }

        if ($canonicalize) {
            if (!$this->exists($path)) {
                return null;
            }

            if ('\\' === \DIRECTORY_SEPARATOR) {
                $path = readlink($path);
            }

            return realpath($path);
        }

        if ('\\' === \DIRECTORY_SEPARATOR) {
            return realpath($path);
        }

        return readlink($path);
    }

    /**
     * Given an existing path, convert it to a path relative to a given starting path.
     *
     * @return string Path of target relative to starting path
     */
    public function makePathRelative(string $endPath, string $startPath)
    {
        if (!$this->isAbsolutePath($startPath)) {
            throw new InvalidArgumentException(sprintf('The start path "%s" is not absolute.', $startPath));
        }

        if (!$this->isAbsolutePath($endPath)) {
            throw new InvalidArgumentException(sprintf('The end path "%s" is not absolute.', $endPath));
        }

        // Normalize separators on Windows
        if ('\\' === \DIRECTORY_SEPARATOR) {
            $endPath = str_replace('\\', '/', $endPath);
            $startPath = str_replace('\\', '/', $startPath);
        }

        $stripDriveLetter = function ($path) {
            if (\strlen($path) > 2 && ':' === $path[1] && '/' === $path[2] && ctype_alpha($path[0])) {
                return substr($path, 2);
            }

            return $path;
        };

        $endPath = $stripDriveLetter($endPath);
        $startPath = $stripDriveLetter($startPath);

        // Split the paths into arrays
        $startPathArr = explode('/', trim($startPath, '/'));
        $endPathArr = explode('/', trim($endPath, '/'));

        $normalizePathArray = function ($pathSegments) {
            $result = [];

            foreach ($pathSegments as $segment) {
                if ('..' === $segment) {
                    array_pop($result);
                } elseif ('.' !== $segment) {
                    $result[] = $segment;
                }
            }

            return $result;
        };

        $startPathArr = $normalizePathArray($startPathArr);
        $endPathArr = $normalizePathArray($endPathArr);

        // Find for which directory the common path stops
        $index = 0;
        while (isset($startPathArr[$index]) && isset($endPathArr[$index]) && $startPathArr[$index] === $endPathArr[$index]) {
            ++$index;
        }

        // Determine how deep the start path is relative to the common path (ie, "web/bundles" = 2 levels)
        if (1 === \count($startPathArr) && '' === $startPathArr[0]) {
            $depth = 0;
        } else {
            $depth = \count($startPathArr) - $index;
        }

        // Repeated "../" for each level need to reach the common path
        $traverser = str_repeat('../', $depth);

        $endPathRemainder = implode('/', \array_slice($endPathArr, $index));

        // Construct $endPath from traversing to the common path, then to the remaining $endPath
        $relativePath = $traverser.('' !== $endPathRemainder ? $endPathRemainder.'/' : '');

        return '' === $relativePath ? './' : $relativePath;
    }

    /**
     * Mirrors a directory to another.
     *
     * Copies files and directories from the origin directory into the target directory. By default:
     *
     *  - existing files in the target directory will be overwritten, except if they are newer (see the `override` option)
     *  - files in the target directory that do not exist in the source directory will not be deleted (see the `delete` option)
     *
     * @param \Traversable|null $iterator Iterator that filters which files and directories to copy, if null a recursive iterator is created
     * @param array             $options  An array of boolean options
     *                                    Valid options are:
     *                                    - $options['override'] If true, target files newer than origin files are overwritten (see copy(), defaults to false)
     *                                    - $options['copy_on_windows'] Whether to copy files instead of links on Windows (see symlink(), defaults to false)
     *                                    - $options['delete'] Whether to delete files that are not in the source directory (defaults to false)
     *
     * @throws IOException When file type is unknown
     */
    public function mirror(string $originDir, string $targetDir, \Traversable $iterator = null, array $options = [])
    {
        $targetDir = rtrim($targetDir, '/\\');
        $originDir = rtrim($originDir, '/\\');
        $originDirLen = \strlen($originDir);

        if (!$this->exists($originDir)) {
            throw new IOException(sprintf('The origin directory specified "%s" was not found.', $originDir), 0, null, $originDir);
        }

        // Iterate in destination folder to remove obsolete entries
        if ($this->exists($targetDir) && isset($options['delete']) && $options['delete']) {
            $deleteIterator = $iterator;
            if (null === $deleteIterator) {
                $flags = \FilesystemIterator::SKIP_DOTS;
                $deleteIterator = new \RecursiveIteratorIterator(new \RecursiveDirectoryIterator($targetDir, $flags), \RecursiveIteratorIterator::CHILD_FIRST);
            }
            $targetDirLen = \strlen($targetDir);
            foreach ($deleteIterator as $file) {
                $origin = $originDir.substr($file->getPathname(), $targetDirLen);
                if (!$this->exists($origin)) {
                    $this->remove($file);
                }
            }
        }

        $copyOnWindows = $options['copy_on_windows'] ?? false;

        if (null === $iterator) {
            $flags = $copyOnWindows ? \FilesystemIterator::SKIP_DOTS | \FilesystemIterator::FOLLOW_SYMLINKS : \FilesystemIterator::SKIP_DOTS;
            $iterator = new \RecursiveIteratorIterator(new \RecursiveDirectoryIterator($originDir, $flags), \RecursiveIteratorIterator::SELF_FIRST);
        }

        $this->mkdir($targetDir);
        $filesCreatedWhileMirroring = [];

        foreach ($iterator as $file) {
            if ($file->getPathname() === $targetDir || $file->getRealPath() === $targetDir || isset($filesCreatedWhileMirroring[$file->getRealPath()])) {
                continue;
            }

            $target = $targetDir.substr($file->getPathname(), $originDirLen);
            $filesCreatedWhileMirroring[$target] = true;

            if (!$copyOnWindows && is_link($file)) {
                $this->symlink($file->getLinkTarget(), $target);
            } elseif (is_dir($file)) {
                $this->mkdir($target);
            } elseif (is_file($file)) {
                $this->copy($file, $target, isset($options['override']) ? $options['override'] : false);
            } else {
                throw new IOException(sprintf('Unable to guess "%s" file type.', $file), 0, null, $file);
            }
        }
    }

    /**
     * Returns whether the file path is an absolute path.
     *
     * @return bool
     */
    public function isAbsolutePath(string $file)
    {
        return strspn($file, '/\\', 0, 1)
            || (\strlen($file) > 3 && ctype_alpha($file[0])
                && ':' === $file[1]
                && strspn($file, '/\\', 2, 1)
            )
            || null !== parse_url($file, PHP_URL_SCHEME)
        ;
    }

    /**
     * Creates a temporary file with support for custom stream wrappers.
     *
     * @param string $prefix The prefix of the generated temporary filename
     *                       Note: Windows uses only the first three characters of prefix
     *
     * @return string The new temporary filename (with path), or throw an exception on failure
     */
    public function tempnam(string $dir, string $prefix)
    {
        list($scheme, $hierarchy) = $this->getSchemeAndHierarchy($dir);

        // If no scheme or scheme is "file" or "gs" (Google Cloud) create temp file in local filesystem
        if (null === $scheme || 'file' === $scheme || 'gs' === $scheme) {
            $tmpFile = @tempnam($hierarchy, $prefix);

            // If tempnam failed or no scheme return the filename otherwise prepend the scheme
            if (false !== $tmpFile) {
                if (null !== $scheme && 'gs' !== $scheme) {
                    return $scheme.'://'.$tmpFile;
                }

                return $tmpFile;
            }

            throw new IOException('A temporary file could not be created.');
        }

        // Loop until we create a valid temp file or have reached 10 attempts
        for ($i = 0; $i < 10; ++$i) {
            // Create a unique filename
            $tmpFile = $dir.'/'.$prefix.uniqid(mt_rand(), true);

            // Use fopen instead of file_exists as some streams do not support stat
            // Use mode 'x+' to atomically check existence and create to avoid a TOCTOU vulnerability
            $handle = @fopen($tmpFile, 'x+');

            // If unsuccessful restart the loop
            if (false === $handle) {
                continue;
            }

            // Close the file if it was successfully opened
            @fclose($handle);

            return $tmpFile;
        }

        throw new IOException('A temporary file could not be created.');
    }

    /**
     * Atomically dumps content into a file.
     *
     * @param string|resource $content The data to write into the file
     *
     * @throws IOException if the file cannot be written to
     */
    public function dumpFile(string $filename, $content)
    {
        if (\is_array($content)) {
            throw new \TypeError(sprintf('Argument 2 passed to "%s()" must be string or resource, array given.', __METHOD__));
        }

        $dir = \dirname($filename);

        if (!is_dir($dir)) {
            $this->mkdir($dir);
        }

        if (!is_writable($dir)) {
            throw new IOException(sprintf('Unable to write to the "%s" directory.', $dir), 0, null, $dir);
        }

        // Will create a temp file with 0600 access rights
        // when the filesystem supports chmod.
        $tmpFile = $this->tempnam($dir, basename($filename));

        if (false === @file_put_contents($tmpFile, $content)) {
            throw new IOException(sprintf('Failed to write file "%s".', $filename), 0, null, $filename);
        }

        @chmod($tmpFile, file_exists($filename) ? fileperms($filename) : 0666 & ~umask());

        $this->rename($tmpFile, $filename, true);
    }

    /**
     * Appends content to an existing file.
     *
     * @param string|resource $content The content to append
     *
     * @throws IOException If the file is not writable
     */
    public function appendToFile(string $filename, $content)
    {
        if (\is_array($content)) {
            throw new \TypeError(sprintf('Argument 2 passed to "%s()" must be string or resource, array given.', __METHOD__));
        }

        $dir = \dirname($filename);

        if (!is_dir($dir)) {
            $this->mkdir($dir);
        }

        if (!is_writable($dir)) {
            throw new IOException(sprintf('Unable to write to the "%s" directory.', $dir), 0, null, $dir);
        }

        if (false === @file_put_contents($filename, $content, FILE_APPEND)) {
            throw new IOException(sprintf('Failed to write file "%s".', $filename), 0, null, $filename);
        }
    }

    private function toIterable($files): iterable
    {
        return \is_array($files) || $files instanceof \Traversable ? $files : [$files];
    }

    /**
     * Gets a 2-tuple of scheme (may be null) and hierarchical part of a filename (e.g. file:///tmp -> [file, tmp]).
     */
    private function getSchemeAndHierarchy(string $filename): array
    {
        $components = explode('://', $filename, 2);

        return 2 === \count($components) ? [$components[0], $components[1]] : [null, $components[0]];
    }

    /**
     * @return mixed
     */
    private static function box(callable $func)
    {
        self::$lastError = null;
        set_error_handler(__CLASS__.'::handleError');
        try {
            $result = $func(...\array_slice(\func_get_args(), 1));
            restore_error_handler();

            return $result;
        } catch (\Throwable $e) {
        }
        restore_error_handler();

        throw $e;
    }

    /**
     * @internal
     */
    public static function handleError($type, $msg)
    {
        self::$lastError = $msg;
    }
}
PKϤ$Z
n�j��+filesystem/Exception/ExceptionInterface.phpnu�[���<?php

/*
 * This file is part of the Symfony package.
 *
 * (c) Fabien Potencier <fabien@symfony.com>
 *
 * For the full copyright and license information, please view the LICENSE
 * file that was distributed with this source code.
 */

namespace Symfony\Component\Filesystem\Exception;

/**
 * Exception interface for all exceptions thrown by the component.
 *
 * @author Romain Neutron <imprec@gmail.com>
 */
interface ExceptionInterface extends \Throwable
{
}
PKϤ$Z�*����1filesystem/Exception/InvalidArgumentException.phpnu�[���<?php

/*
 * This file is part of the Symfony package.
 *
 * (c) Fabien Potencier <fabien@symfony.com>
 *
 * For the full copyright and license information, please view the LICENSE
 * file that was distributed with this source code.
 */

namespace Symfony\Component\Filesystem\Exception;

/**
 * @author Christian Flothmann <christian.flothmann@sensiolabs.de>
 */
class InvalidArgumentException extends \InvalidArgumentException implements ExceptionInterface
{
}
PKϤ$ZHD���$filesystem/Exception/IOException.phpnu�[���<?php

/*
 * This file is part of the Symfony package.
 *
 * (c) Fabien Potencier <fabien@symfony.com>
 *
 * For the full copyright and license information, please view the LICENSE
 * file that was distributed with this source code.
 */

namespace Symfony\Component\Filesystem\Exception;

/**
 * Exception class thrown when a filesystem operation failure happens.
 *
 * @author Romain Neutron <imprec@gmail.com>
 * @author Christian Gärtner <christiangaertner.film@googlemail.com>
 * @author Fabien Potencier <fabien@symfony.com>
 */
class IOException extends \RuntimeException implements IOExceptionInterface
{
    private $path;

    public function __construct(string $message, int $code = 0, \Throwable $previous = null, string $path = null)
    {
        $this->path = $path;

        parent::__construct($message, $code, $previous);
    }

    /**
     * {@inheritdoc}
     */
    public function getPath()
    {
        return $this->path;
    }
}
PKϤ$Z��i���-filesystem/Exception/IOExceptionInterface.phpnu�[���<?php

/*
 * This file is part of the Symfony package.
 *
 * (c) Fabien Potencier <fabien@symfony.com>
 *
 * For the full copyright and license information, please view the LICENSE
 * file that was distributed with this source code.
 */

namespace Symfony\Component\Filesystem\Exception;

/**
 * IOException interface for file and input/output stream related exceptions thrown by the component.
 *
 * @author Christian Gärtner <christiangaertner.film@googlemail.com>
 */
interface IOExceptionInterface extends ExceptionInterface
{
    /**
     * Returns the associated path for the exception.
     *
     * @return string|null The path
     */
    public function getPath();
}
PKϤ$ZFʹ��.filesystem/Exception/FileNotFoundException.phpnu�[���<?php

/*
 * This file is part of the Symfony package.
 *
 * (c) Fabien Potencier <fabien@symfony.com>
 *
 * For the full copyright and license information, please view the LICENSE
 * file that was distributed with this source code.
 */

namespace Symfony\Component\Filesystem\Exception;

/**
 * Exception class thrown when a file couldn't be found.
 *
 * @author Fabien Potencier <fabien@symfony.com>
 * @author Christian Gärtner <christiangaertner.film@googlemail.com>
 */
class FileNotFoundException extends IOException
{
    public function __construct(string $message = null, int $code = 0, \Throwable $previous = null, string $path = null)
    {
        if (null === $message) {
            if (null === $path) {
                $message = 'File could not be found.';
            } else {
                $message = sprintf('File "%s" could not be found.', $path);
            }
        }

        parent::__construct($message, $code, $previous, $path);
    }
}
PKϤ$Z���[��filesystem/CHANGELOG.mdnu�[���CHANGELOG
=========

5.0.0
-----

 * `Filesystem::dumpFile()` and `appendToFile()` don't accept arrays anymore

4.4.0
-----

 * support for passing a `null` value to `Filesystem::isAbsolutePath()` is deprecated and will be removed in 5.0

4.3.0
-----

 * support for passing arrays to `Filesystem::dumpFile()` is deprecated and will be removed in 5.0
 * support for passing arrays to `Filesystem::appendToFile()` is deprecated and will be removed in 5.0

4.0.0
-----

 * removed `LockHandler`
 * Support for passing relative paths to `Filesystem::makePathRelative()` has been removed.

3.4.0
-----

 * support for passing relative paths to `Filesystem::makePathRelative()` is deprecated and will be removed in 4.0

3.3.0
-----

 * added `appendToFile()` to append contents to existing files

3.2.0
-----

 * added `readlink()` as a platform independent method to read links

3.0.0
-----

 * removed `$mode` argument from `Filesystem::dumpFile()`

2.8.0
-----

 * added tempnam() a stream aware version of PHP's native tempnam()

2.6.0
-----

 * added LockHandler

2.3.12
------

 * deprecated dumpFile() file mode argument.

2.3.0
-----

 * added the dumpFile() method to atomically write files

2.2.0
-----

 * added a delete option for the mirror() method

2.1.0
-----

 * 24eb396 : BC Break : mkdir() function now throws exception in case of failure instead of returning Boolean value
 * created the component
PKϤ$Z=��))filesystem/LICENSEnu�[���Copyright (c) 2004-2020 Fabien Potencier

Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is furnished
to do so, subject to the following conditions:

The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.

THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
THE SOFTWARE.
PKϤ$Z��w"w" translation/MessageCatalogue.phpnu�[���<?php

/*
 * This file is part of the Symfony package.
 *
 * (c) Fabien Potencier <fabien@symfony.com>
 *
 * For the full copyright and license information, please view the LICENSE
 * file that was distributed with this source code.
 */

namespace Symfony\Component\Translation;

use Symfony\Component\Config\Resource\ResourceInterface;
use Symfony\Component\Translation\Exception\LogicException;

/**
 * @author Fabien Potencier <fabien@symfony.com>
 */
class MessageCatalogue implements MessageCatalogueInterface, MetadataAwareInterface
{
    private $messages = [];
    private $metadata = [];
    private $resources = [];
    private $locale;
    private $fallbackCatalogue;
    private $parent;

    /**
     * @param string $locale   The locale
     * @param array  $messages An array of messages classified by domain
     */
    public function __construct(string $locale, array $messages = [])
    {
        $this->locale = $locale;
        $this->messages = $messages;
    }

    /**
     * {@inheritdoc}
     */
    public function getLocale()
    {
        return $this->locale;
    }

    /**
     * {@inheritdoc}
     */
    public function getDomains()
    {
        $domains = [];
        $suffixLength = \strlen(self::INTL_DOMAIN_SUFFIX);

        foreach ($this->messages as $domain => $messages) {
            if (\strlen($domain) > $suffixLength && false !== $i = strpos($domain, self::INTL_DOMAIN_SUFFIX, -$suffixLength)) {
                $domain = substr($domain, 0, $i);
            }
            $domains[$domain] = $domain;
        }

        return array_values($domains);
    }

    /**
     * {@inheritdoc}
     */
    public function all(string $domain = null)
    {
        if (null !== $domain) {
            return ($this->messages[$domain.self::INTL_DOMAIN_SUFFIX] ?? []) + ($this->messages[$domain] ?? []);
        }

        $allMessages = [];
        $suffixLength = \strlen(self::INTL_DOMAIN_SUFFIX);

        foreach ($this->messages as $domain => $messages) {
            if (\strlen($domain) > $suffixLength && false !== $i = strpos($domain, self::INTL_DOMAIN_SUFFIX, -$suffixLength)) {
                $domain = substr($domain, 0, $i);
                $allMessages[$domain] = $messages + ($allMessages[$domain] ?? []);
            } else {
                $allMessages[$domain] = ($allMessages[$domain] ?? []) + $messages;
            }
        }

        return $allMessages;
    }

    /**
     * {@inheritdoc}
     */
    public function set(string $id, string $translation, string $domain = 'messages')
    {
        $this->add([$id => $translation], $domain);
    }

    /**
     * {@inheritdoc}
     */
    public function has(string $id, string $domain = 'messages')
    {
        if (isset($this->messages[$domain][$id]) || isset($this->messages[$domain.self::INTL_DOMAIN_SUFFIX][$id])) {
            return true;
        }

        if (null !== $this->fallbackCatalogue) {
            return $this->fallbackCatalogue->has($id, $domain);
        }

        return false;
    }

    /**
     * {@inheritdoc}
     */
    public function defines(string $id, string $domain = 'messages')
    {
        return isset($this->messages[$domain][$id]) || isset($this->messages[$domain.self::INTL_DOMAIN_SUFFIX][$id]);
    }

    /**
     * {@inheritdoc}
     */
    public function get(string $id, string $domain = 'messages')
    {
        if (isset($this->messages[$domain.self::INTL_DOMAIN_SUFFIX][$id])) {
            return $this->messages[$domain.self::INTL_DOMAIN_SUFFIX][$id];
        }

        if (isset($this->messages[$domain][$id])) {
            return $this->messages[$domain][$id];
        }

        if (null !== $this->fallbackCatalogue) {
            return $this->fallbackCatalogue->get($id, $domain);
        }

        return $id;
    }

    /**
     * {@inheritdoc}
     */
    public function replace(array $messages, string $domain = 'messages')
    {
        unset($this->messages[$domain], $this->messages[$domain.self::INTL_DOMAIN_SUFFIX]);

        $this->add($messages, $domain);
    }

    /**
     * {@inheritdoc}
     */
    public function add(array $messages, string $domain = 'messages')
    {
        if (!isset($this->messages[$domain])) {
            $this->messages[$domain] = [];
        }
        $intlDomain = $domain;
        $suffixLength = \strlen(self::INTL_DOMAIN_SUFFIX);
        if (\strlen($domain) > $suffixLength && false !== strpos($domain, self::INTL_DOMAIN_SUFFIX, -$suffixLength)) {
            $intlDomain .= self::INTL_DOMAIN_SUFFIX;
        }
        foreach ($messages as $id => $message) {
            if (isset($this->messages[$intlDomain]) && \array_key_exists($id, $this->messages[$intlDomain])) {
                $this->messages[$intlDomain][$id] = $message;
            } else {
                $this->messages[$domain][$id] = $message;
            }
        }
    }

    /**
     * {@inheritdoc}
     */
    public function addCatalogue(MessageCatalogueInterface $catalogue)
    {
        if ($catalogue->getLocale() !== $this->locale) {
            throw new LogicException(sprintf('Cannot add a catalogue for locale "%s" as the current locale for this catalogue is "%s".', $catalogue->getLocale(), $this->locale));
        }

        foreach ($catalogue->all() as $domain => $messages) {
            if ($intlMessages = $catalogue->all($domain.self::INTL_DOMAIN_SUFFIX)) {
                $this->add($intlMessages, $domain.self::INTL_DOMAIN_SUFFIX);
                $messages = array_diff_key($messages, $intlMessages);
            }
            $this->add($messages, $domain);
        }

        foreach ($catalogue->getResources() as $resource) {
            $this->addResource($resource);
        }

        if ($catalogue instanceof MetadataAwareInterface) {
            $metadata = $catalogue->getMetadata('', '');
            $this->addMetadata($metadata);
        }
    }

    /**
     * {@inheritdoc}
     */
    public function addFallbackCatalogue(MessageCatalogueInterface $catalogue)
    {
        // detect circular references
        $c = $catalogue;
        while ($c = $c->getFallbackCatalogue()) {
            if ($c->getLocale() === $this->getLocale()) {
                throw new LogicException(sprintf('Circular reference detected when adding a fallback catalogue for locale "%s".', $catalogue->getLocale()));
            }
        }

        $c = $this;
        do {
            if ($c->getLocale() === $catalogue->getLocale()) {
                throw new LogicException(sprintf('Circular reference detected when adding a fallback catalogue for locale "%s".', $catalogue->getLocale()));
            }

            foreach ($catalogue->getResources() as $resource) {
                $c->addResource($resource);
            }
        } while ($c = $c->parent);

        $catalogue->parent = $this;
        $this->fallbackCatalogue = $catalogue;

        foreach ($catalogue->getResources() as $resource) {
            $this->addResource($resource);
        }
    }

    /**
     * {@inheritdoc}
     */
    public function getFallbackCatalogue()
    {
        return $this->fallbackCatalogue;
    }

    /**
     * {@inheritdoc}
     */
    public function getResources()
    {
        return array_values($this->resources);
    }

    /**
     * {@inheritdoc}
     */
    public function addResource(ResourceInterface $resource)
    {
        $this->resources[$resource->__toString()] = $resource;
    }

    /**
     * {@inheritdoc}
     */
    public function getMetadata(string $key = '', string $domain = 'messages')
    {
        if ('' == $domain) {
            return $this->metadata;
        }

        if (isset($this->metadata[$domain])) {
            if ('' == $key) {
                return $this->metadata[$domain];
            }

            if (isset($this->metadata[$domain][$key])) {
                return $this->metadata[$domain][$key];
            }
        }

        return null;
    }

    /**
     * {@inheritdoc}
     */
    public function setMetadata(string $key, $value, string $domain = 'messages')
    {
        $this->metadata[$domain][$key] = $value;
    }

    /**
     * {@inheritdoc}
     */
    public function deleteMetadata(string $key = '', string $domain = 'messages')
    {
        if ('' == $domain) {
            $this->metadata = [];
        } elseif ('' == $key) {
            unset($this->metadata[$domain]);
        } else {
            unset($this->metadata[$domain][$key]);
        }
    }

    /**
     * Adds current values with the new values.
     *
     * @param array $values Values to add
     */
    private function addMetadata(array $values)
    {
        foreach ($values as $domain => $keys) {
            foreach ($keys as $key => $value) {
                $this->setMetadata($key, $value, $domain);
            }
        }
    }
}
PKϤ$Z��߄��,translation/Tests/IdentityTranslatorTest.phpnu�[���<?php

/*
 * This file is part of the Symfony package.
 *
 * (c) Fabien Potencier <fabien@symfony.com>
 *
 * For the full copyright and license information, please view the LICENSE
 * file that was distributed with this source code.
 */

namespace Symfony\Component\Translation\Tests;

use Symfony\Component\Intl\Util\IntlTestHelper;
use Symfony\Component\Translation\IdentityTranslator;

class IdentityTranslatorTest extends \PHPUnit_Framework_TestCase
{
    /**
     * @dataProvider getTransTests
     */
    public function testTrans($expected, $id, $parameters)
    {
        $translator = new IdentityTranslator();

        $this->assertEquals($expected, $translator->trans($id, $parameters));
    }

    /**
     * @dataProvider getTransChoiceTests
     */
    public function testTransChoiceWithExplicitLocale($expected, $id, $number, $parameters)
    {
        $translator = new IdentityTranslator();
        $translator->setLocale('en');

        $this->assertEquals($expected, $translator->transChoice($id, $number, $parameters));
    }

    /**
     * @dataProvider getTransChoiceTests
     */
    public function testTransChoiceWithDefaultLocale($expected, $id, $number, $parameters)
    {
        \Locale::setDefault('en');

        $translator = new IdentityTranslator();

        $this->assertEquals($expected, $translator->transChoice($id, $number, $parameters));
    }

    public function testGetSetLocale()
    {
        $translator = new IdentityTranslator();
        $translator->setLocale('en');

        $this->assertEquals('en', $translator->getLocale());
    }

    public function testGetLocaleReturnsDefaultLocaleIfNotSet()
    {
        // in order to test with "pt_BR"
        IntlTestHelper::requireFullIntl($this);

        $translator = new IdentityTranslator();

        \Locale::setDefault('en');
        $this->assertEquals('en', $translator->getLocale());

        \Locale::setDefault('pt_BR');
        $this->assertEquals('pt_BR', $translator->getLocale());
    }

    public function getTransTests()
    {
        return array(
            array('Symfony is great!', 'Symfony is great!', array()),
            array('Symfony is awesome!', 'Symfony is %what%!', array('%what%' => 'awesome')),
        );
    }

    public function getTransChoiceTests()
    {
        return array(
            array('There are no apples', '{0} There are no apples|{1} There is one apple|]1,Inf] There are %count% apples', 0, array('%count%' => 0)),
            array('There is one apple', '{0} There are no apples|{1} There is one apple|]1,Inf] There are %count% apples', 1, array('%count%' => 1)),
            array('There are 10 apples', '{0} There are no apples|{1} There is one apple|]1,Inf] There are %count% apples', 10, array('%count%' => 10)),
            array('There are 0 apples', 'There is 1 apple|There are %count% apples', 0, array('%count%' => 0)),
            array('There is 1 apple', 'There is 1 apple|There are %count% apples', 1, array('%count%' => 1)),
            array('There are 10 apples', 'There is 1 apple|There are %count% apples', 10, array('%count%' => 10)),
            // custom validation messages may be coded with a fixed value
            array('There are 2 apples', 'There are 2 apples', 2, array('%count%' => 2)),
        );
    }
}
PKϤ$Z;.�BB%translation/Tests/fixtures/plurals.ponu�[���msgid "foo"
msgid_plural "foos"
msgstr[0] "bar"
msgstr[1] "bars"

PKϤ$Z��W44'translation/Tests/fixtures/resources.monu�[�����$,-1foobarPKϤ$Z$translation/Tests/fixtures/empty.csvnu�[���PKϤ$Z:&�݊�'translation/Tests/fixtures/withnote.xlfnu�[���<?xml version="1.0" encoding="utf-8"?>
<xliff xmlns="urn:oasis:names:tc:xliff:document:1.2" version="1.2">
  <file source-language="en" datatype="plaintext" original="file.ext">
    <body>
      <trans-unit id="1">
        <source>foo</source>
        <target>bar</target>
        <note priority="1">foo</note>
      </trans-unit>
      <trans-unit id="2">
        <source>extra</source>
        <note from="foo">bar</note>
      </trans-unit>
      <trans-unit id="3">
        <source>key</source>
        <target></target>
        <note>baz</note>
        <note priority="2" from="bar">qux</note>
      </trans-unit>
    </body>
  </file>
</xliff>
PKϤ$Z#]9ӱ�2translation/Tests/fixtures/resources-2.0-clean.xlfnu�[���<?xml version="1.0" encoding="utf-8"?>
<xliff xmlns="urn:oasis:names:tc:xliff:document:2.0" version="2.0" srcLang="fr-FR" trgLang="en-US">
  <file id="messages.en_US">
    <unit id="acbd18db4cc2f85cedef654fccc4a4d8">
      <segment>
        <source>foo</source>
        <target>bar</target>
      </segment>
    </unit>
    <unit id="3c6e0b8a9c15224a8228b9a98ca1531d">
      <segment>
        <source>key</source>
        <target order="1"></target>
      </segment>
    </unit>
    <unit id="18e6a493872558d949b4c16ea1fa6ab6">
      <segment>
        <source>key.with.cdata</source>
        <target><![CDATA[<source> & <target>]]></target>
      </segment>
    </unit>
  </file>
</xliff>
PKϤ$Z�@-��.translation/Tests/fixtures/with-attributes.xlfnu�[���<?xml version="1.0" encoding="utf-8"?>
<xliff xmlns="urn:oasis:names:tc:xliff:document:1.2" version="1.2">
    <file source-language="en" datatype="plaintext" original="file.ext">
        <body>
            <trans-unit id="1">
                <source>foo</source>
                <target state="translated">bar</target>
            </trans-unit>
            <trans-unit id="2">
                <source>extra</source>
                <target state="needs-translation">bar</target>
            </trans-unit>
            <trans-unit id="3">
                <source>key</source>
                <target></target>
                <note>baz</note>
                <note priority="2" from="bar">qux</note>
            </trans-unit>
        </body>
    </file>
</xliff>
PKϤ$Z�D��``(translation/Tests/fixtures/resources.csvnu�[���"foo"; "bar"
#"bar"; "foo"
"incorrect"; "number"; "columns"; "will"; "be"; "ignored"
"incorrect"PKϤ$Z���		(translation/Tests/fixtures/resources.ymlnu�[���foo: bar
PKϤ$Z�.�zz(translation/Tests/fixtures/resources.xlfnu�[���<?xml version="1.0" encoding="utf-8"?>
<xliff xmlns="urn:oasis:names:tc:xliff:document:1.2" version="1.2">
  <file source-language="en" datatype="plaintext" original="file.ext">
    <body>
      <trans-unit id="1">
        <source>foo</source>
        <target>bar</target>
      </trans-unit>
      <trans-unit id="2">
        <source>extra</source>
      </trans-unit>
      <trans-unit id="3">
        <source>key</source>
        <target></target>
      </trans-unit>
      <trans-unit id="4">
        <source>test</source>
        <target>with</target>
        <note>note</note>
      </trans-unit>
    </body>
  </file>
</xliff>
PKϤ$Z� TT(translation/Tests/fixtures/non-valid.xlfnu�[���<?xml version="1.0"?>
<xliff version="1.2" xmlns="urn:oasis:names:tc:xliff:document:1.2">
    <file source-language="en" datatype="plaintext" original="file.ext">
        <body>
            <trans-unit>
                <source>foo</source>
                <target>bar</target>
            </trans-unit>
        </body>
    </file>
</xliff>
PKϤ$Zd��2��,translation/Tests/fixtures/resources-2.0.xlfnu�[���<xliff xmlns="urn:oasis:names:tc:xliff:document:2.0" version="2.0" srcLang="en-US" trgLang="ja-JP">
    <file id="f1" original="Graphic Example.psd">
        <skeleton href="Graphic Example.psd.skl"/>
        <unit id="1">
            <segment>
                <source>Quetzal</source>
                <target>Quetzal</target>
            </segment>
        </unit>
        <group id="1">
            <unit id="2">
                <segment>
                    <source>foo</source>
                    <target>XLIFF 文書を編集、または処理 するアプリケーションです。</target>
                </segment>
            </unit>
            <unit id="3">
                <segment>
                    <source>bar</source>
                    <target order="1">XLIFF データ・マネージャ</target>
                </segment>
            </unit>
        </group>
    </file>
</xliff>
PKϤ$Zl�d��2translation/Tests/fixtures/resources-tool-info.xlfnu�[���<?xml version="1.0" encoding="utf-8"?>
<xliff xmlns="urn:oasis:names:tc:xliff:document:1.2" version="1.2">
  <file source-language="en-US" target-language="en-US" datatype="plaintext" original="file.ext">
    <header>
      <tool tool-id="foo" tool-name="foo" tool-version="0.0" tool-company="Foo"/>
    </header>
    <body>
      <trans-unit id="acbd18db4cc2f85cedef654fccc4a4d8" resname="foo">
        <source>foo</source>
        <target>bar</target>
      </trans-unit>
    </body>
  </file>
</xliff>
PKϤ$Z$translation/Tests/fixtures/empty.ininu�[���PKϤ$Z+�L�TT4translation/Tests/fixtures/resourcebundle/res/en.resnu�[��� �'ResB 

foobarPKϤ$Z��<�Atranslation/Tests/fixtures/resourcebundle/corrupted/resources.datnu�[���XXXPKϤ$Z�M�Rxx4translation/Tests/fixtures/resourcebundle/dat/en.resnu�[��� �'ResB 	symfonySymfony 2 is great��	PKϤ$Z���L((4translation/Tests/fixtures/resourcebundle/dat/fr.txtnu�[���fr{
    symfony{"Symfony est génial"}
}PKϤ$ZrQ�``;translation/Tests/fixtures/resourcebundle/dat/resources.datnu�[��� �'CmnD@%�resources/en.resresources/fr.res���������� �'ResB 	symfonySymfony 2 is great��	�������� �'ResB 	symfonySymfony 2 est g�nial��	����PKϤ$Z���+%%4translation/Tests/fixtures/resourcebundle/dat/en.txtnu�[���en{
    symfony{"Symfony is great"}
}PKϤ$Z�g.�=translation/Tests/fixtures/resourcebundle/dat/packagelist.txtnu�[���en.res
fr.res
PKϤ$Zw˦(||4translation/Tests/fixtures/resourcebundle/dat/fr.resnu�[��� �'ResB 	symfonySymfony 2 est g�nial��	PKϤ$Zo
�j'''translation/Tests/fixtures/messages.ymlnu�[���foo:
    bar1: value1
    bar2: value2
PKϤ$Z#translation/Tests/fixtures/empty.ponu�[���PKϤ$Zh�Ƙ.translation/Tests/fixtures/resources.dump.jsonnu�[���{"foo":"\u0022bar\u0022"}PKϤ$Z%translation/Tests/fixtures/empty.jsonnu�[���PKϤ$Z$translation/Tests/fixtures/empty.ymlnu�[���PKϤ$Z�:�++(translation/Tests/fixtures/resources.phpnu�[���<?php

return array (
  'foo' => 'bar',
);
PKϤ$Z�B��0translation/Tests/fixtures/escaped-id-plurals.ponu�[���msgid ""
msgstr ""
"Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: 8bit\n"
"Language: en\n"

msgid "escaped \"foo\""
msgid_plural "escaped \"foos\""
msgstr[0] "escaped \"bar\""
msgstr[1] "escaped \"bars\""
PKϤ$Z��111/translation/Tests/fixtures/empty-translation.monu�[�����$,-1fooPKϤ$Z�C(���'translation/Tests/fixtures/resources.tsnu�[���<?xml version="1.0" encoding="utf-8"?>
<TS>
  <context>
    <name>resources</name>
    <message>
      <source>foo</source>
      <translation>bar</translation>
    </message>
  </context>
</TS>
PKϤ$Z�e2~(translation/Tests/fixtures/non-valid.ymlnu�[���foo
PKϤ$Z�B$$$translation/Tests/fixtures/valid.csvnu�[���foo;bar
bar;"foo
foo"
"foo;foo";bar
PKϤ$Z����)translation/Tests/fixtures/resources.jsonnu�[���{
    "foo": "bar"
}PKϤ$Z���n��'translation/Tests/fixtures/encoding.xlfnu�[���<?xml version="1.0" encoding="ISO-8859-1"?>
<xliff xmlns="urn:oasis:names:tc:xliff:document:1.2" version="1.2">
  <file source-language="en" datatype="plaintext" original="file.ext">
    <body>
      <trans-unit id="1" resname="foo">
        <source>foo</source>
        <target>b�r</target>
        <note>b�z</note>
      </trans-unit>
      <trans-unit id="2" resname="bar">
        <source>bar</source>
        <target>f��</target>
      </trans-unit>
    </body>
  </file>
</xliff>
PKϤ$Z=Bs/translation/Tests/fixtures/empty-translation.ponu�[���msgid "foo"
msgstr ""

PKϤ$Z&�S��.translation/Tests/fixtures/resources-clean.xlfnu�[���<?xml version="1.0" encoding="utf-8"?>
<xliff xmlns="urn:oasis:names:tc:xliff:document:1.2" version="1.2">
  <file source-language="fr-FR" target-language="en-US" datatype="plaintext" original="file.ext">
    <header>
      <tool tool-id="symfony" tool-name="Symfony"/>
    </header>
    <body>
      <trans-unit id="acbd18db4cc2f85cedef654fccc4a4d8" resname="foo">
        <source>foo</source>
        <target>bar</target>
        <note priority="1" from="bar">baz</note>
      </trans-unit>
      <trans-unit id="3c6e0b8a9c15224a8228b9a98ca1531d" resname="key">
        <source>key</source>
        <target></target>
        <note>baz</note>
        <note>qux</note>
      </trans-unit>
      <trans-unit id="18e6a493872558d949b4c16ea1fa6ab6" resname="key.with.cdata">
        <source>key.with.cdata</source>
        <target><![CDATA[<source> & <target>]]></target>
      </trans-unit>
    </body>
  </file>
</xliff>
PKϤ$Z!f����'translation/Tests/fixtures/resources.ponu�[���msgid ""
msgstr ""
"Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: 8bit\n"
"Language: en\n"

msgid "foo"
msgstr "bar"PKϤ$Z�<�S)translation/Tests/fixtures/malformed.jsonnu�[���{
    "foo" "bar"
}PKϤ$Z1@'||0translation/Tests/fixtures/fuzzy-translations.ponu�[���#, php-format
msgid "foo1"
msgstr "bar1"

#, fuzzy, php-format
msgid "foo2"
msgstr "fuzzy bar2"

msgid "foo3"
msgstr "bar3"
PKϤ$Zj5)���(translation/Tests/fixtures/escaped-id.ponu�[���msgid ""
msgstr ""
"Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: 8bit\n"
"Language: en\n"

msgid "escaped \"foo\""
msgstr "escaped \"bar\""
PKϤ$Z���\"".translation/Tests/fixtures/messages_linear.ymlnu�[���foo.bar1: value1
foo.bar2: value2
PKϤ$Z��jj*translation/Tests/fixtures/withdoctype.xlfnu�[���<?xml version="1.0"?>
<!DOCTYPE foo>
<xliff version="1.2" xmlns="urn:oasis:names:tc:xliff:document:1.2">
    <file source-language="en" datatype="plaintext" original="file.ext">
        <body>
            <trans-unit id="1">
                <source>foo</source>
                <target>bar</target>
            </trans-unit>
        </body>
    </file>
</xliff>
PKϤ$Z*֔�JJ%translation/Tests/fixtures/plurals.monu�[�����$,8AfoofoosbarbarsPKϤ$Zd֥��:translation/Tests/fixtures/resources-target-attributes.xlfnu�[���<?xml version="1.0" encoding="utf-8"?>
<xliff xmlns="urn:oasis:names:tc:xliff:document:1.2" version="1.2">
  <file source-language="fr-FR" target-language="en-US" datatype="plaintext" original="file.ext">
    <header>
      <tool tool-id="symfony" tool-name="Symfony"/>
    </header>
    <body>
      <trans-unit id="acbd18db4cc2f85cedef654fccc4a4d8" resname="foo">
        <source>foo</source>
        <target state="needs-translation">bar</target>
      </trans-unit>
    </body>
  </file>
</xliff>
PKϤ$ZY���44&translation/Tests/fixtures/resname.xlfnu�[���<?xml version="1.0" encoding="utf-8"?>
<xliff xmlns="urn:oasis:names:tc:xliff:document:1.2" version="1.2">
  <file source-language="en" datatype="plaintext" original="file.ext">
    <body>
      <trans-unit id="1" resname="foo">
        <source></source>
        <target>bar</target>
      </trans-unit>
      <trans-unit id="2" resname="bar">
        <source>bar source</source>
        <target>baz</target>
      </trans-unit>
      <trans-unit id="3">
        <source>baz</source>
        <target>foo</target>
      </trans-unit>
    </body>
  </file>
</xliff>
PKϤ$Z$translation/Tests/fixtures/empty.xlfnu�[���PKϤ$Z#translation/Tests/fixtures/empty.monu�[���PKϤ$Z�'�F

(translation/Tests/fixtures/resources.ininu�[���foo="bar"
PKϤ$Z/�
��4translation/Tests/fixtures/invalid-xml-resources.xlfnu�[���<?xml version="1.0" encoding="utf-8"?>
<xliff xmlns="urn:oasis:names:tc:xliff:document:1.2" version="1.2">
    <file source-language="en" datatype="plaintext" original="file.ext">
        <body>
            <trans-unit id="1">
                <source>foo</source>
                <target>bar
            </trans-unit>
            <trans-unit id="2">
                <source>extra</source>
            </trans-unit>
            <trans-unit id="3">
                <source>key</source>
                <target></target>
            </trans-unit>
            <trans-unit id="4">
                <source>test</source>
                <target>with</target>
                <note>note</note>
            </trans-unit>
        </body>
    </file>
</xliff>
PKϤ$ZdZ%�	�	-translation/Tests/Loader/MoFileLoaderTest.phpnu�[���<?php

/*
 * This file is part of the Symfony package.
 *
 * (c) Fabien Potencier <fabien@symfony.com>
 *
 * For the full copyright and license information, please view the LICENSE
 * file that was distributed with this source code.
 */

namespace Symfony\Component\Translation\Tests\Loader;

use Symfony\Component\Translation\Loader\MoFileLoader;
use Symfony\Component\Config\Resource\FileResource;

class MoFileLoaderTest extends \PHPUnit_Framework_TestCase
{
    public function testLoad()
    {
        $loader = new MoFileLoader();
        $resource = __DIR__.'/../fixtures/resources.mo';
        $catalogue = $loader->load($resource, 'en', 'domain1');

        $this->assertEquals(array('foo' => 'bar'), $catalogue->all('domain1'));
        $this->assertEquals('en', $catalogue->getLocale());
        $this->assertEquals(array(new FileResource($resource)), $catalogue->getResources());
    }

    public function testLoadPlurals()
    {
        $loader = new MoFileLoader();
        $resource = __DIR__.'/../fixtures/plurals.mo';
        $catalogue = $loader->load($resource, 'en', 'domain1');

        $this->assertEquals(array('foo' => 'bar', 'foos' => '{0} bar|{1} bars'), $catalogue->all('domain1'));
        $this->assertEquals('en', $catalogue->getLocale());
        $this->assertEquals(array(new FileResource($resource)), $catalogue->getResources());
    }

    /**
     * @expectedException \Symfony\Component\Translation\Exception\NotFoundResourceException
     */
    public function testLoadNonExistingResource()
    {
        $loader = new MoFileLoader();
        $resource = __DIR__.'/../fixtures/non-existing.mo';
        $loader->load($resource, 'en', 'domain1');
    }

    /**
     * @expectedException \Symfony\Component\Translation\Exception\InvalidResourceException
     */
    public function testLoadInvalidResource()
    {
        $loader = new MoFileLoader();
        $resource = __DIR__.'/../fixtures/empty.mo';
        $loader->load($resource, 'en', 'domain1');
    }

    public function testLoadEmptyTranslation()
    {
        $loader = new MoFileLoader();
        $resource = __DIR__.'/../fixtures/empty-translation.mo';
        $catalogue = $loader->load($resource, 'en', 'message');

        $this->assertEquals(array(), $catalogue->all('message'));
        $this->assertEquals('en', $catalogue->getLocale());
        $this->assertEquals(array(new FileResource($resource)), $catalogue->getResources());
    }
}
PKϤ$Z��|=��-translation/Tests/Loader/QtFileLoaderTest.phpnu�[���<?php

/*
 * This file is part of the Symfony package.
 *
 * (c) Fabien Potencier <fabien@symfony.com>
 *
 * For the full copyright and license information, please view the LICENSE
 * file that was distributed with this source code.
 */

namespace Symfony\Component\Translation\Tests\Loader;

use Symfony\Component\Translation\Loader\QtFileLoader;
use Symfony\Component\Config\Resource\FileResource;

class QtFileLoaderTest extends \PHPUnit_Framework_TestCase
{
    public function testLoad()
    {
        $loader = new QtFileLoader();
        $resource = __DIR__.'/../fixtures/resources.ts';
        $catalogue = $loader->load($resource, 'en', 'resources');

        $this->assertEquals(array('foo' => 'bar'), $catalogue->all('resources'));
        $this->assertEquals('en', $catalogue->getLocale());
        $this->assertEquals(array(new FileResource($resource)), $catalogue->getResources());
    }

    /**
     * @expectedException \Symfony\Component\Translation\Exception\NotFoundResourceException
     */
    public function testLoadNonExistingResource()
    {
        $loader = new QtFileLoader();
        $resource = __DIR__.'/../fixtures/non-existing.ts';
        $loader->load($resource, 'en', 'domain1');
    }

    /**
     * @expectedException \Symfony\Component\Translation\Exception\InvalidResourceException
     */
    public function testLoadNonLocalResource()
    {
        $loader = new QtFileLoader();
        $resource = 'http://domain1.com/resources.ts';
        $loader->load($resource, 'en', 'domain1');
    }

    /**
     * @expectedException \Symfony\Component\Translation\Exception\InvalidResourceException
     */
    public function testLoadInvalidResource()
    {
        $loader = new QtFileLoader();
        $resource = __DIR__.'/../fixtures/invalid-xml-resources.xlf';
        $loader->load($resource, 'en', 'domain1');
    }

    public function testLoadEmptyResource()
    {
        $loader = new QtFileLoader();
        $resource = __DIR__.'/../fixtures/empty.xlf';
        $this->setExpectedException('Symfony\Component\Translation\Exception\InvalidResourceException', sprintf('Unable to load "%s".', $resource));
        $loader->load($resource, 'en', 'domain1');
    }
}
PKϤ$Z���YY0translation/Tests/Loader/XliffFileLoaderTest.phpnu�[���<?php

/*
 * This file is part of the Symfony package.
 *
 * (c) Fabien Potencier <fabien@symfony.com>
 *
 * For the full copyright and license information, please view the LICENSE
 * file that was distributed with this source code.
 */

namespace Symfony\Component\Translation\Tests\Loader;

use Symfony\Component\Translation\Loader\XliffFileLoader;
use Symfony\Component\Config\Resource\FileResource;

class XliffFileLoaderTest extends \PHPUnit_Framework_TestCase
{
    public function testLoad()
    {
        $loader = new XliffFileLoader();
        $resource = __DIR__.'/../fixtures/resources.xlf';
        $catalogue = $loader->load($resource, 'en', 'domain1');

        $this->assertEquals('en', $catalogue->getLocale());
        $this->assertEquals(array(new FileResource($resource)), $catalogue->getResources());
        $this->assertSame(array(), libxml_get_errors());
        $this->assertContainsOnly('string', $catalogue->all('domain1'));
    }

    public function testLoadWithInternalErrorsEnabled()
    {
        $internalErrors = libxml_use_internal_errors(true);

        $this->assertSame(array(), libxml_get_errors());

        $loader = new XliffFileLoader();
        $resource = __DIR__.'/../fixtures/resources.xlf';
        $catalogue = $loader->load($resource, 'en', 'domain1');

        $this->assertEquals('en', $catalogue->getLocale());
        $this->assertEquals(array(new FileResource($resource)), $catalogue->getResources());
        $this->assertSame(array(), libxml_get_errors());

        libxml_clear_errors();
        libxml_use_internal_errors($internalErrors);
    }

    public function testLoadWithResname()
    {
        $loader = new XliffFileLoader();
        $catalogue = $loader->load(__DIR__.'/../fixtures/resname.xlf', 'en', 'domain1');

        $this->assertEquals(array('foo' => 'bar', 'bar' => 'baz', 'baz' => 'foo'), $catalogue->all('domain1'));
    }

    public function testIncompleteResource()
    {
        $loader = new XliffFileLoader();
        $catalogue = $loader->load(__DIR__.'/../fixtures/resources.xlf', 'en', 'domain1');

        $this->assertEquals(array('foo' => 'bar', 'extra' => 'extra', 'key' => '', 'test' => 'with'), $catalogue->all('domain1'));
    }

    public function testEncoding()
    {
        $loader = new XliffFileLoader();
        $catalogue = $loader->load(__DIR__.'/../fixtures/encoding.xlf', 'en', 'domain1');

        $this->assertEquals(utf8_decode('föö'), $catalogue->get('bar', 'domain1'));
        $this->assertEquals(utf8_decode('bär'), $catalogue->get('foo', 'domain1'));
        $this->assertEquals(array('notes' => array(array('content' => utf8_decode('bäz')))), $catalogue->getMetadata('foo', 'domain1'));
    }

    public function testTargetAttributesAreStoredCorrectly()
    {
        $loader = new XliffFileLoader();
        $catalogue = $loader->load(__DIR__.'/../fixtures/with-attributes.xlf', 'en', 'domain1');

        $metadata = $catalogue->getMetadata('foo', 'domain1');
        $this->assertEquals('translated', $metadata['target-attributes']['state']);
    }

    /**
     * @expectedException \Symfony\Component\Translation\Exception\InvalidResourceException
     */
    public function testLoadInvalidResource()
    {
        $loader = new XliffFileLoader();
        $loader->load(__DIR__.'/../fixtures/resources.php', 'en', 'domain1');
    }

    /**
     * @expectedException \Symfony\Component\Translation\Exception\InvalidResourceException
     */
    public function testLoadResourceDoesNotValidate()
    {
        $loader = new XliffFileLoader();
        $loader->load(__DIR__.'/../fixtures/non-valid.xlf', 'en', 'domain1');
    }

    /**
     * @expectedException \Symfony\Component\Translation\Exception\NotFoundResourceException
     */
    public function testLoadNonExistingResource()
    {
        $loader = new XliffFileLoader();
        $resource = __DIR__.'/../fixtures/non-existing.xlf';
        $loader->load($resource, 'en', 'domain1');
    }

    /**
     * @expectedException \Symfony\Component\Translation\Exception\InvalidResourceException
     */
    public function testLoadThrowsAnExceptionIfFileNotLocal()
    {
        $loader = new XliffFileLoader();
        $resource = 'http://example.com/resources.xlf';
        $loader->load($resource, 'en', 'domain1');
    }

    /**
     * @expectedException        \Symfony\Component\Translation\Exception\InvalidResourceException
     * @expectedExceptionMessage Document types are not allowed.
     */
    public function testDocTypeIsNotAllowed()
    {
        $loader = new XliffFileLoader();
        $loader->load(__DIR__.'/../fixtures/withdoctype.xlf', 'en', 'domain1');
    }

    public function testParseEmptyFile()
    {
        $loader = new XliffFileLoader();
        $resource = __DIR__.'/../fixtures/empty.xlf';
        $this->setExpectedException('Symfony\Component\Translation\Exception\InvalidResourceException', sprintf('Unable to load "%s":', $resource));
        $loader->load($resource, 'en', 'domain1');
    }

    public function testLoadNotes()
    {
        $loader = new XliffFileLoader();
        $catalogue = $loader->load(__DIR__.'/../fixtures/withnote.xlf', 'en', 'domain1');

        $this->assertEquals(array('notes' => array(array('priority' => 1, 'content' => 'foo'))), $catalogue->getMetadata('foo', 'domain1'));
        // message without target
        $this->assertEquals(array('notes' => array(array('content' => 'bar', 'from' => 'foo'))), $catalogue->getMetadata('extra', 'domain1'));
        // message with empty target
        $this->assertEquals(array('notes' => array(array('content' => 'baz'), array('priority' => 2, 'from' => 'bar', 'content' => 'qux'))), $catalogue->getMetadata('key', 'domain1'));
    }

    public function testLoadVersion2()
    {
        $loader = new XliffFileLoader();
        $resource = __DIR__.'/../fixtures/resources-2.0.xlf';
        $catalogue = $loader->load($resource, 'en', 'domain1');

        $this->assertEquals('en', $catalogue->getLocale());
        $this->assertEquals(array(new FileResource($resource)), $catalogue->getResources());
        $this->assertSame(array(), libxml_get_errors());

        $domains = $catalogue->all();
        $this->assertCount(3, $domains['domain1']);
        $this->assertContainsOnly('string', $catalogue->all('domain1'));

        // target attributes
        $this->assertEquals(array('target-attributes' => array('order' => 1)), $catalogue->getMetadata('bar', 'domain1'));
    }
}
PKϤ$Z���.translation/Tests/Loader/PhpFileLoaderTest.phpnu�[���<?php

/*
 * This file is part of the Symfony package.
 *
 * (c) Fabien Potencier <fabien@symfony.com>
 *
 * For the full copyright and license information, please view the LICENSE
 * file that was distributed with this source code.
 */

namespace Symfony\Component\Translation\Tests\Loader;

use Symfony\Component\Translation\Loader\PhpFileLoader;
use Symfony\Component\Config\Resource\FileResource;

class PhpFileLoaderTest extends \PHPUnit_Framework_TestCase
{
    public function testLoad()
    {
        $loader = new PhpFileLoader();
        $resource = __DIR__.'/../fixtures/resources.php';
        $catalogue = $loader->load($resource, 'en', 'domain1');

        $this->assertEquals(array('foo' => 'bar'), $catalogue->all('domain1'));
        $this->assertEquals('en', $catalogue->getLocale());
        $this->assertEquals(array(new FileResource($resource)), $catalogue->getResources());
    }

    /**
     * @expectedException \Symfony\Component\Translation\Exception\NotFoundResourceException
     */
    public function testLoadNonExistingResource()
    {
        $loader = new PhpFileLoader();
        $resource = __DIR__.'/../fixtures/non-existing.php';
        $loader->load($resource, 'en', 'domain1');
    }

    /**
     * @expectedException \Symfony\Component\Translation\Exception\InvalidResourceException
     */
    public function testLoadThrowsAnExceptionIfFileNotLocal()
    {
        $loader = new PhpFileLoader();
        $resource = 'http://example.com/resources.php';
        $loader->load($resource, 'en', 'domain1');
    }
}
PKϤ$ZF��bb	b	1translation/Tests/Loader/IcuDatFileLoaderTest.phpnu�[���<?php

/*
 * This file is part of the Symfony package.
 *
 * (c) Fabien Potencier <fabien@symfony.com>
 *
 * For the full copyright and license information, please view the LICENSE
 * file that was distributed with this source code.
 */

namespace Symfony\Component\Translation\Tests\Loader;

use Symfony\Component\Translation\Loader\IcuDatFileLoader;
use Symfony\Component\Config\Resource\FileResource;

/**
 * @requires extension intl
 */
class IcuDatFileLoaderTest extends LocalizedTestCase
{
    /**
     * @expectedException \Symfony\Component\Translation\Exception\InvalidResourceException
     */
    public function testLoadInvalidResource()
    {
        $loader = new IcuDatFileLoader();
        $loader->load(__DIR__.'/../fixtures/resourcebundle/corrupted/resources', 'es', 'domain2');
    }

    public function testDatEnglishLoad()
    {
        // bundled resource is build using pkgdata command which at least in ICU 4.2 comes in extremely! buggy form
        // you must specify an temporary build directory which is not the same as current directory and
        // MUST reside on the same partition. pkgdata -p resources -T /srv -d.packagelist.txt
        $loader = new IcuDatFileLoader();
        $resource = __DIR__.'/../fixtures/resourcebundle/dat/resources';
        $catalogue = $loader->load($resource, 'en', 'domain1');

        $this->assertEquals(array('symfony' => 'Symfony 2 is great'), $catalogue->all('domain1'));
        $this->assertEquals('en', $catalogue->getLocale());
        $this->assertEquals(array(new FileResource($resource.'.dat')), $catalogue->getResources());
    }

    public function testDatFrenchLoad()
    {
        $loader = new IcuDatFileLoader();
        $resource = __DIR__.'/../fixtures/resourcebundle/dat/resources';
        $catalogue = $loader->load($resource, 'fr', 'domain1');

        $this->assertEquals(array('symfony' => 'Symfony 2 est génial'), $catalogue->all('domain1'));
        $this->assertEquals('fr', $catalogue->getLocale());
        $this->assertEquals(array(new FileResource($resource.'.dat')), $catalogue->getResources());
    }

    /**
     * @expectedException \Symfony\Component\Translation\Exception\NotFoundResourceException
     */
    public function testLoadNonExistingResource()
    {
        $loader = new IcuDatFileLoader();
        $loader->load(__DIR__.'/../fixtures/non-existing.txt', 'en', 'domain1');
    }
}
PKϤ$Z���F��-translation/Tests/Loader/PoFileLoaderTest.phpnu�[���<?php

/*
 * This file is part of the Symfony package.
 *
 * (c) Fabien Potencier <fabien@symfony.com>
 *
 * For the full copyright and license information, please view the LICENSE
 * file that was distributed with this source code.
 */

namespace Symfony\Component\Translation\Tests\Loader;

use Symfony\Component\Translation\Loader\PoFileLoader;
use Symfony\Component\Config\Resource\FileResource;

class PoFileLoaderTest extends \PHPUnit_Framework_TestCase
{
    public function testLoad()
    {
        $loader = new PoFileLoader();
        $resource = __DIR__.'/../fixtures/resources.po';
        $catalogue = $loader->load($resource, 'en', 'domain1');

        $this->assertEquals(array('foo' => 'bar'), $catalogue->all('domain1'));
        $this->assertEquals('en', $catalogue->getLocale());
        $this->assertEquals(array(new FileResource($resource)), $catalogue->getResources());
    }

    public function testLoadPlurals()
    {
        $loader = new PoFileLoader();
        $resource = __DIR__.'/../fixtures/plurals.po';
        $catalogue = $loader->load($resource, 'en', 'domain1');

        $this->assertEquals(array('foo' => 'bar', 'foos' => 'bar|bars'), $catalogue->all('domain1'));
        $this->assertEquals('en', $catalogue->getLocale());
        $this->assertEquals(array(new FileResource($resource)), $catalogue->getResources());
    }

    public function testLoadDoesNothingIfEmpty()
    {
        $loader = new PoFileLoader();
        $resource = __DIR__.'/../fixtures/empty.po';
        $catalogue = $loader->load($resource, 'en', 'domain1');

        $this->assertEquals(array(), $catalogue->all('domain1'));
        $this->assertEquals('en', $catalogue->getLocale());
        $this->assertEquals(array(new FileResource($resource)), $catalogue->getResources());
    }

    /**
     * @expectedException \Symfony\Component\Translation\Exception\NotFoundResourceException
     */
    public function testLoadNonExistingResource()
    {
        $loader = new PoFileLoader();
        $resource = __DIR__.'/../fixtures/non-existing.po';
        $loader->load($resource, 'en', 'domain1');
    }

    public function testLoadEmptyTranslation()
    {
        $loader = new PoFileLoader();
        $resource = __DIR__.'/../fixtures/empty-translation.po';
        $catalogue = $loader->load($resource, 'en', 'domain1');

        $this->assertEquals(array('foo' => ''), $catalogue->all('domain1'));
        $this->assertEquals('en', $catalogue->getLocale());
        $this->assertEquals(array(new FileResource($resource)), $catalogue->getResources());
    }

    public function testEscapedId()
    {
        $loader = new PoFileLoader();
        $resource = __DIR__.'/../fixtures/escaped-id.po';
        $catalogue = $loader->load($resource, 'en', 'domain1');

        $messages = $catalogue->all('domain1');
        $this->assertArrayHasKey('escaped "foo"', $messages);
        $this->assertEquals('escaped "bar"', $messages['escaped "foo"']);
    }

    public function testEscapedIdPlurals()
    {
        $loader = new PoFileLoader();
        $resource = __DIR__.'/../fixtures/escaped-id-plurals.po';
        $catalogue = $loader->load($resource, 'en', 'domain1');

        $messages = $catalogue->all('domain1');
        $this->assertArrayHasKey('escaped "foo"', $messages);
        $this->assertArrayHasKey('escaped "foos"', $messages);
        $this->assertEquals('escaped "bar"', $messages['escaped "foo"']);
        $this->assertEquals('escaped "bar"|escaped "bars"', $messages['escaped "foos"']);
    }

    public function testSkipFuzzyTranslations()
    {
        $loader = new PoFileLoader();
        $resource = __DIR__.'/../fixtures/fuzzy-translations.po';
        $catalogue = $loader->load($resource, 'en', 'domain1');

        $messages = $catalogue->all('domain1');
        $this->assertArrayHasKey('foo1', $messages);
        $this->assertArrayNotHasKey('foo2', $messages);
        $this->assertArrayHasKey('foo3', $messages);
    }
}
PKϤ$Z����<<1translation/Tests/Loader/IcuResFileLoaderTest.phpnu�[���<?php

/*
 * This file is part of the Symfony package.
 *
 * (c) Fabien Potencier <fabien@symfony.com>
 *
 * For the full copyright and license information, please view the LICENSE
 * file that was distributed with this source code.
 */

namespace Symfony\Component\Translation\Tests\Loader;

use Symfony\Component\Translation\Loader\IcuResFileLoader;
use Symfony\Component\Config\Resource\DirectoryResource;

/**
 * @requires extension intl
 */
class IcuResFileLoaderTest extends LocalizedTestCase
{
    public function testLoad()
    {
        // resource is build using genrb command
        $loader = new IcuResFileLoader();
        $resource = __DIR__.'/../fixtures/resourcebundle/res';
        $catalogue = $loader->load($resource, 'en', 'domain1');

        $this->assertEquals(array('foo' => 'bar'), $catalogue->all('domain1'));
        $this->assertEquals('en', $catalogue->getLocale());
        $this->assertEquals(array(new DirectoryResource($resource)), $catalogue->getResources());
    }

    /**
     * @expectedException \Symfony\Component\Translation\Exception\NotFoundResourceException
     */
    public function testLoadNonExistingResource()
    {
        $loader = new IcuResFileLoader();
        $loader->load(__DIR__.'/../fixtures/non-existing.txt', 'en', 'domain1');
    }

    /**
     * @expectedException \Symfony\Component\Translation\Exception\InvalidResourceException
     */
    public function testLoadInvalidResource()
    {
        $loader = new IcuResFileLoader();
        $loader->load(__DIR__.'/../fixtures/resourcebundle/corrupted', 'en', 'domain1');
    }
}
PKϤ$Z��:�.translation/Tests/Loader/LocalizedTestCase.phpnu�[���<?php

/*
 * This file is part of the Symfony package.
 *
 * (c) Fabien Potencier <fabien@symfony.com>
 *
 * For the full copyright and license information, please view the LICENSE
 * file that was distributed with this source code.
 */

namespace Symfony\Component\Translation\Tests\Loader;

abstract class LocalizedTestCase extends \PHPUnit_Framework_TestCase
{
    protected function setUp()
    {
        if (!extension_loaded('intl')) {
            $this->markTestSkipped('Extension intl is required.');
        }
    }
}
PKϤ$Z~�		/translation/Tests/Loader/YamlFileLoaderTest.phpnu�[���<?php

/*
 * This file is part of the Symfony package.
 *
 * (c) Fabien Potencier <fabien@symfony.com>
 *
 * For the full copyright and license information, please view the LICENSE
 * file that was distributed with this source code.
 */

namespace Symfony\Component\Translation\Tests\Loader;

use Symfony\Component\Translation\Loader\YamlFileLoader;
use Symfony\Component\Config\Resource\FileResource;

class YamlFileLoaderTest extends \PHPUnit_Framework_TestCase
{
    public function testLoad()
    {
        $loader = new YamlFileLoader();
        $resource = __DIR__.'/../fixtures/resources.yml';
        $catalogue = $loader->load($resource, 'en', 'domain1');

        $this->assertEquals(array('foo' => 'bar'), $catalogue->all('domain1'));
        $this->assertEquals('en', $catalogue->getLocale());
        $this->assertEquals(array(new FileResource($resource)), $catalogue->getResources());
    }

    public function testLoadDoesNothingIfEmpty()
    {
        $loader = new YamlFileLoader();
        $resource = __DIR__.'/../fixtures/empty.yml';
        $catalogue = $loader->load($resource, 'en', 'domain1');

        $this->assertEquals(array(), $catalogue->all('domain1'));
        $this->assertEquals('en', $catalogue->getLocale());
        $this->assertEquals(array(new FileResource($resource)), $catalogue->getResources());
    }

    /**
     * @expectedException \Symfony\Component\Translation\Exception\NotFoundResourceException
     */
    public function testLoadNonExistingResource()
    {
        $loader = new YamlFileLoader();
        $resource = __DIR__.'/../fixtures/non-existing.yml';
        $loader->load($resource, 'en', 'domain1');
    }

    /**
     * @expectedException \Symfony\Component\Translation\Exception\InvalidResourceException
     */
    public function testLoadThrowsAnExceptionIfFileNotLocal()
    {
        $loader = new YamlFileLoader();
        $resource = 'http://example.com/resources.yml';
        $loader->load($resource, 'en', 'domain1');
    }

    /**
     * @expectedException \Symfony\Component\Translation\Exception\InvalidResourceException
     */
    public function testLoadThrowsAnExceptionIfNotAnArray()
    {
        $loader = new YamlFileLoader();
        $resource = __DIR__.'/../fixtures/non-valid.yml';
        $loader->load($resource, 'en', 'domain1');
    }
}
PKϤ$Z[����.translation/Tests/Loader/CsvFileLoaderTest.phpnu�[���<?php

/*
 * This file is part of the Symfony package.
 *
 * (c) Fabien Potencier <fabien@symfony.com>
 *
 * For the full copyright and license information, please view the LICENSE
 * file that was distributed with this source code.
 */

namespace Symfony\Component\Translation\Tests\Loader;

use Symfony\Component\Translation\Loader\CsvFileLoader;
use Symfony\Component\Config\Resource\FileResource;

class CsvFileLoaderTest extends \PHPUnit_Framework_TestCase
{
    public function testLoad()
    {
        $loader = new CsvFileLoader();
        $resource = __DIR__.'/../fixtures/resources.csv';
        $catalogue = $loader->load($resource, 'en', 'domain1');

        $this->assertEquals(array('foo' => 'bar'), $catalogue->all('domain1'));
        $this->assertEquals('en', $catalogue->getLocale());
        $this->assertEquals(array(new FileResource($resource)), $catalogue->getResources());
    }

    public function testLoadDoesNothingIfEmpty()
    {
        $loader = new CsvFileLoader();
        $resource = __DIR__.'/../fixtures/empty.csv';
        $catalogue = $loader->load($resource, 'en', 'domain1');

        $this->assertEquals(array(), $catalogue->all('domain1'));
        $this->assertEquals('en', $catalogue->getLocale());
        $this->assertEquals(array(new FileResource($resource)), $catalogue->getResources());
    }

    /**
     * @expectedException \Symfony\Component\Translation\Exception\NotFoundResourceException
     */
    public function testLoadNonExistingResource()
    {
        $loader = new CsvFileLoader();
        $resource = __DIR__.'/../fixtures/not-exists.csv';
        $loader->load($resource, 'en', 'domain1');
    }

    /**
     * @expectedException \Symfony\Component\Translation\Exception\InvalidResourceException
     */
    public function testLoadNonLocalResource()
    {
        $loader = new CsvFileLoader();
        $resource = 'http://example.com/resources.csv';
        $loader->load($resource, 'en', 'domain1');
    }
}
PKϤ$Zx��""/translation/Tests/Loader/JsonFileLoaderTest.phpnu�[���<?php

/*
 * This file is part of the Symfony package.
 *
 * (c) Fabien Potencier <fabien@symfony.com>
 *
 * For the full copyright and license information, please view the LICENSE
 * file that was distributed with this source code.
 */

namespace Symfony\Component\Translation\Tests\Loader;

use Symfony\Component\Translation\Loader\JsonFileLoader;
use Symfony\Component\Config\Resource\FileResource;

class JsonFileLoaderTest extends \PHPUnit_Framework_TestCase
{
    public function testLoad()
    {
        $loader = new JsonFileLoader();
        $resource = __DIR__.'/../fixtures/resources.json';
        $catalogue = $loader->load($resource, 'en', 'domain1');

        $this->assertEquals(array('foo' => 'bar'), $catalogue->all('domain1'));
        $this->assertEquals('en', $catalogue->getLocale());
        $this->assertEquals(array(new FileResource($resource)), $catalogue->getResources());
    }

    public function testLoadDoesNothingIfEmpty()
    {
        $loader = new JsonFileLoader();
        $resource = __DIR__.'/../fixtures/empty.json';
        $catalogue = $loader->load($resource, 'en', 'domain1');

        $this->assertEquals(array(), $catalogue->all('domain1'));
        $this->assertEquals('en', $catalogue->getLocale());
        $this->assertEquals(array(new FileResource($resource)), $catalogue->getResources());
    }

    /**
     * @expectedException \Symfony\Component\Translation\Exception\NotFoundResourceException
     */
    public function testLoadNonExistingResource()
    {
        $loader = new JsonFileLoader();
        $resource = __DIR__.'/../fixtures/non-existing.json';
        $loader->load($resource, 'en', 'domain1');
    }

    /**
     * @expectedException           \Symfony\Component\Translation\Exception\InvalidResourceException
     * @expectedExceptionMessage    Error parsing JSON - Syntax error, malformed JSON
     */
    public function testParseException()
    {
        $loader = new JsonFileLoader();
        $resource = __DIR__.'/../fixtures/malformed.json';
        $loader->load($resource, 'en', 'domain1');
    }
}
PKϤ$Z/�݂�.translation/Tests/Loader/IniFileLoaderTest.phpnu�[���<?php

/*
 * This file is part of the Symfony package.
 *
 * (c) Fabien Potencier <fabien@symfony.com>
 *
 * For the full copyright and license information, please view the LICENSE
 * file that was distributed with this source code.
 */

namespace Symfony\Component\Translation\Tests\Loader;

use Symfony\Component\Translation\Loader\IniFileLoader;
use Symfony\Component\Config\Resource\FileResource;

class IniFileLoaderTest extends \PHPUnit_Framework_TestCase
{
    public function testLoad()
    {
        $loader = new IniFileLoader();
        $resource = __DIR__.'/../fixtures/resources.ini';
        $catalogue = $loader->load($resource, 'en', 'domain1');

        $this->assertEquals(array('foo' => 'bar'), $catalogue->all('domain1'));
        $this->assertEquals('en', $catalogue->getLocale());
        $this->assertEquals(array(new FileResource($resource)), $catalogue->getResources());
    }

    public function testLoadDoesNothingIfEmpty()
    {
        $loader = new IniFileLoader();
        $resource = __DIR__.'/../fixtures/empty.ini';
        $catalogue = $loader->load($resource, 'en', 'domain1');

        $this->assertEquals(array(), $catalogue->all('domain1'));
        $this->assertEquals('en', $catalogue->getLocale());
        $this->assertEquals(array(new FileResource($resource)), $catalogue->getResources());
    }

    /**
     * @expectedException \Symfony\Component\Translation\Exception\NotFoundResourceException
     */
    public function testLoadNonExistingResource()
    {
        $loader = new IniFileLoader();
        $resource = __DIR__.'/../fixtures/non-existing.ini';
        $loader->load($resource, 'en', 'domain1');
    }
}
PKϤ$Z0�u^��-translation/Tests/Util/ArrayConverterTest.phpnu�[���<?php

/*
 * This file is part of the Symfony package.
 *
 * (c) Fabien Potencier <fabien@symfony.com>
 *
 * For the full copyright and license information, please view the LICENSE
 * file that was distributed with this source code.
 */

namespace Symfony\Component\Translation\Tests\Util;

use Symfony\Component\Translation\Util\ArrayConverter;

class ArrayConverterTest extends \PHPUnit_Framework_TestCase
{
    /**
     * @dataProvider messsagesData
     */
    public function testDump($input, $expectedOutput)
    {
        $this->assertEquals($expectedOutput, ArrayConverter::expandToTree($input));
    }

    public function messsagesData()
    {
        return array(
            array(
                // input
                array(
                    'foo1' => 'bar',
                    'foo.bar' => 'value',
                ),
                // expected output
                array(
                    'foo1' => 'bar',
                    'foo' => array('bar' => 'value'),
                ),
            ),
            array(
                // input
                array(
                    'foo.bar' => 'value1',
                    'foo.bar.test' => 'value2',
                ),
                // expected output
                array(
                    'foo' => array(
                        'bar' => 'value1',
                        'bar.test' => 'value2',
                    ),
                ),
            ),
            array(
                // input
                array(
                    'foo.level2.level3.level4' => 'value1',
                    'foo.level2' => 'value2',
                    'foo.bar' => 'value3',
                ),
                // expected output
                array(
                    'foo' => array(
                        'level2' => 'value2',
                        'level2.level3.level4' => 'value1',
                        'bar' => 'value3',
                    ),
                ),
            ),
        );
    }
}
PKϤ$Z���ڟ�1translation/Tests/Catalogue/DiffOperationTest.phpnu�[���<?php

/*
 * This file is part of the Symfony package.
 *
 * (c) Fabien Potencier <fabien@symfony.com>
 *
 * For the full copyright and license information, please view the LICENSE
 * file that was distributed with this source code.
 */

namespace Symfony\Component\Translation\Tests\Catalogue;

use Symfony\Component\Translation\Catalogue\DiffOperation;
use Symfony\Component\Translation\MessageCatalogueInterface;

/**
 * @group legacy
 */
class DiffOperationTest extends TargetOperationTest
{
    protected function createOperation(MessageCatalogueInterface $source, MessageCatalogueInterface $target)
    {
        return new DiffOperation($source, $target);
    }
}
PKϤ$Z�T%<��2translation/Tests/Catalogue/MergeOperationTest.phpnu�[���<?php

/*
 * This file is part of the Symfony package.
 *
 * (c) Fabien Potencier <fabien@symfony.com>
 *
 * For the full copyright and license information, please view the LICENSE
 * file that was distributed with this source code.
 */

namespace Symfony\Component\Translation\Tests\Catalogue;

use Symfony\Component\Translation\Catalogue\MergeOperation;
use Symfony\Component\Translation\MessageCatalogue;
use Symfony\Component\Translation\MessageCatalogueInterface;

class MergeOperationTest extends AbstractOperationTest
{
    public function testGetMessagesFromSingleDomain()
    {
        $operation = $this->createOperation(
            new MessageCatalogue('en', array('messages' => array('a' => 'old_a', 'b' => 'old_b'))),
            new MessageCatalogue('en', array('messages' => array('a' => 'new_a', 'c' => 'new_c')))
        );

        $this->assertEquals(
            array('a' => 'old_a', 'b' => 'old_b', 'c' => 'new_c'),
            $operation->getMessages('messages')
        );

        $this->assertEquals(
            array('c' => 'new_c'),
            $operation->getNewMessages('messages')
        );

        $this->assertEquals(
            array(),
            $operation->getObsoleteMessages('messages')
        );
    }

    public function testGetResultFromSingleDomain()
    {
        $this->assertEquals(
            new MessageCatalogue('en', array(
                'messages' => array('a' => 'old_a', 'b' => 'old_b', 'c' => 'new_c'),
            )),
            $this->createOperation(
                new MessageCatalogue('en', array('messages' => array('a' => 'old_a', 'b' => 'old_b'))),
                new MessageCatalogue('en', array('messages' => array('a' => 'new_a', 'c' => 'new_c')))
            )->getResult()
        );
    }

    public function testGetResultWithMetadata()
    {
        $leftCatalogue = new MessageCatalogue('en', array('messages' => array('a' => 'old_a', 'b' => 'old_b')));
        $leftCatalogue->setMetadata('a', 'foo', 'messages');
        $leftCatalogue->setMetadata('b', 'bar', 'messages');
        $rightCatalogue = new MessageCatalogue('en', array('messages' => array('b' => 'new_b', 'c' => 'new_c')));
        $rightCatalogue->setMetadata('b', 'baz', 'messages');
        $rightCatalogue->setMetadata('c', 'qux', 'messages');

        $mergedCatalogue = new MessageCatalogue('en', array('messages' => array('a' => 'old_a', 'b' => 'old_b', 'c' => 'new_c')));
        $mergedCatalogue->setMetadata('a', 'foo', 'messages');
        $mergedCatalogue->setMetadata('b', 'bar', 'messages');
        $mergedCatalogue->setMetadata('c', 'qux', 'messages');

        $this->assertEquals(
            $mergedCatalogue,
            $this->createOperation(
                $leftCatalogue,
                $rightCatalogue
            )->getResult()
        );
    }

    protected function createOperation(MessageCatalogueInterface $source, MessageCatalogueInterface $target)
    {
        return new MergeOperation($source, $target);
    }
}
PKϤ$Zײ�))5translation/Tests/Catalogue/AbstractOperationTest.phpnu�[���<?php

/*
 * This file is part of the Symfony package.
 *
 * (c) Fabien Potencier <fabien@symfony.com>
 *
 * For the full copyright and license information, please view the LICENSE
 * file that was distributed with this source code.
 */

namespace Symfony\Component\Translation\Tests\Catalogue;

use Symfony\Component\Translation\MessageCatalogue;
use Symfony\Component\Translation\MessageCatalogueInterface;

abstract class AbstractOperationTest extends \PHPUnit_Framework_TestCase
{
    public function testGetEmptyDomains()
    {
        $this->assertEquals(
            array(),
            $this->createOperation(
                new MessageCatalogue('en'),
                new MessageCatalogue('en')
            )->getDomains()
        );
    }

    public function testGetMergedDomains()
    {
        $this->assertEquals(
            array('a', 'b', 'c'),
            $this->createOperation(
                new MessageCatalogue('en', array('a' => array(), 'b' => array())),
                new MessageCatalogue('en', array('b' => array(), 'c' => array()))
            )->getDomains()
        );
    }

    public function testGetMessagesFromUnknownDomain()
    {
        $this->setExpectedException('InvalidArgumentException');
        $this->createOperation(
            new MessageCatalogue('en'),
            new MessageCatalogue('en')
        )->getMessages('domain');
    }

    public function testGetEmptyMessages()
    {
        $this->assertEquals(
            array(),
            $this->createOperation(
                new MessageCatalogue('en', array('a' => array())),
                new MessageCatalogue('en')
            )->getMessages('a')
        );
    }

    public function testGetEmptyResult()
    {
        $this->assertEquals(
            new MessageCatalogue('en'),
            $this->createOperation(
                new MessageCatalogue('en'),
                new MessageCatalogue('en')
            )->getResult()
        );
    }

    abstract protected function createOperation(MessageCatalogueInterface $source, MessageCatalogueInterface $target);
}
PKϤ$Z��SS3translation/Tests/Catalogue/TargetOperationTest.phpnu�[���<?php

/*
 * This file is part of the Symfony package.
 *
 * (c) Fabien Potencier <fabien@symfony.com>
 *
 * For the full copyright and license information, please view the LICENSE
 * file that was distributed with this source code.
 */

namespace Symfony\Component\Translation\Tests\Catalogue;

use Symfony\Component\Translation\Catalogue\TargetOperation;
use Symfony\Component\Translation\MessageCatalogue;
use Symfony\Component\Translation\MessageCatalogueInterface;

class TargetOperationTest extends AbstractOperationTest
{
    public function testGetMessagesFromSingleDomain()
    {
        $operation = $this->createOperation(
            new MessageCatalogue('en', array('messages' => array('a' => 'old_a', 'b' => 'old_b'))),
            new MessageCatalogue('en', array('messages' => array('a' => 'new_a', 'c' => 'new_c')))
        );

        $this->assertEquals(
            array('a' => 'old_a', 'c' => 'new_c'),
            $operation->getMessages('messages')
        );

        $this->assertEquals(
            array('c' => 'new_c'),
            $operation->getNewMessages('messages')
        );

        $this->assertEquals(
            array('b' => 'old_b'),
            $operation->getObsoleteMessages('messages')
        );
    }

    public function testGetResultFromSingleDomain()
    {
        $this->assertEquals(
            new MessageCatalogue('en', array(
                'messages' => array('a' => 'old_a', 'c' => 'new_c'),
            )),
            $this->createOperation(
                new MessageCatalogue('en', array('messages' => array('a' => 'old_a', 'b' => 'old_b'))),
                new MessageCatalogue('en', array('messages' => array('a' => 'new_a', 'c' => 'new_c')))
            )->getResult()
        );
    }

    public function testGetResultWithMetadata()
    {
        $leftCatalogue = new MessageCatalogue('en', array('messages' => array('a' => 'old_a', 'b' => 'old_b')));
        $leftCatalogue->setMetadata('a', 'foo', 'messages');
        $leftCatalogue->setMetadata('b', 'bar', 'messages');
        $rightCatalogue = new MessageCatalogue('en', array('messages' => array('b' => 'new_b', 'c' => 'new_c')));
        $rightCatalogue->setMetadata('b', 'baz', 'messages');
        $rightCatalogue->setMetadata('c', 'qux', 'messages');

        $diffCatalogue = new MessageCatalogue('en', array('messages' => array('b' => 'old_b', 'c' => 'new_c')));
        $diffCatalogue->setMetadata('b', 'bar', 'messages');
        $diffCatalogue->setMetadata('c', 'qux', 'messages');

        $this->assertEquals(
            $diffCatalogue,
            $this->createOperation(
                $leftCatalogue,
                $rightCatalogue
            )->getResult()
        );
    }

    protected function createOperation(MessageCatalogueInterface $source, MessageCatalogueInterface $target)
    {
        return new TargetOperation($source, $target);
    }
}
PKϤ$Z<�-translation/Tests/Dumper/QtFileDumperTest.phpnu�[���<?php

/*
 * This file is part of the Symfony package.
 *
 * (c) Fabien Potencier <fabien@symfony.com>
 *
 * For the full copyright and license information, please view the LICENSE
 * file that was distributed with this source code.
 */

namespace Symfony\Component\Translation\Tests\Dumper;

use Symfony\Component\Translation\MessageCatalogue;
use Symfony\Component\Translation\Dumper\QtFileDumper;

class QtFileDumperTest extends \PHPUnit_Framework_TestCase
{
    public function testFormatCatalogue()
    {
        $catalogue = new MessageCatalogue('en');
        $catalogue->add(array('foo' => 'bar'), 'resources');

        $dumper = new QtFileDumper();

        $this->assertStringEqualsFile(__DIR__.'/../fixtures/resources.ts', $dumper->formatCatalogue($catalogue, 'resources'));
    }
}
PKϤ$Z���/translation/Tests/Dumper/JsonFileDumperTest.phpnu�[���<?php

/*
 * This file is part of the Symfony package.
 *
 * (c) Fabien Potencier <fabien@symfony.com>
 *
 * For the full copyright and license information, please view the LICENSE
 * file that was distributed with this source code.
 */

namespace Symfony\Component\Translation\Tests\Dumper;

use Symfony\Component\Translation\MessageCatalogue;
use Symfony\Component\Translation\Dumper\JsonFileDumper;

class JsonFileDumperTest extends \PHPUnit_Framework_TestCase
{
    public function testFormatCatalogue()
    {
        if (PHP_VERSION_ID < 50400) {
            $this->markTestIncomplete('PHP below 5.4 doesn\'t support JSON pretty printing');
        }

        $catalogue = new MessageCatalogue('en');
        $catalogue->add(array('foo' => 'bar'));

        $dumper = new JsonFileDumper();

        $this->assertStringEqualsFile(__DIR__.'/../fixtures/resources.json', $dumper->formatCatalogue($catalogue, 'messages'));
    }

    public function testDumpWithCustomEncoding()
    {
        $catalogue = new MessageCatalogue('en');
        $catalogue->add(array('foo' => '"bar"'));

        $dumper = new JsonFileDumper();

        $this->assertStringEqualsFile(__DIR__.'/../fixtures/resources.dump.json', $dumper->formatCatalogue($catalogue, 'messages', array('json_encoding' => JSON_HEX_QUOT)));
    }
}
PKϤ$Z`����0translation/Tests/Dumper/XliffFileDumperTest.phpnu�[���<?php

/*
 * This file is part of the Symfony package.
 *
 * (c) Fabien Potencier <fabien@symfony.com>
 *
 * For the full copyright and license information, please view the LICENSE
 * file that was distributed with this source code.
 */

namespace Symfony\Component\Translation\Tests\Dumper;

use Symfony\Component\Translation\MessageCatalogue;
use Symfony\Component\Translation\Dumper\XliffFileDumper;

class XliffFileDumperTest extends \PHPUnit_Framework_TestCase
{
    public function testFormatCatalogue()
    {
        $catalogue = new MessageCatalogue('en_US');
        $catalogue->add(array(
            'foo' => 'bar',
            'key' => '',
            'key.with.cdata' => '<source> & <target>',
        ));
        $catalogue->setMetadata('foo', array('notes' => array(array('priority' => 1, 'from' => 'bar', 'content' => 'baz'))));
        $catalogue->setMetadata('key', array('notes' => array(array('content' => 'baz'), array('content' => 'qux'))));

        $dumper = new XliffFileDumper();

        $this->assertStringEqualsFile(
            __DIR__.'/../fixtures/resources-clean.xlf',
            $dumper->formatCatalogue($catalogue, 'messages', array('default_locale' => 'fr_FR'))
        );
    }

    public function testFormatCatalogueXliff2()
    {
        $catalogue = new MessageCatalogue('en_US');
        $catalogue->add(array(
            'foo' => 'bar',
            'key' => '',
            'key.with.cdata' => '<source> & <target>',
        ));
        $catalogue->setMetadata('key', array('target-attributes' => array('order' => 1)));

        $dumper = new XliffFileDumper();

        $this->assertStringEqualsFile(
            __DIR__.'/../fixtures/resources-2.0-clean.xlf',
            $dumper->formatCatalogue($catalogue, 'messages', array('default_locale' => 'fr_FR', 'xliff_version' => '2.0'))
        );
    }

    public function testFormatCatalogueWithCustomToolInfo()
    {
        $options = array(
            'default_locale' => 'en_US',
            'tool_info' => array('tool-id' => 'foo', 'tool-name' => 'foo', 'tool-version' => '0.0', 'tool-company' => 'Foo'),
        );

        $catalogue = new MessageCatalogue('en_US');
        $catalogue->add(array('foo' => 'bar'));

        $dumper = new XliffFileDumper();

        $this->assertStringEqualsFile(
            __DIR__.'/../fixtures/resources-tool-info.xlf',
            $dumper->formatCatalogue($catalogue, 'messages', $options)
        );
    }

    public function testFormatCatalogueWithTargetAttributesMetadata()
    {
        $catalogue = new MessageCatalogue('en_US');
        $catalogue->add(array(
            'foo' => 'bar',
        ));
        $catalogue->setMetadata('foo', array('target-attributes' => array('state' => 'needs-translation')));

        $dumper = new XliffFileDumper();

        $this->assertStringEqualsFile(
            __DIR__.'/../fixtures/resources-target-attributes.xlf',
            $dumper->formatCatalogue($catalogue, 'messages', array('default_locale' => 'fr_FR'))
        );
    }
}
PKϤ$Z��ԙGG/translation/Tests/Dumper/YamlFileDumperTest.phpnu�[���<?php

/*
 * This file is part of the Symfony package.
 *
 * (c) Fabien Potencier <fabien@symfony.com>
 *
 * For the full copyright and license information, please view the LICENSE
 * file that was distributed with this source code.
 */

namespace Symfony\Component\Translation\Tests\Dumper;

use Symfony\Component\Translation\MessageCatalogue;
use Symfony\Component\Translation\Dumper\YamlFileDumper;

class YamlFileDumperTest extends \PHPUnit_Framework_TestCase
{
    public function testTreeFormatCatalogue()
    {
        $catalogue = new MessageCatalogue('en');
        $catalogue->add(
            array(
                'foo.bar1' => 'value1',
                'foo.bar2' => 'value2',
            ));

        $dumper = new YamlFileDumper();

        $this->assertStringEqualsFile(__DIR__.'/../fixtures/messages.yml', $dumper->formatCatalogue($catalogue, 'messages', array('as_tree' => true, 'inline' => 999)));
    }

    public function testLinearFormatCatalogue()
    {
        $catalogue = new MessageCatalogue('en');
        $catalogue->add(
            array(
                'foo.bar1' => 'value1',
                'foo.bar2' => 'value2',
            ));

        $dumper = new YamlFileDumper();

        $this->assertStringEqualsFile(__DIR__.'/../fixtures/messages_linear.yml', $dumper->formatCatalogue($catalogue, 'messages'));
    }
}
PKϤ$ZR��

-translation/Tests/Dumper/PoFileDumperTest.phpnu�[���<?php

/*
 * This file is part of the Symfony package.
 *
 * (c) Fabien Potencier <fabien@symfony.com>
 *
 * For the full copyright and license information, please view the LICENSE
 * file that was distributed with this source code.
 */

namespace Symfony\Component\Translation\Tests\Dumper;

use Symfony\Component\Translation\MessageCatalogue;
use Symfony\Component\Translation\Dumper\PoFileDumper;

class PoFileDumperTest extends \PHPUnit_Framework_TestCase
{
    public function testFormatCatalogue()
    {
        $catalogue = new MessageCatalogue('en');
        $catalogue->add(array('foo' => 'bar'));

        $dumper = new PoFileDumper();

        $this->assertStringEqualsFile(__DIR__.'/../fixtures/resources.po', $dumper->formatCatalogue($catalogue, 'messages'));
    }
}
PKϤ$Z\p�55.translation/Tests/Dumper/CsvFileDumperTest.phpnu�[���<?php

/*
 * This file is part of the Symfony package.
 *
 * (c) Fabien Potencier <fabien@symfony.com>
 *
 * For the full copyright and license information, please view the LICENSE
 * file that was distributed with this source code.
 */

namespace Symfony\Component\Translation\Tests\Dumper;

use Symfony\Component\Translation\MessageCatalogue;
use Symfony\Component\Translation\Dumper\CsvFileDumper;

class CsvFileDumperTest extends \PHPUnit_Framework_TestCase
{
    public function testFormatCatalogue()
    {
        $catalogue = new MessageCatalogue('en');
        $catalogue->add(array('foo' => 'bar', 'bar' => 'foo
foo', 'foo;foo' => 'bar'));

        $dumper = new CsvFileDumper();

        $this->assertStringEqualsFile(__DIR__.'/../fixtures/valid.csv', $dumper->formatCatalogue($catalogue, 'messages'));
    }
}
PKϤ$Z� k.translation/Tests/Dumper/IniFileDumperTest.phpnu�[���<?php

/*
 * This file is part of the Symfony package.
 *
 * (c) Fabien Potencier <fabien@symfony.com>
 *
 * For the full copyright and license information, please view the LICENSE
 * file that was distributed with this source code.
 */

namespace Symfony\Component\Translation\Tests\Dumper;

use Symfony\Component\Translation\MessageCatalogue;
use Symfony\Component\Translation\Dumper\IniFileDumper;

class IniFileDumperTest extends \PHPUnit_Framework_TestCase
{
    public function testFormatCatalogue()
    {
        $catalogue = new MessageCatalogue('en');
        $catalogue->add(array('foo' => 'bar'));

        $dumper = new IniFileDumper();

        $this->assertStringEqualsFile(__DIR__.'/../fixtures/resources.ini', $dumper->formatCatalogue($catalogue, 'messages'));
    }
}
PKϤ$Z����

-translation/Tests/Dumper/MoFileDumperTest.phpnu�[���<?php

/*
 * This file is part of the Symfony package.
 *
 * (c) Fabien Potencier <fabien@symfony.com>
 *
 * For the full copyright and license information, please view the LICENSE
 * file that was distributed with this source code.
 */

namespace Symfony\Component\Translation\Tests\Dumper;

use Symfony\Component\Translation\MessageCatalogue;
use Symfony\Component\Translation\Dumper\MoFileDumper;

class MoFileDumperTest extends \PHPUnit_Framework_TestCase
{
    public function testFormatCatalogue()
    {
        $catalogue = new MessageCatalogue('en');
        $catalogue->add(array('foo' => 'bar'));

        $dumper = new MoFileDumper();

        $this->assertStringEqualsFile(__DIR__.'/../fixtures/resources.mo', $dumper->formatCatalogue($catalogue, 'messages'));
    }
}
PKϤ$Z݈�n.translation/Tests/Dumper/PhpFileDumperTest.phpnu�[���<?php

/*
 * This file is part of the Symfony package.
 *
 * (c) Fabien Potencier <fabien@symfony.com>
 *
 * For the full copyright and license information, please view the LICENSE
 * file that was distributed with this source code.
 */

namespace Symfony\Component\Translation\Tests\Dumper;

use Symfony\Component\Translation\MessageCatalogue;
use Symfony\Component\Translation\Dumper\PhpFileDumper;

class PhpFileDumperTest extends \PHPUnit_Framework_TestCase
{
    public function testFormatCatalogue()
    {
        $catalogue = new MessageCatalogue('en');
        $catalogue->add(array('foo' => 'bar'));

        $dumper = new PhpFileDumper();

        $this->assertStringEqualsFile(__DIR__.'/../fixtures/resources.php', $dumper->formatCatalogue($catalogue, 'messages'));
    }
}
PKϤ$Z��M��+translation/Tests/Dumper/FileDumperTest.phpnu�[���<?php

/*
 * This file is part of the Symfony package.
 *
 * (c) Fabien Potencier <fabien@symfony.com>
 *
 * For the full copyright and license information, please view the LICENSE
 * file that was distributed with this source code.
 */

namespace Symfony\Component\Translation\Tests\Dumper;

use Symfony\Component\Translation\MessageCatalogue;
use Symfony\Component\Translation\Dumper\FileDumper;

class FileDumperTest extends \PHPUnit_Framework_TestCase
{
    public function testDump()
    {
        $tempDir = sys_get_temp_dir();

        $catalogue = new MessageCatalogue('en');
        $catalogue->add(array('foo' => 'bar'));

        $dumper = new ConcreteFileDumper();
        $dumper->dump($catalogue, array('path' => $tempDir));

        $this->assertTrue(file_exists($tempDir.'/messages.en.concrete'));
    }

    public function testDumpBackupsFileIfExisting()
    {
        $tempDir = sys_get_temp_dir();
        $file = $tempDir.'/messages.en.concrete';
        $backupFile = $file.'~';

        @touch($file);

        $catalogue = new MessageCatalogue('en');
        $catalogue->add(array('foo' => 'bar'));

        $dumper = new ConcreteFileDumper();
        $dumper->dump($catalogue, array('path' => $tempDir));

        $this->assertTrue(file_exists($backupFile));

        @unlink($file);
        @unlink($backupFile);
    }

    public function testDumpCreatesNestedDirectoriesAndFile()
    {
        $tempDir = sys_get_temp_dir();
        $translationsDir = $tempDir.'/test/translations';
        $file = $translationsDir.'/messages.en.concrete';

        $catalogue = new MessageCatalogue('en');
        $catalogue->add(array('foo' => 'bar'));

        $dumper = new ConcreteFileDumper();
        $dumper->setRelativePathTemplate('test/translations/%domain%.%locale%.%extension%');
        $dumper->dump($catalogue, array('path' => $tempDir));

        $this->assertTrue(file_exists($file));

        @unlink($file);
        @rmdir($translationsDir);
    }
}

class ConcreteFileDumper extends FileDumper
{
    public function formatCatalogue(MessageCatalogue $messages, $domain, array $options = array())
    {
        return '';
    }

    protected function getExtension()
    {
        return 'concrete';
    }
}
PKϤ$ZA�~C&&1translation/Tests/Dumper/IcuResFileDumperTest.phpnu�[���<?php

/*
 * This file is part of the Symfony package.
 *
 * (c) Fabien Potencier <fabien@symfony.com>
 *
 * For the full copyright and license information, please view the LICENSE
 * file that was distributed with this source code.
 */

namespace Symfony\Component\Translation\Tests\Dumper;

use Symfony\Component\Translation\MessageCatalogue;
use Symfony\Component\Translation\Dumper\IcuResFileDumper;

class IcuResFileDumperTest extends \PHPUnit_Framework_TestCase
{
    public function testFormatCatalogue()
    {
        $catalogue = new MessageCatalogue('en');
        $catalogue->add(array('foo' => 'bar'));

        $dumper = new IcuResFileDumper();

        $this->assertStringEqualsFile(__DIR__.'/../fixtures/resourcebundle/res/en.res', $dumper->formatCatalogue($catalogue, 'messages'));
    }
}
PKϤ$Zr��ݢ�1translation/Tests/DataCollectorTranslatorTest.phpnu�[���<?php

/*
 * This file is part of the Symfony package.
 *
 * (c) Fabien Potencier <fabien@symfony.com>
 *
 * For the full copyright and license information, please view the LICENSE
 * file that was distributed with this source code.
 */

namespace Symfony\Component\Translation\Tests;

use Symfony\Component\Translation\Translator;
use Symfony\Component\Translation\DataCollectorTranslator;
use Symfony\Component\Translation\Loader\ArrayLoader;

class DataCollectorTranslatorTest extends \PHPUnit_Framework_TestCase
{
    public function testCollectMessages()
    {
        $collector = $this->createCollector();
        $collector->setFallbackLocales(array('fr', 'ru'));

        $collector->trans('foo');
        $collector->trans('bar');
        $collector->transChoice('choice', 0);
        $collector->trans('bar_ru');
        $collector->trans('bar_ru', array('foo' => 'bar'));

        $expectedMessages = array();
        $expectedMessages[] = array(
              'id' => 'foo',
              'translation' => 'foo (en)',
              'locale' => 'en',
              'domain' => 'messages',
              'state' => DataCollectorTranslator::MESSAGE_DEFINED,
              'parameters' => array(),
              'transChoiceNumber' => null,
        );
        $expectedMessages[] = array(
              'id' => 'bar',
              'translation' => 'bar (fr)',
              'locale' => 'fr',
              'domain' => 'messages',
              'state' => DataCollectorTranslator::MESSAGE_EQUALS_FALLBACK,
              'parameters' => array(),
              'transChoiceNumber' => null,
        );
        $expectedMessages[] = array(
              'id' => 'choice',
              'translation' => 'choice',
              'locale' => 'en',
              'domain' => 'messages',
              'state' => DataCollectorTranslator::MESSAGE_MISSING,
              'parameters' => array(),
              'transChoiceNumber' => 0,
        );
        $expectedMessages[] = array(
              'id' => 'bar_ru',
              'translation' => 'bar (ru)',
              'locale' => 'ru',
              'domain' => 'messages',
              'state' => DataCollectorTranslator::MESSAGE_EQUALS_FALLBACK,
              'parameters' => array(),
              'transChoiceNumber' => null,
        );
        $expectedMessages[] = array(
              'id' => 'bar_ru',
              'translation' => 'bar (ru)',
              'locale' => 'ru',
              'domain' => 'messages',
              'state' => DataCollectorTranslator::MESSAGE_EQUALS_FALLBACK,
              'parameters' => array('foo' => 'bar'),
              'transChoiceNumber' => null,
        );

        $this->assertEquals($expectedMessages, $collector->getCollectedMessages());
    }

    private function createCollector()
    {
        $translator = new Translator('en');
        $translator->addLoader('array', new ArrayLoader());
        $translator->addResource('array', array('foo' => 'foo (en)'), 'en');
        $translator->addResource('array', array('bar' => 'bar (fr)'), 'fr');
        $translator->addResource('array', array('bar_ru' => 'bar (ru)'), 'ru');

        $collector = new DataCollectorTranslator($translator);

        return $collector;
    }
}
PKϤ$Z1J��+translation/Tests/LoggingTranslatorTest.phpnu�[���<?php

/*
 * This file is part of the Symfony package.
 *
 * (c) Fabien Potencier <fabien@symfony.com>
 *
 * For the full copyright and license information, please view the LICENSE
 * file that was distributed with this source code.
 */

namespace Symfony\Component\Translation\Tests;

use Symfony\Component\Translation\Translator;
use Symfony\Component\Translation\LoggingTranslator;
use Symfony\Component\Translation\Loader\ArrayLoader;

class LoggingTranslatorTest extends \PHPUnit_Framework_TestCase
{
    public function testTransWithNoTranslationIsLogged()
    {
        $logger = $this->getMock('Psr\Log\LoggerInterface');
        $logger->expects($this->exactly(2))
            ->method('warning')
            ->with('Translation not found.')
        ;

        $translator = new Translator('ar');
        $loggableTranslator = new LoggingTranslator($translator, $logger);
        $loggableTranslator->transChoice('some_message2', 10, array('%count%' => 10));
        $loggableTranslator->trans('bar');
    }

    public function testTransChoiceFallbackIsLogged()
    {
        $logger = $this->getMock('Psr\Log\LoggerInterface');
        $logger->expects($this->once())
            ->method('debug')
            ->with('Translation use fallback catalogue.')
        ;

        $translator = new Translator('ar');
        $translator->setFallbackLocales(array('en'));
        $translator->addLoader('array', new ArrayLoader());
        $translator->addResource('array', array('some_message2' => 'one thing|%count% things'), 'en');
        $loggableTranslator = new LoggingTranslator($translator, $logger);
        $loggableTranslator->transChoice('some_message2', 10, array('%count%' => 10));
    }
}
PKϤ$ZH8#|+|+)translation/Tests/TranslatorCacheTest.phpnu�[���<?php

/*
 * This file is part of the Symfony package.
 *
 * (c) Fabien Potencier <fabien@symfony.com>
 *
 * For the full copyright and license information, please view the LICENSE
 * file that was distributed with this source code.
 */

namespace Symfony\Component\Translation\Tests;

use Symfony\Component\Config\Resource\SelfCheckingResourceInterface;
use Symfony\Component\Translation\Loader\ArrayLoader;
use Symfony\Component\Translation\Loader\LoaderInterface;
use Symfony\Component\Translation\Translator;
use Symfony\Component\Translation\MessageCatalogue;

class TranslatorCacheTest extends \PHPUnit_Framework_TestCase
{
    protected $tmpDir;

    protected function setUp()
    {
        $this->tmpDir = sys_get_temp_dir().'/sf2_translation';
        $this->deleteTmpDir();
    }

    protected function tearDown()
    {
        $this->deleteTmpDir();
    }

    protected function deleteTmpDir()
    {
        if (!file_exists($dir = $this->tmpDir)) {
            return;
        }

        $iterator = new \RecursiveIteratorIterator(new \RecursiveDirectoryIterator($this->tmpDir), \RecursiveIteratorIterator::CHILD_FIRST);
        foreach ($iterator as $path) {
            if (preg_match('#[/\\\\]\.\.?$#', $path->__toString())) {
                continue;
            }
            if ($path->isDir()) {
                rmdir($path->__toString());
            } else {
                unlink($path->__toString());
            }
        }
        rmdir($this->tmpDir);
    }

    /**
     * @dataProvider runForDebugAndProduction
     */
    public function testThatACacheIsUsed($debug)
    {
        $locale = 'any_locale';
        $format = 'some_format';
        $msgid = 'test';

        // Prime the cache
        $translator = new Translator($locale, null, $this->tmpDir, $debug);
        $translator->addLoader($format, new ArrayLoader());
        $translator->addResource($format, array($msgid => 'OK'), $locale);
        $translator->trans($msgid);

        // Try again and see we get a valid result whilst no loader can be used
        $translator = new Translator($locale, null, $this->tmpDir, $debug);
        $translator->addLoader($format, $this->createFailingLoader());
        $translator->addResource($format, array($msgid => 'OK'), $locale);
        $this->assertEquals('OK', $translator->trans($msgid), '-> caching does not work in '.($debug ? 'debug' : 'production'));
    }

    public function testCatalogueIsReloadedWhenResourcesAreNoLongerFresh()
    {
        /*
         * The testThatACacheIsUsed() test showed that we don't need the loader as long as the cache
         * is fresh.
         *
         * Now we add a Resource that is never fresh and make sure that the
         * cache is discarded (the loader is called twice).
         *
         * We need to run this for debug=true only because in production the cache
         * will never be revalidated.
         */

        $locale = 'any_locale';
        $format = 'some_format';
        $msgid = 'test';

        $catalogue = new MessageCatalogue($locale, array());
        $catalogue->addResource(new StaleResource()); // better use a helper class than a mock, because it gets serialized in the cache and re-loaded

        /** @var LoaderInterface|\PHPUnit_Framework_MockObject_MockObject $loader */
        $loader = $this->getMock('Symfony\Component\Translation\Loader\LoaderInterface');
        $loader
            ->expects($this->exactly(2))
            ->method('load')
            ->will($this->returnValue($catalogue))
        ;

        // 1st pass
        $translator = new Translator($locale, null, $this->tmpDir, true);
        $translator->addLoader($format, $loader);
        $translator->addResource($format, null, $locale);
        $translator->trans($msgid);

        // 2nd pass
        $translator = new Translator($locale, null, $this->tmpDir, true);
        $translator->addLoader($format, $loader);
        $translator->addResource($format, null, $locale);
        $translator->trans($msgid);
    }

    /**
     * @dataProvider runForDebugAndProduction
     */
    public function testDifferentTranslatorsForSameLocaleDoNotOverwriteEachOthersCache($debug)
    {
        /*
         * Similar to the previous test. After we used the second translator, make
         * sure there's still a useable cache for the first one.
         */

        $locale = 'any_locale';
        $format = 'some_format';
        $msgid = 'test';

        // Create a Translator and prime its cache
        $translator = new Translator($locale, null, $this->tmpDir, $debug);
        $translator->addLoader($format, new ArrayLoader());
        $translator->addResource($format, array($msgid => 'OK'), $locale);
        $translator->trans($msgid);

        // Create another Translator with a different catalogue for the same locale
        $translator = new Translator($locale, null, $this->tmpDir, $debug);
        $translator->addLoader($format, new ArrayLoader());
        $translator->addResource($format, array($msgid => 'FAIL'), $locale);
        $translator->trans($msgid);

        // Now the first translator must still have a useable cache.
        $translator = new Translator($locale, null, $this->tmpDir, $debug);
        $translator->addLoader($format, $this->createFailingLoader());
        $translator->addResource($format, array($msgid => 'OK'), $locale);
        $this->assertEquals('OK', $translator->trans($msgid), '-> the cache was overwritten by another translator instance in '.($debug ? 'debug' : 'production'));
    }

    public function testDifferentCacheFilesAreUsedForDifferentSetsOfFallbackLocales()
    {
        /*
         * Because the cache file contains a catalogue including all of its fallback
         * catalogues, we must take the set of fallback locales into consideration when
         * loading a catalogue from the cache.
         */
        $translator = new Translator('a', null, $this->tmpDir);
        $translator->setFallbackLocales(array('b'));

        $translator->addLoader('array', new ArrayLoader());
        $translator->addResource('array', array('foo' => 'foo (a)'), 'a');
        $translator->addResource('array', array('bar' => 'bar (b)'), 'b');

        $this->assertEquals('bar (b)', $translator->trans('bar'));

        // Remove fallback locale
        $translator->setFallbackLocales(array());
        $this->assertEquals('bar', $translator->trans('bar'));

        // Use a fresh translator with no fallback locales, result should be the same
        $translator = new Translator('a', null, $this->tmpDir);

        $translator->addLoader('array', new ArrayLoader());
        $translator->addResource('array', array('foo' => 'foo (a)'), 'a');
        $translator->addResource('array', array('bar' => 'bar (b)'), 'b');

        $this->assertEquals('bar', $translator->trans('bar'));
    }

    public function testPrimaryAndFallbackCataloguesContainTheSameMessagesRegardlessOfCaching()
    {
        /*
         * As a safeguard against potential BC breaks, make sure that primary and fallback
         * catalogues (reachable via getFallbackCatalogue()) always contain the full set of
         * messages provided by the loader. This must also be the case when these catalogues
         * are (internally) read from a cache.
         *
         * Optimizations inside the translator must not change this behaviour.
         */

        /*
         * Create a translator that loads two catalogues for two different locales.
         * The catalogues contain distinct sets of messages.
         */
        $translator = new Translator('a', null, $this->tmpDir);
        $translator->setFallbackLocales(array('b'));

        $translator->addLoader('array', new ArrayLoader());
        $translator->addResource('array', array('foo' => 'foo (a)'), 'a');
        $translator->addResource('array', array('foo' => 'foo (b)'), 'b');
        $translator->addResource('array', array('bar' => 'bar (b)'), 'b');

        $catalogue = $translator->getCatalogue('a');
        $this->assertFalse($catalogue->defines('bar')); // Sure, the "a" catalogue does not contain that message.

        $fallback = $catalogue->getFallbackCatalogue();
        $this->assertTrue($fallback->defines('foo')); // "foo" is present in "a" and "b"

        /*
         * Now, repeat the same test.
         * Behind the scenes, the cache is used. But that should not matter, right?
         */
        $translator = new Translator('a', null, $this->tmpDir);
        $translator->setFallbackLocales(array('b'));

        $translator->addLoader('array', new ArrayLoader());
        $translator->addResource('array', array('foo' => 'foo (a)'), 'a');
        $translator->addResource('array', array('foo' => 'foo (b)'), 'b');
        $translator->addResource('array', array('bar' => 'bar (b)'), 'b');

        $catalogue = $translator->getCatalogue('a');
        $this->assertFalse($catalogue->defines('bar'));

        $fallback = $catalogue->getFallbackCatalogue();
        $this->assertTrue($fallback->defines('foo'));
    }

    public function testRefreshCacheWhenResourcesAreNoLongerFresh()
    {
        $resource = $this->getMock('Symfony\Component\Config\Resource\SelfCheckingResourceInterface');
        $loader = $this->getMock('Symfony\Component\Translation\Loader\LoaderInterface');
        $resource->method('isFresh')->will($this->returnValue(false));
        $loader
            ->expects($this->exactly(2))
            ->method('load')
            ->will($this->returnValue($this->getCatalogue('fr', array(), array($resource))));

        // prime the cache
        $translator = new Translator('fr', null, $this->tmpDir, true);
        $translator->addLoader('loader', $loader);
        $translator->addResource('loader', 'foo', 'fr');
        $translator->trans('foo');

        // prime the cache second time
        $translator = new Translator('fr', null, $this->tmpDir, true);
        $translator->addLoader('loader', $loader);
        $translator->addResource('loader', 'foo', 'fr');
        $translator->trans('foo');
    }

    protected function getCatalogue($locale, $messages, $resources = array())
    {
        $catalogue = new MessageCatalogue($locale);
        foreach ($messages as $key => $translation) {
            $catalogue->set($key, $translation);
        }
        foreach ($resources as $resource) {
            $catalogue->addResource($resource);
        }

        return $catalogue;
    }

    public function runForDebugAndProduction()
    {
        return array(array(true), array(false));
    }

    /**
     * @return LoaderInterface
     */
    private function createFailingLoader()
    {
        $loader = $this->getMock('Symfony\Component\Translation\Loader\LoaderInterface');
        $loader
            ->expects($this->never())
            ->method('load');

        return $loader;
    }
}

class StaleResource implements SelfCheckingResourceInterface
{
    public function isFresh($timestamp)
    {
        return false;
    }

    public function getResource()
    {
    }

    public function __toString()
    {
        return '';
    }
}
PKϤ$Zo���((,translation/Tests/PluralizationRulesTest.phpnu�[���<?php

/*
 * This file is part of the Symfony package.
 *
 * (c) Fabien Potencier <fabien@symfony.com>
 *
 * For the full copyright and license information, please view the LICENSE
 * file that was distributed with this source code.
 */

namespace Symfony\Component\Translation\Tests;

use Symfony\Component\Translation\PluralizationRules;

/**
 * Test should cover all languages mentioned on http://translate.sourceforge.net/wiki/l10n/pluralforms
 * and Plural forms mentioned on http://www.gnu.org/software/gettext/manual/gettext.html#Plural-forms.
 *
 * See also https://developer.mozilla.org/en/Localization_and_Plurals which mentions 15 rules having a maximum of 6 forms.
 * The mozilla code is also interesting to check for.
 *
 * As mentioned by chx http://drupal.org/node/1273968 we can cover all by testing number from 0 to 199
 *
 * The goal to cover all languages is to far fetched so this test case is smaller.
 *
 * @author Clemens Tolboom clemens@build2be.nl
 */
class PluralizationRulesTest extends \PHPUnit_Framework_TestCase
{
    /**
     * We test failed langcode here.
     *
     * TODO: The languages mentioned in the data provide need to get fixed somehow within PluralizationRules.
     *
     * @dataProvider failingLangcodes
     */
    public function testFailedLangcodes($nplural, $langCodes)
    {
        $matrix = $this->generateTestData($nplural, $langCodes);
        $this->validateMatrix($nplural, $matrix, false);
    }

    /**
     * @dataProvider successLangcodes
     */
    public function testLangcodes($nplural, $langCodes)
    {
        $matrix = $this->generateTestData($nplural, $langCodes);
        $this->validateMatrix($nplural, $matrix);
    }

    /**
     * This array should contain all currently known langcodes.
     *
     * As it is impossible to have this ever complete we should try as hard as possible to have it almost complete.
     *
     * @return array
     */
    public function successLangcodes()
    {
        return array(
            array('1', array('ay', 'bo', 'cgg', 'dz', 'id', 'ja', 'jbo', 'ka', 'kk', 'km', 'ko', 'ky')),
            array('2', array('nl', 'fr', 'en', 'de', 'de_GE', 'hy', 'hy_AM')),
            array('3', array('be', 'bs', 'cs', 'hr')),
            array('4', array('cy', 'mt', 'sl')),
            array('5', array()),
            array('6', array('ar')),
        );
    }

    /**
     * This array should be at least empty within the near future.
     *
     * This both depends on a complete list trying to add above as understanding
     * the plural rules of the current failing languages.
     *
     * @return array with nplural together with langcodes
     */
    public function failingLangcodes()
    {
        return array(
            array('1', array('fa')),
            array('2', array('jbo')),
            array('3', array('cbs')),
            array('4', array('gd', 'kw')),
            array('5', array('ga')),
            array('6', array()),
        );
    }

    /**
     * We validate only on the plural coverage. Thus the real rules is not tested.
     *
     * @param string $nplural       plural expected
     * @param array  $matrix        containing langcodes and their plural index values.
     * @param bool   $expectSuccess
     */
    protected function validateMatrix($nplural, $matrix, $expectSuccess = true)
    {
        foreach ($matrix as $langCode => $data) {
            $indexes = array_flip($data);
            if ($expectSuccess) {
                $this->assertEquals($nplural, count($indexes), "Langcode '$langCode' has '$nplural' plural forms.");
            } else {
                $this->assertNotEquals((int) $nplural, count($indexes), "Langcode '$langCode' has '$nplural' plural forms.");
            }
        }
    }

    protected function generateTestData($plural, $langCodes)
    {
        $matrix = array();
        foreach ($langCodes as $langCode) {
            for ($count = 0; $count < 200; ++$count) {
                $plural = PluralizationRules::get($count, $langCode);
                $matrix[$langCode][$count] = $plural;
            }
        }

        return $matrix;
    }
}
PKϤ$Z�Cr��)translation/Tests/MessageSelectorTest.phpnu�[���<?php

/*
 * This file is part of the Symfony package.
 *
 * (c) Fabien Potencier <fabien@symfony.com>
 *
 * For the full copyright and license information, please view the LICENSE
 * file that was distributed with this source code.
 */

namespace Symfony\Component\Translation\Tests;

use Symfony\Component\Translation\MessageSelector;

class MessageSelectorTest extends \PHPUnit_Framework_TestCase
{
    /**
     * @dataProvider getChooseTests
     */
    public function testChoose($expected, $id, $number)
    {
        $selector = new MessageSelector();

        $this->assertEquals($expected, $selector->choose($id, $number, 'en'));
    }

    public function testReturnMessageIfExactlyOneStandardRuleIsGiven()
    {
        $selector = new MessageSelector();

        $this->assertEquals('There are two apples', $selector->choose('There are two apples', 2, 'en'));
    }

    /**
     * @dataProvider getNonMatchingMessages
     * @expectedException \InvalidArgumentException
     */
    public function testThrowExceptionIfMatchingMessageCannotBeFound($id, $number)
    {
        $selector = new MessageSelector();

        $selector->choose($id, $number, 'en');
    }

    public function getNonMatchingMessages()
    {
        return array(
            array('{0} There are no apples|{1} There is one apple', 2),
            array('{1} There is one apple|]1,Inf] There are %count% apples', 0),
            array('{1} There is one apple|]2,Inf] There are %count% apples', 2),
            array('{0} There are no apples|There is one apple', 2),
        );
    }

    public function getChooseTests()
    {
        return array(
            array('There are no apples', '{0} There are no apples|{1} There is one apple|]1,Inf] There are %count% apples', 0),
            array('There are no apples', '{0}     There are no apples|{1} There is one apple|]1,Inf] There are %count% apples', 0),
            array('There are no apples', '{0}There are no apples|{1} There is one apple|]1,Inf] There are %count% apples', 0),

            array('There is one apple', '{0} There are no apples|{1} There is one apple|]1,Inf] There are %count% apples', 1),

            array('There are %count% apples', '{0} There are no apples|{1} There is one apple|]1,Inf] There are %count% apples', 10),
            array('There are %count% apples', '{0} There are no apples|{1} There is one apple|]1,Inf]There are %count% apples', 10),
            array('There are %count% apples', '{0} There are no apples|{1} There is one apple|]1,Inf]     There are %count% apples', 10),

            array('There are %count% apples', 'There is one apple|There are %count% apples', 0),
            array('There is one apple', 'There is one apple|There are %count% apples', 1),
            array('There are %count% apples', 'There is one apple|There are %count% apples', 10),

            array('There are %count% apples', 'one: There is one apple|more: There are %count% apples', 0),
            array('There is one apple', 'one: There is one apple|more: There are %count% apples', 1),
            array('There are %count% apples', 'one: There is one apple|more: There are %count% apples', 10),

            array('There are no apples', '{0} There are no apples|one: There is one apple|more: There are %count% apples', 0),
            array('There is one apple', '{0} There are no apples|one: There is one apple|more: There are %count% apples', 1),
            array('There are %count% apples', '{0} There are no apples|one: There is one apple|more: There are %count% apples', 10),

            array('', '{0}|{1} There is one apple|]1,Inf] There are %count% apples', 0),
            array('', '{0} There are no apples|{1}|]1,Inf] There are %count% apples', 1),

            // Indexed only tests which are Gettext PoFile* compatible strings.
            array('There are %count% apples', 'There is one apple|There are %count% apples', 0),
            array('There is one apple', 'There is one apple|There are %count% apples', 1),
            array('There are %count% apples', 'There is one apple|There are %count% apples', 2),

            // Tests for float numbers
            array('There is almost one apple', '{0} There are no apples|]0,1[ There is almost one apple|{1} There is one apple|[1,Inf] There is more than one apple', 0.7),
            array('There is one apple', '{0} There are no apples|]0,1[There are %count% apples|{1} There is one apple|[1,Inf] There is more than one apple', 1),
            array('There is more than one apple', '{0} There are no apples|]0,1[There are %count% apples|{1} There is one apple|[1,Inf] There is more than one apple', 1.7),
            array('There are no apples', '{0} There are no apples|]0,1[There are %count% apples|{1} There is one apple|[1,Inf] There is more than one apple', 0),
            array('There are no apples', '{0} There are no apples|]0,1[There are %count% apples|{1} There is one apple|[1,Inf] There is more than one apple', 0.0),
            array('There are no apples', '{0.0} There are no apples|]0,1[There are %count% apples|{1} There is one apple|[1,Inf] There is more than one apple', 0),

            // Test texts with new-lines
            // with double-quotes and \n in id & double-quotes and actual newlines in text
            array("This is a text with a\n            new-line in it. Selector = 0.", '{0}This is a text with a
            new-line in it. Selector = 0.|{1}This is a text with a
            new-line in it. Selector = 1.|[1,Inf]This is a text with a
            new-line in it. Selector > 1.', 0),
            // with double-quotes and \n in id and single-quotes and actual newlines in text
            array("This is a text with a\n            new-line in it. Selector = 1.", '{0}This is a text with a
            new-line in it. Selector = 0.|{1}This is a text with a
            new-line in it. Selector = 1.|[1,Inf]This is a text with a
            new-line in it. Selector > 1.', 1),
            array("This is a text with a\n            new-line in it. Selector > 1.", '{0}This is a text with a
            new-line in it. Selector = 0.|{1}This is a text with a
            new-line in it. Selector = 1.|[1,Inf]This is a text with a
            new-line in it. Selector > 1.', 5),
            // with double-quotes and id split accros lines
            array('This is a text with a
            new-line in it. Selector = 1.', '{0}This is a text with a
            new-line in it. Selector = 0.|{1}This is a text with a
            new-line in it. Selector = 1.|[1,Inf]This is a text with a
            new-line in it. Selector > 1.', 1),
            // with single-quotes and id split accros lines
            array('This is a text with a
            new-line in it. Selector > 1.', '{0}This is a text with a
            new-line in it. Selector = 0.|{1}This is a text with a
            new-line in it. Selector = 1.|[1,Inf]This is a text with a
            new-line in it. Selector > 1.', 5),
            // with single-quotes and \n in text
            array('This is a text with a\nnew-line in it. Selector = 0.', '{0}This is a text with a\nnew-line in it. Selector = 0.|{1}This is a text with a\nnew-line in it. Selector = 1.|[1,Inf]This is a text with a\nnew-line in it. Selector > 1.', 0),
            // with double-quotes and id split accros lines
            array("This is a text with a\nnew-line in it. Selector = 1.", "{0}This is a text with a\nnew-line in it. Selector = 0.|{1}This is a text with a\nnew-line in it. Selector = 1.|[1,Inf]This is a text with a\nnew-line in it. Selector > 1.", 1),
        );
    }
}
PKϤ$Z�� � *translation/Tests/MessageCatalogueTest.phpnu�[���<?php

/*
 * This file is part of the Symfony package.
 *
 * (c) Fabien Potencier <fabien@symfony.com>
 *
 * For the full copyright and license information, please view the LICENSE
 * file that was distributed with this source code.
 */

namespace Symfony\Component\Translation\Tests;

use Symfony\Component\Translation\MessageCatalogue;

class MessageCatalogueTest extends \PHPUnit_Framework_TestCase
{
    public function testGetLocale()
    {
        $catalogue = new MessageCatalogue('en');

        $this->assertEquals('en', $catalogue->getLocale());
    }

    public function testGetDomains()
    {
        $catalogue = new MessageCatalogue('en', array('domain1' => array(), 'domain2' => array()));

        $this->assertEquals(array('domain1', 'domain2'), $catalogue->getDomains());
    }

    public function testAll()
    {
        $catalogue = new MessageCatalogue('en', $messages = array('domain1' => array('foo' => 'foo'), 'domain2' => array('bar' => 'bar')));

        $this->assertEquals(array('foo' => 'foo'), $catalogue->all('domain1'));
        $this->assertEquals(array(), $catalogue->all('domain88'));
        $this->assertEquals($messages, $catalogue->all());
    }

    public function testHas()
    {
        $catalogue = new MessageCatalogue('en', array('domain1' => array('foo' => 'foo'), 'domain2' => array('bar' => 'bar')));

        $this->assertTrue($catalogue->has('foo', 'domain1'));
        $this->assertFalse($catalogue->has('bar', 'domain1'));
        $this->assertFalse($catalogue->has('foo', 'domain88'));
    }

    public function testGetSet()
    {
        $catalogue = new MessageCatalogue('en', array('domain1' => array('foo' => 'foo'), 'domain2' => array('bar' => 'bar')));
        $catalogue->set('foo1', 'foo1', 'domain1');

        $this->assertEquals('foo', $catalogue->get('foo', 'domain1'));
        $this->assertEquals('foo1', $catalogue->get('foo1', 'domain1'));
    }

    public function testAdd()
    {
        $catalogue = new MessageCatalogue('en', array('domain1' => array('foo' => 'foo'), 'domain2' => array('bar' => 'bar')));
        $catalogue->add(array('foo1' => 'foo1'), 'domain1');

        $this->assertEquals('foo', $catalogue->get('foo', 'domain1'));
        $this->assertEquals('foo1', $catalogue->get('foo1', 'domain1'));

        $catalogue->add(array('foo' => 'bar'), 'domain1');
        $this->assertEquals('bar', $catalogue->get('foo', 'domain1'));
        $this->assertEquals('foo1', $catalogue->get('foo1', 'domain1'));

        $catalogue->add(array('foo' => 'bar'), 'domain88');
        $this->assertEquals('bar', $catalogue->get('foo', 'domain88'));
    }

    public function testReplace()
    {
        $catalogue = new MessageCatalogue('en', array('domain1' => array('foo' => 'foo'), 'domain2' => array('bar' => 'bar')));
        $catalogue->replace($messages = array('foo1' => 'foo1'), 'domain1');

        $this->assertEquals($messages, $catalogue->all('domain1'));
    }

    public function testAddCatalogue()
    {
        $r = $this->getMock('Symfony\Component\Config\Resource\ResourceInterface');
        $r->expects($this->any())->method('__toString')->will($this->returnValue('r'));

        $r1 = $this->getMock('Symfony\Component\Config\Resource\ResourceInterface');
        $r1->expects($this->any())->method('__toString')->will($this->returnValue('r1'));

        $catalogue = new MessageCatalogue('en', array('domain1' => array('foo' => 'foo'), 'domain2' => array('bar' => 'bar')));
        $catalogue->addResource($r);

        $catalogue1 = new MessageCatalogue('en', array('domain1' => array('foo1' => 'foo1')));
        $catalogue1->addResource($r1);

        $catalogue->addCatalogue($catalogue1);

        $this->assertEquals('foo', $catalogue->get('foo', 'domain1'));
        $this->assertEquals('foo1', $catalogue->get('foo1', 'domain1'));

        $this->assertEquals(array($r, $r1), $catalogue->getResources());
    }

    public function testAddFallbackCatalogue()
    {
        $r = $this->getMock('Symfony\Component\Config\Resource\ResourceInterface');
        $r->expects($this->any())->method('__toString')->will($this->returnValue('r'));

        $r1 = $this->getMock('Symfony\Component\Config\Resource\ResourceInterface');
        $r1->expects($this->any())->method('__toString')->will($this->returnValue('r1'));

        $catalogue = new MessageCatalogue('en_US', array('domain1' => array('foo' => 'foo'), 'domain2' => array('bar' => 'bar')));
        $catalogue->addResource($r);

        $catalogue1 = new MessageCatalogue('en', array('domain1' => array('foo' => 'bar', 'foo1' => 'foo1')));
        $catalogue1->addResource($r1);

        $catalogue->addFallbackCatalogue($catalogue1);

        $this->assertEquals('foo', $catalogue->get('foo', 'domain1'));
        $this->assertEquals('foo1', $catalogue->get('foo1', 'domain1'));

        $this->assertEquals(array($r, $r1), $catalogue->getResources());
    }

    /**
     * @expectedException \LogicException
     */
    public function testAddFallbackCatalogueWithParentCircularReference()
    {
        $main = new MessageCatalogue('en_US');
        $fallback = new MessageCatalogue('fr_FR');

        $fallback->addFallbackCatalogue($main);
        $main->addFallbackCatalogue($fallback);
    }

    /**
     * @expectedException \LogicException
     */
    public function testAddFallbackCatalogueWithFallbackCircularReference()
    {
        $fr = new MessageCatalogue('fr');
        $en = new MessageCatalogue('en');
        $es = new MessageCatalogue('es');

        $fr->addFallbackCatalogue($en);
        $es->addFallbackCatalogue($en);
        $en->addFallbackCatalogue($fr);
    }

    /**
     * @expectedException \LogicException
     */
    public function testAddCatalogueWhenLocaleIsNotTheSameAsTheCurrentOne()
    {
        $catalogue = new MessageCatalogue('en');
        $catalogue->addCatalogue(new MessageCatalogue('fr', array()));
    }

    public function testGetAddResource()
    {
        $catalogue = new MessageCatalogue('en');
        $r = $this->getMock('Symfony\Component\Config\Resource\ResourceInterface');
        $r->expects($this->any())->method('__toString')->will($this->returnValue('r'));
        $catalogue->addResource($r);
        $catalogue->addResource($r);
        $r1 = $this->getMock('Symfony\Component\Config\Resource\ResourceInterface');
        $r1->expects($this->any())->method('__toString')->will($this->returnValue('r1'));
        $catalogue->addResource($r1);

        $this->assertEquals(array($r, $r1), $catalogue->getResources());
    }

    public function testMetadataDelete()
    {
        $catalogue = new MessageCatalogue('en');
        $this->assertEquals(array(), $catalogue->getMetadata('', ''), 'Metadata is empty');
        $catalogue->deleteMetadata('key', 'messages');
        $catalogue->deleteMetadata('', 'messages');
        $catalogue->deleteMetadata();
    }

    public function testMetadataSetGetDelete()
    {
        $catalogue = new MessageCatalogue('en');
        $catalogue->setMetadata('key', 'value');
        $this->assertEquals('value', $catalogue->getMetadata('key', 'messages'), "Metadata 'key' = 'value'");

        $catalogue->setMetadata('key2', array());
        $this->assertEquals(array(), $catalogue->getMetadata('key2', 'messages'), 'Metadata key2 is array');

        $catalogue->deleteMetadata('key2', 'messages');
        $this->assertNull($catalogue->getMetadata('key2', 'messages'), 'Metadata key2 should is deleted.');

        $catalogue->deleteMetadata('key2', 'domain');
        $this->assertNull($catalogue->getMetadata('key2', 'domain'), 'Metadata key2 should is deleted.');
    }

    public function testMetadataMerge()
    {
        $cat1 = new MessageCatalogue('en');
        $cat1->setMetadata('a', 'b');
        $this->assertEquals(array('messages' => array('a' => 'b')), $cat1->getMetadata('', ''), 'Cat1 contains messages metadata.');

        $cat2 = new MessageCatalogue('en');
        $cat2->setMetadata('b', 'c', 'domain');
        $this->assertEquals(array('domain' => array('b' => 'c')), $cat2->getMetadata('', ''), 'Cat2 contains domain metadata.');

        $cat1->addCatalogue($cat2);
        $this->assertEquals(array('messages' => array('a' => 'b'), 'domain' => array('b' => 'c')), $cat1->getMetadata('', ''), 'Cat1 contains merged metadata.');
    }
}
PKϤ$Zd�,�__@translation/Tests/DataCollector/TranslationDataCollectorTest.phpnu�[���<?php

/*
 * This file is part of the Symfony package.
 *
 * (c) Fabien Potencier <fabien@symfony.com>
 *
 * For the full copyright and license information, please view the LICENSE
 * file that was distributed with this source code.
 */

namespace Symfony\Component\Translation\Tests\DataCollector;

use Symfony\Component\Translation\DataCollectorTranslator;
use Symfony\Component\Translation\DataCollector\TranslationDataCollector;

class TranslationDataCollectorTest extends \PHPUnit_Framework_TestCase
{
    protected function setUp()
    {
        if (!class_exists('Symfony\Component\HttpKernel\DataCollector\DataCollector')) {
            $this->markTestSkipped('The "DataCollector" is not available');
        }
    }

    public function testCollectEmptyMessages()
    {
        $translator = $this->getTranslator();
        $translator->expects($this->any())->method('getCollectedMessages')->will($this->returnValue(array()));

        $dataCollector = new TranslationDataCollector($translator);
        $dataCollector->lateCollect();

        $this->assertEquals(0, $dataCollector->getCountMissings());
        $this->assertEquals(0, $dataCollector->getCountFallbacks());
        $this->assertEquals(0, $dataCollector->getCountDefines());
        $this->assertEquals(array(), $dataCollector->getMessages());
    }

    public function testCollect()
    {
        $collectedMessages = array(
            array(
                  'id' => 'foo',
                  'translation' => 'foo (en)',
                  'locale' => 'en',
                  'domain' => 'messages',
                  'state' => DataCollectorTranslator::MESSAGE_DEFINED,
                  'parameters' => array(),
                  'transChoiceNumber' => null,
            ),
            array(
                  'id' => 'bar',
                  'translation' => 'bar (fr)',
                  'locale' => 'fr',
                  'domain' => 'messages',
                  'state' => DataCollectorTranslator::MESSAGE_EQUALS_FALLBACK,
                  'parameters' => array(),
                  'transChoiceNumber' => null,
            ),
            array(
                  'id' => 'choice',
                  'translation' => 'choice',
                  'locale' => 'en',
                  'domain' => 'messages',
                  'state' => DataCollectorTranslator::MESSAGE_MISSING,
                  'parameters' => array('%count%' => 3),
                  'transChoiceNumber' => 3,
            ),
            array(
                  'id' => 'choice',
                  'translation' => 'choice',
                  'locale' => 'en',
                  'domain' => 'messages',
                  'state' => DataCollectorTranslator::MESSAGE_MISSING,
                  'parameters' => array('%count%' => 3),
                  'transChoiceNumber' => 3,
            ),
            array(
                  'id' => 'choice',
                  'translation' => 'choice',
                  'locale' => 'en',
                  'domain' => 'messages',
                  'state' => DataCollectorTranslator::MESSAGE_MISSING,
                  'parameters' => array('%count%' => 4, '%foo%' => 'bar'),
                  'transChoiceNumber' => 4,
            ),
        );
        $expectedMessages = array(
            array(
                  'id' => 'foo',
                  'translation' => 'foo (en)',
                  'locale' => 'en',
                  'domain' => 'messages',
                  'state' => DataCollectorTranslator::MESSAGE_DEFINED,
                  'count' => 1,
                  'parameters' => array(),
                  'transChoiceNumber' => null,
            ),
            array(
                  'id' => 'bar',
                  'translation' => 'bar (fr)',
                  'locale' => 'fr',
                  'domain' => 'messages',
                  'state' => DataCollectorTranslator::MESSAGE_EQUALS_FALLBACK,
                  'count' => 1,
                  'parameters' => array(),
                  'transChoiceNumber' => null,
            ),
            array(
                  'id' => 'choice',
                  'translation' => 'choice',
                  'locale' => 'en',
                  'domain' => 'messages',
                  'state' => DataCollectorTranslator::MESSAGE_MISSING,
                  'count' => 3,
                  'parameters' => array(
                      array('%count%' => 3),
                      array('%count%' => 3),
                      array('%count%' => 4, '%foo%' => 'bar'),
                  ),
                  'transChoiceNumber' => 3,
            ),
        );

        $translator = $this->getTranslator();
        $translator->expects($this->any())->method('getCollectedMessages')->will($this->returnValue($collectedMessages));

        $dataCollector = new TranslationDataCollector($translator);
        $dataCollector->lateCollect();

        $this->assertEquals(1, $dataCollector->getCountMissings());
        $this->assertEquals(1, $dataCollector->getCountFallbacks());
        $this->assertEquals(1, $dataCollector->getCountDefines());
        $this->assertEquals($expectedMessages, array_values($dataCollector->getMessages()));
    }

    private function getTranslator()
    {
        $translator = $this
            ->getMockBuilder('Symfony\Component\Translation\DataCollectorTranslator')
            ->disableOriginalConstructor()
            ->getMock()
        ;

        return $translator;
    }
}
PKϤ$Zi"l3��2translation/Tests/Writer/TranslationWriterTest.phpnu�[���<?php

/*
 * This file is part of the Symfony package.
 *
 * (c) Fabien Potencier <fabien@symfony.com>
 *
 * For the full copyright and license information, please view the LICENSE
 * file that was distributed with this source code.
 */

namespace Symfony\Component\Translation\Tests\Writer;

use Symfony\Component\Translation\Dumper\DumperInterface;
use Symfony\Component\Translation\MessageCatalogue;
use Symfony\Component\Translation\Writer\TranslationWriter;

class TranslationWriterTest extends \PHPUnit_Framework_TestCase
{
    public function testWriteTranslations()
    {
        $dumper = $this->getMock('Symfony\Component\Translation\Dumper\DumperInterface');
        $dumper
            ->expects($this->once())
            ->method('dump');

        $writer = new TranslationWriter();
        $writer->addDumper('test', $dumper);
        $writer->writeTranslations(new MessageCatalogue(array()), 'test');
    }

    public function testDisableBackup()
    {
        $nonBackupDumper = new NonBackupDumper();
        $backupDumper = new BackupDumper();

        $writer = new TranslationWriter();
        $writer->addDumper('non_backup', $nonBackupDumper);
        $writer->addDumper('backup', $backupDumper);
        $writer->disableBackup();

        $this->assertFalse($backupDumper->backup, 'backup can be disabled if setBackup() method does exist');
    }
}

class NonBackupDumper implements DumperInterface
{
    public function dump(MessageCatalogue $messages, $options = array())
    {
    }
}

class BackupDumper implements DumperInterface
{
    public $backup = true;

    public function dump(MessageCatalogue $messages, $options = array())
    {
    }

    public function setBackup($backup)
    {
        $this->backup = $backup;
    }
}
PKϤ$Z0�2��"translation/Tests/IntervalTest.phpnu�[���<?php

/*
 * This file is part of the Symfony package.
 *
 * (c) Fabien Potencier <fabien@symfony.com>
 *
 * For the full copyright and license information, please view the LICENSE
 * file that was distributed with this source code.
 */

namespace Symfony\Component\Translation\Tests;

use Symfony\Component\Translation\Interval;

class IntervalTest extends \PHPUnit_Framework_TestCase
{
    /**
     * @dataProvider getTests
     */
    public function testTest($expected, $number, $interval)
    {
        $this->assertEquals($expected, Interval::test($number, $interval));
    }

    /**
     * @expectedException \InvalidArgumentException
     */
    public function testTestException()
    {
        Interval::test(1, 'foobar');
    }

    public function getTests()
    {
        return array(
            array(true, 3, '{1,2, 3 ,4}'),
            array(false, 10, '{1,2, 3 ,4}'),
            array(false, 3, '[1,2]'),
            array(true, 1, '[1,2]'),
            array(true, 2, '[1,2]'),
            array(false, 1, ']1,2['),
            array(false, 2, ']1,2['),
            array(true, log(0), '[-Inf,2['),
            array(true, -log(0), '[-2,+Inf]'),
        );
    }
}
PKϤ$Z,����^�^$translation/Tests/TranslatorTest.phpnu�[���<?php

/*
 * This file is part of the Symfony package.
 *
 * (c) Fabien Potencier <fabien@symfony.com>
 *
 * For the full copyright and license information, please view the LICENSE
 * file that was distributed with this source code.
 */

namespace Symfony\Component\Translation\Tests;

use Symfony\Component\Translation\Translator;
use Symfony\Component\Translation\MessageSelector;
use Symfony\Component\Translation\Loader\ArrayLoader;
use Symfony\Component\Translation\MessageCatalogue;

class TranslatorTest extends \PHPUnit_Framework_TestCase
{
    /**
     * @dataProvider      getInvalidLocalesTests
     * @expectedException \InvalidArgumentException
     */
    public function testConstructorInvalidLocale($locale)
    {
        $translator = new Translator($locale, new MessageSelector());
    }

    /**
     * @dataProvider getValidLocalesTests
     */
    public function testConstructorValidLocale($locale)
    {
        $translator = new Translator($locale, new MessageSelector());

        $this->assertEquals($locale, $translator->getLocale());
    }

    public function testConstructorWithoutLocale()
    {
        $translator = new Translator(null, new MessageSelector());

        $this->assertNull($translator->getLocale());
    }

    public function testSetGetLocale()
    {
        $translator = new Translator('en');

        $this->assertEquals('en', $translator->getLocale());

        $translator->setLocale('fr');
        $this->assertEquals('fr', $translator->getLocale());
    }

    /**
     * @dataProvider      getInvalidLocalesTests
     * @expectedException \InvalidArgumentException
     */
    public function testSetInvalidLocale($locale)
    {
        $translator = new Translator('fr', new MessageSelector());
        $translator->setLocale($locale);
    }

    /**
     * @dataProvider getValidLocalesTests
     */
    public function testSetValidLocale($locale)
    {
        $translator = new Translator($locale, new MessageSelector());
        $translator->setLocale($locale);

        $this->assertEquals($locale, $translator->getLocale());
    }

    public function testGetCatalogue()
    {
        $translator = new Translator('en');

        $this->assertEquals(new MessageCatalogue('en'), $translator->getCatalogue());

        $translator->setLocale('fr');
        $this->assertEquals(new MessageCatalogue('fr'), $translator->getCatalogue('fr'));
    }

    public function testGetCatalogueReturnsConsolidatedCatalogue()
    {
        /*
         * This will be useful once we refactor so that different domains will be loaded lazily (on-demand).
         * In that case, getCatalogue() will probably have to load all missing domains in order to return
         * one complete catalogue.
         */

        $locale = 'whatever';
        $translator = new Translator($locale);
        $translator->addLoader('loader-a', new ArrayLoader());
        $translator->addLoader('loader-b', new ArrayLoader());
        $translator->addResource('loader-a', array('foo' => 'foofoo'), $locale, 'domain-a');
        $translator->addResource('loader-b', array('bar' => 'foobar'), $locale, 'domain-b');

        /*
         * Test that we get a single catalogue comprising messages
         * from different loaders and different domains
         */
        $catalogue = $translator->getCatalogue($locale);
        $this->assertTrue($catalogue->defines('foo', 'domain-a'));
        $this->assertTrue($catalogue->defines('bar', 'domain-b'));
    }

    public function testSetFallbackLocales()
    {
        $translator = new Translator('en');
        $translator->addLoader('array', new ArrayLoader());
        $translator->addResource('array', array('foo' => 'foofoo'), 'en');
        $translator->addResource('array', array('bar' => 'foobar'), 'fr');

        // force catalogue loading
        $translator->trans('bar');

        $translator->setFallbackLocales(array('fr'));
        $this->assertEquals('foobar', $translator->trans('bar'));
    }

    public function testSetFallbackLocalesMultiple()
    {
        $translator = new Translator('en');
        $translator->addLoader('array', new ArrayLoader());
        $translator->addResource('array', array('foo' => 'foo (en)'), 'en');
        $translator->addResource('array', array('bar' => 'bar (fr)'), 'fr');

        // force catalogue loading
        $translator->trans('bar');

        $translator->setFallbackLocales(array('fr_FR', 'fr'));
        $this->assertEquals('bar (fr)', $translator->trans('bar'));
    }

    /**
     * @dataProvider      getInvalidLocalesTests
     * @expectedException \InvalidArgumentException
     */
    public function testSetFallbackInvalidLocales($locale)
    {
        $translator = new Translator('fr', new MessageSelector());
        $translator->setFallbackLocales(array('fr', $locale));
    }

    /**
     * @dataProvider getValidLocalesTests
     */
    public function testSetFallbackValidLocales($locale)
    {
        $translator = new Translator($locale, new MessageSelector());
        $translator->setFallbackLocales(array('fr', $locale));
        // no assertion. this method just asserts that no exception is thrown
    }

    public function testTransWithFallbackLocale()
    {
        $translator = new Translator('fr_FR');
        $translator->setFallbackLocales(array('en'));

        $translator->addLoader('array', new ArrayLoader());
        $translator->addResource('array', array('bar' => 'foobar'), 'en');

        $this->assertEquals('foobar', $translator->trans('bar'));
    }

    /**
     * @dataProvider      getInvalidLocalesTests
     * @expectedException \InvalidArgumentException
     */
    public function testAddResourceInvalidLocales($locale)
    {
        $translator = new Translator('fr', new MessageSelector());
        $translator->addResource('array', array('foo' => 'foofoo'), $locale);
    }

    /**
     * @dataProvider getValidLocalesTests
     */
    public function testAddResourceValidLocales($locale)
    {
        $translator = new Translator('fr', new MessageSelector());
        $translator->addResource('array', array('foo' => 'foofoo'), $locale);
        // no assertion. this method just asserts that no exception is thrown
    }

    public function testAddResourceAfterTrans()
    {
        $translator = new Translator('fr');
        $translator->addLoader('array', new ArrayLoader());

        $translator->setFallbackLocales(array('en'));

        $translator->addResource('array', array('foo' => 'foofoo'), 'en');
        $this->assertEquals('foofoo', $translator->trans('foo'));

        $translator->addResource('array', array('bar' => 'foobar'), 'en');
        $this->assertEquals('foobar', $translator->trans('bar'));
    }

    /**
     * @dataProvider      getTransFileTests
     * @expectedException \Symfony\Component\Translation\Exception\NotFoundResourceException
     */
    public function testTransWithoutFallbackLocaleFile($format, $loader)
    {
        $loaderClass = 'Symfony\\Component\\Translation\\Loader\\'.$loader;
        $translator = new Translator('en');
        $translator->addLoader($format, new $loaderClass());
        $translator->addResource($format, __DIR__.'/fixtures/non-existing', 'en');
        $translator->addResource($format, __DIR__.'/fixtures/resources.'.$format, 'en');

        // force catalogue loading
        $translator->trans('foo');
    }

    /**
     * @dataProvider getTransFileTests
     */
    public function testTransWithFallbackLocaleFile($format, $loader)
    {
        $loaderClass = 'Symfony\\Component\\Translation\\Loader\\'.$loader;
        $translator = new Translator('en_GB');
        $translator->addLoader($format, new $loaderClass());
        $translator->addResource($format, __DIR__.'/fixtures/non-existing', 'en_GB');
        $translator->addResource($format, __DIR__.'/fixtures/resources.'.$format, 'en', 'resources');

        $this->assertEquals('bar', $translator->trans('foo', array(), 'resources'));
    }

    public function testTransWithFallbackLocaleBis()
    {
        $translator = new Translator('en_US');
        $translator->addLoader('array', new ArrayLoader());
        $translator->addResource('array', array('foo' => 'foofoo'), 'en_US');
        $translator->addResource('array', array('bar' => 'foobar'), 'en');
        $this->assertEquals('foobar', $translator->trans('bar'));
    }

    public function testTransWithFallbackLocaleTer()
    {
        $translator = new Translator('fr_FR');
        $translator->addLoader('array', new ArrayLoader());
        $translator->addResource('array', array('foo' => 'foo (en_US)'), 'en_US');
        $translator->addResource('array', array('bar' => 'bar (en)'), 'en');

        $translator->setFallbackLocales(array('en_US', 'en'));

        $this->assertEquals('foo (en_US)', $translator->trans('foo'));
        $this->assertEquals('bar (en)', $translator->trans('bar'));
    }

    public function testTransNonExistentWithFallback()
    {
        $translator = new Translator('fr');
        $translator->setFallbackLocales(array('en'));
        $translator->addLoader('array', new ArrayLoader());
        $this->assertEquals('non-existent', $translator->trans('non-existent'));
    }

    /**
     * @expectedException \RuntimeException
     */
    public function testWhenAResourceHasNoRegisteredLoader()
    {
        $translator = new Translator('en');
        $translator->addResource('array', array('foo' => 'foofoo'), 'en');

        $translator->trans('foo');
    }

    public function testFallbackCatalogueResources()
    {
        $translator = new Translator('en_GB', new MessageSelector());
        $translator->addLoader('yml', new \Symfony\Component\Translation\Loader\YamlFileLoader());
        $translator->addResource('yml', __DIR__.'/fixtures/empty.yml', 'en_GB');
        $translator->addResource('yml', __DIR__.'/fixtures/resources.yml', 'en');

        // force catalogue loading
        $this->assertEquals('bar', $translator->trans('foo', array()));

        $resources = $translator->getCatalogue('en')->getResources();
        $this->assertCount(1, $resources);
        $this->assertContains( __DIR__.DIRECTORY_SEPARATOR.'fixtures'.DIRECTORY_SEPARATOR.'resources.yml', $resources);

        $resources = $translator->getCatalogue('en_GB')->getResources();
        $this->assertCount(2, $resources);
        $this->assertContains( __DIR__.DIRECTORY_SEPARATOR.'fixtures'.DIRECTORY_SEPARATOR.'empty.yml', $resources);
        $this->assertContains( __DIR__.DIRECTORY_SEPARATOR.'fixtures'.DIRECTORY_SEPARATOR.'resources.yml', $resources);
    }

    /**
     * @dataProvider getTransTests
     */
    public function testTrans($expected, $id, $translation, $parameters, $locale, $domain)
    {
        $translator = new Translator('en');
        $translator->addLoader('array', new ArrayLoader());
        $translator->addResource('array', array((string) $id => $translation), $locale, $domain);

        $this->assertEquals($expected, $translator->trans($id, $parameters, $domain, $locale));
    }

    /**
     * @dataProvider      getInvalidLocalesTests
     * @expectedException \InvalidArgumentException
     */
    public function testTransInvalidLocale($locale)
    {
        $translator = new Translator('en', new MessageSelector());
        $translator->addLoader('array', new ArrayLoader());
        $translator->addResource('array', array('foo' => 'foofoo'), 'en');

        $translator->trans('foo', array(), '', $locale);
    }

    /**
     * @dataProvider      getValidLocalesTests
     */
    public function testTransValidLocale($locale)
    {
        $translator = new Translator($locale, new MessageSelector());
        $translator->addLoader('array', new ArrayLoader());
        $translator->addResource('array', array('test' => 'OK'), $locale);

        $this->assertEquals('OK', $translator->trans('test'));
        $this->assertEquals('OK', $translator->trans('test', array(), null, $locale));
    }

    /**
     * @dataProvider getFlattenedTransTests
     */
    public function testFlattenedTrans($expected, $messages, $id)
    {
        $translator = new Translator('en');
        $translator->addLoader('array', new ArrayLoader());
        $translator->addResource('array', $messages, 'fr', '');

        $this->assertEquals($expected, $translator->trans($id, array(), '', 'fr'));
    }

    /**
     * @dataProvider getTransChoiceTests
     */
    public function testTransChoice($expected, $id, $translation, $number, $parameters, $locale, $domain)
    {
        $translator = new Translator('en');
        $translator->addLoader('array', new ArrayLoader());
        $translator->addResource('array', array((string) $id => $translation), $locale, $domain);

        $this->assertEquals($expected, $translator->transChoice($id, $number, $parameters, $domain, $locale));
    }

    /**
     * @dataProvider      getInvalidLocalesTests
     * @expectedException \InvalidArgumentException
     */
    public function testTransChoiceInvalidLocale($locale)
    {
        $translator = new Translator('en', new MessageSelector());
        $translator->addLoader('array', new ArrayLoader());
        $translator->addResource('array', array('foo' => 'foofoo'), 'en');

        $translator->transChoice('foo', 1, array(), '', $locale);
    }

    /**
     * @dataProvider      getValidLocalesTests
     */
    public function testTransChoiceValidLocale($locale)
    {
        $translator = new Translator('en', new MessageSelector());
        $translator->addLoader('array', new ArrayLoader());
        $translator->addResource('array', array('foo' => 'foofoo'), 'en');

        $translator->transChoice('foo', 1, array(), '', $locale);
        // no assertion. this method just asserts that no exception is thrown
    }

    public function getTransFileTests()
    {
        return array(
            array('csv', 'CsvFileLoader'),
            array('ini', 'IniFileLoader'),
            array('mo', 'MoFileLoader'),
            array('po', 'PoFileLoader'),
            array('php', 'PhpFileLoader'),
            array('ts', 'QtFileLoader'),
            array('xlf', 'XliffFileLoader'),
            array('yml', 'YamlFileLoader'),
            array('json', 'JsonFileLoader'),
        );
    }

    public function getTransTests()
    {
        return array(
            array('Symfony est super !', 'Symfony is great!', 'Symfony est super !', array(), 'fr', ''),
            array('Symfony est awesome !', 'Symfony is %what%!', 'Symfony est %what% !', array('%what%' => 'awesome'), 'fr', ''),
            array('Symfony est super !', new StringClass('Symfony is great!'), 'Symfony est super !', array(), 'fr', ''),
        );
    }

    public function getFlattenedTransTests()
    {
        $messages = array(
            'symfony' => array(
                'is' => array(
                    'great' => 'Symfony est super!',
                ),
            ),
            'foo' => array(
                'bar' => array(
                    'baz' => 'Foo Bar Baz',
                ),
                'baz' => 'Foo Baz',
            ),
        );

        return array(
            array('Symfony est super!', $messages, 'symfony.is.great'),
            array('Foo Bar Baz', $messages, 'foo.bar.baz'),
            array('Foo Baz', $messages, 'foo.baz'),
        );
    }

    public function getTransChoiceTests()
    {
        return array(
            array('Il y a 0 pomme', '{0} There are no appless|{1} There is one apple|]1,Inf] There is %count% apples', '[0,1] Il y a %count% pomme|]1,Inf] Il y a %count% pommes', 0, array('%count%' => 0), 'fr', ''),
            array('Il y a 1 pomme', '{0} There are no appless|{1} There is one apple|]1,Inf] There is %count% apples', '[0,1] Il y a %count% pomme|]1,Inf] Il y a %count% pommes', 1, array('%count%' => 1), 'fr', ''),
            array('Il y a 10 pommes', '{0} There are no appless|{1} There is one apple|]1,Inf] There is %count% apples', '[0,1] Il y a %count% pomme|]1,Inf] Il y a %count% pommes', 10, array('%count%' => 10), 'fr', ''),

            array('Il y a 0 pomme', 'There is one apple|There is %count% apples', 'Il y a %count% pomme|Il y a %count% pommes', 0, array('%count%' => 0), 'fr', ''),
            array('Il y a 1 pomme', 'There is one apple|There is %count% apples', 'Il y a %count% pomme|Il y a %count% pommes', 1, array('%count%' => 1), 'fr', ''),
            array('Il y a 10 pommes', 'There is one apple|There is %count% apples', 'Il y a %count% pomme|Il y a %count% pommes', 10, array('%count%' => 10), 'fr', ''),

            array('Il y a 0 pomme', 'one: There is one apple|more: There is %count% apples', 'one: Il y a %count% pomme|more: Il y a %count% pommes', 0, array('%count%' => 0), 'fr', ''),
            array('Il y a 1 pomme', 'one: There is one apple|more: There is %count% apples', 'one: Il y a %count% pomme|more: Il y a %count% pommes', 1, array('%count%' => 1), 'fr', ''),
            array('Il y a 10 pommes', 'one: There is one apple|more: There is %count% apples', 'one: Il y a %count% pomme|more: Il y a %count% pommes', 10, array('%count%' => 10), 'fr', ''),

            array('Il n\'y a aucune pomme', '{0} There are no apples|one: There is one apple|more: There is %count% apples', '{0} Il n\'y a aucune pomme|one: Il y a %count% pomme|more: Il y a %count% pommes', 0, array('%count%' => 0), 'fr', ''),
            array('Il y a 1 pomme', '{0} There are no apples|one: There is one apple|more: There is %count% apples', '{0} Il n\'y a aucune pomme|one: Il y a %count% pomme|more: Il y a %count% pommes', 1, array('%count%' => 1), 'fr', ''),
            array('Il y a 10 pommes', '{0} There are no apples|one: There is one apple|more: There is %count% apples', '{0} Il n\'y a aucune pomme|one: Il y a %count% pomme|more: Il y a %count% pommes', 10, array('%count%' => 10), 'fr', ''),

            array('Il y a 0 pomme', new StringClass('{0} There are no appless|{1} There is one apple|]1,Inf] There is %count% apples'), '[0,1] Il y a %count% pomme|]1,Inf] Il y a %count% pommes', 0, array('%count%' => 0), 'fr', ''),
        );
    }

    public function getInvalidLocalesTests()
    {
        return array(
            array('fr FR'),
            array('français'),
            array('fr+en'),
            array('utf#8'),
            array('fr&en'),
            array('fr~FR'),
            array(' fr'),
            array('fr '),
            array('fr*'),
            array('fr/FR'),
            array('fr\\FR'),
        );
    }

    public function getValidLocalesTests()
    {
        return array(
            array(''),
            array(null),
            array('fr'),
            array('francais'),
            array('FR'),
            array('frFR'),
            array('fr-FR'),
            array('fr_FR'),
            array('fr.FR'),
            array('fr-FR.UTF8'),
            array('sr@latin'),
        );
    }

    public function testTransChoiceFallback()
    {
        $translator = new Translator('ru');
        $translator->setFallbackLocales(array('en'));
        $translator->addLoader('array', new ArrayLoader());
        $translator->addResource('array', array('some_message2' => 'one thing|%count% things'), 'en');

        $this->assertEquals('10 things', $translator->transChoice('some_message2', 10, array('%count%' => 10)));
    }

    public function testTransChoiceFallbackBis()
    {
        $translator = new Translator('ru');
        $translator->setFallbackLocales(array('en_US', 'en'));
        $translator->addLoader('array', new ArrayLoader());
        $translator->addResource('array', array('some_message2' => 'one thing|%count% things'), 'en_US');

        $this->assertEquals('10 things', $translator->transChoice('some_message2', 10, array('%count%' => 10)));
    }

    public function testTransChoiceFallbackWithNoTranslation()
    {
        $translator = new Translator('ru');
        $translator->setFallbackLocales(array('en'));
        $translator->addLoader('array', new ArrayLoader());

        // consistent behavior with Translator::trans(), which returns the string
        // unchanged if it can't be found
        $this->assertEquals('some_message2', $translator->transChoice('some_message2', 10, array('%count%' => 10)));
    }

    /**
     * @group legacy
     * @dataProvider dataProviderGetMessages
     */
    public function testLegacyGetMessages($resources, $locale, $expected)
    {
        $locales = array_keys($resources);
        $_locale = null !== $locale ? $locale : reset($locales);
        $locales = array_slice($locales, 0, array_search($_locale, $locales));

        $translator = new Translator($_locale, new MessageSelector());
        $translator->setFallbackLocales(array_reverse($locales));
        $translator->addLoader('array', new ArrayLoader());
        foreach ($resources as $_locale => $domainMessages) {
            foreach ($domainMessages as $domain => $messages) {
                $translator->addResource('array', $messages, $_locale, $domain);
            }
        }
        $result = $translator->getMessages($locale);

        $this->assertEquals($expected, $result);
    }

    public function dataProviderGetMessages()
    {
        $resources = array(
            'en' => array(
                'jsmessages' => array(
                    'foo' => 'foo (EN)',
                    'bar' => 'bar (EN)',
                ),
                'messages' => array(
                    'foo' => 'foo messages (EN)',
                ),
                'validators' => array(
                    'int' => 'integer (EN)',
                ),
            ),
            'pt-PT' => array(
                'messages' => array(
                    'foo' => 'foo messages (PT)',
                ),
                'validators' => array(
                    'str' => 'integer (PT)',
                ),
            ),
            'pt_BR' => array(
                'validators' => array(
                    'int' => 'integer (BR)',
                ),
            ),
        );

        return array(
            array($resources, null,
                array(
                    'jsmessages' => array(
                        'foo' => 'foo (EN)',
                        'bar' => 'bar (EN)',
                    ),
                    'messages' => array(
                        'foo' => 'foo messages (EN)',
                    ),
                    'validators' => array(
                        'int' => 'integer (EN)',
                    ),
                ),
            ),
            array($resources, 'en',
                array(
                    'jsmessages' => array(
                        'foo' => 'foo (EN)',
                        'bar' => 'bar (EN)',
                    ),
                    'messages' => array(
                        'foo' => 'foo messages (EN)',
                    ),
                    'validators' => array(
                        'int' => 'integer (EN)',
                    ),
                ),
            ),
            array($resources, 'pt-PT',
                array(
                    'jsmessages' => array(
                        'foo' => 'foo (EN)',
                        'bar' => 'bar (EN)',
                    ),
                    'messages' => array(
                        'foo' => 'foo messages (PT)',
                    ),
                    'validators' => array(
                        'int' => 'integer (EN)',
                        'str' => 'integer (PT)',
                    ),
                ),
            ),
            array($resources, 'pt_BR',
                array(
                    'jsmessages' => array(
                        'foo' => 'foo (EN)',
                        'bar' => 'bar (EN)',
                    ),
                    'messages' => array(
                        'foo' => 'foo messages (PT)',
                    ),
                    'validators' => array(
                        'int' => 'integer (BR)',
                        'str' => 'integer (PT)',
                    ),
                ),
            ),
        );
    }
}

class StringClass
{
    protected $str;

    public function __construct($str)
    {
        $this->str = $str;
    }

    public function __toString()
    {
        return $this->str;
    }
}
PKϤ$Z&���]]"translation/PluralizationRules.phpnu�[���<?php

/*
 * This file is part of the Symfony package.
 *
 * (c) Fabien Potencier <fabien@symfony.com>
 *
 * For the full copyright and license information, please view the LICENSE
 * file that was distributed with this source code.
 */

namespace Symfony\Component\Translation;

/**
 * Returns the plural rules for a given locale.
 *
 * @author Fabien Potencier <fabien@symfony.com>
 */
class PluralizationRules
{
    private static $rules = array();

    /**
     * Returns the plural position to use for the given locale and number.
     *
     * @param int    $number The number
     * @param string $locale The locale
     *
     * @return int The plural position
     */
    public static function get($number, $locale)
    {
        if ('pt_BR' === $locale) {
            // temporary set a locale for brazilian
            $locale = 'xbr';
        }

        if (strlen($locale) > 3) {
            $locale = substr($locale, 0, -strlen(strrchr($locale, '_')));
        }

        if (isset(self::$rules[$locale])) {
            $return = call_user_func(self::$rules[$locale], $number);

            if (!is_int($return) || $return < 0) {
                return 0;
            }

            return $return;
        }

        /*
         * The plural rules are derived from code of the Zend Framework (2010-09-25),
         * which is subject to the new BSD license (http://framework.zend.com/license/new-bsd).
         * Copyright (c) 2005-2010 Zend Technologies USA Inc. (http://www.zend.com)
         */
        switch ($locale) {
            case 'az':
            case 'bo':
            case 'dz':
            case 'id':
            case 'ja':
            case 'jv':
            case 'ka':
            case 'km':
            case 'kn':
            case 'ko':
            case 'ms':
            case 'th':
            case 'tr':
            case 'vi':
            case 'zh':
                return 0;
                break;

            case 'af':
            case 'bn':
            case 'bg':
            case 'ca':
            case 'da':
            case 'de':
            case 'el':
            case 'en':
            case 'eo':
            case 'es':
            case 'et':
            case 'eu':
            case 'fa':
            case 'fi':
            case 'fo':
            case 'fur':
            case 'fy':
            case 'gl':
            case 'gu':
            case 'ha':
            case 'he':
            case 'hu':
            case 'is':
            case 'it':
            case 'ku':
            case 'lb':
            case 'ml':
            case 'mn':
            case 'mr':
            case 'nah':
            case 'nb':
            case 'ne':
            case 'nl':
            case 'nn':
            case 'no':
            case 'om':
            case 'or':
            case 'pa':
            case 'pap':
            case 'ps':
            case 'pt':
            case 'so':
            case 'sq':
            case 'sv':
            case 'sw':
            case 'ta':
            case 'te':
            case 'tk':
            case 'ur':
            case 'zu':
                return ($number == 1) ? 0 : 1;

            case 'am':
            case 'bh':
            case 'fil':
            case 'fr':
            case 'gun':
            case 'hi':
            case 'hy':
            case 'ln':
            case 'mg':
            case 'nso':
            case 'xbr':
            case 'ti':
            case 'wa':
                return (($number == 0) || ($number == 1)) ? 0 : 1;

            case 'be':
            case 'bs':
            case 'hr':
            case 'ru':
            case 'sr':
            case 'uk':
                return (($number % 10 == 1) && ($number % 100 != 11)) ? 0 : ((($number % 10 >= 2) && ($number % 10 <= 4) && (($number % 100 < 10) || ($number % 100 >= 20))) ? 1 : 2);

            case 'cs':
            case 'sk':
                return ($number == 1) ? 0 : ((($number >= 2) && ($number <= 4)) ? 1 : 2);

            case 'ga':
                return ($number == 1) ? 0 : (($number == 2) ? 1 : 2);

            case 'lt':
                return (($number % 10 == 1) && ($number % 100 != 11)) ? 0 : ((($number % 10 >= 2) && (($number % 100 < 10) || ($number % 100 >= 20))) ? 1 : 2);

            case 'sl':
                return ($number % 100 == 1) ? 0 : (($number % 100 == 2) ? 1 : ((($number % 100 == 3) || ($number % 100 == 4)) ? 2 : 3));

            case 'mk':
                return ($number % 10 == 1) ? 0 : 1;

            case 'mt':
                return ($number == 1) ? 0 : ((($number == 0) || (($number % 100 > 1) && ($number % 100 < 11))) ? 1 : ((($number % 100 > 10) && ($number % 100 < 20)) ? 2 : 3));

            case 'lv':
                return ($number == 0) ? 0 : ((($number % 10 == 1) && ($number % 100 != 11)) ? 1 : 2);

            case 'pl':
                return ($number == 1) ? 0 : ((($number % 10 >= 2) && ($number % 10 <= 4) && (($number % 100 < 12) || ($number % 100 > 14))) ? 1 : 2);

            case 'cy':
                return ($number == 1) ? 0 : (($number == 2) ? 1 : ((($number == 8) || ($number == 11)) ? 2 : 3));

            case 'ro':
                return ($number == 1) ? 0 : ((($number == 0) || (($number % 100 > 0) && ($number % 100 < 20))) ? 1 : 2);

            case 'ar':
                return ($number == 0) ? 0 : (($number == 1) ? 1 : (($number == 2) ? 2 : ((($number % 100 >= 3) && ($number % 100 <= 10)) ? 3 : ((($number % 100 >= 11) && ($number % 100 <= 99)) ? 4 : 5))));

            default:
                return 0;
        }
    }

    /**
     * Overrides the default plural rule for a given locale.
     *
     * @param callable $rule   A PHP callable
     * @param string   $locale The locale
     *
     * @throws \LogicException
     */
    public static function set($rule, $locale)
    {
        if ('pt_BR' === $locale) {
            // temporary set a locale for brazilian
            $locale = 'xbr';
        }

        if (strlen($locale) > 3) {
            $locale = substr($locale, 0, -strlen(strrchr($locale, '_')));
        }

        if (!is_callable($rule)) {
            throw new \LogicException('The given rule can not be called');
        }

        self::$rules[$locale] = $rule;
    }
}
PKϤ$Z�B��))&translation/TranslatorBagInterface.phpnu�[���<?php

/*
 * This file is part of the Symfony package.
 *
 * (c) Fabien Potencier <fabien@symfony.com>
 *
 * For the full copyright and license information, please view the LICENSE
 * file that was distributed with this source code.
 */

namespace Symfony\Component\Translation;

use Symfony\Component\Translation\Exception\InvalidArgumentException;

/**
 * TranslatorBagInterface.
 *
 * @author Abdellatif Ait boudad <a.aitboudad@gmail.com>
 */
interface TranslatorBagInterface
{
    /**
     * Gets the catalogue by locale.
     *
     * @param string|null $locale The locale or null to use the default
     *
     * @return MessageCatalogueInterface
     *
     * @throws InvalidArgumentException If the locale contains invalid characters
     */
    public function getCatalogue(string $locale = null);
}
PKϤ$Z[Q3��"translation/IdentityTranslator.phpnu�[���<?php

/*
 * This file is part of the Symfony package.
 *
 * (c) Fabien Potencier <fabien@symfony.com>
 *
 * For the full copyright and license information, please view the LICENSE
 * file that was distributed with this source code.
 */

namespace Symfony\Component\Translation;

use Symfony\Contracts\Translation\LocaleAwareInterface;
use Symfony\Contracts\Translation\TranslatorInterface;
use Symfony\Contracts\Translation\TranslatorTrait;

/**
 * IdentityTranslator does not translate anything.
 *
 * @author Fabien Potencier <fabien@symfony.com>
 */
class IdentityTranslator implements TranslatorInterface, LocaleAwareInterface
{
    use TranslatorTrait;
}
PKϤ$Z�Ř�a5a5translation/Translator.phpnu�[���<?php

/*
 * This file is part of the Symfony package.
 *
 * (c) Fabien Potencier <fabien@symfony.com>
 *
 * For the full copyright and license information, please view the LICENSE
 * file that was distributed with this source code.
 */

namespace Symfony\Component\Translation;

use Symfony\Component\Config\ConfigCacheFactory;
use Symfony\Component\Config\ConfigCacheFactoryInterface;
use Symfony\Component\Config\ConfigCacheInterface;
use Symfony\Component\Translation\Exception\InvalidArgumentException;
use Symfony\Component\Translation\Exception\NotFoundResourceException;
use Symfony\Component\Translation\Exception\RuntimeException;
use Symfony\Component\Translation\Formatter\IntlFormatterInterface;
use Symfony\Component\Translation\Formatter\MessageFormatter;
use Symfony\Component\Translation\Formatter\MessageFormatterInterface;
use Symfony\Component\Translation\Loader\LoaderInterface;
use Symfony\Contracts\Translation\LocaleAwareInterface;
use Symfony\Contracts\Translation\TranslatorInterface;

/**
 * @author Fabien Potencier <fabien@symfony.com>
 */
class Translator implements TranslatorInterface, TranslatorBagInterface, LocaleAwareInterface
{
    /**
     * @var MessageCatalogueInterface[]
     */
    protected $catalogues = [];

    /**
     * @var string
     */
    private $locale;

    /**
     * @var array
     */
    private $fallbackLocales = [];

    /**
     * @var LoaderInterface[]
     */
    private $loaders = [];

    /**
     * @var array
     */
    private $resources = [];

    /**
     * @var MessageFormatterInterface
     */
    private $formatter;

    /**
     * @var string
     */
    private $cacheDir;

    /**
     * @var bool
     */
    private $debug;

    private $cacheVary;

    /**
     * @var ConfigCacheFactoryInterface|null
     */
    private $configCacheFactory;

    /**
     * @var array|null
     */
    private $parentLocales;

    private $hasIntlFormatter;

    /**
     * @throws InvalidArgumentException If a locale contains invalid characters
     */
    public function __construct(string $locale, MessageFormatterInterface $formatter = null, string $cacheDir = null, bool $debug = false, array $cacheVary = [])
    {
        $this->setLocale($locale);

        if (null === $formatter) {
            $formatter = new MessageFormatter();
        }

        $this->formatter = $formatter;
        $this->cacheDir = $cacheDir;
        $this->debug = $debug;
        $this->cacheVary = $cacheVary;
        $this->hasIntlFormatter = $formatter instanceof IntlFormatterInterface;
    }

    public function setConfigCacheFactory(ConfigCacheFactoryInterface $configCacheFactory)
    {
        $this->configCacheFactory = $configCacheFactory;
    }

    /**
     * Adds a Loader.
     *
     * @param string $format The name of the loader (@see addResource())
     */
    public function addLoader(string $format, LoaderInterface $loader)
    {
        $this->loaders[$format] = $loader;
    }

    /**
     * Adds a Resource.
     *
     * @param string $format   The name of the loader (@see addLoader())
     * @param mixed  $resource The resource name
     *
     * @throws InvalidArgumentException If the locale contains invalid characters
     */
    public function addResource(string $format, $resource, string $locale, string $domain = null)
    {
        if (null === $domain) {
            $domain = 'messages';
        }

        $this->assertValidLocale($locale);

        $this->resources[$locale][] = [$format, $resource, $domain];

        if (\in_array($locale, $this->fallbackLocales)) {
            $this->catalogues = [];
        } else {
            unset($this->catalogues[$locale]);
        }
    }

    /**
     * {@inheritdoc}
     */
    public function setLocale(string $locale)
    {
        $this->assertValidLocale($locale);
        $this->locale = $locale;
    }

    /**
     * {@inheritdoc}
     */
    public function getLocale()
    {
        return $this->locale;
    }

    /**
     * Sets the fallback locales.
     *
     * @param array $locales The fallback locales
     *
     * @throws InvalidArgumentException If a locale contains invalid characters
     */
    public function setFallbackLocales(array $locales)
    {
        // needed as the fallback locales are linked to the already loaded catalogues
        $this->catalogues = [];

        foreach ($locales as $locale) {
            $this->assertValidLocale($locale);
        }

        $this->fallbackLocales = $this->cacheVary['fallback_locales'] = $locales;
    }

    /**
     * Gets the fallback locales.
     *
     * @internal
     */
    public function getFallbackLocales(): array
    {
        return $this->fallbackLocales;
    }

    /**
     * {@inheritdoc}
     */
    public function trans(?string $id, array $parameters = [], string $domain = null, string $locale = null)
    {
        if (null === $id || '' === $id) {
            return '';
        }

        if (null === $domain) {
            $domain = 'messages';
        }

        $catalogue = $this->getCatalogue($locale);
        $locale = $catalogue->getLocale();
        while (!$catalogue->defines($id, $domain)) {
            if ($cat = $catalogue->getFallbackCatalogue()) {
                $catalogue = $cat;
                $locale = $catalogue->getLocale();
            } else {
                break;
            }
        }

        if ($this->hasIntlFormatter && $catalogue->defines($id, $domain.MessageCatalogue::INTL_DOMAIN_SUFFIX)) {
            return $this->formatter->formatIntl($catalogue->get($id, $domain), $locale, $parameters);
        }

        return $this->formatter->format($catalogue->get($id, $domain), $locale, $parameters);
    }

    /**
     * {@inheritdoc}
     */
    public function getCatalogue(string $locale = null)
    {
        if (null === $locale) {
            $locale = $this->getLocale();
        } else {
            $this->assertValidLocale($locale);
        }

        if (!isset($this->catalogues[$locale])) {
            $this->loadCatalogue($locale);
        }

        return $this->catalogues[$locale];
    }

    /**
     * Gets the loaders.
     *
     * @return array LoaderInterface[]
     */
    protected function getLoaders()
    {
        return $this->loaders;
    }

    protected function loadCatalogue(string $locale)
    {
        if (null === $this->cacheDir) {
            $this->initializeCatalogue($locale);
        } else {
            $this->initializeCacheCatalogue($locale);
        }
    }

    protected function initializeCatalogue(string $locale)
    {
        $this->assertValidLocale($locale);

        try {
            $this->doLoadCatalogue($locale);
        } catch (NotFoundResourceException $e) {
            if (!$this->computeFallbackLocales($locale)) {
                throw $e;
            }
        }
        $this->loadFallbackCatalogues($locale);
    }

    private function initializeCacheCatalogue(string $locale): void
    {
        if (isset($this->catalogues[$locale])) {
            /* Catalogue already initialized. */
            return;
        }

        $this->assertValidLocale($locale);
        $cache = $this->getConfigCacheFactory()->cache($this->getCatalogueCachePath($locale),
            function (ConfigCacheInterface $cache) use ($locale) {
                $this->dumpCatalogue($locale, $cache);
            }
        );

        if (isset($this->catalogues[$locale])) {
            /* Catalogue has been initialized as it was written out to cache. */
            return;
        }

        /* Read catalogue from cache. */
        $this->catalogues[$locale] = include $cache->getPath();
    }

    private function dumpCatalogue(string $locale, ConfigCacheInterface $cache): void
    {
        $this->initializeCatalogue($locale);
        $fallbackContent = $this->getFallbackContent($this->catalogues[$locale]);

        $content = sprintf(<<<EOF
<?php

use Symfony\Component\Translation\MessageCatalogue;

\$catalogue = new MessageCatalogue('%s', %s);

%s
return \$catalogue;

EOF
            ,
            $locale,
            var_export($this->getAllMessages($this->catalogues[$locale]), true),
            $fallbackContent
        );

        $cache->write($content, $this->catalogues[$locale]->getResources());
    }

    private function getFallbackContent(MessageCatalogue $catalogue): string
    {
        $fallbackContent = '';
        $current = '';
        $replacementPattern = '/[^a-z0-9_]/i';
        $fallbackCatalogue = $catalogue->getFallbackCatalogue();
        while ($fallbackCatalogue) {
            $fallback = $fallbackCatalogue->getLocale();
            $fallbackSuffix = ucfirst(preg_replace($replacementPattern, '_', $fallback));
            $currentSuffix = ucfirst(preg_replace($replacementPattern, '_', $current));

            $fallbackContent .= sprintf(<<<'EOF'
$catalogue%s = new MessageCatalogue('%s', %s);
$catalogue%s->addFallbackCatalogue($catalogue%s);

EOF
                ,
                $fallbackSuffix,
                $fallback,
                var_export($this->getAllMessages($fallbackCatalogue), true),
                $currentSuffix,
                $fallbackSuffix
            );
            $current = $fallbackCatalogue->getLocale();
            $fallbackCatalogue = $fallbackCatalogue->getFallbackCatalogue();
        }

        return $fallbackContent;
    }

    private function getCatalogueCachePath(string $locale): string
    {
        return $this->cacheDir.'/catalogue.'.$locale.'.'.strtr(substr(base64_encode(hash('sha256', serialize($this->cacheVary), true)), 0, 7), '/', '_').'.php';
    }

    /**
     * @internal
     */
    protected function doLoadCatalogue(string $locale): void
    {
        $this->catalogues[$locale] = new MessageCatalogue($locale);

        if (isset($this->resources[$locale])) {
            foreach ($this->resources[$locale] as $resource) {
                if (!isset($this->loaders[$resource[0]])) {
                    throw new RuntimeException(sprintf('The "%s" translation loader is not registered.', $resource[0]));
                }
                $this->catalogues[$locale]->addCatalogue($this->loaders[$resource[0]]->load($resource[1], $locale, $resource[2]));
            }
        }
    }

    private function loadFallbackCatalogues(string $locale): void
    {
        $current = $this->catalogues[$locale];

        foreach ($this->computeFallbackLocales($locale) as $fallback) {
            if (!isset($this->catalogues[$fallback])) {
                $this->initializeCatalogue($fallback);
            }

            $fallbackCatalogue = new MessageCatalogue($fallback, $this->getAllMessages($this->catalogues[$fallback]));
            foreach ($this->catalogues[$fallback]->getResources() as $resource) {
                $fallbackCatalogue->addResource($resource);
            }
            $current->addFallbackCatalogue($fallbackCatalogue);
            $current = $fallbackCatalogue;
        }
    }

    protected function computeFallbackLocales(string $locale)
    {
        if (null === $this->parentLocales) {
            $parentLocales = json_decode(file_get_contents(__DIR__.'/Resources/data/parents.json'), true);
        }

        $locales = [];
        foreach ($this->fallbackLocales as $fallback) {
            if ($fallback === $locale) {
                continue;
            }

            $locales[] = $fallback;
        }

        while ($locale) {
            $parent = $parentLocales[$locale] ?? null;

            if ($parent) {
                $locale = 'root' !== $parent ? $parent : null;
            } elseif (\function_exists('locale_parse')) {
                $localeSubTags = locale_parse($locale);
                $locale = null;
                if (1 < \count($localeSubTags)) {
                    array_pop($localeSubTags);
                    $locale = locale_compose($localeSubTags) ?: null;
                }
            } elseif ($i = strrpos($locale, '_') ?: strrpos($locale, '-')) {
                $locale = substr($locale, 0, $i);
            } else {
                $locale = null;
            }

            if (null !== $locale) {
                array_unshift($locales, $locale);
            }
        }

        return array_unique($locales);
    }

    /**
     * Asserts that the locale is valid, throws an Exception if not.
     *
     * @throws InvalidArgumentException If the locale contains invalid characters
     */
    protected function assertValidLocale(string $locale)
    {
        if (1 !== preg_match('/^[a-z0-9@_\\.\\-]*$/i', $locale)) {
            throw new InvalidArgumentException(sprintf('Invalid "%s" locale.', $locale));
        }
    }

    /**
     * Provides the ConfigCache factory implementation, falling back to a
     * default implementation if necessary.
     */
    private function getConfigCacheFactory(): ConfigCacheFactoryInterface
    {
        if (!$this->configCacheFactory) {
            $this->configCacheFactory = new ConfigCacheFactory($this->debug);
        }

        return $this->configCacheFactory;
    }

    private function getAllMessages(MessageCatalogueInterface $catalogue): array
    {
        $allMessages = [];

        foreach ($catalogue->all() as $domain => $messages) {
            if ($intlMessages = $catalogue->all($domain.MessageCatalogue::INTL_DOMAIN_SUFFIX)) {
                $allMessages[$domain.MessageCatalogue::INTL_DOMAIN_SUFFIX] = $intlMessages;
                $messages = array_diff_key($messages, $intlMessages);
            }
            if ($messages) {
                $allMessages[$domain] = $messages;
            }
        }

        return $allMessages;
    }
}
PKϤ$ZpuA���)translation/MessageCatalogueInterface.phpnu�[���<?php

/*
 * This file is part of the Symfony package.
 *
 * (c) Fabien Potencier <fabien@symfony.com>
 *
 * For the full copyright and license information, please view the LICENSE
 * file that was distributed with this source code.
 */

namespace Symfony\Component\Translation;

use Symfony\Component\Config\Resource\ResourceInterface;

/**
 * MessageCatalogueInterface.
 *
 * @author Fabien Potencier <fabien@symfony.com>
 */
interface MessageCatalogueInterface
{
    const INTL_DOMAIN_SUFFIX = '+intl-icu';

    /**
     * Gets the catalogue locale.
     *
     * @return string The locale
     */
    public function getLocale();

    /**
     * Gets the domains.
     *
     * @return array An array of domains
     */
    public function getDomains();

    /**
     * Gets the messages within a given domain.
     *
     * If $domain is null, it returns all messages.
     *
     * @param string $domain The domain name
     *
     * @return array An array of messages
     */
    public function all(string $domain = null);

    /**
     * Sets a message translation.
     *
     * @param string $id          The message id
     * @param string $translation The messages translation
     * @param string $domain      The domain name
     */
    public function set(string $id, string $translation, string $domain = 'messages');

    /**
     * Checks if a message has a translation.
     *
     * @param string $id     The message id
     * @param string $domain The domain name
     *
     * @return bool true if the message has a translation, false otherwise
     */
    public function has(string $id, string $domain = 'messages');

    /**
     * Checks if a message has a translation (it does not take into account the fallback mechanism).
     *
     * @param string $id     The message id
     * @param string $domain The domain name
     *
     * @return bool true if the message has a translation, false otherwise
     */
    public function defines(string $id, string $domain = 'messages');

    /**
     * Gets a message translation.
     *
     * @param string $id     The message id
     * @param string $domain The domain name
     *
     * @return string The message translation
     */
    public function get(string $id, string $domain = 'messages');

    /**
     * Sets translations for a given domain.
     *
     * @param array  $messages An array of translations
     * @param string $domain   The domain name
     */
    public function replace(array $messages, string $domain = 'messages');

    /**
     * Adds translations for a given domain.
     *
     * @param array  $messages An array of translations
     * @param string $domain   The domain name
     */
    public function add(array $messages, string $domain = 'messages');

    /**
     * Merges translations from the given Catalogue into the current one.
     *
     * The two catalogues must have the same locale.
     */
    public function addCatalogue(self $catalogue);

    /**
     * Merges translations from the given Catalogue into the current one
     * only when the translation does not exist.
     *
     * This is used to provide default translations when they do not exist for the current locale.
     */
    public function addFallbackCatalogue(self $catalogue);

    /**
     * Gets the fallback catalogue.
     *
     * @return self|null A MessageCatalogueInterface instance or null when no fallback has been set
     */
    public function getFallbackCatalogue();

    /**
     * Returns an array of resources loaded to build this collection.
     *
     * @return ResourceInterface[] An array of resources
     */
    public function getResources();

    /**
     * Adds a resource for this collection.
     */
    public function addResource(ResourceInterface $resource);
}
PKϤ$Z?�9���%translation/Loader/JsonFileLoader.phpnu�[���<?php

/*
 * This file is part of the Symfony package.
 *
 * (c) Fabien Potencier <fabien@symfony.com>
 *
 * For the full copyright and license information, please view the LICENSE
 * file that was distributed with this source code.
 */

namespace Symfony\Component\Translation\Loader;

use Symfony\Component\Translation\Exception\InvalidResourceException;

/**
 * JsonFileLoader loads translations from an json file.
 *
 * @author singles
 */
class JsonFileLoader extends FileLoader
{
    /**
     * {@inheritdoc}
     */
    protected function loadResource($resource)
    {
        $messages = [];
        if ($data = file_get_contents($resource)) {
            $messages = json_decode($data, true);

            if (0 < $errorCode = json_last_error()) {
                throw new InvalidResourceException('Error parsing JSON: '.$this->getJSONErrorMessage($errorCode));
            }
        }

        return $messages;
    }

    /**
     * Translates JSON_ERROR_* constant into meaningful message.
     */
    private function getJSONErrorMessage(int $errorCode): string
    {
        switch ($errorCode) {
            case JSON_ERROR_DEPTH:
                return 'Maximum stack depth exceeded';
            case JSON_ERROR_STATE_MISMATCH:
                return 'Underflow or the modes mismatch';
            case JSON_ERROR_CTRL_CHAR:
                return 'Unexpected control character found';
            case JSON_ERROR_SYNTAX:
                return 'Syntax error, malformed JSON';
            case JSON_ERROR_UTF8:
                return 'Malformed UTF-8 characters, possibly incorrectly encoded';
            default:
                return 'Unknown error';
        }
    }
}
PKϤ$Z�q���#translation/Loader/MoFileLoader.phpnu�[���<?php

/*
 * This file is part of the Symfony package.
 *
 * (c) Fabien Potencier <fabien@symfony.com>
 *
 * For the full copyright and license information, please view the LICENSE
 * file that was distributed with this source code.
 */

namespace Symfony\Component\Translation\Loader;

use Symfony\Component\Translation\Exception\InvalidResourceException;

/**
 * @copyright Copyright (c) 2010, Union of RAD http://union-of-rad.org (http://lithify.me/)
 */
class MoFileLoader extends FileLoader
{
    /**
     * Magic used for validating the format of a MO file as well as
     * detecting if the machine used to create that file was little endian.
     */
    const MO_LITTLE_ENDIAN_MAGIC = 0x950412de;

    /**
     * Magic used for validating the format of a MO file as well as
     * detecting if the machine used to create that file was big endian.
     */
    const MO_BIG_ENDIAN_MAGIC = 0xde120495;

    /**
     * The size of the header of a MO file in bytes.
     */
    const MO_HEADER_SIZE = 28;

    /**
     * Parses machine object (MO) format, independent of the machine's endian it
     * was created on. Both 32bit and 64bit systems are supported.
     *
     * {@inheritdoc}
     */
    protected function loadResource($resource)
    {
        $stream = fopen($resource, 'r');

        $stat = fstat($stream);

        if ($stat['size'] < self::MO_HEADER_SIZE) {
            throw new InvalidResourceException('MO stream content has an invalid format.');
        }
        $magic = unpack('V1', fread($stream, 4));
        $magic = hexdec(substr(dechex(current($magic)), -8));

        if (self::MO_LITTLE_ENDIAN_MAGIC == $magic) {
            $isBigEndian = false;
        } elseif (self::MO_BIG_ENDIAN_MAGIC == $magic) {
            $isBigEndian = true;
        } else {
            throw new InvalidResourceException('MO stream content has an invalid format.');
        }

        // formatRevision
        $this->readLong($stream, $isBigEndian);
        $count = $this->readLong($stream, $isBigEndian);
        $offsetId = $this->readLong($stream, $isBigEndian);
        $offsetTranslated = $this->readLong($stream, $isBigEndian);
        // sizeHashes
        $this->readLong($stream, $isBigEndian);
        // offsetHashes
        $this->readLong($stream, $isBigEndian);

        $messages = [];

        for ($i = 0; $i < $count; ++$i) {
            $pluralId = null;
            $translated = null;

            fseek($stream, $offsetId + $i * 8);

            $length = $this->readLong($stream, $isBigEndian);
            $offset = $this->readLong($stream, $isBigEndian);

            if ($length < 1) {
                continue;
            }

            fseek($stream, $offset);
            $singularId = fread($stream, $length);

            if (false !== strpos($singularId, "\000")) {
                list($singularId, $pluralId) = explode("\000", $singularId);
            }

            fseek($stream, $offsetTranslated + $i * 8);
            $length = $this->readLong($stream, $isBigEndian);
            $offset = $this->readLong($stream, $isBigEndian);

            if ($length < 1) {
                continue;
            }

            fseek($stream, $offset);
            $translated = fread($stream, $length);

            if (false !== strpos($translated, "\000")) {
                $translated = explode("\000", $translated);
            }

            $ids = ['singular' => $singularId, 'plural' => $pluralId];
            $item = compact('ids', 'translated');

            if (!empty($item['ids']['singular'])) {
                $id = $item['ids']['singular'];
                if (isset($item['ids']['plural'])) {
                    $id .= '|'.$item['ids']['plural'];
                }
                $messages[$id] = stripcslashes(implode('|', (array) $item['translated']));
            }
        }

        fclose($stream);

        return array_filter($messages);
    }

    /**
     * Reads an unsigned long from stream respecting endianness.
     *
     * @param resource $stream
     */
    private function readLong($stream, bool $isBigEndian): int
    {
        $result = unpack($isBigEndian ? 'N1' : 'V1', fread($stream, 4));
        $result = current($result);

        return (int) substr($result, -8);
    }
}
PKϤ$Z����dd&translation/Loader/LoaderInterface.phpnu�[���<?php

/*
 * This file is part of the Symfony package.
 *
 * (c) Fabien Potencier <fabien@symfony.com>
 *
 * For the full copyright and license information, please view the LICENSE
 * file that was distributed with this source code.
 */

namespace Symfony\Component\Translation\Loader;

use Symfony\Component\Translation\Exception\InvalidResourceException;
use Symfony\Component\Translation\Exception\NotFoundResourceException;
use Symfony\Component\Translation\MessageCatalogue;

/**
 * LoaderInterface is the interface implemented by all translation loaders.
 *
 * @author Fabien Potencier <fabien@symfony.com>
 */
interface LoaderInterface
{
    /**
     * Loads a locale.
     *
     * @param mixed  $resource A resource
     * @param string $locale   A locale
     * @param string $domain   The domain
     *
     * @return MessageCatalogue A MessageCatalogue instance
     *
     * @throws NotFoundResourceException when the resource cannot be found
     * @throws InvalidResourceException  when the resource cannot be loaded
     */
    public function load($resource, string $locale, string $domain = 'messages');
}
PKϤ$Z"@�"�"0translation/Loader/schema/dic/xliff-core/xml.xsdnu�[���<?xml version='1.0'?>
<?xml-stylesheet href="../2008/09/xsd.xsl" type="text/xsl"?>
<xs:schema targetNamespace="http://www.w3.org/XML/1998/namespace" 
  xmlns:xs="http://www.w3.org/2001/XMLSchema" 
  xmlns ="http://www.w3.org/1999/xhtml"
  xml:lang="en">

 <xs:annotation>
  <xs:documentation>
   <div>
    <h1>About the XML namespace</h1>

    <div class="bodytext">
     <p>

      This schema document describes the XML namespace, in a form
      suitable for import by other schema documents.
     </p>
     <p>
      See <a href="http://www.w3.org/XML/1998/namespace.html">
      http://www.w3.org/XML/1998/namespace.html</a> and
      <a href="http://www.w3.org/TR/REC-xml">
      http://www.w3.org/TR/REC-xml</a> for information 
      about this namespace.
     </p>

     <p>
      Note that local names in this namespace are intended to be
      defined only by the World Wide Web Consortium or its subgroups.
      The names currently defined in this namespace are listed below.
      They should not be used with conflicting semantics by any Working
      Group, specification, or document instance.
     </p>
     <p>   
      See further below in this document for more information about <a
      href="#usage">how to refer to this schema document from your own
      XSD schema documents</a> and about <a href="#nsversioning">the
      namespace-versioning policy governing this schema document</a>.
     </p>
    </div>
   </div>

  </xs:documentation>
 </xs:annotation>

 <xs:attribute name="lang">
  <xs:annotation>
   <xs:documentation>
    <div>
     
      <h3>lang (as an attribute name)</h3>
      <p>

       denotes an attribute whose value
       is a language code for the natural language of the content of
       any element; its value is inherited.  This name is reserved
       by virtue of its definition in the XML specification.</p>
     
    </div>
    <div>
     <h4>Notes</h4>
     <p>
      Attempting to install the relevant ISO 2- and 3-letter
      codes as the enumerated possible values is probably never
      going to be a realistic possibility.  
     </p>
     <p>

      See BCP 47 at <a href="http://www.rfc-editor.org/rfc/bcp/bcp47.txt">
       http://www.rfc-editor.org/rfc/bcp/bcp47.txt</a>
      and the IANA language subtag registry at
      <a href="http://www.iana.org/assignments/language-subtag-registry">
       http://www.iana.org/assignments/language-subtag-registry</a>
      for further information.
     </p>
     <p>

      The union allows for the 'un-declaration' of xml:lang with
      the empty string.
     </p>
    </div>
   </xs:documentation>
  </xs:annotation>
  <xs:simpleType>
   <xs:union memberTypes="xs:language">
    <xs:simpleType>    
     <xs:restriction base="xs:string">
      <xs:enumeration value=""/>

     </xs:restriction>
    </xs:simpleType>
   </xs:union>
  </xs:simpleType>
 </xs:attribute>

 <xs:attribute name="space">
  <xs:annotation>
   <xs:documentation>

    <div>
     
      <h3>space (as an attribute name)</h3>
      <p>
       denotes an attribute whose
       value is a keyword indicating what whitespace processing
       discipline is intended for the content of the element; its
       value is inherited.  This name is reserved by virtue of its
       definition in the XML specification.</p>
     
    </div>
   </xs:documentation>
  </xs:annotation>
  <xs:simpleType>

   <xs:restriction base="xs:NCName">
    <xs:enumeration value="default"/>
    <xs:enumeration value="preserve"/>
   </xs:restriction>
  </xs:simpleType>
 </xs:attribute>
 
 <xs:attribute name="base" type="xs:anyURI"> <xs:annotation>
   <xs:documentation>

    <div>
     
      <h3>base (as an attribute name)</h3>
      <p>
       denotes an attribute whose value
       provides a URI to be used as the base for interpreting any
       relative URIs in the scope of the element on which it
       appears; its value is inherited.  This name is reserved
       by virtue of its definition in the XML Base specification.</p>
     
     <p>
      See <a
      href="http://www.w3.org/TR/xmlbase/">http://www.w3.org/TR/xmlbase/</a>
      for information about this attribute.
     </p>

    </div>
   </xs:documentation>
  </xs:annotation>
 </xs:attribute>
 
 <xs:attribute name="id" type="xs:ID">
  <xs:annotation>
   <xs:documentation>
    <div>
     
      <h3>id (as an attribute name)</h3> 
      <p>

       denotes an attribute whose value
       should be interpreted as if declared to be of type ID.
       This name is reserved by virtue of its definition in the
       xml:id specification.</p>
     
     <p>
      See <a
      href="http://www.w3.org/TR/xml-id/">http://www.w3.org/TR/xml-id/</a>
      for information about this attribute.
     </p>
    </div>
   </xs:documentation>
  </xs:annotation>

 </xs:attribute>

 <xs:attributeGroup name="specialAttrs">
  <xs:attribute ref="xml:base"/>
  <xs:attribute ref="xml:lang"/>
  <xs:attribute ref="xml:space"/>
  <xs:attribute ref="xml:id"/>
 </xs:attributeGroup>

 <xs:annotation>

  <xs:documentation>
   <div>
   
    <h3>Father (in any context at all)</h3> 

    <div class="bodytext">
     <p>
      denotes Jon Bosak, the chair of 
      the original XML Working Group.  This name is reserved by 
      the following decision of the W3C XML Plenary and 
      XML Coordination groups:
     </p>
     <blockquote>
       <p>

	In appreciation for his vision, leadership and
	dedication the W3C XML Plenary on this 10th day of
	February, 2000, reserves for Jon Bosak in perpetuity
	the XML name "xml:Father".
       </p>
     </blockquote>
    </div>
   </div>
  </xs:documentation>
 </xs:annotation>

 <xs:annotation>
  <xs:documentation>

   <div xml:id="usage" id="usage">
    <h2><a name="usage">About this schema document</a></h2>

    <div class="bodytext">
     <p>
      This schema defines attributes and an attribute group suitable
      for use by schemas wishing to allow <code>xml:base</code>,
      <code>xml:lang</code>, <code>xml:space</code> or
      <code>xml:id</code> attributes on elements they define.
     </p>

     <p>
      To enable this, such a schema must import this schema for
      the XML namespace, e.g. as follows:
     </p>
     <pre>
          &lt;schema.. .>
          .. .
           &lt;import namespace="http://www.w3.org/XML/1998/namespace"
                      schemaLocation="http://www.w3.org/2001/xml.xsd"/>
     </pre>
     <p>
      or
     </p>
     <pre>

           &lt;import namespace="http://www.w3.org/XML/1998/namespace"
                      schemaLocation="http://www.w3.org/2009/01/xml.xsd"/>
     </pre>
     <p>
      Subsequently, qualified reference to any of the attributes or the
      group defined below will have the desired effect, e.g.
     </p>
     <pre>
          &lt;type.. .>
          .. .
           &lt;attributeGroup ref="xml:specialAttrs"/>
     </pre>
     <p>
      will define a type which will schema-validate an instance element
      with any of those attributes.
     </p>

    </div>
   </div>
  </xs:documentation>
 </xs:annotation>

 <xs:annotation>
  <xs:documentation>
   <div id="nsversioning" xml:id="nsversioning">
    <h2><a name="nsversioning">Versioning policy for this schema document</a></h2>

    <div class="bodytext">
     <p>
      In keeping with the XML Schema WG's standard versioning
      policy, this schema document will persist at
      <a href="http://www.w3.org/2009/01/xml.xsd">
       http://www.w3.org/2009/01/xml.xsd</a>.
     </p>
     <p>
      At the date of issue it can also be found at
      <a href="http://www.w3.org/2001/xml.xsd">
       http://www.w3.org/2001/xml.xsd</a>.
     </p>

     <p>
      The schema document at that URI may however change in the future,
      in order to remain compatible with the latest version of XML
      Schema itself, or with the XML namespace itself.  In other words,
      if the XML Schema or XML namespaces change, the version of this
      document at <a href="http://www.w3.org/2001/xml.xsd">
       http://www.w3.org/2001/xml.xsd 
      </a> 
      will change accordingly; the version at 
      <a href="http://www.w3.org/2009/01/xml.xsd">
       http://www.w3.org/2009/01/xml.xsd 
      </a> 
      will not change.
     </p>
     <p>

      Previous dated (and unchanging) versions of this schema 
      document are at:
     </p>
     <ul>
      <li><a href="http://www.w3.org/2009/01/xml.xsd">
	http://www.w3.org/2009/01/xml.xsd</a></li>
      <li><a href="http://www.w3.org/2007/08/xml.xsd">
	http://www.w3.org/2007/08/xml.xsd</a></li>
      <li><a href="http://www.w3.org/2004/10/xml.xsd">

	http://www.w3.org/2004/10/xml.xsd</a></li>
      <li><a href="http://www.w3.org/2001/03/xml.xsd">
	http://www.w3.org/2001/03/xml.xsd</a></li>
     </ul>
    </div>
   </div>
  </xs:documentation>
 </xs:annotation>

</xs:schema>
PKϤ$ZD���lAlA;translation/Loader/schema/dic/xliff-core/xliff-core-2.0.xsdnu�[���<?xml version="1.0" encoding="UTF-8"?>
<!--

    XLIFF Version 2.0
    OASIS Standard
    05 August 2014
    Copyright (c) OASIS Open 2014. All rights reserved.
    Source: http://docs.oasis-open.org/xliff/xliff-core/v2.0/os/schemas/
     -->
<xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema"
    elementFormDefault="qualified"
    xmlns:xlf="urn:oasis:names:tc:xliff:document:2.0"
    targetNamespace="urn:oasis:names:tc:xliff:document:2.0">

  <!-- Import -->

  <xs:import namespace="http://www.w3.org/XML/1998/namespace"
      schemaLocation="informativeCopiesOf3rdPartySchemas/w3c/xml.xsd"/>

  <!-- Element Group -->

  <xs:group name="inline">
    <xs:choice>
      <xs:element ref="xlf:cp"/>
      <xs:element ref="xlf:ph"/>
      <xs:element ref="xlf:pc"/>
      <xs:element ref="xlf:sc"/>
      <xs:element ref="xlf:ec"/>
      <xs:element ref="xlf:mrk"/>
      <xs:element ref="xlf:sm"/>
      <xs:element ref="xlf:em"/>
    </xs:choice>
  </xs:group>

  <!-- Attribute Types -->

  <xs:simpleType name="yesNo">
    <xs:restriction base="xs:string">
      <xs:enumeration value="yes"/>
      <xs:enumeration value="no"/>
    </xs:restriction>
  </xs:simpleType>

  <xs:simpleType name="yesNoFirstNo">
    <xs:restriction base="xs:string">
      <xs:enumeration value="yes"/>
      <xs:enumeration value="firstNo"/>
      <xs:enumeration value="no"/>
    </xs:restriction>
  </xs:simpleType>

  <xs:simpleType name="dirValue">
    <xs:restriction base="xs:string">
      <xs:enumeration value="ltr"/>
      <xs:enumeration value="rtl"/>
      <xs:enumeration value="auto"/>
    </xs:restriction>
  </xs:simpleType>

  <xs:simpleType name="appliesTo">
    <xs:restriction base="xs:string">
      <xs:enumeration value="source"/>
      <xs:enumeration value="target"/>
    </xs:restriction>
  </xs:simpleType>

  <xs:simpleType name="userDefinedValue">
    <xs:restriction base="xs:string">
      <xs:pattern value="[^\s:]+:[^\s:]+"/>
    </xs:restriction>
  </xs:simpleType>

  <xs:simpleType name="attrType_type">
    <xs:restriction base="xs:string">
      <xs:enumeration value="fmt"/>
      <xs:enumeration value="ui"/>
      <xs:enumeration value="quote"/>
      <xs:enumeration value="link"/>
      <xs:enumeration value="image"/>
      <xs:enumeration value="other"/>
    </xs:restriction>
  </xs:simpleType>

  <xs:simpleType name="typeForMrkValues">
    <xs:restriction base="xs:NMTOKEN">
      <xs:enumeration value="generic"/>
      <xs:enumeration value="comment"/>
      <xs:enumeration value="term"/>
    </xs:restriction>
  </xs:simpleType>

  <xs:simpleType name="attrType_typeForMrk">
    <xs:union memberTypes="xlf:typeForMrkValues xlf:userDefinedValue"/>
  </xs:simpleType>

  <xs:simpleType name="priorityValue">
    <xs:restriction base="xs:positiveInteger">
      <xs:minInclusive value="1"/>
      <xs:maxInclusive value="10"/>
    </xs:restriction>
  </xs:simpleType>

  <xs:simpleType name="stateType">
    <xs:restriction base="xs:string">
      <xs:enumeration value="initial"/>
      <xs:enumeration value="translated"/>
      <xs:enumeration value="reviewed"/>
      <xs:enumeration value="final"/>
    </xs:restriction>
  </xs:simpleType>

  <!-- Structural Elements -->

  <xs:element name="xliff">
    <xs:complexType mixed="false">
      <xs:sequence>
        <xs:element minOccurs="1" maxOccurs="unbounded" ref="xlf:file"/>
      </xs:sequence>
      <xs:attribute name="version" use="required"/>
      <xs:attribute name="srcLang" use="required"/>
      <xs:attribute name="trgLang" use="optional"/>
      <xs:attribute ref="xml:space" use="optional" default="default"/>
      <xs:anyAttribute namespace="##other" processContents="lax"/>
    </xs:complexType>
  </xs:element>

  <xs:element name="file">
    <xs:complexType mixed="false">
      <xs:sequence>
        <xs:element minOccurs="0" maxOccurs="1" ref="xlf:skeleton"/>
        <xs:any minOccurs="0" maxOccurs="unbounded" namespace="##other"
            processContents="lax"/>
        <xs:element minOccurs="0" maxOccurs="1" ref="xlf:notes"/>
        <xs:choice minOccurs="1" maxOccurs="unbounded">
          <xs:element ref="xlf:unit"/>
          <xs:element ref="xlf:group"/>
        </xs:choice>
      </xs:sequence>
      <xs:attribute name="id" use="required" type="xs:NMTOKEN"/>
      <xs:attribute name="canResegment" use="optional" type="xlf:yesNo" default="yes"/>
      <xs:attribute name="original" use="optional"/>
      <xs:attribute name="translate" use="optional" type="xlf:yesNo" default="yes"/>
      <xs:attribute name="srcDir" use="optional" type="xlf:dirValue" default="auto"/>
      <xs:attribute name="trgDir" use="optional" type="xlf:dirValue" default="auto"/>
      <xs:attribute ref="xml:space" use="optional"/>
      <xs:anyAttribute namespace="##other" processContents="lax"/>
    </xs:complexType>
  </xs:element>

  <xs:element name="skeleton">
    <xs:complexType mixed="true">
      <xs:sequence>
        <xs:any minOccurs="0" maxOccurs="unbounded" namespace="##other"
            processContents="lax"/>
      </xs:sequence>
      <xs:attribute name="href" use="optional"/>
    </xs:complexType>
  </xs:element>

  <xs:element name="group">
    <xs:complexType mixed="false">
      <xs:sequence>
        <xs:any minOccurs="0" maxOccurs="unbounded" namespace="##other"
            processContents="lax"/>
        <xs:element minOccurs="0" maxOccurs="1" ref="xlf:notes"/>
        <xs:choice minOccurs="0" maxOccurs="unbounded">
          <xs:element ref="xlf:unit"/>
          <xs:element ref="xlf:group"/>
        </xs:choice>
      </xs:sequence>
      <xs:attribute name="id" use="required" type="xs:NMTOKEN"/>
      <xs:attribute name="name" use="optional"/>
      <xs:attribute name="canResegment" use="optional" type="xlf:yesNo"/>
      <xs:attribute name="translate" use="optional" type="xlf:yesNo"/>
      <xs:attribute name="srcDir" use="optional" type="xlf:dirValue"/>
      <xs:attribute name="trgDir" use="optional" type="xlf:dirValue"/>
      <xs:attribute name="type" use="optional" type="xlf:userDefinedValue"/>
      <xs:attribute ref="xml:space" use="optional"/>
      <xs:anyAttribute namespace="##other" processContents="lax"/>
    </xs:complexType>
  </xs:element>

  <xs:element name="unit">
    <xs:complexType mixed="false">
      <xs:sequence>
        <xs:any minOccurs="0" maxOccurs="unbounded" namespace="##other"
            processContents="lax"/>
        <xs:element minOccurs="0" maxOccurs="1" ref="xlf:notes"/>
        <xs:element minOccurs="0" maxOccurs="1" ref="xlf:originalData"/>
        <xs:choice minOccurs="1" maxOccurs="unbounded">
          <xs:element ref="xlf:segment"/>
          <xs:element ref="xlf:ignorable"/>
        </xs:choice>
      </xs:sequence>
      <xs:attribute name="id" use="required" type="xs:NMTOKEN"/>
      <xs:attribute name="name" use="optional"/>
      <xs:attribute name="canResegment" use="optional" type="xlf:yesNo"/>
      <xs:attribute name="translate" use="optional" type="xlf:yesNo"/>
      <xs:attribute name="srcDir" use="optional" type="xlf:dirValue"/>
      <xs:attribute name="trgDir" use="optional" type="xlf:dirValue"/>
      <xs:attribute ref="xml:space" use="optional"/>
      <xs:attribute name="type" use="optional" type="xlf:userDefinedValue"/>
      <xs:anyAttribute namespace="##other" processContents="lax"/>
    </xs:complexType>
  </xs:element>

  <xs:element name="segment">
    <xs:complexType mixed="false">
      <xs:sequence>
        <xs:element minOccurs="1" maxOccurs="1" ref="xlf:source"/>
        <xs:element minOccurs="0" maxOccurs="1" ref="xlf:target"/>
      </xs:sequence>
      <xs:attribute name="id" use="optional" type="xs:NMTOKEN"/>
      <xs:attribute name="canResegment" use="optional" type="xlf:yesNo"/>
      <xs:attribute name="state" use="optional" type="xlf:stateType" default="initial"/>
      <xs:attribute name="subState" use="optional"/>
    </xs:complexType>
  </xs:element>

  <xs:element name="ignorable">
    <xs:complexType mixed="false">
      <xs:sequence>
        <xs:element minOccurs="1" maxOccurs="1" ref="xlf:source"/>
        <xs:element minOccurs="0" maxOccurs="1" ref="xlf:target"/>
      </xs:sequence>
      <xs:attribute name="id" use="optional" type="xs:NMTOKEN"/>
    </xs:complexType>
  </xs:element>

  <xs:element name="notes">
    <xs:complexType mixed="false">
      <xs:sequence>
        <xs:element minOccurs="1" maxOccurs="unbounded" ref="xlf:note"/>
      </xs:sequence>
    </xs:complexType>
  </xs:element>

  <xs:element name="note">
    <xs:complexType mixed="true">
      <xs:attribute name="id" use="optional" type="xs:NMTOKEN"/>
      <xs:attribute name="appliesTo" use="optional" type="xlf:appliesTo"/>
      <xs:attribute name="category" use="optional"/>
      <xs:attribute name="priority" use="optional" type="xlf:priorityValue" default="1"/>
      <xs:anyAttribute namespace="##other" processContents="lax"/>
    </xs:complexType>
  </xs:element>

  <xs:element name="originalData">
    <xs:complexType mixed="false">
      <xs:sequence>
        <xs:element minOccurs="1" maxOccurs="unbounded" ref="xlf:data"/>
      </xs:sequence>
    </xs:complexType>
  </xs:element>

  <xs:element name="data">
    <xs:complexType mixed="true">
      <xs:sequence>
        <xs:element minOccurs="0" maxOccurs="unbounded" ref="xlf:cp"/>
      </xs:sequence>
      <xs:attribute name="id" use="required" type="xs:NMTOKEN"/>
      <xs:attribute name="dir" use="optional" type="xlf:dirValue" default="auto"/>
      <xs:attribute ref="xml:space" use="optional" fixed="preserve"/>
    </xs:complexType>
  </xs:element>

  <xs:element name="source">
    <xs:complexType mixed="true">
      <xs:group ref="xlf:inline" minOccurs="0" maxOccurs="unbounded"/>
      <xs:attribute ref="xml:lang" use="optional"/>
      <xs:attribute ref="xml:space" use="optional"/>
    </xs:complexType>
  </xs:element>

  <xs:element name="target">
    <xs:complexType mixed="true">
      <xs:group ref="xlf:inline" minOccurs="0" maxOccurs="unbounded"/>
      <xs:attribute ref="xml:lang" use="optional"/>
      <xs:attribute ref="xml:space" use="optional"/>
      <xs:attribute name="order" use="optional" type="xs:positiveInteger"/>
    </xs:complexType>
  </xs:element>

  <!-- Inline Elements -->

  <xs:element name="cp">
    <!-- Code Point -->
    <xs:complexType mixed="false">
      <xs:attribute name="hex" use="required" type="xs:hexBinary"/>
    </xs:complexType>
  </xs:element>

  <xs:element name="ph">
    <!-- Placeholder -->
    <xs:complexType mixed="false">
      <xs:attribute name="canCopy" use="optional" type="xlf:yesNo" default="yes"/>
      <xs:attribute name="canDelete" use="optional" type="xlf:yesNo" default="yes"/>
      <xs:attribute name="canReorder" use="optional" type="xlf:yesNoFirstNo" default="yes"/>
      <xs:attribute name="copyOf" use="optional" type="xs:NMTOKEN"/>
      <xs:attribute name="disp" use="optional"/>
      <xs:attribute name="equiv" use="optional"/>
      <xs:attribute name="id" use="required" type="xs:NMTOKEN"/>
      <xs:attribute name="dataRef" use="optional" type="xs:NMTOKEN"/>
      <xs:attribute name="subFlows" use="optional" type="xs:NMTOKENS"/>
      <xs:attribute name="subType" use="optional" type="xlf:userDefinedValue"/>
      <xs:attribute name="type" use="optional" type="xlf:attrType_type"/>
      <xs:anyAttribute namespace="##other" processContents="lax"/>
    </xs:complexType>
  </xs:element>

  <xs:element name="pc">
    <!-- Paired Code -->
    <xs:complexType mixed="true">
      <xs:group ref="xlf:inline" minOccurs="0" maxOccurs="unbounded"/>
      <xs:attribute name="canCopy" use="optional" type="xlf:yesNo" default="yes"/>
      <xs:attribute name="canDelete" use="optional" type="xlf:yesNo" default="yes"/>
      <xs:attribute name="canOverlap" use="optional" type="xlf:yesNo"/>
      <xs:attribute name="canReorder" use="optional" type="xlf:yesNoFirstNo" default="yes"/>
      <xs:attribute name="copyOf" use="optional" type="xs:NMTOKEN"/>
      <xs:attribute name="dispEnd" use="optional"/>
      <xs:attribute name="dispStart" use="optional"/>
      <xs:attribute name="equivEnd" use="optional"/>
      <xs:attribute name="equivStart" use="optional"/>
      <xs:attribute name="id" use="required" type="xs:NMTOKEN"/>
      <xs:attribute name="dataRefEnd" use="optional" type="xs:NMTOKEN"/>
      <xs:attribute name="dataRefStart" use="optional" type="xs:NMTOKEN"/>
      <xs:attribute name="subFlowsEnd" use="optional" type="xs:NMTOKENS"/>
      <xs:attribute name="subFlowsStart" use="optional" type="xs:NMTOKENS"/>
      <xs:attribute name="subType" use="optional" type="xlf:userDefinedValue"/>
      <xs:attribute name="type" use="optional" type="xlf:attrType_type"/>
      <xs:attribute name="dir" use="optional" type="xlf:dirValue"/>
      <xs:anyAttribute namespace="##other" processContents="lax"/>
    </xs:complexType>
  </xs:element>

  <xs:element name="sc">
    <!-- Start Code -->
    <xs:complexType mixed="false">
      <xs:attribute name="canCopy" use="optional" type="xlf:yesNo" default="yes"/>
      <xs:attribute name="canDelete" use="optional" type="xlf:yesNo" default="yes"/>
      <xs:attribute name="canOverlap" use="optional" type="xlf:yesNo" default="yes"/>
      <xs:attribute name="canReorder" use="optional" type="xlf:yesNoFirstNo" default="yes"/>
      <xs:attribute name="copyOf" use="optional" type="xs:NMTOKEN"/>
      <xs:attribute name="dataRef" use="optional" type="xs:NMTOKEN"/>
      <xs:attribute name="dir" use="optional" type="xlf:dirValue"/>
      <xs:attribute name="disp" use="optional"/>
      <xs:attribute name="equiv" use="optional"/>
      <xs:attribute name="id" use="required" type="xs:NMTOKEN"/>
      <xs:attribute name="isolated" use="optional" type="xlf:yesNo" default="no"/>
      <xs:attribute name="subFlows" use="optional" type="xs:NMTOKENS"/>
      <xs:attribute name="subType" use="optional" type="xlf:userDefinedValue"/>
      <xs:attribute name="type" use="optional" type="xlf:attrType_type"/>
      <xs:anyAttribute namespace="##other" processContents="lax"/>
    </xs:complexType>
  </xs:element>

  <xs:element name="ec">
    <!-- End Code -->
    <xs:complexType mixed="false">
      <xs:attribute name="canCopy" use="optional" type="xlf:yesNo" default="yes"/>
      <xs:attribute name="canDelete" use="optional" type="xlf:yesNo" default="yes"/>
      <xs:attribute name="canOverlap" use="optional" type="xlf:yesNo" default="yes"/>
      <xs:attribute name="canReorder" use="optional" type="xlf:yesNoFirstNo" default="yes"/>
      <xs:attribute name="copyOf" use="optional" type="xs:NMTOKEN"/>
      <xs:attribute name="dataRef" use="optional" type="xs:NMTOKEN"/>
      <xs:attribute name="dir" use="optional" type="xlf:dirValue"/>
      <xs:attribute name="disp" use="optional"/>
      <xs:attribute name="equiv" use="optional"/>
      <xs:attribute name="id" use="optional" type="xs:NMTOKEN"/>
      <xs:attribute name="isolated" use="optional" type="xlf:yesNo" default="no"/>
      <xs:attribute name="startRef" use="optional" type="xs:NMTOKEN"/>
      <xs:attribute name="subFlows" use="optional" type="xs:NMTOKENS"/>
      <xs:attribute name="subType" use="optional" type="xlf:userDefinedValue"/>
      <xs:attribute name="type" use="optional" type="xlf:attrType_type"/>
      <xs:anyAttribute namespace="##other" processContents="lax"/>
    </xs:complexType>
  </xs:element>

  <xs:element name="mrk">
    <!-- Annotation Marker -->
    <xs:complexType mixed="true">
      <xs:group ref="xlf:inline" minOccurs="0" maxOccurs="unbounded"/>
      <xs:attribute name="id" use="required" type="xs:NMTOKEN"/>
      <xs:attribute name="translate" use="optional" type="xlf:yesNo"/>
      <xs:attribute name="type" use="optional" type="xlf:attrType_typeForMrk"/>
      <xs:attribute name="ref" use="optional" type="xs:anyURI"/>
      <xs:attribute name="value" use="optional"/>
      <xs:anyAttribute namespace="##other" processContents="lax"/>
    </xs:complexType>
  </xs:element>

  <xs:element name="sm">
    <!-- Start Annotation Marker -->
    <xs:complexType mixed="false">
      <xs:attribute name="id" use="required" type="xs:NMTOKEN"/>
      <xs:attribute name="translate" use="optional" type="xlf:yesNo"/>
      <xs:attribute name="type" use="optional" type="xlf:attrType_typeForMrk"/>
      <xs:attribute name="ref" use="optional" type="xs:anyURI"/>
      <xs:attribute name="value" use="optional"/>
      <xs:anyAttribute namespace="##other" processContents="lax"/>
    </xs:complexType>
  </xs:element>

  <xs:element name="em">
    <!-- End Annotation Marker -->
    <xs:complexType mixed="false">
      <xs:attribute name="startRef" use="required" type="xs:NMTOKEN"/>
    </xs:complexType>
  </xs:element>

</xs:schema>
PKϤ$Z�xO��Btranslation/Loader/schema/dic/xliff-core/xliff-core-1.2-strict.xsdnu�[���<?xml version="1.0" encoding="UTF-8"?>

<!--

May-19-2004:
- Changed the <choice> for ElemType_header, moving minOccurs="0" maxOccurs="unbounded" from its elements 
to <choice> itself.
- Added <choice> for ElemType_trans-unit to allow "any order" for <context-group>, <count-group>, <prop-group>, <note>, and
<alt-trans>.

Oct-2005
- updated version info to 1.2
- equiv-trans attribute to <trans-unit> element 
- merged-trans attribute for <group> element
- Add the <seg-source> element as optional in the <trans-unit> and <alt-trans> content models, at the same level as <source> 
- Create a new value "seg" for the mtype attribute of the <mrk> element
- Add mid as an optional attribute for the <alt-trans> element

Nov-14-2005
- Changed name attribute for <context-group> from required to optional
- Added extension point at <xliff>

Jan-9-2006
- Added alttranstype type attribute to <alt-trans>, and values

Jan-10-2006
- Corrected error with overwritten purposeValueList
- Corrected name="AttrType_Version",  attribute should have been "name"

-->
<xsd:schema xmlns:xlf="urn:oasis:names:tc:xliff:document:1.2" xmlns:xsd="http://www.w3.org/2001/XMLSchema" elementFormDefault="qualified" targetNamespace="urn:oasis:names:tc:xliff:document:1.2" xml:lang="en">
  <!-- Import for xml:lang and xml:space -->
  <xsd:import namespace="http://www.w3.org/XML/1998/namespace" schemaLocation="http://www.w3.org/2001/xml.xsd"/>
  <!-- Attributes Lists -->
  <xsd:simpleType name="XTend">
    <xsd:restriction base="xsd:string">
      <xsd:pattern value="x-[^\s]+"/>
    </xsd:restriction>
  </xsd:simpleType>
  <xsd:simpleType name="context-typeValueList">
    <xsd:annotation>
      <xsd:documentation>Values for the attribute 'context-type'.</xsd:documentation>
    </xsd:annotation>
    <xsd:restriction base="xsd:string">
      <xsd:enumeration value="database">
        <xsd:annotation>
          <xsd:documentation>Indicates a database content.</xsd:documentation>
        </xsd:annotation>
      </xsd:enumeration>
      <xsd:enumeration value="element">
        <xsd:annotation>
          <xsd:documentation>Indicates the content of an element within an XML document.</xsd:documentation>
        </xsd:annotation>
      </xsd:enumeration>
      <xsd:enumeration value="elementtitle">
        <xsd:annotation>
          <xsd:documentation>Indicates the name of an element within an XML document.</xsd:documentation>
        </xsd:annotation>
      </xsd:enumeration>
      <xsd:enumeration value="linenumber">
        <xsd:annotation>
          <xsd:documentation>Indicates the line number from the sourcefile (see context-type="sourcefile") where the &lt;source&gt; is found.</xsd:documentation>
        </xsd:annotation>
      </xsd:enumeration>
      <xsd:enumeration value="numparams">
        <xsd:annotation>
          <xsd:documentation>Indicates a the number of parameters contained within the &lt;source&gt;.</xsd:documentation>
        </xsd:annotation>
      </xsd:enumeration>
      <xsd:enumeration value="paramnotes">
        <xsd:annotation>
          <xsd:documentation>Indicates notes pertaining to the parameters in the &lt;source&gt;.</xsd:documentation>
        </xsd:annotation>
      </xsd:enumeration>
      <xsd:enumeration value="record">
        <xsd:annotation>
          <xsd:documentation>Indicates the content of a record within a database.</xsd:documentation>
        </xsd:annotation>
      </xsd:enumeration>
      <xsd:enumeration value="recordtitle">
        <xsd:annotation>
          <xsd:documentation>Indicates the name of a record within a database.</xsd:documentation>
        </xsd:annotation>
      </xsd:enumeration>
      <xsd:enumeration value="sourcefile">
        <xsd:annotation>
          <xsd:documentation>Indicates the original source file in the case that multiple files are merged to form the original file from which the XLIFF file is created. This differs from the original &lt;file&gt; attribute in that this sourcefile is one of many that make up that file.</xsd:documentation>
        </xsd:annotation>
      </xsd:enumeration>
    </xsd:restriction>
  </xsd:simpleType>
  <xsd:simpleType name="count-typeValueList">
    <xsd:annotation>
      <xsd:documentation>Values for the attribute 'count-type'.</xsd:documentation>
    </xsd:annotation>
    <xsd:restriction base="xsd:NMTOKEN">
      <xsd:enumeration value="num-usages">
        <xsd:annotation>
          <xsd:documentation>Indicates the count units are items that are used X times in a certain context; example: this is a reusable text unit which is used 42 times in other texts.</xsd:documentation>
        </xsd:annotation>
      </xsd:enumeration>
      <xsd:enumeration value="repetition">
        <xsd:annotation>
          <xsd:documentation>Indicates the count units are translation units existing already in the same document.</xsd:documentation>
        </xsd:annotation>
      </xsd:enumeration>
      <xsd:enumeration value="total">
        <xsd:annotation>
          <xsd:documentation>Indicates a total count.</xsd:documentation>
        </xsd:annotation>
      </xsd:enumeration>
    </xsd:restriction>
  </xsd:simpleType>
  <xsd:simpleType name="InlineDelimitersValueList">
    <xsd:annotation>
      <xsd:documentation>Values for the attribute 'ctype' when used other elements than &lt;ph&gt; or &lt;x&gt;.</xsd:documentation>
    </xsd:annotation>
    <xsd:restriction base="xsd:NMTOKEN">
      <xsd:enumeration value="bold">
        <xsd:annotation>
          <xsd:documentation>Indicates a run of bolded text.</xsd:documentation>
        </xsd:annotation>
      </xsd:enumeration>
      <xsd:enumeration value="italic">
        <xsd:annotation>
          <xsd:documentation>Indicates a run of text in italics.</xsd:documentation>
        </xsd:annotation>
      </xsd:enumeration>
      <xsd:enumeration value="underlined">
        <xsd:annotation>
          <xsd:documentation>Indicates a run of underlined text.</xsd:documentation>
        </xsd:annotation>
      </xsd:enumeration>
      <xsd:enumeration value="link">
        <xsd:annotation>
          <xsd:documentation>Indicates a run of hyper-text.</xsd:documentation>
        </xsd:annotation>
      </xsd:enumeration>
    </xsd:restriction>
  </xsd:simpleType>
  <xsd:simpleType name="InlinePlaceholdersValueList">
    <xsd:annotation>
      <xsd:documentation>Values for the attribute 'ctype' when used with &lt;ph&gt; or &lt;x&gt;.</xsd:documentation>
    </xsd:annotation>
    <xsd:restriction base="xsd:NMTOKEN">
      <xsd:enumeration value="image">
        <xsd:annotation>
          <xsd:documentation>Indicates a inline image.</xsd:documentation>
        </xsd:annotation>
      </xsd:enumeration>
      <xsd:enumeration value="pb">
        <xsd:annotation>
          <xsd:documentation>Indicates a page break.</xsd:documentation>
        </xsd:annotation>
      </xsd:enumeration>
      <xsd:enumeration value="lb">
        <xsd:annotation>
          <xsd:documentation>Indicates a line break.</xsd:documentation>
        </xsd:annotation>
      </xsd:enumeration>
    </xsd:restriction>
  </xsd:simpleType>
  <xsd:simpleType name="mime-typeValueList">
    <xsd:restriction base="xsd:string">
      <xsd:pattern value="(text|multipart|message|application|image|audio|video|model)(/.+)*"/>
    </xsd:restriction>
  </xsd:simpleType>
  <xsd:simpleType name="datatypeValueList">
    <xsd:annotation>
      <xsd:documentation>Values for the attribute 'datatype'.</xsd:documentation>
    </xsd:annotation>
    <xsd:restriction base="xsd:NMTOKEN">
      <xsd:enumeration value="asp">
        <xsd:annotation>
          <xsd:documentation>Indicates Active Server Page data.</xsd:documentation>
        </xsd:annotation>
      </xsd:enumeration>
      <xsd:enumeration value="c">
        <xsd:annotation>
          <xsd:documentation>Indicates C source file data.</xsd:documentation>
        </xsd:annotation>
      </xsd:enumeration>
      <xsd:enumeration value="cdf">
        <xsd:annotation>
          <xsd:documentation>Indicates Channel Definition Format (CDF) data.</xsd:documentation>
        </xsd:annotation>
      </xsd:enumeration>
      <xsd:enumeration value="cfm">
        <xsd:annotation>
          <xsd:documentation>Indicates ColdFusion data.</xsd:documentation>
        </xsd:annotation>
      </xsd:enumeration>
      <xsd:enumeration value="cpp">
        <xsd:annotation>
          <xsd:documentation>Indicates C++ source file data.</xsd:documentation>
        </xsd:annotation>
      </xsd:enumeration>
      <xsd:enumeration value="csharp">
        <xsd:annotation>
          <xsd:documentation>Indicates C-Sharp data.</xsd:documentation>
        </xsd:annotation>
      </xsd:enumeration>
      <xsd:enumeration value="cstring">
        <xsd:annotation>
          <xsd:documentation>Indicates strings from C, ASM, and driver files data.</xsd:documentation>
        </xsd:annotation>
      </xsd:enumeration>
      <xsd:enumeration value="csv">
        <xsd:annotation>
          <xsd:documentation>Indicates comma-separated values data.</xsd:documentation>
        </xsd:annotation>
      </xsd:enumeration>
      <xsd:enumeration value="database">
        <xsd:annotation>
          <xsd:documentation>Indicates database data.</xsd:documentation>
        </xsd:annotation>
      </xsd:enumeration>
      <xsd:enumeration value="documentfooter">
        <xsd:annotation>
          <xsd:documentation>Indicates portions of document that follows data and contains metadata.</xsd:documentation>
        </xsd:annotation>
      </xsd:enumeration>
      <xsd:enumeration value="documentheader">
        <xsd:annotation>
          <xsd:documentation>Indicates portions of document that precedes data and contains metadata.</xsd:documentation>
        </xsd:annotation>
      </xsd:enumeration>
      <xsd:enumeration value="filedialog">
        <xsd:annotation>
          <xsd:documentation>Indicates data from standard UI file operations dialogs (e.g., Open, Save, Save As, Export, Import).</xsd:documentation>
        </xsd:annotation>
      </xsd:enumeration>
      <xsd:enumeration value="form">
        <xsd:annotation>
          <xsd:documentation>Indicates standard user input screen data.</xsd:documentation>
        </xsd:annotation>
      </xsd:enumeration>
      <xsd:enumeration value="html">
        <xsd:annotation>
          <xsd:documentation>Indicates HyperText Markup Language (HTML) data - document instance.</xsd:documentation>
        </xsd:annotation>
      </xsd:enumeration>
      <xsd:enumeration value="htmlbody">
        <xsd:annotation>
          <xsd:documentation>Indicates content within an HTML document’s &lt;body&gt; element.</xsd:documentation>
        </xsd:annotation>
      </xsd:enumeration>
      <xsd:enumeration value="ini">
        <xsd:annotation>
          <xsd:documentation>Indicates Windows INI file data.</xsd:documentation>
        </xsd:annotation>
      </xsd:enumeration>
      <xsd:enumeration value="interleaf">
        <xsd:annotation>
          <xsd:documentation>Indicates Interleaf data.</xsd:documentation>
        </xsd:annotation>
      </xsd:enumeration>
      <xsd:enumeration value="javaclass">
        <xsd:annotation>
          <xsd:documentation>Indicates Java source file data (extension '.java').</xsd:documentation>
        </xsd:annotation>
      </xsd:enumeration>
      <xsd:enumeration value="javapropertyresourcebundle">
        <xsd:annotation>
          <xsd:documentation>Indicates Java property resource bundle data.</xsd:documentation>
        </xsd:annotation>
      </xsd:enumeration>
      <xsd:enumeration value="javalistresourcebundle">
        <xsd:annotation>
          <xsd:documentation>Indicates Java list resource bundle data.</xsd:documentation>
        </xsd:annotation>
      </xsd:enumeration>
      <xsd:enumeration value="javascript">
        <xsd:annotation>
          <xsd:documentation>Indicates JavaScript source file data.</xsd:documentation>
        </xsd:annotation>
      </xsd:enumeration>
      <xsd:enumeration value="jscript">
        <xsd:annotation>
          <xsd:documentation>Indicates JScript source file data.</xsd:documentation>
        </xsd:annotation>
      </xsd:enumeration>
      <xsd:enumeration value="layout">
        <xsd:annotation>
          <xsd:documentation>Indicates information relating to formatting.</xsd:documentation>
        </xsd:annotation>
      </xsd:enumeration>
      <xsd:enumeration value="lisp">
        <xsd:annotation>
          <xsd:documentation>Indicates LISP source file data.</xsd:documentation>
        </xsd:annotation>
      </xsd:enumeration>
      <xsd:enumeration value="margin">
        <xsd:annotation>
          <xsd:documentation>Indicates information relating to margin formats.</xsd:documentation>
        </xsd:annotation>
      </xsd:enumeration>
      <xsd:enumeration value="menufile">
        <xsd:annotation>
          <xsd:documentation>Indicates a file containing menu.</xsd:documentation>
        </xsd:annotation>
      </xsd:enumeration>
      <xsd:enumeration value="messagefile">
        <xsd:annotation>
          <xsd:documentation>Indicates numerically identified string table.</xsd:documentation>
        </xsd:annotation>
      </xsd:enumeration>
      <xsd:enumeration value="mif">
        <xsd:annotation>
          <xsd:documentation>Indicates Maker Interchange Format (MIF) data.</xsd:documentation>
        </xsd:annotation>
      </xsd:enumeration>
      <xsd:enumeration value="mimetype">
        <xsd:annotation>
          <xsd:documentation>Indicates that the datatype attribute value is a MIME Type value and is defined in the mime-type attribute.</xsd:documentation>
        </xsd:annotation>
      </xsd:enumeration>
      <xsd:enumeration value="mo">
        <xsd:annotation>
          <xsd:documentation>Indicates GNU Machine Object data.</xsd:documentation>
        </xsd:annotation>
      </xsd:enumeration>
      <xsd:enumeration value="msglib">
        <xsd:annotation>
          <xsd:documentation>Indicates Message Librarian strings created by Novell's Message Librarian Tool.</xsd:documentation>
        </xsd:annotation>
      </xsd:enumeration>
      <xsd:enumeration value="pagefooter">
        <xsd:annotation>
          <xsd:documentation>Indicates information to be displayed at the bottom of each page of a document.</xsd:documentation>
        </xsd:annotation>
      </xsd:enumeration>
      <xsd:enumeration value="pageheader">
        <xsd:annotation>
          <xsd:documentation>Indicates information to be displayed at the top of each page of a document.</xsd:documentation>
        </xsd:annotation>
      </xsd:enumeration>
      <xsd:enumeration value="parameters">
        <xsd:annotation>
          <xsd:documentation>Indicates a list of property values (e.g., settings within INI files or preferences dialog).</xsd:documentation>
        </xsd:annotation>
      </xsd:enumeration>
      <xsd:enumeration value="pascal">
        <xsd:annotation>
          <xsd:documentation>Indicates Pascal source file data.</xsd:documentation>
        </xsd:annotation>
      </xsd:enumeration>
      <xsd:enumeration value="php">
        <xsd:annotation>
          <xsd:documentation>Indicates Hypertext Preprocessor data.</xsd:documentation>
        </xsd:annotation>
      </xsd:enumeration>
      <xsd:enumeration value="plaintext">
        <xsd:annotation>
          <xsd:documentation>Indicates plain text file (no formatting other than, possibly, wrapping).</xsd:documentation>
        </xsd:annotation>
      </xsd:enumeration>
      <xsd:enumeration value="po">
        <xsd:annotation>
          <xsd:documentation>Indicates GNU Portable Object file.</xsd:documentation>
        </xsd:annotation>
      </xsd:enumeration>
      <xsd:enumeration value="report">
        <xsd:annotation>
          <xsd:documentation>Indicates dynamically generated user defined document. e.g. Oracle Report, Crystal Report, etc.</xsd:documentation>
        </xsd:annotation>
      </xsd:enumeration>
      <xsd:enumeration value="resources">
        <xsd:annotation>
          <xsd:documentation>Indicates Windows .NET binary resources.</xsd:documentation>
        </xsd:annotation>
      </xsd:enumeration>
      <xsd:enumeration value="resx">
        <xsd:annotation>
          <xsd:documentation>Indicates Windows .NET Resources.</xsd:documentation>
        </xsd:annotation>
      </xsd:enumeration>
      <xsd:enumeration value="rtf">
        <xsd:annotation>
          <xsd:documentation>Indicates Rich Text Format (RTF) data.</xsd:documentation>
        </xsd:annotation>
      </xsd:enumeration>
      <xsd:enumeration value="sgml">
        <xsd:annotation>
          <xsd:documentation>Indicates Standard Generalized Markup Language (SGML) data - document instance.</xsd:documentation>
        </xsd:annotation>
      </xsd:enumeration>
      <xsd:enumeration value="sgmldtd">
        <xsd:annotation>
          <xsd:documentation>Indicates Standard Generalized Markup Language (SGML) data - Document Type Definition (DTD).</xsd:documentation>
        </xsd:annotation>
      </xsd:enumeration>
      <xsd:enumeration value="svg">
        <xsd:annotation>
          <xsd:documentation>Indicates Scalable Vector Graphic (SVG) data.</xsd:documentation>
        </xsd:annotation>
      </xsd:enumeration>
      <xsd:enumeration value="vbscript">
        <xsd:annotation>
          <xsd:documentation>Indicates VisualBasic Script source file.</xsd:documentation>
        </xsd:annotation>
      </xsd:enumeration>
      <xsd:enumeration value="warning">
        <xsd:annotation>
          <xsd:documentation>Indicates warning message.</xsd:documentation>
        </xsd:annotation>
      </xsd:enumeration>
      <xsd:enumeration value="winres">
        <xsd:annotation>
          <xsd:documentation>Indicates Windows (Win32) resources (i.e. resources extracted from an RC script, a message file, or a compiled file).</xsd:documentation>
        </xsd:annotation>
      </xsd:enumeration>
      <xsd:enumeration value="xhtml">
        <xsd:annotation>
          <xsd:documentation>Indicates Extensible HyperText Markup Language (XHTML) data - document instance.</xsd:documentation>
        </xsd:annotation>
      </xsd:enumeration>
      <xsd:enumeration value="xml">
        <xsd:annotation>
          <xsd:documentation>Indicates Extensible Markup Language (XML) data - document instance.</xsd:documentation>
        </xsd:annotation>
      </xsd:enumeration>
      <xsd:enumeration value="xmldtd">
        <xsd:annotation>
          <xsd:documentation>Indicates Extensible Markup Language (XML) data - Document Type Definition (DTD).</xsd:documentation>
        </xsd:annotation>
      </xsd:enumeration>
      <xsd:enumeration value="xsl">
        <xsd:annotation>
          <xsd:documentation>Indicates Extensible Stylesheet Language (XSL) data.</xsd:documentation>
        </xsd:annotation>
      </xsd:enumeration>
      <xsd:enumeration value="xul">
        <xsd:annotation>
          <xsd:documentation>Indicates XUL elements.</xsd:documentation>
        </xsd:annotation>
      </xsd:enumeration>
    </xsd:restriction>
  </xsd:simpleType>
  <xsd:simpleType name="mtypeValueList">
    <xsd:annotation>
      <xsd:documentation>Values for the attribute 'mtype'.</xsd:documentation>
    </xsd:annotation>
    <xsd:restriction base="xsd:NMTOKEN">
      <xsd:enumeration value="abbrev">
        <xsd:annotation>
          <xsd:documentation>Indicates the marked text is an abbreviation.</xsd:documentation>
        </xsd:annotation>
      </xsd:enumeration>
      <xsd:enumeration value="abbreviated-form">
        <xsd:annotation>
          <xsd:documentation>ISO-12620 2.1.8: A term resulting from the omission of any part of the full term while designating the same concept.</xsd:documentation>
        </xsd:annotation>
      </xsd:enumeration>
      <xsd:enumeration value="abbreviation">
        <xsd:annotation>
          <xsd:documentation>ISO-12620 2.1.8.1: An abbreviated form of a simple term resulting from the omission of some of its letters (e.g. 'adj.' for 'adjective').</xsd:documentation>
        </xsd:annotation>
      </xsd:enumeration>
      <xsd:enumeration value="acronym">
        <xsd:annotation>
          <xsd:documentation>ISO-12620 2.1.8.4: An abbreviated form of a term made up of letters from the full form of a multiword term strung together into a sequence pronounced only syllabically (e.g. 'radar' for 'radio detecting and ranging').</xsd:documentation>
        </xsd:annotation>
      </xsd:enumeration>
      <xsd:enumeration value="appellation">
        <xsd:annotation>
          <xsd:documentation>ISO-12620: A proper-name term, such as the name of an agency or other proper entity.</xsd:documentation>
        </xsd:annotation>
      </xsd:enumeration>
      <xsd:enumeration value="collocation">
        <xsd:annotation>
          <xsd:documentation>ISO-12620 2.1.18.1: A recurrent word combination characterized by cohesion in that the components of the collocation must co-occur within an utterance or series of utterances, even though they do not necessarily have to maintain immediate proximity to one another.</xsd:documentation>
        </xsd:annotation>
      </xsd:enumeration>
      <xsd:enumeration value="common-name">
        <xsd:annotation>
          <xsd:documentation>ISO-12620 2.1.5: A synonym for an international scientific term that is used in general discourse in a given language.</xsd:documentation>
        </xsd:annotation>
      </xsd:enumeration>
      <xsd:enumeration value="datetime">
        <xsd:annotation>
          <xsd:documentation>Indicates the marked text is a date and/or time.</xsd:documentation>
        </xsd:annotation>
      </xsd:enumeration>
      <xsd:enumeration value="equation">
        <xsd:annotation>
          <xsd:documentation>ISO-12620 2.1.15: An expression used to represent a concept based on a statement that two mathematical expressions are, for instance, equal as identified by the equal sign (=), or assigned to one another by a similar sign.</xsd:documentation>
        </xsd:annotation>
      </xsd:enumeration>
      <xsd:enumeration value="expanded-form">
        <xsd:annotation>
          <xsd:documentation>ISO-12620 2.1.7: The complete representation of a term for which there is an abbreviated form.</xsd:documentation>
        </xsd:annotation>
      </xsd:enumeration>
      <xsd:enumeration value="formula">
        <xsd:annotation>
          <xsd:documentation>ISO-12620 2.1.14: Figures, symbols or the like used to express a concept briefly, such as a mathematical or chemical formula.</xsd:documentation>
        </xsd:annotation>
      </xsd:enumeration>
      <xsd:enumeration value="head-term">
        <xsd:annotation>
          <xsd:documentation>ISO-12620 2.1.1: The concept designation that has been chosen to head a terminological record.</xsd:documentation>
        </xsd:annotation>
      </xsd:enumeration>
      <xsd:enumeration value="initialism">
        <xsd:annotation>
          <xsd:documentation>ISO-12620 2.1.8.3: An abbreviated form of a term consisting of some of the initial letters of the words making up a multiword term or the term elements making up a compound term when these letters are pronounced individually (e.g. 'BSE' for 'bovine spongiform encephalopathy').</xsd:documentation>
        </xsd:annotation>
      </xsd:enumeration>
      <xsd:enumeration value="international-scientific-term">
        <xsd:annotation>
          <xsd:documentation>ISO-12620 2.1.4: A term that is part of an international scientific nomenclature as adopted by an appropriate scientific body.</xsd:documentation>
        </xsd:annotation>
      </xsd:enumeration>
      <xsd:enumeration value="internationalism">
        <xsd:annotation>
          <xsd:documentation>ISO-12620 2.1.6: A term that has the same or nearly identical orthographic or phonemic form in many languages.</xsd:documentation>
        </xsd:annotation>
      </xsd:enumeration>
      <xsd:enumeration value="logical-expression">
        <xsd:annotation>
          <xsd:documentation>ISO-12620 2.1.16: An expression used to represent a concept based on mathematical or logical relations, such as statements of inequality, set relationships, Boolean operations, and the like.</xsd:documentation>
        </xsd:annotation>
      </xsd:enumeration>
      <xsd:enumeration value="materials-management-unit">
        <xsd:annotation>
          <xsd:documentation>ISO-12620 2.1.17: A unit to track object.</xsd:documentation>
        </xsd:annotation>
      </xsd:enumeration>
      <xsd:enumeration value="name">
        <xsd:annotation>
          <xsd:documentation>Indicates the marked text is a name.</xsd:documentation>
        </xsd:annotation>
      </xsd:enumeration>
      <xsd:enumeration value="near-synonym">
        <xsd:annotation>
          <xsd:documentation>ISO-12620 2.1.3: A term that represents the same or a very similar concept as another term in the same language, but for which interchangeability is limited to some contexts and inapplicable in others.</xsd:documentation>
        </xsd:annotation>
      </xsd:enumeration>
      <xsd:enumeration value="part-number">
        <xsd:annotation>
          <xsd:documentation>ISO-12620 2.1.17.2: A unique alphanumeric designation assigned to an object in a manufacturing system.</xsd:documentation>
        </xsd:annotation>
      </xsd:enumeration>
      <xsd:enumeration value="phrase">
        <xsd:annotation>
          <xsd:documentation>Indicates the marked text is a phrase.</xsd:documentation>
        </xsd:annotation>
      </xsd:enumeration>
      <xsd:enumeration value="phraseological-unit">
        <xsd:annotation>
          <xsd:documentation>ISO-12620 2.1.18: Any group of two or more words that form a unit, the meaning of which frequently cannot be deduced based on the combined sense of the words making up the phrase.</xsd:documentation>
        </xsd:annotation>
      </xsd:enumeration>
      <xsd:enumeration value="protected">
        <xsd:annotation>
          <xsd:documentation>Indicates the marked text should not be translated.</xsd:documentation>
        </xsd:annotation>
      </xsd:enumeration>
      <xsd:enumeration value="romanized-form">
        <xsd:annotation>
          <xsd:documentation>ISO-12620 2.1.12: A form of a term resulting from an operation whereby non-Latin writing systems are converted to the Latin alphabet.</xsd:documentation>
        </xsd:annotation>
      </xsd:enumeration>
      <xsd:enumeration value="seg">
        <xsd:annotation>
          <xsd:documentation>Indicates that the marked text represents a segment.</xsd:documentation>
        </xsd:annotation>
      </xsd:enumeration>
      <xsd:enumeration value="set-phrase">
        <xsd:annotation>
          <xsd:documentation>ISO-12620 2.1.18.2: A fixed, lexicalized phrase.</xsd:documentation>
        </xsd:annotation>
      </xsd:enumeration>
      <xsd:enumeration value="short-form">
        <xsd:annotation>
          <xsd:documentation>ISO-12620 2.1.8.2: A variant of a multiword term that includes fewer words than the full form of the term (e.g. 'Group of Twenty-four' for 'Intergovernmental Group of Twenty-four on International Monetary Affairs').</xsd:documentation>
        </xsd:annotation>
      </xsd:enumeration>
      <xsd:enumeration value="sku">
        <xsd:annotation>
          <xsd:documentation>ISO-12620 2.1.17.1: Stock keeping unit, an inventory item identified by a unique alphanumeric designation assigned to an object in an inventory control system.</xsd:documentation>
        </xsd:annotation>
      </xsd:enumeration>
      <xsd:enumeration value="standard-text">
        <xsd:annotation>
          <xsd:documentation>ISO-12620 2.1.19: A fixed chunk of recurring text.</xsd:documentation>
        </xsd:annotation>
      </xsd:enumeration>
      <xsd:enumeration value="symbol">
        <xsd:annotation>
          <xsd:documentation>ISO-12620 2.1.13: A designation of a concept by letters, numerals, pictograms or any combination thereof.</xsd:documentation>
        </xsd:annotation>
      </xsd:enumeration>
      <xsd:enumeration value="synonym">
        <xsd:annotation>
          <xsd:documentation>ISO-12620 2.1.2: Any term that represents the same or a very similar concept as the main entry term in a term entry.</xsd:documentation>
        </xsd:annotation>
      </xsd:enumeration>
      <xsd:enumeration value="synonymous-phrase">
        <xsd:annotation>
          <xsd:documentation>ISO-12620 2.1.18.3: Phraseological unit in a language that expresses the same semantic content as another phrase in that same language.</xsd:documentation>
        </xsd:annotation>
      </xsd:enumeration>
      <xsd:enumeration value="term">
        <xsd:annotation>
          <xsd:documentation>Indicates the marked text is a term.</xsd:documentation>
        </xsd:annotation>
      </xsd:enumeration>
      <xsd:enumeration value="transcribed-form">
        <xsd:annotation>
          <xsd:documentation>ISO-12620 2.1.11: A form of a term resulting from an operation whereby the characters of one writing system are represented by characters from another writing system, taking into account the pronunciation of the characters converted.</xsd:documentation>
        </xsd:annotation>
      </xsd:enumeration>
      <xsd:enumeration value="transliterated-form">
        <xsd:annotation>
          <xsd:documentation>ISO-12620 2.1.10: A form of a term resulting from an operation whereby the characters of an alphabetic writing system are represented by characters from another alphabetic writing system.</xsd:documentation>
        </xsd:annotation>
      </xsd:enumeration>
      <xsd:enumeration value="truncated-term">
        <xsd:annotation>
          <xsd:documentation>ISO-12620 2.1.8.5: An abbreviated form of a term resulting from the omission of one or more term elements or syllables (e.g. 'flu' for 'influenza').</xsd:documentation>
        </xsd:annotation>
      </xsd:enumeration>
      <xsd:enumeration value="variant">
        <xsd:annotation>
          <xsd:documentation>ISO-12620 2.1.9: One of the alternate forms of a term.</xsd:documentation>
        </xsd:annotation>
      </xsd:enumeration>
    </xsd:restriction>
  </xsd:simpleType>
  <xsd:simpleType name="restypeValueList">
    <xsd:annotation>
      <xsd:documentation>Values for the attribute 'restype'.</xsd:documentation>
    </xsd:annotation>
    <xsd:restriction base="xsd:NMTOKEN">
      <xsd:enumeration value="auto3state">
        <xsd:annotation>
          <xsd:documentation>Indicates a Windows RC AUTO3STATE control.</xsd:documentation>
        </xsd:annotation>
      </xsd:enumeration>
      <xsd:enumeration value="autocheckbox">
        <xsd:annotation>
          <xsd:documentation>Indicates a Windows RC AUTOCHECKBOX control.</xsd:documentation>
        </xsd:annotation>
      </xsd:enumeration>
      <xsd:enumeration value="autoradiobutton">
        <xsd:annotation>
          <xsd:documentation>Indicates a Windows RC AUTORADIOBUTTON control.</xsd:documentation>
        </xsd:annotation>
      </xsd:enumeration>
      <xsd:enumeration value="bedit">
        <xsd:annotation>
          <xsd:documentation>Indicates a Windows RC BEDIT control.</xsd:documentation>
        </xsd:annotation>
      </xsd:enumeration>
      <xsd:enumeration value="bitmap">
        <xsd:annotation>
          <xsd:documentation>Indicates a bitmap, for example a BITMAP resource in Windows.</xsd:documentation>
        </xsd:annotation>
      </xsd:enumeration>
      <xsd:enumeration value="button">
        <xsd:annotation>
          <xsd:documentation>Indicates a button object, for example a BUTTON control Windows.</xsd:documentation>
        </xsd:annotation>
      </xsd:enumeration>
      <xsd:enumeration value="caption">
        <xsd:annotation>
          <xsd:documentation>Indicates a caption, such as the caption of a dialog box.</xsd:documentation>
        </xsd:annotation>
      </xsd:enumeration>
      <xsd:enumeration value="cell">
        <xsd:annotation>
          <xsd:documentation>Indicates the cell in a table, for example the content of the &lt;td&gt; element in HTML.</xsd:documentation>
        </xsd:annotation>
      </xsd:enumeration>
      <xsd:enumeration value="checkbox">
        <xsd:annotation>
          <xsd:documentation>Indicates check box object, for example a CHECKBOX control in Windows.</xsd:documentation>
        </xsd:annotation>
      </xsd:enumeration>
      <xsd:enumeration value="checkboxmenuitem">
        <xsd:annotation>
          <xsd:documentation>Indicates a menu item with an associated checkbox.</xsd:documentation>
        </xsd:annotation>
      </xsd:enumeration>
      <xsd:enumeration value="checkedlistbox">
        <xsd:annotation>
          <xsd:documentation>Indicates a list box, but with a check-box for each item.</xsd:documentation>
        </xsd:annotation>
      </xsd:enumeration>
      <xsd:enumeration value="colorchooser">
        <xsd:annotation>
          <xsd:documentation>Indicates a color selection dialog.</xsd:documentation>
        </xsd:annotation>
      </xsd:enumeration>
      <xsd:enumeration value="combobox">
        <xsd:annotation>
          <xsd:documentation>Indicates a combination of edit box and listbox object, for example a COMBOBOX control in Windows.</xsd:documentation>
        </xsd:annotation>
      </xsd:enumeration>
      <xsd:enumeration value="comboboxexitem">
        <xsd:annotation>
          <xsd:documentation>Indicates an initialization entry of an extended combobox DLGINIT resource block. (code 0x1234).</xsd:documentation>
        </xsd:annotation>
      </xsd:enumeration>
      <xsd:enumeration value="comboboxitem">
        <xsd:annotation>
          <xsd:documentation>Indicates an initialization entry of a combobox DLGINIT resource block (code 0x0403).</xsd:documentation>
        </xsd:annotation>
      </xsd:enumeration>
      <xsd:enumeration value="component">
        <xsd:annotation>
          <xsd:documentation>Indicates a UI base class element that cannot be represented by any other element.</xsd:documentation>
        </xsd:annotation>
      </xsd:enumeration>
      <xsd:enumeration value="contextmenu">
        <xsd:annotation>
          <xsd:documentation>Indicates a context menu.</xsd:documentation>
        </xsd:annotation>
      </xsd:enumeration>
      <xsd:enumeration value="ctext">
        <xsd:annotation>
          <xsd:documentation>Indicates a Windows RC CTEXT control.</xsd:documentation>
        </xsd:annotation>
      </xsd:enumeration>
      <xsd:enumeration value="cursor">
        <xsd:annotation>
          <xsd:documentation>Indicates a cursor, for example a CURSOR resource in Windows.</xsd:documentation>
        </xsd:annotation>
      </xsd:enumeration>
      <xsd:enumeration value="datetimepicker">
        <xsd:annotation>
          <xsd:documentation>Indicates a date/time picker.</xsd:documentation>
        </xsd:annotation>
      </xsd:enumeration>
      <xsd:enumeration value="defpushbutton">
        <xsd:annotation>
          <xsd:documentation>Indicates a Windows RC DEFPUSHBUTTON control.</xsd:documentation>
        </xsd:annotation>
      </xsd:enumeration>
      <xsd:enumeration value="dialog">
        <xsd:annotation>
          <xsd:documentation>Indicates a dialog box.</xsd:documentation>
        </xsd:annotation>
      </xsd:enumeration>
      <xsd:enumeration value="dlginit">
        <xsd:annotation>
          <xsd:documentation>Indicates a Windows RC DLGINIT resource block.</xsd:documentation>
        </xsd:annotation>
      </xsd:enumeration>
      <xsd:enumeration value="edit">
        <xsd:annotation>
          <xsd:documentation>Indicates an edit box object, for example an EDIT control in Windows.</xsd:documentation>
        </xsd:annotation>
      </xsd:enumeration>
      <xsd:enumeration value="file">
        <xsd:annotation>
          <xsd:documentation>Indicates a filename.</xsd:documentation>
        </xsd:annotation>
      </xsd:enumeration>
      <xsd:enumeration value="filechooser">
        <xsd:annotation>
          <xsd:documentation>Indicates a file dialog.</xsd:documentation>
        </xsd:annotation>
      </xsd:enumeration>
      <xsd:enumeration value="fn">
        <xsd:annotation>
          <xsd:documentation>Indicates a footnote.</xsd:documentation>
        </xsd:annotation>
      </xsd:enumeration>
      <xsd:enumeration value="font">
        <xsd:annotation>
          <xsd:documentation>Indicates a font name.</xsd:documentation>
        </xsd:annotation>
      </xsd:enumeration>
      <xsd:enumeration value="footer">
        <xsd:annotation>
          <xsd:documentation>Indicates a footer.</xsd:documentation>
        </xsd:annotation>
      </xsd:enumeration>
      <xsd:enumeration value="frame">
        <xsd:annotation>
          <xsd:documentation>Indicates a frame object.</xsd:documentation>
        </xsd:annotation>
      </xsd:enumeration>
      <xsd:enumeration value="grid">
        <xsd:annotation>
          <xsd:documentation>Indicates a XUL grid element.</xsd:documentation>
        </xsd:annotation>
      </xsd:enumeration>
      <xsd:enumeration value="groupbox">
        <xsd:annotation>
          <xsd:documentation>Indicates a groupbox object, for example a GROUPBOX control in Windows.</xsd:documentation>
        </xsd:annotation>
      </xsd:enumeration>
      <xsd:enumeration value="header">
        <xsd:annotation>
          <xsd:documentation>Indicates a header item.</xsd:documentation>
        </xsd:annotation>
      </xsd:enumeration>
      <xsd:enumeration value="heading">
        <xsd:annotation>
          <xsd:documentation>Indicates a heading, such has the content of &lt;h1&gt;, &lt;h2&gt;, etc. in HTML.</xsd:documentation>
        </xsd:annotation>
      </xsd:enumeration>
      <xsd:enumeration value="hedit">
        <xsd:annotation>
          <xsd:documentation>Indicates a Windows RC HEDIT control.</xsd:documentation>
        </xsd:annotation>
      </xsd:enumeration>
      <xsd:enumeration value="hscrollbar">
        <xsd:annotation>
          <xsd:documentation>Indicates a horizontal scrollbar.</xsd:documentation>
        </xsd:annotation>
      </xsd:enumeration>
      <xsd:enumeration value="icon">
        <xsd:annotation>
          <xsd:documentation>Indicates an icon, for example an ICON resource in Windows.</xsd:documentation>
        </xsd:annotation>
      </xsd:enumeration>
      <xsd:enumeration value="iedit">
        <xsd:annotation>
          <xsd:documentation>Indicates a Windows RC IEDIT control.</xsd:documentation>
        </xsd:annotation>
      </xsd:enumeration>
      <xsd:enumeration value="keywords">
        <xsd:annotation>
          <xsd:documentation>Indicates keyword list, such as the content of the Keywords meta-data in HTML, or a K footnote in WinHelp RTF.</xsd:documentation>
        </xsd:annotation>
      </xsd:enumeration>
      <xsd:enumeration value="label">
        <xsd:annotation>
          <xsd:documentation>Indicates a label object.</xsd:documentation>
        </xsd:annotation>
      </xsd:enumeration>
      <xsd:enumeration value="linklabel">
        <xsd:annotation>
          <xsd:documentation>Indicates a label that is also a HTML link (not necessarily a URL).</xsd:documentation>
        </xsd:annotation>
      </xsd:enumeration>
      <xsd:enumeration value="list">
        <xsd:annotation>
          <xsd:documentation>Indicates a list (a group of list-items, for example an &lt;ol&gt; or &lt;ul&gt; element in HTML).</xsd:documentation>
        </xsd:annotation>
      </xsd:enumeration>
      <xsd:enumeration value="listbox">
        <xsd:annotation>
          <xsd:documentation>Indicates a listbox object, for example an LISTBOX control in Windows.</xsd:documentation>
        </xsd:annotation>
      </xsd:enumeration>
      <xsd:enumeration value="listitem">
        <xsd:annotation>
          <xsd:documentation>Indicates an list item (an entry in a list).</xsd:documentation>
        </xsd:annotation>
      </xsd:enumeration>
      <xsd:enumeration value="ltext">
        <xsd:annotation>
          <xsd:documentation>Indicates a Windows RC LTEXT control.</xsd:documentation>
        </xsd:annotation>
      </xsd:enumeration>
      <xsd:enumeration value="menu">
        <xsd:annotation>
          <xsd:documentation>Indicates a menu (a group of menu-items).</xsd:documentation>
        </xsd:annotation>
      </xsd:enumeration>
      <xsd:enumeration value="menubar">
        <xsd:annotation>
          <xsd:documentation>Indicates a toolbar containing one or more tope level menus.</xsd:documentation>
        </xsd:annotation>
      </xsd:enumeration>
      <xsd:enumeration value="menuitem">
        <xsd:annotation>
          <xsd:documentation>Indicates a menu item (an entry in a menu).</xsd:documentation>
        </xsd:annotation>
      </xsd:enumeration>
      <xsd:enumeration value="menuseparator">
        <xsd:annotation>
          <xsd:documentation>Indicates a XUL menuseparator element.</xsd:documentation>
        </xsd:annotation>
      </xsd:enumeration>
      <xsd:enumeration value="message">
        <xsd:annotation>
          <xsd:documentation>Indicates a message, for example an entry in a MESSAGETABLE resource in Windows.</xsd:documentation>
        </xsd:annotation>
      </xsd:enumeration>
      <xsd:enumeration value="monthcalendar">
        <xsd:annotation>
          <xsd:documentation>Indicates a calendar control.</xsd:documentation>
        </xsd:annotation>
      </xsd:enumeration>
      <xsd:enumeration value="numericupdown">
        <xsd:annotation>
          <xsd:documentation>Indicates an edit box beside a spin control.</xsd:documentation>
        </xsd:annotation>
      </xsd:enumeration>
      <xsd:enumeration value="panel">
        <xsd:annotation>
          <xsd:documentation>Indicates a catch all for rectangular areas.</xsd:documentation>
        </xsd:annotation>
      </xsd:enumeration>
      <xsd:enumeration value="popupmenu">
        <xsd:annotation>
          <xsd:documentation>Indicates a standalone menu not necessarily associated with a menubar.</xsd:documentation>
        </xsd:annotation>
      </xsd:enumeration>
      <xsd:enumeration value="pushbox">
        <xsd:annotation>
          <xsd:documentation>Indicates a pushbox object, for example a PUSHBOX control in Windows.</xsd:documentation>
        </xsd:annotation>
      </xsd:enumeration>
      <xsd:enumeration value="pushbutton">
        <xsd:annotation>
          <xsd:documentation>Indicates a Windows RC PUSHBUTTON control.</xsd:documentation>
        </xsd:annotation>
      </xsd:enumeration>
      <xsd:enumeration value="radio">
        <xsd:annotation>
          <xsd:documentation>Indicates a radio button object.</xsd:documentation>
        </xsd:annotation>
      </xsd:enumeration>
      <xsd:enumeration value="radiobuttonmenuitem">
        <xsd:annotation>
          <xsd:documentation>Indicates a menuitem with associated radio button.</xsd:documentation>
        </xsd:annotation>
      </xsd:enumeration>
      <xsd:enumeration value="rcdata">
        <xsd:annotation>
          <xsd:documentation>Indicates raw data resources for an application.</xsd:documentation>
        </xsd:annotation>
      </xsd:enumeration>
      <xsd:enumeration value="row">
        <xsd:annotation>
          <xsd:documentation>Indicates a row in a table.</xsd:documentation>
        </xsd:annotation>
      </xsd:enumeration>
      <xsd:enumeration value="rtext">
        <xsd:annotation>
          <xsd:documentation>Indicates a Windows RC RTEXT control.</xsd:documentation>
        </xsd:annotation>
      </xsd:enumeration>
      <xsd:enumeration value="scrollpane">
        <xsd:annotation>
          <xsd:documentation>Indicates a user navigable container used to show a portion of a document.</xsd:documentation>
        </xsd:annotation>
      </xsd:enumeration>
      <xsd:enumeration value="separator">
        <xsd:annotation>
          <xsd:documentation>Indicates a generic divider object (e.g. menu group separator).</xsd:documentation>
        </xsd:annotation>
      </xsd:enumeration>
      <xsd:enumeration value="shortcut">
        <xsd:annotation>
          <xsd:documentation>Windows accelerators, shortcuts in resource or property files.</xsd:documentation>
        </xsd:annotation>
      </xsd:enumeration>
      <xsd:enumeration value="spinner">
        <xsd:annotation>
          <xsd:documentation>Indicates a UI control to indicate process activity but not progress.</xsd:documentation>
        </xsd:annotation>
      </xsd:enumeration>
      <xsd:enumeration value="splitter">
        <xsd:annotation>
          <xsd:documentation>Indicates a splitter bar.</xsd:documentation>
        </xsd:annotation>
      </xsd:enumeration>
      <xsd:enumeration value="state3">
        <xsd:annotation>
          <xsd:documentation>Indicates a Windows RC STATE3 control.</xsd:documentation>
        </xsd:annotation>
      </xsd:enumeration>
      <xsd:enumeration value="statusbar">
        <xsd:annotation>
          <xsd:documentation>Indicates a window for providing feedback to the users, like 'read-only', etc.</xsd:documentation>
        </xsd:annotation>
      </xsd:enumeration>
      <xsd:enumeration value="string">
        <xsd:annotation>
          <xsd:documentation>Indicates a string, for example an entry in a STRINGTABLE resource in Windows.</xsd:documentation>
        </xsd:annotation>
      </xsd:enumeration>
      <xsd:enumeration value="tabcontrol">
        <xsd:annotation>
          <xsd:documentation>Indicates a layers of controls with a tab to select layers.</xsd:documentation>
        </xsd:annotation>
      </xsd:enumeration>
      <xsd:enumeration value="table">
        <xsd:annotation>
          <xsd:documentation>Indicates a display and edits regular two-dimensional tables of cells.</xsd:documentation>
        </xsd:annotation>
      </xsd:enumeration>
      <xsd:enumeration value="textbox">
        <xsd:annotation>
          <xsd:documentation>Indicates a XUL textbox element.</xsd:documentation>
        </xsd:annotation>
      </xsd:enumeration>
      <xsd:enumeration value="togglebutton">
        <xsd:annotation>
          <xsd:documentation>Indicates a UI button that can be toggled to on or off state.</xsd:documentation>
        </xsd:annotation>
      </xsd:enumeration>
      <xsd:enumeration value="toolbar">
        <xsd:annotation>
          <xsd:documentation>Indicates an array of controls, usually buttons.</xsd:documentation>
        </xsd:annotation>
      </xsd:enumeration>
      <xsd:enumeration value="tooltip">
        <xsd:annotation>
          <xsd:documentation>Indicates a pop up tool tip text.</xsd:documentation>
        </xsd:annotation>
      </xsd:enumeration>
      <xsd:enumeration value="trackbar">
        <xsd:annotation>
          <xsd:documentation>Indicates a bar with a pointer indicating a position within a certain range.</xsd:documentation>
        </xsd:annotation>
      </xsd:enumeration>
      <xsd:enumeration value="tree">
        <xsd:annotation>
          <xsd:documentation>Indicates a control that displays a set of hierarchical data.</xsd:documentation>
        </xsd:annotation>
      </xsd:enumeration>
      <xsd:enumeration value="uri">
        <xsd:annotation>
          <xsd:documentation>Indicates a URI (URN or URL).</xsd:documentation>
        </xsd:annotation>
      </xsd:enumeration>
      <xsd:enumeration value="userbutton">
        <xsd:annotation>
          <xsd:documentation>Indicates a Windows RC USERBUTTON control.</xsd:documentation>
        </xsd:annotation>
      </xsd:enumeration>
      <xsd:enumeration value="usercontrol">
        <xsd:annotation>
          <xsd:documentation>Indicates a user-defined control like CONTROL control in Windows.</xsd:documentation>
        </xsd:annotation>
      </xsd:enumeration>
      <xsd:enumeration value="var">
        <xsd:annotation>
          <xsd:documentation>Indicates the text of a variable.</xsd:documentation>
        </xsd:annotation>
      </xsd:enumeration>
      <xsd:enumeration value="versioninfo">
        <xsd:annotation>
          <xsd:documentation>Indicates version information about a resource like VERSIONINFO in Windows.</xsd:documentation>
        </xsd:annotation>
      </xsd:enumeration>
      <xsd:enumeration value="vscrollbar">
        <xsd:annotation>
          <xsd:documentation>Indicates a vertical scrollbar.</xsd:documentation>
        </xsd:annotation>
      </xsd:enumeration>
      <xsd:enumeration value="window">
        <xsd:annotation>
          <xsd:documentation>Indicates a graphical window.</xsd:documentation>
        </xsd:annotation>
      </xsd:enumeration>
    </xsd:restriction>
  </xsd:simpleType>
  <xsd:simpleType name="size-unitValueList">
    <xsd:annotation>
      <xsd:documentation>Values for the attribute 'size-unit'.</xsd:documentation>
    </xsd:annotation>
    <xsd:restriction base="xsd:NMTOKEN">
      <xsd:enumeration value="byte">
        <xsd:annotation>
          <xsd:documentation>Indicates a size in 8-bit bytes.</xsd:documentation>
        </xsd:annotation>
      </xsd:enumeration>
      <xsd:enumeration value="char">
        <xsd:annotation>
          <xsd:documentation>Indicates a size in Unicode characters.</xsd:documentation>
        </xsd:annotation>
      </xsd:enumeration>
      <xsd:enumeration value="col">
        <xsd:annotation>
          <xsd:documentation>Indicates a size in columns. Used for HTML text area.</xsd:documentation>
        </xsd:annotation>
      </xsd:enumeration>
      <xsd:enumeration value="cm">
        <xsd:annotation>
          <xsd:documentation>Indicates a size in centimeters.</xsd:documentation>
        </xsd:annotation>
      </xsd:enumeration>
      <xsd:enumeration value="dlgunit">
        <xsd:annotation>
          <xsd:documentation>Indicates a size in dialog units, as defined in Windows resources.</xsd:documentation>
        </xsd:annotation>
      </xsd:enumeration>
      <xsd:enumeration value="em">
        <xsd:annotation>
          <xsd:documentation>Indicates a size in 'font-size' units (as defined in CSS).</xsd:documentation>
        </xsd:annotation>
      </xsd:enumeration>
      <xsd:enumeration value="ex">
        <xsd:annotation>
          <xsd:documentation>Indicates a size in 'x-height' units (as defined in CSS).</xsd:documentation>
        </xsd:annotation>
      </xsd:enumeration>
      <xsd:enumeration value="glyph">
        <xsd:annotation>
          <xsd:documentation>Indicates a size in glyphs. A glyph is considered to be one or more combined Unicode characters that represent a single displayable text character. Sometimes referred to as a 'grapheme cluster'</xsd:documentation>
        </xsd:annotation>
      </xsd:enumeration>
      <xsd:enumeration value="in">
        <xsd:annotation>
          <xsd:documentation>Indicates a size in inches.</xsd:documentation>
        </xsd:annotation>
      </xsd:enumeration>
      <xsd:enumeration value="mm">
        <xsd:annotation>
          <xsd:documentation>Indicates a size in millimeters.</xsd:documentation>
        </xsd:annotation>
      </xsd:enumeration>
      <xsd:enumeration value="percent">
        <xsd:annotation>
          <xsd:documentation>Indicates a size in percentage.</xsd:documentation>
        </xsd:annotation>
      </xsd:enumeration>
      <xsd:enumeration value="pixel">
        <xsd:annotation>
          <xsd:documentation>Indicates a size in pixels.</xsd:documentation>
        </xsd:annotation>
      </xsd:enumeration>
      <xsd:enumeration value="point">
        <xsd:annotation>
          <xsd:documentation>Indicates a size in point.</xsd:documentation>
        </xsd:annotation>
      </xsd:enumeration>
      <xsd:enumeration value="row">
        <xsd:annotation>
          <xsd:documentation>Indicates a size in rows. Used for HTML text area.</xsd:documentation>
        </xsd:annotation>
      </xsd:enumeration>
    </xsd:restriction>
  </xsd:simpleType>
  <xsd:simpleType name="stateValueList">
    <xsd:annotation>
      <xsd:documentation>Values for the attribute 'state'.</xsd:documentation>
    </xsd:annotation>
    <xsd:restriction base="xsd:NMTOKEN">
      <xsd:enumeration value="final">
        <xsd:annotation>
          <xsd:documentation>Indicates the terminating state.</xsd:documentation>
        </xsd:annotation>
      </xsd:enumeration>
      <xsd:enumeration value="needs-adaptation">
        <xsd:annotation>
          <xsd:documentation>Indicates only non-textual information needs adaptation.</xsd:documentation>
        </xsd:annotation>
      </xsd:enumeration>
      <xsd:enumeration value="needs-l10n">
        <xsd:annotation>
          <xsd:documentation>Indicates both text and non-textual information needs adaptation.</xsd:documentation>
        </xsd:annotation>
      </xsd:enumeration>
      <xsd:enumeration value="needs-review-adaptation">
        <xsd:annotation>
          <xsd:documentation>Indicates only non-textual information needs review.</xsd:documentation>
        </xsd:annotation>
      </xsd:enumeration>
      <xsd:enumeration value="needs-review-l10n">
        <xsd:annotation>
          <xsd:documentation>Indicates both text and non-textual information needs review.</xsd:documentation>
        </xsd:annotation>
      </xsd:enumeration>
      <xsd:enumeration value="needs-review-translation">
        <xsd:annotation>
          <xsd:documentation>Indicates that only the text of the item needs to be reviewed.</xsd:documentation>
        </xsd:annotation>
      </xsd:enumeration>
      <xsd:enumeration value="needs-translation">
        <xsd:annotation>
          <xsd:documentation>Indicates that the item needs to be translated.</xsd:documentation>
        </xsd:annotation>
      </xsd:enumeration>
      <xsd:enumeration value="new">
        <xsd:annotation>
          <xsd:documentation>Indicates that the item is new. For example, translation units that were not in a previous version of the document.</xsd:documentation>
        </xsd:annotation>
      </xsd:enumeration>
      <xsd:enumeration value="signed-off">
        <xsd:annotation>
          <xsd:documentation>Indicates that changes are reviewed and approved.</xsd:documentation>
        </xsd:annotation>
      </xsd:enumeration>
      <xsd:enumeration value="translated">
        <xsd:annotation>
          <xsd:documentation>Indicates that the item has been translated.</xsd:documentation>
        </xsd:annotation>
      </xsd:enumeration>
    </xsd:restriction>
  </xsd:simpleType>
  <xsd:simpleType name="state-qualifierValueList">
    <xsd:annotation>
      <xsd:documentation>Values for the attribute 'state-qualifier'.</xsd:documentation>
    </xsd:annotation>
    <xsd:restriction base="xsd:NMTOKEN">
      <xsd:enumeration value="exact-match">
        <xsd:annotation>
          <xsd:documentation>Indicates an exact match. An exact match occurs when a source text of a segment is exactly the same as the source text of a segment that was translated previously.</xsd:documentation>
        </xsd:annotation>
      </xsd:enumeration>
      <xsd:enumeration value="fuzzy-match">
        <xsd:annotation>
          <xsd:documentation>Indicates a fuzzy match. A fuzzy match occurs when a source text of a segment is very similar to the source text of a segment that was translated previously (e.g. when the difference is casing, a few changed words, white-space discripancy, etc.).</xsd:documentation>
        </xsd:annotation>
      </xsd:enumeration>
      <xsd:enumeration value="id-match">
        <xsd:annotation>
          <xsd:documentation>Indicates a match based on matching IDs (in addition to matching text).</xsd:documentation>
        </xsd:annotation>
      </xsd:enumeration>
      <xsd:enumeration value="leveraged-glossary">
        <xsd:annotation>
          <xsd:documentation>Indicates a translation derived from a glossary.</xsd:documentation>
        </xsd:annotation>
      </xsd:enumeration>
      <xsd:enumeration value="leveraged-inherited">
        <xsd:annotation>
          <xsd:documentation>Indicates a translation derived from existing translation.</xsd:documentation>
        </xsd:annotation>
      </xsd:enumeration>
      <xsd:enumeration value="leveraged-mt">
        <xsd:annotation>
          <xsd:documentation>Indicates a translation derived from machine translation.</xsd:documentation>
        </xsd:annotation>
      </xsd:enumeration>
      <xsd:enumeration value="leveraged-repository">
        <xsd:annotation>
          <xsd:documentation>Indicates a translation derived from a translation repository.</xsd:documentation>
        </xsd:annotation>
      </xsd:enumeration>
      <xsd:enumeration value="leveraged-tm">
        <xsd:annotation>
          <xsd:documentation>Indicates a translation derived from a translation memory.</xsd:documentation>
        </xsd:annotation>
      </xsd:enumeration>
      <xsd:enumeration value="mt-suggestion">
        <xsd:annotation>
          <xsd:documentation>Indicates the translation is suggested by machine translation.</xsd:documentation>
        </xsd:annotation>
      </xsd:enumeration>
      <xsd:enumeration value="rejected-grammar">
        <xsd:annotation>
          <xsd:documentation>Indicates that the item has been rejected because of incorrect grammar.</xsd:documentation>
        </xsd:annotation>
      </xsd:enumeration>
      <xsd:enumeration value="rejected-inaccurate">
        <xsd:annotation>
          <xsd:documentation>Indicates that the item has been rejected because it is incorrect.</xsd:documentation>
        </xsd:annotation>
      </xsd:enumeration>
      <xsd:enumeration value="rejected-length">
        <xsd:annotation>
          <xsd:documentation>Indicates that the item has been rejected because it is too long or too short.</xsd:documentation>
        </xsd:annotation>
      </xsd:enumeration>
      <xsd:enumeration value="rejected-spelling">
        <xsd:annotation>
          <xsd:documentation>Indicates that the item has been rejected because of incorrect spelling.</xsd:documentation>
        </xsd:annotation>
      </xsd:enumeration>
      <xsd:enumeration value="tm-suggestion">
        <xsd:annotation>
          <xsd:documentation>Indicates the translation is suggested by translation memory.</xsd:documentation>
        </xsd:annotation>
      </xsd:enumeration>
    </xsd:restriction>
  </xsd:simpleType>
  <xsd:simpleType name="unitValueList">
    <xsd:annotation>
      <xsd:documentation>Values for the attribute 'unit'.</xsd:documentation>
    </xsd:annotation>
    <xsd:restriction base="xsd:NMTOKEN">
      <xsd:enumeration value="word">
        <xsd:annotation>
          <xsd:documentation>Refers to words.</xsd:documentation>
        </xsd:annotation>
      </xsd:enumeration>
      <xsd:enumeration value="page">
        <xsd:annotation>
          <xsd:documentation>Refers to pages.</xsd:documentation>
        </xsd:annotation>
      </xsd:enumeration>
      <xsd:enumeration value="trans-unit">
        <xsd:annotation>
          <xsd:documentation>Refers to &lt;trans-unit&gt; elements.</xsd:documentation>
        </xsd:annotation>
      </xsd:enumeration>
      <xsd:enumeration value="bin-unit">
        <xsd:annotation>
          <xsd:documentation>Refers to &lt;bin-unit&gt; elements.</xsd:documentation>
        </xsd:annotation>
      </xsd:enumeration>
      <xsd:enumeration value="glyph">
        <xsd:annotation>
          <xsd:documentation>Refers to glyphs.</xsd:documentation>
        </xsd:annotation>
      </xsd:enumeration>
      <xsd:enumeration value="item">
        <xsd:annotation>
          <xsd:documentation>Refers to &lt;trans-unit&gt; and/or &lt;bin-unit&gt; elements.</xsd:documentation>
        </xsd:annotation>
      </xsd:enumeration>
      <xsd:enumeration value="instance">
        <xsd:annotation>
          <xsd:documentation>Refers to the occurrences of instances defined by the count-type value.</xsd:documentation>
        </xsd:annotation>
      </xsd:enumeration>
      <xsd:enumeration value="character">
        <xsd:annotation>
          <xsd:documentation>Refers to characters.</xsd:documentation>
        </xsd:annotation>
      </xsd:enumeration>
      <xsd:enumeration value="line">
        <xsd:annotation>
          <xsd:documentation>Refers to lines.</xsd:documentation>
        </xsd:annotation>
      </xsd:enumeration>
      <xsd:enumeration value="sentence">
        <xsd:annotation>
          <xsd:documentation>Refers to sentences.</xsd:documentation>
        </xsd:annotation>
      </xsd:enumeration>
      <xsd:enumeration value="paragraph">
        <xsd:annotation>
          <xsd:documentation>Refers to paragraphs.</xsd:documentation>
        </xsd:annotation>
      </xsd:enumeration>
      <xsd:enumeration value="segment">
        <xsd:annotation>
          <xsd:documentation>Refers to segments.</xsd:documentation>
        </xsd:annotation>
      </xsd:enumeration>
      <xsd:enumeration value="placeable">
        <xsd:annotation>
          <xsd:documentation>Refers to placeables (inline elements).</xsd:documentation>
        </xsd:annotation>
      </xsd:enumeration>
    </xsd:restriction>
  </xsd:simpleType>
  <xsd:simpleType name="priorityValueList">
    <xsd:annotation>
      <xsd:documentation>Values for the attribute 'priority'.</xsd:documentation>
    </xsd:annotation>
    <xsd:restriction base="xsd:positiveInteger">
      <xsd:enumeration value="1">
        <xsd:annotation>
          <xsd:documentation>Highest priority.</xsd:documentation>
        </xsd:annotation>
      </xsd:enumeration>
      <xsd:enumeration value="2">
        <xsd:annotation>
          <xsd:documentation>High priority.</xsd:documentation>
        </xsd:annotation>
      </xsd:enumeration>
      <xsd:enumeration value="3">
        <xsd:annotation>
          <xsd:documentation>High priority, but not as important as 2.</xsd:documentation>
        </xsd:annotation>
      </xsd:enumeration>
      <xsd:enumeration value="4">
        <xsd:annotation>
          <xsd:documentation>High priority, but not as important as 3.</xsd:documentation>
        </xsd:annotation>
      </xsd:enumeration>
      <xsd:enumeration value="5">
        <xsd:annotation>
          <xsd:documentation>Medium priority, but more important than 6.</xsd:documentation>
        </xsd:annotation>
      </xsd:enumeration>
      <xsd:enumeration value="6">
        <xsd:annotation>
          <xsd:documentation>Medium priority, but less important than 5.</xsd:documentation>
        </xsd:annotation>
      </xsd:enumeration>
      <xsd:enumeration value="7">
        <xsd:annotation>
          <xsd:documentation>Low priority, but more important than 8.</xsd:documentation>
        </xsd:annotation>
      </xsd:enumeration>
      <xsd:enumeration value="8">
        <xsd:annotation>
          <xsd:documentation>Low priority, but more important than 9.</xsd:documentation>
        </xsd:annotation>
      </xsd:enumeration>
      <xsd:enumeration value="9">
        <xsd:annotation>
          <xsd:documentation>Low priority.</xsd:documentation>
        </xsd:annotation>
      </xsd:enumeration>
      <xsd:enumeration value="10">
        <xsd:annotation>
          <xsd:documentation>Lowest priority.</xsd:documentation>
        </xsd:annotation>
      </xsd:enumeration>
    </xsd:restriction>
  </xsd:simpleType>
  <xsd:simpleType name="reformatValueYesNo">
    <xsd:restriction base="xsd:string">
      <xsd:enumeration value="yes">
        <xsd:annotation>
          <xsd:documentation>This value indicates that all properties can be reformatted. This value must be used alone.</xsd:documentation>
        </xsd:annotation>
      </xsd:enumeration>
      <xsd:enumeration value="no">
        <xsd:annotation>
          <xsd:documentation>This value indicates that no properties should be reformatted. This value must be used alone.</xsd:documentation>
        </xsd:annotation>
      </xsd:enumeration>
    </xsd:restriction>
  </xsd:simpleType>
  <xsd:simpleType name="reformatValueList">
    <xsd:list>
      <xsd:simpleType>
        <xsd:union memberTypes="xlf:XTend">
          <xsd:simpleType>
            <xsd:restriction base="xsd:string">
              <xsd:enumeration value="coord">
                <xsd:annotation>
                  <xsd:documentation>This value indicates that all information in the coord attribute can be modified.</xsd:documentation>
                </xsd:annotation>
              </xsd:enumeration>
              <xsd:enumeration value="coord-x">
                <xsd:annotation>
                  <xsd:documentation>This value indicates that the x information in the coord attribute can be modified.</xsd:documentation>
                </xsd:annotation>
              </xsd:enumeration>
              <xsd:enumeration value="coord-y">
                <xsd:annotation>
                  <xsd:documentation>This value indicates that the y information in the coord attribute can be modified.</xsd:documentation>
                </xsd:annotation>
              </xsd:enumeration>
              <xsd:enumeration value="coord-cx">
                <xsd:annotation>
                  <xsd:documentation>This value indicates that the cx information in the coord attribute can be modified.</xsd:documentation>
                </xsd:annotation>
              </xsd:enumeration>
              <xsd:enumeration value="coord-cy">
                <xsd:annotation>
                  <xsd:documentation>This value indicates that the cy information in the coord attribute can be modified.</xsd:documentation>
                </xsd:annotation>
              </xsd:enumeration>
              <xsd:enumeration value="font">
                <xsd:annotation>
                  <xsd:documentation>This value indicates that all the information in the font attribute can be modified.</xsd:documentation>
                </xsd:annotation>
              </xsd:enumeration>
              <xsd:enumeration value="font-name">
                <xsd:annotation>
                  <xsd:documentation>This value indicates that the name information in the font attribute can be modified.</xsd:documentation>
                </xsd:annotation>
              </xsd:enumeration>
              <xsd:enumeration value="font-size">
                <xsd:annotation>
                  <xsd:documentation>This value indicates that the size information in the font attribute can be modified.</xsd:documentation>
                </xsd:annotation>
              </xsd:enumeration>
              <xsd:enumeration value="font-weight">
                <xsd:annotation>
                  <xsd:documentation>This value indicates that the weight information in the font attribute can be modified.</xsd:documentation>
                </xsd:annotation>
              </xsd:enumeration>
              <xsd:enumeration value="css-style">
                <xsd:annotation>
                  <xsd:documentation>This value indicates that the information in the css-style attribute can be modified.</xsd:documentation>
                </xsd:annotation>
              </xsd:enumeration>
              <xsd:enumeration value="style">
                <xsd:annotation>
                  <xsd:documentation>This value indicates that the information in the style attribute can be modified.</xsd:documentation>
                </xsd:annotation>
              </xsd:enumeration>
              <xsd:enumeration value="ex-style">
                <xsd:annotation>
                  <xsd:documentation>This value indicates that the information in the exstyle attribute can be modified.</xsd:documentation>
                </xsd:annotation>
              </xsd:enumeration>
            </xsd:restriction>
          </xsd:simpleType>
        </xsd:union>
      </xsd:simpleType>
    </xsd:list>
  </xsd:simpleType>
  <xsd:simpleType name="purposeValueList">
    <xsd:restriction base="xsd:string">
      <xsd:enumeration value="information">
        <xsd:annotation>
          <xsd:documentation>Indicates that the context is informational in nature, specifying for example, how a term should be translated. Thus, should be displayed to anyone editing the XLIFF document.</xsd:documentation>
        </xsd:annotation>
      </xsd:enumeration>
      <xsd:enumeration value="location">
        <xsd:annotation>
          <xsd:documentation>Indicates that the context-group is used to specify where the term was found in the translatable source. Thus, it is not displayed.</xsd:documentation>
        </xsd:annotation>
      </xsd:enumeration>
      <xsd:enumeration value="match">
        <xsd:annotation>
          <xsd:documentation>Indicates that the context information should be used during translation memory lookups. Thus, it is not displayed.</xsd:documentation>
        </xsd:annotation>
      </xsd:enumeration>
    </xsd:restriction>
  </xsd:simpleType>
  <xsd:simpleType name="alttranstypeValueList">
    <xsd:restriction base="xsd:string">
      <xsd:enumeration value="proposal">
        <xsd:annotation>
          <xsd:documentation>Represents a translation proposal from a translation memory or other resource.</xsd:documentation>
        </xsd:annotation>
      </xsd:enumeration>
      <xsd:enumeration value="previous-version">
        <xsd:annotation>
          <xsd:documentation>Represents a previous version of the target element.</xsd:documentation>
        </xsd:annotation>
      </xsd:enumeration>
      <xsd:enumeration value="rejected">
        <xsd:annotation>
          <xsd:documentation>Represents a rejected version of the target element.</xsd:documentation>
        </xsd:annotation>
      </xsd:enumeration>
      <xsd:enumeration value="reference">
        <xsd:annotation>
          <xsd:documentation>Represents a translation to be used for reference purposes only, for example from a related product or a different language.</xsd:documentation>
        </xsd:annotation>
      </xsd:enumeration>
      <xsd:enumeration value="accepted">
        <xsd:annotation>
          <xsd:documentation>Represents a proposed translation that was used for the translation of the trans-unit, possibly modified.</xsd:documentation>
        </xsd:annotation>
      </xsd:enumeration>
    </xsd:restriction>
  </xsd:simpleType>
  <!-- Other Types -->
  <xsd:complexType name="ElemType_ExternalReference">
    <xsd:choice>
      <xsd:element ref="xlf:internal-file"/>
      <xsd:element ref="xlf:external-file"/>
    </xsd:choice>
  </xsd:complexType>
  <xsd:simpleType name="AttrType_purpose">
    <xsd:list>
      <xsd:simpleType>
        <xsd:union memberTypes="xlf:purposeValueList xlf:XTend"/>
      </xsd:simpleType>
    </xsd:list>
  </xsd:simpleType>
  <xsd:simpleType name="AttrType_datatype">
    <xsd:union memberTypes="xlf:datatypeValueList xlf:XTend"/>
  </xsd:simpleType>
  <xsd:simpleType name="AttrType_restype">
    <xsd:union memberTypes="xlf:restypeValueList xlf:XTend"/>
  </xsd:simpleType>
  <xsd:simpleType name="AttrType_alttranstype">
    <xsd:union memberTypes="xlf:alttranstypeValueList xlf:XTend"/>
  </xsd:simpleType>
  <xsd:simpleType name="AttrType_context-type">
    <xsd:union memberTypes="xlf:context-typeValueList xlf:XTend"/>
  </xsd:simpleType>
  <xsd:simpleType name="AttrType_state">
    <xsd:union memberTypes="xlf:stateValueList xlf:XTend"/>
  </xsd:simpleType>
  <xsd:simpleType name="AttrType_state-qualifier">
    <xsd:union memberTypes="xlf:state-qualifierValueList xlf:XTend"/>
  </xsd:simpleType>
  <xsd:simpleType name="AttrType_count-type">
    <xsd:union memberTypes="xlf:restypeValueList xlf:count-typeValueList xlf:datatypeValueList xlf:stateValueList xlf:state-qualifierValueList xlf:XTend"/>
  </xsd:simpleType>
  <xsd:simpleType name="AttrType_InlineDelimiters">
    <xsd:union memberTypes="xlf:InlineDelimitersValueList xlf:XTend"/>
  </xsd:simpleType>
  <xsd:simpleType name="AttrType_InlinePlaceholders">
    <xsd:union memberTypes="xlf:InlinePlaceholdersValueList xlf:XTend"/>
  </xsd:simpleType>
  <xsd:simpleType name="AttrType_size-unit">
    <xsd:union memberTypes="xlf:size-unitValueList xlf:XTend"/>
  </xsd:simpleType>
  <xsd:simpleType name="AttrType_mtype">
    <xsd:union memberTypes="xlf:mtypeValueList xlf:XTend"/>
  </xsd:simpleType>
  <xsd:simpleType name="AttrType_unit">
    <xsd:union memberTypes="xlf:unitValueList xlf:XTend"/>
  </xsd:simpleType>
  <xsd:simpleType name="AttrType_priority">
    <xsd:union memberTypes="xlf:priorityValueList"/>
  </xsd:simpleType>
  <xsd:simpleType name="AttrType_reformat">
    <xsd:union memberTypes="xlf:reformatValueYesNo xlf:reformatValueList"/>
  </xsd:simpleType>
  <xsd:simpleType name="AttrType_YesNo">
    <xsd:restriction base="xsd:NMTOKEN">
      <xsd:enumeration value="yes"/>
      <xsd:enumeration value="no"/>
    </xsd:restriction>
  </xsd:simpleType>
  <xsd:simpleType name="AttrType_Position">
    <xsd:restriction base="xsd:NMTOKEN">
      <xsd:enumeration value="open"/>
      <xsd:enumeration value="close"/>
    </xsd:restriction>
  </xsd:simpleType>
  <xsd:simpleType name="AttrType_assoc">
    <xsd:restriction base="xsd:NMTOKEN">
      <xsd:enumeration value="preceding"/>
      <xsd:enumeration value="following"/>
      <xsd:enumeration value="both"/>
    </xsd:restriction>
  </xsd:simpleType>
  <xsd:simpleType name="AttrType_annotates">
    <xsd:restriction base="xsd:NMTOKEN">
      <xsd:enumeration value="source"/>
      <xsd:enumeration value="target"/>
      <xsd:enumeration value="general"/>
    </xsd:restriction>
  </xsd:simpleType>
  <xsd:simpleType name="AttrType_Coordinates">
    <xsd:annotation>
      <xsd:documentation>Values for the attribute 'coord'.</xsd:documentation>
    </xsd:annotation>
    <xsd:restriction base="xsd:string">
      <xsd:pattern value="(-?\d+|#);(-?\d+|#);(-?\d+|#);(-?\d+|#)"/>
    </xsd:restriction>
  </xsd:simpleType>
  <xsd:simpleType name="AttrType_Version">
    <xsd:annotation>
      <xsd:documentation>Version values: 1.0 and 1.1 are allowed for backward compatibility.</xsd:documentation>
    </xsd:annotation>
    <xsd:restriction base="xsd:string">
      <xsd:enumeration value="1.2"/>
      <xsd:enumeration value="1.1"/>
      <xsd:enumeration value="1.0"/>
    </xsd:restriction>
  </xsd:simpleType>
  <!-- Groups -->
  <xsd:group name="ElemGroup_TextContent">
    <xsd:choice>
      <xsd:element ref="xlf:g"/>
      <xsd:element ref="xlf:bpt"/>
      <xsd:element ref="xlf:ept"/>
      <xsd:element ref="xlf:ph"/>
      <xsd:element ref="xlf:it"/>
      <xsd:element ref="xlf:mrk"/>
      <xsd:element ref="xlf:x"/>
      <xsd:element ref="xlf:bx"/>
      <xsd:element ref="xlf:ex"/>
    </xsd:choice>
  </xsd:group>
  <xsd:attributeGroup name="AttrGroup_TextContent">
    <xsd:attribute name="id" type="xsd:string" use="required"/>
    <xsd:attribute name="xid" type="xsd:string" use="optional"/>
    <xsd:attribute name="equiv-text" type="xsd:string" use="optional"/>
    <xsd:anyAttribute namespace="##other" processContents="strict"/>
  </xsd:attributeGroup>
  <!-- XLIFF Structure -->
  <xsd:element name="xliff">
    <xsd:complexType>
      <xsd:sequence maxOccurs="unbounded">
        <xsd:any maxOccurs="unbounded" minOccurs="0" namespace="##other" processContents="strict"/>
        <xsd:element ref="xlf:file"/>
      </xsd:sequence>
      <xsd:attribute name="version" type="xlf:AttrType_Version" use="required"/>
      <xsd:attribute ref="xml:lang" use="optional"/>
      <xsd:anyAttribute namespace="##other" processContents="strict"/>
    </xsd:complexType>
  </xsd:element>
  <xsd:element name="file">
    <xsd:complexType>
      <xsd:sequence>
        <xsd:element minOccurs="0" ref="xlf:header"/>
        <xsd:element ref="xlf:body"/>
      </xsd:sequence>
      <xsd:attribute name="original" type="xsd:string" use="required"/>
      <xsd:attribute name="source-language" type="xsd:language" use="required"/>
      <xsd:attribute name="datatype" type="xlf:AttrType_datatype" use="required"/>
      <xsd:attribute name="tool-id" type="xsd:string" use="optional"/>
      <xsd:attribute name="date" type="xsd:dateTime" use="optional"/>
      <xsd:attribute ref="xml:space" use="optional"/>
      <xsd:attribute name="category" type="xsd:string" use="optional"/>
      <xsd:attribute name="target-language" type="xsd:language" use="optional"/>
      <xsd:attribute name="product-name" type="xsd:string" use="optional"/>
      <xsd:attribute name="product-version" type="xsd:string" use="optional"/>
      <xsd:attribute name="build-num" type="xsd:string" use="optional"/>
      <xsd:anyAttribute namespace="##other" processContents="strict"/>
    </xsd:complexType>
    <xsd:unique name="U_group_id">
      <xsd:selector xpath=".//xlf:group"/>
      <xsd:field xpath="@id"/>
    </xsd:unique>
    <xsd:key name="K_unit_id">
      <xsd:selector xpath=".//xlf:trans-unit|.//xlf:bin-unit"/>
      <xsd:field xpath="@id"/>
    </xsd:key>
    <xsd:keyref name="KR_unit_id" refer="xlf:K_unit_id">
      <xsd:selector xpath=".//bpt|.//ept|.//it|.//ph|.//g|.//x|.//bx|.//ex|.//sub"/>
      <xsd:field xpath="@xid"/>
    </xsd:keyref>
    <xsd:key name="K_tool-id">
      <xsd:selector xpath="xlf:header/xlf:tool"/>
      <xsd:field xpath="@tool-id"/>
    </xsd:key>
    <xsd:keyref name="KR_file_tool-id" refer="xlf:K_tool-id">
      <xsd:selector xpath="."/>
      <xsd:field xpath="@tool-id"/>
    </xsd:keyref>
    <xsd:keyref name="KR_phase_tool-id" refer="xlf:K_tool-id">
      <xsd:selector xpath="xlf:header/xlf:phase-group/xlf:phase"/>
      <xsd:field xpath="@tool-id"/>
    </xsd:keyref>
    <xsd:keyref name="KR_alt-trans_tool-id" refer="xlf:K_tool-id">
      <xsd:selector xpath=".//xlf:trans-unit/xlf:alt-trans"/>
      <xsd:field xpath="@tool-id"/>
    </xsd:keyref>
    <xsd:key name="K_count-group_name">
      <xsd:selector xpath=".//xlf:count-group"/>
      <xsd:field xpath="@name"/>
    </xsd:key>
    <xsd:unique name="U_context-group_name">
      <xsd:selector xpath=".//xlf:context-group"/>
      <xsd:field xpath="@name"/>
    </xsd:unique>
    <xsd:key name="K_phase-name">
      <xsd:selector xpath="xlf:header/xlf:phase-group/xlf:phase"/>
      <xsd:field xpath="@phase-name"/>
    </xsd:key>
    <xsd:keyref name="KR_phase-name" refer="xlf:K_phase-name">
      <xsd:selector xpath=".//xlf:count|.//xlf:trans-unit|.//xlf:target|.//bin-unit|.//bin-target"/>
      <xsd:field xpath="@phase-name"/>
    </xsd:keyref>
    <xsd:unique name="U_uid">
      <xsd:selector xpath=".//xlf:external-file"/>
      <xsd:field xpath="@uid"/>
    </xsd:unique>
  </xsd:element>
  <xsd:element name="header">
    <xsd:complexType>
      <xsd:sequence>
        <xsd:element minOccurs="0" name="skl" type="xlf:ElemType_ExternalReference"/>
        <xsd:element minOccurs="0" ref="xlf:phase-group"/>
        <xsd:choice maxOccurs="unbounded" minOccurs="0">
          <xsd:element name="glossary" type="xlf:ElemType_ExternalReference"/>
          <xsd:element name="reference" type="xlf:ElemType_ExternalReference"/>
          <xsd:element ref="xlf:count-group"/>
          <xsd:element ref="xlf:note"/>
          <xsd:element ref="xlf:tool"/>
        </xsd:choice>
        <xsd:any maxOccurs="unbounded" minOccurs="0" namespace="##other" processContents="strict"/>
      </xsd:sequence>
    </xsd:complexType>
  </xsd:element>
  <xsd:element name="internal-file">
    <xsd:complexType>
      <xsd:simpleContent>
        <xsd:extension base="xsd:string">
          <xsd:attribute name="form" type="xsd:string"/>
          <xsd:attribute name="crc" type="xsd:NMTOKEN"/>
        </xsd:extension>
      </xsd:simpleContent>
    </xsd:complexType>
  </xsd:element>
  <xsd:element name="external-file">
    <xsd:complexType>
      <xsd:attribute name="href" type="xsd:string" use="required"/>
      <xsd:attribute name="crc" type="xsd:NMTOKEN"/>
      <xsd:attribute name="uid" type="xsd:NMTOKEN"/>
    </xsd:complexType>
  </xsd:element>
  <xsd:element name="note">
    <xsd:complexType>
      <xsd:simpleContent>
        <xsd:extension base="xsd:string">
          <xsd:attribute ref="xml:lang" use="optional"/>
          <xsd:attribute default="1" name="priority" type="xlf:AttrType_priority" use="optional"/>
          <xsd:attribute name="from" type="xsd:string" use="optional"/>
          <xsd:attribute default="general" name="annotates" type="xlf:AttrType_annotates" use="optional"/>
        </xsd:extension>
      </xsd:simpleContent>
    </xsd:complexType>
  </xsd:element>
  <xsd:element name="phase-group">
    <xsd:complexType>
      <xsd:sequence maxOccurs="unbounded">
        <xsd:element ref="xlf:phase"/>
      </xsd:sequence>
    </xsd:complexType>
  </xsd:element>
  <xsd:element name="phase">
    <xsd:complexType>
      <xsd:sequence maxOccurs="unbounded" minOccurs="0">
        <xsd:element ref="xlf:note"/>
      </xsd:sequence>
      <xsd:attribute name="phase-name" type="xsd:string" use="required"/>
      <xsd:attribute name="process-name" type="xsd:string" use="required"/>
      <xsd:attribute name="company-name" type="xsd:string" use="optional"/>
      <xsd:attribute name="tool-id" type="xsd:string" use="optional"/>
      <xsd:attribute name="date" type="xsd:dateTime" use="optional"/>
      <xsd:attribute name="job-id" type="xsd:string" use="optional"/>
      <xsd:attribute name="contact-name" type="xsd:string" use="optional"/>
      <xsd:attribute name="contact-email" type="xsd:string" use="optional"/>
      <xsd:attribute name="contact-phone" type="xsd:string" use="optional"/>
    </xsd:complexType>
  </xsd:element>
  <xsd:element name="count-group">
    <xsd:complexType>
      <xsd:sequence maxOccurs="unbounded" minOccurs="0">
        <xsd:element ref="xlf:count"/>
      </xsd:sequence>
      <xsd:attribute name="name" type="xsd:string" use="required"/>
    </xsd:complexType>
  </xsd:element>
  <xsd:element name="count">
    <xsd:complexType>
      <xsd:simpleContent>
        <xsd:extension base="xsd:string">
          <xsd:attribute name="count-type" type="xlf:AttrType_count-type" use="optional"/>
          <xsd:attribute name="phase-name" type="xsd:string" use="optional"/>
          <xsd:attribute default="word" name="unit" type="xlf:AttrType_unit" use="optional"/>
        </xsd:extension>
      </xsd:simpleContent>
    </xsd:complexType>
  </xsd:element>
  <xsd:element name="context-group">
    <xsd:complexType>
      <xsd:sequence maxOccurs="unbounded">
        <xsd:element ref="xlf:context"/>
      </xsd:sequence>
      <xsd:attribute name="name" type="xsd:string" use="optional"/>
      <xsd:attribute name="crc" type="xsd:NMTOKEN" use="optional"/>
      <xsd:attribute name="purpose" type="xlf:AttrType_purpose" use="optional"/>
    </xsd:complexType>
  </xsd:element>
  <xsd:element name="context">
    <xsd:complexType>
      <xsd:simpleContent>
        <xsd:extension base="xsd:string">
          <xsd:attribute name="context-type" type="xlf:AttrType_context-type" use="required"/>
          <xsd:attribute default="no" name="match-mandatory" type="xlf:AttrType_YesNo" use="optional"/>
          <xsd:attribute name="crc" type="xsd:NMTOKEN" use="optional"/>
        </xsd:extension>
      </xsd:simpleContent>
    </xsd:complexType>
  </xsd:element>
  <xsd:element name="tool">
    <xsd:complexType mixed="true">
      <xsd:sequence>
        <xsd:any namespace="##any" processContents="strict" minOccurs="0" maxOccurs="unbounded"/>
      </xsd:sequence>
      <xsd:attribute name="tool-id" type="xsd:string" use="required"/>
      <xsd:attribute name="tool-name" type="xsd:string" use="required"/>
      <xsd:attribute name="tool-version" type="xsd:string" use="optional"/>
      <xsd:attribute name="tool-company" type="xsd:string" use="optional"/>
      <xsd:anyAttribute namespace="##other" processContents="strict"/>
    </xsd:complexType>
  </xsd:element>
  <xsd:element name="body">
    <xsd:complexType>
      <xsd:choice maxOccurs="unbounded" minOccurs="0">
        <xsd:element maxOccurs="unbounded" minOccurs="0" ref="xlf:group"/>
        <xsd:element maxOccurs="unbounded" minOccurs="0" ref="xlf:trans-unit"/>
        <xsd:element maxOccurs="unbounded" minOccurs="0" ref="xlf:bin-unit"/>
      </xsd:choice>
    </xsd:complexType>
  </xsd:element>
  <xsd:element name="group">
    <xsd:complexType>
      <xsd:sequence>
        <xsd:sequence>
          <xsd:element maxOccurs="unbounded" minOccurs="0" ref="xlf:context-group"/>
          <xsd:element maxOccurs="unbounded" minOccurs="0" ref="xlf:count-group"/>
          <xsd:element maxOccurs="unbounded" minOccurs="0" ref="xlf:note"/>
          <xsd:any maxOccurs="unbounded" minOccurs="0" namespace="##other" processContents="strict"/>
        </xsd:sequence>
        <xsd:choice maxOccurs="unbounded">
          <xsd:element maxOccurs="unbounded" minOccurs="0" ref="xlf:group"/>
          <xsd:element maxOccurs="unbounded" minOccurs="0" ref="xlf:trans-unit"/>
          <xsd:element maxOccurs="unbounded" minOccurs="0" ref="xlf:bin-unit"/>
        </xsd:choice>
      </xsd:sequence>
      <xsd:attribute name="id" type="xsd:string" use="optional"/>
      <xsd:attribute name="datatype" type="xlf:AttrType_datatype" use="optional"/>
      <xsd:attribute default="default" ref="xml:space" use="optional"/>
      <xsd:attribute name="restype" type="xlf:AttrType_restype" use="optional"/>
      <xsd:attribute name="resname" type="xsd:string" use="optional"/>
      <xsd:attribute name="extradata" type="xsd:string" use="optional"/>
      <xsd:attribute name="extype" type="xsd:string" use="optional"/>
      <xsd:attribute name="help-id" type="xsd:NMTOKEN" use="optional"/>
      <xsd:attribute name="menu" type="xsd:string" use="optional"/>
      <xsd:attribute name="menu-option" type="xsd:string" use="optional"/>
      <xsd:attribute name="menu-name" type="xsd:string" use="optional"/>
      <xsd:attribute name="coord" type="xlf:AttrType_Coordinates" use="optional"/>
      <xsd:attribute name="font" type="xsd:string" use="optional"/>
      <xsd:attribute name="css-style" type="xsd:string" use="optional"/>
      <xsd:attribute name="style" type="xsd:NMTOKEN" use="optional"/>
      <xsd:attribute name="exstyle" type="xsd:NMTOKEN" use="optional"/>
      <xsd:attribute default="yes" name="translate" type="xlf:AttrType_YesNo" use="optional"/>
      <xsd:attribute default="yes" name="reformat" type="xlf:AttrType_reformat" use="optional"/>
      <xsd:attribute default="pixel" name="size-unit" type="xlf:AttrType_size-unit" use="optional"/>
      <xsd:attribute name="maxwidth" type="xsd:NMTOKEN" use="optional"/>
      <xsd:attribute name="minwidth" type="xsd:NMTOKEN" use="optional"/>
      <xsd:attribute name="maxheight" type="xsd:NMTOKEN" use="optional"/>
      <xsd:attribute name="minheight" type="xsd:NMTOKEN" use="optional"/>
      <xsd:attribute name="maxbytes" type="xsd:NMTOKEN" use="optional"/>
      <xsd:attribute name="minbytes" type="xsd:NMTOKEN" use="optional"/>
      <xsd:attribute name="charclass" type="xsd:string" use="optional"/>
      <xsd:attribute default="no" name="merged-trans" type="xlf:AttrType_YesNo" use="optional"/>
      <xsd:anyAttribute namespace="##other" processContents="strict"/>
    </xsd:complexType>
  </xsd:element>
  <xsd:element name="trans-unit">
    <xsd:complexType>
      <xsd:sequence>
        <xsd:element ref="xlf:source"/>
        <xsd:element minOccurs="0" ref="xlf:seg-source"/>
        <xsd:element minOccurs="0" ref="xlf:target"/>
        <xsd:choice maxOccurs="unbounded" minOccurs="0">
          <xsd:element ref="xlf:context-group"/>
          <xsd:element ref="xlf:count-group"/>
          <xsd:element ref="xlf:note"/>
          <xsd:element ref="xlf:alt-trans"/>
        </xsd:choice>
        <xsd:any maxOccurs="unbounded" minOccurs="0" namespace="##other" processContents="strict"/>
      </xsd:sequence>
      <xsd:attribute name="id" type="xsd:string" use="required"/>
      <xsd:attribute name="approved" type="xlf:AttrType_YesNo" use="optional"/>
      <xsd:attribute default="yes" name="translate" type="xlf:AttrType_YesNo" use="optional"/>
      <xsd:attribute default="yes" name="reformat" type="xlf:AttrType_reformat" use="optional"/>
      <xsd:attribute default="default" ref="xml:space" use="optional"/>
      <xsd:attribute name="datatype" type="xlf:AttrType_datatype" use="optional"/>
      <xsd:attribute name="phase-name" type="xsd:string" use="optional"/>
      <xsd:attribute name="restype" type="xlf:AttrType_restype" use="optional"/>
      <xsd:attribute name="resname" type="xsd:string" use="optional"/>
      <xsd:attribute name="extradata" type="xsd:string" use="optional"/>
      <xsd:attribute name="extype" type="xsd:string" use="optional"/>
      <xsd:attribute name="help-id" type="xsd:NMTOKEN" use="optional"/>
      <xsd:attribute name="menu" type="xsd:string" use="optional"/>
      <xsd:attribute name="menu-option" type="xsd:string" use="optional"/>
      <xsd:attribute name="menu-name" type="xsd:string" use="optional"/>
      <xsd:attribute name="coord" type="xlf:AttrType_Coordinates" use="optional"/>
      <xsd:attribute name="font" type="xsd:string" use="optional"/>
      <xsd:attribute name="css-style" type="xsd:string" use="optional"/>
      <xsd:attribute name="style" type="xsd:NMTOKEN" use="optional"/>
      <xsd:attribute name="exstyle" type="xsd:NMTOKEN" use="optional"/>
      <xsd:attribute default="pixel" name="size-unit" type="xlf:AttrType_size-unit" use="optional"/>
      <xsd:attribute name="maxwidth" type="xsd:NMTOKEN" use="optional"/>
      <xsd:attribute name="minwidth" type="xsd:NMTOKEN" use="optional"/>
      <xsd:attribute name="maxheight" type="xsd:NMTOKEN" use="optional"/>
      <xsd:attribute name="minheight" type="xsd:NMTOKEN" use="optional"/>
      <xsd:attribute name="maxbytes" type="xsd:NMTOKEN" use="optional"/>
      <xsd:attribute name="minbytes" type="xsd:NMTOKEN" use="optional"/>
      <xsd:attribute name="charclass" type="xsd:string" use="optional"/>
      <xsd:attribute default="yes" name="merged-trans" type="xlf:AttrType_YesNo" use="optional"/>
      <xsd:anyAttribute namespace="##other" processContents="strict"/>
    </xsd:complexType>
    <xsd:unique name="U_tu_segsrc_mid">
      <xsd:selector xpath="./xlf:seg-source/xlf:mrk"/>
      <xsd:field xpath="@mid"/>
    </xsd:unique>
    <xsd:keyref name="KR_tu_segsrc_mid" refer="xlf:U_tu_segsrc_mid">
      <xsd:selector xpath="./xlf:target/xlf:mrk|./xlf:alt-trans"/>
      <xsd:field xpath="@mid"/>
    </xsd:keyref>
  </xsd:element>
  <xsd:element name="source">
    <xsd:complexType mixed="true">
      <xsd:group maxOccurs="unbounded" minOccurs="0" ref="xlf:ElemGroup_TextContent"/>
      <xsd:attribute ref="xml:lang" use="optional"/>
      <xsd:anyAttribute namespace="##other" processContents="strict"/>
    </xsd:complexType>
    <xsd:unique name="U_source_bpt_rid">
      <xsd:selector xpath=".//xlf:bpt"/>
      <xsd:field xpath="@rid"/>
    </xsd:unique>
    <xsd:keyref name="KR_source_ept_rid" refer="xlf:U_source_bpt_rid">
      <xsd:selector xpath=".//xlf:ept"/>
      <xsd:field xpath="@rid"/>
    </xsd:keyref>
    <xsd:unique name="U_source_bx_rid">
      <xsd:selector xpath=".//xlf:bx"/>
      <xsd:field xpath="@rid"/>
    </xsd:unique>
    <xsd:keyref name="KR_source_ex_rid" refer="xlf:U_source_bx_rid">
      <xsd:selector xpath=".//xlf:ex"/>
      <xsd:field xpath="@rid"/>
    </xsd:keyref>
  </xsd:element>
  <xsd:element name="seg-source">
    <xsd:complexType mixed="true">
      <xsd:group maxOccurs="unbounded" minOccurs="0" ref="xlf:ElemGroup_TextContent"/>
      <xsd:attribute ref="xml:lang" use="optional"/>
      <xsd:anyAttribute namespace="##other" processContents="strict"/>
    </xsd:complexType>
    <xsd:unique name="U_segsrc_bpt_rid">
      <xsd:selector xpath=".//xlf:bpt"/>
      <xsd:field xpath="@rid"/>
    </xsd:unique>
    <xsd:keyref name="KR_segsrc_ept_rid" refer="xlf:U_segsrc_bpt_rid">
      <xsd:selector xpath=".//xlf:ept"/>
      <xsd:field xpath="@rid"/>
    </xsd:keyref>
    <xsd:unique name="U_segsrc_bx_rid">
      <xsd:selector xpath=".//xlf:bx"/>
      <xsd:field xpath="@rid"/>
    </xsd:unique>
    <xsd:keyref name="KR_segsrc_ex_rid" refer="xlf:U_segsrc_bx_rid">
      <xsd:selector xpath=".//xlf:ex"/>
      <xsd:field xpath="@rid"/>
    </xsd:keyref>
  </xsd:element>
  <xsd:element name="target">
    <xsd:complexType mixed="true">
      <xsd:group maxOccurs="unbounded" minOccurs="0" ref="xlf:ElemGroup_TextContent"/>
      <xsd:attribute name="state" type="xlf:AttrType_state" use="optional"/>
      <xsd:attribute name="state-qualifier" type="xlf:AttrType_state-qualifier" use="optional"/>
      <xsd:attribute name="phase-name" type="xsd:NMTOKEN" use="optional"/>
      <xsd:attribute ref="xml:lang" use="optional"/>
      <xsd:attribute name="resname" type="xsd:string" use="optional"/>
      <xsd:attribute name="coord" type="xlf:AttrType_Coordinates" use="optional"/>
      <xsd:attribute name="font" type="xsd:string" use="optional"/>
      <xsd:attribute name="css-style" type="xsd:string" use="optional"/>
      <xsd:attribute name="style" type="xsd:NMTOKEN" use="optional"/>
      <xsd:attribute name="exstyle" type="xsd:NMTOKEN" use="optional"/>
      <xsd:attribute default="yes" name="equiv-trans" type="xlf:AttrType_YesNo" use="optional"/>
      <xsd:anyAttribute namespace="##other" processContents="strict"/>
    </xsd:complexType>
    <xsd:unique name="U_target_bpt_rid">
      <xsd:selector xpath=".//xlf:bpt"/>
      <xsd:field xpath="@rid"/>
    </xsd:unique>
    <xsd:keyref name="KR_target_ept_rid" refer="xlf:U_target_bpt_rid">
      <xsd:selector xpath=".//xlf:ept"/>
      <xsd:field xpath="@rid"/>
    </xsd:keyref>
    <xsd:unique name="U_target_bx_rid">
      <xsd:selector xpath=".//xlf:bx"/>
      <xsd:field xpath="@rid"/>
    </xsd:unique>
    <xsd:keyref name="KR_target_ex_rid" refer="xlf:U_target_bx_rid">
      <xsd:selector xpath=".//xlf:ex"/>
      <xsd:field xpath="@rid"/>
    </xsd:keyref>
  </xsd:element>
  <xsd:element name="alt-trans">
    <xsd:complexType>
      <xsd:sequence>
        <xsd:element minOccurs="0" ref="xlf:source"/>
        <xsd:element minOccurs="0" ref="xlf:seg-source"/>
        <xsd:element maxOccurs="1" ref="xlf:target"/>
        <xsd:element maxOccurs="unbounded" minOccurs="0" ref="xlf:context-group"/>
        <xsd:element maxOccurs="unbounded" minOccurs="0" ref="xlf:note"/>
        <xsd:any maxOccurs="unbounded" minOccurs="0" namespace="##other" processContents="strict"/>
      </xsd:sequence>
      <xsd:attribute name="match-quality" type="xsd:string" use="optional"/>
      <xsd:attribute name="tool-id" type="xsd:string" use="optional"/>
      <xsd:attribute name="crc" type="xsd:NMTOKEN" use="optional"/>
      <xsd:attribute ref="xml:lang" use="optional"/>
      <xsd:attribute name="origin" type="xsd:string" use="optional"/>
      <xsd:attribute name="datatype" type="xlf:AttrType_datatype" use="optional"/>
      <xsd:attribute default="default" ref="xml:space" use="optional"/>
      <xsd:attribute name="restype" type="xlf:AttrType_restype" use="optional"/>
      <xsd:attribute name="resname" type="xsd:string" use="optional"/>
      <xsd:attribute name="extradata" type="xsd:string" use="optional"/>
      <xsd:attribute name="extype" type="xsd:string" use="optional"/>
      <xsd:attribute name="help-id" type="xsd:NMTOKEN" use="optional"/>
      <xsd:attribute name="menu" type="xsd:string" use="optional"/>
      <xsd:attribute name="menu-option" type="xsd:string" use="optional"/>
      <xsd:attribute name="menu-name" type="xsd:string" use="optional"/>
      <xsd:attribute name="mid" type="xsd:NMTOKEN" use="optional"/>
      <xsd:attribute name="coord" type="xlf:AttrType_Coordinates" use="optional"/>
      <xsd:attribute name="font" type="xsd:string" use="optional"/>
      <xsd:attribute name="css-style" type="xsd:string" use="optional"/>
      <xsd:attribute name="style" type="xsd:NMTOKEN" use="optional"/>
      <xsd:attribute name="exstyle" type="xsd:NMTOKEN" use="optional"/>
      <xsd:attribute name="phase-name" type="xsd:NMTOKEN" use="optional"/>
      <xsd:attribute default="proposal" name="alttranstype" type="xlf:AttrType_alttranstype" use="optional"/>
      <xsd:anyAttribute namespace="##other" processContents="strict"/>
    </xsd:complexType>
    <xsd:unique name="U_at_segsrc_mid">
      <xsd:selector xpath="./xlf:seg-source/xlf:mrk"/>
      <xsd:field xpath="@mid"/>
    </xsd:unique>
    <xsd:keyref name="KR_at_segsrc_mid" refer="xlf:U_at_segsrc_mid">
      <xsd:selector xpath="./xlf:target/xlf:mrk"/>
      <xsd:field xpath="@mid"/>
    </xsd:keyref>
  </xsd:element>
  <xsd:element name="bin-unit">
    <xsd:complexType>
      <xsd:sequence>
        <xsd:element ref="xlf:bin-source"/>
        <xsd:element minOccurs="0" ref="xlf:bin-target"/>
        <xsd:choice maxOccurs="unbounded" minOccurs="0">
          <xsd:element ref="xlf:context-group"/>
          <xsd:element ref="xlf:count-group"/>
          <xsd:element ref="xlf:note"/>
          <xsd:element ref="xlf:trans-unit"/>
        </xsd:choice>
        <xsd:any maxOccurs="unbounded" minOccurs="0" namespace="##other" processContents="strict"/>
      </xsd:sequence>
      <xsd:attribute name="id" type="xsd:string" use="required"/>
      <xsd:attribute name="mime-type" type="xlf:mime-typeValueList" use="required"/>
      <xsd:attribute name="approved" type="xlf:AttrType_YesNo" use="optional"/>
      <xsd:attribute default="yes" name="translate" type="xlf:AttrType_YesNo" use="optional"/>
      <xsd:attribute default="yes" name="reformat" type="xlf:AttrType_reformat" use="optional"/>
      <xsd:attribute name="restype" type="xlf:AttrType_restype" use="optional"/>
      <xsd:attribute name="resname" type="xsd:string" use="optional"/>
      <xsd:attribute name="phase-name" type="xsd:string" use="optional"/>
      <xsd:anyAttribute namespace="##other" processContents="strict"/>
    </xsd:complexType>
  </xsd:element>
  <xsd:element name="bin-source">
    <xsd:complexType>
      <xsd:choice>
        <xsd:element ref="xlf:internal-file"/>
        <xsd:element ref="xlf:external-file"/>
      </xsd:choice>
      <xsd:anyAttribute namespace="##other" processContents="strict"/>
    </xsd:complexType>
  </xsd:element>
  <xsd:element name="bin-target">
    <xsd:complexType>
      <xsd:choice>
        <xsd:element ref="xlf:internal-file"/>
        <xsd:element ref="xlf:external-file"/>
      </xsd:choice>
      <xsd:attribute name="mime-type" type="xlf:mime-typeValueList" use="optional"/>
      <xsd:attribute name="state" type="xlf:AttrType_state" use="optional"/>
      <xsd:attribute name="state-qualifier" type="xlf:AttrType_state-qualifier" use="optional"/>
      <xsd:attribute name="phase-name" type="xsd:NMTOKEN" use="optional"/>
      <xsd:attribute name="restype" type="xlf:AttrType_restype" use="optional"/>
      <xsd:attribute name="resname" type="xsd:string" use="optional"/>
      <xsd:anyAttribute namespace="##other" processContents="strict"/>
    </xsd:complexType>
  </xsd:element>
  <!-- Element for inline codes -->
  <xsd:element name="g">
    <xsd:complexType mixed="true">
      <xsd:group maxOccurs="unbounded" minOccurs="0" ref="xlf:ElemGroup_TextContent"/>
      <xsd:attribute name="ctype" type="xlf:AttrType_InlineDelimiters" use="optional"/>
      <xsd:attribute default="yes" name="clone" type="xlf:AttrType_YesNo" use="optional"/>
      <xsd:attributeGroup ref="xlf:AttrGroup_TextContent"/>
    </xsd:complexType>
  </xsd:element>
  <xsd:element name="x">
    <xsd:complexType>
      <xsd:attribute name="ctype" type="xlf:AttrType_InlinePlaceholders" use="optional"/>
      <xsd:attribute default="yes" name="clone" type="xlf:AttrType_YesNo" use="optional"/>
      <xsd:attributeGroup ref="xlf:AttrGroup_TextContent"/>
    </xsd:complexType>
  </xsd:element>
  <xsd:element name="bx">
    <xsd:complexType>
      <xsd:attribute name="rid" type="xsd:NMTOKEN" use="optional"/>
      <xsd:attribute name="ctype" type="xlf:AttrType_InlineDelimiters" use="optional"/>
      <xsd:attribute default="yes" name="clone" type="xlf:AttrType_YesNo" use="optional"/>
      <xsd:attributeGroup ref="xlf:AttrGroup_TextContent"/>
    </xsd:complexType>
  </xsd:element>
  <xsd:element name="ex">
    <xsd:complexType>
      <xsd:attribute name="rid" type="xsd:NMTOKEN" use="optional"/>
      <xsd:attributeGroup ref="xlf:AttrGroup_TextContent"/>
    </xsd:complexType>
  </xsd:element>
  <xsd:element name="ph">
    <xsd:complexType mixed="true">
      <xsd:sequence maxOccurs="unbounded" minOccurs="0">
        <xsd:element ref="xlf:sub"/>
      </xsd:sequence>
      <xsd:attribute name="ctype" type="xlf:AttrType_InlinePlaceholders" use="optional"/>
      <xsd:attribute name="crc" type="xsd:string" use="optional"/>
      <xsd:attribute name="assoc" type="xlf:AttrType_assoc" use="optional"/>
      <xsd:attributeGroup ref="xlf:AttrGroup_TextContent"/>
    </xsd:complexType>
  </xsd:element>
  <xsd:element name="bpt">
    <xsd:complexType mixed="true">
      <xsd:sequence maxOccurs="unbounded" minOccurs="0">
        <xsd:element ref="xlf:sub"/>
      </xsd:sequence>
      <xsd:attribute name="rid" type="xsd:NMTOKEN" use="optional"/>
      <xsd:attribute name="ctype" type="xlf:AttrType_InlineDelimiters" use="optional"/>
      <xsd:attribute name="crc" type="xsd:string" use="optional"/>
      <xsd:attributeGroup ref="xlf:AttrGroup_TextContent"/>
    </xsd:complexType>
  </xsd:element>
  <xsd:element name="ept">
    <xsd:complexType mixed="true">
      <xsd:sequence maxOccurs="unbounded" minOccurs="0">
        <xsd:element ref="xlf:sub"/>
      </xsd:sequence>
      <xsd:attribute name="rid" type="xsd:NMTOKEN" use="optional"/>
      <xsd:attribute name="crc" type="xsd:string" use="optional"/>
      <xsd:attributeGroup ref="xlf:AttrGroup_TextContent"/>
    </xsd:complexType>
  </xsd:element>
  <xsd:element name="it">
    <xsd:complexType mixed="true">
      <xsd:sequence maxOccurs="unbounded" minOccurs="0">
        <xsd:element ref="xlf:sub"/>
      </xsd:sequence>
      <xsd:attribute name="pos" type="xlf:AttrType_Position" use="required"/>
      <xsd:attribute name="rid" type="xsd:NMTOKEN" use="optional"/>
      <xsd:attribute name="ctype" type="xlf:AttrType_InlineDelimiters" use="optional"/>
      <xsd:attribute name="crc" type="xsd:string" use="optional"/>
      <xsd:attributeGroup ref="xlf:AttrGroup_TextContent"/>
    </xsd:complexType>
  </xsd:element>
  <xsd:element name="sub">
    <xsd:complexType mixed="true">
      <xsd:group maxOccurs="unbounded" minOccurs="0" ref="xlf:ElemGroup_TextContent"/>
      <xsd:attribute name="datatype" type="xlf:AttrType_datatype" use="optional"/>
      <xsd:attribute name="ctype" type="xlf:AttrType_InlineDelimiters" use="optional"/>
      <xsd:attribute name="xid" type="xsd:string" use="optional"/>
    </xsd:complexType>
  </xsd:element>
  <xsd:element name="mrk">
    <xsd:complexType mixed="true">
      <xsd:group maxOccurs="unbounded" minOccurs="0" ref="xlf:ElemGroup_TextContent"/>
      <xsd:attribute name="mtype" type="xlf:AttrType_mtype" use="required"/>
      <xsd:attribute name="mid" type="xsd:NMTOKEN" use="optional"/>
      <xsd:attribute name="comment" type="xsd:string" use="optional"/>
      <xsd:anyAttribute namespace="##other" processContents="strict"/>
    </xsd:complexType>
  </xsd:element>
</xsd:schema>
PKϤ$ZDo�E��$translation/Loader/CsvFileLoader.phpnu�[���<?php

/*
 * This file is part of the Symfony package.
 *
 * (c) Fabien Potencier <fabien@symfony.com>
 *
 * For the full copyright and license information, please view the LICENSE
 * file that was distributed with this source code.
 */

namespace Symfony\Component\Translation\Loader;

use Symfony\Component\Translation\Exception\NotFoundResourceException;

/**
 * CsvFileLoader loads translations from CSV files.
 *
 * @author Saša Stamenković <umpirsky@gmail.com>
 */
class CsvFileLoader extends FileLoader
{
    private $delimiter = ';';
    private $enclosure = '"';
    private $escape = '\\';

    /**
     * {@inheritdoc}
     */
    protected function loadResource($resource)
    {
        $messages = [];

        try {
            $file = new \SplFileObject($resource, 'rb');
        } catch (\RuntimeException $e) {
            throw new NotFoundResourceException(sprintf('Error opening file "%s".', $resource), 0, $e);
        }

        $file->setFlags(\SplFileObject::READ_CSV | \SplFileObject::SKIP_EMPTY);
        $file->setCsvControl($this->delimiter, $this->enclosure, $this->escape);

        foreach ($file as $data) {
            if (false === $data) {
                continue;
            }

            if ('#' !== substr($data[0], 0, 1) && isset($data[1]) && 2 === \count($data)) {
                $messages[$data[0]] = $data[1];
            }
        }

        return $messages;
    }

    /**
     * Sets the delimiter, enclosure, and escape character for CSV.
     */
    public function setCsvControl(string $delimiter = ';', string $enclosure = '"', string $escape = '\\')
    {
        $this->delimiter = $delimiter;
        $this->enclosure = $enclosure;
        $this->escape = $escape;
    }
}
PKϤ$ZI#�sI
I
#translation/Loader/QtFileLoader.phpnu�[���<?php

/*
 * This file is part of the Symfony package.
 *
 * (c) Fabien Potencier <fabien@symfony.com>
 *
 * For the full copyright and license information, please view the LICENSE
 * file that was distributed with this source code.
 */

namespace Symfony\Component\Translation\Loader;

use Symfony\Component\Config\Resource\FileResource;
use Symfony\Component\Config\Util\XmlUtils;
use Symfony\Component\Translation\Exception\InvalidResourceException;
use Symfony\Component\Translation\Exception\NotFoundResourceException;
use Symfony\Component\Translation\MessageCatalogue;

/**
 * QtFileLoader loads translations from QT Translations XML files.
 *
 * @author Benjamin Eberlei <kontakt@beberlei.de>
 */
class QtFileLoader implements LoaderInterface
{
    /**
     * {@inheritdoc}
     */
    public function load($resource, string $locale, string $domain = 'messages')
    {
        if (!stream_is_local($resource)) {
            throw new InvalidResourceException(sprintf('This is not a local file "%s".', $resource));
        }

        if (!file_exists($resource)) {
            throw new NotFoundResourceException(sprintf('File "%s" not found.', $resource));
        }

        try {
            $dom = XmlUtils::loadFile($resource);
        } catch (\InvalidArgumentException $e) {
            throw new InvalidResourceException(sprintf('Unable to load "%s".', $resource), $e->getCode(), $e);
        }

        $internalErrors = libxml_use_internal_errors(true);
        libxml_clear_errors();

        $xpath = new \DOMXPath($dom);
        $nodes = $xpath->evaluate('//TS/context/name[text()="'.$domain.'"]');

        $catalogue = new MessageCatalogue($locale);
        if (1 == $nodes->length) {
            $translations = $nodes->item(0)->nextSibling->parentNode->parentNode->getElementsByTagName('message');
            foreach ($translations as $translation) {
                $translationValue = (string) $translation->getElementsByTagName('translation')->item(0)->nodeValue;

                if (!empty($translationValue)) {
                    $catalogue->set(
                        (string) $translation->getElementsByTagName('source')->item(0)->nodeValue,
                        $translationValue,
                        $domain
                    );
                }
                $translation = $translation->nextSibling;
            }

            if (class_exists('Symfony\Component\Config\Resource\FileResource')) {
                $catalogue->addResource(new FileResource($resource));
            }
        }

        libxml_use_internal_errors($internalErrors);

        return $catalogue;
    }
}
PKϤ$Z�j�S��"translation/Loader/ArrayLoader.phpnu�[���<?php

/*
 * This file is part of the Symfony package.
 *
 * (c) Fabien Potencier <fabien@symfony.com>
 *
 * For the full copyright and license information, please view the LICENSE
 * file that was distributed with this source code.
 */

namespace Symfony\Component\Translation\Loader;

use Symfony\Component\Translation\MessageCatalogue;

/**
 * ArrayLoader loads translations from a PHP array.
 *
 * @author Fabien Potencier <fabien@symfony.com>
 */
class ArrayLoader implements LoaderInterface
{
    /**
     * {@inheritdoc}
     */
    public function load($resource, string $locale, string $domain = 'messages')
    {
        $resource = $this->flatten($resource);
        $catalogue = new MessageCatalogue($locale);
        $catalogue->add($resource, $domain);

        return $catalogue;
    }

    /**
     * Flattens an nested array of translations.
     *
     * The scheme used is:
     *   'key' => ['key2' => ['key3' => 'value']]
     * Becomes:
     *   'key.key2.key3' => 'value'
     */
    private function flatten(array $messages): array
    {
        $result = [];
        foreach ($messages as $key => $value) {
            if (\is_array($value)) {
                foreach ($this->flatten($value) as $k => $v) {
                    $result[$key.'.'.$k] = $v;
                }
            } else {
                $result[$key] = $value;
            }
        }

        return $result;
    }
}
PKϤ$Z~v;�GG%translation/Loader/YamlFileLoader.phpnu�[���<?php

/*
 * This file is part of the Symfony package.
 *
 * (c) Fabien Potencier <fabien@symfony.com>
 *
 * For the full copyright and license information, please view the LICENSE
 * file that was distributed with this source code.
 */

namespace Symfony\Component\Translation\Loader;

use Symfony\Component\Translation\Exception\InvalidResourceException;
use Symfony\Component\Translation\Exception\LogicException;
use Symfony\Component\Yaml\Exception\ParseException;
use Symfony\Component\Yaml\Parser as YamlParser;
use Symfony\Component\Yaml\Yaml;

/**
 * YamlFileLoader loads translations from Yaml files.
 *
 * @author Fabien Potencier <fabien@symfony.com>
 */
class YamlFileLoader extends FileLoader
{
    private $yamlParser;

    /**
     * {@inheritdoc}
     */
    protected function loadResource($resource)
    {
        if (null === $this->yamlParser) {
            if (!class_exists('Symfony\Component\Yaml\Parser')) {
                throw new LogicException('Loading translations from the YAML format requires the Symfony Yaml component.');
            }

            $this->yamlParser = new YamlParser();
        }

        try {
            $messages = $this->yamlParser->parseFile($resource, Yaml::PARSE_CONSTANT);
        } catch (ParseException $e) {
            throw new InvalidResourceException(sprintf('Error parsing YAML, invalid file "%s".', $resource), 0, $e);
        }

        if (null !== $messages && !\is_array($messages)) {
            throw new InvalidResourceException(sprintf('Unable to load file "%s".', $resource));
        }

        return $messages ?: [];
    }
}
PKϤ$ZyR��QQ'translation/Loader/IcuDatFileLoader.phpnu�[���<?php

/*
 * This file is part of the Symfony package.
 *
 * (c) Fabien Potencier <fabien@symfony.com>
 *
 * For the full copyright and license information, please view the LICENSE
 * file that was distributed with this source code.
 */

namespace Symfony\Component\Translation\Loader;

use Symfony\Component\Config\Resource\FileResource;
use Symfony\Component\Translation\Exception\InvalidResourceException;
use Symfony\Component\Translation\Exception\NotFoundResourceException;
use Symfony\Component\Translation\MessageCatalogue;

/**
 * IcuResFileLoader loads translations from a resource bundle.
 *
 * @author stealth35
 */
class IcuDatFileLoader extends IcuResFileLoader
{
    /**
     * {@inheritdoc}
     */
    public function load($resource, string $locale, string $domain = 'messages')
    {
        if (!stream_is_local($resource.'.dat')) {
            throw new InvalidResourceException(sprintf('This is not a local file "%s".', $resource));
        }

        if (!file_exists($resource.'.dat')) {
            throw new NotFoundResourceException(sprintf('File "%s" not found.', $resource));
        }

        try {
            $rb = new \ResourceBundle($locale, $resource);
        } catch (\Exception $e) {
            $rb = null;
        }

        if (!$rb) {
            throw new InvalidResourceException(sprintf('Cannot load resource "%s".', $resource));
        } elseif (intl_is_failure($rb->getErrorCode())) {
            throw new InvalidResourceException($rb->getErrorMessage(), $rb->getErrorCode());
        }

        $messages = $this->flatten($rb);
        $catalogue = new MessageCatalogue($locale);
        $catalogue->add($messages, $domain);

        if (class_exists('Symfony\Component\Config\Resource\FileResource')) {
            $catalogue->addResource(new FileResource($resource.'.dat'));
        }

        return $catalogue;
    }
}
PKϤ$Zu��'��#translation/Loader/PoFileLoader.phpnu�[���<?php

/*
 * This file is part of the Symfony package.
 *
 * (c) Fabien Potencier <fabien@symfony.com>
 *
 * For the full copyright and license information, please view the LICENSE
 * file that was distributed with this source code.
 */

namespace Symfony\Component\Translation\Loader;

/**
 * @copyright Copyright (c) 2010, Union of RAD https://github.com/UnionOfRAD/lithium
 * @copyright Copyright (c) 2012, Clemens Tolboom
 */
class PoFileLoader extends FileLoader
{
    /**
     * Parses portable object (PO) format.
     *
     * From https://www.gnu.org/software/gettext/manual/gettext.html#PO-Files
     * we should be able to parse files having:
     *
     * white-space
     * #  translator-comments
     * #. extracted-comments
     * #: reference...
     * #, flag...
     * #| msgid previous-untranslated-string
     * msgid untranslated-string
     * msgstr translated-string
     *
     * extra or different lines are:
     *
     * #| msgctxt previous-context
     * #| msgid previous-untranslated-string
     * msgctxt context
     *
     * #| msgid previous-untranslated-string-singular
     * #| msgid_plural previous-untranslated-string-plural
     * msgid untranslated-string-singular
     * msgid_plural untranslated-string-plural
     * msgstr[0] translated-string-case-0
     * ...
     * msgstr[N] translated-string-case-n
     *
     * The definition states:
     * - white-space and comments are optional.
     * - msgid "" that an empty singleline defines a header.
     *
     * This parser sacrifices some features of the reference implementation the
     * differences to that implementation are as follows.
     * - No support for comments spanning multiple lines.
     * - Translator and extracted comments are treated as being the same type.
     * - Message IDs are allowed to have other encodings as just US-ASCII.
     *
     * Items with an empty id are ignored.
     *
     * {@inheritdoc}
     */
    protected function loadResource($resource)
    {
        $stream = fopen($resource, 'r');

        $defaults = [
            'ids' => [],
            'translated' => null,
        ];

        $messages = [];
        $item = $defaults;
        $flags = [];

        while ($line = fgets($stream)) {
            $line = trim($line);

            if ('' === $line) {
                // Whitespace indicated current item is done
                if (!\in_array('fuzzy', $flags)) {
                    $this->addMessage($messages, $item);
                }
                $item = $defaults;
                $flags = [];
            } elseif ('#,' === substr($line, 0, 2)) {
                $flags = array_map('trim', explode(',', substr($line, 2)));
            } elseif ('msgid "' === substr($line, 0, 7)) {
                // We start a new msg so save previous
                // TODO: this fails when comments or contexts are added
                $this->addMessage($messages, $item);
                $item = $defaults;
                $item['ids']['singular'] = substr($line, 7, -1);
            } elseif ('msgstr "' === substr($line, 0, 8)) {
                $item['translated'] = substr($line, 8, -1);
            } elseif ('"' === $line[0]) {
                $continues = isset($item['translated']) ? 'translated' : 'ids';

                if (\is_array($item[$continues])) {
                    end($item[$continues]);
                    $item[$continues][key($item[$continues])] .= substr($line, 1, -1);
                } else {
                    $item[$continues] .= substr($line, 1, -1);
                }
            } elseif ('msgid_plural "' === substr($line, 0, 14)) {
                $item['ids']['plural'] = substr($line, 14, -1);
            } elseif ('msgstr[' === substr($line, 0, 7)) {
                $size = strpos($line, ']');
                $item['translated'][(int) substr($line, 7, 1)] = substr($line, $size + 3, -1);
            }
        }
        // save last item
        if (!\in_array('fuzzy', $flags)) {
            $this->addMessage($messages, $item);
        }
        fclose($stream);

        return $messages;
    }

    /**
     * Save a translation item to the messages.
     *
     * A .po file could contain by error missing plural indexes. We need to
     * fix these before saving them.
     */
    private function addMessage(array &$messages, array $item)
    {
        if (!empty($item['ids']['singular'])) {
            $id = stripcslashes($item['ids']['singular']);
            if (isset($item['ids']['plural'])) {
                $id .= '|'.stripcslashes($item['ids']['plural']);
            }

            $translated = (array) $item['translated'];
            // PO are by definition indexed so sort by index.
            ksort($translated);
            // Make sure every index is filled.
            end($translated);
            $count = key($translated);
            // Fill missing spots with '-'.
            $empties = array_fill(0, $count + 1, '-');
            $translated += $empties;
            ksort($translated);

            $messages[$id] = stripcslashes(implode('|', $translated));
        }
    }
}
PKϤ$Z������$translation/Loader/PhpFileLoader.phpnu�[���<?php

/*
 * This file is part of the Symfony package.
 *
 * (c) Fabien Potencier <fabien@symfony.com>
 *
 * For the full copyright and license information, please view the LICENSE
 * file that was distributed with this source code.
 */

namespace Symfony\Component\Translation\Loader;

/**
 * PhpFileLoader loads translations from PHP files returning an array of translations.
 *
 * @author Fabien Potencier <fabien@symfony.com>
 */
class PhpFileLoader extends FileLoader
{
    private static $cache = [];

    /**
     * {@inheritdoc}
     */
    protected function loadResource($resource)
    {
        if ([] === self::$cache && \function_exists('opcache_invalidate') && filter_var(ini_get('opcache.enable'), FILTER_VALIDATE_BOOLEAN) && (!\in_array(\PHP_SAPI, ['cli', 'phpdbg'], true) || filter_var(ini_get('opcache.enable_cli'), FILTER_VALIDATE_BOOLEAN))) {
            self::$cache = null;
        }

        if (null === self::$cache) {
            return require $resource;
        }

        if (isset(self::$cache[$resource])) {
            return self::$cache[$resource];
        }

        return self::$cache[$resource] = require $resource;
    }
}
PKϤ$Z���00$translation/Loader/IniFileLoader.phpnu�[���<?php

/*
 * This file is part of the Symfony package.
 *
 * (c) Fabien Potencier <fabien@symfony.com>
 *
 * For the full copyright and license information, please view the LICENSE
 * file that was distributed with this source code.
 */

namespace Symfony\Component\Translation\Loader;

/**
 * IniFileLoader loads translations from an ini file.
 *
 * @author stealth35
 */
class IniFileLoader extends FileLoader
{
    /**
     * {@inheritdoc}
     */
    protected function loadResource($resource)
    {
        return parse_ini_file($resource, true);
    }
}
PKϤ$Z�X���&translation/Loader/XliffFileLoader.phpnu�[���<?php

/*
 * This file is part of the Symfony package.
 *
 * (c) Fabien Potencier <fabien@symfony.com>
 *
 * For the full copyright and license information, please view the LICENSE
 * file that was distributed with this source code.
 */

namespace Symfony\Component\Translation\Loader;

use Symfony\Component\Config\Resource\FileResource;
use Symfony\Component\Config\Util\XmlUtils;
use Symfony\Component\Translation\Exception\InvalidResourceException;
use Symfony\Component\Translation\Exception\NotFoundResourceException;
use Symfony\Component\Translation\MessageCatalogue;
use Symfony\Component\Translation\Util\XliffUtils;

/**
 * XliffFileLoader loads translations from XLIFF files.
 *
 * @author Fabien Potencier <fabien@symfony.com>
 */
class XliffFileLoader implements LoaderInterface
{
    /**
     * {@inheritdoc}
     */
    public function load($resource, string $locale, string $domain = 'messages')
    {
        if (!stream_is_local($resource)) {
            throw new InvalidResourceException(sprintf('This is not a local file "%s".', $resource));
        }

        if (!file_exists($resource)) {
            throw new NotFoundResourceException(sprintf('File "%s" not found.', $resource));
        }

        $catalogue = new MessageCatalogue($locale);
        $this->extract($resource, $catalogue, $domain);

        if (class_exists('Symfony\Component\Config\Resource\FileResource')) {
            $catalogue->addResource(new FileResource($resource));
        }

        return $catalogue;
    }

    private function extract($resource, MessageCatalogue $catalogue, string $domain)
    {
        try {
            $dom = XmlUtils::loadFile($resource);
        } catch (\InvalidArgumentException $e) {
            throw new InvalidResourceException(sprintf('Unable to load "%s": '.$e->getMessage(), $resource), $e->getCode(), $e);
        }

        $xliffVersion = XliffUtils::getVersionNumber($dom);
        if ($errors = XliffUtils::validateSchema($dom)) {
            throw new InvalidResourceException(sprintf('Invalid resource provided: "%s"; Errors: '.XliffUtils::getErrorsAsString($errors), $resource));
        }

        if ('1.2' === $xliffVersion) {
            $this->extractXliff1($dom, $catalogue, $domain);
        }

        if ('2.0' === $xliffVersion) {
            $this->extractXliff2($dom, $catalogue, $domain);
        }
    }

    /**
     * Extract messages and metadata from DOMDocument into a MessageCatalogue.
     */
    private function extractXliff1(\DOMDocument $dom, MessageCatalogue $catalogue, string $domain)
    {
        $xml = simplexml_import_dom($dom);
        $encoding = strtoupper($dom->encoding);

        $namespace = 'urn:oasis:names:tc:xliff:document:1.2';
        $xml->registerXPathNamespace('xliff', $namespace);

        foreach ($xml->xpath('//xliff:file') as $file) {
            $fileAttributes = $file->attributes();

            $file->registerXPathNamespace('xliff', $namespace);

            foreach ($file->xpath('.//xliff:trans-unit') as $translation) {
                $attributes = $translation->attributes();

                if (!(isset($attributes['resname']) || isset($translation->source))) {
                    continue;
                }

                $source = isset($attributes['resname']) && $attributes['resname'] ? $attributes['resname'] : $translation->source;
                // If the xlf file has another encoding specified, try to convert it because
                // simple_xml will always return utf-8 encoded values
                $target = $this->utf8ToCharset((string) ($translation->target ?? $translation->source), $encoding);

                $catalogue->set((string) $source, $target, $domain);

                $metadata = [
                    'source' => (string) $translation->source,
                    'file' => [
                        'original' => (string) $fileAttributes['original'],
                    ],
                ];
                if ($notes = $this->parseNotesMetadata($translation->note, $encoding)) {
                    $metadata['notes'] = $notes;
                }

                if (isset($translation->target) && $translation->target->attributes()) {
                    $metadata['target-attributes'] = [];
                    foreach ($translation->target->attributes() as $key => $value) {
                        $metadata['target-attributes'][$key] = (string) $value;
                    }
                }

                if (isset($attributes['id'])) {
                    $metadata['id'] = (string) $attributes['id'];
                }

                $catalogue->setMetadata((string) $source, $metadata, $domain);
            }
        }
    }

    private function extractXliff2(\DOMDocument $dom, MessageCatalogue $catalogue, string $domain)
    {
        $xml = simplexml_import_dom($dom);
        $encoding = strtoupper($dom->encoding);

        $xml->registerXPathNamespace('xliff', 'urn:oasis:names:tc:xliff:document:2.0');

        foreach ($xml->xpath('//xliff:unit') as $unit) {
            foreach ($unit->segment as $segment) {
                $source = $segment->source;

                // If the xlf file has another encoding specified, try to convert it because
                // simple_xml will always return utf-8 encoded values
                $target = $this->utf8ToCharset((string) (isset($segment->target) ? $segment->target : $source), $encoding);

                $catalogue->set((string) $source, $target, $domain);

                $metadata = [];
                if (isset($segment->target) && $segment->target->attributes()) {
                    $metadata['target-attributes'] = [];
                    foreach ($segment->target->attributes() as $key => $value) {
                        $metadata['target-attributes'][$key] = (string) $value;
                    }
                }

                if (isset($unit->notes)) {
                    $metadata['notes'] = [];
                    foreach ($unit->notes->note as $noteNode) {
                        $note = [];
                        foreach ($noteNode->attributes() as $key => $value) {
                            $note[$key] = (string) $value;
                        }
                        $note['content'] = (string) $noteNode;
                        $metadata['notes'][] = $note;
                    }
                }

                $catalogue->setMetadata((string) $source, $metadata, $domain);
            }
        }
    }

    /**
     * Convert a UTF8 string to the specified encoding.
     */
    private function utf8ToCharset(string $content, string $encoding = null): string
    {
        if ('UTF-8' !== $encoding && !empty($encoding)) {
            return mb_convert_encoding($content, $encoding, 'UTF-8');
        }

        return $content;
    }

    private function parseNotesMetadata(\SimpleXMLElement $noteElement = null, string $encoding = null): array
    {
        $notes = [];

        if (null === $noteElement) {
            return $notes;
        }

        /** @var \SimpleXMLElement $xmlNote */
        foreach ($noteElement as $xmlNote) {
            $noteAttributes = $xmlNote->attributes();
            $note = ['content' => $this->utf8ToCharset((string) $xmlNote, $encoding)];
            if (isset($noteAttributes['priority'])) {
                $note['priority'] = (int) $noteAttributes['priority'];
            }

            if (isset($noteAttributes['from'])) {
                $note['from'] = (string) $noteAttributes['from'];
            }

            $notes[] = $note;
        }

        return $notes;
    }
}
PKϤ$Zk�C�!translation/Loader/FileLoader.phpnu�[���<?php

/*
 * This file is part of the Symfony package.
 *
 * (c) Fabien Potencier <fabien@symfony.com>
 *
 * For the full copyright and license information, please view the LICENSE
 * file that was distributed with this source code.
 */

namespace Symfony\Component\Translation\Loader;

use Symfony\Component\Config\Resource\FileResource;
use Symfony\Component\Translation\Exception\InvalidResourceException;
use Symfony\Component\Translation\Exception\NotFoundResourceException;

/**
 * @author Abdellatif Ait boudad <a.aitboudad@gmail.com>
 */
abstract class FileLoader extends ArrayLoader
{
    /**
     * {@inheritdoc}
     */
    public function load($resource, string $locale, string $domain = 'messages')
    {
        if (!stream_is_local($resource)) {
            throw new InvalidResourceException(sprintf('This is not a local file "%s".', $resource));
        }

        if (!file_exists($resource)) {
            throw new NotFoundResourceException(sprintf('File "%s" not found.', $resource));
        }

        $messages = $this->loadResource($resource);

        // empty resource
        if (null === $messages) {
            $messages = [];
        }

        // not an array
        if (!\is_array($messages)) {
            throw new InvalidResourceException(sprintf('Unable to load file "%s".', $resource));
        }

        $catalogue = parent::load($messages, $locale, $domain);

        if (class_exists('Symfony\Component\Config\Resource\FileResource')) {
            $catalogue->addResource(new FileResource($resource));
        }

        return $catalogue;
    }

    /**
     * @param string $resource
     *
     * @return array
     *
     * @throws InvalidResourceException if stream content has an invalid format
     */
    abstract protected function loadResource($resource);
}
PKϤ$Z�[\�DD'translation/Loader/IcuResFileLoader.phpnu�[���<?php

/*
 * This file is part of the Symfony package.
 *
 * (c) Fabien Potencier <fabien@symfony.com>
 *
 * For the full copyright and license information, please view the LICENSE
 * file that was distributed with this source code.
 */

namespace Symfony\Component\Translation\Loader;

use Symfony\Component\Config\Resource\DirectoryResource;
use Symfony\Component\Translation\Exception\InvalidResourceException;
use Symfony\Component\Translation\Exception\NotFoundResourceException;
use Symfony\Component\Translation\MessageCatalogue;

/**
 * IcuResFileLoader loads translations from a resource bundle.
 *
 * @author stealth35
 */
class IcuResFileLoader implements LoaderInterface
{
    /**
     * {@inheritdoc}
     */
    public function load($resource, string $locale, string $domain = 'messages')
    {
        if (!stream_is_local($resource)) {
            throw new InvalidResourceException(sprintf('This is not a local file "%s".', $resource));
        }

        if (!is_dir($resource)) {
            throw new NotFoundResourceException(sprintf('File "%s" not found.', $resource));
        }

        try {
            $rb = new \ResourceBundle($locale, $resource);
        } catch (\Exception $e) {
            $rb = null;
        }

        if (!$rb) {
            throw new InvalidResourceException(sprintf('Cannot load resource "%s".', $resource));
        } elseif (intl_is_failure($rb->getErrorCode())) {
            throw new InvalidResourceException($rb->getErrorMessage(), $rb->getErrorCode());
        }

        $messages = $this->flatten($rb);
        $catalogue = new MessageCatalogue($locale);
        $catalogue->add($messages, $domain);

        if (class_exists('Symfony\Component\Config\Resource\DirectoryResource')) {
            $catalogue->addResource(new DirectoryResource($resource));
        }

        return $catalogue;
    }

    /**
     * Flattens an ResourceBundle.
     *
     * The scheme used is:
     *   key { key2 { key3 { "value" } } }
     * Becomes:
     *   'key.key2.key3' => 'value'
     *
     * This function takes an array by reference and will modify it
     *
     * @param \ResourceBundle $rb       The ResourceBundle that will be flattened
     * @param array           $messages Used internally for recursive calls
     * @param string          $path     Current path being parsed, used internally for recursive calls
     *
     * @return array the flattened ResourceBundle
     */
    protected function flatten(\ResourceBundle $rb, array &$messages = [], string $path = null)
    {
        foreach ($rb as $key => $value) {
            $nodePath = $path ? $path.'.'.$key : $key;
            if ($value instanceof \ResourceBundle) {
                $this->flatten($value, $messages, $nodePath);
            } else {
                $messages[$nodePath] = $value;
            }
        }

        return $messages;
    }
}
PKϤ$Z�o&ltranslation/Util/XliffUtils.phpnu�[���<?php

/*
 * This file is part of the Symfony package.
 *
 * (c) Fabien Potencier <fabien@symfony.com>
 *
 * For the full copyright and license information, please view the LICENSE
 * file that was distributed with this source code.
 */

namespace Symfony\Component\Translation\Util;

use Symfony\Component\Translation\Exception\InvalidArgumentException;
use Symfony\Component\Translation\Exception\InvalidResourceException;

/**
 * Provides some utility methods for XLIFF translation files, such as validating
 * their contents according to the XSD schema.
 *
 * @author Fabien Potencier <fabien@symfony.com>
 */
class XliffUtils
{
    /**
     * Gets xliff file version based on the root "version" attribute.
     *
     * Defaults to 1.2 for backwards compatibility.
     *
     * @throws InvalidArgumentException
     */
    public static function getVersionNumber(\DOMDocument $dom): string
    {
        /** @var \DOMNode $xliff */
        foreach ($dom->getElementsByTagName('xliff') as $xliff) {
            $version = $xliff->attributes->getNamedItem('version');
            if ($version) {
                return $version->nodeValue;
            }

            $namespace = $xliff->attributes->getNamedItem('xmlns');
            if ($namespace) {
                if (0 !== substr_compare('urn:oasis:names:tc:xliff:document:', $namespace->nodeValue, 0, 34)) {
                    throw new InvalidArgumentException(sprintf('Not a valid XLIFF namespace "%s".', $namespace));
                }

                return substr($namespace, 34);
            }
        }

        // Falls back to v1.2
        return '1.2';
    }

    /**
     * Validates and parses the given file into a DOMDocument.
     *
     * @throws InvalidResourceException
     */
    public static function validateSchema(\DOMDocument $dom): array
    {
        $xliffVersion = static::getVersionNumber($dom);
        $internalErrors = libxml_use_internal_errors(true);
        $disableEntities = libxml_disable_entity_loader(false);

        $isValid = @$dom->schemaValidateSource(self::getSchema($xliffVersion));
        if (!$isValid) {
            libxml_disable_entity_loader($disableEntities);

            return self::getXmlErrors($internalErrors);
        }

        libxml_disable_entity_loader($disableEntities);

        $dom->normalizeDocument();

        libxml_clear_errors();
        libxml_use_internal_errors($internalErrors);

        return [];
    }

    public static function getErrorsAsString(array $xmlErrors): string
    {
        $errorsAsString = '';

        foreach ($xmlErrors as $error) {
            $errorsAsString .= sprintf("[%s %s] %s (in %s - line %d, column %d)\n",
                LIBXML_ERR_WARNING === $error['level'] ? 'WARNING' : 'ERROR',
                $error['code'],
                $error['message'],
                $error['file'],
                $error['line'],
                $error['column']
            );
        }

        return $errorsAsString;
    }

    private static function getSchema(string $xliffVersion): string
    {
        if ('1.2' === $xliffVersion) {
            $schemaSource = file_get_contents(__DIR__.'/../Resources/schemas/xliff-core-1.2-strict.xsd');
            $xmlUri = 'http://www.w3.org/2001/xml.xsd';
        } elseif ('2.0' === $xliffVersion) {
            $schemaSource = file_get_contents(__DIR__.'/../Resources/schemas/xliff-core-2.0.xsd');
            $xmlUri = 'informativeCopiesOf3rdPartySchemas/w3c/xml.xsd';
        } else {
            throw new InvalidArgumentException(sprintf('No support implemented for loading XLIFF version "%s".', $xliffVersion));
        }

        return self::fixXmlLocation($schemaSource, $xmlUri);
    }

    /**
     * Internally changes the URI of a dependent xsd to be loaded locally.
     */
    private static function fixXmlLocation(string $schemaSource, string $xmlUri): string
    {
        $newPath = str_replace('\\', '/', __DIR__).'/../Resources/schemas/xml.xsd';
        $parts = explode('/', $newPath);
        $locationstart = 'file:///';
        if (0 === stripos($newPath, 'phar://')) {
            $tmpfile = tempnam(sys_get_temp_dir(), 'symfony');
            if ($tmpfile) {
                copy($newPath, $tmpfile);
                $parts = explode('/', str_replace('\\', '/', $tmpfile));
            } else {
                array_shift($parts);
                $locationstart = 'phar:///';
            }
        }

        $drive = '\\' === \DIRECTORY_SEPARATOR ? array_shift($parts).'/' : '';
        $newPath = $locationstart.$drive.implode('/', array_map('rawurlencode', $parts));

        return str_replace($xmlUri, $newPath, $schemaSource);
    }

    /**
     * Returns the XML errors of the internal XML parser.
     */
    private static function getXmlErrors(bool $internalErrors): array
    {
        $errors = [];
        foreach (libxml_get_errors() as $error) {
            $errors[] = [
                'level' => LIBXML_ERR_WARNING == $error->level ? 'WARNING' : 'ERROR',
                'code' => $error->code,
                'message' => trim($error->message),
                'file' => $error->file ?: 'n/a',
                'line' => $error->line,
                'column' => $error->column,
            ];
        }

        libxml_clear_errors();
        libxml_use_internal_errors($internalErrors);

        return $errors;
    }
}
PKϤ$Z|�E 00#translation/Util/ArrayConverter.phpnu�[���<?php

/*
 * This file is part of the Symfony package.
 *
 * (c) Fabien Potencier <fabien@symfony.com>
 *
 * For the full copyright and license information, please view the LICENSE
 * file that was distributed with this source code.
 */

namespace Symfony\Component\Translation\Util;

/**
 * ArrayConverter generates tree like structure from a message catalogue.
 * e.g. this
 *   'foo.bar1' => 'test1',
 *   'foo.bar2' => 'test2'
 * converts to follows:
 *   foo:
 *     bar1: test1
 *     bar2: test2.
 *
 * @author Gennady Telegin <gtelegin@gmail.com>
 */
class ArrayConverter
{
    /**
     * Converts linear messages array to tree-like array.
     * For example this array('foo.bar' => 'value') will be converted to ['foo' => ['bar' => 'value']].
     *
     * @param array $messages Linear messages array
     *
     * @return array Tree-like messages array
     */
    public static function expandToTree(array $messages)
    {
        $tree = [];

        foreach ($messages as $id => $value) {
            $referenceToElement = &self::getElementByPath($tree, explode('.', $id));

            $referenceToElement = $value;

            unset($referenceToElement);
        }

        return $tree;
    }

    private static function &getElementByPath(array &$tree, array $parts)
    {
        $elem = &$tree;
        $parentOfElem = null;

        foreach ($parts as $i => $part) {
            if (isset($elem[$part]) && \is_string($elem[$part])) {
                /* Process next case:
                 *    'foo': 'test1',
                 *    'foo.bar': 'test2'
                 *
                 * $tree['foo'] was string before we found array {bar: test2}.
                 *  Treat new element as string too, e.g. add $tree['foo.bar'] = 'test2';
                 */
                $elem = &$elem[implode('.', \array_slice($parts, $i))];
                break;
            }
            $parentOfElem = &$elem;
            $elem = &$elem[$part];
        }

        if ($elem && \is_array($elem) && $parentOfElem) {
            /* Process next case:
             *    'foo.bar': 'test1'
             *    'foo': 'test2'
             *
             * $tree['foo'] was array = {bar: 'test1'} before we found string constant `foo`.
             * Cancel treating $tree['foo'] as array and cancel back it expansion,
             *  e.g. make it $tree['foo.bar'] = 'test1' again.
             */
            self::cancelExpand($parentOfElem, $part, $elem);
        }

        return $elem;
    }

    private static function cancelExpand(array &$tree, string $prefix, array $node)
    {
        $prefix .= '.';

        foreach ($node as $id => $value) {
            if (\is_string($value)) {
                $tree[$prefix.$id] = $value;
            } else {
                self::cancelExpand($tree, $prefix.$id, $value);
            }
        }
    }
}
PKϤ$Z��ڶ'translation/DataCollectorTranslator.phpnu�[���<?php

/*
 * This file is part of the Symfony package.
 *
 * (c) Fabien Potencier <fabien@symfony.com>
 *
 * For the full copyright and license information, please view the LICENSE
 * file that was distributed with this source code.
 */

namespace Symfony\Component\Translation;

use Symfony\Component\HttpKernel\CacheWarmer\WarmableInterface;
use Symfony\Component\Translation\Exception\InvalidArgumentException;
use Symfony\Contracts\Translation\LocaleAwareInterface;
use Symfony\Contracts\Translation\TranslatorInterface;

/**
 * @author Abdellatif Ait boudad <a.aitboudad@gmail.com>
 */
class DataCollectorTranslator implements TranslatorInterface, TranslatorBagInterface, LocaleAwareInterface, WarmableInterface
{
    const MESSAGE_DEFINED = 0;
    const MESSAGE_MISSING = 1;
    const MESSAGE_EQUALS_FALLBACK = 2;

    /**
     * @var TranslatorInterface|TranslatorBagInterface
     */
    private $translator;

    private $messages = [];

    /**
     * @param TranslatorInterface $translator The translator must implement TranslatorBagInterface
     */
    public function __construct(TranslatorInterface $translator)
    {
        if (!$translator instanceof TranslatorBagInterface || !$translator instanceof LocaleAwareInterface) {
            throw new InvalidArgumentException(sprintf('The Translator "%s" must implement TranslatorInterface, TranslatorBagInterface and LocaleAwareInterface.', \get_class($translator)));
        }

        $this->translator = $translator;
    }

    /**
     * {@inheritdoc}
     */
    public function trans(?string $id, array $parameters = [], string $domain = null, string $locale = null)
    {
        $trans = $this->translator->trans($id = (string) $id, $parameters, $domain, $locale);
        $this->collectMessage($locale, $domain, $id, $trans, $parameters);

        return $trans;
    }

    /**
     * {@inheritdoc}
     */
    public function setLocale(string $locale)
    {
        $this->translator->setLocale($locale);
    }

    /**
     * {@inheritdoc}
     */
    public function getLocale()
    {
        return $this->translator->getLocale();
    }

    /**
     * {@inheritdoc}
     */
    public function getCatalogue(string $locale = null)
    {
        return $this->translator->getCatalogue($locale);
    }

    /**
     * {@inheritdoc}
     */
    public function warmUp(string $cacheDir)
    {
        if ($this->translator instanceof WarmableInterface) {
            $this->translator->warmUp($cacheDir);
        }
    }

    /**
     * Gets the fallback locales.
     *
     * @return array The fallback locales
     */
    public function getFallbackLocales()
    {
        if ($this->translator instanceof Translator || method_exists($this->translator, 'getFallbackLocales')) {
            return $this->translator->getFallbackLocales();
        }

        return [];
    }

    /**
     * Passes through all unknown calls onto the translator object.
     */
    public function __call(string $method, array $args)
    {
        return $this->translator->{$method}(...$args);
    }

    /**
     * @return array
     */
    public function getCollectedMessages()
    {
        return $this->messages;
    }

    private function collectMessage(?string $locale, ?string $domain, string $id, string $translation, ?array $parameters = [])
    {
        if (null === $domain) {
            $domain = 'messages';
        }

        $catalogue = $this->translator->getCatalogue($locale);
        $locale = $catalogue->getLocale();
        $fallbackLocale = null;
        if ($catalogue->defines($id, $domain)) {
            $state = self::MESSAGE_DEFINED;
        } elseif ($catalogue->has($id, $domain)) {
            $state = self::MESSAGE_EQUALS_FALLBACK;

            $fallbackCatalogue = $catalogue->getFallbackCatalogue();
            while ($fallbackCatalogue) {
                if ($fallbackCatalogue->defines($id, $domain)) {
                    $fallbackLocale = $fallbackCatalogue->getLocale();
                    break;
                }
                $fallbackCatalogue = $fallbackCatalogue->getFallbackCatalogue();
            }
        } else {
            $state = self::MESSAGE_MISSING;
        }

        $this->messages[] = [
            'locale' => $locale,
            'fallbackLocale' => $fallbackLocale,
            'domain' => $domain,
            'id' => $id,
            'translation' => $translation,
            'parameters' => $parameters,
            'state' => $state,
            'transChoiceNumber' => isset($parameters['%count%']) && is_numeric($parameters['%count%']) ? $parameters['%count%'] : null,
        ];
    }
}
PKϤ$Z�ꪴ\\.translation/Extractor/PhpStringTokenParser.phpnu�[���<?php

/*
 * This file is part of the Symfony package.
 *
 * (c) Fabien Potencier <fabien@symfony.com>
 *
 * For the full copyright and license information, please view the LICENSE
 * file that was distributed with this source code.
 */

namespace Symfony\Component\Translation\Extractor;

/*
 * The following is derived from code at http://github.com/nikic/PHP-Parser
 *
 * Copyright (c) 2011 by Nikita Popov
 *
 * Some rights reserved.
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions are
 * met:
 *
 *     * Redistributions of source code must retain the above copyright
 *       notice, this list of conditions and the following disclaimer.
 *
 *     * Redistributions in binary form must reproduce the above
 *       copyright notice, this list of conditions and the following
 *       disclaimer in the documentation and/or other materials provided
 *       with the distribution.
 *
 *     * The names of the contributors may not be used to endorse or
 *       promote products derived from this software without specific
 *       prior written permission.
 *
 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
 * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
 * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
 * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 */

class PhpStringTokenParser
{
    protected static $replacements = [
        '\\' => '\\',
        '$' => '$',
        'n' => "\n",
        'r' => "\r",
        't' => "\t",
        'f' => "\f",
        'v' => "\v",
        'e' => "\x1B",
    ];

    /**
     * Parses a string token.
     *
     * @param string $str String token content
     *
     * @return string The parsed string
     */
    public static function parse(string $str)
    {
        $bLength = 0;
        if ('b' === $str[0]) {
            $bLength = 1;
        }

        if ('\'' === $str[$bLength]) {
            return str_replace(
                ['\\\\', '\\\''],
                ['\\', '\''],
                substr($str, $bLength + 1, -1)
            );
        } else {
            return self::parseEscapeSequences(substr($str, $bLength + 1, -1), '"');
        }
    }

    /**
     * Parses escape sequences in strings (all string types apart from single quoted).
     *
     * @param string      $str   String without quotes
     * @param string|null $quote Quote type
     *
     * @return string String with escape sequences parsed
     */
    public static function parseEscapeSequences(string $str, string $quote = null)
    {
        if (null !== $quote) {
            $str = str_replace('\\'.$quote, $quote, $str);
        }

        return preg_replace_callback(
            '~\\\\([\\\\$nrtfve]|[xX][0-9a-fA-F]{1,2}|[0-7]{1,3})~',
            [__CLASS__, 'parseCallback'],
            $str
        );
    }

    private static function parseCallback(array $matches): string
    {
        $str = $matches[1];

        if (isset(self::$replacements[$str])) {
            return self::$replacements[$str];
        } elseif ('x' === $str[0] || 'X' === $str[0]) {
            return \chr(hexdec($str));
        } else {
            return \chr(octdec($str));
        }
    }

    /**
     * Parses a constant doc string.
     *
     * @param string $startToken Doc string start token content (<<<SMTHG)
     * @param string $str        String token content
     *
     * @return string Parsed string
     */
    public static function parseDocString(string $startToken, string $str)
    {
        // strip last newline (thanks tokenizer for sticking it into the string!)
        $str = preg_replace('~(\r\n|\n|\r)$~', '', $str);

        // nowdoc string
        if (false !== strpos($startToken, '\'')) {
            return $str;
        }

        return self::parseEscapeSequences($str, null);
    }
}
PKϤ$Zxp:CC(translation/Extractor/ChainExtractor.phpnu�[���<?php

/*
 * This file is part of the Symfony package.
 *
 * (c) Fabien Potencier <fabien@symfony.com>
 *
 * For the full copyright and license information, please view the LICENSE
 * file that was distributed with this source code.
 */

namespace Symfony\Component\Translation\Extractor;

use Symfony\Component\Translation\MessageCatalogue;

/**
 * ChainExtractor extracts translation messages from template files.
 *
 * @author Michel Salib <michelsalib@hotmail.com>
 */
class ChainExtractor implements ExtractorInterface
{
    /**
     * The extractors.
     *
     * @var ExtractorInterface[]
     */
    private $extractors = [];

    /**
     * Adds a loader to the translation extractor.
     *
     * @param string $format The format of the loader
     */
    public function addExtractor(string $format, ExtractorInterface $extractor)
    {
        $this->extractors[$format] = $extractor;
    }

    /**
     * {@inheritdoc}
     */
    public function setPrefix(string $prefix)
    {
        foreach ($this->extractors as $extractor) {
            $extractor->setPrefix($prefix);
        }
    }

    /**
     * {@inheritdoc}
     */
    public function extract($directory, MessageCatalogue $catalogue)
    {
        foreach ($this->extractors as $extractor) {
            $extractor->extract($directory, $catalogue);
        }
    }
}
PKϤ$Z/�*��,translation/Extractor/ExtractorInterface.phpnu�[���<?php

/*
 * This file is part of the Symfony package.
 *
 * (c) Fabien Potencier <fabien@symfony.com>
 *
 * For the full copyright and license information, please view the LICENSE
 * file that was distributed with this source code.
 */

namespace Symfony\Component\Translation\Extractor;

use Symfony\Component\Translation\MessageCatalogue;

/**
 * Extracts translation messages from a directory or files to the catalogue.
 * New found messages are injected to the catalogue using the prefix.
 *
 * @author Michel Salib <michelsalib@hotmail.com>
 */
interface ExtractorInterface
{
    /**
     * Extracts translation messages from files, a file or a directory to the catalogue.
     *
     * @param string|array $resource Files, a file or a directory
     */
    public function extract($resource, MessageCatalogue $catalogue);

    /**
     * Sets the prefix that should be used for new found messages.
     *
     * @param string $prefix The prefix
     */
    public function setPrefix(string $prefix);
}
PKϤ$Z*u5��&translation/Extractor/PhpExtractor.phpnu�[���<?php

/*
 * This file is part of the Symfony package.
 *
 * (c) Fabien Potencier <fabien@symfony.com>
 *
 * For the full copyright and license information, please view the LICENSE
 * file that was distributed with this source code.
 */

namespace Symfony\Component\Translation\Extractor;

use Symfony\Component\Finder\Finder;
use Symfony\Component\Translation\MessageCatalogue;

/**
 * PhpExtractor extracts translation messages from a PHP template.
 *
 * @author Michel Salib <michelsalib@hotmail.com>
 */
class PhpExtractor extends AbstractFileExtractor implements ExtractorInterface
{
    const MESSAGE_TOKEN = 300;
    const METHOD_ARGUMENTS_TOKEN = 1000;
    const DOMAIN_TOKEN = 1001;

    /**
     * Prefix for new found message.
     *
     * @var string
     */
    private $prefix = '';

    /**
     * The sequence that captures translation messages.
     *
     * @var array
     */
    protected $sequences = [
        [
            '->',
            'trans',
            '(',
            self::MESSAGE_TOKEN,
            ',',
            self::METHOD_ARGUMENTS_TOKEN,
            ',',
            self::DOMAIN_TOKEN,
        ],
        [
            '->',
            'trans',
            '(',
            self::MESSAGE_TOKEN,
        ],
    ];

    /**
     * {@inheritdoc}
     */
    public function extract($resource, MessageCatalogue $catalog)
    {
        $files = $this->extractFiles($resource);
        foreach ($files as $file) {
            $this->parseTokens(token_get_all(file_get_contents($file)), $catalog, $file);

            gc_mem_caches();
        }
    }

    /**
     * {@inheritdoc}
     */
    public function setPrefix(string $prefix)
    {
        $this->prefix = $prefix;
    }

    /**
     * Normalizes a token.
     *
     * @param mixed $token
     *
     * @return string|null
     */
    protected function normalizeToken($token)
    {
        if (isset($token[1]) && 'b"' !== $token) {
            return $token[1];
        }

        return $token;
    }

    /**
     * Seeks to a non-whitespace token.
     */
    private function seekToNextRelevantToken(\Iterator $tokenIterator)
    {
        for (; $tokenIterator->valid(); $tokenIterator->next()) {
            $t = $tokenIterator->current();
            if (T_WHITESPACE !== $t[0]) {
                break;
            }
        }
    }

    private function skipMethodArgument(\Iterator $tokenIterator)
    {
        $openBraces = 0;

        for (; $tokenIterator->valid(); $tokenIterator->next()) {
            $t = $tokenIterator->current();

            if ('[' === $t[0] || '(' === $t[0]) {
                ++$openBraces;
            }

            if (']' === $t[0] || ')' === $t[0]) {
                --$openBraces;
            }

            if ((0 === $openBraces && ',' === $t[0]) || (-1 === $openBraces && ')' === $t[0])) {
                break;
            }
        }
    }

    /**
     * Extracts the message from the iterator while the tokens
     * match allowed message tokens.
     */
    private function getValue(\Iterator $tokenIterator)
    {
        $message = '';
        $docToken = '';
        $docPart = '';

        for (; $tokenIterator->valid(); $tokenIterator->next()) {
            $t = $tokenIterator->current();
            if ('.' === $t) {
                // Concatenate with next token
                continue;
            }
            if (!isset($t[1])) {
                break;
            }

            switch ($t[0]) {
                case T_START_HEREDOC:
                    $docToken = $t[1];
                    break;
                case T_ENCAPSED_AND_WHITESPACE:
                case T_CONSTANT_ENCAPSED_STRING:
                    if ('' === $docToken) {
                        $message .= PhpStringTokenParser::parse($t[1]);
                    } else {
                        $docPart = $t[1];
                    }
                    break;
                case T_END_HEREDOC:
                    $message .= PhpStringTokenParser::parseDocString($docToken, $docPart);
                    $docToken = '';
                    $docPart = '';
                    break;
                case T_WHITESPACE:
                    break;
                default:
                    break 2;
            }
        }

        return $message;
    }

    /**
     * Extracts trans message from PHP tokens.
     */
    protected function parseTokens(array $tokens, MessageCatalogue $catalog, string $filename)
    {
        $tokenIterator = new \ArrayIterator($tokens);

        for ($key = 0; $key < $tokenIterator->count(); ++$key) {
            foreach ($this->sequences as $sequence) {
                $message = '';
                $domain = 'messages';
                $tokenIterator->seek($key);

                foreach ($sequence as $sequenceKey => $item) {
                    $this->seekToNextRelevantToken($tokenIterator);

                    if ($this->normalizeToken($tokenIterator->current()) === $item) {
                        $tokenIterator->next();
                        continue;
                    } elseif (self::MESSAGE_TOKEN === $item) {
                        $message = $this->getValue($tokenIterator);

                        if (\count($sequence) === ($sequenceKey + 1)) {
                            break;
                        }
                    } elseif (self::METHOD_ARGUMENTS_TOKEN === $item) {
                        $this->skipMethodArgument($tokenIterator);
                    } elseif (self::DOMAIN_TOKEN === $item) {
                        $domainToken = $this->getValue($tokenIterator);
                        if ('' !== $domainToken) {
                            $domain = $domainToken;
                        }

                        break;
                    } else {
                        break;
                    }
                }

                if ($message) {
                    $catalog->set($message, $this->prefix.$message, $domain);
                    $metadata = $catalog->getMetadata($message, $domain) ?? [];
                    $normalizedFilename = preg_replace('{[\\\\/]+}', '/', $filename);
                    $metadata['sources'][] = $normalizedFilename.':'.$tokens[$key][2];
                    $catalog->setMetadata($message, $metadata, $domain);
                    break;
                }
            }
        }
    }

    /**
     * @return bool
     *
     * @throws \InvalidArgumentException
     */
    protected function canBeExtracted(string $file)
    {
        return $this->isFile($file) && 'php' === pathinfo($file, PATHINFO_EXTENSION);
    }

    /**
     * {@inheritdoc}
     */
    protected function extractFromDirectory($directory)
    {
        $finder = new Finder();

        return $finder->files()->name('*.php')->in($directory);
    }
}
PKϤ$Zq�dD��/translation/Extractor/AbstractFileExtractor.phpnu�[���<?php

/*
 * This file is part of the Symfony package.
 *
 * (c) Fabien Potencier <fabien@symfony.com>
 *
 * For the full copyright and license information, please view the LICENSE
 * file that was distributed with this source code.
 */

namespace Symfony\Component\Translation\Extractor;

use Symfony\Component\Translation\Exception\InvalidArgumentException;

/**
 * Base class used by classes that extract translation messages from files.
 *
 * @author Marcos D. Sánchez <marcosdsanchez@gmail.com>
 */
abstract class AbstractFileExtractor
{
    /**
     * @param string|iterable $resource Files, a file or a directory
     *
     * @return iterable
     */
    protected function extractFiles($resource)
    {
        if (is_iterable($resource)) {
            $files = [];
            foreach ($resource as $file) {
                if ($this->canBeExtracted($file)) {
                    $files[] = $this->toSplFileInfo($file);
                }
            }
        } elseif (is_file($resource)) {
            $files = $this->canBeExtracted($resource) ? [$this->toSplFileInfo($resource)] : [];
        } else {
            $files = $this->extractFromDirectory($resource);
        }

        return $files;
    }

    private function toSplFileInfo(string $file): \SplFileInfo
    {
        return new \SplFileInfo($file);
    }

    /**
     * @return bool
     *
     * @throws InvalidArgumentException
     */
    protected function isFile(string $file)
    {
        if (!is_file($file)) {
            throw new InvalidArgumentException(sprintf('The "%s" file does not exist.', $file));
        }

        return true;
    }

    /**
     * @return bool
     */
    abstract protected function canBeExtracted(string $file);

    /**
     * @param string|array $resource Files, a file or a directory
     *
     * @return iterable files to be extracted
     */
    abstract protected function extractFromDirectory($resource);
}
PKϤ$Z_:U&��+translation/Catalogue/AbstractOperation.phpnu�[���<?php

/*
 * This file is part of the Symfony package.
 *
 * (c) Fabien Potencier <fabien@symfony.com>
 *
 * For the full copyright and license information, please view the LICENSE
 * file that was distributed with this source code.
 */

namespace Symfony\Component\Translation\Catalogue;

use Symfony\Component\Translation\Exception\InvalidArgumentException;
use Symfony\Component\Translation\Exception\LogicException;
use Symfony\Component\Translation\MessageCatalogue;
use Symfony\Component\Translation\MessageCatalogueInterface;

/**
 * Base catalogues binary operation class.
 *
 * A catalogue binary operation performs operation on
 * source (the left argument) and target (the right argument) catalogues.
 *
 * @author Jean-François Simon <contact@jfsimon.fr>
 */
abstract class AbstractOperation implements OperationInterface
{
    protected $source;
    protected $target;
    protected $result;

    /**
     * @var array|null The domains affected by this operation
     */
    private $domains;

    /**
     * This array stores 'all', 'new' and 'obsolete' messages for all valid domains.
     *
     * The data structure of this array is as follows:
     *
     *     [
     *         'domain 1' => [
     *             'all' => [...],
     *             'new' => [...],
     *             'obsolete' => [...]
     *         ],
     *         'domain 2' => [
     *             'all' => [...],
     *             'new' => [...],
     *             'obsolete' => [...]
     *         ],
     *         ...
     *     ]
     *
     * @var array The array that stores 'all', 'new' and 'obsolete' messages
     */
    protected $messages;

    /**
     * @throws LogicException
     */
    public function __construct(MessageCatalogueInterface $source, MessageCatalogueInterface $target)
    {
        if ($source->getLocale() !== $target->getLocale()) {
            throw new LogicException('Operated catalogues must belong to the same locale.');
        }

        $this->source = $source;
        $this->target = $target;
        $this->result = new MessageCatalogue($source->getLocale());
        $this->messages = [];
    }

    /**
     * {@inheritdoc}
     */
    public function getDomains()
    {
        if (null === $this->domains) {
            $this->domains = array_values(array_unique(array_merge($this->source->getDomains(), $this->target->getDomains())));
        }

        return $this->domains;
    }

    /**
     * {@inheritdoc}
     */
    public function getMessages(string $domain)
    {
        if (!\in_array($domain, $this->getDomains())) {
            throw new InvalidArgumentException(sprintf('Invalid domain: "%s".', $domain));
        }

        if (!isset($this->messages[$domain]['all'])) {
            $this->processDomain($domain);
        }

        return $this->messages[$domain]['all'];
    }

    /**
     * {@inheritdoc}
     */
    public function getNewMessages(string $domain)
    {
        if (!\in_array($domain, $this->getDomains())) {
            throw new InvalidArgumentException(sprintf('Invalid domain: "%s".', $domain));
        }

        if (!isset($this->messages[$domain]['new'])) {
            $this->processDomain($domain);
        }

        return $this->messages[$domain]['new'];
    }

    /**
     * {@inheritdoc}
     */
    public function getObsoleteMessages(string $domain)
    {
        if (!\in_array($domain, $this->getDomains())) {
            throw new InvalidArgumentException(sprintf('Invalid domain: "%s".', $domain));
        }

        if (!isset($this->messages[$domain]['obsolete'])) {
            $this->processDomain($domain);
        }

        return $this->messages[$domain]['obsolete'];
    }

    /**
     * {@inheritdoc}
     */
    public function getResult()
    {
        foreach ($this->getDomains() as $domain) {
            if (!isset($this->messages[$domain])) {
                $this->processDomain($domain);
            }
        }

        return $this->result;
    }

    /**
     * Performs operation on source and target catalogues for the given domain and
     * stores the results.
     *
     * @param string $domain The domain which the operation will be performed for
     */
    abstract protected function processDomain(string $domain);
}
PKϤ$Z�)�??(translation/Catalogue/MergeOperation.phpnu�[���<?php

/*
 * This file is part of the Symfony package.
 *
 * (c) Fabien Potencier <fabien@symfony.com>
 *
 * For the full copyright and license information, please view the LICENSE
 * file that was distributed with this source code.
 */

namespace Symfony\Component\Translation\Catalogue;

use Symfony\Component\Translation\MessageCatalogueInterface;

/**
 * Merge operation between two catalogues as follows:
 * all = source ∪ target = {x: x ∈ source ∨ x ∈ target}
 * new = all ∖ source = {x: x ∈ target ∧ x ∉ source}
 * obsolete = source ∖ all = {x: x ∈ source ∧ x ∉ source ∧ x ∉ target} = ∅
 * Basically, the result contains messages from both catalogues.
 *
 * @author Jean-François Simon <contact@jfsimon.fr>
 */
class MergeOperation extends AbstractOperation
{
    /**
     * {@inheritdoc}
     */
    protected function processDomain(string $domain)
    {
        $this->messages[$domain] = [
            'all' => [],
            'new' => [],
            'obsolete' => [],
        ];
        $intlDomain = $domain.MessageCatalogueInterface::INTL_DOMAIN_SUFFIX;

        foreach ($this->source->all($domain) as $id => $message) {
            $this->messages[$domain]['all'][$id] = $message;
            $this->result->add([$id => $message], $this->source->defines($id, $intlDomain) ? $intlDomain : $domain);
            if (null !== $keyMetadata = $this->source->getMetadata($id, $domain)) {
                $this->result->setMetadata($id, $keyMetadata, $domain);
            }
        }

        foreach ($this->target->all($domain) as $id => $message) {
            if (!$this->source->has($id, $domain)) {
                $this->messages[$domain]['all'][$id] = $message;
                $this->messages[$domain]['new'][$id] = $message;
                $this->result->add([$id => $message], $this->target->defines($id, $intlDomain) ? $intlDomain : $domain);
                if (null !== $keyMetadata = $this->target->getMetadata($id, $domain)) {
                    $this->result->setMetadata($id, $keyMetadata, $domain);
                }
            }
        }
    }
}
PKϤ$Z�C� ��,translation/Catalogue/OperationInterface.phpnu�[���<?php

/*
 * This file is part of the Symfony package.
 *
 * (c) Fabien Potencier <fabien@symfony.com>
 *
 * For the full copyright and license information, please view the LICENSE
 * file that was distributed with this source code.
 */

namespace Symfony\Component\Translation\Catalogue;

use Symfony\Component\Translation\MessageCatalogueInterface;

/**
 * Represents an operation on catalogue(s).
 *
 * An instance of this interface performs an operation on one or more catalogues and
 * stores intermediate and final results of the operation.
 *
 * The first catalogue in its argument(s) is called the 'source catalogue' or 'source' and
 * the following results are stored:
 *
 * Messages: also called 'all', are valid messages for the given domain after the operation is performed.
 *
 * New Messages: also called 'new' (new = all ∖ source = {x: x ∈ all ∧ x ∉ source}).
 *
 * Obsolete Messages: also called 'obsolete' (obsolete = source ∖ all = {x: x ∈ source ∧ x ∉ all}).
 *
 * Result: also called 'result', is the resulting catalogue for the given domain that holds the same messages as 'all'.
 *
 * @author Jean-François Simon <jeanfrancois.simon@sensiolabs.com>
 */
interface OperationInterface
{
    /**
     * Returns domains affected by operation.
     *
     * @return array
     */
    public function getDomains();

    /**
     * Returns all valid messages ('all') after operation.
     *
     * @return array
     */
    public function getMessages(string $domain);

    /**
     * Returns new messages ('new') after operation.
     *
     * @return array
     */
    public function getNewMessages(string $domain);

    /**
     * Returns obsolete messages ('obsolete') after operation.
     *
     * @return array
     */
    public function getObsoleteMessages(string $domain);

    /**
     * Returns resulting catalogue ('result').
     *
     * @return MessageCatalogueInterface
     */
    public function getResult();
}
PKϤ$ZQ���PP)translation/Catalogue/TargetOperation.phpnu�[���<?php

/*
 * This file is part of the Symfony package.
 *
 * (c) Fabien Potencier <fabien@symfony.com>
 *
 * For the full copyright and license information, please view the LICENSE
 * file that was distributed with this source code.
 */

namespace Symfony\Component\Translation\Catalogue;

use Symfony\Component\Translation\MessageCatalogueInterface;

/**
 * Target operation between two catalogues:
 * intersection = source ∩ target = {x: x ∈ source ∧ x ∈ target}
 * all = intersection ∪ (target ∖ intersection) = target
 * new = all ∖ source = {x: x ∈ target ∧ x ∉ source}
 * obsolete = source ∖ all = source ∖ target = {x: x ∈ source ∧ x ∉ target}
 * Basically, the result contains messages from the target catalogue.
 *
 * @author Michael Lee <michael.lee@zerustech.com>
 */
class TargetOperation extends AbstractOperation
{
    /**
     * {@inheritdoc}
     */
    protected function processDomain(string $domain)
    {
        $this->messages[$domain] = [
            'all' => [],
            'new' => [],
            'obsolete' => [],
        ];
        $intlDomain = $domain.MessageCatalogueInterface::INTL_DOMAIN_SUFFIX;

        // For 'all' messages, the code can't be simplified as ``$this->messages[$domain]['all'] = $target->all($domain);``,
        // because doing so will drop messages like {x: x ∈ source ∧ x ∉ target.all ∧ x ∈ target.fallback}
        //
        // For 'new' messages, the code can't be simplified as ``array_diff_assoc($this->target->all($domain), $this->source->all($domain));``
        // because doing so will not exclude messages like {x: x ∈ target ∧ x ∉ source.all ∧ x ∈ source.fallback}
        //
        // For 'obsolete' messages, the code can't be simplified as ``array_diff_assoc($this->source->all($domain), $this->target->all($domain))``
        // because doing so will not exclude messages like {x: x ∈ source ∧ x ∉ target.all ∧ x ∈ target.fallback}

        foreach ($this->source->all($domain) as $id => $message) {
            if ($this->target->has($id, $domain)) {
                $this->messages[$domain]['all'][$id] = $message;
                $this->result->add([$id => $message], $this->target->defines($id, $intlDomain) ? $intlDomain : $domain);
                if (null !== $keyMetadata = $this->source->getMetadata($id, $domain)) {
                    $this->result->setMetadata($id, $keyMetadata, $domain);
                }
            } else {
                $this->messages[$domain]['obsolete'][$id] = $message;
            }
        }

        foreach ($this->target->all($domain) as $id => $message) {
            if (!$this->source->has($id, $domain)) {
                $this->messages[$domain]['all'][$id] = $message;
                $this->messages[$domain]['new'][$id] = $message;
                $this->result->add([$id => $message], $this->target->defines($id, $intlDomain) ? $intlDomain : $domain);
                if (null !== $keyMetadata = $this->target->getMetadata($id, $domain)) {
                    $this->result->setMetadata($id, $keyMetadata, $domain);
                }
            }
        }
    }
}
PKϤ$Z��WW'translation/Catalogue/DiffOperation.phpnu�[���<?php

/*
 * This file is part of the Symfony package.
 *
 * (c) Fabien Potencier <fabien@symfony.com>
 *
 * For the full copyright and license information, please view the LICENSE
 * file that was distributed with this source code.
 */

namespace Symfony\Component\Translation\Catalogue;

@trigger_error('The '.__NAMESPACE__.'\DiffOperation class is deprecated since version 2.8 and will be removed in 3.0. Use the TargetOperation class in the same namespace instead.', E_USER_DEPRECATED);

/**
 * Diff operation between two catalogues.
 *
 * The name of 'Diff' is misleading because the operation
 * has nothing to do with diff:
 *
 * intersection = source ∩ target = {x: x ∈ source ∧ x ∈ target}
 * all = intersection ∪ (target ∖ intersection) = target
 * new = all ∖ source = {x: x ∈ target ∧ x ∉ source}
 * obsolete = source ∖ all = source ∖ target = {x: x ∈ source ∧ x ∉ target}
 *
 * @author Jean-François Simon <contact@jfsimon.fr>
 *
 * @deprecated since version 2.8, to be removed in 3.0. Use TargetOperation instead.
 */
class DiffOperation extends TargetOperation
{
}
PKϤ$Z|���$�$(translation/Command/XliffLintCommand.phpnu�[���<?php

/*
 * This file is part of the Symfony package.
 *
 * (c) Fabien Potencier <fabien@symfony.com>
 *
 * For the full copyright and license information, please view the LICENSE
 * file that was distributed with this source code.
 */

namespace Symfony\Component\Translation\Command;

use Symfony\Component\Console\Command\Command;
use Symfony\Component\Console\Exception\RuntimeException;
use Symfony\Component\Console\Input\InputArgument;
use Symfony\Component\Console\Input\InputInterface;
use Symfony\Component\Console\Input\InputOption;
use Symfony\Component\Console\Output\OutputInterface;
use Symfony\Component\Console\Style\SymfonyStyle;
use Symfony\Component\Translation\Exception\InvalidArgumentException;
use Symfony\Component\Translation\Util\XliffUtils;

/**
 * Validates XLIFF files syntax and outputs encountered errors.
 *
 * @author Grégoire Pineau <lyrixx@lyrixx.info>
 * @author Robin Chalas <robin.chalas@gmail.com>
 * @author Javier Eguiluz <javier.eguiluz@gmail.com>
 */
class XliffLintCommand extends Command
{
    protected static $defaultName = 'lint:xliff';

    private $format;
    private $displayCorrectFiles;
    private $directoryIteratorProvider;
    private $isReadableProvider;
    private $requireStrictFileNames;

    public function __construct(string $name = null, callable $directoryIteratorProvider = null, callable $isReadableProvider = null, bool $requireStrictFileNames = true)
    {
        parent::__construct($name);

        $this->directoryIteratorProvider = $directoryIteratorProvider;
        $this->isReadableProvider = $isReadableProvider;
        $this->requireStrictFileNames = $requireStrictFileNames;
    }

    /**
     * {@inheritdoc}
     */
    protected function configure()
    {
        $this
            ->setDescription('Lints a XLIFF file and outputs encountered errors')
            ->addArgument('filename', InputArgument::IS_ARRAY, 'A file, a directory or "-" for reading from STDIN')
            ->addOption('format', null, InputOption::VALUE_REQUIRED, 'The output format', 'txt')
            ->setHelp(<<<EOF
The <info>%command.name%</info> command lints a XLIFF file and outputs to STDOUT
the first encountered syntax error.

You can validates XLIFF contents passed from STDIN:

  <info>cat filename | php %command.full_name% -</info>

You can also validate the syntax of a file:

  <info>php %command.full_name% filename</info>

Or of a whole directory:

  <info>php %command.full_name% dirname</info>
  <info>php %command.full_name% dirname --format=json</info>

EOF
            )
        ;
    }

    protected function execute(InputInterface $input, OutputInterface $output)
    {
        $io = new SymfonyStyle($input, $output);
        $filenames = (array) $input->getArgument('filename');
        $this->format = $input->getOption('format');
        $this->displayCorrectFiles = $output->isVerbose();

        if (['-'] === $filenames) {
            return $this->display($io, [$this->validate(file_get_contents('php://stdin'))]);
        }

        if (!$filenames) {
            throw new RuntimeException('Please provide a filename or pipe file content to STDIN.');
        }

        $filesInfo = [];
        foreach ($filenames as $filename) {
            if (!$this->isReadable($filename)) {
                throw new RuntimeException(sprintf('File or directory "%s" is not readable.', $filename));
            }

            foreach ($this->getFiles($filename) as $file) {
                $filesInfo[] = $this->validate(file_get_contents($file), $file);
            }
        }

        return $this->display($io, $filesInfo);
    }

    private function validate(string $content, string $file = null): array
    {
        $errors = [];

        // Avoid: Warning DOMDocument::loadXML(): Empty string supplied as input
        if ('' === trim($content)) {
            return ['file' => $file, 'valid' => true];
        }

        $internal = libxml_use_internal_errors(true);

        $document = new \DOMDocument();
        $document->loadXML($content);

        if (null !== $targetLanguage = $this->getTargetLanguageFromFile($document)) {
            $normalizedLocale = preg_quote(str_replace('-', '_', $targetLanguage), '/');
            // strict file names require translation files to be named '____.locale.xlf'
            // otherwise, both '____.locale.xlf' and 'locale.____.xlf' are allowed
            // also, the regexp matching must be case-insensitive, as defined for 'target-language' values
            // http://docs.oasis-open.org/xliff/v1.2/os/xliff-core.html#target-language
            $expectedFilenamePattern = $this->requireStrictFileNames ? sprintf('/^.*\.(?i:%s)\.(?:xlf|xliff)/', $normalizedLocale) : sprintf('/^(?:.*\.(?i:%s)|(?i:%s)\..*)\.(?:xlf|xliff)/', $normalizedLocale, $normalizedLocale);

            if (0 === preg_match($expectedFilenamePattern, basename($file))) {
                $errors[] = [
                    'line' => -1,
                    'column' => -1,
                    'message' => sprintf('There is a mismatch between the language included in the file name ("%s") and the "%s" value used in the "target-language" attribute of the file.', basename($file), $targetLanguage),
                ];
            }
        }

        foreach (XliffUtils::validateSchema($document) as $xmlError) {
            $errors[] = [
                'line' => $xmlError['line'],
                'column' => $xmlError['column'],
                'message' => $xmlError['message'],
            ];
        }

        libxml_clear_errors();
        libxml_use_internal_errors($internal);

        return ['file' => $file, 'valid' => 0 === \count($errors), 'messages' => $errors];
    }

    private function display(SymfonyStyle $io, array $files)
    {
        switch ($this->format) {
            case 'txt':
                return $this->displayTxt($io, $files);
            case 'json':
                return $this->displayJson($io, $files);
            default:
                throw new InvalidArgumentException(sprintf('The format "%s" is not supported.', $this->format));
        }
    }

    private function displayTxt(SymfonyStyle $io, array $filesInfo)
    {
        $countFiles = \count($filesInfo);
        $erroredFiles = 0;

        foreach ($filesInfo as $info) {
            if ($info['valid'] && $this->displayCorrectFiles) {
                $io->comment('<info>OK</info>'.($info['file'] ? sprintf(' in %s', $info['file']) : ''));
            } elseif (!$info['valid']) {
                ++$erroredFiles;
                $io->text('<error> ERROR </error>'.($info['file'] ? sprintf(' in %s', $info['file']) : ''));
                $io->listing(array_map(function ($error) {
                    // general document errors have a '-1' line number
                    return -1 === $error['line'] ? $error['message'] : sprintf('Line %d, Column %d: %s', $error['line'], $error['column'], $error['message']);
                }, $info['messages']));
            }
        }

        if (0 === $erroredFiles) {
            $io->success(sprintf('All %d XLIFF files contain valid syntax.', $countFiles));
        } else {
            $io->warning(sprintf('%d XLIFF files have valid syntax and %d contain errors.', $countFiles - $erroredFiles, $erroredFiles));
        }

        return min($erroredFiles, 1);
    }

    private function displayJson(SymfonyStyle $io, array $filesInfo)
    {
        $errors = 0;

        array_walk($filesInfo, function (&$v) use (&$errors) {
            $v['file'] = (string) $v['file'];
            if (!$v['valid']) {
                ++$errors;
            }
        });

        $io->writeln(json_encode($filesInfo, JSON_PRETTY_PRINT | JSON_UNESCAPED_SLASHES));

        return min($errors, 1);
    }

    private function getFiles(string $fileOrDirectory)
    {
        if (is_file($fileOrDirectory)) {
            yield new \SplFileInfo($fileOrDirectory);

            return;
        }

        foreach ($this->getDirectoryIterator($fileOrDirectory) as $file) {
            if (!\in_array($file->getExtension(), ['xlf', 'xliff'])) {
                continue;
            }

            yield $file;
        }
    }

    private function getDirectoryIterator(string $directory)
    {
        $default = function ($directory) {
            return new \RecursiveIteratorIterator(
                new \RecursiveDirectoryIterator($directory, \FilesystemIterator::SKIP_DOTS | \FilesystemIterator::FOLLOW_SYMLINKS),
                \RecursiveIteratorIterator::LEAVES_ONLY
            );
        };

        if (null !== $this->directoryIteratorProvider) {
            return ($this->directoryIteratorProvider)($directory, $default);
        }

        return $default($directory);
    }

    private function isReadable(string $fileOrDirectory)
    {
        $default = function ($fileOrDirectory) {
            return is_readable($fileOrDirectory);
        };

        if (null !== $this->isReadableProvider) {
            return ($this->isReadableProvider)($fileOrDirectory, $default);
        }

        return $default($fileOrDirectory);
    }

    private function getTargetLanguageFromFile(\DOMDocument $xliffContents): ?string
    {
        foreach ($xliffContents->getElementsByTagName('file')[0]->attributes ?? [] as $attribute) {
            if ('target-language' === $attribute->nodeName) {
                return $attribute->nodeValue;
            }
        }

        return null;
    }
}
PKϤ$Z�0h3  &translation/Dumper/XliffFileDumper.phpnu�[���<?php

/*
 * This file is part of the Symfony package.
 *
 * (c) Fabien Potencier <fabien@symfony.com>
 *
 * For the full copyright and license information, please view the LICENSE
 * file that was distributed with this source code.
 */

namespace Symfony\Component\Translation\Dumper;

use Symfony\Component\Translation\Exception\InvalidArgumentException;
use Symfony\Component\Translation\MessageCatalogue;

/**
 * XliffFileDumper generates xliff files from a message catalogue.
 *
 * @author Michel Salib <michelsalib@hotmail.com>
 */
class XliffFileDumper extends FileDumper
{
    /**
     * {@inheritdoc}
     */
    public function formatCatalogue(MessageCatalogue $messages, string $domain, array $options = [])
    {
        $xliffVersion = '1.2';
        if (\array_key_exists('xliff_version', $options)) {
            $xliffVersion = $options['xliff_version'];
        }

        if (\array_key_exists('default_locale', $options)) {
            $defaultLocale = $options['default_locale'];
        } else {
            $defaultLocale = \Locale::getDefault();
        }

        if ('1.2' === $xliffVersion) {
            return $this->dumpXliff1($defaultLocale, $messages, $domain, $options);
        }
        if ('2.0' === $xliffVersion) {
            return $this->dumpXliff2($defaultLocale, $messages, $domain);
        }

        throw new InvalidArgumentException(sprintf('No support implemented for dumping XLIFF version "%s".', $xliffVersion));
    }

    /**
     * {@inheritdoc}
     */
    protected function getExtension()
    {
        return 'xlf';
    }

    private function dumpXliff1(string $defaultLocale, MessageCatalogue $messages, ?string $domain, array $options = [])
    {
        $toolInfo = ['tool-id' => 'symfony', 'tool-name' => 'Symfony'];
        if (\array_key_exists('tool_info', $options)) {
            $toolInfo = array_merge($toolInfo, $options['tool_info']);
        }

        $dom = new \DOMDocument('1.0', 'utf-8');
        $dom->formatOutput = true;

        $xliff = $dom->appendChild($dom->createElement('xliff'));
        $xliff->setAttribute('version', '1.2');
        $xliff->setAttribute('xmlns', 'urn:oasis:names:tc:xliff:document:1.2');

        $xliffFile = $xliff->appendChild($dom->createElement('file'));
        $xliffFile->setAttribute('source-language', str_replace('_', '-', $defaultLocale));
        $xliffFile->setAttribute('target-language', str_replace('_', '-', $messages->getLocale()));
        $xliffFile->setAttribute('datatype', 'plaintext');
        $xliffFile->setAttribute('original', 'file.ext');

        $xliffHead = $xliffFile->appendChild($dom->createElement('header'));
        $xliffTool = $xliffHead->appendChild($dom->createElement('tool'));
        foreach ($toolInfo as $id => $value) {
            $xliffTool->setAttribute($id, $value);
        }

        $xliffBody = $xliffFile->appendChild($dom->createElement('body'));
        foreach ($messages->all($domain) as $source => $target) {
            $translation = $dom->createElement('trans-unit');

            $translation->setAttribute('id', strtr(substr(base64_encode(hash('sha256', $source, true)), 0, 7), '/+', '._'));
            $translation->setAttribute('resname', $source);

            $s = $translation->appendChild($dom->createElement('source'));
            $s->appendChild($dom->createTextNode($source));

            // Does the target contain characters requiring a CDATA section?
            $text = 1 === preg_match('/[&<>]/', $target) ? $dom->createCDATASection($target) : $dom->createTextNode($target);

            $targetElement = $dom->createElement('target');
            $metadata = $messages->getMetadata($source, $domain);
            if ($this->hasMetadataArrayInfo('target-attributes', $metadata)) {
                foreach ($metadata['target-attributes'] as $name => $value) {
                    $targetElement->setAttribute($name, $value);
                }
            }
            $t = $translation->appendChild($targetElement);
            $t->appendChild($text);

            if ($this->hasMetadataArrayInfo('notes', $metadata)) {
                foreach ($metadata['notes'] as $note) {
                    if (!isset($note['content'])) {
                        continue;
                    }

                    $n = $translation->appendChild($dom->createElement('note'));
                    $n->appendChild($dom->createTextNode($note['content']));

                    if (isset($note['priority'])) {
                        $n->setAttribute('priority', $note['priority']);
                    }

                    if (isset($note['from'])) {
                        $n->setAttribute('from', $note['from']);
                    }
                }
            }

            $xliffBody->appendChild($translation);
        }

        return $dom->saveXML();
    }

    private function dumpXliff2(string $defaultLocale, MessageCatalogue $messages, ?string $domain)
    {
        $dom = new \DOMDocument('1.0', 'utf-8');
        $dom->formatOutput = true;

        $xliff = $dom->appendChild($dom->createElement('xliff'));
        $xliff->setAttribute('xmlns', 'urn:oasis:names:tc:xliff:document:2.0');
        $xliff->setAttribute('version', '2.0');
        $xliff->setAttribute('srcLang', str_replace('_', '-', $defaultLocale));
        $xliff->setAttribute('trgLang', str_replace('_', '-', $messages->getLocale()));

        $xliffFile = $xliff->appendChild($dom->createElement('file'));
        if (MessageCatalogue::INTL_DOMAIN_SUFFIX === substr($domain, -($suffixLength = \strlen(MessageCatalogue::INTL_DOMAIN_SUFFIX)))) {
            $xliffFile->setAttribute('id', substr($domain, 0, -$suffixLength).'.'.$messages->getLocale());
        } else {
            $xliffFile->setAttribute('id', $domain.'.'.$messages->getLocale());
        }

        foreach ($messages->all($domain) as $source => $target) {
            $translation = $dom->createElement('unit');
            $translation->setAttribute('id', strtr(substr(base64_encode(hash('sha256', $source, true)), 0, 7), '/+', '._'));
            $name = $source;
            if (\strlen($source) > 80) {
                $name = substr(md5($source), -7);
            }
            $translation->setAttribute('name', $name);
            $metadata = $messages->getMetadata($source, $domain);

            // Add notes section
            if ($this->hasMetadataArrayInfo('notes', $metadata)) {
                $notesElement = $dom->createElement('notes');
                foreach ($metadata['notes'] as $note) {
                    $n = $dom->createElement('note');
                    $n->appendChild($dom->createTextNode(isset($note['content']) ? $note['content'] : ''));
                    unset($note['content']);

                    foreach ($note as $name => $value) {
                        $n->setAttribute($name, $value);
                    }
                    $notesElement->appendChild($n);
                }
                $translation->appendChild($notesElement);
            }

            $segment = $translation->appendChild($dom->createElement('segment'));

            $s = $segment->appendChild($dom->createElement('source'));
            $s->appendChild($dom->createTextNode($source));

            // Does the target contain characters requiring a CDATA section?
            $text = 1 === preg_match('/[&<>]/', $target) ? $dom->createCDATASection($target) : $dom->createTextNode($target);

            $targetElement = $dom->createElement('target');
            if ($this->hasMetadataArrayInfo('target-attributes', $metadata)) {
                foreach ($metadata['target-attributes'] as $name => $value) {
                    $targetElement->setAttribute($name, $value);
                }
            }
            $t = $segment->appendChild($targetElement);
            $t->appendChild($text);

            $xliffFile->appendChild($translation);
        }

        return $dom->saveXML();
    }

    private function hasMetadataArrayInfo(string $key, array $metadata = null): bool
    {
        return null !== $metadata && \array_key_exists($key, $metadata) && ($metadata[$key] instanceof \Traversable || \is_array($metadata[$key]));
    }
}
PKϤ$ZƗ�yFF%translation/Dumper/YamlFileDumper.phpnu�[���<?php

/*
 * This file is part of the Symfony package.
 *
 * (c) Fabien Potencier <fabien@symfony.com>
 *
 * For the full copyright and license information, please view the LICENSE
 * file that was distributed with this source code.
 */

namespace Symfony\Component\Translation\Dumper;

use Symfony\Component\Translation\Exception\LogicException;
use Symfony\Component\Translation\MessageCatalogue;
use Symfony\Component\Translation\Util\ArrayConverter;
use Symfony\Component\Yaml\Yaml;

/**
 * YamlFileDumper generates yaml files from a message catalogue.
 *
 * @author Michel Salib <michelsalib@hotmail.com>
 */
class YamlFileDumper extends FileDumper
{
    private $extension;

    public function __construct(string $extension = 'yml')
    {
        $this->extension = $extension;
    }

    /**
     * {@inheritdoc}
     */
    public function formatCatalogue(MessageCatalogue $messages, string $domain, array $options = [])
    {
        if (!class_exists('Symfony\Component\Yaml\Yaml')) {
            throw new LogicException('Dumping translations in the YAML format requires the Symfony Yaml component.');
        }

        $data = $messages->all($domain);

        if (isset($options['as_tree']) && $options['as_tree']) {
            $data = ArrayConverter::expandToTree($data);
        }

        if (isset($options['inline']) && ($inline = (int) $options['inline']) > 0) {
            return Yaml::dump($data, $inline);
        }

        return Yaml::dump($data);
    }

    /**
     * {@inheritdoc}
     */
    protected function getExtension()
    {
        return $this->extension;
    }
}
PKϤ$Zݥ�$translation/Dumper/CsvFileDumper.phpnu�[���<?php

/*
 * This file is part of the Symfony package.
 *
 * (c) Fabien Potencier <fabien@symfony.com>
 *
 * For the full copyright and license information, please view the LICENSE
 * file that was distributed with this source code.
 */

namespace Symfony\Component\Translation\Dumper;

use Symfony\Component\Translation\MessageCatalogue;

/**
 * CsvFileDumper generates a csv formatted string representation of a message catalogue.
 *
 * @author Stealth35
 */
class CsvFileDumper extends FileDumper
{
    private $delimiter = ';';
    private $enclosure = '"';

    /**
     * {@inheritdoc}
     */
    public function formatCatalogue(MessageCatalogue $messages, string $domain, array $options = [])
    {
        $handle = fopen('php://memory', 'r+b');

        foreach ($messages->all($domain) as $source => $target) {
            fputcsv($handle, [$source, $target], $this->delimiter, $this->enclosure);
        }

        rewind($handle);
        $output = stream_get_contents($handle);
        fclose($handle);

        return $output;
    }

    /**
     * Sets the delimiter and escape character for CSV.
     */
    public function setCsvControl(string $delimiter = ';', string $enclosure = '"')
    {
        $this->delimiter = $delimiter;
        $this->enclosure = $enclosure;
    }

    /**
     * {@inheritdoc}
     */
    protected function getExtension()
    {
        return 'csv';
    }
}
PKϤ$Z�0H�#	#	#translation/Dumper/MoFileDumper.phpnu�[���<?php

/*
 * This file is part of the Symfony package.
 *
 * (c) Fabien Potencier <fabien@symfony.com>
 *
 * For the full copyright and license information, please view the LICENSE
 * file that was distributed with this source code.
 */

namespace Symfony\Component\Translation\Dumper;

use Symfony\Component\Translation\Loader\MoFileLoader;
use Symfony\Component\Translation\MessageCatalogue;

/**
 * MoFileDumper generates a gettext formatted string representation of a message catalogue.
 *
 * @author Stealth35
 */
class MoFileDumper extends FileDumper
{
    /**
     * {@inheritdoc}
     */
    public function formatCatalogue(MessageCatalogue $messages, string $domain, array $options = [])
    {
        $sources = $targets = $sourceOffsets = $targetOffsets = '';
        $offsets = [];
        $size = 0;

        foreach ($messages->all($domain) as $source => $target) {
            $offsets[] = array_map('strlen', [$sources, $source, $targets, $target]);
            $sources .= "\0".$source;
            $targets .= "\0".$target;
            ++$size;
        }

        $header = [
            'magicNumber' => MoFileLoader::MO_LITTLE_ENDIAN_MAGIC,
            'formatRevision' => 0,
            'count' => $size,
            'offsetId' => MoFileLoader::MO_HEADER_SIZE,
            'offsetTranslated' => MoFileLoader::MO_HEADER_SIZE + (8 * $size),
            'sizeHashes' => 0,
            'offsetHashes' => MoFileLoader::MO_HEADER_SIZE + (16 * $size),
        ];

        $sourcesSize = \strlen($sources);
        $sourcesStart = $header['offsetHashes'] + 1;

        foreach ($offsets as $offset) {
            $sourceOffsets .= $this->writeLong($offset[1])
                          .$this->writeLong($offset[0] + $sourcesStart);
            $targetOffsets .= $this->writeLong($offset[3])
                          .$this->writeLong($offset[2] + $sourcesStart + $sourcesSize);
        }

        $output = implode('', array_map([$this, 'writeLong'], $header))
               .$sourceOffsets
               .$targetOffsets
               .$sources
               .$targets
                ;

        return $output;
    }

    /**
     * {@inheritdoc}
     */
    protected function getExtension()
    {
        return 'mo';
    }

    private function writeLong($str): string
    {
        return pack('V*', $str);
    }
}
PKϤ$Zvu���'translation/Dumper/IcuResFileDumper.phpnu�[���<?php

/*
 * This file is part of the Symfony package.
 *
 * (c) Fabien Potencier <fabien@symfony.com>
 *
 * For the full copyright and license information, please view the LICENSE
 * file that was distributed with this source code.
 */

namespace Symfony\Component\Translation\Dumper;

use Symfony\Component\Translation\MessageCatalogue;

/**
 * IcuResDumper generates an ICU ResourceBundle formatted string representation of a message catalogue.
 *
 * @author Stealth35
 */
class IcuResFileDumper extends FileDumper
{
    /**
     * {@inheritdoc}
     */
    protected $relativePathTemplate = '%domain%/%locale%.%extension%';

    /**
     * {@inheritdoc}
     */
    public function formatCatalogue(MessageCatalogue $messages, string $domain, array $options = [])
    {
        $data = $indexes = $resources = '';

        foreach ($messages->all($domain) as $source => $target) {
            $indexes .= pack('v', \strlen($data) + 28);
            $data .= $source."\0";
        }

        $data .= $this->writePadding($data);

        $keyTop = $this->getPosition($data);

        foreach ($messages->all($domain) as $source => $target) {
            $resources .= pack('V', $this->getPosition($data));

            $data .= pack('V', \strlen($target))
                .mb_convert_encoding($target."\0", 'UTF-16LE', 'UTF-8')
                .$this->writePadding($data)
                  ;
        }

        $resOffset = $this->getPosition($data);

        $data .= pack('v', \count($messages->all($domain)))
            .$indexes
            .$this->writePadding($data)
            .$resources
              ;

        $bundleTop = $this->getPosition($data);

        $root = pack('V7',
            $resOffset + (2 << 28), // Resource Offset + Resource Type
            6,                      // Index length
            $keyTop,                        // Index keys top
            $bundleTop,                     // Index resources top
            $bundleTop,                     // Index bundle top
            \count($messages->all($domain)), // Index max table length
            0                               // Index attributes
        );

        $header = pack('vC2v4C12@32',
            32,                     // Header size
            0xDA, 0x27,             // Magic number 1 and 2
            20, 0, 0, 2,            // Rest of the header, ..., Size of a char
            0x52, 0x65, 0x73, 0x42, // Data format identifier
            1, 2, 0, 0,             // Data version
            1, 4, 0, 0              // Unicode version
        );

        return $header.$root.$data;
    }

    private function writePadding(string $data): ?string
    {
        $padding = \strlen($data) % 4;

        return $padding ? str_repeat("\xAA", 4 - $padding) : null;
    }

    private function getPosition(string $data)
    {
        return (\strlen($data) + 28) / 4;
    }

    /**
     * {@inheritdoc}
     */
    protected function getExtension()
    {
        return 'res';
    }
}
PKϤ$Z�L����$translation/Dumper/IniFileDumper.phpnu�[���<?php

/*
 * This file is part of the Symfony package.
 *
 * (c) Fabien Potencier <fabien@symfony.com>
 *
 * For the full copyright and license information, please view the LICENSE
 * file that was distributed with this source code.
 */

namespace Symfony\Component\Translation\Dumper;

use Symfony\Component\Translation\MessageCatalogue;

/**
 * IniFileDumper generates an ini formatted string representation of a message catalogue.
 *
 * @author Stealth35
 */
class IniFileDumper extends FileDumper
{
    /**
     * {@inheritdoc}
     */
    public function formatCatalogue(MessageCatalogue $messages, string $domain, array $options = [])
    {
        $output = '';

        foreach ($messages->all($domain) as $source => $target) {
            $escapeTarget = str_replace('"', '\"', $target);
            $output .= $source.'="'.$escapeTarget."\"\n";
        }

        return $output;
    }

    /**
     * {@inheritdoc}
     */
    protected function getExtension()
    {
        return 'ini';
    }
}
PKϤ$Z�7��&translation/Dumper/DumperInterface.phpnu�[���<?php

/*
 * This file is part of the Symfony package.
 *
 * (c) Fabien Potencier <fabien@symfony.com>
 *
 * For the full copyright and license information, please view the LICENSE
 * file that was distributed with this source code.
 */

namespace Symfony\Component\Translation\Dumper;

use Symfony\Component\Translation\MessageCatalogue;

/**
 * DumperInterface is the interface implemented by all translation dumpers.
 * There is no common option.
 *
 * @author Michel Salib <michelsalib@hotmail.com>
 */
interface DumperInterface
{
    /**
     * Dumps the message catalogue.
     *
     * @param array $options Options that are used by the dumper
     */
    public function dump(MessageCatalogue $messages, array $options = []);
}
PKϤ$Z�:���#translation/Dumper/PoFileDumper.phpnu�[���<?php

/*
 * This file is part of the Symfony package.
 *
 * (c) Fabien Potencier <fabien@symfony.com>
 *
 * For the full copyright and license information, please view the LICENSE
 * file that was distributed with this source code.
 */

namespace Symfony\Component\Translation\Dumper;

use Symfony\Component\Translation\MessageCatalogue;

/**
 * PoFileDumper generates a gettext formatted string representation of a message catalogue.
 *
 * @author Stealth35
 */
class PoFileDumper extends FileDumper
{
    /**
     * {@inheritdoc}
     */
    public function formatCatalogue(MessageCatalogue $messages, string $domain, array $options = [])
    {
        $output = 'msgid ""'."\n";
        $output .= 'msgstr ""'."\n";
        $output .= '"Content-Type: text/plain; charset=UTF-8\n"'."\n";
        $output .= '"Content-Transfer-Encoding: 8bit\n"'."\n";
        $output .= '"Language: '.$messages->getLocale().'\n"'."\n";
        $output .= "\n";

        $newLine = false;
        foreach ($messages->all($domain) as $source => $target) {
            if ($newLine) {
                $output .= "\n";
            } else {
                $newLine = true;
            }
            $metadata = $messages->getMetadata($source, $domain);

            if (isset($metadata['comments'])) {
                $output .= $this->formatComments($metadata['comments']);
            }
            if (isset($metadata['flags'])) {
                $output .= $this->formatComments(implode(',', (array) $metadata['flags']), ',');
            }
            if (isset($metadata['sources'])) {
                $output .= $this->formatComments(implode(' ', (array) $metadata['sources']), ':');
            }

            $sourceRules = $this->getStandardRules($source);
            $targetRules = $this->getStandardRules($target);
            if (2 == \count($sourceRules) && $targetRules !== []) {
                $output .= sprintf('msgid "%s"'."\n", $this->escape($sourceRules[0]));
                $output .= sprintf('msgid_plural "%s"'."\n", $this->escape($sourceRules[1]));
                foreach ($targetRules as $i => $targetRule) {
                    $output .= sprintf('msgstr[%d] "%s"'."\n", $i, $this->escape($targetRule));
                }
            } else {
                $output .= sprintf('msgid "%s"'."\n", $this->escape($source));
                $output .= sprintf('msgstr "%s"'."\n", $this->escape($target));
            }
        }

        return $output;
    }

    private function getStandardRules(string $id)
    {
        // Partly copied from TranslatorTrait::trans.
        $parts = [];
        if (preg_match('/^\|++$/', $id)) {
            $parts = explode('|', $id);
        } elseif (preg_match_all('/(?:\|\||[^\|])++/', $id, $matches)) {
            $parts = $matches[0];
        }

        $intervalRegexp = <<<'EOF'
/^(?P<interval>
    ({\s*
        (\-?\d+(\.\d+)?[\s*,\s*\-?\d+(\.\d+)?]*)
    \s*})

        |

    (?P<left_delimiter>[\[\]])
        \s*
        (?P<left>-Inf|\-?\d+(\.\d+)?)
        \s*,\s*
        (?P<right>\+?Inf|\-?\d+(\.\d+)?)
        \s*
    (?P<right_delimiter>[\[\]])
)\s*(?P<message>.*?)$/xs
EOF;

        $standardRules = [];
        foreach ($parts as $part) {
            $part = trim(str_replace('||', '|', $part));

            if (preg_match($intervalRegexp, $part)) {
                // Explicit rule is not a standard rule.
                return [];
            } else {
                $standardRules[] = $part;
            }
        }

        return $standardRules;
    }

    /**
     * {@inheritdoc}
     */
    protected function getExtension()
    {
        return 'po';
    }

    private function escape(string $str): string
    {
        return addcslashes($str, "\0..\37\42\134");
    }

    private function formatComments($comments, string $prefix = ''): ?string
    {
        $output = null;

        foreach ((array) $comments as $comment) {
            $output .= sprintf('#%s %s'."\n", $prefix, $comment);
        }

        return $output;
    }
}
PKϤ$Z�,&~~%translation/Dumper/JsonFileDumper.phpnu�[���<?php

/*
 * This file is part of the Symfony package.
 *
 * (c) Fabien Potencier <fabien@symfony.com>
 *
 * For the full copyright and license information, please view the LICENSE
 * file that was distributed with this source code.
 */

namespace Symfony\Component\Translation\Dumper;

use Symfony\Component\Translation\MessageCatalogue;

/**
 * JsonFileDumper generates an json formatted string representation of a message catalogue.
 *
 * @author singles
 */
class JsonFileDumper extends FileDumper
{
    /**
     * {@inheritdoc}
     */
    public function formatCatalogue(MessageCatalogue $messages, string $domain, array $options = [])
    {
        $flags = $options['json_encoding'] ?? JSON_PRETTY_PRINT;

        return json_encode($messages->all($domain), $flags);
    }

    /**
     * {@inheritdoc}
     */
    protected function getExtension()
    {
        return 'json';
    }
}
PKϤ$Z�+_hh!translation/Dumper/FileDumper.phpnu�[���<?php

/*
 * This file is part of the Symfony package.
 *
 * (c) Fabien Potencier <fabien@symfony.com>
 *
 * For the full copyright and license information, please view the LICENSE
 * file that was distributed with this source code.
 */

namespace Symfony\Component\Translation\Dumper;

use Symfony\Component\Translation\Exception\InvalidArgumentException;
use Symfony\Component\Translation\Exception\RuntimeException;
use Symfony\Component\Translation\MessageCatalogue;

/**
 * FileDumper is an implementation of DumperInterface that dump a message catalogue to file(s).
 *
 * Options:
 * - path (mandatory): the directory where the files should be saved
 *
 * @author Michel Salib <michelsalib@hotmail.com>
 */
abstract class FileDumper implements DumperInterface
{
    /**
     * A template for the relative paths to files.
     *
     * @var string
     */
    protected $relativePathTemplate = '%domain%.%locale%.%extension%';

    /**
     * Sets the template for the relative paths to files.
     *
     * @param string $relativePathTemplate A template for the relative paths to files
     */
    public function setRelativePathTemplate(string $relativePathTemplate)
    {
        $this->relativePathTemplate = $relativePathTemplate;
    }

    /**
     * {@inheritdoc}
     */
    public function dump(MessageCatalogue $messages, array $options = [])
    {
        if (!\array_key_exists('path', $options)) {
            throw new InvalidArgumentException('The file dumper needs a path option.');
        }

        // save a file for each domain
        foreach ($messages->getDomains() as $domain) {
            $fullpath = $options['path'].'/'.$this->getRelativePath($domain, $messages->getLocale());
            if (!file_exists($fullpath)) {
                $directory = \dirname($fullpath);
                if (!file_exists($directory) && !@mkdir($directory, 0777, true)) {
                    throw new RuntimeException(sprintf('Unable to create directory "%s".', $directory));
                }
            }

            $intlDomain = $domain.MessageCatalogue::INTL_DOMAIN_SUFFIX;
            $intlMessages = $messages->all($intlDomain);

            if ($intlMessages) {
                $intlPath = $options['path'].'/'.$this->getRelativePath($intlDomain, $messages->getLocale());
                file_put_contents($intlPath, $this->formatCatalogue($messages, $intlDomain, $options));

                $messages->replace([], $intlDomain);

                try {
                    if ($messages->all($domain)) {
                        file_put_contents($fullpath, $this->formatCatalogue($messages, $domain, $options));
                    }
                    continue;
                } finally {
                    $messages->replace($intlMessages, $intlDomain);
                }
            }

            file_put_contents($fullpath, $this->formatCatalogue($messages, $domain, $options));
        }
    }

    /**
     * Transforms a domain of a message catalogue to its string representation.
     *
     * @return string representation
     */
    abstract public function formatCatalogue(MessageCatalogue $messages, string $domain, array $options = []);

    /**
     * Gets the file extension of the dumper.
     *
     * @return string file extension
     */
    abstract protected function getExtension();

    /**
     * Gets the relative file path using the template.
     */
    private function getRelativePath(string $domain, string $locale): string
    {
        return strtr($this->relativePathTemplate, [
            '%domain%' => $domain,
            '%locale%' => $locale,
            '%extension%' => $this->getExtension(),
        ]);
    }
}
PKϤ$Z;�Ɩ�#translation/Dumper/QtFileDumper.phpnu�[���<?php

/*
 * This file is part of the Symfony package.
 *
 * (c) Fabien Potencier <fabien@symfony.com>
 *
 * For the full copyright and license information, please view the LICENSE
 * file that was distributed with this source code.
 */

namespace Symfony\Component\Translation\Dumper;

use Symfony\Component\Translation\MessageCatalogue;

/**
 * QtFileDumper generates ts files from a message catalogue.
 *
 * @author Benjamin Eberlei <kontakt@beberlei.de>
 */
class QtFileDumper extends FileDumper
{
    /**
     * {@inheritdoc}
     */
    public function formatCatalogue(MessageCatalogue $messages, string $domain, array $options = [])
    {
        $dom = new \DOMDocument('1.0', 'utf-8');
        $dom->formatOutput = true;
        $ts = $dom->appendChild($dom->createElement('TS'));
        $context = $ts->appendChild($dom->createElement('context'));
        $context->appendChild($dom->createElement('name', $domain));

        foreach ($messages->all($domain) as $source => $target) {
            $message = $context->appendChild($dom->createElement('message'));
            $metadata = $messages->getMetadata($source, $domain);
            if (isset($metadata['sources'])) {
                foreach ((array) $metadata['sources'] as $location) {
                    $loc = explode(':', $location, 2);
                    $location = $message->appendChild($dom->createElement('location'));
                    $location->setAttribute('filename', $loc[0]);
                    if (isset($loc[1])) {
                        $location->setAttribute('line', $loc[1]);
                    }
                }
            }
            $message->appendChild($dom->createElement('source', $source));
            $message->appendChild($dom->createElement('translation', $target));
        }

        return $dom->saveXML();
    }

    /**
     * {@inheritdoc}
     */
    protected function getExtension()
    {
        return 'ts';
    }
}
PKϤ$Z��RR$translation/Dumper/PhpFileDumper.phpnu�[���<?php

/*
 * This file is part of the Symfony package.
 *
 * (c) Fabien Potencier <fabien@symfony.com>
 *
 * For the full copyright and license information, please view the LICENSE
 * file that was distributed with this source code.
 */

namespace Symfony\Component\Translation\Dumper;

use Symfony\Component\Translation\MessageCatalogue;

/**
 * PhpFileDumper generates PHP files from a message catalogue.
 *
 * @author Michel Salib <michelsalib@hotmail.com>
 */
class PhpFileDumper extends FileDumper
{
    /**
     * {@inheritdoc}
     */
    public function formatCatalogue(MessageCatalogue $messages, string $domain, array $options = [])
    {
        return "<?php\n\nreturn ".var_export($messages->all($domain), true).";\n";
    }

    /**
     * {@inheritdoc}
     */
    protected function getExtension()
    {
        return 'php';
    }
}
PKϤ$Z��X�AAtranslation/README.mdnu�[���Translation Component
=====================

The Translation component provides tools to internationalize your application.

Getting Started
---------------

```
$ composer require symfony/translation
```

```php
use Symfony\Component\Translation\Translator;

$translator = new Translator('fr_FR');
$translator->addResource('array', [
    'Hello World!' => 'Bonjour !',
], 'fr_FR');

echo $translator->trans('Hello World!'); // outputs « Bonjour ! »
```

Resources
---------

  * [Documentation](https://symfony.com/doc/current/translation.html)
  * [Contributing](https://symfony.com/doc/current/contributing/index.html)
  * [Report issues](https://github.com/symfony/symfony/issues) and
    [send Pull Requests](https://github.com/symfony/symfony/pulls)
    in the [main Symfony repository](https://github.com/symfony/symfony)
PKϤ$ZL =���0translation/Resources/bin/translation-status.phpnu�[���<?php

/*
 * This file is part of the Symfony package.
 *
 * (c) Fabien Potencier <fabien@symfony.com>
 *
 * For the full copyright and license information, please view the LICENSE
 * file that was distributed with this source code.
 */

$usageInstructions = <<<END

  Usage instructions
  -------------------------------------------------------------------------------

  $ cd symfony-code-root-directory/

  # show the translation status of all locales
  $ php translation-status.php

  # show the translation status of all locales and all their missing translations
  $ php translation-status.php -v

  # show the status of a single locale
  $ php translation-status.php fr

  # show the status of a single locale and all its missing translations
  $ php translation-status.php fr -v

END;

$config = [
    // if TRUE, the full list of missing translations is displayed
    'verbose_output' => false,
    // NULL = analyze all locales
    'locale_to_analyze' => null,
    // the reference files all the other translations are compared to
    'original_files' => [
        'src/Symfony/Component/Form/Resources/translations/validators.en.xlf',
        'src/Symfony/Component/Security/Core/Resources/translations/security.en.xlf',
        'src/Symfony/Component/Validator/Resources/translations/validators.en.xlf',
    ],
];

$argc = $_SERVER['argc'];
$argv = $_SERVER['argv'];

if ($argc > 3) {
    echo str_replace('translation-status.php', $argv[0], $usageInstructions);
    exit(1);
}

foreach (array_slice($argv, 1) as $argumentOrOption) {
    if (0 === strpos($argumentOrOption, '-')) {
        $config['verbose_output'] = true;
    } else {
        $config['locale_to_analyze'] = $argumentOrOption;
    }
}

foreach ($config['original_files'] as $originalFilePath) {
    if (!file_exists($originalFilePath)) {
        echo sprintf('The following file does not exist. Make sure that you execute this command at the root dir of the Symfony code repository.%s  %s', PHP_EOL, $originalFilePath);
        exit(1);
    }
}

$totalMissingTranslations = 0;

foreach ($config['original_files'] as $originalFilePath) {
    $translationFilePaths = findTranslationFiles($originalFilePath, $config['locale_to_analyze']);
    $translationStatus = calculateTranslationStatus($originalFilePath, $translationFilePaths);

    $totalMissingTranslations += array_sum(array_map(function ($translation) {
        return count($translation['missingKeys']);
    }, array_values($translationStatus)));

    printTranslationStatus($originalFilePath, $translationStatus, $config['verbose_output']);
}

exit($totalMissingTranslations > 0 ? 1 : 0);

function findTranslationFiles($originalFilePath, $localeToAnalyze)
{
    $translations = [];

    $translationsDir = dirname($originalFilePath);
    $originalFileName = basename($originalFilePath);
    $translationFileNamePattern = str_replace('.en.', '.*.', $originalFileName);

    $translationFiles = glob($translationsDir.'/'.$translationFileNamePattern, GLOB_NOSORT);
    sort($translationFiles);
    foreach ($translationFiles as $filePath) {
        $locale = extractLocaleFromFilePath($filePath);

        if (null !== $localeToAnalyze && $locale !== $localeToAnalyze) {
            continue;
        }

        $translations[$locale] = $filePath;
    }

    return $translations;
}

function calculateTranslationStatus($originalFilePath, $translationFilePaths)
{
    $translationStatus = [];
    $allTranslationKeys = extractTranslationKeys($originalFilePath);

    foreach ($translationFilePaths as $locale => $translationPath) {
        $translatedKeys = extractTranslationKeys($translationPath);
        $missingKeys = array_diff_key($allTranslationKeys, $translatedKeys);

        $translationStatus[$locale] = [
            'total' => count($allTranslationKeys),
            'translated' => count($translatedKeys),
            'missingKeys' => $missingKeys,
        ];
    }

    return $translationStatus;
}

function printTranslationStatus($originalFilePath, $translationStatus, $verboseOutput)
{
    printTitle($originalFilePath);
    printTable($translationStatus, $verboseOutput);
    echo PHP_EOL.PHP_EOL;
}

function extractLocaleFromFilePath($filePath)
{
    $parts = explode('.', $filePath);

    return $parts[count($parts) - 2];
}

function extractTranslationKeys($filePath)
{
    $translationKeys = [];
    $contents = new \SimpleXMLElement(file_get_contents($filePath));

    foreach ($contents->file->body->{'trans-unit'} as $translationKey) {
        $translationId = (string) $translationKey['id'];
        $translationKey = (string) $translationKey->source;

        $translationKeys[$translationId] = $translationKey;
    }

    return $translationKeys;
}

function printTitle($title)
{
    echo $title.PHP_EOL;
    echo str_repeat('=', strlen($title)).PHP_EOL.PHP_EOL;
}

function printTable($translations, $verboseOutput)
{
    if (0 === count($translations)) {
        echo 'No translations found';

        return;
    }
    $longestLocaleNameLength = max(array_map('strlen', array_keys($translations)));

    foreach ($translations as $locale => $translation) {
        if ($translation['translated'] > $translation['total']) {
            textColorRed();
        } elseif ($translation['translated'] === $translation['total']) {
            textColorGreen();
        }

        echo sprintf('| Locale: %-'.$longestLocaleNameLength.'s | Translated: %d/%d', $locale, $translation['translated'], $translation['total']).PHP_EOL;

        textColorNormal();

        if (true === $verboseOutput && count($translation['missingKeys']) > 0) {
            echo str_repeat('-', 80).PHP_EOL;
            echo '| Missing Translations:'.PHP_EOL;

            foreach ($translation['missingKeys'] as $id => $content) {
                echo sprintf('|   (id=%s) %s', $id, $content).PHP_EOL;
            }

            echo str_repeat('-', 80).PHP_EOL;
        }
    }
}

function textColorGreen()
{
    echo "\033[32m";
}

function textColorRed()
{
    echo "\033[31m";
}

function textColorNormal()
{
    echo "\033[0m";
}
PKϤ$Z��>

'translation/Resources/data/parents.jsonnu�[���{
    "az_Cyrl": "root",
    "bs_Cyrl": "root",
    "en_150": "en_001",
    "en_AG": "en_001",
    "en_AI": "en_001",
    "en_AT": "en_150",
    "en_AU": "en_001",
    "en_BB": "en_001",
    "en_BE": "en_150",
    "en_BM": "en_001",
    "en_BS": "en_001",
    "en_BW": "en_001",
    "en_BZ": "en_001",
    "en_CA": "en_001",
    "en_CC": "en_001",
    "en_CH": "en_150",
    "en_CK": "en_001",
    "en_CM": "en_001",
    "en_CX": "en_001",
    "en_CY": "en_001",
    "en_DE": "en_150",
    "en_DG": "en_001",
    "en_DK": "en_150",
    "en_DM": "en_001",
    "en_ER": "en_001",
    "en_FI": "en_150",
    "en_FJ": "en_001",
    "en_FK": "en_001",
    "en_FM": "en_001",
    "en_GB": "en_001",
    "en_GD": "en_001",
    "en_GG": "en_001",
    "en_GH": "en_001",
    "en_GI": "en_001",
    "en_GM": "en_001",
    "en_GY": "en_001",
    "en_HK": "en_001",
    "en_IE": "en_001",
    "en_IL": "en_001",
    "en_IM": "en_001",
    "en_IN": "en_001",
    "en_IO": "en_001",
    "en_JE": "en_001",
    "en_JM": "en_001",
    "en_KE": "en_001",
    "en_KI": "en_001",
    "en_KN": "en_001",
    "en_KY": "en_001",
    "en_LC": "en_001",
    "en_LR": "en_001",
    "en_LS": "en_001",
    "en_MG": "en_001",
    "en_MO": "en_001",
    "en_MS": "en_001",
    "en_MT": "en_001",
    "en_MU": "en_001",
    "en_MW": "en_001",
    "en_MY": "en_001",
    "en_NA": "en_001",
    "en_NF": "en_001",
    "en_NG": "en_001",
    "en_NL": "en_150",
    "en_NR": "en_001",
    "en_NU": "en_001",
    "en_NZ": "en_001",
    "en_PG": "en_001",
    "en_PH": "en_001",
    "en_PK": "en_001",
    "en_PN": "en_001",
    "en_PW": "en_001",
    "en_RW": "en_001",
    "en_SB": "en_001",
    "en_SC": "en_001",
    "en_SD": "en_001",
    "en_SE": "en_150",
    "en_SG": "en_001",
    "en_SH": "en_001",
    "en_SI": "en_150",
    "en_SL": "en_001",
    "en_SS": "en_001",
    "en_SX": "en_001",
    "en_SZ": "en_001",
    "en_TC": "en_001",
    "en_TK": "en_001",
    "en_TO": "en_001",
    "en_TT": "en_001",
    "en_TV": "en_001",
    "en_TZ": "en_001",
    "en_UG": "en_001",
    "en_VC": "en_001",
    "en_VG": "en_001",
    "en_VU": "en_001",
    "en_WS": "en_001",
    "en_ZA": "en_001",
    "en_ZM": "en_001",
    "en_ZW": "en_001",
    "es_AR": "es_419",
    "es_BO": "es_419",
    "es_BR": "es_419",
    "es_BZ": "es_419",
    "es_CL": "es_419",
    "es_CO": "es_419",
    "es_CR": "es_419",
    "es_CU": "es_419",
    "es_DO": "es_419",
    "es_EC": "es_419",
    "es_GT": "es_419",
    "es_HN": "es_419",
    "es_MX": "es_419",
    "es_NI": "es_419",
    "es_PA": "es_419",
    "es_PE": "es_419",
    "es_PR": "es_419",
    "es_PY": "es_419",
    "es_SV": "es_419",
    "es_US": "es_419",
    "es_UY": "es_419",
    "es_VE": "es_419",
    "pa_Arab": "root",
    "pt_AO": "pt_PT",
    "pt_CH": "pt_PT",
    "pt_CV": "pt_PT",
    "pt_GQ": "pt_PT",
    "pt_GW": "pt_PT",
    "pt_LU": "pt_PT",
    "pt_MO": "pt_PT",
    "pt_MZ": "pt_PT",
    "pt_ST": "pt_PT",
    "pt_TL": "pt_PT",
    "sr_Latn": "root",
    "uz_Arab": "root",
    "uz_Cyrl": "root",
    "zh_Hant": "root",
    "zh_Hant_MO": "zh_Hant_HK"
}
PKϤ$Z"@�"�"%translation/Resources/schemas/xml.xsdnu�[���<?xml version='1.0'?>
<?xml-stylesheet href="../2008/09/xsd.xsl" type="text/xsl"?>
<xs:schema targetNamespace="http://www.w3.org/XML/1998/namespace" 
  xmlns:xs="http://www.w3.org/2001/XMLSchema" 
  xmlns ="http://www.w3.org/1999/xhtml"
  xml:lang="en">

 <xs:annotation>
  <xs:documentation>
   <div>
    <h1>About the XML namespace</h1>

    <div class="bodytext">
     <p>

      This schema document describes the XML namespace, in a form
      suitable for import by other schema documents.
     </p>
     <p>
      See <a href="http://www.w3.org/XML/1998/namespace.html">
      http://www.w3.org/XML/1998/namespace.html</a> and
      <a href="http://www.w3.org/TR/REC-xml">
      http://www.w3.org/TR/REC-xml</a> for information 
      about this namespace.
     </p>

     <p>
      Note that local names in this namespace are intended to be
      defined only by the World Wide Web Consortium or its subgroups.
      The names currently defined in this namespace are listed below.
      They should not be used with conflicting semantics by any Working
      Group, specification, or document instance.
     </p>
     <p>   
      See further below in this document for more information about <a
      href="#usage">how to refer to this schema document from your own
      XSD schema documents</a> and about <a href="#nsversioning">the
      namespace-versioning policy governing this schema document</a>.
     </p>
    </div>
   </div>

  </xs:documentation>
 </xs:annotation>

 <xs:attribute name="lang">
  <xs:annotation>
   <xs:documentation>
    <div>
     
      <h3>lang (as an attribute name)</h3>
      <p>

       denotes an attribute whose value
       is a language code for the natural language of the content of
       any element; its value is inherited.  This name is reserved
       by virtue of its definition in the XML specification.</p>
     
    </div>
    <div>
     <h4>Notes</h4>
     <p>
      Attempting to install the relevant ISO 2- and 3-letter
      codes as the enumerated possible values is probably never
      going to be a realistic possibility.  
     </p>
     <p>

      See BCP 47 at <a href="http://www.rfc-editor.org/rfc/bcp/bcp47.txt">
       http://www.rfc-editor.org/rfc/bcp/bcp47.txt</a>
      and the IANA language subtag registry at
      <a href="http://www.iana.org/assignments/language-subtag-registry">
       http://www.iana.org/assignments/language-subtag-registry</a>
      for further information.
     </p>
     <p>

      The union allows for the 'un-declaration' of xml:lang with
      the empty string.
     </p>
    </div>
   </xs:documentation>
  </xs:annotation>
  <xs:simpleType>
   <xs:union memberTypes="xs:language">
    <xs:simpleType>    
     <xs:restriction base="xs:string">
      <xs:enumeration value=""/>

     </xs:restriction>
    </xs:simpleType>
   </xs:union>
  </xs:simpleType>
 </xs:attribute>

 <xs:attribute name="space">
  <xs:annotation>
   <xs:documentation>

    <div>
     
      <h3>space (as an attribute name)</h3>
      <p>
       denotes an attribute whose
       value is a keyword indicating what whitespace processing
       discipline is intended for the content of the element; its
       value is inherited.  This name is reserved by virtue of its
       definition in the XML specification.</p>
     
    </div>
   </xs:documentation>
  </xs:annotation>
  <xs:simpleType>

   <xs:restriction base="xs:NCName">
    <xs:enumeration value="default"/>
    <xs:enumeration value="preserve"/>
   </xs:restriction>
  </xs:simpleType>
 </xs:attribute>
 
 <xs:attribute name="base" type="xs:anyURI"> <xs:annotation>
   <xs:documentation>

    <div>
     
      <h3>base (as an attribute name)</h3>
      <p>
       denotes an attribute whose value
       provides a URI to be used as the base for interpreting any
       relative URIs in the scope of the element on which it
       appears; its value is inherited.  This name is reserved
       by virtue of its definition in the XML Base specification.</p>
     
     <p>
      See <a
      href="http://www.w3.org/TR/xmlbase/">http://www.w3.org/TR/xmlbase/</a>
      for information about this attribute.
     </p>

    </div>
   </xs:documentation>
  </xs:annotation>
 </xs:attribute>
 
 <xs:attribute name="id" type="xs:ID">
  <xs:annotation>
   <xs:documentation>
    <div>
     
      <h3>id (as an attribute name)</h3> 
      <p>

       denotes an attribute whose value
       should be interpreted as if declared to be of type ID.
       This name is reserved by virtue of its definition in the
       xml:id specification.</p>
     
     <p>
      See <a
      href="http://www.w3.org/TR/xml-id/">http://www.w3.org/TR/xml-id/</a>
      for information about this attribute.
     </p>
    </div>
   </xs:documentation>
  </xs:annotation>

 </xs:attribute>

 <xs:attributeGroup name="specialAttrs">
  <xs:attribute ref="xml:base"/>
  <xs:attribute ref="xml:lang"/>
  <xs:attribute ref="xml:space"/>
  <xs:attribute ref="xml:id"/>
 </xs:attributeGroup>

 <xs:annotation>

  <xs:documentation>
   <div>
   
    <h3>Father (in any context at all)</h3> 

    <div class="bodytext">
     <p>
      denotes Jon Bosak, the chair of 
      the original XML Working Group.  This name is reserved by 
      the following decision of the W3C XML Plenary and 
      XML Coordination groups:
     </p>
     <blockquote>
       <p>

	In appreciation for his vision, leadership and
	dedication the W3C XML Plenary on this 10th day of
	February, 2000, reserves for Jon Bosak in perpetuity
	the XML name "xml:Father".
       </p>
     </blockquote>
    </div>
   </div>
  </xs:documentation>
 </xs:annotation>

 <xs:annotation>
  <xs:documentation>

   <div xml:id="usage" id="usage">
    <h2><a name="usage">About this schema document</a></h2>

    <div class="bodytext">
     <p>
      This schema defines attributes and an attribute group suitable
      for use by schemas wishing to allow <code>xml:base</code>,
      <code>xml:lang</code>, <code>xml:space</code> or
      <code>xml:id</code> attributes on elements they define.
     </p>

     <p>
      To enable this, such a schema must import this schema for
      the XML namespace, e.g. as follows:
     </p>
     <pre>
          &lt;schema.. .>
          .. .
           &lt;import namespace="http://www.w3.org/XML/1998/namespace"
                      schemaLocation="http://www.w3.org/2001/xml.xsd"/>
     </pre>
     <p>
      or
     </p>
     <pre>

           &lt;import namespace="http://www.w3.org/XML/1998/namespace"
                      schemaLocation="http://www.w3.org/2009/01/xml.xsd"/>
     </pre>
     <p>
      Subsequently, qualified reference to any of the attributes or the
      group defined below will have the desired effect, e.g.
     </p>
     <pre>
          &lt;type.. .>
          .. .
           &lt;attributeGroup ref="xml:specialAttrs"/>
     </pre>
     <p>
      will define a type which will schema-validate an instance element
      with any of those attributes.
     </p>

    </div>
   </div>
  </xs:documentation>
 </xs:annotation>

 <xs:annotation>
  <xs:documentation>
   <div id="nsversioning" xml:id="nsversioning">
    <h2><a name="nsversioning">Versioning policy for this schema document</a></h2>

    <div class="bodytext">
     <p>
      In keeping with the XML Schema WG's standard versioning
      policy, this schema document will persist at
      <a href="http://www.w3.org/2009/01/xml.xsd">
       http://www.w3.org/2009/01/xml.xsd</a>.
     </p>
     <p>
      At the date of issue it can also be found at
      <a href="http://www.w3.org/2001/xml.xsd">
       http://www.w3.org/2001/xml.xsd</a>.
     </p>

     <p>
      The schema document at that URI may however change in the future,
      in order to remain compatible with the latest version of XML
      Schema itself, or with the XML namespace itself.  In other words,
      if the XML Schema or XML namespaces change, the version of this
      document at <a href="http://www.w3.org/2001/xml.xsd">
       http://www.w3.org/2001/xml.xsd 
      </a> 
      will change accordingly; the version at 
      <a href="http://www.w3.org/2009/01/xml.xsd">
       http://www.w3.org/2009/01/xml.xsd 
      </a> 
      will not change.
     </p>
     <p>

      Previous dated (and unchanging) versions of this schema 
      document are at:
     </p>
     <ul>
      <li><a href="http://www.w3.org/2009/01/xml.xsd">
	http://www.w3.org/2009/01/xml.xsd</a></li>
      <li><a href="http://www.w3.org/2007/08/xml.xsd">
	http://www.w3.org/2007/08/xml.xsd</a></li>
      <li><a href="http://www.w3.org/2004/10/xml.xsd">

	http://www.w3.org/2004/10/xml.xsd</a></li>
      <li><a href="http://www.w3.org/2001/03/xml.xsd">
	http://www.w3.org/2001/03/xml.xsd</a></li>
     </ul>
    </div>
   </div>
  </xs:documentation>
 </xs:annotation>

</xs:schema>
PKϤ$ZD���lAlA0translation/Resources/schemas/xliff-core-2.0.xsdnu�[���<?xml version="1.0" encoding="UTF-8"?>
<!--

    XLIFF Version 2.0
    OASIS Standard
    05 August 2014
    Copyright (c) OASIS Open 2014. All rights reserved.
    Source: http://docs.oasis-open.org/xliff/xliff-core/v2.0/os/schemas/
     -->
<xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema"
    elementFormDefault="qualified"
    xmlns:xlf="urn:oasis:names:tc:xliff:document:2.0"
    targetNamespace="urn:oasis:names:tc:xliff:document:2.0">

  <!-- Import -->

  <xs:import namespace="http://www.w3.org/XML/1998/namespace"
      schemaLocation="informativeCopiesOf3rdPartySchemas/w3c/xml.xsd"/>

  <!-- Element Group -->

  <xs:group name="inline">
    <xs:choice>
      <xs:element ref="xlf:cp"/>
      <xs:element ref="xlf:ph"/>
      <xs:element ref="xlf:pc"/>
      <xs:element ref="xlf:sc"/>
      <xs:element ref="xlf:ec"/>
      <xs:element ref="xlf:mrk"/>
      <xs:element ref="xlf:sm"/>
      <xs:element ref="xlf:em"/>
    </xs:choice>
  </xs:group>

  <!-- Attribute Types -->

  <xs:simpleType name="yesNo">
    <xs:restriction base="xs:string">
      <xs:enumeration value="yes"/>
      <xs:enumeration value="no"/>
    </xs:restriction>
  </xs:simpleType>

  <xs:simpleType name="yesNoFirstNo">
    <xs:restriction base="xs:string">
      <xs:enumeration value="yes"/>
      <xs:enumeration value="firstNo"/>
      <xs:enumeration value="no"/>
    </xs:restriction>
  </xs:simpleType>

  <xs:simpleType name="dirValue">
    <xs:restriction base="xs:string">
      <xs:enumeration value="ltr"/>
      <xs:enumeration value="rtl"/>
      <xs:enumeration value="auto"/>
    </xs:restriction>
  </xs:simpleType>

  <xs:simpleType name="appliesTo">
    <xs:restriction base="xs:string">
      <xs:enumeration value="source"/>
      <xs:enumeration value="target"/>
    </xs:restriction>
  </xs:simpleType>

  <xs:simpleType name="userDefinedValue">
    <xs:restriction base="xs:string">
      <xs:pattern value="[^\s:]+:[^\s:]+"/>
    </xs:restriction>
  </xs:simpleType>

  <xs:simpleType name="attrType_type">
    <xs:restriction base="xs:string">
      <xs:enumeration value="fmt"/>
      <xs:enumeration value="ui"/>
      <xs:enumeration value="quote"/>
      <xs:enumeration value="link"/>
      <xs:enumeration value="image"/>
      <xs:enumeration value="other"/>
    </xs:restriction>
  </xs:simpleType>

  <xs:simpleType name="typeForMrkValues">
    <xs:restriction base="xs:NMTOKEN">
      <xs:enumeration value="generic"/>
      <xs:enumeration value="comment"/>
      <xs:enumeration value="term"/>
    </xs:restriction>
  </xs:simpleType>

  <xs:simpleType name="attrType_typeForMrk">
    <xs:union memberTypes="xlf:typeForMrkValues xlf:userDefinedValue"/>
  </xs:simpleType>

  <xs:simpleType name="priorityValue">
    <xs:restriction base="xs:positiveInteger">
      <xs:minInclusive value="1"/>
      <xs:maxInclusive value="10"/>
    </xs:restriction>
  </xs:simpleType>

  <xs:simpleType name="stateType">
    <xs:restriction base="xs:string">
      <xs:enumeration value="initial"/>
      <xs:enumeration value="translated"/>
      <xs:enumeration value="reviewed"/>
      <xs:enumeration value="final"/>
    </xs:restriction>
  </xs:simpleType>

  <!-- Structural Elements -->

  <xs:element name="xliff">
    <xs:complexType mixed="false">
      <xs:sequence>
        <xs:element minOccurs="1" maxOccurs="unbounded" ref="xlf:file"/>
      </xs:sequence>
      <xs:attribute name="version" use="required"/>
      <xs:attribute name="srcLang" use="required"/>
      <xs:attribute name="trgLang" use="optional"/>
      <xs:attribute ref="xml:space" use="optional" default="default"/>
      <xs:anyAttribute namespace="##other" processContents="lax"/>
    </xs:complexType>
  </xs:element>

  <xs:element name="file">
    <xs:complexType mixed="false">
      <xs:sequence>
        <xs:element minOccurs="0" maxOccurs="1" ref="xlf:skeleton"/>
        <xs:any minOccurs="0" maxOccurs="unbounded" namespace="##other"
            processContents="lax"/>
        <xs:element minOccurs="0" maxOccurs="1" ref="xlf:notes"/>
        <xs:choice minOccurs="1" maxOccurs="unbounded">
          <xs:element ref="xlf:unit"/>
          <xs:element ref="xlf:group"/>
        </xs:choice>
      </xs:sequence>
      <xs:attribute name="id" use="required" type="xs:NMTOKEN"/>
      <xs:attribute name="canResegment" use="optional" type="xlf:yesNo" default="yes"/>
      <xs:attribute name="original" use="optional"/>
      <xs:attribute name="translate" use="optional" type="xlf:yesNo" default="yes"/>
      <xs:attribute name="srcDir" use="optional" type="xlf:dirValue" default="auto"/>
      <xs:attribute name="trgDir" use="optional" type="xlf:dirValue" default="auto"/>
      <xs:attribute ref="xml:space" use="optional"/>
      <xs:anyAttribute namespace="##other" processContents="lax"/>
    </xs:complexType>
  </xs:element>

  <xs:element name="skeleton">
    <xs:complexType mixed="true">
      <xs:sequence>
        <xs:any minOccurs="0" maxOccurs="unbounded" namespace="##other"
            processContents="lax"/>
      </xs:sequence>
      <xs:attribute name="href" use="optional"/>
    </xs:complexType>
  </xs:element>

  <xs:element name="group">
    <xs:complexType mixed="false">
      <xs:sequence>
        <xs:any minOccurs="0" maxOccurs="unbounded" namespace="##other"
            processContents="lax"/>
        <xs:element minOccurs="0" maxOccurs="1" ref="xlf:notes"/>
        <xs:choice minOccurs="0" maxOccurs="unbounded">
          <xs:element ref="xlf:unit"/>
          <xs:element ref="xlf:group"/>
        </xs:choice>
      </xs:sequence>
      <xs:attribute name="id" use="required" type="xs:NMTOKEN"/>
      <xs:attribute name="name" use="optional"/>
      <xs:attribute name="canResegment" use="optional" type="xlf:yesNo"/>
      <xs:attribute name="translate" use="optional" type="xlf:yesNo"/>
      <xs:attribute name="srcDir" use="optional" type="xlf:dirValue"/>
      <xs:attribute name="trgDir" use="optional" type="xlf:dirValue"/>
      <xs:attribute name="type" use="optional" type="xlf:userDefinedValue"/>
      <xs:attribute ref="xml:space" use="optional"/>
      <xs:anyAttribute namespace="##other" processContents="lax"/>
    </xs:complexType>
  </xs:element>

  <xs:element name="unit">
    <xs:complexType mixed="false">
      <xs:sequence>
        <xs:any minOccurs="0" maxOccurs="unbounded" namespace="##other"
            processContents="lax"/>
        <xs:element minOccurs="0" maxOccurs="1" ref="xlf:notes"/>
        <xs:element minOccurs="0" maxOccurs="1" ref="xlf:originalData"/>
        <xs:choice minOccurs="1" maxOccurs="unbounded">
          <xs:element ref="xlf:segment"/>
          <xs:element ref="xlf:ignorable"/>
        </xs:choice>
      </xs:sequence>
      <xs:attribute name="id" use="required" type="xs:NMTOKEN"/>
      <xs:attribute name="name" use="optional"/>
      <xs:attribute name="canResegment" use="optional" type="xlf:yesNo"/>
      <xs:attribute name="translate" use="optional" type="xlf:yesNo"/>
      <xs:attribute name="srcDir" use="optional" type="xlf:dirValue"/>
      <xs:attribute name="trgDir" use="optional" type="xlf:dirValue"/>
      <xs:attribute ref="xml:space" use="optional"/>
      <xs:attribute name="type" use="optional" type="xlf:userDefinedValue"/>
      <xs:anyAttribute namespace="##other" processContents="lax"/>
    </xs:complexType>
  </xs:element>

  <xs:element name="segment">
    <xs:complexType mixed="false">
      <xs:sequence>
        <xs:element minOccurs="1" maxOccurs="1" ref="xlf:source"/>
        <xs:element minOccurs="0" maxOccurs="1" ref="xlf:target"/>
      </xs:sequence>
      <xs:attribute name="id" use="optional" type="xs:NMTOKEN"/>
      <xs:attribute name="canResegment" use="optional" type="xlf:yesNo"/>
      <xs:attribute name="state" use="optional" type="xlf:stateType" default="initial"/>
      <xs:attribute name="subState" use="optional"/>
    </xs:complexType>
  </xs:element>

  <xs:element name="ignorable">
    <xs:complexType mixed="false">
      <xs:sequence>
        <xs:element minOccurs="1" maxOccurs="1" ref="xlf:source"/>
        <xs:element minOccurs="0" maxOccurs="1" ref="xlf:target"/>
      </xs:sequence>
      <xs:attribute name="id" use="optional" type="xs:NMTOKEN"/>
    </xs:complexType>
  </xs:element>

  <xs:element name="notes">
    <xs:complexType mixed="false">
      <xs:sequence>
        <xs:element minOccurs="1" maxOccurs="unbounded" ref="xlf:note"/>
      </xs:sequence>
    </xs:complexType>
  </xs:element>

  <xs:element name="note">
    <xs:complexType mixed="true">
      <xs:attribute name="id" use="optional" type="xs:NMTOKEN"/>
      <xs:attribute name="appliesTo" use="optional" type="xlf:appliesTo"/>
      <xs:attribute name="category" use="optional"/>
      <xs:attribute name="priority" use="optional" type="xlf:priorityValue" default="1"/>
      <xs:anyAttribute namespace="##other" processContents="lax"/>
    </xs:complexType>
  </xs:element>

  <xs:element name="originalData">
    <xs:complexType mixed="false">
      <xs:sequence>
        <xs:element minOccurs="1" maxOccurs="unbounded" ref="xlf:data"/>
      </xs:sequence>
    </xs:complexType>
  </xs:element>

  <xs:element name="data">
    <xs:complexType mixed="true">
      <xs:sequence>
        <xs:element minOccurs="0" maxOccurs="unbounded" ref="xlf:cp"/>
      </xs:sequence>
      <xs:attribute name="id" use="required" type="xs:NMTOKEN"/>
      <xs:attribute name="dir" use="optional" type="xlf:dirValue" default="auto"/>
      <xs:attribute ref="xml:space" use="optional" fixed="preserve"/>
    </xs:complexType>
  </xs:element>

  <xs:element name="source">
    <xs:complexType mixed="true">
      <xs:group ref="xlf:inline" minOccurs="0" maxOccurs="unbounded"/>
      <xs:attribute ref="xml:lang" use="optional"/>
      <xs:attribute ref="xml:space" use="optional"/>
    </xs:complexType>
  </xs:element>

  <xs:element name="target">
    <xs:complexType mixed="true">
      <xs:group ref="xlf:inline" minOccurs="0" maxOccurs="unbounded"/>
      <xs:attribute ref="xml:lang" use="optional"/>
      <xs:attribute ref="xml:space" use="optional"/>
      <xs:attribute name="order" use="optional" type="xs:positiveInteger"/>
    </xs:complexType>
  </xs:element>

  <!-- Inline Elements -->

  <xs:element name="cp">
    <!-- Code Point -->
    <xs:complexType mixed="false">
      <xs:attribute name="hex" use="required" type="xs:hexBinary"/>
    </xs:complexType>
  </xs:element>

  <xs:element name="ph">
    <!-- Placeholder -->
    <xs:complexType mixed="false">
      <xs:attribute name="canCopy" use="optional" type="xlf:yesNo" default="yes"/>
      <xs:attribute name="canDelete" use="optional" type="xlf:yesNo" default="yes"/>
      <xs:attribute name="canReorder" use="optional" type="xlf:yesNoFirstNo" default="yes"/>
      <xs:attribute name="copyOf" use="optional" type="xs:NMTOKEN"/>
      <xs:attribute name="disp" use="optional"/>
      <xs:attribute name="equiv" use="optional"/>
      <xs:attribute name="id" use="required" type="xs:NMTOKEN"/>
      <xs:attribute name="dataRef" use="optional" type="xs:NMTOKEN"/>
      <xs:attribute name="subFlows" use="optional" type="xs:NMTOKENS"/>
      <xs:attribute name="subType" use="optional" type="xlf:userDefinedValue"/>
      <xs:attribute name="type" use="optional" type="xlf:attrType_type"/>
      <xs:anyAttribute namespace="##other" processContents="lax"/>
    </xs:complexType>
  </xs:element>

  <xs:element name="pc">
    <!-- Paired Code -->
    <xs:complexType mixed="true">
      <xs:group ref="xlf:inline" minOccurs="0" maxOccurs="unbounded"/>
      <xs:attribute name="canCopy" use="optional" type="xlf:yesNo" default="yes"/>
      <xs:attribute name="canDelete" use="optional" type="xlf:yesNo" default="yes"/>
      <xs:attribute name="canOverlap" use="optional" type="xlf:yesNo"/>
      <xs:attribute name="canReorder" use="optional" type="xlf:yesNoFirstNo" default="yes"/>
      <xs:attribute name="copyOf" use="optional" type="xs:NMTOKEN"/>
      <xs:attribute name="dispEnd" use="optional"/>
      <xs:attribute name="dispStart" use="optional"/>
      <xs:attribute name="equivEnd" use="optional"/>
      <xs:attribute name="equivStart" use="optional"/>
      <xs:attribute name="id" use="required" type="xs:NMTOKEN"/>
      <xs:attribute name="dataRefEnd" use="optional" type="xs:NMTOKEN"/>
      <xs:attribute name="dataRefStart" use="optional" type="xs:NMTOKEN"/>
      <xs:attribute name="subFlowsEnd" use="optional" type="xs:NMTOKENS"/>
      <xs:attribute name="subFlowsStart" use="optional" type="xs:NMTOKENS"/>
      <xs:attribute name="subType" use="optional" type="xlf:userDefinedValue"/>
      <xs:attribute name="type" use="optional" type="xlf:attrType_type"/>
      <xs:attribute name="dir" use="optional" type="xlf:dirValue"/>
      <xs:anyAttribute namespace="##other" processContents="lax"/>
    </xs:complexType>
  </xs:element>

  <xs:element name="sc">
    <!-- Start Code -->
    <xs:complexType mixed="false">
      <xs:attribute name="canCopy" use="optional" type="xlf:yesNo" default="yes"/>
      <xs:attribute name="canDelete" use="optional" type="xlf:yesNo" default="yes"/>
      <xs:attribute name="canOverlap" use="optional" type="xlf:yesNo" default="yes"/>
      <xs:attribute name="canReorder" use="optional" type="xlf:yesNoFirstNo" default="yes"/>
      <xs:attribute name="copyOf" use="optional" type="xs:NMTOKEN"/>
      <xs:attribute name="dataRef" use="optional" type="xs:NMTOKEN"/>
      <xs:attribute name="dir" use="optional" type="xlf:dirValue"/>
      <xs:attribute name="disp" use="optional"/>
      <xs:attribute name="equiv" use="optional"/>
      <xs:attribute name="id" use="required" type="xs:NMTOKEN"/>
      <xs:attribute name="isolated" use="optional" type="xlf:yesNo" default="no"/>
      <xs:attribute name="subFlows" use="optional" type="xs:NMTOKENS"/>
      <xs:attribute name="subType" use="optional" type="xlf:userDefinedValue"/>
      <xs:attribute name="type" use="optional" type="xlf:attrType_type"/>
      <xs:anyAttribute namespace="##other" processContents="lax"/>
    </xs:complexType>
  </xs:element>

  <xs:element name="ec">
    <!-- End Code -->
    <xs:complexType mixed="false">
      <xs:attribute name="canCopy" use="optional" type="xlf:yesNo" default="yes"/>
      <xs:attribute name="canDelete" use="optional" type="xlf:yesNo" default="yes"/>
      <xs:attribute name="canOverlap" use="optional" type="xlf:yesNo" default="yes"/>
      <xs:attribute name="canReorder" use="optional" type="xlf:yesNoFirstNo" default="yes"/>
      <xs:attribute name="copyOf" use="optional" type="xs:NMTOKEN"/>
      <xs:attribute name="dataRef" use="optional" type="xs:NMTOKEN"/>
      <xs:attribute name="dir" use="optional" type="xlf:dirValue"/>
      <xs:attribute name="disp" use="optional"/>
      <xs:attribute name="equiv" use="optional"/>
      <xs:attribute name="id" use="optional" type="xs:NMTOKEN"/>
      <xs:attribute name="isolated" use="optional" type="xlf:yesNo" default="no"/>
      <xs:attribute name="startRef" use="optional" type="xs:NMTOKEN"/>
      <xs:attribute name="subFlows" use="optional" type="xs:NMTOKENS"/>
      <xs:attribute name="subType" use="optional" type="xlf:userDefinedValue"/>
      <xs:attribute name="type" use="optional" type="xlf:attrType_type"/>
      <xs:anyAttribute namespace="##other" processContents="lax"/>
    </xs:complexType>
  </xs:element>

  <xs:element name="mrk">
    <!-- Annotation Marker -->
    <xs:complexType mixed="true">
      <xs:group ref="xlf:inline" minOccurs="0" maxOccurs="unbounded"/>
      <xs:attribute name="id" use="required" type="xs:NMTOKEN"/>
      <xs:attribute name="translate" use="optional" type="xlf:yesNo"/>
      <xs:attribute name="type" use="optional" type="xlf:attrType_typeForMrk"/>
      <xs:attribute name="ref" use="optional" type="xs:anyURI"/>
      <xs:attribute name="value" use="optional"/>
      <xs:anyAttribute namespace="##other" processContents="lax"/>
    </xs:complexType>
  </xs:element>

  <xs:element name="sm">
    <!-- Start Annotation Marker -->
    <xs:complexType mixed="false">
      <xs:attribute name="id" use="required" type="xs:NMTOKEN"/>
      <xs:attribute name="translate" use="optional" type="xlf:yesNo"/>
      <xs:attribute name="type" use="optional" type="xlf:attrType_typeForMrk"/>
      <xs:attribute name="ref" use="optional" type="xs:anyURI"/>
      <xs:attribute name="value" use="optional"/>
      <xs:anyAttribute namespace="##other" processContents="lax"/>
    </xs:complexType>
  </xs:element>

  <xs:element name="em">
    <!-- End Annotation Marker -->
    <xs:complexType mixed="false">
      <xs:attribute name="startRef" use="required" type="xs:NMTOKEN"/>
    </xs:complexType>
  </xs:element>

</xs:schema>
PKϤ$Z�a����7translation/Resources/schemas/xliff-core-1.2-strict.xsdnu�[���<?xml version="1.0" encoding="UTF-8"?>

<!--

May-19-2004:
- Changed the <choice> for ElemType_header, moving minOccurs="0" maxOccurs="unbounded" from its elements
to <choice> itself.
- Added <choice> for ElemType_trans-unit to allow "any order" for <context-group>, <count-group>, <prop-group>, <note>, and
<alt-trans>.

Oct-2005
- updated version info to 1.2
- equiv-trans attribute to <trans-unit> element
- merged-trans attribute for <group> element
- Add the <seg-source> element as optional in the <trans-unit> and <alt-trans> content models, at the same level as <source>
- Create a new value "seg" for the mtype attribute of the <mrk> element
- Add mid as an optional attribute for the <alt-trans> element

Nov-14-2005
- Changed name attribute for <context-group> from required to optional
- Added extension point at <xliff>

Jan-9-2006
- Added alttranstype type attribute to <alt-trans>, and values

Jan-10-2006
- Corrected error with overwritten purposeValueList
- Corrected name="AttrType_Version",  attribute should have been "name"

-->
<xsd:schema xmlns:xlf="urn:oasis:names:tc:xliff:document:1.2" xmlns:xsd="http://www.w3.org/2001/XMLSchema" elementFormDefault="qualified" targetNamespace="urn:oasis:names:tc:xliff:document:1.2" xml:lang="en">
  <!-- Import for xml:lang and xml:space -->
  <xsd:import namespace="http://www.w3.org/XML/1998/namespace" schemaLocation="http://www.w3.org/2001/xml.xsd"/>
  <!-- Attributes Lists -->
  <xsd:simpleType name="XTend">
    <xsd:restriction base="xsd:string">
      <xsd:pattern value="x-[^\s]+"/>
    </xsd:restriction>
  </xsd:simpleType>
  <xsd:simpleType name="context-typeValueList">
    <xsd:annotation>
      <xsd:documentation>Values for the attribute 'context-type'.</xsd:documentation>
    </xsd:annotation>
    <xsd:restriction base="xsd:string">
      <xsd:enumeration value="database">
        <xsd:annotation>
          <xsd:documentation>Indicates a database content.</xsd:documentation>
        </xsd:annotation>
      </xsd:enumeration>
      <xsd:enumeration value="element">
        <xsd:annotation>
          <xsd:documentation>Indicates the content of an element within an XML document.</xsd:documentation>
        </xsd:annotation>
      </xsd:enumeration>
      <xsd:enumeration value="elementtitle">
        <xsd:annotation>
          <xsd:documentation>Indicates the name of an element within an XML document.</xsd:documentation>
        </xsd:annotation>
      </xsd:enumeration>
      <xsd:enumeration value="linenumber">
        <xsd:annotation>
          <xsd:documentation>Indicates the line number from the sourcefile (see context-type="sourcefile") where the &lt;source&gt; is found.</xsd:documentation>
        </xsd:annotation>
      </xsd:enumeration>
      <xsd:enumeration value="numparams">
        <xsd:annotation>
          <xsd:documentation>Indicates a the number of parameters contained within the &lt;source&gt;.</xsd:documentation>
        </xsd:annotation>
      </xsd:enumeration>
      <xsd:enumeration value="paramnotes">
        <xsd:annotation>
          <xsd:documentation>Indicates notes pertaining to the parameters in the &lt;source&gt;.</xsd:documentation>
        </xsd:annotation>
      </xsd:enumeration>
      <xsd:enumeration value="record">
        <xsd:annotation>
          <xsd:documentation>Indicates the content of a record within a database.</xsd:documentation>
        </xsd:annotation>
      </xsd:enumeration>
      <xsd:enumeration value="recordtitle">
        <xsd:annotation>
          <xsd:documentation>Indicates the name of a record within a database.</xsd:documentation>
        </xsd:annotation>
      </xsd:enumeration>
      <xsd:enumeration value="sourcefile">
        <xsd:annotation>
          <xsd:documentation>Indicates the original source file in the case that multiple files are merged to form the original file from which the XLIFF file is created. This differs from the original &lt;file&gt; attribute in that this sourcefile is one of many that make up that file.</xsd:documentation>
        </xsd:annotation>
      </xsd:enumeration>
    </xsd:restriction>
  </xsd:simpleType>
  <xsd:simpleType name="count-typeValueList">
    <xsd:annotation>
      <xsd:documentation>Values for the attribute 'count-type'.</xsd:documentation>
    </xsd:annotation>
    <xsd:restriction base="xsd:NMTOKEN">
      <xsd:enumeration value="num-usages">
        <xsd:annotation>
          <xsd:documentation>Indicates the count units are items that are used X times in a certain context; example: this is a reusable text unit which is used 42 times in other texts.</xsd:documentation>
        </xsd:annotation>
      </xsd:enumeration>
      <xsd:enumeration value="repetition">
        <xsd:annotation>
          <xsd:documentation>Indicates the count units are translation units existing already in the same document.</xsd:documentation>
        </xsd:annotation>
      </xsd:enumeration>
      <xsd:enumeration value="total">
        <xsd:annotation>
          <xsd:documentation>Indicates a total count.</xsd:documentation>
        </xsd:annotation>
      </xsd:enumeration>
    </xsd:restriction>
  </xsd:simpleType>
  <xsd:simpleType name="InlineDelimitersValueList">
    <xsd:annotation>
      <xsd:documentation>Values for the attribute 'ctype' when used other elements than &lt;ph&gt; or &lt;x&gt;.</xsd:documentation>
    </xsd:annotation>
    <xsd:restriction base="xsd:NMTOKEN">
      <xsd:enumeration value="bold">
        <xsd:annotation>
          <xsd:documentation>Indicates a run of bolded text.</xsd:documentation>
        </xsd:annotation>
      </xsd:enumeration>
      <xsd:enumeration value="italic">
        <xsd:annotation>
          <xsd:documentation>Indicates a run of text in italics.</xsd:documentation>
        </xsd:annotation>
      </xsd:enumeration>
      <xsd:enumeration value="underlined">
        <xsd:annotation>
          <xsd:documentation>Indicates a run of underlined text.</xsd:documentation>
        </xsd:annotation>
      </xsd:enumeration>
      <xsd:enumeration value="link">
        <xsd:annotation>
          <xsd:documentation>Indicates a run of hyper-text.</xsd:documentation>
        </xsd:annotation>
      </xsd:enumeration>
    </xsd:restriction>
  </xsd:simpleType>
  <xsd:simpleType name="InlinePlaceholdersValueList">
    <xsd:annotation>
      <xsd:documentation>Values for the attribute 'ctype' when used with &lt;ph&gt; or &lt;x&gt;.</xsd:documentation>
    </xsd:annotation>
    <xsd:restriction base="xsd:NMTOKEN">
      <xsd:enumeration value="image">
        <xsd:annotation>
          <xsd:documentation>Indicates a inline image.</xsd:documentation>
        </xsd:annotation>
      </xsd:enumeration>
      <xsd:enumeration value="pb">
        <xsd:annotation>
          <xsd:documentation>Indicates a page break.</xsd:documentation>
        </xsd:annotation>
      </xsd:enumeration>
      <xsd:enumeration value="lb">
        <xsd:annotation>
          <xsd:documentation>Indicates a line break.</xsd:documentation>
        </xsd:annotation>
      </xsd:enumeration>
    </xsd:restriction>
  </xsd:simpleType>
  <xsd:simpleType name="mime-typeValueList">
    <xsd:restriction base="xsd:string">
      <xsd:pattern value="(text|multipart|message|application|image|audio|video|model)(/.+)*"/>
    </xsd:restriction>
  </xsd:simpleType>
  <xsd:simpleType name="datatypeValueList">
    <xsd:annotation>
      <xsd:documentation>Values for the attribute 'datatype'.</xsd:documentation>
    </xsd:annotation>
    <xsd:restriction base="xsd:NMTOKEN">
      <xsd:enumeration value="asp">
        <xsd:annotation>
          <xsd:documentation>Indicates Active Server Page data.</xsd:documentation>
        </xsd:annotation>
      </xsd:enumeration>
      <xsd:enumeration value="c">
        <xsd:annotation>
          <xsd:documentation>Indicates C source file data.</xsd:documentation>
        </xsd:annotation>
      </xsd:enumeration>
      <xsd:enumeration value="cdf">
        <xsd:annotation>
          <xsd:documentation>Indicates Channel Definition Format (CDF) data.</xsd:documentation>
        </xsd:annotation>
      </xsd:enumeration>
      <xsd:enumeration value="cfm">
        <xsd:annotation>
          <xsd:documentation>Indicates ColdFusion data.</xsd:documentation>
        </xsd:annotation>
      </xsd:enumeration>
      <xsd:enumeration value="cpp">
        <xsd:annotation>
          <xsd:documentation>Indicates C++ source file data.</xsd:documentation>
        </xsd:annotation>
      </xsd:enumeration>
      <xsd:enumeration value="csharp">
        <xsd:annotation>
          <xsd:documentation>Indicates C-Sharp data.</xsd:documentation>
        </xsd:annotation>
      </xsd:enumeration>
      <xsd:enumeration value="cstring">
        <xsd:annotation>
          <xsd:documentation>Indicates strings from C, ASM, and driver files data.</xsd:documentation>
        </xsd:annotation>
      </xsd:enumeration>
      <xsd:enumeration value="csv">
        <xsd:annotation>
          <xsd:documentation>Indicates comma-separated values data.</xsd:documentation>
        </xsd:annotation>
      </xsd:enumeration>
      <xsd:enumeration value="database">
        <xsd:annotation>
          <xsd:documentation>Indicates database data.</xsd:documentation>
        </xsd:annotation>
      </xsd:enumeration>
      <xsd:enumeration value="documentfooter">
        <xsd:annotation>
          <xsd:documentation>Indicates portions of document that follows data and contains metadata.</xsd:documentation>
        </xsd:annotation>
      </xsd:enumeration>
      <xsd:enumeration value="documentheader">
        <xsd:annotation>
          <xsd:documentation>Indicates portions of document that precedes data and contains metadata.</xsd:documentation>
        </xsd:annotation>
      </xsd:enumeration>
      <xsd:enumeration value="filedialog">
        <xsd:annotation>
          <xsd:documentation>Indicates data from standard UI file operations dialogs (e.g., Open, Save, Save As, Export, Import).</xsd:documentation>
        </xsd:annotation>
      </xsd:enumeration>
      <xsd:enumeration value="form">
        <xsd:annotation>
          <xsd:documentation>Indicates standard user input screen data.</xsd:documentation>
        </xsd:annotation>
      </xsd:enumeration>
      <xsd:enumeration value="html">
        <xsd:annotation>
          <xsd:documentation>Indicates HyperText Markup Language (HTML) data - document instance.</xsd:documentation>
        </xsd:annotation>
      </xsd:enumeration>
      <xsd:enumeration value="htmlbody">
        <xsd:annotation>
          <xsd:documentation>Indicates content within an HTML document’s &lt;body&gt; element.</xsd:documentation>
        </xsd:annotation>
      </xsd:enumeration>
      <xsd:enumeration value="ini">
        <xsd:annotation>
          <xsd:documentation>Indicates Windows INI file data.</xsd:documentation>
        </xsd:annotation>
      </xsd:enumeration>
      <xsd:enumeration value="interleaf">
        <xsd:annotation>
          <xsd:documentation>Indicates Interleaf data.</xsd:documentation>
        </xsd:annotation>
      </xsd:enumeration>
      <xsd:enumeration value="javaclass">
        <xsd:annotation>
          <xsd:documentation>Indicates Java source file data (extension '.java').</xsd:documentation>
        </xsd:annotation>
      </xsd:enumeration>
      <xsd:enumeration value="javapropertyresourcebundle">
        <xsd:annotation>
          <xsd:documentation>Indicates Java property resource bundle data.</xsd:documentation>
        </xsd:annotation>
      </xsd:enumeration>
      <xsd:enumeration value="javalistresourcebundle">
        <xsd:annotation>
          <xsd:documentation>Indicates Java list resource bundle data.</xsd:documentation>
        </xsd:annotation>
      </xsd:enumeration>
      <xsd:enumeration value="javascript">
        <xsd:annotation>
          <xsd:documentation>Indicates JavaScript source file data.</xsd:documentation>
        </xsd:annotation>
      </xsd:enumeration>
      <xsd:enumeration value="jscript">
        <xsd:annotation>
          <xsd:documentation>Indicates JScript source file data.</xsd:documentation>
        </xsd:annotation>
      </xsd:enumeration>
      <xsd:enumeration value="layout">
        <xsd:annotation>
          <xsd:documentation>Indicates information relating to formatting.</xsd:documentation>
        </xsd:annotation>
      </xsd:enumeration>
      <xsd:enumeration value="lisp">
        <xsd:annotation>
          <xsd:documentation>Indicates LISP source file data.</xsd:documentation>
        </xsd:annotation>
      </xsd:enumeration>
      <xsd:enumeration value="margin">
        <xsd:annotation>
          <xsd:documentation>Indicates information relating to margin formats.</xsd:documentation>
        </xsd:annotation>
      </xsd:enumeration>
      <xsd:enumeration value="menufile">
        <xsd:annotation>
          <xsd:documentation>Indicates a file containing menu.</xsd:documentation>
        </xsd:annotation>
      </xsd:enumeration>
      <xsd:enumeration value="messagefile">
        <xsd:annotation>
          <xsd:documentation>Indicates numerically identified string table.</xsd:documentation>
        </xsd:annotation>
      </xsd:enumeration>
      <xsd:enumeration value="mif">
        <xsd:annotation>
          <xsd:documentation>Indicates Maker Interchange Format (MIF) data.</xsd:documentation>
        </xsd:annotation>
      </xsd:enumeration>
      <xsd:enumeration value="mimetype">
        <xsd:annotation>
          <xsd:documentation>Indicates that the datatype attribute value is a MIME Type value and is defined in the mime-type attribute.</xsd:documentation>
        </xsd:annotation>
      </xsd:enumeration>
      <xsd:enumeration value="mo">
        <xsd:annotation>
          <xsd:documentation>Indicates GNU Machine Object data.</xsd:documentation>
        </xsd:annotation>
      </xsd:enumeration>
      <xsd:enumeration value="msglib">
        <xsd:annotation>
          <xsd:documentation>Indicates Message Librarian strings created by Novell's Message Librarian Tool.</xsd:documentation>
        </xsd:annotation>
      </xsd:enumeration>
      <xsd:enumeration value="pagefooter">
        <xsd:annotation>
          <xsd:documentation>Indicates information to be displayed at the bottom of each page of a document.</xsd:documentation>
        </xsd:annotation>
      </xsd:enumeration>
      <xsd:enumeration value="pageheader">
        <xsd:annotation>
          <xsd:documentation>Indicates information to be displayed at the top of each page of a document.</xsd:documentation>
        </xsd:annotation>
      </xsd:enumeration>
      <xsd:enumeration value="parameters">
        <xsd:annotation>
          <xsd:documentation>Indicates a list of property values (e.g., settings within INI files or preferences dialog).</xsd:documentation>
        </xsd:annotation>
      </xsd:enumeration>
      <xsd:enumeration value="pascal">
        <xsd:annotation>
          <xsd:documentation>Indicates Pascal source file data.</xsd:documentation>
        </xsd:annotation>
      </xsd:enumeration>
      <xsd:enumeration value="php">
        <xsd:annotation>
          <xsd:documentation>Indicates Hypertext Preprocessor data.</xsd:documentation>
        </xsd:annotation>
      </xsd:enumeration>
      <xsd:enumeration value="plaintext">
        <xsd:annotation>
          <xsd:documentation>Indicates plain text file (no formatting other than, possibly, wrapping).</xsd:documentation>
        </xsd:annotation>
      </xsd:enumeration>
      <xsd:enumeration value="po">
        <xsd:annotation>
          <xsd:documentation>Indicates GNU Portable Object file.</xsd:documentation>
        </xsd:annotation>
      </xsd:enumeration>
      <xsd:enumeration value="report">
        <xsd:annotation>
          <xsd:documentation>Indicates dynamically generated user defined document. e.g. Oracle Report, Crystal Report, etc.</xsd:documentation>
        </xsd:annotation>
      </xsd:enumeration>
      <xsd:enumeration value="resources">
        <xsd:annotation>
          <xsd:documentation>Indicates Windows .NET binary resources.</xsd:documentation>
        </xsd:annotation>
      </xsd:enumeration>
      <xsd:enumeration value="resx">
        <xsd:annotation>
          <xsd:documentation>Indicates Windows .NET Resources.</xsd:documentation>
        </xsd:annotation>
      </xsd:enumeration>
      <xsd:enumeration value="rtf">
        <xsd:annotation>
          <xsd:documentation>Indicates Rich Text Format (RTF) data.</xsd:documentation>
        </xsd:annotation>
      </xsd:enumeration>
      <xsd:enumeration value="sgml">
        <xsd:annotation>
          <xsd:documentation>Indicates Standard Generalized Markup Language (SGML) data - document instance.</xsd:documentation>
        </xsd:annotation>
      </xsd:enumeration>
      <xsd:enumeration value="sgmldtd">
        <xsd:annotation>
          <xsd:documentation>Indicates Standard Generalized Markup Language (SGML) data - Document Type Definition (DTD).</xsd:documentation>
        </xsd:annotation>
      </xsd:enumeration>
      <xsd:enumeration value="svg">
        <xsd:annotation>
          <xsd:documentation>Indicates Scalable Vector Graphic (SVG) data.</xsd:documentation>
        </xsd:annotation>
      </xsd:enumeration>
      <xsd:enumeration value="vbscript">
        <xsd:annotation>
          <xsd:documentation>Indicates VisualBasic Script source file.</xsd:documentation>
        </xsd:annotation>
      </xsd:enumeration>
      <xsd:enumeration value="warning">
        <xsd:annotation>
          <xsd:documentation>Indicates warning message.</xsd:documentation>
        </xsd:annotation>
      </xsd:enumeration>
      <xsd:enumeration value="winres">
        <xsd:annotation>
          <xsd:documentation>Indicates Windows (Win32) resources (i.e. resources extracted from an RC script, a message file, or a compiled file).</xsd:documentation>
        </xsd:annotation>
      </xsd:enumeration>
      <xsd:enumeration value="xhtml">
        <xsd:annotation>
          <xsd:documentation>Indicates Extensible HyperText Markup Language (XHTML) data - document instance.</xsd:documentation>
        </xsd:annotation>
      </xsd:enumeration>
      <xsd:enumeration value="xml">
        <xsd:annotation>
          <xsd:documentation>Indicates Extensible Markup Language (XML) data - document instance.</xsd:documentation>
        </xsd:annotation>
      </xsd:enumeration>
      <xsd:enumeration value="xmldtd">
        <xsd:annotation>
          <xsd:documentation>Indicates Extensible Markup Language (XML) data - Document Type Definition (DTD).</xsd:documentation>
        </xsd:annotation>
      </xsd:enumeration>
      <xsd:enumeration value="xsl">
        <xsd:annotation>
          <xsd:documentation>Indicates Extensible Stylesheet Language (XSL) data.</xsd:documentation>
        </xsd:annotation>
      </xsd:enumeration>
      <xsd:enumeration value="xul">
        <xsd:annotation>
          <xsd:documentation>Indicates XUL elements.</xsd:documentation>
        </xsd:annotation>
      </xsd:enumeration>
    </xsd:restriction>
  </xsd:simpleType>
  <xsd:simpleType name="mtypeValueList">
    <xsd:annotation>
      <xsd:documentation>Values for the attribute 'mtype'.</xsd:documentation>
    </xsd:annotation>
    <xsd:restriction base="xsd:NMTOKEN">
      <xsd:enumeration value="abbrev">
        <xsd:annotation>
          <xsd:documentation>Indicates the marked text is an abbreviation.</xsd:documentation>
        </xsd:annotation>
      </xsd:enumeration>
      <xsd:enumeration value="abbreviated-form">
        <xsd:annotation>
          <xsd:documentation>ISO-12620 2.1.8: A term resulting from the omission of any part of the full term while designating the same concept.</xsd:documentation>
        </xsd:annotation>
      </xsd:enumeration>
      <xsd:enumeration value="abbreviation">
        <xsd:annotation>
          <xsd:documentation>ISO-12620 2.1.8.1: An abbreviated form of a simple term resulting from the omission of some of its letters (e.g. 'adj.' for 'adjective').</xsd:documentation>
        </xsd:annotation>
      </xsd:enumeration>
      <xsd:enumeration value="acronym">
        <xsd:annotation>
          <xsd:documentation>ISO-12620 2.1.8.4: An abbreviated form of a term made up of letters from the full form of a multiword term strung together into a sequence pronounced only syllabically (e.g. 'radar' for 'radio detecting and ranging').</xsd:documentation>
        </xsd:annotation>
      </xsd:enumeration>
      <xsd:enumeration value="appellation">
        <xsd:annotation>
          <xsd:documentation>ISO-12620: A proper-name term, such as the name of an agency or other proper entity.</xsd:documentation>
        </xsd:annotation>
      </xsd:enumeration>
      <xsd:enumeration value="collocation">
        <xsd:annotation>
          <xsd:documentation>ISO-12620 2.1.18.1: A recurrent word combination characterized by cohesion in that the components of the collocation must co-occur within an utterance or series of utterances, even though they do not necessarily have to maintain immediate proximity to one another.</xsd:documentation>
        </xsd:annotation>
      </xsd:enumeration>
      <xsd:enumeration value="common-name">
        <xsd:annotation>
          <xsd:documentation>ISO-12620 2.1.5: A synonym for an international scientific term that is used in general discourse in a given language.</xsd:documentation>
        </xsd:annotation>
      </xsd:enumeration>
      <xsd:enumeration value="datetime">
        <xsd:annotation>
          <xsd:documentation>Indicates the marked text is a date and/or time.</xsd:documentation>
        </xsd:annotation>
      </xsd:enumeration>
      <xsd:enumeration value="equation">
        <xsd:annotation>
          <xsd:documentation>ISO-12620 2.1.15: An expression used to represent a concept based on a statement that two mathematical expressions are, for instance, equal as identified by the equal sign (=), or assigned to one another by a similar sign.</xsd:documentation>
        </xsd:annotation>
      </xsd:enumeration>
      <xsd:enumeration value="expanded-form">
        <xsd:annotation>
          <xsd:documentation>ISO-12620 2.1.7: The complete representation of a term for which there is an abbreviated form.</xsd:documentation>
        </xsd:annotation>
      </xsd:enumeration>
      <xsd:enumeration value="formula">
        <xsd:annotation>
          <xsd:documentation>ISO-12620 2.1.14: Figures, symbols or the like used to express a concept briefly, such as a mathematical or chemical formula.</xsd:documentation>
        </xsd:annotation>
      </xsd:enumeration>
      <xsd:enumeration value="head-term">
        <xsd:annotation>
          <xsd:documentation>ISO-12620 2.1.1: The concept designation that has been chosen to head a terminological record.</xsd:documentation>
        </xsd:annotation>
      </xsd:enumeration>
      <xsd:enumeration value="initialism">
        <xsd:annotation>
          <xsd:documentation>ISO-12620 2.1.8.3: An abbreviated form of a term consisting of some of the initial letters of the words making up a multiword term or the term elements making up a compound term when these letters are pronounced individually (e.g. 'BSE' for 'bovine spongiform encephalopathy').</xsd:documentation>
        </xsd:annotation>
      </xsd:enumeration>
      <xsd:enumeration value="international-scientific-term">
        <xsd:annotation>
          <xsd:documentation>ISO-12620 2.1.4: A term that is part of an international scientific nomenclature as adopted by an appropriate scientific body.</xsd:documentation>
        </xsd:annotation>
      </xsd:enumeration>
      <xsd:enumeration value="internationalism">
        <xsd:annotation>
          <xsd:documentation>ISO-12620 2.1.6: A term that has the same or nearly identical orthographic or phonemic form in many languages.</xsd:documentation>
        </xsd:annotation>
      </xsd:enumeration>
      <xsd:enumeration value="logical-expression">
        <xsd:annotation>
          <xsd:documentation>ISO-12620 2.1.16: An expression used to represent a concept based on mathematical or logical relations, such as statements of inequality, set relationships, Boolean operations, and the like.</xsd:documentation>
        </xsd:annotation>
      </xsd:enumeration>
      <xsd:enumeration value="materials-management-unit">
        <xsd:annotation>
          <xsd:documentation>ISO-12620 2.1.17: A unit to track object.</xsd:documentation>
        </xsd:annotation>
      </xsd:enumeration>
      <xsd:enumeration value="name">
        <xsd:annotation>
          <xsd:documentation>Indicates the marked text is a name.</xsd:documentation>
        </xsd:annotation>
      </xsd:enumeration>
      <xsd:enumeration value="near-synonym">
        <xsd:annotation>
          <xsd:documentation>ISO-12620 2.1.3: A term that represents the same or a very similar concept as another term in the same language, but for which interchangeability is limited to some contexts and inapplicable in others.</xsd:documentation>
        </xsd:annotation>
      </xsd:enumeration>
      <xsd:enumeration value="part-number">
        <xsd:annotation>
          <xsd:documentation>ISO-12620 2.1.17.2: A unique alphanumeric designation assigned to an object in a manufacturing system.</xsd:documentation>
        </xsd:annotation>
      </xsd:enumeration>
      <xsd:enumeration value="phrase">
        <xsd:annotation>
          <xsd:documentation>Indicates the marked text is a phrase.</xsd:documentation>
        </xsd:annotation>
      </xsd:enumeration>
      <xsd:enumeration value="phraseological-unit">
        <xsd:annotation>
          <xsd:documentation>ISO-12620 2.1.18: Any group of two or more words that form a unit, the meaning of which frequently cannot be deduced based on the combined sense of the words making up the phrase.</xsd:documentation>
        </xsd:annotation>
      </xsd:enumeration>
      <xsd:enumeration value="protected">
        <xsd:annotation>
          <xsd:documentation>Indicates the marked text should not be translated.</xsd:documentation>
        </xsd:annotation>
      </xsd:enumeration>
      <xsd:enumeration value="romanized-form">
        <xsd:annotation>
          <xsd:documentation>ISO-12620 2.1.12: A form of a term resulting from an operation whereby non-Latin writing systems are converted to the Latin alphabet.</xsd:documentation>
        </xsd:annotation>
      </xsd:enumeration>
      <xsd:enumeration value="seg">
        <xsd:annotation>
          <xsd:documentation>Indicates that the marked text represents a segment.</xsd:documentation>
        </xsd:annotation>
      </xsd:enumeration>
      <xsd:enumeration value="set-phrase">
        <xsd:annotation>
          <xsd:documentation>ISO-12620 2.1.18.2: A fixed, lexicalized phrase.</xsd:documentation>
        </xsd:annotation>
      </xsd:enumeration>
      <xsd:enumeration value="short-form">
        <xsd:annotation>
          <xsd:documentation>ISO-12620 2.1.8.2: A variant of a multiword term that includes fewer words than the full form of the term (e.g. 'Group of Twenty-four' for 'Intergovernmental Group of Twenty-four on International Monetary Affairs').</xsd:documentation>
        </xsd:annotation>
      </xsd:enumeration>
      <xsd:enumeration value="sku">
        <xsd:annotation>
          <xsd:documentation>ISO-12620 2.1.17.1: Stock keeping unit, an inventory item identified by a unique alphanumeric designation assigned to an object in an inventory control system.</xsd:documentation>
        </xsd:annotation>
      </xsd:enumeration>
      <xsd:enumeration value="standard-text">
        <xsd:annotation>
          <xsd:documentation>ISO-12620 2.1.19: A fixed chunk of recurring text.</xsd:documentation>
        </xsd:annotation>
      </xsd:enumeration>
      <xsd:enumeration value="symbol">
        <xsd:annotation>
          <xsd:documentation>ISO-12620 2.1.13: A designation of a concept by letters, numerals, pictograms or any combination thereof.</xsd:documentation>
        </xsd:annotation>
      </xsd:enumeration>
      <xsd:enumeration value="synonym">
        <xsd:annotation>
          <xsd:documentation>ISO-12620 2.1.2: Any term that represents the same or a very similar concept as the main entry term in a term entry.</xsd:documentation>
        </xsd:annotation>
      </xsd:enumeration>
      <xsd:enumeration value="synonymous-phrase">
        <xsd:annotation>
          <xsd:documentation>ISO-12620 2.1.18.3: Phraseological unit in a language that expresses the same semantic content as another phrase in that same language.</xsd:documentation>
        </xsd:annotation>
      </xsd:enumeration>
      <xsd:enumeration value="term">
        <xsd:annotation>
          <xsd:documentation>Indicates the marked text is a term.</xsd:documentation>
        </xsd:annotation>
      </xsd:enumeration>
      <xsd:enumeration value="transcribed-form">
        <xsd:annotation>
          <xsd:documentation>ISO-12620 2.1.11: A form of a term resulting from an operation whereby the characters of one writing system are represented by characters from another writing system, taking into account the pronunciation of the characters converted.</xsd:documentation>
        </xsd:annotation>
      </xsd:enumeration>
      <xsd:enumeration value="transliterated-form">
        <xsd:annotation>
          <xsd:documentation>ISO-12620 2.1.10: A form of a term resulting from an operation whereby the characters of an alphabetic writing system are represented by characters from another alphabetic writing system.</xsd:documentation>
        </xsd:annotation>
      </xsd:enumeration>
      <xsd:enumeration value="truncated-term">
        <xsd:annotation>
          <xsd:documentation>ISO-12620 2.1.8.5: An abbreviated form of a term resulting from the omission of one or more term elements or syllables (e.g. 'flu' for 'influenza').</xsd:documentation>
        </xsd:annotation>
      </xsd:enumeration>
      <xsd:enumeration value="variant">
        <xsd:annotation>
          <xsd:documentation>ISO-12620 2.1.9: One of the alternate forms of a term.</xsd:documentation>
        </xsd:annotation>
      </xsd:enumeration>
    </xsd:restriction>
  </xsd:simpleType>
  <xsd:simpleType name="restypeValueList">
    <xsd:annotation>
      <xsd:documentation>Values for the attribute 'restype'.</xsd:documentation>
    </xsd:annotation>
    <xsd:restriction base="xsd:NMTOKEN">
      <xsd:enumeration value="auto3state">
        <xsd:annotation>
          <xsd:documentation>Indicates a Windows RC AUTO3STATE control.</xsd:documentation>
        </xsd:annotation>
      </xsd:enumeration>
      <xsd:enumeration value="autocheckbox">
        <xsd:annotation>
          <xsd:documentation>Indicates a Windows RC AUTOCHECKBOX control.</xsd:documentation>
        </xsd:annotation>
      </xsd:enumeration>
      <xsd:enumeration value="autoradiobutton">
        <xsd:annotation>
          <xsd:documentation>Indicates a Windows RC AUTORADIOBUTTON control.</xsd:documentation>
        </xsd:annotation>
      </xsd:enumeration>
      <xsd:enumeration value="bedit">
        <xsd:annotation>
          <xsd:documentation>Indicates a Windows RC BEDIT control.</xsd:documentation>
        </xsd:annotation>
      </xsd:enumeration>
      <xsd:enumeration value="bitmap">
        <xsd:annotation>
          <xsd:documentation>Indicates a bitmap, for example a BITMAP resource in Windows.</xsd:documentation>
        </xsd:annotation>
      </xsd:enumeration>
      <xsd:enumeration value="button">
        <xsd:annotation>
          <xsd:documentation>Indicates a button object, for example a BUTTON control Windows.</xsd:documentation>
        </xsd:annotation>
      </xsd:enumeration>
      <xsd:enumeration value="caption">
        <xsd:annotation>
          <xsd:documentation>Indicates a caption, such as the caption of a dialog box.</xsd:documentation>
        </xsd:annotation>
      </xsd:enumeration>
      <xsd:enumeration value="cell">
        <xsd:annotation>
          <xsd:documentation>Indicates the cell in a table, for example the content of the &lt;td&gt; element in HTML.</xsd:documentation>
        </xsd:annotation>
      </xsd:enumeration>
      <xsd:enumeration value="checkbox">
        <xsd:annotation>
          <xsd:documentation>Indicates check box object, for example a CHECKBOX control in Windows.</xsd:documentation>
        </xsd:annotation>
      </xsd:enumeration>
      <xsd:enumeration value="checkboxmenuitem">
        <xsd:annotation>
          <xsd:documentation>Indicates a menu item with an associated checkbox.</xsd:documentation>
        </xsd:annotation>
      </xsd:enumeration>
      <xsd:enumeration value="checkedlistbox">
        <xsd:annotation>
          <xsd:documentation>Indicates a list box, but with a check-box for each item.</xsd:documentation>
        </xsd:annotation>
      </xsd:enumeration>
      <xsd:enumeration value="colorchooser">
        <xsd:annotation>
          <xsd:documentation>Indicates a color selection dialog.</xsd:documentation>
        </xsd:annotation>
      </xsd:enumeration>
      <xsd:enumeration value="combobox">
        <xsd:annotation>
          <xsd:documentation>Indicates a combination of edit box and listbox object, for example a COMBOBOX control in Windows.</xsd:documentation>
        </xsd:annotation>
      </xsd:enumeration>
      <xsd:enumeration value="comboboxexitem">
        <xsd:annotation>
          <xsd:documentation>Indicates an initialization entry of an extended combobox DLGINIT resource block. (code 0x1234).</xsd:documentation>
        </xsd:annotation>
      </xsd:enumeration>
      <xsd:enumeration value="comboboxitem">
        <xsd:annotation>
          <xsd:documentation>Indicates an initialization entry of a combobox DLGINIT resource block (code 0x0403).</xsd:documentation>
        </xsd:annotation>
      </xsd:enumeration>
      <xsd:enumeration value="component">
        <xsd:annotation>
          <xsd:documentation>Indicates a UI base class element that cannot be represented by any other element.</xsd:documentation>
        </xsd:annotation>
      </xsd:enumeration>
      <xsd:enumeration value="contextmenu">
        <xsd:annotation>
          <xsd:documentation>Indicates a context menu.</xsd:documentation>
        </xsd:annotation>
      </xsd:enumeration>
      <xsd:enumeration value="ctext">
        <xsd:annotation>
          <xsd:documentation>Indicates a Windows RC CTEXT control.</xsd:documentation>
        </xsd:annotation>
      </xsd:enumeration>
      <xsd:enumeration value="cursor">
        <xsd:annotation>
          <xsd:documentation>Indicates a cursor, for example a CURSOR resource in Windows.</xsd:documentation>
        </xsd:annotation>
      </xsd:enumeration>
      <xsd:enumeration value="datetimepicker">
        <xsd:annotation>
          <xsd:documentation>Indicates a date/time picker.</xsd:documentation>
        </xsd:annotation>
      </xsd:enumeration>
      <xsd:enumeration value="defpushbutton">
        <xsd:annotation>
          <xsd:documentation>Indicates a Windows RC DEFPUSHBUTTON control.</xsd:documentation>
        </xsd:annotation>
      </xsd:enumeration>
      <xsd:enumeration value="dialog">
        <xsd:annotation>
          <xsd:documentation>Indicates a dialog box.</xsd:documentation>
        </xsd:annotation>
      </xsd:enumeration>
      <xsd:enumeration value="dlginit">
        <xsd:annotation>
          <xsd:documentation>Indicates a Windows RC DLGINIT resource block.</xsd:documentation>
        </xsd:annotation>
      </xsd:enumeration>
      <xsd:enumeration value="edit">
        <xsd:annotation>
          <xsd:documentation>Indicates an edit box object, for example an EDIT control in Windows.</xsd:documentation>
        </xsd:annotation>
      </xsd:enumeration>
      <xsd:enumeration value="file">
        <xsd:annotation>
          <xsd:documentation>Indicates a filename.</xsd:documentation>
        </xsd:annotation>
      </xsd:enumeration>
      <xsd:enumeration value="filechooser">
        <xsd:annotation>
          <xsd:documentation>Indicates a file dialog.</xsd:documentation>
        </xsd:annotation>
      </xsd:enumeration>
      <xsd:enumeration value="fn">
        <xsd:annotation>
          <xsd:documentation>Indicates a footnote.</xsd:documentation>
        </xsd:annotation>
      </xsd:enumeration>
      <xsd:enumeration value="font">
        <xsd:annotation>
          <xsd:documentation>Indicates a font name.</xsd:documentation>
        </xsd:annotation>
      </xsd:enumeration>
      <xsd:enumeration value="footer">
        <xsd:annotation>
          <xsd:documentation>Indicates a footer.</xsd:documentation>
        </xsd:annotation>
      </xsd:enumeration>
      <xsd:enumeration value="frame">
        <xsd:annotation>
          <xsd:documentation>Indicates a frame object.</xsd:documentation>
        </xsd:annotation>
      </xsd:enumeration>
      <xsd:enumeration value="grid">
        <xsd:annotation>
          <xsd:documentation>Indicates a XUL grid element.</xsd:documentation>
        </xsd:annotation>
      </xsd:enumeration>
      <xsd:enumeration value="groupbox">
        <xsd:annotation>
          <xsd:documentation>Indicates a groupbox object, for example a GROUPBOX control in Windows.</xsd:documentation>
        </xsd:annotation>
      </xsd:enumeration>
      <xsd:enumeration value="header">
        <xsd:annotation>
          <xsd:documentation>Indicates a header item.</xsd:documentation>
        </xsd:annotation>
      </xsd:enumeration>
      <xsd:enumeration value="heading">
        <xsd:annotation>
          <xsd:documentation>Indicates a heading, such has the content of &lt;h1&gt;, &lt;h2&gt;, etc. in HTML.</xsd:documentation>
        </xsd:annotation>
      </xsd:enumeration>
      <xsd:enumeration value="hedit">
        <xsd:annotation>
          <xsd:documentation>Indicates a Windows RC HEDIT control.</xsd:documentation>
        </xsd:annotation>
      </xsd:enumeration>
      <xsd:enumeration value="hscrollbar">
        <xsd:annotation>
          <xsd:documentation>Indicates a horizontal scrollbar.</xsd:documentation>
        </xsd:annotation>
      </xsd:enumeration>
      <xsd:enumeration value="icon">
        <xsd:annotation>
          <xsd:documentation>Indicates an icon, for example an ICON resource in Windows.</xsd:documentation>
        </xsd:annotation>
      </xsd:enumeration>
      <xsd:enumeration value="iedit">
        <xsd:annotation>
          <xsd:documentation>Indicates a Windows RC IEDIT control.</xsd:documentation>
        </xsd:annotation>
      </xsd:enumeration>
      <xsd:enumeration value="keywords">
        <xsd:annotation>
          <xsd:documentation>Indicates keyword list, such as the content of the Keywords meta-data in HTML, or a K footnote in WinHelp RTF.</xsd:documentation>
        </xsd:annotation>
      </xsd:enumeration>
      <xsd:enumeration value="label">
        <xsd:annotation>
          <xsd:documentation>Indicates a label object.</xsd:documentation>
        </xsd:annotation>
      </xsd:enumeration>
      <xsd:enumeration value="linklabel">
        <xsd:annotation>
          <xsd:documentation>Indicates a label that is also a HTML link (not necessarily a URL).</xsd:documentation>
        </xsd:annotation>
      </xsd:enumeration>
      <xsd:enumeration value="list">
        <xsd:annotation>
          <xsd:documentation>Indicates a list (a group of list-items, for example an &lt;ol&gt; or &lt;ul&gt; element in HTML).</xsd:documentation>
        </xsd:annotation>
      </xsd:enumeration>
      <xsd:enumeration value="listbox">
        <xsd:annotation>
          <xsd:documentation>Indicates a listbox object, for example an LISTBOX control in Windows.</xsd:documentation>
        </xsd:annotation>
      </xsd:enumeration>
      <xsd:enumeration value="listitem">
        <xsd:annotation>
          <xsd:documentation>Indicates an list item (an entry in a list).</xsd:documentation>
        </xsd:annotation>
      </xsd:enumeration>
      <xsd:enumeration value="ltext">
        <xsd:annotation>
          <xsd:documentation>Indicates a Windows RC LTEXT control.</xsd:documentation>
        </xsd:annotation>
      </xsd:enumeration>
      <xsd:enumeration value="menu">
        <xsd:annotation>
          <xsd:documentation>Indicates a menu (a group of menu-items).</xsd:documentation>
        </xsd:annotation>
      </xsd:enumeration>
      <xsd:enumeration value="menubar">
        <xsd:annotation>
          <xsd:documentation>Indicates a toolbar containing one or more tope level menus.</xsd:documentation>
        </xsd:annotation>
      </xsd:enumeration>
      <xsd:enumeration value="menuitem">
        <xsd:annotation>
          <xsd:documentation>Indicates a menu item (an entry in a menu).</xsd:documentation>
        </xsd:annotation>
      </xsd:enumeration>
      <xsd:enumeration value="menuseparator">
        <xsd:annotation>
          <xsd:documentation>Indicates a XUL menuseparator element.</xsd:documentation>
        </xsd:annotation>
      </xsd:enumeration>
      <xsd:enumeration value="message">
        <xsd:annotation>
          <xsd:documentation>Indicates a message, for example an entry in a MESSAGETABLE resource in Windows.</xsd:documentation>
        </xsd:annotation>
      </xsd:enumeration>
      <xsd:enumeration value="monthcalendar">
        <xsd:annotation>
          <xsd:documentation>Indicates a calendar control.</xsd:documentation>
        </xsd:annotation>
      </xsd:enumeration>
      <xsd:enumeration value="numericupdown">
        <xsd:annotation>
          <xsd:documentation>Indicates an edit box beside a spin control.</xsd:documentation>
        </xsd:annotation>
      </xsd:enumeration>
      <xsd:enumeration value="panel">
        <xsd:annotation>
          <xsd:documentation>Indicates a catch all for rectangular areas.</xsd:documentation>
        </xsd:annotation>
      </xsd:enumeration>
      <xsd:enumeration value="popupmenu">
        <xsd:annotation>
          <xsd:documentation>Indicates a standalone menu not necessarily associated with a menubar.</xsd:documentation>
        </xsd:annotation>
      </xsd:enumeration>
      <xsd:enumeration value="pushbox">
        <xsd:annotation>
          <xsd:documentation>Indicates a pushbox object, for example a PUSHBOX control in Windows.</xsd:documentation>
        </xsd:annotation>
      </xsd:enumeration>
      <xsd:enumeration value="pushbutton">
        <xsd:annotation>
          <xsd:documentation>Indicates a Windows RC PUSHBUTTON control.</xsd:documentation>
        </xsd:annotation>
      </xsd:enumeration>
      <xsd:enumeration value="radio">
        <xsd:annotation>
          <xsd:documentation>Indicates a radio button object.</xsd:documentation>
        </xsd:annotation>
      </xsd:enumeration>
      <xsd:enumeration value="radiobuttonmenuitem">
        <xsd:annotation>
          <xsd:documentation>Indicates a menuitem with associated radio button.</xsd:documentation>
        </xsd:annotation>
      </xsd:enumeration>
      <xsd:enumeration value="rcdata">
        <xsd:annotation>
          <xsd:documentation>Indicates raw data resources for an application.</xsd:documentation>
        </xsd:annotation>
      </xsd:enumeration>
      <xsd:enumeration value="row">
        <xsd:annotation>
          <xsd:documentation>Indicates a row in a table.</xsd:documentation>
        </xsd:annotation>
      </xsd:enumeration>
      <xsd:enumeration value="rtext">
        <xsd:annotation>
          <xsd:documentation>Indicates a Windows RC RTEXT control.</xsd:documentation>
        </xsd:annotation>
      </xsd:enumeration>
      <xsd:enumeration value="scrollpane">
        <xsd:annotation>
          <xsd:documentation>Indicates a user navigable container used to show a portion of a document.</xsd:documentation>
        </xsd:annotation>
      </xsd:enumeration>
      <xsd:enumeration value="separator">
        <xsd:annotation>
          <xsd:documentation>Indicates a generic divider object (e.g. menu group separator).</xsd:documentation>
        </xsd:annotation>
      </xsd:enumeration>
      <xsd:enumeration value="shortcut">
        <xsd:annotation>
          <xsd:documentation>Windows accelerators, shortcuts in resource or property files.</xsd:documentation>
        </xsd:annotation>
      </xsd:enumeration>
      <xsd:enumeration value="spinner">
        <xsd:annotation>
          <xsd:documentation>Indicates a UI control to indicate process activity but not progress.</xsd:documentation>
        </xsd:annotation>
      </xsd:enumeration>
      <xsd:enumeration value="splitter">
        <xsd:annotation>
          <xsd:documentation>Indicates a splitter bar.</xsd:documentation>
        </xsd:annotation>
      </xsd:enumeration>
      <xsd:enumeration value="state3">
        <xsd:annotation>
          <xsd:documentation>Indicates a Windows RC STATE3 control.</xsd:documentation>
        </xsd:annotation>
      </xsd:enumeration>
      <xsd:enumeration value="statusbar">
        <xsd:annotation>
          <xsd:documentation>Indicates a window for providing feedback to the users, like 'read-only', etc.</xsd:documentation>
        </xsd:annotation>
      </xsd:enumeration>
      <xsd:enumeration value="string">
        <xsd:annotation>
          <xsd:documentation>Indicates a string, for example an entry in a STRINGTABLE resource in Windows.</xsd:documentation>
        </xsd:annotation>
      </xsd:enumeration>
      <xsd:enumeration value="tabcontrol">
        <xsd:annotation>
          <xsd:documentation>Indicates a layers of controls with a tab to select layers.</xsd:documentation>
        </xsd:annotation>
      </xsd:enumeration>
      <xsd:enumeration value="table">
        <xsd:annotation>
          <xsd:documentation>Indicates a display and edits regular two-dimensional tables of cells.</xsd:documentation>
        </xsd:annotation>
      </xsd:enumeration>
      <xsd:enumeration value="textbox">
        <xsd:annotation>
          <xsd:documentation>Indicates a XUL textbox element.</xsd:documentation>
        </xsd:annotation>
      </xsd:enumeration>
      <xsd:enumeration value="togglebutton">
        <xsd:annotation>
          <xsd:documentation>Indicates a UI button that can be toggled to on or off state.</xsd:documentation>
        </xsd:annotation>
      </xsd:enumeration>
      <xsd:enumeration value="toolbar">
        <xsd:annotation>
          <xsd:documentation>Indicates an array of controls, usually buttons.</xsd:documentation>
        </xsd:annotation>
      </xsd:enumeration>
      <xsd:enumeration value="tooltip">
        <xsd:annotation>
          <xsd:documentation>Indicates a pop up tool tip text.</xsd:documentation>
        </xsd:annotation>
      </xsd:enumeration>
      <xsd:enumeration value="trackbar">
        <xsd:annotation>
          <xsd:documentation>Indicates a bar with a pointer indicating a position within a certain range.</xsd:documentation>
        </xsd:annotation>
      </xsd:enumeration>
      <xsd:enumeration value="tree">
        <xsd:annotation>
          <xsd:documentation>Indicates a control that displays a set of hierarchical data.</xsd:documentation>
        </xsd:annotation>
      </xsd:enumeration>
      <xsd:enumeration value="uri">
        <xsd:annotation>
          <xsd:documentation>Indicates a URI (URN or URL).</xsd:documentation>
        </xsd:annotation>
      </xsd:enumeration>
      <xsd:enumeration value="userbutton">
        <xsd:annotation>
          <xsd:documentation>Indicates a Windows RC USERBUTTON control.</xsd:documentation>
        </xsd:annotation>
      </xsd:enumeration>
      <xsd:enumeration value="usercontrol">
        <xsd:annotation>
          <xsd:documentation>Indicates a user-defined control like CONTROL control in Windows.</xsd:documentation>
        </xsd:annotation>
      </xsd:enumeration>
      <xsd:enumeration value="var">
        <xsd:annotation>
          <xsd:documentation>Indicates the text of a variable.</xsd:documentation>
        </xsd:annotation>
      </xsd:enumeration>
      <xsd:enumeration value="versioninfo">
        <xsd:annotation>
          <xsd:documentation>Indicates version information about a resource like VERSIONINFO in Windows.</xsd:documentation>
        </xsd:annotation>
      </xsd:enumeration>
      <xsd:enumeration value="vscrollbar">
        <xsd:annotation>
          <xsd:documentation>Indicates a vertical scrollbar.</xsd:documentation>
        </xsd:annotation>
      </xsd:enumeration>
      <xsd:enumeration value="window">
        <xsd:annotation>
          <xsd:documentation>Indicates a graphical window.</xsd:documentation>
        </xsd:annotation>
      </xsd:enumeration>
    </xsd:restriction>
  </xsd:simpleType>
  <xsd:simpleType name="size-unitValueList">
    <xsd:annotation>
      <xsd:documentation>Values for the attribute 'size-unit'.</xsd:documentation>
    </xsd:annotation>
    <xsd:restriction base="xsd:NMTOKEN">
      <xsd:enumeration value="byte">
        <xsd:annotation>
          <xsd:documentation>Indicates a size in 8-bit bytes.</xsd:documentation>
        </xsd:annotation>
      </xsd:enumeration>
      <xsd:enumeration value="char">
        <xsd:annotation>
          <xsd:documentation>Indicates a size in Unicode characters.</xsd:documentation>
        </xsd:annotation>
      </xsd:enumeration>
      <xsd:enumeration value="col">
        <xsd:annotation>
          <xsd:documentation>Indicates a size in columns. Used for HTML text area.</xsd:documentation>
        </xsd:annotation>
      </xsd:enumeration>
      <xsd:enumeration value="cm">
        <xsd:annotation>
          <xsd:documentation>Indicates a size in centimeters.</xsd:documentation>
        </xsd:annotation>
      </xsd:enumeration>
      <xsd:enumeration value="dlgunit">
        <xsd:annotation>
          <xsd:documentation>Indicates a size in dialog units, as defined in Windows resources.</xsd:documentation>
        </xsd:annotation>
      </xsd:enumeration>
      <xsd:enumeration value="em">
        <xsd:annotation>
          <xsd:documentation>Indicates a size in 'font-size' units (as defined in CSS).</xsd:documentation>
        </xsd:annotation>
      </xsd:enumeration>
      <xsd:enumeration value="ex">
        <xsd:annotation>
          <xsd:documentation>Indicates a size in 'x-height' units (as defined in CSS).</xsd:documentation>
        </xsd:annotation>
      </xsd:enumeration>
      <xsd:enumeration value="glyph">
        <xsd:annotation>
          <xsd:documentation>Indicates a size in glyphs. A glyph is considered to be one or more combined Unicode characters that represent a single displayable text character. Sometimes referred to as a 'grapheme cluster'</xsd:documentation>
        </xsd:annotation>
      </xsd:enumeration>
      <xsd:enumeration value="in">
        <xsd:annotation>
          <xsd:documentation>Indicates a size in inches.</xsd:documentation>
        </xsd:annotation>
      </xsd:enumeration>
      <xsd:enumeration value="mm">
        <xsd:annotation>
          <xsd:documentation>Indicates a size in millimeters.</xsd:documentation>
        </xsd:annotation>
      </xsd:enumeration>
      <xsd:enumeration value="percent">
        <xsd:annotation>
          <xsd:documentation>Indicates a size in percentage.</xsd:documentation>
        </xsd:annotation>
      </xsd:enumeration>
      <xsd:enumeration value="pixel">
        <xsd:annotation>
          <xsd:documentation>Indicates a size in pixels.</xsd:documentation>
        </xsd:annotation>
      </xsd:enumeration>
      <xsd:enumeration value="point">
        <xsd:annotation>
          <xsd:documentation>Indicates a size in point.</xsd:documentation>
        </xsd:annotation>
      </xsd:enumeration>
      <xsd:enumeration value="row">
        <xsd:annotation>
          <xsd:documentation>Indicates a size in rows. Used for HTML text area.</xsd:documentation>
        </xsd:annotation>
      </xsd:enumeration>
    </xsd:restriction>
  </xsd:simpleType>
  <xsd:simpleType name="stateValueList">
    <xsd:annotation>
      <xsd:documentation>Values for the attribute 'state'.</xsd:documentation>
    </xsd:annotation>
    <xsd:restriction base="xsd:NMTOKEN">
      <xsd:enumeration value="final">
        <xsd:annotation>
          <xsd:documentation>Indicates the terminating state.</xsd:documentation>
        </xsd:annotation>
      </xsd:enumeration>
      <xsd:enumeration value="needs-adaptation">
        <xsd:annotation>
          <xsd:documentation>Indicates only non-textual information needs adaptation.</xsd:documentation>
        </xsd:annotation>
      </xsd:enumeration>
      <xsd:enumeration value="needs-l10n">
        <xsd:annotation>
          <xsd:documentation>Indicates both text and non-textual information needs adaptation.</xsd:documentation>
        </xsd:annotation>
      </xsd:enumeration>
      <xsd:enumeration value="needs-review-adaptation">
        <xsd:annotation>
          <xsd:documentation>Indicates only non-textual information needs review.</xsd:documentation>
        </xsd:annotation>
      </xsd:enumeration>
      <xsd:enumeration value="needs-review-l10n">
        <xsd:annotation>
          <xsd:documentation>Indicates both text and non-textual information needs review.</xsd:documentation>
        </xsd:annotation>
      </xsd:enumeration>
      <xsd:enumeration value="needs-review-translation">
        <xsd:annotation>
          <xsd:documentation>Indicates that only the text of the item needs to be reviewed.</xsd:documentation>
        </xsd:annotation>
      </xsd:enumeration>
      <xsd:enumeration value="needs-translation">
        <xsd:annotation>
          <xsd:documentation>Indicates that the item needs to be translated.</xsd:documentation>
        </xsd:annotation>
      </xsd:enumeration>
      <xsd:enumeration value="new">
        <xsd:annotation>
          <xsd:documentation>Indicates that the item is new. For example, translation units that were not in a previous version of the document.</xsd:documentation>
        </xsd:annotation>
      </xsd:enumeration>
      <xsd:enumeration value="signed-off">
        <xsd:annotation>
          <xsd:documentation>Indicates that changes are reviewed and approved.</xsd:documentation>
        </xsd:annotation>
      </xsd:enumeration>
      <xsd:enumeration value="translated">
        <xsd:annotation>
          <xsd:documentation>Indicates that the item has been translated.</xsd:documentation>
        </xsd:annotation>
      </xsd:enumeration>
    </xsd:restriction>
  </xsd:simpleType>
  <xsd:simpleType name="state-qualifierValueList">
    <xsd:annotation>
      <xsd:documentation>Values for the attribute 'state-qualifier'.</xsd:documentation>
    </xsd:annotation>
    <xsd:restriction base="xsd:NMTOKEN">
      <xsd:enumeration value="exact-match">
        <xsd:annotation>
          <xsd:documentation>Indicates an exact match. An exact match occurs when a source text of a segment is exactly the same as the source text of a segment that was translated previously.</xsd:documentation>
        </xsd:annotation>
      </xsd:enumeration>
      <xsd:enumeration value="fuzzy-match">
        <xsd:annotation>
          <xsd:documentation>Indicates a fuzzy match. A fuzzy match occurs when a source text of a segment is very similar to the source text of a segment that was translated previously (e.g. when the difference is casing, a few changed words, white-space discripancy, etc.).</xsd:documentation>
        </xsd:annotation>
      </xsd:enumeration>
      <xsd:enumeration value="id-match">
        <xsd:annotation>
          <xsd:documentation>Indicates a match based on matching IDs (in addition to matching text).</xsd:documentation>
        </xsd:annotation>
      </xsd:enumeration>
      <xsd:enumeration value="leveraged-glossary">
        <xsd:annotation>
          <xsd:documentation>Indicates a translation derived from a glossary.</xsd:documentation>
        </xsd:annotation>
      </xsd:enumeration>
      <xsd:enumeration value="leveraged-inherited">
        <xsd:annotation>
          <xsd:documentation>Indicates a translation derived from existing translation.</xsd:documentation>
        </xsd:annotation>
      </xsd:enumeration>
      <xsd:enumeration value="leveraged-mt">
        <xsd:annotation>
          <xsd:documentation>Indicates a translation derived from machine translation.</xsd:documentation>
        </xsd:annotation>
      </xsd:enumeration>
      <xsd:enumeration value="leveraged-repository">
        <xsd:annotation>
          <xsd:documentation>Indicates a translation derived from a translation repository.</xsd:documentation>
        </xsd:annotation>
      </xsd:enumeration>
      <xsd:enumeration value="leveraged-tm">
        <xsd:annotation>
          <xsd:documentation>Indicates a translation derived from a translation memory.</xsd:documentation>
        </xsd:annotation>
      </xsd:enumeration>
      <xsd:enumeration value="mt-suggestion">
        <xsd:annotation>
          <xsd:documentation>Indicates the translation is suggested by machine translation.</xsd:documentation>
        </xsd:annotation>
      </xsd:enumeration>
      <xsd:enumeration value="rejected-grammar">
        <xsd:annotation>
          <xsd:documentation>Indicates that the item has been rejected because of incorrect grammar.</xsd:documentation>
        </xsd:annotation>
      </xsd:enumeration>
      <xsd:enumeration value="rejected-inaccurate">
        <xsd:annotation>
          <xsd:documentation>Indicates that the item has been rejected because it is incorrect.</xsd:documentation>
        </xsd:annotation>
      </xsd:enumeration>
      <xsd:enumeration value="rejected-length">
        <xsd:annotation>
          <xsd:documentation>Indicates that the item has been rejected because it is too long or too short.</xsd:documentation>
        </xsd:annotation>
      </xsd:enumeration>
      <xsd:enumeration value="rejected-spelling">
        <xsd:annotation>
          <xsd:documentation>Indicates that the item has been rejected because of incorrect spelling.</xsd:documentation>
        </xsd:annotation>
      </xsd:enumeration>
      <xsd:enumeration value="tm-suggestion">
        <xsd:annotation>
          <xsd:documentation>Indicates the translation is suggested by translation memory.</xsd:documentation>
        </xsd:annotation>
      </xsd:enumeration>
    </xsd:restriction>
  </xsd:simpleType>
  <xsd:simpleType name="unitValueList">
    <xsd:annotation>
      <xsd:documentation>Values for the attribute 'unit'.</xsd:documentation>
    </xsd:annotation>
    <xsd:restriction base="xsd:NMTOKEN">
      <xsd:enumeration value="word">
        <xsd:annotation>
          <xsd:documentation>Refers to words.</xsd:documentation>
        </xsd:annotation>
      </xsd:enumeration>
      <xsd:enumeration value="page">
        <xsd:annotation>
          <xsd:documentation>Refers to pages.</xsd:documentation>
        </xsd:annotation>
      </xsd:enumeration>
      <xsd:enumeration value="trans-unit">
        <xsd:annotation>
          <xsd:documentation>Refers to &lt;trans-unit&gt; elements.</xsd:documentation>
        </xsd:annotation>
      </xsd:enumeration>
      <xsd:enumeration value="bin-unit">
        <xsd:annotation>
          <xsd:documentation>Refers to &lt;bin-unit&gt; elements.</xsd:documentation>
        </xsd:annotation>
      </xsd:enumeration>
      <xsd:enumeration value="glyph">
        <xsd:annotation>
          <xsd:documentation>Refers to glyphs.</xsd:documentation>
        </xsd:annotation>
      </xsd:enumeration>
      <xsd:enumeration value="item">
        <xsd:annotation>
          <xsd:documentation>Refers to &lt;trans-unit&gt; and/or &lt;bin-unit&gt; elements.</xsd:documentation>
        </xsd:annotation>
      </xsd:enumeration>
      <xsd:enumeration value="instance">
        <xsd:annotation>
          <xsd:documentation>Refers to the occurrences of instances defined by the count-type value.</xsd:documentation>
        </xsd:annotation>
      </xsd:enumeration>
      <xsd:enumeration value="character">
        <xsd:annotation>
          <xsd:documentation>Refers to characters.</xsd:documentation>
        </xsd:annotation>
      </xsd:enumeration>
      <xsd:enumeration value="line">
        <xsd:annotation>
          <xsd:documentation>Refers to lines.</xsd:documentation>
        </xsd:annotation>
      </xsd:enumeration>
      <xsd:enumeration value="sentence">
        <xsd:annotation>
          <xsd:documentation>Refers to sentences.</xsd:documentation>
        </xsd:annotation>
      </xsd:enumeration>
      <xsd:enumeration value="paragraph">
        <xsd:annotation>
          <xsd:documentation>Refers to paragraphs.</xsd:documentation>
        </xsd:annotation>
      </xsd:enumeration>
      <xsd:enumeration value="segment">
        <xsd:annotation>
          <xsd:documentation>Refers to segments.</xsd:documentation>
        </xsd:annotation>
      </xsd:enumeration>
      <xsd:enumeration value="placeable">
        <xsd:annotation>
          <xsd:documentation>Refers to placeables (inline elements).</xsd:documentation>
        </xsd:annotation>
      </xsd:enumeration>
    </xsd:restriction>
  </xsd:simpleType>
  <xsd:simpleType name="priorityValueList">
    <xsd:annotation>
      <xsd:documentation>Values for the attribute 'priority'.</xsd:documentation>
    </xsd:annotation>
    <xsd:restriction base="xsd:positiveInteger">
      <xsd:enumeration value="1">
        <xsd:annotation>
          <xsd:documentation>Highest priority.</xsd:documentation>
        </xsd:annotation>
      </xsd:enumeration>
      <xsd:enumeration value="2">
        <xsd:annotation>
          <xsd:documentation>High priority.</xsd:documentation>
        </xsd:annotation>
      </xsd:enumeration>
      <xsd:enumeration value="3">
        <xsd:annotation>
          <xsd:documentation>High priority, but not as important as 2.</xsd:documentation>
        </xsd:annotation>
      </xsd:enumeration>
      <xsd:enumeration value="4">
        <xsd:annotation>
          <xsd:documentation>High priority, but not as important as 3.</xsd:documentation>
        </xsd:annotation>
      </xsd:enumeration>
      <xsd:enumeration value="5">
        <xsd:annotation>
          <xsd:documentation>Medium priority, but more important than 6.</xsd:documentation>
        </xsd:annotation>
      </xsd:enumeration>
      <xsd:enumeration value="6">
        <xsd:annotation>
          <xsd:documentation>Medium priority, but less important than 5.</xsd:documentation>
        </xsd:annotation>
      </xsd:enumeration>
      <xsd:enumeration value="7">
        <xsd:annotation>
          <xsd:documentation>Low priority, but more important than 8.</xsd:documentation>
        </xsd:annotation>
      </xsd:enumeration>
      <xsd:enumeration value="8">
        <xsd:annotation>
          <xsd:documentation>Low priority, but more important than 9.</xsd:documentation>
        </xsd:annotation>
      </xsd:enumeration>
      <xsd:enumeration value="9">
        <xsd:annotation>
          <xsd:documentation>Low priority.</xsd:documentation>
        </xsd:annotation>
      </xsd:enumeration>
      <xsd:enumeration value="10">
        <xsd:annotation>
          <xsd:documentation>Lowest priority.</xsd:documentation>
        </xsd:annotation>
      </xsd:enumeration>
    </xsd:restriction>
  </xsd:simpleType>
  <xsd:simpleType name="reformatValueYesNo">
    <xsd:restriction base="xsd:string">
      <xsd:enumeration value="yes">
        <xsd:annotation>
          <xsd:documentation>This value indicates that all properties can be reformatted. This value must be used alone.</xsd:documentation>
        </xsd:annotation>
      </xsd:enumeration>
      <xsd:enumeration value="no">
        <xsd:annotation>
          <xsd:documentation>This value indicates that no properties should be reformatted. This value must be used alone.</xsd:documentation>
        </xsd:annotation>
      </xsd:enumeration>
    </xsd:restriction>
  </xsd:simpleType>
  <xsd:simpleType name="reformatValueList">
    <xsd:list>
      <xsd:simpleType>
        <xsd:union memberTypes="xlf:XTend">
          <xsd:simpleType>
            <xsd:restriction base="xsd:string">
              <xsd:enumeration value="coord">
                <xsd:annotation>
                  <xsd:documentation>This value indicates that all information in the coord attribute can be modified.</xsd:documentation>
                </xsd:annotation>
              </xsd:enumeration>
              <xsd:enumeration value="coord-x">
                <xsd:annotation>
                  <xsd:documentation>This value indicates that the x information in the coord attribute can be modified.</xsd:documentation>
                </xsd:annotation>
              </xsd:enumeration>
              <xsd:enumeration value="coord-y">
                <xsd:annotation>
                  <xsd:documentation>This value indicates that the y information in the coord attribute can be modified.</xsd:documentation>
                </xsd:annotation>
              </xsd:enumeration>
              <xsd:enumeration value="coord-cx">
                <xsd:annotation>
                  <xsd:documentation>This value indicates that the cx information in the coord attribute can be modified.</xsd:documentation>
                </xsd:annotation>
              </xsd:enumeration>
              <xsd:enumeration value="coord-cy">
                <xsd:annotation>
                  <xsd:documentation>This value indicates that the cy information in the coord attribute can be modified.</xsd:documentation>
                </xsd:annotation>
              </xsd:enumeration>
              <xsd:enumeration value="font">
                <xsd:annotation>
                  <xsd:documentation>This value indicates that all the information in the font attribute can be modified.</xsd:documentation>
                </xsd:annotation>
              </xsd:enumeration>
              <xsd:enumeration value="font-name">
                <xsd:annotation>
                  <xsd:documentation>This value indicates that the name information in the font attribute can be modified.</xsd:documentation>
                </xsd:annotation>
              </xsd:enumeration>
              <xsd:enumeration value="font-size">
                <xsd:annotation>
                  <xsd:documentation>This value indicates that the size information in the font attribute can be modified.</xsd:documentation>
                </xsd:annotation>
              </xsd:enumeration>
              <xsd:enumeration value="font-weight">
                <xsd:annotation>
                  <xsd:documentation>This value indicates that the weight information in the font attribute can be modified.</xsd:documentation>
                </xsd:annotation>
              </xsd:enumeration>
              <xsd:enumeration value="css-style">
                <xsd:annotation>
                  <xsd:documentation>This value indicates that the information in the css-style attribute can be modified.</xsd:documentation>
                </xsd:annotation>
              </xsd:enumeration>
              <xsd:enumeration value="style">
                <xsd:annotation>
                  <xsd:documentation>This value indicates that the information in the style attribute can be modified.</xsd:documentation>
                </xsd:annotation>
              </xsd:enumeration>
              <xsd:enumeration value="ex-style">
                <xsd:annotation>
                  <xsd:documentation>This value indicates that the information in the exstyle attribute can be modified.</xsd:documentation>
                </xsd:annotation>
              </xsd:enumeration>
            </xsd:restriction>
          </xsd:simpleType>
        </xsd:union>
      </xsd:simpleType>
    </xsd:list>
  </xsd:simpleType>
  <xsd:simpleType name="purposeValueList">
    <xsd:restriction base="xsd:string">
      <xsd:enumeration value="information">
        <xsd:annotation>
          <xsd:documentation>Indicates that the context is informational in nature, specifying for example, how a term should be translated. Thus, should be displayed to anyone editing the XLIFF document.</xsd:documentation>
        </xsd:annotation>
      </xsd:enumeration>
      <xsd:enumeration value="location">
        <xsd:annotation>
          <xsd:documentation>Indicates that the context-group is used to specify where the term was found in the translatable source. Thus, it is not displayed.</xsd:documentation>
        </xsd:annotation>
      </xsd:enumeration>
      <xsd:enumeration value="match">
        <xsd:annotation>
          <xsd:documentation>Indicates that the context information should be used during translation memory lookups. Thus, it is not displayed.</xsd:documentation>
        </xsd:annotation>
      </xsd:enumeration>
    </xsd:restriction>
  </xsd:simpleType>
  <xsd:simpleType name="alttranstypeValueList">
    <xsd:restriction base="xsd:string">
      <xsd:enumeration value="proposal">
        <xsd:annotation>
          <xsd:documentation>Represents a translation proposal from a translation memory or other resource.</xsd:documentation>
        </xsd:annotation>
      </xsd:enumeration>
      <xsd:enumeration value="previous-version">
        <xsd:annotation>
          <xsd:documentation>Represents a previous version of the target element.</xsd:documentation>
        </xsd:annotation>
      </xsd:enumeration>
      <xsd:enumeration value="rejected">
        <xsd:annotation>
          <xsd:documentation>Represents a rejected version of the target element.</xsd:documentation>
        </xsd:annotation>
      </xsd:enumeration>
      <xsd:enumeration value="reference">
        <xsd:annotation>
          <xsd:documentation>Represents a translation to be used for reference purposes only, for example from a related product or a different language.</xsd:documentation>
        </xsd:annotation>
      </xsd:enumeration>
      <xsd:enumeration value="accepted">
        <xsd:annotation>
          <xsd:documentation>Represents a proposed translation that was used for the translation of the trans-unit, possibly modified.</xsd:documentation>
        </xsd:annotation>
      </xsd:enumeration>
    </xsd:restriction>
  </xsd:simpleType>
  <!-- Other Types -->
  <xsd:complexType name="ElemType_ExternalReference">
    <xsd:choice>
      <xsd:element ref="xlf:internal-file"/>
      <xsd:element ref="xlf:external-file"/>
    </xsd:choice>
  </xsd:complexType>
  <xsd:simpleType name="AttrType_purpose">
    <xsd:list>
      <xsd:simpleType>
        <xsd:union memberTypes="xlf:purposeValueList xlf:XTend"/>
      </xsd:simpleType>
    </xsd:list>
  </xsd:simpleType>
  <xsd:simpleType name="AttrType_datatype">
    <xsd:union memberTypes="xlf:datatypeValueList xlf:XTend"/>
  </xsd:simpleType>
  <xsd:simpleType name="AttrType_restype">
    <xsd:union memberTypes="xlf:restypeValueList xlf:XTend"/>
  </xsd:simpleType>
  <xsd:simpleType name="AttrType_alttranstype">
    <xsd:union memberTypes="xlf:alttranstypeValueList xlf:XTend"/>
  </xsd:simpleType>
  <xsd:simpleType name="AttrType_context-type">
    <xsd:union memberTypes="xlf:context-typeValueList xlf:XTend"/>
  </xsd:simpleType>
  <xsd:simpleType name="AttrType_state">
    <xsd:union memberTypes="xlf:stateValueList xlf:XTend"/>
  </xsd:simpleType>
  <xsd:simpleType name="AttrType_state-qualifier">
    <xsd:union memberTypes="xlf:state-qualifierValueList xlf:XTend"/>
  </xsd:simpleType>
  <xsd:simpleType name="AttrType_count-type">
    <xsd:union memberTypes="xlf:restypeValueList xlf:count-typeValueList xlf:datatypeValueList xlf:stateValueList xlf:state-qualifierValueList xlf:XTend"/>
  </xsd:simpleType>
  <xsd:simpleType name="AttrType_InlineDelimiters">
    <xsd:union memberTypes="xlf:InlineDelimitersValueList xlf:XTend"/>
  </xsd:simpleType>
  <xsd:simpleType name="AttrType_InlinePlaceholders">
    <xsd:union memberTypes="xlf:InlinePlaceholdersValueList xlf:XTend"/>
  </xsd:simpleType>
  <xsd:simpleType name="AttrType_size-unit">
    <xsd:union memberTypes="xlf:size-unitValueList xlf:XTend"/>
  </xsd:simpleType>
  <xsd:simpleType name="AttrType_mtype">
    <xsd:union memberTypes="xlf:mtypeValueList xlf:XTend"/>
  </xsd:simpleType>
  <xsd:simpleType name="AttrType_unit">
    <xsd:union memberTypes="xlf:unitValueList xlf:XTend"/>
  </xsd:simpleType>
  <xsd:simpleType name="AttrType_priority">
    <xsd:union memberTypes="xlf:priorityValueList"/>
  </xsd:simpleType>
  <xsd:simpleType name="AttrType_reformat">
    <xsd:union memberTypes="xlf:reformatValueYesNo xlf:reformatValueList"/>
  </xsd:simpleType>
  <xsd:simpleType name="AttrType_YesNo">
    <xsd:restriction base="xsd:NMTOKEN">
      <xsd:enumeration value="yes"/>
      <xsd:enumeration value="no"/>
    </xsd:restriction>
  </xsd:simpleType>
  <xsd:simpleType name="AttrType_Position">
    <xsd:restriction base="xsd:NMTOKEN">
      <xsd:enumeration value="open"/>
      <xsd:enumeration value="close"/>
    </xsd:restriction>
  </xsd:simpleType>
  <xsd:simpleType name="AttrType_assoc">
    <xsd:restriction base="xsd:NMTOKEN">
      <xsd:enumeration value="preceding"/>
      <xsd:enumeration value="following"/>
      <xsd:enumeration value="both"/>
    </xsd:restriction>
  </xsd:simpleType>
  <xsd:simpleType name="AttrType_annotates">
    <xsd:restriction base="xsd:NMTOKEN">
      <xsd:enumeration value="source"/>
      <xsd:enumeration value="target"/>
      <xsd:enumeration value="general"/>
    </xsd:restriction>
  </xsd:simpleType>
  <xsd:simpleType name="AttrType_Coordinates">
    <xsd:annotation>
      <xsd:documentation>Values for the attribute 'coord'.</xsd:documentation>
    </xsd:annotation>
    <xsd:restriction base="xsd:string">
      <xsd:pattern value="(-?\d+|#);(-?\d+|#);(-?\d+|#);(-?\d+|#)"/>
    </xsd:restriction>
  </xsd:simpleType>
  <xsd:simpleType name="AttrType_Version">
    <xsd:annotation>
      <xsd:documentation>Version values: 1.0 and 1.1 are allowed for backward compatibility.</xsd:documentation>
    </xsd:annotation>
    <xsd:restriction base="xsd:string">
      <xsd:enumeration value="1.2"/>
      <xsd:enumeration value="1.1"/>
      <xsd:enumeration value="1.0"/>
    </xsd:restriction>
  </xsd:simpleType>
  <!-- Groups -->
  <xsd:group name="ElemGroup_TextContent">
    <xsd:choice>
      <xsd:element ref="xlf:g"/>
      <xsd:element ref="xlf:bpt"/>
      <xsd:element ref="xlf:ept"/>
      <xsd:element ref="xlf:ph"/>
      <xsd:element ref="xlf:it"/>
      <xsd:element ref="xlf:mrk"/>
      <xsd:element ref="xlf:x"/>
      <xsd:element ref="xlf:bx"/>
      <xsd:element ref="xlf:ex"/>
    </xsd:choice>
  </xsd:group>
  <xsd:attributeGroup name="AttrGroup_TextContent">
    <xsd:attribute name="id" type="xsd:string" use="required"/>
    <xsd:attribute name="xid" type="xsd:string" use="optional"/>
    <xsd:attribute name="equiv-text" type="xsd:string" use="optional"/>
    <xsd:anyAttribute namespace="##other" processContents="strict"/>
  </xsd:attributeGroup>
  <!-- XLIFF Structure -->
  <xsd:element name="xliff">
    <xsd:complexType>
      <xsd:sequence maxOccurs="unbounded">
        <xsd:any maxOccurs="unbounded" minOccurs="0" namespace="##other" processContents="strict"/>
        <xsd:element ref="xlf:file"/>
      </xsd:sequence>
      <xsd:attribute name="version" type="xlf:AttrType_Version" use="required"/>
      <xsd:attribute ref="xml:lang" use="optional"/>
      <xsd:anyAttribute namespace="##other" processContents="strict"/>
    </xsd:complexType>
  </xsd:element>
  <xsd:element name="file">
    <xsd:complexType>
      <xsd:sequence>
        <xsd:element minOccurs="0" ref="xlf:header"/>
        <xsd:element ref="xlf:body"/>
      </xsd:sequence>
      <xsd:attribute name="original" type="xsd:string" use="required"/>
      <xsd:attribute name="source-language" type="xsd:language" use="required"/>
      <xsd:attribute name="datatype" type="xlf:AttrType_datatype" use="required"/>
      <xsd:attribute name="tool-id" type="xsd:string" use="optional"/>
      <xsd:attribute name="date" type="xsd:dateTime" use="optional"/>
      <xsd:attribute ref="xml:space" use="optional"/>
      <xsd:attribute name="category" type="xsd:string" use="optional"/>
      <xsd:attribute name="target-language" type="xsd:language" use="optional"/>
      <xsd:attribute name="product-name" type="xsd:string" use="optional"/>
      <xsd:attribute name="product-version" type="xsd:string" use="optional"/>
      <xsd:attribute name="build-num" type="xsd:string" use="optional"/>
      <xsd:anyAttribute namespace="##other" processContents="strict"/>
    </xsd:complexType>
    <xsd:unique name="U_group_id">
      <xsd:selector xpath=".//xlf:group"/>
      <xsd:field xpath="@id"/>
    </xsd:unique>
    <xsd:key name="K_unit_id">
      <xsd:selector xpath=".//xlf:trans-unit|.//xlf:bin-unit"/>
      <xsd:field xpath="@id"/>
    </xsd:key>
    <xsd:keyref name="KR_unit_id" refer="xlf:K_unit_id">
      <xsd:selector xpath=".//bpt|.//ept|.//it|.//ph|.//g|.//x|.//bx|.//ex|.//sub"/>
      <xsd:field xpath="@xid"/>
    </xsd:keyref>
    <xsd:key name="K_tool-id">
      <xsd:selector xpath="xlf:header/xlf:tool"/>
      <xsd:field xpath="@tool-id"/>
    </xsd:key>
    <xsd:keyref name="KR_file_tool-id" refer="xlf:K_tool-id">
      <xsd:selector xpath="."/>
      <xsd:field xpath="@tool-id"/>
    </xsd:keyref>
    <xsd:keyref name="KR_phase_tool-id" refer="xlf:K_tool-id">
      <xsd:selector xpath="xlf:header/xlf:phase-group/xlf:phase"/>
      <xsd:field xpath="@tool-id"/>
    </xsd:keyref>
    <xsd:keyref name="KR_alt-trans_tool-id" refer="xlf:K_tool-id">
      <xsd:selector xpath=".//xlf:trans-unit/xlf:alt-trans"/>
      <xsd:field xpath="@tool-id"/>
    </xsd:keyref>
    <xsd:key name="K_count-group_name">
      <xsd:selector xpath=".//xlf:count-group"/>
      <xsd:field xpath="@name"/>
    </xsd:key>
    <xsd:unique name="U_context-group_name">
      <xsd:selector xpath=".//xlf:context-group"/>
      <xsd:field xpath="@name"/>
    </xsd:unique>
    <xsd:key name="K_phase-name">
      <xsd:selector xpath="xlf:header/xlf:phase-group/xlf:phase"/>
      <xsd:field xpath="@phase-name"/>
    </xsd:key>
    <xsd:keyref name="KR_phase-name" refer="xlf:K_phase-name">
      <xsd:selector xpath=".//xlf:count|.//xlf:trans-unit|.//xlf:target|.//bin-unit|.//bin-target"/>
      <xsd:field xpath="@phase-name"/>
    </xsd:keyref>
    <xsd:unique name="U_uid">
      <xsd:selector xpath=".//xlf:external-file"/>
      <xsd:field xpath="@uid"/>
    </xsd:unique>
  </xsd:element>
  <xsd:element name="header">
    <xsd:complexType>
      <xsd:sequence>
        <xsd:element minOccurs="0" name="skl" type="xlf:ElemType_ExternalReference"/>
        <xsd:element minOccurs="0" ref="xlf:phase-group"/>
        <xsd:choice maxOccurs="unbounded" minOccurs="0">
          <xsd:element name="glossary" type="xlf:ElemType_ExternalReference"/>
          <xsd:element name="reference" type="xlf:ElemType_ExternalReference"/>
          <xsd:element ref="xlf:count-group"/>
          <xsd:element ref="xlf:note"/>
          <xsd:element ref="xlf:tool"/>
        </xsd:choice>
        <xsd:any maxOccurs="unbounded" minOccurs="0" namespace="##other" processContents="strict"/>
      </xsd:sequence>
    </xsd:complexType>
  </xsd:element>
  <xsd:element name="internal-file">
    <xsd:complexType>
      <xsd:simpleContent>
        <xsd:extension base="xsd:string">
          <xsd:attribute name="form" type="xsd:string"/>
          <xsd:attribute name="crc" type="xsd:NMTOKEN"/>
        </xsd:extension>
      </xsd:simpleContent>
    </xsd:complexType>
  </xsd:element>
  <xsd:element name="external-file">
    <xsd:complexType>
      <xsd:attribute name="href" type="xsd:string" use="required"/>
      <xsd:attribute name="crc" type="xsd:NMTOKEN"/>
      <xsd:attribute name="uid" type="xsd:NMTOKEN"/>
    </xsd:complexType>
  </xsd:element>
  <xsd:element name="note">
    <xsd:complexType>
      <xsd:simpleContent>
        <xsd:extension base="xsd:string">
          <xsd:attribute ref="xml:lang" use="optional"/>
          <xsd:attribute default="1" name="priority" type="xlf:AttrType_priority" use="optional"/>
          <xsd:attribute name="from" type="xsd:string" use="optional"/>
          <xsd:attribute default="general" name="annotates" type="xlf:AttrType_annotates" use="optional"/>
        </xsd:extension>
      </xsd:simpleContent>
    </xsd:complexType>
  </xsd:element>
  <xsd:element name="phase-group">
    <xsd:complexType>
      <xsd:sequence maxOccurs="unbounded">
        <xsd:element ref="xlf:phase"/>
      </xsd:sequence>
    </xsd:complexType>
  </xsd:element>
  <xsd:element name="phase">
    <xsd:complexType>
      <xsd:sequence maxOccurs="unbounded" minOccurs="0">
        <xsd:element ref="xlf:note"/>
      </xsd:sequence>
      <xsd:attribute name="phase-name" type="xsd:string" use="required"/>
      <xsd:attribute name="process-name" type="xsd:string" use="required"/>
      <xsd:attribute name="company-name" type="xsd:string" use="optional"/>
      <xsd:attribute name="tool-id" type="xsd:string" use="optional"/>
      <xsd:attribute name="date" type="xsd:dateTime" use="optional"/>
      <xsd:attribute name="job-id" type="xsd:string" use="optional"/>
      <xsd:attribute name="contact-name" type="xsd:string" use="optional"/>
      <xsd:attribute name="contact-email" type="xsd:string" use="optional"/>
      <xsd:attribute name="contact-phone" type="xsd:string" use="optional"/>
    </xsd:complexType>
  </xsd:element>
  <xsd:element name="count-group">
    <xsd:complexType>
      <xsd:sequence maxOccurs="unbounded" minOccurs="0">
        <xsd:element ref="xlf:count"/>
      </xsd:sequence>
      <xsd:attribute name="name" type="xsd:string" use="required"/>
    </xsd:complexType>
  </xsd:element>
  <xsd:element name="count">
    <xsd:complexType>
      <xsd:simpleContent>
        <xsd:extension base="xsd:string">
          <xsd:attribute name="count-type" type="xlf:AttrType_count-type" use="optional"/>
          <xsd:attribute name="phase-name" type="xsd:string" use="optional"/>
          <xsd:attribute default="word" name="unit" type="xlf:AttrType_unit" use="optional"/>
        </xsd:extension>
      </xsd:simpleContent>
    </xsd:complexType>
  </xsd:element>
  <xsd:element name="context-group">
    <xsd:complexType>
      <xsd:sequence maxOccurs="unbounded">
        <xsd:element ref="xlf:context"/>
      </xsd:sequence>
      <xsd:attribute name="name" type="xsd:string" use="optional"/>
      <xsd:attribute name="crc" type="xsd:NMTOKEN" use="optional"/>
      <xsd:attribute name="purpose" type="xlf:AttrType_purpose" use="optional"/>
    </xsd:complexType>
  </xsd:element>
  <xsd:element name="context">
    <xsd:complexType>
      <xsd:simpleContent>
        <xsd:extension base="xsd:string">
          <xsd:attribute name="context-type" type="xlf:AttrType_context-type" use="required"/>
          <xsd:attribute default="no" name="match-mandatory" type="xlf:AttrType_YesNo" use="optional"/>
          <xsd:attribute name="crc" type="xsd:NMTOKEN" use="optional"/>
        </xsd:extension>
      </xsd:simpleContent>
    </xsd:complexType>
  </xsd:element>
  <xsd:element name="tool">
    <xsd:complexType mixed="true">
      <xsd:sequence>
        <xsd:any namespace="##any" processContents="strict" minOccurs="0" maxOccurs="unbounded"/>
      </xsd:sequence>
      <xsd:attribute name="tool-id" type="xsd:string" use="required"/>
      <xsd:attribute name="tool-name" type="xsd:string" use="required"/>
      <xsd:attribute name="tool-version" type="xsd:string" use="optional"/>
      <xsd:attribute name="tool-company" type="xsd:string" use="optional"/>
      <xsd:anyAttribute namespace="##other" processContents="strict"/>
    </xsd:complexType>
  </xsd:element>
  <xsd:element name="body">
    <xsd:complexType>
      <xsd:choice maxOccurs="unbounded" minOccurs="0">
        <xsd:element maxOccurs="unbounded" minOccurs="0" ref="xlf:group"/>
        <xsd:element maxOccurs="unbounded" minOccurs="0" ref="xlf:trans-unit"/>
        <xsd:element maxOccurs="unbounded" minOccurs="0" ref="xlf:bin-unit"/>
      </xsd:choice>
    </xsd:complexType>
  </xsd:element>
  <xsd:element name="group">
    <xsd:complexType>
      <xsd:sequence>
        <xsd:sequence>
          <xsd:element maxOccurs="unbounded" minOccurs="0" ref="xlf:context-group"/>
          <xsd:element maxOccurs="unbounded" minOccurs="0" ref="xlf:count-group"/>
          <xsd:element maxOccurs="unbounded" minOccurs="0" ref="xlf:note"/>
          <xsd:any maxOccurs="unbounded" minOccurs="0" namespace="##other" processContents="strict"/>
        </xsd:sequence>
        <xsd:choice maxOccurs="unbounded">
          <xsd:element maxOccurs="unbounded" minOccurs="0" ref="xlf:group"/>
          <xsd:element maxOccurs="unbounded" minOccurs="0" ref="xlf:trans-unit"/>
          <xsd:element maxOccurs="unbounded" minOccurs="0" ref="xlf:bin-unit"/>
        </xsd:choice>
      </xsd:sequence>
      <xsd:attribute name="id" type="xsd:string" use="optional"/>
      <xsd:attribute name="datatype" type="xlf:AttrType_datatype" use="optional"/>
      <xsd:attribute default="default" ref="xml:space" use="optional"/>
      <xsd:attribute name="restype" type="xlf:AttrType_restype" use="optional"/>
      <xsd:attribute name="resname" type="xsd:string" use="optional"/>
      <xsd:attribute name="extradata" type="xsd:string" use="optional"/>
      <xsd:attribute name="extype" type="xsd:string" use="optional"/>
      <xsd:attribute name="help-id" type="xsd:NMTOKEN" use="optional"/>
      <xsd:attribute name="menu" type="xsd:string" use="optional"/>
      <xsd:attribute name="menu-option" type="xsd:string" use="optional"/>
      <xsd:attribute name="menu-name" type="xsd:string" use="optional"/>
      <xsd:attribute name="coord" type="xlf:AttrType_Coordinates" use="optional"/>
      <xsd:attribute name="font" type="xsd:string" use="optional"/>
      <xsd:attribute name="css-style" type="xsd:string" use="optional"/>
      <xsd:attribute name="style" type="xsd:NMTOKEN" use="optional"/>
      <xsd:attribute name="exstyle" type="xsd:NMTOKEN" use="optional"/>
      <xsd:attribute default="yes" name="translate" type="xlf:AttrType_YesNo" use="optional"/>
      <xsd:attribute default="yes" name="reformat" type="xlf:AttrType_reformat" use="optional"/>
      <xsd:attribute default="pixel" name="size-unit" type="xlf:AttrType_size-unit" use="optional"/>
      <xsd:attribute name="maxwidth" type="xsd:NMTOKEN" use="optional"/>
      <xsd:attribute name="minwidth" type="xsd:NMTOKEN" use="optional"/>
      <xsd:attribute name="maxheight" type="xsd:NMTOKEN" use="optional"/>
      <xsd:attribute name="minheight" type="xsd:NMTOKEN" use="optional"/>
      <xsd:attribute name="maxbytes" type="xsd:NMTOKEN" use="optional"/>
      <xsd:attribute name="minbytes" type="xsd:NMTOKEN" use="optional"/>
      <xsd:attribute name="charclass" type="xsd:string" use="optional"/>
      <xsd:attribute default="no" name="merged-trans" type="xlf:AttrType_YesNo" use="optional"/>
      <xsd:anyAttribute namespace="##other" processContents="strict"/>
    </xsd:complexType>
  </xsd:element>
  <xsd:element name="trans-unit">
    <xsd:complexType>
      <xsd:sequence>
        <xsd:element ref="xlf:source"/>
        <xsd:element minOccurs="0" ref="xlf:seg-source"/>
        <xsd:element minOccurs="0" ref="xlf:target"/>
        <xsd:choice maxOccurs="unbounded" minOccurs="0">
          <xsd:element ref="xlf:context-group"/>
          <xsd:element ref="xlf:count-group"/>
          <xsd:element ref="xlf:note"/>
          <xsd:element ref="xlf:alt-trans"/>
        </xsd:choice>
        <xsd:any maxOccurs="unbounded" minOccurs="0" namespace="##other" processContents="strict"/>
      </xsd:sequence>
      <xsd:attribute name="id" type="xsd:string" use="required"/>
      <xsd:attribute name="approved" type="xlf:AttrType_YesNo" use="optional"/>
      <xsd:attribute default="yes" name="translate" type="xlf:AttrType_YesNo" use="optional"/>
      <xsd:attribute default="yes" name="reformat" type="xlf:AttrType_reformat" use="optional"/>
      <xsd:attribute default="default" ref="xml:space" use="optional"/>
      <xsd:attribute name="datatype" type="xlf:AttrType_datatype" use="optional"/>
      <xsd:attribute name="phase-name" type="xsd:string" use="optional"/>
      <xsd:attribute name="restype" type="xlf:AttrType_restype" use="optional"/>
      <xsd:attribute name="resname" type="xsd:string" use="optional"/>
      <xsd:attribute name="extradata" type="xsd:string" use="optional"/>
      <xsd:attribute name="extype" type="xsd:string" use="optional"/>
      <xsd:attribute name="help-id" type="xsd:NMTOKEN" use="optional"/>
      <xsd:attribute name="menu" type="xsd:string" use="optional"/>
      <xsd:attribute name="menu-option" type="xsd:string" use="optional"/>
      <xsd:attribute name="menu-name" type="xsd:string" use="optional"/>
      <xsd:attribute name="coord" type="xlf:AttrType_Coordinates" use="optional"/>
      <xsd:attribute name="font" type="xsd:string" use="optional"/>
      <xsd:attribute name="css-style" type="xsd:string" use="optional"/>
      <xsd:attribute name="style" type="xsd:NMTOKEN" use="optional"/>
      <xsd:attribute name="exstyle" type="xsd:NMTOKEN" use="optional"/>
      <xsd:attribute default="pixel" name="size-unit" type="xlf:AttrType_size-unit" use="optional"/>
      <xsd:attribute name="maxwidth" type="xsd:NMTOKEN" use="optional"/>
      <xsd:attribute name="minwidth" type="xsd:NMTOKEN" use="optional"/>
      <xsd:attribute name="maxheight" type="xsd:NMTOKEN" use="optional"/>
      <xsd:attribute name="minheight" type="xsd:NMTOKEN" use="optional"/>
      <xsd:attribute name="maxbytes" type="xsd:NMTOKEN" use="optional"/>
      <xsd:attribute name="minbytes" type="xsd:NMTOKEN" use="optional"/>
      <xsd:attribute name="charclass" type="xsd:string" use="optional"/>
      <xsd:attribute default="yes" name="merged-trans" type="xlf:AttrType_YesNo" use="optional"/>
      <xsd:anyAttribute namespace="##other" processContents="strict"/>
    </xsd:complexType>
    <xsd:unique name="U_tu_segsrc_mid">
      <xsd:selector xpath="./xlf:seg-source/xlf:mrk"/>
      <xsd:field xpath="@mid"/>
    </xsd:unique>
    <xsd:keyref name="KR_tu_segsrc_mid" refer="xlf:U_tu_segsrc_mid">
      <xsd:selector xpath="./xlf:target/xlf:mrk|./xlf:alt-trans"/>
      <xsd:field xpath="@mid"/>
    </xsd:keyref>
  </xsd:element>
  <xsd:element name="source">
    <xsd:complexType mixed="true">
      <xsd:group maxOccurs="unbounded" minOccurs="0" ref="xlf:ElemGroup_TextContent"/>
      <xsd:attribute ref="xml:lang" use="optional"/>
      <xsd:anyAttribute namespace="##other" processContents="strict"/>
    </xsd:complexType>
    <xsd:unique name="U_source_bpt_rid">
      <xsd:selector xpath=".//xlf:bpt"/>
      <xsd:field xpath="@rid"/>
    </xsd:unique>
    <xsd:keyref name="KR_source_ept_rid" refer="xlf:U_source_bpt_rid">
      <xsd:selector xpath=".//xlf:ept"/>
      <xsd:field xpath="@rid"/>
    </xsd:keyref>
    <xsd:unique name="U_source_bx_rid">
      <xsd:selector xpath=".//xlf:bx"/>
      <xsd:field xpath="@rid"/>
    </xsd:unique>
    <xsd:keyref name="KR_source_ex_rid" refer="xlf:U_source_bx_rid">
      <xsd:selector xpath=".//xlf:ex"/>
      <xsd:field xpath="@rid"/>
    </xsd:keyref>
  </xsd:element>
  <xsd:element name="seg-source">
    <xsd:complexType mixed="true">
      <xsd:group maxOccurs="unbounded" minOccurs="0" ref="xlf:ElemGroup_TextContent"/>
      <xsd:attribute ref="xml:lang" use="optional"/>
      <xsd:anyAttribute namespace="##other" processContents="strict"/>
    </xsd:complexType>
    <xsd:unique name="U_segsrc_bpt_rid">
      <xsd:selector xpath=".//xlf:bpt"/>
      <xsd:field xpath="@rid"/>
    </xsd:unique>
    <xsd:keyref name="KR_segsrc_ept_rid" refer="xlf:U_segsrc_bpt_rid">
      <xsd:selector xpath=".//xlf:ept"/>
      <xsd:field xpath="@rid"/>
    </xsd:keyref>
    <xsd:unique name="U_segsrc_bx_rid">
      <xsd:selector xpath=".//xlf:bx"/>
      <xsd:field xpath="@rid"/>
    </xsd:unique>
    <xsd:keyref name="KR_segsrc_ex_rid" refer="xlf:U_segsrc_bx_rid">
      <xsd:selector xpath=".//xlf:ex"/>
      <xsd:field xpath="@rid"/>
    </xsd:keyref>
  </xsd:element>
  <xsd:element name="target">
    <xsd:complexType mixed="true">
      <xsd:group maxOccurs="unbounded" minOccurs="0" ref="xlf:ElemGroup_TextContent"/>
      <xsd:attribute name="state" type="xlf:AttrType_state" use="optional"/>
      <xsd:attribute name="state-qualifier" type="xlf:AttrType_state-qualifier" use="optional"/>
      <xsd:attribute name="phase-name" type="xsd:NMTOKEN" use="optional"/>
      <xsd:attribute ref="xml:lang" use="optional"/>
      <xsd:attribute name="resname" type="xsd:string" use="optional"/>
      <xsd:attribute name="coord" type="xlf:AttrType_Coordinates" use="optional"/>
      <xsd:attribute name="font" type="xsd:string" use="optional"/>
      <xsd:attribute name="css-style" type="xsd:string" use="optional"/>
      <xsd:attribute name="style" type="xsd:NMTOKEN" use="optional"/>
      <xsd:attribute name="exstyle" type="xsd:NMTOKEN" use="optional"/>
      <xsd:attribute default="yes" name="equiv-trans" type="xlf:AttrType_YesNo" use="optional"/>
      <xsd:anyAttribute namespace="##other" processContents="strict"/>
    </xsd:complexType>
    <xsd:unique name="U_target_bpt_rid">
      <xsd:selector xpath=".//xlf:bpt"/>
      <xsd:field xpath="@rid"/>
    </xsd:unique>
    <xsd:keyref name="KR_target_ept_rid" refer="xlf:U_target_bpt_rid">
      <xsd:selector xpath=".//xlf:ept"/>
      <xsd:field xpath="@rid"/>
    </xsd:keyref>
    <xsd:unique name="U_target_bx_rid">
      <xsd:selector xpath=".//xlf:bx"/>
      <xsd:field xpath="@rid"/>
    </xsd:unique>
    <xsd:keyref name="KR_target_ex_rid" refer="xlf:U_target_bx_rid">
      <xsd:selector xpath=".//xlf:ex"/>
      <xsd:field xpath="@rid"/>
    </xsd:keyref>
  </xsd:element>
  <xsd:element name="alt-trans">
    <xsd:complexType>
      <xsd:sequence>
        <xsd:element minOccurs="0" ref="xlf:source"/>
        <xsd:element minOccurs="0" ref="xlf:seg-source"/>
        <xsd:element maxOccurs="1" ref="xlf:target"/>
        <xsd:element maxOccurs="unbounded" minOccurs="0" ref="xlf:context-group"/>
        <xsd:element maxOccurs="unbounded" minOccurs="0" ref="xlf:note"/>
        <xsd:any maxOccurs="unbounded" minOccurs="0" namespace="##other" processContents="strict"/>
      </xsd:sequence>
      <xsd:attribute name="match-quality" type="xsd:string" use="optional"/>
      <xsd:attribute name="tool-id" type="xsd:string" use="optional"/>
      <xsd:attribute name="crc" type="xsd:NMTOKEN" use="optional"/>
      <xsd:attribute ref="xml:lang" use="optional"/>
      <xsd:attribute name="origin" type="xsd:string" use="optional"/>
      <xsd:attribute name="datatype" type="xlf:AttrType_datatype" use="optional"/>
      <xsd:attribute default="default" ref="xml:space" use="optional"/>
      <xsd:attribute name="restype" type="xlf:AttrType_restype" use="optional"/>
      <xsd:attribute name="resname" type="xsd:string" use="optional"/>
      <xsd:attribute name="extradata" type="xsd:string" use="optional"/>
      <xsd:attribute name="extype" type="xsd:string" use="optional"/>
      <xsd:attribute name="help-id" type="xsd:NMTOKEN" use="optional"/>
      <xsd:attribute name="menu" type="xsd:string" use="optional"/>
      <xsd:attribute name="menu-option" type="xsd:string" use="optional"/>
      <xsd:attribute name="menu-name" type="xsd:string" use="optional"/>
      <xsd:attribute name="mid" type="xsd:NMTOKEN" use="optional"/>
      <xsd:attribute name="coord" type="xlf:AttrType_Coordinates" use="optional"/>
      <xsd:attribute name="font" type="xsd:string" use="optional"/>
      <xsd:attribute name="css-style" type="xsd:string" use="optional"/>
      <xsd:attribute name="style" type="xsd:NMTOKEN" use="optional"/>
      <xsd:attribute name="exstyle" type="xsd:NMTOKEN" use="optional"/>
      <xsd:attribute name="phase-name" type="xsd:NMTOKEN" use="optional"/>
      <xsd:attribute default="proposal" name="alttranstype" type="xlf:AttrType_alttranstype" use="optional"/>
      <xsd:anyAttribute namespace="##other" processContents="strict"/>
    </xsd:complexType>
    <xsd:unique name="U_at_segsrc_mid">
      <xsd:selector xpath="./xlf:seg-source/xlf:mrk"/>
      <xsd:field xpath="@mid"/>
    </xsd:unique>
    <xsd:keyref name="KR_at_segsrc_mid" refer="xlf:U_at_segsrc_mid">
      <xsd:selector xpath="./xlf:target/xlf:mrk"/>
      <xsd:field xpath="@mid"/>
    </xsd:keyref>
  </xsd:element>
  <xsd:element name="bin-unit">
    <xsd:complexType>
      <xsd:sequence>
        <xsd:element ref="xlf:bin-source"/>
        <xsd:element minOccurs="0" ref="xlf:bin-target"/>
        <xsd:choice maxOccurs="unbounded" minOccurs="0">
          <xsd:element ref="xlf:context-group"/>
          <xsd:element ref="xlf:count-group"/>
          <xsd:element ref="xlf:note"/>
          <xsd:element ref="xlf:trans-unit"/>
        </xsd:choice>
        <xsd:any maxOccurs="unbounded" minOccurs="0" namespace="##other" processContents="strict"/>
      </xsd:sequence>
      <xsd:attribute name="id" type="xsd:string" use="required"/>
      <xsd:attribute name="mime-type" type="xlf:mime-typeValueList" use="required"/>
      <xsd:attribute name="approved" type="xlf:AttrType_YesNo" use="optional"/>
      <xsd:attribute default="yes" name="translate" type="xlf:AttrType_YesNo" use="optional"/>
      <xsd:attribute default="yes" name="reformat" type="xlf:AttrType_reformat" use="optional"/>
      <xsd:attribute name="restype" type="xlf:AttrType_restype" use="optional"/>
      <xsd:attribute name="resname" type="xsd:string" use="optional"/>
      <xsd:attribute name="phase-name" type="xsd:string" use="optional"/>
      <xsd:anyAttribute namespace="##other" processContents="strict"/>
    </xsd:complexType>
  </xsd:element>
  <xsd:element name="bin-source">
    <xsd:complexType>
      <xsd:choice>
        <xsd:element ref="xlf:internal-file"/>
        <xsd:element ref="xlf:external-file"/>
      </xsd:choice>
      <xsd:anyAttribute namespace="##other" processContents="strict"/>
    </xsd:complexType>
  </xsd:element>
  <xsd:element name="bin-target">
    <xsd:complexType>
      <xsd:choice>
        <xsd:element ref="xlf:internal-file"/>
        <xsd:element ref="xlf:external-file"/>
      </xsd:choice>
      <xsd:attribute name="mime-type" type="xlf:mime-typeValueList" use="optional"/>
      <xsd:attribute name="state" type="xlf:AttrType_state" use="optional"/>
      <xsd:attribute name="state-qualifier" type="xlf:AttrType_state-qualifier" use="optional"/>
      <xsd:attribute name="phase-name" type="xsd:NMTOKEN" use="optional"/>
      <xsd:attribute name="restype" type="xlf:AttrType_restype" use="optional"/>
      <xsd:attribute name="resname" type="xsd:string" use="optional"/>
      <xsd:anyAttribute namespace="##other" processContents="strict"/>
    </xsd:complexType>
  </xsd:element>
  <!-- Element for inline codes -->
  <xsd:element name="g">
    <xsd:complexType mixed="true">
      <xsd:group maxOccurs="unbounded" minOccurs="0" ref="xlf:ElemGroup_TextContent"/>
      <xsd:attribute name="ctype" type="xlf:AttrType_InlineDelimiters" use="optional"/>
      <xsd:attribute default="yes" name="clone" type="xlf:AttrType_YesNo" use="optional"/>
      <xsd:attributeGroup ref="xlf:AttrGroup_TextContent"/>
    </xsd:complexType>
  </xsd:element>
  <xsd:element name="x">
    <xsd:complexType>
      <xsd:attribute name="ctype" type="xlf:AttrType_InlinePlaceholders" use="optional"/>
      <xsd:attribute default="yes" name="clone" type="xlf:AttrType_YesNo" use="optional"/>
      <xsd:attributeGroup ref="xlf:AttrGroup_TextContent"/>
    </xsd:complexType>
  </xsd:element>
  <xsd:element name="bx">
    <xsd:complexType>
      <xsd:attribute name="rid" type="xsd:NMTOKEN" use="optional"/>
      <xsd:attribute name="ctype" type="xlf:AttrType_InlineDelimiters" use="optional"/>
      <xsd:attribute default="yes" name="clone" type="xlf:AttrType_YesNo" use="optional"/>
      <xsd:attributeGroup ref="xlf:AttrGroup_TextContent"/>
    </xsd:complexType>
  </xsd:element>
  <xsd:element name="ex">
    <xsd:complexType>
      <xsd:attribute name="rid" type="xsd:NMTOKEN" use="optional"/>
      <xsd:attributeGroup ref="xlf:AttrGroup_TextContent"/>
    </xsd:complexType>
  </xsd:element>
  <xsd:element name="ph">
    <xsd:complexType mixed="true">
      <xsd:sequence maxOccurs="unbounded" minOccurs="0">
        <xsd:element ref="xlf:sub"/>
      </xsd:sequence>
      <xsd:attribute name="ctype" type="xlf:AttrType_InlinePlaceholders" use="optional"/>
      <xsd:attribute name="crc" type="xsd:string" use="optional"/>
      <xsd:attribute name="assoc" type="xlf:AttrType_assoc" use="optional"/>
      <xsd:attributeGroup ref="xlf:AttrGroup_TextContent"/>
    </xsd:complexType>
  </xsd:element>
  <xsd:element name="bpt">
    <xsd:complexType mixed="true">
      <xsd:sequence maxOccurs="unbounded" minOccurs="0">
        <xsd:element ref="xlf:sub"/>
      </xsd:sequence>
      <xsd:attribute name="rid" type="xsd:NMTOKEN" use="optional"/>
      <xsd:attribute name="ctype" type="xlf:AttrType_InlineDelimiters" use="optional"/>
      <xsd:attribute name="crc" type="xsd:string" use="optional"/>
      <xsd:attributeGroup ref="xlf:AttrGroup_TextContent"/>
    </xsd:complexType>
  </xsd:element>
  <xsd:element name="ept">
    <xsd:complexType mixed="true">
      <xsd:sequence maxOccurs="unbounded" minOccurs="0">
        <xsd:element ref="xlf:sub"/>
      </xsd:sequence>
      <xsd:attribute name="rid" type="xsd:NMTOKEN" use="optional"/>
      <xsd:attribute name="crc" type="xsd:string" use="optional"/>
      <xsd:attributeGroup ref="xlf:AttrGroup_TextContent"/>
    </xsd:complexType>
  </xsd:element>
  <xsd:element name="it">
    <xsd:complexType mixed="true">
      <xsd:sequence maxOccurs="unbounded" minOccurs="0">
        <xsd:element ref="xlf:sub"/>
      </xsd:sequence>
      <xsd:attribute name="pos" type="xlf:AttrType_Position" use="required"/>
      <xsd:attribute name="rid" type="xsd:NMTOKEN" use="optional"/>
      <xsd:attribute name="ctype" type="xlf:AttrType_InlineDelimiters" use="optional"/>
      <xsd:attribute name="crc" type="xsd:string" use="optional"/>
      <xsd:attributeGroup ref="xlf:AttrGroup_TextContent"/>
    </xsd:complexType>
  </xsd:element>
  <xsd:element name="sub">
    <xsd:complexType mixed="true">
      <xsd:group maxOccurs="unbounded" minOccurs="0" ref="xlf:ElemGroup_TextContent"/>
      <xsd:attribute name="datatype" type="xlf:AttrType_datatype" use="optional"/>
      <xsd:attribute name="ctype" type="xlf:AttrType_InlineDelimiters" use="optional"/>
      <xsd:attribute name="xid" type="xsd:string" use="optional"/>
    </xsd:complexType>
  </xsd:element>
  <xsd:element name="mrk">
    <xsd:complexType mixed="true">
      <xsd:group maxOccurs="unbounded" minOccurs="0" ref="xlf:ElemGroup_TextContent"/>
      <xsd:attribute name="mtype" type="xlf:AttrType_mtype" use="required"/>
      <xsd:attribute name="mid" type="xsd:NMTOKEN" use="optional"/>
      <xsd:attribute name="comment" type="xsd:string" use="optional"/>
      <xsd:anyAttribute namespace="##other" processContents="strict"/>
    </xsd:complexType>
  </xsd:element>
</xsd:schema>
PKϤ$Z�|�FFtranslation/MessageSelector.phpnu�[���<?php

/*
 * This file is part of the Symfony package.
 *
 * (c) Fabien Potencier <fabien@symfony.com>
 *
 * For the full copyright and license information, please view the LICENSE
 * file that was distributed with this source code.
 */

namespace Symfony\Component\Translation;

/**
 * MessageSelector.
 *
 * @author Fabien Potencier <fabien@symfony.com>
 * @author Bernhard Schussek <bschussek@gmail.com>
 */
class MessageSelector
{
    /**
     * Given a message with different plural translations separated by a
     * pipe (|), this method returns the correct portion of the message based
     * on the given number, locale and the pluralization rules in the message
     * itself.
     *
     * The message supports two different types of pluralization rules:
     *
     * interval: {0} There are no apples|{1} There is one apple|]1,Inf] There are %count% apples
     * indexed:  There is one apple|There are %count% apples
     *
     * The indexed solution can also contain labels (e.g. one: There is one apple).
     * This is purely for making the translations more clear - it does not
     * affect the functionality.
     *
     * The two methods can also be mixed:
     *     {0} There are no apples|one: There is one apple|more: There are %count% apples
     *
     * @param string $message The message being translated
     * @param int    $number  The number of items represented for the message
     * @param string $locale  The locale to use for choosing
     *
     * @return string
     *
     * @throws \InvalidArgumentException
     */
    public function choose($message, $number, $locale)
    {
        $parts = explode('|', $message);
        $explicitRules = array();
        $standardRules = array();
        foreach ($parts as $part) {
            $part = trim($part);

            if (preg_match('/^(?P<interval>'.Interval::getIntervalRegexp().')\s*(?P<message>.*?)$/xs', $part, $matches)) {
                $explicitRules[$matches['interval']] = $matches['message'];
            } elseif (preg_match('/^\w+\:\s*(.*?)$/', $part, $matches)) {
                $standardRules[] = $matches[1];
            } else {
                $standardRules[] = $part;
            }
        }

        // try to match an explicit rule, then fallback to the standard ones
        foreach ($explicitRules as $interval => $m) {
            if (Interval::test($number, $interval)) {
                return $m;
            }
        }

        $position = PluralizationRules::get($number, $locale);

        if (!isset($standardRules[$position])) {
            // when there's exactly one rule given, and that rule is a standard
            // rule, use this rule
            if (1 === count($parts) && isset($standardRules[0])) {
                return $standardRules[0];
            }

            throw new \InvalidArgumentException(sprintf('Unable to choose a translation for "%s" with locale "%s" for value "%d". Double check that this translation has the correct plural options (e.g. "There is one apple|There are %%count%% apples").', $message, $locale, $number));
        }

        return $standardRules[$position];
    }
}
PKϤ$ZN���
�
2translation/DependencyInjection/TranslatorPass.phpnu�[���<?php

/*
 * This file is part of the Symfony package.
 *
 * (c) Fabien Potencier <fabien@symfony.com>
 *
 * For the full copyright and license information, please view the LICENSE
 * file that was distributed with this source code.
 */

namespace Symfony\Component\Translation\DependencyInjection;

use Symfony\Component\DependencyInjection\Compiler\CompilerPassInterface;
use Symfony\Component\DependencyInjection\Compiler\ServiceLocatorTagPass;
use Symfony\Component\DependencyInjection\ContainerBuilder;
use Symfony\Component\DependencyInjection\Reference;

class TranslatorPass implements CompilerPassInterface
{
    private $translatorServiceId;
    private $readerServiceId;
    private $loaderTag;
    private $debugCommandServiceId;
    private $updateCommandServiceId;

    public function __construct(string $translatorServiceId = 'translator.default', string $readerServiceId = 'translation.reader', string $loaderTag = 'translation.loader', string $debugCommandServiceId = 'console.command.translation_debug', string $updateCommandServiceId = 'console.command.translation_update')
    {
        $this->translatorServiceId = $translatorServiceId;
        $this->readerServiceId = $readerServiceId;
        $this->loaderTag = $loaderTag;
        $this->debugCommandServiceId = $debugCommandServiceId;
        $this->updateCommandServiceId = $updateCommandServiceId;
    }

    public function process(ContainerBuilder $container)
    {
        if (!$container->hasDefinition($this->translatorServiceId)) {
            return;
        }

        $loaders = [];
        $loaderRefs = [];
        foreach ($container->findTaggedServiceIds($this->loaderTag, true) as $id => $attributes) {
            $loaderRefs[$id] = new Reference($id);
            $loaders[$id][] = $attributes[0]['alias'];
            if (isset($attributes[0]['legacy-alias'])) {
                $loaders[$id][] = $attributes[0]['legacy-alias'];
            }
        }

        if ($container->hasDefinition($this->readerServiceId)) {
            $definition = $container->getDefinition($this->readerServiceId);
            foreach ($loaders as $id => $formats) {
                foreach ($formats as $format) {
                    $definition->addMethodCall('addLoader', [$format, $loaderRefs[$id]]);
                }
            }
        }

        $container
            ->findDefinition($this->translatorServiceId)
            ->replaceArgument(0, ServiceLocatorTagPass::register($container, $loaderRefs))
            ->replaceArgument(3, $loaders)
        ;

        if (!$container->hasParameter('twig.default_path')) {
            return;
        }

        $paths = array_keys($container->getDefinition('twig.template_iterator')->getArgument(1));
        if ($container->hasDefinition($this->debugCommandServiceId)) {
            $definition = $container->getDefinition($this->debugCommandServiceId);
            $definition->replaceArgument(4, $container->getParameter('twig.default_path'));

            if (\count($definition->getArguments()) > 6) {
                $definition->replaceArgument(6, $paths);
            }
        }
        if ($container->hasDefinition($this->updateCommandServiceId)) {
            $definition = $container->getDefinition($this->updateCommandServiceId);
            $definition->replaceArgument(5, $container->getParameter('twig.default_path'));

            if (\count($definition->getArguments()) > 7) {
                $definition->replaceArgument(7, $paths);
            }
        }
    }
}
PKϤ$Zeʱ��<translation/DependencyInjection/TranslationExtractorPass.phpnu�[���<?php

/*
 * This file is part of the Symfony package.
 *
 * (c) Fabien Potencier <fabien@symfony.com>
 *
 * For the full copyright and license information, please view the LICENSE
 * file that was distributed with this source code.
 */

namespace Symfony\Component\Translation\DependencyInjection;

use Symfony\Component\DependencyInjection\Compiler\CompilerPassInterface;
use Symfony\Component\DependencyInjection\ContainerBuilder;
use Symfony\Component\DependencyInjection\Exception\RuntimeException;
use Symfony\Component\DependencyInjection\Reference;

/**
 * Adds tagged translation.extractor services to translation extractor.
 */
class TranslationExtractorPass implements CompilerPassInterface
{
    private $extractorServiceId;
    private $extractorTag;

    public function __construct(string $extractorServiceId = 'translation.extractor', string $extractorTag = 'translation.extractor')
    {
        $this->extractorServiceId = $extractorServiceId;
        $this->extractorTag = $extractorTag;
    }

    public function process(ContainerBuilder $container)
    {
        if (!$container->hasDefinition($this->extractorServiceId)) {
            return;
        }

        $definition = $container->getDefinition($this->extractorServiceId);

        foreach ($container->findTaggedServiceIds($this->extractorTag, true) as $id => $attributes) {
            if (!isset($attributes[0]['alias'])) {
                throw new RuntimeException(sprintf('The alias for the tag "translation.extractor" of service "%s" must be set.', $id));
            }

            $definition->addMethodCall('addExtractor', [$attributes[0]['alias'], new Reference($id)]);
        }
    }
}
PKϤ$ZI�*OO9translation/DependencyInjection/TranslationDumperPass.phpnu�[���<?php

/*
 * This file is part of the Symfony package.
 *
 * (c) Fabien Potencier <fabien@symfony.com>
 *
 * For the full copyright and license information, please view the LICENSE
 * file that was distributed with this source code.
 */

namespace Symfony\Component\Translation\DependencyInjection;

use Symfony\Component\DependencyInjection\Compiler\CompilerPassInterface;
use Symfony\Component\DependencyInjection\ContainerBuilder;
use Symfony\Component\DependencyInjection\Reference;

/**
 * Adds tagged translation.formatter services to translation writer.
 */
class TranslationDumperPass implements CompilerPassInterface
{
    private $writerServiceId;
    private $dumperTag;

    public function __construct(string $writerServiceId = 'translation.writer', string $dumperTag = 'translation.dumper')
    {
        $this->writerServiceId = $writerServiceId;
        $this->dumperTag = $dumperTag;
    }

    public function process(ContainerBuilder $container)
    {
        if (!$container->hasDefinition($this->writerServiceId)) {
            return;
        }

        $definition = $container->getDefinition($this->writerServiceId);

        foreach ($container->findTaggedServiceIds($this->dumperTag, true) as $id => $attributes) {
            $definition->addMethodCall('addDumper', [$attributes[0]['alias'], new Reference($id)]);
        }
    }
}
PKϤ$Z{����7translation/DependencyInjection/TranslatorPathsPass.phpnu�[���<?php

/*
 * This file is part of the Symfony package.
 *
 * (c) Fabien Potencier <fabien@symfony.com>
 *
 * For the full copyright and license information, please view the LICENSE
 * file that was distributed with this source code.
 */

namespace Symfony\Component\Translation\DependencyInjection;

use Symfony\Component\DependencyInjection\Compiler\AbstractRecursivePass;
use Symfony\Component\DependencyInjection\ContainerBuilder;
use Symfony\Component\DependencyInjection\Definition;
use Symfony\Component\DependencyInjection\Reference;
use Symfony\Component\DependencyInjection\ServiceLocator;

/**
 * @author Yonel Ceruto <yonelceruto@gmail.com>
 */
class TranslatorPathsPass extends AbstractRecursivePass
{
    private $translatorServiceId;
    private $debugCommandServiceId;
    private $updateCommandServiceId;
    private $resolverServiceId;
    private $level = 0;
    private $paths = [];
    private $definitions = [];
    private $controllers = [];

    public function __construct(string $translatorServiceId = 'translator', string $debugCommandServiceId = 'console.command.translation_debug', string $updateCommandServiceId = 'console.command.translation_update', string $resolverServiceId = 'argument_resolver.service')
    {
        $this->translatorServiceId = $translatorServiceId;
        $this->debugCommandServiceId = $debugCommandServiceId;
        $this->updateCommandServiceId = $updateCommandServiceId;
        $this->resolverServiceId = $resolverServiceId;
    }

    public function process(ContainerBuilder $container)
    {
        if (!$container->hasDefinition($this->translatorServiceId)) {
            return;
        }

        foreach ($this->findControllerArguments($container) as $controller => $argument) {
            $id = substr($controller, 0, strpos($controller, ':') ?: \strlen($controller));
            if ($container->hasDefinition($id)) {
                list($locatorRef) = $argument->getValues();
                $this->controllers[(string) $locatorRef][$container->getDefinition($id)->getClass()] = true;
            }
        }

        try {
            parent::process($container);

            $paths = [];
            foreach ($this->paths as $class => $_) {
                if (($r = $container->getReflectionClass($class)) && !$r->isInterface()) {
                    $paths[] = $r->getFileName();
                }
            }
            if ($paths) {
                if ($container->hasDefinition($this->debugCommandServiceId)) {
                    $definition = $container->getDefinition($this->debugCommandServiceId);
                    $definition->replaceArgument(6, array_merge($definition->getArgument(6), $paths));
                }
                if ($container->hasDefinition($this->updateCommandServiceId)) {
                    $definition = $container->getDefinition($this->updateCommandServiceId);
                    $definition->replaceArgument(7, array_merge($definition->getArgument(7), $paths));
                }
            }
        } finally {
            $this->level = 0;
            $this->paths = [];
            $this->definitions = [];
        }
    }

    protected function processValue($value, bool $isRoot = false)
    {
        if ($value instanceof Reference) {
            if ((string) $value === $this->translatorServiceId) {
                for ($i = $this->level - 1; $i >= 0; --$i) {
                    $class = $this->definitions[$i]->getClass();

                    if (ServiceLocator::class === $class) {
                        if (!isset($this->controllers[$this->currentId])) {
                            continue;
                        }
                        foreach ($this->controllers[$this->currentId] as $class => $_) {
                            $this->paths[$class] = true;
                        }
                    } else {
                        $this->paths[$class] = true;
                    }

                    break;
                }
            }

            return $value;
        }

        if ($value instanceof Definition) {
            $this->definitions[$this->level++] = $value;
            $value = parent::processValue($value, $isRoot);
            unset($this->definitions[--$this->level]);

            return $value;
        }

        return parent::processValue($value, $isRoot);
    }

    private function findControllerArguments(ContainerBuilder $container): array
    {
        if ($container->hasDefinition($this->resolverServiceId)) {
            $argument = $container->getDefinition($this->resolverServiceId)->getArgument(0);
            if ($argument instanceof Reference) {
                $argument = $container->getDefinition($argument);
            }

            return $argument->getArgument(0);
        }

        if ($container->hasDefinition('debug.'.$this->resolverServiceId)) {
            $argument = $container->getDefinition('debug.'.$this->resolverServiceId)->getArgument(0);
            if ($argument instanceof Reference) {
                $argument = $container->getDefinition($argument);
            }
            $argument = $argument->getArgument(0);
            if ($argument instanceof Reference) {
                $argument = $container->getDefinition($argument);
            }

            return $argument->getArgument(0);
        }

        return [];
    }
}
PKϤ$Z�Ы�
�
translation/Interval.phpnu�[���<?php

/*
 * This file is part of the Symfony package.
 *
 * (c) Fabien Potencier <fabien@symfony.com>
 *
 * For the full copyright and license information, please view the LICENSE
 * file that was distributed with this source code.
 */

namespace Symfony\Component\Translation;

/**
 * Tests if a given number belongs to a given math interval.
 *
 * An interval can represent a finite set of numbers:
 *
 *  {1,2,3,4}
 *
 * An interval can represent numbers between two numbers:
 *
 *  [1, +Inf]
 *  ]-1,2[
 *
 * The left delimiter can be [ (inclusive) or ] (exclusive).
 * The right delimiter can be [ (exclusive) or ] (inclusive).
 * Beside numbers, you can use -Inf and +Inf for the infinite.
 *
 * @author Fabien Potencier <fabien@symfony.com>
 *
 * @see    http://en.wikipedia.org/wiki/Interval_%28mathematics%29#The_ISO_notation
 */
class Interval
{
    /**
     * Tests if the given number is in the math interval.
     *
     * @param int    $number   A number
     * @param string $interval An interval
     *
     * @return bool
     *
     * @throws \InvalidArgumentException
     */
    public static function test($number, $interval)
    {
        $interval = trim($interval);

        if (!preg_match('/^'.self::getIntervalRegexp().'$/x', $interval, $matches)) {
            throw new \InvalidArgumentException(sprintf('"%s" is not a valid interval.', $interval));
        }

        if ($matches[1]) {
            foreach (explode(',', $matches[2]) as $n) {
                if ($number == $n) {
                    return true;
                }
            }
        } else {
            $leftNumber = self::convertNumber($matches['left']);
            $rightNumber = self::convertNumber($matches['right']);

            return
                ('[' === $matches['left_delimiter'] ? $number >= $leftNumber : $number > $leftNumber)
                && (']' === $matches['right_delimiter'] ? $number <= $rightNumber : $number < $rightNumber)
            ;
        }

        return false;
    }

    /**
     * Returns a Regexp that matches valid intervals.
     *
     * @return string A Regexp (without the delimiters)
     */
    public static function getIntervalRegexp()
    {
        return <<<EOF
        ({\s*
            (\-?\d+(\.\d+)?[\s*,\s*\-?\d+(\.\d+)?]*)
        \s*})

            |

        (?P<left_delimiter>[\[\]])
            \s*
            (?P<left>-Inf|\-?\d+(\.\d+)?)
            \s*,\s*
            (?P<right>\+?Inf|\-?\d+(\.\d+)?)
            \s*
        (?P<right_delimiter>[\[\]])
EOF;
    }

    private static function convertNumber($number)
    {
        if ('-Inf' === $number) {
            return log(0);
        } elseif ('+Inf' === $number || 'Inf' === $number) {
            return -log(0);
        }

        return (float) $number;
    }
}
PKϤ$Z�R�99&translation/MetadataAwareInterface.phpnu�[���<?php

/*
 * This file is part of the Symfony package.
 *
 * (c) Fabien Potencier <fabien@symfony.com>
 *
 * For the full copyright and license information, please view the LICENSE
 * file that was distributed with this source code.
 */

namespace Symfony\Component\Translation;

/**
 * MetadataAwareInterface.
 *
 * @author Fabien Potencier <fabien@symfony.com>
 */
interface MetadataAwareInterface
{
    /**
     * Gets metadata for the given domain and key.
     *
     * Passing an empty domain will return an array with all metadata indexed by
     * domain and then by key. Passing an empty key will return an array with all
     * metadata for the given domain.
     *
     * @param string $key    The key
     * @param string $domain The domain name
     *
     * @return mixed The value that was set or an array with the domains/keys or null
     */
    public function getMetadata(string $key = '', string $domain = 'messages');

    /**
     * Adds metadata to a message domain.
     *
     * @param string $key    The key
     * @param mixed  $value  The value
     * @param string $domain The domain name
     */
    public function setMetadata(string $key, $value, string $domain = 'messages');

    /**
     * Deletes metadata for the given key and domain.
     *
     * Passing an empty domain will delete all metadata. Passing an empty key will
     * delete all metadata for the given domain.
     *
     * @param string $key    The key
     * @param string $domain The domain name
     */
    public function deleteMetadata(string $key = '', string $domain = 'messages');
}
PKϤ$Z�c|:��1translation/Reader/TranslationReaderInterface.phpnu�[���<?php

/*
 * This file is part of the Symfony package.
 *
 * (c) Fabien Potencier <fabien@symfony.com>
 *
 * For the full copyright and license information, please view the LICENSE
 * file that was distributed with this source code.
 */

namespace Symfony\Component\Translation\Reader;

use Symfony\Component\Translation\MessageCatalogue;

/**
 * TranslationReader reads translation messages from translation files.
 *
 * @author Tobias Nyholm <tobias.nyholm@gmail.com>
 */
interface TranslationReaderInterface
{
    /**
     * Reads translation messages from a directory to the catalogue.
     */
    public function read(string $directory, MessageCatalogue $catalogue);
}
PKϤ$Zȳ}��(translation/Reader/TranslationReader.phpnu�[���<?php

/*
 * This file is part of the Symfony package.
 *
 * (c) Fabien Potencier <fabien@symfony.com>
 *
 * For the full copyright and license information, please view the LICENSE
 * file that was distributed with this source code.
 */

namespace Symfony\Component\Translation\Reader;

use Symfony\Component\Finder\Finder;
use Symfony\Component\Translation\Loader\LoaderInterface;
use Symfony\Component\Translation\MessageCatalogue;

/**
 * TranslationReader reads translation messages from translation files.
 *
 * @author Michel Salib <michelsalib@hotmail.com>
 */
class TranslationReader implements TranslationReaderInterface
{
    /**
     * Loaders used for import.
     *
     * @var array
     */
    private $loaders = [];

    /**
     * Adds a loader to the translation extractor.
     *
     * @param string $format The format of the loader
     */
    public function addLoader(string $format, LoaderInterface $loader)
    {
        $this->loaders[$format] = $loader;
    }

    /**
     * {@inheritdoc}
     */
    public function read(string $directory, MessageCatalogue $catalogue)
    {
        if (!is_dir($directory)) {
            return;
        }

        foreach ($this->loaders as $format => $loader) {
            // load any existing translation files
            $finder = new Finder();
            $extension = $catalogue->getLocale().'.'.$format;
            $files = $finder->files()->name('*.'.$extension)->in($directory);
            foreach ($files as $file) {
                $domain = substr($file->getFilename(), 0, -1 * \strlen($extension) - 1);
                $catalogue->addCatalogue($loader->load($file->getPathname(), $catalogue->getLocale(), $domain));
            }
        }
    }
}
PKϤ$ZCa����(translation/Exception/LogicException.phpnu�[���<?php

/*
 * This file is part of the Symfony package.
 *
 * (c) Fabien Potencier <fabien@symfony.com>
 *
 * For the full copyright and license information, please view the LICENSE
 * file that was distributed with this source code.
 */

namespace Symfony\Component\Translation\Exception;

/**
 * Base LogicException for Translation component.
 *
 * @author Abdellatif Ait boudad <a.aitboudad@gmail.com>
 */
class LogicException extends \LogicException implements ExceptionInterface
{
}
PKϤ$ZGP����3translation/Exception/NotFoundResourceException.phpnu�[���<?php

/*
 * This file is part of the Symfony package.
 *
 * (c) Fabien Potencier <fabien@symfony.com>
 *
 * For the full copyright and license information, please view the LICENSE
 * file that was distributed with this source code.
 */

namespace Symfony\Component\Translation\Exception;

/**
 * Thrown when a resource does not exist.
 *
 * @author Fabien Potencier <fabien@symfony.com>
 */
class NotFoundResourceException extends \InvalidArgumentException implements ExceptionInterface
{
}
PKϤ$Z?�[��,translation/Exception/ExceptionInterface.phpnu�[���<?php

/*
 * This file is part of the Symfony package.
 *
 * (c) Fabien Potencier <fabien@symfony.com>
 *
 * For the full copyright and license information, please view the LICENSE
 * file that was distributed with this source code.
 */

namespace Symfony\Component\Translation\Exception;

/**
 * Exception interface for all exceptions thrown by the component.
 *
 * @author Fabien Potencier <fabien@symfony.com>
 */
interface ExceptionInterface extends \Throwable
{
}
PKϤ$Z>O�		2translation/Exception/InvalidArgumentException.phpnu�[���<?php

/*
 * This file is part of the Symfony package.
 *
 * (c) Fabien Potencier <fabien@symfony.com>
 *
 * For the full copyright and license information, please view the LICENSE
 * file that was distributed with this source code.
 */

namespace Symfony\Component\Translation\Exception;

/**
 * Base InvalidArgumentException for the Translation component.
 *
 * @author Abdellatif Ait boudad <a.aitboudad@gmail.com>
 */
class InvalidArgumentException extends \InvalidArgumentException implements ExceptionInterface
{
}
PKϤ$Z ����2translation/Exception/InvalidResourceException.phpnu�[���<?php

/*
 * This file is part of the Symfony package.
 *
 * (c) Fabien Potencier <fabien@symfony.com>
 *
 * For the full copyright and license information, please view the LICENSE
 * file that was distributed with this source code.
 */

namespace Symfony\Component\Translation\Exception;

/**
 * Thrown when a resource cannot be loaded.
 *
 * @author Fabien Potencier <fabien@symfony.com>
 */
class InvalidResourceException extends \InvalidArgumentException implements ExceptionInterface
{
}
PKϤ$Z[��N��*translation/Exception/RuntimeException.phpnu�[���<?php

/*
 * This file is part of the Symfony package.
 *
 * (c) Fabien Potencier <fabien@symfony.com>
 *
 * For the full copyright and license information, please view the LICENSE
 * file that was distributed with this source code.
 */

namespace Symfony\Component\Translation\Exception;

/**
 * Base RuntimeException for the Translation component.
 *
 * @author Abdellatif Ait boudad <a.aitboudad@gmail.com>
 */
class RuntimeException extends \RuntimeException implements ExceptionInterface
{
}
PKϤ$Z+v��bbtranslation/CHANGELOG.mdnu�[���CHANGELOG
=========

5.0.0
-----

 * removed support for using `null` as the locale in `Translator`
 * removed `TranslatorInterface`
 * removed `MessageSelector`
 * removed `ChoiceMessageFormatterInterface`
 * removed `PluralizationRule`
 * removed `Interval`
 * removed `transChoice()` methods, use the trans() method instead with a %count% parameter
 * removed `FileDumper::setBackup()` and `TranslationWriter::disableBackup()`
 * removed `MessageFormatter::choiceFormat()`
 * added argument `$filename` to `PhpExtractor::parseTokens()`
 * removed support for implicit STDIN usage in the `lint:xliff` command, use `lint:xliff -` (append a dash) instead to make it explicit.

4.4.0
-----

 * deprecated support for using `null` as the locale in `Translator`
 * deprecated accepting STDIN implicitly when using the `lint:xliff` command, use `lint:xliff -` (append a dash) instead to make it explicit.
 * Marked the `TranslationDataCollector` class as `@final`.

4.3.0
-----

 * Improved Xliff 1.2 loader to load the original file's metadata
 * Added `TranslatorPathsPass`

4.2.0
-----

 * Started using ICU parent locales as fallback locales.
 * allow using the ICU message format using domains with the "+intl-icu" suffix
 * deprecated `Translator::transChoice()` in favor of using `Translator::trans()` with a `%count%` parameter
 * deprecated `TranslatorInterface` in favor of `Symfony\Contracts\Translation\TranslatorInterface`
 * deprecated `MessageSelector`, `Interval` and `PluralizationRules`; use `IdentityTranslator` instead
 * Added `IntlFormatter` and `IntlFormatterInterface`
 * added support for multiple files and directories in `XliffLintCommand`
 * Marked `Translator::getFallbackLocales()` and `TranslationDataCollector::getFallbackLocales()` as internal

4.1.0
-----

 * The `FileDumper::setBackup()` method is deprecated.
 * The `TranslationWriter::disableBackup()` method is deprecated.
 * The `XliffFileDumper` will write "name" on the "unit" node when dumping XLIFF 2.0.

4.0.0
-----

 * removed the backup feature of the `FileDumper` class
 * removed `TranslationWriter::writeTranslations()` method
 * removed support for passing `MessageSelector` instances to the constructor of the `Translator` class

3.4.0
-----

 * Added `TranslationDumperPass`
 * Added `TranslationExtractorPass`
 * Added `TranslatorPass`
 * Added `TranslationReader` and `TranslationReaderInterface`
 * Added `<notes>` section to the Xliff 2.0 dumper.
 * Improved Xliff 2.0 loader to load `<notes>` section.
 * Added `TranslationWriterInterface`
 * Deprecated `TranslationWriter::writeTranslations` in favor of `TranslationWriter::write`
 * added support for adding custom message formatter and decoupling the default one.
 * Added `PhpExtractor`
 * Added `PhpStringTokenParser`

3.2.0
-----

 * Added support for escaping `|` in plural translations with double pipe.

3.1.0
-----

 * Deprecated the backup feature of the file dumper classes.

3.0.0
-----

 * removed `FileDumper::format()` method.
 * Changed the visibility of the locale property in `Translator` from protected to private.

2.8.0
-----

 * deprecated FileDumper::format(), overwrite FileDumper::formatCatalogue() instead.
 * deprecated Translator::getMessages(), rely on TranslatorBagInterface::getCatalogue() instead.
 * added `FileDumper::formatCatalogue` which allows format the catalogue without dumping it into file.
 * added option `json_encoding` to JsonFileDumper
 * added options `as_tree`, `inline` to YamlFileDumper
 * added support for XLIFF 2.0.
 * added support for XLIFF target and tool attributes.
 * added message parameters to DataCollectorTranslator.
 * [DEPRECATION] The `DiffOperation` class has been deprecated and
   will be removed in Symfony 3.0, since its operation has nothing to do with 'diff',
   so the class name is misleading. The `TargetOperation` class should be used for
   this use-case instead.

2.7.0
-----

 * added DataCollectorTranslator for collecting the translated messages.

2.6.0
-----

 * added possibility to cache catalogues
 * added TranslatorBagInterface
 * added LoggingTranslator
 * added Translator::getMessages() for retrieving the message catalogue as an array

2.5.0
-----

 * added relative file path template to the file dumpers
 * added optional backup to the file dumpers
 * changed IcuResFileDumper to extend FileDumper

2.3.0
-----

 * added classes to make operations on catalogues (like making a diff or a merge on 2 catalogues)
 * added Translator::getFallbackLocales()
 * deprecated Translator::setFallbackLocale() in favor of the new Translator::setFallbackLocales() method

2.2.0
-----

 * QtTranslationsLoader class renamed to QtFileLoader. QtTranslationsLoader is deprecated and will be removed in 2.3.
 * [BC BREAK] uniformized the exception thrown by the load() method when an error occurs. The load() method now
   throws Symfony\Component\Translation\Exception\NotFoundResourceException when a resource cannot be found
   and Symfony\Component\Translation\Exception\InvalidResourceException when a resource is invalid.
 * changed the exception class thrown by some load() methods from \RuntimeException to \InvalidArgumentException
   (IcuDatFileLoader, IcuResFileLoader and QtFileLoader)

2.1.0
-----

 * added support for more than one fallback locale
 * added support for extracting translation messages from templates (Twig and PHP)
 * added dumpers for translation catalogs
 * added support for QT, gettext, and ResourceBundles
PKϤ$Z=��))translation/LICENSEnu�[���Copyright (c) 2004-2020 Fabien Potencier

Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is furnished
to do so, subject to the following conditions:

The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.

THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
THE SOFTWARE.
PKϤ$ZǤ���6translation/DataCollector/TranslationDataCollector.phpnu�[���<?php

/*
 * This file is part of the Symfony package.
 *
 * (c) Fabien Potencier <fabien@symfony.com>
 *
 * For the full copyright and license information, please view the LICENSE
 * file that was distributed with this source code.
 */

namespace Symfony\Component\Translation\DataCollector;

use Symfony\Component\HttpFoundation\Request;
use Symfony\Component\HttpFoundation\Response;
use Symfony\Component\HttpKernel\DataCollector\DataCollector;
use Symfony\Component\HttpKernel\DataCollector\LateDataCollectorInterface;
use Symfony\Component\Translation\DataCollectorTranslator;
use Symfony\Component\VarDumper\Cloner\Data;

/**
 * @author Abdellatif Ait boudad <a.aitboudad@gmail.com>
 *
 * @final
 */
class TranslationDataCollector extends DataCollector implements LateDataCollectorInterface
{
    private $translator;

    public function __construct(DataCollectorTranslator $translator)
    {
        $this->translator = $translator;
    }

    /**
     * {@inheritdoc}
     */
    public function lateCollect()
    {
        $messages = $this->sanitizeCollectedMessages($this->translator->getCollectedMessages());

        $this->data += $this->computeCount($messages);
        $this->data['messages'] = $messages;

        $this->data = $this->cloneVar($this->data);
    }

    /**
     * {@inheritdoc}
     */
    public function collect(Request $request, Response $response, \Throwable $exception = null)
    {
        $this->data['locale'] = $this->translator->getLocale();
        $this->data['fallback_locales'] = $this->translator->getFallbackLocales();
    }

    /**
     * {@inheritdoc}
     */
    public function reset()
    {
        $this->data = [];
    }

    /**
     * @return array|Data
     */
    public function getMessages()
    {
        return isset($this->data['messages']) ? $this->data['messages'] : [];
    }

    /**
     * @return int
     */
    public function getCountMissings()
    {
        return isset($this->data[DataCollectorTranslator::MESSAGE_MISSING]) ? $this->data[DataCollectorTranslator::MESSAGE_MISSING] : 0;
    }

    /**
     * @return int
     */
    public function getCountFallbacks()
    {
        return isset($this->data[DataCollectorTranslator::MESSAGE_EQUALS_FALLBACK]) ? $this->data[DataCollectorTranslator::MESSAGE_EQUALS_FALLBACK] : 0;
    }

    /**
     * @return int
     */
    public function getCountDefines()
    {
        return isset($this->data[DataCollectorTranslator::MESSAGE_DEFINED]) ? $this->data[DataCollectorTranslator::MESSAGE_DEFINED] : 0;
    }

    public function getLocale()
    {
        return !empty($this->data['locale']) ? $this->data['locale'] : null;
    }

    /**
     * @internal
     */
    public function getFallbackLocales()
    {
        return (isset($this->data['fallback_locales']) && \count($this->data['fallback_locales']) > 0) ? $this->data['fallback_locales'] : [];
    }

    /**
     * {@inheritdoc}
     */
    public function getName()
    {
        return 'translation';
    }

    private function sanitizeCollectedMessages(array $messages)
    {
        $result = [];
        foreach ($messages as $key => $message) {
            $messageId = $message['locale'].$message['domain'].$message['id'];

            if (!isset($result[$messageId])) {
                $message['count'] = 1;
                $message['parameters'] = !empty($message['parameters']) ? [$message['parameters']] : [];
                $messages[$key]['translation'] = $this->sanitizeString($message['translation']);
                $result[$messageId] = $message;
            } else {
                if (!empty($message['parameters'])) {
                    $result[$messageId]['parameters'][] = $message['parameters'];
                }

                ++$result[$messageId]['count'];
            }

            unset($messages[$key]);
        }

        return $result;
    }

    private function computeCount(array $messages)
    {
        $count = [
            DataCollectorTranslator::MESSAGE_DEFINED => 0,
            DataCollectorTranslator::MESSAGE_MISSING => 0,
            DataCollectorTranslator::MESSAGE_EQUALS_FALLBACK => 0,
        ];

        foreach ($messages as $message) {
            ++$count[$message['state']];
        }

        return $count;
    }

    private function sanitizeString(string $string, int $length = 80)
    {
        $string = trim(preg_replace('/\s+/', ' ', $string));

        if (false !== $encoding = mb_detect_encoding($string, null, true)) {
            if (mb_strlen($string, $encoding) > $length) {
                return mb_substr($string, 0, $length - 3, $encoding).'...';
            }
        } elseif (\strlen($string) > $length) {
            return substr($string, 0, $length - 3).'...';
        }

        return $string;
    }
}
PKϤ$Z��8"NN(translation/Writer/TranslationWriter.phpnu�[���<?php

/*
 * This file is part of the Symfony package.
 *
 * (c) Fabien Potencier <fabien@symfony.com>
 *
 * For the full copyright and license information, please view the LICENSE
 * file that was distributed with this source code.
 */

namespace Symfony\Component\Translation\Writer;

use Symfony\Component\Translation\Dumper\DumperInterface;
use Symfony\Component\Translation\Exception\InvalidArgumentException;
use Symfony\Component\Translation\Exception\RuntimeException;
use Symfony\Component\Translation\MessageCatalogue;

/**
 * TranslationWriter writes translation messages.
 *
 * @author Michel Salib <michelsalib@hotmail.com>
 */
class TranslationWriter implements TranslationWriterInterface
{
    private $dumpers = [];

    /**
     * Adds a dumper to the writer.
     *
     * @param string $format The format of the dumper
     */
    public function addDumper($format, DumperInterface $dumper)
    {
        $this->dumpers[$format] = $dumper;
    }

    /**
     * Obtains the list of supported formats.
     *
     * @return array
     */
    public function getFormats()
    {
        return array_keys($this->dumpers);
    }

    /**
     * Writes translation from the catalogue according to the selected format.
     *
     * @param string $format  The format to use to dump the messages
     * @param array  $options Options that are passed to the dumper
     *
     * @throws InvalidArgumentException
     */
    public function write(MessageCatalogue $catalogue, string $format, array $options = [])
    {
        if (!isset($this->dumpers[$format])) {
            throw new InvalidArgumentException(sprintf('There is no dumper associated with format "%s".', $format));
        }

        // get the right dumper
        $dumper = $this->dumpers[$format];

        if (isset($options['path']) && !is_dir($options['path']) && !@mkdir($options['path'], 0777, true) && !is_dir($options['path'])) {
            throw new RuntimeException(sprintf('Translation Writer was not able to create directory "%s".', $options['path']));
        }

        // save
        $dumper->dump($catalogue, $options);
    }
}
PKϤ$Z�,�8��1translation/Writer/TranslationWriterInterface.phpnu�[���<?php

/*
 * This file is part of the Symfony package.
 *
 * (c) Fabien Potencier <fabien@symfony.com>
 *
 * For the full copyright and license information, please view the LICENSE
 * file that was distributed with this source code.
 */

namespace Symfony\Component\Translation\Writer;

use Symfony\Component\Translation\Exception\InvalidArgumentException;
use Symfony\Component\Translation\MessageCatalogue;

/**
 * TranslationWriter writes translation messages.
 *
 * @author Michel Salib <michelsalib@hotmail.com>
 */
interface TranslationWriterInterface
{
    /**
     * Writes translation from the catalogue according to the selected format.
     *
     * @param string $format  The format to use to dump the messages
     * @param array  $options Options that are passed to the dumper
     *
     * @throws InvalidArgumentException
     */
    public function write(MessageCatalogue $catalogue, string $format, array $options = []);
}
PKϤ$Z���ϲ�0translation/Formatter/IntlFormatterInterface.phpnu�[���<?php

/*
 * This file is part of the Symfony package.
 *
 * (c) Fabien Potencier <fabien@symfony.com>
 *
 * For the full copyright and license information, please view the LICENSE
 * file that was distributed with this source code.
 */

namespace Symfony\Component\Translation\Formatter;

/**
 * Formats ICU message patterns.
 *
 * @author Nicolas Grekas <p@tchwork.com>
 */
interface IntlFormatterInterface
{
    /**
     * Formats a localized message using rules defined by ICU MessageFormat.
     *
     * @see http://icu-project.org/apiref/icu4c/classMessageFormat.html#details
     */
    public function formatIntl(string $message, string $locale, array $parameters = []): string;
}
PKϤ$Z�t{*��'translation/Formatter/IntlFormatter.phpnu�[���<?php

/*
 * This file is part of the Symfony package.
 *
 * (c) Fabien Potencier <fabien@symfony.com>
 *
 * For the full copyright and license information, please view the LICENSE
 * file that was distributed with this source code.
 */

namespace Symfony\Component\Translation\Formatter;

use Symfony\Component\Translation\Exception\InvalidArgumentException;
use Symfony\Component\Translation\Exception\LogicException;

/**
 * @author Guilherme Blanco <guilhermeblanco@hotmail.com>
 * @author Abdellatif Ait boudad <a.aitboudad@gmail.com>
 */
class IntlFormatter implements IntlFormatterInterface
{
    private $hasMessageFormatter;
    private $cache = [];

    /**
     * {@inheritdoc}
     */
    public function formatIntl(string $message, string $locale, array $parameters = []): string
    {
        // MessageFormatter constructor throws an exception if the message is empty
        if ('' === $message) {
            return '';
        }

        if (!$formatter = $this->cache[$locale][$message] ?? null) {
            if (!($this->hasMessageFormatter ?? $this->hasMessageFormatter = class_exists(\MessageFormatter::class))) {
                throw new LogicException('Cannot parse message translation: please install the "intl" PHP extension or the "symfony/polyfill-intl-messageformatter" package.');
            }
            try {
                $this->cache[$locale][$message] = $formatter = new \MessageFormatter($locale, $message);
            } catch (\IntlException $e) {
                throw new InvalidArgumentException(sprintf('Invalid message format (error #%d): '.intl_get_error_message(), intl_get_error_code()), 0, $e);
            }
        }

        foreach ($parameters as $key => $value) {
            if (\in_array($key[0] ?? null, ['%', '{'], true)) {
                unset($parameters[$key]);
                $parameters[trim($key, '%{ }')] = $value;
            }
        }

        if (false === $message = $formatter->format($parameters)) {
            throw new InvalidArgumentException(sprintf('Unable to format message (error #%s): '.$formatter->getErrorMessage(), $formatter->getErrorCode()));
        }

        return $message;
    }
}
PKϤ$Zh�
kk3translation/Formatter/MessageFormatterInterface.phpnu�[���<?php

/*
 * This file is part of the Symfony package.
 *
 * (c) Fabien Potencier <fabien@symfony.com>
 *
 * For the full copyright and license information, please view the LICENSE
 * file that was distributed with this source code.
 */

namespace Symfony\Component\Translation\Formatter;

/**
 * @author Guilherme Blanco <guilhermeblanco@hotmail.com>
 * @author Abdellatif Ait boudad <a.aitboudad@gmail.com>
 */
interface MessageFormatterInterface
{
    /**
     * Formats a localized message pattern with given arguments.
     *
     * @param string $message    The message (may also be an object that can be cast to string)
     * @param string $locale     The message locale
     * @param array  $parameters An array of parameters for the message
     *
     * @return string
     */
    public function format(string $message, string $locale, array $parameters = []);
}
PKϤ$Z��!{{*translation/Formatter/MessageFormatter.phpnu�[���<?php

/*
 * This file is part of the Symfony package.
 *
 * (c) Fabien Potencier <fabien@symfony.com>
 *
 * For the full copyright and license information, please view the LICENSE
 * file that was distributed with this source code.
 */

namespace Symfony\Component\Translation\Formatter;

use Symfony\Component\Translation\IdentityTranslator;
use Symfony\Contracts\Translation\TranslatorInterface;

// Help opcache.preload discover always-needed symbols
class_exists(IntlFormatter::class);

/**
 * @author Abdellatif Ait boudad <a.aitboudad@gmail.com>
 */
class MessageFormatter implements MessageFormatterInterface, IntlFormatterInterface
{
    private $translator;
    private $intlFormatter;

    /**
     * @param TranslatorInterface|null $translator An identity translator to use as selector for pluralization
     */
    public function __construct(TranslatorInterface $translator = null, IntlFormatterInterface $intlFormatter = null)
    {
        $this->translator = $translator ?? new IdentityTranslator();
        $this->intlFormatter = $intlFormatter ?? new IntlFormatter();
    }

    /**
     * {@inheritdoc}
     */
    public function format(string $message, string $locale, array $parameters = [])
    {
        if ($this->translator instanceof TranslatorInterface) {
            return $this->translator->trans($message, $parameters, null, $locale);
        }

        return strtr($message, $parameters);
    }

    /**
     * {@inheritdoc}
     */
    public function formatIntl(string $message, string $locale, array $parameters = []): string
    {
        return $this->intlFormatter->formatIntl($message, $locale, $parameters);
    }
}
PKϤ$Z���t::!translation/LoggingTranslator.phpnu�[���<?php

/*
 * This file is part of the Symfony package.
 *
 * (c) Fabien Potencier <fabien@symfony.com>
 *
 * For the full copyright and license information, please view the LICENSE
 * file that was distributed with this source code.
 */

namespace Symfony\Component\Translation;

use Psr\Log\LoggerInterface;
use Symfony\Component\Translation\Exception\InvalidArgumentException;
use Symfony\Contracts\Translation\LocaleAwareInterface;
use Symfony\Contracts\Translation\TranslatorInterface;

/**
 * @author Abdellatif Ait boudad <a.aitboudad@gmail.com>
 */
class LoggingTranslator implements TranslatorInterface, TranslatorBagInterface, LocaleAwareInterface
{
    /**
     * @var TranslatorInterface|TranslatorBagInterface
     */
    private $translator;

    private $logger;

    /**
     * @param TranslatorInterface $translator The translator must implement TranslatorBagInterface
     */
    public function __construct(TranslatorInterface $translator, LoggerInterface $logger)
    {
        if (!$translator instanceof TranslatorBagInterface || !$translator instanceof LocaleAwareInterface) {
            throw new InvalidArgumentException(sprintf('The Translator "%s" must implement TranslatorInterface, TranslatorBagInterface and LocaleAwareInterface.', \get_class($translator)));
        }

        $this->translator = $translator;
        $this->logger = $logger;
    }

    /**
     * {@inheritdoc}
     */
    public function trans(?string $id, array $parameters = [], string $domain = null, string $locale = null)
    {
        $trans = $this->translator->trans($id = (string) $id, $parameters, $domain, $locale);
        $this->log($id, $domain, $locale);

        return $trans;
    }

    /**
     * {@inheritdoc}
     */
    public function setLocale(string $locale)
    {
        $prev = $this->translator->getLocale();
        $this->translator->setLocale($locale);
        if ($prev === $locale) {
            return;
        }

        $this->logger->debug(sprintf('The locale of the translator has changed from "%s" to "%s".', $prev, $locale));
    }

    /**
     * {@inheritdoc}
     */
    public function getLocale()
    {
        return $this->translator->getLocale();
    }

    /**
     * {@inheritdoc}
     */
    public function getCatalogue(string $locale = null)
    {
        return $this->translator->getCatalogue($locale);
    }

    /**
     * Gets the fallback locales.
     *
     * @return array The fallback locales
     */
    public function getFallbackLocales()
    {
        if ($this->translator instanceof Translator || method_exists($this->translator, 'getFallbackLocales')) {
            return $this->translator->getFallbackLocales();
        }

        return [];
    }

    /**
     * Passes through all unknown calls onto the translator object.
     */
    public function __call(string $method, array $args)
    {
        return $this->translator->{$method}(...$args);
    }

    /**
     * Logs for missing translations.
     */
    private function log(string $id, ?string $domain, ?string $locale)
    {
        if (null === $domain) {
            $domain = 'messages';
        }

        $catalogue = $this->translator->getCatalogue($locale);
        if ($catalogue->defines($id, $domain)) {
            return;
        }

        if ($catalogue->has($id, $domain)) {
            $this->logger->debug('Translation use fallback catalogue.', ['id' => $id, 'domain' => $domain, 'locale' => $catalogue->getLocale()]);
        } else {
            $this->logger->warning('Translation not found.', ['id' => $id, 'domain' => $domain, 'locale' => $catalogue->getLocale()]);
        }
    }
}
PKϤ$Zj|��7&7&#polyfill-intl-grapheme/Grapheme.phpnu�[���<?php

/*
 * This file is part of the Symfony package.
 *
 * (c) Fabien Potencier <fabien@symfony.com>
 *
 * For the full copyright and license information, please view the LICENSE
 * file that was distributed with this source code.
 */

namespace Symfony\Polyfill\Intl\Grapheme;

\define('SYMFONY_GRAPHEME_CLUSTER_RX', ((float) \PCRE_VERSION < 10 ? (float) \PCRE_VERSION >= 8.32 : (float) \PCRE_VERSION >= 10.39) ? '\X' : Grapheme::GRAPHEME_CLUSTER_RX);

/**
 * Partial intl implementation in pure PHP.
 *
 * Implemented:
 * - grapheme_extract  - Extract a sequence of grapheme clusters from a text buffer, which must be encoded in UTF-8
 * - grapheme_stripos  - Find position (in grapheme units) of first occurrence of a case-insensitive string
 * - grapheme_stristr  - Returns part of haystack string from the first occurrence of case-insensitive needle to the end of haystack
 * - grapheme_strlen   - Get string length in grapheme units
 * - grapheme_strpos   - Find position (in grapheme units) of first occurrence of a string
 * - grapheme_strripos - Find position (in grapheme units) of last occurrence of a case-insensitive string
 * - grapheme_strrpos  - Find position (in grapheme units) of last occurrence of a string
 * - grapheme_strstr   - Returns part of haystack string from the first occurrence of needle to the end of haystack
 * - grapheme_substr   - Return part of a string
 *
 * @author Nicolas Grekas <p@tchwork.com>
 *
 * @internal
 */
final class Grapheme
{
    // (CRLF|([ZWNJ-ZWJ]|T+|L*(LV?V+|LV|LVT)T*|L+|[^Control])[Extend]*|[Control])
    // This regular expression is a work around for http://bugs.exim.org/1279
    public const GRAPHEME_CLUSTER_RX = '(?:\r\n|(?:[ -~\x{200C}\x{200D}]|[ᆨ-ᇹ]+|[ᄀ-ᅟ]*(?:[가개갸걔거게겨계고과괘괴교구궈궤귀규그긔기까깨꺄꺠꺼께껴꼐꼬꽈꽤꾀꾜꾸꿔꿰뀌뀨끄끠끼나내냐냬너네녀녜노놔놰뇌뇨누눠눼뉘뉴느늬니다대댜댸더데뎌뎨도돠돼되됴두둬뒈뒤듀드듸디따때땨떄떠떼뗘뗴또똬뙈뙤뚀뚜뚸뛔뛰뜌뜨띄띠라래랴럐러레려례로롸뢔뢰료루뤄뤠뤼류르릐리마매먀먜머메며몌모뫄뫠뫼묘무뭐뭬뮈뮤므믜미바배뱌뱨버베벼볘보봐봬뵈뵤부붜붸뷔뷰브븨비빠빼뺘뺴뻐뻬뼈뼤뽀뽜뽸뾔뾰뿌뿨쀄쀠쀼쁘쁴삐사새샤섀서세셔셰소솨쇄쇠쇼수숴쉐쉬슈스싀시싸쌔쌰썌써쎄쎠쎼쏘쏴쐐쐬쑈쑤쒀쒜쒸쓔쓰씌씨아애야얘어에여예오와왜외요우워웨위유으의이자재쟈쟤저제져졔조좌좨죄죠주줘줴쥐쥬즈즤지짜째쨔쨰쩌쩨쪄쪠쪼쫘쫴쬐쬬쭈쭤쮀쮜쮸쯔쯰찌차채챠챼처체쳐쳬초촤쵀최쵸추춰췌취츄츠츼치카캐캬컈커케켜켸코콰쾌쾨쿄쿠쿼퀘퀴큐크킈키타태탸턔터테텨톄토톼퇘퇴툐투퉈퉤튀튜트틔티파패퍄퍠퍼페펴폐포퐈퐤푀표푸풔풰퓌퓨프픠피하해햐햬허헤혀혜호화홰회효후훠훼휘휴흐희히]?[ᅠ-ᆢ]+|[가-힣])[ᆨ-ᇹ]*|[ᄀ-ᅟ]+|[^\p{Cc}\p{Cf}\p{Zl}\p{Zp}])[\p{Mn}\p{Me}\x{09BE}\x{09D7}\x{0B3E}\x{0B57}\x{0BBE}\x{0BD7}\x{0CC2}\x{0CD5}\x{0CD6}\x{0D3E}\x{0D57}\x{0DCF}\x{0DDF}\x{200C}\x{200D}\x{1D165}\x{1D16E}-\x{1D172}]*|[\p{Cc}\p{Cf}\p{Zl}\p{Zp}])';

    private const CASE_FOLD = [
        ['µ', 'ſ', "\xCD\x85", 'ς', "\xCF\x90", "\xCF\x91", "\xCF\x95", "\xCF\x96", "\xCF\xB0", "\xCF\xB1", "\xCF\xB5", "\xE1\xBA\x9B", "\xE1\xBE\xBE"],
        ['μ', 's', 'ι',        'σ', 'β',        'θ',        'φ',        'π',        'κ',        'ρ',        'ε',        "\xE1\xB9\xA1", 'ι'],
    ];

    public static function grapheme_extract($s, $size, $type = \GRAPHEME_EXTR_COUNT, $start = 0, &$next = 0)
    {
        if (0 > $start) {
            $start = \strlen($s) + $start;
        }

        if (!is_scalar($s)) {
            $hasError = false;
            set_error_handler(function () use (&$hasError) { $hasError = true; });
            $next = substr($s, $start);
            restore_error_handler();
            if ($hasError) {
                substr($s, $start);
                $s = '';
            } else {
                $s = $next;
            }
        } else {
            $s = substr($s, $start);
        }
        $size = (int) $size;
        $type = (int) $type;
        $start = (int) $start;

        if (\GRAPHEME_EXTR_COUNT !== $type && \GRAPHEME_EXTR_MAXBYTES !== $type && \GRAPHEME_EXTR_MAXCHARS !== $type) {
            if (80000 > \PHP_VERSION_ID) {
                return false;
            }

            throw new \ValueError('grapheme_extract(): Argument #3 ($type) must be one of GRAPHEME_EXTR_COUNT, GRAPHEME_EXTR_MAXBYTES, or GRAPHEME_EXTR_MAXCHARS');
        }

        if (!isset($s[0]) || 0 > $size || 0 > $start) {
            return false;
        }
        if (0 === $size) {
            return '';
        }

        $next = $start;

        $s = preg_split('/('.SYMFONY_GRAPHEME_CLUSTER_RX.')/u', "\r\n".$s, $size + 1, \PREG_SPLIT_NO_EMPTY | \PREG_SPLIT_DELIM_CAPTURE);

        if (!isset($s[1])) {
            return false;
        }

        $i = 1;
        $ret = '';

        do {
            if (\GRAPHEME_EXTR_COUNT === $type) {
                --$size;
            } elseif (\GRAPHEME_EXTR_MAXBYTES === $type) {
                $size -= \strlen($s[$i]);
            } else {
                $size -= iconv_strlen($s[$i], 'UTF-8//IGNORE');
            }

            if ($size >= 0) {
                $ret .= $s[$i];
            }
        } while (isset($s[++$i]) && $size > 0);

        $next += \strlen($ret);

        return $ret;
    }

    public static function grapheme_strlen($s)
    {
        preg_replace('/'.SYMFONY_GRAPHEME_CLUSTER_RX.'/u', '', $s, -1, $len);

        return 0 === $len && '' !== $s ? null : $len;
    }

    public static function grapheme_substr($s, $start, $len = null)
    {
        if (null === $len) {
            $len = 2147483647;
        }

        preg_match_all('/'.SYMFONY_GRAPHEME_CLUSTER_RX.'/u', $s, $s);

        $slen = \count($s[0]);
        $start = (int) $start;

        if (0 > $start) {
            $start += $slen;
        }
        if (0 > $start) {
            if (\PHP_VERSION_ID < 80000) {
                return false;
            }

            $start = 0;
        }
        if ($start >= $slen) {
            return \PHP_VERSION_ID >= 80000 ? '' : false;
        }

        $rem = $slen - $start;

        if (0 > $len) {
            $len += $rem;
        }
        if (0 === $len) {
            return '';
        }
        if (0 > $len) {
            return \PHP_VERSION_ID >= 80000 ? '' : false;
        }
        if ($len > $rem) {
            $len = $rem;
        }

        return implode('', \array_slice($s[0], $start, $len));
    }

    public static function grapheme_strpos($s, $needle, $offset = 0)
    {
        return self::grapheme_position($s, $needle, $offset, 0);
    }

    public static function grapheme_stripos($s, $needle, $offset = 0)
    {
        return self::grapheme_position($s, $needle, $offset, 1);
    }

    public static function grapheme_strrpos($s, $needle, $offset = 0)
    {
        return self::grapheme_position($s, $needle, $offset, 2);
    }

    public static function grapheme_strripos($s, $needle, $offset = 0)
    {
        return self::grapheme_position($s, $needle, $offset, 3);
    }

    public static function grapheme_stristr($s, $needle, $beforeNeedle = false)
    {
        return mb_stristr($s, $needle, $beforeNeedle, 'UTF-8');
    }

    public static function grapheme_strstr($s, $needle, $beforeNeedle = false)
    {
        return mb_strstr($s, $needle, $beforeNeedle, 'UTF-8');
    }

    private static function grapheme_position($s, $needle, $offset, $mode)
    {
        $needle = (string) $needle;
        if (80000 > \PHP_VERSION_ID && !preg_match('/./us', $needle)) {
            return false;
        }
        $s = (string) $s;
        if (!preg_match('/./us', $s)) {
            return false;
        }
        if ($offset > 0) {
            $s = self::grapheme_substr($s, $offset);
        } elseif ($offset < 0) {
            if (2 > $mode) {
                $offset += self::grapheme_strlen($s);
                $s = self::grapheme_substr($s, $offset);
                if (0 > $offset) {
                    $offset = 0;
                }
            } elseif (0 > $offset += self::grapheme_strlen($needle)) {
                $s = self::grapheme_substr($s, 0, $offset);
                $offset = 0;
            } else {
                $offset = 0;
            }
        }

        // As UTF-8 is self-synchronizing, and we have ensured the strings are valid UTF-8,
        // we can use normal binary string functions here. For case-insensitive searches,
        // case fold the strings first.
        $caseInsensitive = $mode & 1;
        $reverse = $mode & 2;
        if ($caseInsensitive) {
            // Use the same case folding mode as mbstring does for mb_stripos().
            // Stick to SIMPLE case folding to avoid changing the length of the string, which
            // might result in offsets being shifted.
            $mode = \defined('MB_CASE_FOLD_SIMPLE') ? \MB_CASE_FOLD_SIMPLE : \MB_CASE_LOWER;
            $s = mb_convert_case($s, $mode, 'UTF-8');
            $needle = mb_convert_case($needle, $mode, 'UTF-8');

            if (!\defined('MB_CASE_FOLD_SIMPLE')) {
                $s = str_replace(self::CASE_FOLD[0], self::CASE_FOLD[1], $s);
                $needle = str_replace(self::CASE_FOLD[0], self::CASE_FOLD[1], $needle);
            }
        }
        if ($reverse) {
            $needlePos = strrpos($s, $needle);
        } else {
            $needlePos = strpos($s, $needle);
        }

        return false !== $needlePos ? self::grapheme_strlen(substr($s, 0, $needlePos)) + $offset : false;
    }
}
PKϤ$ZC�>KK polyfill-intl-grapheme/README.mdnu�[���Symfony Polyfill / Intl: Grapheme
=================================

This component provides a partial, native PHP implementation of the
[Grapheme functions](https://php.net/intl.grapheme) from the
[Intl](https://php.net/intl) extension.

- [`grapheme_extract`](https://php.net/grapheme_extract): Extract a sequence of grapheme
  clusters from a text buffer, which must be encoded in UTF-8
- [`grapheme_stripos`](https://php.net/grapheme_stripos): Find position (in grapheme units)
  of first occurrence of a case-insensitive string
- [`grapheme_stristr`](https://php.net/grapheme_stristr): Returns part of haystack string
  from the first occurrence of case-insensitive needle to the end of haystack
- [`grapheme_strlen`](https://php.net/grapheme_strlen): Get string length in grapheme units
- [`grapheme_strpos`](https://php.net/grapheme_strpos): Find position (in grapheme units)
  of first occurrence of a string
- [`grapheme_strripos`](https://php.net/grapheme_strripos): Find position (in grapheme units)
  of last occurrence of a case-insensitive string
- [`grapheme_strrpos`](https://php.net/grapheme_strrpos): Find position (in grapheme units)
  of last occurrence of a string
- [`grapheme_strstr`](https://php.net/grapheme_strstr): Returns part of haystack string from
  the first occurrence of needle to the end of haystack
- [`grapheme_substr`](https://php.net/grapheme_substr): Return part of a string

More information can be found in the
[main Polyfill README](https://github.com/symfony/polyfill/blob/main/README.md).

License
=======

This library is released under the [MIT license](LICENSE).
PKϤ$Z����$polyfill-intl-grapheme/bootstrap.phpnu�[���<?php

/*
 * This file is part of the Symfony package.
 *
 * (c) Fabien Potencier <fabien@symfony.com>
 *
 * For the full copyright and license information, please view the LICENSE
 * file that was distributed with this source code.
 */

use Symfony\Polyfill\Intl\Grapheme as p;

if (extension_loaded('intl')) {
    return;
}

if (\PHP_VERSION_ID >= 80000) {
    return require __DIR__.'/bootstrap80.php';
}

if (!defined('GRAPHEME_EXTR_COUNT')) {
    define('GRAPHEME_EXTR_COUNT', 0);
}
if (!defined('GRAPHEME_EXTR_MAXBYTES')) {
    define('GRAPHEME_EXTR_MAXBYTES', 1);
}
if (!defined('GRAPHEME_EXTR_MAXCHARS')) {
    define('GRAPHEME_EXTR_MAXCHARS', 2);
}

if (!function_exists('grapheme_extract')) {
    function grapheme_extract($haystack, $size, $type = 0, $start = 0, &$next = 0) { return p\Grapheme::grapheme_extract($haystack, $size, $type, $start, $next); }
}
if (!function_exists('grapheme_stripos')) {
    function grapheme_stripos($haystack, $needle, $offset = 0) { return p\Grapheme::grapheme_stripos($haystack, $needle, $offset); }
}
if (!function_exists('grapheme_stristr')) {
    function grapheme_stristr($haystack, $needle, $beforeNeedle = false) { return p\Grapheme::grapheme_stristr($haystack, $needle, $beforeNeedle); }
}
if (!function_exists('grapheme_strlen')) {
    function grapheme_strlen($input) { return p\Grapheme::grapheme_strlen($input); }
}
if (!function_exists('grapheme_strpos')) {
    function grapheme_strpos($haystack, $needle, $offset = 0) { return p\Grapheme::grapheme_strpos($haystack, $needle, $offset); }
}
if (!function_exists('grapheme_strripos')) {
    function grapheme_strripos($haystack, $needle, $offset = 0) { return p\Grapheme::grapheme_strripos($haystack, $needle, $offset); }
}
if (!function_exists('grapheme_strrpos')) {
    function grapheme_strrpos($haystack, $needle, $offset = 0) { return p\Grapheme::grapheme_strrpos($haystack, $needle, $offset); }
}
if (!function_exists('grapheme_strstr')) {
    function grapheme_strstr($haystack, $needle, $beforeNeedle = false) { return p\Grapheme::grapheme_strstr($haystack, $needle, $beforeNeedle); }
}
if (!function_exists('grapheme_substr')) {
    function grapheme_substr($string, $offset, $length = null) { return p\Grapheme::grapheme_substr($string, $offset, $length); }
}
PKϤ$Z�\�))polyfill-intl-grapheme/LICENSEnu�[���Copyright (c) 2015-2019 Fabien Potencier

Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is furnished
to do so, subject to the following conditions:

The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.

THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
THE SOFTWARE.
PKϤ$Z��E{g
g
&polyfill-intl-grapheme/bootstrap80.phpnu�[���<?php

/*
 * This file is part of the Symfony package.
 *
 * (c) Fabien Potencier <fabien@symfony.com>
 *
 * For the full copyright and license information, please view the LICENSE
 * file that was distributed with this source code.
 */

use Symfony\Polyfill\Intl\Grapheme as p;

if (!defined('GRAPHEME_EXTR_COUNT')) {
    define('GRAPHEME_EXTR_COUNT', 0);
}
if (!defined('GRAPHEME_EXTR_MAXBYTES')) {
    define('GRAPHEME_EXTR_MAXBYTES', 1);
}
if (!defined('GRAPHEME_EXTR_MAXCHARS')) {
    define('GRAPHEME_EXTR_MAXCHARS', 2);
}

if (!function_exists('grapheme_extract')) {
    function grapheme_extract(?string $haystack, ?int $size, ?int $type = GRAPHEME_EXTR_COUNT, ?int $offset = 0, &$next = null): string|false { return p\Grapheme::grapheme_extract((string) $haystack, (int) $size, (int) $type, (int) $offset, $next); }
}
if (!function_exists('grapheme_stripos')) {
    function grapheme_stripos(?string $haystack, ?string $needle, ?int $offset = 0): int|false { return p\Grapheme::grapheme_stripos((string) $haystack, (string) $needle, (int) $offset); }
}
if (!function_exists('grapheme_stristr')) {
    function grapheme_stristr(?string $haystack, ?string $needle, ?bool $beforeNeedle = false): string|false { return p\Grapheme::grapheme_stristr((string) $haystack, (string) $needle, (bool) $beforeNeedle); }
}
if (!function_exists('grapheme_strlen')) {
    function grapheme_strlen(?string $string): int|false|null { return p\Grapheme::grapheme_strlen((string) $string); }
}
if (!function_exists('grapheme_strpos')) {
    function grapheme_strpos(?string $haystack, ?string $needle, ?int $offset = 0): int|false { return p\Grapheme::grapheme_strpos((string) $haystack, (string) $needle, (int) $offset); }
}
if (!function_exists('grapheme_strripos')) {
    function grapheme_strripos(?string $haystack, ?string $needle, ?int $offset = 0): int|false { return p\Grapheme::grapheme_strripos((string) $haystack, (string) $needle, (int) $offset); }
}
if (!function_exists('grapheme_strrpos')) {
    function grapheme_strrpos(?string $haystack, ?string $needle, ?int $offset = 0): int|false { return p\Grapheme::grapheme_strrpos((string) $haystack, (string) $needle, (int) $offset); }
}
if (!function_exists('grapheme_strstr')) {
    function grapheme_strstr(?string $haystack, ?string $needle, ?bool $beforeNeedle = false): string|false { return p\Grapheme::grapheme_strstr((string) $haystack, (string) $needle, (bool) $beforeNeedle); }
}
if (!function_exists('grapheme_substr')) {
    function grapheme_substr(?string $string, ?int $offset, ?int $length = null): string|false { return p\Grapheme::grapheme_substr((string) $string, (int) $offset, $length); }
}
PKϤ$Z���))%http-foundation/ResponseHeaderBag.phpnu�[���<?php

/*
 * This file is part of the Symfony package.
 *
 * (c) Fabien Potencier <fabien@symfony.com>
 *
 * For the full copyright and license information, please view the LICENSE
 * file that was distributed with this source code.
 */

namespace Symfony\Component\HttpFoundation;

/**
 * ResponseHeaderBag is a container for Response HTTP headers.
 *
 * @author Fabien Potencier <fabien@symfony.com>
 */
class ResponseHeaderBag extends HeaderBag
{
    public const COOKIES_FLAT = 'flat';
    public const COOKIES_ARRAY = 'array';

    public const DISPOSITION_ATTACHMENT = 'attachment';
    public const DISPOSITION_INLINE = 'inline';

    protected $computedCacheControl = [];
    protected $cookies = [];
    protected $headerNames = [];

    public function __construct(array $headers = [])
    {
        parent::__construct($headers);

        if (!isset($this->headers['cache-control'])) {
            $this->set('Cache-Control', '');
        }

        /* RFC2616 - 14.18 says all Responses need to have a Date */
        if (!isset($this->headers['date'])) {
            $this->initDate();
        }
    }

    /**
     * Returns the headers, with original capitalizations.
     *
     * @return array An array of headers
     */
    public function allPreserveCase()
    {
        $headers = [];
        foreach ($this->all() as $name => $value) {
            $headers[$this->headerNames[$name] ?? $name] = $value;
        }

        return $headers;
    }

    public function allPreserveCaseWithoutCookies()
    {
        $headers = $this->allPreserveCase();
        if (isset($this->headerNames['set-cookie'])) {
            unset($headers[$this->headerNames['set-cookie']]);
        }

        return $headers;
    }

    /**
     * {@inheritdoc}
     */
    public function replace(array $headers = [])
    {
        $this->headerNames = [];

        parent::replace($headers);

        if (!isset($this->headers['cache-control'])) {
            $this->set('Cache-Control', '');
        }

        if (!isset($this->headers['date'])) {
            $this->initDate();
        }
    }

    /**
     * {@inheritdoc}
     */
    public function all(string $key = null)
    {
        $headers = parent::all();

        if (null !== $key) {
            $key = strtr($key, self::UPPER, self::LOWER);

            return 'set-cookie' !== $key ? $headers[$key] ?? [] : array_map('strval', $this->getCookies());
        }

        foreach ($this->getCookies() as $cookie) {
            $headers['set-cookie'][] = (string) $cookie;
        }

        return $headers;
    }

    /**
     * {@inheritdoc}
     */
    public function set(string $key, $values, bool $replace = true)
    {
        $uniqueKey = strtr($key, self::UPPER, self::LOWER);

        if ('set-cookie' === $uniqueKey) {
            if ($replace) {
                $this->cookies = [];
            }
            foreach ((array) $values as $cookie) {
                $this->setCookie(Cookie::fromString($cookie));
            }
            $this->headerNames[$uniqueKey] = $key;

            return;
        }

        $this->headerNames[$uniqueKey] = $key;

        parent::set($key, $values, $replace);

        // ensure the cache-control header has sensible defaults
        if (\in_array($uniqueKey, ['cache-control', 'etag', 'last-modified', 'expires'], true) && '' !== $computed = $this->computeCacheControlValue()) {
            $this->headers['cache-control'] = [$computed];
            $this->headerNames['cache-control'] = 'Cache-Control';
            $this->computedCacheControl = $this->parseCacheControl($computed);
        }
    }

    /**
     * {@inheritdoc}
     */
    public function remove(string $key)
    {
        $uniqueKey = strtr($key, self::UPPER, self::LOWER);
        unset($this->headerNames[$uniqueKey]);

        if ('set-cookie' === $uniqueKey) {
            $this->cookies = [];

            return;
        }

        parent::remove($key);

        if ('cache-control' === $uniqueKey) {
            $this->computedCacheControl = [];
        }

        if ('date' === $uniqueKey) {
            $this->initDate();
        }
    }

    /**
     * {@inheritdoc}
     */
    public function hasCacheControlDirective(string $key)
    {
        return \array_key_exists($key, $this->computedCacheControl);
    }

    /**
     * {@inheritdoc}
     */
    public function getCacheControlDirective(string $key)
    {
        return $this->computedCacheControl[$key] ?? null;
    }

    public function setCookie(Cookie $cookie)
    {
        $this->cookies[$cookie->getDomain()][$cookie->getPath()][$cookie->getName()] = $cookie;
        $this->headerNames['set-cookie'] = 'Set-Cookie';
    }

    /**
     * Removes a cookie from the array, but does not unset it in the browser.
     */
    public function removeCookie(string $name, ?string $path = '/', string $domain = null)
    {
        if (null === $path) {
            $path = '/';
        }

        unset($this->cookies[$domain][$path][$name]);

        if (empty($this->cookies[$domain][$path])) {
            unset($this->cookies[$domain][$path]);

            if (empty($this->cookies[$domain])) {
                unset($this->cookies[$domain]);
            }
        }

        if (empty($this->cookies)) {
            unset($this->headerNames['set-cookie']);
        }
    }

    /**
     * Returns an array with all cookies.
     *
     * @return Cookie[]
     *
     * @throws \InvalidArgumentException When the $format is invalid
     */
    public function getCookies(string $format = self::COOKIES_FLAT)
    {
        if (!\in_array($format, [self::COOKIES_FLAT, self::COOKIES_ARRAY])) {
            throw new \InvalidArgumentException(sprintf('Format "%s" invalid (%s).', $format, implode(', ', [self::COOKIES_FLAT, self::COOKIES_ARRAY])));
        }

        if (self::COOKIES_ARRAY === $format) {
            return $this->cookies;
        }

        $flattenedCookies = [];
        foreach ($this->cookies as $path) {
            foreach ($path as $cookies) {
                foreach ($cookies as $cookie) {
                    $flattenedCookies[] = $cookie;
                }
            }
        }

        return $flattenedCookies;
    }

    /**
     * Clears a cookie in the browser.
     */
    public function clearCookie(string $name, ?string $path = '/', string $domain = null, bool $secure = false, bool $httpOnly = true, string $sameSite = null)
    {
        $this->setCookie(new Cookie($name, null, 1, $path, $domain, $secure, $httpOnly, false, $sameSite));
    }

    /**
     * @see HeaderUtils::makeDisposition()
     */
    public function makeDisposition(string $disposition, string $filename, string $filenameFallback = '')
    {
        return HeaderUtils::makeDisposition($disposition, $filename, $filenameFallback);
    }

    /**
     * Returns the calculated value of the cache-control header.
     *
     * This considers several other headers and calculates or modifies the
     * cache-control header to a sensible, conservative value.
     *
     * @return string
     */
    protected function computeCacheControlValue()
    {
        if (!$this->cacheControl) {
            if ($this->has('Last-Modified') || $this->has('Expires')) {
                return 'private, must-revalidate'; // allows for heuristic expiration (RFC 7234 Section 4.2.2) in the case of "Last-Modified"
            }

            // conservative by default
            return 'no-cache, private';
        }

        $header = $this->getCacheControlHeader();
        if (isset($this->cacheControl['public']) || isset($this->cacheControl['private'])) {
            return $header;
        }

        // public if s-maxage is defined, private otherwise
        if (!isset($this->cacheControl['s-maxage'])) {
            return $header.', private';
        }

        return $header;
    }

    private function initDate(): void
    {
        $this->set('Date', gmdate('D, d M Y H:i:s').' GMT');
    }
}
PKϤ$Z�"T�http-foundation/UrlHelper.phpnu�[���<?php

/*
 * This file is part of the Symfony package.
 *
 * (c) Fabien Potencier <fabien@symfony.com>
 *
 * For the full copyright and license information, please view the LICENSE
 * file that was distributed with this source code.
 */

namespace Symfony\Component\HttpFoundation;

use Symfony\Component\Routing\RequestContext;

/**
 * A helper service for manipulating URLs within and outside the request scope.
 *
 * @author Valentin Udaltsov <udaltsov.valentin@gmail.com>
 */
final class UrlHelper
{
    private $requestStack;
    private $requestContext;

    public function __construct(RequestStack $requestStack, RequestContext $requestContext = null)
    {
        $this->requestStack = $requestStack;
        $this->requestContext = $requestContext;
    }

    public function getAbsoluteUrl(string $path): string
    {
        if (str_contains($path, '://') || '//' === substr($path, 0, 2)) {
            return $path;
        }

        if (null === $request = $this->requestStack->getMainRequest()) {
            return $this->getAbsoluteUrlFromContext($path);
        }

        if ('#' === $path[0]) {
            $path = $request->getRequestUri().$path;
        } elseif ('?' === $path[0]) {
            $path = $request->getPathInfo().$path;
        }

        if (!$path || '/' !== $path[0]) {
            $prefix = $request->getPathInfo();
            $last = \strlen($prefix) - 1;
            if ($last !== $pos = strrpos($prefix, '/')) {
                $prefix = substr($prefix, 0, $pos).'/';
            }

            return $request->getUriForPath($prefix.$path);
        }

        return $request->getSchemeAndHttpHost().$path;
    }

    public function getRelativePath(string $path): string
    {
        if (str_contains($path, '://') || '//' === substr($path, 0, 2)) {
            return $path;
        }

        if (null === $request = $this->requestStack->getMainRequest()) {
            return $path;
        }

        return $request->getRelativeUriForPath($path);
    }

    private function getAbsoluteUrlFromContext(string $path): string
    {
        if (null === $this->requestContext || '' === $host = $this->requestContext->getHost()) {
            return $path;
        }

        $scheme = $this->requestContext->getScheme();
        $port = '';

        if ('http' === $scheme && 80 !== $this->requestContext->getHttpPort()) {
            $port = ':'.$this->requestContext->getHttpPort();
        } elseif ('https' === $scheme && 443 !== $this->requestContext->getHttpsPort()) {
            $port = ':'.$this->requestContext->getHttpsPort();
        }

        if ('#' === $path[0]) {
            $queryString = $this->requestContext->getQueryString();
            $path = $this->requestContext->getPathInfo().($queryString ? '?'.$queryString : '').$path;
        } elseif ('?' === $path[0]) {
            $path = $this->requestContext->getPathInfo().$path;
        }

        if ('/' !== $path[0]) {
            $path = rtrim($this->requestContext->getBaseUrl(), '/').'/'.$path;
        }

        return $scheme.'://'.$host.$port.$path;
    }
}
PKϤ$Z�Ϡ!gg#http-foundation/Session/Session.phpnu�[���<?php

/*
 * This file is part of the Symfony package.
 *
 * (c) Fabien Potencier <fabien@symfony.com>
 *
 * For the full copyright and license information, please view the LICENSE
 * file that was distributed with this source code.
 */

namespace Symfony\Component\HttpFoundation\Session;

use Symfony\Component\HttpFoundation\Session\Attribute\AttributeBag;
use Symfony\Component\HttpFoundation\Session\Attribute\AttributeBagInterface;
use Symfony\Component\HttpFoundation\Session\Flash\FlashBag;
use Symfony\Component\HttpFoundation\Session\Flash\FlashBagInterface;
use Symfony\Component\HttpFoundation\Session\Storage\NativeSessionStorage;
use Symfony\Component\HttpFoundation\Session\Storage\SessionStorageInterface;

// Help opcache.preload discover always-needed symbols
class_exists(AttributeBag::class);
class_exists(FlashBag::class);
class_exists(SessionBagProxy::class);

/**
 * @author Fabien Potencier <fabien@symfony.com>
 * @author Drak <drak@zikula.org>
 */
class Session implements SessionInterface, \IteratorAggregate, \Countable
{
    protected $storage;

    private $flashName;
    private $attributeName;
    private $data = [];
    private $usageIndex = 0;
    private $usageReporter;

    public function __construct(SessionStorageInterface $storage = null, AttributeBagInterface $attributes = null, FlashBagInterface $flashes = null, callable $usageReporter = null)
    {
        $this->storage = $storage ?? new NativeSessionStorage();
        $this->usageReporter = $usageReporter;

        $attributes = $attributes ?? new AttributeBag();
        $this->attributeName = $attributes->getName();
        $this->registerBag($attributes);

        $flashes = $flashes ?? new FlashBag();
        $this->flashName = $flashes->getName();
        $this->registerBag($flashes);
    }

    /**
     * {@inheritdoc}
     */
    public function start()
    {
        return $this->storage->start();
    }

    /**
     * {@inheritdoc}
     */
    public function has(string $name)
    {
        return $this->getAttributeBag()->has($name);
    }

    /**
     * {@inheritdoc}
     */
    public function get(string $name, $default = null)
    {
        return $this->getAttributeBag()->get($name, $default);
    }

    /**
     * {@inheritdoc}
     */
    public function set(string $name, $value)
    {
        $this->getAttributeBag()->set($name, $value);
    }

    /**
     * {@inheritdoc}
     */
    public function all()
    {
        return $this->getAttributeBag()->all();
    }

    /**
     * {@inheritdoc}
     */
    public function replace(array $attributes)
    {
        $this->getAttributeBag()->replace($attributes);
    }

    /**
     * {@inheritdoc}
     */
    public function remove(string $name)
    {
        return $this->getAttributeBag()->remove($name);
    }

    /**
     * {@inheritdoc}
     */
    public function clear()
    {
        $this->getAttributeBag()->clear();
    }

    /**
     * {@inheritdoc}
     */
    public function isStarted()
    {
        return $this->storage->isStarted();
    }

    /**
     * Returns an iterator for attributes.
     *
     * @return \ArrayIterator An \ArrayIterator instance
     */
    #[\ReturnTypeWillChange]
    public function getIterator()
    {
        return new \ArrayIterator($this->getAttributeBag()->all());
    }

    /**
     * Returns the number of attributes.
     *
     * @return int
     */
    #[\ReturnTypeWillChange]
    public function count()
    {
        return \count($this->getAttributeBag()->all());
    }

    public function &getUsageIndex(): int
    {
        return $this->usageIndex;
    }

    /**
     * @internal
     */
    public function isEmpty(): bool
    {
        if ($this->isStarted()) {
            ++$this->usageIndex;
            if ($this->usageReporter && 0 <= $this->usageIndex) {
                ($this->usageReporter)();
            }
        }
        foreach ($this->data as &$data) {
            if (!empty($data)) {
                return false;
            }
        }

        return true;
    }

    /**
     * {@inheritdoc}
     */
    public function invalidate(int $lifetime = null)
    {
        $this->storage->clear();

        return $this->migrate(true, $lifetime);
    }

    /**
     * {@inheritdoc}
     */
    public function migrate(bool $destroy = false, int $lifetime = null)
    {
        return $this->storage->regenerate($destroy, $lifetime);
    }

    /**
     * {@inheritdoc}
     */
    public function save()
    {
        $this->storage->save();
    }

    /**
     * {@inheritdoc}
     */
    public function getId()
    {
        return $this->storage->getId();
    }

    /**
     * {@inheritdoc}
     */
    public function setId(string $id)
    {
        if ($this->storage->getId() !== $id) {
            $this->storage->setId($id);
        }
    }

    /**
     * {@inheritdoc}
     */
    public function getName()
    {
        return $this->storage->getName();
    }

    /**
     * {@inheritdoc}
     */
    public function setName(string $name)
    {
        $this->storage->setName($name);
    }

    /**
     * {@inheritdoc}
     */
    public function getMetadataBag()
    {
        ++$this->usageIndex;
        if ($this->usageReporter && 0 <= $this->usageIndex) {
            ($this->usageReporter)();
        }

        return $this->storage->getMetadataBag();
    }

    /**
     * {@inheritdoc}
     */
    public function registerBag(SessionBagInterface $bag)
    {
        $this->storage->registerBag(new SessionBagProxy($bag, $this->data, $this->usageIndex, $this->usageReporter));
    }

    /**
     * {@inheritdoc}
     */
    public function getBag(string $name)
    {
        $bag = $this->storage->getBag($name);

        return method_exists($bag, 'getBag') ? $bag->getBag() : $bag;
    }

    /**
     * Gets the flashbag interface.
     *
     * @return FlashBagInterface
     */
    public function getFlashBag()
    {
        return $this->getBag($this->flashName);
    }

    /**
     * Gets the attributebag interface.
     *
     * Note that this method was added to help with IDE autocompletion.
     */
    private function getAttributeBag(): AttributeBagInterface
    {
        return $this->getBag($this->attributeName);
    }
}
PKϤ$Z\Ȣ��*http-foundation/Session/SessionFactory.phpnu�[���<?php

/*
 * This file is part of the Symfony package.
 *
 * (c) Fabien Potencier <fabien@symfony.com>
 *
 * For the full copyright and license information, please view the LICENSE
 * file that was distributed with this source code.
 */

namespace Symfony\Component\HttpFoundation\Session;

use Symfony\Component\HttpFoundation\RequestStack;
use Symfony\Component\HttpFoundation\Session\Storage\SessionStorageFactoryInterface;

// Help opcache.preload discover always-needed symbols
class_exists(Session::class);

/**
 * @author Jérémy Derussé <jeremy@derusse.com>
 */
class SessionFactory
{
    private $requestStack;
    private $storageFactory;
    private $usageReporter;

    public function __construct(RequestStack $requestStack, SessionStorageFactoryInterface $storageFactory, callable $usageReporter = null)
    {
        $this->requestStack = $requestStack;
        $this->storageFactory = $storageFactory;
        $this->usageReporter = $usageReporter;
    }

    public function createSession(): SessionInterface
    {
        return new Session($this->storageFactory->createStorage($this->requestStack->getMainRequest()), null, null, $this->usageReporter);
    }
}
PKϤ$Z��<<,http-foundation/Session/SessionInterface.phpnu�[���<?php

/*
 * This file is part of the Symfony package.
 *
 * (c) Fabien Potencier <fabien@symfony.com>
 *
 * For the full copyright and license information, please view the LICENSE
 * file that was distributed with this source code.
 */

namespace Symfony\Component\HttpFoundation\Session;

use Symfony\Component\HttpFoundation\Session\Storage\MetadataBag;

/**
 * Interface for the session.
 *
 * @author Drak <drak@zikula.org>
 */
interface SessionInterface
{
    /**
     * Starts the session storage.
     *
     * @return bool
     *
     * @throws \RuntimeException if session fails to start
     */
    public function start();

    /**
     * Returns the session ID.
     *
     * @return string
     */
    public function getId();

    /**
     * Sets the session ID.
     */
    public function setId(string $id);

    /**
     * Returns the session name.
     *
     * @return string
     */
    public function getName();

    /**
     * Sets the session name.
     */
    public function setName(string $name);

    /**
     * Invalidates the current session.
     *
     * Clears all session attributes and flashes and regenerates the
     * session and deletes the old session from persistence.
     *
     * @param int $lifetime Sets the cookie lifetime for the session cookie. A null value
     *                      will leave the system settings unchanged, 0 sets the cookie
     *                      to expire with browser session. Time is in seconds, and is
     *                      not a Unix timestamp.
     *
     * @return bool
     */
    public function invalidate(int $lifetime = null);

    /**
     * Migrates the current session to a new session id while maintaining all
     * session attributes.
     *
     * @param bool $destroy  Whether to delete the old session or leave it to garbage collection
     * @param int  $lifetime Sets the cookie lifetime for the session cookie. A null value
     *                       will leave the system settings unchanged, 0 sets the cookie
     *                       to expire with browser session. Time is in seconds, and is
     *                       not a Unix timestamp.
     *
     * @return bool
     */
    public function migrate(bool $destroy = false, int $lifetime = null);

    /**
     * Force the session to be saved and closed.
     *
     * This method is generally not required for real sessions as
     * the session will be automatically saved at the end of
     * code execution.
     */
    public function save();

    /**
     * Checks if an attribute is defined.
     *
     * @return bool
     */
    public function has(string $name);

    /**
     * Returns an attribute.
     *
     * @param mixed $default The default value if not found
     *
     * @return mixed
     */
    public function get(string $name, $default = null);

    /**
     * Sets an attribute.
     *
     * @param mixed $value
     */
    public function set(string $name, $value);

    /**
     * Returns attributes.
     *
     * @return array
     */
    public function all();

    /**
     * Sets attributes.
     */
    public function replace(array $attributes);

    /**
     * Removes an attribute.
     *
     * @return mixed The removed value or null when it does not exist
     */
    public function remove(string $name);

    /**
     * Clears all attributes.
     */
    public function clear();

    /**
     * Checks if the session was started.
     *
     * @return bool
     */
    public function isStarted();

    /**
     * Registers a SessionBagInterface with the session.
     */
    public function registerBag(SessionBagInterface $bag);

    /**
     * Gets a bag instance by name.
     *
     * @return SessionBagInterface
     */
    public function getBag(string $name);

    /**
     * Gets session meta.
     *
     * @return MetadataBag
     */
    public function getMetadataBag();
}
PKϤ$Z�6�))+http-foundation/Session/SessionBagProxy.phpnu�[���<?php

/*
 * This file is part of the Symfony package.
 *
 * (c) Fabien Potencier <fabien@symfony.com>
 *
 * For the full copyright and license information, please view the LICENSE
 * file that was distributed with this source code.
 */

namespace Symfony\Component\HttpFoundation\Session;

/**
 * @author Nicolas Grekas <p@tchwork.com>
 *
 * @internal
 */
final class SessionBagProxy implements SessionBagInterface
{
    private $bag;
    private $data;
    private $usageIndex;
    private $usageReporter;

    public function __construct(SessionBagInterface $bag, array &$data, ?int &$usageIndex, ?callable $usageReporter)
    {
        $this->bag = $bag;
        $this->data = &$data;
        $this->usageIndex = &$usageIndex;
        $this->usageReporter = $usageReporter;
    }

    public function getBag(): SessionBagInterface
    {
        ++$this->usageIndex;
        if ($this->usageReporter && 0 <= $this->usageIndex) {
            ($this->usageReporter)();
        }

        return $this->bag;
    }

    public function isEmpty(): bool
    {
        if (!isset($this->data[$this->bag->getStorageKey()])) {
            return true;
        }
        ++$this->usageIndex;
        if ($this->usageReporter && 0 <= $this->usageIndex) {
            ($this->usageReporter)();
        }

        return empty($this->data[$this->bag->getStorageKey()]);
    }

    /**
     * {@inheritdoc}
     */
    public function getName(): string
    {
        return $this->bag->getName();
    }

    /**
     * {@inheritdoc}
     */
    public function initialize(array &$array): void
    {
        ++$this->usageIndex;
        if ($this->usageReporter && 0 <= $this->usageIndex) {
            ($this->usageReporter)();
        }

        $this->data[$this->bag->getStorageKey()] = &$array;

        $this->bag->initialize($array);
    }

    /**
     * {@inheritdoc}
     */
    public function getStorageKey(): string
    {
        return $this->bag->getStorageKey();
    }

    /**
     * {@inheritdoc}
     */
    public function clear()
    {
        return $this->bag->clear();
    }
}
PKϤ$Z�n$�QQ/http-foundation/Session/SessionBagInterface.phpnu�[���<?php

/*
 * This file is part of the Symfony package.
 *
 * (c) Fabien Potencier <fabien@symfony.com>
 *
 * For the full copyright and license information, please view the LICENSE
 * file that was distributed with this source code.
 */

namespace Symfony\Component\HttpFoundation\Session;

/**
 * Session Bag store.
 *
 * @author Drak <drak@zikula.org>
 */
interface SessionBagInterface
{
    /**
     * Gets this bag's name.
     *
     * @return string
     */
    public function getName();

    /**
     * Initializes the Bag.
     */
    public function initialize(array &$array);

    /**
     * Gets the storage key for this bag.
     *
     * @return string
     */
    public function getStorageKey();

    /**
     * Clears out data from bag.
     *
     * @return mixed Whatever data was contained
     */
    public function clear();
}
PKϤ$Z�Et+RR3http-foundation/Session/Flash/FlashBagInterface.phpnu�[���<?php

/*
 * This file is part of the Symfony package.
 *
 * (c) Fabien Potencier <fabien@symfony.com>
 *
 * For the full copyright and license information, please view the LICENSE
 * file that was distributed with this source code.
 */

namespace Symfony\Component\HttpFoundation\Session\Flash;

use Symfony\Component\HttpFoundation\Session\SessionBagInterface;

/**
 * FlashBagInterface.
 *
 * @author Drak <drak@zikula.org>
 */
interface FlashBagInterface extends SessionBagInterface
{
    /**
     * Adds a flash message for the given type.
     *
     * @param mixed $message
     */
    public function add(string $type, $message);

    /**
     * Registers one or more messages for a given type.
     *
     * @param string|array $messages
     */
    public function set(string $type, $messages);

    /**
     * Gets flash messages for a given type.
     *
     * @param string $type    Message category type
     * @param array  $default Default value if $type does not exist
     *
     * @return array
     */
    public function peek(string $type, array $default = []);

    /**
     * Gets all flash messages.
     *
     * @return array
     */
    public function peekAll();

    /**
     * Gets and clears flash from the stack.
     *
     * @param array $default Default value if $type does not exist
     *
     * @return array
     */
    public function get(string $type, array $default = []);

    /**
     * Gets and clears flashes from the stack.
     *
     * @return array
     */
    public function all();

    /**
     * Sets all flash messages.
     */
    public function setAll(array $messages);

    /**
     * Has flash messages for a given type?
     *
     * @return bool
     */
    public function has(string $type);

    /**
     * Returns a list of all defined types.
     *
     * @return array
     */
    public function keys();
}
PKϤ$Z`�D�
�
*http-foundation/Session/Flash/FlashBag.phpnu�[���<?php

/*
 * This file is part of the Symfony package.
 *
 * (c) Fabien Potencier <fabien@symfony.com>
 *
 * For the full copyright and license information, please view the LICENSE
 * file that was distributed with this source code.
 */

namespace Symfony\Component\HttpFoundation\Session\Flash;

/**
 * FlashBag flash message container.
 *
 * @author Drak <drak@zikula.org>
 */
class FlashBag implements FlashBagInterface
{
    private $name = 'flashes';
    private $flashes = [];
    private $storageKey;

    /**
     * @param string $storageKey The key used to store flashes in the session
     */
    public function __construct(string $storageKey = '_symfony_flashes')
    {
        $this->storageKey = $storageKey;
    }

    /**
     * {@inheritdoc}
     */
    public function getName()
    {
        return $this->name;
    }

    public function setName(string $name)
    {
        $this->name = $name;
    }

    /**
     * {@inheritdoc}
     */
    public function initialize(array &$flashes)
    {
        $this->flashes = &$flashes;
    }

    /**
     * {@inheritdoc}
     */
    public function add(string $type, $message)
    {
        $this->flashes[$type][] = $message;
    }

    /**
     * {@inheritdoc}
     */
    public function peek(string $type, array $default = [])
    {
        return $this->has($type) ? $this->flashes[$type] : $default;
    }

    /**
     * {@inheritdoc}
     */
    public function peekAll()
    {
        return $this->flashes;
    }

    /**
     * {@inheritdoc}
     */
    public function get(string $type, array $default = [])
    {
        if (!$this->has($type)) {
            return $default;
        }

        $return = $this->flashes[$type];

        unset($this->flashes[$type]);

        return $return;
    }

    /**
     * {@inheritdoc}
     */
    public function all()
    {
        $return = $this->peekAll();
        $this->flashes = [];

        return $return;
    }

    /**
     * {@inheritdoc}
     */
    public function set(string $type, $messages)
    {
        $this->flashes[$type] = (array) $messages;
    }

    /**
     * {@inheritdoc}
     */
    public function setAll(array $messages)
    {
        $this->flashes = $messages;
    }

    /**
     * {@inheritdoc}
     */
    public function has(string $type)
    {
        return \array_key_exists($type, $this->flashes) && $this->flashes[$type];
    }

    /**
     * {@inheritdoc}
     */
    public function keys()
    {
        return array_keys($this->flashes);
    }

    /**
     * {@inheritdoc}
     */
    public function getStorageKey()
    {
        return $this->storageKey;
    }

    /**
     * {@inheritdoc}
     */
    public function clear()
    {
        return $this->all();
    }
}
PKϤ$Z�X��
�
4http-foundation/Session/Flash/AutoExpireFlashBag.phpnu�[���<?php

/*
 * This file is part of the Symfony package.
 *
 * (c) Fabien Potencier <fabien@symfony.com>
 *
 * For the full copyright and license information, please view the LICENSE
 * file that was distributed with this source code.
 */

namespace Symfony\Component\HttpFoundation\Session\Flash;

/**
 * AutoExpireFlashBag flash message container.
 *
 * @author Drak <drak@zikula.org>
 */
class AutoExpireFlashBag implements FlashBagInterface
{
    private $name = 'flashes';
    private $flashes = ['display' => [], 'new' => []];
    private $storageKey;

    /**
     * @param string $storageKey The key used to store flashes in the session
     */
    public function __construct(string $storageKey = '_symfony_flashes')
    {
        $this->storageKey = $storageKey;
    }

    /**
     * {@inheritdoc}
     */
    public function getName()
    {
        return $this->name;
    }

    public function setName(string $name)
    {
        $this->name = $name;
    }

    /**
     * {@inheritdoc}
     */
    public function initialize(array &$flashes)
    {
        $this->flashes = &$flashes;

        // The logic: messages from the last request will be stored in new, so we move them to previous
        // This request we will show what is in 'display'.  What is placed into 'new' this time round will
        // be moved to display next time round.
        $this->flashes['display'] = \array_key_exists('new', $this->flashes) ? $this->flashes['new'] : [];
        $this->flashes['new'] = [];
    }

    /**
     * {@inheritdoc}
     */
    public function add(string $type, $message)
    {
        $this->flashes['new'][$type][] = $message;
    }

    /**
     * {@inheritdoc}
     */
    public function peek(string $type, array $default = [])
    {
        return $this->has($type) ? $this->flashes['display'][$type] : $default;
    }

    /**
     * {@inheritdoc}
     */
    public function peekAll()
    {
        return \array_key_exists('display', $this->flashes) ? (array) $this->flashes['display'] : [];
    }

    /**
     * {@inheritdoc}
     */
    public function get(string $type, array $default = [])
    {
        $return = $default;

        if (!$this->has($type)) {
            return $return;
        }

        if (isset($this->flashes['display'][$type])) {
            $return = $this->flashes['display'][$type];
            unset($this->flashes['display'][$type]);
        }

        return $return;
    }

    /**
     * {@inheritdoc}
     */
    public function all()
    {
        $return = $this->flashes['display'];
        $this->flashes['display'] = [];

        return $return;
    }

    /**
     * {@inheritdoc}
     */
    public function setAll(array $messages)
    {
        $this->flashes['new'] = $messages;
    }

    /**
     * {@inheritdoc}
     */
    public function set(string $type, $messages)
    {
        $this->flashes['new'][$type] = (array) $messages;
    }

    /**
     * {@inheritdoc}
     */
    public function has(string $type)
    {
        return \array_key_exists($type, $this->flashes['display']) && $this->flashes['display'][$type];
    }

    /**
     * {@inheritdoc}
     */
    public function keys()
    {
        return array_keys($this->flashes['display']);
    }

    /**
     * {@inheritdoc}
     */
    public function getStorageKey()
    {
        return $this->storageKey;
    }

    /**
     * {@inheritdoc}
     */
    public function clear()
    {
        return $this->all();
    }
}
PKϤ$Z�g���Bhttp-foundation/Session/Storage/PhpBridgeSessionStorageFactory.phpnu�[���<?php

/*
 * This file is part of the Symfony package.
 *
 * (c) Fabien Potencier <fabien@symfony.com>
 *
 * For the full copyright and license information, please view the LICENSE
 * file that was distributed with this source code.
 */

namespace Symfony\Component\HttpFoundation\Session\Storage;

use Symfony\Component\HttpFoundation\Request;

// Help opcache.preload discover always-needed symbols
class_exists(PhpBridgeSessionStorage::class);

/**
 * @author Jérémy Derussé <jeremy@derusse.com>
 */
class PhpBridgeSessionStorageFactory implements SessionStorageFactoryInterface
{
    private $handler;
    private $metaBag;
    private $secure;

    /**
     * @see PhpBridgeSessionStorage constructor.
     */
    public function __construct($handler = null, MetadataBag $metaBag = null, bool $secure = false)
    {
        $this->handler = $handler;
        $this->metaBag = $metaBag;
        $this->secure = $secure;
    }

    public function createStorage(?Request $request): SessionStorageInterface
    {
        $storage = new PhpBridgeSessionStorage($this->handler, $this->metaBag);
        if ($this->secure && $request && $request->isSecure()) {
            $storage->setOptions(['cookie_secure' => true]);
        }

        return $storage;
    }
}
PKϤ$Z 2CW��;http-foundation/Session/Storage/MockArraySessionStorage.phpnu�[���<?php

/*
 * This file is part of the Symfony package.
 *
 * (c) Fabien Potencier <fabien@symfony.com>
 *
 * For the full copyright and license information, please view the LICENSE
 * file that was distributed with this source code.
 */

namespace Symfony\Component\HttpFoundation\Session\Storage;

use Symfony\Component\HttpFoundation\Session\SessionBagInterface;

/**
 * MockArraySessionStorage mocks the session for unit tests.
 *
 * No PHP session is actually started since a session can be initialized
 * and shutdown only once per PHP execution cycle.
 *
 * When doing functional testing, you should use MockFileSessionStorage instead.
 *
 * @author Fabien Potencier <fabien@symfony.com>
 * @author Bulat Shakirzyanov <mallluhuct@gmail.com>
 * @author Drak <drak@zikula.org>
 */
class MockArraySessionStorage implements SessionStorageInterface
{
    /**
     * @var string
     */
    protected $id = '';

    /**
     * @var string
     */
    protected $name;

    /**
     * @var bool
     */
    protected $started = false;

    /**
     * @var bool
     */
    protected $closed = false;

    /**
     * @var array
     */
    protected $data = [];

    /**
     * @var MetadataBag
     */
    protected $metadataBag;

    /**
     * @var array|SessionBagInterface[]
     */
    protected $bags = [];

    public function __construct(string $name = 'MOCKSESSID', MetadataBag $metaBag = null)
    {
        $this->name = $name;
        $this->setMetadataBag($metaBag);
    }

    public function setSessionData(array $array)
    {
        $this->data = $array;
    }

    /**
     * {@inheritdoc}
     */
    public function start()
    {
        if ($this->started) {
            return true;
        }

        if (empty($this->id)) {
            $this->id = $this->generateId();
        }

        $this->loadSession();

        return true;
    }

    /**
     * {@inheritdoc}
     */
    public function regenerate(bool $destroy = false, int $lifetime = null)
    {
        if (!$this->started) {
            $this->start();
        }

        $this->metadataBag->stampNew($lifetime);
        $this->id = $this->generateId();

        return true;
    }

    /**
     * {@inheritdoc}
     */
    public function getId()
    {
        return $this->id;
    }

    /**
     * {@inheritdoc}
     */
    public function setId(string $id)
    {
        if ($this->started) {
            throw new \LogicException('Cannot set session ID after the session has started.');
        }

        $this->id = $id;
    }

    /**
     * {@inheritdoc}
     */
    public function getName()
    {
        return $this->name;
    }

    /**
     * {@inheritdoc}
     */
    public function setName(string $name)
    {
        $this->name = $name;
    }

    /**
     * {@inheritdoc}
     */
    public function save()
    {
        if (!$this->started || $this->closed) {
            throw new \RuntimeException('Trying to save a session that was not started yet or was already closed.');
        }
        // nothing to do since we don't persist the session data
        $this->closed = false;
        $this->started = false;
    }

    /**
     * {@inheritdoc}
     */
    public function clear()
    {
        // clear out the bags
        foreach ($this->bags as $bag) {
            $bag->clear();
        }

        // clear out the session
        $this->data = [];

        // reconnect the bags to the session
        $this->loadSession();
    }

    /**
     * {@inheritdoc}
     */
    public function registerBag(SessionBagInterface $bag)
    {
        $this->bags[$bag->getName()] = $bag;
    }

    /**
     * {@inheritdoc}
     */
    public function getBag(string $name)
    {
        if (!isset($this->bags[$name])) {
            throw new \InvalidArgumentException(sprintf('The SessionBagInterface "%s" is not registered.', $name));
        }

        if (!$this->started) {
            $this->start();
        }

        return $this->bags[$name];
    }

    /**
     * {@inheritdoc}
     */
    public function isStarted()
    {
        return $this->started;
    }

    public function setMetadataBag(MetadataBag $bag = null)
    {
        if (null === $bag) {
            $bag = new MetadataBag();
        }

        $this->metadataBag = $bag;
    }

    /**
     * Gets the MetadataBag.
     *
     * @return MetadataBag
     */
    public function getMetadataBag()
    {
        return $this->metadataBag;
    }

    /**
     * Generates a session ID.
     *
     * This doesn't need to be particularly cryptographically secure since this is just
     * a mock.
     *
     * @return string
     */
    protected function generateId()
    {
        return hash('sha256', uniqid('ss_mock_', true));
    }

    protected function loadSession()
    {
        $bags = array_merge($this->bags, [$this->metadataBag]);

        foreach ($bags as $bag) {
            $key = $bag->getStorageKey();
            $this->data[$key] = $this->data[$key] ?? [];
            $bag->initialize($this->data[$key]);
        }

        $this->started = true;
        $this->closed = false;
    }
}
PKϤ$Z�w���:http-foundation/Session/Storage/MockFileSessionStorage.phpnu�[���<?php

/*
 * This file is part of the Symfony package.
 *
 * (c) Fabien Potencier <fabien@symfony.com>
 *
 * For the full copyright and license information, please view the LICENSE
 * file that was distributed with this source code.
 */

namespace Symfony\Component\HttpFoundation\Session\Storage;

/**
 * MockFileSessionStorage is used to mock sessions for
 * functional testing when done in a single PHP process.
 *
 * No PHP session is actually started since a session can be initialized
 * and shutdown only once per PHP execution cycle and this class does
 * not pollute any session related globals, including session_*() functions
 * or session.* PHP ini directives.
 *
 * @author Drak <drak@zikula.org>
 */
class MockFileSessionStorage extends MockArraySessionStorage
{
    private $savePath;

    /**
     * @param string $savePath Path of directory to save session files
     */
    public function __construct(string $savePath = null, string $name = 'MOCKSESSID', MetadataBag $metaBag = null)
    {
        if (null === $savePath) {
            $savePath = sys_get_temp_dir();
        }

        if (!is_dir($savePath) && !@mkdir($savePath, 0777, true) && !is_dir($savePath)) {
            throw new \RuntimeException(sprintf('Session Storage was not able to create directory "%s".', $savePath));
        }

        $this->savePath = $savePath;

        parent::__construct($name, $metaBag);
    }

    /**
     * {@inheritdoc}
     */
    public function start()
    {
        if ($this->started) {
            return true;
        }

        if (!$this->id) {
            $this->id = $this->generateId();
        }

        $this->read();

        $this->started = true;

        return true;
    }

    /**
     * {@inheritdoc}
     */
    public function regenerate(bool $destroy = false, int $lifetime = null)
    {
        if (!$this->started) {
            $this->start();
        }

        if ($destroy) {
            $this->destroy();
        }

        return parent::regenerate($destroy, $lifetime);
    }

    /**
     * {@inheritdoc}
     */
    public function save()
    {
        if (!$this->started) {
            throw new \RuntimeException('Trying to save a session that was not started yet or was already closed.');
        }

        $data = $this->data;

        foreach ($this->bags as $bag) {
            if (empty($data[$key = $bag->getStorageKey()])) {
                unset($data[$key]);
            }
        }
        if ([$key = $this->metadataBag->getStorageKey()] === array_keys($data)) {
            unset($data[$key]);
        }

        try {
            if ($data) {
                $path = $this->getFilePath();
                $tmp = $path.bin2hex(random_bytes(6));
                file_put_contents($tmp, serialize($data));
                rename($tmp, $path);
            } else {
                $this->destroy();
            }
        } finally {
            $this->data = $data;
        }

        // this is needed when the session object is re-used across multiple requests
        // in functional tests.
        $this->started = false;
    }

    /**
     * Deletes a session from persistent storage.
     * Deliberately leaves session data in memory intact.
     */
    private function destroy(): void
    {
        set_error_handler(static function () {});
        try {
            unlink($this->getFilePath());
        } finally {
            restore_error_handler();
        }
    }

    /**
     * Calculate path to file.
     */
    private function getFilePath(): string
    {
        return $this->savePath.'/'.$this->id.'.mocksess';
    }

    /**
     * Reads session from storage and loads session.
     */
    private function read(): void
    {
        set_error_handler(static function () {});
        try {
            $data = file_get_contents($this->getFilePath());
        } finally {
            restore_error_handler();
        }

        $this->data = $data ? unserialize($data) : [];

        $this->loadSession();
    }
}
PKϤ$Z\�
,FF/http-foundation/Session/Storage/MetadataBag.phpnu�[���<?php

/*
 * This file is part of the Symfony package.
 *
 * (c) Fabien Potencier <fabien@symfony.com>
 *
 * For the full copyright and license information, please view the LICENSE
 * file that was distributed with this source code.
 */

namespace Symfony\Component\HttpFoundation\Session\Storage;

use Symfony\Component\HttpFoundation\Session\SessionBagInterface;

/**
 * Metadata container.
 *
 * Adds metadata to the session.
 *
 * @author Drak <drak@zikula.org>
 */
class MetadataBag implements SessionBagInterface
{
    public const CREATED = 'c';
    public const UPDATED = 'u';
    public const LIFETIME = 'l';

    /**
     * @var string
     */
    private $name = '__metadata';

    /**
     * @var string
     */
    private $storageKey;

    /**
     * @var array
     */
    protected $meta = [self::CREATED => 0, self::UPDATED => 0, self::LIFETIME => 0];

    /**
     * Unix timestamp.
     *
     * @var int
     */
    private $lastUsed;

    /**
     * @var int
     */
    private $updateThreshold;

    /**
     * @param string $storageKey      The key used to store bag in the session
     * @param int    $updateThreshold The time to wait between two UPDATED updates
     */
    public function __construct(string $storageKey = '_sf2_meta', int $updateThreshold = 0)
    {
        $this->storageKey = $storageKey;
        $this->updateThreshold = $updateThreshold;
    }

    /**
     * {@inheritdoc}
     */
    public function initialize(array &$array)
    {
        $this->meta = &$array;

        if (isset($array[self::CREATED])) {
            $this->lastUsed = $this->meta[self::UPDATED];

            $timeStamp = time();
            if ($timeStamp - $array[self::UPDATED] >= $this->updateThreshold) {
                $this->meta[self::UPDATED] = $timeStamp;
            }
        } else {
            $this->stampCreated();
        }
    }

    /**
     * Gets the lifetime that the session cookie was set with.
     *
     * @return int
     */
    public function getLifetime()
    {
        return $this->meta[self::LIFETIME];
    }

    /**
     * Stamps a new session's metadata.
     *
     * @param int $lifetime Sets the cookie lifetime for the session cookie. A null value
     *                      will leave the system settings unchanged, 0 sets the cookie
     *                      to expire with browser session. Time is in seconds, and is
     *                      not a Unix timestamp.
     */
    public function stampNew(int $lifetime = null)
    {
        $this->stampCreated($lifetime);
    }

    /**
     * {@inheritdoc}
     */
    public function getStorageKey()
    {
        return $this->storageKey;
    }

    /**
     * Gets the created timestamp metadata.
     *
     * @return int Unix timestamp
     */
    public function getCreated()
    {
        return $this->meta[self::CREATED];
    }

    /**
     * Gets the last used metadata.
     *
     * @return int Unix timestamp
     */
    public function getLastUsed()
    {
        return $this->lastUsed;
    }

    /**
     * {@inheritdoc}
     */
    public function clear()
    {
        // nothing to do
    }

    /**
     * {@inheritdoc}
     */
    public function getName()
    {
        return $this->name;
    }

    /**
     * Sets name.
     */
    public function setName(string $name)
    {
        $this->name = $name;
    }

    private function stampCreated(int $lifetime = null): void
    {
        $timeStamp = time();
        $this->meta[self::CREATED] = $this->meta[self::UPDATED] = $this->lastUsed = $timeStamp;
        $this->meta[self::LIFETIME] = $lifetime ?? (int) ini_get('session.cookie_lifetime');
    }
}
PKϤ$ZM�k�FF?http-foundation/Session/Storage/NativeSessionStorageFactory.phpnu�[���<?php

/*
 * This file is part of the Symfony package.
 *
 * (c) Fabien Potencier <fabien@symfony.com>
 *
 * For the full copyright and license information, please view the LICENSE
 * file that was distributed with this source code.
 */

namespace Symfony\Component\HttpFoundation\Session\Storage;

use Symfony\Component\HttpFoundation\Request;

// Help opcache.preload discover always-needed symbols
class_exists(NativeSessionStorage::class);

/**
 * @author Jérémy Derussé <jeremy@derusse.com>
 */
class NativeSessionStorageFactory implements SessionStorageFactoryInterface
{
    private $options;
    private $handler;
    private $metaBag;
    private $secure;

    /**
     * @see NativeSessionStorage constructor.
     */
    public function __construct(array $options = [], $handler = null, MetadataBag $metaBag = null, bool $secure = false)
    {
        $this->options = $options;
        $this->handler = $handler;
        $this->metaBag = $metaBag;
        $this->secure = $secure;
    }

    public function createStorage(?Request $request): SessionStorageInterface
    {
        $storage = new NativeSessionStorage($this->options, $this->handler, $this->metaBag);
        if ($this->secure && $request && $request->isSecure()) {
            $storage->setOptions(['cookie_secure' => true]);
        }

        return $storage;
    }
}
PKϤ$ZP-gC��5http-foundation/Session/Storage/Proxy/NativeProxy.phpnu�[���<?php

/*
 * This file is part of the Symfony package.
 *
 * (c) Fabien Potencier <fabien@symfony.com>
 *
 * For the full copyright and license information, please view the LICENSE
 * file that was distributed with this source code.
 */

namespace Symfony\Component\HttpFoundation\Session\Storage\Proxy;

/**
 * NativeProxy.
 *
 * This proxy is built-in session handlers in PHP 5.3.x
 *
 * @author Drak <drak@zikula.org>
 */
class NativeProxy extends AbstractProxy
{
    /**
     * Constructor.
     */
    public function __construct()
    {
        // this makes an educated guess as to what the handler is since it should already be set.
        $this->saveHandlerName = ini_get('session.save_handler');
    }

    /**
     * Returns true if this handler wraps an internal PHP session save handler using \SessionHandler.
     *
     * @return bool False.
     */
    public function isWrapper()
    {
        return false;
    }
}
PKϤ$Z�x��	�	=http-foundation/Session/Storage/Proxy/SessionHandlerProxy.phpnu�[���<?php

/*
 * This file is part of the Symfony package.
 *
 * (c) Fabien Potencier <fabien@symfony.com>
 *
 * For the full copyright and license information, please view the LICENSE
 * file that was distributed with this source code.
 */

namespace Symfony\Component\HttpFoundation\Session\Storage\Proxy;

/**
 * @author Drak <drak@zikula.org>
 */
class SessionHandlerProxy extends AbstractProxy implements \SessionHandlerInterface, \SessionUpdateTimestampHandlerInterface
{
    protected $handler;

    public function __construct(\SessionHandlerInterface $handler)
    {
        $this->handler = $handler;
        $this->wrapper = ($handler instanceof \SessionHandler);
        $this->saveHandlerName = $this->wrapper ? ini_get('session.save_handler') : 'user';
    }

    /**
     * @return \SessionHandlerInterface
     */
    public function getHandler()
    {
        return $this->handler;
    }

    // \SessionHandlerInterface

    /**
     * @return bool
     */
    #[\ReturnTypeWillChange]
    public function open($savePath, $sessionName)
    {
        return (bool) $this->handler->open($savePath, $sessionName);
    }

    /**
     * @return bool
     */
    #[\ReturnTypeWillChange]
    public function close()
    {
        return (bool) $this->handler->close();
    }

    /**
     * @return string
     */
    #[\ReturnTypeWillChange]
    public function read($sessionId)
    {
        return (string) $this->handler->read($sessionId);
    }

    /**
     * @return bool
     */
    #[\ReturnTypeWillChange]
    public function write($sessionId, $data)
    {
        return (bool) $this->handler->write($sessionId, $data);
    }

    /**
     * @return bool
     */
    #[\ReturnTypeWillChange]
    public function destroy($sessionId)
    {
        return (bool) $this->handler->destroy($sessionId);
    }

    /**
     * @return int|false
     */
    #[\ReturnTypeWillChange]
    public function gc($maxlifetime)
    {
        return $this->handler->gc($maxlifetime);
    }

    /**
     * @return bool
     */
    #[\ReturnTypeWillChange]
    public function validateId($sessionId)
    {
        return !$this->handler instanceof \SessionUpdateTimestampHandlerInterface || $this->handler->validateId($sessionId);
    }

    /**
     * @return bool
     */
    #[\ReturnTypeWillChange]
    public function updateTimestamp($sessionId, $data)
    {
        return $this->handler instanceof \SessionUpdateTimestampHandlerInterface ? $this->handler->updateTimestamp($sessionId, $data) : $this->write($sessionId, $data);
    }
}
PKϤ$Z����7http-foundation/Session/Storage/Proxy/AbstractProxy.phpnu�[���<?php

/*
 * This file is part of the Symfony package.
 *
 * (c) Fabien Potencier <fabien@symfony.com>
 *
 * For the full copyright and license information, please view the LICENSE
 * file that was distributed with this source code.
 */

namespace Symfony\Component\HttpFoundation\Session\Storage\Proxy;

/**
 * @author Drak <drak@zikula.org>
 */
abstract class AbstractProxy
{
    /**
     * Flag if handler wraps an internal PHP session handler (using \SessionHandler).
     *
     * @var bool
     */
    protected $wrapper = false;

    /**
     * @var string
     */
    protected $saveHandlerName;

    /**
     * Gets the session.save_handler name.
     *
     * @return string|null
     */
    public function getSaveHandlerName()
    {
        return $this->saveHandlerName;
    }

    /**
     * Is this proxy handler and instance of \SessionHandlerInterface.
     *
     * @return bool
     */
    public function isSessionHandlerInterface()
    {
        return $this instanceof \SessionHandlerInterface;
    }

    /**
     * Returns true if this handler wraps an internal PHP session save handler using \SessionHandler.
     *
     * @return bool
     */
    public function isWrapper()
    {
        return $this->wrapper;
    }

    /**
     * Has a session started?
     *
     * @return bool
     */
    public function isActive()
    {
        return \PHP_SESSION_ACTIVE === session_status();
    }

    /**
     * Gets the session ID.
     *
     * @return string
     */
    public function getId()
    {
        return session_id();
    }

    /**
     * Sets the session ID.
     *
     * @throws \LogicException
     */
    public function setId(string $id)
    {
        if ($this->isActive()) {
            throw new \LogicException('Cannot change the ID of an active session.');
        }

        session_id($id);
    }

    /**
     * Gets the session name.
     *
     * @return string
     */
    public function getName()
    {
        return session_name();
    }

    /**
     * Sets the session name.
     *
     * @throws \LogicException
     */
    public function setName(string $name)
    {
        if ($this->isActive()) {
            throw new \LogicException('Cannot change the name of an active session.');
        }

        session_name($name);
    }
}
PKϤ$Z.�ľ��>http-foundation/Session/Storage/Handler/IdentityMarshaller.phpnu�[���<?php

/*
 * This file is part of the Symfony package.
 *
 * (c) Fabien Potencier <fabien@symfony.com>
 *
 * For the full copyright and license information, please view the LICENSE
 * file that was distributed with this source code.
 */

namespace Symfony\Component\HttpFoundation\Session\Storage\Handler;

use Symfony\Component\Cache\Marshaller\MarshallerInterface;

/**
 * @author Ahmed TAILOULOUTE <ahmed.tailouloute@gmail.com>
 */
class IdentityMarshaller implements MarshallerInterface
{
    /**
     * {@inheritdoc}
     */
    public function marshall(array $values, ?array &$failed): array
    {
        foreach ($values as $key => $value) {
            if (!\is_string($value)) {
                throw new \LogicException(sprintf('%s accepts only string as data.', __METHOD__));
            }
        }

        return $values;
    }

    /**
     * {@inheritdoc}
     */
    public function unmarshall(string $value): string
    {
        return $value;
    }
}
PKϤ$Zx�Bhttp-foundation/Session/Storage/Handler/AbstractSessionHandler.phpnu�[���<?php

/*
 * This file is part of the Symfony package.
 *
 * (c) Fabien Potencier <fabien@symfony.com>
 *
 * For the full copyright and license information, please view the LICENSE
 * file that was distributed with this source code.
 */

namespace Symfony\Component\HttpFoundation\Session\Storage\Handler;

use Symfony\Component\HttpFoundation\Session\SessionUtils;

/**
 * This abstract session handler provides a generic implementation
 * of the PHP 7.0 SessionUpdateTimestampHandlerInterface,
 * enabling strict and lazy session handling.
 *
 * @author Nicolas Grekas <p@tchwork.com>
 */
abstract class AbstractSessionHandler implements \SessionHandlerInterface, \SessionUpdateTimestampHandlerInterface
{
    private $sessionName;
    private $prefetchId;
    private $prefetchData;
    private $newSessionId;
    private $igbinaryEmptyData;

    /**
     * @return bool
     */
    #[\ReturnTypeWillChange]
    public function open($savePath, $sessionName)
    {
        $this->sessionName = $sessionName;
        if (!headers_sent() && !ini_get('session.cache_limiter') && '0' !== ini_get('session.cache_limiter')) {
            header(sprintf('Cache-Control: max-age=%d, private, must-revalidate', 60 * (int) ini_get('session.cache_expire')));
        }

        return true;
    }

    /**
     * @return string
     */
    abstract protected function doRead(string $sessionId);

    /**
     * @return bool
     */
    abstract protected function doWrite(string $sessionId, string $data);

    /**
     * @return bool
     */
    abstract protected function doDestroy(string $sessionId);

    /**
     * @return bool
     */
    #[\ReturnTypeWillChange]
    public function validateId($sessionId)
    {
        $this->prefetchData = $this->read($sessionId);
        $this->prefetchId = $sessionId;

        if (\PHP_VERSION_ID < 70317 || (70400 <= \PHP_VERSION_ID && \PHP_VERSION_ID < 70405)) {
            // work around https://bugs.php.net/79413
            foreach (debug_backtrace(\DEBUG_BACKTRACE_IGNORE_ARGS) as $frame) {
                if (!isset($frame['class']) && isset($frame['function']) && \in_array($frame['function'], ['session_regenerate_id', 'session_create_id'], true)) {
                    return '' === $this->prefetchData;
                }
            }
        }

        return '' !== $this->prefetchData;
    }

    /**
     * @return string
     */
    #[\ReturnTypeWillChange]
    public function read($sessionId)
    {
        if (null !== $this->prefetchId) {
            $prefetchId = $this->prefetchId;
            $prefetchData = $this->prefetchData;
            $this->prefetchId = $this->prefetchData = null;

            if ($prefetchId === $sessionId || '' === $prefetchData) {
                $this->newSessionId = '' === $prefetchData ? $sessionId : null;

                return $prefetchData;
            }
        }

        $data = $this->doRead($sessionId);
        $this->newSessionId = '' === $data ? $sessionId : null;

        return $data;
    }

    /**
     * @return bool
     */
    #[\ReturnTypeWillChange]
    public function write($sessionId, $data)
    {
        if (null === $this->igbinaryEmptyData) {
            // see https://github.com/igbinary/igbinary/issues/146
            $this->igbinaryEmptyData = \function_exists('igbinary_serialize') ? igbinary_serialize([]) : '';
        }
        if ('' === $data || $this->igbinaryEmptyData === $data) {
            return $this->destroy($sessionId);
        }
        $this->newSessionId = null;

        return $this->doWrite($sessionId, $data);
    }

    /**
     * @return bool
     */
    #[\ReturnTypeWillChange]
    public function destroy($sessionId)
    {
        if (!headers_sent() && filter_var(ini_get('session.use_cookies'), \FILTER_VALIDATE_BOOLEAN)) {
            if (!$this->sessionName) {
                throw new \LogicException(sprintf('Session name cannot be empty, did you forget to call "parent::open()" in "%s"?.', static::class));
            }
            $cookie = SessionUtils::popSessionCookie($this->sessionName, $sessionId);

            /*
             * We send an invalidation Set-Cookie header (zero lifetime)
             * when either the session was started or a cookie with
             * the session name was sent by the client (in which case
             * we know it's invalid as a valid session cookie would've
             * started the session).
             */
            if (null === $cookie || isset($_COOKIE[$this->sessionName])) {
                if (\PHP_VERSION_ID < 70300) {
                    setcookie($this->sessionName, '', 0, ini_get('session.cookie_path'), ini_get('session.cookie_domain'), filter_var(ini_get('session.cookie_secure'), \FILTER_VALIDATE_BOOLEAN), filter_var(ini_get('session.cookie_httponly'), \FILTER_VALIDATE_BOOLEAN));
                } else {
                    $params = session_get_cookie_params();
                    unset($params['lifetime']);
                    setcookie($this->sessionName, '', $params);
                }
            }
        }

        return $this->newSessionId === $sessionId || $this->doDestroy($sessionId);
    }
}
PKϤ$Z����ܒܒ=http-foundation/Session/Storage/Handler/PdoSessionHandler.phpnu�[���<?php

/*
 * This file is part of the Symfony package.
 *
 * (c) Fabien Potencier <fabien@symfony.com>
 *
 * For the full copyright and license information, please view the LICENSE
 * file that was distributed with this source code.
 */

namespace Symfony\Component\HttpFoundation\Session\Storage\Handler;

/**
 * Session handler using a PDO connection to read and write data.
 *
 * It works with MySQL, PostgreSQL, Oracle, SQL Server and SQLite and implements
 * different locking strategies to handle concurrent access to the same session.
 * Locking is necessary to prevent loss of data due to race conditions and to keep
 * the session data consistent between read() and write(). With locking, requests
 * for the same session will wait until the other one finished writing. For this
 * reason it's best practice to close a session as early as possible to improve
 * concurrency. PHPs internal files session handler also implements locking.
 *
 * Attention: Since SQLite does not support row level locks but locks the whole database,
 * it means only one session can be accessed at a time. Even different sessions would wait
 * for another to finish. So saving session in SQLite should only be considered for
 * development or prototypes.
 *
 * Session data is a binary string that can contain non-printable characters like the null byte.
 * For this reason it must be saved in a binary column in the database like BLOB in MySQL.
 * Saving it in a character column could corrupt the data. You can use createTable()
 * to initialize a correctly defined table.
 *
 * @see https://php.net/sessionhandlerinterface
 *
 * @author Fabien Potencier <fabien@symfony.com>
 * @author Michael Williams <michael.williams@funsational.com>
 * @author Tobias Schultze <http://tobion.de>
 */
class PdoSessionHandler extends AbstractSessionHandler
{
    /**
     * No locking is done. This means sessions are prone to loss of data due to
     * race conditions of concurrent requests to the same session. The last session
     * write will win in this case. It might be useful when you implement your own
     * logic to deal with this like an optimistic approach.
     */
    public const LOCK_NONE = 0;

    /**
     * Creates an application-level lock on a session. The disadvantage is that the
     * lock is not enforced by the database and thus other, unaware parts of the
     * application could still concurrently modify the session. The advantage is it
     * does not require a transaction.
     * This mode is not available for SQLite and not yet implemented for oci and sqlsrv.
     */
    public const LOCK_ADVISORY = 1;

    /**
     * Issues a real row lock. Since it uses a transaction between opening and
     * closing a session, you have to be careful when you use same database connection
     * that you also use for your application logic. This mode is the default because
     * it's the only reliable solution across DBMSs.
     */
    public const LOCK_TRANSACTIONAL = 2;

    private const MAX_LIFETIME = 315576000;

    /**
     * @var \PDO|null PDO instance or null when not connected yet
     */
    private $pdo;

    /**
     * @var string|false|null DSN string or null for session.save_path or false when lazy connection disabled
     */
    private $dsn = false;

    /**
     * @var string Database driver
     */
    private $driver;

    /**
     * @var string Table name
     */
    private $table = 'sessions';

    /**
     * @var string Column for session id
     */
    private $idCol = 'sess_id';

    /**
     * @var string Column for session data
     */
    private $dataCol = 'sess_data';

    /**
     * @var string Column for lifetime
     */
    private $lifetimeCol = 'sess_lifetime';

    /**
     * @var string Column for timestamp
     */
    private $timeCol = 'sess_time';

    /**
     * @var string Username when lazy-connect
     */
    private $username = '';

    /**
     * @var string Password when lazy-connect
     */
    private $password = '';

    /**
     * @var array Connection options when lazy-connect
     */
    private $connectionOptions = [];

    /**
     * @var int The strategy for locking, see constants
     */
    private $lockMode = self::LOCK_TRANSACTIONAL;

    /**
     * It's an array to support multiple reads before closing which is manual, non-standard usage.
     *
     * @var \PDOStatement[] An array of statements to release advisory locks
     */
    private $unlockStatements = [];

    /**
     * @var bool True when the current session exists but expired according to session.gc_maxlifetime
     */
    private $sessionExpired = false;

    /**
     * @var bool Whether a transaction is active
     */
    private $inTransaction = false;

    /**
     * @var bool Whether gc() has been called
     */
    private $gcCalled = false;

    /**
     * You can either pass an existing database connection as PDO instance or
     * pass a DSN string that will be used to lazy-connect to the database
     * when the session is actually used. Furthermore it's possible to pass null
     * which will then use the session.save_path ini setting as PDO DSN parameter.
     *
     * List of available options:
     *  * db_table: The name of the table [default: sessions]
     *  * db_id_col: The column where to store the session id [default: sess_id]
     *  * db_data_col: The column where to store the session data [default: sess_data]
     *  * db_lifetime_col: The column where to store the lifetime [default: sess_lifetime]
     *  * db_time_col: The column where to store the timestamp [default: sess_time]
     *  * db_username: The username when lazy-connect [default: '']
     *  * db_password: The password when lazy-connect [default: '']
     *  * db_connection_options: An array of driver-specific connection options [default: []]
     *  * lock_mode: The strategy for locking, see constants [default: LOCK_TRANSACTIONAL]
     *
     * @param \PDO|string|null $pdoOrDsn A \PDO instance or DSN string or URL string or null
     *
     * @throws \InvalidArgumentException When PDO error mode is not PDO::ERRMODE_EXCEPTION
     */
    public function __construct($pdoOrDsn = null, array $options = [])
    {
        if ($pdoOrDsn instanceof \PDO) {
            if (\PDO::ERRMODE_EXCEPTION !== $pdoOrDsn->getAttribute(\PDO::ATTR_ERRMODE)) {
                throw new \InvalidArgumentException(sprintf('"%s" requires PDO error mode attribute be set to throw Exceptions (i.e. $pdo->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION)).', __CLASS__));
            }

            $this->pdo = $pdoOrDsn;
            $this->driver = $this->pdo->getAttribute(\PDO::ATTR_DRIVER_NAME);
        } elseif (\is_string($pdoOrDsn) && str_contains($pdoOrDsn, '://')) {
            $this->dsn = $this->buildDsnFromUrl($pdoOrDsn);
        } else {
            $this->dsn = $pdoOrDsn;
        }

        $this->table = $options['db_table'] ?? $this->table;
        $this->idCol = $options['db_id_col'] ?? $this->idCol;
        $this->dataCol = $options['db_data_col'] ?? $this->dataCol;
        $this->lifetimeCol = $options['db_lifetime_col'] ?? $this->lifetimeCol;
        $this->timeCol = $options['db_time_col'] ?? $this->timeCol;
        $this->username = $options['db_username'] ?? $this->username;
        $this->password = $options['db_password'] ?? $this->password;
        $this->connectionOptions = $options['db_connection_options'] ?? $this->connectionOptions;
        $this->lockMode = $options['lock_mode'] ?? $this->lockMode;
    }

    /**
     * Creates the table to store sessions which can be called once for setup.
     *
     * Session ID is saved in a column of maximum length 128 because that is enough even
     * for a 512 bit configured session.hash_function like Whirlpool. Session data is
     * saved in a BLOB. One could also use a shorter inlined varbinary column
     * if one was sure the data fits into it.
     *
     * @throws \PDOException    When the table already exists
     * @throws \DomainException When an unsupported PDO driver is used
     */
    public function createTable()
    {
        // connect if we are not yet
        $this->getConnection();

        switch ($this->driver) {
            case 'mysql':
                // We use varbinary for the ID column because it prevents unwanted conversions:
                // - character set conversions between server and client
                // - trailing space removal
                // - case-insensitivity
                // - language processing like é == e
                $sql = "CREATE TABLE $this->table ($this->idCol VARBINARY(128) NOT NULL PRIMARY KEY, $this->dataCol BLOB NOT NULL, $this->lifetimeCol INTEGER UNSIGNED NOT NULL, $this->timeCol INTEGER UNSIGNED NOT NULL) COLLATE utf8mb4_bin, ENGINE = InnoDB";
                break;
            case 'sqlite':
                $sql = "CREATE TABLE $this->table ($this->idCol TEXT NOT NULL PRIMARY KEY, $this->dataCol BLOB NOT NULL, $this->lifetimeCol INTEGER NOT NULL, $this->timeCol INTEGER NOT NULL)";
                break;
            case 'pgsql':
                $sql = "CREATE TABLE $this->table ($this->idCol VARCHAR(128) NOT NULL PRIMARY KEY, $this->dataCol BYTEA NOT NULL, $this->lifetimeCol INTEGER NOT NULL, $this->timeCol INTEGER NOT NULL)";
                break;
            case 'oci':
                $sql = "CREATE TABLE $this->table ($this->idCol VARCHAR2(128) NOT NULL PRIMARY KEY, $this->dataCol BLOB NOT NULL, $this->lifetimeCol INTEGER NOT NULL, $this->timeCol INTEGER NOT NULL)";
                break;
            case 'sqlsrv':
                $sql = "CREATE TABLE $this->table ($this->idCol VARCHAR(128) NOT NULL PRIMARY KEY, $this->dataCol VARBINARY(MAX) NOT NULL, $this->lifetimeCol INTEGER NOT NULL, $this->timeCol INTEGER NOT NULL)";
                break;
            default:
                throw new \DomainException(sprintf('Creating the session table is currently not implemented for PDO driver "%s".', $this->driver));
        }

        try {
            $this->pdo->exec($sql);
            $this->pdo->exec("CREATE INDEX EXPIRY ON $this->table ($this->lifetimeCol)");
        } catch (\PDOException $e) {
            $this->rollback();

            throw $e;
        }
    }

    /**
     * Returns true when the current session exists but expired according to session.gc_maxlifetime.
     *
     * Can be used to distinguish between a new session and one that expired due to inactivity.
     *
     * @return bool Whether current session expired
     */
    public function isSessionExpired()
    {
        return $this->sessionExpired;
    }

    /**
     * @return bool
     */
    #[\ReturnTypeWillChange]
    public function open($savePath, $sessionName)
    {
        $this->sessionExpired = false;

        if (null === $this->pdo) {
            $this->connect($this->dsn ?: $savePath);
        }

        return parent::open($savePath, $sessionName);
    }

    /**
     * @return string
     */
    #[\ReturnTypeWillChange]
    public function read($sessionId)
    {
        try {
            return parent::read($sessionId);
        } catch (\PDOException $e) {
            $this->rollback();

            throw $e;
        }
    }

    /**
     * @return int|false
     */
    #[\ReturnTypeWillChange]
    public function gc($maxlifetime)
    {
        // We delay gc() to close() so that it is executed outside the transactional and blocking read-write process.
        // This way, pruning expired sessions does not block them from being started while the current session is used.
        $this->gcCalled = true;

        return 0;
    }

    /**
     * {@inheritdoc}
     */
    protected function doDestroy(string $sessionId)
    {
        // delete the record associated with this id
        $sql = "DELETE FROM $this->table WHERE $this->idCol = :id";

        try {
            $stmt = $this->pdo->prepare($sql);
            $stmt->bindParam(':id', $sessionId, \PDO::PARAM_STR);
            $stmt->execute();
        } catch (\PDOException $e) {
            $this->rollback();

            throw $e;
        }

        return true;
    }

    /**
     * {@inheritdoc}
     */
    protected function doWrite(string $sessionId, string $data)
    {
        $maxlifetime = (int) ini_get('session.gc_maxlifetime');

        try {
            // We use a single MERGE SQL query when supported by the database.
            $mergeStmt = $this->getMergeStatement($sessionId, $data, $maxlifetime);
            if (null !== $mergeStmt) {
                $mergeStmt->execute();

                return true;
            }

            $updateStmt = $this->getUpdateStatement($sessionId, $data, $maxlifetime);
            $updateStmt->execute();

            // When MERGE is not supported, like in Postgres < 9.5, we have to use this approach that can result in
            // duplicate key errors when the same session is written simultaneously (given the LOCK_NONE behavior).
            // We can just catch such an error and re-execute the update. This is similar to a serializable
            // transaction with retry logic on serialization failures but without the overhead and without possible
            // false positives due to longer gap locking.
            if (!$updateStmt->rowCount()) {
                try {
                    $insertStmt = $this->getInsertStatement($sessionId, $data, $maxlifetime);
                    $insertStmt->execute();
                } catch (\PDOException $e) {
                    // Handle integrity violation SQLSTATE 23000 (or a subclass like 23505 in Postgres) for duplicate keys
                    if (str_starts_with($e->getCode(), '23')) {
                        $updateStmt->execute();
                    } else {
                        throw $e;
                    }
                }
            }
        } catch (\PDOException $e) {
            $this->rollback();

            throw $e;
        }

        return true;
    }

    /**
     * @return bool
     */
    #[\ReturnTypeWillChange]
    public function updateTimestamp($sessionId, $data)
    {
        $expiry = time() + (int) ini_get('session.gc_maxlifetime');

        try {
            $updateStmt = $this->pdo->prepare(
                "UPDATE $this->table SET $this->lifetimeCol = :expiry, $this->timeCol = :time WHERE $this->idCol = :id"
            );
            $updateStmt->bindParam(':id', $sessionId, \PDO::PARAM_STR);
            $updateStmt->bindParam(':expiry', $expiry, \PDO::PARAM_INT);
            $updateStmt->bindValue(':time', time(), \PDO::PARAM_INT);
            $updateStmt->execute();
        } catch (\PDOException $e) {
            $this->rollback();

            throw $e;
        }

        return true;
    }

    /**
     * @return bool
     */
    #[\ReturnTypeWillChange]
    public function close()
    {
        $this->commit();

        while ($unlockStmt = array_shift($this->unlockStatements)) {
            $unlockStmt->execute();
        }

        if ($this->gcCalled) {
            $this->gcCalled = false;

            // delete the session records that have expired
            $sql = "DELETE FROM $this->table WHERE $this->lifetimeCol < :time AND $this->lifetimeCol > :min";
            $stmt = $this->pdo->prepare($sql);
            $stmt->bindValue(':time', time(), \PDO::PARAM_INT);
            $stmt->bindValue(':min', self::MAX_LIFETIME, \PDO::PARAM_INT);
            $stmt->execute();
            // to be removed in 6.0
            if ('mysql' === $this->driver) {
                $legacySql = "DELETE FROM $this->table WHERE $this->lifetimeCol <= :min AND $this->lifetimeCol + $this->timeCol < :time";
            } else {
                $legacySql = "DELETE FROM $this->table WHERE $this->lifetimeCol <= :min AND $this->lifetimeCol < :time - $this->timeCol";
            }

            $stmt = $this->pdo->prepare($legacySql);
            $stmt->bindValue(':time', time(), \PDO::PARAM_INT);
            $stmt->bindValue(':min', self::MAX_LIFETIME, \PDO::PARAM_INT);
            $stmt->execute();
        }

        if (false !== $this->dsn) {
            $this->pdo = null; // only close lazy-connection
        }

        return true;
    }

    /**
     * Lazy-connects to the database.
     */
    private function connect(string $dsn): void
    {
        $this->pdo = new \PDO($dsn, $this->username, $this->password, $this->connectionOptions);
        $this->pdo->setAttribute(\PDO::ATTR_ERRMODE, \PDO::ERRMODE_EXCEPTION);
        $this->driver = $this->pdo->getAttribute(\PDO::ATTR_DRIVER_NAME);
    }

    /**
     * Builds a PDO DSN from a URL-like connection string.
     *
     * @todo implement missing support for oci DSN (which look totally different from other PDO ones)
     */
    private function buildDsnFromUrl(string $dsnOrUrl): string
    {
        // (pdo_)?sqlite3?:///... => (pdo_)?sqlite3?://localhost/... or else the URL will be invalid
        $url = preg_replace('#^((?:pdo_)?sqlite3?):///#', '$1://localhost/', $dsnOrUrl);

        $params = parse_url($url);

        if (false === $params) {
            return $dsnOrUrl; // If the URL is not valid, let's assume it might be a DSN already.
        }

        $params = array_map('rawurldecode', $params);

        // Override the default username and password. Values passed through options will still win over these in the constructor.
        if (isset($params['user'])) {
            $this->username = $params['user'];
        }

        if (isset($params['pass'])) {
            $this->password = $params['pass'];
        }

        if (!isset($params['scheme'])) {
            throw new \InvalidArgumentException('URLs without scheme are not supported to configure the PdoSessionHandler.');
        }

        $driverAliasMap = [
            'mssql' => 'sqlsrv',
            'mysql2' => 'mysql', // Amazon RDS, for some weird reason
            'postgres' => 'pgsql',
            'postgresql' => 'pgsql',
            'sqlite3' => 'sqlite',
        ];

        $driver = $driverAliasMap[$params['scheme']] ?? $params['scheme'];

        // Doctrine DBAL supports passing its internal pdo_* driver names directly too (allowing both dashes and underscores). This allows supporting the same here.
        if (str_starts_with($driver, 'pdo_') || str_starts_with($driver, 'pdo-')) {
            $driver = substr($driver, 4);
        }

        $dsn = null;
        switch ($driver) {
            case 'mysql':
                $dsn = 'mysql:';
                if ('' !== ($params['query'] ?? '')) {
                    $queryParams = [];
                    parse_str($params['query'], $queryParams);
                    if ('' !== ($queryParams['charset'] ?? '')) {
                        $dsn .= 'charset='.$queryParams['charset'].';';
                    }

                    if ('' !== ($queryParams['unix_socket'] ?? '')) {
                        $dsn .= 'unix_socket='.$queryParams['unix_socket'].';';

                        if (isset($params['path'])) {
                            $dbName = substr($params['path'], 1); // Remove the leading slash
                            $dsn .= 'dbname='.$dbName.';';
                        }

                        return $dsn;
                    }
                }
            // If "unix_socket" is not in the query, we continue with the same process as pgsql
            // no break
            case 'pgsql':
                $dsn ?? $dsn = 'pgsql:';

                if (isset($params['host']) && '' !== $params['host']) {
                    $dsn .= 'host='.$params['host'].';';
                }

                if (isset($params['port']) && '' !== $params['port']) {
                    $dsn .= 'port='.$params['port'].';';
                }

                if (isset($params['path'])) {
                    $dbName = substr($params['path'], 1); // Remove the leading slash
                    $dsn .= 'dbname='.$dbName.';';
                }

                return $dsn;

            case 'sqlite':
                return 'sqlite:'.substr($params['path'], 1);

            case 'sqlsrv':
                $dsn = 'sqlsrv:server=';

                if (isset($params['host'])) {
                    $dsn .= $params['host'];
                }

                if (isset($params['port']) && '' !== $params['port']) {
                    $dsn .= ','.$params['port'];
                }

                if (isset($params['path'])) {
                    $dbName = substr($params['path'], 1); // Remove the leading slash
                    $dsn .= ';Database='.$dbName;
                }

                return $dsn;

            default:
                throw new \InvalidArgumentException(sprintf('The scheme "%s" is not supported by the PdoSessionHandler URL configuration. Pass a PDO DSN directly.', $params['scheme']));
        }
    }

    /**
     * Helper method to begin a transaction.
     *
     * Since SQLite does not support row level locks, we have to acquire a reserved lock
     * on the database immediately. Because of https://bugs.php.net/42766 we have to create
     * such a transaction manually which also means we cannot use PDO::commit or
     * PDO::rollback or PDO::inTransaction for SQLite.
     *
     * Also MySQLs default isolation, REPEATABLE READ, causes deadlock for different sessions
     * due to https://percona.com/blog/2013/12/12/one-more-innodb-gap-lock-to-avoid/ .
     * So we change it to READ COMMITTED.
     */
    private function beginTransaction(): void
    {
        if (!$this->inTransaction) {
            if ('sqlite' === $this->driver) {
                $this->pdo->exec('BEGIN IMMEDIATE TRANSACTION');
            } else {
                if ('mysql' === $this->driver) {
                    $this->pdo->exec('SET TRANSACTION ISOLATION LEVEL READ COMMITTED');
                }
                $this->pdo->beginTransaction();
            }
            $this->inTransaction = true;
        }
    }

    /**
     * Helper method to commit a transaction.
     */
    private function commit(): void
    {
        if ($this->inTransaction) {
            try {
                // commit read-write transaction which also releases the lock
                if ('sqlite' === $this->driver) {
                    $this->pdo->exec('COMMIT');
                } else {
                    $this->pdo->commit();
                }
                $this->inTransaction = false;
            } catch (\PDOException $e) {
                $this->rollback();

                throw $e;
            }
        }
    }

    /**
     * Helper method to rollback a transaction.
     */
    private function rollback(): void
    {
        // We only need to rollback if we are in a transaction. Otherwise the resulting
        // error would hide the real problem why rollback was called. We might not be
        // in a transaction when not using the transactional locking behavior or when
        // two callbacks (e.g. destroy and write) are invoked that both fail.
        if ($this->inTransaction) {
            if ('sqlite' === $this->driver) {
                $this->pdo->exec('ROLLBACK');
            } else {
                $this->pdo->rollBack();
            }
            $this->inTransaction = false;
        }
    }

    /**
     * Reads the session data in respect to the different locking strategies.
     *
     * We need to make sure we do not return session data that is already considered garbage according
     * to the session.gc_maxlifetime setting because gc() is called after read() and only sometimes.
     *
     * @return string
     */
    protected function doRead(string $sessionId)
    {
        if (self::LOCK_ADVISORY === $this->lockMode) {
            $this->unlockStatements[] = $this->doAdvisoryLock($sessionId);
        }

        $selectSql = $this->getSelectSql();
        $selectStmt = $this->pdo->prepare($selectSql);
        $selectStmt->bindParam(':id', $sessionId, \PDO::PARAM_STR);
        $insertStmt = null;

        do {
            $selectStmt->execute();
            $sessionRows = $selectStmt->fetchAll(\PDO::FETCH_NUM);

            if ($sessionRows) {
                $expiry = (int) $sessionRows[0][1];
                if ($expiry <= self::MAX_LIFETIME) {
                    $expiry += $sessionRows[0][2];
                }

                if ($expiry < time()) {
                    $this->sessionExpired = true;

                    return '';
                }

                return \is_resource($sessionRows[0][0]) ? stream_get_contents($sessionRows[0][0]) : $sessionRows[0][0];
            }

            if (null !== $insertStmt) {
                $this->rollback();
                throw new \RuntimeException('Failed to read session: INSERT reported a duplicate id but next SELECT did not return any data.');
            }

            if (!filter_var(ini_get('session.use_strict_mode'), \FILTER_VALIDATE_BOOLEAN) && self::LOCK_TRANSACTIONAL === $this->lockMode && 'sqlite' !== $this->driver) {
                // In strict mode, session fixation is not possible: new sessions always start with a unique
                // random id, so that concurrency is not possible and this code path can be skipped.
                // Exclusive-reading of non-existent rows does not block, so we need to do an insert to block
                // until other connections to the session are committed.
                try {
                    $insertStmt = $this->getInsertStatement($sessionId, '', 0);
                    $insertStmt->execute();
                } catch (\PDOException $e) {
                    // Catch duplicate key error because other connection created the session already.
                    // It would only not be the case when the other connection destroyed the session.
                    if (str_starts_with($e->getCode(), '23')) {
                        // Retrieve finished session data written by concurrent connection by restarting the loop.
                        // We have to start a new transaction as a failed query will mark the current transaction as
                        // aborted in PostgreSQL and disallow further queries within it.
                        $this->rollback();
                        $this->beginTransaction();
                        continue;
                    }

                    throw $e;
                }
            }

            return '';
        } while (true);
    }

    /**
     * Executes an application-level lock on the database.
     *
     * @return \PDOStatement The statement that needs to be executed later to release the lock
     *
     * @throws \DomainException When an unsupported PDO driver is used
     *
     * @todo implement missing advisory locks
     *       - for oci using DBMS_LOCK.REQUEST
     *       - for sqlsrv using sp_getapplock with LockOwner = Session
     */
    private function doAdvisoryLock(string $sessionId): \PDOStatement
    {
        switch ($this->driver) {
            case 'mysql':
                // MySQL 5.7.5 and later enforces a maximum length on lock names of 64 characters. Previously, no limit was enforced.
                $lockId = substr($sessionId, 0, 64);
                // should we handle the return value? 0 on timeout, null on error
                // we use a timeout of 50 seconds which is also the default for innodb_lock_wait_timeout
                $stmt = $this->pdo->prepare('SELECT GET_LOCK(:key, 50)');
                $stmt->bindValue(':key', $lockId, \PDO::PARAM_STR);
                $stmt->execute();

                $releaseStmt = $this->pdo->prepare('DO RELEASE_LOCK(:key)');
                $releaseStmt->bindValue(':key', $lockId, \PDO::PARAM_STR);

                return $releaseStmt;
            case 'pgsql':
                // Obtaining an exclusive session level advisory lock requires an integer key.
                // When session.sid_bits_per_character > 4, the session id can contain non-hex-characters.
                // So we cannot just use hexdec().
                if (4 === \PHP_INT_SIZE) {
                    $sessionInt1 = $this->convertStringToInt($sessionId);
                    $sessionInt2 = $this->convertStringToInt(substr($sessionId, 4, 4));

                    $stmt = $this->pdo->prepare('SELECT pg_advisory_lock(:key1, :key2)');
                    $stmt->bindValue(':key1', $sessionInt1, \PDO::PARAM_INT);
                    $stmt->bindValue(':key2', $sessionInt2, \PDO::PARAM_INT);
                    $stmt->execute();

                    $releaseStmt = $this->pdo->prepare('SELECT pg_advisory_unlock(:key1, :key2)');
                    $releaseStmt->bindValue(':key1', $sessionInt1, \PDO::PARAM_INT);
                    $releaseStmt->bindValue(':key2', $sessionInt2, \PDO::PARAM_INT);
                } else {
                    $sessionBigInt = $this->convertStringToInt($sessionId);

                    $stmt = $this->pdo->prepare('SELECT pg_advisory_lock(:key)');
                    $stmt->bindValue(':key', $sessionBigInt, \PDO::PARAM_INT);
                    $stmt->execute();

                    $releaseStmt = $this->pdo->prepare('SELECT pg_advisory_unlock(:key)');
                    $releaseStmt->bindValue(':key', $sessionBigInt, \PDO::PARAM_INT);
                }

                return $releaseStmt;
            case 'sqlite':
                throw new \DomainException('SQLite does not support advisory locks.');
            default:
                throw new \DomainException(sprintf('Advisory locks are currently not implemented for PDO driver "%s".', $this->driver));
        }
    }

    /**
     * Encodes the first 4 (when PHP_INT_SIZE == 4) or 8 characters of the string as an integer.
     *
     * Keep in mind, PHP integers are signed.
     */
    private function convertStringToInt(string $string): int
    {
        if (4 === \PHP_INT_SIZE) {
            return (\ord($string[3]) << 24) + (\ord($string[2]) << 16) + (\ord($string[1]) << 8) + \ord($string[0]);
        }

        $int1 = (\ord($string[7]) << 24) + (\ord($string[6]) << 16) + (\ord($string[5]) << 8) + \ord($string[4]);
        $int2 = (\ord($string[3]) << 24) + (\ord($string[2]) << 16) + (\ord($string[1]) << 8) + \ord($string[0]);

        return $int2 + ($int1 << 32);
    }

    /**
     * Return a locking or nonlocking SQL query to read session information.
     *
     * @throws \DomainException When an unsupported PDO driver is used
     */
    private function getSelectSql(): string
    {
        if (self::LOCK_TRANSACTIONAL === $this->lockMode) {
            $this->beginTransaction();

            // selecting the time column should be removed in 6.0
            switch ($this->driver) {
                case 'mysql':
                case 'oci':
                case 'pgsql':
                    return "SELECT $this->dataCol, $this->lifetimeCol, $this->timeCol FROM $this->table WHERE $this->idCol = :id FOR UPDATE";
                case 'sqlsrv':
                    return "SELECT $this->dataCol, $this->lifetimeCol, $this->timeCol FROM $this->table WITH (UPDLOCK, ROWLOCK) WHERE $this->idCol = :id";
                case 'sqlite':
                    // we already locked when starting transaction
                    break;
                default:
                    throw new \DomainException(sprintf('Transactional locks are currently not implemented for PDO driver "%s".', $this->driver));
            }
        }

        return "SELECT $this->dataCol, $this->lifetimeCol, $this->timeCol FROM $this->table WHERE $this->idCol = :id";
    }

    /**
     * Returns an insert statement supported by the database for writing session data.
     */
    private function getInsertStatement(string $sessionId, string $sessionData, int $maxlifetime): \PDOStatement
    {
        switch ($this->driver) {
            case 'oci':
                $data = fopen('php://memory', 'r+');
                fwrite($data, $sessionData);
                rewind($data);
                $sql = "INSERT INTO $this->table ($this->idCol, $this->dataCol, $this->lifetimeCol, $this->timeCol) VALUES (:id, EMPTY_BLOB(), :expiry, :time) RETURNING $this->dataCol into :data";
                break;
            default:
                $data = $sessionData;
                $sql = "INSERT INTO $this->table ($this->idCol, $this->dataCol, $this->lifetimeCol, $this->timeCol) VALUES (:id, :data, :expiry, :time)";
                break;
        }

        $stmt = $this->pdo->prepare($sql);
        $stmt->bindParam(':id', $sessionId, \PDO::PARAM_STR);
        $stmt->bindParam(':data', $data, \PDO::PARAM_LOB);
        $stmt->bindValue(':expiry', time() + $maxlifetime, \PDO::PARAM_INT);
        $stmt->bindValue(':time', time(), \PDO::PARAM_INT);

        return $stmt;
    }

    /**
     * Returns an update statement supported by the database for writing session data.
     */
    private function getUpdateStatement(string $sessionId, string $sessionData, int $maxlifetime): \PDOStatement
    {
        switch ($this->driver) {
            case 'oci':
                $data = fopen('php://memory', 'r+');
                fwrite($data, $sessionData);
                rewind($data);
                $sql = "UPDATE $this->table SET $this->dataCol = EMPTY_BLOB(), $this->lifetimeCol = :expiry, $this->timeCol = :time WHERE $this->idCol = :id RETURNING $this->dataCol into :data";
                break;
            default:
                $data = $sessionData;
                $sql = "UPDATE $this->table SET $this->dataCol = :data, $this->lifetimeCol = :expiry, $this->timeCol = :time WHERE $this->idCol = :id";
                break;
        }

        $stmt = $this->pdo->prepare($sql);
        $stmt->bindParam(':id', $sessionId, \PDO::PARAM_STR);
        $stmt->bindParam(':data', $data, \PDO::PARAM_LOB);
        $stmt->bindValue(':expiry', time() + $maxlifetime, \PDO::PARAM_INT);
        $stmt->bindValue(':time', time(), \PDO::PARAM_INT);

        return $stmt;
    }

    /**
     * Returns a merge/upsert (i.e. insert or update) statement when supported by the database for writing session data.
     */
    private function getMergeStatement(string $sessionId, string $data, int $maxlifetime): ?\PDOStatement
    {
        switch (true) {
            case 'mysql' === $this->driver:
                $mergeSql = "INSERT INTO $this->table ($this->idCol, $this->dataCol, $this->lifetimeCol, $this->timeCol) VALUES (:id, :data, :expiry, :time) ".
                    "ON DUPLICATE KEY UPDATE $this->dataCol = VALUES($this->dataCol), $this->lifetimeCol = VALUES($this->lifetimeCol), $this->timeCol = VALUES($this->timeCol)";
                break;
            case 'sqlsrv' === $this->driver && version_compare($this->pdo->getAttribute(\PDO::ATTR_SERVER_VERSION), '10', '>='):
                // MERGE is only available since SQL Server 2008 and must be terminated by semicolon
                // It also requires HOLDLOCK according to https://weblogs.sqlteam.com/dang/2009/01/31/upsert-race-condition-with-merge/
                $mergeSql = "MERGE INTO $this->table WITH (HOLDLOCK) USING (SELECT 1 AS dummy) AS src ON ($this->idCol = ?) ".
                    "WHEN NOT MATCHED THEN INSERT ($this->idCol, $this->dataCol, $this->lifetimeCol, $this->timeCol) VALUES (?, ?, ?, ?) ".
                    "WHEN MATCHED THEN UPDATE SET $this->dataCol = ?, $this->lifetimeCol = ?, $this->timeCol = ?;";
                break;
            case 'sqlite' === $this->driver:
                $mergeSql = "INSERT OR REPLACE INTO $this->table ($this->idCol, $this->dataCol, $this->lifetimeCol, $this->timeCol) VALUES (:id, :data, :expiry, :time)";
                break;
            case 'pgsql' === $this->driver && version_compare($this->pdo->getAttribute(\PDO::ATTR_SERVER_VERSION), '9.5', '>='):
                $mergeSql = "INSERT INTO $this->table ($this->idCol, $this->dataCol, $this->lifetimeCol, $this->timeCol) VALUES (:id, :data, :expiry, :time) ".
                    "ON CONFLICT ($this->idCol) DO UPDATE SET ($this->dataCol, $this->lifetimeCol, $this->timeCol) = (EXCLUDED.$this->dataCol, EXCLUDED.$this->lifetimeCol, EXCLUDED.$this->timeCol)";
                break;
            default:
                // MERGE is not supported with LOBs: https://oracle.com/technetwork/articles/fuecks-lobs-095315.html
                return null;
        }

        $mergeStmt = $this->pdo->prepare($mergeSql);

        if ('sqlsrv' === $this->driver) {
            $mergeStmt->bindParam(1, $sessionId, \PDO::PARAM_STR);
            $mergeStmt->bindParam(2, $sessionId, \PDO::PARAM_STR);
            $mergeStmt->bindParam(3, $data, \PDO::PARAM_LOB);
            $mergeStmt->bindValue(4, time() + $maxlifetime, \PDO::PARAM_INT);
            $mergeStmt->bindValue(5, time(), \PDO::PARAM_INT);
            $mergeStmt->bindParam(6, $data, \PDO::PARAM_LOB);
            $mergeStmt->bindValue(7, time() + $maxlifetime, \PDO::PARAM_INT);
            $mergeStmt->bindValue(8, time(), \PDO::PARAM_INT);
        } else {
            $mergeStmt->bindParam(':id', $sessionId, \PDO::PARAM_STR);
            $mergeStmt->bindParam(':data', $data, \PDO::PARAM_LOB);
            $mergeStmt->bindValue(':expiry', time() + $maxlifetime, \PDO::PARAM_INT);
            $mergeStmt->bindValue(':time', time(), \PDO::PARAM_INT);
        }

        return $mergeStmt;
    }

    /**
     * Return a PDO instance.
     *
     * @return \PDO
     */
    protected function getConnection()
    {
        if (null === $this->pdo) {
            $this->connect($this->dsn ?: ini_get('session.save_path'));
        }

        return $this->pdo;
    }
}
PKϤ$Z��Zֶ	�	@http-foundation/Session/Storage/Handler/StrictSessionHandler.phpnu�[���<?php

/*
 * This file is part of the Symfony package.
 *
 * (c) Fabien Potencier <fabien@symfony.com>
 *
 * For the full copyright and license information, please view the LICENSE
 * file that was distributed with this source code.
 */

namespace Symfony\Component\HttpFoundation\Session\Storage\Handler;

/**
 * Adds basic `SessionUpdateTimestampHandlerInterface` behaviors to another `SessionHandlerInterface`.
 *
 * @author Nicolas Grekas <p@tchwork.com>
 */
class StrictSessionHandler extends AbstractSessionHandler
{
    private $handler;
    private $doDestroy;

    public function __construct(\SessionHandlerInterface $handler)
    {
        if ($handler instanceof \SessionUpdateTimestampHandlerInterface) {
            throw new \LogicException(sprintf('"%s" is already an instance of "SessionUpdateTimestampHandlerInterface", you cannot wrap it with "%s".', get_debug_type($handler), self::class));
        }

        $this->handler = $handler;
    }

    /**
     * @return bool
     */
    #[\ReturnTypeWillChange]
    public function open($savePath, $sessionName)
    {
        parent::open($savePath, $sessionName);

        return $this->handler->open($savePath, $sessionName);
    }

    /**
     * {@inheritdoc}
     */
    protected function doRead(string $sessionId)
    {
        return $this->handler->read($sessionId);
    }

    /**
     * @return bool
     */
    #[\ReturnTypeWillChange]
    public function updateTimestamp($sessionId, $data)
    {
        return $this->write($sessionId, $data);
    }

    /**
     * {@inheritdoc}
     */
    protected function doWrite(string $sessionId, string $data)
    {
        return $this->handler->write($sessionId, $data);
    }

    /**
     * @return bool
     */
    #[\ReturnTypeWillChange]
    public function destroy($sessionId)
    {
        $this->doDestroy = true;
        $destroyed = parent::destroy($sessionId);

        return $this->doDestroy ? $this->doDestroy($sessionId) : $destroyed;
    }

    /**
     * {@inheritdoc}
     */
    protected function doDestroy(string $sessionId)
    {
        $this->doDestroy = false;

        return $this->handler->destroy($sessionId);
    }

    /**
     * @return bool
     */
    #[\ReturnTypeWillChange]
    public function close()
    {
        return $this->handler->close();
    }

    /**
     * @return int|false
     */
    #[\ReturnTypeWillChange]
    public function gc($maxlifetime)
    {
        return $this->handler->gc($maxlifetime);
    }
}
PKϤ$Z<[	[	Ehttp-foundation/Session/Storage/Handler/MarshallingSessionHandler.phpnu�[���<?php

/*
 * This file is part of the Symfony package.
 *
 * (c) Fabien Potencier <fabien@symfony.com>
 *
 * For the full copyright and license information, please view the LICENSE
 * file that was distributed with this source code.
 */

namespace Symfony\Component\HttpFoundation\Session\Storage\Handler;

use Symfony\Component\Cache\Marshaller\MarshallerInterface;

/**
 * @author Ahmed TAILOULOUTE <ahmed.tailouloute@gmail.com>
 */
class MarshallingSessionHandler implements \SessionHandlerInterface, \SessionUpdateTimestampHandlerInterface
{
    private $handler;
    private $marshaller;

    public function __construct(AbstractSessionHandler $handler, MarshallerInterface $marshaller)
    {
        $this->handler = $handler;
        $this->marshaller = $marshaller;
    }

    /**
     * @return bool
     */
    #[\ReturnTypeWillChange]
    public function open($savePath, $name)
    {
        return $this->handler->open($savePath, $name);
    }

    /**
     * @return bool
     */
    #[\ReturnTypeWillChange]
    public function close()
    {
        return $this->handler->close();
    }

    /**
     * @return bool
     */
    #[\ReturnTypeWillChange]
    public function destroy($sessionId)
    {
        return $this->handler->destroy($sessionId);
    }

    /**
     * @return int|false
     */
    #[\ReturnTypeWillChange]
    public function gc($maxlifetime)
    {
        return $this->handler->gc($maxlifetime);
    }

    /**
     * @return string
     */
    #[\ReturnTypeWillChange]
    public function read($sessionId)
    {
        return $this->marshaller->unmarshall($this->handler->read($sessionId));
    }

    /**
     * @return bool
     */
    #[\ReturnTypeWillChange]
    public function write($sessionId, $data)
    {
        $failed = [];
        $marshalledData = $this->marshaller->marshall(['data' => $data], $failed);

        if (isset($failed['data'])) {
            return false;
        }

        return $this->handler->write($sessionId, $marshalledData['data']);
    }

    /**
     * @return bool
     */
    #[\ReturnTypeWillChange]
    public function validateId($sessionId)
    {
        return $this->handler->validateId($sessionId);
    }

    /**
     * @return bool
     */
    #[\ReturnTypeWillChange]
    public function updateTimestamp($sessionId, $data)
    {
        return $this->handler->updateTimestamp($sessionId, $data);
    }
}
PKϤ$Zkί���Ahttp-foundation/Session/Storage/Handler/MongoDbSessionHandler.phpnu�[���<?php

/*
 * This file is part of the Symfony package.
 *
 * (c) Fabien Potencier <fabien@symfony.com>
 *
 * For the full copyright and license information, please view the LICENSE
 * file that was distributed with this source code.
 */

namespace Symfony\Component\HttpFoundation\Session\Storage\Handler;

/**
 * Session handler using the mongodb/mongodb package and MongoDB driver extension.
 *
 * @author Markus Bachmann <markus.bachmann@bachi.biz>
 *
 * @see https://packagist.org/packages/mongodb/mongodb
 * @see https://php.net/mongodb
 */
class MongoDbSessionHandler extends AbstractSessionHandler
{
    private $mongo;

    /**
     * @var \MongoDB\Collection
     */
    private $collection;

    /**
     * @var array
     */
    private $options;

    /**
     * Constructor.
     *
     * List of available options:
     *  * database: The name of the database [required]
     *  * collection: The name of the collection [required]
     *  * id_field: The field name for storing the session id [default: _id]
     *  * data_field: The field name for storing the session data [default: data]
     *  * time_field: The field name for storing the timestamp [default: time]
     *  * expiry_field: The field name for storing the expiry-timestamp [default: expires_at].
     *
     * It is strongly recommended to put an index on the `expiry_field` for
     * garbage-collection. Alternatively it's possible to automatically expire
     * the sessions in the database as described below:
     *
     * A TTL collections can be used on MongoDB 2.2+ to cleanup expired sessions
     * automatically. Such an index can for example look like this:
     *
     *     db.<session-collection>.createIndex(
     *         { "<expiry-field>": 1 },
     *         { "expireAfterSeconds": 0 }
     *     )
     *
     * More details on: https://docs.mongodb.org/manual/tutorial/expire-data/
     *
     * If you use such an index, you can drop `gc_probability` to 0 since
     * no garbage-collection is required.
     *
     * @throws \InvalidArgumentException When "database" or "collection" not provided
     */
    public function __construct(\MongoDB\Client $mongo, array $options)
    {
        if (!isset($options['database']) || !isset($options['collection'])) {
            throw new \InvalidArgumentException('You must provide the "database" and "collection" option for MongoDBSessionHandler.');
        }

        $this->mongo = $mongo;

        $this->options = array_merge([
            'id_field' => '_id',
            'data_field' => 'data',
            'time_field' => 'time',
            'expiry_field' => 'expires_at',
        ], $options);
    }

    /**
     * @return bool
     */
    public function close()
    {
        return true;
    }

    /**
     * {@inheritdoc}
     */
    protected function doDestroy(string $sessionId)
    {
        $this->getCollection()->deleteOne([
            $this->options['id_field'] => $sessionId,
        ]);

        return true;
    }

    /**
     * @return int|false
     */
    #[\ReturnTypeWillChange]
    public function gc($maxlifetime)
    {
        return $this->getCollection()->deleteMany([
            $this->options['expiry_field'] => ['$lt' => new \MongoDB\BSON\UTCDateTime()],
        ])->getDeletedCount();
    }

    /**
     * {@inheritdoc}
     */
    protected function doWrite(string $sessionId, string $data)
    {
        $expiry = new \MongoDB\BSON\UTCDateTime((time() + (int) ini_get('session.gc_maxlifetime')) * 1000);

        $fields = [
            $this->options['time_field'] => new \MongoDB\BSON\UTCDateTime(),
            $this->options['expiry_field'] => $expiry,
            $this->options['data_field'] => new \MongoDB\BSON\Binary($data, \MongoDB\BSON\Binary::TYPE_OLD_BINARY),
        ];

        $this->getCollection()->updateOne(
            [$this->options['id_field'] => $sessionId],
            ['$set' => $fields],
            ['upsert' => true]
        );

        return true;
    }

    /**
     * @return bool
     */
    public function updateTimestamp($sessionId, $data)
    {
        $expiry = new \MongoDB\BSON\UTCDateTime((time() + (int) ini_get('session.gc_maxlifetime')) * 1000);

        $this->getCollection()->updateOne(
            [$this->options['id_field'] => $sessionId],
            ['$set' => [
                $this->options['time_field'] => new \MongoDB\BSON\UTCDateTime(),
                $this->options['expiry_field'] => $expiry,
            ]]
        );

        return true;
    }

    /**
     * {@inheritdoc}
     */
    protected function doRead(string $sessionId)
    {
        $dbData = $this->getCollection()->findOne([
            $this->options['id_field'] => $sessionId,
            $this->options['expiry_field'] => ['$gte' => new \MongoDB\BSON\UTCDateTime()],
        ]);

        if (null === $dbData) {
            return '';
        }

        return $dbData[$this->options['data_field']]->getData();
    }

    private function getCollection(): \MongoDB\Collection
    {
        if (null === $this->collection) {
            $this->collection = $this->mongo->selectCollection($this->options['database'], $this->options['collection']);
        }

        return $this->collection;
    }

    /**
     * @return \MongoDB\Client
     */
    protected function getMongo()
    {
        return $this->mongo;
    }
}
PKϤ$Z��]v$$@http-foundation/Session/Storage/Handler/NativeSessionHandler.phpnu�[���<?php

/*
 * This file is part of the Symfony package.
 *
 * (c) Fabien Potencier <fabien@symfony.com>
 *
 * For the full copyright and license information, please view the LICENSE
 * file that was distributed with this source code.
 */

namespace Symfony\Component\HttpFoundation\Session\Storage\Handler;

// Adds SessionHandler functionality if available.
// @see http://php.net/sessionhandler
if (PHP_VERSION_ID >= 50400) {
    class NativeSessionHandler extends \SessionHandler
    {
    }
} else {
    class NativeSessionHandler
    {
    }
}
PKϤ$Z��W��
�
Bhttp-foundation/Session/Storage/Handler/MemcacheSessionHandler.phpnu�[���<?php

/*
 * This file is part of the Symfony package.
 *
 * (c) Fabien Potencier <fabien@symfony.com>
 *
 * For the full copyright and license information, please view the LICENSE
 * file that was distributed with this source code.
 */

namespace Symfony\Component\HttpFoundation\Session\Storage\Handler;

/**
 * MemcacheSessionHandler.
 *
 * @author Drak <drak@zikula.org>
 */
class MemcacheSessionHandler implements \SessionHandlerInterface
{
    /**
     * @var \Memcache Memcache driver.
     */
    private $memcache;

    /**
     * @var int Time to live in seconds
     */
    private $ttl;

    /**
     * @var string Key prefix for shared environments.
     */
    private $prefix;

    /**
     * Constructor.
     *
     * List of available options:
     *  * prefix: The prefix to use for the memcache keys in order to avoid collision
     *  * expiretime: The time to live in seconds
     *
     * @param \Memcache $memcache A \Memcache instance
     * @param array     $options  An associative array of Memcache options
     *
     * @throws \InvalidArgumentException When unsupported options are passed
     */
    public function __construct(\Memcache $memcache, array $options = array())
    {
        if ($diff = array_diff(array_keys($options), array('prefix', 'expiretime'))) {
            throw new \InvalidArgumentException(sprintf(
                'The following options are not supported "%s"', implode(', ', $diff)
            ));
        }

        $this->memcache = $memcache;
        $this->ttl = isset($options['expiretime']) ? (int) $options['expiretime'] : 86400;
        $this->prefix = isset($options['prefix']) ? $options['prefix'] : 'sf2s';
    }

    /**
     * {@inheritdoc}
     */
    public function open($savePath, $sessionName)
    {
        return true;
    }

    /**
     * {@inheritdoc}
     */
    public function close()
    {
        return $this->memcache->close();
    }

    /**
     * {@inheritdoc}
     */
    public function read($sessionId)
    {
        return $this->memcache->get($this->prefix.$sessionId) ?: '';
    }

    /**
     * {@inheritdoc}
     */
    public function write($sessionId, $data)
    {
        return $this->memcache->set($this->prefix.$sessionId, $data, 0, time() + $this->ttl);
    }

    /**
     * {@inheritdoc}
     */
    public function destroy($sessionId)
    {
        return $this->memcache->delete($this->prefix.$sessionId);
    }

    /**
     * {@inheritdoc}
     */
    public function gc($maxlifetime)
    {
        // not required here because memcache will auto expire the records anyhow.
        return true;
    }

    /**
     * Return a Memcache instance.
     *
     * @return \Memcache
     */
    protected function getMemcache()
    {
        return $this->memcache;
    }
}
PKϤ$Z�	�Ɩ�Chttp-foundation/Session/Storage/Handler/MemcachedSessionHandler.phpnu�[���<?php

/*
 * This file is part of the Symfony package.
 *
 * (c) Fabien Potencier <fabien@symfony.com>
 *
 * For the full copyright and license information, please view the LICENSE
 * file that was distributed with this source code.
 */

namespace Symfony\Component\HttpFoundation\Session\Storage\Handler;

/**
 * Memcached based session storage handler based on the Memcached class
 * provided by the PHP memcached extension.
 *
 * @see https://php.net/memcached
 *
 * @author Drak <drak@zikula.org>
 */
class MemcachedSessionHandler extends AbstractSessionHandler
{
    private $memcached;

    /**
     * @var int Time to live in seconds
     */
    private $ttl;

    /**
     * @var string Key prefix for shared environments
     */
    private $prefix;

    /**
     * Constructor.
     *
     * List of available options:
     *  * prefix: The prefix to use for the memcached keys in order to avoid collision
     *  * expiretime: The time to live in seconds.
     *
     * @throws \InvalidArgumentException When unsupported options are passed
     */
    public function __construct(\Memcached $memcached, array $options = [])
    {
        $this->memcached = $memcached;

        if ($diff = array_diff(array_keys($options), ['prefix', 'expiretime'])) {
            throw new \InvalidArgumentException(sprintf('The following options are not supported "%s".', implode(', ', $diff)));
        }

        $this->ttl = isset($options['expiretime']) ? (int) $options['expiretime'] : 86400;
        $this->prefix = $options['prefix'] ?? 'sf2s';
    }

    /**
     * @return bool
     */
    #[\ReturnTypeWillChange]
    public function close()
    {
        return $this->memcached->quit();
    }

    /**
     * {@inheritdoc}
     */
    protected function doRead(string $sessionId)
    {
        return $this->memcached->get($this->prefix.$sessionId) ?: '';
    }

    /**
     * @return bool
     */
    #[\ReturnTypeWillChange]
    public function updateTimestamp($sessionId, $data)
    {
        $this->memcached->touch($this->prefix.$sessionId, time() + $this->ttl);

        return true;
    }

    /**
     * {@inheritdoc}
     */
    protected function doWrite(string $sessionId, string $data)
    {
        return $this->memcached->set($this->prefix.$sessionId, $data, time() + $this->ttl);
    }

    /**
     * {@inheritdoc}
     */
    protected function doDestroy(string $sessionId)
    {
        $result = $this->memcached->delete($this->prefix.$sessionId);

        return $result || \Memcached::RES_NOTFOUND == $this->memcached->getResultCode();
    }

    /**
     * @return int|false
     */
    #[\ReturnTypeWillChange]
    public function gc($maxlifetime)
    {
        // not required here because memcached will auto expire the records anyhow.
        return 0;
    }

    /**
     * Return a Memcached instance.
     *
     * @return \Memcached
     */
    protected function getMemcached()
    {
        return $this->memcached;
    }
}
PKϤ$Z�n�ttAhttp-foundation/Session/Storage/Handler/SessionHandlerFactory.phpnu�[���<?php

/*
 * This file is part of the Symfony package.
 *
 * (c) Fabien Potencier <fabien@symfony.com>
 *
 * For the full copyright and license information, please view the LICENSE
 * file that was distributed with this source code.
 */

namespace Symfony\Component\HttpFoundation\Session\Storage\Handler;

use Doctrine\DBAL\DriverManager;
use Symfony\Component\Cache\Adapter\AbstractAdapter;
use Symfony\Component\Cache\Traits\RedisClusterProxy;
use Symfony\Component\Cache\Traits\RedisProxy;

/**
 * @author Nicolas Grekas <p@tchwork.com>
 */
class SessionHandlerFactory
{
    /**
     * @param \Redis|\RedisArray|\RedisCluster|\Predis\ClientInterface|RedisProxy|RedisClusterProxy|\Memcached|\PDO|string $connection Connection or DSN
     */
    public static function createHandler($connection): AbstractSessionHandler
    {
        if (!\is_string($connection) && !\is_object($connection)) {
            throw new \TypeError(sprintf('Argument 1 passed to "%s()" must be a string or a connection object, "%s" given.', __METHOD__, get_debug_type($connection)));
        }

        switch (true) {
            case $connection instanceof \Redis:
            case $connection instanceof \RedisArray:
            case $connection instanceof \RedisCluster:
            case $connection instanceof \Predis\ClientInterface:
            case $connection instanceof RedisProxy:
            case $connection instanceof RedisClusterProxy:
                return new RedisSessionHandler($connection);

            case $connection instanceof \Memcached:
                return new MemcachedSessionHandler($connection);

            case $connection instanceof \PDO:
                return new PdoSessionHandler($connection);

            case !\is_string($connection):
                throw new \InvalidArgumentException(sprintf('Unsupported Connection: "%s".', get_debug_type($connection)));
            case str_starts_with($connection, 'file://'):
                $savePath = substr($connection, 7);

                return new StrictSessionHandler(new NativeFileSessionHandler('' === $savePath ? null : $savePath));

            case str_starts_with($connection, 'redis:'):
            case str_starts_with($connection, 'rediss:'):
            case str_starts_with($connection, 'memcached:'):
                if (!class_exists(AbstractAdapter::class)) {
                    throw new \InvalidArgumentException(sprintf('Unsupported DSN "%s". Try running "composer require symfony/cache".', $connection));
                }
                $handlerClass = str_starts_with($connection, 'memcached:') ? MemcachedSessionHandler::class : RedisSessionHandler::class;
                $connection = AbstractAdapter::createConnection($connection, ['lazy' => true]);

                return new $handlerClass($connection);

            case str_starts_with($connection, 'pdo_oci://'):
                if (!class_exists(DriverManager::class)) {
                    throw new \InvalidArgumentException(sprintf('Unsupported DSN "%s". Try running "composer require doctrine/dbal".', $connection));
                }
                $connection = DriverManager::getConnection(['url' => $connection])->getWrappedConnection();
                // no break;

            case str_starts_with($connection, 'mssql://'):
            case str_starts_with($connection, 'mysql://'):
            case str_starts_with($connection, 'mysql2://'):
            case str_starts_with($connection, 'pgsql://'):
            case str_starts_with($connection, 'postgres://'):
            case str_starts_with($connection, 'postgresql://'):
            case str_starts_with($connection, 'sqlsrv://'):
            case str_starts_with($connection, 'sqlite://'):
            case str_starts_with($connection, 'sqlite3://'):
                return new PdoSessionHandler($connection);
        }

        throw new \InvalidArgumentException(sprintf('Unsupported Connection: "%s".', $connection));
    }
}
PKϤ$Z4tkb�
�
Chttp-foundation/Session/Storage/Handler/MigratingSessionHandler.phpnu�[���<?php

/*
 * This file is part of the Symfony package.
 *
 * (c) Fabien Potencier <fabien@symfony.com>
 *
 * For the full copyright and license information, please view the LICENSE
 * file that was distributed with this source code.
 */

namespace Symfony\Component\HttpFoundation\Session\Storage\Handler;

/**
 * Migrating session handler for migrating from one handler to another. It reads
 * from the current handler and writes both the current and new ones.
 *
 * It ignores errors from the new handler.
 *
 * @author Ross Motley <ross.motley@amara.com>
 * @author Oliver Radwell <oliver.radwell@amara.com>
 */
class MigratingSessionHandler implements \SessionHandlerInterface, \SessionUpdateTimestampHandlerInterface
{
    private $currentHandler;
    private $writeOnlyHandler;

    public function __construct(\SessionHandlerInterface $currentHandler, \SessionHandlerInterface $writeOnlyHandler)
    {
        if (!$currentHandler instanceof \SessionUpdateTimestampHandlerInterface) {
            $currentHandler = new StrictSessionHandler($currentHandler);
        }
        if (!$writeOnlyHandler instanceof \SessionUpdateTimestampHandlerInterface) {
            $writeOnlyHandler = new StrictSessionHandler($writeOnlyHandler);
        }

        $this->currentHandler = $currentHandler;
        $this->writeOnlyHandler = $writeOnlyHandler;
    }

    /**
     * @return bool
     */
    #[\ReturnTypeWillChange]
    public function close()
    {
        $result = $this->currentHandler->close();
        $this->writeOnlyHandler->close();

        return $result;
    }

    /**
     * @return bool
     */
    #[\ReturnTypeWillChange]
    public function destroy($sessionId)
    {
        $result = $this->currentHandler->destroy($sessionId);
        $this->writeOnlyHandler->destroy($sessionId);

        return $result;
    }

    /**
     * @return int|false
     */
    #[\ReturnTypeWillChange]
    public function gc($maxlifetime)
    {
        $result = $this->currentHandler->gc($maxlifetime);
        $this->writeOnlyHandler->gc($maxlifetime);

        return $result;
    }

    /**
     * @return bool
     */
    #[\ReturnTypeWillChange]
    public function open($savePath, $sessionName)
    {
        $result = $this->currentHandler->open($savePath, $sessionName);
        $this->writeOnlyHandler->open($savePath, $sessionName);

        return $result;
    }

    /**
     * @return string
     */
    #[\ReturnTypeWillChange]
    public function read($sessionId)
    {
        // No reading from new handler until switch-over
        return $this->currentHandler->read($sessionId);
    }

    /**
     * @return bool
     */
    #[\ReturnTypeWillChange]
    public function write($sessionId, $sessionData)
    {
        $result = $this->currentHandler->write($sessionId, $sessionData);
        $this->writeOnlyHandler->write($sessionId, $sessionData);

        return $result;
    }

    /**
     * @return bool
     */
    #[\ReturnTypeWillChange]
    public function validateId($sessionId)
    {
        // No reading from new handler until switch-over
        return $this->currentHandler->validateId($sessionId);
    }

    /**
     * @return bool
     */
    #[\ReturnTypeWillChange]
    public function updateTimestamp($sessionId, $sessionData)
    {
        $result = $this->currentHandler->updateTimestamp($sessionId, $sessionData);
        $this->writeOnlyHandler->updateTimestamp($sessionId, $sessionData);

        return $result;
    }
}
PKϤ$Z;9����Dhttp-foundation/Session/Storage/Handler/WriteCheckSessionHandler.phpnu�[���<?php

/*
 * This file is part of the Symfony package.
 *
 * (c) Fabien Potencier <fabien@symfony.com>
 *
 * For the full copyright and license information, please view the LICENSE
 * file that was distributed with this source code.
 */

namespace Symfony\Component\HttpFoundation\Session\Storage\Handler;

/**
 * Wraps another SessionHandlerInterface to only write the session when it has been modified.
 *
 * @author Adrien Brault <adrien.brault@gmail.com>
 */
class WriteCheckSessionHandler implements \SessionHandlerInterface
{
    /**
     * @var \SessionHandlerInterface
     */
    private $wrappedSessionHandler;

    /**
     * @var array sessionId => session
     */
    private $readSessions;

    public function __construct(\SessionHandlerInterface $wrappedSessionHandler)
    {
        $this->wrappedSessionHandler = $wrappedSessionHandler;
    }

    /**
     * {@inheritdoc}
     */
    public function close()
    {
        return $this->wrappedSessionHandler->close();
    }

    /**
     * {@inheritdoc}
     */
    public function destroy($sessionId)
    {
        return $this->wrappedSessionHandler->destroy($sessionId);
    }

    /**
     * {@inheritdoc}
     */
    public function gc($maxlifetime)
    {
        return $this->wrappedSessionHandler->gc($maxlifetime);
    }

    /**
     * {@inheritdoc}
     */
    public function open($savePath, $sessionName)
    {
        return $this->wrappedSessionHandler->open($savePath, $sessionName);
    }

    /**
     * {@inheritdoc}
     */
    public function read($sessionId)
    {
        $session = $this->wrappedSessionHandler->read($sessionId);

        $this->readSessions[$sessionId] = $session;

        return $session;
    }

    /**
     * {@inheritdoc}
     */
    public function write($sessionId, $data)
    {
        if (isset($this->readSessions[$sessionId]) && $data === $this->readSessions[$sessionId]) {
            return true;
        }

        return $this->wrappedSessionHandler->write($sessionId, $data);
    }
}
PKϤ$Z���S��>http-foundation/Session/Storage/Handler/NullSessionHandler.phpnu�[���<?php

/*
 * This file is part of the Symfony package.
 *
 * (c) Fabien Potencier <fabien@symfony.com>
 *
 * For the full copyright and license information, please view the LICENSE
 * file that was distributed with this source code.
 */

namespace Symfony\Component\HttpFoundation\Session\Storage\Handler;

/**
 * Can be used in unit testing or in a situations where persisted sessions are not desired.
 *
 * @author Drak <drak@zikula.org>
 */
class NullSessionHandler extends AbstractSessionHandler
{
    /**
     * @return bool
     */
    #[\ReturnTypeWillChange]
    public function close()
    {
        return true;
    }

    /**
     * @return bool
     */
    #[\ReturnTypeWillChange]
    public function validateId($sessionId)
    {
        return true;
    }

    /**
     * {@inheritdoc}
     */
    protected function doRead(string $sessionId)
    {
        return '';
    }

    /**
     * @return bool
     */
    #[\ReturnTypeWillChange]
    public function updateTimestamp($sessionId, $data)
    {
        return true;
    }

    /**
     * {@inheritdoc}
     */
    protected function doWrite(string $sessionId, string $data)
    {
        return true;
    }

    /**
     * {@inheritdoc}
     */
    protected function doDestroy(string $sessionId)
    {
        return true;
    }

    /**
     * @return int|false
     */
    #[\ReturnTypeWillChange]
    public function gc($maxlifetime)
    {
        return 0;
    }
}
PKϤ$Z�E�
(
(Chttp-foundation/Session/Storage/Handler/LegacyPdoSessionHandler.phpnu�[���<?php

/*
 * This file is part of the Symfony package.
 *
 * (c) Fabien Potencier <fabien@symfony.com>
 *
 * For the full copyright and license information, please view the LICENSE
 * file that was distributed with this source code.
 */

namespace Symfony\Component\HttpFoundation\Session\Storage\Handler;

@trigger_error('The '.__NAMESPACE__.'\LegacyPdoSessionHandler class is deprecated since version 2.6 and will be removed in 3.0. Use the Symfony\Component\HttpFoundation\Session\Storage\Handler\PdoSessionHandler class instead.', E_USER_DEPRECATED);

/**
 * Session handler using a PDO connection to read and write data.
 *
 * Session data is a binary string that can contain non-printable characters like the null byte.
 * For this reason this handler base64 encodes the data to be able to save it in a character column.
 *
 * This version of the PdoSessionHandler does NOT implement locking. So concurrent requests to the
 * same session can result in data loss due to race conditions.
 *
 * @author Fabien Potencier <fabien@symfony.com>
 * @author Michael Williams <michael.williams@funsational.com>
 * @author Tobias Schultze <http://tobion.de>
 *
 * @deprecated since version 2.6, to be removed in 3.0. Use
 *             {@link PdoSessionHandler} instead.
 */
class LegacyPdoSessionHandler implements \SessionHandlerInterface
{
    /**
     * @var \PDO PDO instance
     */
    private $pdo;

    /**
     * @var string Table name
     */
    private $table;

    /**
     * @var string Column for session id
     */
    private $idCol;

    /**
     * @var string Column for session data
     */
    private $dataCol;

    /**
     * @var string Column for timestamp
     */
    private $timeCol;

    /**
     * Constructor.
     *
     * List of available options:
     *  * db_table: The name of the table [required]
     *  * db_id_col: The column where to store the session id [default: sess_id]
     *  * db_data_col: The column where to store the session data [default: sess_data]
     *  * db_time_col: The column where to store the timestamp [default: sess_time]
     *
     * @param \PDO  $pdo       A \PDO instance
     * @param array $dbOptions An associative array of DB options
     *
     * @throws \InvalidArgumentException When "db_table" option is not provided
     */
    public function __construct(\PDO $pdo, array $dbOptions = array())
    {
        if (!array_key_exists('db_table', $dbOptions)) {
            throw new \InvalidArgumentException('You must provide the "db_table" option for a PdoSessionStorage.');
        }
        if (\PDO::ERRMODE_EXCEPTION !== $pdo->getAttribute(\PDO::ATTR_ERRMODE)) {
            throw new \InvalidArgumentException(sprintf('"%s" requires PDO error mode attribute be set to throw Exceptions (i.e. $pdo->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION))', __CLASS__));
        }

        $this->pdo = $pdo;
        $dbOptions = array_merge(array(
            'db_id_col' => 'sess_id',
            'db_data_col' => 'sess_data',
            'db_time_col' => 'sess_time',
        ), $dbOptions);

        $this->table = $dbOptions['db_table'];
        $this->idCol = $dbOptions['db_id_col'];
        $this->dataCol = $dbOptions['db_data_col'];
        $this->timeCol = $dbOptions['db_time_col'];
    }

    /**
     * {@inheritdoc}
     */
    public function open($savePath, $sessionName)
    {
        return true;
    }

    /**
     * {@inheritdoc}
     */
    public function close()
    {
        return true;
    }

    /**
     * {@inheritdoc}
     */
    public function destroy($sessionId)
    {
        // delete the record associated with this id
        $sql = "DELETE FROM $this->table WHERE $this->idCol = :id";

        try {
            $stmt = $this->pdo->prepare($sql);
            $stmt->bindParam(':id', $sessionId, \PDO::PARAM_STR);
            $stmt->execute();
        } catch (\PDOException $e) {
            throw new \RuntimeException(sprintf('PDOException was thrown when trying to delete a session: %s', $e->getMessage()), 0, $e);
        }

        return true;
    }

    /**
     * {@inheritdoc}
     */
    public function gc($maxlifetime)
    {
        // delete the session records that have expired
        $sql = "DELETE FROM $this->table WHERE $this->timeCol < :time";

        try {
            $stmt = $this->pdo->prepare($sql);
            $stmt->bindValue(':time', time() - $maxlifetime, \PDO::PARAM_INT);
            $stmt->execute();
        } catch (\PDOException $e) {
            throw new \RuntimeException(sprintf('PDOException was thrown when trying to delete expired sessions: %s', $e->getMessage()), 0, $e);
        }

        return true;
    }

    /**
     * {@inheritdoc}
     */
    public function read($sessionId)
    {
        $sql = "SELECT $this->dataCol FROM $this->table WHERE $this->idCol = :id";

        try {
            $stmt = $this->pdo->prepare($sql);
            $stmt->bindParam(':id', $sessionId, \PDO::PARAM_STR);
            $stmt->execute();

            // We use fetchAll instead of fetchColumn to make sure the DB cursor gets closed
            $sessionRows = $stmt->fetchAll(\PDO::FETCH_NUM);

            if ($sessionRows) {
                return base64_decode($sessionRows[0][0]);
            }

            return '';
        } catch (\PDOException $e) {
            throw new \RuntimeException(sprintf('PDOException was thrown when trying to read the session data: %s', $e->getMessage()), 0, $e);
        }
    }

    /**
     * {@inheritdoc}
     */
    public function write($sessionId, $data)
    {
        $encoded = base64_encode($data);

        try {
            // We use a single MERGE SQL query when supported by the database.
            $mergeSql = $this->getMergeSql();

            if (null !== $mergeSql) {
                $mergeStmt = $this->pdo->prepare($mergeSql);
                $mergeStmt->bindParam(':id', $sessionId, \PDO::PARAM_STR);
                $mergeStmt->bindParam(':data', $encoded, \PDO::PARAM_STR);
                $mergeStmt->bindValue(':time', time(), \PDO::PARAM_INT);
                $mergeStmt->execute();

                return true;
            }

            $updateStmt = $this->pdo->prepare(
                "UPDATE $this->table SET $this->dataCol = :data, $this->timeCol = :time WHERE $this->idCol = :id"
            );
            $updateStmt->bindParam(':id', $sessionId, \PDO::PARAM_STR);
            $updateStmt->bindParam(':data', $encoded, \PDO::PARAM_STR);
            $updateStmt->bindValue(':time', time(), \PDO::PARAM_INT);
            $updateStmt->execute();

            // When MERGE is not supported, like in Postgres, we have to use this approach that can result in
            // duplicate key errors when the same session is written simultaneously. We can just catch such an
            // error and re-execute the update. This is similar to a serializable transaction with retry logic
            // on serialization failures but without the overhead and without possible false positives due to
            // longer gap locking.
            if (!$updateStmt->rowCount()) {
                try {
                    $insertStmt = $this->pdo->prepare(
                        "INSERT INTO $this->table ($this->idCol, $this->dataCol, $this->timeCol) VALUES (:id, :data, :time)"
                    );
                    $insertStmt->bindParam(':id', $sessionId, \PDO::PARAM_STR);
                    $insertStmt->bindParam(':data', $encoded, \PDO::PARAM_STR);
                    $insertStmt->bindValue(':time', time(), \PDO::PARAM_INT);
                    $insertStmt->execute();
                } catch (\PDOException $e) {
                    // Handle integrity violation SQLSTATE 23000 (or a subclass like 23505 in Postgres) for duplicate keys
                    if (0 === strpos($e->getCode(), '23')) {
                        $updateStmt->execute();
                    } else {
                        throw $e;
                    }
                }
            }
        } catch (\PDOException $e) {
            throw new \RuntimeException(sprintf('PDOException was thrown when trying to write the session data: %s', $e->getMessage()), 0, $e);
        }

        return true;
    }

    /**
     * Returns a merge/upsert (i.e. insert or update) SQL query when supported by the database.
     *
     * @return string|null The SQL string or null when not supported
     */
    private function getMergeSql()
    {
        $driver = $this->pdo->getAttribute(\PDO::ATTR_DRIVER_NAME);

        switch ($driver) {
            case 'mysql':
                return "INSERT INTO $this->table ($this->idCol, $this->dataCol, $this->timeCol) VALUES (:id, :data, :time) ".
                "ON DUPLICATE KEY UPDATE $this->dataCol = VALUES($this->dataCol), $this->timeCol = VALUES($this->timeCol)";
            case 'oci':
                // DUAL is Oracle specific dummy table
                return "MERGE INTO $this->table USING DUAL ON ($this->idCol = :id) ".
                "WHEN NOT MATCHED THEN INSERT ($this->idCol, $this->dataCol, $this->timeCol) VALUES (:id, :data, :time) ".
                "WHEN MATCHED THEN UPDATE SET $this->dataCol = :data, $this->timeCol = :time";
            case 'sqlsrv' === $driver && version_compare($this->pdo->getAttribute(\PDO::ATTR_SERVER_VERSION), '10', '>='):
                // MERGE is only available since SQL Server 2008 and must be terminated by semicolon
                // It also requires HOLDLOCK according to http://weblogs.sqlteam.com/dang/archive/2009/01/31/UPSERT-Race-Condition-With-MERGE.aspx
                return "MERGE INTO $this->table WITH (HOLDLOCK) USING (SELECT 1 AS dummy) AS src ON ($this->idCol = :id) ".
                "WHEN NOT MATCHED THEN INSERT ($this->idCol, $this->dataCol, $this->timeCol) VALUES (:id, :data, :time) ".
                "WHEN MATCHED THEN UPDATE SET $this->dataCol = :data, $this->timeCol = :time;";
            case 'sqlite':
                return "INSERT OR REPLACE INTO $this->table ($this->idCol, $this->dataCol, $this->timeCol) VALUES (:id, :data, :time)";
        }
    }

    /**
     * Return a PDO instance.
     *
     * @return \PDO
     */
    protected function getConnection()
    {
        return $this->pdo;
    }
}
PKϤ$Z+�8##Dhttp-foundation/Session/Storage/Handler/NativeFileSessionHandler.phpnu�[���<?php

/*
 * This file is part of the Symfony package.
 *
 * (c) Fabien Potencier <fabien@symfony.com>
 *
 * For the full copyright and license information, please view the LICENSE
 * file that was distributed with this source code.
 */

namespace Symfony\Component\HttpFoundation\Session\Storage\Handler;

/**
 * Native session handler using PHP's built in file storage.
 *
 * @author Drak <drak@zikula.org>
 */
class NativeFileSessionHandler extends \SessionHandler
{
    /**
     * @param string $savePath Path of directory to save session files
     *                         Default null will leave setting as defined by PHP.
     *                         '/path', 'N;/path', or 'N;octal-mode;/path
     *
     * @see https://php.net/session.configuration#ini.session.save-path for further details.
     *
     * @throws \InvalidArgumentException On invalid $savePath
     * @throws \RuntimeException         When failing to create the save directory
     */
    public function __construct(string $savePath = null)
    {
        if (null === $savePath) {
            $savePath = ini_get('session.save_path');
        }

        $baseDir = $savePath;

        if ($count = substr_count($savePath, ';')) {
            if ($count > 2) {
                throw new \InvalidArgumentException(sprintf('Invalid argument $savePath \'%s\'.', $savePath));
            }

            // characters after last ';' are the path
            $baseDir = ltrim(strrchr($savePath, ';'), ';');
        }

        if ($baseDir && !is_dir($baseDir) && !@mkdir($baseDir, 0777, true) && !is_dir($baseDir)) {
            throw new \RuntimeException(sprintf('Session Storage was not able to create directory "%s".', $baseDir));
        }

        ini_set('session.save_path', $savePath);
        ini_set('session.save_handler', 'files');
    }
}
PKϤ$Z>�B9PP?http-foundation/Session/Storage/Handler/RedisSessionHandler.phpnu�[���<?php

/*
 * This file is part of the Symfony package.
 *
 * (c) Fabien Potencier <fabien@symfony.com>
 *
 * For the full copyright and license information, please view the LICENSE
 * file that was distributed with this source code.
 */

namespace Symfony\Component\HttpFoundation\Session\Storage\Handler;

use Predis\Response\ErrorInterface;
use Symfony\Component\Cache\Traits\RedisClusterProxy;
use Symfony\Component\Cache\Traits\RedisProxy;

/**
 * Redis based session storage handler based on the Redis class
 * provided by the PHP redis extension.
 *
 * @author Dalibor Karlović <dalibor@flexolabs.io>
 */
class RedisSessionHandler extends AbstractSessionHandler
{
    private $redis;

    /**
     * @var string Key prefix for shared environments
     */
    private $prefix;

    /**
     * @var int Time to live in seconds
     */
    private $ttl;

    /**
     * List of available options:
     *  * prefix: The prefix to use for the keys in order to avoid collision on the Redis server
     *  * ttl: The time to live in seconds.
     *
     * @param \Redis|\RedisArray|\RedisCluster|\Predis\ClientInterface|RedisProxy|RedisClusterProxy $redis
     *
     * @throws \InvalidArgumentException When unsupported client or options are passed
     */
    public function __construct($redis, array $options = [])
    {
        if (
            !$redis instanceof \Redis &&
            !$redis instanceof \RedisArray &&
            !$redis instanceof \RedisCluster &&
            !$redis instanceof \Predis\ClientInterface &&
            !$redis instanceof RedisProxy &&
            !$redis instanceof RedisClusterProxy
        ) {
            throw new \InvalidArgumentException(sprintf('"%s()" expects parameter 1 to be Redis, RedisArray, RedisCluster or Predis\ClientInterface, "%s" given.', __METHOD__, get_debug_type($redis)));
        }

        if ($diff = array_diff(array_keys($options), ['prefix', 'ttl'])) {
            throw new \InvalidArgumentException(sprintf('The following options are not supported "%s".', implode(', ', $diff)));
        }

        $this->redis = $redis;
        $this->prefix = $options['prefix'] ?? 'sf_s';
        $this->ttl = $options['ttl'] ?? null;
    }

    /**
     * {@inheritdoc}
     */
    protected function doRead(string $sessionId): string
    {
        return $this->redis->get($this->prefix.$sessionId) ?: '';
    }

    /**
     * {@inheritdoc}
     */
    protected function doWrite(string $sessionId, string $data): bool
    {
        $result = $this->redis->setEx($this->prefix.$sessionId, (int) ($this->ttl ?? ini_get('session.gc_maxlifetime')), $data);

        return $result && !$result instanceof ErrorInterface;
    }

    /**
     * {@inheritdoc}
     */
    protected function doDestroy(string $sessionId): bool
    {
        static $unlink = true;

        if ($unlink) {
            try {
                $unlink = false !== $this->redis->unlink($this->prefix.$sessionId);
            } catch (\Throwable $e) {
                $unlink = false;
            }
        }

        if (!$unlink) {
            $this->redis->del($this->prefix.$sessionId);
        }

        return true;
    }

    /**
     * {@inheritdoc}
     */
    public function close(): bool
    {
        return true;
    }

    /**
     * {@inheritdoc}
     *
     * @return int|false
     */
    #[\ReturnTypeWillChange]
    public function gc($maxlifetime)
    {
        return 0;
    }

    /**
     * @return bool
     */
    public function updateTimestamp($sessionId, $data)
    {
        return (bool) $this->redis->expire($this->prefix.$sessionId, (int) ($this->ttl ?? ini_get('session.gc_maxlifetime')));
    }
}
PKϤ$Z#���9http-foundation/Session/Storage/ServiceSessionFactory.phpnu�[���<?php

/*
 * This file is part of the Symfony package.
 *
 * (c) Fabien Potencier <fabien@symfony.com>
 *
 * For the full copyright and license information, please view the LICENSE
 * file that was distributed with this source code.
 */

namespace Symfony\Component\HttpFoundation\Session\Storage;

use Symfony\Component\HttpFoundation\Request;

/**
 * @author Jérémy Derussé <jeremy@derusse.com>
 *
 * @internal to be removed in Symfony 6
 */
final class ServiceSessionFactory implements SessionStorageFactoryInterface
{
    private $storage;

    public function __construct(SessionStorageInterface $storage)
    {
        $this->storage = $storage;
    }

    public function createStorage(?Request $request): SessionStorageInterface
    {
        if ($this->storage instanceof NativeSessionStorage && $request && $request->isSecure()) {
            $this->storage->setOptions(['cookie_secure' => true]);
        }

        return $this->storage;
    }
}
PKϤ$Z����ZZBhttp-foundation/Session/Storage/SessionStorageFactoryInterface.phpnu�[���<?php

/*
 * This file is part of the Symfony package.
 *
 * (c) Fabien Potencier <fabien@symfony.com>
 *
 * For the full copyright and license information, please view the LICENSE
 * file that was distributed with this source code.
 */

namespace Symfony\Component\HttpFoundation\Session\Storage;

use Symfony\Component\HttpFoundation\Request;

/**
 * @author Jérémy Derussé <jeremy@derusse.com>
 */
interface SessionStorageFactoryInterface
{
    /**
     * Creates a new instance of SessionStorageInterface.
     */
    public function createStorage(?Request $request): SessionStorageInterface;
}
PKϤ$Z4�ٜ�;http-foundation/Session/Storage/SessionStorageInterface.phpnu�[���<?php

/*
 * This file is part of the Symfony package.
 *
 * (c) Fabien Potencier <fabien@symfony.com>
 *
 * For the full copyright and license information, please view the LICENSE
 * file that was distributed with this source code.
 */

namespace Symfony\Component\HttpFoundation\Session\Storage;

use Symfony\Component\HttpFoundation\Session\SessionBagInterface;

/**
 * StorageInterface.
 *
 * @author Fabien Potencier <fabien@symfony.com>
 * @author Drak <drak@zikula.org>
 */
interface SessionStorageInterface
{
    /**
     * Starts the session.
     *
     * @return bool True if started
     *
     * @throws \RuntimeException if something goes wrong starting the session
     */
    public function start();

    /**
     * Checks if the session is started.
     *
     * @return bool True if started, false otherwise
     */
    public function isStarted();

    /**
     * Returns the session ID.
     *
     * @return string The session ID or empty
     */
    public function getId();

    /**
     * Sets the session ID.
     */
    public function setId(string $id);

    /**
     * Returns the session name.
     *
     * @return string The session name
     */
    public function getName();

    /**
     * Sets the session name.
     */
    public function setName(string $name);

    /**
     * Regenerates id that represents this storage.
     *
     * This method must invoke session_regenerate_id($destroy) unless
     * this interface is used for a storage object designed for unit
     * or functional testing where a real PHP session would interfere
     * with testing.
     *
     * Note regenerate+destroy should not clear the session data in memory
     * only delete the session data from persistent storage.
     *
     * Care: When regenerating the session ID no locking is involved in PHP's
     * session design. See https://bugs.php.net/61470 for a discussion.
     * So you must make sure the regenerated session is saved BEFORE sending the
     * headers with the new ID. Symfony's HttpKernel offers a listener for this.
     * See Symfony\Component\HttpKernel\EventListener\SaveSessionListener.
     * Otherwise session data could get lost again for concurrent requests with the
     * new ID. One result could be that you get logged out after just logging in.
     *
     * @param bool $destroy  Destroy session when regenerating?
     * @param int  $lifetime Sets the cookie lifetime for the session cookie. A null value
     *                       will leave the system settings unchanged, 0 sets the cookie
     *                       to expire with browser session. Time is in seconds, and is
     *                       not a Unix timestamp.
     *
     * @return bool True if session regenerated, false if error
     *
     * @throws \RuntimeException If an error occurs while regenerating this storage
     */
    public function regenerate(bool $destroy = false, int $lifetime = null);

    /**
     * Force the session to be saved and closed.
     *
     * This method must invoke session_write_close() unless this interface is
     * used for a storage object design for unit or functional testing where
     * a real PHP session would interfere with testing, in which case
     * it should actually persist the session data if required.
     *
     * @throws \RuntimeException if the session is saved without being started, or if the session
     *                           is already closed
     */
    public function save();

    /**
     * Clear all session data in memory.
     */
    public function clear();

    /**
     * Gets a SessionBagInterface by name.
     *
     * @return SessionBagInterface
     *
     * @throws \InvalidArgumentException If the bag does not exist
     */
    public function getBag(string $name);

    /**
     * Registers a SessionBagInterface for use.
     */
    public function registerBag(SessionBagInterface $bag);

    /**
     * @return MetadataBag
     */
    public function getMetadataBag();
}
PKϤ$Z=S*c��;http-foundation/Session/Storage/PhpBridgeSessionStorage.phpnu�[���<?php

/*
 * This file is part of the Symfony package.
 *
 * (c) Fabien Potencier <fabien@symfony.com>
 *
 * For the full copyright and license information, please view the LICENSE
 * file that was distributed with this source code.
 */

namespace Symfony\Component\HttpFoundation\Session\Storage;

use Symfony\Component\HttpFoundation\Session\Storage\Proxy\AbstractProxy;

/**
 * Allows session to be started by PHP and managed by Symfony.
 *
 * @author Drak <drak@zikula.org>
 */
class PhpBridgeSessionStorage extends NativeSessionStorage
{
    /**
     * @param AbstractProxy|\SessionHandlerInterface|null $handler
     */
    public function __construct($handler = null, MetadataBag $metaBag = null)
    {
        if (!\extension_loaded('session')) {
            throw new \LogicException('PHP extension "session" is required.');
        }

        $this->setMetadataBag($metaBag);
        $this->setSaveHandler($handler);
    }

    /**
     * {@inheritdoc}
     */
    public function start()
    {
        if ($this->started) {
            return true;
        }

        $this->loadSession();

        return true;
    }

    /**
     * {@inheritdoc}
     */
    public function clear()
    {
        // clear out the bags and nothing else that may be set
        // since the purpose of this driver is to share a handler
        foreach ($this->bags as $bag) {
            $bag->clear();
        }

        // reconnect the bags to the session
        $this->loadSession();
    }
}
PKϤ$Z����ddAhttp-foundation/Session/Storage/MockFileSessionStorageFactory.phpnu�[���<?php

/*
 * This file is part of the Symfony package.
 *
 * (c) Fabien Potencier <fabien@symfony.com>
 *
 * For the full copyright and license information, please view the LICENSE
 * file that was distributed with this source code.
 */

namespace Symfony\Component\HttpFoundation\Session\Storage;

use Symfony\Component\HttpFoundation\Request;

// Help opcache.preload discover always-needed symbols
class_exists(MockFileSessionStorage::class);

/**
 * @author Jérémy Derussé <jeremy@derusse.com>
 */
class MockFileSessionStorageFactory implements SessionStorageFactoryInterface
{
    private $savePath;
    private $name;
    private $metaBag;

    /**
     * @see MockFileSessionStorage constructor.
     */
    public function __construct(string $savePath = null, string $name = 'MOCKSESSID', MetadataBag $metaBag = null)
    {
        $this->savePath = $savePath;
        $this->name = $name;
        $this->metaBag = $metaBag;
    }

    public function createStorage(?Request $request): SessionStorageInterface
    {
        return new MockFileSessionStorage($this->savePath, $this->name, $this->metaBag);
    }
}
PKϤ$Z�X��7�78http-foundation/Session/Storage/NativeSessionStorage.phpnu�[���<?php

/*
 * This file is part of the Symfony package.
 *
 * (c) Fabien Potencier <fabien@symfony.com>
 *
 * For the full copyright and license information, please view the LICENSE
 * file that was distributed with this source code.
 */

namespace Symfony\Component\HttpFoundation\Session\Storage;

use Symfony\Component\HttpFoundation\Session\SessionBagInterface;
use Symfony\Component\HttpFoundation\Session\SessionUtils;
use Symfony\Component\HttpFoundation\Session\Storage\Handler\StrictSessionHandler;
use Symfony\Component\HttpFoundation\Session\Storage\Proxy\AbstractProxy;
use Symfony\Component\HttpFoundation\Session\Storage\Proxy\SessionHandlerProxy;

// Help opcache.preload discover always-needed symbols
class_exists(MetadataBag::class);
class_exists(StrictSessionHandler::class);
class_exists(SessionHandlerProxy::class);

/**
 * This provides a base class for session attribute storage.
 *
 * @author Drak <drak@zikula.org>
 */
class NativeSessionStorage implements SessionStorageInterface
{
    /**
     * @var SessionBagInterface[]
     */
    protected $bags = [];

    /**
     * @var bool
     */
    protected $started = false;

    /**
     * @var bool
     */
    protected $closed = false;

    /**
     * @var AbstractProxy|\SessionHandlerInterface
     */
    protected $saveHandler;

    /**
     * @var MetadataBag
     */
    protected $metadataBag;

    /**
     * @var string|null
     */
    private $emulateSameSite;

    /**
     * Depending on how you want the storage driver to behave you probably
     * want to override this constructor entirely.
     *
     * List of options for $options array with their defaults.
     *
     * @see https://php.net/session.configuration for options
     * but we omit 'session.' from the beginning of the keys for convenience.
     *
     * ("auto_start", is not supported as it tells PHP to start a session before
     * PHP starts to execute user-land code. Setting during runtime has no effect).
     *
     * cache_limiter, "" (use "0" to prevent headers from being sent entirely).
     * cache_expire, "0"
     * cookie_domain, ""
     * cookie_httponly, ""
     * cookie_lifetime, "0"
     * cookie_path, "/"
     * cookie_secure, ""
     * cookie_samesite, null
     * gc_divisor, "100"
     * gc_maxlifetime, "1440"
     * gc_probability, "1"
     * lazy_write, "1"
     * name, "PHPSESSID"
     * referer_check, ""
     * serialize_handler, "php"
     * use_strict_mode, "1"
     * use_cookies, "1"
     * use_only_cookies, "1"
     * use_trans_sid, "0"
     * upload_progress.enabled, "1"
     * upload_progress.cleanup, "1"
     * upload_progress.prefix, "upload_progress_"
     * upload_progress.name, "PHP_SESSION_UPLOAD_PROGRESS"
     * upload_progress.freq, "1%"
     * upload_progress.min-freq, "1"
     * url_rewriter.tags, "a=href,area=href,frame=src,form=,fieldset="
     * sid_length, "32"
     * sid_bits_per_character, "5"
     * trans_sid_hosts, $_SERVER['HTTP_HOST']
     * trans_sid_tags, "a=href,area=href,frame=src,form="
     *
     * @param AbstractProxy|\SessionHandlerInterface|null $handler
     */
    public function __construct(array $options = [], $handler = null, MetadataBag $metaBag = null)
    {
        if (!\extension_loaded('session')) {
            throw new \LogicException('PHP extension "session" is required.');
        }

        $options += [
            'cache_limiter' => '',
            'cache_expire' => 0,
            'use_cookies' => 1,
            'lazy_write' => 1,
            'use_strict_mode' => 1,
        ];

        session_register_shutdown();

        $this->setMetadataBag($metaBag);
        $this->setOptions($options);
        $this->setSaveHandler($handler);
    }

    /**
     * Gets the save handler instance.
     *
     * @return AbstractProxy|\SessionHandlerInterface
     */
    public function getSaveHandler()
    {
        return $this->saveHandler;
    }

    /**
     * {@inheritdoc}
     */
    public function start()
    {
        if ($this->started) {
            return true;
        }

        if (\PHP_SESSION_ACTIVE === session_status()) {
            throw new \RuntimeException('Failed to start the session: already started by PHP.');
        }

        if (filter_var(ini_get('session.use_cookies'), \FILTER_VALIDATE_BOOLEAN) && headers_sent($file, $line)) {
            throw new \RuntimeException(sprintf('Failed to start the session because headers have already been sent by "%s" at line %d.', $file, $line));
        }

        // ok to try and start the session
        if (!session_start()) {
            throw new \RuntimeException('Failed to start the session.');
        }

        if (null !== $this->emulateSameSite) {
            $originalCookie = SessionUtils::popSessionCookie(session_name(), session_id());
            if (null !== $originalCookie) {
                header(sprintf('%s; SameSite=%s', $originalCookie, $this->emulateSameSite), false);
            }
        }

        $this->loadSession();

        return true;
    }

    /**
     * {@inheritdoc}
     */
    public function getId()
    {
        return $this->saveHandler->getId();
    }

    /**
     * {@inheritdoc}
     */
    public function setId(string $id)
    {
        $this->saveHandler->setId($id);
    }

    /**
     * {@inheritdoc}
     */
    public function getName()
    {
        return $this->saveHandler->getName();
    }

    /**
     * {@inheritdoc}
     */
    public function setName(string $name)
    {
        $this->saveHandler->setName($name);
    }

    /**
     * {@inheritdoc}
     */
    public function regenerate(bool $destroy = false, int $lifetime = null)
    {
        // Cannot regenerate the session ID for non-active sessions.
        if (\PHP_SESSION_ACTIVE !== session_status()) {
            return false;
        }

        if (headers_sent()) {
            return false;
        }

        if (null !== $lifetime && $lifetime != ini_get('session.cookie_lifetime')) {
            $this->save();
            ini_set('session.cookie_lifetime', $lifetime);
            $this->start();
        }

        if ($destroy) {
            $this->metadataBag->stampNew();
        }

        $isRegenerated = session_regenerate_id($destroy);

        if (null !== $this->emulateSameSite) {
            $originalCookie = SessionUtils::popSessionCookie(session_name(), session_id());
            if (null !== $originalCookie) {
                header(sprintf('%s; SameSite=%s', $originalCookie, $this->emulateSameSite), false);
            }
        }

        return $isRegenerated;
    }

    /**
     * {@inheritdoc}
     */
    public function save()
    {
        // Store a copy so we can restore the bags in case the session was not left empty
        $session = $_SESSION;

        foreach ($this->bags as $bag) {
            if (empty($_SESSION[$key = $bag->getStorageKey()])) {
                unset($_SESSION[$key]);
            }
        }
        if ([$key = $this->metadataBag->getStorageKey()] === array_keys($_SESSION)) {
            unset($_SESSION[$key]);
        }

        // Register error handler to add information about the current save handler
        $previousHandler = set_error_handler(function ($type, $msg, $file, $line) use (&$previousHandler) {
            if (\E_WARNING === $type && str_starts_with($msg, 'session_write_close():')) {
                $handler = $this->saveHandler instanceof SessionHandlerProxy ? $this->saveHandler->getHandler() : $this->saveHandler;
                $msg = sprintf('session_write_close(): Failed to write session data with "%s" handler', \get_class($handler));
            }

            return $previousHandler ? $previousHandler($type, $msg, $file, $line) : false;
        });

        try {
            session_write_close();
        } finally {
            restore_error_handler();

            // Restore only if not empty
            if ($_SESSION) {
                $_SESSION = $session;
            }
        }

        $this->closed = true;
        $this->started = false;
    }

    /**
     * {@inheritdoc}
     */
    public function clear()
    {
        // clear out the bags
        foreach ($this->bags as $bag) {
            $bag->clear();
        }

        // clear out the session
        $_SESSION = [];

        // reconnect the bags to the session
        $this->loadSession();
    }

    /**
     * {@inheritdoc}
     */
    public function registerBag(SessionBagInterface $bag)
    {
        if ($this->started) {
            throw new \LogicException('Cannot register a bag when the session is already started.');
        }

        $this->bags[$bag->getName()] = $bag;
    }

    /**
     * {@inheritdoc}
     */
    public function getBag(string $name)
    {
        if (!isset($this->bags[$name])) {
            throw new \InvalidArgumentException(sprintf('The SessionBagInterface "%s" is not registered.', $name));
        }

        if (!$this->started && $this->saveHandler->isActive()) {
            $this->loadSession();
        } elseif (!$this->started) {
            $this->start();
        }

        return $this->bags[$name];
    }

    public function setMetadataBag(MetadataBag $metaBag = null)
    {
        if (null === $metaBag) {
            $metaBag = new MetadataBag();
        }

        $this->metadataBag = $metaBag;
    }

    /**
     * Gets the MetadataBag.
     *
     * @return MetadataBag
     */
    public function getMetadataBag()
    {
        return $this->metadataBag;
    }

    /**
     * {@inheritdoc}
     */
    public function isStarted()
    {
        return $this->started;
    }

    /**
     * Sets session.* ini variables.
     *
     * For convenience we omit 'session.' from the beginning of the keys.
     * Explicitly ignores other ini keys.
     *
     * @param array $options Session ini directives [key => value]
     *
     * @see https://php.net/session.configuration
     */
    public function setOptions(array $options)
    {
        if (headers_sent() || \PHP_SESSION_ACTIVE === session_status()) {
            return;
        }

        $validOptions = array_flip([
            'cache_expire', 'cache_limiter', 'cookie_domain', 'cookie_httponly',
            'cookie_lifetime', 'cookie_path', 'cookie_secure', 'cookie_samesite',
            'gc_divisor', 'gc_maxlifetime', 'gc_probability',
            'lazy_write', 'name', 'referer_check',
            'serialize_handler', 'use_strict_mode', 'use_cookies',
            'use_only_cookies', 'use_trans_sid', 'upload_progress.enabled',
            'upload_progress.cleanup', 'upload_progress.prefix', 'upload_progress.name',
            'upload_progress.freq', 'upload_progress.min_freq', 'url_rewriter.tags',
            'sid_length', 'sid_bits_per_character', 'trans_sid_hosts', 'trans_sid_tags',
        ]);

        foreach ($options as $key => $value) {
            if (isset($validOptions[$key])) {
                if ('cookie_samesite' === $key && \PHP_VERSION_ID < 70300) {
                    // PHP < 7.3 does not support same_site cookies. We will emulate it in
                    // the start() method instead.
                    $this->emulateSameSite = $value;
                    continue;
                }
                if ('cookie_secure' === $key && 'auto' === $value) {
                    continue;
                }
                ini_set('url_rewriter.tags' !== $key ? 'session.'.$key : $key, $value);
            }
        }
    }

    /**
     * Registers session save handler as a PHP session handler.
     *
     * To use internal PHP session save handlers, override this method using ini_set with
     * session.save_handler and session.save_path e.g.
     *
     *     ini_set('session.save_handler', 'files');
     *     ini_set('session.save_path', '/tmp');
     *
     * or pass in a \SessionHandler instance which configures session.save_handler in the
     * constructor, for a template see NativeFileSessionHandler.
     *
     * @see https://php.net/session-set-save-handler
     * @see https://php.net/sessionhandlerinterface
     * @see https://php.net/sessionhandler
     *
     * @param AbstractProxy|\SessionHandlerInterface|null $saveHandler
     *
     * @throws \InvalidArgumentException
     */
    public function setSaveHandler($saveHandler = null)
    {
        if (!$saveHandler instanceof AbstractProxy &&
            !$saveHandler instanceof \SessionHandlerInterface &&
            null !== $saveHandler) {
            throw new \InvalidArgumentException('Must be instance of AbstractProxy; implement \SessionHandlerInterface; or be null.');
        }

        // Wrap $saveHandler in proxy and prevent double wrapping of proxy
        if (!$saveHandler instanceof AbstractProxy && $saveHandler instanceof \SessionHandlerInterface) {
            $saveHandler = new SessionHandlerProxy($saveHandler);
        } elseif (!$saveHandler instanceof AbstractProxy) {
            $saveHandler = new SessionHandlerProxy(new StrictSessionHandler(new \SessionHandler()));
        }
        $this->saveHandler = $saveHandler;

        if (headers_sent() || \PHP_SESSION_ACTIVE === session_status()) {
            return;
        }

        if ($this->saveHandler instanceof SessionHandlerProxy) {
            session_set_save_handler($this->saveHandler, false);
        }
    }

    /**
     * Load the session with attributes.
     *
     * After starting the session, PHP retrieves the session from whatever handlers
     * are set to (either PHP's internal, or a custom save handler set with session_set_save_handler()).
     * PHP takes the return value from the read() handler, unserializes it
     * and populates $_SESSION with the result automatically.
     */
    protected function loadSession(array &$session = null)
    {
        if (null === $session) {
            $session = &$_SESSION;
        }

        $bags = array_merge($this->bags, [$this->metadataBag]);

        foreach ($bags as $bag) {
            $key = $bag->getStorageKey();
            $session[$key] = isset($session[$key]) && \is_array($session[$key]) ? $session[$key] : [];
            $bag->initialize($session[$key]);
        }

        $this->started = true;
        $this->closed = false;
    }
}
PKϤ$Z	��\]](http-foundation/Session/SessionUtils.phpnu�[���<?php

/*
 * This file is part of the Symfony package.
 *
 * (c) Fabien Potencier <fabien@symfony.com>
 *
 * For the full copyright and license information, please view the LICENSE
 * file that was distributed with this source code.
 */

namespace Symfony\Component\HttpFoundation\Session;

/**
 * Session utility functions.
 *
 * @author Nicolas Grekas <p@tchwork.com>
 * @author Rémon van de Kamp <rpkamp@gmail.com>
 *
 * @internal
 */
final class SessionUtils
{
    /**
     * Finds the session header amongst the headers that are to be sent, removes it, and returns
     * it so the caller can process it further.
     */
    public static function popSessionCookie(string $sessionName, string $sessionId): ?string
    {
        $sessionCookie = null;
        $sessionCookiePrefix = sprintf(' %s=', urlencode($sessionName));
        $sessionCookieWithId = sprintf('%s%s;', $sessionCookiePrefix, urlencode($sessionId));
        $otherCookies = [];
        foreach (headers_list() as $h) {
            if (0 !== stripos($h, 'Set-Cookie:')) {
                continue;
            }
            if (11 === strpos($h, $sessionCookiePrefix, 11)) {
                $sessionCookie = $h;

                if (11 !== strpos($h, $sessionCookieWithId, 11)) {
                    $otherCookies[] = $h;
                }
            } else {
                $otherCookies[] = $h;
            }
        }
        if (null === $sessionCookie) {
            return null;
        }

        header_remove('Set-Cookie');
        foreach ($otherCookies as $h) {
            header($h, false);
        }

        return $sessionCookie;
    }
}
PKϤ$ZY$p��<http-foundation/Session/Attribute/NamespacedAttributeBag.phpnu�[���<?php

/*
 * This file is part of the Symfony package.
 *
 * (c) Fabien Potencier <fabien@symfony.com>
 *
 * For the full copyright and license information, please view the LICENSE
 * file that was distributed with this source code.
 */

namespace Symfony\Component\HttpFoundation\Session\Attribute;

trigger_deprecation('symfony/http-foundation', '5.3', 'The "%s" class is deprecated.', NamespacedAttributeBag::class);

/**
 * This class provides structured storage of session attributes using
 * a name spacing character in the key.
 *
 * @author Drak <drak@zikula.org>
 *
 * @deprecated since Symfony 5.3
 */
class NamespacedAttributeBag extends AttributeBag
{
    private $namespaceCharacter;

    /**
     * @param string $storageKey         Session storage key
     * @param string $namespaceCharacter Namespace character to use in keys
     */
    public function __construct(string $storageKey = '_sf2_attributes', string $namespaceCharacter = '/')
    {
        $this->namespaceCharacter = $namespaceCharacter;
        parent::__construct($storageKey);
    }

    /**
     * {@inheritdoc}
     */
    public function has(string $name)
    {
        // reference mismatch: if fixed, re-introduced in array_key_exists; keep as it is
        $attributes = $this->resolveAttributePath($name);
        $name = $this->resolveKey($name);

        if (null === $attributes) {
            return false;
        }

        return \array_key_exists($name, $attributes);
    }

    /**
     * {@inheritdoc}
     */
    public function get(string $name, $default = null)
    {
        // reference mismatch: if fixed, re-introduced in array_key_exists; keep as it is
        $attributes = $this->resolveAttributePath($name);
        $name = $this->resolveKey($name);

        if (null === $attributes) {
            return $default;
        }

        return \array_key_exists($name, $attributes) ? $attributes[$name] : $default;
    }

    /**
     * {@inheritdoc}
     */
    public function set(string $name, $value)
    {
        $attributes = &$this->resolveAttributePath($name, true);
        $name = $this->resolveKey($name);
        $attributes[$name] = $value;
    }

    /**
     * {@inheritdoc}
     */
    public function remove(string $name)
    {
        $retval = null;
        $attributes = &$this->resolveAttributePath($name);
        $name = $this->resolveKey($name);
        if (null !== $attributes && \array_key_exists($name, $attributes)) {
            $retval = $attributes[$name];
            unset($attributes[$name]);
        }

        return $retval;
    }

    /**
     * Resolves a path in attributes property and returns it as a reference.
     *
     * This method allows structured namespacing of session attributes.
     *
     * @param string $name         Key name
     * @param bool   $writeContext Write context, default false
     *
     * @return array|null
     */
    protected function &resolveAttributePath(string $name, bool $writeContext = false)
    {
        $array = &$this->attributes;
        $name = (str_starts_with($name, $this->namespaceCharacter)) ? substr($name, 1) : $name;

        // Check if there is anything to do, else return
        if (!$name) {
            return $array;
        }

        $parts = explode($this->namespaceCharacter, $name);
        if (\count($parts) < 2) {
            if (!$writeContext) {
                return $array;
            }

            $array[$parts[0]] = [];

            return $array;
        }

        unset($parts[\count($parts) - 1]);

        foreach ($parts as $part) {
            if (null !== $array && !\array_key_exists($part, $array)) {
                if (!$writeContext) {
                    $null = null;

                    return $null;
                }

                $array[$part] = [];
            }

            $array = &$array[$part];
        }

        return $array;
    }

    /**
     * Resolves the key from the name.
     *
     * This is the last part in a dot separated string.
     *
     * @return string
     */
    protected function resolveKey(string $name)
    {
        if (false !== $pos = strrpos($name, $this->namespaceCharacter)) {
            $name = substr($name, $pos + 1);
        }

        return $name;
    }
}
PKϤ$Z6Z$y;http-foundation/Session/Attribute/AttributeBagInterface.phpnu�[���<?php

/*
 * This file is part of the Symfony package.
 *
 * (c) Fabien Potencier <fabien@symfony.com>
 *
 * For the full copyright and license information, please view the LICENSE
 * file that was distributed with this source code.
 */

namespace Symfony\Component\HttpFoundation\Session\Attribute;

use Symfony\Component\HttpFoundation\Session\SessionBagInterface;

/**
 * Attributes store.
 *
 * @author Drak <drak@zikula.org>
 */
interface AttributeBagInterface extends SessionBagInterface
{
    /**
     * Checks if an attribute is defined.
     *
     * @return bool true if the attribute is defined, false otherwise
     */
    public function has(string $name);

    /**
     * Returns an attribute.
     *
     * @param mixed $default The default value if not found
     *
     * @return mixed
     */
    public function get(string $name, $default = null);

    /**
     * Sets an attribute.
     *
     * @param mixed $value
     */
    public function set(string $name, $value);

    /**
     * Returns attributes.
     *
     * @return array
     */
    public function all();

    public function replace(array $attributes);

    /**
     * Removes an attribute.
     *
     * @return mixed The removed value or null when it does not exist
     */
    public function remove(string $name);
}
PKϤ$Z1%�)��2http-foundation/Session/Attribute/AttributeBag.phpnu�[���<?php

/*
 * This file is part of the Symfony package.
 *
 * (c) Fabien Potencier <fabien@symfony.com>
 *
 * For the full copyright and license information, please view the LICENSE
 * file that was distributed with this source code.
 */

namespace Symfony\Component\HttpFoundation\Session\Attribute;

/**
 * This class relates to session attribute storage.
 */
class AttributeBag implements AttributeBagInterface, \IteratorAggregate, \Countable
{
    private $name = 'attributes';
    private $storageKey;

    protected $attributes = [];

    /**
     * @param string $storageKey The key used to store attributes in the session
     */
    public function __construct(string $storageKey = '_sf2_attributes')
    {
        $this->storageKey = $storageKey;
    }

    /**
     * {@inheritdoc}
     */
    public function getName()
    {
        return $this->name;
    }

    public function setName(string $name)
    {
        $this->name = $name;
    }

    /**
     * {@inheritdoc}
     */
    public function initialize(array &$attributes)
    {
        $this->attributes = &$attributes;
    }

    /**
     * {@inheritdoc}
     */
    public function getStorageKey()
    {
        return $this->storageKey;
    }

    /**
     * {@inheritdoc}
     */
    public function has(string $name)
    {
        return \array_key_exists($name, $this->attributes);
    }

    /**
     * {@inheritdoc}
     */
    public function get(string $name, $default = null)
    {
        return \array_key_exists($name, $this->attributes) ? $this->attributes[$name] : $default;
    }

    /**
     * {@inheritdoc}
     */
    public function set(string $name, $value)
    {
        $this->attributes[$name] = $value;
    }

    /**
     * {@inheritdoc}
     */
    public function all()
    {
        return $this->attributes;
    }

    /**
     * {@inheritdoc}
     */
    public function replace(array $attributes)
    {
        $this->attributes = [];
        foreach ($attributes as $key => $value) {
            $this->set($key, $value);
        }
    }

    /**
     * {@inheritdoc}
     */
    public function remove(string $name)
    {
        $retval = null;
        if (\array_key_exists($name, $this->attributes)) {
            $retval = $this->attributes[$name];
            unset($this->attributes[$name]);
        }

        return $retval;
    }

    /**
     * {@inheritdoc}
     */
    public function clear()
    {
        $return = $this->attributes;
        $this->attributes = [];

        return $return;
    }

    /**
     * Returns an iterator for attributes.
     *
     * @return \ArrayIterator An \ArrayIterator instance
     */
    #[\ReturnTypeWillChange]
    public function getIterator()
    {
        return new \ArrayIterator($this->attributes);
    }

    /**
     * Returns the number of attributes.
     *
     * @return int The number of attributes
     */
    #[\ReturnTypeWillChange]
    public function count()
    {
        return \count($this->attributes);
    }
}
PKϤ$Z^�v�$�$http-foundation/HeaderUtils.phpnu�[���<?php

/*
 * This file is part of the Symfony package.
 *
 * (c) Fabien Potencier <fabien@symfony.com>
 *
 * For the full copyright and license information, please view the LICENSE
 * file that was distributed with this source code.
 */

namespace Symfony\Component\HttpFoundation;

/**
 * HTTP header utility functions.
 *
 * @author Christian Schmidt <github@chsc.dk>
 */
class HeaderUtils
{
    public const DISPOSITION_ATTACHMENT = 'attachment';
    public const DISPOSITION_INLINE = 'inline';

    /**
     * This class should not be instantiated.
     */
    private function __construct()
    {
    }

    /**
     * Splits an HTTP header by one or more separators.
     *
     * Example:
     *
     *     HeaderUtils::split("da, en-gb;q=0.8", ",;")
     *     // => ['da'], ['en-gb', 'q=0.8']]
     *
     * @param string $separators List of characters to split on, ordered by
     *                           precedence, e.g. ",", ";=", or ",;="
     *
     * @return array Nested array with as many levels as there are characters in
     *               $separators
     */
    public static function split(string $header, string $separators): array
    {
        $quotedSeparators = preg_quote($separators, '/');

        preg_match_all('
            /
                (?!\s)
                    (?:
                        # quoted-string
                        "(?:[^"\\\\]|\\\\.)*(?:"|\\\\|$)
                    |
                        # token
                        [^"'.$quotedSeparators.']+
                    )+
                (?<!\s)
            |
                # separator
                \s*
                (?<separator>['.$quotedSeparators.'])
                \s*
            /x', trim($header), $matches, \PREG_SET_ORDER);

        return self::groupParts($matches, $separators);
    }

    /**
     * Combines an array of arrays into one associative array.
     *
     * Each of the nested arrays should have one or two elements. The first
     * value will be used as the keys in the associative array, and the second
     * will be used as the values, or true if the nested array only contains one
     * element. Array keys are lowercased.
     *
     * Example:
     *
     *     HeaderUtils::combine([["foo", "abc"], ["bar"]])
     *     // => ["foo" => "abc", "bar" => true]
     */
    public static function combine(array $parts): array
    {
        $assoc = [];
        foreach ($parts as $part) {
            $name = strtolower($part[0]);
            $value = $part[1] ?? true;
            $assoc[$name] = $value;
        }

        return $assoc;
    }

    /**
     * Joins an associative array into a string for use in an HTTP header.
     *
     * The key and value of each entry are joined with "=", and all entries
     * are joined with the specified separator and an additional space (for
     * readability). Values are quoted if necessary.
     *
     * Example:
     *
     *     HeaderUtils::toString(["foo" => "abc", "bar" => true, "baz" => "a b c"], ",")
     *     // => 'foo=abc, bar, baz="a b c"'
     */
    public static function toString(array $assoc, string $separator): string
    {
        $parts = [];
        foreach ($assoc as $name => $value) {
            if (true === $value) {
                $parts[] = $name;
            } else {
                $parts[] = $name.'='.self::quote($value);
            }
        }

        return implode($separator.' ', $parts);
    }

    /**
     * Encodes a string as a quoted string, if necessary.
     *
     * If a string contains characters not allowed by the "token" construct in
     * the HTTP specification, it is backslash-escaped and enclosed in quotes
     * to match the "quoted-string" construct.
     */
    public static function quote(string $s): string
    {
        if (preg_match('/^[a-z0-9!#$%&\'*.^_`|~-]+$/i', $s)) {
            return $s;
        }

        return '"'.addcslashes($s, '"\\"').'"';
    }

    /**
     * Decodes a quoted string.
     *
     * If passed an unquoted string that matches the "token" construct (as
     * defined in the HTTP specification), it is passed through verbatimly.
     */
    public static function unquote(string $s): string
    {
        return preg_replace('/\\\\(.)|"/', '$1', $s);
    }

    /**
     * Generates an HTTP Content-Disposition field-value.
     *
     * @param string $disposition      One of "inline" or "attachment"
     * @param string $filename         A unicode string
     * @param string $filenameFallback A string containing only ASCII characters that
     *                                 is semantically equivalent to $filename. If the filename is already ASCII,
     *                                 it can be omitted, or just copied from $filename
     *
     * @return string A string suitable for use as a Content-Disposition field-value
     *
     * @throws \InvalidArgumentException
     *
     * @see RFC 6266
     */
    public static function makeDisposition(string $disposition, string $filename, string $filenameFallback = ''): string
    {
        if (!\in_array($disposition, [self::DISPOSITION_ATTACHMENT, self::DISPOSITION_INLINE])) {
            throw new \InvalidArgumentException(sprintf('The disposition must be either "%s" or "%s".', self::DISPOSITION_ATTACHMENT, self::DISPOSITION_INLINE));
        }

        if ('' === $filenameFallback) {
            $filenameFallback = $filename;
        }

        // filenameFallback is not ASCII.
        if (!preg_match('/^[\x20-\x7e]*$/', $filenameFallback)) {
            throw new \InvalidArgumentException('The filename fallback must only contain ASCII characters.');
        }

        // percent characters aren't safe in fallback.
        if (str_contains($filenameFallback, '%')) {
            throw new \InvalidArgumentException('The filename fallback cannot contain the "%" character.');
        }

        // path separators aren't allowed in either.
        if (str_contains($filename, '/') || str_contains($filename, '\\') || str_contains($filenameFallback, '/') || str_contains($filenameFallback, '\\')) {
            throw new \InvalidArgumentException('The filename and the fallback cannot contain the "/" and "\\" characters.');
        }

        $params = ['filename' => $filenameFallback];
        if ($filename !== $filenameFallback) {
            $params['filename*'] = "utf-8''".rawurlencode($filename);
        }

        return $disposition.'; '.self::toString($params, ';');
    }

    /**
     * Like parse_str(), but preserves dots in variable names.
     */
    public static function parseQuery(string $query, bool $ignoreBrackets = false, string $separator = '&'): array
    {
        $q = [];

        foreach (explode($separator, $query) as $v) {
            if (false !== $i = strpos($v, "\0")) {
                $v = substr($v, 0, $i);
            }

            if (false === $i = strpos($v, '=')) {
                $k = urldecode($v);
                $v = '';
            } else {
                $k = urldecode(substr($v, 0, $i));
                $v = substr($v, $i);
            }

            if (false !== $i = strpos($k, "\0")) {
                $k = substr($k, 0, $i);
            }

            $k = ltrim($k, ' ');

            if ($ignoreBrackets) {
                $q[$k][] = urldecode(substr($v, 1));

                continue;
            }

            if (false === $i = strpos($k, '[')) {
                $q[] = bin2hex($k).$v;
            } else {
                $q[] = bin2hex(substr($k, 0, $i)).rawurlencode(substr($k, $i)).$v;
            }
        }

        if ($ignoreBrackets) {
            return $q;
        }

        parse_str(implode('&', $q), $q);

        $query = [];

        foreach ($q as $k => $v) {
            if (false !== $i = strpos($k, '_')) {
                $query[substr_replace($k, hex2bin(substr($k, 0, $i)).'[', 0, 1 + $i)] = $v;
            } else {
                $query[hex2bin($k)] = $v;
            }
        }

        return $query;
    }

    private static function groupParts(array $matches, string $separators, bool $first = true): array
    {
        $separator = $separators[0];
        $partSeparators = substr($separators, 1);

        $i = 0;
        $partMatches = [];
        $previousMatchWasSeparator = false;
        foreach ($matches as $match) {
            if (!$first && $previousMatchWasSeparator && isset($match['separator']) && $match['separator'] === $separator) {
                $previousMatchWasSeparator = true;
                $partMatches[$i][] = $match;
            } elseif (isset($match['separator']) && $match['separator'] === $separator) {
                $previousMatchWasSeparator = true;
                ++$i;
            } else {
                $previousMatchWasSeparator = false;
                $partMatches[$i][] = $match;
            }
        }

        $parts = [];
        if ($partSeparators) {
            foreach ($partMatches as $matches) {
                $parts[] = self::groupParts($matches, $partSeparators, false);
            }
        } else {
            foreach ($partMatches as $matches) {
                $parts[] = self::unquote($matches[0][0]);
            }

            if (!$first && 2 < \count($parts)) {
                $parts = [
                    $parts[0],
                    implode($separator, \array_slice($parts, 1)),
                ];
            }
        }

        return $parts;
    }
}
PKϤ$Z�hT);(;(%http-foundation/File/UploadedFile.phpnu�[���<?php

/*
 * This file is part of the Symfony package.
 *
 * (c) Fabien Potencier <fabien@symfony.com>
 *
 * For the full copyright and license information, please view the LICENSE
 * file that was distributed with this source code.
 */

namespace Symfony\Component\HttpFoundation\File;

use Symfony\Component\HttpFoundation\File\Exception\CannotWriteFileException;
use Symfony\Component\HttpFoundation\File\Exception\ExtensionFileException;
use Symfony\Component\HttpFoundation\File\Exception\FileException;
use Symfony\Component\HttpFoundation\File\Exception\FileNotFoundException;
use Symfony\Component\HttpFoundation\File\Exception\FormSizeFileException;
use Symfony\Component\HttpFoundation\File\Exception\IniSizeFileException;
use Symfony\Component\HttpFoundation\File\Exception\NoFileException;
use Symfony\Component\HttpFoundation\File\Exception\NoTmpDirFileException;
use Symfony\Component\HttpFoundation\File\Exception\PartialFileException;
use Symfony\Component\Mime\MimeTypes;

/**
 * A file uploaded through a form.
 *
 * @author Bernhard Schussek <bschussek@gmail.com>
 * @author Florian Eckerstorfer <florian@eckerstorfer.org>
 * @author Fabien Potencier <fabien@symfony.com>
 */
class UploadedFile extends File
{
    private $test;
    private $originalName;
    private $mimeType;
    private $error;

    /**
     * Accepts the information of the uploaded file as provided by the PHP global $_FILES.
     *
     * The file object is only created when the uploaded file is valid (i.e. when the
     * isValid() method returns true). Otherwise the only methods that could be called
     * on an UploadedFile instance are:
     *
     *   * getClientOriginalName,
     *   * getClientMimeType,
     *   * isValid,
     *   * getError.
     *
     * Calling any other method on an non-valid instance will cause an unpredictable result.
     *
     * @param string      $path         The full temporary path to the file
     * @param string      $originalName The original file name of the uploaded file
     * @param string|null $mimeType     The type of the file as provided by PHP; null defaults to application/octet-stream
     * @param int|null    $error        The error constant of the upload (one of PHP's UPLOAD_ERR_XXX constants); null defaults to UPLOAD_ERR_OK
     * @param bool        $test         Whether the test mode is active
     *                                  Local files are used in test mode hence the code should not enforce HTTP uploads
     *
     * @throws FileException         If file_uploads is disabled
     * @throws FileNotFoundException If the file does not exist
     */
    public function __construct(string $path, string $originalName, string $mimeType = null, int $error = null, bool $test = false)
    {
        $this->originalName = $this->getName($originalName);
        $this->mimeType = $mimeType ?: 'application/octet-stream';
        $this->error = $error ?: \UPLOAD_ERR_OK;
        $this->test = $test;

        parent::__construct($path, \UPLOAD_ERR_OK === $this->error);
    }

    /**
     * Returns the original file name.
     *
     * It is extracted from the request from which the file has been uploaded.
     * Then it should not be considered as a safe value.
     *
     * @return string The original name
     */
    public function getClientOriginalName()
    {
        return $this->originalName;
    }

    /**
     * Returns the original file extension.
     *
     * It is extracted from the original file name that was uploaded.
     * Then it should not be considered as a safe value.
     *
     * @return string The extension
     */
    public function getClientOriginalExtension()
    {
        return pathinfo($this->originalName, \PATHINFO_EXTENSION);
    }

    /**
     * Returns the file mime type.
     *
     * The client mime type is extracted from the request from which the file
     * was uploaded, so it should not be considered as a safe value.
     *
     * For a trusted mime type, use getMimeType() instead (which guesses the mime
     * type based on the file content).
     *
     * @return string The mime type
     *
     * @see getMimeType()
     */
    public function getClientMimeType()
    {
        return $this->mimeType;
    }

    /**
     * Returns the extension based on the client mime type.
     *
     * If the mime type is unknown, returns null.
     *
     * This method uses the mime type as guessed by getClientMimeType()
     * to guess the file extension. As such, the extension returned
     * by this method cannot be trusted.
     *
     * For a trusted extension, use guessExtension() instead (which guesses
     * the extension based on the guessed mime type for the file).
     *
     * @return string|null The guessed extension or null if it cannot be guessed
     *
     * @see guessExtension()
     * @see getClientMimeType()
     */
    public function guessClientExtension()
    {
        if (!class_exists(MimeTypes::class)) {
            throw new \LogicException('You cannot guess the extension as the Mime component is not installed. Try running "composer require symfony/mime".');
        }

        return MimeTypes::getDefault()->getExtensions($this->getClientMimeType())[0] ?? null;
    }

    /**
     * Returns the upload error.
     *
     * If the upload was successful, the constant UPLOAD_ERR_OK is returned.
     * Otherwise one of the other UPLOAD_ERR_XXX constants is returned.
     *
     * @return int The upload error
     */
    public function getError()
    {
        return $this->error;
    }

    /**
     * Returns whether the file was uploaded successfully.
     *
     * @return bool True if the file has been uploaded with HTTP and no error occurred
     */
    public function isValid()
    {
        $isOk = \UPLOAD_ERR_OK === $this->error;

        return $this->test ? $isOk : $isOk && is_uploaded_file($this->getPathname());
    }

    /**
     * Moves the file to a new location.
     *
     * @return File A File object representing the new file
     *
     * @throws FileException if, for any reason, the file could not have been moved
     */
    public function move(string $directory, string $name = null)
    {
        if ($this->isValid()) {
            if ($this->test) {
                return parent::move($directory, $name);
            }

            $target = $this->getTargetFile($directory, $name);

            set_error_handler(function ($type, $msg) use (&$error) { $error = $msg; });
            $moved = move_uploaded_file($this->getPathname(), $target);
            restore_error_handler();
            if (!$moved) {
                throw new FileException(sprintf('Could not move the file "%s" to "%s" (%s).', $this->getPathname(), $target, strip_tags($error)));
            }

            @chmod($target, 0666 & ~umask());

            return $target;
        }

        switch ($this->error) {
            case \UPLOAD_ERR_INI_SIZE:
                throw new IniSizeFileException($this->getErrorMessage());
            case \UPLOAD_ERR_FORM_SIZE:
                throw new FormSizeFileException($this->getErrorMessage());
            case \UPLOAD_ERR_PARTIAL:
                throw new PartialFileException($this->getErrorMessage());
            case \UPLOAD_ERR_NO_FILE:
                throw new NoFileException($this->getErrorMessage());
            case \UPLOAD_ERR_CANT_WRITE:
                throw new CannotWriteFileException($this->getErrorMessage());
            case \UPLOAD_ERR_NO_TMP_DIR:
                throw new NoTmpDirFileException($this->getErrorMessage());
            case \UPLOAD_ERR_EXTENSION:
                throw new ExtensionFileException($this->getErrorMessage());
        }

        throw new FileException($this->getErrorMessage());
    }

    /**
     * Returns the maximum size of an uploaded file as configured in php.ini.
     *
     * @return int|float The maximum size of an uploaded file in bytes (returns float if size > PHP_INT_MAX)
     */
    public static function getMaxFilesize()
    {
        $sizePostMax = self::parseFilesize(ini_get('post_max_size'));
        $sizeUploadMax = self::parseFilesize(ini_get('upload_max_filesize'));

        return min($sizePostMax ?: \PHP_INT_MAX, $sizeUploadMax ?: \PHP_INT_MAX);
    }

    /**
     * Returns the given size from an ini value in bytes.
     *
     * @return int|float Returns float if size > PHP_INT_MAX
     */
    private static function parseFilesize(string $size)
    {
        if ('' === $size) {
            return 0;
        }

        $size = strtolower($size);

        $max = ltrim($size, '+');
        if (str_starts_with($max, '0x')) {
            $max = \intval($max, 16);
        } elseif (str_starts_with($max, '0')) {
            $max = \intval($max, 8);
        } else {
            $max = (int) $max;
        }

        switch (substr($size, -1)) {
            case 't': $max *= 1024;
            // no break
            case 'g': $max *= 1024;
            // no break
            case 'm': $max *= 1024;
            // no break
            case 'k': $max *= 1024;
        }

        return $max;
    }

    /**
     * Returns an informative upload error message.
     *
     * @return string The error message regarding the specified error code
     */
    public function getErrorMessage()
    {
        static $errors = [
            \UPLOAD_ERR_INI_SIZE => 'The file "%s" exceeds your upload_max_filesize ini directive (limit is %d KiB).',
            \UPLOAD_ERR_FORM_SIZE => 'The file "%s" exceeds the upload limit defined in your form.',
            \UPLOAD_ERR_PARTIAL => 'The file "%s" was only partially uploaded.',
            \UPLOAD_ERR_NO_FILE => 'No file was uploaded.',
            \UPLOAD_ERR_CANT_WRITE => 'The file "%s" could not be written on disk.',
            \UPLOAD_ERR_NO_TMP_DIR => 'File could not be uploaded: missing temporary directory.',
            \UPLOAD_ERR_EXTENSION => 'File upload was stopped by a PHP extension.',
        ];

        $errorCode = $this->error;
        $maxFilesize = \UPLOAD_ERR_INI_SIZE === $errorCode ? self::getMaxFilesize() / 1024 : 0;
        $message = $errors[$errorCode] ?? 'The file "%s" was not uploaded due to an unknown error.';

        return sprintf($message, $this->getClientOriginalName(), $maxFilesize);
    }
}
PKϤ$Z�ˇ1�	�	2http-foundation/File/MimeType/ExtensionGuesser.phpnu�[���<?php

/*
 * This file is part of the Symfony package.
 *
 * (c) Fabien Potencier <fabien@symfony.com>
 *
 * For the full copyright and license information, please view the LICENSE
 * file that was distributed with this source code.
 */

namespace Symfony\Component\HttpFoundation\File\MimeType;

/**
 * A singleton mime type to file extension guesser.
 *
 * A default guesser is provided.
 * You can register custom guessers by calling the register()
 * method on the singleton instance:
 *
 *     $guesser = ExtensionGuesser::getInstance();
 *     $guesser->register(new MyCustomExtensionGuesser());
 *
 * The last registered guesser is preferred over previously registered ones.
 */
class ExtensionGuesser implements ExtensionGuesserInterface
{
    /**
     * The singleton instance.
     *
     * @var ExtensionGuesser
     */
    private static $instance = null;

    /**
     * All registered ExtensionGuesserInterface instances.
     *
     * @var array
     */
    protected $guessers = array();

    /**
     * Returns the singleton instance.
     *
     * @return ExtensionGuesser
     */
    public static function getInstance()
    {
        if (null === self::$instance) {
            self::$instance = new self();
        }

        return self::$instance;
    }

    /**
     * Registers all natively provided extension guessers.
     */
    private function __construct()
    {
        $this->register(new MimeTypeExtensionGuesser());
    }

    /**
     * Registers a new extension guesser.
     *
     * When guessing, this guesser is preferred over previously registered ones.
     *
     * @param ExtensionGuesserInterface $guesser
     */
    public function register(ExtensionGuesserInterface $guesser)
    {
        array_unshift($this->guessers, $guesser);
    }

    /**
     * Tries to guess the extension.
     *
     * The mime type is passed to each registered mime type guesser in reverse order
     * of their registration (last registered is queried first). Once a guesser
     * returns a value that is not NULL, this method terminates and returns the
     * value.
     *
     * @param string $mimeType The mime type
     *
     * @return string The guessed extension or NULL, if none could be guessed
     */
    public function guess($mimeType)
    {
        foreach ($this->guessers as $guesser) {
            if (null !== $extension = $guesser->guess($mimeType)) {
                return $extension;
            }
        }
    }
}
PKϤ$Z��f���;http-foundation/File/MimeType/ExtensionGuesserInterface.phpnu�[���<?php

/*
 * This file is part of the Symfony package.
 *
 * (c) Fabien Potencier <fabien@symfony.com>
 *
 * For the full copyright and license information, please view the LICENSE
 * file that was distributed with this source code.
 */

namespace Symfony\Component\HttpFoundation\File\MimeType;

/**
 * Guesses the file extension corresponding to a given mime type.
 */
interface ExtensionGuesserInterface
{
    /**
     * Makes a best guess for a file extension, given a mime type.
     *
     * @param string $mimeType The mime type
     *
     * @return string The guessed extension or NULL, if none could be guessed
     */
    public function guess($mimeType);
}
PKϤ$Z�>O��:http-foundation/File/MimeType/MimeTypeGuesserInterface.phpnu�[���<?php

/*
 * This file is part of the Symfony package.
 *
 * (c) Fabien Potencier <fabien@symfony.com>
 *
 * For the full copyright and license information, please view the LICENSE
 * file that was distributed with this source code.
 */

namespace Symfony\Component\HttpFoundation\File\MimeType;

use Symfony\Component\HttpFoundation\File\Exception\FileNotFoundException;
use Symfony\Component\HttpFoundation\File\Exception\AccessDeniedException;

/**
 * Guesses the mime type of a file.
 *
 * @author Bernhard Schussek <bschussek@gmail.com>
 */
interface MimeTypeGuesserInterface
{
    /**
     * Guesses the mime type of the file with the given path.
     *
     * @param string $path The path to the file
     *
     * @return string The mime type or NULL, if none could be guessed
     *
     * @throws FileNotFoundException If the file does not exist
     * @throws AccessDeniedException If the file could not be read
     */
    public function guess($path);
}
PKϤ$Zp�'��1http-foundation/File/MimeType/MimeTypeGuesser.phpnu�[���<?php

/*
 * This file is part of the Symfony package.
 *
 * (c) Fabien Potencier <fabien@symfony.com>
 *
 * For the full copyright and license information, please view the LICENSE
 * file that was distributed with this source code.
 */

namespace Symfony\Component\HttpFoundation\File\MimeType;

use Symfony\Component\HttpFoundation\File\Exception\FileNotFoundException;
use Symfony\Component\HttpFoundation\File\Exception\AccessDeniedException;

/**
 * A singleton mime type guesser.
 *
 * By default, all mime type guessers provided by the framework are installed
 * (if available on the current OS/PHP setup).
 *
 * You can register custom guessers by calling the register() method on the
 * singleton instance. Custom guessers are always called before any default ones.
 *
 *     $guesser = MimeTypeGuesser::getInstance();
 *     $guesser->register(new MyCustomMimeTypeGuesser());
 *
 * If you want to change the order of the default guessers, just re-register your
 * preferred one as a custom one. The last registered guesser is preferred over
 * previously registered ones.
 *
 * Re-registering a built-in guesser also allows you to configure it:
 *
 *     $guesser = MimeTypeGuesser::getInstance();
 *     $guesser->register(new FileinfoMimeTypeGuesser('/path/to/magic/file'));
 *
 * @author Bernhard Schussek <bschussek@gmail.com>
 */
class MimeTypeGuesser implements MimeTypeGuesserInterface
{
    /**
     * The singleton instance.
     *
     * @var MimeTypeGuesser
     */
    private static $instance = null;

    /**
     * All registered MimeTypeGuesserInterface instances.
     *
     * @var array
     */
    protected $guessers = array();

    /**
     * Returns the singleton instance.
     *
     * @return MimeTypeGuesser
     */
    public static function getInstance()
    {
        if (null === self::$instance) {
            self::$instance = new self();
        }

        return self::$instance;
    }

    /**
     * Resets the singleton instance.
     */
    public static function reset()
    {
        self::$instance = null;
    }

    /**
     * Registers all natively provided mime type guessers.
     */
    private function __construct()
    {
        if (FileBinaryMimeTypeGuesser::isSupported()) {
            $this->register(new FileBinaryMimeTypeGuesser());
        }

        if (FileinfoMimeTypeGuesser::isSupported()) {
            $this->register(new FileinfoMimeTypeGuesser());
        }
    }

    /**
     * Registers a new mime type guesser.
     *
     * When guessing, this guesser is preferred over previously registered ones.
     *
     * @param MimeTypeGuesserInterface $guesser
     */
    public function register(MimeTypeGuesserInterface $guesser)
    {
        array_unshift($this->guessers, $guesser);
    }

    /**
     * Tries to guess the mime type of the given file.
     *
     * The file is passed to each registered mime type guesser in reverse order
     * of their registration (last registered is queried first). Once a guesser
     * returns a value that is not NULL, this method terminates and returns the
     * value.
     *
     * @param string $path The path to the file
     *
     * @return string The mime type or NULL, if none could be guessed
     *
     * @throws \LogicException
     * @throws FileNotFoundException
     * @throws AccessDeniedException
     */
    public function guess($path)
    {
        if (!is_file($path)) {
            throw new FileNotFoundException($path);
        }

        if (!is_readable($path)) {
            throw new AccessDeniedException($path);
        }

        if (!$this->guessers) {
            $msg = 'Unable to guess the mime type as no guessers are available';
            if (!FileinfoMimeTypeGuesser::isSupported()) {
                $msg .= ' (Did you enable the php_fileinfo extension?)';
            }
            throw new \LogicException($msg);
        }

        foreach ($this->guessers as $guesser) {
            if (null !== $mimeType = $guesser->guess($path)) {
                return $mimeType;
            }
        }
    }
}
PKϤ$Z�b�o����:http-foundation/File/MimeType/MimeTypeExtensionGuesser.phpnu�[���<?php

/*
 * This file is part of the Symfony package.
 *
 * (c) Fabien Potencier <fabien@symfony.com>
 *
 * For the full copyright and license information, please view the LICENSE
 * file that was distributed with this source code.
 */

namespace Symfony\Component\HttpFoundation\File\MimeType;

/**
 * Provides a best-guess mapping of mime type to file extension.
 */
class MimeTypeExtensionGuesser implements ExtensionGuesserInterface
{
    /**
     * A map of mime types and their default extensions.
     *
     * This list has been placed under the public domain by the Apache HTTPD project.
     * This list has been updated from upstream on 2013-04-23.
     *
     * @see http://svn.apache.org/repos/asf/httpd/httpd/trunk/docs/conf/mime.types
     *
     * @var array
     */
    protected $defaultExtensions = array(
        'application/andrew-inset' => 'ez',
        'application/applixware' => 'aw',
        'application/atom+xml' => 'atom',
        'application/atomcat+xml' => 'atomcat',
        'application/atomsvc+xml' => 'atomsvc',
        'application/ccxml+xml' => 'ccxml',
        'application/cdmi-capability' => 'cdmia',
        'application/cdmi-container' => 'cdmic',
        'application/cdmi-domain' => 'cdmid',
        'application/cdmi-object' => 'cdmio',
        'application/cdmi-queue' => 'cdmiq',
        'application/cu-seeme' => 'cu',
        'application/davmount+xml' => 'davmount',
        'application/docbook+xml' => 'dbk',
        'application/dssc+der' => 'dssc',
        'application/dssc+xml' => 'xdssc',
        'application/ecmascript' => 'ecma',
        'application/emma+xml' => 'emma',
        'application/epub+zip' => 'epub',
        'application/exi' => 'exi',
        'application/font-tdpfr' => 'pfr',
        'application/gml+xml' => 'gml',
        'application/gpx+xml' => 'gpx',
        'application/gxf' => 'gxf',
        'application/hyperstudio' => 'stk',
        'application/inkml+xml' => 'ink',
        'application/ipfix' => 'ipfix',
        'application/java-archive' => 'jar',
        'application/java-serialized-object' => 'ser',
        'application/java-vm' => 'class',
        'application/javascript' => 'js',
        'application/json' => 'json',
        'application/jsonml+json' => 'jsonml',
        'application/lost+xml' => 'lostxml',
        'application/mac-binhex40' => 'hqx',
        'application/mac-compactpro' => 'cpt',
        'application/mads+xml' => 'mads',
        'application/marc' => 'mrc',
        'application/marcxml+xml' => 'mrcx',
        'application/mathematica' => 'ma',
        'application/mathml+xml' => 'mathml',
        'application/mbox' => 'mbox',
        'application/mediaservercontrol+xml' => 'mscml',
        'application/metalink+xml' => 'metalink',
        'application/metalink4+xml' => 'meta4',
        'application/mets+xml' => 'mets',
        'application/mods+xml' => 'mods',
        'application/mp21' => 'm21',
        'application/mp4' => 'mp4s',
        'application/msword' => 'doc',
        'application/mxf' => 'mxf',
        'application/octet-stream' => 'bin',
        'application/oda' => 'oda',
        'application/oebps-package+xml' => 'opf',
        'application/ogg' => 'ogx',
        'application/omdoc+xml' => 'omdoc',
        'application/onenote' => 'onetoc',
        'application/oxps' => 'oxps',
        'application/patch-ops-error+xml' => 'xer',
        'application/pdf' => 'pdf',
        'application/pgp-encrypted' => 'pgp',
        'application/pgp-signature' => 'asc',
        'application/pics-rules' => 'prf',
        'application/pkcs10' => 'p10',
        'application/pkcs7-mime' => 'p7m',
        'application/pkcs7-signature' => 'p7s',
        'application/pkcs8' => 'p8',
        'application/pkix-attr-cert' => 'ac',
        'application/pkix-cert' => 'cer',
        'application/pkix-crl' => 'crl',
        'application/pkix-pkipath' => 'pkipath',
        'application/pkixcmp' => 'pki',
        'application/pls+xml' => 'pls',
        'application/postscript' => 'ai',
        'application/prs.cww' => 'cww',
        'application/pskc+xml' => 'pskcxml',
        'application/rdf+xml' => 'rdf',
        'application/reginfo+xml' => 'rif',
        'application/relax-ng-compact-syntax' => 'rnc',
        'application/resource-lists+xml' => 'rl',
        'application/resource-lists-diff+xml' => 'rld',
        'application/rls-services+xml' => 'rs',
        'application/rpki-ghostbusters' => 'gbr',
        'application/rpki-manifest' => 'mft',
        'application/rpki-roa' => 'roa',
        'application/rsd+xml' => 'rsd',
        'application/rss+xml' => 'rss',
        'application/rtf' => 'rtf',
        'application/sbml+xml' => 'sbml',
        'application/scvp-cv-request' => 'scq',
        'application/scvp-cv-response' => 'scs',
        'application/scvp-vp-request' => 'spq',
        'application/scvp-vp-response' => 'spp',
        'application/sdp' => 'sdp',
        'application/set-payment-initiation' => 'setpay',
        'application/set-registration-initiation' => 'setreg',
        'application/shf+xml' => 'shf',
        'application/smil+xml' => 'smi',
        'application/sparql-query' => 'rq',
        'application/sparql-results+xml' => 'srx',
        'application/srgs' => 'gram',
        'application/srgs+xml' => 'grxml',
        'application/sru+xml' => 'sru',
        'application/ssdl+xml' => 'ssdl',
        'application/ssml+xml' => 'ssml',
        'application/tei+xml' => 'tei',
        'application/thraud+xml' => 'tfi',
        'application/timestamped-data' => 'tsd',
        'application/vnd.3gpp.pic-bw-large' => 'plb',
        'application/vnd.3gpp.pic-bw-small' => 'psb',
        'application/vnd.3gpp.pic-bw-var' => 'pvb',
        'application/vnd.3gpp2.tcap' => 'tcap',
        'application/vnd.3m.post-it-notes' => 'pwn',
        'application/vnd.accpac.simply.aso' => 'aso',
        'application/vnd.accpac.simply.imp' => 'imp',
        'application/vnd.acucobol' => 'acu',
        'application/vnd.acucorp' => 'atc',
        'application/vnd.adobe.air-application-installer-package+zip' => 'air',
        'application/vnd.adobe.formscentral.fcdt' => 'fcdt',
        'application/vnd.adobe.fxp' => 'fxp',
        'application/vnd.adobe.xdp+xml' => 'xdp',
        'application/vnd.adobe.xfdf' => 'xfdf',
        'application/vnd.ahead.space' => 'ahead',
        'application/vnd.airzip.filesecure.azf' => 'azf',
        'application/vnd.airzip.filesecure.azs' => 'azs',
        'application/vnd.amazon.ebook' => 'azw',
        'application/vnd.americandynamics.acc' => 'acc',
        'application/vnd.amiga.ami' => 'ami',
        'application/vnd.android.package-archive' => 'apk',
        'application/vnd.anser-web-certificate-issue-initiation' => 'cii',
        'application/vnd.anser-web-funds-transfer-initiation' => 'fti',
        'application/vnd.antix.game-component' => 'atx',
        'application/vnd.apple.installer+xml' => 'mpkg',
        'application/vnd.apple.mpegurl' => 'm3u8',
        'application/vnd.aristanetworks.swi' => 'swi',
        'application/vnd.astraea-software.iota' => 'iota',
        'application/vnd.audiograph' => 'aep',
        'application/vnd.blueice.multipass' => 'mpm',
        'application/vnd.bmi' => 'bmi',
        'application/vnd.businessobjects' => 'rep',
        'application/vnd.chemdraw+xml' => 'cdxml',
        'application/vnd.chipnuts.karaoke-mmd' => 'mmd',
        'application/vnd.cinderella' => 'cdy',
        'application/vnd.claymore' => 'cla',
        'application/vnd.cloanto.rp9' => 'rp9',
        'application/vnd.clonk.c4group' => 'c4g',
        'application/vnd.cluetrust.cartomobile-config' => 'c11amc',
        'application/vnd.cluetrust.cartomobile-config-pkg' => 'c11amz',
        'application/vnd.commonspace' => 'csp',
        'application/vnd.contact.cmsg' => 'cdbcmsg',
        'application/vnd.cosmocaller' => 'cmc',
        'application/vnd.crick.clicker' => 'clkx',
        'application/vnd.crick.clicker.keyboard' => 'clkk',
        'application/vnd.crick.clicker.palette' => 'clkp',
        'application/vnd.crick.clicker.template' => 'clkt',
        'application/vnd.crick.clicker.wordbank' => 'clkw',
        'application/vnd.criticaltools.wbs+xml' => 'wbs',
        'application/vnd.ctc-posml' => 'pml',
        'application/vnd.cups-ppd' => 'ppd',
        'application/vnd.curl.car' => 'car',
        'application/vnd.curl.pcurl' => 'pcurl',
        'application/vnd.dart' => 'dart',
        'application/vnd.data-vision.rdz' => 'rdz',
        'application/vnd.dece.data' => 'uvf',
        'application/vnd.dece.ttml+xml' => 'uvt',
        'application/vnd.dece.unspecified' => 'uvx',
        'application/vnd.dece.zip' => 'uvz',
        'application/vnd.denovo.fcselayout-link' => 'fe_launch',
        'application/vnd.dna' => 'dna',
        'application/vnd.dolby.mlp' => 'mlp',
        'application/vnd.dpgraph' => 'dpg',
        'application/vnd.dreamfactory' => 'dfac',
        'application/vnd.ds-keypoint' => 'kpxx',
        'application/vnd.dvb.ait' => 'ait',
        'application/vnd.dvb.service' => 'svc',
        'application/vnd.dynageo' => 'geo',
        'application/vnd.ecowin.chart' => 'mag',
        'application/vnd.enliven' => 'nml',
        'application/vnd.epson.esf' => 'esf',
        'application/vnd.epson.msf' => 'msf',
        'application/vnd.epson.quickanime' => 'qam',
        'application/vnd.epson.salt' => 'slt',
        'application/vnd.epson.ssf' => 'ssf',
        'application/vnd.eszigno3+xml' => 'es3',
        'application/vnd.ezpix-album' => 'ez2',
        'application/vnd.ezpix-package' => 'ez3',
        'application/vnd.fdf' => 'fdf',
        'application/vnd.fdsn.mseed' => 'mseed',
        'application/vnd.fdsn.seed' => 'seed',
        'application/vnd.flographit' => 'gph',
        'application/vnd.fluxtime.clip' => 'ftc',
        'application/vnd.framemaker' => 'fm',
        'application/vnd.frogans.fnc' => 'fnc',
        'application/vnd.frogans.ltf' => 'ltf',
        'application/vnd.fsc.weblaunch' => 'fsc',
        'application/vnd.fujitsu.oasys' => 'oas',
        'application/vnd.fujitsu.oasys2' => 'oa2',
        'application/vnd.fujitsu.oasys3' => 'oa3',
        'application/vnd.fujitsu.oasysgp' => 'fg5',
        'application/vnd.fujitsu.oasysprs' => 'bh2',
        'application/vnd.fujixerox.ddd' => 'ddd',
        'application/vnd.fujixerox.docuworks' => 'xdw',
        'application/vnd.fujixerox.docuworks.binder' => 'xbd',
        'application/vnd.fuzzysheet' => 'fzs',
        'application/vnd.genomatix.tuxedo' => 'txd',
        'application/vnd.geogebra.file' => 'ggb',
        'application/vnd.geogebra.tool' => 'ggt',
        'application/vnd.geometry-explorer' => 'gex',
        'application/vnd.geonext' => 'gxt',
        'application/vnd.geoplan' => 'g2w',
        'application/vnd.geospace' => 'g3w',
        'application/vnd.gmx' => 'gmx',
        'application/vnd.google-earth.kml+xml' => 'kml',
        'application/vnd.google-earth.kmz' => 'kmz',
        'application/vnd.grafeq' => 'gqf',
        'application/vnd.groove-account' => 'gac',
        'application/vnd.groove-help' => 'ghf',
        'application/vnd.groove-identity-message' => 'gim',
        'application/vnd.groove-injector' => 'grv',
        'application/vnd.groove-tool-message' => 'gtm',
        'application/vnd.groove-tool-template' => 'tpl',
        'application/vnd.groove-vcard' => 'vcg',
        'application/vnd.hal+xml' => 'hal',
        'application/vnd.handheld-entertainment+xml' => 'zmm',
        'application/vnd.hbci' => 'hbci',
        'application/vnd.hhe.lesson-player' => 'les',
        'application/vnd.hp-hpgl' => 'hpgl',
        'application/vnd.hp-hpid' => 'hpid',
        'application/vnd.hp-hps' => 'hps',
        'application/vnd.hp-jlyt' => 'jlt',
        'application/vnd.hp-pcl' => 'pcl',
        'application/vnd.hp-pclxl' => 'pclxl',
        'application/vnd.hydrostatix.sof-data' => 'sfd-hdstx',
        'application/vnd.ibm.minipay' => 'mpy',
        'application/vnd.ibm.modcap' => 'afp',
        'application/vnd.ibm.rights-management' => 'irm',
        'application/vnd.ibm.secure-container' => 'sc',
        'application/vnd.iccprofile' => 'icc',
        'application/vnd.igloader' => 'igl',
        'application/vnd.immervision-ivp' => 'ivp',
        'application/vnd.immervision-ivu' => 'ivu',
        'application/vnd.insors.igm' => 'igm',
        'application/vnd.intercon.formnet' => 'xpw',
        'application/vnd.intergeo' => 'i2g',
        'application/vnd.intu.qbo' => 'qbo',
        'application/vnd.intu.qfx' => 'qfx',
        'application/vnd.ipunplugged.rcprofile' => 'rcprofile',
        'application/vnd.irepository.package+xml' => 'irp',
        'application/vnd.is-xpr' => 'xpr',
        'application/vnd.isac.fcs' => 'fcs',
        'application/vnd.jam' => 'jam',
        'application/vnd.jcp.javame.midlet-rms' => 'rms',
        'application/vnd.jisp' => 'jisp',
        'application/vnd.joost.joda-archive' => 'joda',
        'application/vnd.kahootz' => 'ktz',
        'application/vnd.kde.karbon' => 'karbon',
        'application/vnd.kde.kchart' => 'chrt',
        'application/vnd.kde.kformula' => 'kfo',
        'application/vnd.kde.kivio' => 'flw',
        'application/vnd.kde.kontour' => 'kon',
        'application/vnd.kde.kpresenter' => 'kpr',
        'application/vnd.kde.kspread' => 'ksp',
        'application/vnd.kde.kword' => 'kwd',
        'application/vnd.kenameaapp' => 'htke',
        'application/vnd.kidspiration' => 'kia',
        'application/vnd.kinar' => 'kne',
        'application/vnd.koan' => 'skp',
        'application/vnd.kodak-descriptor' => 'sse',
        'application/vnd.las.las+xml' => 'lasxml',
        'application/vnd.llamagraphics.life-balance.desktop' => 'lbd',
        'application/vnd.llamagraphics.life-balance.exchange+xml' => 'lbe',
        'application/vnd.lotus-1-2-3' => '123',
        'application/vnd.lotus-approach' => 'apr',
        'application/vnd.lotus-freelance' => 'pre',
        'application/vnd.lotus-notes' => 'nsf',
        'application/vnd.lotus-organizer' => 'org',
        'application/vnd.lotus-screencam' => 'scm',
        'application/vnd.lotus-wordpro' => 'lwp',
        'application/vnd.macports.portpkg' => 'portpkg',
        'application/vnd.mcd' => 'mcd',
        'application/vnd.medcalcdata' => 'mc1',
        'application/vnd.mediastation.cdkey' => 'cdkey',
        'application/vnd.mfer' => 'mwf',
        'application/vnd.mfmp' => 'mfm',
        'application/vnd.micrografx.flo' => 'flo',
        'application/vnd.micrografx.igx' => 'igx',
        'application/vnd.mif' => 'mif',
        'application/vnd.mobius.daf' => 'daf',
        'application/vnd.mobius.dis' => 'dis',
        'application/vnd.mobius.mbk' => 'mbk',
        'application/vnd.mobius.mqy' => 'mqy',
        'application/vnd.mobius.msl' => 'msl',
        'application/vnd.mobius.plc' => 'plc',
        'application/vnd.mobius.txf' => 'txf',
        'application/vnd.mophun.application' => 'mpn',
        'application/vnd.mophun.certificate' => 'mpc',
        'application/vnd.mozilla.xul+xml' => 'xul',
        'application/vnd.ms-artgalry' => 'cil',
        'application/vnd.ms-cab-compressed' => 'cab',
        'application/vnd.ms-excel' => 'xls',
        'application/vnd.ms-excel.addin.macroenabled.12' => 'xlam',
        'application/vnd.ms-excel.sheet.binary.macroenabled.12' => 'xlsb',
        'application/vnd.ms-excel.sheet.macroenabled.12' => 'xlsm',
        'application/vnd.ms-excel.template.macroenabled.12' => 'xltm',
        'application/vnd.ms-fontobject' => 'eot',
        'application/vnd.ms-htmlhelp' => 'chm',
        'application/vnd.ms-ims' => 'ims',
        'application/vnd.ms-lrm' => 'lrm',
        'application/vnd.ms-officetheme' => 'thmx',
        'application/vnd.ms-pki.seccat' => 'cat',
        'application/vnd.ms-pki.stl' => 'stl',
        'application/vnd.ms-powerpoint' => 'ppt',
        'application/vnd.ms-powerpoint.addin.macroenabled.12' => 'ppam',
        'application/vnd.ms-powerpoint.presentation.macroenabled.12' => 'pptm',
        'application/vnd.ms-powerpoint.slide.macroenabled.12' => 'sldm',
        'application/vnd.ms-powerpoint.slideshow.macroenabled.12' => 'ppsm',
        'application/vnd.ms-powerpoint.template.macroenabled.12' => 'potm',
        'application/vnd.ms-project' => 'mpp',
        'application/vnd.ms-word.document.macroenabled.12' => 'docm',
        'application/vnd.ms-word.template.macroenabled.12' => 'dotm',
        'application/vnd.ms-works' => 'wps',
        'application/vnd.ms-wpl' => 'wpl',
        'application/vnd.ms-xpsdocument' => 'xps',
        'application/vnd.mseq' => 'mseq',
        'application/vnd.musician' => 'mus',
        'application/vnd.muvee.style' => 'msty',
        'application/vnd.mynfc' => 'taglet',
        'application/vnd.neurolanguage.nlu' => 'nlu',
        'application/vnd.nitf' => 'ntf',
        'application/vnd.noblenet-directory' => 'nnd',
        'application/vnd.noblenet-sealer' => 'nns',
        'application/vnd.noblenet-web' => 'nnw',
        'application/vnd.nokia.n-gage.data' => 'ngdat',
        'application/vnd.nokia.n-gage.symbian.install' => 'n-gage',
        'application/vnd.nokia.radio-preset' => 'rpst',
        'application/vnd.nokia.radio-presets' => 'rpss',
        'application/vnd.novadigm.edm' => 'edm',
        'application/vnd.novadigm.edx' => 'edx',
        'application/vnd.novadigm.ext' => 'ext',
        'application/vnd.oasis.opendocument.chart' => 'odc',
        'application/vnd.oasis.opendocument.chart-template' => 'otc',
        'application/vnd.oasis.opendocument.database' => 'odb',
        'application/vnd.oasis.opendocument.formula' => 'odf',
        'application/vnd.oasis.opendocument.formula-template' => 'odft',
        'application/vnd.oasis.opendocument.graphics' => 'odg',
        'application/vnd.oasis.opendocument.graphics-template' => 'otg',
        'application/vnd.oasis.opendocument.image' => 'odi',
        'application/vnd.oasis.opendocument.image-template' => 'oti',
        'application/vnd.oasis.opendocument.presentation' => 'odp',
        'application/vnd.oasis.opendocument.presentation-template' => 'otp',
        'application/vnd.oasis.opendocument.spreadsheet' => 'ods',
        'application/vnd.oasis.opendocument.spreadsheet-template' => 'ots',
        'application/vnd.oasis.opendocument.text' => 'odt',
        'application/vnd.oasis.opendocument.text-master' => 'odm',
        'application/vnd.oasis.opendocument.text-template' => 'ott',
        'application/vnd.oasis.opendocument.text-web' => 'oth',
        'application/vnd.olpc-sugar' => 'xo',
        'application/vnd.oma.dd2+xml' => 'dd2',
        'application/vnd.openofficeorg.extension' => 'oxt',
        'application/vnd.openxmlformats-officedocument.presentationml.presentation' => 'pptx',
        'application/vnd.openxmlformats-officedocument.presentationml.slide' => 'sldx',
        'application/vnd.openxmlformats-officedocument.presentationml.slideshow' => 'ppsx',
        'application/vnd.openxmlformats-officedocument.presentationml.template' => 'potx',
        'application/vnd.openxmlformats-officedocument.spreadsheetml.sheet' => 'xlsx',
        'application/vnd.openxmlformats-officedocument.spreadsheetml.template' => 'xltx',
        'application/vnd.openxmlformats-officedocument.wordprocessingml.document' => 'docx',
        'application/vnd.openxmlformats-officedocument.wordprocessingml.template' => 'dotx',
        'application/vnd.osgeo.mapguide.package' => 'mgp',
        'application/vnd.osgi.dp' => 'dp',
        'application/vnd.osgi.subsystem' => 'esa',
        'application/vnd.palm' => 'pdb',
        'application/vnd.pawaafile' => 'paw',
        'application/vnd.pg.format' => 'str',
        'application/vnd.pg.osasli' => 'ei6',
        'application/vnd.picsel' => 'efif',
        'application/vnd.pmi.widget' => 'wg',
        'application/vnd.pocketlearn' => 'plf',
        'application/vnd.powerbuilder6' => 'pbd',
        'application/vnd.previewsystems.box' => 'box',
        'application/vnd.proteus.magazine' => 'mgz',
        'application/vnd.publishare-delta-tree' => 'qps',
        'application/vnd.pvi.ptid1' => 'ptid',
        'application/vnd.quark.quarkxpress' => 'qxd',
        'application/vnd.realvnc.bed' => 'bed',
        'application/vnd.recordare.musicxml' => 'mxl',
        'application/vnd.recordare.musicxml+xml' => 'musicxml',
        'application/vnd.rig.cryptonote' => 'cryptonote',
        'application/vnd.rim.cod' => 'cod',
        'application/vnd.rn-realmedia' => 'rm',
        'application/vnd.rn-realmedia-vbr' => 'rmvb',
        'application/vnd.route66.link66+xml' => 'link66',
        'application/vnd.sailingtracker.track' => 'st',
        'application/vnd.seemail' => 'see',
        'application/vnd.sema' => 'sema',
        'application/vnd.semd' => 'semd',
        'application/vnd.semf' => 'semf',
        'application/vnd.shana.informed.formdata' => 'ifm',
        'application/vnd.shana.informed.formtemplate' => 'itp',
        'application/vnd.shana.informed.interchange' => 'iif',
        'application/vnd.shana.informed.package' => 'ipk',
        'application/vnd.simtech-mindmapper' => 'twd',
        'application/vnd.smaf' => 'mmf',
        'application/vnd.smart.teacher' => 'teacher',
        'application/vnd.solent.sdkm+xml' => 'sdkm',
        'application/vnd.spotfire.dxp' => 'dxp',
        'application/vnd.spotfire.sfs' => 'sfs',
        'application/vnd.stardivision.calc' => 'sdc',
        'application/vnd.stardivision.draw' => 'sda',
        'application/vnd.stardivision.impress' => 'sdd',
        'application/vnd.stardivision.math' => 'smf',
        'application/vnd.stardivision.writer' => 'sdw',
        'application/vnd.stardivision.writer-global' => 'sgl',
        'application/vnd.stepmania.package' => 'smzip',
        'application/vnd.stepmania.stepchart' => 'sm',
        'application/vnd.sun.xml.calc' => 'sxc',
        'application/vnd.sun.xml.calc.template' => 'stc',
        'application/vnd.sun.xml.draw' => 'sxd',
        'application/vnd.sun.xml.draw.template' => 'std',
        'application/vnd.sun.xml.impress' => 'sxi',
        'application/vnd.sun.xml.impress.template' => 'sti',
        'application/vnd.sun.xml.math' => 'sxm',
        'application/vnd.sun.xml.writer' => 'sxw',
        'application/vnd.sun.xml.writer.global' => 'sxg',
        'application/vnd.sun.xml.writer.template' => 'stw',
        'application/vnd.sus-calendar' => 'sus',
        'application/vnd.svd' => 'svd',
        'application/vnd.symbian.install' => 'sis',
        'application/vnd.syncml+xml' => 'xsm',
        'application/vnd.syncml.dm+wbxml' => 'bdm',
        'application/vnd.syncml.dm+xml' => 'xdm',
        'application/vnd.tao.intent-module-archive' => 'tao',
        'application/vnd.tcpdump.pcap' => 'pcap',
        'application/vnd.tmobile-livetv' => 'tmo',
        'application/vnd.trid.tpt' => 'tpt',
        'application/vnd.triscape.mxs' => 'mxs',
        'application/vnd.trueapp' => 'tra',
        'application/vnd.ufdl' => 'ufd',
        'application/vnd.uiq.theme' => 'utz',
        'application/vnd.umajin' => 'umj',
        'application/vnd.unity' => 'unityweb',
        'application/vnd.uoml+xml' => 'uoml',
        'application/vnd.vcx' => 'vcx',
        'application/vnd.visio' => 'vsd',
        'application/vnd.visionary' => 'vis',
        'application/vnd.vsf' => 'vsf',
        'application/vnd.wap.wbxml' => 'wbxml',
        'application/vnd.wap.wmlc' => 'wmlc',
        'application/vnd.wap.wmlscriptc' => 'wmlsc',
        'application/vnd.webturbo' => 'wtb',
        'application/vnd.wolfram.player' => 'nbp',
        'application/vnd.wordperfect' => 'wpd',
        'application/vnd.wqd' => 'wqd',
        'application/vnd.wt.stf' => 'stf',
        'application/vnd.xara' => 'xar',
        'application/vnd.xfdl' => 'xfdl',
        'application/vnd.yamaha.hv-dic' => 'hvd',
        'application/vnd.yamaha.hv-script' => 'hvs',
        'application/vnd.yamaha.hv-voice' => 'hvp',
        'application/vnd.yamaha.openscoreformat' => 'osf',
        'application/vnd.yamaha.openscoreformat.osfpvg+xml' => 'osfpvg',
        'application/vnd.yamaha.smaf-audio' => 'saf',
        'application/vnd.yamaha.smaf-phrase' => 'spf',
        'application/vnd.yellowriver-custom-menu' => 'cmp',
        'application/vnd.zul' => 'zir',
        'application/vnd.zzazz.deck+xml' => 'zaz',
        'application/voicexml+xml' => 'vxml',
        'application/widget' => 'wgt',
        'application/winhlp' => 'hlp',
        'application/wsdl+xml' => 'wsdl',
        'application/wspolicy+xml' => 'wspolicy',
        'application/x-7z-compressed' => '7z',
        'application/x-abiword' => 'abw',
        'application/x-ace-compressed' => 'ace',
        'application/x-apple-diskimage' => 'dmg',
        'application/x-authorware-bin' => 'aab',
        'application/x-authorware-map' => 'aam',
        'application/x-authorware-seg' => 'aas',
        'application/x-bcpio' => 'bcpio',
        'application/x-bittorrent' => 'torrent',
        'application/x-blorb' => 'blb',
        'application/x-bzip' => 'bz',
        'application/x-bzip2' => 'bz2',
        'application/x-cbr' => 'cbr',
        'application/x-cdlink' => 'vcd',
        'application/x-cfs-compressed' => 'cfs',
        'application/x-chat' => 'chat',
        'application/x-chess-pgn' => 'pgn',
        'application/x-conference' => 'nsc',
        'application/x-cpio' => 'cpio',
        'application/x-csh' => 'csh',
        'application/x-debian-package' => 'deb',
        'application/x-dgc-compressed' => 'dgc',
        'application/x-director' => 'dir',
        'application/x-doom' => 'wad',
        'application/x-dtbncx+xml' => 'ncx',
        'application/x-dtbook+xml' => 'dtb',
        'application/x-dtbresource+xml' => 'res',
        'application/x-dvi' => 'dvi',
        'application/x-envoy' => 'evy',
        'application/x-eva' => 'eva',
        'application/x-font-bdf' => 'bdf',
        'application/x-font-ghostscript' => 'gsf',
        'application/x-font-linux-psf' => 'psf',
        'application/x-font-otf' => 'otf',
        'application/x-font-pcf' => 'pcf',
        'application/x-font-snf' => 'snf',
        'application/x-font-ttf' => 'ttf',
        'application/x-font-type1' => 'pfa',
        'application/x-font-woff' => 'woff',
        'application/x-freearc' => 'arc',
        'application/x-futuresplash' => 'spl',
        'application/x-gca-compressed' => 'gca',
        'application/x-glulx' => 'ulx',
        'application/x-gnumeric' => 'gnumeric',
        'application/x-gramps-xml' => 'gramps',
        'application/x-gtar' => 'gtar',
        'application/x-hdf' => 'hdf',
        'application/x-install-instructions' => 'install',
        'application/x-iso9660-image' => 'iso',
        'application/x-java-jnlp-file' => 'jnlp',
        'application/x-latex' => 'latex',
        'application/x-lzh-compressed' => 'lzh',
        'application/x-mie' => 'mie',
        'application/x-mobipocket-ebook' => 'prc',
        'application/x-ms-application' => 'application',
        'application/x-ms-shortcut' => 'lnk',
        'application/x-ms-wmd' => 'wmd',
        'application/x-ms-wmz' => 'wmz',
        'application/x-ms-xbap' => 'xbap',
        'application/x-msaccess' => 'mdb',
        'application/x-msbinder' => 'obd',
        'application/x-mscardfile' => 'crd',
        'application/x-msclip' => 'clp',
        'application/x-msdownload' => 'exe',
        'application/x-msmediaview' => 'mvb',
        'application/x-msmetafile' => 'wmf',
        'application/x-msmoney' => 'mny',
        'application/x-mspublisher' => 'pub',
        'application/x-msschedule' => 'scd',
        'application/x-msterminal' => 'trm',
        'application/x-mswrite' => 'wri',
        'application/x-netcdf' => 'nc',
        'application/x-nzb' => 'nzb',
        'application/x-pkcs12' => 'p12',
        'application/x-pkcs7-certificates' => 'p7b',
        'application/x-pkcs7-certreqresp' => 'p7r',
        'application/x-rar-compressed' => 'rar',
        'application/x-rar' => 'rar',
        'application/x-research-info-systems' => 'ris',
        'application/x-sh' => 'sh',
        'application/x-shar' => 'shar',
        'application/x-shockwave-flash' => 'swf',
        'application/x-silverlight-app' => 'xap',
        'application/x-sql' => 'sql',
        'application/x-stuffit' => 'sit',
        'application/x-stuffitx' => 'sitx',
        'application/x-subrip' => 'srt',
        'application/x-sv4cpio' => 'sv4cpio',
        'application/x-sv4crc' => 'sv4crc',
        'application/x-t3vm-image' => 't3',
        'application/x-tads' => 'gam',
        'application/x-tar' => 'tar',
        'application/x-tcl' => 'tcl',
        'application/x-tex' => 'tex',
        'application/x-tex-tfm' => 'tfm',
        'application/x-texinfo' => 'texinfo',
        'application/x-tgif' => 'obj',
        'application/x-ustar' => 'ustar',
        'application/x-wais-source' => 'src',
        'application/x-x509-ca-cert' => 'der',
        'application/x-xfig' => 'fig',
        'application/x-xliff+xml' => 'xlf',
        'application/x-xpinstall' => 'xpi',
        'application/x-xz' => 'xz',
        'application/x-zmachine' => 'z1',
        'application/xaml+xml' => 'xaml',
        'application/xcap-diff+xml' => 'xdf',
        'application/xenc+xml' => 'xenc',
        'application/xhtml+xml' => 'xhtml',
        'application/xml' => 'xml',
        'application/xml-dtd' => 'dtd',
        'application/xop+xml' => 'xop',
        'application/xproc+xml' => 'xpl',
        'application/xslt+xml' => 'xslt',
        'application/xspf+xml' => 'xspf',
        'application/xv+xml' => 'mxml',
        'application/yang' => 'yang',
        'application/yin+xml' => 'yin',
        'application/zip' => 'zip',
        'audio/adpcm' => 'adp',
        'audio/basic' => 'au',
        'audio/midi' => 'mid',
        'audio/mp4' => 'mp4a',
        'audio/mpeg' => 'mpga',
        'audio/ogg' => 'oga',
        'audio/s3m' => 's3m',
        'audio/silk' => 'sil',
        'audio/vnd.dece.audio' => 'uva',
        'audio/vnd.digital-winds' => 'eol',
        'audio/vnd.dra' => 'dra',
        'audio/vnd.dts' => 'dts',
        'audio/vnd.dts.hd' => 'dtshd',
        'audio/vnd.lucent.voice' => 'lvp',
        'audio/vnd.ms-playready.media.pya' => 'pya',
        'audio/vnd.nuera.ecelp4800' => 'ecelp4800',
        'audio/vnd.nuera.ecelp7470' => 'ecelp7470',
        'audio/vnd.nuera.ecelp9600' => 'ecelp9600',
        'audio/vnd.rip' => 'rip',
        'audio/webm' => 'weba',
        'audio/x-aac' => 'aac',
        'audio/x-aiff' => 'aif',
        'audio/x-caf' => 'caf',
        'audio/x-flac' => 'flac',
        'audio/x-matroska' => 'mka',
        'audio/x-mpegurl' => 'm3u',
        'audio/x-ms-wax' => 'wax',
        'audio/x-ms-wma' => 'wma',
        'audio/x-pn-realaudio' => 'ram',
        'audio/x-pn-realaudio-plugin' => 'rmp',
        'audio/x-wav' => 'wav',
        'audio/xm' => 'xm',
        'chemical/x-cdx' => 'cdx',
        'chemical/x-cif' => 'cif',
        'chemical/x-cmdf' => 'cmdf',
        'chemical/x-cml' => 'cml',
        'chemical/x-csml' => 'csml',
        'chemical/x-xyz' => 'xyz',
        'image/bmp' => 'bmp',
        'image/x-ms-bmp' => 'bmp',
        'image/cgm' => 'cgm',
        'image/g3fax' => 'g3',
        'image/gif' => 'gif',
        'image/ief' => 'ief',
        'image/jpeg' => 'jpeg',
        'image/ktx' => 'ktx',
        'image/png' => 'png',
        'image/prs.btif' => 'btif',
        'image/sgi' => 'sgi',
        'image/svg+xml' => 'svg',
        'image/tiff' => 'tiff',
        'image/vnd.adobe.photoshop' => 'psd',
        'image/vnd.dece.graphic' => 'uvi',
        'image/vnd.dvb.subtitle' => 'sub',
        'image/vnd.djvu' => 'djvu',
        'image/vnd.dwg' => 'dwg',
        'image/vnd.dxf' => 'dxf',
        'image/vnd.fastbidsheet' => 'fbs',
        'image/vnd.fpx' => 'fpx',
        'image/vnd.fst' => 'fst',
        'image/vnd.fujixerox.edmics-mmr' => 'mmr',
        'image/vnd.fujixerox.edmics-rlc' => 'rlc',
        'image/vnd.ms-modi' => 'mdi',
        'image/vnd.ms-photo' => 'wdp',
        'image/vnd.net-fpx' => 'npx',
        'image/vnd.wap.wbmp' => 'wbmp',
        'image/vnd.xiff' => 'xif',
        'image/webp' => 'webp',
        'image/x-3ds' => '3ds',
        'image/x-cmu-raster' => 'ras',
        'image/x-cmx' => 'cmx',
        'image/x-freehand' => 'fh',
        'image/x-icon' => 'ico',
        'image/x-mrsid-image' => 'sid',
        'image/x-pcx' => 'pcx',
        'image/x-pict' => 'pic',
        'image/x-portable-anymap' => 'pnm',
        'image/x-portable-bitmap' => 'pbm',
        'image/x-portable-graymap' => 'pgm',
        'image/x-portable-pixmap' => 'ppm',
        'image/x-rgb' => 'rgb',
        'image/x-tga' => 'tga',
        'image/x-xbitmap' => 'xbm',
        'image/x-xpixmap' => 'xpm',
        'image/x-xwindowdump' => 'xwd',
        'message/rfc822' => 'eml',
        'model/iges' => 'igs',
        'model/mesh' => 'msh',
        'model/vnd.collada+xml' => 'dae',
        'model/vnd.dwf' => 'dwf',
        'model/vnd.gdl' => 'gdl',
        'model/vnd.gtw' => 'gtw',
        'model/vnd.mts' => 'mts',
        'model/vnd.vtu' => 'vtu',
        'model/vrml' => 'wrl',
        'model/x3d+binary' => 'x3db',
        'model/x3d+vrml' => 'x3dv',
        'model/x3d+xml' => 'x3d',
        'text/cache-manifest' => 'appcache',
        'text/calendar' => 'ics',
        'text/css' => 'css',
        'text/csv' => 'csv',
        'text/html' => 'html',
        'text/n3' => 'n3',
        'text/plain' => 'txt',
        'text/prs.lines.tag' => 'dsc',
        'text/richtext' => 'rtx',
        'text/rtf' => 'rtf',
        'text/sgml' => 'sgml',
        'text/tab-separated-values' => 'tsv',
        'text/troff' => 't',
        'text/turtle' => 'ttl',
        'text/uri-list' => 'uri',
        'text/vcard' => 'vcard',
        'text/vnd.curl' => 'curl',
        'text/vnd.curl.dcurl' => 'dcurl',
        'text/vnd.curl.scurl' => 'scurl',
        'text/vnd.curl.mcurl' => 'mcurl',
        'text/vnd.dvb.subtitle' => 'sub',
        'text/vnd.fly' => 'fly',
        'text/vnd.fmi.flexstor' => 'flx',
        'text/vnd.graphviz' => 'gv',
        'text/vnd.in3d.3dml' => '3dml',
        'text/vnd.in3d.spot' => 'spot',
        'text/vnd.sun.j2me.app-descriptor' => 'jad',
        'text/vnd.wap.wml' => 'wml',
        'text/vnd.wap.wmlscript' => 'wmls',
        'text/x-asm' => 's',
        'text/x-c' => 'c',
        'text/x-fortran' => 'f',
        'text/x-pascal' => 'p',
        'text/x-java-source' => 'java',
        'text/x-opml' => 'opml',
        'text/x-nfo' => 'nfo',
        'text/x-setext' => 'etx',
        'text/x-sfv' => 'sfv',
        'text/x-uuencode' => 'uu',
        'text/x-vcalendar' => 'vcs',
        'text/x-vcard' => 'vcf',
        'video/3gpp' => '3gp',
        'video/3gpp2' => '3g2',
        'video/h261' => 'h261',
        'video/h263' => 'h263',
        'video/h264' => 'h264',
        'video/jpeg' => 'jpgv',
        'video/jpm' => 'jpm',
        'video/mj2' => 'mj2',
        'video/mp4' => 'mp4',
        'video/mpeg' => 'mpeg',
        'video/ogg' => 'ogv',
        'video/quicktime' => 'qt',
        'video/vnd.dece.hd' => 'uvh',
        'video/vnd.dece.mobile' => 'uvm',
        'video/vnd.dece.pd' => 'uvp',
        'video/vnd.dece.sd' => 'uvs',
        'video/vnd.dece.video' => 'uvv',
        'video/vnd.dvb.file' => 'dvb',
        'video/vnd.fvt' => 'fvt',
        'video/vnd.mpegurl' => 'mxu',
        'video/vnd.ms-playready.media.pyv' => 'pyv',
        'video/vnd.uvvu.mp4' => 'uvu',
        'video/vnd.vivo' => 'viv',
        'video/webm' => 'webm',
        'video/x-f4v' => 'f4v',
        'video/x-fli' => 'fli',
        'video/x-flv' => 'flv',
        'video/x-m4v' => 'm4v',
        'video/x-matroska' => 'mkv',
        'video/x-mng' => 'mng',
        'video/x-ms-asf' => 'asf',
        'video/x-ms-vob' => 'vob',
        'video/x-ms-wm' => 'wm',
        'video/x-ms-wmv' => 'wmv',
        'video/x-ms-wmx' => 'wmx',
        'video/x-ms-wvx' => 'wvx',
        'video/x-msvideo' => 'avi',
        'video/x-sgi-movie' => 'movie',
        'video/x-smv' => 'smv',
        'x-conference/x-cooltalk' => 'ice',
    );

    /**
     * {@inheritdoc}
     */
    public function guess($mimeType)
    {
        return isset($this->defaultExtensions[$mimeType]) ? $this->defaultExtensions[$mimeType] : null;
    }
}
PKϤ$Z9`;9http-foundation/File/MimeType/FileinfoMimeTypeGuesser.phpnu�[���<?php

/*
 * This file is part of the Symfony package.
 *
 * (c) Fabien Potencier <fabien@symfony.com>
 *
 * For the full copyright and license information, please view the LICENSE
 * file that was distributed with this source code.
 */

namespace Symfony\Component\HttpFoundation\File\MimeType;

use Symfony\Component\HttpFoundation\File\Exception\FileNotFoundException;
use Symfony\Component\HttpFoundation\File\Exception\AccessDeniedException;

/**
 * Guesses the mime type using the PECL extension FileInfo.
 *
 * @author Bernhard Schussek <bschussek@gmail.com>
 */
class FileinfoMimeTypeGuesser implements MimeTypeGuesserInterface
{
    private $magicFile;

    /**
     * Constructor.
     *
     * @param string $magicFile A magic file to use with the finfo instance
     *
     * @link http://www.php.net/manual/en/function.finfo-open.php
     */
    public function __construct($magicFile = null)
    {
        $this->magicFile = $magicFile;
    }

    /**
     * Returns whether this guesser is supported on the current OS/PHP setup.
     *
     * @return bool
     */
    public static function isSupported()
    {
        return function_exists('finfo_open');
    }

    /**
     * {@inheritdoc}
     */
    public function guess($path)
    {
        if (!is_file($path)) {
            throw new FileNotFoundException($path);
        }

        if (!is_readable($path)) {
            throw new AccessDeniedException($path);
        }

        if (!self::isSupported()) {
            return;
        }

        if (!$finfo = new \finfo(FILEINFO_MIME_TYPE, $this->magicFile)) {
            return;
        }

        return $finfo->file($path);
    }
}
PKϤ$Z���Ձ�;http-foundation/File/MimeType/FileBinaryMimeTypeGuesser.phpnu�[���<?php

/*
 * This file is part of the Symfony package.
 *
 * (c) Fabien Potencier <fabien@symfony.com>
 *
 * For the full copyright and license information, please view the LICENSE
 * file that was distributed with this source code.
 */

namespace Symfony\Component\HttpFoundation\File\MimeType;

use Symfony\Component\HttpFoundation\File\Exception\FileNotFoundException;
use Symfony\Component\HttpFoundation\File\Exception\AccessDeniedException;

/**
 * Guesses the mime type with the binary "file" (only available on *nix).
 *
 * @author Bernhard Schussek <bschussek@gmail.com>
 */
class FileBinaryMimeTypeGuesser implements MimeTypeGuesserInterface
{
    private $cmd;

    /**
     * Constructor.
     *
     * The $cmd pattern must contain a "%s" string that will be replaced
     * with the file name to guess.
     *
     * The command output must start with the mime type of the file.
     *
     * @param string $cmd The command to run to get the mime type of a file
     */
    public function __construct($cmd = 'file -b --mime %s 2>/dev/null')
    {
        $this->cmd = $cmd;
    }

    /**
     * Returns whether this guesser is supported on the current OS.
     *
     * @return bool
     */
    public static function isSupported()
    {
        return '\\' !== DIRECTORY_SEPARATOR && function_exists('passthru') && function_exists('escapeshellarg');
    }

    /**
     * {@inheritdoc}
     */
    public function guess($path)
    {
        if (!is_file($path)) {
            throw new FileNotFoundException($path);
        }

        if (!is_readable($path)) {
            throw new AccessDeniedException($path);
        }

        if (!self::isSupported()) {
            return;
        }

        ob_start();

        // need to use --mime instead of -i. see #6641
        passthru(sprintf($this->cmd, escapeshellarg($path)), $return);
        if ($return > 0) {
            ob_end_clean();

            return;
        }

        $type = trim(ob_get_clean());

        if (!preg_match('#^([a-z0-9\-]+/[a-z0-9\-\.]+)#i', $type, $match)) {
            // it's not a type, but an error message
            return;
        }

        return $match[1];
    }
}
PKϤ$Z n�/66http-foundation/File/Stream.phpnu�[���<?php

/*
 * This file is part of the Symfony package.
 *
 * (c) Fabien Potencier <fabien@symfony.com>
 *
 * For the full copyright and license information, please view the LICENSE
 * file that was distributed with this source code.
 */

namespace Symfony\Component\HttpFoundation\File;

/**
 * A PHP stream of unknown size.
 *
 * @author Nicolas Grekas <p@tchwork.com>
 */
class Stream extends File
{
    /**
     * {@inheritdoc}
     *
     * @return int|false
     */
    #[\ReturnTypeWillChange]
    public function getSize()
    {
        return false;
    }
}
PKϤ$Z��4��0http-foundation/File/Exception/FileException.phpnu�[���<?php

/*
 * This file is part of the Symfony package.
 *
 * (c) Fabien Potencier <fabien@symfony.com>
 *
 * For the full copyright and license information, please view the LICENSE
 * file that was distributed with this source code.
 */

namespace Symfony\Component\HttpFoundation\File\Exception;

/**
 * Thrown when an error occurred in the component File.
 *
 * @author Bernhard Schussek <bschussek@gmail.com>
 */
class FileException extends \RuntimeException
{
}
PKϤ$Z�_���2http-foundation/File/Exception/NoFileException.phpnu�[���<?php

/*
 * This file is part of the Symfony package.
 *
 * (c) Fabien Potencier <fabien@symfony.com>
 *
 * For the full copyright and license information, please view the LICENSE
 * file that was distributed with this source code.
 */

namespace Symfony\Component\HttpFoundation\File\Exception;

/**
 * Thrown when an UPLOAD_ERR_NO_FILE error occurred with UploadedFile.
 *
 * @author Florent Mata <florentmata@gmail.com>
 */
class NoFileException extends FileException
{
}
PKϤ$Z�[���2http-foundation/File/Exception/UploadException.phpnu�[���<?php

/*
 * This file is part of the Symfony package.
 *
 * (c) Fabien Potencier <fabien@symfony.com>
 *
 * For the full copyright and license information, please view the LICENSE
 * file that was distributed with this source code.
 */

namespace Symfony\Component\HttpFoundation\File\Exception;

/**
 * Thrown when an error occurred during file upload.
 *
 * @author Bernhard Schussek <bschussek@gmail.com>
 */
class UploadException extends FileException
{
}
PKϤ$Z��t���7http-foundation/File/Exception/IniSizeFileException.phpnu�[���<?php

/*
 * This file is part of the Symfony package.
 *
 * (c) Fabien Potencier <fabien@symfony.com>
 *
 * For the full copyright and license information, please view the LICENSE
 * file that was distributed with this source code.
 */

namespace Symfony\Component\HttpFoundation\File\Exception;

/**
 * Thrown when an UPLOAD_ERR_INI_SIZE error occurred with UploadedFile.
 *
 * @author Florent Mata <florentmata@gmail.com>
 */
class IniSizeFileException extends FileException
{
}
PKϤ$Z�{��##:http-foundation/File/Exception/UnexpectedTypeException.phpnu�[���<?php

/*
 * This file is part of the Symfony package.
 *
 * (c) Fabien Potencier <fabien@symfony.com>
 *
 * For the full copyright and license information, please view the LICENSE
 * file that was distributed with this source code.
 */

namespace Symfony\Component\HttpFoundation\File\Exception;

class UnexpectedTypeException extends FileException
{
    public function __construct($value, string $expectedType)
    {
        parent::__construct(sprintf('Expected argument of type %s, %s given', $expectedType, get_debug_type($value)));
    }
}
PKϤ$Z��j@��8http-foundation/File/Exception/NoTmpDirFileException.phpnu�[���<?php

/*
 * This file is part of the Symfony package.
 *
 * (c) Fabien Potencier <fabien@symfony.com>
 *
 * For the full copyright and license information, please view the LICENSE
 * file that was distributed with this source code.
 */

namespace Symfony\Component\HttpFoundation\File\Exception;

/**
 * Thrown when an UPLOAD_ERR_NO_TMP_DIR error occurred with UploadedFile.
 *
 * @author Florent Mata <florentmata@gmail.com>
 */
class NoTmpDirFileException extends FileException
{
}
PKϤ$Z����;http-foundation/File/Exception/CannotWriteFileException.phpnu�[���<?php

/*
 * This file is part of the Symfony package.
 *
 * (c) Fabien Potencier <fabien@symfony.com>
 *
 * For the full copyright and license information, please view the LICENSE
 * file that was distributed with this source code.
 */

namespace Symfony\Component\HttpFoundation\File\Exception;

/**
 * Thrown when an UPLOAD_ERR_CANT_WRITE error occurred with UploadedFile.
 *
 * @author Florent Mata <florentmata@gmail.com>
 */
class CannotWriteFileException extends FileException
{
}
PKϤ$Z�2����7http-foundation/File/Exception/PartialFileException.phpnu�[���<?php

/*
 * This file is part of the Symfony package.
 *
 * (c) Fabien Potencier <fabien@symfony.com>
 *
 * For the full copyright and license information, please view the LICENSE
 * file that was distributed with this source code.
 */

namespace Symfony\Component\HttpFoundation\File\Exception;

/**
 * Thrown when an UPLOAD_ERR_PARTIAL error occurred with UploadedFile.
 *
 * @author Florent Mata <florentmata@gmail.com>
 */
class PartialFileException extends FileException
{
}
PKϤ$Z��e���9http-foundation/File/Exception/ExtensionFileException.phpnu�[���<?php

/*
 * This file is part of the Symfony package.
 *
 * (c) Fabien Potencier <fabien@symfony.com>
 *
 * For the full copyright and license information, please view the LICENSE
 * file that was distributed with this source code.
 */

namespace Symfony\Component\HttpFoundation\File\Exception;

/**
 * Thrown when an UPLOAD_ERR_EXTENSION error occurred with UploadedFile.
 *
 * @author Florent Mata <florentmata@gmail.com>
 */
class ExtensionFileException extends FileException
{
}
PKϤ$ZPu��JJ8http-foundation/File/Exception/FileNotFoundException.phpnu�[���<?php

/*
 * This file is part of the Symfony package.
 *
 * (c) Fabien Potencier <fabien@symfony.com>
 *
 * For the full copyright and license information, please view the LICENSE
 * file that was distributed with this source code.
 */

namespace Symfony\Component\HttpFoundation\File\Exception;

/**
 * Thrown when a file was not found.
 *
 * @author Bernhard Schussek <bschussek@gmail.com>
 */
class FileNotFoundException extends FileException
{
    public function __construct(string $path)
    {
        parent::__construct(sprintf('The file "%s" does not exist', $path));
    }
}
PKϤ$Zu�ZZ8http-foundation/File/Exception/AccessDeniedException.phpnu�[���<?php

/*
 * This file is part of the Symfony package.
 *
 * (c) Fabien Potencier <fabien@symfony.com>
 *
 * For the full copyright and license information, please view the LICENSE
 * file that was distributed with this source code.
 */

namespace Symfony\Component\HttpFoundation\File\Exception;

/**
 * Thrown when the access on a file was denied.
 *
 * @author Bernhard Schussek <bschussek@gmail.com>
 */
class AccessDeniedException extends FileException
{
    public function __construct(string $path)
    {
        parent::__construct(sprintf('The file %s could not be accessed', $path));
    }
}
PKϤ$Z�{���8http-foundation/File/Exception/FormSizeFileException.phpnu�[���<?php

/*
 * This file is part of the Symfony package.
 *
 * (c) Fabien Potencier <fabien@symfony.com>
 *
 * For the full copyright and license information, please view the LICENSE
 * file that was distributed with this source code.
 */

namespace Symfony\Component\HttpFoundation\File\Exception;

/**
 * Thrown when an UPLOAD_ERR_FORM_SIZE error occurred with UploadedFile.
 *
 * @author Florent Mata <florentmata@gmail.com>
 */
class FormSizeFileException extends FileException
{
}
PKϤ$Z��11http-foundation/File/File.phpnu�[���<?php

/*
 * This file is part of the Symfony package.
 *
 * (c) Fabien Potencier <fabien@symfony.com>
 *
 * For the full copyright and license information, please view the LICENSE
 * file that was distributed with this source code.
 */

namespace Symfony\Component\HttpFoundation\File;

use Symfony\Component\HttpFoundation\File\Exception\FileException;
use Symfony\Component\HttpFoundation\File\Exception\FileNotFoundException;
use Symfony\Component\Mime\MimeTypes;

/**
 * A file in the file system.
 *
 * @author Bernhard Schussek <bschussek@gmail.com>
 */
class File extends \SplFileInfo
{
    /**
     * Constructs a new file from the given path.
     *
     * @param string $path      The path to the file
     * @param bool   $checkPath Whether to check the path or not
     *
     * @throws FileNotFoundException If the given path is not a file
     */
    public function __construct(string $path, bool $checkPath = true)
    {
        if ($checkPath && !is_file($path)) {
            throw new FileNotFoundException($path);
        }

        parent::__construct($path);
    }

    /**
     * Returns the extension based on the mime type.
     *
     * If the mime type is unknown, returns null.
     *
     * This method uses the mime type as guessed by getMimeType()
     * to guess the file extension.
     *
     * @return string|null The guessed extension or null if it cannot be guessed
     *
     * @see MimeTypes
     * @see getMimeType()
     */
    public function guessExtension()
    {
        if (!class_exists(MimeTypes::class)) {
            throw new \LogicException('You cannot guess the extension as the Mime component is not installed. Try running "composer require symfony/mime".');
        }

        return MimeTypes::getDefault()->getExtensions($this->getMimeType())[0] ?? null;
    }

    /**
     * Returns the mime type of the file.
     *
     * The mime type is guessed using a MimeTypeGuesserInterface instance,
     * which uses finfo_file() then the "file" system binary,
     * depending on which of those are available.
     *
     * @return string|null The guessed mime type (e.g. "application/pdf")
     *
     * @see MimeTypes
     */
    public function getMimeType()
    {
        if (!class_exists(MimeTypes::class)) {
            throw new \LogicException('You cannot guess the mime type as the Mime component is not installed. Try running "composer require symfony/mime".');
        }

        return MimeTypes::getDefault()->guessMimeType($this->getPathname());
    }

    /**
     * Moves the file to a new location.
     *
     * @return self A File object representing the new file
     *
     * @throws FileException if the target file could not be created
     */
    public function move(string $directory, string $name = null)
    {
        $target = $this->getTargetFile($directory, $name);

        set_error_handler(function ($type, $msg) use (&$error) { $error = $msg; });
        $renamed = rename($this->getPathname(), $target);
        restore_error_handler();
        if (!$renamed) {
            throw new FileException(sprintf('Could not move the file "%s" to "%s" (%s).', $this->getPathname(), $target, strip_tags($error)));
        }

        @chmod($target, 0666 & ~umask());

        return $target;
    }

    public function getContent(): string
    {
        $content = file_get_contents($this->getPathname());

        if (false === $content) {
            throw new FileException(sprintf('Could not get the content of the file "%s".', $this->getPathname()));
        }

        return $content;
    }

    /**
     * @return self
     */
    protected function getTargetFile(string $directory, string $name = null)
    {
        if (!is_dir($directory)) {
            if (false === @mkdir($directory, 0777, true) && !is_dir($directory)) {
                throw new FileException(sprintf('Unable to create the "%s" directory.', $directory));
            }
        } elseif (!is_writable($directory)) {
            throw new FileException(sprintf('Unable to write in the "%s" directory.', $directory));
        }

        $target = rtrim($directory, '/\\').\DIRECTORY_SEPARATOR.(null === $name ? $this->getBasename() : $this->getName($name));

        return new self($target, false);
    }

    /**
     * Returns locale independent base name of the given path.
     *
     * @return string
     */
    protected function getName(string $name)
    {
        $originalName = str_replace('\\', '/', $name);
        $pos = strrpos($originalName, '/');
        $originalName = false === $pos ? $originalName : substr($originalName, $pos + 1);

        return $originalName;
    }
}
PKϤ$Z��w�nn.http-foundation/Tests/StreamedResponseTest.phpnu�[���<?php

/*
 * This file is part of the Symfony package.
 *
 * (c) Fabien Potencier <fabien@symfony.com>
 *
 * For the full copyright and license information, please view the LICENSE
 * file that was distributed with this source code.
 */

namespace Symfony\Component\HttpFoundation\Tests;

use Symfony\Component\HttpFoundation\Request;
use Symfony\Component\HttpFoundation\StreamedResponse;

class StreamedResponseTest extends \PHPUnit_Framework_TestCase
{
    public function testConstructor()
    {
        $response = new StreamedResponse(function () { echo 'foo'; }, 404, array('Content-Type' => 'text/plain'));

        $this->assertEquals(404, $response->getStatusCode());
        $this->assertEquals('text/plain', $response->headers->get('Content-Type'));
    }

    public function testPrepareWith11Protocol()
    {
        $response = new StreamedResponse(function () { echo 'foo'; });
        $request = Request::create('/');
        $request->server->set('SERVER_PROTOCOL', 'HTTP/1.1');

        $response->prepare($request);

        $this->assertEquals('1.1', $response->getProtocolVersion());
        $this->assertNotEquals('chunked', $response->headers->get('Transfer-Encoding'), 'Apache assumes responses with a Transfer-Encoding header set to chunked to already be encoded.');
    }

    public function testPrepareWith10Protocol()
    {
        $response = new StreamedResponse(function () { echo 'foo'; });
        $request = Request::create('/');
        $request->server->set('SERVER_PROTOCOL', 'HTTP/1.0');

        $response->prepare($request);

        $this->assertEquals('1.0', $response->getProtocolVersion());
        $this->assertNull($response->headers->get('Transfer-Encoding'));
    }

    public function testPrepareWithHeadRequest()
    {
        $response = new StreamedResponse(function () { echo 'foo'; });
        $request = Request::create('/', 'HEAD');

        $response->prepare($request);
    }

    public function testPrepareWithCacheHeaders()
    {
        $response = new StreamedResponse(function () { echo 'foo'; }, 200, array('Cache-Control' => 'max-age=600, public'));
        $request = Request::create('/', 'GET');

        $response->prepare($request);
        $this->assertEquals('max-age=600, public', $response->headers->get('Cache-Control'));
    }

    public function testSendContent()
    {
        $called = 0;

        $response = new StreamedResponse(function () use (&$called) { ++$called; });

        $response->sendContent();
        $this->assertEquals(1, $called);

        $response->sendContent();
        $this->assertEquals(1, $called);
    }

    /**
     * @expectedException \LogicException
     */
    public function testSendContentWithNonCallable()
    {
        $response = new StreamedResponse(null);
        $response->sendContent();
    }

    /**
     * @expectedException \LogicException
     */
    public function testSetCallbackNonCallable()
    {
        $response = new StreamedResponse(null);
        $response->setCallback(null);
    }

    /**
     * @expectedException \LogicException
     */
    public function testSetContent()
    {
        $response = new StreamedResponse(function () { echo 'foo'; });
        $response->setContent('foo');
    }

    public function testGetContent()
    {
        $response = new StreamedResponse(function () { echo 'foo'; });
        $this->assertFalse($response->getContent());
    }

    public function testCreate()
    {
        $response = StreamedResponse::create(function () {}, 204);

        $this->assertInstanceOf('Symfony\Component\HttpFoundation\StreamedResponse', $response);
        $this->assertEquals(204, $response->getStatusCode());
    }
}
PKϤ$ZQ�08��-http-foundation/Tests/Session/SessionTest.phpnu�[���<?php

/*
 * This file is part of the Symfony package.
 *
 * (c) Fabien Potencier <fabien@symfony.com>
 *
 * For the full copyright and license information, please view the LICENSE
 * file that was distributed with this source code.
 */

namespace Symfony\Component\HttpFoundation\Tests\Session;

use Symfony\Component\HttpFoundation\Session\Session;
use Symfony\Component\HttpFoundation\Session\Flash\FlashBag;
use Symfony\Component\HttpFoundation\Session\Attribute\AttributeBag;
use Symfony\Component\HttpFoundation\Session\Storage\MockArraySessionStorage;

/**
 * SessionTest.
 *
 * @author Fabien Potencier <fabien@symfony.com>
 * @author Robert Schönthal <seroscho@googlemail.com>
 * @author Drak <drak@zikula.org>
 */
class SessionTest extends \PHPUnit_Framework_TestCase
{
    /**
     * @var \Symfony\Component\HttpFoundation\Session\Storage\SessionStorageInterface
     */
    protected $storage;

    /**
     * @var \Symfony\Component\HttpFoundation\Session\SessionInterface
     */
    protected $session;

    protected function setUp()
    {
        $this->storage = new MockArraySessionStorage();
        $this->session = new Session($this->storage, new AttributeBag(), new FlashBag());
    }

    protected function tearDown()
    {
        $this->storage = null;
        $this->session = null;
    }

    public function testStart()
    {
        $this->assertEquals('', $this->session->getId());
        $this->assertTrue($this->session->start());
        $this->assertNotEquals('', $this->session->getId());
    }

    public function testIsStarted()
    {
        $this->assertFalse($this->session->isStarted());
        $this->session->start();
        $this->assertTrue($this->session->isStarted());
    }

    public function testSetId()
    {
        $this->assertEquals('', $this->session->getId());
        $this->session->setId('0123456789abcdef');
        $this->session->start();
        $this->assertEquals('0123456789abcdef', $this->session->getId());
    }

    public function testSetName()
    {
        $this->assertEquals('MOCKSESSID', $this->session->getName());
        $this->session->setName('session.test.com');
        $this->session->start();
        $this->assertEquals('session.test.com', $this->session->getName());
    }

    public function testGet()
    {
        // tests defaults
        $this->assertNull($this->session->get('foo'));
        $this->assertEquals(1, $this->session->get('foo', 1));
    }

    /**
     * @dataProvider setProvider
     */
    public function testSet($key, $value)
    {
        $this->session->set($key, $value);
        $this->assertEquals($value, $this->session->get($key));
    }

    /**
     * @dataProvider setProvider
     */
    public function testHas($key, $value)
    {
        $this->session->set($key, $value);
        $this->assertTrue($this->session->has($key));
        $this->assertFalse($this->session->has($key.'non_value'));
    }

    public function testReplace()
    {
        $this->session->replace(array('happiness' => 'be good', 'symfony' => 'awesome'));
        $this->assertEquals(array('happiness' => 'be good', 'symfony' => 'awesome'), $this->session->all());
        $this->session->replace(array());
        $this->assertEquals(array(), $this->session->all());
    }

    /**
     * @dataProvider setProvider
     */
    public function testAll($key, $value, $result)
    {
        $this->session->set($key, $value);
        $this->assertEquals($result, $this->session->all());
    }

    /**
     * @dataProvider setProvider
     */
    public function testClear($key, $value)
    {
        $this->session->set('hi', 'fabien');
        $this->session->set($key, $value);
        $this->session->clear();
        $this->assertEquals(array(), $this->session->all());
    }

    public function setProvider()
    {
        return array(
            array('foo', 'bar', array('foo' => 'bar')),
            array('foo.bar', 'too much beer', array('foo.bar' => 'too much beer')),
            array('great', 'symfony is great', array('great' => 'symfony is great')),
        );
    }

    /**
     * @dataProvider setProvider
     */
    public function testRemove($key, $value)
    {
        $this->session->set('hi.world', 'have a nice day');
        $this->session->set($key, $value);
        $this->session->remove($key);
        $this->assertEquals(array('hi.world' => 'have a nice day'), $this->session->all());
    }

    public function testInvalidate()
    {
        $this->session->set('invalidate', 123);
        $this->session->invalidate();
        $this->assertEquals(array(), $this->session->all());
    }

    public function testMigrate()
    {
        $this->session->set('migrate', 321);
        $this->session->migrate();
        $this->assertEquals(321, $this->session->get('migrate'));
    }

    public function testMigrateDestroy()
    {
        $this->session->set('migrate', 333);
        $this->session->migrate(true);
        $this->assertEquals(333, $this->session->get('migrate'));
    }

    public function testSave()
    {
        $this->session->start();
        $this->session->save();
    }

    public function testGetId()
    {
        $this->assertEquals('', $this->session->getId());
        $this->session->start();
        $this->assertNotEquals('', $this->session->getId());
    }

    public function testGetFlashBag()
    {
        $this->assertInstanceOf('Symfony\\Component\\HttpFoundation\\Session\\Flash\\FlashBagInterface', $this->session->getFlashBag());
    }

    public function testGetIterator()
    {
        $attributes = array('hello' => 'world', 'symfony' => 'rocks');
        foreach ($attributes as $key => $val) {
            $this->session->set($key, $val);
        }

        $i = 0;
        foreach ($this->session as $key => $val) {
            $this->assertEquals($attributes[$key], $val);
            ++$i;
        }

        $this->assertEquals(count($attributes), $i);
    }

    public function testGetCount()
    {
        $this->session->set('hello', 'world');
        $this->session->set('symfony', 'rocks');

        $this->assertCount(2, $this->session);
    }

    public function testGetMeta()
    {
        $this->assertInstanceOf('Symfony\Component\HttpFoundation\Session\Storage\MetadataBag', $this->session->getMetadataBag());
    }
}
PKϤ$Z\�)�444http-foundation/Tests/Session/Flash/FlashBagTest.phpnu�[���<?php

/*
 * This file is part of the Symfony package.
 *
 * (c) Fabien Potencier <fabien@symfony.com>
 *
 * For the full copyright and license information, please view the LICENSE
 * file that was distributed with this source code.
 */

namespace Symfony\Component\HttpFoundation\Tests\Session\Flash;

use Symfony\Component\HttpFoundation\Session\Flash\FlashBag;

/**
 * FlashBagTest.
 *
 * @author Drak <drak@zikula.org>
 */
class FlashBagTest extends \PHPUnit_Framework_TestCase
{
    /**
     * @var \Symfony\Component\HttpFoundation\Session\Flash\FlashBagInterface
     */
    private $bag;

    /**
     * @var array
     */
    protected $array = array();

    protected function setUp()
    {
        parent::setUp();
        $this->bag = new FlashBag();
        $this->array = array('notice' => array('A previous flash message'));
        $this->bag->initialize($this->array);
    }

    protected function tearDown()
    {
        $this->bag = null;
        parent::tearDown();
    }

    public function testInitialize()
    {
        $bag = new FlashBag();
        $bag->initialize($this->array);
        $this->assertEquals($this->array, $bag->peekAll());
        $array = array('should' => array('change'));
        $bag->initialize($array);
        $this->assertEquals($array, $bag->peekAll());
    }

    public function testGetStorageKey()
    {
        $this->assertEquals('_sf2_flashes', $this->bag->getStorageKey());
        $attributeBag = new FlashBag('test');
        $this->assertEquals('test', $attributeBag->getStorageKey());
    }

    public function testGetSetName()
    {
        $this->assertEquals('flashes', $this->bag->getName());
        $this->bag->setName('foo');
        $this->assertEquals('foo', $this->bag->getName());
    }

    public function testPeek()
    {
        $this->assertEquals(array(), $this->bag->peek('non_existing'));
        $this->assertEquals(array('default'), $this->bag->peek('not_existing', array('default')));
        $this->assertEquals(array('A previous flash message'), $this->bag->peek('notice'));
        $this->assertEquals(array('A previous flash message'), $this->bag->peek('notice'));
    }

    public function testGet()
    {
        $this->assertEquals(array(), $this->bag->get('non_existing'));
        $this->assertEquals(array('default'), $this->bag->get('not_existing', array('default')));
        $this->assertEquals(array('A previous flash message'), $this->bag->get('notice'));
        $this->assertEquals(array(), $this->bag->get('notice'));
    }

    public function testAll()
    {
        $this->bag->set('notice', 'Foo');
        $this->bag->set('error', 'Bar');
        $this->assertEquals(array(
            'notice' => array('Foo'),
            'error' => array('Bar'), ), $this->bag->all()
        );

        $this->assertEquals(array(), $this->bag->all());
    }

    public function testSet()
    {
        $this->bag->set('notice', 'Foo');
        $this->bag->set('notice', 'Bar');
        $this->assertEquals(array('Bar'), $this->bag->peek('notice'));
    }

    public function testHas()
    {
        $this->assertFalse($this->bag->has('nothing'));
        $this->assertTrue($this->bag->has('notice'));
    }

    public function testKeys()
    {
        $this->assertEquals(array('notice'), $this->bag->keys());
    }

    public function testPeekAll()
    {
        $this->bag->set('notice', 'Foo');
        $this->bag->set('error', 'Bar');
        $this->assertEquals(array(
            'notice' => array('Foo'),
            'error' => array('Bar'),
            ), $this->bag->peekAll()
        );
        $this->assertTrue($this->bag->has('notice'));
        $this->assertTrue($this->bag->has('error'));
        $this->assertEquals(array(
            'notice' => array('Foo'),
            'error' => array('Bar'),
            ), $this->bag->peekAll()
        );
    }

    /**
     * @group legacy
     */
    public function testLegacyGetIterator()
    {
        $flashes = array('hello' => 'world', 'beep' => 'boop', 'notice' => 'nope');
        foreach ($flashes as $key => $val) {
            $this->bag->set($key, $val);
        }

        $i = 0;
        foreach ($this->bag as $key => $val) {
            $this->assertEquals(array($flashes[$key]), $val);
            ++$i;
        }

        $this->assertEquals(count($flashes), $i);
        $this->assertCount(0, $this->bag->all());
    }
}
PKϤ$Z�ۈ���>http-foundation/Tests/Session/Flash/AutoExpireFlashBagTest.phpnu�[���<?php

/*
 * This file is part of the Symfony package.
 *
 * (c) Fabien Potencier <fabien@symfony.com>
 *
 * For the full copyright and license information, please view the LICENSE
 * file that was distributed with this source code.
 */

namespace Symfony\Component\HttpFoundation\Tests\Session\Flash;

use Symfony\Component\HttpFoundation\Session\Flash\AutoExpireFlashBag as FlashBag;

/**
 * AutoExpireFlashBagTest.
 *
 * @author Drak <drak@zikula.org>
 */
class AutoExpireFlashBagTest extends \PHPUnit_Framework_TestCase
{
    /**
     * @var \Symfony\Component\HttpFoundation\Session\Flash\AutoExpireFlashBag
     */
    private $bag;

    /**
     * @var array
     */
    protected $array = array();

    protected function setUp()
    {
        parent::setUp();
        $this->bag = new FlashBag();
        $this->array = array('new' => array('notice' => array('A previous flash message')));
        $this->bag->initialize($this->array);
    }

    protected function tearDown()
    {
        $this->bag = null;
        parent::tearDown();
    }

    public function testInitialize()
    {
        $bag = new FlashBag();
        $array = array('new' => array('notice' => array('A previous flash message')));
        $bag->initialize($array);
        $this->assertEquals(array('A previous flash message'), $bag->peek('notice'));
        $array = array('new' => array(
                'notice' => array('Something else'),
                'error' => array('a'),
            ));
        $bag->initialize($array);
        $this->assertEquals(array('Something else'), $bag->peek('notice'));
        $this->assertEquals(array('a'), $bag->peek('error'));
    }

    public function testGetStorageKey()
    {
        $this->assertEquals('_sf2_flashes', $this->bag->getStorageKey());
        $attributeBag = new FlashBag('test');
        $this->assertEquals('test', $attributeBag->getStorageKey());
    }

    public function testGetSetName()
    {
        $this->assertEquals('flashes', $this->bag->getName());
        $this->bag->setName('foo');
        $this->assertEquals('foo', $this->bag->getName());
    }

    public function testPeek()
    {
        $this->assertEquals(array(), $this->bag->peek('non_existing'));
        $this->assertEquals(array('default'), $this->bag->peek('non_existing', array('default')));
        $this->assertEquals(array('A previous flash message'), $this->bag->peek('notice'));
        $this->assertEquals(array('A previous flash message'), $this->bag->peek('notice'));
    }

    public function testSet()
    {
        $this->bag->set('notice', 'Foo');
        $this->assertEquals(array('A previous flash message'), $this->bag->peek('notice'));
    }

    public function testHas()
    {
        $this->assertFalse($this->bag->has('nothing'));
        $this->assertTrue($this->bag->has('notice'));
    }

    public function testKeys()
    {
        $this->assertEquals(array('notice'), $this->bag->keys());
    }

    public function testPeekAll()
    {
        $array = array(
            'new' => array(
                'notice' => 'Foo',
                'error' => 'Bar',
            ),
        );

        $this->bag->initialize($array);
        $this->assertEquals(array(
            'notice' => 'Foo',
            'error' => 'Bar',
            ), $this->bag->peekAll()
        );

        $this->assertEquals(array(
            'notice' => 'Foo',
            'error' => 'Bar',
            ), $this->bag->peekAll()
        );
    }

    public function testGet()
    {
        $this->assertEquals(array(), $this->bag->get('non_existing'));
        $this->assertEquals(array('default'), $this->bag->get('non_existing', array('default')));
        $this->assertEquals(array('A previous flash message'), $this->bag->get('notice'));
        $this->assertEquals(array(), $this->bag->get('notice'));
    }

    public function testSetAll()
    {
        $this->bag->setAll(array('a' => 'first', 'b' => 'second'));
        $this->assertFalse($this->bag->has('a'));
        $this->assertFalse($this->bag->has('b'));
    }

    public function testAll()
    {
        $this->bag->set('notice', 'Foo');
        $this->bag->set('error', 'Bar');
        $this->assertEquals(array(
            'notice' => array('A previous flash message'),
            ), $this->bag->all()
        );

        $this->assertEquals(array(), $this->bag->all());
    }

    public function testClear()
    {
        $this->assertEquals(array('notice' => array('A previous flash message')), $this->bag->clear());
    }
}
PKϤ$Z$�pɴ�Ehttp-foundation/Tests/Session/Storage/PhpBridgeSessionStorageTest.phpnu�[���<?php

/*
 * This file is part of the Symfony package.
 *
 * (c) Fabien Potencier <fabien@symfony.com>
 *
 * For the full copyright and license information, please view the LICENSE
 * file that was distributed with this source code.
 */

namespace Symfony\Component\HttpFoundation\Tests\Session\Storage;

use Symfony\Component\HttpFoundation\Session\Storage\PhpBridgeSessionStorage;
use Symfony\Component\HttpFoundation\Session\Attribute\AttributeBag;

/**
 * Test class for PhpSessionStorage.
 *
 * @author Drak <drak@zikula.org>
 *
 * These tests require separate processes.
 *
 * @runTestsInSeparateProcesses
 * @preserveGlobalState disabled
 */
class PhpBridgeSessionStorageTest extends \PHPUnit_Framework_TestCase
{
    private $savePath;

    protected function setUp()
    {
        $this->iniSet('session.save_handler', 'files');
        $this->iniSet('session.save_path', $this->savePath = sys_get_temp_dir().'/sf2test');
        if (!is_dir($this->savePath)) {
            mkdir($this->savePath);
        }
    }

    protected function tearDown()
    {
        session_write_close();
        array_map('unlink', glob($this->savePath.'/*'));
        if (is_dir($this->savePath)) {
            rmdir($this->savePath);
        }

        $this->savePath = null;
    }

    /**
     * @return PhpBridgeSessionStorage
     */
    protected function getStorage()
    {
        $storage = new PhpBridgeSessionStorage();
        $storage->registerBag(new AttributeBag());

        return $storage;
    }

    public function testPhpSession53()
    {
        if (PHP_VERSION_ID >= 50400) {
            $this->markTestSkipped('Test skipped, for PHP 5.3 only.');
        }

        $storage = $this->getStorage();

        $this->assertFalse(isset($_SESSION));
        $this->assertFalse($storage->getSaveHandler()->isActive());

        session_start();
        $this->assertTrue(isset($_SESSION));
        // in PHP 5.3 we cannot reliably tell if a session has started
        $this->assertFalse($storage->getSaveHandler()->isActive());
        // PHP session might have started, but the storage driver has not, so false is correct here
        $this->assertFalse($storage->isStarted());

        $key = $storage->getMetadataBag()->getStorageKey();
        $this->assertFalse(isset($_SESSION[$key]));
        $storage->start();
        $this->assertTrue(isset($_SESSION[$key]));
    }

    /**
     * @requires PHP 5.4
     */
    public function testPhpSession54()
    {
        $storage = $this->getStorage();

        $this->assertFalse($storage->getSaveHandler()->isActive());
        $this->assertFalse($storage->isStarted());

        session_start();
        $this->assertTrue(isset($_SESSION));
        // in PHP 5.4 we can reliably detect a session started
        $this->assertTrue($storage->getSaveHandler()->isActive());
        // PHP session might have started, but the storage driver has not, so false is correct here
        $this->assertFalse($storage->isStarted());

        $key = $storage->getMetadataBag()->getStorageKey();
        $this->assertFalse(isset($_SESSION[$key]));
        $storage->start();
        $this->assertTrue(isset($_SESSION[$key]));
    }

    public function testClear()
    {
        $storage = $this->getStorage();
        session_start();
        $_SESSION['drak'] = 'loves symfony';
        $storage->getBag('attributes')->set('symfony', 'greatness');
        $key = $storage->getBag('attributes')->getStorageKey();
        $this->assertEquals($_SESSION[$key], array('symfony' => 'greatness'));
        $this->assertEquals($_SESSION['drak'], 'loves symfony');
        $storage->clear();
        $this->assertEquals($_SESSION[$key], array());
        $this->assertEquals($_SESSION['drak'], 'loves symfony');
    }
}
PKϤ$Z9����Ghttp-foundation/Tests/Session/Storage/Proxy/SessionHandlerProxyTest.phpnu�[���<?php

/*
 * This file is part of the Symfony package.
 *
 * (c) Fabien Potencier <fabien@symfony.com>
 *
 * For the full copyright and license information, please view the LICENSE
 * file that was distributed with this source code.
 */

namespace Symfony\Component\HttpFoundation\Tests\Session\Storage\Proxy;

use Symfony\Component\HttpFoundation\Session\Storage\Proxy\SessionHandlerProxy;

/**
 * Tests for SessionHandlerProxy class.
 *
 * @author Drak <drak@zikula.org>
 *
 * @runTestsInSeparateProcesses
 * @preserveGlobalState disabled
 */
class SessionHandlerProxyTest extends \PHPUnit_Framework_TestCase
{
    /**
     * @var \PHPUnit_Framework_MockObject_Matcher
     */
    private $mock;

    /**
     * @var SessionHandlerProxy
     */
    private $proxy;

    protected function setUp()
    {
        $this->mock = $this->getMock('SessionHandlerInterface');
        $this->proxy = new SessionHandlerProxy($this->mock);
    }

    protected function tearDown()
    {
        $this->mock = null;
        $this->proxy = null;
    }

    public function testOpen()
    {
        $this->mock->expects($this->once())
            ->method('open')
            ->will($this->returnValue(true));

        $this->assertFalse($this->proxy->isActive());
        $this->proxy->open('name', 'id');
        if (PHP_VERSION_ID < 50400) {
            $this->assertTrue($this->proxy->isActive());
        } else {
            $this->assertFalse($this->proxy->isActive());
        }
    }

    public function testOpenFalse()
    {
        $this->mock->expects($this->once())
            ->method('open')
            ->will($this->returnValue(false));

        $this->assertFalse($this->proxy->isActive());
        $this->proxy->open('name', 'id');
        $this->assertFalse($this->proxy->isActive());
    }

    public function testClose()
    {
        $this->mock->expects($this->once())
            ->method('close')
            ->will($this->returnValue(true));

        $this->assertFalse($this->proxy->isActive());
        $this->proxy->close();
        $this->assertFalse($this->proxy->isActive());
    }

    public function testCloseFalse()
    {
        $this->mock->expects($this->once())
            ->method('close')
            ->will($this->returnValue(false));

        $this->assertFalse($this->proxy->isActive());
        $this->proxy->close();
        $this->assertFalse($this->proxy->isActive());
    }

    public function testRead()
    {
        $this->mock->expects($this->once())
            ->method('read');

        $this->proxy->read('id');
    }

    public function testWrite()
    {
        $this->mock->expects($this->once())
            ->method('write');

        $this->proxy->write('id', 'data');
    }

    public function testDestroy()
    {
        $this->mock->expects($this->once())
            ->method('destroy');

        $this->proxy->destroy('id');
    }

    public function testGc()
    {
        $this->mock->expects($this->once())
            ->method('gc');

        $this->proxy->gc(86400);
    }
}
PKϤ$Z1�\���Ahttp-foundation/Tests/Session/Storage/Proxy/AbstractProxyTest.phpnu�[���<?php

/*
 * This file is part of the Symfony package.
 *
 * (c) Fabien Potencier <fabien@symfony.com>
 *
 * For the full copyright and license information, please view the LICENSE
 * file that was distributed with this source code.
 */

namespace Symfony\Component\HttpFoundation\Tests\Session\Storage\Proxy;

use Symfony\Component\HttpFoundation\Session\Storage\Proxy\AbstractProxy;

// Note until PHPUnit_Mock_Objects 1.2 is released you cannot mock abstracts due to
// https://github.com/sebastianbergmann/phpunit-mock-objects/issues/73
class ConcreteProxy extends AbstractProxy
{
}

class ConcreteSessionHandlerInterfaceProxy extends AbstractProxy implements \SessionHandlerInterface
{
    public function open($savePath, $sessionName)
    {
    }

    public function close()
    {
    }

    public function read($id)
    {
    }

    public function write($id, $data)
    {
    }

    public function destroy($id)
    {
    }

    public function gc($maxlifetime)
    {
    }
}

/**
 * Test class for AbstractProxy.
 *
 * @author Drak <drak@zikula.org>
 */
class AbstractProxyTest extends \PHPUnit_Framework_TestCase
{
    /**
     * @var AbstractProxy
     */
    protected $proxy;

    protected function setUp()
    {
        $this->proxy = new ConcreteProxy();
    }

    protected function tearDown()
    {
        $this->proxy = null;
    }

    public function testGetSaveHandlerName()
    {
        $this->assertNull($this->proxy->getSaveHandlerName());
    }

    public function testIsSessionHandlerInterface()
    {
        $this->assertFalse($this->proxy->isSessionHandlerInterface());
        $sh = new ConcreteSessionHandlerInterfaceProxy();
        $this->assertTrue($sh->isSessionHandlerInterface());
    }

    public function testIsWrapper()
    {
        $this->assertFalse($this->proxy->isWrapper());
    }

    public function testIsActivePhp53()
    {
        if (PHP_VERSION_ID >= 50400) {
            $this->markTestSkipped('Test skipped, for PHP 5.3 only.');
        }

        $this->assertFalse($this->proxy->isActive());
    }

    /**
     * @runInSeparateProcess
     * @preserveGlobalState disabled
     * @requires PHP 5.4
     */
    public function testIsActivePhp54()
    {
        $this->assertFalse($this->proxy->isActive());
        session_start();
        $this->assertTrue($this->proxy->isActive());
    }

    public function testSetActivePhp53()
    {
        if (PHP_VERSION_ID >= 50400) {
            $this->markTestSkipped('Test skipped, for PHP 5.3 only.');
        }

        $this->proxy->setActive(true);
        $this->assertTrue($this->proxy->isActive());
        $this->proxy->setActive(false);
        $this->assertFalse($this->proxy->isActive());
    }

    /**
     * @runInSeparateProcess
     * @preserveGlobalState disabled
     * @expectedException \LogicException
     * @requires PHP 5.4
     */
    public function testSetActivePhp54()
    {
        $this->proxy->setActive(true);
    }

    /**
     * @runInSeparateProcess
     * @preserveGlobalState disabled
     */
    public function testName()
    {
        $this->assertEquals(session_name(), $this->proxy->getName());
        $this->proxy->setName('foo');
        $this->assertEquals('foo', $this->proxy->getName());
        $this->assertEquals(session_name(), $this->proxy->getName());
    }

    /**
     * @expectedException \LogicException
     */
    public function testNameExceptionPhp53()
    {
        if (PHP_VERSION_ID >= 50400) {
            $this->markTestSkipped('Test skipped, for PHP 5.3 only.');
        }

        $this->proxy->setActive(true);
        $this->proxy->setName('foo');
    }

    /**
     * @runInSeparateProcess
     * @preserveGlobalState disabled
     * @expectedException \LogicException
     * @requires PHP 5.4
     */
    public function testNameExceptionPhp54()
    {
        session_start();
        $this->proxy->setName('foo');
    }

    /**
     * @runInSeparateProcess
     * @preserveGlobalState disabled
     */
    public function testId()
    {
        $this->assertEquals(session_id(), $this->proxy->getId());
        $this->proxy->setId('foo');
        $this->assertEquals('foo', $this->proxy->getId());
        $this->assertEquals(session_id(), $this->proxy->getId());
    }

    /**
     * @expectedException \LogicException
     */
    public function testIdExceptionPhp53()
    {
        if (PHP_VERSION_ID >= 50400) {
            $this->markTestSkipped('Test skipped, for PHP 5.3 only.');
        }

        $this->proxy->setActive(true);
        $this->proxy->setId('foo');
    }

    /**
     * @runInSeparateProcess
     * @preserveGlobalState disabled
     * @expectedException \LogicException
     * @requires PHP 5.4
     */
    public function testIdExceptionPhp54()
    {
        session_start();
        $this->proxy->setId('foo');
    }
}
PKϤ$Z�@|B``?http-foundation/Tests/Session/Storage/Proxy/NativeProxyTest.phpnu�[���<?php

/*
 * This file is part of the Symfony package.
 *
 * (c) Fabien Potencier <fabien@symfony.com>
 *
 * For the full copyright and license information, please view the LICENSE
 * file that was distributed with this source code.
 */

namespace Symfony\Component\HttpFoundation\Tests\Session\Storage\Proxy;

use Symfony\Component\HttpFoundation\Session\Storage\Proxy\NativeProxy;

/**
 * Test class for NativeProxy.
 *
 * @author Drak <drak@zikula.org>
 */
class NativeProxyTest extends \PHPUnit_Framework_TestCase
{
    public function testIsWrapper()
    {
        $proxy = new NativeProxy();
        $this->assertFalse($proxy->isWrapper());
    }

    public function testGetSaveHandlerName()
    {
        $name = ini_get('session.save_handler');
        $proxy = new NativeProxy();
        $this->assertEquals($name, $proxy->getSaveHandlerName());
    }
}
PKϤ$Z�@=\&&9http-foundation/Tests/Session/Storage/MetadataBagTest.phpnu�[���<?php

/*
 * This file is part of the Symfony package.
 *
 * (c) Fabien Potencier <fabien@symfony.com>
 *
 * For the full copyright and license information, please view the LICENSE
 * file that was distributed with this source code.
 */

namespace Symfony\Component\HttpFoundation\Tests\Session\Storage;

use Symfony\Component\HttpFoundation\Session\Storage\MetadataBag;

/**
 * Test class for MetadataBag.
 *
 * @group time-sensitive
 */
class MetadataBagTest extends \PHPUnit_Framework_TestCase
{
    /**
     * @var MetadataBag
     */
    protected $bag;

    /**
     * @var array
     */
    protected $array = array();

    protected function setUp()
    {
        parent::setUp();
        $this->bag = new MetadataBag();
        $this->array = array(MetadataBag::CREATED => 1234567, MetadataBag::UPDATED => 12345678, MetadataBag::LIFETIME => 0);
        $this->bag->initialize($this->array);
    }

    protected function tearDown()
    {
        $this->array = array();
        $this->bag = null;
        parent::tearDown();
    }

    public function testInitialize()
    {
        $sessionMetadata = array();

        $bag1 = new MetadataBag();
        $bag1->initialize($sessionMetadata);
        $this->assertGreaterThanOrEqual(time(), $bag1->getCreated());
        $this->assertEquals($bag1->getCreated(), $bag1->getLastUsed());

        sleep(1);
        $bag2 = new MetadataBag();
        $bag2->initialize($sessionMetadata);
        $this->assertEquals($bag1->getCreated(), $bag2->getCreated());
        $this->assertEquals($bag1->getLastUsed(), $bag2->getLastUsed());
        $this->assertEquals($bag2->getCreated(), $bag2->getLastUsed());

        sleep(1);
        $bag3 = new MetadataBag();
        $bag3->initialize($sessionMetadata);
        $this->assertEquals($bag1->getCreated(), $bag3->getCreated());
        $this->assertGreaterThan($bag2->getLastUsed(), $bag3->getLastUsed());
        $this->assertNotEquals($bag3->getCreated(), $bag3->getLastUsed());
    }

    public function testGetSetName()
    {
        $this->assertEquals('__metadata', $this->bag->getName());
        $this->bag->setName('foo');
        $this->assertEquals('foo', $this->bag->getName());
    }

    public function testGetStorageKey()
    {
        $this->assertEquals('_sf2_meta', $this->bag->getStorageKey());
    }

    public function testGetLifetime()
    {
        $bag = new MetadataBag();
        $array = array(MetadataBag::CREATED => 1234567, MetadataBag::UPDATED => 12345678, MetadataBag::LIFETIME => 1000);
        $bag->initialize($array);
        $this->assertEquals(1000, $bag->getLifetime());
    }

    public function testGetCreated()
    {
        $this->assertEquals(1234567, $this->bag->getCreated());
    }

    public function testGetLastUsed()
    {
        $this->assertLessThanOrEqual(time(), $this->bag->getLastUsed());
    }

    public function testClear()
    {
        $this->bag->clear();
    }

    public function testSkipLastUsedUpdate()
    {
        $bag = new MetadataBag('', 30);
        $timeStamp = time();

        $created = $timeStamp - 15;
        $sessionMetadata = array(
            MetadataBag::CREATED => $created,
            MetadataBag::UPDATED => $created,
            MetadataBag::LIFETIME => 1000,
        );
        $bag->initialize($sessionMetadata);

        $this->assertEquals($created, $sessionMetadata[MetadataBag::UPDATED]);
    }

    public function testDoesNotSkipLastUsedUpdate()
    {
        $bag = new MetadataBag('', 30);
        $timeStamp = time();

        $created = $timeStamp - 45;
        $sessionMetadata = array(
            MetadataBag::CREATED => $created,
            MetadataBag::UPDATED => $created,
            MetadataBag::LIFETIME => 1000,
        );
        $bag->initialize($sessionMetadata);

        $this->assertEquals($timeStamp, $sessionMetadata[MetadataBag::UPDATED]);
    }
}
PKϤ$ZW�4��Hhttp-foundation/Tests/Session/Storage/Handler/NullSessionHandlerTest.phpnu�[���<?php

/*
 * This file is part of the Symfony package.
 *
 * (c) Fabien Potencier <fabien@symfony.com>
 *
 * For the full copyright and license information, please view the LICENSE
 * file that was distributed with this source code.
 */

namespace Symfony\Component\HttpFoundation\Tests\Session\Storage\Handler;

use Symfony\Component\HttpFoundation\Session\Storage\Handler\NullSessionHandler;
use Symfony\Component\HttpFoundation\Session\Storage\NativeSessionStorage;
use Symfony\Component\HttpFoundation\Session\Session;

/**
 * Test class for NullSessionHandler.
 *
 * @author Drak <drak@zikula.org>
 *
 * @runTestsInSeparateProcesses
 * @preserveGlobalState disabled
 */
class NullSessionHandlerTest extends \PHPUnit_Framework_TestCase
{
    public function testSaveHandlers()
    {
        $storage = $this->getStorage();
        $this->assertEquals('user', ini_get('session.save_handler'));
    }

    public function testSession()
    {
        session_id('nullsessionstorage');
        $storage = $this->getStorage();
        $session = new Session($storage);
        $this->assertNull($session->get('something'));
        $session->set('something', 'unique');
        $this->assertEquals('unique', $session->get('something'));
    }

    public function testNothingIsPersisted()
    {
        session_id('nullsessionstorage');
        $storage = $this->getStorage();
        $session = new Session($storage);
        $session->start();
        $this->assertEquals('nullsessionstorage', $session->getId());
        $this->assertNull($session->get('something'));
    }

    public function getStorage()
    {
        return new NativeSessionStorage(array(), new NullSessionHandler());
    }
}
PKϤ$Z���[eeMhttp-foundation/Tests/Session/Storage/Handler/MemcachedSessionHandlerTest.phpnu�[���<?php

/*
 * This file is part of the Symfony package.
 *
 * (c) Fabien Potencier <fabien@symfony.com>
 *
 * For the full copyright and license information, please view the LICENSE
 * file that was distributed with this source code.
 */

namespace Symfony\Component\HttpFoundation\Tests\Session\Storage\Handler;

use Symfony\Component\HttpFoundation\Session\Storage\Handler\MemcachedSessionHandler;

/**
 * @requires extension memcached
 * @group time-sensitive
 */
class MemcachedSessionHandlerTest extends \PHPUnit_Framework_TestCase
{
    const PREFIX = 'prefix_';
    const TTL = 1000;

    /**
     * @var MemcachedSessionHandler
     */
    protected $storage;

    protected $memcached;

    protected function setUp()
    {
        if (defined('HHVM_VERSION')) {
            $this->markTestSkipped('PHPUnit_MockObject cannot mock the Memcached class on HHVM. See https://github.com/sebastianbergmann/phpunit-mock-objects/pull/289');
        }

        parent::setUp();

        if (version_compare(phpversion('memcached'), '2.2.0', '>=')) {
            $this->markTestSkipped('Tests can only be run with memcached extension 2.1.0 or lower');
        }

        $this->memcached = $this->getMock('Memcached');
        $this->storage = new MemcachedSessionHandler(
            $this->memcached,
            array('prefix' => self::PREFIX, 'expiretime' => self::TTL)
        );
    }

    protected function tearDown()
    {
        $this->memcached = null;
        $this->storage = null;
        parent::tearDown();
    }

    public function testOpenSession()
    {
        $this->assertTrue($this->storage->open('', ''));
    }

    public function testCloseSession()
    {
        $this->assertTrue($this->storage->close());
    }

    public function testReadSession()
    {
        $this->memcached
            ->expects($this->once())
            ->method('get')
            ->with(self::PREFIX.'id')
        ;

        $this->assertEquals('', $this->storage->read('id'));
    }

    public function testWriteSession()
    {
        $this->memcached
            ->expects($this->once())
            ->method('set')
            ->with(self::PREFIX.'id', 'data', $this->equalTo(time() + self::TTL, 2))
            ->will($this->returnValue(true))
        ;

        $this->assertTrue($this->storage->write('id', 'data'));
    }

    public function testDestroySession()
    {
        $this->memcached
            ->expects($this->once())
            ->method('delete')
            ->with(self::PREFIX.'id')
            ->will($this->returnValue(true))
        ;

        $this->assertTrue($this->storage->destroy('id'));
    }

    public function testGcSession()
    {
        $this->assertTrue($this->storage->gc(123));
    }

    /**
     * @dataProvider getOptionFixtures
     */
    public function testSupportedOptions($options, $supported)
    {
        try {
            new MemcachedSessionHandler($this->memcached, $options);
            $this->assertTrue($supported);
        } catch (\InvalidArgumentException $e) {
            $this->assertFalse($supported);
        }
    }

    public function getOptionFixtures()
    {
        return array(
            array(array('prefix' => 'session'), true),
            array(array('expiretime' => 100), true),
            array(array('prefix' => 'session', 'expiretime' => 200), true),
            array(array('expiretime' => 100, 'foo' => 'bar'), false),
        );
    }

    public function testGetConnection()
    {
        $method = new \ReflectionMethod($this->storage, 'getMemcached');
        $method->setAccessible(true);

        $this->assertInstanceOf('\Memcached', $method->invoke($this->storage));
    }
}
PKϤ$ZL�&�"�"Khttp-foundation/Tests/Session/Storage/Handler/MongoDbSessionHandlerTest.phpnu�[���<?php

/*
 * This file is part of the Symfony package.
 *
 * (c) Fabien Potencier <fabien@symfony.com>
 *
 * For the full copyright and license information, please view the LICENSE
 * file that was distributed with this source code.
 */

namespace Symfony\Component\HttpFoundation\Tests\Session\Storage\Handler;

use Symfony\Component\HttpFoundation\Session\Storage\Handler\MongoDbSessionHandler;

/**
 * @author Markus Bachmann <markus.bachmann@bachi.biz>
 * @requires extension mongo
 * @group time-sensitive
 */
class MongoDbSessionHandlerTest extends \PHPUnit_Framework_TestCase
{
    /**
     * @var \PHPUnit_Framework_MockObject_MockObject
     */
    private $mongo;
    private $storage;
    public $options;

    protected function setUp()
    {
        parent::setUp();

        $mongoClass = version_compare(phpversion('mongo'), '1.3.0', '<') ? 'Mongo' : 'MongoClient';

        $this->mongo = $this->getMockBuilder($mongoClass)
            ->disableOriginalConstructor()
            ->getMock();

        $this->options = array(
            'id_field' => '_id',
            'data_field' => 'data',
            'time_field' => 'time',
            'expiry_field' => 'expires_at',
            'database' => 'sf2-test',
            'collection' => 'session-test',
        );

        $this->storage = new MongoDbSessionHandler($this->mongo, $this->options);
    }

    /**
     * @expectedException \InvalidArgumentException
     */
    public function testConstructorShouldThrowExceptionForInvalidMongo()
    {
        new MongoDbSessionHandler(new \stdClass(), $this->options);
    }

    /**
     * @expectedException \InvalidArgumentException
     */
    public function testConstructorShouldThrowExceptionForMissingOptions()
    {
        new MongoDbSessionHandler($this->mongo, array());
    }

    public function testOpenMethodAlwaysReturnTrue()
    {
        $this->assertTrue($this->storage->open('test', 'test'), 'The "open" method should always return true');
    }

    public function testCloseMethodAlwaysReturnTrue()
    {
        $this->assertTrue($this->storage->close(), 'The "close" method should always return true');
    }

    public function testRead()
    {
        $collection = $this->createMongoCollectionMock();

        $this->mongo->expects($this->once())
            ->method('selectCollection')
            ->with($this->options['database'], $this->options['collection'])
            ->will($this->returnValue($collection));

        $that = $this;

        // defining the timeout before the actual method call
        // allows to test for "greater than" values in the $criteria
        $testTimeout = time() + 1;

        $collection->expects($this->once())
            ->method('findOne')
            ->will($this->returnCallback(function ($criteria) use ($that, $testTimeout) {
                $that->assertArrayHasKey($that->options['id_field'], $criteria);
                $that->assertEquals($criteria[$that->options['id_field']], 'foo');

                $that->assertArrayHasKey($that->options['expiry_field'], $criteria);
                $that->assertArrayHasKey('$gte', $criteria[$that->options['expiry_field']]);
                $that->assertInstanceOf('MongoDate', $criteria[$that->options['expiry_field']]['$gte']);
                $that->assertGreaterThanOrEqual($criteria[$that->options['expiry_field']]['$gte']->sec, $testTimeout);

                return array(
                    $that->options['id_field'] => 'foo',
                    $that->options['data_field'] => new \MongoBinData('bar', \MongoBinData::BYTE_ARRAY),
                    $that->options['id_field'] => new \MongoDate(),
                );
            }));

        $this->assertEquals('bar', $this->storage->read('foo'));
    }

    public function testWrite()
    {
        $collection = $this->createMongoCollectionMock();

        $this->mongo->expects($this->once())
            ->method('selectCollection')
            ->with($this->options['database'], $this->options['collection'])
            ->will($this->returnValue($collection));

        $that = $this;
        $data = array();

        $collection->expects($this->once())
            ->method('update')
            ->will($this->returnCallback(function ($criteria, $updateData, $options) use ($that, &$data) {
                $that->assertEquals(array($that->options['id_field'] => 'foo'), $criteria);
                $that->assertEquals(array('upsert' => true, 'multiple' => false), $options);

                $data = $updateData['$set'];
            }));

        $expectedExpiry = time() + (int) ini_get('session.gc_maxlifetime');
        $this->assertTrue($this->storage->write('foo', 'bar'));

        $this->assertEquals('bar', $data[$this->options['data_field']]->bin);
        $that->assertInstanceOf('MongoDate', $data[$this->options['time_field']]);
        $this->assertInstanceOf('MongoDate', $data[$this->options['expiry_field']]);
        $this->assertGreaterThanOrEqual($expectedExpiry, $data[$this->options['expiry_field']]->sec);
    }

    public function testWriteWhenUsingExpiresField()
    {
        $this->options = array(
            'id_field' => '_id',
            'data_field' => 'data',
            'time_field' => 'time',
            'database' => 'sf2-test',
            'collection' => 'session-test',
            'expiry_field' => 'expiresAt',
        );

        $this->storage = new MongoDbSessionHandler($this->mongo, $this->options);

        $collection = $this->createMongoCollectionMock();

        $this->mongo->expects($this->once())
            ->method('selectCollection')
            ->with($this->options['database'], $this->options['collection'])
            ->will($this->returnValue($collection));

        $that = $this;
        $data = array();

        $collection->expects($this->once())
            ->method('update')
            ->will($this->returnCallback(function ($criteria, $updateData, $options) use ($that, &$data) {
                $that->assertEquals(array($that->options['id_field'] => 'foo'), $criteria);
                $that->assertEquals(array('upsert' => true, 'multiple' => false), $options);

                $data = $updateData['$set'];
            }));

        $this->assertTrue($this->storage->write('foo', 'bar'));

        $this->assertEquals('bar', $data[$this->options['data_field']]->bin);
        $that->assertInstanceOf('MongoDate', $data[$this->options['time_field']]);
        $that->assertInstanceOf('MongoDate', $data[$this->options['expiry_field']]);
    }

    public function testReplaceSessionData()
    {
        $collection = $this->createMongoCollectionMock();

        $this->mongo->expects($this->once())
            ->method('selectCollection')
            ->with($this->options['database'], $this->options['collection'])
            ->will($this->returnValue($collection));

        $data = array();

        $collection->expects($this->exactly(2))
            ->method('update')
            ->will($this->returnCallback(function ($criteria, $updateData, $options) use (&$data) {
                $data = $updateData;
            }));

        $this->storage->write('foo', 'bar');
        $this->storage->write('foo', 'foobar');

        $this->assertEquals('foobar', $data['$set'][$this->options['data_field']]->bin);
    }

    public function testDestroy()
    {
        $collection = $this->createMongoCollectionMock();

        $this->mongo->expects($this->once())
            ->method('selectCollection')
            ->with($this->options['database'], $this->options['collection'])
            ->will($this->returnValue($collection));

        $collection->expects($this->once())
            ->method('remove')
            ->with(array($this->options['id_field'] => 'foo'));

        $this->assertTrue($this->storage->destroy('foo'));
    }

    public function testGc()
    {
        $collection = $this->createMongoCollectionMock();

        $this->mongo->expects($this->once())
            ->method('selectCollection')
            ->with($this->options['database'], $this->options['collection'])
            ->will($this->returnValue($collection));

        $that = $this;

        $collection->expects($this->once())
            ->method('remove')
            ->will($this->returnCallback(function ($criteria) use ($that) {
                $that->assertInstanceOf('MongoDate', $criteria[$that->options['expiry_field']]['$lt']);
                $that->assertGreaterThanOrEqual(time() - 1, $criteria[$that->options['expiry_field']]['$lt']->sec);
            }));

        $this->assertTrue($this->storage->gc(1));
    }

    private function createMongoCollectionMock()
    {
        $collection = $this->getMockBuilder('MongoCollection')
            ->disableOriginalConstructor()
            ->getMock();

        return $collection;
    }
}
PKϤ$Z�r^aaNhttp-foundation/Tests/Session/Storage/Handler/WriteCheckSessionHandlerTest.phpnu�[���<?php

/*
 * This file is part of the Symfony package.
 *
 * (c) Fabien Potencier <fabien@symfony.com>
 *
 * For the full copyright and license information, please view the LICENSE
 * file that was distributed with this source code.
 */

namespace Symfony\Component\HttpFoundation\Tests\Session\Storage\Handler;

use Symfony\Component\HttpFoundation\Session\Storage\Handler\WriteCheckSessionHandler;

/**
 * @author Adrien Brault <adrien.brault@gmail.com>
 */
class WriteCheckSessionHandlerTest extends \PHPUnit_Framework_TestCase
{
    public function test()
    {
        $wrappedSessionHandlerMock = $this->getMock('SessionHandlerInterface');
        $writeCheckSessionHandler = new WriteCheckSessionHandler($wrappedSessionHandlerMock);

        $wrappedSessionHandlerMock
            ->expects($this->once())
            ->method('close')
            ->with()
            ->will($this->returnValue(true))
        ;

        $this->assertTrue($writeCheckSessionHandler->close());
    }

    public function testWrite()
    {
        $wrappedSessionHandlerMock = $this->getMock('SessionHandlerInterface');
        $writeCheckSessionHandler = new WriteCheckSessionHandler($wrappedSessionHandlerMock);

        $wrappedSessionHandlerMock
            ->expects($this->once())
            ->method('write')
            ->with('foo', 'bar')
            ->will($this->returnValue(true))
        ;

        $this->assertTrue($writeCheckSessionHandler->write('foo', 'bar'));
    }

    public function testSkippedWrite()
    {
        $wrappedSessionHandlerMock = $this->getMock('SessionHandlerInterface');
        $writeCheckSessionHandler = new WriteCheckSessionHandler($wrappedSessionHandlerMock);

        $wrappedSessionHandlerMock
            ->expects($this->once())
            ->method('read')
            ->with('foo')
            ->will($this->returnValue('bar'))
        ;

        $wrappedSessionHandlerMock
            ->expects($this->never())
            ->method('write')
        ;

        $this->assertEquals('bar', $writeCheckSessionHandler->read('foo'));
        $this->assertTrue($writeCheckSessionHandler->write('foo', 'bar'));
    }

    public function testNonSkippedWrite()
    {
        $wrappedSessionHandlerMock = $this->getMock('SessionHandlerInterface');
        $writeCheckSessionHandler = new WriteCheckSessionHandler($wrappedSessionHandlerMock);

        $wrappedSessionHandlerMock
            ->expects($this->once())
            ->method('read')
            ->with('foo')
            ->will($this->returnValue('bar'))
        ;

        $wrappedSessionHandlerMock
            ->expects($this->once())
            ->method('write')
            ->with('foo', 'baZZZ')
            ->will($this->returnValue(true))
        ;

        $this->assertEquals('bar', $writeCheckSessionHandler->read('foo'));
        $this->assertTrue($writeCheckSessionHandler->write('foo', 'baZZZ'));
    }
}
PKϤ$ZӭJz00Lhttp-foundation/Tests/Session/Storage/Handler/MemcacheSessionHandlerTest.phpnu�[���<?php

/*
 * This file is part of the Symfony package.
 *
 * (c) Fabien Potencier <fabien@symfony.com>
 *
 * For the full copyright and license information, please view the LICENSE
 * file that was distributed with this source code.
 */

namespace Symfony\Component\HttpFoundation\Tests\Session\Storage\Handler;

use Symfony\Component\HttpFoundation\Session\Storage\Handler\MemcacheSessionHandler;

/**
 * @requires extension memcache
 * @group time-sensitive
 */
class MemcacheSessionHandlerTest extends \PHPUnit_Framework_TestCase
{
    const PREFIX = 'prefix_';
    const TTL = 1000;
    /**
     * @var MemcacheSessionHandler
     */
    protected $storage;

    protected $memcache;

    protected function setUp()
    {
        if (defined('HHVM_VERSION')) {
            $this->markTestSkipped('PHPUnit_MockObject cannot mock the Memcache class on HHVM. See https://github.com/sebastianbergmann/phpunit-mock-objects/pull/289');
        }

        parent::setUp();
        $this->memcache = $this->getMock('Memcache');
        $this->storage = new MemcacheSessionHandler(
            $this->memcache,
            array('prefix' => self::PREFIX, 'expiretime' => self::TTL)
        );
    }

    protected function tearDown()
    {
        $this->memcache = null;
        $this->storage = null;
        parent::tearDown();
    }

    public function testOpenSession()
    {
        $this->assertTrue($this->storage->open('', ''));
    }

    public function testCloseSession()
    {
        $this->memcache
            ->expects($this->once())
            ->method('close')
            ->will($this->returnValue(true))
        ;

        $this->assertTrue($this->storage->close());
    }

    public function testReadSession()
    {
        $this->memcache
            ->expects($this->once())
            ->method('get')
            ->with(self::PREFIX.'id')
        ;

        $this->assertEquals('', $this->storage->read('id'));
    }

    public function testWriteSession()
    {
        $this->memcache
            ->expects($this->once())
            ->method('set')
            ->with(self::PREFIX.'id', 'data', 0, $this->equalTo(time() + self::TTL, 2))
            ->will($this->returnValue(true))
        ;

        $this->assertTrue($this->storage->write('id', 'data'));
    }

    public function testDestroySession()
    {
        $this->memcache
            ->expects($this->once())
            ->method('delete')
            ->with(self::PREFIX.'id')
            ->will($this->returnValue(true))
        ;

        $this->assertTrue($this->storage->destroy('id'));
    }

    public function testGcSession()
    {
        $this->assertTrue($this->storage->gc(123));
    }

    /**
     * @dataProvider getOptionFixtures
     */
    public function testSupportedOptions($options, $supported)
    {
        try {
            new MemcacheSessionHandler($this->memcache, $options);
            $this->assertTrue($supported);
        } catch (\InvalidArgumentException $e) {
            $this->assertFalse($supported);
        }
    }

    public function getOptionFixtures()
    {
        return array(
            array(array('prefix' => 'session'), true),
            array(array('expiretime' => 100), true),
            array(array('prefix' => 'session', 'expiretime' => 200), true),
            array(array('expiretime' => 100, 'foo' => 'bar'), false),
        );
    }

    public function testGetConnection()
    {
        $method = new \ReflectionMethod($this->storage, 'getMemcache');
        $method->setAccessible(true);

        $this->assertInstanceOf('\Memcache', $method->invoke($this->storage));
    }
}
PKϤ$Z(���Jhttp-foundation/Tests/Session/Storage/Handler/NativeSessionHandlerTest.phpnu�[���<?php

/*
 * This file is part of the Symfony package.
 *
 * (c) Fabien Potencier <fabien@symfony.com>
 *
 * For the full copyright and license information, please view the LICENSE
 * file that was distributed with this source code.
 */

namespace Symfony\Component\HttpFoundation\Tests\Session\Storage\Handler;

use Symfony\Component\HttpFoundation\Session\Storage\Handler\NativeSessionHandler;

/**
 * Test class for NativeSessionHandler.
 *
 * @author Drak <drak@zikula.org>
 *
 * @runTestsInSeparateProcesses
 * @preserveGlobalState disabled
 */
class NativeSessionHandlerTest extends \PHPUnit_Framework_TestCase
{
    public function testConstruct()
    {
        $handler = new NativeSessionHandler();

        // note for PHPUnit optimisers - the use of assertTrue/False
        // here is deliberate since the tests do not require the classes to exist - drak
        if (PHP_VERSION_ID < 50400) {
            $this->assertFalse($handler instanceof \SessionHandler);
            $this->assertTrue($handler instanceof NativeSessionHandler);
        } else {
            $this->assertTrue($handler instanceof \SessionHandler);
            $this->assertTrue($handler instanceof NativeSessionHandler);
        }
    }
}
PKϤ$Z>�Mhttp-foundation/Tests/Session/Storage/Handler/LegacyPdoSessionHandlerTest.phpnu�[���<?php

/*
 * This file is part of the Symfony package.
 *
 * (c) Fabien Potencier <fabien@symfony.com>
 *
 * For the full copyright and license information, please view the LICENSE
 * file that was distributed with this source code.
 */

namespace Symfony\Component\HttpFoundation\Tests\Session\Storage\Handler;

use Symfony\Component\HttpFoundation\Session\Storage\Handler\LegacyPdoSessionHandler;

/**
 * @group legacy
 * @group time-sensitive
 * @requires extension pdo_sqlite
 */
class LegacyPdoSessionHandlerTest extends \PHPUnit_Framework_TestCase
{
    private $pdo;

    protected function setUp()
    {
        parent::setUp();
        $this->pdo = new \PDO('sqlite::memory:');
        $this->pdo->setAttribute(\PDO::ATTR_ERRMODE, \PDO::ERRMODE_EXCEPTION);
        $sql = 'CREATE TABLE sessions (sess_id VARCHAR(128) PRIMARY KEY, sess_data TEXT, sess_time INTEGER)';
        $this->pdo->exec($sql);
    }

    public function testIncompleteOptions()
    {
        $this->setExpectedException('InvalidArgumentException');
        $storage = new LegacyPdoSessionHandler($this->pdo, array());
    }

    public function testWrongPdoErrMode()
    {
        $pdo = new \PDO('sqlite::memory:');
        $pdo->setAttribute(\PDO::ATTR_ERRMODE, \PDO::ERRMODE_SILENT);
        $pdo->exec('CREATE TABLE sessions (sess_id VARCHAR(128) PRIMARY KEY, sess_data TEXT, sess_time INTEGER)');

        $this->setExpectedException('InvalidArgumentException');
        $storage = new LegacyPdoSessionHandler($pdo, array('db_table' => 'sessions'));
    }

    public function testWrongTableOptionsWrite()
    {
        $storage = new LegacyPdoSessionHandler($this->pdo, array('db_table' => 'bad_name'));
        $this->setExpectedException('RuntimeException');
        $storage->write('foo', 'bar');
    }

    public function testWrongTableOptionsRead()
    {
        $storage = new LegacyPdoSessionHandler($this->pdo, array('db_table' => 'bad_name'));
        $this->setExpectedException('RuntimeException');
        $storage->read('foo', 'bar');
    }

    public function testWriteRead()
    {
        $storage = new LegacyPdoSessionHandler($this->pdo, array('db_table' => 'sessions'));
        $storage->write('foo', 'bar');
        $this->assertEquals('bar', $storage->read('foo'), 'written value can be read back correctly');
    }

    public function testMultipleInstances()
    {
        $storage1 = new LegacyPdoSessionHandler($this->pdo, array('db_table' => 'sessions'));
        $storage1->write('foo', 'bar');

        $storage2 = new LegacyPdoSessionHandler($this->pdo, array('db_table' => 'sessions'));
        $this->assertEquals('bar', $storage2->read('foo'), 'values persist between instances');
    }

    public function testSessionDestroy()
    {
        $storage = new LegacyPdoSessionHandler($this->pdo, array('db_table' => 'sessions'));
        $storage->write('foo', 'bar');
        $this->assertCount(1, $this->pdo->query('SELECT * FROM sessions')->fetchAll());

        $storage->destroy('foo');

        $this->assertCount(0, $this->pdo->query('SELECT * FROM sessions')->fetchAll());
    }

    public function testSessionGC()
    {
        $storage = new LegacyPdoSessionHandler($this->pdo, array('db_table' => 'sessions'));

        $storage->write('foo', 'bar');
        $storage->write('baz', 'bar');

        $this->assertCount(2, $this->pdo->query('SELECT * FROM sessions')->fetchAll());

        $storage->gc(-1);
        $this->assertCount(0, $this->pdo->query('SELECT * FROM sessions')->fetchAll());
    }

    public function testGetConnection()
    {
        $storage = new LegacyPdoSessionHandler($this->pdo, array('db_table' => 'sessions'), array());

        $method = new \ReflectionMethod($storage, 'getConnection');
        $method->setAccessible(true);

        $this->assertInstanceOf('\PDO', $method->invoke($storage));
    }
}
PKϤ$Z���!
!
Nhttp-foundation/Tests/Session/Storage/Handler/NativeFileSessionHandlerTest.phpnu�[���<?php

/*
 * This file is part of the Symfony package.
 *
 * (c) Fabien Potencier <fabien@symfony.com>
 *
 * For the full copyright and license information, please view the LICENSE
 * file that was distributed with this source code.
 */

namespace Symfony\Component\HttpFoundation\Tests\Session\Storage\Handler;

use Symfony\Component\HttpFoundation\Session\Storage\Handler\NativeFileSessionHandler;
use Symfony\Component\HttpFoundation\Session\Storage\NativeSessionStorage;

/**
 * Test class for NativeFileSessionHandler.
 *
 * @author Drak <drak@zikula.org>
 *
 * @runTestsInSeparateProcesses
 * @preserveGlobalState disabled
 */
class NativeFileSessionHandlerTest extends \PHPUnit_Framework_TestCase
{
    public function testConstruct()
    {
        $storage = new NativeSessionStorage(array('name' => 'TESTING'), new NativeFileSessionHandler(sys_get_temp_dir()));

        if (PHP_VERSION_ID < 50400) {
            $this->assertEquals('files', $storage->getSaveHandler()->getSaveHandlerName());
            $this->assertEquals('files', ini_get('session.save_handler'));
        } else {
            $this->assertEquals('files', $storage->getSaveHandler()->getSaveHandlerName());
            $this->assertEquals('user', ini_get('session.save_handler'));
        }

        $this->assertEquals(sys_get_temp_dir(), ini_get('session.save_path'));
        $this->assertEquals('TESTING', ini_get('session.name'));
    }

    /**
     * @dataProvider savePathDataProvider
     */
    public function testConstructSavePath($savePath, $expectedSavePath, $path)
    {
        $handler = new NativeFileSessionHandler($savePath);
        $this->assertEquals($expectedSavePath, ini_get('session.save_path'));
        $this->assertTrue(is_dir(realpath($path)));

        rmdir($path);
    }

    public function savePathDataProvider()
    {
        $base = sys_get_temp_dir();

        return array(
            array("$base/foo", "$base/foo", "$base/foo"),
            array("5;$base/foo", "5;$base/foo", "$base/foo"),
            array("5;0600;$base/foo", "5;0600;$base/foo", "$base/foo"),
        );
    }

    /**
     * @expectedException \InvalidArgumentException
     */
    public function testConstructException()
    {
        $handler = new NativeFileSessionHandler('something;invalid;with;too-many-args');
    }

    public function testConstructDefault()
    {
        $path = ini_get('session.save_path');
        $storage = new NativeSessionStorage(array('name' => 'TESTING'), new NativeFileSessionHandler());

        $this->assertEquals($path, ini_get('session.save_path'));
    }
}
PKϤ$Z�0(��.�.Ghttp-foundation/Tests/Session/Storage/Handler/PdoSessionHandlerTest.phpnu�[���<?php

/*
 * This file is part of the Symfony package.
 *
 * (c) Fabien Potencier <fabien@symfony.com>
 *
 * For the full copyright and license information, please view the LICENSE
 * file that was distributed with this source code.
 */

namespace Symfony\Component\HttpFoundation\Tests\Session\Storage\Handler;

use Symfony\Component\HttpFoundation\Session\Storage\Handler\PdoSessionHandler;

/**
 * @requires extension pdo_sqlite
 * @group time-sensitive
 */
class PdoSessionHandlerTest extends \PHPUnit_Framework_TestCase
{
    private $dbFile;

    protected function tearDown()
    {
        // make sure the temporary database file is deleted when it has been created (even when a test fails)
        if ($this->dbFile) {
            @unlink($this->dbFile);
        }
        parent::tearDown();
    }

    protected function getPersistentSqliteDsn()
    {
        $this->dbFile = tempnam(sys_get_temp_dir(), 'sf2_sqlite_sessions');

        return 'sqlite:'.$this->dbFile;
    }

    protected function getMemorySqlitePdo()
    {
        $pdo = new \PDO('sqlite::memory:');
        $pdo->setAttribute(\PDO::ATTR_ERRMODE, \PDO::ERRMODE_EXCEPTION);
        $storage = new PdoSessionHandler($pdo);
        $storage->createTable();

        return $pdo;
    }

    /**
     * @expectedException \InvalidArgumentException
     */
    public function testWrongPdoErrMode()
    {
        $pdo = $this->getMemorySqlitePdo();
        $pdo->setAttribute(\PDO::ATTR_ERRMODE, \PDO::ERRMODE_SILENT);

        $storage = new PdoSessionHandler($pdo);
    }

    /**
     * @expectedException \RuntimeException
     */
    public function testInexistentTable()
    {
        $storage = new PdoSessionHandler($this->getMemorySqlitePdo(), array('db_table' => 'inexistent_table'));
        $storage->open('', 'sid');
        $storage->read('id');
        $storage->write('id', 'data');
        $storage->close();
    }

    /**
     * @expectedException \RuntimeException
     */
    public function testCreateTableTwice()
    {
        $storage = new PdoSessionHandler($this->getMemorySqlitePdo());
        $storage->createTable();
    }

    public function testWithLazyDsnConnection()
    {
        $dsn = $this->getPersistentSqliteDsn();

        $storage = new PdoSessionHandler($dsn);
        $storage->createTable();
        $storage->open('', 'sid');
        $data = $storage->read('id');
        $storage->write('id', 'data');
        $storage->close();
        $this->assertSame('', $data, 'New session returns empty string data');

        $storage->open('', 'sid');
        $data = $storage->read('id');
        $storage->close();
        $this->assertSame('data', $data, 'Written value can be read back correctly');
    }

    public function testWithLazySavePathConnection()
    {
        $dsn = $this->getPersistentSqliteDsn();

        // Open is called with what ini_set('session.save_path', $dsn) would mean
        $storage = new PdoSessionHandler(null);
        $storage->open($dsn, 'sid');
        $storage->createTable();
        $data = $storage->read('id');
        $storage->write('id', 'data');
        $storage->close();
        $this->assertSame('', $data, 'New session returns empty string data');

        $storage->open($dsn, 'sid');
        $data = $storage->read('id');
        $storage->close();
        $this->assertSame('data', $data, 'Written value can be read back correctly');
    }

    public function testReadWriteReadWithNullByte()
    {
        $sessionData = 'da'."\0".'ta';

        $storage = new PdoSessionHandler($this->getMemorySqlitePdo());
        $storage->open('', 'sid');
        $readData = $storage->read('id');
        $storage->write('id', $sessionData);
        $storage->close();
        $this->assertSame('', $readData, 'New session returns empty string data');

        $storage->open('', 'sid');
        $readData = $storage->read('id');
        $storage->close();
        $this->assertSame($sessionData, $readData, 'Written value can be read back correctly');
    }

    public function testReadConvertsStreamToString()
    {
        if (defined('HHVM_VERSION')) {
            $this->markTestSkipped('PHPUnit_MockObject cannot mock the PDOStatement class on HHVM. See https://github.com/sebastianbergmann/phpunit-mock-objects/pull/289');
        }

        $pdo = new MockPdo('pgsql');
        $pdo->prepareResult = $this->getMock('PDOStatement');

        $content = 'foobar';
        $stream = $this->createStream($content);

        $pdo->prepareResult->expects($this->once())->method('fetchAll')
            ->will($this->returnValue(array(array($stream, 42, time()))));

        $storage = new PdoSessionHandler($pdo);
        $result = $storage->read('foo');

        $this->assertSame($content, $result);
    }

    public function testReadLockedConvertsStreamToString()
    {
        if (defined('HHVM_VERSION')) {
            $this->markTestSkipped('PHPUnit_MockObject cannot mock the PDOStatement class on HHVM. See https://github.com/sebastianbergmann/phpunit-mock-objects/pull/289');
        }

        $pdo = new MockPdo('pgsql');
        $selectStmt = $this->getMock('PDOStatement');
        $insertStmt = $this->getMock('PDOStatement');

        $pdo->prepareResult = function ($statement) use ($selectStmt, $insertStmt) {
            return 0 === strpos($statement, 'INSERT') ? $insertStmt : $selectStmt;
        };

        $content = 'foobar';
        $stream = $this->createStream($content);
        $exception = null;

        $selectStmt->expects($this->atLeast(2))->method('fetchAll')
            ->will($this->returnCallback(function () use (&$exception, $stream) {
                return $exception ? array(array($stream, 42, time())) : array();
            }));

        $insertStmt->expects($this->once())->method('execute')
            ->will($this->returnCallback(function () use (&$exception) {
                throw $exception = new \PDOException('', '23');
            }));

        $storage = new PdoSessionHandler($pdo);
        $result = $storage->read('foo');

        $this->assertSame($content, $result);
    }

    public function testReadingRequiresExactlySameId()
    {
        $storage = new PdoSessionHandler($this->getMemorySqlitePdo());
        $storage->open('', 'sid');
        $storage->write('id', 'data');
        $storage->write('test', 'data');
        $storage->write('space ', 'data');
        $storage->close();

        $storage->open('', 'sid');
        $readDataCaseSensitive = $storage->read('ID');
        $readDataNoCharFolding = $storage->read('tést');
        $readDataKeepSpace = $storage->read('space ');
        $readDataExtraSpace = $storage->read('space  ');
        $storage->close();

        $this->assertSame('', $readDataCaseSensitive, 'Retrieval by ID should be case-sensitive (collation setting)');
        $this->assertSame('', $readDataNoCharFolding, 'Retrieval by ID should not do character folding (collation setting)');
        $this->assertSame('data', $readDataKeepSpace, 'Retrieval by ID requires spaces as-is');
        $this->assertSame('', $readDataExtraSpace, 'Retrieval by ID requires spaces as-is');
    }

    /**
     * Simulates session_regenerate_id(true) which will require an INSERT or UPDATE (replace).
     */
    public function testWriteDifferentSessionIdThanRead()
    {
        $storage = new PdoSessionHandler($this->getMemorySqlitePdo());
        $storage->open('', 'sid');
        $storage->read('id');
        $storage->destroy('id');
        $storage->write('new_id', 'data_of_new_session_id');
        $storage->close();

        $storage->open('', 'sid');
        $data = $storage->read('new_id');
        $storage->close();

        $this->assertSame('data_of_new_session_id', $data, 'Data of regenerated session id is available');
    }

    public function testWrongUsageStillWorks()
    {
        // wrong method sequence that should no happen, but still works
        $storage = new PdoSessionHandler($this->getMemorySqlitePdo());
        $storage->write('id', 'data');
        $storage->write('other_id', 'other_data');
        $storage->destroy('inexistent');
        $storage->open('', 'sid');
        $data = $storage->read('id');
        $otherData = $storage->read('other_id');
        $storage->close();

        $this->assertSame('data', $data);
        $this->assertSame('other_data', $otherData);
    }

    public function testSessionDestroy()
    {
        $pdo = $this->getMemorySqlitePdo();
        $storage = new PdoSessionHandler($pdo);

        $storage->open('', 'sid');
        $storage->read('id');
        $storage->write('id', 'data');
        $storage->close();
        $this->assertEquals(1, $pdo->query('SELECT COUNT(*) FROM sessions')->fetchColumn());

        $storage->open('', 'sid');
        $storage->read('id');
        $storage->destroy('id');
        $storage->close();
        $this->assertEquals(0, $pdo->query('SELECT COUNT(*) FROM sessions')->fetchColumn());

        $storage->open('', 'sid');
        $data = $storage->read('id');
        $storage->close();
        $this->assertSame('', $data, 'Destroyed session returns empty string');
    }

    public function testSessionGC()
    {
        $previousLifeTime = ini_set('session.gc_maxlifetime', 1000);
        $pdo = $this->getMemorySqlitePdo();
        $storage = new PdoSessionHandler($pdo);

        $storage->open('', 'sid');
        $storage->read('id');
        $storage->write('id', 'data');
        $storage->close();

        $storage->open('', 'sid');
        $storage->read('gc_id');
        ini_set('session.gc_maxlifetime', -1); // test that you can set lifetime of a session after it has been read
        $storage->write('gc_id', 'data');
        $storage->close();
        $this->assertEquals(2, $pdo->query('SELECT COUNT(*) FROM sessions')->fetchColumn(), 'No session pruned because gc not called');

        $storage->open('', 'sid');
        $data = $storage->read('gc_id');
        $storage->gc(-1);
        $storage->close();

        ini_set('session.gc_maxlifetime', $previousLifeTime);

        $this->assertSame('', $data, 'Session already considered garbage, so not returning data even if it is not pruned yet');
        $this->assertEquals(1, $pdo->query('SELECT COUNT(*) FROM sessions')->fetchColumn(), 'Expired session is pruned');
    }

    public function testGetConnection()
    {
        $storage = new PdoSessionHandler($this->getMemorySqlitePdo());

        $method = new \ReflectionMethod($storage, 'getConnection');
        $method->setAccessible(true);

        $this->assertInstanceOf('\PDO', $method->invoke($storage));
    }

    public function testGetConnectionConnectsIfNeeded()
    {
        $storage = new PdoSessionHandler('sqlite::memory:');

        $method = new \ReflectionMethod($storage, 'getConnection');
        $method->setAccessible(true);

        $this->assertInstanceOf('\PDO', $method->invoke($storage));
    }

    private function createStream($content)
    {
        $stream = tmpfile();
        fwrite($stream, $content);
        fseek($stream, 0);

        return $stream;
    }
}

class MockPdo extends \PDO
{
    public $prepareResult;
    private $driverName;
    private $errorMode;

    public function __construct($driverName = null, $errorMode = null)
    {
        $this->driverName = $driverName;
        $this->errorMode = null !== $errorMode ?: \PDO::ERRMODE_EXCEPTION;
    }

    public function getAttribute($attribute)
    {
        if (\PDO::ATTR_ERRMODE === $attribute) {
            return $this->errorMode;
        }

        if (\PDO::ATTR_DRIVER_NAME === $attribute) {
            return $this->driverName;
        }

        return parent::getAttribute($attribute);
    }

    public function prepare($statement, $driverOptions = array())
    {
        return is_callable($this->prepareResult)
            ? call_user_func($this->prepareResult, $statement, $driverOptions)
            : $this->prepareResult;
    }

    public function beginTransaction()
    {
    }
}
PKϤ$Zh]�
Dhttp-foundation/Tests/Session/Storage/MockFileSessionStorageTest.phpnu�[���<?php

/*
 * This file is part of the Symfony package.
 *
 * (c) Fabien Potencier <fabien@symfony.com>
 *
 * For the full copyright and license information, please view the LICENSE
 * file that was distributed with this source code.
 */

namespace Symfony\Component\HttpFoundation\Tests\Session\Storage;

use Symfony\Component\HttpFoundation\Session\Storage\MockFileSessionStorage;
use Symfony\Component\HttpFoundation\Session\Flash\FlashBag;
use Symfony\Component\HttpFoundation\Session\Attribute\AttributeBag;

/**
 * Test class for MockFileSessionStorage.
 *
 * @author Drak <drak@zikula.org>
 */
class MockFileSessionStorageTest extends \PHPUnit_Framework_TestCase
{
    /**
     * @var string
     */
    private $sessionDir;

    /**
     * @var MockFileSessionStorage
     */
    protected $storage;

    protected function setUp()
    {
        $this->sessionDir = sys_get_temp_dir().'/sf2test';
        $this->storage = $this->getStorage();
    }

    protected function tearDown()
    {
        $this->sessionDir = null;
        $this->storage = null;
        array_map('unlink', glob($this->sessionDir.'/*.session'));
        if (is_dir($this->sessionDir)) {
            rmdir($this->sessionDir);
        }
    }

    public function testStart()
    {
        $this->assertEquals('', $this->storage->getId());
        $this->assertTrue($this->storage->start());
        $id = $this->storage->getId();
        $this->assertNotEquals('', $this->storage->getId());
        $this->assertTrue($this->storage->start());
        $this->assertEquals($id, $this->storage->getId());
    }

    public function testRegenerate()
    {
        $this->storage->start();
        $this->storage->getBag('attributes')->set('regenerate', 1234);
        $this->storage->regenerate();
        $this->assertEquals(1234, $this->storage->getBag('attributes')->get('regenerate'));
        $this->storage->regenerate(true);
        $this->assertEquals(1234, $this->storage->getBag('attributes')->get('regenerate'));
    }

    public function testGetId()
    {
        $this->assertEquals('', $this->storage->getId());
        $this->storage->start();
        $this->assertNotEquals('', $this->storage->getId());
    }

    public function testSave()
    {
        $this->storage->start();
        $id = $this->storage->getId();
        $this->assertNotEquals('108', $this->storage->getBag('attributes')->get('new'));
        $this->assertFalse($this->storage->getBag('flashes')->has('newkey'));
        $this->storage->getBag('attributes')->set('new', '108');
        $this->storage->getBag('flashes')->set('newkey', 'test');
        $this->storage->save();

        $storage = $this->getStorage();
        $storage->setId($id);
        $storage->start();
        $this->assertEquals('108', $storage->getBag('attributes')->get('new'));
        $this->assertTrue($storage->getBag('flashes')->has('newkey'));
        $this->assertEquals(array('test'), $storage->getBag('flashes')->peek('newkey'));
    }

    public function testMultipleInstances()
    {
        $storage1 = $this->getStorage();
        $storage1->start();
        $storage1->getBag('attributes')->set('foo', 'bar');
        $storage1->save();

        $storage2 = $this->getStorage();
        $storage2->setId($storage1->getId());
        $storage2->start();
        $this->assertEquals('bar', $storage2->getBag('attributes')->get('foo'), 'values persist between instances');
    }

    /**
     * @expectedException \RuntimeException
     */
    public function testSaveWithoutStart()
    {
        $storage1 = $this->getStorage();
        $storage1->save();
    }

    private function getStorage()
    {
        $storage = new MockFileSessionStorage($this->sessionDir);
        $storage->registerBag(new FlashBag());
        $storage->registerBag(new AttributeBag());

        return $storage;
    }
}
PKϤ$Z"F~�T&T&Bhttp-foundation/Tests/Session/Storage/NativeSessionStorageTest.phpnu�[���<?php

/*
 * This file is part of the Symfony package.
 *
 * (c) Fabien Potencier <fabien@symfony.com>
 *
 * For the full copyright and license information, please view the LICENSE
 * file that was distributed with this source code.
 */

namespace Symfony\Component\HttpFoundation\Tests\Session\Storage;

use Symfony\Component\HttpFoundation\Session\Attribute\AttributeBag;
use Symfony\Component\HttpFoundation\Session\Flash\FlashBag;
use Symfony\Component\HttpFoundation\Session\Storage\Handler\NativeSessionHandler;
use Symfony\Component\HttpFoundation\Session\Storage\Handler\NullSessionHandler;
use Symfony\Component\HttpFoundation\Session\Storage\NativeSessionStorage;
use Symfony\Component\HttpFoundation\Session\Storage\Proxy\NativeProxy;
use Symfony\Component\HttpFoundation\Session\Storage\Proxy\SessionHandlerProxy;

/**
 * Test class for NativeSessionStorage.
 *
 * @author Drak <drak@zikula.org>
 *
 * These tests require separate processes.
 *
 * @runTestsInSeparateProcesses
 * @preserveGlobalState disabled
 */
class NativeSessionStorageTest extends \PHPUnit_Framework_TestCase
{
    private $savePath;

    protected function setUp()
    {
        $this->iniSet('session.save_handler', 'files');
        $this->iniSet('session.save_path', $this->savePath = sys_get_temp_dir().'/sf2test');
        if (!is_dir($this->savePath)) {
            mkdir($this->savePath);
        }
    }

    protected function tearDown()
    {
        session_write_close();
        array_map('unlink', glob($this->savePath.'/*'));
        if (is_dir($this->savePath)) {
            rmdir($this->savePath);
        }

        $this->savePath = null;
    }

    /**
     * @param array $options
     *
     * @return NativeSessionStorage
     */
    protected function getStorage(array $options = array())
    {
        $storage = new NativeSessionStorage($options);
        $storage->registerBag(new AttributeBag());

        return $storage;
    }

    public function testBag()
    {
        $storage = $this->getStorage();
        $bag = new FlashBag();
        $storage->registerBag($bag);
        $this->assertSame($bag, $storage->getBag($bag->getName()));
    }

    /**
     * @expectedException \InvalidArgumentException
     */
    public function testRegisterBagException()
    {
        $storage = $this->getStorage();
        $storage->getBag('non_existing');
    }

    /**
     * @expectedException \LogicException
     */
    public function testRegisterBagForAStartedSessionThrowsException()
    {
        $storage = $this->getStorage();
        $storage->start();
        $storage->registerBag(new AttributeBag());
    }

    public function testGetId()
    {
        $storage = $this->getStorage();
        $this->assertSame('', $storage->getId(), 'Empty ID before starting session');

        $storage->start();
        $id = $storage->getId();
        $this->assertInternalType('string', $id);
        $this->assertNotSame('', $id);

        $storage->save();
        $this->assertSame($id, $storage->getId(), 'ID stays after saving session');
    }

    public function testRegenerate()
    {
        $storage = $this->getStorage();
        $storage->start();
        $id = $storage->getId();
        $storage->getBag('attributes')->set('lucky', 7);
        $storage->regenerate();
        $this->assertNotEquals($id, $storage->getId());
        $this->assertEquals(7, $storage->getBag('attributes')->get('lucky'));
    }

    public function testRegenerateDestroy()
    {
        $storage = $this->getStorage();
        $storage->start();
        $id = $storage->getId();
        $storage->getBag('attributes')->set('legs', 11);
        $storage->regenerate(true);
        $this->assertNotEquals($id, $storage->getId());
        $this->assertEquals(11, $storage->getBag('attributes')->get('legs'));
    }

    public function testSessionGlobalIsUpToDateAfterIdRegeneration()
    {
        $storage = $this->getStorage();
        $storage->start();
        $storage->getBag('attributes')->set('lucky', 7);
        $storage->regenerate();
        $storage->getBag('attributes')->set('lucky', 42);

        $this->assertEquals(42, $_SESSION['_sf2_attributes']['lucky']);
    }

    public function testRegenerationFailureDoesNotFlagStorageAsStarted()
    {
        $storage = $this->getStorage();
        $this->assertFalse($storage->regenerate());
        $this->assertFalse($storage->isStarted());
    }

    public function testDefaultSessionCacheLimiter()
    {
        $this->iniSet('session.cache_limiter', 'nocache');

        $storage = new NativeSessionStorage();
        $this->assertEquals('', ini_get('session.cache_limiter'));
    }

    public function testExplicitSessionCacheLimiter()
    {
        $this->iniSet('session.cache_limiter', 'nocache');

        $storage = new NativeSessionStorage(array('cache_limiter' => 'public'));
        $this->assertEquals('public', ini_get('session.cache_limiter'));
    }

    public function testCookieOptions()
    {
        $options = array(
            'cookie_lifetime' => 123456,
            'cookie_path' => '/my/cookie/path',
            'cookie_domain' => 'symfony.example.com',
            'cookie_secure' => true,
            'cookie_httponly' => false,
        );

        $this->getStorage($options);
        $temp = session_get_cookie_params();
        $gco = array();

        foreach ($temp as $key => $value) {
            $gco['cookie_'.$key] = $value;
        }

        $this->assertEquals($options, $gco);
    }

    /**
     * @expectedException \InvalidArgumentException
     */
    public function testSetSaveHandlerException()
    {
        $storage = $this->getStorage();
        $storage->setSaveHandler(new \stdClass());
    }

    public function testSetSaveHandler53()
    {
        if (PHP_VERSION_ID >= 50400) {
            $this->markTestSkipped('Test skipped, for PHP 5.3 only.');
        }

        $this->iniSet('session.save_handler', 'files');
        $storage = $this->getStorage();
        $storage->setSaveHandler();
        $this->assertInstanceOf('Symfony\Component\HttpFoundation\Session\Storage\Proxy\NativeProxy', $storage->getSaveHandler());
        $storage->setSaveHandler(null);
        $this->assertInstanceOf('Symfony\Component\HttpFoundation\Session\Storage\Proxy\NativeProxy', $storage->getSaveHandler());
        $storage->setSaveHandler(new NativeSessionHandler());
        $this->assertInstanceOf('Symfony\Component\HttpFoundation\Session\Storage\Proxy\NativeProxy', $storage->getSaveHandler());
        $storage->setSaveHandler(new SessionHandlerProxy(new NullSessionHandler()));
        $this->assertInstanceOf('Symfony\Component\HttpFoundation\Session\Storage\Proxy\SessionHandlerProxy', $storage->getSaveHandler());
        $storage->setSaveHandler(new NullSessionHandler());
        $this->assertInstanceOf('Symfony\Component\HttpFoundation\Session\Storage\Proxy\SessionHandlerProxy', $storage->getSaveHandler());
        $storage->setSaveHandler(new NativeProxy());
        $this->assertInstanceOf('Symfony\Component\HttpFoundation\Session\Storage\Proxy\NativeProxy', $storage->getSaveHandler());
    }

    /**
     * @requires PHP 5.4
     */
    public function testSetSaveHandler54()
    {
        $this->iniSet('session.save_handler', 'files');
        $storage = $this->getStorage();
        $storage->setSaveHandler();
        $this->assertInstanceOf('Symfony\Component\HttpFoundation\Session\Storage\Proxy\SessionHandlerProxy', $storage->getSaveHandler());
        $storage->setSaveHandler(null);
        $this->assertInstanceOf('Symfony\Component\HttpFoundation\Session\Storage\Proxy\SessionHandlerProxy', $storage->getSaveHandler());
        $storage->setSaveHandler(new SessionHandlerProxy(new NativeSessionHandler()));
        $this->assertInstanceOf('Symfony\Component\HttpFoundation\Session\Storage\Proxy\SessionHandlerProxy', $storage->getSaveHandler());
        $storage->setSaveHandler(new NativeSessionHandler());
        $this->assertInstanceOf('Symfony\Component\HttpFoundation\Session\Storage\Proxy\SessionHandlerProxy', $storage->getSaveHandler());
        $storage->setSaveHandler(new SessionHandlerProxy(new NullSessionHandler()));
        $this->assertInstanceOf('Symfony\Component\HttpFoundation\Session\Storage\Proxy\SessionHandlerProxy', $storage->getSaveHandler());
        $storage->setSaveHandler(new NullSessionHandler());
        $this->assertInstanceOf('Symfony\Component\HttpFoundation\Session\Storage\Proxy\SessionHandlerProxy', $storage->getSaveHandler());
    }

    /**
     * @expectedException \RuntimeException
     */
    public function testStartedOutside()
    {
        $storage = $this->getStorage();

        $this->assertFalse($storage->getSaveHandler()->isActive());
        $this->assertFalse($storage->isStarted());

        session_start();
        $this->assertTrue(isset($_SESSION));
        if (PHP_VERSION_ID >= 50400) {
            // this only works in PHP >= 5.4 where session_status is available
            $this->assertTrue($storage->getSaveHandler()->isActive());
        }
        // PHP session might have started, but the storage driver has not, so false is correct here
        $this->assertFalse($storage->isStarted());

        $key = $storage->getMetadataBag()->getStorageKey();
        $this->assertFalse(isset($_SESSION[$key]));
        $storage->start();
    }

    public function testRestart()
    {
        $storage = $this->getStorage();
        $storage->start();
        $id = $storage->getId();
        $storage->getBag('attributes')->set('lucky', 7);
        $storage->save();
        $storage->start();
        $this->assertSame($id, $storage->getId(), 'Same session ID after restarting');
        $this->assertSame(7, $storage->getBag('attributes')->get('lucky'), 'Data still available');
    }
}
PKϤ$Z�����Ehttp-foundation/Tests/Session/Storage/MockArraySessionStorageTest.phpnu�[���<?php

/*
 * This file is part of the Symfony package.
 *
 * (c) Fabien Potencier <fabien@symfony.com>
 *
 * For the full copyright and license information, please view the LICENSE
 * file that was distributed with this source code.
 */

namespace Symfony\Component\HttpFoundation\Tests\Session\Storage;

use Symfony\Component\HttpFoundation\Session\Storage\MockArraySessionStorage;
use Symfony\Component\HttpFoundation\Session\Attribute\AttributeBag;
use Symfony\Component\HttpFoundation\Session\Flash\FlashBag;

/**
 * Test class for MockArraySessionStorage.
 *
 * @author Drak <drak@zikula.org>
 */
class MockArraySessionStorageTest extends \PHPUnit_Framework_TestCase
{
    /**
     * @var MockArraySessionStorage
     */
    private $storage;

    /**
     * @var AttributeBag
     */
    private $attributes;

    /**
     * @var FlashBag
     */
    private $flashes;

    private $data;

    protected function setUp()
    {
        $this->attributes = new AttributeBag();
        $this->flashes = new FlashBag();

        $this->data = array(
            $this->attributes->getStorageKey() => array('foo' => 'bar'),
            $this->flashes->getStorageKey() => array('notice' => 'hello'),
            );

        $this->storage = new MockArraySessionStorage();
        $this->storage->registerBag($this->flashes);
        $this->storage->registerBag($this->attributes);
        $this->storage->setSessionData($this->data);
    }

    protected function tearDown()
    {
        $this->data = null;
        $this->flashes = null;
        $this->attributes = null;
        $this->storage = null;
    }

    public function testStart()
    {
        $this->assertEquals('', $this->storage->getId());
        $this->storage->start();
        $id = $this->storage->getId();
        $this->assertNotEquals('', $id);
        $this->storage->start();
        $this->assertEquals($id, $this->storage->getId());
    }

    public function testRegenerate()
    {
        $this->storage->start();
        $id = $this->storage->getId();
        $this->storage->regenerate();
        $this->assertNotEquals($id, $this->storage->getId());
        $this->assertEquals(array('foo' => 'bar'), $this->storage->getBag('attributes')->all());
        $this->assertEquals(array('notice' => 'hello'), $this->storage->getBag('flashes')->peekAll());

        $id = $this->storage->getId();
        $this->storage->regenerate(true);
        $this->assertNotEquals($id, $this->storage->getId());
        $this->assertEquals(array('foo' => 'bar'), $this->storage->getBag('attributes')->all());
        $this->assertEquals(array('notice' => 'hello'), $this->storage->getBag('flashes')->peekAll());
    }

    public function testGetId()
    {
        $this->assertEquals('', $this->storage->getId());
        $this->storage->start();
        $this->assertNotEquals('', $this->storage->getId());
    }

    /**
     * @expectedException \RuntimeException
     */
    public function testUnstartedSave()
    {
        $this->storage->save();
    }
}
PKϤ$Z(��vFhttp-foundation/Tests/Session/Attribute/NamespacedAttributeBagTest.phpnu�[���<?php

/*
 * This file is part of the Symfony package.
 *
 * (c) Fabien Potencier <fabien@symfony.com>
 *
 * For the full copyright and license information, please view the LICENSE
 * file that was distributed with this source code.
 */

namespace Symfony\Component\HttpFoundation\Tests\Session\Attribute;

use Symfony\Component\HttpFoundation\Session\Attribute\NamespacedAttributeBag;

/**
 * Tests NamespacedAttributeBag.
 *
 * @author Drak <drak@zikula.org>
 */
class NamespacedAttributeBagTest extends \PHPUnit_Framework_TestCase
{
    /**
     * @var array
     */
    private $array;

    /**
     * @var NamespacedAttributeBag
     */
    private $bag;

    protected function setUp()
    {
        $this->array = array(
            'hello' => 'world',
            'always' => 'be happy',
            'user.login' => 'drak',
            'csrf.token' => array(
                'a' => '1234',
                'b' => '4321',
            ),
            'category' => array(
                'fishing' => array(
                    'first' => 'cod',
                    'second' => 'sole',
                ),
            ),
        );
        $this->bag = new NamespacedAttributeBag('_sf2', '/');
        $this->bag->initialize($this->array);
    }

    protected function tearDown()
    {
        $this->bag = null;
        $this->array = array();
    }

    public function testInitialize()
    {
        $bag = new NamespacedAttributeBag();
        $bag->initialize($this->array);
        $this->assertEquals($this->array, $this->bag->all());
        $array = array('should' => 'not stick');
        $bag->initialize($array);

        // should have remained the same
        $this->assertEquals($this->array, $this->bag->all());
    }

    public function testGetStorageKey()
    {
        $this->assertEquals('_sf2', $this->bag->getStorageKey());
        $attributeBag = new NamespacedAttributeBag('test');
        $this->assertEquals('test', $attributeBag->getStorageKey());
    }

    /**
     * @dataProvider attributesProvider
     */
    public function testHas($key, $value, $exists)
    {
        $this->assertEquals($exists, $this->bag->has($key));
    }

    /**
     * @dataProvider attributesProvider
     */
    public function testGet($key, $value, $expected)
    {
        $this->assertEquals($value, $this->bag->get($key));
    }

    public function testGetDefaults()
    {
        $this->assertNull($this->bag->get('user2.login'));
        $this->assertEquals('default', $this->bag->get('user2.login', 'default'));
    }

    /**
     * @dataProvider attributesProvider
     */
    public function testSet($key, $value, $expected)
    {
        $this->bag->set($key, $value);
        $this->assertEquals($value, $this->bag->get($key));
    }

    public function testAll()
    {
        $this->assertEquals($this->array, $this->bag->all());

        $this->bag->set('hello', 'fabien');
        $array = $this->array;
        $array['hello'] = 'fabien';
        $this->assertEquals($array, $this->bag->all());
    }

    public function testReplace()
    {
        $array = array();
        $array['name'] = 'jack';
        $array['foo.bar'] = 'beep';
        $this->bag->replace($array);
        $this->assertEquals($array, $this->bag->all());
        $this->assertNull($this->bag->get('hello'));
        $this->assertNull($this->bag->get('always'));
        $this->assertNull($this->bag->get('user.login'));
    }

    public function testRemove()
    {
        $this->assertEquals('world', $this->bag->get('hello'));
        $this->bag->remove('hello');
        $this->assertNull($this->bag->get('hello'));

        $this->assertEquals('be happy', $this->bag->get('always'));
        $this->bag->remove('always');
        $this->assertNull($this->bag->get('always'));

        $this->assertEquals('drak', $this->bag->get('user.login'));
        $this->bag->remove('user.login');
        $this->assertNull($this->bag->get('user.login'));
    }

    public function testRemoveExistingNamespacedAttribute()
    {
        $this->assertSame('cod', $this->bag->remove('category/fishing/first'));
    }

    public function testRemoveNonexistingNamespacedAttribute()
    {
        $this->assertNull($this->bag->remove('foo/bar/baz'));
    }

    public function testClear()
    {
        $this->bag->clear();
        $this->assertEquals(array(), $this->bag->all());
    }

    public function attributesProvider()
    {
        return array(
            array('hello', 'world', true),
            array('always', 'be happy', true),
            array('user.login', 'drak', true),
            array('csrf.token', array('a' => '1234', 'b' => '4321'), true),
            array('csrf.token/a', '1234', true),
            array('csrf.token/b', '4321', true),
            array('category', array('fishing' => array('first' => 'cod', 'second' => 'sole')), true),
            array('category/fishing', array('first' => 'cod', 'second' => 'sole'), true),
            array('category/fishing/missing/first', null, false),
            array('category/fishing/first', 'cod', true),
            array('category/fishing/second', 'sole', true),
            array('category/fishing/missing/second', null, false),
            array('user2.login', null, false),
            array('never', null, false),
            array('bye', null, false),
            array('bye/for/now', null, false),
        );
    }
}
PKϤ$Z9`Lv<http-foundation/Tests/Session/Attribute/AttributeBagTest.phpnu�[���<?php

/*
 * This file is part of the Symfony package.
 *
 * (c) Fabien Potencier <fabien@symfony.com>
 *
 * For the full copyright and license information, please view the LICENSE
 * file that was distributed with this source code.
 */

namespace Symfony\Component\HttpFoundation\Tests\Session\Attribute;

use Symfony\Component\HttpFoundation\Session\Attribute\AttributeBag;

/**
 * Tests AttributeBag.
 *
 * @author Drak <drak@zikula.org>
 */
class AttributeBagTest extends \PHPUnit_Framework_TestCase
{
    /**
     * @var array
     */
    private $array;

    /**
     * @var AttributeBag
     */
    private $bag;

    protected function setUp()
    {
        $this->array = array(
            'hello' => 'world',
            'always' => 'be happy',
            'user.login' => 'drak',
            'csrf.token' => array(
                'a' => '1234',
                'b' => '4321',
            ),
            'category' => array(
                'fishing' => array(
                    'first' => 'cod',
                    'second' => 'sole',
                ),
            ),
        );
        $this->bag = new AttributeBag('_sf2');
        $this->bag->initialize($this->array);
    }

    protected function tearDown()
    {
        $this->bag = null;
        $this->array = array();
    }

    public function testInitialize()
    {
        $bag = new AttributeBag();
        $bag->initialize($this->array);
        $this->assertEquals($this->array, $bag->all());
        $array = array('should' => 'change');
        $bag->initialize($array);
        $this->assertEquals($array, $bag->all());
    }

    public function testGetStorageKey()
    {
        $this->assertEquals('_sf2', $this->bag->getStorageKey());
        $attributeBag = new AttributeBag('test');
        $this->assertEquals('test', $attributeBag->getStorageKey());
    }

    public function testGetSetName()
    {
        $this->assertEquals('attributes', $this->bag->getName());
        $this->bag->setName('foo');
        $this->assertEquals('foo', $this->bag->getName());
    }

    /**
     * @dataProvider attributesProvider
     */
    public function testHas($key, $value, $exists)
    {
        $this->assertEquals($exists, $this->bag->has($key));
    }

    /**
     * @dataProvider attributesProvider
     */
    public function testGet($key, $value, $expected)
    {
        $this->assertEquals($value, $this->bag->get($key));
    }

    public function testGetDefaults()
    {
        $this->assertNull($this->bag->get('user2.login'));
        $this->assertEquals('default', $this->bag->get('user2.login', 'default'));
    }

    /**
     * @dataProvider attributesProvider
     */
    public function testSet($key, $value, $expected)
    {
        $this->bag->set($key, $value);
        $this->assertEquals($value, $this->bag->get($key));
    }

    public function testAll()
    {
        $this->assertEquals($this->array, $this->bag->all());

        $this->bag->set('hello', 'fabien');
        $array = $this->array;
        $array['hello'] = 'fabien';
        $this->assertEquals($array, $this->bag->all());
    }

    public function testReplace()
    {
        $array = array();
        $array['name'] = 'jack';
        $array['foo.bar'] = 'beep';
        $this->bag->replace($array);
        $this->assertEquals($array, $this->bag->all());
        $this->assertNull($this->bag->get('hello'));
        $this->assertNull($this->bag->get('always'));
        $this->assertNull($this->bag->get('user.login'));
    }

    public function testRemove()
    {
        $this->assertEquals('world', $this->bag->get('hello'));
        $this->bag->remove('hello');
        $this->assertNull($this->bag->get('hello'));

        $this->assertEquals('be happy', $this->bag->get('always'));
        $this->bag->remove('always');
        $this->assertNull($this->bag->get('always'));

        $this->assertEquals('drak', $this->bag->get('user.login'));
        $this->bag->remove('user.login');
        $this->assertNull($this->bag->get('user.login'));
    }

    public function testClear()
    {
        $this->bag->clear();
        $this->assertEquals(array(), $this->bag->all());
    }

    public function attributesProvider()
    {
        return array(
            array('hello', 'world', true),
            array('always', 'be happy', true),
            array('user.login', 'drak', true),
            array('csrf.token', array('a' => '1234', 'b' => '4321'), true),
            array('category', array('fishing' => array('first' => 'cod', 'second' => 'sole')), true),
            array('user2.login', null, false),
            array('never', null, false),
            array('bye', null, false),
            array('bye/for/now', null, false),
        );
    }

    public function testGetIterator()
    {
        $i = 0;
        foreach ($this->bag as $key => $val) {
            $this->assertEquals($this->array[$key], $val);
            ++$i;
        }

        $this->assertEquals(count($this->array), $i);
    }

    public function testCount()
    {
        $this->assertEquals(count($this->array), count($this->bag));
    }
}
PKϤ$Z6�-��,http-foundation/Tests/RequestMatcherTest.phpnu�[���<?php

/*
 * This file is part of the Symfony package.
 *
 * (c) Fabien Potencier <fabien@symfony.com>
 *
 * For the full copyright and license information, please view the LICENSE
 * file that was distributed with this source code.
 */

namespace Symfony\Component\HttpFoundation\Tests;

use Symfony\Component\HttpFoundation\RequestMatcher;
use Symfony\Component\HttpFoundation\Request;

class RequestMatcherTest extends \PHPUnit_Framework_TestCase
{
    /**
     * @dataProvider testMethodFixtures
     */
    public function testMethod($requestMethod, $matcherMethod, $isMatch)
    {
        $matcher = new RequestMatcher();
        $matcher->matchMethod($matcherMethod);
        $request = Request::create('', $requestMethod);
        $this->assertSame($isMatch, $matcher->matches($request));

        $matcher = new RequestMatcher(null, null, $matcherMethod);
        $request = Request::create('', $requestMethod);
        $this->assertSame($isMatch, $matcher->matches($request));
    }

    public function testMethodFixtures()
    {
        return array(
            array('get', 'get', true),
            array('get', array('get', 'post'), true),
            array('get', 'post', false),
            array('get', 'GET', true),
            array('get', array('GET', 'POST'), true),
            array('get', 'POST', false),
        );
    }

    public function testScheme()
    {
        $httpRequest = $request = $request = Request::create('');
        $httpsRequest = $request = $request = Request::create('', 'get', array(), array(), array(), array('HTTPS' => 'on'));

        $matcher = new RequestMatcher();
        $matcher->matchScheme('https');
        $this->assertFalse($matcher->matches($httpRequest));
        $this->assertTrue($matcher->matches($httpsRequest));

        $matcher->matchScheme('http');
        $this->assertFalse($matcher->matches($httpsRequest));
        $this->assertTrue($matcher->matches($httpRequest));

        $matcher = new RequestMatcher();
        $this->assertTrue($matcher->matches($httpsRequest));
        $this->assertTrue($matcher->matches($httpRequest));
    }

    /**
     * @dataProvider testHostFixture
     */
    public function testHost($pattern, $isMatch)
    {
        $matcher = new RequestMatcher();
        $request = Request::create('', 'get', array(), array(), array(), array('HTTP_HOST' => 'foo.example.com'));

        $matcher->matchHost($pattern);
        $this->assertSame($isMatch, $matcher->matches($request));

        $matcher = new RequestMatcher(null, $pattern);
        $this->assertSame($isMatch, $matcher->matches($request));
    }

    public function testHostFixture()
    {
        return array(
            array('.*\.example\.com', true),
            array('\.example\.com$', true),
            array('^.*\.example\.com$', true),
            array('.*\.sensio\.com', false),
            array('.*\.example\.COM', true),
            array('\.example\.COM$', true),
            array('^.*\.example\.COM$', true),
            array('.*\.sensio\.COM', false),
        );
    }

    public function testPath()
    {
        $matcher = new RequestMatcher();

        $request = Request::create('/admin/foo');

        $matcher->matchPath('/admin/.*');
        $this->assertTrue($matcher->matches($request));

        $matcher->matchPath('/admin');
        $this->assertTrue($matcher->matches($request));

        $matcher->matchPath('^/admin/.*$');
        $this->assertTrue($matcher->matches($request));

        $matcher->matchMethod('/blog/.*');
        $this->assertFalse($matcher->matches($request));
    }

    public function testPathWithLocaleIsNotSupported()
    {
        $matcher = new RequestMatcher();
        $request = Request::create('/en/login');
        $request->setLocale('en');

        $matcher->matchPath('^/{_locale}/login$');
        $this->assertFalse($matcher->matches($request));
    }

    public function testPathWithEncodedCharacters()
    {
        $matcher = new RequestMatcher();
        $request = Request::create('/admin/fo%20o');
        $matcher->matchPath('^/admin/fo o*$');
        $this->assertTrue($matcher->matches($request));
    }

    public function testAttributes()
    {
        $matcher = new RequestMatcher();

        $request = Request::create('/admin/foo');
        $request->attributes->set('foo', 'foo_bar');

        $matcher->matchAttribute('foo', 'foo_.*');
        $this->assertTrue($matcher->matches($request));

        $matcher->matchAttribute('foo', 'foo');
        $this->assertTrue($matcher->matches($request));

        $matcher->matchAttribute('foo', '^foo_bar$');
        $this->assertTrue($matcher->matches($request));

        $matcher->matchAttribute('foo', 'babar');
        $this->assertFalse($matcher->matches($request));
    }
}
PKϤ$ZY�up55/http-foundation/Tests/File/UploadedFileTest.phpnu�[���<?php

/*
 * This file is part of the Symfony package.
 *
 * (c) Fabien Potencier <fabien@symfony.com>
 *
 * For the full copyright and license information, please view the LICENSE
 * file that was distributed with this source code.
 */

namespace Symfony\Component\HttpFoundation\Tests\File;

use Symfony\Component\HttpFoundation\File\UploadedFile;

class UploadedFileTest extends \PHPUnit_Framework_TestCase
{
    protected function setUp()
    {
        if (!ini_get('file_uploads')) {
            $this->markTestSkipped('file_uploads is disabled in php.ini');
        }
    }

    public function testConstructWhenFileNotExists()
    {
        $this->setExpectedException('Symfony\Component\HttpFoundation\File\Exception\FileNotFoundException');

        new UploadedFile(
            __DIR__.'/Fixtures/not_here',
            'original.gif',
            null
        );
    }

    public function testFileUploadsWithNoMimeType()
    {
        $file = new UploadedFile(
            __DIR__.'/Fixtures/test.gif',
            'original.gif',
            null,
            filesize(__DIR__.'/Fixtures/test.gif'),
            UPLOAD_ERR_OK
        );

        $this->assertEquals('application/octet-stream', $file->getClientMimeType());

        if (extension_loaded('fileinfo')) {
            $this->assertEquals('image/gif', $file->getMimeType());
        }
    }

    public function testFileUploadsWithUnknownMimeType()
    {
        $file = new UploadedFile(
            __DIR__.'/Fixtures/.unknownextension',
            'original.gif',
            null,
            filesize(__DIR__.'/Fixtures/.unknownextension'),
            UPLOAD_ERR_OK
        );

        $this->assertEquals('application/octet-stream', $file->getClientMimeType());
    }

    public function testGuessClientExtension()
    {
        $file = new UploadedFile(
            __DIR__.'/Fixtures/test.gif',
            'original.gif',
            'image/gif',
            filesize(__DIR__.'/Fixtures/test.gif'),
            null
        );

        $this->assertEquals('gif', $file->guessClientExtension());
    }

    public function testGuessClientExtensionWithIncorrectMimeType()
    {
        $file = new UploadedFile(
            __DIR__.'/Fixtures/test.gif',
            'original.gif',
            'image/jpeg',
            filesize(__DIR__.'/Fixtures/test.gif'),
            null
        );

        $this->assertEquals('jpeg', $file->guessClientExtension());
    }

    public function testErrorIsOkByDefault()
    {
        $file = new UploadedFile(
            __DIR__.'/Fixtures/test.gif',
            'original.gif',
            'image/gif',
            filesize(__DIR__.'/Fixtures/test.gif'),
            null
        );

        $this->assertEquals(UPLOAD_ERR_OK, $file->getError());
    }

    public function testGetClientOriginalName()
    {
        $file = new UploadedFile(
            __DIR__.'/Fixtures/test.gif',
            'original.gif',
            'image/gif',
            filesize(__DIR__.'/Fixtures/test.gif'),
            null
        );

        $this->assertEquals('original.gif', $file->getClientOriginalName());
    }

    public function testGetClientOriginalExtension()
    {
        $file = new UploadedFile(
            __DIR__.'/Fixtures/test.gif',
            'original.gif',
            'image/gif',
            filesize(__DIR__.'/Fixtures/test.gif'),
            null
        );

        $this->assertEquals('gif', $file->getClientOriginalExtension());
    }

    /**
     * @expectedException \Symfony\Component\HttpFoundation\File\Exception\FileException
     */
    public function testMoveLocalFileIsNotAllowed()
    {
        $file = new UploadedFile(
            __DIR__.'/Fixtures/test.gif',
            'original.gif',
            'image/gif',
            filesize(__DIR__.'/Fixtures/test.gif'),
            UPLOAD_ERR_OK
        );

        $movedFile = $file->move(__DIR__.'/Fixtures/directory');
    }

    public function testMoveLocalFileIsAllowedInTestMode()
    {
        $path = __DIR__.'/Fixtures/test.copy.gif';
        $targetDir = __DIR__.'/Fixtures/directory';
        $targetPath = $targetDir.'/test.copy.gif';
        @unlink($path);
        @unlink($targetPath);
        copy(__DIR__.'/Fixtures/test.gif', $path);

        $file = new UploadedFile(
            $path,
            'original.gif',
            'image/gif',
            filesize($path),
            UPLOAD_ERR_OK,
            true
        );

        $movedFile = $file->move(__DIR__.'/Fixtures/directory');

        $this->assertFileExists($targetPath);
        $this->assertFileNotExists($path);
        $this->assertEquals(realpath($targetPath), $movedFile->getRealPath());

        @unlink($targetPath);
    }

    public function testGetClientOriginalNameSanitizeFilename()
    {
        $file = new UploadedFile(
            __DIR__.'/Fixtures/test.gif',
            '../../original.gif',
            'image/gif',
            filesize(__DIR__.'/Fixtures/test.gif'),
            null
        );

        $this->assertEquals('original.gif', $file->getClientOriginalName());
    }

    public function testGetSize()
    {
        $file = new UploadedFile(
            __DIR__.'/Fixtures/test.gif',
            'original.gif',
            'image/gif',
            filesize(__DIR__.'/Fixtures/test.gif'),
            null
        );

        $this->assertEquals(filesize(__DIR__.'/Fixtures/test.gif'), $file->getSize());

        $file = new UploadedFile(
            __DIR__.'/Fixtures/test',
            'original.gif',
            'image/gif'
        );

        $this->assertEquals(filesize(__DIR__.'/Fixtures/test'), $file->getSize());
    }

    public function testGetExtension()
    {
        $file = new UploadedFile(
            __DIR__.'/Fixtures/test.gif',
            'original.gif',
            null
        );

        $this->assertEquals('gif', $file->getExtension());
    }

    public function testIsValid()
    {
        $file = new UploadedFile(
            __DIR__.'/Fixtures/test.gif',
            'original.gif',
            null,
            filesize(__DIR__.'/Fixtures/test.gif'),
            UPLOAD_ERR_OK,
            true
        );

        $this->assertTrue($file->isValid());
    }

    /**
     * @dataProvider uploadedFileErrorProvider
     */
    public function testIsInvalidOnUploadError($error)
    {
        $file = new UploadedFile(
            __DIR__.'/Fixtures/test.gif',
            'original.gif',
            null,
            filesize(__DIR__.'/Fixtures/test.gif'),
            $error
        );

        $this->assertFalse($file->isValid());
    }

    public function uploadedFileErrorProvider()
    {
        return array(
            array(UPLOAD_ERR_INI_SIZE),
            array(UPLOAD_ERR_FORM_SIZE),
            array(UPLOAD_ERR_PARTIAL),
            array(UPLOAD_ERR_NO_TMP_DIR),
            array(UPLOAD_ERR_EXTENSION),
        );
    }

    public function testIsInvalidIfNotHttpUpload()
    {
        $file = new UploadedFile(
            __DIR__.'/Fixtures/test.gif',
            'original.gif',
            null,
            filesize(__DIR__.'/Fixtures/test.gif'),
            UPLOAD_ERR_OK
        );

        $this->assertFalse($file->isValid());
    }
}
PKϤ$Z��4c00'http-foundation/Tests/File/FileTest.phpnu�[���<?php

/*
 * This file is part of the Symfony package.
 *
 * (c) Fabien Potencier <fabien@symfony.com>
 *
 * For the full copyright and license information, please view the LICENSE
 * file that was distributed with this source code.
 */

namespace Symfony\Component\HttpFoundation\Tests\File;

use Symfony\Component\HttpFoundation\File\File;
use Symfony\Component\HttpFoundation\File\MimeType\MimeTypeGuesser;

class FileTest extends \PHPUnit_Framework_TestCase
{
    protected $file;

    public function testGetMimeTypeUsesMimeTypeGuessers()
    {
        $file = new File(__DIR__.'/Fixtures/test.gif');
        $guesser = $this->createMockGuesser($file->getPathname(), 'image/gif');

        MimeTypeGuesser::getInstance()->register($guesser);

        $this->assertEquals('image/gif', $file->getMimeType());
    }

    public function testGuessExtensionWithoutGuesser()
    {
        $file = new File(__DIR__.'/Fixtures/directory/.empty');

        $this->assertNull($file->guessExtension());
    }

    public function testGuessExtensionIsBasedOnMimeType()
    {
        $file = new File(__DIR__.'/Fixtures/test');
        $guesser = $this->createMockGuesser($file->getPathname(), 'image/gif');

        MimeTypeGuesser::getInstance()->register($guesser);

        $this->assertEquals('gif', $file->guessExtension());
    }

    /**
     * @requires extension fileinfo
     */
    public function testGuessExtensionWithReset()
    {
        $file = new File(__DIR__.'/Fixtures/other-file.example');
        $guesser = $this->createMockGuesser($file->getPathname(), 'image/gif');
        MimeTypeGuesser::getInstance()->register($guesser);

        $this->assertEquals('gif', $file->guessExtension());

        MimeTypeGuesser::reset();

        $this->assertNull($file->guessExtension());
    }

    public function testConstructWhenFileNotExists()
    {
        $this->setExpectedException('Symfony\Component\HttpFoundation\File\Exception\FileNotFoundException');

        new File(__DIR__.'/Fixtures/not_here');
    }

    public function testMove()
    {
        $path = __DIR__.'/Fixtures/test.copy.gif';
        $targetDir = __DIR__.'/Fixtures/directory';
        $targetPath = $targetDir.'/test.copy.gif';
        @unlink($path);
        @unlink($targetPath);
        copy(__DIR__.'/Fixtures/test.gif', $path);

        $file = new File($path);
        $movedFile = $file->move($targetDir);
        $this->assertInstanceOf('Symfony\Component\HttpFoundation\File\File', $movedFile);

        $this->assertFileExists($targetPath);
        $this->assertFileNotExists($path);
        $this->assertEquals(realpath($targetPath), $movedFile->getRealPath());

        @unlink($targetPath);
    }

    public function testMoveWithNewName()
    {
        $path = __DIR__.'/Fixtures/test.copy.gif';
        $targetDir = __DIR__.'/Fixtures/directory';
        $targetPath = $targetDir.'/test.newname.gif';
        @unlink($path);
        @unlink($targetPath);
        copy(__DIR__.'/Fixtures/test.gif', $path);

        $file = new File($path);
        $movedFile = $file->move($targetDir, 'test.newname.gif');

        $this->assertFileExists($targetPath);
        $this->assertFileNotExists($path);
        $this->assertEquals(realpath($targetPath), $movedFile->getRealPath());

        @unlink($targetPath);
    }

    public function getFilenameFixtures()
    {
        return array(
            array('original.gif', 'original.gif'),
            array('..\\..\\original.gif', 'original.gif'),
            array('../../original.gif', 'original.gif'),
            array('файлfile.gif', 'файлfile.gif'),
            array('..\\..\\файлfile.gif', 'файлfile.gif'),
            array('../../файлfile.gif', 'файлfile.gif'),
        );
    }

    /**
     * @dataProvider getFilenameFixtures
     */
    public function testMoveWithNonLatinName($filename, $sanitizedFilename)
    {
        $path = __DIR__.'/Fixtures/'.$sanitizedFilename;
        $targetDir = __DIR__.'/Fixtures/directory/';
        $targetPath = $targetDir.$sanitizedFilename;
        @unlink($path);
        @unlink($targetPath);
        copy(__DIR__.'/Fixtures/test.gif', $path);

        $file = new File($path);
        $movedFile = $file->move($targetDir, $filename);
        $this->assertInstanceOf('Symfony\Component\HttpFoundation\File\File', $movedFile);

        $this->assertFileExists($targetPath);
        $this->assertFileNotExists($path);
        $this->assertEquals(realpath($targetPath), $movedFile->getRealPath());

        @unlink($targetPath);
    }

    public function testMoveToAnUnexistentDirectory()
    {
        $sourcePath = __DIR__.'/Fixtures/test.copy.gif';
        $targetDir = __DIR__.'/Fixtures/directory/sub';
        $targetPath = $targetDir.'/test.copy.gif';
        @unlink($sourcePath);
        @unlink($targetPath);
        @rmdir($targetDir);
        copy(__DIR__.'/Fixtures/test.gif', $sourcePath);

        $file = new File($sourcePath);
        $movedFile = $file->move($targetDir);

        $this->assertFileExists($targetPath);
        $this->assertFileNotExists($sourcePath);
        $this->assertEquals(realpath($targetPath), $movedFile->getRealPath());

        @unlink($sourcePath);
        @unlink($targetPath);
        @rmdir($targetDir);
    }

    protected function createMockGuesser($path, $mimeType)
    {
        $guesser = $this->getMock('Symfony\Component\HttpFoundation\File\MimeType\MimeTypeGuesserInterface');
        $guesser
            ->expects($this->once())
            ->method('guess')
            ->with($this->equalTo($path))
            ->will($this->returnValue($mimeType))
        ;

        return $guesser;
    }
}
PKϤ$Z�n+�@@'http-foundation/Tests/File/FakeFile.phpnu�[���<?php

/*
 * This file is part of the Symfony package.
 *
 * (c) Fabien Potencier <fabien@symfony.com>
 *
 * For the full copyright and license information, please view the LICENSE
 * file that was distributed with this source code.
 */

namespace Symfony\Component\HttpFoundation\Tests\File;

use Symfony\Component\HttpFoundation\File\File as OrigFile;

class FakeFile extends OrigFile
{
    private $realpath;

    public function __construct($realpath, $path)
    {
        $this->realpath = $realpath;
        parent::__construct($path, false);
    }

    public function isReadable()
    {
        return true;
    }

    public function getRealpath()
    {
        return $this->realpath;
    }

    public function getSize()
    {
        return 42;
    }

    public function getMTime()
    {
        return time();
    }
}
PKϤ$Z�/#��4http-foundation/Tests/File/MimeType/MimeTypeTest.phpnu�[���<?php

/*
 * This file is part of the Symfony package.
 *
 * (c) Fabien Potencier <fabien@symfony.com>
 *
 * For the full copyright and license information, please view the LICENSE
 * file that was distributed with this source code.
 */

namespace Symfony\Component\HttpFoundation\Tests\File\MimeType;

use Symfony\Component\HttpFoundation\File\MimeType\MimeTypeGuesser;
use Symfony\Component\HttpFoundation\File\MimeType\FileBinaryMimeTypeGuesser;

/**
 * @requires extension fileinfo
 */
class MimeTypeTest extends \PHPUnit_Framework_TestCase
{
    protected $path;

    public function testGuessImageWithoutExtension()
    {
        $this->assertEquals('image/gif', MimeTypeGuesser::getInstance()->guess(__DIR__.'/../Fixtures/test'));
    }

    public function testGuessImageWithDirectory()
    {
        $this->setExpectedException('Symfony\Component\HttpFoundation\File\Exception\FileNotFoundException');

        MimeTypeGuesser::getInstance()->guess(__DIR__.'/../Fixtures/directory');
    }

    public function testGuessImageWithFileBinaryMimeTypeGuesser()
    {
        $guesser = MimeTypeGuesser::getInstance();
        $guesser->register(new FileBinaryMimeTypeGuesser());
        $this->assertEquals('image/gif', MimeTypeGuesser::getInstance()->guess(__DIR__.'/../Fixtures/test'));
    }

    public function testGuessImageWithKnownExtension()
    {
        $this->assertEquals('image/gif', MimeTypeGuesser::getInstance()->guess(__DIR__.'/../Fixtures/test.gif'));
    }

    public function testGuessFileWithUnknownExtension()
    {
        $this->assertEquals('application/octet-stream', MimeTypeGuesser::getInstance()->guess(__DIR__.'/../Fixtures/.unknownextension'));
    }

    public function testGuessWithIncorrectPath()
    {
        $this->setExpectedException('Symfony\Component\HttpFoundation\File\Exception\FileNotFoundException');
        MimeTypeGuesser::getInstance()->guess(__DIR__.'/../Fixtures/not_here');
    }

    public function testGuessWithNonReadablePath()
    {
        if ('\\' === DIRECTORY_SEPARATOR) {
            $this->markTestSkipped('Can not verify chmod operations on Windows');
        }

        if (!getenv('USER') || 'root' === getenv('USER')) {
            $this->markTestSkipped('This test will fail if run under superuser');
        }

        $path = __DIR__.'/../Fixtures/to_delete';
        touch($path);
        @chmod($path, 0333);

        if (substr(sprintf('%o', fileperms($path)), -4) == '0333') {
            $this->setExpectedException('Symfony\Component\HttpFoundation\File\Exception\AccessDeniedException');
            MimeTypeGuesser::getInstance()->guess($path);
        } else {
            $this->markTestSkipped('Can not verify chmod operations, change of file permissions failed');
        }
    }

    public static function tearDownAfterClass()
    {
        $path = __DIR__.'/../Fixtures/to_delete';
        if (file_exists($path)) {
            @chmod($path, 0666);
            @unlink($path);
        }
    }
}
PKϤ$Z�+�v5http-foundation/Tests/File/Fixtures/.unknownextensionnu�[���fPKϤ$Z��܏##,http-foundation/Tests/File/Fixtures/test.gifnu�[���GIF87a�������,D;PKϤ$Z6http-foundation/Tests/File/Fixtures/other-file.examplenu�[���PKϤ$Z4http-foundation/Tests/File/Fixtures/directory/.emptynu�[���PKϤ$Z�y���'http-foundation/Tests/HeaderBagTest.phpnu�[���<?php

/*
 * This file is part of the Symfony package.
 *
 * (c) Fabien Potencier <fabien@symfony.com>
 *
 * For the full copyright and license information, please view the LICENSE
 * file that was distributed with this source code.
 */

namespace Symfony\Component\HttpFoundation\Tests;

use Symfony\Component\HttpFoundation\HeaderBag;

class HeaderBagTest extends \PHPUnit_Framework_TestCase
{
    public function testConstructor()
    {
        $bag = new HeaderBag(array('foo' => 'bar'));
        $this->assertTrue($bag->has('foo'));
    }

    public function testToStringNull()
    {
        $bag = new HeaderBag();
        $this->assertEquals('', $bag->__toString());
    }

    public function testToStringNotNull()
    {
        $bag = new HeaderBag(array('foo' => 'bar'));
        $this->assertEquals("Foo: bar\r\n", $bag->__toString());
    }

    public function testKeys()
    {
        $bag = new HeaderBag(array('foo' => 'bar'));
        $keys = $bag->keys();
        $this->assertEquals('foo', $keys[0]);
    }

    public function testGetDate()
    {
        $bag = new HeaderBag(array('foo' => 'Tue, 4 Sep 2012 20:00:00 +0200'));
        $headerDate = $bag->getDate('foo');
        $this->assertInstanceOf('DateTime', $headerDate);
    }

    /**
     * @expectedException \RuntimeException
     */
    public function testGetDateException()
    {
        $bag = new HeaderBag(array('foo' => 'Tue'));
        $headerDate = $bag->getDate('foo');
    }

    public function testGetCacheControlHeader()
    {
        $bag = new HeaderBag();
        $bag->addCacheControlDirective('public', '#a');
        $this->assertTrue($bag->hasCacheControlDirective('public'));
        $this->assertEquals('#a', $bag->getCacheControlDirective('public'));
    }

    public function testAll()
    {
        $bag = new HeaderBag(array('foo' => 'bar'));
        $this->assertEquals(array('foo' => array('bar')), $bag->all(), '->all() gets all the input');

        $bag = new HeaderBag(array('FOO' => 'BAR'));
        $this->assertEquals(array('foo' => array('BAR')), $bag->all(), '->all() gets all the input key are lower case');
    }

    public function testReplace()
    {
        $bag = new HeaderBag(array('foo' => 'bar'));

        $bag->replace(array('NOPE' => 'BAR'));
        $this->assertEquals(array('nope' => array('BAR')), $bag->all(), '->replace() replaces the input with the argument');
        $this->assertFalse($bag->has('foo'), '->replace() overrides previously set the input');
    }

    public function testGet()
    {
        $bag = new HeaderBag(array('foo' => 'bar', 'fuzz' => 'bizz'));
        $this->assertEquals('bar', $bag->get('foo'), '->get return current value');
        $this->assertEquals('bar', $bag->get('FoO'), '->get key in case insensitive');
        $this->assertEquals(array('bar'), $bag->get('foo', 'nope', false), '->get return the value as array');

        // defaults
        $this->assertNull($bag->get('none'), '->get unknown values returns null');
        $this->assertEquals('default', $bag->get('none', 'default'), '->get unknown values returns default');
        $this->assertEquals(array('default'), $bag->get('none', 'default', false), '->get unknown values returns default as array');

        $bag->set('foo', 'bor', false);
        $this->assertEquals('bar', $bag->get('foo'), '->get return first value');
        $this->assertEquals(array('bar', 'bor'), $bag->get('foo', 'nope', false), '->get return all values as array');
    }

    public function testSetAssociativeArray()
    {
        $bag = new HeaderBag();
        $bag->set('foo', array('bad-assoc-index' => 'value'));
        $this->assertSame('value', $bag->get('foo'));
        $this->assertEquals(array('value'), $bag->get('foo', 'nope', false), 'assoc indices of multi-valued headers are ignored');
    }

    public function testContains()
    {
        $bag = new HeaderBag(array('foo' => 'bar', 'fuzz' => 'bizz'));
        $this->assertTrue($bag->contains('foo', 'bar'), '->contains first value');
        $this->assertTrue($bag->contains('fuzz', 'bizz'), '->contains second value');
        $this->assertFalse($bag->contains('nope', 'nope'), '->contains unknown value');
        $this->assertFalse($bag->contains('foo', 'nope'), '->contains unknown value');

        // Multiple values
        $bag->set('foo', 'bor', false);
        $this->assertTrue($bag->contains('foo', 'bar'), '->contains first value');
        $this->assertTrue($bag->contains('foo', 'bor'), '->contains second value');
        $this->assertFalse($bag->contains('foo', 'nope'), '->contains unknown value');
    }

    public function testCacheControlDirectiveAccessors()
    {
        $bag = new HeaderBag();
        $bag->addCacheControlDirective('public');

        $this->assertTrue($bag->hasCacheControlDirective('public'));
        $this->assertTrue($bag->getCacheControlDirective('public'));
        $this->assertEquals('public', $bag->get('cache-control'));

        $bag->addCacheControlDirective('max-age', 10);
        $this->assertTrue($bag->hasCacheControlDirective('max-age'));
        $this->assertEquals(10, $bag->getCacheControlDirective('max-age'));
        $this->assertEquals('max-age=10, public', $bag->get('cache-control'));

        $bag->removeCacheControlDirective('max-age');
        $this->assertFalse($bag->hasCacheControlDirective('max-age'));
    }

    public function testCacheControlDirectiveParsing()
    {
        $bag = new HeaderBag(array('cache-control' => 'public, max-age=10'));
        $this->assertTrue($bag->hasCacheControlDirective('public'));
        $this->assertTrue($bag->getCacheControlDirective('public'));

        $this->assertTrue($bag->hasCacheControlDirective('max-age'));
        $this->assertEquals(10, $bag->getCacheControlDirective('max-age'));

        $bag->addCacheControlDirective('s-maxage', 100);
        $this->assertEquals('max-age=10, public, s-maxage=100', $bag->get('cache-control'));
    }

    public function testCacheControlDirectiveParsingQuotedZero()
    {
        $bag = new HeaderBag(array('cache-control' => 'max-age="0"'));
        $this->assertTrue($bag->hasCacheControlDirective('max-age'));
        $this->assertEquals(0, $bag->getCacheControlDirective('max-age'));
    }

    public function testCacheControlDirectiveOverrideWithReplace()
    {
        $bag = new HeaderBag(array('cache-control' => 'private, max-age=100'));
        $bag->replace(array('cache-control' => 'public, max-age=10'));
        $this->assertTrue($bag->hasCacheControlDirective('public'));
        $this->assertTrue($bag->getCacheControlDirective('public'));

        $this->assertTrue($bag->hasCacheControlDirective('max-age'));
        $this->assertEquals(10, $bag->getCacheControlDirective('max-age'));
    }

    public function testGetIterator()
    {
        $headers = array('foo' => 'bar', 'hello' => 'world', 'third' => 'charm');
        $headerBag = new HeaderBag($headers);

        $i = 0;
        foreach ($headerBag as $key => $val) {
            ++$i;
            $this->assertEquals(array($headers[$key]), $val);
        }

        $this->assertEquals(count($headers), $i);
    }

    public function testCount()
    {
        $headers = array('foo' => 'bar', 'HELLO' => 'WORLD');
        $headerBag = new HeaderBag($headers);

        $this->assertEquals(count($headers), count($headerBag));
    }
}
PKϤ$Z�+߶� � *http-foundation/Tests/ParameterBagTest.phpnu�[���<?php

/*
 * This file is part of the Symfony package.
 *
 * (c) Fabien Potencier <fabien@symfony.com>
 *
 * For the full copyright and license information, please view the LICENSE
 * file that was distributed with this source code.
 */

namespace Symfony\Component\HttpFoundation\Tests;

use Symfony\Component\HttpFoundation\ParameterBag;

class ParameterBagTest extends \PHPUnit_Framework_TestCase
{
    public function testConstructor()
    {
        $this->testAll();
    }

    public function testAll()
    {
        $bag = new ParameterBag(array('foo' => 'bar'));
        $this->assertEquals(array('foo' => 'bar'), $bag->all(), '->all() gets all the input');
    }

    public function testKeys()
    {
        $bag = new ParameterBag(array('foo' => 'bar'));
        $this->assertEquals(array('foo'), $bag->keys());
    }

    public function testAdd()
    {
        $bag = new ParameterBag(array('foo' => 'bar'));
        $bag->add(array('bar' => 'bas'));
        $this->assertEquals(array('foo' => 'bar', 'bar' => 'bas'), $bag->all());
    }

    public function testRemove()
    {
        $bag = new ParameterBag(array('foo' => 'bar'));
        $bag->add(array('bar' => 'bas'));
        $this->assertEquals(array('foo' => 'bar', 'bar' => 'bas'), $bag->all());
        $bag->remove('bar');
        $this->assertEquals(array('foo' => 'bar'), $bag->all());
    }

    public function testReplace()
    {
        $bag = new ParameterBag(array('foo' => 'bar'));

        $bag->replace(array('FOO' => 'BAR'));
        $this->assertEquals(array('FOO' => 'BAR'), $bag->all(), '->replace() replaces the input with the argument');
        $this->assertFalse($bag->has('foo'), '->replace() overrides previously set the input');
    }

    public function testGet()
    {
        $bag = new ParameterBag(array('foo' => 'bar', 'null' => null));

        $this->assertEquals('bar', $bag->get('foo'), '->get() gets the value of a parameter');
        $this->assertEquals('default', $bag->get('unknown', 'default'), '->get() returns second argument as default if a parameter is not defined');
        $this->assertNull($bag->get('null', 'default'), '->get() returns null if null is set');
    }

    public function testGetDoesNotUseDeepByDefault()
    {
        $bag = new ParameterBag(array('foo' => array('bar' => 'moo')));

        $this->assertNull($bag->get('foo[bar]'));
    }

    /**
     * @group legacy
     * @dataProvider getInvalidPaths
     * @expectedException \InvalidArgumentException
     */
    public function testGetDeepWithInvalidPaths($path)
    {
        $bag = new ParameterBag(array('foo' => array('bar' => 'moo')));

        $bag->get($path, null, true);
    }

    public function getInvalidPaths()
    {
        return array(
            array('foo[['),
            array('foo[d'),
            array('foo[bar]]'),
            array('foo[bar]d'),
        );
    }

    /**
     * @group legacy
     */
    public function testGetDeep()
    {
        $bag = new ParameterBag(array('foo' => array('bar' => array('moo' => 'boo'))));

        $this->assertEquals(array('moo' => 'boo'), $bag->get('foo[bar]', null, true));
        $this->assertEquals('boo', $bag->get('foo[bar][moo]', null, true));
        $this->assertEquals('default', $bag->get('foo[bar][foo]', 'default', true));
        $this->assertEquals('default', $bag->get('bar[moo][foo]', 'default', true));
    }

    public function testSet()
    {
        $bag = new ParameterBag(array());

        $bag->set('foo', 'bar');
        $this->assertEquals('bar', $bag->get('foo'), '->set() sets the value of parameter');

        $bag->set('foo', 'baz');
        $this->assertEquals('baz', $bag->get('foo'), '->set() overrides previously set parameter');
    }

    public function testHas()
    {
        $bag = new ParameterBag(array('foo' => 'bar'));

        $this->assertTrue($bag->has('foo'), '->has() returns true if a parameter is defined');
        $this->assertFalse($bag->has('unknown'), '->has() return false if a parameter is not defined');
    }

    public function testGetAlpha()
    {
        $bag = new ParameterBag(array('word' => 'foo_BAR_012'));

        $this->assertEquals('fooBAR', $bag->getAlpha('word'), '->getAlpha() gets only alphabetic characters');
        $this->assertEquals('', $bag->getAlpha('unknown'), '->getAlpha() returns empty string if a parameter is not defined');
    }

    public function testGetAlnum()
    {
        $bag = new ParameterBag(array('word' => 'foo_BAR_012'));

        $this->assertEquals('fooBAR012', $bag->getAlnum('word'), '->getAlnum() gets only alphanumeric characters');
        $this->assertEquals('', $bag->getAlnum('unknown'), '->getAlnum() returns empty string if a parameter is not defined');
    }

    public function testGetDigits()
    {
        $bag = new ParameterBag(array('word' => 'foo_BAR_012'));

        $this->assertEquals('012', $bag->getDigits('word'), '->getDigits() gets only digits as string');
        $this->assertEquals('', $bag->getDigits('unknown'), '->getDigits() returns empty string if a parameter is not defined');
    }

    public function testGetInt()
    {
        $bag = new ParameterBag(array('digits' => '0123'));

        $this->assertEquals(123, $bag->getInt('digits'), '->getInt() gets a value of parameter as integer');
        $this->assertEquals(0, $bag->getInt('unknown'), '->getInt() returns zero if a parameter is not defined');
    }

    public function testFilter()
    {
        $bag = new ParameterBag(array(
            'digits' => '0123ab',
            'email' => 'example@example.com',
            'url' => 'http://example.com/foo',
            'dec' => '256',
            'hex' => '0x100',
            'array' => array('bang'),
            ));

        $this->assertEmpty($bag->filter('nokey'), '->filter() should return empty by default if no key is found');

        $this->assertEquals('0123', $bag->filter('digits', '', FILTER_SANITIZE_NUMBER_INT), '->filter() gets a value of parameter as integer filtering out invalid characters');

        $this->assertEquals('example@example.com', $bag->filter('email', '', FILTER_VALIDATE_EMAIL), '->filter() gets a value of parameter as email');

        $this->assertEquals('http://example.com/foo', $bag->filter('url', '', FILTER_VALIDATE_URL, array('flags' => FILTER_FLAG_PATH_REQUIRED)), '->filter() gets a value of parameter as URL with a path');

        // This test is repeated for code-coverage
        $this->assertEquals('http://example.com/foo', $bag->filter('url', '', FILTER_VALIDATE_URL, FILTER_FLAG_PATH_REQUIRED), '->filter() gets a value of parameter as URL with a path');

        $this->assertFalse($bag->filter('dec', '', FILTER_VALIDATE_INT, array(
            'flags' => FILTER_FLAG_ALLOW_HEX,
            'options' => array('min_range' => 1, 'max_range' => 0xff),
        )), '->filter() gets a value of parameter as integer between boundaries');

        $this->assertFalse($bag->filter('hex', '', FILTER_VALIDATE_INT, array(
            'flags' => FILTER_FLAG_ALLOW_HEX,
            'options' => array('min_range' => 1, 'max_range' => 0xff),
        )), '->filter() gets a value of parameter as integer between boundaries');

        $this->assertEquals(array('bang'), $bag->filter('array', ''), '->filter() gets a value of parameter as an array');
    }

    public function testGetIterator()
    {
        $parameters = array('foo' => 'bar', 'hello' => 'world');
        $bag = new ParameterBag($parameters);

        $i = 0;
        foreach ($bag as $key => $val) {
            ++$i;
            $this->assertEquals($parameters[$key], $val);
        }

        $this->assertEquals(count($parameters), $i);
    }

    public function testCount()
    {
        $parameters = array('foo' => 'bar', 'hello' => 'world');
        $bag = new ParameterBag($parameters);

        $this->assertEquals(count($parameters), count($bag));
    }

    public function testGetBoolean()
    {
        $parameters = array('string_true' => 'true', 'string_false' => 'false');
        $bag = new ParameterBag($parameters);

        $this->assertTrue($bag->getBoolean('string_true'), '->getBoolean() gets the string true as boolean true');
        $this->assertFalse($bag->getBoolean('string_false'), '->getBoolean() gets the string false as boolean false');
        $this->assertFalse($bag->getBoolean('unknown'), '->getBoolean() returns false if a parameter is not defined');
    }
}
PKϤ$Z�&���%http-foundation/Tests/IpUtilsTest.phpnu�[���<?php

/*
 * This file is part of the Symfony package.
 *
 * (c) Fabien Potencier <fabien@symfony.com>
 *
 * For the full copyright and license information, please view the LICENSE
 * file that was distributed with this source code.
 */

namespace Symfony\Component\HttpFoundation\Tests;

use Symfony\Component\HttpFoundation\IpUtils;

class IpUtilsTest extends \PHPUnit_Framework_TestCase
{
    /**
     * @dataProvider testIpv4Provider
     */
    public function testIpv4($matches, $remoteAddr, $cidr)
    {
        $this->assertSame($matches, IpUtils::checkIp($remoteAddr, $cidr));
    }

    public function testIpv4Provider()
    {
        return array(
            array(true, '192.168.1.1', '192.168.1.1'),
            array(true, '192.168.1.1', '192.168.1.1/1'),
            array(true, '192.168.1.1', '192.168.1.0/24'),
            array(false, '192.168.1.1', '1.2.3.4/1'),
            array(false, '192.168.1.1', '192.168.1.1/33'), // invalid subnet
            array(true, '192.168.1.1', array('1.2.3.4/1', '192.168.1.0/24')),
            array(true, '192.168.1.1', array('192.168.1.0/24', '1.2.3.4/1')),
            array(false, '192.168.1.1', array('1.2.3.4/1', '4.3.2.1/1')),
            array(true, '1.2.3.4', '0.0.0.0/0'),
            array(true, '1.2.3.4', '192.168.1.0/0'),
            array(false, '1.2.3.4', '256.256.256/0'), // invalid CIDR notation
        );
    }

    /**
     * @dataProvider testIpv6Provider
     */
    public function testIpv6($matches, $remoteAddr, $cidr)
    {
        if (!defined('AF_INET6')) {
            $this->markTestSkipped('Only works when PHP is compiled without the option "disable-ipv6".');
        }

        $this->assertSame($matches, IpUtils::checkIp($remoteAddr, $cidr));
    }

    public function testIpv6Provider()
    {
        return array(
            array(true, '2a01:198:603:0:396e:4789:8e99:890f', '2a01:198:603:0::/65'),
            array(false, '2a00:198:603:0:396e:4789:8e99:890f', '2a01:198:603:0::/65'),
            array(false, '2a01:198:603:0:396e:4789:8e99:890f', '::1'),
            array(true, '0:0:0:0:0:0:0:1', '::1'),
            array(false, '0:0:603:0:396e:4789:8e99:0001', '::1'),
            array(true, '2a01:198:603:0:396e:4789:8e99:890f', array('::1', '2a01:198:603:0::/65')),
            array(true, '2a01:198:603:0:396e:4789:8e99:890f', array('2a01:198:603:0::/65', '::1')),
            array(false, '2a01:198:603:0:396e:4789:8e99:890f', array('::1', '1a01:198:603:0::/65')),
            array(false, '}__test|O:21:&quot;JDatabaseDriverMysqli&quot;:3:{s:2', '::1'),
            array(false, '2a01:198:603:0:396e:4789:8e99:890f', 'unknown'),
        );
    }

    /**
     * @expectedException \RuntimeException
     * @requires extension sockets
     */
    public function testAnIpv6WithOptionDisabledIpv6()
    {
        if (defined('AF_INET6')) {
            $this->markTestSkipped('Only works when PHP is compiled with the option "disable-ipv6".');
        }

        IpUtils::checkIp('2a01:198:603:0:396e:4789:8e99:890f', '2a01:198:603:0::/65');
    }
}
PKϤ$ZZV�K~K~&http-foundation/Tests/ResponseTest.phpnu�[���<?php

/*
 * This file is part of the Symfony package.
 *
 * (c) Fabien Potencier <fabien@symfony.com>
 *
 * For the full copyright and license information, please view the LICENSE
 * file that was distributed with this source code.
 */

namespace Symfony\Component\HttpFoundation\Tests;

use Symfony\Component\HttpFoundation\Request;
use Symfony\Component\HttpFoundation\Response;

/**
 * @group time-sensitive
 */
class ResponseTest extends ResponseTestCase
{
    public function testCreate()
    {
        $response = Response::create('foo', 301, array('Foo' => 'bar'));

        $this->assertInstanceOf('Symfony\Component\HttpFoundation\Response', $response);
        $this->assertEquals(301, $response->getStatusCode());
        $this->assertEquals('bar', $response->headers->get('foo'));
    }

    public function testToString()
    {
        $response = new Response();
        $response = explode("\r\n", $response);
        $this->assertEquals('HTTP/1.0 200 OK', $response[0]);
        $this->assertEquals('Cache-Control: no-cache', $response[1]);
    }

    public function testClone()
    {
        $response = new Response();
        $responseClone = clone $response;
        $this->assertEquals($response, $responseClone);
    }

    public function testSendHeaders()
    {
        $response = new Response();
        $headers = $response->sendHeaders();
        $this->assertObjectHasAttribute('headers', $headers);
        $this->assertObjectHasAttribute('content', $headers);
        $this->assertObjectHasAttribute('version', $headers);
        $this->assertObjectHasAttribute('statusCode', $headers);
        $this->assertObjectHasAttribute('statusText', $headers);
        $this->assertObjectHasAttribute('charset', $headers);
    }

    public function testSend()
    {
        $response = new Response();
        $responseSend = $response->send();
        $this->assertObjectHasAttribute('headers', $responseSend);
        $this->assertObjectHasAttribute('content', $responseSend);
        $this->assertObjectHasAttribute('version', $responseSend);
        $this->assertObjectHasAttribute('statusCode', $responseSend);
        $this->assertObjectHasAttribute('statusText', $responseSend);
        $this->assertObjectHasAttribute('charset', $responseSend);
    }

    public function testGetCharset()
    {
        $response = new Response();
        $charsetOrigin = 'UTF-8';
        $response->setCharset($charsetOrigin);
        $charset = $response->getCharset();
        $this->assertEquals($charsetOrigin, $charset);
    }

    public function testIsCacheable()
    {
        $response = new Response();
        $this->assertFalse($response->isCacheable());
    }

    public function testIsCacheableWithErrorCode()
    {
        $response = new Response('', 500);
        $this->assertFalse($response->isCacheable());
    }

    public function testIsCacheableWithNoStoreDirective()
    {
        $response = new Response();
        $response->headers->set('cache-control', 'private');
        $this->assertFalse($response->isCacheable());
    }

    public function testIsCacheableWithSetTtl()
    {
        $response = new Response();
        $response->setTtl(10);
        $this->assertTrue($response->isCacheable());
    }

    public function testMustRevalidate()
    {
        $response = new Response();
        $this->assertFalse($response->mustRevalidate());
    }

    public function testMustRevalidateWithMustRevalidateCacheControlHeader()
    {
        $response = new Response();
        $response->headers->set('cache-control', 'must-revalidate');

        $this->assertTrue($response->mustRevalidate());
    }

    public function testMustRevalidateWithProxyRevalidateCacheControlHeader()
    {
        $response = new Response();
        $response->headers->set('cache-control', 'proxy-revalidate');

        $this->assertTrue($response->mustRevalidate());
    }

    public function testSetNotModified()
    {
        $response = new Response();
        $modified = $response->setNotModified();
        $this->assertObjectHasAttribute('headers', $modified);
        $this->assertObjectHasAttribute('content', $modified);
        $this->assertObjectHasAttribute('version', $modified);
        $this->assertObjectHasAttribute('statusCode', $modified);
        $this->assertObjectHasAttribute('statusText', $modified);
        $this->assertObjectHasAttribute('charset', $modified);
        $this->assertEquals(304, $modified->getStatusCode());
    }

    public function testIsSuccessful()
    {
        $response = new Response();
        $this->assertTrue($response->isSuccessful());
    }

    public function testIsNotModified()
    {
        $response = new Response();
        $modified = $response->isNotModified(new Request());
        $this->assertFalse($modified);
    }

    public function testIsNotModifiedNotSafe()
    {
        $request = Request::create('/homepage', 'POST');

        $response = new Response();
        $this->assertFalse($response->isNotModified($request));
    }

    public function testIsNotModifiedLastModified()
    {
        $before = 'Sun, 25 Aug 2013 18:32:31 GMT';
        $modified = 'Sun, 25 Aug 2013 18:33:31 GMT';
        $after = 'Sun, 25 Aug 2013 19:33:31 GMT';

        $request = new Request();
        $request->headers->set('If-Modified-Since', $modified);

        $response = new Response();

        $response->headers->set('Last-Modified', $modified);
        $this->assertTrue($response->isNotModified($request));

        $response->headers->set('Last-Modified', $before);
        $this->assertTrue($response->isNotModified($request));

        $response->headers->set('Last-Modified', $after);
        $this->assertFalse($response->isNotModified($request));

        $response->headers->set('Last-Modified', '');
        $this->assertFalse($response->isNotModified($request));
    }

    public function testIsNotModifiedEtag()
    {
        $etagOne = 'randomly_generated_etag';
        $etagTwo = 'randomly_generated_etag_2';

        $request = new Request();
        $request->headers->set('if_none_match', sprintf('%s, %s, %s', $etagOne, $etagTwo, 'etagThree'));

        $response = new Response();

        $response->headers->set('ETag', $etagOne);
        $this->assertTrue($response->isNotModified($request));

        $response->headers->set('ETag', $etagTwo);
        $this->assertTrue($response->isNotModified($request));

        $response->headers->set('ETag', '');
        $this->assertFalse($response->isNotModified($request));
    }

    public function testIsNotModifiedLastModifiedAndEtag()
    {
        $before = 'Sun, 25 Aug 2013 18:32:31 GMT';
        $modified = 'Sun, 25 Aug 2013 18:33:31 GMT';
        $after = 'Sun, 25 Aug 2013 19:33:31 GMT';
        $etag = 'randomly_generated_etag';

        $request = new Request();
        $request->headers->set('if_none_match', sprintf('%s, %s', $etag, 'etagThree'));
        $request->headers->set('If-Modified-Since', $modified);

        $response = new Response();

        $response->headers->set('ETag', $etag);
        $response->headers->set('Last-Modified', $after);
        $this->assertFalse($response->isNotModified($request));

        $response->headers->set('ETag', 'non-existent-etag');
        $response->headers->set('Last-Modified', $before);
        $this->assertFalse($response->isNotModified($request));

        $response->headers->set('ETag', $etag);
        $response->headers->set('Last-Modified', $modified);
        $this->assertTrue($response->isNotModified($request));
    }

    public function testIsNotModifiedIfModifiedSinceAndEtagWithoutLastModified()
    {
        $modified = 'Sun, 25 Aug 2013 18:33:31 GMT';
        $etag = 'randomly_generated_etag';

        $request = new Request();
        $request->headers->set('if_none_match', sprintf('%s, %s', $etag, 'etagThree'));
        $request->headers->set('If-Modified-Since', $modified);

        $response = new Response();

        $response->headers->set('ETag', $etag);
        $this->assertTrue($response->isNotModified($request));

        $response->headers->set('ETag', 'non-existent-etag');
        $this->assertFalse($response->isNotModified($request));
    }

    public function testIsValidateable()
    {
        $response = new Response('', 200, array('Last-Modified' => $this->createDateTimeOneHourAgo()->format(DATE_RFC2822)));
        $this->assertTrue($response->isValidateable(), '->isValidateable() returns true if Last-Modified is present');

        $response = new Response('', 200, array('ETag' => '"12345"'));
        $this->assertTrue($response->isValidateable(), '->isValidateable() returns true if ETag is present');

        $response = new Response();
        $this->assertFalse($response->isValidateable(), '->isValidateable() returns false when no validator is present');
    }

    public function testGetDate()
    {
        $oneHourAgo = $this->createDateTimeOneHourAgo();
        $response = new Response('', 200, array('Date' => $oneHourAgo->format(DATE_RFC2822)));
        $date = $response->getDate();
        $this->assertEquals($oneHourAgo->getTimestamp(), $date->getTimestamp(), '->getDate() returns the Date header if present');

        $response = new Response();
        $date = $response->getDate();
        $this->assertEquals(time(), $date->getTimestamp(), '->getDate() returns the current Date if no Date header present');

        $response = new Response('', 200, array('Date' => $this->createDateTimeOneHourAgo()->format(DATE_RFC2822)));
        $now = $this->createDateTimeNow();
        $response->headers->set('Date', $now->format(DATE_RFC2822));
        $date = $response->getDate();
        $this->assertEquals($now->getTimestamp(), $date->getTimestamp(), '->getDate() returns the date when the header has been modified');

        $response = new Response('', 200);
        $response->headers->remove('Date');
        $this->assertInstanceOf('\DateTime', $response->getDate());
    }

    public function testGetMaxAge()
    {
        $response = new Response();
        $response->headers->set('Cache-Control', 's-maxage=600, max-age=0');
        $this->assertEquals(600, $response->getMaxAge(), '->getMaxAge() uses s-maxage cache control directive when present');

        $response = new Response();
        $response->headers->set('Cache-Control', 'max-age=600');
        $this->assertEquals(600, $response->getMaxAge(), '->getMaxAge() falls back to max-age when no s-maxage directive present');

        $response = new Response();
        $response->headers->set('Cache-Control', 'must-revalidate');
        $response->headers->set('Expires', $this->createDateTimeOneHourLater()->format(DATE_RFC2822));
        $this->assertEquals(3600, $response->getMaxAge(), '->getMaxAge() falls back to Expires when no max-age or s-maxage directive present');

        $response = new Response();
        $response->headers->set('Cache-Control', 'must-revalidate');
        $response->headers->set('Expires', -1);
        $this->assertEquals('Sat, 01 Jan 00 00:00:00 +0000', $response->getExpires()->format(DATE_RFC822));

        $response = new Response();
        $this->assertNull($response->getMaxAge(), '->getMaxAge() returns null if no freshness information available');
    }

    public function testSetSharedMaxAge()
    {
        $response = new Response();
        $response->setSharedMaxAge(20);

        $cacheControl = $response->headers->get('Cache-Control');
        $this->assertEquals('public, s-maxage=20', $cacheControl);
    }

    public function testIsPrivate()
    {
        $response = new Response();
        $response->headers->set('Cache-Control', 'max-age=100');
        $response->setPrivate();
        $this->assertEquals(100, $response->headers->getCacheControlDirective('max-age'), '->isPrivate() adds the private Cache-Control directive when set to true');
        $this->assertTrue($response->headers->getCacheControlDirective('private'), '->isPrivate() adds the private Cache-Control directive when set to true');

        $response = new Response();
        $response->headers->set('Cache-Control', 'public, max-age=100');
        $response->setPrivate();
        $this->assertEquals(100, $response->headers->getCacheControlDirective('max-age'), '->isPrivate() adds the private Cache-Control directive when set to true');
        $this->assertTrue($response->headers->getCacheControlDirective('private'), '->isPrivate() adds the private Cache-Control directive when set to true');
        $this->assertFalse($response->headers->hasCacheControlDirective('public'), '->isPrivate() removes the public Cache-Control directive');
    }

    public function testExpire()
    {
        $response = new Response();
        $response->headers->set('Cache-Control', 'max-age=100');
        $response->expire();
        $this->assertEquals(100, $response->headers->get('Age'), '->expire() sets the Age to max-age when present');

        $response = new Response();
        $response->headers->set('Cache-Control', 'max-age=100, s-maxage=500');
        $response->expire();
        $this->assertEquals(500, $response->headers->get('Age'), '->expire() sets the Age to s-maxage when both max-age and s-maxage are present');

        $response = new Response();
        $response->headers->set('Cache-Control', 'max-age=5, s-maxage=500');
        $response->headers->set('Age', '1000');
        $response->expire();
        $this->assertEquals(1000, $response->headers->get('Age'), '->expire() does nothing when the response is already stale/expired');

        $response = new Response();
        $response->expire();
        $this->assertFalse($response->headers->has('Age'), '->expire() does nothing when the response does not include freshness information');

        $response = new Response();
        $response->headers->set('Expires', -1);
        $response->expire();
        $this->assertNull($response->headers->get('Age'), '->expire() does not set the Age when the response is expired');
    }

    public function testGetTtl()
    {
        $response = new Response();
        $this->assertNull($response->getTtl(), '->getTtl() returns null when no Expires or Cache-Control headers are present');

        $response = new Response();
        $response->headers->set('Expires', $this->createDateTimeOneHourLater()->format(DATE_RFC2822));
        $this->assertEquals(3600, $response->getTtl(), '->getTtl() uses the Expires header when no max-age is present');

        $response = new Response();
        $response->headers->set('Expires', $this->createDateTimeOneHourAgo()->format(DATE_RFC2822));
        $this->assertLessThan(0, $response->getTtl(), '->getTtl() returns negative values when Expires is in past');

        $response = new Response();
        $response->headers->set('Expires', $response->getDate()->format(DATE_RFC2822));
        $response->headers->set('Age', 0);
        $this->assertSame(0, $response->getTtl(), '->getTtl() correctly handles zero');

        $response = new Response();
        $response->headers->set('Cache-Control', 'max-age=60');
        $this->assertEquals(60, $response->getTtl(), '->getTtl() uses Cache-Control max-age when present');
    }

    public function testSetClientTtl()
    {
        $response = new Response();
        $response->setClientTtl(10);

        $this->assertEquals($response->getMaxAge(), $response->getAge() + 10);
    }

    public function testGetSetProtocolVersion()
    {
        $response = new Response();

        $this->assertEquals('1.0', $response->getProtocolVersion());

        $response->setProtocolVersion('1.1');

        $this->assertEquals('1.1', $response->getProtocolVersion());
    }

    public function testGetVary()
    {
        $response = new Response();
        $this->assertEquals(array(), $response->getVary(), '->getVary() returns an empty array if no Vary header is present');

        $response = new Response();
        $response->headers->set('Vary', 'Accept-Language');
        $this->assertEquals(array('Accept-Language'), $response->getVary(), '->getVary() parses a single header name value');

        $response = new Response();
        $response->headers->set('Vary', 'Accept-Language User-Agent    X-Foo');
        $this->assertEquals(array('Accept-Language', 'User-Agent', 'X-Foo'), $response->getVary(), '->getVary() parses multiple header name values separated by spaces');

        $response = new Response();
        $response->headers->set('Vary', 'Accept-Language,User-Agent,    X-Foo');
        $this->assertEquals(array('Accept-Language', 'User-Agent', 'X-Foo'), $response->getVary(), '->getVary() parses multiple header name values separated by commas');

        $vary = array('Accept-Language', 'User-Agent', 'X-foo');

        $response = new Response();
        $response->headers->set('Vary', $vary);
        $this->assertEquals($vary, $response->getVary(), '->getVary() parses multiple header name values in arrays');

        $response = new Response();
        $response->headers->set('Vary', 'Accept-Language, User-Agent, X-foo');
        $this->assertEquals($vary, $response->getVary(), '->getVary() parses multiple header name values in arrays');
    }

    public function testSetVary()
    {
        $response = new Response();
        $response->setVary('Accept-Language');
        $this->assertEquals(array('Accept-Language'), $response->getVary());

        $response->setVary('Accept-Language, User-Agent');
        $this->assertEquals(array('Accept-Language', 'User-Agent'), $response->getVary(), '->setVary() replace the vary header by default');

        $response->setVary('X-Foo', false);
        $this->assertEquals(array('Accept-Language', 'User-Agent', 'X-Foo'), $response->getVary(), '->setVary() doesn\'t wipe out earlier Vary headers if replace is set to false');
    }

    public function testDefaultContentType()
    {
        $headerMock = $this->getMock('Symfony\Component\HttpFoundation\ResponseHeaderBag', array('set'));
        $headerMock->expects($this->at(0))
            ->method('set')
            ->with('Content-Type', 'text/html');
        $headerMock->expects($this->at(1))
            ->method('set')
            ->with('Content-Type', 'text/html; charset=UTF-8');

        $response = new Response('foo');
        $response->headers = $headerMock;

        $response->prepare(new Request());
    }

    public function testContentTypeCharset()
    {
        $response = new Response();
        $response->headers->set('Content-Type', 'text/css');

        // force fixContentType() to be called
        $response->prepare(new Request());

        $this->assertEquals('text/css; charset=UTF-8', $response->headers->get('Content-Type'));
    }

    public function testPrepareDoesNothingIfContentTypeIsSet()
    {
        $response = new Response('foo');
        $response->headers->set('Content-Type', 'text/plain');

        $response->prepare(new Request());

        $this->assertEquals('text/plain; charset=UTF-8', $response->headers->get('content-type'));
    }

    public function testPrepareDoesNothingIfRequestFormatIsNotDefined()
    {
        $response = new Response('foo');

        $response->prepare(new Request());

        $this->assertEquals('text/html; charset=UTF-8', $response->headers->get('content-type'));
    }

    public function testPrepareSetContentType()
    {
        $response = new Response('foo');
        $request = Request::create('/');
        $request->setRequestFormat('json');

        $response->prepare($request);

        $this->assertEquals('application/json', $response->headers->get('content-type'));
    }

    public function testPrepareRemovesContentForHeadRequests()
    {
        $response = new Response('foo');
        $request = Request::create('/', 'HEAD');

        $length = 12345;
        $response->headers->set('Content-Length', $length);
        $response->prepare($request);

        $this->assertEquals('', $response->getContent());
        $this->assertEquals($length, $response->headers->get('Content-Length'), 'Content-Length should be as if it was GET; see RFC2616 14.13');
    }

    public function testPrepareRemovesContentForInformationalResponse()
    {
        $response = new Response('foo');
        $request = Request::create('/');

        $response->setContent('content');
        $response->setStatusCode(101);
        $response->prepare($request);
        $this->assertEquals('', $response->getContent());
        $this->assertFalse($response->headers->has('Content-Type'));
        $this->assertFalse($response->headers->has('Content-Type'));

        $response->setContent('content');
        $response->setStatusCode(304);
        $response->prepare($request);
        $this->assertEquals('', $response->getContent());
        $this->assertFalse($response->headers->has('Content-Type'));
        $this->assertFalse($response->headers->has('Content-Length'));
    }

    public function testPrepareRemovesContentLength()
    {
        $response = new Response('foo');
        $request = Request::create('/');

        $response->headers->set('Content-Length', 12345);
        $response->prepare($request);
        $this->assertEquals(12345, $response->headers->get('Content-Length'));

        $response->headers->set('Transfer-Encoding', 'chunked');
        $response->prepare($request);
        $this->assertFalse($response->headers->has('Content-Length'));
    }

    public function testPrepareSetsPragmaOnHttp10Only()
    {
        $request = Request::create('/', 'GET');
        $request->server->set('SERVER_PROTOCOL', 'HTTP/1.0');

        $response = new Response('foo');
        $response->prepare($request);
        $this->assertEquals('no-cache', $response->headers->get('pragma'));
        $this->assertEquals('-1', $response->headers->get('expires'));

        $request->server->set('SERVER_PROTOCOL', 'HTTP/1.1');
        $response = new Response('foo');
        $response->prepare($request);
        $this->assertFalse($response->headers->has('pragma'));
        $this->assertFalse($response->headers->has('expires'));
    }

    public function testSetCache()
    {
        $response = new Response();
        //array('etag', 'last_modified', 'max_age', 's_maxage', 'private', 'public')
        try {
            $response->setCache(array('wrong option' => 'value'));
            $this->fail('->setCache() throws an InvalidArgumentException if an option is not supported');
        } catch (\Exception $e) {
            $this->assertInstanceOf('InvalidArgumentException', $e, '->setCache() throws an InvalidArgumentException if an option is not supported');
            $this->assertContains('"wrong option"', $e->getMessage());
        }

        $options = array('etag' => '"whatever"');
        $response->setCache($options);
        $this->assertEquals($response->getEtag(), '"whatever"');

        $now = $this->createDateTimeNow();
        $options = array('last_modified' => $now);
        $response->setCache($options);
        $this->assertEquals($response->getLastModified()->getTimestamp(), $now->getTimestamp());

        $options = array('max_age' => 100);
        $response->setCache($options);
        $this->assertEquals($response->getMaxAge(), 100);

        $options = array('s_maxage' => 200);
        $response->setCache($options);
        $this->assertEquals($response->getMaxAge(), 200);

        $this->assertTrue($response->headers->hasCacheControlDirective('public'));
        $this->assertFalse($response->headers->hasCacheControlDirective('private'));

        $response->setCache(array('public' => true));
        $this->assertTrue($response->headers->hasCacheControlDirective('public'));
        $this->assertFalse($response->headers->hasCacheControlDirective('private'));

        $response->setCache(array('public' => false));
        $this->assertFalse($response->headers->hasCacheControlDirective('public'));
        $this->assertTrue($response->headers->hasCacheControlDirective('private'));

        $response->setCache(array('private' => true));
        $this->assertFalse($response->headers->hasCacheControlDirective('public'));
        $this->assertTrue($response->headers->hasCacheControlDirective('private'));

        $response->setCache(array('private' => false));
        $this->assertTrue($response->headers->hasCacheControlDirective('public'));
        $this->assertFalse($response->headers->hasCacheControlDirective('private'));
    }

    public function testSendContent()
    {
        $response = new Response('test response rendering', 200);

        ob_start();
        $response->sendContent();
        $string = ob_get_clean();
        $this->assertContains('test response rendering', $string);
    }

    public function testSetPublic()
    {
        $response = new Response();
        $response->setPublic();

        $this->assertTrue($response->headers->hasCacheControlDirective('public'));
        $this->assertFalse($response->headers->hasCacheControlDirective('private'));
    }

    public function testSetExpires()
    {
        $response = new Response();
        $response->setExpires(null);

        $this->assertNull($response->getExpires(), '->setExpires() remove the header when passed null');

        $now = $this->createDateTimeNow();
        $response->setExpires($now);

        $this->assertEquals($response->getExpires()->getTimestamp(), $now->getTimestamp());
    }

    public function testSetLastModified()
    {
        $response = new Response();
        $response->setLastModified($this->createDateTimeNow());
        $this->assertNotNull($response->getLastModified());

        $response->setLastModified(null);
        $this->assertNull($response->getLastModified());
    }

    public function testIsInvalid()
    {
        $response = new Response();

        try {
            $response->setStatusCode(99);
            $this->fail();
        } catch (\InvalidArgumentException $e) {
            $this->assertTrue($response->isInvalid());
        }

        try {
            $response->setStatusCode(650);
            $this->fail();
        } catch (\InvalidArgumentException $e) {
            $this->assertTrue($response->isInvalid());
        }

        $response = new Response('', 200);
        $this->assertFalse($response->isInvalid());
    }

    /**
     * @dataProvider getStatusCodeFixtures
     */
    public function testSetStatusCode($code, $text, $expectedText)
    {
        $response = new Response();

        $response->setStatusCode($code, $text);

        $statusText = new \ReflectionProperty($response, 'statusText');
        $statusText->setAccessible(true);

        $this->assertEquals($expectedText, $statusText->getValue($response));
    }

    public function getStatusCodeFixtures()
    {
        return array(
            array('200', null, 'OK'),
            array('200', false, ''),
            array('200', 'foo', 'foo'),
            array('199', null, 'unknown status'),
            array('199', false, ''),
            array('199', 'foo', 'foo'),
        );
    }

    public function testIsInformational()
    {
        $response = new Response('', 100);
        $this->assertTrue($response->isInformational());

        $response = new Response('', 200);
        $this->assertFalse($response->isInformational());
    }

    public function testIsRedirectRedirection()
    {
        foreach (array(301, 302, 303, 307) as $code) {
            $response = new Response('', $code);
            $this->assertTrue($response->isRedirection());
            $this->assertTrue($response->isRedirect());
        }

        $response = new Response('', 304);
        $this->assertTrue($response->isRedirection());
        $this->assertFalse($response->isRedirect());

        $response = new Response('', 200);
        $this->assertFalse($response->isRedirection());
        $this->assertFalse($response->isRedirect());

        $response = new Response('', 404);
        $this->assertFalse($response->isRedirection());
        $this->assertFalse($response->isRedirect());

        $response = new Response('', 301, array('Location' => '/good-uri'));
        $this->assertFalse($response->isRedirect('/bad-uri'));
        $this->assertTrue($response->isRedirect('/good-uri'));
    }

    public function testIsNotFound()
    {
        $response = new Response('', 404);
        $this->assertTrue($response->isNotFound());

        $response = new Response('', 200);
        $this->assertFalse($response->isNotFound());
    }

    public function testIsEmpty()
    {
        foreach (array(204, 304) as $code) {
            $response = new Response('', $code);
            $this->assertTrue($response->isEmpty());
        }

        $response = new Response('', 200);
        $this->assertFalse($response->isEmpty());
    }

    public function testIsForbidden()
    {
        $response = new Response('', 403);
        $this->assertTrue($response->isForbidden());

        $response = new Response('', 200);
        $this->assertFalse($response->isForbidden());
    }

    public function testIsOk()
    {
        $response = new Response('', 200);
        $this->assertTrue($response->isOk());

        $response = new Response('', 404);
        $this->assertFalse($response->isOk());
    }

    public function testIsServerOrClientError()
    {
        $response = new Response('', 404);
        $this->assertTrue($response->isClientError());
        $this->assertFalse($response->isServerError());

        $response = new Response('', 500);
        $this->assertFalse($response->isClientError());
        $this->assertTrue($response->isServerError());
    }

    public function testHasVary()
    {
        $response = new Response();
        $this->assertFalse($response->hasVary());

        $response->setVary('User-Agent');
        $this->assertTrue($response->hasVary());
    }

    public function testSetEtag()
    {
        $response = new Response('', 200, array('ETag' => '"12345"'));
        $response->setEtag();

        $this->assertNull($response->headers->get('Etag'), '->setEtag() removes Etags when call with null');
    }

    /**
     * @dataProvider validContentProvider
     */
    public function testSetContent($content)
    {
        $response = new Response();
        $response->setContent($content);
        $this->assertEquals((string) $content, $response->getContent());
    }

    /**
     * @expectedException \UnexpectedValueException
     * @dataProvider invalidContentProvider
     */
    public function testSetContentInvalid($content)
    {
        $response = new Response();
        $response->setContent($content);
    }

    public function testSettersAreChainable()
    {
        $response = new Response();

        $setters = array(
            'setProtocolVersion' => '1.0',
            'setCharset' => 'UTF-8',
            'setPublic' => null,
            'setPrivate' => null,
            'setDate' => $this->createDateTimeNow(),
            'expire' => null,
            'setMaxAge' => 1,
            'setSharedMaxAge' => 1,
            'setTtl' => 1,
            'setClientTtl' => 1,
        );

        foreach ($setters as $setter => $arg) {
            $this->assertEquals($response, $response->{$setter}($arg));
        }
    }

    public function validContentProvider()
    {
        return array(
            'obj' => array(new StringableObject()),
            'string' => array('Foo'),
            'int' => array(2),
        );
    }

    public function invalidContentProvider()
    {
        return array(
            'obj' => array(new \stdClass()),
            'array' => array(array()),
            'bool' => array(true, '1'),
        );
    }

    protected function createDateTimeOneHourAgo()
    {
        return $this->createDateTimeNow()->sub(new \DateInterval('PT1H'));
    }

    protected function createDateTimeOneHourLater()
    {
        return $this->createDateTimeNow()->add(new \DateInterval('PT1H'));
    }

    protected function createDateTimeNow()
    {
        $date = new \DateTime();

        return $date->setTimestamp(time());
    }

    protected function provideResponse()
    {
        return new Response();
    }
}

class StringableObject
{
    public function __toString()
    {
        return 'Foo';
    }
}
PKϤ$Zw<�%%'http-foundation/Tests/ServerBagTest.phpnu�[���<?php

/*
 * This file is part of the Symfony package.
 *
 * (c) Fabien Potencier <fabien@symfony.com>
 *
 * For the full copyright and license information, please view the LICENSE
 * file that was distributed with this source code.
 */

namespace Symfony\Component\HttpFoundation\Tests;

use Symfony\Component\HttpFoundation\ServerBag;

/**
 * ServerBagTest.
 *
 * @author Bulat Shakirzyanov <mallluhuct@gmail.com>
 */
class ServerBagTest extends \PHPUnit_Framework_TestCase
{
    public function testShouldExtractHeadersFromServerArray()
    {
        $server = array(
            'SOME_SERVER_VARIABLE' => 'value',
            'SOME_SERVER_VARIABLE2' => 'value',
            'ROOT' => 'value',
            'HTTP_CONTENT_TYPE' => 'text/html',
            'HTTP_CONTENT_LENGTH' => '0',
            'HTTP_ETAG' => 'asdf',
            'PHP_AUTH_USER' => 'foo',
            'PHP_AUTH_PW' => 'bar',
        );

        $bag = new ServerBag($server);

        $this->assertEquals(array(
            'CONTENT_TYPE' => 'text/html',
            'CONTENT_LENGTH' => '0',
            'ETAG' => 'asdf',
            'AUTHORIZATION' => 'Basic '.base64_encode('foo:bar'),
            'PHP_AUTH_USER' => 'foo',
            'PHP_AUTH_PW' => 'bar',
        ), $bag->getHeaders());
    }

    public function testHttpPasswordIsOptional()
    {
        $bag = new ServerBag(array('PHP_AUTH_USER' => 'foo'));

        $this->assertEquals(array(
            'AUTHORIZATION' => 'Basic '.base64_encode('foo:'),
            'PHP_AUTH_USER' => 'foo',
            'PHP_AUTH_PW' => '',
        ), $bag->getHeaders());
    }

    public function testHttpBasicAuthWithPhpCgi()
    {
        $bag = new ServerBag(array('HTTP_AUTHORIZATION' => 'Basic '.base64_encode('foo:bar')));

        $this->assertEquals(array(
            'AUTHORIZATION' => 'Basic '.base64_encode('foo:bar'),
            'PHP_AUTH_USER' => 'foo',
            'PHP_AUTH_PW' => 'bar',
        ), $bag->getHeaders());
    }

    public function testHttpBasicAuthWithPhpCgiBogus()
    {
        $bag = new ServerBag(array('HTTP_AUTHORIZATION' => 'Basic_'.base64_encode('foo:bar')));

        // Username and passwords should not be set as the header is bogus
        $headers = $bag->getHeaders();
        $this->assertFalse(isset($headers['PHP_AUTH_USER']));
        $this->assertFalse(isset($headers['PHP_AUTH_PW']));
    }

    public function testHttpBasicAuthWithPhpCgiRedirect()
    {
        $bag = new ServerBag(array('REDIRECT_HTTP_AUTHORIZATION' => 'Basic '.base64_encode('username:pass:word')));

        $this->assertEquals(array(
            'AUTHORIZATION' => 'Basic '.base64_encode('username:pass:word'),
            'PHP_AUTH_USER' => 'username',
            'PHP_AUTH_PW' => 'pass:word',
        ), $bag->getHeaders());
    }

    public function testHttpBasicAuthWithPhpCgiEmptyPassword()
    {
        $bag = new ServerBag(array('HTTP_AUTHORIZATION' => 'Basic '.base64_encode('foo:')));

        $this->assertEquals(array(
            'AUTHORIZATION' => 'Basic '.base64_encode('foo:'),
            'PHP_AUTH_USER' => 'foo',
            'PHP_AUTH_PW' => '',
        ), $bag->getHeaders());
    }

    public function testHttpDigestAuthWithPhpCgi()
    {
        $digest = 'Digest username="foo", realm="acme", nonce="'.md5('secret').'", uri="/protected, qop="auth"';
        $bag = new ServerBag(array('HTTP_AUTHORIZATION' => $digest));

        $this->assertEquals(array(
            'AUTHORIZATION' => $digest,
            'PHP_AUTH_DIGEST' => $digest,
        ), $bag->getHeaders());
    }

    public function testHttpDigestAuthWithPhpCgiBogus()
    {
        $digest = 'Digest_username="foo", realm="acme", nonce="'.md5('secret').'", uri="/protected, qop="auth"';
        $bag = new ServerBag(array('HTTP_AUTHORIZATION' => $digest));

        // Username and passwords should not be set as the header is bogus
        $headers = $bag->getHeaders();
        $this->assertFalse(isset($headers['PHP_AUTH_USER']));
        $this->assertFalse(isset($headers['PHP_AUTH_PW']));
    }

    public function testHttpDigestAuthWithPhpCgiRedirect()
    {
        $digest = 'Digest username="foo", realm="acme", nonce="'.md5('secret').'", uri="/protected, qop="auth"';
        $bag = new ServerBag(array('REDIRECT_HTTP_AUTHORIZATION' => $digest));

        $this->assertEquals(array(
            'AUTHORIZATION' => $digest,
            'PHP_AUTH_DIGEST' => $digest,
        ), $bag->getHeaders());
    }

    public function testOAuthBearerAuth()
    {
        $headerContent = 'Bearer L-yLEOr9zhmUYRkzN1jwwxwQ-PBNiKDc8dgfB4hTfvo';
        $bag = new ServerBag(array('HTTP_AUTHORIZATION' => $headerContent));

        $this->assertEquals(array(
            'AUTHORIZATION' => $headerContent,
        ), $bag->getHeaders());
    }

    public function testOAuthBearerAuthWithRedirect()
    {
        $headerContent = 'Bearer L-yLEOr9zhmUYRkzN1jwwxwQ-PBNiKDc8dgfB4hTfvo';
        $bag = new ServerBag(array('REDIRECT_HTTP_AUTHORIZATION' => $headerContent));

        $this->assertEquals(array(
            'AUTHORIZATION' => $headerContent,
        ), $bag->getHeaders());
    }

    /**
     * @see https://github.com/symfony/symfony/issues/17345
     */
    public function testItDoesNotOverwriteTheAuthorizationHeaderIfItIsAlreadySet()
    {
        $headerContent = 'Bearer L-yLEOr9zhmUYRkzN1jwwxwQ-PBNiKDc8dgfB4hTfvo';
        $bag = new ServerBag(array('PHP_AUTH_USER' => 'foo', 'HTTP_AUTHORIZATION' => $headerContent));

        $this->assertEquals(array(
            'AUTHORIZATION' => $headerContent,
            'PHP_AUTH_USER' => 'foo',
            'PHP_AUTH_PW' => '',
        ), $bag->getHeaders());
    }
}
PKϤ$Z���cDD$http-foundation/Tests/CookieTest.phpnu�[���<?php

/*
 * This file is part of the Symfony package.
 *
 * (c) Fabien Potencier <fabien@symfony.com>
 *
 * For the full copyright and license information, please view the LICENSE
 * file that was distributed with this source code.
 */

namespace Symfony\Component\HttpFoundation\Tests;

use Symfony\Component\HttpFoundation\Cookie;

/**
 * CookieTest.
 *
 * @author John Kary <john@johnkary.net>
 * @author Hugo Hamon <hugo.hamon@sensio.com>
 *
 * @group time-sensitive
 */
class CookieTest extends \PHPUnit_Framework_TestCase
{
    public function invalidNames()
    {
        return array(
            array(''),
            array(',MyName'),
            array(';MyName'),
            array(' MyName'),
            array("\tMyName"),
            array("\rMyName"),
            array("\nMyName"),
            array("\013MyName"),
            array("\014MyName"),
        );
    }

    /**
     * @dataProvider invalidNames
     * @expectedException \InvalidArgumentException
     */
    public function testInstantiationThrowsExceptionIfCookieNameContainsInvalidCharacters($name)
    {
        new Cookie($name);
    }

    /**
     * @expectedException \InvalidArgumentException
     */
    public function testInvalidExpiration()
    {
        $cookie = new Cookie('MyCookie', 'foo', 'bar');
    }

    public function testGetValue()
    {
        $value = 'MyValue';
        $cookie = new Cookie('MyCookie', $value);

        $this->assertSame($value, $cookie->getValue(), '->getValue() returns the proper value');
    }

    public function testGetPath()
    {
        $cookie = new Cookie('foo', 'bar');

        $this->assertSame('/', $cookie->getPath(), '->getPath() returns / as the default path');
    }

    public function testGetExpiresTime()
    {
        $cookie = new Cookie('foo', 'bar', 3600);

        $this->assertEquals(3600, $cookie->getExpiresTime(), '->getExpiresTime() returns the expire date');
    }

    public function testConstructorWithDateTime()
    {
        $expire = new \DateTime();
        $cookie = new Cookie('foo', 'bar', $expire);

        $this->assertEquals($expire->format('U'), $cookie->getExpiresTime(), '->getExpiresTime() returns the expire date');
    }

    /**
     * @requires PHP 5.5
     */
    public function testConstructorWithDateTimeImmutable()
    {
        $expire = new \DateTimeImmutable();
        $cookie = new Cookie('foo', 'bar', $expire);

        $this->assertEquals($expire->format('U'), $cookie->getExpiresTime(), '->getExpiresTime() returns the expire date');
    }

    public function testGetExpiresTimeWithStringValue()
    {
        $value = '+1 day';
        $cookie = new Cookie('foo', 'bar', $value);
        $expire = strtotime($value);

        $this->assertEquals($expire, $cookie->getExpiresTime(), '->getExpiresTime() returns the expire date', 1);
    }

    public function testGetDomain()
    {
        $cookie = new Cookie('foo', 'bar', 3600, '/', '.myfoodomain.com');

        $this->assertEquals('.myfoodomain.com', $cookie->getDomain(), '->getDomain() returns the domain name on which the cookie is valid');
    }

    public function testIsSecure()
    {
        $cookie = new Cookie('foo', 'bar', 3600, '/', '.myfoodomain.com', true);

        $this->assertTrue($cookie->isSecure(), '->isSecure() returns whether the cookie is transmitted over HTTPS');
    }

    public function testIsHttpOnly()
    {
        $cookie = new Cookie('foo', 'bar', 3600, '/', '.myfoodomain.com', false, true);

        $this->assertTrue($cookie->isHttpOnly(), '->isHttpOnly() returns whether the cookie is only transmitted over HTTP');
    }

    public function testCookieIsNotCleared()
    {
        $cookie = new Cookie('foo', 'bar', time() + 3600 * 24);

        $this->assertFalse($cookie->isCleared(), '->isCleared() returns false if the cookie did not expire yet');
    }

    public function testCookieIsCleared()
    {
        $cookie = new Cookie('foo', 'bar', time() - 20);

        $this->assertTrue($cookie->isCleared(), '->isCleared() returns true if the cookie has expired');
    }

    public function testToString()
    {
        $cookie = new Cookie('foo', 'bar', strtotime('Fri, 20-May-2011 15:25:52 GMT'), '/', '.myfoodomain.com', true);
        $this->assertEquals('foo=bar; expires=Fri, 20-May-2011 15:25:52 GMT; path=/; domain=.myfoodomain.com; secure; httponly', $cookie->__toString(), '->__toString() returns string representation of the cookie');

        $cookie = new Cookie('foo', null, 1, '/admin/', '.myfoodomain.com');
        $this->assertEquals('foo=deleted; expires='.gmdate('D, d-M-Y H:i:s T', time() - 31536001).'; path=/admin/; domain=.myfoodomain.com; httponly', $cookie->__toString(), '->__toString() returns string representation of a cleared cookie if value is NULL');

        $cookie = new Cookie('foo', 'bar', 0, '/', '');
        $this->assertEquals('foo=bar; path=/; httponly', $cookie->__toString());
    }
}
PKϤ$Z��lOD
D
*http-foundation/Tests/ResponseTestCase.phpnu�[���<?php

/*
 * This file is part of the Symfony package.
 *
 * (c) Fabien Potencier <fabien@symfony.com>
 *
 * For the full copyright and license information, please view the LICENSE
 * file that was distributed with this source code.
 */

namespace Symfony\Component\HttpFoundation\Tests;

use Symfony\Component\HttpFoundation\Request;

abstract class ResponseTestCase extends \PHPUnit_Framework_TestCase
{
    public function testNoCacheControlHeaderOnAttachmentUsingHTTPSAndMSIE()
    {
        // Check for HTTPS and IE 8
        $request = new Request();
        $request->server->set('HTTPS', true);
        $request->server->set('HTTP_USER_AGENT', 'Mozilla/4.0 (compatible; MSIE 8.0; Windows NT 6.0; Trident/4.0)');

        $response = $this->provideResponse();
        $response->headers->set('Content-Disposition', 'attachment; filename="fname.ext"');
        $response->prepare($request);

        $this->assertFalse($response->headers->has('Cache-Control'));

        // Check for IE 10 and HTTPS
        $request->server->set('HTTP_USER_AGENT', 'Mozilla/5.0 (compatible; MSIE 10.0; Windows NT 6.1; WOW64; Trident/6.0)');

        $response = $this->provideResponse();
        $response->headers->set('Content-Disposition', 'attachment; filename="fname.ext"');
        $response->prepare($request);

        $this->assertTrue($response->headers->has('Cache-Control'));

        // Check for IE 9 and HTTPS
        $request->server->set('HTTP_USER_AGENT', 'Mozilla/5.0 (compatible; MSIE 9.0; Windows NT 7.1; Trident/5.0)');

        $response = $this->provideResponse();
        $response->headers->set('Content-Disposition', 'attachment; filename="fname.ext"');
        $response->prepare($request);

        $this->assertTrue($response->headers->has('Cache-Control'));

        // Check for IE 9 and HTTP
        $request->server->set('HTTPS', false);

        $response = $this->provideResponse();
        $response->headers->set('Content-Disposition', 'attachment; filename="fname.ext"');
        $response->prepare($request);

        $this->assertTrue($response->headers->has('Cache-Control'));

        // Check for IE 8 and HTTP
        $request->server->set('HTTP_USER_AGENT', 'Mozilla/4.0 (compatible; MSIE 8.0; Windows NT 6.0; Trident/4.0)');

        $response = $this->provideResponse();
        $response->headers->set('Content-Disposition', 'attachment; filename="fname.ext"');
        $response->prepare($request);

        $this->assertTrue($response->headers->has('Cache-Control'));

        // Check for non-IE and HTTPS
        $request->server->set('HTTPS', true);
        $request->server->set('HTTP_USER_AGENT', 'Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/537.17 (KHTML, like Gecko) Chrome/24.0.1312.60 Safari/537.17');

        $response = $this->provideResponse();
        $response->headers->set('Content-Disposition', 'attachment; filename="fname.ext"');
        $response->prepare($request);

        $this->assertTrue($response->headers->has('Cache-Control'));

        // Check for non-IE and HTTP
        $request->server->set('HTTPS', false);

        $response = $this->provideResponse();
        $response->headers->set('Content-Disposition', 'attachment; filename="fname.ext"');
        $response->prepare($request);

        $this->assertTrue($response->headers->has('Cache-Control'));
    }

    abstract protected function provideResponse();
}
PKϤ$Z��fUU%http-foundation/Tests/FileBagTest.phpnu�[���<?php

/*
 * This file is part of the Symfony package.
 *
 * (c) Fabien Potencier <fabien@symfony.com>
 *
 * For the full copyright and license information, please view the LICENSE
 * file that was distributed with this source code.
 */

namespace Symfony\Component\HttpFoundation\Tests;

use Symfony\Component\HttpFoundation\File\UploadedFile;
use Symfony\Component\HttpFoundation\FileBag;

/**
 * FileBagTest.
 *
 * @author Fabien Potencier <fabien@symfony.com>
 * @author Bulat Shakirzyanov <mallluhuct@gmail.com>
 */
class FileBagTest extends \PHPUnit_Framework_TestCase
{
    /**
     * @expectedException \InvalidArgumentException
     */
    public function testFileMustBeAnArrayOrUploadedFile()
    {
        new FileBag(array('file' => 'foo'));
    }

    public function testShouldConvertsUploadedFiles()
    {
        $tmpFile = $this->createTempFile();
        $file = new UploadedFile($tmpFile, basename($tmpFile), 'text/plain', 100, 0);

        $bag = new FileBag(array('file' => array(
            'name' => basename($tmpFile),
            'type' => 'text/plain',
            'tmp_name' => $tmpFile,
            'error' => 0,
            'size' => 100,
        )));

        $this->assertEquals($file, $bag->get('file'));
    }

    public function testShouldSetEmptyUploadedFilesToNull()
    {
        $bag = new FileBag(array('file' => array(
            'name' => '',
            'type' => '',
            'tmp_name' => '',
            'error' => UPLOAD_ERR_NO_FILE,
            'size' => 0,
        )));

        $this->assertNull($bag->get('file'));
    }

    public function testShouldConvertUploadedFilesWithPhpBug()
    {
        $tmpFile = $this->createTempFile();
        $file = new UploadedFile($tmpFile, basename($tmpFile), 'text/plain', 100, 0);

        $bag = new FileBag(array(
            'child' => array(
                'name' => array(
                    'file' => basename($tmpFile),
                ),
                'type' => array(
                    'file' => 'text/plain',
                ),
                'tmp_name' => array(
                    'file' => $tmpFile,
                ),
                'error' => array(
                    'file' => 0,
                ),
                'size' => array(
                    'file' => 100,
                ),
            ),
        ));

        $files = $bag->all();
        $this->assertEquals($file, $files['child']['file']);
    }

    public function testShouldConvertNestedUploadedFilesWithPhpBug()
    {
        $tmpFile = $this->createTempFile();
        $file = new UploadedFile($tmpFile, basename($tmpFile), 'text/plain', 100, 0);

        $bag = new FileBag(array(
            'child' => array(
                'name' => array(
                    'sub' => array('file' => basename($tmpFile)),
                ),
                'type' => array(
                    'sub' => array('file' => 'text/plain'),
                ),
                'tmp_name' => array(
                    'sub' => array('file' => $tmpFile),
                ),
                'error' => array(
                    'sub' => array('file' => 0),
                ),
                'size' => array(
                    'sub' => array('file' => 100),
                ),
            ),
        ));

        $files = $bag->all();
        $this->assertEquals($file, $files['child']['sub']['file']);
    }

    public function testShouldNotConvertNestedUploadedFiles()
    {
        $tmpFile = $this->createTempFile();
        $file = new UploadedFile($tmpFile, basename($tmpFile), 'text/plain', 100, 0);
        $bag = new FileBag(array('image' => array('file' => $file)));

        $files = $bag->all();
        $this->assertEquals($file, $files['image']['file']);
    }

    protected function createTempFile()
    {
        return tempnam(sys_get_temp_dir().'/form_test', 'FormTest');
    }

    protected function setUp()
    {
        mkdir(sys_get_temp_dir().'/form_test', 0777, true);
    }

    protected function tearDown()
    {
        foreach (glob(sys_get_temp_dir().'/form_test/*') as $file) {
            unlink($file);
        }

        rmdir(sys_get_temp_dir().'/form_test');
    }
}
PKϤ$Z��*http-foundation/Tests/RequestStackTest.phpnu�[���<?php

/*
 * This file is part of the Symfony package.
 *
 * (c) Fabien Potencier <fabien@symfony.com>
 *
 * For the full copyright and license information, please view the LICENSE
 * file that was distributed with this source code.
 */

namespace Symfony\Component\HttpFoundation\Tests;

use Symfony\Component\HttpFoundation\Request;
use Symfony\Component\HttpFoundation\RequestStack;

class RequestStackTest extends \PHPUnit_Framework_TestCase
{
    public function testGetCurrentRequest()
    {
        $requestStack = new RequestStack();
        $this->assertNull($requestStack->getCurrentRequest());

        $request = Request::create('/foo');

        $requestStack->push($request);
        $this->assertSame($request, $requestStack->getCurrentRequest());

        $this->assertSame($request, $requestStack->pop());
        $this->assertNull($requestStack->getCurrentRequest());

        $this->assertNull($requestStack->pop());
    }

    public function testGetMasterRequest()
    {
        $requestStack = new RequestStack();
        $this->assertNull($requestStack->getMasterRequest());

        $masterRequest = Request::create('/foo');
        $subRequest = Request::create('/bar');

        $requestStack->push($masterRequest);
        $requestStack->push($subRequest);

        $this->assertSame($masterRequest, $requestStack->getMasterRequest());
    }

    public function testGetParentRequest()
    {
        $requestStack = new RequestStack();
        $this->assertNull($requestStack->getParentRequest());

        $masterRequest = Request::create('/foo');

        $requestStack->push($masterRequest);
        $this->assertNull($requestStack->getParentRequest());

        $firstSubRequest = Request::create('/bar');

        $requestStack->push($firstSubRequest);
        $this->assertSame($masterRequest, $requestStack->getParentRequest());

        $secondSubRequest = Request::create('/baz');

        $requestStack->push($secondSubRequest);
        $this->assertSame($firstSubRequest, $requestStack->getParentRequest());
    }
}
PKϤ$Z��)<i7i7%http-foundation/Tests/RequestTest.phpnu�[���<?php

/*
 * This file is part of the Symfony package.
 *
 * (c) Fabien Potencier <fabien@symfony.com>
 *
 * For the full copyright and license information, please view the LICENSE
 * file that was distributed with this source code.
 */

namespace Symfony\Component\HttpFoundation\Tests;

use Symfony\Component\HttpFoundation\Session\Storage\MockArraySessionStorage;
use Symfony\Component\HttpFoundation\Session\Session;
use Symfony\Component\HttpFoundation\Request;

class RequestTest extends \PHPUnit_Framework_TestCase
{
    public function testInitialize()
    {
        $request = new Request();

        $request->initialize(array('foo' => 'bar'));
        $this->assertEquals('bar', $request->query->get('foo'), '->initialize() takes an array of query parameters as its first argument');

        $request->initialize(array(), array('foo' => 'bar'));
        $this->assertEquals('bar', $request->request->get('foo'), '->initialize() takes an array of request parameters as its second argument');

        $request->initialize(array(), array(), array('foo' => 'bar'));
        $this->assertEquals('bar', $request->attributes->get('foo'), '->initialize() takes an array of attributes as its third argument');

        $request->initialize(array(), array(), array(), array(), array(), array('HTTP_FOO' => 'bar'));
        $this->assertEquals('bar', $request->headers->get('FOO'), '->initialize() takes an array of HTTP headers as its sixth argument');
    }

    public function testGetLocale()
    {
        $request = new Request();
        $request->setLocale('pl');
        $locale = $request->getLocale();
        $this->assertEquals('pl', $locale);
    }

    public function testGetUser()
    {
        $request = Request::create('http://user_test:password_test@test.com/');
        $user = $request->getUser();

        $this->assertEquals('user_test', $user);
    }

    public function testGetPassword()
    {
        $request = Request::create('http://user_test:password_test@test.com/');
        $password = $request->getPassword();

        $this->assertEquals('password_test', $password);
    }

    public function testIsNoCache()
    {
        $request = new Request();
        $isNoCache = $request->isNoCache();

        $this->assertFalse($isNoCache);
    }

    public function testGetContentType()
    {
        $request = new Request();
        $contentType = $request->getContentType();

        $this->assertNull($contentType);
    }

    public function testSetDefaultLocale()
    {
        $request = new Request();
        $request->setDefaultLocale('pl');
        $locale = $request->getLocale();

        $this->assertEquals('pl', $locale);
    }

    public function testCreate()
    {
        $request = Request::create('http://test.com/foo?bar=baz');
        $this->assertEquals('http://test.com/foo?bar=baz', $request->getUri());
        $this->assertEquals('/foo', $request->getPathInfo());
        $this->assertEquals('bar=baz', $request->getQueryString());
        $this->assertEquals(80, $request->getPort());
        $this->assertEquals('test.com', $request->getHttpHost());
        $this->assertFalse($request->isSecure());

        $request = Request::create('http://test.com/foo', 'GET', array('bar' => 'baz'));
        $this->assertEquals('http://test.com/foo?bar=baz', $request->getUri());
        $this->assertEquals('/foo', $request->getPathInfo());
        $this->assertEquals('bar=baz', $request->getQueryString());
        $this->assertEquals(80, $request->getPort());
        $this->assertEquals('test.com', $request->getHttpHost());
        $this->assertFalse($request->isSecure());

        $request = Request::create('http://test.com/foo?bar=foo', 'GET', array('bar' => 'baz'));
        $this->assertEquals('http://test.com/foo?bar=baz', $request->getUri());
        $this->assertEquals('/foo', $request->getPathInfo());
        $this->assertEquals('bar=baz', $request->getQueryString());
        $this->assertEquals(80, $request->getPort());
        $this->assertEquals('test.com', $request->getHttpHost());
        $this->assertFalse($request->isSecure());

        $request = Request::create('https://test.com/foo?bar=baz');
        $this->assertEquals('https://test.com/foo?bar=baz', $request->getUri());
        $this->assertEquals('/foo', $request->getPathInfo());
        $this->assertEquals('bar=baz', $request->getQueryString());
        $this->assertEquals(443, $request->getPort());
        $this->assertEquals('test.com', $request->getHttpHost());
        $this->assertTrue($request->isSecure());

        $request = Request::create('test.com:90/foo');
        $this->assertEquals('http://test.com:90/foo', $request->getUri());
        $this->assertEquals('/foo', $request->getPathInfo());
        $this->assertEquals('test.com', $request->getHost());
        $this->assertEquals('test.com:90', $request->getHttpHost());
        $this->assertEquals(90, $request->getPort());
        $this->assertFalse($request->isSecure());

        $request = Request::create('https://test.com:90/foo');
        $this->assertEquals('https://test.com:90/foo', $request->getUri());
        $this->assertEquals('/foo', $request->getPathInfo());
        $this->assertEquals('test.com', $request->getHost());
        $this->assertEquals('test.com:90', $request->getHttpHost());
        $this->assertEquals(90, $request->getPort());
        $this->assertTrue($request->isSecure());

        $request = Request::create('https://127.0.0.1:90/foo');
        $this->assertEquals('https://127.0.0.1:90/foo', $request->getUri());
        $this->assertEquals('/foo', $request->getPathInfo());
        $this->assertEquals('127.0.0.1', $request->getHost());
        $this->assertEquals('127.0.0.1:90', $request->getHttpHost());
        $this->assertEquals(90, $request->getPort());
        $this->assertTrue($request->isSecure());

        $request = Request::create('https://[::1]:90/foo');
        $this->assertEquals('https://[::1]:90/foo', $request->getUri());
        $this->assertEquals('/foo', $request->getPathInfo());
        $this->assertEquals('[::1]', $request->getHost());
        $this->assertEquals('[::1]:90', $request->getHttpHost());
        $this->assertEquals(90, $request->getPort());
        $this->assertTrue($request->isSecure());

        $request = Request::create('https://[::1]/foo');
        $this->assertEquals('https://[::1]/foo', $request->getUri());
        $this->assertEquals('/foo', $request->getPathInfo());
        $this->assertEquals('[::1]', $request->getHost());
        $this->assertEquals('[::1]', $request->getHttpHost());
        $this->assertEquals(443, $request->getPort());
        $this->assertTrue($request->isSecure());

        $json = '{"jsonrpc":"2.0","method":"echo","id":7,"params":["Hello World"]}';
        $request = Request::create('http://example.com/jsonrpc', 'POST', array(), array(), array(), array(), $json);
        $this->assertEquals($json, $request->getContent());
        $this->assertFalse($request->isSecure());

        $request = Request::create('http://test.com');
        $this->assertEquals('http://test.com/', $request->getUri());
        $this->assertEquals('/', $request->getPathInfo());
        $this->assertEquals('', $request->getQueryString());
        $this->assertEquals(80, $request->getPort());
        $this->assertEquals('test.com', $request->getHttpHost());
        $this->assertFalse($request->isSecure());

        $request = Request::create('http://test.com?test=1');
        $this->assertEquals('http://test.com/?test=1', $request->getUri());
        $this->assertEquals('/', $request->getPathInfo());
        $this->assertEquals('test=1', $request->getQueryString());
        $this->assertEquals(80, $request->getPort());
        $this->assertEquals('test.com', $request->getHttpHost());
        $this->assertFalse($request->isSecure());

        $request = Request::create('http://test.com:90/?test=1');
        $this->assertEquals('http://test.com:90/?test=1', $request->getUri());
        $this->assertEquals('/', $request->getPathInfo());
        $this->assertEquals('test=1', $request->getQueryString());
        $this->assertEquals(90, $request->getPort());
        $this->assertEquals('test.com:90', $request->getHttpHost());
        $this->assertFalse($request->isSecure());

        $request = Request::create('http://username:password@test.com');
        $this->assertEquals('http://test.com/', $request->getUri());
        $this->assertEquals('/', $request->getPathInfo());
        $this->assertEquals('', $request->getQueryString());
        $this->assertEquals(80, $request->getPort());
        $this->assertEquals('test.com', $request->getHttpHost());
        $this->assertEquals('username', $request->getUser());
        $this->assertEquals('password', $request->getPassword());
        $this->assertFalse($request->isSecure());

        $request = Request::create('http://username@test.com');
        $this->assertEquals('http://test.com/', $request->getUri());
        $this->assertEquals('/', $request->getPathInfo());
        $this->assertEquals('', $request->getQueryString());
        $this->assertEquals(80, $request->getPort());
        $this->assertEquals('test.com', $request->getHttpHost());
        $this->assertEquals('username', $request->getUser());
        $this->assertSame('', $request->getPassword());
        $this->assertFalse($request->isSecure());

        $request = Request::create('http://test.com/?foo');
        $this->assertEquals('/?foo', $request->getRequestUri());
        $this->assertEquals(array('foo' => ''), $request->query->all());

        // assume rewrite rule: (.*) --> app/app.php; app/ is a symlink to a symfony web/ directory
        $request = Request::create('http://test.com/apparthotel-1234', 'GET', array(), array(), array(),
            array(
                'DOCUMENT_ROOT' => '/var/www/www.test.com',
                'SCRIPT_FILENAME' => '/var/www/www.test.com/app/app.php',
                'SCRIPT_NAME' => '/app/app.php',
                'PHP_SELF' => '/app/app.php/apparthotel-1234',
            ));
        $this->assertEquals('http://test.com/apparthotel-1234', $request->getUri());
        $this->assertEquals('/apparthotel-1234', $request->getPathInfo());
        $this->assertEquals('', $request->getQueryString());
        $this->assertEquals(80, $request->getPort());
        $this->assertEquals('test.com', $request->getHttpHost());
        $this->assertFalse($request->isSecure());
    }

    public function testCreateCheckPrecedence()
    {
        // server is used by default
        $request = Request::create('/', 'DELETE', array(), array(), array(), array(
            'HTTP_HOST' => 'example.com',
            'HTTPS' => 'on',
            'SERVER_PORT' => 443,
            'PHP_AUTH_USER' => 'fabien',
            'PHP_AUTH_PW' => 'pa$$',
            'QUERY_STRING' => 'foo=bar',
            'CONTENT_TYPE' => 'application/json',
        ));
        $this->assertEquals('example.com', $request->getHost());
        $this->assertEquals(443, $request->getPort());
        $this->assertTrue($request->isSecure());
        $this->assertEquals('fabien', $request->getUser());
        $this->assertEquals('pa$$', $request->getPassword());
        $this->assertEquals('', $request->getQueryString());
        $this->assertEquals('application/json', $request->headers->get('CONTENT_TYPE'));

        // URI has precedence over server
        $request = Request::create('http://thomas:pokemon@example.net:8080/?foo=bar', 'GET', array(), array(), array(), array(
            'HTTP_HOST' => 'example.com',
            'HTTPS' => 'on',
            'SERVER_PORT' => 443,
        ));
        $this->assertEquals('example.net', $request->getHost());
        $this->assertEquals(8080, $request->getPort());
        $this->assertFalse($request->isSecure());
        $this->assertEquals('thomas', $request->getUser());
        $this->assertEquals('pokemon', $request->getPassword());
        $this->assertEquals('foo=bar', $request->getQueryString());
    }

    public function testDuplicate()
    {
        $request = new Request(array('foo' => 'bar'), array('foo' => 'bar'), array('foo' => 'bar'), array(), array(), array('HTTP_FOO' => 'bar'));
        $dup = $request->duplicate();

        $this->assertEquals($request->query->all(), $dup->query->all(), '->duplicate() duplicates a request an copy the current query parameters');
        $this->assertEquals($request->request->all(), $dup->request->all(), '->duplicate() duplicates a request an copy the current request parameters');
        $this->assertEquals($request->attributes->all(), $dup->attributes->all(), '->duplicate() duplicates a request an copy the current attributes');
        $this->assertEquals($request->headers->all(), $dup->headers->all(), '->duplicate() duplicates a request an copy the current HTTP headers');

        $dup = $request->duplicate(array('foo' => 'foobar'), array('foo' => 'foobar'), array('foo' => 'foobar'), array(), array(), array('HTTP_FOO' => 'foobar'));

        $this->assertEquals(array('foo' => 'foobar'), $dup->query->all(), '->duplicate() overrides the query parameters if provided');
        $this->assertEquals(array('foo' => 'foobar'), $dup->request->all(), '->duplicate() overrides the request parameters if provided');
        $this->assertEquals(array('foo' => 'foobar'), $dup->attributes->all(), '->duplicate() overrides the attributes if provided');
        $this->assertEquals(array('foo' => array('foobar')), $dup->headers->all(), '->duplicate() overrides the HTTP header if provided');
    }

    public function testDuplicateWithFormat()
    {
        $request = new Request(array(), array(), array('_format' => 'json'));
        $dup = $request->duplicate();

        $this->assertEquals('json', $dup->getRequestFormat());
        $this->assertEquals('json', $dup->attributes->get('_format'));

        $request = new Request();
        $request->setRequestFormat('xml');
        $dup = $request->duplicate();

        $this->assertEquals('xml', $dup->getRequestFormat());
    }

    /**
     * @dataProvider getFormatToMimeTypeMapProvider
     */
    public function testGetFormatFromMimeType($format, $mimeTypes)
    {
        $request = new Request();
        foreach ($mimeTypes as $mime) {
            $this->assertEquals($format, $request->getFormat($mime));
        }
        $request->setFormat($format, $mimeTypes);
        foreach ($mimeTypes as $mime) {
            $this->assertEquals($format, $request->getFormat($mime));
        }
    }

    public function testGetFormatFromMimeTypeWithParameters()
    {
        $request = new Request();
        $this->assertEquals('json', $request->getFormat('application/json; charset=utf-8'));
    }

    /**
     * @dataProvider getFormatToMimeTypeMapProvider
     */
    public function testGetMimeTypeFromFormat($format, $mimeTypes)
    {
        if (null !== $format) {
            $request = new Request();
            $this->assertEquals($mimeTypes[0], $request->getMimeType($format));
        }
    }

    public function testGetFormatWithCustomMimeType()
    {
        $request = new Request();
        $request->setFormat('custom', 'application/vnd.foo.api;myversion=2.3');
        $this->assertEquals('custom', $request->getFormat('application/vnd.foo.api;myversion=2.3'));
    }

    public function getFormatToMimeTypeMapProvider()
    {
        return array(
            array(null, array(null, 'unexistent-mime-type')),
            array('txt', array('text/plain')),
            array('js', array('application/javascript', 'application/x-javascript', 'text/javascript')),
            array('css', array('text/css')),
            array('json', array('application/json', 'application/x-json')),
            array('xml', array('text/xml', 'application/xml', 'application/x-xml')),
            array('rdf', array('application/rdf+xml')),
            array('atom', array('application/atom+xml')),
        );
    }

    public function testGetUri()
    {
        $server = array();

        // Standard Request on non default PORT
        // http://host:8080/index.php/path/info?query=string

        $server['HTTP_HOST'] = 'host:8080';
        $server['SERVER_NAME'] = 'servername';
        $server['SERVER_PORT'] = '8080';

        $server['QUERY_STRING'] = 'query=string';
        $server['REQUEST_URI'] = '/index.php/path/info?query=string';
        $server['SCRIPT_NAME'] = '/index.php';
        $server['PATH_INFO'] = '/path/info';
        $server['PATH_TRANSLATED'] = 'redirect:/index.php/path/info';
        $server['PHP_SELF'] = '/index_dev.php/path/info';
        $server['SCRIPT_FILENAME'] = '/some/where/index.php';

        $request = new Request();

        $request->initialize(array(), array(), array(), array(), array(), $server);

        $this->assertEquals('http://host:8080/index.php/path/info?query=string', $request->getUri(), '->getUri() with non default port');

        // Use std port number
        $server['HTTP_HOST'] = 'host';
        $server['SERVER_NAME'] = 'servername';
        $server['SERVER_PORT'] = '80';

        $request->initialize(array(), array(), array(), array(), array(), $server);

        $this->assertEquals('http://host/index.php/path/info?query=string', $request->getUri(), '->getUri() with default port');

        // Without HOST HEADER
        unset($server['HTTP_HOST']);
        $server['SERVER_NAME'] = 'servername';
        $server['SERVER_PORT'] = '80';

        $request->initialize(array(), array(), array(), array(), array(), $server);

        $this->assertEquals('http://servername/index.php/path/info?query=string', $request->getUri(), '->getUri() with default port without HOST_HEADER');

        // Request with URL REWRITING (hide index.php)
        //   RewriteCond %{REQUEST_FILENAME} !-f
        //   RewriteRule ^(.*)$ index.php [QSA,L]
        // http://host:8080/path/info?query=string
        $server = array();
        $server['HTTP_HOST'] = 'host:8080';
        $server['SERVER_NAME'] = 'servername';
        $server['SERVER_PORT'] = '8080';

        $server['REDIRECT_QUERY_STRING'] = 'query=string';
        $server['REDIRECT_URL'] = '/path/info';
        $server['SCRIPT_NAME'] = '/index.php';
        $server['QUERY_STRING'] = 'query=string';
        $server['REQUEST_URI'] = '/path/info?toto=test&1=1';
        $server['SCRIPT_NAME'] = '/index.php';
        $server['PHP_SELF'] = '/index.php';
        $server['SCRIPT_FILENAME'] = '/some/where/index.php';

        $request->initialize(array(), array(), array(), array(), array(), $server);
        $this->assertEquals('http://host:8080/path/info?query=string', $request->getUri(), '->getUri() with rewrite');

        // Use std port number
        //  http://host/path/info?query=string
        $server['HTTP_HOST'] = 'host';
        $server['SERVER_NAME'] = 'servername';
        $server['SERVER_PORT'] = '80';

        $request->initialize(array(), array(), array(), array(), array(), $server);

        $this->assertEquals('http://host/path/info?query=string', $request->getUri(), '->getUri() with rewrite and default port');

        // Without HOST HEADER
        unset($server['HTTP_HOST']);
        $server['SERVER_NAME'] = 'servername';
        $server['SERVER_PORT'] = '80';

        $request->initialize(array(), array(), array(), array(), array(), $server);

        $this->assertEquals('http://servername/path/info?query=string', $request->getUri(), '->getUri() with rewrite, default port without HOST_HEADER');

        // With encoded characters

        $server = array(
            'HTTP_HOST' => 'host:8080',
            'SERVER_NAME' => 'servername',
            'SERVER_PORT' => '8080',
            'QUERY_STRING' => 'query=string',
            'REQUEST_URI' => '/ba%20se/index_dev.php/foo%20bar/in+fo?query=string',
            'SCRIPT_NAME' => '/ba se/index_dev.php',
            'PATH_TRANSLATED' => 'redirect:/index.php/foo bar/in+fo',
            'PHP_SELF' => '/ba se/index_dev.php/path/info',
            'SCRIPT_FILENAME' => '/some/where/ba se/index_dev.php',
        );

        $request->initialize(array(), array(), array(), array(), array(), $server);

        $this->assertEquals(
            'http://host:8080/ba%20se/index_dev.php/foo%20bar/in+fo?query=string',
            $request->getUri()
        );

        // with user info

        $server['PHP_AUTH_USER'] = 'fabien';
        $request->initialize(array(), array(), array(), array(), array(), $server);
        $this->assertEquals('http://host:8080/ba%20se/index_dev.php/foo%20bar/in+fo?query=string', $request->getUri());

        $server['PHP_AUTH_PW'] = 'symfony';
        $request->initialize(array(), array(), array(), array(), array(), $server);
        $this->assertEquals('http://host:8080/ba%20se/index_dev.php/foo%20bar/in+fo?query=string', $request->getUri());
    }

    public function testGetUriForPath()
    {
        $request = Request::create('http://test.com/foo?bar=baz');
        $this->assertEquals('http://test.com/some/path', $request->getUriForPath('/some/path'));

        $request = Request::create('http://test.com:90/foo?bar=baz');
        $this->assertEquals('http://test.com:90/some/path', $request->getUriForPath('/some/path'));

        $request = Request::create('https://test.com/foo?bar=baz');
        $this->assertEquals('https://test.com/some/path', $request->getUriForPath('/some/path'));

        $request = Request::create('https://test.com:90/foo?bar=baz');
        $this->assertEquals('https://test.com:90/some/path', $request->getUriForPath('/some/path'));

        $server = array();

        // Standard Request on non default PORT
        // http://host:8080/index.php/path/info?query=string

        $server['HTTP_HOST'] = 'host:8080';
        $server['SERVER_NAME'] = 'servername';
        $server['SERVER_PORT'] = '8080';

        $server['QUERY_STRING'] = 'query=string';
        $server['REQUEST_URI'] = '/index.php/path/info?query=string';
        $server['SCRIPT_NAME'] = '/index.php';
        $server['PATH_INFO'] = '/path/info';
        $server['PATH_TRANSLATED'] = 'redirect:/index.php/path/info';
        $server['PHP_SELF'] = '/index_dev.php/path/info';
        $server['SCRIPT_FILENAME'] = '/some/where/index.php';

        $request = new Request();

        $request->initialize(array(), array(), array(), array(), array(), $server);

        $this->assertEquals('http://host:8080/index.php/some/path', $request->getUriForPath('/some/path'), '->getUriForPath() with non default port');

        // Use std port number
        $server['HTTP_HOST'] = 'host';
        $server['SERVER_NAME'] = 'servername';
        $server['SERVER_PORT'] = '80';

        $request->initialize(array(), array(), array(), array(), array(), $server);

        $this->assertEquals('http://host/index.php/some/path', $request->getUriForPath('/some/path'), '->getUriForPath() with default port');

        // Without HOST HEADER
        unset($server['HTTP_HOST']);
        $server['SERVER_NAME'] = 'servername';
        $server['SERVER_PORT'] = '80';

        $request->initialize(array(), array(), array(), array(), array(), $server);

        $this->assertEquals('http://servername/index.php/some/path', $request->getUriForPath('/some/path'), '->getUriForPath() with default port without HOST_HEADER');

        // Request with URL REWRITING (hide index.php)
        //   RewriteCond %{REQUEST_FILENAME} !-f
        //   RewriteRule ^(.*)$ index.php [QSA,L]
        // http://host:8080/path/info?query=string
        $server = array();
        $server['HTTP_HOST'] = 'host:8080';
        $server['SERVER_NAME'] = 'servername';
        $server['SERVER_PORT'] = '8080';

        $server['REDIRECT_QUERY_STRING'] = 'query=string';
        $server['REDIRECT_URL'] = '/path/info';
        $server['SCRIPT_NAME'] = '/index.php';
        $server['QUERY_STRING'] = 'query=string';
        $server['REQUEST_URI'] = '/path/info?toto=test&1=1';
        $server['SCRIPT_NAME'] = '/index.php';
        $server['PHP_SELF'] = '/index.php';
        $server['SCRIPT_FILENAME'] = '/some/where/index.php';

        $request->initialize(array(), array(), array(), array(), array(), $server);
        $this->assertEquals('http://host:8080/some/path', $request->getUriForPath('/some/path'), '->getUri() with rewrite');

        // Use std port number
        //  http://host/path/info?query=string
        $server['HTTP_HOST'] = 'host';
        $server['SERVER_NAME'] = 'servername';
        $server['SERVER_PORT'] = '80';

        $request->initialize(array(), array(), array(), array(), array(), $server);

        $this->assertEquals('http://host/some/path', $request->getUriForPath('/some/path'), '->getUriForPath() with rewrite and default port');

        // Without HOST HEADER
        unset($server['HTTP_HOST']);
        $server['SERVER_NAME'] = 'servername';
        $server['SERVER_PORT'] = '80';

        $request->initialize(array(), array(), array(), array(), array(), $server);

        $this->assertEquals('http://servername/some/path', $request->getUriForPath('/some/path'), '->getUriForPath() with rewrite, default port without HOST_HEADER');
        $this->assertEquals('servername', $request->getHttpHost());

        // with user info

        $server['PHP_AUTH_USER'] = 'fabien';
        $request->initialize(array(), array(), array(), array(), array(), $server);
        $this->assertEquals('http://servername/some/path', $request->getUriForPath('/some/path'));

        $server['PHP_AUTH_PW'] = 'symfony';
        $request->initialize(array(), array(), array(), array(), array(), $server);
        $this->assertEquals('http://servername/some/path', $request->getUriForPath('/some/path'));
    }

    /**
     * @dataProvider getRelativeUriForPathData()
     */
    public function testGetRelativeUriForPath($expected, $pathinfo, $path)
    {
        $this->assertEquals($expected, Request::create($pathinfo)->getRelativeUriForPath($path));
    }

    public function getRelativeUriForPathData()
    {
        return array(
            array('me.png', '/foo', '/me.png'),
            array('../me.png', '/foo/bar', '/me.png'),
            array('me.png', '/foo/bar', '/foo/me.png'),
            array('../baz/me.png', '/foo/bar/b', '/foo/baz/me.png'),
            array('../../fooz/baz/me.png', '/foo/bar/b', '/fooz/baz/me.png'),
            array('baz/me.png', '/foo/bar/b', 'baz/me.png'),
        );
    }

    public function testGetUserInfo()
    {
        $request = new Request();

        $server = array('PHP_AUTH_USER' => 'fabien');
        $request->initialize(array(), array(), array(), array(), array(), $server);
        $this->assertEquals('fabien', $request->getUserInfo());

        $server['PHP_AUTH_USER'] = '0';
        $request->initialize(array(), array(), array(), array(), array(), $server);
        $this->assertEquals('0', $request->getUserInfo());

        $server['PHP_AUTH_PW'] = '0';
        $request->initialize(array(), array(), array(), array(), array(), $server);
        $this->assertEquals('0:0', $request->getUserInfo());
    }

    public function testGetSchemeAndHttpHost()
    {
        $request = new Request();

        $server = array();
        $server['SERVER_NAME'] = 'servername';
        $server['SERVER_PORT'] = '90';
        $request->initialize(array(), array(), array(), array(), array(), $server);
        $this->assertEquals('http://servername:90', $request->getSchemeAndHttpHost());

        $server['PHP_AUTH_USER'] = 'fabien';
        $request->initialize(array(), array(), array(), array(), array(), $server);
        $this->assertEquals('http://servername:90', $request->getSchemeAndHttpHost());

        $server['PHP_AUTH_USER'] = '0';
        $request->initialize(array(), array(), array(), array(), array(), $server);
        $this->assertEquals('http://servername:90', $request->getSchemeAndHttpHost());

        $server['PHP_AUTH_PW'] = '0';
        $request->initialize(array(), array(), array(), array(), array(), $server);
        $this->assertEquals('http://servername:90', $request->getSchemeAndHttpHost());
    }

    /**
     * @dataProvider getQueryStringNormalizationData
     */
    public function testGetQueryString($query, $expectedQuery, $msg)
    {
        $request = new Request();

        $request->server->set('QUERY_STRING', $query);
        $this->assertSame($expectedQuery, $request->getQueryString(), $msg);
    }

    public function getQueryStringNormalizationData()
    {
        return array(
            array('foo', 'foo', 'works with valueless parameters'),
            array('foo=', 'foo=', 'includes a dangling equal sign'),
            array('bar=&foo=bar', 'bar=&foo=bar', '->works with empty parameters'),
            array('foo=bar&bar=', 'bar=&foo=bar', 'sorts keys alphabetically'),

            // GET parameters, that are submitted from a HTML form, encode spaces as "+" by default (as defined in enctype application/x-www-form-urlencoded).
            // PHP also converts "+" to spaces when filling the global _GET or when using the function parse_str.
            array('him=John%20Doe&her=Jane+Doe', 'her=Jane%20Doe&him=John%20Doe', 'normalizes spaces in both encodings "%20" and "+"'),

            array('foo[]=1&foo[]=2', 'foo%5B%5D=1&foo%5B%5D=2', 'allows array notation'),
            array('foo=1&foo=2', 'foo=1&foo=2', 'allows repeated parameters'),
            array('pa%3Dram=foo%26bar%3Dbaz&test=test', 'pa%3Dram=foo%26bar%3Dbaz&test=test', 'works with encoded delimiters'),
            array('0', '0', 'allows "0"'),
            array('Jane Doe&John%20Doe', 'Jane%20Doe&John%20Doe', 'normalizes encoding in keys'),
            array('her=Jane Doe&him=John%20Doe', 'her=Jane%20Doe&him=John%20Doe', 'normalizes encoding in values'),
            array('foo=bar&&&test&&', 'foo=bar&test', 'removes unneeded delimiters'),
            array('formula=e=m*c^2', 'formula=e%3Dm%2Ac%5E2', 'correctly treats only the first "=" as delimiter and the next as value'),

            // Ignore pairs with empty key, even if there was a value, e.g. "=value", as such nameless values cannot be retrieved anyway.
            // PHP also does not include them when building _GET.
            array('foo=bar&=a=b&=x=y', 'foo=bar', 'removes params with empty key'),
        );
    }

    public function testGetQueryStringReturnsNull()
    {
        $request = new Request();

        $this->assertNull($request->getQueryString(), '->getQueryString() returns null for non-existent query string');

        $request->server->set('QUERY_STRING', '');
        $this->assertNull($request->getQueryString(), '->getQueryString() returns null for empty query string');
    }

    public function testGetHost()
    {
        $request = new Request();

        $request->initialize(array('foo' => 'bar'));
        $this->assertEquals('', $request->getHost(), '->getHost() return empty string if not initialized');

        $request->initialize(array(), array(), array(), array(), array(), array('HTTP_HOST' => 'www.example.com'));
        $this->assertEquals('www.example.com', $request->getHost(), '->getHost() from Host Header');

        // Host header with port number
        $request->initialize(array(), array(), array(), array(), array(), array('HTTP_HOST' => 'www.example.com:8080'));
        $this->assertEquals('www.example.com', $request->getHost(), '->getHost() from Host Header with port number');

        // Server values
        $request->initialize(array(), array(), array(), array(), array(), array('SERVER_NAME' => 'www.example.com'));
        $this->assertEquals('www.example.com', $request->getHost(), '->getHost() from server name');

        $request->initialize(array(), array(), array(), array(), array(), array('SERVER_NAME' => 'www.example.com', 'HTTP_HOST' => 'www.host.com'));
        $this->assertEquals('www.host.com', $request->getHost(), '->getHost() value from Host header has priority over SERVER_NAME ');
    }

    public function testGetPort()
    {
        $request = Request::create('http://example.com', 'GET', array(), array(), array(), array(
            'HTTP_X_FORWARDED_PROTO' => 'https',
            'HTTP_X_FORWARDED_PORT' => '443',
        ));
        $port = $request->getPort();

        $this->assertEquals(80, $port, 'Without trusted proxies FORWARDED_PROTO and FORWARDED_PORT are ignored.');

        Request::setTrustedProxies(array('1.1.1.1'));
        $request = Request::create('http://example.com', 'GET', array(), array(), array(), array(
            'HTTP_X_FORWARDED_PROTO' => 'https',
            'HTTP_X_FORWARDED_PORT' => '8443',
        ));
        $this->assertEquals(80, $request->getPort(), 'With PROTO and PORT on untrusted connection server value takes precedence.');
        $request->server->set('REMOTE_ADDR', '1.1.1.1');
        $this->assertEquals(8443, $request->getPort(), 'With PROTO and PORT set PORT takes precedence.');

        $request = Request::create('http://example.com', 'GET', array(), array(), array(), array(
            'HTTP_X_FORWARDED_PROTO' => 'https',
        ));
        $this->assertEquals(80, $request->getPort(), 'With only PROTO set getPort() ignores trusted headers on untrusted connection.');
        $request->server->set('REMOTE_ADDR', '1.1.1.1');
        $this->assertEquals(443, $request->getPort(), 'With only PROTO set getPort() defaults to 443.');

        $request = Request::create('http://example.com', 'GET', array(), array(), array(), array(
            'HTTP_X_FORWARDED_PROTO' => 'http',
        ));
        $this->assertEquals(80, $request->getPort(), 'If X_FORWARDED_PROTO is set to HTTP getPort() ignores trusted headers on untrusted connection.');
        $request->server->set('REMOTE_ADDR', '1.1.1.1');
        $this->assertEquals(80, $request->getPort(), 'If X_FORWARDED_PROTO is set to HTTP getPort() returns port of the original request.');

        $request = Request::create('http://example.com', 'GET', array(), array(), array(), array(
            'HTTP_X_FORWARDED_PROTO' => 'On',
        ));
        $this->assertEquals(80, $request->getPort(), 'With only PROTO set and value is On, getPort() ignores trusted headers on untrusted connection.');
        $request->server->set('REMOTE_ADDR', '1.1.1.1');
        $this->assertEquals(443, $request->getPort(), 'With only PROTO set and value is On, getPort() defaults to 443.');

        $request = Request::create('http://example.com', 'GET', array(), array(), array(), array(
            'HTTP_X_FORWARDED_PROTO' => '1',
        ));
        $this->assertEquals(80, $request->getPort(), 'With only PROTO set and value is 1, getPort() ignores trusted headers on untrusted connection.');
        $request->server->set('REMOTE_ADDR', '1.1.1.1');
        $this->assertEquals(443, $request->getPort(), 'With only PROTO set and value is 1, getPort() defaults to 443.');

        $request = Request::create('http://example.com', 'GET', array(), array(), array(), array(
            'HTTP_X_FORWARDED_PROTO' => 'something-else',
        ));
        $port = $request->getPort();
        $this->assertEquals(80, $port, 'With only PROTO set and value is not recognized, getPort() defaults to 80.');

        Request::setTrustedProxies(array());
    }

    /**
     * @expectedException \RuntimeException
     */
    public function testGetHostWithFakeHttpHostValue()
    {
        $request = new Request();
        $request->initialize(array(), array(), array(), array(), array(), array('HTTP_HOST' => 'www.host.com?query=string'));
        $request->getHost();
    }

    public function testGetSetMethod()
    {
        $request = new Request();

        $this->assertEquals('GET', $request->getMethod(), '->getMethod() returns GET if no method is defined');

        $request->setMethod('get');
        $this->assertEquals('GET', $request->getMethod(), '->getMethod() returns an uppercased string');

        $request->setMethod('PURGE');
        $this->assertEquals('PURGE', $request->getMethod(), '->getMethod() returns the method even if it is not a standard one');

        $request->setMethod('POST');
        $this->assertEquals('POST', $request->getMethod(), '->getMethod() returns the method POST if no _method is defined');

        $request->setMethod('POST');
        $request->request->set('_method', 'purge');
        $this->assertEquals('POST', $request->getMethod(), '->getMethod() does not return the method from _method if defined and POST but support not enabled');

        $request = new Request();
        $request->setMethod('POST');
        $request->request->set('_method', 'purge');

        $this->assertFalse(Request::getHttpMethodParameterOverride(), 'httpMethodParameterOverride should be disabled by default');

        Request::enableHttpMethodParameterOverride();

        $this->assertTrue(Request::getHttpMethodParameterOverride(), 'httpMethodParameterOverride should be enabled now but it is not');

        $this->assertEquals('PURGE', $request->getMethod(), '->getMethod() returns the method from _method if defined and POST');
        $this->disableHttpMethodParameterOverride();

        $request = new Request();
        $request->setMethod('POST');
        $request->query->set('_method', 'purge');
        $this->assertEquals('POST', $request->getMethod(), '->getMethod() does not return the method from _method if defined and POST but support not enabled');

        $request = new Request();
        $request->setMethod('POST');
        $request->query->set('_method', 'purge');
        Request::enableHttpMethodParameterOverride();
        $this->assertEquals('PURGE', $request->getMethod(), '->getMethod() returns the method from _method if defined and POST');
        $this->disableHttpMethodParameterOverride();

        $request = new Request();
        $request->setMethod('POST');
        $request->headers->set('X-HTTP-METHOD-OVERRIDE', 'delete');
        $this->assertEquals('DELETE', $request->getMethod(), '->getMethod() returns the method from X-HTTP-Method-Override even though _method is set if defined and POST');

        $request = new Request();
        $request->setMethod('POST');
        $request->headers->set('X-HTTP-METHOD-OVERRIDE', 'delete');
        $this->assertEquals('DELETE', $request->getMethod(), '->getMethod() returns the method from X-HTTP-Method-Override if defined and POST');
    }

    /**
     * @dataProvider testGetClientIpsProvider
     */
    public function testGetClientIp($expected, $remoteAddr, $httpForwardedFor, $trustedProxies)
    {
        $request = $this->getRequestInstanceForClientIpTests($remoteAddr, $httpForwardedFor, $trustedProxies);

        $this->assertEquals($expected[0], $request->getClientIp());

        Request::setTrustedProxies(array());
    }

    /**
     * @dataProvider testGetClientIpsProvider
     */
    public function testGetClientIps($expected, $remoteAddr, $httpForwardedFor, $trustedProxies)
    {
        $request = $this->getRequestInstanceForClientIpTests($remoteAddr, $httpForwardedFor, $trustedProxies);

        $this->assertEquals($expected, $request->getClientIps());

        Request::setTrustedProxies(array());
    }

    /**
     * @dataProvider testGetClientIpsForwardedProvider
     */
    public function testGetClientIpsForwarded($expected, $remoteAddr, $httpForwarded, $trustedProxies)
    {
        $request = $this->getRequestInstanceForClientIpsForwardedTests($remoteAddr, $httpForwarded, $trustedProxies);

        $this->assertEquals($expected, $request->getClientIps());

        Request::setTrustedProxies(array());
    }

    public function testGetClientIpsForwardedProvider()
    {
        //              $expected                                  $remoteAddr  $httpForwarded                                       $trustedProxies
        return array(
            array(array('127.0.0.1'),                              '127.0.0.1', 'for="_gazonk"',                                      null),
            array(array('127.0.0.1'),                              '127.0.0.1', 'for="_gazonk"',                                      array('127.0.0.1')),
            array(array('88.88.88.88'),                            '127.0.0.1', 'for="88.88.88.88:80"',                               array('127.0.0.1')),
            array(array('192.0.2.60'),                             '::1',       'for=192.0.2.60;proto=http;by=203.0.113.43',          array('::1')),
            array(array('2620:0:1cfe:face:b00c::3', '192.0.2.43'), '::1',       'for=192.0.2.43, for=2620:0:1cfe:face:b00c::3',       array('::1')),
            array(array('2001:db8:cafe::17'),                      '::1',       'for="[2001:db8:cafe::17]:4711',                      array('::1')),
        );
    }

    public function testGetClientIpsProvider()
    {
        //        $expected                   $remoteAddr                $httpForwardedFor            $trustedProxies
        return array(
            // simple IPv4
            array(array('88.88.88.88'),              '88.88.88.88',              null,                        null),
            // trust the IPv4 remote addr
            array(array('88.88.88.88'),              '88.88.88.88',              null,                        array('88.88.88.88')),

            // simple IPv6
            array(array('::1'),                      '::1',                      null,                        null),
            // trust the IPv6 remote addr
            array(array('::1'),                      '::1',                      null,                        array('::1')),

            // forwarded for with remote IPv4 addr not trusted
            array(array('127.0.0.1'),                '127.0.0.1',                '88.88.88.88',               null),
            // forwarded for with remote IPv4 addr trusted
            array(array('88.88.88.88'),              '127.0.0.1',                '88.88.88.88',               array('127.0.0.1')),
            // forwarded for with remote IPv4 and all FF addrs trusted
            array(array('88.88.88.88'),              '127.0.0.1',                '88.88.88.88',               array('127.0.0.1', '88.88.88.88')),
            // forwarded for with remote IPv4 range trusted
            array(array('88.88.88.88'),              '123.45.67.89',             '88.88.88.88',               array('123.45.67.0/24')),

            // forwarded for with remote IPv6 addr not trusted
            array(array('1620:0:1cfe:face:b00c::3'), '1620:0:1cfe:face:b00c::3', '2620:0:1cfe:face:b00c::3',  null),
            // forwarded for with remote IPv6 addr trusted
            array(array('2620:0:1cfe:face:b00c::3'), '1620:0:1cfe:face:b00c::3', '2620:0:1cfe:face:b00c::3',  array('1620:0:1cfe:face:b00c::3')),
            // forwarded for with remote IPv6 range trusted
            array(array('88.88.88.88'),              '2a01:198:603:0:396e:4789:8e99:890f', '88.88.88.88',     array('2a01:198:603:0::/65')),

            // multiple forwarded for with remote IPv4 addr trusted
            array(array('88.88.88.88', '87.65.43.21', '127.0.0.1'), '123.45.67.89', '127.0.0.1, 87.65.43.21, 88.88.88.88', array('123.45.67.89')),
            // multiple forwarded for with remote IPv4 addr and some reverse proxies trusted
            array(array('87.65.43.21', '127.0.0.1'), '123.45.67.89',             '127.0.0.1, 87.65.43.21, 88.88.88.88', array('123.45.67.89', '88.88.88.88')),
            // multiple forwarded for with remote IPv4 addr and some reverse proxies trusted but in the middle
            array(array('88.88.88.88', '127.0.0.1'), '123.45.67.89',             '127.0.0.1, 87.65.43.21, 88.88.88.88', array('123.45.67.89', '87.65.43.21')),
            // multiple forwarded for with remote IPv4 addr and all reverse proxies trusted
            array(array('127.0.0.1'),                '123.45.67.89',             '127.0.0.1, 87.65.43.21, 88.88.88.88', array('123.45.67.89', '87.65.43.21', '88.88.88.88', '127.0.0.1')),

            // multiple forwarded for with remote IPv6 addr trusted
            array(array('2620:0:1cfe:face:b00c::3', '3620:0:1cfe:face:b00c::3'), '1620:0:1cfe:face:b00c::3', '3620:0:1cfe:face:b00c::3,2620:0:1cfe:face:b00c::3', array('1620:0:1cfe:face:b00c::3')),
            // multiple forwarded for with remote IPv6 addr and some reverse proxies trusted
            array(array('3620:0:1cfe:face:b00c::3'), '1620:0:1cfe:face:b00c::3', '3620:0:1cfe:face:b00c::3,2620:0:1cfe:face:b00c::3', array('1620:0:1cfe:face:b00c::3', '2620:0:1cfe:face:b00c::3')),
            // multiple forwarded for with remote IPv4 addr and some reverse proxies trusted but in the middle
            array(array('2620:0:1cfe:face:b00c::3', '4620:0:1cfe:face:b00c::3'), '1620:0:1cfe:face:b00c::3', '4620:0:1cfe:face:b00c::3,3620:0:1cfe:face:b00c::3,2620:0:1cfe:face:b00c::3', array('1620:0:1cfe:face:b00c::3', '3620:0:1cfe:face:b00c::3')),

            // client IP with port
            array(array('88.88.88.88'), '127.0.0.1', '88.88.88.88:12345, 127.0.0.1', array('127.0.0.1')),

            // invalid forwarded IP is ignored
            array(array('88.88.88.88'), '127.0.0.1', 'unknown,88.88.88.88', array('127.0.0.1')),
            array(array('88.88.88.88'), '127.0.0.1', '}__test|O:21:&quot;JDatabaseDriverMysqli&quot;:3:{s:2,88.88.88.88', array('127.0.0.1')),
        );
    }

    public function testGetContentWorksTwiceInDefaultMode()
    {
        $req = new Request();
        $this->assertEquals('', $req->getContent());
        $this->assertEquals('', $req->getContent());
    }

    public function testGetContentReturnsResource()
    {
        $req = new Request();
        $retval = $req->getContent(true);
        $this->assertInternalType('resource', $retval);
        $this->assertEquals('', fread($retval, 1));
        $this->assertTrue(feof($retval));
    }

    public function testGetContentReturnsResourceWhenContentSetInConstructor()
    {
        $req = new Request(array(), array(), array(), array(), array(), array(), 'MyContent');
        $resource = $req->getContent(true);

        $this->assertTrue(is_resource($resource));
        $this->assertEquals('MyContent', stream_get_contents($resource));
    }

    public function testContentAsResource()
    {
        $resource = fopen('php://memory', 'r+');
        fwrite($resource, 'My other content');
        rewind($resource);

        $req = new Request(array(), array(), array(), array(), array(), array(), $resource);
        $this->assertEquals('My other content', stream_get_contents($req->getContent(true)));
        $this->assertEquals('My other content', $req->getContent());
    }

    /**
     * @expectedException \LogicException
     * @dataProvider getContentCantBeCalledTwiceWithResourcesProvider
     */
    public function testGetContentCantBeCalledTwiceWithResources($first, $second)
    {
        if (PHP_VERSION_ID >= 50600) {
            $this->markTestSkipped('PHP >= 5.6 allows to open php://input several times.');
        }

        $req = new Request();
        $req->getContent($first);
        $req->getContent($second);
    }

    /**
     * @dataProvider getContentCantBeCalledTwiceWithResourcesProvider
     * @requires PHP 5.6
     */
    public function testGetContentCanBeCalledTwiceWithResources($first, $second)
    {
        $req = new Request();
        $a = $req->getContent($first);
        $b = $req->getContent($second);

        if ($first) {
            $a = stream_get_contents($a);
        }

        if ($second) {
            $b = stream_get_contents($b);
        }

        $this->assertEquals($a, $b);
    }

    public function getContentCantBeCalledTwiceWithResourcesProvider()
    {
        return array(
            'Resource then fetch' => array(true, false),
            'Resource then resource' => array(true, true),
        );
    }

    public function provideOverloadedMethods()
    {
        return array(
            array('PUT'),
            array('DELETE'),
            array('PATCH'),
            array('put'),
            array('delete'),
            array('patch'),

        );
    }

    /**
     * @dataProvider provideOverloadedMethods
     */
    public function testCreateFromGlobals($method)
    {
        $normalizedMethod = strtoupper($method);

        $_GET['foo1'] = 'bar1';
        $_POST['foo2'] = 'bar2';
        $_COOKIE['foo3'] = 'bar3';
        $_FILES['foo4'] = array('bar4');
        $_SERVER['foo5'] = 'bar5';

        $request = Request::createFromGlobals();
        $this->assertEquals('bar1', $request->query->get('foo1'), '::fromGlobals() uses values from $_GET');
        $this->assertEquals('bar2', $request->request->get('foo2'), '::fromGlobals() uses values from $_POST');
        $this->assertEquals('bar3', $request->cookies->get('foo3'), '::fromGlobals() uses values from $_COOKIE');
        $this->assertEquals(array('bar4'), $request->files->get('foo4'), '::fromGlobals() uses values from $_FILES');
        $this->assertEquals('bar5', $request->server->get('foo5'), '::fromGlobals() uses values from $_SERVER');

        unset($_GET['foo1'], $_POST['foo2'], $_COOKIE['foo3'], $_FILES['foo4'], $_SERVER['foo5']);

        $_SERVER['REQUEST_METHOD'] = $method;
        $_SERVER['CONTENT_TYPE'] = 'application/x-www-form-urlencoded';
        $request = RequestContentProxy::createFromGlobals();
        $this->assertEquals($normalizedMethod, $request->getMethod());
        $this->assertEquals('mycontent', $request->request->get('content'));

        unset($_SERVER['REQUEST_METHOD'], $_SERVER['CONTENT_TYPE']);

        Request::createFromGlobals();
        Request::enableHttpMethodParameterOverride();
        $_POST['_method'] = $method;
        $_POST['foo6'] = 'bar6';
        $_SERVER['REQUEST_METHOD'] = 'PoSt';
        $request = Request::createFromGlobals();
        $this->assertEquals($normalizedMethod, $request->getMethod());
        $this->assertEquals('POST', $request->getRealMethod());
        $this->assertEquals('bar6', $request->request->get('foo6'));

        unset($_POST['_method'], $_POST['foo6'], $_SERVER['REQUEST_METHOD']);
        $this->disableHttpMethodParameterOverride();
    }

    public function testOverrideGlobals()
    {
        $request = new Request();
        $request->initialize(array('foo' => 'bar'));

        // as the Request::overrideGlobals really work, it erase $_SERVER, so we must backup it
        $server = $_SERVER;

        $request->overrideGlobals();

        $this->assertEquals(array('foo' => 'bar'), $_GET);

        $request->initialize(array(), array('foo' => 'bar'));
        $request->overrideGlobals();

        $this->assertEquals(array('foo' => 'bar'), $_POST);

        $this->assertArrayNotHasKey('HTTP_X_FORWARDED_PROTO', $_SERVER);

        $request->headers->set('X_FORWARDED_PROTO', 'https');

        Request::setTrustedProxies(array('1.1.1.1'));
        $this->assertFalse($request->isSecure());
        $request->server->set('REMOTE_ADDR', '1.1.1.1');
        $this->assertTrue($request->isSecure());
        Request::setTrustedProxies(array());

        $request->overrideGlobals();

        $this->assertArrayHasKey('HTTP_X_FORWARDED_PROTO', $_SERVER);

        $request->headers->set('CONTENT_TYPE', 'multipart/form-data');
        $request->headers->set('CONTENT_LENGTH', 12345);

        $request->overrideGlobals();

        $this->assertArrayHasKey('CONTENT_TYPE', $_SERVER);
        $this->assertArrayHasKey('CONTENT_LENGTH', $_SERVER);

        $request->initialize(array('foo' => 'bar', 'baz' => 'foo'));
        $request->query->remove('baz');

        $request->overrideGlobals();

        $this->assertEquals(array('foo' => 'bar'), $_GET);
        $this->assertEquals('foo=bar', $_SERVER['QUERY_STRING']);
        $this->assertEquals('foo=bar', $request->server->get('QUERY_STRING'));

        // restore initial $_SERVER array
        $_SERVER = $server;
    }

    public function testGetScriptName()
    {
        $request = new Request();
        $this->assertEquals('', $request->getScriptName());

        $server = array();
        $server['SCRIPT_NAME'] = '/index.php';

        $request->initialize(array(), array(), array(), array(), array(), $server);

        $this->assertEquals('/index.php', $request->getScriptName());

        $server = array();
        $server['ORIG_SCRIPT_NAME'] = '/frontend.php';
        $request->initialize(array(), array(), array(), array(), array(), $server);

        $this->assertEquals('/frontend.php', $request->getScriptName());

        $server = array();
        $server['SCRIPT_NAME'] = '/index.php';
        $server['ORIG_SCRIPT_NAME'] = '/frontend.php';
        $request->initialize(array(), array(), array(), array(), array(), $server);

        $this->assertEquals('/index.php', $request->getScriptName());
    }

    public function testGetBasePath()
    {
        $request = new Request();
        $this->assertEquals('', $request->getBasePath());

        $server = array();
        $server['SCRIPT_FILENAME'] = '/some/where/index.php';
        $request->initialize(array(), array(), array(), array(), array(), $server);
        $this->assertEquals('', $request->getBasePath());

        $server = array();
        $server['SCRIPT_FILENAME'] = '/some/where/index.php';
        $server['SCRIPT_NAME'] = '/index.php';
        $request->initialize(array(), array(), array(), array(), array(), $server);

        $this->assertEquals('', $request->getBasePath());

        $server = array();
        $server['SCRIPT_FILENAME'] = '/some/where/index.php';
        $server['PHP_SELF'] = '/index.php';
        $request->initialize(array(), array(), array(), array(), array(), $server);

        $this->assertEquals('', $request->getBasePath());

        $server = array();
        $server['SCRIPT_FILENAME'] = '/some/where/index.php';
        $server['ORIG_SCRIPT_NAME'] = '/index.php';
        $request->initialize(array(), array(), array(), array(), array(), $server);

        $this->assertEquals('', $request->getBasePath());
    }

    public function testGetPathInfo()
    {
        $request = new Request();
        $this->assertEquals('/', $request->getPathInfo());

        $server = array();
        $server['REQUEST_URI'] = '/path/info';
        $request->initialize(array(), array(), array(), array(), array(), $server);

        $this->assertEquals('/path/info', $request->getPathInfo());

        $server = array();
        $server['REQUEST_URI'] = '/path%20test/info';
        $request->initialize(array(), array(), array(), array(), array(), $server);

        $this->assertEquals('/path%20test/info', $request->getPathInfo());
    }

    public function testGetPreferredLanguage()
    {
        $request = new Request();
        $this->assertNull($request->getPreferredLanguage());
        $this->assertNull($request->getPreferredLanguage(array()));
        $this->assertEquals('fr', $request->getPreferredLanguage(array('fr')));
        $this->assertEquals('fr', $request->getPreferredLanguage(array('fr', 'en')));
        $this->assertEquals('en', $request->getPreferredLanguage(array('en', 'fr')));
        $this->assertEquals('fr-ch', $request->getPreferredLanguage(array('fr-ch', 'fr-fr')));

        $request = new Request();
        $request->headers->set('Accept-language', 'zh, en-us; q=0.8, en; q=0.6');
        $this->assertEquals('en', $request->getPreferredLanguage(array('en', 'en-us')));

        $request = new Request();
        $request->headers->set('Accept-language', 'zh, en-us; q=0.8, en; q=0.6');
        $this->assertEquals('en', $request->getPreferredLanguage(array('fr', 'en')));

        $request = new Request();
        $request->headers->set('Accept-language', 'zh, en-us; q=0.8');
        $this->assertEquals('en', $request->getPreferredLanguage(array('fr', 'en')));

        $request = new Request();
        $request->headers->set('Accept-language', 'zh, en-us; q=0.8, fr-fr; q=0.6, fr; q=0.5');
        $this->assertEquals('en', $request->getPreferredLanguage(array('fr', 'en')));
    }

    public function testIsXmlHttpRequest()
    {
        $request = new Request();
        $this->assertFalse($request->isXmlHttpRequest());

        $request->headers->set('X-Requested-With', 'XMLHttpRequest');
        $this->assertTrue($request->isXmlHttpRequest());

        $request->headers->remove('X-Requested-With');
        $this->assertFalse($request->isXmlHttpRequest());
    }

    /**
     * @requires extension intl
     */
    public function testIntlLocale()
    {
        $request = new Request();

        $request->setDefaultLocale('fr');
        $this->assertEquals('fr', $request->getLocale());
        $this->assertEquals('fr', \Locale::getDefault());

        $request->setLocale('en');
        $this->assertEquals('en', $request->getLocale());
        $this->assertEquals('en', \Locale::getDefault());

        $request->setDefaultLocale('de');
        $this->assertEquals('en', $request->getLocale());
        $this->assertEquals('en', \Locale::getDefault());
    }

    public function testGetCharsets()
    {
        $request = new Request();
        $this->assertEquals(array(), $request->getCharsets());
        $request->headers->set('Accept-Charset', 'ISO-8859-1, US-ASCII, UTF-8; q=0.8, ISO-10646-UCS-2; q=0.6');
        $this->assertEquals(array(), $request->getCharsets()); // testing caching

        $request = new Request();
        $request->headers->set('Accept-Charset', 'ISO-8859-1, US-ASCII, UTF-8; q=0.8, ISO-10646-UCS-2; q=0.6');
        $this->assertEquals(array('ISO-8859-1', 'US-ASCII', 'UTF-8', 'ISO-10646-UCS-2'), $request->getCharsets());

        $request = new Request();
        $request->headers->set('Accept-Charset', 'ISO-8859-1,utf-8;q=0.7,*;q=0.7');
        $this->assertEquals(array('ISO-8859-1', 'utf-8', '*'), $request->getCharsets());
    }

    public function testGetEncodings()
    {
        $request = new Request();
        $this->assertEquals(array(), $request->getEncodings());
        $request->headers->set('Accept-Encoding', 'gzip,deflate,sdch');
        $this->assertEquals(array(), $request->getEncodings()); // testing caching

        $request = new Request();
        $request->headers->set('Accept-Encoding', 'gzip,deflate,sdch');
        $this->assertEquals(array('gzip', 'deflate', 'sdch'), $request->getEncodings());

        $request = new Request();
        $request->headers->set('Accept-Encoding', 'gzip;q=0.4,deflate;q=0.9,compress;q=0.7');
        $this->assertEquals(array('deflate', 'compress', 'gzip'), $request->getEncodings());
    }

    public function testGetAcceptableContentTypes()
    {
        $request = new Request();
        $this->assertEquals(array(), $request->getAcceptableContentTypes());
        $request->headers->set('Accept', 'application/vnd.wap.wmlscriptc, text/vnd.wap.wml, application/vnd.wap.xhtml+xml, application/xhtml+xml, text/html, multipart/mixed, */*');
        $this->assertEquals(array(), $request->getAcceptableContentTypes()); // testing caching

        $request = new Request();
        $request->headers->set('Accept', 'application/vnd.wap.wmlscriptc, text/vnd.wap.wml, application/vnd.wap.xhtml+xml, application/xhtml+xml, text/html, multipart/mixed, */*');
        $this->assertEquals(array('application/vnd.wap.wmlscriptc', 'text/vnd.wap.wml', 'application/vnd.wap.xhtml+xml', 'application/xhtml+xml', 'text/html', 'multipart/mixed', '*/*'), $request->getAcceptableContentTypes());
    }

    public function testGetLanguages()
    {
        $request = new Request();
        $this->assertEquals(array(), $request->getLanguages());

        $request = new Request();
        $request->headers->set('Accept-language', 'zh, en-us; q=0.8, en; q=0.6');
        $this->assertEquals(array('zh', 'en_US', 'en'), $request->getLanguages());
        $this->assertEquals(array('zh', 'en_US', 'en'), $request->getLanguages());

        $request = new Request();
        $request->headers->set('Accept-language', 'zh, en-us; q=0.6, en; q=0.8');
        $this->assertEquals(array('zh', 'en', 'en_US'), $request->getLanguages()); // Test out of order qvalues

        $request = new Request();
        $request->headers->set('Accept-language', 'zh, en, en-us');
        $this->assertEquals(array('zh', 'en', 'en_US'), $request->getLanguages()); // Test equal weighting without qvalues

        $request = new Request();
        $request->headers->set('Accept-language', 'zh; q=0.6, en, en-us; q=0.6');
        $this->assertEquals(array('en', 'zh', 'en_US'), $request->getLanguages()); // Test equal weighting with qvalues

        $request = new Request();
        $request->headers->set('Accept-language', 'zh, i-cherokee; q=0.6');
        $this->assertEquals(array('zh', 'cherokee'), $request->getLanguages());
    }

    public function testGetRequestFormat()
    {
        $request = new Request();
        $this->assertEquals('html', $request->getRequestFormat());

        $request = new Request();
        $this->assertNull($request->getRequestFormat(null));

        $request = new Request();
        $this->assertNull($request->setRequestFormat('foo'));
        $this->assertEquals('foo', $request->getRequestFormat(null));
    }

    public function testHasSession()
    {
        $request = new Request();

        $this->assertFalse($request->hasSession());
        $request->setSession(new Session(new MockArraySessionStorage()));
        $this->assertTrue($request->hasSession());
    }

    public function testGetSession()
    {
        $request = new Request();

        $request->setSession(new Session(new MockArraySessionStorage()));
        $this->assertTrue($request->hasSession());

        $session = $request->getSession();
        $this->assertObjectHasAttribute('storage', $session);
        $this->assertObjectHasAttribute('flashName', $session);
        $this->assertObjectHasAttribute('attributeName', $session);
    }

    public function testHasPreviousSession()
    {
        $request = new Request();

        $this->assertFalse($request->hasPreviousSession());
        $request->cookies->set('MOCKSESSID', 'foo');
        $this->assertFalse($request->hasPreviousSession());
        $request->setSession(new Session(new MockArraySessionStorage()));
        $this->assertTrue($request->hasPreviousSession());
    }

    public function testToString()
    {
        $request = new Request();

        $request->headers->set('Accept-language', 'zh, en-us; q=0.8, en; q=0.6');

        $this->assertContains('Accept-Language: zh, en-us; q=0.8, en; q=0.6', $request->__toString());
    }

    public function testIsMethod()
    {
        $request = new Request();
        $request->setMethod('POST');
        $this->assertTrue($request->isMethod('POST'));
        $this->assertTrue($request->isMethod('post'));
        $this->assertFalse($request->isMethod('GET'));
        $this->assertFalse($request->isMethod('get'));

        $request->setMethod('GET');
        $this->assertTrue($request->isMethod('GET'));
        $this->assertTrue($request->isMethod('get'));
        $this->assertFalse($request->isMethod('POST'));
        $this->assertFalse($request->isMethod('post'));
    }

    /**
     * @dataProvider getBaseUrlData
     */
    public function testGetBaseUrl($uri, $server, $expectedBaseUrl, $expectedPathInfo)
    {
        $request = Request::create($uri, 'GET', array(), array(), array(), $server);

        $this->assertSame($expectedBaseUrl, $request->getBaseUrl(), 'baseUrl');
        $this->assertSame($expectedPathInfo, $request->getPathInfo(), 'pathInfo');
    }

    public function getBaseUrlData()
    {
        return array(
            array(
                '/fruit/strawberry/1234index.php/blah',
                array(
                    'SCRIPT_FILENAME' => 'E:/Sites/cc-new/public_html/fruit/index.php',
                    'SCRIPT_NAME' => '/fruit/index.php',
                    'PHP_SELF' => '/fruit/index.php',
                ),
                '/fruit',
                '/strawberry/1234index.php/blah',
            ),
            array(
                '/fruit/strawberry/1234index.php/blah',
                array(
                    'SCRIPT_FILENAME' => 'E:/Sites/cc-new/public_html/index.php',
                    'SCRIPT_NAME' => '/index.php',
                    'PHP_SELF' => '/index.php',
                ),
                '',
                '/fruit/strawberry/1234index.php/blah',
            ),
            array(
                '/foo%20bar/',
                array(
                    'SCRIPT_FILENAME' => '/home/John Doe/public_html/foo bar/app.php',
                    'SCRIPT_NAME' => '/foo bar/app.php',
                    'PHP_SELF' => '/foo bar/app.php',
                ),
                '/foo%20bar',
                '/',
            ),
            array(
                '/foo%20bar/home',
                array(
                    'SCRIPT_FILENAME' => '/home/John Doe/public_html/foo bar/app.php',
                    'SCRIPT_NAME' => '/foo bar/app.php',
                    'PHP_SELF' => '/foo bar/app.php',
                ),
                '/foo%20bar',
                '/home',
            ),
            array(
                '/foo%20bar/app.php/home',
                array(
                    'SCRIPT_FILENAME' => '/home/John Doe/public_html/foo bar/app.php',
                    'SCRIPT_NAME' => '/foo bar/app.php',
                    'PHP_SELF' => '/foo bar/app.php',
                ),
                '/foo%20bar/app.php',
                '/home',
            ),
            array(
                '/foo%20bar/app.php/home%3Dbaz',
                array(
                    'SCRIPT_FILENAME' => '/home/John Doe/public_html/foo bar/app.php',
                    'SCRIPT_NAME' => '/foo bar/app.php',
                    'PHP_SELF' => '/foo bar/app.php',
                ),
                '/foo%20bar/app.php',
                '/home%3Dbaz',
            ),
            array(
                '/foo/bar+baz',
                array(
                    'SCRIPT_FILENAME' => '/home/John Doe/public_html/foo/app.php',
                    'SCRIPT_NAME' => '/foo/app.php',
                    'PHP_SELF' => '/foo/app.php',
                ),
                '/foo',
                '/bar+baz',
            ),
        );
    }

    /**
     * @dataProvider urlencodedStringPrefixData
     */
    public function testUrlencodedStringPrefix($string, $prefix, $expect)
    {
        $request = new Request();

        $me = new \ReflectionMethod($request, 'getUrlencodedPrefix');
        $me->setAccessible(true);

        $this->assertSame($expect, $me->invoke($request, $string, $prefix));
    }

    public function urlencodedStringPrefixData()
    {
        return array(
            array('foo', 'foo', 'foo'),
            array('fo%6f', 'foo', 'fo%6f'),
            array('foo/bar', 'foo', 'foo'),
            array('fo%6f/bar', 'foo', 'fo%6f'),
            array('f%6f%6f/bar', 'foo', 'f%6f%6f'),
            array('%66%6F%6F/bar', 'foo', '%66%6F%6F'),
            array('fo+o/bar', 'fo+o', 'fo+o'),
            array('fo%2Bo/bar', 'fo+o', 'fo%2Bo'),
        );
    }

    private function disableHttpMethodParameterOverride()
    {
        $class = new \ReflectionClass('Symfony\\Component\\HttpFoundation\\Request');
        $property = $class->getProperty('httpMethodParameterOverride');
        $property->setAccessible(true);
        $property->setValue(false);
    }

    private function getRequestInstanceForClientIpTests($remoteAddr, $httpForwardedFor, $trustedProxies)
    {
        $request = new Request();

        $server = array('REMOTE_ADDR' => $remoteAddr);
        if (null !== $httpForwardedFor) {
            $server['HTTP_X_FORWARDED_FOR'] = $httpForwardedFor;
        }

        if ($trustedProxies) {
            Request::setTrustedProxies($trustedProxies);
        }

        $request->initialize(array(), array(), array(), array(), array(), $server);

        return $request;
    }

    private function getRequestInstanceForClientIpsForwardedTests($remoteAddr, $httpForwarded, $trustedProxies)
    {
        $request = new Request();

        $server = array('REMOTE_ADDR' => $remoteAddr);

        if (null !== $httpForwarded) {
            $server['HTTP_FORWARDED'] = $httpForwarded;
        }

        if ($trustedProxies) {
            Request::setTrustedProxies($trustedProxies);
        }

        $request->initialize(array(), array(), array(), array(), array(), $server);

        return $request;
    }

    public function testTrustedProxies()
    {
        $request = Request::create('http://example.com/');
        $request->server->set('REMOTE_ADDR', '3.3.3.3');
        $request->headers->set('X_FORWARDED_FOR', '1.1.1.1, 2.2.2.2');
        $request->headers->set('X_FORWARDED_HOST', 'foo.example.com, real.example.com:8080');
        $request->headers->set('X_FORWARDED_PROTO', 'https');
        $request->headers->set('X_FORWARDED_PORT', 443);
        $request->headers->set('X_MY_FOR', '3.3.3.3, 4.4.4.4');
        $request->headers->set('X_MY_HOST', 'my.example.com');
        $request->headers->set('X_MY_PROTO', 'http');
        $request->headers->set('X_MY_PORT', 81);

        // no trusted proxies
        $this->assertEquals('3.3.3.3', $request->getClientIp());
        $this->assertEquals('example.com', $request->getHost());
        $this->assertEquals(80, $request->getPort());
        $this->assertFalse($request->isSecure());

        // disabling proxy trusting
        Request::setTrustedProxies(array());
        $this->assertEquals('3.3.3.3', $request->getClientIp());
        $this->assertEquals('example.com', $request->getHost());
        $this->assertEquals(80, $request->getPort());
        $this->assertFalse($request->isSecure());

        // request is forwarded by a non-trusted proxy
        Request::setTrustedProxies(array('2.2.2.2'));
        $this->assertEquals('3.3.3.3', $request->getClientIp());
        $this->assertEquals('example.com', $request->getHost());
        $this->assertEquals(80, $request->getPort());
        $this->assertFalse($request->isSecure());

        // trusted proxy via setTrustedProxies()
        Request::setTrustedProxies(array('3.3.3.3', '2.2.2.2'));
        $this->assertEquals('1.1.1.1', $request->getClientIp());
        $this->assertEquals('real.example.com', $request->getHost());
        $this->assertEquals(443, $request->getPort());
        $this->assertTrue($request->isSecure());

        // trusted proxy via setTrustedProxies()
        Request::setTrustedProxies(array('3.3.3.4', '2.2.2.2'));
        $this->assertEquals('3.3.3.3', $request->getClientIp());
        $this->assertEquals('example.com', $request->getHost());
        $this->assertEquals(80, $request->getPort());
        $this->assertFalse($request->isSecure());

        // check various X_FORWARDED_PROTO header values
        Request::setTrustedProxies(array('3.3.3.3', '2.2.2.2'));
        $request->headers->set('X_FORWARDED_PROTO', 'ssl');
        $this->assertTrue($request->isSecure());

        $request->headers->set('X_FORWARDED_PROTO', 'https, http');
        $this->assertTrue($request->isSecure());

        // custom header names
        Request::setTrustedHeaderName(Request::HEADER_CLIENT_IP, 'X_MY_FOR');
        Request::setTrustedHeaderName(Request::HEADER_CLIENT_HOST, 'X_MY_HOST');
        Request::setTrustedHeaderName(Request::HEADER_CLIENT_PORT, 'X_MY_PORT');
        Request::setTrustedHeaderName(Request::HEADER_CLIENT_PROTO, 'X_MY_PROTO');
        $this->assertEquals('4.4.4.4', $request->getClientIp());
        $this->assertEquals('my.example.com', $request->getHost());
        $this->assertEquals(81, $request->getPort());
        $this->assertFalse($request->isSecure());

        // disabling via empty header names
        Request::setTrustedHeaderName(Request::HEADER_CLIENT_IP, null);
        Request::setTrustedHeaderName(Request::HEADER_CLIENT_HOST, null);
        Request::setTrustedHeaderName(Request::HEADER_CLIENT_PORT, null);
        Request::setTrustedHeaderName(Request::HEADER_CLIENT_PROTO, null);
        $this->assertEquals('3.3.3.3', $request->getClientIp());
        $this->assertEquals('example.com', $request->getHost());
        $this->assertEquals(80, $request->getPort());
        $this->assertFalse($request->isSecure());

        // reset
        Request::setTrustedProxies(array());
        Request::setTrustedHeaderName(Request::HEADER_CLIENT_IP, 'X_FORWARDED_FOR');
        Request::setTrustedHeaderName(Request::HEADER_CLIENT_HOST, 'X_FORWARDED_HOST');
        Request::setTrustedHeaderName(Request::HEADER_CLIENT_PORT, 'X_FORWARDED_PORT');
        Request::setTrustedHeaderName(Request::HEADER_CLIENT_PROTO, 'X_FORWARDED_PROTO');
    }

    /**
     * @expectedException \InvalidArgumentException
     */
    public function testSetTrustedProxiesInvalidHeaderName()
    {
        Request::create('http://example.com/');
        Request::setTrustedHeaderName('bogus name', 'X_MY_FOR');
    }

    /**
     * @expectedException \InvalidArgumentException
     */
    public function testGetTrustedProxiesInvalidHeaderName()
    {
        Request::create('http://example.com/');
        Request::getTrustedHeaderName('bogus name');
    }

    /**
     * @dataProvider iisRequestUriProvider
     */
    public function testIISRequestUri($headers, $server, $expectedRequestUri)
    {
        $request = new Request();
        $request->headers->replace($headers);
        $request->server->replace($server);

        $this->assertEquals($expectedRequestUri, $request->getRequestUri(), '->getRequestUri() is correct');

        $subRequestUri = '/bar/foo';
        $subRequest = Request::create($subRequestUri, 'get', array(), array(), array(), $request->server->all());
        $this->assertEquals($subRequestUri, $subRequest->getRequestUri(), '->getRequestUri() is correct in sub request');
    }

    public function iisRequestUriProvider()
    {
        return array(
            array(
                array(
                    'X_ORIGINAL_URL' => '/foo/bar',
                ),
                array(),
                '/foo/bar',
            ),
            array(
                array(
                    'X_REWRITE_URL' => '/foo/bar',
                ),
                array(),
                '/foo/bar',
            ),
            array(
                array(),
                array(
                    'IIS_WasUrlRewritten' => '1',
                    'UNENCODED_URL' => '/foo/bar',
                ),
                '/foo/bar',
            ),
            array(
                array(
                    'X_ORIGINAL_URL' => '/foo/bar',
                ),
                array(
                    'HTTP_X_ORIGINAL_URL' => '/foo/bar',
                ),
                '/foo/bar',
            ),
            array(
                array(
                    'X_ORIGINAL_URL' => '/foo/bar',
                ),
                array(
                    'IIS_WasUrlRewritten' => '1',
                    'UNENCODED_URL' => '/foo/bar',
                ),
                '/foo/bar',
            ),
            array(
                array(
                    'X_ORIGINAL_URL' => '/foo/bar',
                ),
                array(
                    'HTTP_X_ORIGINAL_URL' => '/foo/bar',
                    'IIS_WasUrlRewritten' => '1',
                    'UNENCODED_URL' => '/foo/bar',
                ),
                '/foo/bar',
            ),
            array(
                array(),
                array(
                    'ORIG_PATH_INFO' => '/foo/bar',
                ),
                '/foo/bar',
            ),
            array(
                array(),
                array(
                    'ORIG_PATH_INFO' => '/foo/bar',
                    'QUERY_STRING' => 'foo=bar',
                ),
                '/foo/bar?foo=bar',
            ),
        );
    }

    public function testTrustedHosts()
    {
        // create a request
        $request = Request::create('/');

        // no trusted host set -> no host check
        $request->headers->set('host', 'evil.com');
        $this->assertEquals('evil.com', $request->getHost());

        // add a trusted domain and all its subdomains
        Request::setTrustedHosts(array('^([a-z]{9}\.)?trusted\.com$'));

        // untrusted host
        $request->headers->set('host', 'evil.com');
        try {
            $request->getHost();
            $this->fail('Request::getHost() should throw an exception when host is not trusted.');
        } catch (\UnexpectedValueException $e) {
            $this->assertEquals('Untrusted Host "evil.com"', $e->getMessage());
        }

        // trusted hosts
        $request->headers->set('host', 'trusted.com');
        $this->assertEquals('trusted.com', $request->getHost());
        $this->assertEquals(80, $request->getPort());

        $request->server->set('HTTPS', true);
        $request->headers->set('host', 'trusted.com');
        $this->assertEquals('trusted.com', $request->getHost());
        $this->assertEquals(443, $request->getPort());
        $request->server->set('HTTPS', false);

        $request->headers->set('host', 'trusted.com:8000');
        $this->assertEquals('trusted.com', $request->getHost());
        $this->assertEquals(8000, $request->getPort());

        $request->headers->set('host', 'subdomain.trusted.com');
        $this->assertEquals('subdomain.trusted.com', $request->getHost());

        // reset request for following tests
        Request::setTrustedHosts(array());
    }

    public function testFactory()
    {
        Request::setFactory(function (array $query = array(), array $request = array(), array $attributes = array(), array $cookies = array(), array $files = array(), array $server = array(), $content = null) {
            return new NewRequest();
        });

        $this->assertEquals('foo', Request::create('/')->getFoo());

        Request::setFactory(null);
    }

    /**
     * @dataProvider getLongHostNames
     */
    public function testVeryLongHosts($host)
    {
        $start = microtime(true);

        $request = Request::create('/');
        $request->headers->set('host', $host);
        $this->assertEquals($host, $request->getHost());
        $this->assertLessThan(5, microtime(true) - $start);
    }

    /**
     * @dataProvider getHostValidities
     */
    public function testHostValidity($host, $isValid, $expectedHost = null, $expectedPort = null)
    {
        $request = Request::create('/');
        $request->headers->set('host', $host);

        if ($isValid) {
            $this->assertSame($expectedHost ?: $host, $request->getHost());
            if ($expectedPort) {
                $this->assertSame($expectedPort, $request->getPort());
            }
        } else {
            $this->setExpectedException('UnexpectedValueException', 'Invalid Host');
            $request->getHost();
        }
    }

    public function getHostValidities()
    {
        return array(
            array('.a', false),
            array('a..', false),
            array('a.', true),
            array("\xE9", false),
            array('[::1]', true),
            array('[::1]:80', true, '[::1]', 80),
            array(str_repeat('.', 101), false),
        );
    }

    public function getLongHostNames()
    {
        return array(
            array('a'.str_repeat('.a', 40000)),
            array(str_repeat(':', 101)),
        );
    }
}

class RequestContentProxy extends Request
{
    public function getContent($asResource = false)
    {
        return http_build_query(array('_method' => 'PUT', 'content' => 'mycontent'));
    }
}

class NewRequest extends Request
{
    public function getFoo()
    {
        return 'foo';
    }
}
PKϤ$Z�D�:�
�
+http-foundation/Tests/ApacheRequestTest.phpnu�[���<?php

/*
 * This file is part of the Symfony package.
 *
 * (c) Fabien Potencier <fabien@symfony.com>
 *
 * For the full copyright and license information, please view the LICENSE
 * file that was distributed with this source code.
 */

namespace Symfony\Component\HttpFoundation\Tests;

use Symfony\Component\HttpFoundation\ApacheRequest;

class ApacheRequestTest extends \PHPUnit_Framework_TestCase
{
    /**
     * @dataProvider provideServerVars
     */
    public function testUriMethods($server, $expectedRequestUri, $expectedBaseUrl, $expectedPathInfo)
    {
        $request = new ApacheRequest();
        $request->server->replace($server);

        $this->assertEquals($expectedRequestUri, $request->getRequestUri(), '->getRequestUri() is correct');
        $this->assertEquals($expectedBaseUrl, $request->getBaseUrl(), '->getBaseUrl() is correct');
        $this->assertEquals($expectedPathInfo, $request->getPathInfo(), '->getPathInfo() is correct');
    }

    public function provideServerVars()
    {
        return array(
            array(
                array(
                    'REQUEST_URI' => '/foo/app_dev.php/bar',
                    'SCRIPT_NAME' => '/foo/app_dev.php',
                    'PATH_INFO' => '/bar',
                ),
                '/foo/app_dev.php/bar',
                '/foo/app_dev.php',
                '/bar',
            ),
            array(
                array(
                    'REQUEST_URI' => '/foo/bar',
                    'SCRIPT_NAME' => '/foo/app_dev.php',
                ),
                '/foo/bar',
                '/foo',
                '/bar',
            ),
            array(
                array(
                    'REQUEST_URI' => '/app_dev.php/foo/bar',
                    'SCRIPT_NAME' => '/app_dev.php',
                    'PATH_INFO' => '/foo/bar',
                ),
                '/app_dev.php/foo/bar',
                '/app_dev.php',
                '/foo/bar',
            ),
            array(
                array(
                    'REQUEST_URI' => '/foo/bar',
                    'SCRIPT_NAME' => '/app_dev.php',
                ),
                '/foo/bar',
                '',
                '/foo/bar',
            ),
            array(
                array(
                    'REQUEST_URI' => '/app_dev.php',
                    'SCRIPT_NAME' => '/app_dev.php',
                ),
                '/app_dev.php',
                '/app_dev.php',
                '/',
            ),
            array(
                array(
                    'REQUEST_URI' => '/',
                    'SCRIPT_NAME' => '/app_dev.php',
                ),
                '/',
                '',
                '/',
            ),
        );
    }
}
PKϤ$Z%6h�xx*http-foundation/Tests/JsonResponseTest.phpnu�[���<?php

/*
 * This file is part of the Symfony package.
 *
 * (c) Fabien Potencier <fabien@symfony.com>
 *
 * For the full copyright and license information, please view the LICENSE
 * file that was distributed with this source code.
 */

namespace Symfony\Component\HttpFoundation\Tests;

use Symfony\Component\HttpFoundation\JsonResponse;

class JsonResponseTest extends \PHPUnit_Framework_TestCase
{
    public function testConstructorEmptyCreatesJsonObject()
    {
        $response = new JsonResponse();
        $this->assertSame('{}', $response->getContent());
    }

    public function testConstructorWithArrayCreatesJsonArray()
    {
        $response = new JsonResponse(array(0, 1, 2, 3));
        $this->assertSame('[0,1,2,3]', $response->getContent());
    }

    public function testConstructorWithAssocArrayCreatesJsonObject()
    {
        $response = new JsonResponse(array('foo' => 'bar'));
        $this->assertSame('{"foo":"bar"}', $response->getContent());
    }

    public function testConstructorWithSimpleTypes()
    {
        $response = new JsonResponse('foo');
        $this->assertSame('"foo"', $response->getContent());

        $response = new JsonResponse(0);
        $this->assertSame('0', $response->getContent());

        $response = new JsonResponse(0.1);
        $this->assertSame('0.1', $response->getContent());

        $response = new JsonResponse(true);
        $this->assertSame('true', $response->getContent());
    }

    public function testConstructorWithCustomStatus()
    {
        $response = new JsonResponse(array(), 202);
        $this->assertSame(202, $response->getStatusCode());
    }

    public function testConstructorAddsContentTypeHeader()
    {
        $response = new JsonResponse();
        $this->assertSame('application/json', $response->headers->get('Content-Type'));
    }

    public function testConstructorWithCustomHeaders()
    {
        $response = new JsonResponse(array(), 200, array('ETag' => 'foo'));
        $this->assertSame('application/json', $response->headers->get('Content-Type'));
        $this->assertSame('foo', $response->headers->get('ETag'));
    }

    public function testConstructorWithCustomContentType()
    {
        $headers = array('Content-Type' => 'application/vnd.acme.blog-v1+json');

        $response = new JsonResponse(array(), 200, $headers);
        $this->assertSame('application/vnd.acme.blog-v1+json', $response->headers->get('Content-Type'));
    }

    public function testCreate()
    {
        $response = JsonResponse::create(array('foo' => 'bar'), 204);

        $this->assertInstanceOf('Symfony\Component\HttpFoundation\JsonResponse', $response);
        $this->assertEquals('{"foo":"bar"}', $response->getContent());
        $this->assertEquals(204, $response->getStatusCode());
    }

    public function testStaticCreateEmptyJsonObject()
    {
        $response = JsonResponse::create();
        $this->assertInstanceOf('Symfony\Component\HttpFoundation\JsonResponse', $response);
        $this->assertSame('{}', $response->getContent());
    }

    public function testStaticCreateJsonArray()
    {
        $response = JsonResponse::create(array(0, 1, 2, 3));
        $this->assertInstanceOf('Symfony\Component\HttpFoundation\JsonResponse', $response);
        $this->assertSame('[0,1,2,3]', $response->getContent());
    }

    public function testStaticCreateJsonObject()
    {
        $response = JsonResponse::create(array('foo' => 'bar'));
        $this->assertInstanceOf('Symfony\Component\HttpFoundation\JsonResponse', $response);
        $this->assertSame('{"foo":"bar"}', $response->getContent());
    }

    public function testStaticCreateWithSimpleTypes()
    {
        $response = JsonResponse::create('foo');
        $this->assertInstanceOf('Symfony\Component\HttpFoundation\JsonResponse', $response);
        $this->assertSame('"foo"', $response->getContent());

        $response = JsonResponse::create(0);
        $this->assertInstanceOf('Symfony\Component\HttpFoundation\JsonResponse', $response);
        $this->assertSame('0', $response->getContent());

        $response = JsonResponse::create(0.1);
        $this->assertInstanceOf('Symfony\Component\HttpFoundation\JsonResponse', $response);
        $this->assertSame('0.1', $response->getContent());

        $response = JsonResponse::create(true);
        $this->assertInstanceOf('Symfony\Component\HttpFoundation\JsonResponse', $response);
        $this->assertSame('true', $response->getContent());
    }

    public function testStaticCreateWithCustomStatus()
    {
        $response = JsonResponse::create(array(), 202);
        $this->assertSame(202, $response->getStatusCode());
    }

    public function testStaticCreateAddsContentTypeHeader()
    {
        $response = JsonResponse::create();
        $this->assertSame('application/json', $response->headers->get('Content-Type'));
    }

    public function testStaticCreateWithCustomHeaders()
    {
        $response = JsonResponse::create(array(), 200, array('ETag' => 'foo'));
        $this->assertSame('application/json', $response->headers->get('Content-Type'));
        $this->assertSame('foo', $response->headers->get('ETag'));
    }

    public function testStaticCreateWithCustomContentType()
    {
        $headers = array('Content-Type' => 'application/vnd.acme.blog-v1+json');

        $response = JsonResponse::create(array(), 200, $headers);
        $this->assertSame('application/vnd.acme.blog-v1+json', $response->headers->get('Content-Type'));
    }

    public function testSetCallback()
    {
        $response = JsonResponse::create(array('foo' => 'bar'))->setCallback('callback');

        $this->assertEquals('/**/callback({"foo":"bar"});', $response->getContent());
        $this->assertEquals('text/javascript', $response->headers->get('Content-Type'));
    }

    public function testJsonEncodeFlags()
    {
        $response = new JsonResponse('<>\'&"');

        $this->assertEquals('"\u003C\u003E\u0027\u0026\u0022"', $response->getContent());
    }

    public function testGetEncodingOptions()
    {
        $response = new JsonResponse();

        $this->assertEquals(JSON_HEX_TAG | JSON_HEX_APOS | JSON_HEX_AMP | JSON_HEX_QUOT, $response->getEncodingOptions());
    }

    public function testSetEncodingOptions()
    {
        $response = new JsonResponse();
        $response->setData(array(array(1, 2, 3)));

        $this->assertEquals('[[1,2,3]]', $response->getContent());

        $response->setEncodingOptions(JSON_FORCE_OBJECT);

        $this->assertEquals('{"0":{"0":1,"1":2,"2":3}}', $response->getContent());
    }

    /**
     * @expectedException \InvalidArgumentException
     */
    public function testSetCallbackInvalidIdentifier()
    {
        $response = new JsonResponse('foo');
        $response->setCallback('+invalid');
    }

    /**
     * @expectedException \InvalidArgumentException
     */
    public function testSetContent()
    {
        JsonResponse::create("\xB1\x31");
    }

    /**
     * @expectedException \Exception
     * @expectedExceptionMessage This error is expected
     * @requires PHP 5.4
     */
    public function testSetContentJsonSerializeError()
    {
        $serializable = new JsonSerializableObject();

        JsonResponse::create($serializable);
    }
}

if (interface_exists('JsonSerializable')) {
    class JsonSerializableObject implements \JsonSerializable
    {
        public function jsonSerialize()
        {
            throw new \Exception('This error is expected');
        }
    }
}
PKϤ$Z�k	�
�
.http-foundation/Tests/AcceptHeaderItemTest.phpnu�[���<?php

/*
 * This file is part of the Symfony package.
 *
 * (c) Fabien Potencier <fabien@symfony.com>
 *
 * For the full copyright and license information, please view the LICENSE
 * file that was distributed with this source code.
 */

namespace Symfony\Component\HttpFoundation\Tests;

use Symfony\Component\HttpFoundation\AcceptHeaderItem;

class AcceptHeaderItemTest extends \PHPUnit_Framework_TestCase
{
    /**
     * @dataProvider provideFromStringData
     */
    public function testFromString($string, $value, array $attributes)
    {
        $item = AcceptHeaderItem::fromString($string);
        $this->assertEquals($value, $item->getValue());
        $this->assertEquals($attributes, $item->getAttributes());
    }

    public function provideFromStringData()
    {
        return array(
            array(
                'text/html',
                'text/html', array(),
            ),
            array(
                '"this;should,not=matter"',
                'this;should,not=matter', array(),
            ),
            array(
                "text/plain; charset=utf-8;param=\"this;should,not=matter\";\tfootnotes=true",
                'text/plain', array('charset' => 'utf-8', 'param' => 'this;should,not=matter', 'footnotes' => 'true'),
            ),
            array(
                '"this;should,not=matter";charset=utf-8',
                'this;should,not=matter', array('charset' => 'utf-8'),
            ),
        );
    }

    /**
     * @dataProvider provideToStringData
     */
    public function testToString($value, array $attributes, $string)
    {
        $item = new AcceptHeaderItem($value, $attributes);
        $this->assertEquals($string, (string) $item);
    }

    public function provideToStringData()
    {
        return array(
            array(
                'text/html', array(),
                'text/html',
            ),
            array(
                'text/plain', array('charset' => 'utf-8', 'param' => 'this;should,not=matter', 'footnotes' => 'true'),
                'text/plain;charset=utf-8;param="this;should,not=matter";footnotes=true',
            ),
        );
    }

    public function testValue()
    {
        $item = new AcceptHeaderItem('value', array());
        $this->assertEquals('value', $item->getValue());

        $item->setValue('new value');
        $this->assertEquals('new value', $item->getValue());

        $item->setValue(1);
        $this->assertEquals('1', $item->getValue());
    }

    public function testQuality()
    {
        $item = new AcceptHeaderItem('value', array());
        $this->assertEquals(1.0, $item->getQuality());

        $item->setQuality(0.5);
        $this->assertEquals(0.5, $item->getQuality());

        $item->setAttribute('q', 0.75);
        $this->assertEquals(0.75, $item->getQuality());
        $this->assertFalse($item->hasAttribute('q'));
    }

    public function testAttribute()
    {
        $item = new AcceptHeaderItem('value', array());
        $this->assertEquals(array(), $item->getAttributes());
        $this->assertFalse($item->hasAttribute('test'));
        $this->assertNull($item->getAttribute('test'));
        $this->assertEquals('default', $item->getAttribute('test', 'default'));

        $item->setAttribute('test', 'value');
        $this->assertEquals(array('test' => 'value'), $item->getAttributes());
        $this->assertTrue($item->hasAttribute('test'));
        $this->assertEquals('value', $item->getAttribute('test'));
        $this->assertEquals('value', $item->getAttribute('test', 'default'));
    }
}
PKϤ$Z�q�H��.http-foundation/Tests/RedirectResponseTest.phpnu�[���<?php

/*
 * This file is part of the Symfony package.
 *
 * (c) Fabien Potencier <fabien@symfony.com>
 *
 * For the full copyright and license information, please view the LICENSE
 * file that was distributed with this source code.
 */

namespace Symfony\Component\HttpFoundation\Tests;

use Symfony\Component\HttpFoundation\RedirectResponse;

class RedirectResponseTest extends \PHPUnit_Framework_TestCase
{
    public function testGenerateMetaRedirect()
    {
        $response = new RedirectResponse('foo.bar');

        $this->assertEquals(1, preg_match(
            '#<meta http-equiv="refresh" content="\d+;url=foo\.bar" />#',
            preg_replace(array('/\s+/', '/\'/'), array(' ', '"'), $response->getContent())
        ));
    }

    /**
     * @expectedException \InvalidArgumentException
     */
    public function testRedirectResponseConstructorNullUrl()
    {
        $response = new RedirectResponse(null);
    }

    /**
     * @expectedException \InvalidArgumentException
     */
    public function testRedirectResponseConstructorWrongStatusCode()
    {
        $response = new RedirectResponse('foo.bar', 404);
    }

    public function testGenerateLocationHeader()
    {
        $response = new RedirectResponse('foo.bar');

        $this->assertTrue($response->headers->has('Location'));
        $this->assertEquals('foo.bar', $response->headers->get('Location'));
    }

    public function testGetTargetUrl()
    {
        $response = new RedirectResponse('foo.bar');

        $this->assertEquals('foo.bar', $response->getTargetUrl());
    }

    public function testSetTargetUrl()
    {
        $response = new RedirectResponse('foo.bar');
        $response->setTargetUrl('baz.beep');

        $this->assertEquals('baz.beep', $response->getTargetUrl());
    }

    /**
     * @expectedException \InvalidArgumentException
     */
    public function testSetTargetUrlNull()
    {
        $response = new RedirectResponse('foo.bar');
        $response->setTargetUrl(null);
    }

    public function testCreate()
    {
        $response = RedirectResponse::create('foo', 301);

        $this->assertInstanceOf('Symfony\Component\HttpFoundation\RedirectResponse', $response);
        $this->assertEquals(301, $response->getStatusCode());
    }
}
PKϤ$Z�����-�-0http-foundation/Tests/BinaryFileResponseTest.phpnu�[���<?php

/*
 * This file is part of the Symfony package.
 *
 * (c) Fabien Potencier <fabien@symfony.com>
 *
 * For the full copyright and license information, please view the LICENSE
 * file that was distributed with this source code.
 */

namespace Symfony\Component\HttpFoundation\Tests;

use Symfony\Component\HttpFoundation\BinaryFileResponse;
use Symfony\Component\HttpFoundation\Request;
use Symfony\Component\HttpFoundation\ResponseHeaderBag;
use Symfony\Component\HttpFoundation\Tests\File\FakeFile;

class BinaryFileResponseTest extends ResponseTestCase
{
    public function testConstruction()
    {
        $file = __DIR__.'/../README.md';
        $response = new BinaryFileResponse($file, 404, array('X-Header' => 'Foo'), true, null, true, true);
        $this->assertEquals(404, $response->getStatusCode());
        $this->assertEquals('Foo', $response->headers->get('X-Header'));
        $this->assertTrue($response->headers->has('ETag'));
        $this->assertTrue($response->headers->has('Last-Modified'));
        $this->assertFalse($response->headers->has('Content-Disposition'));

        $response = BinaryFileResponse::create($file, 404, array(), true, ResponseHeaderBag::DISPOSITION_INLINE);
        $this->assertEquals(404, $response->getStatusCode());
        $this->assertFalse($response->headers->has('ETag'));
        $this->assertEquals('inline; filename="README.md"', $response->headers->get('Content-Disposition'));
    }

    public function testConstructWithNonAsciiFilename()
    {
        touch(sys_get_temp_dir().'/fööö.html');

        $response = new BinaryFileResponse(sys_get_temp_dir().'/fööö.html', 200, array(), true, 'attachment');

        @unlink(sys_get_temp_dir().'/fööö.html');

        $this->assertSame('fööö.html', $response->getFile()->getFilename());
    }

    /**
     * @expectedException \LogicException
     */
    public function testSetContent()
    {
        $response = new BinaryFileResponse(__FILE__);
        $response->setContent('foo');
    }

    public function testGetContent()
    {
        $response = new BinaryFileResponse(__FILE__);
        $this->assertFalse($response->getContent());
    }

    public function testSetContentDispositionGeneratesSafeFallbackFilename()
    {
        $response = new BinaryFileResponse(__FILE__);
        $response->setContentDisposition(ResponseHeaderBag::DISPOSITION_ATTACHMENT, 'föö.html');

        $this->assertSame('attachment; filename="f__.html"; filename*=utf-8\'\'f%C3%B6%C3%B6.html', $response->headers->get('Content-Disposition'));
    }

    /**
     * @dataProvider provideRanges
     */
    public function testRequests($requestRange, $offset, $length, $responseRange)
    {
        $response = BinaryFileResponse::create(__DIR__.'/File/Fixtures/test.gif', 200, array('Content-Type' => 'application/octet-stream'))->setAutoEtag();

        // do a request to get the ETag
        $request = Request::create('/');
        $response->prepare($request);
        $etag = $response->headers->get('ETag');

        // prepare a request for a range of the testing file
        $request = Request::create('/');
        $request->headers->set('If-Range', $etag);
        $request->headers->set('Range', $requestRange);

        $file = fopen(__DIR__.'/File/Fixtures/test.gif', 'r');
        fseek($file, $offset);
        $data = fread($file, $length);
        fclose($file);

        $this->expectOutputString($data);
        $response = clone $response;
        $response->prepare($request);
        $response->sendContent();

        $this->assertEquals(206, $response->getStatusCode());
        $this->assertEquals($responseRange, $response->headers->get('Content-Range'));
    }

    /**
     * @dataProvider provideRanges
     */
    public function testRequestsWithoutEtag($requestRange, $offset, $length, $responseRange)
    {
        $response = BinaryFileResponse::create(__DIR__.'/File/Fixtures/test.gif', 200, array('Content-Type' => 'application/octet-stream'));

        // do a request to get the LastModified
        $request = Request::create('/');
        $response->prepare($request);
        $lastModified = $response->headers->get('Last-Modified');

        // prepare a request for a range of the testing file
        $request = Request::create('/');
        $request->headers->set('If-Range', $lastModified);
        $request->headers->set('Range', $requestRange);

        $file = fopen(__DIR__.'/File/Fixtures/test.gif', 'r');
        fseek($file, $offset);
        $data = fread($file, $length);
        fclose($file);

        $this->expectOutputString($data);
        $response = clone $response;
        $response->prepare($request);
        $response->sendContent();

        $this->assertEquals(206, $response->getStatusCode());
        $this->assertEquals($responseRange, $response->headers->get('Content-Range'));
    }

    public function provideRanges()
    {
        return array(
            array('bytes=1-4', 1, 4, 'bytes 1-4/35'),
            array('bytes=-5', 30, 5, 'bytes 30-34/35'),
            array('bytes=30-', 30, 5, 'bytes 30-34/35'),
            array('bytes=30-30', 30, 1, 'bytes 30-30/35'),
            array('bytes=30-34', 30, 5, 'bytes 30-34/35'),
        );
    }

    public function testRangeRequestsWithoutLastModifiedDate()
    {
        // prevent auto last modified
        $response = BinaryFileResponse::create(__DIR__.'/File/Fixtures/test.gif', 200, array('Content-Type' => 'application/octet-stream'), true, null, false, false);

        // prepare a request for a range of the testing file
        $request = Request::create('/');
        $request->headers->set('If-Range', date('D, d M Y H:i:s').' GMT');
        $request->headers->set('Range', 'bytes=1-4');

        $this->expectOutputString(file_get_contents(__DIR__.'/File/Fixtures/test.gif'));
        $response = clone $response;
        $response->prepare($request);
        $response->sendContent();

        $this->assertEquals(200, $response->getStatusCode());
        $this->assertNull($response->headers->get('Content-Range'));
    }

    /**
     * @dataProvider provideFullFileRanges
     */
    public function testFullFileRequests($requestRange)
    {
        $response = BinaryFileResponse::create(__DIR__.'/File/Fixtures/test.gif', 200, array('Content-Type' => 'application/octet-stream'))->setAutoEtag();

        // prepare a request for a range of the testing file
        $request = Request::create('/');
        $request->headers->set('Range', $requestRange);

        $file = fopen(__DIR__.'/File/Fixtures/test.gif', 'r');
        $data = fread($file, 35);
        fclose($file);

        $this->expectOutputString($data);
        $response = clone $response;
        $response->prepare($request);
        $response->sendContent();

        $this->assertEquals(200, $response->getStatusCode());
    }

    public function provideFullFileRanges()
    {
        return array(
            array('bytes=0-'),
            array('bytes=0-34'),
            array('bytes=-35'),
            // Syntactical invalid range-request should also return the full resource
            array('bytes=20-10'),
            array('bytes=50-40'),
        );
    }

    /**
     * @dataProvider provideInvalidRanges
     */
    public function testInvalidRequests($requestRange)
    {
        $response = BinaryFileResponse::create(__DIR__.'/File/Fixtures/test.gif', 200, array('Content-Type' => 'application/octet-stream'))->setAutoEtag();

        // prepare a request for a range of the testing file
        $request = Request::create('/');
        $request->headers->set('Range', $requestRange);

        $response = clone $response;
        $response->prepare($request);
        $response->sendContent();

        $this->assertEquals(416, $response->getStatusCode());
        $this->assertEquals('bytes */35', $response->headers->get('Content-Range'));
    }

    public function provideInvalidRanges()
    {
        return array(
            array('bytes=-40'),
            array('bytes=30-40'),
        );
    }

    /**
     * @dataProvider provideXSendfileFiles
     */
    public function testXSendfile($file)
    {
        $request = Request::create('/');
        $request->headers->set('X-Sendfile-Type', 'X-Sendfile');

        BinaryFileResponse::trustXSendfileTypeHeader();
        $response = BinaryFileResponse::create($file, 200, array('Content-Type' => 'application/octet-stream'));
        $response->prepare($request);

        $this->expectOutputString('');
        $response->sendContent();

        $this->assertContains('README.md', $response->headers->get('X-Sendfile'));
    }

    public function provideXSendfileFiles()
    {
        return array(
            array(__DIR__.'/../README.md'),
            array('file://'.__DIR__.'/../README.md'),
        );
    }

    /**
     * @dataProvider getSampleXAccelMappings
     */
    public function testXAccelMapping($realpath, $mapping, $virtual)
    {
        $request = Request::create('/');
        $request->headers->set('X-Sendfile-Type', 'X-Accel-Redirect');
        $request->headers->set('X-Accel-Mapping', $mapping);

        $file = new FakeFile($realpath, __DIR__.'/File/Fixtures/test');

        BinaryFileResponse::trustXSendfileTypeHeader();
        $response = new BinaryFileResponse($file, 200, array('Content-Type' => 'application/octet-stream'));
        $reflection = new \ReflectionObject($response);
        $property = $reflection->getProperty('file');
        $property->setAccessible(true);
        $property->setValue($response, $file);

        $response->prepare($request);
        $this->assertEquals($virtual, $response->headers->get('X-Accel-Redirect'));
    }

    public function testDeleteFileAfterSend()
    {
        $request = Request::create('/');

        $path = __DIR__.'/File/Fixtures/to_delete';
        touch($path);
        $realPath = realpath($path);
        $this->assertFileExists($realPath);

        $response = new BinaryFileResponse($realPath, 200, array('Content-Type' => 'application/octet-stream'));
        $response->deleteFileAfterSend(true);

        $response->prepare($request);
        $response->sendContent();

        $this->assertFileNotExists($path);
    }

    public function testAcceptRangeOnUnsafeMethods()
    {
        $request = Request::create('/', 'POST');
        $response = BinaryFileResponse::create(__DIR__.'/File/Fixtures/test.gif', 200, array('Content-Type' => 'application/octet-stream'));
        $response->prepare($request);

        $this->assertEquals('none', $response->headers->get('Accept-Ranges'));
    }

    public function testAcceptRangeNotOverriden()
    {
        $request = Request::create('/', 'POST');
        $response = BinaryFileResponse::create(__DIR__.'/File/Fixtures/test.gif', 200, array('Content-Type' => 'application/octet-stream'));
        $response->headers->set('Accept-Ranges', 'foo');
        $response->prepare($request);

        $this->assertEquals('foo', $response->headers->get('Accept-Ranges'));
    }

    public function getSampleXAccelMappings()
    {
        return array(
            array('/var/www/var/www/files/foo.txt', '/var/www/=/files/', '/files/var/www/files/foo.txt'),
            array('/home/foo/bar.txt', '/var/www/=/files/,/home/foo/=/baz/', '/baz/bar.txt'),
        );
    }

    protected function provideResponse()
    {
        return new BinaryFileResponse(__DIR__.'/../README.md', 200, array('Content-Type' => 'application/octet-stream'));
    }

    public static function tearDownAfterClass()
    {
        $path = __DIR__.'/../Fixtures/to_delete';
        if (file_exists($path)) {
            @unlink($path);
        }
    }
}
PKϤ$Zqr��



6http-foundation/Tests/ExpressionRequestMatcherTest.phpnu�[���<?php

/*
 * This file is part of the Symfony package.
 *
 * (c) Fabien Potencier <fabien@symfony.com>
 *
 * For the full copyright and license information, please view the LICENSE
 * file that was distributed with this source code.
 */

namespace Symfony\Component\HttpFoundation\Tests;

use Symfony\Component\ExpressionLanguage\ExpressionLanguage;
use Symfony\Component\HttpFoundation\ExpressionRequestMatcher;
use Symfony\Component\HttpFoundation\Request;

class ExpressionRequestMatcherTest extends \PHPUnit_Framework_TestCase
{
    /**
     * @expectedException \LogicException
     */
    public function testWhenNoExpressionIsSet()
    {
        $expressionRequestMatcher = new ExpressionRequestMatcher();
        $expressionRequestMatcher->matches(new Request());
    }

    /**
     * @dataProvider provideExpressions
     */
    public function testMatchesWhenParentMatchesIsTrue($expression, $expected)
    {
        $request = Request::create('/foo');
        $expressionRequestMatcher = new ExpressionRequestMatcher();

        $expressionRequestMatcher->setExpression(new ExpressionLanguage(), $expression);
        $this->assertSame($expected, $expressionRequestMatcher->matches($request));
    }

    /**
     * @dataProvider provideExpressions
     */
    public function testMatchesWhenParentMatchesIsFalse($expression)
    {
        $request = Request::create('/foo');
        $request->attributes->set('foo', 'foo');
        $expressionRequestMatcher = new ExpressionRequestMatcher();
        $expressionRequestMatcher->matchAttribute('foo', 'bar');

        $expressionRequestMatcher->setExpression(new ExpressionLanguage(), $expression);
        $this->assertFalse($expressionRequestMatcher->matches($request));
    }

    public function provideExpressions()
    {
        return array(
            array('request.getMethod() == method', true),
            array('request.getPathInfo() == path', true),
            array('request.getHost() == host', true),
            array('request.getClientIp() == ip', true),
            array('request.attributes.all() == attributes', true),
            array('request.getMethod() == method && request.getPathInfo() == path && request.getHost() == host && request.getClientIp() == ip &&  request.attributes.all() == attributes', true),
            array('request.getMethod() != method', false),
            array('request.getMethod() != method && request.getPathInfo() == path && request.getHost() == host && request.getClientIp() == ip &&  request.attributes.all() == attributes', false),
        );
    }
}
PKϤ$Z�1r�
�
*http-foundation/Tests/AcceptHeaderTest.phpnu�[���<?php

/*
 * This file is part of the Symfony package.
 *
 * (c) Fabien Potencier <fabien@symfony.com>
 *
 * For the full copyright and license information, please view the LICENSE
 * file that was distributed with this source code.
 */

namespace Symfony\Component\HttpFoundation\Tests;

use Symfony\Component\HttpFoundation\AcceptHeader;
use Symfony\Component\HttpFoundation\AcceptHeaderItem;

class AcceptHeaderTest extends \PHPUnit_Framework_TestCase
{
    public function testFirst()
    {
        $header = AcceptHeader::fromString('text/plain; q=0.5, text/html, text/x-dvi; q=0.8, text/x-c');
        $this->assertSame('text/html', $header->first()->getValue());
    }

    /**
     * @dataProvider provideFromStringData
     */
    public function testFromString($string, array $items)
    {
        $header = AcceptHeader::fromString($string);
        $parsed = array_values($header->all());
        // reset index since the fixtures don't have them set
        foreach ($parsed as $item) {
            $item->setIndex(0);
        }
        $this->assertEquals($items, $parsed);
    }

    public function provideFromStringData()
    {
        return array(
            array('', array()),
            array('gzip', array(new AcceptHeaderItem('gzip'))),
            array('gzip,deflate,sdch', array(new AcceptHeaderItem('gzip'), new AcceptHeaderItem('deflate'), new AcceptHeaderItem('sdch'))),
            array("gzip, deflate\t,sdch", array(new AcceptHeaderItem('gzip'), new AcceptHeaderItem('deflate'), new AcceptHeaderItem('sdch'))),
            array('"this;should,not=matter"', array(new AcceptHeaderItem('this;should,not=matter'))),
        );
    }

    /**
     * @dataProvider provideToStringData
     */
    public function testToString(array $items, $string)
    {
        $header = new AcceptHeader($items);
        $this->assertEquals($string, (string) $header);
    }

    public function provideToStringData()
    {
        return array(
            array(array(), ''),
            array(array(new AcceptHeaderItem('gzip')), 'gzip'),
            array(array(new AcceptHeaderItem('gzip'), new AcceptHeaderItem('deflate'), new AcceptHeaderItem('sdch')), 'gzip,deflate,sdch'),
            array(array(new AcceptHeaderItem('this;should,not=matter')), 'this;should,not=matter'),
        );
    }

    /**
     * @dataProvider provideFilterData
     */
    public function testFilter($string, $filter, array $values)
    {
        $header = AcceptHeader::fromString($string)->filter($filter);
        $this->assertEquals($values, array_keys($header->all()));
    }

    public function provideFilterData()
    {
        return array(
            array('fr-FR,fr;q=0.8,en-US;q=0.6,en;q=0.4', '/fr.*/', array('fr-FR', 'fr')),
        );
    }

    /**
     * @dataProvider provideSortingData
     */
    public function testSorting($string, array $values)
    {
        $header = AcceptHeader::fromString($string);
        $this->assertEquals($values, array_keys($header->all()));
    }

    public function provideSortingData()
    {
        return array(
            'quality has priority' => array('*;q=0.3,ISO-8859-1,utf-8;q=0.7',  array('ISO-8859-1', 'utf-8', '*')),
            'order matters when q is equal' => array('*;q=0.3,ISO-8859-1;q=0.7,utf-8;q=0.7',  array('ISO-8859-1', 'utf-8', '*')),
            'order matters when q is equal2' => array('*;q=0.3,utf-8;q=0.7,ISO-8859-1;q=0.7',  array('utf-8', 'ISO-8859-1', '*')),
        );
    }
}
PKϤ$ZL���-�-/http-foundation/Tests/ResponseHeaderBagTest.phpnu�[���<?php

/*
 * This file is part of the Symfony package.
 *
 * (c) Fabien Potencier <fabien@symfony.com>
 *
 * For the full copyright and license information, please view the LICENSE
 * file that was distributed with this source code.
 */

namespace Symfony\Component\HttpFoundation\Tests;

use Symfony\Component\HttpFoundation\ResponseHeaderBag;
use Symfony\Component\HttpFoundation\Cookie;

/**
 * @group time-sensitive
 */
class ResponseHeaderBagTest extends \PHPUnit_Framework_TestCase
{
    /**
     * @dataProvider provideAllPreserveCase
     */
    public function testAllPreserveCase($headers, $expected)
    {
        $bag = new ResponseHeaderBag($headers);

        $this->assertEquals($expected, $bag->allPreserveCase(), '->allPreserveCase() gets all input keys in original case');
    }

    public function provideAllPreserveCase()
    {
        return array(
            array(
                array('fOo' => 'BAR'),
                array('fOo' => array('BAR'), 'Cache-Control' => array('no-cache')),
            ),
            array(
                array('ETag' => 'xyzzy'),
                array('ETag' => array('xyzzy'), 'Cache-Control' => array('private, must-revalidate')),
            ),
            array(
                array('Content-MD5' => 'Q2hlY2sgSW50ZWdyaXR5IQ=='),
                array('Content-MD5' => array('Q2hlY2sgSW50ZWdyaXR5IQ=='), 'Cache-Control' => array('no-cache')),
            ),
            array(
                array('P3P' => 'CP="CAO PSA OUR"'),
                array('P3P' => array('CP="CAO PSA OUR"'), 'Cache-Control' => array('no-cache')),
            ),
            array(
                array('WWW-Authenticate' => 'Basic realm="WallyWorld"'),
                array('WWW-Authenticate' => array('Basic realm="WallyWorld"'), 'Cache-Control' => array('no-cache')),
            ),
            array(
                array('X-UA-Compatible' => 'IE=edge,chrome=1'),
                array('X-UA-Compatible' => array('IE=edge,chrome=1'), 'Cache-Control' => array('no-cache')),
            ),
            array(
                array('X-XSS-Protection' => '1; mode=block'),
                array('X-XSS-Protection' => array('1; mode=block'), 'Cache-Control' => array('no-cache')),
            ),
        );
    }

    public function testCacheControlHeader()
    {
        $bag = new ResponseHeaderBag(array());
        $this->assertEquals('no-cache', $bag->get('Cache-Control'));
        $this->assertTrue($bag->hasCacheControlDirective('no-cache'));

        $bag = new ResponseHeaderBag(array('Cache-Control' => 'public'));
        $this->assertEquals('public', $bag->get('Cache-Control'));
        $this->assertTrue($bag->hasCacheControlDirective('public'));

        $bag = new ResponseHeaderBag(array('ETag' => 'abcde'));
        $this->assertEquals('private, must-revalidate', $bag->get('Cache-Control'));
        $this->assertTrue($bag->hasCacheControlDirective('private'));
        $this->assertTrue($bag->hasCacheControlDirective('must-revalidate'));
        $this->assertFalse($bag->hasCacheControlDirective('max-age'));

        $bag = new ResponseHeaderBag(array('Expires' => 'Wed, 16 Feb 2011 14:17:43 GMT'));
        $this->assertEquals('private, must-revalidate', $bag->get('Cache-Control'));

        $bag = new ResponseHeaderBag(array(
            'Expires' => 'Wed, 16 Feb 2011 14:17:43 GMT',
            'Cache-Control' => 'max-age=3600',
        ));
        $this->assertEquals('max-age=3600, private', $bag->get('Cache-Control'));

        $bag = new ResponseHeaderBag(array('Last-Modified' => 'abcde'));
        $this->assertEquals('private, must-revalidate', $bag->get('Cache-Control'));

        $bag = new ResponseHeaderBag(array('Etag' => 'abcde', 'Last-Modified' => 'abcde'));
        $this->assertEquals('private, must-revalidate', $bag->get('Cache-Control'));

        $bag = new ResponseHeaderBag(array('cache-control' => 'max-age=100'));
        $this->assertEquals('max-age=100, private', $bag->get('Cache-Control'));

        $bag = new ResponseHeaderBag(array('cache-control' => 's-maxage=100'));
        $this->assertEquals('s-maxage=100', $bag->get('Cache-Control'));

        $bag = new ResponseHeaderBag(array('cache-control' => 'private, max-age=100'));
        $this->assertEquals('max-age=100, private', $bag->get('Cache-Control'));

        $bag = new ResponseHeaderBag(array('cache-control' => 'public, max-age=100'));
        $this->assertEquals('max-age=100, public', $bag->get('Cache-Control'));

        $bag = new ResponseHeaderBag();
        $bag->set('Last-Modified', 'abcde');
        $this->assertEquals('private, must-revalidate', $bag->get('Cache-Control'));
    }

    public function testToStringIncludesCookieHeaders()
    {
        $bag = new ResponseHeaderBag(array());
        $bag->setCookie(new Cookie('foo', 'bar'));

        $this->assertContains('Set-Cookie: foo=bar; path=/; httponly', explode("\r\n", $bag->__toString()));

        $bag->clearCookie('foo');

        $this->assertRegExp('#^Set-Cookie: foo=deleted; expires='.gmdate('D, d-M-Y H:i:s T', time() - 31536001).'; path=/; httponly#m', $bag->__toString());
    }

    public function testClearCookieSecureNotHttpOnly()
    {
        $bag = new ResponseHeaderBag(array());

        $bag->clearCookie('foo', '/', null, true, false);

        $this->assertRegExp('#^Set-Cookie: foo=deleted; expires='.gmdate('D, d-M-Y H:i:s T', time() - 31536001).'; path=/; secure#m', $bag->__toString());
    }

    public function testReplace()
    {
        $bag = new ResponseHeaderBag(array());
        $this->assertEquals('no-cache', $bag->get('Cache-Control'));
        $this->assertTrue($bag->hasCacheControlDirective('no-cache'));

        $bag->replace(array('Cache-Control' => 'public'));
        $this->assertEquals('public', $bag->get('Cache-Control'));
        $this->assertTrue($bag->hasCacheControlDirective('public'));
    }

    public function testReplaceWithRemove()
    {
        $bag = new ResponseHeaderBag(array());
        $this->assertEquals('no-cache', $bag->get('Cache-Control'));
        $this->assertTrue($bag->hasCacheControlDirective('no-cache'));

        $bag->remove('Cache-Control');
        $bag->replace(array());
        $this->assertEquals('no-cache', $bag->get('Cache-Control'));
        $this->assertTrue($bag->hasCacheControlDirective('no-cache'));
    }

    public function testCookiesWithSameNames()
    {
        $bag = new ResponseHeaderBag();
        $bag->setCookie(new Cookie('foo', 'bar', 0, '/path/foo', 'foo.bar'));
        $bag->setCookie(new Cookie('foo', 'bar', 0, '/path/bar', 'foo.bar'));
        $bag->setCookie(new Cookie('foo', 'bar', 0, '/path/bar', 'bar.foo'));
        $bag->setCookie(new Cookie('foo', 'bar'));

        $this->assertCount(4, $bag->getCookies());

        $headers = explode("\r\n", $bag->__toString());
        $this->assertContains('Set-Cookie: foo=bar; path=/path/foo; domain=foo.bar; httponly', $headers);
        $this->assertContains('Set-Cookie: foo=bar; path=/path/foo; domain=foo.bar; httponly', $headers);
        $this->assertContains('Set-Cookie: foo=bar; path=/path/bar; domain=bar.foo; httponly', $headers);
        $this->assertContains('Set-Cookie: foo=bar; path=/; httponly', $headers);

        $cookies = $bag->getCookies(ResponseHeaderBag::COOKIES_ARRAY);
        $this->assertTrue(isset($cookies['foo.bar']['/path/foo']['foo']));
        $this->assertTrue(isset($cookies['foo.bar']['/path/bar']['foo']));
        $this->assertTrue(isset($cookies['bar.foo']['/path/bar']['foo']));
        $this->assertTrue(isset($cookies['']['/']['foo']));
    }

    public function testRemoveCookie()
    {
        $bag = new ResponseHeaderBag();
        $bag->setCookie(new Cookie('foo', 'bar', 0, '/path/foo', 'foo.bar'));
        $bag->setCookie(new Cookie('bar', 'foo', 0, '/path/bar', 'foo.bar'));

        $cookies = $bag->getCookies(ResponseHeaderBag::COOKIES_ARRAY);
        $this->assertTrue(isset($cookies['foo.bar']['/path/foo']));

        $bag->removeCookie('foo', '/path/foo', 'foo.bar');

        $cookies = $bag->getCookies(ResponseHeaderBag::COOKIES_ARRAY);
        $this->assertFalse(isset($cookies['foo.bar']['/path/foo']));

        $bag->removeCookie('bar', '/path/bar', 'foo.bar');

        $cookies = $bag->getCookies(ResponseHeaderBag::COOKIES_ARRAY);
        $this->assertFalse(isset($cookies['foo.bar']));
    }

    public function testRemoveCookieWithNullRemove()
    {
        $bag = new ResponseHeaderBag();
        $bag->setCookie(new Cookie('foo', 'bar', 0));
        $bag->setCookie(new Cookie('bar', 'foo', 0));

        $cookies = $bag->getCookies(ResponseHeaderBag::COOKIES_ARRAY);
        $this->assertTrue(isset($cookies['']['/']));

        $bag->removeCookie('foo', null);
        $cookies = $bag->getCookies(ResponseHeaderBag::COOKIES_ARRAY);
        $this->assertFalse(isset($cookies['']['/']['foo']));

        $bag->removeCookie('bar', null);
        $cookies = $bag->getCookies(ResponseHeaderBag::COOKIES_ARRAY);
        $this->assertFalse(isset($cookies['']['/']['bar']));
    }

    /**
     * @expectedException \InvalidArgumentException
     */
    public function testGetCookiesWithInvalidArgument()
    {
        $bag = new ResponseHeaderBag();

        $cookies = $bag->getCookies('invalid_argument');
    }

    /**
     * @expectedException \InvalidArgumentException
     */
    public function testMakeDispositionInvalidDisposition()
    {
        $headers = new ResponseHeaderBag();

        $headers->makeDisposition('invalid', 'foo.html');
    }

    /**
     * @dataProvider provideMakeDisposition
     */
    public function testMakeDisposition($disposition, $filename, $filenameFallback, $expected)
    {
        $headers = new ResponseHeaderBag();

        $this->assertEquals($expected, $headers->makeDisposition($disposition, $filename, $filenameFallback));
    }

    public function testToStringDoesntMessUpHeaders()
    {
        $headers = new ResponseHeaderBag();

        $headers->set('Location', 'http://www.symfony.com');
        $headers->set('Content-type', 'text/html');

        (string) $headers;

        $allHeaders = $headers->allPreserveCase();
        $this->assertEquals(array('http://www.symfony.com'), $allHeaders['Location']);
        $this->assertEquals(array('text/html'), $allHeaders['Content-type']);
    }

    public function provideMakeDisposition()
    {
        return array(
            array('attachment', 'foo.html', 'foo.html', 'attachment; filename="foo.html"'),
            array('attachment', 'foo.html', '', 'attachment; filename="foo.html"'),
            array('attachment', 'foo bar.html', '', 'attachment; filename="foo bar.html"'),
            array('attachment', 'foo "bar".html', '', 'attachment; filename="foo \\"bar\\".html"'),
            array('attachment', 'foo%20bar.html', 'foo bar.html', 'attachment; filename="foo bar.html"; filename*=utf-8\'\'foo%2520bar.html'),
            array('attachment', 'föö.html', 'foo.html', 'attachment; filename="foo.html"; filename*=utf-8\'\'f%C3%B6%C3%B6.html'),
        );
    }

    /**
     * @dataProvider provideMakeDispositionFail
     * @expectedException \InvalidArgumentException
     */
    public function testMakeDispositionFail($disposition, $filename)
    {
        $headers = new ResponseHeaderBag();

        $headers->makeDisposition($disposition, $filename);
    }

    public function provideMakeDispositionFail()
    {
        return array(
            array('attachment', 'foo%20bar.html'),
            array('attachment', 'foo/bar.html'),
            array('attachment', '/foo.html'),
            array('attachment', 'foo\bar.html'),
            array('attachment', '\foo.html'),
            array('attachment', 'föö.html'),
        );
    }
}
PKϤ$Z#���AA$http-foundation/StreamedResponse.phpnu�[���<?php

/*
 * This file is part of the Symfony package.
 *
 * (c) Fabien Potencier <fabien@symfony.com>
 *
 * For the full copyright and license information, please view the LICENSE
 * file that was distributed with this source code.
 */

namespace Symfony\Component\HttpFoundation;

/**
 * StreamedResponse represents a streamed HTTP response.
 *
 * A StreamedResponse uses a callback for its content.
 *
 * The callback should use the standard PHP functions like echo
 * to stream the response back to the client. The flush() function
 * can also be used if needed.
 *
 * @see flush()
 *
 * @author Fabien Potencier <fabien@symfony.com>
 */
class StreamedResponse extends Response
{
    protected $callback;
    protected $streamed;
    private $headersSent;

    public function __construct(callable $callback = null, int $status = 200, array $headers = [])
    {
        parent::__construct(null, $status, $headers);

        if (null !== $callback) {
            $this->setCallback($callback);
        }
        $this->streamed = false;
        $this->headersSent = false;
    }

    /**
     * Factory method for chainability.
     *
     * @param callable|null $callback A valid PHP callback or null to set it later
     *
     * @return static
     *
     * @deprecated since Symfony 5.1, use __construct() instead.
     */
    public static function create($callback = null, int $status = 200, array $headers = [])
    {
        trigger_deprecation('symfony/http-foundation', '5.1', 'The "%s()" method is deprecated, use "new %s()" instead.', __METHOD__, static::class);

        return new static($callback, $status, $headers);
    }

    /**
     * Sets the PHP callback associated with this Response.
     *
     * @return $this
     */
    public function setCallback(callable $callback)
    {
        $this->callback = $callback;

        return $this;
    }

    /**
     * {@inheritdoc}
     *
     * This method only sends the headers once.
     *
     * @return $this
     */
    public function sendHeaders()
    {
        if ($this->headersSent) {
            return $this;
        }

        $this->headersSent = true;

        return parent::sendHeaders();
    }

    /**
     * {@inheritdoc}
     *
     * This method only sends the content once.
     *
     * @return $this
     */
    public function sendContent()
    {
        if ($this->streamed) {
            return $this;
        }

        $this->streamed = true;

        if (null === $this->callback) {
            throw new \LogicException('The Response callback must not be null.');
        }

        ($this->callback)();

        return $this;
    }

    /**
     * {@inheritdoc}
     *
     * @throws \LogicException when the content is not null
     *
     * @return $this
     */
    public function setContent(?string $content)
    {
        if (null !== $content) {
            throw new \LogicException('The content cannot be set on a StreamedResponse instance.');
        }

        $this->streamed = true;

        return $this;
    }

    /**
     * {@inheritdoc}
     */
    public function getContent()
    {
        return false;
    }
}
PKϤ$Z��k��-�-http-foundation/Cookie.phpnu�[���<?php

/*
 * This file is part of the Symfony package.
 *
 * (c) Fabien Potencier <fabien@symfony.com>
 *
 * For the full copyright and license information, please view the LICENSE
 * file that was distributed with this source code.
 */

namespace Symfony\Component\HttpFoundation;

/**
 * Represents a cookie.
 *
 * @author Johannes M. Schmitt <schmittjoh@gmail.com>
 */
class Cookie
{
    public const SAMESITE_NONE = 'none';
    public const SAMESITE_LAX = 'lax';
    public const SAMESITE_STRICT = 'strict';

    protected $name;
    protected $value;
    protected $domain;
    protected $expire;
    protected $path;
    protected $secure;
    protected $httpOnly;

    private $raw;
    private $sameSite;
    private $secureDefault = false;

    private static $reservedCharsList = "=,; \t\r\n\v\f";
    private const RESERVED_CHARS_FROM = ['=', ',', ';', ' ', "\t", "\r", "\n", "\v", "\f"];
    private const RESERVED_CHARS_TO = ['%3D', '%2C', '%3B', '%20', '%09', '%0D', '%0A', '%0B', '%0C'];

    /**
     * Creates cookie from raw header string.
     *
     * @return static
     */
    public static function fromString(string $cookie, bool $decode = false)
    {
        $data = [
            'expires' => 0,
            'path' => '/',
            'domain' => null,
            'secure' => false,
            'httponly' => false,
            'raw' => !$decode,
            'samesite' => null,
        ];

        $parts = HeaderUtils::split($cookie, ';=');
        $part = array_shift($parts);

        $name = $decode ? urldecode($part[0]) : $part[0];
        $value = isset($part[1]) ? ($decode ? urldecode($part[1]) : $part[1]) : null;

        $data = HeaderUtils::combine($parts) + $data;
        $data['expires'] = self::expiresTimestamp($data['expires']);

        if (isset($data['max-age']) && ($data['max-age'] > 0 || $data['expires'] > time())) {
            $data['expires'] = time() + (int) $data['max-age'];
        }

        return new static($name, $value, $data['expires'], $data['path'], $data['domain'], $data['secure'], $data['httponly'], $data['raw'], $data['samesite']);
    }

    public static function create(string $name, string $value = null, $expire = 0, ?string $path = '/', string $domain = null, bool $secure = null, bool $httpOnly = true, bool $raw = false, ?string $sameSite = self::SAMESITE_LAX): self
    {
        return new self($name, $value, $expire, $path, $domain, $secure, $httpOnly, $raw, $sameSite);
    }

    /**
     * @param string                        $name     The name of the cookie
     * @param string|null                   $value    The value of the cookie
     * @param int|string|\DateTimeInterface $expire   The time the cookie expires
     * @param string                        $path     The path on the server in which the cookie will be available on
     * @param string|null                   $domain   The domain that the cookie is available to
     * @param bool|null                     $secure   Whether the client should send back the cookie only over HTTPS or null to auto-enable this when the request is already using HTTPS
     * @param bool                          $httpOnly Whether the cookie will be made accessible only through the HTTP protocol
     * @param bool                          $raw      Whether the cookie value should be sent with no url encoding
     * @param string|null                   $sameSite Whether the cookie will be available for cross-site requests
     *
     * @throws \InvalidArgumentException
     */
    public function __construct(string $name, string $value = null, $expire = 0, ?string $path = '/', string $domain = null, bool $secure = null, bool $httpOnly = true, bool $raw = false, ?string $sameSite = 'lax')
    {
        // from PHP source code
        if ($raw && false !== strpbrk($name, self::$reservedCharsList)) {
            throw new \InvalidArgumentException(sprintf('The cookie name "%s" contains invalid characters.', $name));
        }

        if (empty($name)) {
            throw new \InvalidArgumentException('The cookie name cannot be empty.');
        }

        $this->name = $name;
        $this->value = $value;
        $this->domain = $domain;
        $this->expire = self::expiresTimestamp($expire);
        $this->path = empty($path) ? '/' : $path;
        $this->secure = $secure;
        $this->httpOnly = $httpOnly;
        $this->raw = $raw;
        $this->sameSite = $this->withSameSite($sameSite)->sameSite;
    }

    /**
     * Creates a cookie copy with a new value.
     *
     * @return static
     */
    public function withValue(?string $value): self
    {
        $cookie = clone $this;
        $cookie->value = $value;

        return $cookie;
    }

    /**
     * Creates a cookie copy with a new domain that the cookie is available to.
     *
     * @return static
     */
    public function withDomain(?string $domain): self
    {
        $cookie = clone $this;
        $cookie->domain = $domain;

        return $cookie;
    }

    /**
     * Creates a cookie copy with a new time the cookie expires.
     *
     * @param int|string|\DateTimeInterface $expire
     *
     * @return static
     */
    public function withExpires($expire = 0): self
    {
        $cookie = clone $this;
        $cookie->expire = self::expiresTimestamp($expire);

        return $cookie;
    }

    /**
     * Converts expires formats to a unix timestamp.
     *
     * @param int|string|\DateTimeInterface $expire
     *
     * @return int
     */
    private static function expiresTimestamp($expire = 0)
    {
        // convert expiration time to a Unix timestamp
        if ($expire instanceof \DateTimeInterface) {
            $expire = $expire->format('U');
        } elseif (!is_numeric($expire)) {
            $expire = strtotime($expire);

            if (false === $expire) {
                throw new \InvalidArgumentException('The cookie expiration time is not valid.');
            }
        }

        return 0 < $expire ? (int) $expire : 0;
    }

    /**
     * Creates a cookie copy with a new path on the server in which the cookie will be available on.
     *
     * @return static
     */
    public function withPath(string $path): self
    {
        $cookie = clone $this;
        $cookie->path = '' === $path ? '/' : $path;

        return $cookie;
    }

    /**
     * Creates a cookie copy that only be transmitted over a secure HTTPS connection from the client.
     *
     * @return static
     */
    public function withSecure(bool $secure = true): self
    {
        $cookie = clone $this;
        $cookie->secure = $secure;

        return $cookie;
    }

    /**
     * Creates a cookie copy that be accessible only through the HTTP protocol.
     *
     * @return static
     */
    public function withHttpOnly(bool $httpOnly = true): self
    {
        $cookie = clone $this;
        $cookie->httpOnly = $httpOnly;

        return $cookie;
    }

    /**
     * Creates a cookie copy that uses no url encoding.
     *
     * @return static
     */
    public function withRaw(bool $raw = true): self
    {
        if ($raw && false !== strpbrk($this->name, self::$reservedCharsList)) {
            throw new \InvalidArgumentException(sprintf('The cookie name "%s" contains invalid characters.', $this->name));
        }

        $cookie = clone $this;
        $cookie->raw = $raw;

        return $cookie;
    }

    /**
     * Creates a cookie copy with SameSite attribute.
     *
     * @return static
     */
    public function withSameSite(?string $sameSite): self
    {
        if ('' === $sameSite) {
            $sameSite = null;
        } elseif (null !== $sameSite) {
            $sameSite = strtolower($sameSite);
        }

        if (!\in_array($sameSite, [self::SAMESITE_LAX, self::SAMESITE_STRICT, self::SAMESITE_NONE, null], true)) {
            throw new \InvalidArgumentException('The "sameSite" parameter value is not valid.');
        }

        $cookie = clone $this;
        $cookie->sameSite = $sameSite;

        return $cookie;
    }

    /**
     * Returns the cookie as a string.
     *
     * @return string The cookie
     */
    public function __toString()
    {
        if ($this->isRaw()) {
            $str = $this->getName();
        } else {
            $str = str_replace(self::RESERVED_CHARS_FROM, self::RESERVED_CHARS_TO, $this->getName());
        }

        $str .= '=';

        if ('' === (string) $this->getValue()) {
            $str .= 'deleted; expires='.gmdate('D, d-M-Y H:i:s T', time() - 31536001).'; Max-Age=0';
        } else {
            $str .= $this->isRaw() ? $this->getValue() : rawurlencode($this->getValue());

            if (0 !== $this->getExpiresTime()) {
                $str .= '; expires='.gmdate('D, d-M-Y H:i:s T', $this->getExpiresTime()).'; Max-Age='.$this->getMaxAge();
            }
        }

        if ($this->getPath()) {
            $str .= '; path='.$this->getPath();
        }

        if ($this->getDomain()) {
            $str .= '; domain='.$this->getDomain();
        }

        if (true === $this->isSecure()) {
            $str .= '; secure';
        }

        if (true === $this->isHttpOnly()) {
            $str .= '; httponly';
        }

        if (null !== $this->getSameSite()) {
            $str .= '; samesite='.$this->getSameSite();
        }

        return $str;
    }

    /**
     * Gets the name of the cookie.
     *
     * @return string
     */
    public function getName()
    {
        return $this->name;
    }

    /**
     * Gets the value of the cookie.
     *
     * @return string|null
     */
    public function getValue()
    {
        return $this->value;
    }

    /**
     * Gets the domain that the cookie is available to.
     *
     * @return string|null
     */
    public function getDomain()
    {
        return $this->domain;
    }

    /**
     * Gets the time the cookie expires.
     *
     * @return int
     */
    public function getExpiresTime()
    {
        return $this->expire;
    }

    /**
     * Gets the max-age attribute.
     *
     * @return int
     */
    public function getMaxAge()
    {
        $maxAge = $this->expire - time();

        return 0 >= $maxAge ? 0 : $maxAge;
    }

    /**
     * Gets the path on the server in which the cookie will be available on.
     *
     * @return string
     */
    public function getPath()
    {
        return $this->path;
    }

    /**
     * Checks whether the cookie should only be transmitted over a secure HTTPS connection from the client.
     *
     * @return bool
     */
    public function isSecure()
    {
        return $this->secure ?? $this->secureDefault;
    }

    /**
     * Checks whether the cookie will be made accessible only through the HTTP protocol.
     *
     * @return bool
     */
    public function isHttpOnly()
    {
        return $this->httpOnly;
    }

    /**
     * Whether this cookie is about to be cleared.
     *
     * @return bool
     */
    public function isCleared()
    {
        return 0 !== $this->expire && $this->expire < time();
    }

    /**
     * Checks if the cookie value should be sent with no url encoding.
     *
     * @return bool
     */
    public function isRaw()
    {
        return $this->raw;
    }

    /**
     * Gets the SameSite attribute.
     *
     * @return string|null
     */
    public function getSameSite()
    {
        return $this->sameSite;
    }

    /**
     * @param bool $default The default value of the "secure" flag when it is set to null
     */
    public function setSecureDefault(bool $default): void
    {
        $this->secureDefault = $default;
    }
}
PKϤ$Z�/	���http-foundation/ServerBag.phpnu�[���<?php

/*
 * This file is part of the Symfony package.
 *
 * (c) Fabien Potencier <fabien@symfony.com>
 *
 * For the full copyright and license information, please view the LICENSE
 * file that was distributed with this source code.
 */

namespace Symfony\Component\HttpFoundation;

/**
 * ServerBag is a container for HTTP headers from the $_SERVER variable.
 *
 * @author Fabien Potencier <fabien@symfony.com>
 * @author Bulat Shakirzyanov <mallluhuct@gmail.com>
 * @author Robert Kiss <kepten@gmail.com>
 */
class ServerBag extends ParameterBag
{
    /**
     * Gets the HTTP headers.
     *
     * @return array
     */
    public function getHeaders()
    {
        $headers = [];
        foreach ($this->parameters as $key => $value) {
            if (str_starts_with($key, 'HTTP_')) {
                $headers[substr($key, 5)] = $value;
            } elseif (\in_array($key, ['CONTENT_TYPE', 'CONTENT_LENGTH', 'CONTENT_MD5'], true)) {
                $headers[$key] = $value;
            }
        }

        if (isset($this->parameters['PHP_AUTH_USER'])) {
            $headers['PHP_AUTH_USER'] = $this->parameters['PHP_AUTH_USER'];
            $headers['PHP_AUTH_PW'] = $this->parameters['PHP_AUTH_PW'] ?? '';
        } else {
            /*
             * php-cgi under Apache does not pass HTTP Basic user/pass to PHP by default
             * For this workaround to work, add these lines to your .htaccess file:
             * RewriteCond %{HTTP:Authorization} .+
             * RewriteRule ^ - [E=HTTP_AUTHORIZATION:%0]
             *
             * A sample .htaccess file:
             * RewriteEngine On
             * RewriteCond %{HTTP:Authorization} .+
             * RewriteRule ^ - [E=HTTP_AUTHORIZATION:%0]
             * RewriteCond %{REQUEST_FILENAME} !-f
             * RewriteRule ^(.*)$ app.php [QSA,L]
             */

            $authorizationHeader = null;
            if (isset($this->parameters['HTTP_AUTHORIZATION'])) {
                $authorizationHeader = $this->parameters['HTTP_AUTHORIZATION'];
            } elseif (isset($this->parameters['REDIRECT_HTTP_AUTHORIZATION'])) {
                $authorizationHeader = $this->parameters['REDIRECT_HTTP_AUTHORIZATION'];
            }

            if (null !== $authorizationHeader) {
                if (0 === stripos($authorizationHeader, 'basic ')) {
                    // Decode AUTHORIZATION header into PHP_AUTH_USER and PHP_AUTH_PW when authorization header is basic
                    $exploded = explode(':', base64_decode(substr($authorizationHeader, 6)), 2);
                    if (2 == \count($exploded)) {
                        [$headers['PHP_AUTH_USER'], $headers['PHP_AUTH_PW']] = $exploded;
                    }
                } elseif (empty($this->parameters['PHP_AUTH_DIGEST']) && (0 === stripos($authorizationHeader, 'digest '))) {
                    // In some circumstances PHP_AUTH_DIGEST needs to be set
                    $headers['PHP_AUTH_DIGEST'] = $authorizationHeader;
                    $this->parameters['PHP_AUTH_DIGEST'] = $authorizationHeader;
                } elseif (0 === stripos($authorizationHeader, 'bearer ')) {
                    /*
                     * XXX: Since there is no PHP_AUTH_BEARER in PHP predefined variables,
                     *      I'll just set $headers['AUTHORIZATION'] here.
                     *      https://php.net/reserved.variables.server
                     */
                    $headers['AUTHORIZATION'] = $authorizationHeader;
                }
            }
        }

        if (isset($headers['AUTHORIZATION'])) {
            return $headers;
        }

        // PHP_AUTH_USER/PHP_AUTH_PW
        if (isset($headers['PHP_AUTH_USER'])) {
            $headers['AUTHORIZATION'] = 'Basic '.base64_encode($headers['PHP_AUTH_USER'].':'.$headers['PHP_AUTH_PW']);
        } elseif (isset($headers['PHP_AUTH_DIGEST'])) {
            $headers['AUTHORIZATION'] = $headers['PHP_AUTH_DIGEST'];
        }

        return $headers;
    }
}
PKϤ$Zw4�mP
P
$http-foundation/AcceptHeaderItem.phpnu�[���<?php

/*
 * This file is part of the Symfony package.
 *
 * (c) Fabien Potencier <fabien@symfony.com>
 *
 * For the full copyright and license information, please view the LICENSE
 * file that was distributed with this source code.
 */

namespace Symfony\Component\HttpFoundation;

/**
 * Represents an Accept-* header item.
 *
 * @author Jean-François Simon <contact@jfsimon.fr>
 */
class AcceptHeaderItem
{
    private $value;
    private $quality = 1.0;
    private $index = 0;
    private $attributes = [];

    public function __construct(string $value, array $attributes = [])
    {
        $this->value = $value;
        foreach ($attributes as $name => $value) {
            $this->setAttribute($name, $value);
        }
    }

    /**
     * Builds an AcceptHeaderInstance instance from a string.
     *
     * @return self
     */
    public static function fromString(?string $itemValue)
    {
        $parts = HeaderUtils::split($itemValue ?? '', ';=');

        $part = array_shift($parts);
        $attributes = HeaderUtils::combine($parts);

        return new self($part[0], $attributes);
    }

    /**
     * Returns header value's string representation.
     *
     * @return string
     */
    public function __toString()
    {
        $string = $this->value.($this->quality < 1 ? ';q='.$this->quality : '');
        if (\count($this->attributes) > 0) {
            $string .= '; '.HeaderUtils::toString($this->attributes, ';');
        }

        return $string;
    }

    /**
     * Set the item value.
     *
     * @return $this
     */
    public function setValue(string $value)
    {
        $this->value = $value;

        return $this;
    }

    /**
     * Returns the item value.
     *
     * @return string
     */
    public function getValue()
    {
        return $this->value;
    }

    /**
     * Set the item quality.
     *
     * @return $this
     */
    public function setQuality(float $quality)
    {
        $this->quality = $quality;

        return $this;
    }

    /**
     * Returns the item quality.
     *
     * @return float
     */
    public function getQuality()
    {
        return $this->quality;
    }

    /**
     * Set the item index.
     *
     * @return $this
     */
    public function setIndex(int $index)
    {
        $this->index = $index;

        return $this;
    }

    /**
     * Returns the item index.
     *
     * @return int
     */
    public function getIndex()
    {
        return $this->index;
    }

    /**
     * Tests if an attribute exists.
     *
     * @return bool
     */
    public function hasAttribute(string $name)
    {
        return isset($this->attributes[$name]);
    }

    /**
     * Returns an attribute by its name.
     *
     * @param mixed $default
     *
     * @return mixed
     */
    public function getAttribute(string $name, $default = null)
    {
        return $this->attributes[$name] ?? $default;
    }

    /**
     * Returns all attributes.
     *
     * @return array
     */
    public function getAttributes()
    {
        return $this->attributes;
    }

    /**
     * Set an attribute.
     *
     * @return $this
     */
    public function setAttribute(string $name, string $value)
    {
        if ('q' === $name) {
            $this->quality = (float) $value;
        } else {
            $this->attributes[$name] = $value;
        }

        return $this;
    }
}
PKϤ$ZvZ�]��http-foundation/IpUtils.phpnu�[���<?php

/*
 * This file is part of the Symfony package.
 *
 * (c) Fabien Potencier <fabien@symfony.com>
 *
 * For the full copyright and license information, please view the LICENSE
 * file that was distributed with this source code.
 */

namespace Symfony\Component\HttpFoundation;

/**
 * Http utility functions.
 *
 * @author Fabien Potencier <fabien@symfony.com>
 */
class IpUtils
{
    private static $checkedIps = [];

    /**
     * This class should not be instantiated.
     */
    private function __construct()
    {
    }

    /**
     * Checks if an IPv4 or IPv6 address is contained in the list of given IPs or subnets.
     *
     * @param string|array $ips List of IPs or subnets (can be a string if only a single one)
     *
     * @return bool Whether the IP is valid
     */
    public static function checkIp(?string $requestIp, $ips)
    {
        if (!\is_array($ips)) {
            $ips = [$ips];
        }

        $method = substr_count($requestIp, ':') > 1 ? 'checkIp6' : 'checkIp4';

        foreach ($ips as $ip) {
            if (self::$method($requestIp, $ip)) {
                return true;
            }
        }

        return false;
    }

    /**
     * Compares two IPv4 addresses.
     * In case a subnet is given, it checks if it contains the request IP.
     *
     * @param string $ip IPv4 address or subnet in CIDR notation
     *
     * @return bool Whether the request IP matches the IP, or whether the request IP is within the CIDR subnet
     */
    public static function checkIp4(?string $requestIp, string $ip)
    {
        $cacheKey = $requestIp.'-'.$ip;
        if (isset(self::$checkedIps[$cacheKey])) {
            return self::$checkedIps[$cacheKey];
        }

        if (!filter_var($requestIp, \FILTER_VALIDATE_IP, \FILTER_FLAG_IPV4)) {
            return self::$checkedIps[$cacheKey] = false;
        }

        if (str_contains($ip, '/')) {
            [$address, $netmask] = explode('/', $ip, 2);

            if ('0' === $netmask) {
                return self::$checkedIps[$cacheKey] = filter_var($address, \FILTER_VALIDATE_IP, \FILTER_FLAG_IPV4);
            }

            if ($netmask < 0 || $netmask > 32) {
                return self::$checkedIps[$cacheKey] = false;
            }
        } else {
            $address = $ip;
            $netmask = 32;
        }

        if (false === ip2long($address)) {
            return self::$checkedIps[$cacheKey] = false;
        }

        return self::$checkedIps[$cacheKey] = 0 === substr_compare(sprintf('%032b', ip2long($requestIp)), sprintf('%032b', ip2long($address)), 0, $netmask);
    }

    /**
     * Compares two IPv6 addresses.
     * In case a subnet is given, it checks if it contains the request IP.
     *
     * @author David Soria Parra <dsp at php dot net>
     *
     * @see https://github.com/dsp/v6tools
     *
     * @param string $ip IPv6 address or subnet in CIDR notation
     *
     * @return bool Whether the IP is valid
     *
     * @throws \RuntimeException When IPV6 support is not enabled
     */
    public static function checkIp6(?string $requestIp, string $ip)
    {
        $cacheKey = $requestIp.'-'.$ip;
        if (isset(self::$checkedIps[$cacheKey])) {
            return self::$checkedIps[$cacheKey];
        }

        if (!((\extension_loaded('sockets') && \defined('AF_INET6')) || @inet_pton('::1'))) {
            throw new \RuntimeException('Unable to check Ipv6. Check that PHP was not compiled with option "disable-ipv6".');
        }

        if (str_contains($ip, '/')) {
            [$address, $netmask] = explode('/', $ip, 2);

            if ('0' === $netmask) {
                return (bool) unpack('n*', @inet_pton($address));
            }

            if ($netmask < 1 || $netmask > 128) {
                return self::$checkedIps[$cacheKey] = false;
            }
        } else {
            $address = $ip;
            $netmask = 128;
        }

        $bytesAddr = unpack('n*', @inet_pton($address));
        $bytesTest = unpack('n*', @inet_pton($requestIp));

        if (!$bytesAddr || !$bytesTest) {
            return self::$checkedIps[$cacheKey] = false;
        }

        for ($i = 1, $ceil = ceil($netmask / 16); $i <= $ceil; ++$i) {
            $left = $netmask - 16 * ($i - 1);
            $left = ($left <= 16) ? $left : 16;
            $mask = ~(0xffff >> $left) & 0xffff;
            if (($bytesAddr[$i] & $mask) != ($bytesTest[$i] & $mask)) {
                return self::$checkedIps[$cacheKey] = false;
            }
        }

        return self::$checkedIps[$cacheKey] = true;
    }

    /**
     * Anonymizes an IP/IPv6.
     *
     * Removes the last byte for v4 and the last 8 bytes for v6 IPs
     */
    public static function anonymize(string $ip): string
    {
        $wrappedIPv6 = false;
        if ('[' === substr($ip, 0, 1) && ']' === substr($ip, -1, 1)) {
            $wrappedIPv6 = true;
            $ip = substr($ip, 1, -1);
        }

        $packedAddress = inet_pton($ip);
        if (4 === \strlen($packedAddress)) {
            $mask = '255.255.255.0';
        } elseif ($ip === inet_ntop($packedAddress & inet_pton('::ffff:ffff:ffff'))) {
            $mask = '::ffff:ffff:ff00';
        } elseif ($ip === inet_ntop($packedAddress & inet_pton('::ffff:ffff'))) {
            $mask = '::ffff:ff00';
        } else {
            $mask = 'ffff:ffff:ffff:ffff:0000:0000:0000:0000';
        }
        $ip = inet_ntop($packedAddress & inet_pton($mask));

        if ($wrappedIPv6) {
            $ip = '['.$ip.']';
        }

        return $ip;
    }
}
PKϤ$ZƜ`��� http-foundation/ParameterBag.phpnu�[���<?php

/*
 * This file is part of the Symfony package.
 *
 * (c) Fabien Potencier <fabien@symfony.com>
 *
 * For the full copyright and license information, please view the LICENSE
 * file that was distributed with this source code.
 */

namespace Symfony\Component\HttpFoundation;

use Symfony\Component\HttpFoundation\Exception\BadRequestException;

/**
 * ParameterBag is a container for key/value pairs.
 *
 * @author Fabien Potencier <fabien@symfony.com>
 */
class ParameterBag implements \IteratorAggregate, \Countable
{
    /**
     * Parameter storage.
     */
    protected $parameters;

    public function __construct(array $parameters = [])
    {
        $this->parameters = $parameters;
    }

    /**
     * Returns the parameters.
     *
     * @param string|null $key The name of the parameter to return or null to get them all
     *
     * @return array An array of parameters
     */
    public function all(/*string $key = null*/)
    {
        $key = \func_num_args() > 0 ? func_get_arg(0) : null;

        if (null === $key) {
            return $this->parameters;
        }

        if (!\is_array($value = $this->parameters[$key] ?? [])) {
            throw new BadRequestException(sprintf('Unexpected value for parameter "%s": expecting "array", got "%s".', $key, get_debug_type($value)));
        }

        return $value;
    }

    /**
     * Returns the parameter keys.
     *
     * @return array An array of parameter keys
     */
    public function keys()
    {
        return array_keys($this->parameters);
    }

    /**
     * Replaces the current parameters by a new set.
     */
    public function replace(array $parameters = [])
    {
        $this->parameters = $parameters;
    }

    /**
     * Adds parameters.
     */
    public function add(array $parameters = [])
    {
        $this->parameters = array_replace($this->parameters, $parameters);
    }

    /**
     * Returns a parameter by name.
     *
     * @param mixed $default The default value if the parameter key does not exist
     *
     * @return mixed
     */
    public function get(string $key, $default = null)
    {
        return \array_key_exists($key, $this->parameters) ? $this->parameters[$key] : $default;
    }

    /**
     * Sets a parameter by name.
     *
     * @param mixed $value The value
     */
    public function set(string $key, $value)
    {
        $this->parameters[$key] = $value;
    }

    /**
     * Returns true if the parameter is defined.
     *
     * @return bool true if the parameter exists, false otherwise
     */
    public function has(string $key)
    {
        return \array_key_exists($key, $this->parameters);
    }

    /**
     * Removes a parameter.
     */
    public function remove(string $key)
    {
        unset($this->parameters[$key]);
    }

    /**
     * Returns the alphabetic characters of the parameter value.
     *
     * @return string The filtered value
     */
    public function getAlpha(string $key, string $default = '')
    {
        return preg_replace('/[^[:alpha:]]/', '', $this->get($key, $default));
    }

    /**
     * Returns the alphabetic characters and digits of the parameter value.
     *
     * @return string The filtered value
     */
    public function getAlnum(string $key, string $default = '')
    {
        return preg_replace('/[^[:alnum:]]/', '', $this->get($key, $default));
    }

    /**
     * Returns the digits of the parameter value.
     *
     * @return string The filtered value
     */
    public function getDigits(string $key, string $default = '')
    {
        // we need to remove - and + because they're allowed in the filter
        return str_replace(['-', '+'], '', $this->filter($key, $default, \FILTER_SANITIZE_NUMBER_INT));
    }

    /**
     * Returns the parameter value converted to integer.
     *
     * @return int The filtered value
     */
    public function getInt(string $key, int $default = 0)
    {
        return (int) $this->get($key, $default);
    }

    /**
     * Returns the parameter value converted to boolean.
     *
     * @return bool The filtered value
     */
    public function getBoolean(string $key, bool $default = false)
    {
        return $this->filter($key, $default, \FILTER_VALIDATE_BOOLEAN);
    }

    /**
     * Filter key.
     *
     * @param mixed $default Default = null
     * @param int   $filter  FILTER_* constant
     * @param mixed $options Filter options
     *
     * @see https://php.net/filter-var
     *
     * @return mixed
     */
    public function filter(string $key, $default = null, int $filter = \FILTER_DEFAULT, $options = [])
    {
        $value = $this->get($key, $default);

        // Always turn $options into an array - this allows filter_var option shortcuts.
        if (!\is_array($options) && $options) {
            $options = ['flags' => $options];
        }

        // Add a convenience check for arrays.
        if (\is_array($value) && !isset($options['flags'])) {
            $options['flags'] = \FILTER_REQUIRE_ARRAY;
        }

        if ((\FILTER_CALLBACK & $filter) && !(($options['options'] ?? null) instanceof \Closure)) {
            trigger_deprecation('symfony/http-foundation', '5.2', 'Not passing a Closure together with FILTER_CALLBACK to "%s()" is deprecated. Wrap your filter in a closure instead.', __METHOD__);
            // throw new \InvalidArgumentException(sprintf('A Closure must be passed to "%s()" when FILTER_CALLBACK is used, "%s" given.', __METHOD__, get_debug_type($options['options'] ?? null)));
        }

        return filter_var($value, $filter, $options);
    }

    /**
     * Returns an iterator for parameters.
     *
     * @return \ArrayIterator An \ArrayIterator instance
     */
    #[\ReturnTypeWillChange]
    public function getIterator()
    {
        return new \ArrayIterator($this->parameters);
    }

    /**
     * Returns the number of parameters.
     *
     * @return int The number of parameters
     */
    #[\ReturnTypeWillChange]
    public function count()
    {
        return \count($this->parameters);
    }
}
PKϤ$Z�K>��!http-foundation/ApacheRequest.phpnu�[���<?php

/*
 * This file is part of the Symfony package.
 *
 * (c) Fabien Potencier <fabien@symfony.com>
 *
 * For the full copyright and license information, please view the LICENSE
 * file that was distributed with this source code.
 */

namespace Symfony\Component\HttpFoundation;

/**
 * Request represents an HTTP request from an Apache server.
 *
 * @author Fabien Potencier <fabien@symfony.com>
 */
class ApacheRequest extends Request
{
    /**
     * {@inheritdoc}
     */
    protected function prepareRequestUri()
    {
        return $this->server->get('REQUEST_URI');
    }

    /**
     * {@inheritdoc}
     */
    protected function prepareBaseUrl()
    {
        $baseUrl = $this->server->get('SCRIPT_NAME');

        if (false === strpos($this->server->get('REQUEST_URI'), $baseUrl)) {
            // assume mod_rewrite
            return rtrim(dirname($baseUrl), '/\\');
        }

        return $baseUrl;
    }
}
PKϤ$Z�j��0�0&http-foundation/BinaryFileResponse.phpnu�[���<?php

/*
 * This file is part of the Symfony package.
 *
 * (c) Fabien Potencier <fabien@symfony.com>
 *
 * For the full copyright and license information, please view the LICENSE
 * file that was distributed with this source code.
 */

namespace Symfony\Component\HttpFoundation;

use Symfony\Component\HttpFoundation\File\Exception\FileException;
use Symfony\Component\HttpFoundation\File\File;

/**
 * BinaryFileResponse represents an HTTP response delivering a file.
 *
 * @author Niklas Fiekas <niklas.fiekas@tu-clausthal.de>
 * @author stealth35 <stealth35-php@live.fr>
 * @author Igor Wiedler <igor@wiedler.ch>
 * @author Jordan Alliot <jordan.alliot@gmail.com>
 * @author Sergey Linnik <linniksa@gmail.com>
 */
class BinaryFileResponse extends Response
{
    protected static $trustXSendfileTypeHeader = false;

    /**
     * @var File
     */
    protected $file;
    protected $offset = 0;
    protected $maxlen = -1;
    protected $deleteFileAfterSend = false;

    /**
     * @param \SplFileInfo|string $file               The file to stream
     * @param int                 $status             The response status code
     * @param array               $headers            An array of response headers
     * @param bool                $public             Files are public by default
     * @param string|null         $contentDisposition The type of Content-Disposition to set automatically with the filename
     * @param bool                $autoEtag           Whether the ETag header should be automatically set
     * @param bool                $autoLastModified   Whether the Last-Modified header should be automatically set
     */
    public function __construct($file, int $status = 200, array $headers = [], bool $public = true, string $contentDisposition = null, bool $autoEtag = false, bool $autoLastModified = true)
    {
        parent::__construct(null, $status, $headers);

        $this->setFile($file, $contentDisposition, $autoEtag, $autoLastModified);

        if ($public) {
            $this->setPublic();
        }
    }

    /**
     * @param \SplFileInfo|string $file               The file to stream
     * @param int                 $status             The response status code
     * @param array               $headers            An array of response headers
     * @param bool                $public             Files are public by default
     * @param string|null         $contentDisposition The type of Content-Disposition to set automatically with the filename
     * @param bool                $autoEtag           Whether the ETag header should be automatically set
     * @param bool                $autoLastModified   Whether the Last-Modified header should be automatically set
     *
     * @return static
     *
     * @deprecated since Symfony 5.2, use __construct() instead.
     */
    public static function create($file = null, int $status = 200, array $headers = [], bool $public = true, string $contentDisposition = null, bool $autoEtag = false, bool $autoLastModified = true)
    {
        trigger_deprecation('symfony/http-foundation', '5.2', 'The "%s()" method is deprecated, use "new %s()" instead.', __METHOD__, static::class);

        return new static($file, $status, $headers, $public, $contentDisposition, $autoEtag, $autoLastModified);
    }

    /**
     * Sets the file to stream.
     *
     * @param \SplFileInfo|string $file The file to stream
     *
     * @return $this
     *
     * @throws FileException
     */
    public function setFile($file, string $contentDisposition = null, bool $autoEtag = false, bool $autoLastModified = true)
    {
        if (!$file instanceof File) {
            if ($file instanceof \SplFileInfo) {
                $file = new File($file->getPathname());
            } else {
                $file = new File((string) $file);
            }
        }

        if (!$file->isReadable()) {
            throw new FileException('File must be readable.');
        }

        $this->file = $file;

        if ($autoEtag) {
            $this->setAutoEtag();
        }

        if ($autoLastModified) {
            $this->setAutoLastModified();
        }

        if ($contentDisposition) {
            $this->setContentDisposition($contentDisposition);
        }

        return $this;
    }

    /**
     * Gets the file.
     *
     * @return File The file to stream
     */
    public function getFile()
    {
        return $this->file;
    }

    /**
     * Automatically sets the Last-Modified header according the file modification date.
     */
    public function setAutoLastModified()
    {
        $this->setLastModified(\DateTime::createFromFormat('U', $this->file->getMTime()));

        return $this;
    }

    /**
     * Automatically sets the ETag header according to the checksum of the file.
     */
    public function setAutoEtag()
    {
        $this->setEtag(base64_encode(hash_file('sha256', $this->file->getPathname(), true)));

        return $this;
    }

    /**
     * Sets the Content-Disposition header with the given filename.
     *
     * @param string $disposition      ResponseHeaderBag::DISPOSITION_INLINE or ResponseHeaderBag::DISPOSITION_ATTACHMENT
     * @param string $filename         Optionally use this UTF-8 encoded filename instead of the real name of the file
     * @param string $filenameFallback A fallback filename, containing only ASCII characters. Defaults to an automatically encoded filename
     *
     * @return $this
     */
    public function setContentDisposition(string $disposition, string $filename = '', string $filenameFallback = '')
    {
        if ('' === $filename) {
            $filename = $this->file->getFilename();
        }

        if ('' === $filenameFallback && (!preg_match('/^[\x20-\x7e]*$/', $filename) || str_contains($filename, '%'))) {
            $encoding = mb_detect_encoding($filename, null, true) ?: '8bit';

            for ($i = 0, $filenameLength = mb_strlen($filename, $encoding); $i < $filenameLength; ++$i) {
                $char = mb_substr($filename, $i, 1, $encoding);

                if ('%' === $char || \ord($char) < 32 || \ord($char) > 126) {
                    $filenameFallback .= '_';
                } else {
                    $filenameFallback .= $char;
                }
            }
        }

        $dispositionHeader = $this->headers->makeDisposition($disposition, $filename, $filenameFallback);
        $this->headers->set('Content-Disposition', $dispositionHeader);

        return $this;
    }

    /**
     * {@inheritdoc}
     */
    public function prepare(Request $request)
    {
        if (!$this->headers->has('Content-Type')) {
            $this->headers->set('Content-Type', $this->file->getMimeType() ?: 'application/octet-stream');
        }

        if ('HTTP/1.0' !== $request->server->get('SERVER_PROTOCOL')) {
            $this->setProtocolVersion('1.1');
        }

        $this->ensureIEOverSSLCompatibility($request);

        $this->offset = 0;
        $this->maxlen = -1;

        if (false === $fileSize = $this->file->getSize()) {
            return $this;
        }
        $this->headers->set('Content-Length', $fileSize);

        if (!$this->headers->has('Accept-Ranges')) {
            // Only accept ranges on safe HTTP methods
            $this->headers->set('Accept-Ranges', $request->isMethodSafe() ? 'bytes' : 'none');
        }

        if (self::$trustXSendfileTypeHeader && $request->headers->has('X-Sendfile-Type')) {
            // Use X-Sendfile, do not send any content.
            $type = $request->headers->get('X-Sendfile-Type');
            $path = $this->file->getRealPath();
            // Fall back to scheme://path for stream wrapped locations.
            if (false === $path) {
                $path = $this->file->getPathname();
            }
            if ('x-accel-redirect' === strtolower($type)) {
                // Do X-Accel-Mapping substitutions.
                // @link https://www.nginx.com/resources/wiki/start/topics/examples/x-accel/#x-accel-redirect
                $parts = HeaderUtils::split($request->headers->get('X-Accel-Mapping', ''), ',=');
                foreach ($parts as $part) {
                    [$pathPrefix, $location] = $part;
                    if (substr($path, 0, \strlen($pathPrefix)) === $pathPrefix) {
                        $path = $location.substr($path, \strlen($pathPrefix));
                        // Only set X-Accel-Redirect header if a valid URI can be produced
                        // as nginx does not serve arbitrary file paths.
                        $this->headers->set($type, $path);
                        $this->maxlen = 0;
                        break;
                    }
                }
            } else {
                $this->headers->set($type, $path);
                $this->maxlen = 0;
            }
        } elseif ($request->headers->has('Range') && $request->isMethod('GET')) {
            // Process the range headers.
            if (!$request->headers->has('If-Range') || $this->hasValidIfRangeHeader($request->headers->get('If-Range'))) {
                $range = $request->headers->get('Range');

                if (str_starts_with($range, 'bytes=')) {
                    [$start, $end] = explode('-', substr($range, 6), 2) + [0];

                    $end = ('' === $end) ? $fileSize - 1 : (int) $end;

                    if ('' === $start) {
                        $start = $fileSize - $end;
                        $end = $fileSize - 1;
                    } else {
                        $start = (int) $start;
                    }

                    if ($start <= $end) {
                        $end = min($end, $fileSize - 1);
                        if ($start < 0 || $start > $end) {
                            $this->setStatusCode(416);
                            $this->headers->set('Content-Range', sprintf('bytes */%s', $fileSize));
                        } elseif ($end - $start < $fileSize - 1) {
                            $this->maxlen = $end < $fileSize ? $end - $start + 1 : -1;
                            $this->offset = $start;

                            $this->setStatusCode(206);
                            $this->headers->set('Content-Range', sprintf('bytes %s-%s/%s', $start, $end, $fileSize));
                            $this->headers->set('Content-Length', $end - $start + 1);
                        }
                    }
                }
            }
        }

        return $this;
    }

    private function hasValidIfRangeHeader(?string $header): bool
    {
        if ($this->getEtag() === $header) {
            return true;
        }

        if (null === $lastModified = $this->getLastModified()) {
            return false;
        }

        return $lastModified->format('D, d M Y H:i:s').' GMT' === $header;
    }

    /**
     * Sends the file.
     *
     * {@inheritdoc}
     */
    public function sendContent()
    {
        if (!$this->isSuccessful()) {
            return parent::sendContent();
        }

        if (0 === $this->maxlen) {
            return $this;
        }

        $out = fopen('php://output', 'w');
        $file = fopen($this->file->getPathname(), 'r');

        stream_copy_to_stream($file, $out, $this->maxlen, $this->offset);

        fclose($out);
        fclose($file);

        if ($this->deleteFileAfterSend && is_file($this->file->getPathname())) {
            unlink($this->file->getPathname());
        }

        return $this;
    }

    /**
     * {@inheritdoc}
     *
     * @throws \LogicException when the content is not null
     */
    public function setContent(?string $content)
    {
        if (null !== $content) {
            throw new \LogicException('The content cannot be set on a BinaryFileResponse instance.');
        }

        return $this;
    }

    /**
     * {@inheritdoc}
     */
    public function getContent()
    {
        return false;
    }

    /**
     * Trust X-Sendfile-Type header.
     */
    public static function trustXSendfileTypeHeader()
    {
        self::$trustXSendfileTypeHeader = true;
    }

    /**
     * If this is set to true, the file will be unlinked after the request is sent
     * Note: If the X-Sendfile header is used, the deleteFileAfterSend setting will not be used.
     *
     * @return $this
     */
    public function deleteFileAfterSend(bool $shouldDelete = true)
    {
        $this->deleteFileAfterSend = $shouldDelete;

        return $this;
    }
}
PKϤ$Zƅg�hh;http-foundation/Test/Constraint/ResponseCookieValueSame.phpnu�[���<?php

/*
 * This file is part of the Symfony package.
 *
 * (c) Fabien Potencier <fabien@symfony.com>
 *
 * For the full copyright and license information, please view the LICENSE
 * file that was distributed with this source code.
 */

namespace Symfony\Component\HttpFoundation\Test\Constraint;

use PHPUnit\Framework\Constraint\Constraint;
use Symfony\Component\HttpFoundation\Cookie;
use Symfony\Component\HttpFoundation\Response;

final class ResponseCookieValueSame extends Constraint
{
    private $name;
    private $value;
    private $path;
    private $domain;

    public function __construct(string $name, string $value, string $path = '/', string $domain = null)
    {
        $this->name = $name;
        $this->value = $value;
        $this->path = $path;
        $this->domain = $domain;
    }

    /**
     * {@inheritdoc}
     */
    public function toString(): string
    {
        $str = sprintf('has cookie "%s"', $this->name);
        if ('/' !== $this->path) {
            $str .= sprintf(' with path "%s"', $this->path);
        }
        if ($this->domain) {
            $str .= sprintf(' for domain "%s"', $this->domain);
        }
        $str .= sprintf(' with value "%s"', $this->value);

        return $str;
    }

    /**
     * @param Response $response
     *
     * {@inheritdoc}
     */
    protected function matches($response): bool
    {
        $cookie = $this->getCookie($response);
        if (!$cookie) {
            return false;
        }

        return $this->value === $cookie->getValue();
    }

    /**
     * @param Response $response
     *
     * {@inheritdoc}
     */
    protected function failureDescription($response): string
    {
        return 'the Response '.$this->toString();
    }

    protected function getCookie(Response $response): ?Cookie
    {
        $cookies = $response->headers->getCookies();

        $filteredCookies = array_filter($cookies, function (Cookie $cookie) {
            return $cookie->getName() === $this->name && $cookie->getPath() === $this->path && $cookie->getDomain() === $this->domain;
        });

        return reset($filteredCookies) ?: null;
    }
}
PKϤ$ZD�j�ww5http-foundation/Test/Constraint/ResponseHasCookie.phpnu�[���<?php

/*
 * This file is part of the Symfony package.
 *
 * (c) Fabien Potencier <fabien@symfony.com>
 *
 * For the full copyright and license information, please view the LICENSE
 * file that was distributed with this source code.
 */

namespace Symfony\Component\HttpFoundation\Test\Constraint;

use PHPUnit\Framework\Constraint\Constraint;
use Symfony\Component\HttpFoundation\Cookie;
use Symfony\Component\HttpFoundation\Response;

final class ResponseHasCookie extends Constraint
{
    private $name;
    private $path;
    private $domain;

    public function __construct(string $name, string $path = '/', string $domain = null)
    {
        $this->name = $name;
        $this->path = $path;
        $this->domain = $domain;
    }

    /**
     * {@inheritdoc}
     */
    public function toString(): string
    {
        $str = sprintf('has cookie "%s"', $this->name);
        if ('/' !== $this->path) {
            $str .= sprintf(' with path "%s"', $this->path);
        }
        if ($this->domain) {
            $str .= sprintf(' for domain "%s"', $this->domain);
        }

        return $str;
    }

    /**
     * @param Response $response
     *
     * {@inheritdoc}
     */
    protected function matches($response): bool
    {
        return null !== $this->getCookie($response);
    }

    /**
     * @param Response $response
     *
     * {@inheritdoc}
     */
    protected function failureDescription($response): string
    {
        return 'the Response '.$this->toString();
    }

    private function getCookie(Response $response): ?Cookie
    {
        $cookies = $response->headers->getCookies();

        $filteredCookies = array_filter($cookies, function (Cookie $cookie) {
            return $cookie->getName() === $this->name && $cookie->getPath() === $this->path && $cookie->getDomain() === $this->domain;
        });

        return reset($filteredCookies) ?: null;
    }
}
PKϤ$Z���l

6http-foundation/Test/Constraint/ResponseHeaderSame.phpnu�[���<?php

/*
 * This file is part of the Symfony package.
 *
 * (c) Fabien Potencier <fabien@symfony.com>
 *
 * For the full copyright and license information, please view the LICENSE
 * file that was distributed with this source code.
 */

namespace Symfony\Component\HttpFoundation\Test\Constraint;

use PHPUnit\Framework\Constraint\Constraint;
use Symfony\Component\HttpFoundation\Response;

final class ResponseHeaderSame extends Constraint
{
    private $headerName;
    private $expectedValue;

    public function __construct(string $headerName, string $expectedValue)
    {
        $this->headerName = $headerName;
        $this->expectedValue = $expectedValue;
    }

    /**
     * {@inheritdoc}
     */
    public function toString(): string
    {
        return sprintf('has header "%s" with value "%s"', $this->headerName, $this->expectedValue);
    }

    /**
     * @param Response $response
     *
     * {@inheritdoc}
     */
    protected function matches($response): bool
    {
        return $this->expectedValue === $response->headers->get($this->headerName, null);
    }

    /**
     * @param Response $response
     *
     * {@inheritdoc}
     */
    protected function failureDescription($response): string
    {
        return 'the Response '.$this->toString();
    }
}
PKϤ$Z�C�yy8http-foundation/Test/Constraint/ResponseIsSuccessful.phpnu�[���<?php

/*
 * This file is part of the Symfony package.
 *
 * (c) Fabien Potencier <fabien@symfony.com>
 *
 * For the full copyright and license information, please view the LICENSE
 * file that was distributed with this source code.
 */

namespace Symfony\Component\HttpFoundation\Test\Constraint;

use PHPUnit\Framework\Constraint\Constraint;
use Symfony\Component\HttpFoundation\Response;

final class ResponseIsSuccessful extends Constraint
{
    /**
     * {@inheritdoc}
     */
    public function toString(): string
    {
        return 'is successful';
    }

    /**
     * @param Response $response
     *
     * {@inheritdoc}
     */
    protected function matches($response): bool
    {
        return $response->isSuccessful();
    }

    /**
     * @param Response $response
     *
     * {@inheritdoc}
     */
    protected function failureDescription($response): string
    {
        return 'the Response '.$this->toString();
    }

    /**
     * @param Response $response
     *
     * {@inheritdoc}
     */
    protected function additionalFailureDescription($response): string
    {
        return (string) $response;
    }
}
PKϤ$Z0��'':http-foundation/Test/Constraint/ResponseStatusCodeSame.phpnu�[���<?php

/*
 * This file is part of the Symfony package.
 *
 * (c) Fabien Potencier <fabien@symfony.com>
 *
 * For the full copyright and license information, please view the LICENSE
 * file that was distributed with this source code.
 */

namespace Symfony\Component\HttpFoundation\Test\Constraint;

use PHPUnit\Framework\Constraint\Constraint;
use Symfony\Component\HttpFoundation\Response;

final class ResponseStatusCodeSame extends Constraint
{
    private $statusCode;

    public function __construct(int $statusCode)
    {
        $this->statusCode = $statusCode;
    }

    /**
     * {@inheritdoc}
     */
    public function toString(): string
    {
        return 'status code is '.$this->statusCode;
    }

    /**
     * @param Response $response
     *
     * {@inheritdoc}
     */
    protected function matches($response): bool
    {
        return $this->statusCode === $response->getStatusCode();
    }

    /**
     * @param Response $response
     *
     * {@inheritdoc}
     */
    protected function failureDescription($response): string
    {
        return 'the Response '.$this->toString();
    }

    /**
     * @param Response $response
     *
     * {@inheritdoc}
     */
    protected function additionalFailureDescription($response): string
    {
        return (string) $response;
    }
}
PKϤ$Z���|ee5http-foundation/Test/Constraint/ResponseHasHeader.phpnu�[���<?php

/*
 * This file is part of the Symfony package.
 *
 * (c) Fabien Potencier <fabien@symfony.com>
 *
 * For the full copyright and license information, please view the LICENSE
 * file that was distributed with this source code.
 */

namespace Symfony\Component\HttpFoundation\Test\Constraint;

use PHPUnit\Framework\Constraint\Constraint;
use Symfony\Component\HttpFoundation\Response;

final class ResponseHasHeader extends Constraint
{
    private $headerName;

    public function __construct(string $headerName)
    {
        $this->headerName = $headerName;
    }

    /**
     * {@inheritdoc}
     */
    public function toString(): string
    {
        return sprintf('has header "%s"', $this->headerName);
    }

    /**
     * @param Response $response
     *
     * {@inheritdoc}
     */
    protected function matches($response): bool
    {
        return $response->headers->has($this->headerName);
    }

    /**
     * @param Response $response
     *
     * {@inheritdoc}
     */
    protected function failureDescription($response): string
    {
        return 'the Response '.$this->toString();
    }
}
PKϤ$Z:O��%%6http-foundation/Test/Constraint/ResponseFormatSame.phpnu�[���<?php

/*
 * This file is part of the Symfony package.
 *
 * (c) Fabien Potencier <fabien@symfony.com>
 *
 * For the full copyright and license information, please view the LICENSE
 * file that was distributed with this source code.
 */

namespace Symfony\Component\HttpFoundation\Test\Constraint;

use PHPUnit\Framework\Constraint\Constraint;
use Symfony\Component\HttpFoundation\Request;
use Symfony\Component\HttpFoundation\Response;

/**
 * Asserts that the response is in the given format.
 *
 * @author Kévin Dunglas <dunglas@gmail.com>
 */
final class ResponseFormatSame extends Constraint
{
    private $request;
    private $format;

    public function __construct(Request $request, ?string $format)
    {
        $this->request = $request;
        $this->format = $format;
    }

    /**
     * {@inheritdoc}
     */
    public function toString(): string
    {
        return 'format is '.($this->format ?? 'null');
    }

    /**
     * @param Response $response
     *
     * {@inheritdoc}
     */
    protected function matches($response): bool
    {
        return $this->format === $this->request->getFormat($response->headers->get('Content-Type'));
    }

    /**
     * @param Response $response
     *
     * {@inheritdoc}
     */
    protected function failureDescription($response): string
    {
        return 'the Response '.$this->toString();
    }

    /**
     * @param Response $response
     *
     * {@inheritdoc}
     */
    protected function additionalFailureDescription($response): string
    {
        return (string) $response;
    }
}
PKϤ$Z�(1ww8http-foundation/Test/Constraint/ResponseIsRedirected.phpnu�[���<?php

/*
 * This file is part of the Symfony package.
 *
 * (c) Fabien Potencier <fabien@symfony.com>
 *
 * For the full copyright and license information, please view the LICENSE
 * file that was distributed with this source code.
 */

namespace Symfony\Component\HttpFoundation\Test\Constraint;

use PHPUnit\Framework\Constraint\Constraint;
use Symfony\Component\HttpFoundation\Response;

final class ResponseIsRedirected extends Constraint
{
    /**
     * {@inheritdoc}
     */
    public function toString(): string
    {
        return 'is redirected';
    }

    /**
     * @param Response $response
     *
     * {@inheritdoc}
     */
    protected function matches($response): bool
    {
        return $response->isRedirect();
    }

    /**
     * @param Response $response
     *
     * {@inheritdoc}
     */
    protected function failureDescription($response): string
    {
        return 'the Response '.$this->toString();
    }

    /**
     * @param Response $response
     *
     * {@inheritdoc}
     */
    protected function additionalFailureDescription($response): string
    {
        return (string) $response;
    }
}
PKϤ$ZO�\��=http-foundation/Test/Constraint/RequestAttributeValueSame.phpnu�[���<?php

/*
 * This file is part of the Symfony package.
 *
 * (c) Fabien Potencier <fabien@symfony.com>
 *
 * For the full copyright and license information, please view the LICENSE
 * file that was distributed with this source code.
 */

namespace Symfony\Component\HttpFoundation\Test\Constraint;

use PHPUnit\Framework\Constraint\Constraint;
use Symfony\Component\HttpFoundation\Request;

final class RequestAttributeValueSame extends Constraint
{
    private $name;
    private $value;

    public function __construct(string $name, string $value)
    {
        $this->name = $name;
        $this->value = $value;
    }

    /**
     * {@inheritdoc}
     */
    public function toString(): string
    {
        return sprintf('has attribute "%s" with value "%s"', $this->name, $this->value);
    }

    /**
     * @param Request $request
     *
     * {@inheritdoc}
     */
    protected function matches($request): bool
    {
        return $this->value === $request->attributes->get($this->name);
    }

    /**
     * @param Request $request
     *
     * {@inheritdoc}
     */
    protected function failureDescription($request): string
    {
        return 'the Request '.$this->toString();
    }
}
PKϤ$Z*��g"http-foundation/RequestMatcher.phpnu�[���<?php

/*
 * This file is part of the Symfony package.
 *
 * (c) Fabien Potencier <fabien@symfony.com>
 *
 * For the full copyright and license information, please view the LICENSE
 * file that was distributed with this source code.
 */

namespace Symfony\Component\HttpFoundation;

/**
 * RequestMatcher compares a pre-defined set of checks against a Request instance.
 *
 * @author Fabien Potencier <fabien@symfony.com>
 */
class RequestMatcher implements RequestMatcherInterface
{
    /**
     * @var string|null
     */
    private $path;

    /**
     * @var string|null
     */
    private $host;

    /**
     * @var int|null
     */
    private $port;

    /**
     * @var string[]
     */
    private $methods = [];

    /**
     * @var string[]
     */
    private $ips = [];

    /**
     * @var array
     */
    private $attributes = [];

    /**
     * @var string[]
     */
    private $schemes = [];

    /**
     * @param string|string[]|null $methods
     * @param string|string[]|null $ips
     * @param string|string[]|null $schemes
     */
    public function __construct(string $path = null, string $host = null, $methods = null, $ips = null, array $attributes = [], $schemes = null, int $port = null)
    {
        $this->matchPath($path);
        $this->matchHost($host);
        $this->matchMethod($methods);
        $this->matchIps($ips);
        $this->matchScheme($schemes);
        $this->matchPort($port);

        foreach ($attributes as $k => $v) {
            $this->matchAttribute($k, $v);
        }
    }

    /**
     * Adds a check for the HTTP scheme.
     *
     * @param string|string[]|null $scheme An HTTP scheme or an array of HTTP schemes
     */
    public function matchScheme($scheme)
    {
        $this->schemes = null !== $scheme ? array_map('strtolower', (array) $scheme) : [];
    }

    /**
     * Adds a check for the URL host name.
     */
    public function matchHost(?string $regexp)
    {
        $this->host = $regexp;
    }

    /**
     * Adds a check for the the URL port.
     *
     * @param int|null $port The port number to connect to
     */
    public function matchPort(?int $port)
    {
        $this->port = $port;
    }

    /**
     * Adds a check for the URL path info.
     */
    public function matchPath(?string $regexp)
    {
        $this->path = $regexp;
    }

    /**
     * Adds a check for the client IP.
     *
     * @param string $ip A specific IP address or a range specified using IP/netmask like 192.168.1.0/24
     */
    public function matchIp(string $ip)
    {
        $this->matchIps($ip);
    }

    /**
     * Adds a check for the client IP.
     *
     * @param string|string[]|null $ips A specific IP address or a range specified using IP/netmask like 192.168.1.0/24
     */
    public function matchIps($ips)
    {
        $ips = null !== $ips ? (array) $ips : [];

        $this->ips = array_reduce($ips, static function (array $ips, string $ip) {
            return array_merge($ips, preg_split('/\s*,\s*/', $ip));
        }, []);
    }

    /**
     * Adds a check for the HTTP method.
     *
     * @param string|string[]|null $method An HTTP method or an array of HTTP methods
     */
    public function matchMethod($method)
    {
        $this->methods = null !== $method ? array_map('strtoupper', (array) $method) : [];
    }

    /**
     * Adds a check for request attribute.
     */
    public function matchAttribute(string $key, string $regexp)
    {
        $this->attributes[$key] = $regexp;
    }

    /**
     * {@inheritdoc}
     */
    public function matches(Request $request)
    {
        if ($this->schemes && !\in_array($request->getScheme(), $this->schemes, true)) {
            return false;
        }

        if ($this->methods && !\in_array($request->getMethod(), $this->methods, true)) {
            return false;
        }

        foreach ($this->attributes as $key => $pattern) {
            $requestAttribute = $request->attributes->get($key);
            if (!\is_string($requestAttribute)) {
                return false;
            }
            if (!preg_match('{'.$pattern.'}', $requestAttribute)) {
                return false;
            }
        }

        if (null !== $this->path && !preg_match('{'.$this->path.'}', rawurldecode($request->getPathInfo()))) {
            return false;
        }

        if (null !== $this->host && !preg_match('{'.$this->host.'}i', $request->getHost())) {
            return false;
        }

        if (null !== $this->port && 0 < $this->port && $request->getPort() !== $this->port) {
            return false;
        }

        if (IpUtils::checkIp($request->getClientIp(), $this->ips)) {
            return true;
        }

        // Note to future implementors: add additional checks above the
        // foreach above or else your check might not be run!
        return 0 === \count($this->ips);
    }
}
PKϤ$Z�[Ū.�.�http-foundation/Response.phpnu�[���<?php

/*
 * This file is part of the Symfony package.
 *
 * (c) Fabien Potencier <fabien@symfony.com>
 *
 * For the full copyright and license information, please view the LICENSE
 * file that was distributed with this source code.
 */

namespace Symfony\Component\HttpFoundation;

// Help opcache.preload discover always-needed symbols
class_exists(ResponseHeaderBag::class);

/**
 * Response represents an HTTP response.
 *
 * @author Fabien Potencier <fabien@symfony.com>
 */
class Response
{
    public const HTTP_CONTINUE = 100;
    public const HTTP_SWITCHING_PROTOCOLS = 101;
    public const HTTP_PROCESSING = 102;            // RFC2518
    public const HTTP_EARLY_HINTS = 103;           // RFC8297
    public const HTTP_OK = 200;
    public const HTTP_CREATED = 201;
    public const HTTP_ACCEPTED = 202;
    public const HTTP_NON_AUTHORITATIVE_INFORMATION = 203;
    public const HTTP_NO_CONTENT = 204;
    public const HTTP_RESET_CONTENT = 205;
    public const HTTP_PARTIAL_CONTENT = 206;
    public const HTTP_MULTI_STATUS = 207;          // RFC4918
    public const HTTP_ALREADY_REPORTED = 208;      // RFC5842
    public const HTTP_IM_USED = 226;               // RFC3229
    public const HTTP_MULTIPLE_CHOICES = 300;
    public const HTTP_MOVED_PERMANENTLY = 301;
    public const HTTP_FOUND = 302;
    public const HTTP_SEE_OTHER = 303;
    public const HTTP_NOT_MODIFIED = 304;
    public const HTTP_USE_PROXY = 305;
    public const HTTP_RESERVED = 306;
    public const HTTP_TEMPORARY_REDIRECT = 307;
    public const HTTP_PERMANENTLY_REDIRECT = 308;  // RFC7238
    public const HTTP_BAD_REQUEST = 400;
    public const HTTP_UNAUTHORIZED = 401;
    public const HTTP_PAYMENT_REQUIRED = 402;
    public const HTTP_FORBIDDEN = 403;
    public const HTTP_NOT_FOUND = 404;
    public const HTTP_METHOD_NOT_ALLOWED = 405;
    public const HTTP_NOT_ACCEPTABLE = 406;
    public const HTTP_PROXY_AUTHENTICATION_REQUIRED = 407;
    public const HTTP_REQUEST_TIMEOUT = 408;
    public const HTTP_CONFLICT = 409;
    public const HTTP_GONE = 410;
    public const HTTP_LENGTH_REQUIRED = 411;
    public const HTTP_PRECONDITION_FAILED = 412;
    public const HTTP_REQUEST_ENTITY_TOO_LARGE = 413;
    public const HTTP_REQUEST_URI_TOO_LONG = 414;
    public const HTTP_UNSUPPORTED_MEDIA_TYPE = 415;
    public const HTTP_REQUESTED_RANGE_NOT_SATISFIABLE = 416;
    public const HTTP_EXPECTATION_FAILED = 417;
    public const HTTP_I_AM_A_TEAPOT = 418;                                               // RFC2324
    public const HTTP_MISDIRECTED_REQUEST = 421;                                         // RFC7540
    public const HTTP_UNPROCESSABLE_ENTITY = 422;                                        // RFC4918
    public const HTTP_LOCKED = 423;                                                      // RFC4918
    public const HTTP_FAILED_DEPENDENCY = 424;                                           // RFC4918
    public const HTTP_TOO_EARLY = 425;                                                   // RFC-ietf-httpbis-replay-04
    public const HTTP_UPGRADE_REQUIRED = 426;                                            // RFC2817
    public const HTTP_PRECONDITION_REQUIRED = 428;                                       // RFC6585
    public const HTTP_TOO_MANY_REQUESTS = 429;                                           // RFC6585
    public const HTTP_REQUEST_HEADER_FIELDS_TOO_LARGE = 431;                             // RFC6585
    public const HTTP_UNAVAILABLE_FOR_LEGAL_REASONS = 451;
    public const HTTP_INTERNAL_SERVER_ERROR = 500;
    public const HTTP_NOT_IMPLEMENTED = 501;
    public const HTTP_BAD_GATEWAY = 502;
    public const HTTP_SERVICE_UNAVAILABLE = 503;
    public const HTTP_GATEWAY_TIMEOUT = 504;
    public const HTTP_VERSION_NOT_SUPPORTED = 505;
    public const HTTP_VARIANT_ALSO_NEGOTIATES_EXPERIMENTAL = 506;                        // RFC2295
    public const HTTP_INSUFFICIENT_STORAGE = 507;                                        // RFC4918
    public const HTTP_LOOP_DETECTED = 508;                                               // RFC5842
    public const HTTP_NOT_EXTENDED = 510;                                                // RFC2774
    public const HTTP_NETWORK_AUTHENTICATION_REQUIRED = 511;                             // RFC6585

    /**
     * @see https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Cache-Control
     */
    private const HTTP_RESPONSE_CACHE_CONTROL_DIRECTIVES = [
        'must_revalidate' => false,
        'no_cache' => false,
        'no_store' => false,
        'no_transform' => false,
        'public' => false,
        'private' => false,
        'proxy_revalidate' => false,
        'max_age' => true,
        's_maxage' => true,
        'immutable' => false,
        'last_modified' => true,
        'etag' => true,
    ];

    /**
     * @var ResponseHeaderBag
     */
    public $headers;

    /**
     * @var string
     */
    protected $content;

    /**
     * @var string
     */
    protected $version;

    /**
     * @var int
     */
    protected $statusCode;

    /**
     * @var string
     */
    protected $statusText;

    /**
     * @var string
     */
    protected $charset;

    /**
     * Status codes translation table.
     *
     * The list of codes is complete according to the
     * {@link https://www.iana.org/assignments/http-status-codes/http-status-codes.xhtml Hypertext Transfer Protocol (HTTP) Status Code Registry}
     * (last updated 2016-03-01).
     *
     * Unless otherwise noted, the status code is defined in RFC2616.
     *
     * @var array
     */
    public static $statusTexts = [
        100 => 'Continue',
        101 => 'Switching Protocols',
        102 => 'Processing',            // RFC2518
        103 => 'Early Hints',
        200 => 'OK',
        201 => 'Created',
        202 => 'Accepted',
        203 => 'Non-Authoritative Information',
        204 => 'No Content',
        205 => 'Reset Content',
        206 => 'Partial Content',
        207 => 'Multi-Status',          // RFC4918
        208 => 'Already Reported',      // RFC5842
        226 => 'IM Used',               // RFC3229
        300 => 'Multiple Choices',
        301 => 'Moved Permanently',
        302 => 'Found',
        303 => 'See Other',
        304 => 'Not Modified',
        305 => 'Use Proxy',
        307 => 'Temporary Redirect',
        308 => 'Permanent Redirect',    // RFC7238
        400 => 'Bad Request',
        401 => 'Unauthorized',
        402 => 'Payment Required',
        403 => 'Forbidden',
        404 => 'Not Found',
        405 => 'Method Not Allowed',
        406 => 'Not Acceptable',
        407 => 'Proxy Authentication Required',
        408 => 'Request Timeout',
        409 => 'Conflict',
        410 => 'Gone',
        411 => 'Length Required',
        412 => 'Precondition Failed',
        413 => 'Payload Too Large',
        414 => 'URI Too Long',
        415 => 'Unsupported Media Type',
        416 => 'Range Not Satisfiable',
        417 => 'Expectation Failed',
        418 => 'I\'m a teapot',                                               // RFC2324
        421 => 'Misdirected Request',                                         // RFC7540
        422 => 'Unprocessable Entity',                                        // RFC4918
        423 => 'Locked',                                                      // RFC4918
        424 => 'Failed Dependency',                                           // RFC4918
        425 => 'Too Early',                                                   // RFC-ietf-httpbis-replay-04
        426 => 'Upgrade Required',                                            // RFC2817
        428 => 'Precondition Required',                                       // RFC6585
        429 => 'Too Many Requests',                                           // RFC6585
        431 => 'Request Header Fields Too Large',                             // RFC6585
        451 => 'Unavailable For Legal Reasons',                               // RFC7725
        500 => 'Internal Server Error',
        501 => 'Not Implemented',
        502 => 'Bad Gateway',
        503 => 'Service Unavailable',
        504 => 'Gateway Timeout',
        505 => 'HTTP Version Not Supported',
        506 => 'Variant Also Negotiates',                                     // RFC2295
        507 => 'Insufficient Storage',                                        // RFC4918
        508 => 'Loop Detected',                                               // RFC5842
        510 => 'Not Extended',                                                // RFC2774
        511 => 'Network Authentication Required',                             // RFC6585
    ];

    /**
     * @throws \InvalidArgumentException When the HTTP status code is not valid
     */
    public function __construct(?string $content = '', int $status = 200, array $headers = [])
    {
        $this->headers = new ResponseHeaderBag($headers);
        $this->setContent($content);
        $this->setStatusCode($status);
        $this->setProtocolVersion('1.0');
    }

    /**
     * Factory method for chainability.
     *
     * Example:
     *
     *     return Response::create($body, 200)
     *         ->setSharedMaxAge(300);
     *
     * @return static
     *
     * @deprecated since Symfony 5.1, use __construct() instead.
     */
    public static function create(?string $content = '', int $status = 200, array $headers = [])
    {
        trigger_deprecation('symfony/http-foundation', '5.1', 'The "%s()" method is deprecated, use "new %s()" instead.', __METHOD__, static::class);

        return new static($content, $status, $headers);
    }

    /**
     * Returns the Response as an HTTP string.
     *
     * The string representation of the Response is the same as the
     * one that will be sent to the client only if the prepare() method
     * has been called before.
     *
     * @return string The Response as an HTTP string
     *
     * @see prepare()
     */
    public function __toString()
    {
        return
            sprintf('HTTP/%s %s %s', $this->version, $this->statusCode, $this->statusText)."\r\n".
            $this->headers."\r\n".
            $this->getContent();
    }

    /**
     * Clones the current Response instance.
     */
    public function __clone()
    {
        $this->headers = clone $this->headers;
    }

    /**
     * Prepares the Response before it is sent to the client.
     *
     * This method tweaks the Response to ensure that it is
     * compliant with RFC 2616. Most of the changes are based on
     * the Request that is "associated" with this Response.
     *
     * @return $this
     */
    public function prepare(Request $request)
    {
        $headers = $this->headers;

        if ($this->isInformational() || $this->isEmpty()) {
            $this->setContent(null);
            $headers->remove('Content-Type');
            $headers->remove('Content-Length');
            // prevent PHP from sending the Content-Type header based on default_mimetype
            ini_set('default_mimetype', '');
        } else {
            // Content-type based on the Request
            if (!$headers->has('Content-Type')) {
                $format = $request->getRequestFormat(null);
                if (null !== $format && $mimeType = $request->getMimeType($format)) {
                    $headers->set('Content-Type', $mimeType);
                }
            }

            // Fix Content-Type
            $charset = $this->charset ?: 'UTF-8';
            if (!$headers->has('Content-Type')) {
                $headers->set('Content-Type', 'text/html; charset='.$charset);
            } elseif (0 === stripos($headers->get('Content-Type'), 'text/') && false === stripos($headers->get('Content-Type'), 'charset')) {
                // add the charset
                $headers->set('Content-Type', $headers->get('Content-Type').'; charset='.$charset);
            }

            // Fix Content-Length
            if ($headers->has('Transfer-Encoding')) {
                $headers->remove('Content-Length');
            }

            if ($request->isMethod('HEAD')) {
                // cf. RFC2616 14.13
                $length = $headers->get('Content-Length');
                $this->setContent(null);
                if ($length) {
                    $headers->set('Content-Length', $length);
                }
            }
        }

        // Fix protocol
        if ('HTTP/1.0' != $request->server->get('SERVER_PROTOCOL')) {
            $this->setProtocolVersion('1.1');
        }

        // Check if we need to send extra expire info headers
        if ('1.0' == $this->getProtocolVersion() && str_contains($headers->get('Cache-Control', ''), 'no-cache')) {
            $headers->set('pragma', 'no-cache');
            $headers->set('expires', -1);
        }

        $this->ensureIEOverSSLCompatibility($request);

        if ($request->isSecure()) {
            foreach ($headers->getCookies() as $cookie) {
                $cookie->setSecureDefault(true);
            }
        }

        return $this;
    }

    /**
     * Sends HTTP headers.
     *
     * @return $this
     */
    public function sendHeaders()
    {
        // headers have already been sent by the developer
        if (headers_sent()) {
            return $this;
        }

        // headers
        foreach ($this->headers->allPreserveCaseWithoutCookies() as $name => $values) {
            $replace = 0 === strcasecmp($name, 'Content-Type');
            foreach ($values as $value) {
                header($name.': '.$value, $replace, $this->statusCode);
            }
        }

        // cookies
        foreach ($this->headers->getCookies() as $cookie) {
            header('Set-Cookie: '.$cookie, false, $this->statusCode);
        }

        // status
        header(sprintf('HTTP/%s %s %s', $this->version, $this->statusCode, $this->statusText), true, $this->statusCode);

        return $this;
    }

    /**
     * Sends content for the current web response.
     *
     * @return $this
     */
    public function sendContent()
    {
        echo $this->content;

        return $this;
    }

    /**
     * Sends HTTP headers and content.
     *
     * @return $this
     */
    public function send()
    {
        $this->sendHeaders();
        $this->sendContent();

        if (\function_exists('fastcgi_finish_request')) {
            fastcgi_finish_request();
        } elseif (!\in_array(\PHP_SAPI, ['cli', 'phpdbg'], true)) {
            static::closeOutputBuffers(0, true);
        }

        return $this;
    }

    /**
     * Sets the response content.
     *
     * @return $this
     *
     * @throws \UnexpectedValueException
     */
    public function setContent(?string $content)
    {
        $this->content = $content ?? '';

        return $this;
    }

    /**
     * Gets the current response content.
     *
     * @return string|false
     */
    public function getContent()
    {
        return $this->content;
    }

    /**
     * Sets the HTTP protocol version (1.0 or 1.1).
     *
     * @return $this
     *
     * @final
     */
    public function setProtocolVersion(string $version): object
    {
        $this->version = $version;

        return $this;
    }

    /**
     * Gets the HTTP protocol version.
     *
     * @final
     */
    public function getProtocolVersion(): string
    {
        return $this->version;
    }

    /**
     * Sets the response status code.
     *
     * If the status text is null it will be automatically populated for the known
     * status codes and left empty otherwise.
     *
     * @return $this
     *
     * @throws \InvalidArgumentException When the HTTP status code is not valid
     *
     * @final
     */
    public function setStatusCode(int $code, string $text = null): object
    {
        $this->statusCode = $code;
        if ($this->isInvalid()) {
            throw new \InvalidArgumentException(sprintf('The HTTP status code "%s" is not valid.', $code));
        }

        if (null === $text) {
            $this->statusText = self::$statusTexts[$code] ?? 'unknown status';

            return $this;
        }

        if (false === $text) {
            $this->statusText = '';

            return $this;
        }

        $this->statusText = $text;

        return $this;
    }

    /**
     * Retrieves the status code for the current web response.
     *
     * @final
     */
    public function getStatusCode(): int
    {
        return $this->statusCode;
    }

    /**
     * Sets the response charset.
     *
     * @return $this
     *
     * @final
     */
    public function setCharset(string $charset): object
    {
        $this->charset = $charset;

        return $this;
    }

    /**
     * Retrieves the response charset.
     *
     * @final
     */
    public function getCharset(): ?string
    {
        return $this->charset;
    }

    /**
     * Returns true if the response may safely be kept in a shared (surrogate) cache.
     *
     * Responses marked "private" with an explicit Cache-Control directive are
     * considered uncacheable.
     *
     * Responses with neither a freshness lifetime (Expires, max-age) nor cache
     * validator (Last-Modified, ETag) are considered uncacheable because there is
     * no way to tell when or how to remove them from the cache.
     *
     * Note that RFC 7231 and RFC 7234 possibly allow for a more permissive implementation,
     * for example "status codes that are defined as cacheable by default [...]
     * can be reused by a cache with heuristic expiration unless otherwise indicated"
     * (https://tools.ietf.org/html/rfc7231#section-6.1)
     *
     * @final
     */
    public function isCacheable(): bool
    {
        if (!\in_array($this->statusCode, [200, 203, 300, 301, 302, 404, 410])) {
            return false;
        }

        if ($this->headers->hasCacheControlDirective('no-store') || $this->headers->getCacheControlDirective('private')) {
            return false;
        }

        return $this->isValidateable() || $this->isFresh();
    }

    /**
     * Returns true if the response is "fresh".
     *
     * Fresh responses may be served from cache without any interaction with the
     * origin. A response is considered fresh when it includes a Cache-Control/max-age
     * indicator or Expires header and the calculated age is less than the freshness lifetime.
     *
     * @final
     */
    public function isFresh(): bool
    {
        return $this->getTtl() > 0;
    }

    /**
     * Returns true if the response includes headers that can be used to validate
     * the response with the origin server using a conditional GET request.
     *
     * @final
     */
    public function isValidateable(): bool
    {
        return $this->headers->has('Last-Modified') || $this->headers->has('ETag');
    }

    /**
     * Marks the response as "private".
     *
     * It makes the response ineligible for serving other clients.
     *
     * @return $this
     *
     * @final
     */
    public function setPrivate(): object
    {
        $this->headers->removeCacheControlDirective('public');
        $this->headers->addCacheControlDirective('private');

        return $this;
    }

    /**
     * Marks the response as "public".
     *
     * It makes the response eligible for serving other clients.
     *
     * @return $this
     *
     * @final
     */
    public function setPublic(): object
    {
        $this->headers->addCacheControlDirective('public');
        $this->headers->removeCacheControlDirective('private');

        return $this;
    }

    /**
     * Marks the response as "immutable".
     *
     * @return $this
     *
     * @final
     */
    public function setImmutable(bool $immutable = true): object
    {
        if ($immutable) {
            $this->headers->addCacheControlDirective('immutable');
        } else {
            $this->headers->removeCacheControlDirective('immutable');
        }

        return $this;
    }

    /**
     * Returns true if the response is marked as "immutable".
     *
     * @final
     */
    public function isImmutable(): bool
    {
        return $this->headers->hasCacheControlDirective('immutable');
    }

    /**
     * Returns true if the response must be revalidated by shared caches once it has become stale.
     *
     * This method indicates that the response must not be served stale by a
     * cache in any circumstance without first revalidating with the origin.
     * When present, the TTL of the response should not be overridden to be
     * greater than the value provided by the origin.
     *
     * @final
     */
    public function mustRevalidate(): bool
    {
        return $this->headers->hasCacheControlDirective('must-revalidate') || $this->headers->hasCacheControlDirective('proxy-revalidate');
    }

    /**
     * Returns the Date header as a DateTime instance.
     *
     * @throws \RuntimeException When the header is not parseable
     *
     * @final
     */
    public function getDate(): ?\DateTimeInterface
    {
        return $this->headers->getDate('Date');
    }

    /**
     * Sets the Date header.
     *
     * @return $this
     *
     * @final
     */
    public function setDate(\DateTimeInterface $date): object
    {
        if ($date instanceof \DateTime) {
            $date = \DateTimeImmutable::createFromMutable($date);
        }

        $date = $date->setTimezone(new \DateTimeZone('UTC'));
        $this->headers->set('Date', $date->format('D, d M Y H:i:s').' GMT');

        return $this;
    }

    /**
     * Returns the age of the response in seconds.
     *
     * @final
     */
    public function getAge(): int
    {
        if (null !== $age = $this->headers->get('Age')) {
            return (int) $age;
        }

        return max(time() - (int) $this->getDate()->format('U'), 0);
    }

    /**
     * Marks the response stale by setting the Age header to be equal to the maximum age of the response.
     *
     * @return $this
     */
    public function expire()
    {
        if ($this->isFresh()) {
            $this->headers->set('Age', $this->getMaxAge());
            $this->headers->remove('Expires');
        }

        return $this;
    }

    /**
     * Returns the value of the Expires header as a DateTime instance.
     *
     * @final
     */
    public function getExpires(): ?\DateTimeInterface
    {
        try {
            return $this->headers->getDate('Expires');
        } catch (\RuntimeException $e) {
            // according to RFC 2616 invalid date formats (e.g. "0" and "-1") must be treated as in the past
            return \DateTime::createFromFormat('U', time() - 172800);
        }
    }

    /**
     * Sets the Expires HTTP header with a DateTime instance.
     *
     * Passing null as value will remove the header.
     *
     * @return $this
     *
     * @final
     */
    public function setExpires(\DateTimeInterface $date = null): object
    {
        if (null === $date) {
            $this->headers->remove('Expires');

            return $this;
        }

        if ($date instanceof \DateTime) {
            $date = \DateTimeImmutable::createFromMutable($date);
        }

        $date = $date->setTimezone(new \DateTimeZone('UTC'));
        $this->headers->set('Expires', $date->format('D, d M Y H:i:s').' GMT');

        return $this;
    }

    /**
     * Returns the number of seconds after the time specified in the response's Date
     * header when the response should no longer be considered fresh.
     *
     * First, it checks for a s-maxage directive, then a max-age directive, and then it falls
     * back on an expires header. It returns null when no maximum age can be established.
     *
     * @final
     */
    public function getMaxAge(): ?int
    {
        if ($this->headers->hasCacheControlDirective('s-maxage')) {
            return (int) $this->headers->getCacheControlDirective('s-maxage');
        }

        if ($this->headers->hasCacheControlDirective('max-age')) {
            return (int) $this->headers->getCacheControlDirective('max-age');
        }

        if (null !== $this->getExpires()) {
            return (int) $this->getExpires()->format('U') - (int) $this->getDate()->format('U');
        }

        return null;
    }

    /**
     * Sets the number of seconds after which the response should no longer be considered fresh.
     *
     * This methods sets the Cache-Control max-age directive.
     *
     * @return $this
     *
     * @final
     */
    public function setMaxAge(int $value): object
    {
        $this->headers->addCacheControlDirective('max-age', $value);

        return $this;
    }

    /**
     * Sets the number of seconds after which the response should no longer be considered fresh by shared caches.
     *
     * This methods sets the Cache-Control s-maxage directive.
     *
     * @return $this
     *
     * @final
     */
    public function setSharedMaxAge(int $value): object
    {
        $this->setPublic();
        $this->headers->addCacheControlDirective('s-maxage', $value);

        return $this;
    }

    /**
     * Returns the response's time-to-live in seconds.
     *
     * It returns null when no freshness information is present in the response.
     *
     * When the responses TTL is <= 0, the response may not be served from cache without first
     * revalidating with the origin.
     *
     * @final
     */
    public function getTtl(): ?int
    {
        $maxAge = $this->getMaxAge();

        return null !== $maxAge ? $maxAge - $this->getAge() : null;
    }

    /**
     * Sets the response's time-to-live for shared caches in seconds.
     *
     * This method adjusts the Cache-Control/s-maxage directive.
     *
     * @return $this
     *
     * @final
     */
    public function setTtl(int $seconds): object
    {
        $this->setSharedMaxAge($this->getAge() + $seconds);

        return $this;
    }

    /**
     * Sets the response's time-to-live for private/client caches in seconds.
     *
     * This method adjusts the Cache-Control/max-age directive.
     *
     * @return $this
     *
     * @final
     */
    public function setClientTtl(int $seconds): object
    {
        $this->setMaxAge($this->getAge() + $seconds);

        return $this;
    }

    /**
     * Returns the Last-Modified HTTP header as a DateTime instance.
     *
     * @throws \RuntimeException When the HTTP header is not parseable
     *
     * @final
     */
    public function getLastModified(): ?\DateTimeInterface
    {
        return $this->headers->getDate('Last-Modified');
    }

    /**
     * Sets the Last-Modified HTTP header with a DateTime instance.
     *
     * Passing null as value will remove the header.
     *
     * @return $this
     *
     * @final
     */
    public function setLastModified(\DateTimeInterface $date = null): object
    {
        if (null === $date) {
            $this->headers->remove('Last-Modified');

            return $this;
        }

        if ($date instanceof \DateTime) {
            $date = \DateTimeImmutable::createFromMutable($date);
        }

        $date = $date->setTimezone(new \DateTimeZone('UTC'));
        $this->headers->set('Last-Modified', $date->format('D, d M Y H:i:s').' GMT');

        return $this;
    }

    /**
     * Returns the literal value of the ETag HTTP header.
     *
     * @final
     */
    public function getEtag(): ?string
    {
        return $this->headers->get('ETag');
    }

    /**
     * Sets the ETag value.
     *
     * @param string|null $etag The ETag unique identifier or null to remove the header
     * @param bool        $weak Whether you want a weak ETag or not
     *
     * @return $this
     *
     * @final
     */
    public function setEtag(string $etag = null, bool $weak = false): object
    {
        if (null === $etag) {
            $this->headers->remove('Etag');
        } else {
            if (!str_starts_with($etag, '"')) {
                $etag = '"'.$etag.'"';
            }

            $this->headers->set('ETag', (true === $weak ? 'W/' : '').$etag);
        }

        return $this;
    }

    /**
     * Sets the response's cache headers (validation and/or expiration).
     *
     * Available options are: must_revalidate, no_cache, no_store, no_transform, public, private, proxy_revalidate, max_age, s_maxage, immutable, last_modified and etag.
     *
     * @return $this
     *
     * @throws \InvalidArgumentException
     *
     * @final
     */
    public function setCache(array $options): object
    {
        if ($diff = array_diff(array_keys($options), array_keys(self::HTTP_RESPONSE_CACHE_CONTROL_DIRECTIVES))) {
            throw new \InvalidArgumentException(sprintf('Response does not support the following options: "%s".', implode('", "', $diff)));
        }

        if (isset($options['etag'])) {
            $this->setEtag($options['etag']);
        }

        if (isset($options['last_modified'])) {
            $this->setLastModified($options['last_modified']);
        }

        if (isset($options['max_age'])) {
            $this->setMaxAge($options['max_age']);
        }

        if (isset($options['s_maxage'])) {
            $this->setSharedMaxAge($options['s_maxage']);
        }

        foreach (self::HTTP_RESPONSE_CACHE_CONTROL_DIRECTIVES as $directive => $hasValue) {
            if (!$hasValue && isset($options[$directive])) {
                if ($options[$directive]) {
                    $this->headers->addCacheControlDirective(str_replace('_', '-', $directive));
                } else {
                    $this->headers->removeCacheControlDirective(str_replace('_', '-', $directive));
                }
            }
        }

        if (isset($options['public'])) {
            if ($options['public']) {
                $this->setPublic();
            } else {
                $this->setPrivate();
            }
        }

        if (isset($options['private'])) {
            if ($options['private']) {
                $this->setPrivate();
            } else {
                $this->setPublic();
            }
        }

        return $this;
    }

    /**
     * Modifies the response so that it conforms to the rules defined for a 304 status code.
     *
     * This sets the status, removes the body, and discards any headers
     * that MUST NOT be included in 304 responses.
     *
     * @return $this
     *
     * @see https://tools.ietf.org/html/rfc2616#section-10.3.5
     *
     * @final
     */
    public function setNotModified(): object
    {
        $this->setStatusCode(304);
        $this->setContent(null);

        // remove headers that MUST NOT be included with 304 Not Modified responses
        foreach (['Allow', 'Content-Encoding', 'Content-Language', 'Content-Length', 'Content-MD5', 'Content-Type', 'Last-Modified'] as $header) {
            $this->headers->remove($header);
        }

        return $this;
    }

    /**
     * Returns true if the response includes a Vary header.
     *
     * @final
     */
    public function hasVary(): bool
    {
        return null !== $this->headers->get('Vary');
    }

    /**
     * Returns an array of header names given in the Vary header.
     *
     * @final
     */
    public function getVary(): array
    {
        if (!$vary = $this->headers->all('Vary')) {
            return [];
        }

        $ret = [];
        foreach ($vary as $item) {
            $ret = array_merge($ret, preg_split('/[\s,]+/', $item));
        }

        return $ret;
    }

    /**
     * Sets the Vary header.
     *
     * @param string|array $headers
     * @param bool         $replace Whether to replace the actual value or not (true by default)
     *
     * @return $this
     *
     * @final
     */
    public function setVary($headers, bool $replace = true): object
    {
        $this->headers->set('Vary', $headers, $replace);

        return $this;
    }

    /**
     * Determines if the Response validators (ETag, Last-Modified) match
     * a conditional value specified in the Request.
     *
     * If the Response is not modified, it sets the status code to 304 and
     * removes the actual content by calling the setNotModified() method.
     *
     * @return bool true if the Response validators match the Request, false otherwise
     *
     * @final
     */
    public function isNotModified(Request $request): bool
    {
        if (!$request->isMethodCacheable()) {
            return false;
        }

        $notModified = false;
        $lastModified = $this->headers->get('Last-Modified');
        $modifiedSince = $request->headers->get('If-Modified-Since');

        if ($ifNoneMatchEtags = $request->getETags()) {
            $etag = $this->getEtag();
            if (0 == strncmp($etag, 'W/', 2)) {
                $etag = substr($etag, 2);
            }

            // Use weak comparison as per https://tools.ietf.org/html/rfc7232#section-3.2.
            foreach ($ifNoneMatchEtags as $ifNoneMatchEtag) {
                if (0 == strncmp($ifNoneMatchEtag, 'W/', 2)) {
                    $ifNoneMatchEtag = substr($ifNoneMatchEtag, 2);
                }

                if ($ifNoneMatchEtag === $etag || '*' === $ifNoneMatchEtag) {
                    $notModified = true;
                    break;
                }
            }
        }
        // Only do If-Modified-Since date comparison when If-None-Match is not present as per https://tools.ietf.org/html/rfc7232#section-3.3.
        elseif ($modifiedSince && $lastModified) {
            $notModified = strtotime($modifiedSince) >= strtotime($lastModified);
        }

        if ($notModified) {
            $this->setNotModified();
        }

        return $notModified;
    }

    /**
     * Is response invalid?
     *
     * @see https://www.w3.org/Protocols/rfc2616/rfc2616-sec10.html
     *
     * @final
     */
    public function isInvalid(): bool
    {
        return $this->statusCode < 100 || $this->statusCode >= 600;
    }

    /**
     * Is response informative?
     *
     * @final
     */
    public function isInformational(): bool
    {
        return $this->statusCode >= 100 && $this->statusCode < 200;
    }

    /**
     * Is response successful?
     *
     * @final
     */
    public function isSuccessful(): bool
    {
        return $this->statusCode >= 200 && $this->statusCode < 300;
    }

    /**
     * Is the response a redirect?
     *
     * @final
     */
    public function isRedirection(): bool
    {
        return $this->statusCode >= 300 && $this->statusCode < 400;
    }

    /**
     * Is there a client error?
     *
     * @final
     */
    public function isClientError(): bool
    {
        return $this->statusCode >= 400 && $this->statusCode < 500;
    }

    /**
     * Was there a server side error?
     *
     * @final
     */
    public function isServerError(): bool
    {
        return $this->statusCode >= 500 && $this->statusCode < 600;
    }

    /**
     * Is the response OK?
     *
     * @final
     */
    public function isOk(): bool
    {
        return 200 === $this->statusCode;
    }

    /**
     * Is the response forbidden?
     *
     * @final
     */
    public function isForbidden(): bool
    {
        return 403 === $this->statusCode;
    }

    /**
     * Is the response a not found error?
     *
     * @final
     */
    public function isNotFound(): bool
    {
        return 404 === $this->statusCode;
    }

    /**
     * Is the response a redirect of some form?
     *
     * @final
     */
    public function isRedirect(string $location = null): bool
    {
        return \in_array($this->statusCode, [201, 301, 302, 303, 307, 308]) && (null === $location ?: $location == $this->headers->get('Location'));
    }

    /**
     * Is the response empty?
     *
     * @final
     */
    public function isEmpty(): bool
    {
        return \in_array($this->statusCode, [204, 304]);
    }

    /**
     * Cleans or flushes output buffers up to target level.
     *
     * Resulting level can be greater than target level if a non-removable buffer has been encountered.
     *
     * @final
     */
    public static function closeOutputBuffers(int $targetLevel, bool $flush): void
    {
        $status = ob_get_status(true);
        $level = \count($status);
        $flags = \PHP_OUTPUT_HANDLER_REMOVABLE | ($flush ? \PHP_OUTPUT_HANDLER_FLUSHABLE : \PHP_OUTPUT_HANDLER_CLEANABLE);

        while ($level-- > $targetLevel && ($s = $status[$level]) && (!isset($s['del']) ? !isset($s['flags']) || ($s['flags'] & $flags) === $flags : $s['del'])) {
            if ($flush) {
                ob_end_flush();
            } else {
                ob_end_clean();
            }
        }
    }

    /**
     * Marks a response as safe according to RFC8674.
     *
     * @see https://tools.ietf.org/html/rfc8674
     */
    public function setContentSafe(bool $safe = true): void
    {
        if ($safe) {
            $this->headers->set('Preference-Applied', 'safe');
        } elseif ('safe' === $this->headers->get('Preference-Applied')) {
            $this->headers->remove('Preference-Applied');
        }

        $this->setVary('Prefer', false);
    }

    /**
     * Checks if we need to remove Cache-Control for SSL encrypted downloads when using IE < 9.
     *
     * @see http://support.microsoft.com/kb/323308
     *
     * @final
     */
    protected function ensureIEOverSSLCompatibility(Request $request): void
    {
        if (false !== stripos($this->headers->get('Content-Disposition') ?? '', 'attachment') && 1 == preg_match('/MSIE (.*?);/i', $request->server->get('HTTP_USER_AGENT') ?? '', $match) && true === $request->isSecure()) {
            if ((int) preg_replace('/(MSIE )(.*?);/', '$2', $match[0]) < 9) {
                $this->headers->remove('Cache-Control');
            }
        }
    }
}
PKϤ$Z�&��http-foundation/README.mdnu�[���HttpFoundation Component
========================

The HttpFoundation component defines an object-oriented layer for the HTTP
specification.

Resources
---------

 * [Documentation](https://symfony.com/doc/current/components/http_foundation.html)
 * [Contributing](https://symfony.com/doc/current/contributing/index.html)
 * [Report issues](https://github.com/symfony/symfony/issues) and
   [send Pull Requests](https://github.com/symfony/symfony/pulls)
   in the [main Symfony repository](https://github.com/symfony/symfony)
PKϤ$Z@g�{rr:http-foundation/RateLimiter/AbstractRequestRateLimiter.phpnu�[���<?php

/*
 * This file is part of the Symfony package.
 *
 * (c) Fabien Potencier <fabien@symfony.com>
 *
 * For the full copyright and license information, please view the LICENSE
 * file that was distributed with this source code.
 */

namespace Symfony\Component\HttpFoundation\RateLimiter;

use Symfony\Component\HttpFoundation\Request;
use Symfony\Component\RateLimiter\LimiterInterface;
use Symfony\Component\RateLimiter\Policy\NoLimiter;
use Symfony\Component\RateLimiter\RateLimit;

/**
 * An implementation of RequestRateLimiterInterface that
 * fits most use-cases.
 *
 * @author Wouter de Jong <wouter@wouterj.nl>
 *
 * @experimental in 5.3
 */
abstract class AbstractRequestRateLimiter implements RequestRateLimiterInterface
{
    public function consume(Request $request): RateLimit
    {
        $limiters = $this->getLimiters($request);
        if (0 === \count($limiters)) {
            $limiters = [new NoLimiter()];
        }

        $minimalRateLimit = null;
        foreach ($limiters as $limiter) {
            $rateLimit = $limiter->consume(1);

            if (null === $minimalRateLimit || $rateLimit->getRemainingTokens() < $minimalRateLimit->getRemainingTokens()) {
                $minimalRateLimit = $rateLimit;
            }
        }

        return $minimalRateLimit;
    }

    public function reset(Request $request): void
    {
        foreach ($this->getLimiters($request) as $limiter) {
            $limiter->reset();
        }
    }

    /**
     * @return LimiterInterface[] a set of limiters using keys extracted from the request
     */
    abstract protected function getLimiters(Request $request): array;
}
PKϤ$Z�_uI��;http-foundation/RateLimiter/RequestRateLimiterInterface.phpnu�[���<?php

/*
 * This file is part of the Symfony package.
 *
 * (c) Fabien Potencier <fabien@symfony.com>
 *
 * For the full copyright and license information, please view the LICENSE
 * file that was distributed with this source code.
 */

namespace Symfony\Component\HttpFoundation\RateLimiter;

use Symfony\Component\HttpFoundation\Request;
use Symfony\Component\RateLimiter\RateLimit;

/**
 * A special type of limiter that deals with requests.
 *
 * This allows to limit on different types of information
 * from the requests.
 *
 * @author Wouter de Jong <wouter@wouterj.nl>
 *
 * @experimental in 5.3
 */
interface RequestRateLimiterInterface
{
    public function consume(Request $request): RateLimit;

    public function reset(Request $request): void;
}
PKϤ$ZfL5�((http-foundation/InputBag.phpnu�[���<?php

/*
 * This file is part of the Symfony package.
 *
 * (c) Fabien Potencier <fabien@symfony.com>
 *
 * For the full copyright and license information, please view the LICENSE
 * file that was distributed with this source code.
 */

namespace Symfony\Component\HttpFoundation;

use Symfony\Component\HttpFoundation\Exception\BadRequestException;

/**
 * InputBag is a container for user input values such as $_GET, $_POST, $_REQUEST, and $_COOKIE.
 *
 * @author Saif Eddin Gmati <azjezz@protonmail.com>
 */
final class InputBag extends ParameterBag
{
    /**
     * Returns a scalar input value by name.
     *
     * @param string|int|float|bool|null $default The default value if the input key does not exist
     *
     * @return string|int|float|bool|null
     */
    public function get(string $key, $default = null)
    {
        if (null !== $default && !is_scalar($default) && !(\is_object($default) && method_exists($default, '__toString'))) {
            trigger_deprecation('symfony/http-foundation', '5.1', 'Passing a non-scalar value as 2nd argument to "%s()" is deprecated, pass a scalar or null instead.', __METHOD__);
        }

        $value = parent::get($key, $this);

        if (null !== $value && $this !== $value && !is_scalar($value) && !(\is_object($value) && method_exists($value, '__toString'))) {
            trigger_deprecation('symfony/http-foundation', '5.1', 'Retrieving a non-string value from "%s()" is deprecated, and will throw a "%s" exception in Symfony 6.0, use "%s::all($key)" instead.', __METHOD__, BadRequestException::class, __CLASS__);
        }

        return $this === $value ? $default : $value;
    }

    /**
     * {@inheritdoc}
     */
    public function all(string $key = null): array
    {
        return parent::all($key);
    }

    /**
     * Replaces the current input values by a new set.
     */
    public function replace(array $inputs = [])
    {
        $this->parameters = [];
        $this->add($inputs);
    }

    /**
     * Adds input values.
     */
    public function add(array $inputs = [])
    {
        foreach ($inputs as $input => $value) {
            $this->set($input, $value);
        }
    }

    /**
     * Sets an input by name.
     *
     * @param string|int|float|bool|array|null $value
     */
    public function set(string $key, $value)
    {
        if (null !== $value && !is_scalar($value) && !\is_array($value) && !method_exists($value, '__toString')) {
            trigger_deprecation('symfony/http-foundation', '5.1', 'Passing "%s" as a 2nd Argument to "%s()" is deprecated, pass a scalar, array, or null instead.', get_debug_type($value), __METHOD__);
        }

        $this->parameters[$key] = $value;
    }

    /**
     * {@inheritdoc}
     */
    public function filter(string $key, $default = null, int $filter = \FILTER_DEFAULT, $options = [])
    {
        $value = $this->has($key) ? $this->all()[$key] : $default;

        // Always turn $options into an array - this allows filter_var option shortcuts.
        if (!\is_array($options) && $options) {
            $options = ['flags' => $options];
        }

        if (\is_array($value) && !(($options['flags'] ?? 0) & (\FILTER_REQUIRE_ARRAY | \FILTER_FORCE_ARRAY))) {
            trigger_deprecation('symfony/http-foundation', '5.1', 'Filtering an array value with "%s()" without passing the FILTER_REQUIRE_ARRAY or FILTER_FORCE_ARRAY flag is deprecated', __METHOD__);

            if (!isset($options['flags'])) {
                $options['flags'] = \FILTER_REQUIRE_ARRAY;
            }
        }

        if ((\FILTER_CALLBACK & $filter) && !(($options['options'] ?? null) instanceof \Closure)) {
            trigger_deprecation('symfony/http-foundation', '5.2', 'Not passing a Closure together with FILTER_CALLBACK to "%s()" is deprecated. Wrap your filter in a closure instead.', __METHOD__);
            // throw new \InvalidArgumentException(sprintf('A Closure must be passed to "%s()" when FILTER_CALLBACK is used, "%s" given.', __METHOD__, get_debug_type($options['options'] ?? null)));
        }

        return filter_var($value, $filter, $options);
    }
}
PKϤ$Z ����+http-foundation/RequestMatcherInterface.phpnu�[���<?php

/*
 * This file is part of the Symfony package.
 *
 * (c) Fabien Potencier <fabien@symfony.com>
 *
 * For the full copyright and license information, please view the LICENSE
 * file that was distributed with this source code.
 */

namespace Symfony\Component\HttpFoundation;

/**
 * RequestMatcherInterface is an interface for strategies to match a Request.
 *
 * @author Fabien Potencier <fabien@symfony.com>
 */
interface RequestMatcherInterface
{
    /**
     * Decides whether the rule(s) implemented by the strategy matches the supplied request.
     *
     * @return bool true if the request matches, false otherwise
     */
    public function matches(Request $request);
}
PKϤ$Z�5���http-foundation/FileBag.phpnu�[���<?php

/*
 * This file is part of the Symfony package.
 *
 * (c) Fabien Potencier <fabien@symfony.com>
 *
 * For the full copyright and license information, please view the LICENSE
 * file that was distributed with this source code.
 */

namespace Symfony\Component\HttpFoundation;

use Symfony\Component\HttpFoundation\File\UploadedFile;

/**
 * FileBag is a container for uploaded files.
 *
 * @author Fabien Potencier <fabien@symfony.com>
 * @author Bulat Shakirzyanov <mallluhuct@gmail.com>
 */
class FileBag extends ParameterBag
{
    private const FILE_KEYS = ['error', 'name', 'size', 'tmp_name', 'type'];

    /**
     * @param array|UploadedFile[] $parameters An array of HTTP files
     */
    public function __construct(array $parameters = [])
    {
        $this->replace($parameters);
    }

    /**
     * {@inheritdoc}
     */
    public function replace(array $files = [])
    {
        $this->parameters = [];
        $this->add($files);
    }

    /**
     * {@inheritdoc}
     */
    public function set(string $key, $value)
    {
        if (!\is_array($value) && !$value instanceof UploadedFile) {
            throw new \InvalidArgumentException('An uploaded file must be an array or an instance of UploadedFile.');
        }

        parent::set($key, $this->convertFileInformation($value));
    }

    /**
     * {@inheritdoc}
     */
    public function add(array $files = [])
    {
        foreach ($files as $key => $file) {
            $this->set($key, $file);
        }
    }

    /**
     * Converts uploaded files to UploadedFile instances.
     *
     * @param array|UploadedFile $file A (multi-dimensional) array of uploaded file information
     *
     * @return UploadedFile[]|UploadedFile|null A (multi-dimensional) array of UploadedFile instances
     */
    protected function convertFileInformation($file)
    {
        if ($file instanceof UploadedFile) {
            return $file;
        }

        $file = $this->fixPhpFilesArray($file);
        $keys = array_keys($file);
        sort($keys);

        if (self::FILE_KEYS == $keys) {
            if (\UPLOAD_ERR_NO_FILE == $file['error']) {
                $file = null;
            } else {
                $file = new UploadedFile($file['tmp_name'], $file['name'], $file['type'], $file['error'], false);
            }
        } else {
            $file = array_map(function ($v) { return $v instanceof UploadedFile || \is_array($v) ? $this->convertFileInformation($v) : $v; }, $file);
            if (array_keys($keys) === $keys) {
                $file = array_filter($file);
            }
        }

        return $file;
    }

    /**
     * Fixes a malformed PHP $_FILES array.
     *
     * PHP has a bug that the format of the $_FILES array differs, depending on
     * whether the uploaded file fields had normal field names or array-like
     * field names ("normal" vs. "parent[child]").
     *
     * This method fixes the array to look like the "normal" $_FILES array.
     *
     * It's safe to pass an already converted array, in which case this method
     * just returns the original array unmodified.
     *
     * @return array
     */
    protected function fixPhpFilesArray(array $data)
    {
        // Remove extra key added by PHP 8.1.
        unset($data['full_path']);
        $keys = array_keys($data);
        sort($keys);

        if (self::FILE_KEYS != $keys || !isset($data['name']) || !\is_array($data['name'])) {
            return $data;
        }

        $files = $data;
        foreach (self::FILE_KEYS as $k) {
            unset($files[$k]);
        }

        foreach ($data['name'] as $key => $name) {
            $files[$key] = $this->fixPhpFilesArray([
                'error' => $data['error'][$key],
                'name' => $name,
                'type' => $data['type'][$key],
                'tmp_name' => $data['tmp_name'][$key],
                'size' => $data['size'][$key],
            ]);
        }

        return $files;
    }
}
PKϤ$Z��(7ZZhttp-foundation/Request.phpnu�[���<?php

/*
 * This file is part of the Symfony package.
 *
 * (c) Fabien Potencier <fabien@symfony.com>
 *
 * For the full copyright and license information, please view the LICENSE
 * file that was distributed with this source code.
 */

namespace Symfony\Component\HttpFoundation;

use Symfony\Component\HttpFoundation\Exception\ConflictingHeadersException;
use Symfony\Component\HttpFoundation\Exception\JsonException;
use Symfony\Component\HttpFoundation\Exception\SessionNotFoundException;
use Symfony\Component\HttpFoundation\Exception\SuspiciousOperationException;
use Symfony\Component\HttpFoundation\Session\SessionInterface;

// Help opcache.preload discover always-needed symbols
class_exists(AcceptHeader::class);
class_exists(FileBag::class);
class_exists(HeaderBag::class);
class_exists(HeaderUtils::class);
class_exists(InputBag::class);
class_exists(ParameterBag::class);
class_exists(ServerBag::class);

/**
 * Request represents an HTTP request.
 *
 * The methods dealing with URL accept / return a raw path (% encoded):
 *   * getBasePath
 *   * getBaseUrl
 *   * getPathInfo
 *   * getRequestUri
 *   * getUri
 *   * getUriForPath
 *
 * @author Fabien Potencier <fabien@symfony.com>
 */
class Request
{
    public const HEADER_FORWARDED = 0b000001; // When using RFC 7239
    public const HEADER_X_FORWARDED_FOR = 0b000010;
    public const HEADER_X_FORWARDED_HOST = 0b000100;
    public const HEADER_X_FORWARDED_PROTO = 0b001000;
    public const HEADER_X_FORWARDED_PORT = 0b010000;
    public const HEADER_X_FORWARDED_PREFIX = 0b100000;

    /** @deprecated since Symfony 5.2, use either "HEADER_X_FORWARDED_FOR | HEADER_X_FORWARDED_HOST | HEADER_X_FORWARDED_PORT | HEADER_X_FORWARDED_PROTO" or "HEADER_X_FORWARDED_AWS_ELB" or "HEADER_X_FORWARDED_TRAEFIK" constants instead. */
    public const HEADER_X_FORWARDED_ALL = 0b1011110; // All "X-Forwarded-*" headers sent by "usual" reverse proxy
    public const HEADER_X_FORWARDED_AWS_ELB = 0b0011010; // AWS ELB doesn't send X-Forwarded-Host
    public const HEADER_X_FORWARDED_TRAEFIK = 0b0111110; // All "X-Forwarded-*" headers sent by Traefik reverse proxy

    public const METHOD_HEAD = 'HEAD';
    public const METHOD_GET = 'GET';
    public const METHOD_POST = 'POST';
    public const METHOD_PUT = 'PUT';
    public const METHOD_PATCH = 'PATCH';
    public const METHOD_DELETE = 'DELETE';
    public const METHOD_PURGE = 'PURGE';
    public const METHOD_OPTIONS = 'OPTIONS';
    public const METHOD_TRACE = 'TRACE';
    public const METHOD_CONNECT = 'CONNECT';

    /**
     * @var string[]
     */
    protected static $trustedProxies = [];

    /**
     * @var string[]
     */
    protected static $trustedHostPatterns = [];

    /**
     * @var string[]
     */
    protected static $trustedHosts = [];

    protected static $httpMethodParameterOverride = false;

    /**
     * Custom parameters.
     *
     * @var ParameterBag
     */
    public $attributes;

    /**
     * Request body parameters ($_POST).
     *
     * @var InputBag
     */
    public $request;

    /**
     * Query string parameters ($_GET).
     *
     * @var InputBag
     */
    public $query;

    /**
     * Server and execution environment parameters ($_SERVER).
     *
     * @var ServerBag
     */
    public $server;

    /**
     * Uploaded files ($_FILES).
     *
     * @var FileBag
     */
    public $files;

    /**
     * Cookies ($_COOKIE).
     *
     * @var InputBag
     */
    public $cookies;

    /**
     * Headers (taken from the $_SERVER).
     *
     * @var HeaderBag
     */
    public $headers;

    /**
     * @var string|resource|false|null
     */
    protected $content;

    /**
     * @var array
     */
    protected $languages;

    /**
     * @var array
     */
    protected $charsets;

    /**
     * @var array
     */
    protected $encodings;

    /**
     * @var array
     */
    protected $acceptableContentTypes;

    /**
     * @var string
     */
    protected $pathInfo;

    /**
     * @var string
     */
    protected $requestUri;

    /**
     * @var string
     */
    protected $baseUrl;

    /**
     * @var string
     */
    protected $basePath;

    /**
     * @var string
     */
    protected $method;

    /**
     * @var string
     */
    protected $format;

    /**
     * @var SessionInterface|callable
     */
    protected $session;

    /**
     * @var string
     */
    protected $locale;

    /**
     * @var string
     */
    protected $defaultLocale = 'en';

    /**
     * @var array
     */
    protected static $formats;

    protected static $requestFactory;

    /**
     * @var string|null
     */
    private $preferredFormat;
    private $isHostValid = true;
    private $isForwardedValid = true;

    /**
     * @var bool|null
     */
    private $isSafeContentPreferred;

    private static $trustedHeaderSet = -1;

    private const FORWARDED_PARAMS = [
        self::HEADER_X_FORWARDED_FOR => 'for',
        self::HEADER_X_FORWARDED_HOST => 'host',
        self::HEADER_X_FORWARDED_PROTO => 'proto',
        self::HEADER_X_FORWARDED_PORT => 'host',
    ];

    /**
     * Names for headers that can be trusted when
     * using trusted proxies.
     *
     * The FORWARDED header is the standard as of rfc7239.
     *
     * The other headers are non-standard, but widely used
     * by popular reverse proxies (like Apache mod_proxy or Amazon EC2).
     */
    private const TRUSTED_HEADERS = [
        self::HEADER_FORWARDED => 'FORWARDED',
        self::HEADER_X_FORWARDED_FOR => 'X_FORWARDED_FOR',
        self::HEADER_X_FORWARDED_HOST => 'X_FORWARDED_HOST',
        self::HEADER_X_FORWARDED_PROTO => 'X_FORWARDED_PROTO',
        self::HEADER_X_FORWARDED_PORT => 'X_FORWARDED_PORT',
        self::HEADER_X_FORWARDED_PREFIX => 'X_FORWARDED_PREFIX',
    ];

    /**
     * @param array                $query      The GET parameters
     * @param array                $request    The POST parameters
     * @param array                $attributes The request attributes (parameters parsed from the PATH_INFO, ...)
     * @param array                $cookies    The COOKIE parameters
     * @param array                $files      The FILES parameters
     * @param array                $server     The SERVER parameters
     * @param string|resource|null $content    The raw body data
     */
    public function __construct(array $query = [], array $request = [], array $attributes = [], array $cookies = [], array $files = [], array $server = [], $content = null)
    {
        $this->initialize($query, $request, $attributes, $cookies, $files, $server, $content);
    }

    /**
     * Sets the parameters for this request.
     *
     * This method also re-initializes all properties.
     *
     * @param array                $query      The GET parameters
     * @param array                $request    The POST parameters
     * @param array                $attributes The request attributes (parameters parsed from the PATH_INFO, ...)
     * @param array                $cookies    The COOKIE parameters
     * @param array                $files      The FILES parameters
     * @param array                $server     The SERVER parameters
     * @param string|resource|null $content    The raw body data
     */
    public function initialize(array $query = [], array $request = [], array $attributes = [], array $cookies = [], array $files = [], array $server = [], $content = null)
    {
        $this->request = new InputBag($request);
        $this->query = new InputBag($query);
        $this->attributes = new ParameterBag($attributes);
        $this->cookies = new InputBag($cookies);
        $this->files = new FileBag($files);
        $this->server = new ServerBag($server);
        $this->headers = new HeaderBag($this->server->getHeaders());

        $this->content = $content;
        $this->languages = null;
        $this->charsets = null;
        $this->encodings = null;
        $this->acceptableContentTypes = null;
        $this->pathInfo = null;
        $this->requestUri = null;
        $this->baseUrl = null;
        $this->basePath = null;
        $this->method = null;
        $this->format = null;
    }

    /**
     * Creates a new request with values from PHP's super globals.
     *
     * @return static
     */
    public static function createFromGlobals()
    {
        $request = self::createRequestFromFactory($_GET, $_POST, [], $_COOKIE, $_FILES, $_SERVER);

        if (str_starts_with($request->headers->get('CONTENT_TYPE', ''), 'application/x-www-form-urlencoded')
            && \in_array(strtoupper($request->server->get('REQUEST_METHOD', 'GET')), ['PUT', 'DELETE', 'PATCH'])
        ) {
            parse_str($request->getContent(), $data);
            $request->request = new InputBag($data);
        }

        return $request;
    }

    /**
     * Creates a Request based on a given URI and configuration.
     *
     * The information contained in the URI always take precedence
     * over the other information (server and parameters).
     *
     * @param string               $uri        The URI
     * @param string               $method     The HTTP method
     * @param array                $parameters The query (GET) or request (POST) parameters
     * @param array                $cookies    The request cookies ($_COOKIE)
     * @param array                $files      The request files ($_FILES)
     * @param array                $server     The server parameters ($_SERVER)
     * @param string|resource|null $content    The raw body data
     *
     * @return static
     */
    public static function create(string $uri, string $method = 'GET', array $parameters = [], array $cookies = [], array $files = [], array $server = [], $content = null)
    {
        $server = array_replace([
            'SERVER_NAME' => 'localhost',
            'SERVER_PORT' => 80,
            'HTTP_HOST' => 'localhost',
            'HTTP_USER_AGENT' => 'Symfony',
            'HTTP_ACCEPT' => 'text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8',
            'HTTP_ACCEPT_LANGUAGE' => 'en-us,en;q=0.5',
            'HTTP_ACCEPT_CHARSET' => 'ISO-8859-1,utf-8;q=0.7,*;q=0.7',
            'REMOTE_ADDR' => '127.0.0.1',
            'SCRIPT_NAME' => '',
            'SCRIPT_FILENAME' => '',
            'SERVER_PROTOCOL' => 'HTTP/1.1',
            'REQUEST_TIME' => time(),
            'REQUEST_TIME_FLOAT' => microtime(true),
        ], $server);

        $server['PATH_INFO'] = '';
        $server['REQUEST_METHOD'] = strtoupper($method);

        $components = parse_url($uri);
        if (isset($components['host'])) {
            $server['SERVER_NAME'] = $components['host'];
            $server['HTTP_HOST'] = $components['host'];
        }

        if (isset($components['scheme'])) {
            if ('https' === $components['scheme']) {
                $server['HTTPS'] = 'on';
                $server['SERVER_PORT'] = 443;
            } else {
                unset($server['HTTPS']);
                $server['SERVER_PORT'] = 80;
            }
        }

        if (isset($components['port'])) {
            $server['SERVER_PORT'] = $components['port'];
            $server['HTTP_HOST'] .= ':'.$components['port'];
        }

        if (isset($components['user'])) {
            $server['PHP_AUTH_USER'] = $components['user'];
        }

        if (isset($components['pass'])) {
            $server['PHP_AUTH_PW'] = $components['pass'];
        }

        if (!isset($components['path'])) {
            $components['path'] = '/';
        }

        switch (strtoupper($method)) {
            case 'POST':
            case 'PUT':
            case 'DELETE':
                if (!isset($server['CONTENT_TYPE'])) {
                    $server['CONTENT_TYPE'] = 'application/x-www-form-urlencoded';
                }
                // no break
            case 'PATCH':
                $request = $parameters;
                $query = [];
                break;
            default:
                $request = [];
                $query = $parameters;
                break;
        }

        $queryString = '';
        if (isset($components['query'])) {
            parse_str(html_entity_decode($components['query']), $qs);

            if ($query) {
                $query = array_replace($qs, $query);
                $queryString = http_build_query($query, '', '&');
            } else {
                $query = $qs;
                $queryString = $components['query'];
            }
        } elseif ($query) {
            $queryString = http_build_query($query, '', '&');
        }

        $server['REQUEST_URI'] = $components['path'].('' !== $queryString ? '?'.$queryString : '');
        $server['QUERY_STRING'] = $queryString;

        return self::createRequestFromFactory($query, $request, [], $cookies, $files, $server, $content);
    }

    /**
     * Sets a callable able to create a Request instance.
     *
     * This is mainly useful when you need to override the Request class
     * to keep BC with an existing system. It should not be used for any
     * other purpose.
     */
    public static function setFactory(?callable $callable)
    {
        self::$requestFactory = $callable;
    }

    /**
     * Clones a request and overrides some of its parameters.
     *
     * @param array $query      The GET parameters
     * @param array $request    The POST parameters
     * @param array $attributes The request attributes (parameters parsed from the PATH_INFO, ...)
     * @param array $cookies    The COOKIE parameters
     * @param array $files      The FILES parameters
     * @param array $server     The SERVER parameters
     *
     * @return static
     */
    public function duplicate(array $query = null, array $request = null, array $attributes = null, array $cookies = null, array $files = null, array $server = null)
    {
        $dup = clone $this;
        if (null !== $query) {
            $dup->query = new InputBag($query);
        }
        if (null !== $request) {
            $dup->request = new InputBag($request);
        }
        if (null !== $attributes) {
            $dup->attributes = new ParameterBag($attributes);
        }
        if (null !== $cookies) {
            $dup->cookies = new InputBag($cookies);
        }
        if (null !== $files) {
            $dup->files = new FileBag($files);
        }
        if (null !== $server) {
            $dup->server = new ServerBag($server);
            $dup->headers = new HeaderBag($dup->server->getHeaders());
        }
        $dup->languages = null;
        $dup->charsets = null;
        $dup->encodings = null;
        $dup->acceptableContentTypes = null;
        $dup->pathInfo = null;
        $dup->requestUri = null;
        $dup->baseUrl = null;
        $dup->basePath = null;
        $dup->method = null;
        $dup->format = null;

        if (!$dup->get('_format') && $this->get('_format')) {
            $dup->attributes->set('_format', $this->get('_format'));
        }

        if (!$dup->getRequestFormat(null)) {
            $dup->setRequestFormat($this->getRequestFormat(null));
        }

        return $dup;
    }

    /**
     * Clones the current request.
     *
     * Note that the session is not cloned as duplicated requests
     * are most of the time sub-requests of the main one.
     */
    public function __clone()
    {
        $this->query = clone $this->query;
        $this->request = clone $this->request;
        $this->attributes = clone $this->attributes;
        $this->cookies = clone $this->cookies;
        $this->files = clone $this->files;
        $this->server = clone $this->server;
        $this->headers = clone $this->headers;
    }

    /**
     * Returns the request as a string.
     *
     * @return string The request
     */
    public function __toString()
    {
        $content = $this->getContent();

        $cookieHeader = '';
        $cookies = [];

        foreach ($this->cookies as $k => $v) {
            $cookies[] = $k.'='.$v;
        }

        if (!empty($cookies)) {
            $cookieHeader = 'Cookie: '.implode('; ', $cookies)."\r\n";
        }

        return
            sprintf('%s %s %s', $this->getMethod(), $this->getRequestUri(), $this->server->get('SERVER_PROTOCOL'))."\r\n".
            $this->headers.
            $cookieHeader."\r\n".
            $content;
    }

    /**
     * Overrides the PHP global variables according to this request instance.
     *
     * It overrides $_GET, $_POST, $_REQUEST, $_SERVER, $_COOKIE.
     * $_FILES is never overridden, see rfc1867
     */
    public function overrideGlobals()
    {
        $this->server->set('QUERY_STRING', static::normalizeQueryString(http_build_query($this->query->all(), '', '&')));

        $_GET = $this->query->all();
        $_POST = $this->request->all();
        $_SERVER = $this->server->all();
        $_COOKIE = $this->cookies->all();

        foreach ($this->headers->all() as $key => $value) {
            $key = strtoupper(str_replace('-', '_', $key));
            if (\in_array($key, ['CONTENT_TYPE', 'CONTENT_LENGTH', 'CONTENT_MD5'], true)) {
                $_SERVER[$key] = implode(', ', $value);
            } else {
                $_SERVER['HTTP_'.$key] = implode(', ', $value);
            }
        }

        $request = ['g' => $_GET, 'p' => $_POST, 'c' => $_COOKIE];

        $requestOrder = ini_get('request_order') ?: ini_get('variables_order');
        $requestOrder = preg_replace('#[^cgp]#', '', strtolower($requestOrder)) ?: 'gp';

        $_REQUEST = [[]];

        foreach (str_split($requestOrder) as $order) {
            $_REQUEST[] = $request[$order];
        }

        $_REQUEST = array_merge(...$_REQUEST);
    }

    /**
     * Sets a list of trusted proxies.
     *
     * You should only list the reverse proxies that you manage directly.
     *
     * @param array $proxies          A list of trusted proxies, the string 'REMOTE_ADDR' will be replaced with $_SERVER['REMOTE_ADDR']
     * @param int   $trustedHeaderSet A bit field of Request::HEADER_*, to set which headers to trust from your proxies
     */
    public static function setTrustedProxies(array $proxies, int $trustedHeaderSet)
    {
        if (self::HEADER_X_FORWARDED_ALL === $trustedHeaderSet) {
            trigger_deprecation('symfony/http-foundation', '5.2', 'The "HEADER_X_FORWARDED_ALL" constant is deprecated, use either "HEADER_X_FORWARDED_FOR | HEADER_X_FORWARDED_HOST | HEADER_X_FORWARDED_PORT | HEADER_X_FORWARDED_PROTO" or "HEADER_X_FORWARDED_AWS_ELB" or "HEADER_X_FORWARDED_TRAEFIK" constants instead.');
        }
        self::$trustedProxies = array_reduce($proxies, function ($proxies, $proxy) {
            if ('REMOTE_ADDR' !== $proxy) {
                $proxies[] = $proxy;
            } elseif (isset($_SERVER['REMOTE_ADDR'])) {
                $proxies[] = $_SERVER['REMOTE_ADDR'];
            }

            return $proxies;
        }, []);
        self::$trustedHeaderSet = $trustedHeaderSet;
    }

    /**
     * Gets the list of trusted proxies.
     *
     * @return array An array of trusted proxies
     */
    public static function getTrustedProxies()
    {
        return self::$trustedProxies;
    }

    /**
     * Gets the set of trusted headers from trusted proxies.
     *
     * @return int A bit field of Request::HEADER_* that defines which headers are trusted from your proxies
     */
    public static function getTrustedHeaderSet()
    {
        return self::$trustedHeaderSet;
    }

    /**
     * Sets a list of trusted host patterns.
     *
     * You should only list the hosts you manage using regexs.
     *
     * @param array $hostPatterns A list of trusted host patterns
     */
    public static function setTrustedHosts(array $hostPatterns)
    {
        self::$trustedHostPatterns = array_map(function ($hostPattern) {
            return sprintf('{%s}i', $hostPattern);
        }, $hostPatterns);
        // we need to reset trusted hosts on trusted host patterns change
        self::$trustedHosts = [];
    }

    /**
     * Gets the list of trusted host patterns.
     *
     * @return array An array of trusted host patterns
     */
    public static function getTrustedHosts()
    {
        return self::$trustedHostPatterns;
    }

    /**
     * Normalizes a query string.
     *
     * It builds a normalized query string, where keys/value pairs are alphabetized,
     * have consistent escaping and unneeded delimiters are removed.
     *
     * @return string A normalized query string for the Request
     */
    public static function normalizeQueryString(?string $qs)
    {
        if ('' === ($qs ?? '')) {
            return '';
        }

        $qs = HeaderUtils::parseQuery($qs);
        ksort($qs);

        return http_build_query($qs, '', '&', \PHP_QUERY_RFC3986);
    }

    /**
     * Enables support for the _method request parameter to determine the intended HTTP method.
     *
     * Be warned that enabling this feature might lead to CSRF issues in your code.
     * Check that you are using CSRF tokens when required.
     * If the HTTP method parameter override is enabled, an html-form with method "POST" can be altered
     * and used to send a "PUT" or "DELETE" request via the _method request parameter.
     * If these methods are not protected against CSRF, this presents a possible vulnerability.
     *
     * The HTTP method can only be overridden when the real HTTP method is POST.
     */
    public static function enableHttpMethodParameterOverride()
    {
        self::$httpMethodParameterOverride = true;
    }

    /**
     * Checks whether support for the _method request parameter is enabled.
     *
     * @return bool True when the _method request parameter is enabled, false otherwise
     */
    public static function getHttpMethodParameterOverride()
    {
        return self::$httpMethodParameterOverride;
    }

    /**
     * Gets a "parameter" value from any bag.
     *
     * This method is mainly useful for libraries that want to provide some flexibility. If you don't need the
     * flexibility in controllers, it is better to explicitly get request parameters from the appropriate
     * public property instead (attributes, query, request).
     *
     * Order of precedence: PATH (routing placeholders or custom attributes), GET, POST
     *
     * @param mixed $default The default value if the parameter key does not exist
     *
     * @return mixed
     */
    public function get(string $key, $default = null)
    {
        if ($this !== $result = $this->attributes->get($key, $this)) {
            return $result;
        }

        if ($this->query->has($key)) {
            return $this->query->all()[$key];
        }

        if ($this->request->has($key)) {
            return $this->request->all()[$key];
        }

        return $default;
    }

    /**
     * Gets the Session.
     *
     * @return SessionInterface The session
     */
    public function getSession()
    {
        $session = $this->session;
        if (!$session instanceof SessionInterface && null !== $session) {
            $this->setSession($session = $session());
        }

        if (null === $session) {
            throw new SessionNotFoundException('Session has not been set.');
        }

        return $session;
    }

    /**
     * Whether the request contains a Session which was started in one of the
     * previous requests.
     *
     * @return bool
     */
    public function hasPreviousSession()
    {
        // the check for $this->session avoids malicious users trying to fake a session cookie with proper name
        return $this->hasSession() && $this->cookies->has($this->getSession()->getName());
    }

    /**
     * Whether the request contains a Session object.
     *
     * This method does not give any information about the state of the session object,
     * like whether the session is started or not. It is just a way to check if this Request
     * is associated with a Session instance.
     *
     * @return bool true when the Request contains a Session object, false otherwise
     */
    public function hasSession()
    {
        return null !== $this->session;
    }

    public function setSession(SessionInterface $session)
    {
        $this->session = $session;
    }

    /**
     * @internal
     */
    public function setSessionFactory(callable $factory)
    {
        $this->session = $factory;
    }

    /**
     * Returns the client IP addresses.
     *
     * In the returned array the most trusted IP address is first, and the
     * least trusted one last. The "real" client IP address is the last one,
     * but this is also the least trusted one. Trusted proxies are stripped.
     *
     * Use this method carefully; you should use getClientIp() instead.
     *
     * @return array The client IP addresses
     *
     * @see getClientIp()
     */
    public function getClientIps()
    {
        $ip = $this->server->get('REMOTE_ADDR');

        if (!$this->isFromTrustedProxy()) {
            return [$ip];
        }

        return $this->getTrustedValues(self::HEADER_X_FORWARDED_FOR, $ip) ?: [$ip];
    }

    /**
     * Returns the client IP address.
     *
     * This method can read the client IP address from the "X-Forwarded-For" header
     * when trusted proxies were set via "setTrustedProxies()". The "X-Forwarded-For"
     * header value is a comma+space separated list of IP addresses, the left-most
     * being the original client, and each successive proxy that passed the request
     * adding the IP address where it received the request from.
     *
     * If your reverse proxy uses a different header name than "X-Forwarded-For",
     * ("Client-Ip" for instance), configure it via the $trustedHeaderSet
     * argument of the Request::setTrustedProxies() method instead.
     *
     * @return string|null The client IP address
     *
     * @see getClientIps()
     * @see https://wikipedia.org/wiki/X-Forwarded-For
     */
    public function getClientIp()
    {
        $ipAddresses = $this->getClientIps();

        return $ipAddresses[0];
    }

    /**
     * Returns current script name.
     *
     * @return string
     */
    public function getScriptName()
    {
        return $this->server->get('SCRIPT_NAME', $this->server->get('ORIG_SCRIPT_NAME', ''));
    }

    /**
     * Returns the path being requested relative to the executed script.
     *
     * The path info always starts with a /.
     *
     * Suppose this request is instantiated from /mysite on localhost:
     *
     *  * http://localhost/mysite              returns an empty string
     *  * http://localhost/mysite/about        returns '/about'
     *  * http://localhost/mysite/enco%20ded   returns '/enco%20ded'
     *  * http://localhost/mysite/about?var=1  returns '/about'
     *
     * @return string The raw path (i.e. not urldecoded)
     */
    public function getPathInfo()
    {
        if (null === $this->pathInfo) {
            $this->pathInfo = $this->preparePathInfo();
        }

        return $this->pathInfo;
    }

    /**
     * Returns the root path from which this request is executed.
     *
     * Suppose that an index.php file instantiates this request object:
     *
     *  * http://localhost/index.php         returns an empty string
     *  * http://localhost/index.php/page    returns an empty string
     *  * http://localhost/web/index.php     returns '/web'
     *  * http://localhost/we%20b/index.php  returns '/we%20b'
     *
     * @return string The raw path (i.e. not urldecoded)
     */
    public function getBasePath()
    {
        if (null === $this->basePath) {
            $this->basePath = $this->prepareBasePath();
        }

        return $this->basePath;
    }

    /**
     * Returns the root URL from which this request is executed.
     *
     * The base URL never ends with a /.
     *
     * This is similar to getBasePath(), except that it also includes the
     * script filename (e.g. index.php) if one exists.
     *
     * @return string The raw URL (i.e. not urldecoded)
     */
    public function getBaseUrl()
    {
        $trustedPrefix = '';

        // the proxy prefix must be prepended to any prefix being needed at the webserver level
        if ($this->isFromTrustedProxy() && $trustedPrefixValues = $this->getTrustedValues(self::HEADER_X_FORWARDED_PREFIX)) {
            $trustedPrefix = rtrim($trustedPrefixValues[0], '/');
        }

        return $trustedPrefix.$this->getBaseUrlReal();
    }

    /**
     * Returns the real base URL received by the webserver from which this request is executed.
     * The URL does not include trusted reverse proxy prefix.
     *
     * @return string The raw URL (i.e. not urldecoded)
     */
    private function getBaseUrlReal()
    {
        if (null === $this->baseUrl) {
            $this->baseUrl = $this->prepareBaseUrl();
        }

        return $this->baseUrl;
    }

    /**
     * Gets the request's scheme.
     *
     * @return string
     */
    public function getScheme()
    {
        return $this->isSecure() ? 'https' : 'http';
    }

    /**
     * Returns the port on which the request is made.
     *
     * This method can read the client port from the "X-Forwarded-Port" header
     * when trusted proxies were set via "setTrustedProxies()".
     *
     * The "X-Forwarded-Port" header must contain the client port.
     *
     * @return int|string can be a string if fetched from the server bag
     */
    public function getPort()
    {
        if ($this->isFromTrustedProxy() && $host = $this->getTrustedValues(self::HEADER_X_FORWARDED_PORT)) {
            $host = $host[0];
        } elseif ($this->isFromTrustedProxy() && $host = $this->getTrustedValues(self::HEADER_X_FORWARDED_HOST)) {
            $host = $host[0];
        } elseif (!$host = $this->headers->get('HOST')) {
            return $this->server->get('SERVER_PORT');
        }

        if ('[' === $host[0]) {
            $pos = strpos($host, ':', strrpos($host, ']'));
        } else {
            $pos = strrpos($host, ':');
        }

        if (false !== $pos && $port = substr($host, $pos + 1)) {
            return (int) $port;
        }

        return 'https' === $this->getScheme() ? 443 : 80;
    }

    /**
     * Returns the user.
     *
     * @return string|null
     */
    public function getUser()
    {
        return $this->headers->get('PHP_AUTH_USER');
    }

    /**
     * Returns the password.
     *
     * @return string|null
     */
    public function getPassword()
    {
        return $this->headers->get('PHP_AUTH_PW');
    }

    /**
     * Gets the user info.
     *
     * @return string A user name and, optionally, scheme-specific information about how to gain authorization to access the server
     */
    public function getUserInfo()
    {
        $userinfo = $this->getUser();

        $pass = $this->getPassword();
        if ('' != $pass) {
            $userinfo .= ":$pass";
        }

        return $userinfo;
    }

    /**
     * Returns the HTTP host being requested.
     *
     * The port name will be appended to the host if it's non-standard.
     *
     * @return string
     */
    public function getHttpHost()
    {
        $scheme = $this->getScheme();
        $port = $this->getPort();

        if (('http' == $scheme && 80 == $port) || ('https' == $scheme && 443 == $port)) {
            return $this->getHost();
        }

        return $this->getHost().':'.$port;
    }

    /**
     * Returns the requested URI (path and query string).
     *
     * @return string The raw URI (i.e. not URI decoded)
     */
    public function getRequestUri()
    {
        if (null === $this->requestUri) {
            $this->requestUri = $this->prepareRequestUri();
        }

        return $this->requestUri;
    }

    /**
     * Gets the scheme and HTTP host.
     *
     * If the URL was called with basic authentication, the user
     * and the password are not added to the generated string.
     *
     * @return string The scheme and HTTP host
     */
    public function getSchemeAndHttpHost()
    {
        return $this->getScheme().'://'.$this->getHttpHost();
    }

    /**
     * Generates a normalized URI (URL) for the Request.
     *
     * @return string A normalized URI (URL) for the Request
     *
     * @see getQueryString()
     */
    public function getUri()
    {
        if (null !== $qs = $this->getQueryString()) {
            $qs = '?'.$qs;
        }

        return $this->getSchemeAndHttpHost().$this->getBaseUrl().$this->getPathInfo().$qs;
    }

    /**
     * Generates a normalized URI for the given path.
     *
     * @param string $path A path to use instead of the current one
     *
     * @return string The normalized URI for the path
     */
    public function getUriForPath(string $path)
    {
        return $this->getSchemeAndHttpHost().$this->getBaseUrl().$path;
    }

    /**
     * Returns the path as relative reference from the current Request path.
     *
     * Only the URIs path component (no schema, host etc.) is relevant and must be given.
     * Both paths must be absolute and not contain relative parts.
     * Relative URLs from one resource to another are useful when generating self-contained downloadable document archives.
     * Furthermore, they can be used to reduce the link size in documents.
     *
     * Example target paths, given a base path of "/a/b/c/d":
     * - "/a/b/c/d"     -> ""
     * - "/a/b/c/"      -> "./"
     * - "/a/b/"        -> "../"
     * - "/a/b/c/other" -> "other"
     * - "/a/x/y"       -> "../../x/y"
     *
     * @return string The relative target path
     */
    public function getRelativeUriForPath(string $path)
    {
        // be sure that we are dealing with an absolute path
        if (!isset($path[0]) || '/' !== $path[0]) {
            return $path;
        }

        if ($path === $basePath = $this->getPathInfo()) {
            return '';
        }

        $sourceDirs = explode('/', isset($basePath[0]) && '/' === $basePath[0] ? substr($basePath, 1) : $basePath);
        $targetDirs = explode('/', substr($path, 1));
        array_pop($sourceDirs);
        $targetFile = array_pop($targetDirs);

        foreach ($sourceDirs as $i => $dir) {
            if (isset($targetDirs[$i]) && $dir === $targetDirs[$i]) {
                unset($sourceDirs[$i], $targetDirs[$i]);
            } else {
                break;
            }
        }

        $targetDirs[] = $targetFile;
        $path = str_repeat('../', \count($sourceDirs)).implode('/', $targetDirs);

        // A reference to the same base directory or an empty subdirectory must be prefixed with "./".
        // This also applies to a segment with a colon character (e.g., "file:colon") that cannot be used
        // as the first segment of a relative-path reference, as it would be mistaken for a scheme name
        // (see https://tools.ietf.org/html/rfc3986#section-4.2).
        return !isset($path[0]) || '/' === $path[0]
            || false !== ($colonPos = strpos($path, ':')) && ($colonPos < ($slashPos = strpos($path, '/')) || false === $slashPos)
            ? "./$path" : $path;
    }

    /**
     * Generates the normalized query string for the Request.
     *
     * It builds a normalized query string, where keys/value pairs are alphabetized
     * and have consistent escaping.
     *
     * @return string|null A normalized query string for the Request
     */
    public function getQueryString()
    {
        $qs = static::normalizeQueryString($this->server->get('QUERY_STRING'));

        return '' === $qs ? null : $qs;
    }

    /**
     * Checks whether the request is secure or not.
     *
     * This method can read the client protocol from the "X-Forwarded-Proto" header
     * when trusted proxies were set via "setTrustedProxies()".
     *
     * The "X-Forwarded-Proto" header must contain the protocol: "https" or "http".
     *
     * @return bool
     */
    public function isSecure()
    {
        if ($this->isFromTrustedProxy() && $proto = $this->getTrustedValues(self::HEADER_X_FORWARDED_PROTO)) {
            return \in_array(strtolower($proto[0]), ['https', 'on', 'ssl', '1'], true);
        }

        $https = $this->server->get('HTTPS');

        return !empty($https) && 'off' !== strtolower($https);
    }

    /**
     * Returns the host name.
     *
     * This method can read the client host name from the "X-Forwarded-Host" header
     * when trusted proxies were set via "setTrustedProxies()".
     *
     * The "X-Forwarded-Host" header must contain the client host name.
     *
     * @return string
     *
     * @throws SuspiciousOperationException when the host name is invalid or not trusted
     */
    public function getHost()
    {
        if ($this->isFromTrustedProxy() && $host = $this->getTrustedValues(self::HEADER_X_FORWARDED_HOST)) {
            $host = $host[0];
        } elseif (!$host = $this->headers->get('HOST')) {
            if (!$host = $this->server->get('SERVER_NAME')) {
                $host = $this->server->get('SERVER_ADDR', '');
            }
        }

        // trim and remove port number from host
        // host is lowercase as per RFC 952/2181
        $host = strtolower(preg_replace('/:\d+$/', '', trim($host)));

        // as the host can come from the user (HTTP_HOST and depending on the configuration, SERVER_NAME too can come from the user)
        // check that it does not contain forbidden characters (see RFC 952 and RFC 2181)
        // use preg_replace() instead of preg_match() to prevent DoS attacks with long host names
        if ($host && '' !== preg_replace('/(?:^\[)?[a-zA-Z0-9-:\]_]+\.?/', '', $host)) {
            if (!$this->isHostValid) {
                return '';
            }
            $this->isHostValid = false;

            throw new SuspiciousOperationException(sprintf('Invalid Host "%s".', $host));
        }

        if (\count(self::$trustedHostPatterns) > 0) {
            // to avoid host header injection attacks, you should provide a list of trusted host patterns

            if (\in_array($host, self::$trustedHosts)) {
                return $host;
            }

            foreach (self::$trustedHostPatterns as $pattern) {
                if (preg_match($pattern, $host)) {
                    self::$trustedHosts[] = $host;

                    return $host;
                }
            }

            if (!$this->isHostValid) {
                return '';
            }
            $this->isHostValid = false;

            throw new SuspiciousOperationException(sprintf('Untrusted Host "%s".', $host));
        }

        return $host;
    }

    /**
     * Sets the request method.
     */
    public function setMethod(string $method)
    {
        $this->method = null;
        $this->server->set('REQUEST_METHOD', $method);
    }

    /**
     * Gets the request "intended" method.
     *
     * If the X-HTTP-Method-Override header is set, and if the method is a POST,
     * then it is used to determine the "real" intended HTTP method.
     *
     * The _method request parameter can also be used to determine the HTTP method,
     * but only if enableHttpMethodParameterOverride() has been called.
     *
     * The method is always an uppercased string.
     *
     * @return string The request method
     *
     * @see getRealMethod()
     */
    public function getMethod()
    {
        if (null !== $this->method) {
            return $this->method;
        }

        $this->method = strtoupper($this->server->get('REQUEST_METHOD', 'GET'));

        if ('POST' !== $this->method) {
            return $this->method;
        }

        $method = $this->headers->get('X-HTTP-METHOD-OVERRIDE');

        if (!$method && self::$httpMethodParameterOverride) {
            $method = $this->request->get('_method', $this->query->get('_method', 'POST'));
        }

        if (!\is_string($method)) {
            return $this->method;
        }

        $method = strtoupper($method);

        if (\in_array($method, ['GET', 'HEAD', 'POST', 'PUT', 'DELETE', 'CONNECT', 'OPTIONS', 'PATCH', 'PURGE', 'TRACE'], true)) {
            return $this->method = $method;
        }

        if (!preg_match('/^[A-Z]++$/D', $method)) {
            throw new SuspiciousOperationException(sprintf('Invalid method override "%s".', $method));
        }

        return $this->method = $method;
    }

    /**
     * Gets the "real" request method.
     *
     * @return string The request method
     *
     * @see getMethod()
     */
    public function getRealMethod()
    {
        return strtoupper($this->server->get('REQUEST_METHOD', 'GET'));
    }

    /**
     * Gets the mime type associated with the format.
     *
     * @return string|null The associated mime type (null if not found)
     */
    public function getMimeType(string $format)
    {
        if (null === static::$formats) {
            static::initializeFormats();
        }

        return isset(static::$formats[$format]) ? static::$formats[$format][0] : null;
    }

    /**
     * Gets the mime types associated with the format.
     *
     * @return array The associated mime types
     */
    public static function getMimeTypes(string $format)
    {
        if (null === static::$formats) {
            static::initializeFormats();
        }

        return static::$formats[$format] ?? [];
    }

    /**
     * Gets the format associated with the mime type.
     *
     * @return string|null The format (null if not found)
     */
    public function getFormat(?string $mimeType)
    {
        $canonicalMimeType = null;
        if ($mimeType && false !== $pos = strpos($mimeType, ';')) {
            $canonicalMimeType = trim(substr($mimeType, 0, $pos));
        }

        if (null === static::$formats) {
            static::initializeFormats();
        }

        foreach (static::$formats as $format => $mimeTypes) {
            if (\in_array($mimeType, (array) $mimeTypes)) {
                return $format;
            }
            if (null !== $canonicalMimeType && \in_array($canonicalMimeType, (array) $mimeTypes)) {
                return $format;
            }
        }

        return null;
    }

    /**
     * Associates a format with mime types.
     *
     * @param string|array $mimeTypes The associated mime types (the preferred one must be the first as it will be used as the content type)
     */
    public function setFormat(?string $format, $mimeTypes)
    {
        if (null === static::$formats) {
            static::initializeFormats();
        }

        static::$formats[$format] = \is_array($mimeTypes) ? $mimeTypes : [$mimeTypes];
    }

    /**
     * Gets the request format.
     *
     * Here is the process to determine the format:
     *
     *  * format defined by the user (with setRequestFormat())
     *  * _format request attribute
     *  * $default
     *
     * @see getPreferredFormat
     *
     * @return string|null The request format
     */
    public function getRequestFormat(?string $default = 'html')
    {
        if (null === $this->format) {
            $this->format = $this->attributes->get('_format');
        }

        return $this->format ?? $default;
    }

    /**
     * Sets the request format.
     */
    public function setRequestFormat(?string $format)
    {
        $this->format = $format;
    }

    /**
     * Gets the format associated with the request.
     *
     * @return string|null The format (null if no content type is present)
     */
    public function getContentType()
    {
        return $this->getFormat($this->headers->get('CONTENT_TYPE', ''));
    }

    /**
     * Sets the default locale.
     */
    public function setDefaultLocale(string $locale)
    {
        $this->defaultLocale = $locale;

        if (null === $this->locale) {
            $this->setPhpDefaultLocale($locale);
        }
    }

    /**
     * Get the default locale.
     *
     * @return string
     */
    public function getDefaultLocale()
    {
        return $this->defaultLocale;
    }

    /**
     * Sets the locale.
     */
    public function setLocale(string $locale)
    {
        $this->setPhpDefaultLocale($this->locale = $locale);
    }

    /**
     * Get the locale.
     *
     * @return string
     */
    public function getLocale()
    {
        return null === $this->locale ? $this->defaultLocale : $this->locale;
    }

    /**
     * Checks if the request method is of specified type.
     *
     * @param string $method Uppercase request method (GET, POST etc)
     *
     * @return bool
     */
    public function isMethod(string $method)
    {
        return $this->getMethod() === strtoupper($method);
    }

    /**
     * Checks whether or not the method is safe.
     *
     * @see https://tools.ietf.org/html/rfc7231#section-4.2.1
     *
     * @return bool
     */
    public function isMethodSafe()
    {
        return \in_array($this->getMethod(), ['GET', 'HEAD', 'OPTIONS', 'TRACE']);
    }

    /**
     * Checks whether or not the method is idempotent.
     *
     * @return bool
     */
    public function isMethodIdempotent()
    {
        return \in_array($this->getMethod(), ['HEAD', 'GET', 'PUT', 'DELETE', 'TRACE', 'OPTIONS', 'PURGE']);
    }

    /**
     * Checks whether the method is cacheable or not.
     *
     * @see https://tools.ietf.org/html/rfc7231#section-4.2.3
     *
     * @return bool True for GET and HEAD, false otherwise
     */
    public function isMethodCacheable()
    {
        return \in_array($this->getMethod(), ['GET', 'HEAD']);
    }

    /**
     * Returns the protocol version.
     *
     * If the application is behind a proxy, the protocol version used in the
     * requests between the client and the proxy and between the proxy and the
     * server might be different. This returns the former (from the "Via" header)
     * if the proxy is trusted (see "setTrustedProxies()"), otherwise it returns
     * the latter (from the "SERVER_PROTOCOL" server parameter).
     *
     * @return string|null
     */
    public function getProtocolVersion()
    {
        if ($this->isFromTrustedProxy()) {
            preg_match('~^(HTTP/)?([1-9]\.[0-9]) ~', $this->headers->get('Via'), $matches);

            if ($matches) {
                return 'HTTP/'.$matches[2];
            }
        }

        return $this->server->get('SERVER_PROTOCOL');
    }

    /**
     * Returns the request body content.
     *
     * @param bool $asResource If true, a resource will be returned
     *
     * @return string|resource The request body content or a resource to read the body stream
     */
    public function getContent(bool $asResource = false)
    {
        $currentContentIsResource = \is_resource($this->content);

        if (true === $asResource) {
            if ($currentContentIsResource) {
                rewind($this->content);

                return $this->content;
            }

            // Content passed in parameter (test)
            if (\is_string($this->content)) {
                $resource = fopen('php://temp', 'r+');
                fwrite($resource, $this->content);
                rewind($resource);

                return $resource;
            }

            $this->content = false;

            return fopen('php://input', 'r');
        }

        if ($currentContentIsResource) {
            rewind($this->content);

            return stream_get_contents($this->content);
        }

        if (null === $this->content || false === $this->content) {
            $this->content = file_get_contents('php://input');
        }

        return $this->content;
    }

    /**
     * Gets the request body decoded as array, typically from a JSON payload.
     *
     * @throws JsonException When the body cannot be decoded to an array
     *
     * @return array
     */
    public function toArray()
    {
        if ('' === $content = $this->getContent()) {
            throw new JsonException('Request body is empty.');
        }

        try {
            $content = json_decode($content, true, 512, \JSON_BIGINT_AS_STRING | (\PHP_VERSION_ID >= 70300 ? \JSON_THROW_ON_ERROR : 0));
        } catch (\JsonException $e) {
            throw new JsonException('Could not decode request body.', $e->getCode(), $e);
        }

        if (\PHP_VERSION_ID < 70300 && \JSON_ERROR_NONE !== json_last_error()) {
            throw new JsonException('Could not decode request body: '.json_last_error_msg(), json_last_error());
        }

        if (!\is_array($content)) {
            throw new JsonException(sprintf('JSON content was expected to decode to an array, "%s" returned.', get_debug_type($content)));
        }

        return $content;
    }

    /**
     * Gets the Etags.
     *
     * @return array The entity tags
     */
    public function getETags()
    {
        return preg_split('/\s*,\s*/', $this->headers->get('If-None-Match', ''), -1, \PREG_SPLIT_NO_EMPTY);
    }

    /**
     * @return bool
     */
    public function isNoCache()
    {
        return $this->headers->hasCacheControlDirective('no-cache') || 'no-cache' == $this->headers->get('Pragma');
    }

    /**
     * Gets the preferred format for the response by inspecting, in the following order:
     *   * the request format set using setRequestFormat;
     *   * the values of the Accept HTTP header.
     *
     * Note that if you use this method, you should send the "Vary: Accept" header
     * in the response to prevent any issues with intermediary HTTP caches.
     */
    public function getPreferredFormat(?string $default = 'html'): ?string
    {
        if (null !== $this->preferredFormat || null !== $this->preferredFormat = $this->getRequestFormat(null)) {
            return $this->preferredFormat;
        }

        foreach ($this->getAcceptableContentTypes() as $mimeType) {
            if ($this->preferredFormat = $this->getFormat($mimeType)) {
                return $this->preferredFormat;
            }
        }

        return $default;
    }

    /**
     * Returns the preferred language.
     *
     * @param string[] $locales An array of ordered available locales
     *
     * @return string|null The preferred locale
     */
    public function getPreferredLanguage(array $locales = null)
    {
        $preferredLanguages = $this->getLanguages();

        if (empty($locales)) {
            return $preferredLanguages[0] ?? null;
        }

        if (!$preferredLanguages) {
            return $locales[0];
        }

        $extendedPreferredLanguages = [];
        foreach ($preferredLanguages as $language) {
            $extendedPreferredLanguages[] = $language;
            if (false !== $position = strpos($language, '_')) {
                $superLanguage = substr($language, 0, $position);
                if (!\in_array($superLanguage, $preferredLanguages)) {
                    $extendedPreferredLanguages[] = $superLanguage;
                }
            }
        }

        $preferredLanguages = array_values(array_intersect($extendedPreferredLanguages, $locales));

        return $preferredLanguages[0] ?? $locales[0];
    }

    /**
     * Gets a list of languages acceptable by the client browser.
     *
     * @return array Languages ordered in the user browser preferences
     */
    public function getLanguages()
    {
        if (null !== $this->languages) {
            return $this->languages;
        }

        $languages = AcceptHeader::fromString($this->headers->get('Accept-Language'))->all();
        $this->languages = [];
        foreach ($languages as $lang => $acceptHeaderItem) {
            if (str_contains($lang, '-')) {
                $codes = explode('-', $lang);
                if ('i' === $codes[0]) {
                    // Language not listed in ISO 639 that are not variants
                    // of any listed language, which can be registered with the
                    // i-prefix, such as i-cherokee
                    if (\count($codes) > 1) {
                        $lang = $codes[1];
                    }
                } else {
                    for ($i = 0, $max = \count($codes); $i < $max; ++$i) {
                        if (0 === $i) {
                            $lang = strtolower($codes[0]);
                        } else {
                            $lang .= '_'.strtoupper($codes[$i]);
                        }
                    }
                }
            }

            $this->languages[] = $lang;
        }

        return $this->languages;
    }

    /**
     * Gets a list of charsets acceptable by the client browser.
     *
     * @return array List of charsets in preferable order
     */
    public function getCharsets()
    {
        if (null !== $this->charsets) {
            return $this->charsets;
        }

        return $this->charsets = array_keys(AcceptHeader::fromString($this->headers->get('Accept-Charset'))->all());
    }

    /**
     * Gets a list of encodings acceptable by the client browser.
     *
     * @return array List of encodings in preferable order
     */
    public function getEncodings()
    {
        if (null !== $this->encodings) {
            return $this->encodings;
        }

        return $this->encodings = array_keys(AcceptHeader::fromString($this->headers->get('Accept-Encoding'))->all());
    }

    /**
     * Gets a list of content types acceptable by the client browser.
     *
     * @return array List of content types in preferable order
     */
    public function getAcceptableContentTypes()
    {
        if (null !== $this->acceptableContentTypes) {
            return $this->acceptableContentTypes;
        }

        return $this->acceptableContentTypes = array_keys(AcceptHeader::fromString($this->headers->get('Accept'))->all());
    }

    /**
     * Returns true if the request is an XMLHttpRequest.
     *
     * It works if your JavaScript library sets an X-Requested-With HTTP header.
     * It is known to work with common JavaScript frameworks:
     *
     * @see https://wikipedia.org/wiki/List_of_Ajax_frameworks#JavaScript
     *
     * @return bool true if the request is an XMLHttpRequest, false otherwise
     */
    public function isXmlHttpRequest()
    {
        return 'XMLHttpRequest' == $this->headers->get('X-Requested-With');
    }

    /**
     * Checks whether the client browser prefers safe content or not according to RFC8674.
     *
     * @see https://tools.ietf.org/html/rfc8674
     */
    public function preferSafeContent(): bool
    {
        if (null !== $this->isSafeContentPreferred) {
            return $this->isSafeContentPreferred;
        }

        if (!$this->isSecure()) {
            // see https://tools.ietf.org/html/rfc8674#section-3
            $this->isSafeContentPreferred = false;

            return $this->isSafeContentPreferred;
        }

        $this->isSafeContentPreferred = AcceptHeader::fromString($this->headers->get('Prefer'))->has('safe');

        return $this->isSafeContentPreferred;
    }

    /*
     * The following methods are derived from code of the Zend Framework (1.10dev - 2010-01-24)
     *
     * Code subject to the new BSD license (https://framework.zend.com/license).
     *
     * Copyright (c) 2005-2010 Zend Technologies USA Inc. (https://www.zend.com/)
     */

    protected function prepareRequestUri()
    {
        $requestUri = '';

        if ('1' == $this->server->get('IIS_WasUrlRewritten') && '' != $this->server->get('UNENCODED_URL')) {
            // IIS7 with URL Rewrite: make sure we get the unencoded URL (double slash problem)
            $requestUri = $this->server->get('UNENCODED_URL');
            $this->server->remove('UNENCODED_URL');
            $this->server->remove('IIS_WasUrlRewritten');
        } elseif ($this->server->has('REQUEST_URI')) {
            $requestUri = $this->server->get('REQUEST_URI');

            if ('' !== $requestUri && '/' === $requestUri[0]) {
                // To only use path and query remove the fragment.
                if (false !== $pos = strpos($requestUri, '#')) {
                    $requestUri = substr($requestUri, 0, $pos);
                }
            } else {
                // HTTP proxy reqs setup request URI with scheme and host [and port] + the URL path,
                // only use URL path.
                $uriComponents = parse_url($requestUri);

                if (isset($uriComponents['path'])) {
                    $requestUri = $uriComponents['path'];
                }

                if (isset($uriComponents['query'])) {
                    $requestUri .= '?'.$uriComponents['query'];
                }
            }
        } elseif ($this->server->has('ORIG_PATH_INFO')) {
            // IIS 5.0, PHP as CGI
            $requestUri = $this->server->get('ORIG_PATH_INFO');
            if ('' != $this->server->get('QUERY_STRING')) {
                $requestUri .= '?'.$this->server->get('QUERY_STRING');
            }
            $this->server->remove('ORIG_PATH_INFO');
        }

        // normalize the request URI to ease creating sub-requests from this request
        $this->server->set('REQUEST_URI', $requestUri);

        return $requestUri;
    }

    /**
     * Prepares the base URL.
     *
     * @return string
     */
    protected function prepareBaseUrl()
    {
        $filename = basename($this->server->get('SCRIPT_FILENAME', ''));

        if (basename($this->server->get('SCRIPT_NAME', '')) === $filename) {
            $baseUrl = $this->server->get('SCRIPT_NAME');
        } elseif (basename($this->server->get('PHP_SELF', '')) === $filename) {
            $baseUrl = $this->server->get('PHP_SELF');
        } elseif (basename($this->server->get('ORIG_SCRIPT_NAME', '')) === $filename) {
            $baseUrl = $this->server->get('ORIG_SCRIPT_NAME'); // 1and1 shared hosting compatibility
        } else {
            // Backtrack up the script_filename to find the portion matching
            // php_self
            $path = $this->server->get('PHP_SELF', '');
            $file = $this->server->get('SCRIPT_FILENAME', '');
            $segs = explode('/', trim($file, '/'));
            $segs = array_reverse($segs);
            $index = 0;
            $last = \count($segs);
            $baseUrl = '';
            do {
                $seg = $segs[$index];
                $baseUrl = '/'.$seg.$baseUrl;
                ++$index;
            } while ($last > $index && (false !== $pos = strpos($path, $baseUrl)) && 0 != $pos);
        }

        // Does the baseUrl have anything in common with the request_uri?
        $requestUri = $this->getRequestUri();
        if ('' !== $requestUri && '/' !== $requestUri[0]) {
            $requestUri = '/'.$requestUri;
        }

        if ($baseUrl && null !== $prefix = $this->getUrlencodedPrefix($requestUri, $baseUrl)) {
            // full $baseUrl matches
            return $prefix;
        }

        if ($baseUrl && null !== $prefix = $this->getUrlencodedPrefix($requestUri, rtrim(\dirname($baseUrl), '/'.\DIRECTORY_SEPARATOR).'/')) {
            // directory portion of $baseUrl matches
            return rtrim($prefix, '/'.\DIRECTORY_SEPARATOR);
        }

        $truncatedRequestUri = $requestUri;
        if (false !== $pos = strpos($requestUri, '?')) {
            $truncatedRequestUri = substr($requestUri, 0, $pos);
        }

        $basename = basename($baseUrl ?? '');
        if (empty($basename) || !strpos(rawurldecode($truncatedRequestUri), $basename)) {
            // no match whatsoever; set it blank
            return '';
        }

        // If using mod_rewrite or ISAPI_Rewrite strip the script filename
        // out of baseUrl. $pos !== 0 makes sure it is not matching a value
        // from PATH_INFO or QUERY_STRING
        if (\strlen($requestUri) >= \strlen($baseUrl) && (false !== $pos = strpos($requestUri, $baseUrl)) && 0 !== $pos) {
            $baseUrl = substr($requestUri, 0, $pos + \strlen($baseUrl));
        }

        return rtrim($baseUrl, '/'.\DIRECTORY_SEPARATOR);
    }

    /**
     * Prepares the base path.
     *
     * @return string base path
     */
    protected function prepareBasePath()
    {
        $baseUrl = $this->getBaseUrl();
        if (empty($baseUrl)) {
            return '';
        }

        $filename = basename($this->server->get('SCRIPT_FILENAME'));
        if (basename($baseUrl) === $filename) {
            $basePath = \dirname($baseUrl);
        } else {
            $basePath = $baseUrl;
        }

        if ('\\' === \DIRECTORY_SEPARATOR) {
            $basePath = str_replace('\\', '/', $basePath);
        }

        return rtrim($basePath, '/');
    }

    /**
     * Prepares the path info.
     *
     * @return string path info
     */
    protected function preparePathInfo()
    {
        if (null === ($requestUri = $this->getRequestUri())) {
            return '/';
        }

        // Remove the query string from REQUEST_URI
        if (false !== $pos = strpos($requestUri, '?')) {
            $requestUri = substr($requestUri, 0, $pos);
        }
        if ('' !== $requestUri && '/' !== $requestUri[0]) {
            $requestUri = '/'.$requestUri;
        }

        if (null === ($baseUrl = $this->getBaseUrlReal())) {
            return $requestUri;
        }

        $pathInfo = substr($requestUri, \strlen($baseUrl));
        if (false === $pathInfo || '' === $pathInfo) {
            // If substr() returns false then PATH_INFO is set to an empty string
            return '/';
        }

        return (string) $pathInfo;
    }

    /**
     * Initializes HTTP request formats.
     */
    protected static function initializeFormats()
    {
        static::$formats = [
            'html' => ['text/html', 'application/xhtml+xml'],
            'txt' => ['text/plain'],
            'js' => ['application/javascript', 'application/x-javascript', 'text/javascript'],
            'css' => ['text/css'],
            'json' => ['application/json', 'application/x-json'],
            'jsonld' => ['application/ld+json'],
            'xml' => ['text/xml', 'application/xml', 'application/x-xml'],
            'rdf' => ['application/rdf+xml'],
            'atom' => ['application/atom+xml'],
            'rss' => ['application/rss+xml'],
            'form' => ['application/x-www-form-urlencoded'],
        ];
    }

    private function setPhpDefaultLocale(string $locale): void
    {
        // if either the class Locale doesn't exist, or an exception is thrown when
        // setting the default locale, the intl module is not installed, and
        // the call can be ignored:
        try {
            if (class_exists(\Locale::class, false)) {
                \Locale::setDefault($locale);
            }
        } catch (\Exception $e) {
        }
    }

    /**
     * Returns the prefix as encoded in the string when the string starts with
     * the given prefix, null otherwise.
     */
    private function getUrlencodedPrefix(string $string, string $prefix): ?string
    {
        if (!str_starts_with(rawurldecode($string), $prefix)) {
            return null;
        }

        $len = \strlen($prefix);

        if (preg_match(sprintf('#^(%%[[:xdigit:]]{2}|.){%d}#', $len), $string, $match)) {
            return $match[0];
        }

        return null;
    }

    private static function createRequestFromFactory(array $query = [], array $request = [], array $attributes = [], array $cookies = [], array $files = [], array $server = [], $content = null): self
    {
        if (self::$requestFactory) {
            $request = (self::$requestFactory)($query, $request, $attributes, $cookies, $files, $server, $content);

            if (!$request instanceof self) {
                throw new \LogicException('The Request factory must return an instance of Symfony\Component\HttpFoundation\Request.');
            }

            return $request;
        }

        return new static($query, $request, $attributes, $cookies, $files, $server, $content);
    }

    /**
     * Indicates whether this request originated from a trusted proxy.
     *
     * This can be useful to determine whether or not to trust the
     * contents of a proxy-specific header.
     *
     * @return bool true if the request came from a trusted proxy, false otherwise
     */
    public function isFromTrustedProxy()
    {
        return self::$trustedProxies && IpUtils::checkIp($this->server->get('REMOTE_ADDR', ''), self::$trustedProxies);
    }

    private function getTrustedValues(int $type, string $ip = null): array
    {
        $clientValues = [];
        $forwardedValues = [];

        if ((self::$trustedHeaderSet & $type) && $this->headers->has(self::TRUSTED_HEADERS[$type])) {
            foreach (explode(',', $this->headers->get(self::TRUSTED_HEADERS[$type])) as $v) {
                $clientValues[] = (self::HEADER_X_FORWARDED_PORT === $type ? '0.0.0.0:' : '').trim($v);
            }
        }

        if ((self::$trustedHeaderSet & self::HEADER_FORWARDED) && (isset(self::FORWARDED_PARAMS[$type])) && $this->headers->has(self::TRUSTED_HEADERS[self::HEADER_FORWARDED])) {
            $forwarded = $this->headers->get(self::TRUSTED_HEADERS[self::HEADER_FORWARDED]);
            $parts = HeaderUtils::split($forwarded, ',;=');
            $forwardedValues = [];
            $param = self::FORWARDED_PARAMS[$type];
            foreach ($parts as $subParts) {
                if (null === $v = HeaderUtils::combine($subParts)[$param] ?? null) {
                    continue;
                }
                if (self::HEADER_X_FORWARDED_PORT === $type) {
                    if (str_ends_with($v, ']') || false === $v = strrchr($v, ':')) {
                        $v = $this->isSecure() ? ':443' : ':80';
                    }
                    $v = '0.0.0.0'.$v;
                }
                $forwardedValues[] = $v;
            }
        }

        if (null !== $ip) {
            $clientValues = $this->normalizeAndFilterClientIps($clientValues, $ip);
            $forwardedValues = $this->normalizeAndFilterClientIps($forwardedValues, $ip);
        }

        if ($forwardedValues === $clientValues || !$clientValues) {
            return $forwardedValues;
        }

        if (!$forwardedValues) {
            return $clientValues;
        }

        if (!$this->isForwardedValid) {
            return null !== $ip ? ['0.0.0.0', $ip] : [];
        }
        $this->isForwardedValid = false;

        throw new ConflictingHeadersException(sprintf('The request has both a trusted "%s" header and a trusted "%s" header, conflicting with each other. You should either configure your proxy to remove one of them, or configure your project to distrust the offending one.', self::TRUSTED_HEADERS[self::HEADER_FORWARDED], self::TRUSTED_HEADERS[$type]));
    }

    private function normalizeAndFilterClientIps(array $clientIps, string $ip): array
    {
        if (!$clientIps) {
            return [];
        }
        $clientIps[] = $ip; // Complete the IP chain with the IP the request actually came from
        $firstTrustedIp = null;

        foreach ($clientIps as $key => $clientIp) {
            if (strpos($clientIp, '.')) {
                // Strip :port from IPv4 addresses. This is allowed in Forwarded
                // and may occur in X-Forwarded-For.
                $i = strpos($clientIp, ':');
                if ($i) {
                    $clientIps[$key] = $clientIp = substr($clientIp, 0, $i);
                }
            } elseif (str_starts_with($clientIp, '[')) {
                // Strip brackets and :port from IPv6 addresses.
                $i = strpos($clientIp, ']', 1);
                $clientIps[$key] = $clientIp = substr($clientIp, 1, $i - 1);
            }

            if (!filter_var($clientIp, \FILTER_VALIDATE_IP)) {
                unset($clientIps[$key]);

                continue;
            }

            if (IpUtils::checkIp($clientIp, self::$trustedProxies)) {
                unset($clientIps[$key]);

                // Fallback to this when the client IP falls into the range of trusted proxies
                if (null === $firstTrustedIp) {
                    $firstTrustedIp = $clientIp;
                }
            }
        }

        // Now the IP chain contains only untrusted proxies and the client IP
        return $clientIps ? array_reverse($clientIps) : [$firstTrustedIp];
    }
}
PKϤ$Z'_.79http-foundation/Exception/ConflictingHeadersException.phpnu�[���<?php

/*
 * This file is part of the Symfony package.
 *
 * (c) Fabien Potencier <fabien@symfony.com>
 *
 * For the full copyright and license information, please view the LICENSE
 * file that was distributed with this source code.
 */

namespace Symfony\Component\HttpFoundation\Exception;

/**
 * The HTTP request contains headers with conflicting information.
 *
 * @author Magnus Nordlander <magnus@fervo.se>
 */
class ConflictingHeadersException extends \UnexpectedValueException implements RequestExceptionInterface
{
}
PKϤ$Za7�:http-foundation/Exception/SuspiciousOperationException.phpnu�[���<?php

/*
 * This file is part of the Symfony package.
 *
 * (c) Fabien Potencier <fabien@symfony.com>
 *
 * For the full copyright and license information, please view the LICENSE
 * file that was distributed with this source code.
 */

namespace Symfony\Component\HttpFoundation\Exception;

/**
 * Raised when a user has performed an operation that should be considered
 * suspicious from a security perspective.
 */
class SuspiciousOperationException extends \UnexpectedValueException implements RequestExceptionInterface
{
}
PKϤ$Z���+http-foundation/Exception/JsonException.phpnu�[���<?php

/*
 * This file is part of the Symfony package.
 *
 * (c) Fabien Potencier <fabien@symfony.com>
 *
 * For the full copyright and license information, please view the LICENSE
 * file that was distributed with this source code.
 */

namespace Symfony\Component\HttpFoundation\Exception;

/**
 * Thrown by Request::toArray() when the content cannot be JSON-decoded.
 *
 * @author Tobias Nyholm <tobias.nyholm@gmail.com>
 */
final class JsonException extends \UnexpectedValueException implements RequestExceptionInterface
{
}
PKϤ$Z"37��7http-foundation/Exception/RequestExceptionInterface.phpnu�[���<?php

/*
 * This file is part of the Symfony package.
 *
 * (c) Fabien Potencier <fabien@symfony.com>
 *
 * For the full copyright and license information, please view the LICENSE
 * file that was distributed with this source code.
 */

namespace Symfony\Component\HttpFoundation\Exception;

/**
 * Interface for Request exceptions.
 *
 * Exceptions implementing this interface should trigger an HTTP 400 response in the application code.
 */
interface RequestExceptionInterface
{
}
PKϤ$Zk&�gKK6http-foundation/Exception/SessionNotFoundException.phpnu�[���<?php

/*
 * This file is part of the Symfony package.
 *
 * (c) Fabien Potencier <fabien@symfony.com>
 *
 * For the full copyright and license information, please view the LICENSE
 * file that was distributed with this source code.
 */

namespace Symfony\Component\HttpFoundation\Exception;

/**
 * Raised when a session does not exists. This happens in the following cases:
 * - the session is not enabled
 * - attempt to read a session outside a request context (ie. cli script).
 *
 * @author Jérémy Derussé <jeremy@derusse.com>
 */
class SessionNotFoundException extends \LogicException implements RequestExceptionInterface
{
    public function __construct(string $message = 'There is currently no session available.', int $code = 0, \Throwable $previous = null)
    {
        parent::__construct($message, $code, $previous);
    }
}
PKϤ$Z,l���1http-foundation/Exception/BadRequestException.phpnu�[���<?php

/*
 * This file is part of the Symfony package.
 *
 * (c) Fabien Potencier <fabien@symfony.com>
 *
 * For the full copyright and license information, please view the LICENSE
 * file that was distributed with this source code.
 */

namespace Symfony\Component\HttpFoundation\Exception;

/**
 * Raised when a user sends a malformed request.
 */
class BadRequestException extends \UnexpectedValueException implements RequestExceptionInterface
{
}
PKϤ$Z��F��;�;http-foundation/CHANGELOG.mdnu�[���CHANGELOG
=========

5.3
---

 * Add the `SessionFactory`, `NativeSessionStorageFactory`, `PhpBridgeSessionStorageFactory` and `MockFileSessionStorageFactory` classes
 * Calling `Request::getSession()` when there is no available session throws a `SessionNotFoundException`
 * Add the `RequestStack::getSession` method
 * Deprecate the `NamespacedAttributeBag` class
 * Add `ResponseFormatSame` PHPUnit constraint
 * Deprecate the `RequestStack::getMasterRequest()` method and add `getMainRequest()` as replacement

5.2.0
-----

 * added support for `X-Forwarded-Prefix` header
 * added `HeaderUtils::parseQuery()`: it does the same as `parse_str()` but preserves dots in variable names
 * added `File::getContent()`
 * added ability to use comma separated ip addresses for `RequestMatcher::matchIps()`
 * added `Request::toArray()` to parse a JSON request body to an array
 * added `RateLimiter\RequestRateLimiterInterface` and `RateLimiter\AbstractRequestRateLimiter`
 * deprecated not passing a `Closure` together with `FILTER_CALLBACK` to `ParameterBag::filter()`; wrap your filter in a closure instead.
 * Deprecated the `Request::HEADER_X_FORWARDED_ALL` constant, use either `HEADER_X_FORWARDED_FOR | HEADER_X_FORWARDED_HOST | HEADER_X_FORWARDED_PORT | HEADER_X_FORWARDED_PROTO` or `HEADER_X_FORWARDED_AWS_ELB` or `HEADER_X_FORWARDED_TRAEFIK` constants instead.
 * Deprecated `BinaryFileResponse::create()`, use `__construct()` instead

5.1.0
-----

 * added `Cookie::withValue`, `Cookie::withDomain`, `Cookie::withExpires`,
   `Cookie::withPath`, `Cookie::withSecure`, `Cookie::withHttpOnly`,
   `Cookie::withRaw`, `Cookie::withSameSite`
 * Deprecate `Response::create()`, `JsonResponse::create()`,
   `RedirectResponse::create()`, and `StreamedResponse::create()` methods (use
   `__construct()` instead)
 * added `Request::preferSafeContent()` and `Response::setContentSafe()` to handle "safe" HTTP preference
   according to [RFC 8674](https://tools.ietf.org/html/rfc8674)
 * made the Mime component an optional dependency
 * added `MarshallingSessionHandler`, `IdentityMarshaller`
 * made `Session` accept a callback to report when the session is being used
 * Add support for all core cache control directives
 * Added `Symfony\Component\HttpFoundation\InputBag`
 * Deprecated retrieving non-string values using `InputBag::get()`, use `InputBag::all()` if you need access to the collection of values

5.0.0
-----

 * made `Cookie` auto-secure and lax by default
 * removed classes in the `MimeType` namespace, use the Symfony Mime component instead
 * removed method `UploadedFile::getClientSize()` and the related constructor argument
 * made `Request::getSession()` throw if the session has not been set before
 * removed `Response::HTTP_RESERVED_FOR_WEBDAV_ADVANCED_COLLECTIONS_EXPIRED_PROPOSAL`
 * passing a null url when instantiating a `RedirectResponse` is not allowed

4.4.0
-----

 * passing arguments to `Request::isMethodSafe()` is deprecated.
 * `ApacheRequest` is deprecated, use the `Request` class instead.
 * passing a third argument to `HeaderBag::get()` is deprecated, use method `all()` instead
 * [BC BREAK] `PdoSessionHandler` with MySQL changed the type of the lifetime column,
   make sure to run `ALTER TABLE sessions MODIFY sess_lifetime INTEGER UNSIGNED NOT NULL` to
   update your database.
 * `PdoSessionHandler` now precalculates the expiry timestamp in the lifetime column,
    make sure to run `CREATE INDEX EXPIRY ON sessions (sess_lifetime)` to update your database
    to speed up garbage collection of expired sessions.
 * added `SessionHandlerFactory` to create session handlers with a DSN
 * added `IpUtils::anonymize()` to help with GDPR compliance.

4.3.0
-----

 * added PHPUnit constraints: `RequestAttributeValueSame`, `ResponseCookieValueSame`, `ResponseHasCookie`,
   `ResponseHasHeader`, `ResponseHeaderSame`, `ResponseIsRedirected`, `ResponseIsSuccessful`, and `ResponseStatusCodeSame`
 * deprecated `MimeTypeGuesserInterface` and `ExtensionGuesserInterface` in favor of `Symfony\Component\Mime\MimeTypesInterface`.
 * deprecated `MimeType` and `MimeTypeExtensionGuesser` in favor of `Symfony\Component\Mime\MimeTypes`.
 * deprecated `FileBinaryMimeTypeGuesser` in favor of `Symfony\Component\Mime\FileBinaryMimeTypeGuesser`.
 * deprecated `FileinfoMimeTypeGuesser` in favor of `Symfony\Component\Mime\FileinfoMimeTypeGuesser`.
 * added `UrlHelper` that allows to get an absolute URL and a relative path for a given path

4.2.0
-----

 * the default value of the "$secure" and "$samesite" arguments of Cookie's constructor
   will respectively change from "false" to "null" and from "null" to "lax" in Symfony
   5.0, you should define their values explicitly or use "Cookie::create()" instead.
 * added `matchPort()` in RequestMatcher

4.1.3
-----

 * [BC BREAK] Support for the IIS-only `X_ORIGINAL_URL` and `X_REWRITE_URL`
   HTTP headers has been dropped for security reasons.

4.1.0
-----

 * Query string normalization uses `parse_str()` instead of custom parsing logic.
 * Passing the file size to the constructor of the `UploadedFile` class is deprecated.
 * The `getClientSize()` method of the `UploadedFile` class is deprecated. Use `getSize()` instead.
 * added `RedisSessionHandler` to use Redis as a session storage
 * The `get()` method of the `AcceptHeader` class now takes into account the
   `*` and `*/*` default values (if they are present in the Accept HTTP header)
   when looking for items.
 * deprecated `Request::getSession()` when no session has been set. Use `Request::hasSession()` instead.
 * added `CannotWriteFileException`, `ExtensionFileException`, `FormSizeFileException`,
   `IniSizeFileException`, `NoFileException`, `NoTmpDirFileException`, `PartialFileException` to
   handle failed `UploadedFile`.
 * added `MigratingSessionHandler` for migrating between two session handlers without losing sessions
 * added `HeaderUtils`.

4.0.0
-----

 * the `Request::setTrustedHeaderName()` and `Request::getTrustedHeaderName()`
   methods have been removed
 * the `Request::HEADER_CLIENT_IP` constant has been removed, use
   `Request::HEADER_X_FORWARDED_FOR` instead
 * the `Request::HEADER_CLIENT_HOST` constant has been removed, use
   `Request::HEADER_X_FORWARDED_HOST` instead
 * the `Request::HEADER_CLIENT_PROTO` constant has been removed, use
   `Request::HEADER_X_FORWARDED_PROTO` instead
 * the `Request::HEADER_CLIENT_PORT` constant has been removed, use
   `Request::HEADER_X_FORWARDED_PORT` instead
 * checking for cacheable HTTP methods using the `Request::isMethodSafe()`
   method (by not passing `false` as its argument) is not supported anymore and
   throws a `\BadMethodCallException`
 * the `WriteCheckSessionHandler`, `NativeSessionHandler` and `NativeProxy` classes have been removed
 * setting session save handlers that do not implement `\SessionHandlerInterface` in
   `NativeSessionStorage::setSaveHandler()` is not supported anymore and throws a
   `\TypeError`

3.4.0
-----

 * implemented PHP 7.0's `SessionUpdateTimestampHandlerInterface` with a new
   `AbstractSessionHandler` base class and a new `StrictSessionHandler` wrapper
 * deprecated the `WriteCheckSessionHandler`, `NativeSessionHandler` and `NativeProxy` classes
 * deprecated setting session save handlers that do not implement `\SessionHandlerInterface` in `NativeSessionStorage::setSaveHandler()`
 * deprecated using `MongoDbSessionHandler` with the legacy mongo extension; use it with the mongodb/mongodb package and ext-mongodb instead
 * deprecated `MemcacheSessionHandler`; use `MemcachedSessionHandler` instead

3.3.0
-----

 * the `Request::setTrustedProxies()` method takes a new `$trustedHeaderSet` argument,
   see https://symfony.com/doc/current/deployment/proxies.html for more info,
 * deprecated the `Request::setTrustedHeaderName()` and `Request::getTrustedHeaderName()` methods,
 * added `File\Stream`, to be passed to `BinaryFileResponse` when the size of the served file is unknown,
   disabling `Range` and `Content-Length` handling, switching to chunked encoding instead
 * added the `Cookie::fromString()` method that allows to create a cookie from a
   raw header string

3.1.0
-----

 * Added support for creating `JsonResponse` with a string of JSON data

3.0.0
-----

 * The precedence of parameters returned from `Request::get()` changed from "GET, PATH, BODY" to "PATH, GET, BODY"

2.8.0
-----

 * Finding deep items in `ParameterBag::get()` is deprecated since version 2.8 and
   will be removed in 3.0.

2.6.0
-----

 * PdoSessionHandler changes
   - implemented different session locking strategies to prevent loss of data by concurrent access to the same session
   - [BC BREAK] save session data in a binary column without base64_encode
   - [BC BREAK] added lifetime column to the session table which allows to have different lifetimes for each session
   - implemented lazy connections that are only opened when a session is used by either passing a dsn string
     explicitly or falling back to session.save_path ini setting
   - added a createTable method that initializes a correctly defined table depending on the database vendor

2.5.0
-----

 * added `JsonResponse::setEncodingOptions()` & `JsonResponse::getEncodingOptions()` for easier manipulation
   of the options used while encoding data to JSON format.

2.4.0
-----

 * added RequestStack
 * added Request::getEncodings()
 * added accessors methods to session handlers

2.3.0
-----

 * added support for ranges of IPs in trusted proxies
 * `UploadedFile::isValid` now returns false if the file was not uploaded via HTTP (in a non-test mode)
 * Improved error-handling of `\Symfony\Component\HttpFoundation\Session\Storage\Handler\PdoSessionHandler`
   to ensure the supplied PDO handler throws Exceptions on error (as the class expects). Added related test cases
   to verify that Exceptions are properly thrown when the PDO queries fail.

2.2.0
-----

 * fixed the Request::create() precedence (URI information always take precedence now)
 * added Request::getTrustedProxies()
 * deprecated Request::isProxyTrusted()
 * [BC BREAK] JsonResponse does not turn a top level empty array to an object anymore, use an ArrayObject to enforce objects
 * added a IpUtils class to check if an IP belongs to a CIDR
 * added Request::getRealMethod() to get the "real" HTTP method (getMethod() returns the "intended" HTTP method)
 * disabled _method request parameter support by default (call Request::enableHttpMethodParameterOverride() to
   enable it, and Request::getHttpMethodParameterOverride() to check if it is supported)
 * Request::splitHttpAcceptHeader() method is deprecated and will be removed in 2.3
 * Deprecated Flashbag::count() and \Countable interface, will be removed in 2.3

2.1.0
-----

 * added Request::getSchemeAndHttpHost() and Request::getUserInfo()
 * added a fluent interface to the Response class
 * added Request::isProxyTrusted()
 * added JsonResponse
 * added a getTargetUrl method to RedirectResponse
 * added support for streamed responses
 * made Response::prepare() method the place to enforce HTTP specification
 * [BC BREAK] moved management of the locale from the Session class to the Request class
 * added a generic access to the PHP built-in filter mechanism: ParameterBag::filter()
 * made FileBinaryMimeTypeGuesser command configurable
 * added Request::getUser() and Request::getPassword()
 * added support for the PATCH method in Request
 * removed the ContentTypeMimeTypeGuesser class as it is deprecated and never used on PHP 5.3
 * added ResponseHeaderBag::makeDisposition() (implements RFC 6266)
 * made mimetype to extension conversion configurable
 * [BC BREAK] Moved all session related classes and interfaces into own namespace, as
   `Symfony\Component\HttpFoundation\Session` and renamed classes accordingly.
   Session handlers are located in the subnamespace `Symfony\Component\HttpFoundation\Session\Handler`.
 * SessionHandlers must implement `\SessionHandlerInterface` or extend from the
   `Symfony\Component\HttpFoundation\Storage\Handler\NativeSessionHandler` base class.
 * Added internal storage driver proxy mechanism for forward compatibility with
   PHP 5.4 `\SessionHandler` class.
 * Added session handlers for custom Memcache, Memcached and Null session save handlers.
 * [BC BREAK] Removed `NativeSessionStorage` and replaced with `NativeFileSessionHandler`.
 * [BC BREAK] `SessionStorageInterface` methods removed: `write()`, `read()` and
   `remove()`.  Added `getBag()`, `registerBag()`.  The `NativeSessionStorage` class
   is a mediator for the session storage internals including the session handlers
   which do the real work of participating in the internal PHP session workflow.
 * [BC BREAK] Introduced mock implementations of `SessionStorage` to enable unit
   and functional testing without starting real PHP sessions.  Removed
   `ArraySessionStorage`, and replaced with `MockArraySessionStorage` for unit
   tests; removed `FilesystemSessionStorage`, and replaced with`MockFileSessionStorage`
   for functional tests.  These do not interact with global session ini
   configuration values, session functions or `$_SESSION` superglobal. This means
   they can be configured directly allowing multiple instances to work without
   conflicting in the same PHP process.
 * [BC BREAK] Removed the `close()` method from the `Session` class, as this is
   now redundant.
 * Deprecated the following methods from the Session class: `setFlash()`, `setFlashes()`
   `getFlash()`, `hasFlash()`, and `removeFlash()`. Use `getFlashBag()` instead
   which returns a `FlashBagInterface`.
 * `Session->clear()` now only clears session attributes as before it cleared
   flash messages and attributes. `Session->getFlashBag()->all()` clears flashes now.
 * Session data is now managed by `SessionBagInterface` to better encapsulate
   session data.
 * Refactored session attribute and flash messages system to their own
  `SessionBagInterface` implementations.
 * Added `FlashBag`. Flashes expire when retrieved by `get()` or `all()`. This
   implementation is ESI compatible.
 * Added `AutoExpireFlashBag` (default) to replicate Symfony 2.0.x auto expire
   behavior of messages auto expiring after one page page load.  Messages must
   be retrieved by `get()` or `all()`.
 * Added `Symfony\Component\HttpFoundation\Attribute\AttributeBag` to replicate
   attributes storage behavior from 2.0.x (default).
 * Added `Symfony\Component\HttpFoundation\Attribute\NamespacedAttributeBag` for
   namespace session attributes.
 * Flash API can stores messages in an array so there may be multiple messages
   per flash type.  The old `Session` class API remains without BC break as it
   will allow single messages as before.
 * Added basic session meta-data to the session to record session create time,
   last updated time, and the lifetime of the session cookie that was provided
   to the client.
 * Request::getClientIp() method doesn't take a parameter anymore but bases
   itself on the trustProxy parameter.
 * Added isMethod() to Request object.
 * [BC BREAK] The methods `getPathInfo()`, `getBaseUrl()` and `getBasePath()` of
   a `Request` now all return a raw value (vs a urldecoded value before). Any call
   to one of these methods must be checked and wrapped in a `rawurldecode()` if
   needed.
PKϤ$Z�7�0$http-foundation/RedirectResponse.phpnu�[���<?php

/*
 * This file is part of the Symfony package.
 *
 * (c) Fabien Potencier <fabien@symfony.com>
 *
 * For the full copyright and license information, please view the LICENSE
 * file that was distributed with this source code.
 */

namespace Symfony\Component\HttpFoundation;

/**
 * RedirectResponse represents an HTTP response doing a redirect.
 *
 * @author Fabien Potencier <fabien@symfony.com>
 */
class RedirectResponse extends Response
{
    protected $targetUrl;

    /**
     * Creates a redirect response so that it conforms to the rules defined for a redirect status code.
     *
     * @param string $url     The URL to redirect to. The URL should be a full URL, with schema etc.,
     *                        but practically every browser redirects on paths only as well
     * @param int    $status  The status code (302 by default)
     * @param array  $headers The headers (Location is always set to the given URL)
     *
     * @throws \InvalidArgumentException
     *
     * @see https://tools.ietf.org/html/rfc2616#section-10.3
     */
    public function __construct(string $url, int $status = 302, array $headers = [])
    {
        parent::__construct('', $status, $headers);

        $this->setTargetUrl($url);

        if (!$this->isRedirect()) {
            throw new \InvalidArgumentException(sprintf('The HTTP status code is not a redirect ("%s" given).', $status));
        }

        if (301 == $status && !\array_key_exists('cache-control', array_change_key_case($headers, \CASE_LOWER))) {
            $this->headers->remove('cache-control');
        }
    }

    /**
     * Factory method for chainability.
     *
     * @param string $url The URL to redirect to
     *
     * @return static
     *
     * @deprecated since Symfony 5.1, use __construct() instead.
     */
    public static function create($url = '', int $status = 302, array $headers = [])
    {
        trigger_deprecation('symfony/http-foundation', '5.1', 'The "%s()" method is deprecated, use "new %s()" instead.', __METHOD__, static::class);

        return new static($url, $status, $headers);
    }

    /**
     * Returns the target URL.
     *
     * @return string target URL
     */
    public function getTargetUrl()
    {
        return $this->targetUrl;
    }

    /**
     * Sets the redirect target of this response.
     *
     * @return $this
     *
     * @throws \InvalidArgumentException
     */
    public function setTargetUrl(string $url)
    {
        if ('' === $url) {
            throw new \InvalidArgumentException('Cannot redirect to an empty URL.');
        }

        $this->targetUrl = $url;

        $this->setContent(
            sprintf('<!DOCTYPE html>
<html>
    <head>
        <meta charset="UTF-8" />
        <meta http-equiv="refresh" content="0;url=\'%1$s\'" />

        <title>Redirecting to %1$s</title>
    </head>
    <body>
        Redirecting to <a href="%1$s">%1$s</a>.
    </body>
</html>', htmlspecialchars($url, \ENT_QUOTES, 'UTF-8')));

        $this->headers->set('Location', $url);

        return $this;
    }
}
PKϤ$Z}��
77 http-foundation/AcceptHeader.phpnu�[���<?php

/*
 * This file is part of the Symfony package.
 *
 * (c) Fabien Potencier <fabien@symfony.com>
 *
 * For the full copyright and license information, please view the LICENSE
 * file that was distributed with this source code.
 */

namespace Symfony\Component\HttpFoundation;

// Help opcache.preload discover always-needed symbols
class_exists(AcceptHeaderItem::class);

/**
 * Represents an Accept-* header.
 *
 * An accept header is compound with a list of items,
 * sorted by descending quality.
 *
 * @author Jean-François Simon <contact@jfsimon.fr>
 */
class AcceptHeader
{
    /**
     * @var AcceptHeaderItem[]
     */
    private $items = [];

    /**
     * @var bool
     */
    private $sorted = true;

    /**
     * @param AcceptHeaderItem[] $items
     */
    public function __construct(array $items)
    {
        foreach ($items as $item) {
            $this->add($item);
        }
    }

    /**
     * Builds an AcceptHeader instance from a string.
     *
     * @return self
     */
    public static function fromString(?string $headerValue)
    {
        $index = 0;

        $parts = HeaderUtils::split($headerValue ?? '', ',;=');

        return new self(array_map(function ($subParts) use (&$index) {
            $part = array_shift($subParts);
            $attributes = HeaderUtils::combine($subParts);

            $item = new AcceptHeaderItem($part[0], $attributes);
            $item->setIndex($index++);

            return $item;
        }, $parts));
    }

    /**
     * Returns header value's string representation.
     *
     * @return string
     */
    public function __toString()
    {
        return implode(',', $this->items);
    }

    /**
     * Tests if header has given value.
     *
     * @return bool
     */
    public function has(string $value)
    {
        return isset($this->items[$value]);
    }

    /**
     * Returns given value's item, if exists.
     *
     * @return AcceptHeaderItem|null
     */
    public function get(string $value)
    {
        return $this->items[$value] ?? $this->items[explode('/', $value)[0].'/*'] ?? $this->items['*/*'] ?? $this->items['*'] ?? null;
    }

    /**
     * Adds an item.
     *
     * @return $this
     */
    public function add(AcceptHeaderItem $item)
    {
        $this->items[$item->getValue()] = $item;
        $this->sorted = false;

        return $this;
    }

    /**
     * Returns all items.
     *
     * @return AcceptHeaderItem[]
     */
    public function all()
    {
        $this->sort();

        return $this->items;
    }

    /**
     * Filters items on their value using given regex.
     *
     * @return self
     */
    public function filter(string $pattern)
    {
        return new self(array_filter($this->items, function (AcceptHeaderItem $item) use ($pattern) {
            return preg_match($pattern, $item->getValue());
        }));
    }

    /**
     * Returns first item.
     *
     * @return AcceptHeaderItem|null
     */
    public function first()
    {
        $this->sort();

        return !empty($this->items) ? reset($this->items) : null;
    }

    /**
     * Sorts items by descending quality.
     */
    private function sort(): void
    {
        if (!$this->sorted) {
            uasort($this->items, function (AcceptHeaderItem $a, AcceptHeaderItem $b) {
                $qA = $a->getQuality();
                $qB = $b->getQuality();

                if ($qA === $qB) {
                    return $a->getIndex() > $b->getIndex() ? 1 : -1;
                }

                return $qA > $qB ? -1 : 1;
            });

            $this->sorted = true;
        }
    }
}
PKϤ$Z�
��))http-foundation/LICENSEnu�[���Copyright (c) 2004-2021 Fabien Potencier

Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is furnished
to do so, subject to the following conditions:

The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.

THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
THE SOFTWARE.
PKϤ$Z�`!-�� http-foundation/JsonResponse.phpnu�[���<?php

/*
 * This file is part of the Symfony package.
 *
 * (c) Fabien Potencier <fabien@symfony.com>
 *
 * For the full copyright and license information, please view the LICENSE
 * file that was distributed with this source code.
 */

namespace Symfony\Component\HttpFoundation;

/**
 * Response represents an HTTP response in JSON format.
 *
 * Note that this class does not force the returned JSON content to be an
 * object. It is however recommended that you do return an object as it
 * protects yourself against XSSI and JSON-JavaScript Hijacking.
 *
 * @see https://github.com/OWASP/CheatSheetSeries/blob/master/cheatsheets/AJAX_Security_Cheat_Sheet.md#always-return-json-with-an-object-on-the-outside
 *
 * @author Igor Wiedler <igor@wiedler.ch>
 */
class JsonResponse extends Response
{
    protected $data;
    protected $callback;

    // Encode <, >, ', &, and " characters in the JSON, making it also safe to be embedded into HTML.
    // 15 === JSON_HEX_TAG | JSON_HEX_APOS | JSON_HEX_AMP | JSON_HEX_QUOT
    public const DEFAULT_ENCODING_OPTIONS = 15;

    protected $encodingOptions = self::DEFAULT_ENCODING_OPTIONS;

    /**
     * @param mixed $data    The response data
     * @param int   $status  The response status code
     * @param array $headers An array of response headers
     * @param bool  $json    If the data is already a JSON string
     */
    public function __construct($data = null, int $status = 200, array $headers = [], bool $json = false)
    {
        parent::__construct('', $status, $headers);

        if ($json && !\is_string($data) && !is_numeric($data) && !\is_callable([$data, '__toString'])) {
            throw new \TypeError(sprintf('"%s": If $json is set to true, argument $data must be a string or object implementing __toString(), "%s" given.', __METHOD__, get_debug_type($data)));
        }

        if (null === $data) {
            $data = new \ArrayObject();
        }

        $json ? $this->setJson($data) : $this->setData($data);
    }

    /**
     * Factory method for chainability.
     *
     * Example:
     *
     *     return JsonResponse::create(['key' => 'value'])
     *         ->setSharedMaxAge(300);
     *
     * @param mixed $data    The JSON response data
     * @param int   $status  The response status code
     * @param array $headers An array of response headers
     *
     * @return static
     *
     * @deprecated since Symfony 5.1, use __construct() instead.
     */
    public static function create($data = null, int $status = 200, array $headers = [])
    {
        trigger_deprecation('symfony/http-foundation', '5.1', 'The "%s()" method is deprecated, use "new %s()" instead.', __METHOD__, static::class);

        return new static($data, $status, $headers);
    }

    /**
     * Factory method for chainability.
     *
     * Example:
     *
     *     return JsonResponse::fromJsonString('{"key": "value"}')
     *         ->setSharedMaxAge(300);
     *
     * @param string $data    The JSON response string
     * @param int    $status  The response status code
     * @param array  $headers An array of response headers
     *
     * @return static
     */
    public static function fromJsonString(string $data, int $status = 200, array $headers = [])
    {
        return new static($data, $status, $headers, true);
    }

    /**
     * Sets the JSONP callback.
     *
     * @param string|null $callback The JSONP callback or null to use none
     *
     * @return $this
     *
     * @throws \InvalidArgumentException When the callback name is not valid
     */
    public function setCallback(string $callback = null)
    {
        if (null !== $callback) {
            // partially taken from https://geekality.net/2011/08/03/valid-javascript-identifier/
            // partially taken from https://github.com/willdurand/JsonpCallbackValidator
            //      JsonpCallbackValidator is released under the MIT License. See https://github.com/willdurand/JsonpCallbackValidator/blob/v1.1.0/LICENSE for details.
            //      (c) William Durand <william.durand1@gmail.com>
            $pattern = '/^[$_\p{L}][$_\p{L}\p{Mn}\p{Mc}\p{Nd}\p{Pc}\x{200C}\x{200D}]*(?:\[(?:"(?:\\\.|[^"\\\])*"|\'(?:\\\.|[^\'\\\])*\'|\d+)\])*?$/u';
            $reserved = [
                'break', 'do', 'instanceof', 'typeof', 'case', 'else', 'new', 'var', 'catch', 'finally', 'return', 'void', 'continue', 'for', 'switch', 'while',
                'debugger', 'function', 'this', 'with', 'default', 'if', 'throw', 'delete', 'in', 'try', 'class', 'enum', 'extends', 'super',  'const', 'export',
                'import', 'implements', 'let', 'private', 'public', 'yield', 'interface', 'package', 'protected', 'static', 'null', 'true', 'false',
            ];
            $parts = explode('.', $callback);
            foreach ($parts as $part) {
                if (!preg_match($pattern, $part) || \in_array($part, $reserved, true)) {
                    throw new \InvalidArgumentException('The callback name is not valid.');
                }
            }
        }

        $this->callback = $callback;

        return $this->update();
    }

    /**
     * Sets a raw string containing a JSON document to be sent.
     *
     * @return $this
     */
    public function setJson(string $json)
    {
        $this->data = $json;

        return $this->update();
    }

    /**
     * Sets the data to be sent as JSON.
     *
     * @param mixed $data
     *
     * @return $this
     *
     * @throws \InvalidArgumentException
     */
    public function setData($data = [])
    {
        try {
            $data = json_encode($data, $this->encodingOptions);
        } catch (\Exception $e) {
            if ('Exception' === \get_class($e) && str_starts_with($e->getMessage(), 'Failed calling ')) {
                throw $e->getPrevious() ?: $e;
            }
            throw $e;
        }

        if (\PHP_VERSION_ID >= 70300 && (\JSON_THROW_ON_ERROR & $this->encodingOptions)) {
            return $this->setJson($data);
        }

        if (\JSON_ERROR_NONE !== json_last_error()) {
            throw new \InvalidArgumentException(json_last_error_msg());
        }

        return $this->setJson($data);
    }

    /**
     * Returns options used while encoding data to JSON.
     *
     * @return int
     */
    public function getEncodingOptions()
    {
        return $this->encodingOptions;
    }

    /**
     * Sets options used while encoding data to JSON.
     *
     * @return $this
     */
    public function setEncodingOptions(int $encodingOptions)
    {
        $this->encodingOptions = $encodingOptions;

        return $this->setData(json_decode($this->data));
    }

    /**
     * Updates the content and headers according to the JSON data and callback.
     *
     * @return $this
     */
    protected function update()
    {
        if (null !== $this->callback) {
            // Not using application/javascript for compatibility reasons with older browsers.
            $this->headers->set('Content-Type', 'text/javascript');

            return $this->setContent(sprintf('/**/%s(%s);', $this->callback, $this->data));
        }

        // Only set the header when there is none or when it equals 'text/javascript' (from a previous update with callback)
        // in order to not overwrite a custom definition.
        if (!$this->headers->has('Content-Type') || 'text/javascript' === $this->headers->get('Content-Type')) {
            $this->headers->set('Content-Type', 'application/json');
        }

        return $this->setContent($this->data);
    }
}
PKϤ$Z�)
NN http-foundation/RequestStack.phpnu�[���<?php

/*
 * This file is part of the Symfony package.
 *
 * (c) Fabien Potencier <fabien@symfony.com>
 *
 * For the full copyright and license information, please view the LICENSE
 * file that was distributed with this source code.
 */

namespace Symfony\Component\HttpFoundation;

use Symfony\Component\HttpFoundation\Exception\SessionNotFoundException;
use Symfony\Component\HttpFoundation\Session\SessionInterface;

/**
 * Request stack that controls the lifecycle of requests.
 *
 * @author Benjamin Eberlei <kontakt@beberlei.de>
 */
class RequestStack
{
    /**
     * @var Request[]
     */
    private $requests = [];

    /**
     * Pushes a Request on the stack.
     *
     * This method should generally not be called directly as the stack
     * management should be taken care of by the application itself.
     */
    public function push(Request $request)
    {
        $this->requests[] = $request;
    }

    /**
     * Pops the current request from the stack.
     *
     * This operation lets the current request go out of scope.
     *
     * This method should generally not be called directly as the stack
     * management should be taken care of by the application itself.
     *
     * @return Request|null
     */
    public function pop()
    {
        if (!$this->requests) {
            return null;
        }

        return array_pop($this->requests);
    }

    /**
     * @return Request|null
     */
    public function getCurrentRequest()
    {
        return end($this->requests) ?: null;
    }

    /**
     * Gets the main request.
     *
     * Be warned that making your code aware of the main request
     * might make it un-compatible with other features of your framework
     * like ESI support.
     */
    public function getMainRequest(): ?Request
    {
        if (!$this->requests) {
            return null;
        }

        return $this->requests[0];
    }

    /**
     * Gets the master request.
     *
     * @return Request|null
     *
     * @deprecated since symfony/http-foundation 5.3, use getMainRequest() instead
     */
    public function getMasterRequest()
    {
        trigger_deprecation('symfony/http-foundation', '5.3', '"%s()" is deprecated, use "getMainRequest()" instead.', __METHOD__);

        return $this->getMainRequest();
    }

    /**
     * Returns the parent request of the current.
     *
     * Be warned that making your code aware of the parent request
     * might make it un-compatible with other features of your framework
     * like ESI support.
     *
     * If current Request is the main request, it returns null.
     *
     * @return Request|null
     */
    public function getParentRequest()
    {
        $pos = \count($this->requests) - 2;

        return $this->requests[$pos] ?? null;
    }

    /**
     * Gets the current session.
     *
     * @throws SessionNotFoundException
     */
    public function getSession(): SessionInterface
    {
        if ((null !== $request = end($this->requests) ?: null) && $request->hasSession()) {
            return $request->getSession();
        }

        throw new SessionNotFoundException();
    }
}
PKϤ$Z�ǫ|JJ,http-foundation/ExpressionRequestMatcher.phpnu�[���<?php

/*
 * This file is part of the Symfony package.
 *
 * (c) Fabien Potencier <fabien@symfony.com>
 *
 * For the full copyright and license information, please view the LICENSE
 * file that was distributed with this source code.
 */

namespace Symfony\Component\HttpFoundation;

use Symfony\Component\ExpressionLanguage\ExpressionLanguage;

/**
 * ExpressionRequestMatcher uses an expression to match a Request.
 *
 * @author Fabien Potencier <fabien@symfony.com>
 */
class ExpressionRequestMatcher extends RequestMatcher
{
    private $language;
    private $expression;

    public function setExpression(ExpressionLanguage $language, $expression)
    {
        $this->language = $language;
        $this->expression = $expression;
    }

    public function matches(Request $request)
    {
        if (!$this->language) {
            throw new \LogicException('Unable to match the request as the expression language is not available.');
        }

        return $this->language->evaluate($this->expression, [
            'request' => $request,
            'method' => $request->getMethod(),
            'path' => rawurldecode($request->getPathInfo()),
            'host' => $request->getHost(),
            'ip' => $request->getClientIp(),
            'attributes' => $request->attributes->all(),
        ]) && parent::matches($request);
    }
}
PKϤ$ZXpa�

http-foundation/HeaderBag.phpnu�[���<?php

/*
 * This file is part of the Symfony package.
 *
 * (c) Fabien Potencier <fabien@symfony.com>
 *
 * For the full copyright and license information, please view the LICENSE
 * file that was distributed with this source code.
 */

namespace Symfony\Component\HttpFoundation;

/**
 * HeaderBag is a container for HTTP headers.
 *
 * @author Fabien Potencier <fabien@symfony.com>
 */
class HeaderBag implements \IteratorAggregate, \Countable
{
    protected const UPPER = '_ABCDEFGHIJKLMNOPQRSTUVWXYZ';
    protected const LOWER = '-abcdefghijklmnopqrstuvwxyz';

    protected $headers = [];
    protected $cacheControl = [];

    public function __construct(array $headers = [])
    {
        foreach ($headers as $key => $values) {
            $this->set($key, $values);
        }
    }

    /**
     * Returns the headers as a string.
     *
     * @return string The headers
     */
    public function __toString()
    {
        if (!$headers = $this->all()) {
            return '';
        }

        ksort($headers);
        $max = max(array_map('strlen', array_keys($headers))) + 1;
        $content = '';
        foreach ($headers as $name => $values) {
            $name = ucwords($name, '-');
            foreach ($values as $value) {
                $content .= sprintf("%-{$max}s %s\r\n", $name.':', $value);
            }
        }

        return $content;
    }

    /**
     * Returns the headers.
     *
     * @param string|null $key The name of the headers to return or null to get them all
     *
     * @return array An array of headers
     */
    public function all(string $key = null)
    {
        if (null !== $key) {
            return $this->headers[strtr($key, self::UPPER, self::LOWER)] ?? [];
        }

        return $this->headers;
    }

    /**
     * Returns the parameter keys.
     *
     * @return array An array of parameter keys
     */
    public function keys()
    {
        return array_keys($this->all());
    }

    /**
     * Replaces the current HTTP headers by a new set.
     */
    public function replace(array $headers = [])
    {
        $this->headers = [];
        $this->add($headers);
    }

    /**
     * Adds new headers the current HTTP headers set.
     */
    public function add(array $headers)
    {
        foreach ($headers as $key => $values) {
            $this->set($key, $values);
        }
    }

    /**
     * Returns a header value by name.
     *
     * @return string|null The first header value or default value
     */
    public function get(string $key, string $default = null)
    {
        $headers = $this->all($key);

        if (!$headers) {
            return $default;
        }

        if (null === $headers[0]) {
            return null;
        }

        return (string) $headers[0];
    }

    /**
     * Sets a header by name.
     *
     * @param string|string[]|null $values  The value or an array of values
     * @param bool                 $replace Whether to replace the actual value or not (true by default)
     */
    public function set(string $key, $values, bool $replace = true)
    {
        $key = strtr($key, self::UPPER, self::LOWER);

        if (\is_array($values)) {
            $values = array_values($values);

            if (true === $replace || !isset($this->headers[$key])) {
                $this->headers[$key] = $values;
            } else {
                $this->headers[$key] = array_merge($this->headers[$key], $values);
            }
        } else {
            if (true === $replace || !isset($this->headers[$key])) {
                $this->headers[$key] = [$values];
            } else {
                $this->headers[$key][] = $values;
            }
        }

        if ('cache-control' === $key) {
            $this->cacheControl = $this->parseCacheControl(implode(', ', $this->headers[$key]));
        }
    }

    /**
     * Returns true if the HTTP header is defined.
     *
     * @return bool true if the parameter exists, false otherwise
     */
    public function has(string $key)
    {
        return \array_key_exists(strtr($key, self::UPPER, self::LOWER), $this->all());
    }

    /**
     * Returns true if the given HTTP header contains the given value.
     *
     * @return bool true if the value is contained in the header, false otherwise
     */
    public function contains(string $key, string $value)
    {
        return \in_array($value, $this->all($key));
    }

    /**
     * Removes a header.
     */
    public function remove(string $key)
    {
        $key = strtr($key, self::UPPER, self::LOWER);

        unset($this->headers[$key]);

        if ('cache-control' === $key) {
            $this->cacheControl = [];
        }
    }

    /**
     * Returns the HTTP header value converted to a date.
     *
     * @return \DateTimeInterface|null The parsed DateTime or the default value if the header does not exist
     *
     * @throws \RuntimeException When the HTTP header is not parseable
     */
    public function getDate(string $key, \DateTime $default = null)
    {
        if (null === $value = $this->get($key)) {
            return $default;
        }

        if (false === $date = \DateTime::createFromFormat(\DATE_RFC2822, $value)) {
            throw new \RuntimeException(sprintf('The "%s" HTTP header is not parseable (%s).', $key, $value));
        }

        return $date;
    }

    /**
     * Adds a custom Cache-Control directive.
     *
     * @param bool|string $value The Cache-Control directive value
     */
    public function addCacheControlDirective(string $key, $value = true)
    {
        $this->cacheControl[$key] = $value;

        $this->set('Cache-Control', $this->getCacheControlHeader());
    }

    /**
     * Returns true if the Cache-Control directive is defined.
     *
     * @return bool true if the directive exists, false otherwise
     */
    public function hasCacheControlDirective(string $key)
    {
        return \array_key_exists($key, $this->cacheControl);
    }

    /**
     * Returns a Cache-Control directive value by name.
     *
     * @return bool|string|null The directive value if defined, null otherwise
     */
    public function getCacheControlDirective(string $key)
    {
        return $this->cacheControl[$key] ?? null;
    }

    /**
     * Removes a Cache-Control directive.
     */
    public function removeCacheControlDirective(string $key)
    {
        unset($this->cacheControl[$key]);

        $this->set('Cache-Control', $this->getCacheControlHeader());
    }

    /**
     * Returns an iterator for headers.
     *
     * @return \ArrayIterator An \ArrayIterator instance
     */
    #[\ReturnTypeWillChange]
    public function getIterator()
    {
        return new \ArrayIterator($this->headers);
    }

    /**
     * Returns the number of headers.
     *
     * @return int The number of headers
     */
    #[\ReturnTypeWillChange]
    public function count()
    {
        return \count($this->headers);
    }

    protected function getCacheControlHeader()
    {
        ksort($this->cacheControl);

        return HeaderUtils::toString($this->cacheControl, ',');
    }

    /**
     * Parses a Cache-Control HTTP header.
     *
     * @return array An array representing the attribute values
     */
    protected function parseCacheControl(string $header)
    {
        $parts = HeaderUtils::split($header, ',=');

        return HeaderUtils::combine($parts);
    }
}
PKϤ$Z3	�polyfill-php80/README.mdnu�[���Symfony Polyfill / Php80
========================

This component provides features added to PHP 8.0 core:

- `Stringable` interface
- [`fdiv`](https://php.net/fdiv)
- `ValueError` class
- `UnhandledMatchError` class
- `FILTER_VALIDATE_BOOL` constant
- [`get_debug_type`](https://php.net/get_debug_type)
- [`preg_last_error_msg`](https://php.net/preg_last_error_msg)
- [`str_contains`](https://php.net/str_contains)
- [`str_starts_with`](https://php.net/str_starts_with)
- [`str_ends_with`](https://php.net/str_ends_with)
- [`get_resource_id`](https://php.net/get_resource_id)

More information can be found in the
[main Polyfill README](https://github.com/symfony/polyfill/blob/master/README.md).

License
=======

This library is released under the [MIT license](LICENSE).
PKϤ$Zy4%336polyfill-php80/Resources/stubs/UnhandledMatchError.phpnu�[���<?php

class UnhandledMatchError extends Error
{
}
PKϤ$Z��7�hh-polyfill-php80/Resources/stubs/Stringable.phpnu�[���<?php

interface Stringable
{
    /**
     * @return string
     */
    public function __toString();
}
PKϤ$Z���***-polyfill-php80/Resources/stubs/ValueError.phpnu�[���<?php

class ValueError extends Error
{
}
PKϤ$Z��5-
-
polyfill-php80/Php80.phpnu�[���<?php

/*
 * This file is part of the Symfony package.
 *
 * (c) Fabien Potencier <fabien@symfony.com>
 *
 * For the full copyright and license information, please view the LICENSE
 * file that was distributed with this source code.
 */

namespace Symfony\Polyfill\Php80;

/**
 * @author Ion Bazan <ion.bazan@gmail.com>
 * @author Nico Oelgart <nicoswd@gmail.com>
 * @author Nicolas Grekas <p@tchwork.com>
 *
 * @internal
 */
final class Php80
{
    public static function fdiv(float $dividend, float $divisor): float
    {
        return @($dividend / $divisor);
    }

    public static function get_debug_type($value): string
    {
        switch (true) {
            case null === $value: return 'null';
            case \is_bool($value): return 'bool';
            case \is_string($value): return 'string';
            case \is_array($value): return 'array';
            case \is_int($value): return 'int';
            case \is_float($value): return 'float';
            case \is_object($value): break;
            case $value instanceof \__PHP_Incomplete_Class: return '__PHP_Incomplete_Class';
            default:
                if (null === $type = @get_resource_type($value)) {
                    return 'unknown';
                }

                if ('Unknown' === $type) {
                    $type = 'closed';
                }

                return "resource ($type)";
        }

        $class = \get_class($value);

        if (false === strpos($class, '@')) {
            return $class;
        }

        return (get_parent_class($class) ?: key(class_implements($class)) ?: 'class').'@anonymous';
    }

    public static function get_resource_id($res): int
    {
        if (!\is_resource($res) && null === @get_resource_type($res)) {
            throw new \TypeError(sprintf('Argument 1 passed to get_resource_id() must be of the type resource, %s given', get_debug_type($res)));
        }

        return (int) $res;
    }

    public static function preg_last_error_msg(): string
    {
        switch (preg_last_error()) {
            case PREG_INTERNAL_ERROR:
                return 'Internal error';
            case PREG_BAD_UTF8_ERROR:
                return 'Malformed UTF-8 characters, possibly incorrectly encoded';
            case PREG_BAD_UTF8_OFFSET_ERROR:
                return 'The offset did not correspond to the beginning of a valid UTF-8 code point';
            case PREG_BACKTRACK_LIMIT_ERROR:
                return 'Backtrack limit exhausted';
            case PREG_RECURSION_LIMIT_ERROR:
                return 'Recursion limit exhausted';
            case PREG_JIT_STACKLIMIT_ERROR:
                return 'JIT stack limit exhausted';
            case PREG_NO_ERROR:
                return 'No error';
            default:
                return 'Unknown error';
        }
    }

    public static function str_contains(string $haystack, string $needle): bool
    {
        return '' === $needle || false !== strpos($haystack, $needle);
    }

    public static function str_starts_with(string $haystack, string $needle): bool
    {
        return 0 === \strncmp($haystack, $needle, \strlen($needle));
    }

    public static function str_ends_with(string $haystack, string $needle): bool
    {
        return '' === $needle || ('' !== $haystack && 0 === \substr_compare($haystack, $needle, -\strlen($needle)));
    }
}
PKϤ$Zu�^"��polyfill-php80/bootstrap.phpnu�[���<?php

/*
 * This file is part of the Symfony package.
 *
 * (c) Fabien Potencier <fabien@symfony.com>
 *
 * For the full copyright and license information, please view the LICENSE
 * file that was distributed with this source code.
 */

use Symfony\Polyfill\Php80 as p;

if (PHP_VERSION_ID >= 80000) {
    return;
}

if (!defined('FILTER_VALIDATE_BOOL') && defined('FILTER_VALIDATE_BOOLEAN')) {
    define('FILTER_VALIDATE_BOOL', FILTER_VALIDATE_BOOLEAN);
}

if (!function_exists('fdiv')) {
    function fdiv(float $dividend, float $divisor): float { return p\Php80::fdiv($dividend, $divisor); }
}
if (!function_exists('preg_last_error_msg')) {
    function preg_last_error_msg(): string { return p\Php80::preg_last_error_msg(); }
}
if (!function_exists('str_contains')) {
    function str_contains(string $haystack, string $needle): bool { return p\Php80::str_contains($haystack, $needle); }
}
if (!function_exists('str_starts_with')) {
    function str_starts_with(string $haystack, string $needle): bool { return p\Php80::str_starts_with($haystack, $needle); }
}
if (!function_exists('str_ends_with')) {
    function str_ends_with(string $haystack, string $needle): bool { return p\Php80::str_ends_with($haystack, $needle); }
}
if (!function_exists('get_debug_type')) {
    function get_debug_type($value): string { return p\Php80::get_debug_type($value); }
}
if (!function_exists('get_resource_id')) {
    function get_resource_id($res): int { return p\Php80::get_resource_id($res); }
}
PKϤ$ZLO!
$$polyfill-php80/LICENSEnu�[���Copyright (c) 2020 Fabien Potencier

Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is furnished
to do so, subject to the following conditions:

The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.

THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
THE SOFTWARE.
PKϤ$Z |��$finder/Comparator/DateComparator.phpnu�[���<?php

/*
 * This file is part of the Symfony package.
 *
 * (c) Fabien Potencier <fabien@symfony.com>
 *
 * For the full copyright and license information, please view the LICENSE
 * file that was distributed with this source code.
 */

namespace Symfony\Component\Finder\Comparator;

/**
 * DateCompare compiles date comparisons.
 *
 * @author Fabien Potencier <fabien@symfony.com>
 */
class DateComparator extends Comparator
{
    /**
     * @param string $test A comparison string
     *
     * @throws \InvalidArgumentException If the test is not understood
     */
    public function __construct(string $test)
    {
        if (!preg_match('#^\s*(==|!=|[<>]=?|after|since|before|until)?\s*(.+?)\s*$#i', $test, $matches)) {
            throw new \InvalidArgumentException(sprintf('Don\'t understand "%s" as a date test.', $test));
        }

        try {
            $date = new \DateTime($matches[2]);
            $target = $date->format('U');
        } catch (\Exception $e) {
            throw new \InvalidArgumentException(sprintf('"%s" is not a valid date.', $matches[2]));
        }

        $operator = $matches[1] ?? '==';
        if ('since' === $operator || 'after' === $operator) {
            $operator = '>';
        }

        if ('until' === $operator || 'before' === $operator) {
            $operator = '<';
        }

        $this->setOperator($operator);
        $this->setTarget($target);
    }
}
PKϤ$Z�3�#
#
&finder/Comparator/NumberComparator.phpnu�[���<?php

/*
 * This file is part of the Symfony package.
 *
 * (c) Fabien Potencier <fabien@symfony.com>
 *
 * For the full copyright and license information, please view the LICENSE
 * file that was distributed with this source code.
 */

namespace Symfony\Component\Finder\Comparator;

/**
 * NumberComparator compiles a simple comparison to an anonymous
 * subroutine, which you can call with a value to be tested again.
 *
 * Now this would be very pointless, if NumberCompare didn't understand
 * magnitudes.
 *
 * The target value may use magnitudes of kilobytes (k, ki),
 * megabytes (m, mi), or gigabytes (g, gi).  Those suffixed
 * with an i use the appropriate 2**n version in accordance with the
 * IEC standard: http://physics.nist.gov/cuu/Units/binary.html
 *
 * Based on the Perl Number::Compare module.
 *
 * @author    Fabien Potencier <fabien@symfony.com> PHP port
 * @author    Richard Clamp <richardc@unixbeard.net> Perl version
 * @copyright 2004-2005 Fabien Potencier <fabien@symfony.com>
 * @copyright 2002 Richard Clamp <richardc@unixbeard.net>
 *
 * @see http://physics.nist.gov/cuu/Units/binary.html
 */
class NumberComparator extends Comparator
{
    /**
     * @param string|int $test A comparison string or an integer
     *
     * @throws \InvalidArgumentException If the test is not understood
     */
    public function __construct(?string $test)
    {
        if (null === $test || !preg_match('#^\s*(==|!=|[<>]=?)?\s*([0-9\.]+)\s*([kmg]i?)?\s*$#i', $test, $matches)) {
            throw new \InvalidArgumentException(sprintf('Don\'t understand "%s" as a number test.', $test ?? 'null'));
        }

        $target = $matches[2];
        if (!is_numeric($target)) {
            throw new \InvalidArgumentException(sprintf('Invalid number "%s".', $target));
        }
        if (isset($matches[3])) {
            // magnitude
            switch (strtolower($matches[3])) {
                case 'k':
                    $target *= 1000;
                    break;
                case 'ki':
                    $target *= 1024;
                    break;
                case 'm':
                    $target *= 1000000;
                    break;
                case 'mi':
                    $target *= 1024 * 1024;
                    break;
                case 'g':
                    $target *= 1000000000;
                    break;
                case 'gi':
                    $target *= 1024 * 1024 * 1024;
                    break;
            }
        }

        $this->setTarget($target);
        $this->setOperator($matches[1] ?? '==');
    }
}
PKϤ$Zu���}} finder/Comparator/Comparator.phpnu�[���<?php

/*
 * This file is part of the Symfony package.
 *
 * (c) Fabien Potencier <fabien@symfony.com>
 *
 * For the full copyright and license information, please view the LICENSE
 * file that was distributed with this source code.
 */

namespace Symfony\Component\Finder\Comparator;

/**
 * Comparator.
 *
 * @author Fabien Potencier <fabien@symfony.com>
 */
class Comparator
{
    private $target;
    private $operator = '==';

    /**
     * Gets the target value.
     *
     * @return string The target value
     */
    public function getTarget()
    {
        return $this->target;
    }

    public function setTarget(string $target)
    {
        $this->target = $target;
    }

    /**
     * Gets the comparison operator.
     *
     * @return string The operator
     */
    public function getOperator()
    {
        return $this->operator;
    }

    /**
     * Sets the comparison operator.
     *
     * @throws \InvalidArgumentException
     */
    public function setOperator(string $operator)
    {
        if ('' === $operator) {
            $operator = '==';
        }

        if (!\in_array($operator, ['>', '<', '>=', '<=', '==', '!='])) {
            throw new \InvalidArgumentException(sprintf('Invalid operator "%s".', $operator));
        }

        $this->operator = $operator;
    }

    /**
     * Tests against the target.
     *
     * @param mixed $test A test value
     *
     * @return bool
     */
    public function test($test)
    {
        switch ($this->operator) {
            case '>':
                return $test > $this->target;
            case '>=':
                return $test >= $this->target;
            case '<':
                return $test < $this->target;
            case '<=':
                return $test <= $this->target;
            case '!=':
                return $test != $this->target;
        }

        return $test == $this->target;
    }
}
PKϤ$Z��qqfinder/Adapter/PhpAdapter.phpnu�[���<?php

/*
 * This file is part of the Symfony package.
 *
 * (c) Fabien Potencier <fabien@symfony.com>
 *
 * For the full copyright and license information, please view the LICENSE
 * file that was distributed with this source code.
 */

namespace Symfony\Component\Finder\Adapter;

@trigger_error('The '.__NAMESPACE__.'\PhpAdapter class is deprecated since version 2.8 and will be removed in 3.0. Use directly the Finder class instead.', E_USER_DEPRECATED);

use Symfony\Component\Finder\Iterator;

/**
 * PHP finder engine implementation.
 *
 * @author Jean-François Simon <contact@jfsimon.fr>
 *
 * @deprecated since 2.8, to be removed in 3.0. Use Finder instead.
 */
class PhpAdapter extends AbstractAdapter
{
    /**
     * {@inheritdoc}
     */
    public function searchInDirectory($dir)
    {
        $flags = \RecursiveDirectoryIterator::SKIP_DOTS;

        if ($this->followLinks) {
            $flags |= \RecursiveDirectoryIterator::FOLLOW_SYMLINKS;
        }

        $iterator = new Iterator\RecursiveDirectoryIterator($dir, $flags, $this->ignoreUnreadableDirs);

        if ($this->exclude) {
            $iterator = new Iterator\ExcludeDirectoryFilterIterator($iterator, $this->exclude);
        }

        $iterator = new \RecursiveIteratorIterator($iterator, \RecursiveIteratorIterator::SELF_FIRST);

        if ($this->minDepth > 0 || $this->maxDepth < PHP_INT_MAX) {
            $iterator = new Iterator\DepthRangeFilterIterator($iterator, $this->minDepth, $this->maxDepth);
        }

        if ($this->mode) {
            $iterator = new Iterator\FileTypeFilterIterator($iterator, $this->mode);
        }

        if ($this->names || $this->notNames) {
            $iterator = new Iterator\FilenameFilterIterator($iterator, $this->names, $this->notNames);
        }

        if ($this->contains || $this->notContains) {
            $iterator = new Iterator\FilecontentFilterIterator($iterator, $this->contains, $this->notContains);
        }

        if ($this->sizes) {
            $iterator = new Iterator\SizeRangeFilterIterator($iterator, $this->sizes);
        }

        if ($this->dates) {
            $iterator = new Iterator\DateRangeFilterIterator($iterator, $this->dates);
        }

        if ($this->filters) {
            $iterator = new Iterator\CustomFilterIterator($iterator, $this->filters);
        }

        if ($this->paths || $this->notPaths) {
            $iterator = new Iterator\PathFilterIterator($iterator, $this->paths, $this->notPaths);
        }

        if ($this->sort) {
            $iteratorAggregate = new Iterator\SortableIterator($iterator, $this->sort);
            $iterator = $iteratorAggregate->getIterator();
        }

        return $iterator;
    }

    /**
     * {@inheritdoc}
     */
    public function getName()
    {
        return 'php';
    }

    /**
     * {@inheritdoc}
     */
    protected function canBeUsed()
    {
        return true;
    }
}
PKϤ$ZmT�A��#finder/Adapter/AdapterInterface.phpnu�[���<?php

/*
 * This file is part of the Symfony package.
 *
 * (c) Fabien Potencier <fabien@symfony.com>
 *
 * For the full copyright and license information, please view the LICENSE
 * file that was distributed with this source code.
 */

namespace Symfony\Component\Finder\Adapter;

/**
 * @author Jean-François Simon <contact@jfsimon.fr>
 *
 * @deprecated since 2.8, to be removed in 3.0.
 */
interface AdapterInterface
{
    /**
     * @param bool $followLinks
     *
     * @return AdapterInterface Current instance
     */
    public function setFollowLinks($followLinks);

    /**
     * @param int $mode
     *
     * @return AdapterInterface Current instance
     */
    public function setMode($mode);

    /**
     * @param array $exclude
     *
     * @return AdapterInterface Current instance
     */
    public function setExclude(array $exclude);

    /**
     * @param array $depths
     *
     * @return AdapterInterface Current instance
     */
    public function setDepths(array $depths);

    /**
     * @param array $names
     *
     * @return AdapterInterface Current instance
     */
    public function setNames(array $names);

    /**
     * @param array $notNames
     *
     * @return AdapterInterface Current instance
     */
    public function setNotNames(array $notNames);

    /**
     * @param array $contains
     *
     * @return AdapterInterface Current instance
     */
    public function setContains(array $contains);

    /**
     * @param array $notContains
     *
     * @return AdapterInterface Current instance
     */
    public function setNotContains(array $notContains);

    /**
     * @param array $sizes
     *
     * @return AdapterInterface Current instance
     */
    public function setSizes(array $sizes);

    /**
     * @param array $dates
     *
     * @return AdapterInterface Current instance
     */
    public function setDates(array $dates);

    /**
     * @param array $filters
     *
     * @return AdapterInterface Current instance
     */
    public function setFilters(array $filters);

    /**
     * @param \Closure|int $sort
     *
     * @return AdapterInterface Current instance
     */
    public function setSort($sort);

    /**
     * @param array $paths
     *
     * @return AdapterInterface Current instance
     */
    public function setPath(array $paths);

    /**
     * @param array $notPaths
     *
     * @return AdapterInterface Current instance
     */
    public function setNotPath(array $notPaths);

    /**
     * @param bool $ignore
     *
     * @return AdapterInterface Current instance
     */
    public function ignoreUnreadableDirs($ignore = true);

    /**
     * @param string $dir
     *
     * @return \Iterator Result iterator
     */
    public function searchInDirectory($dir);

    /**
     * Tests adapter support for current platform.
     *
     * @return bool
     */
    public function isSupported();

    /**
     * Returns adapter name.
     *
     * @return string
     */
    public function getName();
}
PKϤ$Z�f!���!finder/Adapter/GnuFindAdapter.phpnu�[���<?php

/*
 * This file is part of the Symfony package.
 *
 * (c) Fabien Potencier <fabien@symfony.com>
 *
 * For the full copyright and license information, please view the LICENSE
 * file that was distributed with this source code.
 */

namespace Symfony\Component\Finder\Adapter;

@trigger_error('The '.__NAMESPACE__.'\GnuFindAdapter class is deprecated since version 2.8 and will be removed in 3.0. Use directly the Finder class instead.', E_USER_DEPRECATED);

use Symfony\Component\Finder\Shell\Shell;
use Symfony\Component\Finder\Shell\Command;
use Symfony\Component\Finder\Iterator\SortableIterator;
use Symfony\Component\Finder\Expression\Expression;

/**
 * Shell engine implementation using GNU find command.
 *
 * @author Jean-François Simon <contact@jfsimon.fr>
 *
 * @deprecated since 2.8, to be removed in 3.0. Use Finder instead.
 */
class GnuFindAdapter extends AbstractFindAdapter
{
    /**
     * {@inheritdoc}
     */
    public function getName()
    {
        return 'gnu_find';
    }

    /**
     * {@inheritdoc}
     */
    protected function buildFormatSorting(Command $command, $sort)
    {
        switch ($sort) {
            case SortableIterator::SORT_BY_NAME:
                $command->ins('sort')->add('| sort');

                return;
            case SortableIterator::SORT_BY_TYPE:
                $format = '%y';
                break;
            case SortableIterator::SORT_BY_ACCESSED_TIME:
                $format = '%A@';
                break;
            case SortableIterator::SORT_BY_CHANGED_TIME:
                $format = '%C@';
                break;
            case SortableIterator::SORT_BY_MODIFIED_TIME:
                $format = '%T@';
                break;
            default:
                throw new \InvalidArgumentException(sprintf('Unknown sort options: %s.', $sort));
        }

        $command
            ->get('find')
            ->add('-printf')
            ->arg($format.' %h/%f\\n')
            ->add('| sort | cut')
            ->arg('-d ')
            ->arg('-f2-')
        ;
    }

    /**
     * {@inheritdoc}
     */
    protected function canBeUsed()
    {
        return $this->shell->getType() === Shell::TYPE_UNIX && parent::canBeUsed();
    }

    /**
     * {@inheritdoc}
     */
    protected function buildFindCommand(Command $command, $dir)
    {
        return parent::buildFindCommand($command, $dir)->add('-regextype posix-extended');
    }

    /**
     * {@inheritdoc}
     */
    protected function buildContentFiltering(Command $command, array $contains, $not = false)
    {
        foreach ($contains as $contain) {
            $expr = Expression::create($contain);

            // todo: avoid forking process for each $pattern by using multiple -e options
            $command
                ->add('| xargs -I{} -r grep -I')
                ->add($expr->isCaseSensitive() ? null : '-i')
                ->add($not ? '-L' : '-l')
                ->add('-Ee')->arg($expr->renderPattern())
                ->add('{}')
            ;
        }
    }
}
PKϤ$ZO��H��!finder/Adapter/BsdFindAdapter.phpnu�[���<?php

/*
 * This file is part of the Symfony package.
 *
 * (c) Fabien Potencier <fabien@symfony.com>
 *
 * For the full copyright and license information, please view the LICENSE
 * file that was distributed with this source code.
 */

namespace Symfony\Component\Finder\Adapter;

@trigger_error('The '.__NAMESPACE__.'\BsdFindAdapter class is deprecated since version 2.8 and will be removed in 3.0. Use directly the Finder class instead.', E_USER_DEPRECATED);

use Symfony\Component\Finder\Shell\Shell;
use Symfony\Component\Finder\Shell\Command;
use Symfony\Component\Finder\Iterator\SortableIterator;
use Symfony\Component\Finder\Expression\Expression;

/**
 * Shell engine implementation using BSD find command.
 *
 * @author Jean-François Simon <contact@jfsimon.fr>
 *
 * @deprecated since 2.8, to be removed in 3.0. Use Finder instead.
 */
class BsdFindAdapter extends AbstractFindAdapter
{
    /**
     * {@inheritdoc}
     */
    public function getName()
    {
        return 'bsd_find';
    }

    /**
     * {@inheritdoc}
     */
    protected function canBeUsed()
    {
        return in_array($this->shell->getType(), array(Shell::TYPE_BSD, Shell::TYPE_DARWIN)) && parent::canBeUsed();
    }

    /**
     * {@inheritdoc}
     */
    protected function buildFormatSorting(Command $command, $sort)
    {
        switch ($sort) {
            case SortableIterator::SORT_BY_NAME:
                $command->ins('sort')->add('| sort');

                return;
            case SortableIterator::SORT_BY_TYPE:
                $format = '%HT';
                break;
            case SortableIterator::SORT_BY_ACCESSED_TIME:
                $format = '%a';
                break;
            case SortableIterator::SORT_BY_CHANGED_TIME:
                $format = '%c';
                break;
            case SortableIterator::SORT_BY_MODIFIED_TIME:
                $format = '%m';
                break;
            default:
                throw new \InvalidArgumentException(sprintf('Unknown sort options: %s.', $sort));
        }

        $command
            ->add('-print0 | xargs -0 stat -f')
            ->arg($format.'%t%N')
            ->add('| sort | cut -f 2');
    }

    /**
     * {@inheritdoc}
     */
    protected function buildFindCommand(Command $command, $dir)
    {
        parent::buildFindCommand($command, $dir)->addAtIndex('-E', 1);

        return $command;
    }

    /**
     * {@inheritdoc}
     */
    protected function buildContentFiltering(Command $command, array $contains, $not = false)
    {
        foreach ($contains as $contain) {
            $expr = Expression::create($contain);

            // todo: avoid forking process for each $pattern by using multiple -e options
            $command
                ->add('| grep -v \'^$\'')
                ->add('| xargs -I{} grep -I')
                ->add($expr->isCaseSensitive() ? null : '-i')
                ->add($not ? '-L' : '-l')
                ->add('-Ee')->arg($expr->renderPattern())
                ->add('{}')
            ;
        }
    }
}
PKϤ$Z*�+�*�*&finder/Adapter/AbstractFindAdapter.phpnu�[���<?php

/*
 * This file is part of the Symfony package.
 *
 * (c) Fabien Potencier <fabien@symfony.com>
 *
 * For the full copyright and license information, please view the LICENSE
 * file that was distributed with this source code.
 */

namespace Symfony\Component\Finder\Adapter;

@trigger_error('The '.__NAMESPACE__.'\AbstractFindAdapter class is deprecated since version 2.8 and will be removed in 3.0. Use directly the Finder class instead.', E_USER_DEPRECATED);

use Symfony\Component\Finder\Exception\AccessDeniedException;
use Symfony\Component\Finder\Iterator;
use Symfony\Component\Finder\Shell\Shell;
use Symfony\Component\Finder\Expression\Expression;
use Symfony\Component\Finder\Shell\Command;
use Symfony\Component\Finder\Comparator\NumberComparator;
use Symfony\Component\Finder\Comparator\DateComparator;

/**
 * Shell engine implementation using GNU find command.
 *
 * @author Jean-François Simon <contact@jfsimon.fr>
 *
 * @deprecated since 2.8, to be removed in 3.0. Use Finder instead.
 */
abstract class AbstractFindAdapter extends AbstractAdapter
{
    /**
     * @var Shell
     */
    protected $shell;

    /**
     * Constructor.
     */
    public function __construct()
    {
        $this->shell = new Shell();
    }

    /**
     * {@inheritdoc}
     */
    public function searchInDirectory($dir)
    {
        // having "/../" in path make find fail
        $dir = realpath($dir);

        // searching directories containing or not containing strings leads to no result
        if (Iterator\FileTypeFilterIterator::ONLY_DIRECTORIES === $this->mode && ($this->contains || $this->notContains)) {
            return new Iterator\FilePathsIterator(array(), $dir);
        }

        $command = Command::create();
        $find = $this->buildFindCommand($command, $dir);

        if ($this->followLinks) {
            $find->add('-follow');
        }

        $find->add('-mindepth')->add($this->minDepth + 1);

        if (PHP_INT_MAX !== $this->maxDepth) {
            $find->add('-maxdepth')->add($this->maxDepth + 1);
        }

        if (Iterator\FileTypeFilterIterator::ONLY_DIRECTORIES === $this->mode) {
            $find->add('-type d');
        } elseif (Iterator\FileTypeFilterIterator::ONLY_FILES === $this->mode) {
            $find->add('-type f');
        }

        $this->buildNamesFiltering($find, $this->names);
        $this->buildNamesFiltering($find, $this->notNames, true);
        $this->buildPathsFiltering($find, $dir, $this->paths);
        $this->buildPathsFiltering($find, $dir, $this->notPaths, true);
        $this->buildSizesFiltering($find, $this->sizes);
        $this->buildDatesFiltering($find, $this->dates);

        $useGrep = $this->shell->testCommand('grep') && $this->shell->testCommand('xargs');
        $useSort = is_int($this->sort) && $this->shell->testCommand('sort') && $this->shell->testCommand('cut');

        if ($useGrep && ($this->contains || $this->notContains)) {
            $grep = $command->ins('grep');
            $this->buildContentFiltering($grep, $this->contains);
            $this->buildContentFiltering($grep, $this->notContains, true);
        }

        if ($useSort) {
            $this->buildSorting($command, $this->sort);
        }

        $command->setErrorHandler(
            $this->ignoreUnreadableDirs
                // If directory is unreadable and finder is set to ignore it, `stderr` is ignored.
                ? function ($stderr) { }
                : function ($stderr) { throw new AccessDeniedException($stderr); }
        );

        $paths = $this->shell->testCommand('uniq') ? $command->add('| uniq')->execute() : array_unique($command->execute());
        $iterator = new Iterator\FilePathsIterator($paths, $dir);

        if ($this->exclude) {
            $iterator = new Iterator\ExcludeDirectoryFilterIterator($iterator, $this->exclude);
        }

        if (!$useGrep && ($this->contains || $this->notContains)) {
            $iterator = new Iterator\FilecontentFilterIterator($iterator, $this->contains, $this->notContains);
        }

        if ($this->filters) {
            $iterator = new Iterator\CustomFilterIterator($iterator, $this->filters);
        }

        if (!$useSort && $this->sort) {
            $iteratorAggregate = new Iterator\SortableIterator($iterator, $this->sort);
            $iterator = $iteratorAggregate->getIterator();
        }

        return $iterator;
    }

    /**
     * {@inheritdoc}
     */
    protected function canBeUsed()
    {
        return $this->shell->testCommand('find');
    }

    /**
     * @param Command $command
     * @param string  $dir
     *
     * @return Command
     */
    protected function buildFindCommand(Command $command, $dir)
    {
        return $command
            ->ins('find')
            ->add('find ')
            ->arg($dir)
            ->add('-noleaf'); // the -noleaf option is required for filesystems that don't follow the '.' and '..' conventions
    }

    /**
     * @param Command  $command
     * @param string[] $names
     * @param bool     $not
     */
    private function buildNamesFiltering(Command $command, array $names, $not = false)
    {
        if (0 === count($names)) {
            return;
        }

        $command->add($not ? '-not' : null)->cmd('(');

        foreach ($names as $i => $name) {
            $expr = Expression::create($name);

            // Find does not support expandable globs ("*.{a,b}" syntax).
            if ($expr->isGlob() && $expr->getGlob()->isExpandable()) {
                $expr = Expression::create($expr->getGlob()->toRegex(false));
            }

            // Fixes 'not search' and 'full path matching' regex problems.
            // - Jokers '.' are replaced by [^/].
            // - We add '[^/]*' before and after regex (if no ^|$ flags are present).
            if ($expr->isRegex()) {
                $regex = $expr->getRegex();
                $regex->prepend($regex->hasStartFlag() ? '/' : '/[^/]*')
                    ->setStartFlag(false)
                    ->setStartJoker(true)
                    ->replaceJokers('[^/]');
                if (!$regex->hasEndFlag() || $regex->hasEndJoker()) {
                    $regex->setEndJoker(false)->append('[^/]*');
                }
            }

            $command
                ->add($i > 0 ? '-or' : null)
                ->add($expr->isRegex()
                    ? ($expr->isCaseSensitive() ? '-regex' : '-iregex')
                    : ($expr->isCaseSensitive() ? '-name' : '-iname')
                )
                ->arg($expr->renderPattern());
        }

        $command->cmd(')');
    }

    /**
     * @param Command  $command
     * @param string   $dir
     * @param string[] $paths
     * @param bool     $not
     */
    private function buildPathsFiltering(Command $command, $dir, array $paths, $not = false)
    {
        if (0 === count($paths)) {
            return;
        }

        $command->add($not ? '-not' : null)->cmd('(');

        foreach ($paths as $i => $path) {
            $expr = Expression::create($path);

            // Find does not support expandable globs ("*.{a,b}" syntax).
            if ($expr->isGlob() && $expr->getGlob()->isExpandable()) {
                $expr = Expression::create($expr->getGlob()->toRegex(false));
            }

            // Fixes 'not search' regex problems.
            if ($expr->isRegex()) {
                $regex = $expr->getRegex();
                $regex->prepend($regex->hasStartFlag() ? preg_quote($dir).DIRECTORY_SEPARATOR : '.*')->setEndJoker(!$regex->hasEndFlag());
            } else {
                $expr->prepend('*')->append('*');
            }

            $command
                ->add($i > 0 ? '-or' : null)
                ->add($expr->isRegex()
                    ? ($expr->isCaseSensitive() ? '-regex' : '-iregex')
                    : ($expr->isCaseSensitive() ? '-path' : '-ipath')
                )
                ->arg($expr->renderPattern());
        }

        $command->cmd(')');
    }

    /**
     * @param Command            $command
     * @param NumberComparator[] $sizes
     */
    private function buildSizesFiltering(Command $command, array $sizes)
    {
        foreach ($sizes as $i => $size) {
            $command->add($i > 0 ? '-and' : null);

            switch ($size->getOperator()) {
                case '<=':
                    $command->add('-size -'.($size->getTarget() + 1).'c');
                    break;
                case '>=':
                    $command->add('-size +'.($size->getTarget() - 1).'c');
                    break;
                case '>':
                    $command->add('-size +'.$size->getTarget().'c');
                    break;
                case '!=':
                    $command->add('-size -'.$size->getTarget().'c');
                    $command->add('-size +'.$size->getTarget().'c');
                    break;
                case '<':
                default:
                    $command->add('-size -'.$size->getTarget().'c');
            }
        }
    }

    /**
     * @param Command          $command
     * @param DateComparator[] $dates
     */
    private function buildDatesFiltering(Command $command, array $dates)
    {
        foreach ($dates as $i => $date) {
            $command->add($i > 0 ? '-and' : null);

            $mins = (int) round((time() - $date->getTarget()) / 60);

            if (0 > $mins) {
                // mtime is in the future
                $command->add(' -mmin -0');
                // we will have no result so we don't need to continue
                return;
            }

            switch ($date->getOperator()) {
                case '<=':
                    $command->add('-mmin +'.($mins - 1));
                    break;
                case '>=':
                    $command->add('-mmin -'.($mins + 1));
                    break;
                case '>':
                    $command->add('-mmin -'.$mins);
                    break;
                case '!=':
                    $command->add('-mmin +'.$mins.' -or -mmin -'.$mins);
                    break;
                case '<':
                default:
                    $command->add('-mmin +'.$mins);
            }
        }
    }

    /**
     * @param Command $command
     * @param string  $sort
     *
     * @throws \InvalidArgumentException
     */
    private function buildSorting(Command $command, $sort)
    {
        $this->buildFormatSorting($command, $sort);
    }

    /**
     * @param Command $command
     * @param string  $sort
     */
    abstract protected function buildFormatSorting(Command $command, $sort);

    /**
     * @param Command $command
     * @param array   $contains
     * @param bool    $not
     */
    abstract protected function buildContentFiltering(Command $command, array $contains, $not = false);
}
PKϤ$Z�����"finder/Adapter/AbstractAdapter.phpnu�[���<?php

/*
 * This file is part of the Symfony package.
 *
 * (c) Fabien Potencier <fabien@symfony.com>
 *
 * For the full copyright and license information, please view the LICENSE
 * file that was distributed with this source code.
 */

namespace Symfony\Component\Finder\Adapter;

@trigger_error('The '.__NAMESPACE__.'\AbstractAdapter class is deprecated since version 2.8 and will be removed in 3.0. Use directly the Finder class instead.', E_USER_DEPRECATED);

/**
 * Interface for finder engine implementations.
 *
 * @author Jean-François Simon <contact@jfsimon.fr>
 *
 * @deprecated since 2.8, to be removed in 3.0. Use Finder instead.
 */
abstract class AbstractAdapter implements AdapterInterface
{
    protected $followLinks = false;
    protected $mode = 0;
    protected $minDepth = 0;
    protected $maxDepth = PHP_INT_MAX;
    protected $exclude = array();
    protected $names = array();
    protected $notNames = array();
    protected $contains = array();
    protected $notContains = array();
    protected $sizes = array();
    protected $dates = array();
    protected $filters = array();
    protected $sort = false;
    protected $paths = array();
    protected $notPaths = array();
    protected $ignoreUnreadableDirs = false;

    private static $areSupported = array();

    /**
     * {@inheritdoc}
     */
    public function isSupported()
    {
        $name = $this->getName();

        if (!array_key_exists($name, self::$areSupported)) {
            self::$areSupported[$name] = $this->canBeUsed();
        }

        return self::$areSupported[$name];
    }

    /**
     * {@inheritdoc}
     */
    public function setFollowLinks($followLinks)
    {
        $this->followLinks = $followLinks;

        return $this;
    }

    /**
     * {@inheritdoc}
     */
    public function setMode($mode)
    {
        $this->mode = $mode;

        return $this;
    }

    /**
     * {@inheritdoc}
     */
    public function setDepths(array $depths)
    {
        $this->minDepth = 0;
        $this->maxDepth = PHP_INT_MAX;

        foreach ($depths as $comparator) {
            switch ($comparator->getOperator()) {
                case '>':
                    $this->minDepth = $comparator->getTarget() + 1;
                    break;
                case '>=':
                    $this->minDepth = $comparator->getTarget();
                    break;
                case '<':
                    $this->maxDepth = $comparator->getTarget() - 1;
                    break;
                case '<=':
                    $this->maxDepth = $comparator->getTarget();
                    break;
                default:
                    $this->minDepth = $this->maxDepth = $comparator->getTarget();
            }
        }

        return $this;
    }

    /**
     * {@inheritdoc}
     */
    public function setExclude(array $exclude)
    {
        $this->exclude = $exclude;

        return $this;
    }

    /**
     * {@inheritdoc}
     */
    public function setNames(array $names)
    {
        $this->names = $names;

        return $this;
    }

    /**
     * {@inheritdoc}
     */
    public function setNotNames(array $notNames)
    {
        $this->notNames = $notNames;

        return $this;
    }

    /**
     * {@inheritdoc}
     */
    public function setContains(array $contains)
    {
        $this->contains = $contains;

        return $this;
    }

    /**
     * {@inheritdoc}
     */
    public function setNotContains(array $notContains)
    {
        $this->notContains = $notContains;

        return $this;
    }

    /**
     * {@inheritdoc}
     */
    public function setSizes(array $sizes)
    {
        $this->sizes = $sizes;

        return $this;
    }

    /**
     * {@inheritdoc}
     */
    public function setDates(array $dates)
    {
        $this->dates = $dates;

        return $this;
    }

    /**
     * {@inheritdoc}
     */
    public function setFilters(array $filters)
    {
        $this->filters = $filters;

        return $this;
    }

    /**
     * {@inheritdoc}
     */
    public function setSort($sort)
    {
        $this->sort = $sort;

        return $this;
    }

    /**
     * {@inheritdoc}
     */
    public function setPath(array $paths)
    {
        $this->paths = $paths;

        return $this;
    }

    /**
     * {@inheritdoc}
     */
    public function setNotPath(array $notPaths)
    {
        $this->notPaths = $notPaths;

        return $this;
    }

    /**
     * {@inheritdoc}
     */
    public function ignoreUnreadableDirs($ignore = true)
    {
        $this->ignoreUnreadableDirs = (bool) $ignore;

        return $this;
    }

    /**
     * Returns whether the adapter is supported in the current environment.
     *
     * This method should be implemented in all adapters. Do not implement
     * isSupported in the adapters as the generic implementation provides a cache
     * layer.
     *
     * @see isSupported()
     *
     * @return bool Whether the adapter is supported
     */
    abstract protected function canBeUsed();
}
PKϤ$ZW�W-�	�	.finder/Tests/Comparator/DateComparatorTest.phpnu�[���<?php

/*
 * This file is part of the Symfony package.
 *
 * (c) Fabien Potencier <fabien@symfony.com>
 *
 * For the full copyright and license information, please view the LICENSE
 * file that was distributed with this source code.
 */

namespace Symfony\Component\Finder\Tests\Comparator;

use Symfony\Component\Finder\Comparator\DateComparator;

class DateComparatorTest extends \PHPUnit_Framework_TestCase
{
    public function testConstructor()
    {
        try {
            new DateComparator('foobar');
            $this->fail('__construct() throws an \InvalidArgumentException if the test expression is not valid.');
        } catch (\Exception $e) {
            $this->assertInstanceOf('InvalidArgumentException', $e, '__construct() throws an \InvalidArgumentException if the test expression is not valid.');
        }

        try {
            new DateComparator('');
            $this->fail('__construct() throws an \InvalidArgumentException if the test expression is not valid.');
        } catch (\Exception $e) {
            $this->assertInstanceOf('InvalidArgumentException', $e, '__construct() throws an \InvalidArgumentException if the test expression is not valid.');
        }
    }

    /**
     * @dataProvider getTestData
     */
    public function testTest($test, $match, $noMatch)
    {
        $c = new DateComparator($test);

        foreach ($match as $m) {
            $this->assertTrue($c->test($m), '->test() tests a string against the expression');
        }

        foreach ($noMatch as $m) {
            $this->assertFalse($c->test($m), '->test() tests a string against the expression');
        }
    }

    public function getTestData()
    {
        return array(
            array('< 2005-10-10', array(strtotime('2005-10-09')), array(strtotime('2005-10-15'))),
            array('until 2005-10-10', array(strtotime('2005-10-09')), array(strtotime('2005-10-15'))),
            array('before 2005-10-10', array(strtotime('2005-10-09')), array(strtotime('2005-10-15'))),
            array('> 2005-10-10', array(strtotime('2005-10-15')), array(strtotime('2005-10-09'))),
            array('after 2005-10-10', array(strtotime('2005-10-15')), array(strtotime('2005-10-09'))),
            array('since 2005-10-10', array(strtotime('2005-10-15')), array(strtotime('2005-10-09'))),
            array('!= 2005-10-10', array(strtotime('2005-10-11')), array(strtotime('2005-10-10'))),
        );
    }
}
PKϤ$ZaU�HH0finder/Tests/Comparator/NumberComparatorTest.phpnu�[���<?php

/*
 * This file is part of the Symfony package.
 *
 * (c) Fabien Potencier <fabien@symfony.com>
 *
 * For the full copyright and license information, please view the LICENSE
 * file that was distributed with this source code.
 */

namespace Symfony\Component\Finder\Tests\Comparator;

use Symfony\Component\Finder\Comparator\NumberComparator;

class NumberComparatorTest extends \PHPUnit_Framework_TestCase
{
    /**
     * @dataProvider getConstructorTestData
     */
    public function testConstructor($successes, $failures)
    {
        foreach ($successes as $s) {
            new NumberComparator($s);
        }

        foreach ($failures as $f) {
            try {
                new NumberComparator($f);
                $this->fail('__construct() throws an \InvalidArgumentException if the test expression is not valid.');
            } catch (\Exception $e) {
                $this->assertInstanceOf('InvalidArgumentException', $e, '__construct() throws an \InvalidArgumentException if the test expression is not valid.');
            }
        }
    }

    /**
     * @dataProvider getTestData
     */
    public function testTest($test, $match, $noMatch)
    {
        $c = new NumberComparator($test);

        foreach ($match as $m) {
            $this->assertTrue($c->test($m), '->test() tests a string against the expression');
        }

        foreach ($noMatch as $m) {
            $this->assertFalse($c->test($m), '->test() tests a string against the expression');
        }
    }

    public function getTestData()
    {
        return array(
            array('< 1000', array('500', '999'), array('1000', '1500')),

            array('< 1K', array('500', '999'), array('1000', '1500')),
            array('<1k', array('500', '999'), array('1000', '1500')),
            array('  < 1 K ', array('500', '999'), array('1000', '1500')),
            array('<= 1K', array('1000'), array('1001')),
            array('> 1K', array('1001'), array('1000')),
            array('>= 1K', array('1000'), array('999')),

            array('< 1KI', array('500', '1023'), array('1024', '1500')),
            array('<= 1KI', array('1024'), array('1025')),
            array('> 1KI', array('1025'), array('1024')),
            array('>= 1KI', array('1024'), array('1023')),

            array('1KI', array('1024'), array('1023', '1025')),
            array('==1KI', array('1024'), array('1023', '1025')),

            array('==1m', array('1000000'), array('999999', '1000001')),
            array('==1mi', array(1024 * 1024), array(1024 * 1024 - 1, 1024 * 1024 + 1)),

            array('==1g', array('1000000000'), array('999999999', '1000000001')),
            array('==1gi', array(1024 * 1024 * 1024), array(1024 * 1024 * 1024 - 1, 1024 * 1024 * 1024 + 1)),

            array('!= 1000', array('500', '999'), array('1000')),
        );
    }

    public function getConstructorTestData()
    {
        return array(
            array(
                array(
                    '1', '0',
                    '3.5', '33.55', '123.456', '123456.78',
                    '.1', '.123',
                    '.0', '0.0',
                    '1.', '0.', '123.',
                    '==1', '!=1', '<1', '>1', '<=1', '>=1',
                    '==1k', '==1ki', '==1m', '==1mi', '==1g', '==1gi',
                    '1k', '1ki', '1m', '1mi', '1g', '1gi',
                ),
                array(
                    false, null, '',
                    ' ', 'foobar',
                    '=1', '===1',
                    '0 . 1', '123 .45', '234. 567',
                    '..', '.0.', '0.1.2',
                ),
            ),
        );
    }
}
PKϤ$Z��Ŗ�*finder/Tests/Comparator/ComparatorTest.phpnu�[���<?php

/*
 * This file is part of the Symfony package.
 *
 * (c) Fabien Potencier <fabien@symfony.com>
 *
 * For the full copyright and license information, please view the LICENSE
 * file that was distributed with this source code.
 */

namespace Symfony\Component\Finder\Tests\Comparator;

use Symfony\Component\Finder\Comparator\Comparator;

class ComparatorTest extends \PHPUnit_Framework_TestCase
{
    public function testGetSetOperator()
    {
        $comparator = new Comparator();
        try {
            $comparator->setOperator('foo');
            $this->fail('->setOperator() throws an \InvalidArgumentException if the operator is not valid.');
        } catch (\Exception $e) {
            $this->assertInstanceOf('InvalidArgumentException', $e, '->setOperator() throws an \InvalidArgumentException if the operator is not valid.');
        }

        $comparator = new Comparator();
        $comparator->setOperator('>');
        $this->assertEquals('>', $comparator->getOperator(), '->getOperator() returns the current operator');
    }

    public function testGetSetTarget()
    {
        $comparator = new Comparator();
        $comparator->setTarget(8);
        $this->assertEquals(8, $comparator->getTarget(), '->getTarget() returns the target');
    }

    /**
     * @dataProvider getTestData
     */
    public function testTest($operator, $target, $match, $noMatch)
    {
        $c = new Comparator();
        $c->setOperator($operator);
        $c->setTarget($target);

        foreach ($match as $m) {
            $this->assertTrue($c->test($m), '->test() tests a string against the expression');
        }

        foreach ($noMatch as $m) {
            $this->assertFalse($c->test($m), '->test() tests a string against the expression');
        }
    }

    public function getTestData()
    {
        return array(
            array('<', '1000', array('500', '999'), array('1000', '1500')),
        );
    }
}
PKϤ$Z0�B���"finder/Tests/Shell/CommandTest.phpnu�[���<?php

/*
 * This file is part of the Symfony package.
 *
 * (c) Fabien Potencier <fabien@symfony.com>
 *
 * For the full copyright and license information, please view the LICENSE
 * file that was distributed with this source code.
 */

namespace Symfony\Component\Finder\Tests\Shell;

use Symfony\Component\Finder\Shell\Command;

/**
 * @group legacy
 */
class CommandTest extends \PHPUnit_Framework_TestCase
{
    public function testCreate()
    {
        $this->assertInstanceOf('Symfony\Component\Finder\Shell\Command', Command::create());
    }

    public function testAdd()
    {
        $cmd = Command::create()->add('--force');
        $this->assertSame('--force', $cmd->join());
    }

    public function testAddAsFirst()
    {
        $cmd = Command::create()->add('--force');

        $cmd->addAtIndex(Command::create()->add('-F'), 0);
        $this->assertSame('-F --force', $cmd->join());
    }

    public function testAddAsLast()
    {
        $cmd = Command::create()->add('--force');

        $cmd->addAtIndex(Command::create()->add('-F'), 1);
        $this->assertSame('--force -F', $cmd->join());
    }

    public function testAddInBetween()
    {
        $cmd = Command::create()->add('--force');
        $cmd->addAtIndex(Command::create()->add('-F'), 0);

        $cmd->addAtIndex(Command::create()->add('-X'), 1);
        $this->assertSame('-F -X --force', $cmd->join());
    }

    public function testCount()
    {
        $cmd = Command::create();
        $this->assertSame(0, $cmd->length());

        $cmd->add('--force');
        $this->assertSame(1, $cmd->length());

        $cmd->add('--run');
        $this->assertSame(2, $cmd->length());
    }

    public function testTop()
    {
        $cmd = Command::create()->add('--force');

        $cmd->top('--run');
        $this->assertSame('--run --force', $cmd->join());
    }

    public function testTopLabeled()
    {
        $cmd = Command::create()->add('--force');

        $cmd->top('--run');
        $cmd->ins('--something');
        $cmd->top('--something');
        $this->assertSame('--something --run --force ', $cmd->join());
    }

    public function testArg()
    {
        $cmd = Command::create()->add('--force');

        $cmd->arg('--run');
        $this->assertSame('--force '.escapeshellarg('--run'), $cmd->join());
    }

    public function testCmd()
    {
        $cmd = Command::create()->add('--force');

        $cmd->cmd('run');
        $this->assertSame('--force run', $cmd->join());
    }

    public function testInsDuplicateLabelException()
    {
        $cmd = Command::create()->add('--force');

        $cmd->ins('label');
        $this->setExpectedException('RuntimeException');
        $cmd->ins('label');
    }

    public function testEnd()
    {
        $parent = Command::create();
        $cmd = Command::create($parent);

        $this->assertSame($parent, $cmd->end());
    }

    public function testEndNoParentException()
    {
        $cmd = Command::create();

        $this->setExpectedException('RuntimeException');
        $cmd->end();
    }

    public function testGetMissingLabelException()
    {
        $cmd = Command::create();

        $this->setExpectedException('RuntimeException');
        $cmd->get('invalid');
    }

    public function testErrorHandler()
    {
        $cmd = Command::create();
        $handler = function () { return 'error-handler'; };
        $cmd->setErrorHandler($handler);

        $this->assertSame($handler, $cmd->getErrorHandler());
    }

    public function testExecute()
    {
        $cmd = Command::create();
        $cmd->add('php');
        $cmd->add('--version');
        $result = $cmd->execute();

        $this->assertInternalType('array', $result);
        $this->assertNotEmpty($result);
        $this->assertRegexp('/PHP|HipHop/', $result[0]);
    }

    public function testCastToString()
    {
        $cmd = Command::create();
        $cmd->add('--force');
        $cmd->add('--run');

        $this->assertSame('--force --run', (string) $cmd);
    }
}
PKϤ$Z-��u8finder/Tests/Iterator/RecursiveDirectoryIteratorTest.phpnu�[���<?php

/*
 * This file is part of the Symfony package.
 *
 * (c) Fabien Potencier <fabien@symfony.com>
 *
 * For the full copyright and license information, please view the LICENSE
 * file that was distributed with this source code.
 */

namespace Symfony\Component\Finder\Tests\Iterator;

use Symfony\Component\Finder\Iterator\RecursiveDirectoryIterator;

class RecursiveDirectoryIteratorTest extends IteratorTestCase
{
    /**
     * @group network
     */
    public function testRewindOnFtp()
    {
        try {
            $i = new RecursiveDirectoryIterator('ftp://speedtest.tele2.net/', \RecursiveDirectoryIterator::SKIP_DOTS);
        } catch (\UnexpectedValueException $e) {
            $this->markTestSkipped('Unsupported stream "ftp".');
        }

        $i->rewind();

        $this->assertTrue(true);
    }

    /**
     * @group network
     */
    public function testSeekOnFtp()
    {
        try {
            $i = new RecursiveDirectoryIterator('ftp://speedtest.tele2.net/', \RecursiveDirectoryIterator::SKIP_DOTS);
        } catch (\UnexpectedValueException $e) {
            $this->markTestSkipped('Unsupported stream "ftp".');
        }

        $contains = array(
            'ftp://speedtest.tele2.net'.DIRECTORY_SEPARATOR.'1000GB.zip',
            'ftp://speedtest.tele2.net'.DIRECTORY_SEPARATOR.'100GB.zip',
        );
        $actual = array();

        $i->seek(0);
        $actual[] = $i->getPathname();

        $i->seek(1);
        $actual[] = $i->getPathname();

        $this->assertEquals($contains, $actual);
    }
}
PKϤ$Zg��5finder/Tests/Iterator/SizeRangeFilterIteratorTest.phpnu�[���<?php

/*
 * This file is part of the Symfony package.
 *
 * (c) Fabien Potencier <fabien@symfony.com>
 *
 * For the full copyright and license information, please view the LICENSE
 * file that was distributed with this source code.
 */

namespace Symfony\Component\Finder\Tests\Iterator;

use Symfony\Component\Finder\Iterator\SizeRangeFilterIterator;
use Symfony\Component\Finder\Comparator\NumberComparator;

class SizeRangeFilterIteratorTest extends RealIteratorTestCase
{
    /**
     * @dataProvider getAcceptData
     */
    public function testAccept($size, $expected)
    {
        $inner = new InnerSizeIterator(self::$files);

        $iterator = new SizeRangeFilterIterator($inner, $size);

        $this->assertIterator($expected, $iterator);
    }

    public function getAcceptData()
    {
        $lessThan1KGreaterThan05K = array(
            '.foo',
            '.git',
            'foo',
            'test.php',
            'toto',
            'toto/.git',
        );

        return array(
            array(array(new NumberComparator('< 1K'), new NumberComparator('> 0.5K')), $this->toAbsolute($lessThan1KGreaterThan05K)),
        );
    }
}

class InnerSizeIterator extends \ArrayIterator
{
    public function current()
    {
        return new \SplFileInfo(parent::current());
    }

    public function getFilename()
    {
        return parent::current();
    }

    public function isFile()
    {
        return $this->current()->isFile();
    }

    public function getSize()
    {
        return $this->current()->getSize();
    }
}
PKϤ$Z%s�uf
f
*finder/Tests/Iterator/IteratorTestCase.phpnu�[���<?php

/*
 * This file is part of the Symfony package.
 *
 * (c) Fabien Potencier <fabien@symfony.com>
 *
 * For the full copyright and license information, please view the LICENSE
 * file that was distributed with this source code.
 */

namespace Symfony\Component\Finder\Tests\Iterator;

abstract class IteratorTestCase extends \PHPUnit_Framework_TestCase
{
    protected function assertIterator($expected, \Traversable $iterator)
    {
        // set iterator_to_array $use_key to false to avoid values merge
        // this made FinderTest::testAppendWithAnArray() fail with GnuFinderAdapter
        $values = array_map(function (\SplFileInfo $fileinfo) { return str_replace('/', DIRECTORY_SEPARATOR, $fileinfo->getPathname()); }, iterator_to_array($iterator, false));

        $expected = array_map(function ($path) { return str_replace('/', DIRECTORY_SEPARATOR, $path); }, $expected);

        sort($values);
        sort($expected);

        $this->assertEquals($expected, array_values($values));
    }

    protected function assertOrderedIterator($expected, \Traversable $iterator)
    {
        $values = array_map(function (\SplFileInfo $fileinfo) { return $fileinfo->getPathname(); }, iterator_to_array($iterator));

        $this->assertEquals($expected, array_values($values));
    }

    /**
     *  Same as assertOrderedIterator, but checks the order of groups of
     *  array elements.
     *
     *  @param array $expected - an array of arrays. For any two subarrays
     *      $a and $b such that $a goes before $b in $expected, the method
     *      asserts that any element of $a goes before any element of $b
     *      in the sequence generated by $iterator
     *  @param \Traversable $iterator
     */
    protected function assertOrderedIteratorForGroups($expected, \Traversable $iterator)
    {
        $values = array_values(array_map(function (\SplFileInfo $fileinfo) { return $fileinfo->getPathname(); }, iterator_to_array($iterator)));

        foreach ($expected as $subarray) {
            $temp = array();
            while (count($values) && count($temp) < count($subarray)) {
                $temp[] = array_shift($values);
            }
            sort($temp);
            sort($subarray);
            $this->assertEquals($subarray, $temp);
        }
    }

    /**
     * Same as IteratorTestCase::assertIterator with foreach usage.
     *
     * @param array        $expected
     * @param \Traversable $iterator
     */
    protected function assertIteratorInForeach($expected, \Traversable $iterator)
    {
        $values = array();
        foreach ($iterator as $file) {
            $this->assertInstanceOf('Symfony\\Component\\Finder\\SplFileInfo', $file);
            $values[] = $file->getPathname();
        }

        sort($values);
        sort($expected);

        $this->assertEquals($expected, array_values($values));
    }

    /**
     * Same as IteratorTestCase::assertOrderedIterator with foreach usage.
     *
     * @param array        $expected
     * @param \Traversable $iterator
     */
    protected function assertOrderedIteratorInForeach($expected, \Traversable $iterator)
    {
        $values = array();
        foreach ($iterator as $file) {
            $this->assertInstanceOf('Symfony\\Component\\Finder\\SplFileInfo', $file);
            $values[] = $file->getPathname();
        }

        $this->assertEquals($expected, array_values($values));
    }
}
PKϤ$ZYuG
vv.finder/Tests/Iterator/SortableIteratorTest.phpnu�[���<?php

/*
 * This file is part of the Symfony package.
 *
 * (c) Fabien Potencier <fabien@symfony.com>
 *
 * For the full copyright and license information, please view the LICENSE
 * file that was distributed with this source code.
 */

namespace Symfony\Component\Finder\Tests\Iterator;

use Symfony\Component\Finder\Iterator\SortableIterator;

class SortableIteratorTest extends RealIteratorTestCase
{
    public function testConstructor()
    {
        try {
            new SortableIterator(new Iterator(array()), 'foobar');
            $this->fail('__construct() throws an \InvalidArgumentException exception if the mode is not valid');
        } catch (\Exception $e) {
            $this->assertInstanceOf('InvalidArgumentException', $e, '__construct() throws an \InvalidArgumentException exception if the mode is not valid');
        }
    }

    /**
     * @dataProvider getAcceptData
     */
    public function testAccept($mode, $expected)
    {
        if (!is_callable($mode)) {
            switch ($mode) {
                case SortableIterator::SORT_BY_ACCESSED_TIME :
                    if ('\\' === DIRECTORY_SEPARATOR) {
                        touch(self::toAbsolute('.git'));
                    } else {
                        file_get_contents(self::toAbsolute('.git'));
                    }
                    sleep(1);
                    file_get_contents(self::toAbsolute('.bar'));
                    break;
                case SortableIterator::SORT_BY_CHANGED_TIME :
                    file_put_contents(self::toAbsolute('test.php'), 'foo');
                    sleep(1);
                    file_put_contents(self::toAbsolute('test.py'), 'foo');
                    break;
                case SortableIterator::SORT_BY_MODIFIED_TIME :
                    file_put_contents(self::toAbsolute('test.php'), 'foo');
                    sleep(1);
                    file_put_contents(self::toAbsolute('test.py'), 'foo');
                    break;
            }
        }

        $inner = new Iterator(self::$files);

        $iterator = new SortableIterator($inner, $mode);

        if ($mode === SortableIterator::SORT_BY_ACCESSED_TIME
            || $mode === SortableIterator::SORT_BY_CHANGED_TIME
            || $mode === SortableIterator::SORT_BY_MODIFIED_TIME
        ) {
            if ('\\' === DIRECTORY_SEPARATOR && SortableIterator::SORT_BY_MODIFIED_TIME !== $mode) {
                $this->markTestSkipped('Sorting by atime or ctime is not supported on Windows');
            }
            $this->assertOrderedIteratorForGroups($expected, $iterator);
        } else {
            $this->assertOrderedIterator($expected, $iterator);
        }
    }

    public function getAcceptData()
    {
        $sortByName = array(
            '.bar',
            '.foo',
            '.foo/.bar',
            '.foo/bar',
            '.git',
            'foo',
            'foo bar',
            'foo/bar.tmp',
            'test.php',
            'test.py',
            'toto',
            'toto/.git',
        );

        $sortByType = array(
            '.foo',
            '.git',
            'foo',
            'toto',
            'toto/.git',
            '.bar',
            '.foo/.bar',
            '.foo/bar',
            'foo bar',
            'foo/bar.tmp',
            'test.php',
            'test.py',
        );

        $customComparison = array(
            '.bar',
            '.foo',
            '.foo/.bar',
            '.foo/bar',
            '.git',
            'foo',
            'foo bar',
            'foo/bar.tmp',
            'test.php',
            'test.py',
            'toto',
            'toto/.git',
        );

        $sortByAccessedTime = array(
            // For these two files the access time was set to 2005-10-15
            array('foo/bar.tmp', 'test.php'),
            // These files were created more or less at the same time
            array(
                '.git',
                '.foo',
                '.foo/.bar',
                '.foo/bar',
                'test.py',
                'foo',
                'toto',
                'toto/.git',
                'foo bar',
            ),
            // This file was accessed after sleeping for 1 sec
            array('.bar'),
        );

        $sortByChangedTime = array(
            array(
                '.git',
                '.foo',
                '.foo/.bar',
                '.foo/bar',
                '.bar',
                'foo',
                'foo/bar.tmp',
                'toto',
                'toto/.git',
                'foo bar',
            ),
            array('test.php'),
            array('test.py'),
        );

        $sortByModifiedTime = array(
            array(
                '.git',
                '.foo',
                '.foo/.bar',
                '.foo/bar',
                '.bar',
                'foo',
                'foo/bar.tmp',
                'toto',
                'toto/.git',
                'foo bar',
            ),
            array('test.php'),
            array('test.py'),
        );

        return array(
            array(SortableIterator::SORT_BY_NAME, $this->toAbsolute($sortByName)),
            array(SortableIterator::SORT_BY_TYPE, $this->toAbsolute($sortByType)),
            array(SortableIterator::SORT_BY_ACCESSED_TIME, $this->toAbsolute($sortByAccessedTime)),
            array(SortableIterator::SORT_BY_CHANGED_TIME, $this->toAbsolute($sortByChangedTime)),
            array(SortableIterator::SORT_BY_MODIFIED_TIME, $this->toAbsolute($sortByModifiedTime)),
            array(function (\SplFileInfo $a, \SplFileInfo $b) { return strcmp($a->getRealPath(), $b->getRealPath()); }, $this->toAbsolute($customComparison)),
        );
    }
}
PKϤ$Z��j7��2finder/Tests/Iterator/CustomFilterIteratorTest.phpnu�[���<?php

/*
 * This file is part of the Symfony package.
 *
 * (c) Fabien Potencier <fabien@symfony.com>
 *
 * For the full copyright and license information, please view the LICENSE
 * file that was distributed with this source code.
 */

namespace Symfony\Component\Finder\Tests\Iterator;

use Symfony\Component\Finder\Iterator\CustomFilterIterator;

class CustomFilterIteratorTest extends IteratorTestCase
{
    /**
     * @expectedException \InvalidArgumentException
     */
    public function testWithInvalidFilter()
    {
        new CustomFilterIterator(new Iterator(), array('foo'));
    }

    /**
     * @dataProvider getAcceptData
     */
    public function testAccept($filters, $expected)
    {
        $inner = new Iterator(array('test.php', 'test.py', 'foo.php'));

        $iterator = new CustomFilterIterator($inner, $filters);

        $this->assertIterator($expected, $iterator);
    }

    public function getAcceptData()
    {
        return array(
            array(array(function (\SplFileInfo $fileinfo) { return false; }), array()),
            array(array(function (\SplFileInfo $fileinfo) { return 0 === strpos($fileinfo, 'test'); }), array('test.php', 'test.py')),
            array(array('is_dir'), array()),
        );
    }
}
PKϤ$Z3HUU,finder/Tests/Iterator/FilterIteratorTest.phpnu�[���<?php

/*
 * This file is part of the Symfony package.
 *
 * (c) Fabien Potencier <fabien@symfony.com>
 *
 * For the full copyright and license information, please view the LICENSE
 * file that was distributed with this source code.
 */

namespace Symfony\Component\Finder\Tests\Iterator;

/**
 * @author Alex Bogomazov
 */
class FilterIteratorTest extends RealIteratorTestCase
{
    public function testFilterFilesystemIterators()
    {
        $i = new \FilesystemIterator($this->toAbsolute());

        // it is expected that there are test.py test.php in the tmpDir
        $i = $this->getMockForAbstractClass('Symfony\Component\Finder\Iterator\FilterIterator', array($i));
        $i->expects($this->any())
            ->method('accept')
            ->will($this->returnCallback(function () use ($i) {
                return (bool) preg_match('/\.php/', (string) $i->current());
            })
        );

        $c = 0;
        foreach ($i as $item) {
            ++$c;
        }

        $this->assertEquals(1, $c);

        $i->rewind();

        $c = 0;
        foreach ($i as $item) {
            ++$c;
        }

        // This would fail in php older than 5.5.23/5.6.7 with \FilterIterator
        // but works with Symfony\Component\Finder\Iterator\FilterIterator
        // see https://bugs.php.net/68557
        $this->assertEquals(1, $c);
    }
}
PKϤ$Z����gg4finder/Tests/Iterator/FileTypeFilterIteratorTest.phpnu�[���<?php

/*
 * This file is part of the Symfony package.
 *
 * (c) Fabien Potencier <fabien@symfony.com>
 *
 * For the full copyright and license information, please view the LICENSE
 * file that was distributed with this source code.
 */

namespace Symfony\Component\Finder\Tests\Iterator;

use Symfony\Component\Finder\Iterator\FileTypeFilterIterator;

class FileTypeFilterIteratorTest extends RealIteratorTestCase
{
    /**
     * @dataProvider getAcceptData
     */
    public function testAccept($mode, $expected)
    {
        $inner = new InnerTypeIterator(self::$files);

        $iterator = new FileTypeFilterIterator($inner, $mode);

        $this->assertIterator($expected, $iterator);
    }

    public function getAcceptData()
    {
        $onlyFiles = array(
            'test.py',
            'foo/bar.tmp',
            'test.php',
            '.bar',
            '.foo/.bar',
            '.foo/bar',
            'foo bar',
        );

        $onlyDirectories = array(
            '.git',
            'foo',
            'toto',
            'toto/.git',
            '.foo',
        );

        return array(
            array(FileTypeFilterIterator::ONLY_FILES, $this->toAbsolute($onlyFiles)),
            array(FileTypeFilterIterator::ONLY_DIRECTORIES, $this->toAbsolute($onlyDirectories)),
        );
    }
}

class InnerTypeIterator extends \ArrayIterator
{
    public function current()
    {
        return new \SplFileInfo(parent::current());
    }

    public function isFile()
    {
        return $this->current()->isFile();
    }

    public function isDir()
    {
        return $this->current()->isDir();
    }
}
PKϤ$Z�b�m
m
)finder/Tests/Iterator/MockSplFileInfo.phpnu�[���<?php

/*
 * This file is part of the Symfony package.
 *
 * (c) Fabien Potencier <fabien@symfony.com>
 *
 * For the full copyright and license information, please view the LICENSE
 * file that was distributed with this source code.
 */

namespace Symfony\Component\Finder\Tests\Iterator;

class MockSplFileInfo extends \SplFileInfo
{
    const   TYPE_DIRECTORY = 1;
    const   TYPE_FILE = 2;
    const   TYPE_UNKNOWN = 3;

    private $contents = null;
    private $mode = null;
    private $type = null;
    private $relativePath = null;
    private $relativePathname = null;

    public function __construct($param)
    {
        if (is_string($param)) {
            parent::__construct($param);
        } elseif (is_array($param)) {
            $defaults = array(
              'name' => 'file.txt',
              'contents' => null,
              'mode' => null,
              'type' => null,
              'relativePath' => null,
              'relativePathname' => null,
            );
            $defaults = array_merge($defaults, $param);
            parent::__construct($defaults['name']);
            $this->setContents($defaults['contents']);
            $this->setMode($defaults['mode']);
            $this->setType($defaults['type']);
            $this->setRelativePath($defaults['relativePath']);
            $this->setRelativePathname($defaults['relativePathname']);
        } else {
            throw new \RuntimeException(sprintf('Incorrect parameter "%s"', $param));
        }
    }

    public function isFile()
    {
        if (null === $this->type) {
            return false !== strpos($this->getFilename(), 'file');
        }

        return self::TYPE_FILE === $this->type;
    }

    public function isDir()
    {
        if (null === $this->type) {
            return false !== strpos($this->getFilename(), 'directory');
        }

        return self::TYPE_DIRECTORY === $this->type;
    }

    public function isReadable()
    {
        if (null === $this->mode) {
            return preg_match('/r\+/', $this->getFilename());
        }

        return preg_match('/r\+/', $this->mode);
    }

    public function getContents()
    {
        return $this->contents;
    }

    public function setContents($contents)
    {
        $this->contents = $contents;
    }

    public function setMode($mode)
    {
        $this->mode = $mode;
    }

    public function setType($type)
    {
        if (is_string($type)) {
            switch ($type) {
                case 'directory':
                    $this->type = self::TYPE_DIRECTORY;
                case 'd':
                    $this->type = self::TYPE_DIRECTORY;
                    break;
                case 'file':
                    $this->type = self::TYPE_FILE;
                case 'f':
                    $this->type = self::TYPE_FILE;
                    break;
                default:
                    $this->type = self::TYPE_UNKNOWN;
            }
        } else {
            $this->type = $type;
        }
    }

    public function setRelativePath($relativePath)
    {
        $this->relativePath = $relativePath;
    }

    public function setRelativePathname($relativePathname)
    {
        $this->relativePathname = $relativePathname;
    }

    public function getRelativePath()
    {
        return $this->relativePath;
    }

    public function getRelativePathname()
    {
        return $this->relativePathname;
    }
}
PKϤ$Z�c�Ŕ�<finder/Tests/Iterator/ExcludeDirectoryFilterIteratorTest.phpnu�[���<?php

/*
 * This file is part of the Symfony package.
 *
 * (c) Fabien Potencier <fabien@symfony.com>
 *
 * For the full copyright and license information, please view the LICENSE
 * file that was distributed with this source code.
 */

namespace Symfony\Component\Finder\Tests\Iterator;

use Symfony\Component\Finder\Iterator\ExcludeDirectoryFilterIterator;
use Symfony\Component\Finder\Iterator\RecursiveDirectoryIterator;

class ExcludeDirectoryFilterIteratorTest extends RealIteratorTestCase
{
    /**
     * @dataProvider getAcceptData
     */
    public function testAccept($directories, $expected)
    {
        $inner = new \RecursiveIteratorIterator(new RecursiveDirectoryIterator($this->toAbsolute(), \FilesystemIterator::SKIP_DOTS), \RecursiveIteratorIterator::SELF_FIRST);

        $iterator = new ExcludeDirectoryFilterIterator($inner, $directories);

        $this->assertIterator($expected, $iterator);
    }

    public function getAcceptData()
    {
        $foo = array(
            '.bar',
            '.foo',
            '.foo/.bar',
            '.foo/bar',
            '.git',
            'test.py',
            'test.php',
            'toto',
            'toto/.git',
            'foo bar',
        );

        $fo = array(
            '.bar',
            '.foo',
            '.foo/.bar',
            '.foo/bar',
            '.git',
            'test.py',
            'foo',
            'foo/bar.tmp',
            'test.php',
            'toto',
            'toto/.git',
            'foo bar',
        );

        return array(
            array(array('foo'), $this->toAbsolute($foo)),
            array(array('fo'), $this->toAbsolute($fo)),
        );
    }
}
PKϤ$Zd����8finder/Tests/Iterator/MultiplePcreFilterIteratorTest.phpnu�[���<?php

/*
 * This file is part of the Symfony package.
 *
 * (c) Fabien Potencier <fabien@symfony.com>
 *
 * For the full copyright and license information, please view the LICENSE
 * file that was distributed with this source code.
 */

namespace Symfony\Component\Finder\Tests\Iterator;

use Symfony\Component\Finder\Iterator\MultiplePcreFilterIterator;

class MultiplePcreFilterIteratorTest extends \PHPUnit_Framework_TestCase
{
    /**
     * @dataProvider getIsRegexFixtures
     */
    public function testIsRegex($string, $isRegex, $message)
    {
        $testIterator = new TestMultiplePcreFilterIterator();
        $this->assertEquals($isRegex, $testIterator->isRegex($string), $message);
    }

    public function getIsRegexFixtures()
    {
        return array(
            array('foo', false, 'string'),
            array(' foo ', false, '" " is not a valid delimiter'),
            array('\\foo\\', false, '"\\" is not a valid delimiter'),
            array('afooa', false, '"a" is not a valid delimiter'),
            array('//', false, 'the pattern should contain at least 1 character'),
            array('/a/', true, 'valid regex'),
            array('/foo/', true, 'valid regex'),
            array('/foo/i', true, 'valid regex with a single modifier'),
            array('/foo/imsxu', true, 'valid regex with multiple modifiers'),
            array('#foo#', true, '"#" is a valid delimiter'),
            array('{foo}', true, '"{,}" is a valid delimiter pair'),
            array('[foo]', true, '"[,]" is a valid delimiter pair'),
            array('(foo)', true, '"(,)" is a valid delimiter pair'),
            array('<foo>', true, '"<,>" is a valid delimiter pair'),
            array('*foo.*', false, '"*" is not considered as a valid delimiter'),
            array('?foo.?', false, '"?" is not considered as a valid delimiter'),
        );
    }
}

class TestMultiplePcreFilterIterator extends MultiplePcreFilterIterator
{
    public function __construct()
    {
    }

    public function accept()
    {
        throw new \BadFunctionCallException('Not implemented');
    }

    public function isRegex($str)
    {
        return parent::isRegex($str);
    }

    public function toRegex($str)
    {
        throw new \BadFunctionCallException('Not implemented');
    }
}
PKϤ$ZE�>>/finder/Tests/Iterator/FilePathsIteratorTest.phpnu�[���<?php

/*
 * This file is part of the Symfony package.
 *
 * (c) Fabien Potencier <fabien@symfony.com>
 *
 * For the full copyright and license information, please view the LICENSE
 * file that was distributed with this source code.
 */

namespace Symfony\Component\Finder\Tests\Iterator;

use Symfony\Component\Finder\Iterator\FilePathsIterator;

/**
 * @group legacy
 */
class FilePathsIteratorTest extends RealIteratorTestCase
{
    /**
     * @dataProvider getSubPathData
     */
    public function testSubPath($baseDir, array $paths, array $subPaths, array $subPathnames)
    {
        $iterator = new FilePathsIterator($paths, $baseDir);

        foreach ($iterator as $index => $file) {
            $this->assertEquals($paths[$index], $file->getPathname());
            $this->assertEquals($subPaths[$index], $iterator->getSubPath());
            $this->assertEquals($subPathnames[$index], $iterator->getSubPathname());
        }
    }

    public function getSubPathData()
    {
        $tmpDir = sys_get_temp_dir().'/symfony_finder';

        return array(
            array(
                $tmpDir,
                array(
                    // paths
                    $tmpDir.DIRECTORY_SEPARATOR.'.git' => $tmpDir.DIRECTORY_SEPARATOR.'.git',
                    $tmpDir.DIRECTORY_SEPARATOR.'test.py' => $tmpDir.DIRECTORY_SEPARATOR.'test.py',
                    $tmpDir.DIRECTORY_SEPARATOR.'foo' => $tmpDir.DIRECTORY_SEPARATOR.'foo',
                    $tmpDir.DIRECTORY_SEPARATOR.'foo'.DIRECTORY_SEPARATOR.'bar.tmp' => $tmpDir.DIRECTORY_SEPARATOR.'foo'.DIRECTORY_SEPARATOR.'bar.tmp',
                    $tmpDir.DIRECTORY_SEPARATOR.'test.php' => $tmpDir.DIRECTORY_SEPARATOR.'test.php',
                    $tmpDir.DIRECTORY_SEPARATOR.'toto' => $tmpDir.DIRECTORY_SEPARATOR.'toto',
                ),
                array(
                    // subPaths
                    $tmpDir.DIRECTORY_SEPARATOR.'.git' => '',
                    $tmpDir.DIRECTORY_SEPARATOR.'test.py' => '',
                    $tmpDir.DIRECTORY_SEPARATOR.'foo' => '',
                    $tmpDir.DIRECTORY_SEPARATOR.'foo'.DIRECTORY_SEPARATOR.'bar.tmp' => 'foo',
                    $tmpDir.DIRECTORY_SEPARATOR.'test.php' => '',
                    $tmpDir.DIRECTORY_SEPARATOR.'toto' => '',
                ),
                array(
                    // subPathnames
                    $tmpDir.DIRECTORY_SEPARATOR.'.git' => '.git',
                    $tmpDir.DIRECTORY_SEPARATOR.'test.py' => 'test.py',
                    $tmpDir.DIRECTORY_SEPARATOR.'foo' => 'foo',
                    $tmpDir.DIRECTORY_SEPARATOR.'foo'.DIRECTORY_SEPARATOR.'bar.tmp' => 'foo'.DIRECTORY_SEPARATOR.'bar.tmp',
                    $tmpDir.DIRECTORY_SEPARATOR.'test.php' => 'test.php',
                    $tmpDir.DIRECTORY_SEPARATOR.'toto' => 'toto',
                ),
            ),
        );
    }
}
PKϤ$Z��]ss6finder/Tests/Iterator/DepthRangeFilterIteratorTest.phpnu�[���<?php

/*
 * This file is part of the Symfony package.
 *
 * (c) Fabien Potencier <fabien@symfony.com>
 *
 * For the full copyright and license information, please view the LICENSE
 * file that was distributed with this source code.
 */

namespace Symfony\Component\Finder\Tests\Iterator;

use Symfony\Component\Finder\Iterator\DepthRangeFilterIterator;

class DepthRangeFilterIteratorTest extends RealIteratorTestCase
{
    /**
     * @dataProvider getAcceptData
     */
    public function testAccept($minDepth, $maxDepth, $expected)
    {
        $inner = new \RecursiveIteratorIterator(new \RecursiveDirectoryIterator($this->toAbsolute(), \FilesystemIterator::SKIP_DOTS), \RecursiveIteratorIterator::SELF_FIRST);

        $iterator = new DepthRangeFilterIterator($inner, $minDepth, $maxDepth);

        $actual = array_keys(iterator_to_array($iterator));
        sort($expected);
        sort($actual);
        $this->assertEquals($expected, $actual);
    }

    public function getAcceptData()
    {
        $lessThan1 = array(
            '.git',
            'test.py',
            'foo',
            'test.php',
            'toto',
            '.foo',
            '.bar',
            'foo bar',
        );

        $lessThanOrEqualTo1 = array(
            '.git',
            'test.py',
            'foo',
            'foo/bar.tmp',
            'test.php',
            'toto',
            'toto/.git',
            '.foo',
            '.foo/.bar',
            '.bar',
            'foo bar',
            '.foo/bar',
        );

        $graterThanOrEqualTo1 = array(
            'toto/.git',
            'foo/bar.tmp',
            '.foo/.bar',
            '.foo/bar',
        );

        $equalTo1 = array(
            'toto/.git',
            'foo/bar.tmp',
            '.foo/.bar',
            '.foo/bar',
        );

        return array(
            array(0, 0, $this->toAbsolute($lessThan1)),
            array(0, 1, $this->toAbsolute($lessThanOrEqualTo1)),
            array(2, PHP_INT_MAX, array()),
            array(1, PHP_INT_MAX, $this->toAbsolute($graterThanOrEqualTo1)),
            array(1, 1, $this->toAbsolute($equalTo1)),
        );
    }
}
PKϤ$Z�7���4finder/Tests/Iterator/FilenameFilterIteratorTest.phpnu�[���<?php

/*
 * This file is part of the Symfony package.
 *
 * (c) Fabien Potencier <fabien@symfony.com>
 *
 * For the full copyright and license information, please view the LICENSE
 * file that was distributed with this source code.
 */

namespace Symfony\Component\Finder\Tests\Iterator;

use Symfony\Component\Finder\Iterator\FilenameFilterIterator;

class FilenameFilterIteratorTest extends IteratorTestCase
{
    /**
     * @dataProvider getAcceptData
     */
    public function testAccept($matchPatterns, $noMatchPatterns, $expected)
    {
        $inner = new InnerNameIterator(array('test.php', 'test.py', 'foo.php'));

        $iterator = new FilenameFilterIterator($inner, $matchPatterns, $noMatchPatterns);

        $this->assertIterator($expected, $iterator);
    }

    public function getAcceptData()
    {
        return array(
            array(array('test.*'), array(), array('test.php', 'test.py')),
            array(array(), array('test.*'), array('foo.php')),
            array(array('*.php'), array('test.*'), array('foo.php')),
            array(array('*.php', '*.py'), array('foo.*'), array('test.php', 'test.py')),
            array(array('/\.php$/'), array(), array('test.php', 'foo.php')),
            array(array(), array('/\.php$/'), array('test.py')),
        );
    }
}

class InnerNameIterator extends \ArrayIterator
{
    public function current()
    {
        return new \SplFileInfo(parent::current());
    }

    public function getFilename()
    {
        return parent::current();
    }
}
PKϤ$Z�S�"finder/Tests/Iterator/Iterator.phpnu�[���<?php

/*
 * This file is part of the Symfony package.
 *
 * (c) Fabien Potencier <fabien@symfony.com>
 *
 * For the full copyright and license information, please view the LICENSE
 * file that was distributed with this source code.
 */

namespace Symfony\Component\Finder\Tests\Iterator;

class Iterator implements \Iterator
{
    protected $values = array();

    public function __construct(array $values = array())
    {
        foreach ($values as $value) {
            $this->attach(new \SplFileInfo($value));
        }
        $this->rewind();
    }

    public function attach(\SplFileInfo $fileinfo)
    {
        $this->values[] = $fileinfo;
    }

    public function rewind()
    {
        reset($this->values);
    }

    public function valid()
    {
        return false !== $this->current();
    }

    public function next()
    {
        next($this->values);
    }

    public function current()
    {
        return current($this->values);
    }

    public function key()
    {
        return key($this->values);
    }
}
PKϤ$Z��v�r
r
7finder/Tests/Iterator/FilecontentFilterIteratorTest.phpnu�[���<?php

/*
 * This file is part of the Symfony package.
 *
 * (c) Fabien Potencier <fabien@symfony.com>
 *
 * For the full copyright and license information, please view the LICENSE
 * file that was distributed with this source code.
 */

namespace Symfony\Component\Finder\Tests\Iterator;

use Symfony\Component\Finder\Iterator\FilecontentFilterIterator;

class FilecontentFilterIteratorTest extends IteratorTestCase
{
    public function testAccept()
    {
        $inner = new MockFileListIterator(array('test.txt'));
        $iterator = new FilecontentFilterIterator($inner, array(), array());
        $this->assertIterator(array('test.txt'), $iterator);
    }

    public function testDirectory()
    {
        $inner = new MockFileListIterator(array('directory'));
        $iterator = new FilecontentFilterIterator($inner, array('directory'), array());
        $this->assertIterator(array(), $iterator);
    }

    public function testUnreadableFile()
    {
        $inner = new MockFileListIterator(array('file r-'));
        $iterator = new FilecontentFilterIterator($inner, array('file r-'), array());
        $this->assertIterator(array(), $iterator);
    }

    /**
     * @dataProvider getTestFilterData
     */
    public function testFilter(\Iterator $inner, array $matchPatterns, array $noMatchPatterns, array $resultArray)
    {
        $iterator = new FilecontentFilterIterator($inner, $matchPatterns, $noMatchPatterns);
        $this->assertIterator($resultArray, $iterator);
    }

    public function getTestFilterData()
    {
        $inner = new MockFileListIterator();

        $inner[] = new MockSplFileInfo(array(
            'name' => 'a.txt',
            'contents' => 'Lorem ipsum...',
            'type' => 'file',
            'mode' => 'r+', )
        );

        $inner[] = new MockSplFileInfo(array(
            'name' => 'b.yml',
            'contents' => 'dolor sit...',
            'type' => 'file',
            'mode' => 'r+', )
        );

        $inner[] = new MockSplFileInfo(array(
            'name' => 'some/other/dir/third.php',
            'contents' => 'amet...',
            'type' => 'file',
            'mode' => 'r+', )
        );

        $inner[] = new MockSplFileInfo(array(
            'name' => 'unreadable-file.txt',
            'contents' => false,
            'type' => 'file',
            'mode' => 'r+', )
        );

        return array(
            array($inner, array('.'), array(), array('a.txt', 'b.yml', 'some/other/dir/third.php')),
            array($inner, array('ipsum'), array(), array('a.txt')),
            array($inner, array('i', 'amet'), array('Lorem', 'amet'), array('b.yml')),
        );
    }
}
PKϤ$Z`"����0finder/Tests/Iterator/PathFilterIteratorTest.phpnu�[���<?php

/*
 * This file is part of the Symfony package.
 *
 * (c) Fabien Potencier <fabien@symfony.com>
 *
 * For the full copyright and license information, please view the LICENSE
 * file that was distributed with this source code.
 */

namespace Symfony\Component\Finder\Tests\Iterator;

use Symfony\Component\Finder\Iterator\PathFilterIterator;

class PathFilterIteratorTest extends IteratorTestCase
{
    /**
     * @dataProvider getTestFilterData
     */
    public function testFilter(\Iterator $inner, array $matchPatterns, array $noMatchPatterns, array $resultArray)
    {
        $iterator = new PathFilterIterator($inner, $matchPatterns, $noMatchPatterns);
        $this->assertIterator($resultArray, $iterator);
    }

    public function getTestFilterData()
    {
        $inner = new MockFileListIterator();

        //PATH:   A/B/C/abc.dat
        $inner[] = new MockSplFileInfo(array(
            'name' => 'abc.dat',
            'relativePathname' => 'A'.DIRECTORY_SEPARATOR.'B'.DIRECTORY_SEPARATOR.'C'.DIRECTORY_SEPARATOR.'abc.dat',
        ));

        //PATH:   A/B/ab.dat
        $inner[] = new MockSplFileInfo(array(
            'name' => 'ab.dat',
            'relativePathname' => 'A'.DIRECTORY_SEPARATOR.'B'.DIRECTORY_SEPARATOR.'ab.dat',
        ));

        //PATH:   A/a.dat
        $inner[] = new MockSplFileInfo(array(
            'name' => 'a.dat',
            'relativePathname' => 'A'.DIRECTORY_SEPARATOR.'a.dat',
        ));

        //PATH:   copy/A/B/C/abc.dat.copy
        $inner[] = new MockSplFileInfo(array(
            'name' => 'abc.dat.copy',
            'relativePathname' => 'copy'.DIRECTORY_SEPARATOR.'A'.DIRECTORY_SEPARATOR.'B'.DIRECTORY_SEPARATOR.'C'.DIRECTORY_SEPARATOR.'abc.dat',
        ));

        //PATH:   copy/A/B/ab.dat.copy
        $inner[] = new MockSplFileInfo(array(
            'name' => 'ab.dat.copy',
            'relativePathname' => 'copy'.DIRECTORY_SEPARATOR.'A'.DIRECTORY_SEPARATOR.'B'.DIRECTORY_SEPARATOR.'ab.dat',
        ));

        //PATH:   copy/A/a.dat.copy
        $inner[] = new MockSplFileInfo(array(
            'name' => 'a.dat.copy',
            'relativePathname' => 'copy'.DIRECTORY_SEPARATOR.'A'.DIRECTORY_SEPARATOR.'a.dat',
        ));

        return array(
            array($inner, array('/^A/'),       array(), array('abc.dat', 'ab.dat', 'a.dat')),
            array($inner, array('/^A\/B/'),    array(), array('abc.dat', 'ab.dat')),
            array($inner, array('/^A\/B\/C/'), array(), array('abc.dat')),
            array($inner, array('/A\/B\/C/'),  array(), array('abc.dat', 'abc.dat.copy')),

            array($inner, array('A'),      array(), array('abc.dat', 'ab.dat', 'a.dat', 'abc.dat.copy', 'ab.dat.copy', 'a.dat.copy')),
            array($inner, array('A/B'),    array(), array('abc.dat', 'ab.dat', 'abc.dat.copy', 'ab.dat.copy')),
            array($inner, array('A/B/C'),  array(), array('abc.dat', 'abc.dat.copy')),

            array($inner, array('copy/A'),      array(), array('abc.dat.copy', 'ab.dat.copy', 'a.dat.copy')),
            array($inner, array('copy/A/B'),    array(), array('abc.dat.copy', 'ab.dat.copy')),
            array($inner, array('copy/A/B/C'),  array(), array('abc.dat.copy')),

        );
    }
}
PKϤ$Z�y^	��.finder/Tests/Iterator/RealIteratorTestCase.phpnu�[���<?php

/*
 * This file is part of the Symfony package.
 *
 * (c) Fabien Potencier <fabien@symfony.com>
 *
 * For the full copyright and license information, please view the LICENSE
 * file that was distributed with this source code.
 */

namespace Symfony\Component\Finder\Tests\Iterator;

abstract class RealIteratorTestCase extends IteratorTestCase
{
    protected static $tmpDir;
    protected static $files;

    public static function setUpBeforeClass()
    {
        self::$tmpDir = realpath(sys_get_temp_dir()).DIRECTORY_SEPARATOR.'symfony_finder';

        self::$files = array(
            '.git/',
            '.foo/',
            '.foo/.bar',
            '.foo/bar',
            '.bar',
            'test.py',
            'foo/',
            'foo/bar.tmp',
            'test.php',
            'toto/',
            'toto/.git/',
            'foo bar',
        );

        self::$files = self::toAbsolute(self::$files);

        if (is_dir(self::$tmpDir)) {
            self::tearDownAfterClass();
        } else {
            mkdir(self::$tmpDir);
        }

        foreach (self::$files as $file) {
            if (DIRECTORY_SEPARATOR === $file[strlen($file) - 1]) {
                mkdir($file);
            } else {
                touch($file);
            }
        }

        file_put_contents(self::toAbsolute('test.php'), str_repeat(' ', 800));
        file_put_contents(self::toAbsolute('test.py'), str_repeat(' ', 2000));

        touch(self::toAbsolute('foo/bar.tmp'), strtotime('2005-10-15'));
        touch(self::toAbsolute('test.php'), strtotime('2005-10-15'));
    }

    public static function tearDownAfterClass()
    {
        foreach (array_reverse(self::$files) as $file) {
            if (DIRECTORY_SEPARATOR === $file[strlen($file) - 1]) {
                @rmdir($file);
            } else {
                @unlink($file);
            }
        }
    }

    protected static function toAbsolute($files = null)
    {
        /*
         * Without the call to setUpBeforeClass() property can be null.
         */
        if (!self::$tmpDir) {
            self::$tmpDir = realpath(sys_get_temp_dir()).DIRECTORY_SEPARATOR.'symfony_finder';
        }

        if (is_array($files)) {
            $f = array();
            foreach ($files as $file) {
                if (is_array($file)) {
                    $f[] = self::toAbsolute($file);
                } else {
                    $f[] = self::$tmpDir.DIRECTORY_SEPARATOR.str_replace('/', DIRECTORY_SEPARATOR, $file);
                }
            }

            return $f;
        }

        if (is_string($files)) {
            return self::$tmpDir.DIRECTORY_SEPARATOR.str_replace('/', DIRECTORY_SEPARATOR, $files);
        }

        return self::$tmpDir;
    }

    protected static function toAbsoluteFixtures($files)
    {
        $f = array();
        foreach ($files as $file) {
            $f[] = realpath(__DIR__.DIRECTORY_SEPARATOR.'..'.DIRECTORY_SEPARATOR.'Fixtures'.DIRECTORY_SEPARATOR.$file);
        }

        return $f;
    }
}
PKϤ$Z�'�cnn5finder/Tests/Iterator/DateRangeFilterIteratorTest.phpnu�[���<?php

/*
 * This file is part of the Symfony package.
 *
 * (c) Fabien Potencier <fabien@symfony.com>
 *
 * For the full copyright and license information, please view the LICENSE
 * file that was distributed with this source code.
 */

namespace Symfony\Component\Finder\Tests\Iterator;

use Symfony\Component\Finder\Iterator\DateRangeFilterIterator;
use Symfony\Component\Finder\Comparator\DateComparator;

class DateRangeFilterIteratorTest extends RealIteratorTestCase
{
    /**
     * @dataProvider getAcceptData
     */
    public function testAccept($size, $expected)
    {
        $files = self::$files;
        $files[] = self::toAbsolute('doesnotexist');
        $inner = new Iterator($files);

        $iterator = new DateRangeFilterIterator($inner, $size);

        $this->assertIterator($expected, $iterator);
    }

    public function getAcceptData()
    {
        $since20YearsAgo = array(
            '.git',
            'test.py',
            'foo',
            'foo/bar.tmp',
            'test.php',
            'toto',
            'toto/.git',
            '.bar',
            '.foo',
            '.foo/.bar',
            'foo bar',
            '.foo/bar',
        );

        $since2MonthsAgo = array(
            '.git',
            'test.py',
            'foo',
            'toto',
            'toto/.git',
            '.bar',
            '.foo',
            '.foo/.bar',
            'foo bar',
            '.foo/bar',
        );

        $untilLastMonth = array(
            'foo/bar.tmp',
            'test.php',
        );

        return array(
            array(array(new DateComparator('since 20 years ago')), $this->toAbsolute($since20YearsAgo)),
            array(array(new DateComparator('since 2 months ago')), $this->toAbsolute($since2MonthsAgo)),
            array(array(new DateComparator('until last month')), $this->toAbsolute($untilLastMonth)),
        );
    }
}
PKϤ$Z�[+((.finder/Tests/Iterator/MockFileListIterator.phpnu�[���<?php

/*
 * This file is part of the Symfony package.
 *
 * (c) Fabien Potencier <fabien@symfony.com>
 *
 * For the full copyright and license information, please view the LICENSE
 * file that was distributed with this source code.
 */

namespace Symfony\Component\Finder\Tests\Iterator;

class MockFileListIterator extends \ArrayIterator
{
    public function __construct(array $filesArray = array())
    {
        $files = array_map(function ($file) { return new MockSplFileInfo($file); }, $filesArray);
        parent::__construct($files);
    }
}
PKϤ$Z�h{��*finder/Tests/Expression/ExpressionTest.phpnu�[���<?php

/*
 * This file is part of the Symfony package.
 *
 * (c) Fabien Potencier <fabien@symfony.com>
 *
 * For the full copyright and license information, please view the LICENSE
 * file that was distributed with this source code.
 */

namespace Symfony\Component\Finder\Tests\Expression;

use Symfony\Component\Finder\Expression\Expression;

/**
 * @group legacy
 */
class ExpressionTest extends \PHPUnit_Framework_TestCase
{
    /**
     * @dataProvider getTypeGuesserData
     */
    public function testTypeGuesser($expr, $type)
    {
        $this->assertEquals($type, Expression::create($expr)->getType());
    }

    /**
     * @dataProvider getCaseSensitiveData
     */
    public function testCaseSensitive($expr, $isCaseSensitive)
    {
        $this->assertEquals($isCaseSensitive, Expression::create($expr)->isCaseSensitive());
    }

    /**
     * @dataProvider getRegexRenderingData
     */
    public function testRegexRendering($expr, $body)
    {
        $this->assertEquals($body, Expression::create($expr)->renderPattern());
    }

    public function getTypeGuesserData()
    {
        return array(
            array('{foo}', Expression::TYPE_REGEX),
            array('/foo/', Expression::TYPE_REGEX),
            array('foo',   Expression::TYPE_GLOB),
            array('foo*',  Expression::TYPE_GLOB),
        );
    }

    public function getCaseSensitiveData()
    {
        return array(
            array('{foo}m', true),
            array('/foo/i', false),
            array('foo*',   true),
        );
    }

    public function getRegexRenderingData()
    {
        return array(
            array('{foo}m', 'foo'),
            array('/foo/i', 'foo'),
        );
    }
}
PKϤ$Z��u���%finder/Tests/Expression/RegexTest.phpnu�[���<?php

/*
 * This file is part of the Symfony package.
 *
 * (c) Fabien Potencier <fabien@symfony.com>
 *
 * For the full copyright and license information, please view the LICENSE
 * file that was distributed with this source code.
 */

namespace Symfony\Component\Finder\Tests\Expression;

use Symfony\Component\Finder\Expression\Expression;

/**
 * @group legacy
 */
class RegexTest extends \PHPUnit_Framework_TestCase
{
    /**
     * @dataProvider getHasFlagsData
     */
    public function testHasFlags($regex, $start, $end)
    {
        $expr = new Expression($regex);

        $this->assertEquals($start, $expr->getRegex()->hasStartFlag());
        $this->assertEquals($end, $expr->getRegex()->hasEndFlag());
    }

    /**
     * @dataProvider getHasJokersData
     */
    public function testHasJokers($regex, $start, $end)
    {
        $expr = new Expression($regex);

        $this->assertEquals($start, $expr->getRegex()->hasStartJoker());
        $this->assertEquals($end, $expr->getRegex()->hasEndJoker());
    }

    /**
     * @dataProvider getSetFlagsData
     */
    public function testSetFlags($regex, $start, $end, $expected)
    {
        $expr = new Expression($regex);
        $expr->getRegex()->setStartFlag($start)->setEndFlag($end);

        $this->assertEquals($expected, $expr->render());
    }

    /**
     * @dataProvider getSetJokersData
     */
    public function testSetJokers($regex, $start, $end, $expected)
    {
        $expr = new Expression($regex);
        $expr->getRegex()->setStartJoker($start)->setEndJoker($end);

        $this->assertEquals($expected, $expr->render());
    }

    public function testOptions()
    {
        $expr = new Expression('~abc~is');
        $expr->getRegex()->removeOption('i')->addOption('m');

        $this->assertEquals('~abc~sm', $expr->render());
    }

    public function testMixFlagsAndJokers()
    {
        $expr = new Expression('~^.*abc.*$~is');

        $expr->getRegex()->setStartFlag(false)->setEndFlag(false)->setStartJoker(false)->setEndJoker(false);
        $this->assertEquals('~abc~is', $expr->render());

        $expr->getRegex()->setStartFlag(true)->setEndFlag(true)->setStartJoker(true)->setEndJoker(true);
        $this->assertEquals('~^.*abc.*$~is', $expr->render());
    }

    /**
     * @dataProvider getReplaceJokersTestData
     */
    public function testReplaceJokers($regex, $expected)
    {
        $expr = new Expression($regex);
        $expr = $expr->getRegex()->replaceJokers('@');

        $this->assertEquals($expected, $expr->renderPattern());
    }

    public function getHasFlagsData()
    {
        return array(
            array('~^abc~', true, false),
            array('~abc$~', false, true),
            array('~abc~', false, false),
            array('~^abc$~', true, true),
            array('~^abc\\$~', true, false),
        );
    }

    public function getHasJokersData()
    {
        return array(
            array('~.*abc~', true, false),
            array('~abc.*~', false, true),
            array('~abc~', false, false),
            array('~.*abc.*~', true, true),
            array('~.*abc\\.*~', true, false),
        );
    }

    public function getSetFlagsData()
    {
        return array(
            array('~abc~', true, false, '~^abc~'),
            array('~abc~', false, true, '~abc$~'),
            array('~abc~', false, false, '~abc~'),
            array('~abc~', true, true, '~^abc$~'),
        );
    }

    public function getSetJokersData()
    {
        return array(
            array('~abc~', true, false, '~.*abc~'),
            array('~abc~', false, true, '~abc.*~'),
            array('~abc~', false, false, '~abc~'),
            array('~abc~', true, true, '~.*abc.*~'),
        );
    }

    public function getReplaceJokersTestData()
    {
        return array(
            array('~.abc~', '@abc'),
            array('~\\.abc~', '\\.abc'),
            array('~\\\\.abc~', '\\\\@abc'),
            array('~\\\\\\.abc~', '\\\\\\.abc'),
        );
    }
}
PKϤ$Z����$finder/Tests/Expression/GlobTest.phpnu�[���<?php

/*
 * This file is part of the Symfony package.
 *
 * (c) Fabien Potencier <fabien@symfony.com>
 *
 * For the full copyright and license information, please view the LICENSE
 * file that was distributed with this source code.
 */

namespace Symfony\Component\Finder\Tests\Expression;

use Symfony\Component\Finder\Expression\Expression;

/**
 * @group legacy
 */
class GlobTest extends \PHPUnit_Framework_TestCase
{
    /**
     * @dataProvider getToRegexData
     */
    public function testGlobToRegex($glob, $match, $noMatch)
    {
        foreach ($match as $m) {
            $this->assertRegExp(Expression::create($glob)->getRegex()->render(), $m, '::toRegex() converts a glob to a regexp');
        }

        foreach ($noMatch as $m) {
            $this->assertNotRegExp(Expression::create($glob)->getRegex()->render(), $m, '::toRegex() converts a glob to a regexp');
        }
    }

    public function getToRegexData()
    {
        return array(
            array('', array(''), array('f', '/')),
            array('*', array('foo'), array('foo/', '/foo')),
            array('foo.*', array('foo.php', 'foo.a', 'foo.'), array('fooo.php', 'foo.php/foo')),
            array('fo?', array('foo', 'fot'), array('fooo', 'ffoo', 'fo/')),
            array('fo{o,t}', array('foo', 'fot'), array('fob', 'fo/')),
            array('foo(bar|foo)', array('foo(bar|foo)'), array('foobar', 'foofoo')),
            array('foo,bar', array('foo,bar'), array('foo', 'bar')),
            array('fo{o,\\,}', array('foo', 'fo,'), array()),
            array('fo{o,\\\\}', array('foo', 'fo\\'), array()),
            array('/foo', array('/foo'), array('foo')),
        );
    }
}
PKϤ$Z��55finder/Tests/Fixtures/lorem.txtnu�[���lorem ipsum dolor sit amet
LOREM IPSUM DOLOR SIT AMETPKϤ$Z1finder/Tests/Fixtures/r+e.gex[c]a(r)s/dir/bar.datnu�[���PKϤ$Z(finder/Tests/Fixtures/with space/foo.txtnu�[���PKϤ$Z'���))finder/Tests/Fixtures/ipsum.txtnu�[���ipsum dolor sit amet
IPSUM DOLOR SIT AMETPKϤ$Zo�5|finder/Tests/Fixtures/dolor.txtnu�[���dolor sit amet
DOLOR SIT AMETPKϤ$Zfinder/Tests/Fixtures/A/a.datnu�[���PKϤ$Z finder/Tests/Fixtures/A/B/ab.datnu�[���PKϤ$Z#finder/Tests/Fixtures/A/B/C/abc.datnu�[���PKϤ$Zfinder/Tests/Fixtures/one/anu�[���PKϤ$Z"finder/Tests/Fixtures/one/b/d.neonnu�[���PKϤ$Z"finder/Tests/Fixtures/one/b/c.neonnu�[���PKϤ$Z*finder/Tests/Fixtures/copy/A/B/ab.dat.copynu�[���PKϤ$Z-finder/Tests/Fixtures/copy/A/B/C/abc.dat.copynu�[���PKϤ$Z'finder/Tests/Fixtures/copy/A/a.dat.copynu�[���PKϤ$Z`�2��)finder/Tests/FakeAdapter/NamedAdapter.phpnu�[���<?php

/*
 * This file is part of the Symfony package.
 *
 * (c) Fabien Potencier <fabien@symfony.com>
 *
 * For the full copyright and license information, please view the LICENSE
 * file that was distributed with this source code.
 */

namespace Symfony\Component\Finder\Tests\FakeAdapter;

use Symfony\Component\Finder\Adapter\AbstractAdapter;

/**
 * @author Jean-François Simon <contact@jfsimon.fr>
 */
class NamedAdapter extends AbstractAdapter
{
    /**
     * @var string
     */
    private $name;

    /**
     * @param string $name
     */
    public function __construct($name)
    {
        $this->name = $name;
    }

    /**
     * {@inheritdoc}
     */
    public function searchInDirectory($dir)
    {
        return new \ArrayIterator(array());
    }

    /**
     * {@inheritdoc}
     */
    public function getName()
    {
        return $this->name;
    }

    /**
     * {@inheritdoc}
     */
    protected function canBeUsed()
    {
        return true;
    }
}
PKϤ$Z/��00/finder/Tests/FakeAdapter/UnsupportedAdapter.phpnu�[���<?php

/*
 * This file is part of the Symfony package.
 *
 * (c) Fabien Potencier <fabien@symfony.com>
 *
 * For the full copyright and license information, please view the LICENSE
 * file that was distributed with this source code.
 */

namespace Symfony\Component\Finder\Tests\FakeAdapter;

use Symfony\Component\Finder\Adapter\AbstractAdapter;

/**
 * @author Jean-François Simon <contact@jfsimon.fr>
 */
class UnsupportedAdapter extends AbstractAdapter
{
    /**
     * {@inheritdoc}
     */
    public function searchInDirectory($dir)
    {
        return new \ArrayIterator(array());
    }

    /**
     * {@inheritdoc}
     */
    public function getName()
    {
        return 'unsupported';
    }

    /**
     * {@inheritdoc}
     */
    protected function canBeUsed()
    {
        return false;
    }
}
PKϤ$Z��mm+finder/Tests/FakeAdapter/FailingAdapter.phpnu�[���<?php

/*
 * This file is part of the Symfony package.
 *
 * (c) Fabien Potencier <fabien@symfony.com>
 *
 * For the full copyright and license information, please view the LICENSE
 * file that was distributed with this source code.
 */

namespace Symfony\Component\Finder\Tests\FakeAdapter;

use Symfony\Component\Finder\Adapter\AbstractAdapter;
use Symfony\Component\Finder\Exception\AdapterFailureException;

/**
 * @author Jean-François Simon <contact@jfsimon.fr>
 */
class FailingAdapter extends AbstractAdapter
{
    /**
     * {@inheritdoc}
     */
    public function searchInDirectory($dir)
    {
        throw new AdapterFailureException($this);
    }

    /**
     * {@inheritdoc}
     */
    public function getName()
    {
        return 'failing';
    }

    /**
     * {@inheritdoc}
     */
    protected function canBeUsed()
    {
        return true;
    }
}
PKϤ$ZI����)finder/Tests/FakeAdapter/DummyAdapter.phpnu�[���<?php

/*
 * This file is part of the Symfony package.
 *
 * (c) Fabien Potencier <fabien@symfony.com>
 *
 * For the full copyright and license information, please view the LICENSE
 * file that was distributed with this source code.
 */

namespace Symfony\Component\Finder\Tests\FakeAdapter;

use Symfony\Component\Finder\Adapter\AbstractAdapter;

/**
 * @author Jean-François Simon <contact@jfsimon.fr>
 */
class DummyAdapter extends AbstractAdapter
{
    /**
     * @var \Iterator
     */
    private $iterator;

    /**
     * @param \Iterator $iterator
     */
    public function __construct(\Iterator $iterator)
    {
        $this->iterator = $iterator;
    }

    /**
     * {@inheritdoc}
     */
    public function searchInDirectory($dir)
    {
        return $this->iterator;
    }

    /**
     * {@inheritdoc}
     */
    public function getName()
    {
        return 'yes';
    }

    /**
     * {@inheritdoc}
     */
    protected function canBeUsed()
    {
        return true;
    }
}
PKϤ$Z�; ��finder/Tests/BsdFinderTest.phpnu�[���<?php

/*
 * This file is part of the Symfony package.
 *
 * (c) Fabien Potencier <fabien@symfony.com>
 *
 * For the full copyright and license information, please view the LICENSE
 * file that was distributed with this source code.
 */

namespace Symfony\Component\Finder\Tests;

use Symfony\Component\Finder\Adapter\BsdFindAdapter;
use Symfony\Component\Finder\Finder;

/**
 * @group legacy
 */
class BsdFinderTest extends FinderTest
{
    protected function buildFinder()
    {
        $adapter = new BsdFindAdapter();

        if (!$adapter->isSupported()) {
            $this->markTestSkipped(get_class($adapter).' is not supported.');
        }

        return Finder::create()
            ->removeAdapters()
            ->addAdapter($adapter);
    }
}
PKϤ$Zn��=AAfinder/Tests/PhpFinderTest.phpnu�[���<?php

/*
 * This file is part of the Symfony package.
 *
 * (c) Fabien Potencier <fabien@symfony.com>
 *
 * For the full copyright and license information, please view the LICENSE
 * file that was distributed with this source code.
 */

namespace Symfony\Component\Finder\Tests;

use Symfony\Component\Finder\Adapter\PhpAdapter;
use Symfony\Component\Finder\Finder;

/**
 * @group legacy
 */
class PhpFinderTest extends FinderTest
{
    public function testImplementationsAreSynchronized()
    {
        $adapterReflector = new \ReflectionMethod('Symfony\Component\Finder\Adapter\PhpAdapter', 'searchInDirectory');
        $finderReflector = new \ReflectionMethod('Symfony\Component\Finder\Finder', 'searchInDirectory');

        $adapterSource = array_slice(file($adapterReflector->getFileName()), $adapterReflector->getStartLine() + 1, $adapterReflector->getEndLine() - $adapterReflector->getStartLine() - 1);
        $adapterSource = implode('', $adapterSource);
        $adapterSource = str_replace(array('$this->minDepth', '$this->maxDepth'), array('$minDepth', '$maxDepth'), $adapterSource);

        $finderSource = array_slice(file($finderReflector->getFileName()), $finderReflector->getStartLine() + 1, $finderReflector->getEndLine() - $finderReflector->getStartLine() - 1);
        $finderSource = implode('', $finderSource);

        $this->assertStringEndsWith($adapterSource, $finderSource);
    }

    protected function buildFinder()
    {
        $adapter = new PhpAdapter();

        return Finder::create()
            ->removeAdapters()
            ->addAdapter($adapter);
    }
}
PKϤ$ZIPP�|m|mfinder/Tests/FinderTest.phpnu�[���<?php

/*
 * This file is part of the Symfony package.
 *
 * (c) Fabien Potencier <fabien@symfony.com>
 *
 * For the full copyright and license information, please view the LICENSE
 * file that was distributed with this source code.
 */

namespace Symfony\Component\Finder\Tests;

use Symfony\Component\Finder\Adapter\AdapterInterface;
use Symfony\Component\Finder\Adapter\GnuFindAdapter;
use Symfony\Component\Finder\Adapter\PhpAdapter;
use Symfony\Component\Finder\Finder;

class FinderTest extends Iterator\RealIteratorTestCase
{
    public function testCreate()
    {
        $this->assertInstanceOf('Symfony\Component\Finder\Finder', Finder::create());
    }

    public function testDirectories()
    {
        $finder = $this->buildFinder();
        $this->assertSame($finder, $finder->directories());
        $this->assertIterator($this->toAbsolute(array('foo', 'toto')), $finder->in(self::$tmpDir)->getIterator());

        $finder = $this->buildFinder();
        $finder->directories();
        $finder->files();
        $finder->directories();
        $this->assertIterator($this->toAbsolute(array('foo', 'toto')), $finder->in(self::$tmpDir)->getIterator());
    }

    public function testFiles()
    {
        $finder = $this->buildFinder();
        $this->assertSame($finder, $finder->files());
        $this->assertIterator($this->toAbsolute(array('foo/bar.tmp', 'test.php', 'test.py', 'foo bar')), $finder->in(self::$tmpDir)->getIterator());

        $finder = $this->buildFinder();
        $finder->files();
        $finder->directories();
        $finder->files();
        $this->assertIterator($this->toAbsolute(array('foo/bar.tmp', 'test.php', 'test.py', 'foo bar')), $finder->in(self::$tmpDir)->getIterator());
    }

    public function testDepth()
    {
        $finder = $this->buildFinder();
        $this->assertSame($finder, $finder->depth('< 1'));
        $this->assertIterator($this->toAbsolute(array('foo', 'test.php', 'test.py', 'toto', 'foo bar')), $finder->in(self::$tmpDir)->getIterator());

        $finder = $this->buildFinder();
        $this->assertSame($finder, $finder->depth('<= 0'));
        $this->assertIterator($this->toAbsolute(array('foo', 'test.php', 'test.py', 'toto', 'foo bar')), $finder->in(self::$tmpDir)->getIterator());

        $finder = $this->buildFinder();
        $this->assertSame($finder, $finder->depth('>= 1'));
        $this->assertIterator($this->toAbsolute(array('foo/bar.tmp')), $finder->in(self::$tmpDir)->getIterator());

        $finder = $this->buildFinder();
        $finder->depth('< 1')->depth('>= 1');
        $this->assertIterator(array(), $finder->in(self::$tmpDir)->getIterator());
    }

    public function testName()
    {
        $finder = $this->buildFinder();
        $this->assertSame($finder, $finder->name('*.php'));
        $this->assertIterator($this->toAbsolute(array('test.php')), $finder->in(self::$tmpDir)->getIterator());

        $finder = $this->buildFinder();
        $finder->name('test.ph*');
        $finder->name('test.py');
        $this->assertIterator($this->toAbsolute(array('test.php', 'test.py')), $finder->in(self::$tmpDir)->getIterator());

        $finder = $this->buildFinder();
        $finder->name('~^test~i');
        $this->assertIterator($this->toAbsolute(array('test.php', 'test.py')), $finder->in(self::$tmpDir)->getIterator());

        $finder = $this->buildFinder();
        $finder->name('~\\.php$~i');
        $this->assertIterator($this->toAbsolute(array('test.php')), $finder->in(self::$tmpDir)->getIterator());

        $finder = $this->buildFinder();
        $finder->name('test.p{hp,y}');
        $this->assertIterator($this->toAbsolute(array('test.php', 'test.py')), $finder->in(self::$tmpDir)->getIterator());
    }

    public function testNotName()
    {
        $finder = $this->buildFinder();
        $this->assertSame($finder, $finder->notName('*.php'));
        $this->assertIterator($this->toAbsolute(array('foo', 'foo/bar.tmp', 'test.py', 'toto', 'foo bar')), $finder->in(self::$tmpDir)->getIterator());

        $finder = $this->buildFinder();
        $finder->notName('*.php');
        $finder->notName('*.py');
        $this->assertIterator($this->toAbsolute(array('foo', 'foo/bar.tmp', 'toto', 'foo bar')), $finder->in(self::$tmpDir)->getIterator());

        $finder = $this->buildFinder();
        $finder->name('test.ph*');
        $finder->name('test.py');
        $finder->notName('*.php');
        $finder->notName('*.py');
        $this->assertIterator(array(), $finder->in(self::$tmpDir)->getIterator());

        $finder = $this->buildFinder();
        $finder->name('test.ph*');
        $finder->name('test.py');
        $finder->notName('*.p{hp,y}');
        $this->assertIterator(array(), $finder->in(self::$tmpDir)->getIterator());
    }

    /**
     * @dataProvider getRegexNameTestData
     */
    public function testRegexName($regex)
    {
        $finder = $this->buildFinder();
        $finder->name($regex);
        $this->assertIterator($this->toAbsolute(array('test.py', 'test.php')), $finder->in(self::$tmpDir)->getIterator());
    }

    public function testSize()
    {
        $finder = $this->buildFinder();
        $this->assertSame($finder, $finder->files()->size('< 1K')->size('> 500'));
        $this->assertIterator($this->toAbsolute(array('test.php')), $finder->in(self::$tmpDir)->getIterator());
    }

    public function testDate()
    {
        $finder = $this->buildFinder();
        $this->assertSame($finder, $finder->files()->date('until last month'));
        $this->assertIterator($this->toAbsolute(array('foo/bar.tmp', 'test.php')), $finder->in(self::$tmpDir)->getIterator());
    }

    public function testExclude()
    {
        $finder = $this->buildFinder();
        $this->assertSame($finder, $finder->exclude('foo'));
        $this->assertIterator($this->toAbsolute(array('test.php', 'test.py', 'toto', 'foo bar')), $finder->in(self::$tmpDir)->getIterator());
    }

    public function testIgnoreVCS()
    {
        $finder = $this->buildFinder();
        $this->assertSame($finder, $finder->ignoreVCS(false)->ignoreDotFiles(false));
        $this->assertIterator($this->toAbsolute(array('.git', 'foo', 'foo/bar.tmp', 'test.php', 'test.py', 'toto', 'toto/.git', '.bar', '.foo', '.foo/.bar', '.foo/bar', 'foo bar')), $finder->in(self::$tmpDir)->getIterator());

        $finder = $this->buildFinder();
        $finder->ignoreVCS(false)->ignoreVCS(false)->ignoreDotFiles(false);
        $this->assertIterator($this->toAbsolute(array('.git', 'foo', 'foo/bar.tmp', 'test.php', 'test.py', 'toto', 'toto/.git', '.bar', '.foo', '.foo/.bar', '.foo/bar', 'foo bar')), $finder->in(self::$tmpDir)->getIterator());

        $finder = $this->buildFinder();
        $this->assertSame($finder, $finder->ignoreVCS(true)->ignoreDotFiles(false));
        $this->assertIterator($this->toAbsolute(array('foo', 'foo/bar.tmp', 'test.php', 'test.py', 'toto', '.bar', '.foo', '.foo/.bar', '.foo/bar', 'foo bar')), $finder->in(self::$tmpDir)->getIterator());
    }

    public function testIgnoreDotFiles()
    {
        $finder = $this->buildFinder();
        $this->assertSame($finder, $finder->ignoreDotFiles(false)->ignoreVCS(false));
        $this->assertIterator($this->toAbsolute(array('.git', '.bar', '.foo', '.foo/.bar', '.foo/bar', 'foo', 'foo/bar.tmp', 'test.php', 'test.py', 'toto', 'toto/.git', 'foo bar')), $finder->in(self::$tmpDir)->getIterator());

        $finder = $this->buildFinder();
        $finder->ignoreDotFiles(false)->ignoreDotFiles(false)->ignoreVCS(false);
        $this->assertIterator($this->toAbsolute(array('.git', '.bar', '.foo', '.foo/.bar', '.foo/bar', 'foo', 'foo/bar.tmp', 'test.php', 'test.py', 'toto', 'toto/.git', 'foo bar')), $finder->in(self::$tmpDir)->getIterator());

        $finder = $this->buildFinder();
        $this->assertSame($finder, $finder->ignoreDotFiles(true)->ignoreVCS(false));
        $this->assertIterator($this->toAbsolute(array('foo', 'foo/bar.tmp', 'test.php', 'test.py', 'toto', 'foo bar')), $finder->in(self::$tmpDir)->getIterator());
    }

    public function testSortByName()
    {
        $finder = $this->buildFinder();
        $this->assertSame($finder, $finder->sortByName());
        $this->assertIterator($this->toAbsolute(array('foo', 'foo bar', 'foo/bar.tmp', 'test.php', 'test.py', 'toto')), $finder->in(self::$tmpDir)->getIterator());
    }

    public function testSortByType()
    {
        $finder = $this->buildFinder();
        $this->assertSame($finder, $finder->sortByType());
        $this->assertIterator($this->toAbsolute(array('foo', 'foo bar', 'toto', 'foo/bar.tmp', 'test.php', 'test.py')), $finder->in(self::$tmpDir)->getIterator());
    }

    public function testSortByAccessedTime()
    {
        $finder = $this->buildFinder();
        $this->assertSame($finder, $finder->sortByAccessedTime());
        $this->assertIterator($this->toAbsolute(array('foo/bar.tmp', 'test.php', 'toto', 'test.py', 'foo', 'foo bar')), $finder->in(self::$tmpDir)->getIterator());
    }

    public function testSortByChangedTime()
    {
        $finder = $this->buildFinder();
        $this->assertSame($finder, $finder->sortByChangedTime());
        $this->assertIterator($this->toAbsolute(array('toto', 'test.py', 'test.php', 'foo/bar.tmp', 'foo', 'foo bar')), $finder->in(self::$tmpDir)->getIterator());
    }

    public function testSortByModifiedTime()
    {
        $finder = $this->buildFinder();
        $this->assertSame($finder, $finder->sortByModifiedTime());
        $this->assertIterator($this->toAbsolute(array('foo/bar.tmp', 'test.php', 'toto', 'test.py', 'foo', 'foo bar')), $finder->in(self::$tmpDir)->getIterator());
    }

    public function testSort()
    {
        $finder = $this->buildFinder();
        $this->assertSame($finder, $finder->sort(function (\SplFileInfo $a, \SplFileInfo $b) { return strcmp($a->getRealPath(), $b->getRealPath()); }));
        $this->assertIterator($this->toAbsolute(array('foo', 'foo bar', 'foo/bar.tmp', 'test.php', 'test.py', 'toto')), $finder->in(self::$tmpDir)->getIterator());
    }

    public function testFilter()
    {
        $finder = $this->buildFinder();
        $this->assertSame($finder, $finder->filter(function (\SplFileInfo $f) { return false !== strpos($f, 'test'); }));
        $this->assertIterator($this->toAbsolute(array('test.php', 'test.py')), $finder->in(self::$tmpDir)->getIterator());
    }

    public function testFollowLinks()
    {
        if ('\\' == DIRECTORY_SEPARATOR) {
            $this->markTestSkipped('symlinks are not supported on Windows');
        }

        $finder = $this->buildFinder();
        $this->assertSame($finder, $finder->followLinks());
        $this->assertIterator($this->toAbsolute(array('foo', 'foo/bar.tmp', 'test.php', 'test.py', 'toto', 'foo bar')), $finder->in(self::$tmpDir)->getIterator());
    }

    public function testIn()
    {
        $finder = $this->buildFinder();
        $iterator = $finder->files()->name('*.php')->depth('< 1')->in(array(self::$tmpDir, __DIR__))->getIterator();

        $expected = array(
            self::$tmpDir.DIRECTORY_SEPARATOR.'test.php',
            __DIR__.DIRECTORY_SEPARATOR.'BsdFinderTest.php',
            __DIR__.DIRECTORY_SEPARATOR.'FinderTest.php',
            __DIR__.DIRECTORY_SEPARATOR.'GnuFinderTest.php',
            __DIR__.DIRECTORY_SEPARATOR.'PhpFinderTest.php',
            __DIR__.DIRECTORY_SEPARATOR.'GlobTest.php',
        );

        $this->assertIterator($expected, $iterator);
    }

    /**
     * @expectedException \InvalidArgumentException
     */
    public function testInWithNonExistentDirectory()
    {
        $finder = new Finder();
        $finder->in('foobar');
    }

    public function testInWithGlob()
    {
        $finder = $this->buildFinder();
        $finder->in(array(__DIR__.'/Fixtures/*/B/C', __DIR__.'/Fixtures/*/*/B/C'))->getIterator();

        $this->assertIterator($this->toAbsoluteFixtures(array('A/B/C/abc.dat', 'copy/A/B/C/abc.dat.copy')), $finder);
    }

    /**
     * @expectedException \InvalidArgumentException
     */
    public function testInWithNonDirectoryGlob()
    {
        $finder = new Finder();
        $finder->in(__DIR__.'/Fixtures/A/a*');
    }

    public function testInWithGlobBrace()
    {
        $finder = $this->buildFinder();
        $finder->in(array(__DIR__.'/Fixtures/{A,copy/A}/B/C'))->getIterator();

        $this->assertIterator($this->toAbsoluteFixtures(array('A/B/C/abc.dat', 'copy/A/B/C/abc.dat.copy')), $finder);
    }

    /**
     * @expectedException \LogicException
     */
    public function testGetIteratorWithoutIn()
    {
        $finder = Finder::create();
        $finder->getIterator();
    }

    public function testGetIterator()
    {
        $finder = $this->buildFinder();
        $dirs = array();
        foreach ($finder->directories()->in(self::$tmpDir) as $dir) {
            $dirs[] = (string) $dir;
        }

        $expected = $this->toAbsolute(array('foo', 'toto'));

        sort($dirs);
        sort($expected);

        $this->assertEquals($expected, $dirs, 'implements the \IteratorAggregate interface');

        $finder = $this->buildFinder();
        $this->assertEquals(2, iterator_count($finder->directories()->in(self::$tmpDir)), 'implements the \IteratorAggregate interface');

        $finder = $this->buildFinder();
        $a = iterator_to_array($finder->directories()->in(self::$tmpDir));
        $a = array_values(array_map(function ($a) { return (string) $a; }, $a));
        sort($a);
        $this->assertEquals($expected, $a, 'implements the \IteratorAggregate interface');
    }

    public function testRelativePath()
    {
        $finder = $this->buildFinder()->in(self::$tmpDir);

        $paths = array();

        foreach ($finder as $file) {
            $paths[] = $file->getRelativePath();
        }

        $ref = array('', '', '', '', 'foo', '');

        sort($ref);
        sort($paths);

        $this->assertEquals($ref, $paths);
    }

    public function testRelativePathname()
    {
        $finder = $this->buildFinder()->in(self::$tmpDir)->sortByName();

        $paths = array();

        foreach ($finder as $file) {
            $paths[] = $file->getRelativePathname();
        }

        $ref = array('test.php', 'toto', 'test.py', 'foo', 'foo'.DIRECTORY_SEPARATOR.'bar.tmp', 'foo bar');

        sort($paths);
        sort($ref);

        $this->assertEquals($ref, $paths);
    }

    public function testAppendWithAFinder()
    {
        $finder = $this->buildFinder();
        $finder->files()->in(self::$tmpDir.DIRECTORY_SEPARATOR.'foo');

        $finder1 = $this->buildFinder();
        $finder1->directories()->in(self::$tmpDir);

        $finder = $finder->append($finder1);

        $this->assertIterator($this->toAbsolute(array('foo', 'foo/bar.tmp', 'toto')), $finder->getIterator());
    }

    public function testAppendWithAnArray()
    {
        $finder = $this->buildFinder();
        $finder->files()->in(self::$tmpDir.DIRECTORY_SEPARATOR.'foo');

        $finder->append($this->toAbsolute(array('foo', 'toto')));

        $this->assertIterator($this->toAbsolute(array('foo', 'foo/bar.tmp', 'toto')), $finder->getIterator());
    }

    public function testAppendReturnsAFinder()
    {
        $this->assertInstanceOf('Symfony\\Component\\Finder\\Finder', Finder::create()->append(array()));
    }

    public function testAppendDoesNotRequireIn()
    {
        $finder = $this->buildFinder();
        $finder->in(self::$tmpDir.DIRECTORY_SEPARATOR.'foo');

        $finder1 = Finder::create()->append($finder);

        $this->assertIterator(iterator_to_array($finder->getIterator()), $finder1->getIterator());
    }

    public function testCountDirectories()
    {
        $directory = Finder::create()->directories()->in(self::$tmpDir);
        $i = 0;

        foreach ($directory as $dir) {
            ++$i;
        }

        $this->assertCount($i, $directory);
    }

    public function testCountFiles()
    {
        $files = Finder::create()->files()->in(__DIR__.DIRECTORY_SEPARATOR.'Fixtures');
        $i = 0;

        foreach ($files as $file) {
            ++$i;
        }

        $this->assertCount($i, $files);
    }

    /**
     * @expectedException \LogicException
     */
    public function testCountWithoutIn()
    {
        $finder = Finder::create()->files();
        count($finder);
    }

    /**
     * @dataProvider getContainsTestData
     */
    public function testContains($matchPatterns, $noMatchPatterns, $expected)
    {
        $finder = $this->buildFinder();
        $finder->in(__DIR__.DIRECTORY_SEPARATOR.'Fixtures')
            ->name('*.txt')->sortByName()
            ->contains($matchPatterns)
            ->notContains($noMatchPatterns);

        $this->assertIterator($this->toAbsoluteFixtures($expected), $finder);
    }

    public function testContainsOnDirectory()
    {
        $finder = $this->buildFinder();
        $finder->in(__DIR__)
            ->directories()
            ->name('Fixtures')
            ->contains('abc');
        $this->assertIterator(array(), $finder);
    }

    public function testNotContainsOnDirectory()
    {
        $finder = $this->buildFinder();
        $finder->in(__DIR__)
            ->directories()
            ->name('Fixtures')
            ->notContains('abc');
        $this->assertIterator(array(), $finder);
    }

    /**
     * Searching in multiple locations involves AppendIterator which does an unnecessary rewind which leaves FilterIterator
     * with inner FilesystemIterator in an invalid state.
     *
     * @see https://bugs.php.net/68557
     */
    public function testMultipleLocations()
    {
        $locations = array(
            self::$tmpDir.'/',
            self::$tmpDir.'/toto/',
        );

        // it is expected that there are test.py test.php in the tmpDir
        $finder = new Finder();
        $finder->in($locations)
            // the default flag IGNORE_DOT_FILES fixes the problem indirectly
            // so we set it to false for better isolation
            ->ignoreDotFiles(false)
            ->depth('< 1')->name('test.php');

        $this->assertCount(1, $finder);
    }

    /**
     * Searching in multiple locations with sub directories involves
     * AppendIterator which does an unnecessary rewind which leaves
     * FilterIterator with inner FilesystemIterator in an invalid state.
     *
     * @see https://bugs.php.net/68557
     */
    public function testMultipleLocationsWithSubDirectories()
    {
        $locations = array(
            __DIR__.'/Fixtures/one',
            self::$tmpDir.DIRECTORY_SEPARATOR.'toto',
        );

        $finder = $this->buildFinder();
        $finder->in($locations)->depth('< 10')->name('*.neon');

        $expected = array(
            __DIR__.'/Fixtures/one'.DIRECTORY_SEPARATOR.'b'.DIRECTORY_SEPARATOR.'c.neon',
            __DIR__.'/Fixtures/one'.DIRECTORY_SEPARATOR.'b'.DIRECTORY_SEPARATOR.'d.neon',
        );

        $this->assertIterator($expected, $finder);
        $this->assertIteratorInForeach($expected, $finder);
    }

    /**
     * Iterator keys must be the file pathname.
     */
    public function testIteratorKeys()
    {
        $finder = $this->buildFinder()->in(self::$tmpDir);
        foreach ($finder as $key => $file) {
            $this->assertEquals($file->getPathname(), $key);
        }
    }

    public function testRegexSpecialCharsLocationWithPathRestrictionContainingStartFlag()
    {
        $finder = $this->buildFinder();
        $finder->in(__DIR__.DIRECTORY_SEPARATOR.'Fixtures'.DIRECTORY_SEPARATOR.'r+e.gex[c]a(r)s')
            ->path('/^dir/');

        $expected = array('r+e.gex[c]a(r)s'.DIRECTORY_SEPARATOR.'dir', 'r+e.gex[c]a(r)s'.DIRECTORY_SEPARATOR.'dir'.DIRECTORY_SEPARATOR.'bar.dat');
        $this->assertIterator($this->toAbsoluteFixtures($expected), $finder);
    }

    /**
     * @group legacy
     */
    public function testAdaptersOrdering()
    {
        $finder = Finder::create()
            ->removeAdapters()
            ->addAdapter(new FakeAdapter\NamedAdapter('a'), 0)
            ->addAdapter(new FakeAdapter\NamedAdapter('b'), -50)
            ->addAdapter(new FakeAdapter\NamedAdapter('c'), 50)
            ->addAdapter(new FakeAdapter\NamedAdapter('d'), -25)
            ->addAdapter(new FakeAdapter\NamedAdapter('e'), 25);

        $this->assertEquals(
            array('c', 'e', 'a', 'd', 'b'),
            array_map(function (AdapterInterface $adapter) {
                return $adapter->getName();
            }, $finder->getAdapters())
        );
    }

    /**
     * @group legacy
     */
    public function testAdaptersChaining()
    {
        $iterator = new \ArrayIterator(array());
        $filenames = $this->toAbsolute(array('foo', 'foo/bar.tmp', 'test.php', 'test.py', 'toto'));
        foreach ($filenames as $file) {
            $iterator->append(new \Symfony\Component\Finder\SplFileInfo($file, null, null));
        }

        $finder = Finder::create()
            ->removeAdapters()
            ->addAdapter(new FakeAdapter\UnsupportedAdapter(), 3)
            ->addAdapter(new FakeAdapter\FailingAdapter(), 2)
            ->addAdapter(new FakeAdapter\DummyAdapter($iterator), 1);

        $this->assertIterator($filenames, $finder->in(sys_get_temp_dir())->getIterator());
    }

    public function getContainsTestData()
    {
        return array(
            array('', '', array()),
            array('foo', 'bar', array()),
            array('', 'foobar', array('dolor.txt', 'ipsum.txt', 'lorem.txt')),
            array('lorem ipsum dolor sit amet', 'foobar', array('lorem.txt')),
            array('sit', 'bar', array('dolor.txt', 'ipsum.txt', 'lorem.txt')),
            array('dolor sit amet', '@^L@m', array('dolor.txt', 'ipsum.txt')),
            array('/^lorem ipsum dolor sit amet$/m', 'foobar', array('lorem.txt')),
            array('lorem', 'foobar', array('lorem.txt')),
            array('', 'lorem', array('dolor.txt', 'ipsum.txt')),
            array('ipsum dolor sit amet', '/^IPSUM/m', array('lorem.txt')),
        );
    }

    public function getRegexNameTestData()
    {
        return array(
            array('~.+\\.p.+~i'),
            array('~t.*s~i'),
        );
    }

    /**
     * @dataProvider getTestPathData
     */
    public function testPath($matchPatterns, $noMatchPatterns, array $expected)
    {
        $finder = $this->buildFinder();
        $finder->in(__DIR__.DIRECTORY_SEPARATOR.'Fixtures')
            ->path($matchPatterns)
            ->notPath($noMatchPatterns);

        $this->assertIterator($this->toAbsoluteFixtures($expected), $finder);
    }

    /**
     * @group legacy
     */
    public function testAdapterSelection()
    {
        // test that by default, PhpAdapter is selected
        $adapters = Finder::create()->getAdapters();
        $this->assertTrue($adapters[0] instanceof PhpAdapter);

        // test another adapter selection
        $adapters = Finder::create()->setAdapter('gnu_find')->getAdapters();
        $this->assertTrue($adapters[0] instanceof GnuFindAdapter);

        // test that useBestAdapter method removes selection
        $adapters = Finder::create()->useBestAdapter()->getAdapters();
        $this->assertFalse($adapters[0] instanceof PhpAdapter);
    }

    public function getTestPathData()
    {
        return array(
            array('', '', array()),
            array('/^A\/B\/C/', '/C$/',
                array('A'.DIRECTORY_SEPARATOR.'B'.DIRECTORY_SEPARATOR.'C'.DIRECTORY_SEPARATOR.'abc.dat'),
            ),
            array('/^A\/B/', 'foobar',
                array(
                    'A'.DIRECTORY_SEPARATOR.'B',
                    'A'.DIRECTORY_SEPARATOR.'B'.DIRECTORY_SEPARATOR.'C',
                    'A'.DIRECTORY_SEPARATOR.'B'.DIRECTORY_SEPARATOR.'ab.dat',
                    'A'.DIRECTORY_SEPARATOR.'B'.DIRECTORY_SEPARATOR.'C'.DIRECTORY_SEPARATOR.'abc.dat',
                ),
            ),
            array('A/B/C', 'foobar',
                array(
                    'A'.DIRECTORY_SEPARATOR.'B'.DIRECTORY_SEPARATOR.'C',
                    'A'.DIRECTORY_SEPARATOR.'B'.DIRECTORY_SEPARATOR.'C'.DIRECTORY_SEPARATOR.'abc.dat',
                    'copy'.DIRECTORY_SEPARATOR.'A'.DIRECTORY_SEPARATOR.'B'.DIRECTORY_SEPARATOR.'C',
                    'copy'.DIRECTORY_SEPARATOR.'A'.DIRECTORY_SEPARATOR.'B'.DIRECTORY_SEPARATOR.'C'.DIRECTORY_SEPARATOR.'abc.dat.copy',
                ),
            ),
            array('A/B', 'foobar',
                array(
                    //dirs
                    'A'.DIRECTORY_SEPARATOR.'B',
                    'A'.DIRECTORY_SEPARATOR.'B'.DIRECTORY_SEPARATOR.'C',
                    'copy'.DIRECTORY_SEPARATOR.'A'.DIRECTORY_SEPARATOR.'B',
                    'copy'.DIRECTORY_SEPARATOR.'A'.DIRECTORY_SEPARATOR.'B'.DIRECTORY_SEPARATOR.'C',
                    //files
                    'A'.DIRECTORY_SEPARATOR.'B'.DIRECTORY_SEPARATOR.'ab.dat',
                    'A'.DIRECTORY_SEPARATOR.'B'.DIRECTORY_SEPARATOR.'C'.DIRECTORY_SEPARATOR.'abc.dat',
                    'copy'.DIRECTORY_SEPARATOR.'A'.DIRECTORY_SEPARATOR.'B'.DIRECTORY_SEPARATOR.'ab.dat.copy',
                    'copy'.DIRECTORY_SEPARATOR.'A'.DIRECTORY_SEPARATOR.'B'.DIRECTORY_SEPARATOR.'C'.DIRECTORY_SEPARATOR.'abc.dat.copy',
                ),
            ),
            array('/^with space\//', 'foobar',
                array(
                    'with space'.DIRECTORY_SEPARATOR.'foo.txt',
                ),
            ),
        );
    }

    public function testAccessDeniedException()
    {
        if ('\\' === DIRECTORY_SEPARATOR) {
            $this->markTestSkipped('chmod is not supported on Windows');
        }

        $finder = $this->buildFinder();
        $finder->files()->in(self::$tmpDir);

        // make 'foo' directory non-readable
        $testDir = self::$tmpDir.DIRECTORY_SEPARATOR.'foo';
        chmod($testDir, 0333);

        if (false === $couldRead = is_readable($testDir)) {
            try {
                $this->assertIterator($this->toAbsolute(array('foo bar', 'test.php', 'test.py')), $finder->getIterator());
                $this->fail('Finder should throw an exception when opening a non-readable directory.');
            } catch (\Exception $e) {
                $expectedExceptionClass = 'Symfony\\Component\\Finder\\Exception\\AccessDeniedException';
                if ($e instanceof \PHPUnit_Framework_ExpectationFailedException) {
                    $this->fail(sprintf("Expected exception:\n%s\nGot:\n%s\nWith comparison failure:\n%s", $expectedExceptionClass, 'PHPUnit_Framework_ExpectationFailedException', $e->getComparisonFailure()->getExpectedAsString()));
                }

                $this->assertInstanceOf($expectedExceptionClass, $e);
            }
        }

        // restore original permissions
        chmod($testDir, 0777);
        clearstatcache($testDir);

        if ($couldRead) {
            $this->markTestSkipped('could read test files while test requires unreadable');
        }
    }

    public function testIgnoredAccessDeniedException()
    {
        if ('\\' === DIRECTORY_SEPARATOR) {
            $this->markTestSkipped('chmod is not supported on Windows');
        }

        $finder = $this->buildFinder();
        $finder->files()->ignoreUnreadableDirs()->in(self::$tmpDir);

        // make 'foo' directory non-readable
        $testDir = self::$tmpDir.DIRECTORY_SEPARATOR.'foo';
        chmod($testDir, 0333);

        if (false === ($couldRead = is_readable($testDir))) {
            $this->assertIterator($this->toAbsolute(array('foo bar', 'test.php', 'test.py')), $finder->getIterator());
        }

        // restore original permissions
        chmod($testDir, 0777);
        clearstatcache($testDir);

        if ($couldRead) {
            $this->markTestSkipped('could read test files while test requires unreadable');
        }
    }

    protected function buildFinder()
    {
        return Finder::create();
    }
}
PKϤ$Z��2���finder/Tests/GnuFinderTest.phpnu�[���<?php

/*
 * This file is part of the Symfony package.
 *
 * (c) Fabien Potencier <fabien@symfony.com>
 *
 * For the full copyright and license information, please view the LICENSE
 * file that was distributed with this source code.
 */

namespace Symfony\Component\Finder\Tests;

use Symfony\Component\Finder\Adapter\GnuFindAdapter;
use Symfony\Component\Finder\Finder;

/**
 * @group legacy
 */
class GnuFinderTest extends FinderTest
{
    protected function buildFinder()
    {
        $adapter = new GnuFindAdapter();

        if (!$adapter->isSupported()) {
            $this->markTestSkipped(get_class($adapter).' is not supported.');
        }

        return Finder::create()
            ->removeAdapters()
            ->addAdapter($adapter);
    }
}
PKϤ$Z������finder/Tests/GlobTest.phpnu�[���<?php

/*
 * This file is part of the Symfony package.
 *
 * (c) Fabien Potencier <fabien@symfony.com>
 *
 * For the full copyright and license information, please view the LICENSE
 * file that was distributed with this source code.
 */

namespace Symfony\Component\Finder\Tests;

use Symfony\Component\Finder\Glob;

class GlobTest extends \PHPUnit_Framework_TestCase
{
    public function testGlobToRegexDelimiters()
    {
        $this->assertEquals('#^(?=[^\.])\#$#', Glob::toRegex('#'));
        $this->assertEquals('#^\.[^/]*$#', Glob::toRegex('.*'));
        $this->assertEquals('^\.[^/]*$', Glob::toRegex('.*', true, true, ''));
        $this->assertEquals('/^\.[^/]*$/', Glob::toRegex('.*', true, true, '/'));
    }
}
PKϤ$Z���5KKfinder/Shell/Shell.phpnu�[���<?php

/*
 * This file is part of the Symfony package.
 *
 * (c) Fabien Potencier <fabien@symfony.com>
 *
 * For the full copyright and license information, please view the LICENSE
 * file that was distributed with this source code.
 */

namespace Symfony\Component\Finder\Shell;

@trigger_error('The '.__NAMESPACE__.'\Shell class is deprecated since version 2.8 and will be removed in 3.0.', E_USER_DEPRECATED);

/**
 * @author Jean-François Simon <contact@jfsimon.fr>
 *
 * @deprecated since 2.8, to be removed in 3.0.
 */
class Shell
{
    const TYPE_UNIX = 1;
    const TYPE_DARWIN = 2;
    const TYPE_CYGWIN = 3;
    const TYPE_WINDOWS = 4;
    const TYPE_BSD = 5;

    /**
     * @var string|null
     */
    private $type;

    /**
     * Returns guessed OS type.
     *
     * @return int
     */
    public function getType()
    {
        if (null === $this->type) {
            $this->type = $this->guessType();
        }

        return $this->type;
    }

    /**
     * Tests if a command is available.
     *
     * @param string $command
     *
     * @return bool
     */
    public function testCommand($command)
    {
        if (!function_exists('exec')) {
            return false;
        }

        // todo: find a better way (command could not be available)
        $testCommand = 'which ';
        if (self::TYPE_WINDOWS === $this->type) {
            $testCommand = 'where ';
        }

        $command = escapeshellcmd($command);

        exec($testCommand.$command, $output, $code);

        return 0 === $code && count($output) > 0;
    }

    /**
     * Guesses OS type.
     *
     * @return int
     */
    private function guessType()
    {
        $os = strtolower(PHP_OS);

        if (false !== strpos($os, 'cygwin')) {
            return self::TYPE_CYGWIN;
        }

        if (false !== strpos($os, 'darwin')) {
            return self::TYPE_DARWIN;
        }

        if (false !== strpos($os, 'bsd')) {
            return self::TYPE_BSD;
        }

        if (0 === strpos($os, 'win')) {
            return self::TYPE_WINDOWS;
        }

        return self::TYPE_UNIX;
    }
}
PKϤ$Z
�Q+ssfinder/Shell/Command.phpnu�[���<?php

/*
 * This file is part of the Symfony package.
 *
 * (c) Fabien Potencier <fabien@symfony.com>
 *
 * For the full copyright and license information, please view the LICENSE
 * file that was distributed with this source code.
 */

namespace Symfony\Component\Finder\Shell;

@trigger_error('The '.__NAMESPACE__.'\Command class is deprecated since version 2.8 and will be removed in 3.0.', E_USER_DEPRECATED);

/**
 * @author Jean-François Simon <contact@jfsimon.fr>
 *
 * @deprecated since 2.8, to be removed in 3.0.
 */
class Command
{
    /**
     * @var Command|null
     */
    private $parent;

    /**
     * @var array
     */
    private $bits = array();

    /**
     * @var array
     */
    private $labels = array();

    /**
     * @var \Closure|null
     */
    private $errorHandler;

    /**
     * Constructor.
     *
     * @param Command|null $parent Parent command
     */
    public function __construct(Command $parent = null)
    {
        $this->parent = $parent;
    }

    /**
     * Returns command as string.
     *
     * @return string
     */
    public function __toString()
    {
        return $this->join();
    }

    /**
     * Creates a new Command instance.
     *
     * @param Command|null $parent Parent command
     *
     * @return Command New Command instance
     */
    public static function create(Command $parent = null)
    {
        return new self($parent);
    }

    /**
     * Escapes special chars from input.
     *
     * @param string $input A string to escape
     *
     * @return string The escaped string
     */
    public static function escape($input)
    {
        return escapeshellcmd($input);
    }

    /**
     * Quotes input.
     *
     * @param string $input An argument string
     *
     * @return string The quoted string
     */
    public static function quote($input)
    {
        return escapeshellarg($input);
    }

    /**
     * Appends a string or a Command instance.
     *
     * @param string|Command $bit
     *
     * @return Command The current Command instance
     */
    public function add($bit)
    {
        $this->bits[] = $bit;

        return $this;
    }

    /**
     * Prepends a string or a command instance.
     *
     * @param string|Command $bit
     *
     * @return Command The current Command instance
     */
    public function top($bit)
    {
        array_unshift($this->bits, $bit);

        foreach ($this->labels as $label => $index) {
            $this->labels[$label] += 1;
        }

        return $this;
    }

    /**
     * Appends an argument, will be quoted.
     *
     * @param string $arg
     *
     * @return Command The current Command instance
     */
    public function arg($arg)
    {
        $this->bits[] = self::quote($arg);

        return $this;
    }

    /**
     * Appends escaped special command chars.
     *
     * @param string $esc
     *
     * @return Command The current Command instance
     */
    public function cmd($esc)
    {
        $this->bits[] = self::escape($esc);

        return $this;
    }

    /**
     * Inserts a labeled command to feed later.
     *
     * @param string $label The unique label
     *
     * @return Command The current Command instance
     *
     * @throws \RuntimeException If label already exists
     */
    public function ins($label)
    {
        if (isset($this->labels[$label])) {
            throw new \RuntimeException(sprintf('Label "%s" already exists.', $label));
        }

        $this->bits[] = self::create($this);
        $this->labels[$label] = count($this->bits) - 1;

        return $this->bits[$this->labels[$label]];
    }

    /**
     * Retrieves a previously labeled command.
     *
     * @param string $label
     *
     * @return Command The labeled command
     *
     * @throws \RuntimeException
     */
    public function get($label)
    {
        if (!isset($this->labels[$label])) {
            throw new \RuntimeException(sprintf('Label "%s" does not exist.', $label));
        }

        return $this->bits[$this->labels[$label]];
    }

    /**
     * Returns parent command (if any).
     *
     * @return Command Parent command
     *
     * @throws \RuntimeException If command has no parent
     */
    public function end()
    {
        if (null === $this->parent) {
            throw new \RuntimeException('Calling end on root command doesn\'t make sense.');
        }

        return $this->parent;
    }

    /**
     * Counts bits stored in command.
     *
     * @return int The bits count
     */
    public function length()
    {
        return count($this->bits);
    }

    /**
     * @param \Closure $errorHandler
     *
     * @return Command
     */
    public function setErrorHandler(\Closure $errorHandler)
    {
        $this->errorHandler = $errorHandler;

        return $this;
    }

    /**
     * @return \Closure|null
     */
    public function getErrorHandler()
    {
        return $this->errorHandler;
    }

    /**
     * Executes current command.
     *
     * @return array The command result
     *
     * @throws \RuntimeException
     */
    public function execute()
    {
        if (null === $errorHandler = $this->errorHandler) {
            exec($this->join(), $output);
        } else {
            $process = proc_open($this->join(), array(0 => array('pipe', 'r'), 1 => array('pipe', 'w'), 2 => array('pipe', 'w')), $pipes);
            $output = preg_split('~(\r\n|\r|\n)~', stream_get_contents($pipes[1]), -1, PREG_SPLIT_NO_EMPTY);

            if ($error = stream_get_contents($pipes[2])) {
                $errorHandler($error);
            }

            proc_close($process);
        }

        return $output ?: array();
    }

    /**
     * Joins bits.
     *
     * @return string
     */
    public function join()
    {
        return implode(' ', array_filter(
            array_map(function ($bit) {
                return $bit instanceof Command ? $bit->join() : ($bit ?: null);
            }, $this->bits),
            function ($bit) { return null !== $bit; }
        ));
    }

    /**
     * Insert a string or a Command instance before the bit at given position $index (index starts from 0).
     *
     * @param string|Command $bit
     * @param int            $index
     *
     * @return Command The current Command instance
     */
    public function addAtIndex($bit, $index)
    {
        array_splice($this->bits, $index, 0, $bit instanceof self ? array($bit) : $bit);

        return $this;
    }
}
PKϤ$Z�Z����&finder/Iterator/PathFilterIterator.phpnu�[���<?php

/*
 * This file is part of the Symfony package.
 *
 * (c) Fabien Potencier <fabien@symfony.com>
 *
 * For the full copyright and license information, please view the LICENSE
 * file that was distributed with this source code.
 */

namespace Symfony\Component\Finder\Iterator;

/**
 * PathFilterIterator filters files by path patterns (e.g. some/special/dir).
 *
 * @author Fabien Potencier  <fabien@symfony.com>
 * @author Włodzimierz Gajda <gajdaw@gajdaw.pl>
 */
class PathFilterIterator extends MultiplePcreFilterIterator
{
    /**
     * Filters the iterator values.
     *
     * @return bool true if the value should be kept, false otherwise
     */
    #[\ReturnTypeWillChange]
    public function accept()
    {
        $filename = $this->current()->getRelativePathname();

        if ('\\' === \DIRECTORY_SEPARATOR) {
            $filename = str_replace('\\', '/', $filename);
        }

        return $this->isAccepted($filename);
    }

    /**
     * Converts strings to regexp.
     *
     * PCRE patterns are left unchanged.
     *
     * Default conversion:
     *     'lorem/ipsum/dolor' ==>  'lorem\/ipsum\/dolor/'
     *
     * Use only / as directory separator (on Windows also).
     *
     * @param string $str Pattern: regexp or dirname
     *
     * @return string regexp corresponding to a given string or regexp
     */
    protected function toRegex(string $str)
    {
        return $this->isRegex($str) ? $str : '/'.preg_quote($str, '/').'/';
    }
}
PKϤ$ZOI{���.finder/Iterator/RecursiveDirectoryIterator.phpnu�[���<?php

/*
 * This file is part of the Symfony package.
 *
 * (c) Fabien Potencier <fabien@symfony.com>
 *
 * For the full copyright and license information, please view the LICENSE
 * file that was distributed with this source code.
 */

namespace Symfony\Component\Finder\Iterator;

use Symfony\Component\Finder\Exception\AccessDeniedException;
use Symfony\Component\Finder\SplFileInfo;

/**
 * Extends the \RecursiveDirectoryIterator to support relative paths.
 *
 * @author Victor Berchet <victor@suumit.com>
 */
class RecursiveDirectoryIterator extends \RecursiveDirectoryIterator
{
    /**
     * @var bool
     */
    private $ignoreUnreadableDirs;

    /**
     * @var bool
     */
    private $rewindable;

    // these 3 properties take part of the performance optimization to avoid redoing the same work in all iterations
    private $rootPath;
    private $subPath;
    private $directorySeparator = '/';

    /**
     * @throws \RuntimeException
     */
    public function __construct(string $path, int $flags, bool $ignoreUnreadableDirs = false)
    {
        if ($flags & (self::CURRENT_AS_PATHNAME | self::CURRENT_AS_SELF)) {
            throw new \RuntimeException('This iterator only support returning current as fileinfo.');
        }

        parent::__construct($path, $flags);
        $this->ignoreUnreadableDirs = $ignoreUnreadableDirs;
        $this->rootPath = $path;
        if ('/' !== \DIRECTORY_SEPARATOR && !($flags & self::UNIX_PATHS)) {
            $this->directorySeparator = \DIRECTORY_SEPARATOR;
        }
    }

    /**
     * Return an instance of SplFileInfo with support for relative paths.
     *
     * @return SplFileInfo File information
     */
    #[\ReturnTypeWillChange]
    public function current()
    {
        // the logic here avoids redoing the same work in all iterations

        if (null === $subPathname = $this->subPath) {
            $subPathname = $this->subPath = (string) $this->getSubPath();
        }
        if ('' !== $subPathname) {
            $subPathname .= $this->directorySeparator;
        }
        $subPathname .= $this->getFilename();

        if ('/' !== $basePath = $this->rootPath) {
            $basePath .= $this->directorySeparator;
        }

        return new SplFileInfo($basePath.$subPathname, $this->subPath, $subPathname);
    }

    /**
     * @return \RecursiveIterator
     *
     * @throws AccessDeniedException
     */
    #[\ReturnTypeWillChange]
    public function getChildren()
    {
        try {
            $children = parent::getChildren();

            if ($children instanceof self) {
                // parent method will call the constructor with default arguments, so unreadable dirs won't be ignored anymore
                $children->ignoreUnreadableDirs = $this->ignoreUnreadableDirs;

                // performance optimization to avoid redoing the same work in all children
                $children->rewindable = &$this->rewindable;
                $children->rootPath = $this->rootPath;
            }

            return $children;
        } catch (\UnexpectedValueException $e) {
            if ($this->ignoreUnreadableDirs) {
                // If directory is unreadable and finder is set to ignore it, a fake empty content is returned.
                return new \RecursiveArrayIterator([]);
            } else {
                throw new AccessDeniedException($e->getMessage(), $e->getCode(), $e);
            }
        }
    }

    /**
     * Do nothing for non rewindable stream.
     *
     * @return void
     */
    #[\ReturnTypeWillChange]
    public function rewind()
    {
        if (false === $this->isRewindable()) {
            return;
        }

        parent::rewind();
    }

    /**
     * Checks if the stream is rewindable.
     *
     * @return bool true when the stream is rewindable, false otherwise
     */
    public function isRewindable()
    {
        if (null !== $this->rewindable) {
            return $this->rewindable;
        }

        if (false !== $stream = @opendir($this->getPath())) {
            $infos = stream_get_meta_data($stream);
            closedir($stream);

            if ($infos['seekable']) {
                return $this->rewindable = true;
            }
        }

        return $this->rewindable = false;
    }
}
PKϤ$Z�?�nn*finder/Iterator/FileTypeFilterIterator.phpnu�[���<?php

/*
 * This file is part of the Symfony package.
 *
 * (c) Fabien Potencier <fabien@symfony.com>
 *
 * For the full copyright and license information, please view the LICENSE
 * file that was distributed with this source code.
 */

namespace Symfony\Component\Finder\Iterator;

/**
 * FileTypeFilterIterator only keeps files, directories, or both.
 *
 * @author Fabien Potencier <fabien@symfony.com>
 */
class FileTypeFilterIterator extends \FilterIterator
{
    public const ONLY_FILES = 1;
    public const ONLY_DIRECTORIES = 2;

    private $mode;

    /**
     * @param \Iterator $iterator The Iterator to filter
     * @param int       $mode     The mode (self::ONLY_FILES or self::ONLY_DIRECTORIES)
     */
    public function __construct(\Iterator $iterator, int $mode)
    {
        $this->mode = $mode;

        parent::__construct($iterator);
    }

    /**
     * Filters the iterator values.
     *
     * @return bool true if the value should be kept, false otherwise
     */
    #[\ReturnTypeWillChange]
    public function accept()
    {
        $fileinfo = $this->current();
        if (self::ONLY_DIRECTORIES === (self::ONLY_DIRECTORIES & $this->mode) && $fileinfo->isFile()) {
            return false;
        } elseif (self::ONLY_FILES === (self::ONLY_FILES & $this->mode) && $fileinfo->isDir()) {
            return false;
        }

        return true;
    }
}
PKϤ$Z�dٝ�$finder/Iterator/SortableIterator.phpnu�[���<?php

/*
 * This file is part of the Symfony package.
 *
 * (c) Fabien Potencier <fabien@symfony.com>
 *
 * For the full copyright and license information, please view the LICENSE
 * file that was distributed with this source code.
 */

namespace Symfony\Component\Finder\Iterator;

/**
 * SortableIterator applies a sort on a given Iterator.
 *
 * @author Fabien Potencier <fabien@symfony.com>
 */
class SortableIterator implements \IteratorAggregate
{
    public const SORT_BY_NONE = 0;
    public const SORT_BY_NAME = 1;
    public const SORT_BY_TYPE = 2;
    public const SORT_BY_ACCESSED_TIME = 3;
    public const SORT_BY_CHANGED_TIME = 4;
    public const SORT_BY_MODIFIED_TIME = 5;
    public const SORT_BY_NAME_NATURAL = 6;

    private $iterator;
    private $sort;

    /**
     * @param int|callable $sort The sort type (SORT_BY_NAME, SORT_BY_TYPE, or a PHP callback)
     *
     * @throws \InvalidArgumentException
     */
    public function __construct(\Traversable $iterator, $sort, bool $reverseOrder = false)
    {
        $this->iterator = $iterator;
        $order = $reverseOrder ? -1 : 1;

        if (self::SORT_BY_NAME === $sort) {
            $this->sort = static function (\SplFileInfo $a, \SplFileInfo $b) use ($order) {
                return $order * strcmp($a->getRealPath() ?: $a->getPathname(), $b->getRealPath() ?: $b->getPathname());
            };
        } elseif (self::SORT_BY_NAME_NATURAL === $sort) {
            $this->sort = static function (\SplFileInfo $a, \SplFileInfo $b) use ($order) {
                return $order * strnatcmp($a->getRealPath() ?: $a->getPathname(), $b->getRealPath() ?: $b->getPathname());
            };
        } elseif (self::SORT_BY_TYPE === $sort) {
            $this->sort = static function (\SplFileInfo $a, \SplFileInfo $b) use ($order) {
                if ($a->isDir() && $b->isFile()) {
                    return -$order;
                } elseif ($a->isFile() && $b->isDir()) {
                    return $order;
                }

                return $order * strcmp($a->getRealPath() ?: $a->getPathname(), $b->getRealPath() ?: $b->getPathname());
            };
        } elseif (self::SORT_BY_ACCESSED_TIME === $sort) {
            $this->sort = static function (\SplFileInfo $a, \SplFileInfo $b) use ($order) {
                return $order * ($a->getATime() - $b->getATime());
            };
        } elseif (self::SORT_BY_CHANGED_TIME === $sort) {
            $this->sort = static function (\SplFileInfo $a, \SplFileInfo $b) use ($order) {
                return $order * ($a->getCTime() - $b->getCTime());
            };
        } elseif (self::SORT_BY_MODIFIED_TIME === $sort) {
            $this->sort = static function (\SplFileInfo $a, \SplFileInfo $b) use ($order) {
                return $order * ($a->getMTime() - $b->getMTime());
            };
        } elseif (self::SORT_BY_NONE === $sort) {
            $this->sort = $order;
        } elseif (\is_callable($sort)) {
            $this->sort = $reverseOrder ? static function (\SplFileInfo $a, \SplFileInfo $b) use ($sort) { return -$sort($a, $b); } : $sort;
        } else {
            throw new \InvalidArgumentException('The SortableIterator takes a PHP callable or a valid built-in sort algorithm as an argument.');
        }
    }

    /**
     * @return \Traversable
     */
    #[\ReturnTypeWillChange]
    public function getIterator()
    {
        if (1 === $this->sort) {
            return $this->iterator;
        }

        $array = iterator_to_array($this->iterator, true);

        if (-1 === $this->sort) {
            $array = array_reverse($array);
        } else {
            uasort($array, $this->sort);
        }

        return new \ArrayIterator($array);
    }
}
PKϤ$Z���PP%finder/Iterator/FilePathsIterator.phpnu�[���<?php

/*
 * This file is part of the Symfony package.
 *
 * (c) Fabien Potencier <fabien@symfony.com>
 *
 * For the full copyright and license information, please view the LICENSE
 * file that was distributed with this source code.
 */

namespace Symfony\Component\Finder\Iterator;

@trigger_error('The '.__NAMESPACE__.'\FilePathsIterator class is deprecated since version 2.8 and will be removed in 3.0.', E_USER_DEPRECATED);

use Symfony\Component\Finder\SplFileInfo;

/**
 * Iterate over shell command result.
 *
 * @author Jean-François Simon <contact@jfsimon.fr>
 *
 * @deprecated since 2.8, to be removed in 3.0.
 */
class FilePathsIterator extends \ArrayIterator
{
    /**
     * @var string
     */
    private $baseDir;

    /**
     * @var int
     */
    private $baseDirLength;

    /**
     * @var string
     */
    private $subPath;

    /**
     * @var string
     */
    private $subPathname;

    /**
     * @var SplFileInfo
     */
    private $current;

    /**
     * @param array  $paths   List of paths returned by shell command
     * @param string $baseDir Base dir for relative path building
     */
    public function __construct(array $paths, $baseDir)
    {
        $this->baseDir = $baseDir;
        $this->baseDirLength = strlen($baseDir);

        parent::__construct($paths);
    }

    /**
     * @param string $name
     * @param array  $arguments
     *
     * @return mixed
     */
    public function __call($name, array $arguments)
    {
        return call_user_func_array(array($this->current(), $name), $arguments);
    }

    /**
     * Return an instance of SplFileInfo with support for relative paths.
     *
     * @return SplFileInfo File information
     */
    public function current()
    {
        return $this->current;
    }

    /**
     * @return string
     */
    public function key()
    {
        return $this->current->getPathname();
    }

    public function next()
    {
        parent::next();
        $this->buildProperties();
    }

    public function rewind()
    {
        parent::rewind();
        $this->buildProperties();
    }

    /**
     * @return string
     */
    public function getSubPath()
    {
        return $this->subPath;
    }

    /**
     * @return string
     */
    public function getSubPathname()
    {
        return $this->subPathname;
    }

    private function buildProperties()
    {
        $absolutePath = parent::current();

        if ($this->baseDir === substr($absolutePath, 0, $this->baseDirLength)) {
            $this->subPathname = ltrim(substr($absolutePath, $this->baseDirLength), '/\\');
            $dir = dirname($this->subPathname);
            $this->subPath = '.' === $dir ? '' : $dir;
        } else {
            $this->subPath = $this->subPathname = '';
        }

        $this->current = new SplFileInfo(parent::current(), $this->subPath, $this->subPathname);
    }
}
PKϤ$Z���g��.finder/Iterator/MultiplePcreFilterIterator.phpnu�[���<?php

/*
 * This file is part of the Symfony package.
 *
 * (c) Fabien Potencier <fabien@symfony.com>
 *
 * For the full copyright and license information, please view the LICENSE
 * file that was distributed with this source code.
 */

namespace Symfony\Component\Finder\Iterator;

/**
 * MultiplePcreFilterIterator filters files using patterns (regexps, globs or strings).
 *
 * @author Fabien Potencier <fabien@symfony.com>
 */
abstract class MultiplePcreFilterIterator extends \FilterIterator
{
    protected $matchRegexps = [];
    protected $noMatchRegexps = [];

    /**
     * @param \Iterator $iterator        The Iterator to filter
     * @param string[]  $matchPatterns   An array of patterns that need to match
     * @param string[]  $noMatchPatterns An array of patterns that need to not match
     */
    public function __construct(\Iterator $iterator, array $matchPatterns, array $noMatchPatterns)
    {
        foreach ($matchPatterns as $pattern) {
            $this->matchRegexps[] = $this->toRegex($pattern);
        }

        foreach ($noMatchPatterns as $pattern) {
            $this->noMatchRegexps[] = $this->toRegex($pattern);
        }

        parent::__construct($iterator);
    }

    /**
     * Checks whether the string is accepted by the regex filters.
     *
     * If there is no regexps defined in the class, this method will accept the string.
     * Such case can be handled by child classes before calling the method if they want to
     * apply a different behavior.
     *
     * @return bool
     */
    protected function isAccepted(string $string)
    {
        // should at least not match one rule to exclude
        foreach ($this->noMatchRegexps as $regex) {
            if (preg_match($regex, $string)) {
                return false;
            }
        }

        // should at least match one rule
        if ($this->matchRegexps) {
            foreach ($this->matchRegexps as $regex) {
                if (preg_match($regex, $string)) {
                    return true;
                }
            }

            return false;
        }

        // If there is no match rules, the file is accepted
        return true;
    }

    /**
     * Checks whether the string is a regex.
     *
     * @return bool
     */
    protected function isRegex(string $str)
    {
        if (preg_match('/^(.{3,}?)[imsxuADU]*$/', $str, $m)) {
            $start = substr($m[1], 0, 1);
            $end = substr($m[1], -1);

            if ($start === $end) {
                return !preg_match('/[*?[:alnum:] \\\\]/', $start);
            }

            foreach ([['{', '}'], ['(', ')'], ['[', ']'], ['<', '>']] as $delimiters) {
                if ($start === $delimiters[0] && $end === $delimiters[1]) {
                    return true;
                }
            }
        }

        return false;
    }

    /**
     * Converts string into regexp.
     *
     * @return string
     */
    abstract protected function toRegex(string $str);
}
PKϤ$Z�ّ�� finder/Iterator/LazyIterator.phpnu�[���<?php

/*
 * This file is part of the Symfony package.
 *
 * (c) Fabien Potencier <fabien@symfony.com>
 *
 * For the full copyright and license information, please view the LICENSE
 * file that was distributed with this source code.
 */

namespace Symfony\Component\Finder\Iterator;

/**
 * @author Jérémy Derussé <jeremy@derusse.com>
 *
 * @internal
 */
class LazyIterator implements \IteratorAggregate
{
    private $iteratorFactory;

    public function __construct(callable $iteratorFactory)
    {
        $this->iteratorFactory = $iteratorFactory;
    }

    public function getIterator(): \Traversable
    {
        yield from ($this->iteratorFactory)();
    }
}
PKϤ$ZrpF7��+finder/Iterator/DateRangeFilterIterator.phpnu�[���<?php

/*
 * This file is part of the Symfony package.
 *
 * (c) Fabien Potencier <fabien@symfony.com>
 *
 * For the full copyright and license information, please view the LICENSE
 * file that was distributed with this source code.
 */

namespace Symfony\Component\Finder\Iterator;

use Symfony\Component\Finder\Comparator\DateComparator;

/**
 * DateRangeFilterIterator filters out files that are not in the given date range (last modified dates).
 *
 * @author Fabien Potencier <fabien@symfony.com>
 */
class DateRangeFilterIterator extends \FilterIterator
{
    private $comparators = [];

    /**
     * @param \Iterator        $iterator    The Iterator to filter
     * @param DateComparator[] $comparators An array of DateComparator instances
     */
    public function __construct(\Iterator $iterator, array $comparators)
    {
        $this->comparators = $comparators;

        parent::__construct($iterator);
    }

    /**
     * Filters the iterator values.
     *
     * @return bool true if the value should be kept, false otherwise
     */
    #[\ReturnTypeWillChange]
    public function accept()
    {
        $fileinfo = $this->current();

        if (!file_exists($fileinfo->getPathname())) {
            return false;
        }

        $filedate = $fileinfo->getMTime();
        foreach ($this->comparators as $compare) {
            if (!$compare->test($filedate)) {
                return false;
            }
        }

        return true;
    }
}
PKϤ$ZN��-��*finder/Iterator/FilenameFilterIterator.phpnu�[���<?php

/*
 * This file is part of the Symfony package.
 *
 * (c) Fabien Potencier <fabien@symfony.com>
 *
 * For the full copyright and license information, please view the LICENSE
 * file that was distributed with this source code.
 */

namespace Symfony\Component\Finder\Iterator;

use Symfony\Component\Finder\Glob;

/**
 * FilenameFilterIterator filters files by patterns (a regexp, a glob, or a string).
 *
 * @author Fabien Potencier <fabien@symfony.com>
 */
class FilenameFilterIterator extends MultiplePcreFilterIterator
{
    /**
     * Filters the iterator values.
     *
     * @return bool true if the value should be kept, false otherwise
     */
    #[\ReturnTypeWillChange]
    public function accept()
    {
        return $this->isAccepted($this->current()->getFilename());
    }

    /**
     * Converts glob to regexp.
     *
     * PCRE patterns are left unchanged.
     * Glob strings are transformed with Glob::toRegex().
     *
     * @param string $str Pattern: glob or regexp
     *
     * @return string regexp corresponding to a given glob or regexp
     */
    protected function toRegex(string $str)
    {
        return $this->isRegex($str) ? $str : Glob::toRegex($str);
    }
}
PKϤ$Z�\X2
2
2finder/Iterator/ExcludeDirectoryFilterIterator.phpnu�[���<?php

/*
 * This file is part of the Symfony package.
 *
 * (c) Fabien Potencier <fabien@symfony.com>
 *
 * For the full copyright and license information, please view the LICENSE
 * file that was distributed with this source code.
 */

namespace Symfony\Component\Finder\Iterator;

/**
 * ExcludeDirectoryFilterIterator filters out directories.
 *
 * @author Fabien Potencier <fabien@symfony.com>
 */
class ExcludeDirectoryFilterIterator extends \FilterIterator implements \RecursiveIterator
{
    private $iterator;
    private $isRecursive;
    private $excludedDirs = [];
    private $excludedPattern;

    /**
     * @param \Iterator $iterator    The Iterator to filter
     * @param string[]  $directories An array of directories to exclude
     */
    public function __construct(\Iterator $iterator, array $directories)
    {
        $this->iterator = $iterator;
        $this->isRecursive = $iterator instanceof \RecursiveIterator;
        $patterns = [];
        foreach ($directories as $directory) {
            $directory = rtrim($directory, '/');
            if (!$this->isRecursive || str_contains($directory, '/')) {
                $patterns[] = preg_quote($directory, '#');
            } else {
                $this->excludedDirs[$directory] = true;
            }
        }
        if ($patterns) {
            $this->excludedPattern = '#(?:^|/)(?:'.implode('|', $patterns).')(?:/|$)#';
        }

        parent::__construct($iterator);
    }

    /**
     * Filters the iterator values.
     *
     * @return bool True if the value should be kept, false otherwise
     */
    #[\ReturnTypeWillChange]
    public function accept()
    {
        if ($this->isRecursive && isset($this->excludedDirs[$this->getFilename()]) && $this->isDir()) {
            return false;
        }

        if ($this->excludedPattern) {
            $path = $this->isDir() ? $this->current()->getRelativePathname() : $this->current()->getRelativePath();
            $path = str_replace('\\', '/', $path);

            return !preg_match($this->excludedPattern, $path);
        }

        return true;
    }

    /**
     * @return bool
     */
    #[\ReturnTypeWillChange]
    public function hasChildren()
    {
        return $this->isRecursive && $this->iterator->hasChildren();
    }

    /**
     * @return self
     */
    #[\ReturnTypeWillChange]
    public function getChildren()
    {
        $children = new self($this->iterator->getChildren(), []);
        $children->excludedDirs = $this->excludedDirs;
        $children->excludedPattern = $this->excludedPattern;

        return $children;
    }
}
PKϤ$Z#���,finder/Iterator/DepthRangeFilterIterator.phpnu�[���<?php

/*
 * This file is part of the Symfony package.
 *
 * (c) Fabien Potencier <fabien@symfony.com>
 *
 * For the full copyright and license information, please view the LICENSE
 * file that was distributed with this source code.
 */

namespace Symfony\Component\Finder\Iterator;

/**
 * DepthRangeFilterIterator limits the directory depth.
 *
 * @author Fabien Potencier <fabien@symfony.com>
 */
class DepthRangeFilterIterator extends \FilterIterator
{
    private $minDepth = 0;

    /**
     * @param \RecursiveIteratorIterator $iterator The Iterator to filter
     * @param int                        $minDepth The min depth
     * @param int                        $maxDepth The max depth
     */
    public function __construct(\RecursiveIteratorIterator $iterator, int $minDepth = 0, int $maxDepth = \PHP_INT_MAX)
    {
        $this->minDepth = $minDepth;
        $iterator->setMaxDepth(\PHP_INT_MAX === $maxDepth ? -1 : $maxDepth);

        parent::__construct($iterator);
    }

    /**
     * Filters the iterator values.
     *
     * @return bool true if the value should be kept, false otherwise
     */
    #[\ReturnTypeWillChange]
    public function accept()
    {
        return $this->getInnerIterator()->getDepth() >= $this->minDepth;
    }
}
PKϤ$Z�y����(finder/Iterator/CustomFilterIterator.phpnu�[���<?php

/*
 * This file is part of the Symfony package.
 *
 * (c) Fabien Potencier <fabien@symfony.com>
 *
 * For the full copyright and license information, please view the LICENSE
 * file that was distributed with this source code.
 */

namespace Symfony\Component\Finder\Iterator;

/**
 * CustomFilterIterator filters files by applying anonymous functions.
 *
 * The anonymous function receives a \SplFileInfo and must return false
 * to remove files.
 *
 * @author Fabien Potencier <fabien@symfony.com>
 */
class CustomFilterIterator extends \FilterIterator
{
    private $filters = [];

    /**
     * @param \Iterator  $iterator The Iterator to filter
     * @param callable[] $filters  An array of PHP callbacks
     *
     * @throws \InvalidArgumentException
     */
    public function __construct(\Iterator $iterator, array $filters)
    {
        foreach ($filters as $filter) {
            if (!\is_callable($filter)) {
                throw new \InvalidArgumentException('Invalid PHP callback.');
            }
        }
        $this->filters = $filters;

        parent::__construct($iterator);
    }

    /**
     * Filters the iterator values.
     *
     * @return bool true if the value should be kept, false otherwise
     */
    #[\ReturnTypeWillChange]
    public function accept()
    {
        $fileinfo = $this->current();

        foreach ($this->filters as $filter) {
            if (false === $filter($fileinfo)) {
                return false;
            }
        }

        return true;
    }
}
PKϤ$Z����-finder/Iterator/FilecontentFilterIterator.phpnu�[���<?php

/*
 * This file is part of the Symfony package.
 *
 * (c) Fabien Potencier <fabien@symfony.com>
 *
 * For the full copyright and license information, please view the LICENSE
 * file that was distributed with this source code.
 */

namespace Symfony\Component\Finder\Iterator;

/**
 * FilecontentFilterIterator filters files by their contents using patterns (regexps or strings).
 *
 * @author Fabien Potencier  <fabien@symfony.com>
 * @author Włodzimierz Gajda <gajdaw@gajdaw.pl>
 */
class FilecontentFilterIterator extends MultiplePcreFilterIterator
{
    /**
     * Filters the iterator values.
     *
     * @return bool true if the value should be kept, false otherwise
     */
    #[\ReturnTypeWillChange]
    public function accept()
    {
        if (!$this->matchRegexps && !$this->noMatchRegexps) {
            return true;
        }

        $fileinfo = $this->current();

        if ($fileinfo->isDir() || !$fileinfo->isReadable()) {
            return false;
        }

        $content = $fileinfo->getContents();
        if (!$content) {
            return false;
        }

        return $this->isAccepted($content);
    }

    /**
     * Converts string to regexp if necessary.
     *
     * @param string $str Pattern: string or regexp
     *
     * @return string regexp corresponding to a given string or regexp
     */
    protected function toRegex(string $str)
    {
        return $this->isRegex($str) ? $str : '/'.preg_quote($str, '/').'/';
    }
}
PKϤ$ZP-����+finder/Iterator/SizeRangeFilterIterator.phpnu�[���<?php

/*
 * This file is part of the Symfony package.
 *
 * (c) Fabien Potencier <fabien@symfony.com>
 *
 * For the full copyright and license information, please view the LICENSE
 * file that was distributed with this source code.
 */

namespace Symfony\Component\Finder\Iterator;

use Symfony\Component\Finder\Comparator\NumberComparator;

/**
 * SizeRangeFilterIterator filters out files that are not in the given size range.
 *
 * @author Fabien Potencier <fabien@symfony.com>
 */
class SizeRangeFilterIterator extends \FilterIterator
{
    private $comparators = [];

    /**
     * @param \Iterator          $iterator    The Iterator to filter
     * @param NumberComparator[] $comparators An array of NumberComparator instances
     */
    public function __construct(\Iterator $iterator, array $comparators)
    {
        $this->comparators = $comparators;

        parent::__construct($iterator);
    }

    /**
     * Filters the iterator values.
     *
     * @return bool true if the value should be kept, false otherwise
     */
    #[\ReturnTypeWillChange]
    public function accept()
    {
        $fileinfo = $this->current();
        if (!$fileinfo->isFile()) {
            return true;
        }

        $filesize = $fileinfo->getSize();
        foreach ($this->comparators as $compare) {
            if (!$compare->test($filesize)) {
                return false;
            }
        }

        return true;
    }
}
PKϤ$Z�A�;��"finder/Iterator/FilterIterator.phpnu�[���<?php

/*
 * This file is part of the Symfony package.
 *
 * (c) Fabien Potencier <fabien@symfony.com>
 *
 * For the full copyright and license information, please view the LICENSE
 * file that was distributed with this source code.
 */

namespace Symfony\Component\Finder\Iterator;

/**
 * This iterator just overrides the rewind method in order to correct a PHP bug,
 * which existed before version 5.5.23/5.6.7.
 *
 * @see https://bugs.php.net/68557
 *
 * @author Alex Bogomazov
 */
abstract class FilterIterator extends \FilterIterator
{
    /**
     * This is a workaround for the problem with \FilterIterator leaving inner \FilesystemIterator in wrong state after
     * rewind in some cases.
     *
     * @see FilterIterator::rewind()
     */
    public function rewind()
    {
        if (PHP_VERSION_ID > 50607 || (PHP_VERSION_ID > 50523 && PHP_VERSION_ID < 50600)) {
            parent::rewind();

            return;
        }

        $iterator = $this;
        while ($iterator instanceof \OuterIterator) {
            $innerIterator = $iterator->getInnerIterator();

            if ($innerIterator instanceof RecursiveDirectoryIterator) {
                // this condition is necessary for iterators to work properly with non-local filesystems like ftp
                if ($innerIterator->isRewindable()) {
                    $innerIterator->next();
                    $innerIterator->rewind();
                }
            } elseif ($innerIterator instanceof \FilesystemIterator) {
                $innerIterator->next();
                $innerIterator->rewind();
            }

            $iterator = $innerIterator;
        }

        parent::rewind();
    }
}
PKϤ$Zh�N֋
�
finder/Gitignore.phpnu�[���<?php

/*
 * This file is part of the Symfony package.
 *
 * (c) Fabien Potencier <fabien@symfony.com>
 *
 * For the full copyright and license information, please view the LICENSE
 * file that was distributed with this source code.
 */

namespace Symfony\Component\Finder;

/**
 * Gitignore matches against text.
 *
 * @author Michael Voříšek <vorismi3@fel.cvut.cz>
 * @author Ahmed Abdou <mail@ahmd.io>
 */
class Gitignore
{
    /**
     * Returns a regexp which is the equivalent of the gitignore pattern.
     *
     * Format specification: https://git-scm.com/docs/gitignore#_pattern_format
     */
    public static function toRegex(string $gitignoreFileContent): string
    {
        $gitignoreFileContent = preg_replace('~(?<!\\\\)#[^\n\r]*~', '', $gitignoreFileContent);
        $gitignoreLines = preg_split('~\r\n?|\n~', $gitignoreFileContent);

        $res = self::lineToRegex('');
        foreach ($gitignoreLines as $i => $line) {
            $line = preg_replace('~(?<!\\\\)[ \t]+$~', '', $line);

            if ('!' === substr($line, 0, 1)) {
                $line = substr($line, 1);
                $isNegative = true;
            } else {
                $isNegative = false;
            }

            if ('' !== $line) {
                if ($isNegative) {
                    $res = '(?!'.self::lineToRegex($line).'$)'.$res;
                } else {
                    $res = '(?:'.$res.'|'.self::lineToRegex($line).')';
                }
            }
        }

        return '~^(?:'.$res.')~s';
    }

    private static function lineToRegex(string $gitignoreLine): string
    {
        if ('' === $gitignoreLine) {
            return '$f'; // always false
        }

        $slashPos = strpos($gitignoreLine, '/');
        if (false !== $slashPos && \strlen($gitignoreLine) - 1 !== $slashPos) {
            if (0 === $slashPos) {
                $gitignoreLine = substr($gitignoreLine, 1);
            }
            $isAbsolute = true;
        } else {
            $isAbsolute = false;
        }

        $regex = preg_quote(str_replace('\\', '', $gitignoreLine), '~');
        $regex = preg_replace_callback('~\\\\\[((?:\\\\!)?)([^\[\]]*)\\\\\]~', function (array $matches): string {
            return '['.('' !== $matches[1] ? '^' : '').str_replace('\\-', '-', $matches[2]).']';
        }, $regex);
        $regex = preg_replace('~(?:(?:\\\\\*){2,}(/?))+~', '(?:(?:(?!//).(?<!//))+$1)?', $regex);
        $regex = preg_replace('~\\\\\*~', '[^/]*', $regex);
        $regex = preg_replace('~\\\\\?~', '[^/]', $regex);

        return ($isAbsolute ? '' : '(?:[^/]+/)*')
            .$regex
            .(!str_ends_with($gitignoreLine, '/') ? '(?:$|/)' : '');
    }
}
PKϤ$ZU�=O&Y&Yfinder/Finder.phpnu�[���<?php

/*
 * This file is part of the Symfony package.
 *
 * (c) Fabien Potencier <fabien@symfony.com>
 *
 * For the full copyright and license information, please view the LICENSE
 * file that was distributed with this source code.
 */

namespace Symfony\Component\Finder;

use Symfony\Component\Finder\Comparator\DateComparator;
use Symfony\Component\Finder\Comparator\NumberComparator;
use Symfony\Component\Finder\Exception\DirectoryNotFoundException;
use Symfony\Component\Finder\Iterator\CustomFilterIterator;
use Symfony\Component\Finder\Iterator\DateRangeFilterIterator;
use Symfony\Component\Finder\Iterator\DepthRangeFilterIterator;
use Symfony\Component\Finder\Iterator\ExcludeDirectoryFilterIterator;
use Symfony\Component\Finder\Iterator\FilecontentFilterIterator;
use Symfony\Component\Finder\Iterator\FilenameFilterIterator;
use Symfony\Component\Finder\Iterator\LazyIterator;
use Symfony\Component\Finder\Iterator\SizeRangeFilterIterator;
use Symfony\Component\Finder\Iterator\SortableIterator;

/**
 * Finder allows to build rules to find files and directories.
 *
 * It is a thin wrapper around several specialized iterator classes.
 *
 * All rules may be invoked several times.
 *
 * All methods return the current Finder object to allow chaining:
 *
 *     $finder = Finder::create()->files()->name('*.php')->in(__DIR__);
 *
 * @author Fabien Potencier <fabien@symfony.com>
 */
class Finder implements \IteratorAggregate, \Countable
{
    public const IGNORE_VCS_FILES = 1;
    public const IGNORE_DOT_FILES = 2;
    public const IGNORE_VCS_IGNORED_FILES = 4;

    private $mode = 0;
    private $names = [];
    private $notNames = [];
    private $exclude = [];
    private $filters = [];
    private $depths = [];
    private $sizes = [];
    private $followLinks = false;
    private $reverseSorting = false;
    private $sort = false;
    private $ignore = 0;
    private $dirs = [];
    private $dates = [];
    private $iterators = [];
    private $contains = [];
    private $notContains = [];
    private $paths = [];
    private $notPaths = [];
    private $ignoreUnreadableDirs = false;

    private static $vcsPatterns = ['.svn', '_svn', 'CVS', '_darcs', '.arch-params', '.monotone', '.bzr', '.git', '.hg'];

    public function __construct()
    {
        $this->ignore = static::IGNORE_VCS_FILES | static::IGNORE_DOT_FILES;
    }

    /**
     * Creates a new Finder.
     *
     * @return static
     */
    public static function create()
    {
        return new static();
    }

    /**
     * Restricts the matching to directories only.
     *
     * @return $this
     */
    public function directories()
    {
        $this->mode = Iterator\FileTypeFilterIterator::ONLY_DIRECTORIES;

        return $this;
    }

    /**
     * Restricts the matching to files only.
     *
     * @return $this
     */
    public function files()
    {
        $this->mode = Iterator\FileTypeFilterIterator::ONLY_FILES;

        return $this;
    }

    /**
     * Adds tests for the directory depth.
     *
     * Usage:
     *
     *     $finder->depth('> 1') // the Finder will start matching at level 1.
     *     $finder->depth('< 3') // the Finder will descend at most 3 levels of directories below the starting point.
     *     $finder->depth(['>= 1', '< 3'])
     *
     * @param string|int|string[]|int[] $levels The depth level expression or an array of depth levels
     *
     * @return $this
     *
     * @see DepthRangeFilterIterator
     * @see NumberComparator
     */
    public function depth($levels)
    {
        foreach ((array) $levels as $level) {
            $this->depths[] = new Comparator\NumberComparator($level);
        }

        return $this;
    }

    /**
     * Adds tests for file dates (last modified).
     *
     * The date must be something that strtotime() is able to parse:
     *
     *     $finder->date('since yesterday');
     *     $finder->date('until 2 days ago');
     *     $finder->date('> now - 2 hours');
     *     $finder->date('>= 2005-10-15');
     *     $finder->date(['>= 2005-10-15', '<= 2006-05-27']);
     *
     * @param string|string[] $dates A date range string or an array of date ranges
     *
     * @return $this
     *
     * @see strtotime
     * @see DateRangeFilterIterator
     * @see DateComparator
     */
    public function date($dates)
    {
        foreach ((array) $dates as $date) {
            $this->dates[] = new Comparator\DateComparator($date);
        }

        return $this;
    }

    /**
     * Adds rules that files must match.
     *
     * You can use patterns (delimited with / sign), globs or simple strings.
     *
     *     $finder->name('*.php')
     *     $finder->name('/\.php$/') // same as above
     *     $finder->name('test.php')
     *     $finder->name(['test.py', 'test.php'])
     *
     * @param string|string[] $patterns A pattern (a regexp, a glob, or a string) or an array of patterns
     *
     * @return $this
     *
     * @see FilenameFilterIterator
     */
    public function name($patterns)
    {
        $this->names = array_merge($this->names, (array) $patterns);

        return $this;
    }

    /**
     * Adds rules that files must not match.
     *
     * @param string|string[] $patterns A pattern (a regexp, a glob, or a string) or an array of patterns
     *
     * @return $this
     *
     * @see FilenameFilterIterator
     */
    public function notName($patterns)
    {
        $this->notNames = array_merge($this->notNames, (array) $patterns);

        return $this;
    }

    /**
     * Adds tests that file contents must match.
     *
     * Strings or PCRE patterns can be used:
     *
     *     $finder->contains('Lorem ipsum')
     *     $finder->contains('/Lorem ipsum/i')
     *     $finder->contains(['dolor', '/ipsum/i'])
     *
     * @param string|string[] $patterns A pattern (string or regexp) or an array of patterns
     *
     * @return $this
     *
     * @see FilecontentFilterIterator
     */
    public function contains($patterns)
    {
        $this->contains = array_merge($this->contains, (array) $patterns);

        return $this;
    }

    /**
     * Adds tests that file contents must not match.
     *
     * Strings or PCRE patterns can be used:
     *
     *     $finder->notContains('Lorem ipsum')
     *     $finder->notContains('/Lorem ipsum/i')
     *     $finder->notContains(['lorem', '/dolor/i'])
     *
     * @param string|string[] $patterns A pattern (string or regexp) or an array of patterns
     *
     * @return $this
     *
     * @see FilecontentFilterIterator
     */
    public function notContains($patterns)
    {
        $this->notContains = array_merge($this->notContains, (array) $patterns);

        return $this;
    }

    /**
     * Adds rules that filenames must match.
     *
     * You can use patterns (delimited with / sign) or simple strings.
     *
     *     $finder->path('some/special/dir')
     *     $finder->path('/some\/special\/dir/') // same as above
     *     $finder->path(['some dir', 'another/dir'])
     *
     * Use only / as dirname separator.
     *
     * @param string|string[] $patterns A pattern (a regexp or a string) or an array of patterns
     *
     * @return $this
     *
     * @see FilenameFilterIterator
     */
    public function path($patterns)
    {
        $this->paths = array_merge($this->paths, (array) $patterns);

        return $this;
    }

    /**
     * Adds rules that filenames must not match.
     *
     * You can use patterns (delimited with / sign) or simple strings.
     *
     *     $finder->notPath('some/special/dir')
     *     $finder->notPath('/some\/special\/dir/') // same as above
     *     $finder->notPath(['some/file.txt', 'another/file.log'])
     *
     * Use only / as dirname separator.
     *
     * @param string|string[] $patterns A pattern (a regexp or a string) or an array of patterns
     *
     * @return $this
     *
     * @see FilenameFilterIterator
     */
    public function notPath($patterns)
    {
        $this->notPaths = array_merge($this->notPaths, (array) $patterns);

        return $this;
    }

    /**
     * Adds tests for file sizes.
     *
     *     $finder->size('> 10K');
     *     $finder->size('<= 1Ki');
     *     $finder->size(4);
     *     $finder->size(['> 10K', '< 20K'])
     *
     * @param string|int|string[]|int[] $sizes A size range string or an integer or an array of size ranges
     *
     * @return $this
     *
     * @see SizeRangeFilterIterator
     * @see NumberComparator
     */
    public function size($sizes)
    {
        foreach ((array) $sizes as $size) {
            $this->sizes[] = new Comparator\NumberComparator($size);
        }

        return $this;
    }

    /**
     * Excludes directories.
     *
     * Directories passed as argument must be relative to the ones defined with the `in()` method. For example:
     *
     *     $finder->in(__DIR__)->exclude('ruby');
     *
     * @param string|array $dirs A directory path or an array of directories
     *
     * @return $this
     *
     * @see ExcludeDirectoryFilterIterator
     */
    public function exclude($dirs)
    {
        $this->exclude = array_merge($this->exclude, (array) $dirs);

        return $this;
    }

    /**
     * Excludes "hidden" directories and files (starting with a dot).
     *
     * This option is enabled by default.
     *
     * @return $this
     *
     * @see ExcludeDirectoryFilterIterator
     */
    public function ignoreDotFiles(bool $ignoreDotFiles)
    {
        if ($ignoreDotFiles) {
            $this->ignore |= static::IGNORE_DOT_FILES;
        } else {
            $this->ignore &= ~static::IGNORE_DOT_FILES;
        }

        return $this;
    }

    /**
     * Forces the finder to ignore version control directories.
     *
     * This option is enabled by default.
     *
     * @return $this
     *
     * @see ExcludeDirectoryFilterIterator
     */
    public function ignoreVCS(bool $ignoreVCS)
    {
        if ($ignoreVCS) {
            $this->ignore |= static::IGNORE_VCS_FILES;
        } else {
            $this->ignore &= ~static::IGNORE_VCS_FILES;
        }

        return $this;
    }

    /**
     * Forces Finder to obey .gitignore and ignore files based on rules listed there.
     *
     * This option is disabled by default.
     *
     * @return $this
     */
    public function ignoreVCSIgnored(bool $ignoreVCSIgnored)
    {
        if ($ignoreVCSIgnored) {
            $this->ignore |= static::IGNORE_VCS_IGNORED_FILES;
        } else {
            $this->ignore &= ~static::IGNORE_VCS_IGNORED_FILES;
        }

        return $this;
    }

    /**
     * Adds VCS patterns.
     *
     * @see ignoreVCS()
     *
     * @param string|string[] $pattern VCS patterns to ignore
     */
    public static function addVCSPattern($pattern)
    {
        foreach ((array) $pattern as $p) {
            self::$vcsPatterns[] = $p;
        }

        self::$vcsPatterns = array_unique(self::$vcsPatterns);
    }

    /**
     * Sorts files and directories by an anonymous function.
     *
     * The anonymous function receives two \SplFileInfo instances to compare.
     *
     * This can be slow as all the matching files and directories must be retrieved for comparison.
     *
     * @return $this
     *
     * @see SortableIterator
     */
    public function sort(\Closure $closure)
    {
        $this->sort = $closure;

        return $this;
    }

    /**
     * Sorts files and directories by name.
     *
     * This can be slow as all the matching files and directories must be retrieved for comparison.
     *
     * @return $this
     *
     * @see SortableIterator
     */
    public function sortByName(bool $useNaturalSort = false)
    {
        $this->sort = $useNaturalSort ? Iterator\SortableIterator::SORT_BY_NAME_NATURAL : Iterator\SortableIterator::SORT_BY_NAME;

        return $this;
    }

    /**
     * Sorts files and directories by type (directories before files), then by name.
     *
     * This can be slow as all the matching files and directories must be retrieved for comparison.
     *
     * @return $this
     *
     * @see SortableIterator
     */
    public function sortByType()
    {
        $this->sort = Iterator\SortableIterator::SORT_BY_TYPE;

        return $this;
    }

    /**
     * Sorts files and directories by the last accessed time.
     *
     * This is the time that the file was last accessed, read or written to.
     *
     * This can be slow as all the matching files and directories must be retrieved for comparison.
     *
     * @return $this
     *
     * @see SortableIterator
     */
    public function sortByAccessedTime()
    {
        $this->sort = Iterator\SortableIterator::SORT_BY_ACCESSED_TIME;

        return $this;
    }

    /**
     * Reverses the sorting.
     *
     * @return $this
     */
    public function reverseSorting()
    {
        $this->reverseSorting = true;

        return $this;
    }

    /**
     * Sorts files and directories by the last inode changed time.
     *
     * This is the time that the inode information was last modified (permissions, owner, group or other metadata).
     *
     * On Windows, since inode is not available, changed time is actually the file creation time.
     *
     * This can be slow as all the matching files and directories must be retrieved for comparison.
     *
     * @return $this
     *
     * @see SortableIterator
     */
    public function sortByChangedTime()
    {
        $this->sort = Iterator\SortableIterator::SORT_BY_CHANGED_TIME;

        return $this;
    }

    /**
     * Sorts files and directories by the last modified time.
     *
     * This is the last time the actual contents of the file were last modified.
     *
     * This can be slow as all the matching files and directories must be retrieved for comparison.
     *
     * @return $this
     *
     * @see SortableIterator
     */
    public function sortByModifiedTime()
    {
        $this->sort = Iterator\SortableIterator::SORT_BY_MODIFIED_TIME;

        return $this;
    }

    /**
     * Filters the iterator with an anonymous function.
     *
     * The anonymous function receives a \SplFileInfo and must return false
     * to remove files.
     *
     * @return $this
     *
     * @see CustomFilterIterator
     */
    public function filter(\Closure $closure)
    {
        $this->filters[] = $closure;

        return $this;
    }

    /**
     * Forces the following of symlinks.
     *
     * @return $this
     */
    public function followLinks()
    {
        $this->followLinks = true;

        return $this;
    }

    /**
     * Tells finder to ignore unreadable directories.
     *
     * By default, scanning unreadable directories content throws an AccessDeniedException.
     *
     * @return $this
     */
    public function ignoreUnreadableDirs(bool $ignore = true)
    {
        $this->ignoreUnreadableDirs = $ignore;

        return $this;
    }

    /**
     * Searches files and directories which match defined rules.
     *
     * @param string|string[] $dirs A directory path or an array of directories
     *
     * @return $this
     *
     * @throws DirectoryNotFoundException if one of the directories does not exist
     */
    public function in($dirs)
    {
        $resolvedDirs = [];

        foreach ((array) $dirs as $dir) {
            if (is_dir($dir)) {
                $resolvedDirs[] = $this->normalizeDir($dir);
            } elseif ($glob = glob($dir, (\defined('GLOB_BRACE') ? \GLOB_BRACE : 0) | \GLOB_ONLYDIR | \GLOB_NOSORT)) {
                sort($glob);
                $resolvedDirs = array_merge($resolvedDirs, array_map([$this, 'normalizeDir'], $glob));
            } else {
                throw new DirectoryNotFoundException(sprintf('The "%s" directory does not exist.', $dir));
            }
        }

        $this->dirs = array_merge($this->dirs, $resolvedDirs);

        return $this;
    }

    /**
     * Returns an Iterator for the current Finder configuration.
     *
     * This method implements the IteratorAggregate interface.
     *
     * @return \Iterator|SplFileInfo[] An iterator
     *
     * @throws \LogicException if the in() method has not been called
     */
    #[\ReturnTypeWillChange]
    public function getIterator()
    {
        if (0 === \count($this->dirs) && 0 === \count($this->iterators)) {
            throw new \LogicException('You must call one of in() or append() methods before iterating over a Finder.');
        }

        if (1 === \count($this->dirs) && 0 === \count($this->iterators)) {
            $iterator = $this->searchInDirectory($this->dirs[0]);

            if ($this->sort || $this->reverseSorting) {
                $iterator = (new Iterator\SortableIterator($iterator, $this->sort, $this->reverseSorting))->getIterator();
            }

            return $iterator;
        }

        $iterator = new \AppendIterator();
        foreach ($this->dirs as $dir) {
            $iterator->append(new \IteratorIterator(new LazyIterator(function () use ($dir) {
                return $this->searchInDirectory($dir);
            })));
        }

        foreach ($this->iterators as $it) {
            $iterator->append($it);
        }

        if ($this->sort || $this->reverseSorting) {
            $iterator = (new Iterator\SortableIterator($iterator, $this->sort, $this->reverseSorting))->getIterator();
        }

        return $iterator;
    }

    /**
     * Appends an existing set of files/directories to the finder.
     *
     * The set can be another Finder, an Iterator, an IteratorAggregate, or even a plain array.
     *
     * @return $this
     *
     * @throws \InvalidArgumentException when the given argument is not iterable
     */
    public function append(iterable $iterator)
    {
        if ($iterator instanceof \IteratorAggregate) {
            $this->iterators[] = $iterator->getIterator();
        } elseif ($iterator instanceof \Iterator) {
            $this->iterators[] = $iterator;
        } elseif (is_iterable($iterator)) {
            $it = new \ArrayIterator();
            foreach ($iterator as $file) {
                $file = $file instanceof \SplFileInfo ? $file : new \SplFileInfo($file);
                $it[$file->getPathname()] = $file;
            }
            $this->iterators[] = $it;
        } else {
            throw new \InvalidArgumentException('Finder::append() method wrong argument type.');
        }

        return $this;
    }

    /**
     * Check if any results were found.
     *
     * @return bool
     */
    public function hasResults()
    {
        foreach ($this->getIterator() as $_) {
            return true;
        }

        return false;
    }

    /**
     * Counts all the results collected by the iterators.
     *
     * @return int
     */
    #[\ReturnTypeWillChange]
    public function count()
    {
        return iterator_count($this->getIterator());
    }

    private function searchInDirectory(string $dir): \Iterator
    {
        $exclude = $this->exclude;
        $notPaths = $this->notPaths;

        if (static::IGNORE_VCS_FILES === (static::IGNORE_VCS_FILES & $this->ignore)) {
            $exclude = array_merge($exclude, self::$vcsPatterns);
        }

        if (static::IGNORE_DOT_FILES === (static::IGNORE_DOT_FILES & $this->ignore)) {
            $notPaths[] = '#(^|/)\..+(/|$)#';
        }

        if (static::IGNORE_VCS_IGNORED_FILES === (static::IGNORE_VCS_IGNORED_FILES & $this->ignore)) {
            $gitignoreFilePath = sprintf('%s/.gitignore', $dir);
            if (!is_readable($gitignoreFilePath)) {
                throw new \RuntimeException(sprintf('The "ignoreVCSIgnored" option cannot be used by the Finder as the "%s" file is not readable.', $gitignoreFilePath));
            }
            $notPaths = array_merge($notPaths, [Gitignore::toRegex(file_get_contents($gitignoreFilePath))]);
        }

        $minDepth = 0;
        $maxDepth = \PHP_INT_MAX;

        foreach ($this->depths as $comparator) {
            switch ($comparator->getOperator()) {
                case '>':
                    $minDepth = $comparator->getTarget() + 1;
                    break;
                case '>=':
                    $minDepth = $comparator->getTarget();
                    break;
                case '<':
                    $maxDepth = $comparator->getTarget() - 1;
                    break;
                case '<=':
                    $maxDepth = $comparator->getTarget();
                    break;
                default:
                    $minDepth = $maxDepth = $comparator->getTarget();
            }
        }

        $flags = \RecursiveDirectoryIterator::SKIP_DOTS;

        if ($this->followLinks) {
            $flags |= \RecursiveDirectoryIterator::FOLLOW_SYMLINKS;
        }

        $iterator = new Iterator\RecursiveDirectoryIterator($dir, $flags, $this->ignoreUnreadableDirs);

        if ($exclude) {
            $iterator = new Iterator\ExcludeDirectoryFilterIterator($iterator, $exclude);
        }

        $iterator = new \RecursiveIteratorIterator($iterator, \RecursiveIteratorIterator::SELF_FIRST);

        if ($minDepth > 0 || $maxDepth < \PHP_INT_MAX) {
            $iterator = new Iterator\DepthRangeFilterIterator($iterator, $minDepth, $maxDepth);
        }

        if ($this->mode) {
            $iterator = new Iterator\FileTypeFilterIterator($iterator, $this->mode);
        }

        if ($this->names || $this->notNames) {
            $iterator = new Iterator\FilenameFilterIterator($iterator, $this->names, $this->notNames);
        }

        if ($this->contains || $this->notContains) {
            $iterator = new Iterator\FilecontentFilterIterator($iterator, $this->contains, $this->notContains);
        }

        if ($this->sizes) {
            $iterator = new Iterator\SizeRangeFilterIterator($iterator, $this->sizes);
        }

        if ($this->dates) {
            $iterator = new Iterator\DateRangeFilterIterator($iterator, $this->dates);
        }

        if ($this->filters) {
            $iterator = new Iterator\CustomFilterIterator($iterator, $this->filters);
        }

        if ($this->paths || $notPaths) {
            $iterator = new Iterator\PathFilterIterator($iterator, $this->paths, $notPaths);
        }

        return $iterator;
    }

    /**
     * Normalizes given directory names by removing trailing slashes.
     *
     * Excluding: (s)ftp:// or ssh2.(s)ftp:// wrapper
     */
    private function normalizeDir(string $dir): string
    {
        if ('/' === $dir) {
            return $dir;
        }

        $dir = rtrim($dir, '/'.\DIRECTORY_SEPARATOR);

        if (preg_match('#^(ssh2\.)?s?ftp://#', $dir)) {
            $dir .= '/';
        }

        return $dir;
    }
}
PKϤ$Z�FHfinder/Expression/Regex.phpnu�[���<?php

/*
 * This file is part of the Symfony package.
 *
 * (c) Fabien Potencier <fabien@symfony.com>
 *
 * For the full copyright and license information, please view the LICENSE
 * file that was distributed with this source code.
 */

namespace Symfony\Component\Finder\Expression;

@trigger_error('The '.__NAMESPACE__.'\Regex class is deprecated since version 2.8 and will be removed in 3.0.', E_USER_DEPRECATED);

/**
 * @author Jean-François Simon <contact@jfsimon.fr>
 */
class Regex implements ValueInterface
{
    const START_FLAG = '^';
    const END_FLAG = '$';
    const BOUNDARY = '~';
    const JOKER = '.*';
    const ESCAPING = '\\';

    /**
     * @var string
     */
    private $pattern;

    /**
     * @var array
     */
    private $options;

    /**
     * @var bool
     */
    private $startFlag;

    /**
     * @var bool
     */
    private $endFlag;

    /**
     * @var bool
     */
    private $startJoker;

    /**
     * @var bool
     */
    private $endJoker;

    /**
     * @param string $expr
     *
     * @return Regex
     *
     * @throws \InvalidArgumentException
     */
    public static function create($expr)
    {
        if (preg_match('/^(.{3,}?)([imsxuADU]*)$/', $expr, $m)) {
            $start = substr($m[1], 0, 1);
            $end = substr($m[1], -1);

            if (
                ($start === $end && !preg_match('/[*?[:alnum:] \\\\]/', $start))
                || ($start === '{' && $end === '}')
                || ($start === '(' && $end === ')')
            ) {
                return new self(substr($m[1], 1, -1), $m[2], $end);
            }
        }

        throw new \InvalidArgumentException('Given expression is not a regex.');
    }

    /**
     * @param string $pattern
     * @param string $options
     * @param string $delimiter
     */
    public function __construct($pattern, $options = '', $delimiter = null)
    {
        if (null !== $delimiter) {
            // removes delimiter escaping
            $pattern = str_replace('\\'.$delimiter, $delimiter, $pattern);
        }

        $this->parsePattern($pattern);
        $this->options = $options;
    }

    /**
     * @return string
     */
    public function __toString()
    {
        return $this->render();
    }

    /**
     * {@inheritdoc}
     */
    public function render()
    {
        return self::BOUNDARY
            .$this->renderPattern()
            .self::BOUNDARY
            .$this->options;
    }

    /**
     * {@inheritdoc}
     */
    public function renderPattern()
    {
        return ($this->startFlag ? self::START_FLAG : '')
            .($this->startJoker ? self::JOKER : '')
            .str_replace(self::BOUNDARY, '\\'.self::BOUNDARY, $this->pattern)
            .($this->endJoker ? self::JOKER : '')
            .($this->endFlag ? self::END_FLAG : '');
    }

    /**
     * {@inheritdoc}
     */
    public function isCaseSensitive()
    {
        return !$this->hasOption('i');
    }

    /**
     * {@inheritdoc}
     */
    public function getType()
    {
        return Expression::TYPE_REGEX;
    }

    /**
     * {@inheritdoc}
     */
    public function prepend($expr)
    {
        $this->pattern = $expr.$this->pattern;

        return $this;
    }

    /**
     * {@inheritdoc}
     */
    public function append($expr)
    {
        $this->pattern .= $expr;

        return $this;
    }

    /**
     * @param string $option
     *
     * @return bool
     */
    public function hasOption($option)
    {
        return false !== strpos($this->options, $option);
    }

    /**
     * @param string $option
     *
     * @return Regex
     */
    public function addOption($option)
    {
        if (!$this->hasOption($option)) {
            $this->options .= $option;
        }

        return $this;
    }

    /**
     * @param string $option
     *
     * @return Regex
     */
    public function removeOption($option)
    {
        $this->options = str_replace($option, '', $this->options);

        return $this;
    }

    /**
     * @param bool $startFlag
     *
     * @return Regex
     */
    public function setStartFlag($startFlag)
    {
        $this->startFlag = $startFlag;

        return $this;
    }

    /**
     * @return bool
     */
    public function hasStartFlag()
    {
        return $this->startFlag;
    }

    /**
     * @param bool $endFlag
     *
     * @return Regex
     */
    public function setEndFlag($endFlag)
    {
        $this->endFlag = (bool) $endFlag;

        return $this;
    }

    /**
     * @return bool
     */
    public function hasEndFlag()
    {
        return $this->endFlag;
    }

    /**
     * @param bool $startJoker
     *
     * @return Regex
     */
    public function setStartJoker($startJoker)
    {
        $this->startJoker = $startJoker;

        return $this;
    }

    /**
     * @return bool
     */
    public function hasStartJoker()
    {
        return $this->startJoker;
    }

    /**
     * @param bool $endJoker
     *
     * @return Regex
     */
    public function setEndJoker($endJoker)
    {
        $this->endJoker = (bool) $endJoker;

        return $this;
    }

    /**
     * @return bool
     */
    public function hasEndJoker()
    {
        return $this->endJoker;
    }

    /**
     * @param array $replacement
     *
     * @return Regex
     */
    public function replaceJokers($replacement)
    {
        $replace = function ($subject) use ($replacement) {
            $subject = $subject[0];
            $replace = 0 === substr_count($subject, '\\') % 2;

            return $replace ? str_replace('.', $replacement, $subject) : $subject;
        };

        $this->pattern = preg_replace_callback('~[\\\\]*\\.~', $replace, $this->pattern);

        return $this;
    }

    /**
     * @param string $pattern
     */
    private function parsePattern($pattern)
    {
        if ($this->startFlag = self::START_FLAG === substr($pattern, 0, 1)) {
            $pattern = substr($pattern, 1);
        }

        if ($this->startJoker = self::JOKER === substr($pattern, 0, 2)) {
            $pattern = substr($pattern, 2);
        }

        if ($this->endFlag = (self::END_FLAG === substr($pattern, -1) && self::ESCAPING !== substr($pattern, -2, -1))) {
            $pattern = substr($pattern, 0, -1);
        }

        if ($this->endJoker = (self::JOKER === substr($pattern, -2) && self::ESCAPING !== substr($pattern, -3, -2))) {
            $pattern = substr($pattern, 0, -2);
        }

        $this->pattern = $pattern;
    }
}
PKϤ$Zv�V���$finder/Expression/ValueInterface.phpnu�[���<?php

/*
 * This file is part of the Symfony package.
 *
 * (c) Fabien Potencier <fabien@symfony.com>
 *
 * For the full copyright and license information, please view the LICENSE
 * file that was distributed with this source code.
 */

namespace Symfony\Component\Finder\Expression;

@trigger_error('The '.__NAMESPACE__.'\ValueInterface interface is deprecated since version 2.8 and will be removed in 3.0.', E_USER_DEPRECATED);

/**
 * @author Jean-François Simon <contact@jfsimon.fr>
 */
interface ValueInterface
{
    /**
     * Renders string representation of expression.
     *
     * @return string
     */
    public function render();

    /**
     * Renders string representation of pattern.
     *
     * @return string
     */
    public function renderPattern();

    /**
     * Returns value case sensitivity.
     *
     * @return bool
     */
    public function isCaseSensitive();

    /**
     * Returns expression type.
     *
     * @return int
     */
    public function getType();

    /**
     * @param string $expr
     *
     * @return ValueInterface
     */
    public function prepend($expr);

    /**
     * @param string $expr
     *
     * @return ValueInterface
     */
    public function append($expr);
}
PKϤ$Z^�bDDfinder/Expression/Glob.phpnu�[���<?php

/*
 * This file is part of the Symfony package.
 *
 * (c) Fabien Potencier <fabien@symfony.com>
 *
 * For the full copyright and license information, please view the LICENSE
 * file that was distributed with this source code.
 */

namespace Symfony\Component\Finder\Expression;

@trigger_error('The '.__NAMESPACE__.'\Glob class is deprecated since version 2.8 and will be removed in 3.0.', E_USER_DEPRECATED);

use Symfony\Component\Finder\Glob as FinderGlob;

/**
 * @author Jean-François Simon <contact@jfsimon.fr>
 */
class Glob implements ValueInterface
{
    /**
     * @var string
     */
    private $pattern;

    /**
     * @param string $pattern
     */
    public function __construct($pattern)
    {
        $this->pattern = $pattern;
    }

    /**
     * {@inheritdoc}
     */
    public function render()
    {
        return $this->pattern;
    }

    /**
     * {@inheritdoc}
     */
    public function renderPattern()
    {
        return $this->pattern;
    }

    /**
     * {@inheritdoc}
     */
    public function getType()
    {
        return Expression::TYPE_GLOB;
    }

    /**
     * {@inheritdoc}
     */
    public function isCaseSensitive()
    {
        return true;
    }

    /**
     * {@inheritdoc}
     */
    public function prepend($expr)
    {
        $this->pattern = $expr.$this->pattern;

        return $this;
    }

    /**
     * {@inheritdoc}
     */
    public function append($expr)
    {
        $this->pattern .= $expr;

        return $this;
    }

    /**
     * Tests if glob is expandable ("*.{a,b}" syntax).
     *
     * @return bool
     */
    public function isExpandable()
    {
        return false !== strpos($this->pattern, '{')
            && false !== strpos($this->pattern, '}');
    }

    /**
     * @param bool $strictLeadingDot
     * @param bool $strictWildcardSlash
     *
     * @return Regex
     */
    public function toRegex($strictLeadingDot = true, $strictWildcardSlash = true)
    {
        $regex = FinderGlob::toRegex($this->pattern, $strictLeadingDot, $strictWildcardSlash, '');

        return new Regex($regex);
    }
}
PKϤ$Z�\Aݯ
�
 finder/Expression/Expression.phpnu�[���<?php

/*
 * This file is part of the Symfony package.
 *
 * (c) Fabien Potencier <fabien@symfony.com>
 *
 * For the full copyright and license information, please view the LICENSE
 * file that was distributed with this source code.
 */

namespace Symfony\Component\Finder\Expression;

@trigger_error('The '.__NAMESPACE__.'\Expression class is deprecated since version 2.8 and will be removed in 3.0.', E_USER_DEPRECATED);

/**
 * @author Jean-François Simon <contact@jfsimon.fr>
 */
class Expression implements ValueInterface
{
    const TYPE_REGEX = 1;
    const TYPE_GLOB = 2;

    /**
     * @var ValueInterface
     */
    private $value;

    /**
     * @param string $expr
     *
     * @return Expression
     */
    public static function create($expr)
    {
        return new self($expr);
    }

    /**
     * @param string $expr
     */
    public function __construct($expr)
    {
        try {
            $this->value = Regex::create($expr);
        } catch (\InvalidArgumentException $e) {
            $this->value = new Glob($expr);
        }
    }

    /**
     * @return string
     */
    public function __toString()
    {
        return $this->render();
    }

    /**
     * {@inheritdoc}
     */
    public function render()
    {
        return $this->value->render();
    }

    /**
     * {@inheritdoc}
     */
    public function renderPattern()
    {
        return $this->value->renderPattern();
    }

    /**
     * @return bool
     */
    public function isCaseSensitive()
    {
        return $this->value->isCaseSensitive();
    }

    /**
     * @return int
     */
    public function getType()
    {
        return $this->value->getType();
    }

    /**
     * {@inheritdoc}
     */
    public function prepend($expr)
    {
        $this->value->prepend($expr);

        return $this;
    }

    /**
     * {@inheritdoc}
     */
    public function append($expr)
    {
        $this->value->append($expr);

        return $this;
    }

    /**
     * @return bool
     */
    public function isRegex()
    {
        return self::TYPE_REGEX === $this->value->getType();
    }

    /**
     * @return bool
     */
    public function isGlob()
    {
        return self::TYPE_GLOB === $this->value->getType();
    }

    /**
     * @return Glob
     *
     * @throws \LogicException
     */
    public function getGlob()
    {
        if (self::TYPE_GLOB !== $this->value->getType()) {
            throw new \LogicException('Regex can\'t be transformed to glob.');
        }

        return $this->value;
    }

    /**
     * @return Regex
     */
    public function getRegex()
    {
        return self::TYPE_REGEX === $this->value->getType() ? $this->value : $this->value->toRegex();
    }
}
PKϤ$Z�C��finder/README.mdnu�[���Finder Component
================

The Finder component finds files and directories via an intuitive fluent
interface.

Resources
---------

 * [Documentation](https://symfony.com/doc/current/components/finder.html)
 * [Contributing](https://symfony.com/doc/current/contributing/index.html)
 * [Report issues](https://github.com/symfony/symfony/issues) and
   [send Pull Requests](https://github.com/symfony/symfony/pulls)
   in the [main Symfony repository](https://github.com/symfony/symfony)
PKϤ$Z�b�finder/SplFileInfo.phpnu�[���<?php

/*
 * This file is part of the Symfony package.
 *
 * (c) Fabien Potencier <fabien@symfony.com>
 *
 * For the full copyright and license information, please view the LICENSE
 * file that was distributed with this source code.
 */

namespace Symfony\Component\Finder;

/**
 * Extends \SplFileInfo to support relative paths.
 *
 * @author Fabien Potencier <fabien@symfony.com>
 */
class SplFileInfo extends \SplFileInfo
{
    private $relativePath;
    private $relativePathname;

    /**
     * @param string $file             The file name
     * @param string $relativePath     The relative path
     * @param string $relativePathname The relative path name
     */
    public function __construct(string $file, string $relativePath, string $relativePathname)
    {
        parent::__construct($file);
        $this->relativePath = $relativePath;
        $this->relativePathname = $relativePathname;
    }

    /**
     * Returns the relative path.
     *
     * This path does not contain the file name.
     *
     * @return string the relative path
     */
    public function getRelativePath()
    {
        return $this->relativePath;
    }

    /**
     * Returns the relative path name.
     *
     * This path contains the file name.
     *
     * @return string the relative path name
     */
    public function getRelativePathname()
    {
        return $this->relativePathname;
    }

    public function getFilenameWithoutExtension(): string
    {
        $filename = $this->getFilename();

        return pathinfo($filename, \PATHINFO_FILENAME);
    }

    /**
     * Returns the contents of the file.
     *
     * @return string the contents of the file
     *
     * @throws \RuntimeException
     */
    public function getContents()
    {
        set_error_handler(function ($type, $msg) use (&$error) { $error = $msg; });
        $content = file_get_contents($this->getPathname());
        restore_error_handler();
        if (false === $content) {
            throw new \RuntimeException($error);
        }

        return $content;
    }
}
PKϤ$Z�RI��/finder/Exception/DirectoryNotFoundException.phpnu�[���<?php

/*
 * This file is part of the Symfony package.
 *
 * (c) Fabien Potencier <fabien@symfony.com>
 *
 * For the full copyright and license information, please view the LICENSE
 * file that was distributed with this source code.
 */

namespace Symfony\Component\Finder\Exception;

/**
 * @author Andreas Erhard <andreas.erhard@i-med.ac.at>
 */
class DirectoryNotFoundException extends \InvalidArgumentException
{
}
PKϤ$Z|^�KK,finder/Exception/AdapterFailureException.phpnu�[���<?php

/*
 * This file is part of the Symfony package.
 *
 * (c) Fabien Potencier <fabien@symfony.com>
 *
 * For the full copyright and license information, please view the LICENSE
 * file that was distributed with this source code.
 */

namespace Symfony\Component\Finder\Exception;

@trigger_error('The '.__NAMESPACE__.'\AdapterFailureException class is deprecated since version 2.8 and will be removed in 3.0.', E_USER_DEPRECATED);

use Symfony\Component\Finder\Adapter\AdapterInterface;

/**
 * Base exception for all adapter failures.
 *
 * @author Jean-François Simon <contact@jfsimon.fr>
 *
 * @deprecated since 2.8, to be removed in 3.0.
 */
class AdapterFailureException extends \RuntimeException implements ExceptionInterface
{
    /**
     * @var \Symfony\Component\Finder\Adapter\AdapterInterface
     */
    private $adapter;

    /**
     * @param AdapterInterface $adapter
     * @param string|null      $message
     * @param \Exception|null  $previous
     */
    public function __construct(AdapterInterface $adapter, $message = null, \Exception $previous = null)
    {
        $this->adapter = $adapter;
        parent::__construct($message ?: 'Search failed with "'.$adapter->getName().'" adapter.', $previous);
    }

    /**
     * {@inheritdoc}
     */
    public function getAdapter()
    {
        return $this->adapter;
    }
}
PKϤ$Z�7��'finder/Exception/ExceptionInterface.phpnu�[���<?php

/*
 * This file is part of the Symfony package.
 *
 * (c) Fabien Potencier <fabien@symfony.com>
 *
 * For the full copyright and license information, please view the LICENSE
 * file that was distributed with this source code.
 */

namespace Symfony\Component\Finder\Exception;

/**
 * @author Jean-François Simon <contact@jfsimon.fr>
 */
interface ExceptionInterface
{
    /**
     * @return \Symfony\Component\Finder\Adapter\AdapterInterface
     */
    public function getAdapter();
}
PKϤ$Zc
��rr2finder/Exception/OperationNotPermitedException.phpnu�[���<?php

/*
 * This file is part of the Symfony package.
 *
 * (c) Fabien Potencier <fabien@symfony.com>
 *
 * For the full copyright and license information, please view the LICENSE
 * file that was distributed with this source code.
 */

namespace Symfony\Component\Finder\Exception;

@trigger_error('The '.__NAMESPACE__.'\OperationNotPermitedException class is deprecated since version 2.8 and will be removed in 3.0.', E_USER_DEPRECATED);

/**
 * @author Jean-François Simon <contact@jfsimon.fr>
 *
 * @deprecated since 2.8, to be removed in 3.0.
 */
class OperationNotPermitedException extends AdapterFailureException
{
}
PKϤ$Z~�1finder/Exception/ShellCommandFailureException.phpnu�[���<?php

/*
 * This file is part of the Symfony package.
 *
 * (c) Fabien Potencier <fabien@symfony.com>
 *
 * For the full copyright and license information, please view the LICENSE
 * file that was distributed with this source code.
 */

namespace Symfony\Component\Finder\Exception;

@trigger_error('The '.__NAMESPACE__.'\ShellCommandFailureException class is deprecated since version 2.8 and will be removed in 3.0.', E_USER_DEPRECATED);

use Symfony\Component\Finder\Adapter\AdapterInterface;
use Symfony\Component\Finder\Shell\Command;

/**
 * @author Jean-François Simon <contact@jfsimon.fr>
 *
 * @deprecated since 2.8, to be removed in 3.0.
 */
class ShellCommandFailureException extends AdapterFailureException
{
    /**
     * @var Command
     */
    private $command;

    /**
     * @param AdapterInterface $adapter
     * @param Command          $command
     * @param \Exception|null  $previous
     */
    public function __construct(AdapterInterface $adapter, Command $command, \Exception $previous = null)
    {
        $this->command = $command;
        parent::__construct($adapter, 'Shell command failed: "'.$command->join().'".', $previous);
    }

    /**
     * @return Command
     */
    public function getCommand()
    {
        return $this->command;
    }
}
PKϤ$Z�cWޫ�*finder/Exception/AccessDeniedException.phpnu�[���<?php

/*
 * This file is part of the Symfony package.
 *
 * (c) Fabien Potencier <fabien@symfony.com>
 *
 * For the full copyright and license information, please view the LICENSE
 * file that was distributed with this source code.
 */

namespace Symfony\Component\Finder\Exception;

/**
 * @author Jean-François Simon <jeanfrancois.simon@sensiolabs.com>
 */
class AccessDeniedException extends \UnexpectedValueException
{
}
PKϤ$Z�s1ɩ�finder/CHANGELOG.mdnu�[���CHANGELOG
=========

5.0.0
-----

 * added `$useNaturalSort` argument to `Finder::sortByName()`

4.3.0
-----

 * added Finder::ignoreVCSIgnored() to ignore files based on rules listed in .gitignore

4.2.0
-----

 * added $useNaturalSort option to Finder::sortByName() method
 * the `Finder::sortByName()` method will have a new `$useNaturalSort`
   argument in version 5.0, not defining it is deprecated
 * added `Finder::reverseSorting()` to reverse the sorting

4.0.0
-----

 * removed `ExceptionInterface`
 * removed `Symfony\Component\Finder\Iterator\FilterIterator`

3.4.0
-----

 * deprecated `Symfony\Component\Finder\Iterator\FilterIterator`
 * added Finder::hasResults() method to check if any results were found

3.3.0
-----

 * added double-star matching to Glob::toRegex()

3.0.0
-----

 * removed deprecated classes

2.8.0
-----

 * deprecated adapters and related classes

2.5.0
-----
 * added support for GLOB_BRACE in the paths passed to Finder::in()

2.3.0
-----

 * added a way to ignore unreadable directories (via Finder::ignoreUnreadableDirs())
 * unified the way subfolders that are not executable are handled by always throwing an AccessDeniedException exception

2.2.0
-----

 * added Finder::path() and Finder::notPath() methods
 * added finder adapters to improve performance on specific platforms
 * added support for wildcard characters (glob patterns) in the paths passed
   to Finder::in()

2.1.0
-----

 * added Finder::sortByAccessedTime(), Finder::sortByChangedTime(), and
   Finder::sortByModifiedTime()
 * added Countable to Finder
 * added support for an array of directories as an argument to
   Finder::exclude()
 * added searching based on the file content via Finder::contains() and
   Finder::notContains()
 * added support for the != operator in the Comparator
 * [BC BREAK] filter expressions (used for file name and content) are no more
   considered as regexps but glob patterns when they are enclosed in '*' or '?'
PKϤ$Z�t��$$finder/Glob.phpnu�[���<?php

/*
 * This file is part of the Symfony package.
 *
 * (c) Fabien Potencier <fabien@symfony.com>
 *
 * For the full copyright and license information, please view the LICENSE
 * file that was distributed with this source code.
 */

namespace Symfony\Component\Finder;

/**
 * Glob matches globbing patterns against text.
 *
 *     if match_glob("foo.*", "foo.bar") echo "matched\n";
 *
 *     // prints foo.bar and foo.baz
 *     $regex = glob_to_regex("foo.*");
 *     for (['foo.bar', 'foo.baz', 'foo', 'bar'] as $t)
 *     {
 *         if (/$regex/) echo "matched: $car\n";
 *     }
 *
 * Glob implements glob(3) style matching that can be used to match
 * against text, rather than fetching names from a filesystem.
 *
 * Based on the Perl Text::Glob module.
 *
 * @author Fabien Potencier <fabien@symfony.com> PHP port
 * @author     Richard Clamp <richardc@unixbeard.net> Perl version
 * @copyright  2004-2005 Fabien Potencier <fabien@symfony.com>
 * @copyright  2002 Richard Clamp <richardc@unixbeard.net>
 */
class Glob
{
    /**
     * Returns a regexp which is the equivalent of the glob pattern.
     *
     * @return string
     */
    public static function toRegex(string $glob, bool $strictLeadingDot = true, bool $strictWildcardSlash = true, string $delimiter = '#')
    {
        $firstByte = true;
        $escaping = false;
        $inCurlies = 0;
        $regex = '';
        $sizeGlob = \strlen($glob);
        for ($i = 0; $i < $sizeGlob; ++$i) {
            $car = $glob[$i];
            if ($firstByte && $strictLeadingDot && '.' !== $car) {
                $regex .= '(?=[^\.])';
            }

            $firstByte = '/' === $car;

            if ($firstByte && $strictWildcardSlash && isset($glob[$i + 2]) && '**' === $glob[$i + 1].$glob[$i + 2] && (!isset($glob[$i + 3]) || '/' === $glob[$i + 3])) {
                $car = '[^/]++/';
                if (!isset($glob[$i + 3])) {
                    $car .= '?';
                }

                if ($strictLeadingDot) {
                    $car = '(?=[^\.])'.$car;
                }

                $car = '/(?:'.$car.')*';
                $i += 2 + isset($glob[$i + 3]);

                if ('/' === $delimiter) {
                    $car = str_replace('/', '\\/', $car);
                }
            }

            if ($delimiter === $car || '.' === $car || '(' === $car || ')' === $car || '|' === $car || '+' === $car || '^' === $car || '$' === $car) {
                $regex .= "\\$car";
            } elseif ('*' === $car) {
                $regex .= $escaping ? '\\*' : ($strictWildcardSlash ? '[^/]*' : '.*');
            } elseif ('?' === $car) {
                $regex .= $escaping ? '\\?' : ($strictWildcardSlash ? '[^/]' : '.');
            } elseif ('{' === $car) {
                $regex .= $escaping ? '\\{' : '(';
                if (!$escaping) {
                    ++$inCurlies;
                }
            } elseif ('}' === $car && $inCurlies) {
                $regex .= $escaping ? '}' : ')';
                if (!$escaping) {
                    --$inCurlies;
                }
            } elseif (',' === $car && $inCurlies) {
                $regex .= $escaping ? ',' : '|';
            } elseif ('\\' === $car) {
                if ($escaping) {
                    $regex .= '\\\\';
                    $escaping = false;
                } else {
                    $escaping = true;
                }

                continue;
            } else {
                $regex .= $car;
            }
            $escaping = false;
        }

        return $delimiter.'^'.$regex.'$'.$delimiter;
    }
}
PKϤ$Z�
��))finder/LICENSEnu�[���Copyright (c) 2004-2021 Fabien Potencier

Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is furnished
to do so, subject to the following conditions:

The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.

THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
THE SOFTWARE.
PKϤ$Z��SHttpolyfill-mbstring/README.mdnu�[���Symfony Polyfill / Mbstring
===========================

This component provides a partial, native PHP implementation for the
[Mbstring](https://php.net/mbstring) extension.

More information can be found in the
[main Polyfill README](https://github.com/symfony/polyfill/blob/master/README.md).

License
=======

This library is released under the [MIT license](LICENSE).
PKϤ$ZZ����_�_1polyfill-mbstring/Resources/unidata/lowerCase.phpnu�[���<?php

return array (
  'A' => 'a',
  'B' => 'b',
  'C' => 'c',
  'D' => 'd',
  'E' => 'e',
  'F' => 'f',
  'G' => 'g',
  'H' => 'h',
  'I' => 'i',
  'J' => 'j',
  'K' => 'k',
  'L' => 'l',
  'M' => 'm',
  'N' => 'n',
  'O' => 'o',
  'P' => 'p',
  'Q' => 'q',
  'R' => 'r',
  'S' => 's',
  'T' => 't',
  'U' => 'u',
  'V' => 'v',
  'W' => 'w',
  'X' => 'x',
  'Y' => 'y',
  'Z' => 'z',
  'À' => 'à',
  'Á' => 'á',
  'Â' => 'â',
  'Ã' => 'ã',
  'Ä' => 'ä',
  'Å' => 'å',
  'Æ' => 'æ',
  'Ç' => 'ç',
  'È' => 'è',
  'É' => 'é',
  'Ê' => 'ê',
  'Ë' => 'ë',
  'Ì' => 'ì',
  'Í' => 'í',
  'Î' => 'î',
  'Ï' => 'ï',
  'Ð' => 'ð',
  'Ñ' => 'ñ',
  'Ò' => 'ò',
  'Ó' => 'ó',
  'Ô' => 'ô',
  'Õ' => 'õ',
  'Ö' => 'ö',
  'Ø' => 'ø',
  'Ù' => 'ù',
  'Ú' => 'ú',
  'Û' => 'û',
  'Ü' => 'ü',
  'Ý' => 'ý',
  'Þ' => 'þ',
  'Ā' => 'ā',
  'Ă' => 'ă',
  'Ą' => 'ą',
  'Ć' => 'ć',
  'Ĉ' => 'ĉ',
  'Ċ' => 'ċ',
  'Č' => 'č',
  'Ď' => 'ď',
  'Đ' => 'đ',
  'Ē' => 'ē',
  'Ĕ' => 'ĕ',
  'Ė' => 'ė',
  'Ę' => 'ę',
  'Ě' => 'ě',
  'Ĝ' => 'ĝ',
  'Ğ' => 'ğ',
  'Ġ' => 'ġ',
  'Ģ' => 'ģ',
  'Ĥ' => 'ĥ',
  'Ħ' => 'ħ',
  'Ĩ' => 'ĩ',
  'Ī' => 'ī',
  'Ĭ' => 'ĭ',
  'Į' => 'į',
  'İ' => 'i',
  'IJ' => 'ij',
  'Ĵ' => 'ĵ',
  'Ķ' => 'ķ',
  'Ĺ' => 'ĺ',
  'Ļ' => 'ļ',
  'Ľ' => 'ľ',
  'Ŀ' => 'ŀ',
  'Ł' => 'ł',
  'Ń' => 'ń',
  'Ņ' => 'ņ',
  'Ň' => 'ň',
  'Ŋ' => 'ŋ',
  'Ō' => 'ō',
  'Ŏ' => 'ŏ',
  'Ő' => 'ő',
  'Œ' => 'œ',
  'Ŕ' => 'ŕ',
  'Ŗ' => 'ŗ',
  'Ř' => 'ř',
  'Ś' => 'ś',
  'Ŝ' => 'ŝ',
  'Ş' => 'ş',
  'Š' => 'š',
  'Ţ' => 'ţ',
  'Ť' => 'ť',
  'Ŧ' => 'ŧ',
  'Ũ' => 'ũ',
  'Ū' => 'ū',
  'Ŭ' => 'ŭ',
  'Ů' => 'ů',
  'Ű' => 'ű',
  'Ų' => 'ų',
  'Ŵ' => 'ŵ',
  'Ŷ' => 'ŷ',
  'Ÿ' => 'ÿ',
  'Ź' => 'ź',
  'Ż' => 'ż',
  'Ž' => 'ž',
  'Ɓ' => 'ɓ',
  'Ƃ' => 'ƃ',
  'Ƅ' => 'ƅ',
  'Ɔ' => 'ɔ',
  'Ƈ' => 'ƈ',
  'Ɖ' => 'ɖ',
  'Ɗ' => 'ɗ',
  'Ƌ' => 'ƌ',
  'Ǝ' => 'ǝ',
  'Ə' => 'ə',
  'Ɛ' => 'ɛ',
  'Ƒ' => 'ƒ',
  'Ɠ' => 'ɠ',
  'Ɣ' => 'ɣ',
  'Ɩ' => 'ɩ',
  'Ɨ' => 'ɨ',
  'Ƙ' => 'ƙ',
  'Ɯ' => 'ɯ',
  'Ɲ' => 'ɲ',
  'Ɵ' => 'ɵ',
  'Ơ' => 'ơ',
  'Ƣ' => 'ƣ',
  'Ƥ' => 'ƥ',
  'Ʀ' => 'ʀ',
  'Ƨ' => 'ƨ',
  'Ʃ' => 'ʃ',
  'Ƭ' => 'ƭ',
  'Ʈ' => 'ʈ',
  'Ư' => 'ư',
  'Ʊ' => 'ʊ',
  'Ʋ' => 'ʋ',
  'Ƴ' => 'ƴ',
  'Ƶ' => 'ƶ',
  'Ʒ' => 'ʒ',
  'Ƹ' => 'ƹ',
  'Ƽ' => 'ƽ',
  'DŽ' => 'dž',
  'Dž' => 'dž',
  'LJ' => 'lj',
  'Lj' => 'lj',
  'NJ' => 'nj',
  'Nj' => 'nj',
  'Ǎ' => 'ǎ',
  'Ǐ' => 'ǐ',
  'Ǒ' => 'ǒ',
  'Ǔ' => 'ǔ',
  'Ǖ' => 'ǖ',
  'Ǘ' => 'ǘ',
  'Ǚ' => 'ǚ',
  'Ǜ' => 'ǜ',
  'Ǟ' => 'ǟ',
  'Ǡ' => 'ǡ',
  'Ǣ' => 'ǣ',
  'Ǥ' => 'ǥ',
  'Ǧ' => 'ǧ',
  'Ǩ' => 'ǩ',
  'Ǫ' => 'ǫ',
  'Ǭ' => 'ǭ',
  'Ǯ' => 'ǯ',
  'DZ' => 'dz',
  'Dz' => 'dz',
  'Ǵ' => 'ǵ',
  'Ƕ' => 'ƕ',
  'Ƿ' => 'ƿ',
  'Ǹ' => 'ǹ',
  'Ǻ' => 'ǻ',
  'Ǽ' => 'ǽ',
  'Ǿ' => 'ǿ',
  'Ȁ' => 'ȁ',
  'Ȃ' => 'ȃ',
  'Ȅ' => 'ȅ',
  'Ȇ' => 'ȇ',
  'Ȉ' => 'ȉ',
  'Ȋ' => 'ȋ',
  'Ȍ' => 'ȍ',
  'Ȏ' => 'ȏ',
  'Ȑ' => 'ȑ',
  'Ȓ' => 'ȓ',
  'Ȕ' => 'ȕ',
  'Ȗ' => 'ȗ',
  'Ș' => 'ș',
  'Ț' => 'ț',
  'Ȝ' => 'ȝ',
  'Ȟ' => 'ȟ',
  'Ƞ' => 'ƞ',
  'Ȣ' => 'ȣ',
  'Ȥ' => 'ȥ',
  'Ȧ' => 'ȧ',
  'Ȩ' => 'ȩ',
  'Ȫ' => 'ȫ',
  'Ȭ' => 'ȭ',
  'Ȯ' => 'ȯ',
  'Ȱ' => 'ȱ',
  'Ȳ' => 'ȳ',
  'Ⱥ' => 'ⱥ',
  'Ȼ' => 'ȼ',
  'Ƚ' => 'ƚ',
  'Ⱦ' => 'ⱦ',
  'Ɂ' => 'ɂ',
  'Ƀ' => 'ƀ',
  'Ʉ' => 'ʉ',
  'Ʌ' => 'ʌ',
  'Ɇ' => 'ɇ',
  'Ɉ' => 'ɉ',
  'Ɋ' => 'ɋ',
  'Ɍ' => 'ɍ',
  'Ɏ' => 'ɏ',
  'Ͱ' => 'ͱ',
  'Ͳ' => 'ͳ',
  'Ͷ' => 'ͷ',
  'Ϳ' => 'ϳ',
  'Ά' => 'ά',
  'Έ' => 'έ',
  'Ή' => 'ή',
  'Ί' => 'ί',
  'Ό' => 'ό',
  'Ύ' => 'ύ',
  'Ώ' => 'ώ',
  'Α' => 'α',
  'Β' => 'β',
  'Γ' => 'γ',
  'Δ' => 'δ',
  'Ε' => 'ε',
  'Ζ' => 'ζ',
  'Η' => 'η',
  'Θ' => 'θ',
  'Ι' => 'ι',
  'Κ' => 'κ',
  'Λ' => 'λ',
  'Μ' => 'μ',
  'Ν' => 'ν',
  'Ξ' => 'ξ',
  'Ο' => 'ο',
  'Π' => 'π',
  'Ρ' => 'ρ',
  'Σ' => 'σ',
  'Τ' => 'τ',
  'Υ' => 'υ',
  'Φ' => 'φ',
  'Χ' => 'χ',
  'Ψ' => 'ψ',
  'Ω' => 'ω',
  'Ϊ' => 'ϊ',
  'Ϋ' => 'ϋ',
  'Ϗ' => 'ϗ',
  'Ϙ' => 'ϙ',
  'Ϛ' => 'ϛ',
  'Ϝ' => 'ϝ',
  'Ϟ' => 'ϟ',
  'Ϡ' => 'ϡ',
  'Ϣ' => 'ϣ',
  'Ϥ' => 'ϥ',
  'Ϧ' => 'ϧ',
  'Ϩ' => 'ϩ',
  'Ϫ' => 'ϫ',
  'Ϭ' => 'ϭ',
  'Ϯ' => 'ϯ',
  'ϴ' => 'θ',
  'Ϸ' => 'ϸ',
  'Ϲ' => 'ϲ',
  'Ϻ' => 'ϻ',
  'Ͻ' => 'ͻ',
  'Ͼ' => 'ͼ',
  'Ͽ' => 'ͽ',
  'Ѐ' => 'ѐ',
  'Ё' => 'ё',
  'Ђ' => 'ђ',
  'Ѓ' => 'ѓ',
  'Є' => 'є',
  'Ѕ' => 'ѕ',
  'І' => 'і',
  'Ї' => 'ї',
  'Ј' => 'ј',
  'Љ' => 'љ',
  'Њ' => 'њ',
  'Ћ' => 'ћ',
  'Ќ' => 'ќ',
  'Ѝ' => 'ѝ',
  'Ў' => 'ў',
  'Џ' => 'џ',
  'А' => 'а',
  'Б' => 'б',
  'В' => 'в',
  'Г' => 'г',
  'Д' => 'д',
  'Е' => 'е',
  'Ж' => 'ж',
  'З' => 'з',
  'И' => 'и',
  'Й' => 'й',
  'К' => 'к',
  'Л' => 'л',
  'М' => 'м',
  'Н' => 'н',
  'О' => 'о',
  'П' => 'п',
  'Р' => 'р',
  'С' => 'с',
  'Т' => 'т',
  'У' => 'у',
  'Ф' => 'ф',
  'Х' => 'х',
  'Ц' => 'ц',
  'Ч' => 'ч',
  'Ш' => 'ш',
  'Щ' => 'щ',
  'Ъ' => 'ъ',
  'Ы' => 'ы',
  'Ь' => 'ь',
  'Э' => 'э',
  'Ю' => 'ю',
  'Я' => 'я',
  'Ѡ' => 'ѡ',
  'Ѣ' => 'ѣ',
  'Ѥ' => 'ѥ',
  'Ѧ' => 'ѧ',
  'Ѩ' => 'ѩ',
  'Ѫ' => 'ѫ',
  'Ѭ' => 'ѭ',
  'Ѯ' => 'ѯ',
  'Ѱ' => 'ѱ',
  'Ѳ' => 'ѳ',
  'Ѵ' => 'ѵ',
  'Ѷ' => 'ѷ',
  'Ѹ' => 'ѹ',
  'Ѻ' => 'ѻ',
  'Ѽ' => 'ѽ',
  'Ѿ' => 'ѿ',
  'Ҁ' => 'ҁ',
  'Ҋ' => 'ҋ',
  'Ҍ' => 'ҍ',
  'Ҏ' => 'ҏ',
  'Ґ' => 'ґ',
  'Ғ' => 'ғ',
  'Ҕ' => 'ҕ',
  'Җ' => 'җ',
  'Ҙ' => 'ҙ',
  'Қ' => 'қ',
  'Ҝ' => 'ҝ',
  'Ҟ' => 'ҟ',
  'Ҡ' => 'ҡ',
  'Ң' => 'ң',
  'Ҥ' => 'ҥ',
  'Ҧ' => 'ҧ',
  'Ҩ' => 'ҩ',
  'Ҫ' => 'ҫ',
  'Ҭ' => 'ҭ',
  'Ү' => 'ү',
  'Ұ' => 'ұ',
  'Ҳ' => 'ҳ',
  'Ҵ' => 'ҵ',
  'Ҷ' => 'ҷ',
  'Ҹ' => 'ҹ',
  'Һ' => 'һ',
  'Ҽ' => 'ҽ',
  'Ҿ' => 'ҿ',
  'Ӏ' => 'ӏ',
  'Ӂ' => 'ӂ',
  'Ӄ' => 'ӄ',
  'Ӆ' => 'ӆ',
  'Ӈ' => 'ӈ',
  'Ӊ' => 'ӊ',
  'Ӌ' => 'ӌ',
  'Ӎ' => 'ӎ',
  'Ӑ' => 'ӑ',
  'Ӓ' => 'ӓ',
  'Ӕ' => 'ӕ',
  'Ӗ' => 'ӗ',
  'Ә' => 'ә',
  'Ӛ' => 'ӛ',
  'Ӝ' => 'ӝ',
  'Ӟ' => 'ӟ',
  'Ӡ' => 'ӡ',
  'Ӣ' => 'ӣ',
  'Ӥ' => 'ӥ',
  'Ӧ' => 'ӧ',
  'Ө' => 'ө',
  'Ӫ' => 'ӫ',
  'Ӭ' => 'ӭ',
  'Ӯ' => 'ӯ',
  'Ӱ' => 'ӱ',
  'Ӳ' => 'ӳ',
  'Ӵ' => 'ӵ',
  'Ӷ' => 'ӷ',
  'Ӹ' => 'ӹ',
  'Ӻ' => 'ӻ',
  'Ӽ' => 'ӽ',
  'Ӿ' => 'ӿ',
  'Ԁ' => 'ԁ',
  'Ԃ' => 'ԃ',
  'Ԅ' => 'ԅ',
  'Ԇ' => 'ԇ',
  'Ԉ' => 'ԉ',
  'Ԋ' => 'ԋ',
  'Ԍ' => 'ԍ',
  'Ԏ' => 'ԏ',
  'Ԑ' => 'ԑ',
  'Ԓ' => 'ԓ',
  'Ԕ' => 'ԕ',
  'Ԗ' => 'ԗ',
  'Ԙ' => 'ԙ',
  'Ԛ' => 'ԛ',
  'Ԝ' => 'ԝ',
  'Ԟ' => 'ԟ',
  'Ԡ' => 'ԡ',
  'Ԣ' => 'ԣ',
  'Ԥ' => 'ԥ',
  'Ԧ' => 'ԧ',
  'Ԩ' => 'ԩ',
  'Ԫ' => 'ԫ',
  'Ԭ' => 'ԭ',
  'Ԯ' => 'ԯ',
  'Ա' => 'ա',
  'Բ' => 'բ',
  'Գ' => 'գ',
  'Դ' => 'դ',
  'Ե' => 'ե',
  'Զ' => 'զ',
  'Է' => 'է',
  'Ը' => 'ը',
  'Թ' => 'թ',
  'Ժ' => 'ժ',
  'Ի' => 'ի',
  'Լ' => 'լ',
  'Խ' => 'խ',
  'Ծ' => 'ծ',
  'Կ' => 'կ',
  'Հ' => 'հ',
  'Ձ' => 'ձ',
  'Ղ' => 'ղ',
  'Ճ' => 'ճ',
  'Մ' => 'մ',
  'Յ' => 'յ',
  'Ն' => 'ն',
  'Շ' => 'շ',
  'Ո' => 'ո',
  'Չ' => 'չ',
  'Պ' => 'պ',
  'Ջ' => 'ջ',
  'Ռ' => 'ռ',
  'Ս' => 'ս',
  'Վ' => 'վ',
  'Տ' => 'տ',
  'Ր' => 'ր',
  'Ց' => 'ց',
  'Ւ' => 'ւ',
  'Փ' => 'փ',
  'Ք' => 'ք',
  'Օ' => 'օ',
  'Ֆ' => 'ֆ',
  'Ⴀ' => 'ⴀ',
  'Ⴁ' => 'ⴁ',
  'Ⴂ' => 'ⴂ',
  'Ⴃ' => 'ⴃ',
  'Ⴄ' => 'ⴄ',
  'Ⴅ' => 'ⴅ',
  'Ⴆ' => 'ⴆ',
  'Ⴇ' => 'ⴇ',
  'Ⴈ' => 'ⴈ',
  'Ⴉ' => 'ⴉ',
  'Ⴊ' => 'ⴊ',
  'Ⴋ' => 'ⴋ',
  'Ⴌ' => 'ⴌ',
  'Ⴍ' => 'ⴍ',
  'Ⴎ' => 'ⴎ',
  'Ⴏ' => 'ⴏ',
  'Ⴐ' => 'ⴐ',
  'Ⴑ' => 'ⴑ',
  'Ⴒ' => 'ⴒ',
  'Ⴓ' => 'ⴓ',
  'Ⴔ' => 'ⴔ',
  'Ⴕ' => 'ⴕ',
  'Ⴖ' => 'ⴖ',
  'Ⴗ' => 'ⴗ',
  'Ⴘ' => 'ⴘ',
  'Ⴙ' => 'ⴙ',
  'Ⴚ' => 'ⴚ',
  'Ⴛ' => 'ⴛ',
  'Ⴜ' => 'ⴜ',
  'Ⴝ' => 'ⴝ',
  'Ⴞ' => 'ⴞ',
  'Ⴟ' => 'ⴟ',
  'Ⴠ' => 'ⴠ',
  'Ⴡ' => 'ⴡ',
  'Ⴢ' => 'ⴢ',
  'Ⴣ' => 'ⴣ',
  'Ⴤ' => 'ⴤ',
  'Ⴥ' => 'ⴥ',
  'Ⴧ' => 'ⴧ',
  'Ⴭ' => 'ⴭ',
  'Ꭰ' => 'ꭰ',
  'Ꭱ' => 'ꭱ',
  'Ꭲ' => 'ꭲ',
  'Ꭳ' => 'ꭳ',
  'Ꭴ' => 'ꭴ',
  'Ꭵ' => 'ꭵ',
  'Ꭶ' => 'ꭶ',
  'Ꭷ' => 'ꭷ',
  'Ꭸ' => 'ꭸ',
  'Ꭹ' => 'ꭹ',
  'Ꭺ' => 'ꭺ',
  'Ꭻ' => 'ꭻ',
  'Ꭼ' => 'ꭼ',
  'Ꭽ' => 'ꭽ',
  'Ꭾ' => 'ꭾ',
  'Ꭿ' => 'ꭿ',
  'Ꮀ' => 'ꮀ',
  'Ꮁ' => 'ꮁ',
  'Ꮂ' => 'ꮂ',
  'Ꮃ' => 'ꮃ',
  'Ꮄ' => 'ꮄ',
  'Ꮅ' => 'ꮅ',
  'Ꮆ' => 'ꮆ',
  'Ꮇ' => 'ꮇ',
  'Ꮈ' => 'ꮈ',
  'Ꮉ' => 'ꮉ',
  'Ꮊ' => 'ꮊ',
  'Ꮋ' => 'ꮋ',
  'Ꮌ' => 'ꮌ',
  'Ꮍ' => 'ꮍ',
  'Ꮎ' => 'ꮎ',
  'Ꮏ' => 'ꮏ',
  'Ꮐ' => 'ꮐ',
  'Ꮑ' => 'ꮑ',
  'Ꮒ' => 'ꮒ',
  'Ꮓ' => 'ꮓ',
  'Ꮔ' => 'ꮔ',
  'Ꮕ' => 'ꮕ',
  'Ꮖ' => 'ꮖ',
  'Ꮗ' => 'ꮗ',
  'Ꮘ' => 'ꮘ',
  'Ꮙ' => 'ꮙ',
  'Ꮚ' => 'ꮚ',
  'Ꮛ' => 'ꮛ',
  'Ꮜ' => 'ꮜ',
  'Ꮝ' => 'ꮝ',
  'Ꮞ' => 'ꮞ',
  'Ꮟ' => 'ꮟ',
  'Ꮠ' => 'ꮠ',
  'Ꮡ' => 'ꮡ',
  'Ꮢ' => 'ꮢ',
  'Ꮣ' => 'ꮣ',
  'Ꮤ' => 'ꮤ',
  'Ꮥ' => 'ꮥ',
  'Ꮦ' => 'ꮦ',
  'Ꮧ' => 'ꮧ',
  'Ꮨ' => 'ꮨ',
  'Ꮩ' => 'ꮩ',
  'Ꮪ' => 'ꮪ',
  'Ꮫ' => 'ꮫ',
  'Ꮬ' => 'ꮬ',
  'Ꮭ' => 'ꮭ',
  'Ꮮ' => 'ꮮ',
  'Ꮯ' => 'ꮯ',
  'Ꮰ' => 'ꮰ',
  'Ꮱ' => 'ꮱ',
  'Ꮲ' => 'ꮲ',
  'Ꮳ' => 'ꮳ',
  'Ꮴ' => 'ꮴ',
  'Ꮵ' => 'ꮵ',
  'Ꮶ' => 'ꮶ',
  'Ꮷ' => 'ꮷ',
  'Ꮸ' => 'ꮸ',
  'Ꮹ' => 'ꮹ',
  'Ꮺ' => 'ꮺ',
  'Ꮻ' => 'ꮻ',
  'Ꮼ' => 'ꮼ',
  'Ꮽ' => 'ꮽ',
  'Ꮾ' => 'ꮾ',
  'Ꮿ' => 'ꮿ',
  'Ᏸ' => 'ᏸ',
  'Ᏹ' => 'ᏹ',
  'Ᏺ' => 'ᏺ',
  'Ᏻ' => 'ᏻ',
  'Ᏼ' => 'ᏼ',
  'Ᏽ' => 'ᏽ',
  'Ა' => 'ა',
  'Ბ' => 'ბ',
  'Გ' => 'გ',
  'Დ' => 'დ',
  'Ე' => 'ე',
  'Ვ' => 'ვ',
  'Ზ' => 'ზ',
  'Თ' => 'თ',
  'Ი' => 'ი',
  'Კ' => 'კ',
  'Ლ' => 'ლ',
  'Მ' => 'მ',
  'Ნ' => 'ნ',
  'Ო' => 'ო',
  'Პ' => 'პ',
  'Ჟ' => 'ჟ',
  'Რ' => 'რ',
  'Ს' => 'ს',
  'Ტ' => 'ტ',
  'Უ' => 'უ',
  'Ფ' => 'ფ',
  'Ქ' => 'ქ',
  'Ღ' => 'ღ',
  'Ყ' => 'ყ',
  'Შ' => 'შ',
  'Ჩ' => 'ჩ',
  'Ც' => 'ც',
  'Ძ' => 'ძ',
  'Წ' => 'წ',
  'Ჭ' => 'ჭ',
  'Ხ' => 'ხ',
  'Ჯ' => 'ჯ',
  'Ჰ' => 'ჰ',
  'Ჱ' => 'ჱ',
  'Ჲ' => 'ჲ',
  'Ჳ' => 'ჳ',
  'Ჴ' => 'ჴ',
  'Ჵ' => 'ჵ',
  'Ჶ' => 'ჶ',
  'Ჷ' => 'ჷ',
  'Ჸ' => 'ჸ',
  'Ჹ' => 'ჹ',
  'Ჺ' => 'ჺ',
  'Ჽ' => 'ჽ',
  'Ჾ' => 'ჾ',
  'Ჿ' => 'ჿ',
  'Ḁ' => 'ḁ',
  'Ḃ' => 'ḃ',
  'Ḅ' => 'ḅ',
  'Ḇ' => 'ḇ',
  'Ḉ' => 'ḉ',
  'Ḋ' => 'ḋ',
  'Ḍ' => 'ḍ',
  'Ḏ' => 'ḏ',
  'Ḑ' => 'ḑ',
  'Ḓ' => 'ḓ',
  'Ḕ' => 'ḕ',
  'Ḗ' => 'ḗ',
  'Ḙ' => 'ḙ',
  'Ḛ' => 'ḛ',
  'Ḝ' => 'ḝ',
  'Ḟ' => 'ḟ',
  'Ḡ' => 'ḡ',
  'Ḣ' => 'ḣ',
  'Ḥ' => 'ḥ',
  'Ḧ' => 'ḧ',
  'Ḩ' => 'ḩ',
  'Ḫ' => 'ḫ',
  'Ḭ' => 'ḭ',
  'Ḯ' => 'ḯ',
  'Ḱ' => 'ḱ',
  'Ḳ' => 'ḳ',
  'Ḵ' => 'ḵ',
  'Ḷ' => 'ḷ',
  'Ḹ' => 'ḹ',
  'Ḻ' => 'ḻ',
  'Ḽ' => 'ḽ',
  'Ḿ' => 'ḿ',
  'Ṁ' => 'ṁ',
  'Ṃ' => 'ṃ',
  'Ṅ' => 'ṅ',
  'Ṇ' => 'ṇ',
  'Ṉ' => 'ṉ',
  'Ṋ' => 'ṋ',
  'Ṍ' => 'ṍ',
  'Ṏ' => 'ṏ',
  'Ṑ' => 'ṑ',
  'Ṓ' => 'ṓ',
  'Ṕ' => 'ṕ',
  'Ṗ' => 'ṗ',
  'Ṙ' => 'ṙ',
  'Ṛ' => 'ṛ',
  'Ṝ' => 'ṝ',
  'Ṟ' => 'ṟ',
  'Ṡ' => 'ṡ',
  'Ṣ' => 'ṣ',
  'Ṥ' => 'ṥ',
  'Ṧ' => 'ṧ',
  'Ṩ' => 'ṩ',
  'Ṫ' => 'ṫ',
  'Ṭ' => 'ṭ',
  'Ṯ' => 'ṯ',
  'Ṱ' => 'ṱ',
  'Ṳ' => 'ṳ',
  'Ṵ' => 'ṵ',
  'Ṷ' => 'ṷ',
  'Ṹ' => 'ṹ',
  'Ṻ' => 'ṻ',
  'Ṽ' => 'ṽ',
  'Ṿ' => 'ṿ',
  'Ẁ' => 'ẁ',
  'Ẃ' => 'ẃ',
  'Ẅ' => 'ẅ',
  'Ẇ' => 'ẇ',
  'Ẉ' => 'ẉ',
  'Ẋ' => 'ẋ',
  'Ẍ' => 'ẍ',
  'Ẏ' => 'ẏ',
  'Ẑ' => 'ẑ',
  'Ẓ' => 'ẓ',
  'Ẕ' => 'ẕ',
  'ẞ' => 'ß',
  'Ạ' => 'ạ',
  'Ả' => 'ả',
  'Ấ' => 'ấ',
  'Ầ' => 'ầ',
  'Ẩ' => 'ẩ',
  'Ẫ' => 'ẫ',
  'Ậ' => 'ậ',
  'Ắ' => 'ắ',
  'Ằ' => 'ằ',
  'Ẳ' => 'ẳ',
  'Ẵ' => 'ẵ',
  'Ặ' => 'ặ',
  'Ẹ' => 'ẹ',
  'Ẻ' => 'ẻ',
  'Ẽ' => 'ẽ',
  'Ế' => 'ế',
  'Ề' => 'ề',
  'Ể' => 'ể',
  'Ễ' => 'ễ',
  'Ệ' => 'ệ',
  'Ỉ' => 'ỉ',
  'Ị' => 'ị',
  'Ọ' => 'ọ',
  'Ỏ' => 'ỏ',
  'Ố' => 'ố',
  'Ồ' => 'ồ',
  'Ổ' => 'ổ',
  'Ỗ' => 'ỗ',
  'Ộ' => 'ộ',
  'Ớ' => 'ớ',
  'Ờ' => 'ờ',
  'Ở' => 'ở',
  'Ỡ' => 'ỡ',
  'Ợ' => 'ợ',
  'Ụ' => 'ụ',
  'Ủ' => 'ủ',
  'Ứ' => 'ứ',
  'Ừ' => 'ừ',
  'Ử' => 'ử',
  'Ữ' => 'ữ',
  'Ự' => 'ự',
  'Ỳ' => 'ỳ',
  'Ỵ' => 'ỵ',
  'Ỷ' => 'ỷ',
  'Ỹ' => 'ỹ',
  'Ỻ' => 'ỻ',
  'Ỽ' => 'ỽ',
  'Ỿ' => 'ỿ',
  'Ἀ' => 'ἀ',
  'Ἁ' => 'ἁ',
  'Ἂ' => 'ἂ',
  'Ἃ' => 'ἃ',
  'Ἄ' => 'ἄ',
  'Ἅ' => 'ἅ',
  'Ἆ' => 'ἆ',
  'Ἇ' => 'ἇ',
  'Ἐ' => 'ἐ',
  'Ἑ' => 'ἑ',
  'Ἒ' => 'ἒ',
  'Ἓ' => 'ἓ',
  'Ἔ' => 'ἔ',
  'Ἕ' => 'ἕ',
  'Ἠ' => 'ἠ',
  'Ἡ' => 'ἡ',
  'Ἢ' => 'ἢ',
  'Ἣ' => 'ἣ',
  'Ἤ' => 'ἤ',
  'Ἥ' => 'ἥ',
  'Ἦ' => 'ἦ',
  'Ἧ' => 'ἧ',
  'Ἰ' => 'ἰ',
  'Ἱ' => 'ἱ',
  'Ἲ' => 'ἲ',
  'Ἳ' => 'ἳ',
  'Ἴ' => 'ἴ',
  'Ἵ' => 'ἵ',
  'Ἶ' => 'ἶ',
  'Ἷ' => 'ἷ',
  'Ὀ' => 'ὀ',
  'Ὁ' => 'ὁ',
  'Ὂ' => 'ὂ',
  'Ὃ' => 'ὃ',
  'Ὄ' => 'ὄ',
  'Ὅ' => 'ὅ',
  'Ὑ' => 'ὑ',
  'Ὓ' => 'ὓ',
  'Ὕ' => 'ὕ',
  'Ὗ' => 'ὗ',
  'Ὠ' => 'ὠ',
  'Ὡ' => 'ὡ',
  'Ὢ' => 'ὢ',
  'Ὣ' => 'ὣ',
  'Ὤ' => 'ὤ',
  'Ὥ' => 'ὥ',
  'Ὦ' => 'ὦ',
  'Ὧ' => 'ὧ',
  'ᾈ' => 'ᾀ',
  'ᾉ' => 'ᾁ',
  'ᾊ' => 'ᾂ',
  'ᾋ' => 'ᾃ',
  'ᾌ' => 'ᾄ',
  'ᾍ' => 'ᾅ',
  'ᾎ' => 'ᾆ',
  'ᾏ' => 'ᾇ',
  'ᾘ' => 'ᾐ',
  'ᾙ' => 'ᾑ',
  'ᾚ' => 'ᾒ',
  'ᾛ' => 'ᾓ',
  'ᾜ' => 'ᾔ',
  'ᾝ' => 'ᾕ',
  'ᾞ' => 'ᾖ',
  'ᾟ' => 'ᾗ',
  'ᾨ' => 'ᾠ',
  'ᾩ' => 'ᾡ',
  'ᾪ' => 'ᾢ',
  'ᾫ' => 'ᾣ',
  'ᾬ' => 'ᾤ',
  'ᾭ' => 'ᾥ',
  'ᾮ' => 'ᾦ',
  'ᾯ' => 'ᾧ',
  'Ᾰ' => 'ᾰ',
  'Ᾱ' => 'ᾱ',
  'Ὰ' => 'ὰ',
  'Ά' => 'ά',
  'ᾼ' => 'ᾳ',
  'Ὲ' => 'ὲ',
  'Έ' => 'έ',
  'Ὴ' => 'ὴ',
  'Ή' => 'ή',
  'ῌ' => 'ῃ',
  'Ῐ' => 'ῐ',
  'Ῑ' => 'ῑ',
  'Ὶ' => 'ὶ',
  'Ί' => 'ί',
  'Ῠ' => 'ῠ',
  'Ῡ' => 'ῡ',
  'Ὺ' => 'ὺ',
  'Ύ' => 'ύ',
  'Ῥ' => 'ῥ',
  'Ὸ' => 'ὸ',
  'Ό' => 'ό',
  'Ὼ' => 'ὼ',
  'Ώ' => 'ώ',
  'ῼ' => 'ῳ',
  'Ω' => 'ω',
  'K' => 'k',
  'Å' => 'å',
  'Ⅎ' => 'ⅎ',
  'Ⅰ' => 'ⅰ',
  'Ⅱ' => 'ⅱ',
  'Ⅲ' => 'ⅲ',
  'Ⅳ' => 'ⅳ',
  'Ⅴ' => 'ⅴ',
  'Ⅵ' => 'ⅵ',
  'Ⅶ' => 'ⅶ',
  'Ⅷ' => 'ⅷ',
  'Ⅸ' => 'ⅸ',
  'Ⅹ' => 'ⅹ',
  'Ⅺ' => 'ⅺ',
  'Ⅻ' => 'ⅻ',
  'Ⅼ' => 'ⅼ',
  'Ⅽ' => 'ⅽ',
  'Ⅾ' => 'ⅾ',
  'Ⅿ' => 'ⅿ',
  'Ↄ' => 'ↄ',
  'Ⓐ' => 'ⓐ',
  'Ⓑ' => 'ⓑ',
  'Ⓒ' => 'ⓒ',
  'Ⓓ' => 'ⓓ',
  'Ⓔ' => 'ⓔ',
  'Ⓕ' => 'ⓕ',
  'Ⓖ' => 'ⓖ',
  'Ⓗ' => 'ⓗ',
  'Ⓘ' => 'ⓘ',
  'Ⓙ' => 'ⓙ',
  'Ⓚ' => 'ⓚ',
  'Ⓛ' => 'ⓛ',
  'Ⓜ' => 'ⓜ',
  'Ⓝ' => 'ⓝ',
  'Ⓞ' => 'ⓞ',
  'Ⓟ' => 'ⓟ',
  'Ⓠ' => 'ⓠ',
  'Ⓡ' => 'ⓡ',
  'Ⓢ' => 'ⓢ',
  'Ⓣ' => 'ⓣ',
  'Ⓤ' => 'ⓤ',
  'Ⓥ' => 'ⓥ',
  'Ⓦ' => 'ⓦ',
  'Ⓧ' => 'ⓧ',
  'Ⓨ' => 'ⓨ',
  'Ⓩ' => 'ⓩ',
  'Ⰰ' => 'ⰰ',
  'Ⰱ' => 'ⰱ',
  'Ⰲ' => 'ⰲ',
  'Ⰳ' => 'ⰳ',
  'Ⰴ' => 'ⰴ',
  'Ⰵ' => 'ⰵ',
  'Ⰶ' => 'ⰶ',
  'Ⰷ' => 'ⰷ',
  'Ⰸ' => 'ⰸ',
  'Ⰹ' => 'ⰹ',
  'Ⰺ' => 'ⰺ',
  'Ⰻ' => 'ⰻ',
  'Ⰼ' => 'ⰼ',
  'Ⰽ' => 'ⰽ',
  'Ⰾ' => 'ⰾ',
  'Ⰿ' => 'ⰿ',
  'Ⱀ' => 'ⱀ',
  'Ⱁ' => 'ⱁ',
  'Ⱂ' => 'ⱂ',
  'Ⱃ' => 'ⱃ',
  'Ⱄ' => 'ⱄ',
  'Ⱅ' => 'ⱅ',
  'Ⱆ' => 'ⱆ',
  'Ⱇ' => 'ⱇ',
  'Ⱈ' => 'ⱈ',
  'Ⱉ' => 'ⱉ',
  'Ⱊ' => 'ⱊ',
  'Ⱋ' => 'ⱋ',
  'Ⱌ' => 'ⱌ',
  'Ⱍ' => 'ⱍ',
  'Ⱎ' => 'ⱎ',
  'Ⱏ' => 'ⱏ',
  'Ⱐ' => 'ⱐ',
  'Ⱑ' => 'ⱑ',
  'Ⱒ' => 'ⱒ',
  'Ⱓ' => 'ⱓ',
  'Ⱔ' => 'ⱔ',
  'Ⱕ' => 'ⱕ',
  'Ⱖ' => 'ⱖ',
  'Ⱗ' => 'ⱗ',
  'Ⱘ' => 'ⱘ',
  'Ⱙ' => 'ⱙ',
  'Ⱚ' => 'ⱚ',
  'Ⱛ' => 'ⱛ',
  'Ⱜ' => 'ⱜ',
  'Ⱝ' => 'ⱝ',
  'Ⱞ' => 'ⱞ',
  'Ⱡ' => 'ⱡ',
  'Ɫ' => 'ɫ',
  'Ᵽ' => 'ᵽ',
  'Ɽ' => 'ɽ',
  'Ⱨ' => 'ⱨ',
  'Ⱪ' => 'ⱪ',
  'Ⱬ' => 'ⱬ',
  'Ɑ' => 'ɑ',
  'Ɱ' => 'ɱ',
  'Ɐ' => 'ɐ',
  'Ɒ' => 'ɒ',
  'Ⱳ' => 'ⱳ',
  'Ⱶ' => 'ⱶ',
  'Ȿ' => 'ȿ',
  'Ɀ' => 'ɀ',
  'Ⲁ' => 'ⲁ',
  'Ⲃ' => 'ⲃ',
  'Ⲅ' => 'ⲅ',
  'Ⲇ' => 'ⲇ',
  'Ⲉ' => 'ⲉ',
  'Ⲋ' => 'ⲋ',
  'Ⲍ' => 'ⲍ',
  'Ⲏ' => 'ⲏ',
  'Ⲑ' => 'ⲑ',
  'Ⲓ' => 'ⲓ',
  'Ⲕ' => 'ⲕ',
  'Ⲗ' => 'ⲗ',
  'Ⲙ' => 'ⲙ',
  'Ⲛ' => 'ⲛ',
  'Ⲝ' => 'ⲝ',
  'Ⲟ' => 'ⲟ',
  'Ⲡ' => 'ⲡ',
  'Ⲣ' => 'ⲣ',
  'Ⲥ' => 'ⲥ',
  'Ⲧ' => 'ⲧ',
  'Ⲩ' => 'ⲩ',
  'Ⲫ' => 'ⲫ',
  'Ⲭ' => 'ⲭ',
  'Ⲯ' => 'ⲯ',
  'Ⲱ' => 'ⲱ',
  'Ⲳ' => 'ⲳ',
  'Ⲵ' => 'ⲵ',
  'Ⲷ' => 'ⲷ',
  'Ⲹ' => 'ⲹ',
  'Ⲻ' => 'ⲻ',
  'Ⲽ' => 'ⲽ',
  'Ⲿ' => 'ⲿ',
  'Ⳁ' => 'ⳁ',
  'Ⳃ' => 'ⳃ',
  'Ⳅ' => 'ⳅ',
  'Ⳇ' => 'ⳇ',
  'Ⳉ' => 'ⳉ',
  'Ⳋ' => 'ⳋ',
  'Ⳍ' => 'ⳍ',
  'Ⳏ' => 'ⳏ',
  'Ⳑ' => 'ⳑ',
  'Ⳓ' => 'ⳓ',
  'Ⳕ' => 'ⳕ',
  'Ⳗ' => 'ⳗ',
  'Ⳙ' => 'ⳙ',
  'Ⳛ' => 'ⳛ',
  'Ⳝ' => 'ⳝ',
  'Ⳟ' => 'ⳟ',
  'Ⳡ' => 'ⳡ',
  'Ⳣ' => 'ⳣ',
  'Ⳬ' => 'ⳬ',
  'Ⳮ' => 'ⳮ',
  'Ⳳ' => 'ⳳ',
  'Ꙁ' => 'ꙁ',
  'Ꙃ' => 'ꙃ',
  'Ꙅ' => 'ꙅ',
  'Ꙇ' => 'ꙇ',
  'Ꙉ' => 'ꙉ',
  'Ꙋ' => 'ꙋ',
  'Ꙍ' => 'ꙍ',
  'Ꙏ' => 'ꙏ',
  'Ꙑ' => 'ꙑ',
  'Ꙓ' => 'ꙓ',
  'Ꙕ' => 'ꙕ',
  'Ꙗ' => 'ꙗ',
  'Ꙙ' => 'ꙙ',
  'Ꙛ' => 'ꙛ',
  'Ꙝ' => 'ꙝ',
  'Ꙟ' => 'ꙟ',
  'Ꙡ' => 'ꙡ',
  'Ꙣ' => 'ꙣ',
  'Ꙥ' => 'ꙥ',
  'Ꙧ' => 'ꙧ',
  'Ꙩ' => 'ꙩ',
  'Ꙫ' => 'ꙫ',
  'Ꙭ' => 'ꙭ',
  'Ꚁ' => 'ꚁ',
  'Ꚃ' => 'ꚃ',
  'Ꚅ' => 'ꚅ',
  'Ꚇ' => 'ꚇ',
  'Ꚉ' => 'ꚉ',
  'Ꚋ' => 'ꚋ',
  'Ꚍ' => 'ꚍ',
  'Ꚏ' => 'ꚏ',
  'Ꚑ' => 'ꚑ',
  'Ꚓ' => 'ꚓ',
  'Ꚕ' => 'ꚕ',
  'Ꚗ' => 'ꚗ',
  'Ꚙ' => 'ꚙ',
  'Ꚛ' => 'ꚛ',
  'Ꜣ' => 'ꜣ',
  'Ꜥ' => 'ꜥ',
  'Ꜧ' => 'ꜧ',
  'Ꜩ' => 'ꜩ',
  'Ꜫ' => 'ꜫ',
  'Ꜭ' => 'ꜭ',
  'Ꜯ' => 'ꜯ',
  'Ꜳ' => 'ꜳ',
  'Ꜵ' => 'ꜵ',
  'Ꜷ' => 'ꜷ',
  'Ꜹ' => 'ꜹ',
  'Ꜻ' => 'ꜻ',
  'Ꜽ' => 'ꜽ',
  'Ꜿ' => 'ꜿ',
  'Ꝁ' => 'ꝁ',
  'Ꝃ' => 'ꝃ',
  'Ꝅ' => 'ꝅ',
  'Ꝇ' => 'ꝇ',
  'Ꝉ' => 'ꝉ',
  'Ꝋ' => 'ꝋ',
  'Ꝍ' => 'ꝍ',
  'Ꝏ' => 'ꝏ',
  'Ꝑ' => 'ꝑ',
  'Ꝓ' => 'ꝓ',
  'Ꝕ' => 'ꝕ',
  'Ꝗ' => 'ꝗ',
  'Ꝙ' => 'ꝙ',
  'Ꝛ' => 'ꝛ',
  'Ꝝ' => 'ꝝ',
  'Ꝟ' => 'ꝟ',
  'Ꝡ' => 'ꝡ',
  'Ꝣ' => 'ꝣ',
  'Ꝥ' => 'ꝥ',
  'Ꝧ' => 'ꝧ',
  'Ꝩ' => 'ꝩ',
  'Ꝫ' => 'ꝫ',
  'Ꝭ' => 'ꝭ',
  'Ꝯ' => 'ꝯ',
  'Ꝺ' => 'ꝺ',
  'Ꝼ' => 'ꝼ',
  'Ᵹ' => 'ᵹ',
  'Ꝿ' => 'ꝿ',
  'Ꞁ' => 'ꞁ',
  'Ꞃ' => 'ꞃ',
  'Ꞅ' => 'ꞅ',
  'Ꞇ' => 'ꞇ',
  'Ꞌ' => 'ꞌ',
  'Ɥ' => 'ɥ',
  'Ꞑ' => 'ꞑ',
  'Ꞓ' => 'ꞓ',
  'Ꞗ' => 'ꞗ',
  'Ꞙ' => 'ꞙ',
  'Ꞛ' => 'ꞛ',
  'Ꞝ' => 'ꞝ',
  'Ꞟ' => 'ꞟ',
  'Ꞡ' => 'ꞡ',
  'Ꞣ' => 'ꞣ',
  'Ꞥ' => 'ꞥ',
  'Ꞧ' => 'ꞧ',
  'Ꞩ' => 'ꞩ',
  'Ɦ' => 'ɦ',
  'Ɜ' => 'ɜ',
  'Ɡ' => 'ɡ',
  'Ɬ' => 'ɬ',
  'Ɪ' => 'ɪ',
  'Ʞ' => 'ʞ',
  'Ʇ' => 'ʇ',
  'Ʝ' => 'ʝ',
  'Ꭓ' => 'ꭓ',
  'Ꞵ' => 'ꞵ',
  'Ꞷ' => 'ꞷ',
  'Ꞹ' => 'ꞹ',
  'Ꞻ' => 'ꞻ',
  'Ꞽ' => 'ꞽ',
  'Ꞿ' => 'ꞿ',
  'Ꟃ' => 'ꟃ',
  'Ꞔ' => 'ꞔ',
  'Ʂ' => 'ʂ',
  'Ᶎ' => 'ᶎ',
  'Ꟈ' => 'ꟈ',
  'Ꟊ' => 'ꟊ',
  'Ꟶ' => 'ꟶ',
  'A' => 'a',
  'B' => 'b',
  'C' => 'c',
  'D' => 'd',
  'E' => 'e',
  'F' => 'f',
  'G' => 'g',
  'H' => 'h',
  'I' => 'i',
  'J' => 'j',
  'K' => 'k',
  'L' => 'l',
  'M' => 'm',
  'N' => 'n',
  'O' => 'o',
  'P' => 'p',
  'Q' => 'q',
  'R' => 'r',
  'S' => 's',
  'T' => 't',
  'U' => 'u',
  'V' => 'v',
  'W' => 'w',
  'X' => 'x',
  'Y' => 'y',
  'Z' => 'z',
  '𐐀' => '𐐨',
  '𐐁' => '𐐩',
  '𐐂' => '𐐪',
  '𐐃' => '𐐫',
  '𐐄' => '𐐬',
  '𐐅' => '𐐭',
  '𐐆' => '𐐮',
  '𐐇' => '𐐯',
  '𐐈' => '𐐰',
  '𐐉' => '𐐱',
  '𐐊' => '𐐲',
  '𐐋' => '𐐳',
  '𐐌' => '𐐴',
  '𐐍' => '𐐵',
  '𐐎' => '𐐶',
  '𐐏' => '𐐷',
  '𐐐' => '𐐸',
  '𐐑' => '𐐹',
  '𐐒' => '𐐺',
  '𐐓' => '𐐻',
  '𐐔' => '𐐼',
  '𐐕' => '𐐽',
  '𐐖' => '𐐾',
  '𐐗' => '𐐿',
  '𐐘' => '𐑀',
  '𐐙' => '𐑁',
  '𐐚' => '𐑂',
  '𐐛' => '𐑃',
  '𐐜' => '𐑄',
  '𐐝' => '𐑅',
  '𐐞' => '𐑆',
  '𐐟' => '𐑇',
  '𐐠' => '𐑈',
  '𐐡' => '𐑉',
  '𐐢' => '𐑊',
  '𐐣' => '𐑋',
  '𐐤' => '𐑌',
  '𐐥' => '𐑍',
  '𐐦' => '𐑎',
  '𐐧' => '𐑏',
  '𐒰' => '𐓘',
  '𐒱' => '𐓙',
  '𐒲' => '𐓚',
  '𐒳' => '𐓛',
  '𐒴' => '𐓜',
  '𐒵' => '𐓝',
  '𐒶' => '𐓞',
  '𐒷' => '𐓟',
  '𐒸' => '𐓠',
  '𐒹' => '𐓡',
  '𐒺' => '𐓢',
  '𐒻' => '𐓣',
  '𐒼' => '𐓤',
  '𐒽' => '𐓥',
  '𐒾' => '𐓦',
  '𐒿' => '𐓧',
  '𐓀' => '𐓨',
  '𐓁' => '𐓩',
  '𐓂' => '𐓪',
  '𐓃' => '𐓫',
  '𐓄' => '𐓬',
  '𐓅' => '𐓭',
  '𐓆' => '𐓮',
  '𐓇' => '𐓯',
  '𐓈' => '𐓰',
  '𐓉' => '𐓱',
  '𐓊' => '𐓲',
  '𐓋' => '𐓳',
  '𐓌' => '𐓴',
  '𐓍' => '𐓵',
  '𐓎' => '𐓶',
  '𐓏' => '𐓷',
  '𐓐' => '𐓸',
  '𐓑' => '𐓹',
  '𐓒' => '𐓺',
  '𐓓' => '𐓻',
  '𐲀' => '𐳀',
  '𐲁' => '𐳁',
  '𐲂' => '𐳂',
  '𐲃' => '𐳃',
  '𐲄' => '𐳄',
  '𐲅' => '𐳅',
  '𐲆' => '𐳆',
  '𐲇' => '𐳇',
  '𐲈' => '𐳈',
  '𐲉' => '𐳉',
  '𐲊' => '𐳊',
  '𐲋' => '𐳋',
  '𐲌' => '𐳌',
  '𐲍' => '𐳍',
  '𐲎' => '𐳎',
  '𐲏' => '𐳏',
  '𐲐' => '𐳐',
  '𐲑' => '𐳑',
  '𐲒' => '𐳒',
  '𐲓' => '𐳓',
  '𐲔' => '𐳔',
  '𐲕' => '𐳕',
  '𐲖' => '𐳖',
  '𐲗' => '𐳗',
  '𐲘' => '𐳘',
  '𐲙' => '𐳙',
  '𐲚' => '𐳚',
  '𐲛' => '𐳛',
  '𐲜' => '𐳜',
  '𐲝' => '𐳝',
  '𐲞' => '𐳞',
  '𐲟' => '𐳟',
  '𐲠' => '𐳠',
  '𐲡' => '𐳡',
  '𐲢' => '𐳢',
  '𐲣' => '𐳣',
  '𐲤' => '𐳤',
  '𐲥' => '𐳥',
  '𐲦' => '𐳦',
  '𐲧' => '𐳧',
  '𐲨' => '𐳨',
  '𐲩' => '𐳩',
  '𐲪' => '𐳪',
  '𐲫' => '𐳫',
  '𐲬' => '𐳬',
  '𐲭' => '𐳭',
  '𐲮' => '𐳮',
  '𐲯' => '𐳯',
  '𐲰' => '𐳰',
  '𐲱' => '𐳱',
  '𐲲' => '𐳲',
  '𑢠' => '𑣀',
  '𑢡' => '𑣁',
  '𑢢' => '𑣂',
  '𑢣' => '𑣃',
  '𑢤' => '𑣄',
  '𑢥' => '𑣅',
  '𑢦' => '𑣆',
  '𑢧' => '𑣇',
  '𑢨' => '𑣈',
  '𑢩' => '𑣉',
  '𑢪' => '𑣊',
  '𑢫' => '𑣋',
  '𑢬' => '𑣌',
  '𑢭' => '𑣍',
  '𑢮' => '𑣎',
  '𑢯' => '𑣏',
  '𑢰' => '𑣐',
  '𑢱' => '𑣑',
  '𑢲' => '𑣒',
  '𑢳' => '𑣓',
  '𑢴' => '𑣔',
  '𑢵' => '𑣕',
  '𑢶' => '𑣖',
  '𑢷' => '𑣗',
  '𑢸' => '𑣘',
  '𑢹' => '𑣙',
  '𑢺' => '𑣚',
  '𑢻' => '𑣛',
  '𑢼' => '𑣜',
  '𑢽' => '𑣝',
  '𑢾' => '𑣞',
  '𑢿' => '𑣟',
  '𖹀' => '𖹠',
  '𖹁' => '𖹡',
  '𖹂' => '𖹢',
  '𖹃' => '𖹣',
  '𖹄' => '𖹤',
  '𖹅' => '𖹥',
  '𖹆' => '𖹦',
  '𖹇' => '𖹧',
  '𖹈' => '𖹨',
  '𖹉' => '𖹩',
  '𖹊' => '𖹪',
  '𖹋' => '𖹫',
  '𖹌' => '𖹬',
  '𖹍' => '𖹭',
  '𖹎' => '𖹮',
  '𖹏' => '𖹯',
  '𖹐' => '𖹰',
  '𖹑' => '𖹱',
  '𖹒' => '𖹲',
  '𖹓' => '𖹳',
  '𖹔' => '𖹴',
  '𖹕' => '𖹵',
  '𖹖' => '𖹶',
  '𖹗' => '𖹷',
  '𖹘' => '𖹸',
  '𖹙' => '𖹹',
  '𖹚' => '𖹺',
  '𖹛' => '𖹻',
  '𖹜' => '𖹼',
  '𖹝' => '𖹽',
  '𖹞' => '𖹾',
  '𖹟' => '𖹿',
  '𞤀' => '𞤢',
  '𞤁' => '𞤣',
  '𞤂' => '𞤤',
  '𞤃' => '𞤥',
  '𞤄' => '𞤦',
  '𞤅' => '𞤧',
  '𞤆' => '𞤨',
  '𞤇' => '𞤩',
  '𞤈' => '𞤪',
  '𞤉' => '𞤫',
  '𞤊' => '𞤬',
  '𞤋' => '𞤭',
  '𞤌' => '𞤮',
  '𞤍' => '𞤯',
  '𞤎' => '𞤰',
  '𞤏' => '𞤱',
  '𞤐' => '𞤲',
  '𞤑' => '𞤳',
  '𞤒' => '𞤴',
  '𞤓' => '𞤵',
  '𞤔' => '𞤶',
  '𞤕' => '𞤷',
  '𞤖' => '𞤸',
  '𞤗' => '𞤹',
  '𞤘' => '𞤺',
  '𞤙' => '𞤻',
  '𞤚' => '𞤼',
  '𞤛' => '𞤽',
  '𞤜' => '𞤾',
  '𞤝' => '𞤿',
  '𞤞' => '𞥀',
  '𞤟' => '𞥁',
  '𞤠' => '𞥂',
  '𞤡' => '𞥃',
);
PKϤ$Z�S��`�`1polyfill-mbstring/Resources/unidata/upperCase.phpnu�[���<?php

return array (
  'a' => 'A',
  'b' => 'B',
  'c' => 'C',
  'd' => 'D',
  'e' => 'E',
  'f' => 'F',
  'g' => 'G',
  'h' => 'H',
  'i' => 'I',
  'j' => 'J',
  'k' => 'K',
  'l' => 'L',
  'm' => 'M',
  'n' => 'N',
  'o' => 'O',
  'p' => 'P',
  'q' => 'Q',
  'r' => 'R',
  's' => 'S',
  't' => 'T',
  'u' => 'U',
  'v' => 'V',
  'w' => 'W',
  'x' => 'X',
  'y' => 'Y',
  'z' => 'Z',
  'µ' => 'Μ',
  'à' => 'À',
  'á' => 'Á',
  'â' => 'Â',
  'ã' => 'Ã',
  'ä' => 'Ä',
  'å' => 'Å',
  'æ' => 'Æ',
  'ç' => 'Ç',
  'è' => 'È',
  'é' => 'É',
  'ê' => 'Ê',
  'ë' => 'Ë',
  'ì' => 'Ì',
  'í' => 'Í',
  'î' => 'Î',
  'ï' => 'Ï',
  'ð' => 'Ð',
  'ñ' => 'Ñ',
  'ò' => 'Ò',
  'ó' => 'Ó',
  'ô' => 'Ô',
  'õ' => 'Õ',
  'ö' => 'Ö',
  'ø' => 'Ø',
  'ù' => 'Ù',
  'ú' => 'Ú',
  'û' => 'Û',
  'ü' => 'Ü',
  'ý' => 'Ý',
  'þ' => 'Þ',
  'ÿ' => 'Ÿ',
  'ā' => 'Ā',
  'ă' => 'Ă',
  'ą' => 'Ą',
  'ć' => 'Ć',
  'ĉ' => 'Ĉ',
  'ċ' => 'Ċ',
  'č' => 'Č',
  'ď' => 'Ď',
  'đ' => 'Đ',
  'ē' => 'Ē',
  'ĕ' => 'Ĕ',
  'ė' => 'Ė',
  'ę' => 'Ę',
  'ě' => 'Ě',
  'ĝ' => 'Ĝ',
  'ğ' => 'Ğ',
  'ġ' => 'Ġ',
  'ģ' => 'Ģ',
  'ĥ' => 'Ĥ',
  'ħ' => 'Ħ',
  'ĩ' => 'Ĩ',
  'ī' => 'Ī',
  'ĭ' => 'Ĭ',
  'į' => 'Į',
  'ı' => 'I',
  'ij' => 'IJ',
  'ĵ' => 'Ĵ',
  'ķ' => 'Ķ',
  'ĺ' => 'Ĺ',
  'ļ' => 'Ļ',
  'ľ' => 'Ľ',
  'ŀ' => 'Ŀ',
  'ł' => 'Ł',
  'ń' => 'Ń',
  'ņ' => 'Ņ',
  'ň' => 'Ň',
  'ŋ' => 'Ŋ',
  'ō' => 'Ō',
  'ŏ' => 'Ŏ',
  'ő' => 'Ő',
  'œ' => 'Œ',
  'ŕ' => 'Ŕ',
  'ŗ' => 'Ŗ',
  'ř' => 'Ř',
  'ś' => 'Ś',
  'ŝ' => 'Ŝ',
  'ş' => 'Ş',
  'š' => 'Š',
  'ţ' => 'Ţ',
  'ť' => 'Ť',
  'ŧ' => 'Ŧ',
  'ũ' => 'Ũ',
  'ū' => 'Ū',
  'ŭ' => 'Ŭ',
  'ů' => 'Ů',
  'ű' => 'Ű',
  'ų' => 'Ų',
  'ŵ' => 'Ŵ',
  'ŷ' => 'Ŷ',
  'ź' => 'Ź',
  'ż' => 'Ż',
  'ž' => 'Ž',
  'ſ' => 'S',
  'ƀ' => 'Ƀ',
  'ƃ' => 'Ƃ',
  'ƅ' => 'Ƅ',
  'ƈ' => 'Ƈ',
  'ƌ' => 'Ƌ',
  'ƒ' => 'Ƒ',
  'ƕ' => 'Ƕ',
  'ƙ' => 'Ƙ',
  'ƚ' => 'Ƚ',
  'ƞ' => 'Ƞ',
  'ơ' => 'Ơ',
  'ƣ' => 'Ƣ',
  'ƥ' => 'Ƥ',
  'ƨ' => 'Ƨ',
  'ƭ' => 'Ƭ',
  'ư' => 'Ư',
  'ƴ' => 'Ƴ',
  'ƶ' => 'Ƶ',
  'ƹ' => 'Ƹ',
  'ƽ' => 'Ƽ',
  'ƿ' => 'Ƿ',
  'Dž' => 'DŽ',
  'dž' => 'DŽ',
  'Lj' => 'LJ',
  'lj' => 'LJ',
  'Nj' => 'NJ',
  'nj' => 'NJ',
  'ǎ' => 'Ǎ',
  'ǐ' => 'Ǐ',
  'ǒ' => 'Ǒ',
  'ǔ' => 'Ǔ',
  'ǖ' => 'Ǖ',
  'ǘ' => 'Ǘ',
  'ǚ' => 'Ǚ',
  'ǜ' => 'Ǜ',
  'ǝ' => 'Ǝ',
  'ǟ' => 'Ǟ',
  'ǡ' => 'Ǡ',
  'ǣ' => 'Ǣ',
  'ǥ' => 'Ǥ',
  'ǧ' => 'Ǧ',
  'ǩ' => 'Ǩ',
  'ǫ' => 'Ǫ',
  'ǭ' => 'Ǭ',
  'ǯ' => 'Ǯ',
  'Dz' => 'DZ',
  'dz' => 'DZ',
  'ǵ' => 'Ǵ',
  'ǹ' => 'Ǹ',
  'ǻ' => 'Ǻ',
  'ǽ' => 'Ǽ',
  'ǿ' => 'Ǿ',
  'ȁ' => 'Ȁ',
  'ȃ' => 'Ȃ',
  'ȅ' => 'Ȅ',
  'ȇ' => 'Ȇ',
  'ȉ' => 'Ȉ',
  'ȋ' => 'Ȋ',
  'ȍ' => 'Ȍ',
  'ȏ' => 'Ȏ',
  'ȑ' => 'Ȑ',
  'ȓ' => 'Ȓ',
  'ȕ' => 'Ȕ',
  'ȗ' => 'Ȗ',
  'ș' => 'Ș',
  'ț' => 'Ț',
  'ȝ' => 'Ȝ',
  'ȟ' => 'Ȟ',
  'ȣ' => 'Ȣ',
  'ȥ' => 'Ȥ',
  'ȧ' => 'Ȧ',
  'ȩ' => 'Ȩ',
  'ȫ' => 'Ȫ',
  'ȭ' => 'Ȭ',
  'ȯ' => 'Ȯ',
  'ȱ' => 'Ȱ',
  'ȳ' => 'Ȳ',
  'ȼ' => 'Ȼ',
  'ȿ' => 'Ȿ',
  'ɀ' => 'Ɀ',
  'ɂ' => 'Ɂ',
  'ɇ' => 'Ɇ',
  'ɉ' => 'Ɉ',
  'ɋ' => 'Ɋ',
  'ɍ' => 'Ɍ',
  'ɏ' => 'Ɏ',
  'ɐ' => 'Ɐ',
  'ɑ' => 'Ɑ',
  'ɒ' => 'Ɒ',
  'ɓ' => 'Ɓ',
  'ɔ' => 'Ɔ',
  'ɖ' => 'Ɖ',
  'ɗ' => 'Ɗ',
  'ə' => 'Ə',
  'ɛ' => 'Ɛ',
  'ɜ' => 'Ɜ',
  'ɠ' => 'Ɠ',
  'ɡ' => 'Ɡ',
  'ɣ' => 'Ɣ',
  'ɥ' => 'Ɥ',
  'ɦ' => 'Ɦ',
  'ɨ' => 'Ɨ',
  'ɩ' => 'Ɩ',
  'ɪ' => 'Ɪ',
  'ɫ' => 'Ɫ',
  'ɬ' => 'Ɬ',
  'ɯ' => 'Ɯ',
  'ɱ' => 'Ɱ',
  'ɲ' => 'Ɲ',
  'ɵ' => 'Ɵ',
  'ɽ' => 'Ɽ',
  'ʀ' => 'Ʀ',
  'ʂ' => 'Ʂ',
  'ʃ' => 'Ʃ',
  'ʇ' => 'Ʇ',
  'ʈ' => 'Ʈ',
  'ʉ' => 'Ʉ',
  'ʊ' => 'Ʊ',
  'ʋ' => 'Ʋ',
  'ʌ' => 'Ʌ',
  'ʒ' => 'Ʒ',
  'ʝ' => 'Ʝ',
  'ʞ' => 'Ʞ',
  'ͅ' => 'Ι',
  'ͱ' => 'Ͱ',
  'ͳ' => 'Ͳ',
  'ͷ' => 'Ͷ',
  'ͻ' => 'Ͻ',
  'ͼ' => 'Ͼ',
  'ͽ' => 'Ͽ',
  'ά' => 'Ά',
  'έ' => 'Έ',
  'ή' => 'Ή',
  'ί' => 'Ί',
  'α' => 'Α',
  'β' => 'Β',
  'γ' => 'Γ',
  'δ' => 'Δ',
  'ε' => 'Ε',
  'ζ' => 'Ζ',
  'η' => 'Η',
  'θ' => 'Θ',
  'ι' => 'Ι',
  'κ' => 'Κ',
  'λ' => 'Λ',
  'μ' => 'Μ',
  'ν' => 'Ν',
  'ξ' => 'Ξ',
  'ο' => 'Ο',
  'π' => 'Π',
  'ρ' => 'Ρ',
  'ς' => 'Σ',
  'σ' => 'Σ',
  'τ' => 'Τ',
  'υ' => 'Υ',
  'φ' => 'Φ',
  'χ' => 'Χ',
  'ψ' => 'Ψ',
  'ω' => 'Ω',
  'ϊ' => 'Ϊ',
  'ϋ' => 'Ϋ',
  'ό' => 'Ό',
  'ύ' => 'Ύ',
  'ώ' => 'Ώ',
  'ϐ' => 'Β',
  'ϑ' => 'Θ',
  'ϕ' => 'Φ',
  'ϖ' => 'Π',
  'ϗ' => 'Ϗ',
  'ϙ' => 'Ϙ',
  'ϛ' => 'Ϛ',
  'ϝ' => 'Ϝ',
  'ϟ' => 'Ϟ',
  'ϡ' => 'Ϡ',
  'ϣ' => 'Ϣ',
  'ϥ' => 'Ϥ',
  'ϧ' => 'Ϧ',
  'ϩ' => 'Ϩ',
  'ϫ' => 'Ϫ',
  'ϭ' => 'Ϭ',
  'ϯ' => 'Ϯ',
  'ϰ' => 'Κ',
  'ϱ' => 'Ρ',
  'ϲ' => 'Ϲ',
  'ϳ' => 'Ϳ',
  'ϵ' => 'Ε',
  'ϸ' => 'Ϸ',
  'ϻ' => 'Ϻ',
  'а' => 'А',
  'б' => 'Б',
  'в' => 'В',
  'г' => 'Г',
  'д' => 'Д',
  'е' => 'Е',
  'ж' => 'Ж',
  'з' => 'З',
  'и' => 'И',
  'й' => 'Й',
  'к' => 'К',
  'л' => 'Л',
  'м' => 'М',
  'н' => 'Н',
  'о' => 'О',
  'п' => 'П',
  'р' => 'Р',
  'с' => 'С',
  'т' => 'Т',
  'у' => 'У',
  'ф' => 'Ф',
  'х' => 'Х',
  'ц' => 'Ц',
  'ч' => 'Ч',
  'ш' => 'Ш',
  'щ' => 'Щ',
  'ъ' => 'Ъ',
  'ы' => 'Ы',
  'ь' => 'Ь',
  'э' => 'Э',
  'ю' => 'Ю',
  'я' => 'Я',
  'ѐ' => 'Ѐ',
  'ё' => 'Ё',
  'ђ' => 'Ђ',
  'ѓ' => 'Ѓ',
  'є' => 'Є',
  'ѕ' => 'Ѕ',
  'і' => 'І',
  'ї' => 'Ї',
  'ј' => 'Ј',
  'љ' => 'Љ',
  'њ' => 'Њ',
  'ћ' => 'Ћ',
  'ќ' => 'Ќ',
  'ѝ' => 'Ѝ',
  'ў' => 'Ў',
  'џ' => 'Џ',
  'ѡ' => 'Ѡ',
  'ѣ' => 'Ѣ',
  'ѥ' => 'Ѥ',
  'ѧ' => 'Ѧ',
  'ѩ' => 'Ѩ',
  'ѫ' => 'Ѫ',
  'ѭ' => 'Ѭ',
  'ѯ' => 'Ѯ',
  'ѱ' => 'Ѱ',
  'ѳ' => 'Ѳ',
  'ѵ' => 'Ѵ',
  'ѷ' => 'Ѷ',
  'ѹ' => 'Ѹ',
  'ѻ' => 'Ѻ',
  'ѽ' => 'Ѽ',
  'ѿ' => 'Ѿ',
  'ҁ' => 'Ҁ',
  'ҋ' => 'Ҋ',
  'ҍ' => 'Ҍ',
  'ҏ' => 'Ҏ',
  'ґ' => 'Ґ',
  'ғ' => 'Ғ',
  'ҕ' => 'Ҕ',
  'җ' => 'Җ',
  'ҙ' => 'Ҙ',
  'қ' => 'Қ',
  'ҝ' => 'Ҝ',
  'ҟ' => 'Ҟ',
  'ҡ' => 'Ҡ',
  'ң' => 'Ң',
  'ҥ' => 'Ҥ',
  'ҧ' => 'Ҧ',
  'ҩ' => 'Ҩ',
  'ҫ' => 'Ҫ',
  'ҭ' => 'Ҭ',
  'ү' => 'Ү',
  'ұ' => 'Ұ',
  'ҳ' => 'Ҳ',
  'ҵ' => 'Ҵ',
  'ҷ' => 'Ҷ',
  'ҹ' => 'Ҹ',
  'һ' => 'Һ',
  'ҽ' => 'Ҽ',
  'ҿ' => 'Ҿ',
  'ӂ' => 'Ӂ',
  'ӄ' => 'Ӄ',
  'ӆ' => 'Ӆ',
  'ӈ' => 'Ӈ',
  'ӊ' => 'Ӊ',
  'ӌ' => 'Ӌ',
  'ӎ' => 'Ӎ',
  'ӏ' => 'Ӏ',
  'ӑ' => 'Ӑ',
  'ӓ' => 'Ӓ',
  'ӕ' => 'Ӕ',
  'ӗ' => 'Ӗ',
  'ә' => 'Ә',
  'ӛ' => 'Ӛ',
  'ӝ' => 'Ӝ',
  'ӟ' => 'Ӟ',
  'ӡ' => 'Ӡ',
  'ӣ' => 'Ӣ',
  'ӥ' => 'Ӥ',
  'ӧ' => 'Ӧ',
  'ө' => 'Ө',
  'ӫ' => 'Ӫ',
  'ӭ' => 'Ӭ',
  'ӯ' => 'Ӯ',
  'ӱ' => 'Ӱ',
  'ӳ' => 'Ӳ',
  'ӵ' => 'Ӵ',
  'ӷ' => 'Ӷ',
  'ӹ' => 'Ӹ',
  'ӻ' => 'Ӻ',
  'ӽ' => 'Ӽ',
  'ӿ' => 'Ӿ',
  'ԁ' => 'Ԁ',
  'ԃ' => 'Ԃ',
  'ԅ' => 'Ԅ',
  'ԇ' => 'Ԇ',
  'ԉ' => 'Ԉ',
  'ԋ' => 'Ԋ',
  'ԍ' => 'Ԍ',
  'ԏ' => 'Ԏ',
  'ԑ' => 'Ԑ',
  'ԓ' => 'Ԓ',
  'ԕ' => 'Ԕ',
  'ԗ' => 'Ԗ',
  'ԙ' => 'Ԙ',
  'ԛ' => 'Ԛ',
  'ԝ' => 'Ԝ',
  'ԟ' => 'Ԟ',
  'ԡ' => 'Ԡ',
  'ԣ' => 'Ԣ',
  'ԥ' => 'Ԥ',
  'ԧ' => 'Ԧ',
  'ԩ' => 'Ԩ',
  'ԫ' => 'Ԫ',
  'ԭ' => 'Ԭ',
  'ԯ' => 'Ԯ',
  'ա' => 'Ա',
  'բ' => 'Բ',
  'գ' => 'Գ',
  'դ' => 'Դ',
  'ե' => 'Ե',
  'զ' => 'Զ',
  'է' => 'Է',
  'ը' => 'Ը',
  'թ' => 'Թ',
  'ժ' => 'Ժ',
  'ի' => 'Ի',
  'լ' => 'Լ',
  'խ' => 'Խ',
  'ծ' => 'Ծ',
  'կ' => 'Կ',
  'հ' => 'Հ',
  'ձ' => 'Ձ',
  'ղ' => 'Ղ',
  'ճ' => 'Ճ',
  'մ' => 'Մ',
  'յ' => 'Յ',
  'ն' => 'Ն',
  'շ' => 'Շ',
  'ո' => 'Ո',
  'չ' => 'Չ',
  'պ' => 'Պ',
  'ջ' => 'Ջ',
  'ռ' => 'Ռ',
  'ս' => 'Ս',
  'վ' => 'Վ',
  'տ' => 'Տ',
  'ր' => 'Ր',
  'ց' => 'Ց',
  'ւ' => 'Ւ',
  'փ' => 'Փ',
  'ք' => 'Ք',
  'օ' => 'Օ',
  'ֆ' => 'Ֆ',
  'ა' => 'Ა',
  'ბ' => 'Ბ',
  'გ' => 'Გ',
  'დ' => 'Დ',
  'ე' => 'Ე',
  'ვ' => 'Ვ',
  'ზ' => 'Ზ',
  'თ' => 'Თ',
  'ი' => 'Ი',
  'კ' => 'Კ',
  'ლ' => 'Ლ',
  'მ' => 'Მ',
  'ნ' => 'Ნ',
  'ო' => 'Ო',
  'პ' => 'Პ',
  'ჟ' => 'Ჟ',
  'რ' => 'Რ',
  'ს' => 'Ს',
  'ტ' => 'Ტ',
  'უ' => 'Უ',
  'ფ' => 'Ფ',
  'ქ' => 'Ქ',
  'ღ' => 'Ღ',
  'ყ' => 'Ყ',
  'შ' => 'Შ',
  'ჩ' => 'Ჩ',
  'ც' => 'Ც',
  'ძ' => 'Ძ',
  'წ' => 'Წ',
  'ჭ' => 'Ჭ',
  'ხ' => 'Ხ',
  'ჯ' => 'Ჯ',
  'ჰ' => 'Ჰ',
  'ჱ' => 'Ჱ',
  'ჲ' => 'Ჲ',
  'ჳ' => 'Ჳ',
  'ჴ' => 'Ჴ',
  'ჵ' => 'Ჵ',
  'ჶ' => 'Ჶ',
  'ჷ' => 'Ჷ',
  'ჸ' => 'Ჸ',
  'ჹ' => 'Ჹ',
  'ჺ' => 'Ჺ',
  'ჽ' => 'Ჽ',
  'ჾ' => 'Ჾ',
  'ჿ' => 'Ჿ',
  'ᏸ' => 'Ᏸ',
  'ᏹ' => 'Ᏹ',
  'ᏺ' => 'Ᏺ',
  'ᏻ' => 'Ᏻ',
  'ᏼ' => 'Ᏼ',
  'ᏽ' => 'Ᏽ',
  'ᲀ' => 'В',
  'ᲁ' => 'Д',
  'ᲂ' => 'О',
  'ᲃ' => 'С',
  'ᲄ' => 'Т',
  'ᲅ' => 'Т',
  'ᲆ' => 'Ъ',
  'ᲇ' => 'Ѣ',
  'ᲈ' => 'Ꙋ',
  'ᵹ' => 'Ᵹ',
  'ᵽ' => 'Ᵽ',
  'ᶎ' => 'Ᶎ',
  'ḁ' => 'Ḁ',
  'ḃ' => 'Ḃ',
  'ḅ' => 'Ḅ',
  'ḇ' => 'Ḇ',
  'ḉ' => 'Ḉ',
  'ḋ' => 'Ḋ',
  'ḍ' => 'Ḍ',
  'ḏ' => 'Ḏ',
  'ḑ' => 'Ḑ',
  'ḓ' => 'Ḓ',
  'ḕ' => 'Ḕ',
  'ḗ' => 'Ḗ',
  'ḙ' => 'Ḙ',
  'ḛ' => 'Ḛ',
  'ḝ' => 'Ḝ',
  'ḟ' => 'Ḟ',
  'ḡ' => 'Ḡ',
  'ḣ' => 'Ḣ',
  'ḥ' => 'Ḥ',
  'ḧ' => 'Ḧ',
  'ḩ' => 'Ḩ',
  'ḫ' => 'Ḫ',
  'ḭ' => 'Ḭ',
  'ḯ' => 'Ḯ',
  'ḱ' => 'Ḱ',
  'ḳ' => 'Ḳ',
  'ḵ' => 'Ḵ',
  'ḷ' => 'Ḷ',
  'ḹ' => 'Ḹ',
  'ḻ' => 'Ḻ',
  'ḽ' => 'Ḽ',
  'ḿ' => 'Ḿ',
  'ṁ' => 'Ṁ',
  'ṃ' => 'Ṃ',
  'ṅ' => 'Ṅ',
  'ṇ' => 'Ṇ',
  'ṉ' => 'Ṉ',
  'ṋ' => 'Ṋ',
  'ṍ' => 'Ṍ',
  'ṏ' => 'Ṏ',
  'ṑ' => 'Ṑ',
  'ṓ' => 'Ṓ',
  'ṕ' => 'Ṕ',
  'ṗ' => 'Ṗ',
  'ṙ' => 'Ṙ',
  'ṛ' => 'Ṛ',
  'ṝ' => 'Ṝ',
  'ṟ' => 'Ṟ',
  'ṡ' => 'Ṡ',
  'ṣ' => 'Ṣ',
  'ṥ' => 'Ṥ',
  'ṧ' => 'Ṧ',
  'ṩ' => 'Ṩ',
  'ṫ' => 'Ṫ',
  'ṭ' => 'Ṭ',
  'ṯ' => 'Ṯ',
  'ṱ' => 'Ṱ',
  'ṳ' => 'Ṳ',
  'ṵ' => 'Ṵ',
  'ṷ' => 'Ṷ',
  'ṹ' => 'Ṹ',
  'ṻ' => 'Ṻ',
  'ṽ' => 'Ṽ',
  'ṿ' => 'Ṿ',
  'ẁ' => 'Ẁ',
  'ẃ' => 'Ẃ',
  'ẅ' => 'Ẅ',
  'ẇ' => 'Ẇ',
  'ẉ' => 'Ẉ',
  'ẋ' => 'Ẋ',
  'ẍ' => 'Ẍ',
  'ẏ' => 'Ẏ',
  'ẑ' => 'Ẑ',
  'ẓ' => 'Ẓ',
  'ẕ' => 'Ẕ',
  'ẛ' => 'Ṡ',
  'ạ' => 'Ạ',
  'ả' => 'Ả',
  'ấ' => 'Ấ',
  'ầ' => 'Ầ',
  'ẩ' => 'Ẩ',
  'ẫ' => 'Ẫ',
  'ậ' => 'Ậ',
  'ắ' => 'Ắ',
  'ằ' => 'Ằ',
  'ẳ' => 'Ẳ',
  'ẵ' => 'Ẵ',
  'ặ' => 'Ặ',
  'ẹ' => 'Ẹ',
  'ẻ' => 'Ẻ',
  'ẽ' => 'Ẽ',
  'ế' => 'Ế',
  'ề' => 'Ề',
  'ể' => 'Ể',
  'ễ' => 'Ễ',
  'ệ' => 'Ệ',
  'ỉ' => 'Ỉ',
  'ị' => 'Ị',
  'ọ' => 'Ọ',
  'ỏ' => 'Ỏ',
  'ố' => 'Ố',
  'ồ' => 'Ồ',
  'ổ' => 'Ổ',
  'ỗ' => 'Ỗ',
  'ộ' => 'Ộ',
  'ớ' => 'Ớ',
  'ờ' => 'Ờ',
  'ở' => 'Ở',
  'ỡ' => 'Ỡ',
  'ợ' => 'Ợ',
  'ụ' => 'Ụ',
  'ủ' => 'Ủ',
  'ứ' => 'Ứ',
  'ừ' => 'Ừ',
  'ử' => 'Ử',
  'ữ' => 'Ữ',
  'ự' => 'Ự',
  'ỳ' => 'Ỳ',
  'ỵ' => 'Ỵ',
  'ỷ' => 'Ỷ',
  'ỹ' => 'Ỹ',
  'ỻ' => 'Ỻ',
  'ỽ' => 'Ỽ',
  'ỿ' => 'Ỿ',
  'ἀ' => 'Ἀ',
  'ἁ' => 'Ἁ',
  'ἂ' => 'Ἂ',
  'ἃ' => 'Ἃ',
  'ἄ' => 'Ἄ',
  'ἅ' => 'Ἅ',
  'ἆ' => 'Ἆ',
  'ἇ' => 'Ἇ',
  'ἐ' => 'Ἐ',
  'ἑ' => 'Ἑ',
  'ἒ' => 'Ἒ',
  'ἓ' => 'Ἓ',
  'ἔ' => 'Ἔ',
  'ἕ' => 'Ἕ',
  'ἠ' => 'Ἠ',
  'ἡ' => 'Ἡ',
  'ἢ' => 'Ἢ',
  'ἣ' => 'Ἣ',
  'ἤ' => 'Ἤ',
  'ἥ' => 'Ἥ',
  'ἦ' => 'Ἦ',
  'ἧ' => 'Ἧ',
  'ἰ' => 'Ἰ',
  'ἱ' => 'Ἱ',
  'ἲ' => 'Ἲ',
  'ἳ' => 'Ἳ',
  'ἴ' => 'Ἴ',
  'ἵ' => 'Ἵ',
  'ἶ' => 'Ἶ',
  'ἷ' => 'Ἷ',
  'ὀ' => 'Ὀ',
  'ὁ' => 'Ὁ',
  'ὂ' => 'Ὂ',
  'ὃ' => 'Ὃ',
  'ὄ' => 'Ὄ',
  'ὅ' => 'Ὅ',
  'ὑ' => 'Ὑ',
  'ὓ' => 'Ὓ',
  'ὕ' => 'Ὕ',
  'ὗ' => 'Ὗ',
  'ὠ' => 'Ὠ',
  'ὡ' => 'Ὡ',
  'ὢ' => 'Ὢ',
  'ὣ' => 'Ὣ',
  'ὤ' => 'Ὤ',
  'ὥ' => 'Ὥ',
  'ὦ' => 'Ὦ',
  'ὧ' => 'Ὧ',
  'ὰ' => 'Ὰ',
  'ά' => 'Ά',
  'ὲ' => 'Ὲ',
  'έ' => 'Έ',
  'ὴ' => 'Ὴ',
  'ή' => 'Ή',
  'ὶ' => 'Ὶ',
  'ί' => 'Ί',
  'ὸ' => 'Ὸ',
  'ό' => 'Ό',
  'ὺ' => 'Ὺ',
  'ύ' => 'Ύ',
  'ὼ' => 'Ὼ',
  'ώ' => 'Ώ',
  'ᾀ' => 'ᾈ',
  'ᾁ' => 'ᾉ',
  'ᾂ' => 'ᾊ',
  'ᾃ' => 'ᾋ',
  'ᾄ' => 'ᾌ',
  'ᾅ' => 'ᾍ',
  'ᾆ' => 'ᾎ',
  'ᾇ' => 'ᾏ',
  'ᾐ' => 'ᾘ',
  'ᾑ' => 'ᾙ',
  'ᾒ' => 'ᾚ',
  'ᾓ' => 'ᾛ',
  'ᾔ' => 'ᾜ',
  'ᾕ' => 'ᾝ',
  'ᾖ' => 'ᾞ',
  'ᾗ' => 'ᾟ',
  'ᾠ' => 'ᾨ',
  'ᾡ' => 'ᾩ',
  'ᾢ' => 'ᾪ',
  'ᾣ' => 'ᾫ',
  'ᾤ' => 'ᾬ',
  'ᾥ' => 'ᾭ',
  'ᾦ' => 'ᾮ',
  'ᾧ' => 'ᾯ',
  'ᾰ' => 'Ᾰ',
  'ᾱ' => 'Ᾱ',
  'ᾳ' => 'ᾼ',
  'ι' => 'Ι',
  'ῃ' => 'ῌ',
  'ῐ' => 'Ῐ',
  'ῑ' => 'Ῑ',
  'ῠ' => 'Ῠ',
  'ῡ' => 'Ῡ',
  'ῥ' => 'Ῥ',
  'ῳ' => 'ῼ',
  'ⅎ' => 'Ⅎ',
  'ⅰ' => 'Ⅰ',
  'ⅱ' => 'Ⅱ',
  'ⅲ' => 'Ⅲ',
  'ⅳ' => 'Ⅳ',
  'ⅴ' => 'Ⅴ',
  'ⅵ' => 'Ⅵ',
  'ⅶ' => 'Ⅶ',
  'ⅷ' => 'Ⅷ',
  'ⅸ' => 'Ⅸ',
  'ⅹ' => 'Ⅹ',
  'ⅺ' => 'Ⅺ',
  'ⅻ' => 'Ⅻ',
  'ⅼ' => 'Ⅼ',
  'ⅽ' => 'Ⅽ',
  'ⅾ' => 'Ⅾ',
  'ⅿ' => 'Ⅿ',
  'ↄ' => 'Ↄ',
  'ⓐ' => 'Ⓐ',
  'ⓑ' => 'Ⓑ',
  'ⓒ' => 'Ⓒ',
  'ⓓ' => 'Ⓓ',
  'ⓔ' => 'Ⓔ',
  'ⓕ' => 'Ⓕ',
  'ⓖ' => 'Ⓖ',
  'ⓗ' => 'Ⓗ',
  'ⓘ' => 'Ⓘ',
  'ⓙ' => 'Ⓙ',
  'ⓚ' => 'Ⓚ',
  'ⓛ' => 'Ⓛ',
  'ⓜ' => 'Ⓜ',
  'ⓝ' => 'Ⓝ',
  'ⓞ' => 'Ⓞ',
  'ⓟ' => 'Ⓟ',
  'ⓠ' => 'Ⓠ',
  'ⓡ' => 'Ⓡ',
  'ⓢ' => 'Ⓢ',
  'ⓣ' => 'Ⓣ',
  'ⓤ' => 'Ⓤ',
  'ⓥ' => 'Ⓥ',
  'ⓦ' => 'Ⓦ',
  'ⓧ' => 'Ⓧ',
  'ⓨ' => 'Ⓨ',
  'ⓩ' => 'Ⓩ',
  'ⰰ' => 'Ⰰ',
  'ⰱ' => 'Ⰱ',
  'ⰲ' => 'Ⰲ',
  'ⰳ' => 'Ⰳ',
  'ⰴ' => 'Ⰴ',
  'ⰵ' => 'Ⰵ',
  'ⰶ' => 'Ⰶ',
  'ⰷ' => 'Ⰷ',
  'ⰸ' => 'Ⰸ',
  'ⰹ' => 'Ⰹ',
  'ⰺ' => 'Ⰺ',
  'ⰻ' => 'Ⰻ',
  'ⰼ' => 'Ⰼ',
  'ⰽ' => 'Ⰽ',
  'ⰾ' => 'Ⰾ',
  'ⰿ' => 'Ⰿ',
  'ⱀ' => 'Ⱀ',
  'ⱁ' => 'Ⱁ',
  'ⱂ' => 'Ⱂ',
  'ⱃ' => 'Ⱃ',
  'ⱄ' => 'Ⱄ',
  'ⱅ' => 'Ⱅ',
  'ⱆ' => 'Ⱆ',
  'ⱇ' => 'Ⱇ',
  'ⱈ' => 'Ⱈ',
  'ⱉ' => 'Ⱉ',
  'ⱊ' => 'Ⱊ',
  'ⱋ' => 'Ⱋ',
  'ⱌ' => 'Ⱌ',
  'ⱍ' => 'Ⱍ',
  'ⱎ' => 'Ⱎ',
  'ⱏ' => 'Ⱏ',
  'ⱐ' => 'Ⱐ',
  'ⱑ' => 'Ⱑ',
  'ⱒ' => 'Ⱒ',
  'ⱓ' => 'Ⱓ',
  'ⱔ' => 'Ⱔ',
  'ⱕ' => 'Ⱕ',
  'ⱖ' => 'Ⱖ',
  'ⱗ' => 'Ⱗ',
  'ⱘ' => 'Ⱘ',
  'ⱙ' => 'Ⱙ',
  'ⱚ' => 'Ⱚ',
  'ⱛ' => 'Ⱛ',
  'ⱜ' => 'Ⱜ',
  'ⱝ' => 'Ⱝ',
  'ⱞ' => 'Ⱞ',
  'ⱡ' => 'Ⱡ',
  'ⱥ' => 'Ⱥ',
  'ⱦ' => 'Ⱦ',
  'ⱨ' => 'Ⱨ',
  'ⱪ' => 'Ⱪ',
  'ⱬ' => 'Ⱬ',
  'ⱳ' => 'Ⱳ',
  'ⱶ' => 'Ⱶ',
  'ⲁ' => 'Ⲁ',
  'ⲃ' => 'Ⲃ',
  'ⲅ' => 'Ⲅ',
  'ⲇ' => 'Ⲇ',
  'ⲉ' => 'Ⲉ',
  'ⲋ' => 'Ⲋ',
  'ⲍ' => 'Ⲍ',
  'ⲏ' => 'Ⲏ',
  'ⲑ' => 'Ⲑ',
  'ⲓ' => 'Ⲓ',
  'ⲕ' => 'Ⲕ',
  'ⲗ' => 'Ⲗ',
  'ⲙ' => 'Ⲙ',
  'ⲛ' => 'Ⲛ',
  'ⲝ' => 'Ⲝ',
  'ⲟ' => 'Ⲟ',
  'ⲡ' => 'Ⲡ',
  'ⲣ' => 'Ⲣ',
  'ⲥ' => 'Ⲥ',
  'ⲧ' => 'Ⲧ',
  'ⲩ' => 'Ⲩ',
  'ⲫ' => 'Ⲫ',
  'ⲭ' => 'Ⲭ',
  'ⲯ' => 'Ⲯ',
  'ⲱ' => 'Ⲱ',
  'ⲳ' => 'Ⲳ',
  'ⲵ' => 'Ⲵ',
  'ⲷ' => 'Ⲷ',
  'ⲹ' => 'Ⲹ',
  'ⲻ' => 'Ⲻ',
  'ⲽ' => 'Ⲽ',
  'ⲿ' => 'Ⲿ',
  'ⳁ' => 'Ⳁ',
  'ⳃ' => 'Ⳃ',
  'ⳅ' => 'Ⳅ',
  'ⳇ' => 'Ⳇ',
  'ⳉ' => 'Ⳉ',
  'ⳋ' => 'Ⳋ',
  'ⳍ' => 'Ⳍ',
  'ⳏ' => 'Ⳏ',
  'ⳑ' => 'Ⳑ',
  'ⳓ' => 'Ⳓ',
  'ⳕ' => 'Ⳕ',
  'ⳗ' => 'Ⳗ',
  'ⳙ' => 'Ⳙ',
  'ⳛ' => 'Ⳛ',
  'ⳝ' => 'Ⳝ',
  'ⳟ' => 'Ⳟ',
  'ⳡ' => 'Ⳡ',
  'ⳣ' => 'Ⳣ',
  'ⳬ' => 'Ⳬ',
  'ⳮ' => 'Ⳮ',
  'ⳳ' => 'Ⳳ',
  'ⴀ' => 'Ⴀ',
  'ⴁ' => 'Ⴁ',
  'ⴂ' => 'Ⴂ',
  'ⴃ' => 'Ⴃ',
  'ⴄ' => 'Ⴄ',
  'ⴅ' => 'Ⴅ',
  'ⴆ' => 'Ⴆ',
  'ⴇ' => 'Ⴇ',
  'ⴈ' => 'Ⴈ',
  'ⴉ' => 'Ⴉ',
  'ⴊ' => 'Ⴊ',
  'ⴋ' => 'Ⴋ',
  'ⴌ' => 'Ⴌ',
  'ⴍ' => 'Ⴍ',
  'ⴎ' => 'Ⴎ',
  'ⴏ' => 'Ⴏ',
  'ⴐ' => 'Ⴐ',
  'ⴑ' => 'Ⴑ',
  'ⴒ' => 'Ⴒ',
  'ⴓ' => 'Ⴓ',
  'ⴔ' => 'Ⴔ',
  'ⴕ' => 'Ⴕ',
  'ⴖ' => 'Ⴖ',
  'ⴗ' => 'Ⴗ',
  'ⴘ' => 'Ⴘ',
  'ⴙ' => 'Ⴙ',
  'ⴚ' => 'Ⴚ',
  'ⴛ' => 'Ⴛ',
  'ⴜ' => 'Ⴜ',
  'ⴝ' => 'Ⴝ',
  'ⴞ' => 'Ⴞ',
  'ⴟ' => 'Ⴟ',
  'ⴠ' => 'Ⴠ',
  'ⴡ' => 'Ⴡ',
  'ⴢ' => 'Ⴢ',
  'ⴣ' => 'Ⴣ',
  'ⴤ' => 'Ⴤ',
  'ⴥ' => 'Ⴥ',
  'ⴧ' => 'Ⴧ',
  'ⴭ' => 'Ⴭ',
  'ꙁ' => 'Ꙁ',
  'ꙃ' => 'Ꙃ',
  'ꙅ' => 'Ꙅ',
  'ꙇ' => 'Ꙇ',
  'ꙉ' => 'Ꙉ',
  'ꙋ' => 'Ꙋ',
  'ꙍ' => 'Ꙍ',
  'ꙏ' => 'Ꙏ',
  'ꙑ' => 'Ꙑ',
  'ꙓ' => 'Ꙓ',
  'ꙕ' => 'Ꙕ',
  'ꙗ' => 'Ꙗ',
  'ꙙ' => 'Ꙙ',
  'ꙛ' => 'Ꙛ',
  'ꙝ' => 'Ꙝ',
  'ꙟ' => 'Ꙟ',
  'ꙡ' => 'Ꙡ',
  'ꙣ' => 'Ꙣ',
  'ꙥ' => 'Ꙥ',
  'ꙧ' => 'Ꙧ',
  'ꙩ' => 'Ꙩ',
  'ꙫ' => 'Ꙫ',
  'ꙭ' => 'Ꙭ',
  'ꚁ' => 'Ꚁ',
  'ꚃ' => 'Ꚃ',
  'ꚅ' => 'Ꚅ',
  'ꚇ' => 'Ꚇ',
  'ꚉ' => 'Ꚉ',
  'ꚋ' => 'Ꚋ',
  'ꚍ' => 'Ꚍ',
  'ꚏ' => 'Ꚏ',
  'ꚑ' => 'Ꚑ',
  'ꚓ' => 'Ꚓ',
  'ꚕ' => 'Ꚕ',
  'ꚗ' => 'Ꚗ',
  'ꚙ' => 'Ꚙ',
  'ꚛ' => 'Ꚛ',
  'ꜣ' => 'Ꜣ',
  'ꜥ' => 'Ꜥ',
  'ꜧ' => 'Ꜧ',
  'ꜩ' => 'Ꜩ',
  'ꜫ' => 'Ꜫ',
  'ꜭ' => 'Ꜭ',
  'ꜯ' => 'Ꜯ',
  'ꜳ' => 'Ꜳ',
  'ꜵ' => 'Ꜵ',
  'ꜷ' => 'Ꜷ',
  'ꜹ' => 'Ꜹ',
  'ꜻ' => 'Ꜻ',
  'ꜽ' => 'Ꜽ',
  'ꜿ' => 'Ꜿ',
  'ꝁ' => 'Ꝁ',
  'ꝃ' => 'Ꝃ',
  'ꝅ' => 'Ꝅ',
  'ꝇ' => 'Ꝇ',
  'ꝉ' => 'Ꝉ',
  'ꝋ' => 'Ꝋ',
  'ꝍ' => 'Ꝍ',
  'ꝏ' => 'Ꝏ',
  'ꝑ' => 'Ꝑ',
  'ꝓ' => 'Ꝓ',
  'ꝕ' => 'Ꝕ',
  'ꝗ' => 'Ꝗ',
  'ꝙ' => 'Ꝙ',
  'ꝛ' => 'Ꝛ',
  'ꝝ' => 'Ꝝ',
  'ꝟ' => 'Ꝟ',
  'ꝡ' => 'Ꝡ',
  'ꝣ' => 'Ꝣ',
  'ꝥ' => 'Ꝥ',
  'ꝧ' => 'Ꝧ',
  'ꝩ' => 'Ꝩ',
  'ꝫ' => 'Ꝫ',
  'ꝭ' => 'Ꝭ',
  'ꝯ' => 'Ꝯ',
  'ꝺ' => 'Ꝺ',
  'ꝼ' => 'Ꝼ',
  'ꝿ' => 'Ꝿ',
  'ꞁ' => 'Ꞁ',
  'ꞃ' => 'Ꞃ',
  'ꞅ' => 'Ꞅ',
  'ꞇ' => 'Ꞇ',
  'ꞌ' => 'Ꞌ',
  'ꞑ' => 'Ꞑ',
  'ꞓ' => 'Ꞓ',
  'ꞔ' => 'Ꞔ',
  'ꞗ' => 'Ꞗ',
  'ꞙ' => 'Ꞙ',
  'ꞛ' => 'Ꞛ',
  'ꞝ' => 'Ꞝ',
  'ꞟ' => 'Ꞟ',
  'ꞡ' => 'Ꞡ',
  'ꞣ' => 'Ꞣ',
  'ꞥ' => 'Ꞥ',
  'ꞧ' => 'Ꞧ',
  'ꞩ' => 'Ꞩ',
  'ꞵ' => 'Ꞵ',
  'ꞷ' => 'Ꞷ',
  'ꞹ' => 'Ꞹ',
  'ꞻ' => 'Ꞻ',
  'ꞽ' => 'Ꞽ',
  'ꞿ' => 'Ꞿ',
  'ꟃ' => 'Ꟃ',
  'ꟈ' => 'Ꟈ',
  'ꟊ' => 'Ꟊ',
  'ꟶ' => 'Ꟶ',
  'ꭓ' => 'Ꭓ',
  'ꭰ' => 'Ꭰ',
  'ꭱ' => 'Ꭱ',
  'ꭲ' => 'Ꭲ',
  'ꭳ' => 'Ꭳ',
  'ꭴ' => 'Ꭴ',
  'ꭵ' => 'Ꭵ',
  'ꭶ' => 'Ꭶ',
  'ꭷ' => 'Ꭷ',
  'ꭸ' => 'Ꭸ',
  'ꭹ' => 'Ꭹ',
  'ꭺ' => 'Ꭺ',
  'ꭻ' => 'Ꭻ',
  'ꭼ' => 'Ꭼ',
  'ꭽ' => 'Ꭽ',
  'ꭾ' => 'Ꭾ',
  'ꭿ' => 'Ꭿ',
  'ꮀ' => 'Ꮀ',
  'ꮁ' => 'Ꮁ',
  'ꮂ' => 'Ꮂ',
  'ꮃ' => 'Ꮃ',
  'ꮄ' => 'Ꮄ',
  'ꮅ' => 'Ꮅ',
  'ꮆ' => 'Ꮆ',
  'ꮇ' => 'Ꮇ',
  'ꮈ' => 'Ꮈ',
  'ꮉ' => 'Ꮉ',
  'ꮊ' => 'Ꮊ',
  'ꮋ' => 'Ꮋ',
  'ꮌ' => 'Ꮌ',
  'ꮍ' => 'Ꮍ',
  'ꮎ' => 'Ꮎ',
  'ꮏ' => 'Ꮏ',
  'ꮐ' => 'Ꮐ',
  'ꮑ' => 'Ꮑ',
  'ꮒ' => 'Ꮒ',
  'ꮓ' => 'Ꮓ',
  'ꮔ' => 'Ꮔ',
  'ꮕ' => 'Ꮕ',
  'ꮖ' => 'Ꮖ',
  'ꮗ' => 'Ꮗ',
  'ꮘ' => 'Ꮘ',
  'ꮙ' => 'Ꮙ',
  'ꮚ' => 'Ꮚ',
  'ꮛ' => 'Ꮛ',
  'ꮜ' => 'Ꮜ',
  'ꮝ' => 'Ꮝ',
  'ꮞ' => 'Ꮞ',
  'ꮟ' => 'Ꮟ',
  'ꮠ' => 'Ꮠ',
  'ꮡ' => 'Ꮡ',
  'ꮢ' => 'Ꮢ',
  'ꮣ' => 'Ꮣ',
  'ꮤ' => 'Ꮤ',
  'ꮥ' => 'Ꮥ',
  'ꮦ' => 'Ꮦ',
  'ꮧ' => 'Ꮧ',
  'ꮨ' => 'Ꮨ',
  'ꮩ' => 'Ꮩ',
  'ꮪ' => 'Ꮪ',
  'ꮫ' => 'Ꮫ',
  'ꮬ' => 'Ꮬ',
  'ꮭ' => 'Ꮭ',
  'ꮮ' => 'Ꮮ',
  'ꮯ' => 'Ꮯ',
  'ꮰ' => 'Ꮰ',
  'ꮱ' => 'Ꮱ',
  'ꮲ' => 'Ꮲ',
  'ꮳ' => 'Ꮳ',
  'ꮴ' => 'Ꮴ',
  'ꮵ' => 'Ꮵ',
  'ꮶ' => 'Ꮶ',
  'ꮷ' => 'Ꮷ',
  'ꮸ' => 'Ꮸ',
  'ꮹ' => 'Ꮹ',
  'ꮺ' => 'Ꮺ',
  'ꮻ' => 'Ꮻ',
  'ꮼ' => 'Ꮼ',
  'ꮽ' => 'Ꮽ',
  'ꮾ' => 'Ꮾ',
  'ꮿ' => 'Ꮿ',
  'a' => 'A',
  'b' => 'B',
  'c' => 'C',
  'd' => 'D',
  'e' => 'E',
  'f' => 'F',
  'g' => 'G',
  'h' => 'H',
  'i' => 'I',
  'j' => 'J',
  'k' => 'K',
  'l' => 'L',
  'm' => 'M',
  'n' => 'N',
  'o' => 'O',
  'p' => 'P',
  'q' => 'Q',
  'r' => 'R',
  's' => 'S',
  't' => 'T',
  'u' => 'U',
  'v' => 'V',
  'w' => 'W',
  'x' => 'X',
  'y' => 'Y',
  'z' => 'Z',
  '𐐨' => '𐐀',
  '𐐩' => '𐐁',
  '𐐪' => '𐐂',
  '𐐫' => '𐐃',
  '𐐬' => '𐐄',
  '𐐭' => '𐐅',
  '𐐮' => '𐐆',
  '𐐯' => '𐐇',
  '𐐰' => '𐐈',
  '𐐱' => '𐐉',
  '𐐲' => '𐐊',
  '𐐳' => '𐐋',
  '𐐴' => '𐐌',
  '𐐵' => '𐐍',
  '𐐶' => '𐐎',
  '𐐷' => '𐐏',
  '𐐸' => '𐐐',
  '𐐹' => '𐐑',
  '𐐺' => '𐐒',
  '𐐻' => '𐐓',
  '𐐼' => '𐐔',
  '𐐽' => '𐐕',
  '𐐾' => '𐐖',
  '𐐿' => '𐐗',
  '𐑀' => '𐐘',
  '𐑁' => '𐐙',
  '𐑂' => '𐐚',
  '𐑃' => '𐐛',
  '𐑄' => '𐐜',
  '𐑅' => '𐐝',
  '𐑆' => '𐐞',
  '𐑇' => '𐐟',
  '𐑈' => '𐐠',
  '𐑉' => '𐐡',
  '𐑊' => '𐐢',
  '𐑋' => '𐐣',
  '𐑌' => '𐐤',
  '𐑍' => '𐐥',
  '𐑎' => '𐐦',
  '𐑏' => '𐐧',
  '𐓘' => '𐒰',
  '𐓙' => '𐒱',
  '𐓚' => '𐒲',
  '𐓛' => '𐒳',
  '𐓜' => '𐒴',
  '𐓝' => '𐒵',
  '𐓞' => '𐒶',
  '𐓟' => '𐒷',
  '𐓠' => '𐒸',
  '𐓡' => '𐒹',
  '𐓢' => '𐒺',
  '𐓣' => '𐒻',
  '𐓤' => '𐒼',
  '𐓥' => '𐒽',
  '𐓦' => '𐒾',
  '𐓧' => '𐒿',
  '𐓨' => '𐓀',
  '𐓩' => '𐓁',
  '𐓪' => '𐓂',
  '𐓫' => '𐓃',
  '𐓬' => '𐓄',
  '𐓭' => '𐓅',
  '𐓮' => '𐓆',
  '𐓯' => '𐓇',
  '𐓰' => '𐓈',
  '𐓱' => '𐓉',
  '𐓲' => '𐓊',
  '𐓳' => '𐓋',
  '𐓴' => '𐓌',
  '𐓵' => '𐓍',
  '𐓶' => '𐓎',
  '𐓷' => '𐓏',
  '𐓸' => '𐓐',
  '𐓹' => '𐓑',
  '𐓺' => '𐓒',
  '𐓻' => '𐓓',
  '𐳀' => '𐲀',
  '𐳁' => '𐲁',
  '𐳂' => '𐲂',
  '𐳃' => '𐲃',
  '𐳄' => '𐲄',
  '𐳅' => '𐲅',
  '𐳆' => '𐲆',
  '𐳇' => '𐲇',
  '𐳈' => '𐲈',
  '𐳉' => '𐲉',
  '𐳊' => '𐲊',
  '𐳋' => '𐲋',
  '𐳌' => '𐲌',
  '𐳍' => '𐲍',
  '𐳎' => '𐲎',
  '𐳏' => '𐲏',
  '𐳐' => '𐲐',
  '𐳑' => '𐲑',
  '𐳒' => '𐲒',
  '𐳓' => '𐲓',
  '𐳔' => '𐲔',
  '𐳕' => '𐲕',
  '𐳖' => '𐲖',
  '𐳗' => '𐲗',
  '𐳘' => '𐲘',
  '𐳙' => '𐲙',
  '𐳚' => '𐲚',
  '𐳛' => '𐲛',
  '𐳜' => '𐲜',
  '𐳝' => '𐲝',
  '𐳞' => '𐲞',
  '𐳟' => '𐲟',
  '𐳠' => '𐲠',
  '𐳡' => '𐲡',
  '𐳢' => '𐲢',
  '𐳣' => '𐲣',
  '𐳤' => '𐲤',
  '𐳥' => '𐲥',
  '𐳦' => '𐲦',
  '𐳧' => '𐲧',
  '𐳨' => '𐲨',
  '𐳩' => '𐲩',
  '𐳪' => '𐲪',
  '𐳫' => '𐲫',
  '𐳬' => '𐲬',
  '𐳭' => '𐲭',
  '𐳮' => '𐲮',
  '𐳯' => '𐲯',
  '𐳰' => '𐲰',
  '𐳱' => '𐲱',
  '𐳲' => '𐲲',
  '𑣀' => '𑢠',
  '𑣁' => '𑢡',
  '𑣂' => '𑢢',
  '𑣃' => '𑢣',
  '𑣄' => '𑢤',
  '𑣅' => '𑢥',
  '𑣆' => '𑢦',
  '𑣇' => '𑢧',
  '𑣈' => '𑢨',
  '𑣉' => '𑢩',
  '𑣊' => '𑢪',
  '𑣋' => '𑢫',
  '𑣌' => '𑢬',
  '𑣍' => '𑢭',
  '𑣎' => '𑢮',
  '𑣏' => '𑢯',
  '𑣐' => '𑢰',
  '𑣑' => '𑢱',
  '𑣒' => '𑢲',
  '𑣓' => '𑢳',
  '𑣔' => '𑢴',
  '𑣕' => '𑢵',
  '𑣖' => '𑢶',
  '𑣗' => '𑢷',
  '𑣘' => '𑢸',
  '𑣙' => '𑢹',
  '𑣚' => '𑢺',
  '𑣛' => '𑢻',
  '𑣜' => '𑢼',
  '𑣝' => '𑢽',
  '𑣞' => '𑢾',
  '𑣟' => '𑢿',
  '𖹠' => '𖹀',
  '𖹡' => '𖹁',
  '𖹢' => '𖹂',
  '𖹣' => '𖹃',
  '𖹤' => '𖹄',
  '𖹥' => '𖹅',
  '𖹦' => '𖹆',
  '𖹧' => '𖹇',
  '𖹨' => '𖹈',
  '𖹩' => '𖹉',
  '𖹪' => '𖹊',
  '𖹫' => '𖹋',
  '𖹬' => '𖹌',
  '𖹭' => '𖹍',
  '𖹮' => '𖹎',
  '𖹯' => '𖹏',
  '𖹰' => '𖹐',
  '𖹱' => '𖹑',
  '𖹲' => '𖹒',
  '𖹳' => '𖹓',
  '𖹴' => '𖹔',
  '𖹵' => '𖹕',
  '𖹶' => '𖹖',
  '𖹷' => '𖹗',
  '𖹸' => '𖹘',
  '𖹹' => '𖹙',
  '𖹺' => '𖹚',
  '𖹻' => '𖹛',
  '𖹼' => '𖹜',
  '𖹽' => '𖹝',
  '𖹾' => '𖹞',
  '𖹿' => '𖹟',
  '𞤢' => '𞤀',
  '𞤣' => '𞤁',
  '𞤤' => '𞤂',
  '𞤥' => '𞤃',
  '𞤦' => '𞤄',
  '𞤧' => '𞤅',
  '𞤨' => '𞤆',
  '𞤩' => '𞤇',
  '𞤪' => '𞤈',
  '𞤫' => '𞤉',
  '𞤬' => '𞤊',
  '𞤭' => '𞤋',
  '𞤮' => '𞤌',
  '𞤯' => '𞤍',
  '𞤰' => '𞤎',
  '𞤱' => '𞤏',
  '𞤲' => '𞤐',
  '𞤳' => '𞤑',
  '𞤴' => '𞤒',
  '𞤵' => '𞤓',
  '𞤶' => '𞤔',
  '𞤷' => '𞤕',
  '𞤸' => '𞤖',
  '𞤹' => '𞤗',
  '𞤺' => '𞤘',
  '𞤻' => '𞤙',
  '𞤼' => '𞤚',
  '𞤽' => '𞤛',
  '𞤾' => '𞤜',
  '𞤿' => '𞤝',
  '𞥀' => '𞤞',
  '𞥁' => '𞤟',
  '𞥂' => '𞤠',
  '𞥃' => '𞤡',
);
PKϤ$Z>|zK997polyfill-mbstring/Resources/unidata/titleCaseRegexp.phpnu�[���<?php

// from Case_Ignorable in https://unicode.org/Public/UNIDATA/DerivedCoreProperties.txt

return '/(?<![\x{0027}\x{002E}\x{003A}\x{005E}\x{0060}\x{00A8}\x{00AD}\x{00AF}\x{00B4}\x{00B7}\x{00B8}\x{02B0}-\x{02C1}\x{02C2}-\x{02C5}\x{02C6}-\x{02D1}\x{02D2}-\x{02DF}\x{02E0}-\x{02E4}\x{02E5}-\x{02EB}\x{02EC}\x{02ED}\x{02EE}\x{02EF}-\x{02FF}\x{0300}-\x{036F}\x{0374}\x{0375}\x{037A}\x{0384}-\x{0385}\x{0387}\x{0483}-\x{0487}\x{0488}-\x{0489}\x{0559}\x{0591}-\x{05BD}\x{05BF}\x{05C1}-\x{05C2}\x{05C4}-\x{05C5}\x{05C7}\x{05F4}\x{0600}-\x{0605}\x{0610}-\x{061A}\x{061C}\x{0640}\x{064B}-\x{065F}\x{0670}\x{06D6}-\x{06DC}\x{06DD}\x{06DF}-\x{06E4}\x{06E5}-\x{06E6}\x{06E7}-\x{06E8}\x{06EA}-\x{06ED}\x{070F}\x{0711}\x{0730}-\x{074A}\x{07A6}-\x{07B0}\x{07EB}-\x{07F3}\x{07F4}-\x{07F5}\x{07FA}\x{07FD}\x{0816}-\x{0819}\x{081A}\x{081B}-\x{0823}\x{0824}\x{0825}-\x{0827}\x{0828}\x{0829}-\x{082D}\x{0859}-\x{085B}\x{08D3}-\x{08E1}\x{08E2}\x{08E3}-\x{0902}\x{093A}\x{093C}\x{0941}-\x{0948}\x{094D}\x{0951}-\x{0957}\x{0962}-\x{0963}\x{0971}\x{0981}\x{09BC}\x{09C1}-\x{09C4}\x{09CD}\x{09E2}-\x{09E3}\x{09FE}\x{0A01}-\x{0A02}\x{0A3C}\x{0A41}-\x{0A42}\x{0A47}-\x{0A48}\x{0A4B}-\x{0A4D}\x{0A51}\x{0A70}-\x{0A71}\x{0A75}\x{0A81}-\x{0A82}\x{0ABC}\x{0AC1}-\x{0AC5}\x{0AC7}-\x{0AC8}\x{0ACD}\x{0AE2}-\x{0AE3}\x{0AFA}-\x{0AFF}\x{0B01}\x{0B3C}\x{0B3F}\x{0B41}-\x{0B44}\x{0B4D}\x{0B56}\x{0B62}-\x{0B63}\x{0B82}\x{0BC0}\x{0BCD}\x{0C00}\x{0C04}\x{0C3E}-\x{0C40}\x{0C46}-\x{0C48}\x{0C4A}-\x{0C4D}\x{0C55}-\x{0C56}\x{0C62}-\x{0C63}\x{0C81}\x{0CBC}\x{0CBF}\x{0CC6}\x{0CCC}-\x{0CCD}\x{0CE2}-\x{0CE3}\x{0D00}-\x{0D01}\x{0D3B}-\x{0D3C}\x{0D41}-\x{0D44}\x{0D4D}\x{0D62}-\x{0D63}\x{0DCA}\x{0DD2}-\x{0DD4}\x{0DD6}\x{0E31}\x{0E34}-\x{0E3A}\x{0E46}\x{0E47}-\x{0E4E}\x{0EB1}\x{0EB4}-\x{0EB9}\x{0EBB}-\x{0EBC}\x{0EC6}\x{0EC8}-\x{0ECD}\x{0F18}-\x{0F19}\x{0F35}\x{0F37}\x{0F39}\x{0F71}-\x{0F7E}\x{0F80}-\x{0F84}\x{0F86}-\x{0F87}\x{0F8D}-\x{0F97}\x{0F99}-\x{0FBC}\x{0FC6}\x{102D}-\x{1030}\x{1032}-\x{1037}\x{1039}-\x{103A}\x{103D}-\x{103E}\x{1058}-\x{1059}\x{105E}-\x{1060}\x{1071}-\x{1074}\x{1082}\x{1085}-\x{1086}\x{108D}\x{109D}\x{10FC}\x{135D}-\x{135F}\x{1712}-\x{1714}\x{1732}-\x{1734}\x{1752}-\x{1753}\x{1772}-\x{1773}\x{17B4}-\x{17B5}\x{17B7}-\x{17BD}\x{17C6}\x{17C9}-\x{17D3}\x{17D7}\x{17DD}\x{180B}-\x{180D}\x{180E}\x{1843}\x{1885}-\x{1886}\x{18A9}\x{1920}-\x{1922}\x{1927}-\x{1928}\x{1932}\x{1939}-\x{193B}\x{1A17}-\x{1A18}\x{1A1B}\x{1A56}\x{1A58}-\x{1A5E}\x{1A60}\x{1A62}\x{1A65}-\x{1A6C}\x{1A73}-\x{1A7C}\x{1A7F}\x{1AA7}\x{1AB0}-\x{1ABD}\x{1ABE}\x{1B00}-\x{1B03}\x{1B34}\x{1B36}-\x{1B3A}\x{1B3C}\x{1B42}\x{1B6B}-\x{1B73}\x{1B80}-\x{1B81}\x{1BA2}-\x{1BA5}\x{1BA8}-\x{1BA9}\x{1BAB}-\x{1BAD}\x{1BE6}\x{1BE8}-\x{1BE9}\x{1BED}\x{1BEF}-\x{1BF1}\x{1C2C}-\x{1C33}\x{1C36}-\x{1C37}\x{1C78}-\x{1C7D}\x{1CD0}-\x{1CD2}\x{1CD4}-\x{1CE0}\x{1CE2}-\x{1CE8}\x{1CED}\x{1CF4}\x{1CF8}-\x{1CF9}\x{1D2C}-\x{1D6A}\x{1D78}\x{1D9B}-\x{1DBF}\x{1DC0}-\x{1DF9}\x{1DFB}-\x{1DFF}\x{1FBD}\x{1FBF}-\x{1FC1}\x{1FCD}-\x{1FCF}\x{1FDD}-\x{1FDF}\x{1FED}-\x{1FEF}\x{1FFD}-\x{1FFE}\x{200B}-\x{200F}\x{2018}\x{2019}\x{2024}\x{2027}\x{202A}-\x{202E}\x{2060}-\x{2064}\x{2066}-\x{206F}\x{2071}\x{207F}\x{2090}-\x{209C}\x{20D0}-\x{20DC}\x{20DD}-\x{20E0}\x{20E1}\x{20E2}-\x{20E4}\x{20E5}-\x{20F0}\x{2C7C}-\x{2C7D}\x{2CEF}-\x{2CF1}\x{2D6F}\x{2D7F}\x{2DE0}-\x{2DFF}\x{2E2F}\x{3005}\x{302A}-\x{302D}\x{3031}-\x{3035}\x{303B}\x{3099}-\x{309A}\x{309B}-\x{309C}\x{309D}-\x{309E}\x{30FC}-\x{30FE}\x{A015}\x{A4F8}-\x{A4FD}\x{A60C}\x{A66F}\x{A670}-\x{A672}\x{A674}-\x{A67D}\x{A67F}\x{A69C}-\x{A69D}\x{A69E}-\x{A69F}\x{A6F0}-\x{A6F1}\x{A700}-\x{A716}\x{A717}-\x{A71F}\x{A720}-\x{A721}\x{A770}\x{A788}\x{A789}-\x{A78A}\x{A7F8}-\x{A7F9}\x{A802}\x{A806}\x{A80B}\x{A825}-\x{A826}\x{A8C4}-\x{A8C5}\x{A8E0}-\x{A8F1}\x{A8FF}\x{A926}-\x{A92D}\x{A947}-\x{A951}\x{A980}-\x{A982}\x{A9B3}\x{A9B6}-\x{A9B9}\x{A9BC}\x{A9CF}\x{A9E5}\x{A9E6}\x{AA29}-\x{AA2E}\x{AA31}-\x{AA32}\x{AA35}-\x{AA36}\x{AA43}\x{AA4C}\x{AA70}\x{AA7C}\x{AAB0}\x{AAB2}-\x{AAB4}\x{AAB7}-\x{AAB8}\x{AABE}-\x{AABF}\x{AAC1}\x{AADD}\x{AAEC}-\x{AAED}\x{AAF3}-\x{AAF4}\x{AAF6}\x{AB5B}\x{AB5C}-\x{AB5F}\x{ABE5}\x{ABE8}\x{ABED}\x{FB1E}\x{FBB2}-\x{FBC1}\x{FE00}-\x{FE0F}\x{FE13}\x{FE20}-\x{FE2F}\x{FE52}\x{FE55}\x{FEFF}\x{FF07}\x{FF0E}\x{FF1A}\x{FF3E}\x{FF40}\x{FF70}\x{FF9E}-\x{FF9F}\x{FFE3}\x{FFF9}-\x{FFFB}\x{101FD}\x{102E0}\x{10376}-\x{1037A}\x{10A01}-\x{10A03}\x{10A05}-\x{10A06}\x{10A0C}-\x{10A0F}\x{10A38}-\x{10A3A}\x{10A3F}\x{10AE5}-\x{10AE6}\x{10D24}-\x{10D27}\x{10F46}-\x{10F50}\x{11001}\x{11038}-\x{11046}\x{1107F}-\x{11081}\x{110B3}-\x{110B6}\x{110B9}-\x{110BA}\x{110BD}\x{110CD}\x{11100}-\x{11102}\x{11127}-\x{1112B}\x{1112D}-\x{11134}\x{11173}\x{11180}-\x{11181}\x{111B6}-\x{111BE}\x{111C9}-\x{111CC}\x{1122F}-\x{11231}\x{11234}\x{11236}-\x{11237}\x{1123E}\x{112DF}\x{112E3}-\x{112EA}\x{11300}-\x{11301}\x{1133B}-\x{1133C}\x{11340}\x{11366}-\x{1136C}\x{11370}-\x{11374}\x{11438}-\x{1143F}\x{11442}-\x{11444}\x{11446}\x{1145E}\x{114B3}-\x{114B8}\x{114BA}\x{114BF}-\x{114C0}\x{114C2}-\x{114C3}\x{115B2}-\x{115B5}\x{115BC}-\x{115BD}\x{115BF}-\x{115C0}\x{115DC}-\x{115DD}\x{11633}-\x{1163A}\x{1163D}\x{1163F}-\x{11640}\x{116AB}\x{116AD}\x{116B0}-\x{116B5}\x{116B7}\x{1171D}-\x{1171F}\x{11722}-\x{11725}\x{11727}-\x{1172B}\x{1182F}-\x{11837}\x{11839}-\x{1183A}\x{11A01}-\x{11A0A}\x{11A33}-\x{11A38}\x{11A3B}-\x{11A3E}\x{11A47}\x{11A51}-\x{11A56}\x{11A59}-\x{11A5B}\x{11A8A}-\x{11A96}\x{11A98}-\x{11A99}\x{11C30}-\x{11C36}\x{11C38}-\x{11C3D}\x{11C3F}\x{11C92}-\x{11CA7}\x{11CAA}-\x{11CB0}\x{11CB2}-\x{11CB3}\x{11CB5}-\x{11CB6}\x{11D31}-\x{11D36}\x{11D3A}\x{11D3C}-\x{11D3D}\x{11D3F}-\x{11D45}\x{11D47}\x{11D90}-\x{11D91}\x{11D95}\x{11D97}\x{11EF3}-\x{11EF4}\x{16AF0}-\x{16AF4}\x{16B30}-\x{16B36}\x{16B40}-\x{16B43}\x{16F8F}-\x{16F92}\x{16F93}-\x{16F9F}\x{16FE0}-\x{16FE1}\x{1BC9D}-\x{1BC9E}\x{1BCA0}-\x{1BCA3}\x{1D167}-\x{1D169}\x{1D173}-\x{1D17A}\x{1D17B}-\x{1D182}\x{1D185}-\x{1D18B}\x{1D1AA}-\x{1D1AD}\x{1D242}-\x{1D244}\x{1DA00}-\x{1DA36}\x{1DA3B}-\x{1DA6C}\x{1DA75}\x{1DA84}\x{1DA9B}-\x{1DA9F}\x{1DAA1}-\x{1DAAF}\x{1E000}-\x{1E006}\x{1E008}-\x{1E018}\x{1E01B}-\x{1E021}\x{1E023}-\x{1E024}\x{1E026}-\x{1E02A}\x{1E8D0}-\x{1E8D6}\x{1E944}-\x{1E94A}\x{1F3FB}-\x{1F3FF}\x{E0001}\x{E0020}-\x{E007F}\x{E0100}-\x{E01EF}])(\pL)(\pL*+)/u';
PKϤ$Z)~�ί�polyfill-mbstring/bootstrap.phpnu�[���<?php

/*
 * This file is part of the Symfony package.
 *
 * (c) Fabien Potencier <fabien@symfony.com>
 *
 * For the full copyright and license information, please view the LICENSE
 * file that was distributed with this source code.
 */

use Symfony\Polyfill\Mbstring as p;

if (!function_exists('mb_convert_encoding')) {
    function mb_convert_encoding($s, $to, $from = null) { return p\Mbstring::mb_convert_encoding($s, $to, $from); }
}
if (!function_exists('mb_decode_mimeheader')) {
    function mb_decode_mimeheader($s) { return p\Mbstring::mb_decode_mimeheader($s); }
}
if (!function_exists('mb_encode_mimeheader')) {
    function mb_encode_mimeheader($s, $charset = null, $transferEnc = null, $lf = null, $indent = null) { return p\Mbstring::mb_encode_mimeheader($s, $charset, $transferEnc, $lf, $indent); }
}
if (!function_exists('mb_decode_numericentity')) {
    function mb_decode_numericentity($s, $convmap, $enc = null) { return p\Mbstring::mb_decode_numericentity($s, $convmap, $enc); }
}
if (!function_exists('mb_encode_numericentity')) {
    function mb_encode_numericentity($s, $convmap, $enc = null, $is_hex = false) { return p\Mbstring::mb_encode_numericentity($s, $convmap, $enc, $is_hex); }
}
if (!function_exists('mb_convert_case')) {
    function mb_convert_case($s, $mode, $enc = null) { return p\Mbstring::mb_convert_case($s, $mode, $enc); }
}
if (!function_exists('mb_internal_encoding')) {
    function mb_internal_encoding($enc = null) { return p\Mbstring::mb_internal_encoding($enc); }
}
if (!function_exists('mb_language')) {
    function mb_language($lang = null) { return p\Mbstring::mb_language($lang); }
}
if (!function_exists('mb_list_encodings')) {
    function mb_list_encodings() { return p\Mbstring::mb_list_encodings(); }
}
if (!function_exists('mb_encoding_aliases')) {
    function mb_encoding_aliases($encoding) { return p\Mbstring::mb_encoding_aliases($encoding); }
}
if (!function_exists('mb_check_encoding')) {
    function mb_check_encoding($var = null, $encoding = null) { return p\Mbstring::mb_check_encoding($var, $encoding); }
}
if (!function_exists('mb_detect_encoding')) {
    function mb_detect_encoding($str, $encodingList = null, $strict = false) { return p\Mbstring::mb_detect_encoding($str, $encodingList, $strict); }
}
if (!function_exists('mb_detect_order')) {
    function mb_detect_order($encodingList = null) { return p\Mbstring::mb_detect_order($encodingList); }
}
if (!function_exists('mb_parse_str')) {
    function mb_parse_str($s, &$result = array()) { parse_str($s, $result); }
}
if (!function_exists('mb_strlen')) {
    function mb_strlen($s, $enc = null) { return p\Mbstring::mb_strlen($s, $enc); }
}
if (!function_exists('mb_strpos')) {
    function mb_strpos($s, $needle, $offset = 0, $enc = null) { return p\Mbstring::mb_strpos($s, $needle, $offset, $enc); }
}
if (!function_exists('mb_strtolower')) {
    function mb_strtolower($s, $enc = null) { return p\Mbstring::mb_strtolower($s, $enc); }
}
if (!function_exists('mb_strtoupper')) {
    function mb_strtoupper($s, $enc = null) { return p\Mbstring::mb_strtoupper($s, $enc); }
}
if (!function_exists('mb_substitute_character')) {
    function mb_substitute_character($char = null) { return p\Mbstring::mb_substitute_character($char); }
}
if (!function_exists('mb_substr')) {
    function mb_substr($s, $start, $length = 2147483647, $enc = null) { return p\Mbstring::mb_substr($s, $start, $length, $enc); }
}
if (!function_exists('mb_stripos')) {
    function mb_stripos($s, $needle, $offset = 0, $enc = null) { return p\Mbstring::mb_stripos($s, $needle, $offset, $enc); }
}
if (!function_exists('mb_stristr')) {
    function mb_stristr($s, $needle, $part = false, $enc = null) { return p\Mbstring::mb_stristr($s, $needle, $part, $enc); }
}
if (!function_exists('mb_strrchr')) {
    function mb_strrchr($s, $needle, $part = false, $enc = null) { return p\Mbstring::mb_strrchr($s, $needle, $part, $enc); }
}
if (!function_exists('mb_strrichr')) {
    function mb_strrichr($s, $needle, $part = false, $enc = null) { return p\Mbstring::mb_strrichr($s, $needle, $part, $enc); }
}
if (!function_exists('mb_strripos')) {
    function mb_strripos($s, $needle, $offset = 0, $enc = null) { return p\Mbstring::mb_strripos($s, $needle, $offset, $enc); }
}
if (!function_exists('mb_strrpos')) {
    function mb_strrpos($s, $needle, $offset = 0, $enc = null) { return p\Mbstring::mb_strrpos($s, $needle, $offset, $enc); }
}
if (!function_exists('mb_strstr')) {
    function mb_strstr($s, $needle, $part = false, $enc = null) { return p\Mbstring::mb_strstr($s, $needle, $part, $enc); }
}
if (!function_exists('mb_get_info')) {
    function mb_get_info($type = 'all') { return p\Mbstring::mb_get_info($type); }
}
if (!function_exists('mb_http_output')) {
    function mb_http_output($enc = null) { return p\Mbstring::mb_http_output($enc); }
}
if (!function_exists('mb_strwidth')) {
    function mb_strwidth($s, $enc = null) { return p\Mbstring::mb_strwidth($s, $enc); }
}
if (!function_exists('mb_substr_count')) {
    function mb_substr_count($haystack, $needle, $enc = null) { return p\Mbstring::mb_substr_count($haystack, $needle, $enc); }
}
if (!function_exists('mb_output_handler')) {
    function mb_output_handler($contents, $status) { return p\Mbstring::mb_output_handler($contents, $status); }
}
if (!function_exists('mb_http_input')) {
    function mb_http_input($type = '') { return p\Mbstring::mb_http_input($type); }
}
if (!function_exists('mb_convert_variables')) {
    function mb_convert_variables($toEncoding, $fromEncoding, &$a = null, &$b = null, &$c = null, &$d = null, &$e = null, &$f = null) { return p\Mbstring::mb_convert_variables($toEncoding, $fromEncoding, $a, $b, $c, $d, $e, $f); }
}
if (!function_exists('mb_ord')) {
    function mb_ord($s, $enc = null) { return p\Mbstring::mb_ord($s, $enc); }
}
if (!function_exists('mb_chr')) {
    function mb_chr($code, $enc = null) { return p\Mbstring::mb_chr($code, $enc); }
}
if (!function_exists('mb_scrub')) {
    function mb_scrub($s, $enc = null) { $enc = null === $enc ? mb_internal_encoding() : $enc; return mb_convert_encoding($s, $enc, $enc); }
}
if (!function_exists('mb_str_split')) {
    function mb_str_split($string, $split_length = 1, $encoding = null) { return p\Mbstring::mb_str_split($string, $split_length, $encoding); }
}

if (extension_loaded('mbstring')) {
    return;
}

if (!defined('MB_CASE_UPPER')) {
    define('MB_CASE_UPPER', 0);
}
if (!defined('MB_CASE_LOWER')) {
    define('MB_CASE_LOWER', 1);
}
if (!defined('MB_CASE_TITLE')) {
    define('MB_CASE_TITLE', 2);
}
PKϤ$Z�\�))polyfill-mbstring/LICENSEnu�[���Copyright (c) 2015-2019 Fabien Potencier

Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is furnished
to do so, subject to the following conditions:

The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.

THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
THE SOFTWARE.
PKϤ$Z��'�m�mpolyfill-mbstring/Mbstring.phpnu�[���<?php

/*
 * This file is part of the Symfony package.
 *
 * (c) Fabien Potencier <fabien@symfony.com>
 *
 * For the full copyright and license information, please view the LICENSE
 * file that was distributed with this source code.
 */

namespace Symfony\Polyfill\Mbstring;

/**
 * Partial mbstring implementation in PHP, iconv based, UTF-8 centric.
 *
 * Implemented:
 * - mb_chr                  - Returns a specific character from its Unicode code point
 * - mb_convert_encoding     - Convert character encoding
 * - mb_convert_variables    - Convert character code in variable(s)
 * - mb_decode_mimeheader    - Decode string in MIME header field
 * - mb_encode_mimeheader    - Encode string for MIME header XXX NATIVE IMPLEMENTATION IS REALLY BUGGED
 * - mb_decode_numericentity - Decode HTML numeric string reference to character
 * - mb_encode_numericentity - Encode character to HTML numeric string reference
 * - mb_convert_case         - Perform case folding on a string
 * - mb_detect_encoding      - Detect character encoding
 * - mb_get_info             - Get internal settings of mbstring
 * - mb_http_input           - Detect HTTP input character encoding
 * - mb_http_output          - Set/Get HTTP output character encoding
 * - mb_internal_encoding    - Set/Get internal character encoding
 * - mb_list_encodings       - Returns an array of all supported encodings
 * - mb_ord                  - Returns the Unicode code point of a character
 * - mb_output_handler       - Callback function converts character encoding in output buffer
 * - mb_scrub                - Replaces ill-formed byte sequences with substitute characters
 * - mb_strlen               - Get string length
 * - mb_strpos               - Find position of first occurrence of string in a string
 * - mb_strrpos              - Find position of last occurrence of a string in a string
 * - mb_str_split            - Convert a string to an array
 * - mb_strtolower           - Make a string lowercase
 * - mb_strtoupper           - Make a string uppercase
 * - mb_substitute_character - Set/Get substitution character
 * - mb_substr               - Get part of string
 * - mb_stripos              - Finds position of first occurrence of a string within another, case insensitive
 * - mb_stristr              - Finds first occurrence of a string within another, case insensitive
 * - mb_strrchr              - Finds the last occurrence of a character in a string within another
 * - mb_strrichr             - Finds the last occurrence of a character in a string within another, case insensitive
 * - mb_strripos             - Finds position of last occurrence of a string within another, case insensitive
 * - mb_strstr               - Finds first occurrence of a string within another
 * - mb_strwidth             - Return width of string
 * - mb_substr_count         - Count the number of substring occurrences
 *
 * Not implemented:
 * - mb_convert_kana         - Convert "kana" one from another ("zen-kaku", "han-kaku" and more)
 * - mb_ereg_*               - Regular expression with multibyte support
 * - mb_parse_str            - Parse GET/POST/COOKIE data and set global variable
 * - mb_preferred_mime_name  - Get MIME charset string
 * - mb_regex_encoding       - Returns current encoding for multibyte regex as string
 * - mb_regex_set_options    - Set/Get the default options for mbregex functions
 * - mb_send_mail            - Send encoded mail
 * - mb_split                - Split multibyte string using regular expression
 * - mb_strcut               - Get part of string
 * - mb_strimwidth           - Get truncated string with specified width
 *
 * @author Nicolas Grekas <p@tchwork.com>
 *
 * @internal
 */
final class Mbstring
{
    const MB_CASE_FOLD = PHP_INT_MAX;

    private static $encodingList = array('ASCII', 'UTF-8');
    private static $language = 'neutral';
    private static $internalEncoding = 'UTF-8';
    private static $caseFold = array(
        array('µ', 'ſ', "\xCD\x85", 'ς', "\xCF\x90", "\xCF\x91", "\xCF\x95", "\xCF\x96", "\xCF\xB0", "\xCF\xB1", "\xCF\xB5", "\xE1\xBA\x9B", "\xE1\xBE\xBE"),
        array('μ', 's', 'ι',        'σ', 'β',        'θ',        'φ',        'π',        'κ',        'ρ',        'ε',        "\xE1\xB9\xA1", 'ι'),
    );

    public static function mb_convert_encoding($s, $toEncoding, $fromEncoding = null)
    {
        if (\is_array($fromEncoding) || false !== strpos($fromEncoding, ',')) {
            $fromEncoding = self::mb_detect_encoding($s, $fromEncoding);
        } else {
            $fromEncoding = self::getEncoding($fromEncoding);
        }

        $toEncoding = self::getEncoding($toEncoding);

        if ('BASE64' === $fromEncoding) {
            $s = base64_decode($s);
            $fromEncoding = $toEncoding;
        }

        if ('BASE64' === $toEncoding) {
            return base64_encode($s);
        }

        if ('HTML-ENTITIES' === $toEncoding || 'HTML' === $toEncoding) {
            if ('HTML-ENTITIES' === $fromEncoding || 'HTML' === $fromEncoding) {
                $fromEncoding = 'Windows-1252';
            }
            if ('UTF-8' !== $fromEncoding) {
                $s = iconv($fromEncoding, 'UTF-8//IGNORE', $s);
            }

            return preg_replace_callback('/[\x80-\xFF]+/', array(__CLASS__, 'html_encoding_callback'), $s);
        }

        if ('HTML-ENTITIES' === $fromEncoding) {
            $s = html_entity_decode($s, ENT_COMPAT, 'UTF-8');
            $fromEncoding = 'UTF-8';
        }

        return iconv($fromEncoding, $toEncoding.'//IGNORE', $s);
    }

    public static function mb_convert_variables($toEncoding, $fromEncoding, &$a = null, &$b = null, &$c = null, &$d = null, &$e = null, &$f = null)
    {
        $vars = array(&$a, &$b, &$c, &$d, &$e, &$f);

        $ok = true;
        array_walk_recursive($vars, function (&$v) use (&$ok, $toEncoding, $fromEncoding) {
            if (false === $v = Mbstring::mb_convert_encoding($v, $toEncoding, $fromEncoding)) {
                $ok = false;
            }
        });

        return $ok ? $fromEncoding : false;
    }

    public static function mb_decode_mimeheader($s)
    {
        return iconv_mime_decode($s, 2, self::$internalEncoding);
    }

    public static function mb_encode_mimeheader($s, $charset = null, $transferEncoding = null, $linefeed = null, $indent = null)
    {
        trigger_error('mb_encode_mimeheader() is bugged. Please use iconv_mime_encode() instead', E_USER_WARNING);
    }

    public static function mb_decode_numericentity($s, $convmap, $encoding = null)
    {
        if (null !== $s && !\is_scalar($s) && !(\is_object($s) && \method_exists($s, '__toString'))) {
            trigger_error('mb_decode_numericentity() expects parameter 1 to be string, '.\gettype($s).' given', E_USER_WARNING);

            return null;
        }

        if (!\is_array($convmap) || !$convmap) {
            return false;
        }

        if (null !== $encoding && !\is_scalar($encoding)) {
            trigger_error('mb_decode_numericentity() expects parameter 3 to be string, '.\gettype($s).' given', E_USER_WARNING);

            return '';  // Instead of null (cf. mb_encode_numericentity).
        }

        $s = (string) $s;
        if ('' === $s) {
            return '';
        }

        $encoding = self::getEncoding($encoding);

        if ('UTF-8' === $encoding) {
            $encoding = null;
            if (!preg_match('//u', $s)) {
                $s = @iconv('UTF-8', 'UTF-8//IGNORE', $s);
            }
        } else {
            $s = iconv($encoding, 'UTF-8//IGNORE', $s);
        }

        $cnt = floor(\count($convmap) / 4) * 4;

        for ($i = 0; $i < $cnt; $i += 4) {
            // collector_decode_htmlnumericentity ignores $convmap[$i + 3]
            $convmap[$i] += $convmap[$i + 2];
            $convmap[$i + 1] += $convmap[$i + 2];
        }

        $s = preg_replace_callback('/&#(?:0*([0-9]+)|x0*([0-9a-fA-F]+))(?!&);?/', function (array $m) use ($cnt, $convmap) {
            $c = isset($m[2]) ? (int) hexdec($m[2]) : $m[1];
            for ($i = 0; $i < $cnt; $i += 4) {
                if ($c >= $convmap[$i] && $c <= $convmap[$i + 1]) {
                    return Mbstring::mb_chr($c - $convmap[$i + 2]);
                }
            }

            return $m[0];
        }, $s);

        if (null === $encoding) {
            return $s;
        }

        return iconv('UTF-8', $encoding.'//IGNORE', $s);
    }

    public static function mb_encode_numericentity($s, $convmap, $encoding = null, $is_hex = false)
    {
        if (null !== $s && !\is_scalar($s) && !(\is_object($s) && \method_exists($s, '__toString'))) {
            trigger_error('mb_encode_numericentity() expects parameter 1 to be string, '.\gettype($s).' given', E_USER_WARNING);

            return null;
        }

        if (!\is_array($convmap) || !$convmap) {
            return false;
        }

        if (null !== $encoding && !\is_scalar($encoding)) {
            trigger_error('mb_encode_numericentity() expects parameter 3 to be string, '.\gettype($s).' given', E_USER_WARNING);

            return null;  // Instead of '' (cf. mb_decode_numericentity).
        }

        if (null !== $is_hex && !\is_scalar($is_hex)) {
            trigger_error('mb_encode_numericentity() expects parameter 4 to be boolean, '.\gettype($s).' given', E_USER_WARNING);

            return null;
        }

        $s = (string) $s;
        if ('' === $s) {
            return '';
        }

        $encoding = self::getEncoding($encoding);

        if ('UTF-8' === $encoding) {
            $encoding = null;
            if (!preg_match('//u', $s)) {
                $s = @iconv('UTF-8', 'UTF-8//IGNORE', $s);
            }
        } else {
            $s = iconv($encoding, 'UTF-8//IGNORE', $s);
        }

        static $ulenMask = array("\xC0" => 2, "\xD0" => 2, "\xE0" => 3, "\xF0" => 4);

        $cnt = floor(\count($convmap) / 4) * 4;
        $i = 0;
        $len = \strlen($s);
        $result = '';

        while ($i < $len) {
            $ulen = $s[$i] < "\x80" ? 1 : $ulenMask[$s[$i] & "\xF0"];
            $uchr = substr($s, $i, $ulen);
            $i += $ulen;
            $c = self::mb_ord($uchr);

            for ($j = 0; $j < $cnt; $j += 4) {
                if ($c >= $convmap[$j] && $c <= $convmap[$j + 1]) {
                    $cOffset = ($c + $convmap[$j + 2]) & $convmap[$j + 3];
                    $result .= $is_hex ? sprintf('&#x%X;', $cOffset) : '&#'.$cOffset.';';
                    continue 2;
                }
            }
            $result .= $uchr;
        }

        if (null === $encoding) {
            return $result;
        }

        return iconv('UTF-8', $encoding.'//IGNORE', $result);
    }

    public static function mb_convert_case($s, $mode, $encoding = null)
    {
        $s = (string) $s;
        if ('' === $s) {
            return '';
        }

        $encoding = self::getEncoding($encoding);

        if ('UTF-8' === $encoding) {
            $encoding = null;
            if (!preg_match('//u', $s)) {
                $s = @iconv('UTF-8', 'UTF-8//IGNORE', $s);
            }
        } else {
            $s = iconv($encoding, 'UTF-8//IGNORE', $s);
        }

        if (MB_CASE_TITLE == $mode) {
            static $titleRegexp = null;
            if (null === $titleRegexp) {
                $titleRegexp = self::getData('titleCaseRegexp');
            }
            $s = preg_replace_callback($titleRegexp, array(__CLASS__, 'title_case'), $s);
        } else {
            if (MB_CASE_UPPER == $mode) {
                static $upper = null;
                if (null === $upper) {
                    $upper = self::getData('upperCase');
                }
                $map = $upper;
            } else {
                if (self::MB_CASE_FOLD === $mode) {
                    $s = str_replace(self::$caseFold[0], self::$caseFold[1], $s);
                }

                static $lower = null;
                if (null === $lower) {
                    $lower = self::getData('lowerCase');
                }
                $map = $lower;
            }

            static $ulenMask = array("\xC0" => 2, "\xD0" => 2, "\xE0" => 3, "\xF0" => 4);

            $i = 0;
            $len = \strlen($s);

            while ($i < $len) {
                $ulen = $s[$i] < "\x80" ? 1 : $ulenMask[$s[$i] & "\xF0"];
                $uchr = substr($s, $i, $ulen);
                $i += $ulen;

                if (isset($map[$uchr])) {
                    $uchr = $map[$uchr];
                    $nlen = \strlen($uchr);

                    if ($nlen == $ulen) {
                        $nlen = $i;
                        do {
                            $s[--$nlen] = $uchr[--$ulen];
                        } while ($ulen);
                    } else {
                        $s = substr_replace($s, $uchr, $i - $ulen, $ulen);
                        $len += $nlen - $ulen;
                        $i += $nlen - $ulen;
                    }
                }
            }
        }

        if (null === $encoding) {
            return $s;
        }

        return iconv('UTF-8', $encoding.'//IGNORE', $s);
    }

    public static function mb_internal_encoding($encoding = null)
    {
        if (null === $encoding) {
            return self::$internalEncoding;
        }

        $encoding = self::getEncoding($encoding);

        if ('UTF-8' === $encoding || false !== @iconv($encoding, $encoding, ' ')) {
            self::$internalEncoding = $encoding;

            return true;
        }

        return false;
    }

    public static function mb_language($lang = null)
    {
        if (null === $lang) {
            return self::$language;
        }

        switch ($lang = strtolower($lang)) {
            case 'uni':
            case 'neutral':
                self::$language = $lang;

                return true;
        }

        return false;
    }

    public static function mb_list_encodings()
    {
        return array('UTF-8');
    }

    public static function mb_encoding_aliases($encoding)
    {
        switch (strtoupper($encoding)) {
            case 'UTF8':
            case 'UTF-8':
                return array('utf8');
        }

        return false;
    }

    public static function mb_check_encoding($var = null, $encoding = null)
    {
        if (null === $encoding) {
            if (null === $var) {
                return false;
            }
            $encoding = self::$internalEncoding;
        }

        return self::mb_detect_encoding($var, array($encoding)) || false !== @iconv($encoding, $encoding, $var);
    }

    public static function mb_detect_encoding($str, $encodingList = null, $strict = false)
    {
        if (null === $encodingList) {
            $encodingList = self::$encodingList;
        } else {
            if (!\is_array($encodingList)) {
                $encodingList = array_map('trim', explode(',', $encodingList));
            }
            $encodingList = array_map('strtoupper', $encodingList);
        }

        foreach ($encodingList as $enc) {
            switch ($enc) {
                case 'ASCII':
                    if (!preg_match('/[\x80-\xFF]/', $str)) {
                        return $enc;
                    }
                    break;

                case 'UTF8':
                case 'UTF-8':
                    if (preg_match('//u', $str)) {
                        return 'UTF-8';
                    }
                    break;

                default:
                    if (0 === strncmp($enc, 'ISO-8859-', 9)) {
                        return $enc;
                    }
            }
        }

        return false;
    }

    public static function mb_detect_order($encodingList = null)
    {
        if (null === $encodingList) {
            return self::$encodingList;
        }

        if (!\is_array($encodingList)) {
            $encodingList = array_map('trim', explode(',', $encodingList));
        }
        $encodingList = array_map('strtoupper', $encodingList);

        foreach ($encodingList as $enc) {
            switch ($enc) {
                default:
                    if (strncmp($enc, 'ISO-8859-', 9)) {
                        return false;
                    }
                    // no break
                case 'ASCII':
                case 'UTF8':
                case 'UTF-8':
            }
        }

        self::$encodingList = $encodingList;

        return true;
    }

    public static function mb_strlen($s, $encoding = null)
    {
        $encoding = self::getEncoding($encoding);
        if ('CP850' === $encoding || 'ASCII' === $encoding) {
            return \strlen($s);
        }

        return @iconv_strlen($s, $encoding);
    }

    public static function mb_strpos($haystack, $needle, $offset = 0, $encoding = null)
    {
        $encoding = self::getEncoding($encoding);
        if ('CP850' === $encoding || 'ASCII' === $encoding) {
            return strpos($haystack, $needle, $offset);
        }

        $needle = (string) $needle;
        if ('' === $needle) {
            trigger_error(__METHOD__.': Empty delimiter', E_USER_WARNING);

            return false;
        }

        return iconv_strpos($haystack, $needle, $offset, $encoding);
    }

    public static function mb_strrpos($haystack, $needle, $offset = 0, $encoding = null)
    {
        $encoding = self::getEncoding($encoding);
        if ('CP850' === $encoding || 'ASCII' === $encoding) {
            return strrpos($haystack, $needle, $offset);
        }

        if ($offset != (int) $offset) {
            $offset = 0;
        } elseif ($offset = (int) $offset) {
            if ($offset < 0) {
                if (0 > $offset += self::mb_strlen($needle)) {
                    $haystack = self::mb_substr($haystack, 0, $offset, $encoding);
                }
                $offset = 0;
            } else {
                $haystack = self::mb_substr($haystack, $offset, 2147483647, $encoding);
            }
        }

        $pos = iconv_strrpos($haystack, $needle, $encoding);

        return false !== $pos ? $offset + $pos : false;
    }

    public static function mb_str_split($string, $split_length = 1, $encoding = null)
    {
        if (null !== $string && !\is_scalar($string) && !(\is_object($string) && \method_exists($string, '__toString'))) {
            trigger_error('mb_str_split() expects parameter 1 to be string, '.\gettype($string).' given', E_USER_WARNING);

            return null;
        }

        if (1 > $split_length = (int) $split_length) {
            trigger_error('The length of each segment must be greater than zero', E_USER_WARNING);

            return false;
        }

        if (null === $encoding) {
            $encoding = mb_internal_encoding();
        }

        if ('UTF-8' === $encoding = self::getEncoding($encoding)) {
            $rx = '/(';
            while (65535 < $split_length) {
                $rx .= '.{65535}';
                $split_length -= 65535;
            }
            $rx .= '.{'.$split_length.'})/us';

            return preg_split($rx, $string, null, PREG_SPLIT_DELIM_CAPTURE | PREG_SPLIT_NO_EMPTY);
        }

        $result = array();
        $length = mb_strlen($string, $encoding);

        for ($i = 0; $i < $length; $i += $split_length) {
            $result[] = mb_substr($string, $i, $split_length, $encoding);
        }

        return $result;
    }

    public static function mb_strtolower($s, $encoding = null)
    {
        return self::mb_convert_case($s, MB_CASE_LOWER, $encoding);
    }

    public static function mb_strtoupper($s, $encoding = null)
    {
        return self::mb_convert_case($s, MB_CASE_UPPER, $encoding);
    }

    public static function mb_substitute_character($c = null)
    {
        if (0 === strcasecmp($c, 'none')) {
            return true;
        }

        return null !== $c ? false : 'none';
    }

    public static function mb_substr($s, $start, $length = null, $encoding = null)
    {
        $encoding = self::getEncoding($encoding);
        if ('CP850' === $encoding || 'ASCII' === $encoding) {
            return (string) substr($s, $start, null === $length ? 2147483647 : $length);
        }

        if ($start < 0) {
            $start = iconv_strlen($s, $encoding) + $start;
            if ($start < 0) {
                $start = 0;
            }
        }

        if (null === $length) {
            $length = 2147483647;
        } elseif ($length < 0) {
            $length = iconv_strlen($s, $encoding) + $length - $start;
            if ($length < 0) {
                return '';
            }
        }

        return (string) iconv_substr($s, $start, $length, $encoding);
    }

    public static function mb_stripos($haystack, $needle, $offset = 0, $encoding = null)
    {
        $haystack = self::mb_convert_case($haystack, self::MB_CASE_FOLD, $encoding);
        $needle = self::mb_convert_case($needle, self::MB_CASE_FOLD, $encoding);

        return self::mb_strpos($haystack, $needle, $offset, $encoding);
    }

    public static function mb_stristr($haystack, $needle, $part = false, $encoding = null)
    {
        $pos = self::mb_stripos($haystack, $needle, 0, $encoding);

        return self::getSubpart($pos, $part, $haystack, $encoding);
    }

    public static function mb_strrchr($haystack, $needle, $part = false, $encoding = null)
    {
        $encoding = self::getEncoding($encoding);
        if ('CP850' === $encoding || 'ASCII' === $encoding) {
            return strrchr($haystack, $needle, $part);
        }
        $needle = self::mb_substr($needle, 0, 1, $encoding);
        $pos = iconv_strrpos($haystack, $needle, $encoding);

        return self::getSubpart($pos, $part, $haystack, $encoding);
    }

    public static function mb_strrichr($haystack, $needle, $part = false, $encoding = null)
    {
        $needle = self::mb_substr($needle, 0, 1, $encoding);
        $pos = self::mb_strripos($haystack, $needle, $encoding);

        return self::getSubpart($pos, $part, $haystack, $encoding);
    }

    public static function mb_strripos($haystack, $needle, $offset = 0, $encoding = null)
    {
        $haystack = self::mb_convert_case($haystack, self::MB_CASE_FOLD, $encoding);
        $needle = self::mb_convert_case($needle, self::MB_CASE_FOLD, $encoding);

        return self::mb_strrpos($haystack, $needle, $offset, $encoding);
    }

    public static function mb_strstr($haystack, $needle, $part = false, $encoding = null)
    {
        $pos = strpos($haystack, $needle);
        if (false === $pos) {
            return false;
        }
        if ($part) {
            return substr($haystack, 0, $pos);
        }

        return substr($haystack, $pos);
    }

    public static function mb_get_info($type = 'all')
    {
        $info = array(
            'internal_encoding' => self::$internalEncoding,
            'http_output' => 'pass',
            'http_output_conv_mimetypes' => '^(text/|application/xhtml\+xml)',
            'func_overload' => 0,
            'func_overload_list' => 'no overload',
            'mail_charset' => 'UTF-8',
            'mail_header_encoding' => 'BASE64',
            'mail_body_encoding' => 'BASE64',
            'illegal_chars' => 0,
            'encoding_translation' => 'Off',
            'language' => self::$language,
            'detect_order' => self::$encodingList,
            'substitute_character' => 'none',
            'strict_detection' => 'Off',
        );

        if ('all' === $type) {
            return $info;
        }
        if (isset($info[$type])) {
            return $info[$type];
        }

        return false;
    }

    public static function mb_http_input($type = '')
    {
        return false;
    }

    public static function mb_http_output($encoding = null)
    {
        return null !== $encoding ? 'pass' === $encoding : 'pass';
    }

    public static function mb_strwidth($s, $encoding = null)
    {
        $encoding = self::getEncoding($encoding);

        if ('UTF-8' !== $encoding) {
            $s = iconv($encoding, 'UTF-8//IGNORE', $s);
        }

        $s = preg_replace('/[\x{1100}-\x{115F}\x{2329}\x{232A}\x{2E80}-\x{303E}\x{3040}-\x{A4CF}\x{AC00}-\x{D7A3}\x{F900}-\x{FAFF}\x{FE10}-\x{FE19}\x{FE30}-\x{FE6F}\x{FF00}-\x{FF60}\x{FFE0}-\x{FFE6}\x{20000}-\x{2FFFD}\x{30000}-\x{3FFFD}]/u', '', $s, -1, $wide);

        return ($wide << 1) + iconv_strlen($s, 'UTF-8');
    }

    public static function mb_substr_count($haystack, $needle, $encoding = null)
    {
        return substr_count($haystack, $needle);
    }

    public static function mb_output_handler($contents, $status)
    {
        return $contents;
    }

    public static function mb_chr($code, $encoding = null)
    {
        if (0x80 > $code %= 0x200000) {
            $s = \chr($code);
        } elseif (0x800 > $code) {
            $s = \chr(0xC0 | $code >> 6).\chr(0x80 | $code & 0x3F);
        } elseif (0x10000 > $code) {
            $s = \chr(0xE0 | $code >> 12).\chr(0x80 | $code >> 6 & 0x3F).\chr(0x80 | $code & 0x3F);
        } else {
            $s = \chr(0xF0 | $code >> 18).\chr(0x80 | $code >> 12 & 0x3F).\chr(0x80 | $code >> 6 & 0x3F).\chr(0x80 | $code & 0x3F);
        }

        if ('UTF-8' !== $encoding = self::getEncoding($encoding)) {
            $s = mb_convert_encoding($s, $encoding, 'UTF-8');
        }

        return $s;
    }

    public static function mb_ord($s, $encoding = null)
    {
        if ('UTF-8' !== $encoding = self::getEncoding($encoding)) {
            $s = mb_convert_encoding($s, 'UTF-8', $encoding);
        }

        if (1 === \strlen($s)) {
            return \ord($s);
        }

        $code = ($s = unpack('C*', substr($s, 0, 4))) ? $s[1] : 0;
        if (0xF0 <= $code) {
            return (($code - 0xF0) << 18) + (($s[2] - 0x80) << 12) + (($s[3] - 0x80) << 6) + $s[4] - 0x80;
        }
        if (0xE0 <= $code) {
            return (($code - 0xE0) << 12) + (($s[2] - 0x80) << 6) + $s[3] - 0x80;
        }
        if (0xC0 <= $code) {
            return (($code - 0xC0) << 6) + $s[2] - 0x80;
        }

        return $code;
    }

    private static function getSubpart($pos, $part, $haystack, $encoding)
    {
        if (false === $pos) {
            return false;
        }
        if ($part) {
            return self::mb_substr($haystack, 0, $pos, $encoding);
        }

        return self::mb_substr($haystack, $pos, null, $encoding);
    }

    private static function html_encoding_callback(array $m)
    {
        $i = 1;
        $entities = '';
        $m = unpack('C*', htmlentities($m[0], ENT_COMPAT, 'UTF-8'));

        while (isset($m[$i])) {
            if (0x80 > $m[$i]) {
                $entities .= \chr($m[$i++]);
                continue;
            }
            if (0xF0 <= $m[$i]) {
                $c = (($m[$i++] - 0xF0) << 18) + (($m[$i++] - 0x80) << 12) + (($m[$i++] - 0x80) << 6) + $m[$i++] - 0x80;
            } elseif (0xE0 <= $m[$i]) {
                $c = (($m[$i++] - 0xE0) << 12) + (($m[$i++] - 0x80) << 6) + $m[$i++] - 0x80;
            } else {
                $c = (($m[$i++] - 0xC0) << 6) + $m[$i++] - 0x80;
            }

            $entities .= '&#'.$c.';';
        }

        return $entities;
    }

    private static function title_case(array $s)
    {
        return self::mb_convert_case($s[1], MB_CASE_UPPER, 'UTF-8').self::mb_convert_case($s[2], MB_CASE_LOWER, 'UTF-8');
    }

    private static function getData($file)
    {
        if (file_exists($file = __DIR__.'/Resources/unidata/'.$file.'.php')) {
            return require $file;
        }

        return false;
    }

    private static function getEncoding($encoding)
    {
        if (null === $encoding) {
            return self::$internalEncoding;
        }

        if ('UTF-8' === $encoding) {
            return 'UTF-8';
        }

        $encoding = strtoupper($encoding);

        if ('8BIT' === $encoding || 'BINARY' === $encoding) {
            return 'CP850';
        }

        if ('UTF8' === $encoding) {
            return 'UTF-8';
        }

        return $encoding;
    }
}
PKϤ$Z$�!mmcache/Adapter/Psr16Adapter.phpnu�[���<?php

/*
 * This file is part of the Symfony package.
 *
 * (c) Fabien Potencier <fabien@symfony.com>
 *
 * For the full copyright and license information, please view the LICENSE
 * file that was distributed with this source code.
 */

namespace Symfony\Component\Cache\Adapter;

use Psr\SimpleCache\CacheInterface;
use Symfony\Component\Cache\PruneableInterface;
use Symfony\Component\Cache\ResettableInterface;
use Symfony\Component\Cache\Traits\ProxyTrait;

/**
 * Turns a PSR-16 cache into a PSR-6 one.
 *
 * @author Nicolas Grekas <p@tchwork.com>
 */
class Psr16Adapter extends AbstractAdapter implements PruneableInterface, ResettableInterface
{
    /**
     * @internal
     */
    protected const NS_SEPARATOR = '_';

    use ProxyTrait;

    private $miss;

    public function __construct(CacheInterface $pool, string $namespace = '', int $defaultLifetime = 0)
    {
        parent::__construct($namespace, $defaultLifetime);

        $this->pool = $pool;
        $this->miss = new \stdClass();
    }

    /**
     * {@inheritdoc}
     */
    protected function doFetch(array $ids)
    {
        foreach ($this->pool->getMultiple($ids, $this->miss) as $key => $value) {
            if ($this->miss !== $value) {
                yield $key => $value;
            }
        }
    }

    /**
     * {@inheritdoc}
     */
    protected function doHave(string $id)
    {
        return $this->pool->has($id);
    }

    /**
     * {@inheritdoc}
     */
    protected function doClear(string $namespace)
    {
        return $this->pool->clear();
    }

    /**
     * {@inheritdoc}
     */
    protected function doDelete(array $ids)
    {
        return $this->pool->deleteMultiple($ids);
    }

    /**
     * {@inheritdoc}
     */
    protected function doSave(array $values, int $lifetime)
    {
        return $this->pool->setMultiple($values, 0 === $lifetime ? null : $lifetime);
    }
}
PKϤ$Zh5�)*cache/Adapter/TagAwareAdapterInterface.phpnu�[���<?php

/*
 * This file is part of the Symfony package.
 *
 * (c) Fabien Potencier <fabien@symfony.com>
 *
 * For the full copyright and license information, please view the LICENSE
 * file that was distributed with this source code.
 */

namespace Symfony\Component\Cache\Adapter;

use Psr\Cache\InvalidArgumentException;

/**
 * Interface for invalidating cached items using tags.
 *
 * @author Nicolas Grekas <p@tchwork.com>
 */
interface TagAwareAdapterInterface extends AdapterInterface
{
    /**
     * Invalidates cached items using tags.
     *
     * @param string[] $tags An array of tags to invalidate
     *
     * @return bool True on success
     *
     * @throws InvalidArgumentException When $tags is not valid
     */
    public function invalidateTags(array $tags);
}
PKϤ$Z'�.1.1!cache/Adapter/PhpArrayAdapter.phpnu�[���<?php

/*
 * This file is part of the Symfony package.
 *
 * (c) Fabien Potencier <fabien@symfony.com>
 *
 * For the full copyright and license information, please view the LICENSE
 * file that was distributed with this source code.
 */

namespace Symfony\Component\Cache\Adapter;

use Psr\Cache\CacheItemInterface;
use Psr\Cache\CacheItemPoolInterface;
use Symfony\Component\Cache\CacheItem;
use Symfony\Component\Cache\Exception\InvalidArgumentException;
use Symfony\Component\Cache\PruneableInterface;
use Symfony\Component\Cache\ResettableInterface;
use Symfony\Component\Cache\Traits\ContractsTrait;
use Symfony\Component\Cache\Traits\ProxyTrait;
use Symfony\Component\VarExporter\VarExporter;
use Symfony\Contracts\Cache\CacheInterface;

/**
 * Caches items at warm up time using a PHP array that is stored in shared memory by OPCache since PHP 7.0.
 * Warmed up items are read-only and run-time discovered items are cached using a fallback adapter.
 *
 * @author Titouan Galopin <galopintitouan@gmail.com>
 * @author Nicolas Grekas <p@tchwork.com>
 */
class PhpArrayAdapter implements AdapterInterface, CacheInterface, PruneableInterface, ResettableInterface
{
    use ContractsTrait;
    use ProxyTrait;

    private $file;
    private $keys;
    private $values;
    private $createCacheItem;

    private static $valuesCache = [];

    /**
     * @param string           $file         The PHP file were values are cached
     * @param AdapterInterface $fallbackPool A pool to fallback on when an item is not hit
     */
    public function __construct(string $file, AdapterInterface $fallbackPool)
    {
        $this->file = $file;
        $this->pool = $fallbackPool;
        $this->createCacheItem = \Closure::bind(
            static function ($key, $value, $isHit) {
                $item = new CacheItem();
                $item->key = $key;
                $item->value = $value;
                $item->isHit = $isHit;

                return $item;
            },
            null,
            CacheItem::class
        );
    }

    /**
     * This adapter takes advantage of how PHP stores arrays in its latest versions.
     *
     * @param string                 $file         The PHP file were values are cached
     * @param CacheItemPoolInterface $fallbackPool A pool to fallback on when an item is not hit
     *
     * @return CacheItemPoolInterface
     */
    public static function create(string $file, CacheItemPoolInterface $fallbackPool)
    {
        if (!$fallbackPool instanceof AdapterInterface) {
            $fallbackPool = new ProxyAdapter($fallbackPool);
        }

        return new static($file, $fallbackPool);
    }

    /**
     * {@inheritdoc}
     */
    public function get(string $key, callable $callback, float $beta = null, array &$metadata = null)
    {
        if (null === $this->values) {
            $this->initialize();
        }
        if (!isset($this->keys[$key])) {
            get_from_pool:
            if ($this->pool instanceof CacheInterface) {
                return $this->pool->get($key, $callback, $beta, $metadata);
            }

            return $this->doGet($this->pool, $key, $callback, $beta, $metadata);
        }
        $value = $this->values[$this->keys[$key]];

        if ('N;' === $value) {
            return null;
        }
        try {
            if ($value instanceof \Closure) {
                return $value();
            }
        } catch (\Throwable $e) {
            unset($this->keys[$key]);
            goto get_from_pool;
        }

        return $value;
    }

    /**
     * {@inheritdoc}
     */
    public function getItem($key)
    {
        if (!\is_string($key)) {
            throw new InvalidArgumentException(sprintf('Cache key must be string, "%s" given.', get_debug_type($key)));
        }
        if (null === $this->values) {
            $this->initialize();
        }
        if (!isset($this->keys[$key])) {
            return $this->pool->getItem($key);
        }

        $value = $this->values[$this->keys[$key]];
        $isHit = true;

        if ('N;' === $value) {
            $value = null;
        } elseif ($value instanceof \Closure) {
            try {
                $value = $value();
            } catch (\Throwable $e) {
                $value = null;
                $isHit = false;
            }
        }

        $f = $this->createCacheItem;

        return $f($key, $value, $isHit);
    }

    /**
     * {@inheritdoc}
     */
    public function getItems(array $keys = [])
    {
        foreach ($keys as $key) {
            if (!\is_string($key)) {
                throw new InvalidArgumentException(sprintf('Cache key must be string, "%s" given.', get_debug_type($key)));
            }
        }
        if (null === $this->values) {
            $this->initialize();
        }

        return $this->generateItems($keys);
    }

    /**
     * {@inheritdoc}
     *
     * @return bool
     */
    public function hasItem($key)
    {
        if (!\is_string($key)) {
            throw new InvalidArgumentException(sprintf('Cache key must be string, "%s" given.', get_debug_type($key)));
        }
        if (null === $this->values) {
            $this->initialize();
        }

        return isset($this->keys[$key]) || $this->pool->hasItem($key);
    }

    /**
     * {@inheritdoc}
     *
     * @return bool
     */
    public function deleteItem($key)
    {
        if (!\is_string($key)) {
            throw new InvalidArgumentException(sprintf('Cache key must be string, "%s" given.', get_debug_type($key)));
        }
        if (null === $this->values) {
            $this->initialize();
        }

        return !isset($this->keys[$key]) && $this->pool->deleteItem($key);
    }

    /**
     * {@inheritdoc}
     *
     * @return bool
     */
    public function deleteItems(array $keys)
    {
        $deleted = true;
        $fallbackKeys = [];

        foreach ($keys as $key) {
            if (!\is_string($key)) {
                throw new InvalidArgumentException(sprintf('Cache key must be string, "%s" given.', get_debug_type($key)));
            }

            if (isset($this->keys[$key])) {
                $deleted = false;
            } else {
                $fallbackKeys[] = $key;
            }
        }
        if (null === $this->values) {
            $this->initialize();
        }

        if ($fallbackKeys) {
            $deleted = $this->pool->deleteItems($fallbackKeys) && $deleted;
        }

        return $deleted;
    }

    /**
     * {@inheritdoc}
     *
     * @return bool
     */
    public function save(CacheItemInterface $item)
    {
        if (null === $this->values) {
            $this->initialize();
        }

        return !isset($this->keys[$item->getKey()]) && $this->pool->save($item);
    }

    /**
     * {@inheritdoc}
     *
     * @return bool
     */
    public function saveDeferred(CacheItemInterface $item)
    {
        if (null === $this->values) {
            $this->initialize();
        }

        return !isset($this->keys[$item->getKey()]) && $this->pool->saveDeferred($item);
    }

    /**
     * {@inheritdoc}
     *
     * @return bool
     */
    public function commit()
    {
        return $this->pool->commit();
    }

    /**
     * {@inheritdoc}
     *
     * @return bool
     */
    public function clear(string $prefix = '')
    {
        $this->keys = $this->values = [];

        $cleared = @unlink($this->file) || !file_exists($this->file);
        unset(self::$valuesCache[$this->file]);

        if ($this->pool instanceof AdapterInterface) {
            return $this->pool->clear($prefix) && $cleared;
        }

        return $this->pool->clear() && $cleared;
    }

    /**
     * Store an array of cached values.
     *
     * @param array $values The cached values
     *
     * @return string[] A list of classes to preload on PHP 7.4+
     */
    public function warmUp(array $values)
    {
        if (file_exists($this->file)) {
            if (!is_file($this->file)) {
                throw new InvalidArgumentException(sprintf('Cache path exists and is not a file: "%s".', $this->file));
            }

            if (!is_writable($this->file)) {
                throw new InvalidArgumentException(sprintf('Cache file is not writable: "%s".', $this->file));
            }
        } else {
            $directory = \dirname($this->file);

            if (!is_dir($directory) && !@mkdir($directory, 0777, true)) {
                throw new InvalidArgumentException(sprintf('Cache directory does not exist and cannot be created: "%s".', $directory));
            }

            if (!is_writable($directory)) {
                throw new InvalidArgumentException(sprintf('Cache directory is not writable: "%s".', $directory));
            }
        }

        $preload = [];
        $dumpedValues = '';
        $dumpedMap = [];
        $dump = <<<'EOF'
<?php

// This file has been auto-generated by the Symfony Cache Component.

return [[


EOF;

        foreach ($values as $key => $value) {
            CacheItem::validateKey(\is_int($key) ? (string) $key : $key);
            $isStaticValue = true;

            if (null === $value) {
                $value = "'N;'";
            } elseif (\is_object($value) || \is_array($value)) {
                try {
                    $value = VarExporter::export($value, $isStaticValue, $preload);
                } catch (\Exception $e) {
                    throw new InvalidArgumentException(sprintf('Cache key "%s" has non-serializable "%s" value.', $key, get_debug_type($value)), 0, $e);
                }
            } elseif (\is_string($value)) {
                // Wrap "N;" in a closure to not confuse it with an encoded `null`
                if ('N;' === $value) {
                    $isStaticValue = false;
                }
                $value = var_export($value, true);
            } elseif (!is_scalar($value)) {
                throw new InvalidArgumentException(sprintf('Cache key "%s" has non-serializable "%s" value.', $key, get_debug_type($value)));
            } else {
                $value = var_export($value, true);
            }

            if (!$isStaticValue) {
                $value = str_replace("\n", "\n    ", $value);
                $value = "static function () {\n    return {$value};\n}";
            }
            $hash = hash('md5', $value);

            if (null === $id = $dumpedMap[$hash] ?? null) {
                $id = $dumpedMap[$hash] = \count($dumpedMap);
                $dumpedValues .= "{$id} => {$value},\n";
            }

            $dump .= var_export($key, true)." => {$id},\n";
        }

        $dump .= "\n], [\n\n{$dumpedValues}\n]];\n";

        $tmpFile = uniqid($this->file, true);

        file_put_contents($tmpFile, $dump);
        @chmod($tmpFile, 0666 & ~umask());
        unset($serialized, $value, $dump);

        @rename($tmpFile, $this->file);
        unset(self::$valuesCache[$this->file]);

        $this->initialize();

        return $preload;
    }

    /**
     * Load the cache file.
     */
    private function initialize()
    {
        if (isset(self::$valuesCache[$this->file])) {
            $values = self::$valuesCache[$this->file];
        } elseif (!is_file($this->file)) {
            $this->keys = $this->values = [];

            return;
        } else {
            $values = self::$valuesCache[$this->file] = (include $this->file) ?: [[], []];
        }

        if (2 !== \count($values) || !isset($values[0], $values[1])) {
            $this->keys = $this->values = [];
        } else {
            [$this->keys, $this->values] = $values;
        }
    }

    private function generateItems(array $keys): \Generator
    {
        $f = $this->createCacheItem;
        $fallbackKeys = [];

        foreach ($keys as $key) {
            if (isset($this->keys[$key])) {
                $value = $this->values[$this->keys[$key]];

                if ('N;' === $value) {
                    yield $key => $f($key, null, true);
                } elseif ($value instanceof \Closure) {
                    try {
                        yield $key => $f($key, $value(), true);
                    } catch (\Throwable $e) {
                        yield $key => $f($key, null, false);
                    }
                } else {
                    yield $key => $f($key, $value, true);
                }
            } else {
                $fallbackKeys[] = $key;
            }
        }

        if ($fallbackKeys) {
            yield from $this->pool->getItems($fallbackKeys);
        }
    }
}
PKϤ$Z�@2d

!cache/Adapter/DoctrineAdapter.phpnu�[���<?php

/*
 * This file is part of the Symfony package.
 *
 * (c) Fabien Potencier <fabien@symfony.com>
 *
 * For the full copyright and license information, please view the LICENSE
 * file that was distributed with this source code.
 */

namespace Symfony\Component\Cache\Adapter;

use Doctrine\Common\Cache\CacheProvider;

/**
 * @author Nicolas Grekas <p@tchwork.com>
 */
class DoctrineAdapter extends AbstractAdapter
{
    private $provider;

    public function __construct(CacheProvider $provider, string $namespace = '', int $defaultLifetime = 0)
    {
        parent::__construct('', $defaultLifetime);
        $this->provider = $provider;
        $provider->setNamespace($namespace);
    }

    /**
     * {@inheritdoc}
     */
    public function reset()
    {
        parent::reset();
        $this->provider->setNamespace($this->provider->getNamespace());
    }

    /**
     * {@inheritdoc}
     */
    protected function doFetch(array $ids)
    {
        $unserializeCallbackHandler = ini_set('unserialize_callback_func', parent::class.'::handleUnserializeCallback');
        try {
            return $this->provider->fetchMultiple($ids);
        } catch (\Error $e) {
            $trace = $e->getTrace();

            if (isset($trace[0]['function']) && !isset($trace[0]['class'])) {
                switch ($trace[0]['function']) {
                    case 'unserialize':
                    case 'apcu_fetch':
                    case 'apc_fetch':
                        throw new \ErrorException($e->getMessage(), $e->getCode(), \E_ERROR, $e->getFile(), $e->getLine());
                }
            }

            throw $e;
        } finally {
            ini_set('unserialize_callback_func', $unserializeCallbackHandler);
        }
    }

    /**
     * {@inheritdoc}
     */
    protected function doHave(string $id)
    {
        return $this->provider->contains($id);
    }

    /**
     * {@inheritdoc}
     */
    protected function doClear(string $namespace)
    {
        $namespace = $this->provider->getNamespace();

        return isset($namespace[0])
            ? $this->provider->deleteAll()
            : $this->provider->flushAll();
    }

    /**
     * {@inheritdoc}
     */
    protected function doDelete(array $ids)
    {
        $ok = true;
        foreach ($ids as $id) {
            $ok = $this->provider->delete($id) && $ok;
        }

        return $ok;
    }

    /**
     * {@inheritdoc}
     */
    protected function doSave(array $values, int $lifetime)
    {
        return $this->provider->saveMultiple($values, $lifetime);
    }
}
PKϤ$Z�����"cache/Adapter/AdapterInterface.phpnu�[���<?php

/*
 * This file is part of the Symfony package.
 *
 * (c) Fabien Potencier <fabien@symfony.com>
 *
 * For the full copyright and license information, please view the LICENSE
 * file that was distributed with this source code.
 */

namespace Symfony\Component\Cache\Adapter;

use Psr\Cache\CacheItemPoolInterface;
use Symfony\Component\Cache\CacheItem;

// Help opcache.preload discover always-needed symbols
class_exists(CacheItem::class);

/**
 * Interface for adapters managing instances of Symfony's CacheItem.
 *
 * @author Kévin Dunglas <dunglas@gmail.com>
 */
interface AdapterInterface extends CacheItemPoolInterface
{
    /**
     * {@inheritdoc}
     *
     * @return CacheItem
     */
    public function getItem($key);

    /**
     * {@inheritdoc}
     *
     * @return \Traversable|CacheItem[]
     */
    public function getItems(array $keys = []);

    /**
     * {@inheritdoc}
     *
     * @return bool
     */
    public function clear(string $prefix = '');
}
PKϤ$Z_���b+b+cache/Adapter/ArrayAdapter.phpnu�[���<?php

/*
 * This file is part of the Symfony package.
 *
 * (c) Fabien Potencier <fabien@symfony.com>
 *
 * For the full copyright and license information, please view the LICENSE
 * file that was distributed with this source code.
 */

namespace Symfony\Component\Cache\Adapter;

use Psr\Cache\CacheItemInterface;
use Psr\Log\LoggerAwareInterface;
use Psr\Log\LoggerAwareTrait;
use Symfony\Component\Cache\CacheItem;
use Symfony\Component\Cache\Exception\InvalidArgumentException;
use Symfony\Component\Cache\ResettableInterface;
use Symfony\Contracts\Cache\CacheInterface;

/**
 * An in-memory cache storage.
 *
 * Acts as a least-recently-used (LRU) storage when configured with a maximum number of items.
 *
 * @author Nicolas Grekas <p@tchwork.com>
 */
class ArrayAdapter implements AdapterInterface, CacheInterface, LoggerAwareInterface, ResettableInterface
{
    use LoggerAwareTrait;

    private $storeSerialized;
    private $values = [];
    private $expiries = [];
    private $createCacheItem;
    private $defaultLifetime;
    private $maxLifetime;
    private $maxItems;

    /**
     * @param bool $storeSerialized Disabling serialization can lead to cache corruptions when storing mutable values but increases performance otherwise
     */
    public function __construct(int $defaultLifetime = 0, bool $storeSerialized = true, float $maxLifetime = 0, int $maxItems = 0)
    {
        if (0 > $maxLifetime) {
            throw new InvalidArgumentException(sprintf('Argument $maxLifetime must be positive, %F passed.', $maxLifetime));
        }

        if (0 > $maxItems) {
            throw new InvalidArgumentException(sprintf('Argument $maxItems must be a positive integer, %d passed.', $maxItems));
        }

        $this->defaultLifetime = $defaultLifetime;
        $this->storeSerialized = $storeSerialized;
        $this->maxLifetime = $maxLifetime;
        $this->maxItems = $maxItems;
        $this->createCacheItem = \Closure::bind(
            static function ($key, $value, $isHit) {
                $item = new CacheItem();
                $item->key = $key;
                $item->value = $value;
                $item->isHit = $isHit;

                return $item;
            },
            null,
            CacheItem::class
        );
    }

    /**
     * {@inheritdoc}
     */
    public function get(string $key, callable $callback, float $beta = null, array &$metadata = null)
    {
        $item = $this->getItem($key);
        $metadata = $item->getMetadata();

        // ArrayAdapter works in memory, we don't care about stampede protection
        if (\INF === $beta || !$item->isHit()) {
            $save = true;
            $this->save($item->set($callback($item, $save)));
        }

        return $item->get();
    }

    /**
     * {@inheritdoc}
     */
    public function delete(string $key): bool
    {
        return $this->deleteItem($key);
    }

    /**
     * {@inheritdoc}
     *
     * @return bool
     */
    public function hasItem($key)
    {
        if (\is_string($key) && isset($this->expiries[$key]) && $this->expiries[$key] > microtime(true)) {
            if ($this->maxItems) {
                // Move the item last in the storage
                $value = $this->values[$key];
                unset($this->values[$key]);
                $this->values[$key] = $value;
            }

            return true;
        }
        CacheItem::validateKey($key);

        return isset($this->expiries[$key]) && !$this->deleteItem($key);
    }

    /**
     * {@inheritdoc}
     */
    public function getItem($key)
    {
        if (!$isHit = $this->hasItem($key)) {
            $value = null;

            if (!$this->maxItems) {
                // Track misses in non-LRU mode only
                $this->values[$key] = null;
            }
        } else {
            $value = $this->storeSerialized ? $this->unfreeze($key, $isHit) : $this->values[$key];
        }
        $f = $this->createCacheItem;

        return $f($key, $value, $isHit);
    }

    /**
     * {@inheritdoc}
     */
    public function getItems(array $keys = [])
    {
        foreach ($keys as $key) {
            if (!\is_string($key) || !isset($this->expiries[$key])) {
                CacheItem::validateKey($key);
            }
        }

        return $this->generateItems($keys, microtime(true), $this->createCacheItem);
    }

    /**
     * {@inheritdoc}
     *
     * @return bool
     */
    public function deleteItem($key)
    {
        if (!\is_string($key) || !isset($this->expiries[$key])) {
            CacheItem::validateKey($key);
        }
        unset($this->values[$key], $this->expiries[$key]);

        return true;
    }

    /**
     * {@inheritdoc}
     *
     * @return bool
     */
    public function deleteItems(array $keys)
    {
        foreach ($keys as $key) {
            $this->deleteItem($key);
        }

        return true;
    }

    /**
     * {@inheritdoc}
     *
     * @return bool
     */
    public function save(CacheItemInterface $item)
    {
        if (!$item instanceof CacheItem) {
            return false;
        }
        $item = (array) $item;
        $key = $item["\0*\0key"];
        $value = $item["\0*\0value"];
        $expiry = $item["\0*\0expiry"];

        $now = microtime(true);

        if (0 === $expiry) {
            $expiry = \PHP_INT_MAX;
        }

        if (null !== $expiry && $expiry <= $now) {
            $this->deleteItem($key);

            return true;
        }
        if ($this->storeSerialized && null === $value = $this->freeze($value, $key)) {
            return false;
        }
        if (null === $expiry && 0 < $this->defaultLifetime) {
            $expiry = $this->defaultLifetime;
            $expiry = $now + ($expiry > ($this->maxLifetime ?: $expiry) ? $this->maxLifetime : $expiry);
        } elseif ($this->maxLifetime && (null === $expiry || $expiry > $now + $this->maxLifetime)) {
            $expiry = $now + $this->maxLifetime;
        }

        if ($this->maxItems) {
            unset($this->values[$key]);

            // Iterate items and vacuum expired ones while we are at it
            foreach ($this->values as $k => $v) {
                if ($this->expiries[$k] > $now && \count($this->values) < $this->maxItems) {
                    break;
                }

                unset($this->values[$k], $this->expiries[$k]);
            }
        }

        $this->values[$key] = $value;
        $this->expiries[$key] = null !== $expiry ? $expiry : \PHP_INT_MAX;

        return true;
    }

    /**
     * {@inheritdoc}
     *
     * @return bool
     */
    public function saveDeferred(CacheItemInterface $item)
    {
        return $this->save($item);
    }

    /**
     * {@inheritdoc}
     *
     * @return bool
     */
    public function commit()
    {
        return true;
    }

    /**
     * {@inheritdoc}
     *
     * @return bool
     */
    public function clear(string $prefix = '')
    {
        if ('' !== $prefix) {
            $now = microtime(true);

            foreach ($this->values as $key => $value) {
                if (!isset($this->expiries[$key]) || $this->expiries[$key] <= $now || 0 === strpos($key, $prefix)) {
                    unset($this->values[$key], $this->expiries[$key]);
                }
            }

            if ($this->values) {
                return true;
            }
        }

        $this->values = $this->expiries = [];

        return true;
    }

    /**
     * Returns all cached values, with cache miss as null.
     *
     * @return array
     */
    public function getValues()
    {
        if (!$this->storeSerialized) {
            return $this->values;
        }

        $values = $this->values;
        foreach ($values as $k => $v) {
            if (null === $v || 'N;' === $v) {
                continue;
            }
            if (!\is_string($v) || !isset($v[2]) || ':' !== $v[1]) {
                $values[$k] = serialize($v);
            }
        }

        return $values;
    }

    /**
     * {@inheritdoc}
     */
    public function reset()
    {
        $this->clear();
    }

    private function generateItems(array $keys, $now, $f)
    {
        foreach ($keys as $i => $key) {
            if (!$isHit = isset($this->expiries[$key]) && ($this->expiries[$key] > $now || !$this->deleteItem($key))) {
                $value = null;

                if (!$this->maxItems) {
                    // Track misses in non-LRU mode only
                    $this->values[$key] = null;
                }
            } else {
                if ($this->maxItems) {
                    // Move the item last in the storage
                    $value = $this->values[$key];
                    unset($this->values[$key]);
                    $this->values[$key] = $value;
                }

                $value = $this->storeSerialized ? $this->unfreeze($key, $isHit) : $this->values[$key];
            }
            unset($keys[$i]);

            yield $key => $f($key, $value, $isHit);
        }

        foreach ($keys as $key) {
            yield $key => $f($key, null, false);
        }
    }

    private function freeze($value, $key)
    {
        if (null === $value) {
            return 'N;';
        }
        if (\is_string($value)) {
            // Serialize strings if they could be confused with serialized objects or arrays
            if ('N;' === $value || (isset($value[2]) && ':' === $value[1])) {
                return serialize($value);
            }
        } elseif (!is_scalar($value)) {
            try {
                $serialized = serialize($value);
            } catch (\Exception $e) {
                $type = get_debug_type($value);
                $message = sprintf('Failed to save key "{key}" of type %s: %s', $type, $e->getMessage());
                CacheItem::log($this->logger, $message, ['key' => $key, 'exception' => $e, 'cache-adapter' => get_debug_type($this)]);

                return;
            }
            // Keep value serialized if it contains any objects or any internal references
            if ('C' === $serialized[0] || 'O' === $serialized[0] || preg_match('/;[OCRr]:[1-9]/', $serialized)) {
                return $serialized;
            }
        }

        return $value;
    }

    private function unfreeze(string $key, bool &$isHit)
    {
        if ('N;' === $value = $this->values[$key]) {
            return null;
        }
        if (\is_string($value) && isset($value[2]) && ':' === $value[1]) {
            try {
                $value = unserialize($value);
            } catch (\Exception $e) {
                CacheItem::log($this->logger, 'Failed to unserialize key "{key}": '.$e->getMessage(), ['key' => $key, 'exception' => $e, 'cache-adapter' => get_debug_type($this)]);
                $value = false;
            }
            if (false === $value) {
                $value = null;
                $isHit = false;

                if (!$this->maxItems) {
                    $this->values[$key] = null;
                }
            }
        }

        return $value;
    }
}
PKϤ$ZY� ��+cache/Adapter/FilesystemTagAwareAdapter.phpnu�[���<?php

/*
 * This file is part of the Symfony package.
 *
 * (c) Fabien Potencier <fabien@symfony.com>
 *
 * For the full copyright and license information, please view the LICENSE
 * file that was distributed with this source code.
 */

namespace Symfony\Component\Cache\Adapter;

use Symfony\Component\Cache\Marshaller\MarshallerInterface;
use Symfony\Component\Cache\Marshaller\TagAwareMarshaller;
use Symfony\Component\Cache\PruneableInterface;
use Symfony\Component\Cache\Traits\FilesystemTrait;

/**
 * Stores tag id <> cache id relationship as a symlink, and lookup on invalidation calls.
 *
 * @author Nicolas Grekas <p@tchwork.com>
 * @author André Rømcke <andre.romcke+symfony@gmail.com>
 */
class FilesystemTagAwareAdapter extends AbstractTagAwareAdapter implements PruneableInterface
{
    use FilesystemTrait {
        doClear as private doClearCache;
        doSave as private doSaveCache;
    }

    /**
     * Folder used for tag symlinks.
     */
    private const TAG_FOLDER = 'tags';

    public function __construct(string $namespace = '', int $defaultLifetime = 0, string $directory = null, MarshallerInterface $marshaller = null)
    {
        $this->marshaller = new TagAwareMarshaller($marshaller);
        parent::__construct('', $defaultLifetime);
        $this->init($namespace, $directory);
    }

    /**
     * {@inheritdoc}
     */
    protected function doClear(string $namespace)
    {
        $ok = $this->doClearCache($namespace);

        if ('' !== $namespace) {
            return $ok;
        }

        set_error_handler(static function () {});
        $chars = '+-ABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789';

        try {
            foreach ($this->scanHashDir($this->directory.self::TAG_FOLDER.\DIRECTORY_SEPARATOR) as $dir) {
                if (rename($dir, $renamed = substr_replace($dir, bin2hex(random_bytes(4)), -8))) {
                    $dir = $renamed.\DIRECTORY_SEPARATOR;
                } else {
                    $dir .= \DIRECTORY_SEPARATOR;
                    $renamed = null;
                }

                for ($i = 0; $i < 38; ++$i) {
                    if (!is_dir($dir.$chars[$i])) {
                        continue;
                    }
                    for ($j = 0; $j < 38; ++$j) {
                        if (!is_dir($d = $dir.$chars[$i].\DIRECTORY_SEPARATOR.$chars[$j])) {
                            continue;
                        }
                        foreach (scandir($d, \SCANDIR_SORT_NONE) ?: [] as $link) {
                            if ('.' !== $link && '..' !== $link && (null !== $renamed || !realpath($d.\DIRECTORY_SEPARATOR.$link))) {
                                unlink($d.\DIRECTORY_SEPARATOR.$link);
                            }
                        }
                        null === $renamed ?: rmdir($d);
                    }
                    null === $renamed ?: rmdir($dir.$chars[$i]);
                }
                null === $renamed ?: rmdir($renamed);
            }
        } finally {
            restore_error_handler();
        }

        return $ok;
    }

    /**
     * {@inheritdoc}
     */
    protected function doSave(array $values, int $lifetime, array $addTagData = [], array $removeTagData = []): array
    {
        $failed = $this->doSaveCache($values, $lifetime);

        // Add Tags as symlinks
        foreach ($addTagData as $tagId => $ids) {
            $tagFolder = $this->getTagFolder($tagId);
            foreach ($ids as $id) {
                if ($failed && \in_array($id, $failed, true)) {
                    continue;
                }

                $file = $this->getFile($id);

                if (!@symlink($file, $tagLink = $this->getFile($id, true, $tagFolder)) && !is_link($tagLink)) {
                    @unlink($file);
                    $failed[] = $id;
                }
            }
        }

        // Unlink removed Tags
        foreach ($removeTagData as $tagId => $ids) {
            $tagFolder = $this->getTagFolder($tagId);
            foreach ($ids as $id) {
                if ($failed && \in_array($id, $failed, true)) {
                    continue;
                }

                @unlink($this->getFile($id, false, $tagFolder));
            }
        }

        return $failed;
    }

    /**
     * {@inheritdoc}
     */
    protected function doDeleteYieldTags(array $ids): iterable
    {
        foreach ($ids as $id) {
            $file = $this->getFile($id);
            if (!is_file($file) || !$h = @fopen($file, 'r')) {
                continue;
            }

            if ((\PHP_VERSION_ID >= 70300 || '\\' !== \DIRECTORY_SEPARATOR) && !@unlink($file)) {
                fclose($h);
                continue;
            }

            $meta = explode("\n", fread($h, 4096), 3)[2] ?? '';

            // detect the compact format used in marshall() using magic numbers in the form 9D-..-..-..-..-00-..-..-..-5F
            if (13 < \strlen($meta) && "\x9D" === $meta[0] && "\0" === $meta[5] && "\x5F" === $meta[9]) {
                $meta[9] = "\0";
                $tagLen = unpack('Nlen', $meta, 9)['len'];
                $meta = substr($meta, 13, $tagLen);

                if (0 < $tagLen -= \strlen($meta)) {
                    $meta .= fread($h, $tagLen);
                }

                try {
                    yield $id => '' === $meta ? [] : $this->marshaller->unmarshall($meta);
                } catch (\Exception $e) {
                    yield $id => [];
                }
            }

            fclose($h);

            if (\PHP_VERSION_ID < 70300 && '\\' === \DIRECTORY_SEPARATOR) {
                @unlink($file);
            }
        }
    }

    /**
     * {@inheritdoc}
     */
    protected function doDeleteTagRelations(array $tagData): bool
    {
        foreach ($tagData as $tagId => $idList) {
            $tagFolder = $this->getTagFolder($tagId);
            foreach ($idList as $id) {
                @unlink($this->getFile($id, false, $tagFolder));
            }
        }

        return true;
    }

    /**
     * {@inheritdoc}
     */
    protected function doInvalidate(array $tagIds): bool
    {
        foreach ($tagIds as $tagId) {
            if (!is_dir($tagFolder = $this->getTagFolder($tagId))) {
                continue;
            }

            set_error_handler(static function () {});

            try {
                if (rename($tagFolder, $renamed = substr_replace($tagFolder, bin2hex(random_bytes(4)), -9))) {
                    $tagFolder = $renamed.\DIRECTORY_SEPARATOR;
                } else {
                    $renamed = null;
                }

                foreach ($this->scanHashDir($tagFolder) as $itemLink) {
                    unlink(realpath($itemLink) ?: $itemLink);
                    unlink($itemLink);
                }

                if (null === $renamed) {
                    continue;
                }

                $chars = '+-ABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789';

                for ($i = 0; $i < 38; ++$i) {
                    for ($j = 0; $j < 38; ++$j) {
                        rmdir($tagFolder.$chars[$i].\DIRECTORY_SEPARATOR.$chars[$j]);
                    }
                    rmdir($tagFolder.$chars[$i]);
                }
                rmdir($renamed);
            } finally {
                restore_error_handler();
            }
        }

        return true;
    }

    private function getTagFolder(string $tagId): string
    {
        return $this->getFile($tagId, false, $this->directory.self::TAG_FOLDER.\DIRECTORY_SEPARATOR).\DIRECTORY_SEPARATOR;
    }
}
PKϤ$Zd���#cache/Adapter/FilesystemAdapter.phpnu�[���<?php

/*
 * This file is part of the Symfony package.
 *
 * (c) Fabien Potencier <fabien@symfony.com>
 *
 * For the full copyright and license information, please view the LICENSE
 * file that was distributed with this source code.
 */

namespace Symfony\Component\Cache\Adapter;

use Symfony\Component\Cache\Marshaller\DefaultMarshaller;
use Symfony\Component\Cache\Marshaller\MarshallerInterface;
use Symfony\Component\Cache\PruneableInterface;
use Symfony\Component\Cache\Traits\FilesystemTrait;

class FilesystemAdapter extends AbstractAdapter implements PruneableInterface
{
    use FilesystemTrait;

    public function __construct(string $namespace = '', int $defaultLifetime = 0, string $directory = null, MarshallerInterface $marshaller = null)
    {
        $this->marshaller = $marshaller ?? new DefaultMarshaller();
        parent::__construct('', $defaultLifetime);
        $this->init($namespace, $directory);
    }
}
PKϤ$Z6�t�0�0)cache/Adapter/AbstractTagAwareAdapter.phpnu�[���<?php

/*
 * This file is part of the Symfony package.
 *
 * (c) Fabien Potencier <fabien@symfony.com>
 *
 * For the full copyright and license information, please view the LICENSE
 * file that was distributed with this source code.
 */

namespace Symfony\Component\Cache\Adapter;

use Psr\Log\LoggerAwareInterface;
use Symfony\Component\Cache\CacheItem;
use Symfony\Component\Cache\Exception\InvalidArgumentException;
use Symfony\Component\Cache\ResettableInterface;
use Symfony\Component\Cache\Traits\AbstractAdapterTrait;
use Symfony\Component\Cache\Traits\ContractsTrait;
use Symfony\Contracts\Cache\TagAwareCacheInterface;

/**
 * Abstract for native TagAware adapters.
 *
 * To keep info on tags, the tags are both serialized as part of cache value and provided as tag ids
 * to Adapters on operations when needed for storage to doSave(), doDelete() & doInvalidate().
 *
 * @author Nicolas Grekas <p@tchwork.com>
 * @author André Rømcke <andre.romcke+symfony@gmail.com>
 *
 * @internal
 */
abstract class AbstractTagAwareAdapter implements TagAwareAdapterInterface, TagAwareCacheInterface, LoggerAwareInterface, ResettableInterface
{
    use AbstractAdapterTrait;
    use ContractsTrait;

    private const TAGS_PREFIX = "\0tags\0";

    protected function __construct(string $namespace = '', int $defaultLifetime = 0)
    {
        $this->namespace = '' === $namespace ? '' : CacheItem::validateKey($namespace).':';
        if (null !== $this->maxIdLength && \strlen($namespace) > $this->maxIdLength - 24) {
            throw new InvalidArgumentException(sprintf('Namespace must be %d chars max, %d given ("%s").', $this->maxIdLength - 24, \strlen($namespace), $namespace));
        }
        $this->createCacheItem = \Closure::bind(
            static function ($key, $value, $isHit) {
                $item = new CacheItem();
                $item->key = $key;
                $item->isTaggable = true;
                // If structure does not match what we expect return item as is (no value and not a hit)
                if (!\is_array($value) || !\array_key_exists('value', $value)) {
                    return $item;
                }
                $item->isHit = $isHit;
                // Extract value, tags and meta data from the cache value
                $item->value = $value['value'];
                $item->metadata[CacheItem::METADATA_TAGS] = $value['tags'] ?? [];
                if (isset($value['meta'])) {
                    // For compactness these values are packed, & expiry is offset to reduce size
                    $v = unpack('Ve/Nc', $value['meta']);
                    $item->metadata[CacheItem::METADATA_EXPIRY] = $v['e'] + CacheItem::METADATA_EXPIRY_OFFSET;
                    $item->metadata[CacheItem::METADATA_CTIME] = $v['c'];
                }

                return $item;
            },
            null,
            CacheItem::class
        );
        $getId = \Closure::fromCallable([$this, 'getId']);
        $tagPrefix = self::TAGS_PREFIX;
        $this->mergeByLifetime = \Closure::bind(
            static function ($deferred, &$expiredIds) use ($getId, $tagPrefix, $defaultLifetime) {
                $byLifetime = [];
                $now = microtime(true);
                $expiredIds = [];

                foreach ($deferred as $key => $item) {
                    $key = (string) $key;
                    if (null === $item->expiry) {
                        $ttl = 0 < $defaultLifetime ? $defaultLifetime : 0;
                    } elseif (0 === $item->expiry) {
                        $ttl = 0;
                    } elseif (0 >= $ttl = (int) (0.1 + $item->expiry - $now)) {
                        $expiredIds[] = $getId($key);
                        continue;
                    }
                    // Store Value and Tags on the cache value
                    if (isset(($metadata = $item->newMetadata)[CacheItem::METADATA_TAGS])) {
                        $value = ['value' => $item->value, 'tags' => $metadata[CacheItem::METADATA_TAGS]];
                        unset($metadata[CacheItem::METADATA_TAGS]);
                    } else {
                        $value = ['value' => $item->value, 'tags' => []];
                    }

                    if ($metadata) {
                        // For compactness, expiry and creation duration are packed, using magic numbers as separators
                        $value['meta'] = pack('VN', (int) (0.1 + $metadata[self::METADATA_EXPIRY] - self::METADATA_EXPIRY_OFFSET), $metadata[self::METADATA_CTIME]);
                    }

                    // Extract tag changes, these should be removed from values in doSave()
                    $value['tag-operations'] = ['add' => [], 'remove' => []];
                    $oldTags = $item->metadata[CacheItem::METADATA_TAGS] ?? [];
                    foreach (array_diff($value['tags'], $oldTags) as $addedTag) {
                        $value['tag-operations']['add'][] = $getId($tagPrefix.$addedTag);
                    }
                    foreach (array_diff($oldTags, $value['tags']) as $removedTag) {
                        $value['tag-operations']['remove'][] = $getId($tagPrefix.$removedTag);
                    }

                    $byLifetime[$ttl][$getId($key)] = $value;
                }

                return $byLifetime;
            },
            null,
            CacheItem::class
        );
    }

    /**
     * Persists several cache items immediately.
     *
     * @param array   $values        The values to cache, indexed by their cache identifier
     * @param int     $lifetime      The lifetime of the cached values, 0 for persisting until manual cleaning
     * @param array[] $addTagData    Hash where key is tag id, and array value is list of cache id's to add to tag
     * @param array[] $removeTagData Hash where key is tag id, and array value is list of cache id's to remove to tag
     *
     * @return array The identifiers that failed to be cached or a boolean stating if caching succeeded or not
     */
    abstract protected function doSave(array $values, int $lifetime, array $addTagData = [], array $removeTagData = []): array;

    /**
     * Removes multiple items from the pool and their corresponding tags.
     *
     * @param array $ids An array of identifiers that should be removed from the pool
     *
     * @return bool True if the items were successfully removed, false otherwise
     */
    abstract protected function doDelete(array $ids);

    /**
     * Removes relations between tags and deleted items.
     *
     * @param array $tagData Array of tag => key identifiers that should be removed from the pool
     */
    abstract protected function doDeleteTagRelations(array $tagData): bool;

    /**
     * Invalidates cached items using tags.
     *
     * @param string[] $tagIds An array of tags to invalidate, key is tag and value is tag id
     *
     * @return bool True on success
     */
    abstract protected function doInvalidate(array $tagIds): bool;

    /**
     * Delete items and yields the tags they were bound to.
     */
    protected function doDeleteYieldTags(array $ids): iterable
    {
        foreach ($this->doFetch($ids) as $id => $value) {
            yield $id => \is_array($value) && \is_array($value['tags'] ?? null) ? $value['tags'] : [];
        }

        $this->doDelete($ids);
    }

    /**
     * {@inheritdoc}
     */
    public function commit(): bool
    {
        $ok = true;
        $byLifetime = $this->mergeByLifetime;
        $byLifetime = $byLifetime($this->deferred, $expiredIds);
        $retry = $this->deferred = [];

        if ($expiredIds) {
            // Tags are not cleaned up in this case, however that is done on invalidateTags().
            $this->doDelete($expiredIds);
        }
        foreach ($byLifetime as $lifetime => $values) {
            try {
                $values = $this->extractTagData($values, $addTagData, $removeTagData);
                $e = $this->doSave($values, $lifetime, $addTagData, $removeTagData);
            } catch (\Exception $e) {
            }
            if (true === $e || [] === $e) {
                continue;
            }
            if (\is_array($e) || 1 === \count($values)) {
                foreach (\is_array($e) ? $e : array_keys($values) as $id) {
                    $ok = false;
                    $v = $values[$id];
                    $type = get_debug_type($v);
                    $message = sprintf('Failed to save key "{key}" of type %s%s', $type, $e instanceof \Exception ? ': '.$e->getMessage() : '.');
                    CacheItem::log($this->logger, $message, ['key' => substr($id, \strlen($this->namespace)), 'exception' => $e instanceof \Exception ? $e : null, 'cache-adapter' => get_debug_type($this)]);
                }
            } else {
                foreach ($values as $id => $v) {
                    $retry[$lifetime][] = $id;
                }
            }
        }

        // When bulk-save failed, retry each item individually
        foreach ($retry as $lifetime => $ids) {
            foreach ($ids as $id) {
                try {
                    $v = $byLifetime[$lifetime][$id];
                    $values = $this->extractTagData([$id => $v], $addTagData, $removeTagData);
                    $e = $this->doSave($values, $lifetime, $addTagData, $removeTagData);
                } catch (\Exception $e) {
                }
                if (true === $e || [] === $e) {
                    continue;
                }
                $ok = false;
                $type = get_debug_type($v);
                $message = sprintf('Failed to save key "{key}" of type %s%s', $type, $e instanceof \Exception ? ': '.$e->getMessage() : '.');
                CacheItem::log($this->logger, $message, ['key' => substr($id, \strlen($this->namespace)), 'exception' => $e instanceof \Exception ? $e : null, 'cache-adapter' => get_debug_type($this)]);
            }
        }

        return $ok;
    }

    /**
     * {@inheritdoc}
     */
    public function deleteItems(array $keys): bool
    {
        if (!$keys) {
            return true;
        }

        $ok = true;
        $ids = [];
        $tagData = [];

        foreach ($keys as $key) {
            $ids[$key] = $this->getId($key);
            unset($this->deferred[$key]);
        }

        try {
            foreach ($this->doDeleteYieldTags(array_values($ids)) as $id => $tags) {
                foreach ($tags as $tag) {
                    $tagData[$this->getId(self::TAGS_PREFIX.$tag)][] = $id;
                }
            }
        } catch (\Exception $e) {
            $ok = false;
        }

        try {
            if ((!$tagData || $this->doDeleteTagRelations($tagData)) && $ok) {
                return true;
            }
        } catch (\Exception $e) {
        }

        // When bulk-delete failed, retry each item individually
        foreach ($ids as $key => $id) {
            try {
                $e = null;
                if ($this->doDelete([$id])) {
                    continue;
                }
            } catch (\Exception $e) {
            }
            $message = 'Failed to delete key "{key}"'.($e instanceof \Exception ? ': '.$e->getMessage() : '.');
            CacheItem::log($this->logger, $message, ['key' => $key, 'exception' => $e, 'cache-adapter' => get_debug_type($this)]);
            $ok = false;
        }

        return $ok;
    }

    /**
     * {@inheritdoc}
     */
    public function invalidateTags(array $tags)
    {
        if (empty($tags)) {
            return false;
        }

        $tagIds = [];
        foreach (array_unique($tags) as $tag) {
            $tagIds[] = $this->getId(self::TAGS_PREFIX.$tag);
        }

        if ($this->doInvalidate($tagIds)) {
            return true;
        }

        return false;
    }

    /**
     * Extracts tags operation data from $values set in mergeByLifetime, and returns values without it.
     */
    private function extractTagData(array $values, ?array &$addTagData, ?array &$removeTagData): array
    {
        $addTagData = $removeTagData = [];
        foreach ($values as $id => $value) {
            foreach ($value['tag-operations']['add'] as $tag => $tagId) {
                $addTagData[$tagId][] = $id;
            }

            foreach ($value['tag-operations']['remove'] as $tag => $tagId) {
                $removeTagData[$tagId][] = $id;
            }

            unset($values[$id]['tag-operations']);
        }

        return $values;
    }
}
PKϤ$Z�/�r r cache/Adapter/ProxyAdapter.phpnu�[���<?php

/*
 * This file is part of the Symfony package.
 *
 * (c) Fabien Potencier <fabien@symfony.com>
 *
 * For the full copyright and license information, please view the LICENSE
 * file that was distributed with this source code.
 */

namespace Symfony\Component\Cache\Adapter;

use Psr\Cache\CacheItemInterface;
use Psr\Cache\CacheItemPoolInterface;
use Symfony\Component\Cache\CacheItem;
use Symfony\Component\Cache\PruneableInterface;
use Symfony\Component\Cache\ResettableInterface;
use Symfony\Component\Cache\Traits\ContractsTrait;
use Symfony\Component\Cache\Traits\ProxyTrait;
use Symfony\Contracts\Cache\CacheInterface;

/**
 * @author Nicolas Grekas <p@tchwork.com>
 */
class ProxyAdapter implements AdapterInterface, CacheInterface, PruneableInterface, ResettableInterface
{
    use ContractsTrait;
    use ProxyTrait;

    private $namespace;
    private $namespaceLen;
    private $createCacheItem;
    private $setInnerItem;
    private $poolHash;
    private $defaultLifetime;

    public function __construct(CacheItemPoolInterface $pool, string $namespace = '', int $defaultLifetime = 0)
    {
        $this->pool = $pool;
        $this->poolHash = $poolHash = spl_object_hash($pool);
        $this->namespace = '' === $namespace ? '' : CacheItem::validateKey($namespace);
        $this->namespaceLen = \strlen($namespace);
        $this->defaultLifetime = $defaultLifetime;
        $this->createCacheItem = \Closure::bind(
            static function ($key, $innerItem) use ($poolHash) {
                $item = new CacheItem();
                $item->key = $key;

                if (null === $innerItem) {
                    return $item;
                }

                $item->value = $v = $innerItem->get();
                $item->isHit = $innerItem->isHit();
                $item->innerItem = $innerItem;
                $item->poolHash = $poolHash;

                // Detect wrapped values that encode for their expiry and creation duration
                // For compactness, these values are packed in the key of an array using
                // magic numbers in the form 9D-..-..-..-..-00-..-..-..-5F
                if (\is_array($v) && 1 === \count($v) && 10 === \strlen($k = (string) key($v)) && "\x9D" === $k[0] && "\0" === $k[5] && "\x5F" === $k[9]) {
                    $item->value = $v[$k];
                    $v = unpack('Ve/Nc', substr($k, 1, -1));
                    $item->metadata[CacheItem::METADATA_EXPIRY] = $v['e'] + CacheItem::METADATA_EXPIRY_OFFSET;
                    $item->metadata[CacheItem::METADATA_CTIME] = $v['c'];
                } elseif ($innerItem instanceof CacheItem) {
                    $item->metadata = $innerItem->metadata;
                }
                $innerItem->set(null);

                return $item;
            },
            null,
            CacheItem::class
        );
        $this->setInnerItem = \Closure::bind(
            /**
             * @param array $item A CacheItem cast to (array); accessing protected properties requires adding the "\0*\0" PHP prefix
             */
            static function (CacheItemInterface $innerItem, array $item) {
                // Tags are stored separately, no need to account for them when considering this item's newly set metadata
                if (isset(($metadata = $item["\0*\0newMetadata"])[CacheItem::METADATA_TAGS])) {
                    unset($metadata[CacheItem::METADATA_TAGS]);
                }
                if ($metadata) {
                    // For compactness, expiry and creation duration are packed in the key of an array, using magic numbers as separators
                    $item["\0*\0value"] = ["\x9D".pack('VN', (int) (0.1 + $metadata[self::METADATA_EXPIRY] - self::METADATA_EXPIRY_OFFSET), $metadata[self::METADATA_CTIME])."\x5F" => $item["\0*\0value"]];
                }
                $innerItem->set($item["\0*\0value"]);
                $innerItem->expiresAt(null !== $item["\0*\0expiry"] ? \DateTime::createFromFormat('U.u', sprintf('%.6F', 0 === $item["\0*\0expiry"] ? \PHP_INT_MAX : $item["\0*\0expiry"])) : null);
            },
            null,
            CacheItem::class
        );
    }

    /**
     * {@inheritdoc}
     */
    public function get(string $key, callable $callback, float $beta = null, array &$metadata = null)
    {
        if (!$this->pool instanceof CacheInterface) {
            return $this->doGet($this, $key, $callback, $beta, $metadata);
        }

        return $this->pool->get($this->getId($key), function ($innerItem, bool &$save) use ($key, $callback) {
            $item = ($this->createCacheItem)($key, $innerItem);
            $item->set($value = $callback($item, $save));
            ($this->setInnerItem)($innerItem, (array) $item);

            return $value;
        }, $beta, $metadata);
    }

    /**
     * {@inheritdoc}
     */
    public function getItem($key)
    {
        $f = $this->createCacheItem;
        $item = $this->pool->getItem($this->getId($key));

        return $f($key, $item);
    }

    /**
     * {@inheritdoc}
     */
    public function getItems(array $keys = [])
    {
        if ($this->namespaceLen) {
            foreach ($keys as $i => $key) {
                $keys[$i] = $this->getId($key);
            }
        }

        return $this->generateItems($this->pool->getItems($keys));
    }

    /**
     * {@inheritdoc}
     *
     * @return bool
     */
    public function hasItem($key)
    {
        return $this->pool->hasItem($this->getId($key));
    }

    /**
     * {@inheritdoc}
     *
     * @return bool
     */
    public function clear(string $prefix = '')
    {
        if ($this->pool instanceof AdapterInterface) {
            return $this->pool->clear($this->namespace.$prefix);
        }

        return $this->pool->clear();
    }

    /**
     * {@inheritdoc}
     *
     * @return bool
     */
    public function deleteItem($key)
    {
        return $this->pool->deleteItem($this->getId($key));
    }

    /**
     * {@inheritdoc}
     *
     * @return bool
     */
    public function deleteItems(array $keys)
    {
        if ($this->namespaceLen) {
            foreach ($keys as $i => $key) {
                $keys[$i] = $this->getId($key);
            }
        }

        return $this->pool->deleteItems($keys);
    }

    /**
     * {@inheritdoc}
     *
     * @return bool
     */
    public function save(CacheItemInterface $item)
    {
        return $this->doSave($item, __FUNCTION__);
    }

    /**
     * {@inheritdoc}
     *
     * @return bool
     */
    public function saveDeferred(CacheItemInterface $item)
    {
        return $this->doSave($item, __FUNCTION__);
    }

    /**
     * {@inheritdoc}
     *
     * @return bool
     */
    public function commit()
    {
        return $this->pool->commit();
    }

    private function doSave(CacheItemInterface $item, string $method)
    {
        if (!$item instanceof CacheItem) {
            return false;
        }
        $item = (array) $item;
        if (null === $item["\0*\0expiry"] && 0 < $this->defaultLifetime) {
            $item["\0*\0expiry"] = microtime(true) + $this->defaultLifetime;
        }

        if ($item["\0*\0poolHash"] === $this->poolHash && $item["\0*\0innerItem"]) {
            $innerItem = $item["\0*\0innerItem"];
        } elseif ($this->pool instanceof AdapterInterface) {
            // this is an optimization specific for AdapterInterface implementations
            // so we can save a round-trip to the backend by just creating a new item
            $f = $this->createCacheItem;
            $innerItem = $f($this->namespace.$item["\0*\0key"], null);
        } else {
            $innerItem = $this->pool->getItem($this->namespace.$item["\0*\0key"]);
        }

        ($this->setInnerItem)($innerItem, $item);

        return $this->pool->$method($innerItem);
    }

    private function generateItems(iterable $items)
    {
        $f = $this->createCacheItem;

        foreach ($items as $key => $item) {
            if ($this->namespaceLen) {
                $key = substr($key, $this->namespaceLen);
            }

            yield $key => $f($key, $item);
        }
    }

    private function getId($key): string
    {
        CacheItem::validateKey($key);

        return $this->namespace.$key;
    }
}
PKϤ$Z��,,,,&cache/Adapter/RedisTagAwareAdapter.phpnu�[���<?php

/*
 * This file is part of the Symfony package.
 *
 * (c) Fabien Potencier <fabien@symfony.com>
 *
 * For the full copyright and license information, please view the LICENSE
 * file that was distributed with this source code.
 */

namespace Symfony\Component\Cache\Adapter;

use Predis\Connection\Aggregate\ClusterInterface;
use Predis\Connection\Aggregate\PredisCluster;
use Predis\Response\Status;
use Symfony\Component\Cache\Exception\InvalidArgumentException;
use Symfony\Component\Cache\Exception\LogicException;
use Symfony\Component\Cache\Marshaller\DeflateMarshaller;
use Symfony\Component\Cache\Marshaller\MarshallerInterface;
use Symfony\Component\Cache\Marshaller\TagAwareMarshaller;
use Symfony\Component\Cache\Traits\RedisTrait;

/**
 * Stores tag id <> cache id relationship as a Redis Set, lookup on invalidation using RENAME+SMEMBERS.
 *
 * Set (tag relation info) is stored without expiry (non-volatile), while cache always gets an expiry (volatile) even
 * if not set by caller. Thus if you configure redis with the right eviction policy you can be safe this tag <> cache
 * relationship survives eviction (cache cleanup when Redis runs out of memory).
 *
 * Requirements:
 *  - Client: PHP Redis or Predis
 *            Note: Due to lack of RENAME support it is NOT recommended to use Cluster on Predis, instead use phpredis.
 *  - Server: Redis 2.8+
 *            Configured with any `volatile-*` eviction policy, OR `noeviction` if it will NEVER fill up memory
 *
 * Design limitations:
 *  - Max 4 billion cache keys per cache tag as limited by Redis Set datatype.
 *    E.g. If you use a "all" items tag for expiry instead of clear(), that limits you to 4 billion cache items also.
 *
 * @see https://redis.io/topics/lru-cache#eviction-policies Documentation for Redis eviction policies.
 * @see https://redis.io/topics/data-types#sets Documentation for Redis Set datatype.
 *
 * @author Nicolas Grekas <p@tchwork.com>
 * @author André Rømcke <andre.romcke+symfony@gmail.com>
 */
class RedisTagAwareAdapter extends AbstractTagAwareAdapter
{
    use RedisTrait;

    /**
     * Limits for how many keys are deleted in batch.
     */
    private const BULK_DELETE_LIMIT = 10000;

    /**
     * On cache items without a lifetime set, we set it to 100 days. This is to make sure cache items are
     * preferred to be evicted over tag Sets, if eviction policy is configured according to requirements.
     */
    private const DEFAULT_CACHE_TTL = 8640000;

    /**
     * @var string|null detected eviction policy used on Redis server
     */
    private $redisEvictionPolicy;

    /**
     * @param \Redis|\RedisArray|\RedisCluster|\Predis\ClientInterface $redisClient     The redis client
     * @param string                                                   $namespace       The default namespace
     * @param int                                                      $defaultLifetime The default lifetime
     */
    public function __construct($redisClient, string $namespace = '', int $defaultLifetime = 0, MarshallerInterface $marshaller = null)
    {
        if ($redisClient instanceof \Predis\ClientInterface && $redisClient->getConnection() instanceof ClusterInterface && !$redisClient->getConnection() instanceof PredisCluster) {
            throw new InvalidArgumentException(sprintf('Unsupported Predis cluster connection: only "%s" is, "%s" given.', PredisCluster::class, get_debug_type($redisClient->getConnection())));
        }

        if (\defined('Redis::OPT_COMPRESSION') && ($redisClient instanceof \Redis || $redisClient instanceof \RedisArray || $redisClient instanceof \RedisCluster)) {
            $compression = $redisClient->getOption(\Redis::OPT_COMPRESSION);

            foreach (\is_array($compression) ? $compression : [$compression] as $c) {
                if (\Redis::COMPRESSION_NONE !== $c) {
                    throw new InvalidArgumentException(sprintf('phpredis compression must be disabled when using "%s", use "%s" instead.', static::class, DeflateMarshaller::class));
                }
            }
        }

        $this->init($redisClient, $namespace, $defaultLifetime, new TagAwareMarshaller($marshaller));
    }

    /**
     * {@inheritdoc}
     */
    protected function doSave(array $values, int $lifetime, array $addTagData = [], array $delTagData = []): array
    {
        $eviction = $this->getRedisEvictionPolicy();
        if ('noeviction' !== $eviction && 0 !== strpos($eviction, 'volatile-')) {
            throw new LogicException(sprintf('Redis maxmemory-policy setting "%s" is *not* supported by RedisTagAwareAdapter, use "noeviction" or  "volatile-*" eviction policies.', $eviction));
        }

        // serialize values
        if (!$serialized = $this->marshaller->marshall($values, $failed)) {
            return $failed;
        }

        // While pipeline isn't supported on RedisCluster, other setups will at least benefit from doing this in one op
        $results = $this->pipeline(static function () use ($serialized, $lifetime, $addTagData, $delTagData, $failed) {
            // Store cache items, force a ttl if none is set, as there is no MSETEX we need to set each one
            foreach ($serialized as $id => $value) {
                yield 'setEx' => [
                    $id,
                    0 >= $lifetime ? self::DEFAULT_CACHE_TTL : $lifetime,
                    $value,
                ];
            }

            // Add and Remove Tags
            foreach ($addTagData as $tagId => $ids) {
                if (!$failed || $ids = array_diff($ids, $failed)) {
                    yield 'sAdd' => array_merge([$tagId], $ids);
                }
            }

            foreach ($delTagData as $tagId => $ids) {
                if (!$failed || $ids = array_diff($ids, $failed)) {
                    yield 'sRem' => array_merge([$tagId], $ids);
                }
            }
        });

        foreach ($results as $id => $result) {
            // Skip results of SADD/SREM operations, they'll be 1 or 0 depending on if set value already existed or not
            if (is_numeric($result)) {
                continue;
            }
            // setEx results
            if (true !== $result && (!$result instanceof Status || Status::get('OK') !== $result)) {
                $failed[] = $id;
            }
        }

        return $failed;
    }

    /**
     * {@inheritdoc}
     */
    protected function doDeleteYieldTags(array $ids): iterable
    {
        $lua = <<<'EOLUA'
            local v = redis.call('GET', KEYS[1])
            redis.call('DEL', KEYS[1])

            if not v or v:len() <= 13 or v:byte(1) ~= 0x9D or v:byte(6) ~= 0 or v:byte(10) ~= 0x5F then
                return ''
            end

            return v:sub(14, 13 + v:byte(13) + v:byte(12) * 256 + v:byte(11) * 65536)
EOLUA;

        if ($this->redis instanceof \Predis\ClientInterface) {
            $evalArgs = [$lua, 1, &$id];
        } else {
            $evalArgs = [$lua, [&$id], 1];
        }

        $results = $this->pipeline(function () use ($ids, &$id, $evalArgs) {
            foreach ($ids as $id) {
                yield 'eval' => $evalArgs;
            }
        });

        foreach ($results as $id => $result) {
            try {
                yield $id => !\is_string($result) || '' === $result ? [] : $this->marshaller->unmarshall($result);
            } catch (\Exception $e) {
                yield $id => [];
            }
        }
    }

    /**
     * {@inheritdoc}
     */
    protected function doDeleteTagRelations(array $tagData): bool
    {
        $this->pipeline(static function () use ($tagData) {
            foreach ($tagData as $tagId => $idList) {
                array_unshift($idList, $tagId);
                yield 'sRem' => $idList;
            }
        })->rewind();

        return true;
    }

    /**
     * {@inheritdoc}
     */
    protected function doInvalidate(array $tagIds): bool
    {
        if (!$this->redis instanceof \Predis\ClientInterface || !$this->redis->getConnection() instanceof PredisCluster) {
            $movedTagSetIds = $this->renameKeys($this->redis, $tagIds);
        } else {
            $clusterConnection = $this->redis->getConnection();
            $tagIdsByConnection = new \SplObjectStorage();
            $movedTagSetIds = [];

            foreach ($tagIds as $id) {
                $connection = $clusterConnection->getConnectionByKey($id);
                $slot = $tagIdsByConnection[$connection] ?? $tagIdsByConnection[$connection] = new \ArrayObject();
                $slot[] = $id;
            }

            foreach ($tagIdsByConnection as $connection) {
                $slot = $tagIdsByConnection[$connection];
                $movedTagSetIds = array_merge($movedTagSetIds, $this->renameKeys(new $this->redis($connection, $this->redis->getOptions()), $slot->getArrayCopy()));
            }
        }

        // No Sets found
        if (!$movedTagSetIds) {
            return false;
        }

        // Now safely take the time to read the keys in each set and collect ids we need to delete
        $tagIdSets = $this->pipeline(static function () use ($movedTagSetIds) {
            foreach ($movedTagSetIds as $movedTagId) {
                yield 'sMembers' => [$movedTagId];
            }
        });

        // Return combination of the temporary Tag Set ids and their values (cache ids)
        $ids = array_merge($movedTagSetIds, ...iterator_to_array($tagIdSets, false));

        // Delete cache in chunks to avoid overloading the connection
        foreach (array_chunk(array_unique($ids), self::BULK_DELETE_LIMIT) as $chunkIds) {
            $this->doDelete($chunkIds);
        }

        return true;
    }

    /**
     * Renames several keys in order to be able to operate on them without risk of race conditions.
     *
     * Filters out keys that do not exist before returning new keys.
     *
     * @see https://redis.io/commands/rename
     * @see https://redis.io/topics/cluster-spec#keys-hash-tags
     *
     * @return array Filtered list of the valid moved keys (only those that existed)
     */
    private function renameKeys($redis, array $ids): array
    {
        $newIds = [];
        $uniqueToken = bin2hex(random_bytes(10));

        $results = $this->pipeline(static function () use ($ids, $uniqueToken) {
            foreach ($ids as $id) {
                yield 'rename' => [$id, '{'.$id.'}'.$uniqueToken];
            }
        }, $redis);

        foreach ($results as $id => $result) {
            if (true === $result || ($result instanceof Status && Status::get('OK') === $result)) {
                // Only take into account if ok (key existed), will be false on phpredis if it did not exist
                $newIds[] = '{'.$id.'}'.$uniqueToken;
            }
        }

        return $newIds;
    }

    private function getRedisEvictionPolicy(): string
    {
        if (null !== $this->redisEvictionPolicy) {
            return $this->redisEvictionPolicy;
        }

        foreach ($this->getHosts() as $host) {
            $info = $host->info('Memory');
            $info = $info['Memory'] ?? $info;

            return $this->redisEvictionPolicy = $info['maxmemory_policy'];
        }

        return $this->redisEvictionPolicy = '';
    }
}
PKϤ$Z����"cache/Adapter/TraceableAdapter.phpnu�[���<?php

/*
 * This file is part of the Symfony package.
 *
 * (c) Fabien Potencier <fabien@symfony.com>
 *
 * For the full copyright and license information, please view the LICENSE
 * file that was distributed with this source code.
 */

namespace Symfony\Component\Cache\Adapter;

use Psr\Cache\CacheItemInterface;
use Symfony\Component\Cache\CacheItem;
use Symfony\Component\Cache\PruneableInterface;
use Symfony\Component\Cache\ResettableInterface;
use Symfony\Contracts\Cache\CacheInterface;
use Symfony\Contracts\Service\ResetInterface;

/**
 * An adapter that collects data about all cache calls.
 *
 * @author Aaron Scherer <aequasi@gmail.com>
 * @author Tobias Nyholm <tobias.nyholm@gmail.com>
 * @author Nicolas Grekas <p@tchwork.com>
 */
class TraceableAdapter implements AdapterInterface, CacheInterface, PruneableInterface, ResettableInterface
{
    protected $pool;
    private $calls = [];

    public function __construct(AdapterInterface $pool)
    {
        $this->pool = $pool;
    }

    /**
     * {@inheritdoc}
     */
    public function get(string $key, callable $callback, float $beta = null, array &$metadata = null)
    {
        if (!$this->pool instanceof CacheInterface) {
            throw new \BadMethodCallException(sprintf('Cannot call "%s::get()": this class doesn\'t implement "%s".', get_debug_type($this->pool), CacheInterface::class));
        }

        $isHit = true;
        $callback = function (CacheItem $item, bool &$save) use ($callback, &$isHit) {
            $isHit = $item->isHit();

            return $callback($item, $save);
        };

        $event = $this->start(__FUNCTION__);
        try {
            $value = $this->pool->get($key, $callback, $beta, $metadata);
            $event->result[$key] = get_debug_type($value);
        } finally {
            $event->end = microtime(true);
        }
        if ($isHit) {
            ++$event->hits;
        } else {
            ++$event->misses;
        }

        return $value;
    }

    /**
     * {@inheritdoc}
     */
    public function getItem($key)
    {
        $event = $this->start(__FUNCTION__);
        try {
            $item = $this->pool->getItem($key);
        } finally {
            $event->end = microtime(true);
        }
        if ($event->result[$key] = $item->isHit()) {
            ++$event->hits;
        } else {
            ++$event->misses;
        }

        return $item;
    }

    /**
     * {@inheritdoc}
     *
     * @return bool
     */
    public function hasItem($key)
    {
        $event = $this->start(__FUNCTION__);
        try {
            return $event->result[$key] = $this->pool->hasItem($key);
        } finally {
            $event->end = microtime(true);
        }
    }

    /**
     * {@inheritdoc}
     *
     * @return bool
     */
    public function deleteItem($key)
    {
        $event = $this->start(__FUNCTION__);
        try {
            return $event->result[$key] = $this->pool->deleteItem($key);
        } finally {
            $event->end = microtime(true);
        }
    }

    /**
     * {@inheritdoc}
     *
     * @return bool
     */
    public function save(CacheItemInterface $item)
    {
        $event = $this->start(__FUNCTION__);
        try {
            return $event->result[$item->getKey()] = $this->pool->save($item);
        } finally {
            $event->end = microtime(true);
        }
    }

    /**
     * {@inheritdoc}
     *
     * @return bool
     */
    public function saveDeferred(CacheItemInterface $item)
    {
        $event = $this->start(__FUNCTION__);
        try {
            return $event->result[$item->getKey()] = $this->pool->saveDeferred($item);
        } finally {
            $event->end = microtime(true);
        }
    }

    /**
     * {@inheritdoc}
     */
    public function getItems(array $keys = [])
    {
        $event = $this->start(__FUNCTION__);
        try {
            $result = $this->pool->getItems($keys);
        } finally {
            $event->end = microtime(true);
        }
        $f = function () use ($result, $event) {
            $event->result = [];
            foreach ($result as $key => $item) {
                if ($event->result[$key] = $item->isHit()) {
                    ++$event->hits;
                } else {
                    ++$event->misses;
                }
                yield $key => $item;
            }
        };

        return $f();
    }

    /**
     * {@inheritdoc}
     *
     * @return bool
     */
    public function clear(string $prefix = '')
    {
        $event = $this->start(__FUNCTION__);
        try {
            if ($this->pool instanceof AdapterInterface) {
                return $event->result = $this->pool->clear($prefix);
            }

            return $event->result = $this->pool->clear();
        } finally {
            $event->end = microtime(true);
        }
    }

    /**
     * {@inheritdoc}
     *
     * @return bool
     */
    public function deleteItems(array $keys)
    {
        $event = $this->start(__FUNCTION__);
        $event->result['keys'] = $keys;
        try {
            return $event->result['result'] = $this->pool->deleteItems($keys);
        } finally {
            $event->end = microtime(true);
        }
    }

    /**
     * {@inheritdoc}
     *
     * @return bool
     */
    public function commit()
    {
        $event = $this->start(__FUNCTION__);
        try {
            return $event->result = $this->pool->commit();
        } finally {
            $event->end = microtime(true);
        }
    }

    /**
     * {@inheritdoc}
     */
    public function prune()
    {
        if (!$this->pool instanceof PruneableInterface) {
            return false;
        }
        $event = $this->start(__FUNCTION__);
        try {
            return $event->result = $this->pool->prune();
        } finally {
            $event->end = microtime(true);
        }
    }

    /**
     * {@inheritdoc}
     */
    public function reset()
    {
        if ($this->pool instanceof ResetInterface) {
            $this->pool->reset();
        }

        $this->clearCalls();
    }

    /**
     * {@inheritdoc}
     */
    public function delete(string $key): bool
    {
        $event = $this->start(__FUNCTION__);
        try {
            return $event->result[$key] = $this->pool->deleteItem($key);
        } finally {
            $event->end = microtime(true);
        }
    }

    public function getCalls()
    {
        return $this->calls;
    }

    public function clearCalls()
    {
        $this->calls = [];
    }

    protected function start($name)
    {
        $this->calls[] = $event = new TraceableAdapterEvent();
        $event->name = $name;
        $event->start = microtime(true);

        return $event;
    }
}

class TraceableAdapterEvent
{
    public $name;
    public $start;
    public $end;
    public $result;
    public $hits = 0;
    public $misses = 0;
}
PKϤ$Zc~�cache/Adapter/RedisAdapter.phpnu�[���<?php

/*
 * This file is part of the Symfony package.
 *
 * (c) Fabien Potencier <fabien@symfony.com>
 *
 * For the full copyright and license information, please view the LICENSE
 * file that was distributed with this source code.
 */

namespace Symfony\Component\Cache\Adapter;

use Symfony\Component\Cache\Marshaller\MarshallerInterface;
use Symfony\Component\Cache\Traits\RedisTrait;

class RedisAdapter extends AbstractAdapter
{
    use RedisTrait;

    /**
     * @param \Redis|\RedisArray|\RedisCluster|\Predis\ClientInterface $redisClient     The redis client
     * @param string                                                   $namespace       The default namespace
     * @param int                                                      $defaultLifetime The default lifetime
     */
    public function __construct($redisClient, string $namespace = '', int $defaultLifetime = 0, MarshallerInterface $marshaller = null)
    {
        $this->init($redisClient, $namespace, $defaultLifetime, $marshaller);
    }
}
PKϤ$Z���@(cache/Adapter/CouchbaseBucketAdapter.phpnu�[���<?php

/*
 * This file is part of the Symfony package.
 *
 * (c) Fabien Potencier <fabien@symfony.com>
 *
 * For the full copyright and license information, please view the LICENSE
 * file that was distributed with this source code.
 */

namespace Symfony\Component\Cache\Adapter;

use Symfony\Component\Cache\Exception\CacheException;
use Symfony\Component\Cache\Exception\InvalidArgumentException;
use Symfony\Component\Cache\Marshaller\DefaultMarshaller;
use Symfony\Component\Cache\Marshaller\MarshallerInterface;

/**
 * @author Antonio Jose Cerezo Aranda <aj.cerezo@gmail.com>
 */
class CouchbaseBucketAdapter extends AbstractAdapter
{
    private const THIRTY_DAYS_IN_SECONDS = 2592000;
    private const MAX_KEY_LENGTH = 250;
    private const KEY_NOT_FOUND = 13;
    private const VALID_DSN_OPTIONS = [
        'operationTimeout',
        'configTimeout',
        'configNodeTimeout',
        'n1qlTimeout',
        'httpTimeout',
        'configDelay',
        'htconfigIdleTimeout',
        'durabilityInterval',
        'durabilityTimeout',
    ];

    private $bucket;
    private $marshaller;

    public function __construct(\CouchbaseBucket $bucket, string $namespace = '', int $defaultLifetime = 0, MarshallerInterface $marshaller = null)
    {
        if (!static::isSupported()) {
            throw new CacheException('Couchbase >= 2.6.0 < 3.0.0 is required.');
        }

        $this->maxIdLength = static::MAX_KEY_LENGTH;

        $this->bucket = $bucket;

        parent::__construct($namespace, $defaultLifetime);
        $this->enableVersioning();
        $this->marshaller = $marshaller ?? new DefaultMarshaller();
    }

    /**
     * @param array|string $servers
     */
    public static function createConnection($servers, array $options = []): \CouchbaseBucket
    {
        if (\is_string($servers)) {
            $servers = [$servers];
        } elseif (!\is_array($servers)) {
            throw new \TypeError(sprintf('Argument 1 passed to "%s()" must be array or string, "%s" given.', __METHOD__, get_debug_type($servers)));
        }

        if (!static::isSupported()) {
            throw new CacheException('Couchbase >= 2.6.0 < 3.0.0 is required.');
        }

        set_error_handler(function ($type, $msg, $file, $line) { throw new \ErrorException($msg, 0, $type, $file, $line); });

        $dsnPattern = '/^(?<protocol>couchbase(?:s)?)\:\/\/(?:(?<username>[^\:]+)\:(?<password>[^\@]{6,})@)?'
            .'(?<host>[^\:]+(?:\:\d+)?)(?:\/(?<bucketName>[^\?]+))(?:\?(?<options>.*))?$/i';

        $newServers = [];
        $protocol = 'couchbase';
        try {
            $options = self::initOptions($options);
            $username = $options['username'];
            $password = $options['password'];

            foreach ($servers as $dsn) {
                if (0 !== strpos($dsn, 'couchbase:')) {
                    throw new InvalidArgumentException(sprintf('Invalid Couchbase DSN: "%s" does not start with "couchbase:".', $dsn));
                }

                preg_match($dsnPattern, $dsn, $matches);

                $username = $matches['username'] ?: $username;
                $password = $matches['password'] ?: $password;
                $protocol = $matches['protocol'] ?: $protocol;

                if (isset($matches['options'])) {
                    $optionsInDsn = self::getOptions($matches['options']);

                    foreach ($optionsInDsn as $parameter => $value) {
                        $options[$parameter] = $value;
                    }
                }

                $newServers[] = $matches['host'];
            }

            $connectionString = $protocol.'://'.implode(',', $newServers);

            $client = new \CouchbaseCluster($connectionString);
            $client->authenticateAs($username, $password);

            $bucket = $client->openBucket($matches['bucketName']);

            unset($options['username'], $options['password']);
            foreach ($options as $option => $value) {
                if (!empty($value)) {
                    $bucket->$option = $value;
                }
            }

            return $bucket;
        } finally {
            restore_error_handler();
        }
    }

    public static function isSupported(): bool
    {
        return \extension_loaded('couchbase') && version_compare(phpversion('couchbase'), '2.6.0', '>=') && version_compare(phpversion('couchbase'), '3.0', '<');
    }

    private static function getOptions(string $options): array
    {
        $results = [];
        $optionsInArray = explode('&', $options);

        foreach ($optionsInArray as $option) {
            [$key, $value] = explode('=', $option);

            if (\in_array($key, static::VALID_DSN_OPTIONS, true)) {
                $results[$key] = $value;
            }
        }

        return $results;
    }

    private static function initOptions(array $options): array
    {
        $options['username'] = $options['username'] ?? '';
        $options['password'] = $options['password'] ?? '';
        $options['operationTimeout'] = $options['operationTimeout'] ?? 0;
        $options['configTimeout'] = $options['configTimeout'] ?? 0;
        $options['configNodeTimeout'] = $options['configNodeTimeout'] ?? 0;
        $options['n1qlTimeout'] = $options['n1qlTimeout'] ?? 0;
        $options['httpTimeout'] = $options['httpTimeout'] ?? 0;
        $options['configDelay'] = $options['configDelay'] ?? 0;
        $options['htconfigIdleTimeout'] = $options['htconfigIdleTimeout'] ?? 0;
        $options['durabilityInterval'] = $options['durabilityInterval'] ?? 0;
        $options['durabilityTimeout'] = $options['durabilityTimeout'] ?? 0;

        return $options;
    }

    /**
     * {@inheritdoc}
     */
    protected function doFetch(array $ids)
    {
        $resultsCouchbase = $this->bucket->get($ids);

        $results = [];
        foreach ($resultsCouchbase as $key => $value) {
            if (null !== $value->error) {
                continue;
            }
            $results[$key] = $this->marshaller->unmarshall($value->value);
        }

        return $results;
    }

    /**
     * {@inheritdoc}
     */
    protected function doHave($id): bool
    {
        return false !== $this->bucket->get($id);
    }

    /**
     * {@inheritdoc}
     */
    protected function doClear($namespace): bool
    {
        if ('' === $namespace) {
            $this->bucket->manager()->flush();

            return true;
        }

        return false;
    }

    /**
     * {@inheritdoc}
     */
    protected function doDelete(array $ids): bool
    {
        $results = $this->bucket->remove(array_values($ids));

        foreach ($results as $key => $result) {
            if (null !== $result->error && static::KEY_NOT_FOUND !== $result->error->getCode()) {
                continue;
            }
            unset($results[$key]);
        }

        return 0 === \count($results);
    }

    /**
     * {@inheritdoc}
     */
    protected function doSave(array $values, $lifetime)
    {
        if (!$values = $this->marshaller->marshall($values, $failed)) {
            return $failed;
        }

        $lifetime = $this->normalizeExpiry($lifetime);

        $ko = [];
        foreach ($values as $key => $value) {
            $result = $this->bucket->upsert($key, $value, ['expiry' => $lifetime]);

            if (null !== $result->error) {
                $ko[$key] = $result;
            }
        }

        return [] === $ko ? true : $ko;
    }

    private function normalizeExpiry(int $expiry): int
    {
        if ($expiry && $expiry > static::THIRTY_DAYS_IN_SECONDS) {
            $expiry += time();
        }

        return $expiry;
    }
}
PKϤ$Z��:�5�5"cache/Adapter/MemcachedAdapter.phpnu�[���<?php

/*
 * This file is part of the Symfony package.
 *
 * (c) Fabien Potencier <fabien@symfony.com>
 *
 * For the full copyright and license information, please view the LICENSE
 * file that was distributed with this source code.
 */

namespace Symfony\Component\Cache\Adapter;

use Symfony\Component\Cache\Exception\CacheException;
use Symfony\Component\Cache\Exception\InvalidArgumentException;
use Symfony\Component\Cache\Marshaller\DefaultMarshaller;
use Symfony\Component\Cache\Marshaller\MarshallerInterface;

/**
 * @author Rob Frawley 2nd <rmf@src.run>
 * @author Nicolas Grekas <p@tchwork.com>
 */
class MemcachedAdapter extends AbstractAdapter
{
    /**
     * We are replacing characters that are illegal in Memcached keys with reserved characters from
     * {@see \Symfony\Contracts\Cache\ItemInterface::RESERVED_CHARACTERS} that are legal in Memcached.
This conversation was marked as resolved by lstrojny
     * Note: don’t use {@see \Symfony\Component\Cache\Adapter\AbstractAdapter::NS_SEPARATOR}.
     */
    private const RESERVED_MEMCACHED = " \n\r\t\v\f\0";
    private const RESERVED_PSR6 = '@()\{}/';

    protected $maxIdLength = 250;

    private const DEFAULT_CLIENT_OPTIONS = [
        'persistent_id' => null,
        'username' => null,
        'password' => null,
        \Memcached::OPT_SERIALIZER => \Memcached::SERIALIZER_PHP,
    ];

    private $marshaller;
    private $client;
    private $lazyClient;

    /**
     * Using a MemcachedAdapter with a TagAwareAdapter for storing tags is discouraged.
     * Using a RedisAdapter is recommended instead. If you cannot do otherwise, be aware that:
     * - the Memcached::OPT_BINARY_PROTOCOL must be enabled
     *   (that's the default when using MemcachedAdapter::createConnection());
     * - tags eviction by Memcached's LRU algorithm will break by-tags invalidation;
     *   your Memcached memory should be large enough to never trigger LRU.
     *
     * Using a MemcachedAdapter as a pure items store is fine.
     */
    public function __construct(\Memcached $client, string $namespace = '', int $defaultLifetime = 0, MarshallerInterface $marshaller = null)
    {
        if (!static::isSupported()) {
            throw new CacheException('Memcached >= 2.2.0 is required.');
        }
        if ('Memcached' === \get_class($client)) {
            $opt = $client->getOption(\Memcached::OPT_SERIALIZER);
            if (\Memcached::SERIALIZER_PHP !== $opt && \Memcached::SERIALIZER_IGBINARY !== $opt) {
                throw new CacheException('MemcachedAdapter: "serializer" option must be "php" or "igbinary".');
            }
            $this->maxIdLength -= \strlen($client->getOption(\Memcached::OPT_PREFIX_KEY));
            $this->client = $client;
        } else {
            $this->lazyClient = $client;
        }

        parent::__construct($namespace, $defaultLifetime);
        $this->enableVersioning();
        $this->marshaller = $marshaller ?? new DefaultMarshaller();
    }

    public static function isSupported()
    {
        return \extension_loaded('memcached') && version_compare(phpversion('memcached'), '2.2.0', '>=');
    }

    /**
     * Creates a Memcached instance.
     *
     * By default, the binary protocol, no block, and libketama compatible options are enabled.
     *
     * Examples for servers:
     * - 'memcached://user:pass@localhost?weight=33'
     * - [['localhost', 11211, 33]]
     *
     * @param array[]|string|string[] $servers An array of servers, a DSN, or an array of DSNs
     * @param array                   $options An array of options
     *
     * @return \Memcached
     *
     * @throws \ErrorException When invalid options or servers are provided
     */
    public static function createConnection($servers, array $options = [])
    {
        if (\is_string($servers)) {
            $servers = [$servers];
        } elseif (!\is_array($servers)) {
            throw new InvalidArgumentException(sprintf('MemcachedAdapter::createClient() expects array or string as first argument, "%s" given.', get_debug_type($servers)));
        }
        if (!static::isSupported()) {
            throw new CacheException('Memcached >= 2.2.0 is required.');
        }
        set_error_handler(function ($type, $msg, $file, $line) { throw new \ErrorException($msg, 0, $type, $file, $line); });
        try {
            $options += static::DEFAULT_CLIENT_OPTIONS;
            $client = new \Memcached($options['persistent_id']);
            $username = $options['username'];
            $password = $options['password'];

            // parse any DSN in $servers
            foreach ($servers as $i => $dsn) {
                if (\is_array($dsn)) {
                    continue;
                }
                if (0 !== strpos($dsn, 'memcached:')) {
                    throw new InvalidArgumentException(sprintf('Invalid Memcached DSN: "%s" does not start with "memcached:".', $dsn));
                }
                $params = preg_replace_callback('#^memcached:(//)?(?:([^@]*+)@)?#', function ($m) use (&$username, &$password) {
                    if (!empty($m[2])) {
                        [$username, $password] = explode(':', $m[2], 2) + [1 => null];
                    }

                    return 'file:'.($m[1] ?? '');
                }, $dsn);
                if (false === $params = parse_url($params)) {
                    throw new InvalidArgumentException(sprintf('Invalid Memcached DSN: "%s".', $dsn));
                }
                $query = $hosts = [];
                if (isset($params['query'])) {
                    parse_str($params['query'], $query);

                    if (isset($query['host'])) {
                        if (!\is_array($hosts = $query['host'])) {
                            throw new InvalidArgumentException(sprintf('Invalid Memcached DSN: "%s".', $dsn));
                        }
                        foreach ($hosts as $host => $weight) {
                            if (false === $port = strrpos($host, ':')) {
                                $hosts[$host] = [$host, 11211, (int) $weight];
                            } else {
                                $hosts[$host] = [substr($host, 0, $port), (int) substr($host, 1 + $port), (int) $weight];
                            }
                        }
                        $hosts = array_values($hosts);
                        unset($query['host']);
                    }
                    if ($hosts && !isset($params['host']) && !isset($params['path'])) {
                        unset($servers[$i]);
                        $servers = array_merge($servers, $hosts);
                        continue;
                    }
                }
                if (!isset($params['host']) && !isset($params['path'])) {
                    throw new InvalidArgumentException(sprintf('Invalid Memcached DSN: "%s".', $dsn));
                }
                if (isset($params['path']) && preg_match('#/(\d+)$#', $params['path'], $m)) {
                    $params['weight'] = $m[1];
                    $params['path'] = substr($params['path'], 0, -\strlen($m[0]));
                }
                $params += [
                    'host' => $params['host'] ?? $params['path'],
                    'port' => isset($params['host']) ? 11211 : null,
                    'weight' => 0,
                ];
                if ($query) {
                    $params += $query;
                    $options = $query + $options;
                }

                $servers[$i] = [$params['host'], $params['port'], $params['weight']];

                if ($hosts) {
                    $servers = array_merge($servers, $hosts);
                }
            }

            // set client's options
            unset($options['persistent_id'], $options['username'], $options['password'], $options['weight'], $options['lazy']);
            $options = array_change_key_case($options, \CASE_UPPER);
            $client->setOption(\Memcached::OPT_BINARY_PROTOCOL, true);
            $client->setOption(\Memcached::OPT_NO_BLOCK, true);
            $client->setOption(\Memcached::OPT_TCP_NODELAY, true);
            if (!\array_key_exists('LIBKETAMA_COMPATIBLE', $options) && !\array_key_exists(\Memcached::OPT_LIBKETAMA_COMPATIBLE, $options)) {
                $client->setOption(\Memcached::OPT_LIBKETAMA_COMPATIBLE, true);
            }
            foreach ($options as $name => $value) {
                if (\is_int($name)) {
                    continue;
                }
                if ('HASH' === $name || 'SERIALIZER' === $name || 'DISTRIBUTION' === $name) {
                    $value = \constant('Memcached::'.$name.'_'.strtoupper($value));
                }
                $opt = \constant('Memcached::OPT_'.$name);

                unset($options[$name]);
                $options[$opt] = $value;
            }
            $client->setOptions($options);

            // set client's servers, taking care of persistent connections
            if (!$client->isPristine()) {
                $oldServers = [];
                foreach ($client->getServerList() as $server) {
                    $oldServers[] = [$server['host'], $server['port']];
                }

                $newServers = [];
                foreach ($servers as $server) {
                    if (1 < \count($server)) {
                        $server = array_values($server);
                        unset($server[2]);
                        $server[1] = (int) $server[1];
                    }
                    $newServers[] = $server;
                }

                if ($oldServers !== $newServers) {
                    $client->resetServerList();
                    $client->addServers($servers);
                }
            } else {
                $client->addServers($servers);
            }

            if (null !== $username || null !== $password) {
                if (!method_exists($client, 'setSaslAuthData')) {
                    trigger_error('Missing SASL support: the memcached extension must be compiled with --enable-memcached-sasl.');
                }
                $client->setSaslAuthData($username, $password);
            }

            return $client;
        } finally {
            restore_error_handler();
        }
    }

    /**
     * {@inheritdoc}
     */
    protected function doSave(array $values, int $lifetime)
    {
        if (!$values = $this->marshaller->marshall($values, $failed)) {
            return $failed;
        }

        if ($lifetime && $lifetime > 30 * 86400) {
            $lifetime += time();
        }

        $encodedValues = [];
        foreach ($values as $key => $value) {
            $encodedValues[self::encodeKey($key)] = $value;
        }

        return $this->checkResultCode($this->getClient()->setMulti($encodedValues, $lifetime)) ? $failed : false;
    }

    /**
     * {@inheritdoc}
     */
    protected function doFetch(array $ids)
    {
        try {
            $encodedIds = array_map('self::encodeKey', $ids);

            $encodedResult = $this->checkResultCode($this->getClient()->getMulti($encodedIds));

            $result = [];
            foreach ($encodedResult as $key => $value) {
                $result[self::decodeKey($key)] = $this->marshaller->unmarshall($value);
            }

            return $result;
        } catch (\Error $e) {
            throw new \ErrorException($e->getMessage(), $e->getCode(), \E_ERROR, $e->getFile(), $e->getLine());
        }
    }

    /**
     * {@inheritdoc}
     */
    protected function doHave(string $id)
    {
        return false !== $this->getClient()->get(self::encodeKey($id)) || $this->checkResultCode(\Memcached::RES_SUCCESS === $this->client->getResultCode());
    }

    /**
     * {@inheritdoc}
     */
    protected function doDelete(array $ids)
    {
        $ok = true;
        $encodedIds = array_map('self::encodeKey', $ids);
        foreach ($this->checkResultCode($this->getClient()->deleteMulti($encodedIds)) as $result) {
            if (\Memcached::RES_SUCCESS !== $result && \Memcached::RES_NOTFOUND !== $result) {
                $ok = false;
            }
        }

        return $ok;
    }

    /**
     * {@inheritdoc}
     */
    protected function doClear(string $namespace)
    {
        return '' === $namespace && $this->getClient()->flush();
    }

    private function checkResultCode($result)
    {
        $code = $this->client->getResultCode();

        if (\Memcached::RES_SUCCESS === $code || \Memcached::RES_NOTFOUND === $code) {
            return $result;
        }

        throw new CacheException('MemcachedAdapter client error: '.strtolower($this->client->getResultMessage()));
    }

    private function getClient(): \Memcached
    {
        if ($this->client) {
            return $this->client;
        }

        $opt = $this->lazyClient->getOption(\Memcached::OPT_SERIALIZER);
        if (\Memcached::SERIALIZER_PHP !== $opt && \Memcached::SERIALIZER_IGBINARY !== $opt) {
            throw new CacheException('MemcachedAdapter: "serializer" option must be "php" or "igbinary".');
        }
        if ('' !== $prefix = (string) $this->lazyClient->getOption(\Memcached::OPT_PREFIX_KEY)) {
            throw new CacheException(sprintf('MemcachedAdapter: "prefix_key" option must be empty when using proxified connections, "%s" given.', $prefix));
        }

        return $this->client = $this->lazyClient;
    }

    private static function encodeKey(string $key): string
    {
        return strtr($key, self::RESERVED_MEMCACHED, self::RESERVED_PSR6);
    }

    private static function decodeKey(string $key): string
    {
        return strtr($key, self::RESERVED_PSR6, self::RESERVED_MEMCACHED);
    }
}
PKϤ$ZiTď�"�"cache/Adapter/ChainAdapter.phpnu�[���<?php

/*
 * This file is part of the Symfony package.
 *
 * (c) Fabien Potencier <fabien@symfony.com>
 *
 * For the full copyright and license information, please view the LICENSE
 * file that was distributed with this source code.
 */

namespace Symfony\Component\Cache\Adapter;

use Psr\Cache\CacheItemInterface;
use Psr\Cache\CacheItemPoolInterface;
use Symfony\Component\Cache\CacheItem;
use Symfony\Component\Cache\Exception\InvalidArgumentException;
use Symfony\Component\Cache\PruneableInterface;
use Symfony\Component\Cache\ResettableInterface;
use Symfony\Component\Cache\Traits\ContractsTrait;
use Symfony\Contracts\Cache\CacheInterface;
use Symfony\Contracts\Service\ResetInterface;

/**
 * Chains several adapters together.
 *
 * Cached items are fetched from the first adapter having them in its data store.
 * They are saved and deleted in all adapters at once.
 *
 * @author Kévin Dunglas <dunglas@gmail.com>
 */
class ChainAdapter implements AdapterInterface, CacheInterface, PruneableInterface, ResettableInterface
{
    use ContractsTrait;

    private $adapters = [];
    private $adapterCount;
    private $syncItem;

    /**
     * @param CacheItemPoolInterface[] $adapters        The ordered list of adapters used to fetch cached items
     * @param int                      $defaultLifetime The default lifetime of items propagated from lower adapters to upper ones
     */
    public function __construct(array $adapters, int $defaultLifetime = 0)
    {
        if (!$adapters) {
            throw new InvalidArgumentException('At least one adapter must be specified.');
        }

        foreach ($adapters as $adapter) {
            if (!$adapter instanceof CacheItemPoolInterface) {
                throw new InvalidArgumentException(sprintf('The class "%s" does not implement the "%s" interface.', get_debug_type($adapter), CacheItemPoolInterface::class));
            }
            if (\in_array(\PHP_SAPI, ['cli', 'phpdbg'], true) && $adapter instanceof ApcuAdapter && !filter_var(ini_get('apc.enable_cli'), \FILTER_VALIDATE_BOOLEAN)) {
                continue; // skip putting APCu in the chain when the backend is disabled
            }

            if ($adapter instanceof AdapterInterface) {
                $this->adapters[] = $adapter;
            } else {
                $this->adapters[] = new ProxyAdapter($adapter);
            }
        }
        $this->adapterCount = \count($this->adapters);

        $this->syncItem = \Closure::bind(
            static function ($sourceItem, $item, $sourceMetadata = null) use ($defaultLifetime) {
                $sourceItem->isTaggable = false;
                $sourceMetadata = $sourceMetadata ?? $sourceItem->metadata;
                unset($sourceMetadata[CacheItem::METADATA_TAGS]);

                $item->value = $sourceItem->value;
                $item->isHit = $sourceItem->isHit;
                $item->metadata = $item->newMetadata = $sourceItem->metadata = $sourceMetadata;

                if (isset($item->metadata[CacheItem::METADATA_EXPIRY])) {
                    $item->expiresAt(\DateTime::createFromFormat('U.u', sprintf('%.6F', $item->metadata[CacheItem::METADATA_EXPIRY])));
                } elseif (0 < $defaultLifetime) {
                    $item->expiresAfter($defaultLifetime);
                }

                return $item;
            },
            null,
            CacheItem::class
        );
    }

    /**
     * {@inheritdoc}
     */
    public function get(string $key, callable $callback, float $beta = null, array &$metadata = null)
    {
        $lastItem = null;
        $i = 0;
        $wrap = function (CacheItem $item = null) use ($key, $callback, $beta, &$wrap, &$i, &$lastItem, &$metadata) {
            $adapter = $this->adapters[$i];
            if (isset($this->adapters[++$i])) {
                $callback = $wrap;
                $beta = \INF === $beta ? \INF : 0;
            }
            if ($adapter instanceof CacheInterface) {
                $value = $adapter->get($key, $callback, $beta, $metadata);
            } else {
                $value = $this->doGet($adapter, $key, $callback, $beta, $metadata);
            }
            if (null !== $item) {
                ($this->syncItem)($lastItem = $lastItem ?? $item, $item, $metadata);
            }

            return $value;
        };

        return $wrap();
    }

    /**
     * {@inheritdoc}
     */
    public function getItem($key)
    {
        $syncItem = $this->syncItem;
        $misses = [];

        foreach ($this->adapters as $i => $adapter) {
            $item = $adapter->getItem($key);

            if ($item->isHit()) {
                while (0 <= --$i) {
                    $this->adapters[$i]->save($syncItem($item, $misses[$i]));
                }

                return $item;
            }

            $misses[$i] = $item;
        }

        return $item;
    }

    /**
     * {@inheritdoc}
     */
    public function getItems(array $keys = [])
    {
        return $this->generateItems($this->adapters[0]->getItems($keys), 0);
    }

    private function generateItems(iterable $items, int $adapterIndex)
    {
        $missing = [];
        $misses = [];
        $nextAdapterIndex = $adapterIndex + 1;
        $nextAdapter = $this->adapters[$nextAdapterIndex] ?? null;

        foreach ($items as $k => $item) {
            if (!$nextAdapter || $item->isHit()) {
                yield $k => $item;
            } else {
                $missing[] = $k;
                $misses[$k] = $item;
            }
        }

        if ($missing) {
            $syncItem = $this->syncItem;
            $adapter = $this->adapters[$adapterIndex];
            $items = $this->generateItems($nextAdapter->getItems($missing), $nextAdapterIndex);

            foreach ($items as $k => $item) {
                if ($item->isHit()) {
                    $adapter->save($syncItem($item, $misses[$k]));
                }

                yield $k => $item;
            }
        }
    }

    /**
     * {@inheritdoc}
     *
     * @return bool
     */
    public function hasItem($key)
    {
        foreach ($this->adapters as $adapter) {
            if ($adapter->hasItem($key)) {
                return true;
            }
        }

        return false;
    }

    /**
     * {@inheritdoc}
     *
     * @return bool
     */
    public function clear(string $prefix = '')
    {
        $cleared = true;
        $i = $this->adapterCount;

        while ($i--) {
            if ($this->adapters[$i] instanceof AdapterInterface) {
                $cleared = $this->adapters[$i]->clear($prefix) && $cleared;
            } else {
                $cleared = $this->adapters[$i]->clear() && $cleared;
            }
        }

        return $cleared;
    }

    /**
     * {@inheritdoc}
     *
     * @return bool
     */
    public function deleteItem($key)
    {
        $deleted = true;
        $i = $this->adapterCount;

        while ($i--) {
            $deleted = $this->adapters[$i]->deleteItem($key) && $deleted;
        }

        return $deleted;
    }

    /**
     * {@inheritdoc}
     *
     * @return bool
     */
    public function deleteItems(array $keys)
    {
        $deleted = true;
        $i = $this->adapterCount;

        while ($i--) {
            $deleted = $this->adapters[$i]->deleteItems($keys) && $deleted;
        }

        return $deleted;
    }

    /**
     * {@inheritdoc}
     *
     * @return bool
     */
    public function save(CacheItemInterface $item)
    {
        $saved = true;
        $i = $this->adapterCount;

        while ($i--) {
            $saved = $this->adapters[$i]->save($item) && $saved;
        }

        return $saved;
    }

    /**
     * {@inheritdoc}
     *
     * @return bool
     */
    public function saveDeferred(CacheItemInterface $item)
    {
        $saved = true;
        $i = $this->adapterCount;

        while ($i--) {
            $saved = $this->adapters[$i]->saveDeferred($item) && $saved;
        }

        return $saved;
    }

    /**
     * {@inheritdoc}
     *
     * @return bool
     */
    public function commit()
    {
        $committed = true;
        $i = $this->adapterCount;

        while ($i--) {
            $committed = $this->adapters[$i]->commit() && $committed;
        }

        return $committed;
    }

    /**
     * {@inheritdoc}
     */
    public function prune()
    {
        $pruned = true;

        foreach ($this->adapters as $adapter) {
            if ($adapter instanceof PruneableInterface) {
                $pruned = $adapter->prune() && $pruned;
            }
        }

        return $pruned;
    }

    /**
     * {@inheritdoc}
     */
    public function reset()
    {
        foreach ($this->adapters as $adapter) {
            if ($adapter instanceof ResetInterface) {
                $adapter->reset();
            }
        }
    }
}
PKϤ$Z�:v���cache/Adapter/ApcuAdapter.phpnu�[���<?php

/*
 * This file is part of the Symfony package.
 *
 * (c) Fabien Potencier <fabien@symfony.com>
 *
 * For the full copyright and license information, please view the LICENSE
 * file that was distributed with this source code.
 */

namespace Symfony\Component\Cache\Adapter;

use Symfony\Component\Cache\CacheItem;
use Symfony\Component\Cache\Exception\CacheException;

/**
 * @author Nicolas Grekas <p@tchwork.com>
 */
class ApcuAdapter extends AbstractAdapter
{
    /**
     * @throws CacheException if APCu is not enabled
     */
    public function __construct(string $namespace = '', int $defaultLifetime = 0, string $version = null)
    {
        if (!static::isSupported()) {
            throw new CacheException('APCu is not enabled.');
        }
        if ('cli' === \PHP_SAPI) {
            ini_set('apc.use_request_time', 0);
        }
        parent::__construct($namespace, $defaultLifetime);

        if (null !== $version) {
            CacheItem::validateKey($version);

            if (!apcu_exists($version.'@'.$namespace)) {
                $this->doClear($namespace);
                apcu_add($version.'@'.$namespace, null);
            }
        }
    }

    public static function isSupported()
    {
        return \function_exists('apcu_fetch') && filter_var(ini_get('apc.enabled'), \FILTER_VALIDATE_BOOLEAN);
    }

    /**
     * {@inheritdoc}
     */
    protected function doFetch(array $ids)
    {
        $unserializeCallbackHandler = ini_set('unserialize_callback_func', __CLASS__.'::handleUnserializeCallback');
        try {
            $values = [];
            foreach (apcu_fetch($ids, $ok) ?: [] as $k => $v) {
                if (null !== $v || $ok) {
                    $values[$k] = $v;
                }
            }

            return $values;
        } catch (\Error $e) {
            throw new \ErrorException($e->getMessage(), $e->getCode(), \E_ERROR, $e->getFile(), $e->getLine());
        } finally {
            ini_set('unserialize_callback_func', $unserializeCallbackHandler);
        }
    }

    /**
     * {@inheritdoc}
     */
    protected function doHave(string $id)
    {
        return apcu_exists($id);
    }

    /**
     * {@inheritdoc}
     */
    protected function doClear(string $namespace)
    {
        return isset($namespace[0]) && class_exists(\APCuIterator::class, false) && ('cli' !== \PHP_SAPI || filter_var(ini_get('apc.enable_cli'), \FILTER_VALIDATE_BOOLEAN))
            ? apcu_delete(new \APCuIterator(sprintf('/^%s/', preg_quote($namespace, '/')), \APC_ITER_KEY))
            : apcu_clear_cache();
    }

    /**
     * {@inheritdoc}
     */
    protected function doDelete(array $ids)
    {
        foreach ($ids as $id) {
            apcu_delete($id);
        }

        return true;
    }

    /**
     * {@inheritdoc}
     */
    protected function doSave(array $values, int $lifetime)
    {
        try {
            if (false === $failures = apcu_store($values, null, $lifetime)) {
                $failures = $values;
            }

            return array_keys($failures);
        } catch (\Throwable $e) {
            if (1 === \count($values)) {
                // Workaround https://github.com/krakjoe/apcu/issues/170
                apcu_delete(key($values));
            }

            throw $e;
        }
    }
}
PKϤ$Z�)瞞�*cache/Adapter/TraceableTagAwareAdapter.phpnu�[���<?php

/*
 * This file is part of the Symfony package.
 *
 * (c) Fabien Potencier <fabien@symfony.com>
 *
 * For the full copyright and license information, please view the LICENSE
 * file that was distributed with this source code.
 */

namespace Symfony\Component\Cache\Adapter;

use Symfony\Contracts\Cache\TagAwareCacheInterface;

/**
 * @author Robin Chalas <robin.chalas@gmail.com>
 */
class TraceableTagAwareAdapter extends TraceableAdapter implements TagAwareAdapterInterface, TagAwareCacheInterface
{
    public function __construct(TagAwareAdapterInterface $pool)
    {
        parent::__construct($pool);
    }

    /**
     * {@inheritdoc}
     */
    public function invalidateTags(array $tags)
    {
        $event = $this->start(__FUNCTION__);
        try {
            return $event->result = $this->pool->invalidateTags($tags);
        } finally {
            $event->end = microtime(true);
        }
    }
}
PKϤ$Z*��--!cache/Adapter/TagAwareAdapter.phpnu�[���<?php

/*
 * This file is part of the Symfony package.
 *
 * (c) Fabien Potencier <fabien@symfony.com>
 *
 * For the full copyright and license information, please view the LICENSE
 * file that was distributed with this source code.
 */

namespace Symfony\Component\Cache\Adapter;

use Psr\Cache\CacheItemInterface;
use Psr\Cache\InvalidArgumentException;
use Symfony\Component\Cache\CacheItem;
use Symfony\Component\Cache\PruneableInterface;
use Symfony\Component\Cache\ResettableInterface;
use Symfony\Component\Cache\Traits\ContractsTrait;
use Symfony\Component\Cache\Traits\ProxyTrait;
use Symfony\Contracts\Cache\TagAwareCacheInterface;

/**
 * @author Nicolas Grekas <p@tchwork.com>
 */
class TagAwareAdapter implements TagAwareAdapterInterface, TagAwareCacheInterface, PruneableInterface, ResettableInterface
{
    public const TAGS_PREFIX = "\0tags\0";

    use ContractsTrait;
    use ProxyTrait;

    private $deferred = [];
    private $createCacheItem;
    private $setCacheItemTags;
    private $getTagsByKey;
    private $invalidateTags;
    private $tags;
    private $knownTagVersions = [];
    private $knownTagVersionsTtl;

    public function __construct(AdapterInterface $itemsPool, AdapterInterface $tagsPool = null, float $knownTagVersionsTtl = 0.15)
    {
        $this->pool = $itemsPool;
        $this->tags = $tagsPool ?: $itemsPool;
        $this->knownTagVersionsTtl = $knownTagVersionsTtl;
        $this->createCacheItem = \Closure::bind(
            static function ($key, $value, CacheItem $protoItem) {
                $item = new CacheItem();
                $item->key = $key;
                $item->value = $value;
                $item->expiry = $protoItem->expiry;
                $item->poolHash = $protoItem->poolHash;

                return $item;
            },
            null,
            CacheItem::class
        );
        $this->setCacheItemTags = \Closure::bind(
            static function (CacheItem $item, $key, array &$itemTags) {
                $item->isTaggable = true;
                if (!$item->isHit) {
                    return $item;
                }
                if (isset($itemTags[$key])) {
                    foreach ($itemTags[$key] as $tag => $version) {
                        $item->metadata[CacheItem::METADATA_TAGS][$tag] = $tag;
                    }
                    unset($itemTags[$key]);
                } else {
                    $item->value = null;
                    $item->isHit = false;
                }

                return $item;
            },
            null,
            CacheItem::class
        );
        $this->getTagsByKey = \Closure::bind(
            static function ($deferred) {
                $tagsByKey = [];
                foreach ($deferred as $key => $item) {
                    $tagsByKey[$key] = $item->newMetadata[CacheItem::METADATA_TAGS] ?? [];
                }

                return $tagsByKey;
            },
            null,
            CacheItem::class
        );
        $this->invalidateTags = \Closure::bind(
            static function (AdapterInterface $tagsAdapter, array $tags) {
                foreach ($tags as $v) {
                    $v->expiry = 0;
                    $tagsAdapter->saveDeferred($v);
                }

                return $tagsAdapter->commit();
            },
            null,
            CacheItem::class
        );
    }

    /**
     * {@inheritdoc}
     */
    public function invalidateTags(array $tags)
    {
        $ok = true;
        $tagsByKey = [];
        $invalidatedTags = [];
        foreach ($tags as $tag) {
            CacheItem::validateKey($tag);
            $invalidatedTags[$tag] = 0;
        }

        if ($this->deferred) {
            $items = $this->deferred;
            foreach ($items as $key => $item) {
                if (!$this->pool->saveDeferred($item)) {
                    unset($this->deferred[$key]);
                    $ok = false;
                }
            }

            $f = $this->getTagsByKey;
            $tagsByKey = $f($items);
            $this->deferred = [];
        }

        $tagVersions = $this->getTagVersions($tagsByKey, $invalidatedTags);
        $f = $this->createCacheItem;

        foreach ($tagsByKey as $key => $tags) {
            $this->pool->saveDeferred($f(static::TAGS_PREFIX.$key, array_intersect_key($tagVersions, $tags), $items[$key]));
        }
        $ok = $this->pool->commit() && $ok;

        if ($invalidatedTags) {
            $f = $this->invalidateTags;
            $ok = $f($this->tags, $invalidatedTags) && $ok;
        }

        return $ok;
    }

    /**
     * {@inheritdoc}
     *
     * @return bool
     */
    public function hasItem($key)
    {
        if ($this->deferred) {
            $this->commit();
        }
        if (!$this->pool->hasItem($key)) {
            return false;
        }

        $itemTags = $this->pool->getItem(static::TAGS_PREFIX.$key);

        if (!$itemTags->isHit()) {
            return false;
        }

        if (!$itemTags = $itemTags->get()) {
            return true;
        }

        foreach ($this->getTagVersions([$itemTags]) as $tag => $version) {
            if ($itemTags[$tag] !== $version && 1 !== $itemTags[$tag] - $version) {
                return false;
            }
        }

        return true;
    }

    /**
     * {@inheritdoc}
     */
    public function getItem($key)
    {
        foreach ($this->getItems([$key]) as $item) {
            return $item;
        }

        return null;
    }

    /**
     * {@inheritdoc}
     */
    public function getItems(array $keys = [])
    {
        if ($this->deferred) {
            $this->commit();
        }
        $tagKeys = [];

        foreach ($keys as $key) {
            if ('' !== $key && \is_string($key)) {
                $key = static::TAGS_PREFIX.$key;
                $tagKeys[$key] = $key;
            }
        }

        try {
            $items = $this->pool->getItems($tagKeys + $keys);
        } catch (InvalidArgumentException $e) {
            $this->pool->getItems($keys); // Should throw an exception

            throw $e;
        }

        return $this->generateItems($items, $tagKeys);
    }

    /**
     * {@inheritdoc}
     *
     * @return bool
     */
    public function clear(string $prefix = '')
    {
        if ('' !== $prefix) {
            foreach ($this->deferred as $key => $item) {
                if (0 === strpos($key, $prefix)) {
                    unset($this->deferred[$key]);
                }
            }
        } else {
            $this->deferred = [];
        }

        if ($this->pool instanceof AdapterInterface) {
            return $this->pool->clear($prefix);
        }

        return $this->pool->clear();
    }

    /**
     * {@inheritdoc}
     *
     * @return bool
     */
    public function deleteItem($key)
    {
        return $this->deleteItems([$key]);
    }

    /**
     * {@inheritdoc}
     *
     * @return bool
     */
    public function deleteItems(array $keys)
    {
        foreach ($keys as $key) {
            if ('' !== $key && \is_string($key)) {
                $keys[] = static::TAGS_PREFIX.$key;
            }
        }

        return $this->pool->deleteItems($keys);
    }

    /**
     * {@inheritdoc}
     *
     * @return bool
     */
    public function save(CacheItemInterface $item)
    {
        if (!$item instanceof CacheItem) {
            return false;
        }
        $this->deferred[$item->getKey()] = $item;

        return $this->commit();
    }

    /**
     * {@inheritdoc}
     *
     * @return bool
     */
    public function saveDeferred(CacheItemInterface $item)
    {
        if (!$item instanceof CacheItem) {
            return false;
        }
        $this->deferred[$item->getKey()] = $item;

        return true;
    }

    /**
     * {@inheritdoc}
     *
     * @return bool
     */
    public function commit()
    {
        return $this->invalidateTags([]);
    }

    public function __sleep()
    {
        throw new \BadMethodCallException('Cannot serialize '.__CLASS__);
    }

    public function __wakeup()
    {
        throw new \BadMethodCallException('Cannot unserialize '.__CLASS__);
    }

    public function __destruct()
    {
        $this->commit();
    }

    private function generateItems(iterable $items, array $tagKeys)
    {
        $bufferedItems = $itemTags = [];
        $f = $this->setCacheItemTags;

        foreach ($items as $key => $item) {
            if (!$tagKeys) {
                yield $key => $f($item, static::TAGS_PREFIX.$key, $itemTags);
                continue;
            }
            if (!isset($tagKeys[$key])) {
                $bufferedItems[$key] = $item;
                continue;
            }

            unset($tagKeys[$key]);

            if ($item->isHit()) {
                $itemTags[$key] = $item->get() ?: [];
            }

            if (!$tagKeys) {
                $tagVersions = $this->getTagVersions($itemTags);

                foreach ($itemTags as $key => $tags) {
                    foreach ($tags as $tag => $version) {
                        if ($tagVersions[$tag] !== $version && 1 !== $version - $tagVersions[$tag]) {
                            unset($itemTags[$key]);
                            continue 2;
                        }
                    }
                }
                $tagVersions = $tagKeys = null;

                foreach ($bufferedItems as $key => $item) {
                    yield $key => $f($item, static::TAGS_PREFIX.$key, $itemTags);
                }
                $bufferedItems = null;
            }
        }
    }

    private function getTagVersions(array $tagsByKey, array &$invalidatedTags = [])
    {
        $tagVersions = $invalidatedTags;

        foreach ($tagsByKey as $tags) {
            $tagVersions += $tags;
        }

        if (!$tagVersions) {
            return [];
        }

        if (!$fetchTagVersions = 1 !== \func_num_args()) {
            foreach ($tagsByKey as $tags) {
                foreach ($tags as $tag => $version) {
                    if ($tagVersions[$tag] > $version) {
                        $tagVersions[$tag] = $version;
                    }
                }
            }
        }

        $now = microtime(true);
        $tags = [];
        foreach ($tagVersions as $tag => $version) {
            $tags[$tag.static::TAGS_PREFIX] = $tag;
            if ($fetchTagVersions || !isset($this->knownTagVersions[$tag])) {
                $fetchTagVersions = true;
                continue;
            }
            $version -= $this->knownTagVersions[$tag][1];
            if ((0 !== $version && 1 !== $version) || $now - $this->knownTagVersions[$tag][0] >= $this->knownTagVersionsTtl) {
                // reuse previously fetched tag versions up to the ttl, unless we are storing items or a potential miss arises
                $fetchTagVersions = true;
            } else {
                $this->knownTagVersions[$tag][1] += $version;
            }
        }

        if (!$fetchTagVersions) {
            return $tagVersions;
        }

        foreach ($this->tags->getItems(array_keys($tags)) as $tag => $version) {
            $tagVersions[$tag = $tags[$tag]] = $version->get() ?: 0;
            if (isset($invalidatedTags[$tag])) {
                $invalidatedTags[$tag] = $version->set(++$tagVersions[$tag]);
            }
            $this->knownTagVersions[$tag] = [$now, $tagVersions[$tag]];
        }

        return $tagVersions;
    }
}
PKϤ$Z�2�
�
cache/Adapter/NullAdapter.phpnu�[���<?php

/*
 * This file is part of the Symfony package.
 *
 * (c) Fabien Potencier <fabien@symfony.com>
 *
 * For the full copyright and license information, please view the LICENSE
 * file that was distributed with this source code.
 */

namespace Symfony\Component\Cache\Adapter;

use Psr\Cache\CacheItemInterface;
use Symfony\Component\Cache\CacheItem;
use Symfony\Contracts\Cache\CacheInterface;

/**
 * @author Titouan Galopin <galopintitouan@gmail.com>
 */
class NullAdapter implements AdapterInterface, CacheInterface
{
    private $createCacheItem;

    public function __construct()
    {
        $this->createCacheItem = \Closure::bind(
            function ($key) {
                $item = new CacheItem();
                $item->key = $key;
                $item->isHit = false;

                return $item;
            },
            $this,
            CacheItem::class
        );
    }

    /**
     * {@inheritdoc}
     */
    public function get(string $key, callable $callback, float $beta = null, array &$metadata = null)
    {
        $save = true;

        return $callback(($this->createCacheItem)($key), $save);
    }

    /**
     * {@inheritdoc}
     */
    public function getItem($key)
    {
        $f = $this->createCacheItem;

        return $f($key);
    }

    /**
     * {@inheritdoc}
     */
    public function getItems(array $keys = [])
    {
        return $this->generateItems($keys);
    }

    /**
     * {@inheritdoc}
     *
     * @return bool
     */
    public function hasItem($key)
    {
        return false;
    }

    /**
     * {@inheritdoc}
     *
     * @return bool
     */
    public function clear(string $prefix = '')
    {
        return true;
    }

    /**
     * {@inheritdoc}
     *
     * @return bool
     */
    public function deleteItem($key)
    {
        return true;
    }

    /**
     * {@inheritdoc}
     *
     * @return bool
     */
    public function deleteItems(array $keys)
    {
        return true;
    }

    /**
     * {@inheritdoc}
     *
     * @return bool
     */
    public function save(CacheItemInterface $item)
    {
        return false;
    }

    /**
     * {@inheritdoc}
     *
     * @return bool
     */
    public function saveDeferred(CacheItemInterface $item)
    {
        return false;
    }

    /**
     * {@inheritdoc}
     *
     * @return bool
     */
    public function commit()
    {
        return false;
    }

    /**
     * {@inheritdoc}
     */
    public function delete(string $key): bool
    {
        return $this->deleteItem($key);
    }

    private function generateItems(array $keys)
    {
        $f = $this->createCacheItem;

        foreach ($keys as $key) {
            yield $key => $f($key);
        }
    }
}
PKϤ$ZH���0V0Vcache/Adapter/PdoAdapter.phpnu�[���<?php

/*
 * This file is part of the Symfony package.
 *
 * (c) Fabien Potencier <fabien@symfony.com>
 *
 * For the full copyright and license information, please view the LICENSE
 * file that was distributed with this source code.
 */

namespace Symfony\Component\Cache\Adapter;

use Doctrine\DBAL\Connection;
use Doctrine\DBAL\DBALException;
use Doctrine\DBAL\Driver\ServerInfoAwareConnection;
use Doctrine\DBAL\DriverManager;
use Doctrine\DBAL\Exception;
use Doctrine\DBAL\Exception\TableNotFoundException;
use Doctrine\DBAL\Schema\Schema;
use Symfony\Component\Cache\Exception\InvalidArgumentException;
use Symfony\Component\Cache\Marshaller\DefaultMarshaller;
use Symfony\Component\Cache\Marshaller\MarshallerInterface;
use Symfony\Component\Cache\PruneableInterface;

class PdoAdapter extends AbstractAdapter implements PruneableInterface
{
    protected $maxIdLength = 255;

    private $marshaller;
    private $conn;
    private $dsn;
    private $driver;
    private $serverVersion;
    private $table = 'cache_items';
    private $idCol = 'item_id';
    private $dataCol = 'item_data';
    private $lifetimeCol = 'item_lifetime';
    private $timeCol = 'item_time';
    private $username = '';
    private $password = '';
    private $connectionOptions = [];
    private $namespace;

    /**
     * You can either pass an existing database connection as PDO instance or
     * a Doctrine DBAL Connection or a DSN string that will be used to
     * lazy-connect to the database when the cache is actually used.
     *
     * When a Doctrine DBAL Connection is passed, the cache table is created
     * automatically when possible. Otherwise, use the createTable() method.
     *
     * List of available options:
     *  * db_table: The name of the table [default: cache_items]
     *  * db_id_col: The column where to store the cache id [default: item_id]
     *  * db_data_col: The column where to store the cache data [default: item_data]
     *  * db_lifetime_col: The column where to store the lifetime [default: item_lifetime]
     *  * db_time_col: The column where to store the timestamp [default: item_time]
     *  * db_username: The username when lazy-connect [default: '']
     *  * db_password: The password when lazy-connect [default: '']
     *  * db_connection_options: An array of driver-specific connection options [default: []]
     *
     * @param \PDO|Connection|string $connOrDsn a \PDO or Connection instance or DSN string or null
     *
     * @throws InvalidArgumentException When first argument is not PDO nor Connection nor string
     * @throws InvalidArgumentException When PDO error mode is not PDO::ERRMODE_EXCEPTION
     * @throws InvalidArgumentException When namespace contains invalid characters
     */
    public function __construct($connOrDsn, string $namespace = '', int $defaultLifetime = 0, array $options = [], MarshallerInterface $marshaller = null)
    {
        if (isset($namespace[0]) && preg_match('#[^-+.A-Za-z0-9]#', $namespace, $match)) {
            throw new InvalidArgumentException(sprintf('Namespace contains "%s" but only characters in [-+.A-Za-z0-9] are allowed.', $match[0]));
        }

        if ($connOrDsn instanceof \PDO) {
            if (\PDO::ERRMODE_EXCEPTION !== $connOrDsn->getAttribute(\PDO::ATTR_ERRMODE)) {
                throw new InvalidArgumentException(sprintf('"%s" requires PDO error mode attribute be set to throw Exceptions (i.e. $pdo->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION)).', __CLASS__));
            }

            $this->conn = $connOrDsn;
        } elseif ($connOrDsn instanceof Connection) {
            $this->conn = $connOrDsn;
        } elseif (\is_string($connOrDsn)) {
            $this->dsn = $connOrDsn;
        } else {
            throw new InvalidArgumentException(sprintf('"%s" requires PDO or Doctrine\DBAL\Connection instance or DSN string as first argument, "%s" given.', __CLASS__, get_debug_type($connOrDsn)));
        }

        $this->table = $options['db_table'] ?? $this->table;
        $this->idCol = $options['db_id_col'] ?? $this->idCol;
        $this->dataCol = $options['db_data_col'] ?? $this->dataCol;
        $this->lifetimeCol = $options['db_lifetime_col'] ?? $this->lifetimeCol;
        $this->timeCol = $options['db_time_col'] ?? $this->timeCol;
        $this->username = $options['db_username'] ?? $this->username;
        $this->password = $options['db_password'] ?? $this->password;
        $this->connectionOptions = $options['db_connection_options'] ?? $this->connectionOptions;
        $this->namespace = $namespace;
        $this->marshaller = $marshaller ?? new DefaultMarshaller();

        parent::__construct($namespace, $defaultLifetime);
    }

    /**
     * Creates the table to store cache items which can be called once for setup.
     *
     * Cache ID are saved in a column of maximum length 255. Cache data is
     * saved in a BLOB.
     *
     * @throws \PDOException    When the table already exists
     * @throws DBALException    When the table already exists
     * @throws Exception        When the table already exists
     * @throws \DomainException When an unsupported PDO driver is used
     */
    public function createTable()
    {
        // connect if we are not yet
        $conn = $this->getConnection();

        if ($conn instanceof Connection) {
            $schema = new Schema();
            $this->addTableToSchema($schema);

            foreach ($schema->toSql($conn->getDatabasePlatform()) as $sql) {
                if (method_exists($conn, 'executeStatement')) {
                    $conn->executeStatement($sql);
                } else {
                    $conn->exec($sql);
                }
            }

            return;
        }

        switch ($this->driver) {
            case 'mysql':
                // We use varbinary for the ID column because it prevents unwanted conversions:
                // - character set conversions between server and client
                // - trailing space removal
                // - case-insensitivity
                // - language processing like é == e
                $sql = "CREATE TABLE $this->table ($this->idCol VARBINARY(255) NOT NULL PRIMARY KEY, $this->dataCol MEDIUMBLOB NOT NULL, $this->lifetimeCol INTEGER UNSIGNED, $this->timeCol INTEGER UNSIGNED NOT NULL) COLLATE utf8_bin, ENGINE = InnoDB";
                break;
            case 'sqlite':
                $sql = "CREATE TABLE $this->table ($this->idCol TEXT NOT NULL PRIMARY KEY, $this->dataCol BLOB NOT NULL, $this->lifetimeCol INTEGER, $this->timeCol INTEGER NOT NULL)";
                break;
            case 'pgsql':
                $sql = "CREATE TABLE $this->table ($this->idCol VARCHAR(255) NOT NULL PRIMARY KEY, $this->dataCol BYTEA NOT NULL, $this->lifetimeCol INTEGER, $this->timeCol INTEGER NOT NULL)";
                break;
            case 'oci':
                $sql = "CREATE TABLE $this->table ($this->idCol VARCHAR2(255) NOT NULL PRIMARY KEY, $this->dataCol BLOB NOT NULL, $this->lifetimeCol INTEGER, $this->timeCol INTEGER NOT NULL)";
                break;
            case 'sqlsrv':
                $sql = "CREATE TABLE $this->table ($this->idCol VARCHAR(255) NOT NULL PRIMARY KEY, $this->dataCol VARBINARY(MAX) NOT NULL, $this->lifetimeCol INTEGER, $this->timeCol INTEGER NOT NULL)";
                break;
            default:
                throw new \DomainException(sprintf('Creating the cache table is currently not implemented for PDO driver "%s".', $this->driver));
        }

        if (method_exists($conn, 'executeStatement')) {
            $conn->executeStatement($sql);
        } else {
            $conn->exec($sql);
        }
    }

    /**
     * Adds the Table to the Schema if the adapter uses this Connection.
     */
    public function configureSchema(Schema $schema, Connection $forConnection): void
    {
        // only update the schema for this connection
        if ($forConnection !== $this->getConnection()) {
            return;
        }

        if ($schema->hasTable($this->table)) {
            return;
        }

        $this->addTableToSchema($schema);
    }

    /**
     * {@inheritdoc}
     */
    public function prune()
    {
        $deleteSql = "DELETE FROM $this->table WHERE $this->lifetimeCol + $this->timeCol <= :time";

        if ('' !== $this->namespace) {
            $deleteSql .= " AND $this->idCol LIKE :namespace";
        }

        try {
            $delete = $this->getConnection()->prepare($deleteSql);
        } catch (TableNotFoundException $e) {
            return true;
        } catch (\PDOException $e) {
            return true;
        }
        $delete->bindValue(':time', time(), \PDO::PARAM_INT);

        if ('' !== $this->namespace) {
            $delete->bindValue(':namespace', sprintf('%s%%', $this->namespace), \PDO::PARAM_STR);
        }
        try {
            return $delete->execute();
        } catch (TableNotFoundException $e) {
            return true;
        } catch (\PDOException $e) {
            return true;
        }
    }

    /**
     * {@inheritdoc}
     */
    protected function doFetch(array $ids)
    {
        $now = time();
        $expired = [];

        $sql = str_pad('', (\count($ids) << 1) - 1, '?,');
        $sql = "SELECT $this->idCol, CASE WHEN $this->lifetimeCol IS NULL OR $this->lifetimeCol + $this->timeCol > ? THEN $this->dataCol ELSE NULL END FROM $this->table WHERE $this->idCol IN ($sql)";
        $stmt = $this->getConnection()->prepare($sql);
        $stmt->bindValue($i = 1, $now, \PDO::PARAM_INT);
        foreach ($ids as $id) {
            $stmt->bindValue(++$i, $id);
        }
        $result = $stmt->execute();

        if (\is_object($result)) {
            $result = $result->iterateNumeric();
        } else {
            $stmt->setFetchMode(\PDO::FETCH_NUM);
            $result = $stmt;
        }

        foreach ($result as $row) {
            if (null === $row[1]) {
                $expired[] = $row[0];
            } else {
                yield $row[0] => $this->marshaller->unmarshall(\is_resource($row[1]) ? stream_get_contents($row[1]) : $row[1]);
            }
        }

        if ($expired) {
            $sql = str_pad('', (\count($expired) << 1) - 1, '?,');
            $sql = "DELETE FROM $this->table WHERE $this->lifetimeCol + $this->timeCol <= ? AND $this->idCol IN ($sql)";
            $stmt = $this->getConnection()->prepare($sql);
            $stmt->bindValue($i = 1, $now, \PDO::PARAM_INT);
            foreach ($expired as $id) {
                $stmt->bindValue(++$i, $id);
            }
            $stmt->execute();
        }
    }

    /**
     * {@inheritdoc}
     */
    protected function doHave(string $id)
    {
        $sql = "SELECT 1 FROM $this->table WHERE $this->idCol = :id AND ($this->lifetimeCol IS NULL OR $this->lifetimeCol + $this->timeCol > :time)";
        $stmt = $this->getConnection()->prepare($sql);

        $stmt->bindValue(':id', $id);
        $stmt->bindValue(':time', time(), \PDO::PARAM_INT);
        $result = $stmt->execute();

        return (bool) (\is_object($result) ? $result->fetchOne() : $stmt->fetchColumn());
    }

    /**
     * {@inheritdoc}
     */
    protected function doClear(string $namespace)
    {
        $conn = $this->getConnection();

        if ('' === $namespace) {
            if ('sqlite' === $this->driver) {
                $sql = "DELETE FROM $this->table";
            } else {
                $sql = "TRUNCATE TABLE $this->table";
            }
        } else {
            $sql = "DELETE FROM $this->table WHERE $this->idCol LIKE '$namespace%'";
        }

        try {
            if (method_exists($conn, 'executeStatement')) {
                $conn->executeStatement($sql);
            } else {
                $conn->exec($sql);
            }
        } catch (TableNotFoundException $e) {
        } catch (\PDOException $e) {
        }

        return true;
    }

    /**
     * {@inheritdoc}
     */
    protected function doDelete(array $ids)
    {
        $sql = str_pad('', (\count($ids) << 1) - 1, '?,');
        $sql = "DELETE FROM $this->table WHERE $this->idCol IN ($sql)";
        try {
            $stmt = $this->getConnection()->prepare($sql);
            $stmt->execute(array_values($ids));
        } catch (TableNotFoundException $e) {
        } catch (\PDOException $e) {
        }

        return true;
    }

    /**
     * {@inheritdoc}
     */
    protected function doSave(array $values, int $lifetime)
    {
        if (!$values = $this->marshaller->marshall($values, $failed)) {
            return $failed;
        }

        $conn = $this->getConnection();
        $driver = $this->driver;
        $insertSql = "INSERT INTO $this->table ($this->idCol, $this->dataCol, $this->lifetimeCol, $this->timeCol) VALUES (:id, :data, :lifetime, :time)";

        switch (true) {
            case 'mysql' === $driver:
                $sql = $insertSql." ON DUPLICATE KEY UPDATE $this->dataCol = VALUES($this->dataCol), $this->lifetimeCol = VALUES($this->lifetimeCol), $this->timeCol = VALUES($this->timeCol)";
                break;
            case 'oci' === $driver:
                // DUAL is Oracle specific dummy table
                $sql = "MERGE INTO $this->table USING DUAL ON ($this->idCol = ?) ".
                    "WHEN NOT MATCHED THEN INSERT ($this->idCol, $this->dataCol, $this->lifetimeCol, $this->timeCol) VALUES (?, ?, ?, ?) ".
                    "WHEN MATCHED THEN UPDATE SET $this->dataCol = ?, $this->lifetimeCol = ?, $this->timeCol = ?";
                break;
            case 'sqlsrv' === $driver && version_compare($this->getServerVersion(), '10', '>='):
                // MERGE is only available since SQL Server 2008 and must be terminated by semicolon
                // It also requires HOLDLOCK according to http://weblogs.sqlteam.com/dang/archive/2009/01/31/UPSERT-Race-Condition-With-MERGE.aspx
                $sql = "MERGE INTO $this->table WITH (HOLDLOCK) USING (SELECT 1 AS dummy) AS src ON ($this->idCol = ?) ".
                    "WHEN NOT MATCHED THEN INSERT ($this->idCol, $this->dataCol, $this->lifetimeCol, $this->timeCol) VALUES (?, ?, ?, ?) ".
                    "WHEN MATCHED THEN UPDATE SET $this->dataCol = ?, $this->lifetimeCol = ?, $this->timeCol = ?;";
                break;
            case 'sqlite' === $driver:
                $sql = 'INSERT OR REPLACE'.substr($insertSql, 6);
                break;
            case 'pgsql' === $driver && version_compare($this->getServerVersion(), '9.5', '>='):
                $sql = $insertSql." ON CONFLICT ($this->idCol) DO UPDATE SET ($this->dataCol, $this->lifetimeCol, $this->timeCol) = (EXCLUDED.$this->dataCol, EXCLUDED.$this->lifetimeCol, EXCLUDED.$this->timeCol)";
                break;
            default:
                $driver = null;
                $sql = "UPDATE $this->table SET $this->dataCol = :data, $this->lifetimeCol = :lifetime, $this->timeCol = :time WHERE $this->idCol = :id";
                break;
        }

        $now = time();
        $lifetime = $lifetime ?: null;
        try {
            $stmt = $conn->prepare($sql);
        } catch (TableNotFoundException $e) {
            if (!$conn->isTransactionActive() || \in_array($this->driver, ['pgsql', 'sqlite', 'sqlsrv'], true)) {
                $this->createTable();
            }
            $stmt = $conn->prepare($sql);
        } catch (\PDOException $e) {
            if (!$conn->inTransaction() || \in_array($this->driver, ['pgsql', 'sqlite', 'sqlsrv'], true)) {
                $this->createTable();
            }
            $stmt = $conn->prepare($sql);
        }

        if ('sqlsrv' === $driver || 'oci' === $driver) {
            $stmt->bindParam(1, $id);
            $stmt->bindParam(2, $id);
            $stmt->bindParam(3, $data, \PDO::PARAM_LOB);
            $stmt->bindValue(4, $lifetime, \PDO::PARAM_INT);
            $stmt->bindValue(5, $now, \PDO::PARAM_INT);
            $stmt->bindParam(6, $data, \PDO::PARAM_LOB);
            $stmt->bindValue(7, $lifetime, \PDO::PARAM_INT);
            $stmt->bindValue(8, $now, \PDO::PARAM_INT);
        } else {
            $stmt->bindParam(':id', $id);
            $stmt->bindParam(':data', $data, \PDO::PARAM_LOB);
            $stmt->bindValue(':lifetime', $lifetime, \PDO::PARAM_INT);
            $stmt->bindValue(':time', $now, \PDO::PARAM_INT);
        }
        if (null === $driver) {
            $insertStmt = $conn->prepare($insertSql);

            $insertStmt->bindParam(':id', $id);
            $insertStmt->bindParam(':data', $data, \PDO::PARAM_LOB);
            $insertStmt->bindValue(':lifetime', $lifetime, \PDO::PARAM_INT);
            $insertStmt->bindValue(':time', $now, \PDO::PARAM_INT);
        }

        foreach ($values as $id => $data) {
            try {
                $result = $stmt->execute();
            } catch (TableNotFoundException $e) {
                if (!$conn->isTransactionActive() || \in_array($this->driver, ['pgsql', 'sqlite', 'sqlsrv'], true)) {
                    $this->createTable();
                }
                $result = $stmt->execute();
            } catch (\PDOException $e) {
                if (!$conn->inTransaction() || \in_array($this->driver, ['pgsql', 'sqlite', 'sqlsrv'], true)) {
                    $this->createTable();
                }
                $result = $stmt->execute();
            }
            if (null === $driver && !(\is_object($result) ? $result->rowCount() : $stmt->rowCount())) {
                try {
                    $insertStmt->execute();
                } catch (DBALException | Exception $e) {
                } catch (\PDOException $e) {
                    // A concurrent write won, let it be
                }
            }
        }

        return $failed;
    }

    /**
     * @return \PDO|Connection
     */
    private function getConnection(): object
    {
        if (null === $this->conn) {
            if (strpos($this->dsn, '://')) {
                if (!class_exists(DriverManager::class)) {
                    throw new InvalidArgumentException(sprintf('Failed to parse the DSN "%s". Try running "composer require doctrine/dbal".', $this->dsn));
                }
                $this->conn = DriverManager::getConnection(['url' => $this->dsn]);
            } else {
                $this->conn = new \PDO($this->dsn, $this->username, $this->password, $this->connectionOptions);
                $this->conn->setAttribute(\PDO::ATTR_ERRMODE, \PDO::ERRMODE_EXCEPTION);
            }
        }
        if (null === $this->driver) {
            if ($this->conn instanceof \PDO) {
                $this->driver = $this->conn->getAttribute(\PDO::ATTR_DRIVER_NAME);
            } else {
                $driver = $this->conn->getDriver();

                switch (true) {
                    case $driver instanceof \Doctrine\DBAL\Driver\Mysqli\Driver:
                        throw new \LogicException(sprintf('The adapter "%s" does not support the mysqli driver, use pdo_mysql instead.', static::class));
                    case $driver instanceof \Doctrine\DBAL\Driver\AbstractMySQLDriver:
                        $this->driver = 'mysql';
                        break;
                    case $driver instanceof \Doctrine\DBAL\Driver\PDOSqlite\Driver:
                    case $driver instanceof \Doctrine\DBAL\Driver\PDO\SQLite\Driver:
                        $this->driver = 'sqlite';
                        break;
                    case $driver instanceof \Doctrine\DBAL\Driver\PDOPgSql\Driver:
                    case $driver instanceof \Doctrine\DBAL\Driver\PDO\PgSQL\Driver:
                        $this->driver = 'pgsql';
                        break;
                    case $driver instanceof \Doctrine\DBAL\Driver\OCI8\Driver:
                    case $driver instanceof \Doctrine\DBAL\Driver\PDOOracle\Driver:
                    case $driver instanceof \Doctrine\DBAL\Driver\PDO\OCI\Driver:
                        $this->driver = 'oci';
                        break;
                    case $driver instanceof \Doctrine\DBAL\Driver\SQLSrv\Driver:
                    case $driver instanceof \Doctrine\DBAL\Driver\PDOSqlsrv\Driver:
                    case $driver instanceof \Doctrine\DBAL\Driver\PDO\SQLSrv\Driver:
                        $this->driver = 'sqlsrv';
                        break;
                    default:
                        $this->driver = \get_class($driver);
                        break;
                }
            }
        }

        return $this->conn;
    }

    private function getServerVersion(): string
    {
        if (null === $this->serverVersion) {
            $conn = $this->conn instanceof \PDO ? $this->conn : $this->conn->getWrappedConnection();
            if ($conn instanceof \PDO) {
                $this->serverVersion = $conn->getAttribute(\PDO::ATTR_SERVER_VERSION);
            } elseif ($conn instanceof ServerInfoAwareConnection) {
                $this->serverVersion = $conn->getServerVersion();
            } else {
                $this->serverVersion = '0';
            }
        }

        return $this->serverVersion;
    }

    private function addTableToSchema(Schema $schema): void
    {
        $types = [
            'mysql' => 'binary',
            'sqlite' => 'text',
            'pgsql' => 'string',
            'oci' => 'string',
            'sqlsrv' => 'string',
        ];
        if (!isset($types[$this->driver])) {
            throw new \DomainException(sprintf('Creating the cache table is currently not implemented for PDO driver "%s".', $this->driver));
        }

        $table = $schema->createTable($this->table);
        $table->addColumn($this->idCol, $types[$this->driver], ['length' => 255]);
        $table->addColumn($this->dataCol, 'blob', ['length' => 16777215]);
        $table->addColumn($this->lifetimeCol, 'integer', ['unsigned' => true, 'notnull' => false]);
        $table->addColumn($this->timeCol, 'integer', ['unsigned' => true]);
        $table->setPrimaryKey([$this->idCol]);
    }
}
PKϤ$Z��I((!cache/Adapter/PhpFilesAdapter.phpnu�[���<?php

/*
 * This file is part of the Symfony package.
 *
 * (c) Fabien Potencier <fabien@symfony.com>
 *
 * For the full copyright and license information, please view the LICENSE
 * file that was distributed with this source code.
 */

namespace Symfony\Component\Cache\Adapter;

use Symfony\Component\Cache\Exception\CacheException;
use Symfony\Component\Cache\Exception\InvalidArgumentException;
use Symfony\Component\Cache\PruneableInterface;
use Symfony\Component\Cache\Traits\FilesystemCommonTrait;
use Symfony\Component\VarExporter\VarExporter;

/**
 * @author Piotr Stankowski <git@trakos.pl>
 * @author Nicolas Grekas <p@tchwork.com>
 * @author Rob Frawley 2nd <rmf@src.run>
 */
class PhpFilesAdapter extends AbstractAdapter implements PruneableInterface
{
    use FilesystemCommonTrait {
        doClear as private doCommonClear;
        doDelete as private doCommonDelete;
    }

    private $includeHandler;
    private $appendOnly;
    private $values = [];
    private $files = [];

    private static $startTime;
    private static $valuesCache = [];

    /**
     * @param $appendOnly Set to `true` to gain extra performance when the items stored in this pool never expire.
     *                    Doing so is encouraged because it fits perfectly OPcache's memory model.
     *
     * @throws CacheException if OPcache is not enabled
     */
    public function __construct(string $namespace = '', int $defaultLifetime = 0, string $directory = null, bool $appendOnly = false)
    {
        $this->appendOnly = $appendOnly;
        self::$startTime = self::$startTime ?? $_SERVER['REQUEST_TIME'] ?? time();
        parent::__construct('', $defaultLifetime);
        $this->init($namespace, $directory);
        $this->includeHandler = static function ($type, $msg, $file, $line) {
            throw new \ErrorException($msg, 0, $type, $file, $line);
        };
    }

    public static function isSupported()
    {
        self::$startTime = self::$startTime ?? $_SERVER['REQUEST_TIME'] ?? time();

        return \function_exists('opcache_invalidate') && filter_var(ini_get('opcache.enable'), \FILTER_VALIDATE_BOOLEAN) && (!\in_array(\PHP_SAPI, ['cli', 'phpdbg'], true) || filter_var(ini_get('opcache.enable_cli'), \FILTER_VALIDATE_BOOLEAN));
    }

    /**
     * @return bool
     */
    public function prune()
    {
        $time = time();
        $pruned = true;
        $getExpiry = true;

        set_error_handler($this->includeHandler);
        try {
            foreach ($this->scanHashDir($this->directory) as $file) {
                try {
                    if (\is_array($expiresAt = include $file)) {
                        $expiresAt = $expiresAt[0];
                    }
                } catch (\ErrorException $e) {
                    $expiresAt = $time;
                }

                if ($time >= $expiresAt) {
                    $pruned = $this->doUnlink($file) && !file_exists($file) && $pruned;
                }
            }
        } finally {
            restore_error_handler();
        }

        return $pruned;
    }

    /**
     * {@inheritdoc}
     */
    protected function doFetch(array $ids)
    {
        if ($this->appendOnly) {
            $now = 0;
            $missingIds = [];
        } else {
            $now = time();
            $missingIds = $ids;
            $ids = [];
        }
        $values = [];

        begin:
        $getExpiry = false;

        foreach ($ids as $id) {
            if (null === $value = $this->values[$id] ?? null) {
                $missingIds[] = $id;
            } elseif ('N;' === $value) {
                $values[$id] = null;
            } elseif (!\is_object($value)) {
                $values[$id] = $value;
            } elseif (!$value instanceof LazyValue) {
                $values[$id] = $value();
            } elseif (false === $values[$id] = include $value->file) {
                unset($values[$id], $this->values[$id]);
                $missingIds[] = $id;
            }
            if (!$this->appendOnly) {
                unset($this->values[$id]);
            }
        }

        if (!$missingIds) {
            return $values;
        }

        set_error_handler($this->includeHandler);
        try {
            $getExpiry = true;

            foreach ($missingIds as $k => $id) {
                try {
                    $file = $this->files[$id] ?? $this->files[$id] = $this->getFile($id);

                    if (isset(self::$valuesCache[$file])) {
                        [$expiresAt, $this->values[$id]] = self::$valuesCache[$file];
                    } elseif (\is_array($expiresAt = include $file)) {
                        if ($this->appendOnly) {
                            self::$valuesCache[$file] = $expiresAt;
                        }

                        [$expiresAt, $this->values[$id]] = $expiresAt;
                    } elseif ($now < $expiresAt) {
                        $this->values[$id] = new LazyValue($file);
                    }

                    if ($now >= $expiresAt) {
                        unset($this->values[$id], $missingIds[$k], self::$valuesCache[$file]);
                    }
                } catch (\ErrorException $e) {
                    unset($missingIds[$k]);
                }
            }
        } finally {
            restore_error_handler();
        }

        $ids = $missingIds;
        $missingIds = [];
        goto begin;
    }

    /**
     * {@inheritdoc}
     */
    protected function doHave(string $id)
    {
        if ($this->appendOnly && isset($this->values[$id])) {
            return true;
        }

        set_error_handler($this->includeHandler);
        try {
            $file = $this->files[$id] ?? $this->files[$id] = $this->getFile($id);
            $getExpiry = true;

            if (isset(self::$valuesCache[$file])) {
                [$expiresAt, $value] = self::$valuesCache[$file];
            } elseif (\is_array($expiresAt = include $file)) {
                if ($this->appendOnly) {
                    self::$valuesCache[$file] = $expiresAt;
                }

                [$expiresAt, $value] = $expiresAt;
            } elseif ($this->appendOnly) {
                $value = new LazyValue($file);
            }
        } catch (\ErrorException $e) {
            return false;
        } finally {
            restore_error_handler();
        }
        if ($this->appendOnly) {
            $now = 0;
            $this->values[$id] = $value;
        } else {
            $now = time();
        }

        return $now < $expiresAt;
    }

    /**
     * {@inheritdoc}
     */
    protected function doSave(array $values, int $lifetime)
    {
        $ok = true;
        $expiry = $lifetime ? time() + $lifetime : 'PHP_INT_MAX';
        $allowCompile = self::isSupported();

        foreach ($values as $key => $value) {
            unset($this->values[$key]);
            $isStaticValue = true;
            if (null === $value) {
                $value = "'N;'";
            } elseif (\is_object($value) || \is_array($value)) {
                try {
                    $value = VarExporter::export($value, $isStaticValue);
                } catch (\Exception $e) {
                    throw new InvalidArgumentException(sprintf('Cache key "%s" has non-serializable "%s" value.', $key, get_debug_type($value)), 0, $e);
                }
            } elseif (\is_string($value)) {
                // Wrap "N;" in a closure to not confuse it with an encoded `null`
                if ('N;' === $value) {
                    $isStaticValue = false;
                }
                $value = var_export($value, true);
            } elseif (!is_scalar($value)) {
                throw new InvalidArgumentException(sprintf('Cache key "%s" has non-serializable "%s" value.', $key, get_debug_type($value)));
            } else {
                $value = var_export($value, true);
            }

            $encodedKey = rawurlencode($key);

            if ($isStaticValue) {
                $value = "return [{$expiry}, {$value}];";
            } elseif ($this->appendOnly) {
                $value = "return [{$expiry}, static function () { return {$value}; }];";
            } else {
                // We cannot use a closure here because of https://bugs.php.net/76982
                $value = str_replace('\Symfony\Component\VarExporter\Internal\\', '', $value);
                $value = "namespace Symfony\Component\VarExporter\Internal;\n\nreturn \$getExpiry ? {$expiry} : {$value};";
            }

            $file = $this->files[$key] = $this->getFile($key, true);
            // Since OPcache only compiles files older than the script execution start, set the file's mtime in the past
            $ok = $this->write($file, "<?php //{$encodedKey}\n\n{$value}\n", self::$startTime - 10) && $ok;

            if ($allowCompile) {
                @opcache_invalidate($file, true);
                @opcache_compile_file($file);
            }
            unset(self::$valuesCache[$file]);
        }

        if (!$ok && !is_writable($this->directory)) {
            throw new CacheException(sprintf('Cache directory is not writable (%s).', $this->directory));
        }

        return $ok;
    }

    /**
     * {@inheritdoc}
     */
    protected function doClear(string $namespace)
    {
        $this->values = [];

        return $this->doCommonClear($namespace);
    }

    /**
     * {@inheritdoc}
     */
    protected function doDelete(array $ids)
    {
        foreach ($ids as $id) {
            unset($this->values[$id]);
        }

        return $this->doCommonDelete($ids);
    }

    protected function doUnlink($file)
    {
        unset(self::$valuesCache[$file]);

        if (self::isSupported()) {
            @opcache_invalidate($file, true);
        }

        return @unlink($file);
    }

    private function getFileKey(string $file): string
    {
        if (!$h = @fopen($file, 'r')) {
            return '';
        }

        $encodedKey = substr(fgets($h), 8);
        fclose($h);

        return rawurldecode(rtrim($encodedKey));
    }
}

/**
 * @internal
 */
class LazyValue
{
    public $file;

    public function __construct($file)
    {
        $this->file = $file;
    }
}
PKϤ$Z|�����!cache/Adapter/AbstractAdapter.phpnu�[���<?php

/*
 * This file is part of the Symfony package.
 *
 * (c) Fabien Potencier <fabien@symfony.com>
 *
 * For the full copyright and license information, please view the LICENSE
 * file that was distributed with this source code.
 */

namespace Symfony\Component\Cache\Adapter;

use Psr\Log\LoggerAwareInterface;
use Psr\Log\LoggerInterface;
use Symfony\Component\Cache\CacheItem;
use Symfony\Component\Cache\Exception\InvalidArgumentException;
use Symfony\Component\Cache\ResettableInterface;
use Symfony\Component\Cache\Traits\AbstractAdapterTrait;
use Symfony\Component\Cache\Traits\ContractsTrait;
use Symfony\Contracts\Cache\CacheInterface;

/**
 * @author Nicolas Grekas <p@tchwork.com>
 */
abstract class AbstractAdapter implements AdapterInterface, CacheInterface, LoggerAwareInterface, ResettableInterface
{
    /**
     * @internal
     */
    protected const NS_SEPARATOR = ':';

    use AbstractAdapterTrait;
    use ContractsTrait;

    private static $apcuSupported;
    private static $phpFilesSupported;

    protected function __construct(string $namespace = '', int $defaultLifetime = 0)
    {
        $this->namespace = '' === $namespace ? '' : CacheItem::validateKey($namespace).static::NS_SEPARATOR;
        if (null !== $this->maxIdLength && \strlen($namespace) > $this->maxIdLength - 24) {
            throw new InvalidArgumentException(sprintf('Namespace must be %d chars max, %d given ("%s").', $this->maxIdLength - 24, \strlen($namespace), $namespace));
        }
        $this->createCacheItem = \Closure::bind(
            static function ($key, $value, $isHit) {
                $item = new CacheItem();
                $item->key = $key;
                $item->value = $v = $value;
                $item->isHit = $isHit;
                // Detect wrapped values that encode for their expiry and creation duration
                // For compactness, these values are packed in the key of an array using
                // magic numbers in the form 9D-..-..-..-..-00-..-..-..-5F
                if (\is_array($v) && 1 === \count($v) && 10 === \strlen($k = (string) key($v)) && "\x9D" === $k[0] && "\0" === $k[5] && "\x5F" === $k[9]) {
                    $item->value = $v[$k];
                    $v = unpack('Ve/Nc', substr($k, 1, -1));
                    $item->metadata[CacheItem::METADATA_EXPIRY] = $v['e'] + CacheItem::METADATA_EXPIRY_OFFSET;
                    $item->metadata[CacheItem::METADATA_CTIME] = $v['c'];
                }

                return $item;
            },
            null,
            CacheItem::class
        );
        $getId = \Closure::fromCallable([$this, 'getId']);
        $this->mergeByLifetime = \Closure::bind(
            static function ($deferred, $namespace, &$expiredIds) use ($getId, $defaultLifetime) {
                $byLifetime = [];
                $now = microtime(true);
                $expiredIds = [];

                foreach ($deferred as $key => $item) {
                    $key = (string) $key;
                    if (null === $item->expiry) {
                        $ttl = 0 < $defaultLifetime ? $defaultLifetime : 0;
                    } elseif (0 === $item->expiry) {
                        $ttl = 0;
                    } elseif (0 >= $ttl = (int) (0.1 + $item->expiry - $now)) {
                        $expiredIds[] = $getId($key);
                        continue;
                    }
                    if (isset(($metadata = $item->newMetadata)[CacheItem::METADATA_TAGS])) {
                        unset($metadata[CacheItem::METADATA_TAGS]);
                    }
                    // For compactness, expiry and creation duration are packed in the key of an array, using magic numbers as separators
                    $byLifetime[$ttl][$getId($key)] = $metadata ? ["\x9D".pack('VN', (int) (0.1 + $metadata[self::METADATA_EXPIRY] - self::METADATA_EXPIRY_OFFSET), $metadata[self::METADATA_CTIME])."\x5F" => $item->value] : $item->value;
                }

                return $byLifetime;
            },
            null,
            CacheItem::class
        );
    }

    /**
     * Returns the best possible adapter that your runtime supports.
     *
     * Using ApcuAdapter makes system caches compatible with read-only filesystems.
     *
     * @return AdapterInterface
     */
    public static function createSystemCache(string $namespace, int $defaultLifetime, string $version, string $directory, LoggerInterface $logger = null)
    {
        $opcache = new PhpFilesAdapter($namespace, $defaultLifetime, $directory, true);
        if (null !== $logger) {
            $opcache->setLogger($logger);
        }

        if (!self::$apcuSupported = self::$apcuSupported ?? ApcuAdapter::isSupported()) {
            return $opcache;
        }

        if (\in_array(\PHP_SAPI, ['cli', 'phpdbg'], true) && !filter_var(ini_get('apc.enable_cli'), \FILTER_VALIDATE_BOOLEAN)) {
            return $opcache;
        }

        $apcu = new ApcuAdapter($namespace, (int) $defaultLifetime / 5, $version);
        if (null !== $logger) {
            $apcu->setLogger($logger);
        }

        return new ChainAdapter([$apcu, $opcache]);
    }

    public static function createConnection(string $dsn, array $options = [])
    {
        if (0 === strpos($dsn, 'redis:') || 0 === strpos($dsn, 'rediss:')) {
            return RedisAdapter::createConnection($dsn, $options);
        }
        if (0 === strpos($dsn, 'memcached:')) {
            return MemcachedAdapter::createConnection($dsn, $options);
        }
        if (0 === strpos($dsn, 'couchbase:')) {
            return CouchbaseBucketAdapter::createConnection($dsn, $options);
        }

        throw new InvalidArgumentException(sprintf('Unsupported DSN: "%s".', $dsn));
    }

    /**
     * {@inheritdoc}
     *
     * @return bool
     */
    public function commit()
    {
        $ok = true;
        $byLifetime = $this->mergeByLifetime;
        $byLifetime = $byLifetime($this->deferred, $this->namespace, $expiredIds);
        $retry = $this->deferred = [];

        if ($expiredIds) {
            $this->doDelete($expiredIds);
        }
        foreach ($byLifetime as $lifetime => $values) {
            try {
                $e = $this->doSave($values, $lifetime);
            } catch (\Exception $e) {
            }
            if (true === $e || [] === $e) {
                continue;
            }
            if (\is_array($e) || 1 === \count($values)) {
                foreach (\is_array($e) ? $e : array_keys($values) as $id) {
                    $ok = false;
                    $v = $values[$id];
                    $type = get_debug_type($v);
                    $message = sprintf('Failed to save key "{key}" of type %s%s', $type, $e instanceof \Exception ? ': '.$e->getMessage() : '.');
                    CacheItem::log($this->logger, $message, ['key' => substr($id, \strlen($this->namespace)), 'exception' => $e instanceof \Exception ? $e : null, 'cache-adapter' => get_debug_type($this)]);
                }
            } else {
                foreach ($values as $id => $v) {
                    $retry[$lifetime][] = $id;
                }
            }
        }

        // When bulk-save failed, retry each item individually
        foreach ($retry as $lifetime => $ids) {
            foreach ($ids as $id) {
                try {
                    $v = $byLifetime[$lifetime][$id];
                    $e = $this->doSave([$id => $v], $lifetime);
                } catch (\Exception $e) {
                }
                if (true === $e || [] === $e) {
                    continue;
                }
                $ok = false;
                $type = get_debug_type($v);
                $message = sprintf('Failed to save key "{key}" of type %s%s', $type, $e instanceof \Exception ? ': '.$e->getMessage() : '.');
                CacheItem::log($this->logger, $message, ['key' => substr($id, \strlen($this->namespace)), 'exception' => $e instanceof \Exception ? $e : null, 'cache-adapter' => get_debug_type($this)]);
            }
        }

        return $ok;
    }
}
PKϤ$Z�3Y��cache/PruneableInterface.phpnu�[���<?php

/*
 * This file is part of the Symfony package.
 *
 * (c) Fabien Potencier <fabien@symfony.com>
 *
 * For the full copyright and license information, please view the LICENSE
 * file that was distributed with this source code.
 */

namespace Symfony\Component\Cache;

/**
 * Interface extends psr-6 and psr-16 caches to allow for pruning (deletion) of all expired cache items.
 */
interface PruneableInterface
{
    /**
     * @return bool
     */
    public function prune();
}
PKϤ$Z:j[���cache/CacheItem.phpnu�[���<?php

/*
 * This file is part of the Symfony package.
 *
 * (c) Fabien Potencier <fabien@symfony.com>
 *
 * For the full copyright and license information, please view the LICENSE
 * file that was distributed with this source code.
 */

namespace Symfony\Component\Cache;

use Psr\Log\LoggerInterface;
use Symfony\Component\Cache\Exception\InvalidArgumentException;
use Symfony\Component\Cache\Exception\LogicException;
use Symfony\Contracts\Cache\ItemInterface;

/**
 * @author Nicolas Grekas <p@tchwork.com>
 */
final class CacheItem implements ItemInterface
{
    private const METADATA_EXPIRY_OFFSET = 1527506807;

    protected $key;
    protected $value;
    protected $isHit = false;
    protected $expiry;
    protected $metadata = [];
    protected $newMetadata = [];
    protected $innerItem;
    protected $poolHash;
    protected $isTaggable = false;

    /**
     * {@inheritdoc}
     */
    public function getKey(): string
    {
        return $this->key;
    }

    /**
     * {@inheritdoc}
     *
     * @return mixed
     */
    public function get()
    {
        return $this->value;
    }

    /**
     * {@inheritdoc}
     */
    public function isHit(): bool
    {
        return $this->isHit;
    }

    /**
     * {@inheritdoc}
     *
     * @return $this
     */
    public function set($value): self
    {
        $this->value = $value;

        return $this;
    }

    /**
     * {@inheritdoc}
     *
     * @return $this
     */
    public function expiresAt($expiration): self
    {
        if (null === $expiration) {
            $this->expiry = null;
        } elseif ($expiration instanceof \DateTimeInterface) {
            $this->expiry = (float) $expiration->format('U.u');
        } else {
            throw new InvalidArgumentException(sprintf('Expiration date must implement DateTimeInterface or be null, "%s" given.', get_debug_type($expiration)));
        }

        return $this;
    }

    /**
     * {@inheritdoc}
     *
     * @return $this
     */
    public function expiresAfter($time): self
    {
        if (null === $time) {
            $this->expiry = null;
        } elseif ($time instanceof \DateInterval) {
            $this->expiry = microtime(true) + \DateTime::createFromFormat('U', 0)->add($time)->format('U.u');
        } elseif (\is_int($time)) {
            $this->expiry = $time + microtime(true);
        } else {
            throw new InvalidArgumentException(sprintf('Expiration date must be an integer, a DateInterval or null, "%s" given.', get_debug_type($time)));
        }

        return $this;
    }

    /**
     * {@inheritdoc}
     */
    public function tag($tags): ItemInterface
    {
        if (!$this->isTaggable) {
            throw new LogicException(sprintf('Cache item "%s" comes from a non tag-aware pool: you cannot tag it.', $this->key));
        }
        if (!is_iterable($tags)) {
            $tags = [$tags];
        }
        foreach ($tags as $tag) {
            if (!\is_string($tag) && !(\is_object($tag) && method_exists($tag, '__toString'))) {
                throw new InvalidArgumentException(sprintf('Cache tag must be string or object that implements __toString(), "%s" given.', \is_object($tag) ? \get_class($tag) : \gettype($tag)));
            }
            $tag = (string) $tag;
            if (isset($this->newMetadata[self::METADATA_TAGS][$tag])) {
                continue;
            }
            if ('' === $tag) {
                throw new InvalidArgumentException('Cache tag length must be greater than zero.');
            }
            if (false !== strpbrk($tag, self::RESERVED_CHARACTERS)) {
                throw new InvalidArgumentException(sprintf('Cache tag "%s" contains reserved characters "%s".', $tag, self::RESERVED_CHARACTERS));
            }
            $this->newMetadata[self::METADATA_TAGS][$tag] = $tag;
        }

        return $this;
    }

    /**
     * {@inheritdoc}
     */
    public function getMetadata(): array
    {
        return $this->metadata;
    }

    /**
     * Validates a cache key according to PSR-6.
     *
     * @param string $key The key to validate
     *
     * @throws InvalidArgumentException When $key is not valid
     */
    public static function validateKey($key): string
    {
        if (!\is_string($key)) {
            throw new InvalidArgumentException(sprintf('Cache key must be string, "%s" given.', get_debug_type($key)));
        }
        if ('' === $key) {
            throw new InvalidArgumentException('Cache key length must be greater than zero.');
        }
        if (false !== strpbrk($key, self::RESERVED_CHARACTERS)) {
            throw new InvalidArgumentException(sprintf('Cache key "%s" contains reserved characters "%s".', $key, self::RESERVED_CHARACTERS));
        }

        return $key;
    }

    /**
     * Internal logging helper.
     *
     * @internal
     */
    public static function log(?LoggerInterface $logger, string $message, array $context = [])
    {
        if ($logger) {
            $logger->warning($message, $context);
        } else {
            $replace = [];
            foreach ($context as $k => $v) {
                if (is_scalar($v)) {
                    $replace['{'.$k.'}'] = $v;
                }
            }
            @trigger_error(strtr($message, $replace), \E_USER_WARNING);
        }
    }
}
PKϤ$Z�i����cache/ResettableInterface.phpnu�[���<?php

/*
 * This file is part of the Symfony package.
 *
 * (c) Fabien Potencier <fabien@symfony.com>
 *
 * For the full copyright and license information, please view the LICENSE
 * file that was distributed with this source code.
 */

namespace Symfony\Component\Cache;

use Symfony\Contracts\Service\ResetInterface;

/**
 * Resets a pool's local state.
 */
interface ResettableInterface extends ResetInterface
{
}
PKϤ$ZRL$���cache/README.mdnu�[���Symfony PSR-6 implementation for caching
========================================

The Cache component provides an extended
[PSR-6](http://www.php-fig.org/psr/psr-6/) implementation for adding cache to
your applications. It is designed to have a low overhead so that caching is
fastest. It ships with a few caching adapters for the most widespread and
suited to caching backends. It also provides a `doctrine/cache` proxy adapter
to cover more advanced caching needs and a proxy adapter for greater
interoperability between PSR-6 implementations.

Resources
---------

  * [Documentation](https://symfony.com/doc/current/components/cache.html)
  * [Contributing](https://symfony.com/doc/current/contributing/index.html)
  * [Report issues](https://github.com/symfony/symfony/issues) and
    [send Pull Requests](https://github.com/symfony/symfony/pulls)
    in the [main Symfony repository](https://github.com/symfony/symfony)
PKϤ$Z^w�S S cache/Psr16Cache.phpnu�[���<?php

/*
 * This file is part of the Symfony package.
 *
 * (c) Fabien Potencier <fabien@symfony.com>
 *
 * For the full copyright and license information, please view the LICENSE
 * file that was distributed with this source code.
 */

namespace Symfony\Component\Cache;

use Psr\Cache\CacheException as Psr6CacheException;
use Psr\Cache\CacheItemPoolInterface;
use Psr\SimpleCache\CacheException as SimpleCacheException;
use Psr\SimpleCache\CacheInterface;
use Symfony\Component\Cache\Adapter\AdapterInterface;
use Symfony\Component\Cache\Exception\InvalidArgumentException;
use Symfony\Component\Cache\Traits\ProxyTrait;

/**
 * Turns a PSR-6 cache into a PSR-16 one.
 *
 * @author Nicolas Grekas <p@tchwork.com>
 */
class Psr16Cache implements CacheInterface, PruneableInterface, ResettableInterface
{
    use ProxyTrait;

    private const METADATA_EXPIRY_OFFSET = 1527506807;

    private $createCacheItem;
    private $cacheItemPrototype;

    public function __construct(CacheItemPoolInterface $pool)
    {
        $this->pool = $pool;

        if (!$pool instanceof AdapterInterface) {
            return;
        }
        $cacheItemPrototype = &$this->cacheItemPrototype;
        $createCacheItem = \Closure::bind(
            static function ($key, $value, $allowInt = false) use (&$cacheItemPrototype) {
                $item = clone $cacheItemPrototype;
                $item->poolHash = $item->innerItem = null;
                $item->key = $allowInt && \is_int($key) ? (string) $key : CacheItem::validateKey($key);
                $item->value = $value;
                $item->isHit = false;

                return $item;
            },
            null,
            CacheItem::class
        );
        $this->createCacheItem = function ($key, $value, $allowInt = false) use ($createCacheItem) {
            if (null === $this->cacheItemPrototype) {
                $this->get($allowInt && \is_int($key) ? (string) $key : $key);
            }
            $this->createCacheItem = $createCacheItem;

            return $createCacheItem($key, null, $allowInt)->set($value);
        };
    }

    /**
     * {@inheritdoc}
     *
     * @return mixed
     */
    public function get($key, $default = null)
    {
        try {
            $item = $this->pool->getItem($key);
        } catch (SimpleCacheException $e) {
            throw $e;
        } catch (Psr6CacheException $e) {
            throw new InvalidArgumentException($e->getMessage(), $e->getCode(), $e);
        }
        if (null === $this->cacheItemPrototype) {
            $this->cacheItemPrototype = clone $item;
            $this->cacheItemPrototype->set(null);
        }

        return $item->isHit() ? $item->get() : $default;
    }

    /**
     * {@inheritdoc}
     *
     * @return bool
     */
    public function set($key, $value, $ttl = null)
    {
        try {
            if (null !== $f = $this->createCacheItem) {
                $item = $f($key, $value);
            } else {
                $item = $this->pool->getItem($key)->set($value);
            }
        } catch (SimpleCacheException $e) {
            throw $e;
        } catch (Psr6CacheException $e) {
            throw new InvalidArgumentException($e->getMessage(), $e->getCode(), $e);
        }
        if (null !== $ttl) {
            $item->expiresAfter($ttl);
        }

        return $this->pool->save($item);
    }

    /**
     * {@inheritdoc}
     *
     * @return bool
     */
    public function delete($key)
    {
        try {
            return $this->pool->deleteItem($key);
        } catch (SimpleCacheException $e) {
            throw $e;
        } catch (Psr6CacheException $e) {
            throw new InvalidArgumentException($e->getMessage(), $e->getCode(), $e);
        }
    }

    /**
     * {@inheritdoc}
     *
     * @return bool
     */
    public function clear()
    {
        return $this->pool->clear();
    }

    /**
     * {@inheritdoc}
     *
     * @return iterable
     */
    public function getMultiple($keys, $default = null)
    {
        if ($keys instanceof \Traversable) {
            $keys = iterator_to_array($keys, false);
        } elseif (!\is_array($keys)) {
            throw new InvalidArgumentException(sprintf('Cache keys must be array or Traversable, "%s" given.', get_debug_type($keys)));
        }

        try {
            $items = $this->pool->getItems($keys);
        } catch (SimpleCacheException $e) {
            throw $e;
        } catch (Psr6CacheException $e) {
            throw new InvalidArgumentException($e->getMessage(), $e->getCode(), $e);
        }
        $values = [];

        if (!$this->pool instanceof AdapterInterface) {
            foreach ($items as $key => $item) {
                $values[$key] = $item->isHit() ? $item->get() : $default;
            }

            return $values;
        }

        foreach ($items as $key => $item) {
            if (!$item->isHit()) {
                $values[$key] = $default;
                continue;
            }
            $values[$key] = $item->get();

            if (!$metadata = $item->getMetadata()) {
                continue;
            }
            unset($metadata[CacheItem::METADATA_TAGS]);

            if ($metadata) {
                $values[$key] = ["\x9D".pack('VN', (int) (0.1 + $metadata[CacheItem::METADATA_EXPIRY] - self::METADATA_EXPIRY_OFFSET), $metadata[CacheItem::METADATA_CTIME])."\x5F" => $values[$key]];
            }
        }

        return $values;
    }

    /**
     * {@inheritdoc}
     *
     * @return bool
     */
    public function setMultiple($values, $ttl = null)
    {
        $valuesIsArray = \is_array($values);
        if (!$valuesIsArray && !$values instanceof \Traversable) {
            throw new InvalidArgumentException(sprintf('Cache values must be array or Traversable, "%s" given.', get_debug_type($values)));
        }
        $items = [];

        try {
            if (null !== $f = $this->createCacheItem) {
                $valuesIsArray = false;
                foreach ($values as $key => $value) {
                    $items[$key] = $f($key, $value, true);
                }
            } elseif ($valuesIsArray) {
                $items = [];
                foreach ($values as $key => $value) {
                    $items[] = (string) $key;
                }
                $items = $this->pool->getItems($items);
            } else {
                foreach ($values as $key => $value) {
                    if (\is_int($key)) {
                        $key = (string) $key;
                    }
                    $items[$key] = $this->pool->getItem($key)->set($value);
                }
            }
        } catch (SimpleCacheException $e) {
            throw $e;
        } catch (Psr6CacheException $e) {
            throw new InvalidArgumentException($e->getMessage(), $e->getCode(), $e);
        }
        $ok = true;

        foreach ($items as $key => $item) {
            if ($valuesIsArray) {
                $item->set($values[$key]);
            }
            if (null !== $ttl) {
                $item->expiresAfter($ttl);
            }
            $ok = $this->pool->saveDeferred($item) && $ok;
        }

        return $this->pool->commit() && $ok;
    }

    /**
     * {@inheritdoc}
     *
     * @return bool
     */
    public function deleteMultiple($keys)
    {
        if ($keys instanceof \Traversable) {
            $keys = iterator_to_array($keys, false);
        } elseif (!\is_array($keys)) {
            throw new InvalidArgumentException(sprintf('Cache keys must be array or Traversable, "%s" given.', get_debug_type($keys)));
        }

        try {
            return $this->pool->deleteItems($keys);
        } catch (SimpleCacheException $e) {
            throw $e;
        } catch (Psr6CacheException $e) {
            throw new InvalidArgumentException($e->getMessage(), $e->getCode(), $e);
        }
    }

    /**
     * {@inheritdoc}
     *
     * @return bool
     */
    public function has($key)
    {
        try {
            return $this->pool->hasItem($key);
        } catch (SimpleCacheException $e) {
            throw $e;
        } catch (Psr6CacheException $e) {
            throw new InvalidArgumentException($e->getMessage(), $e->getCode(), $e);
        }
    }
}
PKϤ$Z���cache/DoctrineProvider.phpnu�[���<?php

/*
 * This file is part of the Symfony package.
 *
 * (c) Fabien Potencier <fabien@symfony.com>
 *
 * For the full copyright and license information, please view the LICENSE
 * file that was distributed with this source code.
 */

namespace Symfony\Component\Cache;

use Doctrine\Common\Cache\CacheProvider;
use Psr\Cache\CacheItemPoolInterface;
use Symfony\Contracts\Service\ResetInterface;

/**
 * @author Nicolas Grekas <p@tchwork.com>
 */
class DoctrineProvider extends CacheProvider implements PruneableInterface, ResettableInterface
{
    private $pool;

    public function __construct(CacheItemPoolInterface $pool)
    {
        $this->pool = $pool;
    }

    /**
     * {@inheritdoc}
     */
    public function prune()
    {
        return $this->pool instanceof PruneableInterface && $this->pool->prune();
    }

    /**
     * {@inheritdoc}
     */
    public function reset()
    {
        if ($this->pool instanceof ResetInterface) {
            $this->pool->reset();
        }
        $this->setNamespace($this->getNamespace());
    }

    /**
     * {@inheritdoc}
     */
    protected function doFetch($id)
    {
        $item = $this->pool->getItem(rawurlencode($id));

        return $item->isHit() ? $item->get() : false;
    }

    /**
     * {@inheritdoc}
     *
     * @return bool
     */
    protected function doContains($id)
    {
        return $this->pool->hasItem(rawurlencode($id));
    }

    /**
     * {@inheritdoc}
     *
     * @return bool
     */
    protected function doSave($id, $data, $lifeTime = 0)
    {
        $item = $this->pool->getItem(rawurlencode($id));

        if (0 < $lifeTime) {
            $item->expiresAfter($lifeTime);
        }

        return $this->pool->save($item->set($data));
    }

    /**
     * {@inheritdoc}
     *
     * @return bool
     */
    protected function doDelete($id)
    {
        return $this->pool->deleteItem(rawurlencode($id));
    }

    /**
     * {@inheritdoc}
     *
     * @return bool
     */
    protected function doFlush()
    {
        return $this->pool->clear();
    }

    /**
     * {@inheritdoc}
     *
     * @return array|null
     */
    protected function doGetStats()
    {
        return null;
    }
}
PKϤ$Z�����cache/LockRegistry.phpnu�[���<?php

/*
 * This file is part of the Symfony package.
 *
 * (c) Fabien Potencier <fabien@symfony.com>
 *
 * For the full copyright and license information, please view the LICENSE
 * file that was distributed with this source code.
 */

namespace Symfony\Component\Cache;

use Psr\Log\LoggerInterface;
use Symfony\Contracts\Cache\CacheInterface;
use Symfony\Contracts\Cache\ItemInterface;

/**
 * LockRegistry is used internally by existing adapters to protect against cache stampede.
 *
 * It does so by wrapping the computation of items in a pool of locks.
 * Foreach each apps, there can be at most 20 concurrent processes that
 * compute items at the same time and only one per cache-key.
 *
 * @author Nicolas Grekas <p@tchwork.com>
 */
final class LockRegistry
{
    private static $openedFiles = [];
    private static $lockedFiles = [];

    /**
     * The number of items in this list controls the max number of concurrent processes.
     */
    private static $files = [
        __DIR__.\DIRECTORY_SEPARATOR.'Adapter'.\DIRECTORY_SEPARATOR.'AbstractAdapter.php',
        __DIR__.\DIRECTORY_SEPARATOR.'Adapter'.\DIRECTORY_SEPARATOR.'AbstractTagAwareAdapter.php',
        __DIR__.\DIRECTORY_SEPARATOR.'Adapter'.\DIRECTORY_SEPARATOR.'AdapterInterface.php',
        __DIR__.\DIRECTORY_SEPARATOR.'Adapter'.\DIRECTORY_SEPARATOR.'ApcuAdapter.php',
        __DIR__.\DIRECTORY_SEPARATOR.'Adapter'.\DIRECTORY_SEPARATOR.'ArrayAdapter.php',
        __DIR__.\DIRECTORY_SEPARATOR.'Adapter'.\DIRECTORY_SEPARATOR.'ChainAdapter.php',
        __DIR__.\DIRECTORY_SEPARATOR.'Adapter'.\DIRECTORY_SEPARATOR.'CouchbaseBucketAdapter.php',
        __DIR__.\DIRECTORY_SEPARATOR.'Adapter'.\DIRECTORY_SEPARATOR.'DoctrineAdapter.php',
        __DIR__.\DIRECTORY_SEPARATOR.'Adapter'.\DIRECTORY_SEPARATOR.'FilesystemAdapter.php',
        __DIR__.\DIRECTORY_SEPARATOR.'Adapter'.\DIRECTORY_SEPARATOR.'FilesystemTagAwareAdapter.php',
        __DIR__.\DIRECTORY_SEPARATOR.'Adapter'.\DIRECTORY_SEPARATOR.'MemcachedAdapter.php',
        __DIR__.\DIRECTORY_SEPARATOR.'Adapter'.\DIRECTORY_SEPARATOR.'NullAdapter.php',
        __DIR__.\DIRECTORY_SEPARATOR.'Adapter'.\DIRECTORY_SEPARATOR.'PdoAdapter.php',
        __DIR__.\DIRECTORY_SEPARATOR.'Adapter'.\DIRECTORY_SEPARATOR.'PhpArrayAdapter.php',
        __DIR__.\DIRECTORY_SEPARATOR.'Adapter'.\DIRECTORY_SEPARATOR.'PhpFilesAdapter.php',
        __DIR__.\DIRECTORY_SEPARATOR.'Adapter'.\DIRECTORY_SEPARATOR.'ProxyAdapter.php',
        __DIR__.\DIRECTORY_SEPARATOR.'Adapter'.\DIRECTORY_SEPARATOR.'Psr16Adapter.php',
        __DIR__.\DIRECTORY_SEPARATOR.'Adapter'.\DIRECTORY_SEPARATOR.'RedisAdapter.php',
        __DIR__.\DIRECTORY_SEPARATOR.'Adapter'.\DIRECTORY_SEPARATOR.'RedisTagAwareAdapter.php',
        __DIR__.\DIRECTORY_SEPARATOR.'Adapter'.\DIRECTORY_SEPARATOR.'TagAwareAdapter.php',
        __DIR__.\DIRECTORY_SEPARATOR.'Adapter'.\DIRECTORY_SEPARATOR.'TagAwareAdapterInterface.php',
        __DIR__.\DIRECTORY_SEPARATOR.'Adapter'.\DIRECTORY_SEPARATOR.'TraceableAdapter.php',
        __DIR__.\DIRECTORY_SEPARATOR.'Adapter'.\DIRECTORY_SEPARATOR.'TraceableTagAwareAdapter.php',
    ];

    /**
     * Defines a set of existing files that will be used as keys to acquire locks.
     *
     * @return array The previously defined set of files
     */
    public static function setFiles(array $files): array
    {
        $previousFiles = self::$files;
        self::$files = $files;

        foreach (self::$openedFiles as $file) {
            if ($file) {
                flock($file, \LOCK_UN);
                fclose($file);
            }
        }
        self::$openedFiles = self::$lockedFiles = [];

        return $previousFiles;
    }

    public static function compute(callable $callback, ItemInterface $item, bool &$save, CacheInterface $pool, \Closure $setMetadata = null, LoggerInterface $logger = null)
    {
        $key = self::$files ? crc32($item->getKey()) % \count(self::$files) : -1;

        if ($key < 0 || (self::$lockedFiles[$key] ?? false) || !$lock = self::open($key)) {
            return $callback($item, $save);
        }

        while (true) {
            try {
                // race to get the lock in non-blocking mode
                $locked = flock($lock, \LOCK_EX | \LOCK_NB, $wouldBlock);

                if ($locked || !$wouldBlock) {
                    $logger && $logger->info(sprintf('Lock %s, now computing item "{key}"', $locked ? 'acquired' : 'not supported'), ['key' => $item->getKey()]);
                    self::$lockedFiles[$key] = true;

                    $value = $callback($item, $save);

                    if ($save) {
                        if ($setMetadata) {
                            $setMetadata($item);
                        }

                        $pool->save($item->set($value));
                        $save = false;
                    }

                    return $value;
                }
                // if we failed the race, retry locking in blocking mode to wait for the winner
                $logger && $logger->info('Item "{key}" is locked, waiting for it to be released', ['key' => $item->getKey()]);
                flock($lock, \LOCK_SH);
            } finally {
                flock($lock, \LOCK_UN);
                unset(self::$lockedFiles[$key]);
            }
            static $signalingException, $signalingCallback;
            $signalingException = $signalingException ?? unserialize("O:9:\"Exception\":1:{s:16:\"\0Exception\0trace\";a:0:{}}");
            $signalingCallback = $signalingCallback ?? function () use ($signalingException) { throw $signalingException; };

            try {
                $value = $pool->get($item->getKey(), $signalingCallback, 0);
                $logger && $logger->info('Item "{key}" retrieved after lock was released', ['key' => $item->getKey()]);
                $save = false;

                return $value;
            } catch (\Exception $e) {
                if ($signalingException !== $e) {
                    throw $e;
                }
                $logger && $logger->info('Item "{key}" not found while lock was released, now retrying', ['key' => $item->getKey()]);
            }
        }

        return null;
    }

    private static function open(int $key)
    {
        if (null !== $h = self::$openedFiles[$key] ?? null) {
            return $h;
        }
        set_error_handler(function () {});
        try {
            $h = fopen(self::$files[$key], 'r+');
        } finally {
            restore_error_handler();
        }

        return self::$openedFiles[$key] = $h ?: @fopen(self::$files[$key], 'r');
    }
}
PKϤ$Z͔#��0cache/DependencyInjection/CacheCollectorPass.phpnu�[���<?php

/*
 * This file is part of the Symfony package.
 *
 * (c) Fabien Potencier <fabien@symfony.com>
 *
 * For the full copyright and license information, please view the LICENSE
 * file that was distributed with this source code.
 */

namespace Symfony\Component\Cache\DependencyInjection;

use Symfony\Component\Cache\Adapter\TagAwareAdapterInterface;
use Symfony\Component\Cache\Adapter\TraceableAdapter;
use Symfony\Component\Cache\Adapter\TraceableTagAwareAdapter;
use Symfony\Component\DependencyInjection\Compiler\CompilerPassInterface;
use Symfony\Component\DependencyInjection\ContainerBuilder;
use Symfony\Component\DependencyInjection\Definition;
use Symfony\Component\DependencyInjection\Reference;

/**
 * Inject a data collector to all the cache services to be able to get detailed statistics.
 *
 * @author Tobias Nyholm <tobias.nyholm@gmail.com>
 */
class CacheCollectorPass implements CompilerPassInterface
{
    private $dataCollectorCacheId;
    private $cachePoolTag;
    private $cachePoolRecorderInnerSuffix;

    public function __construct(string $dataCollectorCacheId = 'data_collector.cache', string $cachePoolTag = 'cache.pool', string $cachePoolRecorderInnerSuffix = '.recorder_inner')
    {
        $this->dataCollectorCacheId = $dataCollectorCacheId;
        $this->cachePoolTag = $cachePoolTag;
        $this->cachePoolRecorderInnerSuffix = $cachePoolRecorderInnerSuffix;
    }

    /**
     * {@inheritdoc}
     */
    public function process(ContainerBuilder $container)
    {
        if (!$container->hasDefinition($this->dataCollectorCacheId)) {
            return;
        }

        foreach ($container->findTaggedServiceIds($this->cachePoolTag) as $id => $attributes) {
            $poolName = $attributes[0]['name'] ?? $id;

            $this->addToCollector($id, $poolName, $container);
        }
    }

    private function addToCollector(string $id, string $name, ContainerBuilder $container)
    {
        $definition = $container->getDefinition($id);
        if ($definition->isAbstract()) {
            return;
        }

        $collectorDefinition = $container->getDefinition($this->dataCollectorCacheId);
        $recorder = new Definition(is_subclass_of($definition->getClass(), TagAwareAdapterInterface::class) ? TraceableTagAwareAdapter::class : TraceableAdapter::class);
        $recorder->setTags($definition->getTags());
        if (!$definition->isPublic() || !$definition->isPrivate()) {
            $recorder->setPublic($definition->isPublic());
        }
        $recorder->setArguments([new Reference($innerId = $id.$this->cachePoolRecorderInnerSuffix)]);

        $definition->setTags([]);
        $definition->setPublic(false);

        $container->setDefinition($innerId, $definition);
        $container->setDefinition($id, $recorder);

        // Tell the collector to add the new instance
        $collectorDefinition->addMethodCall('addInstance', [$name, new Reference($id)]);
        $collectorDefinition->setPublic(false);
    }
}
PKϤ$Z/̶�$$+cache/DependencyInjection/CachePoolPass.phpnu�[���<?php

/*
 * This file is part of the Symfony package.
 *
 * (c) Fabien Potencier <fabien@symfony.com>
 *
 * For the full copyright and license information, please view the LICENSE
 * file that was distributed with this source code.
 */

namespace Symfony\Component\Cache\DependencyInjection;

use Symfony\Component\Cache\Adapter\AbstractAdapter;
use Symfony\Component\Cache\Adapter\ArrayAdapter;
use Symfony\Component\Cache\Adapter\ChainAdapter;
use Symfony\Component\DependencyInjection\ChildDefinition;
use Symfony\Component\DependencyInjection\Compiler\CompilerPassInterface;
use Symfony\Component\DependencyInjection\ContainerBuilder;
use Symfony\Component\DependencyInjection\Definition;
use Symfony\Component\DependencyInjection\Exception\InvalidArgumentException;
use Symfony\Component\DependencyInjection\Reference;

/**
 * @author Nicolas Grekas <p@tchwork.com>
 */
class CachePoolPass implements CompilerPassInterface
{
    private $cachePoolTag;
    private $kernelResetTag;
    private $cacheClearerId;
    private $cachePoolClearerTag;
    private $cacheSystemClearerId;
    private $cacheSystemClearerTag;

    public function __construct(string $cachePoolTag = 'cache.pool', string $kernelResetTag = 'kernel.reset', string $cacheClearerId = 'cache.global_clearer', string $cachePoolClearerTag = 'cache.pool.clearer', string $cacheSystemClearerId = 'cache.system_clearer', string $cacheSystemClearerTag = 'kernel.cache_clearer')
    {
        $this->cachePoolTag = $cachePoolTag;
        $this->kernelResetTag = $kernelResetTag;
        $this->cacheClearerId = $cacheClearerId;
        $this->cachePoolClearerTag = $cachePoolClearerTag;
        $this->cacheSystemClearerId = $cacheSystemClearerId;
        $this->cacheSystemClearerTag = $cacheSystemClearerTag;
    }

    /**
     * {@inheritdoc}
     */
    public function process(ContainerBuilder $container)
    {
        if ($container->hasParameter('cache.prefix.seed')) {
            $seed = '.'.$container->getParameterBag()->resolveValue($container->getParameter('cache.prefix.seed'));
        } else {
            $seed = '_'.$container->getParameter('kernel.project_dir');
        }
        $seed .= '.'.$container->getParameter('kernel.container_class');

        $allPools = [];
        $clearers = [];
        $attributes = [
            'provider',
            'name',
            'namespace',
            'default_lifetime',
            'reset',
        ];
        foreach ($container->findTaggedServiceIds($this->cachePoolTag) as $id => $tags) {
            $adapter = $pool = $container->getDefinition($id);
            if ($pool->isAbstract()) {
                continue;
            }
            $class = $adapter->getClass();
            while ($adapter instanceof ChildDefinition) {
                $adapter = $container->findDefinition($adapter->getParent());
                $class = $class ?: $adapter->getClass();
                if ($t = $adapter->getTag($this->cachePoolTag)) {
                    $tags[0] += $t[0];
                }
            }
            $name = $tags[0]['name'] ?? $id;
            if (!isset($tags[0]['namespace'])) {
                $namespaceSeed = $seed;
                if (null !== $class) {
                    $namespaceSeed .= '.'.$class;
                }

                $tags[0]['namespace'] = $this->getNamespace($namespaceSeed, $name);
            }
            if (isset($tags[0]['clearer'])) {
                $clearer = $tags[0]['clearer'];
                while ($container->hasAlias($clearer)) {
                    $clearer = (string) $container->getAlias($clearer);
                }
            } else {
                $clearer = null;
            }
            unset($tags[0]['clearer'], $tags[0]['name']);

            if (isset($tags[0]['provider'])) {
                $tags[0]['provider'] = new Reference(static::getServiceProvider($container, $tags[0]['provider']));
            }

            if (ChainAdapter::class === $class) {
                $adapters = [];
                foreach ($adapter->getArgument(0) as $provider => $adapter) {
                    if ($adapter instanceof ChildDefinition) {
                        $chainedPool = $adapter;
                    } else {
                        $chainedPool = $adapter = new ChildDefinition($adapter);
                    }

                    $chainedTags = [\is_int($provider) ? [] : ['provider' => $provider]];
                    $chainedClass = '';

                    while ($adapter instanceof ChildDefinition) {
                        $adapter = $container->findDefinition($adapter->getParent());
                        $chainedClass = $chainedClass ?: $adapter->getClass();
                        if ($t = $adapter->getTag($this->cachePoolTag)) {
                            $chainedTags[0] += $t[0];
                        }
                    }

                    if (ChainAdapter::class === $chainedClass) {
                        throw new InvalidArgumentException(sprintf('Invalid service "%s": chain of adapters cannot reference another chain, found "%s".', $id, $chainedPool->getParent()));
                    }

                    $i = 0;

                    if (isset($chainedTags[0]['provider'])) {
                        $chainedPool->replaceArgument($i++, new Reference(static::getServiceProvider($container, $chainedTags[0]['provider'])));
                    }

                    if (isset($tags[0]['namespace']) && ArrayAdapter::class !== $adapter->getClass()) {
                        $chainedPool->replaceArgument($i++, $tags[0]['namespace']);
                    }

                    if (isset($tags[0]['default_lifetime'])) {
                        $chainedPool->replaceArgument($i++, $tags[0]['default_lifetime']);
                    }

                    $adapters[] = $chainedPool;
                }

                $pool->replaceArgument(0, $adapters);
                unset($tags[0]['provider'], $tags[0]['namespace']);
                $i = 1;
            } else {
                $i = 0;
            }

            foreach ($attributes as $attr) {
                if (!isset($tags[0][$attr])) {
                    // no-op
                } elseif ('reset' === $attr) {
                    if ($tags[0][$attr]) {
                        $pool->addTag($this->kernelResetTag, ['method' => $tags[0][$attr]]);
                    }
                } elseif ('namespace' !== $attr || ArrayAdapter::class !== $class) {
                    $pool->replaceArgument($i++, $tags[0][$attr]);
                }
                unset($tags[0][$attr]);
            }
            if (!empty($tags[0])) {
                throw new InvalidArgumentException(sprintf('Invalid "%s" tag for service "%s": accepted attributes are "clearer", "provider", "name", "namespace", "default_lifetime" and "reset", found "%s".', $this->cachePoolTag, $id, implode('", "', array_keys($tags[0]))));
            }

            if (null !== $clearer) {
                $clearers[$clearer][$name] = new Reference($id, $container::IGNORE_ON_UNINITIALIZED_REFERENCE);
            }

            $allPools[$name] = new Reference($id, $container::IGNORE_ON_UNINITIALIZED_REFERENCE);
        }

        $notAliasedCacheClearerId = $this->cacheClearerId;
        while ($container->hasAlias($this->cacheClearerId)) {
            $this->cacheClearerId = (string) $container->getAlias($this->cacheClearerId);
        }
        if ($container->hasDefinition($this->cacheClearerId)) {
            $clearers[$notAliasedCacheClearerId] = $allPools;
        }

        foreach ($clearers as $id => $pools) {
            $clearer = $container->getDefinition($id);
            if ($clearer instanceof ChildDefinition) {
                $clearer->replaceArgument(0, $pools);
            } else {
                $clearer->setArgument(0, $pools);
            }
            $clearer->addTag($this->cachePoolClearerTag);

            if ($this->cacheSystemClearerId === $id) {
                $clearer->addTag($this->cacheSystemClearerTag);
            }
        }

        if ($container->hasDefinition('console.command.cache_pool_list')) {
            $container->getDefinition('console.command.cache_pool_list')->replaceArgument(0, array_keys($allPools));
        }
    }

    private function getNamespace(string $seed, string $id)
    {
        return substr(str_replace('/', '-', base64_encode(hash('sha256', $id.$seed, true))), 0, 10);
    }

    /**
     * @internal
     */
    public static function getServiceProvider(ContainerBuilder $container, $name)
    {
        $container->resolveEnvPlaceholders($name, null, $usedEnvs);

        if ($usedEnvs || preg_match('#^[a-z]++:#', $name)) {
            $dsn = $name;

            if (!$container->hasDefinition($name = '.cache_connection.'.ContainerBuilder::hash($dsn))) {
                $definition = new Definition(AbstractAdapter::class);
                $definition->setPublic(false);
                $definition->setFactory([AbstractAdapter::class, 'createConnection']);
                $definition->setArguments([$dsn, ['lazy' => true]]);
                $container->setDefinition($name, $definition);
            }
        }

        return $name;
    }
}
PKϤ$Zd"�e��1cache/DependencyInjection/CachePoolPrunerPass.phpnu�[���<?php

/*
 * This file is part of the Symfony package.
 *
 * (c) Fabien Potencier <fabien@symfony.com>
 *
 * For the full copyright and license information, please view the LICENSE
 * file that was distributed with this source code.
 */

namespace Symfony\Component\Cache\DependencyInjection;

use Symfony\Component\Cache\PruneableInterface;
use Symfony\Component\DependencyInjection\Argument\IteratorArgument;
use Symfony\Component\DependencyInjection\Compiler\CompilerPassInterface;
use Symfony\Component\DependencyInjection\ContainerBuilder;
use Symfony\Component\DependencyInjection\Exception\InvalidArgumentException;
use Symfony\Component\DependencyInjection\Reference;

/**
 * @author Rob Frawley 2nd <rmf@src.run>
 */
class CachePoolPrunerPass implements CompilerPassInterface
{
    private $cacheCommandServiceId;
    private $cachePoolTag;

    public function __construct(string $cacheCommandServiceId = 'console.command.cache_pool_prune', string $cachePoolTag = 'cache.pool')
    {
        $this->cacheCommandServiceId = $cacheCommandServiceId;
        $this->cachePoolTag = $cachePoolTag;
    }

    /**
     * {@inheritdoc}
     */
    public function process(ContainerBuilder $container)
    {
        if (!$container->hasDefinition($this->cacheCommandServiceId)) {
            return;
        }

        $services = [];

        foreach ($container->findTaggedServiceIds($this->cachePoolTag) as $id => $tags) {
            $class = $container->getParameterBag()->resolveValue($container->getDefinition($id)->getClass());

            if (!$reflection = $container->getReflectionClass($class)) {
                throw new InvalidArgumentException(sprintf('Class "%s" used for service "%s" cannot be found.', $class, $id));
            }

            if ($reflection->implementsInterface(PruneableInterface::class)) {
                $services[$id] = new Reference($id);
            }
        }

        $container->getDefinition($this->cacheCommandServiceId)->replaceArgument(0, new IteratorArgument($services));
    }
}
PKϤ$Z1���2cache/DependencyInjection/CachePoolClearerPass.phpnu�[���<?php

/*
 * This file is part of the Symfony package.
 *
 * (c) Fabien Potencier <fabien@symfony.com>
 *
 * For the full copyright and license information, please view the LICENSE
 * file that was distributed with this source code.
 */

namespace Symfony\Component\Cache\DependencyInjection;

use Symfony\Component\DependencyInjection\Compiler\CompilerPassInterface;
use Symfony\Component\DependencyInjection\ContainerBuilder;
use Symfony\Component\DependencyInjection\Reference;

/**
 * @author Nicolas Grekas <p@tchwork.com>
 */
class CachePoolClearerPass implements CompilerPassInterface
{
    private $cachePoolClearerTag;

    public function __construct(string $cachePoolClearerTag = 'cache.pool.clearer')
    {
        $this->cachePoolClearerTag = $cachePoolClearerTag;
    }

    /**
     * {@inheritdoc}
     */
    public function process(ContainerBuilder $container)
    {
        $container->getParameterBag()->remove('cache.prefix.seed');

        foreach ($container->findTaggedServiceIds($this->cachePoolClearerTag) as $id => $attr) {
            $clearer = $container->getDefinition($id);
            $pools = [];
            foreach ($clearer->getArgument(0) as $name => $ref) {
                if ($container->hasDefinition($ref)) {
                    $pools[$name] = new Reference($ref);
                }
            }
            $clearer->replaceArgument(0, $pools);
        }
    }
}
PKϤ$Z��H���"cache/Exception/LogicException.phpnu�[���<?php

/*
 * This file is part of the Symfony package.
 *
 * (c) Fabien Potencier <fabien@symfony.com>
 *
 * For the full copyright and license information, please view the LICENSE
 * file that was distributed with this source code.
 */

namespace Symfony\Component\Cache\Exception;

use Psr\Cache\CacheException as Psr6CacheInterface;
use Psr\SimpleCache\CacheException as SimpleCacheInterface;

if (interface_exists(SimpleCacheInterface::class)) {
    class LogicException extends \LogicException implements Psr6CacheInterface, SimpleCacheInterface
    {
    }
} else {
    class LogicException extends \LogicException implements Psr6CacheInterface
    {
    }
}
PKϤ$Z#���,cache/Exception/InvalidArgumentException.phpnu�[���<?php

/*
 * This file is part of the Symfony package.
 *
 * (c) Fabien Potencier <fabien@symfony.com>
 *
 * For the full copyright and license information, please view the LICENSE
 * file that was distributed with this source code.
 */

namespace Symfony\Component\Cache\Exception;

use Psr\Cache\InvalidArgumentException as Psr6CacheInterface;
use Psr\SimpleCache\InvalidArgumentException as SimpleCacheInterface;

if (interface_exists(SimpleCacheInterface::class)) {
    class InvalidArgumentException extends \InvalidArgumentException implements Psr6CacheInterface, SimpleCacheInterface
    {
    }
} else {
    class InvalidArgumentException extends \InvalidArgumentException implements Psr6CacheInterface
    {
    }
}
PKϤ$Z򹃏�"cache/Exception/CacheException.phpnu�[���<?php

/*
 * This file is part of the Symfony package.
 *
 * (c) Fabien Potencier <fabien@symfony.com>
 *
 * For the full copyright and license information, please view the LICENSE
 * file that was distributed with this source code.
 */

namespace Symfony\Component\Cache\Exception;

use Psr\Cache\CacheException as Psr6CacheInterface;
use Psr\SimpleCache\CacheException as SimpleCacheInterface;

if (interface_exists(SimpleCacheInterface::class)) {
    class CacheException extends \Exception implements Psr6CacheInterface, SimpleCacheInterface
    {
    }
} else {
    class CacheException extends \Exception implements Psr6CacheInterface
    {
    }
}
PKϤ$Zc� o��cache/CHANGELOG.mdnu�[���CHANGELOG
=========

5.1.0
-----

 * added max-items + LRU + max-lifetime capabilities to `ArrayCache`
 * added `CouchbaseBucketAdapter`
 * added context `cache-adapter` to log messages

5.0.0
-----

 * removed all PSR-16 implementations in the `Simple` namespace
 * removed `SimpleCacheAdapter`
 * removed `AbstractAdapter::unserialize()`
 * removed `CacheItem::getPreviousTags()`

4.4.0
-----

 * added support for connecting to Redis Sentinel clusters
 * added argument `$prefix` to `AdapterInterface::clear()`
 * improved `RedisTagAwareAdapter` to support Redis server >= 2.8 and up to 4B items per tag
 * added `TagAwareMarshaller` for optimized data storage when using `AbstractTagAwareAdapter`
 * added `DeflateMarshaller` to compress serialized values
 * removed support for phpredis 4 `compression`
 * [BC BREAK] `RedisTagAwareAdapter` is not compatible with `RedisCluster` from `Predis` anymore, use `phpredis` instead
 * Marked the `CacheDataCollector` class as `@final`.
 * added `SodiumMarshaller` to encrypt/decrypt values using libsodium

4.3.0
-----

 * removed `psr/simple-cache` dependency, run `composer require psr/simple-cache` if you need it
 * deprecated all PSR-16 adapters, use `Psr16Cache` or `Symfony\Contracts\Cache\CacheInterface` implementations instead
 * deprecated `SimpleCacheAdapter`, use `Psr16Adapter` instead

4.2.0
-----

 * added support for connecting to Redis clusters via DSN
 * added support for configuring multiple Memcached servers via DSN
 * added `MarshallerInterface` and `DefaultMarshaller` to allow changing the serializer and provide one that automatically uses igbinary when available
 * implemented `CacheInterface`, which provides stampede protection via probabilistic early expiration and should become the preferred way to use a cache
 * added sub-second expiry accuracy for backends that support it
 * added support for phpredis 4 `compression` and `tcp_keepalive` options
 * added automatic table creation when using Doctrine DBAL with PDO-based backends
 * throw `LogicException` when `CacheItem::tag()` is called on an item coming from a non tag-aware pool
 * deprecated `CacheItem::getPreviousTags()`, use `CacheItem::getMetadata()` instead
 * deprecated the `AbstractAdapter::unserialize()` and `AbstractCache::unserialize()` methods
 * added `CacheCollectorPass` (originally in `FrameworkBundle`)
 * added `CachePoolClearerPass` (originally in `FrameworkBundle`)
 * added `CachePoolPass` (originally in `FrameworkBundle`)
 * added `CachePoolPrunerPass` (originally in `FrameworkBundle`)

3.4.0
-----

 * added using options from Memcached DSN
 * added PruneableInterface so PSR-6 or PSR-16 cache implementations can declare support for manual stale cache pruning
 * added prune logic to FilesystemTrait, PhpFilesTrait, PdoTrait, TagAwareAdapter and ChainTrait
 * now FilesystemAdapter, PhpFilesAdapter, FilesystemCache, PhpFilesCache, PdoAdapter, PdoCache, ChainAdapter, and
   ChainCache implement PruneableInterface and support manual stale cache pruning

3.3.0
-----

 * added CacheItem::getPreviousTags() to get bound tags coming from the pool storage if any
 * added PSR-16 "Simple Cache" implementations for all existing PSR-6 adapters
 * added Psr6Cache and SimpleCacheAdapter for bidirectional interoperability between PSR-6 and PSR-16
 * added MemcachedAdapter (PSR-6) and MemcachedCache (PSR-16)
 * added TraceableAdapter (PSR-6) and TraceableCache (PSR-16)

3.2.0
-----

 * added TagAwareAdapter for tags-based invalidation
 * added PdoAdapter with PDO and Doctrine DBAL support
 * added PhpArrayAdapter and PhpFilesAdapter for OPcache-backed shared memory storage (PHP 7+ only)
 * added NullAdapter

3.1.0
-----

 * added the component with strict PSR-6 implementations
 * added ApcuAdapter, ArrayAdapter, FilesystemAdapter and RedisAdapter
 * added AbstractAdapter, ChainAdapter and ProxyAdapter
 * added DoctrineAdapter and DoctrineProvider for bidirectional interoperability with Doctrine Cache
PKϤ$Zt"?))
cache/LICENSEnu�[���Copyright (c) 2016-2021 Fabien Potencier

Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is furnished
to do so, subject to the following conditions:

The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.

THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
THE SOFTWARE.
PKϤ$Z��)33&cache/Traits/FilesystemCommonTrait.phpnu�[���<?php

/*
 * This file is part of the Symfony package.
 *
 * (c) Fabien Potencier <fabien@symfony.com>
 *
 * For the full copyright and license information, please view the LICENSE
 * file that was distributed with this source code.
 */

namespace Symfony\Component\Cache\Traits;

use Symfony\Component\Cache\Exception\InvalidArgumentException;

/**
 * @author Nicolas Grekas <p@tchwork.com>
 *
 * @internal
 */
trait FilesystemCommonTrait
{
    private $directory;
    private $tmp;

    private function init(string $namespace, ?string $directory)
    {
        if (!isset($directory[0])) {
            $directory = sys_get_temp_dir().\DIRECTORY_SEPARATOR.'symfony-cache';
        } else {
            $directory = realpath($directory) ?: $directory;
        }
        if (isset($namespace[0])) {
            if (preg_match('#[^-+_.A-Za-z0-9]#', $namespace, $match)) {
                throw new InvalidArgumentException(sprintf('Namespace contains "%s" but only characters in [-+_.A-Za-z0-9] are allowed.', $match[0]));
            }
            $directory .= \DIRECTORY_SEPARATOR.$namespace;
        } else {
            $directory .= \DIRECTORY_SEPARATOR.'@';
        }
        if (!is_dir($directory)) {
            @mkdir($directory, 0777, true);
        }
        $directory .= \DIRECTORY_SEPARATOR;
        // On Windows the whole path is limited to 258 chars
        if ('\\' === \DIRECTORY_SEPARATOR && \strlen($directory) > 234) {
            throw new InvalidArgumentException(sprintf('Cache directory too long (%s).', $directory));
        }

        $this->directory = $directory;
    }

    /**
     * {@inheritdoc}
     */
    protected function doClear(string $namespace)
    {
        $ok = true;

        foreach ($this->scanHashDir($this->directory) as $file) {
            if ('' !== $namespace && 0 !== strpos($this->getFileKey($file), $namespace)) {
                continue;
            }

            $ok = ($this->doUnlink($file) || !file_exists($file)) && $ok;
        }

        return $ok;
    }

    /**
     * {@inheritdoc}
     */
    protected function doDelete(array $ids)
    {
        $ok = true;

        foreach ($ids as $id) {
            $file = $this->getFile($id);
            $ok = (!is_file($file) || $this->doUnlink($file) || !file_exists($file)) && $ok;
        }

        return $ok;
    }

    protected function doUnlink($file)
    {
        return @unlink($file);
    }

    private function write(string $file, string $data, int $expiresAt = null)
    {
        set_error_handler(__CLASS__.'::throwError');
        try {
            if (null === $this->tmp) {
                $this->tmp = $this->directory.bin2hex(random_bytes(6));
            }
            try {
                $h = fopen($this->tmp, 'x');
            } catch (\ErrorException $e) {
                if (false === strpos($e->getMessage(), 'File exists')) {
                    throw $e;
                }

                $this->tmp = $this->directory.bin2hex(random_bytes(6));
                $h = fopen($this->tmp, 'x');
            }
            fwrite($h, $data);
            fclose($h);

            if (null !== $expiresAt) {
                touch($this->tmp, $expiresAt);
            }

            return rename($this->tmp, $file);
        } finally {
            restore_error_handler();
        }
    }

    private function getFile(string $id, bool $mkdir = false, string $directory = null)
    {
        // Use MD5 to favor speed over security, which is not an issue here
        $hash = str_replace('/', '-', base64_encode(hash('md5', static::class.$id, true)));
        $dir = ($directory ?? $this->directory).strtoupper($hash[0].\DIRECTORY_SEPARATOR.$hash[1].\DIRECTORY_SEPARATOR);

        if ($mkdir && !is_dir($dir)) {
            @mkdir($dir, 0777, true);
        }

        return $dir.substr($hash, 2, 20);
    }

    private function getFileKey(string $file): string
    {
        return '';
    }

    private function scanHashDir(string $directory): \Generator
    {
        if (!is_dir($directory)) {
            return;
        }

        $chars = '+-ABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789';

        for ($i = 0; $i < 38; ++$i) {
            if (!is_dir($directory.$chars[$i])) {
                continue;
            }

            for ($j = 0; $j < 38; ++$j) {
                if (!is_dir($dir = $directory.$chars[$i].\DIRECTORY_SEPARATOR.$chars[$j])) {
                    continue;
                }

                foreach (@scandir($dir, \SCANDIR_SORT_NONE) ?: [] as $file) {
                    if ('.' !== $file && '..' !== $file) {
                        yield $dir.\DIRECTORY_SEPARATOR.$file;
                    }
                }
            }
        }
    }

    /**
     * @internal
     */
    public static function throwError($type, $message, $file, $line)
    {
        throw new \ErrorException($message, 0, $type, $file, $line);
    }

    /**
     * @return array
     */
    public function __sleep()
    {
        throw new \BadMethodCallException('Cannot serialize '.__CLASS__);
    }

    public function __wakeup()
    {
        throw new \BadMethodCallException('Cannot unserialize '.__CLASS__);
    }

    public function __destruct()
    {
        if (method_exists(parent::class, '__destruct')) {
            parent::__destruct();
        }
        if (null !== $this->tmp && is_file($this->tmp)) {
            unlink($this->tmp);
        }
    }
}
PKϤ$Z�\e..%cache/Traits/AbstractAdapterTrait.phpnu�[���<?php

/*
 * This file is part of the Symfony package.
 *
 * (c) Fabien Potencier <fabien@symfony.com>
 *
 * For the full copyright and license information, please view the LICENSE
 * file that was distributed with this source code.
 */

namespace Symfony\Component\Cache\Traits;

use Psr\Cache\CacheItemInterface;
use Psr\Log\LoggerAwareTrait;
use Symfony\Component\Cache\CacheItem;
use Symfony\Component\Cache\Exception\InvalidArgumentException;

/**
 * @author Nicolas Grekas <p@tchwork.com>
 *
 * @internal
 */
trait AbstractAdapterTrait
{
    use LoggerAwareTrait;

    /**
     * @var \Closure needs to be set by class, signature is function(string <key>, mixed <value>, bool <isHit>)
     */
    private $createCacheItem;

    /**
     * @var \Closure needs to be set by class, signature is function(array <deferred>, string <namespace>, array <&expiredIds>)
     */
    private $mergeByLifetime;

    private $namespace;
    private $namespaceVersion = '';
    private $versioningIsEnabled = false;
    private $deferred = [];
    private $ids = [];

    /**
     * @var int|null The maximum length to enforce for identifiers or null when no limit applies
     */
    protected $maxIdLength;

    /**
     * Fetches several cache items.
     *
     * @param array $ids The cache identifiers to fetch
     *
     * @return array|\Traversable The corresponding values found in the cache
     */
    abstract protected function doFetch(array $ids);

    /**
     * Confirms if the cache contains specified cache item.
     *
     * @param string $id The identifier for which to check existence
     *
     * @return bool True if item exists in the cache, false otherwise
     */
    abstract protected function doHave(string $id);

    /**
     * Deletes all items in the pool.
     *
     * @param string $namespace The prefix used for all identifiers managed by this pool
     *
     * @return bool True if the pool was successfully cleared, false otherwise
     */
    abstract protected function doClear(string $namespace);

    /**
     * Removes multiple items from the pool.
     *
     * @param array $ids An array of identifiers that should be removed from the pool
     *
     * @return bool True if the items were successfully removed, false otherwise
     */
    abstract protected function doDelete(array $ids);

    /**
     * Persists several cache items immediately.
     *
     * @param array $values   The values to cache, indexed by their cache identifier
     * @param int   $lifetime The lifetime of the cached values, 0 for persisting until manual cleaning
     *
     * @return array|bool The identifiers that failed to be cached or a boolean stating if caching succeeded or not
     */
    abstract protected function doSave(array $values, int $lifetime);

    /**
     * {@inheritdoc}
     *
     * @return bool
     */
    public function hasItem($key)
    {
        $id = $this->getId($key);

        if (isset($this->deferred[$key])) {
            $this->commit();
        }

        try {
            return $this->doHave($id);
        } catch (\Exception $e) {
            CacheItem::log($this->logger, 'Failed to check if key "{key}" is cached: '.$e->getMessage(), ['key' => $key, 'exception' => $e, 'cache-adapter' => get_debug_type($this)]);

            return false;
        }
    }

    /**
     * {@inheritdoc}
     *
     * @return bool
     */
    public function clear(string $prefix = '')
    {
        $this->deferred = [];
        if ($cleared = $this->versioningIsEnabled) {
            if ('' === $namespaceVersionToClear = $this->namespaceVersion) {
                foreach ($this->doFetch([static::NS_SEPARATOR.$this->namespace]) as $v) {
                    $namespaceVersionToClear = $v;
                }
            }
            $namespaceToClear = $this->namespace.$namespaceVersionToClear;
            $namespaceVersion = strtr(substr_replace(base64_encode(pack('V', mt_rand())), static::NS_SEPARATOR, 5), '/', '_');
            try {
                $cleared = $this->doSave([static::NS_SEPARATOR.$this->namespace => $namespaceVersion], 0);
            } catch (\Exception $e) {
                $cleared = false;
            }
            if ($cleared = true === $cleared || [] === $cleared) {
                $this->namespaceVersion = $namespaceVersion;
                $this->ids = [];
            }
        } else {
            $namespaceToClear = $this->namespace.$prefix;
        }

        try {
            return $this->doClear($namespaceToClear) || $cleared;
        } catch (\Exception $e) {
            CacheItem::log($this->logger, 'Failed to clear the cache: '.$e->getMessage(), ['exception' => $e, 'cache-adapter' => get_debug_type($this)]);

            return false;
        }
    }

    /**
     * {@inheritdoc}
     *
     * @return bool
     */
    public function deleteItem($key)
    {
        return $this->deleteItems([$key]);
    }

    /**
     * {@inheritdoc}
     *
     * @return bool
     */
    public function deleteItems(array $keys)
    {
        $ids = [];

        foreach ($keys as $key) {
            $ids[$key] = $this->getId($key);
            unset($this->deferred[$key]);
        }

        try {
            if ($this->doDelete($ids)) {
                return true;
            }
        } catch (\Exception $e) {
        }

        $ok = true;

        // When bulk-delete failed, retry each item individually
        foreach ($ids as $key => $id) {
            try {
                $e = null;
                if ($this->doDelete([$id])) {
                    continue;
                }
            } catch (\Exception $e) {
            }
            $message = 'Failed to delete key "{key}"'.($e instanceof \Exception ? ': '.$e->getMessage() : '.');
            CacheItem::log($this->logger, $message, ['key' => $key, 'exception' => $e, 'cache-adapter' => get_debug_type($this)]);
            $ok = false;
        }

        return $ok;
    }

    /**
     * {@inheritdoc}
     */
    public function getItem($key)
    {
        if ($this->deferred) {
            $this->commit();
        }
        $id = $this->getId($key);

        $f = $this->createCacheItem;
        $isHit = false;
        $value = null;

        try {
            foreach ($this->doFetch([$id]) as $value) {
                $isHit = true;
            }

            return $f($key, $value, $isHit);
        } catch (\Exception $e) {
            CacheItem::log($this->logger, 'Failed to fetch key "{key}": '.$e->getMessage(), ['key' => $key, 'exception' => $e, 'cache-adapter' => get_debug_type($this)]);
        }

        return $f($key, null, false);
    }

    /**
     * {@inheritdoc}
     */
    public function getItems(array $keys = [])
    {
        if ($this->deferred) {
            $this->commit();
        }
        $ids = [];

        foreach ($keys as $key) {
            $ids[] = $this->getId($key);
        }
        try {
            $items = $this->doFetch($ids);
        } catch (\Exception $e) {
            CacheItem::log($this->logger, 'Failed to fetch items: '.$e->getMessage(), ['keys' => $keys, 'exception' => $e, 'cache-adapter' => get_debug_type($this)]);
            $items = [];
        }
        $ids = array_combine($ids, $keys);

        return $this->generateItems($items, $ids);
    }

    /**
     * {@inheritdoc}
     *
     * @return bool
     */
    public function save(CacheItemInterface $item)
    {
        if (!$item instanceof CacheItem) {
            return false;
        }
        $this->deferred[$item->getKey()] = $item;

        return $this->commit();
    }

    /**
     * {@inheritdoc}
     *
     * @return bool
     */
    public function saveDeferred(CacheItemInterface $item)
    {
        if (!$item instanceof CacheItem) {
            return false;
        }
        $this->deferred[$item->getKey()] = $item;

        return true;
    }

    /**
     * Enables/disables versioning of items.
     *
     * When versioning is enabled, clearing the cache is atomic and doesn't require listing existing keys to proceed,
     * but old keys may need garbage collection and extra round-trips to the back-end are required.
     *
     * Calling this method also clears the memoized namespace version and thus forces a resynchonization of it.
     *
     * @param bool $enable
     *
     * @return bool the previous state of versioning
     */
    public function enableVersioning($enable = true)
    {
        $wasEnabled = $this->versioningIsEnabled;
        $this->versioningIsEnabled = (bool) $enable;
        $this->namespaceVersion = '';
        $this->ids = [];

        return $wasEnabled;
    }

    /**
     * {@inheritdoc}
     */
    public function reset()
    {
        if ($this->deferred) {
            $this->commit();
        }
        $this->namespaceVersion = '';
        $this->ids = [];
    }

    public function __sleep()
    {
        throw new \BadMethodCallException('Cannot serialize '.__CLASS__);
    }

    public function __wakeup()
    {
        throw new \BadMethodCallException('Cannot unserialize '.__CLASS__);
    }

    public function __destruct()
    {
        if ($this->deferred) {
            $this->commit();
        }
    }

    private function generateItems(iterable $items, array &$keys): iterable
    {
        $f = $this->createCacheItem;

        try {
            foreach ($items as $id => $value) {
                if (!isset($keys[$id])) {
                    throw new InvalidArgumentException(sprintf('Could not match value id "%s" to keys "%s".', $id, implode('", "', $keys)));
                }
                $key = $keys[$id];
                unset($keys[$id]);
                yield $key => $f($key, $value, true);
            }
        } catch (\Exception $e) {
            CacheItem::log($this->logger, 'Failed to fetch items: '.$e->getMessage(), ['keys' => array_values($keys), 'exception' => $e, 'cache-adapter' => get_debug_type($this)]);
        }

        foreach ($keys as $key) {
            yield $key => $f($key, null, false);
        }
    }

    private function getId($key)
    {
        if ($this->versioningIsEnabled && '' === $this->namespaceVersion) {
            $this->ids = [];
            $this->namespaceVersion = '1'.static::NS_SEPARATOR;
            try {
                foreach ($this->doFetch([static::NS_SEPARATOR.$this->namespace]) as $v) {
                    $this->namespaceVersion = $v;
                }
                if ('1'.static::NS_SEPARATOR === $this->namespaceVersion) {
                    $this->namespaceVersion = strtr(substr_replace(base64_encode(pack('V', time())), static::NS_SEPARATOR, 5), '/', '_');
                    $this->doSave([static::NS_SEPARATOR.$this->namespace => $this->namespaceVersion], 0);
                }
            } catch (\Exception $e) {
            }
        }

        if (\is_string($key) && isset($this->ids[$key])) {
            return $this->namespace.$this->namespaceVersion.$this->ids[$key];
        }
        CacheItem::validateKey($key);
        $this->ids[$key] = $key;

        if (null === $this->maxIdLength) {
            return $this->namespace.$this->namespaceVersion.$key;
        }
        if (\strlen($id = $this->namespace.$this->namespaceVersion.$key) > $this->maxIdLength) {
            // Use MD5 to favor speed over security, which is not an issue here
            $this->ids[$key] = $id = substr_replace(base64_encode(hash('md5', $key, true)), static::NS_SEPARATOR, -(\strlen($this->namespaceVersion) + 2));
            $id = $this->namespace.$this->namespaceVersion.$id;
        }

        return $id;
    }

    /**
     * @internal
     */
    public static function handleUnserializeCallback($class)
    {
        throw new \DomainException('Class not found: '.$class);
    }
}
PKϤ$Z��W|�2�2cache/Traits/MemcachedTrait.phpnu�[���<?php

/*
 * This file is part of the Symfony package.
 *
 * (c) Fabien Potencier <fabien@symfony.com>
 *
 * For the full copyright and license information, please view the LICENSE
 * file that was distributed with this source code.
 */

namespace Symfony\Component\Cache\Traits;

use Symfony\Component\Cache\Exception\CacheException;
use Symfony\Component\Cache\Exception\InvalidArgumentException;
use Symfony\Component\Cache\Marshaller\DefaultMarshaller;
use Symfony\Component\Cache\Marshaller\MarshallerInterface;

/**
 * @author Rob Frawley 2nd <rmf@src.run>
 * @author Nicolas Grekas <p@tchwork.com>
 *
 * @internal
 */
trait MemcachedTrait
{
    private static $defaultClientOptions = [
        'persistent_id' => null,
        'username' => null,
        'password' => null,
        \Memcached::OPT_SERIALIZER => \Memcached::SERIALIZER_PHP,
    ];

    /**
     * We are replacing characters that are illegal in Memcached keys with reserved characters from
     * {@see \Symfony\Contracts\Cache\ItemInterface::RESERVED_CHARACTERS} that are legal in Memcached.
     * Note: don’t use {@see \Symfony\Component\Cache\Adapter\AbstractAdapter::NS_SEPARATOR}.
     */
    private static $RESERVED_MEMCACHED = " \n\r\t\v\f\0";
    private static $RESERVED_PSR6 = '@()\{}/';

    private $marshaller;
    private $client;
    private $lazyClient;

    public static function isSupported()
    {
        return \extension_loaded('memcached') && version_compare(phpversion('memcached'), '2.2.0', '>=');
    }

    private function init(\Memcached $client, string $namespace, int $defaultLifetime, ?MarshallerInterface $marshaller)
    {
        if (!static::isSupported()) {
            throw new CacheException('Memcached >= 2.2.0 is required.');
        }
        if ('Memcached' === \get_class($client)) {
            $opt = $client->getOption(\Memcached::OPT_SERIALIZER);
            if (\Memcached::SERIALIZER_PHP !== $opt && \Memcached::SERIALIZER_IGBINARY !== $opt) {
                throw new CacheException('MemcachedAdapter: "serializer" option must be "php" or "igbinary".');
            }
            $this->maxIdLength -= \strlen($client->getOption(\Memcached::OPT_PREFIX_KEY));
            $this->client = $client;
        } else {
            $this->lazyClient = $client;
        }

        parent::__construct($namespace, $defaultLifetime);
        $this->enableVersioning();
        $this->marshaller = $marshaller ?? new DefaultMarshaller();
    }

    /**
     * Creates a Memcached instance.
     *
     * By default, the binary protocol, no block, and libketama compatible options are enabled.
     *
     * Examples for servers:
     * - 'memcached://user:pass@localhost?weight=33'
     * - [['localhost', 11211, 33]]
     *
     * @param array[]|string|string[] $servers An array of servers, a DSN, or an array of DSNs
     *
     * @return \Memcached
     *
     * @throws \ErrorException When invalid options or servers are provided
     */
    public static function createConnection($servers, array $options = [])
    {
        if (\is_string($servers)) {
            $servers = [$servers];
        } elseif (!\is_array($servers)) {
            throw new InvalidArgumentException(sprintf('MemcachedAdapter::createClient() expects array or string as first argument, "%s" given.', \gettype($servers)));
        }
        if (!static::isSupported()) {
            throw new CacheException('Memcached >= 2.2.0 is required.');
        }
        set_error_handler(function ($type, $msg, $file, $line) { throw new \ErrorException($msg, 0, $type, $file, $line); });
        try {
            $options += static::$defaultClientOptions;
            $client = new \Memcached($options['persistent_id']);
            $username = $options['username'];
            $password = $options['password'];

            // parse any DSN in $servers
            foreach ($servers as $i => $dsn) {
                if (\is_array($dsn)) {
                    continue;
                }
                if (0 !== strpos($dsn, 'memcached:')) {
                    throw new InvalidArgumentException(sprintf('Invalid Memcached DSN: "%s" does not start with "memcached:".', $dsn));
                }
                $params = preg_replace_callback('#^memcached:(//)?(?:([^@]*+)@)?#', function ($m) use (&$username, &$password) {
                    if (!empty($m[2])) {
                        [$username, $password] = explode(':', $m[2], 2) + [1 => null];
                    }

                    return 'file:'.($m[1] ?? '');
                }, $dsn);
                if (false === $params = parse_url($params)) {
                    throw new InvalidArgumentException(sprintf('Invalid Memcached DSN: "%s".', $dsn));
                }
                $query = $hosts = [];
                if (isset($params['query'])) {
                    parse_str($params['query'], $query);

                    if (isset($query['host'])) {
                        if (!\is_array($hosts = $query['host'])) {
                            throw new InvalidArgumentException(sprintf('Invalid Memcached DSN: "%s".', $dsn));
                        }
                        foreach ($hosts as $host => $weight) {
                            if (false === $port = strrpos($host, ':')) {
                                $hosts[$host] = [$host, 11211, (int) $weight];
                            } else {
                                $hosts[$host] = [substr($host, 0, $port), (int) substr($host, 1 + $port), (int) $weight];
                            }
                        }
                        $hosts = array_values($hosts);
                        unset($query['host']);
                    }
                    if ($hosts && !isset($params['host']) && !isset($params['path'])) {
                        unset($servers[$i]);
                        $servers = array_merge($servers, $hosts);
                        continue;
                    }
                }
                if (!isset($params['host']) && !isset($params['path'])) {
                    throw new InvalidArgumentException(sprintf('Invalid Memcached DSN: "%s".', $dsn));
                }
                if (isset($params['path']) && preg_match('#/(\d+)$#', $params['path'], $m)) {
                    $params['weight'] = $m[1];
                    $params['path'] = substr($params['path'], 0, -\strlen($m[0]));
                }
                $params += [
                    'host' => $params['host'] ?? $params['path'],
                    'port' => isset($params['host']) ? 11211 : null,
                    'weight' => 0,
                ];
                if ($query) {
                    $params += $query;
                    $options = $query + $options;
                }

                $servers[$i] = [$params['host'], $params['port'], $params['weight']];

                if ($hosts) {
                    $servers = array_merge($servers, $hosts);
                }
            }

            // set client's options
            unset($options['persistent_id'], $options['username'], $options['password'], $options['weight'], $options['lazy']);
            $options = array_change_key_case($options, \CASE_UPPER);
            $client->setOption(\Memcached::OPT_BINARY_PROTOCOL, true);
            $client->setOption(\Memcached::OPT_NO_BLOCK, true);
            $client->setOption(\Memcached::OPT_TCP_NODELAY, true);
            if (!\array_key_exists('LIBKETAMA_COMPATIBLE', $options) && !\array_key_exists(\Memcached::OPT_LIBKETAMA_COMPATIBLE, $options)) {
                $client->setOption(\Memcached::OPT_LIBKETAMA_COMPATIBLE, true);
            }
            foreach ($options as $name => $value) {
                if (\is_int($name)) {
                    continue;
                }
                if ('HASH' === $name || 'SERIALIZER' === $name || 'DISTRIBUTION' === $name) {
                    $value = \constant('Memcached::'.$name.'_'.strtoupper($value));
                }
                $opt = \constant('Memcached::OPT_'.$name);

                unset($options[$name]);
                $options[$opt] = $value;
            }
            $client->setOptions($options);

            // set client's servers, taking care of persistent connections
            if (!$client->isPristine()) {
                $oldServers = [];
                foreach ($client->getServerList() as $server) {
                    $oldServers[] = [$server['host'], $server['port']];
                }

                $newServers = [];
                foreach ($servers as $server) {
                    if (1 < \count($server)) {
                        $server = array_values($server);
                        unset($server[2]);
                        $server[1] = (int) $server[1];
                    }
                    $newServers[] = $server;
                }

                if ($oldServers !== $newServers) {
                    $client->resetServerList();
                    $client->addServers($servers);
                }
            } else {
                $client->addServers($servers);
            }

            if (null !== $username || null !== $password) {
                if (!method_exists($client, 'setSaslAuthData')) {
                    trigger_error('Missing SASL support: the memcached extension must be compiled with --enable-memcached-sasl.');
                }
                $client->setSaslAuthData($username, $password);
            }

            return $client;
        } finally {
            restore_error_handler();
        }
    }

    /**
     * {@inheritdoc}
     */
    protected function doSave(array $values, int $lifetime)
    {
        if (!$values = $this->marshaller->marshall($values, $failed)) {
            return $failed;
        }

        if ($lifetime && $lifetime > 30 * 86400) {
            $lifetime += time();
        }

        $encodedValues = [];
        foreach ($values as $key => $value) {
            $encodedValues[self::encodeKey($key)] = $value;
        }

        return $this->checkResultCode($this->getClient()->setMulti($encodedValues, $lifetime)) ? $failed : false;
    }

    /**
     * {@inheritdoc}
     */
    protected function doFetch(array $ids)
    {
        try {
            $encodedIds = array_map('self::encodeKey', $ids);

            $encodedResult = $this->checkResultCode($this->getClient()->getMulti($encodedIds));

            $result = [];
            foreach ($encodedResult as $key => $value) {
                $result[self::decodeKey($key)] = $this->marshaller->unmarshall($value);
            }

            return $result;
        } catch (\Error $e) {
            throw new \ErrorException($e->getMessage(), $e->getCode(), \E_ERROR, $e->getFile(), $e->getLine());
        }
    }

    /**
     * {@inheritdoc}
     */
    protected function doHave($id)
    {
        return false !== $this->getClient()->get(self::encodeKey($id)) || $this->checkResultCode(\Memcached::RES_SUCCESS === $this->client->getResultCode());
    }

    /**
     * {@inheritdoc}
     */
    protected function doDelete(array $ids)
    {
        $ok = true;
        $encodedIds = array_map('self::encodeKey', $ids);
        foreach ($this->checkResultCode($this->getClient()->deleteMulti($encodedIds)) as $result) {
            if (\Memcached::RES_SUCCESS !== $result && \Memcached::RES_NOTFOUND !== $result) {
                $ok = false;
                break;
            }
        }

        return $ok;
    }

    /**
     * {@inheritdoc}
     */
    protected function doClear($namespace)
    {
        return '' === $namespace && $this->getClient()->flush();
    }

    private function checkResultCode($result)
    {
        $code = $this->client->getResultCode();

        if (\Memcached::RES_SUCCESS === $code || \Memcached::RES_NOTFOUND === $code) {
            return $result;
        }

        throw new CacheException('MemcachedAdapter client error: '.strtolower($this->client->getResultMessage()));
    }

    private function getClient(): \Memcached
    {
        if ($this->client) {
            return $this->client;
        }

        $opt = $this->lazyClient->getOption(\Memcached::OPT_SERIALIZER);
        if (\Memcached::SERIALIZER_PHP !== $opt && \Memcached::SERIALIZER_IGBINARY !== $opt) {
            throw new CacheException('MemcachedAdapter: "serializer" option must be "php" or "igbinary".');
        }
        if ('' !== $prefix = (string) $this->lazyClient->getOption(\Memcached::OPT_PREFIX_KEY)) {
            throw new CacheException(sprintf('MemcachedAdapter: "prefix_key" option must be empty when using proxified connections, "%s" given.', $prefix));
        }

        return $this->client = $this->lazyClient;
    }

    private static function encodeKey(string $key): string
    {
        return strtr($key, self::$RESERVED_MEMCACHED, self::$RESERVED_PSR6);
    }

    private static function decodeKey(string $key): string
    {
        return strtr($key, self::$RESERVED_PSR6, self::$RESERVED_MEMCACHED);
    }
}
PKϤ$Z�^�f�� cache/Traits/FilesystemTrait.phpnu�[���<?php

/*
 * This file is part of the Symfony package.
 *
 * (c) Fabien Potencier <fabien@symfony.com>
 *
 * For the full copyright and license information, please view the LICENSE
 * file that was distributed with this source code.
 */

namespace Symfony\Component\Cache\Traits;

use Symfony\Component\Cache\Exception\CacheException;

/**
 * @author Nicolas Grekas <p@tchwork.com>
 * @author Rob Frawley 2nd <rmf@src.run>
 *
 * @internal
 */
trait FilesystemTrait
{
    use FilesystemCommonTrait;

    private $marshaller;

    /**
     * @return bool
     */
    public function prune()
    {
        $time = time();
        $pruned = true;

        foreach ($this->scanHashDir($this->directory) as $file) {
            if (!$h = @fopen($file, 'r')) {
                continue;
            }

            if (($expiresAt = (int) fgets($h)) && $time >= $expiresAt) {
                fclose($h);
                $pruned = @unlink($file) && !file_exists($file) && $pruned;
            } else {
                fclose($h);
            }
        }

        return $pruned;
    }

    /**
     * {@inheritdoc}
     */
    protected function doFetch(array $ids)
    {
        $values = [];
        $now = time();

        foreach ($ids as $id) {
            $file = $this->getFile($id);
            if (!is_file($file) || !$h = @fopen($file, 'r')) {
                continue;
            }
            if (($expiresAt = (int) fgets($h)) && $now >= $expiresAt) {
                fclose($h);
                @unlink($file);
            } else {
                $i = rawurldecode(rtrim(fgets($h)));
                $value = stream_get_contents($h);
                fclose($h);
                if ($i === $id) {
                    $values[$id] = $this->marshaller->unmarshall($value);
                }
            }
        }

        return $values;
    }

    /**
     * {@inheritdoc}
     */
    protected function doHave(string $id)
    {
        $file = $this->getFile($id);

        return is_file($file) && (@filemtime($file) > time() || $this->doFetch([$id]));
    }

    /**
     * {@inheritdoc}
     */
    protected function doSave(array $values, int $lifetime)
    {
        $expiresAt = $lifetime ? (time() + $lifetime) : 0;
        $values = $this->marshaller->marshall($values, $failed);

        foreach ($values as $id => $value) {
            if (!$this->write($this->getFile($id, true), $expiresAt."\n".rawurlencode($id)."\n".$value, $expiresAt)) {
                $failed[] = $id;
            }
        }

        if ($failed && !is_writable($this->directory)) {
            throw new CacheException(sprintf('Cache directory is not writable (%s).', $this->directory));
        }

        return $failed;
    }

    private function getFileKey(string $file): string
    {
        if (!$h = @fopen($file, 'r')) {
            return '';
        }

        fgets($h); // expiry
        $encodedKey = fgets($h);
        fclose($h);

        return rawurldecode(rtrim($encodedKey));
    }
}
PKϤ$Z����
�
cache/Traits/ContractsTrait.phpnu�[���<?php

/*
 * This file is part of the Symfony package.
 *
 * (c) Fabien Potencier <fabien@symfony.com>
 *
 * For the full copyright and license information, please view the LICENSE
 * file that was distributed with this source code.
 */

namespace Symfony\Component\Cache\Traits;

use Psr\Log\LoggerInterface;
use Symfony\Component\Cache\Adapter\AdapterInterface;
use Symfony\Component\Cache\CacheItem;
use Symfony\Component\Cache\Exception\InvalidArgumentException;
use Symfony\Component\Cache\LockRegistry;
use Symfony\Contracts\Cache\CacheInterface;
use Symfony\Contracts\Cache\CacheTrait;
use Symfony\Contracts\Cache\ItemInterface;

/**
 * @author Nicolas Grekas <p@tchwork.com>
 *
 * @internal
 */
trait ContractsTrait
{
    use CacheTrait {
        doGet as private contractsGet;
    }

    private $callbackWrapper = [LockRegistry::class, 'compute'];
    private $computing = [];

    /**
     * Wraps the callback passed to ->get() in a callable.
     *
     * @return callable the previous callback wrapper
     */
    public function setCallbackWrapper(?callable $callbackWrapper): callable
    {
        $previousWrapper = $this->callbackWrapper;
        $this->callbackWrapper = $callbackWrapper ?? function (callable $callback, ItemInterface $item, bool &$save, CacheInterface $pool, \Closure $setMetadata, ?LoggerInterface $logger) {
            return $callback($item, $save);
        };

        return $previousWrapper;
    }

    private function doGet(AdapterInterface $pool, string $key, callable $callback, ?float $beta, array &$metadata = null)
    {
        if (0 > $beta = $beta ?? 1.0) {
            throw new InvalidArgumentException(sprintf('Argument "$beta" provided to "%s::get()" must be a positive number, %f given.', static::class, $beta));
        }

        static $setMetadata;

        $setMetadata = $setMetadata ?? \Closure::bind(
            static function (CacheItem $item, float $startTime, ?array &$metadata) {
                if ($item->expiry > $endTime = microtime(true)) {
                    $item->newMetadata[CacheItem::METADATA_EXPIRY] = $metadata[CacheItem::METADATA_EXPIRY] = $item->expiry;
                    $item->newMetadata[CacheItem::METADATA_CTIME] = $metadata[CacheItem::METADATA_CTIME] = (int) ceil(1000 * ($endTime - $startTime));
                } else {
                    unset($metadata[CacheItem::METADATA_EXPIRY], $metadata[CacheItem::METADATA_CTIME]);
                }
            },
            null,
            CacheItem::class
        );

        return $this->contractsGet($pool, $key, function (CacheItem $item, bool &$save) use ($pool, $callback, $setMetadata, &$metadata, $key) {
            // don't wrap nor save recursive calls
            if (isset($this->computing[$key])) {
                $value = $callback($item, $save);
                $save = false;

                return $value;
            }

            $this->computing[$key] = $key;
            $startTime = microtime(true);

            try {
                $value = ($this->callbackWrapper)($callback, $item, $save, $pool, function (CacheItem $item) use ($setMetadata, $startTime, &$metadata) {
                    $setMetadata($item, $startTime, $metadata);
                }, $this->logger ?? null);
                $setMetadata($item, $startTime, $metadata);

                return $value;
            } finally {
                unset($this->computing[$key]);
            }
        }, $beta, $metadata, $this->logger ?? null);
    }
}
PKϤ$Z���cache/Traits/RedisProxy.phpnu�[���<?php

/*
 * This file is part of the Symfony package.
 *
 * (c) Fabien Potencier <fabien@symfony.com>
 *
 * For the full copyright and license information, please view the LICENSE
 * file that was distributed with this source code.
 */

namespace Symfony\Component\Cache\Traits;

/**
 * @author Nicolas Grekas <p@tchwork.com>
 *
 * @internal
 */
class RedisProxy
{
    private $redis;
    private $initializer;
    private $ready = false;

    public function __construct(\Redis $redis, \Closure $initializer)
    {
        $this->redis = $redis;
        $this->initializer = $initializer;
    }

    public function __call(string $method, array $args)
    {
        $this->ready ?: $this->ready = $this->initializer->__invoke($this->redis);

        return $this->redis->{$method}(...$args);
    }

    public function hscan($strKey, &$iIterator, $strPattern = null, $iCount = null)
    {
        $this->ready ?: $this->ready = $this->initializer->__invoke($this->redis);

        return $this->redis->hscan($strKey, $iIterator, $strPattern, $iCount);
    }

    public function scan(&$iIterator, $strPattern = null, $iCount = null)
    {
        $this->ready ?: $this->ready = $this->initializer->__invoke($this->redis);

        return $this->redis->scan($iIterator, $strPattern, $iCount);
    }

    public function sscan($strKey, &$iIterator, $strPattern = null, $iCount = null)
    {
        $this->ready ?: $this->ready = $this->initializer->__invoke($this->redis);

        return $this->redis->sscan($strKey, $iIterator, $strPattern, $iCount);
    }

    public function zscan($strKey, &$iIterator, $strPattern = null, $iCount = null)
    {
        $this->ready ?: $this->ready = $this->initializer->__invoke($this->redis);

        return $this->redis->zscan($strKey, $iIterator, $strPattern, $iCount);
    }
}
PKϤ$Z���-11cache/Traits/ProxyTrait.phpnu�[���<?php

/*
 * This file is part of the Symfony package.
 *
 * (c) Fabien Potencier <fabien@symfony.com>
 *
 * For the full copyright and license information, please view the LICENSE
 * file that was distributed with this source code.
 */

namespace Symfony\Component\Cache\Traits;

use Symfony\Component\Cache\PruneableInterface;
use Symfony\Contracts\Service\ResetInterface;

/**
 * @author Nicolas Grekas <p@tchwork.com>
 *
 * @internal
 */
trait ProxyTrait
{
    private $pool;

    /**
     * {@inheritdoc}
     */
    public function prune()
    {
        return $this->pool instanceof PruneableInterface && $this->pool->prune();
    }

    /**
     * {@inheritdoc}
     */
    public function reset()
    {
        if ($this->pool instanceof ResetInterface) {
            $this->pool->reset();
        }
    }
}
PKϤ$ZT%4��"cache/Traits/RedisClusterProxy.phpnu�[���<?php

/*
 * This file is part of the Symfony package.
 *
 * (c) Fabien Potencier <fabien@symfony.com>
 *
 * For the full copyright and license information, please view the LICENSE
 * file that was distributed with this source code.
 */

namespace Symfony\Component\Cache\Traits;

/**
 * @author Alessandro Chitolina <alekitto@gmail.com>
 *
 * @internal
 */
class RedisClusterProxy
{
    private $redis;
    private $initializer;

    public function __construct(\Closure $initializer)
    {
        $this->initializer = $initializer;
    }

    public function __call(string $method, array $args)
    {
        $this->redis ?: $this->redis = $this->initializer->__invoke();

        return $this->redis->{$method}(...$args);
    }

    public function hscan($strKey, &$iIterator, $strPattern = null, $iCount = null)
    {
        $this->redis ?: $this->redis = $this->initializer->__invoke();

        return $this->redis->hscan($strKey, $iIterator, $strPattern, $iCount);
    }

    public function scan(&$iIterator, $strPattern = null, $iCount = null)
    {
        $this->redis ?: $this->redis = $this->initializer->__invoke();

        return $this->redis->scan($iIterator, $strPattern, $iCount);
    }

    public function sscan($strKey, &$iIterator, $strPattern = null, $iCount = null)
    {
        $this->redis ?: $this->redis = $this->initializer->__invoke();

        return $this->redis->sscan($strKey, $iIterator, $strPattern, $iCount);
    }

    public function zscan($strKey, &$iIterator, $strPattern = null, $iCount = null)
    {
        $this->redis ?: $this->redis = $this->initializer->__invoke();

        return $this->redis->zscan($strKey, $iIterator, $strPattern, $iCount);
    }
}
PKϤ$ZHGJ�RRRRcache/Traits/RedisTrait.phpnu�[���<?php

/*
 * This file is part of the Symfony package.
 *
 * (c) Fabien Potencier <fabien@symfony.com>
 *
 * For the full copyright and license information, please view the LICENSE
 * file that was distributed with this source code.
 */

namespace Symfony\Component\Cache\Traits;

use Predis\Connection\Aggregate\ClusterInterface;
use Predis\Connection\Aggregate\RedisCluster;
use Predis\Response\Status;
use Symfony\Component\Cache\Exception\CacheException;
use Symfony\Component\Cache\Exception\InvalidArgumentException;
use Symfony\Component\Cache\Marshaller\DefaultMarshaller;
use Symfony\Component\Cache\Marshaller\MarshallerInterface;

/**
 * @author Aurimas Niekis <aurimas@niekis.lt>
 * @author Nicolas Grekas <p@tchwork.com>
 *
 * @internal
 */
trait RedisTrait
{
    private static $defaultConnectionOptions = [
        'class' => null,
        'persistent' => 0,
        'persistent_id' => null,
        'timeout' => 30,
        'read_timeout' => 0,
        'retry_interval' => 0,
        'tcp_keepalive' => 0,
        'lazy' => null,
        'redis_cluster' => false,
        'redis_sentinel' => null,
        'dbindex' => 0,
        'failover' => 'none',
    ];
    private $redis;
    private $marshaller;

    /**
     * @param \Redis|\RedisArray|\RedisCluster|\Predis\ClientInterface $redisClient
     */
    private function init($redisClient, string $namespace, int $defaultLifetime, ?MarshallerInterface $marshaller)
    {
        parent::__construct($namespace, $defaultLifetime);

        if (preg_match('#[^-+_.A-Za-z0-9]#', $namespace, $match)) {
            throw new InvalidArgumentException(sprintf('RedisAdapter namespace contains "%s" but only characters in [-+_.A-Za-z0-9] are allowed.', $match[0]));
        }

        if (!$redisClient instanceof \Redis && !$redisClient instanceof \RedisArray && !$redisClient instanceof \RedisCluster && !$redisClient instanceof \Predis\ClientInterface && !$redisClient instanceof RedisProxy && !$redisClient instanceof RedisClusterProxy) {
            throw new InvalidArgumentException(sprintf('"%s()" expects parameter 1 to be Redis, RedisArray, RedisCluster or Predis\ClientInterface, "%s" given.', __METHOD__, get_debug_type($redisClient)));
        }

        if ($redisClient instanceof \Predis\ClientInterface && $redisClient->getOptions()->exceptions) {
            $options = clone $redisClient->getOptions();
            \Closure::bind(function () { $this->options['exceptions'] = false; }, $options, $options)();
            $redisClient = new $redisClient($redisClient->getConnection(), $options);
        }

        $this->redis = $redisClient;
        $this->marshaller = $marshaller ?? new DefaultMarshaller();
    }

    /**
     * Creates a Redis connection using a DSN configuration.
     *
     * Example DSN:
     *   - redis://localhost
     *   - redis://example.com:1234
     *   - redis://secret@example.com/13
     *   - redis:///var/run/redis.sock
     *   - redis://secret@/var/run/redis.sock/13
     *
     * @param string $dsn
     * @param array  $options See self::$defaultConnectionOptions
     *
     * @throws InvalidArgumentException when the DSN is invalid
     *
     * @return \Redis|\RedisCluster|RedisClusterProxy|RedisProxy|\Predis\ClientInterface According to the "class" option
     */
    public static function createConnection($dsn, array $options = [])
    {
        if (0 === strpos($dsn, 'redis:')) {
            $scheme = 'redis';
        } elseif (0 === strpos($dsn, 'rediss:')) {
            $scheme = 'rediss';
        } else {
            throw new InvalidArgumentException(sprintf('Invalid Redis DSN: "%s" does not start with "redis:" or "rediss".', $dsn));
        }

        if (!\extension_loaded('redis') && !class_exists(\Predis\Client::class)) {
            throw new CacheException(sprintf('Cannot find the "redis" extension nor the "predis/predis" package: "%s".', $dsn));
        }

        $params = preg_replace_callback('#^'.$scheme.':(//)?(?:(?:[^:@]*+:)?([^@]*+)@)?#', function ($m) use (&$auth) {
            if (isset($m[2])) {
                $auth = $m[2];

                if ('' === $auth) {
                    $auth = null;
                }
            }

            return 'file:'.($m[1] ?? '');
        }, $dsn);

        if (false === $params = parse_url($params)) {
            throw new InvalidArgumentException(sprintf('Invalid Redis DSN: "%s".', $dsn));
        }

        $query = $hosts = [];

        if (isset($params['query'])) {
            parse_str($params['query'], $query);

            if (isset($query['host'])) {
                if (!\is_array($hosts = $query['host'])) {
                    throw new InvalidArgumentException(sprintf('Invalid Redis DSN: "%s".', $dsn));
                }
                foreach ($hosts as $host => $parameters) {
                    if (\is_string($parameters)) {
                        parse_str($parameters, $parameters);
                    }
                    if (false === $i = strrpos($host, ':')) {
                        $hosts[$host] = ['scheme' => 'tcp', 'host' => $host, 'port' => 6379] + $parameters;
                    } elseif ($port = (int) substr($host, 1 + $i)) {
                        $hosts[$host] = ['scheme' => 'tcp', 'host' => substr($host, 0, $i), 'port' => $port] + $parameters;
                    } else {
                        $hosts[$host] = ['scheme' => 'unix', 'path' => substr($host, 0, $i)] + $parameters;
                    }
                }
                $hosts = array_values($hosts);
            }
        }

        if (isset($params['host']) || isset($params['path'])) {
            if (!isset($params['dbindex']) && isset($params['path']) && preg_match('#/(\d+)$#', $params['path'], $m)) {
                $params['dbindex'] = $m[1];
                $params['path'] = substr($params['path'], 0, -\strlen($m[0]));
            }

            if (isset($params['host'])) {
                array_unshift($hosts, ['scheme' => 'tcp', 'host' => $params['host'], 'port' => $params['port'] ?? 6379]);
            } else {
                array_unshift($hosts, ['scheme' => 'unix', 'path' => $params['path']]);
            }
        }

        if (!$hosts) {
            throw new InvalidArgumentException(sprintf('Invalid Redis DSN: "%s".', $dsn));
        }

        $params += $query + $options + self::$defaultConnectionOptions;

        if (isset($params['redis_sentinel']) && !class_exists(\Predis\Client::class)) {
            throw new CacheException(sprintf('Redis Sentinel support requires the "predis/predis" package: "%s".', $dsn));
        }

        if (null === $params['class'] && !isset($params['redis_sentinel']) && \extension_loaded('redis')) {
            $class = $params['redis_cluster'] ? \RedisCluster::class : (1 < \count($hosts) ? \RedisArray::class : \Redis::class);
        } else {
            $class = null === $params['class'] ? \Predis\Client::class : $params['class'];
        }

        if (is_a($class, \Redis::class, true)) {
            $connect = $params['persistent'] || $params['persistent_id'] ? 'pconnect' : 'connect';
            $redis = new $class();

            $initializer = static function ($redis) use ($connect, $params, $dsn, $auth, $hosts) {
                try {
                    @$redis->{$connect}($hosts[0]['host'] ?? $hosts[0]['path'], $hosts[0]['port'] ?? null, $params['timeout'], (string) $params['persistent_id'], $params['retry_interval'], $params['read_timeout']);

                    set_error_handler(function ($type, $msg) use (&$error) { $error = $msg; });
                    $isConnected = $redis->isConnected();
                    restore_error_handler();
                    if (!$isConnected) {
                        $error = preg_match('/^Redis::p?connect\(\): (.*)/', $error, $error) ? sprintf(' (%s)', $error[1]) : '';
                        throw new InvalidArgumentException(sprintf('Redis connection "%s" failed: ', $dsn).$error.'.');
                    }

                    if ((null !== $auth && !$redis->auth($auth))
                        || ($params['dbindex'] && !$redis->select($params['dbindex']))
                    ) {
                        $e = preg_replace('/^ERR /', '', $redis->getLastError());
                        throw new InvalidArgumentException(sprintf('Redis connection "%s" failed: ', $dsn).$e.'.');
                    }

                    if (0 < $params['tcp_keepalive'] && \defined('Redis::OPT_TCP_KEEPALIVE')) {
                        $redis->setOption(\Redis::OPT_TCP_KEEPALIVE, $params['tcp_keepalive']);
                    }
                } catch (\RedisException $e) {
                    throw new InvalidArgumentException(sprintf('Redis connection "%s" failed: ', $dsn).$e->getMessage());
                }

                return true;
            };

            if ($params['lazy']) {
                $redis = new RedisProxy($redis, $initializer);
            } else {
                $initializer($redis);
            }
        } elseif (is_a($class, \RedisArray::class, true)) {
            foreach ($hosts as $i => $host) {
                $hosts[$i] = 'tcp' === $host['scheme'] ? $host['host'].':'.$host['port'] : $host['path'];
            }
            $params['lazy_connect'] = $params['lazy'] ?? true;
            $params['connect_timeout'] = $params['timeout'];

            try {
                $redis = new $class($hosts, $params);
            } catch (\RedisClusterException $e) {
                throw new InvalidArgumentException(sprintf('Redis connection "%s" failed: ', $dsn).$e->getMessage());
            }

            if (0 < $params['tcp_keepalive'] && \defined('Redis::OPT_TCP_KEEPALIVE')) {
                $redis->setOption(\Redis::OPT_TCP_KEEPALIVE, $params['tcp_keepalive']);
            }
        } elseif (is_a($class, \RedisCluster::class, true)) {
            $initializer = static function () use ($class, $params, $dsn, $hosts) {
                foreach ($hosts as $i => $host) {
                    $hosts[$i] = 'tcp' === $host['scheme'] ? $host['host'].':'.$host['port'] : $host['path'];
                }

                try {
                    $redis = new $class(null, $hosts, $params['timeout'], $params['read_timeout'], (bool) $params['persistent'], $params['auth'] ?? '');
                } catch (\RedisClusterException $e) {
                    throw new InvalidArgumentException(sprintf('Redis connection "%s" failed: ', $dsn).$e->getMessage());
                }

                if (0 < $params['tcp_keepalive'] && \defined('Redis::OPT_TCP_KEEPALIVE')) {
                    $redis->setOption(\Redis::OPT_TCP_KEEPALIVE, $params['tcp_keepalive']);
                }
                switch ($params['failover']) {
                    case 'error': $redis->setOption(\RedisCluster::OPT_SLAVE_FAILOVER, \RedisCluster::FAILOVER_ERROR); break;
                    case 'distribute': $redis->setOption(\RedisCluster::OPT_SLAVE_FAILOVER, \RedisCluster::FAILOVER_DISTRIBUTE); break;
                    case 'slaves': $redis->setOption(\RedisCluster::OPT_SLAVE_FAILOVER, \RedisCluster::FAILOVER_DISTRIBUTE_SLAVES); break;
                }

                return $redis;
            };

            $redis = $params['lazy'] ? new RedisClusterProxy($initializer) : $initializer();
        } elseif (is_a($class, \Predis\ClientInterface::class, true)) {
            if ($params['redis_cluster']) {
                $params['cluster'] = 'redis';
                if (isset($params['redis_sentinel'])) {
                    throw new InvalidArgumentException(sprintf('Cannot use both "redis_cluster" and "redis_sentinel" at the same time: "%s".', $dsn));
                }
            } elseif (isset($params['redis_sentinel'])) {
                $params['replication'] = 'sentinel';
                $params['service'] = $params['redis_sentinel'];
            }
            $params += ['parameters' => []];
            $params['parameters'] += [
                'persistent' => $params['persistent'],
                'timeout' => $params['timeout'],
                'read_write_timeout' => $params['read_timeout'],
                'tcp_nodelay' => true,
            ];
            if ($params['dbindex']) {
                $params['parameters']['database'] = $params['dbindex'];
            }
            if (null !== $auth) {
                $params['parameters']['password'] = $auth;
            }
            if (1 === \count($hosts) && !($params['redis_cluster'] || $params['redis_sentinel'])) {
                $hosts = $hosts[0];
            } elseif (\in_array($params['failover'], ['slaves', 'distribute'], true) && !isset($params['replication'])) {
                $params['replication'] = true;
                $hosts[0] += ['alias' => 'master'];
            }
            $params['exceptions'] = false;

            $redis = new $class($hosts, array_diff_key($params, self::$defaultConnectionOptions));
            if (isset($params['redis_sentinel'])) {
                $redis->getConnection()->setSentinelTimeout($params['timeout']);
            }
        } elseif (class_exists($class, false)) {
            throw new InvalidArgumentException(sprintf('"%s" is not a subclass of "Redis", "RedisArray", "RedisCluster" nor "Predis\ClientInterface".', $class));
        } else {
            throw new InvalidArgumentException(sprintf('Class "%s" does not exist.', $class));
        }

        return $redis;
    }

    /**
     * {@inheritdoc}
     */
    protected function doFetch(array $ids)
    {
        if (!$ids) {
            return [];
        }

        $result = [];

        if ($this->redis instanceof \Predis\ClientInterface && $this->redis->getConnection() instanceof ClusterInterface) {
            $values = $this->pipeline(function () use ($ids) {
                foreach ($ids as $id) {
                    yield 'get' => [$id];
                }
            });
        } else {
            $values = $this->redis->mget($ids);

            if (!\is_array($values) || \count($values) !== \count($ids)) {
                return [];
            }

            $values = array_combine($ids, $values);
        }

        foreach ($values as $id => $v) {
            if ($v) {
                $result[$id] = $this->marshaller->unmarshall($v);
            }
        }

        return $result;
    }

    /**
     * {@inheritdoc}
     */
    protected function doHave(string $id)
    {
        return (bool) $this->redis->exists($id);
    }

    /**
     * {@inheritdoc}
     */
    protected function doClear(string $namespace)
    {
        $cleared = true;
        if ($this->redis instanceof \Predis\ClientInterface) {
            $evalArgs = [0, $namespace];
        } else {
            $evalArgs = [[$namespace], 0];
        }

        foreach ($this->getHosts() as $host) {
            if (!isset($namespace[0])) {
                $cleared = $host->flushDb() && $cleared;
                continue;
            }

            $info = $host->info('Server');
            $info = $info['Server'] ?? $info;

            if (!version_compare($info['redis_version'], '2.8', '>=')) {
                // As documented in Redis documentation (http://redis.io/commands/keys) using KEYS
                // can hang your server when it is executed against large databases (millions of items).
                // Whenever you hit this scale, you should really consider upgrading to Redis 2.8 or above.
                $cleared = $host->eval("local keys=redis.call('KEYS',ARGV[1]..'*') for i=1,#keys,5000 do redis.call('DEL',unpack(keys,i,math.min(i+4999,#keys))) end return 1", $evalArgs[0], $evalArgs[1]) && $cleared;
                continue;
            }

            $cursor = null;
            do {
                $keys = $host instanceof \Predis\ClientInterface ? $host->scan($cursor, 'MATCH', $namespace.'*', 'COUNT', 1000) : $host->scan($cursor, $namespace.'*', 1000);
                if (isset($keys[1]) && \is_array($keys[1])) {
                    $cursor = $keys[0];
                    $keys = $keys[1];
                }
                if ($keys) {
                    $this->doDelete($keys);
                }
            } while ($cursor = (int) $cursor);
        }

        return $cleared;
    }

    /**
     * {@inheritdoc}
     */
    protected function doDelete(array $ids)
    {
        if (!$ids) {
            return true;
        }

        if ($this->redis instanceof \Predis\ClientInterface && $this->redis->getConnection() instanceof ClusterInterface) {
            $this->pipeline(function () use ($ids) {
                foreach ($ids as $id) {
                    yield 'del' => [$id];
                }
            })->rewind();
        } else {
            $this->redis->del($ids);
        }

        return true;
    }

    /**
     * {@inheritdoc}
     */
    protected function doSave(array $values, int $lifetime)
    {
        if (!$values = $this->marshaller->marshall($values, $failed)) {
            return $failed;
        }

        $results = $this->pipeline(function () use ($values, $lifetime) {
            foreach ($values as $id => $value) {
                if (0 >= $lifetime) {
                    yield 'set' => [$id, $value];
                } else {
                    yield 'setEx' => [$id, $lifetime, $value];
                }
            }
        });

        foreach ($results as $id => $result) {
            if (true !== $result && (!$result instanceof Status || Status::get('OK') !== $result)) {
                $failed[] = $id;
            }
        }

        return $failed;
    }

    private function pipeline(\Closure $generator, $redis = null): \Generator
    {
        $ids = [];
        $redis = $redis ?? $this->redis;

        if ($redis instanceof RedisClusterProxy || $redis instanceof \RedisCluster || ($redis instanceof \Predis\ClientInterface && $redis->getConnection() instanceof RedisCluster)) {
            // phpredis & predis don't support pipelining with RedisCluster
            // see https://github.com/phpredis/phpredis/blob/develop/cluster.markdown#pipelining
            // see https://github.com/nrk/predis/issues/267#issuecomment-123781423
            $results = [];
            foreach ($generator() as $command => $args) {
                $results[] = $redis->{$command}(...$args);
                $ids[] = 'eval' === $command ? ($redis instanceof \Predis\ClientInterface ? $args[2] : $args[1][0]) : $args[0];
            }
        } elseif ($redis instanceof \Predis\ClientInterface) {
            $results = $redis->pipeline(static function ($redis) use ($generator, &$ids) {
                foreach ($generator() as $command => $args) {
                    $redis->{$command}(...$args);
                    $ids[] = 'eval' === $command ? $args[2] : $args[0];
                }
            });
        } elseif ($redis instanceof \RedisArray) {
            $connections = $results = $ids = [];
            foreach ($generator() as $command => $args) {
                $id = 'eval' === $command ? $args[1][0] : $args[0];
                if (!isset($connections[$h = $redis->_target($id)])) {
                    $connections[$h] = [$redis->_instance($h), -1];
                    $connections[$h][0]->multi(\Redis::PIPELINE);
                }
                $connections[$h][0]->{$command}(...$args);
                $results[] = [$h, ++$connections[$h][1]];
                $ids[] = $id;
            }
            foreach ($connections as $h => $c) {
                $connections[$h] = $c[0]->exec();
            }
            foreach ($results as $k => [$h, $c]) {
                $results[$k] = $connections[$h][$c];
            }
        } else {
            $redis->multi(\Redis::PIPELINE);
            foreach ($generator() as $command => $args) {
                $redis->{$command}(...$args);
                $ids[] = 'eval' === $command ? $args[1][0] : $args[0];
            }
            $results = $redis->exec();
        }

        foreach ($ids as $k => $id) {
            yield $id => $results[$k];
        }
    }

    private function getHosts(): array
    {
        $hosts = [$this->redis];
        if ($this->redis instanceof \Predis\ClientInterface) {
            $connection = $this->redis->getConnection();
            if ($connection instanceof ClusterInterface && $connection instanceof \Traversable) {
                $hosts = [];
                foreach ($connection as $c) {
                    $hosts[] = new \Predis\Client($c);
                }
            }
        } elseif ($this->redis instanceof \RedisArray) {
            $hosts = [];
            foreach ($this->redis->_hosts() as $host) {
                $hosts[] = $this->redis->_instance($host);
            }
        } elseif ($this->redis instanceof RedisClusterProxy || $this->redis instanceof \RedisCluster) {
            $hosts = [];
            foreach ($this->redis->_masters() as $host) {
                $hosts[] = $h = new \Redis();
                $h->connect($host[0], $host[1]);
            }
        }

        return $hosts;
    }
}
PKϤ$Z'�	���*cache/DataCollector/CacheDataCollector.phpnu�[���<?php

/*
 * This file is part of the Symfony package.
 *
 * (c) Fabien Potencier <fabien@symfony.com>
 *
 * For the full copyright and license information, please view the LICENSE
 * file that was distributed with this source code.
 */

namespace Symfony\Component\Cache\DataCollector;

use Symfony\Component\Cache\Adapter\TraceableAdapter;
use Symfony\Component\Cache\Adapter\TraceableAdapterEvent;
use Symfony\Component\HttpFoundation\Request;
use Symfony\Component\HttpFoundation\Response;
use Symfony\Component\HttpKernel\DataCollector\DataCollector;
use Symfony\Component\HttpKernel\DataCollector\LateDataCollectorInterface;

/**
 * @author Aaron Scherer <aequasi@gmail.com>
 * @author Tobias Nyholm <tobias.nyholm@gmail.com>
 *
 * @final
 */
class CacheDataCollector extends DataCollector implements LateDataCollectorInterface
{
    /**
     * @var TraceableAdapter[]
     */
    private $instances = [];

    public function addInstance(string $name, TraceableAdapter $instance)
    {
        $this->instances[$name] = $instance;
    }

    /**
     * {@inheritdoc}
     */
    public function collect(Request $request, Response $response, \Throwable $exception = null)
    {
        $empty = ['calls' => [], 'config' => [], 'options' => [], 'statistics' => []];
        $this->data = ['instances' => $empty, 'total' => $empty];
        foreach ($this->instances as $name => $instance) {
            $this->data['instances']['calls'][$name] = $instance->getCalls();
        }

        $this->data['instances']['statistics'] = $this->calculateStatistics();
        $this->data['total']['statistics'] = $this->calculateTotalStatistics();
    }

    public function reset()
    {
        $this->data = [];
        foreach ($this->instances as $instance) {
            $instance->clearCalls();
        }
    }

    public function lateCollect()
    {
        $this->data['instances']['calls'] = $this->cloneVar($this->data['instances']['calls']);
    }

    /**
     * {@inheritdoc}
     */
    public function getName()
    {
        return 'cache';
    }

    /**
     * Method returns amount of logged Cache reads: "get" calls.
     *
     * @return array
     */
    public function getStatistics()
    {
        return $this->data['instances']['statistics'];
    }

    /**
     * Method returns the statistic totals.
     *
     * @return array
     */
    public function getTotals()
    {
        return $this->data['total']['statistics'];
    }

    /**
     * Method returns all logged Cache call objects.
     *
     * @return mixed
     */
    public function getCalls()
    {
        return $this->data['instances']['calls'];
    }

    private function calculateStatistics(): array
    {
        $statistics = [];
        foreach ($this->data['instances']['calls'] as $name => $calls) {
            $statistics[$name] = [
                'calls' => 0,
                'time' => 0,
                'reads' => 0,
                'writes' => 0,
                'deletes' => 0,
                'hits' => 0,
                'misses' => 0,
            ];
            /** @var TraceableAdapterEvent $call */
            foreach ($calls as $call) {
                ++$statistics[$name]['calls'];
                $statistics[$name]['time'] += $call->end - $call->start;
                if ('get' === $call->name) {
                    ++$statistics[$name]['reads'];
                    if ($call->hits) {
                        ++$statistics[$name]['hits'];
                    } else {
                        ++$statistics[$name]['misses'];
                        ++$statistics[$name]['writes'];
                    }
                } elseif ('getItem' === $call->name) {
                    ++$statistics[$name]['reads'];
                    if ($call->hits) {
                        ++$statistics[$name]['hits'];
                    } else {
                        ++$statistics[$name]['misses'];
                    }
                } elseif ('getItems' === $call->name) {
                    $statistics[$name]['reads'] += $call->hits + $call->misses;
                    $statistics[$name]['hits'] += $call->hits;
                    $statistics[$name]['misses'] += $call->misses;
                } elseif ('hasItem' === $call->name) {
                    ++$statistics[$name]['reads'];
                    if (false === $call->result) {
                        ++$statistics[$name]['misses'];
                    } else {
                        ++$statistics[$name]['hits'];
                    }
                } elseif ('save' === $call->name) {
                    ++$statistics[$name]['writes'];
                } elseif ('deleteItem' === $call->name) {
                    ++$statistics[$name]['deletes'];
                }
            }
            if ($statistics[$name]['reads']) {
                $statistics[$name]['hit_read_ratio'] = round(100 * $statistics[$name]['hits'] / $statistics[$name]['reads'], 2);
            } else {
                $statistics[$name]['hit_read_ratio'] = null;
            }
        }

        return $statistics;
    }

    private function calculateTotalStatistics(): array
    {
        $statistics = $this->getStatistics();
        $totals = [
            'calls' => 0,
            'time' => 0,
            'reads' => 0,
            'writes' => 0,
            'deletes' => 0,
            'hits' => 0,
            'misses' => 0,
        ];
        foreach ($statistics as $name => $values) {
            foreach ($totals as $key => $value) {
                $totals[$key] += $statistics[$name][$key];
            }
        }
        if ($totals['reads']) {
            $totals['hit_read_ratio'] = round(100 * $totals['hits'] / $totals['reads'], 2);
        } else {
            $totals['hit_read_ratio'] = null;
        }

        return $totals;
    }
}
PKϤ$Z$fş��&cache/Marshaller/DeflateMarshaller.phpnu�[���<?php

/*
 * This file is part of the Symfony package.
 *
 * (c) Fabien Potencier <fabien@symfony.com>
 *
 * For the full copyright and license information, please view the LICENSE
 * file that was distributed with this source code.
 */

namespace Symfony\Component\Cache\Marshaller;

use Symfony\Component\Cache\Exception\CacheException;

/**
 * Compresses values using gzdeflate().
 *
 * @author Nicolas Grekas <p@tchwork.com>
 */
class DeflateMarshaller implements MarshallerInterface
{
    private $marshaller;

    public function __construct(MarshallerInterface $marshaller)
    {
        if (!\function_exists('gzdeflate')) {
            throw new CacheException('The "zlib" PHP extension is not loaded.');
        }

        $this->marshaller = $marshaller;
    }

    /**
     * {@inheritdoc}
     */
    public function marshall(array $values, ?array &$failed): array
    {
        return array_map('gzdeflate', $this->marshaller->marshall($values, $failed));
    }

    /**
     * {@inheritdoc}
     */
    public function unmarshall(string $value)
    {
        if (false !== $inflatedValue = @gzinflate($value)) {
            $value = $inflatedValue;
        }

        return $this->marshaller->unmarshall($value);
    }
}
PKϤ$Z��cv
v
&cache/Marshaller/DefaultMarshaller.phpnu�[���<?php

/*
 * This file is part of the Symfony package.
 *
 * (c) Fabien Potencier <fabien@symfony.com>
 *
 * For the full copyright and license information, please view the LICENSE
 * file that was distributed with this source code.
 */

namespace Symfony\Component\Cache\Marshaller;

use Symfony\Component\Cache\Exception\CacheException;

/**
 * Serializes/unserializes values using igbinary_serialize() if available, serialize() otherwise.
 *
 * @author Nicolas Grekas <p@tchwork.com>
 */
class DefaultMarshaller implements MarshallerInterface
{
    private $useIgbinarySerialize = true;

    public function __construct(bool $useIgbinarySerialize = null)
    {
        if (null === $useIgbinarySerialize) {
            $useIgbinarySerialize = \extension_loaded('igbinary') && (\PHP_VERSION_ID < 70400 || version_compare('3.1.6', phpversion('igbinary'), '<='));
        } elseif ($useIgbinarySerialize && (!\extension_loaded('igbinary') || (\PHP_VERSION_ID >= 70400 && version_compare('3.1.6', phpversion('igbinary'), '>')))) {
            throw new CacheException(\extension_loaded('igbinary') && \PHP_VERSION_ID >= 70400 ? 'Please upgrade the "igbinary" PHP extension to v3.1.6 or higher.' : 'The "igbinary" PHP extension is not loaded.');
        }
        $this->useIgbinarySerialize = $useIgbinarySerialize;
    }

    /**
     * {@inheritdoc}
     */
    public function marshall(array $values, ?array &$failed): array
    {
        $serialized = $failed = [];

        foreach ($values as $id => $value) {
            try {
                if ($this->useIgbinarySerialize) {
                    $serialized[$id] = igbinary_serialize($value);
                } else {
                    $serialized[$id] = serialize($value);
                }
            } catch (\Exception $e) {
                $failed[] = $id;
            }
        }

        return $serialized;
    }

    /**
     * {@inheritdoc}
     */
    public function unmarshall(string $value)
    {
        if ('b:0;' === $value) {
            return false;
        }
        if ('N;' === $value) {
            return null;
        }
        static $igbinaryNull;
        if ($value === ($igbinaryNull ?? $igbinaryNull = \extension_loaded('igbinary') ? igbinary_serialize(null) : false)) {
            return null;
        }
        $unserializeCallbackHandler = ini_set('unserialize_callback_func', __CLASS__.'::handleUnserializeCallback');
        try {
            if (':' === ($value[1] ?? ':')) {
                if (false !== $value = unserialize($value)) {
                    return $value;
                }
            } elseif (false === $igbinaryNull) {
                throw new \RuntimeException('Failed to unserialize values, did you forget to install the "igbinary" extension?');
            } elseif (null !== $value = igbinary_unserialize($value)) {
                return $value;
            }

            throw new \DomainException(error_get_last() ? error_get_last()['message'] : 'Failed to unserialize values.');
        } catch (\Error $e) {
            throw new \ErrorException($e->getMessage(), $e->getCode(), \E_ERROR, $e->getFile(), $e->getLine());
        } finally {
            ini_set('unserialize_callback_func', $unserializeCallbackHandler);
        }
    }

    /**
     * @internal
     */
    public static function handleUnserializeCallback(string $class)
    {
        throw new \DomainException('Class not found: '.$class);
    }
}
PKϤ$ZA�lx##'cache/Marshaller/TagAwareMarshaller.phpnu�[���<?php

/*
 * This file is part of the Symfony package.
 *
 * (c) Fabien Potencier <fabien@symfony.com>
 *
 * For the full copyright and license information, please view the LICENSE
 * file that was distributed with this source code.
 */

namespace Symfony\Component\Cache\Marshaller;

/**
 * A marshaller optimized for data structures generated by AbstractTagAwareAdapter.
 *
 * @author Nicolas Grekas <p@tchwork.com>
 */
class TagAwareMarshaller implements MarshallerInterface
{
    private $marshaller;

    public function __construct(MarshallerInterface $marshaller = null)
    {
        $this->marshaller = $marshaller ?? new DefaultMarshaller();
    }

    /**
     * {@inheritdoc}
     */
    public function marshall(array $values, ?array &$failed): array
    {
        $failed = $notSerialized = $serialized = [];

        foreach ($values as $id => $value) {
            if (\is_array($value) && \is_array($value['tags'] ?? null) && \array_key_exists('value', $value) && \count($value) === 2 + (\is_string($value['meta'] ?? null) && 8 === \strlen($value['meta']))) {
                // if the value is an array with keys "tags", "value" and "meta", use a compact serialization format
                // magic numbers in the form 9D-..-..-..-..-00-..-..-..-5F allow detecting this format quickly in unmarshall()

                $v = $this->marshaller->marshall($value, $f);

                if ($f) {
                    $f = [];
                    $failed[] = $id;
                } else {
                    if ([] === $value['tags']) {
                        $v['tags'] = '';
                    }

                    $serialized[$id] = "\x9D".($value['meta'] ?? "\0\0\0\0\0\0\0\0").pack('N', \strlen($v['tags'])).$v['tags'].$v['value'];
                    $serialized[$id][9] = "\x5F";
                }
            } else {
                // other arbitratry values are serialized using the decorated marshaller below
                $notSerialized[$id] = $value;
            }
        }

        if ($notSerialized) {
            $serialized += $this->marshaller->marshall($notSerialized, $f);
            $failed = array_merge($failed, $f);
        }

        return $serialized;
    }

    /**
     * {@inheritdoc}
     */
    public function unmarshall(string $value)
    {
        // detect the compact format used in marshall() using magic numbers in the form 9D-..-..-..-..-00-..-..-..-5F
        if (13 >= \strlen($value) || "\x9D" !== $value[0] || "\0" !== $value[5] || "\x5F" !== $value[9]) {
            return $this->marshaller->unmarshall($value);
        }

        // data consists of value, tags and metadata which we need to unpack
        $meta = substr($value, 1, 12);
        $meta[8] = "\0";
        $tagLen = unpack('Nlen', $meta, 8)['len'];
        $meta = substr($meta, 0, 8);

        return [
            'value' => $this->marshaller->unmarshall(substr($value, 13 + $tagLen)),
            'tags' => $tagLen ? $this->marshaller->unmarshall(substr($value, 13, $tagLen)) : [],
            'meta' => "\0\0\0\0\0\0\0\0" === $meta ? null : $meta,
        ];
    }
}
PKϤ$ZF���99(cache/Marshaller/MarshallerInterface.phpnu�[���<?php

/*
 * This file is part of the Symfony package.
 *
 * (c) Fabien Potencier <fabien@symfony.com>
 *
 * For the full copyright and license information, please view the LICENSE
 * file that was distributed with this source code.
 */

namespace Symfony\Component\Cache\Marshaller;

/**
 * Serializes/unserializes PHP values.
 *
 * Implementations of this interface MUST deal with errors carefully. They MUST
 * also deal with forward and backward compatibility at the storage format level.
 *
 * @author Nicolas Grekas <p@tchwork.com>
 */
interface MarshallerInterface
{
    /**
     * Serializes a list of values.
     *
     * When serialization fails for a specific value, no exception should be
     * thrown. Instead, its key should be listed in $failed.
     */
    public function marshall(array $values, ?array &$failed): array;

    /**
     * Unserializes a single value and throws an exception if anything goes wrong.
     *
     * @return mixed
     *
     * @throws \Exception Whenever unserialization fails
     */
    public function unmarshall(string $value);
}
PKϤ$Z���]	]	%cache/Marshaller/SodiumMarshaller.phpnu�[���<?php

/*
 * This file is part of the Symfony package.
 *
 * (c) Fabien Potencier <fabien@symfony.com>
 *
 * For the full copyright and license information, please view the LICENSE
 * file that was distributed with this source code.
 */

namespace Symfony\Component\Cache\Marshaller;

use Symfony\Component\Cache\Exception\CacheException;
use Symfony\Component\Cache\Exception\InvalidArgumentException;

/**
 * Encrypt/decrypt values using Libsodium.
 *
 * @author Ahmed TAILOULOUTE <ahmed.tailouloute@gmail.com>
 */
class SodiumMarshaller implements MarshallerInterface
{
    private $marshaller;
    private $decryptionKeys;

    /**
     * @param string[] $decryptionKeys The key at index "0" is required and is used to decrypt and encrypt values;
     *                                 more rotating keys can be provided to decrypt values;
     *                                 each key must be generated using sodium_crypto_box_keypair()
     */
    public function __construct(array $decryptionKeys, MarshallerInterface $marshaller = null)
    {
        if (!self::isSupported()) {
            throw new CacheException('The "sodium" PHP extension is not loaded.');
        }

        if (!isset($decryptionKeys[0])) {
            throw new InvalidArgumentException('At least one decryption key must be provided at index "0".');
        }

        $this->marshaller = $marshaller ?? new DefaultMarshaller();
        $this->decryptionKeys = $decryptionKeys;
    }

    public static function isSupported(): bool
    {
        return \function_exists('sodium_crypto_box_seal');
    }

    /**
     * {@inheritdoc}
     */
    public function marshall(array $values, ?array &$failed): array
    {
        $encryptionKey = sodium_crypto_box_publickey($this->decryptionKeys[0]);

        $encryptedValues = [];
        foreach ($this->marshaller->marshall($values, $failed) as $k => $v) {
            $encryptedValues[$k] = sodium_crypto_box_seal($v, $encryptionKey);
        }

        return $encryptedValues;
    }

    /**
     * {@inheritdoc}
     */
    public function unmarshall(string $value)
    {
        foreach ($this->decryptionKeys as $k) {
            if (false !== $decryptedValue = @sodium_crypto_box_seal_open($value, $k)) {
                $value = $decryptedValue;
                break;
            }
        }

        return $this->marshaller->unmarshall($value);
    }
}
PKϤ$Z&�jC(mime/Encoder/Base64MimeHeaderEncoder.phpnu�[���<?php

/*
 * This file is part of the Symfony package.
 *
 * (c) Fabien Potencier <fabien@symfony.com>
 *
 * For the full copyright and license information, please view the LICENSE
 * file that was distributed with this source code.
 */

namespace Symfony\Component\Mime\Encoder;

/**
 * @author Chris Corbyn
 */
final class Base64MimeHeaderEncoder extends Base64Encoder implements MimeHeaderEncoderInterface
{
    public function getName(): string
    {
        return 'B';
    }

    /**
     * Takes an unencoded string and produces a Base64 encoded string from it.
     *
     * If the charset is iso-2022-jp, it uses mb_encode_mimeheader instead of
     * default encodeString, otherwise pass to the parent method.
     */
    public function encodeString(string $string, ?string $charset = 'utf-8', int $firstLineOffset = 0, int $maxLineLength = 0): string
    {
        if ('iso-2022-jp' === strtolower($charset)) {
            $old = mb_internal_encoding();
            mb_internal_encoding('utf-8');
            $newstring = mb_encode_mimeheader($string, 'iso-2022-jp', $this->getName(), "\r\n");
            mb_internal_encoding($old);

            return $newstring;
        }

        return parent::encodeString($string, $charset, $firstLineOffset, $maxLineLength);
    }
}
PKϤ$Z�'�!mime/Encoder/QpContentEncoder.phpnu�[���<?php

/*
 * This file is part of the Symfony package.
 *
 * (c) Fabien Potencier <fabien@symfony.com>
 *
 * For the full copyright and license information, please view the LICENSE
 * file that was distributed with this source code.
 */

namespace Symfony\Component\Mime\Encoder;

/**
 * @author Lars Strojny
 */
final class QpContentEncoder implements ContentEncoderInterface
{
    public function encodeByteStream($stream, int $maxLineLength = 0): iterable
    {
        if (!\is_resource($stream)) {
            throw new \TypeError(sprintf('Method "%s" takes a stream as a first argument.', __METHOD__));
        }

        // we don't use PHP stream filters here as the content should be small enough
        yield $this->encodeString(stream_get_contents($stream), 'utf-8', 0, $maxLineLength);
    }

    public function getName(): string
    {
        return 'quoted-printable';
    }

    public function encodeString(string $string, ?string $charset = 'utf-8', int $firstLineOffset = 0, int $maxLineLength = 0): string
    {
        return $this->standardize(quoted_printable_encode($string));
    }

    /**
     * Make sure CRLF is correct and HT/SPACE are in valid places.
     */
    private function standardize(string $string): string
    {
        // transform CR or LF to CRLF
        $string = preg_replace('~=0D(?!=0A)|(?<!=0D)=0A~', '=0D=0A', $string);
        // transform =0D=0A to CRLF
        $string = str_replace(["\t=0D=0A", ' =0D=0A', '=0D=0A'], ["=09\r\n", "=20\r\n", "\r\n"], $string);

        switch (\ord(substr($string, -1))) {
            case 0x09:
                $string = substr_replace($string, '=09', -1);
                break;
            case 0x20:
                $string = substr_replace($string, '=20', -1);
                break;
        }

        return $string;
    }
}
PKϤ$Z�D���"mime/Encoder/IdnAddressEncoder.phpnu�[���<?php

/*
 * This file is part of the Symfony package.
 *
 * (c) Fabien Potencier <fabien@symfony.com>
 *
 * For the full copyright and license information, please view the LICENSE
 * file that was distributed with this source code.
 */

namespace Symfony\Component\Mime\Encoder;

use Symfony\Component\Mime\Exception\AddressEncoderException;

/**
 * An IDN email address encoder.
 *
 * Encodes the domain part of an address using IDN. This is compatible will all
 * SMTP servers.
 *
 * This encoder does not support email addresses with non-ASCII characters in
 * local-part (the substring before @).
 *
 * @author Christian Schmidt
 */
final class IdnAddressEncoder implements AddressEncoderInterface
{
    /**
     * Encodes the domain part of an address using IDN.
     *
     * @throws AddressEncoderException If local-part contains non-ASCII characters
     */
    public function encodeString(string $address): string
    {
        $i = strrpos($address, '@');
        if (false !== $i) {
            $local = substr($address, 0, $i);
            $domain = substr($address, $i + 1);

            if (preg_match('/[^\x00-\x7F]/', $local)) {
                throw new AddressEncoderException(sprintf('Non-ASCII characters not supported in local-part os "%s".', $address));
            }

            if (preg_match('/[^\x00-\x7F]/', $domain)) {
                $address = sprintf('%s@%s', $local, idn_to_ascii($domain, 0, \INTL_IDNA_VARIANT_UTS46));
            }
        }

        return $address;
    }
}
PKϤ$Z͒����(mime/Encoder/ContentEncoderInterface.phpnu�[���<?php

/*
 * This file is part of the Symfony package.
 *
 * (c) Fabien Potencier <fabien@symfony.com>
 *
 * For the full copyright and license information, please view the LICENSE
 * file that was distributed with this source code.
 */

namespace Symfony\Component\Mime\Encoder;

/**
 * @author Chris Corbyn
 */
interface ContentEncoderInterface extends EncoderInterface
{
    /**
     * Encodes the stream to a Generator.
     *
     * @param resource $stream
     */
    public function encodeByteStream($stream, int $maxLineLength = 0): iterable;

    /**
     * Gets the MIME name of this content encoding scheme.
     */
    public function getName(): string;
}
PKϤ$Z��`//%mime/Encoder/Base64ContentEncoder.phpnu�[���<?php

/*
 * This file is part of the Symfony package.
 *
 * (c) Fabien Potencier <fabien@symfony.com>
 *
 * For the full copyright and license information, please view the LICENSE
 * file that was distributed with this source code.
 */

namespace Symfony\Component\Mime\Encoder;

use Symfony\Component\Mime\Exception\RuntimeException;

/**
 * @author Fabien Potencier <fabien@symfony.com>
 */
final class Base64ContentEncoder extends Base64Encoder implements ContentEncoderInterface
{
    public function encodeByteStream($stream, int $maxLineLength = 0): iterable
    {
        if (!\is_resource($stream)) {
            throw new \TypeError(sprintf('Method "%s" takes a stream as a first argument.', __METHOD__));
        }

        $filter = stream_filter_append($stream, 'convert.base64-encode', \STREAM_FILTER_READ, [
            'line-length' => 0 >= $maxLineLength || 76 < $maxLineLength ? 76 : $maxLineLength,
            'line-break-chars' => "\r\n",
        ]);
        if (!\is_resource($filter)) {
            throw new RuntimeException('Unable to set the base64 content encoder to the filter.');
        }

        while (!feof($stream)) {
            yield fread($stream, 16372);
        }
        stream_filter_remove($filter);
    }

    public function getName(): string
    {
        return 'base64';
    }
}
PKϤ$Z�"�z33$mime/Encoder/QpMimeHeaderEncoder.phpnu�[���<?php

/*
 * This file is part of the Symfony package.
 *
 * (c) Fabien Potencier <fabien@symfony.com>
 *
 * For the full copyright and license information, please view the LICENSE
 * file that was distributed with this source code.
 */

namespace Symfony\Component\Mime\Encoder;

/**
 * @author Chris Corbyn
 */
final class QpMimeHeaderEncoder extends QpEncoder implements MimeHeaderEncoderInterface
{
    protected function initSafeMap(): void
    {
        foreach (array_merge(
            range(0x61, 0x7A), range(0x41, 0x5A),
            range(0x30, 0x39), [0x20, 0x21, 0x2A, 0x2B, 0x2D, 0x2F]
        ) as $byte) {
            $this->safeMap[$byte] = \chr($byte);
        }
    }

    public function getName(): string
    {
        return 'Q';
    }

    public function encodeString(string $string, ?string $charset = 'utf-8', int $firstLineOffset = 0, int $maxLineLength = 0): string
    {
        return str_replace([' ', '=20', "=\r\n"], ['_', '_', "\r\n"],
            parent::encodeString($string, $charset, $firstLineOffset, $maxLineLength)
        );
    }
}
PKϤ$Z�iq
��+mime/Encoder/MimeHeaderEncoderInterface.phpnu�[���<?php

/*
 * This file is part of the Symfony package.
 *
 * (c) Fabien Potencier <fabien@symfony.com>
 *
 * For the full copyright and license information, please view the LICENSE
 * file that was distributed with this source code.
 */

namespace Symfony\Component\Mime\Encoder;

/**
 * @author Chris Corbyn
 */
interface MimeHeaderEncoderInterface
{
    /**
     * Get the MIME name of this content encoding scheme.
     */
    public function getName(): string;
}
PKϤ$Z��%��(mime/Encoder/AddressEncoderInterface.phpnu�[���<?php

/*
 * This file is part of the Symfony package.
 *
 * (c) Fabien Potencier <fabien@symfony.com>
 *
 * For the full copyright and license information, please view the LICENSE
 * file that was distributed with this source code.
 */

namespace Symfony\Component\Mime\Encoder;

use Symfony\Component\Mime\Exception\AddressEncoderException;

/**
 * @author Christian Schmidt
 */
interface AddressEncoderInterface
{
    /**
     * Encodes an email address.
     *
     * @throws AddressEncoderException if the email cannot be represented in
     *                                 the encoding implemented by this class
     */
    public function encodeString(string $address): string;
}
PKϤ$ZƑ}mime/Encoder/Base64Encoder.phpnu�[���<?php

/*
 * This file is part of the Symfony package.
 *
 * (c) Fabien Potencier <fabien@symfony.com>
 *
 * For the full copyright and license information, please view the LICENSE
 * file that was distributed with this source code.
 */

namespace Symfony\Component\Mime\Encoder;

/**
 * @author Chris Corbyn
 */
class Base64Encoder implements EncoderInterface
{
    /**
     * Takes an unencoded string and produces a Base64 encoded string from it.
     *
     * Base64 encoded strings have a maximum line length of 76 characters.
     * If the first line needs to be shorter, indicate the difference with
     * $firstLineOffset.
     */
    public function encodeString(string $string, ?string $charset = 'utf-8', int $firstLineOffset = 0, int $maxLineLength = 0): string
    {
        if (0 >= $maxLineLength || 76 < $maxLineLength) {
            $maxLineLength = 76;
        }

        $encodedString = base64_encode($string);
        $firstLine = '';
        if (0 !== $firstLineOffset) {
            $firstLine = substr($encodedString, 0, $maxLineLength - $firstLineOffset)."\r\n";
            $encodedString = substr($encodedString, $maxLineLength - $firstLineOffset);
        }

        return $firstLine.trim(chunk_split($encodedString, $maxLineLength, "\r\n"));
    }
}
PKϤ$Z�{�5BB'mime/Encoder/EightBitContentEncoder.phpnu�[���<?php

/*
 * This file is part of the Symfony package.
 *
 * (c) Fabien Potencier <fabien@symfony.com>
 *
 * For the full copyright and license information, please view the LICENSE
 * file that was distributed with this source code.
 */

namespace Symfony\Component\Mime\Encoder;

/**
 * @author Fabien Potencier <fabien@symfony.com>
 */
final class EightBitContentEncoder implements ContentEncoderInterface
{
    public function encodeByteStream($stream, int $maxLineLength = 0): iterable
    {
        while (!feof($stream)) {
            yield fread($stream, 16372);
        }
    }

    public function getName(): string
    {
        return '8bit';
    }

    public function encodeString(string $string, ?string $charset = 'utf-8', int $firstLineOffset = 0, int $maxLineLength = 0): string
    {
        return $string;
    }
}
PKϤ$ZC����!mime/Encoder/EncoderInterface.phpnu�[���<?php

/*
 * This file is part of the Symfony package.
 *
 * (c) Fabien Potencier <fabien@symfony.com>
 *
 * For the full copyright and license information, please view the LICENSE
 * file that was distributed with this source code.
 */

namespace Symfony\Component\Mime\Encoder;

/**
 * @author Chris Corbyn
 */
interface EncoderInterface
{
    /**
     * Encode a given string to produce an encoded string.
     *
     * @param int $firstLineOffset if first line needs to be shorter
     * @param int $maxLineLength   - 0 indicates the default length for this encoding
     */
    public function encodeString(string $string, ?string $charset = 'utf-8', int $firstLineOffset = 0, int $maxLineLength = 0): string;
}
PKϤ$Z����mime/Encoder/QpEncoder.phpnu�[���<?php

/*
 * This file is part of the Symfony package.
 *
 * (c) Fabien Potencier <fabien@symfony.com>
 *
 * For the full copyright and license information, please view the LICENSE
 * file that was distributed with this source code.
 */

namespace Symfony\Component\Mime\Encoder;

use Symfony\Component\Mime\CharacterStream;

/**
 * @author Chris Corbyn
 */
class QpEncoder implements EncoderInterface
{
    /**
     * Pre-computed QP for HUGE optimization.
     */
    private static $qpMap = [
        0 => '=00', 1 => '=01', 2 => '=02', 3 => '=03', 4 => '=04',
        5 => '=05', 6 => '=06', 7 => '=07', 8 => '=08', 9 => '=09',
        10 => '=0A', 11 => '=0B', 12 => '=0C', 13 => '=0D', 14 => '=0E',
        15 => '=0F', 16 => '=10', 17 => '=11', 18 => '=12', 19 => '=13',
        20 => '=14', 21 => '=15', 22 => '=16', 23 => '=17', 24 => '=18',
        25 => '=19', 26 => '=1A', 27 => '=1B', 28 => '=1C', 29 => '=1D',
        30 => '=1E', 31 => '=1F', 32 => '=20', 33 => '=21', 34 => '=22',
        35 => '=23', 36 => '=24', 37 => '=25', 38 => '=26', 39 => '=27',
        40 => '=28', 41 => '=29', 42 => '=2A', 43 => '=2B', 44 => '=2C',
        45 => '=2D', 46 => '=2E', 47 => '=2F', 48 => '=30', 49 => '=31',
        50 => '=32', 51 => '=33', 52 => '=34', 53 => '=35', 54 => '=36',
        55 => '=37', 56 => '=38', 57 => '=39', 58 => '=3A', 59 => '=3B',
        60 => '=3C', 61 => '=3D', 62 => '=3E', 63 => '=3F', 64 => '=40',
        65 => '=41', 66 => '=42', 67 => '=43', 68 => '=44', 69 => '=45',
        70 => '=46', 71 => '=47', 72 => '=48', 73 => '=49', 74 => '=4A',
        75 => '=4B', 76 => '=4C', 77 => '=4D', 78 => '=4E', 79 => '=4F',
        80 => '=50', 81 => '=51', 82 => '=52', 83 => '=53', 84 => '=54',
        85 => '=55', 86 => '=56', 87 => '=57', 88 => '=58', 89 => '=59',
        90 => '=5A', 91 => '=5B', 92 => '=5C', 93 => '=5D', 94 => '=5E',
        95 => '=5F', 96 => '=60', 97 => '=61', 98 => '=62', 99 => '=63',
        100 => '=64', 101 => '=65', 102 => '=66', 103 => '=67', 104 => '=68',
        105 => '=69', 106 => '=6A', 107 => '=6B', 108 => '=6C', 109 => '=6D',
        110 => '=6E', 111 => '=6F', 112 => '=70', 113 => '=71', 114 => '=72',
        115 => '=73', 116 => '=74', 117 => '=75', 118 => '=76', 119 => '=77',
        120 => '=78', 121 => '=79', 122 => '=7A', 123 => '=7B', 124 => '=7C',
        125 => '=7D', 126 => '=7E', 127 => '=7F', 128 => '=80', 129 => '=81',
        130 => '=82', 131 => '=83', 132 => '=84', 133 => '=85', 134 => '=86',
        135 => '=87', 136 => '=88', 137 => '=89', 138 => '=8A', 139 => '=8B',
        140 => '=8C', 141 => '=8D', 142 => '=8E', 143 => '=8F', 144 => '=90',
        145 => '=91', 146 => '=92', 147 => '=93', 148 => '=94', 149 => '=95',
        150 => '=96', 151 => '=97', 152 => '=98', 153 => '=99', 154 => '=9A',
        155 => '=9B', 156 => '=9C', 157 => '=9D', 158 => '=9E', 159 => '=9F',
        160 => '=A0', 161 => '=A1', 162 => '=A2', 163 => '=A3', 164 => '=A4',
        165 => '=A5', 166 => '=A6', 167 => '=A7', 168 => '=A8', 169 => '=A9',
        170 => '=AA', 171 => '=AB', 172 => '=AC', 173 => '=AD', 174 => '=AE',
        175 => '=AF', 176 => '=B0', 177 => '=B1', 178 => '=B2', 179 => '=B3',
        180 => '=B4', 181 => '=B5', 182 => '=B6', 183 => '=B7', 184 => '=B8',
        185 => '=B9', 186 => '=BA', 187 => '=BB', 188 => '=BC', 189 => '=BD',
        190 => '=BE', 191 => '=BF', 192 => '=C0', 193 => '=C1', 194 => '=C2',
        195 => '=C3', 196 => '=C4', 197 => '=C5', 198 => '=C6', 199 => '=C7',
        200 => '=C8', 201 => '=C9', 202 => '=CA', 203 => '=CB', 204 => '=CC',
        205 => '=CD', 206 => '=CE', 207 => '=CF', 208 => '=D0', 209 => '=D1',
        210 => '=D2', 211 => '=D3', 212 => '=D4', 213 => '=D5', 214 => '=D6',
        215 => '=D7', 216 => '=D8', 217 => '=D9', 218 => '=DA', 219 => '=DB',
        220 => '=DC', 221 => '=DD', 222 => '=DE', 223 => '=DF', 224 => '=E0',
        225 => '=E1', 226 => '=E2', 227 => '=E3', 228 => '=E4', 229 => '=E5',
        230 => '=E6', 231 => '=E7', 232 => '=E8', 233 => '=E9', 234 => '=EA',
        235 => '=EB', 236 => '=EC', 237 => '=ED', 238 => '=EE', 239 => '=EF',
        240 => '=F0', 241 => '=F1', 242 => '=F2', 243 => '=F3', 244 => '=F4',
        245 => '=F5', 246 => '=F6', 247 => '=F7', 248 => '=F8', 249 => '=F9',
        250 => '=FA', 251 => '=FB', 252 => '=FC', 253 => '=FD', 254 => '=FE',
        255 => '=FF',
    ];

    private static $safeMapShare = [];

    /**
     * A map of non-encoded ascii characters.
     *
     * @var string[]
     *
     * @internal
     */
    protected $safeMap = [];

    public function __construct()
    {
        $id = static::class;
        if (!isset(self::$safeMapShare[$id])) {
            $this->initSafeMap();
            self::$safeMapShare[$id] = $this->safeMap;
        } else {
            $this->safeMap = self::$safeMapShare[$id];
        }
    }

    protected function initSafeMap(): void
    {
        foreach (array_merge([0x09, 0x20], range(0x21, 0x3C), range(0x3E, 0x7E)) as $byte) {
            $this->safeMap[$byte] = \chr($byte);
        }
    }

    /**
     * {@inheritdoc}
     *
     * Takes an unencoded string and produces a QP encoded string from it.
     *
     * QP encoded strings have a maximum line length of 76 characters.
     * If the first line needs to be shorter, indicate the difference with
     * $firstLineOffset.
     */
    public function encodeString(string $string, ?string $charset = 'utf-8', int $firstLineOffset = 0, int $maxLineLength = 0): string
    {
        if ($maxLineLength > 76 || $maxLineLength <= 0) {
            $maxLineLength = 76;
        }

        $thisLineLength = $maxLineLength - $firstLineOffset;

        $lines = [];
        $lNo = 0;
        $lines[$lNo] = '';
        $currentLine = &$lines[$lNo++];
        $size = $lineLen = 0;
        $charStream = new CharacterStream($string, $charset);

        // Fetching more than 4 chars at one is slower, as is fetching fewer bytes
        // Conveniently 4 chars is the UTF-8 safe number since UTF-8 has up to 6
        // bytes per char and (6 * 4 * 3 = 72 chars per line) * =NN is 3 bytes
        while (null !== $bytes = $charStream->readBytes(4)) {
            $enc = $this->encodeByteSequence($bytes, $size);

            $i = strpos($enc, '=0D=0A');
            $newLineLength = $lineLen + (false === $i ? $size : $i);

            if ($currentLine && $newLineLength >= $thisLineLength) {
                $lines[$lNo] = '';
                $currentLine = &$lines[$lNo++];
                $thisLineLength = $maxLineLength;
                $lineLen = 0;
            }

            $currentLine .= $enc;

            if (false === $i) {
                $lineLen += $size;
            } else {
                // 6 is the length of '=0D=0A'.
                $lineLen = $size - strrpos($enc, '=0D=0A') - 6;
            }
        }

        return $this->standardize(implode("=\r\n", $lines));
    }

    /**
     * Encode the given byte array into a verbatim QP form.
     */
    private function encodeByteSequence(array $bytes, int &$size): string
    {
        $ret = '';
        $size = 0;
        foreach ($bytes as $b) {
            if (isset($this->safeMap[$b])) {
                $ret .= $this->safeMap[$b];
                ++$size;
            } else {
                $ret .= self::$qpMap[$b];
                $size += 3;
            }
        }

        return $ret;
    }

    /**
     * Make sure CRLF is correct and HT/SPACE are in valid places.
     */
    private function standardize(string $string): string
    {
        $string = str_replace(["\t=0D=0A", ' =0D=0A', '=0D=0A'], ["=09\r\n", "=20\r\n", "\r\n"], $string);
        switch ($end = \ord(substr($string, -1))) {
            case 0x09:
            case 0x20:
                $string = substr_replace($string, self::$qpMap[$end], -1);
        }

        return $string;
    }
}
PKϤ$Z����mime/Encoder/Rfc2231Encoder.phpnu�[���<?php

/*
 * This file is part of the Symfony package.
 *
 * (c) Fabien Potencier <fabien@symfony.com>
 *
 * For the full copyright and license information, please view the LICENSE
 * file that was distributed with this source code.
 */

namespace Symfony\Component\Mime\Encoder;

use Symfony\Component\Mime\CharacterStream;

/**
 * @author Chris Corbyn
 */
final class Rfc2231Encoder implements EncoderInterface
{
    /**
     * Takes an unencoded string and produces a string encoded according to RFC 2231 from it.
     */
    public function encodeString(string $string, ?string $charset = 'utf-8', int $firstLineOffset = 0, int $maxLineLength = 0): string
    {
        $lines = [];
        $lineCount = 0;
        $lines[] = '';
        $currentLine = &$lines[$lineCount++];

        if (0 >= $maxLineLength) {
            $maxLineLength = 75;
        }

        $charStream = new CharacterStream($string, $charset);
        $thisLineLength = $maxLineLength - $firstLineOffset;

        while (null !== $char = $charStream->read(4)) {
            $encodedChar = rawurlencode($char);
            if (0 !== \strlen($currentLine) && \strlen($currentLine.$encodedChar) > $thisLineLength) {
                $lines[] = '';
                $currentLine = &$lines[$lineCount++];
                $thisLineLength = $maxLineLength;
            }
            $currentLine .= $encodedChar;
        }

        return implode("\r\n", $lines);
    }
}
PKϤ$Z�#��<<mime/Message.phpnu�[���<?php

/*
 * This file is part of the Symfony package.
 *
 * (c) Fabien Potencier <fabien@symfony.com>
 *
 * For the full copyright and license information, please view the LICENSE
 * file that was distributed with this source code.
 */

namespace Symfony\Component\Mime;

use Symfony\Component\Mime\Exception\LogicException;
use Symfony\Component\Mime\Header\Headers;
use Symfony\Component\Mime\Part\AbstractPart;
use Symfony\Component\Mime\Part\TextPart;

/**
 * @author Fabien Potencier <fabien@symfony.com>
 */
class Message extends RawMessage
{
    private $headers;
    private $body;

    public function __construct(Headers $headers = null, AbstractPart $body = null)
    {
        $this->headers = $headers ? clone $headers : new Headers();
        $this->body = $body;
    }

    public function __clone()
    {
        $this->headers = clone $this->headers;

        if (null !== $this->body) {
            $this->body = clone $this->body;
        }
    }

    /**
     * @return $this
     */
    public function setBody(AbstractPart $body = null)
    {
        $this->body = $body;

        return $this;
    }

    public function getBody(): ?AbstractPart
    {
        return $this->body;
    }

    /**
     * @return $this
     */
    public function setHeaders(Headers $headers)
    {
        $this->headers = $headers;

        return $this;
    }

    public function getHeaders(): Headers
    {
        return $this->headers;
    }

    public function getPreparedHeaders(): Headers
    {
        $headers = clone $this->headers;

        if (!$headers->has('From')) {
            if (!$headers->has('Sender')) {
                throw new LogicException('An email must have a "From" or a "Sender" header.');
            }
            $headers->addMailboxListHeader('From', [$headers->get('Sender')->getAddress()]);
        }

        $headers->addTextHeader('MIME-Version', '1.0');

        if (!$headers->has('Date')) {
            $headers->addDateHeader('Date', new \DateTimeImmutable());
        }

        // determine the "real" sender
        if (!$headers->has('Sender') && \count($froms = $headers->get('From')->getAddresses()) > 1) {
            $headers->addMailboxHeader('Sender', $froms[0]);
        }

        if (!$headers->has('Message-ID')) {
            $headers->addIdHeader('Message-ID', $this->generateMessageId());
        }

        // remove the Bcc field which should NOT be part of the sent message
        $headers->remove('Bcc');

        return $headers;
    }

    public function toString(): string
    {
        if (null === $body = $this->getBody()) {
            $body = new TextPart('');
        }

        return $this->getPreparedHeaders()->toString().$body->toString();
    }

    public function toIterable(): iterable
    {
        if (null === $body = $this->getBody()) {
            $body = new TextPart('');
        }

        yield $this->getPreparedHeaders()->toString();
        yield from $body->toIterable();
    }

    public function ensureValidity()
    {
        if (!$this->headers->has('To') && !$this->headers->has('Cc') && !$this->headers->has('Bcc')) {
            throw new LogicException('An email must have a "To", "Cc", or "Bcc" header.');
        }

        if (!$this->headers->has('From') && !$this->headers->has('Sender')) {
            throw new LogicException('An email must have a "From" or a "Sender" header.');
        }

        parent::ensureValidity();
    }

    public function generateMessageId(): string
    {
        if ($this->headers->has('Sender')) {
            $sender = $this->headers->get('Sender')->getAddress();
        } elseif ($this->headers->has('From')) {
            $sender = $this->headers->get('From')->getAddresses()[0];
        } else {
            throw new LogicException('An email must have a "From" or a "Sender" header.');
        }

        return bin2hex(random_bytes(16)).strstr($sender->getAddress(), '@');
    }

    public function __serialize(): array
    {
        return [$this->headers, $this->body];
    }

    public function __unserialize(array $data): void
    {
        [$this->headers, $this->body] = $data;
    }
}
PKϤ$Zc:٤55mime/MimeTypesInterface.phpnu�[���<?php

/*
 * This file is part of the Symfony package.
 *
 * (c) Fabien Potencier <fabien@symfony.com>
 *
 * For the full copyright and license information, please view the LICENSE
 * file that was distributed with this source code.
 */

namespace Symfony\Component\Mime;

/**
 * @author Fabien Potencier <fabien@symfony.com>
 */
interface MimeTypesInterface extends MimeTypeGuesserInterface
{
    /**
     * Gets the extensions for the given MIME type.
     *
     * @return string[] an array of extensions (first one is the preferred one)
     */
    public function getExtensions(string $mimeType): array;

    /**
     * Gets the MIME types for the given extension.
     *
     * @return string[] an array of MIME types (first one is the preferred one)
     */
    public function getMimeTypes(string $ext): array;
}
PKϤ$Z1D���mime/Crypto/SMime.phpnu�[���<?php

/*
 * This file is part of the Symfony package.
 *
 * (c) Fabien Potencier <fabien@symfony.com>
 *
 * For the full copyright and license information, please view the LICENSE
 * file that was distributed with this source code.
 */

namespace Symfony\Component\Mime\Crypto;

use Symfony\Component\Mime\Exception\RuntimeException;
use Symfony\Component\Mime\Part\SMimePart;

/**
 * @author Sebastiaan Stok <s.stok@rollerscapes.net>
 *
 * @internal
 */
abstract class SMime
{
    protected function normalizeFilePath(string $path): string
    {
        if (!file_exists($path)) {
            throw new RuntimeException(sprintf('File does not exist: "%s".', $path));
        }

        return 'file://'.str_replace('\\', '/', realpath($path));
    }

    protected function iteratorToFile(iterable $iterator, $stream): void
    {
        foreach ($iterator as $chunk) {
            fwrite($stream, $chunk);
        }
    }

    protected function convertMessageToSMimePart($stream, string $type, string $subtype): SMimePart
    {
        rewind($stream);

        $headers = '';

        while (!feof($stream)) {
            $buffer = fread($stream, 78);
            $headers .= $buffer;

            // Detect ending of header list
            if (preg_match('/(\r\n\r\n|\n\n)/', $headers, $match)) {
                $headersPosEnd = strpos($headers, $headerBodySeparator = $match[0]);

                break;
            }
        }

        $headers = $this->getMessageHeaders(trim(substr($headers, 0, $headersPosEnd)));

        fseek($stream, $headersPosEnd + \strlen($headerBodySeparator));

        return new SMimePart($this->getStreamIterator($stream), $type, $subtype, $this->getParametersFromHeader($headers['content-type']));
    }

    protected function getStreamIterator($stream): iterable
    {
        while (!feof($stream)) {
            yield str_replace("\n", "\r\n", str_replace("\r\n", "\n", fread($stream, 16372)));
        }
    }

    private function getMessageHeaders(string $headerData): array
    {
        $headers = [];
        $headerLines = explode("\r\n", str_replace("\n", "\r\n", str_replace("\r\n", "\n", $headerData)));
        $currentHeaderName = '';

        // Transform header lines into an associative array
        foreach ($headerLines as $headerLine) {
            // Empty lines between headers indicate a new mime-entity
            if ('' === $headerLine) {
                break;
            }

            // Handle headers that span multiple lines
            if (false === strpos($headerLine, ':')) {
                $headers[$currentHeaderName] .= ' '.trim($headerLine);
                continue;
            }

            $header = explode(':', $headerLine, 2);
            $currentHeaderName = strtolower($header[0]);
            $headers[$currentHeaderName] = trim($header[1]);
        }

        return $headers;
    }

    private function getParametersFromHeader(string $header): array
    {
        $params = [];

        preg_match_all('/(?P<name>[a-z-0-9]+)=(?P<value>"[^"]+"|(?:[^\s;]+|$))(?:\s+;)?/i', $header, $matches);

        foreach ($matches['value'] as $pos => $paramValue) {
            $params[$matches['name'][$pos]] = trim($paramValue, '"');
        }

        return $params;
    }
}
PKϤ$Z�U)��mime/Crypto/SMimeEncrypter.phpnu�[���<?php

/*
 * This file is part of the Symfony package.
 *
 * (c) Fabien Potencier <fabien@symfony.com>
 *
 * For the full copyright and license information, please view the LICENSE
 * file that was distributed with this source code.
 */

namespace Symfony\Component\Mime\Crypto;

use Symfony\Component\Mime\Exception\RuntimeException;
use Symfony\Component\Mime\Message;

/**
 * @author Sebastiaan Stok <s.stok@rollerscapes.net>
 */
final class SMimeEncrypter extends SMime
{
    private $certs;
    private $cipher;

    /**
     * @param string|string[] $certificate The path (or array of paths) of the file(s) containing the X.509 certificate(s)
     * @param int|null        $cipher      A set of algorithms used to encrypt the message. Must be one of these PHP constants: https://www.php.net/manual/en/openssl.ciphers.php
     */
    public function __construct($certificate, int $cipher = null)
    {
        if (!\extension_loaded('openssl')) {
            throw new \LogicException('PHP extension "openssl" is required to use SMime.');
        }

        if (\is_array($certificate)) {
            $this->certs = array_map([$this, 'normalizeFilePath'], $certificate);
        } else {
            $this->certs = $this->normalizeFilePath($certificate);
        }

        $this->cipher = $cipher ?? \OPENSSL_CIPHER_AES_256_CBC;
    }

    public function encrypt(Message $message): Message
    {
        $bufferFile = tmpfile();
        $outputFile = tmpfile();

        $this->iteratorToFile($message->toIterable(), $bufferFile);

        if (!@openssl_pkcs7_encrypt(stream_get_meta_data($bufferFile)['uri'], stream_get_meta_data($outputFile)['uri'], $this->certs, [], 0, $this->cipher)) {
            throw new RuntimeException(sprintf('Failed to encrypt S/Mime message. Error: "%s".', openssl_error_string()));
        }

        $mimePart = $this->convertMessageToSMimePart($outputFile, 'application', 'pkcs7-mime');
        $mimePart->getHeaders()
            ->addTextHeader('Content-Transfer-Encoding', 'base64')
            ->addParameterizedHeader('Content-Disposition', 'attachment', ['name' => 'smime.p7m'])
        ;

        return new Message($message->getHeaders(), $mimePart);
    }
}
PKϤ$Z��K�
�
mime/Crypto/SMimeSigner.phpnu�[���<?php

/*
 * This file is part of the Symfony package.
 *
 * (c) Fabien Potencier <fabien@symfony.com>
 *
 * For the full copyright and license information, please view the LICENSE
 * file that was distributed with this source code.
 */

namespace Symfony\Component\Mime\Crypto;

use Symfony\Component\Mime\Exception\RuntimeException;
use Symfony\Component\Mime\Message;

/**
 * @author Sebastiaan Stok <s.stok@rollerscapes.net>
 */
final class SMimeSigner extends SMime
{
    private $signCertificate;
    private $signPrivateKey;
    private $signOptions;
    private $extraCerts;

    /**
     * @param string      $certificate          The path of the file containing the signing certificate (in PEM format)
     * @param string      $privateKey           The path of the file containing the private key (in PEM format)
     * @param string|null $privateKeyPassphrase A passphrase of the private key (if any)
     * @param string|null $extraCerts           The path of the file containing intermediate certificates (in PEM format) needed by the signing certificate
     * @param int|null    $signOptions          Bitwise operator options for openssl_pkcs7_sign() (@see https://secure.php.net/manual/en/openssl.pkcs7.flags.php)
     */
    public function __construct(string $certificate, string $privateKey, string $privateKeyPassphrase = null, string $extraCerts = null, int $signOptions = null)
    {
        if (!\extension_loaded('openssl')) {
            throw new \LogicException('PHP extension "openssl" is required to use SMime.');
        }

        $this->signCertificate = $this->normalizeFilePath($certificate);

        if (null !== $privateKeyPassphrase) {
            $this->signPrivateKey = [$this->normalizeFilePath($privateKey), $privateKeyPassphrase];
        } else {
            $this->signPrivateKey = $this->normalizeFilePath($privateKey);
        }

        $this->signOptions = $signOptions ?? \PKCS7_DETACHED;
        $this->extraCerts = $extraCerts ? realpath($extraCerts) : null;
    }

    public function sign(Message $message): Message
    {
        $bufferFile = tmpfile();
        $outputFile = tmpfile();

        $this->iteratorToFile($message->getBody()->toIterable(), $bufferFile);

        if (!@openssl_pkcs7_sign(stream_get_meta_data($bufferFile)['uri'], stream_get_meta_data($outputFile)['uri'], $this->signCertificate, $this->signPrivateKey, [], $this->signOptions, $this->extraCerts)) {
            throw new RuntimeException(sprintf('Failed to sign S/Mime message. Error: "%s".', openssl_error_string()));
        }

        return new Message($message->getHeaders(), $this->convertMessageToSMimePart($outputFile, 'multipart', 'signed'));
    }
}
PKϤ$Z�����mime/Address.phpnu�[���<?php

/*
 * This file is part of the Symfony package.
 *
 * (c) Fabien Potencier <fabien@symfony.com>
 *
 * For the full copyright and license information, please view the LICENSE
 * file that was distributed with this source code.
 */

namespace Symfony\Component\Mime;

use Egulias\EmailValidator\EmailValidator;
use Egulias\EmailValidator\Validation\RFCValidation;
use Symfony\Component\Mime\Encoder\IdnAddressEncoder;
use Symfony\Component\Mime\Exception\InvalidArgumentException;
use Symfony\Component\Mime\Exception\LogicException;
use Symfony\Component\Mime\Exception\RfcComplianceException;

/**
 * @author Fabien Potencier <fabien@symfony.com>
 */
final class Address
{
    /**
     * A regex that matches a structure like 'Name <email@address.com>'.
     * It matches anything between the first < and last > as email address.
     * This allows to use a single string to construct an Address, which can be convenient to use in
     * config, and allows to have more readable config.
     * This does not try to cover all edge cases for address.
     */
    private const FROM_STRING_PATTERN = '~(?<displayName>[^<]*)<(?<addrSpec>.*)>[^>]*~';

    private static $validator;
    private static $encoder;

    private $address;
    private $name;

    public function __construct(string $address, string $name = '')
    {
        if (!class_exists(EmailValidator::class)) {
            throw new LogicException(sprintf('The "%s" class cannot be used as it needs "%s"; try running "composer require egulias/email-validator".', __CLASS__, EmailValidator::class));
        }

        if (null === self::$validator) {
            self::$validator = new EmailValidator();
        }

        $this->address = trim($address);
        $this->name = trim(str_replace(["\n", "\r"], '', $name));

        if (!self::$validator->isValid($this->address, new RFCValidation())) {
            throw new RfcComplianceException(sprintf('Email "%s" does not comply with addr-spec of RFC 2822.', $address));
        }
    }

    public function getAddress(): string
    {
        return $this->address;
    }

    public function getName(): string
    {
        return $this->name;
    }

    public function getEncodedAddress(): string
    {
        if (null === self::$encoder) {
            self::$encoder = new IdnAddressEncoder();
        }

        return self::$encoder->encodeString($this->address);
    }

    public function toString(): string
    {
        return ($n = $this->getName()) ? $n.' <'.$this->getEncodedAddress().'>' : $this->getEncodedAddress();
    }

    /**
     * @param Address|string $address
     */
    public static function create($address): self
    {
        if ($address instanceof self) {
            return $address;
        }
        if (\is_string($address)) {
            return self::fromString($address);
        }

        throw new InvalidArgumentException(sprintf('An address can be an instance of Address or a string ("%s") given).', get_debug_type($address)));
    }

    /**
     * @param (Address|string)[] $addresses
     *
     * @return Address[]
     */
    public static function createArray(array $addresses): array
    {
        $addrs = [];
        foreach ($addresses as $address) {
            $addrs[] = self::create($address);
        }

        return $addrs;
    }

    public static function fromString(string $string): self
    {
        if (false === strpos($string, '<')) {
            return new self($string, '');
        }

        if (!preg_match(self::FROM_STRING_PATTERN, $string, $matches)) {
            throw new InvalidArgumentException(sprintf('Could not parse "%s" to a "%s" instance.', $string, static::class));
        }

        return new self($matches['addrSpec'], trim($matches['displayName'], ' \'"'));
    }
}
PKϤ$ZOZ���mime/RawMessage.phpnu�[���<?php

/*
 * This file is part of the Symfony package.
 *
 * (c) Fabien Potencier <fabien@symfony.com>
 *
 * For the full copyright and license information, please view the LICENSE
 * file that was distributed with this source code.
 */

namespace Symfony\Component\Mime;

use Symfony\Component\Mime\Exception\LogicException;

/**
 * @author Fabien Potencier <fabien@symfony.com>
 */
class RawMessage implements \Serializable
{
    private $message;

    /**
     * @param iterable|string $message
     */
    public function __construct($message)
    {
        $this->message = $message;
    }

    public function toString(): string
    {
        if (\is_string($this->message)) {
            return $this->message;
        }

        return $this->message = implode('', iterator_to_array($this->message, false));
    }

    public function toIterable(): iterable
    {
        if (\is_string($this->message)) {
            yield $this->message;

            return;
        }

        $message = '';
        foreach ($this->message as $chunk) {
            $message .= $chunk;
            yield $chunk;
        }
        $this->message = $message;
    }

    /**
     * @throws LogicException if the message is not valid
     */
    public function ensureValidity()
    {
    }

    /**
     * @internal
     */
    final public function serialize(): string
    {
        return serialize($this->__serialize());
    }

    /**
     * @internal
     */
    final public function unserialize($serialized)
    {
        $this->__unserialize(unserialize($serialized));
    }

    public function __serialize(): array
    {
        return [$this->message];
    }

    public function __unserialize(array $data): void
    {
        [$this->message] = $data;
    }
}
PKϤ$Z9o��!mime/MimeTypeGuesserInterface.phpnu�[���<?php

/*
 * This file is part of the Symfony package.
 *
 * (c) Fabien Potencier <fabien@symfony.com>
 *
 * For the full copyright and license information, please view the LICENSE
 * file that was distributed with this source code.
 */

namespace Symfony\Component\Mime;

/**
 * Guesses the MIME type of a file.
 *
 * @author Fabien Potencier <fabien@symfony.com>
 */
interface MimeTypeGuesserInterface
{
    /**
     * Returns true if this guesser is supported.
     */
    public function isGuesserSupported(): bool;

    /**
     * Guesses the MIME type of the file with the given path.
     *
     * @param string $path The path to the file
     *
     * @return string|null The MIME type or null, if none could be guessed
     *
     * @throws \LogicException           If the guesser is not supported
     * @throws \InvalidArgumentException If the file does not exist or is not readable
     */
    public function guessMimeType(string $path): ?string;
}
PKϤ$Z��6ddmime/MessageConverter.phpnu�[���<?php

/*
 * This file is part of the Symfony package.
 *
 * (c) Fabien Potencier <fabien@symfony.com>
 *
 * For the full copyright and license information, please view the LICENSE
 * file that was distributed with this source code.
 */

namespace Symfony\Component\Mime;

use Symfony\Component\Mime\Exception\RuntimeException;
use Symfony\Component\Mime\Part\DataPart;
use Symfony\Component\Mime\Part\Multipart\AlternativePart;
use Symfony\Component\Mime\Part\Multipart\MixedPart;
use Symfony\Component\Mime\Part\Multipart\RelatedPart;
use Symfony\Component\Mime\Part\TextPart;

/**
 * @author Fabien Potencier <fabien@symfony.com>
 */
final class MessageConverter
{
    /**
     * @throws RuntimeException when unable to convert the message to an email
     */
    public static function toEmail(Message $message): Email
    {
        if ($message instanceof Email) {
            return $message;
        }

        // try to convert to a "simple" Email instance
        $body = $message->getBody();
        if ($body instanceof TextPart) {
            return self::createEmailFromTextPart($message, $body);
        }

        if ($body instanceof AlternativePart) {
            return self::createEmailFromAlternativePart($message, $body);
        }

        if ($body instanceof RelatedPart) {
            return self::createEmailFromRelatedPart($message, $body);
        }

        if ($body instanceof MixedPart) {
            $parts = $body->getParts();
            if ($parts[0] instanceof RelatedPart) {
                $email = self::createEmailFromRelatedPart($message, $parts[0]);
            } elseif ($parts[0] instanceof AlternativePart) {
                $email = self::createEmailFromAlternativePart($message, $parts[0]);
            } elseif ($parts[0] instanceof TextPart) {
                $email = self::createEmailFromTextPart($message, $parts[0]);
            } else {
                throw new RuntimeException(sprintf('Unable to create an Email from an instance of "%s" as the body is too complex.', get_debug_type($message)));
            }

            return self::attachParts($email, \array_slice($parts, 1));
        }

        throw new RuntimeException(sprintf('Unable to create an Email from an instance of "%s" as the body is too complex.', get_debug_type($message)));
    }

    private static function createEmailFromTextPart(Message $message, TextPart $part): Email
    {
        if ('text' === $part->getMediaType() && 'plain' === $part->getMediaSubtype()) {
            return (new Email(clone $message->getHeaders()))->text($part->getBody(), $part->getPreparedHeaders()->getHeaderParameter('Content-Type', 'charset') ?: 'utf-8');
        }
        if ('text' === $part->getMediaType() && 'html' === $part->getMediaSubtype()) {
            return (new Email(clone $message->getHeaders()))->html($part->getBody(), $part->getPreparedHeaders()->getHeaderParameter('Content-Type', 'charset') ?: 'utf-8');
        }

        throw new RuntimeException(sprintf('Unable to create an Email from an instance of "%s" as the body is too complex.', get_debug_type($message)));
    }

    private static function createEmailFromAlternativePart(Message $message, AlternativePart $part): Email
    {
        $parts = $part->getParts();
        if (
            2 === \count($parts) &&
            $parts[0] instanceof TextPart && 'text' === $parts[0]->getMediaType() && 'plain' === $parts[0]->getMediaSubtype() &&
            $parts[1] instanceof TextPart && 'text' === $parts[1]->getMediaType() && 'html' === $parts[1]->getMediaSubtype()
         ) {
            return (new Email(clone $message->getHeaders()))
                ->text($parts[0]->getBody(), $parts[0]->getPreparedHeaders()->getHeaderParameter('Content-Type', 'charset') ?: 'utf-8')
                ->html($parts[1]->getBody(), $parts[1]->getPreparedHeaders()->getHeaderParameter('Content-Type', 'charset') ?: 'utf-8')
            ;
        }

        throw new RuntimeException(sprintf('Unable to create an Email from an instance of "%s" as the body is too complex.', get_debug_type($message)));
    }

    private static function createEmailFromRelatedPart(Message $message, RelatedPart $part): Email
    {
        $parts = $part->getParts();
        if ($parts[0] instanceof AlternativePart) {
            $email = self::createEmailFromAlternativePart($message, $parts[0]);
        } elseif ($parts[0] instanceof TextPart) {
            $email = self::createEmailFromTextPart($message, $parts[0]);
        } else {
            throw new RuntimeException(sprintf('Unable to create an Email from an instance of "%s" as the body is too complex.', get_debug_type($message)));
        }

        return self::attachParts($email, \array_slice($parts, 1));
    }

    private static function attachParts(Email $email, array $parts): Email
    {
        foreach ($parts as $part) {
            if (!$part instanceof DataPart) {
                throw new RuntimeException(sprintf('Unable to create an Email from an instance of "%s" as the body is too complex.', get_debug_type($email)));
            }

            $headers = $part->getPreparedHeaders();
            $method = 'inline' === $headers->getHeaderBody('Content-Disposition') ? 'embed' : 'attach';
            $name = $headers->getHeaderParameter('Content-Disposition', 'filename');
            $email->$method($part->getBody(), $name, $part->getMediaType().'/'.$part->getMediaSubtype());
        }

        return $email;
    }
}
PKϤ$Z}��T��'mime/Test/Constraint/EmailHasHeader.phpnu�[���<?php

/*
 * This file is part of the Symfony package.
 *
 * (c) Fabien Potencier <fabien@symfony.com>
 *
 * For the full copyright and license information, please view the LICENSE
 * file that was distributed with this source code.
 */

namespace Symfony\Component\Mime\Test\Constraint;

use PHPUnit\Framework\Constraint\Constraint;
use Symfony\Component\Mime\RawMessage;

final class EmailHasHeader extends Constraint
{
    private $headerName;

    public function __construct(string $headerName)
    {
        $this->headerName = $headerName;
    }

    /**
     * {@inheritdoc}
     */
    public function toString(): string
    {
        return sprintf('has header "%s"', $this->headerName);
    }

    /**
     * @param RawMessage $message
     *
     * {@inheritdoc}
     */
    protected function matches($message): bool
    {
        if (RawMessage::class === \get_class($message)) {
            throw new \LogicException('Unable to test a message header on a RawMessage instance.');
        }

        return $message->getHeaders()->has($this->headerName);
    }

    /**
     * @param RawMessage $message
     *
     * {@inheritdoc}
     */
    protected function failureDescription($message): string
    {
        return 'the Email '.$this->toString();
    }
}
PKϤ$Zq����.mime/Test/Constraint/EmailHtmlBodyContains.phpnu�[���<?php

/*
 * This file is part of the Symfony package.
 *
 * (c) Fabien Potencier <fabien@symfony.com>
 *
 * For the full copyright and license information, please view the LICENSE
 * file that was distributed with this source code.
 */

namespace Symfony\Component\Mime\Test\Constraint;

use PHPUnit\Framework\Constraint\Constraint;
use Symfony\Component\Mime\Message;
use Symfony\Component\Mime\RawMessage;

final class EmailHtmlBodyContains extends Constraint
{
    private $expectedText;

    public function __construct(string $expectedText)
    {
        $this->expectedText = $expectedText;
    }

    /**
     * {@inheritdoc}
     */
    public function toString(): string
    {
        return sprintf('contains "%s"', $this->expectedText);
    }

    /**
     * {@inheritdoc}
     *
     * @param RawMessage $message
     */
    protected function matches($message): bool
    {
        if (RawMessage::class === \get_class($message) || Message::class === \get_class($message)) {
            throw new \LogicException('Unable to test a message HTML body on a RawMessage or Message instance.');
        }

        return false !== mb_strpos($message->getHtmlBody(), $this->expectedText);
    }

    /**
     * {@inheritdoc}
     *
     * @param RawMessage $message
     */
    protected function failureDescription($message): string
    {
        return 'the Email HTML body '.$this->toString();
    }
}
PKϤ$Z]5�5cc-mime/Test/Constraint/EmailAddressContains.phpnu�[���<?php

/*
 * This file is part of the Symfony package.
 *
 * (c) Fabien Potencier <fabien@symfony.com>
 *
 * For the full copyright and license information, please view the LICENSE
 * file that was distributed with this source code.
 */

namespace Symfony\Component\Mime\Test\Constraint;

use PHPUnit\Framework\Constraint\Constraint;
use Symfony\Component\Mime\Header\MailboxHeader;
use Symfony\Component\Mime\Header\MailboxListHeader;
use Symfony\Component\Mime\RawMessage;

final class EmailAddressContains extends Constraint
{
    private $headerName;
    private $expectedValue;

    public function __construct(string $headerName, string $expectedValue)
    {
        $this->headerName = $headerName;
        $this->expectedValue = $expectedValue;
    }

    /**
     * {@inheritdoc}
     */
    public function toString(): string
    {
        return sprintf('contains address "%s" with value "%s"', $this->headerName, $this->expectedValue);
    }

    /**
     * @param RawMessage $message
     *
     * {@inheritdoc}
     */
    protected function matches($message): bool
    {
        if (RawMessage::class === \get_class($message)) {
            throw new \LogicException('Unable to test a message address on a RawMessage instance.');
        }

        $header = $message->getHeaders()->get($this->headerName);
        if ($header instanceof MailboxHeader) {
            return $this->expectedValue === $header->getAddress()->getAddress();
        } elseif ($header instanceof MailboxListHeader) {
            foreach ($header->getAddresses() as $address) {
                if ($this->expectedValue === $address->getAddress()) {
                    return true;
                }
            }

            return false;
        }

        throw new \LogicException(sprintf('Unable to test a message address on a non-address header.'));
    }

    /**
     * @param RawMessage $message
     *
     * {@inheritdoc}
     */
    protected function failureDescription($message): string
    {
        return sprintf('the Email %s (value is %s)', $this->toString(), $message->getHeaders()->get($this->headerName)->getBodyAsString());
    }
}
PKϤ$Z�єn��.mime/Test/Constraint/EmailTextBodyContains.phpnu�[���<?php

/*
 * This file is part of the Symfony package.
 *
 * (c) Fabien Potencier <fabien@symfony.com>
 *
 * For the full copyright and license information, please view the LICENSE
 * file that was distributed with this source code.
 */

namespace Symfony\Component\Mime\Test\Constraint;

use PHPUnit\Framework\Constraint\Constraint;
use Symfony\Component\Mime\Message;
use Symfony\Component\Mime\RawMessage;

final class EmailTextBodyContains extends Constraint
{
    private $expectedText;

    public function __construct(string $expectedText)
    {
        $this->expectedText = $expectedText;
    }

    /**
     * {@inheritdoc}
     */
    public function toString(): string
    {
        return sprintf('contains "%s"', $this->expectedText);
    }

    /**
     * {@inheritdoc}
     *
     * @param RawMessage $message
     */
    protected function matches($message): bool
    {
        if (RawMessage::class === \get_class($message) || Message::class === \get_class($message)) {
            throw new \LogicException('Unable to test a message text body on a RawMessage or Message instance.');
        }

        return false !== mb_strpos($message->getTextBody(), $this->expectedText);
    }

    /**
     * {@inheritdoc}
     *
     * @param RawMessage $message
     */
    protected function failureDescription($message): string
    {
        return 'the Email text body '.$this->toString();
    }
}
PKϤ$Z��5#��(mime/Test/Constraint/EmailHeaderSame.phpnu�[���<?php

/*
 * This file is part of the Symfony package.
 *
 * (c) Fabien Potencier <fabien@symfony.com>
 *
 * For the full copyright and license information, please view the LICENSE
 * file that was distributed with this source code.
 */

namespace Symfony\Component\Mime\Test\Constraint;

use PHPUnit\Framework\Constraint\Constraint;
use Symfony\Component\Mime\Header\UnstructuredHeader;
use Symfony\Component\Mime\RawMessage;

final class EmailHeaderSame extends Constraint
{
    private $headerName;
    private $expectedValue;

    public function __construct(string $headerName, string $expectedValue)
    {
        $this->headerName = $headerName;
        $this->expectedValue = $expectedValue;
    }

    /**
     * {@inheritdoc}
     */
    public function toString(): string
    {
        return sprintf('has header "%s" with value "%s"', $this->headerName, $this->expectedValue);
    }

    /**
     * @param RawMessage $message
     *
     * {@inheritdoc}
     */
    protected function matches($message): bool
    {
        if (RawMessage::class === \get_class($message)) {
            throw new \LogicException('Unable to test a message header on a RawMessage instance.');
        }

        return $this->expectedValue === $this->getHeaderValue($message);
    }

    /**
     * @param RawMessage $message
     *
     * {@inheritdoc}
     */
    protected function failureDescription($message): string
    {
        return sprintf('the Email %s (value is %s)', $this->toString(), $this->getHeaderValue($message));
    }

    private function getHeaderValue($message): string
    {
        $header = $message->getHeaders()->get($this->headerName);

        return $header instanceof UnstructuredHeader ? $header->getValue() : $header->getBodyAsString();
    }
}
PKϤ$ZD`���-mime/Test/Constraint/EmailAttachmentCount.phpnu�[���<?php

/*
 * This file is part of the Symfony package.
 *
 * (c) Fabien Potencier <fabien@symfony.com>
 *
 * For the full copyright and license information, please view the LICENSE
 * file that was distributed with this source code.
 */

namespace Symfony\Component\Mime\Test\Constraint;

use PHPUnit\Framework\Constraint\Constraint;
use Symfony\Component\Mime\Message;
use Symfony\Component\Mime\RawMessage;

final class EmailAttachmentCount extends Constraint
{
    private $expectedValue;
    private $transport;

    public function __construct(int $expectedValue, string $transport = null)
    {
        $this->expectedValue = $expectedValue;
        $this->transport = $transport;
    }

    /**
     * {@inheritdoc}
     */
    public function toString(): string
    {
        return sprintf('has sent "%d" attachment(s)', $this->expectedValue);
    }

    /**
     * @param RawMessage $message
     *
     * {@inheritdoc}
     */
    protected function matches($message): bool
    {
        if (RawMessage::class === \get_class($message) || Message::class === \get_class($message)) {
            throw new \LogicException('Unable to test a message attachment on a RawMessage or Message instance.');
        }

        return $this->expectedValue === \count($message->getAttachments());
    }

    /**
     * @param RawMessage $message
     *
     * {@inheritdoc}
     */
    protected function failureDescription($message): string
    {
        return 'the Email '.$this->toString();
    }
}
PKϤ$Z�BxH�v�vmime/MimeTypes.phpnu�[���<?php

/*
 * This file is part of the Symfony package.
 *
 * (c) Fabien Potencier <fabien@symfony.com>
 *
 * For the full copyright and license information, please view the LICENSE
 * file that was distributed with this source code.
 */

namespace Symfony\Component\Mime;

use Symfony\Component\Mime\Exception\LogicException;

/**
 * Manages MIME types and file extensions.
 *
 * For MIME type guessing, you can register custom guessers
 * by calling the registerGuesser() method.
 * Custom guessers are always called before any default ones:
 *
 *     $guesser = new MimeTypes();
 *     $guesser->registerGuesser(new MyCustomMimeTypeGuesser());
 *
 * If you want to change the order of the default guessers, just re-register your
 * preferred one as a custom one. The last registered guesser is preferred over
 * previously registered ones.
 *
 * Re-registering a built-in guesser also allows you to configure it:
 *
 *     $guesser = new MimeTypes();
 *     $guesser->registerGuesser(new FileinfoMimeTypeGuesser('/path/to/magic/file'));
 *
 * @author Fabien Potencier <fabien@symfony.com>
 */
final class MimeTypes implements MimeTypesInterface
{
    private $extensions = [];
    private $mimeTypes = [];

    /**
     * @var MimeTypeGuesserInterface[]
     */
    private $guessers = [];
    private static $default;

    public function __construct(array $map = [])
    {
        foreach ($map as $mimeType => $extensions) {
            $this->extensions[$mimeType] = $extensions;

            foreach ($extensions as $extension) {
                $this->mimeTypes[$extension][] = $mimeType;
            }
        }
        $this->registerGuesser(new FileBinaryMimeTypeGuesser());
        $this->registerGuesser(new FileinfoMimeTypeGuesser());
    }

    public static function setDefault(self $default)
    {
        self::$default = $default;
    }

    public static function getDefault(): self
    {
        return self::$default ?? self::$default = new self();
    }

    /**
     * Registers a MIME type guesser.
     *
     * The last registered guesser has precedence over the other ones.
     */
    public function registerGuesser(MimeTypeGuesserInterface $guesser)
    {
        array_unshift($this->guessers, $guesser);
    }

    /**
     * {@inheritdoc}
     */
    public function getExtensions(string $mimeType): array
    {
        if ($this->extensions) {
            $extensions = $this->extensions[$mimeType] ?? $this->extensions[$lcMimeType = strtolower($mimeType)] ?? null;
        }

        return $extensions ?? self::$map[$mimeType] ?? self::$map[$lcMimeType ?? strtolower($mimeType)] ?? [];
    }

    /**
     * {@inheritdoc}
     */
    public function getMimeTypes(string $ext): array
    {
        if ($this->mimeTypes) {
            $mimeTypes = $this->mimeTypes[$ext] ?? $this->mimeTypes[$lcExt = strtolower($ext)] ?? null;
        }

        return $mimeTypes ?? self::$reverseMap[$ext] ?? self::$reverseMap[$lcExt ?? strtolower($ext)] ?? [];
    }

    /**
     * {@inheritdoc}
     */
    public function isGuesserSupported(): bool
    {
        foreach ($this->guessers as $guesser) {
            if ($guesser->isGuesserSupported()) {
                return true;
            }
        }

        return false;
    }

    /**
     * {@inheritdoc}
     *
     * The file is passed to each registered MIME type guesser in reverse order
     * of their registration (last registered is queried first). Once a guesser
     * returns a value that is not null, this method terminates and returns the
     * value.
     */
    public function guessMimeType(string $path): ?string
    {
        foreach ($this->guessers as $guesser) {
            if (!$guesser->isGuesserSupported()) {
                continue;
            }

            if (null !== $mimeType = $guesser->guessMimeType($path)) {
                return $mimeType;
            }
        }

        if (!$this->isGuesserSupported()) {
            throw new LogicException('Unable to guess the MIME type as no guessers are available (have you enabled the php_fileinfo extension?).');
        }

        return null;
    }

    /**
     * A map of MIME types and their default extensions.
     *
     * Updated from upstream on 2019-01-16
     *
     * @see Resources/bin/update_mime_types.php
     */
    private static $map = [
        'application/acrobat' => ['pdf'],
        'application/andrew-inset' => ['ez'],
        'application/annodex' => ['anx'],
        'application/applixware' => ['aw'],
        'application/atom+xml' => ['atom'],
        'application/atomcat+xml' => ['atomcat'],
        'application/atomsvc+xml' => ['atomsvc'],
        'application/ccxml+xml' => ['ccxml'],
        'application/cdmi-capability' => ['cdmia'],
        'application/cdmi-container' => ['cdmic'],
        'application/cdmi-domain' => ['cdmid'],
        'application/cdmi-object' => ['cdmio'],
        'application/cdmi-queue' => ['cdmiq'],
        'application/cdr' => ['cdr'],
        'application/coreldraw' => ['cdr'],
        'application/cu-seeme' => ['cu'],
        'application/davmount+xml' => ['davmount'],
        'application/dbase' => ['dbf'],
        'application/dbf' => ['dbf'],
        'application/dicom' => ['dcm'],
        'application/docbook+xml' => ['dbk', 'docbook'],
        'application/dssc+der' => ['dssc'],
        'application/dssc+xml' => ['xdssc'],
        'application/ecmascript' => ['ecma', 'es'],
        'application/emf' => ['emf'],
        'application/emma+xml' => ['emma'],
        'application/epub+zip' => ['epub'],
        'application/exi' => ['exi'],
        'application/font-tdpfr' => ['pfr'],
        'application/font-woff' => ['woff'],
        'application/futuresplash' => ['swf', 'spl'],
        'application/geo+json' => ['geojson', 'geo.json'],
        'application/gml+xml' => ['gml'],
        'application/gnunet-directory' => ['gnd'],
        'application/gpx' => ['gpx'],
        'application/gpx+xml' => ['gpx'],
        'application/gxf' => ['gxf'],
        'application/gzip' => ['gz'],
        'application/hyperstudio' => ['stk'],
        'application/ico' => ['ico'],
        'application/ics' => ['vcs', 'ics'],
        'application/illustrator' => ['ai'],
        'application/inkml+xml' => ['ink', 'inkml'],
        'application/ipfix' => ['ipfix'],
        'application/java' => ['class'],
        'application/java-archive' => ['jar'],
        'application/java-byte-code' => ['class'],
        'application/java-serialized-object' => ['ser'],
        'application/java-vm' => ['class'],
        'application/javascript' => ['js', 'jsm', 'mjs'],
        'application/jrd+json' => ['jrd'],
        'application/json' => ['json'],
        'application/json-patch+json' => ['json-patch'],
        'application/jsonml+json' => ['jsonml'],
        'application/ld+json' => ['jsonld'],
        'application/lost+xml' => ['lostxml'],
        'application/lotus123' => ['123', 'wk1', 'wk3', 'wk4', 'wks'],
        'application/m3u' => ['m3u', 'm3u8', 'vlc'],
        'application/mac-binhex40' => ['hqx'],
        'application/mac-compactpro' => ['cpt'],
        'application/mads+xml' => ['mads'],
        'application/marc' => ['mrc'],
        'application/marcxml+xml' => ['mrcx'],
        'application/mathematica' => ['ma', 'nb', 'mb'],
        'application/mathml+xml' => ['mathml', 'mml'],
        'application/mbox' => ['mbox'],
        'application/mdb' => ['mdb'],
        'application/mediaservercontrol+xml' => ['mscml'],
        'application/metalink+xml' => ['metalink'],
        'application/metalink4+xml' => ['meta4'],
        'application/mets+xml' => ['mets'],
        'application/mods+xml' => ['mods'],
        'application/mp21' => ['m21', 'mp21'],
        'application/mp4' => ['mp4s'],
        'application/ms-tnef' => ['tnef', 'tnf'],
        'application/msaccess' => ['mdb'],
        'application/msexcel' => ['xls', 'xlc', 'xll', 'xlm', 'xlw', 'xla', 'xlt', 'xld'],
        'application/mspowerpoint' => ['ppz', 'ppt', 'pps', 'pot'],
        'application/msword' => ['doc', 'dot'],
        'application/msword-template' => ['dot'],
        'application/mxf' => ['mxf'],
        'application/nappdf' => ['pdf'],
        'application/octet-stream' => ['bin', 'dms', 'lrf', 'mar', 'so', 'dist', 'distz', 'pkg', 'bpk', 'dump', 'elc', 'deploy'],
        'application/oda' => ['oda'],
        'application/oebps-package+xml' => ['opf'],
        'application/ogg' => ['ogx'],
        'application/omdoc+xml' => ['omdoc'],
        'application/onenote' => ['onetoc', 'onetoc2', 'onetmp', 'onepkg'],
        'application/owl+xml' => ['owx'],
        'application/oxps' => ['oxps', 'xps'],
        'application/patch-ops-error+xml' => ['xer'],
        'application/pcap' => ['pcap', 'cap', 'dmp'],
        'application/pdf' => ['pdf'],
        'application/pgp' => ['pgp', 'gpg', 'asc'],
        'application/pgp-encrypted' => ['pgp', 'gpg', 'asc'],
        'application/pgp-keys' => ['skr', 'pkr', 'asc', 'pgp', 'gpg'],
        'application/pgp-signature' => ['asc', 'sig', 'pgp', 'gpg'],
        'application/photoshop' => ['psd'],
        'application/pics-rules' => ['prf'],
        'application/pkcs10' => ['p10'],
        'application/pkcs12' => ['p12', 'pfx'],
        'application/pkcs7-mime' => ['p7m', 'p7c'],
        'application/pkcs7-signature' => ['p7s'],
        'application/pkcs8' => ['p8'],
        'application/pkcs8-encrypted' => ['p8e'],
        'application/pkix-attr-cert' => ['ac'],
        'application/pkix-cert' => ['cer'],
        'application/pkix-crl' => ['crl'],
        'application/pkix-pkipath' => ['pkipath'],
        'application/pkixcmp' => ['pki'],
        'application/pls' => ['pls'],
        'application/pls+xml' => ['pls'],
        'application/postscript' => ['ai', 'eps', 'ps'],
        'application/powerpoint' => ['ppz', 'ppt', 'pps', 'pot'],
        'application/prs.cww' => ['cww'],
        'application/pskc+xml' => ['pskcxml'],
        'application/ram' => ['ram'],
        'application/raml+yaml' => ['raml'],
        'application/rdf+xml' => ['rdf', 'rdfs', 'owl'],
        'application/reginfo+xml' => ['rif'],
        'application/relax-ng-compact-syntax' => ['rnc'],
        'application/resource-lists+xml' => ['rl'],
        'application/resource-lists-diff+xml' => ['rld'],
        'application/rls-services+xml' => ['rs'],
        'application/rpki-ghostbusters' => ['gbr'],
        'application/rpki-manifest' => ['mft'],
        'application/rpki-roa' => ['roa'],
        'application/rsd+xml' => ['rsd'],
        'application/rss+xml' => ['rss'],
        'application/rtf' => ['rtf'],
        'application/sbml+xml' => ['sbml'],
        'application/scvp-cv-request' => ['scq'],
        'application/scvp-cv-response' => ['scs'],
        'application/scvp-vp-request' => ['spq'],
        'application/scvp-vp-response' => ['spp'],
        'application/sdp' => ['sdp'],
        'application/set-payment-initiation' => ['setpay'],
        'application/set-registration-initiation' => ['setreg'],
        'application/shf+xml' => ['shf'],
        'application/sieve' => ['siv'],
        'application/smil' => ['smil', 'smi', 'sml', 'kino'],
        'application/smil+xml' => ['smi', 'smil', 'sml', 'kino'],
        'application/sparql-query' => ['rq'],
        'application/sparql-results+xml' => ['srx'],
        'application/sql' => ['sql'],
        'application/srgs' => ['gram'],
        'application/srgs+xml' => ['grxml'],
        'application/sru+xml' => ['sru'],
        'application/ssdl+xml' => ['ssdl'],
        'application/ssml+xml' => ['ssml'],
        'application/stuffit' => ['sit'],
        'application/tei+xml' => ['tei', 'teicorpus'],
        'application/thraud+xml' => ['tfi'],
        'application/timestamped-data' => ['tsd'],
        'application/trig' => ['trig'],
        'application/vnd.3gpp.pic-bw-large' => ['plb'],
        'application/vnd.3gpp.pic-bw-small' => ['psb'],
        'application/vnd.3gpp.pic-bw-var' => ['pvb'],
        'application/vnd.3gpp2.tcap' => ['tcap'],
        'application/vnd.3m.post-it-notes' => ['pwn'],
        'application/vnd.accpac.simply.aso' => ['aso'],
        'application/vnd.accpac.simply.imp' => ['imp'],
        'application/vnd.acucobol' => ['acu'],
        'application/vnd.acucorp' => ['atc', 'acutc'],
        'application/vnd.adobe.air-application-installer-package+zip' => ['air'],
        'application/vnd.adobe.flash.movie' => ['swf', 'spl'],
        'application/vnd.adobe.formscentral.fcdt' => ['fcdt'],
        'application/vnd.adobe.fxp' => ['fxp', 'fxpl'],
        'application/vnd.adobe.illustrator' => ['ai'],
        'application/vnd.adobe.xdp+xml' => ['xdp'],
        'application/vnd.adobe.xfdf' => ['xfdf'],
        'application/vnd.ahead.space' => ['ahead'],
        'application/vnd.airzip.filesecure.azf' => ['azf'],
        'application/vnd.airzip.filesecure.azs' => ['azs'],
        'application/vnd.amazon.ebook' => ['azw'],
        'application/vnd.americandynamics.acc' => ['acc'],
        'application/vnd.amiga.ami' => ['ami'],
        'application/vnd.android.package-archive' => ['apk'],
        'application/vnd.anser-web-certificate-issue-initiation' => ['cii'],
        'application/vnd.anser-web-funds-transfer-initiation' => ['fti'],
        'application/vnd.antix.game-component' => ['atx'],
        'application/vnd.appimage' => ['appimage'],
        'application/vnd.apple.installer+xml' => ['mpkg'],
        'application/vnd.apple.keynote' => ['key'],
        'application/vnd.apple.mpegurl' => ['m3u8', 'm3u'],
        'application/vnd.aristanetworks.swi' => ['swi'],
        'application/vnd.astraea-software.iota' => ['iota'],
        'application/vnd.audiograph' => ['aep'],
        'application/vnd.blueice.multipass' => ['mpm'],
        'application/vnd.bmi' => ['bmi'],
        'application/vnd.businessobjects' => ['rep'],
        'application/vnd.chemdraw+xml' => ['cdxml'],
        'application/vnd.chess-pgn' => ['pgn'],
        'application/vnd.chipnuts.karaoke-mmd' => ['mmd'],
        'application/vnd.cinderella' => ['cdy'],
        'application/vnd.claymore' => ['cla'],
        'application/vnd.cloanto.rp9' => ['rp9'],
        'application/vnd.clonk.c4group' => ['c4g', 'c4d', 'c4f', 'c4p', 'c4u'],
        'application/vnd.cluetrust.cartomobile-config' => ['c11amc'],
        'application/vnd.cluetrust.cartomobile-config-pkg' => ['c11amz'],
        'application/vnd.coffeescript' => ['coffee'],
        'application/vnd.comicbook+zip' => ['cbz'],
        'application/vnd.comicbook-rar' => ['cbr'],
        'application/vnd.commonspace' => ['csp'],
        'application/vnd.contact.cmsg' => ['cdbcmsg'],
        'application/vnd.corel-draw' => ['cdr'],
        'application/vnd.cosmocaller' => ['cmc'],
        'application/vnd.crick.clicker' => ['clkx'],
        'application/vnd.crick.clicker.keyboard' => ['clkk'],
        'application/vnd.crick.clicker.palette' => ['clkp'],
        'application/vnd.crick.clicker.template' => ['clkt'],
        'application/vnd.crick.clicker.wordbank' => ['clkw'],
        'application/vnd.criticaltools.wbs+xml' => ['wbs'],
        'application/vnd.ctc-posml' => ['pml'],
        'application/vnd.cups-ppd' => ['ppd'],
        'application/vnd.curl.car' => ['car'],
        'application/vnd.curl.pcurl' => ['pcurl'],
        'application/vnd.dart' => ['dart'],
        'application/vnd.data-vision.rdz' => ['rdz'],
        'application/vnd.debian.binary-package' => ['deb', 'udeb'],
        'application/vnd.dece.data' => ['uvf', 'uvvf', 'uvd', 'uvvd'],
        'application/vnd.dece.ttml+xml' => ['uvt', 'uvvt'],
        'application/vnd.dece.unspecified' => ['uvx', 'uvvx'],
        'application/vnd.dece.zip' => ['uvz', 'uvvz'],
        'application/vnd.denovo.fcselayout-link' => ['fe_launch'],
        'application/vnd.dna' => ['dna'],
        'application/vnd.dolby.mlp' => ['mlp'],
        'application/vnd.dpgraph' => ['dpg'],
        'application/vnd.dreamfactory' => ['dfac'],
        'application/vnd.ds-keypoint' => ['kpxx'],
        'application/vnd.dvb.ait' => ['ait'],
        'application/vnd.dvb.service' => ['svc'],
        'application/vnd.dynageo' => ['geo'],
        'application/vnd.ecowin.chart' => ['mag'],
        'application/vnd.emusic-emusic_package' => ['emp'],
        'application/vnd.enliven' => ['nml'],
        'application/vnd.epson.esf' => ['esf'],
        'application/vnd.epson.msf' => ['msf'],
        'application/vnd.epson.quickanime' => ['qam'],
        'application/vnd.epson.salt' => ['slt'],
        'application/vnd.epson.ssf' => ['ssf'],
        'application/vnd.eszigno3+xml' => ['es3', 'et3'],
        'application/vnd.ezpix-album' => ['ez2'],
        'application/vnd.ezpix-package' => ['ez3'],
        'application/vnd.fdf' => ['fdf'],
        'application/vnd.fdsn.mseed' => ['mseed'],
        'application/vnd.fdsn.seed' => ['seed', 'dataless'],
        'application/vnd.flatpak' => ['flatpak', 'xdgapp'],
        'application/vnd.flatpak.ref' => ['flatpakref'],
        'application/vnd.flatpak.repo' => ['flatpakrepo'],
        'application/vnd.flographit' => ['gph'],
        'application/vnd.fluxtime.clip' => ['ftc'],
        'application/vnd.framemaker' => ['fm', 'frame', 'maker', 'book'],
        'application/vnd.frogans.fnc' => ['fnc'],
        'application/vnd.frogans.ltf' => ['ltf'],
        'application/vnd.fsc.weblaunch' => ['fsc'],
        'application/vnd.fujitsu.oasys' => ['oas'],
        'application/vnd.fujitsu.oasys2' => ['oa2'],
        'application/vnd.fujitsu.oasys3' => ['oa3'],
        'application/vnd.fujitsu.oasysgp' => ['fg5'],
        'application/vnd.fujitsu.oasysprs' => ['bh2'],
        'application/vnd.fujixerox.ddd' => ['ddd'],
        'application/vnd.fujixerox.docuworks' => ['xdw'],
        'application/vnd.fujixerox.docuworks.binder' => ['xbd'],
        'application/vnd.fuzzysheet' => ['fzs'],
        'application/vnd.genomatix.tuxedo' => ['txd'],
        'application/vnd.geo+json' => ['geojson', 'geo.json'],
        'application/vnd.geogebra.file' => ['ggb'],
        'application/vnd.geogebra.tool' => ['ggt'],
        'application/vnd.geometry-explorer' => ['gex', 'gre'],
        'application/vnd.geonext' => ['gxt'],
        'application/vnd.geoplan' => ['g2w'],
        'application/vnd.geospace' => ['g3w'],
        'application/vnd.gmx' => ['gmx'],
        'application/vnd.google-earth.kml+xml' => ['kml'],
        'application/vnd.google-earth.kmz' => ['kmz'],
        'application/vnd.grafeq' => ['gqf', 'gqs'],
        'application/vnd.groove-account' => ['gac'],
        'application/vnd.groove-help' => ['ghf'],
        'application/vnd.groove-identity-message' => ['gim'],
        'application/vnd.groove-injector' => ['grv'],
        'application/vnd.groove-tool-message' => ['gtm'],
        'application/vnd.groove-tool-template' => ['tpl'],
        'application/vnd.groove-vcard' => ['vcg'],
        'application/vnd.haansoft-hwp' => ['hwp'],
        'application/vnd.haansoft-hwt' => ['hwt'],
        'application/vnd.hal+xml' => ['hal'],
        'application/vnd.handheld-entertainment+xml' => ['zmm'],
        'application/vnd.hbci' => ['hbci'],
        'application/vnd.hhe.lesson-player' => ['les'],
        'application/vnd.hp-hpgl' => ['hpgl'],
        'application/vnd.hp-hpid' => ['hpid'],
        'application/vnd.hp-hps' => ['hps'],
        'application/vnd.hp-jlyt' => ['jlt'],
        'application/vnd.hp-pcl' => ['pcl'],
        'application/vnd.hp-pclxl' => ['pclxl'],
        'application/vnd.hydrostatix.sof-data' => ['sfd-hdstx'],
        'application/vnd.ibm.minipay' => ['mpy'],
        'application/vnd.ibm.modcap' => ['afp', 'listafp', 'list3820'],
        'application/vnd.ibm.rights-management' => ['irm'],
        'application/vnd.ibm.secure-container' => ['sc'],
        'application/vnd.iccprofile' => ['icc', 'icm'],
        'application/vnd.igloader' => ['igl'],
        'application/vnd.immervision-ivp' => ['ivp'],
        'application/vnd.immervision-ivu' => ['ivu'],
        'application/vnd.insors.igm' => ['igm'],
        'application/vnd.intercon.formnet' => ['xpw', 'xpx'],
        'application/vnd.intergeo' => ['i2g'],
        'application/vnd.intu.qbo' => ['qbo'],
        'application/vnd.intu.qfx' => ['qfx'],
        'application/vnd.ipunplugged.rcprofile' => ['rcprofile'],
        'application/vnd.irepository.package+xml' => ['irp'],
        'application/vnd.is-xpr' => ['xpr'],
        'application/vnd.isac.fcs' => ['fcs'],
        'application/vnd.jam' => ['jam'],
        'application/vnd.jcp.javame.midlet-rms' => ['rms'],
        'application/vnd.jisp' => ['jisp'],
        'application/vnd.joost.joda-archive' => ['joda'],
        'application/vnd.kahootz' => ['ktz', 'ktr'],
        'application/vnd.kde.karbon' => ['karbon'],
        'application/vnd.kde.kchart' => ['chrt'],
        'application/vnd.kde.kformula' => ['kfo'],
        'application/vnd.kde.kivio' => ['flw'],
        'application/vnd.kde.kontour' => ['kon'],
        'application/vnd.kde.kpresenter' => ['kpr', 'kpt'],
        'application/vnd.kde.kspread' => ['ksp'],
        'application/vnd.kde.kword' => ['kwd', 'kwt'],
        'application/vnd.kenameaapp' => ['htke'],
        'application/vnd.kidspiration' => ['kia'],
        'application/vnd.kinar' => ['kne', 'knp'],
        'application/vnd.koan' => ['skp', 'skd', 'skt', 'skm'],
        'application/vnd.kodak-descriptor' => ['sse'],
        'application/vnd.las.las+xml' => ['lasxml'],
        'application/vnd.llamagraphics.life-balance.desktop' => ['lbd'],
        'application/vnd.llamagraphics.life-balance.exchange+xml' => ['lbe'],
        'application/vnd.lotus-1-2-3' => ['123', 'wk1', 'wk3', 'wk4', 'wks'],
        'application/vnd.lotus-approach' => ['apr'],
        'application/vnd.lotus-freelance' => ['pre'],
        'application/vnd.lotus-notes' => ['nsf'],
        'application/vnd.lotus-organizer' => ['org'],
        'application/vnd.lotus-screencam' => ['scm'],
        'application/vnd.lotus-wordpro' => ['lwp'],
        'application/vnd.macports.portpkg' => ['portpkg'],
        'application/vnd.mcd' => ['mcd'],
        'application/vnd.medcalcdata' => ['mc1'],
        'application/vnd.mediastation.cdkey' => ['cdkey'],
        'application/vnd.mfer' => ['mwf'],
        'application/vnd.mfmp' => ['mfm'],
        'application/vnd.micrografx.flo' => ['flo'],
        'application/vnd.micrografx.igx' => ['igx'],
        'application/vnd.mif' => ['mif'],
        'application/vnd.mobius.daf' => ['daf'],
        'application/vnd.mobius.dis' => ['dis'],
        'application/vnd.mobius.mbk' => ['mbk'],
        'application/vnd.mobius.mqy' => ['mqy'],
        'application/vnd.mobius.msl' => ['msl'],
        'application/vnd.mobius.plc' => ['plc'],
        'application/vnd.mobius.txf' => ['txf'],
        'application/vnd.mophun.application' => ['mpn'],
        'application/vnd.mophun.certificate' => ['mpc'],
        'application/vnd.mozilla.xul+xml' => ['xul'],
        'application/vnd.ms-access' => ['mdb'],
        'application/vnd.ms-artgalry' => ['cil'],
        'application/vnd.ms-asf' => ['asf'],
        'application/vnd.ms-cab-compressed' => ['cab'],
        'application/vnd.ms-excel' => ['xls', 'xlm', 'xla', 'xlc', 'xlt', 'xlw', 'xll', 'xld'],
        'application/vnd.ms-excel.addin.macroenabled.12' => ['xlam'],
        'application/vnd.ms-excel.sheet.binary.macroenabled.12' => ['xlsb'],
        'application/vnd.ms-excel.sheet.macroenabled.12' => ['xlsm'],
        'application/vnd.ms-excel.template.macroenabled.12' => ['xltm'],
        'application/vnd.ms-fontobject' => ['eot'],
        'application/vnd.ms-htmlhelp' => ['chm'],
        'application/vnd.ms-ims' => ['ims'],
        'application/vnd.ms-lrm' => ['lrm'],
        'application/vnd.ms-officetheme' => ['thmx'],
        'application/vnd.ms-outlook' => ['msg'],
        'application/vnd.ms-pki.seccat' => ['cat'],
        'application/vnd.ms-pki.stl' => ['stl'],
        'application/vnd.ms-powerpoint' => ['ppt', 'pps', 'pot', 'ppz'],
        'application/vnd.ms-powerpoint.addin.macroenabled.12' => ['ppam'],
        'application/vnd.ms-powerpoint.presentation.macroenabled.12' => ['pptm'],
        'application/vnd.ms-powerpoint.slide.macroenabled.12' => ['sldm'],
        'application/vnd.ms-powerpoint.slideshow.macroenabled.12' => ['ppsm'],
        'application/vnd.ms-powerpoint.template.macroenabled.12' => ['potm'],
        'application/vnd.ms-project' => ['mpp', 'mpt'],
        'application/vnd.ms-publisher' => ['pub'],
        'application/vnd.ms-tnef' => ['tnef', 'tnf'],
        'application/vnd.ms-visio.drawing.macroenabled.main+xml' => ['vsdm'],
        'application/vnd.ms-visio.drawing.main+xml' => ['vsdx'],
        'application/vnd.ms-visio.stencil.macroenabled.main+xml' => ['vssm'],
        'application/vnd.ms-visio.stencil.main+xml' => ['vssx'],
        'application/vnd.ms-visio.template.macroenabled.main+xml' => ['vstm'],
        'application/vnd.ms-visio.template.main+xml' => ['vstx'],
        'application/vnd.ms-word' => ['doc'],
        'application/vnd.ms-word.document.macroenabled.12' => ['docm'],
        'application/vnd.ms-word.template.macroenabled.12' => ['dotm'],
        'application/vnd.ms-works' => ['wps', 'wks', 'wcm', 'wdb', 'xlr'],
        'application/vnd.ms-wpl' => ['wpl'],
        'application/vnd.ms-xpsdocument' => ['xps', 'oxps'],
        'application/vnd.msaccess' => ['mdb'],
        'application/vnd.mseq' => ['mseq'],
        'application/vnd.musician' => ['mus'],
        'application/vnd.muvee.style' => ['msty'],
        'application/vnd.mynfc' => ['taglet'],
        'application/vnd.neurolanguage.nlu' => ['nlu'],
        'application/vnd.nintendo.snes.rom' => ['sfc', 'smc'],
        'application/vnd.nitf' => ['ntf', 'nitf'],
        'application/vnd.noblenet-directory' => ['nnd'],
        'application/vnd.noblenet-sealer' => ['nns'],
        'application/vnd.noblenet-web' => ['nnw'],
        'application/vnd.nokia.n-gage.data' => ['ngdat'],
        'application/vnd.nokia.n-gage.symbian.install' => ['n-gage'],
        'application/vnd.nokia.radio-preset' => ['rpst'],
        'application/vnd.nokia.radio-presets' => ['rpss'],
        'application/vnd.novadigm.edm' => ['edm'],
        'application/vnd.novadigm.edx' => ['edx'],
        'application/vnd.novadigm.ext' => ['ext'],
        'application/vnd.oasis.docbook+xml' => ['dbk', 'docbook'],
        'application/vnd.oasis.opendocument.chart' => ['odc'],
        'application/vnd.oasis.opendocument.chart-template' => ['otc'],
        'application/vnd.oasis.opendocument.database' => ['odb'],
        'application/vnd.oasis.opendocument.formula' => ['odf'],
        'application/vnd.oasis.opendocument.formula-template' => ['odft', 'otf'],
        'application/vnd.oasis.opendocument.graphics' => ['odg'],
        'application/vnd.oasis.opendocument.graphics-flat-xml' => ['fodg'],
        'application/vnd.oasis.opendocument.graphics-template' => ['otg'],
        'application/vnd.oasis.opendocument.image' => ['odi'],
        'application/vnd.oasis.opendocument.image-template' => ['oti'],
        'application/vnd.oasis.opendocument.presentation' => ['odp'],
        'application/vnd.oasis.opendocument.presentation-flat-xml' => ['fodp'],
        'application/vnd.oasis.opendocument.presentation-template' => ['otp'],
        'application/vnd.oasis.opendocument.spreadsheet' => ['ods'],
        'application/vnd.oasis.opendocument.spreadsheet-flat-xml' => ['fods'],
        'application/vnd.oasis.opendocument.spreadsheet-template' => ['ots'],
        'application/vnd.oasis.opendocument.text' => ['odt'],
        'application/vnd.oasis.opendocument.text-flat-xml' => ['fodt'],
        'application/vnd.oasis.opendocument.text-master' => ['odm'],
        'application/vnd.oasis.opendocument.text-template' => ['ott'],
        'application/vnd.oasis.opendocument.text-web' => ['oth'],
        'application/vnd.olpc-sugar' => ['xo'],
        'application/vnd.oma.dd2+xml' => ['dd2'],
        'application/vnd.openofficeorg.extension' => ['oxt'],
        'application/vnd.openxmlformats-officedocument.presentationml.presentation' => ['pptx'],
        'application/vnd.openxmlformats-officedocument.presentationml.slide' => ['sldx'],
        'application/vnd.openxmlformats-officedocument.presentationml.slideshow' => ['ppsx'],
        'application/vnd.openxmlformats-officedocument.presentationml.template' => ['potx'],
        'application/vnd.openxmlformats-officedocument.spreadsheetml.sheet' => ['xlsx'],
        'application/vnd.openxmlformats-officedocument.spreadsheetml.template' => ['xltx'],
        'application/vnd.openxmlformats-officedocument.wordprocessingml.document' => ['docx'],
        'application/vnd.openxmlformats-officedocument.wordprocessingml.template' => ['dotx'],
        'application/vnd.osgeo.mapguide.package' => ['mgp'],
        'application/vnd.osgi.dp' => ['dp'],
        'application/vnd.osgi.subsystem' => ['esa'],
        'application/vnd.palm' => ['pdb', 'pqa', 'oprc', 'prc'],
        'application/vnd.pawaafile' => ['paw'],
        'application/vnd.pg.format' => ['str'],
        'application/vnd.pg.osasli' => ['ei6'],
        'application/vnd.picsel' => ['efif'],
        'application/vnd.pmi.widget' => ['wg'],
        'application/vnd.pocketlearn' => ['plf'],
        'application/vnd.powerbuilder6' => ['pbd'],
        'application/vnd.previewsystems.box' => ['box'],
        'application/vnd.proteus.magazine' => ['mgz'],
        'application/vnd.publishare-delta-tree' => ['qps'],
        'application/vnd.pvi.ptid1' => ['ptid'],
        'application/vnd.quark.quarkxpress' => ['qxd', 'qxt', 'qwd', 'qwt', 'qxl', 'qxb'],
        'application/vnd.rar' => ['rar'],
        'application/vnd.realvnc.bed' => ['bed'],
        'application/vnd.recordare.musicxml' => ['mxl'],
        'application/vnd.recordare.musicxml+xml' => ['musicxml'],
        'application/vnd.rig.cryptonote' => ['cryptonote'],
        'application/vnd.rim.cod' => ['cod'],
        'application/vnd.rn-realmedia' => ['rm', 'rmj', 'rmm', 'rms', 'rmx', 'rmvb'],
        'application/vnd.rn-realmedia-vbr' => ['rmvb', 'rm', 'rmj', 'rmm', 'rms', 'rmx'],
        'application/vnd.route66.link66+xml' => ['link66'],
        'application/vnd.sailingtracker.track' => ['st'],
        'application/vnd.sdp' => ['sdp'],
        'application/vnd.seemail' => ['see'],
        'application/vnd.sema' => ['sema'],
        'application/vnd.semd' => ['semd'],
        'application/vnd.semf' => ['semf'],
        'application/vnd.shana.informed.formdata' => ['ifm'],
        'application/vnd.shana.informed.formtemplate' => ['itp'],
        'application/vnd.shana.informed.interchange' => ['iif'],
        'application/vnd.shana.informed.package' => ['ipk'],
        'application/vnd.simtech-mindmapper' => ['twd', 'twds'],
        'application/vnd.smaf' => ['mmf', 'smaf'],
        'application/vnd.smart.teacher' => ['teacher'],
        'application/vnd.snap' => ['snap'],
        'application/vnd.solent.sdkm+xml' => ['sdkm', 'sdkd'],
        'application/vnd.spotfire.dxp' => ['dxp'],
        'application/vnd.spotfire.sfs' => ['sfs'],
        'application/vnd.sqlite3' => ['sqlite3'],
        'application/vnd.squashfs' => ['sqsh'],
        'application/vnd.stardivision.calc' => ['sdc'],
        'application/vnd.stardivision.chart' => ['sds'],
        'application/vnd.stardivision.draw' => ['sda'],
        'application/vnd.stardivision.impress' => ['sdd', 'sdp'],
        'application/vnd.stardivision.mail' => ['smd'],
        'application/vnd.stardivision.math' => ['smf'],
        'application/vnd.stardivision.writer' => ['sdw', 'vor', 'sgl'],
        'application/vnd.stardivision.writer-global' => ['sgl', 'sdw', 'vor'],
        'application/vnd.stepmania.package' => ['smzip'],
        'application/vnd.stepmania.stepchart' => ['sm'],
        'application/vnd.sun.xml.base' => ['odb'],
        'application/vnd.sun.xml.calc' => ['sxc'],
        'application/vnd.sun.xml.calc.template' => ['stc'],
        'application/vnd.sun.xml.draw' => ['sxd'],
        'application/vnd.sun.xml.draw.template' => ['std'],
        'application/vnd.sun.xml.impress' => ['sxi'],
        'application/vnd.sun.xml.impress.template' => ['sti'],
        'application/vnd.sun.xml.math' => ['sxm'],
        'application/vnd.sun.xml.writer' => ['sxw'],
        'application/vnd.sun.xml.writer.global' => ['sxg'],
        'application/vnd.sun.xml.writer.template' => ['stw'],
        'application/vnd.sus-calendar' => ['sus', 'susp'],
        'application/vnd.svd' => ['svd'],
        'application/vnd.symbian.install' => ['sis', 'sisx'],
        'application/vnd.syncml+xml' => ['xsm'],
        'application/vnd.syncml.dm+wbxml' => ['bdm'],
        'application/vnd.syncml.dm+xml' => ['xdm'],
        'application/vnd.tao.intent-module-archive' => ['tao'],
        'application/vnd.tcpdump.pcap' => ['pcap', 'cap', 'dmp'],
        'application/vnd.tmobile-livetv' => ['tmo'],
        'application/vnd.trid.tpt' => ['tpt'],
        'application/vnd.triscape.mxs' => ['mxs'],
        'application/vnd.trueapp' => ['tra'],
        'application/vnd.ufdl' => ['ufd', 'ufdl'],
        'application/vnd.uiq.theme' => ['utz'],
        'application/vnd.umajin' => ['umj'],
        'application/vnd.unity' => ['unityweb'],
        'application/vnd.uoml+xml' => ['uoml'],
        'application/vnd.vcx' => ['vcx'],
        'application/vnd.visio' => ['vsd', 'vst', 'vss', 'vsw'],
        'application/vnd.visionary' => ['vis'],
        'application/vnd.vsf' => ['vsf'],
        'application/vnd.wap.wbxml' => ['wbxml'],
        'application/vnd.wap.wmlc' => ['wmlc'],
        'application/vnd.wap.wmlscriptc' => ['wmlsc'],
        'application/vnd.webturbo' => ['wtb'],
        'application/vnd.wolfram.player' => ['nbp'],
        'application/vnd.wordperfect' => ['wpd', 'wp', 'wp4', 'wp5', 'wp6', 'wpp'],
        'application/vnd.wqd' => ['wqd'],
        'application/vnd.wt.stf' => ['stf'],
        'application/vnd.xara' => ['xar'],
        'application/vnd.xdgapp' => ['flatpak', 'xdgapp'],
        'application/vnd.xfdl' => ['xfdl'],
        'application/vnd.yamaha.hv-dic' => ['hvd'],
        'application/vnd.yamaha.hv-script' => ['hvs'],
        'application/vnd.yamaha.hv-voice' => ['hvp'],
        'application/vnd.yamaha.openscoreformat' => ['osf'],
        'application/vnd.yamaha.openscoreformat.osfpvg+xml' => ['osfpvg'],
        'application/vnd.yamaha.smaf-audio' => ['saf'],
        'application/vnd.yamaha.smaf-phrase' => ['spf'],
        'application/vnd.yellowriver-custom-menu' => ['cmp'],
        'application/vnd.youtube.yt' => ['yt'],
        'application/vnd.zul' => ['zir', 'zirz'],
        'application/vnd.zzazz.deck+xml' => ['zaz'],
        'application/voicexml+xml' => ['vxml'],
        'application/widget' => ['wgt'],
        'application/winhlp' => ['hlp'],
        'application/wk1' => ['123', 'wk1', 'wk3', 'wk4', 'wks'],
        'application/wmf' => ['wmf'],
        'application/wordperfect' => ['wp', 'wp4', 'wp5', 'wp6', 'wpd', 'wpp'],
        'application/wsdl+xml' => ['wsdl'],
        'application/wspolicy+xml' => ['wspolicy'],
        'application/wwf' => ['wwf'],
        'application/x-123' => ['123', 'wk1', 'wk3', 'wk4', 'wks'],
        'application/x-7z-compressed' => ['7z'],
        'application/x-abiword' => ['abw', 'abw.CRASHED', 'abw.gz', 'zabw'],
        'application/x-ace' => ['ace'],
        'application/x-ace-compressed' => ['ace'],
        'application/x-alz' => ['alz'],
        'application/x-amiga-disk-format' => ['adf'],
        'application/x-amipro' => ['sam'],
        'application/x-annodex' => ['anx'],
        'application/x-aportisdoc' => ['pdb', 'pdc'],
        'application/x-apple-diskimage' => ['dmg'],
        'application/x-applix-spreadsheet' => ['as'],
        'application/x-applix-word' => ['aw'],
        'application/x-archive' => ['a', 'ar'],
        'application/x-arj' => ['arj'],
        'application/x-asp' => ['asp'],
        'application/x-atari-2600-rom' => ['a26'],
        'application/x-atari-7800-rom' => ['a78'],
        'application/x-atari-lynx-rom' => ['lnx'],
        'application/x-authorware-bin' => ['aab', 'x32', 'u32', 'vox'],
        'application/x-authorware-map' => ['aam'],
        'application/x-authorware-seg' => ['aas'],
        'application/x-awk' => ['awk'],
        'application/x-bcpio' => ['bcpio'],
        'application/x-bittorrent' => ['torrent'],
        'application/x-blender' => ['blender', 'blend', 'BLEND'],
        'application/x-blorb' => ['blb', 'blorb'],
        'application/x-bsdiff' => ['bsdiff'],
        'application/x-bzdvi' => ['dvi.bz2'],
        'application/x-bzip' => ['bz', 'bz2'],
        'application/x-bzip-compressed-tar' => ['tar.bz2', 'tar.bz', 'tbz2', 'tbz', 'tb2'],
        'application/x-bzip2' => ['bz2', 'boz', 'bz'],
        'application/x-bzpdf' => ['pdf.bz2'],
        'application/x-bzpostscript' => ['ps.bz2'],
        'application/x-cb7' => ['cb7'],
        'application/x-cbr' => ['cbr', 'cba', 'cbt', 'cbz', 'cb7'],
        'application/x-cbt' => ['cbt'],
        'application/x-cbz' => ['cbz'],
        'application/x-ccmx' => ['ccmx'],
        'application/x-cd-image' => ['iso', 'iso9660'],
        'application/x-cdlink' => ['vcd'],
        'application/x-cdr' => ['cdr'],
        'application/x-cdrdao-toc' => ['toc'],
        'application/x-cfs-compressed' => ['cfs'],
        'application/x-chat' => ['chat'],
        'application/x-chess-pgn' => ['pgn'],
        'application/x-chm' => ['chm'],
        'application/x-cisco-vpn-settings' => ['pcf'],
        'application/x-compress' => ['Z'],
        'application/x-compressed-tar' => ['tar.gz', 'tgz'],
        'application/x-conference' => ['nsc'],
        'application/x-coreldraw' => ['cdr'],
        'application/x-cpio' => ['cpio'],
        'application/x-cpio-compressed' => ['cpio.gz'],
        'application/x-csh' => ['csh'],
        'application/x-cue' => ['cue'],
        'application/x-dar' => ['dar'],
        'application/x-dbase' => ['dbf'],
        'application/x-dbf' => ['dbf'],
        'application/x-dc-rom' => ['dc'],
        'application/x-deb' => ['deb', 'udeb'],
        'application/x-debian-package' => ['deb', 'udeb'],
        'application/x-designer' => ['ui'],
        'application/x-desktop' => ['desktop', 'kdelnk'],
        'application/x-dgc-compressed' => ['dgc'],
        'application/x-dia-diagram' => ['dia'],
        'application/x-dia-shape' => ['shape'],
        'application/x-director' => ['dir', 'dcr', 'dxr', 'cst', 'cct', 'cxt', 'w3d', 'fgd', 'swa'],
        'application/x-docbook+xml' => ['dbk', 'docbook'],
        'application/x-doom' => ['wad'],
        'application/x-doom-wad' => ['wad'],
        'application/x-dtbncx+xml' => ['ncx'],
        'application/x-dtbook+xml' => ['dtb'],
        'application/x-dtbresource+xml' => ['res'],
        'application/x-dvi' => ['dvi'],
        'application/x-e-theme' => ['etheme'],
        'application/x-egon' => ['egon'],
        'application/x-emf' => ['emf'],
        'application/x-envoy' => ['evy'],
        'application/x-eva' => ['eva'],
        'application/x-fd-file' => ['fd', 'qd'],
        'application/x-fds-disk' => ['fds'],
        'application/x-fictionbook' => ['fb2'],
        'application/x-fictionbook+xml' => ['fb2'],
        'application/x-flash-video' => ['flv'],
        'application/x-fluid' => ['fl'],
        'application/x-font-afm' => ['afm'],
        'application/x-font-bdf' => ['bdf'],
        'application/x-font-ghostscript' => ['gsf'],
        'application/x-font-linux-psf' => ['psf'],
        'application/x-font-otf' => ['otf'],
        'application/x-font-pcf' => ['pcf', 'pcf.Z', 'pcf.gz'],
        'application/x-font-snf' => ['snf'],
        'application/x-font-speedo' => ['spd'],
        'application/x-font-ttf' => ['ttf'],
        'application/x-font-ttx' => ['ttx'],
        'application/x-font-type1' => ['pfa', 'pfb', 'pfm', 'afm', 'gsf'],
        'application/x-font-woff' => ['woff'],
        'application/x-frame' => ['fm'],
        'application/x-freearc' => ['arc'],
        'application/x-futuresplash' => ['spl'],
        'application/x-gameboy-color-rom' => ['gbc', 'cgb'],
        'application/x-gameboy-rom' => ['gb', 'sgb'],
        'application/x-gamecube-iso-image' => ['iso'],
        'application/x-gamecube-rom' => ['iso'],
        'application/x-gamegear-rom' => ['gg'],
        'application/x-gba-rom' => ['gba', 'agb'],
        'application/x-gca-compressed' => ['gca'],
        'application/x-gedcom' => ['ged', 'gedcom'],
        'application/x-genesis-32x-rom' => ['32x', 'mdx'],
        'application/x-genesis-rom' => ['gen', 'smd'],
        'application/x-gettext' => ['po'],
        'application/x-gettext-translation' => ['gmo', 'mo'],
        'application/x-glade' => ['glade'],
        'application/x-glulx' => ['ulx'],
        'application/x-gnome-app-info' => ['desktop', 'kdelnk'],
        'application/x-gnucash' => ['gnucash', 'gnc', 'xac'],
        'application/x-gnumeric' => ['gnumeric'],
        'application/x-gnuplot' => ['gp', 'gplt', 'gnuplot'],
        'application/x-go-sgf' => ['sgf'],
        'application/x-gpx' => ['gpx'],
        'application/x-gpx+xml' => ['gpx'],
        'application/x-gramps-xml' => ['gramps'],
        'application/x-graphite' => ['gra'],
        'application/x-gtar' => ['gtar', 'tar', 'gem'],
        'application/x-gtk-builder' => ['ui'],
        'application/x-gz-font-linux-psf' => ['psf.gz'],
        'application/x-gzdvi' => ['dvi.gz'],
        'application/x-gzip' => ['gz'],
        'application/x-gzpdf' => ['pdf.gz'],
        'application/x-gzpostscript' => ['ps.gz'],
        'application/x-hdf' => ['hdf', 'hdf4', 'h4', 'hdf5', 'h5'],
        'application/x-hfe-file' => ['hfe'],
        'application/x-hfe-floppy-image' => ['hfe'],
        'application/x-hwp' => ['hwp'],
        'application/x-hwt' => ['hwt'],
        'application/x-ica' => ['ica'],
        'application/x-install-instructions' => ['install'],
        'application/x-ipynb+json' => ['ipynb'],
        'application/x-iso9660-appimage' => ['appimage'],
        'application/x-iso9660-image' => ['iso', 'iso9660'],
        'application/x-it87' => ['it87'],
        'application/x-iwork-keynote-sffkey' => ['key'],
        'application/x-jar' => ['jar'],
        'application/x-java' => ['class'],
        'application/x-java-archive' => ['jar'],
        'application/x-java-class' => ['class'],
        'application/x-java-jce-keystore' => ['jceks'],
        'application/x-java-jnlp-file' => ['jnlp'],
        'application/x-java-keystore' => ['jks', 'ks'],
        'application/x-java-pack200' => ['pack'],
        'application/x-java-vm' => ['class'],
        'application/x-javascript' => ['js', 'jsm', 'mjs'],
        'application/x-jbuilder-project' => ['jpr', 'jpx'],
        'application/x-karbon' => ['karbon'],
        'application/x-kchart' => ['chrt'],
        'application/x-kexi-connectiondata' => ['kexic'],
        'application/x-kexiproject-shortcut' => ['kexis'],
        'application/x-kexiproject-sqlite' => ['kexi'],
        'application/x-kexiproject-sqlite2' => ['kexi'],
        'application/x-kexiproject-sqlite3' => ['kexi'],
        'application/x-kformula' => ['kfo'],
        'application/x-killustrator' => ['kil'],
        'application/x-kivio' => ['flw'],
        'application/x-kontour' => ['kon'],
        'application/x-kpovmodeler' => ['kpm'],
        'application/x-kpresenter' => ['kpr', 'kpt'],
        'application/x-krita' => ['kra'],
        'application/x-kspread' => ['ksp'],
        'application/x-kugar' => ['kud'],
        'application/x-kword' => ['kwd', 'kwt'],
        'application/x-latex' => ['latex'],
        'application/x-lha' => ['lha', 'lzh'],
        'application/x-lhz' => ['lhz'],
        'application/x-linguist' => ['ts'],
        'application/x-lotus123' => ['123', 'wk1', 'wk3', 'wk4', 'wks'],
        'application/x-lrzip' => ['lrz'],
        'application/x-lrzip-compressed-tar' => ['tar.lrz', 'tlrz'],
        'application/x-lyx' => ['lyx'],
        'application/x-lz4' => ['lz4'],
        'application/x-lz4-compressed-tar' => ['tar.lz4'],
        'application/x-lzh-compressed' => ['lzh', 'lha'],
        'application/x-lzip' => ['lz'],
        'application/x-lzip-compressed-tar' => ['tar.lz'],
        'application/x-lzma' => ['lzma'],
        'application/x-lzma-compressed-tar' => ['tar.lzma', 'tlz'],
        'application/x-lzop' => ['lzo'],
        'application/x-lzpdf' => ['pdf.lz'],
        'application/x-m4' => ['m4'],
        'application/x-magicpoint' => ['mgp'],
        'application/x-markaby' => ['mab'],
        'application/x-mathematica' => ['nb'],
        'application/x-mdb' => ['mdb'],
        'application/x-mie' => ['mie'],
        'application/x-mif' => ['mif'],
        'application/x-mimearchive' => ['mhtml', 'mht'],
        'application/x-mobipocket-ebook' => ['prc', 'mobi'],
        'application/x-ms-application' => ['application'],
        'application/x-ms-asx' => ['asx', 'wax', 'wvx', 'wmx'],
        'application/x-ms-dos-executable' => ['exe'],
        'application/x-ms-shortcut' => ['lnk'],
        'application/x-ms-wim' => ['wim', 'swm'],
        'application/x-ms-wmd' => ['wmd'],
        'application/x-ms-wmz' => ['wmz'],
        'application/x-ms-xbap' => ['xbap'],
        'application/x-msaccess' => ['mdb'],
        'application/x-msbinder' => ['obd'],
        'application/x-mscardfile' => ['crd'],
        'application/x-msclip' => ['clp'],
        'application/x-msdownload' => ['exe', 'dll', 'com', 'bat', 'msi'],
        'application/x-msexcel' => ['xls', 'xlc', 'xll', 'xlm', 'xlw', 'xla', 'xlt', 'xld'],
        'application/x-msi' => ['msi'],
        'application/x-msmediaview' => ['mvb', 'm13', 'm14'],
        'application/x-msmetafile' => ['wmf', 'wmz', 'emf', 'emz'],
        'application/x-msmoney' => ['mny'],
        'application/x-mspowerpoint' => ['ppz', 'ppt', 'pps', 'pot'],
        'application/x-mspublisher' => ['pub'],
        'application/x-msschedule' => ['scd'],
        'application/x-msterminal' => ['trm'],
        'application/x-mswinurl' => ['url'],
        'application/x-msword' => ['doc'],
        'application/x-mswrite' => ['wri'],
        'application/x-msx-rom' => ['msx'],
        'application/x-n64-rom' => ['n64', 'z64', 'v64'],
        'application/x-navi-animation' => ['ani'],
        'application/x-neo-geo-pocket-color-rom' => ['ngc'],
        'application/x-neo-geo-pocket-rom' => ['ngp'],
        'application/x-nes-rom' => ['nes', 'nez', 'unf', 'unif'],
        'application/x-netcdf' => ['nc', 'cdf'],
        'application/x-netshow-channel' => ['nsc'],
        'application/x-nintendo-ds-rom' => ['nds'],
        'application/x-nzb' => ['nzb'],
        'application/x-object' => ['o'],
        'application/x-ogg' => ['ogx'],
        'application/x-oleo' => ['oleo'],
        'application/x-pagemaker' => ['p65', 'pm', 'pm6', 'pmd'],
        'application/x-pak' => ['pak'],
        'application/x-palm-database' => ['prc', 'pdb', 'pqa', 'oprc'],
        'application/x-par2' => ['PAR2', 'par2'],
        'application/x-partial-download' => ['wkdownload', 'crdownload', 'part'],
        'application/x-pc-engine-rom' => ['pce'],
        'application/x-pcap' => ['pcap', 'cap', 'dmp'],
        'application/x-pdf' => ['pdf'],
        'application/x-perl' => ['pl', 'PL', 'pm', 'al', 'perl', 'pod', 't'],
        'application/x-photoshop' => ['psd'],
        'application/x-php' => ['php', 'php3', 'php4', 'php5', 'phps'],
        'application/x-pkcs12' => ['p12', 'pfx'],
        'application/x-pkcs7-certificates' => ['p7b', 'spc'],
        'application/x-pkcs7-certreqresp' => ['p7r'],
        'application/x-planperfect' => ['pln'],
        'application/x-pocket-word' => ['psw'],
        'application/x-pw' => ['pw'],
        'application/x-python-bytecode' => ['pyc', 'pyo'],
        'application/x-qpress' => ['qp'],
        'application/x-qtiplot' => ['qti', 'qti.gz'],
        'application/x-quattropro' => ['wb1', 'wb2', 'wb3'],
        'application/x-quicktime-media-link' => ['qtl'],
        'application/x-quicktimeplayer' => ['qtl'],
        'application/x-qw' => ['qif'],
        'application/x-rar' => ['rar'],
        'application/x-rar-compressed' => ['rar'],
        'application/x-raw-disk-image' => ['raw-disk-image', 'img'],
        'application/x-raw-disk-image-xz-compressed' => ['raw-disk-image.xz', 'img.xz'],
        'application/x-raw-floppy-disk-image' => ['fd', 'qd'],
        'application/x-redhat-package-manager' => ['rpm'],
        'application/x-reject' => ['rej'],
        'application/x-research-info-systems' => ['ris'],
        'application/x-rnc' => ['rnc'],
        'application/x-rpm' => ['rpm'],
        'application/x-ruby' => ['rb'],
        'application/x-sami' => ['smi', 'sami'],
        'application/x-sap-file' => ['sap'],
        'application/x-saturn-rom' => ['bin', 'iso'],
        'application/x-sdp' => ['sdp'],
        'application/x-sega-cd-rom' => ['bin', 'iso'],
        'application/x-sg1000-rom' => ['sg'],
        'application/x-sh' => ['sh'],
        'application/x-shar' => ['shar'],
        'application/x-shared-library-la' => ['la'],
        'application/x-sharedlib' => ['so'],
        'application/x-shellscript' => ['sh'],
        'application/x-shockwave-flash' => ['swf', 'spl'],
        'application/x-shorten' => ['shn'],
        'application/x-siag' => ['siag'],
        'application/x-silverlight-app' => ['xap'],
        'application/x-sit' => ['sit'],
        'application/x-smaf' => ['mmf', 'smaf'],
        'application/x-sms-rom' => ['sms'],
        'application/x-snes-rom' => ['sfc', 'smc'],
        'application/x-source-rpm' => ['src.rpm', 'spm'],
        'application/x-spss-por' => ['por'],
        'application/x-spss-sav' => ['sav', 'zsav'],
        'application/x-spss-savefile' => ['sav', 'zsav'],
        'application/x-sql' => ['sql'],
        'application/x-sqlite2' => ['sqlite2'],
        'application/x-sqlite3' => ['sqlite3'],
        'application/x-srt' => ['srt'],
        'application/x-stuffit' => ['sit'],
        'application/x-stuffitx' => ['sitx'],
        'application/x-subrip' => ['srt'],
        'application/x-sv4cpio' => ['sv4cpio'],
        'application/x-sv4crc' => ['sv4crc'],
        'application/x-t3vm-image' => ['t3'],
        'application/x-t602' => ['602'],
        'application/x-tads' => ['gam'],
        'application/x-tar' => ['tar', 'gtar', 'gem'],
        'application/x-tarz' => ['tar.Z', 'taz'],
        'application/x-tcl' => ['tcl'],
        'application/x-tex' => ['tex', 'ltx', 'sty', 'cls', 'dtx', 'ins', 'latex'],
        'application/x-tex-gf' => ['gf'],
        'application/x-tex-pk' => ['pk'],
        'application/x-tex-tfm' => ['tfm'],
        'application/x-texinfo' => ['texinfo', 'texi'],
        'application/x-tgif' => ['obj'],
        'application/x-theme' => ['theme'],
        'application/x-thomson-cartridge-memo7' => ['m7'],
        'application/x-thomson-cassette' => ['k7'],
        'application/x-thomson-sap-image' => ['sap'],
        'application/x-trash' => ['bak', 'old', 'sik'],
        'application/x-trig' => ['trig'],
        'application/x-troff' => ['tr', 'roff', 't'],
        'application/x-troff-man' => ['man'],
        'application/x-tzo' => ['tar.lzo', 'tzo'],
        'application/x-ufraw' => ['ufraw'],
        'application/x-ustar' => ['ustar'],
        'application/x-virtual-boy-rom' => ['vb'],
        'application/x-vnd.kde.kexi' => ['kexi'],
        'application/x-wais-source' => ['src'],
        'application/x-wbfs' => ['iso'],
        'application/x-wia' => ['iso'],
        'application/x-wii-iso-image' => ['iso'],
        'application/x-wii-rom' => ['iso'],
        'application/x-wii-wad' => ['wad'],
        'application/x-windows-themepack' => ['themepack'],
        'application/x-wmf' => ['wmf'],
        'application/x-wonderswan-color-rom' => ['wsc'],
        'application/x-wonderswan-rom' => ['ws'],
        'application/x-wordperfect' => ['wp', 'wp4', 'wp5', 'wp6', 'wpd', 'wpp'],
        'application/x-wpg' => ['wpg'],
        'application/x-wwf' => ['wwf'],
        'application/x-x509-ca-cert' => ['der', 'crt', 'cert', 'pem'],
        'application/x-xar' => ['xar', 'pkg'],
        'application/x-xbel' => ['xbel'],
        'application/x-xfig' => ['fig'],
        'application/x-xliff' => ['xlf', 'xliff'],
        'application/x-xliff+xml' => ['xlf'],
        'application/x-xpinstall' => ['xpi'],
        'application/x-xspf+xml' => ['xspf'],
        'application/x-xz' => ['xz'],
        'application/x-xz-compressed-tar' => ['tar.xz', 'txz'],
        'application/x-xzpdf' => ['pdf.xz'],
        'application/x-yaml' => ['yaml', 'yml'],
        'application/x-zip' => ['zip'],
        'application/x-zip-compressed' => ['zip'],
        'application/x-zip-compressed-fb2' => ['fb2.zip'],
        'application/x-zmachine' => ['z1', 'z2', 'z3', 'z4', 'z5', 'z6', 'z7', 'z8'],
        'application/x-zoo' => ['zoo'],
        'application/xaml+xml' => ['xaml'],
        'application/xcap-diff+xml' => ['xdf'],
        'application/xenc+xml' => ['xenc'],
        'application/xhtml+xml' => ['xhtml', 'xht'],
        'application/xliff+xml' => ['xlf', 'xliff'],
        'application/xml' => ['xml', 'xsl', 'xbl', 'xsd', 'rng'],
        'application/xml-dtd' => ['dtd'],
        'application/xml-external-parsed-entity' => ['ent'],
        'application/xop+xml' => ['xop'],
        'application/xproc+xml' => ['xpl'],
        'application/xps' => ['oxps', 'xps'],
        'application/xslt+xml' => ['xslt', 'xsl'],
        'application/xspf+xml' => ['xspf'],
        'application/xv+xml' => ['mxml', 'xhvml', 'xvml', 'xvm'],
        'application/yang' => ['yang'],
        'application/yin+xml' => ['yin'],
        'application/zip' => ['zip'],
        'application/zlib' => ['zz'],
        'audio/3gpp' => ['3gp', '3gpp', '3ga'],
        'audio/3gpp-encrypted' => ['3gp', '3gpp', '3ga'],
        'audio/3gpp2' => ['3g2', '3gp2', '3gpp2'],
        'audio/aac' => ['aac', 'adts', 'ass'],
        'audio/ac3' => ['ac3'],
        'audio/adpcm' => ['adp'],
        'audio/amr' => ['amr'],
        'audio/amr-encrypted' => ['amr'],
        'audio/amr-wb' => ['awb'],
        'audio/amr-wb-encrypted' => ['awb'],
        'audio/annodex' => ['axa'],
        'audio/basic' => ['au', 'snd'],
        'audio/flac' => ['flac'],
        'audio/imelody' => ['imy', 'ime'],
        'audio/m3u' => ['m3u', 'm3u8', 'vlc'],
        'audio/m4a' => ['m4a', 'f4a'],
        'audio/midi' => ['mid', 'midi', 'kar', 'rmi'],
        'audio/mobile-xmf' => ['xmf'],
        'audio/mp2' => ['mp2'],
        'audio/mp3' => ['mp3', 'mpga'],
        'audio/mp4' => ['m4a', 'mp4a', 'f4a'],
        'audio/mpeg' => ['mp3', 'mpga', 'mp2', 'mp2a', 'm2a', 'm3a'],
        'audio/mpegurl' => ['m3u', 'm3u8', 'vlc'],
        'audio/ogg' => ['oga', 'ogg', 'spx', 'opus'],
        'audio/prs.sid' => ['sid', 'psid'],
        'audio/s3m' => ['s3m'],
        'audio/scpls' => ['pls'],
        'audio/silk' => ['sil'],
        'audio/tta' => ['tta'],
        'audio/usac' => ['loas', 'xhe'],
        'audio/vnd.audible' => ['aa', 'aax'],
        'audio/vnd.audible.aax' => ['aa', 'aax'],
        'audio/vnd.dece.audio' => ['uva', 'uvva'],
        'audio/vnd.digital-winds' => ['eol'],
        'audio/vnd.dra' => ['dra'],
        'audio/vnd.dts' => ['dts'],
        'audio/vnd.dts.hd' => ['dtshd'],
        'audio/vnd.lucent.voice' => ['lvp'],
        'audio/vnd.m-realaudio' => ['ra', 'rax'],
        'audio/vnd.ms-playready.media.pya' => ['pya'],
        'audio/vnd.nuera.ecelp4800' => ['ecelp4800'],
        'audio/vnd.nuera.ecelp7470' => ['ecelp7470'],
        'audio/vnd.nuera.ecelp9600' => ['ecelp9600'],
        'audio/vnd.rip' => ['rip'],
        'audio/vnd.rn-realaudio' => ['ra', 'rax'],
        'audio/vnd.wave' => ['wav'],
        'audio/vorbis' => ['oga', 'ogg'],
        'audio/wav' => ['wav'],
        'audio/webm' => ['weba'],
        'audio/wma' => ['wma'],
        'audio/x-aac' => ['aac', 'adts', 'ass'],
        'audio/x-aifc' => ['aifc', 'aiffc'],
        'audio/x-aiff' => ['aif', 'aiff', 'aifc'],
        'audio/x-aiffc' => ['aifc', 'aiffc'],
        'audio/x-amzxml' => ['amz'],
        'audio/x-annodex' => ['axa'],
        'audio/x-ape' => ['ape'],
        'audio/x-caf' => ['caf'],
        'audio/x-dts' => ['dts'],
        'audio/x-dtshd' => ['dtshd'],
        'audio/x-flac' => ['flac'],
        'audio/x-flac+ogg' => ['oga', 'ogg'],
        'audio/x-gsm' => ['gsm'],
        'audio/x-hx-aac-adts' => ['aac', 'adts', 'ass'],
        'audio/x-imelody' => ['imy', 'ime'],
        'audio/x-iriver-pla' => ['pla'],
        'audio/x-it' => ['it'],
        'audio/x-m3u' => ['m3u', 'm3u8', 'vlc'],
        'audio/x-m4a' => ['m4a', 'f4a'],
        'audio/x-m4b' => ['m4b', 'f4b'],
        'audio/x-m4r' => ['m4r'],
        'audio/x-matroska' => ['mka'],
        'audio/x-midi' => ['mid', 'midi', 'kar'],
        'audio/x-minipsf' => ['minipsf'],
        'audio/x-mo3' => ['mo3'],
        'audio/x-mod' => ['mod', 'ult', 'uni', 'm15', 'mtm', '669', 'med'],
        'audio/x-mp2' => ['mp2'],
        'audio/x-mp3' => ['mp3', 'mpga'],
        'audio/x-mp3-playlist' => ['m3u', 'm3u8', 'vlc'],
        'audio/x-mpeg' => ['mp3', 'mpga'],
        'audio/x-mpegurl' => ['m3u', 'm3u8', 'vlc'],
        'audio/x-mpg' => ['mp3', 'mpga'],
        'audio/x-ms-asx' => ['asx', 'wax', 'wvx', 'wmx'],
        'audio/x-ms-wax' => ['wax'],
        'audio/x-ms-wma' => ['wma'],
        'audio/x-musepack' => ['mpc', 'mpp', 'mp+'],
        'audio/x-ogg' => ['oga', 'ogg', 'opus'],
        'audio/x-oggflac' => ['oga', 'ogg'],
        'audio/x-opus+ogg' => ['opus'],
        'audio/x-pn-audibleaudio' => ['aa', 'aax'],
        'audio/x-pn-realaudio' => ['ram', 'ra', 'rax'],
        'audio/x-pn-realaudio-plugin' => ['rmp'],
        'audio/x-psf' => ['psf'],
        'audio/x-psflib' => ['psflib'],
        'audio/x-rn-3gpp-amr' => ['3gp', '3gpp', '3ga'],
        'audio/x-rn-3gpp-amr-encrypted' => ['3gp', '3gpp', '3ga'],
        'audio/x-rn-3gpp-amr-wb' => ['3gp', '3gpp', '3ga'],
        'audio/x-rn-3gpp-amr-wb-encrypted' => ['3gp', '3gpp', '3ga'],
        'audio/x-s3m' => ['s3m'],
        'audio/x-scpls' => ['pls'],
        'audio/x-shorten' => ['shn'],
        'audio/x-speex' => ['spx'],
        'audio/x-speex+ogg' => ['oga', 'ogg'],
        'audio/x-stm' => ['stm'],
        'audio/x-tta' => ['tta'],
        'audio/x-voc' => ['voc'],
        'audio/x-vorbis' => ['oga', 'ogg'],
        'audio/x-vorbis+ogg' => ['oga', 'ogg'],
        'audio/x-wav' => ['wav'],
        'audio/x-wavpack' => ['wv', 'wvp'],
        'audio/x-wavpack-correction' => ['wvc'],
        'audio/x-xi' => ['xi'],
        'audio/x-xm' => ['xm'],
        'audio/x-xmf' => ['xmf'],
        'audio/xm' => ['xm'],
        'audio/xmf' => ['xmf'],
        'chemical/x-cdx' => ['cdx'],
        'chemical/x-cif' => ['cif'],
        'chemical/x-cmdf' => ['cmdf'],
        'chemical/x-cml' => ['cml'],
        'chemical/x-csml' => ['csml'],
        'chemical/x-xyz' => ['xyz'],
        'flv-application/octet-stream' => ['flv'],
        'font/collection' => ['ttc'],
        'font/otf' => ['otf'],
        'font/ttf' => ['ttf'],
        'font/woff' => ['woff', 'woff2'],
        'font/woff2' => ['woff2'],
        'image/bmp' => ['bmp', 'dib'],
        'image/cdr' => ['cdr'],
        'image/cgm' => ['cgm'],
        'image/emf' => ['emf'],
        'image/fax-g3' => ['g3'],
        'image/fits' => ['fits'],
        'image/g3fax' => ['g3'],
        'image/gif' => ['gif'],
        'image/heic' => ['heic', 'heif'],
        'image/heic-sequence' => ['heic', 'heif'],
        'image/heif' => ['heic', 'heif'],
        'image/heif-sequence' => ['heic', 'heif'],
        'image/ico' => ['ico'],
        'image/icon' => ['ico'],
        'image/ief' => ['ief'],
        'image/jp2' => ['jp2', 'jpg2'],
        'image/jpeg' => ['jpeg', 'jpg', 'jpe'],
        'image/jpeg2000' => ['jp2', 'jpg2'],
        'image/jpeg2000-image' => ['jp2', 'jpg2'],
        'image/jpm' => ['jpm', 'jpgm'],
        'image/jpx' => ['jpf', 'jpx'],
        'image/ktx' => ['ktx'],
        'image/openraster' => ['ora'],
        'image/pdf' => ['pdf'],
        'image/photoshop' => ['psd'],
        'image/pjpeg' => ['jpeg', 'jpg', 'jpe'],
        'image/png' => ['png'],
        'image/prs.btif' => ['btif'],
        'image/psd' => ['psd'],
        'image/rle' => ['rle'],
        'image/sgi' => ['sgi'],
        'image/svg' => ['svg'],
        'image/svg+xml' => ['svg', 'svgz'],
        'image/svg+xml-compressed' => ['svgz'],
        'image/tiff' => ['tiff', 'tif'],
        'image/vnd.adobe.photoshop' => ['psd'],
        'image/vnd.dece.graphic' => ['uvi', 'uvvi', 'uvg', 'uvvg'],
        'image/vnd.djvu' => ['djvu', 'djv'],
        'image/vnd.djvu+multipage' => ['djvu', 'djv'],
        'image/vnd.dvb.subtitle' => ['sub'],
        'image/vnd.dwg' => ['dwg'],
        'image/vnd.dxf' => ['dxf'],
        'image/vnd.fastbidsheet' => ['fbs'],
        'image/vnd.fpx' => ['fpx'],
        'image/vnd.fst' => ['fst'],
        'image/vnd.fujixerox.edmics-mmr' => ['mmr'],
        'image/vnd.fujixerox.edmics-rlc' => ['rlc'],
        'image/vnd.microsoft.icon' => ['ico'],
        'image/vnd.ms-modi' => ['mdi'],
        'image/vnd.ms-photo' => ['wdp'],
        'image/vnd.net-fpx' => ['npx'],
        'image/vnd.rn-realpix' => ['rp'],
        'image/vnd.wap.wbmp' => ['wbmp'],
        'image/vnd.xiff' => ['xif'],
        'image/vnd.zbrush.pcx' => ['pcx'],
        'image/webp' => ['webp'],
        'image/wmf' => ['wmf'],
        'image/x-3ds' => ['3ds'],
        'image/x-adobe-dng' => ['dng'],
        'image/x-applix-graphics' => ['ag'],
        'image/x-bmp' => ['bmp', 'dib'],
        'image/x-bzeps' => ['eps.bz2', 'epsi.bz2', 'epsf.bz2'],
        'image/x-canon-cr2' => ['cr2'],
        'image/x-canon-crw' => ['crw'],
        'image/x-cdr' => ['cdr'],
        'image/x-cmu-raster' => ['ras'],
        'image/x-cmx' => ['cmx'],
        'image/x-compressed-xcf' => ['xcf.gz', 'xcf.bz2'],
        'image/x-dds' => ['dds'],
        'image/x-djvu' => ['djvu', 'djv'],
        'image/x-emf' => ['emf'],
        'image/x-eps' => ['eps', 'epsi', 'epsf'],
        'image/x-exr' => ['exr'],
        'image/x-fits' => ['fits'],
        'image/x-freehand' => ['fh', 'fhc', 'fh4', 'fh5', 'fh7'],
        'image/x-fuji-raf' => ['raf'],
        'image/x-gimp-gbr' => ['gbr'],
        'image/x-gimp-gih' => ['gih'],
        'image/x-gimp-pat' => ['pat'],
        'image/x-gzeps' => ['eps.gz', 'epsi.gz', 'epsf.gz'],
        'image/x-icb' => ['tga', 'icb', 'tpic', 'vda', 'vst'],
        'image/x-icns' => ['icns'],
        'image/x-ico' => ['ico'],
        'image/x-icon' => ['ico'],
        'image/x-iff' => ['iff', 'ilbm', 'lbm'],
        'image/x-ilbm' => ['iff', 'ilbm', 'lbm'],
        'image/x-jng' => ['jng'],
        'image/x-jp2-codestream' => ['j2c', 'j2k', 'jpc'],
        'image/x-jpeg2000-image' => ['jp2', 'jpg2'],
        'image/x-kodak-dcr' => ['dcr'],
        'image/x-kodak-k25' => ['k25'],
        'image/x-kodak-kdc' => ['kdc'],
        'image/x-lwo' => ['lwo', 'lwob'],
        'image/x-lws' => ['lws'],
        'image/x-macpaint' => ['pntg'],
        'image/x-minolta-mrw' => ['mrw'],
        'image/x-mrsid-image' => ['sid'],
        'image/x-ms-bmp' => ['bmp', 'dib'],
        'image/x-msod' => ['msod'],
        'image/x-nikon-nef' => ['nef'],
        'image/x-olympus-orf' => ['orf'],
        'image/x-panasonic-raw' => ['raw'],
        'image/x-panasonic-raw2' => ['rw2'],
        'image/x-panasonic-rw' => ['raw'],
        'image/x-panasonic-rw2' => ['rw2'],
        'image/x-pcx' => ['pcx'],
        'image/x-pentax-pef' => ['pef'],
        'image/x-photo-cd' => ['pcd'],
        'image/x-photoshop' => ['psd'],
        'image/x-pict' => ['pic', 'pct', 'pict', 'pict1', 'pict2'],
        'image/x-portable-anymap' => ['pnm'],
        'image/x-portable-bitmap' => ['pbm'],
        'image/x-portable-graymap' => ['pgm'],
        'image/x-portable-pixmap' => ['ppm'],
        'image/x-psd' => ['psd'],
        'image/x-quicktime' => ['qtif', 'qif'],
        'image/x-rgb' => ['rgb'],
        'image/x-sgi' => ['sgi'],
        'image/x-sigma-x3f' => ['x3f'],
        'image/x-skencil' => ['sk', 'sk1'],
        'image/x-sony-arw' => ['arw'],
        'image/x-sony-sr2' => ['sr2'],
        'image/x-sony-srf' => ['srf'],
        'image/x-sun-raster' => ['sun'],
        'image/x-tga' => ['tga', 'icb', 'tpic', 'vda', 'vst'],
        'image/x-win-bitmap' => ['cur'],
        'image/x-win-metafile' => ['wmf'],
        'image/x-wmf' => ['wmf'],
        'image/x-xbitmap' => ['xbm'],
        'image/x-xcf' => ['xcf'],
        'image/x-xfig' => ['fig'],
        'image/x-xpixmap' => ['xpm'],
        'image/x-xpm' => ['xpm'],
        'image/x-xwindowdump' => ['xwd'],
        'image/x.djvu' => ['djvu', 'djv'],
        'message/rfc822' => ['eml', 'mime'],
        'model/iges' => ['igs', 'iges'],
        'model/mesh' => ['msh', 'mesh', 'silo'],
        'model/stl' => ['stl'],
        'model/vnd.collada+xml' => ['dae'],
        'model/vnd.dwf' => ['dwf'],
        'model/vnd.gdl' => ['gdl'],
        'model/vnd.gtw' => ['gtw'],
        'model/vnd.mts' => ['mts'],
        'model/vnd.vtu' => ['vtu'],
        'model/vrml' => ['wrl', 'vrml', 'vrm'],
        'model/x.stl-ascii' => ['stl'],
        'model/x.stl-binary' => ['stl'],
        'model/x3d+binary' => ['x3db', 'x3dbz'],
        'model/x3d+vrml' => ['x3dv', 'x3dvz'],
        'model/x3d+xml' => ['x3d', 'x3dz'],
        'text/cache-manifest' => ['appcache', 'manifest'],
        'text/calendar' => ['ics', 'ifb', 'vcs'],
        'text/css' => ['css'],
        'text/csv' => ['csv'],
        'text/csv-schema' => ['csvs'],
        'text/directory' => ['vcard', 'vcf', 'vct', 'gcrd'],
        'text/ecmascript' => ['es'],
        'text/gedcom' => ['ged', 'gedcom'],
        'text/google-video-pointer' => ['gvp'],
        'text/html' => ['html', 'htm'],
        'text/ico' => ['ico'],
        'text/javascript' => ['js', 'jsm', 'mjs'],
        'text/markdown' => ['md', 'mkd', 'markdown'],
        'text/mathml' => ['mml'],
        'text/n3' => ['n3'],
        'text/plain' => ['txt', 'text', 'conf', 'def', 'list', 'log', 'in', 'asc'],
        'text/prs.lines.tag' => ['dsc'],
        'text/rdf' => ['rdf', 'rdfs', 'owl'],
        'text/richtext' => ['rtx'],
        'text/rss' => ['rss'],
        'text/rtf' => ['rtf'],
        'text/rust' => ['rs'],
        'text/sgml' => ['sgml', 'sgm'],
        'text/spreadsheet' => ['sylk', 'slk'],
        'text/tab-separated-values' => ['tsv'],
        'text/troff' => ['t', 'tr', 'roff', 'man', 'me', 'ms'],
        'text/turtle' => ['ttl'],
        'text/uri-list' => ['uri', 'uris', 'urls'],
        'text/vcard' => ['vcard', 'vcf', 'vct', 'gcrd'],
        'text/vnd.curl' => ['curl'],
        'text/vnd.curl.dcurl' => ['dcurl'],
        'text/vnd.curl.mcurl' => ['mcurl'],
        'text/vnd.curl.scurl' => ['scurl'],
        'text/vnd.dvb.subtitle' => ['sub'],
        'text/vnd.fly' => ['fly'],
        'text/vnd.fmi.flexstor' => ['flx'],
        'text/vnd.graphviz' => ['gv', 'dot'],
        'text/vnd.in3d.3dml' => ['3dml'],
        'text/vnd.in3d.spot' => ['spot'],
        'text/vnd.qt.linguist' => ['ts'],
        'text/vnd.rn-realtext' => ['rt'],
        'text/vnd.sun.j2me.app-descriptor' => ['jad'],
        'text/vnd.trolltech.linguist' => ['ts'],
        'text/vnd.wap.wml' => ['wml'],
        'text/vnd.wap.wmlscript' => ['wmls'],
        'text/vtt' => ['vtt'],
        'text/x-adasrc' => ['adb', 'ads'],
        'text/x-asm' => ['s', 'asm'],
        'text/x-bibtex' => ['bib'],
        'text/x-c' => ['c', 'cc', 'cxx', 'cpp', 'h', 'hh', 'dic'],
        'text/x-c++hdr' => ['hh', 'hp', 'hpp', 'h++', 'hxx'],
        'text/x-c++src' => ['cpp', 'cxx', 'cc', 'C', 'c++'],
        'text/x-chdr' => ['h'],
        'text/x-cmake' => ['cmake'],
        'text/x-cobol' => ['cbl', 'cob'],
        'text/x-comma-separated-values' => ['csv'],
        'text/x-csharp' => ['cs'],
        'text/x-csrc' => ['c'],
        'text/x-csv' => ['csv'],
        'text/x-dbus-service' => ['service'],
        'text/x-dcl' => ['dcl'],
        'text/x-diff' => ['diff', 'patch'],
        'text/x-dsl' => ['dsl'],
        'text/x-dsrc' => ['d', 'di'],
        'text/x-dtd' => ['dtd'],
        'text/x-eiffel' => ['e', 'eif'],
        'text/x-emacs-lisp' => ['el'],
        'text/x-erlang' => ['erl'],
        'text/x-fortran' => ['f', 'for', 'f77', 'f90', 'f95'],
        'text/x-genie' => ['gs'],
        'text/x-gettext-translation' => ['po'],
        'text/x-gettext-translation-template' => ['pot'],
        'text/x-gherkin' => ['feature'],
        'text/x-go' => ['go'],
        'text/x-google-video-pointer' => ['gvp'],
        'text/x-haskell' => ['hs'],
        'text/x-idl' => ['idl'],
        'text/x-imelody' => ['imy', 'ime'],
        'text/x-iptables' => ['iptables'],
        'text/x-java' => ['java'],
        'text/x-java-source' => ['java'],
        'text/x-ldif' => ['ldif'],
        'text/x-lilypond' => ['ly'],
        'text/x-literate-haskell' => ['lhs'],
        'text/x-log' => ['log'],
        'text/x-lua' => ['lua'],
        'text/x-lyx' => ['lyx'],
        'text/x-makefile' => ['mk', 'mak'],
        'text/x-markdown' => ['md', 'mkd', 'markdown'],
        'text/x-matlab' => ['m'],
        'text/x-microdvd' => ['sub'],
        'text/x-moc' => ['moc'],
        'text/x-modelica' => ['mo'],
        'text/x-mof' => ['mof'],
        'text/x-mpsub' => ['sub'],
        'text/x-mrml' => ['mrml', 'mrl'],
        'text/x-ms-regedit' => ['reg'],
        'text/x-mup' => ['mup', 'not'],
        'text/x-nfo' => ['nfo'],
        'text/x-objcsrc' => ['m'],
        'text/x-ocaml' => ['ml', 'mli'],
        'text/x-ocl' => ['ocl'],
        'text/x-octave' => ['m'],
        'text/x-ooc' => ['ooc'],
        'text/x-opencl-src' => ['cl'],
        'text/x-opml' => ['opml'],
        'text/x-opml+xml' => ['opml'],
        'text/x-pascal' => ['p', 'pas'],
        'text/x-patch' => ['diff', 'patch'],
        'text/x-perl' => ['pl', 'PL', 'pm', 'al', 'perl', 'pod', 't'],
        'text/x-po' => ['po'],
        'text/x-pot' => ['pot'],
        'text/x-python' => ['py', 'pyx', 'wsgi'],
        'text/x-python3' => ['py', 'py3', 'py3x'],
        'text/x-qml' => ['qml', 'qmltypes', 'qmlproject'],
        'text/x-reject' => ['rej'],
        'text/x-rpm-spec' => ['spec'],
        'text/x-sass' => ['sass'],
        'text/x-scala' => ['scala'],
        'text/x-scheme' => ['scm', 'ss'],
        'text/x-scss' => ['scss'],
        'text/x-setext' => ['etx'],
        'text/x-sfv' => ['sfv'],
        'text/x-sh' => ['sh'],
        'text/x-sql' => ['sql'],
        'text/x-ssa' => ['ssa', 'ass'],
        'text/x-subviewer' => ['sub'],
        'text/x-svhdr' => ['svh'],
        'text/x-svsrc' => ['sv'],
        'text/x-systemd-unit' => ['automount', 'device', 'mount', 'path', 'scope', 'service', 'slice', 'socket', 'swap', 'target', 'timer'],
        'text/x-tcl' => ['tcl', 'tk'],
        'text/x-tex' => ['tex', 'ltx', 'sty', 'cls', 'dtx', 'ins', 'latex'],
        'text/x-texinfo' => ['texi', 'texinfo'],
        'text/x-troff' => ['tr', 'roff', 't'],
        'text/x-troff-me' => ['me'],
        'text/x-troff-mm' => ['mm'],
        'text/x-troff-ms' => ['ms'],
        'text/x-twig' => ['twig'],
        'text/x-txt2tags' => ['t2t'],
        'text/x-uil' => ['uil'],
        'text/x-uuencode' => ['uu', 'uue'],
        'text/x-vala' => ['vala', 'vapi'],
        'text/x-vcalendar' => ['vcs', 'ics'],
        'text/x-vcard' => ['vcf', 'vcard', 'vct', 'gcrd'],
        'text/x-verilog' => ['v'],
        'text/x-vhdl' => ['vhd', 'vhdl'],
        'text/x-xmi' => ['xmi'],
        'text/x-xslfo' => ['fo', 'xslfo'],
        'text/x-yaml' => ['yaml', 'yml'],
        'text/x.gcode' => ['gcode'],
        'text/xml' => ['xml', 'xbl', 'xsd', 'rng'],
        'text/xml-external-parsed-entity' => ['ent'],
        'text/yaml' => ['yaml', 'yml'],
        'video/3gp' => ['3gp', '3gpp', '3ga'],
        'video/3gpp' => ['3gp', '3gpp', '3ga'],
        'video/3gpp-encrypted' => ['3gp', '3gpp', '3ga'],
        'video/3gpp2' => ['3g2', '3gp2', '3gpp2'],
        'video/annodex' => ['axv'],
        'video/avi' => ['avi', 'avf', 'divx'],
        'video/divx' => ['avi', 'avf', 'divx'],
        'video/dv' => ['dv'],
        'video/fli' => ['fli', 'flc'],
        'video/flv' => ['flv'],
        'video/h261' => ['h261'],
        'video/h263' => ['h263'],
        'video/h264' => ['h264'],
        'video/jpeg' => ['jpgv'],
        'video/jpm' => ['jpm', 'jpgm'],
        'video/mj2' => ['mj2', 'mjp2'],
        'video/mp2t' => ['m2t', 'm2ts', 'ts', 'mts', 'cpi', 'clpi', 'mpl', 'mpls', 'bdm', 'bdmv'],
        'video/mp4' => ['mp4', 'mp4v', 'mpg4', 'm4v', 'f4v', 'lrv'],
        'video/mp4v-es' => ['mp4', 'm4v', 'f4v', 'lrv'],
        'video/mpeg' => ['mpeg', 'mpg', 'mpe', 'm1v', 'm2v', 'mp2', 'vob'],
        'video/mpeg-system' => ['mpeg', 'mpg', 'mp2', 'mpe', 'vob'],
        'video/msvideo' => ['avi', 'avf', 'divx'],
        'video/ogg' => ['ogv', 'ogg'],
        'video/quicktime' => ['qt', 'mov', 'moov', 'qtvr'],
        'video/vivo' => ['viv', 'vivo'],
        'video/vnd.dece.hd' => ['uvh', 'uvvh'],
        'video/vnd.dece.mobile' => ['uvm', 'uvvm'],
        'video/vnd.dece.pd' => ['uvp', 'uvvp'],
        'video/vnd.dece.sd' => ['uvs', 'uvvs'],
        'video/vnd.dece.video' => ['uvv', 'uvvv'],
        'video/vnd.divx' => ['avi', 'avf', 'divx'],
        'video/vnd.dvb.file' => ['dvb'],
        'video/vnd.fvt' => ['fvt'],
        'video/vnd.mpegurl' => ['mxu', 'm4u', 'm1u'],
        'video/vnd.ms-playready.media.pyv' => ['pyv'],
        'video/vnd.rn-realvideo' => ['rv', 'rvx'],
        'video/vnd.uvvu.mp4' => ['uvu', 'uvvu'],
        'video/vnd.vivo' => ['viv', 'vivo'],
        'video/webm' => ['webm'],
        'video/x-anim' => ['anim[1-9j]'],
        'video/x-annodex' => ['axv'],
        'video/x-avi' => ['avi', 'avf', 'divx'],
        'video/x-f4v' => ['f4v'],
        'video/x-fli' => ['fli', 'flc'],
        'video/x-flic' => ['fli', 'flc'],
        'video/x-flv' => ['flv'],
        'video/x-javafx' => ['fxm'],
        'video/x-m4v' => ['m4v', 'mp4', 'f4v', 'lrv'],
        'video/x-matroska' => ['mkv', 'mk3d', 'mks'],
        'video/x-matroska-3d' => ['mk3d'],
        'video/x-mjpeg' => ['mjpeg', 'mjpg'],
        'video/x-mng' => ['mng'],
        'video/x-mpeg' => ['mpeg', 'mpg', 'mp2', 'mpe', 'vob'],
        'video/x-mpeg-system' => ['mpeg', 'mpg', 'mp2', 'mpe', 'vob'],
        'video/x-mpeg2' => ['mpeg', 'mpg', 'mp2', 'mpe', 'vob'],
        'video/x-mpegurl' => ['m1u', 'm4u', 'mxu'],
        'video/x-ms-asf' => ['asf', 'asx'],
        'video/x-ms-asf-plugin' => ['asf'],
        'video/x-ms-vob' => ['vob'],
        'video/x-ms-wax' => ['asx', 'wax', 'wvx', 'wmx'],
        'video/x-ms-wm' => ['wm', 'asf'],
        'video/x-ms-wmv' => ['wmv'],
        'video/x-ms-wmx' => ['wmx', 'asx', 'wax', 'wvx'],
        'video/x-ms-wvx' => ['wvx', 'asx', 'wax', 'wmx'],
        'video/x-msvideo' => ['avi', 'avf', 'divx'],
        'video/x-nsv' => ['nsv'],
        'video/x-ogg' => ['ogv', 'ogg'],
        'video/x-ogm' => ['ogm'],
        'video/x-ogm+ogg' => ['ogm'],
        'video/x-real-video' => ['rv', 'rvx'],
        'video/x-sgi-movie' => ['movie'],
        'video/x-smv' => ['smv'],
        'video/x-theora' => ['ogg'],
        'video/x-theora+ogg' => ['ogg'],
        'x-conference/x-cooltalk' => ['ice'],
        'x-epoc/x-sisx-app' => ['sisx'],
        'zz-application/zz-winassoc-123' => ['123', 'wk1', 'wk3', 'wk4', 'wks'],
        'zz-application/zz-winassoc-cab' => ['cab'],
        'zz-application/zz-winassoc-cdr' => ['cdr'],
        'zz-application/zz-winassoc-doc' => ['doc'],
        'zz-application/zz-winassoc-hlp' => ['hlp'],
        'zz-application/zz-winassoc-mdb' => ['mdb'],
        'zz-application/zz-winassoc-uu' => ['uue'],
        'zz-application/zz-winassoc-xls' => ['xls', 'xlc', 'xll', 'xlm', 'xlw', 'xla', 'xlt', 'xld'],
    ];

    private static $reverseMap = [
        '32x' => ['application/x-genesis-32x-rom'],
        '3dml' => ['text/vnd.in3d.3dml'],
        '3ds' => ['image/x-3ds'],
        '3g2' => ['audio/3gpp2', 'video/3gpp2'],
        '3ga' => ['audio/3gpp', 'audio/3gpp-encrypted', 'audio/x-rn-3gpp-amr', 'audio/x-rn-3gpp-amr-encrypted', 'audio/x-rn-3gpp-amr-wb', 'audio/x-rn-3gpp-amr-wb-encrypted', 'video/3gp', 'video/3gpp', 'video/3gpp-encrypted'],
        '3gp' => ['audio/3gpp', 'audio/3gpp-encrypted', 'audio/x-rn-3gpp-amr', 'audio/x-rn-3gpp-amr-encrypted', 'audio/x-rn-3gpp-amr-wb', 'audio/x-rn-3gpp-amr-wb-encrypted', 'video/3gp', 'video/3gpp', 'video/3gpp-encrypted'],
        '3gp2' => ['audio/3gpp2', 'video/3gpp2'],
        '3gpp' => ['audio/3gpp', 'audio/3gpp-encrypted', 'audio/x-rn-3gpp-amr', 'audio/x-rn-3gpp-amr-encrypted', 'audio/x-rn-3gpp-amr-wb', 'audio/x-rn-3gpp-amr-wb-encrypted', 'video/3gp', 'video/3gpp', 'video/3gpp-encrypted'],
        '3gpp2' => ['audio/3gpp2', 'video/3gpp2'],
        '7z' => ['application/x-7z-compressed'],
        'BLEND' => ['application/x-blender'],
        'C' => ['text/x-c++src'],
        'PAR2' => ['application/x-par2'],
        'PL' => ['application/x-perl', 'text/x-perl'],
        'Z' => ['application/x-compress'],
        'a' => ['application/x-archive'],
        'a26' => ['application/x-atari-2600-rom'],
        'a78' => ['application/x-atari-7800-rom'],
        'aa' => ['audio/vnd.audible', 'audio/vnd.audible.aax', 'audio/x-pn-audibleaudio'],
        'aab' => ['application/x-authorware-bin'],
        'aac' => ['audio/aac', 'audio/x-aac', 'audio/x-hx-aac-adts'],
        'aam' => ['application/x-authorware-map'],
        'aas' => ['application/x-authorware-seg'],
        'aax' => ['audio/vnd.audible', 'audio/vnd.audible.aax', 'audio/x-pn-audibleaudio'],
        'abw' => ['application/x-abiword'],
        'abw.CRASHED' => ['application/x-abiword'],
        'abw.gz' => ['application/x-abiword'],
        'ac' => ['application/pkix-attr-cert'],
        'ac3' => ['audio/ac3'],
        'acc' => ['application/vnd.americandynamics.acc'],
        'ace' => ['application/x-ace', 'application/x-ace-compressed'],
        'acu' => ['application/vnd.acucobol'],
        'acutc' => ['application/vnd.acucorp'],
        'adb' => ['text/x-adasrc'],
        'adf' => ['application/x-amiga-disk-format'],
        'adp' => ['audio/adpcm'],
        'ads' => ['text/x-adasrc'],
        'adts' => ['audio/aac', 'audio/x-aac', 'audio/x-hx-aac-adts'],
        'aep' => ['application/vnd.audiograph'],
        'afm' => ['application/x-font-afm', 'application/x-font-type1'],
        'afp' => ['application/vnd.ibm.modcap'],
        'ag' => ['image/x-applix-graphics'],
        'agb' => ['application/x-gba-rom'],
        'ahead' => ['application/vnd.ahead.space'],
        'ai' => ['application/illustrator', 'application/postscript', 'application/vnd.adobe.illustrator'],
        'aif' => ['audio/x-aiff'],
        'aifc' => ['audio/x-aifc', 'audio/x-aiff', 'audio/x-aiffc'],
        'aiff' => ['audio/x-aiff'],
        'aiffc' => ['audio/x-aifc', 'audio/x-aiffc'],
        'air' => ['application/vnd.adobe.air-application-installer-package+zip'],
        'ait' => ['application/vnd.dvb.ait'],
        'al' => ['application/x-perl', 'text/x-perl'],
        'alz' => ['application/x-alz'],
        'ami' => ['application/vnd.amiga.ami'],
        'amr' => ['audio/amr', 'audio/amr-encrypted'],
        'amz' => ['audio/x-amzxml'],
        'ani' => ['application/x-navi-animation'],
        'anim[1-9j]' => ['video/x-anim'],
        'anx' => ['application/annodex', 'application/x-annodex'],
        'ape' => ['audio/x-ape'],
        'apk' => ['application/vnd.android.package-archive'],
        'appcache' => ['text/cache-manifest'],
        'appimage' => ['application/vnd.appimage', 'application/x-iso9660-appimage'],
        'application' => ['application/x-ms-application'],
        'apr' => ['application/vnd.lotus-approach'],
        'aps' => ['application/postscript'],
        'ar' => ['application/x-archive'],
        'arc' => ['application/x-freearc'],
        'arj' => ['application/x-arj'],
        'arw' => ['image/x-sony-arw'],
        'as' => ['application/x-applix-spreadsheet'],
        'asc' => ['application/pgp', 'application/pgp-encrypted', 'application/pgp-keys', 'application/pgp-signature', 'text/plain'],
        'asf' => ['application/vnd.ms-asf', 'video/x-ms-asf', 'video/x-ms-asf-plugin', 'video/x-ms-wm'],
        'asm' => ['text/x-asm'],
        'aso' => ['application/vnd.accpac.simply.aso'],
        'asp' => ['application/x-asp'],
        'ass' => ['audio/aac', 'audio/x-aac', 'audio/x-hx-aac-adts', 'text/x-ssa'],
        'asx' => ['application/x-ms-asx', 'audio/x-ms-asx', 'video/x-ms-asf', 'video/x-ms-wax', 'video/x-ms-wmx', 'video/x-ms-wvx'],
        'atc' => ['application/vnd.acucorp'],
        'atom' => ['application/atom+xml'],
        'atomcat' => ['application/atomcat+xml'],
        'atomsvc' => ['application/atomsvc+xml'],
        'atx' => ['application/vnd.antix.game-component'],
        'au' => ['audio/basic'],
        'automount' => ['text/x-systemd-unit'],
        'avf' => ['video/avi', 'video/divx', 'video/msvideo', 'video/vnd.divx', 'video/x-avi', 'video/x-msvideo'],
        'avi' => ['video/avi', 'video/divx', 'video/msvideo', 'video/vnd.divx', 'video/x-avi', 'video/x-msvideo'],
        'aw' => ['application/applixware', 'application/x-applix-word'],
        'awb' => ['audio/amr-wb', 'audio/amr-wb-encrypted'],
        'awk' => ['application/x-awk'],
        'axa' => ['audio/annodex', 'audio/x-annodex'],
        'axv' => ['video/annodex', 'video/x-annodex'],
        'azf' => ['application/vnd.airzip.filesecure.azf'],
        'azs' => ['application/vnd.airzip.filesecure.azs'],
        'azw' => ['application/vnd.amazon.ebook'],
        'bak' => ['application/x-trash'],
        'bat' => ['application/x-msdownload'],
        'bcpio' => ['application/x-bcpio'],
        'bdf' => ['application/x-font-bdf'],
        'bdm' => ['application/vnd.syncml.dm+wbxml', 'video/mp2t'],
        'bdmv' => ['video/mp2t'],
        'bed' => ['application/vnd.realvnc.bed'],
        'bh2' => ['application/vnd.fujitsu.oasysprs'],
        'bib' => ['text/x-bibtex'],
        'bin' => ['application/octet-stream', 'application/x-saturn-rom', 'application/x-sega-cd-rom'],
        'blb' => ['application/x-blorb'],
        'blend' => ['application/x-blender'],
        'blender' => ['application/x-blender'],
        'blorb' => ['application/x-blorb'],
        'bmi' => ['application/vnd.bmi'],
        'bmp' => ['image/bmp', 'image/x-bmp', 'image/x-ms-bmp'],
        'book' => ['application/vnd.framemaker'],
        'box' => ['application/vnd.previewsystems.box'],
        'boz' => ['application/x-bzip2'],
        'bpk' => ['application/octet-stream'],
        'bsdiff' => ['application/x-bsdiff'],
        'btif' => ['image/prs.btif'],
        'bz' => ['application/x-bzip', 'application/x-bzip2'],
        'bz2' => ['application/x-bz2', 'application/x-bzip', 'application/x-bzip2'],
        'c' => ['text/x-c', 'text/x-csrc'],
        'c++' => ['text/x-c++src'],
        'c11amc' => ['application/vnd.cluetrust.cartomobile-config'],
        'c11amz' => ['application/vnd.cluetrust.cartomobile-config-pkg'],
        'c4d' => ['application/vnd.clonk.c4group'],
        'c4f' => ['application/vnd.clonk.c4group'],
        'c4g' => ['application/vnd.clonk.c4group'],
        'c4p' => ['application/vnd.clonk.c4group'],
        'c4u' => ['application/vnd.clonk.c4group'],
        'cab' => ['application/vnd.ms-cab-compressed', 'zz-application/zz-winassoc-cab'],
        'caf' => ['audio/x-caf'],
        'cap' => ['application/pcap', 'application/vnd.tcpdump.pcap', 'application/x-pcap'],
        'car' => ['application/vnd.curl.car'],
        'cat' => ['application/vnd.ms-pki.seccat'],
        'cb7' => ['application/x-cb7', 'application/x-cbr'],
        'cba' => ['application/x-cbr'],
        'cbl' => ['text/x-cobol'],
        'cbr' => ['application/vnd.comicbook-rar', 'application/x-cbr'],
        'cbt' => ['application/x-cbr', 'application/x-cbt'],
        'cbz' => ['application/vnd.comicbook+zip', 'application/x-cbr', 'application/x-cbz'],
        'cc' => ['text/x-c', 'text/x-c++src'],
        'ccmx' => ['application/x-ccmx'],
        'cct' => ['application/x-director'],
        'ccxml' => ['application/ccxml+xml'],
        'cdbcmsg' => ['application/vnd.contact.cmsg'],
        'cdf' => ['application/x-netcdf'],
        'cdkey' => ['application/vnd.mediastation.cdkey'],
        'cdmia' => ['application/cdmi-capability'],
        'cdmic' => ['application/cdmi-container'],
        'cdmid' => ['application/cdmi-domain'],
        'cdmio' => ['application/cdmi-object'],
        'cdmiq' => ['application/cdmi-queue'],
        'cdr' => ['application/cdr', 'application/coreldraw', 'application/vnd.corel-draw', 'application/x-cdr', 'application/x-coreldraw', 'image/cdr', 'image/x-cdr', 'zz-application/zz-winassoc-cdr'],
        'cdx' => ['chemical/x-cdx'],
        'cdxml' => ['application/vnd.chemdraw+xml'],
        'cdy' => ['application/vnd.cinderella'],
        'cer' => ['application/pkix-cert'],
        'cert' => ['application/x-x509-ca-cert'],
        'cfs' => ['application/x-cfs-compressed'],
        'cgb' => ['application/x-gameboy-color-rom'],
        'cgm' => ['image/cgm'],
        'chat' => ['application/x-chat'],
        'chm' => ['application/vnd.ms-htmlhelp', 'application/x-chm'],
        'chrt' => ['application/vnd.kde.kchart', 'application/x-kchart'],
        'cif' => ['chemical/x-cif'],
        'cii' => ['application/vnd.anser-web-certificate-issue-initiation'],
        'cil' => ['application/vnd.ms-artgalry'],
        'cl' => ['text/x-opencl-src'],
        'cla' => ['application/vnd.claymore'],
        'class' => ['application/java', 'application/java-byte-code', 'application/java-vm', 'application/x-java', 'application/x-java-class', 'application/x-java-vm'],
        'clkk' => ['application/vnd.crick.clicker.keyboard'],
        'clkp' => ['application/vnd.crick.clicker.palette'],
        'clkt' => ['application/vnd.crick.clicker.template'],
        'clkw' => ['application/vnd.crick.clicker.wordbank'],
        'clkx' => ['application/vnd.crick.clicker'],
        'clp' => ['application/x-msclip'],
        'clpi' => ['video/mp2t'],
        'cls' => ['application/x-tex', 'text/x-tex'],
        'cmake' => ['text/x-cmake'],
        'cmc' => ['application/vnd.cosmocaller'],
        'cmdf' => ['chemical/x-cmdf'],
        'cml' => ['chemical/x-cml'],
        'cmp' => ['application/vnd.yellowriver-custom-menu'],
        'cmx' => ['image/x-cmx'],
        'cob' => ['text/x-cobol'],
        'cod' => ['application/vnd.rim.cod'],
        'coffee' => ['application/vnd.coffeescript'],
        'com' => ['application/x-msdownload'],
        'conf' => ['text/plain'],
        'cpi' => ['video/mp2t'],
        'cpio' => ['application/x-cpio'],
        'cpio.gz' => ['application/x-cpio-compressed'],
        'cpp' => ['text/x-c', 'text/x-c++src'],
        'cpt' => ['application/mac-compactpro'],
        'cr2' => ['image/x-canon-cr2'],
        'crd' => ['application/x-mscardfile'],
        'crdownload' => ['application/x-partial-download'],
        'crl' => ['application/pkix-crl'],
        'crt' => ['application/x-x509-ca-cert'],
        'crw' => ['image/x-canon-crw'],
        'cryptonote' => ['application/vnd.rig.cryptonote'],
        'cs' => ['text/x-csharp'],
        'csh' => ['application/x-csh'],
        'csml' => ['chemical/x-csml'],
        'csp' => ['application/vnd.commonspace'],
        'css' => ['text/css'],
        'cst' => ['application/x-director'],
        'csv' => ['text/csv', 'text/x-comma-separated-values', 'text/x-csv'],
        'csvs' => ['text/csv-schema'],
        'cu' => ['application/cu-seeme'],
        'cue' => ['application/x-cue'],
        'cur' => ['image/x-win-bitmap'],
        'curl' => ['text/vnd.curl'],
        'cww' => ['application/prs.cww'],
        'cxt' => ['application/x-director'],
        'cxx' => ['text/x-c', 'text/x-c++src'],
        'd' => ['text/x-dsrc'],
        'dae' => ['model/vnd.collada+xml'],
        'daf' => ['application/vnd.mobius.daf'],
        'dar' => ['application/x-dar'],
        'dart' => ['application/vnd.dart'],
        'dataless' => ['application/vnd.fdsn.seed'],
        'davmount' => ['application/davmount+xml'],
        'dbf' => ['application/dbase', 'application/dbf', 'application/x-dbase', 'application/x-dbf'],
        'dbk' => ['application/docbook+xml', 'application/vnd.oasis.docbook+xml', 'application/x-docbook+xml'],
        'dc' => ['application/x-dc-rom'],
        'dcl' => ['text/x-dcl'],
        'dcm' => ['application/dicom'],
        'dcr' => ['application/x-director', 'image/x-kodak-dcr'],
        'dcurl' => ['text/vnd.curl.dcurl'],
        'dd2' => ['application/vnd.oma.dd2+xml'],
        'ddd' => ['application/vnd.fujixerox.ddd'],
        'dds' => ['image/x-dds'],
        'deb' => ['application/vnd.debian.binary-package', 'application/x-deb', 'application/x-debian-package'],
        'def' => ['text/plain'],
        'deploy' => ['application/octet-stream'],
        'der' => ['application/x-x509-ca-cert'],
        'desktop' => ['application/x-desktop', 'application/x-gnome-app-info'],
        'device' => ['text/x-systemd-unit'],
        'dfac' => ['application/vnd.dreamfactory'],
        'dgc' => ['application/x-dgc-compressed'],
        'di' => ['text/x-dsrc'],
        'dia' => ['application/x-dia-diagram'],
        'dib' => ['image/bmp', 'image/x-bmp', 'image/x-ms-bmp'],
        'dic' => ['text/x-c'],
        'diff' => ['text/x-diff', 'text/x-patch'],
        'dir' => ['application/x-director'],
        'dis' => ['application/vnd.mobius.dis'],
        'dist' => ['application/octet-stream'],
        'distz' => ['application/octet-stream'],
        'divx' => ['video/avi', 'video/divx', 'video/msvideo', 'video/vnd.divx', 'video/x-avi', 'video/x-msvideo'],
        'djv' => ['image/vnd.djvu', 'image/vnd.djvu+multipage', 'image/x-djvu', 'image/x.djvu'],
        'djvu' => ['image/vnd.djvu', 'image/vnd.djvu+multipage', 'image/x-djvu', 'image/x.djvu'],
        'dll' => ['application/x-msdownload'],
        'dmg' => ['application/x-apple-diskimage'],
        'dmp' => ['application/pcap', 'application/vnd.tcpdump.pcap', 'application/x-pcap'],
        'dms' => ['application/octet-stream'],
        'dna' => ['application/vnd.dna'],
        'dng' => ['image/x-adobe-dng'],
        'doc' => ['application/msword', 'application/vnd.ms-word', 'application/x-msword', 'zz-application/zz-winassoc-doc'],
        'docbook' => ['application/docbook+xml', 'application/vnd.oasis.docbook+xml', 'application/x-docbook+xml'],
        'docm' => ['application/vnd.ms-word.document.macroenabled.12'],
        'docx' => ['application/vnd.openxmlformats-officedocument.wordprocessingml.document'],
        'dot' => ['application/msword', 'application/msword-template', 'text/vnd.graphviz'],
        'dotm' => ['application/vnd.ms-word.template.macroenabled.12'],
        'dotx' => ['application/vnd.openxmlformats-officedocument.wordprocessingml.template'],
        'dp' => ['application/vnd.osgi.dp'],
        'dpg' => ['application/vnd.dpgraph'],
        'dra' => ['audio/vnd.dra'],
        'dsc' => ['text/prs.lines.tag'],
        'dsl' => ['text/x-dsl'],
        'dssc' => ['application/dssc+der'],
        'dtb' => ['application/x-dtbook+xml'],
        'dtd' => ['application/xml-dtd', 'text/x-dtd'],
        'dts' => ['audio/vnd.dts', 'audio/x-dts'],
        'dtshd' => ['audio/vnd.dts.hd', 'audio/x-dtshd'],
        'dtx' => ['application/x-tex', 'text/x-tex'],
        'dump' => ['application/octet-stream'],
        'dv' => ['video/dv'],
        'dvb' => ['video/vnd.dvb.file'],
        'dvi' => ['application/x-dvi'],
        'dvi.bz2' => ['application/x-bzdvi'],
        'dvi.gz' => ['application/x-gzdvi'],
        'dwf' => ['model/vnd.dwf'],
        'dwg' => ['image/vnd.dwg'],
        'dxf' => ['image/vnd.dxf'],
        'dxp' => ['application/vnd.spotfire.dxp'],
        'dxr' => ['application/x-director'],
        'e' => ['text/x-eiffel'],
        'ecelp4800' => ['audio/vnd.nuera.ecelp4800'],
        'ecelp7470' => ['audio/vnd.nuera.ecelp7470'],
        'ecelp9600' => ['audio/vnd.nuera.ecelp9600'],
        'ecma' => ['application/ecmascript'],
        'edm' => ['application/vnd.novadigm.edm'],
        'edx' => ['application/vnd.novadigm.edx'],
        'efif' => ['application/vnd.picsel'],
        'egon' => ['application/x-egon'],
        'ei6' => ['application/vnd.pg.osasli'],
        'eif' => ['text/x-eiffel'],
        'el' => ['text/x-emacs-lisp'],
        'elc' => ['application/octet-stream'],
        'emf' => ['application/emf', 'application/x-emf', 'application/x-msmetafile', 'image/emf', 'image/x-emf'],
        'eml' => ['message/rfc822'],
        'emma' => ['application/emma+xml'],
        'emp' => ['application/vnd.emusic-emusic_package'],
        'emz' => ['application/x-msmetafile'],
        'ent' => ['application/xml-external-parsed-entity', 'text/xml-external-parsed-entity'],
        'eol' => ['audio/vnd.digital-winds'],
        'eot' => ['application/vnd.ms-fontobject'],
        'eps' => ['application/postscript', 'image/x-eps'],
        'eps.bz2' => ['image/x-bzeps'],
        'eps.gz' => ['image/x-gzeps'],
        'epsf' => ['image/x-eps'],
        'epsf.bz2' => ['image/x-bzeps'],
        'epsf.gz' => ['image/x-gzeps'],
        'epsi' => ['image/x-eps'],
        'epsi.bz2' => ['image/x-bzeps'],
        'epsi.gz' => ['image/x-gzeps'],
        'epub' => ['application/epub+zip'],
        'erl' => ['text/x-erlang'],
        'es' => ['application/ecmascript', 'text/ecmascript'],
        'es3' => ['application/vnd.eszigno3+xml'],
        'esa' => ['application/vnd.osgi.subsystem'],
        'esf' => ['application/vnd.epson.esf'],
        'et3' => ['application/vnd.eszigno3+xml'],
        'etheme' => ['application/x-e-theme'],
        'etx' => ['text/x-setext'],
        'eva' => ['application/x-eva'],
        'evy' => ['application/x-envoy'],
        'exe' => ['application/x-ms-dos-executable', 'application/x-msdownload'],
        'exi' => ['application/exi'],
        'exr' => ['image/x-exr'],
        'ext' => ['application/vnd.novadigm.ext'],
        'ez' => ['application/andrew-inset'],
        'ez2' => ['application/vnd.ezpix-album'],
        'ez3' => ['application/vnd.ezpix-package'],
        'f' => ['text/x-fortran'],
        'f4a' => ['audio/m4a', 'audio/mp4', 'audio/x-m4a'],
        'f4b' => ['audio/x-m4b'],
        'f4v' => ['video/mp4', 'video/mp4v-es', 'video/x-f4v', 'video/x-m4v'],
        'f77' => ['text/x-fortran'],
        'f90' => ['text/x-fortran'],
        'f95' => ['text/x-fortran'],
        'fb2' => ['application/x-fictionbook', 'application/x-fictionbook+xml'],
        'fb2.zip' => ['application/x-zip-compressed-fb2'],
        'fbs' => ['image/vnd.fastbidsheet'],
        'fcdt' => ['application/vnd.adobe.formscentral.fcdt'],
        'fcs' => ['application/vnd.isac.fcs'],
        'fd' => ['application/x-fd-file', 'application/x-raw-floppy-disk-image'],
        'fdf' => ['application/vnd.fdf'],
        'fds' => ['application/x-fds-disk'],
        'fe_launch' => ['application/vnd.denovo.fcselayout-link'],
        'feature' => ['text/x-gherkin'],
        'fg5' => ['application/vnd.fujitsu.oasysgp'],
        'fgd' => ['application/x-director'],
        'fh' => ['image/x-freehand'],
        'fh4' => ['image/x-freehand'],
        'fh5' => ['image/x-freehand'],
        'fh7' => ['image/x-freehand'],
        'fhc' => ['image/x-freehand'],
        'fig' => ['application/x-xfig', 'image/x-xfig'],
        'fits' => ['image/fits', 'image/x-fits'],
        'fl' => ['application/x-fluid'],
        'flac' => ['audio/flac', 'audio/x-flac'],
        'flatpak' => ['application/vnd.flatpak', 'application/vnd.xdgapp'],
        'flatpakref' => ['application/vnd.flatpak.ref'],
        'flatpakrepo' => ['application/vnd.flatpak.repo'],
        'flc' => ['video/fli', 'video/x-fli', 'video/x-flic'],
        'fli' => ['video/fli', 'video/x-fli', 'video/x-flic'],
        'flo' => ['application/vnd.micrografx.flo'],
        'flv' => ['video/x-flv', 'application/x-flash-video', 'flv-application/octet-stream', 'video/flv'],
        'flw' => ['application/vnd.kde.kivio', 'application/x-kivio'],
        'flx' => ['text/vnd.fmi.flexstor'],
        'fly' => ['text/vnd.fly'],
        'fm' => ['application/vnd.framemaker', 'application/x-frame'],
        'fnc' => ['application/vnd.frogans.fnc'],
        'fo' => ['text/x-xslfo'],
        'fodg' => ['application/vnd.oasis.opendocument.graphics-flat-xml'],
        'fodp' => ['application/vnd.oasis.opendocument.presentation-flat-xml'],
        'fods' => ['application/vnd.oasis.opendocument.spreadsheet-flat-xml'],
        'fodt' => ['application/vnd.oasis.opendocument.text-flat-xml'],
        'for' => ['text/x-fortran'],
        'fpx' => ['image/vnd.fpx'],
        'frame' => ['application/vnd.framemaker'],
        'fsc' => ['application/vnd.fsc.weblaunch'],
        'fst' => ['image/vnd.fst'],
        'ftc' => ['application/vnd.fluxtime.clip'],
        'fti' => ['application/vnd.anser-web-funds-transfer-initiation'],
        'fvt' => ['video/vnd.fvt'],
        'fxm' => ['video/x-javafx'],
        'fxp' => ['application/vnd.adobe.fxp'],
        'fxpl' => ['application/vnd.adobe.fxp'],
        'fzs' => ['application/vnd.fuzzysheet'],
        'g2w' => ['application/vnd.geoplan'],
        'g3' => ['image/fax-g3', 'image/g3fax'],
        'g3w' => ['application/vnd.geospace'],
        'gac' => ['application/vnd.groove-account'],
        'gam' => ['application/x-tads'],
        'gb' => ['application/x-gameboy-rom'],
        'gba' => ['application/x-gba-rom'],
        'gbc' => ['application/x-gameboy-color-rom'],
        'gbr' => ['application/rpki-ghostbusters', 'image/x-gimp-gbr'],
        'gca' => ['application/x-gca-compressed'],
        'gcode' => ['text/x.gcode'],
        'gcrd' => ['text/directory', 'text/vcard', 'text/x-vcard'],
        'gdl' => ['model/vnd.gdl'],
        'ged' => ['application/x-gedcom', 'text/gedcom'],
        'gedcom' => ['application/x-gedcom', 'text/gedcom'],
        'gem' => ['application/x-gtar', 'application/x-tar'],
        'gen' => ['application/x-genesis-rom'],
        'geo' => ['application/vnd.dynageo'],
        'geo.json' => ['application/geo+json', 'application/vnd.geo+json'],
        'geojson' => ['application/geo+json', 'application/vnd.geo+json'],
        'gex' => ['application/vnd.geometry-explorer'],
        'gf' => ['application/x-tex-gf'],
        'gg' => ['application/x-gamegear-rom'],
        'ggb' => ['application/vnd.geogebra.file'],
        'ggt' => ['application/vnd.geogebra.tool'],
        'ghf' => ['application/vnd.groove-help'],
        'gif' => ['image/gif'],
        'gih' => ['image/x-gimp-gih'],
        'gim' => ['application/vnd.groove-identity-message'],
        'glade' => ['application/x-glade'],
        'gml' => ['application/gml+xml'],
        'gmo' => ['application/x-gettext-translation'],
        'gmx' => ['application/vnd.gmx'],
        'gnc' => ['application/x-gnucash'],
        'gnd' => ['application/gnunet-directory'],
        'gnucash' => ['application/x-gnucash'],
        'gnumeric' => ['application/x-gnumeric'],
        'gnuplot' => ['application/x-gnuplot'],
        'go' => ['text/x-go'],
        'gp' => ['application/x-gnuplot'],
        'gpg' => ['application/pgp', 'application/pgp-encrypted', 'application/pgp-keys', 'application/pgp-signature'],
        'gph' => ['application/vnd.flographit'],
        'gplt' => ['application/x-gnuplot'],
        'gpx' => ['application/gpx', 'application/gpx+xml', 'application/x-gpx', 'application/x-gpx+xml'],
        'gqf' => ['application/vnd.grafeq'],
        'gqs' => ['application/vnd.grafeq'],
        'gra' => ['application/x-graphite'],
        'gram' => ['application/srgs'],
        'gramps' => ['application/x-gramps-xml'],
        'gre' => ['application/vnd.geometry-explorer'],
        'grv' => ['application/vnd.groove-injector'],
        'grxml' => ['application/srgs+xml'],
        'gs' => ['text/x-genie'],
        'gsf' => ['application/x-font-ghostscript', 'application/x-font-type1'],
        'gsm' => ['audio/x-gsm'],
        'gtar' => ['application/x-gtar', 'application/x-tar'],
        'gtm' => ['application/vnd.groove-tool-message'],
        'gtw' => ['model/vnd.gtw'],
        'gv' => ['text/vnd.graphviz'],
        'gvp' => ['text/google-video-pointer', 'text/x-google-video-pointer'],
        'gxf' => ['application/gxf'],
        'gxt' => ['application/vnd.geonext'],
        'gz' => ['application/x-gzip', 'application/gzip'],
        'h' => ['text/x-c', 'text/x-chdr'],
        'h++' => ['text/x-c++hdr'],
        'h261' => ['video/h261'],
        'h263' => ['video/h263'],
        'h264' => ['video/h264'],
        'h4' => ['application/x-hdf'],
        'h5' => ['application/x-hdf'],
        'hal' => ['application/vnd.hal+xml'],
        'hbci' => ['application/vnd.hbci'],
        'hdf' => ['application/x-hdf'],
        'hdf4' => ['application/x-hdf'],
        'hdf5' => ['application/x-hdf'],
        'heic' => ['image/heic', 'image/heic-sequence', 'image/heif', 'image/heif-sequence'],
        'heif' => ['image/heic', 'image/heic-sequence', 'image/heif', 'image/heif-sequence'],
        'hfe' => ['application/x-hfe-file', 'application/x-hfe-floppy-image'],
        'hh' => ['text/x-c', 'text/x-c++hdr'],
        'hlp' => ['application/winhlp', 'zz-application/zz-winassoc-hlp'],
        'hp' => ['text/x-c++hdr'],
        'hpgl' => ['application/vnd.hp-hpgl'],
        'hpid' => ['application/vnd.hp-hpid'],
        'hpp' => ['text/x-c++hdr'],
        'hps' => ['application/vnd.hp-hps'],
        'hqx' => ['application/stuffit', 'application/mac-binhex40'],
        'hs' => ['text/x-haskell'],
        'htke' => ['application/vnd.kenameaapp'],
        'htm' => ['text/html'],
        'html' => ['text/html'],
        'hvd' => ['application/vnd.yamaha.hv-dic'],
        'hvp' => ['application/vnd.yamaha.hv-voice'],
        'hvs' => ['application/vnd.yamaha.hv-script'],
        'hwp' => ['application/vnd.haansoft-hwp', 'application/x-hwp'],
        'hwt' => ['application/vnd.haansoft-hwt', 'application/x-hwt'],
        'hxx' => ['text/x-c++hdr'],
        'i2g' => ['application/vnd.intergeo'],
        'ica' => ['application/x-ica'],
        'icb' => ['image/x-icb', 'image/x-tga'],
        'icc' => ['application/vnd.iccprofile'],
        'ice' => ['x-conference/x-cooltalk'],
        'icm' => ['application/vnd.iccprofile'],
        'icns' => ['image/x-icns'],
        'ico' => ['application/ico', 'image/ico', 'image/icon', 'image/vnd.microsoft.icon', 'image/x-ico', 'image/x-icon', 'text/ico'],
        'ics' => ['application/ics', 'text/calendar', 'text/x-vcalendar'],
        'idl' => ['text/x-idl'],
        'ief' => ['image/ief'],
        'ifb' => ['text/calendar'],
        'iff' => ['image/x-iff', 'image/x-ilbm'],
        'ifm' => ['application/vnd.shana.informed.formdata'],
        'iges' => ['model/iges'],
        'igl' => ['application/vnd.igloader'],
        'igm' => ['application/vnd.insors.igm'],
        'igs' => ['model/iges'],
        'igx' => ['application/vnd.micrografx.igx'],
        'iif' => ['application/vnd.shana.informed.interchange'],
        'ilbm' => ['image/x-iff', 'image/x-ilbm'],
        'ime' => ['audio/imelody', 'audio/x-imelody', 'text/x-imelody'],
        'img' => ['application/x-raw-disk-image'],
        'img.xz' => ['application/x-raw-disk-image-xz-compressed'],
        'imp' => ['application/vnd.accpac.simply.imp'],
        'ims' => ['application/vnd.ms-ims'],
        'imy' => ['audio/imelody', 'audio/x-imelody', 'text/x-imelody'],
        'in' => ['text/plain'],
        'ink' => ['application/inkml+xml'],
        'inkml' => ['application/inkml+xml'],
        'ins' => ['application/x-tex', 'text/x-tex'],
        'install' => ['application/x-install-instructions'],
        'iota' => ['application/vnd.astraea-software.iota'],
        'ipfix' => ['application/ipfix'],
        'ipk' => ['application/vnd.shana.informed.package'],
        'iptables' => ['text/x-iptables'],
        'ipynb' => ['application/x-ipynb+json'],
        'irm' => ['application/vnd.ibm.rights-management'],
        'irp' => ['application/vnd.irepository.package+xml'],
        'iso' => ['application/x-cd-image', 'application/x-gamecube-iso-image', 'application/x-gamecube-rom', 'application/x-iso9660-image', 'application/x-saturn-rom', 'application/x-sega-cd-rom', 'application/x-wbfs', 'application/x-wia', 'application/x-wii-iso-image', 'application/x-wii-rom'],
        'iso9660' => ['application/x-cd-image', 'application/x-iso9660-image'],
        'it' => ['audio/x-it'],
        'it87' => ['application/x-it87'],
        'itp' => ['application/vnd.shana.informed.formtemplate'],
        'ivp' => ['application/vnd.immervision-ivp'],
        'ivu' => ['application/vnd.immervision-ivu'],
        'j2c' => ['image/x-jp2-codestream'],
        'j2k' => ['image/x-jp2-codestream'],
        'jad' => ['text/vnd.sun.j2me.app-descriptor'],
        'jam' => ['application/vnd.jam'],
        'jar' => ['application/x-java-archive', 'application/java-archive', 'application/x-jar'],
        'java' => ['text/x-java', 'text/x-java-source'],
        'jceks' => ['application/x-java-jce-keystore'],
        'jisp' => ['application/vnd.jisp'],
        'jks' => ['application/x-java-keystore'],
        'jlt' => ['application/vnd.hp-jlyt'],
        'jng' => ['image/x-jng'],
        'jnlp' => ['application/x-java-jnlp-file'],
        'joda' => ['application/vnd.joost.joda-archive'],
        'jp2' => ['image/jp2', 'image/jpeg2000', 'image/jpeg2000-image', 'image/x-jpeg2000-image'],
        'jpc' => ['image/x-jp2-codestream'],
        'jpe' => ['image/jpeg', 'image/pjpeg'],
        'jpeg' => ['image/jpeg', 'image/pjpeg'],
        'jpf' => ['image/jpx'],
        'jpg' => ['image/jpeg', 'image/pjpeg'],
        'jpg2' => ['image/jp2', 'image/jpeg2000', 'image/jpeg2000-image', 'image/x-jpeg2000-image'],
        'jpgm' => ['image/jpm', 'video/jpm'],
        'jpgv' => ['video/jpeg'],
        'jpm' => ['image/jpm', 'video/jpm'],
        'jpr' => ['application/x-jbuilder-project'],
        'jpx' => ['application/x-jbuilder-project', 'image/jpx'],
        'jrd' => ['application/jrd+json'],
        'js' => ['text/javascript', 'application/javascript', 'application/x-javascript'],
        'jsm' => ['application/javascript', 'application/x-javascript', 'text/javascript'],
        'json' => ['application/json'],
        'json-patch' => ['application/json-patch+json'],
        'jsonld' => ['application/ld+json'],
        'jsonml' => ['application/jsonml+json'],
        'k25' => ['image/x-kodak-k25'],
        'k7' => ['application/x-thomson-cassette'],
        'kar' => ['audio/midi', 'audio/x-midi'],
        'karbon' => ['application/vnd.kde.karbon', 'application/x-karbon'],
        'kdc' => ['image/x-kodak-kdc'],
        'kdelnk' => ['application/x-desktop', 'application/x-gnome-app-info'],
        'kexi' => ['application/x-kexiproject-sqlite', 'application/x-kexiproject-sqlite2', 'application/x-kexiproject-sqlite3', 'application/x-vnd.kde.kexi'],
        'kexic' => ['application/x-kexi-connectiondata'],
        'kexis' => ['application/x-kexiproject-shortcut'],
        'key' => ['application/vnd.apple.keynote', 'application/x-iwork-keynote-sffkey'],
        'kfo' => ['application/vnd.kde.kformula', 'application/x-kformula'],
        'kia' => ['application/vnd.kidspiration'],
        'kil' => ['application/x-killustrator'],
        'kino' => ['application/smil', 'application/smil+xml'],
        'kml' => ['application/vnd.google-earth.kml+xml'],
        'kmz' => ['application/vnd.google-earth.kmz'],
        'kne' => ['application/vnd.kinar'],
        'knp' => ['application/vnd.kinar'],
        'kon' => ['application/vnd.kde.kontour', 'application/x-kontour'],
        'kpm' => ['application/x-kpovmodeler'],
        'kpr' => ['application/vnd.kde.kpresenter', 'application/x-kpresenter'],
        'kpt' => ['application/vnd.kde.kpresenter', 'application/x-kpresenter'],
        'kpxx' => ['application/vnd.ds-keypoint'],
        'kra' => ['application/x-krita'],
        'ks' => ['application/x-java-keystore'],
        'ksp' => ['application/vnd.kde.kspread', 'application/x-kspread'],
        'ktr' => ['application/vnd.kahootz'],
        'ktx' => ['image/ktx'],
        'ktz' => ['application/vnd.kahootz'],
        'kud' => ['application/x-kugar'],
        'kwd' => ['application/vnd.kde.kword', 'application/x-kword'],
        'kwt' => ['application/vnd.kde.kword', 'application/x-kword'],
        'la' => ['application/x-shared-library-la'],
        'lasxml' => ['application/vnd.las.las+xml'],
        'latex' => ['application/x-latex', 'application/x-tex', 'text/x-tex'],
        'lbd' => ['application/vnd.llamagraphics.life-balance.desktop'],
        'lbe' => ['application/vnd.llamagraphics.life-balance.exchange+xml'],
        'lbm' => ['image/x-iff', 'image/x-ilbm'],
        'ldif' => ['text/x-ldif'],
        'les' => ['application/vnd.hhe.lesson-player'],
        'lha' => ['application/x-lha', 'application/x-lzh-compressed'],
        'lhs' => ['text/x-literate-haskell'],
        'lhz' => ['application/x-lhz'],
        'link66' => ['application/vnd.route66.link66+xml'],
        'list' => ['text/plain'],
        'list3820' => ['application/vnd.ibm.modcap'],
        'listafp' => ['application/vnd.ibm.modcap'],
        'lnk' => ['application/x-ms-shortcut'],
        'lnx' => ['application/x-atari-lynx-rom'],
        'loas' => ['audio/usac'],
        'log' => ['text/plain', 'text/x-log'],
        'lostxml' => ['application/lost+xml'],
        'lrf' => ['application/octet-stream'],
        'lrm' => ['application/vnd.ms-lrm'],
        'lrv' => ['video/mp4', 'video/mp4v-es', 'video/x-m4v'],
        'lrz' => ['application/x-lrzip'],
        'ltf' => ['application/vnd.frogans.ltf'],
        'ltx' => ['application/x-tex', 'text/x-tex'],
        'lua' => ['text/x-lua'],
        'lvp' => ['audio/vnd.lucent.voice'],
        'lwo' => ['image/x-lwo'],
        'lwob' => ['image/x-lwo'],
        'lwp' => ['application/vnd.lotus-wordpro'],
        'lws' => ['image/x-lws'],
        'ly' => ['text/x-lilypond'],
        'lyx' => ['application/x-lyx', 'text/x-lyx'],
        'lz' => ['application/x-lzip'],
        'lz4' => ['application/x-lz4'],
        'lzh' => ['application/x-lha', 'application/x-lzh-compressed'],
        'lzma' => ['application/x-lzma'],
        'lzo' => ['application/x-lzop'],
        'm' => ['text/x-matlab', 'text/x-objcsrc', 'text/x-octave'],
        'm13' => ['application/x-msmediaview'],
        'm14' => ['application/x-msmediaview'],
        'm15' => ['audio/x-mod'],
        'm1u' => ['video/vnd.mpegurl', 'video/x-mpegurl'],
        'm1v' => ['video/mpeg'],
        'm21' => ['application/mp21'],
        'm2a' => ['audio/mpeg'],
        'm2t' => ['video/mp2t'],
        'm2ts' => ['video/mp2t'],
        'm2v' => ['video/mpeg'],
        'm3a' => ['audio/mpeg'],
        'm3u' => ['audio/x-mpegurl', 'application/m3u', 'application/vnd.apple.mpegurl', 'audio/m3u', 'audio/mpegurl', 'audio/x-m3u', 'audio/x-mp3-playlist'],
        'm3u8' => ['application/m3u', 'application/vnd.apple.mpegurl', 'audio/m3u', 'audio/mpegurl', 'audio/x-m3u', 'audio/x-mp3-playlist', 'audio/x-mpegurl'],
        'm4' => ['application/x-m4'],
        'm4a' => ['audio/mp4', 'audio/m4a', 'audio/x-m4a'],
        'm4b' => ['audio/x-m4b'],
        'm4r' => ['audio/x-m4r'],
        'm4u' => ['video/vnd.mpegurl', 'video/x-mpegurl'],
        'm4v' => ['video/mp4', 'video/mp4v-es', 'video/x-m4v'],
        'm7' => ['application/x-thomson-cartridge-memo7'],
        'ma' => ['application/mathematica'],
        'mab' => ['application/x-markaby'],
        'mads' => ['application/mads+xml'],
        'mag' => ['application/vnd.ecowin.chart'],
        'mak' => ['text/x-makefile'],
        'maker' => ['application/vnd.framemaker'],
        'man' => ['application/x-troff-man', 'text/troff'],
        'manifest' => ['text/cache-manifest'],
        'mar' => ['application/octet-stream'],
        'markdown' => ['text/markdown', 'text/x-markdown'],
        'mathml' => ['application/mathml+xml'],
        'mb' => ['application/mathematica'],
        'mbk' => ['application/vnd.mobius.mbk'],
        'mbox' => ['application/mbox'],
        'mc1' => ['application/vnd.medcalcdata'],
        'mcd' => ['application/vnd.mcd'],
        'mcurl' => ['text/vnd.curl.mcurl'],
        'md' => ['text/markdown', 'text/x-markdown'],
        'mdb' => ['application/x-msaccess', 'application/mdb', 'application/msaccess', 'application/vnd.ms-access', 'application/vnd.msaccess', 'application/x-mdb', 'zz-application/zz-winassoc-mdb'],
        'mdi' => ['image/vnd.ms-modi'],
        'mdx' => ['application/x-genesis-32x-rom'],
        'me' => ['text/troff', 'text/x-troff-me'],
        'med' => ['audio/x-mod'],
        'mesh' => ['model/mesh'],
        'meta4' => ['application/metalink4+xml'],
        'metalink' => ['application/metalink+xml'],
        'mets' => ['application/mets+xml'],
        'mfm' => ['application/vnd.mfmp'],
        'mft' => ['application/rpki-manifest'],
        'mgp' => ['application/vnd.osgeo.mapguide.package', 'application/x-magicpoint'],
        'mgz' => ['application/vnd.proteus.magazine'],
        'mht' => ['application/x-mimearchive'],
        'mhtml' => ['application/x-mimearchive'],
        'mid' => ['audio/midi', 'audio/x-midi'],
        'midi' => ['audio/midi', 'audio/x-midi'],
        'mie' => ['application/x-mie'],
        'mif' => ['application/vnd.mif', 'application/x-mif'],
        'mime' => ['message/rfc822'],
        'minipsf' => ['audio/x-minipsf'],
        'mj2' => ['video/mj2'],
        'mjp2' => ['video/mj2'],
        'mjpeg' => ['video/x-mjpeg'],
        'mjpg' => ['video/x-mjpeg'],
        'mjs' => ['application/javascript', 'application/x-javascript', 'text/javascript'],
        'mk' => ['text/x-makefile'],
        'mk3d' => ['video/x-matroska', 'video/x-matroska-3d'],
        'mka' => ['audio/x-matroska'],
        'mkd' => ['text/markdown', 'text/x-markdown'],
        'mks' => ['video/x-matroska'],
        'mkv' => ['video/x-matroska'],
        'ml' => ['text/x-ocaml'],
        'mli' => ['text/x-ocaml'],
        'mlp' => ['application/vnd.dolby.mlp'],
        'mm' => ['text/x-troff-mm'],
        'mmd' => ['application/vnd.chipnuts.karaoke-mmd'],
        'mmf' => ['application/vnd.smaf', 'application/x-smaf'],
        'mml' => ['application/mathml+xml', 'text/mathml'],
        'mmr' => ['image/vnd.fujixerox.edmics-mmr'],
        'mng' => ['video/x-mng'],
        'mny' => ['application/x-msmoney'],
        'mo' => ['application/x-gettext-translation', 'text/x-modelica'],
        'mo3' => ['audio/x-mo3'],
        'mobi' => ['application/x-mobipocket-ebook'],
        'moc' => ['text/x-moc'],
        'mod' => ['audio/x-mod'],
        'mods' => ['application/mods+xml'],
        'mof' => ['text/x-mof'],
        'moov' => ['video/quicktime'],
        'mount' => ['text/x-systemd-unit'],
        'mov' => ['video/quicktime'],
        'movie' => ['video/x-sgi-movie'],
        'mp+' => ['audio/x-musepack'],
        'mp2' => ['audio/mp2', 'audio/mpeg', 'audio/x-mp2', 'video/mpeg', 'video/mpeg-system', 'video/x-mpeg', 'video/x-mpeg-system', 'video/x-mpeg2'],
        'mp21' => ['application/mp21'],
        'mp2a' => ['audio/mpeg'],
        'mp3' => ['audio/mpeg', 'audio/mp3', 'audio/x-mp3', 'audio/x-mpeg', 'audio/x-mpg'],
        'mp4' => ['video/mp4', 'video/mp4v-es', 'video/x-m4v'],
        'mp4a' => ['audio/mp4'],
        'mp4s' => ['application/mp4'],
        'mp4v' => ['video/mp4'],
        'mpc' => ['application/vnd.mophun.certificate', 'audio/x-musepack'],
        'mpe' => ['video/mpeg', 'video/mpeg-system', 'video/x-mpeg', 'video/x-mpeg-system', 'video/x-mpeg2'],
        'mpeg' => ['video/mpeg', 'video/mpeg-system', 'video/x-mpeg', 'video/x-mpeg-system', 'video/x-mpeg2'],
        'mpg' => ['video/mpeg', 'video/mpeg-system', 'video/x-mpeg', 'video/x-mpeg-system', 'video/x-mpeg2'],
        'mpg4' => ['video/mp4'],
        'mpga' => ['audio/mp3', 'audio/mpeg', 'audio/x-mp3', 'audio/x-mpeg', 'audio/x-mpg'],
        'mpkg' => ['application/vnd.apple.installer+xml'],
        'mpl' => ['video/mp2t'],
        'mpls' => ['video/mp2t'],
        'mpm' => ['application/vnd.blueice.multipass'],
        'mpn' => ['application/vnd.mophun.application'],
        'mpp' => ['application/vnd.ms-project', 'audio/x-musepack'],
        'mpt' => ['application/vnd.ms-project'],
        'mpy' => ['application/vnd.ibm.minipay'],
        'mqy' => ['application/vnd.mobius.mqy'],
        'mrc' => ['application/marc'],
        'mrcx' => ['application/marcxml+xml'],
        'mrl' => ['text/x-mrml'],
        'mrml' => ['text/x-mrml'],
        'mrw' => ['image/x-minolta-mrw'],
        'ms' => ['text/troff', 'text/x-troff-ms'],
        'mscml' => ['application/mediaservercontrol+xml'],
        'mseed' => ['application/vnd.fdsn.mseed'],
        'mseq' => ['application/vnd.mseq'],
        'msf' => ['application/vnd.epson.msf'],
        'msg' => ['application/vnd.ms-outlook'],
        'msh' => ['model/mesh'],
        'msi' => ['application/x-msdownload', 'application/x-msi'],
        'msl' => ['application/vnd.mobius.msl'],
        'msod' => ['image/x-msod'],
        'msty' => ['application/vnd.muvee.style'],
        'msx' => ['application/x-msx-rom'],
        'mtm' => ['audio/x-mod'],
        'mts' => ['model/vnd.mts', 'video/mp2t'],
        'mup' => ['text/x-mup'],
        'mus' => ['application/vnd.musician'],
        'musicxml' => ['application/vnd.recordare.musicxml+xml'],
        'mvb' => ['application/x-msmediaview'],
        'mwf' => ['application/vnd.mfer'],
        'mxf' => ['application/mxf'],
        'mxl' => ['application/vnd.recordare.musicxml'],
        'mxml' => ['application/xv+xml'],
        'mxs' => ['application/vnd.triscape.mxs'],
        'mxu' => ['video/vnd.mpegurl', 'video/x-mpegurl'],
        'n-gage' => ['application/vnd.nokia.n-gage.symbian.install'],
        'n3' => ['text/n3'],
        'n64' => ['application/x-n64-rom'],
        'nb' => ['application/mathematica', 'application/x-mathematica'],
        'nbp' => ['application/vnd.wolfram.player'],
        'nc' => ['application/x-netcdf'],
        'ncx' => ['application/x-dtbncx+xml'],
        'nds' => ['application/x-nintendo-ds-rom'],
        'nef' => ['image/x-nikon-nef'],
        'nes' => ['application/x-nes-rom'],
        'nez' => ['application/x-nes-rom'],
        'nfo' => ['text/x-nfo'],
        'ngc' => ['application/x-neo-geo-pocket-color-rom'],
        'ngdat' => ['application/vnd.nokia.n-gage.data'],
        'ngp' => ['application/x-neo-geo-pocket-rom'],
        'nitf' => ['application/vnd.nitf'],
        'nlu' => ['application/vnd.neurolanguage.nlu'],
        'nml' => ['application/vnd.enliven'],
        'nnd' => ['application/vnd.noblenet-directory'],
        'nns' => ['application/vnd.noblenet-sealer'],
        'nnw' => ['application/vnd.noblenet-web'],
        'not' => ['text/x-mup'],
        'npx' => ['image/vnd.net-fpx'],
        'nsc' => ['application/x-conference', 'application/x-netshow-channel'],
        'nsf' => ['application/vnd.lotus-notes'],
        'nsv' => ['video/x-nsv'],
        'ntf' => ['application/vnd.nitf'],
        'nzb' => ['application/x-nzb'],
        'o' => ['application/x-object'],
        'oa2' => ['application/vnd.fujitsu.oasys2'],
        'oa3' => ['application/vnd.fujitsu.oasys3'],
        'oas' => ['application/vnd.fujitsu.oasys'],
        'obd' => ['application/x-msbinder'],
        'obj' => ['application/x-tgif'],
        'ocl' => ['text/x-ocl'],
        'oda' => ['application/oda'],
        'odb' => ['application/vnd.oasis.opendocument.database', 'application/vnd.sun.xml.base'],
        'odc' => ['application/vnd.oasis.opendocument.chart'],
        'odf' => ['application/vnd.oasis.opendocument.formula'],
        'odft' => ['application/vnd.oasis.opendocument.formula-template'],
        'odg' => ['application/vnd.oasis.opendocument.graphics'],
        'odi' => ['application/vnd.oasis.opendocument.image'],
        'odm' => ['application/vnd.oasis.opendocument.text-master'],
        'odp' => ['application/vnd.oasis.opendocument.presentation'],
        'ods' => ['application/vnd.oasis.opendocument.spreadsheet'],
        'odt' => ['application/vnd.oasis.opendocument.text'],
        'oga' => ['audio/ogg', 'audio/vorbis', 'audio/x-flac+ogg', 'audio/x-ogg', 'audio/x-oggflac', 'audio/x-speex+ogg', 'audio/x-vorbis', 'audio/x-vorbis+ogg'],
        'ogg' => ['audio/ogg', 'audio/vorbis', 'audio/x-flac+ogg', 'audio/x-ogg', 'audio/x-oggflac', 'audio/x-speex+ogg', 'audio/x-vorbis', 'audio/x-vorbis+ogg', 'video/ogg', 'video/x-ogg', 'video/x-theora', 'video/x-theora+ogg'],
        'ogm' => ['video/x-ogm', 'video/x-ogm+ogg'],
        'ogv' => ['video/ogg', 'video/x-ogg'],
        'ogx' => ['application/ogg', 'application/x-ogg'],
        'old' => ['application/x-trash'],
        'oleo' => ['application/x-oleo'],
        'omdoc' => ['application/omdoc+xml'],
        'onepkg' => ['application/onenote'],
        'onetmp' => ['application/onenote'],
        'onetoc' => ['application/onenote'],
        'onetoc2' => ['application/onenote'],
        'ooc' => ['text/x-ooc'],
        'opf' => ['application/oebps-package+xml'],
        'opml' => ['text/x-opml', 'text/x-opml+xml'],
        'oprc' => ['application/vnd.palm', 'application/x-palm-database'],
        'opus' => ['audio/ogg', 'audio/x-ogg', 'audio/x-opus+ogg'],
        'ora' => ['image/openraster'],
        'orf' => ['image/x-olympus-orf'],
        'org' => ['application/vnd.lotus-organizer'],
        'osf' => ['application/vnd.yamaha.openscoreformat'],
        'osfpvg' => ['application/vnd.yamaha.openscoreformat.osfpvg+xml'],
        'otc' => ['application/vnd.oasis.opendocument.chart-template'],
        'otf' => ['application/vnd.oasis.opendocument.formula-template', 'application/x-font-otf', 'font/otf'],
        'otg' => ['application/vnd.oasis.opendocument.graphics-template'],
        'oth' => ['application/vnd.oasis.opendocument.text-web'],
        'oti' => ['application/vnd.oasis.opendocument.image-template'],
        'otp' => ['application/vnd.oasis.opendocument.presentation-template'],
        'ots' => ['application/vnd.oasis.opendocument.spreadsheet-template'],
        'ott' => ['application/vnd.oasis.opendocument.text-template'],
        'owl' => ['application/rdf+xml', 'text/rdf'],
        'owx' => ['application/owl+xml'],
        'oxps' => ['application/oxps', 'application/vnd.ms-xpsdocument', 'application/xps'],
        'oxt' => ['application/vnd.openofficeorg.extension'],
        'p' => ['text/x-pascal'],
        'p10' => ['application/pkcs10'],
        'p12' => ['application/pkcs12', 'application/x-pkcs12'],
        'p65' => ['application/x-pagemaker'],
        'p7b' => ['application/x-pkcs7-certificates'],
        'p7c' => ['application/pkcs7-mime'],
        'p7m' => ['application/pkcs7-mime'],
        'p7r' => ['application/x-pkcs7-certreqresp'],
        'p7s' => ['application/pkcs7-signature'],
        'p8' => ['application/pkcs8'],
        'p8e' => ['application/pkcs8-encrypted'],
        'pack' => ['application/x-java-pack200'],
        'pak' => ['application/x-pak'],
        'par2' => ['application/x-par2'],
        'part' => ['application/x-partial-download'],
        'pas' => ['text/x-pascal'],
        'pat' => ['image/x-gimp-pat'],
        'patch' => ['text/x-diff', 'text/x-patch'],
        'path' => ['text/x-systemd-unit'],
        'paw' => ['application/vnd.pawaafile'],
        'pbd' => ['application/vnd.powerbuilder6'],
        'pbm' => ['image/x-portable-bitmap'],
        'pcap' => ['application/pcap', 'application/vnd.tcpdump.pcap', 'application/x-pcap'],
        'pcd' => ['image/x-photo-cd'],
        'pce' => ['application/x-pc-engine-rom'],
        'pcf' => ['application/x-cisco-vpn-settings', 'application/x-font-pcf'],
        'pcf.Z' => ['application/x-font-pcf'],
        'pcf.gz' => ['application/x-font-pcf'],
        'pcl' => ['application/vnd.hp-pcl'],
        'pclxl' => ['application/vnd.hp-pclxl'],
        'pct' => ['image/x-pict'],
        'pcurl' => ['application/vnd.curl.pcurl'],
        'pcx' => ['image/vnd.zbrush.pcx', 'image/x-pcx'],
        'pdb' => ['application/vnd.palm', 'application/x-aportisdoc', 'application/x-palm-database'],
        'pdc' => ['application/x-aportisdoc'],
        'pdf' => ['application/pdf', 'application/acrobat', 'application/nappdf', 'application/x-pdf', 'image/pdf'],
        'pdf.bz2' => ['application/x-bzpdf'],
        'pdf.gz' => ['application/x-gzpdf'],
        'pdf.lz' => ['application/x-lzpdf'],
        'pdf.xz' => ['application/x-xzpdf'],
        'pef' => ['image/x-pentax-pef'],
        'pem' => ['application/x-x509-ca-cert'],
        'perl' => ['application/x-perl', 'text/x-perl'],
        'pfa' => ['application/x-font-type1'],
        'pfb' => ['application/x-font-type1'],
        'pfm' => ['application/x-font-type1'],
        'pfr' => ['application/font-tdpfr'],
        'pfx' => ['application/pkcs12', 'application/x-pkcs12'],
        'pgm' => ['image/x-portable-graymap'],
        'pgn' => ['application/vnd.chess-pgn', 'application/x-chess-pgn'],
        'pgp' => ['application/pgp', 'application/pgp-encrypted', 'application/pgp-keys', 'application/pgp-signature'],
        'php' => ['application/x-php'],
        'php3' => ['application/x-php'],
        'php4' => ['application/x-php'],
        'php5' => ['application/x-php'],
        'phps' => ['application/x-php'],
        'pic' => ['image/x-pict'],
        'pict' => ['image/x-pict'],
        'pict1' => ['image/x-pict'],
        'pict2' => ['image/x-pict'],
        'pk' => ['application/x-tex-pk'],
        'pkg' => ['application/octet-stream', 'application/x-xar'],
        'pki' => ['application/pkixcmp'],
        'pkipath' => ['application/pkix-pkipath'],
        'pkr' => ['application/pgp-keys'],
        'pl' => ['application/x-perl', 'text/x-perl'],
        'pla' => ['audio/x-iriver-pla'],
        'plb' => ['application/vnd.3gpp.pic-bw-large'],
        'plc' => ['application/vnd.mobius.plc'],
        'plf' => ['application/vnd.pocketlearn'],
        'pln' => ['application/x-planperfect'],
        'pls' => ['application/pls', 'application/pls+xml', 'audio/scpls', 'audio/x-scpls'],
        'pm' => ['application/x-pagemaker', 'application/x-perl', 'text/x-perl'],
        'pm6' => ['application/x-pagemaker'],
        'pmd' => ['application/x-pagemaker'],
        'pml' => ['application/vnd.ctc-posml'],
        'png' => ['image/png'],
        'pnm' => ['image/x-portable-anymap'],
        'pntg' => ['image/x-macpaint'],
        'po' => ['application/x-gettext', 'text/x-gettext-translation', 'text/x-po'],
        'pod' => ['application/x-perl', 'text/x-perl'],
        'por' => ['application/x-spss-por'],
        'portpkg' => ['application/vnd.macports.portpkg'],
        'pot' => ['application/mspowerpoint', 'application/powerpoint', 'application/vnd.ms-powerpoint', 'application/x-mspowerpoint', 'text/x-gettext-translation-template', 'text/x-pot'],
        'potm' => ['application/vnd.ms-powerpoint.template.macroenabled.12'],
        'potx' => ['application/vnd.openxmlformats-officedocument.presentationml.template'],
        'ppam' => ['application/vnd.ms-powerpoint.addin.macroenabled.12'],
        'ppd' => ['application/vnd.cups-ppd'],
        'ppm' => ['image/x-portable-pixmap'],
        'pps' => ['application/mspowerpoint', 'application/powerpoint', 'application/vnd.ms-powerpoint', 'application/x-mspowerpoint'],
        'ppsm' => ['application/vnd.ms-powerpoint.slideshow.macroenabled.12'],
        'ppsx' => ['application/vnd.openxmlformats-officedocument.presentationml.slideshow'],
        'ppt' => ['application/vnd.ms-powerpoint', 'application/mspowerpoint', 'application/powerpoint', 'application/x-mspowerpoint'],
        'pptm' => ['application/vnd.ms-powerpoint.presentation.macroenabled.12'],
        'pptx' => ['application/vnd.openxmlformats-officedocument.presentationml.presentation'],
        'ppz' => ['application/mspowerpoint', 'application/powerpoint', 'application/vnd.ms-powerpoint', 'application/x-mspowerpoint'],
        'pqa' => ['application/vnd.palm', 'application/x-palm-database'],
        'prc' => ['application/vnd.palm', 'application/x-mobipocket-ebook', 'application/x-palm-database'],
        'pre' => ['application/vnd.lotus-freelance'],
        'prf' => ['application/pics-rules'],
        'ps' => ['application/postscript'],
        'ps.bz2' => ['application/x-bzpostscript'],
        'ps.gz' => ['application/x-gzpostscript'],
        'psb' => ['application/vnd.3gpp.pic-bw-small'],
        'psd' => ['application/photoshop', 'application/x-photoshop', 'image/photoshop', 'image/psd', 'image/vnd.adobe.photoshop', 'image/x-photoshop', 'image/x-psd'],
        'psf' => ['application/x-font-linux-psf', 'audio/x-psf'],
        'psf.gz' => ['application/x-gz-font-linux-psf'],
        'psflib' => ['audio/x-psflib'],
        'psid' => ['audio/prs.sid'],
        'pskcxml' => ['application/pskc+xml'],
        'psw' => ['application/x-pocket-word'],
        'ptid' => ['application/vnd.pvi.ptid1'],
        'pub' => ['application/vnd.ms-publisher', 'application/x-mspublisher'],
        'pvb' => ['application/vnd.3gpp.pic-bw-var'],
        'pw' => ['application/x-pw'],
        'pwn' => ['application/vnd.3m.post-it-notes'],
        'py' => ['text/x-python', 'text/x-python3'],
        'py3' => ['text/x-python3'],
        'py3x' => ['text/x-python3'],
        'pya' => ['audio/vnd.ms-playready.media.pya'],
        'pyc' => ['application/x-python-bytecode'],
        'pyo' => ['application/x-python-bytecode'],
        'pyv' => ['video/vnd.ms-playready.media.pyv'],
        'pyx' => ['text/x-python'],
        'qam' => ['application/vnd.epson.quickanime'],
        'qbo' => ['application/vnd.intu.qbo'],
        'qd' => ['application/x-fd-file', 'application/x-raw-floppy-disk-image'],
        'qfx' => ['application/vnd.intu.qfx'],
        'qif' => ['application/x-qw', 'image/x-quicktime'],
        'qml' => ['text/x-qml'],
        'qmlproject' => ['text/x-qml'],
        'qmltypes' => ['text/x-qml'],
        'qp' => ['application/x-qpress'],
        'qps' => ['application/vnd.publishare-delta-tree'],
        'qt' => ['video/quicktime'],
        'qti' => ['application/x-qtiplot'],
        'qti.gz' => ['application/x-qtiplot'],
        'qtif' => ['image/x-quicktime'],
        'qtl' => ['application/x-quicktime-media-link', 'application/x-quicktimeplayer'],
        'qtvr' => ['video/quicktime'],
        'qwd' => ['application/vnd.quark.quarkxpress'],
        'qwt' => ['application/vnd.quark.quarkxpress'],
        'qxb' => ['application/vnd.quark.quarkxpress'],
        'qxd' => ['application/vnd.quark.quarkxpress'],
        'qxl' => ['application/vnd.quark.quarkxpress'],
        'qxt' => ['application/vnd.quark.quarkxpress'],
        'ra' => ['audio/vnd.m-realaudio', 'audio/vnd.rn-realaudio', 'audio/x-pn-realaudio'],
        'raf' => ['image/x-fuji-raf'],
        'ram' => ['application/ram', 'audio/x-pn-realaudio'],
        'raml' => ['application/raml+yaml'],
        'rar' => ['application/x-rar-compressed', 'application/vnd.rar', 'application/x-rar'],
        'ras' => ['image/x-cmu-raster'],
        'raw' => ['image/x-panasonic-raw', 'image/x-panasonic-rw'],
        'raw-disk-image' => ['application/x-raw-disk-image'],
        'raw-disk-image.xz' => ['application/x-raw-disk-image-xz-compressed'],
        'rax' => ['audio/vnd.m-realaudio', 'audio/vnd.rn-realaudio', 'audio/x-pn-realaudio'],
        'rb' => ['application/x-ruby'],
        'rcprofile' => ['application/vnd.ipunplugged.rcprofile'],
        'rdf' => ['application/rdf+xml', 'text/rdf'],
        'rdfs' => ['application/rdf+xml', 'text/rdf'],
        'rdz' => ['application/vnd.data-vision.rdz'],
        'reg' => ['text/x-ms-regedit'],
        'rej' => ['application/x-reject', 'text/x-reject'],
        'rep' => ['application/vnd.businessobjects'],
        'res' => ['application/x-dtbresource+xml'],
        'rgb' => ['image/x-rgb'],
        'rif' => ['application/reginfo+xml'],
        'rip' => ['audio/vnd.rip'],
        'ris' => ['application/x-research-info-systems'],
        'rl' => ['application/resource-lists+xml'],
        'rlc' => ['image/vnd.fujixerox.edmics-rlc'],
        'rld' => ['application/resource-lists-diff+xml'],
        'rle' => ['image/rle'],
        'rm' => ['application/vnd.rn-realmedia', 'application/vnd.rn-realmedia-vbr'],
        'rmi' => ['audio/midi'],
        'rmj' => ['application/vnd.rn-realmedia', 'application/vnd.rn-realmedia-vbr'],
        'rmm' => ['application/vnd.rn-realmedia', 'application/vnd.rn-realmedia-vbr'],
        'rmp' => ['audio/x-pn-realaudio-plugin'],
        'rms' => ['application/vnd.jcp.javame.midlet-rms', 'application/vnd.rn-realmedia', 'application/vnd.rn-realmedia-vbr'],
        'rmvb' => ['application/vnd.rn-realmedia', 'application/vnd.rn-realmedia-vbr'],
        'rmx' => ['application/vnd.rn-realmedia', 'application/vnd.rn-realmedia-vbr'],
        'rnc' => ['application/relax-ng-compact-syntax', 'application/x-rnc'],
        'rng' => ['application/xml', 'text/xml'],
        'roa' => ['application/rpki-roa'],
        'roff' => ['application/x-troff', 'text/troff', 'text/x-troff'],
        'rp' => ['image/vnd.rn-realpix'],
        'rp9' => ['application/vnd.cloanto.rp9'],
        'rpm' => ['application/x-redhat-package-manager', 'application/x-rpm'],
        'rpss' => ['application/vnd.nokia.radio-presets'],
        'rpst' => ['application/vnd.nokia.radio-preset'],
        'rq' => ['application/sparql-query'],
        'rs' => ['application/rls-services+xml', 'text/rust'],
        'rsd' => ['application/rsd+xml'],
        'rss' => ['application/rss+xml', 'text/rss'],
        'rt' => ['text/vnd.rn-realtext'],
        'rtf' => ['application/rtf', 'text/rtf'],
        'rtx' => ['text/richtext'],
        'rv' => ['video/vnd.rn-realvideo', 'video/x-real-video'],
        'rvx' => ['video/vnd.rn-realvideo', 'video/x-real-video'],
        'rw2' => ['image/x-panasonic-raw2', 'image/x-panasonic-rw2'],
        's' => ['text/x-asm'],
        's3m' => ['audio/s3m', 'audio/x-s3m'],
        'saf' => ['application/vnd.yamaha.smaf-audio'],
        'sam' => ['application/x-amipro'],
        'sami' => ['application/x-sami'],
        'sap' => ['application/x-sap-file', 'application/x-thomson-sap-image'],
        'sass' => ['text/x-sass'],
        'sav' => ['application/x-spss-sav', 'application/x-spss-savefile'],
        'sbml' => ['application/sbml+xml'],
        'sc' => ['application/vnd.ibm.secure-container'],
        'scala' => ['text/x-scala'],
        'scd' => ['application/x-msschedule'],
        'scm' => ['application/vnd.lotus-screencam', 'text/x-scheme'],
        'scope' => ['text/x-systemd-unit'],
        'scq' => ['application/scvp-cv-request'],
        'scs' => ['application/scvp-cv-response'],
        'scss' => ['text/x-scss'],
        'scurl' => ['text/vnd.curl.scurl'],
        'sda' => ['application/vnd.stardivision.draw'],
        'sdc' => ['application/vnd.stardivision.calc'],
        'sdd' => ['application/vnd.stardivision.impress'],
        'sdkd' => ['application/vnd.solent.sdkm+xml'],
        'sdkm' => ['application/vnd.solent.sdkm+xml'],
        'sdp' => ['application/sdp', 'application/vnd.sdp', 'application/vnd.stardivision.impress', 'application/x-sdp'],
        'sds' => ['application/vnd.stardivision.chart'],
        'sdw' => ['application/vnd.stardivision.writer', 'application/vnd.stardivision.writer-global'],
        'see' => ['application/vnd.seemail'],
        'seed' => ['application/vnd.fdsn.seed'],
        'sema' => ['application/vnd.sema'],
        'semd' => ['application/vnd.semd'],
        'semf' => ['application/vnd.semf'],
        'ser' => ['application/java-serialized-object'],
        'service' => ['text/x-dbus-service', 'text/x-systemd-unit'],
        'setpay' => ['application/set-payment-initiation'],
        'setreg' => ['application/set-registration-initiation'],
        'sfc' => ['application/vnd.nintendo.snes.rom', 'application/x-snes-rom'],
        'sfd-hdstx' => ['application/vnd.hydrostatix.sof-data'],
        'sfs' => ['application/vnd.spotfire.sfs'],
        'sfv' => ['text/x-sfv'],
        'sg' => ['application/x-sg1000-rom'],
        'sgb' => ['application/x-gameboy-rom'],
        'sgf' => ['application/x-go-sgf'],
        'sgi' => ['image/sgi', 'image/x-sgi'],
        'sgl' => ['application/vnd.stardivision.writer', 'application/vnd.stardivision.writer-global'],
        'sgm' => ['text/sgml'],
        'sgml' => ['text/sgml'],
        'sh' => ['application/x-sh', 'application/x-shellscript', 'text/x-sh'],
        'shape' => ['application/x-dia-shape'],
        'shar' => ['application/x-shar'],
        'shf' => ['application/shf+xml'],
        'shn' => ['application/x-shorten', 'audio/x-shorten'],
        'siag' => ['application/x-siag'],
        'sid' => ['audio/prs.sid', 'image/x-mrsid-image'],
        'sig' => ['application/pgp-signature'],
        'sik' => ['application/x-trash'],
        'sil' => ['audio/silk'],
        'silo' => ['model/mesh'],
        'sis' => ['application/vnd.symbian.install'],
        'sisx' => ['application/vnd.symbian.install', 'x-epoc/x-sisx-app'],
        'sit' => ['application/x-stuffit', 'application/stuffit', 'application/x-sit'],
        'sitx' => ['application/x-stuffitx'],
        'siv' => ['application/sieve'],
        'sk' => ['image/x-skencil'],
        'sk1' => ['image/x-skencil'],
        'skd' => ['application/vnd.koan'],
        'skm' => ['application/vnd.koan'],
        'skp' => ['application/vnd.koan'],
        'skr' => ['application/pgp-keys'],
        'skt' => ['application/vnd.koan'],
        'sldm' => ['application/vnd.ms-powerpoint.slide.macroenabled.12'],
        'sldx' => ['application/vnd.openxmlformats-officedocument.presentationml.slide'],
        'slice' => ['text/x-systemd-unit'],
        'slk' => ['text/spreadsheet'],
        'slt' => ['application/vnd.epson.salt'],
        'sm' => ['application/vnd.stepmania.stepchart'],
        'smaf' => ['application/vnd.smaf', 'application/x-smaf'],
        'smc' => ['application/vnd.nintendo.snes.rom', 'application/x-snes-rom'],
        'smd' => ['application/vnd.stardivision.mail', 'application/x-genesis-rom'],
        'smf' => ['application/vnd.stardivision.math'],
        'smi' => ['application/smil', 'application/smil+xml', 'application/x-sami'],
        'smil' => ['application/smil', 'application/smil+xml'],
        'sml' => ['application/smil', 'application/smil+xml'],
        'sms' => ['application/x-sms-rom'],
        'smv' => ['video/x-smv'],
        'smzip' => ['application/vnd.stepmania.package'],
        'snap' => ['application/vnd.snap'],
        'snd' => ['audio/basic'],
        'snf' => ['application/x-font-snf'],
        'so' => ['application/octet-stream', 'application/x-sharedlib'],
        'socket' => ['text/x-systemd-unit'],
        'spc' => ['application/x-pkcs7-certificates'],
        'spd' => ['application/x-font-speedo'],
        'spec' => ['text/x-rpm-spec'],
        'spf' => ['application/vnd.yamaha.smaf-phrase'],
        'spl' => ['application/futuresplash', 'application/vnd.adobe.flash.movie', 'application/x-futuresplash', 'application/x-shockwave-flash'],
        'spm' => ['application/x-source-rpm'],
        'spot' => ['text/vnd.in3d.spot'],
        'spp' => ['application/scvp-vp-response'],
        'spq' => ['application/scvp-vp-request'],
        'spx' => ['audio/ogg', 'audio/x-speex'],
        'sql' => ['application/sql', 'application/x-sql', 'text/x-sql'],
        'sqlite2' => ['application/x-sqlite2'],
        'sqlite3' => ['application/vnd.sqlite3', 'application/x-sqlite3'],
        'sqsh' => ['application/vnd.squashfs'],
        'sr2' => ['image/x-sony-sr2'],
        'src' => ['application/x-wais-source'],
        'src.rpm' => ['application/x-source-rpm'],
        'srf' => ['image/x-sony-srf'],
        'srt' => ['application/x-srt', 'application/x-subrip'],
        'sru' => ['application/sru+xml'],
        'srx' => ['application/sparql-results+xml'],
        'ss' => ['text/x-scheme'],
        'ssa' => ['text/x-ssa'],
        'ssdl' => ['application/ssdl+xml'],
        'sse' => ['application/vnd.kodak-descriptor'],
        'ssf' => ['application/vnd.epson.ssf'],
        'ssml' => ['application/ssml+xml'],
        'st' => ['application/vnd.sailingtracker.track'],
        'stc' => ['application/vnd.sun.xml.calc.template'],
        'std' => ['application/vnd.sun.xml.draw.template'],
        'stf' => ['application/vnd.wt.stf'],
        'sti' => ['application/vnd.sun.xml.impress.template'],
        'stk' => ['application/hyperstudio'],
        'stl' => ['application/vnd.ms-pki.stl', 'model/stl', 'model/x.stl-ascii', 'model/x.stl-binary'],
        'stm' => ['audio/x-stm'],
        'str' => ['application/vnd.pg.format'],
        'stw' => ['application/vnd.sun.xml.writer.template'],
        'sty' => ['application/x-tex', 'text/x-tex'],
        'sub' => ['image/vnd.dvb.subtitle', 'text/vnd.dvb.subtitle', 'text/x-microdvd', 'text/x-mpsub', 'text/x-subviewer'],
        'sun' => ['image/x-sun-raster'],
        'sus' => ['application/vnd.sus-calendar'],
        'susp' => ['application/vnd.sus-calendar'],
        'sv' => ['text/x-svsrc'],
        'sv4cpio' => ['application/x-sv4cpio'],
        'sv4crc' => ['application/x-sv4crc'],
        'svc' => ['application/vnd.dvb.service'],
        'svd' => ['application/vnd.svd'],
        'svg' => ['image/svg+xml', 'image/svg'],
        'svgz' => ['image/svg+xml', 'image/svg+xml-compressed'],
        'svh' => ['text/x-svhdr'],
        'swa' => ['application/x-director'],
        'swap' => ['text/x-systemd-unit'],
        'swf' => ['application/futuresplash', 'application/vnd.adobe.flash.movie', 'application/x-shockwave-flash'],
        'swi' => ['application/vnd.aristanetworks.swi'],
        'swm' => ['application/x-ms-wim'],
        'sxc' => ['application/vnd.sun.xml.calc'],
        'sxd' => ['application/vnd.sun.xml.draw'],
        'sxg' => ['application/vnd.sun.xml.writer.global'],
        'sxi' => ['application/vnd.sun.xml.impress'],
        'sxm' => ['application/vnd.sun.xml.math'],
        'sxw' => ['application/vnd.sun.xml.writer'],
        'sylk' => ['text/spreadsheet'],
        't' => ['application/x-perl', 'application/x-troff', 'text/troff', 'text/x-perl', 'text/x-troff'],
        't2t' => ['text/x-txt2tags'],
        't3' => ['application/x-t3vm-image'],
        'taglet' => ['application/vnd.mynfc'],
        'tao' => ['application/vnd.tao.intent-module-archive'],
        'tar' => ['application/x-tar', 'application/x-gtar'],
        'tar.Z' => ['application/x-tarz'],
        'tar.bz' => ['application/x-bzip-compressed-tar'],
        'tar.bz2' => ['application/x-bzip-compressed-tar'],
        'tar.gz' => ['application/x-compressed-tar'],
        'tar.lrz' => ['application/x-lrzip-compressed-tar'],
        'tar.lz' => ['application/x-lzip-compressed-tar'],
        'tar.lz4' => ['application/x-lz4-compressed-tar'],
        'tar.lzma' => ['application/x-lzma-compressed-tar'],
        'tar.lzo' => ['application/x-tzo'],
        'tar.xz' => ['application/x-xz-compressed-tar'],
        'target' => ['text/x-systemd-unit'],
        'taz' => ['application/x-tarz'],
        'tb2' => ['application/x-bzip-compressed-tar'],
        'tbz' => ['application/x-bzip-compressed-tar'],
        'tbz2' => ['application/x-bzip-compressed-tar'],
        'tcap' => ['application/vnd.3gpp2.tcap'],
        'tcl' => ['application/x-tcl', 'text/x-tcl'],
        'teacher' => ['application/vnd.smart.teacher'],
        'tei' => ['application/tei+xml'],
        'teicorpus' => ['application/tei+xml'],
        'tex' => ['application/x-tex', 'text/x-tex'],
        'texi' => ['application/x-texinfo', 'text/x-texinfo'],
        'texinfo' => ['application/x-texinfo', 'text/x-texinfo'],
        'text' => ['text/plain'],
        'tfi' => ['application/thraud+xml'],
        'tfm' => ['application/x-tex-tfm'],
        'tga' => ['image/x-icb', 'image/x-tga'],
        'tgz' => ['application/x-compressed-tar'],
        'theme' => ['application/x-theme'],
        'themepack' => ['application/x-windows-themepack'],
        'thmx' => ['application/vnd.ms-officetheme'],
        'tif' => ['image/tiff'],
        'tiff' => ['image/tiff'],
        'timer' => ['text/x-systemd-unit'],
        'tk' => ['text/x-tcl'],
        'tlrz' => ['application/x-lrzip-compressed-tar'],
        'tlz' => ['application/x-lzma-compressed-tar'],
        'tmo' => ['application/vnd.tmobile-livetv'],
        'tnef' => ['application/ms-tnef', 'application/vnd.ms-tnef'],
        'tnf' => ['application/ms-tnef', 'application/vnd.ms-tnef'],
        'toc' => ['application/x-cdrdao-toc'],
        'torrent' => ['application/x-bittorrent'],
        'tpic' => ['image/x-icb', 'image/x-tga'],
        'tpl' => ['application/vnd.groove-tool-template'],
        'tpt' => ['application/vnd.trid.tpt'],
        'tr' => ['application/x-troff', 'text/troff', 'text/x-troff'],
        'tra' => ['application/vnd.trueapp'],
        'trig' => ['application/trig', 'application/x-trig'],
        'trm' => ['application/x-msterminal'],
        'ts' => ['application/x-linguist', 'text/vnd.qt.linguist', 'text/vnd.trolltech.linguist', 'video/mp2t'],
        'tsd' => ['application/timestamped-data'],
        'tsv' => ['text/tab-separated-values'],
        'tta' => ['audio/tta', 'audio/x-tta'],
        'ttc' => ['font/collection'],
        'ttf' => ['application/x-font-truetype', 'application/x-font-ttf', 'font/ttf'],
        'ttl' => ['text/turtle'],
        'ttx' => ['application/x-font-ttx'],
        'twd' => ['application/vnd.simtech-mindmapper'],
        'twds' => ['application/vnd.simtech-mindmapper'],
        'twig' => ['text/x-twig'],
        'txd' => ['application/vnd.genomatix.tuxedo'],
        'txf' => ['application/vnd.mobius.txf'],
        'txt' => ['text/plain'],
        'txz' => ['application/x-xz-compressed-tar'],
        'tzo' => ['application/x-tzo'],
        'u32' => ['application/x-authorware-bin'],
        'udeb' => ['application/vnd.debian.binary-package', 'application/x-deb', 'application/x-debian-package'],
        'ufd' => ['application/vnd.ufdl'],
        'ufdl' => ['application/vnd.ufdl'],
        'ufraw' => ['application/x-ufraw'],
        'ui' => ['application/x-designer', 'application/x-gtk-builder'],
        'uil' => ['text/x-uil'],
        'ult' => ['audio/x-mod'],
        'ulx' => ['application/x-glulx'],
        'umj' => ['application/vnd.umajin'],
        'unf' => ['application/x-nes-rom'],
        'uni' => ['audio/x-mod'],
        'unif' => ['application/x-nes-rom'],
        'unityweb' => ['application/vnd.unity'],
        'uoml' => ['application/vnd.uoml+xml'],
        'uri' => ['text/uri-list'],
        'uris' => ['text/uri-list'],
        'url' => ['application/x-mswinurl'],
        'urls' => ['text/uri-list'],
        'ustar' => ['application/x-ustar'],
        'utz' => ['application/vnd.uiq.theme'],
        'uu' => ['text/x-uuencode'],
        'uue' => ['text/x-uuencode', 'zz-application/zz-winassoc-uu'],
        'uva' => ['audio/vnd.dece.audio'],
        'uvd' => ['application/vnd.dece.data'],
        'uvf' => ['application/vnd.dece.data'],
        'uvg' => ['image/vnd.dece.graphic'],
        'uvh' => ['video/vnd.dece.hd'],
        'uvi' => ['image/vnd.dece.graphic'],
        'uvm' => ['video/vnd.dece.mobile'],
        'uvp' => ['video/vnd.dece.pd'],
        'uvs' => ['video/vnd.dece.sd'],
        'uvt' => ['application/vnd.dece.ttml+xml'],
        'uvu' => ['video/vnd.uvvu.mp4'],
        'uvv' => ['video/vnd.dece.video'],
        'uvva' => ['audio/vnd.dece.audio'],
        'uvvd' => ['application/vnd.dece.data'],
        'uvvf' => ['application/vnd.dece.data'],
        'uvvg' => ['image/vnd.dece.graphic'],
        'uvvh' => ['video/vnd.dece.hd'],
        'uvvi' => ['image/vnd.dece.graphic'],
        'uvvm' => ['video/vnd.dece.mobile'],
        'uvvp' => ['video/vnd.dece.pd'],
        'uvvs' => ['video/vnd.dece.sd'],
        'uvvt' => ['application/vnd.dece.ttml+xml'],
        'uvvu' => ['video/vnd.uvvu.mp4'],
        'uvvv' => ['video/vnd.dece.video'],
        'uvvx' => ['application/vnd.dece.unspecified'],
        'uvvz' => ['application/vnd.dece.zip'],
        'uvx' => ['application/vnd.dece.unspecified'],
        'uvz' => ['application/vnd.dece.zip'],
        'v' => ['text/x-verilog'],
        'v64' => ['application/x-n64-rom'],
        'vala' => ['text/x-vala'],
        'vapi' => ['text/x-vala'],
        'vb' => ['application/x-virtual-boy-rom'],
        'vcard' => ['text/directory', 'text/vcard', 'text/x-vcard'],
        'vcd' => ['application/x-cdlink'],
        'vcf' => ['text/x-vcard', 'text/directory', 'text/vcard'],
        'vcg' => ['application/vnd.groove-vcard'],
        'vcs' => ['application/ics', 'text/calendar', 'text/x-vcalendar'],
        'vct' => ['text/directory', 'text/vcard', 'text/x-vcard'],
        'vcx' => ['application/vnd.vcx'],
        'vda' => ['image/x-icb', 'image/x-tga'],
        'vhd' => ['text/x-vhdl'],
        'vhdl' => ['text/x-vhdl'],
        'vis' => ['application/vnd.visionary'],
        'viv' => ['video/vivo', 'video/vnd.vivo'],
        'vivo' => ['video/vivo', 'video/vnd.vivo'],
        'vlc' => ['application/m3u', 'audio/m3u', 'audio/mpegurl', 'audio/x-m3u', 'audio/x-mp3-playlist', 'audio/x-mpegurl'],
        'vob' => ['video/mpeg', 'video/mpeg-system', 'video/x-mpeg', 'video/x-mpeg-system', 'video/x-mpeg2', 'video/x-ms-vob'],
        'voc' => ['audio/x-voc'],
        'vor' => ['application/vnd.stardivision.writer', 'application/vnd.stardivision.writer-global'],
        'vox' => ['application/x-authorware-bin'],
        'vrm' => ['model/vrml'],
        'vrml' => ['model/vrml'],
        'vsd' => ['application/vnd.visio'],
        'vsdm' => ['application/vnd.ms-visio.drawing.macroenabled.main+xml'],
        'vsdx' => ['application/vnd.ms-visio.drawing.main+xml'],
        'vsf' => ['application/vnd.vsf'],
        'vss' => ['application/vnd.visio'],
        'vssm' => ['application/vnd.ms-visio.stencil.macroenabled.main+xml'],
        'vssx' => ['application/vnd.ms-visio.stencil.main+xml'],
        'vst' => ['application/vnd.visio', 'image/x-icb', 'image/x-tga'],
        'vstm' => ['application/vnd.ms-visio.template.macroenabled.main+xml'],
        'vstx' => ['application/vnd.ms-visio.template.main+xml'],
        'vsw' => ['application/vnd.visio'],
        'vtt' => ['text/vtt'],
        'vtu' => ['model/vnd.vtu'],
        'vxml' => ['application/voicexml+xml'],
        'w3d' => ['application/x-director'],
        'wad' => ['application/x-doom', 'application/x-doom-wad', 'application/x-wii-wad'],
        'wav' => ['audio/wav', 'audio/vnd.wave', 'audio/x-wav'],
        'wax' => ['application/x-ms-asx', 'audio/x-ms-asx', 'audio/x-ms-wax', 'video/x-ms-wax', 'video/x-ms-wmx', 'video/x-ms-wvx'],
        'wb1' => ['application/x-quattropro'],
        'wb2' => ['application/x-quattropro'],
        'wb3' => ['application/x-quattropro'],
        'wbmp' => ['image/vnd.wap.wbmp'],
        'wbs' => ['application/vnd.criticaltools.wbs+xml'],
        'wbxml' => ['application/vnd.wap.wbxml'],
        'wcm' => ['application/vnd.ms-works'],
        'wdb' => ['application/vnd.ms-works'],
        'wdp' => ['image/vnd.ms-photo'],
        'weba' => ['audio/webm'],
        'webm' => ['video/webm'],
        'webp' => ['image/webp'],
        'wg' => ['application/vnd.pmi.widget'],
        'wgt' => ['application/widget'],
        'wim' => ['application/x-ms-wim'],
        'wk1' => ['application/lotus123', 'application/vnd.lotus-1-2-3', 'application/wk1', 'application/x-123', 'application/x-lotus123', 'zz-application/zz-winassoc-123'],
        'wk3' => ['application/lotus123', 'application/vnd.lotus-1-2-3', 'application/wk1', 'application/x-123', 'application/x-lotus123', 'zz-application/zz-winassoc-123'],
        'wk4' => ['application/lotus123', 'application/vnd.lotus-1-2-3', 'application/wk1', 'application/x-123', 'application/x-lotus123', 'zz-application/zz-winassoc-123'],
        'wkdownload' => ['application/x-partial-download'],
        'wks' => ['application/lotus123', 'application/vnd.lotus-1-2-3', 'application/vnd.ms-works', 'application/wk1', 'application/x-123', 'application/x-lotus123', 'zz-application/zz-winassoc-123'],
        'wm' => ['video/x-ms-wm'],
        'wma' => ['audio/x-ms-wma', 'audio/wma'],
        'wmd' => ['application/x-ms-wmd'],
        'wmf' => ['application/wmf', 'application/x-msmetafile', 'application/x-wmf', 'image/wmf', 'image/x-win-metafile', 'image/x-wmf'],
        'wml' => ['text/vnd.wap.wml'],
        'wmlc' => ['application/vnd.wap.wmlc'],
        'wmls' => ['text/vnd.wap.wmlscript'],
        'wmlsc' => ['application/vnd.wap.wmlscriptc'],
        'wmv' => ['audio/x-ms-wmv', 'video/x-ms-wmv'],
        'wmx' => ['application/x-ms-asx', 'audio/x-ms-asx', 'video/x-ms-wax', 'video/x-ms-wmx', 'video/x-ms-wvx'],
        'wmz' => ['application/x-ms-wmz', 'application/x-msmetafile'],
        'woff' => ['application/font-woff', 'application/x-font-woff', 'font/woff'],
        'woff2' => ['font/woff', 'font/woff2'],
        'wp' => ['application/vnd.wordperfect', 'application/wordperfect', 'application/x-wordperfect'],
        'wp4' => ['application/vnd.wordperfect', 'application/wordperfect', 'application/x-wordperfect'],
        'wp5' => ['application/vnd.wordperfect', 'application/wordperfect', 'application/x-wordperfect'],
        'wp6' => ['application/vnd.wordperfect', 'application/wordperfect', 'application/x-wordperfect'],
        'wpd' => ['application/vnd.wordperfect', 'application/wordperfect', 'application/x-wordperfect'],
        'wpg' => ['application/x-wpg'],
        'wpl' => ['application/vnd.ms-wpl'],
        'wpp' => ['application/vnd.wordperfect', 'application/wordperfect', 'application/x-wordperfect'],
        'wps' => ['application/vnd.ms-works'],
        'wqd' => ['application/vnd.wqd'],
        'wri' => ['application/x-mswrite'],
        'wrl' => ['model/vrml'],
        'ws' => ['application/x-wonderswan-rom'],
        'wsc' => ['application/x-wonderswan-color-rom'],
        'wsdl' => ['application/wsdl+xml'],
        'wsgi' => ['text/x-python'],
        'wspolicy' => ['application/wspolicy+xml'],
        'wtb' => ['application/vnd.webturbo'],
        'wv' => ['audio/x-wavpack'],
        'wvc' => ['audio/x-wavpack-correction'],
        'wvp' => ['audio/x-wavpack'],
        'wvx' => ['application/x-ms-asx', 'audio/x-ms-asx', 'video/x-ms-wax', 'video/x-ms-wmx', 'video/x-ms-wvx'],
        'wwf' => ['application/wwf', 'application/x-wwf'],
        'x32' => ['application/x-authorware-bin'],
        'x3d' => ['model/x3d+xml'],
        'x3db' => ['model/x3d+binary'],
        'x3dbz' => ['model/x3d+binary'],
        'x3dv' => ['model/x3d+vrml'],
        'x3dvz' => ['model/x3d+vrml'],
        'x3dz' => ['model/x3d+xml'],
        'x3f' => ['image/x-sigma-x3f'],
        'xac' => ['application/x-gnucash'],
        'xaml' => ['application/xaml+xml'],
        'xap' => ['application/x-silverlight-app'],
        'xar' => ['application/vnd.xara', 'application/x-xar'],
        'xbap' => ['application/x-ms-xbap'],
        'xbd' => ['application/vnd.fujixerox.docuworks.binder'],
        'xbel' => ['application/x-xbel'],
        'xbl' => ['application/xml', 'text/xml'],
        'xbm' => ['image/x-xbitmap'],
        'xcf' => ['image/x-xcf'],
        'xcf.bz2' => ['image/x-compressed-xcf'],
        'xcf.gz' => ['image/x-compressed-xcf'],
        'xdf' => ['application/xcap-diff+xml'],
        'xdgapp' => ['application/vnd.flatpak', 'application/vnd.xdgapp'],
        'xdm' => ['application/vnd.syncml.dm+xml'],
        'xdp' => ['application/vnd.adobe.xdp+xml'],
        'xdssc' => ['application/dssc+xml'],
        'xdw' => ['application/vnd.fujixerox.docuworks'],
        'xenc' => ['application/xenc+xml'],
        'xer' => ['application/patch-ops-error+xml'],
        'xfdf' => ['application/vnd.adobe.xfdf'],
        'xfdl' => ['application/vnd.xfdl'],
        'xhe' => ['audio/usac'],
        'xht' => ['application/xhtml+xml'],
        'xhtml' => ['application/xhtml+xml'],
        'xhvml' => ['application/xv+xml'],
        'xi' => ['audio/x-xi'],
        'xif' => ['image/vnd.xiff'],
        'xla' => ['application/msexcel', 'application/vnd.ms-excel', 'application/x-msexcel', 'zz-application/zz-winassoc-xls'],
        'xlam' => ['application/vnd.ms-excel.addin.macroenabled.12'],
        'xlc' => ['application/msexcel', 'application/vnd.ms-excel', 'application/x-msexcel', 'zz-application/zz-winassoc-xls'],
        'xld' => ['application/msexcel', 'application/vnd.ms-excel', 'application/x-msexcel', 'zz-application/zz-winassoc-xls'],
        'xlf' => ['application/x-xliff', 'application/x-xliff+xml', 'application/xliff+xml'],
        'xliff' => ['application/x-xliff', 'application/xliff+xml'],
        'xll' => ['application/msexcel', 'application/vnd.ms-excel', 'application/x-msexcel', 'zz-application/zz-winassoc-xls'],
        'xlm' => ['application/msexcel', 'application/vnd.ms-excel', 'application/x-msexcel', 'zz-application/zz-winassoc-xls'],
        'xlr' => ['application/vnd.ms-works'],
        'xls' => ['application/vnd.ms-excel', 'application/msexcel', 'application/x-msexcel', 'zz-application/zz-winassoc-xls'],
        'xlsb' => ['application/vnd.ms-excel.sheet.binary.macroenabled.12'],
        'xlsm' => ['application/vnd.ms-excel.sheet.macroenabled.12'],
        'xlsx' => ['application/vnd.openxmlformats-officedocument.spreadsheetml.sheet'],
        'xlt' => ['application/msexcel', 'application/vnd.ms-excel', 'application/x-msexcel', 'zz-application/zz-winassoc-xls'],
        'xltm' => ['application/vnd.ms-excel.template.macroenabled.12'],
        'xltx' => ['application/vnd.openxmlformats-officedocument.spreadsheetml.template'],
        'xlw' => ['application/msexcel', 'application/vnd.ms-excel', 'application/x-msexcel', 'zz-application/zz-winassoc-xls'],
        'xm' => ['audio/x-xm', 'audio/xm'],
        'xmf' => ['audio/mobile-xmf', 'audio/x-xmf', 'audio/xmf'],
        'xmi' => ['text/x-xmi'],
        'xml' => ['application/xml', 'text/xml'],
        'xo' => ['application/vnd.olpc-sugar'],
        'xop' => ['application/xop+xml'],
        'xpi' => ['application/x-xpinstall'],
        'xpl' => ['application/xproc+xml'],
        'xpm' => ['image/x-xpixmap', 'image/x-xpm'],
        'xpr' => ['application/vnd.is-xpr'],
        'xps' => ['application/oxps', 'application/vnd.ms-xpsdocument', 'application/xps'],
        'xpw' => ['application/vnd.intercon.formnet'],
        'xpx' => ['application/vnd.intercon.formnet'],
        'xsd' => ['application/xml', 'text/xml'],
        'xsl' => ['application/xml', 'application/xslt+xml'],
        'xslfo' => ['text/x-xslfo'],
        'xslt' => ['application/xslt+xml'],
        'xsm' => ['application/vnd.syncml+xml'],
        'xspf' => ['application/x-xspf+xml', 'application/xspf+xml'],
        'xul' => ['application/vnd.mozilla.xul+xml'],
        'xvm' => ['application/xv+xml'],
        'xvml' => ['application/xv+xml'],
        'xwd' => ['image/x-xwindowdump'],
        'xyz' => ['chemical/x-xyz'],
        'xz' => ['application/x-xz'],
        'yaml' => ['application/x-yaml', 'text/x-yaml', 'text/yaml'],
        'yang' => ['application/yang'],
        'yin' => ['application/yin+xml'],
        'yml' => ['application/x-yaml', 'text/x-yaml', 'text/yaml'],
        'yt' => ['application/vnd.youtube.yt'],
        'z1' => ['application/x-zmachine'],
        'z2' => ['application/x-zmachine'],
        'z3' => ['application/x-zmachine'],
        'z4' => ['application/x-zmachine'],
        'z5' => ['application/x-zmachine'],
        'z6' => ['application/x-zmachine'],
        'z64' => ['application/x-n64-rom'],
        'z7' => ['application/x-zmachine'],
        'z8' => ['application/x-zmachine'],
        'zabw' => ['application/x-abiword'],
        'zaz' => ['application/vnd.zzazz.deck+xml'],
        'zip' => ['application/zip', 'application/x-zip', 'application/x-zip-compressed'],
        'zir' => ['application/vnd.zul'],
        'zirz' => ['application/vnd.zul'],
        'zmm' => ['application/vnd.handheld-entertainment+xml'],
        'zoo' => ['application/x-zoo'],
        'zsav' => ['application/x-spss-sav', 'application/x-spss-savefile'],
        'zz' => ['application/zlib'],
        '123' => ['application/lotus123', 'application/vnd.lotus-1-2-3', 'application/wk1', 'application/x-123', 'application/x-lotus123', 'zz-application/zz-winassoc-123'],
        '602' => ['application/x-t602'],
        '669' => ['audio/x-mod'],
    ];
}
PKϤ$Z|�|���mime/README.mdnu�[���MIME Component
==============

The MIME component allows manipulating MIME messages.

Resources
---------

  * [Documentation](https://symfony.com/doc/current/components/mime.html)
  * [Contributing](https://symfony.com/doc/current/contributing/index.html)
  * [Report issues](https://github.com/symfony/symfony/issues) and
    [send Pull Requests](https://github.com/symfony/symfony/pulls)
    in the [main Symfony repository](https://github.com/symfony/symfony)
PKϤ$Z0��M??(mime/Resources/bin/update_mime_types.phpnu�[���<?php

/*
 * This file is part of the Symfony package.
 *
 * (c) Fabien Potencier <fabien@symfony.com>
 *
 * For the full copyright and license information, please view the LICENSE
 * file that was distributed with this source code.
 */

// load new map
$data = file_get_contents('https://svn.apache.org/repos/asf/httpd/httpd/trunk/docs/conf/mime.types');
$new = [];
foreach (explode("\n", $data) as $line) {
    if (!$line || '#' == $line[0]) {
        continue;
    }
    $mimeType = substr($line, 0, strpos($line, "\t"));
    $extensions = explode(' ', substr($line, strrpos($line, "\t") + 1));
    $new[$mimeType] = $extensions;
}

$xml = simplexml_load_string(file_get_contents('https://raw.github.com/minad/mimemagic/master/script/freedesktop.org.xml'));
foreach ($xml as $node) {
    $exts = [];
    foreach ($node->glob as $glob) {
        $pattern = (string) $glob['pattern'];
        if ('*' != $pattern[0] || '.' != $pattern[1]) {
            continue;
        }

        $exts[] = substr($pattern, 2);
    }

    if (!$exts) {
        continue;
    }

    $mt = strtolower((string) $node['type']);
    $new[$mt] = array_merge($new[$mt] ?? [], $exts);
    foreach ($node->alias as $alias) {
        $mt = strtolower((string) $alias['type']);
        $new[$mt] = array_merge($new[$mt] ?? [], $exts);
    }
}

// load current map
$data = file_get_contents($output = __DIR__.'/../../MimeTypes.php');
$current = [];
$pre = '';
$post = '';
foreach (explode("\n", $data) as $line) {
    if (!preg_match("{^        '([^']+/[^']+)' => \['(.+)'\],$}", $line, $matches)) {
        if (!$current) {
            $pre .= $line."\n";
        } else {
            $post .= $line."\n";
        }
        continue;
    }
    $current[$matches[1]] = explode("', '", $matches[2]);
}

// we merge the 2 maps (we never remove old mime types)
$map = array_replace_recursive($current, $new);
ksort($map);

$data = $pre;
foreach ($map as $mimeType => $exts) {
    $data .= sprintf("        '%s' => ['%s'],\n", $mimeType, implode("', '", array_unique($exts)));
}
$data .= $post;

// reverse map
// we prefill the extensions with some preferences for content-types
$exts = [
    'aif' => ['audio/x-aiff'],
    'aiff' => ['audio/x-aiff'],
    'aps' => ['application/postscript'],
    'avi' => ['video/avi'],
    'bmp' => ['image/bmp'],
    'bz2' => ['application/x-bz2'],
    'css' => ['text/css'],
    'csv' => ['text/csv'],
    'dmg' => ['application/x-apple-diskimage'],
    'doc' => ['application/msword'],
    'docx' => ['application/vnd.openxmlformats-officedocument.wordprocessingml.document'],
    'eml' => ['message/rfc822'],
    'exe' => ['application/x-ms-dos-executable'],
    'flv' => ['video/x-flv'],
    'gif' => ['image/gif'],
    'gz' => ['application/x-gzip'],
    'hqx' => ['application/stuffit'],
    'htm' => ['text/html'],
    'html' => ['text/html'],
    'jar' => ['application/x-java-archive'],
    'jpeg' => ['image/jpeg'],
    'jpg' => ['image/jpeg'],
    'js' => ['text/javascript'],
    'm3u' => ['audio/x-mpegurl'],
    'm4a' => ['audio/mp4'],
    'mdb' => ['application/x-msaccess'],
    'mid' => ['audio/midi'],
    'midi' => ['audio/midi'],
    'mov' => ['video/quicktime'],
    'mp3' => ['audio/mpeg'],
    'mp4' => ['video/mp4'],
    'mpeg' => ['video/mpeg'],
    'mpg' => ['video/mpeg'],
    'ogg' => ['audio/ogg'],
    'pdf' => ['application/pdf'],
    'php' => ['application/x-php'],
    'php3' => ['application/x-php'],
    'php4' => ['application/x-php'],
    'php5' => ['application/x-php'],
    'png' => ['image/png'],
    'ppt' => ['application/vnd.ms-powerpoint'],
    'pptx' => ['application/vnd.openxmlformats-officedocument.presentationml.presentation'],
    'ps' => ['application/postscript'],
    'rar' => ['application/x-rar-compressed'],
    'rtf' => ['application/rtf'],
    'sit' => ['application/x-stuffit'],
    'svg' => ['image/svg+xml'],
    'tar' => ['application/x-tar'],
    'tif' => ['image/tiff'],
    'tiff' => ['image/tiff'],
    'ttf' => ['application/x-font-truetype'],
    'txt' => ['text/plain'],
    'vcf' => ['text/x-vcard'],
    'wav' => ['audio/wav'],
    'wma' => ['audio/x-ms-wma'],
    'wmv' => ['audio/x-ms-wmv'],
    'xls' => ['application/vnd.ms-excel'],
    'xlsx' => ['application/vnd.openxmlformats-officedocument.spreadsheetml.sheet'],
    'xml' => ['application/xml'],
    'zip' => ['application/zip'],
];
foreach ($map as $mimeType => $extensions) {
    foreach ($extensions as $extension) {
        $exts[$extension][] = $mimeType;
    }
}
ksort($exts);

$updated = '';
$state = 0;
foreach (explode("\n", $data) as $line) {
    if (!preg_match("{^        '([^'/]+)' => \['(.+)'\],$}", $line, $matches)) {
        if (1 === $state) {
            $state = 2;
            foreach ($exts as $ext => $mimeTypes) {
                $updated .= sprintf("        '%s' => ['%s'],\n", $ext, implode("', '", array_unique($mimeTypes)));
            }
        }
        $updated .= $line."\n";
        continue;
    }
    $state = 1;
}

$updated = preg_replace('{Updated from upstream on .+?\.}', 'Updated from upstream on '.date('Y-m-d'), $updated, -1);

file_put_contents($output, rtrim($updated, "\n")."\n");

echo "Done.\n";
PKϤ$Zd�:{��mime/Part/MessagePart.phpnu�[���<?php

/*
 * This file is part of the Symfony package.
 *
 * (c) Fabien Potencier <fabien@symfony.com>
 *
 * For the full copyright and license information, please view the LICENSE
 * file that was distributed with this source code.
 */

namespace Symfony\Component\Mime\Part;

use Symfony\Component\Mime\Message;
use Symfony\Component\Mime\RawMessage;

/**
 * @final
 *
 * @author Fabien Potencier <fabien@symfony.com>
 */
class MessagePart extends DataPart
{
    private $message;

    public function __construct(RawMessage $message)
    {
        if ($message instanceof Message) {
            $name = $message->getHeaders()->getHeaderBody('Subject').'.eml';
        } else {
            $name = 'email.eml';
        }
        parent::__construct('', $name);

        $this->message = $message;
    }

    public function getMediaType(): string
    {
        return 'message';
    }

    public function getMediaSubtype(): string
    {
        return 'rfc822';
    }

    public function getBody(): string
    {
        return $this->message->toString();
    }

    public function bodyToString(): string
    {
        return $this->getBody();
    }

    public function bodyToIterable(): iterable
    {
        return $this->message->toIterable();
    }
}
PKϤ$ZaT)	)	#mime/Part/AbstractMultipartPart.phpnu�[���<?php

/*
 * This file is part of the Symfony package.
 *
 * (c) Fabien Potencier <fabien@symfony.com>
 *
 * For the full copyright and license information, please view the LICENSE
 * file that was distributed with this source code.
 */

namespace Symfony\Component\Mime\Part;

use Symfony\Component\Mime\Header\Headers;

/**
 * @author Fabien Potencier <fabien@symfony.com>
 */
abstract class AbstractMultipartPart extends AbstractPart
{
    private $boundary;
    private $parts = [];

    public function __construct(AbstractPart ...$parts)
    {
        parent::__construct();

        foreach ($parts as $part) {
            $this->parts[] = $part;
        }
    }

    /**
     * @return AbstractPart[]
     */
    public function getParts(): array
    {
        return $this->parts;
    }

    public function getMediaType(): string
    {
        return 'multipart';
    }

    public function getPreparedHeaders(): Headers
    {
        $headers = parent::getPreparedHeaders();
        $headers->setHeaderParameter('Content-Type', 'boundary', $this->getBoundary());

        return $headers;
    }

    public function bodyToString(): string
    {
        $parts = $this->getParts();
        $string = '';
        foreach ($parts as $part) {
            $string .= '--'.$this->getBoundary()."\r\n".$part->toString()."\r\n";
        }
        $string .= '--'.$this->getBoundary()."--\r\n";

        return $string;
    }

    public function bodyToIterable(): iterable
    {
        $parts = $this->getParts();
        foreach ($parts as $part) {
            yield '--'.$this->getBoundary()."\r\n";
            yield from $part->toIterable();
            yield "\r\n";
        }
        yield '--'.$this->getBoundary()."--\r\n";
    }

    public function asDebugString(): string
    {
        $str = parent::asDebugString();
        foreach ($this->getParts() as $part) {
            $lines = explode("\n", $part->asDebugString());
            $str .= "\n  └ ".array_shift($lines);
            foreach ($lines as $line) {
                $str .= "\n  |".$line;
            }
        }

        return $str;
    }

    private function getBoundary(): string
    {
        if (null === $this->boundary) {
            $this->boundary = strtr(base64_encode(random_bytes(6)), '+/', '-_');
        }

        return $this->boundary;
    }
}
PKϤ$Z_����
�
mime/Part/SMimePart.phpnu�[���<?php

/*
 * This file is part of the Symfony package.
 *
 * (c) Fabien Potencier <fabien@symfony.com>
 *
 * For the full copyright and license information, please view the LICENSE
 * file that was distributed with this source code.
 */

namespace Symfony\Component\Mime\Part;

use Symfony\Component\Mime\Header\Headers;

/**
 * @author Sebastiaan Stok <s.stok@rollerscapes.net>
 */
class SMimePart extends AbstractPart
{
    private $body;
    private $type;
    private $subtype;
    private $parameters;

    /**
     * @param iterable|string $body
     */
    public function __construct($body, string $type, string $subtype, array $parameters)
    {
        parent::__construct();

        if (!\is_string($body) && !is_iterable($body)) {
            throw new \TypeError(sprintf('The body of "%s" must be a string or a iterable (got "%s").', self::class, get_debug_type($body)));
        }

        $this->body = $body;
        $this->type = $type;
        $this->subtype = $subtype;
        $this->parameters = $parameters;
    }

    public function getMediaType(): string
    {
        return $this->type;
    }

    public function getMediaSubtype(): string
    {
        return $this->subtype;
    }

    public function bodyToString(): string
    {
        if (\is_string($this->body)) {
            return $this->body;
        }

        $body = '';
        foreach ($this->body as $chunk) {
            $body .= $chunk;
        }
        $this->body = $body;

        return $body;
    }

    public function bodyToIterable(): iterable
    {
        if (\is_string($this->body)) {
            yield $this->body;

            return;
        }

        $body = '';
        foreach ($this->body as $chunk) {
            $body .= $chunk;
            yield $chunk;
        }
        $this->body = $body;
    }

    public function getPreparedHeaders(): Headers
    {
        $headers = clone parent::getHeaders();

        $headers->setHeaderBody('Parameterized', 'Content-Type', $this->getMediaType().'/'.$this->getMediaSubtype());

        foreach ($this->parameters as $name => $value) {
            $headers->setHeaderParameter('Content-Type', $name, $value);
        }

        return $headers;
    }

    public function __sleep(): array
    {
        // convert iterables to strings for serialization
        if (is_iterable($this->body)) {
            $this->body = $this->bodyToString();
        }

        $this->_headers = $this->getHeaders();

        return ['_headers', 'body', 'type', 'subtype', 'parameters'];
    }

    public function __wakeup(): void
    {
        $r = new \ReflectionProperty(AbstractPart::class, 'headers');
        $r->setAccessible(true);
        $r->setValue($this, $this->_headers);
        unset($this->_headers);
    }
}
PKϤ$Z��FFmime/Part/TextPart.phpnu�[���<?php

/*
 * This file is part of the Symfony package.
 *
 * (c) Fabien Potencier <fabien@symfony.com>
 *
 * For the full copyright and license information, please view the LICENSE
 * file that was distributed with this source code.
 */

namespace Symfony\Component\Mime\Part;

use Symfony\Component\Mime\Encoder\Base64ContentEncoder;
use Symfony\Component\Mime\Encoder\ContentEncoderInterface;
use Symfony\Component\Mime\Encoder\EightBitContentEncoder;
use Symfony\Component\Mime\Encoder\QpContentEncoder;
use Symfony\Component\Mime\Exception\InvalidArgumentException;
use Symfony\Component\Mime\Header\Headers;

/**
 * @author Fabien Potencier <fabien@symfony.com>
 */
class TextPart extends AbstractPart
{
    private static $encoders = [];

    private $body;
    private $charset;
    private $subtype;
    private $disposition;
    private $name;
    private $encoding;
    private $seekable;

    /**
     * @param resource|string $body
     */
    public function __construct($body, ?string $charset = 'utf-8', $subtype = 'plain', string $encoding = null)
    {
        parent::__construct();

        if (!\is_string($body) && !\is_resource($body)) {
            throw new \TypeError(sprintf('The body of "%s" must be a string or a resource (got "%s").', self::class, get_debug_type($body)));
        }

        $this->body = $body;
        $this->charset = $charset;
        $this->subtype = $subtype;
        $this->seekable = \is_resource($body) ? stream_get_meta_data($body)['seekable'] && 0 === fseek($body, 0, \SEEK_CUR) : null;

        if (null === $encoding) {
            $this->encoding = $this->chooseEncoding();
        } else {
            if ('quoted-printable' !== $encoding && 'base64' !== $encoding && '8bit' !== $encoding) {
                throw new InvalidArgumentException(sprintf('The encoding must be one of "quoted-printable", "base64", or "8bit" ("%s" given).', $encoding));
            }
            $this->encoding = $encoding;
        }
    }

    public function getMediaType(): string
    {
        return 'text';
    }

    public function getMediaSubtype(): string
    {
        return $this->subtype;
    }

    /**
     * @param string $disposition one of attachment, inline, or form-data
     *
     * @return $this
     */
    public function setDisposition(string $disposition)
    {
        $this->disposition = $disposition;

        return $this;
    }

    /**
     * Sets the name of the file (used by FormDataPart).
     *
     * @return $this
     */
    public function setName($name)
    {
        $this->name = $name;

        return $this;
    }

    public function getBody(): string
    {
        if (null === $this->seekable) {
            return $this->body;
        }

        if ($this->seekable) {
            rewind($this->body);
        }

        return stream_get_contents($this->body) ?: '';
    }

    public function bodyToString(): string
    {
        return $this->getEncoder()->encodeString($this->getBody(), $this->charset);
    }

    public function bodyToIterable(): iterable
    {
        if (null !== $this->seekable) {
            if ($this->seekable) {
                rewind($this->body);
            }
            yield from $this->getEncoder()->encodeByteStream($this->body);
        } else {
            yield $this->getEncoder()->encodeString($this->body);
        }
    }

    public function getPreparedHeaders(): Headers
    {
        $headers = parent::getPreparedHeaders();

        $headers->setHeaderBody('Parameterized', 'Content-Type', $this->getMediaType().'/'.$this->getMediaSubtype());
        if ($this->charset) {
            $headers->setHeaderParameter('Content-Type', 'charset', $this->charset);
        }
        if ($this->name && 'form-data' !== $this->disposition) {
            $headers->setHeaderParameter('Content-Type', 'name', $this->name);
        }
        $headers->setHeaderBody('Text', 'Content-Transfer-Encoding', $this->encoding);

        if (!$headers->has('Content-Disposition') && null !== $this->disposition) {
            $headers->setHeaderBody('Parameterized', 'Content-Disposition', $this->disposition);
            if ($this->name) {
                $headers->setHeaderParameter('Content-Disposition', 'name', $this->name);
            }
        }

        return $headers;
    }

    public function asDebugString(): string
    {
        $str = parent::asDebugString();
        if (null !== $this->charset) {
            $str .= ' charset: '.$this->charset;
        }
        if (null !== $this->disposition) {
            $str .= ' disposition: '.$this->disposition;
        }

        return $str;
    }

    private function getEncoder(): ContentEncoderInterface
    {
        if ('8bit' === $this->encoding) {
            return self::$encoders[$this->encoding] ?? (self::$encoders[$this->encoding] = new EightBitContentEncoder());
        }

        if ('quoted-printable' === $this->encoding) {
            return self::$encoders[$this->encoding] ?? (self::$encoders[$this->encoding] = new QpContentEncoder());
        }

        return self::$encoders[$this->encoding] ?? (self::$encoders[$this->encoding] = new Base64ContentEncoder());
    }

    private function chooseEncoding(): string
    {
        if (null === $this->charset) {
            return 'base64';
        }

        return 'quoted-printable';
    }

    /**
     * @return array
     */
    public function __sleep()
    {
        // convert resources to strings for serialization
        if (null !== $this->seekable) {
            $this->body = $this->getBody();
        }

        $this->_headers = $this->getHeaders();

        return ['_headers', 'body', 'charset', 'subtype', 'disposition', 'name', 'encoding'];
    }

    public function __wakeup()
    {
        $r = new \ReflectionProperty(AbstractPart::class, 'headers');
        $r->setAccessible(true);
        $r->setValue($this, $this->_headers);
        unset($this->_headers);
    }
}
PKϤ$Z����mime/Part/AbstractPart.phpnu�[���<?php

/*
 * This file is part of the Symfony package.
 *
 * (c) Fabien Potencier <fabien@symfony.com>
 *
 * For the full copyright and license information, please view the LICENSE
 * file that was distributed with this source code.
 */

namespace Symfony\Component\Mime\Part;

use Symfony\Component\Mime\Header\Headers;

/**
 * @author Fabien Potencier <fabien@symfony.com>
 */
abstract class AbstractPart
{
    private $headers;

    public function __construct()
    {
        $this->headers = new Headers();
    }

    public function getHeaders(): Headers
    {
        return $this->headers;
    }

    public function getPreparedHeaders(): Headers
    {
        $headers = clone $this->headers;
        $headers->setHeaderBody('Parameterized', 'Content-Type', $this->getMediaType().'/'.$this->getMediaSubtype());

        return $headers;
    }

    public function toString(): string
    {
        return $this->getPreparedHeaders()->toString()."\r\n".$this->bodyToString();
    }

    public function toIterable(): iterable
    {
        yield $this->getPreparedHeaders()->toString();
        yield "\r\n";
        yield from $this->bodyToIterable();
    }

    public function asDebugString(): string
    {
        return $this->getMediaType().'/'.$this->getMediaSubtype();
    }

    abstract public function bodyToString(): string;

    abstract public function bodyToIterable(): iterable;

    abstract public function getMediaType(): string;

    abstract public function getMediaSubtype(): string;
}
PKϤ$ZI�
��mime/Part/DataPart.phpnu�[���<?php

/*
 * This file is part of the Symfony package.
 *
 * (c) Fabien Potencier <fabien@symfony.com>
 *
 * For the full copyright and license information, please view the LICENSE
 * file that was distributed with this source code.
 */

namespace Symfony\Component\Mime\Part;

use Symfony\Component\Mime\Exception\InvalidArgumentException;
use Symfony\Component\Mime\Header\Headers;
use Symfony\Component\Mime\MimeTypes;

/**
 * @author Fabien Potencier <fabien@symfony.com>
 */
class DataPart extends TextPart
{
    private static $mimeTypes;

    private $filename;
    private $mediaType;
    private $cid;
    private $handle;

    /**
     * @param resource|string $body
     */
    public function __construct($body, string $filename = null, string $contentType = null, string $encoding = null)
    {
        if (null === $contentType) {
            $contentType = 'application/octet-stream';
        }
        list($this->mediaType, $subtype) = explode('/', $contentType);

        parent::__construct($body, null, $subtype, $encoding);

        $this->filename = $filename;
        $this->setName($filename);
        $this->setDisposition('attachment');
    }

    public static function fromPath(string $path, string $name = null, string $contentType = null): self
    {
        // FIXME: if file is not readable, exception?

        if (null === $contentType) {
            $ext = strtolower(substr($path, strrpos($path, '.') + 1));
            if (null === self::$mimeTypes) {
                self::$mimeTypes = new MimeTypes();
            }
            $contentType = self::$mimeTypes->getMimeTypes($ext)[0] ?? 'application/octet-stream';
        }

        if (false === is_readable($path)) {
            throw new InvalidArgumentException(sprintf('Path "%s" is not readable.', $path));
        }

        if (false === $handle = @fopen($path, 'r', false)) {
            throw new InvalidArgumentException(sprintf('Unable to open path "%s".', $path));
        }
        $p = new self($handle, $name ?: basename($path), $contentType);
        $p->handle = $handle;

        return $p;
    }

    /**
     * @return $this
     */
    public function asInline()
    {
        return $this->setDisposition('inline');
    }

    public function getContentId(): string
    {
        return $this->cid ?: $this->cid = $this->generateContentId();
    }

    public function hasContentId(): bool
    {
        return null !== $this->cid;
    }

    public function getMediaType(): string
    {
        return $this->mediaType;
    }

    public function getPreparedHeaders(): Headers
    {
        $headers = parent::getPreparedHeaders();

        if (null !== $this->cid) {
            $headers->setHeaderBody('Id', 'Content-ID', $this->cid);
        }

        if (null !== $this->filename) {
            $headers->setHeaderParameter('Content-Disposition', 'filename', $this->filename);
        }

        return $headers;
    }

    public function asDebugString(): string
    {
        $str = parent::asDebugString();
        if (null !== $this->filename) {
            $str .= ' filename: '.$this->filename;
        }

        return $str;
    }

    private function generateContentId(): string
    {
        return bin2hex(random_bytes(16)).'@symfony';
    }

    public function __destruct()
    {
        if (null !== $this->handle && \is_resource($this->handle)) {
            fclose($this->handle);
        }
    }

    /**
     * @return array
     */
    public function __sleep()
    {
        // converts the body to a string
        parent::__sleep();

        $this->_parent = [];
        foreach (['body', 'charset', 'subtype', 'disposition', 'name', 'encoding'] as $name) {
            $r = new \ReflectionProperty(TextPart::class, $name);
            $r->setAccessible(true);
            $this->_parent[$name] = $r->getValue($this);
        }
        $this->_headers = $this->getHeaders();

        return ['_headers', '_parent', 'filename', 'mediaType'];
    }

    public function __wakeup()
    {
        $r = new \ReflectionProperty(AbstractPart::class, 'headers');
        $r->setAccessible(true);
        $r->setValue($this, $this->_headers);
        unset($this->_headers);

        foreach (['body', 'charset', 'subtype', 'disposition', 'name', 'encoding'] as $name) {
            $r = new \ReflectionProperty(TextPart::class, $name);
            $r->setAccessible(true);
            $r->setValue($this, $this->_parent[$name]);
        }
        unset($this->_parent);
    }
}
PKϤ$Z��S�'''mime/Part/Multipart/AlternativePart.phpnu�[���<?php

/*
 * This file is part of the Symfony package.
 *
 * (c) Fabien Potencier <fabien@symfony.com>
 *
 * For the full copyright and license information, please view the LICENSE
 * file that was distributed with this source code.
 */

namespace Symfony\Component\Mime\Part\Multipart;

use Symfony\Component\Mime\Part\AbstractMultipartPart;

/**
 * @author Fabien Potencier <fabien@symfony.com>
 */
final class AlternativePart extends AbstractMultipartPart
{
    public function getMediaSubtype(): string
    {
        return 'alternative';
    }
}
PKϤ$Z'�?!mime/Part/Multipart/MixedPart.phpnu�[���<?php

/*
 * This file is part of the Symfony package.
 *
 * (c) Fabien Potencier <fabien@symfony.com>
 *
 * For the full copyright and license information, please view the LICENSE
 * file that was distributed with this source code.
 */

namespace Symfony\Component\Mime\Part\Multipart;

use Symfony\Component\Mime\Part\AbstractMultipartPart;

/**
 * @author Fabien Potencier <fabien@symfony.com>
 */
final class MixedPart extends AbstractMultipartPart
{
    public function getMediaSubtype(): string
    {
        return 'mixed';
    }
}
PKϤ$Z;��c��"mime/Part/Multipart/DigestPart.phpnu�[���<?php

/*
 * This file is part of the Symfony package.
 *
 * (c) Fabien Potencier <fabien@symfony.com>
 *
 * For the full copyright and license information, please view the LICENSE
 * file that was distributed with this source code.
 */

namespace Symfony\Component\Mime\Part\Multipart;

use Symfony\Component\Mime\Part\AbstractMultipartPart;
use Symfony\Component\Mime\Part\MessagePart;

/**
 * @author Fabien Potencier <fabien@symfony.com>
 */
final class DigestPart extends AbstractMultipartPart
{
    public function __construct(MessagePart ...$parts)
    {
        parent::__construct(...$parts);
    }

    public function getMediaSubtype(): string
    {
        return 'digest';
    }
}
PKϤ$Zz�~�kk#mime/Part/Multipart/RelatedPart.phpnu�[���<?php

/*
 * This file is part of the Symfony package.
 *
 * (c) Fabien Potencier <fabien@symfony.com>
 *
 * For the full copyright and license information, please view the LICENSE
 * file that was distributed with this source code.
 */

namespace Symfony\Component\Mime\Part\Multipart;

use Symfony\Component\Mime\Part\AbstractMultipartPart;
use Symfony\Component\Mime\Part\AbstractPart;

/**
 * @author Fabien Potencier <fabien@symfony.com>
 */
final class RelatedPart extends AbstractMultipartPart
{
    private $mainPart;

    public function __construct(AbstractPart $mainPart, AbstractPart $part, AbstractPart ...$parts)
    {
        $this->mainPart = $mainPart;
        $this->prepareParts($part, ...$parts);

        parent::__construct($part, ...$parts);
    }

    public function getParts(): array
    {
        return array_merge([$this->mainPart], parent::getParts());
    }

    public function getMediaSubtype(): string
    {
        return 'related';
    }

    private function generateContentId(): string
    {
        return bin2hex(random_bytes(16)).'@symfony';
    }

    private function prepareParts(AbstractPart ...$parts): void
    {
        foreach ($parts as $part) {
            if (!$part->getHeaders()->has('Content-ID')) {
                $part->getHeaders()->setHeaderBody('Id', 'Content-ID', $this->generateContentId());
            }
        }
    }
}
PKϤ$Z94�B�
�
$mime/Part/Multipart/FormDataPart.phpnu�[���<?php

/*
 * This file is part of the Symfony package.
 *
 * (c) Fabien Potencier <fabien@symfony.com>
 *
 * For the full copyright and license information, please view the LICENSE
 * file that was distributed with this source code.
 */

namespace Symfony\Component\Mime\Part\Multipart;

use Symfony\Component\Mime\Exception\InvalidArgumentException;
use Symfony\Component\Mime\Part\AbstractMultipartPart;
use Symfony\Component\Mime\Part\DataPart;
use Symfony\Component\Mime\Part\TextPart;

/**
 * Implements RFC 7578.
 *
 * @author Fabien Potencier <fabien@symfony.com>
 */
final class FormDataPart extends AbstractMultipartPart
{
    private $fields = [];

    /**
     * @param (string|array|DataPart)[] $fields
     */
    public function __construct(array $fields = [])
    {
        parent::__construct();

        foreach ($fields as $name => $value) {
            if (!\is_string($value) && !\is_array($value) && !$value instanceof TextPart) {
                throw new InvalidArgumentException(sprintf('A form field value can only be a string, an array, or an instance of TextPart ("%s" given).', get_debug_type($value)));
            }

            $this->fields[$name] = $value;
        }
        // HTTP does not support \r\n in header values
        $this->getHeaders()->setMaxLineLength(\PHP_INT_MAX);
    }

    public function getMediaSubtype(): string
    {
        return 'form-data';
    }

    public function getParts(): array
    {
        return $this->prepareFields($this->fields);
    }

    private function prepareFields(array $fields): array
    {
        $values = [];

        $prepare = function ($item, $key, $root = null) use (&$values, &$prepare) {
            $fieldName = $root ? sprintf('%s[%s]', $root, $key) : $key;

            if (\is_array($item)) {
                array_walk($item, $prepare, $fieldName);

                return;
            }

            $values[] = $this->preparePart($fieldName, $item);
        };

        array_walk($fields, $prepare);

        return $values;
    }

    private function preparePart(string $name, $value): TextPart
    {
        if (\is_string($value)) {
            return $this->configurePart($name, new TextPart($value, 'utf-8', 'plain', '8bit'));
        }

        return $this->configurePart($name, $value);
    }

    private function configurePart(string $name, TextPart $part): TextPart
    {
        static $r;

        if (null === $r) {
            $r = new \ReflectionProperty(TextPart::class, 'encoding');
            $r->setAccessible(true);
        }

        $part->setDisposition('form-data');
        $part->setName($name);
        // HTTP does not support \r\n in header values
        $part->getHeaders()->setMaxLineLength(\PHP_INT_MAX);
        $r->setValue($part, '8bit');

        return $part;
    }
}
PKϤ$Z�@K#_(_(mime/Header/AbstractHeader.phpnu�[���<?php

/*
 * This file is part of the Symfony package.
 *
 * (c) Fabien Potencier <fabien@symfony.com>
 *
 * For the full copyright and license information, please view the LICENSE
 * file that was distributed with this source code.
 */

namespace Symfony\Component\Mime\Header;

use Symfony\Component\Mime\Encoder\QpMimeHeaderEncoder;

/**
 * An abstract base MIME Header.
 *
 * @author Chris Corbyn
 */
abstract class AbstractHeader implements HeaderInterface
{
    const PHRASE_PATTERN = '(?:(?:(?:(?:(?:(?:(?:[ \t]*(?:\r\n))?[ \t])?(\((?:(?:(?:[ \t]*(?:\r\n))?[ \t])|(?:(?:[\x01-\x08\x0B\x0C\x0E-\x19\x7F]|[\x21-\x27\x2A-\x5B\x5D-\x7E])|(?:\\[\x00-\x08\x0B\x0C\x0E-\x7F])|(?1)))*(?:(?:[ \t]*(?:\r\n))?[ \t])?\)))*(?:(?:(?:(?:[ \t]*(?:\r\n))?[ \t])?(\((?:(?:(?:[ \t]*(?:\r\n))?[ \t])|(?:(?:[\x01-\x08\x0B\x0C\x0E-\x19\x7F]|[\x21-\x27\x2A-\x5B\x5D-\x7E])|(?:\\[\x00-\x08\x0B\x0C\x0E-\x7F])|(?1)))*(?:(?:[ \t]*(?:\r\n))?[ \t])?\)))|(?:(?:[ \t]*(?:\r\n))?[ \t])))?[a-zA-Z0-9!#\$%&\'\*\+\-\/=\?\^_`\{\}\|~]+(?:(?:(?:(?:[ \t]*(?:\r\n))?[ \t])?(\((?:(?:(?:[ \t]*(?:\r\n))?[ \t])|(?:(?:[\x01-\x08\x0B\x0C\x0E-\x19\x7F]|[\x21-\x27\x2A-\x5B\x5D-\x7E])|(?:\\[\x00-\x08\x0B\x0C\x0E-\x7F])|(?1)))*(?:(?:[ \t]*(?:\r\n))?[ \t])?\)))*(?:(?:(?:(?:[ \t]*(?:\r\n))?[ \t])?(\((?:(?:(?:[ \t]*(?:\r\n))?[ \t])|(?:(?:[\x01-\x08\x0B\x0C\x0E-\x19\x7F]|[\x21-\x27\x2A-\x5B\x5D-\x7E])|(?:\\[\x00-\x08\x0B\x0C\x0E-\x7F])|(?1)))*(?:(?:[ \t]*(?:\r\n))?[ \t])?\)))|(?:(?:[ \t]*(?:\r\n))?[ \t])))?)|(?:(?:(?:(?:(?:[ \t]*(?:\r\n))?[ \t])?(\((?:(?:(?:[ \t]*(?:\r\n))?[ \t])|(?:(?:[\x01-\x08\x0B\x0C\x0E-\x19\x7F]|[\x21-\x27\x2A-\x5B\x5D-\x7E])|(?:\\[\x00-\x08\x0B\x0C\x0E-\x7F])|(?1)))*(?:(?:[ \t]*(?:\r\n))?[ \t])?\)))*(?:(?:(?:(?:[ \t]*(?:\r\n))?[ \t])?(\((?:(?:(?:[ \t]*(?:\r\n))?[ \t])|(?:(?:[\x01-\x08\x0B\x0C\x0E-\x19\x7F]|[\x21-\x27\x2A-\x5B\x5D-\x7E])|(?:\\[\x00-\x08\x0B\x0C\x0E-\x7F])|(?1)))*(?:(?:[ \t]*(?:\r\n))?[ \t])?\)))|(?:(?:[ \t]*(?:\r\n))?[ \t])))?"((?:(?:[ \t]*(?:\r\n))?[ \t])?(?:(?:[\x01-\x08\x0B\x0C\x0E-\x19\x7F]|[\x21\x23-\x5B\x5D-\x7E])|(?:\\[\x00-\x08\x0B\x0C\x0E-\x7F])))*(?:(?:[ \t]*(?:\r\n))?[ \t])?"(?:(?:(?:(?:[ \t]*(?:\r\n))?[ \t])?(\((?:(?:(?:[ \t]*(?:\r\n))?[ \t])|(?:(?:[\x01-\x08\x0B\x0C\x0E-\x19\x7F]|[\x21-\x27\x2A-\x5B\x5D-\x7E])|(?:\\[\x00-\x08\x0B\x0C\x0E-\x7F])|(?1)))*(?:(?:[ \t]*(?:\r\n))?[ \t])?\)))*(?:(?:(?:(?:[ \t]*(?:\r\n))?[ \t])?(\((?:(?:(?:[ \t]*(?:\r\n))?[ \t])|(?:(?:[\x01-\x08\x0B\x0C\x0E-\x19\x7F]|[\x21-\x27\x2A-\x5B\x5D-\x7E])|(?:\\[\x00-\x08\x0B\x0C\x0E-\x7F])|(?1)))*(?:(?:[ \t]*(?:\r\n))?[ \t])?\)))|(?:(?:[ \t]*(?:\r\n))?[ \t])))?))+?)';

    private static $encoder;

    private $name;
    private $lineLength = 76;
    private $lang;
    private $charset = 'utf-8';

    public function __construct(string $name)
    {
        $this->name = $name;
    }

    public function setCharset(string $charset)
    {
        $this->charset = $charset;
    }

    public function getCharset(): ?string
    {
        return $this->charset;
    }

    /**
     * Set the language used in this Header.
     *
     * For example, for US English, 'en-us'.
     */
    public function setLanguage(string $lang)
    {
        $this->lang = $lang;
    }

    public function getLanguage(): ?string
    {
        return $this->lang;
    }

    public function getName(): string
    {
        return $this->name;
    }

    public function setMaxLineLength(int $lineLength)
    {
        $this->lineLength = $lineLength;
    }

    public function getMaxLineLength(): int
    {
        return $this->lineLength;
    }

    public function toString(): string
    {
        return $this->tokensToString($this->toTokens());
    }

    /**
     * Produces a compliant, formatted RFC 2822 'phrase' based on the string given.
     *
     * @param string $string  as displayed
     * @param bool   $shorten the first line to make remove for header name
     */
    protected function createPhrase(HeaderInterface $header, string $string, string $charset, bool $shorten = false): string
    {
        // Treat token as exactly what was given
        $phraseStr = $string;

        // If it's not valid
        if (!preg_match('/^'.self::PHRASE_PATTERN.'$/D', $phraseStr)) {
            // .. but it is just ascii text, try escaping some characters
            // and make it a quoted-string
            if (preg_match('/^[\x00-\x08\x0B\x0C\x0E-\x7F]*$/D', $phraseStr)) {
                foreach (['\\', '"'] as $char) {
                    $phraseStr = str_replace($char, '\\'.$char, $phraseStr);
                }
                $phraseStr = '"'.$phraseStr.'"';
            } else {
                // ... otherwise it needs encoding
                // Determine space remaining on line if first line
                if ($shorten) {
                    $usedLength = \strlen($header->getName().': ');
                } else {
                    $usedLength = 0;
                }
                $phraseStr = $this->encodeWords($header, $string, $usedLength);
            }
        }

        return $phraseStr;
    }

    /**
     * Encode needed word tokens within a string of input.
     */
    protected function encodeWords(HeaderInterface $header, string $input, int $usedLength = -1): string
    {
        $value = '';
        $tokens = $this->getEncodableWordTokens($input);
        foreach ($tokens as $token) {
            // See RFC 2822, Sect 2.2 (really 2.2 ??)
            if ($this->tokenNeedsEncoding($token)) {
                // Don't encode starting WSP
                $firstChar = substr($token, 0, 1);
                switch ($firstChar) {
                    case ' ':
                    case "\t":
                        $value .= $firstChar;
                        $token = substr($token, 1);
                }

                if (-1 == $usedLength) {
                    $usedLength = \strlen($header->getName().': ') + \strlen($value);
                }
                $value .= $this->getTokenAsEncodedWord($token, $usedLength);
            } else {
                $value .= $token;
            }
        }

        return $value;
    }

    protected function tokenNeedsEncoding(string $token): bool
    {
        return (bool) preg_match('~[\x00-\x08\x10-\x19\x7F-\xFF\r\n]~', $token);
    }

    /**
     * Splits a string into tokens in blocks of words which can be encoded quickly.
     *
     * @return string[]
     */
    protected function getEncodableWordTokens(string $string): array
    {
        $tokens = [];
        $encodedToken = '';
        // Split at all whitespace boundaries
        foreach (preg_split('~(?=[\t ])~', $string) as $token) {
            if ($this->tokenNeedsEncoding($token)) {
                $encodedToken .= $token;
            } else {
                if (\strlen($encodedToken) > 0) {
                    $tokens[] = $encodedToken;
                    $encodedToken = '';
                }
                $tokens[] = $token;
            }
        }
        if (\strlen($encodedToken)) {
            $tokens[] = $encodedToken;
        }

        return $tokens;
    }

    /**
     * Get a token as an encoded word for safe insertion into headers.
     */
    protected function getTokenAsEncodedWord(string $token, int $firstLineOffset = 0): string
    {
        if (null === self::$encoder) {
            self::$encoder = new QpMimeHeaderEncoder();
        }

        // Adjust $firstLineOffset to account for space needed for syntax
        $charsetDecl = $this->charset;
        if (null !== $this->lang) {
            $charsetDecl .= '*'.$this->lang;
        }
        $encodingWrapperLength = \strlen('=?'.$charsetDecl.'?'.self::$encoder->getName().'??=');

        if ($firstLineOffset >= 75) {
            //Does this logic need to be here?
            $firstLineOffset = 0;
        }

        $encodedTextLines = explode("\r\n",
            self::$encoder->encodeString($token, $this->charset, $firstLineOffset, 75 - $encodingWrapperLength)
        );

        if ('iso-2022-jp' !== strtolower($this->charset)) {
            // special encoding for iso-2022-jp using mb_encode_mimeheader
            foreach ($encodedTextLines as $lineNum => $line) {
                $encodedTextLines[$lineNum] = '=?'.$charsetDecl.'?'.self::$encoder->getName().'?'.$line.'?=';
            }
        }

        return implode("\r\n ", $encodedTextLines);
    }

    /**
     * Generates tokens from the given string which include CRLF as individual tokens.
     *
     * @return string[]
     */
    protected function generateTokenLines(string $token): array
    {
        return preg_split('~(\r\n)~', $token, -1, \PREG_SPLIT_DELIM_CAPTURE);
    }

    /**
     * Generate a list of all tokens in the final header.
     */
    protected function toTokens(string $string = null): array
    {
        if (null === $string) {
            $string = $this->getBodyAsString();
        }

        $tokens = [];
        // Generate atoms; split at all invisible boundaries followed by WSP
        foreach (preg_split('~(?=[ \t])~', $string) as $token) {
            $newTokens = $this->generateTokenLines($token);
            foreach ($newTokens as $newToken) {
                $tokens[] = $newToken;
            }
        }

        return $tokens;
    }

    /**
     * Takes an array of tokens which appear in the header and turns them into
     * an RFC 2822 compliant string, adding FWSP where needed.
     *
     * @param string[] $tokens
     */
    private function tokensToString(array $tokens): string
    {
        $lineCount = 0;
        $headerLines = [];
        $headerLines[] = $this->name.': ';
        $currentLine = &$headerLines[$lineCount++];

        // Build all tokens back into compliant header
        foreach ($tokens as $i => $token) {
            // Line longer than specified maximum or token was just a new line
            if (("\r\n" === $token) ||
                ($i > 0 && \strlen($currentLine.$token) > $this->lineLength)
                && 0 < \strlen($currentLine)) {
                $headerLines[] = '';
                $currentLine = &$headerLines[$lineCount++];
            }

            // Append token to the line
            if ("\r\n" !== $token) {
                $currentLine .= $token;
            }
        }

        // Implode with FWS (RFC 2822, 2.2.3)
        return implode("\r\n", $headerLines);
    }
}
PKϤ$Z.6�!<<#mime/Header/ParameterizedHeader.phpnu�[���<?php

/*
 * This file is part of the Symfony package.
 *
 * (c) Fabien Potencier <fabien@symfony.com>
 *
 * For the full copyright and license information, please view the LICENSE
 * file that was distributed with this source code.
 */

namespace Symfony\Component\Mime\Header;

use Symfony\Component\Mime\Encoder\Rfc2231Encoder;

/**
 * @author Chris Corbyn
 */
final class ParameterizedHeader extends UnstructuredHeader
{
    /**
     * RFC 2231's definition of a token.
     *
     * @var string
     */
    const TOKEN_REGEX = '(?:[\x21\x23-\x27\x2A\x2B\x2D\x2E\x30-\x39\x41-\x5A\x5E-\x7E]+)';

    private $encoder;
    private $parameters = [];

    public function __construct(string $name, string $value, array $parameters = [])
    {
        parent::__construct($name, $value);

        foreach ($parameters as $k => $v) {
            $this->setParameter($k, $v);
        }

        if ('content-type' !== strtolower($name)) {
            $this->encoder = new Rfc2231Encoder();
        }
    }

    public function setParameter(string $parameter, ?string $value)
    {
        $this->setParameters(array_merge($this->getParameters(), [$parameter => $value]));
    }

    public function getParameter(string $parameter): string
    {
        return $this->getParameters()[$parameter] ?? '';
    }

    /**
     * @param string[] $parameters
     */
    public function setParameters(array $parameters)
    {
        $this->parameters = $parameters;
    }

    /**
     * @return string[]
     */
    public function getParameters(): array
    {
        return $this->parameters;
    }

    public function getBodyAsString(): string
    {
        $body = parent::getBodyAsString();
        foreach ($this->parameters as $name => $value) {
            if (null !== $value) {
                $body .= '; '.$this->createParameter($name, $value);
            }
        }

        return $body;
    }

    /**
     * Generate a list of all tokens in the final header.
     *
     * This doesn't need to be overridden in theory, but it is for implementation
     * reasons to prevent potential breakage of attributes.
     */
    protected function toTokens(string $string = null): array
    {
        $tokens = parent::toTokens(parent::getBodyAsString());

        // Try creating any parameters
        foreach ($this->parameters as $name => $value) {
            if (null !== $value) {
                // Add the semi-colon separator
                $tokens[\count($tokens) - 1] .= ';';
                $tokens = array_merge($tokens, $this->generateTokenLines(' '.$this->createParameter($name, $value)));
            }
        }

        return $tokens;
    }

    /**
     * Render a RFC 2047 compliant header parameter from the $name and $value.
     */
    private function createParameter(string $name, string $value): string
    {
        $origValue = $value;

        $encoded = false;
        // Allow room for parameter name, indices, "=" and DQUOTEs
        $maxValueLength = $this->getMaxLineLength() - \strlen($name.'=*N"";') - 1;
        $firstLineOffset = 0;

        // If it's not already a valid parameter value...
        if (!preg_match('/^'.self::TOKEN_REGEX.'$/D', $value)) {
            // TODO: text, or something else??
            // ... and it's not ascii
            if (!preg_match('/^[\x00-\x08\x0B\x0C\x0E-\x7F]*$/D', $value)) {
                $encoded = true;
                // Allow space for the indices, charset and language
                $maxValueLength = $this->getMaxLineLength() - \strlen($name.'*N*="";') - 1;
                $firstLineOffset = \strlen($this->getCharset()."'".$this->getLanguage()."'");
            }
        }

        // Encode if we need to
        if ($encoded || \strlen($value) > $maxValueLength) {
            if (null !== $this->encoder) {
                $value = $this->encoder->encodeString($origValue, $this->getCharset(), $firstLineOffset, $maxValueLength);
            } else {
                // We have to go against RFC 2183/2231 in some areas for interoperability
                $value = $this->getTokenAsEncodedWord($origValue);
                $encoded = false;
            }
        }

        $valueLines = $this->encoder ? explode("\r\n", $value) : [$value];

        // Need to add indices
        if (\count($valueLines) > 1) {
            $paramLines = [];
            foreach ($valueLines as $i => $line) {
                $paramLines[] = $name.'*'.$i.$this->getEndOfParameterValue($line, true, 0 === $i);
            }

            return implode(";\r\n ", $paramLines);
        } else {
            return $name.$this->getEndOfParameterValue($valueLines[0], $encoded, true);
        }
    }

    /**
     * Returns the parameter value from the "=" and beyond.
     *
     * @param string $value to append
     */
    private function getEndOfParameterValue(string $value, bool $encoded = false, bool $firstLine = false): string
    {
        $forceHttpQuoting = 'content-disposition' === strtolower($this->getName()) && 'form-data' === $this->getValue();
        if ($forceHttpQuoting || !preg_match('/^'.self::TOKEN_REGEX.'$/D', $value)) {
            $value = '"'.$value.'"';
        }
        $prepend = '=';
        if ($encoded) {
            $prepend = '*=';
            if ($firstLine) {
                $prepend = '*='.$this->getCharset()."'".$this->getLanguage()."'";
            }
        }

        return $prepend.$value;
    }
}
PKϤ$ZK��1<	<	$mime/Header/IdentificationHeader.phpnu�[���<?php

/*
 * This file is part of the Symfony package.
 *
 * (c) Fabien Potencier <fabien@symfony.com>
 *
 * For the full copyright and license information, please view the LICENSE
 * file that was distributed with this source code.
 */

namespace Symfony\Component\Mime\Header;

use Symfony\Component\Mime\Address;
use Symfony\Component\Mime\Exception\RfcComplianceException;

/**
 * An ID MIME Header for something like Message-ID or Content-ID (one or more addresses).
 *
 * @author Chris Corbyn
 */
final class IdentificationHeader extends AbstractHeader
{
    private $ids = [];
    private $idsAsAddresses = [];

    /**
     * @param string|array $ids
     */
    public function __construct(string $name, $ids)
    {
        parent::__construct($name);

        $this->setId($ids);
    }

    /**
     * @param string|array $body a string ID or an array of IDs
     *
     * @throws RfcComplianceException
     */
    public function setBody($body)
    {
        $this->setId($body);
    }

    public function getBody(): array
    {
        return $this->getIds();
    }

    /**
     * Set the ID used in the value of this header.
     *
     * @param string|array $id
     *
     * @throws RfcComplianceException
     */
    public function setId($id)
    {
        $this->setIds(\is_array($id) ? $id : [$id]);
    }

    /**
     * Get the ID used in the value of this Header.
     *
     * If multiple IDs are set only the first is returned.
     */
    public function getId(): ?string
    {
        return $this->ids[0] ?? null;
    }

    /**
     * Set a collection of IDs to use in the value of this Header.
     *
     * @param string[] $ids
     *
     * @throws RfcComplianceException
     */
    public function setIds(array $ids)
    {
        $this->ids = [];
        $this->idsAsAddresses = [];
        foreach ($ids as $id) {
            $this->idsAsAddresses[] = new Address($id);
            $this->ids[] = $id;
        }
    }

    /**
     * Get the list of IDs used in this Header.
     *
     * @return string[]
     */
    public function getIds(): array
    {
        return $this->ids;
    }

    public function getBodyAsString(): string
    {
        $addrs = [];
        foreach ($this->idsAsAddresses as $address) {
            $addrs[] = '<'.$address->toString().'>';
        }

        return implode(' ', $addrs);
    }
}
PKϤ$Z��{��mime/Header/DateHeader.phpnu�[���<?php

/*
 * This file is part of the Symfony package.
 *
 * (c) Fabien Potencier <fabien@symfony.com>
 *
 * For the full copyright and license information, please view the LICENSE
 * file that was distributed with this source code.
 */

namespace Symfony\Component\Mime\Header;

/**
 * A Date MIME Header.
 *
 * @author Chris Corbyn
 */
final class DateHeader extends AbstractHeader
{
    private $dateTime;

    public function __construct(string $name, \DateTimeInterface $date)
    {
        parent::__construct($name);

        $this->setDateTime($date);
    }

    /**
     * @param \DateTimeInterface $body
     */
    public function setBody($body)
    {
        $this->setDateTime($body);
    }

    public function getBody(): \DateTimeImmutable
    {
        return $this->getDateTime();
    }

    public function getDateTime(): \DateTimeImmutable
    {
        return $this->dateTime;
    }

    /**
     * Set the date-time of the Date in this Header.
     *
     * If a DateTime instance is provided, it is converted to DateTimeImmutable.
     */
    public function setDateTime(\DateTimeInterface $dateTime)
    {
        if ($dateTime instanceof \DateTime) {
            $immutable = new \DateTimeImmutable('@'.$dateTime->getTimestamp());
            $dateTime = $immutable->setTimezone($dateTime->getTimezone());
        }
        $this->dateTime = $dateTime;
    }

    public function getBodyAsString(): string
    {
        return $this->dateTime->format(\DateTime::RFC2822);
    }
}
PKϤ$Z6CzCC!mime/Header/MailboxListHeader.phpnu�[���<?php

/*
 * This file is part of the Symfony package.
 *
 * (c) Fabien Potencier <fabien@symfony.com>
 *
 * For the full copyright and license information, please view the LICENSE
 * file that was distributed with this source code.
 */

namespace Symfony\Component\Mime\Header;

use Symfony\Component\Mime\Address;
use Symfony\Component\Mime\Exception\RfcComplianceException;

/**
 * A Mailbox list MIME Header for something like From, To, Cc, and Bcc (one or more named addresses).
 *
 * @author Chris Corbyn
 */
final class MailboxListHeader extends AbstractHeader
{
    private $addresses = [];

    /**
     * @param Address[] $addresses
     */
    public function __construct(string $name, array $addresses)
    {
        parent::__construct($name);

        $this->setAddresses($addresses);
    }

    /**
     * @param Address[] $body
     *
     * @throws RfcComplianceException
     */
    public function setBody($body)
    {
        $this->setAddresses($body);
    }

    /**
     * @throws RfcComplianceException
     *
     * @return Address[]
     */
    public function getBody(): array
    {
        return $this->getAddresses();
    }

    /**
     * Sets a list of addresses to be shown in this Header.
     *
     * @param Address[] $addresses
     *
     * @throws RfcComplianceException
     */
    public function setAddresses(array $addresses)
    {
        $this->addresses = [];
        $this->addAddresses($addresses);
    }

    /**
     * Sets a list of addresses to be shown in this Header.
     *
     * @param Address[] $addresses
     *
     * @throws RfcComplianceException
     */
    public function addAddresses(array $addresses)
    {
        foreach ($addresses as $address) {
            $this->addAddress($address);
        }
    }

    /**
     * @throws RfcComplianceException
     */
    public function addAddress(Address $address)
    {
        $this->addresses[] = $address;
    }

    /**
     * @return Address[]
     */
    public function getAddresses(): array
    {
        return $this->addresses;
    }

    /**
     * Gets the full mailbox list of this Header as an array of valid RFC 2822 strings.
     *
     * @throws RfcComplianceException
     *
     * @return string[]
     */
    public function getAddressStrings(): array
    {
        $strings = [];
        foreach ($this->addresses as $address) {
            $str = $address->getEncodedAddress();
            if ($name = $address->getName()) {
                $str = $this->createPhrase($this, $name, $this->getCharset(), !$strings).' <'.$str.'>';
            }
            $strings[] = $str;
        }

        return $strings;
    }

    public function getBodyAsString(): string
    {
        return implode(', ', $this->getAddressStrings());
    }

    /**
     * Redefine the encoding requirements for addresses.
     *
     * All "specials" must be encoded as the full header value will not be quoted
     *
     * @see RFC 2822 3.2.1
     */
    protected function tokenNeedsEncoding(string $token): bool
    {
        return preg_match('/[()<>\[\]:;@\,."]/', $token) || parent::tokenNeedsEncoding($token);
    }
}
PKϤ$ZX��"mime/Header/UnstructuredHeader.phpnu�[���<?php

/*
 * This file is part of the Symfony package.
 *
 * (c) Fabien Potencier <fabien@symfony.com>
 *
 * For the full copyright and license information, please view the LICENSE
 * file that was distributed with this source code.
 */

namespace Symfony\Component\Mime\Header;

/**
 * A Simple MIME Header.
 *
 * @author Chris Corbyn
 */
class UnstructuredHeader extends AbstractHeader
{
    private $value;

    public function __construct(string $name, string $value)
    {
        parent::__construct($name);

        $this->setValue($value);
    }

    /**
     * @param string $body
     */
    public function setBody($body)
    {
        $this->setValue($body);
    }

    /**
     * @return string
     */
    public function getBody()
    {
        return $this->getValue();
    }

    /**
     * Get the (unencoded) value of this header.
     */
    public function getValue(): string
    {
        return $this->value;
    }

    /**
     * Set the (unencoded) value of this header.
     */
    public function setValue(string $value)
    {
        $this->value = $value;
    }

    /**
     * Get the value of this header prepared for rendering.
     */
    public function getBodyAsString(): string
    {
        return $this->encodeWords($this, $this->value);
    }
}
PKϤ$ZysK���mime/Header/PathHeader.phpnu�[���<?php

/*
 * This file is part of the Symfony package.
 *
 * (c) Fabien Potencier <fabien@symfony.com>
 *
 * For the full copyright and license information, please view the LICENSE
 * file that was distributed with this source code.
 */

namespace Symfony\Component\Mime\Header;

use Symfony\Component\Mime\Address;
use Symfony\Component\Mime\Exception\RfcComplianceException;

/**
 * A Path Header, such a Return-Path (one address).
 *
 * @author Chris Corbyn
 */
final class PathHeader extends AbstractHeader
{
    private $address;

    public function __construct(string $name, Address $address)
    {
        parent::__construct($name);

        $this->setAddress($address);
    }

    /**
     * @param Address $body
     *
     * @throws RfcComplianceException
     */
    public function setBody($body)
    {
        $this->setAddress($body);
    }

    public function getBody(): Address
    {
        return $this->getAddress();
    }

    public function setAddress(Address $address)
    {
        $this->address = $address;
    }

    public function getAddress(): Address
    {
        return $this->address;
    }

    public function getBodyAsString(): string
    {
        return '<'.$this->address->toString().'>';
    }
}
PKϤ$Z�fhw��mime/Header/MailboxHeader.phpnu�[���<?php

/*
 * This file is part of the Symfony package.
 *
 * (c) Fabien Potencier <fabien@symfony.com>
 *
 * For the full copyright and license information, please view the LICENSE
 * file that was distributed with this source code.
 */

namespace Symfony\Component\Mime\Header;

use Symfony\Component\Mime\Address;
use Symfony\Component\Mime\Exception\RfcComplianceException;

/**
 * A Mailbox MIME Header for something like Sender (one named address).
 *
 * @author Fabien Potencier <fabien@symfony.com>
 */
final class MailboxHeader extends AbstractHeader
{
    private $address;

    public function __construct(string $name, Address $address)
    {
        parent::__construct($name);

        $this->setAddress($address);
    }

    /**
     * @param Address $body
     *
     * @throws RfcComplianceException
     */
    public function setBody($body)
    {
        $this->setAddress($body);
    }

    /**
     * @throws RfcComplianceException
     */
    public function getBody(): Address
    {
        return $this->getAddress();
    }

    /**
     * @throws RfcComplianceException
     */
    public function setAddress(Address $address)
    {
        $this->address = $address;
    }

    public function getAddress(): Address
    {
        return $this->address;
    }

    public function getBodyAsString(): string
    {
        $str = $this->address->getEncodedAddress();
        if ($name = $this->address->getName()) {
            $str = $this->createPhrase($this, $name, $this->getCharset(), true).' <'.$str.'>';
        }

        return $str;
    }

    /**
     * Redefine the encoding requirements for an address.
     *
     * All "specials" must be encoded as the full header value will not be quoted
     *
     * @see RFC 2822 3.2.1
     */
    protected function tokenNeedsEncoding(string $token): bool
    {
        return preg_match('/[()<>\[\]:;@\,."]/', $token) || parent::tokenNeedsEncoding($token);
    }
}
PKϤ$ZA�$��mime/Header/Headers.phpnu�[���<?php

/*
 * This file is part of the Symfony package.
 *
 * (c) Fabien Potencier <fabien@symfony.com>
 *
 * For the full copyright and license information, please view the LICENSE
 * file that was distributed with this source code.
 */

namespace Symfony\Component\Mime\Header;

use Symfony\Component\Mime\Address;
use Symfony\Component\Mime\Exception\LogicException;

/**
 * A collection of headers.
 *
 * @author Fabien Potencier <fabien@symfony.com>
 */
final class Headers
{
    private static $uniqueHeaders = [
        'date', 'from', 'sender', 'reply-to', 'to', 'cc', 'bcc',
        'message-id', 'in-reply-to', 'references', 'subject',
    ];

    private $headers = [];
    private $lineLength = 76;

    public function __construct(HeaderInterface ...$headers)
    {
        foreach ($headers as $header) {
            $this->add($header);
        }
    }

    public function __clone()
    {
        foreach ($this->headers as $name => $collection) {
            foreach ($collection as $i => $header) {
                $this->headers[$name][$i] = clone $header;
            }
        }
    }

    public function setMaxLineLength(int $lineLength)
    {
        $this->lineLength = $lineLength;
        foreach ($this->all() as $header) {
            $header->setMaxLineLength($lineLength);
        }
    }

    public function getMaxLineLength(): int
    {
        return $this->lineLength;
    }

    /**
     * @param (Address|string)[] $addresses
     *
     * @return $this
     */
    public function addMailboxListHeader(string $name, array $addresses): self
    {
        return $this->add(new MailboxListHeader($name, Address::createArray($addresses)));
    }

    /**
     * @param Address|string $address
     *
     * @return $this
     */
    public function addMailboxHeader(string $name, $address): self
    {
        return $this->add(new MailboxHeader($name, Address::create($address)));
    }

    /**
     * @param string|array $ids
     *
     * @return $this
     */
    public function addIdHeader(string $name, $ids): self
    {
        return $this->add(new IdentificationHeader($name, $ids));
    }

    /**
     * @param Address|string $path
     *
     * @return $this
     */
    public function addPathHeader(string $name, $path): self
    {
        return $this->add(new PathHeader($name, $path instanceof Address ? $path : new Address($path)));
    }

    /**
     * @return $this
     */
    public function addDateHeader(string $name, \DateTimeInterface $dateTime): self
    {
        return $this->add(new DateHeader($name, $dateTime));
    }

    /**
     * @return $this
     */
    public function addTextHeader(string $name, string $value): self
    {
        return $this->add(new UnstructuredHeader($name, $value));
    }

    /**
     * @return $this
     */
    public function addParameterizedHeader(string $name, string $value, array $params = []): self
    {
        return $this->add(new ParameterizedHeader($name, $value, $params));
    }

    public function has(string $name): bool
    {
        return isset($this->headers[strtolower($name)]);
    }

    /**
     * @return $this
     */
    public function add(HeaderInterface $header): self
    {
        static $map = [
            'date' => DateHeader::class,
            'from' => MailboxListHeader::class,
            'sender' => MailboxHeader::class,
            'reply-to' => MailboxListHeader::class,
            'to' => MailboxListHeader::class,
            'cc' => MailboxListHeader::class,
            'bcc' => MailboxListHeader::class,
            'message-id' => IdentificationHeader::class,
            'in-reply-to' => IdentificationHeader::class,
            'references' => IdentificationHeader::class,
            'return-path' => PathHeader::class,
        ];

        $header->setMaxLineLength($this->lineLength);
        $name = strtolower($header->getName());

        if (isset($map[$name]) && !$header instanceof $map[$name]) {
            throw new LogicException(sprintf('The "%s" header must be an instance of "%s" (got "%s").', $header->getName(), $map[$name], get_debug_type($header)));
        }

        if (\in_array($name, self::$uniqueHeaders, true) && isset($this->headers[$name]) && \count($this->headers[$name]) > 0) {
            throw new LogicException(sprintf('Impossible to set header "%s" as it\'s already defined and must be unique.', $header->getName()));
        }

        $this->headers[$name][] = $header;

        return $this;
    }

    public function get(string $name): ?HeaderInterface
    {
        $name = strtolower($name);
        if (!isset($this->headers[$name])) {
            return null;
        }

        $values = array_values($this->headers[$name]);

        return array_shift($values);
    }

    public function all(string $name = null): iterable
    {
        if (null === $name) {
            foreach ($this->headers as $name => $collection) {
                foreach ($collection as $header) {
                    yield $name => $header;
                }
            }
        } elseif (isset($this->headers[strtolower($name)])) {
            foreach ($this->headers[strtolower($name)] as $header) {
                yield $header;
            }
        }
    }

    public function getNames(): array
    {
        return array_keys($this->headers);
    }

    public function remove(string $name): void
    {
        unset($this->headers[strtolower($name)]);
    }

    public static function isUniqueHeader(string $name): bool
    {
        return \in_array($name, self::$uniqueHeaders, true);
    }

    public function toString(): string
    {
        $string = '';
        foreach ($this->toArray() as $str) {
            $string .= $str."\r\n";
        }

        return $string;
    }

    public function toArray(): array
    {
        $arr = [];
        foreach ($this->all() as $header) {
            if ('' !== $header->getBodyAsString()) {
                $arr[] = $header->toString();
            }
        }

        return $arr;
    }

    /**
     * @internal
     */
    public function getHeaderBody($name)
    {
        return $this->has($name) ? $this->get($name)->getBody() : null;
    }

    /**
     * @internal
     */
    public function setHeaderBody(string $type, string $name, $body): void
    {
        if ($this->has($name)) {
            $this->get($name)->setBody($body);
        } else {
            $this->{'add'.$type.'Header'}($name, $body);
        }
    }

    /**
     * @internal
     */
    public function getHeaderParameter(string $name, string $parameter): ?string
    {
        if (!$this->has($name)) {
            return null;
        }

        $header = $this->get($name);
        if (!$header instanceof ParameterizedHeader) {
            throw new LogicException(sprintf('Unable to get parameter "%s" on header "%s" as the header is not of class "%s".', $parameter, $name, ParameterizedHeader::class));
        }

        return $header->getParameter($parameter);
    }

    /**
     * @internal
     */
    public function setHeaderParameter(string $name, string $parameter, $value): void
    {
        if (!$this->has($name)) {
            throw new LogicException(sprintf('Unable to set parameter "%s" on header "%s" as the header is not defined.', $parameter, $name));
        }

        $header = $this->get($name);
        if (!$header instanceof ParameterizedHeader) {
            throw new LogicException(sprintf('Unable to set parameter "%s" on header "%s" as the header is not of class "%s".', $parameter, $name, ParameterizedHeader::class));
        }

        $header->setParameter($parameter, $value);
    }
}
PKϤ$Z8�|���mime/Header/HeaderInterface.phpnu�[���<?php

/*
 * This file is part of the Symfony package.
 *
 * (c) Fabien Potencier <fabien@symfony.com>
 *
 * For the full copyright and license information, please view the LICENSE
 * file that was distributed with this source code.
 */

namespace Symfony\Component\Mime\Header;

/**
 * A MIME Header.
 *
 * @author Chris Corbyn
 */
interface HeaderInterface
{
    /**
     * Sets the body.
     *
     * The type depends on the Header concrete class.
     *
     * @param mixed $body
     */
    public function setBody($body);

    /**
     * Gets the body.
     *
     * The return type depends on the Header concrete class.
     *
     * @return mixed
     */
    public function getBody();

    public function setCharset(string $charset);

    public function getCharset(): ?string;

    public function setLanguage(string $lang);

    public function getLanguage(): ?string;

    public function getName(): string;

    public function setMaxLineLength(int $lineLength);

    public function getMaxLineLength(): int;

    /**
     * Gets this Header rendered as a compliant string.
     */
    public function toString(): string;

    /**
     * Gets the header's body, prepared for folding into a final header value.
     *
     * This is not necessarily RFC 2822 compliant since folding white space is
     * not added at this stage (see {@link toString()} for that).
     */
    public function getBodyAsString(): string;
}
PKϤ$Zl�h�6%6%mime/CharacterStream.phpnu�[���<?php

/*
 * This file is part of the Symfony package.
 *
 * (c) Fabien Potencier <fabien@symfony.com>
 *
 * For the full copyright and license information, please view the LICENSE
 * file that was distributed with this source code.
 */

namespace Symfony\Component\Mime;

/**
 * @author Fabien Potencier <fabien@symfony.com>
 * @author Xavier De Cock <xdecock@gmail.com>
 *
 * @internal
 */
final class CharacterStream
{
    /** Pre-computed for optimization */
    private const UTF8_LENGTH_MAP = [
        "\x00" => 1, "\x01" => 1, "\x02" => 1, "\x03" => 1, "\x04" => 1, "\x05" => 1, "\x06" => 1, "\x07" => 1,
        "\x08" => 1, "\x09" => 1, "\x0a" => 1, "\x0b" => 1, "\x0c" => 1, "\x0d" => 1, "\x0e" => 1, "\x0f" => 1,
        "\x10" => 1, "\x11" => 1, "\x12" => 1, "\x13" => 1, "\x14" => 1, "\x15" => 1, "\x16" => 1, "\x17" => 1,
        "\x18" => 1, "\x19" => 1, "\x1a" => 1, "\x1b" => 1, "\x1c" => 1, "\x1d" => 1, "\x1e" => 1, "\x1f" => 1,
        "\x20" => 1, "\x21" => 1, "\x22" => 1, "\x23" => 1, "\x24" => 1, "\x25" => 1, "\x26" => 1, "\x27" => 1,
        "\x28" => 1, "\x29" => 1, "\x2a" => 1, "\x2b" => 1, "\x2c" => 1, "\x2d" => 1, "\x2e" => 1, "\x2f" => 1,
        "\x30" => 1, "\x31" => 1, "\x32" => 1, "\x33" => 1, "\x34" => 1, "\x35" => 1, "\x36" => 1, "\x37" => 1,
        "\x38" => 1, "\x39" => 1, "\x3a" => 1, "\x3b" => 1, "\x3c" => 1, "\x3d" => 1, "\x3e" => 1, "\x3f" => 1,
        "\x40" => 1, "\x41" => 1, "\x42" => 1, "\x43" => 1, "\x44" => 1, "\x45" => 1, "\x46" => 1, "\x47" => 1,
        "\x48" => 1, "\x49" => 1, "\x4a" => 1, "\x4b" => 1, "\x4c" => 1, "\x4d" => 1, "\x4e" => 1, "\x4f" => 1,
        "\x50" => 1, "\x51" => 1, "\x52" => 1, "\x53" => 1, "\x54" => 1, "\x55" => 1, "\x56" => 1, "\x57" => 1,
        "\x58" => 1, "\x59" => 1, "\x5a" => 1, "\x5b" => 1, "\x5c" => 1, "\x5d" => 1, "\x5e" => 1, "\x5f" => 1,
        "\x60" => 1, "\x61" => 1, "\x62" => 1, "\x63" => 1, "\x64" => 1, "\x65" => 1, "\x66" => 1, "\x67" => 1,
        "\x68" => 1, "\x69" => 1, "\x6a" => 1, "\x6b" => 1, "\x6c" => 1, "\x6d" => 1, "\x6e" => 1, "\x6f" => 1,
        "\x70" => 1, "\x71" => 1, "\x72" => 1, "\x73" => 1, "\x74" => 1, "\x75" => 1, "\x76" => 1, "\x77" => 1,
        "\x78" => 1, "\x79" => 1, "\x7a" => 1, "\x7b" => 1, "\x7c" => 1, "\x7d" => 1, "\x7e" => 1, "\x7f" => 1,
        "\x80" => 0, "\x81" => 0, "\x82" => 0, "\x83" => 0, "\x84" => 0, "\x85" => 0, "\x86" => 0, "\x87" => 0,
        "\x88" => 0, "\x89" => 0, "\x8a" => 0, "\x8b" => 0, "\x8c" => 0, "\x8d" => 0, "\x8e" => 0, "\x8f" => 0,
        "\x90" => 0, "\x91" => 0, "\x92" => 0, "\x93" => 0, "\x94" => 0, "\x95" => 0, "\x96" => 0, "\x97" => 0,
        "\x98" => 0, "\x99" => 0, "\x9a" => 0, "\x9b" => 0, "\x9c" => 0, "\x9d" => 0, "\x9e" => 0, "\x9f" => 0,
        "\xa0" => 0, "\xa1" => 0, "\xa2" => 0, "\xa3" => 0, "\xa4" => 0, "\xa5" => 0, "\xa6" => 0, "\xa7" => 0,
        "\xa8" => 0, "\xa9" => 0, "\xaa" => 0, "\xab" => 0, "\xac" => 0, "\xad" => 0, "\xae" => 0, "\xaf" => 0,
        "\xb0" => 0, "\xb1" => 0, "\xb2" => 0, "\xb3" => 0, "\xb4" => 0, "\xb5" => 0, "\xb6" => 0, "\xb7" => 0,
        "\xb8" => 0, "\xb9" => 0, "\xba" => 0, "\xbb" => 0, "\xbc" => 0, "\xbd" => 0, "\xbe" => 0, "\xbf" => 0,
        "\xc0" => 2, "\xc1" => 2, "\xc2" => 2, "\xc3" => 2, "\xc4" => 2, "\xc5" => 2, "\xc6" => 2, "\xc7" => 2,
        "\xc8" => 2, "\xc9" => 2, "\xca" => 2, "\xcb" => 2, "\xcc" => 2, "\xcd" => 2, "\xce" => 2, "\xcf" => 2,
        "\xd0" => 2, "\xd1" => 2, "\xd2" => 2, "\xd3" => 2, "\xd4" => 2, "\xd5" => 2, "\xd6" => 2, "\xd7" => 2,
        "\xd8" => 2, "\xd9" => 2, "\xda" => 2, "\xdb" => 2, "\xdc" => 2, "\xdd" => 2, "\xde" => 2, "\xdf" => 2,
        "\xe0" => 3, "\xe1" => 3, "\xe2" => 3, "\xe3" => 3, "\xe4" => 3, "\xe5" => 3, "\xe6" => 3, "\xe7" => 3,
        "\xe8" => 3, "\xe9" => 3, "\xea" => 3, "\xeb" => 3, "\xec" => 3, "\xed" => 3, "\xee" => 3, "\xef" => 3,
        "\xf0" => 4, "\xf1" => 4, "\xf2" => 4, "\xf3" => 4, "\xf4" => 4, "\xf5" => 4, "\xf6" => 4, "\xf7" => 4,
        "\xf8" => 5, "\xf9" => 5, "\xfa" => 5, "\xfb" => 5, "\xfc" => 6, "\xfd" => 6, "\xfe" => 0, "\xff" => 0,
    ];

    private $data = '';
    private $dataSize = 0;
    private $map = [];
    private $charCount = 0;
    private $currentPos = 0;
    private $fixedWidth = 0;

    /**
     * @param resource|string $input
     */
    public function __construct($input, ?string $charset = 'utf-8')
    {
        $charset = strtolower(trim($charset)) ?: 'utf-8';
        if ('utf-8' === $charset || 'utf8' === $charset) {
            $this->fixedWidth = 0;
            $this->map = ['p' => [], 'i' => []];
        } else {
            switch ($charset) {
                // 16 bits
                case 'ucs2':
                case 'ucs-2':
                case 'utf16':
                case 'utf-16':
                    $this->fixedWidth = 2;
                    break;

                // 32 bits
                case 'ucs4':
                case 'ucs-4':
                case 'utf32':
                case 'utf-32':
                    $this->fixedWidth = 4;
                break;

                // 7-8 bit charsets: (us-)?ascii, (iso|iec)-?8859-?[0-9]+, windows-?125[0-9], cp-?[0-9]+, ansi, macintosh,
                //                   koi-?7, koi-?8-?.+, mik, (cork|t1), v?iscii
                // and fallback
                default:
                    $this->fixedWidth = 1;
            }
        }
        if (\is_resource($input)) {
            $blocks = 16372;
            while (false !== $read = fread($input, $blocks)) {
                $this->write($read);
            }
        } else {
            $this->write($input);
        }
    }

    public function read(int $length): ?string
    {
        if ($this->currentPos >= $this->charCount) {
            return null;
        }
        $length = ($this->currentPos + $length > $this->charCount) ? $this->charCount - $this->currentPos : $length;
        if ($this->fixedWidth > 0) {
            $len = $length * $this->fixedWidth;
            $ret = substr($this->data, $this->currentPos * $this->fixedWidth, $len);
            $this->currentPos += $length;
        } else {
            $end = $this->currentPos + $length;
            $end = $end > $this->charCount ? $this->charCount : $end;
            $ret = '';
            $start = 0;
            if ($this->currentPos > 0) {
                $start = $this->map['p'][$this->currentPos - 1];
            }
            $to = $start;
            for (; $this->currentPos < $end; ++$this->currentPos) {
                if (isset($this->map['i'][$this->currentPos])) {
                    $ret .= substr($this->data, $start, $to - $start).'?';
                    $start = $this->map['p'][$this->currentPos];
                } else {
                    $to = $this->map['p'][$this->currentPos];
                }
            }
            $ret .= substr($this->data, $start, $to - $start);
        }

        return $ret;
    }

    public function readBytes(int $length): ?array
    {
        if (null !== $read = $this->read($length)) {
            return array_map('ord', str_split($read, 1));
        }

        return null;
    }

    public function setPointer(int $charOffset): void
    {
        if ($this->charCount < $charOffset) {
            $charOffset = $this->charCount;
        }
        $this->currentPos = $charOffset;
    }

    public function write(string $chars): void
    {
        $ignored = '';
        $this->data .= $chars;
        if ($this->fixedWidth > 0) {
            $strlen = \strlen($chars);
            $ignoredL = $strlen % $this->fixedWidth;
            $ignored = $ignoredL ? substr($chars, -$ignoredL) : '';
            $this->charCount += ($strlen - $ignoredL) / $this->fixedWidth;
        } else {
            $this->charCount += $this->getUtf8CharPositions($chars, $this->dataSize, $ignored);
        }
        $this->dataSize = \strlen($this->data) - \strlen($ignored);
    }

    private function getUtf8CharPositions(string $string, int $startOffset, string &$ignoredChars): int
    {
        $strlen = \strlen($string);
        $charPos = \count($this->map['p']);
        $foundChars = 0;
        $invalid = false;
        for ($i = 0; $i < $strlen; ++$i) {
            $char = $string[$i];
            $size = self::UTF8_LENGTH_MAP[$char];
            if (0 == $size) {
                /* char is invalid, we must wait for a resync */
                $invalid = true;
                continue;
            }

            if ($invalid) {
                /* We mark the chars as invalid and start a new char */
                $this->map['p'][$charPos + $foundChars] = $startOffset + $i;
                $this->map['i'][$charPos + $foundChars] = true;
                ++$foundChars;
                $invalid = false;
            }
            if (($i + $size) > $strlen) {
                $ignoredChars = substr($string, $i);
                break;
            }
            for ($j = 1; $j < $size; ++$j) {
                $char = $string[$i + $j];
                if ($char > "\x7F" && $char < "\xC0") {
                    // Valid - continue parsing
                } else {
                    /* char is invalid, we must wait for a resync */
                    $invalid = true;
                    continue 2;
                }
            }
            /* Ok we got a complete char here */
            $this->map['p'][$charPos + $foundChars] = $startOffset + $i + $size;
            $i += $j - 1;
            ++$foundChars;
        }

        return $foundChars;
    }
}
PKϤ$Z�'��3mime/DependencyInjection/AddMimeTypeGuesserPass.phpnu�[���<?php

/*
 * This file is part of the Symfony package.
 *
 * (c) Fabien Potencier <fabien@symfony.com>
 *
 * For the full copyright and license information, please view the LICENSE
 * file that was distributed with this source code.
 */

namespace Symfony\Component\Mime\DependencyInjection;

use Symfony\Component\DependencyInjection\Compiler\CompilerPassInterface;
use Symfony\Component\DependencyInjection\ContainerBuilder;
use Symfony\Component\DependencyInjection\Reference;

/**
 * Registers custom mime types guessers.
 *
 * @author Fabien Potencier <fabien@symfony.com>
 */
class AddMimeTypeGuesserPass implements CompilerPassInterface
{
    private $mimeTypesService;
    private $mimeTypeGuesserTag;

    public function __construct(string $mimeTypesService = 'mime_types', string $mimeTypeGuesserTag = 'mime.mime_type_guesser')
    {
        $this->mimeTypesService = $mimeTypesService;
        $this->mimeTypeGuesserTag = $mimeTypeGuesserTag;
    }

    /**
     * {@inheritdoc}
     */
    public function process(ContainerBuilder $container)
    {
        if ($container->has($this->mimeTypesService)) {
            $definition = $container->findDefinition($this->mimeTypesService);
            foreach ($container->findTaggedServiceIds($this->mimeTypeGuesserTag, true) as $id => $attributes) {
                $definition->addMethodCall('registerGuesser', [new Reference($id)]);
            }
        }
    }
}
PKϤ$Z�ӆ)��mime/BodyRendererInterface.phpnu�[���<?php

/*
 * This file is part of the Symfony package.
 *
 * (c) Fabien Potencier <fabien@symfony.com>
 *
 * For the full copyright and license information, please view the LICENSE
 * file that was distributed with this source code.
 */

namespace Symfony\Component\Mime;

/**
 * @author Fabien Potencier <fabien@symfony.com>
 */
interface BodyRendererInterface
{
    public function render(Message $message): void;
}
PKϤ$Z�5AVV mime/FileinfoMimeTypeGuesser.phpnu�[���<?php

/*
 * This file is part of the Symfony package.
 *
 * (c) Fabien Potencier <fabien@symfony.com>
 *
 * For the full copyright and license information, please view the LICENSE
 * file that was distributed with this source code.
 */

namespace Symfony\Component\Mime;

use Symfony\Component\Mime\Exception\InvalidArgumentException;
use Symfony\Component\Mime\Exception\LogicException;

/**
 * Guesses the MIME type using the PECL extension FileInfo.
 *
 * @author Bernhard Schussek <bschussek@gmail.com>
 */
class FileinfoMimeTypeGuesser implements MimeTypeGuesserInterface
{
    private $magicFile;

    /**
     * @param string $magicFile A magic file to use with the finfo instance
     *
     * @see http://www.php.net/manual/en/function.finfo-open.php
     */
    public function __construct(string $magicFile = null)
    {
        $this->magicFile = $magicFile;
    }

    /**
     * {@inheritdoc}
     */
    public function isGuesserSupported(): bool
    {
        return \function_exists('finfo_open');
    }

    /**
     * {@inheritdoc}
     */
    public function guessMimeType(string $path): ?string
    {
        if (!is_file($path) || !is_readable($path)) {
            throw new InvalidArgumentException(sprintf('The "%s" file does not exist or is not readable.', $path));
        }

        if (!$this->isGuesserSupported()) {
            throw new LogicException(sprintf('The "%s" guesser is not supported.', __CLASS__));
        }

        if (false === $finfo = new \finfo(\FILEINFO_MIME_TYPE, $this->magicFile)) {
            return null;
        }
        $mimeType = $finfo->file($path);

        if ($mimeType && 0 === (\strlen($mimeType) % 2)) {
            $mimeStart = substr($mimeType, 0, \strlen($mimeType) >> 1);
            $mimeType = $mimeStart.$mimeStart === $mimeType ? $mimeStart : $mimeType;
        }

        return $mimeType;
    }
}
PKϤ$Zk��H��!mime/Exception/LogicException.phpnu�[���<?php

/*
 * This file is part of the Symfony package.
 *
 * (c) Fabien Potencier <fabien@symfony.com>
 *
 * For the full copyright and license information, please view the LICENSE
 * file that was distributed with this source code.
 */

namespace Symfony\Component\Mime\Exception;

/**
 * @author Fabien Potencier <fabien@symfony.com>
 */
class LogicException extends \LogicException implements ExceptionInterface
{
}
PKϤ$Z��Е�*mime/Exception/AddressEncoderException.phpnu�[���<?php

/*
 * This file is part of the Symfony package.
 *
 * (c) Fabien Potencier <fabien@symfony.com>
 *
 * For the full copyright and license information, please view the LICENSE
 * file that was distributed with this source code.
 */

namespace Symfony\Component\Mime\Exception;

/**
 * @author Fabien Potencier <fabien@symfony.com>
 */
class AddressEncoderException extends RfcComplianceException
{
}
PKϤ$Z�Fz��)mime/Exception/RfcComplianceException.phpnu�[���<?php

/*
 * This file is part of the Symfony package.
 *
 * (c) Fabien Potencier <fabien@symfony.com>
 *
 * For the full copyright and license information, please view the LICENSE
 * file that was distributed with this source code.
 */

namespace Symfony\Component\Mime\Exception;

/**
 * @author Fabien Potencier <fabien@symfony.com>
 */
class RfcComplianceException extends \InvalidArgumentException implements ExceptionInterface
{
}
PKϤ$Z���{��%mime/Exception/ExceptionInterface.phpnu�[���<?php

/*
 * This file is part of the Symfony package.
 *
 * (c) Fabien Potencier <fabien@symfony.com>
 *
 * For the full copyright and license information, please view the LICENSE
 * file that was distributed with this source code.
 */

namespace Symfony\Component\Mime\Exception;

/**
 * @author Fabien Potencier <fabien@symfony.com>
 */
interface ExceptionInterface extends \Throwable
{
}
PKϤ$Z�'���+mime/Exception/InvalidArgumentException.phpnu�[���<?php

/*
 * This file is part of the Symfony package.
 *
 * (c) Fabien Potencier <fabien@symfony.com>
 *
 * For the full copyright and license information, please view the LICENSE
 * file that was distributed with this source code.
 */

namespace Symfony\Component\Mime\Exception;

/**
 * @author Fabien Potencier <fabien@symfony.com>
 */
class InvalidArgumentException extends \InvalidArgumentException implements ExceptionInterface
{
}
PKϤ$Zr)�#mime/Exception/RuntimeException.phpnu�[���<?php

/*
 * This file is part of the Symfony package.
 *
 * (c) Fabien Potencier <fabien@symfony.com>
 *
 * For the full copyright and license information, please view the LICENSE
 * file that was distributed with this source code.
 */

namespace Symfony\Component\Mime\Exception;

/**
 * @author Fabien Potencier <fabien@symfony.com>
 */
class RuntimeException extends \RuntimeException implements ExceptionInterface
{
}
PKϤ$Z��\\mime/CHANGELOG.mdnu�[���CHANGELOG
=========

4.4.0
-----

 * [BC BREAK] Removed `NamedAddress` (`Address` now supports a name)
 * Added PHPUnit constraints
 * Added `AbstractPart::asDebugString()`
 * Added `Address::fromString()`

4.3.3
-----

 * [BC BREAK] Renamed method `Headers::getAll()` to `Headers::all()`.

4.3.0
-----

 * Introduced the component as experimental
PKϤ$Z���))mime/LICENSEnu�[���Copyright (c) 2010-2020 Fabien Potencier

Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is furnished
to do so, subject to the following conditions:

The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.

THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
THE SOFTWARE.
PKϤ$Z��
�:�:mime/Email.phpnu�[���<?php

/*
 * This file is part of the Symfony package.
 *
 * (c) Fabien Potencier <fabien@symfony.com>
 *
 * For the full copyright and license information, please view the LICENSE
 * file that was distributed with this source code.
 */

namespace Symfony\Component\Mime;

use Symfony\Component\Mime\Exception\LogicException;
use Symfony\Component\Mime\Part\AbstractPart;
use Symfony\Component\Mime\Part\DataPart;
use Symfony\Component\Mime\Part\Multipart\AlternativePart;
use Symfony\Component\Mime\Part\Multipart\MixedPart;
use Symfony\Component\Mime\Part\Multipart\RelatedPart;
use Symfony\Component\Mime\Part\TextPart;

/**
 * @author Fabien Potencier <fabien@symfony.com>
 */
class Email extends Message
{
    const PRIORITY_HIGHEST = 1;
    const PRIORITY_HIGH = 2;
    const PRIORITY_NORMAL = 3;
    const PRIORITY_LOW = 4;
    const PRIORITY_LOWEST = 5;

    private const PRIORITY_MAP = [
        self::PRIORITY_HIGHEST => 'Highest',
        self::PRIORITY_HIGH => 'High',
        self::PRIORITY_NORMAL => 'Normal',
        self::PRIORITY_LOW => 'Low',
        self::PRIORITY_LOWEST => 'Lowest',
    ];

    private $text;
    private $textCharset;
    private $html;
    private $htmlCharset;
    private $attachments = [];

    /**
     * @return $this
     */
    public function subject(string $subject)
    {
        return $this->setHeaderBody('Text', 'Subject', $subject);
    }

    public function getSubject(): ?string
    {
        return $this->getHeaders()->getHeaderBody('Subject');
    }

    /**
     * @return $this
     */
    public function date(\DateTimeInterface $dateTime)
    {
        return $this->setHeaderBody('Date', 'Date', $dateTime);
    }

    public function getDate(): ?\DateTimeImmutable
    {
        return $this->getHeaders()->getHeaderBody('Date');
    }

    /**
     * @param Address|string $address
     *
     * @return $this
     */
    public function returnPath($address)
    {
        return $this->setHeaderBody('Path', 'Return-Path', Address::create($address));
    }

    public function getReturnPath(): ?Address
    {
        return $this->getHeaders()->getHeaderBody('Return-Path');
    }

    /**
     * @param Address|string $address
     *
     * @return $this
     */
    public function sender($address)
    {
        return $this->setHeaderBody('Mailbox', 'Sender', Address::create($address));
    }

    public function getSender(): ?Address
    {
        return $this->getHeaders()->getHeaderBody('Sender');
    }

    /**
     * @param Address|string ...$addresses
     *
     * @return $this
     */
    public function addFrom(...$addresses)
    {
        return $this->addListAddressHeaderBody('From', $addresses);
    }

    /**
     * @param Address|string ...$addresses
     *
     * @return $this
     */
    public function from(...$addresses)
    {
        return $this->setListAddressHeaderBody('From', $addresses);
    }

    /**
     * @return Address[]
     */
    public function getFrom(): array
    {
        return $this->getHeaders()->getHeaderBody('From') ?: [];
    }

    /**
     * @param Address|string ...$addresses
     *
     * @return $this
     */
    public function addReplyTo(...$addresses)
    {
        return $this->addListAddressHeaderBody('Reply-To', $addresses);
    }

    /**
     * @param Address|string ...$addresses
     *
     * @return $this
     */
    public function replyTo(...$addresses)
    {
        return $this->setListAddressHeaderBody('Reply-To', $addresses);
    }

    /**
     * @return Address[]
     */
    public function getReplyTo(): array
    {
        return $this->getHeaders()->getHeaderBody('Reply-To') ?: [];
    }

    /**
     * @param Address|string ...$addresses
     *
     * @return $this
     */
    public function addTo(...$addresses)
    {
        return $this->addListAddressHeaderBody('To', $addresses);
    }

    /**
     * @param Address|string ...$addresses
     *
     * @return $this
     */
    public function to(...$addresses)
    {
        return $this->setListAddressHeaderBody('To', $addresses);
    }

    /**
     * @return Address[]
     */
    public function getTo(): array
    {
        return $this->getHeaders()->getHeaderBody('To') ?: [];
    }

    /**
     * @param Address|string ...$addresses
     *
     * @return $this
     */
    public function addCc(...$addresses)
    {
        return $this->addListAddressHeaderBody('Cc', $addresses);
    }

    /**
     * @param Address|string ...$addresses
     *
     * @return $this
     */
    public function cc(...$addresses)
    {
        return $this->setListAddressHeaderBody('Cc', $addresses);
    }

    /**
     * @return Address[]
     */
    public function getCc(): array
    {
        return $this->getHeaders()->getHeaderBody('Cc') ?: [];
    }

    /**
     * @param Address|string ...$addresses
     *
     * @return $this
     */
    public function addBcc(...$addresses)
    {
        return $this->addListAddressHeaderBody('Bcc', $addresses);
    }

    /**
     * @param Address|string ...$addresses
     *
     * @return $this
     */
    public function bcc(...$addresses)
    {
        return $this->setListAddressHeaderBody('Bcc', $addresses);
    }

    /**
     * @return Address[]
     */
    public function getBcc(): array
    {
        return $this->getHeaders()->getHeaderBody('Bcc') ?: [];
    }

    /**
     * Sets the priority of this message.
     *
     * The value is an integer where 1 is the highest priority and 5 is the lowest.
     *
     * @return $this
     */
    public function priority(int $priority)
    {
        if ($priority > 5) {
            $priority = 5;
        } elseif ($priority < 1) {
            $priority = 1;
        }

        return $this->setHeaderBody('Text', 'X-Priority', sprintf('%d (%s)', $priority, self::PRIORITY_MAP[$priority]));
    }

    /**
     * Get the priority of this message.
     *
     * The returned value is an integer where 1 is the highest priority and 5
     * is the lowest.
     */
    public function getPriority(): int
    {
        list($priority) = sscanf($this->getHeaders()->getHeaderBody('X-Priority'), '%[1-5]');

        return $priority ?? 3;
    }

    /**
     * @param resource|string $body
     *
     * @return $this
     */
    public function text($body, string $charset = 'utf-8')
    {
        $this->text = $body;
        $this->textCharset = $charset;

        return $this;
    }

    /**
     * @return resource|string|null
     */
    public function getTextBody()
    {
        return $this->text;
    }

    public function getTextCharset(): ?string
    {
        return $this->textCharset;
    }

    /**
     * @param resource|string|null $body
     *
     * @return $this
     */
    public function html($body, string $charset = 'utf-8')
    {
        $this->html = $body;
        $this->htmlCharset = $charset;

        return $this;
    }

    /**
     * @return resource|string|null
     */
    public function getHtmlBody()
    {
        return $this->html;
    }

    public function getHtmlCharset(): ?string
    {
        return $this->htmlCharset;
    }

    /**
     * @param resource|string $body
     *
     * @return $this
     */
    public function attach($body, string $name = null, string $contentType = null)
    {
        $this->attachments[] = ['body' => $body, 'name' => $name, 'content-type' => $contentType, 'inline' => false];

        return $this;
    }

    /**
     * @return $this
     */
    public function attachFromPath(string $path, string $name = null, string $contentType = null)
    {
        $this->attachments[] = ['path' => $path, 'name' => $name, 'content-type' => $contentType, 'inline' => false];

        return $this;
    }

    /**
     * @param resource|string $body
     *
     * @return $this
     */
    public function embed($body, string $name = null, string $contentType = null)
    {
        $this->attachments[] = ['body' => $body, 'name' => $name, 'content-type' => $contentType, 'inline' => true];

        return $this;
    }

    /**
     * @return $this
     */
    public function embedFromPath(string $path, string $name = null, string $contentType = null)
    {
        $this->attachments[] = ['path' => $path, 'name' => $name, 'content-type' => $contentType, 'inline' => true];

        return $this;
    }

    /**
     * @return $this
     */
    public function attachPart(DataPart $part)
    {
        $this->attachments[] = ['part' => $part];

        return $this;
    }

    /**
     * @return DataPart[]
     */
    public function getAttachments(): array
    {
        $parts = [];
        foreach ($this->attachments as $attachment) {
            $parts[] = $this->createDataPart($attachment);
        }

        return $parts;
    }

    public function getBody(): AbstractPart
    {
        if (null !== $body = parent::getBody()) {
            return $body;
        }

        return $this->generateBody();
    }

    public function ensureValidity()
    {
        if (null === $this->text && null === $this->html && !$this->attachments) {
            throw new LogicException('A message must have a text or an HTML part or attachments.');
        }

        parent::ensureValidity();
    }

    /**
     * Generates an AbstractPart based on the raw body of a message.
     *
     * The most "complex" part generated by this method is when there is text and HTML bodies
     * with related images for the HTML part and some attachments:
     *
     * multipart/mixed
     *         |
     *         |------------> multipart/related
     *         |                      |
     *         |                      |------------> multipart/alternative
     *         |                      |                      |
     *         |                      |                       ------------> text/plain (with content)
     *         |                      |                      |
     *         |                      |                       ------------> text/html (with content)
     *         |                      |
     *         |                       ------------> image/png (with content)
     *         |
     *          ------------> application/pdf (with content)
     */
    private function generateBody(): AbstractPart
    {
        $this->ensureValidity();

        [$htmlPart, $attachmentParts, $inlineParts] = $this->prepareParts();

        $part = null === $this->text ? null : new TextPart($this->text, $this->textCharset);
        if (null !== $htmlPart) {
            if (null !== $part) {
                $part = new AlternativePart($part, $htmlPart);
            } else {
                $part = $htmlPart;
            }
        }

        if ($inlineParts) {
            $part = new RelatedPart($part, ...$inlineParts);
        }

        if ($attachmentParts) {
            if ($part) {
                $part = new MixedPart($part, ...$attachmentParts);
            } else {
                $part = new MixedPart(...$attachmentParts);
            }
        }

        return $part;
    }

    private function prepareParts(): ?array
    {
        $names = [];
        $htmlPart = null;
        $html = $this->html;
        if (null !== $this->html) {
            $htmlPart = new TextPart($html, $this->htmlCharset, 'html');
            $html = $htmlPart->getBody();
            preg_match_all('(<img\s+[^>]*src\s*=\s*(?:([\'"])cid:([^"]+)\\1|cid:([^>\s]+)))i', $html, $names);
            $names = array_filter(array_unique(array_merge($names[2], $names[3])));
        }

        $attachmentParts = $inlineParts = [];
        foreach ($this->attachments as $attachment) {
            foreach ($names as $name) {
                if (isset($attachment['part'])) {
                    continue;
                }
                if ($name !== $attachment['name']) {
                    continue;
                }
                if (isset($inlineParts[$name])) {
                    continue 2;
                }
                $attachment['inline'] = true;
                $inlineParts[$name] = $part = $this->createDataPart($attachment);
                $html = str_replace('cid:'.$name, 'cid:'.$part->getContentId(), $html);
                continue 2;
            }
            $attachmentParts[] = $this->createDataPart($attachment);
        }
        if (null !== $htmlPart) {
            $htmlPart = new TextPart($html, $this->htmlCharset, 'html');
        }

        return [$htmlPart, $attachmentParts, array_values($inlineParts)];
    }

    private function createDataPart(array $attachment): DataPart
    {
        if (isset($attachment['part'])) {
            return $attachment['part'];
        }

        if (isset($attachment['body'])) {
            $part = new DataPart($attachment['body'], $attachment['name'] ?? null, $attachment['content-type'] ?? null);
        } else {
            $part = DataPart::fromPath($attachment['path'] ?? '', $attachment['name'] ?? null, $attachment['content-type'] ?? null);
        }
        if ($attachment['inline']) {
            $part->asInline();
        }

        return $part;
    }

    /**
     * @return $this
     */
    private function setHeaderBody(string $type, string $name, $body): object
    {
        $this->getHeaders()->setHeaderBody($type, $name, $body);

        return $this;
    }

    private function addListAddressHeaderBody(string $name, array $addresses)
    {
        if (!$header = $this->getHeaders()->get($name)) {
            return $this->setListAddressHeaderBody($name, $addresses);
        }
        $header->addAddresses(Address::createArray($addresses));

        return $this;
    }

    private function setListAddressHeaderBody(string $name, array $addresses)
    {
        $addresses = Address::createArray($addresses);
        $headers = $this->getHeaders();
        if ($header = $headers->get($name)) {
            $header->setAddresses($addresses);
        } else {
            $headers->addMailboxListHeader($name, $addresses);
        }

        return $this;
    }

    /**
     * @internal
     */
    public function __serialize(): array
    {
        if (\is_resource($this->text)) {
            $this->text = (new TextPart($this->text))->getBody();
        }

        if (\is_resource($this->html)) {
            $this->html = (new TextPart($this->html))->getBody();
        }

        foreach ($this->attachments as $i => $attachment) {
            if (isset($attachment['body']) && \is_resource($attachment['body'])) {
                $this->attachments[$i]['body'] = (new TextPart($attachment['body']))->getBody();
            }
        }

        return [$this->text, $this->textCharset, $this->html, $this->htmlCharset, $this->attachments, parent::__serialize()];
    }

    /**
     * @internal
     */
    public function __unserialize(array $data): void
    {
        [$this->text, $this->textCharset, $this->html, $this->htmlCharset, $this->attachments, $parentData] = $data;

        parent::__unserialize($parentData);
    }
}
PKϤ$Z,GiJ�	�	"mime/FileBinaryMimeTypeGuesser.phpnu�[���<?php

/*
 * This file is part of the Symfony package.
 *
 * (c) Fabien Potencier <fabien@symfony.com>
 *
 * For the full copyright and license information, please view the LICENSE
 * file that was distributed with this source code.
 */

namespace Symfony\Component\Mime;

use Symfony\Component\Mime\Exception\InvalidArgumentException;
use Symfony\Component\Mime\Exception\LogicException;

/**
 * Guesses the MIME type with the binary "file" (only available on *nix).
 *
 * @author Bernhard Schussek <bschussek@gmail.com>
 */
class FileBinaryMimeTypeGuesser implements MimeTypeGuesserInterface
{
    private $cmd;

    /**
     * The $cmd pattern must contain a "%s" string that will be replaced
     * with the file name to guess.
     *
     * The command output must start with the MIME type of the file.
     *
     * @param string $cmd The command to run to get the MIME type of a file
     */
    public function __construct(string $cmd = 'file -b --mime -- %s 2>/dev/null')
    {
        $this->cmd = $cmd;
    }

    /**
     * {@inheritdoc}
     */
    public function isGuesserSupported(): bool
    {
        static $supported = null;

        if (null !== $supported) {
            return $supported;
        }

        if ('\\' === \DIRECTORY_SEPARATOR || !\function_exists('passthru') || !\function_exists('escapeshellarg')) {
            return $supported = false;
        }

        ob_start();
        passthru('command -v file', $exitStatus);
        $binPath = trim(ob_get_clean());

        return $supported = 0 === $exitStatus && '' !== $binPath;
    }

    /**
     * {@inheritdoc}
     */
    public function guessMimeType(string $path): ?string
    {
        if (!is_file($path) || !is_readable($path)) {
            throw new InvalidArgumentException(sprintf('The "%s" file does not exist or is not readable.', $path));
        }

        if (!$this->isGuesserSupported()) {
            throw new LogicException(sprintf('The "%s" guesser is not supported.', __CLASS__));
        }

        ob_start();

        // need to use --mime instead of -i. see #6641
        passthru(sprintf($this->cmd, escapeshellarg((0 === strpos($path, '-') ? './' : '').$path)), $return);
        if ($return > 0) {
            ob_end_clean();

            return null;
        }

        $type = trim(ob_get_clean());

        if (!preg_match('#^([a-z0-9\-]+/[a-z0-9\-\+\.]+)#i', $type, $match)) {
            // it's not a type, but an error message
            return null;
        }

        return $match[1];
    }
}
PKϤ$Z~6�~~console/ConsoleEvents.phpnu�[���<?php

/*
 * This file is part of the Symfony package.
 *
 * (c) Fabien Potencier <fabien@symfony.com>
 *
 * For the full copyright and license information, please view the LICENSE
 * file that was distributed with this source code.
 */

namespace Symfony\Component\Console;

use Symfony\Component\Console\Event\ConsoleCommandEvent;
use Symfony\Component\Console\Event\ConsoleErrorEvent;
use Symfony\Component\Console\Event\ConsoleSignalEvent;
use Symfony\Component\Console\Event\ConsoleTerminateEvent;

/**
 * Contains all events dispatched by an Application.
 *
 * @author Francesco Levorato <git@flevour.net>
 */
final class ConsoleEvents
{
    /**
     * The COMMAND event allows you to attach listeners before any command is
     * executed by the console. It also allows you to modify the command, input and output
     * before they are handed to the command.
     *
     * @Event("Symfony\Component\Console\Event\ConsoleCommandEvent")
     */
    public const COMMAND = 'console.command';

    /**
     * The SIGNAL event allows you to perform some actions
     * after the command execution was interrupted.
     *
     * @Event("Symfony\Component\Console\Event\ConsoleSignalEvent")
     */
    public const SIGNAL = 'console.signal';

    /**
     * The TERMINATE event allows you to attach listeners after a command is
     * executed by the console.
     *
     * @Event("Symfony\Component\Console\Event\ConsoleTerminateEvent")
     */
    public const TERMINATE = 'console.terminate';

    /**
     * The ERROR event occurs when an uncaught exception or error appears.
     *
     * This event allows you to deal with the exception/error or
     * to modify the thrown exception.
     *
     * @Event("Symfony\Component\Console\Event\ConsoleErrorEvent")
     */
    public const ERROR = 'console.error';

    /**
     * Event aliases.
     *
     * These aliases can be consumed by RegisterListenersPass.
     */
    public const ALIASES = [
        ConsoleCommandEvent::class => self::COMMAND,
        ConsoleErrorEvent::class => self::ERROR,
        ConsoleSignalEvent::class => self::SIGNAL,
        ConsoleTerminateEvent::class => self::TERMINATE,
    ];
}
PKϤ$Z�x0mBB*console/Tests/Tester/CommandTesterTest.phpnu�[���<?php

/*
 * This file is part of the Symfony package.
 *
 * (c) Fabien Potencier <fabien@symfony.com>
 *
 * For the full copyright and license information, please view the LICENSE
 * file that was distributed with this source code.
 */

namespace Symfony\Component\Console\Tests\Tester;

use Symfony\Component\Console\Application;
use Symfony\Component\Console\Command\Command;
use Symfony\Component\Console\Output\Output;
use Symfony\Component\Console\Tester\CommandTester;

class CommandTesterTest extends \PHPUnit_Framework_TestCase
{
    protected $command;
    protected $tester;

    protected function setUp()
    {
        $this->command = new Command('foo');
        $this->command->addArgument('command');
        $this->command->addArgument('foo');
        $this->command->setCode(function ($input, $output) { $output->writeln('foo'); });

        $this->tester = new CommandTester($this->command);
        $this->tester->execute(array('foo' => 'bar'), array('interactive' => false, 'decorated' => false, 'verbosity' => Output::VERBOSITY_VERBOSE));
    }

    protected function tearDown()
    {
        $this->command = null;
        $this->tester = null;
    }

    public function testExecute()
    {
        $this->assertFalse($this->tester->getInput()->isInteractive(), '->execute() takes an interactive option');
        $this->assertFalse($this->tester->getOutput()->isDecorated(), '->execute() takes a decorated option');
        $this->assertEquals(Output::VERBOSITY_VERBOSE, $this->tester->getOutput()->getVerbosity(), '->execute() takes a verbosity option');
    }

    public function testGetInput()
    {
        $this->assertEquals('bar', $this->tester->getInput()->getArgument('foo'), '->getInput() returns the current input instance');
    }

    public function testGetOutput()
    {
        rewind($this->tester->getOutput()->getStream());
        $this->assertEquals('foo'.PHP_EOL, stream_get_contents($this->tester->getOutput()->getStream()), '->getOutput() returns the current output instance');
    }

    public function testGetDisplay()
    {
        $this->assertEquals('foo'.PHP_EOL, $this->tester->getDisplay(), '->getDisplay() returns the display of the last execution');
    }

    public function testGetStatusCode()
    {
        $this->assertSame(0, $this->tester->getStatusCode(), '->getStatusCode() returns the status code');
    }

    public function testCommandFromApplication()
    {
        $application = new Application();
        $application->setAutoExit(false);

        $command = new Command('foo');
        $command->setCode(function ($input, $output) { $output->writeln('foo'); });

        $application->add($command);

        $tester = new CommandTester($application->find('foo'));

        // check that there is no need to pass the command name here
        $this->assertEquals(0, $tester->execute(array()));
    }
}
PKϤ$ZQ��d	d	.console/Tests/Tester/ApplicationTesterTest.phpnu�[���<?php

/*
 * This file is part of the Symfony package.
 *
 * (c) Fabien Potencier <fabien@symfony.com>
 *
 * For the full copyright and license information, please view the LICENSE
 * file that was distributed with this source code.
 */

namespace Symfony\Component\Console\Tests\Tester;

use Symfony\Component\Console\Application;
use Symfony\Component\Console\Output\Output;
use Symfony\Component\Console\Tester\ApplicationTester;

class ApplicationTesterTest extends \PHPUnit_Framework_TestCase
{
    protected $application;
    protected $tester;

    protected function setUp()
    {
        $this->application = new Application();
        $this->application->setAutoExit(false);
        $this->application->register('foo')
            ->addArgument('foo')
            ->setCode(function ($input, $output) { $output->writeln('foo'); })
        ;

        $this->tester = new ApplicationTester($this->application);
        $this->tester->run(array('command' => 'foo', 'foo' => 'bar'), array('interactive' => false, 'decorated' => false, 'verbosity' => Output::VERBOSITY_VERBOSE));
    }

    protected function tearDown()
    {
        $this->application = null;
        $this->tester = null;
    }

    public function testRun()
    {
        $this->assertFalse($this->tester->getInput()->isInteractive(), '->execute() takes an interactive option');
        $this->assertFalse($this->tester->getOutput()->isDecorated(), '->execute() takes a decorated option');
        $this->assertEquals(Output::VERBOSITY_VERBOSE, $this->tester->getOutput()->getVerbosity(), '->execute() takes a verbosity option');
    }

    public function testGetInput()
    {
        $this->assertEquals('bar', $this->tester->getInput()->getArgument('foo'), '->getInput() returns the current input instance');
    }

    public function testGetOutput()
    {
        rewind($this->tester->getOutput()->getStream());
        $this->assertEquals('foo'.PHP_EOL, stream_get_contents($this->tester->getOutput()->getStream()), '->getOutput() returns the current output instance');
    }

    public function testGetDisplay()
    {
        $this->assertEquals('foo'.PHP_EOL, $this->tester->getDisplay(), '->getDisplay() returns the display of the last execution');
    }

    public function testGetStatusCode()
    {
        $this->assertSame(0, $this->tester->getStatusCode(), '->getStatusCode() returns the status code');
    }
}
PKϤ$Z���66.console/Tests/Descriptor/XmlDescriptorTest.phpnu�[���<?php

/*
 * This file is part of the Symfony package.
 *
 * (c) Fabien Potencier <fabien@symfony.com>
 *
 * For the full copyright and license information, please view the LICENSE
 * file that was distributed with this source code.
 */

namespace Symfony\Component\Console\Tests\Descriptor;

use Symfony\Component\Console\Descriptor\XmlDescriptor;

class XmlDescriptorTest extends AbstractDescriptorTest
{
    protected function getDescriptor()
    {
        return new XmlDescriptor();
    }

    protected function getFormat()
    {
        return 'xml';
    }
}
PKϤ$Z%�%H/console/Tests/Descriptor/JsonDescriptorTest.phpnu�[���<?php

/*
 * This file is part of the Symfony package.
 *
 * (c) Fabien Potencier <fabien@symfony.com>
 *
 * For the full copyright and license information, please view the LICENSE
 * file that was distributed with this source code.
 */

namespace Symfony\Component\Console\Tests\Descriptor;

use Symfony\Component\Console\Descriptor\JsonDescriptor;
use Symfony\Component\Console\Output\BufferedOutput;

class JsonDescriptorTest extends AbstractDescriptorTest
{
    protected function getDescriptor()
    {
        return new JsonDescriptor();
    }

    protected function getFormat()
    {
        return 'json';
    }

    protected function assertDescription($expectedDescription, $describedObject)
    {
        $output = new BufferedOutput(BufferedOutput::VERBOSITY_NORMAL, true);
        $this->getDescriptor()->describe($output, $describedObject, array('raw_output' => true));
        $this->assertEquals(json_decode(trim($expectedDescription), true), json_decode(trim(str_replace(PHP_EOL, "\n", $output->fetch())), true));
    }
}
PKϤ$Z�����,console/Tests/Descriptor/ObjectsProvider.phpnu�[���<?php

/*
 * This file is part of the Symfony package.
 *
 * (c) Fabien Potencier <fabien@symfony.com>
 *
 * For the full copyright and license information, please view the LICENSE
 * file that was distributed with this source code.
 */

namespace Symfony\Component\Console\Tests\Descriptor;

use Symfony\Component\Console\Input\InputArgument;
use Symfony\Component\Console\Input\InputDefinition;
use Symfony\Component\Console\Input\InputOption;
use Symfony\Component\Console\Tests\Fixtures\DescriptorApplication1;
use Symfony\Component\Console\Tests\Fixtures\DescriptorApplication2;
use Symfony\Component\Console\Tests\Fixtures\DescriptorCommand1;
use Symfony\Component\Console\Tests\Fixtures\DescriptorCommand2;

/**
 * @author Jean-François Simon <contact@jfsimon.fr>
 */
class ObjectsProvider
{
    public static function getInputArguments()
    {
        return array(
            'input_argument_1' => new InputArgument('argument_name', InputArgument::REQUIRED),
            'input_argument_2' => new InputArgument('argument_name', InputArgument::IS_ARRAY, 'argument description'),
            'input_argument_3' => new InputArgument('argument_name', InputArgument::OPTIONAL, 'argument description', 'default_value'),
            'input_argument_4' => new InputArgument('argument_name', InputArgument::REQUIRED, "multiline\nargument description"),
        );
    }

    public static function getInputOptions()
    {
        return array(
            'input_option_1' => new InputOption('option_name', 'o', InputOption::VALUE_NONE),
            'input_option_2' => new InputOption('option_name', 'o', InputOption::VALUE_OPTIONAL, 'option description', 'default_value'),
            'input_option_3' => new InputOption('option_name', 'o', InputOption::VALUE_REQUIRED, 'option description'),
            'input_option_4' => new InputOption('option_name', 'o', InputOption::VALUE_IS_ARRAY | InputOption::VALUE_OPTIONAL, 'option description', array()),
            'input_option_5' => new InputOption('option_name', 'o', InputOption::VALUE_REQUIRED, "multiline\noption description"),
            'input_option_6' => new InputOption('option_name', array('o', 'O'), InputOption::VALUE_REQUIRED, 'option with multiple shortcuts'),
        );
    }

    public static function getInputDefinitions()
    {
        return array(
            'input_definition_1' => new InputDefinition(),
            'input_definition_2' => new InputDefinition(array(new InputArgument('argument_name', InputArgument::REQUIRED))),
            'input_definition_3' => new InputDefinition(array(new InputOption('option_name', 'o', InputOption::VALUE_NONE))),
            'input_definition_4' => new InputDefinition(array(
                new InputArgument('argument_name', InputArgument::REQUIRED),
                new InputOption('option_name', 'o', InputOption::VALUE_NONE),
            )),
        );
    }

    public static function getCommands()
    {
        return array(
            'command_1' => new DescriptorCommand1(),
            'command_2' => new DescriptorCommand2(),
        );
    }

    public static function getApplications()
    {
        return array(
            'application_1' => new DescriptorApplication1(),
            'application_2' => new DescriptorApplication2(),
        );
    }
}
PKϤ$ZK� 99/console/Tests/Descriptor/TextDescriptorTest.phpnu�[���<?php

/*
 * This file is part of the Symfony package.
 *
 * (c) Fabien Potencier <fabien@symfony.com>
 *
 * For the full copyright and license information, please view the LICENSE
 * file that was distributed with this source code.
 */

namespace Symfony\Component\Console\Tests\Descriptor;

use Symfony\Component\Console\Descriptor\TextDescriptor;

class TextDescriptorTest extends AbstractDescriptorTest
{
    protected function getDescriptor()
    {
        return new TextDescriptor();
    }

    protected function getFormat()
    {
        return 'txt';
    }
}
PKϤ$Z1H�DDD3console/Tests/Descriptor/MarkdownDescriptorTest.phpnu�[���<?php

/*
 * This file is part of the Symfony package.
 *
 * (c) Fabien Potencier <fabien@symfony.com>
 *
 * For the full copyright and license information, please view the LICENSE
 * file that was distributed with this source code.
 */

namespace Symfony\Component\Console\Tests\Descriptor;

use Symfony\Component\Console\Descriptor\MarkdownDescriptor;

class MarkdownDescriptorTest extends AbstractDescriptorTest
{
    protected function getDescriptor()
    {
        return new MarkdownDescriptor();
    }

    protected function getFormat()
    {
        return 'md';
    }
}
PKϤ$Z�aV���3console/Tests/Descriptor/AbstractDescriptorTest.phpnu�[���<?php

/*
 * This file is part of the Symfony package.
 *
 * (c) Fabien Potencier <fabien@symfony.com>
 *
 * For the full copyright and license information, please view the LICENSE
 * file that was distributed with this source code.
 */

namespace Symfony\Component\Console\Tests\Descriptor;

use Symfony\Component\Console\Application;
use Symfony\Component\Console\Command\Command;
use Symfony\Component\Console\Input\InputArgument;
use Symfony\Component\Console\Input\InputDefinition;
use Symfony\Component\Console\Input\InputOption;
use Symfony\Component\Console\Output\BufferedOutput;

abstract class AbstractDescriptorTest extends \PHPUnit_Framework_TestCase
{
    /** @dataProvider getDescribeInputArgumentTestData */
    public function testDescribeInputArgument(InputArgument $argument, $expectedDescription)
    {
        $this->assertDescription($expectedDescription, $argument);
    }

    /** @dataProvider getDescribeInputOptionTestData */
    public function testDescribeInputOption(InputOption $option, $expectedDescription)
    {
        $this->assertDescription($expectedDescription, $option);
    }

    /** @dataProvider getDescribeInputDefinitionTestData */
    public function testDescribeInputDefinition(InputDefinition $definition, $expectedDescription)
    {
        $this->assertDescription($expectedDescription, $definition);
    }

    /** @dataProvider getDescribeCommandTestData */
    public function testDescribeCommand(Command $command, $expectedDescription)
    {
        $this->assertDescription($expectedDescription, $command);
    }

    /** @dataProvider getDescribeApplicationTestData */
    public function testDescribeApplication(Application $application, $expectedDescription)
    {
        // Replaces the dynamic placeholders of the command help text with a static version.
        // The placeholder %command.full_name% includes the script path that is not predictable
        // and can not be tested against.
        foreach ($application->all() as $command) {
            $command->setHelp(str_replace('%command.full_name%', 'app/console %command.name%', $command->getHelp()));
        }

        $this->assertDescription($expectedDescription, $application);
    }

    public function getDescribeInputArgumentTestData()
    {
        return $this->getDescriptionTestData(ObjectsProvider::getInputArguments());
    }

    public function getDescribeInputOptionTestData()
    {
        return $this->getDescriptionTestData(ObjectsProvider::getInputOptions());
    }

    public function getDescribeInputDefinitionTestData()
    {
        return $this->getDescriptionTestData(ObjectsProvider::getInputDefinitions());
    }

    public function getDescribeCommandTestData()
    {
        return $this->getDescriptionTestData(ObjectsProvider::getCommands());
    }

    public function getDescribeApplicationTestData()
    {
        return $this->getDescriptionTestData(ObjectsProvider::getApplications());
    }

    abstract protected function getDescriptor();

    abstract protected function getFormat();

    private function getDescriptionTestData(array $objects)
    {
        $data = array();
        foreach ($objects as $name => $object) {
            $description = file_get_contents(sprintf('%s/../Fixtures/%s.%s', __DIR__, $name, $this->getFormat()));
            $data[] = array($object, $description);
        }

        return $data;
    }

    protected function assertDescription($expectedDescription, $describedObject)
    {
        $output = new BufferedOutput(BufferedOutput::VERBOSITY_NORMAL, true);
        $this->getDescriptor()->describe($output, $describedObject, array('raw_output' => true));
        $this->assertEquals(trim($expectedDescription), trim(str_replace(PHP_EOL, "\n", $output->fetch())));
    }
}
PKϤ$Zb?�}��(console/Tests/Style/SymfonyStyleTest.phpnu�[���<?php

/*
 * This file is part of the Symfony package.
 *
 * (c) Fabien Potencier <fabien@symfony.com>
 *
 * For the full copyright and license information, please view the LICENSE
 * file that was distributed with this source code.
 */

namespace Symfony\Component\Console\Tests\Style;

use PHPUnit_Framework_TestCase;
use Symfony\Component\Console\Command\Command;
use Symfony\Component\Console\Input\InputInterface;
use Symfony\Component\Console\Output\OutputInterface;
use Symfony\Component\Console\Style\SymfonyStyle;
use Symfony\Component\Console\Tester\CommandTester;

class SymfonyStyleTest extends PHPUnit_Framework_TestCase
{
    /** @var Command */
    protected $command;
    /** @var CommandTester */
    protected $tester;

    protected function setUp()
    {
        $this->command = new Command('sfstyle');
        $this->tester = new CommandTester($this->command);
    }

    protected function tearDown()
    {
        $this->command = null;
        $this->tester = null;
    }

    /**
     * @dataProvider inputCommandToOutputFilesProvider
     */
    public function testOutputs($inputCommandFilepath, $outputFilepath)
    {
        $code = require $inputCommandFilepath;
        $this->command->setCode($code);
        $this->tester->execute(array(), array('interactive' => false, 'decorated' => false));
        $this->assertStringEqualsFile($outputFilepath, $this->tester->getDisplay(true));
    }

    public function inputCommandToOutputFilesProvider()
    {
        $baseDir = __DIR__.'/../Fixtures/Style/SymfonyStyle';

        return array_map(null, glob($baseDir.'/command/command_*.php'), glob($baseDir.'/output/output_*.txt'));
    }

    public function testLongWordsBlockWrapping()
    {
        $word = 'Lopadotemachoselachogaleokranioleipsanodrimhypotrimmatosilphioparaomelitokatakechymenokichlepikossyphophattoperisteralektryonoptekephalliokigklopeleiolagoiosiraiobaphetraganopterygovgollhjvhvljfezefeqifzeiqgiqzhrsdgihqzridghqridghqirshdghdghieridgheirhsdgehrsdvhqrsidhqshdgihrsidvqhneriqsdvjzergetsrfhgrstsfhsetsfhesrhdgtesfhbzrtfbrztvetbsdfbrsdfbrn';
        $wordLength = strlen($word);
        $maxLineLength = SymfonyStyle::MAX_LINE_LENGTH - 3;

        $this->command->setCode(function (InputInterface $input, OutputInterface $output) use ($word) {
            $sfStyle = new SymfonyStyleWithForcedLineLength($input, $output);
            $sfStyle->block($word, 'CUSTOM', 'fg=white;bg=blue', ' § ', false);
        });

        $this->tester->execute(array(), array('interactive' => false, 'decorated' => false));
        $expectedCount = (int) ceil($wordLength / ($maxLineLength)) + (int) ($wordLength > $maxLineLength - 5);
        $this->assertSame($expectedCount, substr_count($this->tester->getDisplay(true), ' § '));
    }
}

/**
 * Use this class in tests to force the line length
 * and ensure a consistent output for expectations.
 */
class SymfonyStyleWithForcedLineLength extends SymfonyStyle
{
    public function __construct(InputInterface $input, OutputInterface $output)
    {
        parent::__construct($input, $output);

        $ref = new \ReflectionProperty(get_parent_class($this), 'lineLength');
        $ref->setAccessible(true);
        $ref->setValue($this, 120);
    }
}
PKϤ$Z]HY�����!console/Tests/ApplicationTest.phpnu�[���<?php

/*
 * This file is part of the Symfony package.
 *
 * (c) Fabien Potencier <fabien@symfony.com>
 *
 * For the full copyright and license information, please view the LICENSE
 * file that was distributed with this source code.
 */

namespace Symfony\Component\Console\Tests;

use Symfony\Component\Console\Application;
use Symfony\Component\Console\Helper\HelperSet;
use Symfony\Component\Console\Helper\FormatterHelper;
use Symfony\Component\Console\Input\ArgvInput;
use Symfony\Component\Console\Input\ArrayInput;
use Symfony\Component\Console\Input\InputInterface;
use Symfony\Component\Console\Input\InputArgument;
use Symfony\Component\Console\Input\InputDefinition;
use Symfony\Component\Console\Input\InputOption;
use Symfony\Component\Console\Output\NullOutput;
use Symfony\Component\Console\Output\Output;
use Symfony\Component\Console\Output\OutputInterface;
use Symfony\Component\Console\Output\StreamOutput;
use Symfony\Component\Console\Tester\ApplicationTester;
use Symfony\Component\Console\Event\ConsoleCommandEvent;
use Symfony\Component\Console\Event\ConsoleExceptionEvent;
use Symfony\Component\Console\Event\ConsoleTerminateEvent;
use Symfony\Component\EventDispatcher\EventDispatcher;

class ApplicationTest extends \PHPUnit_Framework_TestCase
{
    protected static $fixturesPath;

    public static function setUpBeforeClass()
    {
        self::$fixturesPath = realpath(__DIR__.'/Fixtures/');
        require_once self::$fixturesPath.'/FooCommand.php';
        require_once self::$fixturesPath.'/Foo1Command.php';
        require_once self::$fixturesPath.'/Foo2Command.php';
        require_once self::$fixturesPath.'/Foo3Command.php';
        require_once self::$fixturesPath.'/Foo4Command.php';
        require_once self::$fixturesPath.'/Foo5Command.php';
        require_once self::$fixturesPath.'/FoobarCommand.php';
        require_once self::$fixturesPath.'/BarBucCommand.php';
        require_once self::$fixturesPath.'/FooSubnamespaced1Command.php';
        require_once self::$fixturesPath.'/FooSubnamespaced2Command.php';
    }

    protected function normalizeLineBreaks($text)
    {
        return str_replace(PHP_EOL, "\n", $text);
    }

    /**
     * Replaces the dynamic placeholders of the command help text with a static version.
     * The placeholder %command.full_name% includes the script path that is not predictable
     * and can not be tested against.
     */
    protected function ensureStaticCommandHelp(Application $application)
    {
        foreach ($application->all() as $command) {
            $command->setHelp(str_replace('%command.full_name%', 'app/console %command.name%', $command->getHelp()));
        }
    }

    public function testConstructor()
    {
        $application = new Application('foo', 'bar');
        $this->assertEquals('foo', $application->getName(), '__construct() takes the application name as its first argument');
        $this->assertEquals('bar', $application->getVersion(), '__construct() takes the application version as its second argument');
        $this->assertEquals(array('help', 'list'), array_keys($application->all()), '__construct() registered the help and list commands by default');
    }

    public function testSetGetName()
    {
        $application = new Application();
        $application->setName('foo');
        $this->assertEquals('foo', $application->getName(), '->setName() sets the name of the application');
    }

    public function testSetGetVersion()
    {
        $application = new Application();
        $application->setVersion('bar');
        $this->assertEquals('bar', $application->getVersion(), '->setVersion() sets the version of the application');
    }

    public function testGetLongVersion()
    {
        $application = new Application('foo', 'bar');
        $this->assertEquals('<info>foo</info> version <comment>bar</comment>', $application->getLongVersion(), '->getLongVersion() returns the long version of the application');
    }

    public function testHelp()
    {
        $application = new Application();
        $this->assertStringEqualsFile(self::$fixturesPath.'/application_gethelp.txt', $this->normalizeLineBreaks($application->getHelp()), '->getHelp() returns a help message');
    }

    public function testAll()
    {
        $application = new Application();
        $commands = $application->all();
        $this->assertInstanceOf('Symfony\\Component\\Console\\Command\\HelpCommand', $commands['help'], '->all() returns the registered commands');

        $application->add(new \FooCommand());
        $commands = $application->all('foo');
        $this->assertCount(1, $commands, '->all() takes a namespace as its first argument');
    }

    public function testRegister()
    {
        $application = new Application();
        $command = $application->register('foo');
        $this->assertEquals('foo', $command->getName(), '->register() registers a new command');
    }

    public function testAdd()
    {
        $application = new Application();
        $application->add($foo = new \FooCommand());
        $commands = $application->all();
        $this->assertEquals($foo, $commands['foo:bar'], '->add() registers a command');

        $application = new Application();
        $application->addCommands(array($foo = new \FooCommand(), $foo1 = new \Foo1Command()));
        $commands = $application->all();
        $this->assertEquals(array($foo, $foo1), array($commands['foo:bar'], $commands['foo:bar1']), '->addCommands() registers an array of commands');
    }

    /**
     * @expectedException \LogicException
     * @expectedExceptionMessage Command class "Foo5Command" is not correctly initialized. You probably forgot to call the parent constructor.
     */
    public function testAddCommandWithEmptyConstructor()
    {
        $application = new Application();
        $application->add(new \Foo5Command());
    }

    public function testHasGet()
    {
        $application = new Application();
        $this->assertTrue($application->has('list'), '->has() returns true if a named command is registered');
        $this->assertFalse($application->has('afoobar'), '->has() returns false if a named command is not registered');

        $application->add($foo = new \FooCommand());
        $this->assertTrue($application->has('afoobar'), '->has() returns true if an alias is registered');
        $this->assertEquals($foo, $application->get('foo:bar'), '->get() returns a command by name');
        $this->assertEquals($foo, $application->get('afoobar'), '->get() returns a command by alias');

        $application = new Application();
        $application->add($foo = new \FooCommand());
        // simulate --help
        $r = new \ReflectionObject($application);
        $p = $r->getProperty('wantHelps');
        $p->setAccessible(true);
        $p->setValue($application, true);
        $command = $application->get('foo:bar');
        $this->assertInstanceOf('Symfony\Component\Console\Command\HelpCommand', $command, '->get() returns the help command if --help is provided as the input');
    }

    public function testSilentHelp()
    {
        $application = new Application();
        $application->setAutoExit(false);
        $application->setCatchExceptions(false);

        $tester = new ApplicationTester($application);
        $tester->run(array('-h' => true, '-q' => true), array('decorated' => false));

        $this->assertEmpty($tester->getDisplay(true));
    }

    /**
     * @expectedException        Symfony\Component\Console\Exception\CommandNotFoundException
     * @expectedExceptionMessage The command "foofoo" does not exist.
     */
    public function testGetInvalidCommand()
    {
        $application = new Application();
        $application->get('foofoo');
    }

    public function testGetNamespaces()
    {
        $application = new Application();
        $application->add(new \FooCommand());
        $application->add(new \Foo1Command());
        $this->assertEquals(array('foo'), $application->getNamespaces(), '->getNamespaces() returns an array of unique used namespaces');
    }

    public function testFindNamespace()
    {
        $application = new Application();
        $application->add(new \FooCommand());
        $this->assertEquals('foo', $application->findNamespace('foo'), '->findNamespace() returns the given namespace if it exists');
        $this->assertEquals('foo', $application->findNamespace('f'), '->findNamespace() finds a namespace given an abbreviation');
        $application->add(new \Foo2Command());
        $this->assertEquals('foo', $application->findNamespace('foo'), '->findNamespace() returns the given namespace if it exists');
    }

    public function testFindNamespaceWithSubnamespaces()
    {
        $application = new Application();
        $application->add(new \FooSubnamespaced1Command());
        $application->add(new \FooSubnamespaced2Command());
        $this->assertEquals('foo', $application->findNamespace('foo'), '->findNamespace() returns commands even if the commands are only contained in subnamespaces');
    }

    /**
     * @expectedException        Symfony\Component\Console\Exception\CommandNotFoundException
     * @expectedExceptionMessage The namespace "f" is ambiguous (foo, foo1).
     */
    public function testFindAmbiguousNamespace()
    {
        $application = new Application();
        $application->add(new \BarBucCommand());
        $application->add(new \FooCommand());
        $application->add(new \Foo2Command());
        $application->findNamespace('f');
    }

    /**
     * @expectedException        Symfony\Component\Console\Exception\CommandNotFoundException
     * @expectedExceptionMessage There are no commands defined in the "bar" namespace.
     */
    public function testFindInvalidNamespace()
    {
        $application = new Application();
        $application->findNamespace('bar');
    }

    /**
     * @expectedException        Symfony\Component\Console\Exception\CommandNotFoundException
     * @expectedExceptionMessage Command "foo1" is not defined
     */
    public function testFindUniqueNameButNamespaceName()
    {
        $application = new Application();
        $application->add(new \FooCommand());
        $application->add(new \Foo1Command());
        $application->add(new \Foo2Command());

        $application->find($commandName = 'foo1');
    }

    public function testFind()
    {
        $application = new Application();
        $application->add(new \FooCommand());

        $this->assertInstanceOf('FooCommand', $application->find('foo:bar'), '->find() returns a command if its name exists');
        $this->assertInstanceOf('Symfony\Component\Console\Command\HelpCommand', $application->find('h'), '->find() returns a command if its name exists');
        $this->assertInstanceOf('FooCommand', $application->find('f:bar'), '->find() returns a command if the abbreviation for the namespace exists');
        $this->assertInstanceOf('FooCommand', $application->find('f:b'), '->find() returns a command if the abbreviation for the namespace and the command name exist');
        $this->assertInstanceOf('FooCommand', $application->find('a'), '->find() returns a command if the abbreviation exists for an alias');
    }

    /**
     * @dataProvider provideAmbiguousAbbreviations
     */
    public function testFindWithAmbiguousAbbreviations($abbreviation, $expectedExceptionMessage)
    {
        $this->setExpectedException('Symfony\Component\Console\Exception\CommandNotFoundException', $expectedExceptionMessage);

        $application = new Application();
        $application->add(new \FooCommand());
        $application->add(new \Foo1Command());
        $application->add(new \Foo2Command());

        $application->find($abbreviation);
    }

    public function provideAmbiguousAbbreviations()
    {
        return array(
            array('f', 'Command "f" is not defined.'),
            array('a', 'Command "a" is ambiguous (afoobar, afoobar1 and 1 more).'),
            array('foo:b', 'Command "foo:b" is ambiguous (foo:bar, foo:bar1 and 1 more).'),
        );
    }

    public function testFindCommandEqualNamespace()
    {
        $application = new Application();
        $application->add(new \Foo3Command());
        $application->add(new \Foo4Command());

        $this->assertInstanceOf('Foo3Command', $application->find('foo3:bar'), '->find() returns the good command even if a namespace has same name');
        $this->assertInstanceOf('Foo4Command', $application->find('foo3:bar:toh'), '->find() returns a command even if its namespace equals another command name');
    }

    public function testFindCommandWithAmbiguousNamespacesButUniqueName()
    {
        $application = new Application();
        $application->add(new \FooCommand());
        $application->add(new \FoobarCommand());

        $this->assertInstanceOf('FoobarCommand', $application->find('f:f'));
    }

    public function testFindCommandWithMissingNamespace()
    {
        $application = new Application();
        $application->add(new \Foo4Command());

        $this->assertInstanceOf('Foo4Command', $application->find('f::t'));
    }

    /**
     * @dataProvider             provideInvalidCommandNamesSingle
     * @expectedException        Symfony\Component\Console\Exception\CommandNotFoundException
     * @expectedExceptionMessage Did you mean this
     */
    public function testFindAlternativeExceptionMessageSingle($name)
    {
        $application = new Application();
        $application->add(new \Foo3Command());
        $application->find($name);
    }

    public function provideInvalidCommandNamesSingle()
    {
        return array(
            array('foo3:baR'),
            array('foO3:bar'),
        );
    }

    public function testFindAlternativeExceptionMessageMultiple()
    {
        $application = new Application();
        $application->add(new \FooCommand());
        $application->add(new \Foo1Command());
        $application->add(new \Foo2Command());

        // Command + plural
        try {
            $application->find('foo:baR');
            $this->fail('->find() throws a CommandNotFoundException if command does not exist, with alternatives');
        } catch (\Exception $e) {
            $this->assertInstanceOf('Symfony\Component\Console\Exception\CommandNotFoundException', $e, '->find() throws a CommandNotFoundException if command does not exist, with alternatives');
            $this->assertRegExp('/Did you mean one of these/', $e->getMessage(), '->find() throws a CommandNotFoundException if command does not exist, with alternatives');
            $this->assertRegExp('/foo1:bar/', $e->getMessage());
            $this->assertRegExp('/foo:bar/', $e->getMessage());
        }

        // Namespace + plural
        try {
            $application->find('foo2:bar');
            $this->fail('->find() throws a CommandNotFoundException if command does not exist, with alternatives');
        } catch (\Exception $e) {
            $this->assertInstanceOf('Symfony\Component\Console\Exception\CommandNotFoundException', $e, '->find() throws a CommandNotFoundException if command does not exist, with alternatives');
            $this->assertRegExp('/Did you mean one of these/', $e->getMessage(), '->find() throws a CommandNotFoundException if command does not exist, with alternatives');
            $this->assertRegExp('/foo1/', $e->getMessage());
        }

        $application->add(new \Foo3Command());
        $application->add(new \Foo4Command());

        // Subnamespace + plural
        try {
            $a = $application->find('foo3:');
            $this->fail('->find() should throw an Symfony\Component\Console\Exception\CommandNotFoundException if a command is ambiguous because of a subnamespace, with alternatives');
        } catch (\Exception $e) {
            $this->assertInstanceOf('Symfony\Component\Console\Exception\CommandNotFoundException', $e);
            $this->assertRegExp('/foo3:bar/', $e->getMessage());
            $this->assertRegExp('/foo3:bar:toh/', $e->getMessage());
        }
    }

    public function testFindAlternativeCommands()
    {
        $application = new Application();

        $application->add(new \FooCommand());
        $application->add(new \Foo1Command());
        $application->add(new \Foo2Command());

        try {
            $application->find($commandName = 'Unknown command');
            $this->fail('->find() throws a CommandNotFoundException if command does not exist');
        } catch (\Exception $e) {
            $this->assertInstanceOf('Symfony\Component\Console\Exception\CommandNotFoundException', $e, '->find() throws a CommandNotFoundException if command does not exist');
            $this->assertSame(array(), $e->getAlternatives());
            $this->assertEquals(sprintf('Command "%s" is not defined.', $commandName), $e->getMessage(), '->find() throws a CommandNotFoundException if command does not exist, without alternatives');
        }

        // Test if "bar1" command throw a "CommandNotFoundException" and does not contain
        // "foo:bar" as alternative because "bar1" is too far from "foo:bar"
        try {
            $application->find($commandName = 'bar1');
            $this->fail('->find() throws a CommandNotFoundException if command does not exist');
        } catch (\Exception $e) {
            $this->assertInstanceOf('Symfony\Component\Console\Exception\CommandNotFoundException', $e, '->find() throws a CommandNotFoundException if command does not exist');
            $this->assertSame(array('afoobar1', 'foo:bar1'), $e->getAlternatives());
            $this->assertRegExp(sprintf('/Command "%s" is not defined./', $commandName), $e->getMessage(), '->find() throws a CommandNotFoundException if command does not exist, with alternatives');
            $this->assertRegExp('/afoobar1/', $e->getMessage(), '->find() throws a CommandNotFoundException if command does not exist, with alternative : "afoobar1"');
            $this->assertRegExp('/foo:bar1/', $e->getMessage(), '->find() throws a CommandNotFoundException if command does not exist, with alternative : "foo:bar1"');
            $this->assertNotRegExp('/foo:bar(?>!1)/', $e->getMessage(), '->find() throws a CommandNotFoundException if command does not exist, without "foo:bar" alternative');
        }
    }

    public function testFindAlternativeCommandsWithAnAlias()
    {
        $fooCommand = new \FooCommand();
        $fooCommand->setAliases(array('foo2'));

        $application = new Application();
        $application->add($fooCommand);

        $result = $application->find('foo');

        $this->assertSame($fooCommand, $result);
    }

    public function testFindAlternativeNamespace()
    {
        $application = new Application();

        $application->add(new \FooCommand());
        $application->add(new \Foo1Command());
        $application->add(new \Foo2Command());
        $application->add(new \foo3Command());

        try {
            $application->find('Unknown-namespace:Unknown-command');
            $this->fail('->find() throws a CommandNotFoundException if namespace does not exist');
        } catch (\Exception $e) {
            $this->assertInstanceOf('Symfony\Component\Console\Exception\CommandNotFoundException', $e, '->find() throws a CommandNotFoundException if namespace does not exist');
            $this->assertSame(array(), $e->getAlternatives());
            $this->assertEquals('There are no commands defined in the "Unknown-namespace" namespace.', $e->getMessage(), '->find() throws a CommandNotFoundException if namespace does not exist, without alternatives');
        }

        try {
            $application->find('foo2:command');
            $this->fail('->find() throws a CommandNotFoundException if namespace does not exist');
        } catch (\Exception $e) {
            $this->assertInstanceOf('Symfony\Component\Console\Exception\CommandNotFoundException', $e, '->find() throws a CommandNotFoundException if namespace does not exist');
            $this->assertCount(3, $e->getAlternatives());
            $this->assertContains('foo', $e->getAlternatives());
            $this->assertContains('foo1', $e->getAlternatives());
            $this->assertContains('foo3', $e->getAlternatives());
            $this->assertRegExp('/There are no commands defined in the "foo2" namespace./', $e->getMessage(), '->find() throws a CommandNotFoundException if namespace does not exist, with alternative');
            $this->assertRegExp('/foo/', $e->getMessage(), '->find() throws a CommandNotFoundException if namespace does not exist, with alternative : "foo"');
            $this->assertRegExp('/foo1/', $e->getMessage(), '->find() throws a CommandNotFoundException if namespace does not exist, with alternative : "foo1"');
            $this->assertRegExp('/foo3/', $e->getMessage(), '->find() throws a CommandNotFoundException if namespace does not exist, with alternative : "foo3"');
        }
    }

    public function testFindNamespaceDoesNotFailOnDeepSimilarNamespaces()
    {
        $application = $this->getMock('Symfony\Component\Console\Application', array('getNamespaces'));
        $application->expects($this->once())
            ->method('getNamespaces')
            ->will($this->returnValue(array('foo:sublong', 'bar:sub')));

        $this->assertEquals('foo:sublong', $application->findNamespace('f:sub'));
    }

    /**
     * @expectedException Symfony\Component\Console\Exception\CommandNotFoundException
     * @expectedExceptionMessage Command "foo::bar" is not defined.
     */
    public function testFindWithDoubleColonInNameThrowsException()
    {
        $application = new Application();
        $application->add(new \FooCommand());
        $application->add(new \Foo4Command());
        $application->find('foo::bar');
    }

    public function testSetCatchExceptions()
    {
        $application = $this->getMock('Symfony\Component\Console\Application', array('getTerminalWidth'));
        $application->setAutoExit(false);
        $application->expects($this->any())
            ->method('getTerminalWidth')
            ->will($this->returnValue(120));
        $tester = new ApplicationTester($application);

        $application->setCatchExceptions(true);
        $tester->run(array('command' => 'foo'), array('decorated' => false));
        $this->assertStringEqualsFile(self::$fixturesPath.'/application_renderexception1.txt', $tester->getDisplay(true), '->setCatchExceptions() sets the catch exception flag');

        $application->setCatchExceptions(false);
        try {
            $tester->run(array('command' => 'foo'), array('decorated' => false));
            $this->fail('->setCatchExceptions() sets the catch exception flag');
        } catch (\Exception $e) {
            $this->assertInstanceOf('\Exception', $e, '->setCatchExceptions() sets the catch exception flag');
            $this->assertEquals('Command "foo" is not defined.', $e->getMessage(), '->setCatchExceptions() sets the catch exception flag');
        }
    }

    /**
     * @group legacy
     */
    public function testLegacyAsText()
    {
        $application = new Application();
        $application->add(new \FooCommand());
        $this->ensureStaticCommandHelp($application);
        $this->assertStringEqualsFile(self::$fixturesPath.'/application_astext1.txt', $this->normalizeLineBreaks($application->asText()), '->asText() returns a text representation of the application');
        $this->assertStringEqualsFile(self::$fixturesPath.'/application_astext2.txt', $this->normalizeLineBreaks($application->asText('foo')), '->asText() returns a text representation of the application');
    }

    /**
     * @group legacy
     */
    public function testLegacyAsXml()
    {
        $application = new Application();
        $application->add(new \FooCommand());
        $this->ensureStaticCommandHelp($application);
        $this->assertXmlStringEqualsXmlFile(self::$fixturesPath.'/application_asxml1.txt', $application->asXml(), '->asXml() returns an XML representation of the application');
        $this->assertXmlStringEqualsXmlFile(self::$fixturesPath.'/application_asxml2.txt', $application->asXml('foo'), '->asXml() returns an XML representation of the application');
    }

    public function testRenderException()
    {
        $application = $this->getMock('Symfony\Component\Console\Application', array('getTerminalWidth'));
        $application->setAutoExit(false);
        $application->expects($this->any())
            ->method('getTerminalWidth')
            ->will($this->returnValue(120));
        $tester = new ApplicationTester($application);

        $tester->run(array('command' => 'foo'), array('decorated' => false));
        $this->assertStringEqualsFile(self::$fixturesPath.'/application_renderexception1.txt', $tester->getDisplay(true), '->renderException() renders a pretty exception');

        $tester->run(array('command' => 'foo'), array('decorated' => false, 'verbosity' => Output::VERBOSITY_VERBOSE));
        $this->assertContains('Exception trace', $tester->getDisplay(), '->renderException() renders a pretty exception with a stack trace when verbosity is verbose');

        $tester->run(array('command' => 'list', '--foo' => true), array('decorated' => false));
        $this->assertStringEqualsFile(self::$fixturesPath.'/application_renderexception2.txt', $tester->getDisplay(true), '->renderException() renders the command synopsis when an exception occurs in the context of a command');

        $application->add(new \Foo3Command());
        $tester = new ApplicationTester($application);
        $tester->run(array('command' => 'foo3:bar'), array('decorated' => false));
        $this->assertStringEqualsFile(self::$fixturesPath.'/application_renderexception3.txt', $tester->getDisplay(true), '->renderException() renders a pretty exceptions with previous exceptions');

        $tester->run(array('command' => 'foo3:bar'), array('decorated' => true));
        $this->assertStringEqualsFile(self::$fixturesPath.'/application_renderexception3decorated.txt', $tester->getDisplay(true), '->renderException() renders a pretty exceptions with previous exceptions');

        $application = $this->getMock('Symfony\Component\Console\Application', array('getTerminalWidth'));
        $application->setAutoExit(false);
        $application->expects($this->any())
            ->method('getTerminalWidth')
            ->will($this->returnValue(32));
        $tester = new ApplicationTester($application);

        $tester->run(array('command' => 'foo'), array('decorated' => false));
        $this->assertStringEqualsFile(self::$fixturesPath.'/application_renderexception4.txt', $tester->getDisplay(true), '->renderException() wraps messages when they are bigger than the terminal');
    }

    public function testRenderExceptionWithDoubleWidthCharacters()
    {
        $application = $this->getMock('Symfony\Component\Console\Application', array('getTerminalWidth'));
        $application->setAutoExit(false);
        $application->expects($this->any())
            ->method('getTerminalWidth')
            ->will($this->returnValue(120));
        $application->register('foo')->setCode(function () {
            throw new \Exception('エラーメッセージ');
        });
        $tester = new ApplicationTester($application);

        $tester->run(array('command' => 'foo'), array('decorated' => false));
        $this->assertStringEqualsFile(self::$fixturesPath.'/application_renderexception_doublewidth1.txt', $tester->getDisplay(true), '->renderException() renders a pretty exceptions with previous exceptions');

        $tester->run(array('command' => 'foo'), array('decorated' => true));
        $this->assertStringEqualsFile(self::$fixturesPath.'/application_renderexception_doublewidth1decorated.txt', $tester->getDisplay(true), '->renderException() renders a pretty exceptions with previous exceptions');

        $application = $this->getMock('Symfony\Component\Console\Application', array('getTerminalWidth'));
        $application->setAutoExit(false);
        $application->expects($this->any())
            ->method('getTerminalWidth')
            ->will($this->returnValue(32));
        $application->register('foo')->setCode(function () {
            throw new \Exception('コマンドの実行中にエラーが発生しました。');
        });
        $tester = new ApplicationTester($application);
        $tester->run(array('command' => 'foo'), array('decorated' => false));
        $this->assertStringEqualsFile(self::$fixturesPath.'/application_renderexception_doublewidth2.txt', $tester->getDisplay(true), '->renderException() wraps messages when they are bigger than the terminal');
    }

    public function testRun()
    {
        $application = new Application();
        $application->setAutoExit(false);
        $application->setCatchExceptions(false);
        $application->add($command = new \Foo1Command());
        $_SERVER['argv'] = array('cli.php', 'foo:bar1');

        ob_start();
        $application->run();
        ob_end_clean();

        $this->assertInstanceOf('Symfony\Component\Console\Input\ArgvInput', $command->input, '->run() creates an ArgvInput by default if none is given');
        $this->assertInstanceOf('Symfony\Component\Console\Output\ConsoleOutput', $command->output, '->run() creates a ConsoleOutput by default if none is given');

        $application = new Application();
        $application->setAutoExit(false);
        $application->setCatchExceptions(false);

        $this->ensureStaticCommandHelp($application);
        $tester = new ApplicationTester($application);

        $tester->run(array(), array('decorated' => false));
        $this->assertStringEqualsFile(self::$fixturesPath.'/application_run1.txt', $tester->getDisplay(true), '->run() runs the list command if no argument is passed');

        $tester->run(array('--help' => true), array('decorated' => false));
        $this->assertStringEqualsFile(self::$fixturesPath.'/application_run2.txt', $tester->getDisplay(true), '->run() runs the help command if --help is passed');

        $tester->run(array('-h' => true), array('decorated' => false));
        $this->assertStringEqualsFile(self::$fixturesPath.'/application_run2.txt', $tester->getDisplay(true), '->run() runs the help command if -h is passed');

        $tester->run(array('command' => 'list', '--help' => true), array('decorated' => false));
        $this->assertStringEqualsFile(self::$fixturesPath.'/application_run3.txt', $tester->getDisplay(true), '->run() displays the help if --help is passed');

        $tester->run(array('command' => 'list', '-h' => true), array('decorated' => false));
        $this->assertStringEqualsFile(self::$fixturesPath.'/application_run3.txt', $tester->getDisplay(true), '->run() displays the help if -h is passed');

        $tester->run(array('--ansi' => true));
        $this->assertTrue($tester->getOutput()->isDecorated(), '->run() forces color output if --ansi is passed');

        $tester->run(array('--no-ansi' => true));
        $this->assertFalse($tester->getOutput()->isDecorated(), '->run() forces color output to be disabled if --no-ansi is passed');

        $tester->run(array('--version' => true), array('decorated' => false));
        $this->assertStringEqualsFile(self::$fixturesPath.'/application_run4.txt', $tester->getDisplay(true), '->run() displays the program version if --version is passed');

        $tester->run(array('-V' => true), array('decorated' => false));
        $this->assertStringEqualsFile(self::$fixturesPath.'/application_run4.txt', $tester->getDisplay(true), '->run() displays the program version if -v is passed');

        $tester->run(array('command' => 'list', '--quiet' => true));
        $this->assertSame('', $tester->getDisplay(), '->run() removes all output if --quiet is passed');

        $tester->run(array('command' => 'list', '-q' => true));
        $this->assertSame('', $tester->getDisplay(), '->run() removes all output if -q is passed');

        $tester->run(array('command' => 'list', '--verbose' => true));
        $this->assertSame(Output::VERBOSITY_VERBOSE, $tester->getOutput()->getVerbosity(), '->run() sets the output to verbose if --verbose is passed');

        $tester->run(array('command' => 'list', '--verbose' => 1));
        $this->assertSame(Output::VERBOSITY_VERBOSE, $tester->getOutput()->getVerbosity(), '->run() sets the output to verbose if --verbose=1 is passed');

        $tester->run(array('command' => 'list', '--verbose' => 2));
        $this->assertSame(Output::VERBOSITY_VERY_VERBOSE, $tester->getOutput()->getVerbosity(), '->run() sets the output to very verbose if --verbose=2 is passed');

        $tester->run(array('command' => 'list', '--verbose' => 3));
        $this->assertSame(Output::VERBOSITY_DEBUG, $tester->getOutput()->getVerbosity(), '->run() sets the output to debug if --verbose=3 is passed');

        $tester->run(array('command' => 'list', '--verbose' => 4));
        $this->assertSame(Output::VERBOSITY_VERBOSE, $tester->getOutput()->getVerbosity(), '->run() sets the output to verbose if unknown --verbose level is passed');

        $tester->run(array('command' => 'list', '-v' => true));
        $this->assertSame(Output::VERBOSITY_VERBOSE, $tester->getOutput()->getVerbosity(), '->run() sets the output to verbose if -v is passed');

        $tester->run(array('command' => 'list', '-vv' => true));
        $this->assertSame(Output::VERBOSITY_VERY_VERBOSE, $tester->getOutput()->getVerbosity(), '->run() sets the output to verbose if -v is passed');

        $tester->run(array('command' => 'list', '-vvv' => true));
        $this->assertSame(Output::VERBOSITY_DEBUG, $tester->getOutput()->getVerbosity(), '->run() sets the output to verbose if -v is passed');

        $application = new Application();
        $application->setAutoExit(false);
        $application->setCatchExceptions(false);
        $application->add(new \FooCommand());
        $tester = new ApplicationTester($application);

        $tester->run(array('command' => 'foo:bar', '--no-interaction' => true), array('decorated' => false));
        $this->assertSame('called'.PHP_EOL, $tester->getDisplay(), '->run() does not call interact() if --no-interaction is passed');

        $tester->run(array('command' => 'foo:bar', '-n' => true), array('decorated' => false));
        $this->assertSame('called'.PHP_EOL, $tester->getDisplay(), '->run() does not call interact() if -n is passed');
    }

    /**
     * Issue #9285.
     *
     * If the "verbose" option is just before an argument in ArgvInput,
     * an argument value should not be treated as verbosity value.
     * This test will fail with "Not enough arguments." if broken
     */
    public function testVerboseValueNotBreakArguments()
    {
        $application = new Application();
        $application->setAutoExit(false);
        $application->setCatchExceptions(false);
        $application->add(new \FooCommand());

        $output = new StreamOutput(fopen('php://memory', 'w', false));

        $input = new ArgvInput(array('cli.php', '-v', 'foo:bar'));
        $application->run($input, $output);

        $input = new ArgvInput(array('cli.php', '--verbose', 'foo:bar'));
        $application->run($input, $output);
    }

    public function testRunReturnsIntegerExitCode()
    {
        $exception = new \Exception('', 4);

        $application = $this->getMock('Symfony\Component\Console\Application', array('doRun'));
        $application->setAutoExit(false);
        $application->expects($this->once())
             ->method('doRun')
             ->will($this->throwException($exception));

        $exitCode = $application->run(new ArrayInput(array()), new NullOutput());

        $this->assertSame(4, $exitCode, '->run() returns integer exit code extracted from raised exception');
    }

    public function testRunReturnsExitCodeOneForExceptionCodeZero()
    {
        $exception = new \Exception('', 0);

        $application = $this->getMock('Symfony\Component\Console\Application', array('doRun'));
        $application->setAutoExit(false);
        $application->expects($this->once())
             ->method('doRun')
             ->will($this->throwException($exception));

        $exitCode = $application->run(new ArrayInput(array()), new NullOutput());

        $this->assertSame(1, $exitCode, '->run() returns exit code 1 when exception code is 0');
    }

    /**
     * @expectedException \LogicException
     * @expectedExceptionMessage An option with shortcut "e" already exists.
     */
    public function testAddingOptionWithDuplicateShortcut()
    {
        $dispatcher = new EventDispatcher();
        $application = new Application();
        $application->setAutoExit(false);
        $application->setCatchExceptions(false);
        $application->setDispatcher($dispatcher);

        $application->getDefinition()->addOption(new InputOption('--env', '-e', InputOption::VALUE_REQUIRED, 'Environment'));

        $application
            ->register('foo')
            ->setAliases(array('f'))
            ->setDefinition(array(new InputOption('survey', 'e', InputOption::VALUE_REQUIRED, 'My option with a shortcut.')))
            ->setCode(function (InputInterface $input, OutputInterface $output) {})
        ;

        $input = new ArrayInput(array('command' => 'foo'));
        $output = new NullOutput();

        $application->run($input, $output);
    }

    /**
     * @expectedException \LogicException
     * @dataProvider getAddingAlreadySetDefinitionElementData
     */
    public function testAddingAlreadySetDefinitionElementData($def)
    {
        $application = new Application();
        $application->setAutoExit(false);
        $application->setCatchExceptions(false);
        $application
            ->register('foo')
            ->setDefinition(array($def))
            ->setCode(function (InputInterface $input, OutputInterface $output) {})
        ;

        $input = new ArrayInput(array('command' => 'foo'));
        $output = new NullOutput();
        $application->run($input, $output);
    }

    public function getAddingAlreadySetDefinitionElementData()
    {
        return array(
            array(new InputArgument('command', InputArgument::REQUIRED)),
            array(new InputOption('quiet', '', InputOption::VALUE_NONE)),
            array(new InputOption('query', 'q', InputOption::VALUE_NONE)),
        );
    }

    public function testGetDefaultHelperSetReturnsDefaultValues()
    {
        $application = new Application();
        $application->setAutoExit(false);
        $application->setCatchExceptions(false);

        $helperSet = $application->getHelperSet();

        $this->assertTrue($helperSet->has('formatter'));
        $this->assertTrue($helperSet->has('dialog'));
        $this->assertTrue($helperSet->has('progress'));
    }

    public function testAddingSingleHelperSetOverwritesDefaultValues()
    {
        $application = new Application();
        $application->setAutoExit(false);
        $application->setCatchExceptions(false);

        $application->setHelperSet(new HelperSet(array(new FormatterHelper())));

        $helperSet = $application->getHelperSet();

        $this->assertTrue($helperSet->has('formatter'));

        // no other default helper set should be returned
        $this->assertFalse($helperSet->has('dialog'));
        $this->assertFalse($helperSet->has('progress'));
    }

    public function testOverwritingDefaultHelperSetOverwritesDefaultValues()
    {
        $application = new CustomApplication();
        $application->setAutoExit(false);
        $application->setCatchExceptions(false);

        $application->setHelperSet(new HelperSet(array(new FormatterHelper())));

        $helperSet = $application->getHelperSet();

        $this->assertTrue($helperSet->has('formatter'));

        // no other default helper set should be returned
        $this->assertFalse($helperSet->has('dialog'));
        $this->assertFalse($helperSet->has('progress'));
    }

    public function testGetDefaultInputDefinitionReturnsDefaultValues()
    {
        $application = new Application();
        $application->setAutoExit(false);
        $application->setCatchExceptions(false);

        $inputDefinition = $application->getDefinition();

        $this->assertTrue($inputDefinition->hasArgument('command'));

        $this->assertTrue($inputDefinition->hasOption('help'));
        $this->assertTrue($inputDefinition->hasOption('quiet'));
        $this->assertTrue($inputDefinition->hasOption('verbose'));
        $this->assertTrue($inputDefinition->hasOption('version'));
        $this->assertTrue($inputDefinition->hasOption('ansi'));
        $this->assertTrue($inputDefinition->hasOption('no-ansi'));
        $this->assertTrue($inputDefinition->hasOption('no-interaction'));
    }

    public function testOverwritingDefaultInputDefinitionOverwritesDefaultValues()
    {
        $application = new CustomApplication();
        $application->setAutoExit(false);
        $application->setCatchExceptions(false);

        $inputDefinition = $application->getDefinition();

        // check whether the default arguments and options are not returned any more
        $this->assertFalse($inputDefinition->hasArgument('command'));

        $this->assertFalse($inputDefinition->hasOption('help'));
        $this->assertFalse($inputDefinition->hasOption('quiet'));
        $this->assertFalse($inputDefinition->hasOption('verbose'));
        $this->assertFalse($inputDefinition->hasOption('version'));
        $this->assertFalse($inputDefinition->hasOption('ansi'));
        $this->assertFalse($inputDefinition->hasOption('no-ansi'));
        $this->assertFalse($inputDefinition->hasOption('no-interaction'));

        $this->assertTrue($inputDefinition->hasOption('custom'));
    }

    public function testSettingCustomInputDefinitionOverwritesDefaultValues()
    {
        $application = new Application();
        $application->setAutoExit(false);
        $application->setCatchExceptions(false);

        $application->setDefinition(new InputDefinition(array(new InputOption('--custom', '-c', InputOption::VALUE_NONE, 'Set the custom input definition.'))));

        $inputDefinition = $application->getDefinition();

        // check whether the default arguments and options are not returned any more
        $this->assertFalse($inputDefinition->hasArgument('command'));

        $this->assertFalse($inputDefinition->hasOption('help'));
        $this->assertFalse($inputDefinition->hasOption('quiet'));
        $this->assertFalse($inputDefinition->hasOption('verbose'));
        $this->assertFalse($inputDefinition->hasOption('version'));
        $this->assertFalse($inputDefinition->hasOption('ansi'));
        $this->assertFalse($inputDefinition->hasOption('no-ansi'));
        $this->assertFalse($inputDefinition->hasOption('no-interaction'));

        $this->assertTrue($inputDefinition->hasOption('custom'));
    }

    public function testRunWithDispatcher()
    {
        $application = new Application();
        $application->setAutoExit(false);
        $application->setDispatcher($this->getDispatcher());

        $application->register('foo')->setCode(function (InputInterface $input, OutputInterface $output) {
            $output->write('foo.');
        });

        $tester = new ApplicationTester($application);
        $tester->run(array('command' => 'foo'));
        $this->assertEquals('before.foo.after.'.PHP_EOL, $tester->getDisplay());
    }

    /**
     * @expectedException        \LogicException
     * @expectedExceptionMessage caught
     */
    public function testRunWithExceptionAndDispatcher()
    {
        $application = new Application();
        $application->setDispatcher($this->getDispatcher());
        $application->setAutoExit(false);
        $application->setCatchExceptions(false);

        $application->register('foo')->setCode(function (InputInterface $input, OutputInterface $output) {
            throw new \RuntimeException('foo');
        });

        $tester = new ApplicationTester($application);
        $tester->run(array('command' => 'foo'));
    }

    public function testRunDispatchesAllEventsWithException()
    {
        $application = new Application();
        $application->setDispatcher($this->getDispatcher());
        $application->setAutoExit(false);

        $application->register('foo')->setCode(function (InputInterface $input, OutputInterface $output) {
            $output->write('foo.');

            throw new \RuntimeException('foo');
        });

        $tester = new ApplicationTester($application);
        $tester->run(array('command' => 'foo'));
        $this->assertContains('before.foo.caught.after.', $tester->getDisplay());
    }

    public function testRunWithDispatcherSkippingCommand()
    {
        $application = new Application();
        $application->setDispatcher($this->getDispatcher(true));
        $application->setAutoExit(false);

        $application->register('foo')->setCode(function (InputInterface $input, OutputInterface $output) {
            $output->write('foo.');
        });

        $tester = new ApplicationTester($application);
        $exitCode = $tester->run(array('command' => 'foo'));
        $this->assertContains('before.after.', $tester->getDisplay());
        $this->assertEquals(ConsoleCommandEvent::RETURN_CODE_DISABLED, $exitCode);
    }

    public function testRunWithDispatcherAccessingInputOptions()
    {
        $noInteractionValue = null;
        $quietValue = null;

        $dispatcher = $this->getDispatcher();
        $dispatcher->addListener('console.command', function (ConsoleCommandEvent $event) use (&$noInteractionValue, &$quietValue) {
            $input = $event->getInput();

            $noInteractionValue = $input->getOption('no-interaction');
            $quietValue = $input->getOption('quiet');
        });

        $application = new Application();
        $application->setDispatcher($dispatcher);
        $application->setAutoExit(false);

        $application->register('foo')->setCode(function (InputInterface $input, OutputInterface $output) {
            $output->write('foo.');
        });

        $tester = new ApplicationTester($application);
        $tester->run(array('command' => 'foo', '--no-interaction' => true));

        $this->assertTrue($noInteractionValue);
        $this->assertFalse($quietValue);
    }

    public function testRunWithDispatcherAddingInputOptions()
    {
        $extraValue = null;

        $dispatcher = $this->getDispatcher();
        $dispatcher->addListener('console.command', function (ConsoleCommandEvent $event) use (&$extraValue) {
            $definition = $event->getCommand()->getDefinition();
            $input = $event->getInput();

            $definition->addOption(new InputOption('extra', null, InputOption::VALUE_REQUIRED));
            $input->bind($definition);

            $extraValue = $input->getOption('extra');
        });

        $application = new Application();
        $application->setDispatcher($dispatcher);
        $application->setAutoExit(false);

        $application->register('foo')->setCode(function (InputInterface $input, OutputInterface $output) {
            $output->write('foo.');
        });

        $tester = new ApplicationTester($application);
        $tester->run(array('command' => 'foo', '--extra' => 'some test value'));

        $this->assertEquals('some test value', $extraValue);
    }

    public function testTerminalDimensions()
    {
        $application = new Application();
        $originalDimensions = $application->getTerminalDimensions();
        $this->assertCount(2, $originalDimensions);

        $width = 80;
        if ($originalDimensions[0] == $width) {
            $width = 100;
        }

        $application->setTerminalDimensions($width, 80);
        $this->assertSame(array($width, 80), $application->getTerminalDimensions());
    }

    protected function getDispatcher($skipCommand = false)
    {
        $dispatcher = new EventDispatcher();
        $dispatcher->addListener('console.command', function (ConsoleCommandEvent $event) use ($skipCommand) {
            $event->getOutput()->write('before.');

            if ($skipCommand) {
                $event->disableCommand();
            }
        });
        $dispatcher->addListener('console.terminate', function (ConsoleTerminateEvent $event) use ($skipCommand) {
            $event->getOutput()->writeln('after.');

            if (!$skipCommand) {
                $event->setExitCode(113);
            }
        });
        $dispatcher->addListener('console.exception', function (ConsoleExceptionEvent $event) {
            $event->getOutput()->write('caught.');

            $event->setException(new \LogicException('caught.', $event->getExitCode(), $event->getException()));
        });

        return $dispatcher;
    }

    public function testSetRunCustomDefaultCommand()
    {
        $command = new \FooCommand();

        $application = new Application();
        $application->setAutoExit(false);
        $application->add($command);
        $application->setDefaultCommand($command->getName());

        $tester = new ApplicationTester($application);
        $tester->run(array());
        $this->assertEquals('interact called'.PHP_EOL.'called'.PHP_EOL, $tester->getDisplay(), 'Application runs the default set command if different from \'list\' command');

        $application = new CustomDefaultCommandApplication();
        $application->setAutoExit(false);

        $tester = new ApplicationTester($application);
        $tester->run(array());

        $this->assertEquals('interact called'.PHP_EOL.'called'.PHP_EOL, $tester->getDisplay(), 'Application runs the default set command if different from \'list\' command');
    }

    /**
     * @requires function posix_isatty
     */
    public function testCanCheckIfTerminalIsInteractive()
    {
        $application = new CustomDefaultCommandApplication();
        $application->setAutoExit(false);

        $tester = new ApplicationTester($application);
        $tester->run(array('command' => 'help'));

        $this->assertFalse($tester->getInput()->hasParameterOption(array('--no-interaction', '-n')));

        $inputStream = $application->getHelperSet()->get('question')->getInputStream();
        $this->assertEquals($tester->getInput()->isInteractive(), @posix_isatty($inputStream));
    }
}

class CustomApplication extends Application
{
    /**
     * Overwrites the default input definition.
     *
     * @return InputDefinition An InputDefinition instance
     */
    protected function getDefaultInputDefinition()
    {
        return new InputDefinition(array(new InputOption('--custom', '-c', InputOption::VALUE_NONE, 'Set the custom input definition.')));
    }

    /**
     * Gets the default helper set with the helpers that should always be available.
     *
     * @return HelperSet A HelperSet instance
     */
    protected function getDefaultHelperSet()
    {
        return new HelperSet(array(new FormatterHelper()));
    }
}

class CustomDefaultCommandApplication extends Application
{
    /**
     * Overwrites the constructor in order to set a different default command.
     */
    public function __construct()
    {
        parent::__construct();

        $command = new \FooCommand();
        $this->add($command);
        $this->setDefaultCommand($command->getName());
    }
}
PKϤ$Z�q��55)console/Tests/Command/HelpCommandTest.phpnu�[���<?php

/*
 * This file is part of the Symfony package.
 *
 * (c) Fabien Potencier <fabien@symfony.com>
 *
 * For the full copyright and license information, please view the LICENSE
 * file that was distributed with this source code.
 */

namespace Symfony\Component\Console\Tests\Command;

use Symfony\Component\Console\Tester\CommandTester;
use Symfony\Component\Console\Command\HelpCommand;
use Symfony\Component\Console\Command\ListCommand;
use Symfony\Component\Console\Application;

class HelpCommandTest extends \PHPUnit_Framework_TestCase
{
    public function testExecuteForCommandAlias()
    {
        $command = new HelpCommand();
        $command->setApplication(new Application());
        $commandTester = new CommandTester($command);
        $commandTester->execute(array('command_name' => 'li'), array('decorated' => false));
        $this->assertContains('list [options] [--] [<namespace>]', $commandTester->getDisplay(), '->execute() returns a text help for the given command alias');
        $this->assertContains('format=FORMAT', $commandTester->getDisplay(), '->execute() returns a text help for the given command alias');
        $this->assertContains('raw', $commandTester->getDisplay(), '->execute() returns a text help for the given command alias');
    }

    public function testExecuteForCommand()
    {
        $command = new HelpCommand();
        $commandTester = new CommandTester($command);
        $command->setCommand(new ListCommand());
        $commandTester->execute(array(), array('decorated' => false));
        $this->assertContains('list [options] [--] [<namespace>]', $commandTester->getDisplay(), '->execute() returns a text help for the given command');
        $this->assertContains('format=FORMAT', $commandTester->getDisplay(), '->execute() returns a text help for the given command');
        $this->assertContains('raw', $commandTester->getDisplay(), '->execute() returns a text help for the given command');
    }

    public function testExecuteForCommandWithXmlOption()
    {
        $command = new HelpCommand();
        $commandTester = new CommandTester($command);
        $command->setCommand(new ListCommand());
        $commandTester->execute(array('--format' => 'xml'));
        $this->assertContains('<command', $commandTester->getDisplay(), '->execute() returns an XML help text if --xml is passed');
    }

    public function testExecuteForApplicationCommand()
    {
        $application = new Application();
        $commandTester = new CommandTester($application->get('help'));
        $commandTester->execute(array('command_name' => 'list'));
        $this->assertContains('list [options] [--] [<namespace>]', $commandTester->getDisplay(), '->execute() returns a text help for the given command');
        $this->assertContains('format=FORMAT', $commandTester->getDisplay(), '->execute() returns a text help for the given command');
        $this->assertContains('raw', $commandTester->getDisplay(), '->execute() returns a text help for the given command');
    }

    public function testExecuteForApplicationCommandWithXmlOption()
    {
        $application = new Application();
        $commandTester = new CommandTester($application->get('help'));
        $commandTester->execute(array('command_name' => 'list', '--format' => 'xml'));
        $this->assertContains('list [--xml] [--raw] [--format FORMAT] [--] [&lt;namespace&gt;]', $commandTester->getDisplay(), '->execute() returns a text help for the given command');
        $this->assertContains('<command', $commandTester->getDisplay(), '->execute() returns an XML help text if --format=xml is passed');
    }
}
PKϤ$Z[�qf)console/Tests/Command/ListCommandTest.phpnu�[���<?php

/*
 * This file is part of the Symfony package.
 *
 * (c) Fabien Potencier <fabien@symfony.com>
 *
 * For the full copyright and license information, please view the LICENSE
 * file that was distributed with this source code.
 */

namespace Symfony\Component\Console\Tests\Command;

use Symfony\Component\Console\Tester\CommandTester;
use Symfony\Component\Console\Application;

class ListCommandTest extends \PHPUnit_Framework_TestCase
{
    public function testExecuteListsCommands()
    {
        $application = new Application();
        $commandTester = new CommandTester($command = $application->get('list'));
        $commandTester->execute(array('command' => $command->getName()), array('decorated' => false));

        $this->assertRegExp('/help\s{2,}Displays help for a command/', $commandTester->getDisplay(), '->execute() returns a list of available commands');
    }

    public function testExecuteListsCommandsWithXmlOption()
    {
        $application = new Application();
        $commandTester = new CommandTester($command = $application->get('list'));
        $commandTester->execute(array('command' => $command->getName(), '--format' => 'xml'));
        $this->assertRegExp('/<command id="list" name="list">/', $commandTester->getDisplay(), '->execute() returns a list of available commands in XML if --xml is passed');
    }

    public function testExecuteListsCommandsWithRawOption()
    {
        $application = new Application();
        $commandTester = new CommandTester($command = $application->get('list'));
        $commandTester->execute(array('command' => $command->getName(), '--raw' => true));
        $output = <<<'EOF'
help   Displays help for a command
list   Lists commands

EOF;

        $this->assertEquals($output, $commandTester->getDisplay(true));
    }

    public function testExecuteListsCommandsWithNamespaceArgument()
    {
        require_once realpath(__DIR__.'/../Fixtures/FooCommand.php');
        $application = new Application();
        $application->add(new \FooCommand());
        $commandTester = new CommandTester($command = $application->get('list'));
        $commandTester->execute(array('command' => $command->getName(), 'namespace' => 'foo', '--raw' => true));
        $output = <<<'EOF'
foo:bar   The foo:bar command

EOF;

        $this->assertEquals($output, $commandTester->getDisplay(true));
    }

    public function testExecuteListsCommandsOrder()
    {
        require_once realpath(__DIR__.'/../Fixtures/Foo6Command.php');
        $application = new Application();
        $application->add(new \Foo6Command());
        $commandTester = new CommandTester($command = $application->get('list'));
        $commandTester->execute(array('command' => $command->getName()), array('decorated' => false));
        $output = <<<'EOF'
Console Tool

Usage:
  command [options] [arguments]

Options:
  -h, --help            Display this help message
  -q, --quiet           Do not output any message
  -V, --version         Display this application version
      --ansi            Force ANSI output
      --no-ansi         Disable ANSI output
  -n, --no-interaction  Do not ask any interactive question
  -v|vv|vvv, --verbose  Increase the verbosity of messages: 1 for normal output, 2 for more verbose output and 3 for debug

Available commands:
  help      Displays help for a command
  list      Lists commands
 0foo
  0foo:bar  0foo:bar command
EOF;

        $this->assertEquals($output, trim($commandTester->getDisplay(true)));
    }

    public function testExecuteListsCommandsOrderRaw()
    {
        require_once realpath(__DIR__.'/../Fixtures/Foo6Command.php');
        $application = new Application();
        $application->add(new \Foo6Command());
        $commandTester = new CommandTester($command = $application->get('list'));
        $commandTester->execute(array('command' => $command->getName(), '--raw' => true));
        $output = <<<'EOF'
help       Displays help for a command
list       Lists commands
0foo:bar   0foo:bar command
EOF;

        $this->assertEquals($output, trim($commandTester->getDisplay(true)));
    }
}
PKϤ$Z�
�5�@�@%console/Tests/Command/CommandTest.phpnu�[���<?php

/*
 * This file is part of the Symfony package.
 *
 * (c) Fabien Potencier <fabien@symfony.com>
 *
 * For the full copyright and license information, please view the LICENSE
 * file that was distributed with this source code.
 */

namespace Symfony\Component\Console\Tests\Command;

use Symfony\Component\Console\Command\Command;
use Symfony\Component\Console\Helper\FormatterHelper;
use Symfony\Component\Console\Application;
use Symfony\Component\Console\Input\InputDefinition;
use Symfony\Component\Console\Input\InputArgument;
use Symfony\Component\Console\Input\InputOption;
use Symfony\Component\Console\Input\InputInterface;
use Symfony\Component\Console\Input\StringInput;
use Symfony\Component\Console\Output\OutputInterface;
use Symfony\Component\Console\Output\NullOutput;
use Symfony\Component\Console\Tester\CommandTester;

class CommandTest extends \PHPUnit_Framework_TestCase
{
    protected static $fixturesPath;

    public static function setUpBeforeClass()
    {
        self::$fixturesPath = __DIR__.'/../Fixtures/';
        require_once self::$fixturesPath.'/TestCommand.php';
    }

    public function testConstructor()
    {
        $command = new Command('foo:bar');
        $this->assertEquals('foo:bar', $command->getName(), '__construct() takes the command name as its first argument');
    }

    /**
     * @expectedException        \LogicException
     * @expectedExceptionMessage The command defined in "Symfony\Component\Console\Command\Command" cannot have an empty name.
     */
    public function testCommandNameCannotBeEmpty()
    {
        new Command();
    }

    public function testSetApplication()
    {
        $application = new Application();
        $command = new \TestCommand();
        $command->setApplication($application);
        $this->assertEquals($application, $command->getApplication(), '->setApplication() sets the current application');
    }

    public function testSetGetDefinition()
    {
        $command = new \TestCommand();
        $ret = $command->setDefinition($definition = new InputDefinition());
        $this->assertEquals($command, $ret, '->setDefinition() implements a fluent interface');
        $this->assertEquals($definition, $command->getDefinition(), '->setDefinition() sets the current InputDefinition instance');
        $command->setDefinition(array(new InputArgument('foo'), new InputOption('bar')));
        $this->assertTrue($command->getDefinition()->hasArgument('foo'), '->setDefinition() also takes an array of InputArguments and InputOptions as an argument');
        $this->assertTrue($command->getDefinition()->hasOption('bar'), '->setDefinition() also takes an array of InputArguments and InputOptions as an argument');
        $command->setDefinition(new InputDefinition());
    }

    public function testAddArgument()
    {
        $command = new \TestCommand();
        $ret = $command->addArgument('foo');
        $this->assertEquals($command, $ret, '->addArgument() implements a fluent interface');
        $this->assertTrue($command->getDefinition()->hasArgument('foo'), '->addArgument() adds an argument to the command');
    }

    public function testAddOption()
    {
        $command = new \TestCommand();
        $ret = $command->addOption('foo');
        $this->assertEquals($command, $ret, '->addOption() implements a fluent interface');
        $this->assertTrue($command->getDefinition()->hasOption('foo'), '->addOption() adds an option to the command');
    }

    public function testGetNamespaceGetNameSetName()
    {
        $command = new \TestCommand();
        $this->assertEquals('namespace:name', $command->getName(), '->getName() returns the command name');
        $command->setName('foo');
        $this->assertEquals('foo', $command->getName(), '->setName() sets the command name');

        $ret = $command->setName('foobar:bar');
        $this->assertEquals($command, $ret, '->setName() implements a fluent interface');
        $this->assertEquals('foobar:bar', $command->getName(), '->setName() sets the command name');
    }

    /**
     * @dataProvider provideInvalidCommandNames
     */
    public function testInvalidCommandNames($name)
    {
        $this->setExpectedException('InvalidArgumentException', sprintf('Command name "%s" is invalid.', $name));

        $command = new \TestCommand();
        $command->setName($name);
    }

    public function provideInvalidCommandNames()
    {
        return array(
            array(''),
            array('foo:'),
        );
    }

    public function testGetSetDescription()
    {
        $command = new \TestCommand();
        $this->assertEquals('description', $command->getDescription(), '->getDescription() returns the description');
        $ret = $command->setDescription('description1');
        $this->assertEquals($command, $ret, '->setDescription() implements a fluent interface');
        $this->assertEquals('description1', $command->getDescription(), '->setDescription() sets the description');
    }

    public function testGetSetHelp()
    {
        $command = new \TestCommand();
        $this->assertEquals('help', $command->getHelp(), '->getHelp() returns the help');
        $ret = $command->setHelp('help1');
        $this->assertEquals($command, $ret, '->setHelp() implements a fluent interface');
        $this->assertEquals('help1', $command->getHelp(), '->setHelp() sets the help');
        $command->setHelp('');
        $this->assertEquals('', $command->getHelp(), '->getHelp() does not fall back to the description');
    }

    public function testGetProcessedHelp()
    {
        $command = new \TestCommand();
        $command->setHelp('The %command.name% command does... Example: php %command.full_name%.');
        $this->assertContains('The namespace:name command does...', $command->getProcessedHelp(), '->getProcessedHelp() replaces %command.name% correctly');
        $this->assertNotContains('%command.full_name%', $command->getProcessedHelp(), '->getProcessedHelp() replaces %command.full_name%');

        $command = new \TestCommand();
        $command->setHelp('');
        $this->assertContains('description', $command->getProcessedHelp(), '->getProcessedHelp() falls back to the description');
    }

    public function testGetSetAliases()
    {
        $command = new \TestCommand();
        $this->assertEquals(array('name'), $command->getAliases(), '->getAliases() returns the aliases');
        $ret = $command->setAliases(array('name1'));
        $this->assertEquals($command, $ret, '->setAliases() implements a fluent interface');
        $this->assertEquals(array('name1'), $command->getAliases(), '->setAliases() sets the aliases');
    }

    public function testGetSynopsis()
    {
        $command = new \TestCommand();
        $command->addOption('foo');
        $command->addArgument('bar');
        $this->assertEquals('namespace:name [--foo] [--] [<bar>]', $command->getSynopsis(), '->getSynopsis() returns the synopsis');
    }

    public function testGetHelper()
    {
        $application = new Application();
        $command = new \TestCommand();
        $command->setApplication($application);
        $formatterHelper = new FormatterHelper();
        $this->assertEquals($formatterHelper->getName(), $command->getHelper('formatter')->getName(), '->getHelper() returns the correct helper');
    }

    /**
     * @expectedException        \LogicException
     * @expectedExceptionMessage Cannot retrieve helper "formatter" because there is no HelperSet defined.
     */
    public function testGetHelperWithoutHelperSet()
    {
        $command = new \TestCommand();
        $command->getHelper('formatter');
    }

    public function testMergeApplicationDefinition()
    {
        $application1 = new Application();
        $application1->getDefinition()->addArguments(array(new InputArgument('foo')));
        $application1->getDefinition()->addOptions(array(new InputOption('bar')));
        $command = new \TestCommand();
        $command->setApplication($application1);
        $command->setDefinition($definition = new InputDefinition(array(new InputArgument('bar'), new InputOption('foo'))));

        $r = new \ReflectionObject($command);
        $m = $r->getMethod('mergeApplicationDefinition');
        $m->setAccessible(true);
        $m->invoke($command);
        $this->assertTrue($command->getDefinition()->hasArgument('foo'), '->mergeApplicationDefinition() merges the application arguments and the command arguments');
        $this->assertTrue($command->getDefinition()->hasArgument('bar'), '->mergeApplicationDefinition() merges the application arguments and the command arguments');
        $this->assertTrue($command->getDefinition()->hasOption('foo'), '->mergeApplicationDefinition() merges the application options and the command options');
        $this->assertTrue($command->getDefinition()->hasOption('bar'), '->mergeApplicationDefinition() merges the application options and the command options');

        $m->invoke($command);
        $this->assertEquals(3, $command->getDefinition()->getArgumentCount(), '->mergeApplicationDefinition() does not try to merge twice the application arguments and options');
    }

    public function testMergeApplicationDefinitionWithoutArgsThenWithArgsAddsArgs()
    {
        $application1 = new Application();
        $application1->getDefinition()->addArguments(array(new InputArgument('foo')));
        $application1->getDefinition()->addOptions(array(new InputOption('bar')));
        $command = new \TestCommand();
        $command->setApplication($application1);
        $command->setDefinition($definition = new InputDefinition(array()));

        $r = new \ReflectionObject($command);
        $m = $r->getMethod('mergeApplicationDefinition');
        $m->setAccessible(true);
        $m->invoke($command, false);
        $this->assertTrue($command->getDefinition()->hasOption('bar'), '->mergeApplicationDefinition(false) merges the application and the command options');
        $this->assertFalse($command->getDefinition()->hasArgument('foo'), '->mergeApplicationDefinition(false) does not merge the application arguments');

        $m->invoke($command, true);
        $this->assertTrue($command->getDefinition()->hasArgument('foo'), '->mergeApplicationDefinition(true) merges the application arguments and the command arguments');

        $m->invoke($command);
        $this->assertEquals(2, $command->getDefinition()->getArgumentCount(), '->mergeApplicationDefinition() does not try to merge twice the application arguments');
    }

    public function testRunInteractive()
    {
        $tester = new CommandTester(new \TestCommand());

        $tester->execute(array(), array('interactive' => true));

        $this->assertEquals('interact called'.PHP_EOL.'execute called'.PHP_EOL, $tester->getDisplay(), '->run() calls the interact() method if the input is interactive');
    }

    public function testRunNonInteractive()
    {
        $tester = new CommandTester(new \TestCommand());

        $tester->execute(array(), array('interactive' => false));

        $this->assertEquals('execute called'.PHP_EOL, $tester->getDisplay(), '->run() does not call the interact() method if the input is not interactive');
    }

    /**
     * @expectedException        \LogicException
     * @expectedExceptionMessage You must override the execute() method in the concrete command class.
     */
    public function testExecuteMethodNeedsToBeOverridden()
    {
        $command = new Command('foo');
        $command->run(new StringInput(''), new NullOutput());
    }

    /**
     * @expectedException        Symfony\Component\Console\Exception\InvalidOptionException
     * @expectedExceptionMessage The "--bar" option does not exist.
     */
    public function testRunWithInvalidOption()
    {
        $command = new \TestCommand();
        $tester = new CommandTester($command);
        $tester->execute(array('--bar' => true));
    }

    public function testRunReturnsIntegerExitCode()
    {
        $command = new \TestCommand();
        $exitCode = $command->run(new StringInput(''), new NullOutput());
        $this->assertSame(0, $exitCode, '->run() returns integer exit code (treats null as 0)');

        $command = $this->getMock('TestCommand', array('execute'));
        $command->expects($this->once())
             ->method('execute')
             ->will($this->returnValue('2.3'));
        $exitCode = $command->run(new StringInput(''), new NullOutput());
        $this->assertSame(2, $exitCode, '->run() returns integer exit code (casts numeric to int)');
    }

    public function testRunWithApplication()
    {
        $command = new \TestCommand();
        $command->setApplication(new Application());
        $exitCode = $command->run(new StringInput(''), new NullOutput());

        $this->assertSame(0, $exitCode, '->run() returns an integer exit code');
    }

    public function testRunReturnsAlwaysInteger()
    {
        $command = new \TestCommand();

        $this->assertSame(0, $command->run(new StringInput(''), new NullOutput()));
    }

    public function testSetCode()
    {
        $command = new \TestCommand();
        $ret = $command->setCode(function (InputInterface $input, OutputInterface $output) {
            $output->writeln('from the code...');
        });
        $this->assertEquals($command, $ret, '->setCode() implements a fluent interface');
        $tester = new CommandTester($command);
        $tester->execute(array());
        $this->assertEquals('interact called'.PHP_EOL.'from the code...'.PHP_EOL, $tester->getDisplay());
    }

    public function getSetCodeBindToClosureTests()
    {
        return array(
            array(true, 'not bound to the command'),
            array(false, 'bound to the command'),
        );
    }

    /**
     * @dataProvider getSetCodeBindToClosureTests
     * @requires PHP 5.4
     */
    public function testSetCodeBindToClosure($previouslyBound, $expected)
    {
        $code = createClosure();
        if ($previouslyBound) {
            $code = $code->bindTo($this);
        }

        $command = new \TestCommand();
        $command->setCode($code);
        $tester = new CommandTester($command);
        $tester->execute(array());
        $this->assertEquals('interact called'.PHP_EOL.$expected.PHP_EOL, $tester->getDisplay());
    }

    public function testSetCodeWithNonClosureCallable()
    {
        $command = new \TestCommand();
        $ret = $command->setCode(array($this, 'callableMethodCommand'));
        $this->assertEquals($command, $ret, '->setCode() implements a fluent interface');
        $tester = new CommandTester($command);
        $tester->execute(array());
        $this->assertEquals('interact called'.PHP_EOL.'from the code...'.PHP_EOL, $tester->getDisplay());
    }

    /**
     * @expectedException        \InvalidArgumentException
     * @expectedExceptionMessage Invalid callable provided to Command::setCode.
     */
    public function testSetCodeWithNonCallable()
    {
        $command = new \TestCommand();
        $command->setCode(array($this, 'nonExistentMethod'));
    }

    public function callableMethodCommand(InputInterface $input, OutputInterface $output)
    {
        $output->writeln('from the code...');
    }

    /**
     * @group legacy
     */
    public function testLegacyAsText()
    {
        $command = new \TestCommand();
        $command->setApplication(new Application());
        $tester = new CommandTester($command);
        $tester->execute(array('command' => $command->getName()));
        $this->assertStringEqualsFile(self::$fixturesPath.'/command_astext.txt', $command->asText(), '->asText() returns a text representation of the command');
    }

    /**
     * @group legacy
     */
    public function testLegacyAsXml()
    {
        $command = new \TestCommand();
        $command->setApplication(new Application());
        $tester = new CommandTester($command);
        $tester->execute(array('command' => $command->getName()));
        $this->assertXmlStringEqualsXmlFile(self::$fixturesPath.'/command_asxml.txt', $command->asXml(), '->asXml() returns an XML representation of the command');
    }
}

// In order to get an unbound closure, we should create it outside a class
// scope.
function createClosure()
{
    return function (InputInterface $input, OutputInterface $output) {
        $output->writeln($this instanceof Command ? 'bound to the command' : 'not bound to the command');
    };
}
PKϤ$Z��[���,console/Tests/Fixtures/input_definition_2.mdnu�[���### Arguments:

**argument_name:**

* Name: argument_name
* Is required: yes
* Is array: no
* Description: <none>
* Default: `NULL`
PKϤ$Z��I��*console/Tests/Fixtures/input_option_3.jsonnu�[���{"name":"--option_name","shortcut":"-o","accept_value":true,"is_value_required":true,"is_multiple":false,"description":"option description","default":null}
PKϤ$Z a���*console/Tests/Fixtures/input_option_4.jsonnu�[���{"name":"--option_name","shortcut":"-o","accept_value":true,"is_value_required":false,"is_multiple":true,"description":"option description","default":[]}
PKϤ$Z6cp��%console/Tests/Fixtures/command_1.jsonnu�[���{"name":"descriptor:command1","usage":["descriptor:command1", "alias1", "alias2"],"description":"command 1 description","help":"command 1 help","definition":{"arguments":[],"options":[]}}
PKϤ$ZD
0@��)console/Tests/Fixtures/command_astext.txtnu�[���<comment>Usage:</comment>
  namespace:name
  name

<comment>Arguments:</comment>
  <info>command</info>               The command to execute

<comment>Options:</comment>
  <info>-h, --help</info>            Display this help message
  <info>-q, --quiet</info>           Do not output any message
  <info>-V, --version</info>         Display this application version
  <info>    --ansi</info>            Force ANSI output
  <info>    --no-ansi</info>         Disable ANSI output
  <info>-n, --no-interaction</info>  Do not ask any interactive question
  <info>-v|vv|vvv, --verbose</info>  Increase the verbosity of messages: 1 for normal output, 2 for more verbose output and 3 for debug

<comment>Help:</comment>
 help
PKϤ$Z;�e^DD#console/Tests/Fixtures/command_2.mdnu�[���descriptor:command2
-------------------

* Description: command 2 description
* Usage:

  * `descriptor:command2 [-o|--option_name] [--] <argument_name>`
  * `descriptor:command2 -o|--option_name <argument_name>`
  * `descriptor:command2 <argument_name>`

command 2 help

### Arguments:

**argument_name:**

* Name: argument_name
* Is required: yes
* Is array: no
* Description: <none>
* Default: `NULL`

### Options:

**option_name:**

* Name: `--option_name`
* Shortcut: `-o`
* Accept value: no
* Is value required: no
* Is multiple: no
* Description: <none>
* Default: `false`
PKϤ$Z�e�d��&console/Tests/Fixtures/Foo4Command.phpnu�[���<?php

use Symfony\Component\Console\Command\Command;

class Foo4Command extends Command
{
    protected function configure()
    {
        $this->setName('foo3:bar:toh');
    }
}
PKϤ$Z��tt*console/Tests/Fixtures/input_argument_1.mdnu�[���**argument_name:**

* Name: argument_name
* Is required: yes
* Is array: no
* Description: <none>
* Default: `NULL`
PKϤ$Z�|�MCC(console/Tests/Fixtures/application_2.txtnu�[���<info>My Symfony application</info> version <comment>v1.0</comment>

<comment>Usage:</comment>
  command [options] [arguments]

<comment>Options:</comment>
  <info>-h, --help</info>            Display this help message
  <info>-q, --quiet</info>           Do not output any message
  <info>-V, --version</info>         Display this application version
  <info>    --ansi</info>            Force ANSI output
  <info>    --no-ansi</info>         Disable ANSI output
  <info>-n, --no-interaction</info>  Do not ask any interactive question
  <info>-v|vv|vvv, --verbose</info>  Increase the verbosity of messages: 1 for normal output, 2 for more verbose output and 3 for debug

<comment>Available commands:</comment>
  <info>alias1</info>               command 1 description
  <info>alias2</info>               command 1 description
  <info>help</info>                 Displays help for a command
  <info>list</info>                 Lists commands
 <comment>descriptor</comment>
  <info>descriptor:command1</info>  command 1 description
  <info>descriptor:command2</info>  command 2 description
PKϤ$Z��c��(console/Tests/Fixtures/input_option_3.mdnu�[���**option_name:**

* Name: `--option_name`
* Shortcut: `-o`
* Accept value: yes
* Is value required: yes
* Is multiple: no
* Description: option description
* Default: `NULL`
PKϤ$Z�v�--+console/Tests/Fixtures/application_run2.txtnu�[���Usage:
  help [options] [--] [<command_name>]

Arguments:
  command               The command to execute
  command_name          The command name [default: "help"]

Options:
      --xml             To output help as XML
      --format=FORMAT   The output format (txt, xml, json, or md) [default: "txt"]
      --raw             To output raw command help
  -h, --help            Display this help message
  -q, --quiet           Do not output any message
  -V, --version         Display this application version
      --ansi            Force ANSI output
      --no-ansi         Disable ANSI output
  -n, --no-interaction  Do not ask any interactive question
  -v|vv|vvv, --verbose  Increase the verbosity of messages: 1 for normal output, 2 for more verbose output and 3 for debug

Help:
 The help command displays help for a given command:
 
   php app/console help list
 
 You can also output the help in other formats by using the --format option:
 
   php app/console help --format=xml list
 
 To display the list of available commands, please use the list command.
PKϤ$Z���0AA7console/Tests/Fixtures/application_renderexception2.txtnu�[���
                                                                
  [Symfony\Component\Console\Exception\InvalidOptionException]  
  The "--foo" option does not exist.                            
                                                                

list [--xml] [--raw] [--format FORMAT] [--] [<namespace>]

PKϤ$Z�hqq)console/Tests/Fixtures/input_option_2.txtnu�[���  <info>-o, --option_name[=OPTION_NAME]</info>  option description<comment> [default: "default_value"]</comment>
PKϤ$Z*�q��.console/Tests/Fixtures/input_definition_3.jsonnu�[���{"arguments":[],"options":{"option_name":{"name":"--option_name","shortcut":"-o","accept_value":false,"is_value_required":false,"is_multiple":false,"description":"","default":false}}}
PKϤ$Z3�P���-console/Tests/Fixtures/input_definition_2.xmlnu�[���<?xml version="1.0" encoding="UTF-8"?>
<definition>
  <arguments>
    <argument name="argument_name" is_required="1" is_array="0">
      <description></description>
      <defaults/>
    </argument>
  </arguments>
  <options/>
</definition>
PKϤ$Z�n<m;;-console/Tests/Fixtures/input_definition_2.txtnu�[���<comment>Arguments:</comment>
  <info>argument_name</info>
PKϤ$Z���33+console/Tests/Fixtures/input_argument_2.txtnu�[���  <info>argument_name</info>  argument description
PKϤ$Z[�p��&console/Tests/Fixtures/Foo6Command.phpnu�[���<?php


use Symfony\Component\Console\Command\Command;

class Foo6Command extends Command
{
    protected function configure()
    {
        $this->setName('0foo:bar')->setDescription('0foo:bar command');
    }
}
PKϤ$Z�R�;;)console/Tests/Fixtures/application_2.jsonnu�[���{"commands":[{"name":"help","usage":["help [--xml] [--format FORMAT] [--raw] [--] [<command_name>]"],"description":"Displays help for a command","help":"The <info>help<\/info> command displays help for a given command:\n\n  <info>php app\/console help list<\/info>\n\nYou can also output the help in other formats by using the <comment>--format<\/comment> option:\n\n  <info>php app\/console help --format=xml list<\/info>\n\nTo display the list of available commands, please use the <info>list<\/info> command.","definition":{"arguments":{"command_name":{"name":"command_name","is_required":false,"is_array":false,"description":"The command name","default":"help"}},"options":{"xml":{"name":"--xml","shortcut":"","accept_value":false,"is_value_required":false,"is_multiple":false,"description":"To output help as XML","default":false},"format":{"name":"--format","shortcut":"","accept_value":true,"is_value_required":true,"is_multiple":false,"description":"The output format (txt, xml, json, or md)","default":"txt"},"raw":{"name":"--raw","shortcut":"","accept_value":false,"is_value_required":false,"is_multiple":false,"description":"To output raw command help","default":false},"help":{"name":"--help","shortcut":"-h","accept_value":false,"is_value_required":false,"is_multiple":false,"description":"Display this help message","default":false},"quiet":{"name":"--quiet","shortcut":"-q","accept_value":false,"is_value_required":false,"is_multiple":false,"description":"Do not output any message","default":false},"verbose":{"name":"--verbose","shortcut":"-v|-vv|-vvv","accept_value":false,"is_value_required":false,"is_multiple":false,"description":"Increase the verbosity of messages: 1 for normal output, 2 for more verbose output and 3 for debug","default":false},"version":{"name":"--version","shortcut":"-V","accept_value":false,"is_value_required":false,"is_multiple":false,"description":"Display this application version","default":false},"ansi":{"name":"--ansi","shortcut":"","accept_value":false,"is_value_required":false,"is_multiple":false,"description":"Force ANSI output","default":false},"no-ansi":{"name":"--no-ansi","shortcut":"","accept_value":false,"is_value_required":false,"is_multiple":false,"description":"Disable ANSI output","default":false},"no-interaction":{"name":"--no-interaction","shortcut":"-n","accept_value":false,"is_value_required":false,"is_multiple":false,"description":"Do not ask any interactive question","default":false}}}},{"name":"list","usage":["list [--xml] [--raw] [--format FORMAT] [--] [<namespace>]"],"description":"Lists commands","help":"The <info>list<\/info> command lists all commands:\n\n  <info>php app\/console list<\/info>\n\nYou can also display the commands for a specific namespace:\n\n  <info>php app\/console list test<\/info>\n\nYou can also output the information in other formats by using the <comment>--format<\/comment> option:\n\n  <info>php app\/console list --format=xml<\/info>\n\nIt's also possible to get raw list of commands (useful for embedding command runner):\n\n  <info>php app\/console list --raw<\/info>","definition":{"arguments":{"namespace":{"name":"namespace","is_required":false,"is_array":false,"description":"The namespace name","default":null}},"options":{"xml":{"name":"--xml","shortcut":"","accept_value":false,"is_value_required":false,"is_multiple":false,"description":"To output list as XML","default":false},"raw":{"name":"--raw","shortcut":"","accept_value":false,"is_value_required":false,"is_multiple":false,"description":"To output raw command list","default":false},"format":{"name":"--format","shortcut":"","accept_value":true,"is_value_required":true,"is_multiple":false,"description":"The output format (txt, xml, json, or md)","default":"txt"}}}},{"name":"descriptor:command1","usage":["descriptor:command1", "alias1", "alias2"],"description":"command 1 description","help":"command 1 help","definition":{"arguments":[],"options":{"help":{"name":"--help","shortcut":"-h","accept_value":false,"is_value_required":false,"is_multiple":false,"description":"Display this help message","default":false},"quiet":{"name":"--quiet","shortcut":"-q","accept_value":false,"is_value_required":false,"is_multiple":false,"description":"Do not output any message","default":false},"verbose":{"name":"--verbose","shortcut":"-v|-vv|-vvv","accept_value":false,"is_value_required":false,"is_multiple":false,"description":"Increase the verbosity of messages: 1 for normal output, 2 for more verbose output and 3 for debug","default":false},"version":{"name":"--version","shortcut":"-V","accept_value":false,"is_value_required":false,"is_multiple":false,"description":"Display this application version","default":false},"ansi":{"name":"--ansi","shortcut":"","accept_value":false,"is_value_required":false,"is_multiple":false,"description":"Force ANSI output","default":false},"no-ansi":{"name":"--no-ansi","shortcut":"","accept_value":false,"is_value_required":false,"is_multiple":false,"description":"Disable ANSI output","default":false},"no-interaction":{"name":"--no-interaction","shortcut":"-n","accept_value":false,"is_value_required":false,"is_multiple":false,"description":"Do not ask any interactive question","default":false}}}},{"name":"descriptor:command2","usage":["descriptor:command2 [-o|--option_name] [--] <argument_name>", "descriptor:command2 -o|--option_name <argument_name>", "descriptor:command2 <argument_name>"],"description":"command 2 description","help":"command 2 help","definition":{"arguments":{"argument_name":{"name":"argument_name","is_required":true,"is_array":false,"description":"","default":null}},"options":{"option_name":{"name":"--option_name","shortcut":"-o","accept_value":false,"is_value_required":false,"is_multiple":false,"description":"","default":false},"help":{"name":"--help","shortcut":"-h","accept_value":false,"is_value_required":false,"is_multiple":false,"description":"Display this help message","default":false},"quiet":{"name":"--quiet","shortcut":"-q","accept_value":false,"is_value_required":false,"is_multiple":false,"description":"Do not output any message","default":false},"verbose":{"name":"--verbose","shortcut":"-v|-vv|-vvv","accept_value":false,"is_value_required":false,"is_multiple":false,"description":"Increase the verbosity of messages: 1 for normal output, 2 for more verbose output and 3 for debug","default":false},"version":{"name":"--version","shortcut":"-V","accept_value":false,"is_value_required":false,"is_multiple":false,"description":"Display this application version","default":false},"ansi":{"name":"--ansi","shortcut":"","accept_value":false,"is_value_required":false,"is_multiple":false,"description":"Force ANSI output","default":false},"no-ansi":{"name":"--no-ansi","shortcut":"","accept_value":false,"is_value_required":false,"is_multiple":false,"description":"Disable ANSI output","default":false},"no-interaction":{"name":"--no-interaction","shortcut":"-n","accept_value":false,"is_value_required":false,"is_multiple":false,"description":"Do not ask any interactive question","default":false}}}}],"namespaces":[{"id":"_global","commands":["alias1","alias2","help","list"]},{"id":"descriptor","commands":["descriptor:command1","descriptor:command2"]}]}PKϤ$Z<|�4UU&console/Tests/Fixtures/Foo1Command.phpnu�[���<?php

use Symfony\Component\Console\Command\Command;
use Symfony\Component\Console\Input\InputInterface;
use Symfony\Component\Console\Output\OutputInterface;

class Foo1Command extends Command
{
    public $input;
    public $output;

    protected function configure()
    {
        $this
            ->setName('foo:bar1')
            ->setDescription('The foo:bar1 command')
            ->setAliases(array('afoobar1'))
        ;
    }

    protected function execute(InputInterface $input, OutputInterface $output)
    {
        $this->input = $input;
        $this->output = $output;
    }
}
PKϤ$Zo��r��+console/Tests/Fixtures/application_run3.txtnu�[���Usage:
  list [options] [--] [<namespace>]

Arguments:
  namespace            The namespace name

Options:
      --xml            To output list as XML
      --raw            To output raw command list
      --format=FORMAT  The output format (txt, xml, json, or md) [default: "txt"]

Help:
 The list command lists all commands:
 
   php app/console list
 
 You can also display the commands for a specific namespace:
 
   php app/console list test
 
 You can also output the information in other formats by using the --format option:
 
   php app/console list --format=xml
 
 It's also possible to get raw list of commands (useful for embedding command runner):
 
   php app/console list --raw
PKϤ$Z%��6XX$console/Tests/Fixtures/command_2.txtnu�[���<comment>Usage:</comment>
  descriptor:command2 [options] [--] <argument_name>
  descriptor:command2 -o|--option_name <argument_name>
  descriptor:command2 <argument_name>

<comment>Arguments:</comment>
  <info>argument_name</info>      

<comment>Options:</comment>
  <info>-o, --option_name</info>  

<comment>Help:</comment>
 command 2 help
PKϤ$Z8�UT

+console/Tests/Fixtures/application_run4.txtnu�[���Console Tool
PKϤ$ZW��،�*console/Tests/Fixtures/input_argument_3.mdnu�[���**argument_name:**

* Name: argument_name
* Is required: no
* Is array: no
* Description: argument description
* Default: `'default_value'`
PKϤ$Z��X��*console/Tests/Fixtures/input_option_1.jsonnu�[���{"name":"--option_name","shortcut":"-o","accept_value":false,"is_value_required":false,"is_multiple":false,"description":"","default":false}
PKϤ$Z�: 8��+console/Tests/Fixtures/input_argument_3.xmlnu�[���<?xml version="1.0" encoding="UTF-8"?>
<argument name="argument_name" is_required="0" is_array="0">
  <description>argument description</description>
  <defaults>
    <default>default_value</default>
  </defaults>
</argument>
PKϤ$Z1"8MM1console/Tests/Fixtures/DescriptorApplication2.phpnu�[���<?php

/*
 * This file is part of the Symfony package.
 *
 * (c) Fabien Potencier <fabien@symfony.com>
 *
 * For the full copyright and license information, please view the LICENSE
 * file that was distributed with this source code.
 */

namespace Symfony\Component\Console\Tests\Fixtures;

use Symfony\Component\Console\Application;

class DescriptorApplication2 extends Application
{
    public function __construct()
    {
        parent::__construct('My Symfony application', 'v1.0');
        $this->add(new DescriptorCommand1());
        $this->add(new DescriptorCommand2());
    }
}
PKϤ$Z8Ǡ7console/Tests/Fixtures/application_renderexception1.txtnu�[���
                                                                  
  [Symfony\Component\Console\Exception\CommandNotFoundException]  
  Command "foo" is not defined.                                   
                                                                  

PKϤ$Z�v��(console/Tests/Fixtures/command_asxml.txtnu�[���<?xml version="1.0" encoding="UTF-8"?>
<command id="namespace:name" name="namespace:name">
  <usages>
    <usage>namespace:name</usage>
    <usage>name</usage>
  </usages>
  <description>description</description>
  <help>help</help>
  <arguments>
    <argument name="command" is_required="1" is_array="0">
      <description>The command to execute</description>
      <defaults/>
    </argument>
  </arguments>
  <options>
    <option name="--help" shortcut="-h" accept_value="0" is_value_required="0" is_multiple="0">
      <description>Display this help message</description>
    </option>
    <option name="--quiet" shortcut="-q" accept_value="0" is_value_required="0" is_multiple="0">
      <description>Do not output any message</description>
    </option>
    <option name="--verbose" shortcut="-v" shortcuts="-v|-vv|-vvv" accept_value="0" is_value_required="0" is_multiple="0">
      <description>Increase the verbosity of messages: 1 for normal output, 2 for more verbose output and 3 for debug</description>
    </option>
    <option name="--version" shortcut="-V" accept_value="0" is_value_required="0" is_multiple="0">
      <description>Display this application version</description>
    </option>
    <option name="--ansi" shortcut="" accept_value="0" is_value_required="0" is_multiple="0">
      <description>Force ANSI output</description>
    </option>
    <option name="--no-ansi" shortcut="" accept_value="0" is_value_required="0" is_multiple="0">
      <description>Disable ANSI output</description>
    </option>
    <option name="--no-interaction" shortcut="-n" accept_value="0" is_value_required="0" is_multiple="0">
      <description>Do not ask any interactive question</description>
    </option>
  </options>
</command>
PKϤ$Z�_�n��+console/Tests/Fixtures/input_argument_1.xmlnu�[���<?xml version="1.0" encoding="UTF-8"?>
<argument name="argument_name" is_required="1" is_array="0">
  <description></description>
  <defaults/>
</argument>
PKϤ$Z�eo�&console/Tests/Fixtures/DummyOutput.phpnu�[���<?php

/*
 * This file is part of the Symfony package.
 *
 * (c) Fabien Potencier <fabien@symfony.com>
 *
 * For the full copyright and license information, please view the LICENSE
 * file that was distributed with this source code.
 */

namespace Symfony\Component\Console\Tests\Fixtures;

use Symfony\Component\Console\Output\BufferedOutput;

/**
 * Dummy output.
 *
 * @author Kévin Dunglas <dunglas@gmail.com>
 */
class DummyOutput extends BufferedOutput
{
    /**
     * @return array
     */
    public function getLogs()
    {
        $logs = array();
        foreach (explode("\n", trim($this->fetch())) as $message) {
            preg_match('/^\[(.*)\] (.*)/', $message, $matches);
            $logs[] = sprintf('%s %s', $matches[1], $matches[2]);
        }

        return $logs;
    }
}
PKϤ$Z�|5!!)console/Tests/Fixtures/input_option_1.txtnu�[���  <info>-o, --option_name</info>
PKϤ$Z۴�2��*console/Tests/Fixtures/input_option_2.jsonnu�[���{"name":"--option_name","shortcut":"-o","accept_value":true,"is_value_required":false,"is_multiple":false,"description":"option description","default":"default_value"}
PKϤ$Z�|��?console/Tests/Fixtures/Style/SymfonyStyle/command/command_4.phpnu�[���<?php

use Symfony\Component\Console\Input\InputInterface;
use Symfony\Component\Console\Output\OutputInterface;
use Symfony\Component\Console\Tests\Style\SymfonyStyleWithForcedLineLength;

//Ensure has single blank line after any text and a title
return function (InputInterface $input, OutputInterface $output) {
    $output = new SymfonyStyleWithForcedLineLength($input, $output);

    $output->write('Lorem ipsum dolor sit amet');
    $output->title('First title');

    $output->writeln('Lorem ipsum dolor sit amet');
    $output->title('Second title');

    $output->write('Lorem ipsum dolor sit amet');
    $output->write('');
    $output->title('Third title');

    //Ensure edge case by appending empty strings to history:
    $output->write('Lorem ipsum dolor sit amet');
    $output->write(array('', '', ''));
    $output->title('Fourth title');

    //Ensure have manual control over number of blank lines:
    $output->writeln('Lorem ipsum dolor sit amet');
    $output->writeln(array('', '')); //Should append an extra blank line
    $output->title('Fifth title');

    $output->writeln('Lorem ipsum dolor sit amet');
    $output->newLine(2); //Should append an extra blank line
    $output->title('Fifth title');
};
PKϤ$Z�z�RR?console/Tests/Fixtures/Style/SymfonyStyle/command/command_6.phpnu�[���<?php

use Symfony\Component\Console\Input\InputInterface;
use Symfony\Component\Console\Output\OutputInterface;
use Symfony\Component\Console\Tests\Style\SymfonyStyleWithForcedLineLength;

//Ensure has proper blank line after text block when using a block like with SymfonyStyle::success
return function (InputInterface $input, OutputInterface $output) {
    $output = new SymfonyStyleWithForcedLineLength($input, $output);

    $output->listing(array(
        'Lorem ipsum dolor sit amet',
        'consectetur adipiscing elit',
    ));
    $output->success('Lorem ipsum dolor sit amet');
};
PKϤ$Z��~O��@console/Tests/Fixtures/Style/SymfonyStyle/command/command_11.phpnu�[���<?php

use Symfony\Component\Console\Input\InputInterface;
use Symfony\Component\Console\Output\OutputInterface;
use Symfony\Component\Console\Tests\Style\SymfonyStyleWithForcedLineLength;

//Ensure that all lines are aligned to the begin of the first one and start with '//' in a very long line comment
return function (InputInterface $input, OutputInterface $output) {
    $output = new SymfonyStyleWithForcedLineLength($input, $output);
    $output->comment(
        'Lorem ipsum dolor sit amet, consectetur adipisicing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum'
    );
};
PKϤ$Z�ժ��?console/Tests/Fixtures/Style/SymfonyStyle/command/command_0.phpnu�[���<?php

use Symfony\Component\Console\Input\InputInterface;
use Symfony\Component\Console\Output\OutputInterface;
use Symfony\Component\Console\Tests\Style\SymfonyStyleWithForcedLineLength;

//Ensure has single blank line at start when using block element
return function (InputInterface $input, OutputInterface $output) {
    $output = new SymfonyStyleWithForcedLineLength($input, $output);
    $output->caution('Lorem ipsum dolor sit amet');
};
PKϤ$Z]�a6aa?console/Tests/Fixtures/Style/SymfonyStyle/command/command_2.phpnu�[���<?php

use Symfony\Component\Console\Input\InputInterface;
use Symfony\Component\Console\Output\OutputInterface;
use Symfony\Component\Console\Tests\Style\SymfonyStyleWithForcedLineLength;

//Ensure has single blank line between blocks
return function (InputInterface $input, OutputInterface $output) {
    $output = new SymfonyStyleWithForcedLineLength($input, $output);
    $output->warning('Warning');
    $output->caution('Caution');
    $output->error('Error');
    $output->success('Success');
    $output->note('Note');
    $output->block('Custom block', 'CUSTOM', 'fg=white;bg=green', 'X ', true);
};
PKϤ$Z�3-���?console/Tests/Fixtures/Style/SymfonyStyle/command/command_1.phpnu�[���<?php

use Symfony\Component\Console\Input\InputInterface;
use Symfony\Component\Console\Output\OutputInterface;
use Symfony\Component\Console\Tests\Style\SymfonyStyleWithForcedLineLength;

//Ensure has single blank line between titles and blocks
return function (InputInterface $input, OutputInterface $output) {
    $output = new SymfonyStyleWithForcedLineLength($input, $output);
    $output->title('Title');
    $output->warning('Lorem ipsum dolor sit amet');
    $output->title('Title');
};
PKϤ$Z������@console/Tests/Fixtures/Style/SymfonyStyle/command/command_10.phpnu�[���<?php

use Symfony\Component\Console\Input\InputInterface;
use Symfony\Component\Console\Output\OutputInterface;
use Symfony\Component\Console\Tests\Style\SymfonyStyleWithForcedLineLength;

//Ensure that all lines are aligned to the begin of the first line in a very long line block
return function (InputInterface $input, OutputInterface $output) {
    $output = new SymfonyStyleWithForcedLineLength($input, $output);
    $output->block(
        'Lorem ipsum dolor sit amet, consectetur adipisicing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum',
        'CUSTOM',
        'fg=white;bg=green',
        'X ',
        true
    );
};
PKϤ$Z�$��?console/Tests/Fixtures/Style/SymfonyStyle/command/command_9.phpnu�[���<?php

use Symfony\Component\Console\Input\InputInterface;
use Symfony\Component\Console\Output\OutputInterface;
use Symfony\Component\Console\Tests\Style\SymfonyStyleWithForcedLineLength;

//Ensure that all lines are aligned to the begin of the first line in a multi-line block
return function (InputInterface $input, OutputInterface $output) {
    $output = new SymfonyStyleWithForcedLineLength($input, $output);
    $output->block(array('Custom block', 'Second custom block line'), 'CUSTOM', 'fg=white;bg=green', 'X ', true);
};
PKϤ$Z_����?console/Tests/Fixtures/Style/SymfonyStyle/command/command_3.phpnu�[���<?php

use Symfony\Component\Console\Input\InputInterface;
use Symfony\Component\Console\Output\OutputInterface;
use Symfony\Component\Console\Tests\Style\SymfonyStyleWithForcedLineLength;

//Ensure has single blank line between two titles
return function (InputInterface $input, OutputInterface $output) {
    $output = new SymfonyStyleWithForcedLineLength($input, $output);
    $output->title('First title');
    $output->title('Second title');
};
PKϤ$ZҜӤpp?console/Tests/Fixtures/Style/SymfonyStyle/command/command_8.phpnu�[���<?php

use Symfony\Component\Console\Input\InputInterface;
use Symfony\Component\Console\Output\OutputInterface;
use Symfony\Component\Console\Tests\Style\SymfonyStyleWithForcedLineLength;
use Symfony\Component\Console\Helper\TableCell;

//Ensure formatting tables when using multiple headers with TableCell
return function (InputInterface $input, OutputInterface $output) {
    $headers = array(
        array(new TableCell('Main table title', array('colspan' => 3))),
        array('ISBN', 'Title', 'Author'),
    );

    $rows = array(
        array(
            '978-0521567817',
            'De Monarchia',
            new TableCell("Dante Alighieri\nspans multiple rows", array('rowspan' => 2)),
        ),
        array('978-0804169127', 'Divine Comedy'),
    );

    $output = new SymfonyStyleWithForcedLineLength($input, $output);
    $output->table($headers, $rows);
};
PKϤ$Z��T��?console/Tests/Fixtures/Style/SymfonyStyle/command/command_7.phpnu�[���<?php

use Symfony\Component\Console\Input\InputInterface;
use Symfony\Component\Console\Output\OutputInterface;
use Symfony\Component\Console\Tests\Style\SymfonyStyleWithForcedLineLength;

//Ensure questions do not output anything when input is non-interactive
return function (InputInterface $input, OutputInterface $output) {
    $output = new SymfonyStyleWithForcedLineLength($input, $output);
    $output->title('Title');
    $output->askHidden('Hidden question');
    $output->choice('Choice question with default', array('choice1', 'choice2'), 'choice1');
    $output->confirm('Confirmation with yes default', true);
    $output->text('Duis aute irure dolor in reprehenderit in voluptate velit esse');
};
PKϤ$Z��m��?console/Tests/Fixtures/Style/SymfonyStyle/command/command_5.phpnu�[���<?php

use Symfony\Component\Console\Input\InputInterface;
use Symfony\Component\Console\Output\OutputInterface;
use Symfony\Component\Console\Tests\Style\SymfonyStyleWithForcedLineLength;

//Ensure has proper line ending before outputing a text block like with SymfonyStyle::listing() or SymfonyStyle::text()
return function (InputInterface $input, OutputInterface $output) {
    $output = new SymfonyStyleWithForcedLineLength($input, $output);

    $output->writeln('Lorem ipsum dolor sit amet');
    $output->listing(array(
        'Lorem ipsum dolor sit amet',
        'consectetur adipiscing elit',
    ));

    //Even using write:
    $output->write('Lorem ipsum dolor sit amet');
    $output->listing(array(
        'Lorem ipsum dolor sit amet',
        'consectetur adipiscing elit',
    ));

    $output->write('Lorem ipsum dolor sit amet');
    $output->text(array(
        'Lorem ipsum dolor sit amet',
        'consectetur adipiscing elit',
    ));

    $output->newLine();

    $output->write('Lorem ipsum dolor sit amet');
    $output->comment(array(
        'Lorem ipsum dolor sit amet',
        'consectetur adipiscing elit',
    ));
};
PKϤ$Z���__>console/Tests/Fixtures/Style/SymfonyStyle/output/output_10.txtnu�[���
X [CUSTOM] Lorem ipsum dolor sit amet, consectetur adipisicing elit, sed do eiusmod tempor incididunt ut labore et      
X          dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea
X          commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat    
X          nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit    
X          anim id est laborum                                                                                          

PKϤ$Zsg�DD=console/Tests/Fixtures/Style/SymfonyStyle/output/output_4.txtnu�[���Lorem ipsum dolor sit amet

First title
===========

Lorem ipsum dolor sit amet

Second title
============

Lorem ipsum dolor sit amet

Third title
===========

Lorem ipsum dolor sit amet

Fourth title
============

Lorem ipsum dolor sit amet


Fifth title
===========

Lorem ipsum dolor sit amet


Fifth title
===========

PKϤ$Z3�*N��=console/Tests/Fixtures/Style/SymfonyStyle/output/output_6.txtnu�[���
 * Lorem ipsum dolor sit amet
 * consectetur adipiscing elit

 [OK] Lorem ipsum dolor sit amet                                                                                        

PKϤ$Z?�*I��=console/Tests/Fixtures/Style/SymfonyStyle/output/output_1.txtnu�[���
Title
=====

 [WARNING] Lorem ipsum dolor sit amet                                                                                   

Title
=====

PKϤ$Z�9����=console/Tests/Fixtures/Style/SymfonyStyle/output/output_8.txtnu�[��� ---------------- --------------- --------------------- 
  Main table title                                      
 ---------------- --------------- --------------------- 
  ISBN             Title           Author               
 ---------------- --------------- --------------------- 
  978-0521567817   De Monarchia    Dante Alighieri      
  978-0804169127   Divine Comedy   spans multiple rows  
 ---------------- --------------- --------------------- 

PKϤ$Z�t
��>console/Tests/Fixtures/Style/SymfonyStyle/output/output_11.txtnu�[���
 // Lorem ipsum dolor sit amet, consectetur adipisicing elit, sed do eiusmod tempor incididunt ut labore et dolore magna
 // aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. 
 // Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur    
 // sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum                 

PKϤ$Z��'555=console/Tests/Fixtures/Style/SymfonyStyle/output/output_3.txtnu�[���
First title
===========

Second title
============

PKϤ$Z� �mm=console/Tests/Fixtures/Style/SymfonyStyle/output/output_9.txtnu�[���
X [CUSTOM] Custom block                                                                                                 
X                                                                                                                       
X          Second custom block line                                                                                     

PKϤ$Z5#%
��=console/Tests/Fixtures/Style/SymfonyStyle/output/output_2.txtnu�[���
 [WARNING] Warning                                                                                                      

 ! [CAUTION] Caution                                                                                                    

 [ERROR] Error                                                                                                          

 [OK] Success                                                                                                           

 ! [NOTE] Note                                                                                                          

X [CUSTOM] Custom block                                                                                                 

PKϤ$Z��DENN=console/Tests/Fixtures/Style/SymfonyStyle/output/output_7.txtnu�[���
Title
=====

 Duis aute irure dolor in reprehenderit in voluptate velit esse
PKϤ$Z�x
��=console/Tests/Fixtures/Style/SymfonyStyle/output/output_5.txtnu�[���Lorem ipsum dolor sit amet
 * Lorem ipsum dolor sit amet
 * consectetur adipiscing elit

Lorem ipsum dolor sit amet
 * Lorem ipsum dolor sit amet
 * consectetur adipiscing elit

Lorem ipsum dolor sit amet
 Lorem ipsum dolor sit amet
 consectetur adipiscing elit

Lorem ipsum dolor sit amet

 // Lorem ipsum dolor sit amet                                                                                          
 //                                                                                                                     
 // consectetur adipiscing elit                                                                                         

PKϤ$Z�':�{{=console/Tests/Fixtures/Style/SymfonyStyle/output/output_0.txtnu�[���
 ! [CAUTION] Lorem ipsum dolor sit amet                                                                                 

PKϤ$ZrA�#jj.console/Tests/Fixtures/application_astext1.txtnu�[���<info>Console Tool</info>

<comment>Usage:</comment>
  command [options] [arguments]

<comment>Options:</comment>
  <info>-h, --help</info>            Display this help message
  <info>-q, --quiet</info>           Do not output any message
  <info>-V, --version</info>         Display this application version
  <info>    --ansi</info>            Force ANSI output
  <info>    --no-ansi</info>         Disable ANSI output
  <info>-n, --no-interaction</info>  Do not ask any interactive question
  <info>-v|vv|vvv, --verbose</info>  Increase the verbosity of messages: 1 for normal output, 2 for more verbose output and 3 for debug

<comment>Available commands:</comment>
  <info>afoobar</info>  The foo:bar command
  <info>help</info>     Displays help for a command
  <info>list</info>     Lists commands
 <comment>foo</comment>
  <info>foo:bar</info>  The foo:bar command
PKϤ$Zt��$$,console/Tests/Fixtures/definition_astext.txtnu�[���<comment>Arguments:</comment>
  <info>foo</info>                The foo argument
  <info>baz</info>                The baz argument<comment> [default: true]</comment>
  <info>bar</info>                The bar argument<comment> [default: ["http://foo.com/"]]</comment>

<comment>Options:</comment>
  <info>-f, --foo=FOO</info>      The foo option
  <info>    --baz[=BAZ]</info>    The baz option<comment> [default: false]</comment>
  <info>-b, --bar[=BAR]</info>    The bar option<comment> [default: "bar"]</comment>
  <info>    --qux[=QUX]</info>    The qux option<comment> [default: ["http://foo.com/","bar"]]</comment><comment> (multiple values allowed)</comment>
  <info>    --qux2[=QUX2]</info>  The qux2 option<comment> [default: {"foo":"bar"}]</comment><comment> (multiple values allowed)</comment>PKϤ$Z�����.console/Tests/Fixtures/input_definition_2.jsonnu�[���{"arguments":{"argument_name":{"name":"argument_name","is_required":true,"is_array":false,"description":"","default":null}},"options":[]}
PKϤ$Z-console/Tests/Fixtures/input_definition_1.txtnu�[���PKϤ$Z��ψ��7console/Tests/Fixtures/application_renderexception3.txtnu�[���
                           
  [Exception]              
  Third exception comment  
                           

                            
  [Exception]               
  Second exception comment  
                            

                                       
  [Exception]                          
  First exception <p>this is html</p>  
                                       

foo3:bar

PKϤ$ZH�VK#K#(console/Tests/Fixtures/application_2.xmlnu�[���<?xml version="1.0" encoding="UTF-8"?>
<symfony name="My Symfony application" version="v1.0">
  <commands>
    <command id="help" name="help">
      <usages>
        <usage>help [--xml] [--format FORMAT] [--raw] [--] [&lt;command_name&gt;]</usage>
      </usages>
      <description>Displays help for a command</description>
      <help>The &lt;info&gt;help&lt;/info&gt; command displays help for a given command:
 
   &lt;info&gt;php app/console help list&lt;/info&gt;
 
 You can also output the help in other formats by using the &lt;comment&gt;--format&lt;/comment&gt; option:
 
   &lt;info&gt;php app/console help --format=xml list&lt;/info&gt;
 
 To display the list of available commands, please use the &lt;info&gt;list&lt;/info&gt; command.</help>
      <arguments>
        <argument name="command_name" is_required="0" is_array="0">
          <description>The command name</description>
          <defaults>
            <default>help</default>
          </defaults>
        </argument>
      </arguments>
      <options>
        <option name="--xml" shortcut="" accept_value="0" is_value_required="0" is_multiple="0">
          <description>To output help as XML</description>
        </option>
        <option name="--format" shortcut="" accept_value="1" is_value_required="1" is_multiple="0">
          <description>The output format (txt, xml, json, or md)</description>
          <defaults>
            <default>txt</default>
          </defaults>
        </option>
        <option name="--raw" shortcut="" accept_value="0" is_value_required="0" is_multiple="0">
          <description>To output raw command help</description>
        </option>
        <option name="--help" shortcut="-h" accept_value="0" is_value_required="0" is_multiple="0">
          <description>Display this help message</description>
        </option>
        <option name="--quiet" shortcut="-q" accept_value="0" is_value_required="0" is_multiple="0">
          <description>Do not output any message</description>
        </option>
        <option name="--verbose" shortcut="-v" shortcuts="-v|-vv|-vvv" accept_value="0" is_value_required="0" is_multiple="0">
          <description>Increase the verbosity of messages: 1 for normal output, 2 for more verbose output and 3 for debug</description>
        </option>
        <option name="--version" shortcut="-V" accept_value="0" is_value_required="0" is_multiple="0">
          <description>Display this application version</description>
        </option>
        <option name="--ansi" shortcut="" accept_value="0" is_value_required="0" is_multiple="0">
          <description>Force ANSI output</description>
        </option>
        <option name="--no-ansi" shortcut="" accept_value="0" is_value_required="0" is_multiple="0">
          <description>Disable ANSI output</description>
        </option>
        <option name="--no-interaction" shortcut="-n" accept_value="0" is_value_required="0" is_multiple="0">
          <description>Do not ask any interactive question</description>
        </option>
      </options>
    </command>
    <command id="list" name="list">
      <usages>
        <usage>list [--xml] [--raw] [--format FORMAT] [--] [&lt;namespace&gt;]</usage>
      </usages>
      <description>Lists commands</description>
      <help>The &lt;info&gt;list&lt;/info&gt; command lists all commands:
 
   &lt;info&gt;php app/console list&lt;/info&gt;
 
 You can also display the commands for a specific namespace:
 
   &lt;info&gt;php app/console list test&lt;/info&gt;
 
 You can also output the information in other formats by using the &lt;comment&gt;--format&lt;/comment&gt; option:
 
   &lt;info&gt;php app/console list --format=xml&lt;/info&gt;
 
 It's also possible to get raw list of commands (useful for embedding command runner):
 
   &lt;info&gt;php app/console list --raw&lt;/info&gt;</help>
      <arguments>
        <argument name="namespace" is_required="0" is_array="0">
          <description>The namespace name</description>
          <defaults/>
        </argument>
      </arguments>
      <options>
        <option name="--xml" shortcut="" accept_value="0" is_value_required="0" is_multiple="0">
          <description>To output list as XML</description>
        </option>
        <option name="--raw" shortcut="" accept_value="0" is_value_required="0" is_multiple="0">
          <description>To output raw command list</description>
        </option>
        <option name="--format" shortcut="" accept_value="1" is_value_required="1" is_multiple="0">
          <description>The output format (txt, xml, json, or md)</description>
          <defaults>
            <default>txt</default>
          </defaults>
        </option>
      </options>
    </command>
    <command id="descriptor:command1" name="descriptor:command1">
      <usages>
        <usage>descriptor:command1</usage>
        <usage>alias1</usage>
        <usage>alias2</usage>
      </usages>
      <description>command 1 description</description>
      <help>command 1 help</help>
      <arguments/>
      <options>
        <option name="--help" shortcut="-h" accept_value="0" is_value_required="0" is_multiple="0">
          <description>Display this help message</description>
        </option>
        <option name="--quiet" shortcut="-q" accept_value="0" is_value_required="0" is_multiple="0">
          <description>Do not output any message</description>
        </option>
        <option name="--verbose" shortcut="-v" shortcuts="-v|-vv|-vvv" accept_value="0" is_value_required="0" is_multiple="0">
          <description>Increase the verbosity of messages: 1 for normal output, 2 for more verbose output and 3 for debug</description>
        </option>
        <option name="--version" shortcut="-V" accept_value="0" is_value_required="0" is_multiple="0">
          <description>Display this application version</description>
        </option>
        <option name="--ansi" shortcut="" accept_value="0" is_value_required="0" is_multiple="0">
          <description>Force ANSI output</description>
        </option>
        <option name="--no-ansi" shortcut="" accept_value="0" is_value_required="0" is_multiple="0">
          <description>Disable ANSI output</description>
        </option>
        <option name="--no-interaction" shortcut="-n" accept_value="0" is_value_required="0" is_multiple="0">
          <description>Do not ask any interactive question</description>
        </option>
      </options>
    </command>
    <command id="descriptor:command2" name="descriptor:command2">
      <usages>
        <usage>descriptor:command2 [-o|--option_name] [--] &lt;argument_name&gt;</usage>
        <usage>descriptor:command2 -o|--option_name &lt;argument_name&gt;</usage>
        <usage>descriptor:command2 &lt;argument_name&gt;</usage>
      </usages>
      <description>command 2 description</description>
      <help>command 2 help</help>
      <arguments>
        <argument name="argument_name" is_required="1" is_array="0">
          <description></description>
          <defaults/>
        </argument>
      </arguments>
      <options>
        <option name="--option_name" shortcut="-o" accept_value="0" is_value_required="0" is_multiple="0">
          <description></description>
        </option>
        <option name="--help" shortcut="-h" accept_value="0" is_value_required="0" is_multiple="0">
          <description>Display this help message</description>
        </option>
        <option name="--quiet" shortcut="-q" accept_value="0" is_value_required="0" is_multiple="0">
          <description>Do not output any message</description>
        </option>
        <option name="--verbose" shortcut="-v" shortcuts="-v|-vv|-vvv" accept_value="0" is_value_required="0" is_multiple="0">
          <description>Increase the verbosity of messages: 1 for normal output, 2 for more verbose output and 3 for debug</description>
        </option>
        <option name="--version" shortcut="-V" accept_value="0" is_value_required="0" is_multiple="0">
          <description>Display this application version</description>
        </option>
        <option name="--ansi" shortcut="" accept_value="0" is_value_required="0" is_multiple="0">
          <description>Force ANSI output</description>
        </option>
        <option name="--no-ansi" shortcut="" accept_value="0" is_value_required="0" is_multiple="0">
          <description>Disable ANSI output</description>
        </option>
        <option name="--no-interaction" shortcut="-n" accept_value="0" is_value_required="0" is_multiple="0">
          <description>Do not ask any interactive question</description>
        </option>
      </options>
    </command>
  </commands>
  <namespaces>
    <namespace id="_global">
      <command>alias1</command>
      <command>alias2</command>
      <command>help</command>
      <command>list</command>
    </namespace>
    <namespace id="descriptor">
      <command>descriptor:command1</command>
      <command>descriptor:command2</command>
    </namespace>
  </namespaces>
</symfony>
PKϤ$Z��϶�Cconsole/Tests/Fixtures/application_renderexception_doublewidth2.txtnu�[���
                              
  [Exception]                 
  コマンドの実行中にエラーが  
  発生しました。              
                              

foo

PKϤ$Zia����+console/Tests/Fixtures/definition_asxml.txtnu�[���<?xml version="1.0" encoding="UTF-8"?>
<definition>
  <arguments>
    <argument name="foo" is_required="0" is_array="0">
      <description>The foo argument</description>
      <defaults/>
    </argument>
    <argument name="baz" is_required="0" is_array="0">
      <description>The baz argument</description>
      <defaults>
        <default>true</default>
      </defaults>
    </argument>
    <argument name="bar" is_required="0" is_array="1">
      <description>The bar argument</description>
      <defaults>
        <default>bar</default>
      </defaults>
    </argument>
  </arguments>
  <options>
    <option name="--foo" shortcut="-f" accept_value="1" is_value_required="1" is_multiple="0">
      <description>The foo option</description>
      <defaults/>
    </option>
    <option name="--baz" shortcut="" accept_value="1" is_value_required="0" is_multiple="0">
      <description>The baz option</description>
      <defaults>
        <default>false</default>
      </defaults>
    </option>
    <option name="--bar" shortcut="-b" accept_value="1" is_value_required="0" is_multiple="0">
      <description>The bar option</description>
      <defaults>
        <default>bar</default>
      </defaults>
    </option>
  </options>
</definition>
PKϤ$Z���(console/Tests/Fixtures/BarBucCommand.phpnu�[���<?php

use Symfony\Component\Console\Command\Command;

class BarBucCommand extends Command
{
    protected function configure()
    {
        $this->setName('bar:buc');
    }
}
PKϤ$Zlc����(console/Tests/Fixtures/application_1.xmlnu�[���<?xml version="1.0" encoding="UTF-8"?>
<symfony>
  <commands>
    <command id="help" name="help">
      <usages>
        <usage>help [--xml] [--format FORMAT] [--raw] [--] [&lt;command_name&gt;]</usage>
      </usages>
      <description>Displays help for a command</description>
      <help>The &lt;info&gt;help&lt;/info&gt; command displays help for a given command:
 
   &lt;info&gt;php app/console help list&lt;/info&gt;
 
 You can also output the help in other formats by using the &lt;comment&gt;--format&lt;/comment&gt; option:
 
   &lt;info&gt;php app/console help --format=xml list&lt;/info&gt;
 
 To display the list of available commands, please use the &lt;info&gt;list&lt;/info&gt; command.</help>
      <arguments>
        <argument name="command_name" is_required="0" is_array="0">
          <description>The command name</description>
          <defaults>
            <default>help</default>
          </defaults>
        </argument>
      </arguments>
      <options>
        <option name="--xml" shortcut="" accept_value="0" is_value_required="0" is_multiple="0">
          <description>To output help as XML</description>
        </option>
        <option name="--format" shortcut="" accept_value="1" is_value_required="1" is_multiple="0">
          <description>The output format (txt, xml, json, or md)</description>
          <defaults>
            <default>txt</default>
          </defaults>
        </option>
        <option name="--raw" shortcut="" accept_value="0" is_value_required="0" is_multiple="0">
          <description>To output raw command help</description>
        </option>
        <option name="--help" shortcut="-h" accept_value="0" is_value_required="0" is_multiple="0">
          <description>Display this help message</description>
        </option>
        <option name="--quiet" shortcut="-q" accept_value="0" is_value_required="0" is_multiple="0">
          <description>Do not output any message</description>
        </option>
        <option name="--verbose" shortcut="-v" shortcuts="-v|-vv|-vvv" accept_value="0" is_value_required="0" is_multiple="0">
          <description>Increase the verbosity of messages: 1 for normal output, 2 for more verbose output and 3 for debug</description>
        </option>
        <option name="--version" shortcut="-V" accept_value="0" is_value_required="0" is_multiple="0">
          <description>Display this application version</description>
        </option>
        <option name="--ansi" shortcut="" accept_value="0" is_value_required="0" is_multiple="0">
          <description>Force ANSI output</description>
        </option>
        <option name="--no-ansi" shortcut="" accept_value="0" is_value_required="0" is_multiple="0">
          <description>Disable ANSI output</description>
        </option>
        <option name="--no-interaction" shortcut="-n" accept_value="0" is_value_required="0" is_multiple="0">
          <description>Do not ask any interactive question</description>
        </option>
      </options>
    </command>
    <command id="list" name="list">
      <usages>
        <usage>list [--xml] [--raw] [--format FORMAT] [--] [&lt;namespace&gt;]</usage>
      </usages>
      <description>Lists commands</description>
      <help>The &lt;info&gt;list&lt;/info&gt; command lists all commands:
 
   &lt;info&gt;php app/console list&lt;/info&gt;
 
 You can also display the commands for a specific namespace:
 
   &lt;info&gt;php app/console list test&lt;/info&gt;
 
 You can also output the information in other formats by using the &lt;comment&gt;--format&lt;/comment&gt; option:
 
   &lt;info&gt;php app/console list --format=xml&lt;/info&gt;
 
 It's also possible to get raw list of commands (useful for embedding command runner):
 
   &lt;info&gt;php app/console list --raw&lt;/info&gt;</help>
      <arguments>
        <argument name="namespace" is_required="0" is_array="0">
          <description>The namespace name</description>
          <defaults/>
        </argument>
      </arguments>
      <options>
        <option name="--xml" shortcut="" accept_value="0" is_value_required="0" is_multiple="0">
          <description>To output list as XML</description>
        </option>
        <option name="--raw" shortcut="" accept_value="0" is_value_required="0" is_multiple="0">
          <description>To output raw command list</description>
        </option>
        <option name="--format" shortcut="" accept_value="1" is_value_required="1" is_multiple="0">
          <description>The output format (txt, xml, json, or md)</description>
          <defaults>
            <default>txt</default>
          </defaults>
        </option>
      </options>
    </command>
  </commands>
  <namespaces>
    <namespace id="_global">
      <command>help</command>
      <command>list</command>
    </namespace>
  </namespaces>
</symfony>
PKϤ$Z��y$$'console/Tests/Fixtures/application_2.mdnu�[���My Symfony application
======================

* alias1
* alias2
* help
* list

**descriptor:**

* descriptor:command1
* descriptor:command2

help
----

* Description: Displays help for a command
* Usage:

  * `help [--xml] [--format FORMAT] [--raw] [--] [<command_name>]`

The <info>help</info> command displays help for a given command:

  <info>php app/console help list</info>

You can also output the help in other formats by using the <comment>--format</comment> option:

  <info>php app/console help --format=xml list</info>

To display the list of available commands, please use the <info>list</info> command.

### Arguments:

**command_name:**

* Name: command_name
* Is required: no
* Is array: no
* Description: The command name
* Default: `'help'`

### Options:

**xml:**

* Name: `--xml`
* Shortcut: <none>
* Accept value: no
* Is value required: no
* Is multiple: no
* Description: To output help as XML
* Default: `false`

**format:**

* Name: `--format`
* Shortcut: <none>
* Accept value: yes
* Is value required: yes
* Is multiple: no
* Description: The output format (txt, xml, json, or md)
* Default: `'txt'`

**raw:**

* Name: `--raw`
* Shortcut: <none>
* Accept value: no
* Is value required: no
* Is multiple: no
* Description: To output raw command help
* Default: `false`

**help:**

* Name: `--help`
* Shortcut: `-h`
* Accept value: no
* Is value required: no
* Is multiple: no
* Description: Display this help message
* Default: `false`

**quiet:**

* Name: `--quiet`
* Shortcut: `-q`
* Accept value: no
* Is value required: no
* Is multiple: no
* Description: Do not output any message
* Default: `false`

**verbose:**

* Name: `--verbose`
* Shortcut: `-v|-vv|-vvv`
* Accept value: no
* Is value required: no
* Is multiple: no
* Description: Increase the verbosity of messages: 1 for normal output, 2 for more verbose output and 3 for debug
* Default: `false`

**version:**

* Name: `--version`
* Shortcut: `-V`
* Accept value: no
* Is value required: no
* Is multiple: no
* Description: Display this application version
* Default: `false`

**ansi:**

* Name: `--ansi`
* Shortcut: <none>
* Accept value: no
* Is value required: no
* Is multiple: no
* Description: Force ANSI output
* Default: `false`

**no-ansi:**

* Name: `--no-ansi`
* Shortcut: <none>
* Accept value: no
* Is value required: no
* Is multiple: no
* Description: Disable ANSI output
* Default: `false`

**no-interaction:**

* Name: `--no-interaction`
* Shortcut: `-n`
* Accept value: no
* Is value required: no
* Is multiple: no
* Description: Do not ask any interactive question
* Default: `false`

list
----

* Description: Lists commands
* Usage:

  * `list [--xml] [--raw] [--format FORMAT] [--] [<namespace>]`

The <info>list</info> command lists all commands:

  <info>php app/console list</info>

You can also display the commands for a specific namespace:

  <info>php app/console list test</info>

You can also output the information in other formats by using the <comment>--format</comment> option:

  <info>php app/console list --format=xml</info>

It's also possible to get raw list of commands (useful for embedding command runner):

  <info>php app/console list --raw</info>

### Arguments:

**namespace:**

* Name: namespace
* Is required: no
* Is array: no
* Description: The namespace name
* Default: `NULL`

### Options:

**xml:**

* Name: `--xml`
* Shortcut: <none>
* Accept value: no
* Is value required: no
* Is multiple: no
* Description: To output list as XML
* Default: `false`

**raw:**

* Name: `--raw`
* Shortcut: <none>
* Accept value: no
* Is value required: no
* Is multiple: no
* Description: To output raw command list
* Default: `false`

**format:**

* Name: `--format`
* Shortcut: <none>
* Accept value: yes
* Is value required: yes
* Is multiple: no
* Description: The output format (txt, xml, json, or md)
* Default: `'txt'`

descriptor:command1
-------------------

* Description: command 1 description
* Usage:

  * `descriptor:command1`
  * `alias1`
  * `alias2`

command 1 help

### Options:

**help:**

* Name: `--help`
* Shortcut: `-h`
* Accept value: no
* Is value required: no
* Is multiple: no
* Description: Display this help message
* Default: `false`

**quiet:**

* Name: `--quiet`
* Shortcut: `-q`
* Accept value: no
* Is value required: no
* Is multiple: no
* Description: Do not output any message
* Default: `false`

**verbose:**

* Name: `--verbose`
* Shortcut: `-v|-vv|-vvv`
* Accept value: no
* Is value required: no
* Is multiple: no
* Description: Increase the verbosity of messages: 1 for normal output, 2 for more verbose output and 3 for debug
* Default: `false`

**version:**

* Name: `--version`
* Shortcut: `-V`
* Accept value: no
* Is value required: no
* Is multiple: no
* Description: Display this application version
* Default: `false`

**ansi:**

* Name: `--ansi`
* Shortcut: <none>
* Accept value: no
* Is value required: no
* Is multiple: no
* Description: Force ANSI output
* Default: `false`

**no-ansi:**

* Name: `--no-ansi`
* Shortcut: <none>
* Accept value: no
* Is value required: no
* Is multiple: no
* Description: Disable ANSI output
* Default: `false`

**no-interaction:**

* Name: `--no-interaction`
* Shortcut: `-n`
* Accept value: no
* Is value required: no
* Is multiple: no
* Description: Do not ask any interactive question
* Default: `false`

descriptor:command2
-------------------

* Description: command 2 description
* Usage:

  * `descriptor:command2 [-o|--option_name] [--] <argument_name>`
  * `descriptor:command2 -o|--option_name <argument_name>`
  * `descriptor:command2 <argument_name>`

command 2 help

### Arguments:

**argument_name:**

* Name: argument_name
* Is required: yes
* Is array: no
* Description: <none>
* Default: `NULL`

### Options:

**option_name:**

* Name: `--option_name`
* Shortcut: `-o`
* Accept value: no
* Is value required: no
* Is multiple: no
* Description: <none>
* Default: `false`

**help:**

* Name: `--help`
* Shortcut: `-h`
* Accept value: no
* Is value required: no
* Is multiple: no
* Description: Display this help message
* Default: `false`

**quiet:**

* Name: `--quiet`
* Shortcut: `-q`
* Accept value: no
* Is value required: no
* Is multiple: no
* Description: Do not output any message
* Default: `false`

**verbose:**

* Name: `--verbose`
* Shortcut: `-v|-vv|-vvv`
* Accept value: no
* Is value required: no
* Is multiple: no
* Description: Increase the verbosity of messages: 1 for normal output, 2 for more verbose output and 3 for debug
* Default: `false`

**version:**

* Name: `--version`
* Shortcut: `-V`
* Accept value: no
* Is value required: no
* Is multiple: no
* Description: Display this application version
* Default: `false`

**ansi:**

* Name: `--ansi`
* Shortcut: <none>
* Accept value: no
* Is value required: no
* Is multiple: no
* Description: Force ANSI output
* Default: `false`

**no-ansi:**

* Name: `--no-ansi`
* Shortcut: <none>
* Accept value: no
* Is value required: no
* Is multiple: no
* Description: Disable ANSI output
* Default: `false`

**no-interaction:**

* Name: `--no-interaction`
* Shortcut: `-n`
* Accept value: no
* Is value required: no
* Is multiple: no
* Description: Do not ask any interactive question
* Default: `false`
PKϤ$Z�F:c-console/Tests/Fixtures/input_definition_3.xmlnu�[���<?xml version="1.0" encoding="UTF-8"?>
<definition>
  <arguments/>
  <options>
    <option name="--option_name" shortcut="-o" accept_value="0" is_value_required="0" is_multiple="0">
      <description></description>
    </option>
  </options>
</definition>
PKϤ$Z`jn`ccCconsole/Tests/Fixtures/application_renderexception_doublewidth1.txtnu�[���
                    
  [Exception]       
  エラーメッセージ  
                    

foo

PKϤ$Z,console/Tests/Fixtures/input_definition_1.mdnu�[���PKϤ$Z��l�AA&console/Tests/Fixtures/Foo3Command.phpnu�[���<?php

use Symfony\Component\Console\Command\Command;
use Symfony\Component\Console\Input\InputInterface;
use Symfony\Component\Console\Output\OutputInterface;

class Foo3Command extends Command
{
    protected function configure()
    {
        $this
            ->setName('foo3:bar')
            ->setDescription('The foo3:bar command')
        ;
    }

    protected function execute(InputInterface $input, OutputInterface $output)
    {
        try {
            try {
                throw new \Exception('First exception <p>this is html</p>');
            } catch (\Exception $e) {
                throw new \Exception('Second exception <comment>comment</comment>', 0, $e);
            }
        } catch (\Exception $e) {
            throw new \Exception('Third exception <fg=blue;bg=red>comment</>', 0, $e);
        }
    }
}
PKϤ$Z��G��)console/Tests/Fixtures/input_option_1.xmlnu�[���<?xml version="1.0" encoding="UTF-8"?>
<option name="--option_name" shortcut="-o" accept_value="0" is_value_required="0" is_multiple="0">
  <description></description>
</option>
PKϤ$Zs�,�[[+console/Tests/Fixtures/input_argument_4.txtnu�[���  <info>argument_name</info>  multiline
                              argument description
PKϤ$Z��\��#console/Tests/Fixtures/command_1.mdnu�[���descriptor:command1
-------------------

* Description: command 1 description
* Usage:

  * `descriptor:command1`
  * `alias1`
  * `alias2`

command 1 help
PKϤ$Zi����)console/Tests/Fixtures/input_option_5.xmlnu�[���<?xml version="1.0" encoding="UTF-8"?>
<option name="--option_name" shortcut="-o" accept_value="1" is_value_required="1" is_multiple="0">
  <description>multiline
option description</description>
  <defaults/>
</option>
PKϤ$ZCQu��-console/Tests/Fixtures/input_definition_4.xmlnu�[���<?xml version="1.0" encoding="UTF-8"?>
<definition>
  <arguments>
    <argument name="argument_name" is_required="1" is_array="0">
      <description></description>
      <defaults/>
    </argument>
  </arguments>
  <options>
    <option name="--option_name" shortcut="-o" accept_value="0" is_value_required="0" is_multiple="0">
      <description></description>
    </option>
  </options>
</definition>
PKϤ$Zٙ���'console/Tests/Fixtures/application_1.mdnu�[���UNKNOWN
=======

* help
* list

help
----

* Description: Displays help for a command
* Usage:

  * `help [--xml] [--format FORMAT] [--raw] [--] [<command_name>]`

The <info>help</info> command displays help for a given command:

  <info>php app/console help list</info>

You can also output the help in other formats by using the <comment>--format</comment> option:

  <info>php app/console help --format=xml list</info>

To display the list of available commands, please use the <info>list</info> command.

### Arguments:

**command_name:**

* Name: command_name
* Is required: no
* Is array: no
* Description: The command name
* Default: `'help'`

### Options:

**xml:**

* Name: `--xml`
* Shortcut: <none>
* Accept value: no
* Is value required: no
* Is multiple: no
* Description: To output help as XML
* Default: `false`

**format:**

* Name: `--format`
* Shortcut: <none>
* Accept value: yes
* Is value required: yes
* Is multiple: no
* Description: The output format (txt, xml, json, or md)
* Default: `'txt'`

**raw:**

* Name: `--raw`
* Shortcut: <none>
* Accept value: no
* Is value required: no
* Is multiple: no
* Description: To output raw command help
* Default: `false`

**help:**

* Name: `--help`
* Shortcut: `-h`
* Accept value: no
* Is value required: no
* Is multiple: no
* Description: Display this help message
* Default: `false`

**quiet:**

* Name: `--quiet`
* Shortcut: `-q`
* Accept value: no
* Is value required: no
* Is multiple: no
* Description: Do not output any message
* Default: `false`

**verbose:**

* Name: `--verbose`
* Shortcut: `-v|-vv|-vvv`
* Accept value: no
* Is value required: no
* Is multiple: no
* Description: Increase the verbosity of messages: 1 for normal output, 2 for more verbose output and 3 for debug
* Default: `false`

**version:**

* Name: `--version`
* Shortcut: `-V`
* Accept value: no
* Is value required: no
* Is multiple: no
* Description: Display this application version
* Default: `false`

**ansi:**

* Name: `--ansi`
* Shortcut: <none>
* Accept value: no
* Is value required: no
* Is multiple: no
* Description: Force ANSI output
* Default: `false`

**no-ansi:**

* Name: `--no-ansi`
* Shortcut: <none>
* Accept value: no
* Is value required: no
* Is multiple: no
* Description: Disable ANSI output
* Default: `false`

**no-interaction:**

* Name: `--no-interaction`
* Shortcut: `-n`
* Accept value: no
* Is value required: no
* Is multiple: no
* Description: Do not ask any interactive question
* Default: `false`

list
----

* Description: Lists commands
* Usage:

  * `list [--xml] [--raw] [--format FORMAT] [--] [<namespace>]`

The <info>list</info> command lists all commands:

  <info>php app/console list</info>

You can also display the commands for a specific namespace:

  <info>php app/console list test</info>

You can also output the information in other formats by using the <comment>--format</comment> option:

  <info>php app/console list --format=xml</info>

It's also possible to get raw list of commands (useful for embedding command runner):

  <info>php app/console list --raw</info>

### Arguments:

**namespace:**

* Name: namespace
* Is required: no
* Is array: no
* Description: The namespace name
* Default: `NULL`

### Options:

**xml:**

* Name: `--xml`
* Shortcut: <none>
* Accept value: no
* Is value required: no
* Is multiple: no
* Description: To output list as XML
* Default: `false`

**raw:**

* Name: `--raw`
* Shortcut: <none>
* Accept value: no
* Is value required: no
* Is multiple: no
* Description: To output raw command list
* Default: `false`

**format:**

* Name: `--format`
* Shortcut: <none>
* Accept value: yes
* Is value required: yes
* Is multiple: no
* Description: The output format (txt, xml, json, or md)
* Default: `'txt'`
PKϤ$Z󚲱}},console/Tests/Fixtures/input_argument_3.jsonnu�[���{"name":"argument_name","is_required":false,"is_array":false,"description":"argument description","default":"default_value"}
PKϤ$ZTg�ll$console/Tests/Fixtures/command_1.txtnu�[���<comment>Usage:</comment>
  descriptor:command1
  alias1
  alias2

<comment>Help:</comment>
 command 1 help
PKϤ$Z�ơ��)console/Tests/Fixtures/application_1.jsonnu�[���{"commands":[{"name":"help","usage":["help [--xml] [--format FORMAT] [--raw] [--] [<command_name>]"],"description":"Displays help for a command","help":"The <info>help<\/info> command displays help for a given command:\n\n  <info>php app\/console help list<\/info>\n\nYou can also output the help in other formats by using the <comment>--format<\/comment> option:\n\n  <info>php app\/console help --format=xml list<\/info>\n\nTo display the list of available commands, please use the <info>list<\/info> command.","definition":{"arguments":{"command_name":{"name":"command_name","is_required":false,"is_array":false,"description":"The command name","default":"help"}},"options":{"xml":{"name":"--xml","shortcut":"","accept_value":false,"is_value_required":false,"is_multiple":false,"description":"To output help as XML","default":false},"format":{"name":"--format","shortcut":"","accept_value":true,"is_value_required":true,"is_multiple":false,"description":"The output format (txt, xml, json, or md)","default":"txt"},"raw":{"name":"--raw","shortcut":"","accept_value":false,"is_value_required":false,"is_multiple":false,"description":"To output raw command help","default":false},"help":{"name":"--help","shortcut":"-h","accept_value":false,"is_value_required":false,"is_multiple":false,"description":"Display this help message","default":false},"quiet":{"name":"--quiet","shortcut":"-q","accept_value":false,"is_value_required":false,"is_multiple":false,"description":"Do not output any message","default":false},"verbose":{"name":"--verbose","shortcut":"-v|-vv|-vvv","accept_value":false,"is_value_required":false,"is_multiple":false,"description":"Increase the verbosity of messages: 1 for normal output, 2 for more verbose output and 3 for debug","default":false},"version":{"name":"--version","shortcut":"-V","accept_value":false,"is_value_required":false,"is_multiple":false,"description":"Display this application version","default":false},"ansi":{"name":"--ansi","shortcut":"","accept_value":false,"is_value_required":false,"is_multiple":false,"description":"Force ANSI output","default":false},"no-ansi":{"name":"--no-ansi","shortcut":"","accept_value":false,"is_value_required":false,"is_multiple":false,"description":"Disable ANSI output","default":false},"no-interaction":{"name":"--no-interaction","shortcut":"-n","accept_value":false,"is_value_required":false,"is_multiple":false,"description":"Do not ask any interactive question","default":false}}}},{"name":"list","usage":["list [--xml] [--raw] [--format FORMAT] [--] [<namespace>]"],"description":"Lists commands","help":"The <info>list<\/info> command lists all commands:\n\n  <info>php app\/console list<\/info>\n\nYou can also display the commands for a specific namespace:\n\n  <info>php app\/console list test<\/info>\n\nYou can also output the information in other formats by using the <comment>--format<\/comment> option:\n\n  <info>php app\/console list --format=xml<\/info>\n\nIt's also possible to get raw list of commands (useful for embedding command runner):\n\n  <info>php app\/console list --raw<\/info>","definition":{"arguments":{"namespace":{"name":"namespace","is_required":false,"is_array":false,"description":"The namespace name","default":null}},"options":{"xml":{"name":"--xml","shortcut":"","accept_value":false,"is_value_required":false,"is_multiple":false,"description":"To output list as XML","default":false},"raw":{"name":"--raw","shortcut":"","accept_value":false,"is_value_required":false,"is_multiple":false,"description":"To output raw command list","default":false},"format":{"name":"--format","shortcut":"","accept_value":true,"is_value_required":true,"is_multiple":false,"description":"The output format (txt, xml, json, or md)","default":"txt"}}}}],"namespaces":[{"id":"_global","commands":["help","list"]}]}
PKϤ$Z���oo,console/Tests/Fixtures/input_argument_2.jsonnu�[���{"name":"argument_name","is_required":false,"is_array":true,"description":"argument description","default":[]}
PKϤ$Z*[Ǿ44,console/Tests/Fixtures/input_definition_4.mdnu�[���### Arguments:

**argument_name:**

* Name: argument_name
* Is required: yes
* Is array: no
* Description: <none>
* Default: `NULL`

### Options:

**option_name:**

* Name: `--option_name`
* Shortcut: `-o`
* Accept value: no
* Is value required: no
* Is multiple: no
* Description: <none>
* Default: `false`
PKϤ$ZP����(console/Tests/Fixtures/input_option_4.mdnu�[���**option_name:**

* Name: `--option_name`
* Shortcut: `-o`
* Accept value: yes
* Is value required: no
* Is multiple: yes
* Description: option description
* Default: `array ()`
PKϤ$ZZ���*console/Tests/Fixtures/input_option_6.jsonnu�[���{"name":"--option_name","shortcut":"-o|-O","accept_value":true,"is_value_required":true,"is_multiple":false,"description":"option with multiple shortcuts","default":null}
PKϤ$Z9p��OO$console/Tests/Fixtures/command_1.xmlnu�[���<?xml version="1.0" encoding="UTF-8"?>
<command id="descriptor:command1" name="descriptor:command1">
  <usages>
    <usage>descriptor:command1</usage>
    <usage>alias1</usage>
    <usage>alias2</usage>
  </usages>
  <description>command 1 description</description>
  <help>command 1 help</help>
  <arguments/>
  <options/>
</command>
PKϤ$Z�I���)console/Tests/Fixtures/input_option_4.xmlnu�[���<?xml version="1.0" encoding="UTF-8"?>
<option name="--option_name" shortcut="-o" accept_value="1" is_value_required="0" is_multiple="1">
  <description>option description</description>
  <defaults/>
</option>
PKϤ$Z����.console/Tests/Fixtures/input_definition_1.jsonnu�[���{"arguments":[],"options":[]}
PKϤ$Z`]�AA)console/Tests/Fixtures/input_option_3.txtnu�[���  <info>-o, --option_name=OPTION_NAME</info>  option description
PKϤ$Zp�����,console/Tests/Fixtures/input_definition_3.mdnu�[���### Options:

**option_name:**

* Name: `--option_name`
* Shortcut: `-o`
* Accept value: no
* Is value required: no
* Is multiple: no
* Description: <none>
* Default: `false`
PKϤ$Z�JhMOO)console/Tests/Fixtures/input_option_6.txtnu�[���  <info>-o|O, --option_name=OPTION_NAME</info>  option with multiple shortcuts
PKϤ$Z�J�2)console/Tests/Fixtures/input_option_2.xmlnu�[���<?xml version="1.0" encoding="UTF-8"?>
<option name="--option_name" shortcut="-o" accept_value="1" is_value_required="0" is_multiple="0">
  <description>option description</description>
  <defaults>
    <default>default_value</default>
  </defaults>
</option>
PKϤ$Z1G~"//(console/Tests/Fixtures/FoobarCommand.phpnu�[���<?php

use Symfony\Component\Console\Command\Command;
use Symfony\Component\Console\Input\InputInterface;
use Symfony\Component\Console\Output\OutputInterface;

class FoobarCommand extends Command
{
    public $input;
    public $output;

    protected function configure()
    {
        $this
            ->setName('foobar:foo')
            ->setDescription('The foobar:foo command')
        ;
    }

    protected function execute(InputInterface $input, OutputInterface $output)
    {
        $this->input = $input;
        $this->output = $output;
    }
}
PKϤ$Z̳��99+console/Tests/Fixtures/application_run1.txtnu�[���Console Tool

Usage:
  command [options] [arguments]

Options:
  -h, --help            Display this help message
  -q, --quiet           Do not output any message
  -V, --version         Display this application version
      --ansi            Force ANSI output
      --no-ansi         Disable ANSI output
  -n, --no-interaction  Do not ask any interactive question
  -v|vv|vvv, --verbose  Increase the verbosity of messages: 1 for normal output, 2 for more verbose output and 3 for debug

Available commands:
  help  Displays help for a command
  list  Lists commands
PKϤ$Zz�Ռ��*console/Tests/Fixtures/input_argument_2.mdnu�[���**argument_name:**

* Name: argument_name
* Is required: no
* Is array: yes
* Description: argument description
* Default: `array ()`
PKϤ$Z^ſ�.console/Tests/Fixtures/application_gethelp.txtnu�[���<info>Console Tool</info>PKϤ$Z9�*A��&console/Tests/Fixtures/TestCommand.phpnu�[���<?php

use Symfony\Component\Console\Command\Command;
use Symfony\Component\Console\Input\InputInterface;
use Symfony\Component\Console\Output\OutputInterface;

class TestCommand extends Command
{
    protected function configure()
    {
        $this
            ->setName('namespace:name')
            ->setAliases(array('name'))
            ->setDescription('description')
            ->setHelp('help')
        ;
    }

    protected function execute(InputInterface $input, OutputInterface $output)
    {
        $output->writeln('execute called');
    }

    protected function interact(InputInterface $input, OutputInterface $output)
    {
        $output->writeln('interact called');
    }
}
PKϤ$Z�L���*console/Tests/Fixtures/input_option_5.jsonnu�[���{"name":"--option_name","shortcut":"-o","accept_value":true,"is_value_required":true,"is_multiple":false,"description":"multiline option description","default":null}
PKϤ$Z�W�yy)console/Tests/Fixtures/input_option_5.txtnu�[���  <info>-o, --option_name=OPTION_NAME</info>  multiline
                                              option description
PKϤ$Z��ڭQQ7console/Tests/Fixtures/application_renderexception4.txtnu�[���
                                                                  
  [Symfony\Component\Console\Exception\CommandNotFoundException]  
  Command "foo" is not define                                     
  d.                                                              
                                                                  

PKϤ$Z�	���&console/Tests/Fixtures/Foo2Command.phpnu�[���<?php

use Symfony\Component\Console\Command\Command;
use Symfony\Component\Console\Input\InputInterface;
use Symfony\Component\Console\Output\OutputInterface;

class Foo2Command extends Command
{
    protected function configure()
    {
        $this
            ->setName('foo1:bar')
            ->setDescription('The foo1:bar command')
            ->setAliases(array('afoobar2'))
        ;
    }

    protected function execute(InputInterface $input, OutputInterface $output)
    {
    }
}
PKϤ$Z	�Ӹ�(console/Tests/Fixtures/input_option_2.mdnu�[���**option_name:**

* Name: `--option_name`
* Shortcut: `-o`
* Accept value: yes
* Is value required: no
* Is multiple: no
* Description: option description
* Default: `'default_value'`
PKϤ$Z��<]],console/Tests/Fixtures/input_argument_1.jsonnu�[���{"name":"argument_name","is_required":true,"is_array":false,"description":"","default":null}
PKϤ$Z��*J��@console/Tests/Fixtures/application_renderexception3decorated.txtnu�[���
                           
  [Exception]              
  Third exception comment  
                           

                            
  [Exception]               
  Second exception comment  
                            

                                       
  [Exception]                          
  First exception <p>this is html</p>  
                                       

foo3:bar

PKϤ$Z��f���+console/Tests/Fixtures/input_argument_2.xmlnu�[���<?xml version="1.0" encoding="UTF-8"?>
<argument name="argument_name" is_required="0" is_array="1">
  <description>argument description</description>
  <defaults/>
</argument>
PKϤ$Z��

$console/Tests/Fixtures/command_2.xmlnu�[���<?xml version="1.0" encoding="UTF-8"?>
<command id="descriptor:command2" name="descriptor:command2">
  <usages>
    <usage>descriptor:command2 [-o|--option_name] [--] &lt;argument_name&gt;</usage>
    <usage>descriptor:command2 -o|--option_name &lt;argument_name&gt;</usage>
    <usage>descriptor:command2 &lt;argument_name&gt;</usage>
  </usages>
  <description>command 2 description</description>
  <help>command 2 help</help>
  <arguments>
    <argument name="argument_name" is_required="1" is_array="0">
      <description></description>
      <defaults/>
    </argument>
  </arguments>
  <options>
    <option name="--option_name" shortcut="-o" accept_value="0" is_value_required="0" is_multiple="0">
      <description></description>
    </option>
  </options>
</command>
PKϤ$Z
�h�==-console/Tests/Fixtures/input_definition_3.txtnu�[���<comment>Options:</comment>
  <info>-o, --option_name</info>
PKϤ$Zǰ@���.console/Tests/Fixtures/application_astext2.txtnu�[���<info>Console Tool</info>

<comment>Usage:</comment>
  command [options] [arguments]

<comment>Options:</comment>
  <info>-h, --help</info>            Display this help message
  <info>-q, --quiet</info>           Do not output any message
  <info>-V, --version</info>         Display this application version
  <info>    --ansi</info>            Force ANSI output
  <info>    --no-ansi</info>         Disable ANSI output
  <info>-n, --no-interaction</info>  Do not ask any interactive question
  <info>-v|vv|vvv, --verbose</info>  Increase the verbosity of messages: 1 for normal output, 2 for more verbose output and 3 for debug

<comment>Available commands for the "foo" namespace:</comment>
  <info>foo:bar</info>  The foo:bar command
PKϤ$Z��8Cii3console/Tests/Fixtures/FooSubnamespaced1Command.phpnu�[���<?php

use Symfony\Component\Console\Command\Command;
use Symfony\Component\Console\Input\InputInterface;
use Symfony\Component\Console\Output\OutputInterface;

class FooSubnamespaced1Command extends Command
{
    public $input;
    public $output;

    protected function configure()
    {
        $this
            ->setName('foo:bar:baz')
            ->setDescription('The foo:bar:baz command')
            ->setAliases(array('foobarbaz'))
        ;
    }

    protected function execute(InputInterface $input, OutputInterface $output)
    {
        $this->input = $input;
        $this->output = $output;
    }
}
PKϤ$Zl᯿pp)console/Tests/Fixtures/input_option_4.txtnu�[���  <info>-o, --option_name[=OPTION_NAME]</info>  option description<comment> (multiple values allowed)</comment>
PKϤ$Z�^t�^^-console/Tests/Fixtures/input_definition_1.xmlnu�[���<?xml version="1.0" encoding="UTF-8"?>
<definition>
  <arguments/>
  <options/>
</definition>
PKϤ$Z�)J��)console/Tests/Fixtures/input_option_6.xmlnu�[���<?xml version="1.0" encoding="UTF-8"?>
<option name="--option_name" shortcut="-o" shortcuts="-o|-O" accept_value="1" is_value_required="1" is_multiple="0">
  <description>option with multiple shortcuts</description>
  <defaults/>
</option>
PKϤ$Z�އ-console/Tests/Fixtures/input_definition_4.txtnu�[���<comment>Arguments:</comment>
  <info>argument_name</info>      

<comment>Options:</comment>
  <info>-o, --option_name</info>
PKϤ$ZEb��aa+console/Tests/Fixtures/input_argument_3.txtnu�[���  <info>argument_name</info>  argument description<comment> [default: "default_value"]</comment>
PKϤ$Z���5+console/Tests/Fixtures/input_argument_1.txtnu�[���  <info>argument_name</info>
PKϤ$Z�%?���(console/Tests/Fixtures/input_option_5.mdnu�[���**option_name:**

* Name: `--option_name`
* Shortcut: `-o`
* Accept value: yes
* Is value required: yes
* Is multiple: no
* Description: multiline
  option description
* Default: `NULL`
PKϤ$Z�
c�%console/Tests/Fixtures/FooCommand.phpnu�[���<?php

use Symfony\Component\Console\Command\Command;
use Symfony\Component\Console\Input\InputInterface;
use Symfony\Component\Console\Output\OutputInterface;

class FooCommand extends Command
{
    public $input;
    public $output;

    protected function configure()
    {
        $this
            ->setName('foo:bar')
            ->setDescription('The foo:bar command')
            ->setAliases(array('afoobar'))
        ;
    }

    protected function interact(InputInterface $input, OutputInterface $output)
    {
        $output->writeln('interact called');
    }

    protected function execute(InputInterface $input, OutputInterface $output)
    {
        $this->input = $input;
        $this->output = $output;

        $output->writeln('called');
    }
}
PKϤ$Z���$$.console/Tests/Fixtures/input_definition_4.jsonnu�[���{"arguments":{"argument_name":{"name":"argument_name","is_required":true,"is_array":false,"description":"","default":null}},"options":{"option_name":{"name":"--option_name","shortcut":"-o","accept_value":false,"is_value_required":false,"is_multiple":false,"description":"","default":false}}}
PKϤ$ZY'�A��-console/Tests/Fixtures/DescriptorCommand1.phpnu�[���<?php

/*
 * This file is part of the Symfony package.
 *
 * (c) Fabien Potencier <fabien@symfony.com>
 *
 * For the full copyright and license information, please view the LICENSE
 * file that was distributed with this source code.
 */

namespace Symfony\Component\Console\Tests\Fixtures;

use Symfony\Component\Console\Command\Command;

class DescriptorCommand1 extends Command
{
    protected function configure()
    {
        $this
            ->setName('descriptor:command1')
            ->setAliases(array('alias1', 'alias2'))
            ->setDescription('command 1 description')
            ->setHelp('command 1 help')
        ;
    }
}
PKϤ$Z�;hc��+console/Tests/Fixtures/input_argument_4.xmlnu�[���<?xml version="1.0" encoding="UTF-8"?>
<argument name="argument_name" is_required="1" is_array="0">
  <description>multiline
argument description</description>
  <defaults/>
</argument>
PKϤ$Z�Zjgg3console/Tests/Fixtures/FooSubnamespaced2Command.phpnu�[���<?php

use Symfony\Component\Console\Command\Command;
use Symfony\Component\Console\Input\InputInterface;
use Symfony\Component\Console\Output\OutputInterface;

class FooSubnamespaced2Command extends Command
{
    public $input;
    public $output;

    protected function configure()
    {
        $this
            ->setName('foo:go:bret')
            ->setDescription('The foo:bar:go command')
            ->setAliases(array('foobargo'))
        ;
    }

    protected function execute(InputInterface $input, OutputInterface $output)
    {
        $this->input = $input;
        $this->output = $output;
    }
}
PKϤ$ZSG�X55%console/Tests/Fixtures/command_2.jsonnu�[���{"name":"descriptor:command2","usage":["descriptor:command2 [-o|--option_name] [--] <argument_name>", "descriptor:command2 -o|--option_name <argument_name>", "descriptor:command2 <argument_name>"],"description":"command 2 description","help":"command 2 help","definition":{"arguments":{"argument_name":{"name":"argument_name","is_required":true,"is_array":false,"description":"","default":null}},"options":{"option_name":{"name":"--option_name","shortcut":"-o","accept_value":false,"is_value_required":false,"is_multiple":false,"description":"","default":false}}}}
PKϤ$Z�3�{{,console/Tests/Fixtures/input_argument_4.jsonnu�[���{"name":"argument_name","is_required":true,"is_array":false,"description":"multiline argument description","default":null}
PKϤ$Z��XX��)console/Tests/Fixtures/input_option_3.xmlnu�[���<?xml version="1.0" encoding="UTF-8"?>
<option name="--option_name" shortcut="-o" accept_value="1" is_value_required="1" is_multiple="0">
  <description>option description</description>
  <defaults/>
</option>
PKϤ$Z^�p���Lconsole/Tests/Fixtures/application_renderexception_doublewidth1decorated.txtnu�[���
                    
  [Exception]       
  エラーメッセージ  
                    

foo

PKϤ$Z#�U��*console/Tests/Fixtures/input_argument_4.mdnu�[���**argument_name:**

* Name: argument_name
* Is required: yes
* Is array: no
* Description: multiline
  argument description
* Default: `NULL`
PKϤ$ZAW�\��-console/Tests/Fixtures/DescriptorCommand2.phpnu�[���<?php

/*
 * This file is part of the Symfony package.
 *
 * (c) Fabien Potencier <fabien@symfony.com>
 *
 * For the full copyright and license information, please view the LICENSE
 * file that was distributed with this source code.
 */

namespace Symfony\Component\Console\Tests\Fixtures;

use Symfony\Component\Console\Command\Command;
use Symfony\Component\Console\Input\InputArgument;
use Symfony\Component\Console\Input\InputOption;

class DescriptorCommand2 extends Command
{
    protected function configure()
    {
        $this
            ->setName('descriptor:command2')
            ->setDescription('command 2 description')
            ->setHelp('command 2 help')
            ->addUsage('-o|--option_name <argument_name>')
            ->addUsage('<argument_name>')
            ->addArgument('argument_name', InputArgument::REQUIRED)
            ->addOption('option_name', 'o', InputOption::VALUE_NONE)
        ;
    }
}
PKϤ$Z�Y-͡�(console/Tests/Fixtures/input_option_1.mdnu�[���**option_name:**

* Name: `--option_name`
* Shortcut: `-o`
* Accept value: no
* Is value required: no
* Is multiple: no
* Description: <none>
* Default: `false`
PKϤ$Z��!��-console/Tests/Fixtures/application_asxml2.txtnu�[���<?xml version="1.0" encoding="UTF-8"?>
<symfony>
  <commands namespace="foo">
    <command id="foo:bar" name="foo:bar">
      <usages>
        <usage>foo:bar</usage>
        <usage>afoobar</usage>
      </usages>
      <description>The foo:bar command</description>
      <help>The foo:bar command</help>
      <arguments/>
      <options>
        <option name="--help" shortcut="-h" accept_value="0" is_value_required="0" is_multiple="0">
          <description>Display this help message</description>
        </option>
        <option name="--quiet" shortcut="-q" accept_value="0" is_value_required="0" is_multiple="0">
          <description>Do not output any message</description>
        </option>
        <option name="--verbose" shortcut="-v" shortcuts="-v|-vv|-vvv" accept_value="0" is_value_required="0" is_multiple="0">
          <description>Increase the verbosity of messages: 1 for normal output, 2 for more verbose output and 3 for debug</description>
        </option>
        <option name="--version" shortcut="-V" accept_value="0" is_value_required="0" is_multiple="0">
          <description>Display this application version</description>
        </option>
        <option name="--ansi" shortcut="" accept_value="0" is_value_required="0" is_multiple="0">
          <description>Force ANSI output</description>
        </option>
        <option name="--no-ansi" shortcut="" accept_value="0" is_value_required="0" is_multiple="0">
          <description>Disable ANSI output</description>
        </option>
        <option name="--no-interaction" shortcut="-n" accept_value="0" is_value_required="0" is_multiple="0">
          <description>Do not ask any interactive question</description>
        </option>
      </options>
    </command>
  </commands>
</symfony>
PKϤ$Z�-/��(console/Tests/Fixtures/application_1.txtnu�[���<info>Console Tool</info>

<comment>Usage:</comment>
  command [options] [arguments]

<comment>Options:</comment>
  <info>-h, --help</info>            Display this help message
  <info>-q, --quiet</info>           Do not output any message
  <info>-V, --version</info>         Display this application version
  <info>    --ansi</info>            Force ANSI output
  <info>    --no-ansi</info>         Disable ANSI output
  <info>-n, --no-interaction</info>  Do not ask any interactive question
  <info>-v|vv|vvv, --verbose</info>  Increase the verbosity of messages: 1 for normal output, 2 for more verbose output and 3 for debug

<comment>Available commands:</comment>
  <info>help</info>  Displays help for a command
  <info>list</info>  Lists commands
PKϤ$Z�/""��&console/Tests/Fixtures/Foo5Command.phpnu�[���<?php

use Symfony\Component\Console\Command\Command;

class Foo5Command extends Command
{
    public function __construct()
    {
    }
}
PKϤ$Z��׊��-console/Tests/Fixtures/application_asxml1.txtnu�[���<?xml version="1.0" encoding="UTF-8"?>
<symfony>
  <commands>
    <command id="help" name="help">
      <usages>
        <usage>help [--xml] [--format FORMAT] [--raw] [--] [&lt;command_name&gt;]</usage>
      </usages>
      <description>Displays help for a command</description>
      <help>The &lt;info&gt;help&lt;/info&gt; command displays help for a given command:
 
   &lt;info&gt;php app/console help list&lt;/info&gt;
 
 You can also output the help in other formats by using the &lt;comment&gt;--format&lt;/comment&gt; option:
 
   &lt;info&gt;php app/console help --format=xml list&lt;/info&gt;
 
 To display the list of available commands, please use the &lt;info&gt;list&lt;/info&gt; command.</help>
      <arguments>
        <argument name="command_name" is_required="0" is_array="0">
          <description>The command name</description>
          <defaults>
            <default>help</default>
          </defaults>
        </argument>
      </arguments>
      <options>
        <option name="--xml" shortcut="" accept_value="0" is_value_required="0" is_multiple="0">
          <description>To output help as XML</description>
        </option>
        <option name="--format" shortcut="" accept_value="1" is_value_required="1" is_multiple="0">
          <description>The output format (txt, xml, json, or md)</description>
          <defaults>
            <default>txt</default>
          </defaults>
        </option>
        <option name="--raw" shortcut="" accept_value="0" is_value_required="0" is_multiple="0">
          <description>To output raw command help</description>
        </option>
        <option name="--help" shortcut="-h" accept_value="0" is_value_required="0" is_multiple="0">
          <description>Display this help message</description>
        </option>
        <option name="--quiet" shortcut="-q" accept_value="0" is_value_required="0" is_multiple="0">
          <description>Do not output any message</description>
        </option>
        <option name="--verbose" shortcut="-v" shortcuts="-v|-vv|-vvv" accept_value="0" is_value_required="0" is_multiple="0">
          <description>Increase the verbosity of messages: 1 for normal output, 2 for more verbose output and 3 for debug</description>
        </option>
        <option name="--version" shortcut="-V" accept_value="0" is_value_required="0" is_multiple="0">
          <description>Display this application version</description>
        </option>
        <option name="--ansi" shortcut="" accept_value="0" is_value_required="0" is_multiple="0">
          <description>Force ANSI output</description>
        </option>
        <option name="--no-ansi" shortcut="" accept_value="0" is_value_required="0" is_multiple="0">
          <description>Disable ANSI output</description>
        </option>
        <option name="--no-interaction" shortcut="-n" accept_value="0" is_value_required="0" is_multiple="0">
          <description>Do not ask any interactive question</description>
        </option>
      </options>
    </command>
    <command id="list" name="list">
      <usages>
        <usage>list [--xml] [--raw] [--format FORMAT] [--] [&lt;namespace&gt;]</usage>
      </usages>
      <description>Lists commands</description>
      <help>The &lt;info&gt;list&lt;/info&gt; command lists all commands:
 
   &lt;info&gt;php app/console list&lt;/info&gt;
 
 You can also display the commands for a specific namespace:
 
   &lt;info&gt;php app/console list test&lt;/info&gt;
 
 You can also output the information in other formats by using the &lt;comment&gt;--format&lt;/comment&gt; option:
 
   &lt;info&gt;php app/console list --format=xml&lt;/info&gt;
 
 It's also possible to get raw list of commands (useful for embedding command runner):
 
   &lt;info&gt;php app/console list --raw&lt;/info&gt;</help>
      <arguments>
        <argument name="namespace" is_required="0" is_array="0">
          <description>The namespace name</description>
          <defaults/>
        </argument>
      </arguments>
      <options>
        <option name="--xml" shortcut="" accept_value="0" is_value_required="0" is_multiple="0">
          <description>To output list as XML</description>
        </option>
        <option name="--raw" shortcut="" accept_value="0" is_value_required="0" is_multiple="0">
          <description>To output raw command list</description>
        </option>
        <option name="--format" shortcut="" accept_value="1" is_value_required="1" is_multiple="0">
          <description>The output format (txt, xml, json, or md)</description>
          <defaults>
            <default>txt</default>
          </defaults>
        </option>
      </options>
    </command>
    <command id="foo:bar" name="foo:bar">
      <usages>
        <usage>foo:bar</usage>
        <usage>afoobar</usage>
      </usages>
      <description>The foo:bar command</description>
      <help>The foo:bar command</help>
      <arguments/>
      <options>
        <option name="--help" shortcut="-h" accept_value="0" is_value_required="0" is_multiple="0">
          <description>Display this help message</description>
        </option>
        <option name="--quiet" shortcut="-q" accept_value="0" is_value_required="0" is_multiple="0">
          <description>Do not output any message</description>
        </option>
        <option name="--verbose" shortcut="-v" shortcuts="-v|-vv|-vvv" accept_value="0" is_value_required="0" is_multiple="0">
          <description>Increase the verbosity of messages: 1 for normal output, 2 for more verbose output and 3 for debug</description>
        </option>
        <option name="--version" shortcut="-V" accept_value="0" is_value_required="0" is_multiple="0">
          <description>Display this application version</description>
        </option>
        <option name="--ansi" shortcut="" accept_value="0" is_value_required="0" is_multiple="0">
          <description>Force ANSI output</description>
        </option>
        <option name="--no-ansi" shortcut="" accept_value="0" is_value_required="0" is_multiple="0">
          <description>Disable ANSI output</description>
        </option>
        <option name="--no-interaction" shortcut="-n" accept_value="0" is_value_required="0" is_multiple="0">
          <description>Do not ask any interactive question</description>
        </option>
      </options>
    </command>
  </commands>
  <namespaces>
    <namespace id="_global">
      <command>afoobar</command>
      <command>help</command>
      <command>list</command>
    </namespace>
    <namespace id="foo">
      <command>foo:bar</command>
    </namespace>
  </namespaces>
</symfony>
PKϤ$Z�q+��1console/Tests/Fixtures/DescriptorApplication1.phpnu�[���<?php

/*
 * This file is part of the Symfony package.
 *
 * (c) Fabien Potencier <fabien@symfony.com>
 *
 * For the full copyright and license information, please view the LICENSE
 * file that was distributed with this source code.
 */

namespace Symfony\Component\Console\Tests\Fixtures;

use Symfony\Component\Console\Application;

class DescriptorApplication1 extends Application
{
}
PKϤ$Za=J��(console/Tests/Fixtures/input_option_6.mdnu�[���**option_name:**

* Name: `--option_name`
* Shortcut: `-o|-O`
* Accept value: yes
* Is value required: yes
* Is multiple: no
* Description: option with multiple shortcuts
* Default: `NULL`
PKϤ$Z�+??*console/Tests/Logger/ConsoleLoggerTest.phpnu�[���<?php

/*
 * This file is part of the Symfony package.
 *
 * (c) Fabien Potencier <fabien@symfony.com>
 *
 * For the full copyright and license information, please view the LICENSE
 * file that was distributed with this source code.
 */

namespace Symfony\Component\Console\Tests\Logger;

use Psr\Log\Test\LoggerInterfaceTest;
use Psr\Log\LogLevel;
use Symfony\Component\Console\Logger\ConsoleLogger;
use Symfony\Component\Console\Tests\Fixtures\DummyOutput;
use Symfony\Component\Console\Output\OutputInterface;

/**
 * Console logger test.
 *
 * @author Kévin Dunglas <dunglas@gmail.com>
 */
class ConsoleLoggerTest extends LoggerInterfaceTest
{
    /**
     * @var DummyOutput
     */
    protected $output;

    /**
     * {@inheritdoc}
     */
    public function getLogger()
    {
        $this->output = new DummyOutput(OutputInterface::VERBOSITY_VERBOSE);

        return new ConsoleLogger($this->output, array(
            LogLevel::EMERGENCY => OutputInterface::VERBOSITY_NORMAL,
            LogLevel::ALERT => OutputInterface::VERBOSITY_NORMAL,
            LogLevel::CRITICAL => OutputInterface::VERBOSITY_NORMAL,
            LogLevel::ERROR => OutputInterface::VERBOSITY_NORMAL,
            LogLevel::WARNING => OutputInterface::VERBOSITY_NORMAL,
            LogLevel::NOTICE => OutputInterface::VERBOSITY_NORMAL,
            LogLevel::INFO => OutputInterface::VERBOSITY_NORMAL,
            LogLevel::DEBUG => OutputInterface::VERBOSITY_NORMAL,
        ));
    }

    /**
     * {@inheritdoc}
     */
    public function getLogs()
    {
        return $this->output->getLogs();
    }
}
PKϤ$Z����)console/Tests/Output/StreamOutputTest.phpnu�[���<?php

/*
 * This file is part of the Symfony package.
 *
 * (c) Fabien Potencier <fabien@symfony.com>
 *
 * For the full copyright and license information, please view the LICENSE
 * file that was distributed with this source code.
 */

namespace Symfony\Component\Console\Tests\Output;

use Symfony\Component\Console\Output\Output;
use Symfony\Component\Console\Output\StreamOutput;

class StreamOutputTest extends \PHPUnit_Framework_TestCase
{
    protected $stream;

    protected function setUp()
    {
        $this->stream = fopen('php://memory', 'a', false);
    }

    protected function tearDown()
    {
        $this->stream = null;
    }

    public function testConstructor()
    {
        $output = new StreamOutput($this->stream, Output::VERBOSITY_QUIET, true);
        $this->assertEquals(Output::VERBOSITY_QUIET, $output->getVerbosity(), '__construct() takes the verbosity as its first argument');
        $this->assertTrue($output->isDecorated(), '__construct() takes the decorated flag as its second argument');
    }

    /**
     * @expectedException        \InvalidArgumentException
     * @expectedExceptionMessage The StreamOutput class needs a stream as its first argument.
     */
    public function testStreamIsRequired()
    {
        new StreamOutput('foo');
    }

    public function testGetStream()
    {
        $output = new StreamOutput($this->stream);
        $this->assertEquals($this->stream, $output->getStream(), '->getStream() returns the current stream');
    }

    public function testDoWrite()
    {
        $output = new StreamOutput($this->stream);
        $output->writeln('foo');
        rewind($output->getStream());
        $this->assertEquals('foo'.PHP_EOL, stream_get_contents($output->getStream()), '->doWrite() writes to the stream');
    }
}
PKϤ$Z;�!��'console/Tests/Output/NullOutputTest.phpnu�[���<?php

/*
 * This file is part of the Symfony package.
 *
 * (c) Fabien Potencier <fabien@symfony.com>
 *
 * For the full copyright and license information, please view the LICENSE
 * file that was distributed with this source code.
 */

namespace Symfony\Component\Console\Tests\Output;

use Symfony\Component\Console\Output\NullOutput;
use Symfony\Component\Console\Output\OutputInterface;

class NullOutputTest extends \PHPUnit_Framework_TestCase
{
    public function testConstructor()
    {
        $output = new NullOutput();

        ob_start();
        $output->write('foo');
        $buffer = ob_get_clean();

        $this->assertSame('', $buffer, '->write() does nothing (at least nothing is printed)');
        $this->assertFalse($output->isDecorated(), '->isDecorated() returns false');
    }

    public function testVerbosity()
    {
        $output = new NullOutput();
        $this->assertSame(OutputInterface::VERBOSITY_QUIET, $output->getVerbosity(), '->getVerbosity() returns VERBOSITY_QUIET for NullOutput by default');

        $output->setVerbosity(OutputInterface::VERBOSITY_VERBOSE);
        $this->assertSame(OutputInterface::VERBOSITY_QUIET, $output->getVerbosity(), '->getVerbosity() always returns VERBOSITY_QUIET for NullOutput');
    }
}
PKϤ$Z���IPP#console/Tests/Output/OutputTest.phpnu�[���<?php

/*
 * This file is part of the Symfony package.
 *
 * (c) Fabien Potencier <fabien@symfony.com>
 *
 * For the full copyright and license information, please view the LICENSE
 * file that was distributed with this source code.
 */

namespace Symfony\Component\Console\Tests\Output;

use Symfony\Component\Console\Output\Output;
use Symfony\Component\Console\Formatter\OutputFormatterStyle;

class OutputTest extends \PHPUnit_Framework_TestCase
{
    public function testConstructor()
    {
        $output = new TestOutput(Output::VERBOSITY_QUIET, true);
        $this->assertEquals(Output::VERBOSITY_QUIET, $output->getVerbosity(), '__construct() takes the verbosity as its first argument');
        $this->assertTrue($output->isDecorated(), '__construct() takes the decorated flag as its second argument');
    }

    public function testSetIsDecorated()
    {
        $output = new TestOutput();
        $output->setDecorated(true);
        $this->assertTrue($output->isDecorated(), 'setDecorated() sets the decorated flag');
    }

    public function testSetGetVerbosity()
    {
        $output = new TestOutput();
        $output->setVerbosity(Output::VERBOSITY_QUIET);
        $this->assertEquals(Output::VERBOSITY_QUIET, $output->getVerbosity(), '->setVerbosity() sets the verbosity');

        $this->assertTrue($output->isQuiet());
        $this->assertFalse($output->isVerbose());
        $this->assertFalse($output->isVeryVerbose());
        $this->assertFalse($output->isDebug());

        $output->setVerbosity(Output::VERBOSITY_NORMAL);
        $this->assertFalse($output->isQuiet());
        $this->assertFalse($output->isVerbose());
        $this->assertFalse($output->isVeryVerbose());
        $this->assertFalse($output->isDebug());

        $output->setVerbosity(Output::VERBOSITY_VERBOSE);
        $this->assertFalse($output->isQuiet());
        $this->assertTrue($output->isVerbose());
        $this->assertFalse($output->isVeryVerbose());
        $this->assertFalse($output->isDebug());

        $output->setVerbosity(Output::VERBOSITY_VERY_VERBOSE);
        $this->assertFalse($output->isQuiet());
        $this->assertTrue($output->isVerbose());
        $this->assertTrue($output->isVeryVerbose());
        $this->assertFalse($output->isDebug());

        $output->setVerbosity(Output::VERBOSITY_DEBUG);
        $this->assertFalse($output->isQuiet());
        $this->assertTrue($output->isVerbose());
        $this->assertTrue($output->isVeryVerbose());
        $this->assertTrue($output->isDebug());
    }

    public function testWriteWithVerbosityQuiet()
    {
        $output = new TestOutput(Output::VERBOSITY_QUIET);
        $output->writeln('foo');
        $this->assertEquals('', $output->output, '->writeln() outputs nothing if verbosity is set to VERBOSITY_QUIET');
    }

    public function testWriteAnArrayOfMessages()
    {
        $output = new TestOutput();
        $output->writeln(array('foo', 'bar'));
        $this->assertEquals("foo\nbar\n", $output->output, '->writeln() can take an array of messages to output');
    }

    /**
     * @dataProvider provideWriteArguments
     */
    public function testWriteRawMessage($message, $type, $expectedOutput)
    {
        $output = new TestOutput();
        $output->writeln($message, $type);
        $this->assertEquals($expectedOutput, $output->output);
    }

    public function provideWriteArguments()
    {
        return array(
            array('<info>foo</info>', Output::OUTPUT_RAW, "<info>foo</info>\n"),
            array('<info>foo</info>', Output::OUTPUT_PLAIN, "foo\n"),
        );
    }

    public function testWriteWithDecorationTurnedOff()
    {
        $output = new TestOutput();
        $output->setDecorated(false);
        $output->writeln('<info>foo</info>');
        $this->assertEquals("foo\n", $output->output, '->writeln() strips decoration tags if decoration is set to false');
    }

    public function testWriteDecoratedMessage()
    {
        $fooStyle = new OutputFormatterStyle('yellow', 'red', array('blink'));
        $output = new TestOutput();
        $output->getFormatter()->setStyle('FOO', $fooStyle);
        $output->setDecorated(true);
        $output->writeln('<foo>foo</foo>');
        $this->assertEquals("\033[33;41;5mfoo\033[39;49;25m\n", $output->output, '->writeln() decorates the output');
    }

    public function testWriteWithInvalidStyle()
    {
        $output = new TestOutput();

        $output->clear();
        $output->write('<bar>foo</bar>');
        $this->assertEquals('<bar>foo</bar>', $output->output, '->write() do nothing when a style does not exist');

        $output->clear();
        $output->writeln('<bar>foo</bar>');
        $this->assertEquals("<bar>foo</bar>\n", $output->output, '->writeln() do nothing when a style does not exist');
    }

    /**
     * @dataProvider verbosityProvider
     */
    public function testWriteWithVerbosityOption($verbosity, $expected, $msg)
    {
        $output = new TestOutput();

        $output->setVerbosity($verbosity);
        $output->clear();
        $output->write('1', false);
        $output->write('2', false, Output::VERBOSITY_QUIET);
        $output->write('3', false, Output::VERBOSITY_NORMAL);
        $output->write('4', false, Output::VERBOSITY_VERBOSE);
        $output->write('5', false, Output::VERBOSITY_VERY_VERBOSE);
        $output->write('6', false, Output::VERBOSITY_DEBUG);
        $this->assertEquals($expected, $output->output, $msg);
    }

    public function verbosityProvider()
    {
        return array(
            array(Output::VERBOSITY_QUIET, '2', '->write() in QUIET mode only outputs when an explicit QUIET verbosity is passed'),
            array(Output::VERBOSITY_NORMAL, '123', '->write() in NORMAL mode outputs anything below an explicit VERBOSE verbosity'),
            array(Output::VERBOSITY_VERBOSE, '1234', '->write() in VERBOSE mode outputs anything below an explicit VERY_VERBOSE verbosity'),
            array(Output::VERBOSITY_VERY_VERBOSE, '12345', '->write() in VERY_VERBOSE mode outputs anything below an explicit DEBUG verbosity'),
            array(Output::VERBOSITY_DEBUG, '123456', '->write() in DEBUG mode outputs everything'),
        );
    }
}

class TestOutput extends Output
{
    public $output = '';

    public function clear()
    {
        $this->output = '';
    }

    protected function doWrite($message, $newline)
    {
        $this->output .= $message.($newline ? "\n" : '');
    }
}
PKϤ$Z)3͐cc*console/Tests/Output/ConsoleOutputTest.phpnu�[���<?php

/*
 * This file is part of the Symfony package.
 *
 * (c) Fabien Potencier <fabien@symfony.com>
 *
 * For the full copyright and license information, please view the LICENSE
 * file that was distributed with this source code.
 */

namespace Symfony\Component\Console\Tests\Output;

use Symfony\Component\Console\Output\ConsoleOutput;
use Symfony\Component\Console\Output\Output;

class ConsoleOutputTest extends \PHPUnit_Framework_TestCase
{
    public function testConstructor()
    {
        $output = new ConsoleOutput(Output::VERBOSITY_QUIET, true);
        $this->assertEquals(Output::VERBOSITY_QUIET, $output->getVerbosity(), '__construct() takes the verbosity as its first argument');
        $this->assertSame($output->getFormatter(), $output->getErrorOutput()->getFormatter(), '__construct() takes a formatter or null as the third argument');
    }
}
PKϤ$Z�BB?##&console/Tests/Input/ArrayInputTest.phpnu�[���<?php

/*
 * This file is part of the Symfony package.
 *
 * (c) Fabien Potencier <fabien@symfony.com>
 *
 * For the full copyright and license information, please view the LICENSE
 * file that was distributed with this source code.
 */

namespace Symfony\Component\Console\Tests\Input;

use Symfony\Component\Console\Input\ArrayInput;
use Symfony\Component\Console\Input\InputDefinition;
use Symfony\Component\Console\Input\InputArgument;
use Symfony\Component\Console\Input\InputOption;

class ArrayInputTest extends \PHPUnit_Framework_TestCase
{
    public function testGetFirstArgument()
    {
        $input = new ArrayInput(array());
        $this->assertNull($input->getFirstArgument(), '->getFirstArgument() returns null if no argument were passed');
        $input = new ArrayInput(array('name' => 'Fabien'));
        $this->assertEquals('Fabien', $input->getFirstArgument(), '->getFirstArgument() returns the first passed argument');
        $input = new ArrayInput(array('--foo' => 'bar', 'name' => 'Fabien'));
        $this->assertEquals('Fabien', $input->getFirstArgument(), '->getFirstArgument() returns the first passed argument');
    }

    public function testHasParameterOption()
    {
        $input = new ArrayInput(array('name' => 'Fabien', '--foo' => 'bar'));
        $this->assertTrue($input->hasParameterOption('--foo'), '->hasParameterOption() returns true if an option is present in the passed parameters');
        $this->assertFalse($input->hasParameterOption('--bar'), '->hasParameterOption() returns false if an option is not present in the passed parameters');

        $input = new ArrayInput(array('--foo'));
        $this->assertTrue($input->hasParameterOption('--foo'), '->hasParameterOption() returns true if an option is present in the passed parameters');
    }

    public function testGetParameterOption()
    {
        $input = new ArrayInput(array('name' => 'Fabien', '--foo' => 'bar'));
        $this->assertEquals('bar', $input->getParameterOption('--foo'), '->getParameterOption() returns the option of specified name');

        $input = new ArrayInput(array('Fabien', '--foo' => 'bar'));
        $this->assertEquals('bar', $input->getParameterOption('--foo'), '->getParameterOption() returns the option of specified name');
    }

    public function testParseArguments()
    {
        $input = new ArrayInput(array('name' => 'foo'), new InputDefinition(array(new InputArgument('name'))));

        $this->assertEquals(array('name' => 'foo'), $input->getArguments(), '->parse() parses required arguments');
    }

    /**
     * @dataProvider provideOptions
     */
    public function testParseOptions($input, $options, $expectedOptions, $message)
    {
        $input = new ArrayInput($input, new InputDefinition($options));

        $this->assertEquals($expectedOptions, $input->getOptions(), $message);
    }

    public function provideOptions()
    {
        return array(
            array(
                array('--foo' => 'bar'),
                array(new InputOption('foo')),
                array('foo' => 'bar'),
                '->parse() parses long options',
            ),
            array(
                array('--foo' => 'bar'),
                array(new InputOption('foo', 'f', InputOption::VALUE_OPTIONAL, '', 'default')),
                array('foo' => 'bar'),
                '->parse() parses long options with a default value',
            ),
            array(
                array('--foo' => null),
                array(new InputOption('foo', 'f', InputOption::VALUE_OPTIONAL, '', 'default')),
                array('foo' => 'default'),
                '->parse() parses long options with a default value',
            ),
            array(
                array('-f' => 'bar'),
                array(new InputOption('foo', 'f')),
                array('foo' => 'bar'),
                '->parse() parses short options',
            ),
        );
    }

    /**
     * @dataProvider provideInvalidInput
     */
    public function testParseInvalidInput($parameters, $definition, $expectedExceptionMessage)
    {
        $this->setExpectedException('InvalidArgumentException', $expectedExceptionMessage);

        new ArrayInput($parameters, $definition);
    }

    public function provideInvalidInput()
    {
        return array(
            array(
                array('foo' => 'foo'),
                new InputDefinition(array(new InputArgument('name'))),
                'The "foo" argument does not exist.',
            ),
            array(
                array('--foo' => null),
                new InputDefinition(array(new InputOption('foo', 'f', InputOption::VALUE_REQUIRED))),
                'The "--foo" option requires a value.',
            ),
            array(
                array('--foo' => 'foo'),
                new InputDefinition(),
                'The "--foo" option does not exist.',
            ),
            array(
                array('-o' => 'foo'),
                new InputDefinition(),
                'The "-o" option does not exist.',
            ),
        );
    }

    public function testToString()
    {
        $input = new ArrayInput(array('-f' => null, '-b' => 'bar', '--foo' => 'b a z', '--lala' => null, 'test' => 'Foo', 'test2' => "A\nB'C"));
        $this->assertEquals('-f -b=bar --foo='.escapeshellarg('b a z').' --lala Foo '.escapeshellarg("A\nB'C"), (string) $input);
    }
}
PKϤ$Z���ȸ�)console/Tests/Input/InputArgumentTest.phpnu�[���<?php

/*
 * This file is part of the Symfony package.
 *
 * (c) Fabien Potencier <fabien@symfony.com>
 *
 * For the full copyright and license information, please view the LICENSE
 * file that was distributed with this source code.
 */

namespace Symfony\Component\Console\Tests\Input;

use Symfony\Component\Console\Input\InputArgument;

class InputArgumentTest extends \PHPUnit_Framework_TestCase
{
    public function testConstructor()
    {
        $argument = new InputArgument('foo');
        $this->assertEquals('foo', $argument->getName(), '__construct() takes a name as its first argument');
    }

    public function testModes()
    {
        $argument = new InputArgument('foo');
        $this->assertFalse($argument->isRequired(), '__construct() gives a "InputArgument::OPTIONAL" mode by default');

        $argument = new InputArgument('foo', null);
        $this->assertFalse($argument->isRequired(), '__construct() can take "InputArgument::OPTIONAL" as its mode');

        $argument = new InputArgument('foo', InputArgument::OPTIONAL);
        $this->assertFalse($argument->isRequired(), '__construct() can take "InputArgument::OPTIONAL" as its mode');

        $argument = new InputArgument('foo', InputArgument::REQUIRED);
        $this->assertTrue($argument->isRequired(), '__construct() can take "InputArgument::REQUIRED" as its mode');
    }

    /**
     * @dataProvider provideInvalidModes
     */
    public function testInvalidModes($mode)
    {
        $this->setExpectedException('InvalidArgumentException', sprintf('Argument mode "%s" is not valid.', $mode));

        new InputArgument('foo', $mode);
    }

    public function provideInvalidModes()
    {
        return array(
            array('ANOTHER_ONE'),
            array(-1),
        );
    }

    public function testIsArray()
    {
        $argument = new InputArgument('foo', InputArgument::IS_ARRAY);
        $this->assertTrue($argument->isArray(), '->isArray() returns true if the argument can be an array');
        $argument = new InputArgument('foo', InputArgument::OPTIONAL | InputArgument::IS_ARRAY);
        $this->assertTrue($argument->isArray(), '->isArray() returns true if the argument can be an array');
        $argument = new InputArgument('foo', InputArgument::OPTIONAL);
        $this->assertFalse($argument->isArray(), '->isArray() returns false if the argument can not be an array');
    }

    public function testGetDescription()
    {
        $argument = new InputArgument('foo', null, 'Some description');
        $this->assertEquals('Some description', $argument->getDescription(), '->getDescription() return the message description');
    }

    public function testGetDefault()
    {
        $argument = new InputArgument('foo', InputArgument::OPTIONAL, '', 'default');
        $this->assertEquals('default', $argument->getDefault(), '->getDefault() return the default value');
    }

    public function testSetDefault()
    {
        $argument = new InputArgument('foo', InputArgument::OPTIONAL, '', 'default');
        $argument->setDefault(null);
        $this->assertNull($argument->getDefault(), '->setDefault() can reset the default value by passing null');
        $argument->setDefault('another');
        $this->assertEquals('another', $argument->getDefault(), '->setDefault() changes the default value');

        $argument = new InputArgument('foo', InputArgument::OPTIONAL | InputArgument::IS_ARRAY);
        $argument->setDefault(array(1, 2));
        $this->assertEquals(array(1, 2), $argument->getDefault(), '->setDefault() changes the default value');
    }

    /**
     * @expectedException        \LogicException
     * @expectedExceptionMessage Cannot set a default value except for InputArgument::OPTIONAL mode.
     */
    public function testSetDefaultWithRequiredArgument()
    {
        $argument = new InputArgument('foo', InputArgument::REQUIRED);
        $argument->setDefault('default');
    }

    /**
     * @expectedException        \LogicException
     * @expectedExceptionMessage A default value for an array argument must be an array.
     */
    public function testSetDefaultWithArrayArgument()
    {
        $argument = new InputArgument('foo', InputArgument::IS_ARRAY);
        $argument->setDefault('default');
    }
}
PKϤ$Z�t7��!console/Tests/Input/InputTest.phpnu�[���<?php

/*
 * This file is part of the Symfony package.
 *
 * (c) Fabien Potencier <fabien@symfony.com>
 *
 * For the full copyright and license information, please view the LICENSE
 * file that was distributed with this source code.
 */

namespace Symfony\Component\Console\Tests\Input;

use Symfony\Component\Console\Input\ArrayInput;
use Symfony\Component\Console\Input\InputDefinition;
use Symfony\Component\Console\Input\InputArgument;
use Symfony\Component\Console\Input\InputOption;

class InputTest extends \PHPUnit_Framework_TestCase
{
    public function testConstructor()
    {
        $input = new ArrayInput(array('name' => 'foo'), new InputDefinition(array(new InputArgument('name'))));
        $this->assertEquals('foo', $input->getArgument('name'), '->__construct() takes a InputDefinition as an argument');
    }

    public function testOptions()
    {
        $input = new ArrayInput(array('--name' => 'foo'), new InputDefinition(array(new InputOption('name'))));
        $this->assertEquals('foo', $input->getOption('name'), '->getOption() returns the value for the given option');

        $input->setOption('name', 'bar');
        $this->assertEquals('bar', $input->getOption('name'), '->setOption() sets the value for a given option');
        $this->assertEquals(array('name' => 'bar'), $input->getOptions(), '->getOptions() returns all option values');

        $input = new ArrayInput(array('--name' => 'foo'), new InputDefinition(array(new InputOption('name'), new InputOption('bar', '', InputOption::VALUE_OPTIONAL, '', 'default'))));
        $this->assertEquals('default', $input->getOption('bar'), '->getOption() returns the default value for optional options');
        $this->assertEquals(array('name' => 'foo', 'bar' => 'default'), $input->getOptions(), '->getOptions() returns all option values, even optional ones');
    }

    /**
     * @expectedException        \InvalidArgumentException
     * @expectedExceptionMessage The "foo" option does not exist.
     */
    public function testSetInvalidOption()
    {
        $input = new ArrayInput(array('--name' => 'foo'), new InputDefinition(array(new InputOption('name'), new InputOption('bar', '', InputOption::VALUE_OPTIONAL, '', 'default'))));
        $input->setOption('foo', 'bar');
    }

    /**
     * @expectedException        \InvalidArgumentException
     * @expectedExceptionMessage The "foo" option does not exist.
     */
    public function testGetInvalidOption()
    {
        $input = new ArrayInput(array('--name' => 'foo'), new InputDefinition(array(new InputOption('name'), new InputOption('bar', '', InputOption::VALUE_OPTIONAL, '', 'default'))));
        $input->getOption('foo');
    }

    public function testArguments()
    {
        $input = new ArrayInput(array('name' => 'foo'), new InputDefinition(array(new InputArgument('name'))));
        $this->assertEquals('foo', $input->getArgument('name'), '->getArgument() returns the value for the given argument');

        $input->setArgument('name', 'bar');
        $this->assertEquals('bar', $input->getArgument('name'), '->setArgument() sets the value for a given argument');
        $this->assertEquals(array('name' => 'bar'), $input->getArguments(), '->getArguments() returns all argument values');

        $input = new ArrayInput(array('name' => 'foo'), new InputDefinition(array(new InputArgument('name'), new InputArgument('bar', InputArgument::OPTIONAL, '', 'default'))));
        $this->assertEquals('default', $input->getArgument('bar'), '->getArgument() returns the default value for optional arguments');
        $this->assertEquals(array('name' => 'foo', 'bar' => 'default'), $input->getArguments(), '->getArguments() returns all argument values, even optional ones');
    }

    /**
     * @expectedException        \InvalidArgumentException
     * @expectedExceptionMessage The "foo" argument does not exist.
     */
    public function testSetInvalidArgument()
    {
        $input = new ArrayInput(array('name' => 'foo'), new InputDefinition(array(new InputArgument('name'), new InputArgument('bar', InputArgument::OPTIONAL, '', 'default'))));
        $input->setArgument('foo', 'bar');
    }

    /**
     * @expectedException        \InvalidArgumentException
     * @expectedExceptionMessage The "foo" argument does not exist.
     */
    public function testGetInvalidArgument()
    {
        $input = new ArrayInput(array('name' => 'foo'), new InputDefinition(array(new InputArgument('name'), new InputArgument('bar', InputArgument::OPTIONAL, '', 'default'))));
        $input->getArgument('foo');
    }

    /**
     * @expectedException        \RuntimeException
     * @expectedExceptionMessage Not enough arguments (missing: "name").
     */
    public function testValidateWithMissingArguments()
    {
        $input = new ArrayInput(array());
        $input->bind(new InputDefinition(array(new InputArgument('name', InputArgument::REQUIRED))));
        $input->validate();
    }

    /**
     * @expectedException        \RuntimeException
     * @expectedExceptionMessage Not enough arguments (missing: "name").
     */
    public function testValidateWithMissingRequiredArguments()
    {
        $input = new ArrayInput(array('bar' => 'baz'));
        $input->bind(new InputDefinition(array(new InputArgument('name', InputArgument::REQUIRED), new InputArgument('bar', InputArgument::OPTIONAL))));
        $input->validate();
    }

    public function testValidate()
    {
        $input = new ArrayInput(array('name' => 'foo'));
        $input->bind(new InputDefinition(array(new InputArgument('name', InputArgument::REQUIRED))));

        $this->assertNull($input->validate());
    }

    public function testSetGetInteractive()
    {
        $input = new ArrayInput(array());
        $this->assertTrue($input->isInteractive(), '->isInteractive() returns whether the input should be interactive or not');
        $input->setInteractive(false);
        $this->assertFalse($input->isInteractive(), '->setInteractive() changes the interactive flag');
    }
}
PKϤ$Zh��oo'console/Tests/Input/StringInputTest.phpnu�[���<?php

/*
 * This file is part of the Symfony package.
 *
 * (c) Fabien Potencier <fabien@symfony.com>
 *
 * For the full copyright and license information, please view the LICENSE
 * file that was distributed with this source code.
 */

namespace Symfony\Component\Console\Tests\Input;

use Symfony\Component\Console\Input\InputDefinition;
use Symfony\Component\Console\Input\InputOption;
use Symfony\Component\Console\Input\StringInput;

class StringInputTest extends \PHPUnit_Framework_TestCase
{
    /**
     * @dataProvider getTokenizeData
     */
    public function testTokenize($input, $tokens, $message)
    {
        $input = new StringInput($input);
        $r = new \ReflectionClass('Symfony\Component\Console\Input\ArgvInput');
        $p = $r->getProperty('tokens');
        $p->setAccessible(true);
        $this->assertEquals($tokens, $p->getValue($input), $message);
    }

    public function testInputOptionWithGivenString()
    {
        $definition = new InputDefinition(
            array(new InputOption('foo', null, InputOption::VALUE_REQUIRED))
        );

        // call to bind
        $input = new StringInput('--foo=bar');
        $input->bind($definition);
        $this->assertEquals('bar', $input->getOption('foo'));
    }

    /**
     * @group legacy
     */
    public function testLegacyInputOptionDefinitionInConstructor()
    {
        $definition = new InputDefinition(
            array(new InputOption('foo', null, InputOption::VALUE_REQUIRED))
        );

        $input = new StringInput('--foo=bar', $definition);
        $this->assertEquals('bar', $input->getOption('foo'));
    }

    public function getTokenizeData()
    {
        return array(
            array('', array(), '->tokenize() parses an empty string'),
            array('foo', array('foo'), '->tokenize() parses arguments'),
            array('  foo  bar  ', array('foo', 'bar'), '->tokenize() ignores whitespaces between arguments'),
            array('"quoted"', array('quoted'), '->tokenize() parses quoted arguments'),
            array("'quoted'", array('quoted'), '->tokenize() parses quoted arguments'),
            array("'a\rb\nc\td'", array("a\rb\nc\td"), '->tokenize() parses whitespace chars in strings'),
            array("'a'\r'b'\n'c'\t'd'", array('a', 'b', 'c', 'd'), '->tokenize() parses whitespace chars between args as spaces'),
            array('\"quoted\"', array('"quoted"'), '->tokenize() parses escaped-quoted arguments'),
            array("\'quoted\'", array('\'quoted\''), '->tokenize() parses escaped-quoted arguments'),
            array('-a', array('-a'), '->tokenize() parses short options'),
            array('-azc', array('-azc'), '->tokenize() parses aggregated short options'),
            array('-awithavalue', array('-awithavalue'), '->tokenize() parses short options with a value'),
            array('-a"foo bar"', array('-afoo bar'), '->tokenize() parses short options with a value'),
            array('-a"foo bar""foo bar"', array('-afoo barfoo bar'), '->tokenize() parses short options with a value'),
            array('-a\'foo bar\'', array('-afoo bar'), '->tokenize() parses short options with a value'),
            array('-a\'foo bar\'\'foo bar\'', array('-afoo barfoo bar'), '->tokenize() parses short options with a value'),
            array('-a\'foo bar\'"foo bar"', array('-afoo barfoo bar'), '->tokenize() parses short options with a value'),
            array('--long-option', array('--long-option'), '->tokenize() parses long options'),
            array('--long-option=foo', array('--long-option=foo'), '->tokenize() parses long options with a value'),
            array('--long-option="foo bar"', array('--long-option=foo bar'), '->tokenize() parses long options with a value'),
            array('--long-option="foo bar""another"', array('--long-option=foo baranother'), '->tokenize() parses long options with a value'),
            array('--long-option=\'foo bar\'', array('--long-option=foo bar'), '->tokenize() parses long options with a value'),
            array("--long-option='foo bar''another'", array('--long-option=foo baranother'), '->tokenize() parses long options with a value'),
            array("--long-option='foo bar'\"another\"", array('--long-option=foo baranother'), '->tokenize() parses long options with a value'),
            array('foo -a -ffoo --long bar', array('foo', '-a', '-ffoo', '--long', 'bar'), '->tokenize() parses when several arguments and options'),
        );
    }

    public function testToString()
    {
        $input = new StringInput('-f foo');
        $this->assertEquals('-f foo', (string) $input);

        $input = new StringInput('-f --bar=foo "a b c d"');
        $this->assertEquals('-f --bar=foo '.escapeshellarg('a b c d'), (string) $input);

        $input = new StringInput('-f --bar=foo \'a b c d\' '."'A\nB\\'C'");
        $this->assertEquals('-f --bar=foo '.escapeshellarg('a b c d').' '.escapeshellarg("A\nB'C"), (string) $input);
    }
}
PKϤ$Z�&;l�I�I+console/Tests/Input/InputDefinitionTest.phpnu�[���<?php

/*
 * This file is part of the Symfony package.
 *
 * (c) Fabien Potencier <fabien@symfony.com>
 *
 * For the full copyright and license information, please view the LICENSE
 * file that was distributed with this source code.
 */

namespace Symfony\Component\Console\Tests\Input;

use Symfony\Component\Console\Input\InputDefinition;
use Symfony\Component\Console\Input\InputArgument;
use Symfony\Component\Console\Input\InputOption;

class InputDefinitionTest extends \PHPUnit_Framework_TestCase
{
    protected static $fixtures;

    protected $foo, $bar, $foo1, $foo2;

    public static function setUpBeforeClass()
    {
        self::$fixtures = __DIR__.'/../Fixtures/';
    }

    public function testConstructorArguments()
    {
        $this->initializeArguments();

        $definition = new InputDefinition();
        $this->assertEquals(array(), $definition->getArguments(), '__construct() creates a new InputDefinition object');

        $definition = new InputDefinition(array($this->foo, $this->bar));
        $this->assertEquals(array('foo' => $this->foo, 'bar' => $this->bar), $definition->getArguments(), '__construct() takes an array of InputArgument objects as its first argument');
    }

    public function testConstructorOptions()
    {
        $this->initializeOptions();

        $definition = new InputDefinition();
        $this->assertEquals(array(), $definition->getOptions(), '__construct() creates a new InputDefinition object');

        $definition = new InputDefinition(array($this->foo, $this->bar));
        $this->assertEquals(array('foo' => $this->foo, 'bar' => $this->bar), $definition->getOptions(), '__construct() takes an array of InputOption objects as its first argument');
    }

    public function testSetArguments()
    {
        $this->initializeArguments();

        $definition = new InputDefinition();
        $definition->setArguments(array($this->foo));
        $this->assertEquals(array('foo' => $this->foo), $definition->getArguments(), '->setArguments() sets the array of InputArgument objects');
        $definition->setArguments(array($this->bar));

        $this->assertEquals(array('bar' => $this->bar), $definition->getArguments(), '->setArguments() clears all InputArgument objects');
    }

    public function testAddArguments()
    {
        $this->initializeArguments();

        $definition = new InputDefinition();
        $definition->addArguments(array($this->foo));
        $this->assertEquals(array('foo' => $this->foo), $definition->getArguments(), '->addArguments() adds an array of InputArgument objects');
        $definition->addArguments(array($this->bar));
        $this->assertEquals(array('foo' => $this->foo, 'bar' => $this->bar), $definition->getArguments(), '->addArguments() does not clear existing InputArgument objects');
    }

    public function testAddArgument()
    {
        $this->initializeArguments();

        $definition = new InputDefinition();
        $definition->addArgument($this->foo);
        $this->assertEquals(array('foo' => $this->foo), $definition->getArguments(), '->addArgument() adds a InputArgument object');
        $definition->addArgument($this->bar);
        $this->assertEquals(array('foo' => $this->foo, 'bar' => $this->bar), $definition->getArguments(), '->addArgument() adds a InputArgument object');
    }

    /**
     * @expectedException        \LogicException
     * @expectedExceptionMessage An argument with name "foo" already exists.
     */
    public function testArgumentsMustHaveDifferentNames()
    {
        $this->initializeArguments();

        $definition = new InputDefinition();
        $definition->addArgument($this->foo);
        $definition->addArgument($this->foo1);
    }

    /**
     * @expectedException        \LogicException
     * @expectedExceptionMessage Cannot add an argument after an array argument.
     */
    public function testArrayArgumentHasToBeLast()
    {
        $this->initializeArguments();

        $definition = new InputDefinition();
        $definition->addArgument(new InputArgument('fooarray', InputArgument::IS_ARRAY));
        $definition->addArgument(new InputArgument('anotherbar'));
    }

    /**
     * @expectedException        \LogicException
     * @expectedExceptionMessage Cannot add a required argument after an optional one.
     */
    public function testRequiredArgumentCannotFollowAnOptionalOne()
    {
        $this->initializeArguments();

        $definition = new InputDefinition();
        $definition->addArgument($this->foo);
        $definition->addArgument($this->foo2);
    }

    public function testGetArgument()
    {
        $this->initializeArguments();

        $definition = new InputDefinition();
        $definition->addArguments(array($this->foo));
        $this->assertEquals($this->foo, $definition->getArgument('foo'), '->getArgument() returns a InputArgument by its name');
    }

    /**
     * @expectedException        \InvalidArgumentException
     * @expectedExceptionMessage The "bar" argument does not exist.
     */
    public function testGetInvalidArgument()
    {
        $this->initializeArguments();

        $definition = new InputDefinition();
        $definition->addArguments(array($this->foo));
        $definition->getArgument('bar');
    }

    public function testHasArgument()
    {
        $this->initializeArguments();

        $definition = new InputDefinition();
        $definition->addArguments(array($this->foo));

        $this->assertTrue($definition->hasArgument('foo'), '->hasArgument() returns true if a InputArgument exists for the given name');
        $this->assertFalse($definition->hasArgument('bar'), '->hasArgument() returns false if a InputArgument exists for the given name');
    }

    public function testGetArgumentRequiredCount()
    {
        $this->initializeArguments();

        $definition = new InputDefinition();
        $definition->addArgument($this->foo2);
        $this->assertEquals(1, $definition->getArgumentRequiredCount(), '->getArgumentRequiredCount() returns the number of required arguments');
        $definition->addArgument($this->foo);
        $this->assertEquals(1, $definition->getArgumentRequiredCount(), '->getArgumentRequiredCount() returns the number of required arguments');
    }

    public function testGetArgumentCount()
    {
        $this->initializeArguments();

        $definition = new InputDefinition();
        $definition->addArgument($this->foo2);
        $this->assertEquals(1, $definition->getArgumentCount(), '->getArgumentCount() returns the number of arguments');
        $definition->addArgument($this->foo);
        $this->assertEquals(2, $definition->getArgumentCount(), '->getArgumentCount() returns the number of arguments');
    }

    public function testGetArgumentDefaults()
    {
        $definition = new InputDefinition(array(
            new InputArgument('foo1', InputArgument::OPTIONAL),
            new InputArgument('foo2', InputArgument::OPTIONAL, '', 'default'),
            new InputArgument('foo3', InputArgument::OPTIONAL | InputArgument::IS_ARRAY),
        //  new InputArgument('foo4', InputArgument::OPTIONAL | InputArgument::IS_ARRAY, '', array(1, 2)),
        ));
        $this->assertEquals(array('foo1' => null, 'foo2' => 'default', 'foo3' => array()), $definition->getArgumentDefaults(), '->getArgumentDefaults() return the default values for each argument');

        $definition = new InputDefinition(array(
            new InputArgument('foo4', InputArgument::OPTIONAL | InputArgument::IS_ARRAY, '', array(1, 2)),
        ));
        $this->assertEquals(array('foo4' => array(1, 2)), $definition->getArgumentDefaults(), '->getArgumentDefaults() return the default values for each argument');
    }

    public function testSetOptions()
    {
        $this->initializeOptions();

        $definition = new InputDefinition(array($this->foo));
        $this->assertEquals(array('foo' => $this->foo), $definition->getOptions(), '->setOptions() sets the array of InputOption objects');
        $definition->setOptions(array($this->bar));
        $this->assertEquals(array('bar' => $this->bar), $definition->getOptions(), '->setOptions() clears all InputOption objects');
    }

    /**
     * @expectedException        \InvalidArgumentException
     * @expectedExceptionMessage The "-f" option does not exist.
     */
    public function testSetOptionsClearsOptions()
    {
        $this->initializeOptions();

        $definition = new InputDefinition(array($this->foo));
        $definition->setOptions(array($this->bar));
        $definition->getOptionForShortcut('f');
    }

    public function testAddOptions()
    {
        $this->initializeOptions();

        $definition = new InputDefinition(array($this->foo));
        $this->assertEquals(array('foo' => $this->foo), $definition->getOptions(), '->addOptions() adds an array of InputOption objects');
        $definition->addOptions(array($this->bar));
        $this->assertEquals(array('foo' => $this->foo, 'bar' => $this->bar), $definition->getOptions(), '->addOptions() does not clear existing InputOption objects');
    }

    public function testAddOption()
    {
        $this->initializeOptions();

        $definition = new InputDefinition();
        $definition->addOption($this->foo);
        $this->assertEquals(array('foo' => $this->foo), $definition->getOptions(), '->addOption() adds a InputOption object');
        $definition->addOption($this->bar);
        $this->assertEquals(array('foo' => $this->foo, 'bar' => $this->bar), $definition->getOptions(), '->addOption() adds a InputOption object');
    }

    /**
     * @expectedException        \LogicException
     * @expectedExceptionMessage An option named "foo" already exists.
     */
    public function testAddDuplicateOption()
    {
        $this->initializeOptions();

        $definition = new InputDefinition();
        $definition->addOption($this->foo);
        $definition->addOption($this->foo2);
    }

    /**
     * @expectedException        \LogicException
     * @expectedExceptionMessage An option with shortcut "f" already exists.
     */
    public function testAddDuplicateShortcutOption()
    {
        $this->initializeOptions();

        $definition = new InputDefinition();
        $definition->addOption($this->foo);
        $definition->addOption($this->foo1);
    }

    public function testGetOption()
    {
        $this->initializeOptions();

        $definition = new InputDefinition(array($this->foo));
        $this->assertEquals($this->foo, $definition->getOption('foo'), '->getOption() returns a InputOption by its name');
    }

    /**
     * @expectedException        \InvalidArgumentException
     * @expectedExceptionMessage The "--bar" option does not exist.
     */
    public function testGetInvalidOption()
    {
        $this->initializeOptions();

        $definition = new InputDefinition(array($this->foo));
        $definition->getOption('bar');
    }

    public function testHasOption()
    {
        $this->initializeOptions();

        $definition = new InputDefinition(array($this->foo));
        $this->assertTrue($definition->hasOption('foo'), '->hasOption() returns true if a InputOption exists for the given name');
        $this->assertFalse($definition->hasOption('bar'), '->hasOption() returns false if a InputOption exists for the given name');
    }

    public function testHasShortcut()
    {
        $this->initializeOptions();

        $definition = new InputDefinition(array($this->foo));
        $this->assertTrue($definition->hasShortcut('f'), '->hasShortcut() returns true if a InputOption exists for the given shortcut');
        $this->assertFalse($definition->hasShortcut('b'), '->hasShortcut() returns false if a InputOption exists for the given shortcut');
    }

    public function testGetOptionForShortcut()
    {
        $this->initializeOptions();

        $definition = new InputDefinition(array($this->foo));
        $this->assertEquals($this->foo, $definition->getOptionForShortcut('f'), '->getOptionForShortcut() returns a InputOption by its shortcut');
    }

    public function testGetOptionForMultiShortcut()
    {
        $this->initializeOptions();

        $definition = new InputDefinition(array($this->multi));
        $this->assertEquals($this->multi, $definition->getOptionForShortcut('m'), '->getOptionForShortcut() returns a InputOption by its shortcut');
        $this->assertEquals($this->multi, $definition->getOptionForShortcut('mmm'), '->getOptionForShortcut() returns a InputOption by its shortcut');
    }

    /**
     * @expectedException        \InvalidArgumentException
     * @expectedExceptionMessage The "-l" option does not exist.
     */
    public function testGetOptionForInvalidShortcut()
    {
        $this->initializeOptions();

        $definition = new InputDefinition(array($this->foo));
        $definition->getOptionForShortcut('l');
    }

    public function testGetOptionDefaults()
    {
        $definition = new InputDefinition(array(
            new InputOption('foo1', null, InputOption::VALUE_NONE),
            new InputOption('foo2', null, InputOption::VALUE_REQUIRED),
            new InputOption('foo3', null, InputOption::VALUE_REQUIRED, '', 'default'),
            new InputOption('foo4', null, InputOption::VALUE_OPTIONAL),
            new InputOption('foo5', null, InputOption::VALUE_OPTIONAL, '', 'default'),
            new InputOption('foo6', null, InputOption::VALUE_OPTIONAL | InputOption::VALUE_IS_ARRAY),
            new InputOption('foo7', null, InputOption::VALUE_OPTIONAL | InputOption::VALUE_IS_ARRAY, '', array(1, 2)),
        ));
        $defaults = array(
            'foo1' => false,
            'foo2' => null,
            'foo3' => 'default',
            'foo4' => null,
            'foo5' => 'default',
            'foo6' => array(),
            'foo7' => array(1, 2),
        );
        $this->assertSame($defaults, $definition->getOptionDefaults(), '->getOptionDefaults() returns the default values for all options');
    }

    /**
     * @dataProvider getGetSynopsisData
     */
    public function testGetSynopsis(InputDefinition $definition, $expectedSynopsis, $message = null)
    {
        $this->assertEquals($expectedSynopsis, $definition->getSynopsis(), $message ? '->getSynopsis() '.$message : '');
    }

    public function getGetSynopsisData()
    {
        return array(
            array(new InputDefinition(array(new InputOption('foo'))), '[--foo]', 'puts optional options in square brackets'),
            array(new InputDefinition(array(new InputOption('foo', 'f'))), '[-f|--foo]', 'separates shortcut with a pipe'),
            array(new InputDefinition(array(new InputOption('foo', 'f', InputOption::VALUE_REQUIRED))), '[-f|--foo FOO]', 'uses shortcut as value placeholder'),
            array(new InputDefinition(array(new InputOption('foo', 'f', InputOption::VALUE_OPTIONAL))), '[-f|--foo [FOO]]', 'puts optional values in square brackets'),

            array(new InputDefinition(array(new InputArgument('foo', InputArgument::REQUIRED))), '<foo>', 'puts arguments in angle brackets'),
            array(new InputDefinition(array(new InputArgument('foo'))), '[<foo>]', 'puts optional arguments in square brackets'),
            array(new InputDefinition(array(new InputArgument('foo', InputArgument::IS_ARRAY))), '[<foo>]...', 'uses an ellipsis for array arguments'),
            array(new InputDefinition(array(new InputArgument('foo', InputArgument::REQUIRED | InputArgument::IS_ARRAY))), '<foo> (<foo>)...', 'uses parenthesis and ellipsis for required array arguments'),

            array(new InputDefinition(array(new InputOption('foo'), new InputArgument('foo', InputArgument::REQUIRED))), '[--foo] [--] <foo>', 'puts [--] between options and arguments'),
        );
    }

    public function testGetShortSynopsis()
    {
        $definition = new InputDefinition(array(new InputOption('foo'), new InputOption('bar'), new InputArgument('cat')));
        $this->assertEquals('[options] [--] [<cat>]', $definition->getSynopsis(true), '->getSynopsis(true) groups options in [options]');
    }

    /**
     * @group legacy
     */
    public function testLegacyAsText()
    {
        $definition = new InputDefinition(array(
            new InputArgument('foo', InputArgument::OPTIONAL, 'The foo argument'),
            new InputArgument('baz', InputArgument::OPTIONAL, 'The baz argument', true),
            new InputArgument('bar', InputArgument::OPTIONAL | InputArgument::IS_ARRAY, 'The bar argument', array('http://foo.com/')),
            new InputOption('foo', 'f', InputOption::VALUE_REQUIRED, 'The foo option'),
            new InputOption('baz', null, InputOption::VALUE_OPTIONAL, 'The baz option', false),
            new InputOption('bar', 'b', InputOption::VALUE_OPTIONAL, 'The bar option', 'bar'),
            new InputOption('qux', '', InputOption::VALUE_OPTIONAL | InputOption::VALUE_IS_ARRAY, 'The qux option', array('http://foo.com/', 'bar')),
            new InputOption('qux2', '', InputOption::VALUE_OPTIONAL | InputOption::VALUE_IS_ARRAY, 'The qux2 option', array('foo' => 'bar')),
        ));

        $this->assertStringEqualsFile(self::$fixtures.'/definition_astext.txt', $definition->asText(), '->asText() returns a textual representation of the InputDefinition');
    }

    /**
     * @group legacy
     */
    public function testLegacyAsXml()
    {
        $definition = new InputDefinition(array(
            new InputArgument('foo', InputArgument::OPTIONAL, 'The foo argument'),
            new InputArgument('baz', InputArgument::OPTIONAL, 'The baz argument', true),
            new InputArgument('bar', InputArgument::OPTIONAL | InputArgument::IS_ARRAY, 'The bar argument', array('bar')),
            new InputOption('foo', 'f', InputOption::VALUE_REQUIRED, 'The foo option'),
            new InputOption('baz', null, InputOption::VALUE_OPTIONAL, 'The baz option', false),
            new InputOption('bar', 'b', InputOption::VALUE_OPTIONAL, 'The bar option', 'bar'),
        ));
        $this->assertXmlStringEqualsXmlFile(self::$fixtures.'/definition_asxml.txt', $definition->asXml(), '->asXml() returns an XML representation of the InputDefinition');
    }

    protected function initializeArguments()
    {
        $this->foo = new InputArgument('foo');
        $this->bar = new InputArgument('bar');
        $this->foo1 = new InputArgument('foo');
        $this->foo2 = new InputArgument('foo2', InputArgument::REQUIRED);
    }

    protected function initializeOptions()
    {
        $this->foo = new InputOption('foo', 'f');
        $this->bar = new InputOption('bar', 'b');
        $this->foo1 = new InputOption('fooBis', 'f');
        $this->foo2 = new InputOption('foo', 'p');
        $this->multi = new InputOption('multi', 'm|mm|mmm');
    }
}
PKϤ$Z}ܑ�#�#'console/Tests/Input/InputOptionTest.phpnu�[���<?php

/*
 * This file is part of the Symfony package.
 *
 * (c) Fabien Potencier <fabien@symfony.com>
 *
 * For the full copyright and license information, please view the LICENSE
 * file that was distributed with this source code.
 */

namespace Symfony\Component\Console\Tests\Input;

use Symfony\Component\Console\Input\InputOption;

class InputOptionTest extends \PHPUnit_Framework_TestCase
{
    public function testConstructor()
    {
        $option = new InputOption('foo');
        $this->assertEquals('foo', $option->getName(), '__construct() takes a name as its first argument');
        $option = new InputOption('--foo');
        $this->assertEquals('foo', $option->getName(), '__construct() removes the leading -- of the option name');
    }

    /**
     * @expectedException        \InvalidArgumentException
     * @expectedExceptionMessage Impossible to have an option mode VALUE_IS_ARRAY if the option does not accept a value.
     */
    public function testArrayModeWithoutValue()
    {
        new InputOption('foo', 'f', InputOption::VALUE_IS_ARRAY);
    }

    public function testShortcut()
    {
        $option = new InputOption('foo', 'f');
        $this->assertEquals('f', $option->getShortcut(), '__construct() can take a shortcut as its second argument');
        $option = new InputOption('foo', '-f|-ff|fff');
        $this->assertEquals('f|ff|fff', $option->getShortcut(), '__construct() removes the leading - of the shortcuts');
        $option = new InputOption('foo', array('f', 'ff', '-fff'));
        $this->assertEquals('f|ff|fff', $option->getShortcut(), '__construct() removes the leading - of the shortcuts');
        $option = new InputOption('foo');
        $this->assertNull($option->getShortcut(), '__construct() makes the shortcut null by default');
    }

    public function testModes()
    {
        $option = new InputOption('foo', 'f');
        $this->assertFalse($option->acceptValue(), '__construct() gives a "InputOption::VALUE_NONE" mode by default');
        $this->assertFalse($option->isValueRequired(), '__construct() gives a "InputOption::VALUE_NONE" mode by default');
        $this->assertFalse($option->isValueOptional(), '__construct() gives a "InputOption::VALUE_NONE" mode by default');

        $option = new InputOption('foo', 'f', null);
        $this->assertFalse($option->acceptValue(), '__construct() can take "InputOption::VALUE_NONE" as its mode');
        $this->assertFalse($option->isValueRequired(), '__construct() can take "InputOption::VALUE_NONE" as its mode');
        $this->assertFalse($option->isValueOptional(), '__construct() can take "InputOption::VALUE_NONE" as its mode');

        $option = new InputOption('foo', 'f', InputOption::VALUE_NONE);
        $this->assertFalse($option->acceptValue(), '__construct() can take "InputOption::VALUE_NONE" as its mode');
        $this->assertFalse($option->isValueRequired(), '__construct() can take "InputOption::VALUE_NONE" as its mode');
        $this->assertFalse($option->isValueOptional(), '__construct() can take "InputOption::VALUE_NONE" as its mode');

        $option = new InputOption('foo', 'f', InputOption::VALUE_REQUIRED);
        $this->assertTrue($option->acceptValue(), '__construct() can take "InputOption::VALUE_REQUIRED" as its mode');
        $this->assertTrue($option->isValueRequired(), '__construct() can take "InputOption::VALUE_REQUIRED" as its mode');
        $this->assertFalse($option->isValueOptional(), '__construct() can take "InputOption::VALUE_REQUIRED" as its mode');

        $option = new InputOption('foo', 'f', InputOption::VALUE_OPTIONAL);
        $this->assertTrue($option->acceptValue(), '__construct() can take "InputOption::VALUE_OPTIONAL" as its mode');
        $this->assertFalse($option->isValueRequired(), '__construct() can take "InputOption::VALUE_OPTIONAL" as its mode');
        $this->assertTrue($option->isValueOptional(), '__construct() can take "InputOption::VALUE_OPTIONAL" as its mode');
    }

    /**
     * @dataProvider provideInvalidModes
     */
    public function testInvalidModes($mode)
    {
        $this->setExpectedException('InvalidArgumentException', sprintf('Option mode "%s" is not valid.', $mode));

        new InputOption('foo', 'f', $mode);
    }

    public function provideInvalidModes()
    {
        return array(
            array('ANOTHER_ONE'),
            array(-1),
        );
    }

    /**
     * @expectedException \InvalidArgumentException
     */
    public function testEmptyNameIsInvalid()
    {
        new InputOption('');
    }

    /**
     * @expectedException \InvalidArgumentException
     */
    public function testDoubleDashNameIsInvalid()
    {
        new InputOption('--');
    }

    /**
     * @expectedException \InvalidArgumentException
     */
    public function testSingleDashOptionIsInvalid()
    {
        new InputOption('foo', '-');
    }

    public function testIsArray()
    {
        $option = new InputOption('foo', null, InputOption::VALUE_OPTIONAL | InputOption::VALUE_IS_ARRAY);
        $this->assertTrue($option->isArray(), '->isArray() returns true if the option can be an array');
        $option = new InputOption('foo', null, InputOption::VALUE_NONE);
        $this->assertFalse($option->isArray(), '->isArray() returns false if the option can not be an array');
    }

    public function testGetDescription()
    {
        $option = new InputOption('foo', 'f', null, 'Some description');
        $this->assertEquals('Some description', $option->getDescription(), '->getDescription() returns the description message');
    }

    public function testGetDefault()
    {
        $option = new InputOption('foo', null, InputOption::VALUE_OPTIONAL, '', 'default');
        $this->assertEquals('default', $option->getDefault(), '->getDefault() returns the default value');

        $option = new InputOption('foo', null, InputOption::VALUE_REQUIRED, '', 'default');
        $this->assertEquals('default', $option->getDefault(), '->getDefault() returns the default value');

        $option = new InputOption('foo', null, InputOption::VALUE_REQUIRED);
        $this->assertNull($option->getDefault(), '->getDefault() returns null if no default value is configured');

        $option = new InputOption('foo', null, InputOption::VALUE_OPTIONAL | InputOption::VALUE_IS_ARRAY);
        $this->assertEquals(array(), $option->getDefault(), '->getDefault() returns an empty array if option is an array');

        $option = new InputOption('foo', null, InputOption::VALUE_NONE);
        $this->assertFalse($option->getDefault(), '->getDefault() returns false if the option does not take a value');
    }

    public function testSetDefault()
    {
        $option = new InputOption('foo', null, InputOption::VALUE_REQUIRED, '', 'default');
        $option->setDefault(null);
        $this->assertNull($option->getDefault(), '->setDefault() can reset the default value by passing null');
        $option->setDefault('another');
        $this->assertEquals('another', $option->getDefault(), '->setDefault() changes the default value');

        $option = new InputOption('foo', null, InputOption::VALUE_REQUIRED | InputOption::VALUE_IS_ARRAY);
        $option->setDefault(array(1, 2));
        $this->assertEquals(array(1, 2), $option->getDefault(), '->setDefault() changes the default value');
    }

    /**
     * @expectedException        \LogicException
     * @expectedExceptionMessage Cannot set a default value when using InputOption::VALUE_NONE mode.
     */
    public function testDefaultValueWithValueNoneMode()
    {
        $option = new InputOption('foo', 'f', InputOption::VALUE_NONE);
        $option->setDefault('default');
    }

    /**
     * @expectedException        \LogicException
     * @expectedExceptionMessage A default value for an array option must be an array.
     */
    public function testDefaultValueWithIsArrayMode()
    {
        $option = new InputOption('foo', 'f', InputOption::VALUE_OPTIONAL | InputOption::VALUE_IS_ARRAY);
        $option->setDefault('default');
    }

    public function testEquals()
    {
        $option = new InputOption('foo', 'f', null, 'Some description');
        $option2 = new InputOption('foo', 'f', null, 'Alternative description');
        $this->assertTrue($option->equals($option2));

        $option = new InputOption('foo', 'f', InputOption::VALUE_OPTIONAL, 'Some description');
        $option2 = new InputOption('foo', 'f', InputOption::VALUE_OPTIONAL, 'Some description', true);
        $this->assertFalse($option->equals($option2));

        $option = new InputOption('foo', 'f', null, 'Some description');
        $option2 = new InputOption('bar', 'f', null, 'Some description');
        $this->assertFalse($option->equals($option2));

        $option = new InputOption('foo', 'f', null, 'Some description');
        $option2 = new InputOption('foo', '', null, 'Some description');
        $this->assertFalse($option->equals($option2));

        $option = new InputOption('foo', 'f', null, 'Some description');
        $option2 = new InputOption('foo', 'f', InputOption::VALUE_OPTIONAL, 'Some description');
        $this->assertFalse($option->equals($option2));
    }
}
PKϤ$Zźgp;p;%console/Tests/Input/ArgvInputTest.phpnu�[���<?php

/*
 * This file is part of the Symfony package.
 *
 * (c) Fabien Potencier <fabien@symfony.com>
 *
 * For the full copyright and license information, please view the LICENSE
 * file that was distributed with this source code.
 */

namespace Symfony\Component\Console\Tests\Input;

use Symfony\Component\Console\Input\ArgvInput;
use Symfony\Component\Console\Input\InputDefinition;
use Symfony\Component\Console\Input\InputArgument;
use Symfony\Component\Console\Input\InputOption;

class ArgvInputTest extends \PHPUnit_Framework_TestCase
{
    public function testConstructor()
    {
        $_SERVER['argv'] = array('cli.php', 'foo');
        $input = new ArgvInput();
        $r = new \ReflectionObject($input);
        $p = $r->getProperty('tokens');
        $p->setAccessible(true);

        $this->assertEquals(array('foo'), $p->getValue($input), '__construct() automatically get its input from the argv server variable');
    }

    public function testParseArguments()
    {
        $input = new ArgvInput(array('cli.php', 'foo'));
        $input->bind(new InputDefinition(array(new InputArgument('name'))));
        $this->assertEquals(array('name' => 'foo'), $input->getArguments(), '->parse() parses required arguments');

        $input->bind(new InputDefinition(array(new InputArgument('name'))));
        $this->assertEquals(array('name' => 'foo'), $input->getArguments(), '->parse() is stateless');
    }

    /**
     * @dataProvider provideOptions
     */
    public function testParseOptions($input, $options, $expectedOptions, $message)
    {
        $input = new ArgvInput($input);
        $input->bind(new InputDefinition($options));

        $this->assertEquals($expectedOptions, $input->getOptions(), $message);
    }

    public function provideOptions()
    {
        return array(
            array(
                array('cli.php', '--foo'),
                array(new InputOption('foo')),
                array('foo' => true),
                '->parse() parses long options without a value',
            ),
            array(
                array('cli.php', '--foo=bar'),
                array(new InputOption('foo', 'f', InputOption::VALUE_REQUIRED)),
                array('foo' => 'bar'),
                '->parse() parses long options with a required value (with a = separator)',
            ),
            array(
                array('cli.php', '--foo', 'bar'),
                array(new InputOption('foo', 'f', InputOption::VALUE_REQUIRED)),
                array('foo' => 'bar'),
                '->parse() parses long options with a required value (with a space separator)',
            ),
            array(
                array('cli.php', '-f'),
                array(new InputOption('foo', 'f')),
                array('foo' => true),
                '->parse() parses short options without a value',
            ),
            array(
                array('cli.php', '-fbar'),
                array(new InputOption('foo', 'f', InputOption::VALUE_REQUIRED)),
                array('foo' => 'bar'),
                '->parse() parses short options with a required value (with no separator)',
            ),
            array(
                array('cli.php', '-f', 'bar'),
                array(new InputOption('foo', 'f', InputOption::VALUE_REQUIRED)),
                array('foo' => 'bar'),
                '->parse() parses short options with a required value (with a space separator)',
            ),
            array(
                array('cli.php', '-f', ''),
                array(new InputOption('foo', 'f', InputOption::VALUE_OPTIONAL)),
                array('foo' => ''),
                '->parse() parses short options with an optional empty value',
            ),
            array(
                array('cli.php', '-f', '', 'foo'),
                array(new InputArgument('name'), new InputOption('foo', 'f', InputOption::VALUE_OPTIONAL)),
                array('foo' => ''),
                '->parse() parses short options with an optional empty value followed by an argument',
            ),
            array(
                array('cli.php', '-f', '', '-b'),
                array(new InputOption('foo', 'f', InputOption::VALUE_OPTIONAL), new InputOption('bar', 'b')),
                array('foo' => '', 'bar' => true),
                '->parse() parses short options with an optional empty value followed by an option',
            ),
            array(
                array('cli.php', '-f', '-b', 'foo'),
                array(new InputArgument('name'), new InputOption('foo', 'f', InputOption::VALUE_OPTIONAL), new InputOption('bar', 'b')),
                array('foo' => null, 'bar' => true),
                '->parse() parses short options with an optional value which is not present',
            ),
            array(
                array('cli.php', '-fb'),
                array(new InputOption('foo', 'f'), new InputOption('bar', 'b')),
                array('foo' => true, 'bar' => true),
                '->parse() parses short options when they are aggregated as a single one',
            ),
            array(
                array('cli.php', '-fb', 'bar'),
                array(new InputOption('foo', 'f'), new InputOption('bar', 'b', InputOption::VALUE_REQUIRED)),
                array('foo' => true, 'bar' => 'bar'),
                '->parse() parses short options when they are aggregated as a single one and the last one has a required value',
            ),
            array(
                array('cli.php', '-fb', 'bar'),
                array(new InputOption('foo', 'f'), new InputOption('bar', 'b', InputOption::VALUE_OPTIONAL)),
                array('foo' => true, 'bar' => 'bar'),
                '->parse() parses short options when they are aggregated as a single one and the last one has an optional value',
            ),
            array(
                array('cli.php', '-fbbar'),
                array(new InputOption('foo', 'f'), new InputOption('bar', 'b', InputOption::VALUE_OPTIONAL)),
                array('foo' => true, 'bar' => 'bar'),
                '->parse() parses short options when they are aggregated as a single one and the last one has an optional value with no separator',
            ),
            array(
                array('cli.php', '-fbbar'),
                array(new InputOption('foo', 'f', InputOption::VALUE_OPTIONAL), new InputOption('bar', 'b', InputOption::VALUE_OPTIONAL)),
                array('foo' => 'bbar', 'bar' => null),
                '->parse() parses short options when they are aggregated as a single one and one of them takes a value',
            ),
        );
    }

    /**
     * @dataProvider provideInvalidInput
     */
    public function testInvalidInput($argv, $definition, $expectedExceptionMessage)
    {
        $this->setExpectedException('RuntimeException', $expectedExceptionMessage);

        $input = new ArgvInput($argv);
        $input->bind($definition);
    }

    public function provideInvalidInput()
    {
        return array(
            array(
                array('cli.php', '--foo'),
                new InputDefinition(array(new InputOption('foo', 'f', InputOption::VALUE_REQUIRED))),
                'The "--foo" option requires a value.',
            ),
            array(
                array('cli.php', '-f'),
                new InputDefinition(array(new InputOption('foo', 'f', InputOption::VALUE_REQUIRED))),
                'The "--foo" option requires a value.',
            ),
            array(
                array('cli.php', '-ffoo'),
                new InputDefinition(array(new InputOption('foo', 'f', InputOption::VALUE_NONE))),
                'The "-o" option does not exist.',
            ),
            array(
                array('cli.php', '--foo=bar'),
                new InputDefinition(array(new InputOption('foo', 'f', InputOption::VALUE_NONE))),
                'The "--foo" option does not accept a value.',
            ),
            array(
                array('cli.php', 'foo', 'bar'),
                new InputDefinition(),
                'Too many arguments.',
            ),
            array(
                array('cli.php', '--foo'),
                new InputDefinition(),
                'The "--foo" option does not exist.',
            ),
            array(
                array('cli.php', '-f'),
                new InputDefinition(),
                'The "-f" option does not exist.',
            ),
            array(
                array('cli.php', '-1'),
                new InputDefinition(array(new InputArgument('number'))),
                'The "-1" option does not exist.',
            ),
        );
    }

    public function testParseArrayArgument()
    {
        $input = new ArgvInput(array('cli.php', 'foo', 'bar', 'baz', 'bat'));
        $input->bind(new InputDefinition(array(new InputArgument('name', InputArgument::IS_ARRAY))));

        $this->assertEquals(array('name' => array('foo', 'bar', 'baz', 'bat')), $input->getArguments(), '->parse() parses array arguments');
    }

    public function testParseArrayOption()
    {
        $input = new ArgvInput(array('cli.php', '--name=foo', '--name=bar', '--name=baz'));
        $input->bind(new InputDefinition(array(new InputOption('name', null, InputOption::VALUE_OPTIONAL | InputOption::VALUE_IS_ARRAY))));

        $this->assertEquals(array('name' => array('foo', 'bar', 'baz')), $input->getOptions(), '->parse() parses array options ("--option=value" syntax)');

        $input = new ArgvInput(array('cli.php', '--name', 'foo', '--name', 'bar', '--name', 'baz'));
        $input->bind(new InputDefinition(array(new InputOption('name', null, InputOption::VALUE_OPTIONAL | InputOption::VALUE_IS_ARRAY))));
        $this->assertEquals(array('name' => array('foo', 'bar', 'baz')), $input->getOptions(), '->parse() parses array options ("--option value" syntax)');

        $input = new ArgvInput(array('cli.php', '--name=foo', '--name=bar', '--name='));
        $input->bind(new InputDefinition(array(new InputOption('name', null, InputOption::VALUE_OPTIONAL | InputOption::VALUE_IS_ARRAY))));
        $this->assertSame(array('name' => array('foo', 'bar', null)), $input->getOptions(), '->parse() parses empty array options as null ("--option=value" syntax)');

        $input = new ArgvInput(array('cli.php', '--name', 'foo', '--name', 'bar', '--name', '--anotherOption'));
        $input->bind(new InputDefinition(array(
            new InputOption('name', null, InputOption::VALUE_OPTIONAL | InputOption::VALUE_IS_ARRAY),
            new InputOption('anotherOption', null, InputOption::VALUE_NONE),
        )));
        $this->assertSame(array('name' => array('foo', 'bar', null), 'anotherOption' => true), $input->getOptions(), '->parse() parses empty array options as null ("--option value" syntax)');
    }

    public function testParseNegativeNumberAfterDoubleDash()
    {
        $input = new ArgvInput(array('cli.php', '--', '-1'));
        $input->bind(new InputDefinition(array(new InputArgument('number'))));
        $this->assertEquals(array('number' => '-1'), $input->getArguments(), '->parse() parses arguments with leading dashes as arguments after having encountered a double-dash sequence');

        $input = new ArgvInput(array('cli.php', '-f', 'bar', '--', '-1'));
        $input->bind(new InputDefinition(array(new InputArgument('number'), new InputOption('foo', 'f', InputOption::VALUE_OPTIONAL))));
        $this->assertEquals(array('foo' => 'bar'), $input->getOptions(), '->parse() parses arguments with leading dashes as options before having encountered a double-dash sequence');
        $this->assertEquals(array('number' => '-1'), $input->getArguments(), '->parse() parses arguments with leading dashes as arguments after having encountered a double-dash sequence');
    }

    public function testParseEmptyStringArgument()
    {
        $input = new ArgvInput(array('cli.php', '-f', 'bar', ''));
        $input->bind(new InputDefinition(array(new InputArgument('empty'), new InputOption('foo', 'f', InputOption::VALUE_OPTIONAL))));

        $this->assertEquals(array('empty' => ''), $input->getArguments(), '->parse() parses empty string arguments');
    }

    public function testGetFirstArgument()
    {
        $input = new ArgvInput(array('cli.php', '-fbbar'));
        $this->assertNull($input->getFirstArgument(), '->getFirstArgument() returns null when there is no arguments');

        $input = new ArgvInput(array('cli.php', '-fbbar', 'foo'));
        $this->assertEquals('foo', $input->getFirstArgument(), '->getFirstArgument() returns the first argument from the raw input');
    }

    public function testHasParameterOption()
    {
        $input = new ArgvInput(array('cli.php', '-f', 'foo'));
        $this->assertTrue($input->hasParameterOption('-f'), '->hasParameterOption() returns true if the given short option is in the raw input');

        $input = new ArgvInput(array('cli.php', '--foo', 'foo'));
        $this->assertTrue($input->hasParameterOption('--foo'), '->hasParameterOption() returns true if the given short option is in the raw input');

        $input = new ArgvInput(array('cli.php', 'foo'));
        $this->assertFalse($input->hasParameterOption('--foo'), '->hasParameterOption() returns false if the given short option is not in the raw input');

        $input = new ArgvInput(array('cli.php', '--foo=bar'));
        $this->assertTrue($input->hasParameterOption('--foo'), '->hasParameterOption() returns true if the given option with provided value is in the raw input');
    }

    public function testToString()
    {
        $input = new ArgvInput(array('cli.php', '-f', 'foo'));
        $this->assertEquals('-f foo', (string) $input);

        $input = new ArgvInput(array('cli.php', '-f', '--bar=foo', 'a b c d', "A\nB'C"));
        $this->assertEquals('-f --bar=foo '.escapeshellarg('a b c d').' '.escapeshellarg("A\nB'C"), (string) $input);
    }

    /**
     * @dataProvider provideGetParameterOptionValues
     */
    public function testGetParameterOptionEqualSign($argv, $key, $expected)
    {
        $input = new ArgvInput($argv);
        $this->assertEquals($expected, $input->getParameterOption($key), '->getParameterOption() returns the expected value');
    }

    public function provideGetParameterOptionValues()
    {
        return array(
            array(array('app/console', 'foo:bar', '-e', 'dev'), '-e', 'dev'),
            array(array('app/console', 'foo:bar', '--env=dev'), '--env', 'dev'),
            array(array('app/console', 'foo:bar', '-e', 'dev'), array('-e', '--env'), 'dev'),
            array(array('app/console', 'foo:bar', '--env=dev'), array('-e', '--env'), 'dev'),
            array(array('app/console', 'foo:bar', '--env=dev', '--en=1'), array('--en'), '1'),
            array(array('app/console', 'foo:bar', '--env=dev', '', '--en=1'), array('--en'), '1'),
        );
    }

    public function testParseSingleDashAsArgument()
    {
        $input = new ArgvInput(array('cli.php', '-'));
        $input->bind(new InputDefinition(array(new InputArgument('file'))));
        $this->assertEquals(array('file' => '-'), $input->getArguments(), '->parse() parses single dash as an argument');
    }
}
PKϤ$Z�TF�*�*.console/Tests/Helper/LegacyTableHelperTest.phpnu�[���<?php

/*
 * This file is part of the Symfony package.
 *
 * (c) Fabien Potencier <fabien@symfony.com>
 *
 * For the full copyright and license information, please view the LICENSE
 * file that was distributed with this source code.
 */

namespace Symfony\Component\Console\Tests\Helper;

use Symfony\Component\Console\Helper\TableHelper;
use Symfony\Component\Console\Output\StreamOutput;

/**
 * @group legacy
 */
class LegacyTableHelperTest extends \PHPUnit_Framework_TestCase
{
    protected $stream;

    protected function setUp()
    {
        $this->stream = fopen('php://memory', 'r+');
    }

    protected function tearDown()
    {
        fclose($this->stream);
        $this->stream = null;
    }

    /**
     * @dataProvider testRenderProvider
     */
    public function testRender($headers, $rows, $layout, $expected)
    {
        $table = new TableHelper();
        $table
            ->setHeaders($headers)
            ->setRows($rows)
            ->setLayout($layout)
        ;
        $table->render($output = $this->getOutputStream());

        $this->assertEquals($expected, $this->getOutputContent($output));
    }

    /**
     * @dataProvider testRenderProvider
     */
    public function testRenderAddRows($headers, $rows, $layout, $expected)
    {
        $table = new TableHelper();
        $table
            ->setHeaders($headers)
            ->addRows($rows)
            ->setLayout($layout)
        ;
        $table->render($output = $this->getOutputStream());

        $this->assertEquals($expected, $this->getOutputContent($output));
    }

    /**
     * @dataProvider testRenderProvider
     */
    public function testRenderAddRowsOneByOne($headers, $rows, $layout, $expected)
    {
        $table = new TableHelper();
        $table
            ->setHeaders($headers)
            ->setLayout($layout)
        ;
        foreach ($rows as $row) {
            $table->addRow($row);
        }
        $table->render($output = $this->getOutputStream());

        $this->assertEquals($expected, $this->getOutputContent($output));
    }

    public function testRenderProvider()
    {
        $books = array(
            array('99921-58-10-7', 'Divine Comedy', 'Dante Alighieri'),
            array('9971-5-0210-0', 'A Tale of Two Cities', 'Charles Dickens'),
            array('960-425-059-0', 'The Lord of the Rings', 'J. R. R. Tolkien'),
            array('80-902734-1-6', 'And Then There Were None', 'Agatha Christie'),
        );

        return array(
            array(
                array('ISBN', 'Title', 'Author'),
                $books,
                TableHelper::LAYOUT_DEFAULT,
<<<'TABLE'
+---------------+--------------------------+------------------+
| ISBN          | Title                    | Author           |
+---------------+--------------------------+------------------+
| 99921-58-10-7 | Divine Comedy            | Dante Alighieri  |
| 9971-5-0210-0 | A Tale of Two Cities     | Charles Dickens  |
| 960-425-059-0 | The Lord of the Rings    | J. R. R. Tolkien |
| 80-902734-1-6 | And Then There Were None | Agatha Christie  |
+---------------+--------------------------+------------------+

TABLE
            ),
            array(
                array('ISBN', 'Title', 'Author'),
                $books,
                TableHelper::LAYOUT_COMPACT,
<<<TABLE
 ISBN          Title                    Author           
 99921-58-10-7 Divine Comedy            Dante Alighieri  
 9971-5-0210-0 A Tale of Two Cities     Charles Dickens  
 960-425-059-0 The Lord of the Rings    J. R. R. Tolkien 
 80-902734-1-6 And Then There Were None Agatha Christie  

TABLE
            ),
            array(
                array('ISBN', 'Title', 'Author'),
                $books,
                TableHelper::LAYOUT_BORDERLESS,
<<<TABLE
 =============== ========================== ================== 
  ISBN            Title                      Author            
 =============== ========================== ================== 
  99921-58-10-7   Divine Comedy              Dante Alighieri   
  9971-5-0210-0   A Tale of Two Cities       Charles Dickens   
  960-425-059-0   The Lord of the Rings      J. R. R. Tolkien  
  80-902734-1-6   And Then There Were None   Agatha Christie   
 =============== ========================== ================== 

TABLE
            ),
            array(
                array('ISBN', 'Title'),
                array(
                    array('99921-58-10-7', 'Divine Comedy', 'Dante Alighieri'),
                    array('9971-5-0210-0'),
                    array('960-425-059-0', 'The Lord of the Rings', 'J. R. R. Tolkien'),
                    array('80-902734-1-6', 'And Then There Were None', 'Agatha Christie'),
                ),
                TableHelper::LAYOUT_DEFAULT,
<<<'TABLE'
+---------------+--------------------------+------------------+
| ISBN          | Title                    |                  |
+---------------+--------------------------+------------------+
| 99921-58-10-7 | Divine Comedy            | Dante Alighieri  |
| 9971-5-0210-0 |                          |                  |
| 960-425-059-0 | The Lord of the Rings    | J. R. R. Tolkien |
| 80-902734-1-6 | And Then There Were None | Agatha Christie  |
+---------------+--------------------------+------------------+

TABLE
            ),
            array(
                array(),
                array(
                    array('99921-58-10-7', 'Divine Comedy', 'Dante Alighieri'),
                    array('9971-5-0210-0'),
                    array('960-425-059-0', 'The Lord of the Rings', 'J. R. R. Tolkien'),
                    array('80-902734-1-6', 'And Then There Were None', 'Agatha Christie'),
                ),
                TableHelper::LAYOUT_DEFAULT,
<<<'TABLE'
+---------------+--------------------------+------------------+
| 99921-58-10-7 | Divine Comedy            | Dante Alighieri  |
| 9971-5-0210-0 |                          |                  |
| 960-425-059-0 | The Lord of the Rings    | J. R. R. Tolkien |
| 80-902734-1-6 | And Then There Were None | Agatha Christie  |
+---------------+--------------------------+------------------+

TABLE
            ),
            array(
                array('ISBN', 'Title', 'Author'),
                array(
                    array('99921-58-10-7', "Divine\nComedy", 'Dante Alighieri'),
                    array('9971-5-0210-2', "Harry Potter\nand the Chamber of Secrets", "Rowling\nJoanne K."),
                    array('9971-5-0210-2', "Harry Potter\nand the Chamber of Secrets", "Rowling\nJoanne K."),
                    array('960-425-059-0', 'The Lord of the Rings', "J. R. R.\nTolkien"),
                ),
                TableHelper::LAYOUT_DEFAULT,
<<<'TABLE'
+---------------+----------------------------+-----------------+
| ISBN          | Title                      | Author          |
+---------------+----------------------------+-----------------+
| 99921-58-10-7 | Divine                     | Dante Alighieri |
|               | Comedy                     |                 |
| 9971-5-0210-2 | Harry Potter               | Rowling         |
|               | and the Chamber of Secrets | Joanne K.       |
| 9971-5-0210-2 | Harry Potter               | Rowling         |
|               | and the Chamber of Secrets | Joanne K.       |
| 960-425-059-0 | The Lord of the Rings      | J. R. R.        |
|               |                            | Tolkien         |
+---------------+----------------------------+-----------------+

TABLE
            ),
            array(
                array('ISBN', 'Title'),
                array(),
                TableHelper::LAYOUT_DEFAULT,
<<<'TABLE'
+------+-------+
| ISBN | Title |
+------+-------+

TABLE
            ),
            array(
                array(),
                array(),
                TableHelper::LAYOUT_DEFAULT,
                '',
            ),
            'Cell text with tags used for Output styling' => array(
                array('ISBN', 'Title', 'Author'),
                array(
                    array('<info>99921-58-10-7</info>', '<error>Divine Comedy</error>', '<fg=blue;bg=white>Dante Alighieri</fg=blue;bg=white>'),
                    array('9971-5-0210-0', 'A Tale of Two Cities', '<info>Charles Dickens</>'),
                ),
                TableHelper::LAYOUT_DEFAULT,
<<<'TABLE'
+---------------+----------------------+-----------------+
| ISBN          | Title                | Author          |
+---------------+----------------------+-----------------+
| 99921-58-10-7 | Divine Comedy        | Dante Alighieri |
| 9971-5-0210-0 | A Tale of Two Cities | Charles Dickens |
+---------------+----------------------+-----------------+

TABLE
            ),
            'Cell text with tags not used for Output styling' => array(
                array('ISBN', 'Title', 'Author'),
                array(
                    array('<strong>99921-58-10-700</strong>', '<f>Divine Com</f>', 'Dante Alighieri'),
                    array('9971-5-0210-0', 'A Tale of Two Cities', 'Charles Dickens'),
                ),
                TableHelper::LAYOUT_DEFAULT,
<<<'TABLE'
+----------------------------------+----------------------+-----------------+
| ISBN                             | Title                | Author          |
+----------------------------------+----------------------+-----------------+
| <strong>99921-58-10-700</strong> | <f>Divine Com</f>    | Dante Alighieri |
| 9971-5-0210-0                    | A Tale of Two Cities | Charles Dickens |
+----------------------------------+----------------------+-----------------+

TABLE
            ),
        );
    }

    public function testRenderMultiByte()
    {
        $table = new TableHelper();
        $table
            ->setHeaders(array('■■'))
            ->setRows(array(array(1234)))
            ->setLayout(TableHelper::LAYOUT_DEFAULT)
        ;
        $table->render($output = $this->getOutputStream());

        $expected =
<<<'TABLE'
+------+
| ■■   |
+------+
| 1234 |
+------+

TABLE;

        $this->assertEquals($expected, $this->getOutputContent($output));
    }

    public function testRenderFullWidthCharacters()
    {
        $table = new TableHelper();
        $table
            ->setHeaders(array('あいうえお'))
            ->setRows(array(array(1234567890)))
            ->setLayout(TableHelper::LAYOUT_DEFAULT)
        ;
        $table->render($output = $this->getOutputStream());

        $expected =
            <<<'TABLE'
+------------+
| あいうえお |
+------------+
| 1234567890 |
+------------+

TABLE;

        $this->assertEquals($expected, $this->getOutputContent($output));
    }

    protected function getOutputStream()
    {
        return new StreamOutput($this->stream, StreamOutput::VERBOSITY_NORMAL, false);
    }

    protected function getOutputContent(StreamOutput $output)
    {
        rewind($output->getStream());

        return str_replace(PHP_EOL, "\n", stream_get_contents($output->getStream()));
    }
}
PKϤ$Z���PtFtF+console/Tests/Helper/QuestionHelperTest.phpnu�[���<?php

/*
 * This file is part of the Symfony package.
 *
 * (c) Fabien Potencier <fabien@symfony.com>
 *
 * For the full copyright and license information, please view the LICENSE
 * file that was distributed with this source code.
 */

namespace Symfony\Component\Console\Tests\Helper;

use Symfony\Component\Console\Formatter\OutputFormatter;
use Symfony\Component\Console\Helper\QuestionHelper;
use Symfony\Component\Console\Helper\HelperSet;
use Symfony\Component\Console\Helper\FormatterHelper;
use Symfony\Component\Console\Output\StreamOutput;
use Symfony\Component\Console\Question\ChoiceQuestion;
use Symfony\Component\Console\Question\ConfirmationQuestion;
use Symfony\Component\Console\Question\Question;

/**
 * @group tty
 */
class QuestionHelperTest extends \PHPUnit_Framework_TestCase
{
    public function testAskChoice()
    {
        $questionHelper = new QuestionHelper();

        $helperSet = new HelperSet(array(new FormatterHelper()));
        $questionHelper->setHelperSet($helperSet);

        $heroes = array('Superman', 'Batman', 'Spiderman');

        $questionHelper->setInputStream($this->getInputStream("\n1\n  1  \nFabien\n1\nFabien\n1\n0,2\n 0 , 2  \n\n\n"));

        $question = new ChoiceQuestion('What is your favorite superhero?', $heroes, '2');
        $question->setMaxAttempts(1);
        // first answer is an empty answer, we're supposed to receive the default value
        $this->assertEquals('Spiderman', $questionHelper->ask($this->createInputInterfaceMock(), $this->createOutputInterface(), $question));

        $question = new ChoiceQuestion('What is your favorite superhero?', $heroes);
        $question->setMaxAttempts(1);
        $this->assertEquals('Batman', $questionHelper->ask($this->createInputInterfaceMock(), $this->createOutputInterface(), $question));
        $this->assertEquals('Batman', $questionHelper->ask($this->createInputInterfaceMock(), $this->createOutputInterface(), $question));

        $question = new ChoiceQuestion('What is your favorite superhero?', $heroes);
        $question->setErrorMessage('Input "%s" is not a superhero!');
        $question->setMaxAttempts(2);
        $this->assertEquals('Batman', $questionHelper->ask($this->createInputInterfaceMock(), $output = $this->createOutputInterface(), $question));

        rewind($output->getStream());
        $stream = stream_get_contents($output->getStream());
        $this->assertContains('Input "Fabien" is not a superhero!', $stream);

        try {
            $question = new ChoiceQuestion('What is your favorite superhero?', $heroes, '1');
            $question->setMaxAttempts(1);
            $questionHelper->ask($this->createInputInterfaceMock(), $output = $this->createOutputInterface(), $question);
            $this->fail();
        } catch (\InvalidArgumentException $e) {
            $this->assertEquals('Value "Fabien" is invalid', $e->getMessage());
        }

        $question = new ChoiceQuestion('What is your favorite superhero?', $heroes, null);
        $question->setMaxAttempts(1);
        $question->setMultiselect(true);

        $this->assertEquals(array('Batman'), $questionHelper->ask($this->createInputInterfaceMock(), $this->createOutputInterface(), $question));
        $this->assertEquals(array('Superman', 'Spiderman'), $questionHelper->ask($this->createInputInterfaceMock(), $this->createOutputInterface(), $question));
        $this->assertEquals(array('Superman', 'Spiderman'), $questionHelper->ask($this->createInputInterfaceMock(), $this->createOutputInterface(), $question));

        $question = new ChoiceQuestion('What is your favorite superhero?', $heroes, '0,1');
        $question->setMaxAttempts(1);
        $question->setMultiselect(true);

        $this->assertEquals(array('Superman', 'Batman'), $questionHelper->ask($this->createInputInterfaceMock(), $this->createOutputInterface(), $question));

        $question = new ChoiceQuestion('What is your favorite superhero?', $heroes, ' 0 , 1 ');
        $question->setMaxAttempts(1);
        $question->setMultiselect(true);

        $this->assertEquals(array('Superman', 'Batman'), $questionHelper->ask($this->createInputInterfaceMock(), $this->createOutputInterface(), $question));
    }

    public function testAsk()
    {
        $dialog = new QuestionHelper();

        $dialog->setInputStream($this->getInputStream("\n8AM\n"));

        $question = new Question('What time is it?', '2PM');
        $this->assertEquals('2PM', $dialog->ask($this->createInputInterfaceMock(), $this->createOutputInterface(), $question));

        $question = new Question('What time is it?', '2PM');
        $this->assertEquals('8AM', $dialog->ask($this->createInputInterfaceMock(), $output = $this->createOutputInterface(), $question));

        rewind($output->getStream());
        $this->assertEquals('What time is it?', stream_get_contents($output->getStream()));
    }

    public function testAskWithAutocomplete()
    {
        if (!$this->hasSttyAvailable()) {
            $this->markTestSkipped('`stty` is required to test autocomplete functionality');
        }

        // Acm<NEWLINE>
        // Ac<BACKSPACE><BACKSPACE>s<TAB>Test<NEWLINE>
        // <NEWLINE>
        // <UP ARROW><UP ARROW><NEWLINE>
        // <UP ARROW><UP ARROW><UP ARROW><UP ARROW><UP ARROW><TAB>Test<NEWLINE>
        // <DOWN ARROW><NEWLINE>
        // S<BACKSPACE><BACKSPACE><DOWN ARROW><DOWN ARROW><NEWLINE>
        // F00<BACKSPACE><BACKSPACE>oo<TAB><NEWLINE>
        $inputStream = $this->getInputStream("Acm\nAc\177\177s\tTest\n\n\033[A\033[A\n\033[A\033[A\033[A\033[A\033[A\tTest\n\033[B\nS\177\177\033[B\033[B\nF00\177\177oo\t\n");

        $dialog = new QuestionHelper();
        $dialog->setInputStream($inputStream);
        $helperSet = new HelperSet(array(new FormatterHelper()));
        $dialog->setHelperSet($helperSet);

        $question = new Question('Please select a bundle', 'FrameworkBundle');
        $question->setAutocompleterValues(array('AcmeDemoBundle', 'AsseticBundle', 'SecurityBundle', 'FooBundle'));

        $this->assertEquals('AcmeDemoBundle', $dialog->ask($this->createInputInterfaceMock(), $this->createOutputInterface(), $question));
        $this->assertEquals('AsseticBundleTest', $dialog->ask($this->createInputInterfaceMock(), $this->createOutputInterface(), $question));
        $this->assertEquals('FrameworkBundle', $dialog->ask($this->createInputInterfaceMock(), $this->createOutputInterface(), $question));
        $this->assertEquals('SecurityBundle', $dialog->ask($this->createInputInterfaceMock(), $this->createOutputInterface(), $question));
        $this->assertEquals('FooBundleTest', $dialog->ask($this->createInputInterfaceMock(), $this->createOutputInterface(), $question));
        $this->assertEquals('AcmeDemoBundle', $dialog->ask($this->createInputInterfaceMock(), $this->createOutputInterface(), $question));
        $this->assertEquals('AsseticBundle', $dialog->ask($this->createInputInterfaceMock(), $this->createOutputInterface(), $question));
        $this->assertEquals('FooBundle', $dialog->ask($this->createInputInterfaceMock(), $this->createOutputInterface(), $question));
    }

    public function testAskWithAutocompleteWithNonSequentialKeys()
    {
        if (!$this->hasSttyAvailable()) {
            $this->markTestSkipped('`stty` is required to test autocomplete functionality');
        }

        // <UP ARROW><UP ARROW><NEWLINE><DOWN ARROW><DOWN ARROW><NEWLINE>
        $inputStream = $this->getInputStream("\033[A\033[A\n\033[B\033[B\n");

        $dialog = new QuestionHelper();
        $dialog->setInputStream($inputStream);
        $dialog->setHelperSet(new HelperSet(array(new FormatterHelper())));

        $question = new ChoiceQuestion('Please select a bundle', array(1 => 'AcmeDemoBundle', 4 => 'AsseticBundle'));
        $question->setMaxAttempts(1);

        $this->assertEquals('AcmeDemoBundle', $dialog->ask($this->createInputInterfaceMock(), $this->createOutputInterface(), $question));
        $this->assertEquals('AsseticBundle', $dialog->ask($this->createInputInterfaceMock(), $this->createOutputInterface(), $question));
    }

    public function testAskHiddenResponse()
    {
        if ('\\' === DIRECTORY_SEPARATOR) {
            $this->markTestSkipped('This test is not supported on Windows');
        }

        $dialog = new QuestionHelper();
        $dialog->setInputStream($this->getInputStream("8AM\n"));

        $question = new Question('What time is it?');
        $question->setHidden(true);

        $this->assertEquals('8AM', $dialog->ask($this->createInputInterfaceMock(), $this->createOutputInterface(), $question));
    }

    /**
     * @dataProvider getAskConfirmationData
     */
    public function testAskConfirmation($question, $expected, $default = true)
    {
        $dialog = new QuestionHelper();

        $dialog->setInputStream($this->getInputStream($question."\n"));
        $question = new ConfirmationQuestion('Do you like French fries?', $default);
        $this->assertEquals($expected, $dialog->ask($this->createInputInterfaceMock(), $this->createOutputInterface(), $question), 'confirmation question should '.($expected ? 'pass' : 'cancel'));
    }

    public function getAskConfirmationData()
    {
        return array(
            array('', true),
            array('', false, false),
            array('y', true),
            array('yes', true),
            array('n', false),
            array('no', false),
        );
    }

    public function testAskConfirmationWithCustomTrueAnswer()
    {
        $dialog = new QuestionHelper();

        $dialog->setInputStream($this->getInputStream("j\ny\n"));
        $question = new ConfirmationQuestion('Do you like French fries?', false, '/^(j|y)/i');
        $this->assertTrue($dialog->ask($this->createInputInterfaceMock(), $this->createOutputInterface(), $question));
        $question = new ConfirmationQuestion('Do you like French fries?', false, '/^(j|y)/i');
        $this->assertTrue($dialog->ask($this->createInputInterfaceMock(), $this->createOutputInterface(), $question));
    }

    public function testAskAndValidate()
    {
        $dialog = new QuestionHelper();
        $helperSet = new HelperSet(array(new FormatterHelper()));
        $dialog->setHelperSet($helperSet);

        $error = 'This is not a color!';
        $validator = function ($color) use ($error) {
            if (!in_array($color, array('white', 'black'))) {
                throw new \InvalidArgumentException($error);
            }

            return $color;
        };

        $question = new Question('What color was the white horse of Henry IV?', 'white');
        $question->setValidator($validator);
        $question->setMaxAttempts(2);

        $dialog->setInputStream($this->getInputStream("\nblack\n"));
        $this->assertEquals('white', $dialog->ask($this->createInputInterfaceMock(), $this->createOutputInterface(), $question));
        $this->assertEquals('black', $dialog->ask($this->createInputInterfaceMock(), $this->createOutputInterface(), $question));

        $dialog->setInputStream($this->getInputStream("green\nyellow\norange\n"));
        try {
            $dialog->ask($this->createInputInterfaceMock(), $this->createOutputInterface(), $question);
            $this->fail();
        } catch (\InvalidArgumentException $e) {
            $this->assertEquals($error, $e->getMessage());
        }
    }

    /**
     * @dataProvider simpleAnswerProvider
     */
    public function testSelectChoiceFromSimpleChoices($providedAnswer, $expectedValue)
    {
        $possibleChoices = array(
            'My environment 1',
            'My environment 2',
            'My environment 3',
        );

        $dialog = new QuestionHelper();
        $dialog->setInputStream($this->getInputStream($providedAnswer."\n"));
        $helperSet = new HelperSet(array(new FormatterHelper()));
        $dialog->setHelperSet($helperSet);

        $question = new ChoiceQuestion('Please select the environment to load', $possibleChoices);
        $question->setMaxAttempts(1);
        $answer = $dialog->ask($this->createInputInterfaceMock(), $this->createOutputInterface(), $question);

        $this->assertSame($expectedValue, $answer);
    }

    public function simpleAnswerProvider()
    {
        return array(
            array(0, 'My environment 1'),
            array(1, 'My environment 2'),
            array(2, 'My environment 3'),
            array('My environment 1', 'My environment 1'),
            array('My environment 2', 'My environment 2'),
            array('My environment 3', 'My environment 3'),
        );
    }

    /**
     * @dataProvider mixedKeysChoiceListAnswerProvider
     */
    public function testChoiceFromChoicelistWithMixedKeys($providedAnswer, $expectedValue)
    {
        $possibleChoices = array(
            '0' => 'No environment',
            '1' => 'My environment 1',
            'env_2' => 'My environment 2',
            3 => 'My environment 3',
        );

        $dialog = new QuestionHelper();
        $dialog->setInputStream($this->getInputStream($providedAnswer."\n"));
        $helperSet = new HelperSet(array(new FormatterHelper()));
        $dialog->setHelperSet($helperSet);

        $question = new ChoiceQuestion('Please select the environment to load', $possibleChoices);
        $question->setMaxAttempts(1);
        $answer = $dialog->ask($this->createInputInterfaceMock(), $this->createOutputInterface(), $question);

        $this->assertSame($expectedValue, $answer);
    }

    public function mixedKeysChoiceListAnswerProvider()
    {
        return array(
            array('0', '0'),
            array('No environment', '0'),
            array('1', '1'),
            array('env_2', 'env_2'),
            array(3, '3'),
            array('My environment 1', '1'),
        );
    }

    /**
     * @dataProvider answerProvider
     */
    public function testSelectChoiceFromChoiceList($providedAnswer, $expectedValue)
    {
        $possibleChoices = array(
            'env_1' => 'My environment 1',
            'env_2' => 'My environment',
            'env_3' => 'My environment',
        );

        $dialog = new QuestionHelper();
        $dialog->setInputStream($this->getInputStream($providedAnswer."\n"));
        $helperSet = new HelperSet(array(new FormatterHelper()));
        $dialog->setHelperSet($helperSet);

        $question = new ChoiceQuestion('Please select the environment to load', $possibleChoices);
        $question->setMaxAttempts(1);
        $answer = $dialog->ask($this->createInputInterfaceMock(), $this->createOutputInterface(), $question);

        $this->assertSame($expectedValue, $answer);
    }

    /**
     * @expectedException        \InvalidArgumentException
     * @expectedExceptionMessage The provided answer is ambiguous. Value should be one of env_2 or env_3.
     */
    public function testAmbiguousChoiceFromChoicelist()
    {
        $possibleChoices = array(
            'env_1' => 'My first environment',
            'env_2' => 'My environment',
            'env_3' => 'My environment',
        );

        $dialog = new QuestionHelper();
        $dialog->setInputStream($this->getInputStream("My environment\n"));
        $helperSet = new HelperSet(array(new FormatterHelper()));
        $dialog->setHelperSet($helperSet);

        $question = new ChoiceQuestion('Please select the environment to load', $possibleChoices);
        $question->setMaxAttempts(1);

        $dialog->ask($this->createInputInterfaceMock(), $this->createOutputInterface(), $question);
    }

    public function answerProvider()
    {
        return array(
            array('env_1', 'env_1'),
            array('env_2', 'env_2'),
            array('env_3', 'env_3'),
            array('My environment 1', 'env_1'),
        );
    }

    public function testNoInteraction()
    {
        $dialog = new QuestionHelper();
        $question = new Question('Do you have a job?', 'not yet');
        $this->assertEquals('not yet', $dialog->ask($this->createInputInterfaceMock(false), $this->createOutputInterface(), $question));
    }

    /**
     * @requires function mb_strwidth
     */
    public function testChoiceOutputFormattingQuestionForUtf8Keys()
    {
        $question = 'Lorem ipsum?';
        $possibleChoices = array(
            'foo' => 'foo',
            'żółw' => 'bar',
            'łabądź' => 'baz',
        );
        $outputShown = array(
            $question,
            '  [<info>foo   </info>] foo',
            '  [<info>żółw  </info>] bar',
            '  [<info>łabądź</info>] baz',
        );
        $output = $this->getMock('\Symfony\Component\Console\Output\OutputInterface');
        $output->method('getFormatter')->willReturn(new OutputFormatter());

        $dialog = new QuestionHelper();
        $dialog->setInputStream($this->getInputStream("\n"));
        $helperSet = new HelperSet(array(new FormatterHelper()));
        $dialog->setHelperSet($helperSet);

        $output->expects($this->once())->method('writeln')->with($this->equalTo($outputShown));

        $question = new ChoiceQuestion($question, $possibleChoices, 'foo');
        $dialog->ask($this->createInputInterfaceMock(), $output, $question);
    }

    protected function getInputStream($input)
    {
        $stream = fopen('php://memory', 'r+', false);
        fwrite($stream, $input);
        rewind($stream);

        return $stream;
    }

    protected function createOutputInterface()
    {
        return new StreamOutput(fopen('php://memory', 'r+', false));
    }

    protected function createInputInterfaceMock($interactive = true)
    {
        $mock = $this->getMock('Symfony\Component\Console\Input\InputInterface');
        $mock->expects($this->any())
            ->method('isInteractive')
            ->will($this->returnValue($interactive));

        return $mock;
    }

    private function hasSttyAvailable()
    {
        exec('stty 2>&1', $output, $exitcode);

        return $exitcode === 0;
    }
}
PKϤ$Z��J��1console/Tests/Helper/LegacyProgressHelperTest.phpnu�[���<?php

/*
 * This file is part of the Symfony package.
 *
 * (c) Fabien Potencier <fabien@symfony.com>
 *
 * For the full copyright and license information, please view the LICENSE
 * file that was distributed with this source code.
 */

namespace Symfony\Component\Console\Tests\Helper;

use Symfony\Component\Console\Helper\ProgressHelper;
use Symfony\Component\Console\Output\StreamOutput;

/**
 * @group legacy
 * @group time-sensitive
 */
class LegacyProgressHelperTest extends \PHPUnit_Framework_TestCase
{
    public function testAdvance()
    {
        $progress = new ProgressHelper();
        $progress->start($output = $this->getOutputStream());
        $progress->advance();

        rewind($output->getStream());
        $this->assertEquals($this->generateOutput('    1 [->--------------------------]'), stream_get_contents($output->getStream()));
    }

    public function testAdvanceWithStep()
    {
        $progress = new ProgressHelper();
        $progress->start($output = $this->getOutputStream());
        $progress->advance(5);

        rewind($output->getStream());
        $this->assertEquals($this->generateOutput('    5 [----->----------------------]'), stream_get_contents($output->getStream()));
    }

    public function testAdvanceMultipleTimes()
    {
        $progress = new ProgressHelper();
        $progress->start($output = $this->getOutputStream());
        $progress->advance(3);
        $progress->advance(2);

        rewind($output->getStream());
        $this->assertEquals($this->generateOutput('    3 [--->------------------------]').$this->generateOutput('    5 [----->----------------------]'), stream_get_contents($output->getStream()));
    }

    public function testCustomizations()
    {
        $progress = new ProgressHelper();
        $progress->setBarWidth(10);
        $progress->setBarCharacter('_');
        $progress->setEmptyBarCharacter(' ');
        $progress->setProgressCharacter('/');
        $progress->setFormat(' %current%/%max% [%bar%] %percent%%');
        $progress->start($output = $this->getOutputStream(), 10);
        $progress->advance();

        rewind($output->getStream());
        $this->assertEquals($this->generateOutput('  1/10 [_/        ]  10%'), stream_get_contents($output->getStream()));
    }

    public function testPercent()
    {
        $progress = new ProgressHelper();
        $progress->start($output = $this->getOutputStream(), 50);
        $progress->display();
        $progress->advance();
        $progress->advance();

        rewind($output->getStream());
        $this->assertEquals($this->generateOutput('  0/50 [>---------------------------]   0%').$this->generateOutput('  1/50 [>---------------------------]   2%').$this->generateOutput('  2/50 [=>--------------------------]   4%'), stream_get_contents($output->getStream()));
    }

    public function testOverwriteWithShorterLine()
    {
        $progress = new ProgressHelper();
        $progress->setFormat(' %current%/%max% [%bar%] %percent%%');
        $progress->start($output = $this->getOutputStream(), 50);
        $progress->display();
        $progress->advance();

        // set shorter format
        $progress->setFormat(' %current%/%max% [%bar%]');
        $progress->advance();

        rewind($output->getStream());
        $this->assertEquals(
            $this->generateOutput('  0/50 [>---------------------------]   0%').
            $this->generateOutput('  1/50 [>---------------------------]   2%').
            $this->generateOutput('  2/50 [=>--------------------------]     '),
            stream_get_contents($output->getStream())
        );
    }

    public function testSetCurrentProgress()
    {
        $progress = new ProgressHelper();
        $progress->start($output = $this->getOutputStream(), 50);
        $progress->display();
        $progress->advance();
        $progress->setCurrent(15);
        $progress->setCurrent(25);

        rewind($output->getStream());
        $this->assertEquals(
            $this->generateOutput('  0/50 [>---------------------------]   0%').
            $this->generateOutput('  1/50 [>---------------------------]   2%').
            $this->generateOutput(' 15/50 [========>-------------------]  30%').
            $this->generateOutput(' 25/50 [==============>-------------]  50%'),
            stream_get_contents($output->getStream())
        );
    }

    /**
     * @expectedException        \LogicException
     * @expectedExceptionMessage You must start the progress bar
     */
    public function testSetCurrentBeforeStarting()
    {
        $progress = new ProgressHelper();
        $progress->setCurrent(15);
    }

    /**
     * @expectedException        \LogicException
     * @expectedExceptionMessage You can't regress the progress bar
     */
    public function testRegressProgress()
    {
        $progress = new ProgressHelper();
        $progress->start($output = $this->getOutputStream(), 50);
        $progress->setCurrent(15);
        $progress->setCurrent(10);
    }

    public function testRedrawFrequency()
    {
        $progress = $this->getMock('Symfony\Component\Console\Helper\ProgressHelper', array('display'));
        $progress->expects($this->exactly(4))
                 ->method('display');

        $progress->setRedrawFrequency(2);

        $progress->start($output = $this->getOutputStream(), 6);
        $progress->setCurrent(1);
        $progress->advance(2);
        $progress->advance(2);
        $progress->advance(1);
    }

    public function testMultiByteSupport()
    {
        $progress = new ProgressHelper();
        $progress->start($output = $this->getOutputStream());
        $progress->setBarCharacter('■');
        $progress->advance(3);

        rewind($output->getStream());
        $this->assertEquals($this->generateOutput('    3 [■■■>------------------------]'), stream_get_contents($output->getStream()));
    }

    public function testClear()
    {
        $progress = new ProgressHelper();
        $progress->start($output = $this->getOutputStream(), 50);
        $progress->setCurrent(25);
        $progress->clear();

        rewind($output->getStream());
        $this->assertEquals(
            $this->generateOutput(' 25/50 [==============>-------------]  50%').$this->generateOutput(''),
            stream_get_contents($output->getStream())
        );
    }

    public function testPercentNotHundredBeforeComplete()
    {
        $progress = new ProgressHelper();
        $progress->start($output = $this->getOutputStream(), 200);
        $progress->display();
        $progress->advance(199);
        $progress->advance();

        rewind($output->getStream());
        $this->assertEquals($this->generateOutput('   0/200 [>---------------------------]   0%').$this->generateOutput(' 199/200 [===========================>]  99%').$this->generateOutput(' 200/200 [============================] 100%'), stream_get_contents($output->getStream()));
    }

    public function testNonDecoratedOutput()
    {
        $progress = new ProgressHelper();
        $progress->start($output = $this->getOutputStream(false));
        $progress->advance();

        rewind($output->getStream());
        $this->assertEquals('', stream_get_contents($output->getStream()));
    }

    protected function getOutputStream($decorated = true)
    {
        return new StreamOutput(fopen('php://memory', 'r+', false), StreamOutput::VERBOSITY_NORMAL, $decorated);
    }

    protected $lastMessagesLength;

    protected function generateOutput($expected)
    {
        $expectedout = $expected;

        if ($this->lastMessagesLength !== null) {
            $expectedout = str_pad($expected, $this->lastMessagesLength, "\x20", STR_PAD_RIGHT);
        }

        $this->lastMessagesLength = strlen($expectedout);

        return "\x0D".$expectedout;
    }
}
PKϤ$Z���	IZIZ(console/Tests/Helper/ProgressBarTest.phpnu�[���<?php

/*
 * This file is part of the Symfony package.
 *
 * (c) Fabien Potencier <fabien@symfony.com>
 *
 * For the full copyright and license information, please view the LICENSE
 * file that was distributed with this source code.
 */

namespace Symfony\Component\Console\Tests\Helper;

use Symfony\Component\Console\Helper\ProgressBar;
use Symfony\Component\Console\Helper\Helper;
use Symfony\Component\Console\Output\StreamOutput;

/**
 * @group time-sensitive
 */
class ProgressBarTest extends \PHPUnit_Framework_TestCase
{
    public function testMultipleStart()
    {
        $bar = new ProgressBar($output = $this->getOutputStream());
        $bar->start();
        $bar->advance();
        $bar->start();

        rewind($output->getStream());
        $this->assertEquals(
            $this->generateOutput('    0 [>---------------------------]').
            $this->generateOutput('    1 [->--------------------------]').
            $this->generateOutput('    0 [>---------------------------]'),
            stream_get_contents($output->getStream())
        );
    }

    public function testAdvance()
    {
        $bar = new ProgressBar($output = $this->getOutputStream());
        $bar->start();
        $bar->advance();

        rewind($output->getStream());
        $this->assertEquals(
            $this->generateOutput('    0 [>---------------------------]').
            $this->generateOutput('    1 [->--------------------------]'),
            stream_get_contents($output->getStream())
        );
    }

    public function testAdvanceWithStep()
    {
        $bar = new ProgressBar($output = $this->getOutputStream());
        $bar->start();
        $bar->advance(5);

        rewind($output->getStream());
        $this->assertEquals(
            $this->generateOutput('    0 [>---------------------------]').
            $this->generateOutput('    5 [----->----------------------]'),
            stream_get_contents($output->getStream())
        );
    }

    public function testAdvanceMultipleTimes()
    {
        $bar = new ProgressBar($output = $this->getOutputStream());
        $bar->start();
        $bar->advance(3);
        $bar->advance(2);

        rewind($output->getStream());
        $this->assertEquals(
            $this->generateOutput('    0 [>---------------------------]').
            $this->generateOutput('    3 [--->------------------------]').
            $this->generateOutput('    5 [----->----------------------]'),
            stream_get_contents($output->getStream())
        );
    }

    public function testAdvanceOverMax()
    {
        $bar = new ProgressBar($output = $this->getOutputStream(), 10);
        $bar->setProgress(9);
        $bar->advance();
        $bar->advance();

        rewind($output->getStream());
        $this->assertEquals(
            $this->generateOutput('  9/10 [=========================>--]  90%').
            $this->generateOutput(' 10/10 [============================] 100%').
            $this->generateOutput(' 11/11 [============================] 100%'),
            stream_get_contents($output->getStream())
        );
    }

    public function testFormat()
    {
        $expected =
            $this->generateOutput('  0/10 [>---------------------------]   0%').
            $this->generateOutput(' 10/10 [============================] 100%').
            $this->generateOutput(' 10/10 [============================] 100%')
        ;

        // max in construct, no format
        $bar = new ProgressBar($output = $this->getOutputStream(), 10);
        $bar->start();
        $bar->advance(10);
        $bar->finish();

        rewind($output->getStream());
        $this->assertEquals($expected, stream_get_contents($output->getStream()));

        // max in start, no format
        $bar = new ProgressBar($output = $this->getOutputStream());
        $bar->start(10);
        $bar->advance(10);
        $bar->finish();

        rewind($output->getStream());
        $this->assertEquals($expected, stream_get_contents($output->getStream()));

        // max in construct, explicit format before
        $bar = new ProgressBar($output = $this->getOutputStream(), 10);
        $bar->setFormat('normal');
        $bar->start();
        $bar->advance(10);
        $bar->finish();

        rewind($output->getStream());
        $this->assertEquals($expected, stream_get_contents($output->getStream()));

        // max in start, explicit format before
        $bar = new ProgressBar($output = $this->getOutputStream());
        $bar->setFormat('normal');
        $bar->start(10);
        $bar->advance(10);
        $bar->finish();

        rewind($output->getStream());
        $this->assertEquals($expected, stream_get_contents($output->getStream()));
    }

    public function testCustomizations()
    {
        $bar = new ProgressBar($output = $this->getOutputStream(), 10);
        $bar->setBarWidth(10);
        $bar->setBarCharacter('_');
        $bar->setEmptyBarCharacter(' ');
        $bar->setProgressCharacter('/');
        $bar->setFormat(' %current%/%max% [%bar%] %percent:3s%%');
        $bar->start();
        $bar->advance();

        rewind($output->getStream());
        $this->assertEquals(
            $this->generateOutput('  0/10 [/         ]   0%').
            $this->generateOutput('  1/10 [_/        ]  10%'),
            stream_get_contents($output->getStream())
        );
    }

    public function testDisplayWithoutStart()
    {
        $bar = new ProgressBar($output = $this->getOutputStream(), 50);
        $bar->display();

        rewind($output->getStream());
        $this->assertEquals(
            $this->generateOutput('  0/50 [>---------------------------]   0%'),
            stream_get_contents($output->getStream())
        );
    }

    public function testDisplayWithQuietVerbosity()
    {
        $bar = new ProgressBar($output = $this->getOutputStream(true, StreamOutput::VERBOSITY_QUIET), 50);
        $bar->display();

        rewind($output->getStream());
        $this->assertEquals(
            '',
            stream_get_contents($output->getStream())
        );
    }

    public function testFinishWithoutStart()
    {
        $bar = new ProgressBar($output = $this->getOutputStream(), 50);
        $bar->finish();

        rewind($output->getStream());
        $this->assertEquals(
            $this->generateOutput(' 50/50 [============================] 100%'),
            stream_get_contents($output->getStream())
        );
    }

    public function testPercent()
    {
        $bar = new ProgressBar($output = $this->getOutputStream(), 50);
        $bar->start();
        $bar->display();
        $bar->advance();
        $bar->advance();

        rewind($output->getStream());
        $this->assertEquals(
            $this->generateOutput('  0/50 [>---------------------------]   0%').
            $this->generateOutput('  0/50 [>---------------------------]   0%').
            $this->generateOutput('  1/50 [>---------------------------]   2%').
            $this->generateOutput('  2/50 [=>--------------------------]   4%'),
            stream_get_contents($output->getStream())
        );
    }

    public function testOverwriteWithShorterLine()
    {
        $bar = new ProgressBar($output = $this->getOutputStream(), 50);
        $bar->setFormat(' %current%/%max% [%bar%] %percent:3s%%');
        $bar->start();
        $bar->display();
        $bar->advance();

        // set shorter format
        $bar->setFormat(' %current%/%max% [%bar%]');
        $bar->advance();

        rewind($output->getStream());
        $this->assertEquals(
            $this->generateOutput('  0/50 [>---------------------------]   0%').
            $this->generateOutput('  0/50 [>---------------------------]   0%').
            $this->generateOutput('  1/50 [>---------------------------]   2%').
            $this->generateOutput('  2/50 [=>--------------------------]'),
            stream_get_contents($output->getStream())
        );
    }

    public function testStartWithMax()
    {
        $bar = new ProgressBar($output = $this->getOutputStream());
        $bar->setFormat('%current%/%max% [%bar%]');
        $bar->start(50);
        $bar->advance();

        rewind($output->getStream());
        $this->assertEquals(
            $this->generateOutput(' 0/50 [>---------------------------]').
            $this->generateOutput(' 1/50 [>---------------------------]'),
            stream_get_contents($output->getStream())
        );
    }

    public function testSetCurrentProgress()
    {
        $bar = new ProgressBar($output = $this->getOutputStream(), 50);
        $bar->start();
        $bar->display();
        $bar->advance();
        $bar->setProgress(15);
        $bar->setProgress(25);

        rewind($output->getStream());
        $this->assertEquals(
            $this->generateOutput('  0/50 [>---------------------------]   0%').
            $this->generateOutput('  0/50 [>---------------------------]   0%').
            $this->generateOutput('  1/50 [>---------------------------]   2%').
            $this->generateOutput(' 15/50 [========>-------------------]  30%').
            $this->generateOutput(' 25/50 [==============>-------------]  50%'),
            stream_get_contents($output->getStream())
        );
    }

    /**
     */
    public function testSetCurrentBeforeStarting()
    {
        $bar = new ProgressBar($this->getOutputStream());
        $bar->setProgress(15);
        $this->assertNotNull($bar->getStartTime());
    }

    /**
     * @expectedException        \LogicException
     * @expectedExceptionMessage You can't regress the progress bar
     */
    public function testRegressProgress()
    {
        $bar = new ProgressBar($output = $this->getOutputStream(), 50);
        $bar->start();
        $bar->setProgress(15);
        $bar->setProgress(10);
    }

    public function testRedrawFrequency()
    {
        $bar = $this->getMock('Symfony\Component\Console\Helper\ProgressBar', array('display'), array($this->getOutputStream(), 6));
        $bar->expects($this->exactly(4))->method('display');

        $bar->setRedrawFrequency(2);
        $bar->start();
        $bar->setProgress(1);
        $bar->advance(2);
        $bar->advance(2);
        $bar->advance(1);
    }

    public function testRedrawFrequencyIsAtLeastOneIfZeroGiven()
    {
        $bar = $this->getMock('Symfony\Component\Console\Helper\ProgressBar', array('display'), array($this->getOutputStream()));

        $bar->expects($this->exactly(2))->method('display');
        $bar->setRedrawFrequency(0);
        $bar->start();
        $bar->advance();
    }

    public function testRedrawFrequencyIsAtLeastOneIfSmallerOneGiven()
    {
        $bar = $this->getMock('Symfony\Component\Console\Helper\ProgressBar', array('display'), array($this->getOutputStream()));

        $bar->expects($this->exactly(2))->method('display');
        $bar->setRedrawFrequency(0.9);
        $bar->start();
        $bar->advance();
    }

    public function testMultiByteSupport()
    {
        $bar = new ProgressBar($output = $this->getOutputStream());
        $bar->start();
        $bar->setBarCharacter('■');
        $bar->advance(3);

        rewind($output->getStream());
        $this->assertEquals(
            $this->generateOutput('    0 [>---------------------------]').
            $this->generateOutput('    3 [■■■>------------------------]'),
            stream_get_contents($output->getStream())
        );
    }

    public function testClear()
    {
        $bar = new ProgressBar($output = $this->getOutputStream(), 50);
        $bar->start();
        $bar->setProgress(25);
        $bar->clear();

        rewind($output->getStream());
        $this->assertEquals(
            $this->generateOutput('  0/50 [>---------------------------]   0%').
            $this->generateOutput(' 25/50 [==============>-------------]  50%').
            $this->generateOutput(''),
            stream_get_contents($output->getStream())
        );
    }

    public function testPercentNotHundredBeforeComplete()
    {
        $bar = new ProgressBar($output = $this->getOutputStream(), 200);
        $bar->start();
        $bar->display();
        $bar->advance(199);
        $bar->advance();

        rewind($output->getStream());
        $this->assertEquals(
            $this->generateOutput('   0/200 [>---------------------------]   0%').
            $this->generateOutput('   0/200 [>---------------------------]   0%').
            $this->generateOutput(' 199/200 [===========================>]  99%').
            $this->generateOutput(' 200/200 [============================] 100%'),
            stream_get_contents($output->getStream())
        );
    }

    public function testNonDecoratedOutput()
    {
        $bar = new ProgressBar($output = $this->getOutputStream(false), 200);
        $bar->start();

        for ($i = 0; $i < 200; ++$i) {
            $bar->advance();
        }

        $bar->finish();

        rewind($output->getStream());
        $this->assertEquals(
            '   0/200 [>---------------------------]   0%'.PHP_EOL.
            '  20/200 [==>-------------------------]  10%'.PHP_EOL.
            '  40/200 [=====>----------------------]  20%'.PHP_EOL.
            '  60/200 [========>-------------------]  30%'.PHP_EOL.
            '  80/200 [===========>----------------]  40%'.PHP_EOL.
            ' 100/200 [==============>-------------]  50%'.PHP_EOL.
            ' 120/200 [================>-----------]  60%'.PHP_EOL.
            ' 140/200 [===================>--------]  70%'.PHP_EOL.
            ' 160/200 [======================>-----]  80%'.PHP_EOL.
            ' 180/200 [=========================>--]  90%'.PHP_EOL.
            ' 200/200 [============================] 100%',
            stream_get_contents($output->getStream())
        );
    }

    public function testNonDecoratedOutputWithClear()
    {
        $bar = new ProgressBar($output = $this->getOutputStream(false), 50);
        $bar->start();
        $bar->setProgress(25);
        $bar->clear();
        $bar->setProgress(50);
        $bar->finish();

        rewind($output->getStream());
        $this->assertEquals(
            '  0/50 [>---------------------------]   0%'.PHP_EOL.
            ' 25/50 [==============>-------------]  50%'.PHP_EOL.
            ' 50/50 [============================] 100%',
            stream_get_contents($output->getStream())
        );
    }

    public function testNonDecoratedOutputWithoutMax()
    {
        $bar = new ProgressBar($output = $this->getOutputStream(false));
        $bar->start();
        $bar->advance();

        rewind($output->getStream());
        $this->assertEquals(
            '    0 [>---------------------------]'.PHP_EOL.
            '    1 [->--------------------------]',
            stream_get_contents($output->getStream())
        );
    }

    public function testParallelBars()
    {
        $output = $this->getOutputStream();
        $bar1 = new ProgressBar($output, 2);
        $bar2 = new ProgressBar($output, 3);
        $bar2->setProgressCharacter('#');
        $bar3 = new ProgressBar($output);

        $bar1->start();
        $output->write("\n");
        $bar2->start();
        $output->write("\n");
        $bar3->start();

        for ($i = 1; $i <= 3; ++$i) {
            // up two lines
            $output->write("\033[2A");
            if ($i <= 2) {
                $bar1->advance();
            }
            $output->write("\n");
            $bar2->advance();
            $output->write("\n");
            $bar3->advance();
        }
        $output->write("\033[2A");
        $output->write("\n");
        $output->write("\n");
        $bar3->finish();

        rewind($output->getStream());
        $this->assertEquals(
            $this->generateOutput(' 0/2 [>---------------------------]   0%')."\n".
            $this->generateOutput(' 0/3 [#---------------------------]   0%')."\n".
            rtrim($this->generateOutput('    0 [>---------------------------]')).

            "\033[2A".
            $this->generateOutput(' 1/2 [==============>-------------]  50%')."\n".
            $this->generateOutput(' 1/3 [=========#------------------]  33%')."\n".
            rtrim($this->generateOutput('    1 [->--------------------------]')).

            "\033[2A".
            $this->generateOutput(' 2/2 [============================] 100%')."\n".
            $this->generateOutput(' 2/3 [==================#---------]  66%')."\n".
            rtrim($this->generateOutput('    2 [-->-------------------------]')).

            "\033[2A".
            "\n".
            $this->generateOutput(' 3/3 [============================] 100%')."\n".
            rtrim($this->generateOutput('    3 [--->------------------------]')).

            "\033[2A".
            "\n".
            "\n".
            rtrim($this->generateOutput('    3 [============================]')),
            stream_get_contents($output->getStream())
        );
    }

    public function testWithoutMax()
    {
        $output = $this->getOutputStream();

        $bar = new ProgressBar($output);
        $bar->start();
        $bar->advance();
        $bar->advance();
        $bar->advance();
        $bar->finish();

        rewind($output->getStream());
        $this->assertEquals(
            rtrim($this->generateOutput('    0 [>---------------------------]')).
            rtrim($this->generateOutput('    1 [->--------------------------]')).
            rtrim($this->generateOutput('    2 [-->-------------------------]')).
            rtrim($this->generateOutput('    3 [--->------------------------]')).
            rtrim($this->generateOutput('    3 [============================]')),
            stream_get_contents($output->getStream())
        );
    }

    public function testAddingPlaceholderFormatter()
    {
        ProgressBar::setPlaceholderFormatterDefinition('remaining_steps', function (ProgressBar $bar) {
            return $bar->getMaxSteps() - $bar->getProgress();
        });
        $bar = new ProgressBar($output = $this->getOutputStream(), 3);
        $bar->setFormat(' %remaining_steps% [%bar%]');

        $bar->start();
        $bar->advance();
        $bar->finish();

        rewind($output->getStream());
        $this->assertEquals(
            $this->generateOutput(' 3 [>---------------------------]').
            $this->generateOutput(' 2 [=========>------------------]').
            $this->generateOutput(' 0 [============================]'),
            stream_get_contents($output->getStream())
        );
    }

    public function testMultilineFormat()
    {
        $bar = new ProgressBar($output = $this->getOutputStream(), 3);
        $bar->setFormat("%bar%\nfoobar");

        $bar->start();
        $bar->advance();
        $bar->clear();
        $bar->finish();

        rewind($output->getStream());
        $this->assertEquals(
            $this->generateOutput(">---------------------------\nfoobar").
            $this->generateOutput("=========>------------------\nfoobar").
            "\x0D\x1B[2K\x1B[1A\x1B[2K".
            $this->generateOutput("============================\nfoobar"),
            stream_get_contents($output->getStream())
        );
    }

    public function testAnsiColorsAndEmojis()
    {
        $bar = new ProgressBar($output = $this->getOutputStream(), 15);
        ProgressBar::setPlaceholderFormatterDefinition('memory', function (ProgressBar $bar) {
            static $i = 0;
            $mem = 100000 * $i;
            $colors = $i++ ? '41;37' : '44;37';

            return "\033[".$colors.'m '.Helper::formatMemory($mem)." \033[0m";
        });
        $bar->setFormat(" \033[44;37m %title:-37s% \033[0m\n %current%/%max% %bar% %percent:3s%%\n 🏁  %remaining:-10s% %memory:37s%");
        $bar->setBarCharacter($done = "\033[32m●\033[0m");
        $bar->setEmptyBarCharacter($empty = "\033[31m●\033[0m");
        $bar->setProgressCharacter($progress = "\033[32m➤ \033[0m");

        $bar->setMessage('Starting the demo... fingers crossed', 'title');
        $bar->start();
        $bar->setMessage('Looks good to me...', 'title');
        $bar->advance(4);
        $bar->setMessage('Thanks, bye', 'title');
        $bar->finish();

        rewind($output->getStream());
        $this->assertEquals(
            $this->generateOutput(
                " \033[44;37m Starting the demo... fingers crossed  \033[0m\n".
                '  0/15 '.$progress.str_repeat($empty, 26)."   0%\n".
                " \xf0\x9f\x8f\x81  < 1 sec                        \033[44;37m 0 B \033[0m"
            ).
            $this->generateOutput(
                " \033[44;37m Looks good to me...                   \033[0m\n".
                '  4/15 '.str_repeat($done, 7).$progress.str_repeat($empty, 19)."  26%\n".
                " \xf0\x9f\x8f\x81  < 1 sec                     \033[41;37m 97 KiB \033[0m"
            ).
            $this->generateOutput(
                " \033[44;37m Thanks, bye                           \033[0m\n".
                ' 15/15 '.str_repeat($done, 28)." 100%\n".
                " \xf0\x9f\x8f\x81  < 1 sec                    \033[41;37m 195 KiB \033[0m"
            ),
            stream_get_contents($output->getStream())
        );
    }

    public function testSetFormat()
    {
        $bar = new ProgressBar($output = $this->getOutputStream());
        $bar->setFormat('normal');
        $bar->start();
        rewind($output->getStream());
        $this->assertEquals(
            $this->generateOutput('    0 [>---------------------------]'),
            stream_get_contents($output->getStream())
        );

        $bar = new ProgressBar($output = $this->getOutputStream(), 10);
        $bar->setFormat('normal');
        $bar->start();
        rewind($output->getStream());
        $this->assertEquals(
            $this->generateOutput('  0/10 [>---------------------------]   0%'),
            stream_get_contents($output->getStream())
        );
    }

    /**
     * @dataProvider provideFormat
     */
    public function testFormatsWithoutMax($format)
    {
        $bar = new ProgressBar($output = $this->getOutputStream());
        $bar->setFormat($format);
        $bar->start();

        rewind($output->getStream());
        $this->assertNotEmpty(stream_get_contents($output->getStream()));
    }

    /**
     * Provides each defined format.
     *
     * @return array
     */
    public function provideFormat()
    {
        return array(
            array('normal'),
            array('verbose'),
            array('very_verbose'),
            array('debug'),
        );
    }

    protected function getOutputStream($decorated = true, $verbosity = StreamOutput::VERBOSITY_NORMAL)
    {
        return new StreamOutput(fopen('php://memory', 'r+', false), $verbosity, $decorated);
    }

    protected function generateOutput($expected)
    {
        $count = substr_count($expected, "\n");

        return "\x0D\x1B[2K".($count ? str_repeat("\x1B[1A\x1B[2K", $count) : '').$expected;
    }
}
PKϤ$Z��F���'console/Tests/Helper/TableStyleTest.phpnu�[���<?php

/*
 * This file is part of the Symfony package.
 *
 * (c) Fabien Potencier <fabien@symfony.com>
 *
 * For the full copyright and license information, please view the LICENSE
 * file that was distributed with this source code.
 */

namespace Symfony\Component\Console\Tests\Helper;

use Symfony\Component\Console\Helper\TableStyle;

class TableStyleTest extends \PHPUnit_Framework_TestCase
{
    /**
     * @expectedException        \InvalidArgumentException
     * @expectedExceptionMessage Invalid padding type. Expected one of (STR_PAD_LEFT, STR_PAD_RIGHT, STR_PAD_BOTH).
     */
    public function testSetPadTypeWithInvalidType()
    {
        $style = new TableStyle();
        $style->setPadType('TEST');
    }
}
PKϤ$Z���$��*console/Tests/Helper/ProcessHelperTest.phpnu�[���<?php

/*
 * This file is part of the Symfony package.
 *
 * (c) Fabien Potencier <fabien@symfony.com>
 *
 * For the full copyright and license information, please view the LICENSE
 * file that was distributed with this source code.
 */

namespace Symfony\Component\Console\Tests\Helper;

use Symfony\Component\Console\Helper\DebugFormatterHelper;
use Symfony\Component\Console\Helper\HelperSet;
use Symfony\Component\Console\Output\StreamOutput;
use Symfony\Component\Console\Helper\ProcessHelper;
use Symfony\Component\Process\Process;

class ProcessHelperTest extends \PHPUnit_Framework_TestCase
{
    /**
     * @dataProvider provideCommandsAndOutput
     */
    public function testVariousProcessRuns($expected, $cmd, $verbosity, $error)
    {
        $helper = new ProcessHelper();
        $helper->setHelperSet(new HelperSet(array(new DebugFormatterHelper())));
        $output = $this->getOutputStream($verbosity);
        $helper->run($output, $cmd, $error);
        $this->assertEquals($expected, $this->getOutput($output));
    }

    public function testPassedCallbackIsExecuted()
    {
        $helper = new ProcessHelper();
        $helper->setHelperSet(new HelperSet(array(new DebugFormatterHelper())));
        $output = $this->getOutputStream(StreamOutput::VERBOSITY_NORMAL);

        $executed = false;
        $callback = function () use (&$executed) { $executed = true; };

        $helper->run($output, 'php -r "echo 42;"', null, $callback);
        $this->assertTrue($executed);
    }

    public function provideCommandsAndOutput()
    {
        $successOutputVerbose = <<<EOT
  RUN  php -r "echo 42;"
  RES  Command ran successfully

EOT;
        $successOutputDebug = <<<EOT
  RUN  php -r "echo 42;"
  OUT  42
  RES  Command ran successfully

EOT;
        $successOutputDebugWithTags = <<<EOT
  RUN  php -r "echo '<info>42</info>';"
  OUT  <info>42</info>
  RES  Command ran successfully

EOT;
        $successOutputProcessDebug = <<<EOT
  RUN  'php' '-r' 'echo 42;'
  OUT  42
  RES  Command ran successfully

EOT;
        $syntaxErrorOutputVerbose = <<<EOT
  RUN  php -r "fwrite(STDERR, 'error message');usleep(50000);fwrite(STDOUT, 'out message');exit(252);"
  RES  252 Command did not run successfully

EOT;
        $syntaxErrorOutputDebug = <<<EOT
  RUN  php -r "fwrite(STDERR, 'error message');usleep(500000);fwrite(STDOUT, 'out message');exit(252);"
  ERR  error message
  OUT  out message
  RES  252 Command did not run successfully

EOT;

        $errorMessage = 'An error occurred';
        if ('\\' === DIRECTORY_SEPARATOR) {
            $successOutputProcessDebug = str_replace("'", '"', $successOutputProcessDebug);
        }

        return array(
            array('', 'php -r "echo 42;"', StreamOutput::VERBOSITY_VERBOSE, null),
            array($successOutputVerbose, 'php -r "echo 42;"', StreamOutput::VERBOSITY_VERY_VERBOSE, null),
            array($successOutputDebug, 'php -r "echo 42;"', StreamOutput::VERBOSITY_DEBUG, null),
            array($successOutputDebugWithTags, 'php -r "echo \'<info>42</info>\';"', StreamOutput::VERBOSITY_DEBUG, null),
            array('', 'php -r "syntax error"', StreamOutput::VERBOSITY_VERBOSE, null),
            array($syntaxErrorOutputVerbose, 'php -r "fwrite(STDERR, \'error message\');usleep(50000);fwrite(STDOUT, \'out message\');exit(252);"', StreamOutput::VERBOSITY_VERY_VERBOSE, null),
            array($syntaxErrorOutputDebug, 'php -r "fwrite(STDERR, \'error message\');usleep(500000);fwrite(STDOUT, \'out message\');exit(252);"', StreamOutput::VERBOSITY_DEBUG, null),
            array($errorMessage.PHP_EOL, 'php -r "fwrite(STDERR, \'error message\');usleep(50000);fwrite(STDOUT, \'out message\');exit(252);"', StreamOutput::VERBOSITY_VERBOSE, $errorMessage),
            array($syntaxErrorOutputVerbose.$errorMessage.PHP_EOL, 'php -r "fwrite(STDERR, \'error message\');usleep(50000);fwrite(STDOUT, \'out message\');exit(252);"', StreamOutput::VERBOSITY_VERY_VERBOSE, $errorMessage),
            array($syntaxErrorOutputDebug.$errorMessage.PHP_EOL, 'php -r "fwrite(STDERR, \'error message\');usleep(500000);fwrite(STDOUT, \'out message\');exit(252);"', StreamOutput::VERBOSITY_DEBUG, $errorMessage),
            array($successOutputProcessDebug, array('php', '-r', 'echo 42;'), StreamOutput::VERBOSITY_DEBUG, null),
            array($successOutputDebug, new Process('php -r "echo 42;"'), StreamOutput::VERBOSITY_DEBUG, null),
        );
    }

    private function getOutputStream($verbosity)
    {
        return new StreamOutput(fopen('php://memory', 'r+', false), $verbosity, false);
    }

    private function getOutput(StreamOutput $output)
    {
        rewind($output->getStream());

        return stream_get_contents($output->getStream());
    }
}
PKϤ$Z�#���#console/Tests/Helper/HelperTest.phpnu�[���<?php

/*
 * This file is part of the Symfony package.
 *
 * (c) Fabien Potencier <fabien@symfony.com>
 *
 * For the full copyright and license information, please view the LICENSE
 * file that was distributed with this source code.
 */

namespace Symfony\Component\Console\Tests\Helper;

use Symfony\Component\Console\Helper\Helper;

class HelperTest extends \PHPUnit_Framework_TestCase
{
    public function formatTimeProvider()
    {
        return array(
            array(0,      '< 1 sec'),
            array(1,      '1 sec'),
            array(2,      '2 secs'),
            array(59,     '59 secs'),
            array(60,     '1 min'),
            array(61,     '1 min'),
            array(119,    '1 min'),
            array(120,    '2 mins'),
            array(121,    '2 mins'),
            array(3599,   '59 mins'),
            array(3600,   '1 hr'),
            array(7199,   '1 hr'),
            array(7200,   '2 hrs'),
            array(7201,   '2 hrs'),
            array(86399,  '23 hrs'),
            array(86400,  '1 day'),
            array(86401,  '1 day'),
            array(172799, '1 day'),
            array(172800, '2 days'),
            array(172801, '2 days'),
        );
    }

    /**
     * @dataProvider formatTimeProvider
     *
     * @param int    $secs
     * @param string $expectedFormat
     */
    public function testFormatTime($secs, $expectedFormat)
    {
        $this->assertEquals($expectedFormat, Helper::formatTime($secs));
    }
}
PKϤ$Z�APk-k-/console/Tests/Helper/LegacyDialogHelperTest.phpnu�[���<?php

/*
 * This file is part of the Symfony package.
 *
 * (c) Fabien Potencier <fabien@symfony.com>
 *
 * For the full copyright and license information, please view the LICENSE
 * file that was distributed with this source code.
 */

namespace Symfony\Component\Console\Tests\Helper;

use Symfony\Component\Console\Input\ArrayInput;
use Symfony\Component\Console\Helper\DialogHelper;
use Symfony\Component\Console\Helper\HelperSet;
use Symfony\Component\Console\Helper\FormatterHelper;
use Symfony\Component\Console\Output\ConsoleOutput;
use Symfony\Component\Console\Output\StreamOutput;
use Symfony\Component\Console\Exception\InvalidArgumentException;

/**
 * @group legacy
 */
class LegacyDialogHelperTest extends \PHPUnit_Framework_TestCase
{
    public function testSelect()
    {
        $dialog = new DialogHelper();

        $helperSet = new HelperSet(array(new FormatterHelper()));
        $dialog->setHelperSet($helperSet);

        $heroes = array('Superman', 'Batman', 'Spiderman');

        $dialog->setInputStream($this->getInputStream("\n1\n  1  \nFabien\n1\nFabien\n1\n0,2\n 0 , 2  \n\n\n"));
        $this->assertEquals('2', $dialog->select($this->getOutputStream(), 'What is your favorite superhero?', $heroes, '2'));
        $this->assertEquals('1', $dialog->select($this->getOutputStream(), 'What is your favorite superhero?', $heroes));
        $this->assertEquals('1', $dialog->select($this->getOutputStream(), 'What is your favorite superhero?', $heroes));
        $this->assertEquals('1', $dialog->select($output = $this->getOutputStream(), 'What is your favorite superhero?', $heroes, null, false, 'Input "%s" is not a superhero!', false));

        rewind($output->getStream());
        $this->assertContains('Input "Fabien" is not a superhero!', stream_get_contents($output->getStream()));

        try {
            $this->assertEquals('1', $dialog->select($output = $this->getOutputStream(), 'What is your favorite superhero?', $heroes, null, 1));
            $this->fail();
        } catch (\InvalidArgumentException $e) {
            $this->assertEquals('Value "Fabien" is invalid', $e->getMessage());
        }

        $this->assertEquals(array('1'), $dialog->select($this->getOutputStream(), 'What is your favorite superhero?', $heroes, null, false, 'Input "%s" is not a superhero!', true));
        $this->assertEquals(array('0', '2'), $dialog->select($this->getOutputStream(), 'What is your favorite superhero?', $heroes, null, false, 'Input "%s" is not a superhero!', true));
        $this->assertEquals(array('0', '2'), $dialog->select($this->getOutputStream(), 'What is your favorite superhero?', $heroes, null, false, 'Input "%s" is not a superhero!', true));
        $this->assertEquals(array('0', '1'), $dialog->select($this->getOutputStream(), 'What is your favorite superhero?', $heroes, '0,1', false, 'Input "%s" is not a superhero!', true));
        $this->assertEquals(array('0', '1'), $dialog->select($this->getOutputStream(), 'What is your favorite superhero?', $heroes, ' 0 , 1 ', false, 'Input "%s" is not a superhero!', true));
    }

    public function testSelectOnErrorOutput()
    {
        $dialog = new DialogHelper();

        $helperSet = new HelperSet(array(new FormatterHelper()));
        $dialog->setHelperSet($helperSet);

        $heroes = array('Superman', 'Batman', 'Spiderman');

        $dialog->setInputStream($this->getInputStream("Stdout\n1\n"));
        $this->assertEquals('1', $dialog->select($output = $this->getConsoleOutput($this->getOutputStream()), 'What is your favorite superhero?', $heroes, null, false, 'Input "%s" is not a superhero!', false));

        rewind($output->getErrorOutput()->getStream());
        $this->assertContains('Input "Stdout" is not a superhero!', stream_get_contents($output->getErrorOutput()->getStream()));
    }

    public function testAsk()
    {
        $dialog = new DialogHelper();

        $dialog->setInputStream($this->getInputStream("\n8AM\n"));

        $this->assertEquals('2PM', $dialog->ask($this->getOutputStream(), 'What time is it?', '2PM'));
        $this->assertEquals('8AM', $dialog->ask($output = $this->getOutputStream(), 'What time is it?', '2PM'));

        rewind($output->getStream());
        $this->assertEquals('What time is it?', stream_get_contents($output->getStream()));
    }

    public function testAskOnErrorOutput()
    {
        if (!$this->hasSttyAvailable()) {
            $this->markTestSkipped('`stderr` is required to test stderr output functionality');
        }

        $dialog = new DialogHelper();

        $dialog->setInputStream($this->getInputStream("not stdout\n"));

        $this->assertEquals('not stdout', $dialog->ask($output = $this->getConsoleOutput($this->getOutputStream()), 'Where should output go?', 'stderr'));

        rewind($output->getErrorOutput()->getStream());
        $this->assertEquals('Where should output go?', stream_get_contents($output->getErrorOutput()->getStream()));
    }

    public function testAskWithAutocomplete()
    {
        if (!$this->hasSttyAvailable()) {
            $this->markTestSkipped('`stty` is required to test autocomplete functionality');
        }

        // Acm<NEWLINE>
        // Ac<BACKSPACE><BACKSPACE>s<TAB>Test<NEWLINE>
        // <NEWLINE>
        // <UP ARROW><UP ARROW><NEWLINE>
        // <UP ARROW><UP ARROW><UP ARROW><UP ARROW><UP ARROW><TAB>Test<NEWLINE>
        // <DOWN ARROW><NEWLINE>
        // S<BACKSPACE><BACKSPACE><DOWN ARROW><DOWN ARROW><NEWLINE>
        // F00<BACKSPACE><BACKSPACE>oo<TAB><NEWLINE>
        $inputStream = $this->getInputStream("Acm\nAc\177\177s\tTest\n\n\033[A\033[A\n\033[A\033[A\033[A\033[A\033[A\tTest\n\033[B\nS\177\177\033[B\033[B\nF00\177\177oo\t\n");

        $dialog = new DialogHelper();
        $dialog->setInputStream($inputStream);

        $bundles = array('AcmeDemoBundle', 'AsseticBundle', 'SecurityBundle', 'FooBundle');

        $this->assertEquals('AcmeDemoBundle', $dialog->ask($this->getOutputStream(), 'Please select a bundle', 'FrameworkBundle', $bundles));
        $this->assertEquals('AsseticBundleTest', $dialog->ask($this->getOutputStream(), 'Please select a bundle', 'FrameworkBundle', $bundles));
        $this->assertEquals('FrameworkBundle', $dialog->ask($this->getOutputStream(), 'Please select a bundle', 'FrameworkBundle', $bundles));
        $this->assertEquals('SecurityBundle', $dialog->ask($this->getOutputStream(), 'Please select a bundle', 'FrameworkBundle', $bundles));
        $this->assertEquals('FooBundleTest', $dialog->ask($this->getOutputStream(), 'Please select a bundle', 'FrameworkBundle', $bundles));
        $this->assertEquals('AcmeDemoBundle', $dialog->ask($this->getOutputStream(), 'Please select a bundle', 'FrameworkBundle', $bundles));
        $this->assertEquals('AsseticBundle', $dialog->ask($this->getOutputStream(), 'Please select a bundle', 'FrameworkBundle', $bundles));
        $this->assertEquals('FooBundle', $dialog->ask($this->getOutputStream(), 'Please select a bundle', 'FrameworkBundle', $bundles));
    }

    /**
     * @group tty
     */
    public function testAskHiddenResponse()
    {
        if ('\\' === DIRECTORY_SEPARATOR) {
            $this->markTestSkipped('This test is not supported on Windows');
        }

        $dialog = new DialogHelper();

        $dialog->setInputStream($this->getInputStream("8AM\n"));

        $this->assertEquals('8AM', $dialog->askHiddenResponse($this->getOutputStream(), 'What time is it?'));
    }

    /**
     * @group tty
     */
    public function testAskHiddenResponseOnErrorOutput()
    {
        if ('\\' === DIRECTORY_SEPARATOR) {
            $this->markTestSkipped('This test is not supported on Windows');
        }

        $dialog = new DialogHelper();

        $dialog->setInputStream($this->getInputStream("8AM\n"));

        $this->assertEquals('8AM', $dialog->askHiddenResponse($output = $this->getConsoleOutput($this->getOutputStream()), 'What time is it?'));

        rewind($output->getErrorOutput()->getStream());
        $this->assertContains('What time is it?', stream_get_contents($output->getErrorOutput()->getStream()));
    }

    public function testAskConfirmation()
    {
        $dialog = new DialogHelper();

        $dialog->setInputStream($this->getInputStream("\n\n"));
        $this->assertTrue($dialog->askConfirmation($this->getOutputStream(), 'Do you like French fries?'));
        $this->assertFalse($dialog->askConfirmation($this->getOutputStream(), 'Do you like French fries?', false));

        $dialog->setInputStream($this->getInputStream("y\nyes\n"));
        $this->assertTrue($dialog->askConfirmation($this->getOutputStream(), 'Do you like French fries?', false));
        $this->assertTrue($dialog->askConfirmation($this->getOutputStream(), 'Do you like French fries?', false));

        $dialog->setInputStream($this->getInputStream("n\nno\n"));
        $this->assertFalse($dialog->askConfirmation($this->getOutputStream(), 'Do you like French fries?', true));
        $this->assertFalse($dialog->askConfirmation($this->getOutputStream(), 'Do you like French fries?', true));
    }

    public function testAskAndValidate()
    {
        $dialog = new DialogHelper();
        $helperSet = new HelperSet(array(new FormatterHelper()));
        $dialog->setHelperSet($helperSet);

        $question = 'What color was the white horse of Henry IV?';
        $error = 'This is not a color!';
        $validator = function ($color) use ($error) {
            if (!in_array($color, array('white', 'black'))) {
                throw new InvalidArgumentException($error);
            }

            return $color;
        };

        $dialog->setInputStream($this->getInputStream("\nblack\n"));
        $this->assertEquals('white', $dialog->askAndValidate($this->getOutputStream(), $question, $validator, 2, 'white'));
        $this->assertEquals('black', $dialog->askAndValidate($this->getOutputStream(), $question, $validator, 2, 'white'));

        $dialog->setInputStream($this->getInputStream("green\nyellow\norange\n"));
        try {
            $this->assertEquals('white', $dialog->askAndValidate($output = $this->getConsoleOutput($this->getOutputStream()), $question, $validator, 2, 'white'));
            $this->fail();
        } catch (\InvalidArgumentException $e) {
            $this->assertEquals($error, $e->getMessage());
            rewind($output->getErrorOutput()->getStream());
            $this->assertContains('What color was the white horse of Henry IV?', stream_get_contents($output->getErrorOutput()->getStream()));
        }
    }

    public function testNoInteraction()
    {
        $dialog = new DialogHelper();

        $input = new ArrayInput(array());
        $input->setInteractive(false);

        $dialog->setInput($input);

        $this->assertEquals('not yet', $dialog->ask($this->getOutputStream(), 'Do you have a job?', 'not yet'));
    }

    protected function getInputStream($input)
    {
        $stream = fopen('php://memory', 'r+', false);
        fwrite($stream, $input);
        rewind($stream);

        return $stream;
    }

    protected function getOutputStream()
    {
        return new StreamOutput(fopen('php://memory', 'r+', false));
    }

    protected function getConsoleOutput($stderr)
    {
        $output = new ConsoleOutput();
        $output->setErrorOutput($stderr);

        return $output;
    }

    private function hasStderrSupport()
    {
        return false === $this->isRunningOS400();
    }

    private function hasSttyAvailable()
    {
        exec('stty 2>&1', $output, $exitcode);

        return $exitcode === 0;
    }
}
PKϤ$ZK�;���.console/Tests/Helper/ProgressIndicatorTest.phpnu�[���<?php

namespace Symfony\Component\Console\Tests\Helper;

use Symfony\Component\Console\Helper\ProgressIndicator;
use Symfony\Component\Console\Output\StreamOutput;

/**
 * @group time-sensitive
 */
class ProgressIndicatorTest extends \PHPUnit_Framework_TestCase
{
    public function testDefaultIndicator()
    {
        $bar = new ProgressIndicator($output = $this->getOutputStream());
        $bar->start('Starting...');
        usleep(101000);
        $bar->advance();
        usleep(101000);
        $bar->advance();
        usleep(101000);
        $bar->advance();
        usleep(101000);
        $bar->advance();
        usleep(101000);
        $bar->advance();
        usleep(101000);
        $bar->setMessage('Advancing...');
        $bar->advance();
        $bar->finish('Done...');
        $bar->start('Starting Again...');
        usleep(101000);
        $bar->advance();
        $bar->finish('Done Again...');

        rewind($output->getStream());

        $this->assertEquals(
            $this->generateOutput(' - Starting...').
            $this->generateOutput(' \\ Starting...').
            $this->generateOutput(' | Starting...').
            $this->generateOutput(' / Starting...').
            $this->generateOutput(' - Starting...').
            $this->generateOutput(' \\ Starting...').
            $this->generateOutput(' \\ Advancing...').
            $this->generateOutput(' | Advancing...').
            $this->generateOutput(' | Done...     ').
            PHP_EOL.
            $this->generateOutput(' - Starting Again...').
            $this->generateOutput(' \\ Starting Again...').
            $this->generateOutput(' \\ Done Again...    ').
            PHP_EOL,
            stream_get_contents($output->getStream())
        );
    }

    public function testNonDecoratedOutput()
    {
        $bar = new ProgressIndicator($output = $this->getOutputStream(false));

        $bar->start('Starting...');
        $bar->advance();
        $bar->advance();
        $bar->setMessage('Midway...');
        $bar->advance();
        $bar->advance();
        $bar->finish('Done...');

        rewind($output->getStream());

        $this->assertEquals(
            ' Starting...'.PHP_EOL.
            ' Midway...  '.PHP_EOL.
            ' Done...    '.PHP_EOL.PHP_EOL,
            stream_get_contents($output->getStream())
        );
    }

    public function testCustomIndicatorValues()
    {
        $bar = new ProgressIndicator($output = $this->getOutputStream(), null, 100, array('a', 'b', 'c'));

        $bar->start('Starting...');
        usleep(101000);
        $bar->advance();
        usleep(101000);
        $bar->advance();
        usleep(101000);
        $bar->advance();

        rewind($output->getStream());

        $this->assertEquals(
            $this->generateOutput(' a Starting...').
            $this->generateOutput(' b Starting...').
            $this->generateOutput(' c Starting...').
            $this->generateOutput(' a Starting...'),
            stream_get_contents($output->getStream())
        );
    }

    /**
     * @expectedException \InvalidArgumentException
     * @expectedExceptionMessage Must have at least 2 indicator value characters.
     */
    public function testCannotSetInvalidIndicatorCharacters()
    {
        $bar = new ProgressIndicator($this->getOutputStream(), null, 100, array('1'));
    }

    /**
     * @expectedException \LogicException
     * @expectedExceptionMessage Progress indicator already started.
     */
    public function testCannotStartAlreadyStartedIndicator()
    {
        $bar = new ProgressIndicator($this->getOutputStream());
        $bar->start('Starting...');
        $bar->start('Starting Again.');
    }

    /**
     * @expectedException \LogicException
     * @expectedExceptionMessage Progress indicator has not yet been started.
     */
    public function testCannotAdvanceUnstartedIndicator()
    {
        $bar = new ProgressIndicator($this->getOutputStream());
        $bar->advance();
    }

    /**
     * @expectedException \LogicException
     * @expectedExceptionMessage Progress indicator has not yet been started.
     */
    public function testCannotFinishUnstartedIndicator()
    {
        $bar = new ProgressIndicator($this->getOutputStream());
        $bar->finish('Finished');
    }

    /**
     * @dataProvider provideFormat
     */
    public function testFormats($format)
    {
        $bar = new ProgressIndicator($output = $this->getOutputStream(), $format);
        $bar->start('Starting...');
        $bar->advance();

        rewind($output->getStream());

        $this->assertNotEmpty(stream_get_contents($output->getStream()));
    }

    /**
     * Provides each defined format.
     *
     * @return array
     */
    public function provideFormat()
    {
        return array(
            array('normal'),
            array('verbose'),
            array('very_verbose'),
            array('debug'),
        );
    }

    protected function getOutputStream($decorated = true, $verbosity = StreamOutput::VERBOSITY_NORMAL)
    {
        return new StreamOutput(fopen('php://memory', 'r+', false), $verbosity, $decorated);
    }

    protected function generateOutput($expected)
    {
        $count = substr_count($expected, "\n");

        return "\x0D".($count ? sprintf("\033[%dA", $count) : '').$expected;
    }
}
PKϤ$Z�I}]  ,console/Tests/Helper/FormatterHelperTest.phpnu�[���<?php

/*
 * This file is part of the Symfony package.
 *
 * (c) Fabien Potencier <fabien@symfony.com>
 *
 * For the full copyright and license information, please view the LICENSE
 * file that was distributed with this source code.
 */

namespace Symfony\Component\Console\Tests\Helper;

use Symfony\Component\Console\Helper\FormatterHelper;

class FormatterHelperTest extends \PHPUnit_Framework_TestCase
{
    public function testFormatSection()
    {
        $formatter = new FormatterHelper();

        $this->assertEquals(
            '<info>[cli]</info> Some text to display',
            $formatter->formatSection('cli', 'Some text to display'),
            '::formatSection() formats a message in a section'
        );
    }

    public function testFormatBlock()
    {
        $formatter = new FormatterHelper();

        $this->assertEquals(
            '<error> Some text to display </error>',
            $formatter->formatBlock('Some text to display', 'error'),
            '::formatBlock() formats a message in a block'
        );

        $this->assertEquals(
            '<error> Some text to display </error>'."\n".
            '<error> foo bar              </error>',
            $formatter->formatBlock(array('Some text to display', 'foo bar'), 'error'),
            '::formatBlock() formats a message in a block'
        );

        $this->assertEquals(
            '<error>                        </error>'."\n".
            '<error>  Some text to display  </error>'."\n".
            '<error>                        </error>',
            $formatter->formatBlock('Some text to display', 'error', true),
            '::formatBlock() formats a message in a block'
        );
    }

    public function testFormatBlockWithDiacriticLetters()
    {
        $formatter = new FormatterHelper();

        $this->assertEquals(
            '<error>                       </error>'."\n".
            '<error>  Du texte à afficher  </error>'."\n".
            '<error>                       </error>',
            $formatter->formatBlock('Du texte à afficher', 'error', true),
            '::formatBlock() formats a message in a block'
        );
    }

    public function testFormatBlockWithDoubleWidthDiacriticLetters()
    {
        $formatter = new FormatterHelper();
        $this->assertEquals(
            '<error>                    </error>'."\n".
            '<error>  表示するテキスト  </error>'."\n".
            '<error>                    </error>',
            $formatter->formatBlock('表示するテキスト', 'error', true),
            '::formatBlock() formats a message in a block'
        );
    }

    public function testFormatBlockLGEscaping()
    {
        $formatter = new FormatterHelper();

        $this->assertEquals(
            '<error>                            </error>'."\n".
            '<error>  \<info>some info\</info>  </error>'."\n".
            '<error>                            </error>',
            $formatter->formatBlock('<info>some info</info>', 'error', true),
            '::formatBlock() escapes \'<\' chars'
        );
    }
}
PKϤ$Z�~�[�["console/Tests/Helper/TableTest.phpnu�[���<?php

/*
 * This file is part of the Symfony package.
 *
 * (c) Fabien Potencier <fabien@symfony.com>
 *
 * For the full copyright and license information, please view the LICENSE
 * file that was distributed with this source code.
 */

namespace Symfony\Component\Console\Tests\Helper;

use Symfony\Component\Console\Helper\Table;
use Symfony\Component\Console\Helper\TableStyle;
use Symfony\Component\Console\Helper\TableSeparator;
use Symfony\Component\Console\Helper\TableCell;
use Symfony\Component\Console\Output\StreamOutput;

class TableTest extends \PHPUnit_Framework_TestCase
{
    protected $stream;

    protected function setUp()
    {
        $this->stream = fopen('php://memory', 'r+');
    }

    protected function tearDown()
    {
        fclose($this->stream);
        $this->stream = null;
    }

    /**
     * @dataProvider testRenderProvider
     */
    public function testRender($headers, $rows, $style, $expected)
    {
        $table = new Table($output = $this->getOutputStream());
        $table
            ->setHeaders($headers)
            ->setRows($rows)
            ->setStyle($style)
        ;
        $table->render();

        $this->assertEquals($expected, $this->getOutputContent($output));
    }

    /**
     * @dataProvider testRenderProvider
     */
    public function testRenderAddRows($headers, $rows, $style, $expected)
    {
        $table = new Table($output = $this->getOutputStream());
        $table
            ->setHeaders($headers)
            ->addRows($rows)
            ->setStyle($style)
        ;
        $table->render();

        $this->assertEquals($expected, $this->getOutputContent($output));
    }

    /**
     * @dataProvider testRenderProvider
     */
    public function testRenderAddRowsOneByOne($headers, $rows, $style, $expected)
    {
        $table = new Table($output = $this->getOutputStream());
        $table
            ->setHeaders($headers)
            ->setStyle($style)
        ;
        foreach ($rows as $row) {
            $table->addRow($row);
        }
        $table->render();

        $this->assertEquals($expected, $this->getOutputContent($output));
    }

    public function testRenderProvider()
    {
        $books = array(
            array('99921-58-10-7', 'Divine Comedy', 'Dante Alighieri'),
            array('9971-5-0210-0', 'A Tale of Two Cities', 'Charles Dickens'),
            array('960-425-059-0', 'The Lord of the Rings', 'J. R. R. Tolkien'),
            array('80-902734-1-6', 'And Then There Were None', 'Agatha Christie'),
        );

        return array(
            array(
                array('ISBN', 'Title', 'Author'),
                $books,
                'default',
<<<TABLE
+---------------+--------------------------+------------------+
| ISBN          | Title                    | Author           |
+---------------+--------------------------+------------------+
| 99921-58-10-7 | Divine Comedy            | Dante Alighieri  |
| 9971-5-0210-0 | A Tale of Two Cities     | Charles Dickens  |
| 960-425-059-0 | The Lord of the Rings    | J. R. R. Tolkien |
| 80-902734-1-6 | And Then There Were None | Agatha Christie  |
+---------------+--------------------------+------------------+

TABLE
            ),
            array(
                array('ISBN', 'Title', 'Author'),
                $books,
                'compact',
<<<TABLE
 ISBN          Title                    Author           
 99921-58-10-7 Divine Comedy            Dante Alighieri  
 9971-5-0210-0 A Tale of Two Cities     Charles Dickens  
 960-425-059-0 The Lord of the Rings    J. R. R. Tolkien 
 80-902734-1-6 And Then There Were None Agatha Christie  

TABLE
            ),
            array(
                array('ISBN', 'Title', 'Author'),
                $books,
                'borderless',
<<<TABLE
 =============== ========================== ================== 
  ISBN            Title                      Author            
 =============== ========================== ================== 
  99921-58-10-7   Divine Comedy              Dante Alighieri   
  9971-5-0210-0   A Tale of Two Cities       Charles Dickens   
  960-425-059-0   The Lord of the Rings      J. R. R. Tolkien  
  80-902734-1-6   And Then There Were None   Agatha Christie   
 =============== ========================== ================== 

TABLE
            ),
            array(
                array('ISBN', 'Title'),
                array(
                    array('99921-58-10-7', 'Divine Comedy', 'Dante Alighieri'),
                    array('9971-5-0210-0'),
                    array('960-425-059-0', 'The Lord of the Rings', 'J. R. R. Tolkien'),
                    array('80-902734-1-6', 'And Then There Were None', 'Agatha Christie'),
                ),
                'default',
<<<TABLE
+---------------+--------------------------+------------------+
| ISBN          | Title                    |                  |
+---------------+--------------------------+------------------+
| 99921-58-10-7 | Divine Comedy            | Dante Alighieri  |
| 9971-5-0210-0 |                          |                  |
| 960-425-059-0 | The Lord of the Rings    | J. R. R. Tolkien |
| 80-902734-1-6 | And Then There Were None | Agatha Christie  |
+---------------+--------------------------+------------------+

TABLE
            ),
            array(
                array(),
                array(
                    array('99921-58-10-7', 'Divine Comedy', 'Dante Alighieri'),
                    array('9971-5-0210-0'),
                    array('960-425-059-0', 'The Lord of the Rings', 'J. R. R. Tolkien'),
                    array('80-902734-1-6', 'And Then There Were None', 'Agatha Christie'),
                ),
                'default',
<<<TABLE
+---------------+--------------------------+------------------+
| 99921-58-10-7 | Divine Comedy            | Dante Alighieri  |
| 9971-5-0210-0 |                          |                  |
| 960-425-059-0 | The Lord of the Rings    | J. R. R. Tolkien |
| 80-902734-1-6 | And Then There Were None | Agatha Christie  |
+---------------+--------------------------+------------------+

TABLE
            ),
            array(
                array('ISBN', 'Title', 'Author'),
                array(
                    array('99921-58-10-7', "Divine\nComedy", 'Dante Alighieri'),
                    array('9971-5-0210-2', "Harry Potter\nand the Chamber of Secrets", "Rowling\nJoanne K."),
                    array('9971-5-0210-2', "Harry Potter\nand the Chamber of Secrets", "Rowling\nJoanne K."),
                    array('960-425-059-0', 'The Lord of the Rings', "J. R. R.\nTolkien"),
                ),
                'default',
<<<TABLE
+---------------+----------------------------+-----------------+
| ISBN          | Title                      | Author          |
+---------------+----------------------------+-----------------+
| 99921-58-10-7 | Divine                     | Dante Alighieri |
|               | Comedy                     |                 |
| 9971-5-0210-2 | Harry Potter               | Rowling         |
|               | and the Chamber of Secrets | Joanne K.       |
| 9971-5-0210-2 | Harry Potter               | Rowling         |
|               | and the Chamber of Secrets | Joanne K.       |
| 960-425-059-0 | The Lord of the Rings      | J. R. R.        |
|               |                            | Tolkien         |
+---------------+----------------------------+-----------------+

TABLE
            ),
            array(
                array('ISBN', 'Title'),
                array(),
                'default',
<<<TABLE
+------+-------+
| ISBN | Title |
+------+-------+

TABLE
            ),
            array(
                array(),
                array(),
                'default',
                '',
            ),
            'Cell text with tags used for Output styling' => array(
                array('ISBN', 'Title', 'Author'),
                array(
                    array('<info>99921-58-10-7</info>', '<error>Divine Comedy</error>', '<fg=blue;bg=white>Dante Alighieri</fg=blue;bg=white>'),
                    array('9971-5-0210-0', 'A Tale of Two Cities', '<info>Charles Dickens</>'),
                ),
                'default',
<<<TABLE
+---------------+----------------------+-----------------+
| ISBN          | Title                | Author          |
+---------------+----------------------+-----------------+
| 99921-58-10-7 | Divine Comedy        | Dante Alighieri |
| 9971-5-0210-0 | A Tale of Two Cities | Charles Dickens |
+---------------+----------------------+-----------------+

TABLE
            ),
            'Cell text with tags not used for Output styling' => array(
                array('ISBN', 'Title', 'Author'),
                array(
                    array('<strong>99921-58-10-700</strong>', '<f>Divine Com</f>', 'Dante Alighieri'),
                    array('9971-5-0210-0', 'A Tale of Two Cities', 'Charles Dickens'),
                ),
                'default',
<<<TABLE
+----------------------------------+----------------------+-----------------+
| ISBN                             | Title                | Author          |
+----------------------------------+----------------------+-----------------+
| <strong>99921-58-10-700</strong> | <f>Divine Com</f>    | Dante Alighieri |
| 9971-5-0210-0                    | A Tale of Two Cities | Charles Dickens |
+----------------------------------+----------------------+-----------------+

TABLE
            ),
            'Cell with colspan' => array(
                array('ISBN', 'Title', 'Author'),
                array(
                    array('99921-58-10-7', 'Divine Comedy', 'Dante Alighieri'),
                    new TableSeparator(),
                    array(new TableCell('Divine Comedy(Dante Alighieri)', array('colspan' => 3))),
                    new TableSeparator(),
                    array(
                        new TableCell('Arduino: A Quick-Start Guide', array('colspan' => 2)),
                        'Mark Schmidt',
                    ),
                    new TableSeparator(),
                    array(
                        '9971-5-0210-0',
                        new TableCell("A Tale of \nTwo Cities", array('colspan' => 2)),
                    ),
                    new TableSeparator(),
                    array(
                        new TableCell('Cupiditate dicta atque porro, tempora exercitationem modi animi nulla nemo vel nihil!', array('colspan' => 3)),
                    ),
                ),
                'default',
<<<TABLE
+-------------------------------+-------------------------------+-----------------------------+
| ISBN                          | Title                         | Author                      |
+-------------------------------+-------------------------------+-----------------------------+
| 99921-58-10-7                 | Divine Comedy                 | Dante Alighieri             |
+-------------------------------+-------------------------------+-----------------------------+
| Divine Comedy(Dante Alighieri)                                                              |
+-------------------------------+-------------------------------+-----------------------------+
| Arduino: A Quick-Start Guide                                  | Mark Schmidt                |
+-------------------------------+-------------------------------+-----------------------------+
| 9971-5-0210-0                 | A Tale of                                                   |
|                               | Two Cities                                                  |
+-------------------------------+-------------------------------+-----------------------------+
| Cupiditate dicta atque porro, tempora exercitationem modi animi nulla nemo vel nihil!       |
+-------------------------------+-------------------------------+-----------------------------+

TABLE
            ),
            'Cell with rowspan' => array(
                array('ISBN', 'Title', 'Author'),
                array(
                    array(
                        new TableCell('9971-5-0210-0', array('rowspan' => 3)),
                        'Divine Comedy',
                        'Dante Alighieri',
                    ),
                    array('A Tale of Two Cities', 'Charles Dickens'),
                    array("The Lord of \nthe Rings", "J. R. \nR. Tolkien"),
                    new TableSeparator(),
                    array('80-902734-1-6', new TableCell("And Then \nThere \nWere None", array('rowspan' => 3)), 'Agatha Christie'),
                    array('80-902734-1-7', 'Test'),
                ),
                'default',
<<<TABLE
+---------------+----------------------+-----------------+
| ISBN          | Title                | Author          |
+---------------+----------------------+-----------------+
| 9971-5-0210-0 | Divine Comedy        | Dante Alighieri |
|               | A Tale of Two Cities | Charles Dickens |
|               | The Lord of          | J. R.           |
|               | the Rings            | R. Tolkien      |
+---------------+----------------------+-----------------+
| 80-902734-1-6 | And Then             | Agatha Christie |
| 80-902734-1-7 | There                | Test            |
|               | Were None            |                 |
+---------------+----------------------+-----------------+

TABLE
            ),
            'Cell with rowspan and colspan' => array(
                array('ISBN', 'Title', 'Author'),
                array(
                    array(
                        new TableCell('9971-5-0210-0', array('rowspan' => 2, 'colspan' => 2)),
                        'Dante Alighieri',
                    ),
                    array('Charles Dickens'),
                    new TableSeparator(),
                    array(
                        'Dante Alighieri',
                        new TableCell('9971-5-0210-0', array('rowspan' => 3, 'colspan' => 2)),
                    ),
                    array('J. R. R. Tolkien'),
                    array('J. R. R'),
                ),
                'default',
<<<TABLE
+------------------+---------+-----------------+
| ISBN             | Title   | Author          |
+------------------+---------+-----------------+
| 9971-5-0210-0              | Dante Alighieri |
|                            | Charles Dickens |
+------------------+---------+-----------------+
| Dante Alighieri  | 9971-5-0210-0             |
| J. R. R. Tolkien |                           |
| J. R. R          |                           |
+------------------+---------+-----------------+

TABLE
            ),
            'Cell with rowspan and colspan contains new line break' => array(
                array('ISBN', 'Title', 'Author'),
                array(
                    array(
                        new TableCell("9971\n-5-\n021\n0-0", array('rowspan' => 2, 'colspan' => 2)),
                        'Dante Alighieri',
                    ),
                    array('Charles Dickens'),
                    new TableSeparator(),
                    array(
                        'Dante Alighieri',
                        new TableCell("9971\n-5-\n021\n0-0", array('rowspan' => 2, 'colspan' => 2)),
                    ),
                    array('Charles Dickens'),
                    new TableSeparator(),
                    array(
                        new TableCell("9971\n-5-\n021\n0-0", array('rowspan' => 2, 'colspan' => 2)),
                        new TableCell("Dante \nAlighieri", array('rowspan' => 2, 'colspan' => 1)),
                    ),
                ),
                'default',
<<<TABLE
+-----------------+-------+-----------------+
| ISBN            | Title | Author          |
+-----------------+-------+-----------------+
| 9971                    | Dante Alighieri |
| -5-                     | Charles Dickens |
| 021                     |                 |
| 0-0                     |                 |
+-----------------+-------+-----------------+
| Dante Alighieri | 9971                    |
| Charles Dickens | -5-                     |
|                 | 021                     |
|                 | 0-0                     |
+-----------------+-------+-----------------+
| 9971                    | Dante           |
| -5-                     | Alighieri       |
| 021                     |                 |
| 0-0                     |                 |
+-----------------+-------+-----------------+

TABLE
            ),
            'Cell with rowspan and colspan without using TableSeparator' => array(
                array('ISBN', 'Title', 'Author'),
                array(
                    array(
                        new TableCell("9971\n-5-\n021\n0-0", array('rowspan' => 2, 'colspan' => 2)),
                        'Dante Alighieri',
                    ),
                    array('Charles Dickens'),
                    array(
                        'Dante Alighieri',
                        new TableCell("9971\n-5-\n021\n0-0", array('rowspan' => 2, 'colspan' => 2)),
                    ),
                    array('Charles Dickens'),
                ),
                'default',
<<<TABLE
+-----------------+-------+-----------------+
| ISBN            | Title | Author          |
+-----------------+-------+-----------------+
| 9971                    | Dante Alighieri |
| -5-                     | Charles Dickens |
| 021                     |                 |
| 0-0                     |                 |
| Dante Alighieri | 9971                    |
| Charles Dickens | -5-                     |
|                 | 021                     |
|                 | 0-0                     |
+-----------------+-------+-----------------+

TABLE
            ),
            'Cell with rowspan and colspan with separator inside a rowspan' => array(
                array('ISBN', 'Author'),
                array(
                    array(
                        new TableCell('9971-5-0210-0', array('rowspan' => 3, 'colspan' => 1)),
                        'Dante Alighieri',
                    ),
                    array(new TableSeparator()),
                    array('Charles Dickens'),
                ),
                'default',
<<<TABLE
+---------------+-----------------+
| ISBN          | Author          |
+---------------+-----------------+
| 9971-5-0210-0 | Dante Alighieri |
|               |-----------------|
|               | Charles Dickens |
+---------------+-----------------+

TABLE
            ),
            'Multiple header lines' => array(
                array(
                    array(new TableCell('Main title', array('colspan' => 3))),
                    array('ISBN', 'Title', 'Author'),
                ),
                array(),
                'default',
<<<TABLE
+------+-------+--------+
| Main title            |
+------+-------+--------+
| ISBN | Title | Author |
+------+-------+--------+

TABLE
            ),
            'Row with multiple cells' => array(
                array(),
                array(
                    array(
                        new TableCell('1', array('colspan' => 3)),
                        new TableCell('2', array('colspan' => 2)),
                        new TableCell('3', array('colspan' => 2)),
                        new TableCell('4', array('colspan' => 2)),
                    ),
        ),
                'default',
<<<TABLE
+---+--+--+---+--+---+--+---+--+
| 1       | 2    | 3    | 4    |
+---+--+--+---+--+---+--+---+--+

TABLE
            ),
        );
    }

    public function testRenderMultiByte()
    {
        $table = new Table($output = $this->getOutputStream());
        $table
            ->setHeaders(array('■■'))
            ->setRows(array(array(1234)))
            ->setStyle('default')
        ;
        $table->render();

        $expected =
<<<TABLE
+------+
| ■■   |
+------+
| 1234 |
+------+

TABLE;

        $this->assertEquals($expected, $this->getOutputContent($output));
    }

    public function testStyle()
    {
        $style = new TableStyle();
        $style
            ->setHorizontalBorderChar('.')
            ->setVerticalBorderChar('.')
            ->setCrossingChar('.')
        ;

        Table::setStyleDefinition('dotfull', $style);
        $table = new Table($output = $this->getOutputStream());
        $table
            ->setHeaders(array('Foo'))
            ->setRows(array(array('Bar')))
            ->setStyle('dotfull');
        $table->render();

        $expected =
<<<TABLE
.......
. Foo .
.......
. Bar .
.......

TABLE;

        $this->assertEquals($expected, $this->getOutputContent($output));
    }

    public function testRowSeparator()
    {
        $table = new Table($output = $this->getOutputStream());
        $table
            ->setHeaders(array('Foo'))
            ->setRows(array(
                array('Bar1'),
                new TableSeparator(),
                array('Bar2'),
                new TableSeparator(),
                array('Bar3'),
            ));
        $table->render();

        $expected =
<<<TABLE
+------+
| Foo  |
+------+
| Bar1 |
+------+
| Bar2 |
+------+
| Bar3 |
+------+

TABLE;

        $this->assertEquals($expected, $this->getOutputContent($output));

        $this->assertEquals($table, $table->addRow(new TableSeparator()), 'fluent interface on addRow() with a single TableSeparator() works');
    }

    public function testRenderMultiCalls()
    {
        $table = new Table($output = $this->getOutputStream());
        $table->setRows(array(
            array(new TableCell('foo', array('colspan' => 2))),
        ));
        $table->render();
        $table->render();
        $table->render();

        $expected =
<<<TABLE
+----+---+
| foo    |
+----+---+
+----+---+
| foo    |
+----+---+
+----+---+
| foo    |
+----+---+

TABLE;

        $this->assertEquals($expected, $this->getOutputContent($output));
    }

    public function testColumnStyle()
    {
        $table = new Table($output = $this->getOutputStream());
        $table
            ->setHeaders(array('ISBN', 'Title', 'Author', 'Price'))
            ->setRows(array(
                array('99921-58-10-7', 'Divine Comedy', 'Dante Alighieri', '9.95'),
                array('9971-5-0210-0', 'A Tale of Two Cities', 'Charles Dickens', '139.25'),
            ));

        $style = new TableStyle();
        $style->setPadType(STR_PAD_LEFT);
        $table->setColumnStyle(3, $style);

        $table->render();

        $expected =
            <<<TABLE
+---------------+----------------------+-----------------+--------+
| ISBN          | Title                | Author          |  Price |
+---------------+----------------------+-----------------+--------+
| 99921-58-10-7 | Divine Comedy        | Dante Alighieri |   9.95 |
| 9971-5-0210-0 | A Tale of Two Cities | Charles Dickens | 139.25 |
+---------------+----------------------+-----------------+--------+

TABLE;

        $this->assertEquals($expected, $this->getOutputContent($output));
    }

    protected function getOutputStream()
    {
        return new StreamOutput($this->stream, StreamOutput::VERBOSITY_NORMAL, false);
    }

    protected function getOutputContent(StreamOutput $output)
    {
        rewind($output->getStream());

        return str_replace(PHP_EOL, "\n", stream_get_contents($output->getStream()));
    }
}
PKϤ$Z
c�>��&console/Tests/Helper/HelperSetTest.phpnu�[���<?php

/*
 * This file is part of the Symfony package.
 *
 * (c) Fabien Potencier <fabien@symfony.com>
 *
 * For the full copyright and license information, please view the LICENSE
 * file that was distributed with this source code.
 */

namespace Symfony\Component\Console\Tests\Helper;

use Symfony\Component\Console\Helper\HelperSet;
use Symfony\Component\Console\Command\Command;

class HelperSetTest extends \PHPUnit_Framework_TestCase
{
    public function testConstructor()
    {
        $mock_helper = $this->getGenericMockHelper('fake_helper');
        $helperset = new HelperSet(array('fake_helper_alias' => $mock_helper));

        $this->assertEquals($mock_helper, $helperset->get('fake_helper_alias'), '__construct sets given helper to helpers');
        $this->assertTrue($helperset->has('fake_helper_alias'), '__construct sets helper alias for given helper');
    }

    public function testSet()
    {
        $helperset = new HelperSet();
        $helperset->set($this->getGenericMockHelper('fake_helper', $helperset));
        $this->assertTrue($helperset->has('fake_helper'), '->set() adds helper to helpers');

        $helperset = new HelperSet();
        $helperset->set($this->getGenericMockHelper('fake_helper_01', $helperset));
        $helperset->set($this->getGenericMockHelper('fake_helper_02', $helperset));
        $this->assertTrue($helperset->has('fake_helper_01'), '->set() will set multiple helpers on consecutive calls');
        $this->assertTrue($helperset->has('fake_helper_02'), '->set() will set multiple helpers on consecutive calls');

        $helperset = new HelperSet();
        $helperset->set($this->getGenericMockHelper('fake_helper', $helperset), 'fake_helper_alias');
        $this->assertTrue($helperset->has('fake_helper'), '->set() adds helper alias when set');
        $this->assertTrue($helperset->has('fake_helper_alias'), '->set() adds helper alias when set');
    }

    public function testHas()
    {
        $helperset = new HelperSet(array('fake_helper_alias' => $this->getGenericMockHelper('fake_helper')));
        $this->assertTrue($helperset->has('fake_helper'), '->has() finds set helper');
        $this->assertTrue($helperset->has('fake_helper_alias'), '->has() finds set helper by alias');
    }

    public function testGet()
    {
        $helper_01 = $this->getGenericMockHelper('fake_helper_01');
        $helper_02 = $this->getGenericMockHelper('fake_helper_02');
        $helperset = new HelperSet(array('fake_helper_01_alias' => $helper_01, 'fake_helper_02_alias' => $helper_02));
        $this->assertEquals($helper_01, $helperset->get('fake_helper_01'), '->get() returns correct helper by name');
        $this->assertEquals($helper_01, $helperset->get('fake_helper_01_alias'), '->get() returns correct helper by alias');
        $this->assertEquals($helper_02, $helperset->get('fake_helper_02'), '->get() returns correct helper by name');
        $this->assertEquals($helper_02, $helperset->get('fake_helper_02_alias'), '->get() returns correct helper by alias');

        $helperset = new HelperSet();
        try {
            $helperset->get('foo');
            $this->fail('->get() throws InvalidArgumentException when helper not found');
        } catch (\Exception $e) {
            $this->assertInstanceOf('\InvalidArgumentException', $e, '->get() throws InvalidArgumentException when helper not found');
            $this->assertInstanceOf('Symfony\Component\Console\Exception\ExceptionInterface', $e, '->get() throws domain specific exception when helper not found');
            $this->assertContains('The helper "foo" is not defined.', $e->getMessage(), '->get() throws InvalidArgumentException when helper not found');
        }
    }

    public function testSetCommand()
    {
        $cmd_01 = new Command('foo');
        $cmd_02 = new Command('bar');

        $helperset = new HelperSet();
        $helperset->setCommand($cmd_01);
        $this->assertEquals($cmd_01, $helperset->getCommand(), '->setCommand() stores given command');

        $helperset = new HelperSet();
        $helperset->setCommand($cmd_01);
        $helperset->setCommand($cmd_02);
        $this->assertEquals($cmd_02, $helperset->getCommand(), '->setCommand() overwrites stored command with consecutive calls');
    }

    public function testGetCommand()
    {
        $cmd = new Command('foo');
        $helperset = new HelperSet();
        $helperset->setCommand($cmd);
        $this->assertEquals($cmd, $helperset->getCommand(), '->getCommand() retrieves stored command');
    }

    public function testIteration()
    {
        $helperset = new HelperSet();
        $helperset->set($this->getGenericMockHelper('fake_helper_01', $helperset));
        $helperset->set($this->getGenericMockHelper('fake_helper_02', $helperset));

        $helpers = array('fake_helper_01', 'fake_helper_02');
        $i = 0;

        foreach ($helperset as $helper) {
            $this->assertEquals($helpers[$i++], $helper->getName());
        }
    }

    /**
     * Create a generic mock for the helper interface. Optionally check for a call to setHelperSet with a specific
     * helperset instance.
     *
     * @param string    $name
     * @param HelperSet $helperset allows a mock to verify a particular helperset set is being added to the Helper
     */
    private function getGenericMockHelper($name, HelperSet $helperset = null)
    {
        $mock_helper = $this->getMock('\Symfony\Component\Console\Helper\HelperInterface');
        $mock_helper->expects($this->any())
            ->method('getName')
            ->will($this->returnValue($name));

        if ($helperset) {
            $mock_helper->expects($this->any())
                ->method('setHelperSet')
                ->with($this->equalTo($helperset));
        }

        return $mock_helper;
    }
}
PKϤ$Z{�D��4console/Tests/Formatter/OutputFormatterStyleTest.phpnu�[���<?php

/*
 * This file is part of the Symfony package.
 *
 * (c) Fabien Potencier <fabien@symfony.com>
 *
 * For the full copyright and license information, please view the LICENSE
 * file that was distributed with this source code.
 */

namespace Symfony\Component\Console\Tests\Formatter;

use Symfony\Component\Console\Formatter\OutputFormatterStyle;

class OutputFormatterStyleTest extends \PHPUnit_Framework_TestCase
{
    public function testConstructor()
    {
        $style = new OutputFormatterStyle('green', 'black', array('bold', 'underscore'));
        $this->assertEquals("\033[32;40;1;4mfoo\033[39;49;22;24m", $style->apply('foo'));

        $style = new OutputFormatterStyle('red', null, array('blink'));
        $this->assertEquals("\033[31;5mfoo\033[39;25m", $style->apply('foo'));

        $style = new OutputFormatterStyle(null, 'white');
        $this->assertEquals("\033[47mfoo\033[49m", $style->apply('foo'));
    }

    public function testForeground()
    {
        $style = new OutputFormatterStyle();

        $style->setForeground('black');
        $this->assertEquals("\033[30mfoo\033[39m", $style->apply('foo'));

        $style->setForeground('blue');
        $this->assertEquals("\033[34mfoo\033[39m", $style->apply('foo'));

        $style->setForeground('default');
        $this->assertEquals("\033[39mfoo\033[39m", $style->apply('foo'));

        $this->setExpectedException('InvalidArgumentException');
        $style->setForeground('undefined-color');
    }

    public function testBackground()
    {
        $style = new OutputFormatterStyle();

        $style->setBackground('black');
        $this->assertEquals("\033[40mfoo\033[49m", $style->apply('foo'));

        $style->setBackground('yellow');
        $this->assertEquals("\033[43mfoo\033[49m", $style->apply('foo'));

        $style->setBackground('default');
        $this->assertEquals("\033[49mfoo\033[49m", $style->apply('foo'));

        $this->setExpectedException('InvalidArgumentException');
        $style->setBackground('undefined-color');
    }

    public function testOptions()
    {
        $style = new OutputFormatterStyle();

        $style->setOptions(array('reverse', 'conceal'));
        $this->assertEquals("\033[7;8mfoo\033[27;28m", $style->apply('foo'));

        $style->setOption('bold');
        $this->assertEquals("\033[7;8;1mfoo\033[27;28;22m", $style->apply('foo'));

        $style->unsetOption('reverse');
        $this->assertEquals("\033[8;1mfoo\033[28;22m", $style->apply('foo'));

        $style->setOption('bold');
        $this->assertEquals("\033[8;1mfoo\033[28;22m", $style->apply('foo'));

        $style->setOptions(array('bold'));
        $this->assertEquals("\033[1mfoo\033[22m", $style->apply('foo'));

        try {
            $style->setOption('foo');
            $this->fail('->setOption() throws an \InvalidArgumentException when the option does not exist in the available options');
        } catch (\Exception $e) {
            $this->assertInstanceOf('\InvalidArgumentException', $e, '->setOption() throws an \InvalidArgumentException when the option does not exist in the available options');
            $this->assertContains('Invalid option specified: "foo"', $e->getMessage(), '->setOption() throws an \InvalidArgumentException when the option does not exist in the available options');
        }

        try {
            $style->unsetOption('foo');
            $this->fail('->unsetOption() throws an \InvalidArgumentException when the option does not exist in the available options');
        } catch (\Exception $e) {
            $this->assertInstanceOf('\InvalidArgumentException', $e, '->unsetOption() throws an \InvalidArgumentException when the option does not exist in the available options');
            $this->assertContains('Invalid option specified: "foo"', $e->getMessage(), '->unsetOption() throws an \InvalidArgumentException when the option does not exist in the available options');
        }
    }
}
PKϤ$Z� R�ww9console/Tests/Formatter/OutputFormatterStyleStackTest.phpnu�[���<?php

/*
 * This file is part of the Symfony package.
 *
 * (c) Fabien Potencier <fabien@symfony.com>
 *
 * For the full copyright and license information, please view the LICENSE
 * file that was distributed with this source code.
 */

namespace Symfony\Component\Console\Tests\Formatter;

use Symfony\Component\Console\Formatter\OutputFormatterStyleStack;
use Symfony\Component\Console\Formatter\OutputFormatterStyle;

class OutputFormatterStyleStackTest extends \PHPUnit_Framework_TestCase
{
    public function testPush()
    {
        $stack = new OutputFormatterStyleStack();
        $stack->push($s1 = new OutputFormatterStyle('white', 'black'));
        $stack->push($s2 = new OutputFormatterStyle('yellow', 'blue'));

        $this->assertEquals($s2, $stack->getCurrent());

        $stack->push($s3 = new OutputFormatterStyle('green', 'red'));

        $this->assertEquals($s3, $stack->getCurrent());
    }

    public function testPop()
    {
        $stack = new OutputFormatterStyleStack();
        $stack->push($s1 = new OutputFormatterStyle('white', 'black'));
        $stack->push($s2 = new OutputFormatterStyle('yellow', 'blue'));

        $this->assertEquals($s2, $stack->pop());
        $this->assertEquals($s1, $stack->pop());
    }

    public function testPopEmpty()
    {
        $stack = new OutputFormatterStyleStack();
        $style = new OutputFormatterStyle();

        $this->assertEquals($style, $stack->pop());
    }

    public function testPopNotLast()
    {
        $stack = new OutputFormatterStyleStack();
        $stack->push($s1 = new OutputFormatterStyle('white', 'black'));
        $stack->push($s2 = new OutputFormatterStyle('yellow', 'blue'));
        $stack->push($s3 = new OutputFormatterStyle('green', 'red'));

        $this->assertEquals($s2, $stack->pop($s2));
        $this->assertEquals($s1, $stack->pop());
    }

    /**
     * @expectedException \InvalidArgumentException
     */
    public function testInvalidPop()
    {
        $stack = new OutputFormatterStyleStack();
        $stack->push(new OutputFormatterStyle('white', 'black'));
        $stack->pop(new OutputFormatterStyle('yellow', 'blue'));
    }
}
PKϤ$Zp�®� � /console/Tests/Formatter/OutputFormatterTest.phpnu�[���<?php

/*
 * This file is part of the Symfony package.
 *
 * (c) Fabien Potencier <fabien@symfony.com>
 *
 * For the full copyright and license information, please view the LICENSE
 * file that was distributed with this source code.
 */

namespace Symfony\Component\Console\Tests\Formatter;

use Symfony\Component\Console\Formatter\OutputFormatter;
use Symfony\Component\Console\Formatter\OutputFormatterStyle;

class OutputFormatterTest extends \PHPUnit_Framework_TestCase
{
    public function testEmptyTag()
    {
        $formatter = new OutputFormatter(true);
        $this->assertEquals('foo<>bar', $formatter->format('foo<>bar'));
    }

    public function testLGCharEscaping()
    {
        $formatter = new OutputFormatter(true);

        $this->assertEquals('foo<bar', $formatter->format('foo\\<bar'));
        $this->assertEquals('<info>some info</info>', $formatter->format('\\<info>some info\\</info>'));
        $this->assertEquals('\\<info>some info\\</info>', OutputFormatter::escape('<info>some info</info>'));

        $this->assertEquals(
            "\033[33mSymfony\\Component\\Console does work very well!\033[39m",
            $formatter->format('<comment>Symfony\Component\Console does work very well!</comment>')
        );
    }

    public function testBundledStyles()
    {
        $formatter = new OutputFormatter(true);

        $this->assertTrue($formatter->hasStyle('error'));
        $this->assertTrue($formatter->hasStyle('info'));
        $this->assertTrue($formatter->hasStyle('comment'));
        $this->assertTrue($formatter->hasStyle('question'));

        $this->assertEquals(
            "\033[37;41msome error\033[39;49m",
            $formatter->format('<error>some error</error>')
        );
        $this->assertEquals(
            "\033[32msome info\033[39m",
            $formatter->format('<info>some info</info>')
        );
        $this->assertEquals(
            "\033[33msome comment\033[39m",
            $formatter->format('<comment>some comment</comment>')
        );
        $this->assertEquals(
            "\033[30;46msome question\033[39;49m",
            $formatter->format('<question>some question</question>')
        );
    }

    public function testNestedStyles()
    {
        $formatter = new OutputFormatter(true);

        $this->assertEquals(
            "\033[37;41msome \033[39;49m\033[32msome info\033[39m\033[37;41m error\033[39;49m",
            $formatter->format('<error>some <info>some info</info> error</error>')
        );
    }

    public function testAdjacentStyles()
    {
        $formatter = new OutputFormatter(true);

        $this->assertEquals(
            "\033[37;41msome error\033[39;49m\033[32msome info\033[39m",
            $formatter->format('<error>some error</error><info>some info</info>')
        );
    }

    public function testStyleMatchingNotGreedy()
    {
        $formatter = new OutputFormatter(true);

        $this->assertEquals(
            "(\033[32m>=2.0,<2.3\033[39m)",
            $formatter->format('(<info>>=2.0,<2.3</info>)')
        );
    }

    public function testStyleEscaping()
    {
        $formatter = new OutputFormatter(true);

        $this->assertEquals(
            "(\033[32mz>=2.0,<<<a2.3\\\033[39m)",
            $formatter->format('(<info>'.$formatter->escape('z>=2.0,<\\<<a2.3\\').'</info>)')
        );

        $this->assertEquals(
            "\033[32m<error>some error</error>\033[39m",
            $formatter->format('<info>'.$formatter->escape('<error>some error</error>').'</info>')
        );
    }

    public function testDeepNestedStyles()
    {
        $formatter = new OutputFormatter(true);

        $this->assertEquals(
            "\033[37;41merror\033[39;49m\033[32minfo\033[39m\033[33mcomment\033[39m\033[37;41merror\033[39;49m",
            $formatter->format('<error>error<info>info<comment>comment</info>error</error>')
        );
    }

    public function testNewStyle()
    {
        $formatter = new OutputFormatter(true);

        $style = new OutputFormatterStyle('blue', 'white');
        $formatter->setStyle('test', $style);

        $this->assertEquals($style, $formatter->getStyle('test'));
        $this->assertNotEquals($style, $formatter->getStyle('info'));

        $style = new OutputFormatterStyle('blue', 'white');
        $formatter->setStyle('b', $style);

        $this->assertEquals("\033[34;47msome \033[39;49m\033[34;47mcustom\033[39;49m\033[34;47m msg\033[39;49m", $formatter->format('<test>some <b>custom</b> msg</test>'));
    }

    public function testRedefineStyle()
    {
        $formatter = new OutputFormatter(true);

        $style = new OutputFormatterStyle('blue', 'white');
        $formatter->setStyle('info', $style);

        $this->assertEquals("\033[34;47msome custom msg\033[39;49m", $formatter->format('<info>some custom msg</info>'));
    }

    public function testInlineStyle()
    {
        $formatter = new OutputFormatter(true);

        $this->assertEquals("\033[34;41msome text\033[39;49m", $formatter->format('<fg=blue;bg=red>some text</>'));
        $this->assertEquals("\033[34;41msome text\033[39;49m", $formatter->format('<fg=blue;bg=red>some text</fg=blue;bg=red>'));
    }

    public function testNonStyleTag()
    {
        $formatter = new OutputFormatter(true);

        $this->assertEquals("\033[32msome \033[39m\033[32m<tag>\033[39m\033[32m \033[39m\033[32m<setting=value>\033[39m\033[32m styled \033[39m\033[32m<p>\033[39m\033[32msingle-char tag\033[39m\033[32m</p>\033[39m", $formatter->format('<info>some <tag> <setting=value> styled <p>single-char tag</p></info>'));
    }

    public function testFormatLongString()
    {
        $formatter = new OutputFormatter(true);
        $long = str_repeat('\\', 14000);
        $this->assertEquals("\033[37;41msome error\033[39;49m".$long, $formatter->format('<error>some error</error>'.$long));
    }

    public function testFormatToStringObject()
    {
        $formatter = new OutputFormatter(false);
        $this->assertEquals(
            'some info', $formatter->format(new TableCell())
        );
    }

    public function testNotDecoratedFormatter()
    {
        $formatter = new OutputFormatter(false);

        $this->assertTrue($formatter->hasStyle('error'));
        $this->assertTrue($formatter->hasStyle('info'));
        $this->assertTrue($formatter->hasStyle('comment'));
        $this->assertTrue($formatter->hasStyle('question'));

        $this->assertEquals(
            'some error', $formatter->format('<error>some error</error>')
        );
        $this->assertEquals(
            'some info', $formatter->format('<info>some info</info>')
        );
        $this->assertEquals(
            'some comment', $formatter->format('<comment>some comment</comment>')
        );
        $this->assertEquals(
            'some question', $formatter->format('<question>some question</question>')
        );

        $formatter->setDecorated(true);

        $this->assertEquals(
            "\033[37;41msome error\033[39;49m", $formatter->format('<error>some error</error>')
        );
        $this->assertEquals(
            "\033[32msome info\033[39m", $formatter->format('<info>some info</info>')
        );
        $this->assertEquals(
            "\033[33msome comment\033[39m", $formatter->format('<comment>some comment</comment>')
        );
        $this->assertEquals(
            "\033[30;46msome question\033[39;49m", $formatter->format('<question>some question</question>')
        );
    }

    public function testContentWithLineBreaks()
    {
        $formatter = new OutputFormatter(true);

        $this->assertEquals(<<<EOF
\033[32m
some text\033[39m
EOF
            , $formatter->format(<<<'EOF'
<info>
some text</info>
EOF
        ));

        $this->assertEquals(<<<EOF
\033[32msome text
\033[39m
EOF
            , $formatter->format(<<<'EOF'
<info>some text
</info>
EOF
        ));

        $this->assertEquals(<<<EOF
\033[32m
some text
\033[39m
EOF
            , $formatter->format(<<<'EOF'
<info>
some text
</info>
EOF
        ));

        $this->assertEquals(<<<EOF
\033[32m
some text
more text
\033[39m
EOF
            , $formatter->format(<<<'EOF'
<info>
some text
more text
</info>
EOF
        ));
    }
}

class TableCell
{
    public function __toString()
    {
        return '<info>some info</info>';
    }
}
PKϤ$Z��+,��console/Shell.phpnu�[���<?php

/*
 * This file is part of the Symfony package.
 *
 * (c) Fabien Potencier <fabien@symfony.com>
 *
 * For the full copyright and license information, please view the LICENSE
 * file that was distributed with this source code.
 */

namespace Symfony\Component\Console;

use Symfony\Component\Console\Exception\RuntimeException;
use Symfony\Component\Console\Input\StringInput;
use Symfony\Component\Console\Output\ConsoleOutput;
use Symfony\Component\Process\ProcessBuilder;
use Symfony\Component\Process\PhpExecutableFinder;

/**
 * A Shell wraps an Application to add shell capabilities to it.
 *
 * Support for history and completion only works with a PHP compiled
 * with readline support (either --with-readline or --with-libedit)
 *
 * @deprecated since version 2.8, to be removed in 3.0.
 *
 * @author Fabien Potencier <fabien@symfony.com>
 * @author Martin Hasoň <martin.hason@gmail.com>
 */
class Shell
{
    private $application;
    private $history;
    private $output;
    private $hasReadline;
    private $processIsolation = false;

    /**
     * Constructor.
     *
     * If there is no readline support for the current PHP executable
     * a \RuntimeException exception is thrown.
     *
     * @param Application $application An application instance
     */
    public function __construct(Application $application)
    {
        @trigger_error('The '.__CLASS__.' class is deprecated since Symfony 2.8 and will be removed in 3.0.', E_USER_DEPRECATED);

        $this->hasReadline = function_exists('readline');
        $this->application = $application;
        $this->history = getenv('HOME').'/.history_'.$application->getName();
        $this->output = new ConsoleOutput();
    }

    /**
     * Runs the shell.
     */
    public function run()
    {
        $this->application->setAutoExit(false);
        $this->application->setCatchExceptions(true);

        if ($this->hasReadline) {
            readline_read_history($this->history);
            readline_completion_function(array($this, 'autocompleter'));
        }

        $this->output->writeln($this->getHeader());
        $php = null;
        if ($this->processIsolation) {
            $finder = new PhpExecutableFinder();
            $php = $finder->find();
            $this->output->writeln(<<<'EOF'
<info>Running with process isolation, you should consider this:</info>
  * each command is executed as separate process,
  * commands don't support interactivity, all params must be passed explicitly,
  * commands output is not colorized.

EOF
            );
        }

        while (true) {
            $command = $this->readline();

            if (false === $command) {
                $this->output->writeln("\n");

                break;
            }

            if ($this->hasReadline) {
                readline_add_history($command);
                readline_write_history($this->history);
            }

            if ($this->processIsolation) {
                $pb = new ProcessBuilder();

                $process = $pb
                    ->add($php)
                    ->add($_SERVER['argv'][0])
                    ->add($command)
                    ->inheritEnvironmentVariables(true)
                    ->getProcess()
                ;

                $output = $this->output;
                $process->run(function ($type, $data) use ($output) {
                    $output->writeln($data);
                });

                $ret = $process->getExitCode();
            } else {
                $ret = $this->application->run(new StringInput($command), $this->output);
            }

            if (0 !== $ret) {
                $this->output->writeln(sprintf('<error>The command terminated with an error status (%s)</error>', $ret));
            }
        }
    }

    /**
     * Returns the shell header.
     *
     * @return string The header string
     */
    protected function getHeader()
    {
        return <<<EOF

Welcome to the <info>{$this->application->getName()}</info> shell (<comment>{$this->application->getVersion()}</comment>).

At the prompt, type <comment>help</comment> for some help,
or <comment>list</comment> to get a list of available commands.

To exit the shell, type <comment>^D</comment>.

EOF;
    }

    /**
     * Renders a prompt.
     *
     * @return string The prompt
     */
    protected function getPrompt()
    {
        // using the formatter here is required when using readline
        return $this->output->getFormatter()->format($this->application->getName().' > ');
    }

    protected function getOutput()
    {
        return $this->output;
    }

    protected function getApplication()
    {
        return $this->application;
    }

    /**
     * Tries to return autocompletion for the current entered text.
     *
     * @param string $text The last segment of the entered text
     *
     * @return bool|array A list of guessed strings or true
     */
    private function autocompleter($text)
    {
        $info = readline_info();
        $text = substr($info['line_buffer'], 0, $info['end']);

        if ($info['point'] !== $info['end']) {
            return true;
        }

        // task name?
        if (false === strpos($text, ' ') || !$text) {
            return array_keys($this->application->all());
        }

        // options and arguments?
        try {
            $command = $this->application->find(substr($text, 0, strpos($text, ' ')));
        } catch (\Exception $e) {
            return true;
        }

        $list = array('--help');
        foreach ($command->getDefinition()->getOptions() as $option) {
            $list[] = '--'.$option->getName();
        }

        return $list;
    }

    /**
     * Reads a single line from standard input.
     *
     * @return string The single line from standard input
     */
    private function readline()
    {
        if ($this->hasReadline) {
            $line = readline($this->getPrompt());
        } else {
            $this->output->write($this->getPrompt());
            $line = fgets(STDIN, 1024);
            $line = (false === $line || '' === $line) ? false : rtrim($line);
        }

        return $line;
    }

    public function getProcessIsolation()
    {
        return $this->processIsolation;
    }

    public function setProcessIsolation($processIsolation)
    {
        $this->processIsolation = (bool) $processIsolation;

        if ($this->processIsolation && !class_exists('Symfony\\Component\\Process\\Process')) {
            throw new RuntimeException('Unable to isolate processes as the Symfony Process Component is not installed.');
        }
    }
}
PKϤ$Z�t5N*console/Tester/CommandCompletionTester.phpnu�[���<?php

/*
 * This file is part of the Symfony package.
 *
 * (c) Fabien Potencier <fabien@symfony.com>
 *
 * For the full copyright and license information, please view the LICENSE
 * file that was distributed with this source code.
 */

namespace Symfony\Component\Console\Tester;

use Symfony\Component\Console\Command\Command;
use Symfony\Component\Console\Completion\CompletionInput;
use Symfony\Component\Console\Completion\CompletionSuggestions;

/**
 * Eases the testing of command completion.
 *
 * @author Jérôme Tamarelle <jerome@tamarelle.net>
 */
class CommandCompletionTester
{
    private $command;

    public function __construct(Command $command)
    {
        $this->command = $command;
    }

    /**
     * Create completion suggestions from input tokens.
     */
    public function complete(array $input): array
    {
        $currentIndex = \count($input);
        if ('' === end($input)) {
            array_pop($input);
        }
        array_unshift($input, $this->command->getName());

        $completionInput = CompletionInput::fromTokens($input, $currentIndex);
        $completionInput->bind($this->command->getDefinition());
        $suggestions = new CompletionSuggestions();

        $this->command->complete($completionInput, $suggestions);

        $options = [];
        foreach ($suggestions->getOptionSuggestions() as $option) {
            $options[] = '--'.$option->getName();
        }

        return array_map('strval', array_merge($options, $suggestions->getValueSuggestions()));
    }
}
PKϤ$Z7)a�:	:	 console/Tester/CommandTester.phpnu�[���<?php

/*
 * This file is part of the Symfony package.
 *
 * (c) Fabien Potencier <fabien@symfony.com>
 *
 * For the full copyright and license information, please view the LICENSE
 * file that was distributed with this source code.
 */

namespace Symfony\Component\Console\Tester;

use Symfony\Component\Console\Command\Command;
use Symfony\Component\Console\Input\ArrayInput;

/**
 * Eases the testing of console commands.
 *
 * @author Fabien Potencier <fabien@symfony.com>
 * @author Robin Chalas <robin.chalas@gmail.com>
 */
class CommandTester
{
    use TesterTrait;

    private $command;

    public function __construct(Command $command)
    {
        $this->command = $command;
    }

    /**
     * Executes the command.
     *
     * Available execution options:
     *
     *  * interactive:               Sets the input interactive flag
     *  * decorated:                 Sets the output decorated flag
     *  * verbosity:                 Sets the output verbosity flag
     *  * capture_stderr_separately: Make output of stdOut and stdErr separately available
     *
     * @param array $input   An array of command arguments and options
     * @param array $options An array of execution options
     *
     * @return int The command exit code
     */
    public function execute(array $input, array $options = [])
    {
        // set the command name automatically if the application requires
        // this argument and no command name was passed
        if (!isset($input['command'])
            && (null !== $application = $this->command->getApplication())
            && $application->getDefinition()->hasArgument('command')
        ) {
            $input = array_merge(['command' => $this->command->getName()], $input);
        }

        $this->input = new ArrayInput($input);
        // Use an in-memory input stream even if no inputs are set so that QuestionHelper::ask() does not rely on the blocking STDIN.
        $this->input->setStream(self::createStream($this->inputs));

        if (isset($options['interactive'])) {
            $this->input->setInteractive($options['interactive']);
        }

        if (!isset($options['decorated'])) {
            $options['decorated'] = false;
        }

        $this->initOutput($options);

        return $this->statusCode = $this->command->run($this->input, $this->output);
    }
}
PKϤ$Zz1�W��console/Tester/TesterTrait.phpnu�[���<?php

/*
 * This file is part of the Symfony package.
 *
 * (c) Fabien Potencier <fabien@symfony.com>
 *
 * For the full copyright and license information, please view the LICENSE
 * file that was distributed with this source code.
 */

namespace Symfony\Component\Console\Tester;

use PHPUnit\Framework\Assert;
use Symfony\Component\Console\Input\InputInterface;
use Symfony\Component\Console\Output\ConsoleOutput;
use Symfony\Component\Console\Output\OutputInterface;
use Symfony\Component\Console\Output\StreamOutput;
use Symfony\Component\Console\Tester\Constraint\CommandIsSuccessful;

/**
 * @author Amrouche Hamza <hamza.simperfit@gmail.com>
 */
trait TesterTrait
{
    /** @var StreamOutput */
    private $output;
    private $inputs = [];
    private $captureStreamsIndependently = false;
    /** @var InputInterface */
    private $input;
    /** @var int */
    private $statusCode;

    /**
     * Gets the display returned by the last execution of the command or application.
     *
     * @throws \RuntimeException If it's called before the execute method
     *
     * @return string
     */
    public function getDisplay(bool $normalize = false)
    {
        if (null === $this->output) {
            throw new \RuntimeException('Output not initialized, did you execute the command before requesting the display?');
        }

        rewind($this->output->getStream());

        $display = stream_get_contents($this->output->getStream());

        if ($normalize) {
            $display = str_replace(\PHP_EOL, "\n", $display);
        }

        return $display;
    }

    /**
     * Gets the output written to STDERR by the application.
     *
     * @param bool $normalize Whether to normalize end of lines to \n or not
     *
     * @return string
     */
    public function getErrorOutput(bool $normalize = false)
    {
        if (!$this->captureStreamsIndependently) {
            throw new \LogicException('The error output is not available when the tester is run without "capture_stderr_separately" option set.');
        }

        rewind($this->output->getErrorOutput()->getStream());

        $display = stream_get_contents($this->output->getErrorOutput()->getStream());

        if ($normalize) {
            $display = str_replace(\PHP_EOL, "\n", $display);
        }

        return $display;
    }

    /**
     * Gets the input instance used by the last execution of the command or application.
     *
     * @return InputInterface
     */
    public function getInput()
    {
        return $this->input;
    }

    /**
     * Gets the output instance used by the last execution of the command or application.
     *
     * @return OutputInterface
     */
    public function getOutput()
    {
        return $this->output;
    }

    /**
     * Gets the status code returned by the last execution of the command or application.
     *
     * @throws \RuntimeException If it's called before the execute method
     *
     * @return int
     */
    public function getStatusCode()
    {
        if (null === $this->statusCode) {
            throw new \RuntimeException('Status code not initialized, did you execute the command before requesting the status code?');
        }

        return $this->statusCode;
    }

    public function assertCommandIsSuccessful(string $message = ''): void
    {
        Assert::assertThat($this->statusCode, new CommandIsSuccessful(), $message);
    }

    /**
     * Sets the user inputs.
     *
     * @param array $inputs An array of strings representing each input
     *                      passed to the command input stream
     *
     * @return $this
     */
    public function setInputs(array $inputs)
    {
        $this->inputs = $inputs;

        return $this;
    }

    /**
     * Initializes the output property.
     *
     * Available options:
     *
     *  * decorated:                 Sets the output decorated flag
     *  * verbosity:                 Sets the output verbosity flag
     *  * capture_stderr_separately: Make output of stdOut and stdErr separately available
     */
    private function initOutput(array $options)
    {
        $this->captureStreamsIndependently = \array_key_exists('capture_stderr_separately', $options) && $options['capture_stderr_separately'];
        if (!$this->captureStreamsIndependently) {
            $this->output = new StreamOutput(fopen('php://memory', 'w', false));
            if (isset($options['decorated'])) {
                $this->output->setDecorated($options['decorated']);
            }
            if (isset($options['verbosity'])) {
                $this->output->setVerbosity($options['verbosity']);
            }
        } else {
            $this->output = new ConsoleOutput(
                $options['verbosity'] ?? ConsoleOutput::VERBOSITY_NORMAL,
                $options['decorated'] ?? null
            );

            $errorOutput = new StreamOutput(fopen('php://memory', 'w', false));
            $errorOutput->setFormatter($this->output->getFormatter());
            $errorOutput->setVerbosity($this->output->getVerbosity());
            $errorOutput->setDecorated($this->output->isDecorated());

            $reflectedOutput = new \ReflectionObject($this->output);
            $strErrProperty = $reflectedOutput->getProperty('stderr');
            $strErrProperty->setAccessible(true);
            $strErrProperty->setValue($this->output, $errorOutput);

            $reflectedParent = $reflectedOutput->getParentClass();
            $streamProperty = $reflectedParent->getProperty('stream');
            $streamProperty->setAccessible(true);
            $streamProperty->setValue($this->output, fopen('php://memory', 'w', false));
        }
    }

    /**
     * @return resource
     */
    private static function createStream(array $inputs)
    {
        $stream = fopen('php://memory', 'r+', false);

        foreach ($inputs as $input) {
            fwrite($stream, $input.\PHP_EOL);
        }

        rewind($stream);

        return $stream;
    }
}
PKϤ$Zѧز��1console/Tester/Constraint/CommandIsSuccessful.phpnu�[���<?php

/*
 * This file is part of the Symfony package.
 *
 * (c) Fabien Potencier <fabien@symfony.com>
 *
 * For the full copyright and license information, please view the LICENSE
 * file that was distributed with this source code.
 */

namespace Symfony\Component\Console\Tester\Constraint;

use PHPUnit\Framework\Constraint\Constraint;
use Symfony\Component\Console\Command\Command;

final class CommandIsSuccessful extends Constraint
{
    /**
     * {@inheritdoc}
     */
    public function toString(): string
    {
        return 'is successful';
    }

    /**
     * {@inheritdoc}
     */
    protected function matches($other): bool
    {
        return Command::SUCCESS === $other;
    }

    /**
     * {@inheritdoc}
     */
    protected function failureDescription($other): string
    {
        return 'the command '.$this->toString();
    }

    /**
     * {@inheritdoc}
     */
    protected function additionalFailureDescription($other): string
    {
        $mapping = [
            Command::FAILURE => 'Command failed.',
            Command::INVALID => 'Command was invalid.',
        ];

        return $mapping[$other] ?? sprintf('Command returned exit status %d.', $other);
    }
}
PKϤ$Z�!t\
\
$console/Tester/ApplicationTester.phpnu�[���<?php

/*
 * This file is part of the Symfony package.
 *
 * (c) Fabien Potencier <fabien@symfony.com>
 *
 * For the full copyright and license information, please view the LICENSE
 * file that was distributed with this source code.
 */

namespace Symfony\Component\Console\Tester;

use Symfony\Component\Console\Application;
use Symfony\Component\Console\Input\ArrayInput;

/**
 * Eases the testing of console applications.
 *
 * When testing an application, don't forget to disable the auto exit flag:
 *
 *     $application = new Application();
 *     $application->setAutoExit(false);
 *
 * @author Fabien Potencier <fabien@symfony.com>
 */
class ApplicationTester
{
    use TesterTrait;

    private $application;

    public function __construct(Application $application)
    {
        $this->application = $application;
    }

    /**
     * Executes the application.
     *
     * Available options:
     *
     *  * interactive:               Sets the input interactive flag
     *  * decorated:                 Sets the output decorated flag
     *  * verbosity:                 Sets the output verbosity flag
     *  * capture_stderr_separately: Make output of stdOut and stdErr separately available
     *
     * @return int The command exit code
     */
    public function run(array $input, array $options = [])
    {
        $prevShellVerbosity = getenv('SHELL_VERBOSITY');

        try {
            $this->input = new ArrayInput($input);
            if (isset($options['interactive'])) {
                $this->input->setInteractive($options['interactive']);
            }

            if ($this->inputs) {
                $this->input->setStream(self::createStream($this->inputs));
            }

            $this->initOutput($options);

            return $this->statusCode = $this->application->run($this->input, $this->output);
        } finally {
            // SHELL_VERBOSITY is set by Application::configureIO so we need to unset/reset it
            // to its previous value to avoid one test's verbosity to spread to the following tests
            if (false === $prevShellVerbosity) {
                if (\function_exists('putenv')) {
                    @putenv('SHELL_VERBOSITY');
                }
                unset($_ENV['SHELL_VERBOSITY']);
                unset($_SERVER['SHELL_VERBOSITY']);
            } else {
                if (\function_exists('putenv')) {
                    @putenv('SHELL_VERBOSITY='.$prevShellVerbosity);
                }
                $_ENV['SHELL_VERBOSITY'] = $prevShellVerbosity;
                $_SERVER['SHELL_VERBOSITY'] = $prevShellVerbosity;
            }
        }
    }
}
PKϤ$Z�p����console/Application.phpnu�[���<?php

/*
 * This file is part of the Symfony package.
 *
 * (c) Fabien Potencier <fabien@symfony.com>
 *
 * For the full copyright and license information, please view the LICENSE
 * file that was distributed with this source code.
 */

namespace Symfony\Component\Console;

use Symfony\Component\Console\Command\Command;
use Symfony\Component\Console\Command\CompleteCommand;
use Symfony\Component\Console\Command\DumpCompletionCommand;
use Symfony\Component\Console\Command\HelpCommand;
use Symfony\Component\Console\Command\LazyCommand;
use Symfony\Component\Console\Command\ListCommand;
use Symfony\Component\Console\Command\SignalableCommandInterface;
use Symfony\Component\Console\CommandLoader\CommandLoaderInterface;
use Symfony\Component\Console\Completion\CompletionInput;
use Symfony\Component\Console\Completion\CompletionSuggestions;
use Symfony\Component\Console\Event\ConsoleCommandEvent;
use Symfony\Component\Console\Event\ConsoleErrorEvent;
use Symfony\Component\Console\Event\ConsoleSignalEvent;
use Symfony\Component\Console\Event\ConsoleTerminateEvent;
use Symfony\Component\Console\Exception\CommandNotFoundException;
use Symfony\Component\Console\Exception\ExceptionInterface;
use Symfony\Component\Console\Exception\LogicException;
use Symfony\Component\Console\Exception\NamespaceNotFoundException;
use Symfony\Component\Console\Exception\RuntimeException;
use Symfony\Component\Console\Formatter\OutputFormatter;
use Symfony\Component\Console\Helper\DebugFormatterHelper;
use Symfony\Component\Console\Helper\FormatterHelper;
use Symfony\Component\Console\Helper\Helper;
use Symfony\Component\Console\Helper\HelperSet;
use Symfony\Component\Console\Helper\ProcessHelper;
use Symfony\Component\Console\Helper\QuestionHelper;
use Symfony\Component\Console\Input\ArgvInput;
use Symfony\Component\Console\Input\ArrayInput;
use Symfony\Component\Console\Input\InputArgument;
use Symfony\Component\Console\Input\InputAwareInterface;
use Symfony\Component\Console\Input\InputDefinition;
use Symfony\Component\Console\Input\InputInterface;
use Symfony\Component\Console\Input\InputOption;
use Symfony\Component\Console\Output\ConsoleOutput;
use Symfony\Component\Console\Output\ConsoleOutputInterface;
use Symfony\Component\Console\Output\OutputInterface;
use Symfony\Component\Console\SignalRegistry\SignalRegistry;
use Symfony\Component\Console\Style\SymfonyStyle;
use Symfony\Component\ErrorHandler\ErrorHandler;
use Symfony\Contracts\EventDispatcher\EventDispatcherInterface;
use Symfony\Contracts\Service\ResetInterface;

/**
 * An Application is the container for a collection of commands.
 *
 * It is the main entry point of a Console application.
 *
 * This class is optimized for a standard CLI environment.
 *
 * Usage:
 *
 *     $app = new Application('myapp', '1.0 (stable)');
 *     $app->add(new SimpleCommand());
 *     $app->run();
 *
 * @author Fabien Potencier <fabien@symfony.com>
 */
class Application implements ResetInterface
{
    private $commands = [];
    private $wantHelps = false;
    private $runningCommand;
    private $name;
    private $version;
    private $commandLoader;
    private $catchExceptions = true;
    private $autoExit = true;
    private $definition;
    private $helperSet;
    private $dispatcher;
    private $terminal;
    private $defaultCommand;
    private $singleCommand = false;
    private $initialized;
    private $signalRegistry;
    private $signalsToDispatchEvent = [];

    public function __construct(string $name = 'UNKNOWN', string $version = 'UNKNOWN')
    {
        $this->name = $name;
        $this->version = $version;
        $this->terminal = new Terminal();
        $this->defaultCommand = 'list';
        if (\defined('SIGINT') && SignalRegistry::isSupported()) {
            $this->signalRegistry = new SignalRegistry();
            $this->signalsToDispatchEvent = [\SIGINT, \SIGTERM, \SIGUSR1, \SIGUSR2];
        }
    }

    /**
     * @final
     */
    public function setDispatcher(EventDispatcherInterface $dispatcher)
    {
        $this->dispatcher = $dispatcher;
    }

    public function setCommandLoader(CommandLoaderInterface $commandLoader)
    {
        $this->commandLoader = $commandLoader;
    }

    public function getSignalRegistry(): SignalRegistry
    {
        if (!$this->signalRegistry) {
            throw new RuntimeException('Signals are not supported. Make sure that the `pcntl` extension is installed and that "pcntl_*" functions are not disabled by your php.ini\'s "disable_functions" directive.');
        }

        return $this->signalRegistry;
    }

    public function setSignalsToDispatchEvent(int ...$signalsToDispatchEvent)
    {
        $this->signalsToDispatchEvent = $signalsToDispatchEvent;
    }

    /**
     * Runs the current application.
     *
     * @return int 0 if everything went fine, or an error code
     *
     * @throws \Exception When running fails. Bypass this when {@link setCatchExceptions()}.
     */
    public function run(InputInterface $input = null, OutputInterface $output = null)
    {
        if (\function_exists('putenv')) {
            @putenv('LINES='.$this->terminal->getHeight());
            @putenv('COLUMNS='.$this->terminal->getWidth());
        }

        if (null === $input) {
            $input = new ArgvInput();
        }

        if (null === $output) {
            $output = new ConsoleOutput();
        }

        $renderException = function (\Throwable $e) use ($output) {
            if ($output instanceof ConsoleOutputInterface) {
                $this->renderThrowable($e, $output->getErrorOutput());
            } else {
                $this->renderThrowable($e, $output);
            }
        };
        if ($phpHandler = set_exception_handler($renderException)) {
            restore_exception_handler();
            if (!\is_array($phpHandler) || !$phpHandler[0] instanceof ErrorHandler) {
                $errorHandler = true;
            } elseif ($errorHandler = $phpHandler[0]->setExceptionHandler($renderException)) {
                $phpHandler[0]->setExceptionHandler($errorHandler);
            }
        }

        $this->configureIO($input, $output);

        try {
            $exitCode = $this->doRun($input, $output);
        } catch (\Exception $e) {
            if (!$this->catchExceptions) {
                throw $e;
            }

            $renderException($e);

            $exitCode = $e->getCode();
            if (is_numeric($exitCode)) {
                $exitCode = (int) $exitCode;
                if ($exitCode <= 0) {
                    $exitCode = 1;
                }
            } else {
                $exitCode = 1;
            }
        } finally {
            // if the exception handler changed, keep it
            // otherwise, unregister $renderException
            if (!$phpHandler) {
                if (set_exception_handler($renderException) === $renderException) {
                    restore_exception_handler();
                }
                restore_exception_handler();
            } elseif (!$errorHandler) {
                $finalHandler = $phpHandler[0]->setExceptionHandler(null);
                if ($finalHandler !== $renderException) {
                    $phpHandler[0]->setExceptionHandler($finalHandler);
                }
            }
        }

        if ($this->autoExit) {
            if ($exitCode > 255) {
                $exitCode = 255;
            }

            exit($exitCode);
        }

        return $exitCode;
    }

    /**
     * Runs the current application.
     *
     * @return int 0 if everything went fine, or an error code
     */
    public function doRun(InputInterface $input, OutputInterface $output)
    {
        if (true === $input->hasParameterOption(['--version', '-V'], true)) {
            $output->writeln($this->getLongVersion());

            return 0;
        }

        try {
            // Makes ArgvInput::getFirstArgument() able to distinguish an option from an argument.
            $input->bind($this->getDefinition());
        } catch (ExceptionInterface $e) {
            // Errors must be ignored, full binding/validation happens later when the command is known.
        }

        $name = $this->getCommandName($input);
        if (true === $input->hasParameterOption(['--help', '-h'], true)) {
            if (!$name) {
                $name = 'help';
                $input = new ArrayInput(['command_name' => $this->defaultCommand]);
            } else {
                $this->wantHelps = true;
            }
        }

        if (!$name) {
            $name = $this->defaultCommand;
            $definition = $this->getDefinition();
            $definition->setArguments(array_merge(
                $definition->getArguments(),
                [
                    'command' => new InputArgument('command', InputArgument::OPTIONAL, $definition->getArgument('command')->getDescription(), $name),
                ]
            ));
        }

        try {
            $this->runningCommand = null;
            // the command name MUST be the first element of the input
            $command = $this->find($name);
        } catch (\Throwable $e) {
            if (!($e instanceof CommandNotFoundException && !$e instanceof NamespaceNotFoundException) || 1 !== \count($alternatives = $e->getAlternatives()) || !$input->isInteractive()) {
                if (null !== $this->dispatcher) {
                    $event = new ConsoleErrorEvent($input, $output, $e);
                    $this->dispatcher->dispatch($event, ConsoleEvents::ERROR);

                    if (0 === $event->getExitCode()) {
                        return 0;
                    }

                    $e = $event->getError();
                }

                throw $e;
            }

            $alternative = $alternatives[0];

            $style = new SymfonyStyle($input, $output);
            $style->block(sprintf("\nCommand \"%s\" is not defined.\n", $name), null, 'error');
            if (!$style->confirm(sprintf('Do you want to run "%s" instead? ', $alternative), false)) {
                if (null !== $this->dispatcher) {
                    $event = new ConsoleErrorEvent($input, $output, $e);
                    $this->dispatcher->dispatch($event, ConsoleEvents::ERROR);

                    return $event->getExitCode();
                }

                return 1;
            }

            $command = $this->find($alternative);
        }

        if ($command instanceof LazyCommand) {
            $command = $command->getCommand();
        }

        $this->runningCommand = $command;
        $exitCode = $this->doRunCommand($command, $input, $output);
        $this->runningCommand = null;

        return $exitCode;
    }

    /**
     * {@inheritdoc}
     */
    public function reset()
    {
    }

    public function setHelperSet(HelperSet $helperSet)
    {
        $this->helperSet = $helperSet;
    }

    /**
     * Get the helper set associated with the command.
     *
     * @return HelperSet
     */
    public function getHelperSet()
    {
        if (!$this->helperSet) {
            $this->helperSet = $this->getDefaultHelperSet();
        }

        return $this->helperSet;
    }

    public function setDefinition(InputDefinition $definition)
    {
        $this->definition = $definition;
    }

    /**
     * Gets the InputDefinition related to this Application.
     *
     * @return InputDefinition
     */
    public function getDefinition()
    {
        if (!$this->definition) {
            $this->definition = $this->getDefaultInputDefinition();
        }

        if ($this->singleCommand) {
            $inputDefinition = $this->definition;
            $inputDefinition->setArguments();

            return $inputDefinition;
        }

        return $this->definition;
    }

    /**
     * Adds suggestions to $suggestions for the current completion input (e.g. option or argument).
     */
    public function complete(CompletionInput $input, CompletionSuggestions $suggestions): void
    {
        if (
            CompletionInput::TYPE_ARGUMENT_VALUE === $input->getCompletionType()
            && 'command' === $input->getCompletionName()
        ) {
            $commandNames = [];
            foreach ($this->all() as $name => $command) {
                // skip hidden commands and aliased commands as they already get added below
                if ($command->isHidden() || $command->getName() !== $name) {
                    continue;
                }
                $commandNames[] = $command->getName();
                foreach ($command->getAliases() as $name) {
                    $commandNames[] = $name;
                }
            }
            $suggestions->suggestValues(array_filter($commandNames));

            return;
        }

        if (CompletionInput::TYPE_OPTION_NAME === $input->getCompletionType()) {
            $suggestions->suggestOptions($this->getDefinition()->getOptions());

            return;
        }
    }

    /**
     * Gets the help message.
     *
     * @return string
     */
    public function getHelp()
    {
        return $this->getLongVersion();
    }

    /**
     * Gets whether to catch exceptions or not during commands execution.
     *
     * @return bool
     */
    public function areExceptionsCaught()
    {
        return $this->catchExceptions;
    }

    /**
     * Sets whether to catch exceptions or not during commands execution.
     */
    public function setCatchExceptions(bool $boolean)
    {
        $this->catchExceptions = $boolean;
    }

    /**
     * Gets whether to automatically exit after a command execution or not.
     *
     * @return bool
     */
    public function isAutoExitEnabled()
    {
        return $this->autoExit;
    }

    /**
     * Sets whether to automatically exit after a command execution or not.
     */
    public function setAutoExit(bool $boolean)
    {
        $this->autoExit = $boolean;
    }

    /**
     * Gets the name of the application.
     *
     * @return string
     */
    public function getName()
    {
        return $this->name;
    }

    /**
     * Sets the application name.
     **/
    public function setName(string $name)
    {
        $this->name = $name;
    }

    /**
     * Gets the application version.
     *
     * @return string
     */
    public function getVersion()
    {
        return $this->version;
    }

    /**
     * Sets the application version.
     */
    public function setVersion(string $version)
    {
        $this->version = $version;
    }

    /**
     * Returns the long version of the application.
     *
     * @return string
     */
    public function getLongVersion()
    {
        if ('UNKNOWN' !== $this->getName()) {
            if ('UNKNOWN' !== $this->getVersion()) {
                return sprintf('%s <info>%s</info>', $this->getName(), $this->getVersion());
            }

            return $this->getName();
        }

        return 'Console Tool';
    }

    /**
     * Registers a new command.
     *
     * @return Command
     */
    public function register(string $name)
    {
        return $this->add(new Command($name));
    }

    /**
     * Adds an array of command objects.
     *
     * If a Command is not enabled it will not be added.
     *
     * @param Command[] $commands An array of commands
     */
    public function addCommands(array $commands)
    {
        foreach ($commands as $command) {
            $this->add($command);
        }
    }

    /**
     * Adds a command object.
     *
     * If a command with the same name already exists, it will be overridden.
     * If the command is not enabled it will not be added.
     *
     * @return Command|null
     */
    public function add(Command $command)
    {
        $this->init();

        $command->setApplication($this);

        if (!$command->isEnabled()) {
            $command->setApplication(null);

            return null;
        }

        if (!$command instanceof LazyCommand) {
            // Will throw if the command is not correctly initialized.
            $command->getDefinition();
        }

        if (!$command->getName()) {
            throw new LogicException(sprintf('The command defined in "%s" cannot have an empty name.', get_debug_type($command)));
        }

        $this->commands[$command->getName()] = $command;

        foreach ($command->getAliases() as $alias) {
            $this->commands[$alias] = $command;
        }

        return $command;
    }

    /**
     * Returns a registered command by name or alias.
     *
     * @return Command
     *
     * @throws CommandNotFoundException When given command name does not exist
     */
    public function get(string $name)
    {
        $this->init();

        if (!$this->has($name)) {
            throw new CommandNotFoundException(sprintf('The command "%s" does not exist.', $name));
        }

        // When the command has a different name than the one used at the command loader level
        if (!isset($this->commands[$name])) {
            throw new CommandNotFoundException(sprintf('The "%s" command cannot be found because it is registered under multiple names. Make sure you don\'t set a different name via constructor or "setName()".', $name));
        }

        $command = $this->commands[$name];

        if ($this->wantHelps) {
            $this->wantHelps = false;

            $helpCommand = $this->get('help');
            $helpCommand->setCommand($command);

            return $helpCommand;
        }

        return $command;
    }

    /**
     * Returns true if the command exists, false otherwise.
     *
     * @return bool
     */
    public function has(string $name)
    {
        $this->init();

        return isset($this->commands[$name]) || ($this->commandLoader && $this->commandLoader->has($name) && $this->add($this->commandLoader->get($name)));
    }

    /**
     * Returns an array of all unique namespaces used by currently registered commands.
     *
     * It does not return the global namespace which always exists.
     *
     * @return string[]
     */
    public function getNamespaces()
    {
        $namespaces = [];
        foreach ($this->all() as $command) {
            if ($command->isHidden()) {
                continue;
            }

            $namespaces[] = $this->extractAllNamespaces($command->getName());

            foreach ($command->getAliases() as $alias) {
                $namespaces[] = $this->extractAllNamespaces($alias);
            }
        }

        return array_values(array_unique(array_filter(array_merge([], ...$namespaces))));
    }

    /**
     * Finds a registered namespace by a name or an abbreviation.
     *
     * @return string
     *
     * @throws NamespaceNotFoundException When namespace is incorrect or ambiguous
     */
    public function findNamespace(string $namespace)
    {
        $allNamespaces = $this->getNamespaces();
        $expr = implode('[^:]*:', array_map('preg_quote', explode(':', $namespace))).'[^:]*';
        $namespaces = preg_grep('{^'.$expr.'}', $allNamespaces);

        if (empty($namespaces)) {
            $message = sprintf('There are no commands defined in the "%s" namespace.', $namespace);

            if ($alternatives = $this->findAlternatives($namespace, $allNamespaces)) {
                if (1 == \count($alternatives)) {
                    $message .= "\n\nDid you mean this?\n    ";
                } else {
                    $message .= "\n\nDid you mean one of these?\n    ";
                }

                $message .= implode("\n    ", $alternatives);
            }

            throw new NamespaceNotFoundException($message, $alternatives);
        }

        $exact = \in_array($namespace, $namespaces, true);
        if (\count($namespaces) > 1 && !$exact) {
            throw new NamespaceNotFoundException(sprintf("The namespace \"%s\" is ambiguous.\nDid you mean one of these?\n%s.", $namespace, $this->getAbbreviationSuggestions(array_values($namespaces))), array_values($namespaces));
        }

        return $exact ? $namespace : reset($namespaces);
    }

    /**
     * Finds a command by name or alias.
     *
     * Contrary to get, this command tries to find the best
     * match if you give it an abbreviation of a name or alias.
     *
     * @return Command
     *
     * @throws CommandNotFoundException When command name is incorrect or ambiguous
     */
    public function find(string $name)
    {
        $this->init();

        $aliases = [];

        foreach ($this->commands as $command) {
            foreach ($command->getAliases() as $alias) {
                if (!$this->has($alias)) {
                    $this->commands[$alias] = $command;
                }
            }
        }

        if ($this->has($name)) {
            return $this->get($name);
        }

        $allCommands = $this->commandLoader ? array_merge($this->commandLoader->getNames(), array_keys($this->commands)) : array_keys($this->commands);
        $expr = implode('[^:]*:', array_map('preg_quote', explode(':', $name))).'[^:]*';
        $commands = preg_grep('{^'.$expr.'}', $allCommands);

        if (empty($commands)) {
            $commands = preg_grep('{^'.$expr.'}i', $allCommands);
        }

        // if no commands matched or we just matched namespaces
        if (empty($commands) || \count(preg_grep('{^'.$expr.'$}i', $commands)) < 1) {
            if (false !== $pos = strrpos($name, ':')) {
                // check if a namespace exists and contains commands
                $this->findNamespace(substr($name, 0, $pos));
            }

            $message = sprintf('Command "%s" is not defined.', $name);

            if ($alternatives = $this->findAlternatives($name, $allCommands)) {
                // remove hidden commands
                $alternatives = array_filter($alternatives, function ($name) {
                    return !$this->get($name)->isHidden();
                });

                if (1 == \count($alternatives)) {
                    $message .= "\n\nDid you mean this?\n    ";
                } else {
                    $message .= "\n\nDid you mean one of these?\n    ";
                }
                $message .= implode("\n    ", $alternatives);
            }

            throw new CommandNotFoundException($message, array_values($alternatives));
        }

        // filter out aliases for commands which are already on the list
        if (\count($commands) > 1) {
            $commandList = $this->commandLoader ? array_merge(array_flip($this->commandLoader->getNames()), $this->commands) : $this->commands;
            $commands = array_unique(array_filter($commands, function ($nameOrAlias) use (&$commandList, $commands, &$aliases) {
                if (!$commandList[$nameOrAlias] instanceof Command) {
                    $commandList[$nameOrAlias] = $this->commandLoader->get($nameOrAlias);
                }

                $commandName = $commandList[$nameOrAlias]->getName();

                $aliases[$nameOrAlias] = $commandName;

                return $commandName === $nameOrAlias || !\in_array($commandName, $commands);
            }));
        }

        if (\count($commands) > 1) {
            $usableWidth = $this->terminal->getWidth() - 10;
            $abbrevs = array_values($commands);
            $maxLen = 0;
            foreach ($abbrevs as $abbrev) {
                $maxLen = max(Helper::width($abbrev), $maxLen);
            }
            $abbrevs = array_map(function ($cmd) use ($commandList, $usableWidth, $maxLen, &$commands) {
                if ($commandList[$cmd]->isHidden()) {
                    unset($commands[array_search($cmd, $commands)]);

                    return false;
                }

                $abbrev = str_pad($cmd, $maxLen, ' ').' '.$commandList[$cmd]->getDescription();

                return Helper::width($abbrev) > $usableWidth ? Helper::substr($abbrev, 0, $usableWidth - 3).'...' : $abbrev;
            }, array_values($commands));

            if (\count($commands) > 1) {
                $suggestions = $this->getAbbreviationSuggestions(array_filter($abbrevs));

                throw new CommandNotFoundException(sprintf("Command \"%s\" is ambiguous.\nDid you mean one of these?\n%s.", $name, $suggestions), array_values($commands));
            }
        }

        $command = $this->get(reset($commands));

        if ($command->isHidden()) {
            throw new CommandNotFoundException(sprintf('The command "%s" does not exist.', $name));
        }

        return $command;
    }

    /**
     * Gets the commands (registered in the given namespace if provided).
     *
     * The array keys are the full names and the values the command instances.
     *
     * @return Command[]
     */
    public function all(string $namespace = null)
    {
        $this->init();

        if (null === $namespace) {
            if (!$this->commandLoader) {
                return $this->commands;
            }

            $commands = $this->commands;
            foreach ($this->commandLoader->getNames() as $name) {
                if (!isset($commands[$name]) && $this->has($name)) {
                    $commands[$name] = $this->get($name);
                }
            }

            return $commands;
        }

        $commands = [];
        foreach ($this->commands as $name => $command) {
            if ($namespace === $this->extractNamespace($name, substr_count($namespace, ':') + 1)) {
                $commands[$name] = $command;
            }
        }

        if ($this->commandLoader) {
            foreach ($this->commandLoader->getNames() as $name) {
                if (!isset($commands[$name]) && $namespace === $this->extractNamespace($name, substr_count($namespace, ':') + 1) && $this->has($name)) {
                    $commands[$name] = $this->get($name);
                }
            }
        }

        return $commands;
    }

    /**
     * Returns an array of possible abbreviations given a set of names.
     *
     * @return string[][]
     */
    public static function getAbbreviations(array $names)
    {
        $abbrevs = [];
        foreach ($names as $name) {
            for ($len = \strlen($name); $len > 0; --$len) {
                $abbrev = substr($name, 0, $len);
                $abbrevs[$abbrev][] = $name;
            }
        }

        return $abbrevs;
    }

    public function renderThrowable(\Throwable $e, OutputInterface $output): void
    {
        $output->writeln('', OutputInterface::VERBOSITY_QUIET);

        $this->doRenderThrowable($e, $output);

        if (null !== $this->runningCommand) {
            $output->writeln(sprintf('<info>%s</info>', OutputFormatter::escape(sprintf($this->runningCommand->getSynopsis(), $this->getName()))), OutputInterface::VERBOSITY_QUIET);
            $output->writeln('', OutputInterface::VERBOSITY_QUIET);
        }
    }

    protected function doRenderThrowable(\Throwable $e, OutputInterface $output): void
    {
        do {
            $message = trim($e->getMessage());
            if ('' === $message || OutputInterface::VERBOSITY_VERBOSE <= $output->getVerbosity()) {
                $class = get_debug_type($e);
                $title = sprintf('  [%s%s]  ', $class, 0 !== ($code = $e->getCode()) ? ' ('.$code.')' : '');
                $len = Helper::width($title);
            } else {
                $len = 0;
            }

            if (str_contains($message, "@anonymous\0")) {
                $message = preg_replace_callback('/[a-zA-Z_\x7f-\xff][\\\\a-zA-Z0-9_\x7f-\xff]*+@anonymous\x00.*?\.php(?:0x?|:[0-9]++\$)[0-9a-fA-F]++/', function ($m) {
                    return class_exists($m[0], false) ? (get_parent_class($m[0]) ?: key(class_implements($m[0])) ?: 'class').'@anonymous' : $m[0];
                }, $message);
            }

            $width = $this->terminal->getWidth() ? $this->terminal->getWidth() - 1 : \PHP_INT_MAX;
            $lines = [];
            foreach ('' !== $message ? preg_split('/\r?\n/', $message) : [] as $line) {
                foreach ($this->splitStringByWidth($line, $width - 4) as $line) {
                    // pre-format lines to get the right string length
                    $lineLength = Helper::width($line) + 4;
                    $lines[] = [$line, $lineLength];

                    $len = max($lineLength, $len);
                }
            }

            $messages = [];
            if (!$e instanceof ExceptionInterface || OutputInterface::VERBOSITY_VERBOSE <= $output->getVerbosity()) {
                $messages[] = sprintf('<comment>%s</comment>', OutputFormatter::escape(sprintf('In %s line %s:', basename($e->getFile()) ?: 'n/a', $e->getLine() ?: 'n/a')));
            }
            $messages[] = $emptyLine = sprintf('<error>%s</error>', str_repeat(' ', $len));
            if ('' === $message || OutputInterface::VERBOSITY_VERBOSE <= $output->getVerbosity()) {
                $messages[] = sprintf('<error>%s%s</error>', $title, str_repeat(' ', max(0, $len - Helper::width($title))));
            }
            foreach ($lines as $line) {
                $messages[] = sprintf('<error>  %s  %s</error>', OutputFormatter::escape($line[0]), str_repeat(' ', $len - $line[1]));
            }
            $messages[] = $emptyLine;
            $messages[] = '';

            $output->writeln($messages, OutputInterface::VERBOSITY_QUIET);

            if (OutputInterface::VERBOSITY_VERBOSE <= $output->getVerbosity()) {
                $output->writeln('<comment>Exception trace:</comment>', OutputInterface::VERBOSITY_QUIET);

                // exception related properties
                $trace = $e->getTrace();

                array_unshift($trace, [
                    'function' => '',
                    'file' => $e->getFile() ?: 'n/a',
                    'line' => $e->getLine() ?: 'n/a',
                    'args' => [],
                ]);

                for ($i = 0, $count = \count($trace); $i < $count; ++$i) {
                    $class = $trace[$i]['class'] ?? '';
                    $type = $trace[$i]['type'] ?? '';
                    $function = $trace[$i]['function'] ?? '';
                    $file = $trace[$i]['file'] ?? 'n/a';
                    $line = $trace[$i]['line'] ?? 'n/a';

                    $output->writeln(sprintf(' %s%s at <info>%s:%s</info>', $class, $function ? $type.$function.'()' : '', $file, $line), OutputInterface::VERBOSITY_QUIET);
                }

                $output->writeln('', OutputInterface::VERBOSITY_QUIET);
            }
        } while ($e = $e->getPrevious());
    }

    /**
     * Configures the input and output instances based on the user arguments and options.
     */
    protected function configureIO(InputInterface $input, OutputInterface $output)
    {
        if (true === $input->hasParameterOption(['--ansi'], true)) {
            $output->setDecorated(true);
        } elseif (true === $input->hasParameterOption(['--no-ansi'], true)) {
            $output->setDecorated(false);
        }

        if (true === $input->hasParameterOption(['--no-interaction', '-n'], true)) {
            $input->setInteractive(false);
        }

        switch ($shellVerbosity = (int) getenv('SHELL_VERBOSITY')) {
            case -1: $output->setVerbosity(OutputInterface::VERBOSITY_QUIET); break;
            case 1: $output->setVerbosity(OutputInterface::VERBOSITY_VERBOSE); break;
            case 2: $output->setVerbosity(OutputInterface::VERBOSITY_VERY_VERBOSE); break;
            case 3: $output->setVerbosity(OutputInterface::VERBOSITY_DEBUG); break;
            default: $shellVerbosity = 0; break;
        }

        if (true === $input->hasParameterOption(['--quiet', '-q'], true)) {
            $output->setVerbosity(OutputInterface::VERBOSITY_QUIET);
            $shellVerbosity = -1;
        } else {
            if ($input->hasParameterOption('-vvv', true) || $input->hasParameterOption('--verbose=3', true) || 3 === $input->getParameterOption('--verbose', false, true)) {
                $output->setVerbosity(OutputInterface::VERBOSITY_DEBUG);
                $shellVerbosity = 3;
            } elseif ($input->hasParameterOption('-vv', true) || $input->hasParameterOption('--verbose=2', true) || 2 === $input->getParameterOption('--verbose', false, true)) {
                $output->setVerbosity(OutputInterface::VERBOSITY_VERY_VERBOSE);
                $shellVerbosity = 2;
            } elseif ($input->hasParameterOption('-v', true) || $input->hasParameterOption('--verbose=1', true) || $input->hasParameterOption('--verbose', true) || $input->getParameterOption('--verbose', false, true)) {
                $output->setVerbosity(OutputInterface::VERBOSITY_VERBOSE);
                $shellVerbosity = 1;
            }
        }

        if (-1 === $shellVerbosity) {
            $input->setInteractive(false);
        }

        if (\function_exists('putenv')) {
            @putenv('SHELL_VERBOSITY='.$shellVerbosity);
        }
        $_ENV['SHELL_VERBOSITY'] = $shellVerbosity;
        $_SERVER['SHELL_VERBOSITY'] = $shellVerbosity;
    }

    /**
     * Runs the current command.
     *
     * If an event dispatcher has been attached to the application,
     * events are also dispatched during the life-cycle of the command.
     *
     * @return int 0 if everything went fine, or an error code
     */
    protected function doRunCommand(Command $command, InputInterface $input, OutputInterface $output)
    {
        foreach ($command->getHelperSet() as $helper) {
            if ($helper instanceof InputAwareInterface) {
                $helper->setInput($input);
            }
        }

        if ($this->signalsToDispatchEvent) {
            $commandSignals = $command instanceof SignalableCommandInterface ? $command->getSubscribedSignals() : [];

            if ($commandSignals || null !== $this->dispatcher) {
                if (!$this->signalRegistry) {
                    throw new RuntimeException('Unable to subscribe to signal events. Make sure that the `pcntl` extension is installed and that "pcntl_*" functions are not disabled by your php.ini\'s "disable_functions" directive.');
                }

                if (Terminal::hasSttyAvailable()) {
                    $sttyMode = shell_exec('stty -g');

                    foreach ([\SIGINT, \SIGTERM] as $signal) {
                        $this->signalRegistry->register($signal, static function () use ($sttyMode) {
                            shell_exec('stty '.$sttyMode);
                        });
                    }
                }

                foreach ($commandSignals as $signal) {
                    $this->signalRegistry->register($signal, [$command, 'handleSignal']);
                }
            }

            if (null !== $this->dispatcher) {
                foreach ($this->signalsToDispatchEvent as $signal) {
                    $event = new ConsoleSignalEvent($command, $input, $output, $signal);

                    $this->signalRegistry->register($signal, function ($signal, $hasNext) use ($event) {
                        $this->dispatcher->dispatch($event, ConsoleEvents::SIGNAL);

                        // No more handlers, we try to simulate PHP default behavior
                        if (!$hasNext) {
                            if (!\in_array($signal, [\SIGUSR1, \SIGUSR2], true)) {
                                exit(0);
                            }
                        }
                    });
                }
            }
        }

        if (null === $this->dispatcher) {
            return $command->run($input, $output);
        }

        // bind before the console.command event, so the listeners have access to input options/arguments
        try {
            $command->mergeApplicationDefinition();
            $input->bind($command->getDefinition());
        } catch (ExceptionInterface $e) {
            // ignore invalid options/arguments for now, to allow the event listeners to customize the InputDefinition
        }

        $event = new ConsoleCommandEvent($command, $input, $output);
        $e = null;

        try {
            $this->dispatcher->dispatch($event, ConsoleEvents::COMMAND);

            if ($event->commandShouldRun()) {
                $exitCode = $command->run($input, $output);
            } else {
                $exitCode = ConsoleCommandEvent::RETURN_CODE_DISABLED;
            }
        } catch (\Throwable $e) {
            $event = new ConsoleErrorEvent($input, $output, $e, $command);
            $this->dispatcher->dispatch($event, ConsoleEvents::ERROR);
            $e = $event->getError();

            if (0 === $exitCode = $event->getExitCode()) {
                $e = null;
            }
        }

        $event = new ConsoleTerminateEvent($command, $input, $output, $exitCode);
        $this->dispatcher->dispatch($event, ConsoleEvents::TERMINATE);

        if (null !== $e) {
            throw $e;
        }

        return $event->getExitCode();
    }

    /**
     * Gets the name of the command based on input.
     *
     * @return string|null
     */
    protected function getCommandName(InputInterface $input)
    {
        return $this->singleCommand ? $this->defaultCommand : $input->getFirstArgument();
    }

    /**
     * Gets the default input definition.
     *
     * @return InputDefinition
     */
    protected function getDefaultInputDefinition()
    {
        return new InputDefinition([
            new InputArgument('command', InputArgument::REQUIRED, 'The command to execute'),
            new InputOption('--help', '-h', InputOption::VALUE_NONE, 'Display help for the given command. When no command is given display help for the <info>'.$this->defaultCommand.'</info> command'),
            new InputOption('--quiet', '-q', InputOption::VALUE_NONE, 'Do not output any message'),
            new InputOption('--verbose', '-v|vv|vvv', InputOption::VALUE_NONE, 'Increase the verbosity of messages: 1 for normal output, 2 for more verbose output and 3 for debug'),
            new InputOption('--version', '-V', InputOption::VALUE_NONE, 'Display this application version'),
            new InputOption('--ansi', '', InputOption::VALUE_NEGATABLE, 'Force (or disable --no-ansi) ANSI output', null),
            new InputOption('--no-interaction', '-n', InputOption::VALUE_NONE, 'Do not ask any interactive question'),
        ]);
    }

    /**
     * Gets the default commands that should always be available.
     *
     * @return Command[]
     */
    protected function getDefaultCommands()
    {
        return [new HelpCommand(), new ListCommand(), new CompleteCommand(), new DumpCompletionCommand()];
    }

    /**
     * Gets the default helper set with the helpers that should always be available.
     *
     * @return HelperSet
     */
    protected function getDefaultHelperSet()
    {
        return new HelperSet([
            new FormatterHelper(),
            new DebugFormatterHelper(),
            new ProcessHelper(),
            new QuestionHelper(),
        ]);
    }

    /**
     * Returns abbreviated suggestions in string format.
     */
    private function getAbbreviationSuggestions(array $abbrevs): string
    {
        return '    '.implode("\n    ", $abbrevs);
    }

    /**
     * Returns the namespace part of the command name.
     *
     * This method is not part of public API and should not be used directly.
     *
     * @return string
     */
    public function extractNamespace(string $name, int $limit = null)
    {
        $parts = explode(':', $name, -1);

        return implode(':', null === $limit ? $parts : \array_slice($parts, 0, $limit));
    }

    /**
     * Finds alternative of $name among $collection,
     * if nothing is found in $collection, try in $abbrevs.
     *
     * @return string[]
     */
    private function findAlternatives(string $name, iterable $collection): array
    {
        $threshold = 1e3;
        $alternatives = [];

        $collectionParts = [];
        foreach ($collection as $item) {
            $collectionParts[$item] = explode(':', $item);
        }

        foreach (explode(':', $name) as $i => $subname) {
            foreach ($collectionParts as $collectionName => $parts) {
                $exists = isset($alternatives[$collectionName]);
                if (!isset($parts[$i]) && $exists) {
                    $alternatives[$collectionName] += $threshold;
                    continue;
                } elseif (!isset($parts[$i])) {
                    continue;
                }

                $lev = levenshtein($subname, $parts[$i]);
                if ($lev <= \strlen($subname) / 3 || '' !== $subname && str_contains($parts[$i], $subname)) {
                    $alternatives[$collectionName] = $exists ? $alternatives[$collectionName] + $lev : $lev;
                } elseif ($exists) {
                    $alternatives[$collectionName] += $threshold;
                }
            }
        }

        foreach ($collection as $item) {
            $lev = levenshtein($name, $item);
            if ($lev <= \strlen($name) / 3 || str_contains($item, $name)) {
                $alternatives[$item] = isset($alternatives[$item]) ? $alternatives[$item] - $lev : $lev;
            }
        }

        $alternatives = array_filter($alternatives, function ($lev) use ($threshold) { return $lev < 2 * $threshold; });
        ksort($alternatives, \SORT_NATURAL | \SORT_FLAG_CASE);

        return array_keys($alternatives);
    }

    /**
     * Sets the default Command name.
     *
     * @return $this
     */
    public function setDefaultCommand(string $commandName, bool $isSingleCommand = false)
    {
        $this->defaultCommand = explode('|', ltrim($commandName, '|'))[0];

        if ($isSingleCommand) {
            // Ensure the command exist
            $this->find($commandName);

            $this->singleCommand = true;
        }

        return $this;
    }

    /**
     * @internal
     */
    public function isSingleCommand(): bool
    {
        return $this->singleCommand;
    }

    private function splitStringByWidth(string $string, int $width): array
    {
        // str_split is not suitable for multi-byte characters, we should use preg_split to get char array properly.
        // additionally, array_slice() is not enough as some character has doubled width.
        // we need a function to split string not by character count but by string width
        if (false === $encoding = mb_detect_encoding($string, null, true)) {
            return str_split($string, $width);
        }

        $utf8String = mb_convert_encoding($string, 'utf8', $encoding);
        $lines = [];
        $line = '';

        $offset = 0;
        while (preg_match('/.{1,10000}/u', $utf8String, $m, 0, $offset)) {
            $offset += \strlen($m[0]);

            foreach (preg_split('//u', $m[0]) as $char) {
                // test if $char could be appended to current line
                if (mb_strwidth($line.$char, 'utf8') <= $width) {
                    $line .= $char;
                    continue;
                }
                // if not, push current line to array and make new line
                $lines[] = str_pad($line, $width);
                $line = $char;
            }
        }

        $lines[] = \count($lines) ? str_pad($line, $width) : $line;

        mb_convert_variables($encoding, 'utf8', $lines);

        return $lines;
    }

    /**
     * Returns all namespaces of the command name.
     *
     * @return string[]
     */
    private function extractAllNamespaces(string $name): array
    {
        // -1 as third argument is needed to skip the command short name when exploding
        $parts = explode(':', $name, -1);
        $namespaces = [];

        foreach ($parts as $part) {
            if (\count($namespaces)) {
                $namespaces[] = end($namespaces).':'.$part;
            } else {
                $namespaces[] = $part;
            }
        }

        return $namespaces;
    }

    private function init()
    {
        if ($this->initialized) {
            return;
        }
        $this->initialized = true;

        foreach ($this->getDefaultCommands() as $command) {
            $this->add($command);
        }
    }
}
PKϤ$Z[
�&�&$console/Descriptor/XmlDescriptor.phpnu�[���<?php

/*
 * This file is part of the Symfony package.
 *
 * (c) Fabien Potencier <fabien@symfony.com>
 *
 * For the full copyright and license information, please view the LICENSE
 * file that was distributed with this source code.
 */

namespace Symfony\Component\Console\Descriptor;

use Symfony\Component\Console\Application;
use Symfony\Component\Console\Command\Command;
use Symfony\Component\Console\Input\InputArgument;
use Symfony\Component\Console\Input\InputDefinition;
use Symfony\Component\Console\Input\InputOption;

/**
 * XML descriptor.
 *
 * @author Jean-François Simon <contact@jfsimon.fr>
 *
 * @internal
 */
class XmlDescriptor extends Descriptor
{
    public function getInputDefinitionDocument(InputDefinition $definition): \DOMDocument
    {
        $dom = new \DOMDocument('1.0', 'UTF-8');
        $dom->appendChild($definitionXML = $dom->createElement('definition'));

        $definitionXML->appendChild($argumentsXML = $dom->createElement('arguments'));
        foreach ($definition->getArguments() as $argument) {
            $this->appendDocument($argumentsXML, $this->getInputArgumentDocument($argument));
        }

        $definitionXML->appendChild($optionsXML = $dom->createElement('options'));
        foreach ($definition->getOptions() as $option) {
            $this->appendDocument($optionsXML, $this->getInputOptionDocument($option));
        }

        return $dom;
    }

    public function getCommandDocument(Command $command, bool $short = false): \DOMDocument
    {
        $dom = new \DOMDocument('1.0', 'UTF-8');
        $dom->appendChild($commandXML = $dom->createElement('command'));

        $commandXML->setAttribute('id', $command->getName());
        $commandXML->setAttribute('name', $command->getName());
        $commandXML->setAttribute('hidden', $command->isHidden() ? 1 : 0);

        $commandXML->appendChild($usagesXML = $dom->createElement('usages'));

        $commandXML->appendChild($descriptionXML = $dom->createElement('description'));
        $descriptionXML->appendChild($dom->createTextNode(str_replace("\n", "\n ", $command->getDescription())));

        if ($short) {
            foreach ($command->getAliases() as $usage) {
                $usagesXML->appendChild($dom->createElement('usage', $usage));
            }
        } else {
            $command->mergeApplicationDefinition(false);

            foreach (array_merge([$command->getSynopsis()], $command->getAliases(), $command->getUsages()) as $usage) {
                $usagesXML->appendChild($dom->createElement('usage', $usage));
            }

            $commandXML->appendChild($helpXML = $dom->createElement('help'));
            $helpXML->appendChild($dom->createTextNode(str_replace("\n", "\n ", $command->getProcessedHelp())));

            $definitionXML = $this->getInputDefinitionDocument($command->getDefinition());
            $this->appendDocument($commandXML, $definitionXML->getElementsByTagName('definition')->item(0));
        }

        return $dom;
    }

    public function getApplicationDocument(Application $application, string $namespace = null, bool $short = false): \DOMDocument
    {
        $dom = new \DOMDocument('1.0', 'UTF-8');
        $dom->appendChild($rootXml = $dom->createElement('symfony'));

        if ('UNKNOWN' !== $application->getName()) {
            $rootXml->setAttribute('name', $application->getName());
            if ('UNKNOWN' !== $application->getVersion()) {
                $rootXml->setAttribute('version', $application->getVersion());
            }
        }

        $rootXml->appendChild($commandsXML = $dom->createElement('commands'));

        $description = new ApplicationDescription($application, $namespace, true);

        if ($namespace) {
            $commandsXML->setAttribute('namespace', $namespace);
        }

        foreach ($description->getCommands() as $command) {
            $this->appendDocument($commandsXML, $this->getCommandDocument($command, $short));
        }

        if (!$namespace) {
            $rootXml->appendChild($namespacesXML = $dom->createElement('namespaces'));

            foreach ($description->getNamespaces() as $namespaceDescription) {
                $namespacesXML->appendChild($namespaceArrayXML = $dom->createElement('namespace'));
                $namespaceArrayXML->setAttribute('id', $namespaceDescription['id']);

                foreach ($namespaceDescription['commands'] as $name) {
                    $namespaceArrayXML->appendChild($commandXML = $dom->createElement('command'));
                    $commandXML->appendChild($dom->createTextNode($name));
                }
            }
        }

        return $dom;
    }

    /**
     * {@inheritdoc}
     */
    protected function describeInputArgument(InputArgument $argument, array $options = [])
    {
        $this->writeDocument($this->getInputArgumentDocument($argument));
    }

    /**
     * {@inheritdoc}
     */
    protected function describeInputOption(InputOption $option, array $options = [])
    {
        $this->writeDocument($this->getInputOptionDocument($option));
    }

    /**
     * {@inheritdoc}
     */
    protected function describeInputDefinition(InputDefinition $definition, array $options = [])
    {
        $this->writeDocument($this->getInputDefinitionDocument($definition));
    }

    /**
     * {@inheritdoc}
     */
    protected function describeCommand(Command $command, array $options = [])
    {
        $this->writeDocument($this->getCommandDocument($command, $options['short'] ?? false));
    }

    /**
     * {@inheritdoc}
     */
    protected function describeApplication(Application $application, array $options = [])
    {
        $this->writeDocument($this->getApplicationDocument($application, $options['namespace'] ?? null, $options['short'] ?? false));
    }

    /**
     * Appends document children to parent node.
     */
    private function appendDocument(\DOMNode $parentNode, \DOMNode $importedParent)
    {
        foreach ($importedParent->childNodes as $childNode) {
            $parentNode->appendChild($parentNode->ownerDocument->importNode($childNode, true));
        }
    }

    /**
     * Writes DOM document.
     */
    private function writeDocument(\DOMDocument $dom)
    {
        $dom->formatOutput = true;
        $this->write($dom->saveXML());
    }

    private function getInputArgumentDocument(InputArgument $argument): \DOMDocument
    {
        $dom = new \DOMDocument('1.0', 'UTF-8');

        $dom->appendChild($objectXML = $dom->createElement('argument'));
        $objectXML->setAttribute('name', $argument->getName());
        $objectXML->setAttribute('is_required', $argument->isRequired() ? 1 : 0);
        $objectXML->setAttribute('is_array', $argument->isArray() ? 1 : 0);
        $objectXML->appendChild($descriptionXML = $dom->createElement('description'));
        $descriptionXML->appendChild($dom->createTextNode($argument->getDescription()));

        $objectXML->appendChild($defaultsXML = $dom->createElement('defaults'));
        $defaults = \is_array($argument->getDefault()) ? $argument->getDefault() : (\is_bool($argument->getDefault()) ? [var_export($argument->getDefault(), true)] : ($argument->getDefault() ? [$argument->getDefault()] : []));
        foreach ($defaults as $default) {
            $defaultsXML->appendChild($defaultXML = $dom->createElement('default'));
            $defaultXML->appendChild($dom->createTextNode($default));
        }

        return $dom;
    }

    private function getInputOptionDocument(InputOption $option): \DOMDocument
    {
        $dom = new \DOMDocument('1.0', 'UTF-8');

        $dom->appendChild($objectXML = $dom->createElement('option'));
        $objectXML->setAttribute('name', '--'.$option->getName());
        $pos = strpos($option->getShortcut() ?? '', '|');
        if (false !== $pos) {
            $objectXML->setAttribute('shortcut', '-'.substr($option->getShortcut(), 0, $pos));
            $objectXML->setAttribute('shortcuts', '-'.str_replace('|', '|-', $option->getShortcut()));
        } else {
            $objectXML->setAttribute('shortcut', $option->getShortcut() ? '-'.$option->getShortcut() : '');
        }
        $objectXML->setAttribute('accept_value', $option->acceptValue() ? 1 : 0);
        $objectXML->setAttribute('is_value_required', $option->isValueRequired() ? 1 : 0);
        $objectXML->setAttribute('is_multiple', $option->isArray() ? 1 : 0);
        $objectXML->appendChild($descriptionXML = $dom->createElement('description'));
        $descriptionXML->appendChild($dom->createTextNode($option->getDescription()));

        if ($option->acceptValue()) {
            $defaults = \is_array($option->getDefault()) ? $option->getDefault() : (\is_bool($option->getDefault()) ? [var_export($option->getDefault(), true)] : ($option->getDefault() ? [$option->getDefault()] : []));
            $objectXML->appendChild($defaultsXML = $dom->createElement('defaults'));

            if (!empty($defaults)) {
                foreach ($defaults as $default) {
                    $defaultsXML->appendChild($defaultXML = $dom->createElement('default'));
                    $defaultXML->appendChild($dom->createTextNode($default));
                }
            }
        }

        if ($option->isNegatable()) {
            $dom->appendChild($objectXML = $dom->createElement('option'));
            $objectXML->setAttribute('name', '--no-'.$option->getName());
            $objectXML->setAttribute('shortcut', '');
            $objectXML->setAttribute('accept_value', 0);
            $objectXML->setAttribute('is_value_required', 0);
            $objectXML->setAttribute('is_multiple', 0);
            $objectXML->appendChild($descriptionXML = $dom->createElement('description'));
            $descriptionXML->appendChild($dom->createTextNode('Negate the "--'.$option->getName().'" option'));
        }

        return $dom;
    }
}
PKϤ$Z-����-console/Descriptor/ApplicationDescription.phpnu�[���<?php

/*
 * This file is part of the Symfony package.
 *
 * (c) Fabien Potencier <fabien@symfony.com>
 *
 * For the full copyright and license information, please view the LICENSE
 * file that was distributed with this source code.
 */

namespace Symfony\Component\Console\Descriptor;

use Symfony\Component\Console\Application;
use Symfony\Component\Console\Command\Command;
use Symfony\Component\Console\Exception\CommandNotFoundException;

/**
 * @author Jean-François Simon <jeanfrancois.simon@sensiolabs.com>
 *
 * @internal
 */
class ApplicationDescription
{
    public const GLOBAL_NAMESPACE = '_global';

    private $application;
    private $namespace;
    private $showHidden;

    /**
     * @var array
     */
    private $namespaces;

    /**
     * @var array<string, Command>
     */
    private $commands;

    /**
     * @var array<string, Command>
     */
    private $aliases;

    public function __construct(Application $application, string $namespace = null, bool $showHidden = false)
    {
        $this->application = $application;
        $this->namespace = $namespace;
        $this->showHidden = $showHidden;
    }

    public function getNamespaces(): array
    {
        if (null === $this->namespaces) {
            $this->inspectApplication();
        }

        return $this->namespaces;
    }

    /**
     * @return Command[]
     */
    public function getCommands(): array
    {
        if (null === $this->commands) {
            $this->inspectApplication();
        }

        return $this->commands;
    }

    /**
     * @throws CommandNotFoundException
     */
    public function getCommand(string $name): Command
    {
        if (!isset($this->commands[$name]) && !isset($this->aliases[$name])) {
            throw new CommandNotFoundException(sprintf('Command "%s" does not exist.', $name));
        }

        return $this->commands[$name] ?? $this->aliases[$name];
    }

    private function inspectApplication()
    {
        $this->commands = [];
        $this->namespaces = [];

        $all = $this->application->all($this->namespace ? $this->application->findNamespace($this->namespace) : null);
        foreach ($this->sortCommands($all) as $namespace => $commands) {
            $names = [];

            /** @var Command $command */
            foreach ($commands as $name => $command) {
                if (!$command->getName() || (!$this->showHidden && $command->isHidden())) {
                    continue;
                }

                if ($command->getName() === $name) {
                    $this->commands[$name] = $command;
                } else {
                    $this->aliases[$name] = $command;
                }

                $names[] = $name;
            }

            $this->namespaces[$namespace] = ['id' => $namespace, 'commands' => $names];
        }
    }

    private function sortCommands(array $commands): array
    {
        $namespacedCommands = [];
        $globalCommands = [];
        $sortedCommands = [];
        foreach ($commands as $name => $command) {
            $key = $this->application->extractNamespace($name, 1);
            if (\in_array($key, ['', self::GLOBAL_NAMESPACE], true)) {
                $globalCommands[$name] = $command;
            } else {
                $namespacedCommands[$key][$name] = $command;
            }
        }

        if ($globalCommands) {
            ksort($globalCommands);
            $sortedCommands[self::GLOBAL_NAMESPACE] = $globalCommands;
        }

        if ($namespacedCommands) {
            ksort($namespacedCommands, \SORT_STRING);
            foreach ($namespacedCommands as $key => $commandsSet) {
                ksort($commandsSet);
                $sortedCommands[$key] = $commandsSet;
            }
        }

        return $sortedCommands;
    }
}
PKϤ$Z�ቜL1L1%console/Descriptor/TextDescriptor.phpnu�[���<?php

/*
 * This file is part of the Symfony package.
 *
 * (c) Fabien Potencier <fabien@symfony.com>
 *
 * For the full copyright and license information, please view the LICENSE
 * file that was distributed with this source code.
 */

namespace Symfony\Component\Console\Descriptor;

use Symfony\Component\Console\Application;
use Symfony\Component\Console\Command\Command;
use Symfony\Component\Console\Formatter\OutputFormatter;
use Symfony\Component\Console\Helper\Helper;
use Symfony\Component\Console\Input\InputArgument;
use Symfony\Component\Console\Input\InputDefinition;
use Symfony\Component\Console\Input\InputOption;

/**
 * Text descriptor.
 *
 * @author Jean-François Simon <contact@jfsimon.fr>
 *
 * @internal
 */
class TextDescriptor extends Descriptor
{
    /**
     * {@inheritdoc}
     */
    protected function describeInputArgument(InputArgument $argument, array $options = [])
    {
        if (null !== $argument->getDefault() && (!\is_array($argument->getDefault()) || \count($argument->getDefault()))) {
            $default = sprintf('<comment> [default: %s]</comment>', $this->formatDefaultValue($argument->getDefault()));
        } else {
            $default = '';
        }

        $totalWidth = $options['total_width'] ?? Helper::width($argument->getName());
        $spacingWidth = $totalWidth - \strlen($argument->getName());

        $this->writeText(sprintf('  <info>%s</info>  %s%s%s',
            $argument->getName(),
            str_repeat(' ', $spacingWidth),
            // + 4 = 2 spaces before <info>, 2 spaces after </info>
            preg_replace('/\s*[\r\n]\s*/', "\n".str_repeat(' ', $totalWidth + 4), $argument->getDescription()),
            $default
        ), $options);
    }

    /**
     * {@inheritdoc}
     */
    protected function describeInputOption(InputOption $option, array $options = [])
    {
        if ($option->acceptValue() && null !== $option->getDefault() && (!\is_array($option->getDefault()) || \count($option->getDefault()))) {
            $default = sprintf('<comment> [default: %s]</comment>', $this->formatDefaultValue($option->getDefault()));
        } else {
            $default = '';
        }

        $value = '';
        if ($option->acceptValue()) {
            $value = '='.strtoupper($option->getName());

            if ($option->isValueOptional()) {
                $value = '['.$value.']';
            }
        }

        $totalWidth = $options['total_width'] ?? $this->calculateTotalWidthForOptions([$option]);
        $synopsis = sprintf('%s%s',
            $option->getShortcut() ? sprintf('-%s, ', $option->getShortcut()) : '    ',
            sprintf($option->isNegatable() ? '--%1$s|--no-%1$s' : '--%1$s%2$s', $option->getName(), $value)
        );

        $spacingWidth = $totalWidth - Helper::width($synopsis);

        $this->writeText(sprintf('  <info>%s</info>  %s%s%s%s',
            $synopsis,
            str_repeat(' ', $spacingWidth),
            // + 4 = 2 spaces before <info>, 2 spaces after </info>
            preg_replace('/\s*[\r\n]\s*/', "\n".str_repeat(' ', $totalWidth + 4), $option->getDescription()),
            $default,
            $option->isArray() ? '<comment> (multiple values allowed)</comment>' : ''
        ), $options);
    }

    /**
     * {@inheritdoc}
     */
    protected function describeInputDefinition(InputDefinition $definition, array $options = [])
    {
        $totalWidth = $this->calculateTotalWidthForOptions($definition->getOptions());
        foreach ($definition->getArguments() as $argument) {
            $totalWidth = max($totalWidth, Helper::width($argument->getName()));
        }

        if ($definition->getArguments()) {
            $this->writeText('<comment>Arguments:</comment>', $options);
            $this->writeText("\n");
            foreach ($definition->getArguments() as $argument) {
                $this->describeInputArgument($argument, array_merge($options, ['total_width' => $totalWidth]));
                $this->writeText("\n");
            }
        }

        if ($definition->getArguments() && $definition->getOptions()) {
            $this->writeText("\n");
        }

        if ($definition->getOptions()) {
            $laterOptions = [];

            $this->writeText('<comment>Options:</comment>', $options);
            foreach ($definition->getOptions() as $option) {
                if (\strlen($option->getShortcut() ?? '') > 1) {
                    $laterOptions[] = $option;
                    continue;
                }
                $this->writeText("\n");
                $this->describeInputOption($option, array_merge($options, ['total_width' => $totalWidth]));
            }
            foreach ($laterOptions as $option) {
                $this->writeText("\n");
                $this->describeInputOption($option, array_merge($options, ['total_width' => $totalWidth]));
            }
        }
    }

    /**
     * {@inheritdoc}
     */
    protected function describeCommand(Command $command, array $options = [])
    {
        $command->mergeApplicationDefinition(false);

        if ($description = $command->getDescription()) {
            $this->writeText('<comment>Description:</comment>', $options);
            $this->writeText("\n");
            $this->writeText('  '.$description);
            $this->writeText("\n\n");
        }

        $this->writeText('<comment>Usage:</comment>', $options);
        foreach (array_merge([$command->getSynopsis(true)], $command->getAliases(), $command->getUsages()) as $usage) {
            $this->writeText("\n");
            $this->writeText('  '.OutputFormatter::escape($usage), $options);
        }
        $this->writeText("\n");

        $definition = $command->getDefinition();
        if ($definition->getOptions() || $definition->getArguments()) {
            $this->writeText("\n");
            $this->describeInputDefinition($definition, $options);
            $this->writeText("\n");
        }

        $help = $command->getProcessedHelp();
        if ($help && $help !== $description) {
            $this->writeText("\n");
            $this->writeText('<comment>Help:</comment>', $options);
            $this->writeText("\n");
            $this->writeText('  '.str_replace("\n", "\n  ", $help), $options);
            $this->writeText("\n");
        }
    }

    /**
     * {@inheritdoc}
     */
    protected function describeApplication(Application $application, array $options = [])
    {
        $describedNamespace = $options['namespace'] ?? null;
        $description = new ApplicationDescription($application, $describedNamespace);

        if (isset($options['raw_text']) && $options['raw_text']) {
            $width = $this->getColumnWidth($description->getCommands());

            foreach ($description->getCommands() as $command) {
                $this->writeText(sprintf("%-{$width}s %s", $command->getName(), $command->getDescription()), $options);
                $this->writeText("\n");
            }
        } else {
            if ('' != $help = $application->getHelp()) {
                $this->writeText("$help\n\n", $options);
            }

            $this->writeText("<comment>Usage:</comment>\n", $options);
            $this->writeText("  command [options] [arguments]\n\n", $options);

            $this->describeInputDefinition(new InputDefinition($application->getDefinition()->getOptions()), $options);

            $this->writeText("\n");
            $this->writeText("\n");

            $commands = $description->getCommands();
            $namespaces = $description->getNamespaces();
            if ($describedNamespace && $namespaces) {
                // make sure all alias commands are included when describing a specific namespace
                $describedNamespaceInfo = reset($namespaces);
                foreach ($describedNamespaceInfo['commands'] as $name) {
                    $commands[$name] = $description->getCommand($name);
                }
            }

            // calculate max. width based on available commands per namespace
            $width = $this->getColumnWidth(array_merge(...array_values(array_map(function ($namespace) use ($commands) {
                return array_intersect($namespace['commands'], array_keys($commands));
            }, array_values($namespaces)))));

            if ($describedNamespace) {
                $this->writeText(sprintf('<comment>Available commands for the "%s" namespace:</comment>', $describedNamespace), $options);
            } else {
                $this->writeText('<comment>Available commands:</comment>', $options);
            }

            foreach ($namespaces as $namespace) {
                $namespace['commands'] = array_filter($namespace['commands'], function ($name) use ($commands) {
                    return isset($commands[$name]);
                });

                if (!$namespace['commands']) {
                    continue;
                }

                if (!$describedNamespace && ApplicationDescription::GLOBAL_NAMESPACE !== $namespace['id']) {
                    $this->writeText("\n");
                    $this->writeText(' <comment>'.$namespace['id'].'</comment>', $options);
                }

                foreach ($namespace['commands'] as $name) {
                    $this->writeText("\n");
                    $spacingWidth = $width - Helper::width($name);
                    $command = $commands[$name];
                    $commandAliases = $name === $command->getName() ? $this->getCommandAliasesText($command) : '';
                    $this->writeText(sprintf('  <info>%s</info>%s%s', $name, str_repeat(' ', $spacingWidth), $commandAliases.$command->getDescription()), $options);
                }
            }

            $this->writeText("\n");
        }
    }

    /**
     * {@inheritdoc}
     */
    private function writeText(string $content, array $options = [])
    {
        $this->write(
            isset($options['raw_text']) && $options['raw_text'] ? strip_tags($content) : $content,
            isset($options['raw_output']) ? !$options['raw_output'] : true
        );
    }

    /**
     * Formats command aliases to show them in the command description.
     */
    private function getCommandAliasesText(Command $command): string
    {
        $text = '';
        $aliases = $command->getAliases();

        if ($aliases) {
            $text = '['.implode('|', $aliases).'] ';
        }

        return $text;
    }

    /**
     * Formats input option/argument default value.
     *
     * @param mixed $default
     */
    private function formatDefaultValue($default): string
    {
        if (\INF === $default) {
            return 'INF';
        }

        if (\is_string($default)) {
            $default = OutputFormatter::escape($default);
        } elseif (\is_array($default)) {
            foreach ($default as $key => $value) {
                if (\is_string($value)) {
                    $default[$key] = OutputFormatter::escape($value);
                }
            }
        }

        return str_replace('\\\\', '\\', json_encode($default, \JSON_UNESCAPED_SLASHES | \JSON_UNESCAPED_UNICODE));
    }

    /**
     * @param array<Command|string> $commands
     */
    private function getColumnWidth(array $commands): int
    {
        $widths = [];

        foreach ($commands as $command) {
            if ($command instanceof Command) {
                $widths[] = Helper::width($command->getName());
                foreach ($command->getAliases() as $alias) {
                    $widths[] = Helper::width($alias);
                }
            } else {
                $widths[] = Helper::width($command);
            }
        }

        return $widths ? max($widths) + 2 : 0;
    }

    /**
     * @param InputOption[] $options
     */
    private function calculateTotalWidthForOptions(array $options): int
    {
        $totalWidth = 0;
        foreach ($options as $option) {
            // "-" + shortcut + ", --" + name
            $nameLength = 1 + max(Helper::width($option->getShortcut()), 1) + 4 + Helper::width($option->getName());
            if ($option->isNegatable()) {
                $nameLength += 6 + Helper::width($option->getName()); // |--no- + name
            } elseif ($option->acceptValue()) {
                $valueLength = 1 + Helper::width($option->getName()); // = + value
                $valueLength += $option->isValueOptional() ? 2 : 0; // [ + ]

                $nameLength += $valueLength;
            }
            $totalWidth = max($totalWidth, $nameLength);
        }

        return $totalWidth;
    }
}
PKϤ$Z��4{��)console/Descriptor/MarkdownDescriptor.phpnu�[���<?php

/*
 * This file is part of the Symfony package.
 *
 * (c) Fabien Potencier <fabien@symfony.com>
 *
 * For the full copyright and license information, please view the LICENSE
 * file that was distributed with this source code.
 */

namespace Symfony\Component\Console\Descriptor;

use Symfony\Component\Console\Application;
use Symfony\Component\Console\Command\Command;
use Symfony\Component\Console\Helper\Helper;
use Symfony\Component\Console\Input\InputArgument;
use Symfony\Component\Console\Input\InputDefinition;
use Symfony\Component\Console\Input\InputOption;
use Symfony\Component\Console\Output\OutputInterface;

/**
 * Markdown descriptor.
 *
 * @author Jean-François Simon <contact@jfsimon.fr>
 *
 * @internal
 */
class MarkdownDescriptor extends Descriptor
{
    /**
     * {@inheritdoc}
     */
    public function describe(OutputInterface $output, object $object, array $options = [])
    {
        $decorated = $output->isDecorated();
        $output->setDecorated(false);

        parent::describe($output, $object, $options);

        $output->setDecorated($decorated);
    }

    /**
     * {@inheritdoc}
     */
    protected function write(string $content, bool $decorated = true)
    {
        parent::write($content, $decorated);
    }

    /**
     * {@inheritdoc}
     */
    protected function describeInputArgument(InputArgument $argument, array $options = [])
    {
        $this->write(
            '#### `'.($argument->getName() ?: '<none>')."`\n\n"
            .($argument->getDescription() ? preg_replace('/\s*[\r\n]\s*/', "\n", $argument->getDescription())."\n\n" : '')
            .'* Is required: '.($argument->isRequired() ? 'yes' : 'no')."\n"
            .'* Is array: '.($argument->isArray() ? 'yes' : 'no')."\n"
            .'* Default: `'.str_replace("\n", '', var_export($argument->getDefault(), true)).'`'
        );
    }

    /**
     * {@inheritdoc}
     */
    protected function describeInputOption(InputOption $option, array $options = [])
    {
        $name = '--'.$option->getName();
        if ($option->isNegatable()) {
            $name .= '|--no-'.$option->getName();
        }
        if ($option->getShortcut()) {
            $name .= '|-'.str_replace('|', '|-', $option->getShortcut()).'';
        }

        $this->write(
            '#### `'.$name.'`'."\n\n"
            .($option->getDescription() ? preg_replace('/\s*[\r\n]\s*/', "\n", $option->getDescription())."\n\n" : '')
            .'* Accept value: '.($option->acceptValue() ? 'yes' : 'no')."\n"
            .'* Is value required: '.($option->isValueRequired() ? 'yes' : 'no')."\n"
            .'* Is multiple: '.($option->isArray() ? 'yes' : 'no')."\n"
            .'* Is negatable: '.($option->isNegatable() ? 'yes' : 'no')."\n"
            .'* Default: `'.str_replace("\n", '', var_export($option->getDefault(), true)).'`'
        );
    }

    /**
     * {@inheritdoc}
     */
    protected function describeInputDefinition(InputDefinition $definition, array $options = [])
    {
        if ($showArguments = \count($definition->getArguments()) > 0) {
            $this->write('### Arguments');
            foreach ($definition->getArguments() as $argument) {
                $this->write("\n\n");
                if (null !== $describeInputArgument = $this->describeInputArgument($argument)) {
                    $this->write($describeInputArgument);
                }
            }
        }

        if (\count($definition->getOptions()) > 0) {
            if ($showArguments) {
                $this->write("\n\n");
            }

            $this->write('### Options');
            foreach ($definition->getOptions() as $option) {
                $this->write("\n\n");
                if (null !== $describeInputOption = $this->describeInputOption($option)) {
                    $this->write($describeInputOption);
                }
            }
        }
    }

    /**
     * {@inheritdoc}
     */
    protected function describeCommand(Command $command, array $options = [])
    {
        if ($options['short'] ?? false) {
            $this->write(
                '`'.$command->getName()."`\n"
                .str_repeat('-', Helper::width($command->getName()) + 2)."\n\n"
                .($command->getDescription() ? $command->getDescription()."\n\n" : '')
                .'### Usage'."\n\n"
                .array_reduce($command->getAliases(), function ($carry, $usage) {
                    return $carry.'* `'.$usage.'`'."\n";
                })
            );

            return;
        }

        $command->mergeApplicationDefinition(false);

        $this->write(
            '`'.$command->getName()."`\n"
            .str_repeat('-', Helper::width($command->getName()) + 2)."\n\n"
            .($command->getDescription() ? $command->getDescription()."\n\n" : '')
            .'### Usage'."\n\n"
            .array_reduce(array_merge([$command->getSynopsis()], $command->getAliases(), $command->getUsages()), function ($carry, $usage) {
                return $carry.'* `'.$usage.'`'."\n";
            })
        );

        if ($help = $command->getProcessedHelp()) {
            $this->write("\n");
            $this->write($help);
        }

        $definition = $command->getDefinition();
        if ($definition->getOptions() || $definition->getArguments()) {
            $this->write("\n\n");
            $this->describeInputDefinition($definition);
        }
    }

    /**
     * {@inheritdoc}
     */
    protected function describeApplication(Application $application, array $options = [])
    {
        $describedNamespace = $options['namespace'] ?? null;
        $description = new ApplicationDescription($application, $describedNamespace);
        $title = $this->getApplicationTitle($application);

        $this->write($title."\n".str_repeat('=', Helper::width($title)));

        foreach ($description->getNamespaces() as $namespace) {
            if (ApplicationDescription::GLOBAL_NAMESPACE !== $namespace['id']) {
                $this->write("\n\n");
                $this->write('**'.$namespace['id'].':**');
            }

            $this->write("\n\n");
            $this->write(implode("\n", array_map(function ($commandName) use ($description) {
                return sprintf('* [`%s`](#%s)', $commandName, str_replace(':', '', $description->getCommand($commandName)->getName()));
            }, $namespace['commands'])));
        }

        foreach ($description->getCommands() as $command) {
            $this->write("\n\n");
            if (null !== $describeCommand = $this->describeCommand($command, $options)) {
                $this->write($describeCommand);
            }
        }
    }

    private function getApplicationTitle(Application $application): string
    {
        if ('UNKNOWN' !== $application->getName()) {
            if ('UNKNOWN' !== $application->getVersion()) {
                return sprintf('%s %s', $application->getName(), $application->getVersion());
            }

            return $application->getName();
        }

        return 'Console Tool';
    }
}
PKϤ$Z�j��%console/Descriptor/JsonDescriptor.phpnu�[���<?php

/*
 * This file is part of the Symfony package.
 *
 * (c) Fabien Potencier <fabien@symfony.com>
 *
 * For the full copyright and license information, please view the LICENSE
 * file that was distributed with this source code.
 */

namespace Symfony\Component\Console\Descriptor;

use Symfony\Component\Console\Application;
use Symfony\Component\Console\Command\Command;
use Symfony\Component\Console\Input\InputArgument;
use Symfony\Component\Console\Input\InputDefinition;
use Symfony\Component\Console\Input\InputOption;

/**
 * JSON descriptor.
 *
 * @author Jean-François Simon <contact@jfsimon.fr>
 *
 * @internal
 */
class JsonDescriptor extends Descriptor
{
    /**
     * {@inheritdoc}
     */
    protected function describeInputArgument(InputArgument $argument, array $options = [])
    {
        $this->writeData($this->getInputArgumentData($argument), $options);
    }

    /**
     * {@inheritdoc}
     */
    protected function describeInputOption(InputOption $option, array $options = [])
    {
        $this->writeData($this->getInputOptionData($option), $options);
        if ($option->isNegatable()) {
            $this->writeData($this->getInputOptionData($option, true), $options);
        }
    }

    /**
     * {@inheritdoc}
     */
    protected function describeInputDefinition(InputDefinition $definition, array $options = [])
    {
        $this->writeData($this->getInputDefinitionData($definition), $options);
    }

    /**
     * {@inheritdoc}
     */
    protected function describeCommand(Command $command, array $options = [])
    {
        $this->writeData($this->getCommandData($command, $options['short'] ?? false), $options);
    }

    /**
     * {@inheritdoc}
     */
    protected function describeApplication(Application $application, array $options = [])
    {
        $describedNamespace = $options['namespace'] ?? null;
        $description = new ApplicationDescription($application, $describedNamespace, true);
        $commands = [];

        foreach ($description->getCommands() as $command) {
            $commands[] = $this->getCommandData($command, $options['short'] ?? false);
        }

        $data = [];
        if ('UNKNOWN' !== $application->getName()) {
            $data['application']['name'] = $application->getName();
            if ('UNKNOWN' !== $application->getVersion()) {
                $data['application']['version'] = $application->getVersion();
            }
        }

        $data['commands'] = $commands;

        if ($describedNamespace) {
            $data['namespace'] = $describedNamespace;
        } else {
            $data['namespaces'] = array_values($description->getNamespaces());
        }

        $this->writeData($data, $options);
    }

    /**
     * Writes data as json.
     */
    private function writeData(array $data, array $options)
    {
        $flags = $options['json_encoding'] ?? 0;

        $this->write(json_encode($data, $flags));
    }

    private function getInputArgumentData(InputArgument $argument): array
    {
        return [
            'name' => $argument->getName(),
            'is_required' => $argument->isRequired(),
            'is_array' => $argument->isArray(),
            'description' => preg_replace('/\s*[\r\n]\s*/', ' ', $argument->getDescription()),
            'default' => \INF === $argument->getDefault() ? 'INF' : $argument->getDefault(),
        ];
    }

    private function getInputOptionData(InputOption $option, bool $negated = false): array
    {
        return $negated ? [
            'name' => '--no-'.$option->getName(),
            'shortcut' => '',
            'accept_value' => false,
            'is_value_required' => false,
            'is_multiple' => false,
            'description' => 'Negate the "--'.$option->getName().'" option',
            'default' => false,
        ] : [
            'name' => '--'.$option->getName(),
            'shortcut' => $option->getShortcut() ? '-'.str_replace('|', '|-', $option->getShortcut()) : '',
            'accept_value' => $option->acceptValue(),
            'is_value_required' => $option->isValueRequired(),
            'is_multiple' => $option->isArray(),
            'description' => preg_replace('/\s*[\r\n]\s*/', ' ', $option->getDescription()),
            'default' => \INF === $option->getDefault() ? 'INF' : $option->getDefault(),
        ];
    }

    private function getInputDefinitionData(InputDefinition $definition): array
    {
        $inputArguments = [];
        foreach ($definition->getArguments() as $name => $argument) {
            $inputArguments[$name] = $this->getInputArgumentData($argument);
        }

        $inputOptions = [];
        foreach ($definition->getOptions() as $name => $option) {
            $inputOptions[$name] = $this->getInputOptionData($option);
            if ($option->isNegatable()) {
                $inputOptions['no-'.$name] = $this->getInputOptionData($option, true);
            }
        }

        return ['arguments' => $inputArguments, 'options' => $inputOptions];
    }

    private function getCommandData(Command $command, bool $short = false): array
    {
        $data = [
            'name' => $command->getName(),
            'description' => $command->getDescription(),
        ];

        if ($short) {
            $data += [
                'usage' => $command->getAliases(),
            ];
        } else {
            $command->mergeApplicationDefinition(false);

            $data += [
                'usage' => array_merge([$command->getSynopsis()], $command->getUsages(), $command->getAliases()),
                'help' => $command->getProcessedHelp(),
                'definition' => $this->getInputDefinitionData($command->getDefinition()),
            ];
        }

        $data['hidden'] = $command->isHidden();

        return $data;
    }
}
PKϤ$Z0�M$--*console/Descriptor/DescriptorInterface.phpnu�[���<?php

/*
 * This file is part of the Symfony package.
 *
 * (c) Fabien Potencier <fabien@symfony.com>
 *
 * For the full copyright and license information, please view the LICENSE
 * file that was distributed with this source code.
 */

namespace Symfony\Component\Console\Descriptor;

use Symfony\Component\Console\Output\OutputInterface;

/**
 * Descriptor interface.
 *
 * @author Jean-François Simon <contact@jfsimon.fr>
 */
interface DescriptorInterface
{
    public function describe(OutputInterface $output, object $object, array $options = []);
}
PKϤ$Z�k%9��!console/Descriptor/Descriptor.phpnu�[���<?php

/*
 * This file is part of the Symfony package.
 *
 * (c) Fabien Potencier <fabien@symfony.com>
 *
 * For the full copyright and license information, please view the LICENSE
 * file that was distributed with this source code.
 */

namespace Symfony\Component\Console\Descriptor;

use Symfony\Component\Console\Application;
use Symfony\Component\Console\Command\Command;
use Symfony\Component\Console\Exception\InvalidArgumentException;
use Symfony\Component\Console\Input\InputArgument;
use Symfony\Component\Console\Input\InputDefinition;
use Symfony\Component\Console\Input\InputOption;
use Symfony\Component\Console\Output\OutputInterface;

/**
 * @author Jean-François Simon <jeanfrancois.simon@sensiolabs.com>
 *
 * @internal
 */
abstract class Descriptor implements DescriptorInterface
{
    /**
     * @var OutputInterface
     */
    protected $output;

    /**
     * {@inheritdoc}
     */
    public function describe(OutputInterface $output, object $object, array $options = [])
    {
        $this->output = $output;

        switch (true) {
            case $object instanceof InputArgument:
                $this->describeInputArgument($object, $options);
                break;
            case $object instanceof InputOption:
                $this->describeInputOption($object, $options);
                break;
            case $object instanceof InputDefinition:
                $this->describeInputDefinition($object, $options);
                break;
            case $object instanceof Command:
                $this->describeCommand($object, $options);
                break;
            case $object instanceof Application:
                $this->describeApplication($object, $options);
                break;
            default:
                throw new InvalidArgumentException(sprintf('Object of type "%s" is not describable.', get_debug_type($object)));
        }
    }

    /**
     * Writes content to output.
     */
    protected function write(string $content, bool $decorated = false)
    {
        $this->output->write($content, false, $decorated ? OutputInterface::OUTPUT_NORMAL : OutputInterface::OUTPUT_RAW);
    }

    /**
     * Describes an InputArgument instance.
     */
    abstract protected function describeInputArgument(InputArgument $argument, array $options = []);

    /**
     * Describes an InputOption instance.
     */
    abstract protected function describeInputOption(InputOption $option, array $options = []);

    /**
     * Describes an InputDefinition instance.
     */
    abstract protected function describeInputDefinition(InputDefinition $definition, array $options = []);

    /**
     * Describes a Command instance.
     */
    abstract protected function describeCommand(Command $command, array $options = []);

    /**
     * Describes an Application instance.
     */
    abstract protected function describeApplication(Application $application, array $options = []);
}
PKϤ$Z#���
 
 &console/Completion/CompletionInput.phpnu�[���<?php

/*
 * This file is part of the Symfony package.
 *
 * (c) Fabien Potencier <fabien@symfony.com>
 *
 * For the full copyright and license information, please view the LICENSE
 * file that was distributed with this source code.
 */

namespace Symfony\Component\Console\Completion;

use Symfony\Component\Console\Exception\RuntimeException;
use Symfony\Component\Console\Input\ArgvInput;
use Symfony\Component\Console\Input\InputDefinition;
use Symfony\Component\Console\Input\InputOption;

/**
 * An input specialized for shell completion.
 *
 * This input allows unfinished option names or values and exposes what kind of
 * completion is expected.
 *
 * @author Wouter de Jong <wouter@wouterj.nl>
 */
final class CompletionInput extends ArgvInput
{
    public const TYPE_ARGUMENT_VALUE = 'argument_value';
    public const TYPE_OPTION_VALUE = 'option_value';
    public const TYPE_OPTION_NAME = 'option_name';
    public const TYPE_NONE = 'none';

    private $tokens;
    private $currentIndex;
    private $completionType;
    private $completionName = null;
    private $completionValue = '';

    /**
     * Converts a terminal string into tokens.
     *
     * This is required for shell completions without COMP_WORDS support.
     */
    public static function fromString(string $inputStr, int $currentIndex): self
    {
        preg_match_all('/(?<=^|\s)([\'"]?)(.+?)(?<!\\\\)\1(?=$|\s)/', $inputStr, $tokens);

        return self::fromTokens($tokens[0], $currentIndex);
    }

    /**
     * Create an input based on an COMP_WORDS token list.
     *
     * @param string[] $tokens       the set of split tokens (e.g. COMP_WORDS or argv)
     * @param          $currentIndex the index of the cursor (e.g. COMP_CWORD)
     */
    public static function fromTokens(array $tokens, int $currentIndex): self
    {
        $input = new self($tokens);
        $input->tokens = $tokens;
        $input->currentIndex = $currentIndex;

        return $input;
    }

    /**
     * {@inheritdoc}
     */
    public function bind(InputDefinition $definition): void
    {
        parent::bind($definition);

        $relevantToken = $this->getRelevantToken();
        if ('-' === $relevantToken[0]) {
            // the current token is an input option: complete either option name or option value
            [$optionToken, $optionValue] = explode('=', $relevantToken, 2) + ['', ''];

            $option = $this->getOptionFromToken($optionToken);
            if (null === $option && !$this->isCursorFree()) {
                $this->completionType = self::TYPE_OPTION_NAME;
                $this->completionValue = $relevantToken;

                return;
            }

            if (null !== $option && $option->acceptValue()) {
                $this->completionType = self::TYPE_OPTION_VALUE;
                $this->completionName = $option->getName();
                $this->completionValue = $optionValue ?: (!str_starts_with($optionToken, '--') ? substr($optionToken, 2) : '');

                return;
            }
        }

        $previousToken = $this->tokens[$this->currentIndex - 1];
        if ('-' === $previousToken[0] && '' !== trim($previousToken, '-')) {
            // check if previous option accepted a value
            $previousOption = $this->getOptionFromToken($previousToken);
            if (null !== $previousOption && $previousOption->acceptValue()) {
                $this->completionType = self::TYPE_OPTION_VALUE;
                $this->completionName = $previousOption->getName();
                $this->completionValue = $relevantToken;

                return;
            }
        }

        // complete argument value
        $this->completionType = self::TYPE_ARGUMENT_VALUE;

        foreach ($this->definition->getArguments() as $argumentName => $argument) {
            if (!isset($this->arguments[$argumentName])) {
                break;
            }

            $argumentValue = $this->arguments[$argumentName];
            $this->completionName = $argumentName;
            if (\is_array($argumentValue)) {
                $this->completionValue = $argumentValue ? $argumentValue[array_key_last($argumentValue)] : null;
            } else {
                $this->completionValue = $argumentValue;
            }
        }

        if ($this->currentIndex >= \count($this->tokens)) {
            if (!isset($this->arguments[$argumentName]) || $this->definition->getArgument($argumentName)->isArray()) {
                $this->completionName = $argumentName;
                $this->completionValue = '';
            } else {
                // we've reached the end
                $this->completionType = self::TYPE_NONE;
                $this->completionName = null;
                $this->completionValue = '';
            }
        }
    }

    /**
     * Returns the type of completion required.
     *
     * TYPE_ARGUMENT_VALUE when completing the value of an input argument
     * TYPE_OPTION_VALUE   when completing the value of an input option
     * TYPE_OPTION_NAME    when completing the name of an input option
     * TYPE_NONE           when nothing should be completed
     *
     * @return string One of self::TYPE_* constants. TYPE_OPTION_NAME and TYPE_NONE are already implemented by the Console component
     */
    public function getCompletionType(): string
    {
        return $this->completionType;
    }

    /**
     * The name of the input option or argument when completing a value.
     *
     * @return string|null returns null when completing an option name
     */
    public function getCompletionName(): ?string
    {
        return $this->completionName;
    }

    /**
     * The value already typed by the user (or empty string).
     */
    public function getCompletionValue(): string
    {
        return $this->completionValue;
    }

    public function mustSuggestOptionValuesFor(string $optionName): bool
    {
        return self::TYPE_OPTION_VALUE === $this->getCompletionType() && $optionName === $this->getCompletionName();
    }

    public function mustSuggestArgumentValuesFor(string $argumentName): bool
    {
        return self::TYPE_ARGUMENT_VALUE === $this->getCompletionType() && $argumentName === $this->getCompletionName();
    }

    protected function parseToken(string $token, bool $parseOptions): bool
    {
        try {
            return parent::parseToken($token, $parseOptions);
        } catch (RuntimeException $e) {
            // suppress errors, completed input is almost never valid
        }

        return $parseOptions;
    }

    private function getOptionFromToken(string $optionToken): ?InputOption
    {
        $optionName = ltrim($optionToken, '-');
        if (!$optionName) {
            return null;
        }

        if ('-' === ($optionToken[1] ?? ' ')) {
            // long option name
            return $this->definition->hasOption($optionName) ? $this->definition->getOption($optionName) : null;
        }

        // short option name
        return $this->definition->hasShortcut($optionName[0]) ? $this->definition->getOptionForShortcut($optionName[0]) : null;
    }

    /**
     * The token of the cursor, or the last token if the cursor is at the end of the input.
     */
    private function getRelevantToken(): string
    {
        return $this->tokens[$this->isCursorFree() ? $this->currentIndex - 1 : $this->currentIndex];
    }

    /**
     * Whether the cursor is "free" (i.e. at the end of the input preceded by a space).
     */
    private function isCursorFree(): bool
    {
        $nrOfTokens = \count($this->tokens);
        if ($this->currentIndex > $nrOfTokens) {
            throw new \LogicException('Current index is invalid, it must be the number of input tokens or one more.');
        }

        return $this->currentIndex >= $nrOfTokens;
    }

    public function __toString()
    {
        $str = '';
        foreach ($this->tokens as $i => $token) {
            $str .= $token;

            if ($this->currentIndex === $i) {
                $str .= '|';
            }

            $str .= ' ';
        }

        if ($this->currentIndex > $i) {
            $str .= '|';
        }

        return rtrim($str);
    }
}
PKϤ$Zb�ۋ��!console/Completion/Suggestion.phpnu�[���<?php

/*
 * This file is part of the Symfony package.
 *
 * (c) Fabien Potencier <fabien@symfony.com>
 *
 * For the full copyright and license information, please view the LICENSE
 * file that was distributed with this source code.
 */

namespace Symfony\Component\Console\Completion;

/**
 * Represents a single suggested value.
 *
 * @author Wouter de Jong <wouter@wouterj.nl>
 */
class Suggestion
{
    private $value;

    public function __construct(string $value)
    {
        $this->value = $value;
    }

    public function getValue(): string
    {
        return $this->value;
    }

    public function __toString(): string
    {
        return $this->getValue();
    }
}
PKϤ$Z��(NN,console/Completion/CompletionSuggestions.phpnu�[���<?php

/*
 * This file is part of the Symfony package.
 *
 * (c) Fabien Potencier <fabien@symfony.com>
 *
 * For the full copyright and license information, please view the LICENSE
 * file that was distributed with this source code.
 */

namespace Symfony\Component\Console\Completion;

use Symfony\Component\Console\Input\InputOption;

/**
 * Stores all completion suggestions for the current input.
 *
 * @author Wouter de Jong <wouter@wouterj.nl>
 */
final class CompletionSuggestions
{
    private $valueSuggestions = [];
    private $optionSuggestions = [];

    /**
     * Add a suggested value for an input option or argument.
     *
     * @param string|Suggestion $value
     *
     * @return $this
     */
    public function suggestValue($value): self
    {
        $this->valueSuggestions[] = !$value instanceof Suggestion ? new Suggestion($value) : $value;

        return $this;
    }

    /**
     * Add multiple suggested values at once for an input option or argument.
     *
     * @param list<string|Suggestion> $values
     *
     * @return $this
     */
    public function suggestValues(array $values): self
    {
        foreach ($values as $value) {
            $this->suggestValue($value);
        }

        return $this;
    }

    /**
     * Add a suggestion for an input option name.
     *
     * @return $this
     */
    public function suggestOption(InputOption $option): self
    {
        $this->optionSuggestions[] = $option;

        return $this;
    }

    /**
     * Add multiple suggestions for input option names at once.
     *
     * @param InputOption[] $options
     *
     * @return $this
     */
    public function suggestOptions(array $options): self
    {
        foreach ($options as $option) {
            $this->suggestOption($option);
        }

        return $this;
    }

    /**
     * @return InputOption[]
     */
    public function getOptionSuggestions(): array
    {
        return $this->optionSuggestions;
    }

    /**
     * @return Suggestion[]
     */
    public function getValueSuggestions(): array
    {
        return $this->valueSuggestions;
    }
}
PKϤ$Z3��O��7console/Completion/Output/CompletionOutputInterface.phpnu�[���<?php

/*
 * This file is part of the Symfony package.
 *
 * (c) Fabien Potencier <fabien@symfony.com>
 *
 * For the full copyright and license information, please view the LICENSE
 * file that was distributed with this source code.
 */

namespace Symfony\Component\Console\Completion\Output;

use Symfony\Component\Console\Completion\CompletionSuggestions;
use Symfony\Component\Console\Output\OutputInterface;

/**
 * Transforms the {@see CompletionSuggestions} object into output readable by the shell completion.
 *
 * @author Wouter de Jong <wouter@wouterj.nl>
 */
interface CompletionOutputInterface
{
    public function write(CompletionSuggestions $suggestions, OutputInterface $output): void;
}
PKϤ$Z�S���2console/Completion/Output/BashCompletionOutput.phpnu�[���<?php

/*
 * This file is part of the Symfony package.
 *
 * (c) Fabien Potencier <fabien@symfony.com>
 *
 * For the full copyright and license information, please view the LICENSE
 * file that was distributed with this source code.
 */

namespace Symfony\Component\Console\Completion\Output;

use Symfony\Component\Console\Completion\CompletionSuggestions;
use Symfony\Component\Console\Output\OutputInterface;

/**
 * @author Wouter de Jong <wouter@wouterj.nl>
 */
class BashCompletionOutput implements CompletionOutputInterface
{
    public function write(CompletionSuggestions $suggestions, OutputInterface $output): void
    {
        $values = $suggestions->getValueSuggestions();
        foreach ($suggestions->getOptionSuggestions() as $option) {
            $values[] = '--'.$option->getName();
            if ($option->isNegatable()) {
                $values[] = '--no-'.$option->getName();
            }
        }
        $output->writeln(implode("\n", $values));
    }
}
PKϤ$Zv�.�11)console/SignalRegistry/SignalRegistry.phpnu�[���<?php

/*
 * This file is part of the Symfony package.
 *
 * (c) Fabien Potencier <fabien@symfony.com>
 *
 * For the full copyright and license information, please view the LICENSE
 * file that was distributed with this source code.
 */

namespace Symfony\Component\Console\SignalRegistry;

final class SignalRegistry
{
    private $signalHandlers = [];

    public function __construct()
    {
        if (\function_exists('pcntl_async_signals')) {
            pcntl_async_signals(true);
        }
    }

    public function register(int $signal, callable $signalHandler): void
    {
        if (!isset($this->signalHandlers[$signal])) {
            $previousCallback = pcntl_signal_get_handler($signal);

            if (\is_callable($previousCallback)) {
                $this->signalHandlers[$signal][] = $previousCallback;
            }
        }

        $this->signalHandlers[$signal][] = $signalHandler;

        pcntl_signal($signal, [$this, 'handle']);
    }

    public static function isSupported(): bool
    {
        if (!\function_exists('pcntl_signal')) {
            return false;
        }

        if (\in_array('pcntl_signal', explode(',', \ini_get('disable_functions')))) {
            return false;
        }

        return true;
    }

    /**
     * @internal
     */
    public function handle(int $signal): void
    {
        $count = \count($this->signalHandlers[$signal]);

        foreach ($this->signalHandlers[$signal] as $i => $signalHandler) {
            $hasNext = $i !== $count - 1;
            $signalHandler($signal, $hasNext);
        }
    }
}
PKϤ$Z?u��)console/Question/ConfirmationQuestion.phpnu�[���<?php

/*
 * This file is part of the Symfony package.
 *
 * (c) Fabien Potencier <fabien@symfony.com>
 *
 * For the full copyright and license information, please view the LICENSE
 * file that was distributed with this source code.
 */

namespace Symfony\Component\Console\Question;

/**
 * Represents a yes/no question.
 *
 * @author Fabien Potencier <fabien@symfony.com>
 */
class ConfirmationQuestion extends Question
{
    private $trueAnswerRegex;

    /**
     * @param string $question        The question to ask to the user
     * @param bool   $default         The default answer to return, true or false
     * @param string $trueAnswerRegex A regex to match the "yes" answer
     */
    public function __construct(string $question, bool $default = true, string $trueAnswerRegex = '/^y/i')
    {
        parent::__construct($question, $default);

        $this->trueAnswerRegex = $trueAnswerRegex;
        $this->setNormalizer($this->getDefaultNormalizer());
    }

    /**
     * Returns the default answer normalizer.
     */
    private function getDefaultNormalizer(): callable
    {
        $default = $this->getDefault();
        $regex = $this->trueAnswerRegex;

        return function ($answer) use ($default, $regex) {
            if (\is_bool($answer)) {
                return $answer;
            }

            $answerIsTrue = (bool) preg_match($regex, $answer);
            if (false === $default) {
                return $answer && $answerIsTrue;
            }

            return '' === $answer || $answerIsTrue;
        };
    }
}
PKϤ$ZM?|dWWconsole/Question/Question.phpnu�[���<?php

/*
 * This file is part of the Symfony package.
 *
 * (c) Fabien Potencier <fabien@symfony.com>
 *
 * For the full copyright and license information, please view the LICENSE
 * file that was distributed with this source code.
 */

namespace Symfony\Component\Console\Question;

use Symfony\Component\Console\Exception\InvalidArgumentException;
use Symfony\Component\Console\Exception\LogicException;

/**
 * Represents a Question.
 *
 * @author Fabien Potencier <fabien@symfony.com>
 */
class Question
{
    private $question;
    private $attempts;
    private $hidden = false;
    private $hiddenFallback = true;
    private $autocompleterCallback;
    private $validator;
    private $default;
    private $normalizer;
    private $trimmable = true;
    private $multiline = false;

    /**
     * @param string                     $question The question to ask to the user
     * @param string|bool|int|float|null $default  The default answer to return if the user enters nothing
     */
    public function __construct(string $question, $default = null)
    {
        $this->question = $question;
        $this->default = $default;
    }

    /**
     * Returns the question.
     *
     * @return string
     */
    public function getQuestion()
    {
        return $this->question;
    }

    /**
     * Returns the default answer.
     *
     * @return string|bool|int|float|null
     */
    public function getDefault()
    {
        return $this->default;
    }

    /**
     * Returns whether the user response accepts newline characters.
     */
    public function isMultiline(): bool
    {
        return $this->multiline;
    }

    /**
     * Sets whether the user response should accept newline characters.
     *
     * @return $this
     */
    public function setMultiline(bool $multiline): self
    {
        $this->multiline = $multiline;

        return $this;
    }

    /**
     * Returns whether the user response must be hidden.
     *
     * @return bool
     */
    public function isHidden()
    {
        return $this->hidden;
    }

    /**
     * Sets whether the user response must be hidden or not.
     *
     * @return $this
     *
     * @throws LogicException In case the autocompleter is also used
     */
    public function setHidden(bool $hidden)
    {
        if ($this->autocompleterCallback) {
            throw new LogicException('A hidden question cannot use the autocompleter.');
        }

        $this->hidden = $hidden;

        return $this;
    }

    /**
     * In case the response cannot be hidden, whether to fallback on non-hidden question or not.
     *
     * @return bool
     */
    public function isHiddenFallback()
    {
        return $this->hiddenFallback;
    }

    /**
     * Sets whether to fallback on non-hidden question if the response cannot be hidden.
     *
     * @return $this
     */
    public function setHiddenFallback(bool $fallback)
    {
        $this->hiddenFallback = $fallback;

        return $this;
    }

    /**
     * Gets values for the autocompleter.
     *
     * @return iterable|null
     */
    public function getAutocompleterValues()
    {
        $callback = $this->getAutocompleterCallback();

        return $callback ? $callback('') : null;
    }

    /**
     * Sets values for the autocompleter.
     *
     * @return $this
     *
     * @throws LogicException
     */
    public function setAutocompleterValues(?iterable $values)
    {
        if (\is_array($values)) {
            $values = $this->isAssoc($values) ? array_merge(array_keys($values), array_values($values)) : array_values($values);

            $callback = static function () use ($values) {
                return $values;
            };
        } elseif ($values instanceof \Traversable) {
            $valueCache = null;
            $callback = static function () use ($values, &$valueCache) {
                return $valueCache ?? $valueCache = iterator_to_array($values, false);
            };
        } else {
            $callback = null;
        }

        return $this->setAutocompleterCallback($callback);
    }

    /**
     * Gets the callback function used for the autocompleter.
     */
    public function getAutocompleterCallback(): ?callable
    {
        return $this->autocompleterCallback;
    }

    /**
     * Sets the callback function used for the autocompleter.
     *
     * The callback is passed the user input as argument and should return an iterable of corresponding suggestions.
     *
     * @return $this
     */
    public function setAutocompleterCallback(callable $callback = null): self
    {
        if ($this->hidden && null !== $callback) {
            throw new LogicException('A hidden question cannot use the autocompleter.');
        }

        $this->autocompleterCallback = $callback;

        return $this;
    }

    /**
     * Sets a validator for the question.
     *
     * @return $this
     */
    public function setValidator(callable $validator = null)
    {
        $this->validator = $validator;

        return $this;
    }

    /**
     * Gets the validator for the question.
     *
     * @return callable|null
     */
    public function getValidator()
    {
        return $this->validator;
    }

    /**
     * Sets the maximum number of attempts.
     *
     * Null means an unlimited number of attempts.
     *
     * @return $this
     *
     * @throws InvalidArgumentException in case the number of attempts is invalid
     */
    public function setMaxAttempts(?int $attempts)
    {
        if (null !== $attempts && $attempts < 1) {
            throw new InvalidArgumentException('Maximum number of attempts must be a positive value.');
        }

        $this->attempts = $attempts;

        return $this;
    }

    /**
     * Gets the maximum number of attempts.
     *
     * Null means an unlimited number of attempts.
     *
     * @return int|null
     */
    public function getMaxAttempts()
    {
        return $this->attempts;
    }

    /**
     * Sets a normalizer for the response.
     *
     * The normalizer can be a callable (a string), a closure or a class implementing __invoke.
     *
     * @return $this
     */
    public function setNormalizer(callable $normalizer)
    {
        $this->normalizer = $normalizer;

        return $this;
    }

    /**
     * Gets the normalizer for the response.
     *
     * The normalizer can ba a callable (a string), a closure or a class implementing __invoke.
     *
     * @return callable|null
     */
    public function getNormalizer()
    {
        return $this->normalizer;
    }

    protected function isAssoc(array $array)
    {
        return (bool) \count(array_filter(array_keys($array), 'is_string'));
    }

    public function isTrimmable(): bool
    {
        return $this->trimmable;
    }

    /**
     * @return $this
     */
    public function setTrimmable(bool $trimmable): self
    {
        $this->trimmable = $trimmable;

        return $this;
    }
}
PKϤ$Z����#console/Question/ChoiceQuestion.phpnu�[���<?php

/*
 * This file is part of the Symfony package.
 *
 * (c) Fabien Potencier <fabien@symfony.com>
 *
 * For the full copyright and license information, please view the LICENSE
 * file that was distributed with this source code.
 */

namespace Symfony\Component\Console\Question;

use Symfony\Component\Console\Exception\InvalidArgumentException;

/**
 * Represents a choice question.
 *
 * @author Fabien Potencier <fabien@symfony.com>
 */
class ChoiceQuestion extends Question
{
    private $choices;
    private $multiselect = false;
    private $prompt = ' > ';
    private $errorMessage = 'Value "%s" is invalid';

    /**
     * @param string $question The question to ask to the user
     * @param array  $choices  The list of available choices
     * @param mixed  $default  The default answer to return
     */
    public function __construct(string $question, array $choices, $default = null)
    {
        if (!$choices) {
            throw new \LogicException('Choice question must have at least 1 choice available.');
        }

        parent::__construct($question, $default);

        $this->choices = $choices;
        $this->setValidator($this->getDefaultValidator());
        $this->setAutocompleterValues($choices);
    }

    /**
     * Returns available choices.
     *
     * @return array
     */
    public function getChoices()
    {
        return $this->choices;
    }

    /**
     * Sets multiselect option.
     *
     * When multiselect is set to true, multiple choices can be answered.
     *
     * @return $this
     */
    public function setMultiselect(bool $multiselect)
    {
        $this->multiselect = $multiselect;
        $this->setValidator($this->getDefaultValidator());

        return $this;
    }

    /**
     * Returns whether the choices are multiselect.
     *
     * @return bool
     */
    public function isMultiselect()
    {
        return $this->multiselect;
    }

    /**
     * Gets the prompt for choices.
     *
     * @return string
     */
    public function getPrompt()
    {
        return $this->prompt;
    }

    /**
     * Sets the prompt for choices.
     *
     * @return $this
     */
    public function setPrompt(string $prompt)
    {
        $this->prompt = $prompt;

        return $this;
    }

    /**
     * Sets the error message for invalid values.
     *
     * The error message has a string placeholder (%s) for the invalid value.
     *
     * @return $this
     */
    public function setErrorMessage(string $errorMessage)
    {
        $this->errorMessage = $errorMessage;
        $this->setValidator($this->getDefaultValidator());

        return $this;
    }

    private function getDefaultValidator(): callable
    {
        $choices = $this->choices;
        $errorMessage = $this->errorMessage;
        $multiselect = $this->multiselect;
        $isAssoc = $this->isAssoc($choices);

        return function ($selected) use ($choices, $errorMessage, $multiselect, $isAssoc) {
            if ($multiselect) {
                // Check for a separated comma values
                if (!preg_match('/^[^,]+(?:,[^,]+)*$/', (string) $selected, $matches)) {
                    throw new InvalidArgumentException(sprintf($errorMessage, $selected));
                }

                $selectedChoices = explode(',', (string) $selected);
            } else {
                $selectedChoices = [$selected];
            }

            if ($this->isTrimmable()) {
                foreach ($selectedChoices as $k => $v) {
                    $selectedChoices[$k] = trim((string) $v);
                }
            }

            $multiselectChoices = [];
            foreach ($selectedChoices as $value) {
                $results = [];
                foreach ($choices as $key => $choice) {
                    if ($choice === $value) {
                        $results[] = $key;
                    }
                }

                if (\count($results) > 1) {
                    throw new InvalidArgumentException(sprintf('The provided answer is ambiguous. Value should be one of "%s".', implode('" or "', $results)));
                }

                $result = array_search($value, $choices);

                if (!$isAssoc) {
                    if (false !== $result) {
                        $result = $choices[$result];
                    } elseif (isset($choices[$value])) {
                        $result = $choices[$value];
                    }
                } elseif (false === $result && isset($choices[$value])) {
                    $result = $value;
                }

                if (false === $result) {
                    throw new InvalidArgumentException(sprintf($errorMessage, $value));
                }

                // For associative choices, consistently return the key as string:
                $multiselectChoices[] = $isAssoc ? (string) $result : $result;
            }

            if ($multiselect) {
                return $multiselectChoices;
            }

            return current($multiselectChoices);
        };
    }
}
PKϤ$Zі�""console/Cursor.phpnu�[���<?php

/*
 * This file is part of the Symfony package.
 *
 * (c) Fabien Potencier <fabien@symfony.com>
 *
 * For the full copyright and license information, please view the LICENSE
 * file that was distributed with this source code.
 */

namespace Symfony\Component\Console;

use Symfony\Component\Console\Output\OutputInterface;

/**
 * @author Pierre du Plessis <pdples@gmail.com>
 */
final class Cursor
{
    private $output;
    private $input;

    /**
     * @param resource|null $input
     */
    public function __construct(OutputInterface $output, $input = null)
    {
        $this->output = $output;
        $this->input = $input ?? (\defined('STDIN') ? \STDIN : fopen('php://input', 'r+'));
    }

    /**
     * @return $this
     */
    public function moveUp(int $lines = 1): self
    {
        $this->output->write(sprintf("\x1b[%dA", $lines));

        return $this;
    }

    /**
     * @return $this
     */
    public function moveDown(int $lines = 1): self
    {
        $this->output->write(sprintf("\x1b[%dB", $lines));

        return $this;
    }

    /**
     * @return $this
     */
    public function moveRight(int $columns = 1): self
    {
        $this->output->write(sprintf("\x1b[%dC", $columns));

        return $this;
    }

    /**
     * @return $this
     */
    public function moveLeft(int $columns = 1): self
    {
        $this->output->write(sprintf("\x1b[%dD", $columns));

        return $this;
    }

    /**
     * @return $this
     */
    public function moveToColumn(int $column): self
    {
        $this->output->write(sprintf("\x1b[%dG", $column));

        return $this;
    }

    /**
     * @return $this
     */
    public function moveToPosition(int $column, int $row): self
    {
        $this->output->write(sprintf("\x1b[%d;%dH", $row + 1, $column));

        return $this;
    }

    /**
     * @return $this
     */
    public function savePosition(): self
    {
        $this->output->write("\x1b7");

        return $this;
    }

    /**
     * @return $this
     */
    public function restorePosition(): self
    {
        $this->output->write("\x1b8");

        return $this;
    }

    /**
     * @return $this
     */
    public function hide(): self
    {
        $this->output->write("\x1b[?25l");

        return $this;
    }

    /**
     * @return $this
     */
    public function show(): self
    {
        $this->output->write("\x1b[?25h\x1b[?0c");

        return $this;
    }

    /**
     * Clears all the output from the current line.
     *
     * @return $this
     */
    public function clearLine(): self
    {
        $this->output->write("\x1b[2K");

        return $this;
    }

    /**
     * Clears all the output from the current line after the current position.
     */
    public function clearLineAfter(): self
    {
        $this->output->write("\x1b[K");

        return $this;
    }

    /**
     * Clears all the output from the cursors' current position to the end of the screen.
     *
     * @return $this
     */
    public function clearOutput(): self
    {
        $this->output->write("\x1b[0J");

        return $this;
    }

    /**
     * Clears the entire screen.
     *
     * @return $this
     */
    public function clearScreen(): self
    {
        $this->output->write("\x1b[2J");

        return $this;
    }

    /**
     * Returns the current cursor position as x,y coordinates.
     */
    public function getCurrentPosition(): array
    {
        static $isTtySupported;

        if (null === $isTtySupported && \function_exists('proc_open')) {
            $isTtySupported = (bool) @proc_open('echo 1 >/dev/null', [['file', '/dev/tty', 'r'], ['file', '/dev/tty', 'w'], ['file', '/dev/tty', 'w']], $pipes);
        }

        if (!$isTtySupported) {
            return [1, 1];
        }

        $sttyMode = shell_exec('stty -g');
        shell_exec('stty -icanon -echo');

        @fwrite($this->input, "\033[6n");

        $code = trim(fread($this->input, 1024));

        shell_exec(sprintf('stty %s', $sttyMode));

        sscanf($code, "\033[%d;%dR", $row, $col);

        return [$col, $row];
    }
}
PKϤ$Z�"l??#console/CI/GithubActionReporter.phpnu�[���<?php

/*
 * This file is part of the Symfony package.
 *
 * (c) Fabien Potencier <fabien@symfony.com>
 *
 * For the full copyright and license information, please view the LICENSE
 * file that was distributed with this source code.
 */

namespace Symfony\Component\Console\CI;

use Symfony\Component\Console\Output\OutputInterface;

/**
 * Utility class for Github actions.
 *
 * @author Maxime Steinhausser <maxime.steinhausser@gmail.com>
 */
class GithubActionReporter
{
    private $output;

    /**
     * @see https://github.com/actions/toolkit/blob/5e5e1b7aacba68a53836a34db4a288c3c1c1585b/packages/core/src/command.ts#L80-L85
     */
    private const ESCAPED_DATA = [
        '%' => '%25',
        "\r" => '%0D',
        "\n" => '%0A',
    ];

    /**
     * @see https://github.com/actions/toolkit/blob/5e5e1b7aacba68a53836a34db4a288c3c1c1585b/packages/core/src/command.ts#L87-L94
     */
    private const ESCAPED_PROPERTIES = [
        '%' => '%25',
        "\r" => '%0D',
        "\n" => '%0A',
        ':' => '%3A',
        ',' => '%2C',
    ];

    public function __construct(OutputInterface $output)
    {
        $this->output = $output;
    }

    public static function isGithubActionEnvironment(): bool
    {
        return false !== getenv('GITHUB_ACTIONS');
    }

    /**
     * Output an error using the Github annotations format.
     *
     * @see https://docs.github.com/en/free-pro-team@latest/actions/reference/workflow-commands-for-github-actions#setting-an-error-message
     */
    public function error(string $message, string $file = null, int $line = null, int $col = null): void
    {
        $this->log('error', $message, $file, $line, $col);
    }

    /**
     * Output a warning using the Github annotations format.
     *
     * @see https://docs.github.com/en/free-pro-team@latest/actions/reference/workflow-commands-for-github-actions#setting-a-warning-message
     */
    public function warning(string $message, string $file = null, int $line = null, int $col = null): void
    {
        $this->log('warning', $message, $file, $line, $col);
    }

    /**
     * Output a debug log using the Github annotations format.
     *
     * @see https://docs.github.com/en/free-pro-team@latest/actions/reference/workflow-commands-for-github-actions#setting-a-debug-message
     */
    public function debug(string $message, string $file = null, int $line = null, int $col = null): void
    {
        $this->log('debug', $message, $file, $line, $col);
    }

    private function log(string $type, string $message, string $file = null, int $line = null, int $col = null): void
    {
        // Some values must be encoded.
        $message = strtr($message, self::ESCAPED_DATA);

        if (!$file) {
            // No file provided, output the message solely:
            $this->output->writeln(sprintf('::%s::%s', $type, $message));

            return;
        }

        $this->output->writeln(sprintf('::%s file=%s,line=%s,col=%s::%s', $type, strtr($file, self::ESCAPED_PROPERTIES), strtr($line ?? 1, self::ESCAPED_PROPERTIES), strtr($col ?? 0, self::ESCAPED_PROPERTIES), $message));
    }
}
PKϤ$Z������console/Style/OutputStyle.phpnu�[���<?php

/*
 * This file is part of the Symfony package.
 *
 * (c) Fabien Potencier <fabien@symfony.com>
 *
 * For the full copyright and license information, please view the LICENSE
 * file that was distributed with this source code.
 */

namespace Symfony\Component\Console\Style;

use Symfony\Component\Console\Formatter\OutputFormatterInterface;
use Symfony\Component\Console\Helper\ProgressBar;
use Symfony\Component\Console\Output\ConsoleOutputInterface;
use Symfony\Component\Console\Output\OutputInterface;

/**
 * Decorates output to add console style guide helpers.
 *
 * @author Kevin Bond <kevinbond@gmail.com>
 */
abstract class OutputStyle implements OutputInterface, StyleInterface
{
    private $output;

    public function __construct(OutputInterface $output)
    {
        $this->output = $output;
    }

    /**
     * {@inheritdoc}
     */
    public function newLine(int $count = 1)
    {
        $this->output->write(str_repeat(\PHP_EOL, $count));
    }

    /**
     * @return ProgressBar
     */
    public function createProgressBar(int $max = 0)
    {
        return new ProgressBar($this->output, $max);
    }

    /**
     * {@inheritdoc}
     */
    public function write($messages, bool $newline = false, int $type = self::OUTPUT_NORMAL)
    {
        $this->output->write($messages, $newline, $type);
    }

    /**
     * {@inheritdoc}
     */
    public function writeln($messages, int $type = self::OUTPUT_NORMAL)
    {
        $this->output->writeln($messages, $type);
    }

    /**
     * {@inheritdoc}
     */
    public function setVerbosity(int $level)
    {
        $this->output->setVerbosity($level);
    }

    /**
     * {@inheritdoc}
     */
    public function getVerbosity()
    {
        return $this->output->getVerbosity();
    }

    /**
     * {@inheritdoc}
     */
    public function setDecorated(bool $decorated)
    {
        $this->output->setDecorated($decorated);
    }

    /**
     * {@inheritdoc}
     */
    public function isDecorated()
    {
        return $this->output->isDecorated();
    }

    /**
     * {@inheritdoc}
     */
    public function setFormatter(OutputFormatterInterface $formatter)
    {
        $this->output->setFormatter($formatter);
    }

    /**
     * {@inheritdoc}
     */
    public function getFormatter()
    {
        return $this->output->getFormatter();
    }

    /**
     * {@inheritdoc}
     */
    public function isQuiet()
    {
        return $this->output->isQuiet();
    }

    /**
     * {@inheritdoc}
     */
    public function isVerbose()
    {
        return $this->output->isVerbose();
    }

    /**
     * {@inheritdoc}
     */
    public function isVeryVerbose()
    {
        return $this->output->isVeryVerbose();
    }

    /**
     * {@inheritdoc}
     */
    public function isDebug()
    {
        return $this->output->isDebug();
    }

    protected function getErrorOutput()
    {
        if (!$this->output instanceof ConsoleOutputInterface) {
            return $this->output;
        }

        return $this->output->getErrorOutput();
    }
}
PKϤ$Z���)M
M
 console/Style/StyleInterface.phpnu�[���<?php

/*
 * This file is part of the Symfony package.
 *
 * (c) Fabien Potencier <fabien@symfony.com>
 *
 * For the full copyright and license information, please view the LICENSE
 * file that was distributed with this source code.
 */

namespace Symfony\Component\Console\Style;

/**
 * Output style helpers.
 *
 * @author Kevin Bond <kevinbond@gmail.com>
 */
interface StyleInterface
{
    /**
     * Formats a command title.
     */
    public function title(string $message);

    /**
     * Formats a section title.
     */
    public function section(string $message);

    /**
     * Formats a list.
     */
    public function listing(array $elements);

    /**
     * Formats informational text.
     *
     * @param string|array $message
     */
    public function text($message);

    /**
     * Formats a success result bar.
     *
     * @param string|array $message
     */
    public function success($message);

    /**
     * Formats an error result bar.
     *
     * @param string|array $message
     */
    public function error($message);

    /**
     * Formats an warning result bar.
     *
     * @param string|array $message
     */
    public function warning($message);

    /**
     * Formats a note admonition.
     *
     * @param string|array $message
     */
    public function note($message);

    /**
     * Formats a caution admonition.
     *
     * @param string|array $message
     */
    public function caution($message);

    /**
     * Formats a table.
     */
    public function table(array $headers, array $rows);

    /**
     * Asks a question.
     *
     * @return mixed
     */
    public function ask(string $question, string $default = null, callable $validator = null);

    /**
     * Asks a question with the user input hidden.
     *
     * @return mixed
     */
    public function askHidden(string $question, callable $validator = null);

    /**
     * Asks for confirmation.
     *
     * @return bool
     */
    public function confirm(string $question, bool $default = true);

    /**
     * Asks a choice question.
     *
     * @param string|int|null $default
     *
     * @return mixed
     */
    public function choice(string $question, array $choices, $default = null);

    /**
     * Add newline(s).
     */
    public function newLine(int $count = 1);

    /**
     * Starts the progress output.
     */
    public function progressStart(int $max = 0);

    /**
     * Advances the progress output X steps.
     */
    public function progressAdvance(int $step = 1);

    /**
     * Finishes the progress output.
     */
    public function progressFinish();
}
PKϤ$Z��ͨ 9 9console/Style/SymfonyStyle.phpnu�[���<?php

/*
 * This file is part of the Symfony package.
 *
 * (c) Fabien Potencier <fabien@symfony.com>
 *
 * For the full copyright and license information, please view the LICENSE
 * file that was distributed with this source code.
 */

namespace Symfony\Component\Console\Style;

use Symfony\Component\Console\Exception\InvalidArgumentException;
use Symfony\Component\Console\Exception\RuntimeException;
use Symfony\Component\Console\Formatter\OutputFormatter;
use Symfony\Component\Console\Helper\Helper;
use Symfony\Component\Console\Helper\ProgressBar;
use Symfony\Component\Console\Helper\SymfonyQuestionHelper;
use Symfony\Component\Console\Helper\Table;
use Symfony\Component\Console\Helper\TableCell;
use Symfony\Component\Console\Helper\TableSeparator;
use Symfony\Component\Console\Input\InputInterface;
use Symfony\Component\Console\Output\ConsoleOutputInterface;
use Symfony\Component\Console\Output\OutputInterface;
use Symfony\Component\Console\Output\TrimmedBufferOutput;
use Symfony\Component\Console\Question\ChoiceQuestion;
use Symfony\Component\Console\Question\ConfirmationQuestion;
use Symfony\Component\Console\Question\Question;
use Symfony\Component\Console\Terminal;

/**
 * Output decorator helpers for the Symfony Style Guide.
 *
 * @author Kevin Bond <kevinbond@gmail.com>
 */
class SymfonyStyle extends OutputStyle
{
    public const MAX_LINE_LENGTH = 120;

    private $input;
    private $output;
    private $questionHelper;
    private $progressBar;
    private $lineLength;
    private $bufferedOutput;

    public function __construct(InputInterface $input, OutputInterface $output)
    {
        $this->input = $input;
        $this->bufferedOutput = new TrimmedBufferOutput(\DIRECTORY_SEPARATOR === '\\' ? 4 : 2, $output->getVerbosity(), false, clone $output->getFormatter());
        // Windows cmd wraps lines as soon as the terminal width is reached, whether there are following chars or not.
        $width = (new Terminal())->getWidth() ?: self::MAX_LINE_LENGTH;
        $this->lineLength = min($width - (int) (\DIRECTORY_SEPARATOR === '\\'), self::MAX_LINE_LENGTH);

        parent::__construct($this->output = $output);
    }

    /**
     * Formats a message as a block of text.
     *
     * @param string|array $messages The message to write in the block
     */
    public function block($messages, string $type = null, string $style = null, string $prefix = ' ', bool $padding = false, bool $escape = true)
    {
        $messages = \is_array($messages) ? array_values($messages) : [$messages];

        $this->autoPrependBlock();
        $this->writeln($this->createBlock($messages, $type, $style, $prefix, $padding, $escape));
        $this->newLine();
    }

    /**
     * {@inheritdoc}
     */
    public function title(string $message)
    {
        $this->autoPrependBlock();
        $this->writeln([
            sprintf('<comment>%s</>', OutputFormatter::escapeTrailingBackslash($message)),
            sprintf('<comment>%s</>', str_repeat('=', Helper::width(Helper::removeDecoration($this->getFormatter(), $message)))),
        ]);
        $this->newLine();
    }

    /**
     * {@inheritdoc}
     */
    public function section(string $message)
    {
        $this->autoPrependBlock();
        $this->writeln([
            sprintf('<comment>%s</>', OutputFormatter::escapeTrailingBackslash($message)),
            sprintf('<comment>%s</>', str_repeat('-', Helper::width(Helper::removeDecoration($this->getFormatter(), $message)))),
        ]);
        $this->newLine();
    }

    /**
     * {@inheritdoc}
     */
    public function listing(array $elements)
    {
        $this->autoPrependText();
        $elements = array_map(function ($element) {
            return sprintf(' * %s', $element);
        }, $elements);

        $this->writeln($elements);
        $this->newLine();
    }

    /**
     * {@inheritdoc}
     */
    public function text($message)
    {
        $this->autoPrependText();

        $messages = \is_array($message) ? array_values($message) : [$message];
        foreach ($messages as $message) {
            $this->writeln(sprintf(' %s', $message));
        }
    }

    /**
     * Formats a command comment.
     *
     * @param string|array $message
     */
    public function comment($message)
    {
        $this->block($message, null, null, '<fg=default;bg=default> // </>', false, false);
    }

    /**
     * {@inheritdoc}
     */
    public function success($message)
    {
        $this->block($message, 'OK', 'fg=black;bg=green', ' ', true);
    }

    /**
     * {@inheritdoc}
     */
    public function error($message)
    {
        $this->block($message, 'ERROR', 'fg=white;bg=red', ' ', true);
    }

    /**
     * {@inheritdoc}
     */
    public function warning($message)
    {
        $this->block($message, 'WARNING', 'fg=black;bg=yellow', ' ', true);
    }

    /**
     * {@inheritdoc}
     */
    public function note($message)
    {
        $this->block($message, 'NOTE', 'fg=yellow', ' ! ');
    }

    /**
     * Formats an info message.
     *
     * @param string|array $message
     */
    public function info($message)
    {
        $this->block($message, 'INFO', 'fg=green', ' ', true);
    }

    /**
     * {@inheritdoc}
     */
    public function caution($message)
    {
        $this->block($message, 'CAUTION', 'fg=white;bg=red', ' ! ', true);
    }

    /**
     * {@inheritdoc}
     */
    public function table(array $headers, array $rows)
    {
        $this->createTable()
            ->setHeaders($headers)
            ->setRows($rows)
            ->render()
        ;

        $this->newLine();
    }

    /**
     * Formats a horizontal table.
     */
    public function horizontalTable(array $headers, array $rows)
    {
        $this->createTable()
            ->setHorizontal(true)
            ->setHeaders($headers)
            ->setRows($rows)
            ->render()
        ;

        $this->newLine();
    }

    /**
     * Formats a list of key/value horizontally.
     *
     * Each row can be one of:
     * * 'A title'
     * * ['key' => 'value']
     * * new TableSeparator()
     *
     * @param string|array|TableSeparator ...$list
     */
    public function definitionList(...$list)
    {
        $headers = [];
        $row = [];
        foreach ($list as $value) {
            if ($value instanceof TableSeparator) {
                $headers[] = $value;
                $row[] = $value;
                continue;
            }
            if (\is_string($value)) {
                $headers[] = new TableCell($value, ['colspan' => 2]);
                $row[] = null;
                continue;
            }
            if (!\is_array($value)) {
                throw new InvalidArgumentException('Value should be an array, string, or an instance of TableSeparator.');
            }
            $headers[] = key($value);
            $row[] = current($value);
        }

        $this->horizontalTable($headers, [$row]);
    }

    /**
     * {@inheritdoc}
     */
    public function ask(string $question, string $default = null, callable $validator = null)
    {
        $question = new Question($question, $default);
        $question->setValidator($validator);

        return $this->askQuestion($question);
    }

    /**
     * {@inheritdoc}
     */
    public function askHidden(string $question, callable $validator = null)
    {
        $question = new Question($question);

        $question->setHidden(true);
        $question->setValidator($validator);

        return $this->askQuestion($question);
    }

    /**
     * {@inheritdoc}
     */
    public function confirm(string $question, bool $default = true)
    {
        return $this->askQuestion(new ConfirmationQuestion($question, $default));
    }

    /**
     * {@inheritdoc}
     */
    public function choice(string $question, array $choices, $default = null)
    {
        if (null !== $default) {
            $values = array_flip($choices);
            $default = $values[$default] ?? $default;
        }

        return $this->askQuestion(new ChoiceQuestion($question, $choices, $default));
    }

    /**
     * {@inheritdoc}
     */
    public function progressStart(int $max = 0)
    {
        $this->progressBar = $this->createProgressBar($max);
        $this->progressBar->start();
    }

    /**
     * {@inheritdoc}
     */
    public function progressAdvance(int $step = 1)
    {
        $this->getProgressBar()->advance($step);
    }

    /**
     * {@inheritdoc}
     */
    public function progressFinish()
    {
        $this->getProgressBar()->finish();
        $this->newLine(2);
        $this->progressBar = null;
    }

    /**
     * {@inheritdoc}
     */
    public function createProgressBar(int $max = 0)
    {
        $progressBar = parent::createProgressBar($max);

        if ('\\' !== \DIRECTORY_SEPARATOR || 'Hyper' === getenv('TERM_PROGRAM')) {
            $progressBar->setEmptyBarCharacter('░'); // light shade character \u2591
            $progressBar->setProgressCharacter('');
            $progressBar->setBarCharacter('▓'); // dark shade character \u2593
        }

        return $progressBar;
    }

    /**
     * @see ProgressBar::iterate()
     */
    public function progressIterate(iterable $iterable, int $max = null): iterable
    {
        yield from $this->createProgressBar()->iterate($iterable, $max);

        $this->newLine(2);
    }

    /**
     * @return mixed
     */
    public function askQuestion(Question $question)
    {
        if ($this->input->isInteractive()) {
            $this->autoPrependBlock();
        }

        if (!$this->questionHelper) {
            $this->questionHelper = new SymfonyQuestionHelper();
        }

        $answer = $this->questionHelper->ask($this->input, $this, $question);

        if ($this->input->isInteractive()) {
            $this->newLine();
            $this->bufferedOutput->write("\n");
        }

        return $answer;
    }

    /**
     * {@inheritdoc}
     */
    public function writeln($messages, int $type = self::OUTPUT_NORMAL)
    {
        if (!is_iterable($messages)) {
            $messages = [$messages];
        }

        foreach ($messages as $message) {
            parent::writeln($message, $type);
            $this->writeBuffer($message, true, $type);
        }
    }

    /**
     * {@inheritdoc}
     */
    public function write($messages, bool $newline = false, int $type = self::OUTPUT_NORMAL)
    {
        if (!is_iterable($messages)) {
            $messages = [$messages];
        }

        foreach ($messages as $message) {
            parent::write($message, $newline, $type);
            $this->writeBuffer($message, $newline, $type);
        }
    }

    /**
     * {@inheritdoc}
     */
    public function newLine(int $count = 1)
    {
        parent::newLine($count);
        $this->bufferedOutput->write(str_repeat("\n", $count));
    }

    /**
     * Returns a new instance which makes use of stderr if available.
     *
     * @return self
     */
    public function getErrorStyle()
    {
        return new self($this->input, $this->getErrorOutput());
    }

    public function createTable(): Table
    {
        $output = $this->output instanceof ConsoleOutputInterface ? $this->output->section() : $this->output;
        $style = clone Table::getStyleDefinition('symfony-style-guide');
        $style->setCellHeaderFormat('<info>%s</info>');

        return (new Table($output))->setStyle($style);
    }

    private function getProgressBar(): ProgressBar
    {
        if (!$this->progressBar) {
            throw new RuntimeException('The ProgressBar is not started.');
        }

        return $this->progressBar;
    }

    private function autoPrependBlock(): void
    {
        $chars = substr(str_replace(\PHP_EOL, "\n", $this->bufferedOutput->fetch()), -2);

        if (!isset($chars[0])) {
            $this->newLine(); // empty history, so we should start with a new line.

            return;
        }
        // Prepend new line for each non LF chars (This means no blank line was output before)
        $this->newLine(2 - substr_count($chars, "\n"));
    }

    private function autoPrependText(): void
    {
        $fetched = $this->bufferedOutput->fetch();
        // Prepend new line if last char isn't EOL:
        if (!str_ends_with($fetched, "\n")) {
            $this->newLine();
        }
    }

    private function writeBuffer(string $message, bool $newLine, int $type): void
    {
        // We need to know if the last chars are PHP_EOL
        $this->bufferedOutput->write($message, $newLine, $type);
    }

    private function createBlock(iterable $messages, string $type = null, string $style = null, string $prefix = ' ', bool $padding = false, bool $escape = false): array
    {
        $indentLength = 0;
        $prefixLength = Helper::width(Helper::removeDecoration($this->getFormatter(), $prefix));
        $lines = [];

        if (null !== $type) {
            $type = sprintf('[%s] ', $type);
            $indentLength = \strlen($type);
            $lineIndentation = str_repeat(' ', $indentLength);
        }

        // wrap and add newlines for each element
        foreach ($messages as $key => $message) {
            if ($escape) {
                $message = OutputFormatter::escape($message);
            }

            $decorationLength = Helper::width($message) - Helper::width(Helper::removeDecoration($this->getFormatter(), $message));
            $messageLineLength = min($this->lineLength - $prefixLength - $indentLength + $decorationLength, $this->lineLength);
            $messageLines = explode(\PHP_EOL, wordwrap($message, $messageLineLength, \PHP_EOL, true));
            foreach ($messageLines as $messageLine) {
                $lines[] = $messageLine;
            }

            if (\count($messages) > 1 && $key < \count($messages) - 1) {
                $lines[] = '';
            }
        }

        $firstLineIndex = 0;
        if ($padding && $this->isDecorated()) {
            $firstLineIndex = 1;
            array_unshift($lines, '');
            $lines[] = '';
        }

        foreach ($lines as $i => &$line) {
            if (null !== $type) {
                $line = $firstLineIndex === $i ? $type.$line : $lineIndentation.$line;
            }

            $line = $prefix.$line;
            $line .= str_repeat(' ', max($this->lineLength - Helper::width(Helper::removeDecoration($this->getFormatter(), $line)), 0));

            if ($style) {
                $line = sprintf('<%s>%s</>', $style, $line);
            }
        }

        return $lines;
    }
}
PKϤ$Z\q%;'console/EventListener/ErrorListener.phpnu�[���<?php

/*
 * This file is part of the Symfony package.
 *
 * (c) Fabien Potencier <fabien@symfony.com>
 *
 * For the full copyright and license information, please view the LICENSE
 * file that was distributed with this source code.
 */

namespace Symfony\Component\Console\EventListener;

use Psr\Log\LoggerInterface;
use Symfony\Component\Console\ConsoleEvents;
use Symfony\Component\Console\Event\ConsoleErrorEvent;
use Symfony\Component\Console\Event\ConsoleEvent;
use Symfony\Component\Console\Event\ConsoleTerminateEvent;
use Symfony\Component\EventDispatcher\EventSubscriberInterface;

/**
 * @author James Halsall <james.t.halsall@googlemail.com>
 * @author Robin Chalas <robin.chalas@gmail.com>
 */
class ErrorListener implements EventSubscriberInterface
{
    private $logger;

    public function __construct(LoggerInterface $logger = null)
    {
        $this->logger = $logger;
    }

    public function onConsoleError(ConsoleErrorEvent $event)
    {
        if (null === $this->logger) {
            return;
        }

        $error = $event->getError();

        if (!$inputString = $this->getInputString($event)) {
            $this->logger->critical('An error occurred while using the console. Message: "{message}"', ['exception' => $error, 'message' => $error->getMessage()]);

            return;
        }

        $this->logger->critical('Error thrown while running command "{command}". Message: "{message}"', ['exception' => $error, 'command' => $inputString, 'message' => $error->getMessage()]);
    }

    public function onConsoleTerminate(ConsoleTerminateEvent $event)
    {
        if (null === $this->logger) {
            return;
        }

        $exitCode = $event->getExitCode();

        if (0 === $exitCode) {
            return;
        }

        if (!$inputString = $this->getInputString($event)) {
            $this->logger->debug('The console exited with code "{code}"', ['code' => $exitCode]);

            return;
        }

        $this->logger->debug('Command "{command}" exited with code "{code}"', ['command' => $inputString, 'code' => $exitCode]);
    }

    public static function getSubscribedEvents()
    {
        return [
            ConsoleEvents::ERROR => ['onConsoleError', -128],
            ConsoleEvents::TERMINATE => ['onConsoleTerminate', -128],
        ];
    }

    private static function getInputString(ConsoleEvent $event): ?string
    {
        $commandName = $event->getCommand() ? $event->getCommand()->getName() : null;
        $input = $event->getInput();

        if (method_exists($input, '__toString')) {
            if ($commandName) {
                return str_replace(["'$commandName'", "\"$commandName\""], $commandName, (string) $input);
            }

            return (string) $input;
        }

        return $commandName;
    }
}
PKϤ$Z*<�!��console/Color.phpnu�[���<?php

/*
 * This file is part of the Symfony package.
 *
 * (c) Fabien Potencier <fabien@symfony.com>
 *
 * For the full copyright and license information, please view the LICENSE
 * file that was distributed with this source code.
 */

namespace Symfony\Component\Console;

use Symfony\Component\Console\Exception\InvalidArgumentException;

/**
 * @author Fabien Potencier <fabien@symfony.com>
 */
final class Color
{
    private const COLORS = [
        'black' => 0,
        'red' => 1,
        'green' => 2,
        'yellow' => 3,
        'blue' => 4,
        'magenta' => 5,
        'cyan' => 6,
        'white' => 7,
        'default' => 9,
    ];

    private const BRIGHT_COLORS = [
        'gray' => 0,
        'bright-red' => 1,
        'bright-green' => 2,
        'bright-yellow' => 3,
        'bright-blue' => 4,
        'bright-magenta' => 5,
        'bright-cyan' => 6,
        'bright-white' => 7,
    ];

    private const AVAILABLE_OPTIONS = [
        'bold' => ['set' => 1, 'unset' => 22],
        'underscore' => ['set' => 4, 'unset' => 24],
        'blink' => ['set' => 5, 'unset' => 25],
        'reverse' => ['set' => 7, 'unset' => 27],
        'conceal' => ['set' => 8, 'unset' => 28],
    ];

    private $foreground;
    private $background;
    private $options = [];

    public function __construct(string $foreground = '', string $background = '', array $options = [])
    {
        $this->foreground = $this->parseColor($foreground);
        $this->background = $this->parseColor($background, true);

        foreach ($options as $option) {
            if (!isset(self::AVAILABLE_OPTIONS[$option])) {
                throw new InvalidArgumentException(sprintf('Invalid option specified: "%s". Expected one of (%s).', $option, implode(', ', array_keys(self::AVAILABLE_OPTIONS))));
            }

            $this->options[$option] = self::AVAILABLE_OPTIONS[$option];
        }
    }

    public function apply(string $text): string
    {
        return $this->set().$text.$this->unset();
    }

    public function set(): string
    {
        $setCodes = [];
        if ('' !== $this->foreground) {
            $setCodes[] = $this->foreground;
        }
        if ('' !== $this->background) {
            $setCodes[] = $this->background;
        }
        foreach ($this->options as $option) {
            $setCodes[] = $option['set'];
        }
        if (0 === \count($setCodes)) {
            return '';
        }

        return sprintf("\033[%sm", implode(';', $setCodes));
    }

    public function unset(): string
    {
        $unsetCodes = [];
        if ('' !== $this->foreground) {
            $unsetCodes[] = 39;
        }
        if ('' !== $this->background) {
            $unsetCodes[] = 49;
        }
        foreach ($this->options as $option) {
            $unsetCodes[] = $option['unset'];
        }
        if (0 === \count($unsetCodes)) {
            return '';
        }

        return sprintf("\033[%sm", implode(';', $unsetCodes));
    }

    private function parseColor(string $color, bool $background = false): string
    {
        if ('' === $color) {
            return '';
        }

        if ('#' === $color[0]) {
            $color = substr($color, 1);

            if (3 === \strlen($color)) {
                $color = $color[0].$color[0].$color[1].$color[1].$color[2].$color[2];
            }

            if (6 !== \strlen($color)) {
                throw new InvalidArgumentException(sprintf('Invalid "%s" color.', $color));
            }

            return ($background ? '4' : '3').$this->convertHexColorToAnsi(hexdec($color));
        }

        if (isset(self::COLORS[$color])) {
            return ($background ? '4' : '3').self::COLORS[$color];
        }

        if (isset(self::BRIGHT_COLORS[$color])) {
            return ($background ? '10' : '9').self::BRIGHT_COLORS[$color];
        }

        throw new InvalidArgumentException(sprintf('Invalid "%s" color; expected one of (%s).', $color, implode(', ', array_merge(array_keys(self::COLORS), array_keys(self::BRIGHT_COLORS)))));
    }

    private function convertHexColorToAnsi(int $color): string
    {
        $r = ($color >> 16) & 255;
        $g = ($color >> 8) & 255;
        $b = $color & 255;

        // see https://github.com/termstandard/colors/ for more information about true color support
        if ('truecolor' !== getenv('COLORTERM')) {
            return (string) $this->degradeHexColorToAnsi($r, $g, $b);
        }

        return sprintf('8;2;%d;%d;%d', $r, $g, $b);
    }

    private function degradeHexColorToAnsi(int $r, int $g, int $b): int
    {
        if (0 === round($this->getSaturation($r, $g, $b) / 50)) {
            return 0;
        }

        return (round($b / 255) << 2) | (round($g / 255) << 1) | round($r / 255);
    }

    private function getSaturation(int $r, int $g, int $b): int
    {
        $r = $r / 255;
        $g = $g / 255;
        $b = $b / 255;
        $v = max($r, $g, $b);

        if (0 === $diff = $v - min($r, $g, $b)) {
            return 0;
        }

        return (int) $diff * 100 / $v;
    }
}
PKϤ$Z��0w��0console/CommandLoader/ContainerCommandLoader.phpnu�[���<?php

/*
 * This file is part of the Symfony package.
 *
 * (c) Fabien Potencier <fabien@symfony.com>
 *
 * For the full copyright and license information, please view the LICENSE
 * file that was distributed with this source code.
 */

namespace Symfony\Component\Console\CommandLoader;

use Psr\Container\ContainerInterface;
use Symfony\Component\Console\Exception\CommandNotFoundException;

/**
 * Loads commands from a PSR-11 container.
 *
 * @author Robin Chalas <robin.chalas@gmail.com>
 */
class ContainerCommandLoader implements CommandLoaderInterface
{
    private $container;
    private $commandMap;

    /**
     * @param array $commandMap An array with command names as keys and service ids as values
     */
    public function __construct(ContainerInterface $container, array $commandMap)
    {
        $this->container = $container;
        $this->commandMap = $commandMap;
    }

    /**
     * {@inheritdoc}
     */
    public function get(string $name)
    {
        if (!$this->has($name)) {
            throw new CommandNotFoundException(sprintf('Command "%s" does not exist.', $name));
        }

        return $this->container->get($this->commandMap[$name]);
    }

    /**
     * {@inheritdoc}
     */
    public function has(string $name)
    {
        return isset($this->commandMap[$name]) && $this->container->has($this->commandMap[$name]);
    }

    /**
     * {@inheritdoc}
     */
    public function getNames()
    {
        return array_keys($this->commandMap);
    }
}
PKϤ$Z=H��EE.console/CommandLoader/FactoryCommandLoader.phpnu�[���<?php

/*
 * This file is part of the Symfony package.
 *
 * (c) Fabien Potencier <fabien@symfony.com>
 *
 * For the full copyright and license information, please view the LICENSE
 * file that was distributed with this source code.
 */

namespace Symfony\Component\Console\CommandLoader;

use Symfony\Component\Console\Exception\CommandNotFoundException;

/**
 * A simple command loader using factories to instantiate commands lazily.
 *
 * @author Maxime Steinhausser <maxime.steinhausser@gmail.com>
 */
class FactoryCommandLoader implements CommandLoaderInterface
{
    private $factories;

    /**
     * @param callable[] $factories Indexed by command names
     */
    public function __construct(array $factories)
    {
        $this->factories = $factories;
    }

    /**
     * {@inheritdoc}
     */
    public function has(string $name)
    {
        return isset($this->factories[$name]);
    }

    /**
     * {@inheritdoc}
     */
    public function get(string $name)
    {
        if (!isset($this->factories[$name])) {
            throw new CommandNotFoundException(sprintf('Command "%s" does not exist.', $name));
        }

        $factory = $this->factories[$name];

        return $factory();
    }

    /**
     * {@inheritdoc}
     */
    public function getNames()
    {
        return array_keys($this->factories);
    }
}
PKϤ$Z��d5MM0console/CommandLoader/CommandLoaderInterface.phpnu�[���<?php

/*
 * This file is part of the Symfony package.
 *
 * (c) Fabien Potencier <fabien@symfony.com>
 *
 * For the full copyright and license information, please view the LICENSE
 * file that was distributed with this source code.
 */

namespace Symfony\Component\Console\CommandLoader;

use Symfony\Component\Console\Command\Command;
use Symfony\Component\Console\Exception\CommandNotFoundException;

/**
 * @author Robin Chalas <robin.chalas@gmail.com>
 */
interface CommandLoaderInterface
{
    /**
     * Loads a command.
     *
     * @return Command
     *
     * @throws CommandNotFoundException
     */
    public function get(string $name);

    /**
     * Checks if a command exists.
     *
     * @return bool
     */
    public function has(string $name);

    /**
     * @return string[]
     */
    public function getNames();
}
PKϤ$ZZ$FBBconsole/Command/ListCommand.phpnu�[���<?php

/*
 * This file is part of the Symfony package.
 *
 * (c) Fabien Potencier <fabien@symfony.com>
 *
 * For the full copyright and license information, please view the LICENSE
 * file that was distributed with this source code.
 */

namespace Symfony\Component\Console\Command;

use Symfony\Component\Console\Completion\CompletionInput;
use Symfony\Component\Console\Completion\CompletionSuggestions;
use Symfony\Component\Console\Descriptor\ApplicationDescription;
use Symfony\Component\Console\Helper\DescriptorHelper;
use Symfony\Component\Console\Input\InputArgument;
use Symfony\Component\Console\Input\InputInterface;
use Symfony\Component\Console\Input\InputOption;
use Symfony\Component\Console\Output\OutputInterface;

/**
 * ListCommand displays the list of all available commands for the application.
 *
 * @author Fabien Potencier <fabien@symfony.com>
 */
class ListCommand extends Command
{
    /**
     * {@inheritdoc}
     */
    protected function configure()
    {
        $this
            ->setName('list')
            ->setDefinition([
                new InputArgument('namespace', InputArgument::OPTIONAL, 'The namespace name'),
                new InputOption('raw', null, InputOption::VALUE_NONE, 'To output raw command list'),
                new InputOption('format', null, InputOption::VALUE_REQUIRED, 'The output format (txt, xml, json, or md)', 'txt'),
                new InputOption('short', null, InputOption::VALUE_NONE, 'To skip describing commands\' arguments'),
            ])
            ->setDescription('List commands')
            ->setHelp(<<<'EOF'
The <info>%command.name%</info> command lists all commands:

  <info>%command.full_name%</info>

You can also display the commands for a specific namespace:

  <info>%command.full_name% test</info>

You can also output the information in other formats by using the <comment>--format</comment> option:

  <info>%command.full_name% --format=xml</info>

It's also possible to get raw list of commands (useful for embedding command runner):

  <info>%command.full_name% --raw</info>
EOF
            )
        ;
    }

    /**
     * {@inheritdoc}
     */
    protected function execute(InputInterface $input, OutputInterface $output)
    {
        $helper = new DescriptorHelper();
        $helper->describe($output, $this->getApplication(), [
            'format' => $input->getOption('format'),
            'raw_text' => $input->getOption('raw'),
            'namespace' => $input->getArgument('namespace'),
            'short' => $input->getOption('short'),
        ]);

        return 0;
    }

    public function complete(CompletionInput $input, CompletionSuggestions $suggestions): void
    {
        if ($input->mustSuggestArgumentValuesFor('namespace')) {
            $descriptor = new ApplicationDescription($this->getApplication());
            $suggestions->suggestValues(array_keys($descriptor->getNamespaces()));

            return;
        }

        if ($input->mustSuggestOptionValuesFor('format')) {
            $helper = new DescriptorHelper();
            $suggestions->suggestValues($helper->getFormats());
        }
    }
}
PKϤ$Z���n!n!#console/Command/CompleteCommand.phpnu�[���<?php

/*
 * This file is part of the Symfony package.
 *
 * (c) Fabien Potencier <fabien@symfony.com>
 *
 * For the full copyright and license information, please view the LICENSE
 * file that was distributed with this source code.
 */

namespace Symfony\Component\Console\Command;

use Symfony\Component\Console\Completion\CompletionInput;
use Symfony\Component\Console\Completion\CompletionSuggestions;
use Symfony\Component\Console\Completion\Output\BashCompletionOutput;
use Symfony\Component\Console\Completion\Output\CompletionOutputInterface;
use Symfony\Component\Console\Exception\CommandNotFoundException;
use Symfony\Component\Console\Exception\ExceptionInterface;
use Symfony\Component\Console\Input\InputInterface;
use Symfony\Component\Console\Input\InputOption;
use Symfony\Component\Console\Output\OutputInterface;

/**
 * Responsible for providing the values to the shell completion.
 *
 * @author Wouter de Jong <wouter@wouterj.nl>
 */
final class CompleteCommand extends Command
{
    protected static $defaultName = '|_complete';
    protected static $defaultDescription = 'Internal command to provide shell completion suggestions';

    private $completionOutputs;

    private $isDebug = false;

    /**
     * @param array<string, class-string<CompletionOutputInterface>> $completionOutputs A list of additional completion outputs, with shell name as key and FQCN as value
     */
    public function __construct(array $completionOutputs = [])
    {
        // must be set before the parent constructor, as the property value is used in configure()
        $this->completionOutputs = $completionOutputs + ['bash' => BashCompletionOutput::class];

        parent::__construct();
    }

    protected function configure(): void
    {
        $this
            ->addOption('shell', 's', InputOption::VALUE_REQUIRED, 'The shell type ("'.implode('", "', array_keys($this->completionOutputs)).'")')
            ->addOption('input', 'i', InputOption::VALUE_REQUIRED | InputOption::VALUE_IS_ARRAY, 'An array of input tokens (e.g. COMP_WORDS or argv)')
            ->addOption('current', 'c', InputOption::VALUE_REQUIRED, 'The index of the "input" array that the cursor is in (e.g. COMP_CWORD)')
            ->addOption('symfony', 'S', InputOption::VALUE_REQUIRED, 'The version of the completion script')
        ;
    }

    protected function initialize(InputInterface $input, OutputInterface $output)
    {
        $this->isDebug = filter_var(getenv('SYMFONY_COMPLETION_DEBUG'), \FILTER_VALIDATE_BOOLEAN);
    }

    protected function execute(InputInterface $input, OutputInterface $output): int
    {
        try {
            // uncomment when a bugfix or BC break has been introduced in the shell completion scripts
            // $version = $input->getOption('symfony');
            // if ($version && version_compare($version, 'x.y', '>=')) {
            //    $message = sprintf('Completion script version is not supported ("%s" given, ">=x.y" required).', $version);
            //    $this->log($message);

            //    $output->writeln($message.' Install the Symfony completion script again by using the "completion" command.');

            //    return 126;
            // }

            $shell = $input->getOption('shell');
            if (!$shell) {
                throw new \RuntimeException('The "--shell" option must be set.');
            }

            if (!$completionOutput = $this->completionOutputs[$shell] ?? false) {
                throw new \RuntimeException(sprintf('Shell completion is not supported for your shell: "%s" (supported: "%s").', $shell, implode('", "', array_keys($this->completionOutputs))));
            }

            $completionInput = $this->createCompletionInput($input);
            $suggestions = new CompletionSuggestions();

            $this->log([
                '',
                '<comment>'.date('Y-m-d H:i:s').'</>',
                '<info>Input:</> <comment>("|" indicates the cursor position)</>',
                '  '.(string) $completionInput,
                '<info>Command:</>',
                '  '.(string) implode(' ', $_SERVER['argv']),
                '<info>Messages:</>',
            ]);

            $command = $this->findCommand($completionInput, $output);
            if (null === $command) {
                $this->log('  No command found, completing using the Application class.');

                $this->getApplication()->complete($completionInput, $suggestions);
            } elseif (
                $completionInput->mustSuggestArgumentValuesFor('command')
                && $command->getName() !== $completionInput->getCompletionValue()
                && !\in_array($completionInput->getCompletionValue(), $command->getAliases(), true)
            ) {
                $this->log('  No command found, completing using the Application class.');

                // expand shortcut names ("cache:cl<TAB>") into their full name ("cache:clear")
                $suggestions->suggestValues(array_filter(array_merge([$command->getName()], $command->getAliases())));
            } else {
                $command->mergeApplicationDefinition();
                $completionInput->bind($command->getDefinition());

                if (CompletionInput::TYPE_OPTION_NAME === $completionInput->getCompletionType()) {
                    $this->log('  Completing option names for the <comment>'.\get_class($command instanceof LazyCommand ? $command->getCommand() : $command).'</> command.');

                    $suggestions->suggestOptions($command->getDefinition()->getOptions());
                } else {
                    $this->log([
                        '  Completing using the <comment>'.\get_class($command instanceof LazyCommand ? $command->getCommand() : $command).'</> class.',
                        '  Completing <comment>'.$completionInput->getCompletionType().'</> for <comment>'.$completionInput->getCompletionName().'</>',
                    ]);
                    if (null !== $compval = $completionInput->getCompletionValue()) {
                        $this->log('  Current value: <comment>'.$compval.'</>');
                    }

                    $command->complete($completionInput, $suggestions);
                }
            }

            /** @var CompletionOutputInterface $completionOutput */
            $completionOutput = new $completionOutput();

            $this->log('<info>Suggestions:</>');
            if ($options = $suggestions->getOptionSuggestions()) {
                $this->log('  --'.implode(' --', array_map(function ($o) { return $o->getName(); }, $options)));
            } elseif ($values = $suggestions->getValueSuggestions()) {
                $this->log('  '.implode(' ', $values));
            } else {
                $this->log('  <comment>No suggestions were provided</>');
            }

            $completionOutput->write($suggestions, $output);
        } catch (\Throwable $e) {
            $this->log([
                '<error>Error!</error>',
                (string) $e,
            ]);

            if ($output->isDebug()) {
                throw $e;
            }

            return self::FAILURE;
        }

        return self::SUCCESS;
    }

    private function createCompletionInput(InputInterface $input): CompletionInput
    {
        $currentIndex = $input->getOption('current');
        if (!$currentIndex || !ctype_digit($currentIndex)) {
            throw new \RuntimeException('The "--current" option must be set and it must be an integer.');
        }

        $completionInput = CompletionInput::fromTokens($input->getOption('input'), (int) $currentIndex);

        try {
            $completionInput->bind($this->getApplication()->getDefinition());
        } catch (ExceptionInterface $e) {
        }

        return $completionInput;
    }

    private function findCommand(CompletionInput $completionInput, OutputInterface $output): ?Command
    {
        try {
            $inputName = $completionInput->getFirstArgument();
            if (null === $inputName) {
                return null;
            }

            return $this->getApplication()->find($inputName);
        } catch (CommandNotFoundException $e) {
        }

        return null;
    }

    private function log($messages): void
    {
        if (!$this->isDebug) {
            return;
        }

        $commandName = basename($_SERVER['argv'][0]);
        file_put_contents(sys_get_temp_dir().'/sf_'.$commandName.'.log', implode(\PHP_EOL, (array) $messages).\PHP_EOL, \FILE_APPEND);
    }
}
PKϤ$Z��͚((console/Command/HelpCommand.phpnu�[���<?php

/*
 * This file is part of the Symfony package.
 *
 * (c) Fabien Potencier <fabien@symfony.com>
 *
 * For the full copyright and license information, please view the LICENSE
 * file that was distributed with this source code.
 */

namespace Symfony\Component\Console\Command;

use Symfony\Component\Console\Completion\CompletionInput;
use Symfony\Component\Console\Completion\CompletionSuggestions;
use Symfony\Component\Console\Descriptor\ApplicationDescription;
use Symfony\Component\Console\Helper\DescriptorHelper;
use Symfony\Component\Console\Input\InputArgument;
use Symfony\Component\Console\Input\InputInterface;
use Symfony\Component\Console\Input\InputOption;
use Symfony\Component\Console\Output\OutputInterface;

/**
 * HelpCommand displays the help for a given command.
 *
 * @author Fabien Potencier <fabien@symfony.com>
 */
class HelpCommand extends Command
{
    private $command;

    /**
     * {@inheritdoc}
     */
    protected function configure()
    {
        $this->ignoreValidationErrors();

        $this
            ->setName('help')
            ->setDefinition([
                new InputArgument('command_name', InputArgument::OPTIONAL, 'The command name', 'help'),
                new InputOption('format', null, InputOption::VALUE_REQUIRED, 'The output format (txt, xml, json, or md)', 'txt'),
                new InputOption('raw', null, InputOption::VALUE_NONE, 'To output raw command help'),
            ])
            ->setDescription('Display help for a command')
            ->setHelp(<<<'EOF'
The <info>%command.name%</info> command displays help for a given command:

  <info>%command.full_name% list</info>

You can also output the help in other formats by using the <comment>--format</comment> option:

  <info>%command.full_name% --format=xml list</info>

To display the list of available commands, please use the <info>list</info> command.
EOF
            )
        ;
    }

    public function setCommand(Command $command)
    {
        $this->command = $command;
    }

    /**
     * {@inheritdoc}
     */
    protected function execute(InputInterface $input, OutputInterface $output)
    {
        if (null === $this->command) {
            $this->command = $this->getApplication()->find($input->getArgument('command_name'));
        }

        $helper = new DescriptorHelper();
        $helper->describe($output, $this->command, [
            'format' => $input->getOption('format'),
            'raw_text' => $input->getOption('raw'),
        ]);

        $this->command = null;

        return 0;
    }

    public function complete(CompletionInput $input, CompletionSuggestions $suggestions): void
    {
        if ($input->mustSuggestArgumentValuesFor('command_name')) {
            $descriptor = new ApplicationDescription($this->getApplication());
            $suggestions->suggestValues(array_keys($descriptor->getCommands()));

            return;
        }

        if ($input->mustSuggestOptionValuesFor('format')) {
            $helper = new DescriptorHelper();
            $suggestions->suggestValues($helper->getFormats());
        }
    }
}
PKϤ$ZGe�M��.console/Command/SignalableCommandInterface.phpnu�[���<?php

/*
 * This file is part of the Symfony package.
 *
 * (c) Fabien Potencier <fabien@symfony.com>
 *
 * For the full copyright and license information, please view the LICENSE
 * file that was distributed with this source code.
 */

namespace Symfony\Component\Console\Command;

/**
 * Interface for command reacting to signal.
 *
 * @author Grégoire Pineau <lyrixx@lyrix.info>
 */
interface SignalableCommandInterface
{
    /**
     * Returns the list of signals to subscribe.
     */
    public function getSubscribedSignals(): array;

    /**
     * The method will be called when the application is signaled.
     */
    public function handleSignal(int $signal): void;
}
PKϤ$Z�?���!console/Command/LockableTrait.phpnu�[���<?php

/*
 * This file is part of the Symfony package.
 *
 * (c) Fabien Potencier <fabien@symfony.com>
 *
 * For the full copyright and license information, please view the LICENSE
 * file that was distributed with this source code.
 */

namespace Symfony\Component\Console\Command;

use Symfony\Component\Console\Exception\LogicException;
use Symfony\Component\Lock\LockFactory;
use Symfony\Component\Lock\LockInterface;
use Symfony\Component\Lock\Store\FlockStore;
use Symfony\Component\Lock\Store\SemaphoreStore;

/**
 * Basic lock feature for commands.
 *
 * @author Geoffrey Brier <geoffrey.brier@gmail.com>
 */
trait LockableTrait
{
    /** @var LockInterface|null */
    private $lock;

    /**
     * Locks a command.
     */
    private function lock(string $name = null, bool $blocking = false): bool
    {
        if (!class_exists(SemaphoreStore::class)) {
            throw new LogicException('To enable the locking feature you must install the symfony/lock component.');
        }

        if (null !== $this->lock) {
            throw new LogicException('A lock is already in place.');
        }

        if (SemaphoreStore::isSupported()) {
            $store = new SemaphoreStore();
        } else {
            $store = new FlockStore();
        }

        $this->lock = (new LockFactory($store))->createLock($name ?: $this->getName());
        if (!$this->lock->acquire($blocking)) {
            $this->lock = null;

            return false;
        }

        return true;
    }

    /**
     * Releases the command lock if there is one.
     */
    private function release()
    {
        if ($this->lock) {
            $this->lock->release();
            $this->lock = null;
        }
    }
}
PKϤ$Z�:���)console/Command/DumpCompletionCommand.phpnu�[���<?php

/*
 * This file is part of the Symfony package.
 *
 * (c) Fabien Potencier <fabien@symfony.com>
 *
 * For the full copyright and license information, please view the LICENSE
 * file that was distributed with this source code.
 */

namespace Symfony\Component\Console\Command;

use Symfony\Component\Console\Completion\CompletionInput;
use Symfony\Component\Console\Completion\CompletionSuggestions;
use Symfony\Component\Console\Input\InputArgument;
use Symfony\Component\Console\Input\InputInterface;
use Symfony\Component\Console\Input\InputOption;
use Symfony\Component\Console\Output\ConsoleOutputInterface;
use Symfony\Component\Console\Output\OutputInterface;
use Symfony\Component\Process\Process;

/**
 * Dumps the completion script for the current shell.
 *
 * @author Wouter de Jong <wouter@wouterj.nl>
 */
final class DumpCompletionCommand extends Command
{
    protected static $defaultName = 'completion';
    protected static $defaultDescription = 'Dump the shell completion script';

    public function complete(CompletionInput $input, CompletionSuggestions $suggestions): void
    {
        if ($input->mustSuggestArgumentValuesFor('shell')) {
            $suggestions->suggestValues($this->getSupportedShells());
        }
    }

    protected function configure()
    {
        $fullCommand = $_SERVER['PHP_SELF'];
        $commandName = basename($fullCommand);
        $fullCommand = @realpath($fullCommand) ?: $fullCommand;

        $this
            ->setHelp(<<<EOH
The <info>%command.name%</> command dumps the shell completion script required
to use shell autocompletion (currently only bash completion is supported).

<comment>Static installation
-------------------</>

Dump the script to a global completion file and restart your shell:

    <info>%command.full_name% bash | sudo tee /etc/bash_completion.d/{$commandName}</>

Or dump the script to a local file and source it:

    <info>%command.full_name% bash > completion.sh</>

    <comment># source the file whenever you use the project</>
    <info>source completion.sh</>

    <comment># or add this line at the end of your "~/.bashrc" file:</>
    <info>source /path/to/completion.sh</>

<comment>Dynamic installation
--------------------</>

Add this to the end of your shell configuration file (e.g. <info>"~/.bashrc"</>):

    <info>eval "$({$fullCommand} completion bash)"</>
EOH
            )
            ->addArgument('shell', InputArgument::OPTIONAL, 'The shell type (e.g. "bash"), the value of the "$SHELL" env var will be used if this is not given')
            ->addOption('debug', null, InputOption::VALUE_NONE, 'Tail the completion debug log')
        ;
    }

    protected function execute(InputInterface $input, OutputInterface $output): int
    {
        $commandName = basename($_SERVER['argv'][0]);

        if ($input->getOption('debug')) {
            $this->tailDebugLog($commandName, $output);

            return self::SUCCESS;
        }

        $shell = $input->getArgument('shell') ?? self::guessShell();
        $completionFile = __DIR__.'/../Resources/completion.'.$shell;
        if (!file_exists($completionFile)) {
            $supportedShells = $this->getSupportedShells();

            ($output instanceof ConsoleOutputInterface ? $output->getErrorOutput() : $output)
                ->writeln(sprintf('<error>Detected shell "%s", which is not supported by Symfony shell completion (supported shells: "%s").</>', $shell, implode('", "', $supportedShells)));

            return self::INVALID;
        }

        $output->write(str_replace(['{{ COMMAND_NAME }}', '{{ VERSION }}'], [$commandName, $this->getApplication()->getVersion()], file_get_contents($completionFile)));

        return self::SUCCESS;
    }

    private static function guessShell(): string
    {
        return basename($_SERVER['SHELL'] ?? '');
    }

    private function tailDebugLog(string $commandName, OutputInterface $output): void
    {
        $debugFile = sys_get_temp_dir().'/sf_'.$commandName.'.log';
        if (!file_exists($debugFile)) {
            touch($debugFile);
        }
        $process = new Process(['tail', '-f', $debugFile], null, null, null, 0);
        $process->run(function (string $type, string $line) use ($output): void {
            $output->write($line);
        });
    }

    /**
     * @return string[]
     */
    private function getSupportedShells(): array
    {
        return array_map(function ($f) {
            return pathinfo($f, \PATHINFO_EXTENSION);
        }, glob(__DIR__.'/../Resources/completion.*'));
    }
}
PKϤ$Z�?��		console/Command/LazyCommand.phpnu�[���<?php

/*
 * This file is part of the Symfony package.
 *
 * (c) Fabien Potencier <fabien@symfony.com>
 *
 * For the full copyright and license information, please view the LICENSE
 * file that was distributed with this source code.
 */

namespace Symfony\Component\Console\Command;

use Symfony\Component\Console\Application;
use Symfony\Component\Console\Completion\CompletionInput;
use Symfony\Component\Console\Completion\CompletionSuggestions;
use Symfony\Component\Console\Helper\HelperSet;
use Symfony\Component\Console\Input\InputDefinition;
use Symfony\Component\Console\Input\InputInterface;
use Symfony\Component\Console\Output\OutputInterface;

/**
 * @author Nicolas Grekas <p@tchwork.com>
 */
final class LazyCommand extends Command
{
    private $command;
    private $isEnabled;

    public function __construct(string $name, array $aliases, string $description, bool $isHidden, \Closure $commandFactory, ?bool $isEnabled = true)
    {
        $this->setName($name)
            ->setAliases($aliases)
            ->setHidden($isHidden)
            ->setDescription($description);

        $this->command = $commandFactory;
        $this->isEnabled = $isEnabled;
    }

    public function ignoreValidationErrors(): void
    {
        $this->getCommand()->ignoreValidationErrors();
    }

    public function setApplication(Application $application = null): void
    {
        if ($this->command instanceof parent) {
            $this->command->setApplication($application);
        }

        parent::setApplication($application);
    }

    public function setHelperSet(HelperSet $helperSet): void
    {
        if ($this->command instanceof parent) {
            $this->command->setHelperSet($helperSet);
        }

        parent::setHelperSet($helperSet);
    }

    public function isEnabled(): bool
    {
        return $this->isEnabled ?? $this->getCommand()->isEnabled();
    }

    public function run(InputInterface $input, OutputInterface $output): int
    {
        return $this->getCommand()->run($input, $output);
    }

    public function complete(CompletionInput $input, CompletionSuggestions $suggestions): void
    {
        $this->getCommand()->complete($input, $suggestions);
    }

    /**
     * @return $this
     */
    public function setCode(callable $code): self
    {
        $this->getCommand()->setCode($code);

        return $this;
    }

    /**
     * @internal
     */
    public function mergeApplicationDefinition(bool $mergeArgs = true): void
    {
        $this->getCommand()->mergeApplicationDefinition($mergeArgs);
    }

    /**
     * @return $this
     */
    public function setDefinition($definition): self
    {
        $this->getCommand()->setDefinition($definition);

        return $this;
    }

    public function getDefinition(): InputDefinition
    {
        return $this->getCommand()->getDefinition();
    }

    public function getNativeDefinition(): InputDefinition
    {
        return $this->getCommand()->getNativeDefinition();
    }

    /**
     * @return $this
     */
    public function addArgument(string $name, int $mode = null, string $description = '', $default = null): self
    {
        $this->getCommand()->addArgument($name, $mode, $description, $default);

        return $this;
    }

    /**
     * @return $this
     */
    public function addOption(string $name, $shortcut = null, int $mode = null, string $description = '', $default = null): self
    {
        $this->getCommand()->addOption($name, $shortcut, $mode, $description, $default);

        return $this;
    }

    /**
     * @return $this
     */
    public function setProcessTitle(string $title): self
    {
        $this->getCommand()->setProcessTitle($title);

        return $this;
    }

    /**
     * @return $this
     */
    public function setHelp(string $help): self
    {
        $this->getCommand()->setHelp($help);

        return $this;
    }

    public function getHelp(): string
    {
        return $this->getCommand()->getHelp();
    }

    public function getProcessedHelp(): string
    {
        return $this->getCommand()->getProcessedHelp();
    }

    public function getSynopsis(bool $short = false): string
    {
        return $this->getCommand()->getSynopsis($short);
    }

    /**
     * @return $this
     */
    public function addUsage(string $usage): self
    {
        $this->getCommand()->addUsage($usage);

        return $this;
    }

    public function getUsages(): array
    {
        return $this->getCommand()->getUsages();
    }

    /**
     * @return mixed
     */
    public function getHelper(string $name)
    {
        return $this->getCommand()->getHelper($name);
    }

    public function getCommand(): parent
    {
        if (!$this->command instanceof \Closure) {
            return $this->command;
        }

        $command = $this->command = ($this->command)();
        $command->setApplication($this->getApplication());

        if (null !== $this->getHelperSet()) {
            $command->setHelperSet($this->getHelperSet());
        }

        $command->setName($this->getName())
            ->setAliases($this->getAliases())
            ->setHidden($this->isHidden())
            ->setDescription($this->getDescription());

        // Will throw if the command is not correctly initialized.
        $command->getDefinition();

        return $command;
    }
}
PKϤ$Zڽ�WPPconsole/Command/Command.phpnu�[���<?php

/*
 * This file is part of the Symfony package.
 *
 * (c) Fabien Potencier <fabien@symfony.com>
 *
 * For the full copyright and license information, please view the LICENSE
 * file that was distributed with this source code.
 */

namespace Symfony\Component\Console\Command;

use Symfony\Component\Console\Application;
use Symfony\Component\Console\Attribute\AsCommand;
use Symfony\Component\Console\Completion\CompletionInput;
use Symfony\Component\Console\Completion\CompletionSuggestions;
use Symfony\Component\Console\Exception\ExceptionInterface;
use Symfony\Component\Console\Exception\InvalidArgumentException;
use Symfony\Component\Console\Exception\LogicException;
use Symfony\Component\Console\Helper\HelperSet;
use Symfony\Component\Console\Input\InputArgument;
use Symfony\Component\Console\Input\InputDefinition;
use Symfony\Component\Console\Input\InputInterface;
use Symfony\Component\Console\Input\InputOption;
use Symfony\Component\Console\Output\OutputInterface;

/**
 * Base class for all commands.
 *
 * @author Fabien Potencier <fabien@symfony.com>
 */
class Command
{
    // see https://tldp.org/LDP/abs/html/exitcodes.html
    public const SUCCESS = 0;
    public const FAILURE = 1;
    public const INVALID = 2;

    /**
     * @var string|null The default command name
     */
    protected static $defaultName;

    /**
     * @var string|null The default command description
     */
    protected static $defaultDescription;

    private $application;
    private $name;
    private $processTitle;
    private $aliases = [];
    private $definition;
    private $hidden = false;
    private $help = '';
    private $description = '';
    private $fullDefinition;
    private $ignoreValidationErrors = false;
    private $code;
    private $synopsis = [];
    private $usages = [];
    private $helperSet;

    /**
     * @return string|null
     */
    public static function getDefaultName()
    {
        $class = static::class;

        if (\PHP_VERSION_ID >= 80000 && $attribute = (new \ReflectionClass($class))->getAttributes(AsCommand::class)) {
            return $attribute[0]->newInstance()->name;
        }

        $r = new \ReflectionProperty($class, 'defaultName');

        return $class === $r->class ? static::$defaultName : null;
    }

    public static function getDefaultDescription(): ?string
    {
        $class = static::class;

        if (\PHP_VERSION_ID >= 80000 && $attribute = (new \ReflectionClass($class))->getAttributes(AsCommand::class)) {
            return $attribute[0]->newInstance()->description;
        }

        $r = new \ReflectionProperty($class, 'defaultDescription');

        return $class === $r->class ? static::$defaultDescription : null;
    }

    /**
     * @param string|null $name The name of the command; passing null means it must be set in configure()
     *
     * @throws LogicException When the command name is empty
     */
    public function __construct(string $name = null)
    {
        $this->definition = new InputDefinition();

        if (null === $name && null !== $name = static::getDefaultName()) {
            $aliases = explode('|', $name);

            if ('' === $name = array_shift($aliases)) {
                $this->setHidden(true);
                $name = array_shift($aliases);
            }

            $this->setAliases($aliases);
        }

        if (null !== $name) {
            $this->setName($name);
        }

        if ('' === $this->description) {
            $this->setDescription(static::getDefaultDescription() ?? '');
        }

        $this->configure();
    }

    /**
     * Ignores validation errors.
     *
     * This is mainly useful for the help command.
     */
    public function ignoreValidationErrors()
    {
        $this->ignoreValidationErrors = true;
    }

    public function setApplication(Application $application = null)
    {
        $this->application = $application;
        if ($application) {
            $this->setHelperSet($application->getHelperSet());
        } else {
            $this->helperSet = null;
        }

        $this->fullDefinition = null;
    }

    public function setHelperSet(HelperSet $helperSet)
    {
        $this->helperSet = $helperSet;
    }

    /**
     * Gets the helper set.
     *
     * @return HelperSet|null
     */
    public function getHelperSet()
    {
        return $this->helperSet;
    }

    /**
     * Gets the application instance for this command.
     *
     * @return Application|null
     */
    public function getApplication()
    {
        return $this->application;
    }

    /**
     * Checks whether the command is enabled or not in the current environment.
     *
     * Override this to check for x or y and return false if the command cannot
     * run properly under the current conditions.
     *
     * @return bool
     */
    public function isEnabled()
    {
        return true;
    }

    /**
     * Configures the current command.
     */
    protected function configure()
    {
    }

    /**
     * Executes the current command.
     *
     * This method is not abstract because you can use this class
     * as a concrete class. In this case, instead of defining the
     * execute() method, you set the code to execute by passing
     * a Closure to the setCode() method.
     *
     * @return int 0 if everything went fine, or an exit code
     *
     * @throws LogicException When this abstract method is not implemented
     *
     * @see setCode()
     */
    protected function execute(InputInterface $input, OutputInterface $output)
    {
        throw new LogicException('You must override the execute() method in the concrete command class.');
    }

    /**
     * Interacts with the user.
     *
     * This method is executed before the InputDefinition is validated.
     * This means that this is the only place where the command can
     * interactively ask for values of missing required arguments.
     */
    protected function interact(InputInterface $input, OutputInterface $output)
    {
    }

    /**
     * Initializes the command after the input has been bound and before the input
     * is validated.
     *
     * This is mainly useful when a lot of commands extends one main command
     * where some things need to be initialized based on the input arguments and options.
     *
     * @see InputInterface::bind()
     * @see InputInterface::validate()
     */
    protected function initialize(InputInterface $input, OutputInterface $output)
    {
    }

    /**
     * Runs the command.
     *
     * The code to execute is either defined directly with the
     * setCode() method or by overriding the execute() method
     * in a sub-class.
     *
     * @return int The command exit code
     *
     * @throws ExceptionInterface When input binding fails. Bypass this by calling {@link ignoreValidationErrors()}.
     *
     * @see setCode()
     * @see execute()
     */
    public function run(InputInterface $input, OutputInterface $output)
    {
        // add the application arguments and options
        $this->mergeApplicationDefinition();

        // bind the input against the command specific arguments/options
        try {
            $input->bind($this->getDefinition());
        } catch (ExceptionInterface $e) {
            if (!$this->ignoreValidationErrors) {
                throw $e;
            }
        }

        $this->initialize($input, $output);

        if (null !== $this->processTitle) {
            if (\function_exists('cli_set_process_title')) {
                if (!@cli_set_process_title($this->processTitle)) {
                    if ('Darwin' === \PHP_OS) {
                        $output->writeln('<comment>Running "cli_set_process_title" as an unprivileged user is not supported on MacOS.</comment>', OutputInterface::VERBOSITY_VERY_VERBOSE);
                    } else {
                        cli_set_process_title($this->processTitle);
                    }
                }
            } elseif (\function_exists('setproctitle')) {
                setproctitle($this->processTitle);
            } elseif (OutputInterface::VERBOSITY_VERY_VERBOSE === $output->getVerbosity()) {
                $output->writeln('<comment>Install the proctitle PECL to be able to change the process title.</comment>');
            }
        }

        if ($input->isInteractive()) {
            $this->interact($input, $output);
        }

        // The command name argument is often omitted when a command is executed directly with its run() method.
        // It would fail the validation if we didn't make sure the command argument is present,
        // since it's required by the application.
        if ($input->hasArgument('command') && null === $input->getArgument('command')) {
            $input->setArgument('command', $this->getName());
        }

        $input->validate();

        if ($this->code) {
            $statusCode = ($this->code)($input, $output);
        } else {
            $statusCode = $this->execute($input, $output);

            if (!\is_int($statusCode)) {
                throw new \TypeError(sprintf('Return value of "%s::execute()" must be of the type int, "%s" returned.', static::class, get_debug_type($statusCode)));
            }
        }

        return is_numeric($statusCode) ? (int) $statusCode : 0;
    }

    /**
     * Adds suggestions to $suggestions for the current completion input (e.g. option or argument).
     */
    public function complete(CompletionInput $input, CompletionSuggestions $suggestions): void
    {
    }

    /**
     * Sets the code to execute when running this command.
     *
     * If this method is used, it overrides the code defined
     * in the execute() method.
     *
     * @param callable $code A callable(InputInterface $input, OutputInterface $output)
     *
     * @return $this
     *
     * @throws InvalidArgumentException
     *
     * @see execute()
     */
    public function setCode(callable $code)
    {
        if ($code instanceof \Closure) {
            $r = new \ReflectionFunction($code);
            if (null === $r->getClosureThis()) {
                set_error_handler(static function () {});
                try {
                    if ($c = \Closure::bind($code, $this)) {
                        $code = $c;
                    }
                } finally {
                    restore_error_handler();
                }
            }
        }

        $this->code = $code;

        return $this;
    }

    /**
     * Merges the application definition with the command definition.
     *
     * This method is not part of public API and should not be used directly.
     *
     * @param bool $mergeArgs Whether to merge or not the Application definition arguments to Command definition arguments
     *
     * @internal
     */
    public function mergeApplicationDefinition(bool $mergeArgs = true)
    {
        if (null === $this->application) {
            return;
        }

        $this->fullDefinition = new InputDefinition();
        $this->fullDefinition->setOptions($this->definition->getOptions());
        $this->fullDefinition->addOptions($this->application->getDefinition()->getOptions());

        if ($mergeArgs) {
            $this->fullDefinition->setArguments($this->application->getDefinition()->getArguments());
            $this->fullDefinition->addArguments($this->definition->getArguments());
        } else {
            $this->fullDefinition->setArguments($this->definition->getArguments());
        }
    }

    /**
     * Sets an array of argument and option instances.
     *
     * @param array|InputDefinition $definition An array of argument and option instances or a definition instance
     *
     * @return $this
     */
    public function setDefinition($definition)
    {
        if ($definition instanceof InputDefinition) {
            $this->definition = $definition;
        } else {
            $this->definition->setDefinition($definition);
        }

        $this->fullDefinition = null;

        return $this;
    }

    /**
     * Gets the InputDefinition attached to this Command.
     *
     * @return InputDefinition
     */
    public function getDefinition()
    {
        return $this->fullDefinition ?? $this->getNativeDefinition();
    }

    /**
     * Gets the InputDefinition to be used to create representations of this Command.
     *
     * Can be overridden to provide the original command representation when it would otherwise
     * be changed by merging with the application InputDefinition.
     *
     * This method is not part of public API and should not be used directly.
     *
     * @return InputDefinition
     */
    public function getNativeDefinition()
    {
        if (null === $this->definition) {
            throw new LogicException(sprintf('Command class "%s" is not correctly initialized. You probably forgot to call the parent constructor.', static::class));
        }

        return $this->definition;
    }

    /**
     * Adds an argument.
     *
     * @param int|null $mode    The argument mode: InputArgument::REQUIRED or InputArgument::OPTIONAL
     * @param mixed    $default The default value (for InputArgument::OPTIONAL mode only)
     *
     * @throws InvalidArgumentException When argument mode is not valid
     *
     * @return $this
     */
    public function addArgument(string $name, int $mode = null, string $description = '', $default = null)
    {
        $this->definition->addArgument(new InputArgument($name, $mode, $description, $default));
        if (null !== $this->fullDefinition) {
            $this->fullDefinition->addArgument(new InputArgument($name, $mode, $description, $default));
        }

        return $this;
    }

    /**
     * Adds an option.
     *
     * @param string|array|null $shortcut The shortcuts, can be null, a string of shortcuts delimited by | or an array of shortcuts
     * @param int|null          $mode     The option mode: One of the InputOption::VALUE_* constants
     * @param mixed             $default  The default value (must be null for InputOption::VALUE_NONE)
     *
     * @throws InvalidArgumentException If option mode is invalid or incompatible
     *
     * @return $this
     */
    public function addOption(string $name, $shortcut = null, int $mode = null, string $description = '', $default = null)
    {
        $this->definition->addOption(new InputOption($name, $shortcut, $mode, $description, $default));
        if (null !== $this->fullDefinition) {
            $this->fullDefinition->addOption(new InputOption($name, $shortcut, $mode, $description, $default));
        }

        return $this;
    }

    /**
     * Sets the name of the command.
     *
     * This method can set both the namespace and the name if
     * you separate them by a colon (:)
     *
     *     $command->setName('foo:bar');
     *
     * @return $this
     *
     * @throws InvalidArgumentException When the name is invalid
     */
    public function setName(string $name)
    {
        $this->validateName($name);

        $this->name = $name;

        return $this;
    }

    /**
     * Sets the process title of the command.
     *
     * This feature should be used only when creating a long process command,
     * like a daemon.
     *
     * @return $this
     */
    public function setProcessTitle(string $title)
    {
        $this->processTitle = $title;

        return $this;
    }

    /**
     * Returns the command name.
     *
     * @return string|null
     */
    public function getName()
    {
        return $this->name;
    }

    /**
     * @param bool $hidden Whether or not the command should be hidden from the list of commands
     *                     The default value will be true in Symfony 6.0
     *
     * @return $this
     *
     * @final since Symfony 5.1
     */
    public function setHidden(bool $hidden /* = true */)
    {
        $this->hidden = $hidden;

        return $this;
    }

    /**
     * @return bool whether the command should be publicly shown or not
     */
    public function isHidden()
    {
        return $this->hidden;
    }

    /**
     * Sets the description for the command.
     *
     * @return $this
     */
    public function setDescription(string $description)
    {
        $this->description = $description;

        return $this;
    }

    /**
     * Returns the description for the command.
     *
     * @return string
     */
    public function getDescription()
    {
        return $this->description;
    }

    /**
     * Sets the help for the command.
     *
     * @return $this
     */
    public function setHelp(string $help)
    {
        $this->help = $help;

        return $this;
    }

    /**
     * Returns the help for the command.
     *
     * @return string
     */
    public function getHelp()
    {
        return $this->help;
    }

    /**
     * Returns the processed help for the command replacing the %command.name% and
     * %command.full_name% patterns with the real values dynamically.
     *
     * @return string
     */
    public function getProcessedHelp()
    {
        $name = $this->name;
        $isSingleCommand = $this->application && $this->application->isSingleCommand();

        $placeholders = [
            '%command.name%',
            '%command.full_name%',
        ];
        $replacements = [
            $name,
            $isSingleCommand ? $_SERVER['PHP_SELF'] : $_SERVER['PHP_SELF'].' '.$name,
        ];

        return str_replace($placeholders, $replacements, $this->getHelp() ?: $this->getDescription());
    }

    /**
     * Sets the aliases for the command.
     *
     * @param string[] $aliases An array of aliases for the command
     *
     * @return $this
     *
     * @throws InvalidArgumentException When an alias is invalid
     */
    public function setAliases(iterable $aliases)
    {
        $list = [];

        foreach ($aliases as $alias) {
            $this->validateName($alias);
            $list[] = $alias;
        }

        $this->aliases = \is_array($aliases) ? $aliases : $list;

        return $this;
    }

    /**
     * Returns the aliases for the command.
     *
     * @return array
     */
    public function getAliases()
    {
        return $this->aliases;
    }

    /**
     * Returns the synopsis for the command.
     *
     * @param bool $short Whether to show the short version of the synopsis (with options folded) or not
     *
     * @return string
     */
    public function getSynopsis(bool $short = false)
    {
        $key = $short ? 'short' : 'long';

        if (!isset($this->synopsis[$key])) {
            $this->synopsis[$key] = trim(sprintf('%s %s', $this->name, $this->definition->getSynopsis($short)));
        }

        return $this->synopsis[$key];
    }

    /**
     * Add a command usage example, it'll be prefixed with the command name.
     *
     * @return $this
     */
    public function addUsage(string $usage)
    {
        if (!str_starts_with($usage, $this->name)) {
            $usage = sprintf('%s %s', $this->name, $usage);
        }

        $this->usages[] = $usage;

        return $this;
    }

    /**
     * Returns alternative usages of the command.
     *
     * @return array
     */
    public function getUsages()
    {
        return $this->usages;
    }

    /**
     * Gets a helper instance by name.
     *
     * @return mixed
     *
     * @throws LogicException           if no HelperSet is defined
     * @throws InvalidArgumentException if the helper is not defined
     */
    public function getHelper(string $name)
    {
        if (null === $this->helperSet) {
            throw new LogicException(sprintf('Cannot retrieve helper "%s" because there is no HelperSet defined. Did you forget to add your command to the application or to set the application on the command using the setApplication() method? You can also set the HelperSet directly using the setHelperSet() method.', $name));
        }

        return $this->helperSet->get($name);
    }

    /**
     * Validates a command name.
     *
     * It must be non-empty and parts can optionally be separated by ":".
     *
     * @throws InvalidArgumentException When the name is invalid
     */
    private function validateName(string $name)
    {
        if (!preg_match('/^[^\:]++(\:[^\:]++)*$/', $name)) {
            throw new InvalidArgumentException(sprintf('Command name "%s" is invalid.', $name));
        }
    }
}
PKϤ$Z�=NP��console/README.mdnu�[���Console Component
=================

The Console component eases the creation of beautiful and testable command line
interfaces.

Sponsor
-------

The Console component for Symfony 5.4/6.0 is [backed][1] by [Les-Tilleuls.coop][2].

Les-Tilleuls.coop is a team of 50+ Symfony experts who can help you design, develop and
fix your projects. We provide a wide range of professional services including development,
consulting, coaching, training and audits. We also are highly skilled in JS, Go and DevOps.
We are a worker cooperative!

Help Symfony by [sponsoring][3] its development!

Resources
---------

 * [Documentation](https://symfony.com/doc/current/components/console.html)
 * [Contributing](https://symfony.com/doc/current/contributing/index.html)
 * [Report issues](https://github.com/symfony/symfony/issues) and
   [send Pull Requests](https://github.com/symfony/symfony/pulls)
   in the [main Symfony repository](https://github.com/symfony/symfony)

Credits
-------

`Resources/bin/hiddeninput.exe` is a third party binary provided within this
component. Find sources and license at https://github.com/Seldaek/hidden-input.

[1]: https://symfony.com/backers
[2]: https://les-tilleuls.coop
[3]: https://symfony.com/sponsor
PKϤ$Z���v$$%console/Resources/bin/hiddeninput.exenu�[���MZ����@���	�!�L�!This program cannot be run in DOS mode.

$�,�;�B�;�B�;�B�2�מ:�B�2��-�B�2�ƞ9�B�2�ў?�B�a9�8�B�;�C��B�2�Ȟ:�B�2�֞:�B�2�Ӟ:�B�Rich;�B�PEL�MoO�	
8 @`?�@��"P@ Pp!8!@ �.text	
 `.rdata�	 
@@.data�0@�.rsrc @@@.reloc�P"@Bj$��@�xj�� @�e���E�PV� @�EЃ�PV� @�M�X @�e��E�P�5H @�L @YY�5\ @�E�P�5` @�D @YY��P @�M���M�T @3��H�;
0@u���h�@��l3@�$40@�5h3@�40@h$0@h(0@h 0@�� @���00@��}j�Y�jh"@�3ۉ]�d��p�]俀3@SVW�0 @;�t;�u3�F�u��h��4 @��3�F�|3@;�u
j�\Y�;�|3@��u,�5|3@h� @h� @�YY��t�E����������5<0@�|3@;�uh� @h� @�lYY�|3@9]�uSW�8 @9�3@th�3@�Y��t
SjS��3@�$0@�
� @��5$0@�5(0@�5 0@�������80@9,0@u7P�� @�E��	�M�PQ�YYËe�E�80@3�9,0@uP�h @9<0@u�� @�E������80@�øMZf9@t3��M�<@��@�8PEu��H��t��uՃ��v�3�9����xtv�3�9������j�,0@�p @j��l @YY��3@��3@�� @�
t3@��� @�
p3@��� @��x3@�V��=0@uh�@�� @Y�g�=0@�u	j��� @Y3���{�����U���(�H1@�
D1@�@1@�<1@�581@�=41@f�`1@f�
T1@f�01@f�,1@f�%(1@f�-$1@��X1@�E�L1@�E�P1@�E�\1@������0@�P1@�L0@�@0@	��D0@�0@������0@������ @��0@j�?Yj�  @h!@�$ @�=�0@uj�Yh	��( @P�, @�Ë�U��E��8csm�u*�xu$�@= �t=!�t="�t=@�u��3�]�hH@�  @3��%� @jh("@�b�5�3@�5� @��Y�E��u�u�� @Y�gj�Y�e��5�3@�։E�5�3@��YY�E�E�P�E�P�u�5l @��YP�U�E�u�֣�3@�u�փ���3@�E������	�E���j�YË�U��u�N��������YH]Ë�V��!@��!@W��;�s���t�Ѓ�;�r�_^Ë�V�"@�"@W��;�s���t�Ѓ�;�r�_^�%� @���̋�U��M�MZf9t3�]ËA<��8PEu�3ҹf9H�‹�]�����������̋�U��E�H<��ASV�q3�W�D��v�}�H;�r	�X�;�r
B��(;�r�3�_^[]������������̋�U��j�hH"@he@d�P��SVW�0@1E�3�P�E�d��e��E�h@�*�������tU�E-@Ph@�P�������t;�@$���Ѓ��E������M�d�
Y_^[��]ËE��3�=��‹�Ëe��E�����3��M�d�
Y_^[��]��%� @�%� @��he@d�5�D$�l$�l$+�SVW�0@1E�3�P�e�u��E��E������E��E�d�ËM�d�
Y__^[��]Q�U��u�u�u�uh�@h0@����]�Vhh3�V������t
VVVVV����^�3��U����0@�e��e�SW�N�@����;�t
��t	�У0@�`V�E�P�< @�u�3u�� @3� @3� @3�E�P� @�E�3E�3�;�u�O�@����u����50@�։50@^_[��%t @�%x @�%| @�%� @�%� @�%� @�%� @�%� @�%� @Pd�5�D$+d$SVW�(��0@3�P�E�u��E������E�d�ËM�d�
Y__^[��]QËM�3���������M�%T @�T$�B�J�3�����J�3�����l"@�s����#�#�#�)r)b)H)4))�(�(�(�(�(�(�)�#�$%�%&d&�&�$('�'�'�'�'(((6(�'H(Z(t(�('''�'�'l'^'R'F'>'>(0'�'�)�@W@�@�MoOl�!�@0@�0@bad allocationH0@�!@RSDSь���J�!���LZc:\users\seld\documents\visual studio 2010\Projects\hiddeninp\Release\hiddeninp.pdbe������������@@�����������:@������������@�@�����@"�d"@�"�# $#�&D H#(h �#�#�#�)r)b)H)4))�(�(�(�(�(�(�)�#�$%�%&d&�&�$('�'�'�'�'(((6(�'H(Z(t(�('''�'�'l'^'R'F'>'>(0'�'�)�GetConsoleMode�SetConsoleMode;GetStdHandleKERNEL32.dll??$?6DU?$char_traits@D@std@@V?$allocator@D@1@@std@@YAAAV?$basic_ostream@DU?$char_traits@D@std@@@0@AAV10@ABV?$basic_string@DU?$char_traits@D@std@@V?$allocator@D@2@@0@@Z�?cout@std@@3V?$basic_ostream@DU?$char_traits@D@std@@@1@AJ?cin@std@@3V?$basic_istream@DU?$char_traits@D@std@@@1@A�??$getline@DU?$char_traits@D@std@@V?$allocator@D@2@@std@@YAAAV?$basic_istream@DU?$char_traits@D@std@@@0@AAV10@AAV?$basic_string@DU?$char_traits@D@std@@V?$allocator@D@2@@0@@Z??6?$basic_ostream@DU?$char_traits@D@std@@@std@@QAEAAV01@P6AAAV01@AAV01@@Z@Z_??1?$basic_string@DU?$char_traits@D@std@@V?$allocator@D@2@@std@@QAE@XZ{??0?$basic_string@DU?$char_traits@D@std@@V?$allocator@D@2@@std@@QAE@XZ�?endl@std@@YAAAV?$basic_ostream@DU?$char_traits@D@std@@@1@AAV21@@ZMSVCP90.dll_amsg_exit�__getmainargs,_cexit|_exitf_XcptFilter�exit�__initenv_initterm_initterm_e<_configthreadlocale�__setusermatherr_adjust_fdiv�__p__commode�__p__fmodej_encode_pointer�__set_app_typeK_crt_debugger_hookC?terminate@@YAXXZMSVCR90.dll�_unlock�__dllonexitv_lock_onexit`_decode_pointers_except_handler4_common_invoke_watson?_controlfp_s�InterlockedExchange!Sleep�InterlockedCompareExchange-TerminateProcess�GetCurrentProcess>UnhandledExceptionFilterSetUnhandledExceptionFilter�IsDebuggerPresentTQueryPerformanceCounterfGetTickCount�GetCurrentThreadId�GetCurrentProcessIdOGetSystemTimeAsFileTimes__CxxFrameHandler3N�@���D������������$!@ �8�P�h�	�	��@(��CV�(4VS_VERSION_INFO���StringFileInfob040904b0�QFileDescriptionReads from stdin without leaking info to the terminal and outputs back to stdout6FileVersion1, 0, 0, 08InternalNamehiddeninputPLegalCopyrightJordi Boggiano - 2012HOriginalFilenamehiddeninput.exe:
ProductNameHidden Input:ProductVersion1, 0, 0, 0DVarFileInfo$Translation	�<assembly xmlns="urn:schemas-microsoft-com:asm.v1" manifestVersion="1.0">
  <trustInfo xmlns="urn:schemas-microsoft-com:asm.v3">
    <security>
      <requestedPrivileges>
        <requestedExecutionLevel level="asInvoker" uiAccess="false"></requestedExecutionLevel>
      </requestedPrivileges>
    </security>
  </trustInfo>
  <dependency>
    <dependentAssembly>
      <assemblyIdentity type="win32" name="Microsoft.VC90.CRT" version="9.0.21022.8" processorArchitecture="x86" publicKeyToken="1fc8b3b9a1e18e3b"></assemblyIdentity>
    </dependentAssembly>
  </dependency>
</assembly>PAPADDINGXXPADDINGPADDINGXXPADDINGPADDINGXXPADDINGPADDINGXXPADDINGPADDINGXXPADDINGPADDINGXXPADDINGPADDINGXXPADDINGPADDINGXXPADDINGPADDINGXXPADDINGPADDINGXXPADDINGPADDINGXXPADDINGPADDINGXXPADDINGPADDINGXXPADDINGPADDINGXXPADDINGPADDINGXXPADDINGPADDINGXXPADDINGPADDINGXXPADDINGPADDINGXXPADDINGPADDINGXXPADDINGPADDINGXXPADDINGPADDINGXXPADDINGPADDINGXXPADDINGPADDINGXXPADDINGPADDINGXXPADDINGPADDINGXXPADDINGPADDINGXXPADDINGPADDINGXXPADDINGPADDINGXXPADDINGPADDINGXXPADDINGPADDINGXXPADDING@00!0/080F0L0T0^0d0n0{0�0�0�0�0�0�0�0�0�0�0�0�0�01#1-1@1J1O1T1v1{1�1�1�1�1�1�1�1�1�1�1�1�1�1�12"2*23292A2M2_2j2p2�2�2�2�2�2�2�2�2�2�2�2333%303N3T3Z3`3f3l3s3z3�3�3�3�3�3�3�3�3�3�3�3�3�3�3�3�34444%4;4B4�4�4�4�4�4�4�4�4�4�45!5^5c5�5�5�5H6M6_6}6�6�677
7*7w7|7�7�7�7�78
88=8E8P8V8\8b8h8n8t8z8�8�8�89 $�0�0�01 1t1x12 2@2\2`2h2t200PKϤ$Z�bm
X
X
!console/Resources/completion.bashnu�[���# This file is part of the Symfony package.
#
# (c) Fabien Potencier <fabien@symfony.com>
#
# For the full copyright and license information, please view
# https://symfony.com/doc/current/contributing/code/license.html

_sf_{{ COMMAND_NAME }}() {
    # Use newline as only separator to allow space in completion values
    IFS=$'\n'
    local sf_cmd="${COMP_WORDS[0]}"

    # for an alias, get the real script behind it
    if [[ $(type -t $sf_cmd) == "alias" ]]; then
        sf_cmd=$(alias $sf_cmd | sed -E "s/alias $sf_cmd='(.*)'/\1/")
    else
        sf_cmd=$(type -p $sf_cmd)
    fi

    if [ ! -x "$sf_cmd" ]; then
        return 1
    fi

    local cur prev words cword
    _get_comp_words_by_ref -n := cur prev words cword

    local completecmd=("$sf_cmd" "_complete" "-sbash" "-c$cword" "-S{{ VERSION }}")
    for w in ${words[@]}; do
        w=$(printf -- '%b' "$w")
        # remove quotes from typed values
        quote="${w:0:1}"
        if [ "$quote" == \' ]; then
            w="${w%\'}"
            w="${w#\'}"
        elif [ "$quote" == \" ]; then
            w="${w%\"}"
            w="${w#\"}"
        fi
        # empty values are ignored
        if [ ! -z "$w" ]; then
            completecmd+=("-i$w")
        fi
    done

    local sfcomplete
    if sfcomplete=$(${completecmd[@]} 2>&1); then
        local quote suggestions
        quote=${cur:0:1}

        # Use single quotes by default if suggestions contains backslash (FQCN)
        if [ "$quote" == '' ] && [[ "$sfcomplete" =~ \\ ]]; then
            quote=\'
        fi

        if [ "$quote" == \' ]; then
            # single quotes: no additional escaping (does not accept ' in values)
            suggestions=$(for s in $sfcomplete; do printf $'%q%q%q\n' "$quote" "$s" "$quote"; done)
        elif [ "$quote" == \" ]; then
            # double quotes: double escaping for \ $ ` "
            suggestions=$(for s in $sfcomplete; do
                s=${s//\\/\\\\}
                s=${s//\$/\\\$}
                s=${s//\`/\\\`}
                s=${s//\"/\\\"}
                printf $'%q%q%q\n' "$quote" "$s" "$quote";
            done)
        else
            # no quotes: double escaping
            suggestions=$(for s in $sfcomplete; do printf $'%q\n' $(printf '%q' "$s"); done)
        fi
        COMPREPLY=($(IFS=$'\n' compgen -W "$suggestions" -- $(printf -- "%q" "$cur")))
        __ltrim_colon_completions "$cur"
    else
        if [[ "$sfcomplete" != *"Command \"_complete\" is not defined."* ]]; then
            >&2 echo
            >&2 echo $sfcomplete
        fi

        return 1
    fi
}

complete -F _sf_{{ COMMAND_NAME }} {{ COMMAND_NAME }}
PKϤ$Z䪴�""5console/DependencyInjection/AddConsoleCommandPass.phpnu�[���<?php

/*
 * This file is part of the Symfony package.
 *
 * (c) Fabien Potencier <fabien@symfony.com>
 *
 * For the full copyright and license information, please view the LICENSE
 * file that was distributed with this source code.
 */

namespace Symfony\Component\Console\DependencyInjection;

use Symfony\Component\Console\Command\Command;
use Symfony\Component\Console\Command\LazyCommand;
use Symfony\Component\Console\CommandLoader\ContainerCommandLoader;
use Symfony\Component\DependencyInjection\Argument\ServiceClosureArgument;
use Symfony\Component\DependencyInjection\Compiler\CompilerPassInterface;
use Symfony\Component\DependencyInjection\Compiler\ServiceLocatorTagPass;
use Symfony\Component\DependencyInjection\ContainerBuilder;
use Symfony\Component\DependencyInjection\Exception\InvalidArgumentException;
use Symfony\Component\DependencyInjection\Reference;
use Symfony\Component\DependencyInjection\TypedReference;

/**
 * Registers console commands.
 *
 * @author Grégoire Pineau <lyrixx@lyrixx.info>
 */
class AddConsoleCommandPass implements CompilerPassInterface
{
    private $commandLoaderServiceId;
    private $commandTag;
    private $noPreloadTag;
    private $privateTagName;

    public function __construct(string $commandLoaderServiceId = 'console.command_loader', string $commandTag = 'console.command', string $noPreloadTag = 'container.no_preload', string $privateTagName = 'container.private')
    {
        if (0 < \func_num_args()) {
            trigger_deprecation('symfony/console', '5.3', 'Configuring "%s" is deprecated.', __CLASS__);
        }

        $this->commandLoaderServiceId = $commandLoaderServiceId;
        $this->commandTag = $commandTag;
        $this->noPreloadTag = $noPreloadTag;
        $this->privateTagName = $privateTagName;
    }

    public function process(ContainerBuilder $container)
    {
        $commandServices = $container->findTaggedServiceIds($this->commandTag, true);
        $lazyCommandMap = [];
        $lazyCommandRefs = [];
        $serviceIds = [];

        foreach ($commandServices as $id => $tags) {
            $definition = $container->getDefinition($id);
            $definition->addTag($this->noPreloadTag);
            $class = $container->getParameterBag()->resolveValue($definition->getClass());

            if (isset($tags[0]['command'])) {
                $aliases = $tags[0]['command'];
            } else {
                if (!$r = $container->getReflectionClass($class)) {
                    throw new InvalidArgumentException(sprintf('Class "%s" used for service "%s" cannot be found.', $class, $id));
                }
                if (!$r->isSubclassOf(Command::class)) {
                    throw new InvalidArgumentException(sprintf('The service "%s" tagged "%s" must be a subclass of "%s".', $id, $this->commandTag, Command::class));
                }
                $aliases = str_replace('%', '%%', $class::getDefaultName() ?? '');
            }

            $aliases = explode('|', $aliases ?? '');
            $commandName = array_shift($aliases);

            if ($isHidden = '' === $commandName) {
                $commandName = array_shift($aliases);
            }

            if (null === $commandName) {
                if (!$definition->isPublic() || $definition->isPrivate() || $definition->hasTag($this->privateTagName)) {
                    $commandId = 'console.command.public_alias.'.$id;
                    $container->setAlias($commandId, $id)->setPublic(true);
                    $id = $commandId;
                }
                $serviceIds[] = $id;

                continue;
            }

            $description = $tags[0]['description'] ?? null;

            unset($tags[0]);
            $lazyCommandMap[$commandName] = $id;
            $lazyCommandRefs[$id] = new TypedReference($id, $class);

            foreach ($aliases as $alias) {
                $lazyCommandMap[$alias] = $id;
            }

            foreach ($tags as $tag) {
                if (isset($tag['command'])) {
                    $aliases[] = $tag['command'];
                    $lazyCommandMap[$tag['command']] = $id;
                }

                $description = $description ?? $tag['description'] ?? null;
            }

            $definition->addMethodCall('setName', [$commandName]);

            if ($aliases) {
                $definition->addMethodCall('setAliases', [$aliases]);
            }

            if ($isHidden) {
                $definition->addMethodCall('setHidden', [true]);
            }

            if (!$description) {
                if (!$r = $container->getReflectionClass($class)) {
                    throw new InvalidArgumentException(sprintf('Class "%s" used for service "%s" cannot be found.', $class, $id));
                }
                if (!$r->isSubclassOf(Command::class)) {
                    throw new InvalidArgumentException(sprintf('The service "%s" tagged "%s" must be a subclass of "%s".', $id, $this->commandTag, Command::class));
                }
                $description = str_replace('%', '%%', $class::getDefaultDescription() ?? '');
            }

            if ($description) {
                $definition->addMethodCall('setDescription', [$description]);

                $container->register('.'.$id.'.lazy', LazyCommand::class)
                    ->setArguments([$commandName, $aliases, $description, $isHidden, new ServiceClosureArgument($lazyCommandRefs[$id])]);

                $lazyCommandRefs[$id] = new Reference('.'.$id.'.lazy');
            }
        }

        $container
            ->register($this->commandLoaderServiceId, ContainerCommandLoader::class)
            ->setPublic(true)
            ->addTag($this->noPreloadTag)
            ->setArguments([ServiceLocatorTagPass::register($container, $lazyCommandRefs), $lazyCommandMap]);

        $container->setParameter('console.command.ids', $serviceIds);
    }
}
PKϤ$ZU���� console/Logger/ConsoleLogger.phpnu�[���<?php

/*
 * This file is part of the Symfony package.
 *
 * (c) Fabien Potencier <fabien@symfony.com>
 *
 * For the full copyright and license information, please view the LICENSE
 * file that was distributed with this source code.
 */

namespace Symfony\Component\Console\Logger;

use Psr\Log\AbstractLogger;
use Psr\Log\InvalidArgumentException;
use Psr\Log\LogLevel;
use Symfony\Component\Console\Output\ConsoleOutputInterface;
use Symfony\Component\Console\Output\OutputInterface;

/**
 * PSR-3 compliant console logger.
 *
 * @author Kévin Dunglas <dunglas@gmail.com>
 *
 * @see https://www.php-fig.org/psr/psr-3/
 */
class ConsoleLogger extends AbstractLogger
{
    public const INFO = 'info';
    public const ERROR = 'error';

    private $output;
    private $verbosityLevelMap = [
        LogLevel::EMERGENCY => OutputInterface::VERBOSITY_NORMAL,
        LogLevel::ALERT => OutputInterface::VERBOSITY_NORMAL,
        LogLevel::CRITICAL => OutputInterface::VERBOSITY_NORMAL,
        LogLevel::ERROR => OutputInterface::VERBOSITY_NORMAL,
        LogLevel::WARNING => OutputInterface::VERBOSITY_NORMAL,
        LogLevel::NOTICE => OutputInterface::VERBOSITY_VERBOSE,
        LogLevel::INFO => OutputInterface::VERBOSITY_VERY_VERBOSE,
        LogLevel::DEBUG => OutputInterface::VERBOSITY_DEBUG,
    ];
    private $formatLevelMap = [
        LogLevel::EMERGENCY => self::ERROR,
        LogLevel::ALERT => self::ERROR,
        LogLevel::CRITICAL => self::ERROR,
        LogLevel::ERROR => self::ERROR,
        LogLevel::WARNING => self::INFO,
        LogLevel::NOTICE => self::INFO,
        LogLevel::INFO => self::INFO,
        LogLevel::DEBUG => self::INFO,
    ];
    private $errored = false;

    public function __construct(OutputInterface $output, array $verbosityLevelMap = [], array $formatLevelMap = [])
    {
        $this->output = $output;
        $this->verbosityLevelMap = $verbosityLevelMap + $this->verbosityLevelMap;
        $this->formatLevelMap = $formatLevelMap + $this->formatLevelMap;
    }

    /**
     * {@inheritdoc}
     *
     * @return void
     */
    public function log($level, $message, array $context = [])
    {
        if (!isset($this->verbosityLevelMap[$level])) {
            throw new InvalidArgumentException(sprintf('The log level "%s" does not exist.', $level));
        }

        $output = $this->output;

        // Write to the error output if necessary and available
        if (self::ERROR === $this->formatLevelMap[$level]) {
            if ($this->output instanceof ConsoleOutputInterface) {
                $output = $output->getErrorOutput();
            }
            $this->errored = true;
        }

        // the if condition check isn't necessary -- it's the same one that $output will do internally anyway.
        // We only do it for efficiency here as the message formatting is relatively expensive.
        if ($output->getVerbosity() >= $this->verbosityLevelMap[$level]) {
            $output->writeln(sprintf('<%1$s>[%2$s] %3$s</%1$s>', $this->formatLevelMap[$level], $level, $this->interpolate($message, $context)), $this->verbosityLevelMap[$level]);
        }
    }

    /**
     * Returns true when any messages have been logged at error levels.
     *
     * @return bool
     */
    public function hasErrored()
    {
        return $this->errored;
    }

    /**
     * Interpolates context values into the message placeholders.
     *
     * @author PHP Framework Interoperability Group
     */
    private function interpolate(string $message, array $context): string
    {
        if (!str_contains($message, '{')) {
            return $message;
        }

        $replacements = [];
        foreach ($context as $key => $val) {
            if (null === $val || \is_scalar($val) || (\is_object($val) && method_exists($val, '__toString'))) {
                $replacements["{{$key}}"] = $val;
            } elseif ($val instanceof \DateTimeInterface) {
                $replacements["{{$key}}"] = $val->format(\DateTime::RFC3339);
            } elseif (\is_object($val)) {
                $replacements["{{$key}}"] = '[object '.\get_class($val).']';
            } else {
                $replacements["{{$key}}"] = '['.\gettype($val).']';
            }
        }

        return strtr($message, $replacements);
    }
}
PKϤ$Z֚�]]console/Attribute/AsCommand.phpnu�[���<?php

/*
 * This file is part of the Symfony package.
 *
 * (c) Fabien Potencier <fabien@symfony.com>
 *
 * For the full copyright and license information, please view the LICENSE
 * file that was distributed with this source code.
 */

namespace Symfony\Component\Console\Attribute;

/**
 * Service tag to autoconfigure commands.
 */
#[\Attribute(\Attribute::TARGET_CLASS)]
class AsCommand
{
    public function __construct(
        public string $name,
        public ?string $description = null,
        array $aliases = [],
        bool $hidden = false,
    ) {
        if (!$hidden && !$aliases) {
            return;
        }

        $name = explode('|', $name);
        $name = array_merge($name, $aliases);

        if ($hidden && '' !== $name[0]) {
            array_unshift($name, '');
        }

        $this->name = implode('|', $name);
    }
}
PKϤ$Z�t����$console/SingleCommandApplication.phpnu�[���<?php

/*
 * This file is part of the Symfony package.
 *
 * (c) Fabien Potencier <fabien@symfony.com>
 *
 * For the full copyright and license information, please view the LICENSE
 * file that was distributed with this source code.
 */

namespace Symfony\Component\Console;

use Symfony\Component\Console\Command\Command;
use Symfony\Component\Console\Input\InputInterface;
use Symfony\Component\Console\Output\OutputInterface;

/**
 * @author Grégoire Pineau <lyrixx@lyrixx.info>
 */
class SingleCommandApplication extends Command
{
    private $version = 'UNKNOWN';
    private $autoExit = true;
    private $running = false;

    /**
     * @return $this
     */
    public function setVersion(string $version): self
    {
        $this->version = $version;

        return $this;
    }

    /**
     * @final
     *
     * @return $this
     */
    public function setAutoExit(bool $autoExit): self
    {
        $this->autoExit = $autoExit;

        return $this;
    }

    public function run(InputInterface $input = null, OutputInterface $output = null): int
    {
        if ($this->running) {
            return parent::run($input, $output);
        }

        // We use the command name as the application name
        $application = new Application($this->getName() ?: 'UNKNOWN', $this->version);
        $application->setAutoExit($this->autoExit);
        // Fix the usage of the command displayed with "--help"
        $this->setName($_SERVER['argv'][0]);
        $application->add($this);
        $application->setDefaultCommand($this->getName(), true);

        $this->running = true;
        try {
            $ret = $application->run($input, $output);
        } finally {
            $this->running = false;
        }

        return $ret ?? 1;
    }
}
PKϤ$ZSML���$console/Exception/LogicException.phpnu�[���<?php

/*
 * This file is part of the Symfony package.
 *
 * (c) Fabien Potencier <fabien@symfony.com>
 *
 * For the full copyright and license information, please view the LICENSE
 * file that was distributed with this source code.
 */

namespace Symfony\Component\Console\Exception;

/**
 * @author Jérôme Tamarelle <jerome@tamarelle.net>
 */
class LogicException extends \LogicException implements ExceptionInterface
{
}
PKϤ$ZBL�H��0console/Exception/NamespaceNotFoundException.phpnu�[���<?php

/*
 * This file is part of the Symfony package.
 *
 * (c) Fabien Potencier <fabien@symfony.com>
 *
 * For the full copyright and license information, please view the LICENSE
 * file that was distributed with this source code.
 */

namespace Symfony\Component\Console\Exception;

/**
 * Represents an incorrect namespace typed in the console.
 *
 * @author Pierre du Plessis <pdples@gmail.com>
 */
class NamespaceNotFoundException extends CommandNotFoundException
{
}
PKϤ$ZQ�g;��+console/Exception/MissingInputException.phpnu�[���<?php

/*
 * This file is part of the Symfony package.
 *
 * (c) Fabien Potencier <fabien@symfony.com>
 *
 * For the full copyright and license information, please view the LICENSE
 * file that was distributed with this source code.
 */

namespace Symfony\Component\Console\Exception;

/**
 * Represents failure to read input from stdin.
 *
 * @author Gabriel Ostrolucký <gabriel.ostrolucky@gmail.com>
 */
class MissingInputException extends RuntimeException implements ExceptionInterface
{
}
PKϤ$Z�l��(console/Exception/ExceptionInterface.phpnu�[���<?php

/*
 * This file is part of the Symfony package.
 *
 * (c) Fabien Potencier <fabien@symfony.com>
 *
 * For the full copyright and license information, please view the LICENSE
 * file that was distributed with this source code.
 */

namespace Symfony\Component\Console\Exception;

/**
 * ExceptionInterface.
 *
 * @author Jérôme Tamarelle <jerome@tamarelle.net>
 */
interface ExceptionInterface extends \Throwable
{
}
PKϤ$Z����.console/Exception/CommandNotFoundException.phpnu�[���<?php

/*
 * This file is part of the Symfony package.
 *
 * (c) Fabien Potencier <fabien@symfony.com>
 *
 * For the full copyright and license information, please view the LICENSE
 * file that was distributed with this source code.
 */

namespace Symfony\Component\Console\Exception;

/**
 * Represents an incorrect command name typed in the console.
 *
 * @author Jérôme Tamarelle <jerome@tamarelle.net>
 */
class CommandNotFoundException extends \InvalidArgumentException implements ExceptionInterface
{
    private $alternatives;

    /**
     * @param string          $message      Exception message to throw
     * @param string[]        $alternatives List of similar defined names
     * @param int             $code         Exception code
     * @param \Throwable|null $previous     Previous exception used for the exception chaining
     */
    public function __construct(string $message, array $alternatives = [], int $code = 0, \Throwable $previous = null)
    {
        parent::__construct($message, $code, $previous);

        $this->alternatives = $alternatives;
    }

    /**
     * @return string[]
     */
    public function getAlternatives()
    {
        return $this->alternatives;
    }
}
PKϤ$Z�u i��.console/Exception/InvalidArgumentException.phpnu�[���<?php

/*
 * This file is part of the Symfony package.
 *
 * (c) Fabien Potencier <fabien@symfony.com>
 *
 * For the full copyright and license information, please view the LICENSE
 * file that was distributed with this source code.
 */

namespace Symfony\Component\Console\Exception;

/**
 * @author Jérôme Tamarelle <jerome@tamarelle.net>
 */
class InvalidArgumentException extends \InvalidArgumentException implements ExceptionInterface
{
}
PKϤ$Z�;��,console/Exception/InvalidOptionException.phpnu�[���<?php

/*
 * This file is part of the Symfony package.
 *
 * (c) Fabien Potencier <fabien@symfony.com>
 *
 * For the full copyright and license information, please view the LICENSE
 * file that was distributed with this source code.
 */

namespace Symfony\Component\Console\Exception;

/**
 * Represents an incorrect option name typed in the console.
 *
 * @author Jérôme Tamarelle <jerome@tamarelle.net>
 */
class InvalidOptionException extends \InvalidArgumentException implements ExceptionInterface
{
}
PKϤ$Z�*b��&console/Exception/RuntimeException.phpnu�[���<?php

/*
 * This file is part of the Symfony package.
 *
 * (c) Fabien Potencier <fabien@symfony.com>
 *
 * For the full copyright and license information, please view the LICENSE
 * file that was distributed with this source code.
 */

namespace Symfony\Component\Console\Exception;

/**
 * @author Jérôme Tamarelle <jerome@tamarelle.net>
 */
class RuntimeException extends \RuntimeException implements ExceptionInterface
{
}
PKϤ$Z�P��� � console/CHANGELOG.mdnu�[���CHANGELOG
=========

5.4
---

 * Add `TesterTrait::assertCommandIsSuccessful()` to test command
 * Deprecate `HelperSet::setCommand()` and `getCommand()` without replacement

5.3
---

 * Add `GithubActionReporter` to render annotations in a Github Action
 * Add `InputOption::VALUE_NEGATABLE` flag to handle `--foo`/`--no-foo` options
 * Add the `Command::$defaultDescription` static property and the `description` attribute
   on the `console.command` tag to allow the `list` command to instantiate commands lazily
 * Add option `--short` to the `list` command
 * Add support for bright colors
 * Add `#[AsCommand]` attribute for declaring commands on PHP 8
 * Add `Helper::width()` and `Helper::length()`
 * The `--ansi` and `--no-ansi` options now default to `null`.

5.2.0
-----

 * Added `SingleCommandApplication::setAutoExit()` to allow testing via `CommandTester`
 * added support for multiline responses to questions through `Question::setMultiline()`
   and `Question::isMultiline()`
 * Added `SignalRegistry` class to stack signals handlers
 * Added support for signals:
    * Added `Application::getSignalRegistry()` and `Application::setSignalsToDispatchEvent()` methods
    * Added `SignalableCommandInterface` interface
 * Added `TableCellStyle` class to customize table cell
 * Removed `php ` prefix invocation from help messages.

5.1.0
-----

 * `Command::setHidden()` is final since Symfony 5.1
 * Add `SingleCommandApplication`
 * Add `Cursor` class

5.0.0
-----

 * removed support for finding hidden commands using an abbreviation, use the full name instead
 * removed `TableStyle::setCrossingChar()` method in favor of `TableStyle::setDefaultCrossingChar()`
 * removed `TableStyle::setHorizontalBorderChar()` method in favor of `TableStyle::setDefaultCrossingChars()`
 * removed `TableStyle::getHorizontalBorderChar()` method in favor of `TableStyle::getBorderChars()`
 * removed `TableStyle::setVerticalBorderChar()` method in favor of `TableStyle::setVerticalBorderChars()`
 * removed `TableStyle::getVerticalBorderChar()` method in favor of `TableStyle::getBorderChars()`
 * removed support for returning `null` from `Command::execute()`, return `0` instead
 * `ProcessHelper::run()` accepts only `array|Symfony\Component\Process\Process` for its `command` argument
 * `Application::setDispatcher` accepts only `Symfony\Contracts\EventDispatcher\EventDispatcherInterface`
   for its `dispatcher` argument
 * renamed `Application::renderException()` and `Application::doRenderException()`
   to `renderThrowable()` and `doRenderThrowable()` respectively.

4.4.0
-----

 * deprecated finding hidden commands using an abbreviation, use the full name instead
 * added `Question::setTrimmable` default to true to allow the answer to be trimmed
 * added method `minSecondsBetweenRedraws()` and `maxSecondsBetweenRedraws()` on `ProgressBar`
 * `Application` implements `ResetInterface`
 * marked all dispatched event classes as `@final`
 * added support for displaying table horizontally
 * deprecated returning `null` from `Command::execute()`, return `0` instead
 * Deprecated the `Application::renderException()` and `Application::doRenderException()` methods,
   use `renderThrowable()` and `doRenderThrowable()` instead.
 * added support for the `NO_COLOR` env var (https://no-color.org/)

4.3.0
-----

 * added support for hyperlinks
 * added `ProgressBar::iterate()` method that simplify updating the progress bar when iterating
 * added `Question::setAutocompleterCallback()` to provide a callback function
   that dynamically generates suggestions as the user types

4.2.0
-----

 * allowed passing commands as `[$process, 'ENV_VAR' => 'value']` to
   `ProcessHelper::run()` to pass environment variables
 * deprecated passing a command as a string to `ProcessHelper::run()`,
   pass it the command as an array of its arguments instead
 * made the `ProcessHelper` class final
 * added `WrappableOutputFormatterInterface::formatAndWrap()` (implemented in `OutputFormatter`)
 * added `capture_stderr_separately` option to `CommandTester::execute()`

4.1.0
-----

 * added option to run suggested command if command is not found and only 1 alternative is available
 * added option to modify console output and print multiple modifiable sections
 * added support for iterable messages in output `write` and `writeln` methods

4.0.0
-----

 * `OutputFormatter` throws an exception when unknown options are used
 * removed `QuestionHelper::setInputStream()/getInputStream()`
 * removed `Application::getTerminalWidth()/getTerminalHeight()` and
   `Application::setTerminalDimensions()/getTerminalDimensions()`
 * removed `ConsoleExceptionEvent`
 * removed `ConsoleEvents::EXCEPTION`

3.4.0
-----

 * added `SHELL_VERBOSITY` env var to control verbosity
 * added `CommandLoaderInterface`, `FactoryCommandLoader` and PSR-11
   `ContainerCommandLoader` for commands lazy-loading
 * added a case-insensitive command name matching fallback
 * added static `Command::$defaultName/getDefaultName()`, allowing for
   commands to be registered at compile time in the application command loader.
   Setting the `$defaultName` property avoids the need for filling the `command`
   attribute on the `console.command` tag when using `AddConsoleCommandPass`.

3.3.0
-----

 * added `ExceptionListener`
 * added `AddConsoleCommandPass` (originally in FrameworkBundle)
 * [BC BREAK] `Input::getOption()` no longer returns the default value for options
   with value optional explicitly passed empty
 * added console.error event to catch exceptions thrown by other listeners
 * deprecated console.exception event in favor of console.error
 * added ability to handle `CommandNotFoundException` through the
   `console.error` event
 * deprecated default validation in `SymfonyQuestionHelper::ask`

3.2.0
------

 * added `setInputs()` method to CommandTester for ease testing of commands expecting inputs
 * added `setStream()` and `getStream()` methods to Input (implement StreamableInputInterface)
 * added StreamableInputInterface
 * added LockableTrait

3.1.0
-----

 * added truncate method to FormatterHelper
 * added setColumnWidth(s) method to Table

2.8.3
-----

 * remove readline support from the question helper as it caused issues

2.8.0
-----

 * use readline for user input in the question helper when available to allow
   the use of arrow keys

2.6.0
-----

 * added a Process helper
 * added a DebugFormatter helper

2.5.0
-----

 * deprecated the dialog helper (use the question helper instead)
 * deprecated TableHelper in favor of Table
 * deprecated ProgressHelper in favor of ProgressBar
 * added ConsoleLogger
 * added a question helper
 * added a way to set the process name of a command
 * added a way to set a default command instead of `ListCommand`

2.4.0
-----

 * added a way to force terminal dimensions
 * added a convenient method to detect verbosity level
 * [BC BREAK] made descriptors use output instead of returning a string

2.3.0
-----

 * added multiselect support to the select dialog helper
 * added Table Helper for tabular data rendering
 * added support for events in `Application`
 * added a way to normalize EOLs in `ApplicationTester::getDisplay()` and `CommandTester::getDisplay()`
 * added a way to set the progress bar progress via the `setCurrent` method
 * added support for multiple InputOption shortcuts, written as `'-a|-b|-c'`
 * added two additional verbosity levels, VERBOSITY_VERY_VERBOSE and VERBOSITY_DEBUG

2.2.0
-----

 * added support for colorization on Windows via ConEmu
 * add a method to Dialog Helper to ask for a question and hide the response
 * added support for interactive selections in console (DialogHelper::select())
 * added support for autocompletion as you type in Dialog Helper

2.1.0
-----

 * added ConsoleOutputInterface
 * added the possibility to disable a command (Command::isEnabled())
 * added suggestions when a command does not exist
 * added a --raw option to the list command
 * added support for STDERR in the console output class (errors are now sent
   to STDERR)
 * made the defaults (helper set, commands, input definition) in Application
   more easily customizable
 * added support for the shell even if readline is not available
 * added support for process isolation in Symfony shell via
   `--process-isolation` switch
 * added support for `--`, which disables options parsing after that point
   (tokens will be parsed as arguments)
PKϤ$Z���		console/Output/NullOutput.phpnu�[���<?php

/*
 * This file is part of the Symfony package.
 *
 * (c) Fabien Potencier <fabien@symfony.com>
 *
 * For the full copyright and license information, please view the LICENSE
 * file that was distributed with this source code.
 */

namespace Symfony\Component\Console\Output;

use Symfony\Component\Console\Formatter\NullOutputFormatter;
use Symfony\Component\Console\Formatter\OutputFormatterInterface;

/**
 * NullOutput suppresses all output.
 *
 *     $output = new NullOutput();
 *
 * @author Fabien Potencier <fabien@symfony.com>
 * @author Tobias Schultze <http://tobion.de>
 */
class NullOutput implements OutputInterface
{
    private $formatter;

    /**
     * {@inheritdoc}
     */
    public function setFormatter(OutputFormatterInterface $formatter)
    {
        // do nothing
    }

    /**
     * {@inheritdoc}
     */
    public function getFormatter()
    {
        if ($this->formatter) {
            return $this->formatter;
        }
        // to comply with the interface we must return a OutputFormatterInterface
        return $this->formatter = new NullOutputFormatter();
    }

    /**
     * {@inheritdoc}
     */
    public function setDecorated(bool $decorated)
    {
        // do nothing
    }

    /**
     * {@inheritdoc}
     */
    public function isDecorated()
    {
        return false;
    }

    /**
     * {@inheritdoc}
     */
    public function setVerbosity(int $level)
    {
        // do nothing
    }

    /**
     * {@inheritdoc}
     */
    public function getVerbosity()
    {
        return self::VERBOSITY_QUIET;
    }

    /**
     * {@inheritdoc}
     */
    public function isQuiet()
    {
        return true;
    }

    /**
     * {@inheritdoc}
     */
    public function isVerbose()
    {
        return false;
    }

    /**
     * {@inheritdoc}
     */
    public function isVeryVerbose()
    {
        return false;
    }

    /**
     * {@inheritdoc}
     */
    public function isDebug()
    {
        return false;
    }

    /**
     * {@inheritdoc}
     */
    public function writeln($messages, int $options = self::OUTPUT_NORMAL)
    {
        // do nothing
    }

    /**
     * {@inheritdoc}
     */
    public function write($messages, bool $newline = false, int $options = self::OUTPUT_NORMAL)
    {
        // do nothing
    }
}
PKϤ$Z_�  )console/Output/ConsoleOutputInterface.phpnu�[���<?php

/*
 * This file is part of the Symfony package.
 *
 * (c) Fabien Potencier <fabien@symfony.com>
 *
 * For the full copyright and license information, please view the LICENSE
 * file that was distributed with this source code.
 */

namespace Symfony\Component\Console\Output;

/**
 * ConsoleOutputInterface is the interface implemented by ConsoleOutput class.
 * This adds information about stderr and section output stream.
 *
 * @author Dariusz Górecki <darek.krk@gmail.com>
 */
interface ConsoleOutputInterface extends OutputInterface
{
    /**
     * Gets the OutputInterface for errors.
     *
     * @return OutputInterface
     */
    public function getErrorOutput();

    public function setErrorOutput(OutputInterface $error);

    public function section(): ConsoleSectionOutput;
}
PKϤ$Z��66 console/Output/ConsoleOutput.phpnu�[���<?php

/*
 * This file is part of the Symfony package.
 *
 * (c) Fabien Potencier <fabien@symfony.com>
 *
 * For the full copyright and license information, please view the LICENSE
 * file that was distributed with this source code.
 */

namespace Symfony\Component\Console\Output;

use Symfony\Component\Console\Formatter\OutputFormatterInterface;

/**
 * ConsoleOutput is the default class for all CLI output. It uses STDOUT and STDERR.
 *
 * This class is a convenient wrapper around `StreamOutput` for both STDOUT and STDERR.
 *
 *     $output = new ConsoleOutput();
 *
 * This is equivalent to:
 *
 *     $output = new StreamOutput(fopen('php://stdout', 'w'));
 *     $stdErr = new StreamOutput(fopen('php://stderr', 'w'));
 *
 * @author Fabien Potencier <fabien@symfony.com>
 */
class ConsoleOutput extends StreamOutput implements ConsoleOutputInterface
{
    private $stderr;
    private $consoleSectionOutputs = [];

    /**
     * @param int                           $verbosity The verbosity level (one of the VERBOSITY constants in OutputInterface)
     * @param bool|null                     $decorated Whether to decorate messages (null for auto-guessing)
     * @param OutputFormatterInterface|null $formatter Output formatter instance (null to use default OutputFormatter)
     */
    public function __construct(int $verbosity = self::VERBOSITY_NORMAL, bool $decorated = null, OutputFormatterInterface $formatter = null)
    {
        parent::__construct($this->openOutputStream(), $verbosity, $decorated, $formatter);

        if (null === $formatter) {
            // for BC reasons, stdErr has it own Formatter only when user don't inject a specific formatter.
            $this->stderr = new StreamOutput($this->openErrorStream(), $verbosity, $decorated);

            return;
        }

        $actualDecorated = $this->isDecorated();
        $this->stderr = new StreamOutput($this->openErrorStream(), $verbosity, $decorated, $this->getFormatter());

        if (null === $decorated) {
            $this->setDecorated($actualDecorated && $this->stderr->isDecorated());
        }
    }

    /**
     * Creates a new output section.
     */
    public function section(): ConsoleSectionOutput
    {
        return new ConsoleSectionOutput($this->getStream(), $this->consoleSectionOutputs, $this->getVerbosity(), $this->isDecorated(), $this->getFormatter());
    }

    /**
     * {@inheritdoc}
     */
    public function setDecorated(bool $decorated)
    {
        parent::setDecorated($decorated);
        $this->stderr->setDecorated($decorated);
    }

    /**
     * {@inheritdoc}
     */
    public function setFormatter(OutputFormatterInterface $formatter)
    {
        parent::setFormatter($formatter);
        $this->stderr->setFormatter($formatter);
    }

    /**
     * {@inheritdoc}
     */
    public function setVerbosity(int $level)
    {
        parent::setVerbosity($level);
        $this->stderr->setVerbosity($level);
    }

    /**
     * {@inheritdoc}
     */
    public function getErrorOutput()
    {
        return $this->stderr;
    }

    /**
     * {@inheritdoc}
     */
    public function setErrorOutput(OutputInterface $error)
    {
        $this->stderr = $error;
    }

    /**
     * Returns true if current environment supports writing console output to
     * STDOUT.
     *
     * @return bool
     */
    protected function hasStdoutSupport()
    {
        return false === $this->isRunningOS400();
    }

    /**
     * Returns true if current environment supports writing console output to
     * STDERR.
     *
     * @return bool
     */
    protected function hasStderrSupport()
    {
        return false === $this->isRunningOS400();
    }

    /**
     * Checks if current executing environment is IBM iSeries (OS400), which
     * doesn't properly convert character-encodings between ASCII to EBCDIC.
     */
    private function isRunningOS400(): bool
    {
        $checks = [
            \function_exists('php_uname') ? php_uname('s') : '',
            getenv('OSTYPE'),
            \PHP_OS,
        ];

        return false !== stripos(implode(';', $checks), 'OS400');
    }

    /**
     * @return resource
     */
    private function openOutputStream()
    {
        if (!$this->hasStdoutSupport()) {
            return fopen('php://output', 'w');
        }

        // Use STDOUT when possible to prevent from opening too many file descriptors
        return \defined('STDOUT') ? \STDOUT : (@fopen('php://stdout', 'w') ?: fopen('php://output', 'w'));
    }

    /**
     * @return resource
     */
    private function openErrorStream()
    {
        if (!$this->hasStderrSupport()) {
            return fopen('php://output', 'w');
        }

        // Use STDERR when possible to prevent from opening too many file descriptors
        return \defined('STDERR') ? \STDERR : (@fopen('php://stderr', 'w') ?: fopen('php://output', 'w'));
    }
}
PKϤ$Z�$?.�
�
console/Output/StreamOutput.phpnu�[���<?php

/*
 * This file is part of the Symfony package.
 *
 * (c) Fabien Potencier <fabien@symfony.com>
 *
 * For the full copyright and license information, please view the LICENSE
 * file that was distributed with this source code.
 */

namespace Symfony\Component\Console\Output;

use Symfony\Component\Console\Exception\InvalidArgumentException;
use Symfony\Component\Console\Formatter\OutputFormatterInterface;

/**
 * StreamOutput writes the output to a given stream.
 *
 * Usage:
 *
 *     $output = new StreamOutput(fopen('php://stdout', 'w'));
 *
 * As `StreamOutput` can use any stream, you can also use a file:
 *
 *     $output = new StreamOutput(fopen('/path/to/output.log', 'a', false));
 *
 * @author Fabien Potencier <fabien@symfony.com>
 */
class StreamOutput extends Output
{
    private $stream;

    /**
     * @param resource                      $stream    A stream resource
     * @param int                           $verbosity The verbosity level (one of the VERBOSITY constants in OutputInterface)
     * @param bool|null                     $decorated Whether to decorate messages (null for auto-guessing)
     * @param OutputFormatterInterface|null $formatter Output formatter instance (null to use default OutputFormatter)
     *
     * @throws InvalidArgumentException When first argument is not a real stream
     */
    public function __construct($stream, int $verbosity = self::VERBOSITY_NORMAL, bool $decorated = null, OutputFormatterInterface $formatter = null)
    {
        if (!\is_resource($stream) || 'stream' !== get_resource_type($stream)) {
            throw new InvalidArgumentException('The StreamOutput class needs a stream as its first argument.');
        }

        $this->stream = $stream;

        if (null === $decorated) {
            $decorated = $this->hasColorSupport();
        }

        parent::__construct($verbosity, $decorated, $formatter);
    }

    /**
     * Gets the stream attached to this StreamOutput instance.
     *
     * @return resource
     */
    public function getStream()
    {
        return $this->stream;
    }

    /**
     * {@inheritdoc}
     */
    protected function doWrite(string $message, bool $newline)
    {
        if ($newline) {
            $message .= \PHP_EOL;
        }

        @fwrite($this->stream, $message);

        fflush($this->stream);
    }

    /**
     * Returns true if the stream supports colorization.
     *
     * Colorization is disabled if not supported by the stream:
     *
     * This is tricky on Windows, because Cygwin, Msys2 etc emulate pseudo
     * terminals via named pipes, so we can only check the environment.
     *
     * Reference: Composer\XdebugHandler\Process::supportsColor
     * https://github.com/composer/xdebug-handler
     *
     * @return bool true if the stream supports colorization, false otherwise
     */
    protected function hasColorSupport()
    {
        // Follow https://no-color.org/
        if (isset($_SERVER['NO_COLOR']) || false !== getenv('NO_COLOR')) {
            return false;
        }

        if ('Hyper' === getenv('TERM_PROGRAM')) {
            return true;
        }

        if (\DIRECTORY_SEPARATOR === '\\') {
            return (\function_exists('sapi_windows_vt100_support')
                && @sapi_windows_vt100_support($this->stream))
                || false !== getenv('ANSICON')
                || 'ON' === getenv('ConEmuANSI')
                || 'xterm' === getenv('TERM');
        }

        return stream_isatty($this->stream);
    }
}
PKϤ$ZBE$�UU!console/Output/BufferedOutput.phpnu�[���<?php

/*
 * This file is part of the Symfony package.
 *
 * (c) Fabien Potencier <fabien@symfony.com>
 *
 * For the full copyright and license information, please view the LICENSE
 * file that was distributed with this source code.
 */

namespace Symfony\Component\Console\Output;

/**
 * @author Jean-François Simon <contact@jfsimon.fr>
 */
class BufferedOutput extends Output
{
    private $buffer = '';

    /**
     * Empties buffer and returns its content.
     *
     * @return string
     */
    public function fetch()
    {
        $content = $this->buffer;
        $this->buffer = '';

        return $content;
    }

    /**
     * {@inheritdoc}
     */
    protected function doWrite(string $message, bool $newline)
    {
        $this->buffer .= $message;

        if ($newline) {
            $this->buffer .= \PHP_EOL;
        }
    }
}
PKϤ$Z���mWW'console/Output/ConsoleSectionOutput.phpnu�[���<?php

/*
 * This file is part of the Symfony package.
 *
 * (c) Fabien Potencier <fabien@symfony.com>
 *
 * For the full copyright and license information, please view the LICENSE
 * file that was distributed with this source code.
 */

namespace Symfony\Component\Console\Output;

use Symfony\Component\Console\Formatter\OutputFormatterInterface;
use Symfony\Component\Console\Helper\Helper;
use Symfony\Component\Console\Terminal;

/**
 * @author Pierre du Plessis <pdples@gmail.com>
 * @author Gabriel Ostrolucký <gabriel.ostrolucky@gmail.com>
 */
class ConsoleSectionOutput extends StreamOutput
{
    private $content = [];
    private $lines = 0;
    private $sections;
    private $terminal;

    /**
     * @param resource               $stream
     * @param ConsoleSectionOutput[] $sections
     */
    public function __construct($stream, array &$sections, int $verbosity, bool $decorated, OutputFormatterInterface $formatter)
    {
        parent::__construct($stream, $verbosity, $decorated, $formatter);
        array_unshift($sections, $this);
        $this->sections = &$sections;
        $this->terminal = new Terminal();
    }

    /**
     * Clears previous output for this section.
     *
     * @param int $lines Number of lines to clear. If null, then the entire output of this section is cleared
     */
    public function clear(int $lines = null)
    {
        if (empty($this->content) || !$this->isDecorated()) {
            return;
        }

        if ($lines) {
            array_splice($this->content, -($lines * 2)); // Multiply lines by 2 to cater for each new line added between content
        } else {
            $lines = $this->lines;
            $this->content = [];
        }

        $this->lines -= $lines;

        parent::doWrite($this->popStreamContentUntilCurrentSection($lines), false);
    }

    /**
     * Overwrites the previous output with a new message.
     *
     * @param array|string $message
     */
    public function overwrite($message)
    {
        $this->clear();
        $this->writeln($message);
    }

    public function getContent(): string
    {
        return implode('', $this->content);
    }

    /**
     * @internal
     */
    public function addContent(string $input)
    {
        foreach (explode(\PHP_EOL, $input) as $lineContent) {
            $this->lines += ceil($this->getDisplayLength($lineContent) / $this->terminal->getWidth()) ?: 1;
            $this->content[] = $lineContent;
            $this->content[] = \PHP_EOL;
        }
    }

    /**
     * {@inheritdoc}
     */
    protected function doWrite(string $message, bool $newline)
    {
        if (!$this->isDecorated()) {
            parent::doWrite($message, $newline);

            return;
        }

        $erasedContent = $this->popStreamContentUntilCurrentSection();

        $this->addContent($message);

        parent::doWrite($message, true);
        parent::doWrite($erasedContent, false);
    }

    /**
     * At initial stage, cursor is at the end of stream output. This method makes cursor crawl upwards until it hits
     * current section. Then it erases content it crawled through. Optionally, it erases part of current section too.
     */
    private function popStreamContentUntilCurrentSection(int $numberOfLinesToClearFromCurrentSection = 0): string
    {
        $numberOfLinesToClear = $numberOfLinesToClearFromCurrentSection;
        $erasedContent = [];

        foreach ($this->sections as $section) {
            if ($section === $this) {
                break;
            }

            $numberOfLinesToClear += $section->lines;
            $erasedContent[] = $section->getContent();
        }

        if ($numberOfLinesToClear > 0) {
            // move cursor up n lines
            parent::doWrite(sprintf("\x1b[%dA", $numberOfLinesToClear), false);
            // erase to end of screen
            parent::doWrite("\x1b[0J", false);
        }

        return implode('', array_reverse($erasedContent));
    }

    private function getDisplayLength(string $text): int
    {
        return Helper::width(Helper::removeDecoration($this->getFormatter(), str_replace("\t", '        ', $text)));
    }
}
PKϤ$Z�<�);;&console/Output/TrimmedBufferOutput.phpnu�[���<?php

/*
 * This file is part of the Symfony package.
 *
 * (c) Fabien Potencier <fabien@symfony.com>
 *
 * For the full copyright and license information, please view the LICENSE
 * file that was distributed with this source code.
 */

namespace Symfony\Component\Console\Output;

use Symfony\Component\Console\Exception\InvalidArgumentException;
use Symfony\Component\Console\Formatter\OutputFormatterInterface;

/**
 * A BufferedOutput that keeps only the last N chars.
 *
 * @author Jérémy Derussé <jeremy@derusse.com>
 */
class TrimmedBufferOutput extends Output
{
    private $maxLength;
    private $buffer = '';

    public function __construct(int $maxLength, ?int $verbosity = self::VERBOSITY_NORMAL, bool $decorated = false, OutputFormatterInterface $formatter = null)
    {
        if ($maxLength <= 0) {
            throw new InvalidArgumentException(sprintf('"%s()" expects a strictly positive maxLength. Got %d.', __METHOD__, $maxLength));
        }

        parent::__construct($verbosity, $decorated, $formatter);
        $this->maxLength = $maxLength;
    }

    /**
     * Empties buffer and returns its content.
     *
     * @return string
     */
    public function fetch()
    {
        $content = $this->buffer;
        $this->buffer = '';

        return $content;
    }

    /**
     * {@inheritdoc}
     */
    protected function doWrite(string $message, bool $newline)
    {
        $this->buffer .= $message;

        if ($newline) {
            $this->buffer .= \PHP_EOL;
        }

        $this->buffer = substr($this->buffer, 0 - $this->maxLength);
    }
}
PKϤ$Z��t�\\"console/Output/OutputInterface.phpnu�[���<?php

/*
 * This file is part of the Symfony package.
 *
 * (c) Fabien Potencier <fabien@symfony.com>
 *
 * For the full copyright and license information, please view the LICENSE
 * file that was distributed with this source code.
 */

namespace Symfony\Component\Console\Output;

use Symfony\Component\Console\Formatter\OutputFormatterInterface;

/**
 * OutputInterface is the interface implemented by all Output classes.
 *
 * @author Fabien Potencier <fabien@symfony.com>
 */
interface OutputInterface
{
    public const VERBOSITY_QUIET = 16;
    public const VERBOSITY_NORMAL = 32;
    public const VERBOSITY_VERBOSE = 64;
    public const VERBOSITY_VERY_VERBOSE = 128;
    public const VERBOSITY_DEBUG = 256;

    public const OUTPUT_NORMAL = 1;
    public const OUTPUT_RAW = 2;
    public const OUTPUT_PLAIN = 4;

    /**
     * Writes a message to the output.
     *
     * @param string|iterable $messages The message as an iterable of strings or a single string
     * @param bool            $newline  Whether to add a newline
     * @param int             $options  A bitmask of options (one of the OUTPUT or VERBOSITY constants), 0 is considered the same as self::OUTPUT_NORMAL | self::VERBOSITY_NORMAL
     */
    public function write($messages, bool $newline = false, int $options = 0);

    /**
     * Writes a message to the output and adds a newline at the end.
     *
     * @param string|iterable $messages The message as an iterable of strings or a single string
     * @param int             $options  A bitmask of options (one of the OUTPUT or VERBOSITY constants), 0 is considered the same as self::OUTPUT_NORMAL | self::VERBOSITY_NORMAL
     */
    public function writeln($messages, int $options = 0);

    /**
     * Sets the verbosity of the output.
     */
    public function setVerbosity(int $level);

    /**
     * Gets the current verbosity of the output.
     *
     * @return int
     */
    public function getVerbosity();

    /**
     * Returns whether verbosity is quiet (-q).
     *
     * @return bool
     */
    public function isQuiet();

    /**
     * Returns whether verbosity is verbose (-v).
     *
     * @return bool
     */
    public function isVerbose();

    /**
     * Returns whether verbosity is very verbose (-vv).
     *
     * @return bool
     */
    public function isVeryVerbose();

    /**
     * Returns whether verbosity is debug (-vvv).
     *
     * @return bool
     */
    public function isDebug();

    /**
     * Sets the decorated flag.
     */
    public function setDecorated(bool $decorated);

    /**
     * Gets the decorated flag.
     *
     * @return bool
     */
    public function isDecorated();

    public function setFormatter(OutputFormatterInterface $formatter);

    /**
     * Returns current output formatter instance.
     *
     * @return OutputFormatterInterface
     */
    public function getFormatter();
}
PKϤ$Z1���==console/Output/Output.phpnu�[���<?php

/*
 * This file is part of the Symfony package.
 *
 * (c) Fabien Potencier <fabien@symfony.com>
 *
 * For the full copyright and license information, please view the LICENSE
 * file that was distributed with this source code.
 */

namespace Symfony\Component\Console\Output;

use Symfony\Component\Console\Formatter\OutputFormatter;
use Symfony\Component\Console\Formatter\OutputFormatterInterface;

/**
 * Base class for output classes.
 *
 * There are five levels of verbosity:
 *
 *  * normal: no option passed (normal output)
 *  * verbose: -v (more output)
 *  * very verbose: -vv (highly extended output)
 *  * debug: -vvv (all debug output)
 *  * quiet: -q (no output)
 *
 * @author Fabien Potencier <fabien@symfony.com>
 */
abstract class Output implements OutputInterface
{
    private $verbosity;
    private $formatter;

    /**
     * @param int|null                      $verbosity The verbosity level (one of the VERBOSITY constants in OutputInterface)
     * @param bool                          $decorated Whether to decorate messages
     * @param OutputFormatterInterface|null $formatter Output formatter instance (null to use default OutputFormatter)
     */
    public function __construct(?int $verbosity = self::VERBOSITY_NORMAL, bool $decorated = false, OutputFormatterInterface $formatter = null)
    {
        $this->verbosity = $verbosity ?? self::VERBOSITY_NORMAL;
        $this->formatter = $formatter ?? new OutputFormatter();
        $this->formatter->setDecorated($decorated);
    }

    /**
     * {@inheritdoc}
     */
    public function setFormatter(OutputFormatterInterface $formatter)
    {
        $this->formatter = $formatter;
    }

    /**
     * {@inheritdoc}
     */
    public function getFormatter()
    {
        return $this->formatter;
    }

    /**
     * {@inheritdoc}
     */
    public function setDecorated(bool $decorated)
    {
        $this->formatter->setDecorated($decorated);
    }

    /**
     * {@inheritdoc}
     */
    public function isDecorated()
    {
        return $this->formatter->isDecorated();
    }

    /**
     * {@inheritdoc}
     */
    public function setVerbosity(int $level)
    {
        $this->verbosity = $level;
    }

    /**
     * {@inheritdoc}
     */
    public function getVerbosity()
    {
        return $this->verbosity;
    }

    /**
     * {@inheritdoc}
     */
    public function isQuiet()
    {
        return self::VERBOSITY_QUIET === $this->verbosity;
    }

    /**
     * {@inheritdoc}
     */
    public function isVerbose()
    {
        return self::VERBOSITY_VERBOSE <= $this->verbosity;
    }

    /**
     * {@inheritdoc}
     */
    public function isVeryVerbose()
    {
        return self::VERBOSITY_VERY_VERBOSE <= $this->verbosity;
    }

    /**
     * {@inheritdoc}
     */
    public function isDebug()
    {
        return self::VERBOSITY_DEBUG <= $this->verbosity;
    }

    /**
     * {@inheritdoc}
     */
    public function writeln($messages, int $options = self::OUTPUT_NORMAL)
    {
        $this->write($messages, true, $options);
    }

    /**
     * {@inheritdoc}
     */
    public function write($messages, bool $newline = false, int $options = self::OUTPUT_NORMAL)
    {
        if (!is_iterable($messages)) {
            $messages = [$messages];
        }

        $types = self::OUTPUT_NORMAL | self::OUTPUT_RAW | self::OUTPUT_PLAIN;
        $type = $types & $options ?: self::OUTPUT_NORMAL;

        $verbosities = self::VERBOSITY_QUIET | self::VERBOSITY_NORMAL | self::VERBOSITY_VERBOSE | self::VERBOSITY_VERY_VERBOSE | self::VERBOSITY_DEBUG;
        $verbosity = $verbosities & $options ?: self::VERBOSITY_NORMAL;

        if ($verbosity > $this->getVerbosity()) {
            return;
        }

        foreach ($messages as $message) {
            switch ($type) {
                case OutputInterface::OUTPUT_NORMAL:
                    $message = $this->formatter->format($message);
                    break;
                case OutputInterface::OUTPUT_RAW:
                    break;
                case OutputInterface::OUTPUT_PLAIN:
                    $message = strip_tags($this->formatter->format($message));
                    break;
            }

            $this->doWrite($message ?? '', $newline);
        }
    }

    /**
     * Writes a message to the output.
     */
    abstract protected function doWrite(string $message, bool $newline);
}
PKϤ$Za�x))console/LICENSEnu�[���Copyright (c) 2004-2022 Fabien Potencier

Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is furnished
to do so, subject to the following conditions:

The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.

THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
THE SOFTWARE.
PKϤ$Z� '�::%console/Input/InputAwareInterface.phpnu�[���<?php

/*
 * This file is part of the Symfony package.
 *
 * (c) Fabien Potencier <fabien@symfony.com>
 *
 * For the full copyright and license information, please view the LICENSE
 * file that was distributed with this source code.
 */

namespace Symfony\Component\Console\Input;

/**
 * InputAwareInterface should be implemented by classes that depends on the
 * Console Input.
 *
 * @author Wouter J <waldio.webdesign@gmail.com>
 */
interface InputAwareInterface
{
    /**
     * Sets the Console Input.
     */
    public function setInput(InputInterface $input);
}
PKϤ$Z�.�'��console/Input/ArrayInput.phpnu�[���<?php

/*
 * This file is part of the Symfony package.
 *
 * (c) Fabien Potencier <fabien@symfony.com>
 *
 * For the full copyright and license information, please view the LICENSE
 * file that was distributed with this source code.
 */

namespace Symfony\Component\Console\Input;

use Symfony\Component\Console\Exception\InvalidArgumentException;
use Symfony\Component\Console\Exception\InvalidOptionException;

/**
 * ArrayInput represents an input provided as an array.
 *
 * Usage:
 *
 *     $input = new ArrayInput(['command' => 'foo:bar', 'foo' => 'bar', '--bar' => 'foobar']);
 *
 * @author Fabien Potencier <fabien@symfony.com>
 */
class ArrayInput extends Input
{
    private $parameters;

    public function __construct(array $parameters, InputDefinition $definition = null)
    {
        $this->parameters = $parameters;

        parent::__construct($definition);
    }

    /**
     * {@inheritdoc}
     */
    public function getFirstArgument()
    {
        foreach ($this->parameters as $param => $value) {
            if ($param && \is_string($param) && '-' === $param[0]) {
                continue;
            }

            return $value;
        }

        return null;
    }

    /**
     * {@inheritdoc}
     */
    public function hasParameterOption($values, bool $onlyParams = false)
    {
        $values = (array) $values;

        foreach ($this->parameters as $k => $v) {
            if (!\is_int($k)) {
                $v = $k;
            }

            if ($onlyParams && '--' === $v) {
                return false;
            }

            if (\in_array($v, $values)) {
                return true;
            }
        }

        return false;
    }

    /**
     * {@inheritdoc}
     */
    public function getParameterOption($values, $default = false, bool $onlyParams = false)
    {
        $values = (array) $values;

        foreach ($this->parameters as $k => $v) {
            if ($onlyParams && ('--' === $k || (\is_int($k) && '--' === $v))) {
                return $default;
            }

            if (\is_int($k)) {
                if (\in_array($v, $values)) {
                    return true;
                }
            } elseif (\in_array($k, $values)) {
                return $v;
            }
        }

        return $default;
    }

    /**
     * Returns a stringified representation of the args passed to the command.
     *
     * @return string
     */
    public function __toString()
    {
        $params = [];
        foreach ($this->parameters as $param => $val) {
            if ($param && \is_string($param) && '-' === $param[0]) {
                $glue = ('-' === $param[1]) ? '=' : ' ';
                if (\is_array($val)) {
                    foreach ($val as $v) {
                        $params[] = $param.('' != $v ? $glue.$this->escapeToken($v) : '');
                    }
                } else {
                    $params[] = $param.('' != $val ? $glue.$this->escapeToken($val) : '');
                }
            } else {
                $params[] = \is_array($val) ? implode(' ', array_map([$this, 'escapeToken'], $val)) : $this->escapeToken($val);
            }
        }

        return implode(' ', $params);
    }

    /**
     * {@inheritdoc}
     */
    protected function parse()
    {
        foreach ($this->parameters as $key => $value) {
            if ('--' === $key) {
                return;
            }
            if (str_starts_with($key, '--')) {
                $this->addLongOption(substr($key, 2), $value);
            } elseif (str_starts_with($key, '-')) {
                $this->addShortOption(substr($key, 1), $value);
            } else {
                $this->addArgument($key, $value);
            }
        }
    }

    /**
     * Adds a short option value.
     *
     * @throws InvalidOptionException When option given doesn't exist
     */
    private function addShortOption(string $shortcut, $value)
    {
        if (!$this->definition->hasShortcut($shortcut)) {
            throw new InvalidOptionException(sprintf('The "-%s" option does not exist.', $shortcut));
        }

        $this->addLongOption($this->definition->getOptionForShortcut($shortcut)->getName(), $value);
    }

    /**
     * Adds a long option value.
     *
     * @throws InvalidOptionException When option given doesn't exist
     * @throws InvalidOptionException When a required value is missing
     */
    private function addLongOption(string $name, $value)
    {
        if (!$this->definition->hasOption($name)) {
            if (!$this->definition->hasNegation($name)) {
                throw new InvalidOptionException(sprintf('The "--%s" option does not exist.', $name));
            }

            $optionName = $this->definition->negationToName($name);
            $this->options[$optionName] = false;

            return;
        }

        $option = $this->definition->getOption($name);

        if (null === $value) {
            if ($option->isValueRequired()) {
                throw new InvalidOptionException(sprintf('The "--%s" option requires a value.', $name));
            }

            if (!$option->isValueOptional()) {
                $value = true;
            }
        }

        $this->options[$name] = $value;
    }

    /**
     * Adds an argument value.
     *
     * @param string|int $name  The argument name
     * @param mixed      $value The value for the argument
     *
     * @throws InvalidArgumentException When argument given doesn't exist
     */
    private function addArgument($name, $value)
    {
        if (!$this->definition->hasArgument($name)) {
            throw new InvalidArgumentException(sprintf('The "%s" argument does not exist.', $name));
        }

        $this->arguments[$name] = $value;
    }
}
PKϤ$ZK�~U}0}0console/Input/ArgvInput.phpnu�[���<?php

/*
 * This file is part of the Symfony package.
 *
 * (c) Fabien Potencier <fabien@symfony.com>
 *
 * For the full copyright and license information, please view the LICENSE
 * file that was distributed with this source code.
 */

namespace Symfony\Component\Console\Input;

use Symfony\Component\Console\Exception\RuntimeException;

/**
 * ArgvInput represents an input coming from the CLI arguments.
 *
 * Usage:
 *
 *     $input = new ArgvInput();
 *
 * By default, the `$_SERVER['argv']` array is used for the input values.
 *
 * This can be overridden by explicitly passing the input values in the constructor:
 *
 *     $input = new ArgvInput($_SERVER['argv']);
 *
 * If you pass it yourself, don't forget that the first element of the array
 * is the name of the running application.
 *
 * When passing an argument to the constructor, be sure that it respects
 * the same rules as the argv one. It's almost always better to use the
 * `StringInput` when you want to provide your own input.
 *
 * @author Fabien Potencier <fabien@symfony.com>
 *
 * @see http://www.gnu.org/software/libc/manual/html_node/Argument-Syntax.html
 * @see http://www.opengroup.org/onlinepubs/009695399/basedefs/xbd_chap12.html#tag_12_02
 */
class ArgvInput extends Input
{
    private $tokens;
    private $parsed;

    public function __construct(array $argv = null, InputDefinition $definition = null)
    {
        $argv = $argv ?? $_SERVER['argv'] ?? [];

        // strip the application name
        array_shift($argv);

        $this->tokens = $argv;

        parent::__construct($definition);
    }

    protected function setTokens(array $tokens)
    {
        $this->tokens = $tokens;
    }

    /**
     * {@inheritdoc}
     */
    protected function parse()
    {
        $parseOptions = true;
        $this->parsed = $this->tokens;
        while (null !== $token = array_shift($this->parsed)) {
            $parseOptions = $this->parseToken($token, $parseOptions);
        }
    }

    protected function parseToken(string $token, bool $parseOptions): bool
    {
        if ($parseOptions && '' == $token) {
            $this->parseArgument($token);
        } elseif ($parseOptions && '--' == $token) {
            return false;
        } elseif ($parseOptions && str_starts_with($token, '--')) {
            $this->parseLongOption($token);
        } elseif ($parseOptions && '-' === $token[0] && '-' !== $token) {
            $this->parseShortOption($token);
        } else {
            $this->parseArgument($token);
        }

        return $parseOptions;
    }

    /**
     * Parses a short option.
     */
    private function parseShortOption(string $token)
    {
        $name = substr($token, 1);

        if (\strlen($name) > 1) {
            if ($this->definition->hasShortcut($name[0]) && $this->definition->getOptionForShortcut($name[0])->acceptValue()) {
                // an option with a value (with no space)
                $this->addShortOption($name[0], substr($name, 1));
            } else {
                $this->parseShortOptionSet($name);
            }
        } else {
            $this->addShortOption($name, null);
        }
    }

    /**
     * Parses a short option set.
     *
     * @throws RuntimeException When option given doesn't exist
     */
    private function parseShortOptionSet(string $name)
    {
        $len = \strlen($name);
        for ($i = 0; $i < $len; ++$i) {
            if (!$this->definition->hasShortcut($name[$i])) {
                $encoding = mb_detect_encoding($name, null, true);
                throw new RuntimeException(sprintf('The "-%s" option does not exist.', false === $encoding ? $name[$i] : mb_substr($name, $i, 1, $encoding)));
            }

            $option = $this->definition->getOptionForShortcut($name[$i]);
            if ($option->acceptValue()) {
                $this->addLongOption($option->getName(), $i === $len - 1 ? null : substr($name, $i + 1));

                break;
            } else {
                $this->addLongOption($option->getName(), null);
            }
        }
    }

    /**
     * Parses a long option.
     */
    private function parseLongOption(string $token)
    {
        $name = substr($token, 2);

        if (false !== $pos = strpos($name, '=')) {
            if ('' === $value = substr($name, $pos + 1)) {
                array_unshift($this->parsed, $value);
            }
            $this->addLongOption(substr($name, 0, $pos), $value);
        } else {
            $this->addLongOption($name, null);
        }
    }

    /**
     * Parses an argument.
     *
     * @throws RuntimeException When too many arguments are given
     */
    private function parseArgument(string $token)
    {
        $c = \count($this->arguments);

        // if input is expecting another argument, add it
        if ($this->definition->hasArgument($c)) {
            $arg = $this->definition->getArgument($c);
            $this->arguments[$arg->getName()] = $arg->isArray() ? [$token] : $token;

        // if last argument isArray(), append token to last argument
        } elseif ($this->definition->hasArgument($c - 1) && $this->definition->getArgument($c - 1)->isArray()) {
            $arg = $this->definition->getArgument($c - 1);
            $this->arguments[$arg->getName()][] = $token;

        // unexpected argument
        } else {
            $all = $this->definition->getArguments();
            $symfonyCommandName = null;
            if (($inputArgument = $all[$key = array_key_first($all)] ?? null) && 'command' === $inputArgument->getName()) {
                $symfonyCommandName = $this->arguments['command'] ?? null;
                unset($all[$key]);
            }

            if (\count($all)) {
                if ($symfonyCommandName) {
                    $message = sprintf('Too many arguments to "%s" command, expected arguments "%s".', $symfonyCommandName, implode('" "', array_keys($all)));
                } else {
                    $message = sprintf('Too many arguments, expected arguments "%s".', implode('" "', array_keys($all)));
                }
            } elseif ($symfonyCommandName) {
                $message = sprintf('No arguments expected for "%s" command, got "%s".', $symfonyCommandName, $token);
            } else {
                $message = sprintf('No arguments expected, got "%s".', $token);
            }

            throw new RuntimeException($message);
        }
    }

    /**
     * Adds a short option value.
     *
     * @throws RuntimeException When option given doesn't exist
     */
    private function addShortOption(string $shortcut, $value)
    {
        if (!$this->definition->hasShortcut($shortcut)) {
            throw new RuntimeException(sprintf('The "-%s" option does not exist.', $shortcut));
        }

        $this->addLongOption($this->definition->getOptionForShortcut($shortcut)->getName(), $value);
    }

    /**
     * Adds a long option value.
     *
     * @throws RuntimeException When option given doesn't exist
     */
    private function addLongOption(string $name, $value)
    {
        if (!$this->definition->hasOption($name)) {
            if (!$this->definition->hasNegation($name)) {
                throw new RuntimeException(sprintf('The "--%s" option does not exist.', $name));
            }

            $optionName = $this->definition->negationToName($name);
            if (null !== $value) {
                throw new RuntimeException(sprintf('The "--%s" option does not accept a value.', $name));
            }
            $this->options[$optionName] = false;

            return;
        }

        $option = $this->definition->getOption($name);

        if (null !== $value && !$option->acceptValue()) {
            throw new RuntimeException(sprintf('The "--%s" option does not accept a value.', $name));
        }

        if (\in_array($value, ['', null], true) && $option->acceptValue() && \count($this->parsed)) {
            // if option accepts an optional or mandatory argument
            // let's see if there is one provided
            $next = array_shift($this->parsed);
            if ((isset($next[0]) && '-' !== $next[0]) || \in_array($next, ['', null], true)) {
                $value = $next;
            } else {
                array_unshift($this->parsed, $next);
            }
        }

        if (null === $value) {
            if ($option->isValueRequired()) {
                throw new RuntimeException(sprintf('The "--%s" option requires a value.', $name));
            }

            if (!$option->isArray() && !$option->isValueOptional()) {
                $value = true;
            }
        }

        if ($option->isArray()) {
            $this->options[$name][] = $value;
        } else {
            $this->options[$name] = $value;
        }
    }

    /**
     * {@inheritdoc}
     */
    public function getFirstArgument()
    {
        $isOption = false;
        foreach ($this->tokens as $i => $token) {
            if ($token && '-' === $token[0]) {
                if (str_contains($token, '=') || !isset($this->tokens[$i + 1])) {
                    continue;
                }

                // If it's a long option, consider that everything after "--" is the option name.
                // Otherwise, use the last char (if it's a short option set, only the last one can take a value with space separator)
                $name = '-' === $token[1] ? substr($token, 2) : substr($token, -1);
                if (!isset($this->options[$name]) && !$this->definition->hasShortcut($name)) {
                    // noop
                } elseif ((isset($this->options[$name]) || isset($this->options[$name = $this->definition->shortcutToName($name)])) && $this->tokens[$i + 1] === $this->options[$name]) {
                    $isOption = true;
                }

                continue;
            }

            if ($isOption) {
                $isOption = false;
                continue;
            }

            return $token;
        }

        return null;
    }

    /**
     * {@inheritdoc}
     */
    public function hasParameterOption($values, bool $onlyParams = false)
    {
        $values = (array) $values;

        foreach ($this->tokens as $token) {
            if ($onlyParams && '--' === $token) {
                return false;
            }
            foreach ($values as $value) {
                // Options with values:
                //   For long options, test for '--option=' at beginning
                //   For short options, test for '-o' at beginning
                $leading = str_starts_with($value, '--') ? $value.'=' : $value;
                if ($token === $value || '' !== $leading && str_starts_with($token, $leading)) {
                    return true;
                }
            }
        }

        return false;
    }

    /**
     * {@inheritdoc}
     */
    public function getParameterOption($values, $default = false, bool $onlyParams = false)
    {
        $values = (array) $values;
        $tokens = $this->tokens;

        while (0 < \count($tokens)) {
            $token = array_shift($tokens);
            if ($onlyParams && '--' === $token) {
                return $default;
            }

            foreach ($values as $value) {
                if ($token === $value) {
                    return array_shift($tokens);
                }
                // Options with values:
                //   For long options, test for '--option=' at beginning
                //   For short options, test for '-o' at beginning
                $leading = str_starts_with($value, '--') ? $value.'=' : $value;
                if ('' !== $leading && str_starts_with($token, $leading)) {
                    return substr($token, \strlen($leading));
                }
            }
        }

        return $default;
    }

    /**
     * Returns a stringified representation of the args passed to the command.
     *
     * @return string
     */
    public function __toString()
    {
        $tokens = array_map(function ($token) {
            if (preg_match('{^(-[^=]+=)(.+)}', $token, $match)) {
                return $match[1].$this->escapeToken($match[2]);
            }

            if ($token && '-' !== $token[0]) {
                return $this->escapeToken($token);
            }

            return $token;
        }, $this->tokens);

        return implode(' ', $tokens);
    }
}
PKϤ$Z��console/Input/Input.phpnu�[���<?php

/*
 * This file is part of the Symfony package.
 *
 * (c) Fabien Potencier <fabien@symfony.com>
 *
 * For the full copyright and license information, please view the LICENSE
 * file that was distributed with this source code.
 */

namespace Symfony\Component\Console\Input;

use Symfony\Component\Console\Exception\InvalidArgumentException;
use Symfony\Component\Console\Exception\RuntimeException;

/**
 * Input is the base class for all concrete Input classes.
 *
 * Three concrete classes are provided by default:
 *
 *  * `ArgvInput`: The input comes from the CLI arguments (argv)
 *  * `StringInput`: The input is provided as a string
 *  * `ArrayInput`: The input is provided as an array
 *
 * @author Fabien Potencier <fabien@symfony.com>
 */
abstract class Input implements InputInterface, StreamableInputInterface
{
    protected $definition;
    protected $stream;
    protected $options = [];
    protected $arguments = [];
    protected $interactive = true;

    public function __construct(InputDefinition $definition = null)
    {
        if (null === $definition) {
            $this->definition = new InputDefinition();
        } else {
            $this->bind($definition);
            $this->validate();
        }
    }

    /**
     * {@inheritdoc}
     */
    public function bind(InputDefinition $definition)
    {
        $this->arguments = [];
        $this->options = [];
        $this->definition = $definition;

        $this->parse();
    }

    /**
     * Processes command line arguments.
     */
    abstract protected function parse();

    /**
     * {@inheritdoc}
     */
    public function validate()
    {
        $definition = $this->definition;
        $givenArguments = $this->arguments;

        $missingArguments = array_filter(array_keys($definition->getArguments()), function ($argument) use ($definition, $givenArguments) {
            return !\array_key_exists($argument, $givenArguments) && $definition->getArgument($argument)->isRequired();
        });

        if (\count($missingArguments) > 0) {
            throw new RuntimeException(sprintf('Not enough arguments (missing: "%s").', implode(', ', $missingArguments)));
        }
    }

    /**
     * {@inheritdoc}
     */
    public function isInteractive()
    {
        return $this->interactive;
    }

    /**
     * {@inheritdoc}
     */
    public function setInteractive(bool $interactive)
    {
        $this->interactive = $interactive;
    }

    /**
     * {@inheritdoc}
     */
    public function getArguments()
    {
        return array_merge($this->definition->getArgumentDefaults(), $this->arguments);
    }

    /**
     * {@inheritdoc}
     */
    public function getArgument(string $name)
    {
        if (!$this->definition->hasArgument($name)) {
            throw new InvalidArgumentException(sprintf('The "%s" argument does not exist.', $name));
        }

        return $this->arguments[$name] ?? $this->definition->getArgument($name)->getDefault();
    }

    /**
     * {@inheritdoc}
     */
    public function setArgument(string $name, $value)
    {
        if (!$this->definition->hasArgument($name)) {
            throw new InvalidArgumentException(sprintf('The "%s" argument does not exist.', $name));
        }

        $this->arguments[$name] = $value;
    }

    /**
     * {@inheritdoc}
     */
    public function hasArgument(string $name)
    {
        return $this->definition->hasArgument($name);
    }

    /**
     * {@inheritdoc}
     */
    public function getOptions()
    {
        return array_merge($this->definition->getOptionDefaults(), $this->options);
    }

    /**
     * {@inheritdoc}
     */
    public function getOption(string $name)
    {
        if ($this->definition->hasNegation($name)) {
            if (null === $value = $this->getOption($this->definition->negationToName($name))) {
                return $value;
            }

            return !$value;
        }

        if (!$this->definition->hasOption($name)) {
            throw new InvalidArgumentException(sprintf('The "%s" option does not exist.', $name));
        }

        return \array_key_exists($name, $this->options) ? $this->options[$name] : $this->definition->getOption($name)->getDefault();
    }

    /**
     * {@inheritdoc}
     */
    public function setOption(string $name, $value)
    {
        if ($this->definition->hasNegation($name)) {
            $this->options[$this->definition->negationToName($name)] = !$value;

            return;
        } elseif (!$this->definition->hasOption($name)) {
            throw new InvalidArgumentException(sprintf('The "%s" option does not exist.', $name));
        }

        $this->options[$name] = $value;
    }

    /**
     * {@inheritdoc}
     */
    public function hasOption(string $name)
    {
        return $this->definition->hasOption($name) || $this->definition->hasNegation($name);
    }

    /**
     * Escapes a token through escapeshellarg if it contains unsafe chars.
     *
     * @return string
     */
    public function escapeToken(string $token)
    {
        return preg_match('{^[\w-]+$}', $token) ? $token : escapeshellarg($token);
    }

    /**
     * {@inheritdoc}
     */
    public function setStream($stream)
    {
        $this->stream = $stream;
    }

    /**
     * {@inheritdoc}
     */
    public function getStream()
    {
        return $this->stream;
    }
}
PKϤ$Z���.�.!console/Input/InputDefinition.phpnu�[���<?php

/*
 * This file is part of the Symfony package.
 *
 * (c) Fabien Potencier <fabien@symfony.com>
 *
 * For the full copyright and license information, please view the LICENSE
 * file that was distributed with this source code.
 */

namespace Symfony\Component\Console\Input;

use Symfony\Component\Console\Exception\InvalidArgumentException;
use Symfony\Component\Console\Exception\LogicException;

/**
 * A InputDefinition represents a set of valid command line arguments and options.
 *
 * Usage:
 *
 *     $definition = new InputDefinition([
 *         new InputArgument('name', InputArgument::REQUIRED),
 *         new InputOption('foo', 'f', InputOption::VALUE_REQUIRED),
 *     ]);
 *
 * @author Fabien Potencier <fabien@symfony.com>
 */
class InputDefinition
{
    private $arguments;
    private $requiredCount;
    private $lastArrayArgument;
    private $lastOptionalArgument;
    private $options;
    private $negations;
    private $shortcuts;

    /**
     * @param array $definition An array of InputArgument and InputOption instance
     */
    public function __construct(array $definition = [])
    {
        $this->setDefinition($definition);
    }

    /**
     * Sets the definition of the input.
     */
    public function setDefinition(array $definition)
    {
        $arguments = [];
        $options = [];
        foreach ($definition as $item) {
            if ($item instanceof InputOption) {
                $options[] = $item;
            } else {
                $arguments[] = $item;
            }
        }

        $this->setArguments($arguments);
        $this->setOptions($options);
    }

    /**
     * Sets the InputArgument objects.
     *
     * @param InputArgument[] $arguments An array of InputArgument objects
     */
    public function setArguments(array $arguments = [])
    {
        $this->arguments = [];
        $this->requiredCount = 0;
        $this->lastOptionalArgument = null;
        $this->lastArrayArgument = null;
        $this->addArguments($arguments);
    }

    /**
     * Adds an array of InputArgument objects.
     *
     * @param InputArgument[] $arguments An array of InputArgument objects
     */
    public function addArguments(?array $arguments = [])
    {
        if (null !== $arguments) {
            foreach ($arguments as $argument) {
                $this->addArgument($argument);
            }
        }
    }

    /**
     * @throws LogicException When incorrect argument is given
     */
    public function addArgument(InputArgument $argument)
    {
        if (isset($this->arguments[$argument->getName()])) {
            throw new LogicException(sprintf('An argument with name "%s" already exists.', $argument->getName()));
        }

        if (null !== $this->lastArrayArgument) {
            throw new LogicException(sprintf('Cannot add a required argument "%s" after an array argument "%s".', $argument->getName(), $this->lastArrayArgument->getName()));
        }

        if ($argument->isRequired() && null !== $this->lastOptionalArgument) {
            throw new LogicException(sprintf('Cannot add a required argument "%s" after an optional one "%s".', $argument->getName(), $this->lastOptionalArgument->getName()));
        }

        if ($argument->isArray()) {
            $this->lastArrayArgument = $argument;
        }

        if ($argument->isRequired()) {
            ++$this->requiredCount;
        } else {
            $this->lastOptionalArgument = $argument;
        }

        $this->arguments[$argument->getName()] = $argument;
    }

    /**
     * Returns an InputArgument by name or by position.
     *
     * @param string|int $name The InputArgument name or position
     *
     * @return InputArgument
     *
     * @throws InvalidArgumentException When argument given doesn't exist
     */
    public function getArgument($name)
    {
        if (!$this->hasArgument($name)) {
            throw new InvalidArgumentException(sprintf('The "%s" argument does not exist.', $name));
        }

        $arguments = \is_int($name) ? array_values($this->arguments) : $this->arguments;

        return $arguments[$name];
    }

    /**
     * Returns true if an InputArgument object exists by name or position.
     *
     * @param string|int $name The InputArgument name or position
     *
     * @return bool
     */
    public function hasArgument($name)
    {
        $arguments = \is_int($name) ? array_values($this->arguments) : $this->arguments;

        return isset($arguments[$name]);
    }

    /**
     * Gets the array of InputArgument objects.
     *
     * @return InputArgument[]
     */
    public function getArguments()
    {
        return $this->arguments;
    }

    /**
     * Returns the number of InputArguments.
     *
     * @return int
     */
    public function getArgumentCount()
    {
        return null !== $this->lastArrayArgument ? \PHP_INT_MAX : \count($this->arguments);
    }

    /**
     * Returns the number of required InputArguments.
     *
     * @return int
     */
    public function getArgumentRequiredCount()
    {
        return $this->requiredCount;
    }

    /**
     * @return array<string|bool|int|float|array|null>
     */
    public function getArgumentDefaults()
    {
        $values = [];
        foreach ($this->arguments as $argument) {
            $values[$argument->getName()] = $argument->getDefault();
        }

        return $values;
    }

    /**
     * Sets the InputOption objects.
     *
     * @param InputOption[] $options An array of InputOption objects
     */
    public function setOptions(array $options = [])
    {
        $this->options = [];
        $this->shortcuts = [];
        $this->negations = [];
        $this->addOptions($options);
    }

    /**
     * Adds an array of InputOption objects.
     *
     * @param InputOption[] $options An array of InputOption objects
     */
    public function addOptions(array $options = [])
    {
        foreach ($options as $option) {
            $this->addOption($option);
        }
    }

    /**
     * @throws LogicException When option given already exist
     */
    public function addOption(InputOption $option)
    {
        if (isset($this->options[$option->getName()]) && !$option->equals($this->options[$option->getName()])) {
            throw new LogicException(sprintf('An option named "%s" already exists.', $option->getName()));
        }
        if (isset($this->negations[$option->getName()])) {
            throw new LogicException(sprintf('An option named "%s" already exists.', $option->getName()));
        }

        if ($option->getShortcut()) {
            foreach (explode('|', $option->getShortcut()) as $shortcut) {
                if (isset($this->shortcuts[$shortcut]) && !$option->equals($this->options[$this->shortcuts[$shortcut]])) {
                    throw new LogicException(sprintf('An option with shortcut "%s" already exists.', $shortcut));
                }
            }
        }

        $this->options[$option->getName()] = $option;
        if ($option->getShortcut()) {
            foreach (explode('|', $option->getShortcut()) as $shortcut) {
                $this->shortcuts[$shortcut] = $option->getName();
            }
        }

        if ($option->isNegatable()) {
            $negatedName = 'no-'.$option->getName();
            if (isset($this->options[$negatedName])) {
                throw new LogicException(sprintf('An option named "%s" already exists.', $negatedName));
            }
            $this->negations[$negatedName] = $option->getName();
        }
    }

    /**
     * Returns an InputOption by name.
     *
     * @return InputOption
     *
     * @throws InvalidArgumentException When option given doesn't exist
     */
    public function getOption(string $name)
    {
        if (!$this->hasOption($name)) {
            throw new InvalidArgumentException(sprintf('The "--%s" option does not exist.', $name));
        }

        return $this->options[$name];
    }

    /**
     * Returns true if an InputOption object exists by name.
     *
     * This method can't be used to check if the user included the option when
     * executing the command (use getOption() instead).
     *
     * @return bool
     */
    public function hasOption(string $name)
    {
        return isset($this->options[$name]);
    }

    /**
     * Gets the array of InputOption objects.
     *
     * @return InputOption[]
     */
    public function getOptions()
    {
        return $this->options;
    }

    /**
     * Returns true if an InputOption object exists by shortcut.
     *
     * @return bool
     */
    public function hasShortcut(string $name)
    {
        return isset($this->shortcuts[$name]);
    }

    /**
     * Returns true if an InputOption object exists by negated name.
     */
    public function hasNegation(string $name): bool
    {
        return isset($this->negations[$name]);
    }

    /**
     * Gets an InputOption by shortcut.
     *
     * @return InputOption
     */
    public function getOptionForShortcut(string $shortcut)
    {
        return $this->getOption($this->shortcutToName($shortcut));
    }

    /**
     * @return array<string|bool|int|float|array|null>
     */
    public function getOptionDefaults()
    {
        $values = [];
        foreach ($this->options as $option) {
            $values[$option->getName()] = $option->getDefault();
        }

        return $values;
    }

    /**
     * Returns the InputOption name given a shortcut.
     *
     * @throws InvalidArgumentException When option given does not exist
     *
     * @internal
     */
    public function shortcutToName(string $shortcut): string
    {
        if (!isset($this->shortcuts[$shortcut])) {
            throw new InvalidArgumentException(sprintf('The "-%s" option does not exist.', $shortcut));
        }

        return $this->shortcuts[$shortcut];
    }

    /**
     * Returns the InputOption name given a negation.
     *
     * @throws InvalidArgumentException When option given does not exist
     *
     * @internal
     */
    public function negationToName(string $negation): string
    {
        if (!isset($this->negations[$negation])) {
            throw new InvalidArgumentException(sprintf('The "--%s" option does not exist.', $negation));
        }

        return $this->negations[$negation];
    }

    /**
     * Gets the synopsis.
     *
     * @return string
     */
    public function getSynopsis(bool $short = false)
    {
        $elements = [];

        if ($short && $this->getOptions()) {
            $elements[] = '[options]';
        } elseif (!$short) {
            foreach ($this->getOptions() as $option) {
                $value = '';
                if ($option->acceptValue()) {
                    $value = sprintf(
                        ' %s%s%s',
                        $option->isValueOptional() ? '[' : '',
                        strtoupper($option->getName()),
                        $option->isValueOptional() ? ']' : ''
                    );
                }

                $shortcut = $option->getShortcut() ? sprintf('-%s|', $option->getShortcut()) : '';
                $negation = $option->isNegatable() ? sprintf('|--no-%s', $option->getName()) : '';
                $elements[] = sprintf('[%s--%s%s%s]', $shortcut, $option->getName(), $value, $negation);
            }
        }

        if (\count($elements) && $this->getArguments()) {
            $elements[] = '[--]';
        }

        $tail = '';
        foreach ($this->getArguments() as $argument) {
            $element = '<'.$argument->getName().'>';
            if ($argument->isArray()) {
                $element .= '...';
            }

            if (!$argument->isRequired()) {
                $element = '['.$element;
                $tail .= ']';
            }

            $elements[] = $element;
        }

        return implode(' ', $elements).$tail;
    }
}
PKϤ$Z���U
U
console/Input/InputArgument.phpnu�[���<?php

/*
 * This file is part of the Symfony package.
 *
 * (c) Fabien Potencier <fabien@symfony.com>
 *
 * For the full copyright and license information, please view the LICENSE
 * file that was distributed with this source code.
 */

namespace Symfony\Component\Console\Input;

use Symfony\Component\Console\Exception\InvalidArgumentException;
use Symfony\Component\Console\Exception\LogicException;

/**
 * Represents a command line argument.
 *
 * @author Fabien Potencier <fabien@symfony.com>
 */
class InputArgument
{
    public const REQUIRED = 1;
    public const OPTIONAL = 2;
    public const IS_ARRAY = 4;

    private $name;
    private $mode;
    private $default;
    private $description;

    /**
     * @param string                           $name        The argument name
     * @param int|null                         $mode        The argument mode: self::REQUIRED or self::OPTIONAL
     * @param string                           $description A description text
     * @param string|bool|int|float|array|null $default     The default value (for self::OPTIONAL mode only)
     *
     * @throws InvalidArgumentException When argument mode is not valid
     */
    public function __construct(string $name, int $mode = null, string $description = '', $default = null)
    {
        if (null === $mode) {
            $mode = self::OPTIONAL;
        } elseif ($mode > 7 || $mode < 1) {
            throw new InvalidArgumentException(sprintf('Argument mode "%s" is not valid.', $mode));
        }

        $this->name = $name;
        $this->mode = $mode;
        $this->description = $description;

        $this->setDefault($default);
    }

    /**
     * Returns the argument name.
     *
     * @return string
     */
    public function getName()
    {
        return $this->name;
    }

    /**
     * Returns true if the argument is required.
     *
     * @return bool true if parameter mode is self::REQUIRED, false otherwise
     */
    public function isRequired()
    {
        return self::REQUIRED === (self::REQUIRED & $this->mode);
    }

    /**
     * Returns true if the argument can take multiple values.
     *
     * @return bool true if mode is self::IS_ARRAY, false otherwise
     */
    public function isArray()
    {
        return self::IS_ARRAY === (self::IS_ARRAY & $this->mode);
    }

    /**
     * Sets the default value.
     *
     * @param string|bool|int|float|array|null $default
     *
     * @throws LogicException When incorrect default value is given
     */
    public function setDefault($default = null)
    {
        if ($this->isRequired() && null !== $default) {
            throw new LogicException('Cannot set a default value except for InputArgument::OPTIONAL mode.');
        }

        if ($this->isArray()) {
            if (null === $default) {
                $default = [];
            } elseif (!\is_array($default)) {
                throw new LogicException('A default value for an array argument must be an array.');
            }
        }

        $this->default = $default;
    }

    /**
     * Returns the default value.
     *
     * @return string|bool|int|float|array|null
     */
    public function getDefault()
    {
        return $this->default;
    }

    /**
     * Returns the description text.
     *
     * @return string
     */
    public function getDescription()
    {
        return $this->description;
    }
}
PKϤ$ZT�UUconsole/Input/InputOption.phpnu�[���<?php

/*
 * This file is part of the Symfony package.
 *
 * (c) Fabien Potencier <fabien@symfony.com>
 *
 * For the full copyright and license information, please view the LICENSE
 * file that was distributed with this source code.
 */

namespace Symfony\Component\Console\Input;

use Symfony\Component\Console\Exception\InvalidArgumentException;
use Symfony\Component\Console\Exception\LogicException;

/**
 * Represents a command line option.
 *
 * @author Fabien Potencier <fabien@symfony.com>
 */
class InputOption
{
    /**
     * Do not accept input for the option (e.g. --yell). This is the default behavior of options.
     */
    public const VALUE_NONE = 1;

    /**
     * A value must be passed when the option is used (e.g. --iterations=5 or -i5).
     */
    public const VALUE_REQUIRED = 2;

    /**
     * The option may or may not have a value (e.g. --yell or --yell=loud).
     */
    public const VALUE_OPTIONAL = 4;

    /**
     * The option accepts multiple values (e.g. --dir=/foo --dir=/bar).
     */
    public const VALUE_IS_ARRAY = 8;

    /**
     * The option may have either positive or negative value (e.g. --ansi or --no-ansi).
     */
    public const VALUE_NEGATABLE = 16;

    private $name;
    private $shortcut;
    private $mode;
    private $default;
    private $description;

    /**
     * @param string|array|null                $shortcut The shortcuts, can be null, a string of shortcuts delimited by | or an array of shortcuts
     * @param int|null                         $mode     The option mode: One of the VALUE_* constants
     * @param string|bool|int|float|array|null $default  The default value (must be null for self::VALUE_NONE)
     *
     * @throws InvalidArgumentException If option mode is invalid or incompatible
     */
    public function __construct(string $name, $shortcut = null, int $mode = null, string $description = '', $default = null)
    {
        if (str_starts_with($name, '--')) {
            $name = substr($name, 2);
        }

        if (empty($name)) {
            throw new InvalidArgumentException('An option name cannot be empty.');
        }

        if (empty($shortcut)) {
            $shortcut = null;
        }

        if (null !== $shortcut) {
            if (\is_array($shortcut)) {
                $shortcut = implode('|', $shortcut);
            }
            $shortcuts = preg_split('{(\|)-?}', ltrim($shortcut, '-'));
            $shortcuts = array_filter($shortcuts);
            $shortcut = implode('|', $shortcuts);

            if (empty($shortcut)) {
                throw new InvalidArgumentException('An option shortcut cannot be empty.');
            }
        }

        if (null === $mode) {
            $mode = self::VALUE_NONE;
        } elseif ($mode >= (self::VALUE_NEGATABLE << 1) || $mode < 1) {
            throw new InvalidArgumentException(sprintf('Option mode "%s" is not valid.', $mode));
        }

        $this->name = $name;
        $this->shortcut = $shortcut;
        $this->mode = $mode;
        $this->description = $description;

        if ($this->isArray() && !$this->acceptValue()) {
            throw new InvalidArgumentException('Impossible to have an option mode VALUE_IS_ARRAY if the option does not accept a value.');
        }
        if ($this->isNegatable() && $this->acceptValue()) {
            throw new InvalidArgumentException('Impossible to have an option mode VALUE_NEGATABLE if the option also accepts a value.');
        }

        $this->setDefault($default);
    }

    /**
     * Returns the option shortcut.
     *
     * @return string|null
     */
    public function getShortcut()
    {
        return $this->shortcut;
    }

    /**
     * Returns the option name.
     *
     * @return string
     */
    public function getName()
    {
        return $this->name;
    }

    /**
     * Returns true if the option accepts a value.
     *
     * @return bool true if value mode is not self::VALUE_NONE, false otherwise
     */
    public function acceptValue()
    {
        return $this->isValueRequired() || $this->isValueOptional();
    }

    /**
     * Returns true if the option requires a value.
     *
     * @return bool true if value mode is self::VALUE_REQUIRED, false otherwise
     */
    public function isValueRequired()
    {
        return self::VALUE_REQUIRED === (self::VALUE_REQUIRED & $this->mode);
    }

    /**
     * Returns true if the option takes an optional value.
     *
     * @return bool true if value mode is self::VALUE_OPTIONAL, false otherwise
     */
    public function isValueOptional()
    {
        return self::VALUE_OPTIONAL === (self::VALUE_OPTIONAL & $this->mode);
    }

    /**
     * Returns true if the option can take multiple values.
     *
     * @return bool true if mode is self::VALUE_IS_ARRAY, false otherwise
     */
    public function isArray()
    {
        return self::VALUE_IS_ARRAY === (self::VALUE_IS_ARRAY & $this->mode);
    }

    public function isNegatable(): bool
    {
        return self::VALUE_NEGATABLE === (self::VALUE_NEGATABLE & $this->mode);
    }

    /**
     * @param string|bool|int|float|array|null $default
     */
    public function setDefault($default = null)
    {
        if (self::VALUE_NONE === (self::VALUE_NONE & $this->mode) && null !== $default) {
            throw new LogicException('Cannot set a default value when using InputOption::VALUE_NONE mode.');
        }

        if ($this->isArray()) {
            if (null === $default) {
                $default = [];
            } elseif (!\is_array($default)) {
                throw new LogicException('A default value for an array option must be an array.');
            }
        }

        $this->default = $this->acceptValue() || $this->isNegatable() ? $default : false;
    }

    /**
     * Returns the default value.
     *
     * @return string|bool|int|float|array|null
     */
    public function getDefault()
    {
        return $this->default;
    }

    /**
     * Returns the description text.
     *
     * @return string
     */
    public function getDescription()
    {
        return $this->description;
    }

    /**
     * Checks whether the given option equals this one.
     *
     * @return bool
     */
    public function equals(self $option)
    {
        return $option->getName() === $this->getName()
            && $option->getShortcut() === $this->getShortcut()
            && $option->getDefault() === $this->getDefault()
            && $option->isNegatable() === $this->isNegatable()
            && $option->isArray() === $this->isArray()
            && $option->isValueRequired() === $this->isValueRequired()
            && $option->isValueOptional() === $this->isValueOptional()
        ;
    }
}
PKϤ$ZH�?�
�
console/Input/StringInput.phpnu�[���<?php

/*
 * This file is part of the Symfony package.
 *
 * (c) Fabien Potencier <fabien@symfony.com>
 *
 * For the full copyright and license information, please view the LICENSE
 * file that was distributed with this source code.
 */

namespace Symfony\Component\Console\Input;

use Symfony\Component\Console\Exception\InvalidArgumentException;

/**
 * StringInput represents an input provided as a string.
 *
 * Usage:
 *
 *     $input = new StringInput('foo --bar="foobar"');
 *
 * @author Fabien Potencier <fabien@symfony.com>
 */
class StringInput extends ArgvInput
{
    public const REGEX_STRING = '([^\s]+?)(?:\s|(?<!\\\\)"|(?<!\\\\)\'|$)';
    public const REGEX_UNQUOTED_STRING = '([^\s\\\\]+?)';
    public const REGEX_QUOTED_STRING = '(?:"([^"\\\\]*(?:\\\\.[^"\\\\]*)*)"|\'([^\'\\\\]*(?:\\\\.[^\'\\\\]*)*)\')';

    /**
     * @param string $input A string representing the parameters from the CLI
     */
    public function __construct(string $input)
    {
        parent::__construct([]);

        $this->setTokens($this->tokenize($input));
    }

    /**
     * Tokenizes a string.
     *
     * @throws InvalidArgumentException When unable to parse input (should never happen)
     */
    private function tokenize(string $input): array
    {
        $tokens = [];
        $length = \strlen($input);
        $cursor = 0;
        $token = null;
        while ($cursor < $length) {
            if ('\\' === $input[$cursor]) {
                $token .= $input[++$cursor] ?? '';
                ++$cursor;
                continue;
            }

            if (preg_match('/\s+/A', $input, $match, 0, $cursor)) {
                if (null !== $token) {
                    $tokens[] = $token;
                    $token = null;
                }
            } elseif (preg_match('/([^="\'\s]+?)(=?)('.self::REGEX_QUOTED_STRING.'+)/A', $input, $match, 0, $cursor)) {
                $token .= $match[1].$match[2].stripcslashes(str_replace(['"\'', '\'"', '\'\'', '""'], '', substr($match[3], 1, -1)));
            } elseif (preg_match('/'.self::REGEX_QUOTED_STRING.'/A', $input, $match, 0, $cursor)) {
                $token .= stripcslashes(substr($match[0], 1, -1));
            } elseif (preg_match('/'.self::REGEX_UNQUOTED_STRING.'/A', $input, $match, 0, $cursor)) {
                $token .= $match[1];
            } else {
                // should never happen
                throw new InvalidArgumentException(sprintf('Unable to parse input near "... %s ...".', substr($input, $cursor, 10)));
            }

            $cursor += \strlen($match[0]);
        }

        if (null !== $token) {
            $tokens[] = $token;
        }

        return $tokens;
    }
}
PKϤ$Z���ii*console/Input/StreamableInputInterface.phpnu�[���<?php

/*
 * This file is part of the Symfony package.
 *
 * (c) Fabien Potencier <fabien@symfony.com>
 *
 * For the full copyright and license information, please view the LICENSE
 * file that was distributed with this source code.
 */

namespace Symfony\Component\Console\Input;

/**
 * StreamableInputInterface is the interface implemented by all input classes
 * that have an input stream.
 *
 * @author Robin Chalas <robin.chalas@gmail.com>
 */
interface StreamableInputInterface extends InputInterface
{
    /**
     * Sets the input stream to read from when interacting with the user.
     *
     * This is mainly useful for testing purpose.
     *
     * @param resource $stream The input stream
     */
    public function setStream($stream);

    /**
     * Returns the input stream.
     *
     * @return resource|null
     */
    public function getStream();
}
PKϤ$Z�Ӿ}mm console/Input/InputInterface.phpnu�[���<?php

/*
 * This file is part of the Symfony package.
 *
 * (c) Fabien Potencier <fabien@symfony.com>
 *
 * For the full copyright and license information, please view the LICENSE
 * file that was distributed with this source code.
 */

namespace Symfony\Component\Console\Input;

use Symfony\Component\Console\Exception\InvalidArgumentException;
use Symfony\Component\Console\Exception\RuntimeException;

/**
 * InputInterface is the interface implemented by all input classes.
 *
 * @author Fabien Potencier <fabien@symfony.com>
 */
interface InputInterface
{
    /**
     * Returns the first argument from the raw parameters (not parsed).
     *
     * @return string|null
     */
    public function getFirstArgument();

    /**
     * Returns true if the raw parameters (not parsed) contain a value.
     *
     * This method is to be used to introspect the input parameters
     * before they have been validated. It must be used carefully.
     * Does not necessarily return the correct result for short options
     * when multiple flags are combined in the same option.
     *
     * @param string|array $values     The values to look for in the raw parameters (can be an array)
     * @param bool         $onlyParams Only check real parameters, skip those following an end of options (--) signal
     *
     * @return bool
     */
    public function hasParameterOption($values, bool $onlyParams = false);

    /**
     * Returns the value of a raw option (not parsed).
     *
     * This method is to be used to introspect the input parameters
     * before they have been validated. It must be used carefully.
     * Does not necessarily return the correct result for short options
     * when multiple flags are combined in the same option.
     *
     * @param string|array                     $values     The value(s) to look for in the raw parameters (can be an array)
     * @param string|bool|int|float|array|null $default    The default value to return if no result is found
     * @param bool                             $onlyParams Only check real parameters, skip those following an end of options (--) signal
     *
     * @return mixed
     */
    public function getParameterOption($values, $default = false, bool $onlyParams = false);

    /**
     * Binds the current Input instance with the given arguments and options.
     *
     * @throws RuntimeException
     */
    public function bind(InputDefinition $definition);

    /**
     * Validates the input.
     *
     * @throws RuntimeException When not enough arguments are given
     */
    public function validate();

    /**
     * Returns all the given arguments merged with the default values.
     *
     * @return array<string|bool|int|float|array|null>
     */
    public function getArguments();

    /**
     * Returns the argument value for a given argument name.
     *
     * @return mixed
     *
     * @throws InvalidArgumentException When argument given doesn't exist
     */
    public function getArgument(string $name);

    /**
     * Sets an argument value by name.
     *
     * @param mixed $value The argument value
     *
     * @throws InvalidArgumentException When argument given doesn't exist
     */
    public function setArgument(string $name, $value);

    /**
     * Returns true if an InputArgument object exists by name or position.
     *
     * @return bool
     */
    public function hasArgument(string $name);

    /**
     * Returns all the given options merged with the default values.
     *
     * @return array<string|bool|int|float|array|null>
     */
    public function getOptions();

    /**
     * Returns the option value for a given option name.
     *
     * @return mixed
     *
     * @throws InvalidArgumentException When option given doesn't exist
     */
    public function getOption(string $name);

    /**
     * Sets an option value by name.
     *
     * @param mixed $value The option value
     *
     * @throws InvalidArgumentException When option given doesn't exist
     */
    public function setOption(string $name, $value);

    /**
     * Returns true if an InputOption object exists by name.
     *
     * @return bool
     */
    public function hasOption(string $name);

    /**
     * Is this input means interactive?
     *
     * @return bool
     */
    public function isInteractive();

    /**
     * Sets the input interactivity.
     */
    public function setInteractive(bool $interactive);
}
PKϤ$ZF�(rrconsole/Terminal.phpnu�[���<?php

/*
 * This file is part of the Symfony package.
 *
 * (c) Fabien Potencier <fabien@symfony.com>
 *
 * For the full copyright and license information, please view the LICENSE
 * file that was distributed with this source code.
 */

namespace Symfony\Component\Console;

class Terminal
{
    private static $width;
    private static $height;
    private static $stty;

    /**
     * Gets the terminal width.
     *
     * @return int
     */
    public function getWidth()
    {
        $width = getenv('COLUMNS');
        if (false !== $width) {
            return (int) trim($width);
        }

        if (null === self::$width) {
            self::initDimensions();
        }

        return self::$width ?: 80;
    }

    /**
     * Gets the terminal height.
     *
     * @return int
     */
    public function getHeight()
    {
        $height = getenv('LINES');
        if (false !== $height) {
            return (int) trim($height);
        }

        if (null === self::$height) {
            self::initDimensions();
        }

        return self::$height ?: 50;
    }

    /**
     * @internal
     */
    public static function hasSttyAvailable(): bool
    {
        if (null !== self::$stty) {
            return self::$stty;
        }

        // skip check if exec function is disabled
        if (!\function_exists('exec')) {
            return false;
        }

        exec('stty 2>&1', $output, $exitcode);

        return self::$stty = 0 === $exitcode;
    }

    private static function initDimensions()
    {
        if ('\\' === \DIRECTORY_SEPARATOR) {
            if (preg_match('/^(\d+)x(\d+)(?: \((\d+)x(\d+)\))?$/', trim(getenv('ANSICON')), $matches)) {
                // extract [w, H] from "wxh (WxH)"
                // or [w, h] from "wxh"
                self::$width = (int) $matches[1];
                self::$height = isset($matches[4]) ? (int) $matches[4] : (int) $matches[2];
            } elseif (!self::hasVt100Support() && self::hasSttyAvailable()) {
                // only use stty on Windows if the terminal does not support vt100 (e.g. Windows 7 + git-bash)
                // testing for stty in a Windows 10 vt100-enabled console will implicitly disable vt100 support on STDOUT
                self::initDimensionsUsingStty();
            } elseif (null !== $dimensions = self::getConsoleMode()) {
                // extract [w, h] from "wxh"
                self::$width = (int) $dimensions[0];
                self::$height = (int) $dimensions[1];
            }
        } else {
            self::initDimensionsUsingStty();
        }
    }

    /**
     * Returns whether STDOUT has vt100 support (some Windows 10+ configurations).
     */
    private static function hasVt100Support(): bool
    {
        return \function_exists('sapi_windows_vt100_support') && sapi_windows_vt100_support(fopen('php://stdout', 'w'));
    }

    /**
     * Initializes dimensions using the output of an stty columns line.
     */
    private static function initDimensionsUsingStty()
    {
        if ($sttyString = self::getSttyColumns()) {
            if (preg_match('/rows.(\d+);.columns.(\d+);/i', $sttyString, $matches)) {
                // extract [w, h] from "rows h; columns w;"
                self::$width = (int) $matches[2];
                self::$height = (int) $matches[1];
            } elseif (preg_match('/;.(\d+).rows;.(\d+).columns/i', $sttyString, $matches)) {
                // extract [w, h] from "; h rows; w columns"
                self::$width = (int) $matches[2];
                self::$height = (int) $matches[1];
            }
        }
    }

    /**
     * Runs and parses mode CON if it's available, suppressing any error output.
     *
     * @return int[]|null An array composed of the width and the height or null if it could not be parsed
     */
    private static function getConsoleMode(): ?array
    {
        $info = self::readFromProcess('mode CON');

        if (null === $info || !preg_match('/--------+\r?\n.+?(\d+)\r?\n.+?(\d+)\r?\n/', $info, $matches)) {
            return null;
        }

        return [(int) $matches[2], (int) $matches[1]];
    }

    /**
     * Runs and parses stty -a if it's available, suppressing any error output.
     */
    private static function getSttyColumns(): ?string
    {
        return self::readFromProcess('stty -a | grep columns');
    }

    private static function readFromProcess(string $command): ?string
    {
        if (!\function_exists('proc_open')) {
            return null;
        }

        $descriptorspec = [
            1 => ['pipe', 'w'],
            2 => ['pipe', 'w'],
        ];

        $process = proc_open($command, $descriptorspec, $pipes, null, null, ['suppress_errors' => true]);
        if (!\is_resource($process)) {
            return null;
        }

        $info = stream_get_contents($pipes[1]);
        fclose($pipes[1]);
        fclose($pipes[2]);
        proc_close($process);

        return $info;
    }
}
PKϤ$Z	���44$console/Helper/ProgressIndicator.phpnu�[���<?php

/*
 * This file is part of the Symfony package.
 *
 * (c) Fabien Potencier <fabien@symfony.com>
 *
 * For the full copyright and license information, please view the LICENSE
 * file that was distributed with this source code.
 */

namespace Symfony\Component\Console\Helper;

use Symfony\Component\Console\Exception\InvalidArgumentException;
use Symfony\Component\Console\Exception\LogicException;
use Symfony\Component\Console\Output\OutputInterface;

/**
 * @author Kevin Bond <kevinbond@gmail.com>
 */
class ProgressIndicator
{
    private const FORMATS = [
        'normal' => ' %indicator% %message%',
        'normal_no_ansi' => ' %message%',

        'verbose' => ' %indicator% %message% (%elapsed:6s%)',
        'verbose_no_ansi' => ' %message% (%elapsed:6s%)',

        'very_verbose' => ' %indicator% %message% (%elapsed:6s%, %memory:6s%)',
        'very_verbose_no_ansi' => ' %message% (%elapsed:6s%, %memory:6s%)',
    ];

    private $output;
    private $startTime;
    private $format;
    private $message;
    private $indicatorValues;
    private $indicatorCurrent;
    private $indicatorChangeInterval;
    private $indicatorUpdateTime;
    private $started = false;

    /**
     * @var array<string, callable>
     */
    private static $formatters;

    /**
     * @param int        $indicatorChangeInterval Change interval in milliseconds
     * @param array|null $indicatorValues         Animated indicator characters
     */
    public function __construct(OutputInterface $output, string $format = null, int $indicatorChangeInterval = 100, array $indicatorValues = null)
    {
        $this->output = $output;

        if (null === $format) {
            $format = $this->determineBestFormat();
        }

        if (null === $indicatorValues) {
            $indicatorValues = ['-', '\\', '|', '/'];
        }

        $indicatorValues = array_values($indicatorValues);

        if (2 > \count($indicatorValues)) {
            throw new InvalidArgumentException('Must have at least 2 indicator value characters.');
        }

        $this->format = self::getFormatDefinition($format);
        $this->indicatorChangeInterval = $indicatorChangeInterval;
        $this->indicatorValues = $indicatorValues;
        $this->startTime = time();
    }

    /**
     * Sets the current indicator message.
     */
    public function setMessage(?string $message)
    {
        $this->message = $message;

        $this->display();
    }

    /**
     * Starts the indicator output.
     */
    public function start(string $message)
    {
        if ($this->started) {
            throw new LogicException('Progress indicator already started.');
        }

        $this->message = $message;
        $this->started = true;
        $this->startTime = time();
        $this->indicatorUpdateTime = $this->getCurrentTimeInMilliseconds() + $this->indicatorChangeInterval;
        $this->indicatorCurrent = 0;

        $this->display();
    }

    /**
     * Advances the indicator.
     */
    public function advance()
    {
        if (!$this->started) {
            throw new LogicException('Progress indicator has not yet been started.');
        }

        if (!$this->output->isDecorated()) {
            return;
        }

        $currentTime = $this->getCurrentTimeInMilliseconds();

        if ($currentTime < $this->indicatorUpdateTime) {
            return;
        }

        $this->indicatorUpdateTime = $currentTime + $this->indicatorChangeInterval;
        ++$this->indicatorCurrent;

        $this->display();
    }

    /**
     * Finish the indicator with message.
     *
     * @param $message
     */
    public function finish(string $message)
    {
        if (!$this->started) {
            throw new LogicException('Progress indicator has not yet been started.');
        }

        $this->message = $message;
        $this->display();
        $this->output->writeln('');
        $this->started = false;
    }

    /**
     * Gets the format for a given name.
     *
     * @return string|null
     */
    public static function getFormatDefinition(string $name)
    {
        return self::FORMATS[$name] ?? null;
    }

    /**
     * Sets a placeholder formatter for a given name.
     *
     * This method also allow you to override an existing placeholder.
     */
    public static function setPlaceholderFormatterDefinition(string $name, callable $callable)
    {
        if (!self::$formatters) {
            self::$formatters = self::initPlaceholderFormatters();
        }

        self::$formatters[$name] = $callable;
    }

    /**
     * Gets the placeholder formatter for a given name (including the delimiter char like %).
     *
     * @return callable|null
     */
    public static function getPlaceholderFormatterDefinition(string $name)
    {
        if (!self::$formatters) {
            self::$formatters = self::initPlaceholderFormatters();
        }

        return self::$formatters[$name] ?? null;
    }

    private function display()
    {
        if (OutputInterface::VERBOSITY_QUIET === $this->output->getVerbosity()) {
            return;
        }

        $this->overwrite(preg_replace_callback("{%([a-z\-_]+)(?:\:([^%]+))?%}i", function ($matches) {
            if ($formatter = self::getPlaceholderFormatterDefinition($matches[1])) {
                return $formatter($this);
            }

            return $matches[0];
        }, $this->format ?? ''));
    }

    private function determineBestFormat(): string
    {
        switch ($this->output->getVerbosity()) {
            // OutputInterface::VERBOSITY_QUIET: display is disabled anyway
            case OutputInterface::VERBOSITY_VERBOSE:
                return $this->output->isDecorated() ? 'verbose' : 'verbose_no_ansi';
            case OutputInterface::VERBOSITY_VERY_VERBOSE:
            case OutputInterface::VERBOSITY_DEBUG:
                return $this->output->isDecorated() ? 'very_verbose' : 'very_verbose_no_ansi';
            default:
                return $this->output->isDecorated() ? 'normal' : 'normal_no_ansi';
        }
    }

    /**
     * Overwrites a previous message to the output.
     */
    private function overwrite(string $message)
    {
        if ($this->output->isDecorated()) {
            $this->output->write("\x0D\x1B[2K");
            $this->output->write($message);
        } else {
            $this->output->writeln($message);
        }
    }

    private function getCurrentTimeInMilliseconds(): float
    {
        return round(microtime(true) * 1000);
    }

    private static function initPlaceholderFormatters(): array
    {
        return [
            'indicator' => function (self $indicator) {
                return $indicator->indicatorValues[$indicator->indicatorCurrent % \count($indicator->indicatorValues)];
            },
            'message' => function (self $indicator) {
                return $indicator->message;
            },
            'elapsed' => function (self $indicator) {
                return Helper::formatTime(time() - $indicator->startTime);
            },
            'memory' => function () {
                return Helper::formatMemory(memory_get_usage(true));
            },
        ];
    }
}
PKϤ$Z��uu console/Helper/ProcessHelper.phpnu�[���<?php

/*
 * This file is part of the Symfony package.
 *
 * (c) Fabien Potencier <fabien@symfony.com>
 *
 * For the full copyright and license information, please view the LICENSE
 * file that was distributed with this source code.
 */

namespace Symfony\Component\Console\Helper;

use Symfony\Component\Console\Output\ConsoleOutputInterface;
use Symfony\Component\Console\Output\OutputInterface;
use Symfony\Component\Process\Exception\ProcessFailedException;
use Symfony\Component\Process\Process;

/**
 * The ProcessHelper class provides helpers to run external processes.
 *
 * @author Fabien Potencier <fabien@symfony.com>
 *
 * @final
 */
class ProcessHelper extends Helper
{
    /**
     * Runs an external process.
     *
     * @param array|Process $cmd      An instance of Process or an array of the command and arguments
     * @param callable|null $callback A PHP callback to run whenever there is some
     *                                output available on STDOUT or STDERR
     */
    public function run(OutputInterface $output, $cmd, string $error = null, callable $callback = null, int $verbosity = OutputInterface::VERBOSITY_VERY_VERBOSE): Process
    {
        if (!class_exists(Process::class)) {
            throw new \LogicException('The ProcessHelper cannot be run as the Process component is not installed. Try running "compose require symfony/process".');
        }

        if ($output instanceof ConsoleOutputInterface) {
            $output = $output->getErrorOutput();
        }

        $formatter = $this->getHelperSet()->get('debug_formatter');

        if ($cmd instanceof Process) {
            $cmd = [$cmd];
        }

        if (!\is_array($cmd)) {
            throw new \TypeError(sprintf('The "command" argument of "%s()" must be an array or a "%s" instance, "%s" given.', __METHOD__, Process::class, get_debug_type($cmd)));
        }

        if (\is_string($cmd[0] ?? null)) {
            $process = new Process($cmd);
            $cmd = [];
        } elseif (($cmd[0] ?? null) instanceof Process) {
            $process = $cmd[0];
            unset($cmd[0]);
        } else {
            throw new \InvalidArgumentException(sprintf('Invalid command provided to "%s()": the command should be an array whose first element is either the path to the binary to run or a "Process" object.', __METHOD__));
        }

        if ($verbosity <= $output->getVerbosity()) {
            $output->write($formatter->start(spl_object_hash($process), $this->escapeString($process->getCommandLine())));
        }

        if ($output->isDebug()) {
            $callback = $this->wrapCallback($output, $process, $callback);
        }

        $process->run($callback, $cmd);

        if ($verbosity <= $output->getVerbosity()) {
            $message = $process->isSuccessful() ? 'Command ran successfully' : sprintf('%s Command did not run successfully', $process->getExitCode());
            $output->write($formatter->stop(spl_object_hash($process), $message, $process->isSuccessful()));
        }

        if (!$process->isSuccessful() && null !== $error) {
            $output->writeln(sprintf('<error>%s</error>', $this->escapeString($error)));
        }

        return $process;
    }

    /**
     * Runs the process.
     *
     * This is identical to run() except that an exception is thrown if the process
     * exits with a non-zero exit code.
     *
     * @param array|Process $cmd      An instance of Process or a command to run
     * @param callable|null $callback A PHP callback to run whenever there is some
     *                                output available on STDOUT or STDERR
     *
     * @throws ProcessFailedException
     *
     * @see run()
     */
    public function mustRun(OutputInterface $output, $cmd, string $error = null, callable $callback = null): Process
    {
        $process = $this->run($output, $cmd, $error, $callback);

        if (!$process->isSuccessful()) {
            throw new ProcessFailedException($process);
        }

        return $process;
    }

    /**
     * Wraps a Process callback to add debugging output.
     */
    public function wrapCallback(OutputInterface $output, Process $process, callable $callback = null): callable
    {
        if ($output instanceof ConsoleOutputInterface) {
            $output = $output->getErrorOutput();
        }

        $formatter = $this->getHelperSet()->get('debug_formatter');

        return function ($type, $buffer) use ($output, $process, $callback, $formatter) {
            $output->write($formatter->progress(spl_object_hash($process), $this->escapeString($buffer), Process::ERR === $type));

            if (null !== $callback) {
                $callback($type, $buffer);
            }
        };
    }

    private function escapeString(string $str): string
    {
        return str_replace('<', '\\<', $str);
    }

    /**
     * {@inheritdoc}
     */
    public function getName(): string
    {
        return 'process';
    }
}
PKϤ$Z@���

console/Helper/HelperSet.phpnu�[���<?php

/*
 * This file is part of the Symfony package.
 *
 * (c) Fabien Potencier <fabien@symfony.com>
 *
 * For the full copyright and license information, please view the LICENSE
 * file that was distributed with this source code.
 */

namespace Symfony\Component\Console\Helper;

use Symfony\Component\Console\Command\Command;
use Symfony\Component\Console\Exception\InvalidArgumentException;

/**
 * HelperSet represents a set of helpers to be used with a command.
 *
 * @author Fabien Potencier <fabien@symfony.com>
 *
 * @implements \IteratorAggregate<string, Helper>
 */
class HelperSet implements \IteratorAggregate
{
    /** @var array<string, Helper> */
    private $helpers = [];
    private $command;

    /**
     * @param Helper[] $helpers An array of helper
     */
    public function __construct(array $helpers = [])
    {
        foreach ($helpers as $alias => $helper) {
            $this->set($helper, \is_int($alias) ? null : $alias);
        }
    }

    public function set(HelperInterface $helper, string $alias = null)
    {
        $this->helpers[$helper->getName()] = $helper;
        if (null !== $alias) {
            $this->helpers[$alias] = $helper;
        }

        $helper->setHelperSet($this);
    }

    /**
     * Returns true if the helper if defined.
     *
     * @return bool
     */
    public function has(string $name)
    {
        return isset($this->helpers[$name]);
    }

    /**
     * Gets a helper value.
     *
     * @return HelperInterface
     *
     * @throws InvalidArgumentException if the helper is not defined
     */
    public function get(string $name)
    {
        if (!$this->has($name)) {
            throw new InvalidArgumentException(sprintf('The helper "%s" is not defined.', $name));
        }

        return $this->helpers[$name];
    }

    /**
     * @deprecated since Symfony 5.4
     */
    public function setCommand(Command $command = null)
    {
        trigger_deprecation('symfony/console', '5.4', 'Method "%s()" is deprecated.', __METHOD__);

        $this->command = $command;
    }

    /**
     * Gets the command associated with this helper set.
     *
     * @return Command
     *
     * @deprecated since Symfony 5.4
     */
    public function getCommand()
    {
        trigger_deprecation('symfony/console', '5.4', 'Method "%s()" is deprecated.', __METHOD__);

        return $this->command;
    }

    /**
     * @return \Traversable<string, Helper>
     */
    #[\ReturnTypeWillChange]
    public function getIterator()
    {
        return new \ArrayIterator($this->helpers);
    }
}
PKϤ$ZWH��s�sconsole/Helper/Table.phpnu�[���<?php

/*
 * This file is part of the Symfony package.
 *
 * (c) Fabien Potencier <fabien@symfony.com>
 *
 * For the full copyright and license information, please view the LICENSE
 * file that was distributed with this source code.
 */

namespace Symfony\Component\Console\Helper;

use Symfony\Component\Console\Exception\InvalidArgumentException;
use Symfony\Component\Console\Exception\RuntimeException;
use Symfony\Component\Console\Formatter\OutputFormatter;
use Symfony\Component\Console\Formatter\WrappableOutputFormatterInterface;
use Symfony\Component\Console\Output\ConsoleSectionOutput;
use Symfony\Component\Console\Output\OutputInterface;

/**
 * Provides helpers to display a table.
 *
 * @author Fabien Potencier <fabien@symfony.com>
 * @author Саша Стаменковић <umpirsky@gmail.com>
 * @author Abdellatif Ait boudad <a.aitboudad@gmail.com>
 * @author Max Grigorian <maxakawizard@gmail.com>
 * @author Dany Maillard <danymaillard93b@gmail.com>
 */
class Table
{
    private const SEPARATOR_TOP = 0;
    private const SEPARATOR_TOP_BOTTOM = 1;
    private const SEPARATOR_MID = 2;
    private const SEPARATOR_BOTTOM = 3;
    private const BORDER_OUTSIDE = 0;
    private const BORDER_INSIDE = 1;

    private $headerTitle;
    private $footerTitle;

    /**
     * Table headers.
     */
    private $headers = [];

    /**
     * Table rows.
     */
    private $rows = [];
    private $horizontal = false;

    /**
     * Column widths cache.
     */
    private $effectiveColumnWidths = [];

    /**
     * Number of columns cache.
     *
     * @var int
     */
    private $numberOfColumns;

    /**
     * @var OutputInterface
     */
    private $output;

    /**
     * @var TableStyle
     */
    private $style;

    /**
     * @var array
     */
    private $columnStyles = [];

    /**
     * User set column widths.
     *
     * @var array
     */
    private $columnWidths = [];
    private $columnMaxWidths = [];

    /**
     * @var array<string, TableStyle>|null
     */
    private static $styles;

    private $rendered = false;

    public function __construct(OutputInterface $output)
    {
        $this->output = $output;

        if (!self::$styles) {
            self::$styles = self::initStyles();
        }

        $this->setStyle('default');
    }

    /**
     * Sets a style definition.
     */
    public static function setStyleDefinition(string $name, TableStyle $style)
    {
        if (!self::$styles) {
            self::$styles = self::initStyles();
        }

        self::$styles[$name] = $style;
    }

    /**
     * Gets a style definition by name.
     *
     * @return TableStyle
     */
    public static function getStyleDefinition(string $name)
    {
        if (!self::$styles) {
            self::$styles = self::initStyles();
        }

        if (isset(self::$styles[$name])) {
            return self::$styles[$name];
        }

        throw new InvalidArgumentException(sprintf('Style "%s" is not defined.', $name));
    }

    /**
     * Sets table style.
     *
     * @param TableStyle|string $name The style name or a TableStyle instance
     *
     * @return $this
     */
    public function setStyle($name)
    {
        $this->style = $this->resolveStyle($name);

        return $this;
    }

    /**
     * Gets the current table style.
     *
     * @return TableStyle
     */
    public function getStyle()
    {
        return $this->style;
    }

    /**
     * Sets table column style.
     *
     * @param TableStyle|string $name The style name or a TableStyle instance
     *
     * @return $this
     */
    public function setColumnStyle(int $columnIndex, $name)
    {
        $this->columnStyles[$columnIndex] = $this->resolveStyle($name);

        return $this;
    }

    /**
     * Gets the current style for a column.
     *
     * If style was not set, it returns the global table style.
     *
     * @return TableStyle
     */
    public function getColumnStyle(int $columnIndex)
    {
        return $this->columnStyles[$columnIndex] ?? $this->getStyle();
    }

    /**
     * Sets the minimum width of a column.
     *
     * @return $this
     */
    public function setColumnWidth(int $columnIndex, int $width)
    {
        $this->columnWidths[$columnIndex] = $width;

        return $this;
    }

    /**
     * Sets the minimum width of all columns.
     *
     * @return $this
     */
    public function setColumnWidths(array $widths)
    {
        $this->columnWidths = [];
        foreach ($widths as $index => $width) {
            $this->setColumnWidth($index, $width);
        }

        return $this;
    }

    /**
     * Sets the maximum width of a column.
     *
     * Any cell within this column which contents exceeds the specified width will be wrapped into multiple lines, while
     * formatted strings are preserved.
     *
     * @return $this
     */
    public function setColumnMaxWidth(int $columnIndex, int $width): self
    {
        if (!$this->output->getFormatter() instanceof WrappableOutputFormatterInterface) {
            throw new \LogicException(sprintf('Setting a maximum column width is only supported when using a "%s" formatter, got "%s".', WrappableOutputFormatterInterface::class, get_debug_type($this->output->getFormatter())));
        }

        $this->columnMaxWidths[$columnIndex] = $width;

        return $this;
    }

    /**
     * @return $this
     */
    public function setHeaders(array $headers)
    {
        $headers = array_values($headers);
        if (!empty($headers) && !\is_array($headers[0])) {
            $headers = [$headers];
        }

        $this->headers = $headers;

        return $this;
    }

    public function setRows(array $rows)
    {
        $this->rows = [];

        return $this->addRows($rows);
    }

    /**
     * @return $this
     */
    public function addRows(array $rows)
    {
        foreach ($rows as $row) {
            $this->addRow($row);
        }

        return $this;
    }

    /**
     * @return $this
     */
    public function addRow($row)
    {
        if ($row instanceof TableSeparator) {
            $this->rows[] = $row;

            return $this;
        }

        if (!\is_array($row)) {
            throw new InvalidArgumentException('A row must be an array or a TableSeparator instance.');
        }

        $this->rows[] = array_values($row);

        return $this;
    }

    /**
     * Adds a row to the table, and re-renders the table.
     *
     * @return $this
     */
    public function appendRow($row): self
    {
        if (!$this->output instanceof ConsoleSectionOutput) {
            throw new RuntimeException(sprintf('Output should be an instance of "%s" when calling "%s".', ConsoleSectionOutput::class, __METHOD__));
        }

        if ($this->rendered) {
            $this->output->clear($this->calculateRowCount());
        }

        $this->addRow($row);
        $this->render();

        return $this;
    }

    /**
     * @return $this
     */
    public function setRow($column, array $row)
    {
        $this->rows[$column] = $row;

        return $this;
    }

    /**
     * @return $this
     */
    public function setHeaderTitle(?string $title): self
    {
        $this->headerTitle = $title;

        return $this;
    }

    /**
     * @return $this
     */
    public function setFooterTitle(?string $title): self
    {
        $this->footerTitle = $title;

        return $this;
    }

    /**
     * @return $this
     */
    public function setHorizontal(bool $horizontal = true): self
    {
        $this->horizontal = $horizontal;

        return $this;
    }

    /**
     * Renders table to output.
     *
     * Example:
     *
     *     +---------------+-----------------------+------------------+
     *     | ISBN          | Title                 | Author           |
     *     +---------------+-----------------------+------------------+
     *     | 99921-58-10-7 | Divine Comedy         | Dante Alighieri  |
     *     | 9971-5-0210-0 | A Tale of Two Cities  | Charles Dickens  |
     *     | 960-425-059-0 | The Lord of the Rings | J. R. R. Tolkien |
     *     +---------------+-----------------------+------------------+
     */
    public function render()
    {
        $divider = new TableSeparator();
        if ($this->horizontal) {
            $rows = [];
            foreach ($this->headers[0] ?? [] as $i => $header) {
                $rows[$i] = [$header];
                foreach ($this->rows as $row) {
                    if ($row instanceof TableSeparator) {
                        continue;
                    }
                    if (isset($row[$i])) {
                        $rows[$i][] = $row[$i];
                    } elseif ($rows[$i][0] instanceof TableCell && $rows[$i][0]->getColspan() >= 2) {
                        // Noop, there is a "title"
                    } else {
                        $rows[$i][] = null;
                    }
                }
            }
        } else {
            $rows = array_merge($this->headers, [$divider], $this->rows);
        }

        $this->calculateNumberOfColumns($rows);

        $rowGroups = $this->buildTableRows($rows);
        $this->calculateColumnsWidth($rowGroups);

        $isHeader = !$this->horizontal;
        $isFirstRow = $this->horizontal;
        $hasTitle = (bool) $this->headerTitle;

        foreach ($rowGroups as $rowGroup) {
            $isHeaderSeparatorRendered = false;

            foreach ($rowGroup as $row) {
                if ($divider === $row) {
                    $isHeader = false;
                    $isFirstRow = true;

                    continue;
                }

                if ($row instanceof TableSeparator) {
                    $this->renderRowSeparator();

                    continue;
                }

                if (!$row) {
                    continue;
                }

                if ($isHeader && !$isHeaderSeparatorRendered) {
                    $this->renderRowSeparator(
                        $isHeader ? self::SEPARATOR_TOP : self::SEPARATOR_TOP_BOTTOM,
                        $hasTitle ? $this->headerTitle : null,
                        $hasTitle ? $this->style->getHeaderTitleFormat() : null
                    );
                    $hasTitle = false;
                    $isHeaderSeparatorRendered = true;
                }

                if ($isFirstRow) {
                    $this->renderRowSeparator(
                        $isHeader ? self::SEPARATOR_TOP : self::SEPARATOR_TOP_BOTTOM,
                        $hasTitle ? $this->headerTitle : null,
                        $hasTitle ? $this->style->getHeaderTitleFormat() : null
                    );
                    $isFirstRow = false;
                    $hasTitle = false;
                }

                if ($this->horizontal) {
                    $this->renderRow($row, $this->style->getCellRowFormat(), $this->style->getCellHeaderFormat());
                } else {
                    $this->renderRow($row, $isHeader ? $this->style->getCellHeaderFormat() : $this->style->getCellRowFormat());
                }
            }
        }
        $this->renderRowSeparator(self::SEPARATOR_BOTTOM, $this->footerTitle, $this->style->getFooterTitleFormat());

        $this->cleanup();
        $this->rendered = true;
    }

    /**
     * Renders horizontal header separator.
     *
     * Example:
     *
     *     +-----+-----------+-------+
     */
    private function renderRowSeparator(int $type = self::SEPARATOR_MID, string $title = null, string $titleFormat = null)
    {
        if (0 === $count = $this->numberOfColumns) {
            return;
        }

        $borders = $this->style->getBorderChars();
        if (!$borders[0] && !$borders[2] && !$this->style->getCrossingChar()) {
            return;
        }

        $crossings = $this->style->getCrossingChars();
        if (self::SEPARATOR_MID === $type) {
            [$horizontal, $leftChar, $midChar, $rightChar] = [$borders[2], $crossings[8], $crossings[0], $crossings[4]];
        } elseif (self::SEPARATOR_TOP === $type) {
            [$horizontal, $leftChar, $midChar, $rightChar] = [$borders[0], $crossings[1], $crossings[2], $crossings[3]];
        } elseif (self::SEPARATOR_TOP_BOTTOM === $type) {
            [$horizontal, $leftChar, $midChar, $rightChar] = [$borders[0], $crossings[9], $crossings[10], $crossings[11]];
        } else {
            [$horizontal, $leftChar, $midChar, $rightChar] = [$borders[0], $crossings[7], $crossings[6], $crossings[5]];
        }

        $markup = $leftChar;
        for ($column = 0; $column < $count; ++$column) {
            $markup .= str_repeat($horizontal, $this->effectiveColumnWidths[$column]);
            $markup .= $column === $count - 1 ? $rightChar : $midChar;
        }

        if (null !== $title) {
            $titleLength = Helper::width(Helper::removeDecoration($formatter = $this->output->getFormatter(), $formattedTitle = sprintf($titleFormat, $title)));
            $markupLength = Helper::width($markup);
            if ($titleLength > $limit = $markupLength - 4) {
                $titleLength = $limit;
                $formatLength = Helper::width(Helper::removeDecoration($formatter, sprintf($titleFormat, '')));
                $formattedTitle = sprintf($titleFormat, Helper::substr($title, 0, $limit - $formatLength - 3).'...');
            }

            $titleStart = intdiv($markupLength - $titleLength, 2);
            if (false === mb_detect_encoding($markup, null, true)) {
                $markup = substr_replace($markup, $formattedTitle, $titleStart, $titleLength);
            } else {
                $markup = mb_substr($markup, 0, $titleStart).$formattedTitle.mb_substr($markup, $titleStart + $titleLength);
            }
        }

        $this->output->writeln(sprintf($this->style->getBorderFormat(), $markup));
    }

    /**
     * Renders vertical column separator.
     */
    private function renderColumnSeparator(int $type = self::BORDER_OUTSIDE): string
    {
        $borders = $this->style->getBorderChars();

        return sprintf($this->style->getBorderFormat(), self::BORDER_OUTSIDE === $type ? $borders[1] : $borders[3]);
    }

    /**
     * Renders table row.
     *
     * Example:
     *
     *     | 9971-5-0210-0 | A Tale of Two Cities  | Charles Dickens  |
     */
    private function renderRow(array $row, string $cellFormat, string $firstCellFormat = null)
    {
        $rowContent = $this->renderColumnSeparator(self::BORDER_OUTSIDE);
        $columns = $this->getRowColumns($row);
        $last = \count($columns) - 1;
        foreach ($columns as $i => $column) {
            if ($firstCellFormat && 0 === $i) {
                $rowContent .= $this->renderCell($row, $column, $firstCellFormat);
            } else {
                $rowContent .= $this->renderCell($row, $column, $cellFormat);
            }
            $rowContent .= $this->renderColumnSeparator($last === $i ? self::BORDER_OUTSIDE : self::BORDER_INSIDE);
        }
        $this->output->writeln($rowContent);
    }

    /**
     * Renders table cell with padding.
     */
    private function renderCell(array $row, int $column, string $cellFormat): string
    {
        $cell = $row[$column] ?? '';
        $width = $this->effectiveColumnWidths[$column];
        if ($cell instanceof TableCell && $cell->getColspan() > 1) {
            // add the width of the following columns(numbers of colspan).
            foreach (range($column + 1, $column + $cell->getColspan() - 1) as $nextColumn) {
                $width += $this->getColumnSeparatorWidth() + $this->effectiveColumnWidths[$nextColumn];
            }
        }

        // str_pad won't work properly with multi-byte strings, we need to fix the padding
        if (false !== $encoding = mb_detect_encoding($cell, null, true)) {
            $width += \strlen($cell) - mb_strwidth($cell, $encoding);
        }

        $style = $this->getColumnStyle($column);

        if ($cell instanceof TableSeparator) {
            return sprintf($style->getBorderFormat(), str_repeat($style->getBorderChars()[2], $width));
        }

        $width += Helper::length($cell) - Helper::length(Helper::removeDecoration($this->output->getFormatter(), $cell));
        $content = sprintf($style->getCellRowContentFormat(), $cell);

        $padType = $style->getPadType();
        if ($cell instanceof TableCell && $cell->getStyle() instanceof TableCellStyle) {
            $isNotStyledByTag = !preg_match('/^<(\w+|(\w+=[\w,]+;?)*)>.+<\/(\w+|(\w+=\w+;?)*)?>$/', $cell);
            if ($isNotStyledByTag) {
                $cellFormat = $cell->getStyle()->getCellFormat();
                if (!\is_string($cellFormat)) {
                    $tag = http_build_query($cell->getStyle()->getTagOptions(), '', ';');
                    $cellFormat = '<'.$tag.'>%s</>';
                }

                if (strstr($content, '</>')) {
                    $content = str_replace('</>', '', $content);
                    $width -= 3;
                }
                if (strstr($content, '<fg=default;bg=default>')) {
                    $content = str_replace('<fg=default;bg=default>', '', $content);
                    $width -= \strlen('<fg=default;bg=default>');
                }
            }

            $padType = $cell->getStyle()->getPadByAlign();
        }

        return sprintf($cellFormat, str_pad($content, $width, $style->getPaddingChar(), $padType));
    }

    /**
     * Calculate number of columns for this table.
     */
    private function calculateNumberOfColumns(array $rows)
    {
        $columns = [0];
        foreach ($rows as $row) {
            if ($row instanceof TableSeparator) {
                continue;
            }

            $columns[] = $this->getNumberOfColumns($row);
        }

        $this->numberOfColumns = max($columns);
    }

    private function buildTableRows(array $rows): TableRows
    {
        /** @var WrappableOutputFormatterInterface $formatter */
        $formatter = $this->output->getFormatter();
        $unmergedRows = [];
        for ($rowKey = 0; $rowKey < \count($rows); ++$rowKey) {
            $rows = $this->fillNextRows($rows, $rowKey);

            // Remove any new line breaks and replace it with a new line
            foreach ($rows[$rowKey] as $column => $cell) {
                $colspan = $cell instanceof TableCell ? $cell->getColspan() : 1;

                if (isset($this->columnMaxWidths[$column]) && Helper::width(Helper::removeDecoration($formatter, $cell)) > $this->columnMaxWidths[$column]) {
                    $cell = $formatter->formatAndWrap($cell, $this->columnMaxWidths[$column] * $colspan);
                }
                if (!strstr($cell ?? '', "\n")) {
                    continue;
                }
                $escaped = implode("\n", array_map([OutputFormatter::class, 'escapeTrailingBackslash'], explode("\n", $cell)));
                $cell = $cell instanceof TableCell ? new TableCell($escaped, ['colspan' => $cell->getColspan()]) : $escaped;
                $lines = explode("\n", str_replace("\n", "<fg=default;bg=default></>\n", $cell));
                foreach ($lines as $lineKey => $line) {
                    if ($colspan > 1) {
                        $line = new TableCell($line, ['colspan' => $colspan]);
                    }
                    if (0 === $lineKey) {
                        $rows[$rowKey][$column] = $line;
                    } else {
                        if (!\array_key_exists($rowKey, $unmergedRows) || !\array_key_exists($lineKey, $unmergedRows[$rowKey])) {
                            $unmergedRows[$rowKey][$lineKey] = $this->copyRow($rows, $rowKey);
                        }
                        $unmergedRows[$rowKey][$lineKey][$column] = $line;
                    }
                }
            }
        }

        return new TableRows(function () use ($rows, $unmergedRows): \Traversable {
            foreach ($rows as $rowKey => $row) {
                $rowGroup = [$row instanceof TableSeparator ? $row : $this->fillCells($row)];

                if (isset($unmergedRows[$rowKey])) {
                    foreach ($unmergedRows[$rowKey] as $row) {
                        $rowGroup[] = $row instanceof TableSeparator ? $row : $this->fillCells($row);
                    }
                }
                yield $rowGroup;
            }
        });
    }

    private function calculateRowCount(): int
    {
        $numberOfRows = \count(iterator_to_array($this->buildTableRows(array_merge($this->headers, [new TableSeparator()], $this->rows))));

        if ($this->headers) {
            ++$numberOfRows; // Add row for header separator
        }

        if (\count($this->rows) > 0) {
            ++$numberOfRows; // Add row for footer separator
        }

        return $numberOfRows;
    }

    /**
     * fill rows that contains rowspan > 1.
     *
     * @throws InvalidArgumentException
     */
    private function fillNextRows(array $rows, int $line): array
    {
        $unmergedRows = [];
        foreach ($rows[$line] as $column => $cell) {
            if (null !== $cell && !$cell instanceof TableCell && !\is_scalar($cell) && !(\is_object($cell) && method_exists($cell, '__toString'))) {
                throw new InvalidArgumentException(sprintf('A cell must be a TableCell, a scalar or an object implementing "__toString()", "%s" given.', get_debug_type($cell)));
            }
            if ($cell instanceof TableCell && $cell->getRowspan() > 1) {
                $nbLines = $cell->getRowspan() - 1;
                $lines = [$cell];
                if (strstr($cell, "\n")) {
                    $lines = explode("\n", str_replace("\n", "<fg=default;bg=default>\n</>", $cell));
                    $nbLines = \count($lines) > $nbLines ? substr_count($cell, "\n") : $nbLines;

                    $rows[$line][$column] = new TableCell($lines[0], ['colspan' => $cell->getColspan(), 'style' => $cell->getStyle()]);
                    unset($lines[0]);
                }

                // create a two dimensional array (rowspan x colspan)
                $unmergedRows = array_replace_recursive(array_fill($line + 1, $nbLines, []), $unmergedRows);
                foreach ($unmergedRows as $unmergedRowKey => $unmergedRow) {
                    $value = $lines[$unmergedRowKey - $line] ?? '';
                    $unmergedRows[$unmergedRowKey][$column] = new TableCell($value, ['colspan' => $cell->getColspan(), 'style' => $cell->getStyle()]);
                    if ($nbLines === $unmergedRowKey - $line) {
                        break;
                    }
                }
            }
        }

        foreach ($unmergedRows as $unmergedRowKey => $unmergedRow) {
            // we need to know if $unmergedRow will be merged or inserted into $rows
            if (isset($rows[$unmergedRowKey]) && \is_array($rows[$unmergedRowKey]) && ($this->getNumberOfColumns($rows[$unmergedRowKey]) + $this->getNumberOfColumns($unmergedRows[$unmergedRowKey]) <= $this->numberOfColumns)) {
                foreach ($unmergedRow as $cellKey => $cell) {
                    // insert cell into row at cellKey position
                    array_splice($rows[$unmergedRowKey], $cellKey, 0, [$cell]);
                }
            } else {
                $row = $this->copyRow($rows, $unmergedRowKey - 1);
                foreach ($unmergedRow as $column => $cell) {
                    if (!empty($cell)) {
                        $row[$column] = $unmergedRow[$column];
                    }
                }
                array_splice($rows, $unmergedRowKey, 0, [$row]);
            }
        }

        return $rows;
    }

    /**
     * fill cells for a row that contains colspan > 1.
     */
    private function fillCells(iterable $row)
    {
        $newRow = [];

        foreach ($row as $column => $cell) {
            $newRow[] = $cell;
            if ($cell instanceof TableCell && $cell->getColspan() > 1) {
                foreach (range($column + 1, $column + $cell->getColspan() - 1) as $position) {
                    // insert empty value at column position
                    $newRow[] = '';
                }
            }
        }

        return $newRow ?: $row;
    }

    private function copyRow(array $rows, int $line): array
    {
        $row = $rows[$line];
        foreach ($row as $cellKey => $cellValue) {
            $row[$cellKey] = '';
            if ($cellValue instanceof TableCell) {
                $row[$cellKey] = new TableCell('', ['colspan' => $cellValue->getColspan()]);
            }
        }

        return $row;
    }

    /**
     * Gets number of columns by row.
     */
    private function getNumberOfColumns(array $row): int
    {
        $columns = \count($row);
        foreach ($row as $column) {
            $columns += $column instanceof TableCell ? ($column->getColspan() - 1) : 0;
        }

        return $columns;
    }

    /**
     * Gets list of columns for the given row.
     */
    private function getRowColumns(array $row): array
    {
        $columns = range(0, $this->numberOfColumns - 1);
        foreach ($row as $cellKey => $cell) {
            if ($cell instanceof TableCell && $cell->getColspan() > 1) {
                // exclude grouped columns.
                $columns = array_diff($columns, range($cellKey + 1, $cellKey + $cell->getColspan() - 1));
            }
        }

        return $columns;
    }

    /**
     * Calculates columns widths.
     */
    private function calculateColumnsWidth(iterable $groups)
    {
        for ($column = 0; $column < $this->numberOfColumns; ++$column) {
            $lengths = [];
            foreach ($groups as $group) {
                foreach ($group as $row) {
                    if ($row instanceof TableSeparator) {
                        continue;
                    }

                    foreach ($row as $i => $cell) {
                        if ($cell instanceof TableCell) {
                            $textContent = Helper::removeDecoration($this->output->getFormatter(), $cell);
                            $textLength = Helper::width($textContent);
                            if ($textLength > 0) {
                                $contentColumns = str_split($textContent, ceil($textLength / $cell->getColspan()));
                                foreach ($contentColumns as $position => $content) {
                                    $row[$i + $position] = $content;
                                }
                            }
                        }
                    }

                    $lengths[] = $this->getCellWidth($row, $column);
                }
            }

            $this->effectiveColumnWidths[$column] = max($lengths) + Helper::width($this->style->getCellRowContentFormat()) - 2;
        }
    }

    private function getColumnSeparatorWidth(): int
    {
        return Helper::width(sprintf($this->style->getBorderFormat(), $this->style->getBorderChars()[3]));
    }

    private function getCellWidth(array $row, int $column): int
    {
        $cellWidth = 0;

        if (isset($row[$column])) {
            $cell = $row[$column];
            $cellWidth = Helper::width(Helper::removeDecoration($this->output->getFormatter(), $cell));
        }

        $columnWidth = $this->columnWidths[$column] ?? 0;
        $cellWidth = max($cellWidth, $columnWidth);

        return isset($this->columnMaxWidths[$column]) ? min($this->columnMaxWidths[$column], $cellWidth) : $cellWidth;
    }

    /**
     * Called after rendering to cleanup cache data.
     */
    private function cleanup()
    {
        $this->effectiveColumnWidths = [];
        $this->numberOfColumns = null;
    }

    /**
     * @return array<string, TableStyle>
     */
    private static function initStyles(): array
    {
        $borderless = new TableStyle();
        $borderless
            ->setHorizontalBorderChars('=')
            ->setVerticalBorderChars(' ')
            ->setDefaultCrossingChar(' ')
        ;

        $compact = new TableStyle();
        $compact
            ->setHorizontalBorderChars('')
            ->setVerticalBorderChars('')
            ->setDefaultCrossingChar('')
            ->setCellRowContentFormat('%s ')
        ;

        $styleGuide = new TableStyle();
        $styleGuide
            ->setHorizontalBorderChars('-')
            ->setVerticalBorderChars(' ')
            ->setDefaultCrossingChar(' ')
            ->setCellHeaderFormat('%s')
        ;

        $box = (new TableStyle())
            ->setHorizontalBorderChars('─')
            ->setVerticalBorderChars('│')
            ->setCrossingChars('┼', '┌', '┬', '┐', '┤', '┘', '┴', '└', '├')
        ;

        $boxDouble = (new TableStyle())
            ->setHorizontalBorderChars('═', '─')
            ->setVerticalBorderChars('║', '│')
            ->setCrossingChars('┼', '╔', '╤', '╗', '╢', '╝', '╧', '╚', '╟', '╠', '╪', '╣')
        ;

        return [
            'default' => new TableStyle(),
            'borderless' => $borderless,
            'compact' => $compact,
            'symfony-style-guide' => $styleGuide,
            'box' => $box,
            'box-double' => $boxDouble,
        ];
    }

    private function resolveStyle($name): TableStyle
    {
        if ($name instanceof TableStyle) {
            return $name;
        }

        if (isset(self::$styles[$name])) {
            return self::$styles[$name];
        }

        throw new InvalidArgumentException(sprintf('Style "%s" is not defined.', $name));
    }
}
PKϤ$Z-��L�L!console/Helper/QuestionHelper.phpnu�[���<?php

/*
 * This file is part of the Symfony package.
 *
 * (c) Fabien Potencier <fabien@symfony.com>
 *
 * For the full copyright and license information, please view the LICENSE
 * file that was distributed with this source code.
 */

namespace Symfony\Component\Console\Helper;

use Symfony\Component\Console\Cursor;
use Symfony\Component\Console\Exception\MissingInputException;
use Symfony\Component\Console\Exception\RuntimeException;
use Symfony\Component\Console\Formatter\OutputFormatter;
use Symfony\Component\Console\Formatter\OutputFormatterStyle;
use Symfony\Component\Console\Input\InputInterface;
use Symfony\Component\Console\Input\StreamableInputInterface;
use Symfony\Component\Console\Output\ConsoleOutputInterface;
use Symfony\Component\Console\Output\ConsoleSectionOutput;
use Symfony\Component\Console\Output\OutputInterface;
use Symfony\Component\Console\Question\ChoiceQuestion;
use Symfony\Component\Console\Question\Question;
use Symfony\Component\Console\Terminal;

use function Symfony\Component\String\s;

/**
 * The QuestionHelper class provides helpers to interact with the user.
 *
 * @author Fabien Potencier <fabien@symfony.com>
 */
class QuestionHelper extends Helper
{
    /**
     * @var resource|null
     */
    private $inputStream;

    private static $stty = true;
    private static $stdinIsInteractive;

    /**
     * Asks a question to the user.
     *
     * @return mixed The user answer
     *
     * @throws RuntimeException If there is no data to read in the input stream
     */
    public function ask(InputInterface $input, OutputInterface $output, Question $question)
    {
        if ($output instanceof ConsoleOutputInterface) {
            $output = $output->getErrorOutput();
        }

        if (!$input->isInteractive()) {
            return $this->getDefaultAnswer($question);
        }

        if ($input instanceof StreamableInputInterface && $stream = $input->getStream()) {
            $this->inputStream = $stream;
        }

        try {
            if (!$question->getValidator()) {
                return $this->doAsk($output, $question);
            }

            $interviewer = function () use ($output, $question) {
                return $this->doAsk($output, $question);
            };

            return $this->validateAttempts($interviewer, $output, $question);
        } catch (MissingInputException $exception) {
            $input->setInteractive(false);

            if (null === $fallbackOutput = $this->getDefaultAnswer($question)) {
                throw $exception;
            }

            return $fallbackOutput;
        }
    }

    /**
     * {@inheritdoc}
     */
    public function getName()
    {
        return 'question';
    }

    /**
     * Prevents usage of stty.
     */
    public static function disableStty()
    {
        self::$stty = false;
    }

    /**
     * Asks the question to the user.
     *
     * @return mixed
     *
     * @throws RuntimeException In case the fallback is deactivated and the response cannot be hidden
     */
    private function doAsk(OutputInterface $output, Question $question)
    {
        $this->writePrompt($output, $question);

        $inputStream = $this->inputStream ?: \STDIN;
        $autocomplete = $question->getAutocompleterCallback();

        if (null === $autocomplete || !self::$stty || !Terminal::hasSttyAvailable()) {
            $ret = false;
            if ($question->isHidden()) {
                try {
                    $hiddenResponse = $this->getHiddenResponse($output, $inputStream, $question->isTrimmable());
                    $ret = $question->isTrimmable() ? trim($hiddenResponse) : $hiddenResponse;
                } catch (RuntimeException $e) {
                    if (!$question->isHiddenFallback()) {
                        throw $e;
                    }
                }
            }

            if (false === $ret) {
                $ret = $this->readInput($inputStream, $question);
                if (false === $ret) {
                    throw new MissingInputException('Aborted.');
                }
                if ($question->isTrimmable()) {
                    $ret = trim($ret);
                }
            }
        } else {
            $autocomplete = $this->autocomplete($output, $question, $inputStream, $autocomplete);
            $ret = $question->isTrimmable() ? trim($autocomplete) : $autocomplete;
        }

        if ($output instanceof ConsoleSectionOutput) {
            $output->addContent($ret);
        }

        $ret = \strlen($ret) > 0 ? $ret : $question->getDefault();

        if ($normalizer = $question->getNormalizer()) {
            return $normalizer($ret);
        }

        return $ret;
    }

    /**
     * @return mixed
     */
    private function getDefaultAnswer(Question $question)
    {
        $default = $question->getDefault();

        if (null === $default) {
            return $default;
        }

        if ($validator = $question->getValidator()) {
            return \call_user_func($question->getValidator(), $default);
        } elseif ($question instanceof ChoiceQuestion) {
            $choices = $question->getChoices();

            if (!$question->isMultiselect()) {
                return $choices[$default] ?? $default;
            }

            $default = explode(',', $default);
            foreach ($default as $k => $v) {
                $v = $question->isTrimmable() ? trim($v) : $v;
                $default[$k] = $choices[$v] ?? $v;
            }
        }

        return $default;
    }

    /**
     * Outputs the question prompt.
     */
    protected function writePrompt(OutputInterface $output, Question $question)
    {
        $message = $question->getQuestion();

        if ($question instanceof ChoiceQuestion) {
            $output->writeln(array_merge([
                $question->getQuestion(),
            ], $this->formatChoiceQuestionChoices($question, 'info')));

            $message = $question->getPrompt();
        }

        $output->write($message);
    }

    /**
     * @return string[]
     */
    protected function formatChoiceQuestionChoices(ChoiceQuestion $question, string $tag)
    {
        $messages = [];

        $maxWidth = max(array_map([__CLASS__, 'width'], array_keys($choices = $question->getChoices())));

        foreach ($choices as $key => $value) {
            $padding = str_repeat(' ', $maxWidth - self::width($key));

            $messages[] = sprintf("  [<$tag>%s$padding</$tag>] %s", $key, $value);
        }

        return $messages;
    }

    /**
     * Outputs an error message.
     */
    protected function writeError(OutputInterface $output, \Exception $error)
    {
        if (null !== $this->getHelperSet() && $this->getHelperSet()->has('formatter')) {
            $message = $this->getHelperSet()->get('formatter')->formatBlock($error->getMessage(), 'error');
        } else {
            $message = '<error>'.$error->getMessage().'</error>';
        }

        $output->writeln($message);
    }

    /**
     * Autocompletes a question.
     *
     * @param resource $inputStream
     */
    private function autocomplete(OutputInterface $output, Question $question, $inputStream, callable $autocomplete): string
    {
        $cursor = new Cursor($output, $inputStream);

        $fullChoice = '';
        $ret = '';

        $i = 0;
        $ofs = -1;
        $matches = $autocomplete($ret);
        $numMatches = \count($matches);

        $sttyMode = shell_exec('stty -g');
        $isStdin = 'php://stdin' === (stream_get_meta_data($inputStream)['uri'] ?? null);
        $r = [$inputStream];
        $w = [];

        // Disable icanon (so we can fread each keypress) and echo (we'll do echoing here instead)
        shell_exec('stty -icanon -echo');

        // Add highlighted text style
        $output->getFormatter()->setStyle('hl', new OutputFormatterStyle('black', 'white'));

        // Read a keypress
        while (!feof($inputStream)) {
            while ($isStdin && 0 === @stream_select($r, $w, $w, 0, 100)) {
                // Give signal handlers a chance to run
                $r = [$inputStream];
            }
            $c = fread($inputStream, 1);

            // as opposed to fgets(), fread() returns an empty string when the stream content is empty, not false.
            if (false === $c || ('' === $ret && '' === $c && null === $question->getDefault())) {
                shell_exec('stty '.$sttyMode);
                throw new MissingInputException('Aborted.');
            } elseif ("\177" === $c) { // Backspace Character
                if (0 === $numMatches && 0 !== $i) {
                    --$i;
                    $cursor->moveLeft(s($fullChoice)->slice(-1)->width(false));

                    $fullChoice = self::substr($fullChoice, 0, $i);
                }

                if (0 === $i) {
                    $ofs = -1;
                    $matches = $autocomplete($ret);
                    $numMatches = \count($matches);
                } else {
                    $numMatches = 0;
                }

                // Pop the last character off the end of our string
                $ret = self::substr($ret, 0, $i);
            } elseif ("\033" === $c) {
                // Did we read an escape sequence?
                $c .= fread($inputStream, 2);

                // A = Up Arrow. B = Down Arrow
                if (isset($c[2]) && ('A' === $c[2] || 'B' === $c[2])) {
                    if ('A' === $c[2] && -1 === $ofs) {
                        $ofs = 0;
                    }

                    if (0 === $numMatches) {
                        continue;
                    }

                    $ofs += ('A' === $c[2]) ? -1 : 1;
                    $ofs = ($numMatches + $ofs) % $numMatches;
                }
            } elseif (\ord($c) < 32) {
                if ("\t" === $c || "\n" === $c) {
                    if ($numMatches > 0 && -1 !== $ofs) {
                        $ret = (string) $matches[$ofs];
                        // Echo out remaining chars for current match
                        $remainingCharacters = substr($ret, \strlen(trim($this->mostRecentlyEnteredValue($fullChoice))));
                        $output->write($remainingCharacters);
                        $fullChoice .= $remainingCharacters;
                        $i = (false === $encoding = mb_detect_encoding($fullChoice, null, true)) ? \strlen($fullChoice) : mb_strlen($fullChoice, $encoding);

                        $matches = array_filter(
                            $autocomplete($ret),
                            function ($match) use ($ret) {
                                return '' === $ret || str_starts_with($match, $ret);
                            }
                        );
                        $numMatches = \count($matches);
                        $ofs = -1;
                    }

                    if ("\n" === $c) {
                        $output->write($c);
                        break;
                    }

                    $numMatches = 0;
                }

                continue;
            } else {
                if ("\x80" <= $c) {
                    $c .= fread($inputStream, ["\xC0" => 1, "\xD0" => 1, "\xE0" => 2, "\xF0" => 3][$c & "\xF0"]);
                }

                $output->write($c);
                $ret .= $c;
                $fullChoice .= $c;
                ++$i;

                $tempRet = $ret;

                if ($question instanceof ChoiceQuestion && $question->isMultiselect()) {
                    $tempRet = $this->mostRecentlyEnteredValue($fullChoice);
                }

                $numMatches = 0;
                $ofs = 0;

                foreach ($autocomplete($ret) as $value) {
                    // If typed characters match the beginning chunk of value (e.g. [AcmeDe]moBundle)
                    if (str_starts_with($value, $tempRet)) {
                        $matches[$numMatches++] = $value;
                    }
                }
            }

            $cursor->clearLineAfter();

            if ($numMatches > 0 && -1 !== $ofs) {
                $cursor->savePosition();
                // Write highlighted text, complete the partially entered response
                $charactersEntered = \strlen(trim($this->mostRecentlyEnteredValue($fullChoice)));
                $output->write('<hl>'.OutputFormatter::escapeTrailingBackslash(substr($matches[$ofs], $charactersEntered)).'</hl>');
                $cursor->restorePosition();
            }
        }

        // Reset stty so it behaves normally again
        shell_exec('stty '.$sttyMode);

        return $fullChoice;
    }

    private function mostRecentlyEnteredValue(string $entered): string
    {
        // Determine the most recent value that the user entered
        if (!str_contains($entered, ',')) {
            return $entered;
        }

        $choices = explode(',', $entered);
        if ('' !== $lastChoice = trim($choices[\count($choices) - 1])) {
            return $lastChoice;
        }

        return $entered;
    }

    /**
     * Gets a hidden response from user.
     *
     * @param resource $inputStream The handler resource
     * @param bool     $trimmable   Is the answer trimmable
     *
     * @throws RuntimeException In case the fallback is deactivated and the response cannot be hidden
     */
    private function getHiddenResponse(OutputInterface $output, $inputStream, bool $trimmable = true): string
    {
        if ('\\' === \DIRECTORY_SEPARATOR) {
            $exe = __DIR__.'/../Resources/bin/hiddeninput.exe';

            // handle code running from a phar
            if ('phar:' === substr(__FILE__, 0, 5)) {
                $tmpExe = sys_get_temp_dir().'/hiddeninput.exe';
                copy($exe, $tmpExe);
                $exe = $tmpExe;
            }

            $sExec = shell_exec('"'.$exe.'"');
            $value = $trimmable ? rtrim($sExec) : $sExec;
            $output->writeln('');

            if (isset($tmpExe)) {
                unlink($tmpExe);
            }

            return $value;
        }

        if (self::$stty && Terminal::hasSttyAvailable()) {
            $sttyMode = shell_exec('stty -g');
            shell_exec('stty -echo');
        } elseif ($this->isInteractiveInput($inputStream)) {
            throw new RuntimeException('Unable to hide the response.');
        }

        $value = fgets($inputStream, 4096);

        if (self::$stty && Terminal::hasSttyAvailable()) {
            shell_exec('stty '.$sttyMode);
        }

        if (false === $value) {
            throw new MissingInputException('Aborted.');
        }
        if ($trimmable) {
            $value = trim($value);
        }
        $output->writeln('');

        return $value;
    }

    /**
     * Validates an attempt.
     *
     * @param callable $interviewer A callable that will ask for a question and return the result
     *
     * @return mixed The validated response
     *
     * @throws \Exception In case the max number of attempts has been reached and no valid response has been given
     */
    private function validateAttempts(callable $interviewer, OutputInterface $output, Question $question)
    {
        $error = null;
        $attempts = $question->getMaxAttempts();

        while (null === $attempts || $attempts--) {
            if (null !== $error) {
                $this->writeError($output, $error);
            }

            try {
                return $question->getValidator()($interviewer());
            } catch (RuntimeException $e) {
                throw $e;
            } catch (\Exception $error) {
            }
        }

        throw $error;
    }

    private function isInteractiveInput($inputStream): bool
    {
        if ('php://stdin' !== (stream_get_meta_data($inputStream)['uri'] ?? null)) {
            return false;
        }

        if (null !== self::$stdinIsInteractive) {
            return self::$stdinIsInteractive;
        }

        if (\function_exists('stream_isatty')) {
            return self::$stdinIsInteractive = @stream_isatty(fopen('php://stdin', 'r'));
        }

        if (\function_exists('posix_isatty')) {
            return self::$stdinIsInteractive = @posix_isatty(fopen('php://stdin', 'r'));
        }

        if (!\function_exists('exec')) {
            return self::$stdinIsInteractive = true;
        }

        exec('stty 2> /dev/null', $output, $status);

        return self::$stdinIsInteractive = 1 !== $status;
    }

    /**
     * Reads one or more lines of input and returns what is read.
     *
     * @param resource $inputStream The handler resource
     * @param Question $question    The question being asked
     *
     * @return string|false The input received, false in case input could not be read
     */
    private function readInput($inputStream, Question $question)
    {
        if (!$question->isMultiline()) {
            $cp = $this->setIOCodepage();
            $ret = fgets($inputStream, 4096);

            return $this->resetIOCodepage($cp, $ret);
        }

        $multiLineStreamReader = $this->cloneInputStream($inputStream);
        if (null === $multiLineStreamReader) {
            return false;
        }

        $ret = '';
        $cp = $this->setIOCodepage();
        while (false !== ($char = fgetc($multiLineStreamReader))) {
            if (\PHP_EOL === "{$ret}{$char}") {
                break;
            }
            $ret .= $char;
        }

        return $this->resetIOCodepage($cp, $ret);
    }

    /**
     * Sets console I/O to the host code page.
     *
     * @return int Previous code page in IBM/EBCDIC format
     */
    private function setIOCodepage(): int
    {
        if (\function_exists('sapi_windows_cp_set')) {
            $cp = sapi_windows_cp_get();
            sapi_windows_cp_set(sapi_windows_cp_get('oem'));

            return $cp;
        }

        return 0;
    }

    /**
     * Sets console I/O to the specified code page and converts the user input.
     *
     * @param string|false $input
     *
     * @return string|false
     */
    private function resetIOCodepage(int $cp, $input)
    {
        if (0 !== $cp) {
            sapi_windows_cp_set($cp);

            if (false !== $input && '' !== $input) {
                $input = sapi_windows_cp_conv(sapi_windows_cp_get('oem'), $cp, $input);
            }
        }

        return $input;
    }

    /**
     * Clones an input stream in order to act on one instance of the same
     * stream without affecting the other instance.
     *
     * @param resource $inputStream The handler resource
     *
     * @return resource|null The cloned resource, null in case it could not be cloned
     */
    private function cloneInputStream($inputStream)
    {
        $streamMetaData = stream_get_meta_data($inputStream);
        $seekable = $streamMetaData['seekable'] ?? false;
        $mode = $streamMetaData['mode'] ?? 'rb';
        $uri = $streamMetaData['uri'] ?? null;

        if (null === $uri) {
            return null;
        }

        $cloneStream = fopen($uri, $mode);

        // For seekable and writable streams, add all the same data to the
        // cloned stream and then seek to the same offset.
        if (true === $seekable && !\in_array($mode, ['r', 'rb', 'rt'])) {
            $offset = ftell($inputStream);
            rewind($inputStream);
            stream_copy_to_stream($inputStream, $cloneStream);
            fseek($inputStream, $offset);
            fseek($cloneStream, $offset);
        }

        return $cloneStream;
    }
}
PKϤ$Z���o�1�1console/Helper/TableStyle.phpnu�[���<?php

/*
 * This file is part of the Symfony package.
 *
 * (c) Fabien Potencier <fabien@symfony.com>
 *
 * For the full copyright and license information, please view the LICENSE
 * file that was distributed with this source code.
 */

namespace Symfony\Component\Console\Helper;

use Symfony\Component\Console\Exception\InvalidArgumentException;
use Symfony\Component\Console\Exception\LogicException;

/**
 * Defines the styles for a Table.
 *
 * @author Fabien Potencier <fabien@symfony.com>
 * @author Саша Стаменковић <umpirsky@gmail.com>
 * @author Dany Maillard <danymaillard93b@gmail.com>
 */
class TableStyle
{
    private $paddingChar = ' ';
    private $horizontalOutsideBorderChar = '-';
    private $horizontalInsideBorderChar = '-';
    private $verticalOutsideBorderChar = '|';
    private $verticalInsideBorderChar = '|';
    private $crossingChar = '+';
    private $crossingTopRightChar = '+';
    private $crossingTopMidChar = '+';
    private $crossingTopLeftChar = '+';
    private $crossingMidRightChar = '+';
    private $crossingBottomRightChar = '+';
    private $crossingBottomMidChar = '+';
    private $crossingBottomLeftChar = '+';
    private $crossingMidLeftChar = '+';
    private $crossingTopLeftBottomChar = '+';
    private $crossingTopMidBottomChar = '+';
    private $crossingTopRightBottomChar = '+';
    private $headerTitleFormat = '<fg=black;bg=white;options=bold> %s </>';
    private $footerTitleFormat = '<fg=black;bg=white;options=bold> %s </>';
    private $cellHeaderFormat = '<info>%s</info>';
    private $cellRowFormat = '%s';
    private $cellRowContentFormat = ' %s ';
    private $borderFormat = '%s';
    private $padType = \STR_PAD_RIGHT;

    /**
     * Sets padding character, used for cell padding.
     *
     * @return $this
     */
    public function setPaddingChar(string $paddingChar)
    {
        if (!$paddingChar) {
            throw new LogicException('The padding char must not be empty.');
        }

        $this->paddingChar = $paddingChar;

        return $this;
    }

    /**
     * Gets padding character, used for cell padding.
     *
     * @return string
     */
    public function getPaddingChar()
    {
        return $this->paddingChar;
    }

    /**
     * Sets horizontal border characters.
     *
     * <code>
     * ╔═══════════════╤══════════════════════════╤══════════════════╗
     * 1 ISBN          2 Title                    │ Author           ║
     * ╠═══════════════╪══════════════════════════╪══════════════════╣
     * ║ 99921-58-10-7 │ Divine Comedy            │ Dante Alighieri  ║
     * ║ 9971-5-0210-0 │ A Tale of Two Cities     │ Charles Dickens  ║
     * ║ 960-425-059-0 │ The Lord of the Rings    │ J. R. R. Tolkien ║
     * ║ 80-902734-1-6 │ And Then There Were None │ Agatha Christie  ║
     * ╚═══════════════╧══════════════════════════╧══════════════════╝
     * </code>
     *
     * @return $this
     */
    public function setHorizontalBorderChars(string $outside, string $inside = null): self
    {
        $this->horizontalOutsideBorderChar = $outside;
        $this->horizontalInsideBorderChar = $inside ?? $outside;

        return $this;
    }

    /**
     * Sets vertical border characters.
     *
     * <code>
     * ╔═══════════════╤══════════════════════════╤══════════════════╗
     * ║ ISBN          │ Title                    │ Author           ║
     * ╠═══════1═══════╪══════════════════════════╪══════════════════╣
     * ║ 99921-58-10-7 │ Divine Comedy            │ Dante Alighieri  ║
     * ║ 9971-5-0210-0 │ A Tale of Two Cities     │ Charles Dickens  ║
     * ╟───────2───────┼──────────────────────────┼──────────────────╢
     * ║ 960-425-059-0 │ The Lord of the Rings    │ J. R. R. Tolkien ║
     * ║ 80-902734-1-6 │ And Then There Were None │ Agatha Christie  ║
     * ╚═══════════════╧══════════════════════════╧══════════════════╝
     * </code>
     *
     * @return $this
     */
    public function setVerticalBorderChars(string $outside, string $inside = null): self
    {
        $this->verticalOutsideBorderChar = $outside;
        $this->verticalInsideBorderChar = $inside ?? $outside;

        return $this;
    }

    /**
     * Gets border characters.
     *
     * @internal
     */
    public function getBorderChars(): array
    {
        return [
            $this->horizontalOutsideBorderChar,
            $this->verticalOutsideBorderChar,
            $this->horizontalInsideBorderChar,
            $this->verticalInsideBorderChar,
        ];
    }

    /**
     * Sets crossing characters.
     *
     * Example:
     * <code>
     * 1═══════════════2══════════════════════════2══════════════════3
     * ║ ISBN          │ Title                    │ Author           ║
     * 8'══════════════0'═════════════════════════0'═════════════════4'
     * ║ 99921-58-10-7 │ Divine Comedy            │ Dante Alighieri  ║
     * ║ 9971-5-0210-0 │ A Tale of Two Cities     │ Charles Dickens  ║
     * 8───────────────0──────────────────────────0──────────────────4
     * ║ 960-425-059-0 │ The Lord of the Rings    │ J. R. R. Tolkien ║
     * ║ 80-902734-1-6 │ And Then There Were None │ Agatha Christie  ║
     * 7═══════════════6══════════════════════════6══════════════════5
     * </code>
     *
     * @param string      $cross          Crossing char (see #0 of example)
     * @param string      $topLeft        Top left char (see #1 of example)
     * @param string      $topMid         Top mid char (see #2 of example)
     * @param string      $topRight       Top right char (see #3 of example)
     * @param string      $midRight       Mid right char (see #4 of example)
     * @param string      $bottomRight    Bottom right char (see #5 of example)
     * @param string      $bottomMid      Bottom mid char (see #6 of example)
     * @param string      $bottomLeft     Bottom left char (see #7 of example)
     * @param string      $midLeft        Mid left char (see #8 of example)
     * @param string|null $topLeftBottom  Top left bottom char (see #8' of example), equals to $midLeft if null
     * @param string|null $topMidBottom   Top mid bottom char (see #0' of example), equals to $cross if null
     * @param string|null $topRightBottom Top right bottom char (see #4' of example), equals to $midRight if null
     *
     * @return $this
     */
    public function setCrossingChars(string $cross, string $topLeft, string $topMid, string $topRight, string $midRight, string $bottomRight, string $bottomMid, string $bottomLeft, string $midLeft, string $topLeftBottom = null, string $topMidBottom = null, string $topRightBottom = null): self
    {
        $this->crossingChar = $cross;
        $this->crossingTopLeftChar = $topLeft;
        $this->crossingTopMidChar = $topMid;
        $this->crossingTopRightChar = $topRight;
        $this->crossingMidRightChar = $midRight;
        $this->crossingBottomRightChar = $bottomRight;
        $this->crossingBottomMidChar = $bottomMid;
        $this->crossingBottomLeftChar = $bottomLeft;
        $this->crossingMidLeftChar = $midLeft;
        $this->crossingTopLeftBottomChar = $topLeftBottom ?? $midLeft;
        $this->crossingTopMidBottomChar = $topMidBottom ?? $cross;
        $this->crossingTopRightBottomChar = $topRightBottom ?? $midRight;

        return $this;
    }

    /**
     * Sets default crossing character used for each cross.
     *
     * @see {@link setCrossingChars()} for setting each crossing individually.
     */
    public function setDefaultCrossingChar(string $char): self
    {
        return $this->setCrossingChars($char, $char, $char, $char, $char, $char, $char, $char, $char);
    }

    /**
     * Gets crossing character.
     *
     * @return string
     */
    public function getCrossingChar()
    {
        return $this->crossingChar;
    }

    /**
     * Gets crossing characters.
     *
     * @internal
     */
    public function getCrossingChars(): array
    {
        return [
            $this->crossingChar,
            $this->crossingTopLeftChar,
            $this->crossingTopMidChar,
            $this->crossingTopRightChar,
            $this->crossingMidRightChar,
            $this->crossingBottomRightChar,
            $this->crossingBottomMidChar,
            $this->crossingBottomLeftChar,
            $this->crossingMidLeftChar,
            $this->crossingTopLeftBottomChar,
            $this->crossingTopMidBottomChar,
            $this->crossingTopRightBottomChar,
        ];
    }

    /**
     * Sets header cell format.
     *
     * @return $this
     */
    public function setCellHeaderFormat(string $cellHeaderFormat)
    {
        $this->cellHeaderFormat = $cellHeaderFormat;

        return $this;
    }

    /**
     * Gets header cell format.
     *
     * @return string
     */
    public function getCellHeaderFormat()
    {
        return $this->cellHeaderFormat;
    }

    /**
     * Sets row cell format.
     *
     * @return $this
     */
    public function setCellRowFormat(string $cellRowFormat)
    {
        $this->cellRowFormat = $cellRowFormat;

        return $this;
    }

    /**
     * Gets row cell format.
     *
     * @return string
     */
    public function getCellRowFormat()
    {
        return $this->cellRowFormat;
    }

    /**
     * Sets row cell content format.
     *
     * @return $this
     */
    public function setCellRowContentFormat(string $cellRowContentFormat)
    {
        $this->cellRowContentFormat = $cellRowContentFormat;

        return $this;
    }

    /**
     * Gets row cell content format.
     *
     * @return string
     */
    public function getCellRowContentFormat()
    {
        return $this->cellRowContentFormat;
    }

    /**
     * Sets table border format.
     *
     * @return $this
     */
    public function setBorderFormat(string $borderFormat)
    {
        $this->borderFormat = $borderFormat;

        return $this;
    }

    /**
     * Gets table border format.
     *
     * @return string
     */
    public function getBorderFormat()
    {
        return $this->borderFormat;
    }

    /**
     * Sets cell padding type.
     *
     * @return $this
     */
    public function setPadType(int $padType)
    {
        if (!\in_array($padType, [\STR_PAD_LEFT, \STR_PAD_RIGHT, \STR_PAD_BOTH], true)) {
            throw new InvalidArgumentException('Invalid padding type. Expected one of (STR_PAD_LEFT, STR_PAD_RIGHT, STR_PAD_BOTH).');
        }

        $this->padType = $padType;

        return $this;
    }

    /**
     * Gets cell padding type.
     *
     * @return int
     */
    public function getPadType()
    {
        return $this->padType;
    }

    public function getHeaderTitleFormat(): string
    {
        return $this->headerTitleFormat;
    }

    /**
     * @return $this
     */
    public function setHeaderTitleFormat(string $format): self
    {
        $this->headerTitleFormat = $format;

        return $this;
    }

    public function getFooterTitleFormat(): string
    {
        return $this->footerTitleFormat;
    }

    /**
     * @return $this
     */
    public function setFooterTitleFormat(string $format): self
    {
        $this->footerTitleFormat = $format;

        return $this;
    }
}
PKϤ$Z��a�EEconsole/Helper/TableRows.phpnu�[���<?php

/*
 * This file is part of the Symfony package.
 *
 * (c) Fabien Potencier <fabien@symfony.com>
 *
 * For the full copyright and license information, please view the LICENSE
 * file that was distributed with this source code.
 */

namespace Symfony\Component\Console\Helper;

/**
 * @internal
 */
class TableRows implements \IteratorAggregate
{
    private $generator;

    public function __construct(\Closure $generator)
    {
        $this->generator = $generator;
    }

    public function getIterator(): \Traversable
    {
        return ($this->generator)();
    }
}
PKϤ$Z+'�f��console/Helper/Dumper.phpnu�[���<?php

/*
 * This file is part of the Symfony package.
 *
 * (c) Fabien Potencier <fabien@symfony.com>
 *
 * For the full copyright and license information, please view the LICENSE
 * file that was distributed with this source code.
 */

namespace Symfony\Component\Console\Helper;

use Symfony\Component\Console\Output\OutputInterface;
use Symfony\Component\VarDumper\Cloner\ClonerInterface;
use Symfony\Component\VarDumper\Cloner\VarCloner;
use Symfony\Component\VarDumper\Dumper\CliDumper;

/**
 * @author Roland Franssen <franssen.roland@gmail.com>
 */
final class Dumper
{
    private $output;
    private $dumper;
    private $cloner;
    private $handler;

    public function __construct(OutputInterface $output, CliDumper $dumper = null, ClonerInterface $cloner = null)
    {
        $this->output = $output;
        $this->dumper = $dumper;
        $this->cloner = $cloner;

        if (class_exists(CliDumper::class)) {
            $this->handler = function ($var): string {
                $dumper = $this->dumper ?? $this->dumper = new CliDumper(null, null, CliDumper::DUMP_LIGHT_ARRAY | CliDumper::DUMP_COMMA_SEPARATOR);
                $dumper->setColors($this->output->isDecorated());

                return rtrim($dumper->dump(($this->cloner ?? $this->cloner = new VarCloner())->cloneVar($var)->withRefHandles(false), true));
            };
        } else {
            $this->handler = function ($var): string {
                switch (true) {
                    case null === $var:
                        return 'null';
                    case true === $var:
                        return 'true';
                    case false === $var:
                        return 'false';
                    case \is_string($var):
                        return '"'.$var.'"';
                    default:
                        return rtrim(print_r($var, true));
                }
            };
        }
    }

    public function __invoke($var): string
    {
        return ($this->handler)($var);
    }
}
PKϤ$Z-7����!console/Helper/TableCellStyle.phpnu�[���<?php

/*
 * This file is part of the Symfony package.
 *
 * (c) Fabien Potencier <fabien@symfony.com>
 *
 * For the full copyright and license information, please view the LICENSE
 * file that was distributed with this source code.
 */

namespace Symfony\Component\Console\Helper;

use Symfony\Component\Console\Exception\InvalidArgumentException;

/**
 * @author Yewhen Khoptynskyi <khoptynskyi@gmail.com>
 */
class TableCellStyle
{
    public const DEFAULT_ALIGN = 'left';

    private const TAG_OPTIONS = [
        'fg',
        'bg',
        'options',
    ];

    private const ALIGN_MAP = [
        'left' => \STR_PAD_RIGHT,
        'center' => \STR_PAD_BOTH,
        'right' => \STR_PAD_LEFT,
    ];

    private $options = [
        'fg' => 'default',
        'bg' => 'default',
        'options' => null,
        'align' => self::DEFAULT_ALIGN,
        'cellFormat' => null,
    ];

    public function __construct(array $options = [])
    {
        if ($diff = array_diff(array_keys($options), array_keys($this->options))) {
            throw new InvalidArgumentException(sprintf('The TableCellStyle does not support the following options: \'%s\'.', implode('\', \'', $diff)));
        }

        if (isset($options['align']) && !\array_key_exists($options['align'], self::ALIGN_MAP)) {
            throw new InvalidArgumentException(sprintf('Wrong align value. Value must be following: \'%s\'.', implode('\', \'', array_keys(self::ALIGN_MAP))));
        }

        $this->options = array_merge($this->options, $options);
    }

    public function getOptions(): array
    {
        return $this->options;
    }

    /**
     * Gets options we need for tag for example fg, bg.
     *
     * @return string[]
     */
    public function getTagOptions()
    {
        return array_filter(
            $this->getOptions(),
            function ($key) {
                return \in_array($key, self::TAG_OPTIONS) && isset($this->options[$key]);
            },
            \ARRAY_FILTER_USE_KEY
        );
    }

    /**
     * @return int
     */
    public function getPadByAlign()
    {
        return self::ALIGN_MAP[$this->getOptions()['align']];
    }

    public function getCellFormat(): ?string
    {
        return $this->getOptions()['cellFormat'];
    }
}
PKϤ$Z�Nc\IIconsole/Helper/ProgressBar.phpnu�[���<?php

/*
 * This file is part of the Symfony package.
 *
 * (c) Fabien Potencier <fabien@symfony.com>
 *
 * For the full copyright and license information, please view the LICENSE
 * file that was distributed with this source code.
 */

namespace Symfony\Component\Console\Helper;

use Symfony\Component\Console\Cursor;
use Symfony\Component\Console\Exception\LogicException;
use Symfony\Component\Console\Output\ConsoleOutputInterface;
use Symfony\Component\Console\Output\ConsoleSectionOutput;
use Symfony\Component\Console\Output\OutputInterface;
use Symfony\Component\Console\Terminal;

/**
 * The ProgressBar provides helpers to display progress output.
 *
 * @author Fabien Potencier <fabien@symfony.com>
 * @author Chris Jones <leeked@gmail.com>
 */
final class ProgressBar
{
    public const FORMAT_VERBOSE = 'verbose';
    public const FORMAT_VERY_VERBOSE = 'very_verbose';
    public const FORMAT_DEBUG = 'debug';
    public const FORMAT_NORMAL = 'normal';

    private const FORMAT_VERBOSE_NOMAX = 'verbose_nomax';
    private const FORMAT_VERY_VERBOSE_NOMAX = 'very_verbose_nomax';
    private const FORMAT_DEBUG_NOMAX = 'debug_nomax';
    private const FORMAT_NORMAL_NOMAX = 'normal_nomax';

    private $barWidth = 28;
    private $barChar;
    private $emptyBarChar = '-';
    private $progressChar = '>';
    private $format;
    private $internalFormat;
    private $redrawFreq = 1;
    private $writeCount;
    private $lastWriteTime;
    private $minSecondsBetweenRedraws = 0;
    private $maxSecondsBetweenRedraws = 1;
    private $output;
    private $step = 0;
    private $max;
    private $startTime;
    private $stepWidth;
    private $percent = 0.0;
    private $formatLineCount;
    private $messages = [];
    private $overwrite = true;
    private $terminal;
    private $previousMessage;
    private $cursor;

    private static $formatters;
    private static $formats;

    /**
     * @param int $max Maximum steps (0 if unknown)
     */
    public function __construct(OutputInterface $output, int $max = 0, float $minSecondsBetweenRedraws = 1 / 25)
    {
        if ($output instanceof ConsoleOutputInterface) {
            $output = $output->getErrorOutput();
        }

        $this->output = $output;
        $this->setMaxSteps($max);
        $this->terminal = new Terminal();

        if (0 < $minSecondsBetweenRedraws) {
            $this->redrawFreq = null;
            $this->minSecondsBetweenRedraws = $minSecondsBetweenRedraws;
        }

        if (!$this->output->isDecorated()) {
            // disable overwrite when output does not support ANSI codes.
            $this->overwrite = false;

            // set a reasonable redraw frequency so output isn't flooded
            $this->redrawFreq = null;
        }

        $this->startTime = time();
        $this->cursor = new Cursor($output);
    }

    /**
     * Sets a placeholder formatter for a given name.
     *
     * This method also allow you to override an existing placeholder.
     *
     * @param string   $name     The placeholder name (including the delimiter char like %)
     * @param callable $callable A PHP callable
     */
    public static function setPlaceholderFormatterDefinition(string $name, callable $callable): void
    {
        if (!self::$formatters) {
            self::$formatters = self::initPlaceholderFormatters();
        }

        self::$formatters[$name] = $callable;
    }

    /**
     * Gets the placeholder formatter for a given name.
     *
     * @param string $name The placeholder name (including the delimiter char like %)
     */
    public static function getPlaceholderFormatterDefinition(string $name): ?callable
    {
        if (!self::$formatters) {
            self::$formatters = self::initPlaceholderFormatters();
        }

        return self::$formatters[$name] ?? null;
    }

    /**
     * Sets a format for a given name.
     *
     * This method also allow you to override an existing format.
     *
     * @param string $name   The format name
     * @param string $format A format string
     */
    public static function setFormatDefinition(string $name, string $format): void
    {
        if (!self::$formats) {
            self::$formats = self::initFormats();
        }

        self::$formats[$name] = $format;
    }

    /**
     * Gets the format for a given name.
     *
     * @param string $name The format name
     */
    public static function getFormatDefinition(string $name): ?string
    {
        if (!self::$formats) {
            self::$formats = self::initFormats();
        }

        return self::$formats[$name] ?? null;
    }

    /**
     * Associates a text with a named placeholder.
     *
     * The text is displayed when the progress bar is rendered but only
     * when the corresponding placeholder is part of the custom format line
     * (by wrapping the name with %).
     *
     * @param string $message The text to associate with the placeholder
     * @param string $name    The name of the placeholder
     */
    public function setMessage(string $message, string $name = 'message')
    {
        $this->messages[$name] = $message;
    }

    public function getMessage(string $name = 'message')
    {
        return $this->messages[$name];
    }

    public function getStartTime(): int
    {
        return $this->startTime;
    }

    public function getMaxSteps(): int
    {
        return $this->max;
    }

    public function getProgress(): int
    {
        return $this->step;
    }

    private function getStepWidth(): int
    {
        return $this->stepWidth;
    }

    public function getProgressPercent(): float
    {
        return $this->percent;
    }

    public function getBarOffset(): float
    {
        return floor($this->max ? $this->percent * $this->barWidth : (null === $this->redrawFreq ? (int) (min(5, $this->barWidth / 15) * $this->writeCount) : $this->step) % $this->barWidth);
    }

    public function getEstimated(): float
    {
        if (!$this->step) {
            return 0;
        }

        return round((time() - $this->startTime) / $this->step * $this->max);
    }

    public function getRemaining(): float
    {
        if (!$this->step) {
            return 0;
        }

        return round((time() - $this->startTime) / $this->step * ($this->max - $this->step));
    }

    public function setBarWidth(int $size)
    {
        $this->barWidth = max(1, $size);
    }

    public function getBarWidth(): int
    {
        return $this->barWidth;
    }

    public function setBarCharacter(string $char)
    {
        $this->barChar = $char;
    }

    public function getBarCharacter(): string
    {
        return $this->barChar ?? ($this->max ? '=' : $this->emptyBarChar);
    }

    public function setEmptyBarCharacter(string $char)
    {
        $this->emptyBarChar = $char;
    }

    public function getEmptyBarCharacter(): string
    {
        return $this->emptyBarChar;
    }

    public function setProgressCharacter(string $char)
    {
        $this->progressChar = $char;
    }

    public function getProgressCharacter(): string
    {
        return $this->progressChar;
    }

    public function setFormat(string $format)
    {
        $this->format = null;
        $this->internalFormat = $format;
    }

    /**
     * Sets the redraw frequency.
     *
     * @param int|null $freq The frequency in steps
     */
    public function setRedrawFrequency(?int $freq)
    {
        $this->redrawFreq = null !== $freq ? max(1, $freq) : null;
    }

    public function minSecondsBetweenRedraws(float $seconds): void
    {
        $this->minSecondsBetweenRedraws = $seconds;
    }

    public function maxSecondsBetweenRedraws(float $seconds): void
    {
        $this->maxSecondsBetweenRedraws = $seconds;
    }

    /**
     * Returns an iterator that will automatically update the progress bar when iterated.
     *
     * @param int|null $max Number of steps to complete the bar (0 if indeterminate), if null it will be inferred from $iterable
     */
    public function iterate(iterable $iterable, int $max = null): iterable
    {
        $this->start($max ?? (is_countable($iterable) ? \count($iterable) : 0));

        foreach ($iterable as $key => $value) {
            yield $key => $value;

            $this->advance();
        }

        $this->finish();
    }

    /**
     * Starts the progress output.
     *
     * @param int|null $max Number of steps to complete the bar (0 if indeterminate), null to leave unchanged
     */
    public function start(int $max = null)
    {
        $this->startTime = time();
        $this->step = 0;
        $this->percent = 0.0;

        if (null !== $max) {
            $this->setMaxSteps($max);
        }

        $this->display();
    }

    /**
     * Advances the progress output X steps.
     *
     * @param int $step Number of steps to advance
     */
    public function advance(int $step = 1)
    {
        $this->setProgress($this->step + $step);
    }

    /**
     * Sets whether to overwrite the progressbar, false for new line.
     */
    public function setOverwrite(bool $overwrite)
    {
        $this->overwrite = $overwrite;
    }

    public function setProgress(int $step)
    {
        if ($this->max && $step > $this->max) {
            $this->max = $step;
        } elseif ($step < 0) {
            $step = 0;
        }

        $redrawFreq = $this->redrawFreq ?? (($this->max ?: 10) / 10);
        $prevPeriod = (int) ($this->step / $redrawFreq);
        $currPeriod = (int) ($step / $redrawFreq);
        $this->step = $step;
        $this->percent = $this->max ? (float) $this->step / $this->max : 0;
        $timeInterval = microtime(true) - $this->lastWriteTime;

        // Draw regardless of other limits
        if ($this->max === $step) {
            $this->display();

            return;
        }

        // Throttling
        if ($timeInterval < $this->minSecondsBetweenRedraws) {
            return;
        }

        // Draw each step period, but not too late
        if ($prevPeriod !== $currPeriod || $timeInterval >= $this->maxSecondsBetweenRedraws) {
            $this->display();
        }
    }

    public function setMaxSteps(int $max)
    {
        $this->format = null;
        $this->max = max(0, $max);
        $this->stepWidth = $this->max ? Helper::width((string) $this->max) : 4;
    }

    /**
     * Finishes the progress output.
     */
    public function finish(): void
    {
        if (!$this->max) {
            $this->max = $this->step;
        }

        if ($this->step === $this->max && !$this->overwrite) {
            // prevent double 100% output
            return;
        }

        $this->setProgress($this->max);
    }

    /**
     * Outputs the current progress string.
     */
    public function display(): void
    {
        if (OutputInterface::VERBOSITY_QUIET === $this->output->getVerbosity()) {
            return;
        }

        if (null === $this->format) {
            $this->setRealFormat($this->internalFormat ?: $this->determineBestFormat());
        }

        $this->overwrite($this->buildLine());
    }

    /**
     * Removes the progress bar from the current line.
     *
     * This is useful if you wish to write some output
     * while a progress bar is running.
     * Call display() to show the progress bar again.
     */
    public function clear(): void
    {
        if (!$this->overwrite) {
            return;
        }

        if (null === $this->format) {
            $this->setRealFormat($this->internalFormat ?: $this->determineBestFormat());
        }

        $this->overwrite('');
    }

    private function setRealFormat(string $format)
    {
        // try to use the _nomax variant if available
        if (!$this->max && null !== self::getFormatDefinition($format.'_nomax')) {
            $this->format = self::getFormatDefinition($format.'_nomax');
        } elseif (null !== self::getFormatDefinition($format)) {
            $this->format = self::getFormatDefinition($format);
        } else {
            $this->format = $format;
        }

        $this->formatLineCount = substr_count($this->format, "\n");
    }

    /**
     * Overwrites a previous message to the output.
     */
    private function overwrite(string $message): void
    {
        if ($this->previousMessage === $message) {
            return;
        }

        $originalMessage = $message;

        if ($this->overwrite) {
            if (null !== $this->previousMessage) {
                if ($this->output instanceof ConsoleSectionOutput) {
                    $messageLines = explode("\n", $message);
                    $lineCount = \count($messageLines);
                    foreach ($messageLines as $messageLine) {
                        $messageLineLength = Helper::width(Helper::removeDecoration($this->output->getFormatter(), $messageLine));
                        if ($messageLineLength > $this->terminal->getWidth()) {
                            $lineCount += floor($messageLineLength / $this->terminal->getWidth());
                        }
                    }
                    $this->output->clear($lineCount);
                } else {
                    for ($i = 0; $i < $this->formatLineCount; ++$i) {
                        $this->cursor->moveToColumn(1);
                        $this->cursor->clearLine();
                        $this->cursor->moveUp();
                    }

                    $this->cursor->moveToColumn(1);
                    $this->cursor->clearLine();
                }
            }
        } elseif ($this->step > 0) {
            $message = \PHP_EOL.$message;
        }

        $this->previousMessage = $originalMessage;
        $this->lastWriteTime = microtime(true);

        $this->output->write($message);
        ++$this->writeCount;
    }

    private function determineBestFormat(): string
    {
        switch ($this->output->getVerbosity()) {
            // OutputInterface::VERBOSITY_QUIET: display is disabled anyway
            case OutputInterface::VERBOSITY_VERBOSE:
                return $this->max ? self::FORMAT_VERBOSE : self::FORMAT_VERBOSE_NOMAX;
            case OutputInterface::VERBOSITY_VERY_VERBOSE:
                return $this->max ? self::FORMAT_VERY_VERBOSE : self::FORMAT_VERY_VERBOSE_NOMAX;
            case OutputInterface::VERBOSITY_DEBUG:
                return $this->max ? self::FORMAT_DEBUG : self::FORMAT_DEBUG_NOMAX;
            default:
                return $this->max ? self::FORMAT_NORMAL : self::FORMAT_NORMAL_NOMAX;
        }
    }

    private static function initPlaceholderFormatters(): array
    {
        return [
            'bar' => function (self $bar, OutputInterface $output) {
                $completeBars = $bar->getBarOffset();
                $display = str_repeat($bar->getBarCharacter(), $completeBars);
                if ($completeBars < $bar->getBarWidth()) {
                    $emptyBars = $bar->getBarWidth() - $completeBars - Helper::length(Helper::removeDecoration($output->getFormatter(), $bar->getProgressCharacter()));
                    $display .= $bar->getProgressCharacter().str_repeat($bar->getEmptyBarCharacter(), $emptyBars);
                }

                return $display;
            },
            'elapsed' => function (self $bar) {
                return Helper::formatTime(time() - $bar->getStartTime());
            },
            'remaining' => function (self $bar) {
                if (!$bar->getMaxSteps()) {
                    throw new LogicException('Unable to display the remaining time if the maximum number of steps is not set.');
                }

                return Helper::formatTime($bar->getRemaining());
            },
            'estimated' => function (self $bar) {
                if (!$bar->getMaxSteps()) {
                    throw new LogicException('Unable to display the estimated time if the maximum number of steps is not set.');
                }

                return Helper::formatTime($bar->getEstimated());
            },
            'memory' => function (self $bar) {
                return Helper::formatMemory(memory_get_usage(true));
            },
            'current' => function (self $bar) {
                return str_pad($bar->getProgress(), $bar->getStepWidth(), ' ', \STR_PAD_LEFT);
            },
            'max' => function (self $bar) {
                return $bar->getMaxSteps();
            },
            'percent' => function (self $bar) {
                return floor($bar->getProgressPercent() * 100);
            },
        ];
    }

    private static function initFormats(): array
    {
        return [
            self::FORMAT_NORMAL => ' %current%/%max% [%bar%] %percent:3s%%',
            self::FORMAT_NORMAL_NOMAX => ' %current% [%bar%]',

            self::FORMAT_VERBOSE => ' %current%/%max% [%bar%] %percent:3s%% %elapsed:6s%',
            self::FORMAT_VERBOSE_NOMAX => ' %current% [%bar%] %elapsed:6s%',

            self::FORMAT_VERY_VERBOSE => ' %current%/%max% [%bar%] %percent:3s%% %elapsed:6s%/%estimated:-6s%',
            self::FORMAT_VERY_VERBOSE_NOMAX => ' %current% [%bar%] %elapsed:6s%',

            self::FORMAT_DEBUG => ' %current%/%max% [%bar%] %percent:3s%% %elapsed:6s%/%estimated:-6s% %memory:6s%',
            self::FORMAT_DEBUG_NOMAX => ' %current% [%bar%] %elapsed:6s% %memory:6s%',
        ];
    }

    private function buildLine(): string
    {
        $regex = "{%([a-z\-_]+)(?:\:([^%]+))?%}i";
        $callback = function ($matches) {
            if ($formatter = $this::getPlaceholderFormatterDefinition($matches[1])) {
                $text = $formatter($this, $this->output);
            } elseif (isset($this->messages[$matches[1]])) {
                $text = $this->messages[$matches[1]];
            } else {
                return $matches[0];
            }

            if (isset($matches[2])) {
                $text = sprintf('%'.$matches[2], $text);
            }

            return $text;
        };
        $line = preg_replace_callback($regex, $callback, $this->format);

        // gets string length for each sub line with multiline format
        $linesLength = array_map(function ($subLine) {
            return Helper::width(Helper::removeDecoration($this->output->getFormatter(), rtrim($subLine, "\r")));
        }, explode("\n", $line));

        $linesWidth = max($linesLength);

        $terminalWidth = $this->terminal->getWidth();
        if ($linesWidth <= $terminalWidth) {
            return $line;
        }

        $this->setBarWidth($this->barWidth - $linesWidth + $terminalWidth);

        return preg_replace_callback($regex, $callback, $this->format);
    }
}
PKϤ$Z����#console/Helper/InputAwareHelper.phpnu�[���<?php

/*
 * This file is part of the Symfony package.
 *
 * (c) Fabien Potencier <fabien@symfony.com>
 *
 * For the full copyright and license information, please view the LICENSE
 * file that was distributed with this source code.
 */

namespace Symfony\Component\Console\Helper;

use Symfony\Component\Console\Input\InputAwareInterface;
use Symfony\Component\Console\Input\InputInterface;

/**
 * An implementation of InputAwareInterface for Helpers.
 *
 * @author Wouter J <waldio.webdesign@gmail.com>
 */
abstract class InputAwareHelper extends Helper implements InputAwareInterface
{
    protected $input;

    /**
     * {@inheritdoc}
     */
    public function setInput(InputInterface $input)
    {
        $this->input = $input;
    }
}
PKϤ$Z�3T��(console/Helper/SymfonyQuestionHelper.phpnu�[���<?php

/*
 * This file is part of the Symfony package.
 *
 * (c) Fabien Potencier <fabien@symfony.com>
 *
 * For the full copyright and license information, please view the LICENSE
 * file that was distributed with this source code.
 */

namespace Symfony\Component\Console\Helper;

use Symfony\Component\Console\Formatter\OutputFormatter;
use Symfony\Component\Console\Output\OutputInterface;
use Symfony\Component\Console\Question\ChoiceQuestion;
use Symfony\Component\Console\Question\ConfirmationQuestion;
use Symfony\Component\Console\Question\Question;
use Symfony\Component\Console\Style\SymfonyStyle;

/**
 * Symfony Style Guide compliant question helper.
 *
 * @author Kevin Bond <kevinbond@gmail.com>
 */
class SymfonyQuestionHelper extends QuestionHelper
{
    /**
     * {@inheritdoc}
     */
    protected function writePrompt(OutputInterface $output, Question $question)
    {
        $text = OutputFormatter::escapeTrailingBackslash($question->getQuestion());
        $default = $question->getDefault();

        if ($question->isMultiline()) {
            $text .= sprintf(' (press %s to continue)', $this->getEofShortcut());
        }

        switch (true) {
            case null === $default:
                $text = sprintf(' <info>%s</info>:', $text);

                break;

            case $question instanceof ConfirmationQuestion:
                $text = sprintf(' <info>%s (yes/no)</info> [<comment>%s</comment>]:', $text, $default ? 'yes' : 'no');

                break;

            case $question instanceof ChoiceQuestion && $question->isMultiselect():
                $choices = $question->getChoices();
                $default = explode(',', $default);

                foreach ($default as $key => $value) {
                    $default[$key] = $choices[trim($value)];
                }

                $text = sprintf(' <info>%s</info> [<comment>%s</comment>]:', $text, OutputFormatter::escape(implode(', ', $default)));

                break;

            case $question instanceof ChoiceQuestion:
                $choices = $question->getChoices();
                $text = sprintf(' <info>%s</info> [<comment>%s</comment>]:', $text, OutputFormatter::escape($choices[$default] ?? $default));

                break;

            default:
                $text = sprintf(' <info>%s</info> [<comment>%s</comment>]:', $text, OutputFormatter::escape($default));
        }

        $output->writeln($text);

        $prompt = ' > ';

        if ($question instanceof ChoiceQuestion) {
            $output->writeln($this->formatChoiceQuestionChoices($question, 'comment'));

            $prompt = $question->getPrompt();
        }

        $output->write($prompt);
    }

    /**
     * {@inheritdoc}
     */
    protected function writeError(OutputInterface $output, \Exception $error)
    {
        if ($output instanceof SymfonyStyle) {
            $output->newLine();
            $output->error($error->getMessage());

            return;
        }

        parent::writeError($output, $error);
    }

    private function getEofShortcut(): string
    {
        if ('Windows' === \PHP_OS_FAMILY) {
            return '<comment>Ctrl+Z</comment> then <comment>Enter</comment>';
        }

        return '<comment>Ctrl+D</comment>';
    }
}
PKϤ$Zd��8MM"console/Helper/HelperInterface.phpnu�[���<?php

/*
 * This file is part of the Symfony package.
 *
 * (c) Fabien Potencier <fabien@symfony.com>
 *
 * For the full copyright and license information, please view the LICENSE
 * file that was distributed with this source code.
 */

namespace Symfony\Component\Console\Helper;

/**
 * HelperInterface is the interface all helpers must implement.
 *
 * @author Fabien Potencier <fabien@symfony.com>
 */
interface HelperInterface
{
    /**
     * Sets the helper set associated with this helper.
     */
    public function setHelperSet(HelperSet $helperSet = null);

    /**
     * Gets the helper set associated with this helper.
     *
     * @return HelperSet|null
     */
    public function getHelperSet();

    /**
     * Returns the canonical name of this helper.
     *
     * @return string
     */
    public function getName();
}
PKϤ$Z���console/Helper/Helper.phpnu�[���<?php

/*
 * This file is part of the Symfony package.
 *
 * (c) Fabien Potencier <fabien@symfony.com>
 *
 * For the full copyright and license information, please view the LICENSE
 * file that was distributed with this source code.
 */

namespace Symfony\Component\Console\Helper;

use Symfony\Component\Console\Formatter\OutputFormatterInterface;
use Symfony\Component\String\UnicodeString;

/**
 * Helper is the base class for all helper classes.
 *
 * @author Fabien Potencier <fabien@symfony.com>
 */
abstract class Helper implements HelperInterface
{
    protected $helperSet = null;

    /**
     * {@inheritdoc}
     */
    public function setHelperSet(HelperSet $helperSet = null)
    {
        $this->helperSet = $helperSet;
    }

    /**
     * {@inheritdoc}
     */
    public function getHelperSet()
    {
        return $this->helperSet;
    }

    /**
     * Returns the length of a string, using mb_strwidth if it is available.
     *
     * @deprecated since Symfony 5.3
     *
     * @return int
     */
    public static function strlen(?string $string)
    {
        trigger_deprecation('symfony/console', '5.3', 'Method "%s()" is deprecated and will be removed in Symfony 6.0. Use Helper::width() or Helper::length() instead.', __METHOD__);

        return self::width($string);
    }

    /**
     * Returns the width of a string, using mb_strwidth if it is available.
     * The width is how many characters positions the string will use.
     */
    public static function width(?string $string): int
    {
        $string ?? $string = '';

        if (preg_match('//u', $string)) {
            return (new UnicodeString($string))->width(false);
        }

        if (false === $encoding = mb_detect_encoding($string, null, true)) {
            return \strlen($string);
        }

        return mb_strwidth($string, $encoding);
    }

    /**
     * Returns the length of a string, using mb_strlen if it is available.
     * The length is related to how many bytes the string will use.
     */
    public static function length(?string $string): int
    {
        $string ?? $string = '';

        if (preg_match('//u', $string)) {
            return (new UnicodeString($string))->length();
        }

        if (false === $encoding = mb_detect_encoding($string, null, true)) {
            return \strlen($string);
        }

        return mb_strlen($string, $encoding);
    }

    /**
     * Returns the subset of a string, using mb_substr if it is available.
     *
     * @return string
     */
    public static function substr(?string $string, int $from, int $length = null)
    {
        $string ?? $string = '';

        if (false === $encoding = mb_detect_encoding($string, null, true)) {
            return substr($string, $from, $length);
        }

        return mb_substr($string, $from, $length, $encoding);
    }

    public static function formatTime($secs)
    {
        static $timeFormats = [
            [0, '< 1 sec'],
            [1, '1 sec'],
            [2, 'secs', 1],
            [60, '1 min'],
            [120, 'mins', 60],
            [3600, '1 hr'],
            [7200, 'hrs', 3600],
            [86400, '1 day'],
            [172800, 'days', 86400],
        ];

        foreach ($timeFormats as $index => $format) {
            if ($secs >= $format[0]) {
                if ((isset($timeFormats[$index + 1]) && $secs < $timeFormats[$index + 1][0])
                    || $index == \count($timeFormats) - 1
                ) {
                    if (2 == \count($format)) {
                        return $format[1];
                    }

                    return floor($secs / $format[2]).' '.$format[1];
                }
            }
        }
    }

    public static function formatMemory(int $memory)
    {
        if ($memory >= 1024 * 1024 * 1024) {
            return sprintf('%.1f GiB', $memory / 1024 / 1024 / 1024);
        }

        if ($memory >= 1024 * 1024) {
            return sprintf('%.1f MiB', $memory / 1024 / 1024);
        }

        if ($memory >= 1024) {
            return sprintf('%d KiB', $memory / 1024);
        }

        return sprintf('%d B', $memory);
    }

    /**
     * @deprecated since Symfony 5.3
     */
    public static function strlenWithoutDecoration(OutputFormatterInterface $formatter, ?string $string)
    {
        trigger_deprecation('symfony/console', '5.3', 'Method "%s()" is deprecated and will be removed in Symfony 6.0. Use Helper::removeDecoration() instead.', __METHOD__);

        return self::width(self::removeDecoration($formatter, $string));
    }

    public static function removeDecoration(OutputFormatterInterface $formatter, ?string $string)
    {
        $isDecorated = $formatter->isDecorated();
        $formatter->setDecorated(false);
        // remove <...> formatting
        $string = $formatter->format($string ?? '');
        // remove already formatted characters
        $string = preg_replace("/\033\[[^m]*m/", '', $string ?? '');
        $formatter->setDecorated($isDecorated);

        return $string;
    }
}
PKϤ$Z&��
!console/Helper/TableSeparator.phpnu�[���<?php

/*
 * This file is part of the Symfony package.
 *
 * (c) Fabien Potencier <fabien@symfony.com>
 *
 * For the full copyright and license information, please view the LICENSE
 * file that was distributed with this source code.
 */

namespace Symfony\Component\Console\Helper;

/**
 * Marks a row as being a separator.
 *
 * @author Fabien Potencier <fabien@symfony.com>
 */
class TableSeparator extends TableCell
{
    public function __construct(array $options = [])
    {
        parent::__construct('', $options);
    }
}
PKϤ$Z��.console/Helper/TableCell.phpnu�[���<?php

/*
 * This file is part of the Symfony package.
 *
 * (c) Fabien Potencier <fabien@symfony.com>
 *
 * For the full copyright and license information, please view the LICENSE
 * file that was distributed with this source code.
 */

namespace Symfony\Component\Console\Helper;

use Symfony\Component\Console\Exception\InvalidArgumentException;

/**
 * @author Abdellatif Ait boudad <a.aitboudad@gmail.com>
 */
class TableCell
{
    private $value;
    private $options = [
        'rowspan' => 1,
        'colspan' => 1,
        'style' => null,
    ];

    public function __construct(string $value = '', array $options = [])
    {
        $this->value = $value;

        // check option names
        if ($diff = array_diff(array_keys($options), array_keys($this->options))) {
            throw new InvalidArgumentException(sprintf('The TableCell does not support the following options: \'%s\'.', implode('\', \'', $diff)));
        }

        if (isset($options['style']) && !$options['style'] instanceof TableCellStyle) {
            throw new InvalidArgumentException('The style option must be an instance of "TableCellStyle".');
        }

        $this->options = array_merge($this->options, $options);
    }

    /**
     * Returns the cell value.
     *
     * @return string
     */
    public function __toString()
    {
        return $this->value;
    }

    /**
     * Gets number of colspan.
     *
     * @return int
     */
    public function getColspan()
    {
        return (int) $this->options['colspan'];
    }

    /**
     * Gets number of rowspan.
     *
     * @return int
     */
    public function getRowspan()
    {
        return (int) $this->options['rowspan'];
    }

    public function getStyle(): ?TableCellStyle
    {
        return $this->options['style'];
    }
}
PKϤ$ZG�(�J
J
'console/Helper/DebugFormatterHelper.phpnu�[���<?php

/*
 * This file is part of the Symfony package.
 *
 * (c) Fabien Potencier <fabien@symfony.com>
 *
 * For the full copyright and license information, please view the LICENSE
 * file that was distributed with this source code.
 */

namespace Symfony\Component\Console\Helper;

/**
 * Helps outputting debug information when running an external program from a command.
 *
 * An external program can be a Process, an HTTP request, or anything else.
 *
 * @author Fabien Potencier <fabien@symfony.com>
 */
class DebugFormatterHelper extends Helper
{
    private const COLORS = ['black', 'red', 'green', 'yellow', 'blue', 'magenta', 'cyan', 'white', 'default'];
    private $started = [];
    private $count = -1;

    /**
     * Starts a debug formatting session.
     *
     * @return string
     */
    public function start(string $id, string $message, string $prefix = 'RUN')
    {
        $this->started[$id] = ['border' => ++$this->count % \count(self::COLORS)];

        return sprintf("%s<bg=blue;fg=white> %s </> <fg=blue>%s</>\n", $this->getBorder($id), $prefix, $message);
    }

    /**
     * Adds progress to a formatting session.
     *
     * @return string
     */
    public function progress(string $id, string $buffer, bool $error = false, string $prefix = 'OUT', string $errorPrefix = 'ERR')
    {
        $message = '';

        if ($error) {
            if (isset($this->started[$id]['out'])) {
                $message .= "\n";
                unset($this->started[$id]['out']);
            }
            if (!isset($this->started[$id]['err'])) {
                $message .= sprintf('%s<bg=red;fg=white> %s </> ', $this->getBorder($id), $errorPrefix);
                $this->started[$id]['err'] = true;
            }

            $message .= str_replace("\n", sprintf("\n%s<bg=red;fg=white> %s </> ", $this->getBorder($id), $errorPrefix), $buffer);
        } else {
            if (isset($this->started[$id]['err'])) {
                $message .= "\n";
                unset($this->started[$id]['err']);
            }
            if (!isset($this->started[$id]['out'])) {
                $message .= sprintf('%s<bg=green;fg=white> %s </> ', $this->getBorder($id), $prefix);
                $this->started[$id]['out'] = true;
            }

            $message .= str_replace("\n", sprintf("\n%s<bg=green;fg=white> %s </> ", $this->getBorder($id), $prefix), $buffer);
        }

        return $message;
    }

    /**
     * Stops a formatting session.
     *
     * @return string
     */
    public function stop(string $id, string $message, bool $successful, string $prefix = 'RES')
    {
        $trailingEOL = isset($this->started[$id]['out']) || isset($this->started[$id]['err']) ? "\n" : '';

        if ($successful) {
            return sprintf("%s%s<bg=green;fg=white> %s </> <fg=green>%s</>\n", $trailingEOL, $this->getBorder($id), $prefix, $message);
        }

        $message = sprintf("%s%s<bg=red;fg=white> %s </> <fg=red>%s</>\n", $trailingEOL, $this->getBorder($id), $prefix, $message);

        unset($this->started[$id]['out'], $this->started[$id]['err']);

        return $message;
    }

    private function getBorder(string $id): string
    {
        return sprintf('<bg=%s> </>', self::COLORS[$this->started[$id]['border']]);
    }

    /**
     * {@inheritdoc}
     */
    public function getName()
    {
        return 'debug_formatter';
    }
}
PKϤ$Z��sRo1o1!console/Helper/ProgressHelper.phpnu�[���<?php

/*
 * This file is part of the Symfony package.
 *
 * (c) Fabien Potencier <fabien@symfony.com>
 *
 * For the full copyright and license information, please view the LICENSE
 * file that was distributed with this source code.
 */

namespace Symfony\Component\Console\Helper;

use Symfony\Component\Console\Output\NullOutput;
use Symfony\Component\Console\Output\ConsoleOutputInterface;
use Symfony\Component\Console\Output\OutputInterface;
use Symfony\Component\Console\Exception\LogicException;

/**
 * The Progress class provides helpers to display progress output.
 *
 * @author Chris Jones <leeked@gmail.com>
 * @author Fabien Potencier <fabien@symfony.com>
 *
 * @deprecated since version 2.5, to be removed in 3.0
 *             Use {@link ProgressBar} instead.
 */
class ProgressHelper extends Helper
{
    const FORMAT_QUIET = ' %percent%%';
    const FORMAT_NORMAL = ' %current%/%max% [%bar%] %percent%%';
    const FORMAT_VERBOSE = ' %current%/%max% [%bar%] %percent%% Elapsed: %elapsed%';
    const FORMAT_QUIET_NOMAX = ' %current%';
    const FORMAT_NORMAL_NOMAX = ' %current% [%bar%]';
    const FORMAT_VERBOSE_NOMAX = ' %current% [%bar%] Elapsed: %elapsed%';

    // options
    private $barWidth = 28;
    private $barChar = '=';
    private $emptyBarChar = '-';
    private $progressChar = '>';
    private $format = null;
    private $redrawFreq = 1;

    private $lastMessagesLength;
    private $barCharOriginal;

    /**
     * @var OutputInterface
     */
    private $output;

    /**
     * Current step.
     *
     * @var int
     */
    private $current;

    /**
     * Maximum number of steps.
     *
     * @var int
     */
    private $max;

    /**
     * Start time of the progress bar.
     *
     * @var int
     */
    private $startTime;

    /**
     * List of formatting variables.
     *
     * @var array
     */
    private $defaultFormatVars = array(
        'current',
        'max',
        'bar',
        'percent',
        'elapsed',
    );

    /**
     * Available formatting variables.
     *
     * @var array
     */
    private $formatVars;

    /**
     * Stored format part widths (used for padding).
     *
     * @var array
     */
    private $widths = array(
        'current' => 4,
        'max' => 4,
        'percent' => 3,
        'elapsed' => 6,
    );

    /**
     * Various time formats.
     *
     * @var array
     */
    private $timeFormats = array(
        array(0, '???'),
        array(2, '1 sec'),
        array(59, 'secs', 1),
        array(60, '1 min'),
        array(3600, 'mins', 60),
        array(5400, '1 hr'),
        array(86400, 'hrs', 3600),
        array(129600, '1 day'),
        array(604800, 'days', 86400),
    );

    public function __construct($triggerDeprecationError = true)
    {
        if ($triggerDeprecationError) {
            @trigger_error('The '.__CLASS__.' class is deprecated since version 2.5 and will be removed in 3.0. Use the Symfony\Component\Console\Helper\ProgressBar class instead.', E_USER_DEPRECATED);
        }
    }

    /**
     * Sets the progress bar width.
     *
     * @param int $size The progress bar size
     */
    public function setBarWidth($size)
    {
        $this->barWidth = (int) $size;
    }

    /**
     * Sets the bar character.
     *
     * @param string $char A character
     */
    public function setBarCharacter($char)
    {
        $this->barChar = $char;
    }

    /**
     * Sets the empty bar character.
     *
     * @param string $char A character
     */
    public function setEmptyBarCharacter($char)
    {
        $this->emptyBarChar = $char;
    }

    /**
     * Sets the progress bar character.
     *
     * @param string $char A character
     */
    public function setProgressCharacter($char)
    {
        $this->progressChar = $char;
    }

    /**
     * Sets the progress bar format.
     *
     * @param string $format The format
     */
    public function setFormat($format)
    {
        $this->format = $format;
    }

    /**
     * Sets the redraw frequency.
     *
     * @param int $freq The frequency in steps
     */
    public function setRedrawFrequency($freq)
    {
        $this->redrawFreq = (int) $freq;
    }

    /**
     * Starts the progress output.
     *
     * @param OutputInterface $output An Output instance
     * @param int|null        $max    Maximum steps
     */
    public function start(OutputInterface $output, $max = null)
    {
        if ($output instanceof ConsoleOutputInterface) {
            $output = $output->getErrorOutput();
        }

        $this->startTime = time();
        $this->current = 0;
        $this->max = (int) $max;

        // Disabling output when it does not support ANSI codes as it would result in a broken display anyway.
        $this->output = $output->isDecorated() ? $output : new NullOutput();
        $this->lastMessagesLength = 0;
        $this->barCharOriginal = '';

        if (null === $this->format) {
            switch ($output->getVerbosity()) {
                case OutputInterface::VERBOSITY_QUIET:
                    $this->format = self::FORMAT_QUIET_NOMAX;
                    if ($this->max > 0) {
                        $this->format = self::FORMAT_QUIET;
                    }
                    break;
                case OutputInterface::VERBOSITY_VERBOSE:
                case OutputInterface::VERBOSITY_VERY_VERBOSE:
                case OutputInterface::VERBOSITY_DEBUG:
                    $this->format = self::FORMAT_VERBOSE_NOMAX;
                    if ($this->max > 0) {
                        $this->format = self::FORMAT_VERBOSE;
                    }
                    break;
                default:
                    $this->format = self::FORMAT_NORMAL_NOMAX;
                    if ($this->max > 0) {
                        $this->format = self::FORMAT_NORMAL;
                    }
                    break;
            }
        }

        $this->initialize();
    }

    /**
     * Advances the progress output X steps.
     *
     * @param int  $step   Number of steps to advance
     * @param bool $redraw Whether to redraw or not
     *
     * @throws LogicException
     */
    public function advance($step = 1, $redraw = false)
    {
        $this->setCurrent($this->current + $step, $redraw);
    }

    /**
     * Sets the current progress.
     *
     * @param int  $current The current progress
     * @param bool $redraw  Whether to redraw or not
     *
     * @throws LogicException
     */
    public function setCurrent($current, $redraw = false)
    {
        if (null === $this->startTime) {
            throw new LogicException('You must start the progress bar before calling setCurrent().');
        }

        $current = (int) $current;

        if ($current < $this->current) {
            throw new LogicException('You can\'t regress the progress bar');
        }

        if (0 === $this->current) {
            $redraw = true;
        }

        $prevPeriod = (int) ($this->current / $this->redrawFreq);

        $this->current = $current;

        $currPeriod = (int) ($this->current / $this->redrawFreq);
        if ($redraw || $prevPeriod !== $currPeriod || $this->max === $this->current) {
            $this->display();
        }
    }

    /**
     * Outputs the current progress string.
     *
     * @param bool $finish Forces the end result
     *
     * @throws LogicException
     */
    public function display($finish = false)
    {
        if (null === $this->startTime) {
            throw new LogicException('You must start the progress bar before calling display().');
        }

        $message = $this->format;
        foreach ($this->generate($finish) as $name => $value) {
            $message = str_replace("%{$name}%", $value, $message);
        }
        $this->overwrite($this->output, $message);
    }

    /**
     * Removes the progress bar from the current line.
     *
     * This is useful if you wish to write some output
     * while a progress bar is running.
     * Call display() to show the progress bar again.
     */
    public function clear()
    {
        $this->overwrite($this->output, '');
    }

    /**
     * Finishes the progress output.
     */
    public function finish()
    {
        if (null === $this->startTime) {
            throw new LogicException('You must start the progress bar before calling finish().');
        }

        if (null !== $this->startTime) {
            if (!$this->max) {
                $this->barChar = $this->barCharOriginal;
                $this->display(true);
            }
            $this->startTime = null;
            $this->output->writeln('');
            $this->output = null;
        }
    }

    /**
     * Initializes the progress helper.
     */
    private function initialize()
    {
        $this->formatVars = array();
        foreach ($this->defaultFormatVars as $var) {
            if (false !== strpos($this->format, "%{$var}%")) {
                $this->formatVars[$var] = true;
            }
        }

        if ($this->max > 0) {
            $this->widths['max'] = $this->strlen($this->max);
            $this->widths['current'] = $this->widths['max'];
        } else {
            $this->barCharOriginal = $this->barChar;
            $this->barChar = $this->emptyBarChar;
        }
    }

    /**
     * Generates the array map of format variables to values.
     *
     * @param bool $finish Forces the end result
     *
     * @return array Array of format vars and values
     */
    private function generate($finish = false)
    {
        $vars = array();
        $percent = 0;
        if ($this->max > 0) {
            $percent = (float) $this->current / $this->max;
        }

        if (isset($this->formatVars['bar'])) {
            $completeBars = 0;

            if ($this->max > 0) {
                $completeBars = floor($percent * $this->barWidth);
            } else {
                if (!$finish) {
                    $completeBars = floor($this->current % $this->barWidth);
                } else {
                    $completeBars = $this->barWidth;
                }
            }

            $emptyBars = $this->barWidth - $completeBars - $this->strlen($this->progressChar);
            $bar = str_repeat($this->barChar, $completeBars);
            if ($completeBars < $this->barWidth) {
                $bar .= $this->progressChar;
                $bar .= str_repeat($this->emptyBarChar, $emptyBars);
            }

            $vars['bar'] = $bar;
        }

        if (isset($this->formatVars['elapsed'])) {
            $elapsed = time() - $this->startTime;
            $vars['elapsed'] = str_pad($this->humaneTime($elapsed), $this->widths['elapsed'], ' ', STR_PAD_LEFT);
        }

        if (isset($this->formatVars['current'])) {
            $vars['current'] = str_pad($this->current, $this->widths['current'], ' ', STR_PAD_LEFT);
        }

        if (isset($this->formatVars['max'])) {
            $vars['max'] = $this->max;
        }

        if (isset($this->formatVars['percent'])) {
            $vars['percent'] = str_pad(floor($percent * 100), $this->widths['percent'], ' ', STR_PAD_LEFT);
        }

        return $vars;
    }

    /**
     * Converts seconds into human-readable format.
     *
     * @param int $secs Number of seconds
     *
     * @return string Time in readable format
     */
    private function humaneTime($secs)
    {
        $text = '';
        foreach ($this->timeFormats as $format) {
            if ($secs < $format[0]) {
                if (count($format) == 2) {
                    $text = $format[1];
                    break;
                } else {
                    $text = ceil($secs / $format[2]).' '.$format[1];
                    break;
                }
            }
        }

        return $text;
    }

    /**
     * Overwrites a previous message to the output.
     *
     * @param OutputInterface $output  An Output instance
     * @param string          $message The message
     */
    private function overwrite(OutputInterface $output, $message)
    {
        $length = $this->strlen($message);

        // append whitespace to match the last line's length
        if (null !== $this->lastMessagesLength && $this->lastMessagesLength > $length) {
            $message = str_pad($message, $this->lastMessagesLength, "\x20", STR_PAD_RIGHT);
        }

        // carriage return
        $output->write("\x0D");
        $output->write($message);

        $this->lastMessagesLength = $this->strlen($message);
    }

    /**
     * {@inheritdoc}
     */
    public function getName()
    {
        return 'progress';
    }
}
PKϤ$Zu�wYX	X	"console/Helper/FormatterHelper.phpnu�[���<?php

/*
 * This file is part of the Symfony package.
 *
 * (c) Fabien Potencier <fabien@symfony.com>
 *
 * For the full copyright and license information, please view the LICENSE
 * file that was distributed with this source code.
 */

namespace Symfony\Component\Console\Helper;

use Symfony\Component\Console\Formatter\OutputFormatter;

/**
 * The Formatter class provides helpers to format messages.
 *
 * @author Fabien Potencier <fabien@symfony.com>
 */
class FormatterHelper extends Helper
{
    /**
     * Formats a message within a section.
     *
     * @return string
     */
    public function formatSection(string $section, string $message, string $style = 'info')
    {
        return sprintf('<%s>[%s]</%s> %s', $style, $section, $style, $message);
    }

    /**
     * Formats a message as a block of text.
     *
     * @param string|array $messages The message to write in the block
     *
     * @return string
     */
    public function formatBlock($messages, string $style, bool $large = false)
    {
        if (!\is_array($messages)) {
            $messages = [$messages];
        }

        $len = 0;
        $lines = [];
        foreach ($messages as $message) {
            $message = OutputFormatter::escape($message);
            $lines[] = sprintf($large ? '  %s  ' : ' %s ', $message);
            $len = max(self::width($message) + ($large ? 4 : 2), $len);
        }

        $messages = $large ? [str_repeat(' ', $len)] : [];
        for ($i = 0; isset($lines[$i]); ++$i) {
            $messages[] = $lines[$i].str_repeat(' ', $len - self::width($lines[$i]));
        }
        if ($large) {
            $messages[] = str_repeat(' ', $len);
        }

        for ($i = 0; isset($messages[$i]); ++$i) {
            $messages[$i] = sprintf('<%s>%s</%s>', $style, $messages[$i], $style);
        }

        return implode("\n", $messages);
    }

    /**
     * Truncates a message to the given length.
     *
     * @return string
     */
    public function truncate(string $message, int $length, string $suffix = '...')
    {
        $computedLength = $length - self::width($suffix);

        if ($computedLength > self::width($message)) {
            return $message;
        }

        return self::substr($message, 0, $length).$suffix;
    }

    /**
     * {@inheritdoc}
     */
    public function getName()
    {
        return 'formatter';
    }
}
PKϤ$Z�3�ooconsole/Helper/TableHelper.phpnu�[���<?php

/*
 * This file is part of the Symfony package.
 *
 * (c) Fabien Potencier <fabien@symfony.com>
 *
 * For the full copyright and license information, please view the LICENSE
 * file that was distributed with this source code.
 */

namespace Symfony\Component\Console\Helper;

use Symfony\Component\Console\Output\OutputInterface;
use Symfony\Component\Console\Output\NullOutput;
use Symfony\Component\Console\Exception\InvalidArgumentException;

/**
 * Provides helpers to display table output.
 *
 * @author Саша Стаменковић <umpirsky@gmail.com>
 * @author Fabien Potencier <fabien@symfony.com>
 *
 * @deprecated since version 2.5, to be removed in 3.0
 *             Use {@link Table} instead.
 */
class TableHelper extends Helper
{
    const LAYOUT_DEFAULT = 0;
    const LAYOUT_BORDERLESS = 1;
    const LAYOUT_COMPACT = 2;

    /**
     * @var Table
     */
    private $table;

    public function __construct($triggerDeprecationError = true)
    {
        if ($triggerDeprecationError) {
            @trigger_error('The '.__CLASS__.' class is deprecated since version 2.5 and will be removed in 3.0. Use the Symfony\Component\Console\Helper\Table class instead.', E_USER_DEPRECATED);
        }

        $this->table = new Table(new NullOutput());
    }

    /**
     * Sets table layout type.
     *
     * @param int $layout self::LAYOUT_*
     *
     * @return TableHelper
     *
     * @throws InvalidArgumentException when the table layout is not known
     */
    public function setLayout($layout)
    {
        switch ($layout) {
            case self::LAYOUT_BORDERLESS:
                $this->table->setStyle('borderless');
                break;

            case self::LAYOUT_COMPACT:
                $this->table->setStyle('compact');
                break;

            case self::LAYOUT_DEFAULT:
                $this->table->setStyle('default');
                break;

            default:
                throw new InvalidArgumentException(sprintf('Invalid table layout "%s".', $layout));
        }

        return $this;
    }

    public function setHeaders(array $headers)
    {
        $this->table->setHeaders($headers);

        return $this;
    }

    public function setRows(array $rows)
    {
        $this->table->setRows($rows);

        return $this;
    }

    public function addRows(array $rows)
    {
        $this->table->addRows($rows);

        return $this;
    }

    public function addRow(array $row)
    {
        $this->table->addRow($row);

        return $this;
    }

    public function setRow($column, array $row)
    {
        $this->table->setRow($column, $row);

        return $this;
    }

    /**
     * Sets padding character, used for cell padding.
     *
     * @param string $paddingChar
     *
     * @return TableHelper
     */
    public function setPaddingChar($paddingChar)
    {
        $this->table->getStyle()->setPaddingChar($paddingChar);

        return $this;
    }

    /**
     * Sets horizontal border character.
     *
     * @param string $horizontalBorderChar
     *
     * @return TableHelper
     */
    public function setHorizontalBorderChar($horizontalBorderChar)
    {
        $this->table->getStyle()->setHorizontalBorderChar($horizontalBorderChar);

        return $this;
    }

    /**
     * Sets vertical border character.
     *
     * @param string $verticalBorderChar
     *
     * @return TableHelper
     */
    public function setVerticalBorderChar($verticalBorderChar)
    {
        $this->table->getStyle()->setVerticalBorderChar($verticalBorderChar);

        return $this;
    }

    /**
     * Sets crossing character.
     *
     * @param string $crossingChar
     *
     * @return TableHelper
     */
    public function setCrossingChar($crossingChar)
    {
        $this->table->getStyle()->setCrossingChar($crossingChar);

        return $this;
    }

    /**
     * Sets header cell format.
     *
     * @param string $cellHeaderFormat
     *
     * @return TableHelper
     */
    public function setCellHeaderFormat($cellHeaderFormat)
    {
        $this->table->getStyle()->setCellHeaderFormat($cellHeaderFormat);

        return $this;
    }

    /**
     * Sets row cell format.
     *
     * @param string $cellRowFormat
     *
     * @return TableHelper
     */
    public function setCellRowFormat($cellRowFormat)
    {
        $this->table->getStyle()->setCellHeaderFormat($cellRowFormat);

        return $this;
    }

    /**
     * Sets row cell content format.
     *
     * @param string $cellRowContentFormat
     *
     * @return TableHelper
     */
    public function setCellRowContentFormat($cellRowContentFormat)
    {
        $this->table->getStyle()->setCellRowContentFormat($cellRowContentFormat);

        return $this;
    }

    /**
     * Sets table border format.
     *
     * @param string $borderFormat
     *
     * @return TableHelper
     */
    public function setBorderFormat($borderFormat)
    {
        $this->table->getStyle()->setBorderFormat($borderFormat);

        return $this;
    }

    /**
     * Sets cell padding type.
     *
     * @param int $padType STR_PAD_*
     *
     * @return TableHelper
     */
    public function setPadType($padType)
    {
        $this->table->getStyle()->setPadType($padType);

        return $this;
    }

    /**
     * Renders table to output.
     *
     * Example:
     * +---------------+-----------------------+------------------+
     * | ISBN          | Title                 | Author           |
     * +---------------+-----------------------+------------------+
     * | 99921-58-10-7 | Divine Comedy         | Dante Alighieri  |
     * | 9971-5-0210-0 | A Tale of Two Cities  | Charles Dickens  |
     * | 960-425-059-0 | The Lord of the Rings | J. R. R. Tolkien |
     * +---------------+-----------------------+------------------+
     *
     * @param OutputInterface $output
     */
    public function render(OutputInterface $output)
    {
        $p = new \ReflectionProperty($this->table, 'output');
        $p->setAccessible(true);
        $p->setValue($this->table, $output);

        $this->table->render();
    }

    /**
     * {@inheritdoc}
     */
    public function getName()
    {
        return 'table';
    }
}
PKϤ$ZX^}߼	�	#console/Helper/DescriptorHelper.phpnu�[���<?php

/*
 * This file is part of the Symfony package.
 *
 * (c) Fabien Potencier <fabien@symfony.com>
 *
 * For the full copyright and license information, please view the LICENSE
 * file that was distributed with this source code.
 */

namespace Symfony\Component\Console\Helper;

use Symfony\Component\Console\Descriptor\DescriptorInterface;
use Symfony\Component\Console\Descriptor\JsonDescriptor;
use Symfony\Component\Console\Descriptor\MarkdownDescriptor;
use Symfony\Component\Console\Descriptor\TextDescriptor;
use Symfony\Component\Console\Descriptor\XmlDescriptor;
use Symfony\Component\Console\Exception\InvalidArgumentException;
use Symfony\Component\Console\Output\OutputInterface;

/**
 * This class adds helper method to describe objects in various formats.
 *
 * @author Jean-François Simon <contact@jfsimon.fr>
 */
class DescriptorHelper extends Helper
{
    /**
     * @var DescriptorInterface[]
     */
    private $descriptors = [];

    public function __construct()
    {
        $this
            ->register('txt', new TextDescriptor())
            ->register('xml', new XmlDescriptor())
            ->register('json', new JsonDescriptor())
            ->register('md', new MarkdownDescriptor())
        ;
    }

    /**
     * Describes an object if supported.
     *
     * Available options are:
     * * format: string, the output format name
     * * raw_text: boolean, sets output type as raw
     *
     * @throws InvalidArgumentException when the given format is not supported
     */
    public function describe(OutputInterface $output, ?object $object, array $options = [])
    {
        $options = array_merge([
            'raw_text' => false,
            'format' => 'txt',
        ], $options);

        if (!isset($this->descriptors[$options['format']])) {
            throw new InvalidArgumentException(sprintf('Unsupported format "%s".', $options['format']));
        }

        $descriptor = $this->descriptors[$options['format']];
        $descriptor->describe($output, $object, $options);
    }

    /**
     * Registers a descriptor.
     *
     * @return $this
     */
    public function register(string $format, DescriptorInterface $descriptor)
    {
        $this->descriptors[$format] = $descriptor;

        return $this;
    }

    /**
     * {@inheritdoc}
     */
    public function getName()
    {
        return 'descriptor';
    }

    public function getFormats(): array
    {
        return array_keys($this->descriptors);
    }
}
PKϤ$Z����D�Dconsole/Helper/DialogHelper.phpnu�[���<?php

/*
 * This file is part of the Symfony package.
 *
 * (c) Fabien Potencier <fabien@symfony.com>
 *
 * For the full copyright and license information, please view the LICENSE
 * file that was distributed with this source code.
 */

namespace Symfony\Component\Console\Helper;

use Symfony\Component\Console\Exception\InvalidArgumentException;
use Symfony\Component\Console\Exception\RuntimeException;
use Symfony\Component\Console\Output\ConsoleOutputInterface;
use Symfony\Component\Console\Output\OutputInterface;
use Symfony\Component\Console\Formatter\OutputFormatterStyle;

/**
 * The Dialog class provides helpers to interact with the user.
 *
 * @author Fabien Potencier <fabien@symfony.com>
 *
 * @deprecated since version 2.5, to be removed in 3.0.
 *             Use {@link \Symfony\Component\Console\Helper\QuestionHelper} instead.
 */
class DialogHelper extends InputAwareHelper
{
    private $inputStream;
    private static $shell;
    private static $stty;

    public function __construct($triggerDeprecationError = true)
    {
        if ($triggerDeprecationError) {
            @trigger_error('"Symfony\Component\Console\Helper\DialogHelper" is deprecated since version 2.5 and will be removed in 3.0. Use "Symfony\Component\Console\Helper\QuestionHelper" instead.', E_USER_DEPRECATED);
        }
    }

    /**
     * Asks the user to select a value.
     *
     * @param OutputInterface $output       An Output instance
     * @param string|array    $question     The question to ask
     * @param array           $choices      List of choices to pick from
     * @param bool|string     $default      The default answer if the user enters nothing
     * @param bool|int        $attempts     Max number of times to ask before giving up (false by default, which means infinite)
     * @param string          $errorMessage Message which will be shown if invalid value from choice list would be picked
     * @param bool            $multiselect  Select more than one value separated by comma
     *
     * @return int|string|array The selected value or values (the key of the choices array)
     *
     * @throws InvalidArgumentException
     */
    public function select(OutputInterface $output, $question, $choices, $default = null, $attempts = false, $errorMessage = 'Value "%s" is invalid', $multiselect = false)
    {
        if ($output instanceof ConsoleOutputInterface) {
            $output = $output->getErrorOutput();
        }

        $width = max(array_map('strlen', array_keys($choices)));

        $messages = (array) $question;
        foreach ($choices as $key => $value) {
            $messages[] = sprintf("  [<info>%-{$width}s</info>] %s", $key, $value);
        }

        $output->writeln($messages);

        $result = $this->askAndValidate($output, '> ', function ($picked) use ($choices, $errorMessage, $multiselect) {
            // Collapse all spaces.
            $selectedChoices = str_replace(' ', '', $picked);

            if ($multiselect) {
                // Check for a separated comma values
                if (!preg_match('/^[a-zA-Z0-9_-]+(?:,[a-zA-Z0-9_-]+)*$/', $selectedChoices, $matches)) {
                    throw new InvalidArgumentException(sprintf($errorMessage, $picked));
                }
                $selectedChoices = explode(',', $selectedChoices);
            } else {
                $selectedChoices = array($picked);
            }

            $multiselectChoices = array();

            foreach ($selectedChoices as $value) {
                if (empty($choices[$value])) {
                    throw new InvalidArgumentException(sprintf($errorMessage, $value));
                }
                $multiselectChoices[] = $value;
            }

            if ($multiselect) {
                return $multiselectChoices;
            }

            return $picked;
        }, $attempts, $default);

        return $result;
    }

    /**
     * Asks a question to the user.
     *
     * @param OutputInterface $output       An Output instance
     * @param string|array    $question     The question to ask
     * @param string          $default      The default answer if none is given by the user
     * @param array           $autocomplete List of values to autocomplete
     *
     * @return string The user answer
     *
     * @throws RuntimeException If there is no data to read in the input stream
     */
    public function ask(OutputInterface $output, $question, $default = null, array $autocomplete = null)
    {
        if ($this->input && !$this->input->isInteractive()) {
            return $default;
        }

        if ($output instanceof ConsoleOutputInterface) {
            $output = $output->getErrorOutput();
        }

        $output->write($question);

        $inputStream = $this->inputStream ?: STDIN;

        if (null === $autocomplete || !$this->hasSttyAvailable()) {
            $ret = fgets($inputStream, 4096);
            if (false === $ret) {
                throw new RuntimeException('Aborted');
            }
            $ret = trim($ret);
        } else {
            $ret = '';

            $i = 0;
            $ofs = -1;
            $matches = $autocomplete;
            $numMatches = count($matches);

            $sttyMode = shell_exec('stty -g');

            // Disable icanon (so we can fread each keypress) and echo (we'll do echoing here instead)
            shell_exec('stty -icanon -echo');

            // Add highlighted text style
            $output->getFormatter()->setStyle('hl', new OutputFormatterStyle('black', 'white'));

            // Read a keypress
            while (!feof($inputStream)) {
                $c = fread($inputStream, 1);

                // Backspace Character
                if ("\177" === $c) {
                    if (0 === $numMatches && 0 !== $i) {
                        --$i;
                        // Move cursor backwards
                        $output->write("\033[1D");
                    }

                    if ($i === 0) {
                        $ofs = -1;
                        $matches = $autocomplete;
                        $numMatches = count($matches);
                    } else {
                        $numMatches = 0;
                    }

                    // Pop the last character off the end of our string
                    $ret = substr($ret, 0, $i);
                } elseif ("\033" === $c) {
                    // Did we read an escape sequence?
                    $c .= fread($inputStream, 2);

                    // A = Up Arrow. B = Down Arrow
                    if (isset($c[2]) && ('A' === $c[2] || 'B' === $c[2])) {
                        if ('A' === $c[2] && -1 === $ofs) {
                            $ofs = 0;
                        }

                        if (0 === $numMatches) {
                            continue;
                        }

                        $ofs += ('A' === $c[2]) ? -1 : 1;
                        $ofs = ($numMatches + $ofs) % $numMatches;
                    }
                } elseif (ord($c) < 32) {
                    if ("\t" === $c || "\n" === $c) {
                        if ($numMatches > 0 && -1 !== $ofs) {
                            $ret = $matches[$ofs];
                            // Echo out remaining chars for current match
                            $output->write(substr($ret, $i));
                            $i = strlen($ret);
                        }

                        if ("\n" === $c) {
                            $output->write($c);
                            break;
                        }

                        $numMatches = 0;
                    }

                    continue;
                } else {
                    $output->write($c);
                    $ret .= $c;
                    ++$i;

                    $numMatches = 0;
                    $ofs = 0;

                    foreach ($autocomplete as $value) {
                        // If typed characters match the beginning chunk of value (e.g. [AcmeDe]moBundle)
                        if (0 === strpos($value, $ret) && $i !== strlen($value)) {
                            $matches[$numMatches++] = $value;
                        }
                    }
                }

                // Erase characters from cursor to end of line
                $output->write("\033[K");

                if ($numMatches > 0 && -1 !== $ofs) {
                    // Save cursor position
                    $output->write("\0337");
                    // Write highlighted text
                    $output->write('<hl>'.substr($matches[$ofs], $i).'</hl>');
                    // Restore cursor position
                    $output->write("\0338");
                }
            }

            // Reset stty so it behaves normally again
            shell_exec(sprintf('stty %s', $sttyMode));
        }

        return strlen($ret) > 0 ? $ret : $default;
    }

    /**
     * Asks a confirmation to the user.
     *
     * The question will be asked until the user answers by nothing, yes, or no.
     *
     * @param OutputInterface $output   An Output instance
     * @param string|array    $question The question to ask
     * @param bool            $default  The default answer if the user enters nothing
     *
     * @return bool true if the user has confirmed, false otherwise
     */
    public function askConfirmation(OutputInterface $output, $question, $default = true)
    {
        $answer = 'z';
        while ($answer && !in_array(strtolower($answer[0]), array('y', 'n'))) {
            $answer = $this->ask($output, $question);
        }

        if (false === $default) {
            return $answer && 'y' == strtolower($answer[0]);
        }

        return !$answer || 'y' == strtolower($answer[0]);
    }

    /**
     * Asks a question to the user, the response is hidden.
     *
     * @param OutputInterface $output   An Output instance
     * @param string|array    $question The question
     * @param bool            $fallback In case the response can not be hidden, whether to fallback on non-hidden question or not
     *
     * @return string The answer
     *
     * @throws RuntimeException In case the fallback is deactivated and the response can not be hidden
     */
    public function askHiddenResponse(OutputInterface $output, $question, $fallback = true)
    {
        if ($output instanceof ConsoleOutputInterface) {
            $output = $output->getErrorOutput();
        }

        if ('\\' === DIRECTORY_SEPARATOR) {
            $exe = __DIR__.'/../Resources/bin/hiddeninput.exe';

            // handle code running from a phar
            if ('phar:' === substr(__FILE__, 0, 5)) {
                $tmpExe = sys_get_temp_dir().'/hiddeninput.exe';
                copy($exe, $tmpExe);
                $exe = $tmpExe;
            }

            $output->write($question);
            $value = rtrim(shell_exec($exe));
            $output->writeln('');

            if (isset($tmpExe)) {
                unlink($tmpExe);
            }

            return $value;
        }

        if ($this->hasSttyAvailable()) {
            $output->write($question);

            $sttyMode = shell_exec('stty -g');

            shell_exec('stty -echo');
            $value = fgets($this->inputStream ?: STDIN, 4096);
            shell_exec(sprintf('stty %s', $sttyMode));

            if (false === $value) {
                throw new RuntimeException('Aborted');
            }

            $value = trim($value);
            $output->writeln('');

            return $value;
        }

        if (false !== $shell = $this->getShell()) {
            $output->write($question);
            $readCmd = $shell === 'csh' ? 'set mypassword = $<' : 'read -r mypassword';
            $command = sprintf("/usr/bin/env %s -c 'stty -echo; %s; stty echo; echo \$mypassword'", $shell, $readCmd);
            $value = rtrim(shell_exec($command));
            $output->writeln('');

            return $value;
        }

        if ($fallback) {
            return $this->ask($output, $question);
        }

        throw new RuntimeException('Unable to hide the response');
    }

    /**
     * Asks for a value and validates the response.
     *
     * The validator receives the data to validate. It must return the
     * validated data when the data is valid and throw an exception
     * otherwise.
     *
     * @param OutputInterface $output       An Output instance
     * @param string|array    $question     The question to ask
     * @param callable        $validator    A PHP callback
     * @param int|false       $attempts     Max number of times to ask before giving up (false by default, which means infinite)
     * @param string          $default      The default answer if none is given by the user
     * @param array           $autocomplete List of values to autocomplete
     *
     * @return mixed
     *
     * @throws \Exception When any of the validators return an error
     */
    public function askAndValidate(OutputInterface $output, $question, $validator, $attempts = false, $default = null, array $autocomplete = null)
    {
        $that = $this;

        $interviewer = function () use ($output, $question, $default, $autocomplete, $that) {
            return $that->ask($output, $question, $default, $autocomplete);
        };

        return $this->validateAttempts($interviewer, $output, $validator, $attempts);
    }

    /**
     * Asks for a value, hide and validates the response.
     *
     * The validator receives the data to validate. It must return the
     * validated data when the data is valid and throw an exception
     * otherwise.
     *
     * @param OutputInterface $output    An Output instance
     * @param string|array    $question  The question to ask
     * @param callable        $validator A PHP callback
     * @param int|false       $attempts  Max number of times to ask before giving up (false by default, which means infinite)
     * @param bool            $fallback  In case the response can not be hidden, whether to fallback on non-hidden question or not
     *
     * @return string The response
     *
     * @throws \Exception       When any of the validators return an error
     * @throws RuntimeException In case the fallback is deactivated and the response can not be hidden
     */
    public function askHiddenResponseAndValidate(OutputInterface $output, $question, $validator, $attempts = false, $fallback = true)
    {
        $that = $this;

        $interviewer = function () use ($output, $question, $fallback, $that) {
            return $that->askHiddenResponse($output, $question, $fallback);
        };

        return $this->validateAttempts($interviewer, $output, $validator, $attempts);
    }

    /**
     * Sets the input stream to read from when interacting with the user.
     *
     * This is mainly useful for testing purpose.
     *
     * @param resource $stream The input stream
     */
    public function setInputStream($stream)
    {
        $this->inputStream = $stream;
    }

    /**
     * Returns the helper's input stream.
     *
     * @return resource|null The input stream or null if the default STDIN is used
     */
    public function getInputStream()
    {
        return $this->inputStream;
    }

    /**
     * {@inheritdoc}
     */
    public function getName()
    {
        return 'dialog';
    }

    /**
     * Return a valid Unix shell.
     *
     * @return string|bool The valid shell name, false in case no valid shell is found
     */
    private function getShell()
    {
        if (null !== self::$shell) {
            return self::$shell;
        }

        self::$shell = false;

        if (file_exists('/usr/bin/env')) {
            // handle other OSs with bash/zsh/ksh/csh if available to hide the answer
            $test = "/usr/bin/env %s -c 'echo OK' 2> /dev/null";
            foreach (array('bash', 'zsh', 'ksh', 'csh') as $sh) {
                if ('OK' === rtrim(shell_exec(sprintf($test, $sh)))) {
                    self::$shell = $sh;
                    break;
                }
            }
        }

        return self::$shell;
    }

    private function hasSttyAvailable()
    {
        if (null !== self::$stty) {
            return self::$stty;
        }

        exec('stty 2>&1', $output, $exitcode);

        return self::$stty = $exitcode === 0;
    }

    /**
     * Validate an attempt.
     *
     * @param callable        $interviewer A callable that will ask for a question and return the result
     * @param OutputInterface $output      An Output instance
     * @param callable        $validator   A PHP callback
     * @param int|false       $attempts    Max number of times to ask before giving up; false will ask infinitely
     *
     * @return string The validated response
     *
     * @throws \Exception In case the max number of attempts has been reached and no valid response has been given
     */
    private function validateAttempts($interviewer, OutputInterface $output, $validator, $attempts)
    {
        if ($output instanceof ConsoleOutputInterface) {
            $output = $output->getErrorOutput();
        }

        $e = null;
        while (false === $attempts || $attempts--) {
            if (null !== $e) {
                $output->writeln($this->getHelperSet()->get('formatter')->formatBlock($e->getMessage(), 'error'));
            }

            try {
                return call_user_func($validator, $interviewer());
            } catch (\Exception $e) {
            }
        }

        throw $e;
    }
}
PKϤ$Z�*���	�	/console/Formatter/OutputFormatterStyleStack.phpnu�[���<?php

/*
 * This file is part of the Symfony package.
 *
 * (c) Fabien Potencier <fabien@symfony.com>
 *
 * For the full copyright and license information, please view the LICENSE
 * file that was distributed with this source code.
 */

namespace Symfony\Component\Console\Formatter;

use Symfony\Component\Console\Exception\InvalidArgumentException;
use Symfony\Contracts\Service\ResetInterface;

/**
 * @author Jean-François Simon <contact@jfsimon.fr>
 */
class OutputFormatterStyleStack implements ResetInterface
{
    /**
     * @var OutputFormatterStyleInterface[]
     */
    private $styles;

    private $emptyStyle;

    public function __construct(OutputFormatterStyleInterface $emptyStyle = null)
    {
        $this->emptyStyle = $emptyStyle ?? new OutputFormatterStyle();
        $this->reset();
    }

    /**
     * Resets stack (ie. empty internal arrays).
     */
    public function reset()
    {
        $this->styles = [];
    }

    /**
     * Pushes a style in the stack.
     */
    public function push(OutputFormatterStyleInterface $style)
    {
        $this->styles[] = $style;
    }

    /**
     * Pops a style from the stack.
     *
     * @return OutputFormatterStyleInterface
     *
     * @throws InvalidArgumentException When style tags incorrectly nested
     */
    public function pop(OutputFormatterStyleInterface $style = null)
    {
        if (empty($this->styles)) {
            return $this->emptyStyle;
        }

        if (null === $style) {
            return array_pop($this->styles);
        }

        foreach (array_reverse($this->styles, true) as $index => $stackedStyle) {
            if ($style->apply('') === $stackedStyle->apply('')) {
                $this->styles = \array_slice($this->styles, 0, $index);

                return $stackedStyle;
            }
        }

        throw new InvalidArgumentException('Incorrectly nested style tag found.');
    }

    /**
     * Computes current style with stacks top codes.
     *
     * @return OutputFormatterStyle
     */
    public function getCurrent()
    {
        if (empty($this->styles)) {
            return $this->emptyStyle;
        }

        return $this->styles[\count($this->styles) - 1];
    }

    /**
     * @return $this
     */
    public function setEmptyStyle(OutputFormatterStyleInterface $emptyStyle)
    {
        $this->emptyStyle = $emptyStyle;

        return $this;
    }

    /**
     * @return OutputFormatterStyleInterface
     */
    public function getEmptyStyle()
    {
        return $this->emptyStyle;
    }
}
PKϤ$Z{=X���.console/Formatter/NullOutputFormatterStyle.phpnu�[���<?php

/*
 * This file is part of the Symfony package.
 *
 * (c) Fabien Potencier <fabien@symfony.com>
 *
 * For the full copyright and license information, please view the LICENSE
 * file that was distributed with this source code.
 */

namespace Symfony\Component\Console\Formatter;

/**
 * @author Tien Xuan Vo <tien.xuan.vo@gmail.com>
 */
final class NullOutputFormatterStyle implements OutputFormatterStyleInterface
{
    /**
     * {@inheritdoc}
     */
    public function apply(string $text): string
    {
        return $text;
    }

    /**
     * {@inheritdoc}
     */
    public function setBackground(string $color = null): void
    {
        // do nothing
    }

    /**
     * {@inheritdoc}
     */
    public function setForeground(string $color = null): void
    {
        // do nothing
    }

    /**
     * {@inheritdoc}
     */
    public function setOption(string $option): void
    {
        // do nothing
    }

    /**
     * {@inheritdoc}
     */
    public function setOptions(array $options): void
    {
        // do nothing
    }

    /**
     * {@inheritdoc}
     */
    public function unsetOption(string $option): void
    {
        // do nothing
    }
}
PKϤ$Z}z���7console/Formatter/WrappableOutputFormatterInterface.phpnu�[���<?php

/*
 * This file is part of the Symfony package.
 *
 * (c) Fabien Potencier <fabien@symfony.com>
 *
 * For the full copyright and license information, please view the LICENSE
 * file that was distributed with this source code.
 */

namespace Symfony\Component\Console\Formatter;

/**
 * Formatter interface for console output that supports word wrapping.
 *
 * @author Roland Franssen <franssen.roland@gmail.com>
 */
interface WrappableOutputFormatterInterface extends OutputFormatterInterface
{
    /**
     * Formats a message according to the given styles, wrapping at `$width` (0 means no wrapping).
     */
    public function formatAndWrap(?string $message, int $width);
}
PKϤ$ZpbdPP*console/Formatter/OutputFormatterStyle.phpnu�[���<?php

/*
 * This file is part of the Symfony package.
 *
 * (c) Fabien Potencier <fabien@symfony.com>
 *
 * For the full copyright and license information, please view the LICENSE
 * file that was distributed with this source code.
 */

namespace Symfony\Component\Console\Formatter;

use Symfony\Component\Console\Color;

/**
 * Formatter style class for defining styles.
 *
 * @author Konstantin Kudryashov <ever.zet@gmail.com>
 */
class OutputFormatterStyle implements OutputFormatterStyleInterface
{
    private $color;
    private $foreground;
    private $background;
    private $options;
    private $href;
    private $handlesHrefGracefully;

    /**
     * Initializes output formatter style.
     *
     * @param string|null $foreground The style foreground color name
     * @param string|null $background The style background color name
     */
    public function __construct(string $foreground = null, string $background = null, array $options = [])
    {
        $this->color = new Color($this->foreground = $foreground ?: '', $this->background = $background ?: '', $this->options = $options);
    }

    /**
     * {@inheritdoc}
     */
    public function setForeground(string $color = null)
    {
        $this->color = new Color($this->foreground = $color ?: '', $this->background, $this->options);
    }

    /**
     * {@inheritdoc}
     */
    public function setBackground(string $color = null)
    {
        $this->color = new Color($this->foreground, $this->background = $color ?: '', $this->options);
    }

    public function setHref(string $url): void
    {
        $this->href = $url;
    }

    /**
     * {@inheritdoc}
     */
    public function setOption(string $option)
    {
        $this->options[] = $option;
        $this->color = new Color($this->foreground, $this->background, $this->options);
    }

    /**
     * {@inheritdoc}
     */
    public function unsetOption(string $option)
    {
        $pos = array_search($option, $this->options);
        if (false !== $pos) {
            unset($this->options[$pos]);
        }

        $this->color = new Color($this->foreground, $this->background, $this->options);
    }

    /**
     * {@inheritdoc}
     */
    public function setOptions(array $options)
    {
        $this->color = new Color($this->foreground, $this->background, $this->options = $options);
    }

    /**
     * {@inheritdoc}
     */
    public function apply(string $text)
    {
        if (null === $this->handlesHrefGracefully) {
            $this->handlesHrefGracefully = 'JetBrains-JediTerm' !== getenv('TERMINAL_EMULATOR')
                && (!getenv('KONSOLE_VERSION') || (int) getenv('KONSOLE_VERSION') > 201100);
        }

        if (null !== $this->href && $this->handlesHrefGracefully) {
            $text = "\033]8;;$this->href\033\\$text\033]8;;\033\\";
        }

        return $this->color->apply($text);
    }
}
PKϤ$Z ��``%console/Formatter/OutputFormatter.phpnu�[���<?php

/*
 * This file is part of the Symfony package.
 *
 * (c) Fabien Potencier <fabien@symfony.com>
 *
 * For the full copyright and license information, please view the LICENSE
 * file that was distributed with this source code.
 */

namespace Symfony\Component\Console\Formatter;

use Symfony\Component\Console\Exception\InvalidArgumentException;

/**
 * Formatter class for console output.
 *
 * @author Konstantin Kudryashov <ever.zet@gmail.com>
 * @author Roland Franssen <franssen.roland@gmail.com>
 */
class OutputFormatter implements WrappableOutputFormatterInterface
{
    private $decorated;
    private $styles = [];
    private $styleStack;

    public function __clone()
    {
        $this->styleStack = clone $this->styleStack;
        foreach ($this->styles as $key => $value) {
            $this->styles[$key] = clone $value;
        }
    }

    /**
     * Escapes "<" and ">" special chars in given text.
     *
     * @return string
     */
    public static function escape(string $text)
    {
        $text = preg_replace('/([^\\\\]|^)([<>])/', '$1\\\\$2', $text);

        return self::escapeTrailingBackslash($text);
    }

    /**
     * Escapes trailing "\" in given text.
     *
     * @internal
     */
    public static function escapeTrailingBackslash(string $text): string
    {
        if (str_ends_with($text, '\\')) {
            $len = \strlen($text);
            $text = rtrim($text, '\\');
            $text = str_replace("\0", '', $text);
            $text .= str_repeat("\0", $len - \strlen($text));
        }

        return $text;
    }

    /**
     * Initializes console output formatter.
     *
     * @param OutputFormatterStyleInterface[] $styles Array of "name => FormatterStyle" instances
     */
    public function __construct(bool $decorated = false, array $styles = [])
    {
        $this->decorated = $decorated;

        $this->setStyle('error', new OutputFormatterStyle('white', 'red'));
        $this->setStyle('info', new OutputFormatterStyle('green'));
        $this->setStyle('comment', new OutputFormatterStyle('yellow'));
        $this->setStyle('question', new OutputFormatterStyle('black', 'cyan'));

        foreach ($styles as $name => $style) {
            $this->setStyle($name, $style);
        }

        $this->styleStack = new OutputFormatterStyleStack();
    }

    /**
     * {@inheritdoc}
     */
    public function setDecorated(bool $decorated)
    {
        $this->decorated = $decorated;
    }

    /**
     * {@inheritdoc}
     */
    public function isDecorated()
    {
        return $this->decorated;
    }

    /**
     * {@inheritdoc}
     */
    public function setStyle(string $name, OutputFormatterStyleInterface $style)
    {
        $this->styles[strtolower($name)] = $style;
    }

    /**
     * {@inheritdoc}
     */
    public function hasStyle(string $name)
    {
        return isset($this->styles[strtolower($name)]);
    }

    /**
     * {@inheritdoc}
     */
    public function getStyle(string $name)
    {
        if (!$this->hasStyle($name)) {
            throw new InvalidArgumentException(sprintf('Undefined style: "%s".', $name));
        }

        return $this->styles[strtolower($name)];
    }

    /**
     * {@inheritdoc}
     */
    public function format(?string $message)
    {
        return $this->formatAndWrap($message, 0);
    }

    /**
     * {@inheritdoc}
     */
    public function formatAndWrap(?string $message, int $width)
    {
        if (null === $message) {
            return '';
        }

        $offset = 0;
        $output = '';
        $openTagRegex = '[a-z](?:[^\\\\<>]*+ | \\\\.)*';
        $closeTagRegex = '[a-z][^<>]*+';
        $currentLineLength = 0;
        preg_match_all("#<(($openTagRegex) | /($closeTagRegex)?)>#ix", $message, $matches, \PREG_OFFSET_CAPTURE);
        foreach ($matches[0] as $i => $match) {
            $pos = $match[1];
            $text = $match[0];

            if (0 != $pos && '\\' == $message[$pos - 1]) {
                continue;
            }

            // add the text up to the next tag
            $output .= $this->applyCurrentStyle(substr($message, $offset, $pos - $offset), $output, $width, $currentLineLength);
            $offset = $pos + \strlen($text);

            // opening tag?
            if ($open = '/' != $text[1]) {
                $tag = $matches[1][$i][0];
            } else {
                $tag = $matches[3][$i][0] ?? '';
            }

            if (!$open && !$tag) {
                // </>
                $this->styleStack->pop();
            } elseif (null === $style = $this->createStyleFromString($tag)) {
                $output .= $this->applyCurrentStyle($text, $output, $width, $currentLineLength);
            } elseif ($open) {
                $this->styleStack->push($style);
            } else {
                $this->styleStack->pop($style);
            }
        }

        $output .= $this->applyCurrentStyle(substr($message, $offset), $output, $width, $currentLineLength);

        return strtr($output, ["\0" => '\\', '\\<' => '<', '\\>' => '>']);
    }

    /**
     * @return OutputFormatterStyleStack
     */
    public function getStyleStack()
    {
        return $this->styleStack;
    }

    /**
     * Tries to create new style instance from string.
     */
    private function createStyleFromString(string $string): ?OutputFormatterStyleInterface
    {
        if (isset($this->styles[$string])) {
            return $this->styles[$string];
        }

        if (!preg_match_all('/([^=]+)=([^;]+)(;|$)/', $string, $matches, \PREG_SET_ORDER)) {
            return null;
        }

        $style = new OutputFormatterStyle();
        foreach ($matches as $match) {
            array_shift($match);
            $match[0] = strtolower($match[0]);

            if ('fg' == $match[0]) {
                $style->setForeground(strtolower($match[1]));
            } elseif ('bg' == $match[0]) {
                $style->setBackground(strtolower($match[1]));
            } elseif ('href' === $match[0]) {
                $url = preg_replace('{\\\\([<>])}', '$1', $match[1]);
                $style->setHref($url);
            } elseif ('options' === $match[0]) {
                preg_match_all('([^,;]+)', strtolower($match[1]), $options);
                $options = array_shift($options);
                foreach ($options as $option) {
                    $style->setOption($option);
                }
            } else {
                return null;
            }
        }

        return $style;
    }

    /**
     * Applies current style from stack to text, if must be applied.
     */
    private function applyCurrentStyle(string $text, string $current, int $width, int &$currentLineLength): string
    {
        if ('' === $text) {
            return '';
        }

        if (!$width) {
            return $this->isDecorated() ? $this->styleStack->getCurrent()->apply($text) : $text;
        }

        if (!$currentLineLength && '' !== $current) {
            $text = ltrim($text);
        }

        if ($currentLineLength) {
            $prefix = substr($text, 0, $i = $width - $currentLineLength)."\n";
            $text = substr($text, $i);
        } else {
            $prefix = '';
        }

        preg_match('~(\\n)$~', $text, $matches);
        $text = $prefix.preg_replace('~([^\\n]{'.$width.'})\\ *~', "\$1\n", $text);
        $text = rtrim($text, "\n").($matches[1] ?? '');

        if (!$currentLineLength && '' !== $current && "\n" !== substr($current, -1)) {
            $text = "\n".$text;
        }

        $lines = explode("\n", $text);

        foreach ($lines as $line) {
            $currentLineLength += \strlen($line);
            if ($width <= $currentLineLength) {
                $currentLineLength = 0;
            }
        }

        if ($this->isDecorated()) {
            foreach ($lines as $i => $line) {
                $lines[$i] = $this->styleStack->getCurrent()->apply($line);
            }
        }

        return implode("\n", $lines);
    }
}
PKϤ$Z?�V�77.console/Formatter/OutputFormatterInterface.phpnu�[���<?php

/*
 * This file is part of the Symfony package.
 *
 * (c) Fabien Potencier <fabien@symfony.com>
 *
 * For the full copyright and license information, please view the LICENSE
 * file that was distributed with this source code.
 */

namespace Symfony\Component\Console\Formatter;

/**
 * Formatter interface for console output.
 *
 * @author Konstantin Kudryashov <ever.zet@gmail.com>
 */
interface OutputFormatterInterface
{
    /**
     * Sets the decorated flag.
     */
    public function setDecorated(bool $decorated);

    /**
     * Whether the output will decorate messages.
     *
     * @return bool
     */
    public function isDecorated();

    /**
     * Sets a new style.
     */
    public function setStyle(string $name, OutputFormatterStyleInterface $style);

    /**
     * Checks if output formatter has style with specified name.
     *
     * @return bool
     */
    public function hasStyle(string $name);

    /**
     * Gets style options from style with specified name.
     *
     * @return OutputFormatterStyleInterface
     *
     * @throws \InvalidArgumentException When style isn't defined
     */
    public function getStyle(string $name);

    /**
     * Formats a message according to the given styles.
     *
     * @return string|null
     */
    public function format(?string $message);
}
PKϤ$Zs���ZZ3console/Formatter/OutputFormatterStyleInterface.phpnu�[���<?php

/*
 * This file is part of the Symfony package.
 *
 * (c) Fabien Potencier <fabien@symfony.com>
 *
 * For the full copyright and license information, please view the LICENSE
 * file that was distributed with this source code.
 */

namespace Symfony\Component\Console\Formatter;

/**
 * Formatter style interface for defining styles.
 *
 * @author Konstantin Kudryashov <ever.zet@gmail.com>
 */
interface OutputFormatterStyleInterface
{
    /**
     * Sets style foreground color.
     */
    public function setForeground(string $color = null);

    /**
     * Sets style background color.
     */
    public function setBackground(string $color = null);

    /**
     * Sets some specific style option.
     */
    public function setOption(string $option);

    /**
     * Unsets some specific style option.
     */
    public function unsetOption(string $option);

    /**
     * Sets multiple style options at once.
     */
    public function setOptions(array $options);

    /**
     * Applies the style to a given text.
     *
     * @return string
     */
    public function apply(string $text);
}
PKϤ$Z��p�YY)console/Formatter/NullOutputFormatter.phpnu�[���<?php

/*
 * This file is part of the Symfony package.
 *
 * (c) Fabien Potencier <fabien@symfony.com>
 *
 * For the full copyright and license information, please view the LICENSE
 * file that was distributed with this source code.
 */

namespace Symfony\Component\Console\Formatter;

/**
 * @author Tien Xuan Vo <tien.xuan.vo@gmail.com>
 */
final class NullOutputFormatter implements OutputFormatterInterface
{
    private $style;

    /**
     * {@inheritdoc}
     */
    public function format(?string $message): ?string
    {
        return null;
    }

    /**
     * {@inheritdoc}
     */
    public function getStyle(string $name): OutputFormatterStyleInterface
    {
        // to comply with the interface we must return a OutputFormatterStyleInterface
        return $this->style ?? $this->style = new NullOutputFormatterStyle();
    }

    /**
     * {@inheritdoc}
     */
    public function hasStyle(string $name): bool
    {
        return false;
    }

    /**
     * {@inheritdoc}
     */
    public function isDecorated(): bool
    {
        return false;
    }

    /**
     * {@inheritdoc}
     */
    public function setDecorated(bool $decorated): void
    {
        // do nothing
    }

    /**
     * {@inheritdoc}
     */
    public function setStyle(string $name, OutputFormatterStyleInterface $style): void
    {
        // do nothing
    }
}
PKϤ$ZT�����#console/Event/ConsoleErrorEvent.phpnu�[���<?php

/*
 * This file is part of the Symfony package.
 *
 * (c) Fabien Potencier <fabien@symfony.com>
 *
 * For the full copyright and license information, please view the LICENSE
 * file that was distributed with this source code.
 */

namespace Symfony\Component\Console\Event;

use Symfony\Component\Console\Command\Command;
use Symfony\Component\Console\Input\InputInterface;
use Symfony\Component\Console\Output\OutputInterface;

/**
 * Allows to handle throwables thrown while running a command.
 *
 * @author Wouter de Jong <wouter@wouterj.nl>
 */
final class ConsoleErrorEvent extends ConsoleEvent
{
    private $error;
    private $exitCode;

    public function __construct(InputInterface $input, OutputInterface $output, \Throwable $error, Command $command = null)
    {
        parent::__construct($command, $input, $output);

        $this->error = $error;
    }

    public function getError(): \Throwable
    {
        return $this->error;
    }

    public function setError(\Throwable $error): void
    {
        $this->error = $error;
    }

    public function setExitCode(int $exitCode): void
    {
        $this->exitCode = $exitCode;

        $r = new \ReflectionProperty($this->error, 'code');
        $r->setAccessible(true);
        $r->setValue($this->error, $this->exitCode);
    }

    public function getExitCode(): int
    {
        return $this->exitCode ?? (\is_int($this->error->getCode()) && 0 !== $this->error->getCode() ? $this->error->getCode() : 1);
    }
}
PKϤ$Z���=='console/Event/ConsoleExceptionEvent.phpnu�[���<?php

/*
 * This file is part of the Symfony package.
 *
 * (c) Fabien Potencier <fabien@symfony.com>
 *
 * For the full copyright and license information, please view the LICENSE
 * file that was distributed with this source code.
 */

namespace Symfony\Component\Console\Event;

use Symfony\Component\Console\Command\Command;
use Symfony\Component\Console\Input\InputInterface;
use Symfony\Component\Console\Output\OutputInterface;

/**
 * Allows to handle exception thrown in a command.
 *
 * @author Fabien Potencier <fabien@symfony.com>
 */
class ConsoleExceptionEvent extends ConsoleEvent
{
    private $exception;
    private $exitCode;

    public function __construct(Command $command, InputInterface $input, OutputInterface $output, \Exception $exception, $exitCode)
    {
        parent::__construct($command, $input, $output);

        $this->setException($exception);
        $this->exitCode = (int) $exitCode;
    }

    /**
     * Returns the thrown exception.
     *
     * @return \Exception The thrown exception
     */
    public function getException()
    {
        return $this->exception;
    }

    /**
     * Replaces the thrown exception.
     *
     * This exception will be thrown if no response is set in the event.
     *
     * @param \Exception $exception The thrown exception
     */
    public function setException(\Exception $exception)
    {
        $this->exception = $exception;
    }

    /**
     * Gets the exit code.
     *
     * @return int The command exit code
     */
    public function getExitCode()
    {
        return $this->exitCode;
    }
}
PKϤ$Z�q��""'console/Event/ConsoleTerminateEvent.phpnu�[���<?php

/*
 * This file is part of the Symfony package.
 *
 * (c) Fabien Potencier <fabien@symfony.com>
 *
 * For the full copyright and license information, please view the LICENSE
 * file that was distributed with this source code.
 */

namespace Symfony\Component\Console\Event;

use Symfony\Component\Console\Command\Command;
use Symfony\Component\Console\Input\InputInterface;
use Symfony\Component\Console\Output\OutputInterface;

/**
 * Allows to manipulate the exit code of a command after its execution.
 *
 * @author Francesco Levorato <git@flevour.net>
 */
final class ConsoleTerminateEvent extends ConsoleEvent
{
    private $exitCode;

    public function __construct(Command $command, InputInterface $input, OutputInterface $output, int $exitCode)
    {
        parent::__construct($command, $input, $output);

        $this->setExitCode($exitCode);
    }

    public function setExitCode(int $exitCode): void
    {
        $this->exitCode = $exitCode;
    }

    public function getExitCode(): int
    {
        return $this->exitCode;
    }
}
PKϤ$Zb���$console/Event/ConsoleSignalEvent.phpnu�[���<?php

/*
 * This file is part of the Symfony package.
 *
 * (c) Fabien Potencier <fabien@symfony.com>
 *
 * For the full copyright and license information, please view the LICENSE
 * file that was distributed with this source code.
 */

namespace Symfony\Component\Console\Event;

use Symfony\Component\Console\Command\Command;
use Symfony\Component\Console\Input\InputInterface;
use Symfony\Component\Console\Output\OutputInterface;

/**
 * @author marie <marie@users.noreply.github.com>
 */
final class ConsoleSignalEvent extends ConsoleEvent
{
    private $handlingSignal;

    public function __construct(Command $command, InputInterface $input, OutputInterface $output, int $handlingSignal)
    {
        parent::__construct($command, $input, $output);
        $this->handlingSignal = $handlingSignal;
    }

    public function getHandlingSignal(): int
    {
        return $this->handlingSignal;
    }
}
PKϤ$Z:�[&ttconsole/Event/ConsoleEvent.phpnu�[���<?php

/*
 * This file is part of the Symfony package.
 *
 * (c) Fabien Potencier <fabien@symfony.com>
 *
 * For the full copyright and license information, please view the LICENSE
 * file that was distributed with this source code.
 */

namespace Symfony\Component\Console\Event;

use Symfony\Component\Console\Command\Command;
use Symfony\Component\Console\Input\InputInterface;
use Symfony\Component\Console\Output\OutputInterface;
use Symfony\Contracts\EventDispatcher\Event;

/**
 * Allows to inspect input and output of a command.
 *
 * @author Francesco Levorato <git@flevour.net>
 */
class ConsoleEvent extends Event
{
    protected $command;

    private $input;
    private $output;

    public function __construct(?Command $command, InputInterface $input, OutputInterface $output)
    {
        $this->command = $command;
        $this->input = $input;
        $this->output = $output;
    }

    /**
     * Gets the command that is executed.
     *
     * @return Command|null
     */
    public function getCommand()
    {
        return $this->command;
    }

    /**
     * Gets the input instance.
     *
     * @return InputInterface
     */
    public function getInput()
    {
        return $this->input;
    }

    /**
     * Gets the output instance.
     *
     * @return OutputInterface
     */
    public function getOutput()
    {
        return $this->output;
    }
}
PKϤ$Z����%console/Event/ConsoleCommandEvent.phpnu�[���<?php

/*
 * This file is part of the Symfony package.
 *
 * (c) Fabien Potencier <fabien@symfony.com>
 *
 * For the full copyright and license information, please view the LICENSE
 * file that was distributed with this source code.
 */

namespace Symfony\Component\Console\Event;

/**
 * Allows to do things before the command is executed, like skipping the command or changing the input.
 *
 * @author Fabien Potencier <fabien@symfony.com>
 */
final class ConsoleCommandEvent extends ConsoleEvent
{
    /**
     * The return code for skipped commands, this will also be passed into the terminate event.
     */
    public const RETURN_CODE_DISABLED = 113;

    /**
     * Indicates if the command should be run or skipped.
     */
    private $commandShouldRun = true;

    /**
     * Disables the command, so it won't be run.
     */
    public function disableCommand(): bool
    {
        return $this->commandShouldRun = false;
    }

    public function enableCommand(): bool
    {
        return $this->commandShouldRun = true;
    }

    /**
     * Returns true if the command is runnable, false otherwise.
     */
    public function commandShouldRun(): bool
    {
        return $this->commandShouldRun;
    }
}
PKϤ$Z���bpolyfill-php54/README.mdnu�[���Symfony Polyfill / Php54
========================

This component provides functions unavailable in releases prior to PHP 5.4:

- [`trait_exists`](http://php.net/trait_exists)
- [`class_uses`](http://php.net/class_uses)
- [`hex2bin`](http://php.net/hex2bin)
- [`session_register_shutdown`](http://php.net/session_register_shutdown)

More information can be found in the
[main Polyfill README](https://github.com/symfony/polyfill/blob/master/README.md).

License
=======

This library is released under the [MIT license](LICENSE).
PKϤ$Z拝�9polyfill-php54/Resources/stubs/CallbackFilterIterator.phpnu�[���<?php

/*
 * This file is part of the Symfony package.
 *
 * (c) Fabien Potencier <fabien@symfony.com>
 *
 * For the full copyright and license information, please view the LICENSE
 * file that was distributed with this source code.
 */

class CallbackFilterIterator extends FilterIterator
{
    private $iterator;
    private $callback;

    public function __construct(Iterator $iterator, $callback)
    {
        $this->iterator = $iterator;
        $this->callback = $callback;
        parent::__construct($iterator);
    }

    public function accept()
    {
        return call_user_func($this->callback, $this->current(), $this->key(), $this->iterator);
    }
}
PKϤ$Z
�(;;:polyfill-php54/Resources/stubs/SessionHandlerInterface.phpnu�[���<?php

/*
 * This file is part of the Symfony package.
 *
 * (c) Fabien Potencier <fabien@symfony.com>
 *
 * For the full copyright and license information, please view the LICENSE
 * file that was distributed with this source code.
 */

/**
 * SessionHandlerInterface for PHP < 5.4.
 *
 * The order in which these methods are invoked by PHP are:
 * 1. open [session_start]
 * 2. read
 * 3. gc [optional depending on probability settings: gc_probability / gc_divisor]
 * 4. destroy [optional when session_regenerate_id(true) is used]
 * 5. write [session_write_close] or destroy [session_destroy]
 * 6. close
 *
 * Extensive documentation can be found at php.net, see links:
 *
 * @see http://php.net/sessionhandlerinterface
 * @see http://php.net/session.customhandler
 * @see http://php.net/session-set-save-handler
 *
 * @author Drak <drak@zikula.org>
 * @author Tobias Schultze <http://tobion.de>
 */
interface SessionHandlerInterface
{
    /**
     * Re-initializes existing session, or creates a new one.
     *
     * @see http://php.net/sessionhandlerinterface.open
     *
     * @param string $savePath    Save path
     * @param string $sessionName Session name, see http://php.net/function.session-name.php
     *
     * @return bool true on success, false on failure
     */
    public function open($savePath, $sessionName);

    /**
     * Closes the current session.
     *
     * @see http://php.net/sessionhandlerinterface.close
     *
     * @return bool true on success, false on failure
     */
    public function close();

    /**
     * Reads the session data.
     *
     * @see http://php.net/sessionhandlerinterface.read
     *
     * @param string $sessionId Session ID, see http://php.net/function.session-id
     *
     * @return string Same session data as passed in write() or empty string when non-existent or on failure
     */
    public function read($sessionId);

    /**
     * Writes the session data to the storage.
     *
     * Care, the session ID passed to write() can be different from the one previously
     * received in read() when the session ID changed due to session_regenerate_id().
     *
     * @see http://php.net/sessionhandlerinterface.write
     *
     * @param string $sessionId Session ID , see http://php.net/function.session-id
     * @param string $data      Serialized session data to save
     *
     * @return bool true on success, false on failure
     */
    public function write($sessionId, $data);

    /**
     * Destroys a session.
     *
     * @see http://php.net/sessionhandlerinterface.destroy
     *
     * @param string $sessionId Session ID, see http://php.net/function.session-id
     *
     * @return bool true on success, false on failure
     */
    public function destroy($sessionId);

    /**
     * Cleans up expired sessions (garbage collection).
     *
     * @see http://php.net/sessionhandlerinterface.gc
     *
     * @param string|int $maxlifetime Sessions that have not updated for the last maxlifetime seconds will be removed
     *
     * @return bool true on success, false on failure
     */
    public function gc($maxlifetime);
}
PKϤ$ZT��--Bpolyfill-php54/Resources/stubs/RecursiveCallbackFilterIterator.phpnu�[���<?php

/*
 * This file is part of the Symfony package.
 *
 * (c) Fabien Potencier <fabien@symfony.com>
 *
 * For the full copyright and license information, please view the LICENSE
 * file that was distributed with this source code.
 */

class RecursiveCallbackFilterIterator extends CallbackFilterIterator implements RecursiveIterator
{
    private $iterator;
    private $callback;

    public function __construct(RecursiveIterator $iterator, $callback)
    {
        $this->iterator = $iterator;
        $this->callback = $callback;
        parent::__construct($iterator, $callback);
    }

    public function hasChildren()
    {
        return $this->iterator->hasChildren();
    }

    public function getChildren()
    {
        return new static($this->iterator->getChildren(), $this->callback);
    }
}
PKϤ$Zl�f�polyfill-php54/bootstrap.phpnu�[���<?php

/*
 * This file is part of the Symfony package.
 *
 * (c) Fabien Potencier <fabien@symfony.com>
 *
 * For the full copyright and license information, please view the LICENSE
 * file that was distributed with this source code.
 */

use Symfony\Polyfill\Php54 as p;

if (PHP_VERSION_ID < 50400) {
    if (!function_exists('trait_exists')) {
        function trait_exists($class, $autoload = true) { return $autoload && class_exists($class, $autoload) && false; }
    }
    if (!function_exists('class_uses')) {
        function class_uses($class, $autoload = true)
        {
            if (is_object($class) || class_exists($class, $autoload) || interface_exists($class, false)) {
                return array();
            }

            return false;
        }
    }
    if (!function_exists('hex2bin')) {
        function hex2bin($data) { return p\Php54::hex2bin($data); }
    }
    if (!function_exists('session_register_shutdown')) {
        function session_register_shutdown() { register_shutdown_function('session_write_close'); }
    }
}
PKϤ$Z�*L))polyfill-php54/LICENSEnu�[���Copyright (c) 2014-2016 Fabien Potencier

Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is furnished
to do so, subject to the following conditions:

The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.

THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
THE SOFTWARE.
PKϤ$Zۻ_��polyfill-php54/Php54.phpnu�[���<?php

/*
 * This file is part of the Symfony package.
 *
 * (c) Fabien Potencier <fabien@symfony.com>
 *
 * For the full copyright and license information, please view the LICENSE
 * file that was distributed with this source code.
 */

namespace Symfony\Polyfill\Php54;

/**
 * @author Nicolas Grekas <p@tchwork.com>
 *
 * @internal
 */
final class Php54
{
    public static function hex2bin($data)
    {
        $len = strlen($data);

        if (null === $len) {
            return;
        }
        if ($len % 2) {
            trigger_error('hex2bin(): Hexadecimal input string must have an even length', E_USER_WARNING);

            return false;
        }

        return pack('H*', $data);
    }
}
PKϤ$Z�Q�m9m9-translation-contracts/Test/TranslatorTest.phpnu�[���<?php

/*
 * This file is part of the Symfony package.
 *
 * (c) Fabien Potencier <fabien@symfony.com>
 *
 * For the full copyright and license information, please view the LICENSE
 * file that was distributed with this source code.
 */

namespace Symfony\Contracts\Translation\Test;

use PHPUnit\Framework\TestCase;
use Symfony\Contracts\Translation\TranslatorInterface;
use Symfony\Contracts\Translation\TranslatorTrait;

/**
 * Test should cover all languages mentioned on http://translate.sourceforge.net/wiki/l10n/pluralforms
 * and Plural forms mentioned on http://www.gnu.org/software/gettext/manual/gettext.html#Plural-forms.
 *
 * See also https://developer.mozilla.org/en/Localization_and_Plurals which mentions 15 rules having a maximum of 6 forms.
 * The mozilla code is also interesting to check for.
 *
 * As mentioned by chx http://drupal.org/node/1273968 we can cover all by testing number from 0 to 199
 *
 * The goal to cover all languages is to far fetched so this test case is smaller.
 *
 * @author Clemens Tolboom clemens@build2be.nl
 */
class TranslatorTest extends TestCase
{
    public function getTranslator()
    {
        return new class() implements TranslatorInterface {
            use TranslatorTrait;
        };
    }

    /**
     * @dataProvider getTransTests
     */
    public function testTrans($expected, $id, $parameters)
    {
        $translator = $this->getTranslator();

        $this->assertEquals($expected, $translator->trans($id, $parameters));
    }

    /**
     * @dataProvider getTransChoiceTests
     */
    public function testTransChoiceWithExplicitLocale($expected, $id, $number)
    {
        $translator = $this->getTranslator();
        $translator->setLocale('en');

        $this->assertEquals($expected, $translator->trans($id, ['%count%' => $number]));
    }

    /**
     * @dataProvider getTransChoiceTests
     */
    public function testTransChoiceWithDefaultLocale($expected, $id, $number)
    {
        \Locale::setDefault('en');

        $translator = $this->getTranslator();

        $this->assertEquals($expected, $translator->trans($id, ['%count%' => $number]));
    }

    public function testGetSetLocale()
    {
        $translator = $this->getTranslator();
        $translator->setLocale('en');

        $this->assertEquals('en', $translator->getLocale());
    }

    /**
     * @requires extension intl
     */
    public function testGetLocaleReturnsDefaultLocaleIfNotSet()
    {
        $translator = $this->getTranslator();

        \Locale::setDefault('pt_BR');
        $this->assertEquals('pt_BR', $translator->getLocale());

        \Locale::setDefault('en');
        $this->assertEquals('en', $translator->getLocale());
    }

    public function getTransTests()
    {
        return [
            ['Symfony is great!', 'Symfony is great!', []],
            ['Symfony is awesome!', 'Symfony is %what%!', ['%what%' => 'awesome']],
        ];
    }

    public function getTransChoiceTests()
    {
        return [
            ['There are no apples', '{0} There are no apples|{1} There is one apple|]1,Inf] There are %count% apples', 0],
            ['There is one apple', '{0} There are no apples|{1} There is one apple|]1,Inf] There are %count% apples', 1],
            ['There are 10 apples', '{0} There are no apples|{1} There is one apple|]1,Inf] There are %count% apples', 10],
            ['There are 0 apples', 'There is 1 apple|There are %count% apples', 0],
            ['There is 1 apple', 'There is 1 apple|There are %count% apples', 1],
            ['There are 10 apples', 'There is 1 apple|There are %count% apples', 10],
            // custom validation messages may be coded with a fixed value
            ['There are 2 apples', 'There are 2 apples', 2],
        ];
    }

    /**
     * @dataProvider getInternal
     */
    public function testInterval($expected, $number, $interval)
    {
        $translator = $this->getTranslator();

        $this->assertEquals($expected, $translator->trans($interval.' foo|[1,Inf[ bar', ['%count%' => $number]));
    }

    public function getInternal()
    {
        return [
            ['foo', 3, '{1,2, 3 ,4}'],
            ['bar', 10, '{1,2, 3 ,4}'],
            ['bar', 3, '[1,2]'],
            ['foo', 1, '[1,2]'],
            ['foo', 2, '[1,2]'],
            ['bar', 1, ']1,2['],
            ['bar', 2, ']1,2['],
            ['foo', log(0), '[-Inf,2['],
            ['foo', -log(0), '[-2,+Inf]'],
        ];
    }

    /**
     * @dataProvider getChooseTests
     */
    public function testChoose($expected, $id, $number)
    {
        $translator = $this->getTranslator();

        $this->assertEquals($expected, $translator->trans($id, ['%count%' => $number]));
    }

    public function testReturnMessageIfExactlyOneStandardRuleIsGiven()
    {
        $translator = $this->getTranslator();

        $this->assertEquals('There are two apples', $translator->trans('There are two apples', ['%count%' => 2]));
    }

    /**
     * @dataProvider getNonMatchingMessages
     */
    public function testThrowExceptionIfMatchingMessageCannotBeFound($id, $number)
    {
        $this->expectException('InvalidArgumentException');
        $translator = $this->getTranslator();

        $translator->trans($id, ['%count%' => $number]);
    }

    public function getNonMatchingMessages()
    {
        return [
            ['{0} There are no apples|{1} There is one apple', 2],
            ['{1} There is one apple|]1,Inf] There are %count% apples', 0],
            ['{1} There is one apple|]2,Inf] There are %count% apples', 2],
            ['{0} There are no apples|There is one apple', 2],
        ];
    }

    public function getChooseTests()
    {
        return [
            ['There are no apples', '{0} There are no apples|{1} There is one apple|]1,Inf] There are %count% apples', 0],
            ['There are no apples', '{0}     There are no apples|{1} There is one apple|]1,Inf] There are %count% apples', 0],
            ['There are no apples', '{0}There are no apples|{1} There is one apple|]1,Inf] There are %count% apples', 0],

            ['There is one apple', '{0} There are no apples|{1} There is one apple|]1,Inf] There are %count% apples', 1],

            ['There are 10 apples', '{0} There are no apples|{1} There is one apple|]1,Inf] There are %count% apples', 10],
            ['There are 10 apples', '{0} There are no apples|{1} There is one apple|]1,Inf]There are %count% apples', 10],
            ['There are 10 apples', '{0} There are no apples|{1} There is one apple|]1,Inf]     There are %count% apples', 10],

            ['There are 0 apples', 'There is one apple|There are %count% apples', 0],
            ['There is one apple', 'There is one apple|There are %count% apples', 1],
            ['There are 10 apples', 'There is one apple|There are %count% apples', 10],

            ['There are 0 apples', 'one: There is one apple|more: There are %count% apples', 0],
            ['There is one apple', 'one: There is one apple|more: There are %count% apples', 1],
            ['There are 10 apples', 'one: There is one apple|more: There are %count% apples', 10],

            ['There are no apples', '{0} There are no apples|one: There is one apple|more: There are %count% apples', 0],
            ['There is one apple', '{0} There are no apples|one: There is one apple|more: There are %count% apples', 1],
            ['There are 10 apples', '{0} There are no apples|one: There is one apple|more: There are %count% apples', 10],

            ['', '{0}|{1} There is one apple|]1,Inf] There are %count% apples', 0],
            ['', '{0} There are no apples|{1}|]1,Inf] There are %count% apples', 1],

            // Indexed only tests which are Gettext PoFile* compatible strings.
            ['There are 0 apples', 'There is one apple|There are %count% apples', 0],
            ['There is one apple', 'There is one apple|There are %count% apples', 1],
            ['There are 2 apples', 'There is one apple|There are %count% apples', 2],

            // Tests for float numbers
            ['There is almost one apple', '{0} There are no apples|]0,1[ There is almost one apple|{1} There is one apple|[1,Inf] There is more than one apple', 0.7],
            ['There is one apple', '{0} There are no apples|]0,1[There are %count% apples|{1} There is one apple|[1,Inf] There is more than one apple', 1],
            ['There is more than one apple', '{0} There are no apples|]0,1[There are %count% apples|{1} There is one apple|[1,Inf] There is more than one apple', 1.7],
            ['There are no apples', '{0} There are no apples|]0,1[There are %count% apples|{1} There is one apple|[1,Inf] There is more than one apple', 0],
            ['There are no apples', '{0} There are no apples|]0,1[There are %count% apples|{1} There is one apple|[1,Inf] There is more than one apple', 0.0],
            ['There are no apples', '{0.0} There are no apples|]0,1[There are %count% apples|{1} There is one apple|[1,Inf] There is more than one apple', 0],

            // Test texts with new-lines
            // with double-quotes and \n in id & double-quotes and actual newlines in text
            ["This is a text with a\n            new-line in it. Selector = 0.", '{0}This is a text with a
            new-line in it. Selector = 0.|{1}This is a text with a
            new-line in it. Selector = 1.|[1,Inf]This is a text with a
            new-line in it. Selector > 1.', 0],
            // with double-quotes and \n in id and single-quotes and actual newlines in text
            ["This is a text with a\n            new-line in it. Selector = 1.", '{0}This is a text with a
            new-line in it. Selector = 0.|{1}This is a text with a
            new-line in it. Selector = 1.|[1,Inf]This is a text with a
            new-line in it. Selector > 1.', 1],
            ["This is a text with a\n            new-line in it. Selector > 1.", '{0}This is a text with a
            new-line in it. Selector = 0.|{1}This is a text with a
            new-line in it. Selector = 1.|[1,Inf]This is a text with a
            new-line in it. Selector > 1.', 5],
            // with double-quotes and id split accros lines
            ['This is a text with a
            new-line in it. Selector = 1.', '{0}This is a text with a
            new-line in it. Selector = 0.|{1}This is a text with a
            new-line in it. Selector = 1.|[1,Inf]This is a text with a
            new-line in it. Selector > 1.', 1],
            // with single-quotes and id split accros lines
            ['This is a text with a
            new-line in it. Selector > 1.', '{0}This is a text with a
            new-line in it. Selector = 0.|{1}This is a text with a
            new-line in it. Selector = 1.|[1,Inf]This is a text with a
            new-line in it. Selector > 1.', 5],
            // with single-quotes and \n in text
            ['This is a text with a\nnew-line in it. Selector = 0.', '{0}This is a text with a\nnew-line in it. Selector = 0.|{1}This is a text with a\nnew-line in it. Selector = 1.|[1,Inf]This is a text with a\nnew-line in it. Selector > 1.', 0],
            // with double-quotes and id split accros lines
            ["This is a text with a\nnew-line in it. Selector = 1.", "{0}This is a text with a\nnew-line in it. Selector = 0.|{1}This is a text with a\nnew-line in it. Selector = 1.|[1,Inf]This is a text with a\nnew-line in it. Selector > 1.", 1],
            // esacape pipe
            ['This is a text with | in it. Selector = 0.', '{0}This is a text with || in it. Selector = 0.|{1}This is a text with || in it. Selector = 1.', 0],
            // Empty plural set (2 plural forms) from a .PO file
            ['', '|', 1],
            // Empty plural set (3 plural forms) from a .PO file
            ['', '||', 1],
        ];
    }

    /**
     * @dataProvider failingLangcodes
     */
    public function testFailedLangcodes($nplural, $langCodes)
    {
        $matrix = $this->generateTestData($langCodes);
        $this->validateMatrix($nplural, $matrix, false);
    }

    /**
     * @dataProvider successLangcodes
     */
    public function testLangcodes($nplural, $langCodes)
    {
        $matrix = $this->generateTestData($langCodes);
        $this->validateMatrix($nplural, $matrix);
    }

    /**
     * This array should contain all currently known langcodes.
     *
     * As it is impossible to have this ever complete we should try as hard as possible to have it almost complete.
     *
     * @return array
     */
    public function successLangcodes()
    {
        return [
            ['1', ['ay', 'bo', 'cgg', 'dz', 'id', 'ja', 'jbo', 'ka', 'kk', 'km', 'ko', 'ky']],
            ['2', ['nl', 'fr', 'en', 'de', 'de_GE', 'hy', 'hy_AM']],
            ['3', ['be', 'bs', 'cs', 'hr']],
            ['4', ['cy', 'mt', 'sl']],
            ['6', ['ar']],
        ];
    }

    /**
     * This array should be at least empty within the near future.
     *
     * This both depends on a complete list trying to add above as understanding
     * the plural rules of the current failing languages.
     *
     * @return array with nplural together with langcodes
     */
    public function failingLangcodes()
    {
        return [
            ['1', ['fa']],
            ['2', ['jbo']],
            ['3', ['cbs']],
            ['4', ['gd', 'kw']],
            ['5', ['ga']],
        ];
    }

    /**
     * We validate only on the plural coverage. Thus the real rules is not tested.
     *
     * @param string $nplural       Plural expected
     * @param array  $matrix        Containing langcodes and their plural index values
     * @param bool   $expectSuccess
     */
    protected function validateMatrix($nplural, $matrix, $expectSuccess = true)
    {
        foreach ($matrix as $langCode => $data) {
            $indexes = array_flip($data);
            if ($expectSuccess) {
                $this->assertEquals($nplural, \count($indexes), "Langcode '$langCode' has '$nplural' plural forms.");
            } else {
                $this->assertNotEquals((int) $nplural, \count($indexes), "Langcode '$langCode' has '$nplural' plural forms.");
            }
        }
    }

    protected function generateTestData($langCodes)
    {
        $translator = new class() {
            use TranslatorTrait {
                getPluralizationRule as public;
            }
        };

        $matrix = [];
        foreach ($langCodes as $langCode) {
            for ($count = 0; $count < 200; ++$count) {
                $plural = $translator->getPluralizationRule($count, $langCode);
                $matrix[$langCode][$count] = $plural;
            }
        }

        return $matrix;
    }
}
PKϤ$Z\�=4�	�	-translation-contracts/TranslatorInterface.phpnu�[���<?php

/*
 * This file is part of the Symfony package.
 *
 * (c) Fabien Potencier <fabien@symfony.com>
 *
 * For the full copyright and license information, please view the LICENSE
 * file that was distributed with this source code.
 */

namespace Symfony\Contracts\Translation;

/**
 * @author Fabien Potencier <fabien@symfony.com>
 */
interface TranslatorInterface
{
    /**
     * Translates the given message.
     *
     * When a number is provided as a parameter named "%count%", the message is parsed for plural
     * forms and a translation is chosen according to this number using the following rules:
     *
     * Given a message with different plural translations separated by a
     * pipe (|), this method returns the correct portion of the message based
     * on the given number, locale and the pluralization rules in the message
     * itself.
     *
     * The message supports two different types of pluralization rules:
     *
     * interval: {0} There are no apples|{1} There is one apple|]1,Inf] There are %count% apples
     * indexed:  There is one apple|There are %count% apples
     *
     * The indexed solution can also contain labels (e.g. one: There is one apple).
     * This is purely for making the translations more clear - it does not
     * affect the functionality.
     *
     * The two methods can also be mixed:
     *     {0} There are no apples|one: There is one apple|more: There are %count% apples
     *
     * An interval can represent a finite set of numbers:
     *  {1,2,3,4}
     *
     * An interval can represent numbers between two numbers:
     *  [1, +Inf]
     *  ]-1,2[
     *
     * The left delimiter can be [ (inclusive) or ] (exclusive).
     * The right delimiter can be [ (exclusive) or ] (inclusive).
     * Beside numbers, you can use -Inf and +Inf for the infinite.
     *
     * @see https://en.wikipedia.org/wiki/ISO_31-11
     *
     * @param string      $id         The message id (may also be an object that can be cast to string)
     * @param array       $parameters An array of parameters for the message
     * @param string|null $domain     The domain for the message or null to use the default
     * @param string|null $locale     The locale or null to use the default
     *
     * @return string The translated string
     *
     * @throws \InvalidArgumentException If the locale contains invalid characters
     */
    public function trans(string $id, array $parameters = [], string $domain = null, string $locale = null);
}
PKϤ$Z��.p��/translation-contracts/TranslatableInterface.phpnu�[���<?php

/*
 * This file is part of the Symfony package.
 *
 * (c) Fabien Potencier <fabien@symfony.com>
 *
 * For the full copyright and license information, please view the LICENSE
 * file that was distributed with this source code.
 */

namespace Symfony\Contracts\Translation;

/**
 * @author Nicolas Grekas <p@tchwork.com>
 */
interface TranslatableInterface
{
    public function trans(TranslatorInterface $translator, string $locale = null): string;
}
PKϤ$ZVNK�VVtranslation-contracts/README.mdnu�[���Symfony Translation Contracts
=============================

A set of abstractions extracted out of the Symfony components.

Can be used to build on semantics that the Symfony components proved useful - and
that already have battle tested implementations.

See https://github.com/symfony/contracts/blob/master/README.md for more information.
PKϤ$Z�����"translation-contracts/CHANGELOG.mdnu�[���CHANGELOG
=========

The changelog is maintained for all Symfony contracts at the following URL:
https://github.com/symfony/contracts/blob/master/CHANGELOG.md
PKϤ$Z��� � )translation-contracts/TranslatorTrait.phpnu�[���<?php

/*
 * This file is part of the Symfony package.
 *
 * (c) Fabien Potencier <fabien@symfony.com>
 *
 * For the full copyright and license information, please view the LICENSE
 * file that was distributed with this source code.
 */

namespace Symfony\Contracts\Translation;

use Symfony\Component\Translation\Exception\InvalidArgumentException;

/**
 * A trait to help implement TranslatorInterface and LocaleAwareInterface.
 *
 * @author Fabien Potencier <fabien@symfony.com>
 */
trait TranslatorTrait
{
    private $locale;

    /**
     * {@inheritdoc}
     */
    public function setLocale(string $locale)
    {
        $this->locale = $locale;
    }

    /**
     * {@inheritdoc}
     */
    public function getLocale()
    {
        return $this->locale ?: (class_exists(\Locale::class) ? \Locale::getDefault() : 'en');
    }

    /**
     * {@inheritdoc}
     */
    public function trans(?string $id, array $parameters = [], string $domain = null, string $locale = null): string
    {
        if (null === $id || '' === $id) {
            return '';
        }

        if (!isset($parameters['%count%']) || !is_numeric($parameters['%count%'])) {
            return strtr($id, $parameters);
        }

        $number = (float) $parameters['%count%'];
        $locale = $locale ?: $this->getLocale();

        $parts = [];
        if (preg_match('/^\|++$/', $id)) {
            $parts = explode('|', $id);
        } elseif (preg_match_all('/(?:\|\||[^\|])++/', $id, $matches)) {
            $parts = $matches[0];
        }

        $intervalRegexp = <<<'EOF'
/^(?P<interval>
    ({\s*
        (\-?\d+(\.\d+)?[\s*,\s*\-?\d+(\.\d+)?]*)
    \s*})

        |

    (?P<left_delimiter>[\[\]])
        \s*
        (?P<left>-Inf|\-?\d+(\.\d+)?)
        \s*,\s*
        (?P<right>\+?Inf|\-?\d+(\.\d+)?)
        \s*
    (?P<right_delimiter>[\[\]])
)\s*(?P<message>.*?)$/xs
EOF;

        $standardRules = [];
        foreach ($parts as $part) {
            $part = trim(str_replace('||', '|', $part));

            // try to match an explicit rule, then fallback to the standard ones
            if (preg_match($intervalRegexp, $part, $matches)) {
                if ($matches[2]) {
                    foreach (explode(',', $matches[3]) as $n) {
                        if ($number == $n) {
                            return strtr($matches['message'], $parameters);
                        }
                    }
                } else {
                    $leftNumber = '-Inf' === $matches['left'] ? -\INF : (float) $matches['left'];
                    $rightNumber = is_numeric($matches['right']) ? (float) $matches['right'] : \INF;

                    if (('[' === $matches['left_delimiter'] ? $number >= $leftNumber : $number > $leftNumber)
                        && (']' === $matches['right_delimiter'] ? $number <= $rightNumber : $number < $rightNumber)
                    ) {
                        return strtr($matches['message'], $parameters);
                    }
                }
            } elseif (preg_match('/^\w+\:\s*(.*?)$/', $part, $matches)) {
                $standardRules[] = $matches[1];
            } else {
                $standardRules[] = $part;
            }
        }

        $position = $this->getPluralizationRule($number, $locale);

        if (!isset($standardRules[$position])) {
            // when there's exactly one rule given, and that rule is a standard
            // rule, use this rule
            if (1 === \count($parts) && isset($standardRules[0])) {
                return strtr($standardRules[0], $parameters);
            }

            $message = sprintf('Unable to choose a translation for "%s" with locale "%s" for value "%d". Double check that this translation has the correct plural options (e.g. "There is one apple|There are %%count%% apples").', $id, $locale, $number);

            if (class_exists(InvalidArgumentException::class)) {
                throw new InvalidArgumentException($message);
            }

            throw new \InvalidArgumentException($message);
        }

        return strtr($standardRules[$position], $parameters);
    }

    /**
     * Returns the plural position to use for the given locale and number.
     *
     * The plural rules are derived from code of the Zend Framework (2010-09-25),
     * which is subject to the new BSD license (http://framework.zend.com/license/new-bsd).
     * Copyright (c) 2005-2010 Zend Technologies USA Inc. (http://www.zend.com)
     */
    private function getPluralizationRule(int $number, string $locale): int
    {
        switch ('pt_BR' !== $locale && \strlen($locale) > 3 ? substr($locale, 0, strrpos($locale, '_')) : $locale) {
            case 'af':
            case 'bn':
            case 'bg':
            case 'ca':
            case 'da':
            case 'de':
            case 'el':
            case 'en':
            case 'eo':
            case 'es':
            case 'et':
            case 'eu':
            case 'fa':
            case 'fi':
            case 'fo':
            case 'fur':
            case 'fy':
            case 'gl':
            case 'gu':
            case 'ha':
            case 'he':
            case 'hu':
            case 'is':
            case 'it':
            case 'ku':
            case 'lb':
            case 'ml':
            case 'mn':
            case 'mr':
            case 'nah':
            case 'nb':
            case 'ne':
            case 'nl':
            case 'nn':
            case 'no':
            case 'oc':
            case 'om':
            case 'or':
            case 'pa':
            case 'pap':
            case 'ps':
            case 'pt':
            case 'so':
            case 'sq':
            case 'sv':
            case 'sw':
            case 'ta':
            case 'te':
            case 'tk':
            case 'ur':
            case 'zu':
                return (1 == $number) ? 0 : 1;

            case 'am':
            case 'bh':
            case 'fil':
            case 'fr':
            case 'gun':
            case 'hi':
            case 'hy':
            case 'ln':
            case 'mg':
            case 'nso':
            case 'pt_BR':
            case 'ti':
            case 'wa':
                return ((0 == $number) || (1 == $number)) ? 0 : 1;

            case 'be':
            case 'bs':
            case 'hr':
            case 'ru':
            case 'sh':
            case 'sr':
            case 'uk':
                return ((1 == $number % 10) && (11 != $number % 100)) ? 0 : ((($number % 10 >= 2) && ($number % 10 <= 4) && (($number % 100 < 10) || ($number % 100 >= 20))) ? 1 : 2);

            case 'cs':
            case 'sk':
                return (1 == $number) ? 0 : ((($number >= 2) && ($number <= 4)) ? 1 : 2);

            case 'ga':
                return (1 == $number) ? 0 : ((2 == $number) ? 1 : 2);

            case 'lt':
                return ((1 == $number % 10) && (11 != $number % 100)) ? 0 : ((($number % 10 >= 2) && (($number % 100 < 10) || ($number % 100 >= 20))) ? 1 : 2);

            case 'sl':
                return (1 == $number % 100) ? 0 : ((2 == $number % 100) ? 1 : (((3 == $number % 100) || (4 == $number % 100)) ? 2 : 3));

            case 'mk':
                return (1 == $number % 10) ? 0 : 1;

            case 'mt':
                return (1 == $number) ? 0 : (((0 == $number) || (($number % 100 > 1) && ($number % 100 < 11))) ? 1 : ((($number % 100 > 10) && ($number % 100 < 20)) ? 2 : 3));

            case 'lv':
                return (0 == $number) ? 0 : (((1 == $number % 10) && (11 != $number % 100)) ? 1 : 2);

            case 'pl':
                return (1 == $number) ? 0 : ((($number % 10 >= 2) && ($number % 10 <= 4) && (($number % 100 < 12) || ($number % 100 > 14))) ? 1 : 2);

            case 'cy':
                return (1 == $number) ? 0 : ((2 == $number) ? 1 : (((8 == $number) || (11 == $number)) ? 2 : 3));

            case 'ro':
                return (1 == $number) ? 0 : (((0 == $number) || (($number % 100 > 0) && ($number % 100 < 20))) ? 1 : 2);

            case 'ar':
                return (0 == $number) ? 0 : ((1 == $number) ? 1 : ((2 == $number) ? 2 : ((($number % 100 >= 3) && ($number % 100 <= 10)) ? 3 : ((($number % 100 >= 11) && ($number % 100 <= 99)) ? 4 : 5))));

            default:
                return 0;
        }
    }
}
PKϤ$Zi8�z))translation-contracts/LICENSEnu�[���Copyright (c) 2018-2020 Fabien Potencier

Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is furnished
to do so, subject to the following conditions:

The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.

THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
THE SOFTWARE.
PKϤ$Z8"=��.translation-contracts/LocaleAwareInterface.phpnu�[���<?php

/*
 * This file is part of the Symfony package.
 *
 * (c) Fabien Potencier <fabien@symfony.com>
 *
 * For the full copyright and license information, please view the LICENSE
 * file that was distributed with this source code.
 */

namespace Symfony\Contracts\Translation;

interface LocaleAwareInterface
{
    /**
     * Sets the current locale.
     *
     * @param string $locale The locale
     *
     * @throws \InvalidArgumentException If the locale contains invalid characters
     */
    public function setLocale(string $locale);

    /**
     * Returns the current locale.
     *
     * @return string The locale
     */
    public function getLocale();
}
PKϤ$Z��3��deprecation-contracts/README.mdnu�[���Symfony Deprecation Contracts
=============================

A generic function and convention to trigger deprecation notices.

This package provides a single global function named `trigger_deprecation()` that triggers silenced deprecation notices.

By using a custom PHP error handler such as the one provided by the Symfony ErrorHandler component,
the triggered deprecations can be caught and logged for later discovery, both on dev and prod environments.

The function requires at least 3 arguments:
 - the name of the Composer package that is triggering the deprecation
 - the version of the package that introduced the deprecation
 - the message of the deprecation
 - more arguments can be provided: they will be inserted in the message using `printf()` formatting

Example:
```php
trigger_deprecation('symfony/blockchain', '8.9', 'Using "%s" is deprecated, use "%s" instead.', 'bitcoin', 'fabcoin');
```

This will generate the following message:
`Since symfony/blockchain 8.9: Using "bitcoin" is deprecated, use "fabcoin" instead.`

While not necessarily recommended, the deprecation notices can be completely ignored by declaring an empty
`function trigger_deprecation() {}` in your application.
PKϤ$Zrg����"deprecation-contracts/function.phpnu�[���<?php

/*
 * This file is part of the Symfony package.
 *
 * (c) Fabien Potencier <fabien@symfony.com>
 *
 * For the full copyright and license information, please view the LICENSE
 * file that was distributed with this source code.
 */

if (!function_exists('trigger_deprecation')) {
    /**
     * Triggers a silenced deprecation notice.
     *
     * @param string $package The name of the Composer package that is triggering the deprecation
     * @param string $version The version of the package that introduced the deprecation
     * @param string $message The message of the deprecation
     * @param mixed  ...$args Values to insert in the message using printf() formatting
     *
     * @author Nicolas Grekas <p@tchwork.com>
     */
    function trigger_deprecation(string $package, string $version, string $message, ...$args): void
    {
        @trigger_error(($package || $version ? "Since $package $version: " : '').($args ? vsprintf($message, $args) : $message), \E_USER_DEPRECATED);
    }
}
PKϤ$Z�����"deprecation-contracts/CHANGELOG.mdnu�[���CHANGELOG
=========

The changelog is maintained for all Symfony contracts at the following URL:
https://github.com/symfony/contracts/blob/master/CHANGELOG.md
PKϤ$ZLO!
$$deprecation-contracts/LICENSEnu�[���Copyright (c) 2020 Fabien Potencier

Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is furnished
to do so, subject to the following conditions:

The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.

THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
THE SOFTWARE.
PKϤ$Z��R�	�	process/PhpProcess.phpnu�[���<?php

/*
 * This file is part of the Symfony package.
 *
 * (c) Fabien Potencier <fabien@symfony.com>
 *
 * For the full copyright and license information, please view the LICENSE
 * file that was distributed with this source code.
 */

namespace Symfony\Component\Process;

use Symfony\Component\Process\Exception\LogicException;
use Symfony\Component\Process\Exception\RuntimeException;

/**
 * PhpProcess runs a PHP script in an independent process.
 *
 *     $p = new PhpProcess('<?php echo "foo"; ?>');
 *     $p->run();
 *     print $p->getOutput()."\n";
 *
 * @author Fabien Potencier <fabien@symfony.com>
 */
class PhpProcess extends Process
{
    /**
     * @param string      $script  The PHP script to run (as a string)
     * @param string|null $cwd     The working directory or null to use the working dir of the current PHP process
     * @param array|null  $env     The environment variables or null to use the same environment as the current PHP process
     * @param int         $timeout The timeout in seconds
     * @param array|null  $php     Path to the PHP binary to use with any additional arguments
     */
    public function __construct(string $script, string $cwd = null, array $env = null, int $timeout = 60, array $php = null)
    {
        if (null === $php) {
            $executableFinder = new PhpExecutableFinder();
            $php = $executableFinder->find(false);
            $php = false === $php ? null : array_merge([$php], $executableFinder->findArguments());
        }
        if ('phpdbg' === \PHP_SAPI) {
            $file = tempnam(sys_get_temp_dir(), 'dbg');
            file_put_contents($file, $script);
            register_shutdown_function('unlink', $file);
            $php[] = $file;
            $script = null;
        }

        parent::__construct($php, $cwd, $env, $script, $timeout);
    }

    /**
     * {@inheritdoc}
     */
    public static function fromShellCommandline(string $command, string $cwd = null, array $env = null, $input = null, ?float $timeout = 60)
    {
        throw new LogicException(sprintf('The "%s()" method cannot be called when using "%s".', __METHOD__, self::class));
    }

    /**
     * {@inheritdoc}
     */
    public function start(callable $callback = null, array $env = [])
    {
        if (null === $this->getCommandLine()) {
            throw new RuntimeException('Unable to find the PHP executable.');
        }

        parent::start($callback, $env);
    }
}
PKϤ$Zf�#�� process/Tests/SignalListener.phpnu�[���<?php

/*
 * This file is part of the Symfony package.
 *
 * (c) Fabien Potencier <fabien@symfony.com>
 *
 * For the full copyright and license information, please view the LICENSE
 * file that was distributed with this source code.
 */

pcntl_signal(SIGUSR1, function () { echo 'SIGUSR1'; exit; });

echo 'Caught ';

$n = 0;

while ($n++ < 400) {
    usleep(10000);
    pcntl_signal_dispatch();
}
PKϤ$Z�y$^��)process/Tests/PhpExecutableFinderTest.phpnu�[���<?php

/*
 * This file is part of the Symfony package.
 *
 * (c) Fabien Potencier <fabien@symfony.com>
 *
 * For the full copyright and license information, please view the LICENSE
 * file that was distributed with this source code.
 */

namespace Symfony\Component\Process\Tests;

use PHPUnit\Framework\TestCase;
use Symfony\Component\Process\PhpExecutableFinder;

/**
 * @author Robert Schönthal <seroscho@googlemail.com>
 */
class PhpExecutableFinderTest extends TestCase
{
    /**
     * tests find() with the constant PHP_BINARY.
     */
    public function testFind()
    {
        if (defined('HHVM_VERSION')) {
            $this->markTestSkipped('Should not be executed in HHVM context.');
        }

        $f = new PhpExecutableFinder();

        $current = PHP_BINARY;
        $args = 'phpdbg' === PHP_SAPI ? ' -qrr' : '';

        $this->assertEquals($current.$args, $f->find(), '::find() returns the executable PHP');
        $this->assertEquals($current, $f->find(false), '::find() returns the executable PHP');
    }

    /**
     * tests find() with the env var / constant PHP_BINARY with HHVM.
     */
    public function testFindWithHHVM()
    {
        if (!defined('HHVM_VERSION')) {
            $this->markTestSkipped('Should be executed in HHVM context.');
        }

        $f = new PhpExecutableFinder();

        $current = getenv('PHP_BINARY') ?: PHP_BINARY;

        $this->assertEquals($current.' --php', $f->find(), '::find() returns the executable PHP');
        $this->assertEquals($current, $f->find(false), '::find() returns the executable PHP');
    }

    /**
     * tests find() with the env var PHP_PATH.
     */
    public function testFindArguments()
    {
        $f = new PhpExecutableFinder();

        if (defined('HHVM_VERSION')) {
            $this->assertEquals($f->findArguments(), array('--php'), '::findArguments() returns HHVM arguments');
        } elseif ('phpdbg' === PHP_SAPI) {
            $this->assertEquals($f->findArguments(), array('-qrr'), '::findArguments() returns phpdbg arguments');
        } else {
            $this->assertEquals($f->findArguments(), array(), '::findArguments() returns no arguments');
        }
    }
}
PKϤ$Z��¨��5process/Tests/PipeStdinInStdoutStdErrStreamSelect.phpnu�[���<?php

/*
 * This file is part of the Symfony package.
 *
 * (c) Fabien Potencier <fabien@symfony.com>
 *
 * For the full copyright and license information, please view the LICENSE
 * file that was distributed with this source code.
 */

define('ERR_SELECT_FAILED', 1);
define('ERR_TIMEOUT', 2);
define('ERR_READ_FAILED', 3);
define('ERR_WRITE_FAILED', 4);

$read = array(STDIN);
$write = array(STDOUT, STDERR);

stream_set_blocking(STDIN, 0);
stream_set_blocking(STDOUT, 0);
stream_set_blocking(STDERR, 0);

$out = $err = '';
while ($read || $write) {
    $r = $read;
    $w = $write;
    $e = null;
    $n = stream_select($r, $w, $e, 5);

    if (false === $n) {
        die(ERR_SELECT_FAILED);
    } elseif ($n < 1) {
        die(ERR_TIMEOUT);
    }

    if (in_array(STDOUT, $w) && strlen($out) > 0) {
        $written = fwrite(STDOUT, (binary) $out, 32768);
        if (false === $written) {
            die(ERR_WRITE_FAILED);
        }
        $out = (binary) substr($out, $written);
    }
    if (null === $read && '' === $out) {
        $write = array_diff($write, array(STDOUT));
    }

    if (in_array(STDERR, $w) && strlen($err) > 0) {
        $written = fwrite(STDERR, (binary) $err, 32768);
        if (false === $written) {
            die(ERR_WRITE_FAILED);
        }
        $err = (binary) substr($err, $written);
    }
    if (null === $read && '' === $err) {
        $write = array_diff($write, array(STDERR));
    }

    if ($r) {
        $str = fread(STDIN, 32768);
        if (false !== $str) {
            $out .= $str;
            $err .= $str;
        }
        if (false === $str || feof(STDIN)) {
            $read = null;
            if (!feof(STDIN)) {
                die(ERR_READ_FAILED);
            }
        }
    }
}
PKϤ$ZI+sL��$process/Tests/ProcessBuilderTest.phpnu�[���<?php

/*
 * This file is part of the Symfony package.
 *
 * (c) Fabien Potencier <fabien@symfony.com>
 *
 * For the full copyright and license information, please view the LICENSE
 * file that was distributed with this source code.
 */

namespace Symfony\Component\Process\Tests;

use PHPUnit\Framework\TestCase;
use Symfony\Component\Process\ProcessBuilder;

class ProcessBuilderTest extends TestCase
{
    /**
     * @group legacy
     */
    public function testInheritEnvironmentVars()
    {
        $proc = ProcessBuilder::create()
            ->add('foo')
            ->getProcess();

        $this->assertTrue($proc->areEnvironmentVariablesInherited());

        $proc = ProcessBuilder::create()
            ->add('foo')
            ->inheritEnvironmentVariables(false)
            ->getProcess();

        $this->assertFalse($proc->areEnvironmentVariablesInherited());
    }

    public function testAddEnvironmentVariables()
    {
        $pb = new ProcessBuilder();
        $env = array(
            'foo' => 'bar',
            'foo2' => 'bar2',
        );
        $proc = $pb
            ->add('command')
            ->setEnv('foo', 'bar2')
            ->addEnvironmentVariables($env)
            ->getProcess()
        ;

        $this->assertSame($env, $proc->getEnv());
    }

    /**
     * @expectedException \Symfony\Component\Process\Exception\InvalidArgumentException
     */
    public function testNegativeTimeoutFromSetter()
    {
        $pb = new ProcessBuilder();
        $pb->setTimeout(-1);
    }

    public function testNullTimeout()
    {
        $pb = new ProcessBuilder();
        $pb->setTimeout(10);
        $pb->setTimeout(null);

        $r = new \ReflectionObject($pb);
        $p = $r->getProperty('timeout');
        $p->setAccessible(true);

        $this->assertNull($p->getValue($pb));
    }

    public function testShouldSetArguments()
    {
        $pb = new ProcessBuilder(array('initial'));
        $pb->setArguments(array('second'));

        $proc = $pb->getProcess();

        $this->assertContains('second', $proc->getCommandLine());
    }

    public function testPrefixIsPrependedToAllGeneratedProcess()
    {
        $pb = new ProcessBuilder();
        $pb->setPrefix('/usr/bin/php');

        $proc = $pb->setArguments(array('-v'))->getProcess();
        if ('\\' === DIRECTORY_SEPARATOR) {
            $this->assertEquals('"/usr/bin/php" -v', $proc->getCommandLine());
        } else {
            $this->assertEquals("'/usr/bin/php' '-v'", $proc->getCommandLine());
        }

        $proc = $pb->setArguments(array('-i'))->getProcess();
        if ('\\' === DIRECTORY_SEPARATOR) {
            $this->assertEquals('"/usr/bin/php" -i', $proc->getCommandLine());
        } else {
            $this->assertEquals("'/usr/bin/php' '-i'", $proc->getCommandLine());
        }
    }

    public function testArrayPrefixesArePrependedToAllGeneratedProcess()
    {
        $pb = new ProcessBuilder();
        $pb->setPrefix(array('/usr/bin/php', 'composer.phar'));

        $proc = $pb->setArguments(array('-v'))->getProcess();
        if ('\\' === DIRECTORY_SEPARATOR) {
            $this->assertEquals('"/usr/bin/php" composer.phar -v', $proc->getCommandLine());
        } else {
            $this->assertEquals("'/usr/bin/php' 'composer.phar' '-v'", $proc->getCommandLine());
        }

        $proc = $pb->setArguments(array('-i'))->getProcess();
        if ('\\' === DIRECTORY_SEPARATOR) {
            $this->assertEquals('"/usr/bin/php" composer.phar -i', $proc->getCommandLine());
        } else {
            $this->assertEquals("'/usr/bin/php' 'composer.phar' '-i'", $proc->getCommandLine());
        }
    }

    public function testShouldEscapeArguments()
    {
        $pb = new ProcessBuilder(array('%path%', 'foo " bar', '%baz%baz'));
        $proc = $pb->getProcess();

        if ('\\' === DIRECTORY_SEPARATOR) {
            $this->assertSame('""^%"path"^%"" "foo "" bar" ""^%"baz"^%"baz"', $proc->getCommandLine());
        } else {
            $this->assertSame("'%path%' 'foo \" bar' '%baz%baz'", $proc->getCommandLine());
        }
    }

    public function testShouldEscapeArgumentsAndPrefix()
    {
        $pb = new ProcessBuilder(array('arg'));
        $pb->setPrefix('%prefix%');
        $proc = $pb->getProcess();

        if ('\\' === DIRECTORY_SEPARATOR) {
            $this->assertSame('""^%"prefix"^%"" arg', $proc->getCommandLine());
        } else {
            $this->assertSame("'%prefix%' 'arg'", $proc->getCommandLine());
        }
    }

    /**
     * @expectedException \Symfony\Component\Process\Exception\LogicException
     */
    public function testShouldThrowALogicExceptionIfNoPrefixAndNoArgument()
    {
        ProcessBuilder::create()->getProcess();
    }

    public function testShouldNotThrowALogicExceptionIfNoArgument()
    {
        $process = ProcessBuilder::create()
            ->setPrefix('/usr/bin/php')
            ->getProcess();

        if ('\\' === DIRECTORY_SEPARATOR) {
            $this->assertEquals('"/usr/bin/php"', $process->getCommandLine());
        } else {
            $this->assertEquals("'/usr/bin/php'", $process->getCommandLine());
        }
    }

    public function testShouldNotThrowALogicExceptionIfNoPrefix()
    {
        $process = ProcessBuilder::create(array('/usr/bin/php'))
            ->getProcess();

        if ('\\' === DIRECTORY_SEPARATOR) {
            $this->assertEquals('"/usr/bin/php"', $process->getCommandLine());
        } else {
            $this->assertEquals("'/usr/bin/php'", $process->getCommandLine());
        }
    }

    public function testShouldReturnProcessWithDisabledOutput()
    {
        $process = ProcessBuilder::create(array('/usr/bin/php'))
            ->disableOutput()
            ->getProcess();

        $this->assertTrue($process->isOutputDisabled());
    }

    public function testShouldReturnProcessWithEnabledOutput()
    {
        $process = ProcessBuilder::create(array('/usr/bin/php'))
            ->disableOutput()
            ->enableOutput()
            ->getProcess();

        $this->assertFalse($process->isOutputDisabled());
    }

    /**
     * @expectedException \Symfony\Component\Process\Exception\InvalidArgumentException
     * @expectedExceptionMessage Symfony\Component\Process\ProcessBuilder::setInput only accepts strings, Traversable objects or stream resources.
     */
    public function testInvalidInput()
    {
        $builder = ProcessBuilder::create();
        $builder->setInput(array());
    }

    public function testDoesNotPrefixExec()
    {
        if ('\\' === DIRECTORY_SEPARATOR) {
            $this->markTestSkipped('This test cannot run on Windows.');
        }

        $builder = ProcessBuilder::create(array('command', '-v', 'ls'));
        $process = $builder->getProcess();
        $process->run();

        $this->assertTrue($process->isSuccessful());
    }
}
PKϤ$ZS��{��"process/Tests/ProcessUtilsTest.phpnu�[���<?php

/*
 * This file is part of the Symfony package.
 *
 * (c) Fabien Potencier <fabien@symfony.com>
 *
 * For the full copyright and license information, please view the LICENSE
 * file that was distributed with this source code.
 */

namespace Symfony\Component\Process\Tests;

use PHPUnit\Framework\TestCase;
use Symfony\Component\Process\ProcessUtils;

/**
 * @group legacy
 */
class ProcessUtilsTest extends TestCase
{
    /**
     * @dataProvider dataArguments
     */
    public function testEscapeArgument($result, $argument)
    {
        $this->assertSame($result, ProcessUtils::escapeArgument($argument));
    }

    public function dataArguments()
    {
        if ('\\' === DIRECTORY_SEPARATOR) {
            return array(
                array('"\"php\" \"-v\""', '"php" "-v"'),
                array('"foo bar"', 'foo bar'),
                array('^%"path"^%', '%path%'),
                array('"<|>\\" \\"\'f"', '<|>" "\'f'),
                array('""', ''),
                array('"with\trailingbs\\\\"', 'with\trailingbs\\'),
            );
        }

        return array(
            array("'\"php\" \"-v\"'", '"php" "-v"'),
            array("'foo bar'", 'foo bar'),
            array("'%path%'", '%path%'),
            array("'<|>\" \"'\\''f'", '<|>" "\'f'),
            array("''", ''),
            array("'with\\trailingbs\\'", 'with\trailingbs\\'),
            array("'withNonAsciiAccentLikeéÉèÈàÀöä'", 'withNonAsciiAccentLikeéÉèÈàÀöä'),
        );
    }
}
PKϤ$Z��f�&process/Tests/ExecutableFinderTest.phpnu�[���<?php

/*
 * This file is part of the Symfony package.
 *
 * (c) Fabien Potencier <fabien@symfony.com>
 *
 * For the full copyright and license information, please view the LICENSE
 * file that was distributed with this source code.
 */

namespace Symfony\Component\Process\Tests;

use PHPUnit\Framework\TestCase;
use Symfony\Component\Process\ExecutableFinder;

/**
 * @author Chris Smith <chris@cs278.org>
 */
class ExecutableFinderTest extends TestCase
{
    private $path;

    protected function tearDown()
    {
        if ($this->path) {
            // Restore path if it was changed.
            putenv('PATH='.$this->path);
        }
    }

    private function setPath($path)
    {
        $this->path = getenv('PATH');
        putenv('PATH='.$path);
    }

    public function testFind()
    {
        if (ini_get('open_basedir')) {
            $this->markTestSkipped('Cannot test when open_basedir is set');
        }

        $this->setPath(dirname(PHP_BINARY));

        $finder = new ExecutableFinder();
        $result = $finder->find($this->getPhpBinaryName());

        $this->assertSamePath(PHP_BINARY, $result);
    }

    public function testFindWithDefault()
    {
        if (ini_get('open_basedir')) {
            $this->markTestSkipped('Cannot test when open_basedir is set');
        }

        $expected = 'defaultValue';

        $this->setPath('');

        $finder = new ExecutableFinder();
        $result = $finder->find('foo', $expected);

        $this->assertEquals($expected, $result);
    }

    public function testFindWithExtraDirs()
    {
        if (ini_get('open_basedir')) {
            $this->markTestSkipped('Cannot test when open_basedir is set');
        }

        $this->setPath('');

        $extraDirs = array(dirname(PHP_BINARY));

        $finder = new ExecutableFinder();
        $result = $finder->find($this->getPhpBinaryName(), null, $extraDirs);

        $this->assertSamePath(PHP_BINARY, $result);
    }

    public function testFindWithOpenBaseDir()
    {
        if ('\\' === DIRECTORY_SEPARATOR) {
            $this->markTestSkipped('Cannot run test on windows');
        }

        if (ini_get('open_basedir')) {
            $this->markTestSkipped('Cannot test when open_basedir is set');
        }

        $this->iniSet('open_basedir', dirname(PHP_BINARY).(!defined('HHVM_VERSION') || HHVM_VERSION_ID >= 30800 ? PATH_SEPARATOR.'/' : ''));

        $finder = new ExecutableFinder();
        $result = $finder->find($this->getPhpBinaryName());

        $this->assertSamePath(PHP_BINARY, $result);
    }

    public function testFindProcessInOpenBasedir()
    {
        if (ini_get('open_basedir')) {
            $this->markTestSkipped('Cannot test when open_basedir is set');
        }
        if ('\\' === DIRECTORY_SEPARATOR) {
            $this->markTestSkipped('Cannot run test on windows');
        }

        $this->setPath('');
        $this->iniSet('open_basedir', PHP_BINARY.(!defined('HHVM_VERSION') || HHVM_VERSION_ID >= 30800 ? PATH_SEPARATOR.'/' : ''));

        $finder = new ExecutableFinder();
        $result = $finder->find($this->getPhpBinaryName(), false);

        $this->assertSamePath(PHP_BINARY, $result);
    }

    private function assertSamePath($expected, $tested)
    {
        if ('\\' === DIRECTORY_SEPARATOR) {
            $this->assertEquals(strtolower($expected), strtolower($tested));
        } else {
            $this->assertEquals($expected, $tested);
        }
    }

    private function getPhpBinaryName()
    {
        return basename(PHP_BINARY, '\\' === DIRECTORY_SEPARATOR ? '.exe' : '');
    }
}
PKϤ$Z�"+<��process/Tests/ProcessTest.phpnu�[���<?php

/*
 * This file is part of the Symfony package.
 *
 * (c) Fabien Potencier <fabien@symfony.com>
 *
 * For the full copyright and license information, please view the LICENSE
 * file that was distributed with this source code.
 */

namespace Symfony\Component\Process\Tests;

use PHPUnit\Framework\TestCase;
use Symfony\Component\Process\Exception\LogicException;
use Symfony\Component\Process\Exception\ProcessTimedOutException;
use Symfony\Component\Process\Exception\RuntimeException;
use Symfony\Component\Process\InputStream;
use Symfony\Component\Process\PhpExecutableFinder;
use Symfony\Component\Process\Pipes\PipesInterface;
use Symfony\Component\Process\Process;

/**
 * @author Robert Schönthal <seroscho@googlemail.com>
 */
class ProcessTest extends TestCase
{
    private static $phpBin;
    private static $process;
    private static $sigchild;
    private static $notEnhancedSigchild = false;

    public static function setUpBeforeClass()
    {
        $phpBin = new PhpExecutableFinder();
        self::$phpBin = getenv('SYMFONY_PROCESS_PHP_TEST_BINARY') ?: ('phpdbg' === PHP_SAPI ? 'php' : $phpBin->find());

        ob_start();
        phpinfo(INFO_GENERAL);
        self::$sigchild = false !== strpos(ob_get_clean(), '--enable-sigchild');
    }

    protected function tearDown()
    {
        if (self::$process) {
            self::$process->stop(0);
            self::$process = null;
        }
    }

    public function testThatProcessDoesNotThrowWarningDuringRun()
    {
        if ('\\' === DIRECTORY_SEPARATOR) {
            $this->markTestSkipped('This test is transient on Windows');
        }
        @trigger_error('Test Error', E_USER_NOTICE);
        $process = $this->getProcessForCode('sleep(3)');
        $process->run();
        $actualError = error_get_last();
        $this->assertEquals('Test Error', $actualError['message']);
        $this->assertEquals(E_USER_NOTICE, $actualError['type']);
    }

    /**
     * @expectedException \Symfony\Component\Process\Exception\InvalidArgumentException
     */
    public function testNegativeTimeoutFromConstructor()
    {
        $this->getProcess('', null, null, null, -1);
    }

    /**
     * @expectedException \Symfony\Component\Process\Exception\InvalidArgumentException
     */
    public function testNegativeTimeoutFromSetter()
    {
        $p = $this->getProcess('');
        $p->setTimeout(-1);
    }

    public function testFloatAndNullTimeout()
    {
        $p = $this->getProcess('');

        $p->setTimeout(10);
        $this->assertSame(10.0, $p->getTimeout());

        $p->setTimeout(null);
        $this->assertNull($p->getTimeout());

        $p->setTimeout(0.0);
        $this->assertNull($p->getTimeout());
    }

    /**
     * @requires extension pcntl
     */
    public function testStopWithTimeoutIsActuallyWorking()
    {
        $p = $this->getProcess(array(self::$phpBin, __DIR__.'/NonStopableProcess.php', 30));
        $p->start();

        while (false === strpos($p->getOutput(), 'received')) {
            usleep(1000);
        }
        $start = microtime(true);
        $p->stop(0.1);

        $p->wait();

        $this->assertLessThan(15, microtime(true) - $start);
    }

    public function testAllOutputIsActuallyReadOnTermination()
    {
        // this code will result in a maximum of 2 reads of 8192 bytes by calling
        // start() and isRunning().  by the time getOutput() is called the process
        // has terminated so the internal pipes array is already empty. normally
        // the call to start() will not read any data as the process will not have
        // generated output, but this is non-deterministic so we must count it as
        // a possibility.  therefore we need 2 * PipesInterface::CHUNK_SIZE plus
        // another byte which will never be read.
        $expectedOutputSize = PipesInterface::CHUNK_SIZE * 2 + 2;

        $code = sprintf('echo str_repeat(\'*\', %d);', $expectedOutputSize);
        $p = $this->getProcessForCode($code);

        $p->start();

        // Don't call Process::run nor Process::wait to avoid any read of pipes
        $h = new \ReflectionProperty($p, 'process');
        $h->setAccessible(true);
        $h = $h->getValue($p);
        $s = @proc_get_status($h);

        while (!empty($s['running'])) {
            usleep(1000);
            $s = proc_get_status($h);
        }

        $o = $p->getOutput();

        $this->assertEquals($expectedOutputSize, strlen($o));
    }

    public function testCallbacksAreExecutedWithStart()
    {
        $process = $this->getProcess('echo foo');
        $process->start(function ($type, $buffer) use (&$data) {
            $data .= $buffer;
        });

        $process->wait();

        $this->assertSame('foo'.PHP_EOL, $data);
    }

    /**
     * tests results from sub processes.
     *
     * @dataProvider responsesCodeProvider
     */
    public function testProcessResponses($expected, $getter, $code)
    {
        $p = $this->getProcessForCode($code);
        $p->run();

        $this->assertSame($expected, $p->$getter());
    }

    /**
     * tests results from sub processes.
     *
     * @dataProvider pipesCodeProvider
     */
    public function testProcessPipes($code, $size)
    {
        $expected = str_repeat(str_repeat('*', 1024), $size).'!';
        $expectedLength = (1024 * $size) + 1;

        $p = $this->getProcessForCode($code);
        $p->setInput($expected);
        $p->run();

        $this->assertEquals($expectedLength, strlen($p->getOutput()));
        $this->assertEquals($expectedLength, strlen($p->getErrorOutput()));
    }

    /**
     * @dataProvider pipesCodeProvider
     */
    public function testSetStreamAsInput($code, $size)
    {
        $expected = str_repeat(str_repeat('*', 1024), $size).'!';
        $expectedLength = (1024 * $size) + 1;

        $stream = fopen('php://temporary', 'w+');
        fwrite($stream, $expected);
        rewind($stream);

        $p = $this->getProcessForCode($code);
        $p->setInput($stream);
        $p->run();

        fclose($stream);

        $this->assertEquals($expectedLength, strlen($p->getOutput()));
        $this->assertEquals($expectedLength, strlen($p->getErrorOutput()));
    }

    public function testLiveStreamAsInput()
    {
        $stream = fopen('php://memory', 'r+');
        fwrite($stream, 'hello');
        rewind($stream);

        $p = $this->getProcessForCode('stream_copy_to_stream(STDIN, STDOUT);');
        $p->setInput($stream);
        $p->start(function ($type, $data) use ($stream) {
            if ('hello' === $data) {
                fclose($stream);
            }
        });
        $p->wait();

        $this->assertSame('hello', $p->getOutput());
    }

    /**
     * @expectedException \Symfony\Component\Process\Exception\LogicException
     * @expectedExceptionMessage Input can not be set while the process is running.
     */
    public function testSetInputWhileRunningThrowsAnException()
    {
        $process = $this->getProcessForCode('sleep(30);');
        $process->start();
        try {
            $process->setInput('foobar');
            $process->stop();
            $this->fail('A LogicException should have been raised.');
        } catch (LogicException $e) {
        }
        $process->stop();

        throw $e;
    }

    /**
     * @dataProvider provideInvalidInputValues
     * @expectedException \Symfony\Component\Process\Exception\InvalidArgumentException
     * @expectedExceptionMessage Symfony\Component\Process\Process::setInput only accepts strings, Traversable objects or stream resources.
     */
    public function testInvalidInput($value)
    {
        $process = $this->getProcess('foo');
        $process->setInput($value);
    }

    public function provideInvalidInputValues()
    {
        return array(
            array(array()),
            array(new NonStringifiable()),
        );
    }

    /**
     * @dataProvider provideInputValues
     */
    public function testValidInput($expected, $value)
    {
        $process = $this->getProcess('foo');
        $process->setInput($value);
        $this->assertSame($expected, $process->getInput());
    }

    public function provideInputValues()
    {
        return array(
            array(null, null),
            array('24.5', 24.5),
            array('input data', 'input data'),
        );
    }

    public function chainedCommandsOutputProvider()
    {
        if ('\\' === DIRECTORY_SEPARATOR) {
            return array(
                array("2 \r\n2\r\n", '&&', '2'),
            );
        }

        return array(
            array("1\n1\n", ';', '1'),
            array("2\n2\n", '&&', '2'),
        );
    }

    /**
     * @dataProvider chainedCommandsOutputProvider
     */
    public function testChainedCommandsOutput($expected, $operator, $input)
    {
        $process = $this->getProcess(sprintf('echo %s %s echo %s', $input, $operator, $input));
        $process->run();
        $this->assertEquals($expected, $process->getOutput());
    }

    public function testCallbackIsExecutedForOutput()
    {
        $p = $this->getProcessForCode('echo \'foo\';');

        $called = false;
        $p->run(function ($type, $buffer) use (&$called) {
            $called = $buffer === 'foo';
        });

        $this->assertTrue($called, 'The callback should be executed with the output');
    }

    public function testCallbackIsExecutedForOutputWheneverOutputIsDisabled()
    {
        $p = $this->getProcessForCode('echo \'foo\';');
        $p->disableOutput();

        $called = false;
        $p->run(function ($type, $buffer) use (&$called) {
            $called = $buffer === 'foo';
        });

        $this->assertTrue($called, 'The callback should be executed with the output');
    }

    public function testGetErrorOutput()
    {
        $p = $this->getProcessForCode('$n = 0; while ($n < 3) { file_put_contents(\'php://stderr\', \'ERROR\'); $n++; }');

        $p->run();
        $this->assertEquals(3, preg_match_all('/ERROR/', $p->getErrorOutput(), $matches));
    }

    public function testFlushErrorOutput()
    {
        $p = $this->getProcessForCode('$n = 0; while ($n < 3) { file_put_contents(\'php://stderr\', \'ERROR\'); $n++; }');

        $p->run();
        $p->clearErrorOutput();
        $this->assertEmpty($p->getErrorOutput());
    }

    /**
     * @dataProvider provideIncrementalOutput
     */
    public function testIncrementalOutput($getOutput, $getIncrementalOutput, $uri)
    {
        $lock = tempnam(sys_get_temp_dir(), __FUNCTION__);

        $p = $this->getProcessForCode('file_put_contents($s = \''.$uri.'\', \'foo\'); flock(fopen('.var_export($lock, true).', \'r\'), LOCK_EX); file_put_contents($s, \'bar\');');

        $h = fopen($lock, 'w');
        flock($h, LOCK_EX);

        $p->start();

        foreach (array('foo', 'bar') as $s) {
            while (false === strpos($p->$getOutput(), $s)) {
                usleep(1000);
            }

            $this->assertSame($s, $p->$getIncrementalOutput());
            $this->assertSame('', $p->$getIncrementalOutput());

            flock($h, LOCK_UN);
        }

        fclose($h);
    }

    public function provideIncrementalOutput()
    {
        return array(
            array('getOutput', 'getIncrementalOutput', 'php://stdout'),
            array('getErrorOutput', 'getIncrementalErrorOutput', 'php://stderr'),
        );
    }

    public function testGetOutput()
    {
        $p = $this->getProcessForCode('$n = 0; while ($n < 3) { echo \' foo \'; $n++; }');

        $p->run();
        $this->assertEquals(3, preg_match_all('/foo/', $p->getOutput(), $matches));
    }

    public function testFlushOutput()
    {
        $p = $this->getProcessForCode('$n=0;while ($n<3) {echo \' foo \';$n++;}');

        $p->run();
        $p->clearOutput();
        $this->assertEmpty($p->getOutput());
    }

    public function testZeroAsOutput()
    {
        if ('\\' === DIRECTORY_SEPARATOR) {
            // see http://stackoverflow.com/questions/7105433/windows-batch-echo-without-new-line
            $p = $this->getProcess('echo | set /p dummyName=0');
        } else {
            $p = $this->getProcess('printf 0');
        }

        $p->run();
        $this->assertSame('0', $p->getOutput());
    }

    public function testExitCodeCommandFailed()
    {
        if ('\\' === DIRECTORY_SEPARATOR) {
            $this->markTestSkipped('Windows does not support POSIX exit code');
        }
        $this->skipIfNotEnhancedSigchild();

        // such command run in bash return an exitcode 127
        $process = $this->getProcess('nonexistingcommandIhopeneversomeonewouldnameacommandlikethis');
        $process->run();

        $this->assertGreaterThan(0, $process->getExitCode());
    }

    /**
     * @group tty
     */
    public function testTTYCommand()
    {
        if ('\\' === DIRECTORY_SEPARATOR) {
            $this->markTestSkipped('Windows does not have /dev/tty support');
        }

        $process = $this->getProcess('echo "foo" >> /dev/null && '.$this->getProcessForCode('usleep(100000);')->getCommandLine());
        $process->setTty(true);
        $process->start();
        $this->assertTrue($process->isRunning());
        $process->wait();

        $this->assertSame(Process::STATUS_TERMINATED, $process->getStatus());
    }

    /**
     * @group tty
     */
    public function testTTYCommandExitCode()
    {
        if ('\\' === DIRECTORY_SEPARATOR) {
            $this->markTestSkipped('Windows does have /dev/tty support');
        }
        $this->skipIfNotEnhancedSigchild();

        $process = $this->getProcess('echo "foo" >> /dev/null');
        $process->setTty(true);
        $process->run();

        $this->assertTrue($process->isSuccessful());
    }

    /**
     * @expectedException \Symfony\Component\Process\Exception\RuntimeException
     * @expectedExceptionMessage TTY mode is not supported on Windows platform.
     */
    public function testTTYInWindowsEnvironment()
    {
        if ('\\' !== DIRECTORY_SEPARATOR) {
            $this->markTestSkipped('This test is for Windows platform only');
        }

        $process = $this->getProcess('echo "foo" >> /dev/null');
        $process->setTty(false);
        $process->setTty(true);
    }

    public function testExitCodeTextIsNullWhenExitCodeIsNull()
    {
        $this->skipIfNotEnhancedSigchild();

        $process = $this->getProcess('');
        $this->assertNull($process->getExitCodeText());
    }

    public function testPTYCommand()
    {
        if (!Process::isPtySupported()) {
            $this->markTestSkipped('PTY is not supported on this operating system.');
        }

        $process = $this->getProcess('echo "foo"');
        $process->setPty(true);
        $process->run();

        $this->assertSame(Process::STATUS_TERMINATED, $process->getStatus());
        $this->assertEquals("foo\r\n", $process->getOutput());
    }

    public function testMustRun()
    {
        $this->skipIfNotEnhancedSigchild();

        $process = $this->getProcess('echo foo');

        $this->assertSame($process, $process->mustRun());
        $this->assertEquals('foo'.PHP_EOL, $process->getOutput());
    }

    public function testSuccessfulMustRunHasCorrectExitCode()
    {
        $this->skipIfNotEnhancedSigchild();

        $process = $this->getProcess('echo foo')->mustRun();
        $this->assertEquals(0, $process->getExitCode());
    }

    /**
     * @expectedException \Symfony\Component\Process\Exception\ProcessFailedException
     */
    public function testMustRunThrowsException()
    {
        $this->skipIfNotEnhancedSigchild();

        $process = $this->getProcess('exit 1');
        $process->mustRun();
    }

    public function testExitCodeText()
    {
        $this->skipIfNotEnhancedSigchild();

        $process = $this->getProcess('');
        $r = new \ReflectionObject($process);
        $p = $r->getProperty('exitcode');
        $p->setAccessible(true);

        $p->setValue($process, 2);
        $this->assertEquals('Misuse of shell builtins', $process->getExitCodeText());
    }

    public function testStartIsNonBlocking()
    {
        $process = $this->getProcessForCode('usleep(500000);');
        $start = microtime(true);
        $process->start();
        $end = microtime(true);
        $this->assertLessThan(0.4, $end - $start);
        $process->stop();
    }

    public function testUpdateStatus()
    {
        $process = $this->getProcess('echo foo');
        $process->run();
        $this->assertTrue(strlen($process->getOutput()) > 0);
    }

    public function testGetExitCodeIsNullOnStart()
    {
        $this->skipIfNotEnhancedSigchild();

        $process = $this->getProcessForCode('usleep(100000);');
        $this->assertNull($process->getExitCode());
        $process->start();
        $this->assertNull($process->getExitCode());
        $process->wait();
        $this->assertEquals(0, $process->getExitCode());
    }

    public function testGetExitCodeIsNullOnWhenStartingAgain()
    {
        $this->skipIfNotEnhancedSigchild();

        $process = $this->getProcessForCode('usleep(100000);');
        $process->run();
        $this->assertEquals(0, $process->getExitCode());
        $process->start();
        $this->assertNull($process->getExitCode());
        $process->wait();
        $this->assertEquals(0, $process->getExitCode());
    }

    public function testGetExitCode()
    {
        $this->skipIfNotEnhancedSigchild();

        $process = $this->getProcess('echo foo');
        $process->run();
        $this->assertSame(0, $process->getExitCode());
    }

    public function testStatus()
    {
        $process = $this->getProcessForCode('usleep(100000);');
        $this->assertFalse($process->isRunning());
        $this->assertFalse($process->isStarted());
        $this->assertFalse($process->isTerminated());
        $this->assertSame(Process::STATUS_READY, $process->getStatus());
        $process->start();
        $this->assertTrue($process->isRunning());
        $this->assertTrue($process->isStarted());
        $this->assertFalse($process->isTerminated());
        $this->assertSame(Process::STATUS_STARTED, $process->getStatus());
        $process->wait();
        $this->assertFalse($process->isRunning());
        $this->assertTrue($process->isStarted());
        $this->assertTrue($process->isTerminated());
        $this->assertSame(Process::STATUS_TERMINATED, $process->getStatus());
    }

    public function testStop()
    {
        $process = $this->getProcessForCode('sleep(31);');
        $process->start();
        $this->assertTrue($process->isRunning());
        $process->stop();
        $this->assertFalse($process->isRunning());
    }

    public function testIsSuccessful()
    {
        $this->skipIfNotEnhancedSigchild();

        $process = $this->getProcess('echo foo');
        $process->run();
        $this->assertTrue($process->isSuccessful());
    }

    public function testIsSuccessfulOnlyAfterTerminated()
    {
        $this->skipIfNotEnhancedSigchild();

        $process = $this->getProcessForCode('usleep(100000);');
        $process->start();

        $this->assertFalse($process->isSuccessful());

        $process->wait();

        $this->assertTrue($process->isSuccessful());
    }

    public function testIsNotSuccessful()
    {
        $this->skipIfNotEnhancedSigchild();

        $process = $this->getProcessForCode('throw new \Exception(\'BOUM\');');
        $process->run();
        $this->assertFalse($process->isSuccessful());
    }

    public function testProcessIsNotSignaled()
    {
        if ('\\' === DIRECTORY_SEPARATOR) {
            $this->markTestSkipped('Windows does not support POSIX signals');
        }
        $this->skipIfNotEnhancedSigchild();

        $process = $this->getProcess('echo foo');
        $process->run();
        $this->assertFalse($process->hasBeenSignaled());
    }

    public function testProcessWithoutTermSignal()
    {
        if ('\\' === DIRECTORY_SEPARATOR) {
            $this->markTestSkipped('Windows does not support POSIX signals');
        }
        $this->skipIfNotEnhancedSigchild();

        $process = $this->getProcess('echo foo');
        $process->run();
        $this->assertEquals(0, $process->getTermSignal());
    }

    public function testProcessIsSignaledIfStopped()
    {
        if ('\\' === DIRECTORY_SEPARATOR) {
            $this->markTestSkipped('Windows does not support POSIX signals');
        }
        $this->skipIfNotEnhancedSigchild();

        $process = $this->getProcessForCode('sleep(32);');
        $process->start();
        $process->stop();
        $this->assertTrue($process->hasBeenSignaled());
        $this->assertEquals(15, $process->getTermSignal()); // SIGTERM
    }

    /**
     * @expectedException \Symfony\Component\Process\Exception\RuntimeException
     * @expectedExceptionMessage The process has been signaled
     */
    public function testProcessThrowsExceptionWhenExternallySignaled()
    {
        if (!function_exists('posix_kill')) {
            $this->markTestSkipped('Function posix_kill is required.');
        }
        $this->skipIfNotEnhancedSigchild(false);

        $process = $this->getProcessForCode('sleep(32.1);');
        $process->start();
        posix_kill($process->getPid(), 9); // SIGKILL

        $process->wait();
    }

    public function testRestart()
    {
        $process1 = $this->getProcessForCode('echo getmypid();');
        $process1->run();
        $process2 = $process1->restart();

        $process2->wait(); // wait for output

        // Ensure that both processed finished and the output is numeric
        $this->assertFalse($process1->isRunning());
        $this->assertFalse($process2->isRunning());
        $this->assertInternalType('numeric', $process1->getOutput());
        $this->assertInternalType('numeric', $process2->getOutput());

        // Ensure that restart returned a new process by check that the output is different
        $this->assertNotEquals($process1->getOutput(), $process2->getOutput());
    }

    /**
     * @expectedException \Symfony\Component\Process\Exception\ProcessTimedOutException
     * @expectedExceptionMessage exceeded the timeout of 0.1 seconds.
     */
    public function testRunProcessWithTimeout()
    {
        $process = $this->getProcessForCode('sleep(30);');
        $process->setTimeout(0.1);
        $start = microtime(true);
        try {
            $process->run();
            $this->fail('A RuntimeException should have been raised');
        } catch (RuntimeException $e) {
        }

        $this->assertLessThan(15, microtime(true) - $start);

        throw $e;
    }

    /**
     * @expectedException \Symfony\Component\Process\Exception\ProcessTimedOutException
     * @expectedExceptionMessage exceeded the timeout of 0.1 seconds.
     */
    public function testIterateOverProcessWithTimeout()
    {
        $process = $this->getProcessForCode('sleep(30);');
        $process->setTimeout(0.1);
        $start = microtime(true);
        try {
            $process->start();
            foreach ($process as $buffer);
            $this->fail('A RuntimeException should have been raised');
        } catch (RuntimeException $e) {
        }

        $this->assertLessThan(15, microtime(true) - $start);

        throw $e;
    }

    public function testCheckTimeoutOnNonStartedProcess()
    {
        $process = $this->getProcess('echo foo');
        $this->assertNull($process->checkTimeout());
    }

    public function testCheckTimeoutOnTerminatedProcess()
    {
        $process = $this->getProcess('echo foo');
        $process->run();
        $this->assertNull($process->checkTimeout());
    }

    /**
     * @expectedException \Symfony\Component\Process\Exception\ProcessTimedOutException
     * @expectedExceptionMessage exceeded the timeout of 0.1 seconds.
     */
    public function testCheckTimeoutOnStartedProcess()
    {
        $process = $this->getProcessForCode('sleep(33);');
        $process->setTimeout(0.1);

        $process->start();
        $start = microtime(true);

        try {
            while ($process->isRunning()) {
                $process->checkTimeout();
                usleep(100000);
            }
            $this->fail('A ProcessTimedOutException should have been raised');
        } catch (ProcessTimedOutException $e) {
        }

        $this->assertLessThan(15, microtime(true) - $start);

        throw $e;
    }

    public function testIdleTimeout()
    {
        $process = $this->getProcessForCode('sleep(34);');
        $process->setTimeout(60);
        $process->setIdleTimeout(0.1);

        try {
            $process->run();

            $this->fail('A timeout exception was expected.');
        } catch (ProcessTimedOutException $e) {
            $this->assertTrue($e->isIdleTimeout());
            $this->assertFalse($e->isGeneralTimeout());
            $this->assertEquals(0.1, $e->getExceededTimeout());
        }
    }

    public function testIdleTimeoutNotExceededWhenOutputIsSent()
    {
        $process = $this->getProcessForCode('while (true) {echo \'foo \'; usleep(1000);}');
        $process->setTimeout(1);
        $process->start();

        while (false === strpos($process->getOutput(), 'foo')) {
            usleep(1000);
        }

        $process->setIdleTimeout(0.5);

        try {
            $process->wait();
            $this->fail('A timeout exception was expected.');
        } catch (ProcessTimedOutException $e) {
            $this->assertTrue($e->isGeneralTimeout(), 'A general timeout is expected.');
            $this->assertFalse($e->isIdleTimeout(), 'No idle timeout is expected.');
            $this->assertEquals(1, $e->getExceededTimeout());
        }
    }

    /**
     * @expectedException \Symfony\Component\Process\Exception\ProcessTimedOutException
     * @expectedExceptionMessage exceeded the timeout of 0.1 seconds.
     */
    public function testStartAfterATimeout()
    {
        $process = $this->getProcessForCode('sleep(35);');
        $process->setTimeout(0.1);

        try {
            $process->run();
            $this->fail('A ProcessTimedOutException should have been raised.');
        } catch (ProcessTimedOutException $e) {
        }
        $this->assertFalse($process->isRunning());
        $process->start();
        $this->assertTrue($process->isRunning());
        $process->stop(0);

        throw $e;
    }

    public function testGetPid()
    {
        $process = $this->getProcessForCode('sleep(36);');
        $process->start();
        $this->assertGreaterThan(0, $process->getPid());
        $process->stop(0);
    }

    public function testGetPidIsNullBeforeStart()
    {
        $process = $this->getProcess('foo');
        $this->assertNull($process->getPid());
    }

    public function testGetPidIsNullAfterRun()
    {
        $process = $this->getProcess('echo foo');
        $process->run();
        $this->assertNull($process->getPid());
    }

    /**
     * @requires extension pcntl
     */
    public function testSignal()
    {
        $process = $this->getProcess(array(self::$phpBin, __DIR__.'/SignalListener.php'));
        $process->start();

        while (false === strpos($process->getOutput(), 'Caught')) {
            usleep(1000);
        }
        $process->signal(SIGUSR1);
        $process->wait();

        $this->assertEquals('Caught SIGUSR1', $process->getOutput());
    }

    /**
     * @requires extension pcntl
     */
    public function testExitCodeIsAvailableAfterSignal()
    {
        $this->skipIfNotEnhancedSigchild();

        $process = $this->getProcess('sleep 4');
        $process->start();
        $process->signal(SIGKILL);

        while ($process->isRunning()) {
            usleep(10000);
        }

        $this->assertFalse($process->isRunning());
        $this->assertTrue($process->hasBeenSignaled());
        $this->assertFalse($process->isSuccessful());
        $this->assertEquals(137, $process->getExitCode());
    }

    /**
     * @expectedException \Symfony\Component\Process\Exception\LogicException
     * @expectedExceptionMessage Can not send signal on a non running process.
     */
    public function testSignalProcessNotRunning()
    {
        $process = $this->getProcess('foo');
        $process->signal(1); // SIGHUP
    }

    /**
     * @dataProvider provideMethodsThatNeedARunningProcess
     */
    public function testMethodsThatNeedARunningProcess($method)
    {
        $process = $this->getProcess('foo');

        if (method_exists($this, 'expectException')) {
            $this->expectException('Symfony\Component\Process\Exception\LogicException');
            $this->expectExceptionMessage(sprintf('Process must be started before calling %s.', $method));
        } else {
            $this->setExpectedException('Symfony\Component\Process\Exception\LogicException', sprintf('Process must be started before calling %s.', $method));
        }

        $process->{$method}();
    }

    public function provideMethodsThatNeedARunningProcess()
    {
        return array(
            array('getOutput'),
            array('getIncrementalOutput'),
            array('getErrorOutput'),
            array('getIncrementalErrorOutput'),
            array('wait'),
        );
    }

    /**
     * @dataProvider provideMethodsThatNeedATerminatedProcess
     * @expectedException \Symfony\Component\Process\Exception\LogicException
     * @expectedExceptionMessage Process must be terminated before calling
     */
    public function testMethodsThatNeedATerminatedProcess($method)
    {
        $process = $this->getProcessForCode('sleep(37);');
        $process->start();
        try {
            $process->{$method}();
            $process->stop(0);
            $this->fail('A LogicException must have been thrown');
        } catch (\Exception $e) {
        }
        $process->stop(0);

        throw $e;
    }

    public function provideMethodsThatNeedATerminatedProcess()
    {
        return array(
            array('hasBeenSignaled'),
            array('getTermSignal'),
            array('hasBeenStopped'),
            array('getStopSignal'),
        );
    }

    /**
     * @dataProvider provideWrongSignal
     * @expectedException \Symfony\Component\Process\Exception\RuntimeException
     */
    public function testWrongSignal($signal)
    {
        if ('\\' === DIRECTORY_SEPARATOR) {
            $this->markTestSkipped('POSIX signals do not work on Windows');
        }

        $process = $this->getProcessForCode('sleep(38);');
        $process->start();
        try {
            $process->signal($signal);
            $this->fail('A RuntimeException must have been thrown');
        } catch (RuntimeException $e) {
            $process->stop(0);
        }

        throw $e;
    }

    public function provideWrongSignal()
    {
        return array(
            array(-4),
            array('Céphalopodes'),
        );
    }

    public function testDisableOutputDisablesTheOutput()
    {
        $p = $this->getProcess('foo');
        $this->assertFalse($p->isOutputDisabled());
        $p->disableOutput();
        $this->assertTrue($p->isOutputDisabled());
        $p->enableOutput();
        $this->assertFalse($p->isOutputDisabled());
    }

    /**
     * @expectedException \Symfony\Component\Process\Exception\RuntimeException
     * @expectedExceptionMessage Disabling output while the process is running is not possible.
     */
    public function testDisableOutputWhileRunningThrowsException()
    {
        $p = $this->getProcessForCode('sleep(39);');
        $p->start();
        $p->disableOutput();
    }

    /**
     * @expectedException \Symfony\Component\Process\Exception\RuntimeException
     * @expectedExceptionMessage Enabling output while the process is running is not possible.
     */
    public function testEnableOutputWhileRunningThrowsException()
    {
        $p = $this->getProcessForCode('sleep(40);');
        $p->disableOutput();
        $p->start();
        $p->enableOutput();
    }

    public function testEnableOrDisableOutputAfterRunDoesNotThrowException()
    {
        $p = $this->getProcess('echo foo');
        $p->disableOutput();
        $p->run();
        $p->enableOutput();
        $p->disableOutput();
        $this->assertTrue($p->isOutputDisabled());
    }

    /**
     * @expectedException \Symfony\Component\Process\Exception\LogicException
     * @expectedExceptionMessage Output can not be disabled while an idle timeout is set.
     */
    public function testDisableOutputWhileIdleTimeoutIsSet()
    {
        $process = $this->getProcess('foo');
        $process->setIdleTimeout(1);
        $process->disableOutput();
    }

    /**
     * @expectedException \Symfony\Component\Process\Exception\LogicException
     * @expectedExceptionMessage timeout can not be set while the output is disabled.
     */
    public function testSetIdleTimeoutWhileOutputIsDisabled()
    {
        $process = $this->getProcess('foo');
        $process->disableOutput();
        $process->setIdleTimeout(1);
    }

    public function testSetNullIdleTimeoutWhileOutputIsDisabled()
    {
        $process = $this->getProcess('foo');
        $process->disableOutput();
        $this->assertSame($process, $process->setIdleTimeout(null));
    }

    /**
     * @dataProvider provideOutputFetchingMethods
     * @expectedException \Symfony\Component\Process\Exception\LogicException
     * @expectedExceptionMessage Output has been disabled.
     */
    public function testGetOutputWhileDisabled($fetchMethod)
    {
        $p = $this->getProcessForCode('sleep(41);');
        $p->disableOutput();
        $p->start();
        $p->{$fetchMethod}();
    }

    public function provideOutputFetchingMethods()
    {
        return array(
            array('getOutput'),
            array('getIncrementalOutput'),
            array('getErrorOutput'),
            array('getIncrementalErrorOutput'),
        );
    }

    public function testStopTerminatesProcessCleanly()
    {
        $process = $this->getProcessForCode('echo 123; sleep(42);');
        $process->run(function () use ($process) {
            $process->stop();
        });
        $this->assertTrue(true, 'A call to stop() is not expected to cause wait() to throw a RuntimeException');
    }

    public function testKillSignalTerminatesProcessCleanly()
    {
        $process = $this->getProcessForCode('echo 123; sleep(43);');
        $process->run(function () use ($process) {
            $process->signal(9); // SIGKILL
        });
        $this->assertTrue(true, 'A call to signal() is not expected to cause wait() to throw a RuntimeException');
    }

    public function testTermSignalTerminatesProcessCleanly()
    {
        $process = $this->getProcessForCode('echo 123; sleep(44);');
        $process->run(function () use ($process) {
            $process->signal(15); // SIGTERM
        });
        $this->assertTrue(true, 'A call to signal() is not expected to cause wait() to throw a RuntimeException');
    }

    public function responsesCodeProvider()
    {
        return array(
            //expected output / getter / code to execute
            //array(1,'getExitCode','exit(1);'),
            //array(true,'isSuccessful','exit();'),
            array('output', 'getOutput', 'echo \'output\';'),
        );
    }

    public function pipesCodeProvider()
    {
        $variations = array(
            'fwrite(STDOUT, $in = file_get_contents(\'php://stdin\')); fwrite(STDERR, $in);',
            'include \''.__DIR__.'/PipeStdinInStdoutStdErrStreamSelect.php\';',
        );

        if ('\\' === DIRECTORY_SEPARATOR) {
            // Avoid XL buffers on Windows because of https://bugs.php.net/bug.php?id=65650
            $sizes = array(1, 2, 4, 8);
        } else {
            $sizes = array(1, 16, 64, 1024, 4096);
        }

        $codes = array();
        foreach ($sizes as $size) {
            foreach ($variations as $code) {
                $codes[] = array($code, $size);
            }
        }

        return $codes;
    }

    /**
     * @dataProvider provideVariousIncrementals
     */
    public function testIncrementalOutputDoesNotRequireAnotherCall($stream, $method)
    {
        $process = $this->getProcessForCode('$n = 0; while ($n < 3) { file_put_contents(\''.$stream.'\', $n, 1); $n++; usleep(1000); }', null, null, null, null);
        $process->start();
        $result = '';
        $limit = microtime(true) + 3;
        $expected = '012';

        while ($result !== $expected && microtime(true) < $limit) {
            $result .= $process->$method();
        }

        $this->assertSame($expected, $result);
        $process->stop();
    }

    public function provideVariousIncrementals()
    {
        return array(
            array('php://stdout', 'getIncrementalOutput'),
            array('php://stderr', 'getIncrementalErrorOutput'),
        );
    }

    public function testIteratorInput()
    {
        $input = function () {
            yield 'ping';
            yield 'pong';
        };

        $process = $this->getProcessForCode('stream_copy_to_stream(STDIN, STDOUT);', null, null, $input());
        $process->run();
        $this->assertSame('pingpong', $process->getOutput());
    }

    public function testSimpleInputStream()
    {
        $input = new InputStream();

        $process = $this->getProcessForCode('echo \'ping\'; stream_copy_to_stream(STDIN, STDOUT);');
        $process->setInput($input);

        $process->start(function ($type, $data) use ($input) {
            if ('ping' === $data) {
                $input->write('pang');
            } elseif (!$input->isClosed()) {
                $input->write('pong');
                $input->close();
            }
        });

        $process->wait();
        $this->assertSame('pingpangpong', $process->getOutput());
    }

    public function testInputStreamWithCallable()
    {
        $i = 0;
        $stream = fopen('php://memory', 'w+');
        $stream = function () use ($stream, &$i) {
            if ($i < 3) {
                rewind($stream);
                fwrite($stream, ++$i);
                rewind($stream);

                return $stream;
            }
        };

        $input = new InputStream();
        $input->onEmpty($stream);
        $input->write($stream());

        $process = $this->getProcessForCode('echo fread(STDIN, 3);');
        $process->setInput($input);
        $process->start(function ($type, $data) use ($input) {
            $input->close();
        });

        $process->wait();
        $this->assertSame('123', $process->getOutput());
    }

    public function testInputStreamWithGenerator()
    {
        $input = new InputStream();
        $input->onEmpty(function ($input) {
            yield 'pong';
            $input->close();
        });

        $process = $this->getProcessForCode('stream_copy_to_stream(STDIN, STDOUT);');
        $process->setInput($input);
        $process->start();
        $input->write('ping');
        $process->wait();
        $this->assertSame('pingpong', $process->getOutput());
    }

    public function testInputStreamOnEmpty()
    {
        $i = 0;
        $input = new InputStream();
        $input->onEmpty(function () use (&$i) { ++$i; });

        $process = $this->getProcessForCode('echo 123; echo fread(STDIN, 1); echo 456;');
        $process->setInput($input);
        $process->start(function ($type, $data) use ($input) {
            if ('123' === $data) {
                $input->close();
            }
        });
        $process->wait();

        $this->assertSame(0, $i, 'InputStream->onEmpty callback should be called only when the input *becomes* empty');
        $this->assertSame('123456', $process->getOutput());
    }

    public function testIteratorOutput()
    {
        $input = new InputStream();

        $process = $this->getProcessForCode('fwrite(STDOUT, 123); fwrite(STDERR, 234); flush(); usleep(10000); fwrite(STDOUT, fread(STDIN, 3)); fwrite(STDERR, 456);');
        $process->setInput($input);
        $process->start();
        $output = array();

        foreach ($process as $type => $data) {
            $output[] = array($type, $data);
            break;
        }
        $expectedOutput = array(
            array($process::OUT, '123'),
        );
        $this->assertSame($expectedOutput, $output);

        $input->write(345);

        foreach ($process as $type => $data) {
            $output[] = array($type, $data);
        }

        $this->assertSame('', $process->getOutput());
        $this->assertFalse($process->isRunning());

        $expectedOutput = array(
            array($process::OUT, '123'),
            array($process::ERR, '234'),
            array($process::OUT, '345'),
            array($process::ERR, '456'),
        );
        $this->assertSame($expectedOutput, $output);
    }

    public function testNonBlockingNorClearingIteratorOutput()
    {
        $input = new InputStream();

        $process = $this->getProcessForCode('fwrite(STDOUT, fread(STDIN, 3));');
        $process->setInput($input);
        $process->start();
        $output = array();

        foreach ($process->getIterator($process::ITER_NON_BLOCKING | $process::ITER_KEEP_OUTPUT) as $type => $data) {
            $output[] = array($type, $data);
            break;
        }
        $expectedOutput = array(
            array($process::OUT, ''),
        );
        $this->assertSame($expectedOutput, $output);

        $input->write(123);

        foreach ($process->getIterator($process::ITER_NON_BLOCKING | $process::ITER_KEEP_OUTPUT) as $type => $data) {
            if ('' !== $data) {
                $output[] = array($type, $data);
            }
        }

        $this->assertSame('123', $process->getOutput());
        $this->assertFalse($process->isRunning());

        $expectedOutput = array(
            array($process::OUT, ''),
            array($process::OUT, '123'),
        );
        $this->assertSame($expectedOutput, $output);
    }

    public function testChainedProcesses()
    {
        $p1 = $this->getProcessForCode('fwrite(STDERR, 123); fwrite(STDOUT, 456);');
        $p2 = $this->getProcessForCode('stream_copy_to_stream(STDIN, STDOUT);');
        $p2->setInput($p1);

        $p1->start();
        $p2->run();

        $this->assertSame('123', $p1->getErrorOutput());
        $this->assertSame('', $p1->getOutput());
        $this->assertSame('', $p2->getErrorOutput());
        $this->assertSame('456', $p2->getOutput());
    }

    public function testSetBadEnv()
    {
        $process = $this->getProcess('echo hello');
        $process->setEnv(array('bad%%' => '123'));
        $process->inheritEnvironmentVariables(true);

        $process->run();

        $this->assertSame('hello'.PHP_EOL, $process->getOutput());
        $this->assertSame('', $process->getErrorOutput());
    }

    public function testEnvBackupDoesNotDeleteExistingVars()
    {
        putenv('existing_var=foo');
        $process = $this->getProcess('php -r "echo getenv(\'new_test_var\');"');
        $process->setEnv(array('existing_var' => 'bar', 'new_test_var' => 'foo'));
        $process->inheritEnvironmentVariables();

        $process->run();

        $this->assertSame('foo', $process->getOutput());
        $this->assertSame('foo', getenv('existing_var'));
        $this->assertFalse(getenv('new_test_var'));
    }

    public function testEnvIsInherited()
    {
        $process = $this->getProcessForCode('echo serialize($_SERVER);', null, array('BAR' => 'BAZ'));

        putenv('FOO=BAR');

        $process->run();

        $expected = array('BAR' => 'BAZ', 'FOO' => 'BAR');
        $env = array_intersect_key(unserialize($process->getOutput()), $expected);

        $this->assertEquals($expected, $env);
    }

    /**
     * @group legacy
     */
    public function testInheritEnvDisabled()
    {
        $process = $this->getProcessForCode('echo serialize($_SERVER);', null, array('BAR' => 'BAZ'));

        putenv('FOO=BAR');

        $this->assertSame($process, $process->inheritEnvironmentVariables(false));
        $this->assertFalse($process->areEnvironmentVariablesInherited());

        $process->run();

        $expected = array('BAR' => 'BAZ', 'FOO' => 'BAR');
        $env = array_intersect_key(unserialize($process->getOutput()), $expected);
        unset($expected['FOO']);

        $this->assertSame($expected, $env);
    }

    public function testGetCommandLine()
    {
        $p = new Process(array('/usr/bin/php'));

        $expected = '\\' === DIRECTORY_SEPARATOR ? '"/usr/bin/php"' : "'/usr/bin/php'";
        $this->assertSame($expected, $p->getCommandLine());
    }

    /**
     * @dataProvider provideEscapeArgument
     */
    public function testEscapeArgument($arg)
    {
        $p = new Process(array(self::$phpBin, '-r', 'echo $argv[1];', $arg));
        $p->run();

        $this->assertSame($arg, $p->getOutput());
    }

    /**
     * @dataProvider provideEscapeArgument
     * @group legacy
     */
    public function testEscapeArgumentWhenInheritEnvDisabled($arg)
    {
        $p = new Process(array(self::$phpBin, '-r', 'echo $argv[1];', $arg), null, array('BAR' => 'BAZ'));
        $p->inheritEnvironmentVariables(false);
        $p->run();

        $this->assertSame($arg, $p->getOutput());
    }

    public function testRawCommandLine()
    {
        $p = new Process(sprintf('"%s" -r %s "a" "" "b"', self::$phpBin, escapeshellarg('print_r($argv);')));
        $p->run();

        $expected = <<<EOTXT
Array
(
    [0] => -
    [1] => a
    [2] => 
    [3] => b
)

EOTXT;
        $this->assertSame($expected, $p->getOutput());
    }

    public function provideEscapeArgument()
    {
        yield array('a"b%c%');
        yield array('a"b^c^');
        yield array("a\nb'c");
        yield array('a^b c!');
        yield array("a!b\tc");
        yield array('a\\\\"\\"');
        yield array('éÉèÈàÀöä');
    }

    public function testEnvArgument()
    {
        $env = array('FOO' => 'Foo', 'BAR' => 'Bar');
        $cmd = '\\' === DIRECTORY_SEPARATOR ? 'echo !FOO! !BAR! !BAZ!' : 'echo $FOO $BAR $BAZ';
        $p = new Process($cmd, null, $env);
        $p->run(null, array('BAR' => 'baR', 'BAZ' => 'baZ'));

        $this->assertSame('Foo baR baZ', rtrim($p->getOutput()));
        $this->assertSame($env, $p->getEnv());
    }

    /**
     * @param string      $commandline
     * @param null|string $cwd
     * @param null|array  $env
     * @param null|string $input
     * @param int         $timeout
     * @param array       $options
     *
     * @return Process
     */
    private function getProcess($commandline, $cwd = null, array $env = null, $input = null, $timeout = 60)
    {
        $process = new Process($commandline, $cwd, $env, $input, $timeout);
        $process->inheritEnvironmentVariables();

        if (false !== $enhance = getenv('ENHANCE_SIGCHLD')) {
            try {
                $process->setEnhanceSigchildCompatibility(false);
                $process->getExitCode();
                $this->fail('ENHANCE_SIGCHLD must be used together with a sigchild-enabled PHP.');
            } catch (RuntimeException $e) {
                $this->assertSame('This PHP has been compiled with --enable-sigchild. You must use setEnhanceSigchildCompatibility() to use this method.', $e->getMessage());
                if ($enhance) {
                    $process->setEnhanceSigchildCompatibility(true);
                } else {
                    self::$notEnhancedSigchild = true;
                }
            }
        }

        if (self::$process) {
            self::$process->stop(0);
        }

        return self::$process = $process;
    }

    /**
     * @return Process
     */
    private function getProcessForCode($code, $cwd = null, array $env = null, $input = null, $timeout = 60)
    {
        return $this->getProcess(array(self::$phpBin, '-r', $code), $cwd, $env, $input, $timeout);
    }

    private function skipIfNotEnhancedSigchild($expectException = true)
    {
        if (self::$sigchild) {
            if (!$expectException) {
                $this->markTestSkipped('PHP is compiled with --enable-sigchild.');
            } elseif (self::$notEnhancedSigchild) {
                if (method_exists($this, 'expectException')) {
                    $this->expectException('Symfony\Component\Process\Exception\RuntimeException');
                    $this->expectExceptionMessage('This PHP has been compiled with --enable-sigchild.');
                } else {
                    $this->setExpectedException('Symfony\Component\Process\Exception\RuntimeException', 'This PHP has been compiled with --enable-sigchild.');
                }
            }
        }
    }
}

class NonStringifiable
{
}
PKϤ$Z?9�_%%$process/Tests/NonStopableProcess.phpnu�[���<?php

/*
 * This file is part of the Symfony package.
 *
 * (c) Fabien Potencier <fabien@symfony.com>
 *
 * For the full copyright and license information, please view the LICENSE
 * file that was distributed with this source code.
 */

/**
 * Runs a PHP script that can be stopped only with a SIGKILL (9) signal for 3 seconds.
 *
 * @args duration Run this script with a custom duration
 *
 * @example `php NonStopableProcess.php 42` will run the script for 42 seconds
 */
function handleSignal($signal)
{
    switch ($signal) {
        case SIGTERM:
            $name = 'SIGTERM';
            break;
        case SIGINT:
            $name = 'SIGINT';
            break;
        default:
            $name = $signal.' (unknown)';
            break;
    }

    echo "signal $name\n";
}

pcntl_signal(SIGTERM, 'handleSignal');
pcntl_signal(SIGINT, 'handleSignal');

echo 'received ';

$duration = isset($argv[1]) ? (int) $argv[1] : 3;
$start = microtime(true);

while ($duration > (microtime(true) - $start)) {
    usleep(10000);
    pcntl_signal_dispatch();
}
PKϤ$Z�;,process/Tests/ProcessFailedExceptionTest.phpnu�[���<?php

/*
 * This file is part of the Symfony package.
 *
 * (c) Fabien Potencier <fabien@symfony.com>
 *
 * For the full copyright and license information, please view the LICENSE
 * file that was distributed with this source code.
 */

namespace Symfony\Component\Process\Tests;

use PHPUnit\Framework\TestCase;
use Symfony\Component\Process\Exception\ProcessFailedException;

/**
 * @author Sebastian Marek <proofek@gmail.com>
 */
class ProcessFailedExceptionTest extends TestCase
{
    /**
     * tests ProcessFailedException throws exception if the process was successful.
     */
    public function testProcessFailedExceptionThrowsException()
    {
        $process = $this->getMockBuilder('Symfony\Component\Process\Process')->setMethods(array('isSuccessful'))->setConstructorArgs(array('php'))->getMock();
        $process->expects($this->once())
            ->method('isSuccessful')
            ->will($this->returnValue(true));

        $this->{method_exists($this, $_ = 'expectException') ? $_ : 'setExpectedException'}(
            '\InvalidArgumentException',
            'Expected a failed process, but the given process was successful.'
        );

        new ProcessFailedException($process);
    }

    /**
     * tests ProcessFailedException uses information from process output
     * to generate exception message.
     */
    public function testProcessFailedExceptionPopulatesInformationFromProcessOutput()
    {
        $cmd = 'php';
        $exitCode = 1;
        $exitText = 'General error';
        $output = 'Command output';
        $errorOutput = 'FATAL: Unexpected error';
        $workingDirectory = getcwd();

        $process = $this->getMockBuilder('Symfony\Component\Process\Process')->setMethods(array('isSuccessful', 'getOutput', 'getErrorOutput', 'getExitCode', 'getExitCodeText', 'isOutputDisabled', 'getWorkingDirectory'))->setConstructorArgs(array($cmd))->getMock();
        $process->expects($this->once())
            ->method('isSuccessful')
            ->will($this->returnValue(false));

        $process->expects($this->once())
            ->method('getOutput')
            ->will($this->returnValue($output));

        $process->expects($this->once())
            ->method('getErrorOutput')
            ->will($this->returnValue($errorOutput));

        $process->expects($this->once())
            ->method('getExitCode')
            ->will($this->returnValue($exitCode));

        $process->expects($this->once())
            ->method('getExitCodeText')
            ->will($this->returnValue($exitText));

        $process->expects($this->once())
            ->method('isOutputDisabled')
            ->will($this->returnValue(false));

        $process->expects($this->once())
            ->method('getWorkingDirectory')
            ->will($this->returnValue($workingDirectory));

        $exception = new ProcessFailedException($process);

        $this->assertEquals(
            "The command \"$cmd\" failed.\n\nExit Code: $exitCode($exitText)\n\nWorking directory: {$workingDirectory}\n\nOutput:\n================\n{$output}\n\nError Output:\n================\n{$errorOutput}",
            $exception->getMessage()
        );
    }

    /**
     * Tests that ProcessFailedException does not extract information from
     * process output if it was previously disabled.
     */
    public function testDisabledOutputInFailedExceptionDoesNotPopulateOutput()
    {
        $cmd = 'php';
        $exitCode = 1;
        $exitText = 'General error';
        $workingDirectory = getcwd();

        $process = $this->getMockBuilder('Symfony\Component\Process\Process')->setMethods(array('isSuccessful', 'isOutputDisabled', 'getExitCode', 'getExitCodeText', 'getOutput', 'getErrorOutput', 'getWorkingDirectory'))->setConstructorArgs(array($cmd))->getMock();
        $process->expects($this->once())
            ->method('isSuccessful')
            ->will($this->returnValue(false));

        $process->expects($this->never())
            ->method('getOutput');

        $process->expects($this->never())
            ->method('getErrorOutput');

        $process->expects($this->once())
            ->method('getExitCode')
            ->will($this->returnValue($exitCode));

        $process->expects($this->once())
            ->method('getExitCodeText')
            ->will($this->returnValue($exitText));

        $process->expects($this->once())
            ->method('isOutputDisabled')
            ->will($this->returnValue(true));

        $process->expects($this->once())
            ->method('getWorkingDirectory')
            ->will($this->returnValue($workingDirectory));

        $exception = new ProcessFailedException($process);

        $this->assertEquals(
            "The command \"$cmd\" failed.\n\nExit Code: $exitCode($exitText)\n\nWorking directory: {$workingDirectory}",
            $exception->getMessage()
        );
    }
}
PKϤ$Zи process/Tests/PhpProcessTest.phpnu�[���<?php

/*
 * This file is part of the Symfony package.
 *
 * (c) Fabien Potencier <fabien@symfony.com>
 *
 * For the full copyright and license information, please view the LICENSE
 * file that was distributed with this source code.
 */

namespace Symfony\Component\Process\Tests;

use PHPUnit\Framework\TestCase;
use Symfony\Component\Process\PhpProcess;

class PhpProcessTest extends TestCase
{
    public function testNonBlockingWorks()
    {
        $expected = 'hello world!';
        $process = new PhpProcess(<<<PHP
<?php echo '$expected';
PHP
        );
        $process->start();
        $process->wait();
        $this->assertEquals($expected, $process->getOutput());
    }

    public function testCommandLine()
    {
        $process = new PhpProcess(<<<'PHP'
<?php echo phpversion().PHP_SAPI;
PHP
        );

        $commandLine = $process->getCommandLine();

        $process->start();
        $this->assertContains($commandLine, $process->getCommandLine(), '::getCommandLine() returns the command line of PHP after start');

        $process->wait();
        $this->assertContains($commandLine, $process->getCommandLine(), '::getCommandLine() returns the command line of PHP after wait');

        $this->assertSame(phpversion().PHP_SAPI, $process->getOutput());
    }
}
PKϤ$Z`�*���process/ProcessBuilder.phpnu�[���<?php

/*
 * This file is part of the Symfony package.
 *
 * (c) Fabien Potencier <fabien@symfony.com>
 *
 * For the full copyright and license information, please view the LICENSE
 * file that was distributed with this source code.
 */

namespace Symfony\Component\Process;

use Symfony\Component\Process\Exception\InvalidArgumentException;
use Symfony\Component\Process\Exception\LogicException;

/**
 * Process builder.
 *
 * @author Kris Wallsmith <kris@symfony.com>
 */
class ProcessBuilder
{
    private $arguments;
    private $cwd;
    private $env = array();
    private $input;
    private $timeout = 60;
    private $options;
    private $inheritEnv = true;
    private $prefix = array();
    private $outputDisabled = false;

    /**
     * Constructor.
     *
     * @param string[] $arguments An array of arguments
     */
    public function __construct(array $arguments = array())
    {
        $this->arguments = $arguments;
    }

    /**
     * Creates a process builder instance.
     *
     * @param string[] $arguments An array of arguments
     *
     * @return static
     */
    public static function create(array $arguments = array())
    {
        return new static($arguments);
    }

    /**
     * Adds an unescaped argument to the command string.
     *
     * @param string $argument A command argument
     *
     * @return $this
     */
    public function add($argument)
    {
        $this->arguments[] = $argument;

        return $this;
    }

    /**
     * Adds a prefix to the command string.
     *
     * The prefix is preserved when resetting arguments.
     *
     * @param string|array $prefix A command prefix or an array of command prefixes
     *
     * @return $this
     */
    public function setPrefix($prefix)
    {
        $this->prefix = is_array($prefix) ? $prefix : array($prefix);

        return $this;
    }

    /**
     * Sets the arguments of the process.
     *
     * Arguments must not be escaped.
     * Previous arguments are removed.
     *
     * @param string[] $arguments
     *
     * @return $this
     */
    public function setArguments(array $arguments)
    {
        $this->arguments = $arguments;

        return $this;
    }

    /**
     * Sets the working directory.
     *
     * @param null|string $cwd The working directory
     *
     * @return $this
     */
    public function setWorkingDirectory($cwd)
    {
        $this->cwd = $cwd;

        return $this;
    }

    /**
     * Sets whether environment variables will be inherited or not.
     *
     * @param bool $inheritEnv
     *
     * @return $this
     *
     * @deprecated since version 3.3, to be removed in 4.0.
     */
    public function inheritEnvironmentVariables($inheritEnv = true)
    {
        @trigger_error(sprintf('The %s() method is deprecated since version 3.3 and will be removed in 4.0.', __METHOD__), E_USER_DEPRECATED);

        $this->inheritEnv = $inheritEnv;

        return $this;
    }

    /**
     * Sets an environment variable.
     *
     * Setting a variable overrides its previous value. Use `null` to unset a
     * defined environment variable.
     *
     * @param string      $name  The variable name
     * @param null|string $value The variable value
     *
     * @return $this
     */
    public function setEnv($name, $value)
    {
        $this->env[$name] = $value;

        return $this;
    }

    /**
     * Adds a set of environment variables.
     *
     * Already existing environment variables with the same name will be
     * overridden by the new values passed to this method. Pass `null` to unset
     * a variable.
     *
     * @param array $variables The variables
     *
     * @return $this
     */
    public function addEnvironmentVariables(array $variables)
    {
        $this->env = array_replace($this->env, $variables);

        return $this;
    }

    /**
     * Sets the input of the process.
     *
     * @param resource|scalar|\Traversable|null $input The input content
     *
     * @return $this
     *
     * @throws InvalidArgumentException In case the argument is invalid
     */
    public function setInput($input)
    {
        $this->input = ProcessUtils::validateInput(__METHOD__, $input);

        return $this;
    }

    /**
     * Sets the process timeout.
     *
     * To disable the timeout, set this value to null.
     *
     * @param float|null $timeout
     *
     * @return $this
     *
     * @throws InvalidArgumentException
     */
    public function setTimeout($timeout)
    {
        if (null === $timeout) {
            $this->timeout = null;

            return $this;
        }

        $timeout = (float) $timeout;

        if ($timeout < 0) {
            throw new InvalidArgumentException('The timeout value must be a valid positive integer or float number.');
        }

        $this->timeout = $timeout;

        return $this;
    }

    /**
     * Adds a proc_open option.
     *
     * @param string $name  The option name
     * @param string $value The option value
     *
     * @return $this
     *
     * @deprecated since version 3.3, to be removed in 4.0.
     */
    public function setOption($name, $value)
    {
        @trigger_error(sprintf('The %s() method is deprecated since version 3.3 and will be removed in 4.0.', __METHOD__), E_USER_DEPRECATED);

        $this->options[$name] = $value;

        return $this;
    }

    /**
     * Disables fetching output and error output from the underlying process.
     *
     * @return $this
     */
    public function disableOutput()
    {
        $this->outputDisabled = true;

        return $this;
    }

    /**
     * Enables fetching output and error output from the underlying process.
     *
     * @return $this
     */
    public function enableOutput()
    {
        $this->outputDisabled = false;

        return $this;
    }

    /**
     * Creates a Process instance and returns it.
     *
     * @return Process
     *
     * @throws LogicException In case no arguments have been provided
     */
    public function getProcess()
    {
        if (0 === count($this->prefix) && 0 === count($this->arguments)) {
            throw new LogicException('You must add() command arguments before calling getProcess().');
        }

        $arguments = array_merge($this->prefix, $this->arguments);
        $process = new Process($arguments, $this->cwd, $this->env, $this->input, $this->timeout, $this->options);
        // to preserve the BC with symfony <3.3, we convert the array structure
        // to a string structure to avoid the prefixing with the exec command
        $process->setCommandLine($process->getCommandLine());

        if ($this->inheritEnv) {
            $process->inheritEnvironmentVariables();
        }
        if ($this->outputDisabled) {
            $process->disableOutput();
        }

        return $process;
    }
}
PKϤ$Z��X

process/PhpExecutableFinder.phpnu�[���<?php

/*
 * This file is part of the Symfony package.
 *
 * (c) Fabien Potencier <fabien@symfony.com>
 *
 * For the full copyright and license information, please view the LICENSE
 * file that was distributed with this source code.
 */

namespace Symfony\Component\Process;

/**
 * An executable finder specifically designed for the PHP executable.
 *
 * @author Fabien Potencier <fabien@symfony.com>
 * @author Johannes M. Schmitt <schmittjoh@gmail.com>
 */
class PhpExecutableFinder
{
    private $executableFinder;

    public function __construct()
    {
        $this->executableFinder = new ExecutableFinder();
    }

    /**
     * Finds The PHP executable.
     *
     * @return string|false The PHP executable path or false if it cannot be found
     */
    public function find(bool $includeArgs = true)
    {
        if ($php = getenv('PHP_BINARY')) {
            if (!is_executable($php)) {
                $command = '\\' === \DIRECTORY_SEPARATOR ? 'where' : 'command -v';
                if ($php = strtok(exec($command.' '.escapeshellarg($php)), \PHP_EOL)) {
                    if (!is_executable($php)) {
                        return false;
                    }
                } else {
                    return false;
                }
            }

            return $php;
        }

        $args = $this->findArguments();
        $args = $includeArgs && $args ? ' '.implode(' ', $args) : '';

        // PHP_BINARY return the current sapi executable
        if (\PHP_BINARY && \in_array(\PHP_SAPI, ['cgi-fcgi', 'cli', 'cli-server', 'phpdbg'], true)) {
            return \PHP_BINARY.$args;
        }

        if ($php = getenv('PHP_PATH')) {
            if (!@is_executable($php)) {
                return false;
            }

            return $php;
        }

        if ($php = getenv('PHP_PEAR_PHP_BIN')) {
            if (@is_executable($php)) {
                return $php;
            }
        }

        if (@is_executable($php = \PHP_BINDIR.('\\' === \DIRECTORY_SEPARATOR ? '\\php.exe' : '/php'))) {
            return $php;
        }

        $dirs = [\PHP_BINDIR];
        if ('\\' === \DIRECTORY_SEPARATOR) {
            $dirs[] = 'C:\xampp\php\\';
        }

        return $this->executableFinder->find('php', false, $dirs);
    }

    /**
     * Finds the PHP executable arguments.
     *
     * @return array The PHP executable arguments
     */
    public function findArguments()
    {
        $arguments = [];
        if ('phpdbg' === \PHP_SAPI) {
            $arguments[] = '-qrr';
        }

        return $arguments;
    }
}
PKϤ$Z\3$���process/README.mdnu�[���Process Component
=================

The Process component executes commands in sub-processes.

Resources
---------

 * [Documentation](https://symfony.com/doc/current/components/process.html)
 * [Contributing](https://symfony.com/doc/current/contributing/index.html)
 * [Report issues](https://github.com/symfony/symfony/issues) and
   [send Pull Requests](https://github.com/symfony/symfony/pulls)
   in the [main Symfony repository](https://github.com/symfony/symfony)
PKϤ$Zkm�:

process/ExecutableFinder.phpnu�[���<?php

/*
 * This file is part of the Symfony package.
 *
 * (c) Fabien Potencier <fabien@symfony.com>
 *
 * For the full copyright and license information, please view the LICENSE
 * file that was distributed with this source code.
 */

namespace Symfony\Component\Process;

/**
 * Generic executable finder.
 *
 * @author Fabien Potencier <fabien@symfony.com>
 * @author Johannes M. Schmitt <schmittjoh@gmail.com>
 */
class ExecutableFinder
{
    private $suffixes = ['.exe', '.bat', '.cmd', '.com'];

    /**
     * Replaces default suffixes of executable.
     */
    public function setSuffixes(array $suffixes)
    {
        $this->suffixes = $suffixes;
    }

    /**
     * Adds new possible suffix to check for executable.
     */
    public function addSuffix(string $suffix)
    {
        $this->suffixes[] = $suffix;
    }

    /**
     * Finds an executable by name.
     *
     * @param string      $name      The executable name (without the extension)
     * @param string|null $default   The default to return if no executable is found
     * @param array       $extraDirs Additional dirs to check into
     *
     * @return string|null The executable path or default value
     */
    public function find(string $name, string $default = null, array $extraDirs = [])
    {
        if (ini_get('open_basedir')) {
            $searchPath = array_merge(explode(\PATH_SEPARATOR, ini_get('open_basedir')), $extraDirs);
            $dirs = [];
            foreach ($searchPath as $path) {
                // Silencing against https://bugs.php.net/69240
                if (@is_dir($path)) {
                    $dirs[] = $path;
                } else {
                    if (basename($path) == $name && @is_executable($path)) {
                        return $path;
                    }
                }
            }
        } else {
            $dirs = array_merge(
                explode(\PATH_SEPARATOR, getenv('PATH') ?: getenv('Path')),
                $extraDirs
            );
        }

        $suffixes = [''];
        if ('\\' === \DIRECTORY_SEPARATOR) {
            $pathExt = getenv('PATHEXT');
            $suffixes = array_merge($pathExt ? explode(\PATH_SEPARATOR, $pathExt) : $this->suffixes, $suffixes);
        }
        foreach ($suffixes as $suffix) {
            foreach ($dirs as $dir) {
                if (@is_file($file = $dir.\DIRECTORY_SEPARATOR.$name.$suffix) && ('\\' === \DIRECTORY_SEPARATOR || @is_executable($file))) {
                    return $file;
                }
            }
        }

        return $default;
    }
}
PKϤ$Z|�%�MMprocess/ProcessUtils.phpnu�[���<?php

/*
 * This file is part of the Symfony package.
 *
 * (c) Fabien Potencier <fabien@symfony.com>
 *
 * For the full copyright and license information, please view the LICENSE
 * file that was distributed with this source code.
 */

namespace Symfony\Component\Process;

use Symfony\Component\Process\Exception\InvalidArgumentException;

/**
 * ProcessUtils is a bunch of utility methods.
 *
 * This class contains static methods only and is not meant to be instantiated.
 *
 * @author Martin Hasoň <martin.hason@gmail.com>
 */
class ProcessUtils
{
    /**
     * This class should not be instantiated.
     */
    private function __construct()
    {
    }

    /**
     * Validates and normalizes a Process input.
     *
     * @param string $caller The name of method call that validates the input
     * @param mixed  $input  The input to validate
     *
     * @return mixed The validated input
     *
     * @throws InvalidArgumentException In case the input is not valid
     */
    public static function validateInput(string $caller, $input)
    {
        if (null !== $input) {
            if (\is_resource($input)) {
                return $input;
            }
            if (\is_string($input)) {
                return $input;
            }
            if (is_scalar($input)) {
                return (string) $input;
            }
            if ($input instanceof Process) {
                return $input->getIterator($input::ITER_SKIP_ERR);
            }
            if ($input instanceof \Iterator) {
                return $input;
            }
            if ($input instanceof \Traversable) {
                return new \IteratorIterator($input);
            }

            throw new InvalidArgumentException(sprintf('"%s" only accepts strings, Traversable objects or stream resources.', $caller));
        }

        return $input;
    }
}
PKϤ$Z^1�M��process/Process.phpnu�[���<?php

/*
 * This file is part of the Symfony package.
 *
 * (c) Fabien Potencier <fabien@symfony.com>
 *
 * For the full copyright and license information, please view the LICENSE
 * file that was distributed with this source code.
 */

namespace Symfony\Component\Process;

use Symfony\Component\Process\Exception\InvalidArgumentException;
use Symfony\Component\Process\Exception\LogicException;
use Symfony\Component\Process\Exception\ProcessFailedException;
use Symfony\Component\Process\Exception\ProcessSignaledException;
use Symfony\Component\Process\Exception\ProcessTimedOutException;
use Symfony\Component\Process\Exception\RuntimeException;
use Symfony\Component\Process\Pipes\PipesInterface;
use Symfony\Component\Process\Pipes\UnixPipes;
use Symfony\Component\Process\Pipes\WindowsPipes;

/**
 * Process is a thin wrapper around proc_* functions to easily
 * start independent PHP processes.
 *
 * @author Fabien Potencier <fabien@symfony.com>
 * @author Romain Neutron <imprec@gmail.com>
 */
class Process implements \IteratorAggregate
{
    public const ERR = 'err';
    public const OUT = 'out';

    public const STATUS_READY = 'ready';
    public const STATUS_STARTED = 'started';
    public const STATUS_TERMINATED = 'terminated';

    public const STDIN = 0;
    public const STDOUT = 1;
    public const STDERR = 2;

    // Timeout Precision in seconds.
    public const TIMEOUT_PRECISION = 0.2;

    public const ITER_NON_BLOCKING = 1; // By default, iterating over outputs is a blocking call, use this flag to make it non-blocking
    public const ITER_KEEP_OUTPUT = 2;  // By default, outputs are cleared while iterating, use this flag to keep them in memory
    public const ITER_SKIP_OUT = 4;     // Use this flag to skip STDOUT while iterating
    public const ITER_SKIP_ERR = 8;     // Use this flag to skip STDERR while iterating

    private $callback;
    private $hasCallback = false;
    private $commandline;
    private $cwd;
    private $env;
    private $input;
    private $starttime;
    private $lastOutputTime;
    private $timeout;
    private $idleTimeout;
    private $exitcode;
    private $fallbackStatus = [];
    private $processInformation;
    private $outputDisabled = false;
    private $stdout;
    private $stderr;
    private $process;
    private $status = self::STATUS_READY;
    private $incrementalOutputOffset = 0;
    private $incrementalErrorOutputOffset = 0;
    private $tty = false;
    private $pty;
    private $options = ['suppress_errors' => true, 'bypass_shell' => true];

    private $useFileHandles = false;
    /** @var PipesInterface */
    private $processPipes;

    private $latestSignal;

    private static $sigchild;

    /**
     * Exit codes translation table.
     *
     * User-defined errors must use exit codes in the 64-113 range.
     */
    public static $exitCodes = [
        0 => 'OK',
        1 => 'General error',
        2 => 'Misuse of shell builtins',

        126 => 'Invoked command cannot execute',
        127 => 'Command not found',
        128 => 'Invalid exit argument',

        // signals
        129 => 'Hangup',
        130 => 'Interrupt',
        131 => 'Quit and dump core',
        132 => 'Illegal instruction',
        133 => 'Trace/breakpoint trap',
        134 => 'Process aborted',
        135 => 'Bus error: "access to undefined portion of memory object"',
        136 => 'Floating point exception: "erroneous arithmetic operation"',
        137 => 'Kill (terminate immediately)',
        138 => 'User-defined 1',
        139 => 'Segmentation violation',
        140 => 'User-defined 2',
        141 => 'Write to pipe with no one reading',
        142 => 'Signal raised by alarm',
        143 => 'Termination (request to terminate)',
        // 144 - not defined
        145 => 'Child process terminated, stopped (or continued*)',
        146 => 'Continue if stopped',
        147 => 'Stop executing temporarily',
        148 => 'Terminal stop signal',
        149 => 'Background process attempting to read from tty ("in")',
        150 => 'Background process attempting to write to tty ("out")',
        151 => 'Urgent data available on socket',
        152 => 'CPU time limit exceeded',
        153 => 'File size limit exceeded',
        154 => 'Signal raised by timer counting virtual time: "virtual timer expired"',
        155 => 'Profiling timer expired',
        // 156 - not defined
        157 => 'Pollable event',
        // 158 - not defined
        159 => 'Bad syscall',
    ];

    /**
     * @param array          $command The command to run and its arguments listed as separate entries
     * @param string|null    $cwd     The working directory or null to use the working dir of the current PHP process
     * @param array|null     $env     The environment variables or null to use the same environment as the current PHP process
     * @param mixed          $input   The input as stream resource, scalar or \Traversable, or null for no input
     * @param int|float|null $timeout The timeout in seconds or null to disable
     *
     * @throws LogicException When proc_open is not installed
     */
    public function __construct(array $command, string $cwd = null, array $env = null, $input = null, ?float $timeout = 60)
    {
        if (!\function_exists('proc_open')) {
            throw new LogicException('The Process class relies on proc_open, which is not available on your PHP installation.');
        }

        $this->commandline = $command;
        $this->cwd = $cwd;

        // on Windows, if the cwd changed via chdir(), proc_open defaults to the dir where PHP was started
        // on Gnu/Linux, PHP builds with --enable-maintainer-zts are also affected
        // @see : https://bugs.php.net/51800
        // @see : https://bugs.php.net/50524
        if (null === $this->cwd && (\defined('ZEND_THREAD_SAFE') || '\\' === \DIRECTORY_SEPARATOR)) {
            $this->cwd = getcwd();
        }
        if (null !== $env) {
            $this->setEnv($env);
        }

        $this->setInput($input);
        $this->setTimeout($timeout);
        $this->useFileHandles = '\\' === \DIRECTORY_SEPARATOR;
        $this->pty = false;
    }

    /**
     * Creates a Process instance as a command-line to be run in a shell wrapper.
     *
     * Command-lines are parsed by the shell of your OS (/bin/sh on Unix-like, cmd.exe on Windows.)
     * This allows using e.g. pipes or conditional execution. In this mode, signals are sent to the
     * shell wrapper and not to your commands.
     *
     * In order to inject dynamic values into command-lines, we strongly recommend using placeholders.
     * This will save escaping values, which is not portable nor secure anyway:
     *
     *   $process = Process::fromShellCommandline('my_command "$MY_VAR"');
     *   $process->run(null, ['MY_VAR' => $theValue]);
     *
     * @param string         $command The command line to pass to the shell of the OS
     * @param string|null    $cwd     The working directory or null to use the working dir of the current PHP process
     * @param array|null     $env     The environment variables or null to use the same environment as the current PHP process
     * @param mixed          $input   The input as stream resource, scalar or \Traversable, or null for no input
     * @param int|float|null $timeout The timeout in seconds or null to disable
     *
     * @return static
     *
     * @throws LogicException When proc_open is not installed
     */
    public static function fromShellCommandline(string $command, string $cwd = null, array $env = null, $input = null, ?float $timeout = 60)
    {
        $process = new static([], $cwd, $env, $input, $timeout);
        $process->commandline = $command;

        return $process;
    }

    /**
     * @return array
     */
    public function __sleep()
    {
        throw new \BadMethodCallException('Cannot serialize '.__CLASS__);
    }

    public function __wakeup()
    {
        throw new \BadMethodCallException('Cannot unserialize '.__CLASS__);
    }

    public function __destruct()
    {
        if ($this->options['create_new_console'] ?? false) {
            $this->processPipes->close();
        } else {
            $this->stop(0);
        }
    }

    public function __clone()
    {
        $this->resetProcessData();
    }

    /**
     * Runs the process.
     *
     * The callback receives the type of output (out or err) and
     * some bytes from the output in real-time. It allows to have feedback
     * from the independent process during execution.
     *
     * The STDOUT and STDERR are also available after the process is finished
     * via the getOutput() and getErrorOutput() methods.
     *
     * @param callable|null $callback A PHP callback to run whenever there is some
     *                                output available on STDOUT or STDERR
     *
     * @return int The exit status code
     *
     * @throws RuntimeException         When process can't be launched
     * @throws RuntimeException         When process is already running
     * @throws ProcessTimedOutException When process timed out
     * @throws ProcessSignaledException When process stopped after receiving signal
     * @throws LogicException           In case a callback is provided and output has been disabled
     *
     * @final
     */
    public function run(callable $callback = null, array $env = []): int
    {
        $this->start($callback, $env);

        return $this->wait();
    }

    /**
     * Runs the process.
     *
     * This is identical to run() except that an exception is thrown if the process
     * exits with a non-zero exit code.
     *
     * @return $this
     *
     * @throws ProcessFailedException if the process didn't terminate successfully
     *
     * @final
     */
    public function mustRun(callable $callback = null, array $env = []): self
    {
        if (0 !== $this->run($callback, $env)) {
            throw new ProcessFailedException($this);
        }

        return $this;
    }

    /**
     * Starts the process and returns after writing the input to STDIN.
     *
     * This method blocks until all STDIN data is sent to the process then it
     * returns while the process runs in the background.
     *
     * The termination of the process can be awaited with wait().
     *
     * The callback receives the type of output (out or err) and some bytes from
     * the output in real-time while writing the standard input to the process.
     * It allows to have feedback from the independent process during execution.
     *
     * @param callable|null $callback A PHP callback to run whenever there is some
     *                                output available on STDOUT or STDERR
     *
     * @throws RuntimeException When process can't be launched
     * @throws RuntimeException When process is already running
     * @throws LogicException   In case a callback is provided and output has been disabled
     */
    public function start(callable $callback = null, array $env = [])
    {
        if ($this->isRunning()) {
            throw new RuntimeException('Process is already running.');
        }

        $this->resetProcessData();
        $this->starttime = $this->lastOutputTime = microtime(true);
        $this->callback = $this->buildCallback($callback);
        $this->hasCallback = null !== $callback;
        $descriptors = $this->getDescriptors();

        if ($this->env) {
            $env += $this->env;
        }

        $env += $this->getDefaultEnv();

        if (\is_array($commandline = $this->commandline)) {
            $commandline = implode(' ', array_map([$this, 'escapeArgument'], $commandline));

            if ('\\' !== \DIRECTORY_SEPARATOR) {
                // exec is mandatory to deal with sending a signal to the process
                $commandline = 'exec '.$commandline;
            }
        } else {
            $commandline = $this->replacePlaceholders($commandline, $env);
        }

        if ('\\' === \DIRECTORY_SEPARATOR) {
            $commandline = $this->prepareWindowsCommandLine($commandline, $env);
        } elseif (!$this->useFileHandles && $this->isSigchildEnabled()) {
            // last exit code is output on the fourth pipe and caught to work around --enable-sigchild
            $descriptors[3] = ['pipe', 'w'];

            // See https://unix.stackexchange.com/questions/71205/background-process-pipe-input
            $commandline = '{ ('.$commandline.') <&3 3<&- 3>/dev/null & } 3<&0;';
            $commandline .= 'pid=$!; echo $pid >&3; wait $pid; code=$?; echo $code >&3; exit $code';

            // Workaround for the bug, when PTS functionality is enabled.
            // @see : https://bugs.php.net/69442
            $ptsWorkaround = fopen(__FILE__, 'r');
        }

        $envPairs = [];
        foreach ($env as $k => $v) {
            if (false !== $v) {
                $envPairs[] = $k.'='.$v;
            }
        }

        if (!is_dir($this->cwd)) {
            throw new RuntimeException(sprintf('The provided cwd "%s" does not exist.', $this->cwd));
        }

        $this->process = @proc_open($commandline, $descriptors, $this->processPipes->pipes, $this->cwd, $envPairs, $this->options);

        if (!\is_resource($this->process)) {
            throw new RuntimeException('Unable to launch a new process.');
        }
        $this->status = self::STATUS_STARTED;

        if (isset($descriptors[3])) {
            $this->fallbackStatus['pid'] = (int) fgets($this->processPipes->pipes[3]);
        }

        if ($this->tty) {
            return;
        }

        $this->updateStatus(false);
        $this->checkTimeout();
    }

    /**
     * Restarts the process.
     *
     * Be warned that the process is cloned before being started.
     *
     * @param callable|null $callback A PHP callback to run whenever there is some
     *                                output available on STDOUT or STDERR
     *
     * @return static
     *
     * @throws RuntimeException When process can't be launched
     * @throws RuntimeException When process is already running
     *
     * @see start()
     *
     * @final
     */
    public function restart(callable $callback = null, array $env = []): self
    {
        if ($this->isRunning()) {
            throw new RuntimeException('Process is already running.');
        }

        $process = clone $this;
        $process->start($callback, $env);

        return $process;
    }

    /**
     * Waits for the process to terminate.
     *
     * The callback receives the type of output (out or err) and some bytes
     * from the output in real-time while writing the standard input to the process.
     * It allows to have feedback from the independent process during execution.
     *
     * @param callable|null $callback A valid PHP callback
     *
     * @return int The exitcode of the process
     *
     * @throws ProcessTimedOutException When process timed out
     * @throws ProcessSignaledException When process stopped after receiving signal
     * @throws LogicException           When process is not yet started
     */
    public function wait(callable $callback = null)
    {
        $this->requireProcessIsStarted(__FUNCTION__);

        $this->updateStatus(false);

        if (null !== $callback) {
            if (!$this->processPipes->haveReadSupport()) {
                $this->stop(0);
                throw new LogicException('Pass the callback to the "Process::start" method or call enableOutput to use a callback with "Process::wait".');
            }
            $this->callback = $this->buildCallback($callback);
        }

        do {
            $this->checkTimeout();
            $running = '\\' === \DIRECTORY_SEPARATOR ? $this->isRunning() : $this->processPipes->areOpen();
            $this->readPipes($running, '\\' !== \DIRECTORY_SEPARATOR || !$running);
        } while ($running);

        while ($this->isRunning()) {
            $this->checkTimeout();
            usleep(1000);
        }

        if ($this->processInformation['signaled'] && $this->processInformation['termsig'] !== $this->latestSignal) {
            throw new ProcessSignaledException($this);
        }

        return $this->exitcode;
    }

    /**
     * Waits until the callback returns true.
     *
     * The callback receives the type of output (out or err) and some bytes
     * from the output in real-time while writing the standard input to the process.
     * It allows to have feedback from the independent process during execution.
     *
     * @throws RuntimeException         When process timed out
     * @throws LogicException           When process is not yet started
     * @throws ProcessTimedOutException In case the timeout was reached
     */
    public function waitUntil(callable $callback): bool
    {
        $this->requireProcessIsStarted(__FUNCTION__);
        $this->updateStatus(false);

        if (!$this->processPipes->haveReadSupport()) {
            $this->stop(0);
            throw new LogicException('Pass the callback to the "Process::start" method or call enableOutput to use a callback with "Process::waitUntil".');
        }
        $callback = $this->buildCallback($callback);

        $ready = false;
        while (true) {
            $this->checkTimeout();
            $running = '\\' === \DIRECTORY_SEPARATOR ? $this->isRunning() : $this->processPipes->areOpen();
            $output = $this->processPipes->readAndWrite($running, '\\' !== \DIRECTORY_SEPARATOR || !$running);

            foreach ($output as $type => $data) {
                if (3 !== $type) {
                    $ready = $callback(self::STDOUT === $type ? self::OUT : self::ERR, $data) || $ready;
                } elseif (!isset($this->fallbackStatus['signaled'])) {
                    $this->fallbackStatus['exitcode'] = (int) $data;
                }
            }
            if ($ready) {
                return true;
            }
            if (!$running) {
                return false;
            }

            usleep(1000);
        }
    }

    /**
     * Returns the Pid (process identifier), if applicable.
     *
     * @return int|null The process id if running, null otherwise
     */
    public function getPid()
    {
        return $this->isRunning() ? $this->processInformation['pid'] : null;
    }

    /**
     * Sends a POSIX signal to the process.
     *
     * @param int $signal A valid POSIX signal (see https://php.net/pcntl.constants)
     *
     * @return $this
     *
     * @throws LogicException   In case the process is not running
     * @throws RuntimeException In case --enable-sigchild is activated and the process can't be killed
     * @throws RuntimeException In case of failure
     */
    public function signal(int $signal)
    {
        $this->doSignal($signal, true);

        return $this;
    }

    /**
     * Disables fetching output and error output from the underlying process.
     *
     * @return $this
     *
     * @throws RuntimeException In case the process is already running
     * @throws LogicException   if an idle timeout is set
     */
    public function disableOutput()
    {
        if ($this->isRunning()) {
            throw new RuntimeException('Disabling output while the process is running is not possible.');
        }
        if (null !== $this->idleTimeout) {
            throw new LogicException('Output can not be disabled while an idle timeout is set.');
        }

        $this->outputDisabled = true;

        return $this;
    }

    /**
     * Enables fetching output and error output from the underlying process.
     *
     * @return $this
     *
     * @throws RuntimeException In case the process is already running
     */
    public function enableOutput()
    {
        if ($this->isRunning()) {
            throw new RuntimeException('Enabling output while the process is running is not possible.');
        }

        $this->outputDisabled = false;

        return $this;
    }

    /**
     * Returns true in case the output is disabled, false otherwise.
     *
     * @return bool
     */
    public function isOutputDisabled()
    {
        return $this->outputDisabled;
    }

    /**
     * Returns the current output of the process (STDOUT).
     *
     * @return string The process output
     *
     * @throws LogicException in case the output has been disabled
     * @throws LogicException In case the process is not started
     */
    public function getOutput()
    {
        $this->readPipesForOutput(__FUNCTION__);

        if (false === $ret = stream_get_contents($this->stdout, -1, 0)) {
            return '';
        }

        return $ret;
    }

    /**
     * Returns the output incrementally.
     *
     * In comparison with the getOutput method which always return the whole
     * output, this one returns the new output since the last call.
     *
     * @return string The process output since the last call
     *
     * @throws LogicException in case the output has been disabled
     * @throws LogicException In case the process is not started
     */
    public function getIncrementalOutput()
    {
        $this->readPipesForOutput(__FUNCTION__);

        $latest = stream_get_contents($this->stdout, -1, $this->incrementalOutputOffset);
        $this->incrementalOutputOffset = ftell($this->stdout);

        if (false === $latest) {
            return '';
        }

        return $latest;
    }

    /**
     * Returns an iterator to the output of the process, with the output type as keys (Process::OUT/ERR).
     *
     * @param int $flags A bit field of Process::ITER_* flags
     *
     * @throws LogicException in case the output has been disabled
     * @throws LogicException In case the process is not started
     *
     * @return \Generator
     */
    #[\ReturnTypeWillChange]
    public function getIterator(int $flags = 0)
    {
        $this->readPipesForOutput(__FUNCTION__, false);

        $clearOutput = !(self::ITER_KEEP_OUTPUT & $flags);
        $blocking = !(self::ITER_NON_BLOCKING & $flags);
        $yieldOut = !(self::ITER_SKIP_OUT & $flags);
        $yieldErr = !(self::ITER_SKIP_ERR & $flags);

        while (null !== $this->callback || ($yieldOut && !feof($this->stdout)) || ($yieldErr && !feof($this->stderr))) {
            if ($yieldOut) {
                $out = stream_get_contents($this->stdout, -1, $this->incrementalOutputOffset);

                if (isset($out[0])) {
                    if ($clearOutput) {
                        $this->clearOutput();
                    } else {
                        $this->incrementalOutputOffset = ftell($this->stdout);
                    }

                    yield self::OUT => $out;
                }
            }

            if ($yieldErr) {
                $err = stream_get_contents($this->stderr, -1, $this->incrementalErrorOutputOffset);

                if (isset($err[0])) {
                    if ($clearOutput) {
                        $this->clearErrorOutput();
                    } else {
                        $this->incrementalErrorOutputOffset = ftell($this->stderr);
                    }

                    yield self::ERR => $err;
                }
            }

            if (!$blocking && !isset($out[0]) && !isset($err[0])) {
                yield self::OUT => '';
            }

            $this->checkTimeout();
            $this->readPipesForOutput(__FUNCTION__, $blocking);
        }
    }

    /**
     * Clears the process output.
     *
     * @return $this
     */
    public function clearOutput()
    {
        ftruncate($this->stdout, 0);
        fseek($this->stdout, 0);
        $this->incrementalOutputOffset = 0;

        return $this;
    }

    /**
     * Returns the current error output of the process (STDERR).
     *
     * @return string The process error output
     *
     * @throws LogicException in case the output has been disabled
     * @throws LogicException In case the process is not started
     */
    public function getErrorOutput()
    {
        $this->readPipesForOutput(__FUNCTION__);

        if (false === $ret = stream_get_contents($this->stderr, -1, 0)) {
            return '';
        }

        return $ret;
    }

    /**
     * Returns the errorOutput incrementally.
     *
     * In comparison with the getErrorOutput method which always return the
     * whole error output, this one returns the new error output since the last
     * call.
     *
     * @return string The process error output since the last call
     *
     * @throws LogicException in case the output has been disabled
     * @throws LogicException In case the process is not started
     */
    public function getIncrementalErrorOutput()
    {
        $this->readPipesForOutput(__FUNCTION__);

        $latest = stream_get_contents($this->stderr, -1, $this->incrementalErrorOutputOffset);
        $this->incrementalErrorOutputOffset = ftell($this->stderr);

        if (false === $latest) {
            return '';
        }

        return $latest;
    }

    /**
     * Clears the process output.
     *
     * @return $this
     */
    public function clearErrorOutput()
    {
        ftruncate($this->stderr, 0);
        fseek($this->stderr, 0);
        $this->incrementalErrorOutputOffset = 0;

        return $this;
    }

    /**
     * Returns the exit code returned by the process.
     *
     * @return int|null The exit status code, null if the Process is not terminated
     */
    public function getExitCode()
    {
        $this->updateStatus(false);

        return $this->exitcode;
    }

    /**
     * Returns a string representation for the exit code returned by the process.
     *
     * This method relies on the Unix exit code status standardization
     * and might not be relevant for other operating systems.
     *
     * @return string|null A string representation for the exit status code, null if the Process is not terminated
     *
     * @see http://tldp.org/LDP/abs/html/exitcodes.html
     * @see http://en.wikipedia.org/wiki/Unix_signal
     */
    public function getExitCodeText()
    {
        if (null === $exitcode = $this->getExitCode()) {
            return null;
        }

        return self::$exitCodes[$exitcode] ?? 'Unknown error';
    }

    /**
     * Checks if the process ended successfully.
     *
     * @return bool true if the process ended successfully, false otherwise
     */
    public function isSuccessful()
    {
        return 0 === $this->getExitCode();
    }

    /**
     * Returns true if the child process has been terminated by an uncaught signal.
     *
     * It always returns false on Windows.
     *
     * @return bool
     *
     * @throws LogicException In case the process is not terminated
     */
    public function hasBeenSignaled()
    {
        $this->requireProcessIsTerminated(__FUNCTION__);

        return $this->processInformation['signaled'];
    }

    /**
     * Returns the number of the signal that caused the child process to terminate its execution.
     *
     * It is only meaningful if hasBeenSignaled() returns true.
     *
     * @return int
     *
     * @throws RuntimeException In case --enable-sigchild is activated
     * @throws LogicException   In case the process is not terminated
     */
    public function getTermSignal()
    {
        $this->requireProcessIsTerminated(__FUNCTION__);

        if ($this->isSigchildEnabled() && -1 === $this->processInformation['termsig']) {
            throw new RuntimeException('This PHP has been compiled with --enable-sigchild. Term signal can not be retrieved.');
        }

        return $this->processInformation['termsig'];
    }

    /**
     * Returns true if the child process has been stopped by a signal.
     *
     * It always returns false on Windows.
     *
     * @return bool
     *
     * @throws LogicException In case the process is not terminated
     */
    public function hasBeenStopped()
    {
        $this->requireProcessIsTerminated(__FUNCTION__);

        return $this->processInformation['stopped'];
    }

    /**
     * Returns the number of the signal that caused the child process to stop its execution.
     *
     * It is only meaningful if hasBeenStopped() returns true.
     *
     * @return int
     *
     * @throws LogicException In case the process is not terminated
     */
    public function getStopSignal()
    {
        $this->requireProcessIsTerminated(__FUNCTION__);

        return $this->processInformation['stopsig'];
    }

    /**
     * Checks if the process is currently running.
     *
     * @return bool true if the process is currently running, false otherwise
     */
    public function isRunning()
    {
        if (self::STATUS_STARTED !== $this->status) {
            return false;
        }

        $this->updateStatus(false);

        return $this->processInformation['running'];
    }

    /**
     * Checks if the process has been started with no regard to the current state.
     *
     * @return bool true if status is ready, false otherwise
     */
    public function isStarted()
    {
        return self::STATUS_READY != $this->status;
    }

    /**
     * Checks if the process is terminated.
     *
     * @return bool true if process is terminated, false otherwise
     */
    public function isTerminated()
    {
        $this->updateStatus(false);

        return self::STATUS_TERMINATED == $this->status;
    }

    /**
     * Gets the process status.
     *
     * The status is one of: ready, started, terminated.
     *
     * @return string The current process status
     */
    public function getStatus()
    {
        $this->updateStatus(false);

        return $this->status;
    }

    /**
     * Stops the process.
     *
     * @param int|float $timeout The timeout in seconds
     * @param int       $signal  A POSIX signal to send in case the process has not stop at timeout, default is SIGKILL (9)
     *
     * @return int|null The exit-code of the process or null if it's not running
     */
    public function stop(float $timeout = 10, int $signal = null)
    {
        $timeoutMicro = microtime(true) + $timeout;
        if ($this->isRunning()) {
            // given SIGTERM may not be defined and that "proc_terminate" uses the constant value and not the constant itself, we use the same here
            $this->doSignal(15, false);
            do {
                usleep(1000);
            } while ($this->isRunning() && microtime(true) < $timeoutMicro);

            if ($this->isRunning()) {
                // Avoid exception here: process is supposed to be running, but it might have stopped just
                // after this line. In any case, let's silently discard the error, we cannot do anything.
                $this->doSignal($signal ?: 9, false);
            }
        }

        if ($this->isRunning()) {
            if (isset($this->fallbackStatus['pid'])) {
                unset($this->fallbackStatus['pid']);

                return $this->stop(0, $signal);
            }
            $this->close();
        }

        return $this->exitcode;
    }

    /**
     * Adds a line to the STDOUT stream.
     *
     * @internal
     */
    public function addOutput(string $line)
    {
        $this->lastOutputTime = microtime(true);

        fseek($this->stdout, 0, \SEEK_END);
        fwrite($this->stdout, $line);
        fseek($this->stdout, $this->incrementalOutputOffset);
    }

    /**
     * Adds a line to the STDERR stream.
     *
     * @internal
     */
    public function addErrorOutput(string $line)
    {
        $this->lastOutputTime = microtime(true);

        fseek($this->stderr, 0, \SEEK_END);
        fwrite($this->stderr, $line);
        fseek($this->stderr, $this->incrementalErrorOutputOffset);
    }

    /**
     * Gets the last output time in seconds.
     *
     * @return float|null The last output time in seconds or null if it isn't started
     */
    public function getLastOutputTime(): ?float
    {
        return $this->lastOutputTime;
    }

    /**
     * Gets the command line to be executed.
     *
     * @return string The command to execute
     */
    public function getCommandLine()
    {
        return \is_array($this->commandline) ? implode(' ', array_map([$this, 'escapeArgument'], $this->commandline)) : $this->commandline;
    }

    /**
     * Gets the process timeout (max. runtime).
     *
     * @return float|null The timeout in seconds or null if it's disabled
     */
    public function getTimeout()
    {
        return $this->timeout;
    }

    /**
     * Gets the process idle timeout (max. time since last output).
     *
     * @return float|null The timeout in seconds or null if it's disabled
     */
    public function getIdleTimeout()
    {
        return $this->idleTimeout;
    }

    /**
     * Sets the process timeout (max. runtime) in seconds.
     *
     * To disable the timeout, set this value to null.
     *
     * @return $this
     *
     * @throws InvalidArgumentException if the timeout is negative
     */
    public function setTimeout(?float $timeout)
    {
        $this->timeout = $this->validateTimeout($timeout);

        return $this;
    }

    /**
     * Sets the process idle timeout (max. time since last output) in seconds.
     *
     * To disable the timeout, set this value to null.
     *
     * @return $this
     *
     * @throws LogicException           if the output is disabled
     * @throws InvalidArgumentException if the timeout is negative
     */
    public function setIdleTimeout(?float $timeout)
    {
        if (null !== $timeout && $this->outputDisabled) {
            throw new LogicException('Idle timeout can not be set while the output is disabled.');
        }

        $this->idleTimeout = $this->validateTimeout($timeout);

        return $this;
    }

    /**
     * Enables or disables the TTY mode.
     *
     * @return $this
     *
     * @throws RuntimeException In case the TTY mode is not supported
     */
    public function setTty(bool $tty)
    {
        if ('\\' === \DIRECTORY_SEPARATOR && $tty) {
            throw new RuntimeException('TTY mode is not supported on Windows platform.');
        }

        if ($tty && !self::isTtySupported()) {
            throw new RuntimeException('TTY mode requires /dev/tty to be read/writable.');
        }

        $this->tty = $tty;

        return $this;
    }

    /**
     * Checks if the TTY mode is enabled.
     *
     * @return bool true if the TTY mode is enabled, false otherwise
     */
    public function isTty()
    {
        return $this->tty;
    }

    /**
     * Sets PTY mode.
     *
     * @return $this
     */
    public function setPty(bool $bool)
    {
        $this->pty = $bool;

        return $this;
    }

    /**
     * Returns PTY state.
     *
     * @return bool
     */
    public function isPty()
    {
        return $this->pty;
    }

    /**
     * Gets the working directory.
     *
     * @return string|null The current working directory or null on failure
     */
    public function getWorkingDirectory()
    {
        if (null === $this->cwd) {
            // getcwd() will return false if any one of the parent directories does not have
            // the readable or search mode set, even if the current directory does
            return getcwd() ?: null;
        }

        return $this->cwd;
    }

    /**
     * Sets the current working directory.
     *
     * @return $this
     */
    public function setWorkingDirectory(string $cwd)
    {
        $this->cwd = $cwd;

        return $this;
    }

    /**
     * Gets the environment variables.
     *
     * @return array The current environment variables
     */
    public function getEnv()
    {
        return $this->env;
    }

    /**
     * Sets the environment variables.
     *
     * Each environment variable value should be a string.
     * If it is an array, the variable is ignored.
     * If it is false or null, it will be removed when
     * env vars are otherwise inherited.
     *
     * That happens in PHP when 'argv' is registered into
     * the $_ENV array for instance.
     *
     * @param array $env The new environment variables
     *
     * @return $this
     */
    public function setEnv(array $env)
    {
        // Process can not handle env values that are arrays
        $env = array_filter($env, function ($value) {
            return !\is_array($value);
        });

        $this->env = $env;

        return $this;
    }

    /**
     * Gets the Process input.
     *
     * @return resource|string|\Iterator|null The Process input
     */
    public function getInput()
    {
        return $this->input;
    }

    /**
     * Sets the input.
     *
     * This content will be passed to the underlying process standard input.
     *
     * @param string|int|float|bool|resource|\Traversable|null $input The content
     *
     * @return $this
     *
     * @throws LogicException In case the process is running
     */
    public function setInput($input)
    {
        if ($this->isRunning()) {
            throw new LogicException('Input can not be set while the process is running.');
        }

        $this->input = ProcessUtils::validateInput(__METHOD__, $input);

        return $this;
    }

    /**
     * Performs a check between the timeout definition and the time the process started.
     *
     * In case you run a background process (with the start method), you should
     * trigger this method regularly to ensure the process timeout
     *
     * @throws ProcessTimedOutException In case the timeout was reached
     */
    public function checkTimeout()
    {
        if (self::STATUS_STARTED !== $this->status) {
            return;
        }

        if (null !== $this->timeout && $this->timeout < microtime(true) - $this->starttime) {
            $this->stop(0);

            throw new ProcessTimedOutException($this, ProcessTimedOutException::TYPE_GENERAL);
        }

        if (null !== $this->idleTimeout && $this->idleTimeout < microtime(true) - $this->lastOutputTime) {
            $this->stop(0);

            throw new ProcessTimedOutException($this, ProcessTimedOutException::TYPE_IDLE);
        }
    }

    /**
     * @throws LogicException in case process is not started
     */
    public function getStartTime(): float
    {
        if (!$this->isStarted()) {
            throw new LogicException('Start time is only available after process start.');
        }

        return $this->starttime;
    }

    /**
     * Defines options to pass to the underlying proc_open().
     *
     * @see https://php.net/proc_open for the options supported by PHP.
     *
     * Enabling the "create_new_console" option allows a subprocess to continue
     * to run after the main process exited, on both Windows and *nix
     */
    public function setOptions(array $options)
    {
        if ($this->isRunning()) {
            throw new RuntimeException('Setting options while the process is running is not possible.');
        }

        $defaultOptions = $this->options;
        $existingOptions = ['blocking_pipes', 'create_process_group', 'create_new_console'];

        foreach ($options as $key => $value) {
            if (!\in_array($key, $existingOptions)) {
                $this->options = $defaultOptions;
                throw new LogicException(sprintf('Invalid option "%s" passed to "%s()". Supported options are "%s".', $key, __METHOD__, implode('", "', $existingOptions)));
            }
            $this->options[$key] = $value;
        }
    }

    /**
     * Returns whether TTY is supported on the current operating system.
     */
    public static function isTtySupported(): bool
    {
        static $isTtySupported;

        if (null === $isTtySupported) {
            $isTtySupported = (bool) @proc_open('echo 1 >/dev/null', [['file', '/dev/tty', 'r'], ['file', '/dev/tty', 'w'], ['file', '/dev/tty', 'w']], $pipes);
        }

        return $isTtySupported;
    }

    /**
     * Returns whether PTY is supported on the current operating system.
     *
     * @return bool
     */
    public static function isPtySupported()
    {
        static $result;

        if (null !== $result) {
            return $result;
        }

        if ('\\' === \DIRECTORY_SEPARATOR) {
            return $result = false;
        }

        return $result = (bool) @proc_open('echo 1 >/dev/null', [['pty'], ['pty'], ['pty']], $pipes);
    }

    /**
     * Creates the descriptors needed by the proc_open.
     */
    private function getDescriptors(): array
    {
        if ($this->input instanceof \Iterator) {
            $this->input->rewind();
        }
        if ('\\' === \DIRECTORY_SEPARATOR) {
            $this->processPipes = new WindowsPipes($this->input, !$this->outputDisabled || $this->hasCallback);
        } else {
            $this->processPipes = new UnixPipes($this->isTty(), $this->isPty(), $this->input, !$this->outputDisabled || $this->hasCallback);
        }

        return $this->processPipes->getDescriptors();
    }

    /**
     * Builds up the callback used by wait().
     *
     * The callbacks adds all occurred output to the specific buffer and calls
     * the user callback (if present) with the received output.
     *
     * @param callable|null $callback The user defined PHP callback
     *
     * @return \Closure A PHP closure
     */
    protected function buildCallback(callable $callback = null)
    {
        if ($this->outputDisabled) {
            return function ($type, $data) use ($callback): bool {
                return null !== $callback && $callback($type, $data);
            };
        }

        $out = self::OUT;

        return function ($type, $data) use ($callback, $out): bool {
            if ($out == $type) {
                $this->addOutput($data);
            } else {
                $this->addErrorOutput($data);
            }

            return null !== $callback && $callback($type, $data);
        };
    }

    /**
     * Updates the status of the process, reads pipes.
     *
     * @param bool $blocking Whether to use a blocking read call
     */
    protected function updateStatus(bool $blocking)
    {
        if (self::STATUS_STARTED !== $this->status) {
            return;
        }

        $this->processInformation = proc_get_status($this->process);
        $running = $this->processInformation['running'];

        $this->readPipes($running && $blocking, '\\' !== \DIRECTORY_SEPARATOR || !$running);

        if ($this->fallbackStatus && $this->isSigchildEnabled()) {
            $this->processInformation = $this->fallbackStatus + $this->processInformation;
        }

        if (!$running) {
            $this->close();
        }
    }

    /**
     * Returns whether PHP has been compiled with the '--enable-sigchild' option or not.
     *
     * @return bool
     */
    protected function isSigchildEnabled()
    {
        if (null !== self::$sigchild) {
            return self::$sigchild;
        }

        if (!\function_exists('phpinfo')) {
            return self::$sigchild = false;
        }

        ob_start();
        phpinfo(\INFO_GENERAL);

        return self::$sigchild = str_contains(ob_get_clean(), '--enable-sigchild');
    }

    /**
     * Reads pipes for the freshest output.
     *
     * @param string $caller   The name of the method that needs fresh outputs
     * @param bool   $blocking Whether to use blocking calls or not
     *
     * @throws LogicException in case output has been disabled or process is not started
     */
    private function readPipesForOutput(string $caller, bool $blocking = false)
    {
        if ($this->outputDisabled) {
            throw new LogicException('Output has been disabled.');
        }

        $this->requireProcessIsStarted($caller);

        $this->updateStatus($blocking);
    }

    /**
     * Validates and returns the filtered timeout.
     *
     * @throws InvalidArgumentException if the given timeout is a negative number
     */
    private function validateTimeout(?float $timeout): ?float
    {
        $timeout = (float) $timeout;

        if (0.0 === $timeout) {
            $timeout = null;
        } elseif ($timeout < 0) {
            throw new InvalidArgumentException('The timeout value must be a valid positive integer or float number.');
        }

        return $timeout;
    }

    /**
     * Reads pipes, executes callback.
     *
     * @param bool $blocking Whether to use blocking calls or not
     * @param bool $close    Whether to close file handles or not
     */
    private function readPipes(bool $blocking, bool $close)
    {
        $result = $this->processPipes->readAndWrite($blocking, $close);

        $callback = $this->callback;
        foreach ($result as $type => $data) {
            if (3 !== $type) {
                $callback(self::STDOUT === $type ? self::OUT : self::ERR, $data);
            } elseif (!isset($this->fallbackStatus['signaled'])) {
                $this->fallbackStatus['exitcode'] = (int) $data;
            }
        }
    }

    /**
     * Closes process resource, closes file handles, sets the exitcode.
     *
     * @return int The exitcode
     */
    private function close(): int
    {
        $this->processPipes->close();
        if (\is_resource($this->process)) {
            proc_close($this->process);
        }
        $this->exitcode = $this->processInformation['exitcode'];
        $this->status = self::STATUS_TERMINATED;

        if (-1 === $this->exitcode) {
            if ($this->processInformation['signaled'] && 0 < $this->processInformation['termsig']) {
                // if process has been signaled, no exitcode but a valid termsig, apply Unix convention
                $this->exitcode = 128 + $this->processInformation['termsig'];
            } elseif ($this->isSigchildEnabled()) {
                $this->processInformation['signaled'] = true;
                $this->processInformation['termsig'] = -1;
            }
        }

        // Free memory from self-reference callback created by buildCallback
        // Doing so in other contexts like __destruct or by garbage collector is ineffective
        // Now pipes are closed, so the callback is no longer necessary
        $this->callback = null;

        return $this->exitcode;
    }

    /**
     * Resets data related to the latest run of the process.
     */
    private function resetProcessData()
    {
        $this->starttime = null;
        $this->callback = null;
        $this->exitcode = null;
        $this->fallbackStatus = [];
        $this->processInformation = null;
        $this->stdout = fopen('php://temp/maxmemory:'.(1024 * 1024), 'w+');
        $this->stderr = fopen('php://temp/maxmemory:'.(1024 * 1024), 'w+');
        $this->process = null;
        $this->latestSignal = null;
        $this->status = self::STATUS_READY;
        $this->incrementalOutputOffset = 0;
        $this->incrementalErrorOutputOffset = 0;
    }

    /**
     * Sends a POSIX signal to the process.
     *
     * @param int  $signal         A valid POSIX signal (see https://php.net/pcntl.constants)
     * @param bool $throwException Whether to throw exception in case signal failed
     *
     * @return bool True if the signal was sent successfully, false otherwise
     *
     * @throws LogicException   In case the process is not running
     * @throws RuntimeException In case --enable-sigchild is activated and the process can't be killed
     * @throws RuntimeException In case of failure
     */
    private function doSignal(int $signal, bool $throwException): bool
    {
        if (null === $pid = $this->getPid()) {
            if ($throwException) {
                throw new LogicException('Can not send signal on a non running process.');
            }

            return false;
        }

        if ('\\' === \DIRECTORY_SEPARATOR) {
            exec(sprintf('taskkill /F /T /PID %d 2>&1', $pid), $output, $exitCode);
            if ($exitCode && $this->isRunning()) {
                if ($throwException) {
                    throw new RuntimeException(sprintf('Unable to kill the process (%s).', implode(' ', $output)));
                }

                return false;
            }
        } else {
            if (!$this->isSigchildEnabled()) {
                $ok = @proc_terminate($this->process, $signal);
            } elseif (\function_exists('posix_kill')) {
                $ok = @posix_kill($pid, $signal);
            } elseif ($ok = proc_open(sprintf('kill -%d %d', $signal, $pid), [2 => ['pipe', 'w']], $pipes)) {
                $ok = false === fgets($pipes[2]);
            }
            if (!$ok) {
                if ($throwException) {
                    throw new RuntimeException(sprintf('Error while sending signal "%s".', $signal));
                }

                return false;
            }
        }

        $this->latestSignal = $signal;
        $this->fallbackStatus['signaled'] = true;
        $this->fallbackStatus['exitcode'] = -1;
        $this->fallbackStatus['termsig'] = $this->latestSignal;

        return true;
    }

    private function prepareWindowsCommandLine(string $cmd, array &$env): string
    {
        $uid = uniqid('', true);
        $varCount = 0;
        $varCache = [];
        $cmd = preg_replace_callback(
            '/"(?:(
                [^"%!^]*+
                (?:
                    (?: !LF! | "(?:\^[%!^])?+" )
                    [^"%!^]*+
                )++
            ) | [^"]*+ )"/x',
            function ($m) use (&$env, &$varCache, &$varCount, $uid) {
                if (!isset($m[1])) {
                    return $m[0];
                }
                if (isset($varCache[$m[0]])) {
                    return $varCache[$m[0]];
                }
                if (str_contains($value = $m[1], "\0")) {
                    $value = str_replace("\0", '?', $value);
                }
                if (false === strpbrk($value, "\"%!\n")) {
                    return '"'.$value.'"';
                }

                $value = str_replace(['!LF!', '"^!"', '"^%"', '"^^"', '""'], ["\n", '!', '%', '^', '"'], $value);
                $value = '"'.preg_replace('/(\\\\*)"/', '$1$1\\"', $value).'"';
                $var = $uid.++$varCount;

                $env[$var] = $value;

                return $varCache[$m[0]] = '!'.$var.'!';
            },
            $cmd
        );

        $cmd = 'cmd /V:ON /E:ON /D /C ('.str_replace("\n", ' ', $cmd).')';
        foreach ($this->processPipes->getFiles() as $offset => $filename) {
            $cmd .= ' '.$offset.'>"'.$filename.'"';
        }

        return $cmd;
    }

    /**
     * Ensures the process is running or terminated, throws a LogicException if the process has a not started.
     *
     * @throws LogicException if the process has not run
     */
    private function requireProcessIsStarted(string $functionName)
    {
        if (!$this->isStarted()) {
            throw new LogicException(sprintf('Process must be started before calling "%s()".', $functionName));
        }
    }

    /**
     * Ensures the process is terminated, throws a LogicException if the process has a status different than "terminated".
     *
     * @throws LogicException if the process is not yet terminated
     */
    private function requireProcessIsTerminated(string $functionName)
    {
        if (!$this->isTerminated()) {
            throw new LogicException(sprintf('Process must be terminated before calling "%s()".', $functionName));
        }
    }

    /**
     * Escapes a string to be used as a shell argument.
     */
    private function escapeArgument(?string $argument): string
    {
        if ('' === $argument || null === $argument) {
            return '""';
        }
        if ('\\' !== \DIRECTORY_SEPARATOR) {
            return "'".str_replace("'", "'\\''", $argument)."'";
        }
        if (str_contains($argument, "\0")) {
            $argument = str_replace("\0", '?', $argument);
        }
        if (!preg_match('/[\/()%!^"<>&|\s]/', $argument)) {
            return $argument;
        }
        $argument = preg_replace('/(\\\\+)$/', '$1$1', $argument);

        return '"'.str_replace(['"', '^', '%', '!', "\n"], ['""', '"^^"', '"^%"', '"^!"', '!LF!'], $argument).'"';
    }

    private function replacePlaceholders(string $commandline, array $env)
    {
        return preg_replace_callback('/"\$\{:([_a-zA-Z]++[_a-zA-Z0-9]*+)\}"/', function ($matches) use ($commandline, $env) {
            if (!isset($env[$matches[1]]) || false === $env[$matches[1]]) {
                throw new InvalidArgumentException(sprintf('Command line is missing a value for parameter "%s": ', $matches[1]).$commandline);
            }

            return $this->escapeArgument($env[$matches[1]]);
        }, $commandline);
    }

    private function getDefaultEnv(): array
    {
        $env = [];

        foreach ($_SERVER as $k => $v) {
            if (\is_string($v) && false !== $v = getenv($k)) {
                $env[$k] = $v;
            }
        }

        foreach ($_ENV as $k => $v) {
            if (\is_string($v)) {
                $env[$k] = $v;
            }
        }

        return $env;
    }
}
PKϤ$Z�����.process/Exception/ProcessSignaledException.phpnu�[���<?php

/*
 * This file is part of the Symfony package.
 *
 * (c) Fabien Potencier <fabien@symfony.com>
 *
 * For the full copyright and license information, please view the LICENSE
 * file that was distributed with this source code.
 */

namespace Symfony\Component\Process\Exception;

use Symfony\Component\Process\Process;

/**
 * Exception that is thrown when a process has been signaled.
 *
 * @author Sullivan Senechal <soullivaneuh@gmail.com>
 */
final class ProcessSignaledException extends RuntimeException
{
    private $process;

    public function __construct(Process $process)
    {
        $this->process = $process;

        parent::__construct(sprintf('The process has been signaled with signal "%s".', $process->getTermSignal()));
    }

    public function getProcess(): Process
    {
        return $this->process;
    }

    public function getSignal(): int
    {
        return $this->getProcess()->getTermSignal();
    }
}
PKϤ$Z��W��$process/Exception/LogicException.phpnu�[���<?php

/*
 * This file is part of the Symfony package.
 *
 * (c) Fabien Potencier <fabien@symfony.com>
 *
 * For the full copyright and license information, please view the LICENSE
 * file that was distributed with this source code.
 */

namespace Symfony\Component\Process\Exception;

/**
 * LogicException for the Process Component.
 *
 * @author Romain Neutron <imprec@gmail.com>
 */
class LogicException extends \LogicException implements ExceptionInterface
{
}
PKϤ$Z���+��(process/Exception/ExceptionInterface.phpnu�[���<?php

/*
 * This file is part of the Symfony package.
 *
 * (c) Fabien Potencier <fabien@symfony.com>
 *
 * For the full copyright and license information, please view the LICENSE
 * file that was distributed with this source code.
 */

namespace Symfony\Component\Process\Exception;

/**
 * Marker Interface for the Process Component.
 *
 * @author Johannes M. Schmitt <schmittjoh@gmail.com>
 */
interface ExceptionInterface extends \Throwable
{
}
PKϤ$ZP��5��,process/Exception/ProcessFailedException.phpnu�[���<?php

/*
 * This file is part of the Symfony package.
 *
 * (c) Fabien Potencier <fabien@symfony.com>
 *
 * For the full copyright and license information, please view the LICENSE
 * file that was distributed with this source code.
 */

namespace Symfony\Component\Process\Exception;

use Symfony\Component\Process\Process;

/**
 * Exception for failed processes.
 *
 * @author Johannes M. Schmitt <schmittjoh@gmail.com>
 */
class ProcessFailedException extends RuntimeException
{
    private $process;

    public function __construct(Process $process)
    {
        if ($process->isSuccessful()) {
            throw new InvalidArgumentException('Expected a failed process, but the given process was successful.');
        }

        $error = sprintf('The command "%s" failed.'."\n\nExit Code: %s(%s)\n\nWorking directory: %s",
            $process->getCommandLine(),
            $process->getExitCode(),
            $process->getExitCodeText(),
            $process->getWorkingDirectory()
        );

        if (!$process->isOutputDisabled()) {
            $error .= sprintf("\n\nOutput:\n================\n%s\n\nError Output:\n================\n%s",
                $process->getOutput(),
                $process->getErrorOutput()
            );
        }

        parent::__construct($error);

        $this->process = $process;
    }

    public function getProcess()
    {
        return $this->process;
    }
}
PKϤ$Z˅����.process/Exception/InvalidArgumentException.phpnu�[���<?php

/*
 * This file is part of the Symfony package.
 *
 * (c) Fabien Potencier <fabien@symfony.com>
 *
 * For the full copyright and license information, please view the LICENSE
 * file that was distributed with this source code.
 */

namespace Symfony\Component\Process\Exception;

/**
 * InvalidArgumentException for the Process Component.
 *
 * @author Romain Neutron <imprec@gmail.com>
 */
class InvalidArgumentException extends \InvalidArgumentException implements ExceptionInterface
{
}
PKϤ$Z{0���.process/Exception/ProcessTimedOutException.phpnu�[���<?php

/*
 * This file is part of the Symfony package.
 *
 * (c) Fabien Potencier <fabien@symfony.com>
 *
 * For the full copyright and license information, please view the LICENSE
 * file that was distributed with this source code.
 */

namespace Symfony\Component\Process\Exception;

use Symfony\Component\Process\Process;

/**
 * Exception that is thrown when a process times out.
 *
 * @author Johannes M. Schmitt <schmittjoh@gmail.com>
 */
class ProcessTimedOutException extends RuntimeException
{
    public const TYPE_GENERAL = 1;
    public const TYPE_IDLE = 2;

    private $process;
    private $timeoutType;

    public function __construct(Process $process, int $timeoutType)
    {
        $this->process = $process;
        $this->timeoutType = $timeoutType;

        parent::__construct(sprintf(
            'The process "%s" exceeded the timeout of %s seconds.',
            $process->getCommandLine(),
            $this->getExceededTimeout()
        ));
    }

    public function getProcess()
    {
        return $this->process;
    }

    public function isGeneralTimeout()
    {
        return self::TYPE_GENERAL === $this->timeoutType;
    }

    public function isIdleTimeout()
    {
        return self::TYPE_IDLE === $this->timeoutType;
    }

    public function getExceededTimeout()
    {
        switch ($this->timeoutType) {
            case self::TYPE_GENERAL:
                return $this->process->getTimeout();

            case self::TYPE_IDLE:
                return $this->process->getIdleTimeout();

            default:
                throw new \LogicException(sprintf('Unknown timeout type "%d".', $this->timeoutType));
        }
    }
}
PKϤ$Z>H����&process/Exception/RuntimeException.phpnu�[���<?php

/*
 * This file is part of the Symfony package.
 *
 * (c) Fabien Potencier <fabien@symfony.com>
 *
 * For the full copyright and license information, please view the LICENSE
 * file that was distributed with this source code.
 */

namespace Symfony\Component\Process\Exception;

/**
 * RuntimeException for the Process Component.
 *
 * @author Johannes M. Schmitt <schmittjoh@gmail.com>
 */
class RuntimeException extends \RuntimeException implements ExceptionInterface
{
}
PKϤ$Z(�C��process/CHANGELOG.mdnu�[���CHANGELOG
=========

5.2.0
-----

 * added `Process::setOptions()` to set `Process` specific options
 * added option `create_new_console` to allow a subprocess to continue
   to run after the main script exited, both on Linux and on Windows

5.1.0
-----

 * added `Process::getStartTime()` to retrieve the start time of the process as float

5.0.0
-----

 * removed `Process::inheritEnvironmentVariables()`
 * removed `PhpProcess::setPhpBinary()`
 * `Process` must be instantiated with a command array, use `Process::fromShellCommandline()` when the command should be parsed by the shell
 * removed `Process::setCommandLine()`

4.4.0
-----

 * deprecated `Process::inheritEnvironmentVariables()`: env variables are always inherited.
 * added `Process::getLastOutputTime()` method

4.2.0
-----

 * added the `Process::fromShellCommandline()` to run commands in a shell wrapper
 * deprecated passing a command as string when creating a `Process` instance
 * deprecated the `Process::setCommandline()` and the `PhpProcess::setPhpBinary()` methods
 * added the `Process::waitUntil()` method to wait for the process only for a
   specific output, then continue the normal execution of your application

4.1.0
-----

 * added the `Process::isTtySupported()` method that allows to check for TTY support
 * made `PhpExecutableFinder` look for the `PHP_BINARY` env var when searching the php binary
 * added the `ProcessSignaledException` class to properly catch signaled process errors

4.0.0
-----

 * environment variables will always be inherited
 * added a second `array $env = []` argument to the `start()`, `run()`,
   `mustRun()`, and `restart()` methods of the `Process` class
 * added a second `array $env = []` argument to the `start()` method of the
   `PhpProcess` class
 * the `ProcessUtils::escapeArgument()` method has been removed
 * the `areEnvironmentVariablesInherited()`, `getOptions()`, and `setOptions()`
   methods of the `Process` class have been removed
 * support for passing `proc_open()` options has been removed
 * removed the `ProcessBuilder` class, use the `Process` class instead
 * removed the `getEnhanceWindowsCompatibility()` and `setEnhanceWindowsCompatibility()` methods of the `Process` class
 * passing a not existing working directory to the constructor of the `Symfony\Component\Process\Process` class is not
   supported anymore

3.4.0
-----

 * deprecated the ProcessBuilder class
 * deprecated calling `Process::start()` without setting a valid working directory beforehand (via `setWorkingDirectory()` or constructor)

3.3.0
-----

 * added command line arrays in the `Process` class
 * added `$env` argument to `Process::start()`, `run()`, `mustRun()` and `restart()` methods
 * deprecated the `ProcessUtils::escapeArgument()` method
 * deprecated not inheriting environment variables
 * deprecated configuring `proc_open()` options
 * deprecated configuring enhanced Windows compatibility
 * deprecated configuring enhanced sigchild compatibility

2.5.0
-----

 * added support for PTY mode
 * added the convenience method "mustRun"
 * deprecation: Process::setStdin() is deprecated in favor of Process::setInput()
 * deprecation: Process::getStdin() is deprecated in favor of Process::getInput()
 * deprecation: Process::setInput() and ProcessBuilder::setInput() do not accept non-scalar types

2.4.0
-----

 * added the ability to define an idle timeout

2.3.0
-----

 * added ProcessUtils::escapeArgument() to fix the bug in escapeshellarg() function on Windows
 * added Process::signal()
 * added Process::getPid()
 * added support for a TTY mode

2.2.0
-----

 * added ProcessBuilder::setArguments() to reset the arguments on a builder
 * added a way to retrieve the standard and error output incrementally
 * added Process:restart()

2.1.0
-----

 * added support for non-blocking processes (start(), wait(), isRunning(), stop())
 * enhanced Windows compatibility
 * added Process::getExitCodeText() that returns a string representation for
   the exit code returned by the process
 * added ProcessBuilder
PKϤ$Z�
��))process/LICENSEnu�[���Copyright (c) 2004-2021 Fabien Potencier

Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is furnished
to do so, subject to the following conditions:

The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.

THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
THE SOFTWARE.
PKϤ$Z��^#	#	process/InputStream.phpnu�[���<?php

/*
 * This file is part of the Symfony package.
 *
 * (c) Fabien Potencier <fabien@symfony.com>
 *
 * For the full copyright and license information, please view the LICENSE
 * file that was distributed with this source code.
 */

namespace Symfony\Component\Process;

use Symfony\Component\Process\Exception\RuntimeException;

/**
 * Provides a way to continuously write to the input of a Process until the InputStream is closed.
 *
 * @author Nicolas Grekas <p@tchwork.com>
 */
class InputStream implements \IteratorAggregate
{
    /** @var callable|null */
    private $onEmpty = null;
    private $input = [];
    private $open = true;

    /**
     * Sets a callback that is called when the write buffer becomes empty.
     */
    public function onEmpty(callable $onEmpty = null)
    {
        $this->onEmpty = $onEmpty;
    }

    /**
     * Appends an input to the write buffer.
     *
     * @param resource|string|int|float|bool|\Traversable|null $input The input to append as scalar,
     *                                                                stream resource or \Traversable
     */
    public function write($input)
    {
        if (null === $input) {
            return;
        }
        if ($this->isClosed()) {
            throw new RuntimeException(sprintf('"%s" is closed.', static::class));
        }
        $this->input[] = ProcessUtils::validateInput(__METHOD__, $input);
    }

    /**
     * Closes the write buffer.
     */
    public function close()
    {
        $this->open = false;
    }

    /**
     * Tells whether the write buffer is closed or not.
     */
    public function isClosed()
    {
        return !$this->open;
    }

    /**
     * @return \Traversable
     */
    #[\ReturnTypeWillChange]
    public function getIterator()
    {
        $this->open = true;

        while ($this->open || $this->input) {
            if (!$this->input) {
                yield '';
                continue;
            }
            $current = array_shift($this->input);

            if ($current instanceof \Iterator) {
                yield from $current;
            } else {
                yield $current;
            }
            if (!$this->input && $this->open && null !== $onEmpty = $this->onEmpty) {
                $this->write($onEmpty($this));
            }
        }
    }
}
PKϤ$Z���� process/Pipes/PipesInterface.phpnu�[���<?php

/*
 * This file is part of the Symfony package.
 *
 * (c) Fabien Potencier <fabien@symfony.com>
 *
 * For the full copyright and license information, please view the LICENSE
 * file that was distributed with this source code.
 */

namespace Symfony\Component\Process\Pipes;

/**
 * PipesInterface manages descriptors and pipes for the use of proc_open.
 *
 * @author Romain Neutron <imprec@gmail.com>
 *
 * @internal
 */
interface PipesInterface
{
    public const CHUNK_SIZE = 16384;

    /**
     * Returns an array of descriptors for the use of proc_open.
     */
    public function getDescriptors(): array;

    /**
     * Returns an array of filenames indexed by their related stream in case these pipes use temporary files.
     *
     * @return string[]
     */
    public function getFiles(): array;

    /**
     * Reads data in file handles and pipes.
     *
     * @param bool $blocking Whether to use blocking calls or not
     * @param bool $close    Whether to close pipes if they've reached EOF
     *
     * @return string[] An array of read data indexed by their fd
     */
    public function readAndWrite(bool $blocking, bool $close = false): array;

    /**
     * Returns if the current state has open file handles or pipes.
     */
    public function areOpen(): bool;

    /**
     * Returns if pipes are able to read output.
     */
    public function haveReadSupport(): bool;

    /**
     * Closes file handles and pipes.
     */
    public function close();
}
PKϤ$Za�vddprocess/Pipes/UnixPipes.phpnu�[���<?php

/*
 * This file is part of the Symfony package.
 *
 * (c) Fabien Potencier <fabien@symfony.com>
 *
 * For the full copyright and license information, please view the LICENSE
 * file that was distributed with this source code.
 */

namespace Symfony\Component\Process\Pipes;

use Symfony\Component\Process\Process;

/**
 * UnixPipes implementation uses unix pipes as handles.
 *
 * @author Romain Neutron <imprec@gmail.com>
 *
 * @internal
 */
class UnixPipes extends AbstractPipes
{
    private $ttyMode;
    private $ptyMode;
    private $haveReadSupport;

    public function __construct(?bool $ttyMode, bool $ptyMode, $input, bool $haveReadSupport)
    {
        $this->ttyMode = $ttyMode;
        $this->ptyMode = $ptyMode;
        $this->haveReadSupport = $haveReadSupport;

        parent::__construct($input);
    }

    /**
     * @return array
     */
    public function __sleep()
    {
        throw new \BadMethodCallException('Cannot serialize '.__CLASS__);
    }

    public function __wakeup()
    {
        throw new \BadMethodCallException('Cannot unserialize '.__CLASS__);
    }

    public function __destruct()
    {
        $this->close();
    }

    /**
     * {@inheritdoc}
     */
    public function getDescriptors(): array
    {
        if (!$this->haveReadSupport) {
            $nullstream = fopen('/dev/null', 'c');

            return [
                ['pipe', 'r'],
                $nullstream,
                $nullstream,
            ];
        }

        if ($this->ttyMode) {
            return [
                ['file', '/dev/tty', 'r'],
                ['file', '/dev/tty', 'w'],
                ['file', '/dev/tty', 'w'],
            ];
        }

        if ($this->ptyMode && Process::isPtySupported()) {
            return [
                ['pty'],
                ['pty'],
                ['pty'],
            ];
        }

        return [
            ['pipe', 'r'],
            ['pipe', 'w'], // stdout
            ['pipe', 'w'], // stderr
        ];
    }

    /**
     * {@inheritdoc}
     */
    public function getFiles(): array
    {
        return [];
    }

    /**
     * {@inheritdoc}
     */
    public function readAndWrite(bool $blocking, bool $close = false): array
    {
        $this->unblock();
        $w = $this->write();

        $read = $e = [];
        $r = $this->pipes;
        unset($r[0]);

        // let's have a look if something changed in streams
        set_error_handler([$this, 'handleError']);
        if (($r || $w) && false === stream_select($r, $w, $e, 0, $blocking ? Process::TIMEOUT_PRECISION * 1E6 : 0)) {
            restore_error_handler();
            // if a system call has been interrupted, forget about it, let's try again
            // otherwise, an error occurred, let's reset pipes
            if (!$this->hasSystemCallBeenInterrupted()) {
                $this->pipes = [];
            }

            return $read;
        }
        restore_error_handler();

        foreach ($r as $pipe) {
            // prior PHP 5.4 the array passed to stream_select is modified and
            // lose key association, we have to find back the key
            $read[$type = array_search($pipe, $this->pipes, true)] = '';

            do {
                $data = @fread($pipe, self::CHUNK_SIZE);
                $read[$type] .= $data;
            } while (isset($data[0]) && ($close || isset($data[self::CHUNK_SIZE - 1])));

            if (!isset($read[$type][0])) {
                unset($read[$type]);
            }

            if ($close && feof($pipe)) {
                fclose($pipe);
                unset($this->pipes[$type]);
            }
        }

        return $read;
    }

    /**
     * {@inheritdoc}
     */
    public function haveReadSupport(): bool
    {
        return $this->haveReadSupport;
    }

    /**
     * {@inheritdoc}
     */
    public function areOpen(): bool
    {
        return (bool) $this->pipes;
    }
}
PKϤ$Zvg0��process/Pipes/AbstractPipes.phpnu�[���<?php

/*
 * This file is part of the Symfony package.
 *
 * (c) Fabien Potencier <fabien@symfony.com>
 *
 * For the full copyright and license information, please view the LICENSE
 * file that was distributed with this source code.
 */

namespace Symfony\Component\Process\Pipes;

use Symfony\Component\Process\Exception\InvalidArgumentException;

/**
 * @author Romain Neutron <imprec@gmail.com>
 *
 * @internal
 */
abstract class AbstractPipes implements PipesInterface
{
    public $pipes = [];

    private $inputBuffer = '';
    private $input;
    private $blocked = true;
    private $lastError;

    /**
     * @param resource|string|int|float|bool|\Iterator|null $input
     */
    public function __construct($input)
    {
        if (\is_resource($input) || $input instanceof \Iterator) {
            $this->input = $input;
        } elseif (\is_string($input)) {
            $this->inputBuffer = $input;
        } else {
            $this->inputBuffer = (string) $input;
        }
    }

    /**
     * {@inheritdoc}
     */
    public function close()
    {
        foreach ($this->pipes as $pipe) {
            fclose($pipe);
        }
        $this->pipes = [];
    }

    /**
     * Returns true if a system call has been interrupted.
     */
    protected function hasSystemCallBeenInterrupted(): bool
    {
        $lastError = $this->lastError;
        $this->lastError = null;

        // stream_select returns false when the `select` system call is interrupted by an incoming signal
        return null !== $lastError && false !== stripos($lastError, 'interrupted system call');
    }

    /**
     * Unblocks streams.
     */
    protected function unblock()
    {
        if (!$this->blocked) {
            return;
        }

        foreach ($this->pipes as $pipe) {
            stream_set_blocking($pipe, 0);
        }
        if (\is_resource($this->input)) {
            stream_set_blocking($this->input, 0);
        }

        $this->blocked = false;
    }

    /**
     * Writes input to stdin.
     *
     * @throws InvalidArgumentException When an input iterator yields a non supported value
     */
    protected function write(): ?array
    {
        if (!isset($this->pipes[0])) {
            return null;
        }
        $input = $this->input;

        if ($input instanceof \Iterator) {
            if (!$input->valid()) {
                $input = null;
            } elseif (\is_resource($input = $input->current())) {
                stream_set_blocking($input, 0);
            } elseif (!isset($this->inputBuffer[0])) {
                if (!\is_string($input)) {
                    if (!is_scalar($input)) {
                        throw new InvalidArgumentException(sprintf('"%s" yielded a value of type "%s", but only scalars and stream resources are supported.', get_debug_type($this->input), get_debug_type($input)));
                    }
                    $input = (string) $input;
                }
                $this->inputBuffer = $input;
                $this->input->next();
                $input = null;
            } else {
                $input = null;
            }
        }

        $r = $e = [];
        $w = [$this->pipes[0]];

        // let's have a look if something changed in streams
        if (false === @stream_select($r, $w, $e, 0, 0)) {
            return null;
        }

        foreach ($w as $stdin) {
            if (isset($this->inputBuffer[0])) {
                $written = fwrite($stdin, $this->inputBuffer);
                $this->inputBuffer = substr($this->inputBuffer, $written);
                if (isset($this->inputBuffer[0])) {
                    return [$this->pipes[0]];
                }
            }

            if ($input) {
                for (;;) {
                    $data = fread($input, self::CHUNK_SIZE);
                    if (!isset($data[0])) {
                        break;
                    }
                    $written = fwrite($stdin, $data);
                    $data = substr($data, $written);
                    if (isset($data[0])) {
                        $this->inputBuffer = $data;

                        return [$this->pipes[0]];
                    }
                }
                if (feof($input)) {
                    if ($this->input instanceof \Iterator) {
                        $this->input->next();
                    } else {
                        $this->input = null;
                    }
                }
            }
        }

        // no input to read on resource, buffer is empty
        if (!isset($this->inputBuffer[0]) && !($this->input instanceof \Iterator ? $this->input->valid() : $this->input)) {
            $this->input = null;
            fclose($this->pipes[0]);
            unset($this->pipes[0]);
        } elseif (!$w) {
            return [$this->pipes[0]];
        }

        return null;
    }

    /**
     * @internal
     */
    public function handleError(int $type, string $msg)
    {
        $this->lastError = $msg;
    }
}
PKϤ$Z�OA��process/Pipes/WindowsPipes.phpnu�[���<?php

/*
 * This file is part of the Symfony package.
 *
 * (c) Fabien Potencier <fabien@symfony.com>
 *
 * For the full copyright and license information, please view the LICENSE
 * file that was distributed with this source code.
 */

namespace Symfony\Component\Process\Pipes;

use Symfony\Component\Process\Exception\RuntimeException;
use Symfony\Component\Process\Process;

/**
 * WindowsPipes implementation uses temporary files as handles.
 *
 * @see https://bugs.php.net/51800
 * @see https://bugs.php.net/65650
 *
 * @author Romain Neutron <imprec@gmail.com>
 *
 * @internal
 */
class WindowsPipes extends AbstractPipes
{
    private $files = [];
    private $fileHandles = [];
    private $lockHandles = [];
    private $readBytes = [
        Process::STDOUT => 0,
        Process::STDERR => 0,
    ];
    private $haveReadSupport;

    public function __construct($input, bool $haveReadSupport)
    {
        $this->haveReadSupport = $haveReadSupport;

        if ($this->haveReadSupport) {
            // Fix for PHP bug #51800: reading from STDOUT pipe hangs forever on Windows if the output is too big.
            // Workaround for this problem is to use temporary files instead of pipes on Windows platform.
            //
            // @see https://bugs.php.net/51800
            $pipes = [
                Process::STDOUT => Process::OUT,
                Process::STDERR => Process::ERR,
            ];
            $tmpDir = sys_get_temp_dir();
            $lastError = 'unknown reason';
            set_error_handler(function ($type, $msg) use (&$lastError) { $lastError = $msg; });
            for ($i = 0;; ++$i) {
                foreach ($pipes as $pipe => $name) {
                    $file = sprintf('%s\\sf_proc_%02X.%s', $tmpDir, $i, $name);

                    if (!$h = fopen($file.'.lock', 'w')) {
                        if (file_exists($file.'.lock')) {
                            continue 2;
                        }
                        restore_error_handler();
                        throw new RuntimeException('A temporary file could not be opened to write the process output: '.$lastError);
                    }
                    if (!flock($h, \LOCK_EX | \LOCK_NB)) {
                        continue 2;
                    }
                    if (isset($this->lockHandles[$pipe])) {
                        flock($this->lockHandles[$pipe], \LOCK_UN);
                        fclose($this->lockHandles[$pipe]);
                    }
                    $this->lockHandles[$pipe] = $h;

                    if (!($h = fopen($file, 'w')) || !fclose($h) || !$h = fopen($file, 'r')) {
                        flock($this->lockHandles[$pipe], \LOCK_UN);
                        fclose($this->lockHandles[$pipe]);
                        unset($this->lockHandles[$pipe]);
                        continue 2;
                    }
                    $this->fileHandles[$pipe] = $h;
                    $this->files[$pipe] = $file;
                }
                break;
            }
            restore_error_handler();
        }

        parent::__construct($input);
    }

    /**
     * @return array
     */
    public function __sleep()
    {
        throw new \BadMethodCallException('Cannot serialize '.__CLASS__);
    }

    public function __wakeup()
    {
        throw new \BadMethodCallException('Cannot unserialize '.__CLASS__);
    }

    public function __destruct()
    {
        $this->close();
    }

    /**
     * {@inheritdoc}
     */
    public function getDescriptors(): array
    {
        if (!$this->haveReadSupport) {
            $nullstream = fopen('NUL', 'c');

            return [
                ['pipe', 'r'],
                $nullstream,
                $nullstream,
            ];
        }

        // We're not using pipe on Windows platform as it hangs (https://bugs.php.net/51800)
        // We're not using file handles as it can produce corrupted output https://bugs.php.net/65650
        // So we redirect output within the commandline and pass the nul device to the process
        return [
            ['pipe', 'r'],
            ['file', 'NUL', 'w'],
            ['file', 'NUL', 'w'],
        ];
    }

    /**
     * {@inheritdoc}
     */
    public function getFiles(): array
    {
        return $this->files;
    }

    /**
     * {@inheritdoc}
     */
    public function readAndWrite(bool $blocking, bool $close = false): array
    {
        $this->unblock();
        $w = $this->write();
        $read = $r = $e = [];

        if ($blocking) {
            if ($w) {
                @stream_select($r, $w, $e, 0, Process::TIMEOUT_PRECISION * 1E6);
            } elseif ($this->fileHandles) {
                usleep(Process::TIMEOUT_PRECISION * 1E6);
            }
        }
        foreach ($this->fileHandles as $type => $fileHandle) {
            $data = stream_get_contents($fileHandle, -1, $this->readBytes[$type]);

            if (isset($data[0])) {
                $this->readBytes[$type] += \strlen($data);
                $read[$type] = $data;
            }
            if ($close) {
                ftruncate($fileHandle, 0);
                fclose($fileHandle);
                flock($this->lockHandles[$type], \LOCK_UN);
                fclose($this->lockHandles[$type]);
                unset($this->fileHandles[$type], $this->lockHandles[$type]);
            }
        }

        return $read;
    }

    /**
     * {@inheritdoc}
     */
    public function haveReadSupport(): bool
    {
        return $this->haveReadSupport;
    }

    /**
     * {@inheritdoc}
     */
    public function areOpen(): bool
    {
        return $this->pipes && $this->fileHandles;
    }

    /**
     * {@inheritdoc}
     */
    public function close()
    {
        parent::close();
        foreach ($this->fileHandles as $type => $handle) {
            ftruncate($handle, 0);
            fclose($handle);
            flock($this->lockHandles[$type], \LOCK_UN);
            fclose($this->lockHandles[$type]);
        }
        $this->fileHandles = $this->lockHandles = [];
    }
}
PKϤ$Z��AR��'dependency-injection/TypedReference.phpnu�[���<?php

/*
 * This file is part of the Symfony package.
 *
 * (c) Fabien Potencier <fabien@symfony.com>
 *
 * For the full copyright and license information, please view the LICENSE
 * file that was distributed with this source code.
 */

namespace Symfony\Component\DependencyInjection;

/**
 * Represents a PHP type-hinted service reference.
 *
 * @author Nicolas Grekas <p@tchwork.com>
 */
class TypedReference extends Reference
{
    private $type;
    private $name;

    /**
     * @param string $id              The service identifier
     * @param string $type            The PHP type of the identified service
     * @param int    $invalidBehavior The behavior when the service does not exist
     * @param string $name            The name of the argument targeting the service
     */
    public function __construct(string $id, string $type, int $invalidBehavior = ContainerInterface::EXCEPTION_ON_INVALID_REFERENCE, string $name = null)
    {
        $this->name = $type === $id ? $name : null;
        parent::__construct($id, $invalidBehavior);
        $this->type = $type;
    }

    public function getType()
    {
        return $this->type;
    }

    public function getName(): ?string
    {
        return $this->name;
    }
}
PKϤ$Z��F��5dependency-injection/ResettableContainerInterface.phpnu�[���<?php

/*
 * This file is part of the Symfony package.
 *
 * (c) Fabien Potencier <fabien@symfony.com>
 *
 * For the full copyright and license information, please view the LICENSE
 * file that was distributed with this source code.
 */

namespace Symfony\Component\DependencyInjection;

/**
 * ResettableContainerInterface defines additional resetting functionality
 * for containers, allowing to release shared services when the container is
 * not needed anymore.
 *
 * @author Christophe Coevoet <stof@notk.org>
 */
interface ResettableContainerInterface extends ContainerInterface
{
    /**
     * Resets shared services from the container.
     *
     * The container is not intended to be used again after being reset in a normal workflow. This method is
     * meant as a way to release references for ref-counting.
     * A subsequent call to ContainerInterface::get will recreate a new instance of the shared service.
     */
    public function reset();
}
PKϤ$Z����(((dependency-injection/EnvVarProcessor.phpnu�[���<?php

/*
 * This file is part of the Symfony package.
 *
 * (c) Fabien Potencier <fabien@symfony.com>
 *
 * For the full copyright and license information, please view the LICENSE
 * file that was distributed with this source code.
 */

namespace Symfony\Component\DependencyInjection;

use Symfony\Component\DependencyInjection\Exception\EnvNotFoundException;
use Symfony\Component\DependencyInjection\Exception\ParameterCircularReferenceException;
use Symfony\Component\DependencyInjection\Exception\RuntimeException;

/**
 * @author Nicolas Grekas <p@tchwork.com>
 */
class EnvVarProcessor implements EnvVarProcessorInterface
{
    private $container;
    private $loaders;
    private $loadedVars = [];

    /**
     * @param EnvVarLoaderInterface[] $loaders
     */
    public function __construct(ContainerInterface $container, \Traversable $loaders = null)
    {
        $this->container = $container;
        $this->loaders = $loaders ?? new \ArrayIterator();
    }

    /**
     * {@inheritdoc}
     */
    public static function getProvidedTypes()
    {
        return [
            'base64' => 'string',
            'bool' => 'bool',
            'const' => 'bool|int|float|string|array',
            'csv' => 'array',
            'file' => 'string',
            'float' => 'float',
            'int' => 'int',
            'json' => 'array',
            'key' => 'bool|int|float|string|array',
            'url' => 'array',
            'query_string' => 'array',
            'resolve' => 'string',
            'default' => 'bool|int|float|string|array',
            'string' => 'string',
            'trim' => 'string',
            'require' => 'bool|int|float|string|array',
        ];
    }

    /**
     * {@inheritdoc}
     */
    public function getEnv(string $prefix, string $name, \Closure $getEnv)
    {
        $i = strpos($name, ':');

        if ('key' === $prefix) {
            if (false === $i) {
                throw new RuntimeException(sprintf('Invalid env "key:%s": a key specifier should be provided.', $name));
            }

            $next = substr($name, $i + 1);
            $key = substr($name, 0, $i);
            $array = $getEnv($next);

            if (!\is_array($array)) {
                throw new RuntimeException(sprintf('Resolved value of "%s" did not result in an array value.', $next));
            }

            if (!isset($array[$key]) && !\array_key_exists($key, $array)) {
                throw new EnvNotFoundException(sprintf('Key "%s" not found in %s (resolved from "%s").', $key, json_encode($array), $next));
            }

            return $array[$key];
        }

        if ('default' === $prefix) {
            if (false === $i) {
                throw new RuntimeException(sprintf('Invalid env "default:%s": a fallback parameter should be provided.', $name));
            }

            $next = substr($name, $i + 1);
            $default = substr($name, 0, $i);

            if ('' !== $default && !$this->container->hasParameter($default)) {
                throw new RuntimeException(sprintf('Invalid env fallback in "default:%s": parameter "%s" not found.', $name, $default));
            }

            try {
                $env = $getEnv($next);

                if ('' !== $env && null !== $env) {
                    return $env;
                }
            } catch (EnvNotFoundException $e) {
                // no-op
            }

            return '' === $default ? null : $this->container->getParameter($default);
        }

        if ('file' === $prefix || 'require' === $prefix) {
            if (!is_scalar($file = $getEnv($name))) {
                throw new RuntimeException(sprintf('Invalid file name: env var "%s" is non-scalar.', $name));
            }
            if (!is_file($file)) {
                throw new EnvNotFoundException(sprintf('File "%s" not found (resolved from "%s").', $file, $name));
            }

            if ('file' === $prefix) {
                return file_get_contents($file);
            } else {
                return require $file;
            }
        }

        if (false !== $i || 'string' !== $prefix) {
            $env = $getEnv($name);
        } elseif (isset($_ENV[$name])) {
            $env = $_ENV[$name];
        } elseif (isset($_SERVER[$name]) && 0 !== strpos($name, 'HTTP_')) {
            $env = $_SERVER[$name];
        } elseif (false === ($env = getenv($name)) || null === $env) { // null is a possible value because of thread safety issues
            foreach ($this->loadedVars as $vars) {
                if (false !== $env = ($vars[$name] ?? false)) {
                    break;
                }
            }

            if (false === $env || null === $env) {
                $loaders = $this->loaders;
                $this->loaders = new \ArrayIterator();

                try {
                    $i = 0;
                    $ended = true;
                    $count = $loaders instanceof \Countable ? $loaders->count() : 0;
                    foreach ($loaders as $loader) {
                        if (\count($this->loadedVars) > $i++) {
                            continue;
                        }
                        $this->loadedVars[] = $vars = $loader->loadEnvVars();
                        if (false !== $env = $vars[$name] ?? false) {
                            $ended = false;
                            break;
                        }
                    }
                    if ($ended || $count === $i) {
                        $loaders = $this->loaders;
                    }
                } catch (ParameterCircularReferenceException $e) {
                    // skip loaders that need an env var that is not defined
                } finally {
                    $this->loaders = $loaders;
                }
            }

            if (false === $env || null === $env) {
                if (!$this->container->hasParameter("env($name)")) {
                    throw new EnvNotFoundException(sprintf('Environment variable not found: "%s".', $name));
                }

                $env = $this->container->getParameter("env($name)");
            }
        }

        if (null === $env) {
            if (!isset($this->getProvidedTypes()[$prefix])) {
                throw new RuntimeException(sprintf('Unsupported env var prefix "%s".', $prefix));
            }

            return null;
        }

        if (!is_scalar($env)) {
            throw new RuntimeException(sprintf('Non-scalar env var "%s" cannot be cast to "%s".', $name, $prefix));
        }

        if ('string' === $prefix) {
            return (string) $env;
        }

        if ('bool' === $prefix) {
            return (bool) (filter_var($env, \FILTER_VALIDATE_BOOLEAN) ?: filter_var($env, \FILTER_VALIDATE_INT) ?: filter_var($env, \FILTER_VALIDATE_FLOAT));
        }

        if ('int' === $prefix) {
            if (false === $env = filter_var($env, \FILTER_VALIDATE_INT) ?: filter_var($env, \FILTER_VALIDATE_FLOAT)) {
                throw new RuntimeException(sprintf('Non-numeric env var "%s" cannot be cast to int.', $name));
            }

            return (int) $env;
        }

        if ('float' === $prefix) {
            if (false === $env = filter_var($env, \FILTER_VALIDATE_FLOAT)) {
                throw new RuntimeException(sprintf('Non-numeric env var "%s" cannot be cast to float.', $name));
            }

            return (float) $env;
        }

        if ('const' === $prefix) {
            if (!\defined($env)) {
                throw new RuntimeException(sprintf('Env var "%s" maps to undefined constant "%s".', $name, $env));
            }

            return \constant($env);
        }

        if ('base64' === $prefix) {
            return base64_decode(strtr($env, '-_', '+/'));
        }

        if ('json' === $prefix) {
            $env = json_decode($env, true);

            if (\JSON_ERROR_NONE !== json_last_error()) {
                throw new RuntimeException(sprintf('Invalid JSON in env var "%s": ', $name).json_last_error_msg());
            }

            if (null !== $env && !\is_array($env)) {
                throw new RuntimeException(sprintf('Invalid JSON env var "%s": array or null expected, "%s" given.', $name, get_debug_type($env)));
            }

            return $env;
        }

        if ('url' === $prefix) {
            $parsedEnv = parse_url($env);

            if (false === $parsedEnv) {
                throw new RuntimeException(sprintf('Invalid URL in env var "%s".', $name));
            }
            if (!isset($parsedEnv['scheme'], $parsedEnv['host'])) {
                throw new RuntimeException(sprintf('Invalid URL env var "%s": schema and host expected, "%s" given.', $name, $env));
            }
            $parsedEnv += [
                'port' => null,
                'user' => null,
                'pass' => null,
                'path' => null,
                'query' => null,
                'fragment' => null,
            ];

            // remove the '/' separator
            $parsedEnv['path'] = '/' === $parsedEnv['path'] ? null : substr($parsedEnv['path'], 1);

            return $parsedEnv;
        }

        if ('query_string' === $prefix) {
            $queryString = parse_url($env, \PHP_URL_QUERY) ?: $env;
            parse_str($queryString, $result);

            return $result;
        }

        if ('resolve' === $prefix) {
            return preg_replace_callback('/%%|%([^%\s]+)%/', function ($match) use ($name) {
                if (!isset($match[1])) {
                    return '%';
                }
                $value = $this->container->getParameter($match[1]);
                if (!is_scalar($value)) {
                    throw new RuntimeException(sprintf('Parameter "%s" found when resolving env var "%s" must be scalar, "%s" given.', $match[1], $name, get_debug_type($value)));
                }

                return $value;
            }, $env);
        }

        if ('csv' === $prefix) {
            return str_getcsv($env, ',', '"', \PHP_VERSION_ID >= 70400 ? '' : '\\');
        }

        if ('trim' === $prefix) {
            return trim($env);
        }

        throw new RuntimeException(sprintf('Unsupported env var prefix "%s".', $prefix));
    }
}
PKϤ$Z����6dependency-injection/Tests/DefinitionDecoratorTest.phpnu�[���<?php

/*
 * This file is part of the Symfony package.
 *
 * (c) Fabien Potencier <fabien@symfony.com>
 *
 * For the full copyright and license information, please view the LICENSE
 * file that was distributed with this source code.
 */

namespace Symfony\Component\DependencyInjection\Tests;

use Symfony\Component\DependencyInjection\DefinitionDecorator;

class DefinitionDecoratorTest extends \PHPUnit_Framework_TestCase
{
    public function testConstructor()
    {
        $def = new DefinitionDecorator('foo');

        $this->assertEquals('foo', $def->getParent());
        $this->assertEquals(array(), $def->getChanges());
    }

    /**
     * @dataProvider getPropertyTests
     */
    public function testSetProperty($property, $changeKey)
    {
        $def = new DefinitionDecorator('foo');

        $getter = 'get'.ucfirst($property);
        $setter = 'set'.ucfirst($property);

        $this->assertNull($def->$getter());
        $this->assertSame($def, $def->$setter('foo'));
        $this->assertEquals('foo', $def->$getter());
        $this->assertEquals(array($changeKey => true), $def->getChanges());
    }

    public function getPropertyTests()
    {
        return array(
            array('class', 'class'),
            array('factory', 'factory'),
            array('configurator', 'configurator'),
            array('file', 'file'),
        );
    }

    public function testSetPublic()
    {
        $def = new DefinitionDecorator('foo');

        $this->assertTrue($def->isPublic());
        $this->assertSame($def, $def->setPublic(false));
        $this->assertFalse($def->isPublic());
        $this->assertEquals(array('public' => true), $def->getChanges());
    }

    public function testSetLazy()
    {
        $def = new DefinitionDecorator('foo');

        $this->assertFalse($def->isLazy());
        $this->assertSame($def, $def->setLazy(false));
        $this->assertFalse($def->isLazy());
        $this->assertEquals(array('lazy' => true), $def->getChanges());
    }

    public function testSetAutowired()
    {
        $def = new DefinitionDecorator('foo');

        $this->assertFalse($def->isAutowired());
        $this->assertSame($def, $def->setAutowired(false));
        $this->assertFalse($def->isAutowired());
        $this->assertEquals(array('autowire' => true), $def->getChanges());
    }

    public function testSetArgument()
    {
        $def = new DefinitionDecorator('foo');

        $this->assertEquals(array(), $def->getArguments());
        $this->assertSame($def, $def->replaceArgument(0, 'foo'));
        $this->assertEquals(array('index_0' => 'foo'), $def->getArguments());
    }

    /**
     * @expectedException \InvalidArgumentException
     */
    public function testReplaceArgumentShouldRequireIntegerIndex()
    {
        $def = new DefinitionDecorator('foo');

        $def->replaceArgument('0', 'foo');
    }

    public function testReplaceArgument()
    {
        $def = new DefinitionDecorator('foo');

        $def->setArguments(array(0 => 'foo', 1 => 'bar'));
        $this->assertEquals('foo', $def->getArgument(0));
        $this->assertEquals('bar', $def->getArgument(1));

        $this->assertSame($def, $def->replaceArgument(1, 'baz'));
        $this->assertEquals('foo', $def->getArgument(0));
        $this->assertEquals('baz', $def->getArgument(1));

        $this->assertEquals(array(0 => 'foo', 1 => 'bar', 'index_1' => 'baz'), $def->getArguments());
    }

    /**
     * @expectedException \OutOfBoundsException
     */
    public function testGetArgumentShouldCheckBounds()
    {
        $def = new DefinitionDecorator('foo');

        $def->setArguments(array(0 => 'foo'));
        $def->replaceArgument(0, 'foo');

        $def->getArgument(1);
    }
}
PKϤ$Z^'`�5�5-dependency-injection/Tests/DefinitionTest.phpnu�[���<?php

/*
 * This file is part of the Symfony package.
 *
 * (c) Fabien Potencier <fabien@symfony.com>
 *
 * For the full copyright and license information, please view the LICENSE
 * file that was distributed with this source code.
 */

namespace Symfony\Component\DependencyInjection\Tests;

use Symfony\Component\DependencyInjection\Definition;

class DefinitionTest extends \PHPUnit_Framework_TestCase
{
    public function testConstructor()
    {
        $def = new Definition('stdClass');
        $this->assertEquals('stdClass', $def->getClass(), '__construct() takes the class name as its first argument');

        $def = new Definition('stdClass', array('foo'));
        $this->assertEquals(array('foo'), $def->getArguments(), '__construct() takes an optional array of arguments as its second argument');
    }

    public function testSetGetFactory()
    {
        $def = new Definition('stdClass');

        $this->assertSame($def, $def->setFactory('foo'), '->setFactory() implements a fluent interface');
        $this->assertEquals('foo', $def->getFactory(), '->getFactory() returns the factory');

        $def->setFactory('Foo::bar');
        $this->assertEquals(array('Foo', 'bar'), $def->getFactory(), '->setFactory() converts string static method call to the array');
    }

    public function testSetGetClass()
    {
        $def = new Definition('stdClass');
        $this->assertSame($def, $def->setClass('foo'), '->setClass() implements a fluent interface');
        $this->assertEquals('foo', $def->getClass(), '->getClass() returns the class name');
    }

    public function testSetGetDecoratedService()
    {
        $def = new Definition('stdClass');
        $this->assertNull($def->getDecoratedService());
        $def->setDecoratedService('foo', 'foo.renamed', 5);
        $this->assertEquals(array('foo', 'foo.renamed', 5), $def->getDecoratedService());
        $def->setDecoratedService(null);
        $this->assertNull($def->getDecoratedService());

        $def = new Definition('stdClass');
        $this->assertNull($def->getDecoratedService());
        $def->setDecoratedService('foo', 'foo.renamed');
        $this->assertEquals(array('foo', 'foo.renamed', 0), $def->getDecoratedService());
        $def->setDecoratedService(null);
        $this->assertNull($def->getDecoratedService());

        $def = new Definition('stdClass');
        $def->setDecoratedService('foo');
        $this->assertEquals(array('foo', null, 0), $def->getDecoratedService());
        $def->setDecoratedService(null);
        $this->assertNull($def->getDecoratedService());

        $def = new Definition('stdClass');
        $this->setExpectedException('InvalidArgumentException', 'The decorated service inner name for "foo" must be different than the service name itself.');
        $def->setDecoratedService('foo', 'foo');
    }

    public function testArguments()
    {
        $def = new Definition('stdClass');
        $this->assertSame($def, $def->setArguments(array('foo')), '->setArguments() implements a fluent interface');
        $this->assertEquals(array('foo'), $def->getArguments(), '->getArguments() returns the arguments');
        $this->assertSame($def, $def->addArgument('bar'), '->addArgument() implements a fluent interface');
        $this->assertEquals(array('foo', 'bar'), $def->getArguments(), '->addArgument() adds an argument');
    }

    public function testMethodCalls()
    {
        $def = new Definition('stdClass');
        $this->assertSame($def, $def->setMethodCalls(array(array('foo', array('foo')))), '->setMethodCalls() implements a fluent interface');
        $this->assertEquals(array(array('foo', array('foo'))), $def->getMethodCalls(), '->getMethodCalls() returns the methods to call');
        $this->assertSame($def, $def->addMethodCall('bar', array('bar')), '->addMethodCall() implements a fluent interface');
        $this->assertEquals(array(array('foo', array('foo')), array('bar', array('bar'))), $def->getMethodCalls(), '->addMethodCall() adds a method to call');
        $this->assertTrue($def->hasMethodCall('bar'), '->hasMethodCall() returns true if first argument is a method to call registered');
        $this->assertFalse($def->hasMethodCall('no_registered'), '->hasMethodCall() returns false if first argument is not a method to call registered');
        $this->assertSame($def, $def->removeMethodCall('bar'), '->removeMethodCall() implements a fluent interface');
        $this->assertEquals(array(array('foo', array('foo'))), $def->getMethodCalls(), '->removeMethodCall() removes a method to call');
    }

    /**
     * @expectedException \Symfony\Component\DependencyInjection\Exception\InvalidArgumentException
     * @expectedExceptionMessage Method name cannot be empty.
     */
    public function testExceptionOnEmptyMethodCall()
    {
        $def = new Definition('stdClass');
        $def->addMethodCall('');
    }

    public function testSetGetFile()
    {
        $def = new Definition('stdClass');
        $this->assertSame($def, $def->setFile('foo'), '->setFile() implements a fluent interface');
        $this->assertEquals('foo', $def->getFile(), '->getFile() returns the file to include');
    }

    public function testSetIsShared()
    {
        $def = new Definition('stdClass');
        $this->assertTrue($def->isShared(), '->isShared() returns true by default');
        $this->assertSame($def, $def->setShared(false), '->setShared() implements a fluent interface');
        $this->assertFalse($def->isShared(), '->isShared() returns false if the instance must not be shared');
    }

    public function testSetIsPublic()
    {
        $def = new Definition('stdClass');
        $this->assertTrue($def->isPublic(), '->isPublic() returns true by default');
        $this->assertSame($def, $def->setPublic(false), '->setPublic() implements a fluent interface');
        $this->assertFalse($def->isPublic(), '->isPublic() returns false if the instance must not be public.');
    }

    public function testSetIsSynthetic()
    {
        $def = new Definition('stdClass');
        $this->assertFalse($def->isSynthetic(), '->isSynthetic() returns false by default');
        $this->assertSame($def, $def->setSynthetic(true), '->setSynthetic() implements a fluent interface');
        $this->assertTrue($def->isSynthetic(), '->isSynthetic() returns true if the service is synthetic.');
    }

    public function testSetIsLazy()
    {
        $def = new Definition('stdClass');
        $this->assertFalse($def->isLazy(), '->isLazy() returns false by default');
        $this->assertSame($def, $def->setLazy(true), '->setLazy() implements a fluent interface');
        $this->assertTrue($def->isLazy(), '->isLazy() returns true if the service is lazy.');
    }

    public function testSetIsAbstract()
    {
        $def = new Definition('stdClass');
        $this->assertFalse($def->isAbstract(), '->isAbstract() returns false by default');
        $this->assertSame($def, $def->setAbstract(true), '->setAbstract() implements a fluent interface');
        $this->assertTrue($def->isAbstract(), '->isAbstract() returns true if the instance must not be public.');
    }

    public function testSetIsDeprecated()
    {
        $def = new Definition('stdClass');
        $this->assertFalse($def->isDeprecated(), '->isDeprecated() returns false by default');
        $this->assertSame($def, $def->setDeprecated(true), '->setDeprecated() implements a fluent interface');
        $this->assertTrue($def->isDeprecated(), '->isDeprecated() returns true if the instance should not be used anymore.');
        $this->assertSame('The "deprecated_service" service is deprecated. You should stop using it, as it will soon be removed.', $def->getDeprecationMessage('deprecated_service'), '->getDeprecationMessage() should return a formatted message template');
    }

    /**
     * @dataProvider invalidDeprecationMessageProvider
     * @expectedException \Symfony\Component\DependencyInjection\Exception\InvalidArgumentException
     */
    public function testSetDeprecatedWithInvalidDeprecationTemplate($message)
    {
        $def = new Definition('stdClass');
        $def->setDeprecated(false, $message);
    }

    public function invalidDeprecationMessageProvider()
    {
        return array(
            "With \rs" => array("invalid \r message %service_id%"),
            "With \ns" => array("invalid \n message %service_id%"),
            'With */s' => array('invalid */ message %service_id%'),
            'message not containing require %service_id% variable' => array('this is deprecated'),
        );
    }

    public function testSetGetConfigurator()
    {
        $def = new Definition('stdClass');
        $this->assertSame($def, $def->setConfigurator('foo'), '->setConfigurator() implements a fluent interface');
        $this->assertEquals('foo', $def->getConfigurator(), '->getConfigurator() returns the configurator');
    }

    public function testClearTags()
    {
        $def = new Definition('stdClass');
        $this->assertSame($def, $def->clearTags(), '->clearTags() implements a fluent interface');
        $def->addTag('foo', array('foo' => 'bar'));
        $def->clearTags();
        $this->assertEquals(array(), $def->getTags(), '->clearTags() removes all current tags');
    }

    public function testClearTag()
    {
        $def = new Definition('stdClass');
        $this->assertSame($def, $def->clearTags(), '->clearTags() implements a fluent interface');
        $def->addTag('1foo1', array('foo1' => 'bar1'));
        $def->addTag('2foo2', array('foo2' => 'bar2'));
        $def->addTag('3foo3', array('foo3' => 'bar3'));
        $def->clearTag('2foo2');
        $this->assertTrue($def->hasTag('1foo1'));
        $this->assertFalse($def->hasTag('2foo2'));
        $this->assertTrue($def->hasTag('3foo3'));
        $def->clearTag('1foo1');
        $this->assertFalse($def->hasTag('1foo1'));
        $this->assertTrue($def->hasTag('3foo3'));
    }

    public function testTags()
    {
        $def = new Definition('stdClass');
        $this->assertEquals(array(), $def->getTag('foo'), '->getTag() returns an empty array if the tag is not defined');
        $this->assertFalse($def->hasTag('foo'));
        $this->assertSame($def, $def->addTag('foo'), '->addTag() implements a fluent interface');
        $this->assertTrue($def->hasTag('foo'));
        $this->assertEquals(array(array()), $def->getTag('foo'), '->getTag() returns attributes for a tag name');
        $def->addTag('foo', array('foo' => 'bar'));
        $this->assertEquals(array(array(), array('foo' => 'bar')), $def->getTag('foo'), '->addTag() can adds the same tag several times');
        $def->addTag('bar', array('bar' => 'bar'));
        $this->assertEquals($def->getTags(), array(
            'foo' => array(array(), array('foo' => 'bar')),
            'bar' => array(array('bar' => 'bar')),
        ), '->getTags() returns all tags');
    }

    public function testSetArgument()
    {
        $def = new Definition('stdClass');

        $def->addArgument('foo');
        $this->assertSame(array('foo'), $def->getArguments());

        $this->assertSame($def, $def->replaceArgument(0, 'moo'));
        $this->assertSame(array('moo'), $def->getArguments());

        $def->addArgument('moo');
        $def
            ->replaceArgument(0, 'foo')
            ->replaceArgument(1, 'bar')
        ;
        $this->assertSame(array('foo', 'bar'), $def->getArguments());
    }

    /**
     * @expectedException \OutOfBoundsException
     */
    public function testGetArgumentShouldCheckBounds()
    {
        $def = new Definition('stdClass');

        $def->addArgument('foo');
        $def->getArgument(1);
    }

    /**
     * @expectedException \OutOfBoundsException
     * @expectedExceptionMessage The index "1" is not in the range [0, 0].
     */
    public function testReplaceArgumentShouldCheckBounds()
    {
        $def = new Definition('stdClass');

        $def->addArgument('foo');
        $def->replaceArgument(1, 'bar');
    }

    /**
     * @expectedException \OutOfBoundsException
     * @expectedExceptionMessage Cannot replace arguments if none have been configured yet.
     */
    public function testReplaceArgumentWithoutExistingArgumentsShouldCheckBounds()
    {
        $def = new Definition('stdClass');
        $def->replaceArgument(0, 'bar');
    }

    public function testSetGetProperties()
    {
        $def = new Definition('stdClass');

        $this->assertEquals(array(), $def->getProperties());
        $this->assertSame($def, $def->setProperties(array('foo' => 'bar')));
        $this->assertEquals(array('foo' => 'bar'), $def->getProperties());
    }

    public function testSetProperty()
    {
        $def = new Definition('stdClass');

        $this->assertEquals(array(), $def->getProperties());
        $this->assertSame($def, $def->setProperty('foo', 'bar'));
        $this->assertEquals(array('foo' => 'bar'), $def->getProperties());
    }

    public function testAutowired()
    {
        $def = new Definition('stdClass');
        $this->assertFalse($def->isAutowired());
        $def->setAutowired(true);
        $this->assertTrue($def->isAutowired());
    }

    public function testTypes()
    {
        $def = new Definition('stdClass');

        $this->assertEquals(array(), $def->getAutowiringTypes());
        $this->assertSame($def, $def->setAutowiringTypes(array('Foo')));
        $this->assertEquals(array('Foo'), $def->getAutowiringTypes());
        $this->assertSame($def, $def->addAutowiringType('Bar'));
        $this->assertTrue($def->hasAutowiringType('Bar'));
        $this->assertSame($def, $def->removeAutowiringType('Foo'));
        $this->assertEquals(array('Bar'), $def->getAutowiringTypes());
    }
}
PKϤ$Z�!�1��-dependency-injection/Tests/CrossCheckTest.phpnu�[���<?php

/*
 * This file is part of the Symfony package.
 *
 * (c) Fabien Potencier <fabien@symfony.com>
 *
 * For the full copyright and license information, please view the LICENSE
 * file that was distributed with this source code.
 */

namespace Symfony\Component\DependencyInjection\Tests;

use Symfony\Component\DependencyInjection\ContainerBuilder;
use Symfony\Component\Config\FileLocator;

class CrossCheckTest extends \PHPUnit_Framework_TestCase
{
    protected static $fixturesPath;

    public static function setUpBeforeClass()
    {
        self::$fixturesPath = __DIR__.'/Fixtures/';

        require_once self::$fixturesPath.'/includes/classes.php';
        require_once self::$fixturesPath.'/includes/foo.php';
    }

    /**
     * @dataProvider crossCheckLoadersDumpers
     */
    public function testCrossCheck($fixture, $type)
    {
        $loaderClass = 'Symfony\\Component\\DependencyInjection\\Loader\\'.ucfirst($type).'FileLoader';
        $dumperClass = 'Symfony\\Component\\DependencyInjection\\Dumper\\'.ucfirst($type).'Dumper';

        $tmp = tempnam(sys_get_temp_dir(), 'sf');

        file_put_contents($tmp, file_get_contents(self::$fixturesPath.'/'.$type.'/'.$fixture));

        $container1 = new ContainerBuilder();
        $loader1 = new $loaderClass($container1, new FileLocator());
        $loader1->load($tmp);

        $dumper = new $dumperClass($container1);
        file_put_contents($tmp, $dumper->dump());

        $container2 = new ContainerBuilder();
        $loader2 = new $loaderClass($container2, new FileLocator());
        $loader2->load($tmp);

        unlink($tmp);

        $this->assertEquals($container2->getAliases(), $container1->getAliases(), 'loading a dump from a previously loaded container returns the same container');
        $this->assertEquals($container2->getDefinitions(), $container1->getDefinitions(), 'loading a dump from a previously loaded container returns the same container');
        $this->assertEquals($container2->getParameterBag()->all(), $container1->getParameterBag()->all(), '->getParameterBag() returns the same value for both containers');

        $this->assertEquals(serialize($container2), serialize($container1), 'loading a dump from a previously loaded container returns the same container');

        $services1 = array();
        foreach ($container1 as $id => $service) {
            $services1[$id] = serialize($service);
        }
        $services2 = array();
        foreach ($container2 as $id => $service) {
            $services2[$id] = serialize($service);
        }

        unset($services1['service_container'], $services2['service_container']);

        $this->assertEquals($services2, $services1, 'Iterator on the containers returns the same services');
    }

    public function crossCheckLoadersDumpers()
    {
        return array(
            array('services1.xml', 'xml'),
            array('services2.xml', 'xml'),
            array('services6.xml', 'xml'),
            array('services8.xml', 'xml'),
            array('services9.xml', 'xml'),
            array('services1.yml', 'yaml'),
            array('services2.yml', 'yaml'),
            array('services6.yml', 'yaml'),
            array('services8.yml', 'yaml'),
            array('services9.yml', 'yaml'),
        );
    }
}
PKϤ$Z��2�{{,dependency-injection/Tests/ParameterTest.phpnu�[���<?php

/*
 * This file is part of the Symfony package.
 *
 * (c) Fabien Potencier <fabien@symfony.com>
 *
 * For the full copyright and license information, please view the LICENSE
 * file that was distributed with this source code.
 */

namespace Symfony\Component\DependencyInjection\Tests;

use Symfony\Component\DependencyInjection\Parameter;

class ParameterTest extends \PHPUnit_Framework_TestCase
{
    public function testConstructor()
    {
        $ref = new Parameter('foo');
        $this->assertEquals('foo', (string) $ref, '__construct() sets the id of the parameter, which is used for the __toString() method');
    }
}
PKϤ$Za��`�	�	6dependency-injection/Tests/Extension/ExtensionTest.phpnu�[���<?php

/*
 * This file is part of the Symfony package.
 *
 * (c) Fabien Potencier <fabien@symfony.com>
 *
 * For the full copyright and license information, please view the LICENSE
 * file that was distributed with this source code.
 */

namespace Symfony\Component\DependencyInjection\Tests\Extension;

class ExtensionTest extends \PHPUnit_Framework_TestCase
{
    /**
     * @dataProvider getResolvedEnabledFixtures
     */
    public function testIsConfigEnabledReturnsTheResolvedValue($enabled)
    {
        $pb = $this->getMockBuilder('Symfony\Component\DependencyInjection\ParameterBag\ParameterBag')
            ->setMethods(array('resolveValue'))
            ->getMock()
        ;

        $container = $this->getMockBuilder('Symfony\Component\DependencyInjection\ContainerBuilder')
            ->setMethods(array('getParameterBag'))
            ->getMock()
        ;

        $pb->expects($this->once())
            ->method('resolveValue')
            ->with($this->equalTo($enabled))
            ->will($this->returnValue($enabled))
        ;

        $container->expects($this->once())
            ->method('getParameterBag')
            ->will($this->returnValue($pb))
        ;

        $extension = $this->getMockBuilder('Symfony\Component\DependencyInjection\Extension\Extension')
            ->setMethods(array())
            ->getMockForAbstractClass()
        ;

        $r = new \ReflectionMethod('Symfony\Component\DependencyInjection\Extension\Extension', 'isConfigEnabled');
        $r->setAccessible(true);

        $r->invoke($extension, $container, array('enabled' => $enabled));
    }

    public function getResolvedEnabledFixtures()
    {
        return array(
            array(true),
            array(false),
        );
    }

    /**
     * @expectedException \Symfony\Component\DependencyInjection\Exception\InvalidArgumentException
     * @expectedExceptionMessage The config array has no 'enabled' key.
     */
    public function testIsConfigEnabledOnNonEnableableConfig()
    {
        $container = $this->getMockBuilder('Symfony\Component\DependencyInjection\ContainerBuilder')
            ->getMock()
        ;

        $extension = $this->getMockBuilder('Symfony\Component\DependencyInjection\Extension\Extension')
            ->setMethods(array())
            ->getMockForAbstractClass()
        ;

        $r = new \ReflectionMethod('Symfony\Component\DependencyInjection\Extension\Extension', 'isConfigEnabled');
        $r->setAccessible(true);

        $r->invoke($extension, $container, array());
    }
}
PKϤ$Z-r�5��7dependency-injection/Tests/Loader/PhpFileLoaderTest.phpnu�[���<?php

/*
 * This file is part of the Symfony package.
 *
 * (c) Fabien Potencier <fabien@symfony.com>
 *
 * For the full copyright and license information, please view the LICENSE
 * file that was distributed with this source code.
 */

namespace Symfony\Component\DependencyInjection\Tests\Loader;

use Symfony\Component\DependencyInjection\ContainerBuilder;
use Symfony\Component\DependencyInjection\Loader\PhpFileLoader;
use Symfony\Component\Config\FileLocator;

class PhpFileLoaderTest extends \PHPUnit_Framework_TestCase
{
    public function testSupports()
    {
        $loader = new PhpFileLoader(new ContainerBuilder(), new FileLocator());

        $this->assertTrue($loader->supports('foo.php'), '->supports() returns true if the resource is loadable');
        $this->assertFalse($loader->supports('foo.foo'), '->supports() returns true if the resource is loadable');
    }

    public function testLoad()
    {
        $loader = new PhpFileLoader($container = new ContainerBuilder(), new FileLocator());

        $loader->load(__DIR__.'/../Fixtures/php/simple.php');

        $this->assertEquals('foo', $container->getParameter('foo'), '->load() loads a PHP file resource');
    }
}
PKϤ$Z��͐|�|7dependency-injection/Tests/Loader/XmlFileLoaderTest.phpnu�[���<?php

/*
 * This file is part of the Symfony package.
 *
 * (c) Fabien Potencier <fabien@symfony.com>
 *
 * For the full copyright and license information, please view the LICENSE
 * file that was distributed with this source code.
 */

namespace Symfony\Component\DependencyInjection\Tests\Loader;

use Symfony\Component\DependencyInjection\ContainerInterface;
use Symfony\Component\DependencyInjection\ContainerBuilder;
use Symfony\Component\DependencyInjection\Reference;
use Symfony\Component\DependencyInjection\Loader\XmlFileLoader;
use Symfony\Component\DependencyInjection\Loader\YamlFileLoader;
use Symfony\Component\DependencyInjection\Loader\IniFileLoader;
use Symfony\Component\Config\Loader\LoaderResolver;
use Symfony\Component\Config\FileLocator;
use Symfony\Component\ExpressionLanguage\Expression;

class XmlFileLoaderTest extends \PHPUnit_Framework_TestCase
{
    protected static $fixturesPath;

    public static function setUpBeforeClass()
    {
        self::$fixturesPath = realpath(__DIR__.'/../Fixtures/');
        require_once self::$fixturesPath.'/includes/foo.php';
        require_once self::$fixturesPath.'/includes/ProjectExtension.php';
        require_once self::$fixturesPath.'/includes/ProjectWithXsdExtension.php';
    }

    public function testLoad()
    {
        $loader = new XmlFileLoader(new ContainerBuilder(), new FileLocator(self::$fixturesPath.'/ini'));

        try {
            $loader->load('foo.xml');
            $this->fail('->load() throws an InvalidArgumentException if the loaded file does not exist');
        } catch (\Exception $e) {
            $this->assertInstanceOf('InvalidArgumentException', $e, '->load() throws an InvalidArgumentException if the loaded file does not exist');
            $this->assertStringStartsWith('The file "foo.xml" does not exist (in:', $e->getMessage(), '->load() throws an InvalidArgumentException if the loaded file does not exist');
        }
    }

    public function testParseFile()
    {
        $loader = new XmlFileLoader(new ContainerBuilder(), new FileLocator(self::$fixturesPath.'/ini'));
        $r = new \ReflectionObject($loader);
        $m = $r->getMethod('parseFileToDOM');
        $m->setAccessible(true);

        try {
            $m->invoke($loader, self::$fixturesPath.'/ini/parameters.ini');
            $this->fail('->parseFileToDOM() throws an InvalidArgumentException if the loaded file is not a valid XML file');
        } catch (\Exception $e) {
            $this->assertInstanceOf('Symfony\\Component\\DependencyInjection\\Exception\\InvalidArgumentException', $e, '->parseFileToDOM() throws an InvalidArgumentException if the loaded file is not a valid XML file');
            $this->assertRegExp(sprintf('#^Unable to parse file ".+%s".$#', 'parameters.ini'), $e->getMessage(), '->parseFileToDOM() throws an InvalidArgumentException if the loaded file is not a valid XML file');

            $e = $e->getPrevious();
            $this->assertInstanceOf('InvalidArgumentException', $e, '->parseFileToDOM() throws an InvalidArgumentException if the loaded file is not a valid XML file');
            $this->assertStringStartsWith('[ERROR 4] Start tag expected, \'<\' not found (in', $e->getMessage(), '->parseFileToDOM() throws an InvalidArgumentException if the loaded file is not a valid XML file');
        }

        $loader = new XmlFileLoader(new ContainerBuilder(), new FileLocator(self::$fixturesPath.'/xml'));

        try {
            $m->invoke($loader, self::$fixturesPath.'/xml/nonvalid.xml');
            $this->fail('->parseFileToDOM() throws an InvalidArgumentException if the loaded file does not validate the XSD');
        } catch (\Exception $e) {
            $this->assertInstanceOf('Symfony\\Component\\DependencyInjection\\Exception\\InvalidArgumentException', $e, '->parseFileToDOM() throws an InvalidArgumentException if the loaded file does not validate the XSD');
            $this->assertRegExp(sprintf('#^Unable to parse file ".+%s".$#', 'nonvalid.xml'), $e->getMessage(), '->parseFileToDOM() throws an InvalidArgumentException if the loaded file is not a valid XML file');

            $e = $e->getPrevious();
            $this->assertInstanceOf('InvalidArgumentException', $e, '->parseFileToDOM() throws an InvalidArgumentException if the loaded file does not validate the XSD');
            $this->assertStringStartsWith('[ERROR 1845] Element \'nonvalid\': No matching global declaration available for the validation root. (in', $e->getMessage(), '->parseFileToDOM() throws an InvalidArgumentException if the loaded file does not validate the XSD');
        }

        $xml = $m->invoke($loader, self::$fixturesPath.'/xml/services1.xml');
        $this->assertInstanceOf('DOMDocument', $xml, '->parseFileToDOM() returns an SimpleXMLElement object');
    }

    public function testLoadWithExternalEntitiesDisabled()
    {
        $disableEntities = libxml_disable_entity_loader(true);

        $containerBuilder = new ContainerBuilder();
        $loader = new XmlFileLoader($containerBuilder, new FileLocator(self::$fixturesPath.'/xml'));
        $loader->load('services2.xml');

        libxml_disable_entity_loader($disableEntities);

        $this->assertTrue(count($containerBuilder->getParameterBag()->all()) > 0, 'Parameters can be read from the config file.');
    }

    public function testLoadParameters()
    {
        $container = new ContainerBuilder();
        $loader = new XmlFileLoader($container, new FileLocator(self::$fixturesPath.'/xml'));
        $loader->load('services2.xml');

        $actual = $container->getParameterBag()->all();
        $expected = array(
            'a string',
            'foo' => 'bar',
            'values' => array(
                0,
                'integer' => 4,
                100 => null,
                'true',
                true,
                false,
                'on',
                'off',
                'float' => 1.3,
                1000.3,
                'a string',
                array('foo', 'bar'),
            ),
            'mixedcase' => array('MixedCaseKey' => 'value'),
            'constant' => PHP_EOL,
        );

        $this->assertEquals($expected, $actual, '->load() converts XML values to PHP ones');
    }

    public function testLoadImports()
    {
        $container = new ContainerBuilder();
        $resolver = new LoaderResolver(array(
            new IniFileLoader($container, new FileLocator(self::$fixturesPath.'/ini')),
            new YamlFileLoader($container, new FileLocator(self::$fixturesPath.'/yml')),
            $loader = new XmlFileLoader($container, new FileLocator(self::$fixturesPath.'/xml')),
        ));
        $loader->setResolver($resolver);
        $loader->load('services4.xml');

        $actual = $container->getParameterBag()->all();
        $expected = array(
            'a string',
            'foo' => 'bar',
            'values' => array(
                0,
                'integer' => 4,
                100 => null,
                'true',
                true,
                false,
                'on',
                'off',
                'float' => 1.3,
                1000.3,
                'a string',
                array('foo', 'bar'),
            ),
            'mixedcase' => array('MixedCaseKey' => 'value'),
            'constant' => PHP_EOL,
            'bar' => '%foo%',
            'imported_from_ini' => true,
            'imported_from_yaml' => true,
        );

        $this->assertEquals(array_keys($expected), array_keys($actual), '->load() imports and merges imported files');

        // Bad import throws no exception due to ignore_errors value.
        $loader->load('services4_bad_import.xml');
    }

    public function testLoadAnonymousServices()
    {
        $container = new ContainerBuilder();
        $loader = new XmlFileLoader($container, new FileLocator(self::$fixturesPath.'/xml'));
        $loader->load('services5.xml');
        $services = $container->getDefinitions();
        $this->assertCount(6, $services, '->load() attributes unique ids to anonymous services');

        // anonymous service as an argument
        $args = $services['foo']->getArguments();
        $this->assertCount(1, $args, '->load() references anonymous services as "normal" ones');
        $this->assertInstanceOf('Symfony\\Component\\DependencyInjection\\Reference', $args[0], '->load() converts anonymous services to references to "normal" services');
        $this->assertTrue(isset($services[(string) $args[0]]), '->load() makes a reference to the created ones');
        $inner = $services[(string) $args[0]];
        $this->assertEquals('BarClass', $inner->getClass(), '->load() uses the same configuration as for the anonymous ones');
        $this->assertFalse($inner->isPublic());

        // inner anonymous services
        $args = $inner->getArguments();
        $this->assertCount(1, $args, '->load() references anonymous services as "normal" ones');
        $this->assertInstanceOf('Symfony\\Component\\DependencyInjection\\Reference', $args[0], '->load() converts anonymous services to references to "normal" services');
        $this->assertTrue(isset($services[(string) $args[0]]), '->load() makes a reference to the created ones');
        $inner = $services[(string) $args[0]];
        $this->assertEquals('BazClass', $inner->getClass(), '->load() uses the same configuration as for the anonymous ones');
        $this->assertFalse($inner->isPublic());

        // anonymous service as a property
        $properties = $services['foo']->getProperties();
        $property = $properties['p'];
        $this->assertInstanceOf('Symfony\\Component\\DependencyInjection\\Reference', $property, '->load() converts anonymous services to references to "normal" services');
        $this->assertTrue(isset($services[(string) $property]), '->load() makes a reference to the created ones');
        $inner = $services[(string) $property];
        $this->assertEquals('BuzClass', $inner->getClass(), '->load() uses the same configuration as for the anonymous ones');
        $this->assertFalse($inner->isPublic());

        // "wild" service
        $service = $container->findTaggedServiceIds('biz_tag');
        $this->assertCount(1, $service);

        foreach ($service as $id => $tag) {
            $service = $container->getDefinition($id);
        }
        $this->assertEquals('BizClass', $service->getClass(), '->load() uses the same configuration as for the anonymous ones');
        $this->assertTrue($service->isPublic());

        // anonymous services are shared when using decoration definitions
        $container->compile();
        $services = $container->getDefinitions();
        $fooArgs = $services['foo']->getArguments();
        $barArgs = $services['bar']->getArguments();
        $this->assertSame($fooArgs[0], $barArgs[0]);
    }

    public function testLoadServices()
    {
        $container = new ContainerBuilder();
        $loader = new XmlFileLoader($container, new FileLocator(self::$fixturesPath.'/xml'));
        $loader->load('services6.xml');
        $services = $container->getDefinitions();
        $this->assertTrue(isset($services['foo']), '->load() parses <service> elements');
        $this->assertFalse($services['not_shared']->isShared(), '->load() parses shared flag');
        $this->assertInstanceOf('Symfony\\Component\\DependencyInjection\\Definition', $services['foo'], '->load() converts <service> element to Definition instances');
        $this->assertEquals('FooClass', $services['foo']->getClass(), '->load() parses the class attribute');
        $this->assertEquals('%path%/foo.php', $services['file']->getFile(), '->load() parses the file tag');
        $this->assertEquals(array('foo', new Reference('foo'), array(true, false)), $services['arguments']->getArguments(), '->load() parses the argument tags');
        $this->assertEquals('sc_configure', $services['configurator1']->getConfigurator(), '->load() parses the configurator tag');
        $this->assertEquals(array(new Reference('baz', ContainerInterface::EXCEPTION_ON_INVALID_REFERENCE, false), 'configure'), $services['configurator2']->getConfigurator(), '->load() parses the configurator tag');
        $this->assertEquals(array('BazClass', 'configureStatic'), $services['configurator3']->getConfigurator(), '->load() parses the configurator tag');
        $this->assertEquals(array(array('setBar', array()), array('setBar', array(new Expression('service("foo").foo() ~ (container.hasParameter("foo") ? parameter("foo") : "default")')))), $services['method_call1']->getMethodCalls(), '->load() parses the method_call tag');
        $this->assertEquals(array(array('setBar', array('foo', new Reference('foo'), array(true, false)))), $services['method_call2']->getMethodCalls(), '->load() parses the method_call tag');
        $this->assertEquals('factory', $services['new_factory1']->getFactory(), '->load() parses the factory tag');
        $this->assertEquals(array(new Reference('baz', ContainerInterface::EXCEPTION_ON_INVALID_REFERENCE, false), 'getClass'), $services['new_factory2']->getFactory(), '->load() parses the factory tag');
        $this->assertEquals(array('BazClass', 'getInstance'), $services['new_factory3']->getFactory(), '->load() parses the factory tag');

        $aliases = $container->getAliases();
        $this->assertTrue(isset($aliases['alias_for_foo']), '->load() parses <service> elements');
        $this->assertEquals('foo', (string) $aliases['alias_for_foo'], '->load() parses aliases');
        $this->assertTrue($aliases['alias_for_foo']->isPublic());
        $this->assertTrue(isset($aliases['another_alias_for_foo']));
        $this->assertEquals('foo', (string) $aliases['another_alias_for_foo']);
        $this->assertFalse($aliases['another_alias_for_foo']->isPublic());

        $this->assertEquals(array('decorated', null, 0), $services['decorator_service']->getDecoratedService());
        $this->assertEquals(array('decorated', 'decorated.pif-pouf', 0), $services['decorator_service_with_name']->getDecoratedService());
        $this->assertEquals(array('decorated', 'decorated.pif-pouf', 5), $services['decorator_service_with_name_and_priority']->getDecoratedService());
    }

    public function testParsesTags()
    {
        $container = new ContainerBuilder();
        $loader = new XmlFileLoader($container, new FileLocator(self::$fixturesPath.'/xml'));
        $loader->load('services10.xml');

        $services = $container->findTaggedServiceIds('foo_tag');
        $this->assertCount(1, $services);

        foreach ($services as $id => $tagAttributes) {
            foreach ($tagAttributes as $attributes) {
                $this->assertArrayHasKey('other_option', $attributes);
                $this->assertEquals('lorem', $attributes['other_option']);
                $this->assertArrayHasKey('other-option', $attributes, 'unnormalized tag attributes should not be removed');

                $this->assertEquals('ciz', $attributes['some_option'], 'no overriding should be done when normalizing');
                $this->assertEquals('cat', $attributes['some-option']);

                $this->assertArrayNotHasKey('an_other_option', $attributes, 'normalization should not be done when an underscore is already found');
            }
        }
    }

    /**
     * @expectedException \Symfony\Component\DependencyInjection\Exception\InvalidArgumentException
     */
    public function testParseTagsWithoutNameThrowsException()
    {
        $container = new ContainerBuilder();
        $loader = new XmlFileLoader($container, new FileLocator(self::$fixturesPath.'/xml'));
        $loader->load('tag_without_name.xml');
    }

    /**
     * @expectedException \Symfony\Component\DependencyInjection\Exception\InvalidArgumentException
     * @expectedExceptionMessageRegExp /The tag name for service ".+" in .* must be a non-empty string/
     */
    public function testParseTagWithEmptyNameThrowsException()
    {
        $container = new ContainerBuilder();
        $loader = new XmlFileLoader($container, new FileLocator(self::$fixturesPath.'/xml'));
        $loader->load('tag_with_empty_name.xml');
    }

    public function testDeprecated()
    {
        $container = new ContainerBuilder();
        $loader = new XmlFileLoader($container, new FileLocator(self::$fixturesPath.'/xml'));
        $loader->load('services_deprecated.xml');

        $this->assertTrue($container->getDefinition('foo')->isDeprecated());
        $message = 'The "foo" service is deprecated. You should stop using it, as it will soon be removed.';
        $this->assertSame($message, $container->getDefinition('foo')->getDeprecationMessage('foo'));

        $this->assertTrue($container->getDefinition('bar')->isDeprecated());
        $message = 'The "bar" service is deprecated.';
        $this->assertSame($message, $container->getDefinition('bar')->getDeprecationMessage('bar'));
    }

    public function testConvertDomElementToArray()
    {
        $doc = new \DOMDocument('1.0');
        $doc->loadXML('<foo>bar</foo>');
        $this->assertEquals('bar', XmlFileLoader::convertDomElementToArray($doc->documentElement), '::convertDomElementToArray() converts a \DomElement to an array');

        $doc = new \DOMDocument('1.0');
        $doc->loadXML('<foo foo="bar" />');
        $this->assertEquals(array('foo' => 'bar'), XmlFileLoader::convertDomElementToArray($doc->documentElement), '::convertDomElementToArray() converts a \DomElement to an array');

        $doc = new \DOMDocument('1.0');
        $doc->loadXML('<foo><foo>bar</foo></foo>');
        $this->assertEquals(array('foo' => 'bar'), XmlFileLoader::convertDomElementToArray($doc->documentElement), '::convertDomElementToArray() converts a \DomElement to an array');

        $doc = new \DOMDocument('1.0');
        $doc->loadXML('<foo><foo>bar<foo>bar</foo></foo></foo>');
        $this->assertEquals(array('foo' => array('value' => 'bar', 'foo' => 'bar')), XmlFileLoader::convertDomElementToArray($doc->documentElement), '::convertDomElementToArray() converts a \DomElement to an array');

        $doc = new \DOMDocument('1.0');
        $doc->loadXML('<foo><foo></foo></foo>');
        $this->assertEquals(array('foo' => null), XmlFileLoader::convertDomElementToArray($doc->documentElement), '::convertDomElementToArray() converts a \DomElement to an array');

        $doc = new \DOMDocument('1.0');
        $doc->loadXML('<foo><foo><!-- foo --></foo></foo>');
        $this->assertEquals(array('foo' => null), XmlFileLoader::convertDomElementToArray($doc->documentElement), '::convertDomElementToArray() converts a \DomElement to an array');

        $doc = new \DOMDocument('1.0');
        $doc->loadXML('<foo><foo foo="bar"/><foo foo="bar"/></foo>');
        $this->assertEquals(array('foo' => array(array('foo' => 'bar'), array('foo' => 'bar'))), XmlFileLoader::convertDomElementToArray($doc->documentElement), '::convertDomElementToArray() converts a \DomElement to an array');
    }

    public function testExtensions()
    {
        $container = new ContainerBuilder();
        $container->registerExtension(new \ProjectExtension());
        $container->registerExtension(new \ProjectWithXsdExtension());
        $loader = new XmlFileLoader($container, new FileLocator(self::$fixturesPath.'/xml'));

        // extension without an XSD
        $loader->load('extensions/services1.xml');
        $container->compile();
        $services = $container->getDefinitions();
        $parameters = $container->getParameterBag()->all();

        $this->assertTrue(isset($services['project.service.bar']), '->load() parses extension elements');
        $this->assertTrue(isset($parameters['project.parameter.bar']), '->load() parses extension elements');

        $this->assertEquals('BAR', $services['project.service.foo']->getClass(), '->load() parses extension elements');
        $this->assertEquals('BAR', $parameters['project.parameter.foo'], '->load() parses extension elements');

        // extension with an XSD
        $container = new ContainerBuilder();
        $container->registerExtension(new \ProjectExtension());
        $container->registerExtension(new \ProjectWithXsdExtension());
        $loader = new XmlFileLoader($container, new FileLocator(self::$fixturesPath.'/xml'));
        $loader->load('extensions/services2.xml');
        $container->compile();
        $services = $container->getDefinitions();
        $parameters = $container->getParameterBag()->all();

        $this->assertTrue(isset($services['project.service.bar']), '->load() parses extension elements');
        $this->assertTrue(isset($parameters['project.parameter.bar']), '->load() parses extension elements');

        $this->assertEquals('BAR', $services['project.service.foo']->getClass(), '->load() parses extension elements');
        $this->assertEquals('BAR', $parameters['project.parameter.foo'], '->load() parses extension elements');

        $container = new ContainerBuilder();
        $container->registerExtension(new \ProjectExtension());
        $container->registerExtension(new \ProjectWithXsdExtension());
        $loader = new XmlFileLoader($container, new FileLocator(self::$fixturesPath.'/xml'));

        // extension with an XSD (does not validate)
        try {
            $loader->load('extensions/services3.xml');
            $this->fail('->load() throws an InvalidArgumentException if the configuration does not validate the XSD');
        } catch (\Exception $e) {
            $this->assertInstanceOf('Symfony\\Component\\DependencyInjection\\Exception\\InvalidArgumentException', $e, '->load() throws an InvalidArgumentException if the configuration does not validate the XSD');
            $this->assertRegExp(sprintf('#^Unable to parse file ".+%s".$#', 'services3.xml'), $e->getMessage(), '->load() throws an InvalidArgumentException if the configuration does not validate the XSD');

            $e = $e->getPrevious();
            $this->assertInstanceOf('InvalidArgumentException', $e, '->load() throws an InvalidArgumentException if the configuration does not validate the XSD');
            $this->assertContains('The attribute \'bar\' is not allowed', $e->getMessage(), '->load() throws an InvalidArgumentException if the configuration does not validate the XSD');
        }

        // non-registered extension
        try {
            $loader->load('extensions/services4.xml');
            $this->fail('->load() throws an InvalidArgumentException if the tag is not valid');
        } catch (\Exception $e) {
            $this->assertInstanceOf('\InvalidArgumentException', $e, '->load() throws an InvalidArgumentException if the tag is not valid');
            $this->assertStringStartsWith('There is no extension able to load the configuration for "project:bar" (in', $e->getMessage(), '->load() throws an InvalidArgumentException if the tag is not valid');
        }
    }

    public function testExtensionInPhar()
    {
        if (extension_loaded('suhosin') && false === strpos(ini_get('suhosin.executor.include.whitelist'), 'phar')) {
            $this->markTestSkipped('To run this test, add "phar" to the "suhosin.executor.include.whitelist" settings in your php.ini file.');
        }

        require_once self::$fixturesPath.'/includes/ProjectWithXsdExtensionInPhar.phar';

        // extension with an XSD in PHAR archive
        $container = new ContainerBuilder();
        $container->registerExtension(new \ProjectWithXsdExtensionInPhar());
        $loader = new XmlFileLoader($container, new FileLocator(self::$fixturesPath.'/xml'));
        $loader->load('extensions/services6.xml');

        // extension with an XSD in PHAR archive (does not validate)
        try {
            $loader->load('extensions/services7.xml');
            $this->fail('->load() throws an InvalidArgumentException if the configuration does not validate the XSD');
        } catch (\Exception $e) {
            $this->assertInstanceOf('Symfony\\Component\\DependencyInjection\\Exception\\InvalidArgumentException', $e, '->load() throws an InvalidArgumentException if the configuration does not validate the XSD');
            $this->assertRegExp(sprintf('#^Unable to parse file ".+%s".$#', 'services7.xml'), $e->getMessage(), '->load() throws an InvalidArgumentException if the configuration does not validate the XSD');

            $e = $e->getPrevious();
            $this->assertInstanceOf('InvalidArgumentException', $e, '->load() throws an InvalidArgumentException if the configuration does not validate the XSD');
            $this->assertContains('The attribute \'bar\' is not allowed', $e->getMessage(), '->load() throws an InvalidArgumentException if the configuration does not validate the XSD');
        }
    }

    public function testSupports()
    {
        $loader = new XmlFileLoader(new ContainerBuilder(), new FileLocator());

        $this->assertTrue($loader->supports('foo.xml'), '->supports() returns true if the resource is loadable');
        $this->assertFalse($loader->supports('foo.foo'), '->supports() returns true if the resource is loadable');
    }

    public function testNoNamingConflictsForAnonymousServices()
    {
        $container = new ContainerBuilder();

        $loader1 = new XmlFileLoader($container, new FileLocator(self::$fixturesPath.'/xml/extension1'));
        $loader1->load('services.xml');
        $services = $container->getDefinitions();
        $this->assertCount(2, $services, '->load() attributes unique ids to anonymous services');
        $loader2 = new XmlFileLoader($container, new FileLocator(self::$fixturesPath.'/xml/extension2'));
        $loader2->load('services.xml');
        $services = $container->getDefinitions();
        $this->assertCount(4, $services, '->load() attributes unique ids to anonymous services');

        $services = $container->getDefinitions();
        $args1 = $services['extension1.foo']->getArguments();
        $inner1 = $services[(string) $args1[0]];
        $this->assertEquals('BarClass1', $inner1->getClass(), '->load() uses the same configuration as for the anonymous ones');
        $args2 = $services['extension2.foo']->getArguments();
        $inner2 = $services[(string) $args2[0]];
        $this->assertEquals('BarClass2', $inner2->getClass(), '->load() uses the same configuration as for the anonymous ones');
    }

    public function testDocTypeIsNotAllowed()
    {
        $container = new ContainerBuilder();

        $loader = new XmlFileLoader($container, new FileLocator(self::$fixturesPath.'/xml'));

        // document types are not allowed.
        try {
            $loader->load('withdoctype.xml');
            $this->fail('->load() throws an InvalidArgumentException if the configuration contains a document type');
        } catch (\Exception $e) {
            $this->assertInstanceOf('Symfony\\Component\\DependencyInjection\\Exception\\InvalidArgumentException', $e, '->load() throws an InvalidArgumentException if the configuration contains a document type');
            $this->assertRegExp(sprintf('#^Unable to parse file ".+%s".$#', 'withdoctype.xml'), $e->getMessage(), '->load() throws an InvalidArgumentException if the configuration contains a document type');

            $e = $e->getPrevious();
            $this->assertInstanceOf('InvalidArgumentException', $e, '->load() throws an InvalidArgumentException if the configuration contains a document type');
            $this->assertSame('Document types are not allowed.', $e->getMessage(), '->load() throws an InvalidArgumentException if the configuration contains a document type');
        }
    }

    public function testXmlNamespaces()
    {
        $container = new ContainerBuilder();
        $loader = new XmlFileLoader($container, new FileLocator(self::$fixturesPath.'/xml'));
        $loader->load('namespaces.xml');
        $services = $container->getDefinitions();

        $this->assertTrue(isset($services['foo']), '->load() parses <srv:service> elements');
        $this->assertEquals(1, count($services['foo']->getTag('foo.tag')), '->load parses <srv:tag> elements');
        $this->assertEquals(array(array('setBar', array('foo'))), $services['foo']->getMethodCalls(), '->load() parses the <srv:call> tag');
    }

    public function testLoadIndexedArguments()
    {
        $container = new ContainerBuilder();
        $loader = new XmlFileLoader($container, new FileLocator(self::$fixturesPath.'/xml'));
        $loader->load('services14.xml');

        $this->assertEquals(array('index_0' => 'app'), $container->findDefinition('logger')->getArguments());
    }

    public function testLoadInlinedServices()
    {
        $container = new ContainerBuilder();
        $loader = new XmlFileLoader($container, new FileLocator(self::$fixturesPath.'/xml'));
        $loader->load('services21.xml');

        $foo = $container->getDefinition('foo');

        $fooFactory = $foo->getFactory();
        $this->assertInstanceOf('Symfony\Component\DependencyInjection\Definition', $fooFactory[0]);
        $this->assertSame('FooFactory', $fooFactory[0]->getClass());
        $this->assertSame('createFoo', $fooFactory[1]);

        $fooFactoryFactory = $fooFactory[0]->getFactory();
        $this->assertInstanceOf('Symfony\Component\DependencyInjection\Definition', $fooFactoryFactory[0]);
        $this->assertSame('Foobar', $fooFactoryFactory[0]->getClass());
        $this->assertSame('createFooFactory', $fooFactoryFactory[1]);

        $fooConfigurator = $foo->getConfigurator();
        $this->assertInstanceOf('Symfony\Component\DependencyInjection\Definition', $fooConfigurator[0]);
        $this->assertSame('Bar', $fooConfigurator[0]->getClass());
        $this->assertSame('configureFoo', $fooConfigurator[1]);

        $barConfigurator = $fooConfigurator[0]->getConfigurator();
        $this->assertInstanceOf('Symfony\Component\DependencyInjection\Definition', $barConfigurator[0]);
        $this->assertSame('Baz', $barConfigurator[0]->getClass());
        $this->assertSame('configureBar', $barConfigurator[1]);
    }

    public function testType()
    {
        $container = new ContainerBuilder();
        $loader = new XmlFileLoader($container, new FileLocator(self::$fixturesPath.'/xml'));
        $loader->load('services22.xml');

        $this->assertEquals(array('Bar', 'Baz'), $container->getDefinition('foo')->getAutowiringTypes());
    }

    public function testAutowire()
    {
        $container = new ContainerBuilder();
        $loader = new XmlFileLoader($container, new FileLocator(self::$fixturesPath.'/xml'));
        $loader->load('services23.xml');

        $this->assertTrue($container->getDefinition('bar')->isAutowired());
    }

    /**
     * @group legacy
     * @expectedDeprecation Using the attribute "class" is deprecated for the service "bar" which is defined as an alias %s.
     * @expectedDeprecation Using the element "tag" is deprecated for the service "bar" which is defined as an alias %s.
     * @expectedDeprecation Using the element "factory" is deprecated for the service "bar" which is defined as an alias %s.
     */
    public function testAliasDefinitionContainsUnsupportedElements()
    {
        $container = new ContainerBuilder();
        $loader = new XmlFileLoader($container, new FileLocator(self::$fixturesPath.'/xml'));

        $loader->load('legacy_invalid_alias_definition.xml');

        $this->assertTrue($container->has('bar'));
    }

    public function testArgumentWithKeyOutsideCollection()
    {
        $container = new ContainerBuilder();
        $loader = new XmlFileLoader($container, new FileLocator(self::$fixturesPath.'/xml'));
        $loader->load('with_key_outside_collection.xml');

        $this->assertSame(array('type' => 'foo', 'bar'), $container->getDefinition('foo')->getArguments());
    }
}
PKϤ$ZI����7dependency-injection/Tests/Loader/ClosureLoaderTest.phpnu�[���<?php

/*
 * This file is part of the Symfony package.
 *
 * (c) Fabien Potencier <fabien@symfony.com>
 *
 * For the full copyright and license information, please view the LICENSE
 * file that was distributed with this source code.
 */

namespace Symfony\Component\DependencyInjection\Tests\Loader;

use Symfony\Component\DependencyInjection\ContainerBuilder;
use Symfony\Component\DependencyInjection\Loader\ClosureLoader;

class ClosureLoaderTest extends \PHPUnit_Framework_TestCase
{
    public function testSupports()
    {
        $loader = new ClosureLoader(new ContainerBuilder());

        $this->assertTrue($loader->supports(function ($container) {}), '->supports() returns true if the resource is loadable');
        $this->assertFalse($loader->supports('foo.foo'), '->supports() returns true if the resource is loadable');
    }

    public function testLoad()
    {
        $loader = new ClosureLoader($container = new ContainerBuilder());

        $loader->load(function ($container) {
            $container->setParameter('foo', 'foo');
        });

        $this->assertEquals('foo', $container->getParameter('foo'), '->load() loads a \Closure resource');
    }
}
PKϤ$Zw���E�E8dependency-injection/Tests/Loader/YamlFileLoaderTest.phpnu�[���<?php

/*
 * This file is part of the Symfony package.
 *
 * (c) Fabien Potencier <fabien@symfony.com>
 *
 * For the full copyright and license information, please view the LICENSE
 * file that was distributed with this source code.
 */

namespace Symfony\Component\DependencyInjection\Tests\Loader;

use Symfony\Component\DependencyInjection\ContainerBuilder;
use Symfony\Component\DependencyInjection\Reference;
use Symfony\Component\DependencyInjection\Loader\XmlFileLoader;
use Symfony\Component\DependencyInjection\Loader\YamlFileLoader;
use Symfony\Component\DependencyInjection\Loader\IniFileLoader;
use Symfony\Component\DependencyInjection\Loader\PhpFileLoader;
use Symfony\Component\Config\Loader\LoaderResolver;
use Symfony\Component\Config\FileLocator;
use Symfony\Component\ExpressionLanguage\Expression;

class YamlFileLoaderTest extends \PHPUnit_Framework_TestCase
{
    protected static $fixturesPath;

    public static function setUpBeforeClass()
    {
        self::$fixturesPath = realpath(__DIR__.'/../Fixtures/');
        require_once self::$fixturesPath.'/includes/foo.php';
        require_once self::$fixturesPath.'/includes/ProjectExtension.php';
    }

    public function testLoadFile()
    {
        $loader = new YamlFileLoader(new ContainerBuilder(), new FileLocator(self::$fixturesPath.'/ini'));
        $r = new \ReflectionObject($loader);
        $m = $r->getMethod('loadFile');
        $m->setAccessible(true);

        try {
            $m->invoke($loader, 'foo.yml');
            $this->fail('->load() throws an InvalidArgumentException if the loaded file does not exist');
        } catch (\Exception $e) {
            $this->assertInstanceOf('\InvalidArgumentException', $e, '->load() throws an InvalidArgumentException if the loaded file does not exist');
            $this->assertEquals('The service file "foo.yml" is not valid.', $e->getMessage(), '->load() throws an InvalidArgumentException if the loaded file does not exist');
        }

        try {
            $m->invoke($loader, 'parameters.ini');
            $this->fail('->load() throws an InvalidArgumentException if the loaded file is not a valid YAML file');
        } catch (\Exception $e) {
            $this->assertInstanceOf('\InvalidArgumentException', $e, '->load() throws an InvalidArgumentException if the loaded file is not a valid YAML file');
            $this->assertEquals('The service file "parameters.ini" is not valid.', $e->getMessage(), '->load() throws an InvalidArgumentException if the loaded file is not a valid YAML file');
        }

        $loader = new YamlFileLoader(new ContainerBuilder(), new FileLocator(self::$fixturesPath.'/yaml'));

        foreach (array('nonvalid1', 'nonvalid2') as $fixture) {
            try {
                $m->invoke($loader, $fixture.'.yml');
                $this->fail('->load() throws an InvalidArgumentException if the loaded file does not validate');
            } catch (\Exception $e) {
                $this->assertInstanceOf('\InvalidArgumentException', $e, '->load() throws an InvalidArgumentException if the loaded file does not validate');
                $this->assertStringMatchesFormat('The service file "nonvalid%d.yml" is not valid.', $e->getMessage(), '->load() throws an InvalidArgumentException if the loaded file does not validate');
            }
        }
    }

    /**
     * @dataProvider provideInvalidFiles
     * @expectedException \Symfony\Component\DependencyInjection\Exception\InvalidArgumentException
     */
    public function testLoadInvalidFile($file)
    {
        $loader = new YamlFileLoader(new ContainerBuilder(), new FileLocator(self::$fixturesPath.'/yaml'));

        $loader->load($file.'.yml');
    }

    public function provideInvalidFiles()
    {
        return array(
            array('bad_parameters'),
            array('bad_imports'),
            array('bad_import'),
            array('bad_services'),
            array('bad_service'),
            array('bad_calls'),
            array('bad_format'),
        );
    }

    public function testLoadParameters()
    {
        $container = new ContainerBuilder();
        $loader = new YamlFileLoader($container, new FileLocator(self::$fixturesPath.'/yaml'));
        $loader->load('services2.yml');
        $this->assertEquals(array('foo' => 'bar', 'mixedcase' => array('MixedCaseKey' => 'value'), 'values' => array(true, false, 0, 1000.3), 'bar' => 'foo', 'escape' => '@escapeme', 'foo_bar' => new Reference('foo_bar')), $container->getParameterBag()->all(), '->load() converts YAML keys to lowercase');
    }

    public function testLoadImports()
    {
        $container = new ContainerBuilder();
        $resolver = new LoaderResolver(array(
            new IniFileLoader($container, new FileLocator(self::$fixturesPath.'/ini')),
            new XmlFileLoader($container, new FileLocator(self::$fixturesPath.'/xml')),
            new PhpFileLoader($container, new FileLocator(self::$fixturesPath.'/php')),
            $loader = new YamlFileLoader($container, new FileLocator(self::$fixturesPath.'/yaml')),
        ));
        $loader->setResolver($resolver);
        $loader->load('services4.yml');

        $actual = $container->getParameterBag()->all();
        $expected = array('foo' => 'bar', 'values' => array(true, false), 'bar' => '%foo%', 'escape' => '@escapeme', 'foo_bar' => new Reference('foo_bar'), 'mixedcase' => array('MixedCaseKey' => 'value'), 'imported_from_ini' => true, 'imported_from_xml' => true);
        $this->assertEquals(array_keys($expected), array_keys($actual), '->load() imports and merges imported files');

        // Bad import throws no exception due to ignore_errors value.
        $loader->load('services4_bad_import.yml');
    }

    public function testLoadServices()
    {
        $container = new ContainerBuilder();
        $loader = new YamlFileLoader($container, new FileLocator(self::$fixturesPath.'/yaml'));
        $loader->load('services6.yml');
        $services = $container->getDefinitions();
        $this->assertTrue(isset($services['foo']), '->load() parses service elements');
        $this->assertFalse($services['not_shared']->isShared(), '->load() parses the shared flag');
        $this->assertInstanceOf('Symfony\\Component\\DependencyInjection\\Definition', $services['foo'], '->load() converts service element to Definition instances');
        $this->assertEquals('FooClass', $services['foo']->getClass(), '->load() parses the class attribute');
        $this->assertEquals('%path%/foo.php', $services['file']->getFile(), '->load() parses the file tag');
        $this->assertEquals(array('foo', new Reference('foo'), array(true, false)), $services['arguments']->getArguments(), '->load() parses the argument tags');
        $this->assertEquals('sc_configure', $services['configurator1']->getConfigurator(), '->load() parses the configurator tag');
        $this->assertEquals(array(new Reference('baz'), 'configure'), $services['configurator2']->getConfigurator(), '->load() parses the configurator tag');
        $this->assertEquals(array('BazClass', 'configureStatic'), $services['configurator3']->getConfigurator(), '->load() parses the configurator tag');
        $this->assertEquals(array(array('setBar', array()), array('setBar', array()), array('setBar', array(new Expression('service("foo").foo() ~ (container.hasParameter("foo") ? parameter("foo") : "default")')))), $services['method_call1']->getMethodCalls(), '->load() parses the method_call tag');
        $this->assertEquals(array(array('setBar', array('foo', new Reference('foo'), array(true, false)))), $services['method_call2']->getMethodCalls(), '->load() parses the method_call tag');
        $this->assertEquals('factory', $services['new_factory1']->getFactory(), '->load() parses the factory tag');
        $this->assertEquals(array(new Reference('baz'), 'getClass'), $services['new_factory2']->getFactory(), '->load() parses the factory tag');
        $this->assertEquals(array('BazClass', 'getInstance'), $services['new_factory3']->getFactory(), '->load() parses the factory tag');

        $aliases = $container->getAliases();
        $this->assertTrue(isset($aliases['alias_for_foo']), '->load() parses aliases');
        $this->assertEquals('foo', (string) $aliases['alias_for_foo'], '->load() parses aliases');
        $this->assertTrue($aliases['alias_for_foo']->isPublic());
        $this->assertTrue(isset($aliases['another_alias_for_foo']));
        $this->assertEquals('foo', (string) $aliases['another_alias_for_foo']);
        $this->assertFalse($aliases['another_alias_for_foo']->isPublic());

        $this->assertEquals(array('decorated', null, 0), $services['decorator_service']->getDecoratedService());
        $this->assertEquals(array('decorated', 'decorated.pif-pouf', 0), $services['decorator_service_with_name']->getDecoratedService());
        $this->assertEquals(array('decorated', 'decorated.pif-pouf', 5), $services['decorator_service_with_name_and_priority']->getDecoratedService());
    }

    public function testLoadFactoryShortSyntax()
    {
        $container = new ContainerBuilder();
        $loader = new YamlFileLoader($container, new FileLocator(self::$fixturesPath.'/yaml'));
        $loader->load('services14.yml');
        $services = $container->getDefinitions();

        $this->assertEquals(array(new Reference('baz'), 'getClass'), $services['factory']->getFactory(), '->load() parses the factory tag with service:method');
        $this->assertEquals(array('FooBacFactory', 'createFooBar'), $services['factory_with_static_call']->getFactory(), '->load() parses the factory tag with Class::method');
    }

    public function testExtensions()
    {
        $container = new ContainerBuilder();
        $container->registerExtension(new \ProjectExtension());
        $loader = new YamlFileLoader($container, new FileLocator(self::$fixturesPath.'/yaml'));
        $loader->load('services10.yml');
        $container->compile();
        $services = $container->getDefinitions();
        $parameters = $container->getParameterBag()->all();

        $this->assertTrue(isset($services['project.service.bar']), '->load() parses extension elements');
        $this->assertTrue(isset($parameters['project.parameter.bar']), '->load() parses extension elements');

        $this->assertEquals('BAR', $services['project.service.foo']->getClass(), '->load() parses extension elements');
        $this->assertEquals('BAR', $parameters['project.parameter.foo'], '->load() parses extension elements');

        try {
            $loader->load('services11.yml');
            $this->fail('->load() throws an InvalidArgumentException if the tag is not valid');
        } catch (\Exception $e) {
            $this->assertInstanceOf('\InvalidArgumentException', $e, '->load() throws an InvalidArgumentException if the tag is not valid');
            $this->assertStringStartsWith('There is no extension able to load the configuration for "foobarfoobar" (in', $e->getMessage(), '->load() throws an InvalidArgumentException if the tag is not valid');
        }
    }

    public function testSupports()
    {
        $loader = new YamlFileLoader(new ContainerBuilder(), new FileLocator());

        $this->assertTrue($loader->supports('foo.yml'), '->supports() returns true if the resource is loadable');
        $this->assertTrue($loader->supports('foo.yaml'), '->supports() returns true if the resource is loadable');
        $this->assertFalse($loader->supports('foo.foo'), '->supports() returns true if the resource is loadable');
    }

    public function testNonArrayTagsThrowsException()
    {
        $loader = new YamlFileLoader(new ContainerBuilder(), new FileLocator(self::$fixturesPath.'/yaml'));
        try {
            $loader->load('badtag1.yml');
            $this->fail('->load() should throw an exception when the tags key of a service is not an array');
        } catch (\Exception $e) {
            $this->assertInstanceOf('Symfony\Component\DependencyInjection\Exception\InvalidArgumentException', $e, '->load() throws an InvalidArgumentException if the tags key is not an array');
            $this->assertStringStartsWith('Parameter "tags" must be an array for service', $e->getMessage(), '->load() throws an InvalidArgumentException if the tags key is not an array');
        }
    }

    /**
     * @expectedException \Symfony\Component\DependencyInjection\Exception\InvalidArgumentException
     * @expectedExceptionMessage A "tags" entry must be an array for service
     */
    public function testNonArrayTagThrowsException()
    {
        $loader = new YamlFileLoader(new ContainerBuilder(), new FileLocator(self::$fixturesPath.'/yaml'));
        $loader->load('badtag4.yml');
    }

    public function testTagWithoutNameThrowsException()
    {
        $loader = new YamlFileLoader(new ContainerBuilder(), new FileLocator(self::$fixturesPath.'/yaml'));
        try {
            $loader->load('badtag2.yml');
            $this->fail('->load() should throw an exception when a tag is missing the name key');
        } catch (\Exception $e) {
            $this->assertInstanceOf('Symfony\Component\DependencyInjection\Exception\InvalidArgumentException', $e, '->load() throws an InvalidArgumentException if a tag is missing the name key');
            $this->assertStringStartsWith('A "tags" entry is missing a "name" key for service ', $e->getMessage(), '->load() throws an InvalidArgumentException if a tag is missing the name key');
        }
    }

    public function testTagWithAttributeArrayThrowsException()
    {
        $loader = new YamlFileLoader(new ContainerBuilder(), new FileLocator(self::$fixturesPath.'/yaml'));
        try {
            $loader->load('badtag3.yml');
            $this->fail('->load() should throw an exception when a tag-attribute is not a scalar');
        } catch (\Exception $e) {
            $this->assertInstanceOf('Symfony\Component\DependencyInjection\Exception\InvalidArgumentException', $e, '->load() throws an InvalidArgumentException if a tag-attribute is not a scalar');
            $this->assertStringStartsWith('A "tags" attribute must be of a scalar-type for service "foo_service", tag "foo", attribute "bar"', $e->getMessage(), '->load() throws an InvalidArgumentException if a tag-attribute is not a scalar');
        }
    }

    public function testLoadYamlOnlyWithKeys()
    {
        $container = new ContainerBuilder();
        $loader = new YamlFileLoader($container, new FileLocator(self::$fixturesPath.'/yaml'));
        $loader->load('services21.yml');

        $definition = $container->getDefinition('manager');
        $this->assertEquals(array(array('setLogger', array(new Reference('logger'))), array('setClass', array('User'))), $definition->getMethodCalls());
        $this->assertEquals(array(true), $definition->getArguments());
        $this->assertEquals(array('manager' => array(array('alias' => 'user'))), $definition->getTags());
    }

    /**
     * @expectedException \Symfony\Component\DependencyInjection\Exception\InvalidArgumentException
     * @expectedExceptionMessageRegExp /The tag name for service ".+" in .+ must be a non-empty string/
     */
    public function testTagWithEmptyNameThrowsException()
    {
        $loader = new YamlFileLoader(new ContainerBuilder(), new FileLocator(self::$fixturesPath.'/yaml'));
        $loader->load('tag_name_empty_string.yml');
    }

    /**
     * @expectedException \Symfony\Component\DependencyInjection\Exception\InvalidArgumentException
     * @expectedExceptionMessageREgExp /The tag name for service "\.+" must be a non-empty string/
     */
    public function testTagWithNonStringNameThrowsException()
    {
        $loader = new YamlFileLoader(new ContainerBuilder(), new FileLocator(self::$fixturesPath.'/yaml'));
        $loader->load('tag_name_no_string.yml');
    }

    /**
     * @expectedException \Symfony\Component\DependencyInjection\Exception\InvalidArgumentException
     */
    public function testTypesNotArray()
    {
        $loader = new YamlFileLoader(new ContainerBuilder(), new FileLocator(self::$fixturesPath.'/yaml'));
        $loader->load('bad_types1.yml');
    }

    /**
     * @expectedException \Symfony\Component\DependencyInjection\Exception\InvalidArgumentException
     */
    public function testTypeNotString()
    {
        $loader = new YamlFileLoader(new ContainerBuilder(), new FileLocator(self::$fixturesPath.'/yaml'));
        $loader->load('bad_types2.yml');
    }

    public function testTypes()
    {
        $container = new ContainerBuilder();
        $loader = new YamlFileLoader($container, new FileLocator(self::$fixturesPath.'/yaml'));
        $loader->load('services22.yml');

        $this->assertEquals(array('Foo', 'Bar'), $container->getDefinition('foo_service')->getAutowiringTypes());
        $this->assertEquals(array('Foo'), $container->getDefinition('baz_service')->getAutowiringTypes());
    }

    public function testAutowire()
    {
        $container = new ContainerBuilder();
        $loader = new YamlFileLoader($container, new FileLocator(self::$fixturesPath.'/yaml'));
        $loader->load('services23.yml');

        $this->assertTrue($container->getDefinition('bar_service')->isAutowired());
    }

    /**
     * @expectedException \Symfony\Component\DependencyInjection\Exception\InvalidArgumentException
     * @expectedExceptionMessage The value of the "decorates" option for the "bar" service must be the id of the service without the "@" prefix (replace "@foo" with "foo").
     */
    public function testDecoratedServicesWithWrongSyntaxThrowsException()
    {
        $loader = new YamlFileLoader(new ContainerBuilder(), new FileLocator(self::$fixturesPath.'/yaml'));
        $loader->load('bad_decorates.yml');
    }
}
PKϤ$Z�Op�		9dependency-injection/Tests/Loader/DirectoryLoaderTest.phpnu�[���<?php

/*
 * This file is part of the Symfony package.
 *
 * (c) Fabien Potencier <fabien@symfony.com>
 *
 * For the full copyright and license information, please view the LICENSE
 * file that was distributed with this source code.
 */

namespace Symfony\Component\DependencyInjection\Tests\Loader;

use Symfony\Component\DependencyInjection\ContainerBuilder;
use Symfony\Component\DependencyInjection\Loader\PhpFileLoader;
use Symfony\Component\DependencyInjection\Loader\IniFileLoader;
use Symfony\Component\DependencyInjection\Loader\YamlFileLoader;
use Symfony\Component\DependencyInjection\Loader\DirectoryLoader;
use Symfony\Component\Config\Loader\LoaderResolver;
use Symfony\Component\Config\FileLocator;

class DirectoryLoaderTest extends \PHPUnit_Framework_TestCase
{
    private static $fixturesPath;

    private $container;
    private $loader;

    public static function setUpBeforeClass()
    {
        self::$fixturesPath = realpath(__DIR__.'/../Fixtures/');
    }

    protected function setUp()
    {
        $locator = new FileLocator(self::$fixturesPath);
        $this->container = new ContainerBuilder();
        $this->loader = new DirectoryLoader($this->container, $locator);
        $resolver = new LoaderResolver(array(
            new PhpFileLoader($this->container, $locator),
            new IniFileLoader($this->container, $locator),
            new YamlFileLoader($this->container, $locator),
            $this->loader,
        ));
        $this->loader->setResolver($resolver);
    }

    public function testDirectoryCanBeLoadedRecursively()
    {
        $this->loader->load('directory/');
        $this->assertEquals(array('ini' => 'ini', 'yaml' => 'yaml', 'php' => 'php'), $this->container->getParameterBag()->all(), '->load() takes a single directory');
    }

    public function testImports()
    {
        $this->loader->resolve('directory/import/import.yml')->load('directory/import/import.yml');
        $this->assertEquals(array('ini' => 'ini', 'yaml' => 'yaml'), $this->container->getParameterBag()->all(), '->load() takes a single file that imports a directory');
    }

    /**
     * @expectedException        \InvalidArgumentException
     * @expectedExceptionMessage The file "foo" does not exist (in:
     */
    public function testExceptionIsRaisedWhenDirectoryDoesNotExist()
    {
        $this->loader->load('foo/');
    }

    public function testSupports()
    {
        $loader = new DirectoryLoader(new ContainerBuilder(), new FileLocator());

        $this->assertTrue($loader->supports('directory/'), '->supports("directory/") returns true');
        $this->assertTrue($loader->supports('directory/', 'directory'), '->supports("directory/", "directory") returns true');
        $this->assertFalse($loader->supports('directory'), '->supports("directory") returns false');
        $this->assertTrue($loader->supports('directory', 'directory'), '->supports("directory", "directory") returns true');
        $this->assertFalse($loader->supports('directory', 'foo'), '->supports("directory", "foo") returns false');
    }
}
PKϤ$Z�ߛHH7dependency-injection/Tests/Loader/IniFileLoaderTest.phpnu�[���<?php

/*
 * This file is part of the Symfony package.
 *
 * (c) Fabien Potencier <fabien@symfony.com>
 *
 * For the full copyright and license information, please view the LICENSE
 * file that was distributed with this source code.
 */

namespace Symfony\Component\DependencyInjection\Tests\Loader;

use Symfony\Component\DependencyInjection\ContainerBuilder;
use Symfony\Component\DependencyInjection\Loader\IniFileLoader;
use Symfony\Component\Config\FileLocator;

class IniFileLoaderTest extends \PHPUnit_Framework_TestCase
{
    protected static $fixturesPath;

    protected $container;
    protected $loader;

    public static function setUpBeforeClass()
    {
        self::$fixturesPath = realpath(__DIR__.'/../Fixtures/');
    }

    protected function setUp()
    {
        $this->container = new ContainerBuilder();
        $this->loader = new IniFileLoader($this->container, new FileLocator(self::$fixturesPath.'/ini'));
    }

    public function testIniFileCanBeLoaded()
    {
        $this->loader->load('parameters.ini');
        $this->assertEquals(array('foo' => 'bar', 'bar' => '%foo%'), $this->container->getParameterBag()->all(), '->load() takes a single file name as its first argument');
    }

    /**
     * @expectedException        \InvalidArgumentException
     * @expectedExceptionMessage The file "foo.ini" does not exist (in:
     */
    public function testExceptionIsRaisedWhenIniFileDoesNotExist()
    {
        $this->loader->load('foo.ini');
    }

    /**
     * @expectedException        \InvalidArgumentException
     * @expectedExceptionMessage The "nonvalid.ini" file is not valid.
     */
    public function testExceptionIsRaisedWhenIniFileCannotBeParsed()
    {
        @$this->loader->load('nonvalid.ini');
    }

    public function testSupports()
    {
        $loader = new IniFileLoader(new ContainerBuilder(), new FileLocator());

        $this->assertTrue($loader->supports('foo.ini'), '->supports() returns true if the resource is loadable');
        $this->assertFalse($loader->supports('foo.foo'), '->supports() returns true if the resource is loadable');
    }
}
PKϤ$Z�%���
�
Adependency-injection/Tests/Config/AutowireServiceResourceTest.phpnu�[���<?php

/*
 * This file is part of the Symfony package.
 *
 * (c) Fabien Potencier <fabien@symfony.com>
 *
 * For the full copyright and license information, please view the LICENSE
 * file that was distributed with this source code.
 */

namespace Symfony\Component\DependencyInjection\Tests\Config;

use Symfony\Component\DependencyInjection\Compiler\AutowirePass;
use Symfony\Component\DependencyInjection\Config\AutowireServiceResource;

class AutowireServiceResourceTest extends \PHPUnit_Framework_TestCase
{
    /**
     * @var AutowireServiceResource
     */
    private $resource;
    private $file;
    private $class;
    private $time;

    protected function setUp()
    {
        $this->file = realpath(sys_get_temp_dir()).'/tmp.php';
        $this->time = time();
        touch($this->file, $this->time);

        $this->class = __NAMESPACE__.'\Foo';
        $this->resource = new AutowireServiceResource(
            $this->class,
            $this->file,
            array()
        );
    }

    public function testToString()
    {
        $this->assertSame('service.autowire.'.$this->class, (string) $this->resource);
    }

    public function testSerializeUnserialize()
    {
        $unserialized = unserialize(serialize($this->resource));

        $this->assertEquals($this->resource, $unserialized);
    }

    public function testIsFresh()
    {
        $this->assertTrue($this->resource->isFresh($this->time), '->isFresh() returns true if the resource has not changed in same second');
        $this->assertTrue($this->resource->isFresh($this->time + 10), '->isFresh() returns true if the resource has not changed');
        $this->assertFalse($this->resource->isFresh($this->time - 86400), '->isFresh() returns false if the resource has been updated');
    }

    public function testIsFreshForDeletedResources()
    {
        unlink($this->file);

        $this->assertFalse($this->resource->isFresh($this->getStaleFileTime()), '->isFresh() returns false if the resource does not exist');
    }

    public function testIsNotFreshChangedResource()
    {
        $oldResource = new AutowireServiceResource(
            $this->class,
            $this->file,
            array('will_be_different')
        );

        // test with a stale file *and* a resource that *will* be different than the actual
        $this->assertFalse($oldResource->isFresh($this->getStaleFileTime()), '->isFresh() returns false if the constructor arguments have changed');
    }

    public function testIsFreshSameConstructorArgs()
    {
        $oldResource = AutowirePass::createResourceForClass(
            new \ReflectionClass(__NAMESPACE__.'\Foo')
        );

        // test with a stale file *but* the resource will not be changed
        $this->assertTrue($oldResource->isFresh($this->getStaleFileTime()), '->isFresh() returns false if the constructor arguments have changed');
    }

    public function testNotFreshIfClassNotFound()
    {
        $resource = new AutowireServiceResource(
            'Some\Non\Existent\Class',
            $this->file,
            array()
        );

        $this->assertFalse($resource->isFresh($this->getStaleFileTime()), '->isFresh() returns false if the class no longer exists');
    }

    protected function tearDown()
    {
        if (!file_exists($this->file)) {
            return;
        }

        unlink($this->file);
    }

    private function getStaleFileTime()
    {
        return $this->time - 10;
    }
}

class Foo
{
    public function __construct($foo)
    {
    }
}
PKϤ$Z��=)��3dependency-injection/Tests/Dumper/XmlDumperTest.phpnu�[���<?php

/*
 * This file is part of the Symfony package.
 *
 * (c) Fabien Potencier <fabien@symfony.com>
 *
 * For the full copyright and license information, please view the LICENSE
 * file that was distributed with this source code.
 */

namespace Symfony\Component\DependencyInjection\Tests\Dumper;

use Symfony\Component\DependencyInjection\ContainerBuilder;
use Symfony\Component\DependencyInjection\Dumper\XmlDumper;

class XmlDumperTest extends \PHPUnit_Framework_TestCase
{
    protected static $fixturesPath;

    public static function setUpBeforeClass()
    {
        self::$fixturesPath = realpath(__DIR__.'/../Fixtures/');
    }

    public function testDump()
    {
        $dumper = new XmlDumper(new ContainerBuilder());

        $this->assertXmlStringEqualsXmlFile(self::$fixturesPath.'/xml/services1.xml', $dumper->dump(), '->dump() dumps an empty container as an empty XML file');
    }

    public function testExportParameters()
    {
        $container = include self::$fixturesPath.'//containers/container8.php';
        $dumper = new XmlDumper($container);
        $this->assertXmlStringEqualsXmlFile(self::$fixturesPath.'/xml/services8.xml', $dumper->dump(), '->dump() dumps parameters');
    }

    public function testAddParameters()
    {
        $container = include self::$fixturesPath.'//containers/container8.php';
        $dumper = new XmlDumper($container);
        $this->assertXmlStringEqualsXmlFile(self::$fixturesPath.'/xml/services8.xml', $dumper->dump(), '->dump() dumps parameters');
    }

    public function testAddService()
    {
        $container = include self::$fixturesPath.'/containers/container9.php';
        $dumper = new XmlDumper($container);

        $this->assertEquals(str_replace('%path%', self::$fixturesPath.DIRECTORY_SEPARATOR.'includes'.DIRECTORY_SEPARATOR, file_get_contents(self::$fixturesPath.'/xml/services9.xml')), $dumper->dump(), '->dump() dumps services');

        $dumper = new XmlDumper($container = new ContainerBuilder());
        $container->register('foo', 'FooClass')->addArgument(new \stdClass());
        try {
            $dumper->dump();
            $this->fail('->dump() throws a RuntimeException if the container to be dumped has reference to objects or resources');
        } catch (\Exception $e) {
            $this->assertInstanceOf('\RuntimeException', $e, '->dump() throws a RuntimeException if the container to be dumped has reference to objects or resources');
            $this->assertEquals('Unable to dump a service container if a parameter is an object or a resource.', $e->getMessage(), '->dump() throws a RuntimeException if the container to be dumped has reference to objects or resources');
        }
    }

    public function testDumpAnonymousServices()
    {
        $container = include self::$fixturesPath.'/containers/container11.php';
        $dumper = new XmlDumper($container);
        $this->assertEquals('<?xml version="1.0" encoding="utf-8"?>
<container xmlns="http://symfony.com/schema/dic/services" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://symfony.com/schema/dic/services http://symfony.com/schema/dic/services/services-1.0.xsd">
  <services>
    <service id="foo" class="FooClass">
      <argument type="service">
        <service class="BarClass">
          <argument type="service">
            <service class="BazClass"/>
          </argument>
        </service>
      </argument>
    </service>
  </services>
</container>
', $dumper->dump());
    }

    public function testDumpEntities()
    {
        $container = include self::$fixturesPath.'/containers/container12.php';
        $dumper = new XmlDumper($container);
        $this->assertEquals("<?xml version=\"1.0\" encoding=\"utf-8\"?>
<container xmlns=\"http://symfony.com/schema/dic/services\" xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\" xsi:schemaLocation=\"http://symfony.com/schema/dic/services http://symfony.com/schema/dic/services/services-1.0.xsd\">
  <services>
    <service id=\"foo\" class=\"FooClass\Foo\">
      <tag name=\"foo&quot;bar\bar\" foo=\"foo&quot;barřž€\"/>
      <argument>foo&lt;&gt;&amp;bar</argument>
    </service>
  </services>
</container>
", $dumper->dump());
    }

    /**
     * @dataProvider provideDecoratedServicesData
     */
    public function testDumpDecoratedServices($expectedXmlDump, $container)
    {
        $dumper = new XmlDumper($container);
        $this->assertEquals($expectedXmlDump, $dumper->dump());
    }

    public function provideDecoratedServicesData()
    {
        $fixturesPath = realpath(__DIR__.'/../Fixtures/');

        return array(
            array("<?xml version=\"1.0\" encoding=\"utf-8\"?>
<container xmlns=\"http://symfony.com/schema/dic/services\" xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\" xsi:schemaLocation=\"http://symfony.com/schema/dic/services http://symfony.com/schema/dic/services/services-1.0.xsd\">
  <services>
    <service id=\"foo\" class=\"FooClass\Foo\" decorates=\"bar\" decoration-inner-name=\"bar.woozy\"/>
  </services>
</container>
", include $fixturesPath.'/containers/container15.php'),
            array("<?xml version=\"1.0\" encoding=\"utf-8\"?>
<container xmlns=\"http://symfony.com/schema/dic/services\" xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\" xsi:schemaLocation=\"http://symfony.com/schema/dic/services http://symfony.com/schema/dic/services/services-1.0.xsd\">
  <services>
    <service id=\"foo\" class=\"FooClass\Foo\" decorates=\"bar\"/>
  </services>
</container>
", include $fixturesPath.'/containers/container16.php'),
        );
    }

    /**
     * @dataProvider provideCompiledContainerData
     */
    public function testCompiledContainerCanBeDumped($containerFile)
    {
        $fixturesPath = __DIR__.'/../Fixtures';
        $container = require $fixturesPath.'/containers/'.$containerFile.'.php';
        $container->compile();
        $dumper = new XmlDumper($container);
        $dumper->dump();
    }

    public function provideCompiledContainerData()
    {
        return array(
            array('container8'),
            array('container9'),
            array('container11'),
            array('container12'),
            array('container14'),
        );
    }

    public function testDumpInlinedServices()
    {
        $container = include self::$fixturesPath.'/containers/container21.php';
        $dumper = new XmlDumper($container);

        $this->assertEquals(file_get_contents(self::$fixturesPath.'/xml/services21.xml'), $dumper->dump());
    }

    public function testDumpAutowireData()
    {
        $container = include self::$fixturesPath.'/containers/container24.php';
        $dumper = new XmlDumper($container);

        $this->assertEquals(file_get_contents(self::$fixturesPath.'/xml/services24.xml'), $dumper->dump());
    }
}
PKϤ$Z�&h��<�<3dependency-injection/Tests/Dumper/PhpDumperTest.phpnu�[���<?php

/*
 * This file is part of the Symfony package.
 *
 * (c) Fabien Potencier <fabien@symfony.com>
 *
 * For the full copyright and license information, please view the LICENSE
 * file that was distributed with this source code.
 */

namespace Symfony\Component\DependencyInjection\Tests\Dumper;

use DummyProxyDumper;
use Symfony\Component\DependencyInjection\ContainerBuilder;
use Symfony\Component\DependencyInjection\Dumper\PhpDumper;
use Symfony\Component\DependencyInjection\ParameterBag\ParameterBag;
use Symfony\Component\DependencyInjection\Reference;
use Symfony\Component\DependencyInjection\Definition;
use Symfony\Component\DependencyInjection\Variable;
use Symfony\Component\ExpressionLanguage\Expression;

require_once __DIR__.'/../Fixtures/includes/classes.php';

class PhpDumperTest extends \PHPUnit_Framework_TestCase
{
    protected static $fixturesPath;

    public static function setUpBeforeClass()
    {
        self::$fixturesPath = realpath(__DIR__.'/../Fixtures/');
    }

    public function testDump()
    {
        $dumper = new PhpDumper($container = new ContainerBuilder());

        $this->assertStringEqualsFile(self::$fixturesPath.'/php/services1.php', $dumper->dump(), '->dump() dumps an empty container as an empty PHP class');
        $this->assertStringEqualsFile(self::$fixturesPath.'/php/services1-1.php', $dumper->dump(array('class' => 'Container', 'base_class' => 'AbstractContainer', 'namespace' => 'Symfony\Component\DependencyInjection\Dump')), '->dump() takes a class and a base_class options');

        $container = new ContainerBuilder();
        new PhpDumper($container);
    }

    public function testDumpOptimizationString()
    {
        $definition = new Definition();
        $definition->setClass('stdClass');
        $definition->addArgument(array(
            'only dot' => '.',
            'concatenation as value' => '.\'\'.',
            'concatenation from the start value' => '\'\'.',
            '.' => 'dot as a key',
            '.\'\'.' => 'concatenation as a key',
            '\'\'.' => 'concatenation from the start key',
            'optimize concatenation' => 'string1%some_string%string2',
            'optimize concatenation with empty string' => 'string1%empty_value%string2',
            'optimize concatenation from the start' => '%empty_value%start',
            'optimize concatenation at the end' => 'end%empty_value%',
        ));

        $container = new ContainerBuilder();
        $container->setResourceTracking(false);
        $container->setDefinition('test', $definition);
        $container->setParameter('empty_value', '');
        $container->setParameter('some_string', '-');
        $container->compile();

        $dumper = new PhpDumper($container);
        $this->assertStringEqualsFile(self::$fixturesPath.'/php/services10.php', $dumper->dump(), '->dump() dumps an empty container as an empty PHP class');
    }

    public function testDumpRelativeDir()
    {
        $definition = new Definition();
        $definition->setClass('stdClass');
        $definition->addArgument('%foo%');
        $definition->addArgument(array('%foo%' => '%buz%/'));

        $container = new ContainerBuilder();
        $container->setDefinition('test', $definition);
        $container->setParameter('foo', 'wiz'.dirname(__DIR__));
        $container->setParameter('bar', __DIR__);
        $container->setParameter('baz', '%bar%/PhpDumperTest.php');
        $container->setParameter('buz', dirname(dirname(__DIR__)));
        $container->compile();

        $dumper = new PhpDumper($container);
        $this->assertStringEqualsFile(self::$fixturesPath.'/php/services12.php', $dumper->dump(array('file' => __FILE__)), '->dump() dumps __DIR__ relative strings');
    }

    /**
     * @dataProvider provideInvalidParameters
     * @expectedException \InvalidArgumentException
     */
    public function testExportParameters($parameters)
    {
        $dumper = new PhpDumper(new ContainerBuilder(new ParameterBag($parameters)));
        $dumper->dump();
    }

    public function provideInvalidParameters()
    {
        return array(
            array(array('foo' => new Definition('stdClass'))),
            array(array('foo' => new Expression('service("foo").foo() ~ (container.hasParameter("foo") ? parameter("foo") : "default")'))),
            array(array('foo' => new Reference('foo'))),
            array(array('foo' => new Variable('foo'))),
        );
    }

    public function testAddParameters()
    {
        $container = include self::$fixturesPath.'/containers/container8.php';
        $dumper = new PhpDumper($container);
        $this->assertStringEqualsFile(self::$fixturesPath.'/php/services8.php', $dumper->dump(), '->dump() dumps parameters');
    }

    public function testAddService()
    {
        // without compilation
        $container = include self::$fixturesPath.'/containers/container9.php';
        $dumper = new PhpDumper($container);
        $this->assertEquals(str_replace('%path%', str_replace('\\', '\\\\', self::$fixturesPath.DIRECTORY_SEPARATOR.'includes'.DIRECTORY_SEPARATOR), file_get_contents(self::$fixturesPath.'/php/services9.php')), $dumper->dump(), '->dump() dumps services');

        // with compilation
        $container = include self::$fixturesPath.'/containers/container9.php';
        $container->compile();
        $dumper = new PhpDumper($container);
        $this->assertEquals(str_replace('%path%', str_replace('\\', '\\\\', self::$fixturesPath.DIRECTORY_SEPARATOR.'includes'.DIRECTORY_SEPARATOR), file_get_contents(self::$fixturesPath.'/php/services9_compiled.php')), $dumper->dump(), '->dump() dumps services');

        $dumper = new PhpDumper($container = new ContainerBuilder());
        $container->register('foo', 'FooClass')->addArgument(new \stdClass());
        try {
            $dumper->dump();
            $this->fail('->dump() throws a RuntimeException if the container to be dumped has reference to objects or resources');
        } catch (\Exception $e) {
            $this->assertInstanceOf('\Symfony\Component\DependencyInjection\Exception\RuntimeException', $e, '->dump() throws a RuntimeException if the container to be dumped has reference to objects or resources');
            $this->assertEquals('Unable to dump a service container if a parameter is an object or a resource.', $e->getMessage(), '->dump() throws a RuntimeException if the container to be dumped has reference to objects or resources');
        }
    }

    public function testServicesWithAnonymousFactories()
    {
        $container = include self::$fixturesPath.'/containers/container19.php';
        $dumper = new PhpDumper($container);

        $this->assertStringEqualsFile(self::$fixturesPath.'/php/services19.php', $dumper->dump(), '->dump() dumps services with anonymous factories');
    }

    public function testAddServiceIdWithUnsupportedCharacters()
    {
        $class = 'Symfony_DI_PhpDumper_Test_Unsupported_Characters';
        $container = new ContainerBuilder();
        $container->register('bar$', 'FooClass');
        $container->register('bar$!', 'FooClass');
        $dumper = new PhpDumper($container);
        eval('?>'.$dumper->dump(array('class' => $class)));

        $this->assertTrue(method_exists($class, 'getBarService'));
        $this->assertTrue(method_exists($class, 'getBar2Service'));
    }

    public function testConflictingServiceIds()
    {
        $class = 'Symfony_DI_PhpDumper_Test_Conflicting_Service_Ids';
        $container = new ContainerBuilder();
        $container->register('foo_bar', 'FooClass');
        $container->register('foobar', 'FooClass');
        $dumper = new PhpDumper($container);
        eval('?>'.$dumper->dump(array('class' => $class)));

        $this->assertTrue(method_exists($class, 'getFooBarService'));
        $this->assertTrue(method_exists($class, 'getFoobar2Service'));
    }

    public function testConflictingMethodsWithParent()
    {
        $class = 'Symfony_DI_PhpDumper_Test_Conflicting_Method_With_Parent';
        $container = new ContainerBuilder();
        $container->register('bar', 'FooClass');
        $container->register('foo_bar', 'FooClass');
        $dumper = new PhpDumper($container);
        eval('?>'.$dumper->dump(array(
            'class' => $class,
            'base_class' => 'Symfony\Component\DependencyInjection\Tests\Fixtures\containers\CustomContainer',
        )));

        $this->assertTrue(method_exists($class, 'getBar2Service'));
        $this->assertTrue(method_exists($class, 'getFoobar2Service'));
    }

    /**
     * @dataProvider provideInvalidFactories
     * @expectedException \Symfony\Component\DependencyInjection\Exception\RuntimeException
     * @expectedExceptionMessage Cannot dump definition
     */
    public function testInvalidFactories($factory)
    {
        $container = new ContainerBuilder();
        $def = new Definition('stdClass');
        $def->setFactory($factory);
        $container->setDefinition('bar', $def);
        $dumper = new PhpDumper($container);
        $dumper->dump();
    }

    public function provideInvalidFactories()
    {
        return array(
            array(array('', 'method')),
            array(array('class', '')),
            array(array('...', 'method')),
            array(array('class', '...')),
        );
    }

    public function testAliases()
    {
        $container = include self::$fixturesPath.'/containers/container9.php';
        $container->compile();
        $dumper = new PhpDumper($container);
        eval('?>'.$dumper->dump(array('class' => 'Symfony_DI_PhpDumper_Test_Aliases')));

        $container = new \Symfony_DI_PhpDumper_Test_Aliases();
        $container->set('foo', $foo = new \stdClass());
        $this->assertSame($foo, $container->get('foo'));
        $this->assertSame($foo, $container->get('alias_for_foo'));
        $this->assertSame($foo, $container->get('alias_for_alias'));
    }

    public function testFrozenContainerWithoutAliases()
    {
        $container = new ContainerBuilder();
        $container->compile();

        $dumper = new PhpDumper($container);
        eval('?>'.$dumper->dump(array('class' => 'Symfony_DI_PhpDumper_Test_Frozen_No_Aliases')));

        $container = new \Symfony_DI_PhpDumper_Test_Frozen_No_Aliases();
        $this->assertFalse($container->has('foo'));
    }

    public function testOverrideServiceWhenUsingADumpedContainer()
    {
        require_once self::$fixturesPath.'/php/services9.php';
        require_once self::$fixturesPath.'/includes/foo.php';

        $container = new \ProjectServiceContainer();
        $container->set('bar', $bar = new \stdClass());
        $container->setParameter('foo_bar', 'foo_bar');

        $this->assertSame($bar, $container->get('bar'), '->set() overrides an already defined service');
    }

    public function testOverrideServiceWhenUsingADumpedContainerAndServiceIsUsedFromAnotherOne()
    {
        require_once self::$fixturesPath.'/php/services9.php';
        require_once self::$fixturesPath.'/includes/foo.php';
        require_once self::$fixturesPath.'/includes/classes.php';

        $container = new \ProjectServiceContainer();
        $container->set('bar', $bar = new \stdClass());

        $this->assertSame($bar, $container->get('foo')->bar, '->set() overrides an already defined service');
    }

    /**
     * @expectedException \Symfony\Component\DependencyInjection\Exception\ServiceCircularReferenceException
     */
    public function testCircularReference()
    {
        $container = new ContainerBuilder();
        $container->register('foo', 'stdClass')->addArgument(new Reference('bar'));
        $container->register('bar', 'stdClass')->setPublic(false)->addMethodCall('setA', array(new Reference('baz')));
        $container->register('baz', 'stdClass')->addMethodCall('setA', array(new Reference('foo')));
        $container->compile();

        $dumper = new PhpDumper($container);
        $dumper->dump();
    }

    public function testDumpAutowireData()
    {
        $container = include self::$fixturesPath.'/containers/container24.php';
        $dumper = new PhpDumper($container);

        $this->assertEquals(file_get_contents(self::$fixturesPath.'/php/services24.php'), $dumper->dump());
    }

    public function testInlinedDefinitionReferencingServiceContainer()
    {
        $container = new ContainerBuilder();
        $container->register('foo', 'stdClass')->addMethodCall('add', array(new Reference('service_container')))->setPublic(false);
        $container->register('bar', 'stdClass')->addArgument(new Reference('foo'));
        $container->compile();

        $dumper = new PhpDumper($container);
        $this->assertStringEqualsFile(self::$fixturesPath.'/php/services13.php', $dumper->dump(), '->dump() dumps inline definitions which reference service_container');
    }

    public function testInitializePropertiesBeforeMethodCalls()
    {
        require_once self::$fixturesPath.'/includes/classes.php';

        $container = new ContainerBuilder();
        $container->register('foo', 'stdClass');
        $container->register('bar', 'MethodCallClass')
            ->setProperty('simple', 'bar')
            ->setProperty('complex', new Reference('foo'))
            ->addMethodCall('callMe');
        $container->compile();

        $dumper = new PhpDumper($container);
        eval('?>'.$dumper->dump(array('class' => 'Symfony_DI_PhpDumper_Test_Properties_Before_Method_Calls')));

        $container = new \Symfony_DI_PhpDumper_Test_Properties_Before_Method_Calls();
        $this->assertTrue($container->get('bar')->callPassed(), '->dump() initializes properties before method calls');
    }

    public function testCircularReferenceAllowanceForLazyServices()
    {
        $container = new ContainerBuilder();
        $container->register('foo', 'stdClass')->addArgument(new Reference('bar'));
        $container->register('bar', 'stdClass')->setLazy(true)->addArgument(new Reference('foo'));
        $container->compile();

        $dumper = new PhpDumper($container);
        $dumper->dump();
    }

    public function testCircularReferenceAllowanceForInlinedDefinitionsForLazyServices()
    {
        /*
         *   test graph:
         *              [connection] -> [event_manager] --> [entity_manager](lazy)
         *                                                           |
         *                                                           --(call)- addEventListener ("@lazy_service")
         *
         *              [lazy_service](lazy) -> [entity_manager](lazy)
         *
         */

        $container = new ContainerBuilder();

        $eventManagerDefinition = new Definition('stdClass');

        $connectionDefinition = $container->register('connection', 'stdClass');
        $connectionDefinition->addArgument($eventManagerDefinition);

        $container->register('entity_manager', 'stdClass')
            ->setLazy(true)
            ->addArgument(new Reference('connection'));

        $lazyServiceDefinition = $container->register('lazy_service', 'stdClass');
        $lazyServiceDefinition->setLazy(true);
        $lazyServiceDefinition->addArgument(new Reference('entity_manager'));

        $eventManagerDefinition->addMethodCall('addEventListener', array(new Reference('lazy_service')));

        $container->compile();

        $dumper = new PhpDumper($container);

        $dumper->setProxyDumper(new DummyProxyDumper());
        $dumper->dump();
    }
}
PKϤ$Zm@4�
�
8dependency-injection/Tests/Dumper/GraphvizDumperTest.phpnu�[���<?php

/*
 * This file is part of the Symfony package.
 *
 * (c) Fabien Potencier <fabien@symfony.com>
 *
 * For the full copyright and license information, please view the LICENSE
 * file that was distributed with this source code.
 */

namespace Symfony\Component\DependencyInjection\Tests\Dumper;

use Symfony\Component\DependencyInjection\ContainerBuilder;
use Symfony\Component\DependencyInjection\Dumper\GraphvizDumper;

class GraphvizDumperTest extends \PHPUnit_Framework_TestCase
{
    protected static $fixturesPath;

    public static function setUpBeforeClass()
    {
        self::$fixturesPath = __DIR__.'/../Fixtures/';
    }

    public function testDump()
    {
        $dumper = new GraphvizDumper($container = new ContainerBuilder());

        $this->assertStringEqualsFile(self::$fixturesPath.'/graphviz/services1.dot', $dumper->dump(), '->dump() dumps an empty container as an empty dot file');

        $container = include self::$fixturesPath.'/containers/container9.php';
        $dumper = new GraphvizDumper($container);
        $this->assertEquals(str_replace('%path%', __DIR__, file_get_contents(self::$fixturesPath.'/graphviz/services9.dot')), $dumper->dump(), '->dump() dumps services');

        $container = include self::$fixturesPath.'/containers/container10.php';
        $dumper = new GraphvizDumper($container);
        $this->assertEquals(str_replace('%path%', __DIR__, file_get_contents(self::$fixturesPath.'/graphviz/services10.dot')), $dumper->dump(), '->dump() dumps services');

        $container = include self::$fixturesPath.'/containers/container10.php';
        $dumper = new GraphvizDumper($container);
        $this->assertEquals($dumper->dump(array(
            'graph' => array('ratio' => 'normal'),
            'node' => array('fontsize' => 13, 'fontname' => 'Verdana', 'shape' => 'square'),
            'edge' => array('fontsize' => 12, 'fontname' => 'Verdana', 'color' => 'white', 'arrowhead' => 'closed', 'arrowsize' => 1),
            'node.instance' => array('fillcolor' => 'green', 'style' => 'empty'),
            'node.definition' => array('fillcolor' => 'grey'),
            'node.missing' => array('fillcolor' => 'red', 'style' => 'empty'),
        )), str_replace('%path%', __DIR__, file_get_contents(self::$fixturesPath.'/graphviz/services10-1.dot')), '->dump() dumps services');
    }

    public function testDumpWithFrozenContainer()
    {
        $container = include self::$fixturesPath.'/containers/container13.php';
        $dumper = new GraphvizDumper($container);
        $this->assertEquals(str_replace('%path%', __DIR__, file_get_contents(self::$fixturesPath.'/graphviz/services13.dot')), $dumper->dump(), '->dump() dumps services');
    }

    public function testDumpWithFrozenCustomClassContainer()
    {
        $container = include self::$fixturesPath.'/containers/container14.php';
        $dumper = new GraphvizDumper($container);
        $this->assertEquals(str_replace('%path%', __DIR__, file_get_contents(self::$fixturesPath.'/graphviz/services14.dot')), $dumper->dump(), '->dump() dumps services');
    }

    public function testDumpWithUnresolvedParameter()
    {
        $container = include self::$fixturesPath.'/containers/container17.php';
        $dumper = new GraphvizDumper($container);

        $this->assertEquals(str_replace('%path%', __DIR__, file_get_contents(self::$fixturesPath.'/graphviz/services17.dot')), $dumper->dump(), '->dump() dumps services');
    }
}
PKϤ$Z��5N��4dependency-injection/Tests/Dumper/YamlDumperTest.phpnu�[���<?php

/*
 * This file is part of the Symfony package.
 *
 * (c) Fabien Potencier <fabien@symfony.com>
 *
 * For the full copyright and license information, please view the LICENSE
 * file that was distributed with this source code.
 */

namespace Symfony\Component\DependencyInjection\Tests\Dumper;

use Symfony\Component\DependencyInjection\ContainerBuilder;
use Symfony\Component\DependencyInjection\Dumper\YamlDumper;
use Symfony\Component\Yaml\Yaml;

class YamlDumperTest extends \PHPUnit_Framework_TestCase
{
    protected static $fixturesPath;

    public static function setUpBeforeClass()
    {
        self::$fixturesPath = realpath(__DIR__.'/../Fixtures/');
    }

    public function testDump()
    {
        $dumper = new YamlDumper($container = new ContainerBuilder());

        $this->assertEqualYamlStructure(file_get_contents(self::$fixturesPath.'/yaml/services1.yml'), $dumper->dump(), '->dump() dumps an empty container as an empty YAML file');
    }

    public function testAddParameters()
    {
        $container = include self::$fixturesPath.'/containers/container8.php';
        $dumper = new YamlDumper($container);
        $this->assertEqualYamlStructure(file_get_contents(self::$fixturesPath.'/yaml/services8.yml'), $dumper->dump(), '->dump() dumps parameters');
    }

    public function testAddService()
    {
        $container = include self::$fixturesPath.'/containers/container9.php';
        $dumper = new YamlDumper($container);
        $this->assertEqualYamlStructure(str_replace('%path%', self::$fixturesPath.DIRECTORY_SEPARATOR.'includes'.DIRECTORY_SEPARATOR, file_get_contents(self::$fixturesPath.'/yaml/services9.yml')), $dumper->dump(), '->dump() dumps services');

        $dumper = new YamlDumper($container = new ContainerBuilder());
        $container->register('foo', 'FooClass')->addArgument(new \stdClass());
        try {
            $dumper->dump();
            $this->fail('->dump() throws a RuntimeException if the container to be dumped has reference to objects or resources');
        } catch (\Exception $e) {
            $this->assertInstanceOf('\RuntimeException', $e, '->dump() throws a RuntimeException if the container to be dumped has reference to objects or resources');
            $this->assertEquals('Unable to dump a service container if a parameter is an object or a resource.', $e->getMessage(), '->dump() throws a RuntimeException if the container to be dumped has reference to objects or resources');
        }
    }

    public function testDumpAutowireData()
    {
        $container = include self::$fixturesPath.'/containers/container24.php';
        $dumper = new YamlDumper($container);
        $this->assertStringEqualsFile(self::$fixturesPath.'/yaml/services24.yml', $dumper->dump());
    }

    private function assertEqualYamlStructure($yaml, $expected, $message = '')
    {
        $this->assertEquals(Yaml::parse($expected), Yaml::parse($yaml), $message);
    }
}
PKϤ$Z4[�ZWZW8dependency-injection/Tests/Compiler/AutowirePassTest.phpnu�[���<?php

/*
 * This file is part of the Symfony package.
 *
 * (c) Fabien Potencier <fabien@symfony.com>
 *
 * For the full copyright and license information, please view the LICENSE
 * file that was distributed with this source code.
 */

namespace Symfony\Component\DependencyInjection\Tests\Compiler;

use Symfony\Component\DependencyInjection\Compiler\AutowirePass;
use Symfony\Component\DependencyInjection\ContainerBuilder;
use Symfony\Component\DependencyInjection\Reference;
use Symfony\Component\DependencyInjection\Tests\Fixtures\includes\FooVariadic;

/**
 * @author Kévin Dunglas <dunglas@gmail.com>
 */
class AutowirePassTest extends \PHPUnit_Framework_TestCase
{
    public function testProcess()
    {
        $container = new ContainerBuilder();

        $container->register('foo', __NAMESPACE__.'\Foo');
        $barDefinition = $container->register('bar', __NAMESPACE__.'\Bar');
        $barDefinition->setAutowired(true);

        $pass = new AutowirePass();
        $pass->process($container);

        $this->assertCount(1, $container->getDefinition('bar')->getArguments());
        $this->assertEquals('foo', (string) $container->getDefinition('bar')->getArgument(0));
    }

    /**
     * @requires PHP 5.6
     */
    public function testProcessVariadic()
    {
        $container = new ContainerBuilder();
        $container->register('foo', Foo::class);
        $definition = $container->register('fooVariadic', FooVariadic::class);
        $definition->setAutowired(true);

        $pass = new AutowirePass();
        $pass->process($container);

        $this->assertCount(1, $container->getDefinition('fooVariadic')->getArguments());
        $this->assertEquals('foo', (string) $container->getDefinition('fooVariadic')->getArgument(0));
    }

    public function testProcessAutowireParent()
    {
        $container = new ContainerBuilder();

        $container->register('b', __NAMESPACE__.'\B');
        $cDefinition = $container->register('c', __NAMESPACE__.'\C');
        $cDefinition->setAutowired(true);

        $pass = new AutowirePass();
        $pass->process($container);

        $this->assertCount(1, $container->getDefinition('c')->getArguments());
        $this->assertEquals('b', (string) $container->getDefinition('c')->getArgument(0));
    }

    public function testProcessAutowireInterface()
    {
        $container = new ContainerBuilder();

        $container->register('f', __NAMESPACE__.'\F');
        $gDefinition = $container->register('g', __NAMESPACE__.'\G');
        $gDefinition->setAutowired(true);

        $pass = new AutowirePass();
        $pass->process($container);

        $this->assertCount(3, $container->getDefinition('g')->getArguments());
        $this->assertEquals('f', (string) $container->getDefinition('g')->getArgument(0));
        $this->assertEquals('f', (string) $container->getDefinition('g')->getArgument(1));
        $this->assertEquals('f', (string) $container->getDefinition('g')->getArgument(2));
    }

    public function testCompleteExistingDefinition()
    {
        $container = new ContainerBuilder();

        $container->register('b', __NAMESPACE__.'\B');
        $container->register('f', __NAMESPACE__.'\F');
        $hDefinition = $container->register('h', __NAMESPACE__.'\H')->addArgument(new Reference('b'));
        $hDefinition->setAutowired(true);

        $pass = new AutowirePass();
        $pass->process($container);

        $this->assertCount(2, $container->getDefinition('h')->getArguments());
        $this->assertEquals('b', (string) $container->getDefinition('h')->getArgument(0));
        $this->assertEquals('f', (string) $container->getDefinition('h')->getArgument(1));
    }

    public function testCompleteExistingDefinitionWithNotDefinedArguments()
    {
        $container = new ContainerBuilder();

        $container->register('b', __NAMESPACE__.'\B');
        $container->register('f', __NAMESPACE__.'\F');
        $hDefinition = $container->register('h', __NAMESPACE__.'\H')->addArgument('')->addArgument('');
        $hDefinition->setAutowired(true);

        $pass = new AutowirePass();
        $pass->process($container);

        $this->assertCount(2, $container->getDefinition('h')->getArguments());
        $this->assertEquals('b', (string) $container->getDefinition('h')->getArgument(0));
        $this->assertEquals('f', (string) $container->getDefinition('h')->getArgument(1));
    }

    /**
     * @expectedException \Symfony\Component\DependencyInjection\Exception\RuntimeException
     * @expectedExceptionMessage Unable to autowire argument of type "Symfony\Component\DependencyInjection\Tests\Compiler\CollisionInterface" for the service "a". Multiple services exist for this interface (c1, c2, c3).
     */
    public function testTypeCollision()
    {
        $container = new ContainerBuilder();

        $container->register('c1', __NAMESPACE__.'\CollisionA');
        $container->register('c2', __NAMESPACE__.'\CollisionB');
        $container->register('c3', __NAMESPACE__.'\CollisionB');
        $aDefinition = $container->register('a', __NAMESPACE__.'\CannotBeAutowired');
        $aDefinition->setAutowired(true);

        $pass = new AutowirePass();
        $pass->process($container);
    }

    /**
     * @expectedException \Symfony\Component\DependencyInjection\Exception\RuntimeException
     * @expectedExceptionMessage Unable to autowire argument of type "Symfony\Component\DependencyInjection\Tests\Compiler\Foo" for the service "a". Multiple services exist for this class (a1, a2).
     */
    public function testTypeNotGuessable()
    {
        $container = new ContainerBuilder();

        $container->register('a1', __NAMESPACE__.'\Foo');
        $container->register('a2', __NAMESPACE__.'\Foo');
        $aDefinition = $container->register('a', __NAMESPACE__.'\NotGuessableArgument');
        $aDefinition->setAutowired(true);

        $pass = new AutowirePass();
        $pass->process($container);
    }

    /**
     * @expectedException \Symfony\Component\DependencyInjection\Exception\RuntimeException
     * @expectedExceptionMessage Unable to autowire argument of type "Symfony\Component\DependencyInjection\Tests\Compiler\A" for the service "a". Multiple services exist for this class (a1, a2).
     */
    public function testTypeNotGuessableWithSubclass()
    {
        $container = new ContainerBuilder();

        $container->register('a1', __NAMESPACE__.'\B');
        $container->register('a2', __NAMESPACE__.'\B');
        $aDefinition = $container->register('a', __NAMESPACE__.'\NotGuessableArgumentForSubclass');
        $aDefinition->setAutowired(true);

        $pass = new AutowirePass();
        $pass->process($container);
    }

    /**
     * @expectedException \Symfony\Component\DependencyInjection\Exception\RuntimeException
     * @expectedExceptionMessage Unable to autowire argument of type "Symfony\Component\DependencyInjection\Tests\Compiler\CollisionInterface" for the service "a". No services were found matching this interface and it cannot be auto-registered.
     */
    public function testTypeNotGuessableNoServicesFound()
    {
        $container = new ContainerBuilder();

        $aDefinition = $container->register('a', __NAMESPACE__.'\CannotBeAutowired');
        $aDefinition->setAutowired(true);

        $pass = new AutowirePass();
        $pass->process($container);
    }

    public function testTypeNotGuessableWithTypeSet()
    {
        $container = new ContainerBuilder();

        $container->register('a1', __NAMESPACE__.'\Foo');
        $container->register('a2', __NAMESPACE__.'\Foo')->addAutowiringType(__NAMESPACE__.'\Foo');
        $aDefinition = $container->register('a', __NAMESPACE__.'\NotGuessableArgument');
        $aDefinition->setAutowired(true);

        $pass = new AutowirePass();
        $pass->process($container);

        $this->assertCount(1, $container->getDefinition('a')->getArguments());
        $this->assertEquals('a2', (string) $container->getDefinition('a')->getArgument(0));
    }

    public function testWithTypeSet()
    {
        $container = new ContainerBuilder();

        $container->register('c1', __NAMESPACE__.'\CollisionA');
        $container->register('c2', __NAMESPACE__.'\CollisionB')->addAutowiringType(__NAMESPACE__.'\CollisionInterface');
        $aDefinition = $container->register('a', __NAMESPACE__.'\CannotBeAutowired');
        $aDefinition->setAutowired(true);

        $pass = new AutowirePass();
        $pass->process($container);

        $this->assertCount(1, $container->getDefinition('a')->getArguments());
        $this->assertEquals('c2', (string) $container->getDefinition('a')->getArgument(0));
    }

    public function testCreateDefinition()
    {
        $container = new ContainerBuilder();

        $coopTilleulsDefinition = $container->register('coop_tilleuls', __NAMESPACE__.'\LesTilleuls');
        $coopTilleulsDefinition->setAutowired(true);

        $pass = new AutowirePass();
        $pass->process($container);

        $this->assertCount(1, $container->getDefinition('coop_tilleuls')->getArguments());
        $this->assertEquals('autowired.symfony\component\dependencyinjection\tests\compiler\dunglas', $container->getDefinition('coop_tilleuls')->getArgument(0));

        $dunglasDefinition = $container->getDefinition('autowired.Symfony\Component\DependencyInjection\Tests\Compiler\Dunglas');
        $this->assertEquals(__NAMESPACE__.'\Dunglas', $dunglasDefinition->getClass());
        $this->assertFalse($dunglasDefinition->isPublic());
        $this->assertCount(1, $dunglasDefinition->getArguments());
        $this->assertEquals('autowired.symfony\component\dependencyinjection\tests\compiler\lille', $dunglasDefinition->getArgument(0));

        $lilleDefinition = $container->getDefinition('autowired.Symfony\Component\DependencyInjection\Tests\Compiler\Lille');
        $this->assertEquals(__NAMESPACE__.'\Lille', $lilleDefinition->getClass());
    }

    public function testResolveParameter()
    {
        $container = new ContainerBuilder();

        $container->setParameter('class_name', __NAMESPACE__.'\Foo');
        $container->register('foo', '%class_name%');
        $barDefinition = $container->register('bar', __NAMESPACE__.'\Bar');
        $barDefinition->setAutowired(true);

        $pass = new AutowirePass();
        $pass->process($container);

        $this->assertEquals('foo', $container->getDefinition('bar')->getArgument(0));
    }

    public function testOptionalParameter()
    {
        $container = new ContainerBuilder();

        $container->register('a', __NAMESPACE__.'\A');
        $container->register('foo', __NAMESPACE__.'\Foo');
        $optDefinition = $container->register('opt', __NAMESPACE__.'\OptionalParameter');
        $optDefinition->setAutowired(true);

        $pass = new AutowirePass();
        $pass->process($container);

        $definition = $container->getDefinition('opt');
        $this->assertNull($definition->getArgument(0));
        $this->assertEquals('a', $definition->getArgument(1));
        $this->assertEquals('foo', $definition->getArgument(2));
    }

    public function testDontTriggerAutowiring()
    {
        $container = new ContainerBuilder();

        $container->register('foo', __NAMESPACE__.'\Foo');
        $container->register('bar', __NAMESPACE__.'\Bar');

        $pass = new AutowirePass();
        $pass->process($container);

        $this->assertCount(0, $container->getDefinition('bar')->getArguments());
    }

    /**
     * @expectedException \Symfony\Component\DependencyInjection\Exception\RuntimeException
     * @expectedExceptionMessage Cannot autowire argument 2 for Symfony\Component\DependencyInjection\Tests\Compiler\BadTypeHintedArgument because the type-hinted class does not exist (Class Symfony\Component\DependencyInjection\Tests\Compiler\NotARealClass does not exist).
     */
    public function testClassNotFoundThrowsException()
    {
        $container = new ContainerBuilder();

        $aDefinition = $container->register('a', __NAMESPACE__.'\BadTypeHintedArgument');
        $aDefinition->setAutowired(true);

        $pass = new AutowirePass();
        $pass->process($container);
    }

    /**
     * @expectedException \Symfony\Component\DependencyInjection\Exception\RuntimeException
     * @expectedExceptionMessage Cannot autowire argument 2 for Symfony\Component\DependencyInjection\Tests\Compiler\BadParentTypeHintedArgument because the type-hinted class does not exist (Class Symfony\Component\DependencyInjection\Tests\Compiler\OptionalServiceClass does not exist).
     */
    public function testParentClassNotFoundThrowsException()
    {
        $container = new ContainerBuilder();

        $aDefinition = $container->register('a', __NAMESPACE__.'\BadParentTypeHintedArgument');
        $aDefinition->setAutowired(true);

        $pass = new AutowirePass();
        $pass->process($container);
    }

    public function testDontUseAbstractServices()
    {
        $container = new ContainerBuilder();

        $container->register('abstract_foo', __NAMESPACE__.'\Foo')->setAbstract(true);
        $container->register('foo', __NAMESPACE__.'\Foo');
        $container->register('bar', __NAMESPACE__.'\Bar')->setAutowired(true);

        $pass = new AutowirePass();
        $pass->process($container);

        $arguments = $container->getDefinition('bar')->getArguments();
        $this->assertSame('foo', (string) $arguments[0]);
    }

    public function testSomeSpecificArgumentsAreSet()
    {
        $container = new ContainerBuilder();

        $container->register('foo', __NAMESPACE__.'\Foo');
        $container->register('a', __NAMESPACE__.'\A');
        $container->register('dunglas', __NAMESPACE__.'\Dunglas');
        $container->register('multiple', __NAMESPACE__.'\MultipleArguments')
            ->setAutowired(true)
            // set the 2nd (index 1) argument only: autowire the first and third
            // args are: A, Foo, Dunglas
            ->setArguments(array(
                1 => new Reference('foo'),
            ));

        $pass = new AutowirePass();
        $pass->process($container);

        $definition = $container->getDefinition('multiple');
        $this->assertEquals(
            array(
                new Reference('a'),
                new Reference('foo'),
                new Reference('dunglas'),
            ),
            $definition->getArguments()
        );
    }

    /**
     * @expectedException \Symfony\Component\DependencyInjection\Exception\RuntimeException
     * @expectedExceptionMessage Unable to autowire argument index 1 ($foo) for the service "arg_no_type_hint". If this is an object, give it a type-hint. Otherwise, specify this argument's value explicitly.
     */
    public function testScalarArgsCannotBeAutowired()
    {
        $container = new ContainerBuilder();

        $container->register('a', __NAMESPACE__.'\A');
        $container->register('dunglas', __NAMESPACE__.'\Dunglas');
        $container->register('arg_no_type_hint', __NAMESPACE__.'\MultipleArguments')
            ->setAutowired(true);

        $pass = new AutowirePass();
        $pass->process($container);

        $container->getDefinition('arg_no_type_hint');
    }

    /**
     * @expectedException \Symfony\Component\DependencyInjection\Exception\RuntimeException
     * @expectedExceptionMessage Unable to autowire argument index 1 ($foo) for the service "not_really_optional_scalar". If this is an object, give it a type-hint. Otherwise, specify this argument's value explicitly.
     */
    public function testOptionalScalarNotReallyOptionalThrowException()
    {
        $container = new ContainerBuilder();

        $container->register('a', __NAMESPACE__.'\A');
        $container->register('lille', __NAMESPACE__.'\Lille');
        $container->register('not_really_optional_scalar', __NAMESPACE__.'\MultipleArgumentsOptionalScalarNotReallyOptional')
            ->setAutowired(true);

        $pass = new AutowirePass();
        $pass->process($container);
    }

    public function testOptionalScalarArgsDontMessUpOrder()
    {
        $container = new ContainerBuilder();

        $container->register('a', __NAMESPACE__.'\A');
        $container->register('lille', __NAMESPACE__.'\Lille');
        $container->register('with_optional_scalar', __NAMESPACE__.'\MultipleArgumentsOptionalScalar')
            ->setAutowired(true);

        $pass = new AutowirePass();
        $pass->process($container);

        $definition = $container->getDefinition('with_optional_scalar');
        $this->assertEquals(
            array(
                new Reference('a'),
                // use the default value
                'default_val',
                new Reference('lille'),
            ),
            $definition->getArguments()
        );
    }

    public function testOptionalScalarArgsNotPassedIfLast()
    {
        $container = new ContainerBuilder();

        $container->register('a', __NAMESPACE__.'\A');
        $container->register('lille', __NAMESPACE__.'\Lille');
        $container->register('with_optional_scalar_last', __NAMESPACE__.'\MultipleArgumentsOptionalScalarLast')
            ->setAutowired(true);

        $pass = new AutowirePass();
        $pass->process($container);

        $definition = $container->getDefinition('with_optional_scalar_last');
        $this->assertEquals(
            array(
                new Reference('a'),
                new Reference('lille'),
                // third arg shouldn't *need* to be passed
                // but that's hard to "pull of" with autowiring, so
                // this assumes passing the default val is ok
                'some_val',
            ),
            $definition->getArguments()
        );
    }

    /**
     * @dataProvider getCreateResourceTests
     */
    public function testCreateResourceForClass($className, $isEqual)
    {
        $startingResource = AutowirePass::createResourceForClass(
            new \ReflectionClass(__NAMESPACE__.'\ClassForResource')
        );
        $newResource = AutowirePass::createResourceForClass(
            new \ReflectionClass(__NAMESPACE__.'\\'.$className)
        );

        // hack so the objects don't differ by the class name
        $startingReflObject = new \ReflectionObject($startingResource);
        $reflProp = $startingReflObject->getProperty('class');
        $reflProp->setAccessible(true);
        $reflProp->setValue($startingResource, __NAMESPACE__.'\\'.$className);

        if ($isEqual) {
            $this->assertEquals($startingResource, $newResource);
        } else {
            $this->assertNotEquals($startingResource, $newResource);
        }
    }

    public function getCreateResourceTests()
    {
        return array(
            array('IdenticalClassResource', true),
            array('ClassChangedConstructorArgs', false),
        );
    }

    public function testIgnoreServiceWithClassNotExisting()
    {
        $container = new ContainerBuilder();

        $container->register('class_not_exist', __NAMESPACE__.'\OptionalServiceClass');

        $barDefinition = $container->register('bar', __NAMESPACE__.'\Bar');
        $barDefinition->setAutowired(true);

        $pass = new AutowirePass();
        $pass->process($container);

        $this->assertTrue($container->hasDefinition('bar'));
    }

    public function testEmptyStringIsKept()
    {
        $container = new ContainerBuilder();

        $container->register('a', __NAMESPACE__.'\A');
        $container->register('lille', __NAMESPACE__.'\Lille');
        $container->register('foo', __NAMESPACE__.'\MultipleArgumentsOptionalScalar')
            ->setAutowired(true)
            ->setArguments(array('', ''));

        $pass = new AutowirePass();
        $pass->process($container);

        $this->assertEquals(array(new Reference('a'), '', new Reference('lille')), $container->getDefinition('foo')->getArguments());
    }
}

class Foo
{
}

class Bar
{
    public function __construct(Foo $foo)
    {
    }
}

class A
{
}

class B extends A
{
}

class C
{
    public function __construct(A $a)
    {
    }
}

interface DInterface
{
}

interface EInterface extends DInterface
{
}

interface IInterface
{
}

class I implements IInterface
{
}

class F extends I implements EInterface
{
}

class G
{
    public function __construct(DInterface $d, EInterface $e, IInterface $i)
    {
    }
}

class H
{
    public function __construct(B $b, DInterface $d)
    {
    }
}

interface CollisionInterface
{
}

class CollisionA implements CollisionInterface
{
}

class CollisionB implements CollisionInterface
{
}

class CannotBeAutowired
{
    public function __construct(CollisionInterface $collision)
    {
    }
}

class Lille
{
}

class Dunglas
{
    public function __construct(Lille $l)
    {
    }
}

class LesTilleuls
{
    public function __construct(Dunglas $k)
    {
    }
}

class OptionalParameter
{
    public function __construct(CollisionInterface $c = null, A $a, Foo $f = null)
    {
    }
}

class BadTypeHintedArgument
{
    public function __construct(Dunglas $k, NotARealClass $r)
    {
    }
}
class BadParentTypeHintedArgument
{
    public function __construct(Dunglas $k, OptionalServiceClass $r)
    {
    }
}
class NotGuessableArgument
{
    public function __construct(Foo $k)
    {
    }
}
class NotGuessableArgumentForSubclass
{
    public function __construct(A $k)
    {
    }
}
class MultipleArguments
{
    public function __construct(A $k, $foo, Dunglas $dunglas)
    {
    }
}

class MultipleArgumentsOptionalScalar
{
    public function __construct(A $a, $foo = 'default_val', Lille $lille = null)
    {
    }
}
class MultipleArgumentsOptionalScalarLast
{
    public function __construct(A $a, Lille $lille, $foo = 'some_val')
    {
    }
}
class MultipleArgumentsOptionalScalarNotReallyOptional
{
    public function __construct(A $a, $foo = 'default_val', Lille $lille)
    {
    }
}

/*
 * Classes used for testing createResourceForClass
 */
class ClassForResource
{
    public function __construct($foo, Bar $bar = null)
    {
    }

    public function setBar(Bar $bar)
    {
    }
}
class IdenticalClassResource extends ClassForResource
{
}
class ClassChangedConstructorArgs extends ClassForResource
{
    public function __construct($foo, Bar $bar, $baz)
    {
    }
}
PKϤ$Z™H�X
X
Gdependency-injection/Tests/Compiler/RemoveUnusedDefinitionsPassTest.phpnu�[���<?php

/*
 * This file is part of the Symfony package.
 *
 * (c) Fabien Potencier <fabien@symfony.com>
 *
 * For the full copyright and license information, please view the LICENSE
 * file that was distributed with this source code.
 */

namespace Symfony\Component\DependencyInjection\Tests\Compiler;

use Symfony\Component\DependencyInjection\Compiler\AnalyzeServiceReferencesPass;
use Symfony\Component\DependencyInjection\Compiler\RepeatedPass;
use Symfony\Component\DependencyInjection\Compiler\RemoveUnusedDefinitionsPass;
use Symfony\Component\DependencyInjection\Definition;
use Symfony\Component\DependencyInjection\Reference;
use Symfony\Component\DependencyInjection\ContainerBuilder;

class RemoveUnusedDefinitionsPassTest extends \PHPUnit_Framework_TestCase
{
    public function testProcess()
    {
        $container = new ContainerBuilder();
        $container
            ->register('foo')
            ->setPublic(false)
        ;
        $container
            ->register('bar')
            ->setPublic(false)
        ;
        $container
            ->register('moo')
            ->setArguments(array(new Reference('bar')))
        ;

        $this->process($container);

        $this->assertFalse($container->hasDefinition('foo'));
        $this->assertTrue($container->hasDefinition('bar'));
        $this->assertTrue($container->hasDefinition('moo'));
    }

    public function testProcessRemovesUnusedDefinitionsRecursively()
    {
        $container = new ContainerBuilder();
        $container
            ->register('foo')
            ->setPublic(false)
        ;
        $container
            ->register('bar')
            ->setArguments(array(new Reference('foo')))
            ->setPublic(false)
        ;

        $this->process($container);

        $this->assertFalse($container->hasDefinition('foo'));
        $this->assertFalse($container->hasDefinition('bar'));
    }

    public function testProcessWorksWithInlinedDefinitions()
    {
        $container = new ContainerBuilder();
        $container
            ->register('foo')
            ->setPublic(false)
        ;
        $container
            ->register('bar')
            ->setArguments(array(new Definition(null, array(new Reference('foo')))))
        ;

        $this->process($container);

        $this->assertTrue($container->hasDefinition('foo'));
        $this->assertTrue($container->hasDefinition('bar'));
    }

    public function testProcessWontRemovePrivateFactory()
    {
        $container = new ContainerBuilder();

        $container
            ->register('foo', 'stdClass')
            ->setFactory(array('stdClass', 'getInstance'))
            ->setPublic(false);

        $container
            ->register('bar', 'stdClass')
            ->setFactory(array(new Reference('foo'), 'getInstance'))
            ->setPublic(false);

        $container
            ->register('foobar')
            ->addArgument(new Reference('bar'));

        $this->process($container);

        $this->assertTrue($container->hasDefinition('foo'));
        $this->assertTrue($container->hasDefinition('bar'));
        $this->assertTrue($container->hasDefinition('foobar'));
    }

    protected function process(ContainerBuilder $container)
    {
        $repeatedPass = new RepeatedPass(array(new AnalyzeServiceReferencesPass(), new RemoveUnusedDefinitionsPass()));
        $repeatedPass->process($container);
    }
}
PKϤ$ZfAe��<dependency-injection/Tests/Compiler/OptionalServiceClass.phpnu�[���<?php

/*
 * This file is part of the Symfony package.
 *
 * (c) Fabien Potencier <fabien@symfony.com>
 *
 * For the full copyright and license information, please view the LICENSE
 * file that was distributed with this source code.
 */

namespace Symfony\Component\DependencyInjection\Tests\Compiler;

use Symfony\Bug\NotExistClass;

class OptionalServiceClass extends NotExistClass
{
}
PKϤ$ZD���Hdependency-injection/Tests/Compiler/InlineServiceDefinitionsPassTest.phpnu�[���<?php

/*
 * This file is part of the Symfony package.
 *
 * (c) Fabien Potencier <fabien@symfony.com>
 *
 * For the full copyright and license information, please view the LICENSE
 * file that was distributed with this source code.
 */

namespace Symfony\Component\DependencyInjection\Tests\Compiler;

use Symfony\Component\DependencyInjection\Definition;
use Symfony\Component\DependencyInjection\Compiler\AnalyzeServiceReferencesPass;
use Symfony\Component\DependencyInjection\Compiler\RepeatedPass;
use Symfony\Component\DependencyInjection\Compiler\InlineServiceDefinitionsPass;
use Symfony\Component\DependencyInjection\Reference;
use Symfony\Component\DependencyInjection\ContainerBuilder;

class InlineServiceDefinitionsPassTest extends \PHPUnit_Framework_TestCase
{
    public function testProcess()
    {
        $container = new ContainerBuilder();
        $container
            ->register('inlinable.service')
            ->setPublic(false)
        ;

        $container
            ->register('service')
            ->setArguments(array(new Reference('inlinable.service')))
        ;

        $this->process($container);

        $arguments = $container->getDefinition('service')->getArguments();
        $this->assertInstanceOf('Symfony\Component\DependencyInjection\Definition', $arguments[0]);
        $this->assertSame($container->getDefinition('inlinable.service'), $arguments[0]);
    }

    public function testProcessDoesNotInlinesWhenAliasedServiceIsShared()
    {
        $container = new ContainerBuilder();
        $container
            ->register('foo')
            ->setPublic(false)
        ;
        $container->setAlias('moo', 'foo');

        $container
            ->register('service')
            ->setArguments(array($ref = new Reference('foo')))
        ;

        $this->process($container);

        $arguments = $container->getDefinition('service')->getArguments();
        $this->assertSame($ref, $arguments[0]);
    }

    public function testProcessDoesInlineNonSharedService()
    {
        $container = new ContainerBuilder();
        $container
            ->register('foo')
            ->setShared(false)
        ;
        $container
            ->register('bar')
            ->setPublic(false)
            ->setShared(false)
        ;
        $container->setAlias('moo', 'bar');

        $container
            ->register('service')
            ->setArguments(array(new Reference('foo'), $ref = new Reference('moo'), new Reference('bar')))
        ;

        $this->process($container);

        $arguments = $container->getDefinition('service')->getArguments();
        $this->assertEquals($container->getDefinition('foo'), $arguments[0]);
        $this->assertNotSame($container->getDefinition('foo'), $arguments[0]);
        $this->assertSame($ref, $arguments[1]);
        $this->assertEquals($container->getDefinition('bar'), $arguments[2]);
        $this->assertNotSame($container->getDefinition('bar'), $arguments[2]);
    }

    public function testProcessInlinesIfMultipleReferencesButAllFromTheSameDefinition()
    {
        $container = new ContainerBuilder();

        $a = $container->register('a')->setPublic(false);
        $b = $container
            ->register('b')
            ->addArgument(new Reference('a'))
            ->addArgument(new Definition(null, array(new Reference('a'))))
        ;

        $this->process($container);

        $arguments = $b->getArguments();
        $this->assertSame($a, $arguments[0]);

        $inlinedArguments = $arguments[1]->getArguments();
        $this->assertSame($a, $inlinedArguments[0]);
    }

    public function testProcessInlinesPrivateFactoryReference()
    {
        $container = new ContainerBuilder();

        $container->register('a')->setPublic(false);
        $b = $container
            ->register('b')
            ->setPublic(false)
            ->setFactory(array(new Reference('a'), 'a'))
        ;

        $container
            ->register('foo')
            ->setArguments(array(
                $ref = new Reference('b'),
            ));

        $this->process($container);

        $inlinedArguments = $container->getDefinition('foo')->getArguments();
        $this->assertSame($b, $inlinedArguments[0]);
    }

    public function testProcessDoesNotInlinePrivateFactoryIfReferencedMultipleTimesWithinTheSameDefinition()
    {
        $container = new ContainerBuilder();
        $container
            ->register('a')
        ;
        $container
            ->register('b')
            ->setPublic(false)
            ->setFactory(array(new Reference('a'), 'a'))
        ;

        $container
            ->register('foo')
            ->setArguments(array(
                    $ref1 = new Reference('b'),
                    $ref2 = new Reference('b'),
                ))
        ;
        $this->process($container);

        $args = $container->getDefinition('foo')->getArguments();
        $this->assertSame($ref1, $args[0]);
        $this->assertSame($ref2, $args[1]);
    }

    public function testProcessDoesNotInlineReferenceWhenUsedByInlineFactory()
    {
        $container = new ContainerBuilder();
        $container
            ->register('a')
        ;
        $container
            ->register('b')
            ->setPublic(false)
            ->setFactory(array(new Reference('a'), 'a'))
        ;

        $inlineFactory = new Definition();
        $inlineFactory->setPublic(false);
        $inlineFactory->setFactory(array(new Reference('b'), 'b'));

        $container
            ->register('foo')
            ->setArguments(array(
                    $ref = new Reference('b'),
                    $inlineFactory,
                ))
        ;
        $this->process($container);

        $args = $container->getDefinition('foo')->getArguments();
        $this->assertSame($ref, $args[0]);
    }

    public function testProcessDoesNotInlineWhenServiceIsPrivateButLazy()
    {
        $container = new ContainerBuilder();
        $container
            ->register('foo')
            ->setPublic(false)
            ->setLazy(true)
        ;

        $container
            ->register('service')
            ->setArguments(array($ref = new Reference('foo')))
        ;

        $this->process($container);

        $arguments = $container->getDefinition('service')->getArguments();
        $this->assertSame($ref, $arguments[0]);
    }

    public function testProcessDoesNotInlineWhenServiceReferencesItself()
    {
        $container = new ContainerBuilder();
        $container
            ->register('foo')
            ->setPublic(false)
            ->addMethodCall('foo', array($ref = new Reference('foo')))
        ;

        $this->process($container);

        $calls = $container->getDefinition('foo')->getMethodCalls();
        $this->assertSame($ref, $calls[0][1][0]);
    }

    protected function process(ContainerBuilder $container)
    {
        $repeatedPass = new RepeatedPass(array(new AnalyzeServiceReferencesPass(), new InlineServiceDefinitionsPass()));
        $repeatedPass->process($container);
    }
}
PKϤ$Z�D�^��Ldependency-injection/Tests/Compiler/ResolveParameterPlaceHoldersPassTest.phpnu�[���<?php

/*
 * This file is part of the Symfony package.
 *
 * (c) Fabien Potencier <fabien@symfony.com>
 *
 * For the full copyright and license information, please view the LICENSE
 * file that was distributed with this source code.
 */

namespace Symfony\Component\DependencyInjection\Tests\Compiler;

use Symfony\Component\DependencyInjection\Compiler\ResolveParameterPlaceHoldersPass;
use Symfony\Component\DependencyInjection\ContainerBuilder;

class ResolveParameterPlaceHoldersPassTest extends \PHPUnit_Framework_TestCase
{
    private $compilerPass;
    private $container;
    private $fooDefinition;

    protected function setUp()
    {
        $this->compilerPass = new ResolveParameterPlaceHoldersPass();
        $this->container = $this->createContainerBuilder();
        $this->compilerPass->process($this->container);
        $this->fooDefinition = $this->container->getDefinition('foo');
    }

    public function testClassParametersShouldBeResolved()
    {
        $this->assertSame('Foo', $this->fooDefinition->getClass());
    }

    public function testFactoryParametersShouldBeResolved()
    {
        $this->assertSame(array('FooFactory', 'getFoo'), $this->fooDefinition->getFactory());
    }

    public function testArgumentParametersShouldBeResolved()
    {
        $this->assertSame(array('bar', 'baz'), $this->fooDefinition->getArguments());
    }

    public function testMethodCallParametersShouldBeResolved()
    {
        $this->assertSame(array(array('foobar', array('bar', 'baz'))), $this->fooDefinition->getMethodCalls());
    }

    public function testPropertyParametersShouldBeResolved()
    {
        $this->assertSame(array('bar' => 'baz'), $this->fooDefinition->getProperties());
    }

    public function testFileParametersShouldBeResolved()
    {
        $this->assertSame('foo.php', $this->fooDefinition->getFile());
    }

    public function testAliasParametersShouldBeResolved()
    {
        $this->assertSame('foo', $this->container->getAlias('bar')->__toString());
    }

    private function createContainerBuilder()
    {
        $containerBuilder = new ContainerBuilder();

        $containerBuilder->setParameter('foo.class', 'Foo');
        $containerBuilder->setParameter('foo.factory.class', 'FooFactory');
        $containerBuilder->setParameter('foo.arg1', 'bar');
        $containerBuilder->setParameter('foo.arg2', 'baz');
        $containerBuilder->setParameter('foo.method', 'foobar');
        $containerBuilder->setParameter('foo.property.name', 'bar');
        $containerBuilder->setParameter('foo.property.value', 'baz');
        $containerBuilder->setParameter('foo.file', 'foo.php');
        $containerBuilder->setParameter('alias.id', 'bar');

        $fooDefinition = $containerBuilder->register('foo', '%foo.class%');
        $fooDefinition->setFactory(array('%foo.factory.class%', 'getFoo'));
        $fooDefinition->setArguments(array('%foo.arg1%', '%foo.arg2%'));
        $fooDefinition->addMethodCall('%foo.method%', array('%foo.arg1%', '%foo.arg2%'));
        $fooDefinition->setProperty('%foo.property.name%', '%foo.property.value%');
        $fooDefinition->setFile('%foo.file%');

        $containerBuilder->setAlias('%alias.id%', 'foo');

        return $containerBuilder;
    }
}
PKϤ$Z��� ``Jdependency-injection/Tests/Compiler/ResolveReferencesToAliasesPassTest.phpnu�[���<?php

/*
 * This file is part of the Symfony package.
 *
 * (c) Fabien Potencier <fabien@symfony.com>
 *
 * For the full copyright and license information, please view the LICENSE
 * file that was distributed with this source code.
 */

namespace Symfony\Component\DependencyInjection\Tests\Compiler;

use Symfony\Component\DependencyInjection\Alias;
use Symfony\Component\DependencyInjection\Definition;
use Symfony\Component\DependencyInjection\Reference;
use Symfony\Component\DependencyInjection\Compiler\ResolveReferencesToAliasesPass;
use Symfony\Component\DependencyInjection\ContainerBuilder;

class ResolveReferencesToAliasesPassTest extends \PHPUnit_Framework_TestCase
{
    public function testProcess()
    {
        $container = new ContainerBuilder();
        $container->setAlias('bar', 'foo');
        $def = $container
            ->register('moo')
            ->setArguments(array(new Reference('bar')))
        ;

        $this->process($container);

        $arguments = $def->getArguments();
        $this->assertEquals('foo', (string) $arguments[0]);
    }

    public function testProcessRecursively()
    {
        $container = new ContainerBuilder();
        $container->setAlias('bar', 'foo');
        $container->setAlias('moo', 'bar');
        $def = $container
            ->register('foobar')
            ->setArguments(array(new Reference('moo')))
        ;

        $this->process($container);

        $arguments = $def->getArguments();
        $this->assertEquals('foo', (string) $arguments[0]);
    }

    /**
     * @expectedException \Symfony\Component\DependencyInjection\Exception\ServiceCircularReferenceException
     */
    public function testAliasCircularReference()
    {
        $container = new ContainerBuilder();
        $container->setAlias('bar', 'foo');
        $container->setAlias('foo', 'bar');
        $this->process($container);
    }

    public function testResolveFactory()
    {
        $container = new ContainerBuilder();
        $container->register('factory', 'Factory');
        $container->setAlias('factory_alias', new Alias('factory'));
        $foo = new Definition();
        $foo->setFactory(array(new Reference('factory_alias'), 'createFoo'));
        $container->setDefinition('foo', $foo);
        $bar = new Definition();
        $bar->setFactory(array('Factory', 'createFoo'));
        $container->setDefinition('bar', $bar);

        $this->process($container);

        $resolvedFooFactory = $container->getDefinition('foo')->getFactory();
        $resolvedBarFactory = $container->getDefinition('bar')->getFactory();

        $this->assertSame('factory', (string) $resolvedFooFactory[0]);
        $this->assertSame('Factory', (string) $resolvedBarFactory[0]);
    }

    protected function process(ContainerBuilder $container)
    {
        $pass = new ResolveReferencesToAliasesPass();
        $pass->process($container);
    }
}
PKϤ$Z��LKdependency-injection/Tests/Compiler/MergeExtensionConfigurationPassTest.phpnu�[���<?php

/*
 * This file is part of the Symfony package.
 *
 * (c) Fabien Potencier <fabien@symfony.com>
 *
 * For the full copyright and license information, please view the LICENSE
 * file that was distributed with this source code.
 */

namespace Symfony\Component\DependencyInjection\Tests\Compiler;

use Symfony\Component\DependencyInjection\Compiler\MergeExtensionConfigurationPass;
use Symfony\Component\DependencyInjection\ContainerBuilder;
use Symfony\Component\DependencyInjection\ParameterBag\ParameterBag;

class MergeExtensionConfigurationPassTest extends \PHPUnit_Framework_TestCase
{
    public function testExpressionLanguageProviderForwarding()
    {
        $tmpProviders = array();

        $extension = $this->getMockBuilder('Symfony\\Component\\DependencyInjection\\Extension\\ExtensionInterface')->getMock();
        $extension->expects($this->any())
            ->method('getXsdValidationBasePath')
            ->will($this->returnValue(false));
        $extension->expects($this->any())
            ->method('getNamespace')
            ->will($this->returnValue('http://example.org/schema/dic/foo'));
        $extension->expects($this->any())
            ->method('getAlias')
            ->will($this->returnValue('foo'));
        $extension->expects($this->once())
            ->method('load')
            ->will($this->returnCallback(function (array $config, ContainerBuilder $container) use (&$tmpProviders) {
                $tmpProviders = $container->getExpressionLanguageProviders();
            }));

        $provider = $this->getMockBuilder('Symfony\\Component\\ExpressionLanguage\\ExpressionFunctionProviderInterface')->getMock();
        $container = new ContainerBuilder(new ParameterBag());
        $container->registerExtension($extension);
        $container->prependExtensionConfig('foo', array('bar' => true));
        $container->addExpressionLanguageProvider($provider);

        $pass = new MergeExtensionConfigurationPass();
        $pass->process($container);

        $this->assertEquals(array($provider), $tmpProviders);
    }
}
PKϤ$Z鍁��Xdependency-injection/Tests/Compiler/CheckExceptionOnInvalidReferenceBehaviorPassTest.phpnu�[���<?php

/*
 * This file is part of the Symfony package.
 *
 * (c) Fabien Potencier <fabien@symfony.com>
 *
 * For the full copyright and license information, please view the LICENSE
 * file that was distributed with this source code.
 */

namespace Symfony\Component\DependencyInjection\Tests\Compiler;

use Symfony\Component\DependencyInjection\Definition;
use Symfony\Component\DependencyInjection\Compiler\CheckExceptionOnInvalidReferenceBehaviorPass;
use Symfony\Component\DependencyInjection\Reference;
use Symfony\Component\DependencyInjection\ContainerBuilder;

class CheckExceptionOnInvalidReferenceBehaviorPassTest extends \PHPUnit_Framework_TestCase
{
    public function testProcess()
    {
        $container = new ContainerBuilder();

        $container
            ->register('a', '\stdClass')
            ->addArgument(new Reference('b'))
        ;
        $container->register('b', '\stdClass');
    }

    /**
     * @expectedException \Symfony\Component\DependencyInjection\Exception\ServiceNotFoundException
     */
    public function testProcessThrowsExceptionOnInvalidReference()
    {
        $container = new ContainerBuilder();

        $container
            ->register('a', '\stdClass')
            ->addArgument(new Reference('b'))
        ;

        $this->process($container);
    }

    /**
     * @expectedException \Symfony\Component\DependencyInjection\Exception\ServiceNotFoundException
     */
    public function testProcessThrowsExceptionOnInvalidReferenceFromInlinedDefinition()
    {
        $container = new ContainerBuilder();

        $def = new Definition();
        $def->addArgument(new Reference('b'));

        $container
            ->register('a', '\stdClass')
            ->addArgument($def)
        ;

        $this->process($container);
    }

    private function process(ContainerBuilder $container)
    {
        $pass = new CheckExceptionOnInvalidReferenceBehaviorPass();
        $pass->process($container);
    }
}
PKϤ$Z�܀��Hdependency-injection/Tests/Compiler/ResolveInvalidReferencesPassTest.phpnu�[���<?php

/*
 * This file is part of the Symfony package.
 *
 * (c) Fabien Potencier <fabien@symfony.com>
 *
 * For the full copyright and license information, please view the LICENSE
 * file that was distributed with this source code.
 */

namespace Symfony\Component\DependencyInjection\Tests\Compiler;

use Symfony\Component\DependencyInjection\ContainerInterface;
use Symfony\Component\DependencyInjection\Reference;
use Symfony\Component\DependencyInjection\Compiler\ResolveInvalidReferencesPass;
use Symfony\Component\DependencyInjection\ContainerBuilder;

class ResolveInvalidReferencesPassTest extends \PHPUnit_Framework_TestCase
{
    public function testProcess()
    {
        $container = new ContainerBuilder();
        $def = $container
            ->register('foo')
            ->setArguments(array(
                new Reference('bar', ContainerInterface::NULL_ON_INVALID_REFERENCE),
                new Reference('baz', ContainerInterface::IGNORE_ON_INVALID_REFERENCE),
            ))
            ->addMethodCall('foo', array(new Reference('moo', ContainerInterface::IGNORE_ON_INVALID_REFERENCE)))
        ;

        $this->process($container);

        $arguments = $def->getArguments();
        $this->assertSame(array(null, null), $arguments);
        $this->assertCount(0, $def->getMethodCalls());
    }

    public function testProcessIgnoreInvalidArgumentInCollectionArgument()
    {
        $container = new ContainerBuilder();
        $container->register('baz');
        $def = $container
            ->register('foo')
            ->setArguments(array(
                array(
                    new Reference('bar', ContainerInterface::IGNORE_ON_INVALID_REFERENCE),
                    $baz = new Reference('baz', ContainerInterface::IGNORE_ON_INVALID_REFERENCE),
                    new Reference('moo', ContainerInterface::NULL_ON_INVALID_REFERENCE),
                ),
            ))
        ;

        $this->process($container);

        $arguments = $def->getArguments();
        $this->assertSame(array($baz, null), $arguments[0]);
    }

    public function testProcessKeepMethodCallOnInvalidArgumentInCollectionArgument()
    {
        $container = new ContainerBuilder();
        $container->register('baz');
        $def = $container
            ->register('foo')
            ->addMethodCall('foo', array(
                array(
                    new Reference('bar', ContainerInterface::IGNORE_ON_INVALID_REFERENCE),
                    $baz = new Reference('baz', ContainerInterface::IGNORE_ON_INVALID_REFERENCE),
                    new Reference('moo', ContainerInterface::NULL_ON_INVALID_REFERENCE),
                ),
            ))
        ;

        $this->process($container);

        $calls = $def->getMethodCalls();
        $this->assertCount(1, $def->getMethodCalls());
        $this->assertSame(array($baz, null), $calls[0][1][0]);
    }

    public function testProcessIgnoreNonExistentServices()
    {
        $container = new ContainerBuilder();
        $def = $container
            ->register('foo')
            ->setArguments(array(new Reference('bar')))
        ;

        $this->process($container);

        $arguments = $def->getArguments();
        $this->assertEquals('bar', (string) $arguments[0]);
    }

    public function testProcessRemovesPropertiesOnInvalid()
    {
        $container = new ContainerBuilder();
        $def = $container
            ->register('foo')
            ->setProperty('foo', new Reference('bar', ContainerInterface::IGNORE_ON_INVALID_REFERENCE))
        ;

        $this->process($container);

        $this->assertEquals(array(), $def->getProperties());
    }

    protected function process(ContainerBuilder $container)
    {
        $pass = new ResolveInvalidReferencesPass();
        $pass->process($container);
    }
}
PKϤ$Za�l��Gdependency-injection/Tests/Compiler/CheckCircularReferencesPassTest.phpnu�[���<?php

/*
 * This file is part of the Symfony package.
 *
 * (c) Fabien Potencier <fabien@symfony.com>
 *
 * For the full copyright and license information, please view the LICENSE
 * file that was distributed with this source code.
 */

namespace Symfony\Component\DependencyInjection\Tests\Compiler;

use Symfony\Component\DependencyInjection\Reference;
use Symfony\Component\DependencyInjection\Compiler\CheckCircularReferencesPass;
use Symfony\Component\DependencyInjection\Compiler\AnalyzeServiceReferencesPass;
use Symfony\Component\DependencyInjection\Compiler\Compiler;
use Symfony\Component\DependencyInjection\ContainerBuilder;

class CheckCircularReferencesPassTest extends \PHPUnit_Framework_TestCase
{
    /**
     * @expectedException \Symfony\Component\DependencyInjection\Exception\ServiceCircularReferenceException
     */
    public function testProcess()
    {
        $container = new ContainerBuilder();
        $container->register('a')->addArgument(new Reference('b'));
        $container->register('b')->addArgument(new Reference('a'));

        $this->process($container);
    }

    /**
     * @expectedException \Symfony\Component\DependencyInjection\Exception\ServiceCircularReferenceException
     */
    public function testProcessWithAliases()
    {
        $container = new ContainerBuilder();
        $container->register('a')->addArgument(new Reference('b'));
        $container->setAlias('b', 'c');
        $container->setAlias('c', 'a');

        $this->process($container);
    }

    /**
     * @expectedException \Symfony\Component\DependencyInjection\Exception\ServiceCircularReferenceException
     */
    public function testProcessWithFactory()
    {
        $container = new ContainerBuilder();

        $container
            ->register('a', 'stdClass')
            ->setFactory(array(new Reference('b'), 'getInstance'));

        $container
            ->register('b', 'stdClass')
            ->setFactory(array(new Reference('a'), 'getInstance'));

        $this->process($container);
    }

    /**
     * @expectedException \Symfony\Component\DependencyInjection\Exception\ServiceCircularReferenceException
     */
    public function testProcessDetectsIndirectCircularReference()
    {
        $container = new ContainerBuilder();
        $container->register('a')->addArgument(new Reference('b'));
        $container->register('b')->addArgument(new Reference('c'));
        $container->register('c')->addArgument(new Reference('a'));

        $this->process($container);
    }

    /**
     * @expectedException \Symfony\Component\DependencyInjection\Exception\ServiceCircularReferenceException
     */
    public function testProcessDetectsIndirectCircularReferenceWithFactory()
    {
        $container = new ContainerBuilder();

        $container->register('a')->addArgument(new Reference('b'));

        $container
            ->register('b', 'stdClass')
            ->setFactory(array(new Reference('c'), 'getInstance'));

        $container->register('c')->addArgument(new Reference('a'));

        $this->process($container);
    }

    /**
     * @expectedException \Symfony\Component\DependencyInjection\Exception\ServiceCircularReferenceException
     */
    public function testDeepCircularReference()
    {
        $container = new ContainerBuilder();
        $container->register('a')->addArgument(new Reference('b'));
        $container->register('b')->addArgument(new Reference('c'));
        $container->register('c')->addArgument(new Reference('b'));

        $this->process($container);
    }

    public function testProcessIgnoresMethodCalls()
    {
        $container = new ContainerBuilder();
        $container->register('a')->addArgument(new Reference('b'));
        $container->register('b')->addMethodCall('setA', array(new Reference('a')));

        $this->process($container);
    }

    protected function process(ContainerBuilder $container)
    {
        $compiler = new Compiler();
        $passConfig = $compiler->getPassConfig();
        $passConfig->setOptimizationPasses(array(
            new AnalyzeServiceReferencesPass(true),
            new CheckCircularReferencesPass(),
        ));
        $passConfig->setRemovingPasses(array());

        $compiler->compile($container);
    }
}
PKϤ$Z�
�M

Gdependency-injection/Tests/Compiler/CheckDefinitionValidityPassTest.phpnu�[���<?php

/*
 * This file is part of the Symfony package.
 *
 * (c) Fabien Potencier <fabien@symfony.com>
 *
 * For the full copyright and license information, please view the LICENSE
 * file that was distributed with this source code.
 */

namespace Symfony\Component\DependencyInjection\Tests\Compiler;

use Symfony\Component\DependencyInjection\Compiler\CheckDefinitionValidityPass;
use Symfony\Component\DependencyInjection\ContainerBuilder;

class CheckDefinitionValidityPassTest extends \PHPUnit_Framework_TestCase
{
    /**
     * @expectedException \Symfony\Component\DependencyInjection\Exception\RuntimeException
     */
    public function testProcessDetectsSyntheticNonPublicDefinitions()
    {
        $container = new ContainerBuilder();
        $container->register('a')->setSynthetic(true)->setPublic(false);

        $this->process($container);
    }

    /**
     * @expectedException \Symfony\Component\DependencyInjection\Exception\RuntimeException
     */
    public function testProcessDetectsNonSyntheticNonAbstractDefinitionWithoutClass()
    {
        $container = new ContainerBuilder();
        $container->register('a')->setSynthetic(false)->setAbstract(false);

        $this->process($container);
    }

    public function testProcess()
    {
        $container = new ContainerBuilder();
        $container->register('a', 'class');
        $container->register('b', 'class')->setSynthetic(true)->setPublic(true);
        $container->register('c', 'class')->setAbstract(true);
        $container->register('d', 'class')->setSynthetic(true);

        $this->process($container);
    }

    public function testValidTags()
    {
        $container = new ContainerBuilder();
        $container->register('a', 'class')->addTag('foo', array('bar' => 'baz'));
        $container->register('b', 'class')->addTag('foo', array('bar' => null));
        $container->register('c', 'class')->addTag('foo', array('bar' => 1));
        $container->register('d', 'class')->addTag('foo', array('bar' => 1.1));

        $this->process($container);
    }

    /**
     * @expectedException \Symfony\Component\DependencyInjection\Exception\RuntimeException
     */
    public function testInvalidTags()
    {
        $container = new ContainerBuilder();
        $container->register('a', 'class')->addTag('foo', array('bar' => array('baz' => 'baz')));

        $this->process($container);
    }

    protected function process(ContainerBuilder $container)
    {
        $pass = new CheckDefinitionValidityPass();
        $pass->process($container);
    }
}
PKϤ$ZV�Y���7dependency-injection/Tests/Compiler/IntegrationTest.phpnu�[���<?php

/*
 * This file is part of the Symfony package.
 *
 * (c) Fabien Potencier <fabien@symfony.com>
 *
 * For the full copyright and license information, please view the LICENSE
 * file that was distributed with this source code.
 */

namespace Symfony\Component\DependencyInjection\Tests\Compiler;

use Symfony\Component\DependencyInjection\Alias;
use Symfony\Component\DependencyInjection\Reference;
use Symfony\Component\DependencyInjection\ContainerBuilder;

/**
 * This class tests the integration of the different compiler passes.
 */
class IntegrationTest extends \PHPUnit_Framework_TestCase
{
    /**
     * This tests that dependencies are correctly processed.
     *
     * We're checking that:
     *
     *   * A is public, B/C are private
     *   * A -> C
     *   * B -> C
     */
    public function testProcessRemovesAndInlinesRecursively()
    {
        $container = new ContainerBuilder();
        $container->setResourceTracking(false);

        $a = $container
            ->register('a', '\stdClass')
            ->addArgument(new Reference('c'))
        ;

        $b = $container
            ->register('b', '\stdClass')
            ->addArgument(new Reference('c'))
            ->setPublic(false)
        ;

        $c = $container
            ->register('c', '\stdClass')
            ->setPublic(false)
        ;

        $container->compile();

        $this->assertTrue($container->hasDefinition('a'));
        $arguments = $a->getArguments();
        $this->assertSame($c, $arguments[0]);
        $this->assertFalse($container->hasDefinition('b'));
        $this->assertFalse($container->hasDefinition('c'));
    }

    public function testProcessInlinesReferencesToAliases()
    {
        $container = new ContainerBuilder();
        $container->setResourceTracking(false);

        $a = $container
            ->register('a', '\stdClass')
            ->addArgument(new Reference('b'))
        ;

        $container->setAlias('b', new Alias('c', false));

        $c = $container
            ->register('c', '\stdClass')
            ->setPublic(false)
        ;

        $container->compile();

        $this->assertTrue($container->hasDefinition('a'));
        $arguments = $a->getArguments();
        $this->assertSame($c, $arguments[0]);
        $this->assertFalse($container->hasAlias('b'));
        $this->assertFalse($container->hasDefinition('c'));
    }

    public function testProcessInlinesWhenThereAreMultipleReferencesButFromTheSameDefinition()
    {
        $container = new ContainerBuilder();
        $container->setResourceTracking(false);

        $container
            ->register('a', '\stdClass')
            ->addArgument(new Reference('b'))
            ->addMethodCall('setC', array(new Reference('c')))
        ;

        $container
            ->register('b', '\stdClass')
            ->addArgument(new Reference('c'))
            ->setPublic(false)
        ;

        $container
            ->register('c', '\stdClass')
            ->setPublic(false)
        ;

        $container->compile();

        $this->assertTrue($container->hasDefinition('a'));
        $this->assertFalse($container->hasDefinition('b'));
        $this->assertFalse($container->hasDefinition('c'), 'Service C was not inlined.');
    }
}
PKϤ$Z⬼���Adependency-injection/Tests/Compiler/ExtensionCompilerPassTest.phpnu�[���<?php

/*
 * This file is part of the Symfony package.
 *
 * (c) Fabien Potencier <fabien@symfony.com>
 *
 * For the full copyright and license information, please view the LICENSE
 * file that was distributed with this source code.
 */

namespace Symfony\Component\DependencyInjection\Tests\Compiler;

use Symfony\Component\DependencyInjection\Compiler\ExtensionCompilerPass;

/**
 * @author Wouter J <wouter@wouterj.nl>
 */
class ExtensionCompilerPassTest extends \PHPUnit_Framework_TestCase
{
    private $container;
    private $pass;

    protected function setUp()
    {
        $this->container = $this->getMockBuilder('Symfony\Component\DependencyInjection\ContainerBuilder')->getMock();
        $this->pass = new ExtensionCompilerPass();
    }

    public function testProcess()
    {
        $extension1 = $this->createExtensionMock(true);
        $extension1->expects($this->once())->method('process');
        $extension2 = $this->createExtensionMock(false);
        $extension3 = $this->createExtensionMock(false);
        $extension4 = $this->createExtensionMock(true);
        $extension4->expects($this->once())->method('process');

        $this->container->expects($this->any())
            ->method('getExtensions')
            ->will($this->returnValue(array($extension1, $extension2, $extension3, $extension4)))
        ;

        $this->pass->process($this->container);
    }

    private function createExtensionMock($hasInlineCompile)
    {
        return $this->getMockBuilder('Symfony\Component\DependencyInjection\\'.(
            $hasInlineCompile
            ? 'Compiler\CompilerPassInterface'
            : 'Extension\ExtensionInterface'
        ))->getMock();
    }
}
PKϤ$Z_Ix�+�+Jdependency-injection/Tests/Compiler/ResolveDefinitionTemplatesPassTest.phpnu�[���<?php

/*
 * This file is part of the Symfony package.
 *
 * (c) Fabien Potencier <fabien@symfony.com>
 *
 * For the full copyright and license information, please view the LICENSE
 * file that was distributed with this source code.
 */

namespace Symfony\Component\DependencyInjection\Tests\Compiler;

use Symfony\Component\DependencyInjection\DefinitionDecorator;
use Symfony\Component\DependencyInjection\Compiler\ResolveDefinitionTemplatesPass;
use Symfony\Component\DependencyInjection\ContainerBuilder;

class ResolveDefinitionTemplatesPassTest extends \PHPUnit_Framework_TestCase
{
    public function testProcess()
    {
        $container = new ContainerBuilder();
        $container->register('parent', 'foo')->setArguments(array('moo', 'b'))->setProperty('foo', 'moo');
        $container->setDefinition('child', new DefinitionDecorator('parent'))
            ->replaceArgument(0, 'a')
            ->setProperty('foo', 'bar')
            ->setClass('bar')
        ;

        $this->process($container);

        $def = $container->getDefinition('child');
        $this->assertNotInstanceOf('Symfony\Component\DependencyInjection\DefinitionDecorator', $def);
        $this->assertEquals('bar', $def->getClass());
        $this->assertEquals(array('a', 'b'), $def->getArguments());
        $this->assertEquals(array('foo' => 'bar'), $def->getProperties());
    }

    public function testProcessAppendsMethodCallsAlways()
    {
        $container = new ContainerBuilder();

        $container
            ->register('parent')
            ->addMethodCall('foo', array('bar'))
        ;

        $container
            ->setDefinition('child', new DefinitionDecorator('parent'))
            ->addMethodCall('bar', array('foo'))
        ;

        $this->process($container);

        $def = $container->getDefinition('child');
        $this->assertEquals(array(
            array('foo', array('bar')),
            array('bar', array('foo')),
        ), $def->getMethodCalls());
    }

    public function testProcessDoesNotCopyAbstract()
    {
        $container = new ContainerBuilder();

        $container
            ->register('parent')
            ->setAbstract(true)
        ;

        $container
            ->setDefinition('child', new DefinitionDecorator('parent'))
        ;

        $this->process($container);

        $def = $container->getDefinition('child');
        $this->assertFalse($def->isAbstract());
    }

    public function testProcessDoesNotCopyShared()
    {
        $container = new ContainerBuilder();

        $container
            ->register('parent')
            ->setShared(false)
        ;

        $container
            ->setDefinition('child', new DefinitionDecorator('parent'))
        ;

        $this->process($container);

        $def = $container->getDefinition('child');
        $this->assertTrue($def->isShared());
    }

    public function testProcessDoesNotCopyTags()
    {
        $container = new ContainerBuilder();

        $container
            ->register('parent')
            ->addTag('foo')
        ;

        $container
            ->setDefinition('child', new DefinitionDecorator('parent'))
        ;

        $this->process($container);

        $def = $container->getDefinition('child');
        $this->assertEquals(array(), $def->getTags());
    }

    public function testProcessDoesNotCopyDecoratedService()
    {
        $container = new ContainerBuilder();

        $container
            ->register('parent')
            ->setDecoratedService('foo')
        ;

        $container
            ->setDefinition('child', new DefinitionDecorator('parent'))
        ;

        $this->process($container);

        $def = $container->getDefinition('child');
        $this->assertNull($def->getDecoratedService());
    }

    public function testProcessDoesNotDropShared()
    {
        $container = new ContainerBuilder();

        $container
            ->register('parent')
        ;

        $container
            ->setDefinition('child', new DefinitionDecorator('parent'))
            ->setShared(false)
        ;

        $this->process($container);

        $def = $container->getDefinition('child');
        $this->assertFalse($def->isShared());
    }

    public function testProcessHandlesMultipleInheritance()
    {
        $container = new ContainerBuilder();

        $container
            ->register('parent', 'foo')
            ->setArguments(array('foo', 'bar', 'c'))
        ;

        $container
            ->setDefinition('child2', new DefinitionDecorator('child1'))
            ->replaceArgument(1, 'b')
        ;

        $container
            ->setDefinition('child1', new DefinitionDecorator('parent'))
            ->replaceArgument(0, 'a')
        ;

        $this->process($container);

        $def = $container->getDefinition('child2');
        $this->assertEquals(array('a', 'b', 'c'), $def->getArguments());
        $this->assertEquals('foo', $def->getClass());
    }

    public function testSetLazyOnServiceHasParent()
    {
        $container = new ContainerBuilder();

        $container->register('parent', 'stdClass');

        $container->setDefinition('child1', new DefinitionDecorator('parent'))
            ->setLazy(true)
        ;

        $this->process($container);

        $this->assertTrue($container->getDefinition('child1')->isLazy());
    }

    public function testSetLazyOnServiceIsParent()
    {
        $container = new ContainerBuilder();

        $container->register('parent', 'stdClass')
            ->setLazy(true)
        ;

        $container->setDefinition('child1', new DefinitionDecorator('parent'));

        $this->process($container);

        $this->assertTrue($container->getDefinition('child1')->isLazy());
    }

    public function testSetAutowiredOnServiceHasParent()
    {
        $container = new ContainerBuilder();

        $container->register('parent', 'stdClass');

        $container->setDefinition('child1', new DefinitionDecorator('parent'))
            ->setAutowired(true)
        ;

        $this->process($container);

        $this->assertTrue($container->getDefinition('child1')->isAutowired());
    }

    public function testSetAutowiredOnServiceIsParent()
    {
        $container = new ContainerBuilder();

        $container->register('parent', 'stdClass')
            ->setAutowired(true)
        ;

        $container->setDefinition('child1', new DefinitionDecorator('parent'));

        $this->process($container);

        $this->assertTrue($container->getDefinition('child1')->isAutowired());
    }

    public function testDeepDefinitionsResolving()
    {
        $container = new ContainerBuilder();

        $container->register('parent', 'parentClass');
        $container->register('sibling', 'siblingClass')
            ->setConfigurator(new DefinitionDecorator('parent'), 'foo')
            ->setFactory(array(new DefinitionDecorator('parent'), 'foo'))
            ->addArgument(new DefinitionDecorator('parent'))
            ->setProperty('prop', new DefinitionDecorator('parent'))
            ->addMethodCall('meth', array(new DefinitionDecorator('parent')))
        ;

        $this->process($container);

        $configurator = $container->getDefinition('sibling')->getConfigurator();
        $this->assertSame('Symfony\Component\DependencyInjection\Definition', get_class($configurator));
        $this->assertSame('parentClass', $configurator->getClass());

        $factory = $container->getDefinition('sibling')->getFactory();
        $this->assertSame('Symfony\Component\DependencyInjection\Definition', get_class($factory[0]));
        $this->assertSame('parentClass', $factory[0]->getClass());

        $argument = $container->getDefinition('sibling')->getArgument(0);
        $this->assertSame('Symfony\Component\DependencyInjection\Definition', get_class($argument));
        $this->assertSame('parentClass', $argument->getClass());

        $properties = $container->getDefinition('sibling')->getProperties();
        $this->assertSame('Symfony\Component\DependencyInjection\Definition', get_class($properties['prop']));
        $this->assertSame('parentClass', $properties['prop']->getClass());

        $methodCalls = $container->getDefinition('sibling')->getMethodCalls();
        $this->assertSame('Symfony\Component\DependencyInjection\Definition', get_class($methodCalls[0][1][0]));
        $this->assertSame('parentClass', $methodCalls[0][1][0]->getClass());
    }

    public function testSetDecoratedServiceOnServiceHasParent()
    {
        $container = new ContainerBuilder();

        $container->register('parent', 'stdClass');

        $container->setDefinition('child1', new DefinitionDecorator('parent'))
            ->setDecoratedService('foo', 'foo_inner', 5)
        ;

        $this->process($container);

        $this->assertEquals(array('foo', 'foo_inner', 5), $container->getDefinition('child1')->getDecoratedService());
    }

    public function testDecoratedServiceCopiesDeprecatedStatusFromParent()
    {
        $container = new ContainerBuilder();
        $container->register('deprecated_parent')
            ->setDeprecated(true)
        ;

        $container->setDefinition('decorated_deprecated_parent', new DefinitionDecorator('deprecated_parent'));

        $this->process($container);

        $this->assertTrue($container->getDefinition('decorated_deprecated_parent')->isDeprecated());
    }

    public function testDecoratedServiceCanOverwriteDeprecatedParentStatus()
    {
        $container = new ContainerBuilder();
        $container->register('deprecated_parent')
            ->setDeprecated(true)
        ;

        $container->setDefinition('decorated_deprecated_parent', new DefinitionDecorator('deprecated_parent'))
            ->setDeprecated(false)
        ;

        $this->process($container);

        $this->assertFalse($container->getDefinition('decorated_deprecated_parent')->isDeprecated());
    }

    public function testProcessMergeAutowiringTypes()
    {
        $container = new ContainerBuilder();

        $container
            ->register('parent')
            ->addAutowiringType('Foo')
        ;

        $container
            ->setDefinition('child', new DefinitionDecorator('parent'))
            ->addAutowiringType('Bar')
        ;

        $this->process($container);

        $childDef = $container->getDefinition('child');
        $this->assertEquals(array('Foo', 'Bar'), $childDef->getAutowiringTypes());

        $parentDef = $container->getDefinition('parent');
        $this->assertSame(array('Foo'), $parentDef->getAutowiringTypes());
    }

    public function testProcessResolvesAliases()
    {
        $container = new ContainerBuilder();

        $container->register('parent', 'ParentClass');
        $container->setAlias('parent_alias', 'parent');
        $container->setDefinition('child', new DefinitionDecorator('parent_alias'));

        $this->process($container);

        $def = $container->getDefinition('child');
        $this->assertSame('ParentClass', $def->getClass());
    }

    protected function process(ContainerBuilder $container)
    {
        $pass = new ResolveDefinitionTemplatesPass();
        $pass->process($container);
    }
}
PKϤ$Z�B��Ndependency-injection/Tests/Compiler/ReplaceAliasByActualDefinitionPassTest.phpnu�[���<?php

/*
 * This file is part of the Symfony package.
 *
 * (c) Fabien Potencier <fabien@symfony.com>
 *
 * For the full copyright and license information, please view the LICENSE
 * file that was distributed with this source code.
 */

namespace Symfony\Component\DependencyInjection\Tests\Compiler;

use Symfony\Component\DependencyInjection\Compiler\ReplaceAliasByActualDefinitionPass;
use Symfony\Component\DependencyInjection\ContainerBuilder;
use Symfony\Component\DependencyInjection\Definition;
use Symfony\Component\DependencyInjection\Reference;

require_once __DIR__.'/../Fixtures/includes/foo.php';

class ReplaceAliasByActualDefinitionPassTest extends \PHPUnit_Framework_TestCase
{
    public function testProcess()
    {
        $container = new ContainerBuilder();

        $aDefinition = $container->register('a', '\stdClass');
        $aDefinition->setFactory(array(new Reference('b'), 'createA'));

        $bDefinition = new Definition('\stdClass');
        $bDefinition->setPublic(false);
        $container->setDefinition('b', $bDefinition);

        $container->setAlias('a_alias', 'a');
        $container->setAlias('b_alias', 'b');

        $container->setAlias('container', 'service_container');

        $this->process($container);

        $this->assertTrue($container->has('a'), '->process() does nothing to public definitions.');
        $this->assertTrue($container->hasAlias('a_alias'));
        $this->assertFalse($container->has('b'), '->process() removes non-public definitions.');
        $this->assertTrue(
            $container->has('b_alias') && !$container->hasAlias('b_alias'),
            '->process() replaces alias to actual.'
        );

        $this->assertTrue($container->has('container'));

        $resolvedFactory = $aDefinition->getFactory();
        $this->assertSame('b_alias', (string) $resolvedFactory[0]);
    }

    /**
     * @expectedException \InvalidArgumentException
     */
    public function testProcessWithInvalidAlias()
    {
        $container = new ContainerBuilder();
        $container->setAlias('a_alias', 'a');
        $this->process($container);
    }

    protected function process(ContainerBuilder $container)
    {
        $pass = new ReplaceAliasByActualDefinitionPass();
        $pass->process($container);
    }
}
PKϤ$ZP��!mmHdependency-injection/Tests/Compiler/AnalyzeServiceReferencesPassTest.phpnu�[���<?php

/*
 * This file is part of the Symfony package.
 *
 * (c) Fabien Potencier <fabien@symfony.com>
 *
 * For the full copyright and license information, please view the LICENSE
 * file that was distributed with this source code.
 */

namespace Symfony\Component\DependencyInjection\Tests\Compiler;

use Symfony\Component\DependencyInjection\Definition;
use Symfony\Component\DependencyInjection\Compiler\AnalyzeServiceReferencesPass;
use Symfony\Component\DependencyInjection\Compiler\RepeatedPass;
use Symfony\Component\DependencyInjection\Reference;
use Symfony\Component\DependencyInjection\ContainerBuilder;

class AnalyzeServiceReferencesPassTest extends \PHPUnit_Framework_TestCase
{
    public function testProcess()
    {
        $container = new ContainerBuilder();

        $a = $container
            ->register('a')
            ->addArgument($ref1 = new Reference('b'))
        ;

        $b = $container
            ->register('b')
            ->addMethodCall('setA', array($ref2 = new Reference('a')))
        ;

        $c = $container
            ->register('c')
            ->addArgument($ref3 = new Reference('a'))
            ->addArgument($ref4 = new Reference('b'))
        ;

        $d = $container
            ->register('d')
            ->setProperty('foo', $ref5 = new Reference('b'))
        ;

        $e = $container
            ->register('e')
            ->setConfigurator(array($ref6 = new Reference('b'), 'methodName'))
        ;

        $graph = $this->process($container);

        $this->assertCount(4, $edges = $graph->getNode('b')->getInEdges());

        $this->assertSame($ref1, $edges[0]->getValue());
        $this->assertSame($ref4, $edges[1]->getValue());
        $this->assertSame($ref5, $edges[2]->getValue());
        $this->assertSame($ref6, $edges[3]->getValue());
    }

    public function testProcessDetectsReferencesFromInlinedDefinitions()
    {
        $container = new ContainerBuilder();

        $container
            ->register('a')
        ;

        $container
            ->register('b')
            ->addArgument(new Definition(null, array($ref = new Reference('a'))))
        ;

        $graph = $this->process($container);

        $this->assertCount(1, $refs = $graph->getNode('a')->getInEdges());
        $this->assertSame($ref, $refs[0]->getValue());
    }

    public function testProcessDetectsReferencesFromInlinedFactoryDefinitions()
    {
        $container = new ContainerBuilder();

        $container
            ->register('a')
        ;

        $factory = new Definition();
        $factory->setFactory(array(new Reference('a'), 'a'));

        $container
            ->register('b')
            ->addArgument($factory)
        ;

        $graph = $this->process($container);

        $this->assertTrue($graph->hasNode('a'));
        $this->assertCount(1, $refs = $graph->getNode('a')->getInEdges());
    }

    public function testProcessDoesNotSaveDuplicateReferences()
    {
        $container = new ContainerBuilder();

        $container
            ->register('a')
        ;
        $container
            ->register('b')
            ->addArgument(new Definition(null, array($ref1 = new Reference('a'))))
            ->addArgument(new Definition(null, array($ref2 = new Reference('a'))))
        ;

        $graph = $this->process($container);

        $this->assertCount(2, $graph->getNode('a')->getInEdges());
    }

    public function testProcessDetectsFactoryReferences()
    {
        $container = new ContainerBuilder();

        $container
            ->register('foo', 'stdClass')
            ->setFactory(array('stdClass', 'getInstance'));

        $container
            ->register('bar', 'stdClass')
            ->setFactory(array(new Reference('foo'), 'getInstance'));

        $graph = $this->process($container);

        $this->assertTrue($graph->hasNode('foo'));
        $this->assertCount(1, $graph->getNode('foo')->getInEdges());
    }

    protected function process(ContainerBuilder $container)
    {
        $pass = new RepeatedPass(array(new AnalyzeServiceReferencesPass()));
        $pass->process($container);

        return $container->getCompiler()->getServiceReferenceGraph();
    }
}
PKϤ$Z�ڨ�Fdependency-injection/Tests/Compiler/CheckReferenceValidityPassTest.phpnu�[���<?php

/*
 * This file is part of the Symfony package.
 *
 * (c) Fabien Potencier <fabien@symfony.com>
 *
 * For the full copyright and license information, please view the LICENSE
 * file that was distributed with this source code.
 */

namespace Symfony\Component\DependencyInjection\Tests\Compiler;

use Symfony\Component\DependencyInjection\Compiler\CheckReferenceValidityPass;
use Symfony\Component\DependencyInjection\Reference;
use Symfony\Component\DependencyInjection\ContainerBuilder;

class CheckReferenceValidityPassTest extends \PHPUnit_Framework_TestCase
{
    /**
     * @expectedException \RuntimeException
     */
    public function testProcessDetectsReferenceToAbstractDefinition()
    {
        $container = new ContainerBuilder();

        $container->register('a')->setAbstract(true);
        $container->register('b')->addArgument(new Reference('a'));

        $this->process($container);
    }

    public function testProcess()
    {
        $container = new ContainerBuilder();
        $container->register('a')->addArgument(new Reference('b'));
        $container->register('b');

        $this->process($container);
    }

    protected function process(ContainerBuilder $container)
    {
        $pass = new CheckReferenceValidityPass();
        $pass->process($container);
    }
}
PKϤ$Z��@�@dependency-injection/Tests/Compiler/AutoAliasServicePassTest.phpnu�[���<?php

/*
 * This file is part of the Symfony package.
 *
 * (c) Fabien Potencier <fabien@symfony.com>
 *
 * For the full copyright and license information, please view the LICENSE
 * file that was distributed with this source code.
 */

namespace Symfony\Component\DependencyInjection\Tests\Compiler;

use Symfony\Component\DependencyInjection\Compiler\AutoAliasServicePass;
use Symfony\Component\DependencyInjection\ContainerBuilder;

class AutoAliasServicePassTest extends \PHPUnit_Framework_TestCase
{
    /**
     * @expectedException \Symfony\Component\DependencyInjection\Exception\ParameterNotFoundException
     */
    public function testProcessWithMissingParameter()
    {
        $container = new ContainerBuilder();

        $container->register('example')
          ->addTag('auto_alias', array('format' => '%non_existing%.example'));

        $pass = new AutoAliasServicePass();
        $pass->process($container);
    }

    /**
     * @expectedException \Symfony\Component\DependencyInjection\Exception\InvalidArgumentException
     */
    public function testProcessWithMissingFormat()
    {
        $container = new ContainerBuilder();

        $container->register('example')
          ->addTag('auto_alias', array());
        $container->setParameter('existing', 'mysql');

        $pass = new AutoAliasServicePass();
        $pass->process($container);
    }

    public function testProcessWithNonExistingAlias()
    {
        $container = new ContainerBuilder();

        $container->register('example', 'Symfony\Component\DependencyInjection\Tests\Compiler\ServiceClassDefault')
          ->addTag('auto_alias', array('format' => '%existing%.example'));
        $container->setParameter('existing', 'mysql');

        $pass = new AutoAliasServicePass();
        $pass->process($container);

        $this->assertEquals('Symfony\Component\DependencyInjection\Tests\Compiler\ServiceClassDefault', $container->getDefinition('example')->getClass());
        $this->assertInstanceOf('Symfony\Component\DependencyInjection\Tests\Compiler\ServiceClassDefault', $container->get('example'));
    }

    public function testProcessWithExistingAlias()
    {
        $container = new ContainerBuilder();

        $container->register('example', 'Symfony\Component\DependencyInjection\Tests\Compiler\ServiceClassDefault')
          ->addTag('auto_alias', array('format' => '%existing%.example'));

        $container->register('mysql.example', 'Symfony\Component\DependencyInjection\Tests\Compiler\ServiceClassMysql');
        $container->setParameter('existing', 'mysql');

        $pass = new AutoAliasServicePass();
        $pass->process($container);

        $this->assertTrue($container->hasAlias('example'));
        $this->assertEquals('mysql.example', $container->getAlias('example'));
        $this->assertInstanceOf('Symfony\Component\DependencyInjection\Tests\Compiler\ServiceClassMysql', $container->get('example'));
    }

    public function testProcessWithManualAlias()
    {
        $container = new ContainerBuilder();

        $container->register('example', 'Symfony\Component\DependencyInjection\Tests\Compiler\ServiceClassDefault')
          ->addTag('auto_alias', array('format' => '%existing%.example'));

        $container->register('mysql.example', 'Symfony\Component\DependencyInjection\Tests\Compiler\ServiceClassMysql');
        $container->register('mariadb.example', 'Symfony\Component\DependencyInjection\Tests\Compiler\ServiceClassMariadb');
        $container->setAlias('example', 'mariadb.example');
        $container->setParameter('existing', 'mysql');

        $pass = new AutoAliasServicePass();
        $pass->process($container);

        $this->assertTrue($container->hasAlias('example'));
        $this->assertEquals('mariadb.example', $container->getAlias('example'));
        $this->assertInstanceOf('Symfony\Component\DependencyInjection\Tests\Compiler\ServiceClassMariaDb', $container->get('example'));
    }
}

class ServiceClassDefault
{
}

class ServiceClassMysql extends ServiceClassDefault
{
}

class ServiceClassMariaDb extends ServiceClassMysql
{
}
PKϤ$Z����@dependency-injection/Tests/Compiler/DecoratorServicePassTest.phpnu�[���<?php

/*
 * This file is part of the Symfony package.
 *
 * (c) Fabien Potencier <fabien@symfony.com>
 *
 * For the full copyright and license information, please view the LICENSE
 * file that was distributed with this source code.
 */

namespace Symfony\Component\DependencyInjection\Tests\Compiler;

use Symfony\Component\DependencyInjection\Alias;
use Symfony\Component\DependencyInjection\ContainerBuilder;
use Symfony\Component\DependencyInjection\Compiler\DecoratorServicePass;

class DecoratorServicePassTest extends \PHPUnit_Framework_TestCase
{
    public function testProcessWithoutAlias()
    {
        $container = new ContainerBuilder();
        $fooDefinition = $container
            ->register('foo')
            ->setPublic(false)
        ;
        $fooExtendedDefinition = $container
            ->register('foo.extended')
            ->setPublic(true)
            ->setDecoratedService('foo')
        ;
        $barDefinition = $container
            ->register('bar')
            ->setPublic(true)
        ;
        $barExtendedDefinition = $container
            ->register('bar.extended')
            ->setPublic(true)
            ->setDecoratedService('bar', 'bar.yoo')
        ;

        $this->process($container);

        $this->assertEquals('foo.extended', $container->getAlias('foo'));
        $this->assertFalse($container->getAlias('foo')->isPublic());

        $this->assertEquals('bar.extended', $container->getAlias('bar'));
        $this->assertTrue($container->getAlias('bar')->isPublic());

        $this->assertSame($fooDefinition, $container->getDefinition('foo.extended.inner'));
        $this->assertFalse($container->getDefinition('foo.extended.inner')->isPublic());

        $this->assertSame($barDefinition, $container->getDefinition('bar.yoo'));
        $this->assertFalse($container->getDefinition('bar.yoo')->isPublic());

        $this->assertNull($fooExtendedDefinition->getDecoratedService());
        $this->assertNull($barExtendedDefinition->getDecoratedService());
    }

    public function testProcessWithAlias()
    {
        $container = new ContainerBuilder();
        $container
            ->register('foo')
            ->setPublic(true)
        ;
        $container->setAlias('foo.alias', new Alias('foo', false));
        $fooExtendedDefinition = $container
            ->register('foo.extended')
            ->setPublic(true)
            ->setDecoratedService('foo.alias')
        ;

        $this->process($container);

        $this->assertEquals('foo.extended', $container->getAlias('foo.alias'));
        $this->assertFalse($container->getAlias('foo.alias')->isPublic());

        $this->assertEquals('foo', $container->getAlias('foo.extended.inner'));
        $this->assertFalse($container->getAlias('foo.extended.inner')->isPublic());

        $this->assertNull($fooExtendedDefinition->getDecoratedService());
    }

    public function testProcessWithPriority()
    {
        $container = new ContainerBuilder();
        $fooDefinition = $container
            ->register('foo')
            ->setPublic(false)
        ;
        $barDefinition = $container
            ->register('bar')
            ->setPublic(true)
            ->setDecoratedService('foo')
        ;
        $bazDefinition = $container
            ->register('baz')
            ->setPublic(true)
            ->setDecoratedService('foo', null, 5)
        ;
        $quxDefinition = $container
            ->register('qux')
            ->setPublic(true)
            ->setDecoratedService('foo', null, 3)
        ;

        $this->process($container);

        $this->assertEquals('bar', $container->getAlias('foo'));
        $this->assertFalse($container->getAlias('foo')->isPublic());

        $this->assertSame($fooDefinition, $container->getDefinition('baz.inner'));
        $this->assertFalse($container->getDefinition('baz.inner')->isPublic());

        $this->assertEquals('qux', $container->getAlias('bar.inner'));
        $this->assertFalse($container->getAlias('bar.inner')->isPublic());

        $this->assertEquals('baz', $container->getAlias('qux.inner'));
        $this->assertFalse($container->getAlias('qux.inner')->isPublic());

        $this->assertNull($barDefinition->getDecoratedService());
        $this->assertNull($bazDefinition->getDecoratedService());
        $this->assertNull($quxDefinition->getDecoratedService());
    }

    public function testProcessMovesTagsFromDecoratedDefinitionToDecoratingDefinition()
    {
        $container = new ContainerBuilder();
        $container
            ->register('foo')
            ->setTags(array('bar' => array('attr' => 'baz')))
        ;
        $container
            ->register('baz')
            ->setTags(array('foobar' => array('attr' => 'bar')))
            ->setDecoratedService('foo')
        ;

        $this->process($container);

        $this->assertEmpty($container->getDefinition('baz.inner')->getTags());
        $this->assertEquals(array('bar' => array('attr' => 'baz'), 'foobar' => array('attr' => 'bar')), $container->getDefinition('baz')->getTags());
    }

    public function testProcessMergesAutowiringTypesInDecoratingDefinitionAndRemoveThemFromDecoratedDefinition()
    {
        $container = new ContainerBuilder();

        $container
            ->register('parent')
            ->addAutowiringType('Bar')
        ;

        $container
            ->register('child')
            ->setDecoratedService('parent')
            ->addAutowiringType('Foo')
        ;

        $this->process($container);

        $this->assertEquals(array('Bar', 'Foo'), $container->getDefinition('child')->getAutowiringTypes());
        $this->assertEmpty($container->getDefinition('child.inner')->getAutowiringTypes());
    }

    protected function process(ContainerBuilder $container)
    {
        $repeatedPass = new DecoratorServicePass();
        $repeatedPass->process($container);
    }
}
PKϤ$Z�١���6dependency-injection/Tests/Fixtures/php/services13.phpnu�[���<?php

use Symfony\Component\DependencyInjection\ContainerInterface;
use Symfony\Component\DependencyInjection\Container;
use Symfony\Component\DependencyInjection\Exception\InvalidArgumentException;
use Symfony\Component\DependencyInjection\Exception\LogicException;
use Symfony\Component\DependencyInjection\Exception\RuntimeException;
use Symfony\Component\DependencyInjection\ParameterBag\FrozenParameterBag;

/**
 * ProjectServiceContainer.
 *
 * This class has been auto-generated
 * by the Symfony Dependency Injection Component.
 */
class ProjectServiceContainer extends Container
{
    private $parameters;
    private $targetDirs = array();

    /**
     * Constructor.
     */
    public function __construct()
    {
        $this->services = array();
        $this->methodMap = array(
            'bar' => 'getBarService',
        );

        $this->aliases = array();
    }

    /**
     * {@inheritdoc}
     */
    public function compile()
    {
        throw new LogicException('You cannot compile a dumped frozen container.');
    }

    /**
     * {@inheritdoc}
     */
    public function isFrozen()
    {
        return true;
    }

    /**
     * Gets the 'bar' service.
     *
     * This service is shared.
     * This method always returns the same instance of the service.
     *
     * @return \stdClass A stdClass instance
     */
    protected function getBarService()
    {
        $a = new \stdClass();
        $a->add($this);

        return $this->services['bar'] = new \stdClass($a);
    }
}
PKϤ$Zm"!mm6dependency-injection/Tests/Fixtures/php/services12.phpnu�[���<?php

use Symfony\Component\DependencyInjection\ContainerInterface;
use Symfony\Component\DependencyInjection\Container;
use Symfony\Component\DependencyInjection\Exception\InvalidArgumentException;
use Symfony\Component\DependencyInjection\Exception\LogicException;
use Symfony\Component\DependencyInjection\Exception\RuntimeException;
use Symfony\Component\DependencyInjection\ParameterBag\FrozenParameterBag;

/**
 * ProjectServiceContainer.
 *
 * This class has been auto-generated
 * by the Symfony Dependency Injection Component.
 */
class ProjectServiceContainer extends Container
{
    private $parameters;
    private $targetDirs = array();

    /**
     * Constructor.
     */
    public function __construct()
    {
        $dir = __DIR__;
        for ($i = 1; $i <= 5; ++$i) {
            $this->targetDirs[$i] = $dir = dirname($dir);
        }
        $this->parameters = $this->getDefaultParameters();

        $this->services = array();
        $this->methodMap = array(
            'test' => 'getTestService',
        );

        $this->aliases = array();
    }

    /**
     * {@inheritdoc}
     */
    public function compile()
    {
        throw new LogicException('You cannot compile a dumped frozen container.');
    }

    /**
     * {@inheritdoc}
     */
    public function isFrozen()
    {
        return true;
    }

    /**
     * Gets the 'test' service.
     *
     * This service is shared.
     * This method always returns the same instance of the service.
     *
     * @return \stdClass A stdClass instance
     */
    protected function getTestService()
    {
        return $this->services['test'] = new \stdClass(('wiz'.$this->targetDirs[1]), array(('wiz'.$this->targetDirs[1]) => ($this->targetDirs[2].'/')));
    }

    /**
     * {@inheritdoc}
     */
    public function getParameter($name)
    {
        $name = strtolower($name);

        if (!(isset($this->parameters[$name]) || array_key_exists($name, $this->parameters))) {
            throw new InvalidArgumentException(sprintf('The parameter "%s" must be defined.', $name));
        }

        return $this->parameters[$name];
    }

    /**
     * {@inheritdoc}
     */
    public function hasParameter($name)
    {
        $name = strtolower($name);

        return isset($this->parameters[$name]) || array_key_exists($name, $this->parameters);
    }

    /**
     * {@inheritdoc}
     */
    public function setParameter($name, $value)
    {
        throw new LogicException('Impossible to call set() on a frozen ParameterBag.');
    }

    /**
     * {@inheritdoc}
     */
    public function getParameterBag()
    {
        if (null === $this->parameterBag) {
            $this->parameterBag = new FrozenParameterBag($this->parameters);
        }

        return $this->parameterBag;
    }

    /**
     * Gets the default parameters.
     *
     * @return array An array of the default parameters
     */
    protected function getDefaultParameters()
    {
        return array(
            'foo' => ('wiz'.$this->targetDirs[1]),
            'bar' => __DIR__,
            'baz' => (__DIR__.'/PhpDumperTest.php'),
            'buz' => $this->targetDirs[2],
        );
    }
}
PKϤ$Z�5���5dependency-injection/Tests/Fixtures/php/services1.phpnu�[���<?php

use Symfony\Component\DependencyInjection\ContainerInterface;
use Symfony\Component\DependencyInjection\Container;
use Symfony\Component\DependencyInjection\Exception\InvalidArgumentException;
use Symfony\Component\DependencyInjection\Exception\LogicException;
use Symfony\Component\DependencyInjection\Exception\RuntimeException;
use Symfony\Component\DependencyInjection\ParameterBag\ParameterBag;

/**
 * ProjectServiceContainer.
 *
 * This class has been auto-generated
 * by the Symfony Dependency Injection Component.
 */
class ProjectServiceContainer extends Container
{
    private $parameters;
    private $targetDirs = array();

    /**
     * Constructor.
     */
    public function __construct()
    {
        parent::__construct();
    }
}
PKϤ$Zp�#���6dependency-injection/Tests/Fixtures/php/services10.phpnu�[���<?php

use Symfony\Component\DependencyInjection\ContainerInterface;
use Symfony\Component\DependencyInjection\Container;
use Symfony\Component\DependencyInjection\Exception\InvalidArgumentException;
use Symfony\Component\DependencyInjection\Exception\LogicException;
use Symfony\Component\DependencyInjection\Exception\RuntimeException;
use Symfony\Component\DependencyInjection\ParameterBag\FrozenParameterBag;

/**
 * ProjectServiceContainer.
 *
 * This class has been auto-generated
 * by the Symfony Dependency Injection Component.
 */
class ProjectServiceContainer extends Container
{
    private $parameters;
    private $targetDirs = array();

    /**
     * Constructor.
     */
    public function __construct()
    {
        $this->parameters = $this->getDefaultParameters();

        $this->services = array();
        $this->methodMap = array(
            'test' => 'getTestService',
        );

        $this->aliases = array();
    }

    /**
     * {@inheritdoc}
     */
    public function compile()
    {
        throw new LogicException('You cannot compile a dumped frozen container.');
    }

    /**
     * {@inheritdoc}
     */
    public function isFrozen()
    {
        return true;
    }

    /**
     * Gets the 'test' service.
     *
     * This service is shared.
     * This method always returns the same instance of the service.
     *
     * @return \stdClass A stdClass instance
     */
    protected function getTestService()
    {
        return $this->services['test'] = new \stdClass(array('only dot' => '.', 'concatenation as value' => '.\'\'.', 'concatenation from the start value' => '\'\'.', '.' => 'dot as a key', '.\'\'.' => 'concatenation as a key', '\'\'.' => 'concatenation from the start key', 'optimize concatenation' => 'string1-string2', 'optimize concatenation with empty string' => 'string1string2', 'optimize concatenation from the start' => 'start', 'optimize concatenation at the end' => 'end'));
    }

    /**
     * {@inheritdoc}
     */
    public function getParameter($name)
    {
        $name = strtolower($name);

        if (!(isset($this->parameters[$name]) || array_key_exists($name, $this->parameters))) {
            throw new InvalidArgumentException(sprintf('The parameter "%s" must be defined.', $name));
        }

        return $this->parameters[$name];
    }

    /**
     * {@inheritdoc}
     */
    public function hasParameter($name)
    {
        $name = strtolower($name);

        return isset($this->parameters[$name]) || array_key_exists($name, $this->parameters);
    }

    /**
     * {@inheritdoc}
     */
    public function setParameter($name, $value)
    {
        throw new LogicException('Impossible to call set() on a frozen ParameterBag.');
    }

    /**
     * {@inheritdoc}
     */
    public function getParameterBag()
    {
        if (null === $this->parameterBag) {
            $this->parameterBag = new FrozenParameterBag($this->parameters);
        }

        return $this->parameterBag;
    }

    /**
     * Gets the default parameters.
     *
     * @return array An array of the default parameters
     */
    protected function getDefaultParameters()
    {
        return array(
            'empty_value' => '',
            'some_string' => '-',
        );
    }
}
PKϤ$Z7�l�,�,>dependency-injection/Tests/Fixtures/php/services9_compiled.phpnu�[���<?php

use Symfony\Component\DependencyInjection\ContainerInterface;
use Symfony\Component\DependencyInjection\Container;
use Symfony\Component\DependencyInjection\Exception\InvalidArgumentException;
use Symfony\Component\DependencyInjection\Exception\LogicException;
use Symfony\Component\DependencyInjection\Exception\RuntimeException;
use Symfony\Component\DependencyInjection\ParameterBag\FrozenParameterBag;

/**
 * ProjectServiceContainer.
 *
 * This class has been auto-generated
 * by the Symfony Dependency Injection Component.
 */
class ProjectServiceContainer extends Container
{
    private $parameters;
    private $targetDirs = array();

    /**
     * Constructor.
     */
    public function __construct()
    {
        $this->parameters = $this->getDefaultParameters();

        $this->services = array();
        $this->methodMap = array(
            'bar' => 'getBarService',
            'baz' => 'getBazService',
            'configured_service' => 'getConfiguredServiceService',
            'configured_service_simple' => 'getConfiguredServiceSimpleService',
            'decorator_service' => 'getDecoratorServiceService',
            'decorator_service_with_name' => 'getDecoratorServiceWithNameService',
            'deprecated_service' => 'getDeprecatedServiceService',
            'factory_service' => 'getFactoryServiceService',
            'factory_service_simple' => 'getFactoryServiceSimpleService',
            'foo' => 'getFooService',
            'foo.baz' => 'getFoo_BazService',
            'foo_bar' => 'getFooBarService',
            'foo_with_inline' => 'getFooWithInlineService',
            'method_call1' => 'getMethodCall1Service',
            'new_factory_service' => 'getNewFactoryServiceService',
            'request' => 'getRequestService',
            'service_from_static_method' => 'getServiceFromStaticMethodService',
        );
        $this->aliases = array(
            'alias_for_alias' => 'foo',
            'alias_for_foo' => 'foo',
            'decorated' => 'decorator_service_with_name',
        );
    }

    /**
     * {@inheritdoc}
     */
    public function compile()
    {
        throw new LogicException('You cannot compile a dumped frozen container.');
    }

    /**
     * {@inheritdoc}
     */
    public function isFrozen()
    {
        return true;
    }

    /**
     * Gets the 'bar' service.
     *
     * This service is shared.
     * This method always returns the same instance of the service.
     *
     * @return \Bar\FooClass A Bar\FooClass instance
     */
    protected function getBarService()
    {
        $a = $this->get('foo.baz');

        $this->services['bar'] = $instance = new \Bar\FooClass('foo', $a, $this->getParameter('foo_bar'));

        $a->configure($instance);

        return $instance;
    }

    /**
     * Gets the 'baz' service.
     *
     * This service is shared.
     * This method always returns the same instance of the service.
     *
     * @return \Baz A Baz instance
     */
    protected function getBazService()
    {
        $this->services['baz'] = $instance = new \Baz();

        $instance->setFoo($this->get('foo_with_inline'));

        return $instance;
    }

    /**
     * Gets the 'configured_service' service.
     *
     * This service is shared.
     * This method always returns the same instance of the service.
     *
     * @return \stdClass A stdClass instance
     */
    protected function getConfiguredServiceService()
    {
        $a = new \ConfClass();
        $a->setFoo($this->get('baz'));

        $this->services['configured_service'] = $instance = new \stdClass();

        $a->configureStdClass($instance);

        return $instance;
    }

    /**
     * Gets the 'configured_service_simple' service.
     *
     * This service is shared.
     * This method always returns the same instance of the service.
     *
     * @return \stdClass A stdClass instance
     */
    protected function getConfiguredServiceSimpleService()
    {
        $this->services['configured_service_simple'] = $instance = new \stdClass();

        (new \ConfClass('bar'))->configureStdClass($instance);

        return $instance;
    }

    /**
     * Gets the 'decorator_service' service.
     *
     * This service is shared.
     * This method always returns the same instance of the service.
     *
     * @return \stdClass A stdClass instance
     */
    protected function getDecoratorServiceService()
    {
        return $this->services['decorator_service'] = new \stdClass();
    }

    /**
     * Gets the 'decorator_service_with_name' service.
     *
     * This service is shared.
     * This method always returns the same instance of the service.
     *
     * @return \stdClass A stdClass instance
     */
    protected function getDecoratorServiceWithNameService()
    {
        return $this->services['decorator_service_with_name'] = new \stdClass();
    }

    /**
     * Gets the 'deprecated_service' service.
     *
     * This service is shared.
     * This method always returns the same instance of the service.
     *
     * @return \stdClass A stdClass instance
     *
     * @deprecated The "deprecated_service" service is deprecated. You should stop using it, as it will soon be removed.
     */
    protected function getDeprecatedServiceService()
    {
        @trigger_error('The "deprecated_service" service is deprecated. You should stop using it, as it will soon be removed.', E_USER_DEPRECATED);

        return $this->services['deprecated_service'] = new \stdClass();
    }

    /**
     * Gets the 'factory_service' service.
     *
     * This service is shared.
     * This method always returns the same instance of the service.
     *
     * @return \Bar A Bar instance
     */
    protected function getFactoryServiceService()
    {
        return $this->services['factory_service'] = $this->get('foo.baz')->getInstance();
    }

    /**
     * Gets the 'factory_service_simple' service.
     *
     * This service is shared.
     * This method always returns the same instance of the service.
     *
     * @return \Bar A Bar instance
     */
    protected function getFactoryServiceSimpleService()
    {
        return $this->services['factory_service_simple'] = (new \SimpleFactoryClass('foo'))->getInstance();
    }

    /**
     * Gets the 'foo' service.
     *
     * This service is shared.
     * This method always returns the same instance of the service.
     *
     * @return \Bar\FooClass A Bar\FooClass instance
     */
    protected function getFooService()
    {
        $a = $this->get('foo.baz');

        $this->services['foo'] = $instance = \Bar\FooClass::getInstance('foo', $a, array('bar' => 'foo is bar', 'foobar' => 'bar'), true, $this);

        $instance->foo = 'bar';
        $instance->moo = $a;
        $instance->qux = array('bar' => 'foo is bar', 'foobar' => 'bar');
        $instance->setBar($this->get('bar'));
        $instance->initialize();
        sc_configure($instance);

        return $instance;
    }

    /**
     * Gets the 'foo.baz' service.
     *
     * This service is shared.
     * This method always returns the same instance of the service.
     *
     * @return \BazClass A BazClass instance
     */
    protected function getFoo_BazService()
    {
        $this->services['foo.baz'] = $instance = \BazClass::getInstance();

        \BazClass::configureStatic1($instance);

        return $instance;
    }

    /**
     * Gets the 'foo_bar' service.
     *
     * @return \Bar\FooClass A Bar\FooClass instance
     */
    protected function getFooBarService()
    {
        return new \Bar\FooClass();
    }

    /**
     * Gets the 'foo_with_inline' service.
     *
     * This service is shared.
     * This method always returns the same instance of the service.
     *
     * @return \Foo A Foo instance
     */
    protected function getFooWithInlineService()
    {
        $a = new \Bar();

        $this->services['foo_with_inline'] = $instance = new \Foo();

        $a->pub = 'pub';
        $a->setBaz($this->get('baz'));

        $instance->setBar($a);

        return $instance;
    }

    /**
     * Gets the 'method_call1' service.
     *
     * This service is shared.
     * This method always returns the same instance of the service.
     *
     * @return \Bar\FooClass A Bar\FooClass instance
     */
    protected function getMethodCall1Service()
    {
        require_once '%path%foo.php';

        $this->services['method_call1'] = $instance = new \Bar\FooClass();

        $instance->setBar($this->get('foo'));
        $instance->setBar(NULL);
        $instance->setBar(($this->get("foo")->foo() . (($this->hasParameter("foo")) ? ($this->getParameter("foo")) : ("default"))));

        return $instance;
    }

    /**
     * Gets the 'new_factory_service' service.
     *
     * This service is shared.
     * This method always returns the same instance of the service.
     *
     * @return \FooBarBaz A FooBarBaz instance
     */
    protected function getNewFactoryServiceService()
    {
        $a = new \FactoryClass();
        $a->foo = 'bar';

        $this->services['new_factory_service'] = $instance = $a->getInstance();

        $instance->foo = 'bar';

        return $instance;
    }

    /**
     * Gets the 'request' service.
     *
     * This service is shared.
     * This method always returns the same instance of the service.
     *
     * @throws RuntimeException always since this service is expected to be injected dynamically
     */
    protected function getRequestService()
    {
        throw new RuntimeException('You have requested a synthetic service ("request"). The DIC does not know how to construct this service.');
    }

    /**
     * Gets the 'service_from_static_method' service.
     *
     * This service is shared.
     * This method always returns the same instance of the service.
     *
     * @return \Bar\FooClass A Bar\FooClass instance
     */
    protected function getServiceFromStaticMethodService()
    {
        return $this->services['service_from_static_method'] = \Bar\FooClass::getInstance();
    }

    /**
     * {@inheritdoc}
     */
    public function getParameter($name)
    {
        $name = strtolower($name);

        if (!(isset($this->parameters[$name]) || array_key_exists($name, $this->parameters))) {
            throw new InvalidArgumentException(sprintf('The parameter "%s" must be defined.', $name));
        }

        return $this->parameters[$name];
    }

    /**
     * {@inheritdoc}
     */
    public function hasParameter($name)
    {
        $name = strtolower($name);

        return isset($this->parameters[$name]) || array_key_exists($name, $this->parameters);
    }

    /**
     * {@inheritdoc}
     */
    public function setParameter($name, $value)
    {
        throw new LogicException('Impossible to call set() on a frozen ParameterBag.');
    }

    /**
     * {@inheritdoc}
     */
    public function getParameterBag()
    {
        if (null === $this->parameterBag) {
            $this->parameterBag = new FrozenParameterBag($this->parameters);
        }

        return $this->parameterBag;
    }

    /**
     * Gets the default parameters.
     *
     * @return array An array of the default parameters
     */
    protected function getDefaultParameters()
    {
        return array(
            'baz_class' => 'BazClass',
            'foo_class' => 'Bar\\FooClass',
            'foo' => 'bar',
        );
    }
}
PKϤ$Z�B�	�7�75dependency-injection/Tests/Fixtures/php/services9.phpnu�[���<?php

use Symfony\Component\DependencyInjection\ContainerInterface;
use Symfony\Component\DependencyInjection\Container;
use Symfony\Component\DependencyInjection\Exception\InvalidArgumentException;
use Symfony\Component\DependencyInjection\Exception\LogicException;
use Symfony\Component\DependencyInjection\Exception\RuntimeException;
use Symfony\Component\DependencyInjection\ParameterBag\ParameterBag;

/**
 * ProjectServiceContainer.
 *
 * This class has been auto-generated
 * by the Symfony Dependency Injection Component.
 */
class ProjectServiceContainer extends Container
{
    private $parameters;
    private $targetDirs = array();

    /**
     * Constructor.
     */
    public function __construct()
    {
        parent::__construct(new ParameterBag($this->getDefaultParameters()));
        $this->methodMap = array(
            'bar' => 'getBarService',
            'baz' => 'getBazService',
            'configurator_service' => 'getConfiguratorServiceService',
            'configurator_service_simple' => 'getConfiguratorServiceSimpleService',
            'configured_service' => 'getConfiguredServiceService',
            'configured_service_simple' => 'getConfiguredServiceSimpleService',
            'decorated' => 'getDecoratedService',
            'decorator_service' => 'getDecoratorServiceService',
            'decorator_service_with_name' => 'getDecoratorServiceWithNameService',
            'deprecated_service' => 'getDeprecatedServiceService',
            'factory_service' => 'getFactoryServiceService',
            'factory_service_simple' => 'getFactoryServiceSimpleService',
            'factory_simple' => 'getFactorySimpleService',
            'foo' => 'getFooService',
            'foo.baz' => 'getFoo_BazService',
            'foo_bar' => 'getFooBarService',
            'foo_with_inline' => 'getFooWithInlineService',
            'inlined' => 'getInlinedService',
            'method_call1' => 'getMethodCall1Service',
            'new_factory' => 'getNewFactoryService',
            'new_factory_service' => 'getNewFactoryServiceService',
            'request' => 'getRequestService',
            'service_from_static_method' => 'getServiceFromStaticMethodService',
        );
        $this->aliases = array(
            'alias_for_alias' => 'foo',
            'alias_for_foo' => 'foo',
        );
    }

    /**
     * Gets the 'bar' service.
     *
     * This service is shared.
     * This method always returns the same instance of the service.
     *
     * @return \Bar\FooClass A Bar\FooClass instance
     */
    protected function getBarService()
    {
        $a = $this->get('foo.baz');

        $this->services['bar'] = $instance = new \Bar\FooClass('foo', $a, $this->getParameter('foo_bar'));

        $a->configure($instance);

        return $instance;
    }

    /**
     * Gets the 'baz' service.
     *
     * This service is shared.
     * This method always returns the same instance of the service.
     *
     * @return \Baz A Baz instance
     */
    protected function getBazService()
    {
        $this->services['baz'] = $instance = new \Baz();

        $instance->setFoo($this->get('foo_with_inline'));

        return $instance;
    }

    /**
     * Gets the 'configured_service' service.
     *
     * This service is shared.
     * This method always returns the same instance of the service.
     *
     * @return \stdClass A stdClass instance
     */
    protected function getConfiguredServiceService()
    {
        $this->services['configured_service'] = $instance = new \stdClass();

        $this->get('configurator_service')->configureStdClass($instance);

        return $instance;
    }

    /**
     * Gets the 'configured_service_simple' service.
     *
     * This service is shared.
     * This method always returns the same instance of the service.
     *
     * @return \stdClass A stdClass instance
     */
    protected function getConfiguredServiceSimpleService()
    {
        $this->services['configured_service_simple'] = $instance = new \stdClass();

        $this->get('configurator_service_simple')->configureStdClass($instance);

        return $instance;
    }

    /**
     * Gets the 'decorated' service.
     *
     * This service is shared.
     * This method always returns the same instance of the service.
     *
     * @return \stdClass A stdClass instance
     */
    protected function getDecoratedService()
    {
        return $this->services['decorated'] = new \stdClass();
    }

    /**
     * Gets the 'decorator_service' service.
     *
     * This service is shared.
     * This method always returns the same instance of the service.
     *
     * @return \stdClass A stdClass instance
     */
    protected function getDecoratorServiceService()
    {
        return $this->services['decorator_service'] = new \stdClass();
    }

    /**
     * Gets the 'decorator_service_with_name' service.
     *
     * This service is shared.
     * This method always returns the same instance of the service.
     *
     * @return \stdClass A stdClass instance
     */
    protected function getDecoratorServiceWithNameService()
    {
        return $this->services['decorator_service_with_name'] = new \stdClass();
    }

    /**
     * Gets the 'deprecated_service' service.
     *
     * This service is shared.
     * This method always returns the same instance of the service.
     *
     * @return \stdClass A stdClass instance
     *
     * @deprecated The "deprecated_service" service is deprecated. You should stop using it, as it will soon be removed.
     */
    protected function getDeprecatedServiceService()
    {
        @trigger_error('The "deprecated_service" service is deprecated. You should stop using it, as it will soon be removed.', E_USER_DEPRECATED);

        return $this->services['deprecated_service'] = new \stdClass();
    }

    /**
     * Gets the 'factory_service' service.
     *
     * This service is shared.
     * This method always returns the same instance of the service.
     *
     * @return \Bar A Bar instance
     */
    protected function getFactoryServiceService()
    {
        return $this->services['factory_service'] = $this->get('foo.baz')->getInstance();
    }

    /**
     * Gets the 'factory_service_simple' service.
     *
     * This service is shared.
     * This method always returns the same instance of the service.
     *
     * @return \Bar A Bar instance
     */
    protected function getFactoryServiceSimpleService()
    {
        return $this->services['factory_service_simple'] = $this->get('factory_simple')->getInstance();
    }

    /**
     * Gets the 'foo' service.
     *
     * This service is shared.
     * This method always returns the same instance of the service.
     *
     * @return \Bar\FooClass A Bar\FooClass instance
     */
    protected function getFooService()
    {
        $a = $this->get('foo.baz');

        $this->services['foo'] = $instance = \Bar\FooClass::getInstance('foo', $a, array($this->getParameter('foo') => 'foo is '.$this->getParameter('foo').'', 'foobar' => $this->getParameter('foo')), true, $this);

        $instance->foo = 'bar';
        $instance->moo = $a;
        $instance->qux = array($this->getParameter('foo') => 'foo is '.$this->getParameter('foo').'', 'foobar' => $this->getParameter('foo'));
        $instance->setBar($this->get('bar'));
        $instance->initialize();
        sc_configure($instance);

        return $instance;
    }

    /**
     * Gets the 'foo.baz' service.
     *
     * This service is shared.
     * This method always returns the same instance of the service.
     *
     * @return object A %baz_class% instance
     */
    protected function getFoo_BazService()
    {
        $this->services['foo.baz'] = $instance = call_user_func(array($this->getParameter('baz_class'), 'getInstance'));

        call_user_func(array($this->getParameter('baz_class'), 'configureStatic1'), $instance);

        return $instance;
    }

    /**
     * Gets the 'foo_bar' service.
     *
     * @return object A %foo_class% instance
     */
    protected function getFooBarService()
    {
        $class = $this->getParameter('foo_class');

        return new $class();
    }

    /**
     * Gets the 'foo_with_inline' service.
     *
     * This service is shared.
     * This method always returns the same instance of the service.
     *
     * @return \Foo A Foo instance
     */
    protected function getFooWithInlineService()
    {
        $this->services['foo_with_inline'] = $instance = new \Foo();

        $instance->setBar($this->get('inlined'));

        return $instance;
    }

    /**
     * Gets the 'method_call1' service.
     *
     * This service is shared.
     * This method always returns the same instance of the service.
     *
     * @return \Bar\FooClass A Bar\FooClass instance
     */
    protected function getMethodCall1Service()
    {
        require_once '%path%foo.php';

        $this->services['method_call1'] = $instance = new \Bar\FooClass();

        $instance->setBar($this->get('foo'));
        $instance->setBar($this->get('foo2', ContainerInterface::NULL_ON_INVALID_REFERENCE));
        if ($this->has('foo3')) {
            $instance->setBar($this->get('foo3', ContainerInterface::NULL_ON_INVALID_REFERENCE));
        }
        if ($this->has('foobaz')) {
            $instance->setBar($this->get('foobaz', ContainerInterface::NULL_ON_INVALID_REFERENCE));
        }
        $instance->setBar(($this->get("foo")->foo() . (($this->hasParameter("foo")) ? ($this->getParameter("foo")) : ("default"))));

        return $instance;
    }

    /**
     * Gets the 'new_factory_service' service.
     *
     * This service is shared.
     * This method always returns the same instance of the service.
     *
     * @return \FooBarBaz A FooBarBaz instance
     */
    protected function getNewFactoryServiceService()
    {
        $this->services['new_factory_service'] = $instance = $this->get('new_factory')->getInstance();

        $instance->foo = 'bar';

        return $instance;
    }

    /**
     * Gets the 'request' service.
     *
     * This service is shared.
     * This method always returns the same instance of the service.
     *
     * @throws RuntimeException always since this service is expected to be injected dynamically
     */
    protected function getRequestService()
    {
        throw new RuntimeException('You have requested a synthetic service ("request"). The DIC does not know how to construct this service.');
    }

    /**
     * Gets the 'service_from_static_method' service.
     *
     * This service is shared.
     * This method always returns the same instance of the service.
     *
     * @return \Bar\FooClass A Bar\FooClass instance
     */
    protected function getServiceFromStaticMethodService()
    {
        return $this->services['service_from_static_method'] = \Bar\FooClass::getInstance();
    }

    /**
     * Gets the 'configurator_service' service.
     *
     * This service is shared.
     * This method always returns the same instance of the service.
     *
     * This service is private.
     * If you want to be able to request this service from the container directly,
     * make it public, otherwise you might end up with broken code.
     *
     * @return \ConfClass A ConfClass instance
     */
    protected function getConfiguratorServiceService()
    {
        $this->services['configurator_service'] = $instance = new \ConfClass();

        $instance->setFoo($this->get('baz'));

        return $instance;
    }

    /**
     * Gets the 'configurator_service_simple' service.
     *
     * This service is shared.
     * This method always returns the same instance of the service.
     *
     * This service is private.
     * If you want to be able to request this service from the container directly,
     * make it public, otherwise you might end up with broken code.
     *
     * @return \ConfClass A ConfClass instance
     */
    protected function getConfiguratorServiceSimpleService()
    {
        return $this->services['configurator_service_simple'] = new \ConfClass('bar');
    }

    /**
     * Gets the 'factory_simple' service.
     *
     * This service is shared.
     * This method always returns the same instance of the service.
     *
     * This service is private.
     * If you want to be able to request this service from the container directly,
     * make it public, otherwise you might end up with broken code.
     *
     * @return \SimpleFactoryClass A SimpleFactoryClass instance
     */
    protected function getFactorySimpleService()
    {
        return $this->services['factory_simple'] = new \SimpleFactoryClass('foo');
    }

    /**
     * Gets the 'inlined' service.
     *
     * This service is shared.
     * This method always returns the same instance of the service.
     *
     * This service is private.
     * If you want to be able to request this service from the container directly,
     * make it public, otherwise you might end up with broken code.
     *
     * @return \Bar A Bar instance
     */
    protected function getInlinedService()
    {
        $this->services['inlined'] = $instance = new \Bar();

        $instance->pub = 'pub';
        $instance->setBaz($this->get('baz'));

        return $instance;
    }

    /**
     * Gets the 'new_factory' service.
     *
     * This service is shared.
     * This method always returns the same instance of the service.
     *
     * This service is private.
     * If you want to be able to request this service from the container directly,
     * make it public, otherwise you might end up with broken code.
     *
     * @return \FactoryClass A FactoryClass instance
     */
    protected function getNewFactoryService()
    {
        $this->services['new_factory'] = $instance = new \FactoryClass();

        $instance->foo = 'bar';

        return $instance;
    }

    /**
     * Gets the default parameters.
     *
     * @return array An array of the default parameters
     */
    protected function getDefaultParameters()
    {
        return array(
            'baz_class' => 'BazClass',
            'foo_class' => 'Bar\\FooClass',
            'foo' => 'bar',
        );
    }
}
PKϤ$Z���//2dependency-injection/Tests/Fixtures/php/simple.phpnu�[���<?php

$container->setParameter('foo', 'foo');
PKϤ$Z�*�E7dependency-injection/Tests/Fixtures/php/services1-1.phpnu�[���<?php
namespace Symfony\Component\DependencyInjection\Dump;

use Symfony\Component\DependencyInjection\ContainerInterface;
use Symfony\Component\DependencyInjection\Container;
use Symfony\Component\DependencyInjection\Exception\InvalidArgumentException;
use Symfony\Component\DependencyInjection\Exception\LogicException;
use Symfony\Component\DependencyInjection\Exception\RuntimeException;
use Symfony\Component\DependencyInjection\ParameterBag\ParameterBag;

/**
 * Container.
 *
 * This class has been auto-generated
 * by the Symfony Dependency Injection Component.
 */
class Container extends AbstractContainer
{
    private $parameters;
    private $targetDirs = array();

    /**
     * Constructor.
     */
    public function __construct()
    {
        parent::__construct();
    }
}
PKϤ$Z�BɅ�6dependency-injection/Tests/Fixtures/php/services19.phpnu�[���<?php

use Symfony\Component\DependencyInjection\ContainerInterface;
use Symfony\Component\DependencyInjection\Container;
use Symfony\Component\DependencyInjection\Exception\InvalidArgumentException;
use Symfony\Component\DependencyInjection\Exception\LogicException;
use Symfony\Component\DependencyInjection\Exception\RuntimeException;
use Symfony\Component\DependencyInjection\ParameterBag\ParameterBag;

/**
 * ProjectServiceContainer.
 *
 * This class has been auto-generated
 * by the Symfony Dependency Injection Component.
 */
class ProjectServiceContainer extends Container
{
    private $parameters;
    private $targetDirs = array();

    /**
     * Constructor.
     */
    public function __construct()
    {
        parent::__construct();
        $this->methodMap = array(
            'service_from_anonymous_factory' => 'getServiceFromAnonymousFactoryService',
            'service_with_method_call_and_factory' => 'getServiceWithMethodCallAndFactoryService',
        );
    }

    /**
     * Gets the 'service_from_anonymous_factory' service.
     *
     * This service is shared.
     * This method always returns the same instance of the service.
     *
     * @return \Bar\FooClass A Bar\FooClass instance
     */
    protected function getServiceFromAnonymousFactoryService()
    {
        return $this->services['service_from_anonymous_factory'] = (new \Bar\FooClass())->getInstance();
    }

    /**
     * Gets the 'service_with_method_call_and_factory' service.
     *
     * This service is shared.
     * This method always returns the same instance of the service.
     *
     * @return \Bar\FooClass A Bar\FooClass instance
     */
    protected function getServiceWithMethodCallAndFactoryService()
    {
        $this->services['service_with_method_call_and_factory'] = $instance = new \Bar\FooClass();

        $instance->setBar(\Bar\FooClass::getInstance());

        return $instance;
    }
}
PKϤ$Z��666dependency-injection/Tests/Fixtures/php/services24.phpnu�[���<?php

use Symfony\Component\DependencyInjection\ContainerInterface;
use Symfony\Component\DependencyInjection\Container;
use Symfony\Component\DependencyInjection\Exception\InvalidArgumentException;
use Symfony\Component\DependencyInjection\Exception\LogicException;
use Symfony\Component\DependencyInjection\Exception\RuntimeException;
use Symfony\Component\DependencyInjection\ParameterBag\ParameterBag;

/**
 * ProjectServiceContainer.
 *
 * This class has been auto-generated
 * by the Symfony Dependency Injection Component.
 */
class ProjectServiceContainer extends Container
{
    private $parameters;
    private $targetDirs = array();

    /**
     * Constructor.
     */
    public function __construct()
    {
        parent::__construct();
        $this->methodMap = array(
            'foo' => 'getFooService',
        );
    }

    /**
     * Gets the 'foo' service.
     *
     * This service is autowired.
     *
     * @return \Foo A Foo instance
     */
    protected function getFooService()
    {
        return $this->services['foo'] = new \Foo();
    }
}
PKϤ$Z�\�%��5dependency-injection/Tests/Fixtures/php/services8.phpnu�[���<?php

use Symfony\Component\DependencyInjection\ContainerInterface;
use Symfony\Component\DependencyInjection\Container;
use Symfony\Component\DependencyInjection\Exception\InvalidArgumentException;
use Symfony\Component\DependencyInjection\Exception\LogicException;
use Symfony\Component\DependencyInjection\Exception\RuntimeException;
use Symfony\Component\DependencyInjection\ParameterBag\ParameterBag;

/**
 * ProjectServiceContainer.
 *
 * This class has been auto-generated
 * by the Symfony Dependency Injection Component.
 */
class ProjectServiceContainer extends Container
{
    private $parameters;
    private $targetDirs = array();

    /**
     * Constructor.
     */
    public function __construct()
    {
        parent::__construct(new ParameterBag($this->getDefaultParameters()));
    }

    /**
     * Gets the default parameters.
     *
     * @return array An array of the default parameters
     */
    protected function getDefaultParameters()
    {
        return array(
            'foo' => '%baz%',
            'baz' => 'bar',
            'bar' => 'foo is %%foo bar',
            'escape' => '@escapeme',
            'values' => array(
                0 => true,
                1 => false,
                2 => NULL,
                3 => 0,
                4 => 1000.3,
                5 => 'true',
                6 => 'false',
                7 => 'null',
            ),
        );
    }
}
PKϤ$Z�*�f��7dependency-injection/Tests/Fixtures/yaml/services22.ymlnu�[���services:
    foo_service:
        class:            FooClass
        autowiring_types: [ Foo, Bar ]

    baz_service:
        class:            Baz
        autowiring_types: Foo
PKϤ$Z�aV+;dependency-injection/Tests/Fixtures/yaml/bad_parameters.ymlnu�[���parameters:
    foo:bar
PKϤ$Zzb��nn4dependency-injection/Tests/Fixtures/yaml/badtag1.ymlnu�[���services:
    foo_service:
        class:    FooClass
        # tags is not an array
        tags:     string
PKϤ$ZZ�\6dependency-injection/Tests/Fixtures/yaml/services6.ymlnu�[���services:
    foo: { class: FooClass }
    baz: { class: BazClass }
    not_shared: { class: FooClass, shared: false }
    file: { class: FooClass, file: '%path%/foo.php' }
    arguments: { class: FooClass, arguments: [foo, '@foo', [true, false]] }
    configurator1: { class: FooClass, configurator: sc_configure }
    configurator2: { class: FooClass, configurator: ['@baz', configure] }
    configurator3: { class: FooClass, configurator: [BazClass, configureStatic] }
    method_call1:
        class: FooClass
        calls:
            - [ setBar, [] ]
            - [ setBar ]
            - [ setBar, ['@=service("foo").foo() ~ (container.hasParameter("foo") ? parameter("foo") : "default")'] ]
    method_call2:
        class: FooClass
        calls:
            - [ setBar, [ foo, '@foo', [true, false] ] ]
    alias_for_foo: '@foo'
    another_alias_for_foo:
        alias: foo
        public: false
    request:
        class: Request
        synthetic: true
        lazy: true
    another_third_alias_for_foo:
        alias: foo
    decorator_service:
        decorates: decorated
    decorator_service_with_name:
        decorates: decorated
        decoration_inner_name: decorated.pif-pouf
    decorator_service_with_name_and_priority:
        decorates: decorated
        decoration_inner_name: decorated.pif-pouf
        decoration_priority: 5
    new_factory1: { class: FooBarClass, factory: factory}
    new_factory2: { class: FooBarClass, factory: ['@baz', getClass]}
    new_factory3: { class: FooBarClass, factory: [BazClass, getInstance]}
PKϤ$Z�+�4AAFdependency-injection/Tests/Fixtures/yaml/legacy_invalid_definition.ymlnu�[���services:
    # This definition is valid and should not raise any deprecation notice
    foo:
        class: stdClass
        arguments: [ 'foo', 'bar' ]

    # This definition is invalid and must raise a deprecation notice
    bar:
        class: stdClass
        private: true        # the "private" keyword is invalid
PKϤ$Z�7{��6dependency-injection/Tests/Fixtures/yaml/services2.ymlnu�[���parameters:
    FOO: bar
    values:
        - true
        - false
        - 0
        - 1000.3
    bar: foo
    escape: '@@escapeme'
    foo_bar: '@foo_bar'
    MixedCase:
        MixedCaseKey: value
PKϤ$Z#�&#6dependency-injection/Tests/Fixtures/yaml/nonvalid1.ymlnu�[���foo:
  bar
PKϤ$Z���7dependency-injection/Tests/Fixtures/yaml/services10.ymlnu�[���parameters:
    project.parameter.foo: BAR

services:
    project.service.foo:
        class: BAR

project:
    test: '%project.parameter.foo%'
PKϤ$Z{��_��Bdependency-injection/Tests/Fixtures/yaml/tag_name_empty_string.ymlnu�[���services:
    foo_service:
        class:    FooClass
        tags:
          # tag name is an empty string
          - { name: '', foo: bar }
PKϤ$Z��MM7dependency-injection/Tests/Fixtures/yaml/services23.ymlnu�[���services:
    bar_service:
        class:    BarClass
        autowire: true
PKϤ$ZO_Q�7dependency-injection/Tests/Fixtures/yaml/bad_import.ymlnu�[���imports:
    - foo.yml
PKϤ$Z�OOLdependency-injection/Tests/Fixtures/yaml/legacy_invalid_alias_definition.ymlnu�[���services:
    foo:
        alias: bar
        factory: foo
        parent: quz
PKϤ$Z�l���:dependency-injection/Tests/Fixtures/yaml/bad_decorates.ymlnu�[���services:
    foo:
        class: stdClass
    bar:
        class: stdClass
        decorates: "@foo"
        arguments: ["@bar.inner"]
PKϤ$Zղ��==7dependency-injection/Tests/Fixtures/yaml/services21.ymlnu�[���services:
    manager:
        class: UserManager
        arguments:
          - true
        calls:
          - method: setLogger
            arguments:
              - '@logger'
          - method: setClass
            arguments:
              - User
        tags:
          - name: manager
            alias: user
PKϤ$Zy��??Adependency-injection/Tests/Fixtures/yaml/services4_bad_import.ymlnu�[���imports:
    - { resource: foo_fake.yml, ignore_errors: true }
PKϤ$Z}�>���4dependency-injection/Tests/Fixtures/yaml/badtag2.ymlnu�[���services:
    foo_service:
        class:    FooClass
        tags:
          # tag is missing the name key
          foo_tag:   { foo: bar }
PKϤ$Z����GG7dependency-injection/Tests/Fixtures/yaml/services13.ymlnu�[���# used to test imports in XML
parameters:
    imported_from_yaml: true
PKϤ$Z�[�zz7dependency-injection/Tests/Fixtures/yaml/bad_types1.ymlnu�[���services:
    foo_service:
        class:            FooClass
        # types is not an array
        autowiring_types: 1
PKϤ$ZW�%6dependency-injection/Tests/Fixtures/yaml/nonvalid2.ymlnu�[���false
PKϤ$Z3�Ĉ8dependency-injection/Tests/Fixtures/yaml/bad_imports.ymlnu�[���imports:
    foo:bar
PKϤ$Z�|��DD6dependency-injection/Tests/Fixtures/yaml/services3.ymlnu�[���parameters:
    foo: foo
    values:
        - true
        - false
PKϤ$ZV�v�==6dependency-injection/Tests/Fixtures/yaml/services4.ymlnu�[���imports:
    - { resource: services2.yml }
    - { resource: services3.yml }
    - { resource: "../php/simple.php" }
    - { resource: "../ini/parameters.ini", class: Symfony\Component\DependencyInjection\Loader\IniFileLoader }
    - { resource: "../ini/parameters2.ini" }
    - { resource: "../xml/services13.xml" }
PKϤ$ZW:���7dependency-injection/Tests/Fixtures/yaml/services14.ymlnu�[���services:
    factory: { class: FooBarClass, factory: baz:getClass}
    factory_with_static_call: { class: FooBarClass, factory: FooBacFactory::createFooBar}
PKϤ$Z#����6dependency-injection/Tests/Fixtures/yaml/services9.ymlnu�[���parameters:
    baz_class: BazClass
    foo_class: Bar\FooClass
    foo: bar

services:
    foo:
        class: Bar\FooClass
        tags:
            - { name: foo, foo: foo }
            - { name: foo, bar: bar, baz: baz }
        arguments: [foo, '@foo.baz', { '%foo%': 'foo is %foo%', foobar: '%foo%' }, true, '@service_container']
        properties: { foo: bar, moo: '@foo.baz', qux: { '%foo%': 'foo is %foo%', foobar: '%foo%' } }
        calls:
            - [setBar, ['@bar']]
            - [initialize, {  }]

        factory: [Bar\FooClass, getInstance]
        configurator: sc_configure
    foo.baz:
        class: '%baz_class%'
        factory: ['%baz_class%', getInstance]
        configurator: ['%baz_class%', configureStatic1]
    bar:
        class: Bar\FooClass
        arguments: [foo, '@foo.baz', '%foo_bar%']
        configurator: ['@foo.baz', configure]
    foo_bar:
        class: '%foo_class%'
        shared: false
    method_call1:
        class: Bar\FooClass
        file: '%path%foo.php'
        calls:
            - [setBar, ['@foo']]
            - [setBar, ['@?foo2']]
            - [setBar, ['@?foo3']]
            - [setBar, ['@?foobaz']]
            - [setBar, ['@=service("foo").foo() ~ (container.hasParameter("foo") ? parameter("foo") : "default")']]

    foo_with_inline:
        class: Foo
        calls:
            - [setBar, ['@inlined']]

    inlined:
        class: Bar
        public: false
        properties: { pub: pub }
        calls:
            - [setBaz, ['@baz']]

    baz:
        class: Baz
        calls:
            - [setFoo, ['@foo_with_inline']]

    request:
        class: Request
        synthetic: true
    configurator_service:
        class: ConfClass
        public: false
        calls:
            - [setFoo, ['@baz']]

    configured_service:
        class: stdClass
        configurator: ['@configurator_service', configureStdClass]
    configurator_service_simple:
        class: ConfClass
        public: false
        arguments: ['bar']
    configured_service_simple:
        class: stdClass
        configurator: ['@configurator_service_simple', configureStdClass]
    decorated:
        class: stdClass
    decorator_service:
        class: stdClass
        decorates: decorated
    decorator_service_with_name:
        class: stdClass
        decorates: decorated
        decoration_inner_name: decorated.pif-pouf
    deprecated_service:
        class: stdClass
        deprecated: The "%service_id%" service is deprecated. You should stop using it, as it will soon be removed.
    new_factory:
        class: FactoryClass
        public: false
        properties: { foo: bar }
    factory_service:
        class: Bar
        factory: ['@foo.baz', getInstance]
    new_factory_service:
        class: FooBarBaz
        properties: { foo: bar }
        factory: ['@new_factory', getInstance]
    service_from_static_method:
        class: Bar\FooClass
        factory: [Bar\FooClass, getInstance]
    factory_simple:
        class: SimpleFactoryClass
        public: false
        arguments: ['foo']
    factory_service_simple:
        class: Bar
        factory: ['@factory_simple', getInstance]
    alias_for_foo: '@foo'
    alias_for_alias: '@foo'
PKϤ$ZT4��GG6dependency-injection/Tests/Fixtures/yaml/bad_calls.ymlnu�[���services:
    method_call1:
        class: FooClass
        calls: foo
PKϤ$ZJ�Y��7dependency-injection/Tests/Fixtures/yaml/bad_types2.ymlnu�[���services:
    foo_service:
        class:            FooClass
        # autowiring_types is not a string
        autowiring_types: [ 1 ]
PKϤ$Z���{tt4dependency-injection/Tests/Fixtures/yaml/badtag4.ymlnu�[���services:
    foo_service:
        class:    FooClass
        tags:
          # tag is not an array
          - foo
PKϤ$Z��26dependency-injection/Tests/Fixtures/yaml/services1.ymlnu�[���
PKϤ$Z�*_6��4dependency-injection/Tests/Fixtures/yaml/badtag3.ymlnu�[���services:
    foo_service:
        class:    FooClass
        tags:
          # tag-attribute is not a scalar
          - { name: foo, bar: { foo: foo, bar: bar } }
PKϤ$Z��TD8dependency-injection/Tests/Fixtures/yaml/bad_service.ymlnu�[���services:
    foo: bar
PKϤ$ZFN�9dependency-injection/Tests/Fixtures/yaml/bad_services.ymlnu�[���services: foo
PKϤ$Z����6dependency-injection/Tests/Fixtures/yaml/services8.ymlnu�[���parameters:
    foo: '%baz%'
    baz: bar
    bar: 'foo is %%foo bar'
    escape: '@@escapeme'
    values: [true, false, null, 0, 1000.3, 'true', 'false', 'null']

PKϤ$Z����''6dependency-injection/Tests/Fixtures/yaml/services7.ymlnu�[���services:
    foo: { class: BarClass }
PKϤ$Z�MuA7dependency-injection/Tests/Fixtures/yaml/services11.ymlnu�[���foobarfoobar: {}
PKϤ$ZS�,��?dependency-injection/Tests/Fixtures/yaml/tag_name_no_string.ymlnu�[���services:
    foo_service:
        class:    FooClass
        tags:
          # tag name is not a string
          - { name: [], foo: bar }
PKϤ$Z�,p�7dependency-injection/Tests/Fixtures/yaml/bad_format.ymlnu�[���parameters:
	FOO: bar
PKϤ$Z�u�xx7dependency-injection/Tests/Fixtures/yaml/services24.ymlnu�[���
services:
    foo:
        class: Foo
        autowire: true
        autowiring_types:
            - A
            - B
PKϤ$Z5l%%7dependency-injection/Tests/Fixtures/ini/parameters1.ininu�[���[parameters]
  FOO = foo
  baz = baz
PKϤ$Z۴)�++4dependency-injection/Tests/Fixtures/ini/nonvalid.ininu�[���{NOT AN INI FILE}
{JUST A PLAIN TEXT FILE}
PKϤ$Zs4��''6dependency-injection/Tests/Fixtures/ini/parameters.ininu�[���[parameters]
  foo = bar
  bar = %foo%
PKϤ$Zpu��((7dependency-injection/Tests/Fixtures/ini/parameters2.ininu�[���[parameters]
  imported_from_ini = true
PKϤ$Z����8dependency-injection/Tests/Fixtures/CustomDefinition.phpnu�[���<?php

/*
 * This file is part of the Symfony package.
 *
 * (c) Fabien Potencier <fabien@symfony.com>
 *
 * For the full copyright and license information, please view the LICENSE
 * file that was distributed with this source code.
 */

namespace Symfony\Component\DependencyInjection\Tests\Fixtures;

use Symfony\Component\DependencyInjection\Definition;

class CustomDefinition extends Definition
{
}
PKϤ$Z�䪍qq8dependency-injection/Tests/Fixtures/includes/classes.phpnu�[���<?php

use Symfony\Component\DependencyInjection\Definition;
use Symfony\Component\DependencyInjection\LazyProxy\PhpDumper\DumperInterface as ProxyDumper;

function sc_configure($instance)
{
    $instance->configure();
}

class BarClass
{
    protected $baz;
    public $foo = 'foo';

    public function setBaz(BazClass $baz)
    {
        $this->baz = $baz;
    }

    public function getBaz()
    {
        return $this->baz;
    }
}

class BazClass
{
    protected $foo;

    public function setFoo(Foo $foo)
    {
        $this->foo = $foo;
    }

    public function configure($instance)
    {
        $instance->configure();
    }

    public static function getInstance()
    {
        return new self();
    }

    public static function configureStatic($instance)
    {
        $instance->configure();
    }

    public static function configureStatic1()
    {
    }
}

class BarUserClass
{
    public $bar;

    public function __construct(BarClass $bar)
    {
        $this->bar = $bar;
    }
}

class MethodCallClass
{
    public $simple;
    public $complex;
    private $callPassed = false;

    public function callMe()
    {
        $this->callPassed = is_scalar($this->simple) && is_object($this->complex);
    }

    public function callPassed()
    {
        return $this->callPassed;
    }
}

class DummyProxyDumper implements ProxyDumper
{
    public function isProxyCandidate(Definition $definition)
    {
        return false;
    }

    public function getProxyFactoryCode(Definition $definition, $id)
    {
        return '';
    }

    public function getProxyCode(Definition $definition)
    {
        return '';
    }
}
PKϤ$Z��[[Hdependency-injection/Tests/Fixtures/includes/ProjectWithXsdExtension.phpnu�[���<?php

class ProjectWithXsdExtension extends ProjectExtension
{
    public function getXsdValidationBasePath()
    {
        return __DIR__.'/schema';
    }

    public function getNamespace()
    {
        return 'http://www.example.com/schema/projectwithxsd';
    }

    public function getAlias()
    {
        return 'projectwithxsd';
    }
}
PKϤ$Z�J��Adependency-injection/Tests/Fixtures/includes/ProjectExtension.phpnu�[���<?php

use Symfony\Component\DependencyInjection\ContainerBuilder;
use Symfony\Component\DependencyInjection\Definition;
use Symfony\Component\DependencyInjection\Extension\ExtensionInterface;

class ProjectExtension implements ExtensionInterface
{
    public function load(array $configs, ContainerBuilder $configuration)
    {
        $config = call_user_func_array('array_merge', $configs);

        $configuration->setDefinition('project.service.bar', new Definition('FooClass'));
        $configuration->setParameter('project.parameter.bar', isset($config['foo']) ? $config['foo'] : 'foobar');

        $configuration->setDefinition('project.service.foo', new Definition('FooClass'));
        $configuration->setParameter('project.parameter.foo', isset($config['foo']) ? $config['foo'] : 'foobar');

        return $configuration;
    }

    public function getXsdValidationBasePath()
    {
        return false;
    }

    public function getNamespace()
    {
        return 'http://www.example.com/schema/project';
    }

    public function getAlias()
    {
        return 'project';
    }

    public function getConfiguration(array $config, ContainerBuilder $container)
    {
    }
}
PKϤ$ZRK:��Cdependency-injection/Tests/Fixtures/includes/schema/project-1.0.xsdnu�[���<?xml version="1.0" encoding="UTF-8" ?>

<xsd:schema xmlns="http://www.example.com/schema/projectwithxsd"
    xmlns:xsd="http://www.w3.org/2001/XMLSchema"
    targetNamespace="http://www.example.com/schema/projectwithxsd"
    elementFormDefault="qualified">

  <xsd:element name="bar" type="bar" />

  <xsd:complexType name="bar">
    <xsd:attribute name="foo" type="xsd:string" />
  </xsd:complexType>
</xsd:schema>
PKϤ$Z�mX;dependency-injection/Tests/Fixtures/includes/createphar.phpnu�[���<?php

$file = __DIR__.'/ProjectWithXsdExtensionInPhar.phar';
if (is_file($file)) {
    @unlink($file);
}

$phar = new Phar($file, 0, 'ProjectWithXsdExtensionInPhar.phar');
$phar->addFromString('ProjectWithXsdExtensionInPhar.php', <<<'EOT'
<?php

class ProjectWithXsdExtensionInPhar extends ProjectExtension
{
    public function getXsdValidationBasePath()
    {
        return __DIR__.'/schema';
    }

    public function getNamespace()
    {
        return 'http://www.example.com/schema/projectwithxsdinphar';
    }

    public function getAlias()
    {
        return 'projectwithxsdinphar';
    }
}
EOT
);
$phar->addFromString('schema/project-1.0.xsd', <<<'EOT'
<?xml version="1.0" encoding="UTF-8" ?>

<xsd:schema xmlns="http://www.example.com/schema/projectwithxsdinphar"
    xmlns:xsd="http://www.w3.org/2001/XMLSchema"
    targetNamespace="http://www.example.com/schema/projectwithxsdinphar"
    elementFormDefault="qualified">

  <xsd:element name="bar" type="bar" />

  <xsd:complexType name="bar">
    <xsd:attribute name="foo" type="xsd:string" />
  </xsd:complexType>
</xsd:schema>
EOT
);
$phar->setStub('<?php Phar::mapPhar("ProjectWithXsdExtensionInPhar.phar"); require_once "phar://ProjectWithXsdExtensionInPhar.phar/ProjectWithXsdExtensionInPhar.php"; __HALT_COMPILER(); ?>');
PKϤ$Z6xB ��4dependency-injection/Tests/Fixtures/includes/foo.phpnu�[���<?php

namespace Bar;

class FooClass
{
    public $foo;
    public $moo;

    public $bar = null;
    public $initialized = false;
    public $configured = false;
    public $called = false;
    public $arguments = array();

    public function __construct($arguments = array())
    {
        $this->arguments = $arguments;
    }

    public static function getInstance($arguments = array())
    {
        $obj = new self($arguments);
        $obj->called = true;

        return $obj;
    }

    public function initialize()
    {
        $this->initialized = true;
    }

    public function configure()
    {
        $this->configured = true;
    }

    public function setBar($value = null)
    {
        $this->bar = $value;
    }
}
PKϤ$ZS�x<dependency-injection/Tests/Fixtures/includes/FooVariadic.phpnu�[���<?php

namespace Symfony\Component\DependencyInjection\Tests\Fixtures\includes;

use Symfony\Component\DependencyInjection\Tests\Compiler\Foo;

class FooVariadic
{
    public function __construct(Foo $foo)
    {
    }

    public function bar(...$arguments)
    {
    }
}
PKϤ$Zv�a���Odependency-injection/Tests/Fixtures/includes/ProjectWithXsdExtensionInPhar.pharnu�[���<?php Phar::mapPhar("ProjectWithXsdExtensionInPhar.phar"); require_once "phar://ProjectWithXsdExtensionInPhar.phar/ProjectWithXsdExtensionInPhar.php"; __HALT_COMPILER(); ?>
�"ProjectWithXsdExtensionInPhar.phar!ProjectWithXsdExtensionInPhar.phplT�Ul�WѶschema/project-1.0.xsd�T�U�rr���<?php

class ProjectWithXsdExtensionInPhar extends ProjectExtension
{
    public function getXsdValidationBasePath()
    {
        return __DIR__.'/schema';
    }

    public function getNamespace()
    {
        return 'http://www.example.com/schema/projectwithxsdinphar';
    }

    public function getAlias()
    {
        return 'projectwithxsdinphar';
    }
}<?xml version="1.0" encoding="UTF-8" ?>

<xsd:schema xmlns="http://www.example.com/schema/projectwithxsdinphar"
    xmlns:xsd="http://www.w3.org/2001/XMLSchema"
    targetNamespace="http://www.example.com/schema/projectwithxsdinphar"
    elementFormDefault="qualified">

  <xsd:element name="bar" type="bar" />

  <xsd:complexType name="bar">
    <xsd:attribute name="foo" type="xsd:string" />
  </xsd:complexType>
</xsd:schema>�|���M*c�(�.�k&`�GBMBPKϤ$Zv�&��:dependency-injection/Tests/Fixtures/graphviz/services9.dotnu�[���digraph sc {
  ratio="compress"
  node [fontsize="11" fontname="Arial" shape="record"];
  edge [fontsize="9" fontname="Arial" color="grey" arrowhead="open" arrowsize="0.5"];

  node_foo [label="foo (alias_for_foo)\nBar\\FooClass\n", shape=record, fillcolor="#eeeeee", style="filled"];
  node_foo_baz [label="foo.baz\nBazClass\n", shape=record, fillcolor="#eeeeee", style="filled"];
  node_bar [label="bar\nBar\\FooClass\n", shape=record, fillcolor="#eeeeee", style="filled"];
  node_foo_bar [label="foo_bar\nBar\\FooClass\n", shape=record, fillcolor="#eeeeee", style="dotted"];
  node_method_call1 [label="method_call1\nBar\\FooClass\n", shape=record, fillcolor="#eeeeee", style="filled"];
  node_foo_with_inline [label="foo_with_inline\nFoo\n", shape=record, fillcolor="#eeeeee", style="filled"];
  node_inlined [label="inlined\nBar\n", shape=record, fillcolor="#eeeeee", style="filled"];
  node_baz [label="baz\nBaz\n", shape=record, fillcolor="#eeeeee", style="filled"];
  node_request [label="request\nRequest\n", shape=record, fillcolor="#eeeeee", style="filled"];
  node_configurator_service [label="configurator_service\nConfClass\n", shape=record, fillcolor="#eeeeee", style="filled"];
  node_configured_service [label="configured_service\nstdClass\n", shape=record, fillcolor="#eeeeee", style="filled"];
  node_configurator_service_simple [label="configurator_service_simple\nConfClass\n", shape=record, fillcolor="#eeeeee", style="filled"];
  node_configured_service_simple [label="configured_service_simple\nstdClass\n", shape=record, fillcolor="#eeeeee", style="filled"];
  node_decorated [label="decorated\nstdClass\n", shape=record, fillcolor="#eeeeee", style="filled"];
  node_decorator_service [label="decorator_service\nstdClass\n", shape=record, fillcolor="#eeeeee", style="filled"];
  node_decorator_service_with_name [label="decorator_service_with_name\nstdClass\n", shape=record, fillcolor="#eeeeee", style="filled"];
  node_deprecated_service [label="deprecated_service\nstdClass\n", shape=record, fillcolor="#eeeeee", style="filled"];
  node_new_factory [label="new_factory\nFactoryClass\n", shape=record, fillcolor="#eeeeee", style="filled"];
  node_factory_service [label="factory_service\nBar\n", shape=record, fillcolor="#eeeeee", style="filled"];
  node_new_factory_service [label="new_factory_service\nFooBarBaz\n", shape=record, fillcolor="#eeeeee", style="filled"];
  node_service_from_static_method [label="service_from_static_method\nBar\\FooClass\n", shape=record, fillcolor="#eeeeee", style="filled"];
  node_factory_simple [label="factory_simple\nSimpleFactoryClass\n", shape=record, fillcolor="#eeeeee", style="filled"];
  node_factory_service_simple [label="factory_service_simple\nBar\n", shape=record, fillcolor="#eeeeee", style="filled"];
  node_service_container [label="service_container\nSymfony\\Component\\DependencyInjection\\ContainerBuilder\n", shape=record, fillcolor="#9999ff", style="filled"];
  node_foo2 [label="foo2\n\n", shape=record, fillcolor="#ff9999", style="filled"];
  node_foo3 [label="foo3\n\n", shape=record, fillcolor="#ff9999", style="filled"];
  node_foobaz [label="foobaz\n\n", shape=record, fillcolor="#ff9999", style="filled"];
  node_foo -> node_foo_baz [label="" style="filled"];
  node_foo -> node_service_container [label="" style="filled"];
  node_foo -> node_foo_baz [label="" style="dashed"];
  node_foo -> node_bar [label="setBar()" style="dashed"];
  node_bar -> node_foo_baz [label="" style="filled"];
  node_method_call1 -> node_foo [label="setBar()" style="dashed"];
  node_method_call1 -> node_foo2 [label="setBar()" style="dashed"];
  node_method_call1 -> node_foo3 [label="setBar()" style="dashed"];
  node_method_call1 -> node_foobaz [label="setBar()" style="dashed"];
  node_foo_with_inline -> node_inlined [label="setBar()" style="dashed"];
  node_inlined -> node_baz [label="setBaz()" style="dashed"];
  node_baz -> node_foo_with_inline [label="setFoo()" style="dashed"];
  node_configurator_service -> node_baz [label="setFoo()" style="dashed"];
}
PKϤ$Z�����;dependency-injection/Tests/Fixtures/graphviz/services18.dotnu�[���digraph sc {
  ratio="compress"
  node [fontsize="11" fontname="Arial" shape="record"];
  edge [fontsize="9" fontname="Arial" color="grey" arrowhead="open" arrowsize="0.5"];

  node_foo [label="foo\nFooClass\n", shape=record, fillcolor="#eeeeee", style="filled"];
  node_service_container [label="service_container\nSymfony\\Component\\DependencyInjection\\ContainerBuilder\n", shape=record, fillcolor="#9999ff", style="filled"];
}
PKϤ$ZŏD�;;;dependency-injection/Tests/Fixtures/graphviz/services13.dotnu�[���digraph sc {
  ratio="compress"
  node [fontsize="11" fontname="Arial" shape="record"];
  edge [fontsize="9" fontname="Arial" color="grey" arrowhead="open" arrowsize="0.5"];

  node_foo [label="foo\nFooClass\n", shape=record, fillcolor="#eeeeee", style="filled"];
  node_bar [label="bar\nBarClass\n", shape=record, fillcolor="#eeeeee", style="filled"];
  node_service_container [label="service_container\nSymfony\\Component\\DependencyInjection\\ContainerBuilder\n", shape=record, fillcolor="#9999ff", style="filled"];
  node_foo -> node_bar [label="" style="filled"];
}
PKϤ$ZՁ1*,,=dependency-injection/Tests/Fixtures/graphviz/services10-1.dotnu�[���digraph sc {
  ratio="normal"
  node [fontsize="13" fontname="Verdana" shape="square"];
  edge [fontsize="12" fontname="Verdana" color="white" arrowhead="closed" arrowsize="1"];

  node_foo [label="foo\nFooClass\n", shape=square, fillcolor="grey", style="filled"];
  node_service_container [label="service_container\nSymfony\\Component\\DependencyInjection\\ContainerBuilder\n", shape=square, fillcolor="green", style="empty"];
  node_bar [label="bar\n\n", shape=square, fillcolor="red", style="empty"];
  node_foo -> node_bar [label="" style="filled"];
}
PKϤ$Z��8BB;dependency-injection/Tests/Fixtures/graphviz/services14.dotnu�[���digraph sc {
  ratio="compress"
  node [fontsize="11" fontname="Arial" shape="record"];
  edge [fontsize="9" fontname="Arial" color="grey" arrowhead="open" arrowsize="0.5"];

  node_service_container [label="service_container\nContainer14\\ProjectServiceContainer\n", shape=record, fillcolor="#9999ff", style="filled"];
}
PKϤ$Z&�WW:dependency-injection/Tests/Fixtures/graphviz/services1.dotnu�[���digraph sc {
  ratio="compress"
  node [fontsize="11" fontname="Arial" shape="record"];
  edge [fontsize="9" fontname="Arial" color="grey" arrowhead="open" arrowsize="0.5"];

  node_service_container [label="service_container\nSymfony\\Component\\DependencyInjection\\ContainerBuilder\n", shape=record, fillcolor="#9999ff", style="filled"];
}
PKϤ$Z�cw��;dependency-injection/Tests/Fixtures/graphviz/services17.dotnu�[���digraph sc {
  ratio="compress"
  node [fontsize="11" fontname="Arial" shape="record"];
  edge [fontsize="9" fontname="Arial" color="grey" arrowhead="open" arrowsize="0.5"];

  node_foo [label="foo\n%foo.class%\n", shape=record, fillcolor="#eeeeee", style="filled"];
  node_service_container [label="service_container\nSymfony\\Component\\DependencyInjection\\ContainerBuilder\n", shape=record, fillcolor="#9999ff", style="filled"];
}
PKϤ$Z��33;dependency-injection/Tests/Fixtures/graphviz/services10.dotnu�[���digraph sc {
  ratio="compress"
  node [fontsize="11" fontname="Arial" shape="record"];
  edge [fontsize="9" fontname="Arial" color="grey" arrowhead="open" arrowsize="0.5"];

  node_foo [label="foo\nFooClass\n", shape=record, fillcolor="#eeeeee", style="filled"];
  node_service_container [label="service_container\nSymfony\\Component\\DependencyInjection\\ContainerBuilder\n", shape=record, fillcolor="#9999ff", style="filled"];
  node_bar [label="bar\n\n", shape=record, fillcolor="#ff9999", style="filled"];
  node_foo -> node_bar [label="" style="filled"];
}
PKϤ$ZLC8O��5dependency-injection/Tests/Fixtures/xml/services2.xmlnu�[���<?xml version="1.0" ?>

<container xmlns="http://symfony.com/schema/dic/services"
    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    xsi:schemaLocation="http://symfony.com/schema/dic/services http://symfony.com/schema/dic/services/services-1.0.xsd">
  <parameters>
    <parameter>a string</parameter>
    <parameter key="FOO">bar</parameter>
    <parameter key="values" type="collection">
      <parameter>0</parameter>
      <parameter key="integer">4</parameter>
      <parameter key="100">null</parameter>
      <parameter type="string">true</parameter>
      <parameter>true</parameter>
      <parameter>false</parameter>
      <parameter>on</parameter>
      <parameter>off</parameter>
      <parameter key="float">1.3</parameter>
      <parameter>1000.3</parameter>
      <parameter>a string</parameter>
      <parameter type="collection">
        <parameter>foo</parameter>
        <parameter>bar</parameter>
      </parameter>
    </parameter>
    <parameter key="MixedCase" type="collection"> <!-- Should be lower cased -->
      <parameter key="MixedCaseKey">value</parameter> <!-- Should stay mixed case -->
    </parameter>
    <parameter key="constant" type="constant">PHP_EOL</parameter>
  </parameters>
</container>
PKϤ$Z˕n%%4dependency-injection/Tests/Fixtures/xml/nonvalid.xmlnu�[���<?xml version="1.0" ?>

<nonvalid />
PKϤ$ZͶZD��?dependency-injection/Tests/Fixtures/xml/tag_with_empty_name.xmlnu�[���<?xml version="1.0" ?>
<container xmlns="http://symfony.com/schema/dic/services"
    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    xsi:schemaLocation="http://symfony.com/schema/dic/services http://symfony.com/schema/dic/services/services-1.0.xsd">

    <services>
        <service id="foo" class="BarClass">
            <tag name="" foo="bar" />
        </service>
    </services>
</container>
PKϤ$Z���5dependency-injection/Tests/Fixtures/xml/services9.xmlnu�[���<?xml version="1.0" encoding="utf-8"?>
<container xmlns="http://symfony.com/schema/dic/services" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://symfony.com/schema/dic/services http://symfony.com/schema/dic/services/services-1.0.xsd">
  <parameters>
    <parameter key="baz_class">BazClass</parameter>
    <parameter key="foo_class">Bar\FooClass</parameter>
    <parameter key="foo">bar</parameter>
  </parameters>
  <services>
    <service id="foo" class="Bar\FooClass">
      <tag name="foo" foo="foo"/>
      <tag name="foo" bar="bar" baz="baz"/>
      <argument>foo</argument>
      <argument type="service" id="foo.baz"/>
      <argument type="collection">
        <argument key="%foo%">foo is %foo%</argument>
        <argument key="foobar">%foo%</argument>
      </argument>
      <argument>true</argument>
      <argument type="service" id="service_container"/>
      <property name="foo">bar</property>
      <property name="moo" type="service" id="foo.baz"/>
      <property name="qux" type="collection">
        <property key="%foo%">foo is %foo%</property>
        <property key="foobar">%foo%</property>
      </property>
      <call method="setBar">
        <argument type="service" id="bar"/>
      </call>
      <call method="initialize"/>
      <factory class="Bar\FooClass" method="getInstance"/>
      <configurator function="sc_configure"/>
    </service>
    <service id="foo.baz" class="%baz_class%">
      <factory class="%baz_class%" method="getInstance"/>
      <configurator class="%baz_class%" method="configureStatic1"/>
    </service>
    <service id="bar" class="Bar\FooClass">
      <argument>foo</argument>
      <argument type="service" id="foo.baz"/>
      <argument>%foo_bar%</argument>
      <configurator service="foo.baz" method="configure"/>
    </service>
    <service id="foo_bar" class="%foo_class%" shared="false"/>
    <service id="method_call1" class="Bar\FooClass">
      <file>%path%foo.php</file>
      <call method="setBar">
        <argument type="service" id="foo"/>
      </call>
      <call method="setBar">
        <argument type="service" id="foo2" on-invalid="null"/>
      </call>
      <call method="setBar">
        <argument type="service" id="foo3" on-invalid="ignore"/>
      </call>
      <call method="setBar">
        <argument type="service" id="foobaz" on-invalid="ignore"/>
      </call>
      <call method="setBar">
        <argument type="expression">service("foo").foo() ~ (container.hasParameter("foo") ? parameter("foo") : "default")</argument>
      </call>
    </service>
    <service id="foo_with_inline" class="Foo">
      <call method="setBar">
        <argument type="service" id="inlined"/>
      </call>
    </service>
    <service id="inlined" class="Bar" public="false">
      <property name="pub">pub</property>
      <call method="setBaz">
        <argument type="service" id="baz"/>
      </call>
    </service>
    <service id="baz" class="Baz">
      <call method="setFoo">
        <argument type="service" id="foo_with_inline"/>
      </call>
    </service>
    <service id="request" class="Request" synthetic="true"/>
    <service id="configurator_service" class="ConfClass" public="false">
      <call method="setFoo">
        <argument type="service" id="baz"/>
      </call>
    </service>
    <service id="configured_service" class="stdClass">
      <configurator service="configurator_service" method="configureStdClass"/>
    </service>
    <service id="configurator_service_simple" class="ConfClass" public="false">
      <argument>bar</argument>
    </service>
    <service id="configured_service_simple" class="stdClass">
      <configurator service="configurator_service_simple" method="configureStdClass"/>
    </service>
    <service id="decorated" class="stdClass"/>
    <service id="decorator_service" class="stdClass" decorates="decorated"/>
    <service id="decorator_service_with_name" class="stdClass" decorates="decorated" decoration-inner-name="decorated.pif-pouf"/>
    <service id="deprecated_service" class="stdClass">
      <deprecated>The "%service_id%" service is deprecated. You should stop using it, as it will soon be removed.</deprecated>
    </service>
    <service id="new_factory" class="FactoryClass" public="false">
      <property name="foo">bar</property>
    </service>
    <service id="factory_service" class="Bar">
      <factory service="foo.baz" method="getInstance"/>
    </service>
    <service id="new_factory_service" class="FooBarBaz">
      <property name="foo">bar</property>
      <factory service="new_factory" method="getInstance"/>
    </service>
    <service id="service_from_static_method" class="Bar\FooClass">
      <factory class="Bar\FooClass" method="getInstance"/>
    </service>
    <service id="factory_simple" class="SimpleFactoryClass" public="false">
      <argument>foo</argument>
    </service>
    <service id="factory_service_simple" class="Bar">
      <factory service="factory_simple" method="getInstance"/>
    </service>
    <service id="alias_for_foo" alias="foo"/>
    <service id="alias_for_alias" alias="foo"/>
  </services>
</container>
PKϤ$Z]2�
��?dependency-injection/Tests/Fixtures/xml/extension2/services.xmlnu�[���<?xml version="1.0" ?>

<container xmlns="http://symfony.com/schema/dic/services"
    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    xsi:schemaLocation="http://symfony.com/schema/dic/services http://symfony.com/schema/dic/services/services-1.0.xsd">
  <services>
    <service id="extension2.foo" class="FooClass2">
      <argument type="service">
        <service class="BarClass2">
        </service>
      </argument>
    </service>
  </services>
</container>
PKϤ$Z��Uگ�Gdependency-injection/Tests/Fixtures/xml/with_key_outside_collection.xmlnu�[���<?xml version="1.0" encoding="utf-8"?>
<container xmlns="http://symfony.com/schema/dic/services" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://symfony.com/schema/dic/services http://symfony.com/schema/dic/services/services-1.0.xsd">
  <services>
    <service id="foo" class="Foo">
      <argument key="type">foo</argument>
      <argument>bar</argument>
    </service>
  </services>
</container>
PKϤ$Z\����6dependency-injection/Tests/Fixtures/xml/services24.xmlnu�[���<?xml version="1.0" encoding="utf-8"?>
<container xmlns="http://symfony.com/schema/dic/services" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://symfony.com/schema/dic/services http://symfony.com/schema/dic/services/services-1.0.xsd">
  <services>
    <service id="foo" class="Foo" autowire="true">
      <autowiring-type>A</autowiring-type>
      <autowiring-type>B</autowiring-type>
    </service>
  </services>
</container>
PKϤ$Z�Z	[[6dependency-injection/Tests/Fixtures/xml/services14.xmlnu�[���<?xml version="1.0" encoding="utf-8"?>
<container xmlns="http://symfony.com/schema/dic/services"
           xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
           xsi:schemaLocation="http://symfony.com/schema/dic/services http://symfony.com/schema/dic/services/services-1.0.xsd">
    <services>
        <service id="monolog.logger" parent="monolog.logger_prototype" public="false">
            <argument index="0">app</argument>
        </service>

        <service id="logger" alias="monolog.logger" />

        <service id="monolog.logger" parent="monolog.logger_prototype" public="false">
            <argument index="0">app</argument>
        </service>
        <service id="monolog.logger_prototype" class="Symfony\Bridge\Monolog\Logger" abstract="true">
            <argument /><!-- Channel -->
        </service>
    </services>
</container>
PKϤ$Z2�X8��?dependency-injection/Tests/Fixtures/xml/services_deprecated.xmlnu�[���<?xml version="1.0" encoding="utf-8"?>
<container xmlns="http://symfony.com/schema/dic/services" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://symfony.com/schema/dic/services http://symfony.com/schema/dic/services/services-1.0.xsd">
  <services>
    <service id="foo" class="Foo">
      <deprecated />
    </service>
    <service id="bar" class="Bar">
      <deprecated>The "%service_id%" service is deprecated.</deprecated>
    </service>
  </services>
</container>
PKϤ$Z*��5dependency-injection/Tests/Fixtures/xml/services5.xmlnu�[���<?xml version="1.0" ?>

<container xmlns="http://symfony.com/schema/dic/services"
    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    xsi:schemaLocation="http://symfony.com/schema/dic/services http://symfony.com/schema/dic/services/services-1.0.xsd">
  <services>
    <service id="foo" class="FooClass">
      <argument type="service">
        <service class="BarClass">
          <argument type="service">
            <service class="BazClass">
            </service>
          </argument>
        </service>
      </argument>
      <property name="p" type="service">
        <service class="BuzClass" />
      </property>
    </service>
    <service id="bar" parent="foo" />
    <service class="BizClass">
        <tag name="biz_tag" />
    </service>
  </services>
</container>
PKϤ$Z�![�6dependency-injection/Tests/Fixtures/xml/services10.xmlnu�[���<?xml version="1.0" ?>

<container xmlns="http://symfony.com/schema/dic/services"
    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    xsi:schemaLocation="http://symfony.com/schema/dic/services http://symfony.com/schema/dic/services/services-1.0.xsd">
  <services>
    <service id="foo" class="BarClass">
        <tag name="foo_tag"
            some-option="cat"
            some_option="ciz"
            other-option="lorem"
            an_other-option="ipsum"
        />
    </service>
  </services>
</container>
PKϤ$Z���<ii6dependency-injection/Tests/Fixtures/xml/services13.xmlnu�[���<?xml version="1.0" ?>

<container xmlns="http://symfony.com/schema/dic/services"
    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    xsi:schemaLocation="http://symfony.com/schema/dic/services http://symfony.com/schema/dic/services/services-1.0.xsd">
  <parameters>
    <parameter key="imported_from_xml">true</parameter>
  </parameters>
</container>
PKϤ$Zx'�	117dependency-injection/Tests/Fixtures/xml/withdoctype.xmlnu�[���<?xml version="1.0"?>
<!DOCTYPE foo>
<foo></foo>
PKϤ$Zu�

5dependency-injection/Tests/Fixtures/xml/services4.xmlnu�[���<?xml version="1.0" ?>

<container xmlns="http://symfony.com/schema/dic/services"
    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    xsi:schemaLocation="http://symfony.com/schema/dic/services http://symfony.com/schema/dic/services/services-1.0.xsd">
  <imports>
    <import resource="services2.xml" />
    <import resource="services3.xml" />
    <import resource="../ini/parameters.ini" />
    <import resource="../ini/parameters2.ini" />
    <import resource="../yaml/services13.yml" />
  </imports>
</container>
PKϤ$Z�e<xx5dependency-injection/Tests/Fixtures/xml/services8.xmlnu�[���<?xml version="1.0" encoding="utf-8"?>

<container xmlns="http://symfony.com/schema/dic/services"
    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    xsi:schemaLocation="http://symfony.com/schema/dic/services http://symfony.com/schema/dic/services/services-1.0.xsd">
  <parameters>
    <parameter key="foo">%baz%</parameter>
    <parameter key="baz">bar</parameter>
    <parameter key="bar">foo is %%foo bar</parameter>
    <parameter key="escape">@escapeme</parameter>
    <parameter key="values" type="collection">
      <parameter>true</parameter>
      <parameter>false</parameter>
      <parameter>null</parameter>
      <parameter>0</parameter>
      <parameter>1000.3</parameter>
      <parameter type="string">true</parameter>
      <parameter type="string">false</parameter>
      <parameter type="string">null</parameter>
    </parameter>
  </parameters>
</container>
PKϤ$Z
�T`��6dependency-injection/Tests/Fixtures/xml/services22.xmlnu�[���<?xml version="1.0" encoding="utf-8"?>
<container xmlns="http://symfony.com/schema/dic/services" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://symfony.com/schema/dic/services http://symfony.com/schema/dic/services/services-1.0.xsd">
    <services>
        <service id="foo" class="Foo">
            <autowiring-type>Bar</autowiring-type>
            <autowiring-type>Baz</autowiring-type>
        </service>
    </services>
</container>
PKϤ$Zq����6dependency-injection/Tests/Fixtures/xml/namespaces.xmlnu�[���<?xml version="1.0" ?>

<srv:container xmlns="http://symfony.com/schema/dic/doctrine"
    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    xmlns:srv="http://symfony.com/schema/dic/services"
    xsi:schemaLocation="http://symfony.com/schema/dic/services http://symfony.com/schema/dic/services/services-1.0.xsd
                        http://symfony.com/schema/dic/doctrine http://symfony.com/schema/dic/doctrine/doctrine-1.0.xsd">

    <srv:services>
        <srv:service id="foo" class="FooClass">
            <srv:tag name="foo.tag" />
            <srv:call method="setBar">
                <srv:argument>foo</srv:argument>
            </srv:call>
        </srv:service>
    </srv:services>
</srv:container>
PKϤ$Z6�S��<dependency-injection/Tests/Fixtures/xml/tag_without_name.xmlnu�[���<?xml version="1.0" ?>
<container xmlns="http://symfony.com/schema/dic/services"
    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    xsi:schemaLocation="http://symfony.com/schema/dic/services http://symfony.com/schema/dic/services/services-1.0.xsd">

    <services>
        <service id="foo" class="BarClass">
            <tag foo="bar" />
        </service>
    </services>
</container>
PKϤ$Z����6dependency-injection/Tests/Fixtures/xml/services21.xmlnu�[���<?xml version="1.0" encoding="utf-8"?>
<container xmlns="http://symfony.com/schema/dic/services" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://symfony.com/schema/dic/services http://symfony.com/schema/dic/services/services-1.0.xsd">
  <services>
    <service id="foo" class="Foo">
      <factory method="createFoo">
        <service class="FooFactory">
          <factory method="createFooFactory">
            <service class="Foobar"/>
          </factory>
        </service>
      </factory>
      <configurator method="configureFoo">
        <service class="Bar">
          <configurator method="configureBar">
            <service class="Baz"/>
          </configurator>
        </service>
      </configurator>
    </service>
  </services>
</container>
PKϤ$Z�}��@dependency-injection/Tests/Fixtures/xml/extensions/services2.xmlnu�[���<?xml version="1.0" ?>

<container xmlns="http://symfony.com/schema/dic/services"
    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    xmlns:project="http://www.example.com/schema/projectwithxsd"
    xsi:schemaLocation="http://symfony.com/schema/dic/services http://symfony.com/schema/dic/services/services-1.0.xsd
                        http://www.example.com/schema/projectwithxsd http://www.example.com/schema/projectwithxsd/project-1.0.xsd">

    <parameters>
        <parameter key="project.parameter.foo">BAR</parameter>
    </parameters>

    <services>
        <service id="project.service.foo" class="BAR" />
    </services>

    <project:bar />

</container>
PKϤ$ZŃ����@dependency-injection/Tests/Fixtures/xml/extensions/services5.xmlnu�[���<?xml version="1.0" ?>

<container xmlns="http://symfony.com/schema/dic/services"
    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    xmlns:project="http://www.example.com/schema/projectwithxsd"
    xsi:schemaLocation="http://symfony.com/schema/dic/services http://symfony.com/schema/dic/services/services-1.0.xsd
                        http://www.example.com/schema/projectwithxsd http://www.example.com/schema/projectwithxsd/project-1.0.xsd">

    <project:foobar />

</container>
PKϤ$Zҗ'y��@dependency-injection/Tests/Fixtures/xml/extensions/services4.xmlnu�[���<?xml version="1.0" ?>

<container xmlns="http://symfony.com/schema/dic/services"
    xmlns:project="http://www.example.com/schema/not_registered_extension">
  <project:bar />
</container>
PKϤ$Z>U���@dependency-injection/Tests/Fixtures/xml/extensions/services3.xmlnu�[���<?xml version="1.0" ?>

<container xmlns="http://symfony.com/schema/dic/services"
    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    xmlns:project="http://www.example.com/schema/projectwithxsd"
    xsi:schemaLocation="http://symfony.com/schema/dic/services http://symfony.com/schema/dic/services/services-1.0.xsd
                        http://www.example.com/schema/projectwithxsd http://www.example.com/schema/projectwithxsd/project-1.0.xsd">

    <parameters>
        <parameter key="project.parameter.foo">BAR</parameter>
    </parameters>

    <services>
        <service id="project.service.foo" class="BAR" />
    </services>

    <project:bar bar="bar" />

</container>
PKϤ$Z��	@dependency-injection/Tests/Fixtures/xml/extensions/services7.xmlnu�[���<?xml version="1.0" ?>

<container xmlns="http://symfony.com/schema/dic/services"
    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    xmlns:project="http://www.example.com/schema/projectwithxsdinphar"
    xsi:schemaLocation="http://symfony.com/schema/dic/services http://symfony.com/schema/dic/services/services-1.0.xsd
                        http://www.example.com/schema/projectwithxsdinphar http://www.example.com/schema/projectwithxsdinphar/project-1.0.xsd">

    <project:bar bar="foo" />

</container>
PKϤ$Z�^����@dependency-injection/Tests/Fixtures/xml/extensions/services1.xmlnu�[���<?xml version="1.0" ?>

<container xmlns="http://symfony.com/schema/dic/services"
    xmlns:project="http://www.example.com/schema/project">

    <parameters>
        <parameter key="project.parameter.foo">BAR</parameter>
    </parameters>

    <services>
        <service id="project.service.foo" class="BAR" />
    </services>

    <project:bar babar="babar">
        <another />
        <another2>%project.parameter.foo%</another2>
    </project:bar>

</container>
PKϤ$Zix�C��@dependency-injection/Tests/Fixtures/xml/extensions/services6.xmlnu�[���<?xml version="1.0" ?>

<container xmlns="http://symfony.com/schema/dic/services"
    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    xmlns:project="http://www.example.com/schema/projectwithxsdinphar"
    xsi:schemaLocation="http://symfony.com/schema/dic/services http://symfony.com/schema/dic/services/services-1.0.xsd
                        http://www.example.com/schema/projectwithxsdinphar http://www.example.com/schema/projectwithxsdinphar/project-1.0.xsd">

    <project:bar />

</container>
PKϤ$Z��Pgg@dependency-injection/Tests/Fixtures/xml/services4_bad_import.xmlnu�[���<?xml version="1.0" ?>

<container xmlns="http://symfony.com/schema/dic/services"
    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    xsi:schemaLocation="http://symfony.com/schema/dic/services http://symfony.com/schema/dic/services/services-1.0.xsd">
  <imports>
    <import resource="foo_fake.xml" ignore-errors="true" />
  </imports>
</container>
PKϤ$Z
��qq6dependency-injection/Tests/Fixtures/xml/services23.xmlnu�[���<?xml version="1.0" encoding="utf-8"?>
<container xmlns="http://symfony.com/schema/dic/services" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://symfony.com/schema/dic/services http://symfony.com/schema/dic/services/services-1.0.xsd">
    <services>
        <service id="bar" class="Bar" autowire="true" />
    </services>
</container>
PKϤ$Z\_���5dependency-injection/Tests/Fixtures/xml/services3.xmlnu�[���<?xml version="1.0" ?>

<container xmlns="http://symfony.com/schema/dic/services"
    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    xsi:schemaLocation="http://symfony.com/schema/dic/services http://symfony.com/schema/dic/services/services-1.0.xsd">
  <parameters>
    <parameter key="foo">foo</parameter>
    <parameter key="values" type="collection">
      <parameter>true</parameter>
      <parameter>false</parameter>
    </parameter>
  </parameters>
</container>
PKϤ$Z�_�+WW5dependency-injection/Tests/Fixtures/xml/services7.xmlnu�[���<?xml version="1.0" ?>

<container xmlns="http://symfony.com/schema/dic/services"
    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    xsi:schemaLocation="http://symfony.com/schema/dic/services http://symfony.com/schema/dic/services/services-1.0.xsd">
  <services>
    <service id="foo" class="BarClass" />
  </services>
</container>
PKϤ$Z�(]

5dependency-injection/Tests/Fixtures/xml/services1.xmlnu�[���<?xml version="1.0" encoding="utf-8"?>
<container xmlns="http://symfony.com/schema/dic/services" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://symfony.com/schema/dic/services http://symfony.com/schema/dic/services/services-1.0.xsd"/>
PKϤ$Z'���+
+
5dependency-injection/Tests/Fixtures/xml/services6.xmlnu�[���<?xml version="1.0" ?>

<container xmlns="http://symfony.com/schema/dic/services"
    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    xsi:schemaLocation="http://symfony.com/schema/dic/services http://symfony.com/schema/dic/services/services-1.0.xsd">
  <services>
    <service id="foo" class="FooClass" />
    <service id="baz" class="BazClass" />
    <service id="not_shared" class="FooClass" shared="false" />
    <service id="file" class="FooClass">
      <file>%path%/foo.php</file>
    </service>
    <service id="arguments" class="FooClass">
      <argument>foo</argument>
      <argument type="service" id="foo" />
      <argument type="collection">
        <argument>true</argument>
        <argument>false</argument>
      </argument>
    </service>
    <service id="configurator1" class="FooClass">
      <configurator function="sc_configure" />
    </service>
    <service id="configurator2" class="FooClass">
      <configurator service="baz" method="configure" />
    </service>
    <service id="configurator3" class="FooClass">
      <configurator class="BazClass" method="configureStatic" />
    </service>
    <service id="method_call1" class="FooClass">
      <call method="setBar" />
      <call method="setBar">
        <argument type="expression">service("foo").foo() ~ (container.hasParameter("foo") ? parameter("foo") : "default")</argument>
      </call>
    </service>
    <service id="method_call2" class="FooClass">
      <call method="setBar">
        <argument>foo</argument>
        <argument type="service" id="foo" />
        <argument type="collection">
          <argument>true</argument>
          <argument>false</argument>
        </argument>
      </call>
    </service>
    <service id="alias_for_foo" alias="foo" />
    <service id="another_alias_for_foo" alias="foo" public="false" />
    <service id="request" class="Request" synthetic="true" lazy="true"/>
    <service id="decorator_service" decorates="decorated" />
    <service id="decorator_service_with_name" decorates="decorated" decoration-inner-name="decorated.pif-pouf"/>
    <service id="decorator_service_with_name_and_priority" decorates="decorated" decoration-inner-name="decorated.pif-pouf" decoration-priority="5"/>
    <service id="new_factory1" class="FooBarClass">
      <factory function="factory" />
    </service>
    <service id="new_factory2" class="FooBarClass">
      <factory service="baz" method="getClass" />
    </service>
    <service id="new_factory3" class="FooBarClass">
      <factory class="BazClass" method="getInstance" />
    </service>
  </services>
</container>
PKϤ$ZV�Y���Kdependency-injection/Tests/Fixtures/xml/legacy_invalid_alias_definition.xmlnu�[���<?xml version="1.0" encoding="utf-8"?>
<container xmlns="http://symfony.com/schema/dic/services" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://symfony.com/schema/dic/services http://symfony.com/schema/dic/services/services-1.0.xsd">
  <services>
    <service id="foo" class="Foo" />

    <service id="bar" alias="foo" class="Foo">
        <tag name="foo.bar" />
        <factory service="foobar" method="getBar" />
    </service>
  </services>
</container>
PKϤ$Z������?dependency-injection/Tests/Fixtures/xml/extension1/services.xmlnu�[���<?xml version="1.0" ?>

<container xmlns="http://symfony.com/schema/dic/services"
    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    xsi:schemaLocation="http://symfony.com/schema/dic/services http://symfony.com/schema/dic/services/services-1.0.xsd">
  <services>
    <service id="extension1.foo" class="FooClass1">
      <argument type="service">
        <service class="BarClass1">
        </service>
      </argument>
    </service>
  </services>
</container>
PKϤ$Z�v��//8dependency-injection/Tests/Fixtures/directory/simple.phpnu�[���<?php

$container->setParameter('php', 'php');
PKϤ$Z��}@dependency-injection/Tests/Fixtures/directory/recurse/simple.ymlnu�[���parameters:
    yaml: yaml
PKϤ$Z>�us@dependency-injection/Tests/Fixtures/directory/recurse/simple.ininu�[���[parameters]
  ini = ini
PKϤ$Z�r;�))?dependency-injection/Tests/Fixtures/directory/import/import.ymlnu�[���imports:
    - { resource: ../recurse/ }
PKϤ$ZC�ݲ;;>dependency-injection/Tests/Fixtures/containers/container10.phpnu�[���<?php

require_once __DIR__.'/../includes/classes.php';

use Symfony\Component\DependencyInjection\ContainerBuilder;
use Symfony\Component\DependencyInjection\Reference;

$container = new ContainerBuilder();
$container->
    register('foo', 'FooClass')->
    addArgument(new Reference('bar'))
;

return $container;
PKϤ$Z
�ť��>dependency-injection/Tests/Fixtures/containers/container24.phpnu�[���<?php

use Symfony\Component\DependencyInjection\ContainerBuilder;

$container = new ContainerBuilder();

$container
    ->register('foo', 'Foo')
    ->setAutowired(true)
    ->addAutowiringType('A')
    ->addAutowiringType('B')
;

return $container;
PKϤ$Z�?���=dependency-injection/Tests/Fixtures/containers/container8.phpnu�[���<?php

use Symfony\Component\DependencyInjection\ContainerBuilder;
use Symfony\Component\DependencyInjection\ParameterBag\ParameterBag;

$container = new ContainerBuilder(new ParameterBag(array(
    'FOO' => '%baz%',
    'baz' => 'bar',
    'bar' => 'foo is %%foo bar',
    'escape' => '@escapeme',
    'values' => array(true, false, null, 0, 1000.3, 'true', 'false', 'null'),
)));

return $container;
PKϤ$Z�]��>dependency-injection/Tests/Fixtures/containers/container16.phpnu�[���<?php

use Symfony\Component\DependencyInjection\ContainerBuilder;

$container = new ContainerBuilder();
$container
    ->register('foo', 'FooClass\\Foo')
    ->setDecoratedService('bar')
;

return $container;
PKϤ$ZBreOO>dependency-injection/Tests/Fixtures/containers/container13.phpnu�[���<?php

use Symfony\Component\DependencyInjection\ContainerBuilder;
use Symfony\Component\DependencyInjection\Reference;

$container = new ContainerBuilder();
$container->
    register('foo', 'FooClass')->
    addArgument(new Reference('bar'))
;
$container->
    register('bar', 'BarClass')
;
$container->compile();

return $container;
PKϤ$Z���33>dependency-injection/Tests/Fixtures/containers/container11.phpnu�[���<?php

use Symfony\Component\DependencyInjection\ContainerBuilder;
use Symfony\Component\DependencyInjection\Definition;

$container = new ContainerBuilder();
$container->
    register('foo', 'FooClass')->
    addArgument(new Definition('BarClass', array(new Definition('BazClass'))))
;

return $container;
PKϤ$Z����^^Bdependency-injection/Tests/Fixtures/containers/CustomContainer.phpnu�[���<?php

namespace Symfony\Component\DependencyInjection\Tests\Fixtures\containers;

use Symfony\Component\DependencyInjection\Container;
use Symfony\Component\DependencyInjection\ParameterBag\ParameterBag;

class CustomContainer extends Container
{
    public function getBarService()
    {
    }

    public function getFoobarService()
    {
    }
}
PKϤ$Zb���>dependency-injection/Tests/Fixtures/containers/container15.phpnu�[���<?php

use Symfony\Component\DependencyInjection\ContainerBuilder;

$container = new ContainerBuilder();
$container
    ->register('foo', 'FooClass\\Foo')
    ->setDecoratedService('bar', 'bar.woozy')
;

return $container;
PKϤ$Zܓ�>dependency-injection/Tests/Fixtures/containers/container12.phpnu�[���<?php

use Symfony\Component\DependencyInjection\ContainerBuilder;

$container = new ContainerBuilder();
$container->
    register('foo', 'FooClass\\Foo')->
    addArgument('foo<>&bar')->
    addTag('foo"bar\\bar', array('foo' => 'foo"barřž€'))
;

return $container;
PKϤ$Z�����>dependency-injection/Tests/Fixtures/containers/container19.phpnu�[���<?php

use Symfony\Component\DependencyInjection\ContainerBuilder;
use Symfony\Component\DependencyInjection\Definition;

require_once __DIR__.'/../includes/classes.php';

$container = new ContainerBuilder();

$container
    ->register('service_from_anonymous_factory', 'Bar\FooClass')
    ->setFactory(array(new Definition('Bar\FooClass'), 'getInstance'))
;

$anonymousServiceWithFactory = new Definition('Bar\FooClass');
$anonymousServiceWithFactory->setFactory('Bar\FooClass::getInstance');
$container
    ->register('service_with_method_call_and_factory', 'Bar\FooClass')
    ->addMethodCall('setBar', array($anonymousServiceWithFactory))
;

return $container;
PKϤ$Z��g���=dependency-injection/Tests/Fixtures/containers/container9.phpnu�[���<?php

require_once __DIR__.'/../includes/classes.php';

use Symfony\Component\DependencyInjection\ContainerInterface;
use Symfony\Component\DependencyInjection\ContainerBuilder;
use Symfony\Component\DependencyInjection\Reference;
use Symfony\Component\DependencyInjection\Parameter;
use Symfony\Component\ExpressionLanguage\Expression;

$container = new ContainerBuilder();
$container
    ->register('foo', '\Bar\FooClass')
    ->addTag('foo', array('foo' => 'foo'))
    ->addTag('foo', array('bar' => 'bar', 'baz' => 'baz'))
    ->setFactory(array('Bar\\FooClass', 'getInstance'))
    ->setArguments(array('foo', new Reference('foo.baz'), array('%foo%' => 'foo is %foo%', 'foobar' => '%foo%'), true, new Reference('service_container')))
    ->setProperties(array('foo' => 'bar', 'moo' => new Reference('foo.baz'), 'qux' => array('%foo%' => 'foo is %foo%', 'foobar' => '%foo%')))
    ->addMethodCall('setBar', array(new Reference('bar')))
    ->addMethodCall('initialize')
    ->setConfigurator('sc_configure')
;
$container
    ->register('foo.baz', '%baz_class%')
    ->setFactory(array('%baz_class%', 'getInstance'))
    ->setConfigurator(array('%baz_class%', 'configureStatic1'))
;
$container
    ->register('bar', 'Bar\FooClass')
    ->setArguments(array('foo', new Reference('foo.baz'), new Parameter('foo_bar')))
    ->setConfigurator(array(new Reference('foo.baz'), 'configure'))
;
$container
    ->register('foo_bar', '%foo_class%')
    ->setShared(false)
;
$container->getParameterBag()->clear();
$container->getParameterBag()->add(array(
    'baz_class' => 'BazClass',
    'foo_class' => 'Bar\FooClass',
    'foo' => 'bar',
));
$container->setAlias('alias_for_foo', 'foo');
$container->setAlias('alias_for_alias', 'alias_for_foo');
$container
    ->register('method_call1', 'Bar\FooClass')
    ->setFile(realpath(__DIR__.'/../includes/foo.php'))
    ->addMethodCall('setBar', array(new Reference('foo')))
    ->addMethodCall('setBar', array(new Reference('foo2', ContainerInterface::NULL_ON_INVALID_REFERENCE)))
    ->addMethodCall('setBar', array(new Reference('foo3', ContainerInterface::IGNORE_ON_INVALID_REFERENCE)))
    ->addMethodCall('setBar', array(new Reference('foobaz', ContainerInterface::IGNORE_ON_INVALID_REFERENCE)))
    ->addMethodCall('setBar', array(new Expression('service("foo").foo() ~ (container.hasParameter("foo") ? parameter("foo") : "default")')))
;
$container
    ->register('foo_with_inline', 'Foo')
    ->addMethodCall('setBar', array(new Reference('inlined')))
;
$container
    ->register('inlined', 'Bar')
    ->setProperty('pub', 'pub')
    ->addMethodCall('setBaz', array(new Reference('baz')))
    ->setPublic(false)
;
$container
    ->register('baz', 'Baz')
    ->addMethodCall('setFoo', array(new Reference('foo_with_inline')))
;
$container
    ->register('request', 'Request')
    ->setSynthetic(true)
;
$container
    ->register('configurator_service', 'ConfClass')
    ->setPublic(false)
    ->addMethodCall('setFoo', array(new Reference('baz')))
;
$container
    ->register('configured_service', 'stdClass')
    ->setConfigurator(array(new Reference('configurator_service'), 'configureStdClass'))
;
$container
    ->register('configurator_service_simple', 'ConfClass')
    ->addArgument('bar')
    ->setPublic(false)
;
$container
    ->register('configured_service_simple', 'stdClass')
    ->setConfigurator(array(new Reference('configurator_service_simple'), 'configureStdClass'))
;
$container
    ->register('decorated', 'stdClass')
;
$container
    ->register('decorator_service', 'stdClass')
    ->setDecoratedService('decorated')
;
$container
    ->register('decorator_service_with_name', 'stdClass')
    ->setDecoratedService('decorated', 'decorated.pif-pouf')
;
$container
    ->register('deprecated_service', 'stdClass')
    ->setDeprecated(true)
;
$container
    ->register('new_factory', 'FactoryClass')
    ->setProperty('foo', 'bar')
    ->setPublic(false)
;
$container
    ->register('factory_service', 'Bar')
    ->setFactory(array(new Reference('foo.baz'), 'getInstance'))
;
$container
    ->register('new_factory_service', 'FooBarBaz')
    ->setProperty('foo', 'bar')
    ->setFactory(array(new Reference('new_factory'), 'getInstance'))
;
$container
    ->register('service_from_static_method', 'Bar\FooClass')
    ->setFactory(array('Bar\FooClass', 'getInstance'))
;
$container
    ->register('factory_simple', 'SimpleFactoryClass')
    ->addArgument('foo')
    ->setPublic(false)
;
$container
    ->register('factory_service_simple', 'Bar')
    ->setFactory(array(new Reference('factory_simple'), 'getInstance'))
;

return $container;
PKϤ$Z�cЯ�>dependency-injection/Tests/Fixtures/containers/container17.phpnu�[���<?php

use Symfony\Component\DependencyInjection\ContainerBuilder;

$container = new ContainerBuilder();
$container
    ->register('foo', '%foo.class%')
;

return $container;
PKϤ$Z�"�U"">dependency-injection/Tests/Fixtures/containers/container21.phpnu�[���<?php

use Symfony\Component\DependencyInjection\ContainerBuilder;
use Symfony\Component\DependencyInjection\Definition;

$container = new ContainerBuilder();

$bar = new Definition('Bar');
$bar->setConfigurator(array(new Definition('Baz'), 'configureBar'));

$fooFactory = new Definition('FooFactory');
$fooFactory->setFactory(array(new Definition('Foobar'), 'createFooFactory'));

$container
    ->register('foo', 'Foo')
    ->setFactory(array($fooFactory, 'createFoo'))
    ->setConfigurator(array($bar, 'configureFoo'))
;

return $container;
PKϤ$Z��i��>dependency-injection/Tests/Fixtures/containers/container14.phpnu�[���<?php

namespace Container14;

use Symfony\Component\DependencyInjection\ContainerBuilder;

/*
 * This file is included in Tests\Dumper\GraphvizDumperTest::testDumpWithFrozenCustomClassContainer
 * and Tests\Dumper\XmlDumperTest::testCompiledContainerCanBeDumped.
 */
if (!class_exists('Container14\ProjectServiceContainer')) {
    class ProjectServiceContainer extends ContainerBuilder
    {
    }
}

return new ProjectServiceContainer();
PKϤ$Z#�����Bdependency-injection/Tests/ParameterBag/FrozenParameterBagTest.phpnu�[���<?php

/*
 * This file is part of the Symfony package.
 *
 * (c) Fabien Potencier <fabien@symfony.com>
 *
 * For the full copyright and license information, please view the LICENSE
 * file that was distributed with this source code.
 */

namespace Symfony\Component\DependencyInjection\Tests\ParameterBag;

use Symfony\Component\DependencyInjection\ParameterBag\FrozenParameterBag;

class FrozenParameterBagTest extends \PHPUnit_Framework_TestCase
{
    public function testConstructor()
    {
        $parameters = array(
            'foo' => 'foo',
            'bar' => 'bar',
        );
        $bag = new FrozenParameterBag($parameters);
        $this->assertEquals($parameters, $bag->all(), '__construct() takes an array of parameters as its first argument');
    }

    /**
     * @expectedException \LogicException
     */
    public function testClear()
    {
        $bag = new FrozenParameterBag(array());
        $bag->clear();
    }

    /**
     * @expectedException \LogicException
     */
    public function testSet()
    {
        $bag = new FrozenParameterBag(array());
        $bag->set('foo', 'bar');
    }

    /**
     * @expectedException \LogicException
     */
    public function testAdd()
    {
        $bag = new FrozenParameterBag(array());
        $bag->add(array());
    }

    /**
     * @expectedException \LogicException
     */
    public function testRemove()
    {
        $bag = new FrozenParameterBag(array('foo' => 'bar'));
        $bag->remove('foo');
    }
}
PKϤ$ZVI�<5<5<dependency-injection/Tests/ParameterBag/ParameterBagTest.phpnu�[���<?php

/*
 * This file is part of the Symfony package.
 *
 * (c) Fabien Potencier <fabien@symfony.com>
 *
 * For the full copyright and license information, please view the LICENSE
 * file that was distributed with this source code.
 */

namespace Symfony\Component\DependencyInjection\Tests\ParameterBag;

use Symfony\Component\DependencyInjection\ParameterBag\ParameterBag;
use Symfony\Component\DependencyInjection\Exception\ParameterNotFoundException;
use Symfony\Component\DependencyInjection\Exception\ParameterCircularReferenceException;
use Symfony\Component\DependencyInjection\Exception\RuntimeException;

class ParameterBagTest extends \PHPUnit_Framework_TestCase
{
    public function testConstructor()
    {
        $bag = new ParameterBag($parameters = array(
            'foo' => 'foo',
            'bar' => 'bar',
        ));
        $this->assertEquals($parameters, $bag->all(), '__construct() takes an array of parameters as its first argument');
    }

    public function testClear()
    {
        $bag = new ParameterBag($parameters = array(
            'foo' => 'foo',
            'bar' => 'bar',
        ));
        $bag->clear();
        $this->assertEquals(array(), $bag->all(), '->clear() removes all parameters');
    }

    public function testRemove()
    {
        $bag = new ParameterBag(array(
            'foo' => 'foo',
            'bar' => 'bar',
        ));
        $bag->remove('foo');
        $this->assertEquals(array('bar' => 'bar'), $bag->all(), '->remove() removes a parameter');
        $bag->remove('BAR');
        $this->assertEquals(array(), $bag->all(), '->remove() converts key to lowercase before removing');
    }

    public function testGetSet()
    {
        $bag = new ParameterBag(array('foo' => 'bar'));
        $bag->set('bar', 'foo');
        $this->assertEquals('foo', $bag->get('bar'), '->set() sets the value of a new parameter');

        $bag->set('foo', 'baz');
        $this->assertEquals('baz', $bag->get('foo'), '->set() overrides previously set parameter');

        $bag->set('Foo', 'baz1');
        $this->assertEquals('baz1', $bag->get('foo'), '->set() converts the key to lowercase');
        $this->assertEquals('baz1', $bag->get('FOO'), '->get() converts the key to lowercase');

        try {
            $bag->get('baba');
            $this->fail('->get() throws an Symfony\Component\DependencyInjection\Exception\ParameterNotFoundException if the key does not exist');
        } catch (\Exception $e) {
            $this->assertInstanceOf('Symfony\Component\DependencyInjection\Exception\ParameterNotFoundException', $e, '->get() throws an Symfony\Component\DependencyInjection\Exception\ParameterNotFoundException if the key does not exist');
            $this->assertEquals('You have requested a non-existent parameter "baba".', $e->getMessage(), '->get() throws an Symfony\Component\DependencyInjection\Exception\ParameterNotFoundException if the key does not exist');
        }
    }

    public function testGetThrowParameterNotFoundException()
    {
        $bag = new ParameterBag(array(
            'foo' => 'foo',
            'bar' => 'bar',
            'baz' => 'baz',
        ));

        try {
            $bag->get('foo1');
            $this->fail('->get() throws an Symfony\Component\DependencyInjection\Exception\ParameterNotFoundException if the key does not exist');
        } catch (\Exception $e) {
            $this->assertInstanceOf('Symfony\Component\DependencyInjection\Exception\ParameterNotFoundException', $e, '->get() throws an Symfony\Component\DependencyInjection\Exception\ParameterNotFoundException if the key does not exist');
            $this->assertEquals('You have requested a non-existent parameter "foo1". Did you mean this: "foo"?', $e->getMessage(), '->get() throws an Symfony\Component\DependencyInjection\Exception\ParameterNotFoundException with some advices');
        }

        try {
            $bag->get('bag');
            $this->fail('->get() throws an Symfony\Component\DependencyInjection\Exception\ParameterNotFoundException if the key does not exist');
        } catch (\Exception $e) {
            $this->assertInstanceOf('Symfony\Component\DependencyInjection\Exception\ParameterNotFoundException', $e, '->get() throws an Symfony\Component\DependencyInjection\Exception\ParameterNotFoundException if the key does not exist');
            $this->assertEquals('You have requested a non-existent parameter "bag". Did you mean one of these: "bar", "baz"?', $e->getMessage(), '->get() throws an Symfony\Component\DependencyInjection\Exception\ParameterNotFoundException with some advices');
        }

        try {
            $bag->get('');
            $this->fail('->get() throws an Symfony\Component\DependencyInjection\Exception\ParameterNotFoundException if the key does not exist');
        } catch (\Exception $e) {
            $this->assertInstanceOf('Symfony\Component\DependencyInjection\Exception\ParameterNotFoundException', $e, '->get() throws an Symfony\Component\DependencyInjection\Exception\ParameterNotFoundException if the key does not exist');
            $this->assertEquals('You have requested a non-existent parameter "".', $e->getMessage(), '->get() throws an Symfony\Component\DependencyInjection\Exception\ParameterNotFoundException with some advices');
        }
    }

    public function testHas()
    {
        $bag = new ParameterBag(array('foo' => 'bar'));
        $this->assertTrue($bag->has('foo'), '->has() returns true if a parameter is defined');
        $this->assertTrue($bag->has('Foo'), '->has() converts the key to lowercase');
        $this->assertFalse($bag->has('bar'), '->has() returns false if a parameter is not defined');
    }

    public function testResolveValue()
    {
        $bag = new ParameterBag(array());
        $this->assertEquals('foo', $bag->resolveValue('foo'), '->resolveValue() returns its argument unmodified if no placeholders are found');

        $bag = new ParameterBag(array('foo' => 'bar'));
        $this->assertEquals('I\'m a bar', $bag->resolveValue('I\'m a %foo%'), '->resolveValue() replaces placeholders by their values');
        $this->assertEquals(array('bar' => 'bar'), $bag->resolveValue(array('%foo%' => '%foo%')), '->resolveValue() replaces placeholders in keys and values of arrays');
        $this->assertEquals(array('bar' => array('bar' => array('bar' => 'bar'))), $bag->resolveValue(array('%foo%' => array('%foo%' => array('%foo%' => '%foo%')))), '->resolveValue() replaces placeholders in nested arrays');
        $this->assertEquals('I\'m a %%foo%%', $bag->resolveValue('I\'m a %%foo%%'), '->resolveValue() supports % escaping by doubling it');
        $this->assertEquals('I\'m a bar %%foo bar', $bag->resolveValue('I\'m a %foo% %%foo %foo%'), '->resolveValue() supports % escaping by doubling it');
        $this->assertEquals(array('foo' => array('bar' => array('ding' => 'I\'m a bar %%foo %%bar'))), $bag->resolveValue(array('foo' => array('bar' => array('ding' => 'I\'m a bar %%foo %%bar')))), '->resolveValue() supports % escaping by doubling it');

        $bag = new ParameterBag(array('foo' => true));
        $this->assertTrue($bag->resolveValue('%foo%'), '->resolveValue() replaces arguments that are just a placeholder by their value without casting them to strings');
        $bag = new ParameterBag(array('foo' => null));
        $this->assertNull($bag->resolveValue('%foo%'), '->resolveValue() replaces arguments that are just a placeholder by their value without casting them to strings');

        $bag = new ParameterBag(array('foo' => 'bar', 'baz' => '%%%foo% %foo%%% %%foo%% %%%foo%%%'));
        $this->assertEquals('%%bar bar%% %%foo%% %%bar%%', $bag->resolveValue('%baz%'), '->resolveValue() replaces params placed besides escaped %');

        $bag = new ParameterBag(array('baz' => '%%s?%%s'));
        $this->assertEquals('%%s?%%s', $bag->resolveValue('%baz%'), '->resolveValue() is not replacing greedily');

        $bag = new ParameterBag(array());
        try {
            $bag->resolveValue('%foobar%');
            $this->fail('->resolveValue() throws an InvalidArgumentException if a placeholder references a non-existent parameter');
        } catch (ParameterNotFoundException $e) {
            $this->assertEquals('You have requested a non-existent parameter "foobar".', $e->getMessage(), '->resolveValue() throws a ParameterNotFoundException if a placeholder references a non-existent parameter');
        }

        try {
            $bag->resolveValue('foo %foobar% bar');
            $this->fail('->resolveValue() throws a ParameterNotFoundException if a placeholder references a non-existent parameter');
        } catch (ParameterNotFoundException $e) {
            $this->assertEquals('You have requested a non-existent parameter "foobar".', $e->getMessage(), '->resolveValue() throws a ParameterNotFoundException if a placeholder references a non-existent parameter');
        }

        $bag = new ParameterBag(array('foo' => 'a %bar%', 'bar' => array()));
        try {
            $bag->resolveValue('%foo%');
            $this->fail('->resolveValue() throws a RuntimeException when a parameter embeds another non-string parameter');
        } catch (RuntimeException $e) {
            $this->assertEquals('A string value must be composed of strings and/or numbers, but found parameter "bar" of type array inside string value "a %bar%".', $e->getMessage(), '->resolveValue() throws a RuntimeException when a parameter embeds another non-string parameter');
        }

        $bag = new ParameterBag(array('foo' => '%bar%', 'bar' => '%foobar%', 'foobar' => '%foo%'));
        try {
            $bag->resolveValue('%foo%');
            $this->fail('->resolveValue() throws a ParameterCircularReferenceException when a parameter has a circular reference');
        } catch (ParameterCircularReferenceException $e) {
            $this->assertEquals('Circular reference detected for parameter "foo" ("foo" > "bar" > "foobar" > "foo").', $e->getMessage(), '->resolveValue() throws a ParameterCircularReferenceException when a parameter has a circular reference');
        }

        $bag = new ParameterBag(array('foo' => 'a %bar%', 'bar' => 'a %foobar%', 'foobar' => 'a %foo%'));
        try {
            $bag->resolveValue('%foo%');
            $this->fail('->resolveValue() throws a ParameterCircularReferenceException when a parameter has a circular reference');
        } catch (ParameterCircularReferenceException $e) {
            $this->assertEquals('Circular reference detected for parameter "foo" ("foo" > "bar" > "foobar" > "foo").', $e->getMessage(), '->resolveValue() throws a ParameterCircularReferenceException when a parameter has a circular reference');
        }

        $bag = new ParameterBag(array('host' => 'foo.bar', 'port' => 1337));
        $this->assertEquals('foo.bar:1337', $bag->resolveValue('%host%:%port%'));
    }

    public function testResolveIndicatesWhyAParameterIsNeeded()
    {
        $bag = new ParameterBag(array('foo' => '%bar%'));

        try {
            $bag->resolve();
        } catch (ParameterNotFoundException $e) {
            $this->assertEquals('The parameter "foo" has a dependency on a non-existent parameter "bar".', $e->getMessage());
        }

        $bag = new ParameterBag(array('foo' => '%bar%'));

        try {
            $bag->resolve();
        } catch (ParameterNotFoundException $e) {
            $this->assertEquals('The parameter "foo" has a dependency on a non-existent parameter "bar".', $e->getMessage());
        }
    }

    public function testResolveUnescapesValue()
    {
        $bag = new ParameterBag(array(
            'foo' => array('bar' => array('ding' => 'I\'m a bar %%foo %%bar')),
            'bar' => 'I\'m a %%foo%%',
        ));

        $bag->resolve();

        $this->assertEquals('I\'m a %foo%', $bag->get('bar'), '->resolveValue() supports % escaping by doubling it');
        $this->assertEquals(array('bar' => array('ding' => 'I\'m a bar %foo %bar')), $bag->get('foo'), '->resolveValue() supports % escaping by doubling it');
    }

    public function testEscapeValue()
    {
        $bag = new ParameterBag();

        $bag->add(array(
            'foo' => $bag->escapeValue(array('bar' => array('ding' => 'I\'m a bar %foo %bar', 'zero' => null))),
            'bar' => $bag->escapeValue('I\'m a %foo%'),
        ));

        $this->assertEquals('I\'m a %%foo%%', $bag->get('bar'), '->escapeValue() escapes % by doubling it');
        $this->assertEquals(array('bar' => array('ding' => 'I\'m a bar %%foo %%bar', 'zero' => null)), $bag->get('foo'), '->escapeValue() escapes % by doubling it');
    }

    /**
     * @dataProvider stringsWithSpacesProvider
     */
    public function testResolveStringWithSpacesReturnsString($expected, $test, $description)
    {
        $bag = new ParameterBag(array('foo' => 'bar'));

        try {
            $this->assertEquals($expected, $bag->resolveString($test), $description);
        } catch (ParameterNotFoundException $e) {
            $this->fail(sprintf('%s - "%s"', $description, $expected));
        }
    }

    public function stringsWithSpacesProvider()
    {
        return array(
            array('bar', '%foo%', 'Parameters must be wrapped by %.'),
            array('% foo %', '% foo %', 'Parameters should not have spaces.'),
            array('{% set my_template = "foo" %}', '{% set my_template = "foo" %}', 'Twig-like strings are not parameters.'),
            array('50% is less than 100%', '50% is less than 100%', 'Text between % signs is allowed, if there are spaces.'),
        );
    }
}
PKϤ$Z�r
8�;�;,dependency-injection/Tests/ContainerTest.phpnu�[���<?php

/*
 * This file is part of the Symfony package.
 *
 * (c) Fabien Potencier <fabien@symfony.com>
 *
 * For the full copyright and license information, please view the LICENSE
 * file that was distributed with this source code.
 */

namespace Symfony\Component\DependencyInjection\Tests;

use Symfony\Component\DependencyInjection\Container;
use Symfony\Component\DependencyInjection\ContainerInterface;
use Symfony\Component\DependencyInjection\ParameterBag\ParameterBag;

class ContainerTest extends \PHPUnit_Framework_TestCase
{
    public function testConstructor()
    {
        $sc = new Container();
        $this->assertSame($sc, $sc->get('service_container'), '__construct() automatically registers itself as a service');

        $sc = new Container(new ParameterBag(array('foo' => 'bar')));
        $this->assertEquals(array('foo' => 'bar'), $sc->getParameterBag()->all(), '__construct() takes an array of parameters as its first argument');
    }

    /**
     * @dataProvider dataForTestCamelize
     */
    public function testCamelize($id, $expected)
    {
        $this->assertEquals($expected, Container::camelize($id), sprintf('Container::camelize("%s")', $id));
    }

    public function dataForTestCamelize()
    {
        return array(
            array('foo_bar', 'FooBar'),
            array('foo.bar', 'Foo_Bar'),
            array('foo.bar_baz', 'Foo_BarBaz'),
            array('foo._bar', 'Foo_Bar'),
            array('foo_.bar', 'Foo_Bar'),
            array('_foo', 'Foo'),
            array('.foo', '_Foo'),
            array('foo_', 'Foo'),
            array('foo.', 'Foo_'),
            array('foo\bar', 'Foo_Bar'),
        );
    }

    /**
     * @dataProvider dataForTestUnderscore
     */
    public function testUnderscore($id, $expected)
    {
        $this->assertEquals($expected, Container::underscore($id), sprintf('Container::underscore("%s")', $id));
    }

    public function dataForTestUnderscore()
    {
        return array(
            array('FooBar', 'foo_bar'),
            array('Foo_Bar', 'foo.bar'),
            array('Foo_BarBaz', 'foo.bar_baz'),
            array('FooBar_BazQux', 'foo_bar.baz_qux'),
            array('_Foo', '.foo'),
            array('Foo_', 'foo.'),
        );
    }

    public function testCompile()
    {
        $sc = new Container(new ParameterBag(array('foo' => 'bar')));
        $this->assertFalse($sc->getParameterBag()->isResolved(), '->compile() resolves the parameter bag');
        $sc->compile();
        $this->assertTrue($sc->getParameterBag()->isResolved(), '->compile() resolves the parameter bag');
        $this->assertInstanceOf('Symfony\Component\DependencyInjection\ParameterBag\FrozenParameterBag', $sc->getParameterBag(), '->compile() changes the parameter bag to a FrozenParameterBag instance');
        $this->assertEquals(array('foo' => 'bar'), $sc->getParameterBag()->all(), '->compile() copies the current parameters to the new parameter bag');
    }

    public function testIsFrozen()
    {
        $sc = new Container(new ParameterBag(array('foo' => 'bar')));
        $this->assertFalse($sc->isFrozen(), '->isFrozen() returns false if the parameters are not frozen');
        $sc->compile();
        $this->assertTrue($sc->isFrozen(), '->isFrozen() returns true if the parameters are frozen');
    }

    public function testGetParameterBag()
    {
        $sc = new Container();
        $this->assertEquals(array(), $sc->getParameterBag()->all(), '->getParameterBag() returns an empty array if no parameter has been defined');
    }

    public function testGetSetParameter()
    {
        $sc = new Container(new ParameterBag(array('foo' => 'bar')));
        $sc->setParameter('bar', 'foo');
        $this->assertEquals('foo', $sc->getParameter('bar'), '->setParameter() sets the value of a new parameter');

        $sc->setParameter('foo', 'baz');
        $this->assertEquals('baz', $sc->getParameter('foo'), '->setParameter() overrides previously set parameter');

        $sc->setParameter('Foo', 'baz1');
        $this->assertEquals('baz1', $sc->getParameter('foo'), '->setParameter() converts the key to lowercase');
        $this->assertEquals('baz1', $sc->getParameter('FOO'), '->getParameter() converts the key to lowercase');

        try {
            $sc->getParameter('baba');
            $this->fail('->getParameter() thrown an \InvalidArgumentException if the key does not exist');
        } catch (\Exception $e) {
            $this->assertInstanceOf('\InvalidArgumentException', $e, '->getParameter() thrown an \InvalidArgumentException if the key does not exist');
            $this->assertEquals('You have requested a non-existent parameter "baba".', $e->getMessage(), '->getParameter() thrown an \InvalidArgumentException if the key does not exist');
        }
    }

    public function testGetServiceIds()
    {
        $sc = new Container();
        $sc->set('foo', $obj = new \stdClass());
        $sc->set('bar', $obj = new \stdClass());
        $this->assertEquals(array('service_container', 'foo', 'bar'), $sc->getServiceIds(), '->getServiceIds() returns all defined service ids');

        $sc = new ProjectServiceContainer();
        $sc->set('foo', $obj = new \stdClass());
        $this->assertEquals(array('bar', 'foo_bar', 'foo.baz', 'circular', 'throw_exception', 'throws_exception_on_service_configuration', 'service_container', 'foo'), $sc->getServiceIds(), '->getServiceIds() returns defined service ids by getXXXService() methods, followed by service ids defined by set()');
    }

    public function testSet()
    {
        $sc = new Container();
        $sc->set('foo', $foo = new \stdClass());
        $this->assertSame($foo, $sc->get('foo'), '->set() sets a service');
    }

    public function testSetWithNullResetTheService()
    {
        $sc = new Container();
        $sc->set('foo', null);
        $this->assertFalse($sc->has('foo'), '->set() with null service resets the service');
    }

    public function testSetReplacesAlias()
    {
        $c = new ProjectServiceContainer();

        $c->set('alias', $foo = new \stdClass());
        $this->assertSame($foo, $c->get('alias'), '->set() replaces an existing alias');
    }

    public function testGet()
    {
        $sc = new ProjectServiceContainer();
        $sc->set('foo', $foo = new \stdClass());
        $this->assertSame($foo, $sc->get('foo'), '->get() returns the service for the given id');
        $this->assertSame($foo, $sc->get('Foo'), '->get() returns the service for the given id, and converts id to lowercase');
        $this->assertSame($sc->__bar, $sc->get('bar'), '->get() returns the service for the given id');
        $this->assertSame($sc->__foo_bar, $sc->get('foo_bar'), '->get() returns the service if a get*Method() is defined');
        $this->assertSame($sc->__foo_baz, $sc->get('foo.baz'), '->get() returns the service if a get*Method() is defined');
        $this->assertSame($sc->__foo_baz, $sc->get('foo\\baz'), '->get() returns the service if a get*Method() is defined');

        $sc->set('bar', $bar = new \stdClass());
        $this->assertSame($bar, $sc->get('bar'), '->get() prefers to return a service defined with set() than one defined with a getXXXMethod()');

        try {
            $sc->get('');
            $this->fail('->get() throws a \InvalidArgumentException exception if the service is empty');
        } catch (\Exception $e) {
            $this->assertInstanceOf('Symfony\Component\DependencyInjection\Exception\ServiceNotFoundException', $e, '->get() throws a ServiceNotFoundException exception if the service is empty');
        }
        $this->assertNull($sc->get('', ContainerInterface::NULL_ON_INVALID_REFERENCE), '->get() returns null if the service is empty');
    }

    public function testGetThrowServiceNotFoundException()
    {
        $sc = new ProjectServiceContainer();
        $sc->set('foo', $foo = new \stdClass());
        $sc->set('baz', $foo = new \stdClass());

        try {
            $sc->get('foo1');
            $this->fail('->get() throws an Symfony\Component\DependencyInjection\Exception\ServiceNotFoundException if the key does not exist');
        } catch (\Exception $e) {
            $this->assertInstanceOf('Symfony\Component\DependencyInjection\Exception\ServiceNotFoundException', $e, '->get() throws an Symfony\Component\DependencyInjection\Exception\ServiceNotFoundException if the key does not exist');
            $this->assertEquals('You have requested a non-existent service "foo1". Did you mean this: "foo"?', $e->getMessage(), '->get() throws an Symfony\Component\DependencyInjection\Exception\ServiceNotFoundException with some advices');
        }

        try {
            $sc->get('bag');
            $this->fail('->get() throws an Symfony\Component\DependencyInjection\Exception\ServiceNotFoundException if the key does not exist');
        } catch (\Exception $e) {
            $this->assertInstanceOf('Symfony\Component\DependencyInjection\Exception\ServiceNotFoundException', $e, '->get() throws an Symfony\Component\DependencyInjection\Exception\ServiceNotFoundException if the key does not exist');
            $this->assertEquals('You have requested a non-existent service "bag". Did you mean one of these: "bar", "baz"?', $e->getMessage(), '->get() throws an Symfony\Component\DependencyInjection\Exception\ServiceNotFoundException with some advices');
        }
    }

    public function testGetCircularReference()
    {
        $sc = new ProjectServiceContainer();
        try {
            $sc->get('circular');
            $this->fail('->get() throws a ServiceCircularReferenceException if it contains circular reference');
        } catch (\Exception $e) {
            $this->assertInstanceOf('\Symfony\Component\DependencyInjection\Exception\ServiceCircularReferenceException', $e, '->get() throws a ServiceCircularReferenceException if it contains circular reference');
            $this->assertStringStartsWith('Circular reference detected for service "circular"', $e->getMessage(), '->get() throws a \LogicException if it contains circular reference');
        }
    }

    /**
     * @expectedException \Symfony\Component\DependencyInjection\Exception\RuntimeException
     * @expectedExceptionMessage You have requested a synthetic service ("request"). The DIC does not know how to construct this service.
     */
    public function testGetSyntheticServiceAlwaysThrows()
    {
        require_once __DIR__.'/Fixtures/php/services9.php';

        $container = new \ProjectServiceContainer();
        $container->get('request', ContainerInterface::NULL_ON_INVALID_REFERENCE);
    }

    public function testHas()
    {
        $sc = new ProjectServiceContainer();
        $sc->set('foo', new \stdClass());
        $this->assertFalse($sc->has('foo1'), '->has() returns false if the service does not exist');
        $this->assertTrue($sc->has('foo'), '->has() returns true if the service exists');
        $this->assertTrue($sc->has('bar'), '->has() returns true if a get*Method() is defined');
        $this->assertTrue($sc->has('foo_bar'), '->has() returns true if a get*Method() is defined');
        $this->assertTrue($sc->has('foo.baz'), '->has() returns true if a get*Method() is defined');
        $this->assertTrue($sc->has('foo\\baz'), '->has() returns true if a get*Method() is defined');
    }

    public function testInitialized()
    {
        $sc = new ProjectServiceContainer();
        $sc->set('foo', new \stdClass());
        $this->assertTrue($sc->initialized('foo'), '->initialized() returns true if service is loaded');
        $this->assertFalse($sc->initialized('foo1'), '->initialized() returns false if service is not loaded');
        $this->assertFalse($sc->initialized('bar'), '->initialized() returns false if a service is defined, but not currently loaded');
        $this->assertFalse($sc->initialized('alias'), '->initialized() returns false if an aliased service is not initialized');

        $sc->set('bar', new \stdClass());
        $this->assertTrue($sc->initialized('alias'), '->initialized() returns true for alias if aliased service is initialized');
    }

    public function testReset()
    {
        $c = new Container();
        $c->set('bar', new \stdClass());

        $c->reset();

        $this->assertNull($c->get('bar', ContainerInterface::NULL_ON_INVALID_REFERENCE));
    }

    /**
     * @expectedException \Exception
     * @expectedExceptionMessage Something went terribly wrong!
     */
    public function testGetThrowsException()
    {
        $c = new ProjectServiceContainer();

        try {
            $c->get('throw_exception');
        } catch (\Exception $e) {
            // Do nothing.
        }

        // Retry, to make sure that get*Service() will be called.
        $c->get('throw_exception');
    }

    public function testGetThrowsExceptionOnServiceConfiguration()
    {
        $c = new ProjectServiceContainer();

        try {
            $c->get('throws_exception_on_service_configuration');
        } catch (\Exception $e) {
            // Do nothing.
        }

        $this->assertFalse($c->initialized('throws_exception_on_service_configuration'));

        // Retry, to make sure that get*Service() will be called.
        try {
            $c->get('throws_exception_on_service_configuration');
        } catch (\Exception $e) {
            // Do nothing.
        }
        $this->assertFalse($c->initialized('throws_exception_on_service_configuration'));
    }

    protected function getField($obj, $field)
    {
        $reflection = new \ReflectionProperty($obj, $field);
        $reflection->setAccessible(true);

        return $reflection->getValue($obj);
    }

    public function testAlias()
    {
        $c = new ProjectServiceContainer();

        $this->assertTrue($c->has('alias'));
        $this->assertSame($c->get('alias'), $c->get('bar'));
    }

    public function testThatCloningIsNotSupported()
    {
        $class = new \ReflectionClass('Symfony\Component\DependencyInjection\Container');
        $clone = $class->getMethod('__clone');
        $this->assertFalse($class->isCloneable());
        $this->assertTrue($clone->isPrivate());
    }
}

class ProjectServiceContainer extends Container
{
    public $__bar;
    public $__foo_bar;
    public $__foo_baz;

    public function __construct()
    {
        parent::__construct();

        $this->__bar = new \stdClass();
        $this->__foo_bar = new \stdClass();
        $this->__foo_baz = new \stdClass();
        $this->aliases = array('alias' => 'bar');
    }

    protected function getBarService()
    {
        return $this->__bar;
    }

    protected function getFooBarService()
    {
        return $this->__foo_bar;
    }

    protected function getFoo_BazService()
    {
        return $this->__foo_baz;
    }

    protected function getCircularService()
    {
        return $this->get('circular');
    }

    protected function getThrowExceptionService()
    {
        throw new \Exception('Something went terribly wrong!');
    }

    protected function getThrowsExceptionOnServiceConfigurationService()
    {
        $this->services['throws_exception_on_service_configuration'] = $instance = new \stdClass();

        throw new \Exception('Something was terribly wrong while trying to configure the service!');
    }
}
PKϤ$ZpY����Adependency-injection/Tests/LazyProxy/PhpDumper/NullDumperTest.phpnu�[���<?php

/*
 * This file is part of the Symfony package.
 *
 * (c) Fabien Potencier <fabien@symfony.com>
 *
 * For the full copyright and license information, please view the LICENSE
 * file that was distributed with this source code.
 */

namespace Symfony\Component\DependencyInjection\Tests\LazyProxy\PhpDumper;

use Symfony\Component\DependencyInjection\Definition;
use Symfony\Component\DependencyInjection\LazyProxy\PhpDumper\NullDumper;

/**
 * Tests for {@see \Symfony\Component\DependencyInjection\PhpDumper\NullDumper}.
 *
 * @author Marco Pivetta <ocramius@gmail.com>
 */
class NullDumperTest extends \PHPUnit_Framework_TestCase
{
    public function testNullDumper()
    {
        $dumper = new NullDumper();
        $definition = new Definition('stdClass');

        $this->assertFalse($dumper->isProxyCandidate($definition));
        $this->assertSame('', $dumper->getProxyFactoryCode($definition, 'foo'));
        $this->assertSame('', $dumper->getProxyCode($definition));
    }
}
PKϤ$Z
aȘ��Qdependency-injection/Tests/LazyProxy/Instantiator/RealServiceInstantiatorTest.phpnu�[���<?php

/*
 * This file is part of the Symfony package.
 *
 * (c) Fabien Potencier <fabien@symfony.com>
 *
 * For the full copyright and license information, please view the LICENSE
 * file that was distributed with this source code.
 */

namespace Symfony\Component\DependencyInjection\Tests\LazyProxy\Instantiator;

use Symfony\Component\DependencyInjection\Definition;
use Symfony\Component\DependencyInjection\LazyProxy\Instantiator\RealServiceInstantiator;

/**
 * Tests for {@see \Symfony\Component\DependencyInjection\Instantiator\RealServiceInstantiator}.
 *
 * @author Marco Pivetta <ocramius@gmail.com>
 */
class RealServiceInstantiatorTest extends \PHPUnit_Framework_TestCase
{
    public function testInstantiateProxy()
    {
        $instantiator = new RealServiceInstantiator();
        $instance = new \stdClass();
        $container = $this->getMockBuilder('Symfony\Component\DependencyInjection\ContainerInterface')->getMock();
        $callback = function () use ($instance) {
            return $instance;
        };

        $this->assertSame($instance, $instantiator->instantiateProxy($container, new Definition(), 'foo', $callback));
    }
}
PKϤ$Z��KMM,dependency-injection/Tests/ReferenceTest.phpnu�[���<?php

/*
 * This file is part of the Symfony package.
 *
 * (c) Fabien Potencier <fabien@symfony.com>
 *
 * For the full copyright and license information, please view the LICENSE
 * file that was distributed with this source code.
 */

namespace Symfony\Component\DependencyInjection\Tests;

use Symfony\Component\DependencyInjection\Reference;

class ReferenceTest extends \PHPUnit_Framework_TestCase
{
    public function testConstructor()
    {
        $ref = new Reference('foo');
        $this->assertEquals('foo', (string) $ref, '__construct() sets the id of the reference, which is used for the __toString() method');
    }

    public function testCaseInsensitive()
    {
        $ref = new Reference('FooBar');
        $this->assertEquals('foobar', (string) $ref, 'the id is lowercased as the container is case insensitive');
    }
}
PKϤ$ZZ�H�H�H�3dependency-injection/Tests/ContainerBuilderTest.phpnu�[���<?php

/*
 * This file is part of the Symfony package.
 *
 * (c) Fabien Potencier <fabien@symfony.com>
 *
 * For the full copyright and license information, please view the LICENSE
 * file that was distributed with this source code.
 */

namespace Symfony\Component\DependencyInjection\Tests;

require_once __DIR__.'/Fixtures/includes/classes.php';
require_once __DIR__.'/Fixtures/includes/ProjectExtension.php';

use Symfony\Component\Config\Resource\ResourceInterface;
use Symfony\Component\DependencyInjection\Alias;
use Symfony\Component\DependencyInjection\ContainerBuilder;
use Symfony\Component\DependencyInjection\ContainerInterface;
use Symfony\Component\DependencyInjection\Definition;
use Symfony\Component\DependencyInjection\DefinitionDecorator;
use Symfony\Component\DependencyInjection\Exception\RuntimeException;
use Symfony\Component\DependencyInjection\Exception\ServiceCircularReferenceException;
use Symfony\Component\DependencyInjection\Exception\ServiceNotFoundException;
use Symfony\Component\DependencyInjection\Loader\ClosureLoader;
use Symfony\Component\DependencyInjection\Reference;
use Symfony\Component\DependencyInjection\ParameterBag\ParameterBag;
use Symfony\Component\Config\Resource\FileResource;
use Symfony\Component\DependencyInjection\Tests\Fixtures\CustomDefinition;
use Symfony\Component\ExpressionLanguage\Expression;

class ContainerBuilderTest extends \PHPUnit_Framework_TestCase
{
    public function testDefinitions()
    {
        $builder = new ContainerBuilder();
        $definitions = array(
            'foo' => new Definition('Bar\FooClass'),
            'bar' => new Definition('BarClass'),
        );
        $builder->setDefinitions($definitions);
        $this->assertEquals($definitions, $builder->getDefinitions(), '->setDefinitions() sets the service definitions');
        $this->assertTrue($builder->hasDefinition('foo'), '->hasDefinition() returns true if a service definition exists');
        $this->assertFalse($builder->hasDefinition('foobar'), '->hasDefinition() returns false if a service definition does not exist');

        $builder->setDefinition('foobar', $foo = new Definition('FooBarClass'));
        $this->assertEquals($foo, $builder->getDefinition('foobar'), '->getDefinition() returns a service definition if defined');
        $this->assertTrue($builder->setDefinition('foobar', $foo = new Definition('FooBarClass')) === $foo, '->setDefinition() implements a fluid interface by returning the service reference');

        $builder->addDefinitions($defs = array('foobar' => new Definition('FooBarClass')));
        $this->assertEquals(array_merge($definitions, $defs), $builder->getDefinitions(), '->addDefinitions() adds the service definitions');

        try {
            $builder->getDefinition('baz');
            $this->fail('->getDefinition() throws a ServiceNotFoundException if the service definition does not exist');
        } catch (ServiceNotFoundException $e) {
            $this->assertEquals('You have requested a non-existent service "baz".', $e->getMessage(), '->getDefinition() throws a ServiceNotFoundException if the service definition does not exist');
        }
    }

    /**
     * @group legacy
     * @expectedDeprecation The "deprecated_foo" service is deprecated. You should stop using it, as it will soon be removed.
     */
    public function testCreateDeprecatedService()
    {
        $definition = new Definition('stdClass');
        $definition->setDeprecated(true);

        $builder = new ContainerBuilder();
        $builder->setDefinition('deprecated_foo', $definition);
        $builder->compile();
        $builder->get('deprecated_foo');
    }

    public function testRegister()
    {
        $builder = new ContainerBuilder();
        $builder->register('foo', 'Bar\FooClass');
        $this->assertTrue($builder->hasDefinition('foo'), '->register() registers a new service definition');
        $this->assertInstanceOf('Symfony\Component\DependencyInjection\Definition', $builder->getDefinition('foo'), '->register() returns the newly created Definition instance');
    }

    public function testHas()
    {
        $builder = new ContainerBuilder();
        $this->assertFalse($builder->has('foo'), '->has() returns false if the service does not exist');
        $builder->register('foo', 'Bar\FooClass');
        $this->assertTrue($builder->has('foo'), '->has() returns true if a service definition exists');
        $builder->set('bar', new \stdClass());
        $this->assertTrue($builder->has('bar'), '->has() returns true if a service exists');
    }

    public function testGet()
    {
        $builder = new ContainerBuilder();
        try {
            $builder->get('foo');
            $this->fail('->get() throws a ServiceNotFoundException if the service does not exist');
        } catch (ServiceNotFoundException $e) {
            $this->assertEquals('You have requested a non-existent service "foo".', $e->getMessage(), '->get() throws a ServiceNotFoundException if the service does not exist');
        }

        $this->assertNull($builder->get('foo', ContainerInterface::NULL_ON_INVALID_REFERENCE), '->get() returns null if the service does not exist and NULL_ON_INVALID_REFERENCE is passed as a second argument');

        $builder->register('foo', 'stdClass');
        $this->assertInternalType('object', $builder->get('foo'), '->get() returns the service definition associated with the id');
        $builder->set('bar', $bar = new \stdClass());
        $this->assertEquals($bar, $builder->get('bar'), '->get() returns the service associated with the id');
        $builder->register('bar', 'stdClass');
        $this->assertEquals($bar, $builder->get('bar'), '->get() returns the service associated with the id even if a definition has been defined');

        $builder->register('baz', 'stdClass')->setArguments(array(new Reference('baz')));
        try {
            @$builder->get('baz');
            $this->fail('->get() throws a ServiceCircularReferenceException if the service has a circular reference to itself');
        } catch (ServiceCircularReferenceException $e) {
            $this->assertEquals('Circular reference detected for service "baz", path: "baz".', $e->getMessage(), '->get() throws a LogicException if the service has a circular reference to itself');
        }

        $this->assertTrue($builder->get('bar') === $builder->get('bar'), '->get() always returns the same instance if the service is shared');
    }

    public function testNonSharedServicesReturnsDifferentInstances()
    {
        $builder = new ContainerBuilder();
        $builder->register('bar', 'stdClass')->setShared(false);

        $this->assertNotSame($builder->get('bar'), $builder->get('bar'));
    }

    /**
     * @expectedException        \Symfony\Component\DependencyInjection\Exception\RuntimeException
     * @expectedExceptionMessage You have requested a synthetic service ("foo"). The DIC does not know how to construct this service.
     */
    public function testGetUnsetLoadingServiceWhenCreateServiceThrowsAnException()
    {
        $builder = new ContainerBuilder();
        $builder->register('foo', 'stdClass')->setSynthetic(true);

        // we expect a RuntimeException here as foo is synthetic
        try {
            $builder->get('foo');
        } catch (RuntimeException $e) {
        }

        // we must also have the same RuntimeException here
        $builder->get('foo');
    }

    public function testGetServiceIds()
    {
        $builder = new ContainerBuilder();
        $builder->register('foo', 'stdClass');
        $builder->bar = $bar = new \stdClass();
        $builder->register('bar', 'stdClass');
        $this->assertEquals(array('foo', 'bar', 'service_container'), $builder->getServiceIds(), '->getServiceIds() returns all defined service ids');
    }

    public function testAliases()
    {
        $builder = new ContainerBuilder();
        $builder->register('foo', 'stdClass');
        $builder->setAlias('bar', 'foo');
        $this->assertTrue($builder->hasAlias('bar'), '->hasAlias() returns true if the alias exists');
        $this->assertFalse($builder->hasAlias('foobar'), '->hasAlias() returns false if the alias does not exist');
        $this->assertEquals('foo', (string) $builder->getAlias('bar'), '->getAlias() returns the aliased service');
        $this->assertTrue($builder->has('bar'), '->setAlias() defines a new service');
        $this->assertTrue($builder->get('bar') === $builder->get('foo'), '->setAlias() creates a service that is an alias to another one');

        try {
            $builder->setAlias('foobar', 'foobar');
            $this->fail('->setAlias() throws an InvalidArgumentException if the alias references itself');
        } catch (\InvalidArgumentException $e) {
            $this->assertEquals('An alias can not reference itself, got a circular reference on "foobar".', $e->getMessage(), '->setAlias() throws an InvalidArgumentException if the alias references itself');
        }

        try {
            $builder->getAlias('foobar');
            $this->fail('->getAlias() throws an InvalidArgumentException if the alias does not exist');
        } catch (\InvalidArgumentException $e) {
            $this->assertEquals('The service alias "foobar" does not exist.', $e->getMessage(), '->getAlias() throws an InvalidArgumentException if the alias does not exist');
        }
    }

    public function testGetAliases()
    {
        $builder = new ContainerBuilder();
        $builder->setAlias('bar', 'foo');
        $builder->setAlias('foobar', 'foo');
        $builder->setAlias('moo', new Alias('foo', false));

        $aliases = $builder->getAliases();
        $this->assertEquals('foo', (string) $aliases['bar']);
        $this->assertTrue($aliases['bar']->isPublic());
        $this->assertEquals('foo', (string) $aliases['foobar']);
        $this->assertEquals('foo', (string) $aliases['moo']);
        $this->assertFalse($aliases['moo']->isPublic());

        $builder->register('bar', 'stdClass');
        $this->assertFalse($builder->hasAlias('bar'));

        $builder->set('foobar', 'stdClass');
        $builder->set('moo', 'stdClass');
        $this->assertCount(0, $builder->getAliases(), '->getAliases() does not return aliased services that have been overridden');
    }

    public function testSetAliases()
    {
        $builder = new ContainerBuilder();
        $builder->setAliases(array('bar' => 'foo', 'foobar' => 'foo'));

        $aliases = $builder->getAliases();
        $this->assertTrue(isset($aliases['bar']));
        $this->assertTrue(isset($aliases['foobar']));
    }

    public function testAddAliases()
    {
        $builder = new ContainerBuilder();
        $builder->setAliases(array('bar' => 'foo'));
        $builder->addAliases(array('foobar' => 'foo'));

        $aliases = $builder->getAliases();
        $this->assertTrue(isset($aliases['bar']));
        $this->assertTrue(isset($aliases['foobar']));
    }

    public function testSetReplacesAlias()
    {
        $builder = new ContainerBuilder();
        $builder->setAlias('alias', 'aliased');
        $builder->set('aliased', new \stdClass());

        $builder->set('alias', $foo = new \stdClass());
        $this->assertSame($foo, $builder->get('alias'), '->set() replaces an existing alias');
    }

    public function testAliasesKeepInvalidBehavior()
    {
        $builder = new ContainerBuilder();

        $aliased = new Definition('stdClass');
        $aliased->addMethodCall('setBar', array(new Reference('bar', ContainerInterface::IGNORE_ON_INVALID_REFERENCE)));
        $builder->setDefinition('aliased', $aliased);
        $builder->setAlias('alias', 'aliased');

        $this->assertEquals(new \stdClass(), $builder->get('alias'));
    }

    public function testAddGetCompilerPass()
    {
        $builder = new ContainerBuilder();
        $builder->setResourceTracking(false);
        $builderCompilerPasses = $builder->getCompiler()->getPassConfig()->getPasses();
        $builder->addCompilerPass($this->getMockBuilder('Symfony\Component\DependencyInjection\Compiler\CompilerPassInterface')->getMock());

        $this->assertCount(count($builder->getCompiler()->getPassConfig()->getPasses()) - 1, $builderCompilerPasses);
    }

    public function testCreateService()
    {
        $builder = new ContainerBuilder();
        $builder->register('foo1', 'Bar\FooClass')->setFile(__DIR__.'/Fixtures/includes/foo.php');
        $this->assertInstanceOf('\Bar\FooClass', $builder->get('foo1'), '->createService() requires the file defined by the service definition');
        $builder->register('foo2', 'Bar\FooClass')->setFile(__DIR__.'/Fixtures/includes/%file%.php');
        $builder->setParameter('file', 'foo');
        $this->assertInstanceOf('\Bar\FooClass', $builder->get('foo2'), '->createService() replaces parameters in the file provided by the service definition');
    }

    public function testCreateProxyWithRealServiceInstantiator()
    {
        $builder = new ContainerBuilder();

        $builder->register('foo1', 'Bar\FooClass')->setFile(__DIR__.'/Fixtures/includes/foo.php');
        $builder->getDefinition('foo1')->setLazy(true);

        $foo1 = $builder->get('foo1');

        $this->assertSame($foo1, $builder->get('foo1'), 'The same proxy is retrieved on multiple subsequent calls');
        $this->assertSame('Bar\FooClass', get_class($foo1));
    }

    public function testCreateServiceClass()
    {
        $builder = new ContainerBuilder();
        $builder->register('foo1', '%class%');
        $builder->setParameter('class', 'stdClass');
        $this->assertInstanceOf('\stdClass', $builder->get('foo1'), '->createService() replaces parameters in the class provided by the service definition');
    }

    public function testCreateServiceArguments()
    {
        $builder = new ContainerBuilder();
        $builder->register('bar', 'stdClass');
        $builder->register('foo1', 'Bar\FooClass')->addArgument(array('foo' => '%value%', '%value%' => 'foo', new Reference('bar'), '%%unescape_it%%'));
        $builder->setParameter('value', 'bar');
        $this->assertEquals(array('foo' => 'bar', 'bar' => 'foo', $builder->get('bar'), '%unescape_it%'), $builder->get('foo1')->arguments, '->createService() replaces parameters and service references in the arguments provided by the service definition');
    }

    public function testCreateServiceFactory()
    {
        $builder = new ContainerBuilder();
        $builder->register('foo', 'Bar\FooClass')->setFactory('Bar\FooClass::getInstance');
        $builder->register('qux', 'Bar\FooClass')->setFactory(array('Bar\FooClass', 'getInstance'));
        $builder->register('bar', 'Bar\FooClass')->setFactory(array(new Definition('Bar\FooClass'), 'getInstance'));
        $builder->register('baz', 'Bar\FooClass')->setFactory(array(new Reference('bar'), 'getInstance'));

        $this->assertTrue($builder->get('foo')->called, '->createService() calls the factory method to create the service instance');
        $this->assertTrue($builder->get('qux')->called, '->createService() calls the factory method to create the service instance');
        $this->assertTrue($builder->get('bar')->called, '->createService() uses anonymous service as factory');
        $this->assertTrue($builder->get('baz')->called, '->createService() uses another service as factory');
    }

    public function testCreateServiceMethodCalls()
    {
        $builder = new ContainerBuilder();
        $builder->register('bar', 'stdClass');
        $builder->register('foo1', 'Bar\FooClass')->addMethodCall('setBar', array(array('%value%', new Reference('bar'))));
        $builder->setParameter('value', 'bar');
        $this->assertEquals(array('bar', $builder->get('bar')), $builder->get('foo1')->bar, '->createService() replaces the values in the method calls arguments');
    }

    public function testCreateServiceMethodCallsWithEscapedParam()
    {
        $builder = new ContainerBuilder();
        $builder->register('bar', 'stdClass');
        $builder->register('foo1', 'Bar\FooClass')->addMethodCall('setBar', array(array('%%unescape_it%%')));
        $builder->setParameter('value', 'bar');
        $this->assertEquals(array('%unescape_it%'), $builder->get('foo1')->bar, '->createService() replaces the values in the method calls arguments');
    }

    public function testCreateServiceProperties()
    {
        $builder = new ContainerBuilder();
        $builder->register('bar', 'stdClass');
        $builder->register('foo1', 'Bar\FooClass')->setProperty('bar', array('%value%', new Reference('bar'), '%%unescape_it%%'));
        $builder->setParameter('value', 'bar');
        $this->assertEquals(array('bar', $builder->get('bar'), '%unescape_it%'), $builder->get('foo1')->bar, '->createService() replaces the values in the properties');
    }

    public function testCreateServiceConfigurator()
    {
        $builder = new ContainerBuilder();
        $builder->register('foo1', 'Bar\FooClass')->setConfigurator('sc_configure');
        $this->assertTrue($builder->get('foo1')->configured, '->createService() calls the configurator');

        $builder->register('foo2', 'Bar\FooClass')->setConfigurator(array('%class%', 'configureStatic'));
        $builder->setParameter('class', 'BazClass');
        $this->assertTrue($builder->get('foo2')->configured, '->createService() calls the configurator');

        $builder->register('baz', 'BazClass');
        $builder->register('foo3', 'Bar\FooClass')->setConfigurator(array(new Reference('baz'), 'configure'));
        $this->assertTrue($builder->get('foo3')->configured, '->createService() calls the configurator');

        $builder->register('foo4', 'Bar\FooClass')->setConfigurator(array($builder->getDefinition('baz'), 'configure'));
        $this->assertTrue($builder->get('foo4')->configured, '->createService() calls the configurator');

        $builder->register('foo5', 'Bar\FooClass')->setConfigurator('foo');
        try {
            $builder->get('foo5');
            $this->fail('->createService() throws an InvalidArgumentException if the configure callable is not a valid callable');
        } catch (\InvalidArgumentException $e) {
            $this->assertEquals('The configure callable for class "Bar\FooClass" is not a callable.', $e->getMessage(), '->createService() throws an InvalidArgumentException if the configure callable is not a valid callable');
        }
    }

    /**
     * @expectedException \RuntimeException
     */
    public function testCreateSyntheticService()
    {
        $builder = new ContainerBuilder();
        $builder->register('foo', 'Bar\FooClass')->setSynthetic(true);
        $builder->get('foo');
    }

    public function testCreateServiceWithExpression()
    {
        $builder = new ContainerBuilder();
        $builder->setParameter('bar', 'bar');
        $builder->register('bar', 'BarClass');
        $builder->register('foo', 'Bar\FooClass')->addArgument(array('foo' => new Expression('service("bar").foo ~ parameter("bar")')));
        $this->assertEquals('foobar', $builder->get('foo')->arguments['foo']);
    }

    public function testResolveServices()
    {
        $builder = new ContainerBuilder();
        $builder->register('foo', 'Bar\FooClass');
        $this->assertEquals($builder->get('foo'), $builder->resolveServices(new Reference('foo')), '->resolveServices() resolves service references to service instances');
        $this->assertEquals(array('foo' => array('foo', $builder->get('foo'))), $builder->resolveServices(array('foo' => array('foo', new Reference('foo')))), '->resolveServices() resolves service references to service instances in nested arrays');
        $this->assertEquals($builder->get('foo'), $builder->resolveServices(new Expression('service("foo")')), '->resolveServices() resolves expressions');
    }

    /**
     * @expectedException \Symfony\Component\DependencyInjection\Exception\RuntimeException
     * @expectedExceptionMessage Constructing service "foo" from a parent definition is not supported at build time.
     */
    public function testResolveServicesWithDecoratedDefinition()
    {
        $builder = new ContainerBuilder();
        $builder->setDefinition('grandpa', new Definition('stdClass'));
        $builder->setDefinition('parent', new DefinitionDecorator('grandpa'));
        $builder->setDefinition('foo', new DefinitionDecorator('parent'));

        $builder->get('foo');
    }

    public function testResolveServicesWithCustomDefinitionClass()
    {
        $builder = new ContainerBuilder();
        $builder->setDefinition('foo', new CustomDefinition('stdClass'));

        $this->assertInstanceOf('stdClass', $builder->get('foo'));
    }

    public function testMerge()
    {
        $container = new ContainerBuilder(new ParameterBag(array('bar' => 'foo')));
        $container->setResourceTracking(false);
        $config = new ContainerBuilder(new ParameterBag(array('foo' => 'bar')));
        $container->merge($config);
        $this->assertEquals(array('bar' => 'foo', 'foo' => 'bar'), $container->getParameterBag()->all(), '->merge() merges current parameters with the loaded ones');

        $container = new ContainerBuilder(new ParameterBag(array('bar' => 'foo')));
        $container->setResourceTracking(false);
        $config = new ContainerBuilder(new ParameterBag(array('foo' => '%bar%')));
        $container->merge($config);
        $container->compile();
        $this->assertEquals(array('bar' => 'foo', 'foo' => 'foo'), $container->getParameterBag()->all(), '->merge() evaluates the values of the parameters towards already defined ones');

        $container = new ContainerBuilder(new ParameterBag(array('bar' => 'foo')));
        $container->setResourceTracking(false);
        $config = new ContainerBuilder(new ParameterBag(array('foo' => '%bar%', 'baz' => '%foo%')));
        $container->merge($config);
        $container->compile();
        $this->assertEquals(array('bar' => 'foo', 'foo' => 'foo', 'baz' => 'foo'), $container->getParameterBag()->all(), '->merge() evaluates the values of the parameters towards already defined ones');

        $container = new ContainerBuilder();
        $container->setResourceTracking(false);
        $container->register('foo', 'Bar\FooClass');
        $container->register('bar', 'BarClass');
        $config = new ContainerBuilder();
        $config->setDefinition('baz', new Definition('BazClass'));
        $config->setAlias('alias_for_foo', 'foo');
        $container->merge($config);
        $this->assertEquals(array('foo', 'bar', 'baz'), array_keys($container->getDefinitions()), '->merge() merges definitions already defined ones');

        $aliases = $container->getAliases();
        $this->assertTrue(isset($aliases['alias_for_foo']));
        $this->assertEquals('foo', (string) $aliases['alias_for_foo']);

        $container = new ContainerBuilder();
        $container->setResourceTracking(false);
        $container->register('foo', 'Bar\FooClass');
        $config->setDefinition('foo', new Definition('BazClass'));
        $container->merge($config);
        $this->assertEquals('BazClass', $container->getDefinition('foo')->getClass(), '->merge() overrides already defined services');
    }

    /**
     * @expectedException \LogicException
     */
    public function testMergeLogicException()
    {
        $container = new ContainerBuilder();
        $container->setResourceTracking(false);
        $container->compile();
        $container->merge(new ContainerBuilder());
    }

    public function testfindTaggedServiceIds()
    {
        $builder = new ContainerBuilder();
        $builder
            ->register('foo', 'Bar\FooClass')
            ->addTag('foo', array('foo' => 'foo'))
            ->addTag('bar', array('bar' => 'bar'))
            ->addTag('foo', array('foofoo' => 'foofoo'))
        ;
        $this->assertEquals($builder->findTaggedServiceIds('foo'), array(
            'foo' => array(
                array('foo' => 'foo'),
                array('foofoo' => 'foofoo'),
            ),
        ), '->findTaggedServiceIds() returns an array of service ids and its tag attributes');
        $this->assertEquals(array(), $builder->findTaggedServiceIds('foobar'), '->findTaggedServiceIds() returns an empty array if there is annotated services');
    }

    public function testFindUnusedTags()
    {
        $builder = new ContainerBuilder();
        $builder
            ->register('foo', 'Bar\FooClass')
            ->addTag('kernel.event_listener', array('foo' => 'foo'))
            ->addTag('kenrel.event_listener', array('bar' => 'bar'))
        ;
        $builder->findTaggedServiceIds('kernel.event_listener');
        $this->assertEquals(array('kenrel.event_listener'), $builder->findUnusedTags(), '->findUnusedTags() returns an array with unused tags');
    }

    public function testFindDefinition()
    {
        $container = new ContainerBuilder();
        $container->setDefinition('foo', $definition = new Definition('Bar\FooClass'));
        $container->setAlias('bar', 'foo');
        $container->setAlias('foobar', 'bar');
        $this->assertEquals($definition, $container->findDefinition('foobar'), '->findDefinition() returns a Definition');
    }

    public function testAddObjectResource()
    {
        $container = new ContainerBuilder();

        $container->setResourceTracking(false);
        $container->addObjectResource(new \BarClass());

        $this->assertEmpty($container->getResources(), 'No resources get registered without resource tracking');

        $container->setResourceTracking(true);
        $container->addObjectResource(new \BarClass());

        $resources = $container->getResources();

        $this->assertCount(1, $resources, '1 resource was registered');

        /* @var $resource \Symfony\Component\Config\Resource\FileResource */
        $resource = end($resources);

        $this->assertInstanceOf('Symfony\Component\Config\Resource\FileResource', $resource);
        $this->assertSame(realpath(__DIR__.'/Fixtures/includes/classes.php'), realpath($resource->getResource()));
    }

    public function testAddClassResource()
    {
        $container = new ContainerBuilder();

        $container->setResourceTracking(false);
        $container->addClassResource(new \ReflectionClass('BarClass'));

        $this->assertEmpty($container->getResources(), 'No resources get registered without resource tracking');

        $container->setResourceTracking(true);
        $container->addClassResource(new \ReflectionClass('BarClass'));

        $resources = $container->getResources();

        $this->assertCount(1, $resources, '1 resource was registered');

        /* @var $resource \Symfony\Component\Config\Resource\FileResource */
        $resource = end($resources);

        $this->assertInstanceOf('Symfony\Component\Config\Resource\FileResource', $resource);
        $this->assertSame(realpath(__DIR__.'/Fixtures/includes/classes.php'), realpath($resource->getResource()));
    }

    public function testCompilesClassDefinitionsOfLazyServices()
    {
        $container = new ContainerBuilder();

        $this->assertEmpty($container->getResources(), 'No resources get registered without resource tracking');

        $container->register('foo', 'BarClass');
        $container->getDefinition('foo')->setLazy(true);

        $container->compile();

        $classesPath = realpath(__DIR__.'/Fixtures/includes/classes.php');
        $matchingResources = array_filter(
            $container->getResources(),
            function (ResourceInterface $resource) use ($classesPath) {
                return $resource instanceof FileResource && $classesPath === realpath($resource->getResource());
            }
        );

        $this->assertNotEmpty($matchingResources);
    }

    public function testResources()
    {
        $container = new ContainerBuilder();
        $container->addResource($a = new FileResource(__DIR__.'/Fixtures/xml/services1.xml'));
        $container->addResource($b = new FileResource(__DIR__.'/Fixtures/xml/services2.xml'));
        $resources = array();
        foreach ($container->getResources() as $resource) {
            if (false === strpos($resource, '.php')) {
                $resources[] = $resource;
            }
        }
        $this->assertEquals(array($a, $b), $resources, '->getResources() returns an array of resources read for the current configuration');
        $this->assertSame($container, $container->setResources(array()));
        $this->assertEquals(array(), $container->getResources());
    }

    public function testExtension()
    {
        $container = new ContainerBuilder();
        $container->setResourceTracking(false);

        $container->registerExtension($extension = new \ProjectExtension());
        $this->assertTrue($container->getExtension('project') === $extension, '->registerExtension() registers an extension');

        $this->setExpectedException('LogicException');
        $container->getExtension('no_registered');
    }

    public function testRegisteredButNotLoadedExtension()
    {
        $extension = $this->getMockBuilder('Symfony\\Component\\DependencyInjection\\Extension\\ExtensionInterface')->getMock();
        $extension->expects($this->once())->method('getAlias')->will($this->returnValue('project'));
        $extension->expects($this->never())->method('load');

        $container = new ContainerBuilder();
        $container->setResourceTracking(false);
        $container->registerExtension($extension);
        $container->compile();
    }

    public function testRegisteredAndLoadedExtension()
    {
        $extension = $this->getMockBuilder('Symfony\\Component\\DependencyInjection\\Extension\\ExtensionInterface')->getMock();
        $extension->expects($this->exactly(2))->method('getAlias')->will($this->returnValue('project'));
        $extension->expects($this->once())->method('load')->with(array(array('foo' => 'bar')));

        $container = new ContainerBuilder();
        $container->setResourceTracking(false);
        $container->registerExtension($extension);
        $container->loadFromExtension('project', array('foo' => 'bar'));
        $container->compile();
    }

    public function testPrivateServiceUser()
    {
        $fooDefinition = new Definition('BarClass');
        $fooUserDefinition = new Definition('BarUserClass', array(new Reference('bar')));
        $container = new ContainerBuilder();
        $container->setResourceTracking(false);

        $fooDefinition->setPublic(false);

        $container->addDefinitions(array(
            'bar' => $fooDefinition,
            'bar_user' => $fooUserDefinition,
        ));

        $container->compile();
        $this->assertInstanceOf('BarClass', $container->get('bar_user')->bar);
    }

    /**
     * @expectedException \BadMethodCallException
     */
    public function testThrowsExceptionWhenSetServiceOnAFrozenContainer()
    {
        $container = new ContainerBuilder();
        $container->setResourceTracking(false);
        $container->setDefinition('a', new Definition('stdClass'));
        $container->compile();
        $container->set('a', new \stdClass());
    }

    public function testThrowsExceptionWhenAddServiceOnAFrozenContainer()
    {
        $container = new ContainerBuilder();
        $container->compile();
        $container->set('a', $foo = new \stdClass());
        $this->assertSame($foo, $container->get('a'));
    }

    public function testNoExceptionWhenSetSyntheticServiceOnAFrozenContainer()
    {
        $container = new ContainerBuilder();
        $def = new Definition('stdClass');
        $def->setSynthetic(true);
        $container->setDefinition('a', $def);
        $container->compile();
        $container->set('a', $a = new \stdClass());
        $this->assertEquals($a, $container->get('a'));
    }

    /**
     * @expectedException \BadMethodCallException
     */
    public function testThrowsExceptionWhenSetDefinitionOnAFrozenContainer()
    {
        $container = new ContainerBuilder();
        $container->setResourceTracking(false);
        $container->compile();
        $container->setDefinition('a', new Definition());
    }

    public function testExtensionConfig()
    {
        $container = new ContainerBuilder();

        $configs = $container->getExtensionConfig('foo');
        $this->assertEmpty($configs);

        $first = array('foo' => 'bar');
        $container->prependExtensionConfig('foo', $first);
        $configs = $container->getExtensionConfig('foo');
        $this->assertEquals(array($first), $configs);

        $second = array('ding' => 'dong');
        $container->prependExtensionConfig('foo', $second);
        $configs = $container->getExtensionConfig('foo');
        $this->assertEquals(array($second, $first), $configs);
    }

    public function testAbstractAlias()
    {
        $container = new ContainerBuilder();

        $abstract = new Definition('AbstractClass');
        $abstract->setAbstract(true);

        $container->setDefinition('abstract_service', $abstract);
        $container->setAlias('abstract_alias', 'abstract_service');

        $container->compile();

        $this->assertSame('abstract_service', (string) $container->getAlias('abstract_alias'));
    }

    public function testLazyLoadedService()
    {
        $loader = new ClosureLoader($container = new ContainerBuilder());
        $loader->load(function (ContainerBuilder $container) {
            $container->set('a', new \BazClass());
            $definition = new Definition('BazClass');
            $definition->setLazy(true);
            $container->setDefinition('a', $definition);
        });

        $container->setResourceTracking(true);

        $container->compile();

        $class = new \BazClass();
        $reflectionClass = new \ReflectionClass($class);

        $r = new \ReflectionProperty($container, 'resources');
        $r->setAccessible(true);
        $resources = $r->getValue($container);

        $classInList = false;
        foreach ($resources as $resource) {
            if ($resource->getResource() === $reflectionClass->getFileName()) {
                $classInList = true;
                break;
            }
        }

        $this->assertTrue($classInList);
    }

    public function testInitializePropertiesBeforeMethodCalls()
    {
        $container = new ContainerBuilder();
        $container->register('foo', 'stdClass');
        $container->register('bar', 'MethodCallClass')
            ->setProperty('simple', 'bar')
            ->setProperty('complex', new Reference('foo'))
            ->addMethodCall('callMe');

        $container->compile();

        $this->assertTrue($container->get('bar')->callPassed(), '->compile() initializes properties before method calls');
    }

    public function testAutowiring()
    {
        $container = new ContainerBuilder();

        $container->register('a', __NAMESPACE__.'\A');
        $bDefinition = $container->register('b', __NAMESPACE__.'\B');
        $bDefinition->setAutowired(true);

        $container->compile();

        $this->assertEquals('a', (string) $container->getDefinition('b')->getArgument(0));
    }
}

class FooClass
{
}

class A
{
}

class B
{
    public function __construct(A $a)
    {
    }
}
PKϤ$Z��W��9�9"dependency-injection/Container.phpnu�[���<?php

/*
 * This file is part of the Symfony package.
 *
 * (c) Fabien Potencier <fabien@symfony.com>
 *
 * For the full copyright and license information, please view the LICENSE
 * file that was distributed with this source code.
 */

namespace Symfony\Component\DependencyInjection;

use Symfony\Component\DependencyInjection\Argument\RewindableGenerator;
use Symfony\Component\DependencyInjection\Argument\ServiceLocator as ArgumentServiceLocator;
use Symfony\Component\DependencyInjection\Exception\EnvNotFoundException;
use Symfony\Component\DependencyInjection\Exception\InvalidArgumentException;
use Symfony\Component\DependencyInjection\Exception\ParameterCircularReferenceException;
use Symfony\Component\DependencyInjection\Exception\RuntimeException;
use Symfony\Component\DependencyInjection\Exception\ServiceCircularReferenceException;
use Symfony\Component\DependencyInjection\Exception\ServiceNotFoundException;
use Symfony\Component\DependencyInjection\ParameterBag\EnvPlaceholderParameterBag;
use Symfony\Component\DependencyInjection\ParameterBag\FrozenParameterBag;
use Symfony\Component\DependencyInjection\ParameterBag\ParameterBagInterface;
use Symfony\Contracts\Service\ResetInterface;

// Help opcache.preload discover always-needed symbols
class_exists(RewindableGenerator::class);
class_exists(ArgumentServiceLocator::class);

/**
 * Container is a dependency injection container.
 *
 * It gives access to object instances (services).
 * Services and parameters are simple key/pair stores.
 * The container can have four possible behaviors when a service
 * does not exist (or is not initialized for the last case):
 *
 *  * EXCEPTION_ON_INVALID_REFERENCE: Throws an exception (the default)
 *  * NULL_ON_INVALID_REFERENCE:      Returns null
 *  * IGNORE_ON_INVALID_REFERENCE:    Ignores the wrapping command asking for the reference
 *                                    (for instance, ignore a setter if the service does not exist)
 *  * IGNORE_ON_UNINITIALIZED_REFERENCE: Ignores/returns null for uninitialized services or invalid references
 *
 * @author Fabien Potencier <fabien@symfony.com>
 * @author Johannes M. Schmitt <schmittjoh@gmail.com>
 */
class Container implements ContainerInterface, ResetInterface
{
    protected $parameterBag;
    protected $services = [];
    protected $privates = [];
    protected $fileMap = [];
    protected $methodMap = [];
    protected $factories = [];
    protected $aliases = [];
    protected $loading = [];
    protected $resolving = [];
    protected $syntheticIds = [];

    private $envCache = [];
    private $compiled = false;
    private $getEnv;

    public function __construct(ParameterBagInterface $parameterBag = null)
    {
        $this->parameterBag = $parameterBag ?: new EnvPlaceholderParameterBag();
    }

    /**
     * Compiles the container.
     *
     * This method does two things:
     *
     *  * Parameter values are resolved;
     *  * The parameter bag is frozen.
     */
    public function compile()
    {
        $this->parameterBag->resolve();

        $this->parameterBag = new FrozenParameterBag($this->parameterBag->all());

        $this->compiled = true;
    }

    /**
     * Returns true if the container is compiled.
     *
     * @return bool
     */
    public function isCompiled()
    {
        return $this->compiled;
    }

    /**
     * Gets the service container parameter bag.
     *
     * @return ParameterBagInterface A ParameterBagInterface instance
     */
    public function getParameterBag()
    {
        return $this->parameterBag;
    }

    /**
     * Gets a parameter.
     *
     * @param string $name The parameter name
     *
     * @return mixed The parameter value
     *
     * @throws InvalidArgumentException if the parameter is not defined
     */
    public function getParameter(string $name)
    {
        return $this->parameterBag->get($name);
    }

    /**
     * Checks if a parameter exists.
     *
     * @param string $name The parameter name
     *
     * @return bool The presence of parameter in container
     */
    public function hasParameter(string $name)
    {
        return $this->parameterBag->has($name);
    }

    /**
     * Sets a parameter.
     *
     * @param string $name  The parameter name
     * @param mixed  $value The parameter value
     */
    public function setParameter(string $name, $value)
    {
        $this->parameterBag->set($name, $value);
    }

    /**
     * Sets a service.
     *
     * Setting a synthetic service to null resets it: has() returns false and get()
     * behaves in the same way as if the service was never created.
     */
    public function set(string $id, ?object $service)
    {
        // Runs the internal initializer; used by the dumped container to include always-needed files
        if (isset($this->privates['service_container']) && $this->privates['service_container'] instanceof \Closure) {
            $initialize = $this->privates['service_container'];
            unset($this->privates['service_container']);
            $initialize();
        }

        if ('service_container' === $id) {
            throw new InvalidArgumentException('You cannot set service "service_container".');
        }

        if (!(isset($this->fileMap[$id]) || isset($this->methodMap[$id]))) {
            if (isset($this->syntheticIds[$id]) || !isset($this->getRemovedIds()[$id])) {
                // no-op
            } elseif (null === $service) {
                throw new InvalidArgumentException(sprintf('The "%s" service is private, you cannot unset it.', $id));
            } else {
                throw new InvalidArgumentException(sprintf('The "%s" service is private, you cannot replace it.', $id));
            }
        } elseif (isset($this->services[$id])) {
            throw new InvalidArgumentException(sprintf('The "%s" service is already initialized, you cannot replace it.', $id));
        }

        if (isset($this->aliases[$id])) {
            unset($this->aliases[$id]);
        }

        if (null === $service) {
            unset($this->services[$id]);

            return;
        }

        $this->services[$id] = $service;
    }

    /**
     * Returns true if the given service is defined.
     *
     * @param string $id The service identifier
     *
     * @return bool true if the service is defined, false otherwise
     */
    public function has($id)
    {
        if (isset($this->aliases[$id])) {
            $id = $this->aliases[$id];
        }
        if (isset($this->services[$id])) {
            return true;
        }
        if ('service_container' === $id) {
            return true;
        }

        return isset($this->fileMap[$id]) || isset($this->methodMap[$id]);
    }

    /**
     * Gets a service.
     *
     * @param string $id              The service identifier
     * @param int    $invalidBehavior The behavior when the service does not exist
     *
     * @return object|null The associated service
     *
     * @throws ServiceCircularReferenceException When a circular reference is detected
     * @throws ServiceNotFoundException          When the service is not defined
     * @throws \Exception                        if an exception has been thrown when the service has been resolved
     *
     * @see Reference
     */
    public function get($id, int $invalidBehavior = /* self::EXCEPTION_ON_INVALID_REFERENCE */ 1)
    {
        return $this->services[$id]
            ?? $this->services[$id = $this->aliases[$id] ?? $id]
            ?? ('service_container' === $id ? $this : ($this->factories[$id] ?? [$this, 'make'])($id, $invalidBehavior));
    }

    /**
     * Creates a service.
     *
     * As a separate method to allow "get()" to use the really fast `??` operator.
     */
    private function make(string $id, int $invalidBehavior)
    {
        if (isset($this->loading[$id])) {
            throw new ServiceCircularReferenceException($id, array_merge(array_keys($this->loading), [$id]));
        }

        $this->loading[$id] = true;

        try {
            if (isset($this->fileMap[$id])) {
                return /* self::IGNORE_ON_UNINITIALIZED_REFERENCE */ 4 === $invalidBehavior ? null : $this->load($this->fileMap[$id]);
            } elseif (isset($this->methodMap[$id])) {
                return /* self::IGNORE_ON_UNINITIALIZED_REFERENCE */ 4 === $invalidBehavior ? null : $this->{$this->methodMap[$id]}();
            }
        } catch (\Exception $e) {
            unset($this->services[$id]);

            throw $e;
        } finally {
            unset($this->loading[$id]);
        }

        if (/* self::EXCEPTION_ON_INVALID_REFERENCE */ 1 === $invalidBehavior) {
            if (!$id) {
                throw new ServiceNotFoundException($id);
            }
            if (isset($this->syntheticIds[$id])) {
                throw new ServiceNotFoundException($id, null, null, [], sprintf('The "%s" service is synthetic, it needs to be set at boot time before it can be used.', $id));
            }
            if (isset($this->getRemovedIds()[$id])) {
                throw new ServiceNotFoundException($id, null, null, [], sprintf('The "%s" service or alias has been removed or inlined when the container was compiled. You should either make it public, or stop using the container directly and use dependency injection instead.', $id));
            }

            $alternatives = [];
            foreach ($this->getServiceIds() as $knownId) {
                if ('' === $knownId || '.' === $knownId[0]) {
                    continue;
                }
                $lev = levenshtein($id, $knownId);
                if ($lev <= \strlen($id) / 3 || false !== strpos($knownId, $id)) {
                    $alternatives[] = $knownId;
                }
            }

            throw new ServiceNotFoundException($id, null, null, $alternatives);
        }

        return null;
    }

    /**
     * Returns true if the given service has actually been initialized.
     *
     * @param string $id The service identifier
     *
     * @return bool true if service has already been initialized, false otherwise
     */
    public function initialized(string $id)
    {
        if (isset($this->aliases[$id])) {
            $id = $this->aliases[$id];
        }

        if ('service_container' === $id) {
            return false;
        }

        return isset($this->services[$id]);
    }

    /**
     * {@inheritdoc}
     */
    public function reset()
    {
        $services = $this->services + $this->privates;
        $this->services = $this->factories = $this->privates = [];

        foreach ($services as $service) {
            try {
                if ($service instanceof ResetInterface) {
                    $service->reset();
                }
            } catch (\Throwable $e) {
                continue;
            }
        }
    }

    /**
     * Gets all service ids.
     *
     * @return string[] An array of all defined service ids
     */
    public function getServiceIds()
    {
        return array_map('strval', array_unique(array_merge(['service_container'], array_keys($this->fileMap), array_keys($this->methodMap), array_keys($this->aliases), array_keys($this->services))));
    }

    /**
     * Gets service ids that existed at compile time.
     *
     * @return array
     */
    public function getRemovedIds()
    {
        return [];
    }

    /**
     * Camelizes a string.
     *
     * @param string $id A string to camelize
     *
     * @return string The camelized string
     */
    public static function camelize($id)
    {
        return strtr(ucwords(strtr($id, ['_' => ' ', '.' => '_ ', '\\' => '_ '])), [' ' => '']);
    }

    /**
     * A string to underscore.
     *
     * @param string $id The string to underscore
     *
     * @return string The underscored string
     */
    public static function underscore($id)
    {
        return strtolower(preg_replace(['/([A-Z]+)([A-Z][a-z])/', '/([a-z\d])([A-Z])/'], ['\\1_\\2', '\\1_\\2'], str_replace('_', '.', $id)));
    }

    /**
     * Creates a service by requiring its factory file.
     */
    protected function load($file)
    {
        return require $file;
    }

    /**
     * Fetches a variable from the environment.
     *
     * @param string $name The name of the environment variable
     *
     * @return mixed The value to use for the provided environment variable name
     *
     * @throws EnvNotFoundException When the environment variable is not found and has no default value
     */
    protected function getEnv($name)
    {
        if (isset($this->resolving[$envName = "env($name)"])) {
            throw new ParameterCircularReferenceException(array_keys($this->resolving));
        }
        if (isset($this->envCache[$name]) || \array_key_exists($name, $this->envCache)) {
            return $this->envCache[$name];
        }
        if (!$this->has($id = 'container.env_var_processors_locator')) {
            $this->set($id, new ServiceLocator([]));
        }
        if (!$this->getEnv) {
            $this->getEnv = new \ReflectionMethod($this, __FUNCTION__);
            $this->getEnv->setAccessible(true);
            $this->getEnv = $this->getEnv->getClosure($this);
        }
        $processors = $this->get($id);

        if (false !== $i = strpos($name, ':')) {
            $prefix = substr($name, 0, $i);
            $localName = substr($name, 1 + $i);
        } else {
            $prefix = 'string';
            $localName = $name;
        }
        $processor = $processors->has($prefix) ? $processors->get($prefix) : new EnvVarProcessor($this);

        $this->resolving[$envName] = true;
        try {
            return $this->envCache[$name] = $processor->getEnv($prefix, $localName, $this->getEnv);
        } finally {
            unset($this->resolving[$envName]);
        }
    }

    /**
     * @param string|false $registry
     * @param string|bool  $load
     *
     * @return mixed
     *
     * @internal
     */
    final protected function getService($registry, string $id, ?string $method, $load)
    {
        if ('service_container' === $id) {
            return $this;
        }
        if (\is_string($load)) {
            throw new RuntimeException($load);
        }
        if (null === $method) {
            return false !== $registry ? $this->{$registry}[$id] ?? null : null;
        }
        if (false !== $registry) {
            return $this->{$registry}[$id] ?? $this->{$registry}[$id] = $load ? $this->load($method) : $this->{$method}();
        }
        if (!$load) {
            return $this->{$method}();
        }

        return ($factory = $this->factories[$id] ?? $this->factories['service_container'][$id] ?? null) ? $factory() : $this->load($method);
    }

    private function __clone()
    {
    }
}
PKϤ$Z
VjWW,dependency-injection/ContainerAwareTrait.phpnu�[���<?php

/*
 * This file is part of the Symfony package.
 *
 * (c) Fabien Potencier <fabien@symfony.com>
 *
 * For the full copyright and license information, please view the LICENSE
 * file that was distributed with this source code.
 */

namespace Symfony\Component\DependencyInjection;

/**
 * ContainerAware trait.
 *
 * @author Fabien Potencier <fabien@symfony.com>
 */
trait ContainerAwareTrait
{
    /**
     * @var ContainerInterface
     */
    protected $container;

    public function setContainer(ContainerInterface $container = null)
    {
        $this->container = $container;
    }
}
PKϤ$Z�����"dependency-injection/Parameter.phpnu�[���<?php

/*
 * This file is part of the Symfony package.
 *
 * (c) Fabien Potencier <fabien@symfony.com>
 *
 * For the full copyright and license information, please view the LICENSE
 * file that was distributed with this source code.
 */

namespace Symfony\Component\DependencyInjection;

/**
 * Parameter represents a parameter reference.
 *
 * @author Fabien Potencier <fabien@symfony.com>
 */
class Parameter
{
    private $id;

    public function __construct(string $id)
    {
        $this->id = $id;
    }

    /**
     * @return string The parameter key
     */
    public function __toString()
    {
        return $this->id;
    }
}
PKϤ$Zpn����!dependency-injection/Variable.phpnu�[���<?php

/*
 * This file is part of the Symfony package.
 *
 * (c) Fabien Potencier <fabien@symfony.com>
 *
 * For the full copyright and license information, please view the LICENSE
 * file that was distributed with this source code.
 */

namespace Symfony\Component\DependencyInjection;

/**
 * Represents a variable.
 *
 *     $var = new Variable('a');
 *
 * will be dumped as
 *
 *     $a
 *
 * by the PHP dumper.
 *
 * @author Johannes M. Schmitt <schmittjoh@gmail.com>
 */
class Variable
{
    private $name;

    public function __construct(string $name)
    {
        $this->name = $name;
    }

    /**
     * @return string
     */
    public function __toString()
    {
        return $this->name;
    }
}
PKϤ$Z�-3D��dependency-injection/Alias.phpnu�[���<?php

/*
 * This file is part of the Symfony package.
 *
 * (c) Fabien Potencier <fabien@symfony.com>
 *
 * For the full copyright and license information, please view the LICENSE
 * file that was distributed with this source code.
 */

namespace Symfony\Component\DependencyInjection;

use Symfony\Component\DependencyInjection\Exception\InvalidArgumentException;

class Alias
{
    private $id;
    private $public;
    private $private;
    private $deprecation = [];

    private static $defaultDeprecationTemplate = 'The "%alias_id%" service alias is deprecated. You should stop using it, as it will be removed in the future.';

    public function __construct(string $id, bool $public = true)
    {
        $this->id = $id;
        $this->public = $public;
        $this->private = 2 > \func_num_args();
    }

    /**
     * Checks if this DI Alias should be public or not.
     *
     * @return bool
     */
    public function isPublic()
    {
        return $this->public;
    }

    /**
     * Sets if this Alias is public.
     *
     * @return $this
     */
    public function setPublic(bool $boolean)
    {
        $this->public = $boolean;
        $this->private = false;

        return $this;
    }

    /**
     * Sets if this Alias is private.
     *
     * When set, the "private" state has a higher precedence than "public".
     * In version 3.4, a "private" alias always remains publicly accessible,
     * but triggers a deprecation notice when accessed from the container,
     * so that the alias can be made really private in 4.0.
     *
     * @return $this
     */
    public function setPrivate(bool $boolean)
    {
        $this->private = $boolean;

        return $this;
    }

    /**
     * Whether this alias is private.
     *
     * @return bool
     */
    public function isPrivate()
    {
        return $this->private;
    }

    /**
     * Whether this alias is deprecated, that means it should not be referenced
     * anymore.
     *
     * @param string $package The name of the composer package that is triggering the deprecation
     * @param string $version The version of the package that introduced the deprecation
     * @param string $message The deprecation message to use
     *
     * @return $this
     *
     * @throws InvalidArgumentException when the message template is invalid
     */
    public function setDeprecated(/* string $package, string $version, string $message */)
    {
        $args = \func_get_args();

        if (\func_num_args() < 3) {
            trigger_deprecation('symfony/dependency-injection', '5.1', 'The signature of method "%s()" requires 3 arguments: "string $package, string $version, string $message", not defining them is deprecated.', __METHOD__);

            $status = $args[0] ?? true;

            if (!$status) {
                trigger_deprecation('symfony/dependency-injection', '5.1', 'Passing a null message to un-deprecate a node is deprecated.');
            }

            $message = (string) ($args[1] ?? null);
            $package = $version = '';
        } else {
            $status = true;
            $package = (string) $args[0];
            $version = (string) $args[1];
            $message = (string) $args[2];
        }

        if ('' !== $message) {
            if (preg_match('#[\r\n]|\*/#', $message)) {
                throw new InvalidArgumentException('Invalid characters found in deprecation template.');
            }

            if (false === strpos($message, '%alias_id%')) {
                throw new InvalidArgumentException('The deprecation template must contain the "%alias_id%" placeholder.');
            }
        }

        $this->deprecation = $status ? ['package' => $package, 'version' => $version, 'message' => $message ?: self::$defaultDeprecationTemplate] : [];

        return $this;
    }

    public function isDeprecated(): bool
    {
        return (bool) $this->deprecation;
    }

    /**
     * @deprecated since Symfony 5.1, use "getDeprecation()" instead.
     */
    public function getDeprecationMessage(string $id): string
    {
        trigger_deprecation('symfony/dependency-injection', '5.1', 'The "%s()" method is deprecated, use "getDeprecation()" instead.', __METHOD__);

        return $this->getDeprecation($id)['message'];
    }

    /**
     * @param string $id Service id relying on this definition
     */
    public function getDeprecation(string $id): array
    {
        return [
            'package' => $this->deprecation['package'],
            'version' => $this->deprecation['version'],
            'message' => str_replace('%alias_id%', $id, $this->deprecation['message']),
        ];
    }

    /**
     * Returns the Id of this alias.
     *
     * @return string The alias id
     */
    public function __toString()
    {
        return $this->id;
    }
}
PKϤ$ZW}dAA,dependency-injection/Extension/Extension.phpnu�[���<?php

/*
 * This file is part of the Symfony package.
 *
 * (c) Fabien Potencier <fabien@symfony.com>
 *
 * For the full copyright and license information, please view the LICENSE
 * file that was distributed with this source code.
 */

namespace Symfony\Component\DependencyInjection\Extension;

use Symfony\Component\Config\Definition\ConfigurationInterface;
use Symfony\Component\Config\Definition\Processor;
use Symfony\Component\DependencyInjection\Container;
use Symfony\Component\DependencyInjection\ContainerBuilder;
use Symfony\Component\DependencyInjection\Exception\BadMethodCallException;
use Symfony\Component\DependencyInjection\Exception\InvalidArgumentException;
use Symfony\Component\DependencyInjection\Exception\LogicException;

/**
 * Provides useful features shared by many extensions.
 *
 * @author Fabien Potencier <fabien@symfony.com>
 */
abstract class Extension implements ExtensionInterface, ConfigurationExtensionInterface
{
    private $processedConfigs = [];

    /**
     * {@inheritdoc}
     */
    public function getXsdValidationBasePath()
    {
        return false;
    }

    /**
     * {@inheritdoc}
     */
    public function getNamespace()
    {
        return 'http://example.org/schema/dic/'.$this->getAlias();
    }

    /**
     * Returns the recommended alias to use in XML.
     *
     * This alias is also the mandatory prefix to use when using YAML.
     *
     * This convention is to remove the "Extension" postfix from the class
     * name and then lowercase and underscore the result. So:
     *
     *     AcmeHelloExtension
     *
     * becomes
     *
     *     acme_hello
     *
     * This can be overridden in a sub-class to specify the alias manually.
     *
     * @return string The alias
     *
     * @throws BadMethodCallException When the extension name does not follow conventions
     */
    public function getAlias()
    {
        $className = static::class;
        if ('Extension' != substr($className, -9)) {
            throw new BadMethodCallException('This extension does not follow the naming convention; you must overwrite the getAlias() method.');
        }
        $classBaseName = substr(strrchr($className, '\\'), 1, -9);

        return Container::underscore($classBaseName);
    }

    /**
     * {@inheritdoc}
     */
    public function getConfiguration(array $config, ContainerBuilder $container)
    {
        $class = static::class;

        if (false !== strpos($class, "\0")) {
            return null; // ignore anonymous classes
        }

        $class = substr_replace($class, '\Configuration', strrpos($class, '\\'));
        $class = $container->getReflectionClass($class);

        if (!$class) {
            return null;
        }

        if (!$class->implementsInterface(ConfigurationInterface::class)) {
            throw new LogicException(sprintf('The extension configuration class "%s" must implement "%s".', $class->getName(), ConfigurationInterface::class));
        }

        if (!($constructor = $class->getConstructor()) || !$constructor->getNumberOfRequiredParameters()) {
            return $class->newInstance();
        }

        return null;
    }

    final protected function processConfiguration(ConfigurationInterface $configuration, array $configs): array
    {
        $processor = new Processor();

        return $this->processedConfigs[] = $processor->processConfiguration($configuration, $configs);
    }

    /**
     * @internal
     */
    final public function getProcessedConfigs(): array
    {
        try {
            return $this->processedConfigs;
        } finally {
            $this->processedConfigs = [];
        }
    }

    /**
     * @return bool Whether the configuration is enabled
     *
     * @throws InvalidArgumentException When the config is not enableable
     */
    protected function isConfigEnabled(ContainerBuilder $container, array $config)
    {
        if (!\array_key_exists('enabled', $config)) {
            throw new InvalidArgumentException("The config array has no 'enabled' key.");
        }

        return (bool) $container->getParameterBag()->resolveValue($config['enabled']);
    }
}
PKϤ$Zk²5dependency-injection/Extension/ExtensionInterface.phpnu�[���<?php

/*
 * This file is part of the Symfony package.
 *
 * (c) Fabien Potencier <fabien@symfony.com>
 *
 * For the full copyright and license information, please view the LICENSE
 * file that was distributed with this source code.
 */

namespace Symfony\Component\DependencyInjection\Extension;

use Symfony\Component\DependencyInjection\ContainerBuilder;

/**
 * ExtensionInterface is the interface implemented by container extension classes.
 *
 * @author Fabien Potencier <fabien@symfony.com>
 */
interface ExtensionInterface
{
    /**
     * Loads a specific configuration.
     *
     * @throws \InvalidArgumentException When provided tag is not defined in this extension
     */
    public function load(array $configs, ContainerBuilder $container);

    /**
     * Returns the namespace to be used for this extension (XML namespace).
     *
     * @return string The XML namespace
     */
    public function getNamespace();

    /**
     * Returns the base path for the XSD files.
     *
     * @return string|false
     */
    public function getXsdValidationBasePath();

    /**
     * Returns the recommended alias to use in XML.
     *
     * This alias is also the mandatory prefix to use when using YAML.
     *
     * @return string The alias
     */
    public function getAlias();
}
PKϤ$Z��H�BBBdependency-injection/Extension/ConfigurationExtensionInterface.phpnu�[���<?php

/*
 * This file is part of the Symfony package.
 *
 * (c) Fabien Potencier <fabien@symfony.com>
 *
 * For the full copyright and license information, please view the LICENSE
 * file that was distributed with this source code.
 */

namespace Symfony\Component\DependencyInjection\Extension;

use Symfony\Component\Config\Definition\ConfigurationInterface;
use Symfony\Component\DependencyInjection\ContainerBuilder;

/**
 * ConfigurationExtensionInterface is the interface implemented by container extension classes.
 *
 * @author Kevin Bond <kevinbond@gmail.com>
 */
interface ConfigurationExtensionInterface
{
    /**
     * Returns extension configuration.
     *
     * @return ConfigurationInterface|null The configuration or null
     */
    public function getConfiguration(array $config, ContainerBuilder $container);
}
PKϤ$Z���<dependency-injection/Extension/PrependExtensionInterface.phpnu�[���<?php

/*
 * This file is part of the Symfony package.
 *
 * (c) Fabien Potencier <fabien@symfony.com>
 *
 * For the full copyright and license information, please view the LICENSE
 * file that was distributed with this source code.
 */

namespace Symfony\Component\DependencyInjection\Extension;

use Symfony\Component\DependencyInjection\ContainerBuilder;

interface PrependExtensionInterface
{
    /**
     * Allow an extension to prepend the extension configurations.
     */
    public function prepend(ContainerBuilder $container);
}
PKϤ$Z�&O?""/dependency-injection/Loader/DirectoryLoader.phpnu�[���<?php

/*
 * This file is part of the Symfony package.
 *
 * (c) Fabien Potencier <fabien@symfony.com>
 *
 * For the full copyright and license information, please view the LICENSE
 * file that was distributed with this source code.
 */

namespace Symfony\Component\DependencyInjection\Loader;

/**
 * DirectoryLoader is a recursive loader to go through directories.
 *
 * @author Sebastien Lavoie <seb@wemakecustom.com>
 */
class DirectoryLoader extends FileLoader
{
    /**
     * {@inheritdoc}
     */
    public function load($file, string $type = null)
    {
        $file = rtrim($file, '/');
        $path = $this->locator->locate($file);
        $this->container->fileExists($path, false);

        foreach (scandir($path) as $dir) {
            if ('.' !== $dir[0]) {
                if (is_dir($path.'/'.$dir)) {
                    $dir .= '/'; // append / to allow recursion
                }

                $this->setCurrentDir($path);

                $this->import($dir, null, false, $path);
            }
        }
    }

    /**
     * {@inheritdoc}
     */
    public function supports($resource, string $type = null)
    {
        if ('directory' === $type) {
            return true;
        }

        return null === $type && \is_string($resource) && '/' === substr($resource, -1);
    }
}
PKϤ$Z�Q�]?6?6@dependency-injection/Loader/schema/dic/services/services-1.0.xsdnu�[���<?xml version="1.0" encoding="UTF-8" ?>

<xsd:schema xmlns="http://symfony.com/schema/dic/services"
     xmlns:xsd="http://www.w3.org/2001/XMLSchema"
     targetNamespace="http://symfony.com/schema/dic/services"
     elementFormDefault="qualified">

  <xsd:annotation>
    <xsd:documentation><![CDATA[
      Symfony XML Services Schema, version 1.0
      Authors: Fabien Potencier

      This defines a way to describe PHP objects (services) and their
      dependencies.
    ]]></xsd:documentation>
  </xsd:annotation>

  <xsd:element name="container" type="container" />

  <xsd:complexType name="container">
    <xsd:annotation>
      <xsd:documentation><![CDATA[
        The root element of a service file.
      ]]></xsd:documentation>
    </xsd:annotation>
    <xsd:sequence>
      <xsd:group ref="foreign" />
      <xsd:sequence minOccurs="0">
        <xsd:element name="imports" type="imports" />
        <xsd:group ref="foreign" />
      </xsd:sequence>
      <xsd:sequence minOccurs="0">
        <xsd:element name="parameters" type="parameters" />
        <xsd:group ref="foreign" />
      </xsd:sequence>
      <xsd:sequence minOccurs="0">
        <xsd:element name="services" type="services" />
        <xsd:group ref="foreign" />
      </xsd:sequence>
    </xsd:sequence>
  </xsd:complexType>

  <xsd:group name="foreign">
    <xsd:sequence>
      <xsd:any namespace="##other" processContents="lax" minOccurs="0" maxOccurs="unbounded" />
    </xsd:sequence>
  </xsd:group>

  <xsd:complexType name="services">
    <xsd:annotation>
      <xsd:documentation><![CDATA[
        Enclosing element for the definition of all services
      ]]></xsd:documentation>
    </xsd:annotation>
    <xsd:choice maxOccurs="unbounded">
      <xsd:element name="service" type="service" minOccurs="1" />
      <xsd:element name="prototype" type="prototype" minOccurs="0" />
      <xsd:element name="defaults" type="defaults" minOccurs="0" maxOccurs="1" />
      <xsd:element name="instanceof" type="instanceof" minOccurs="0" />
      <xsd:element name="stack" type="stack" minOccurs="0" />
    </xsd:choice>
  </xsd:complexType>

  <xsd:complexType name="imports">
    <xsd:annotation>
      <xsd:documentation><![CDATA[
        Enclosing element for the import elements
      ]]></xsd:documentation>
    </xsd:annotation>
    <xsd:choice minOccurs="1" maxOccurs="unbounded">
      <xsd:element name="import" type="import" />
    </xsd:choice>
  </xsd:complexType>

  <xsd:complexType name="import">
    <xsd:annotation>
      <xsd:documentation><![CDATA[
        Import an external resource defining other services or parameters
      ]]></xsd:documentation>
    </xsd:annotation>
    <xsd:attribute name="resource" type="xsd:string" use="required" />
    <xsd:attribute name="ignore-errors" type="ignore_errors" />
    <xsd:attribute name="type" type="xsd:string" />
  </xsd:complexType>

  <xsd:complexType name="callable">
    <xsd:choice minOccurs="0" maxOccurs="1">
      <xsd:element name="service" type="service" minOccurs="0" maxOccurs="1" />
    </xsd:choice>
    <xsd:attribute name="service" type="xsd:string" />
    <xsd:attribute name="class" type="xsd:string" />
    <xsd:attribute name="method" type="xsd:string" />
    <xsd:attribute name="function" type="xsd:string" />
  </xsd:complexType>

  <xsd:complexType name="defaults">
    <xsd:annotation>
      <xsd:documentation><![CDATA[
        Enclosing element for the service definitions' defaults for the current file
      ]]></xsd:documentation>
    </xsd:annotation>
    <xsd:choice maxOccurs="unbounded">
      <xsd:element name="tag" type="tag" minOccurs="0" maxOccurs="unbounded" />
      <xsd:element name="bind" type="bind" minOccurs="0" maxOccurs="unbounded" />
    </xsd:choice>
    <xsd:attribute name="public" type="boolean" />
    <xsd:attribute name="autowire" type="boolean" />
    <xsd:attribute name="autoconfigure" type="boolean" />
  </xsd:complexType>

  <xsd:complexType name="service">
    <xsd:choice maxOccurs="unbounded">
      <xsd:element name="file" type="xsd:string" minOccurs="0" maxOccurs="1" />
      <xsd:element name="argument" type="argument" minOccurs="0" maxOccurs="unbounded" />
      <xsd:element name="configurator" type="callable" minOccurs="0" maxOccurs="1" />
      <xsd:element name="factory" type="callable" minOccurs="0" maxOccurs="1" />
      <xsd:element name="deprecated" type="deprecated" minOccurs="0" maxOccurs="1" />
      <xsd:element name="call" type="call" minOccurs="0" maxOccurs="unbounded" />
      <xsd:element name="tag" type="tag" minOccurs="0" maxOccurs="unbounded" />
      <xsd:element name="property" type="property" minOccurs="0" maxOccurs="unbounded" />
      <xsd:element name="bind" type="bind" minOccurs="0" maxOccurs="unbounded" />
    </xsd:choice>
    <xsd:attribute name="id" type="xsd:string" />
    <xsd:attribute name="class" type="xsd:string" />
    <xsd:attribute name="shared" type="boolean" />
    <xsd:attribute name="public" type="boolean" />
    <xsd:attribute name="synthetic" type="boolean" />
    <xsd:attribute name="lazy" type="xsd:string" />
    <xsd:attribute name="abstract" type="boolean" />
    <xsd:attribute name="alias" type="xsd:string" />
    <xsd:attribute name="parent" type="xsd:string" />
    <xsd:attribute name="decorates" type="xsd:string" />
    <xsd:attribute name="decoration-on-invalid" type="invalid_decorated_service_sequence" />
    <xsd:attribute name="decoration-inner-name" type="xsd:string" />
    <xsd:attribute name="decoration-priority" type="xsd:integer" />
    <xsd:attribute name="autowire" type="boolean" />
    <xsd:attribute name="autoconfigure" type="boolean" />
  </xsd:complexType>

  <xsd:complexType name="instanceof">
    <xsd:choice maxOccurs="unbounded">
      <xsd:element name="configurator" type="callable" minOccurs="0" maxOccurs="1" />
      <xsd:element name="call" type="call" minOccurs="0" maxOccurs="unbounded" />
      <xsd:element name="tag" type="tag" minOccurs="0" maxOccurs="unbounded" />
      <xsd:element name="property" type="property" minOccurs="0" maxOccurs="unbounded" />
      <xsd:element name="bind" type="bind" minOccurs="0" maxOccurs="unbounded" />
    </xsd:choice>
    <xsd:attribute name="id" type="xsd:string" use="required" />
    <xsd:attribute name="shared" type="boolean" />
    <xsd:attribute name="public" type="boolean" />
    <xsd:attribute name="lazy" type="xsd:string" />
    <xsd:attribute name="autowire" type="boolean" />
    <xsd:attribute name="autoconfigure" type="boolean" />
  </xsd:complexType>

  <xsd:complexType name="prototype">
    <xsd:choice maxOccurs="unbounded">
      <xsd:element name="argument" type="argument" minOccurs="0" maxOccurs="unbounded" />
      <xsd:element name="configurator" type="callable" minOccurs="0" maxOccurs="1" />
      <xsd:element name="factory" type="callable" minOccurs="0" maxOccurs="1" />
      <xsd:element name="deprecated" type="deprecated" minOccurs="0" maxOccurs="1" />
      <xsd:element name="call" type="call" minOccurs="0" maxOccurs="unbounded" />
      <xsd:element name="tag" type="tag" minOccurs="0" maxOccurs="unbounded" />
      <xsd:element name="property" type="property" minOccurs="0" maxOccurs="unbounded" />
      <xsd:element name="bind" type="bind" minOccurs="0" maxOccurs="unbounded" />
      <xsd:element name="exclude" type="xsd:string" minOccurs="0" maxOccurs="unbounded" />
    </xsd:choice>
    <xsd:attribute name="namespace" type="xsd:string" use="required" />
    <xsd:attribute name="resource" type="xsd:string" use="required" />
    <xsd:attribute name="exclude" type="xsd:string" />
    <xsd:attribute name="shared" type="boolean" />
    <xsd:attribute name="public" type="boolean" />
    <xsd:attribute name="lazy" type="xsd:string" />
    <xsd:attribute name="abstract" type="boolean" />
    <xsd:attribute name="parent" type="xsd:string" />
    <xsd:attribute name="autowire" type="boolean" />
    <xsd:attribute name="autoconfigure" type="boolean" />
  </xsd:complexType>

  <xsd:complexType name="stack">
    <xsd:choice maxOccurs="unbounded">
      <xsd:element name="service" type="service" minOccurs="1" />
      <xsd:element name="deprecated" type="deprecated" minOccurs="0" maxOccurs="1" />
    </xsd:choice>
    <xsd:attribute name="id" type="xsd:string" use="required" />
    <xsd:attribute name="public" type="boolean" />
  </xsd:complexType>

  <xsd:complexType name="tag">
    <xsd:simpleContent>
      <xsd:extension base="xsd:string">
        <xsd:anyAttribute namespace="##any" processContents="lax" />
      </xsd:extension>
    </xsd:simpleContent>
  </xsd:complexType>

  <xsd:complexType name="deprecated">
    <xsd:simpleContent>
      <xsd:extension base="xsd:string">
        <!-- In Symfony 6, make these attributes required -->
        <xsd:attribute name="package" type="xsd:string" />
        <xsd:attribute name="version" type="xsd:string" />
      </xsd:extension>
    </xsd:simpleContent>
  </xsd:complexType>

  <xsd:complexType name="parameters">
    <xsd:choice minOccurs="1" maxOccurs="unbounded">
      <xsd:element name="parameter" type="parameter" />
    </xsd:choice>
    <xsd:attribute name="type" type="parameter_type" />
    <xsd:attribute name="key" type="xsd:string" />
  </xsd:complexType>

  <xsd:complexType name="parameter" mixed="true">
    <xsd:choice minOccurs="0" maxOccurs="unbounded">
      <xsd:element name="parameter" type="parameter" />
    </xsd:choice>
    <xsd:attribute name="type" type="parameter_type" />
    <xsd:attribute name="id" type="xsd:string" />
    <xsd:attribute name="key" type="xsd:string" />
    <xsd:attribute name="on-invalid" type="invalid_sequence" />
  </xsd:complexType>

  <xsd:complexType name="property" mixed="true">
    <xsd:choice minOccurs="0">
      <xsd:element name="property" type="property" maxOccurs="unbounded" />
      <xsd:element name="service" type="service" />
    </xsd:choice>
    <xsd:attribute name="type" type="argument_type" />
    <xsd:attribute name="id" type="xsd:string" />
    <xsd:attribute name="key" type="xsd:string" />
    <xsd:attribute name="name" type="xsd:string" />
    <xsd:attribute name="on-invalid" type="invalid_sequence" />
    <xsd:attribute name="tag" type="xsd:string" />
  </xsd:complexType>

  <xsd:complexType name="bind" mixed="true">
    <xsd:choice maxOccurs="unbounded">
      <xsd:element name="bind" type="argument" minOccurs="0" maxOccurs="unbounded" />
      <xsd:element name="service" type="service" />
    </xsd:choice>
    <xsd:attribute name="type" type="argument_type" />
    <xsd:attribute name="id" type="xsd:string" />
    <xsd:attribute name="key" type="xsd:string" use="required" />
    <xsd:attribute name="on-invalid" type="invalid_sequence" />
    <xsd:attribute name="method" type="xsd:string" />
    <xsd:attribute name="tag" type="xsd:string" />
  </xsd:complexType>

  <xsd:complexType name="argument" mixed="true">
    <xsd:choice minOccurs="0">
      <xsd:element name="argument" type="argument" maxOccurs="unbounded" />
      <xsd:element name="service" type="service" />
    </xsd:choice>
    <xsd:attribute name="type" type="argument_type" />
    <xsd:attribute name="id" type="xsd:string" />
    <xsd:attribute name="key" type="xsd:string" />
    <xsd:attribute name="index" type="xsd:integer" />
    <xsd:attribute name="on-invalid" type="invalid_sequence" />
    <xsd:attribute name="tag" type="xsd:string" />
    <xsd:attribute name="index-by" type="xsd:string" />
    <xsd:attribute name="default-index-method" type="xsd:string" />
    <xsd:attribute name="default-priority-method" type="xsd:string" />
  </xsd:complexType>

  <xsd:complexType name="call">
    <xsd:choice minOccurs="0">
      <xsd:element name="argument" type="argument" maxOccurs="unbounded" />
    </xsd:choice>
    <xsd:attribute name="method" type="xsd:string" />
    <xsd:attribute name="returns-clone" type="boolean" />
  </xsd:complexType>

  <xsd:simpleType name="parameter_type">
    <xsd:restriction base="xsd:string">
      <xsd:enumeration value="collection" />
      <xsd:enumeration value="string" />
      <xsd:enumeration value="constant" />
      <xsd:enumeration value="binary" />
    </xsd:restriction>
  </xsd:simpleType>

  <xsd:simpleType name="argument_type">
    <xsd:restriction base="xsd:string">
      <xsd:enumeration value="abstract" />
      <xsd:enumeration value="collection" />
      <xsd:enumeration value="service" />
      <xsd:enumeration value="expression" />
      <xsd:enumeration value="string" />
      <xsd:enumeration value="constant" />
      <xsd:enumeration value="binary" />
      <xsd:enumeration value="iterator" />
      <xsd:enumeration value="service_locator" />
      <!-- "tagged" is an alias of "tagged_iterator", using "tagged_iterator" is preferred. -->
      <xsd:enumeration value="tagged" />
      <xsd:enumeration value="tagged_iterator" />
      <xsd:enumeration value="tagged_locator" />
    </xsd:restriction>
  </xsd:simpleType>

  <xsd:simpleType name="ignore_errors">
    <xsd:restriction base="xsd:string">
      <xsd:pattern value="(true|false|not_found)" />
    </xsd:restriction>
  </xsd:simpleType>

  <xsd:simpleType name="invalid_sequence">
    <xsd:restriction base="xsd:string">
      <xsd:enumeration value="null" />
      <xsd:enumeration value="ignore" />
      <xsd:enumeration value="exception" />
      <xsd:enumeration value="ignore_uninitialized" />
    </xsd:restriction>
  </xsd:simpleType>

  <xsd:simpleType name="invalid_decorated_service_sequence">
    <xsd:restriction base="xsd:string">
      <xsd:enumeration value="null" />
      <xsd:enumeration value="ignore" />
      <xsd:enumeration value="exception" />
    </xsd:restriction>
  </xsd:simpleType>

  <xsd:simpleType name="boolean">
    <xsd:restriction base="xsd:string">
      <xsd:pattern value="(%.+%|true|false)" />
    </xsd:restriction>
  </xsd:simpleType>
</xsd:schema>
PKϤ$Z�HM"��Adependency-injection/Loader/Configurator/DefaultsConfigurator.phpnu�[���<?php

/*
 * This file is part of the Symfony package.
 *
 * (c) Fabien Potencier <fabien@symfony.com>
 *
 * For the full copyright and license information, please view the LICENSE
 * file that was distributed with this source code.
 */

namespace Symfony\Component\DependencyInjection\Loader\Configurator;

use Symfony\Component\DependencyInjection\Definition;
use Symfony\Component\DependencyInjection\Exception\InvalidArgumentException;

/**
 * @author Nicolas Grekas <p@tchwork.com>
 */
class DefaultsConfigurator extends AbstractServiceConfigurator
{
    const FACTORY = 'defaults';

    use Traits\AutoconfigureTrait;
    use Traits\AutowireTrait;
    use Traits\BindTrait;
    use Traits\PublicTrait;

    private $path;

    public function __construct(ServicesConfigurator $parent, Definition $definition, string $path = null)
    {
        parent::__construct($parent, $definition, null, []);

        $this->path = $path;
    }

    /**
     * Adds a tag for this definition.
     *
     * @return $this
     *
     * @throws InvalidArgumentException when an invalid tag name or attribute is provided
     */
    final public function tag(string $name, array $attributes = []): self
    {
        if ('' === $name) {
            throw new InvalidArgumentException('The tag name in "_defaults" must be a non-empty string.');
        }

        foreach ($attributes as $attribute => $value) {
            if (null !== $value && !is_scalar($value)) {
                throw new InvalidArgumentException(sprintf('Tag "%s", attribute "%s" in "_defaults" must be of a scalar-type.', $name, $attribute));
            }
        }

        $this->definition->addTag($name, $attributes);

        return $this;
    }

    /**
     * Defines an instanceof-conditional to be applied to following service definitions.
     */
    final public function instanceof(string $fqcn): InstanceofConfigurator
    {
        return $this->parent->instanceof($fqcn);
    }
}
PKϤ$Z�;��	�	Bdependency-injection/Loader/Configurator/PrototypeConfigurator.phpnu�[���<?php

/*
 * This file is part of the Symfony package.
 *
 * (c) Fabien Potencier <fabien@symfony.com>
 *
 * For the full copyright and license information, please view the LICENSE
 * file that was distributed with this source code.
 */

namespace Symfony\Component\DependencyInjection\Loader\Configurator;

use Symfony\Component\DependencyInjection\Definition;
use Symfony\Component\DependencyInjection\Loader\PhpFileLoader;

/**
 * @author Nicolas Grekas <p@tchwork.com>
 */
class PrototypeConfigurator extends AbstractServiceConfigurator
{
    const FACTORY = 'load';

    use Traits\AbstractTrait;
    use Traits\ArgumentTrait;
    use Traits\AutoconfigureTrait;
    use Traits\AutowireTrait;
    use Traits\BindTrait;
    use Traits\CallTrait;
    use Traits\ConfiguratorTrait;
    use Traits\DeprecateTrait;
    use Traits\FactoryTrait;
    use Traits\LazyTrait;
    use Traits\ParentTrait;
    use Traits\PropertyTrait;
    use Traits\PublicTrait;
    use Traits\ShareTrait;
    use Traits\TagTrait;

    private $loader;
    private $resource;
    private $excludes;
    private $allowParent;

    public function __construct(ServicesConfigurator $parent, PhpFileLoader $loader, Definition $defaults, string $namespace, string $resource, bool $allowParent)
    {
        $definition = new Definition();
        if (!$defaults->isPublic() || !$defaults->isPrivate()) {
            $definition->setPublic($defaults->isPublic());
        }
        $definition->setAutowired($defaults->isAutowired());
        $definition->setAutoconfigured($defaults->isAutoconfigured());
        // deep clone, to avoid multiple process of the same instance in the passes
        $definition->setBindings(unserialize(serialize($defaults->getBindings())));
        $definition->setChanges([]);

        $this->loader = $loader;
        $this->resource = $resource;
        $this->allowParent = $allowParent;

        parent::__construct($parent, $definition, $namespace, $defaults->getTags());
    }

    public function __destruct()
    {
        parent::__destruct();

        if ($this->loader) {
            $this->loader->registerClasses($this->definition, $this->id, $this->resource, $this->excludes);
        }
        $this->loader = null;
    }

    /**
     * Excludes files from registration using glob patterns.
     *
     * @param string[]|string $excludes
     *
     * @return $this
     */
    final public function exclude($excludes): self
    {
        $this->excludes = (array) $excludes;

        return $this;
    }
}
PKϤ$Z%�j�DDCdependency-injection/Loader/Configurator/ParametersConfigurator.phpnu�[���<?php

/*
 * This file is part of the Symfony package.
 *
 * (c) Fabien Potencier <fabien@symfony.com>
 *
 * For the full copyright and license information, please view the LICENSE
 * file that was distributed with this source code.
 */

namespace Symfony\Component\DependencyInjection\Loader\Configurator;

use Symfony\Component\DependencyInjection\ContainerBuilder;

/**
 * @author Nicolas Grekas <p@tchwork.com>
 */
class ParametersConfigurator extends AbstractConfigurator
{
    const FACTORY = 'parameters';

    private $container;

    public function __construct(ContainerBuilder $container)
    {
        $this->container = $container;
    }

    /**
     * Creates a parameter.
     *
     * @return $this
     */
    final public function set(string $name, $value): self
    {
        $this->container->setParameter($name, static::processValue($value, true));

        return $this;
    }

    /**
     * Creates a parameter.
     *
     * @return $this
     */
    final public function __invoke(string $name, $value): self
    {
        return $this->set($name, $value);
    }
}
PKϤ$Z* ���Fdependency-injection/Loader/Configurator/InlineServiceConfigurator.phpnu�[���<?php

/*
 * This file is part of the Symfony package.
 *
 * (c) Fabien Potencier <fabien@symfony.com>
 *
 * For the full copyright and license information, please view the LICENSE
 * file that was distributed with this source code.
 */

namespace Symfony\Component\DependencyInjection\Loader\Configurator;

use Symfony\Component\DependencyInjection\Definition;

/**
 * @author Nicolas Grekas <p@tchwork.com>
 */
class InlineServiceConfigurator extends AbstractConfigurator
{
    const FACTORY = 'service';

    use Traits\ArgumentTrait;
    use Traits\AutowireTrait;
    use Traits\BindTrait;
    use Traits\CallTrait;
    use Traits\ConfiguratorTrait;
    use Traits\FactoryTrait;
    use Traits\FileTrait;
    use Traits\LazyTrait;
    use Traits\ParentTrait;
    use Traits\PropertyTrait;
    use Traits\TagTrait;

    private $id = '[inline]';
    private $allowParent = true;
    private $path = null;

    public function __construct(Definition $definition)
    {
        $this->definition = $definition;
    }
}
PKϤ$Z �E��
�
Hdependency-injection/Loader/Configurator/AbstractServiceConfigurator.phpnu�[���<?php

/*
 * This file is part of the Symfony package.
 *
 * (c) Fabien Potencier <fabien@symfony.com>
 *
 * For the full copyright and license information, please view the LICENSE
 * file that was distributed with this source code.
 */

namespace Symfony\Component\DependencyInjection\Loader\Configurator;

use Symfony\Component\DependencyInjection\Definition;
use Symfony\Component\DependencyInjection\Exception\ServiceNotFoundException;

abstract class AbstractServiceConfigurator extends AbstractConfigurator
{
    protected $parent;
    protected $id;
    private $defaultTags = [];

    public function __construct(ServicesConfigurator $parent, Definition $definition, string $id = null, array $defaultTags = [])
    {
        $this->parent = $parent;
        $this->definition = $definition;
        $this->id = $id;
        $this->defaultTags = $defaultTags;
    }

    public function __destruct()
    {
        // default tags should be added last
        foreach ($this->defaultTags as $name => $attributes) {
            foreach ($attributes as $attributes) {
                $this->definition->addTag($name, $attributes);
            }
        }
        $this->defaultTags = [];
    }

    /**
     * Registers a service.
     */
    final public function set(?string $id, string $class = null): ServiceConfigurator
    {
        $this->__destruct();

        return $this->parent->set($id, $class);
    }

    /**
     * Creates an alias.
     */
    final public function alias(string $id, string $referencedId): AliasConfigurator
    {
        $this->__destruct();

        return $this->parent->alias($id, $referencedId);
    }

    /**
     * Registers a PSR-4 namespace using a glob pattern.
     */
    final public function load(string $namespace, string $resource): PrototypeConfigurator
    {
        $this->__destruct();

        return $this->parent->load($namespace, $resource);
    }

    /**
     * Gets an already defined service definition.
     *
     * @throws ServiceNotFoundException if the service definition does not exist
     */
    final public function get(string $id): ServiceConfigurator
    {
        $this->__destruct();

        return $this->parent->get($id);
    }

    /**
     * Registers a stack of decorator services.
     *
     * @param InlineServiceConfigurator[]|ReferenceConfigurator[] $services
     */
    final public function stack(string $id, array $services): AliasConfigurator
    {
        $this->__destruct();

        return $this->parent->stack($id, $services);
    }

    /**
     * Registers a service.
     */
    final public function __invoke(string $id, string $class = null): ServiceConfigurator
    {
        $this->__destruct();

        return $this->parent->set($id, $class);
    }
}
PKϤ$Z>���>dependency-injection/Loader/Configurator/AliasConfigurator.phpnu�[���<?php

/*
 * This file is part of the Symfony package.
 *
 * (c) Fabien Potencier <fabien@symfony.com>
 *
 * For the full copyright and license information, please view the LICENSE
 * file that was distributed with this source code.
 */

namespace Symfony\Component\DependencyInjection\Loader\Configurator;

use Symfony\Component\DependencyInjection\Alias;

/**
 * @author Nicolas Grekas <p@tchwork.com>
 */
class AliasConfigurator extends AbstractServiceConfigurator
{
    const FACTORY = 'alias';

    use Traits\DeprecateTrait;
    use Traits\PublicTrait;

    public function __construct(ServicesConfigurator $parent, Alias $alias)
    {
        $this->parent = $parent;
        $this->definition = $alias;
    }
}
PKϤ$Zω'6��Bdependency-injection/Loader/Configurator/Traits/SyntheticTrait.phpnu�[���<?php

/*
 * This file is part of the Symfony package.
 *
 * (c) Fabien Potencier <fabien@symfony.com>
 *
 * For the full copyright and license information, please view the LICENSE
 * file that was distributed with this source code.
 */

namespace Symfony\Component\DependencyInjection\Loader\Configurator\Traits;

trait SyntheticTrait
{
    /**
     * Sets whether this definition is synthetic, that is not constructed by the
     * container, but dynamically injected.
     *
     * @return $this
     */
    final public function synthetic(bool $synthetic = true): self
    {
        $this->definition->setSynthetic($synthetic);

        return $this;
    }
}
PKϤ$Z��;�..=dependency-injection/Loader/Configurator/Traits/CallTrait.phpnu�[���<?php

/*
 * This file is part of the Symfony package.
 *
 * (c) Fabien Potencier <fabien@symfony.com>
 *
 * For the full copyright and license information, please view the LICENSE
 * file that was distributed with this source code.
 */

namespace Symfony\Component\DependencyInjection\Loader\Configurator\Traits;

use Symfony\Component\DependencyInjection\Exception\InvalidArgumentException;

trait CallTrait
{
    /**
     * Adds a method to call after service initialization.
     *
     * @param string $method       The method name to call
     * @param array  $arguments    An array of arguments to pass to the method call
     * @param bool   $returnsClone Whether the call returns the service instance or not
     *
     * @return $this
     *
     * @throws InvalidArgumentException on empty $method param
     */
    final public function call(string $method, array $arguments = [], bool $returnsClone = false): self
    {
        $this->definition->addMethodCall($method, static::processValue($arguments, true), $returnsClone);

        return $this;
    }
}
PKϤ$Z�s��yy<dependency-injection/Loader/Configurator/Traits/TagTrait.phpnu�[���<?php

/*
 * This file is part of the Symfony package.
 *
 * (c) Fabien Potencier <fabien@symfony.com>
 *
 * For the full copyright and license information, please view the LICENSE
 * file that was distributed with this source code.
 */

namespace Symfony\Component\DependencyInjection\Loader\Configurator\Traits;

use Symfony\Component\DependencyInjection\Exception\InvalidArgumentException;

trait TagTrait
{
    /**
     * Adds a tag for this definition.
     *
     * @return $this
     */
    final public function tag(string $name, array $attributes = []): self
    {
        if ('' === $name) {
            throw new InvalidArgumentException(sprintf('The tag name for service "%s" must be a non-empty string.', $this->id));
        }

        foreach ($attributes as $attribute => $value) {
            if (!is_scalar($value) && null !== $value) {
                throw new InvalidArgumentException(sprintf('A tag attribute must be of a scalar-type for service "%s", tag "%s", attribute "%s".', $this->id, $name, $attribute));
            }
        }

        $this->definition->addTag($name, $attributes);

        return $this;
    }
}
PKϤ$Z��5Z��Adependency-injection/Loader/Configurator/Traits/ArgumentTrait.phpnu�[���<?php

/*
 * This file is part of the Symfony package.
 *
 * (c) Fabien Potencier <fabien@symfony.com>
 *
 * For the full copyright and license information, please view the LICENSE
 * file that was distributed with this source code.
 */

namespace Symfony\Component\DependencyInjection\Loader\Configurator\Traits;

trait ArgumentTrait
{
    /**
     * Sets the arguments to pass to the service constructor/factory method.
     *
     * @return $this
     */
    final public function args(array $arguments): self
    {
        $this->definition->setArguments(static::processValue($arguments, true));

        return $this;
    }

    /**
     * Sets one argument to pass to the service constructor/factory method.
     *
     * @param string|int $key
     * @param mixed      $value
     *
     * @return $this
     */
    final public function arg($key, $value): self
    {
        $this->definition->setArgument($key, static::processValue($value, true));

        return $this;
    }
}
PKϤ$Z�=r���Adependency-injection/Loader/Configurator/Traits/AbstractTrait.phpnu�[���<?php

/*
 * This file is part of the Symfony package.
 *
 * (c) Fabien Potencier <fabien@symfony.com>
 *
 * For the full copyright and license information, please view the LICENSE
 * file that was distributed with this source code.
 */

namespace Symfony\Component\DependencyInjection\Loader\Configurator\Traits;

trait AbstractTrait
{
    /**
     * Whether this definition is abstract, that means it merely serves as a
     * template for other definitions.
     *
     * @return $this
     */
    final public function abstract(bool $abstract = true): self
    {
        $this->definition->setAbstract($abstract);

        return $this;
    }
}
PKϤ$ZJ��''=dependency-injection/Loader/Configurator/Traits/LazyTrait.phpnu�[���<?php

/*
 * This file is part of the Symfony package.
 *
 * (c) Fabien Potencier <fabien@symfony.com>
 *
 * For the full copyright and license information, please view the LICENSE
 * file that was distributed with this source code.
 */

namespace Symfony\Component\DependencyInjection\Loader\Configurator\Traits;

trait LazyTrait
{
    /**
     * Sets the lazy flag of this service.
     *
     * @param bool|string $lazy A FQCN to derivate the lazy proxy from or `true` to make it extend from the definition's class
     *
     * @return $this
     */
    final public function lazy($lazy = true): self
    {
        $this->definition->setLazy((bool) $lazy);
        if (\is_string($lazy)) {
            $this->definition->addTag('proxy', ['interface' => $lazy]);
        }

        return $this;
    }
}
PKϤ$Z�*=dependency-injection/Loader/Configurator/Traits/BindTrait.phpnu�[���<?php

/*
 * This file is part of the Symfony package.
 *
 * (c) Fabien Potencier <fabien@symfony.com>
 *
 * For the full copyright and license information, please view the LICENSE
 * file that was distributed with this source code.
 */

namespace Symfony\Component\DependencyInjection\Loader\Configurator\Traits;

use Symfony\Component\DependencyInjection\Argument\BoundArgument;
use Symfony\Component\DependencyInjection\Exception\InvalidArgumentException;
use Symfony\Component\DependencyInjection\Loader\Configurator\DefaultsConfigurator;
use Symfony\Component\DependencyInjection\Loader\Configurator\InstanceofConfigurator;
use Symfony\Component\DependencyInjection\Reference;

trait BindTrait
{
    /**
     * Sets bindings.
     *
     * Bindings map $named or FQCN arguments to values that should be
     * injected in the matching parameters (of the constructor, of methods
     * called and of controller actions).
     *
     * @param string $nameOrFqcn A parameter name with its "$" prefix, or a FQCN
     * @param mixed  $valueOrRef The value or reference to bind
     *
     * @return $this
     */
    final public function bind(string $nameOrFqcn, $valueOrRef): self
    {
        $valueOrRef = static::processValue($valueOrRef, true);
        if (!preg_match('/^(?:(?:array|bool|float|int|string)[ \t]*+)?\$/', $nameOrFqcn) && !$valueOrRef instanceof Reference) {
            throw new InvalidArgumentException(sprintf('Invalid binding for service "%s": named arguments must start with a "$", and FQCN must map to references. Neither applies to binding "%s".', $this->id, $nameOrFqcn));
        }
        $bindings = $this->definition->getBindings();
        $type = $this instanceof DefaultsConfigurator ? BoundArgument::DEFAULTS_BINDING : ($this instanceof InstanceofConfigurator ? BoundArgument::INSTANCEOF_BINDING : BoundArgument::SERVICE_BINDING);
        $bindings[$nameOrFqcn] = new BoundArgument($valueOrRef, true, $type, $this->path ?? null);
        $this->definition->setBindings($bindings);

        return $this;
    }
}
PKϤ$Z�MMAdependency-injection/Loader/Configurator/Traits/DecorateTrait.phpnu�[���<?php

/*
 * This file is part of the Symfony package.
 *
 * (c) Fabien Potencier <fabien@symfony.com>
 *
 * For the full copyright and license information, please view the LICENSE
 * file that was distributed with this source code.
 */

namespace Symfony\Component\DependencyInjection\Loader\Configurator\Traits;

use Symfony\Component\DependencyInjection\ContainerInterface;
use Symfony\Component\DependencyInjection\Exception\InvalidArgumentException;

trait DecorateTrait
{
    /**
     * Sets the service that this service is decorating.
     *
     * @param string|null $id The decorated service id, use null to remove decoration
     *
     * @return $this
     *
     * @throws InvalidArgumentException in case the decorated service id and the new decorated service id are equals
     */
    final public function decorate(?string $id, string $renamedId = null, int $priority = 0, int $invalidBehavior = ContainerInterface::EXCEPTION_ON_INVALID_REFERENCE): self
    {
        $this->definition->setDecoratedService($id, $renamedId, $priority, $invalidBehavior);

        return $this;
    }
}
PKϤ$Z��[���Edependency-injection/Loader/Configurator/Traits/ConfiguratorTrait.phpnu�[���<?php

/*
 * This file is part of the Symfony package.
 *
 * (c) Fabien Potencier <fabien@symfony.com>
 *
 * For the full copyright and license information, please view the LICENSE
 * file that was distributed with this source code.
 */

namespace Symfony\Component\DependencyInjection\Loader\Configurator\Traits;

trait ConfiguratorTrait
{
    /**
     * Sets a configurator to call after the service is fully initialized.
     *
     * @param string|array $configurator A PHP callable reference
     *
     * @return $this
     */
    final public function configurator($configurator): self
    {
        $this->definition->setConfigurator(static::processValue($configurator, true));

        return $this;
    }
}
PKϤ$Z%0�O��?dependency-injection/Loader/Configurator/Traits/PublicTrait.phpnu�[���<?php

/*
 * This file is part of the Symfony package.
 *
 * (c) Fabien Potencier <fabien@symfony.com>
 *
 * For the full copyright and license information, please view the LICENSE
 * file that was distributed with this source code.
 */

namespace Symfony\Component\DependencyInjection\Loader\Configurator\Traits;

trait PublicTrait
{
    /**
     * @return $this
     */
    final public function public(): self
    {
        $this->definition->setPublic(true);

        return $this;
    }

    /**
     * @return $this
     */
    final public function private(): self
    {
        $this->definition->setPublic(false);

        return $this;
    }
}
PKϤ$Z�X�;;>dependency-injection/Loader/Configurator/Traits/ShareTrait.phpnu�[���<?php

/*
 * This file is part of the Symfony package.
 *
 * (c) Fabien Potencier <fabien@symfony.com>
 *
 * For the full copyright and license information, please view the LICENSE
 * file that was distributed with this source code.
 */

namespace Symfony\Component\DependencyInjection\Loader\Configurator\Traits;

trait ShareTrait
{
    /**
     * Sets if the service must be shared or not.
     *
     * @return $this
     */
    final public function share(bool $shared = true): self
    {
        $this->definition->setShared($shared);

        return $this;
    }
}
PKϤ$Z��l��?dependency-injection/Loader/Configurator/Traits/ParentTrait.phpnu�[���<?php

/*
 * This file is part of the Symfony package.
 *
 * (c) Fabien Potencier <fabien@symfony.com>
 *
 * For the full copyright and license information, please view the LICENSE
 * file that was distributed with this source code.
 */

namespace Symfony\Component\DependencyInjection\Loader\Configurator\Traits;

use Symfony\Component\DependencyInjection\ChildDefinition;
use Symfony\Component\DependencyInjection\Exception\InvalidArgumentException;

trait ParentTrait
{
    /**
     * Sets the Definition to inherit from.
     *
     * @return $this
     *
     * @throws InvalidArgumentException when parent cannot be set
     */
    final public function parent(string $parent): self
    {
        if (!$this->allowParent) {
            throw new InvalidArgumentException(sprintf('A parent cannot be defined when either "_instanceof" or "_defaults" are also defined for service prototype "%s".', $this->id));
        }

        if ($this->definition instanceof ChildDefinition) {
            $this->definition->setParent($parent);
        } else {
            // cast Definition to ChildDefinition
            $definition = serialize($this->definition);
            $definition = substr_replace($definition, '53', 2, 2);
            $definition = substr_replace($definition, 'Child', 44, 0);
            $definition = unserialize($definition);

            $this->definition = $definition->setParent($parent);
        }

        return $this;
    }
}
PKϤ$Zʊy�<<Adependency-injection/Loader/Configurator/Traits/AutowireTrait.phpnu�[���<?php

/*
 * This file is part of the Symfony package.
 *
 * (c) Fabien Potencier <fabien@symfony.com>
 *
 * For the full copyright and license information, please view the LICENSE
 * file that was distributed with this source code.
 */

namespace Symfony\Component\DependencyInjection\Loader\Configurator\Traits;

trait AutowireTrait
{
    /**
     * Enables/disables autowiring.
     *
     * @return $this
     */
    final public function autowire(bool $autowired = true): self
    {
        $this->definition->setAutowired($autowired);

        return $this;
    }
}
PKϤ$Zͮ�RR@dependency-injection/Loader/Configurator/Traits/FactoryTrait.phpnu�[���<?php

/*
 * This file is part of the Symfony package.
 *
 * (c) Fabien Potencier <fabien@symfony.com>
 *
 * For the full copyright and license information, please view the LICENSE
 * file that was distributed with this source code.
 */

namespace Symfony\Component\DependencyInjection\Loader\Configurator\Traits;

use Symfony\Component\DependencyInjection\Exception\InvalidArgumentException;

trait FactoryTrait
{
    /**
     * Sets a factory.
     *
     * @param string|array $factory A PHP callable reference
     *
     * @return $this
     */
    final public function factory($factory): self
    {
        if (\is_string($factory) && 1 === substr_count($factory, ':')) {
            $factoryParts = explode(':', $factory);

            throw new InvalidArgumentException(sprintf('Invalid factory "%s": the "service:method" notation is not available when using PHP-based DI configuration. Use "[service(\'%s\'), \'%s\']" instead.', $factory, $factoryParts[0], $factoryParts[1]));
        }

        $this->definition->setFactory(static::processValue($factory, true));

        return $this;
    }
}
PKϤ$Z��a�77=dependency-injection/Loader/Configurator/Traits/FileTrait.phpnu�[���<?php

/*
 * This file is part of the Symfony package.
 *
 * (c) Fabien Potencier <fabien@symfony.com>
 *
 * For the full copyright and license information, please view the LICENSE
 * file that was distributed with this source code.
 */

namespace Symfony\Component\DependencyInjection\Loader\Configurator\Traits;

trait FileTrait
{
    /**
     * Sets a file to require before creating the service.
     *
     * @return $this
     */
    final public function file(string $file): self
    {
        $this->definition->setFile($file);

        return $this;
    }
}
PKϤ$Z��KooBdependency-injection/Loader/Configurator/Traits/DeprecateTrait.phpnu�[���<?php

/*
 * This file is part of the Symfony package.
 *
 * (c) Fabien Potencier <fabien@symfony.com>
 *
 * For the full copyright and license information, please view the LICENSE
 * file that was distributed with this source code.
 */

namespace Symfony\Component\DependencyInjection\Loader\Configurator\Traits;

use Symfony\Component\DependencyInjection\Exception\InvalidArgumentException;

trait DeprecateTrait
{
    /**
     * Whether this definition is deprecated, that means it should not be called anymore.
     *
     * @param string $package The name of the composer package that is triggering the deprecation
     * @param string $version The version of the package that introduced the deprecation
     * @param string $message The deprecation message to use
     *
     * @return $this
     *
     * @throws InvalidArgumentException when the message template is invalid
     */
    final public function deprecate(/* string $package, string $version, string $message */): self
    {
        $args = \func_get_args();
        $package = $version = $message = '';

        if (\func_num_args() < 3) {
            trigger_deprecation('symfony/dependency-injection', '5.1', 'The signature of method "%s()" requires 3 arguments: "string $package, string $version, string $message", not defining them is deprecated.', __METHOD__);

            $message = (string) ($args[0] ?? null);
        } else {
            $package = (string) $args[0];
            $version = (string) $args[1];
            $message = (string) $args[2];
        }

        $this->definition->setDeprecated($package, $version, $message);

        return $this;
    }
}
PKϤ$Z39.�!!>dependency-injection/Loader/Configurator/Traits/ClassTrait.phpnu�[���<?php

/*
 * This file is part of the Symfony package.
 *
 * (c) Fabien Potencier <fabien@symfony.com>
 *
 * For the full copyright and license information, please view the LICENSE
 * file that was distributed with this source code.
 */

namespace Symfony\Component\DependencyInjection\Loader\Configurator\Traits;

trait ClassTrait
{
    /**
     * Sets the service class.
     *
     * @return $this
     */
    final public function class(?string $class): self
    {
        $this->definition->setClass($class);

        return $this;
    }
}
PKϤ$Z`�KqUUAdependency-injection/Loader/Configurator/Traits/PropertyTrait.phpnu�[���<?php

/*
 * This file is part of the Symfony package.
 *
 * (c) Fabien Potencier <fabien@symfony.com>
 *
 * For the full copyright and license information, please view the LICENSE
 * file that was distributed with this source code.
 */

namespace Symfony\Component\DependencyInjection\Loader\Configurator\Traits;

trait PropertyTrait
{
    /**
     * Sets a specific property.
     *
     * @return $this
     */
    final public function property(string $name, $value): self
    {
        $this->definition->setProperty($name, static::processValue($value, true));

        return $this;
    }
}
PKϤ$ZdR(u&&Fdependency-injection/Loader/Configurator/Traits/AutoconfigureTrait.phpnu�[���<?php

/*
 * This file is part of the Symfony package.
 *
 * (c) Fabien Potencier <fabien@symfony.com>
 *
 * For the full copyright and license information, please view the LICENSE
 * file that was distributed with this source code.
 */

namespace Symfony\Component\DependencyInjection\Loader\Configurator\Traits;

use Symfony\Component\DependencyInjection\Exception\InvalidArgumentException;

trait AutoconfigureTrait
{
    /**
     * Sets whether or not instanceof conditionals should be prepended with a global set.
     *
     * @return $this
     *
     * @throws InvalidArgumentException when a parent is already set
     */
    final public function autoconfigure(bool $autoconfigured = true): self
    {
        $this->definition->setAutoconfigured($autoconfigured);

        return $this;
    }
}
PKϤ$Z��d��Adependency-injection/Loader/Configurator/ServicesConfigurator.phpnu�[���<?php

/*
 * This file is part of the Symfony package.
 *
 * (c) Fabien Potencier <fabien@symfony.com>
 *
 * For the full copyright and license information, please view the LICENSE
 * file that was distributed with this source code.
 */

namespace Symfony\Component\DependencyInjection\Loader\Configurator;

use Symfony\Component\DependencyInjection\Alias;
use Symfony\Component\DependencyInjection\ChildDefinition;
use Symfony\Component\DependencyInjection\ContainerBuilder;
use Symfony\Component\DependencyInjection\Definition;
use Symfony\Component\DependencyInjection\Exception\InvalidArgumentException;
use Symfony\Component\DependencyInjection\Exception\ServiceNotFoundException;
use Symfony\Component\DependencyInjection\Loader\PhpFileLoader;

/**
 * @author Nicolas Grekas <p@tchwork.com>
 */
class ServicesConfigurator extends AbstractConfigurator
{
    const FACTORY = 'services';

    private $defaults;
    private $container;
    private $loader;
    private $instanceof;
    private $path;
    private $anonymousHash;
    private $anonymousCount;

    public function __construct(ContainerBuilder $container, PhpFileLoader $loader, array &$instanceof, string $path = null, int &$anonymousCount = 0)
    {
        $this->defaults = new Definition();
        $this->container = $container;
        $this->loader = $loader;
        $this->instanceof = &$instanceof;
        $this->path = $path;
        $this->anonymousHash = ContainerBuilder::hash($path ?: mt_rand());
        $this->anonymousCount = &$anonymousCount;
        $instanceof = [];
    }

    /**
     * Defines a set of defaults for following service definitions.
     */
    final public function defaults(): DefaultsConfigurator
    {
        return new DefaultsConfigurator($this, $this->defaults = new Definition(), $this->path);
    }

    /**
     * Defines an instanceof-conditional to be applied to following service definitions.
     */
    final public function instanceof(string $fqcn): InstanceofConfigurator
    {
        $this->instanceof[$fqcn] = $definition = new ChildDefinition('');

        return new InstanceofConfigurator($this, $definition, $fqcn, $this->path);
    }

    /**
     * Registers a service.
     *
     * @param string|null $id    The service id, or null to create an anonymous service
     * @param string|null $class The class of the service, or null when $id is also the class name
     */
    final public function set(?string $id, string $class = null): ServiceConfigurator
    {
        $defaults = $this->defaults;
        $definition = new Definition();

        if (null === $id) {
            if (!$class) {
                throw new \LogicException('Anonymous services must have a class name.');
            }

            $id = sprintf('.%d_%s', ++$this->anonymousCount, preg_replace('/^.*\\\\/', '', $class).'~'.$this->anonymousHash);
            $definition->setPublic(false);
        } elseif (!$defaults->isPublic() || !$defaults->isPrivate()) {
            $definition->setPublic($defaults->isPublic() && !$defaults->isPrivate());
        }

        $definition->setAutowired($defaults->isAutowired());
        $definition->setAutoconfigured($defaults->isAutoconfigured());
        // deep clone, to avoid multiple process of the same instance in the passes
        $definition->setBindings(unserialize(serialize($defaults->getBindings())));
        $definition->setChanges([]);

        $configurator = new ServiceConfigurator($this->container, $this->instanceof, true, $this, $definition, $id, $defaults->getTags(), $this->path);

        return null !== $class ? $configurator->class($class) : $configurator;
    }

    /**
     * Creates an alias.
     */
    final public function alias(string $id, string $referencedId): AliasConfigurator
    {
        $ref = static::processValue($referencedId, true);
        $alias = new Alias((string) $ref);
        if (!$this->defaults->isPublic() || !$this->defaults->isPrivate()) {
            $alias->setPublic($this->defaults->isPublic());
        }
        $this->container->setAlias($id, $alias);

        return new AliasConfigurator($this, $alias);
    }

    /**
     * Registers a PSR-4 namespace using a glob pattern.
     */
    final public function load(string $namespace, string $resource): PrototypeConfigurator
    {
        return new PrototypeConfigurator($this, $this->loader, $this->defaults, $namespace, $resource, true);
    }

    /**
     * Gets an already defined service definition.
     *
     * @throws ServiceNotFoundException if the service definition does not exist
     */
    final public function get(string $id): ServiceConfigurator
    {
        $definition = $this->container->getDefinition($id);

        return new ServiceConfigurator($this->container, $definition->getInstanceofConditionals(), true, $this, $definition, $id, []);
    }

    /**
     * Registers a stack of decorator services.
     *
     * @param InlineServiceConfigurator[]|ReferenceConfigurator[] $services
     */
    final public function stack(string $id, array $services): AliasConfigurator
    {
        foreach ($services as $i => $service) {
            if ($service instanceof InlineServiceConfigurator) {
                $definition = $service->definition->setInstanceofConditionals($this->instanceof);

                $changes = $definition->getChanges();
                $definition->setAutowired((isset($changes['autowired']) ? $definition : $this->defaults)->isAutowired());
                $definition->setAutoconfigured((isset($changes['autoconfigured']) ? $definition : $this->defaults)->isAutoconfigured());
                $definition->setBindings(array_merge($this->defaults->getBindings(), $definition->getBindings()));
                $definition->setChanges($changes);

                $services[$i] = $definition;
            } elseif (!$service instanceof ReferenceConfigurator) {
                throw new InvalidArgumentException(sprintf('"%s()" expects a list of definitions as returned by "%s()" or "%s()", "%s" given at index "%s" for service "%s".', __METHOD__, InlineServiceConfigurator::FACTORY, ReferenceConfigurator::FACTORY, $service instanceof AbstractConfigurator ? $service::FACTORY.'()' : get_debug_type($service), $i, $id));
            }
        }

        $alias = $this->alias($id, '');
        $alias->definition = $this->set($id)
            ->parent('')
            ->args($services)
            ->tag('container.stack')
            ->definition;

        return $alias;
    }

    /**
     * Registers a service.
     */
    final public function __invoke(string $id, string $class = null): ServiceConfigurator
    {
        return $this->set($id, $class);
    }

    public function __destruct()
    {
        $this->loader->registerAliasesForSinglyImplementedInterfaces();
    }
}
PKϤ$Zj?��Bdependency-injection/Loader/Configurator/ReferenceConfigurator.phpnu�[���<?php

/*
 * This file is part of the Symfony package.
 *
 * (c) Fabien Potencier <fabien@symfony.com>
 *
 * For the full copyright and license information, please view the LICENSE
 * file that was distributed with this source code.
 */

namespace Symfony\Component\DependencyInjection\Loader\Configurator;

use Symfony\Component\DependencyInjection\ContainerInterface;

/**
 * @author Nicolas Grekas <p@tchwork.com>
 */
class ReferenceConfigurator extends AbstractConfigurator
{
    /** @internal */
    protected $id;

    /** @internal */
    protected $invalidBehavior = ContainerInterface::EXCEPTION_ON_INVALID_REFERENCE;

    public function __construct(string $id)
    {
        $this->id = $id;
    }

    /**
     * @return $this
     */
    final public function ignoreOnInvalid(): self
    {
        $this->invalidBehavior = ContainerInterface::IGNORE_ON_INVALID_REFERENCE;

        return $this;
    }

    /**
     * @return $this
     */
    final public function nullOnInvalid(): self
    {
        $this->invalidBehavior = ContainerInterface::NULL_ON_INVALID_REFERENCE;

        return $this;
    }

    /**
     * @return $this
     */
    final public function ignoreOnUninitialized(): self
    {
        $this->invalidBehavior = ContainerInterface::IGNORE_ON_UNINITIALIZED_REFERENCE;

        return $this;
    }

    /**
     * @return string
     */
    public function __toString()
    {
        return $this->id;
    }
}
PKϤ$Z�����Adependency-injection/Loader/Configurator/AbstractConfigurator.phpnu�[���<?php

/*
 * This file is part of the Symfony package.
 *
 * (c) Fabien Potencier <fabien@symfony.com>
 *
 * For the full copyright and license information, please view the LICENSE
 * file that was distributed with this source code.
 */

namespace Symfony\Component\DependencyInjection\Loader\Configurator;

use Symfony\Component\DependencyInjection\Argument\AbstractArgument;
use Symfony\Component\DependencyInjection\Argument\ArgumentInterface;
use Symfony\Component\DependencyInjection\Definition;
use Symfony\Component\DependencyInjection\Exception\InvalidArgumentException;
use Symfony\Component\DependencyInjection\Parameter;
use Symfony\Component\DependencyInjection\Reference;
use Symfony\Component\ExpressionLanguage\Expression;

abstract class AbstractConfigurator
{
    const FACTORY = 'unknown';

    /**
     * @var callable(mixed $value, bool $allowService)|null
     */
    public static $valuePreProcessor;

    /** @internal */
    protected $definition;

    public function __call(string $method, array $args)
    {
        if (method_exists($this, 'set'.$method)) {
            return $this->{'set'.$method}(...$args);
        }

        throw new \BadMethodCallException(sprintf('Call to undefined method "%s::%s()".', static::class, $method));
    }

    /**
     * Checks that a value is valid, optionally replacing Definition and Reference configurators by their configure value.
     *
     * @param mixed $value
     * @param bool  $allowServices whether Definition and Reference are allowed; by default, only scalars and arrays are
     *
     * @return mixed the value, optionally cast to a Definition/Reference
     */
    public static function processValue($value, $allowServices = false)
    {
        if (\is_array($value)) {
            foreach ($value as $k => $v) {
                $value[$k] = static::processValue($v, $allowServices);
            }

            return self::$valuePreProcessor ? (self::$valuePreProcessor)($value, $allowServices) : $value;
        }

        if (self::$valuePreProcessor) {
            $value = (self::$valuePreProcessor)($value, $allowServices);
        }

        if ($value instanceof ReferenceConfigurator) {
            return new Reference($value->id, $value->invalidBehavior);
        }

        if ($value instanceof InlineServiceConfigurator) {
            $def = $value->definition;
            $value->definition = null;

            return $def;
        }

        if ($value instanceof self) {
            throw new InvalidArgumentException(sprintf('"%s()" can be used only at the root of service configuration files.', $value::FACTORY));
        }

        switch (true) {
            case null === $value:
            case is_scalar($value):
                return $value;

            case $value instanceof ArgumentInterface:
            case $value instanceof Definition:
            case $value instanceof Expression:
            case $value instanceof Parameter:
            case $value instanceof AbstractArgument:
            case $value instanceof Reference:
                if ($allowServices) {
                    return $value;
                }
        }

        throw new InvalidArgumentException(sprintf('Cannot use values of type "%s" in service configuration files.', get_debug_type($value)));
    }
}
PKϤ$Z�DECjj@dependency-injection/Loader/Configurator/ServiceConfigurator.phpnu�[���<?php

/*
 * This file is part of the Symfony package.
 *
 * (c) Fabien Potencier <fabien@symfony.com>
 *
 * For the full copyright and license information, please view the LICENSE
 * file that was distributed with this source code.
 */

namespace Symfony\Component\DependencyInjection\Loader\Configurator;

use Symfony\Component\DependencyInjection\ContainerBuilder;
use Symfony\Component\DependencyInjection\Definition;

/**
 * @author Nicolas Grekas <p@tchwork.com>
 */
class ServiceConfigurator extends AbstractServiceConfigurator
{
    const FACTORY = 'services';

    use Traits\AbstractTrait;
    use Traits\ArgumentTrait;
    use Traits\AutoconfigureTrait;
    use Traits\AutowireTrait;
    use Traits\BindTrait;
    use Traits\CallTrait;
    use Traits\ClassTrait;
    use Traits\ConfiguratorTrait;
    use Traits\DecorateTrait;
    use Traits\DeprecateTrait;
    use Traits\FactoryTrait;
    use Traits\FileTrait;
    use Traits\LazyTrait;
    use Traits\ParentTrait;
    use Traits\PropertyTrait;
    use Traits\PublicTrait;
    use Traits\ShareTrait;
    use Traits\SyntheticTrait;
    use Traits\TagTrait;

    private $container;
    private $instanceof;
    private $allowParent;
    private $path;

    public function __construct(ContainerBuilder $container, array $instanceof, bool $allowParent, ServicesConfigurator $parent, Definition $definition, $id, array $defaultTags, string $path = null)
    {
        $this->container = $container;
        $this->instanceof = $instanceof;
        $this->allowParent = $allowParent;
        $this->path = $path;

        parent::__construct($parent, $definition, $id, $defaultTags);
    }

    public function __destruct()
    {
        parent::__destruct();

        $this->container->removeBindings($this->id);
        $this->container->setDefinition($this->id, $this->definition->setInstanceofConditionals($this->instanceof));
    }
}
PKϤ$ZXg�bbBdependency-injection/Loader/Configurator/ContainerConfigurator.phpnu�[���<?php

/*
 * This file is part of the Symfony package.
 *
 * (c) Fabien Potencier <fabien@symfony.com>
 *
 * For the full copyright and license information, please view the LICENSE
 * file that was distributed with this source code.
 */

namespace Symfony\Component\DependencyInjection\Loader\Configurator;

use Symfony\Component\DependencyInjection\Argument\IteratorArgument;
use Symfony\Component\DependencyInjection\Argument\ServiceLocatorArgument;
use Symfony\Component\DependencyInjection\Argument\TaggedIteratorArgument;
use Symfony\Component\DependencyInjection\ContainerBuilder;
use Symfony\Component\DependencyInjection\Definition;
use Symfony\Component\DependencyInjection\Exception\InvalidArgumentException;
use Symfony\Component\DependencyInjection\Extension\ExtensionInterface;
use Symfony\Component\DependencyInjection\Loader\PhpFileLoader;
use Symfony\Component\ExpressionLanguage\Expression;

/**
 * @author Nicolas Grekas <p@tchwork.com>
 */
class ContainerConfigurator extends AbstractConfigurator
{
    const FACTORY = 'container';

    private $container;
    private $loader;
    private $instanceof;
    private $path;
    private $file;
    private $anonymousCount = 0;

    public function __construct(ContainerBuilder $container, PhpFileLoader $loader, array &$instanceof, string $path, string $file)
    {
        $this->container = $container;
        $this->loader = $loader;
        $this->instanceof = &$instanceof;
        $this->path = $path;
        $this->file = $file;
    }

    final public function extension(string $namespace, array $config)
    {
        if (!$this->container->hasExtension($namespace)) {
            $extensions = array_filter(array_map(function (ExtensionInterface $ext) { return $ext->getAlias(); }, $this->container->getExtensions()));
            throw new InvalidArgumentException(sprintf('There is no extension able to load the configuration for "%s" (in "%s"). Looked for namespace "%s", found "%s".', $namespace, $this->file, $namespace, $extensions ? implode('", "', $extensions) : 'none'));
        }

        $this->container->loadFromExtension($namespace, static::processValue($config));
    }

    final public function import(string $resource, string $type = null, $ignoreErrors = false)
    {
        $this->loader->setCurrentDir(\dirname($this->path));
        $this->loader->import($resource, $type, $ignoreErrors, $this->file);
    }

    final public function parameters(): ParametersConfigurator
    {
        return new ParametersConfigurator($this->container);
    }

    final public function services(): ServicesConfigurator
    {
        return new ServicesConfigurator($this->container, $this->loader, $this->instanceof, $this->path, $this->anonymousCount);
    }

    /**
     * @return static
     */
    final public function withPath(string $path): self
    {
        $clone = clone $this;
        $clone->path = $clone->file = $path;

        return $clone;
    }
}

/**
 * Creates a service reference.
 *
 * @deprecated since Symfony 5.1, use service() instead.
 */
function ref(string $id): ReferenceConfigurator
{
    trigger_deprecation('symfony/dependency-injection', '5.1', '"%s()" is deprecated, use "service()" instead.', __FUNCTION__);

    return new ReferenceConfigurator($id);
}

/**
 * Creates a reference to a service.
 */
function service(string $serviceId): ReferenceConfigurator
{
    return new ReferenceConfigurator($serviceId);
}

/**
 * Creates an inline service.
 *
 * @deprecated since Symfony 5.1, use inline_service() instead.
 */
function inline(string $class = null): InlineServiceConfigurator
{
    trigger_deprecation('symfony/dependency-injection', '5.1', '"%s()" is deprecated, use "inline_service()" instead.', __FUNCTION__);

    return new InlineServiceConfigurator(new Definition($class));
}

/**
 * Creates an inline service.
 */
function inline_service(string $class = null): InlineServiceConfigurator
{
    return new InlineServiceConfigurator(new Definition($class));
}

/**
 * Creates a service locator.
 *
 * @param ReferenceConfigurator[] $values
 */
function service_locator(array $values): ServiceLocatorArgument
{
    return new ServiceLocatorArgument(AbstractConfigurator::processValue($values, true));
}

/**
 * Creates a lazy iterator.
 *
 * @param ReferenceConfigurator[] $values
 */
function iterator(array $values): IteratorArgument
{
    return new IteratorArgument(AbstractConfigurator::processValue($values, true));
}

/**
 * Creates a lazy iterator by tag name.
 */
function tagged_iterator(string $tag, string $indexAttribute = null, string $defaultIndexMethod = null, string $defaultPriorityMethod = null): TaggedIteratorArgument
{
    return new TaggedIteratorArgument($tag, $indexAttribute, $defaultIndexMethod, false, $defaultPriorityMethod);
}

/**
 * Creates a service locator by tag name.
 */
function tagged_locator(string $tag, string $indexAttribute = null, string $defaultIndexMethod = null): ServiceLocatorArgument
{
    return new ServiceLocatorArgument(new TaggedIteratorArgument($tag, $indexAttribute, $defaultIndexMethod, true));
}

/**
 * Creates an expression.
 */
function expr(string $expression): Expression
{
    return new Expression($expression);
}
PKϤ$ZP{��Cdependency-injection/Loader/Configurator/InstanceofConfigurator.phpnu�[���<?php

/*
 * This file is part of the Symfony package.
 *
 * (c) Fabien Potencier <fabien@symfony.com>
 *
 * For the full copyright and license information, please view the LICENSE
 * file that was distributed with this source code.
 */

namespace Symfony\Component\DependencyInjection\Loader\Configurator;

use Symfony\Component\DependencyInjection\Definition;

/**
 * @author Nicolas Grekas <p@tchwork.com>
 */
class InstanceofConfigurator extends AbstractServiceConfigurator
{
    const FACTORY = 'instanceof';

    use Traits\AutowireTrait;
    use Traits\BindTrait;
    use Traits\CallTrait;
    use Traits\ConfiguratorTrait;
    use Traits\LazyTrait;
    use Traits\PropertyTrait;
    use Traits\PublicTrait;
    use Traits\ShareTrait;
    use Traits\TagTrait;

    private $path;

    public function __construct(ServicesConfigurator $parent, Definition $definition, string $id, string $path = null)
    {
        parent::__construct($parent, $definition, $id, []);

        $this->path = $path;
    }

    /**
     * Defines an instanceof-conditional to be applied to following service definitions.
     */
    final public function instanceof(string $fqcn): self
    {
        return $this->parent->instanceof($fqcn);
    }
}
PKϤ$Z��Z|�|�.dependency-injection/Loader/YamlFileLoader.phpnu�[���<?php

/*
 * This file is part of the Symfony package.
 *
 * (c) Fabien Potencier <fabien@symfony.com>
 *
 * For the full copyright and license information, please view the LICENSE
 * file that was distributed with this source code.
 */

namespace Symfony\Component\DependencyInjection\Loader;

use Symfony\Component\DependencyInjection\Alias;
use Symfony\Component\DependencyInjection\Argument\AbstractArgument;
use Symfony\Component\DependencyInjection\Argument\ArgumentInterface;
use Symfony\Component\DependencyInjection\Argument\BoundArgument;
use Symfony\Component\DependencyInjection\Argument\IteratorArgument;
use Symfony\Component\DependencyInjection\Argument\ServiceLocatorArgument;
use Symfony\Component\DependencyInjection\Argument\TaggedIteratorArgument;
use Symfony\Component\DependencyInjection\ChildDefinition;
use Symfony\Component\DependencyInjection\ContainerBuilder;
use Symfony\Component\DependencyInjection\ContainerInterface;
use Symfony\Component\DependencyInjection\Definition;
use Symfony\Component\DependencyInjection\Exception\InvalidArgumentException;
use Symfony\Component\DependencyInjection\Exception\RuntimeException;
use Symfony\Component\DependencyInjection\Extension\ExtensionInterface;
use Symfony\Component\DependencyInjection\Reference;
use Symfony\Component\ExpressionLanguage\Expression;
use Symfony\Component\Yaml\Exception\ParseException;
use Symfony\Component\Yaml\Parser as YamlParser;
use Symfony\Component\Yaml\Tag\TaggedValue;
use Symfony\Component\Yaml\Yaml;

/**
 * YamlFileLoader loads YAML files service definitions.
 *
 * @author Fabien Potencier <fabien@symfony.com>
 */
class YamlFileLoader extends FileLoader
{
    private static $serviceKeywords = [
        'alias' => 'alias',
        'parent' => 'parent',
        'class' => 'class',
        'shared' => 'shared',
        'synthetic' => 'synthetic',
        'lazy' => 'lazy',
        'public' => 'public',
        'abstract' => 'abstract',
        'deprecated' => 'deprecated',
        'factory' => 'factory',
        'file' => 'file',
        'arguments' => 'arguments',
        'properties' => 'properties',
        'configurator' => 'configurator',
        'calls' => 'calls',
        'tags' => 'tags',
        'decorates' => 'decorates',
        'decoration_inner_name' => 'decoration_inner_name',
        'decoration_priority' => 'decoration_priority',
        'decoration_on_invalid' => 'decoration_on_invalid',
        'autowire' => 'autowire',
        'autoconfigure' => 'autoconfigure',
        'bind' => 'bind',
    ];

    private static $prototypeKeywords = [
        'resource' => 'resource',
        'namespace' => 'namespace',
        'exclude' => 'exclude',
        'parent' => 'parent',
        'shared' => 'shared',
        'lazy' => 'lazy',
        'public' => 'public',
        'abstract' => 'abstract',
        'deprecated' => 'deprecated',
        'factory' => 'factory',
        'arguments' => 'arguments',
        'properties' => 'properties',
        'configurator' => 'configurator',
        'calls' => 'calls',
        'tags' => 'tags',
        'autowire' => 'autowire',
        'autoconfigure' => 'autoconfigure',
        'bind' => 'bind',
    ];

    private static $instanceofKeywords = [
        'shared' => 'shared',
        'lazy' => 'lazy',
        'public' => 'public',
        'properties' => 'properties',
        'configurator' => 'configurator',
        'calls' => 'calls',
        'tags' => 'tags',
        'autowire' => 'autowire',
        'bind' => 'bind',
    ];

    private static $defaultsKeywords = [
        'public' => 'public',
        'tags' => 'tags',
        'autowire' => 'autowire',
        'autoconfigure' => 'autoconfigure',
        'bind' => 'bind',
    ];

    private $yamlParser;

    private $anonymousServicesCount;
    private $anonymousServicesSuffix;

    protected $autoRegisterAliasesForSinglyImplementedInterfaces = false;

    /**
     * {@inheritdoc}
     */
    public function load($resource, string $type = null)
    {
        $path = $this->locator->locate($resource);

        $content = $this->loadFile($path);

        $this->container->fileExists($path);

        // empty file
        if (null === $content) {
            return;
        }

        // imports
        $this->parseImports($content, $path);

        // parameters
        if (isset($content['parameters'])) {
            if (!\is_array($content['parameters'])) {
                throw new InvalidArgumentException(sprintf('The "parameters" key should contain an array in "%s". Check your YAML syntax.', $path));
            }

            foreach ($content['parameters'] as $key => $value) {
                $this->container->setParameter($key, $this->resolveServices($value, $path, true));
            }
        }

        // extensions
        $this->loadFromExtensions($content);

        // services
        $this->anonymousServicesCount = 0;
        $this->anonymousServicesSuffix = '~'.ContainerBuilder::hash($path);
        $this->setCurrentDir(\dirname($path));
        try {
            $this->parseDefinitions($content, $path);
        } finally {
            $this->instanceof = [];
            $this->registerAliasesForSinglyImplementedInterfaces();
        }
    }

    /**
     * {@inheritdoc}
     */
    public function supports($resource, string $type = null)
    {
        if (!\is_string($resource)) {
            return false;
        }

        if (null === $type && \in_array(pathinfo($resource, \PATHINFO_EXTENSION), ['yaml', 'yml'], true)) {
            return true;
        }

        return \in_array($type, ['yaml', 'yml'], true);
    }

    private function parseImports(array $content, string $file)
    {
        if (!isset($content['imports'])) {
            return;
        }

        if (!\is_array($content['imports'])) {
            throw new InvalidArgumentException(sprintf('The "imports" key should contain an array in "%s". Check your YAML syntax.', $file));
        }

        $defaultDirectory = \dirname($file);
        foreach ($content['imports'] as $import) {
            if (!\is_array($import)) {
                $import = ['resource' => $import];
            }
            if (!isset($import['resource'])) {
                throw new InvalidArgumentException(sprintf('An import should provide a resource in "%s". Check your YAML syntax.', $file));
            }

            $this->setCurrentDir($defaultDirectory);
            $this->import($import['resource'], $import['type'] ?? null, $import['ignore_errors'] ?? false, $file);
        }
    }

    private function parseDefinitions(array $content, string $file)
    {
        if (!isset($content['services'])) {
            return;
        }

        if (!\is_array($content['services'])) {
            throw new InvalidArgumentException(sprintf('The "services" key should contain an array in "%s". Check your YAML syntax.', $file));
        }

        if (\array_key_exists('_instanceof', $content['services'])) {
            $instanceof = $content['services']['_instanceof'];
            unset($content['services']['_instanceof']);

            if (!\is_array($instanceof)) {
                throw new InvalidArgumentException(sprintf('Service "_instanceof" key must be an array, "%s" given in "%s".', get_debug_type($instanceof), $file));
            }
            $this->instanceof = [];
            $this->isLoadingInstanceof = true;
            foreach ($instanceof as $id => $service) {
                if (!$service || !\is_array($service)) {
                    throw new InvalidArgumentException(sprintf('Type definition "%s" must be a non-empty array within "_instanceof" in "%s". Check your YAML syntax.', $id, $file));
                }
                if (\is_string($service) && 0 === strpos($service, '@')) {
                    throw new InvalidArgumentException(sprintf('Type definition "%s" cannot be an alias within "_instanceof" in "%s". Check your YAML syntax.', $id, $file));
                }
                $this->parseDefinition($id, $service, $file, []);
            }
        }

        $this->isLoadingInstanceof = false;
        $defaults = $this->parseDefaults($content, $file);
        foreach ($content['services'] as $id => $service) {
            $this->parseDefinition($id, $service, $file, $defaults);
        }
    }

    /**
     * @throws InvalidArgumentException
     */
    private function parseDefaults(array &$content, string $file): array
    {
        if (!\array_key_exists('_defaults', $content['services'])) {
            return [];
        }
        $defaults = $content['services']['_defaults'];
        unset($content['services']['_defaults']);

        if (!\is_array($defaults)) {
            throw new InvalidArgumentException(sprintf('Service "_defaults" key must be an array, "%s" given in "%s".', get_debug_type($defaults), $file));
        }

        foreach ($defaults as $key => $default) {
            if (!isset(self::$defaultsKeywords[$key])) {
                throw new InvalidArgumentException(sprintf('The configuration key "%s" cannot be used to define a default value in "%s". Allowed keys are "%s".', $key, $file, implode('", "', self::$defaultsKeywords)));
            }
        }

        if (isset($defaults['tags'])) {
            if (!\is_array($tags = $defaults['tags'])) {
                throw new InvalidArgumentException(sprintf('Parameter "tags" in "_defaults" must be an array in "%s". Check your YAML syntax.', $file));
            }

            foreach ($tags as $tag) {
                if (!\is_array($tag)) {
                    $tag = ['name' => $tag];
                }

                if (1 === \count($tag) && \is_array(current($tag))) {
                    $name = key($tag);
                    $tag = current($tag);
                } else {
                    if (!isset($tag['name'])) {
                        throw new InvalidArgumentException(sprintf('A "tags" entry in "_defaults" is missing a "name" key in "%s".', $file));
                    }
                    $name = $tag['name'];
                    unset($tag['name']);
                }

                if (!\is_string($name) || '' === $name) {
                    throw new InvalidArgumentException(sprintf('The tag name in "_defaults" must be a non-empty string in "%s".', $file));
                }

                foreach ($tag as $attribute => $value) {
                    if (!is_scalar($value) && null !== $value) {
                        throw new InvalidArgumentException(sprintf('Tag "%s", attribute "%s" in "_defaults" must be of a scalar-type in "%s". Check your YAML syntax.', $name, $attribute, $file));
                    }
                }
            }
        }

        if (isset($defaults['bind'])) {
            if (!\is_array($defaults['bind'])) {
                throw new InvalidArgumentException(sprintf('Parameter "bind" in "_defaults" must be an array in "%s". Check your YAML syntax.', $file));
            }

            foreach ($this->resolveServices($defaults['bind'], $file) as $argument => $value) {
                $defaults['bind'][$argument] = new BoundArgument($value, true, BoundArgument::DEFAULTS_BINDING, $file);
            }
        }

        return $defaults;
    }

    private function isUsingShortSyntax(array $service): bool
    {
        foreach ($service as $key => $value) {
            if (\is_string($key) && ('' === $key || ('$' !== $key[0] && false === strpos($key, '\\')))) {
                return false;
            }
        }

        return true;
    }

    /**
     * Parses a definition.
     *
     * @param array|string $service
     *
     * @throws InvalidArgumentException When tags are invalid
     */
    private function parseDefinition(string $id, $service, string $file, array $defaults, bool $return = false)
    {
        if (preg_match('/^_[a-zA-Z0-9_]*$/', $id)) {
            throw new InvalidArgumentException(sprintf('Service names that start with an underscore are reserved. Rename the "%s" service or define it in XML instead.', $id));
        }

        if (\is_string($service) && 0 === strpos($service, '@')) {
            $alias = new Alias(substr($service, 1));

            if (isset($defaults['public'])) {
                $alias->setPublic($defaults['public']);
            }

            return $return ? $alias : $this->container->setAlias($id, $alias);
        }

        if (\is_array($service) && $this->isUsingShortSyntax($service)) {
            $service = ['arguments' => $service];
        }

        if (null === $service) {
            $service = [];
        }

        if (!\is_array($service)) {
            throw new InvalidArgumentException(sprintf('A service definition must be an array or a string starting with "@" but "%s" found for service "%s" in "%s". Check your YAML syntax.', get_debug_type($service), $id, $file));
        }

        if (isset($service['stack'])) {
            if (!\is_array($service['stack'])) {
                throw new InvalidArgumentException(sprintf('A stack must be an array of definitions, "%s" given for service "%s" in "%s". Check your YAML syntax.', get_debug_type($service), $id, $file));
            }

            $stack = [];

            foreach ($service['stack'] as $k => $frame) {
                if (\is_array($frame) && 1 === \count($frame) && !isset(self::$serviceKeywords[key($frame)])) {
                    $frame = [
                        'class' => key($frame),
                        'arguments' => current($frame),
                    ];
                }

                if (\is_array($frame) && isset($frame['stack'])) {
                    throw new InvalidArgumentException(sprintf('Service stack "%s" cannot contain another stack in "%s".', $id, $file));
                }

                $definition = $this->parseDefinition($id.'" at index "'.$k, $frame, $file, $defaults, true);

                if ($definition instanceof Definition) {
                    $definition->setInstanceofConditionals($this->instanceof);
                }

                $stack[$k] = $definition;
            }

            if ($diff = array_diff(array_keys($service), ['stack', 'public', 'deprecated'])) {
                throw new InvalidArgumentException(sprintf('Invalid attribute "%s"; supported ones are "public" and "deprecated" for service "%s" in "%s". Check your YAML syntax.', implode('", "', $diff), $id, $file));
            }

            $service = [
                'parent' => '',
                'arguments' => $stack,
                'tags' => ['container.stack'],
                'public' => $service['public'] ?? null,
                'deprecated' => $service['deprecated'] ?? null,
            ];
        }

        $this->checkDefinition($id, $service, $file);

        if (isset($service['alias'])) {
            $alias = new Alias($service['alias']);

            if (isset($service['public'])) {
                $alias->setPublic($service['public']);
            } elseif (isset($defaults['public'])) {
                $alias->setPublic($defaults['public']);
            }

            foreach ($service as $key => $value) {
                if (!\in_array($key, ['alias', 'public', 'deprecated'])) {
                    throw new InvalidArgumentException(sprintf('The configuration key "%s" is unsupported for the service "%s" which is defined as an alias in "%s". Allowed configuration keys for service aliases are "alias", "public" and "deprecated".', $key, $id, $file));
                }

                if ('deprecated' === $key) {
                    $deprecation = \is_array($value) ? $value : ['message' => $value];

                    if (!isset($deprecation['package'])) {
                        trigger_deprecation('symfony/dependency-injection', '5.1', 'Not setting the attribute "package" of the "deprecated" option in "%s" is deprecated.', $file);
                    }

                    if (!isset($deprecation['version'])) {
                        trigger_deprecation('symfony/dependency-injection', '5.1', 'Not setting the attribute "version" of the "deprecated" option in "%s" is deprecated.', $file);
                    }

                    $alias->setDeprecated($deprecation['package'] ?? '', $deprecation['version'] ?? '', $deprecation['message']);
                }
            }

            return $return ? $alias : $this->container->setAlias($id, $alias);
        }

        if ($this->isLoadingInstanceof) {
            $definition = new ChildDefinition('');
        } elseif (isset($service['parent'])) {
            if ('' !== $service['parent'] && '@' === $service['parent'][0]) {
                throw new InvalidArgumentException(sprintf('The value of the "parent" option for the "%s" service must be the id of the service without the "@" prefix (replace "%s" with "%s").', $id, $service['parent'], substr($service['parent'], 1)));
            }

            $definition = new ChildDefinition($service['parent']);
        } else {
            $definition = new Definition();
        }

        if (isset($defaults['public'])) {
            $definition->setPublic($defaults['public']);
        }
        if (isset($defaults['autowire'])) {
            $definition->setAutowired($defaults['autowire']);
        }
        if (isset($defaults['autoconfigure'])) {
            $definition->setAutoconfigured($defaults['autoconfigure']);
        }

        $definition->setChanges([]);

        if (isset($service['class'])) {
            $definition->setClass($service['class']);
        }

        if (isset($service['shared'])) {
            $definition->setShared($service['shared']);
        }

        if (isset($service['synthetic'])) {
            $definition->setSynthetic($service['synthetic']);
        }

        if (isset($service['lazy'])) {
            $definition->setLazy((bool) $service['lazy']);
            if (\is_string($service['lazy'])) {
                $definition->addTag('proxy', ['interface' => $service['lazy']]);
            }
        }

        if (isset($service['public'])) {
            $definition->setPublic($service['public']);
        }

        if (isset($service['abstract'])) {
            $definition->setAbstract($service['abstract']);
        }

        if (isset($service['deprecated'])) {
            $deprecation = \is_array($service['deprecated']) ? $service['deprecated'] : ['message' => $service['deprecated']];

            if (!isset($deprecation['package'])) {
                trigger_deprecation('symfony/dependency-injection', '5.1', 'Not setting the attribute "package" of the "deprecated" option in "%s" is deprecated.', $file);
            }

            if (!isset($deprecation['version'])) {
                trigger_deprecation('symfony/dependency-injection', '5.1', 'Not setting the attribute "version" of the "deprecated" option in "%s" is deprecated.', $file);
            }

            $definition->setDeprecated($deprecation['package'] ?? '', $deprecation['version'] ?? '', $deprecation['message']);
        }

        if (isset($service['factory'])) {
            $definition->setFactory($this->parseCallable($service['factory'], 'factory', $id, $file));
        }

        if (isset($service['file'])) {
            $definition->setFile($service['file']);
        }

        if (isset($service['arguments'])) {
            $definition->setArguments($this->resolveServices($service['arguments'], $file));
        }

        if (isset($service['properties'])) {
            $definition->setProperties($this->resolveServices($service['properties'], $file));
        }

        if (isset($service['configurator'])) {
            $definition->setConfigurator($this->parseCallable($service['configurator'], 'configurator', $id, $file));
        }

        if (isset($service['calls'])) {
            if (!\is_array($service['calls'])) {
                throw new InvalidArgumentException(sprintf('Parameter "calls" must be an array for service "%s" in "%s". Check your YAML syntax.', $id, $file));
            }

            foreach ($service['calls'] as $k => $call) {
                if (!\is_array($call) && (!\is_string($k) || !$call instanceof TaggedValue)) {
                    throw new InvalidArgumentException(sprintf('Invalid method call for service "%s": expected map or array, "%s" given in "%s".', $id, $call instanceof TaggedValue ? '!'.$call->getTag() : get_debug_type($call), $file));
                }

                if (\is_string($k)) {
                    throw new InvalidArgumentException(sprintf('Invalid method call for service "%s", did you forgot a leading dash before "%s: ..." in "%s"?', $id, $k, $file));
                }

                if (isset($call['method'])) {
                    $method = $call['method'];
                    $args = $call['arguments'] ?? [];
                    $returnsClone = $call['returns_clone'] ?? false;
                } else {
                    if (1 === \count($call) && \is_string(key($call))) {
                        $method = key($call);
                        $args = $call[$method];

                        if ($args instanceof TaggedValue) {
                            if ('returns_clone' !== $args->getTag()) {
                                throw new InvalidArgumentException(sprintf('Unsupported tag "!%s", did you mean "!returns_clone" for service "%s" in "%s"?', $args->getTag(), $id, $file));
                            }

                            $returnsClone = true;
                            $args = $args->getValue();
                        } else {
                            $returnsClone = false;
                        }
                    } elseif (empty($call[0])) {
                        throw new InvalidArgumentException(sprintf('Invalid call for service "%s": the method must be defined as the first index of an array or as the only key of a map in "%s".', $id, $file));
                    } else {
                        $method = $call[0];
                        $args = $call[1] ?? [];
                        $returnsClone = $call[2] ?? false;
                    }
                }

                if (!\is_array($args)) {
                    throw new InvalidArgumentException(sprintf('The second parameter for function call "%s" must be an array of its arguments for service "%s" in "%s". Check your YAML syntax.', $method, $id, $file));
                }

                $args = $this->resolveServices($args, $file);
                $definition->addMethodCall($method, $args, $returnsClone);
            }
        }

        $tags = isset($service['tags']) ? $service['tags'] : [];
        if (!\is_array($tags)) {
            throw new InvalidArgumentException(sprintf('Parameter "tags" must be an array for service "%s" in "%s". Check your YAML syntax.', $id, $file));
        }

        if (isset($defaults['tags'])) {
            $tags = array_merge($tags, $defaults['tags']);
        }

        foreach ($tags as $tag) {
            if (!\is_array($tag)) {
                $tag = ['name' => $tag];
            }

            if (1 === \count($tag) && \is_array(current($tag))) {
                $name = key($tag);
                $tag = current($tag);
            } else {
                if (!isset($tag['name'])) {
                    throw new InvalidArgumentException(sprintf('A "tags" entry is missing a "name" key for service "%s" in "%s".', $id, $file));
                }
                $name = $tag['name'];
                unset($tag['name']);
            }

            if (!\is_string($name) || '' === $name) {
                throw new InvalidArgumentException(sprintf('The tag name for service "%s" in "%s" must be a non-empty string.', $id, $file));
            }

            foreach ($tag as $attribute => $value) {
                if (!is_scalar($value) && null !== $value) {
                    throw new InvalidArgumentException(sprintf('A "tags" attribute must be of a scalar-type for service "%s", tag "%s", attribute "%s" in "%s". Check your YAML syntax.', $id, $name, $attribute, $file));
                }
            }

            $definition->addTag($name, $tag);
        }

        if (null !== $decorates = $service['decorates'] ?? null) {
            if ('' !== $decorates && '@' === $decorates[0]) {
                throw new InvalidArgumentException(sprintf('The value of the "decorates" option for the "%s" service must be the id of the service without the "@" prefix (replace "%s" with "%s").', $id, $service['decorates'], substr($decorates, 1)));
            }

            $decorationOnInvalid = \array_key_exists('decoration_on_invalid', $service) ? $service['decoration_on_invalid'] : 'exception';
            if ('exception' === $decorationOnInvalid) {
                $invalidBehavior = ContainerInterface::EXCEPTION_ON_INVALID_REFERENCE;
            } elseif ('ignore' === $decorationOnInvalid) {
                $invalidBehavior = ContainerInterface::IGNORE_ON_INVALID_REFERENCE;
            } elseif (null === $decorationOnInvalid) {
                $invalidBehavior = ContainerInterface::NULL_ON_INVALID_REFERENCE;
            } elseif ('null' === $decorationOnInvalid) {
                throw new InvalidArgumentException(sprintf('Invalid value "%s" for attribute "decoration_on_invalid" on service "%s". Did you mean null (without quotes) in "%s"?', $decorationOnInvalid, $id, $file));
            } else {
                throw new InvalidArgumentException(sprintf('Invalid value "%s" for attribute "decoration_on_invalid" on service "%s". Did you mean "exception", "ignore" or null in "%s"?', $decorationOnInvalid, $id, $file));
            }

            $renameId = isset($service['decoration_inner_name']) ? $service['decoration_inner_name'] : null;
            $priority = isset($service['decoration_priority']) ? $service['decoration_priority'] : 0;

            $definition->setDecoratedService($decorates, $renameId, $priority, $invalidBehavior);
        }

        if (isset($service['autowire'])) {
            $definition->setAutowired($service['autowire']);
        }

        if (isset($defaults['bind']) || isset($service['bind'])) {
            // deep clone, to avoid multiple process of the same instance in the passes
            $bindings = isset($defaults['bind']) ? unserialize(serialize($defaults['bind'])) : [];

            if (isset($service['bind'])) {
                if (!\is_array($service['bind'])) {
                    throw new InvalidArgumentException(sprintf('Parameter "bind" must be an array for service "%s" in "%s". Check your YAML syntax.', $id, $file));
                }

                $bindings = array_merge($bindings, $this->resolveServices($service['bind'], $file));
                $bindingType = $this->isLoadingInstanceof ? BoundArgument::INSTANCEOF_BINDING : BoundArgument::SERVICE_BINDING;
                foreach ($bindings as $argument => $value) {
                    if (!$value instanceof BoundArgument) {
                        $bindings[$argument] = new BoundArgument($value, true, $bindingType, $file);
                    }
                }
            }

            $definition->setBindings($bindings);
        }

        if (isset($service['autoconfigure'])) {
            $definition->setAutoconfigured($service['autoconfigure']);
        }

        if (\array_key_exists('namespace', $service) && !\array_key_exists('resource', $service)) {
            throw new InvalidArgumentException(sprintf('A "resource" attribute must be set when the "namespace" attribute is set for service "%s" in "%s". Check your YAML syntax.', $id, $file));
        }

        if ($return) {
            if (\array_key_exists('resource', $service)) {
                throw new InvalidArgumentException(sprintf('Invalid "resource" attribute found for service "%s" in "%s". Check your YAML syntax.', $id, $file));
            }

            return $definition;
        }

        if (\array_key_exists('resource', $service)) {
            if (!\is_string($service['resource'])) {
                throw new InvalidArgumentException(sprintf('A "resource" attribute must be of type string for service "%s" in "%s". Check your YAML syntax.', $id, $file));
            }
            $exclude = isset($service['exclude']) ? $service['exclude'] : null;
            $namespace = isset($service['namespace']) ? $service['namespace'] : $id;
            $this->registerClasses($definition, $namespace, $service['resource'], $exclude);
        } else {
            $this->setDefinition($id, $definition);
        }
    }

    /**
     * Parses a callable.
     *
     * @param string|array $callable A callable reference
     *
     * @throws InvalidArgumentException When errors occur
     *
     * @return string|array|Reference A parsed callable
     */
    private function parseCallable($callable, string $parameter, string $id, string $file)
    {
        if (\is_string($callable)) {
            if ('' !== $callable && '@' === $callable[0]) {
                if (false === strpos($callable, ':')) {
                    return [$this->resolveServices($callable, $file), '__invoke'];
                }

                throw new InvalidArgumentException(sprintf('The value of the "%s" option for the "%s" service must be the id of the service without the "@" prefix (replace "%s" with "%s" in "%s").', $parameter, $id, $callable, substr($callable, 1), $file));
            }

            return $callable;
        }

        if (\is_array($callable)) {
            if (isset($callable[0]) && isset($callable[1])) {
                return [$this->resolveServices($callable[0], $file), $callable[1]];
            }

            if ('factory' === $parameter && isset($callable[1]) && null === $callable[0]) {
                return $callable;
            }

            throw new InvalidArgumentException(sprintf('Parameter "%s" must contain an array with two elements for service "%s" in "%s". Check your YAML syntax.', $parameter, $id, $file));
        }

        throw new InvalidArgumentException(sprintf('Parameter "%s" must be a string or an array for service "%s" in "%s". Check your YAML syntax.', $parameter, $id, $file));
    }

    /**
     * Loads a YAML file.
     *
     * @param string $file
     *
     * @return array The file content
     *
     * @throws InvalidArgumentException when the given file is not a local file or when it does not exist
     */
    protected function loadFile($file)
    {
        if (!class_exists('Symfony\Component\Yaml\Parser')) {
            throw new RuntimeException('Unable to load YAML config files as the Symfony Yaml Component is not installed.');
        }

        if (!stream_is_local($file)) {
            throw new InvalidArgumentException(sprintf('This is not a local file "%s".', $file));
        }

        if (!is_file($file)) {
            throw new InvalidArgumentException(sprintf('The file "%s" does not exist.', $file));
        }

        if (null === $this->yamlParser) {
            $this->yamlParser = new YamlParser();
        }

        try {
            $configuration = $this->yamlParser->parseFile($file, Yaml::PARSE_CONSTANT | Yaml::PARSE_CUSTOM_TAGS);
        } catch (ParseException $e) {
            throw new InvalidArgumentException(sprintf('The file "%s" does not contain valid YAML: ', $file).$e->getMessage(), 0, $e);
        }

        return $this->validate($configuration, $file);
    }

    /**
     * Validates a YAML file.
     *
     * @throws InvalidArgumentException When service file is not valid
     */
    private function validate($content, string $file): ?array
    {
        if (null === $content) {
            return $content;
        }

        if (!\is_array($content)) {
            throw new InvalidArgumentException(sprintf('The service file "%s" is not valid. It should contain an array. Check your YAML syntax.', $file));
        }

        foreach ($content as $namespace => $data) {
            if (\in_array($namespace, ['imports', 'parameters', 'services'])) {
                continue;
            }

            if (!$this->container->hasExtension($namespace)) {
                $extensionNamespaces = array_filter(array_map(function (ExtensionInterface $ext) { return $ext->getAlias(); }, $this->container->getExtensions()));
                throw new InvalidArgumentException(sprintf('There is no extension able to load the configuration for "%s" (in "%s"). Looked for namespace "%s", found "%s".', $namespace, $file, $namespace, $extensionNamespaces ? sprintf('"%s"', implode('", "', $extensionNamespaces)) : 'none'));
            }
        }

        return $content;
    }

    /**
     * Resolves services.
     *
     * @return array|string|Reference|ArgumentInterface
     */
    private function resolveServices($value, string $file, bool $isParameter = false)
    {
        if ($value instanceof TaggedValue) {
            $argument = $value->getValue();
            if ('iterator' === $value->getTag()) {
                if (!\is_array($argument)) {
                    throw new InvalidArgumentException(sprintf('"!iterator" tag only accepts sequences in "%s".', $file));
                }
                $argument = $this->resolveServices($argument, $file, $isParameter);
                try {
                    return new IteratorArgument($argument);
                } catch (InvalidArgumentException $e) {
                    throw new InvalidArgumentException(sprintf('"!iterator" tag only accepts arrays of "@service" references in "%s".', $file));
                }
            }
            if ('service_locator' === $value->getTag()) {
                if (!\is_array($argument)) {
                    throw new InvalidArgumentException(sprintf('"!service_locator" tag only accepts maps in "%s".', $file));
                }

                $argument = $this->resolveServices($argument, $file, $isParameter);

                try {
                    return new ServiceLocatorArgument($argument);
                } catch (InvalidArgumentException $e) {
                    throw new InvalidArgumentException(sprintf('"!service_locator" tag only accepts maps of "@service" references in "%s".', $file));
                }
            }
            if (\in_array($value->getTag(), ['tagged', 'tagged_iterator', 'tagged_locator'], true)) {
                $forLocator = 'tagged_locator' === $value->getTag();

                if (\is_array($argument) && isset($argument['tag']) && $argument['tag']) {
                    if ($diff = array_diff(array_keys($argument), ['tag', 'index_by', 'default_index_method', 'default_priority_method'])) {
                        throw new InvalidArgumentException(sprintf('"!%s" tag contains unsupported key "%s"; supported ones are "tag", "index_by", "default_index_method", and "default_priority_method".', $value->getTag(), implode('", "', $diff)));
                    }

                    $argument = new TaggedIteratorArgument($argument['tag'], $argument['index_by'] ?? null, $argument['default_index_method'] ?? null, $forLocator, $argument['default_priority_method'] ?? null);
                } elseif (\is_string($argument) && $argument) {
                    $argument = new TaggedIteratorArgument($argument, null, null, $forLocator);
                } else {
                    throw new InvalidArgumentException(sprintf('"!%s" tags only accept a non empty string or an array with a key "tag" in "%s".', $value->getTag(), $file));
                }

                if ($forLocator) {
                    $argument = new ServiceLocatorArgument($argument);
                }

                return $argument;
            }
            if ('service' === $value->getTag()) {
                if ($isParameter) {
                    throw new InvalidArgumentException(sprintf('Using an anonymous service in a parameter is not allowed in "%s".', $file));
                }

                $isLoadingInstanceof = $this->isLoadingInstanceof;
                $this->isLoadingInstanceof = false;
                $instanceof = $this->instanceof;
                $this->instanceof = [];

                $id = sprintf('.%d_%s', ++$this->anonymousServicesCount, preg_replace('/^.*\\\\/', '', isset($argument['class']) ? $argument['class'] : '').$this->anonymousServicesSuffix);
                $this->parseDefinition($id, $argument, $file, []);

                if (!$this->container->hasDefinition($id)) {
                    throw new InvalidArgumentException(sprintf('Creating an alias using the tag "!service" is not allowed in "%s".', $file));
                }

                $this->container->getDefinition($id)->setPublic(false);

                $this->isLoadingInstanceof = $isLoadingInstanceof;
                $this->instanceof = $instanceof;

                return new Reference($id);
            }
            if ('abstract' === $value->getTag()) {
                return new AbstractArgument($value->getValue());
            }

            throw new InvalidArgumentException(sprintf('Unsupported tag "!%s".', $value->getTag()));
        }

        if (\is_array($value)) {
            foreach ($value as $k => $v) {
                $value[$k] = $this->resolveServices($v, $file, $isParameter);
            }
        } elseif (\is_string($value) && 0 === strpos($value, '@=')) {
            if (!class_exists(Expression::class)) {
                throw new \LogicException(sprintf('The "@=" expression syntax cannot be used without the ExpressionLanguage component. Try running "composer require symfony/expression-language".'));
            }

            return new Expression(substr($value, 2));
        } elseif (\is_string($value) && 0 === strpos($value, '@')) {
            if (0 === strpos($value, '@@')) {
                $value = substr($value, 1);
                $invalidBehavior = null;
            } elseif (0 === strpos($value, '@!')) {
                $value = substr($value, 2);
                $invalidBehavior = ContainerInterface::IGNORE_ON_UNINITIALIZED_REFERENCE;
            } elseif (0 === strpos($value, '@?')) {
                $value = substr($value, 2);
                $invalidBehavior = ContainerInterface::IGNORE_ON_INVALID_REFERENCE;
            } else {
                $value = substr($value, 1);
                $invalidBehavior = ContainerInterface::EXCEPTION_ON_INVALID_REFERENCE;
            }

            if (null !== $invalidBehavior) {
                $value = new Reference($value, $invalidBehavior);
            }
        }

        return $value;
    }

    /**
     * Loads from Extensions.
     */
    private function loadFromExtensions(array $content)
    {
        foreach ($content as $namespace => $values) {
            if (\in_array($namespace, ['imports', 'parameters', 'services'])) {
                continue;
            }

            if (!\is_array($values) && null !== $values) {
                $values = [];
            }

            $this->container->loadFromExtension($namespace, $values);
        }
    }

    /**
     * Checks the keywords used to define a service.
     */
    private function checkDefinition(string $id, array $definition, string $file)
    {
        if ($this->isLoadingInstanceof) {
            $keywords = self::$instanceofKeywords;
        } elseif (isset($definition['resource']) || isset($definition['namespace'])) {
            $keywords = self::$prototypeKeywords;
        } else {
            $keywords = self::$serviceKeywords;
        }

        foreach ($definition as $key => $value) {
            if (!isset($keywords[$key])) {
                throw new InvalidArgumentException(sprintf('The configuration key "%s" is unsupported for definition "%s" in "%s". Allowed configuration keys are "%s".', $key, $id, $file, implode('", "', $keywords)));
            }
        }
    }
}
PKϤ$Z��+���-dependency-injection/Loader/PhpFileLoader.phpnu�[���<?php

/*
 * This file is part of the Symfony package.
 *
 * (c) Fabien Potencier <fabien@symfony.com>
 *
 * For the full copyright and license information, please view the LICENSE
 * file that was distributed with this source code.
 */

namespace Symfony\Component\DependencyInjection\Loader;

use Symfony\Component\DependencyInjection\Loader\Configurator\ContainerConfigurator;

/**
 * PhpFileLoader loads service definitions from a PHP file.
 *
 * The PHP file is required and the $container variable can be
 * used within the file to change the container.
 *
 * @author Fabien Potencier <fabien@symfony.com>
 */
class PhpFileLoader extends FileLoader
{
    protected $autoRegisterAliasesForSinglyImplementedInterfaces = false;

    /**
     * {@inheritdoc}
     */
    public function load($resource, $type = null)
    {
        // the container and loader variables are exposed to the included file below
        $container = $this->container;
        $loader = $this;

        $path = $this->locator->locate($resource);
        $this->setCurrentDir(\dirname($path));
        $this->container->fileExists($path);

        // the closure forbids access to the private scope in the included file
        $load = \Closure::bind(function ($path) use ($container, $loader, $resource, $type) {
            return include $path;
        }, $this, ProtectedPhpFileLoader::class);

        try {
            $callback = $load($path);

            if (\is_object($callback) && \is_callable($callback)) {
                $callback(new ContainerConfigurator($this->container, $this, $this->instanceof, $path, $resource), $this->container, $this);
            }
        } finally {
            $this->instanceof = [];
            $this->registerAliasesForSinglyImplementedInterfaces();
        }
    }

    /**
     * {@inheritdoc}
     */
    public function supports($resource, string $type = null)
    {
        if (!\is_string($resource)) {
            return false;
        }

        if (null === $type && 'php' === pathinfo($resource, \PATHINFO_EXTENSION)) {
            return true;
        }

        return 'php' === $type;
    }
}

/**
 * @internal
 */
final class ProtectedPhpFileLoader extends PhpFileLoader
{
}
PKϤ$Z���uu-dependency-injection/Loader/IniFileLoader.phpnu�[���<?php

/*
 * This file is part of the Symfony package.
 *
 * (c) Fabien Potencier <fabien@symfony.com>
 *
 * For the full copyright and license information, please view the LICENSE
 * file that was distributed with this source code.
 */

namespace Symfony\Component\DependencyInjection\Loader;

use Symfony\Component\Config\Util\XmlUtils;
use Symfony\Component\DependencyInjection\Exception\InvalidArgumentException;

/**
 * IniFileLoader loads parameters from INI files.
 *
 * @author Fabien Potencier <fabien@symfony.com>
 */
class IniFileLoader extends FileLoader
{
    /**
     * {@inheritdoc}
     */
    public function load($resource, string $type = null)
    {
        $path = $this->locator->locate($resource);

        $this->container->fileExists($path);

        // first pass to catch parsing errors
        $result = parse_ini_file($path, true);
        if (false === $result || [] === $result) {
            throw new InvalidArgumentException(sprintf('The "%s" file is not valid.', $resource));
        }

        // real raw parsing
        $result = parse_ini_file($path, true, \INI_SCANNER_RAW);

        if (isset($result['parameters']) && \is_array($result['parameters'])) {
            foreach ($result['parameters'] as $key => $value) {
                $this->container->setParameter($key, $this->phpize($value));
            }
        }
    }

    /**
     * {@inheritdoc}
     */
    public function supports($resource, string $type = null)
    {
        if (!\is_string($resource)) {
            return false;
        }

        if (null === $type && 'ini' === pathinfo($resource, \PATHINFO_EXTENSION)) {
            return true;
        }

        return 'ini' === $type;
    }

    /**
     * Note that the following features are not supported:
     *  * strings with escaped quotes are not supported "foo\"bar";
     *  * string concatenation ("foo" "bar").
     *
     * @return mixed
     */
    private function phpize(string $value)
    {
        // trim on the right as comments removal keep whitespaces
        if ($value !== $v = rtrim($value)) {
            $value = '""' === substr_replace($v, '', 1, -1) ? substr($v, 1, -1) : $v;
        }
        $lowercaseValue = strtolower($value);

        switch (true) {
            case \defined($value):
                return \constant($value);
            case 'yes' === $lowercaseValue || 'on' === $lowercaseValue:
                return true;
            case 'no' === $lowercaseValue || 'off' === $lowercaseValue || 'none' === $lowercaseValue:
                return false;
            case isset($value[1]) && (
                ("'" === $value[0] && "'" === $value[\strlen($value) - 1]) ||
                ('"' === $value[0] && '"' === $value[\strlen($value) - 1])
            ):
                // quoted string
                return substr($value, 1, -1);
            default:
                return XmlUtils::phpize($value);
        }
    }
}
PKϤ$Z(0�x�x-dependency-injection/Loader/XmlFileLoader.phpnu�[���<?php

/*
 * This file is part of the Symfony package.
 *
 * (c) Fabien Potencier <fabien@symfony.com>
 *
 * For the full copyright and license information, please view the LICENSE
 * file that was distributed with this source code.
 */

namespace Symfony\Component\DependencyInjection\Loader;

use Symfony\Component\Config\Util\XmlUtils;
use Symfony\Component\DependencyInjection\Alias;
use Symfony\Component\DependencyInjection\Argument\AbstractArgument;
use Symfony\Component\DependencyInjection\Argument\BoundArgument;
use Symfony\Component\DependencyInjection\Argument\IteratorArgument;
use Symfony\Component\DependencyInjection\Argument\ServiceLocatorArgument;
use Symfony\Component\DependencyInjection\Argument\TaggedIteratorArgument;
use Symfony\Component\DependencyInjection\ChildDefinition;
use Symfony\Component\DependencyInjection\ContainerBuilder;
use Symfony\Component\DependencyInjection\ContainerInterface;
use Symfony\Component\DependencyInjection\Definition;
use Symfony\Component\DependencyInjection\Exception\InvalidArgumentException;
use Symfony\Component\DependencyInjection\Exception\RuntimeException;
use Symfony\Component\DependencyInjection\Extension\ExtensionInterface;
use Symfony\Component\DependencyInjection\Reference;
use Symfony\Component\ExpressionLanguage\Expression;

/**
 * XmlFileLoader loads XML files service definitions.
 *
 * @author Fabien Potencier <fabien@symfony.com>
 */
class XmlFileLoader extends FileLoader
{
    const NS = 'http://symfony.com/schema/dic/services';

    protected $autoRegisterAliasesForSinglyImplementedInterfaces = false;

    /**
     * {@inheritdoc}
     */
    public function load($resource, string $type = null)
    {
        $path = $this->locator->locate($resource);

        $xml = $this->parseFileToDOM($path);

        $this->container->fileExists($path);

        $defaults = $this->getServiceDefaults($xml, $path);

        // anonymous services
        $this->processAnonymousServices($xml, $path);

        // imports
        $this->parseImports($xml, $path);

        // parameters
        $this->parseParameters($xml, $path);

        // extensions
        $this->loadFromExtensions($xml);

        // services
        try {
            $this->parseDefinitions($xml, $path, $defaults);
        } finally {
            $this->instanceof = [];
            $this->registerAliasesForSinglyImplementedInterfaces();
        }
    }

    /**
     * {@inheritdoc}
     */
    public function supports($resource, string $type = null)
    {
        if (!\is_string($resource)) {
            return false;
        }

        if (null === $type && 'xml' === pathinfo($resource, \PATHINFO_EXTENSION)) {
            return true;
        }

        return 'xml' === $type;
    }

    private function parseParameters(\DOMDocument $xml, string $file)
    {
        if ($parameters = $this->getChildren($xml->documentElement, 'parameters')) {
            $this->container->getParameterBag()->add($this->getArgumentsAsPhp($parameters[0], 'parameter', $file));
        }
    }

    private function parseImports(\DOMDocument $xml, string $file)
    {
        $xpath = new \DOMXPath($xml);
        $xpath->registerNamespace('container', self::NS);

        if (false === $imports = $xpath->query('//container:imports/container:import')) {
            return;
        }

        $defaultDirectory = \dirname($file);
        foreach ($imports as $import) {
            $this->setCurrentDir($defaultDirectory);
            $this->import($import->getAttribute('resource'), XmlUtils::phpize($import->getAttribute('type')) ?: null, XmlUtils::phpize($import->getAttribute('ignore-errors')) ?: false, $file);
        }
    }

    private function parseDefinitions(\DOMDocument $xml, string $file, Definition $defaults)
    {
        $xpath = new \DOMXPath($xml);
        $xpath->registerNamespace('container', self::NS);

        if (false === $services = $xpath->query('//container:services/container:service|//container:services/container:prototype|//container:services/container:stack')) {
            return;
        }
        $this->setCurrentDir(\dirname($file));

        $this->instanceof = [];
        $this->isLoadingInstanceof = true;
        $instanceof = $xpath->query('//container:services/container:instanceof');
        foreach ($instanceof as $service) {
            $this->setDefinition((string) $service->getAttribute('id'), $this->parseDefinition($service, $file, new Definition()));
        }

        $this->isLoadingInstanceof = false;
        foreach ($services as $service) {
            if ('stack' === $service->tagName) {
                $service->setAttribute('parent', '-');
                $definition = $this->parseDefinition($service, $file, $defaults)
                    ->setTags(array_merge_recursive(['container.stack' => [[]]], $defaults->getTags()))
                ;
                $this->setDefinition($id = (string) $service->getAttribute('id'), $definition);
                $stack = [];

                foreach ($this->getChildren($service, 'service') as $k => $frame) {
                    $k = $frame->getAttribute('id') ?: $k;
                    $frame->setAttribute('id', $id.'" at index "'.$k);

                    if ($alias = $frame->getAttribute('alias')) {
                        $this->validateAlias($frame, $file);
                        $stack[$k] = new Reference($alias);
                    } else {
                        $stack[$k] = $this->parseDefinition($frame, $file, $defaults)
                            ->setInstanceofConditionals($this->instanceof);
                    }
                }

                $definition->setArguments($stack);
            } elseif (null !== $definition = $this->parseDefinition($service, $file, $defaults)) {
                if ('prototype' === $service->tagName) {
                    $excludes = array_column($this->getChildren($service, 'exclude'), 'nodeValue');
                    if ($service->hasAttribute('exclude')) {
                        if (\count($excludes) > 0) {
                            throw new InvalidArgumentException('You cannot use both the attribute "exclude" and <exclude> tags at the same time.');
                        }
                        $excludes = [$service->getAttribute('exclude')];
                    }
                    $this->registerClasses($definition, (string) $service->getAttribute('namespace'), (string) $service->getAttribute('resource'), $excludes);
                } else {
                    $this->setDefinition((string) $service->getAttribute('id'), $definition);
                }
            }
        }
    }

    private function getServiceDefaults(\DOMDocument $xml, string $file): Definition
    {
        $xpath = new \DOMXPath($xml);
        $xpath->registerNamespace('container', self::NS);

        if (null === $defaultsNode = $xpath->query('//container:services/container:defaults')->item(0)) {
            return new Definition();
        }

        $defaultsNode->setAttribute('id', '<defaults>');

        return $this->parseDefinition($defaultsNode, $file, new Definition());
    }

    /**
     * Parses an individual Definition.
     */
    private function parseDefinition(\DOMElement $service, string $file, Definition $defaults): ?Definition
    {
        if ($alias = $service->getAttribute('alias')) {
            $this->validateAlias($service, $file);

            $this->container->setAlias((string) $service->getAttribute('id'), $alias = new Alias($alias));
            if ($publicAttr = $service->getAttribute('public')) {
                $alias->setPublic(XmlUtils::phpize($publicAttr));
            } elseif ($defaults->getChanges()['public'] ?? false) {
                $alias->setPublic($defaults->isPublic());
            }

            if ($deprecated = $this->getChildren($service, 'deprecated')) {
                $message = $deprecated[0]->nodeValue ?: '';
                $package = $deprecated[0]->getAttribute('package') ?: '';
                $version = $deprecated[0]->getAttribute('version') ?: '';

                if (!$deprecated[0]->hasAttribute('package')) {
                    trigger_deprecation('symfony/dependency-injection', '5.1', 'Not setting the attribute "package" of the node "deprecated" in "%s" is deprecated.', $file);
                }

                if (!$deprecated[0]->hasAttribute('version')) {
                    trigger_deprecation('symfony/dependency-injection', '5.1', 'Not setting the attribute "version" of the node "deprecated" in "%s" is deprecated.', $file);
                }

                $alias->setDeprecated($package, $version, $message);
            }

            return null;
        }

        if ($this->isLoadingInstanceof) {
            $definition = new ChildDefinition('');
        } elseif ($parent = $service->getAttribute('parent')) {
            $definition = new ChildDefinition($parent);
        } else {
            $definition = new Definition();
        }

        if ($defaults->getChanges()['public'] ?? false) {
            $definition->setPublic($defaults->isPublic());
        }
        $definition->setAutowired($defaults->isAutowired());
        $definition->setAutoconfigured($defaults->isAutoconfigured());
        $definition->setChanges([]);

        foreach (['class', 'public', 'shared', 'synthetic', 'abstract'] as $key) {
            if ($value = $service->getAttribute($key)) {
                $method = 'set'.$key;
                $definition->$method($value = XmlUtils::phpize($value));
            }
        }

        if ($value = $service->getAttribute('lazy')) {
            $definition->setLazy((bool) $value = XmlUtils::phpize($value));
            if (\is_string($value)) {
                $definition->addTag('proxy', ['interface' => $value]);
            }
        }

        if ($value = $service->getAttribute('autowire')) {
            $definition->setAutowired(XmlUtils::phpize($value));
        }

        if ($value = $service->getAttribute('autoconfigure')) {
            $definition->setAutoconfigured(XmlUtils::phpize($value));
        }

        if ($files = $this->getChildren($service, 'file')) {
            $definition->setFile($files[0]->nodeValue);
        }

        if ($deprecated = $this->getChildren($service, 'deprecated')) {
            $message = $deprecated[0]->nodeValue ?: '';
            $package = $deprecated[0]->getAttribute('package') ?: '';
            $version = $deprecated[0]->getAttribute('version') ?: '';

            if ('' === $package) {
                trigger_deprecation('symfony/dependency-injection', '5.1', 'Not setting the attribute "package" of the node "deprecated" in "%s" is deprecated.', $file);
            }

            if ('' === $version) {
                trigger_deprecation('symfony/dependency-injection', '5.1', 'Not setting the attribute "version" of the node "deprecated" in "%s" is deprecated.', $file);
            }

            $definition->setDeprecated($package, $version, $message);
        }

        $definition->setArguments($this->getArgumentsAsPhp($service, 'argument', $file, $definition instanceof ChildDefinition));
        $definition->setProperties($this->getArgumentsAsPhp($service, 'property', $file));

        if ($factories = $this->getChildren($service, 'factory')) {
            $factory = $factories[0];
            if ($function = $factory->getAttribute('function')) {
                $definition->setFactory($function);
            } else {
                if ($childService = $factory->getAttribute('service')) {
                    $class = new Reference($childService, ContainerInterface::EXCEPTION_ON_INVALID_REFERENCE);
                } else {
                    $class = $factory->hasAttribute('class') ? $factory->getAttribute('class') : null;
                }

                $definition->setFactory([$class, $factory->getAttribute('method') ?: '__invoke']);
            }
        }

        if ($configurators = $this->getChildren($service, 'configurator')) {
            $configurator = $configurators[0];
            if ($function = $configurator->getAttribute('function')) {
                $definition->setConfigurator($function);
            } else {
                if ($childService = $configurator->getAttribute('service')) {
                    $class = new Reference($childService, ContainerInterface::EXCEPTION_ON_INVALID_REFERENCE);
                } else {
                    $class = $configurator->getAttribute('class');
                }

                $definition->setConfigurator([$class, $configurator->getAttribute('method') ?: '__invoke']);
            }
        }

        foreach ($this->getChildren($service, 'call') as $call) {
            $definition->addMethodCall($call->getAttribute('method'), $this->getArgumentsAsPhp($call, 'argument', $file), XmlUtils::phpize($call->getAttribute('returns-clone')));
        }

        $tags = $this->getChildren($service, 'tag');

        foreach ($tags as $tag) {
            $parameters = [];
            $tagName = $tag->nodeValue;
            foreach ($tag->attributes as $name => $node) {
                if ('name' === $name && '' === $tagName) {
                    continue;
                }

                if (false !== strpos($name, '-') && false === strpos($name, '_') && !\array_key_exists($normalizedName = str_replace('-', '_', $name), $parameters)) {
                    $parameters[$normalizedName] = XmlUtils::phpize($node->nodeValue);
                }
                // keep not normalized key
                $parameters[$name] = XmlUtils::phpize($node->nodeValue);
            }

            if ('' === $tagName && '' === $tagName = $tag->getAttribute('name')) {
                throw new InvalidArgumentException(sprintf('The tag name for service "%s" in "%s" must be a non-empty string.', (string) $service->getAttribute('id'), $file));
            }

            $definition->addTag($tagName, $parameters);
        }

        $definition->setTags(array_merge_recursive($definition->getTags(), $defaults->getTags()));

        $bindings = $this->getArgumentsAsPhp($service, 'bind', $file);
        $bindingType = $this->isLoadingInstanceof ? BoundArgument::INSTANCEOF_BINDING : BoundArgument::SERVICE_BINDING;
        foreach ($bindings as $argument => $value) {
            $bindings[$argument] = new BoundArgument($value, true, $bindingType, $file);
        }

        // deep clone, to avoid multiple process of the same instance in the passes
        $bindings = array_merge(unserialize(serialize($defaults->getBindings())), $bindings);

        if ($bindings) {
            $definition->setBindings($bindings);
        }

        if ($decorates = $service->getAttribute('decorates')) {
            $decorationOnInvalid = $service->getAttribute('decoration-on-invalid') ?: 'exception';
            if ('exception' === $decorationOnInvalid) {
                $invalidBehavior = ContainerInterface::EXCEPTION_ON_INVALID_REFERENCE;
            } elseif ('ignore' === $decorationOnInvalid) {
                $invalidBehavior = ContainerInterface::IGNORE_ON_INVALID_REFERENCE;
            } elseif ('null' === $decorationOnInvalid) {
                $invalidBehavior = ContainerInterface::NULL_ON_INVALID_REFERENCE;
            } else {
                throw new InvalidArgumentException(sprintf('Invalid value "%s" for attribute "decoration-on-invalid" on service "%s". Did you mean "exception", "ignore" or "null" in "%s"?', $decorationOnInvalid, (string) $service->getAttribute('id'), $file));
            }

            $renameId = $service->hasAttribute('decoration-inner-name') ? $service->getAttribute('decoration-inner-name') : null;
            $priority = $service->hasAttribute('decoration-priority') ? $service->getAttribute('decoration-priority') : 0;

            $definition->setDecoratedService($decorates, $renameId, $priority, $invalidBehavior);
        }

        return $definition;
    }

    /**
     * Parses a XML file to a \DOMDocument.
     *
     * @throws InvalidArgumentException When loading of XML file returns error
     */
    private function parseFileToDOM(string $file): \DOMDocument
    {
        try {
            $dom = XmlUtils::loadFile($file, [$this, 'validateSchema']);
        } catch (\InvalidArgumentException $e) {
            throw new InvalidArgumentException(sprintf('Unable to parse file "%s": ', $file).$e->getMessage(), $e->getCode(), $e);
        }

        $this->validateExtensions($dom, $file);

        return $dom;
    }

    /**
     * Processes anonymous services.
     */
    private function processAnonymousServices(\DOMDocument $xml, string $file)
    {
        $definitions = [];
        $count = 0;
        $suffix = '~'.ContainerBuilder::hash($file);

        $xpath = new \DOMXPath($xml);
        $xpath->registerNamespace('container', self::NS);

        // anonymous services as arguments/properties
        if (false !== $nodes = $xpath->query('//container:argument[@type="service"][not(@id)]|//container:property[@type="service"][not(@id)]|//container:bind[not(@id)]|//container:factory[not(@service)]|//container:configurator[not(@service)]')) {
            foreach ($nodes as $node) {
                if ($services = $this->getChildren($node, 'service')) {
                    // give it a unique name
                    $id = sprintf('.%d_%s', ++$count, preg_replace('/^.*\\\\/', '', $services[0]->getAttribute('class')).$suffix);
                    $node->setAttribute('id', $id);
                    $node->setAttribute('service', $id);

                    $definitions[$id] = [$services[0], $file];
                    $services[0]->setAttribute('id', $id);

                    // anonymous services are always private
                    // we could not use the constant false here, because of XML parsing
                    $services[0]->setAttribute('public', 'false');
                }
            }
        }

        // anonymous services "in the wild"
        if (false !== $nodes = $xpath->query('//container:services/container:service[not(@id)]')) {
            foreach ($nodes as $node) {
                throw new InvalidArgumentException(sprintf('Top-level services must have "id" attribute, none found in "%s" at line %d.', $file, $node->getLineNo()));
            }
        }

        // resolve definitions
        uksort($definitions, 'strnatcmp');
        foreach (array_reverse($definitions) as $id => list($domElement, $file)) {
            if (null !== $definition = $this->parseDefinition($domElement, $file, new Definition())) {
                $this->setDefinition($id, $definition);
            }
        }
    }

    private function getArgumentsAsPhp(\DOMElement $node, string $name, string $file, bool $isChildDefinition = false): array
    {
        $arguments = [];
        foreach ($this->getChildren($node, $name) as $arg) {
            if ($arg->hasAttribute('name')) {
                $arg->setAttribute('key', $arg->getAttribute('name'));
            }

            // this is used by ChildDefinition to overwrite a specific
            // argument of the parent definition
            if ($arg->hasAttribute('index')) {
                $key = ($isChildDefinition ? 'index_' : '').$arg->getAttribute('index');
            } elseif (!$arg->hasAttribute('key')) {
                // Append an empty argument, then fetch its key to overwrite it later
                $arguments[] = null;
                $keys = array_keys($arguments);
                $key = array_pop($keys);
            } else {
                $key = $arg->getAttribute('key');
            }

            $onInvalid = $arg->getAttribute('on-invalid');
            $invalidBehavior = ContainerInterface::EXCEPTION_ON_INVALID_REFERENCE;
            if ('ignore' == $onInvalid) {
                $invalidBehavior = ContainerInterface::IGNORE_ON_INVALID_REFERENCE;
            } elseif ('ignore_uninitialized' == $onInvalid) {
                $invalidBehavior = ContainerInterface::IGNORE_ON_UNINITIALIZED_REFERENCE;
            } elseif ('null' == $onInvalid) {
                $invalidBehavior = ContainerInterface::NULL_ON_INVALID_REFERENCE;
            }

            switch ($arg->getAttribute('type')) {
                case 'service':
                    if ('' === $arg->getAttribute('id')) {
                        throw new InvalidArgumentException(sprintf('Tag "<%s>" with type="service" has no or empty "id" attribute in "%s".', $name, $file));
                    }

                    $arguments[$key] = new Reference($arg->getAttribute('id'), $invalidBehavior);
                    break;
                case 'expression':
                    if (!class_exists(Expression::class)) {
                        throw new \LogicException(sprintf('The type="expression" attribute cannot be used without the ExpressionLanguage component. Try running "composer require symfony/expression-language".'));
                    }

                    $arguments[$key] = new Expression($arg->nodeValue);
                    break;
                case 'collection':
                    $arguments[$key] = $this->getArgumentsAsPhp($arg, $name, $file);
                    break;
                case 'iterator':
                    $arg = $this->getArgumentsAsPhp($arg, $name, $file);
                    try {
                        $arguments[$key] = new IteratorArgument($arg);
                    } catch (InvalidArgumentException $e) {
                        throw new InvalidArgumentException(sprintf('Tag "<%s>" with type="iterator" only accepts collections of type="service" references in "%s".', $name, $file));
                    }
                    break;
                case 'service_locator':
                    $arg = $this->getArgumentsAsPhp($arg, $name, $file);
                    try {
                        $arguments[$key] = new ServiceLocatorArgument($arg);
                    } catch (InvalidArgumentException $e) {
                        throw new InvalidArgumentException(sprintf('Tag "<%s>" with type="service_locator" only accepts maps of type="service" references in "%s".', $name, $file));
                    }
                    break;
                case 'tagged':
                case 'tagged_iterator':
                case 'tagged_locator':
                    $type = $arg->getAttribute('type');
                    $forLocator = 'tagged_locator' === $type;

                    if (!$arg->getAttribute('tag')) {
                        throw new InvalidArgumentException(sprintf('Tag "<%s>" with type="%s" has no or empty "tag" attribute in "%s".', $name, $type, $file));
                    }

                    $arguments[$key] = new TaggedIteratorArgument($arg->getAttribute('tag'), $arg->getAttribute('index-by') ?: null, $arg->getAttribute('default-index-method') ?: null, $forLocator, $arg->getAttribute('default-priority-method') ?: null);

                    if ($forLocator) {
                        $arguments[$key] = new ServiceLocatorArgument($arguments[$key]);
                    }
                    break;
                case 'binary':
                    if (false === $value = base64_decode($arg->nodeValue)) {
                        throw new InvalidArgumentException(sprintf('Tag "<%s>" with type="binary" is not a valid base64 encoded string.', $name));
                    }
                    $arguments[$key] = $value;
                    break;
                case 'abstract':
                    $arguments[$key] = new AbstractArgument($arg->nodeValue);
                    break;
                case 'string':
                    $arguments[$key] = $arg->nodeValue;
                    break;
                case 'constant':
                    $arguments[$key] = \constant(trim($arg->nodeValue));
                    break;
                default:
                    $arguments[$key] = XmlUtils::phpize($arg->nodeValue);
            }
        }

        return $arguments;
    }

    /**
     * Get child elements by name.
     *
     * @return \DOMElement[]
     */
    private function getChildren(\DOMNode $node, string $name): array
    {
        $children = [];
        foreach ($node->childNodes as $child) {
            if ($child instanceof \DOMElement && $child->localName === $name && self::NS === $child->namespaceURI) {
                $children[] = $child;
            }
        }

        return $children;
    }

    /**
     * Validates a documents XML schema.
     *
     * @return bool
     *
     * @throws RuntimeException When extension references a non-existent XSD file
     */
    public function validateSchema(\DOMDocument $dom)
    {
        $schemaLocations = ['http://symfony.com/schema/dic/services' => str_replace('\\', '/', __DIR__.'/schema/dic/services/services-1.0.xsd')];

        if ($element = $dom->documentElement->getAttributeNS('http://www.w3.org/2001/XMLSchema-instance', 'schemaLocation')) {
            $items = preg_split('/\s+/', $element);
            for ($i = 0, $nb = \count($items); $i < $nb; $i += 2) {
                if (!$this->container->hasExtension($items[$i])) {
                    continue;
                }

                if (($extension = $this->container->getExtension($items[$i])) && false !== $extension->getXsdValidationBasePath()) {
                    $ns = $extension->getNamespace();
                    $path = str_replace([$ns, str_replace('http://', 'https://', $ns)], str_replace('\\', '/', $extension->getXsdValidationBasePath()).'/', $items[$i + 1]);

                    if (!is_file($path)) {
                        throw new RuntimeException(sprintf('Extension "%s" references a non-existent XSD file "%s".', get_debug_type($extension), $path));
                    }

                    $schemaLocations[$items[$i]] = $path;
                }
            }
        }

        $tmpfiles = [];
        $imports = '';
        foreach ($schemaLocations as $namespace => $location) {
            $parts = explode('/', $location);
            $locationstart = 'file:///';
            if (0 === stripos($location, 'phar://')) {
                $tmpfile = tempnam(sys_get_temp_dir(), 'symfony');
                if ($tmpfile) {
                    copy($location, $tmpfile);
                    $tmpfiles[] = $tmpfile;
                    $parts = explode('/', str_replace('\\', '/', $tmpfile));
                } else {
                    array_shift($parts);
                    $locationstart = 'phar:///';
                }
            }
            $drive = '\\' === \DIRECTORY_SEPARATOR ? array_shift($parts).'/' : '';
            $location = $locationstart.$drive.implode('/', array_map('rawurlencode', $parts));

            $imports .= sprintf('  <xsd:import namespace="%s" schemaLocation="%s" />'."\n", $namespace, $location);
        }

        $source = <<<EOF
<?xml version="1.0" encoding="utf-8" ?>
<xsd:schema xmlns="http://symfony.com/schema"
    xmlns:xsd="http://www.w3.org/2001/XMLSchema"
    targetNamespace="http://symfony.com/schema"
    elementFormDefault="qualified">

    <xsd:import namespace="http://www.w3.org/XML/1998/namespace"/>
$imports
</xsd:schema>
EOF
        ;

        if (\LIBXML_VERSION < 20900) {
            $disableEntities = libxml_disable_entity_loader(false);
            $valid = @$dom->schemaValidateSource($source);
            libxml_disable_entity_loader($disableEntities);
        } else {
            $valid = @$dom->schemaValidateSource($source);
        }

        foreach ($tmpfiles as $tmpfile) {
            @unlink($tmpfile);
        }

        return $valid;
    }

    private function validateAlias(\DOMElement $alias, string $file)
    {
        foreach ($alias->attributes as $name => $node) {
            if (!\in_array($name, ['alias', 'id', 'public'])) {
                throw new InvalidArgumentException(sprintf('Invalid attribute "%s" defined for alias "%s" in "%s".', $name, $alias->getAttribute('id'), $file));
            }
        }

        foreach ($alias->childNodes as $child) {
            if (!$child instanceof \DOMElement || self::NS !== $child->namespaceURI) {
                continue;
            }
            if (!\in_array($child->localName, ['deprecated'], true)) {
                throw new InvalidArgumentException(sprintf('Invalid child element "%s" defined for alias "%s" in "%s".', $child->localName, $alias->getAttribute('id'), $file));
            }
        }
    }

    /**
     * Validates an extension.
     *
     * @throws InvalidArgumentException When no extension is found corresponding to a tag
     */
    private function validateExtensions(\DOMDocument $dom, string $file)
    {
        foreach ($dom->documentElement->childNodes as $node) {
            if (!$node instanceof \DOMElement || 'http://symfony.com/schema/dic/services' === $node->namespaceURI) {
                continue;
            }

            // can it be handled by an extension?
            if (!$this->container->hasExtension($node->namespaceURI)) {
                $extensionNamespaces = array_filter(array_map(function (ExtensionInterface $ext) { return $ext->getNamespace(); }, $this->container->getExtensions()));
                throw new InvalidArgumentException(sprintf('There is no extension able to load the configuration for "%s" (in "%s"). Looked for namespace "%s", found "%s".', $node->tagName, $file, $node->namespaceURI, $extensionNamespaces ? implode('", "', $extensionNamespaces) : 'none'));
            }
        }
    }

    /**
     * Loads from an extension.
     */
    private function loadFromExtensions(\DOMDocument $xml)
    {
        foreach ($xml->documentElement->childNodes as $node) {
            if (!$node instanceof \DOMElement || self::NS === $node->namespaceURI) {
                continue;
            }

            $values = static::convertDomElementToArray($node);
            if (!\is_array($values)) {
                $values = [];
            }

            $this->container->loadFromExtension($node->namespaceURI, $values);
        }
    }

    /**
     * Converts a \DOMElement object to a PHP array.
     *
     * The following rules applies during the conversion:
     *
     *  * Each tag is converted to a key value or an array
     *    if there is more than one "value"
     *
     *  * The content of a tag is set under a "value" key (<foo>bar</foo>)
     *    if the tag also has some nested tags
     *
     *  * The attributes are converted to keys (<foo foo="bar"/>)
     *
     *  * The nested-tags are converted to keys (<foo><foo>bar</foo></foo>)
     *
     * @param \DOMElement $element A \DOMElement instance
     *
     * @return mixed
     */
    public static function convertDomElementToArray(\DOMElement $element)
    {
        return XmlUtils::convertDomElementToArray($element);
    }
}
PKϤ$Z6�kk.dependency-injection/Loader/GlobFileLoader.phpnu�[���<?php

/*
 * This file is part of the Symfony package.
 *
 * (c) Fabien Potencier <fabien@symfony.com>
 *
 * For the full copyright and license information, please view the LICENSE
 * file that was distributed with this source code.
 */

namespace Symfony\Component\DependencyInjection\Loader;

/**
 * GlobFileLoader loads files from a glob pattern.
 *
 * @author Nicolas Grekas <p@tchwork.com>
 */
class GlobFileLoader extends FileLoader
{
    /**
     * {@inheritdoc}
     */
    public function load($resource, string $type = null)
    {
        foreach ($this->glob($resource, false, $globResource) as $path => $info) {
            $this->import($path);
        }

        $this->container->addResource($globResource);
    }

    /**
     * {@inheritdoc}
     */
    public function supports($resource, string $type = null)
    {
        return 'glob' === $type;
    }
}
PKϤ$Z&��---dependency-injection/Loader/ClosureLoader.phpnu�[���<?php

/*
 * This file is part of the Symfony package.
 *
 * (c) Fabien Potencier <fabien@symfony.com>
 *
 * For the full copyright and license information, please view the LICENSE
 * file that was distributed with this source code.
 */

namespace Symfony\Component\DependencyInjection\Loader;

use Symfony\Component\Config\Loader\Loader;
use Symfony\Component\DependencyInjection\ContainerBuilder;

/**
 * ClosureLoader loads service definitions from a PHP closure.
 *
 * The Closure has access to the container as its first argument.
 *
 * @author Fabien Potencier <fabien@symfony.com>
 */
class ClosureLoader extends Loader
{
    private $container;

    public function __construct(ContainerBuilder $container)
    {
        $this->container = $container;
    }

    /**
     * {@inheritdoc}
     */
    public function load($resource, string $type = null)
    {
        $resource($this->container);
    }

    /**
     * {@inheritdoc}
     */
    public function supports($resource, string $type = null)
    {
        return $resource instanceof \Closure;
    }
}
PKϤ$ZC�@��#�#*dependency-injection/Loader/FileLoader.phpnu�[���<?php

/*
 * This file is part of the Symfony package.
 *
 * (c) Fabien Potencier <fabien@symfony.com>
 *
 * For the full copyright and license information, please view the LICENSE
 * file that was distributed with this source code.
 */

namespace Symfony\Component\DependencyInjection\Loader;

use Symfony\Component\Config\Exception\FileLocatorFileNotFoundException;
use Symfony\Component\Config\Exception\LoaderLoadException;
use Symfony\Component\Config\FileLocatorInterface;
use Symfony\Component\Config\Loader\FileLoader as BaseFileLoader;
use Symfony\Component\Config\Loader\Loader;
use Symfony\Component\Config\Resource\GlobResource;
use Symfony\Component\DependencyInjection\ChildDefinition;
use Symfony\Component\DependencyInjection\ContainerBuilder;
use Symfony\Component\DependencyInjection\Definition;
use Symfony\Component\DependencyInjection\Exception\InvalidArgumentException;

/**
 * FileLoader is the abstract class used by all built-in loaders that are file based.
 *
 * @author Fabien Potencier <fabien@symfony.com>
 */
abstract class FileLoader extends BaseFileLoader
{
    public const ANONYMOUS_ID_REGEXP = '/^\.\d+_[^~]*+~[._a-zA-Z\d]{7}$/';

    protected $container;
    protected $isLoadingInstanceof = false;
    protected $instanceof = [];
    protected $interfaces = [];
    protected $singlyImplemented = [];
    protected $autoRegisterAliasesForSinglyImplementedInterfaces = true;

    public function __construct(ContainerBuilder $container, FileLocatorInterface $locator)
    {
        $this->container = $container;

        parent::__construct($locator);
    }

    /**
     * {@inheritdoc}
     *
     * @param bool|string $ignoreErrors Whether errors should be ignored; pass "not_found" to ignore only when the loaded resource is not found
     */
    public function import($resource, $type = null, $ignoreErrors = false, $sourceResource = null, $exclude = null)
    {
        $args = \func_get_args();

        if ($ignoreNotFound = 'not_found' === $ignoreErrors) {
            $args[2] = false;
        } elseif (!\is_bool($ignoreErrors)) {
            throw new \TypeError(sprintf('Invalid argument $ignoreErrors provided to "%s::import()": boolean or "not_found" expected, "%s" given.', static::class, get_debug_type($ignoreErrors)));
        }

        try {
            parent::import(...$args);
        } catch (LoaderLoadException $e) {
            if (!$ignoreNotFound || !($prev = $e->getPrevious()) instanceof FileLocatorFileNotFoundException) {
                throw $e;
            }

            foreach ($prev->getTrace() as $frame) {
                if ('import' === ($frame['function'] ?? null) && is_a($frame['class'] ?? '', Loader::class, true)) {
                    break;
                }
            }

            if (__FILE__ !== $frame['file']) {
                throw $e;
            }
        }
    }

    /**
     * Registers a set of classes as services using PSR-4 for discovery.
     *
     * @param Definition           $prototype A definition to use as template
     * @param string               $namespace The namespace prefix of classes in the scanned directory
     * @param string               $resource  The directory to look for classes, glob-patterns allowed
     * @param string|string[]|null $exclude   A globbed path of files to exclude or an array of globbed paths of files to exclude
     */
    public function registerClasses(Definition $prototype, $namespace, $resource, $exclude = null)
    {
        if ('\\' !== substr($namespace, -1)) {
            throw new InvalidArgumentException(sprintf('Namespace prefix must end with a "\\": "%s".', $namespace));
        }
        if (!preg_match('/^(?:[a-zA-Z_\x7f-\xff][a-zA-Z0-9_\x7f-\xff]*+\\\\)++$/', $namespace)) {
            throw new InvalidArgumentException(sprintf('Namespace is not a valid PSR-4 prefix: "%s".', $namespace));
        }

        $classes = $this->findClasses($namespace, $resource, (array) $exclude);
        // prepare for deep cloning
        $serializedPrototype = serialize($prototype);

        foreach ($classes as $class => $errorMessage) {
            if (interface_exists($class, false)) {
                $this->interfaces[] = $class;
            } else {
                $this->setDefinition($class, $definition = unserialize($serializedPrototype));
                if (null !== $errorMessage) {
                    $definition->addError($errorMessage);

                    continue;
                }
                foreach (class_implements($class, false) as $interface) {
                    $this->singlyImplemented[$interface] = ($this->singlyImplemented[$interface] ?? $class) !== $class ? false : $class;
                }
            }
        }

        if ($this->autoRegisterAliasesForSinglyImplementedInterfaces) {
            $this->registerAliasesForSinglyImplementedInterfaces();
        }
    }

    public function registerAliasesForSinglyImplementedInterfaces()
    {
        foreach ($this->interfaces as $interface) {
            if (!empty($this->singlyImplemented[$interface]) && !$this->container->has($interface)) {
                $this->container->setAlias($interface, $this->singlyImplemented[$interface])->setPublic(false);
            }
        }

        $this->interfaces = $this->singlyImplemented = [];
    }

    /**
     * Registers a definition in the container with its instanceof-conditionals.
     *
     * @param string $id
     */
    protected function setDefinition($id, Definition $definition)
    {
        $this->container->removeBindings($id);

        if ($this->isLoadingInstanceof) {
            if (!$definition instanceof ChildDefinition) {
                throw new InvalidArgumentException(sprintf('Invalid type definition "%s": ChildDefinition expected, "%s" given.', $id, get_debug_type($definition)));
            }
            $this->instanceof[$id] = $definition;
        } else {
            $this->container->setDefinition($id, $definition->setInstanceofConditionals($this->instanceof));
        }
    }

    private function findClasses(string $namespace, string $pattern, array $excludePatterns): array
    {
        $parameterBag = $this->container->getParameterBag();

        $excludePaths = [];
        $excludePrefix = null;
        $excludePatterns = $parameterBag->unescapeValue($parameterBag->resolveValue($excludePatterns));
        foreach ($excludePatterns as $excludePattern) {
            foreach ($this->glob($excludePattern, true, $resource, true, true) as $path => $info) {
                if (null === $excludePrefix) {
                    $excludePrefix = $resource->getPrefix();
                }

                // normalize Windows slashes
                $excludePaths[str_replace('\\', '/', $path)] = true;
            }
        }

        $pattern = $parameterBag->unescapeValue($parameterBag->resolveValue($pattern));
        $classes = [];
        $extRegexp = '/\\.php$/';
        $prefixLen = null;
        foreach ($this->glob($pattern, true, $resource, false, false, $excludePaths) as $path => $info) {
            if (null === $prefixLen) {
                $prefixLen = \strlen($resource->getPrefix());

                if ($excludePrefix && 0 !== strpos($excludePrefix, $resource->getPrefix())) {
                    throw new InvalidArgumentException(sprintf('Invalid "exclude" pattern when importing classes for "%s": make sure your "exclude" pattern (%s) is a subset of the "resource" pattern (%s).', $namespace, $excludePattern, $pattern));
                }
            }

            if (isset($excludePaths[str_replace('\\', '/', $path)])) {
                continue;
            }

            if (!preg_match($extRegexp, $path, $m) || !$info->isReadable()) {
                continue;
            }
            $class = $namespace.ltrim(str_replace('/', '\\', substr($path, $prefixLen, -\strlen($m[0]))), '\\');

            if (!preg_match('/^[a-zA-Z_\x7f-\xff][a-zA-Z0-9_\x7f-\xff]*+(?:\\\\[a-zA-Z_\x7f-\xff][a-zA-Z0-9_\x7f-\xff]*+)*+$/', $class)) {
                continue;
            }

            try {
                $r = $this->container->getReflectionClass($class);
            } catch (\ReflectionException $e) {
                $classes[$class] = $e->getMessage();
                continue;
            }
            // check to make sure the expected class exists
            if (!$r) {
                throw new InvalidArgumentException(sprintf('Expected to find class "%s" in file "%s" while importing services from resource "%s", but it was not found! Check the namespace prefix used with the resource.', $class, $path, $pattern));
            }

            if ($r->isInstantiable() || $r->isInterface()) {
                $classes[$class] = null;
            }
        }

        // track only for new & removed files
        if ($resource instanceof GlobResource) {
            $this->container->addResource($resource);
        } else {
            foreach ($resource as $path) {
                $this->container->fileExists($path, false);
            }
        }

        return $classes;
    }
}
PKϤ$Z���"dependency-injection/Reference.phpnu�[���<?php

/*
 * This file is part of the Symfony package.
 *
 * (c) Fabien Potencier <fabien@symfony.com>
 *
 * For the full copyright and license information, please view the LICENSE
 * file that was distributed with this source code.
 */

namespace Symfony\Component\DependencyInjection;

/**
 * Reference represents a service reference.
 *
 * @author Fabien Potencier <fabien@symfony.com>
 */
class Reference
{
    private $id;
    private $invalidBehavior;

    public function __construct(string $id, int $invalidBehavior = ContainerInterface::EXCEPTION_ON_INVALID_REFERENCE)
    {
        $this->id = $id;
        $this->invalidBehavior = $invalidBehavior;
    }

    /**
     * @return string The service identifier
     */
    public function __toString()
    {
        return $this->id;
    }

    /**
     * Returns the behavior to be used when the service does not exist.
     *
     * @return int
     */
    public function getInvalidBehavior()
    {
        return $this->invalidBehavior;
    }
}
PKϤ$Z%�z&&;dependency-injection/Config/ContainerParametersResource.phpnu�[���<?php

/*
 * This file is part of the Symfony package.
 *
 * (c) Fabien Potencier <fabien@symfony.com>
 *
 * For the full copyright and license information, please view the LICENSE
 * file that was distributed with this source code.
 */

namespace Symfony\Component\DependencyInjection\Config;

use Symfony\Component\Config\Resource\ResourceInterface;

/**
 * Tracks container parameters.
 *
 * @author Maxime Steinhausser <maxime.steinhausser@gmail.com>
 *
 * @final
 */
class ContainerParametersResource implements ResourceInterface
{
    private $parameters;

    /**
     * @param array $parameters The container parameters to track
     */
    public function __construct(array $parameters)
    {
        $this->parameters = $parameters;
    }

    /**
     * {@inheritdoc}
     */
    public function __toString(): string
    {
        return 'container_parameters_'.md5(serialize($this->parameters));
    }

    /**
     * @return array Tracked parameters
     */
    public function getParameters(): array
    {
        return $this->parameters;
    }
}
PKϤ$Zn�L���7dependency-injection/Config/AutowireServiceResource.phpnu�[���<?php

/*
 * This file is part of the Symfony package.
 *
 * (c) Fabien Potencier <fabien@symfony.com>
 *
 * For the full copyright and license information, please view the LICENSE
 * file that was distributed with this source code.
 */

namespace Symfony\Component\DependencyInjection\Config;

use Symfony\Component\Config\Resource\SelfCheckingResourceInterface;
use Symfony\Component\DependencyInjection\Compiler\AutowirePass;

class AutowireServiceResource implements SelfCheckingResourceInterface, \Serializable
{
    private $class;
    private $filePath;
    private $autowiringMetadata = array();

    public function __construct($class, $path, array $autowiringMetadata)
    {
        $this->class = $class;
        $this->filePath = $path;
        $this->autowiringMetadata = $autowiringMetadata;
    }

    public function isFresh($timestamp)
    {
        if (!file_exists($this->filePath)) {
            return false;
        }

        // has the file *not* been modified? Definitely fresh
        if (@filemtime($this->filePath) <= $timestamp) {
            return true;
        }

        try {
            $reflectionClass = new \ReflectionClass($this->class);
        } catch (\ReflectionException $e) {
            // the class does not exist anymore!
            return false;
        }

        return (array) $this === (array) AutowirePass::createResourceForClass($reflectionClass);
    }

    public function __toString()
    {
        return 'service.autowire.'.$this->class;
    }

    public function serialize()
    {
        return serialize(array($this->class, $this->filePath, $this->autowiringMetadata));
    }

    public function unserialize($serialized)
    {
        list($this->class, $this->filePath, $this->autowiringMetadata) = unserialize($serialized);
    }

    /**
     * @deprecated Implemented for compatibility with Symfony 2.8
     */
    public function getResource()
    {
        return $this->filePath;
    }
}
PKϤ$Zf��==Bdependency-injection/Config/ContainerParametersResourceChecker.phpnu�[���<?php

/*
 * This file is part of the Symfony package.
 *
 * (c) Fabien Potencier <fabien@symfony.com>
 *
 * For the full copyright and license information, please view the LICENSE
 * file that was distributed with this source code.
 */

namespace Symfony\Component\DependencyInjection\Config;

use Symfony\Component\Config\Resource\ResourceInterface;
use Symfony\Component\Config\ResourceCheckerInterface;
use Symfony\Component\DependencyInjection\ContainerInterface;

/**
 * @author Maxime Steinhausser <maxime.steinhausser@gmail.com>
 */
class ContainerParametersResourceChecker implements ResourceCheckerInterface
{
    /** @var ContainerInterface */
    private $container;

    public function __construct(ContainerInterface $container)
    {
        $this->container = $container;
    }

    /**
     * {@inheritdoc}
     */
    public function supports(ResourceInterface $metadata)
    {
        return $metadata instanceof ContainerParametersResource;
    }

    /**
     * {@inheritdoc}
     */
    public function isFresh(ResourceInterface $resource, int $timestamp)
    {
        foreach ($resource->getParameters() as $key => $value) {
            if (!$this->container->hasParameter($key) || $this->container->getParameter($key) !== $value) {
                return false;
            }
        }

        return true;
    }
}
PKϤ$Z��?��3dependency-injection/ExpressionLanguageProvider.phpnu�[���<?php

/*
 * This file is part of the Symfony package.
 *
 * (c) Fabien Potencier <fabien@symfony.com>
 *
 * For the full copyright and license information, please view the LICENSE
 * file that was distributed with this source code.
 */

namespace Symfony\Component\DependencyInjection;

use Symfony\Component\ExpressionLanguage\ExpressionFunction;
use Symfony\Component\ExpressionLanguage\ExpressionFunctionProviderInterface;

/**
 * Define some ExpressionLanguage functions.
 *
 * To get a service, use service('request').
 * To get a parameter, use parameter('kernel.debug').
 *
 * @author Fabien Potencier <fabien@symfony.com>
 */
class ExpressionLanguageProvider implements ExpressionFunctionProviderInterface
{
    private $serviceCompiler;

    public function __construct(callable $serviceCompiler = null)
    {
        $this->serviceCompiler = $serviceCompiler;
    }

    public function getFunctions()
    {
        return [
            new ExpressionFunction('service', $this->serviceCompiler ?: function ($arg) {
                return sprintf('$this->get(%s)', $arg);
            }, function (array $variables, $value) {
                return $variables['container']->get($value);
            }),

            new ExpressionFunction('parameter', function ($arg) {
                return sprintf('$this->getParameter(%s)', $arg);
            }, function (array $variables, $value) {
                return $variables['container']->getParameter($value);
            }),
        ];
    }
}
PKϤ$Z���*�
�
8dependency-injection/Argument/TaggedIteratorArgument.phpnu�[���<?php

/*
 * This file is part of the Symfony package.
 *
 * (c) Fabien Potencier <fabien@symfony.com>
 *
 * For the full copyright and license information, please view the LICENSE
 * file that was distributed with this source code.
 */

namespace Symfony\Component\DependencyInjection\Argument;

/**
 * Represents a collection of services found by tag name to lazily iterate over.
 *
 * @author Roland Franssen <franssen.roland@gmail.com>
 */
class TaggedIteratorArgument extends IteratorArgument
{
    private $tag;
    private $indexAttribute;
    private $defaultIndexMethod;
    private $defaultPriorityMethod;
    private $needsIndexes = false;

    /**
     * @param string      $tag                   The name of the tag identifying the target services
     * @param string|null $indexAttribute        The name of the attribute that defines the key referencing each service in the tagged collection
     * @param string|null $defaultIndexMethod    The static method that should be called to get each service's key when their tag doesn't define the previous attribute
     * @param bool        $needsIndexes          Whether indexes are required and should be generated when computing the map
     * @param string|null $defaultPriorityMethod The static method that should be called to get each service's priority when their tag doesn't define the "priority" attribute
     */
    public function __construct(string $tag, string $indexAttribute = null, string $defaultIndexMethod = null, bool $needsIndexes = false, string $defaultPriorityMethod = null)
    {
        parent::__construct([]);

        if (null === $indexAttribute && $needsIndexes) {
            $indexAttribute = preg_match('/[^.]++$/', $tag, $m) ? $m[0] : $tag;
        }

        $this->tag = $tag;
        $this->indexAttribute = $indexAttribute;
        $this->defaultIndexMethod = $defaultIndexMethod ?: ('getDefault'.str_replace(' ', '', ucwords(preg_replace('/[^a-zA-Z0-9\x7f-\xff]++/', ' ', $indexAttribute ?? ''))).'Name');
        $this->needsIndexes = $needsIndexes;
        $this->defaultPriorityMethod = $defaultPriorityMethod ?: ('getDefault'.str_replace(' ', '', ucwords(preg_replace('/[^a-zA-Z0-9\x7f-\xff]++/', ' ', $indexAttribute ?? ''))).'Priority');
    }

    public function getTag()
    {
        return $this->tag;
    }

    public function getIndexAttribute(): ?string
    {
        return $this->indexAttribute;
    }

    public function getDefaultIndexMethod(): ?string
    {
        return $this->defaultIndexMethod;
    }

    public function needsIndexes(): bool
    {
        return $this->needsIndexes;
    }

    public function getDefaultPriorityMethod(): ?string
    {
        return $this->defaultPriorityMethod;
    }
}
PKϤ$Z�b��((8dependency-injection/Argument/ServiceLocatorArgument.phpnu�[���<?php

/*
 * This file is part of the Symfony package.
 *
 * (c) Fabien Potencier <fabien@symfony.com>
 *
 * For the full copyright and license information, please view the LICENSE
 * file that was distributed with this source code.
 */

namespace Symfony\Component\DependencyInjection\Argument;

use Symfony\Component\DependencyInjection\Reference;

/**
 * Represents a closure acting as a service locator.
 *
 * @author Nicolas Grekas <p@tchwork.com>
 */
class ServiceLocatorArgument implements ArgumentInterface
{
    use ReferenceSetArgumentTrait;

    private $taggedIteratorArgument;

    /**
     * @param Reference[]|TaggedIteratorArgument $values
     */
    public function __construct($values = [])
    {
        if ($values instanceof TaggedIteratorArgument) {
            $this->taggedIteratorArgument = $values;
            $this->values = [];
        } else {
            $this->setValues($values);
        }
    }

    public function getTaggedIteratorArgument(): ?TaggedIteratorArgument
    {
        return $this->taggedIteratorArgument;
    }
}
PKϤ$Z��*���2dependency-injection/Argument/AbstractArgument.phpnu�[���<?php

/*
 * This file is part of the Symfony package.
 *
 * (c) Fabien Potencier <fabien@symfony.com>
 *
 * For the full copyright and license information, please view the LICENSE
 * file that was distributed with this source code.
 */

namespace Symfony\Component\DependencyInjection\Argument;

/**
 * Represents an abstract service argument, which have to be set by a compiler pass or a DI extension.
 */
final class AbstractArgument
{
    private $text;
    private $context;

    public function __construct(string $text = '')
    {
        $this->text = trim($text, '. ');
    }

    public function setContext(string $context): void
    {
        $this->context = $context.' is abstract'.('' === $this->text ? '' : ': ');
    }

    public function getText(): string
    {
        return $this->text;
    }

    public function getTextWithContext(): string
    {
        return $this->context.$this->text.'.';
    }
}
PKϤ$Z��8�::3dependency-injection/Argument/ArgumentInterface.phpnu�[���<?php

/*
 * This file is part of the Symfony package.
 *
 * (c) Fabien Potencier <fabien@symfony.com>
 *
 * For the full copyright and license information, please view the LICENSE
 * file that was distributed with this source code.
 */

namespace Symfony\Component\DependencyInjection\Argument;

/**
 * Represents a complex argument containing nested values.
 *
 * @author Titouan Galopin <galopintitouan@gmail.com>
 */
interface ArgumentInterface
{
    /**
     * @return array
     */
    public function getValues();

    public function setValues(array $values);
}
PKϤ$Z�Ѿ{��8dependency-injection/Argument/ServiceClosureArgument.phpnu�[���<?php

/*
 * This file is part of the Symfony package.
 *
 * (c) Fabien Potencier <fabien@symfony.com>
 *
 * For the full copyright and license information, please view the LICENSE
 * file that was distributed with this source code.
 */

namespace Symfony\Component\DependencyInjection\Argument;

use Symfony\Component\DependencyInjection\Exception\InvalidArgumentException;
use Symfony\Component\DependencyInjection\Reference;

/**
 * Represents a service wrapped in a memoizing closure.
 *
 * @author Nicolas Grekas <p@tchwork.com>
 */
class ServiceClosureArgument implements ArgumentInterface
{
    private $values;

    public function __construct(Reference $reference)
    {
        $this->values = [$reference];
    }

    /**
     * {@inheritdoc}
     */
    public function getValues()
    {
        return $this->values;
    }

    /**
     * {@inheritdoc}
     */
    public function setValues(array $values)
    {
        if ([0] !== array_keys($values) || !($values[0] instanceof Reference || null === $values[0])) {
            throw new InvalidArgumentException('A ServiceClosureArgument must hold one and only one Reference.');
        }

        $this->values = $values;
    }
}
PKϤ$Z�S%T33;dependency-injection/Argument/ReferenceSetArgumentTrait.phpnu�[���<?php

/*
 * This file is part of the Symfony package.
 *
 * (c) Fabien Potencier <fabien@symfony.com>
 *
 * For the full copyright and license information, please view the LICENSE
 * file that was distributed with this source code.
 */

namespace Symfony\Component\DependencyInjection\Argument;

use Symfony\Component\DependencyInjection\Exception\InvalidArgumentException;
use Symfony\Component\DependencyInjection\Reference;

/**
 * @author Titouan Galopin <galopintitouan@gmail.com>
 * @author Nicolas Grekas <p@tchwork.com>
 */
trait ReferenceSetArgumentTrait
{
    private $values;

    /**
     * @param Reference[] $values
     */
    public function __construct(array $values)
    {
        $this->setValues($values);
    }

    /**
     * @return Reference[] The values in the set
     */
    public function getValues()
    {
        return $this->values;
    }

    /**
     * @param Reference[] $values The service references to put in the set
     */
    public function setValues(array $values)
    {
        foreach ($values as $k => $v) {
            if (null !== $v && !$v instanceof Reference) {
                throw new InvalidArgumentException(sprintf('A "%s" must hold only Reference instances, "%s" given.', __CLASS__, get_debug_type($v)));
            }
        }

        $this->values = $values;
    }
}
PKϤ$Z�jv2dependency-injection/Argument/IteratorArgument.phpnu�[���<?php

/*
 * This file is part of the Symfony package.
 *
 * (c) Fabien Potencier <fabien@symfony.com>
 *
 * For the full copyright and license information, please view the LICENSE
 * file that was distributed with this source code.
 */

namespace Symfony\Component\DependencyInjection\Argument;

/**
 * Represents a collection of values to lazily iterate over.
 *
 * @author Titouan Galopin <galopintitouan@gmail.com>
 */
class IteratorArgument implements ArgumentInterface
{
    use ReferenceSetArgumentTrait;
}
PKϤ$Z=X��/dependency-injection/Argument/BoundArgument.phpnu�[���<?php

/*
 * This file is part of the Symfony package.
 *
 * (c) Fabien Potencier <fabien@symfony.com>
 *
 * For the full copyright and license information, please view the LICENSE
 * file that was distributed with this source code.
 */

namespace Symfony\Component\DependencyInjection\Argument;

/**
 * @author Guilhem Niot <guilhem.niot@gmail.com>
 */
final class BoundArgument implements ArgumentInterface
{
    const SERVICE_BINDING = 0;
    const DEFAULTS_BINDING = 1;
    const INSTANCEOF_BINDING = 2;

    private static $sequence = 0;

    private $value;
    private $identifier;
    private $used;
    private $type;
    private $file;

    public function __construct($value, bool $trackUsage = true, int $type = 0, string $file = null)
    {
        $this->value = $value;
        if ($trackUsage) {
            $this->identifier = ++self::$sequence;
        } else {
            $this->used = true;
        }
        $this->type = $type;
        $this->file = $file;
    }

    /**
     * {@inheritdoc}
     */
    public function getValues(): array
    {
        return [$this->value, $this->identifier, $this->used, $this->type, $this->file];
    }

    /**
     * {@inheritdoc}
     */
    public function setValues(array $values)
    {
        if (5 === \count($values)) {
            list($this->value, $this->identifier, $this->used, $this->type, $this->file) = $values;
        } else {
            list($this->value, $this->identifier, $this->used) = $values;
        }
    }
}
PKϤ$Z�x)>��5dependency-injection/Argument/RewindableGenerator.phpnu�[���<?php

/*
 * This file is part of the Symfony package.
 *
 * (c) Fabien Potencier <fabien@symfony.com>
 *
 * For the full copyright and license information, please view the LICENSE
 * file that was distributed with this source code.
 */

namespace Symfony\Component\DependencyInjection\Argument;

/**
 * @internal
 */
class RewindableGenerator implements \IteratorAggregate, \Countable
{
    private $generator;
    private $count;

    /**
     * @param int|callable $count
     */
    public function __construct(callable $generator, $count)
    {
        $this->generator = $generator;
        $this->count = $count;
    }

    public function getIterator(): \Traversable
    {
        $g = $this->generator;

        return $g();
    }

    public function count(): int
    {
        if (\is_callable($count = $this->count)) {
            $this->count = $count();
        }

        return $this->count;
    }
}
PKϤ$Z������0dependency-injection/Argument/ServiceLocator.phpnu�[���<?php

/*
 * This file is part of the Symfony package.
 *
 * (c) Fabien Potencier <fabien@symfony.com>
 *
 * For the full copyright and license information, please view the LICENSE
 * file that was distributed with this source code.
 */

namespace Symfony\Component\DependencyInjection\Argument;

use Symfony\Component\DependencyInjection\ServiceLocator as BaseServiceLocator;

/**
 * @author Nicolas Grekas <p@tchwork.com>
 *
 * @internal
 */
class ServiceLocator extends BaseServiceLocator
{
    private $factory;
    private $serviceMap;
    private $serviceTypes;

    public function __construct(\Closure $factory, array $serviceMap, array $serviceTypes = null)
    {
        $this->factory = $factory;
        $this->serviceMap = $serviceMap;
        $this->serviceTypes = $serviceTypes;
        parent::__construct($serviceMap);
    }

    /**
     * {@inheritdoc}
     */
    public function get($id)
    {
        return isset($this->serviceMap[$id]) ? ($this->factory)(...$this->serviceMap[$id]) : parent::get($id);
    }

    /**
     * {@inheritdoc}
     */
    public function getProvidedServices(): array
    {
        return $this->serviceTypes ?? $this->serviceTypes = array_map(function () { return '?'; }, $this->serviceMap);
    }
}
PKϤ$Z#��>3>3*dependency-injection/Dumper/YamlDumper.phpnu�[���<?php

/*
 * This file is part of the Symfony package.
 *
 * (c) Fabien Potencier <fabien@symfony.com>
 *
 * For the full copyright and license information, please view the LICENSE
 * file that was distributed with this source code.
 */

namespace Symfony\Component\DependencyInjection\Dumper;

use Symfony\Component\DependencyInjection\Alias;
use Symfony\Component\DependencyInjection\Argument\AbstractArgument;
use Symfony\Component\DependencyInjection\Argument\ArgumentInterface;
use Symfony\Component\DependencyInjection\Argument\IteratorArgument;
use Symfony\Component\DependencyInjection\Argument\ServiceClosureArgument;
use Symfony\Component\DependencyInjection\Argument\ServiceLocatorArgument;
use Symfony\Component\DependencyInjection\Argument\TaggedIteratorArgument;
use Symfony\Component\DependencyInjection\ContainerInterface;
use Symfony\Component\DependencyInjection\Definition;
use Symfony\Component\DependencyInjection\Exception\LogicException;
use Symfony\Component\DependencyInjection\Exception\RuntimeException;
use Symfony\Component\DependencyInjection\Parameter;
use Symfony\Component\DependencyInjection\Reference;
use Symfony\Component\ExpressionLanguage\Expression;
use Symfony\Component\Yaml\Dumper as YmlDumper;
use Symfony\Component\Yaml\Parser;
use Symfony\Component\Yaml\Tag\TaggedValue;
use Symfony\Component\Yaml\Yaml;

/**
 * YamlDumper dumps a service container as a YAML string.
 *
 * @author Fabien Potencier <fabien@symfony.com>
 */
class YamlDumper extends Dumper
{
    private $dumper;

    /**
     * Dumps the service container as an YAML string.
     *
     * @return string A YAML string representing of the service container
     */
    public function dump(array $options = [])
    {
        if (!class_exists('Symfony\Component\Yaml\Dumper')) {
            throw new LogicException('Unable to dump the container as the Symfony Yaml Component is not installed.');
        }

        if (null === $this->dumper) {
            $this->dumper = new YmlDumper();
        }

        return $this->container->resolveEnvPlaceholders($this->addParameters()."\n".$this->addServices());
    }

    private function addService(string $id, Definition $definition): string
    {
        $code = "    $id:\n";
        if ($class = $definition->getClass()) {
            if ('\\' === substr($class, 0, 1)) {
                $class = substr($class, 1);
            }

            $code .= sprintf("        class: %s\n", $this->dumper->dump($class));
        }

        if (!$definition->isPrivate()) {
            $code .= sprintf("        public: %s\n", $definition->isPublic() ? 'true' : 'false');
        }

        $tagsCode = '';
        foreach ($definition->getTags() as $name => $tags) {
            foreach ($tags as $attributes) {
                $att = [];
                foreach ($attributes as $key => $value) {
                    $att[] = sprintf('%s: %s', $this->dumper->dump($key), $this->dumper->dump($value));
                }
                $att = $att ? ': { '.implode(', ', $att).' }' : '';

                $tagsCode .= sprintf("            - %s%s\n", $this->dumper->dump($name), $att);
            }
        }
        if ($tagsCode) {
            $code .= "        tags:\n".$tagsCode;
        }

        if ($definition->getFile()) {
            $code .= sprintf("        file: %s\n", $this->dumper->dump($definition->getFile()));
        }

        if ($definition->isSynthetic()) {
            $code .= "        synthetic: true\n";
        }

        if ($definition->isDeprecated()) {
            $code .= "        deprecated:\n";
            foreach ($definition->getDeprecation('%service_id%') as $key => $value) {
                if ('' !== $value) {
                    $code .= sprintf("            %s: %s\n", $key, $this->dumper->dump($value));
                }
            }
        }

        if ($definition->isAutowired()) {
            $code .= "        autowire: true\n";
        }

        if ($definition->isAutoconfigured()) {
            $code .= "        autoconfigure: true\n";
        }

        if ($definition->isAbstract()) {
            $code .= "        abstract: true\n";
        }

        if ($definition->isLazy()) {
            $code .= "        lazy: true\n";
        }

        if ($definition->getArguments()) {
            $code .= sprintf("        arguments: %s\n", $this->dumper->dump($this->dumpValue($definition->getArguments()), 0));
        }

        if ($definition->getProperties()) {
            $code .= sprintf("        properties: %s\n", $this->dumper->dump($this->dumpValue($definition->getProperties()), 0));
        }

        if ($definition->getMethodCalls()) {
            $code .= sprintf("        calls:\n%s\n", $this->dumper->dump($this->dumpValue($definition->getMethodCalls()), 1, 12));
        }

        if (!$definition->isShared()) {
            $code .= "        shared: false\n";
        }

        if (null !== $decoratedService = $definition->getDecoratedService()) {
            list($decorated, $renamedId, $priority) = $decoratedService;
            $code .= sprintf("        decorates: %s\n", $decorated);
            if (null !== $renamedId) {
                $code .= sprintf("        decoration_inner_name: %s\n", $renamedId);
            }
            if (0 !== $priority) {
                $code .= sprintf("        decoration_priority: %s\n", $priority);
            }

            $decorationOnInvalid = $decoratedService[3] ?? ContainerInterface::EXCEPTION_ON_INVALID_REFERENCE;
            if (\in_array($decorationOnInvalid, [ContainerInterface::IGNORE_ON_INVALID_REFERENCE, ContainerInterface::NULL_ON_INVALID_REFERENCE])) {
                $invalidBehavior = ContainerInterface::NULL_ON_INVALID_REFERENCE === $decorationOnInvalid ? 'null' : 'ignore';
                $code .= sprintf("        decoration_on_invalid: %s\n", $invalidBehavior);
            }
        }

        if ($callable = $definition->getFactory()) {
            $code .= sprintf("        factory: %s\n", $this->dumper->dump($this->dumpCallable($callable), 0));
        }

        if ($callable = $definition->getConfigurator()) {
            $code .= sprintf("        configurator: %s\n", $this->dumper->dump($this->dumpCallable($callable), 0));
        }

        return $code;
    }

    private function addServiceAlias(string $alias, Alias $id): string
    {
        $deprecated = '';

        if ($id->isDeprecated()) {
            $deprecated = "        deprecated:\n";

            foreach ($id->getDeprecation('%alias_id%') as $key => $value) {
                if ('' !== $value) {
                    $deprecated .= sprintf("            %s: %s\n", $key, $value);
                }
            }
        }

        if (!$id->isDeprecated() && $id->isPrivate()) {
            return sprintf("    %s: '@%s'\n", $alias, $id);
        }

        return sprintf("    %s:\n        alias: %s\n        public: %s\n%s", $alias, $id, $id->isPublic() ? 'true' : 'false', $deprecated);
    }

    private function addServices(): string
    {
        if (!$this->container->getDefinitions()) {
            return '';
        }

        $code = "services:\n";
        foreach ($this->container->getDefinitions() as $id => $definition) {
            $code .= $this->addService($id, $definition);
        }

        $aliases = $this->container->getAliases();
        foreach ($aliases as $alias => $id) {
            while (isset($aliases[(string) $id])) {
                $id = $aliases[(string) $id];
            }
            $code .= $this->addServiceAlias($alias, $id);
        }

        return $code;
    }

    private function addParameters(): string
    {
        if (!$this->container->getParameterBag()->all()) {
            return '';
        }

        $parameters = $this->prepareParameters($this->container->getParameterBag()->all(), $this->container->isCompiled());

        return $this->dumper->dump(['parameters' => $parameters], 2);
    }

    /**
     * Dumps callable to YAML format.
     *
     * @param mixed $callable
     *
     * @return mixed
     */
    private function dumpCallable($callable)
    {
        if (\is_array($callable)) {
            if ($callable[0] instanceof Reference) {
                $callable = [$this->getServiceCall((string) $callable[0], $callable[0]), $callable[1]];
            } else {
                $callable = [$callable[0], $callable[1]];
            }
        }

        return $callable;
    }

    /**
     * Dumps the value to YAML format.
     *
     * @return mixed
     *
     * @throws RuntimeException When trying to dump object or resource
     */
    private function dumpValue($value)
    {
        if ($value instanceof ServiceClosureArgument) {
            $value = $value->getValues()[0];
        }
        if ($value instanceof ArgumentInterface) {
            $tag = $value;

            if ($value instanceof TaggedIteratorArgument || ($value instanceof ServiceLocatorArgument && $tag = $value->getTaggedIteratorArgument())) {
                if (null === $tag->getIndexAttribute()) {
                    $content = $tag->getTag();
                } else {
                    $content = [
                        'tag' => $tag->getTag(),
                        'index_by' => $tag->getIndexAttribute(),
                    ];

                    if (null !== $tag->getDefaultIndexMethod()) {
                        $content['default_index_method'] = $tag->getDefaultIndexMethod();
                    }
                    if (null !== $tag->getDefaultPriorityMethod()) {
                        $content['default_priority_method'] = $tag->getDefaultPriorityMethod();
                    }
                }

                return new TaggedValue($value instanceof TaggedIteratorArgument ? 'tagged_iterator' : 'tagged_locator', $content);
            }

            if ($value instanceof IteratorArgument) {
                $tag = 'iterator';
            } elseif ($value instanceof ServiceLocatorArgument) {
                $tag = 'service_locator';
            } else {
                throw new RuntimeException(sprintf('Unspecified Yaml tag for type "%s".', get_debug_type($value)));
            }

            return new TaggedValue($tag, $this->dumpValue($value->getValues()));
        }

        if (\is_array($value)) {
            $code = [];
            foreach ($value as $k => $v) {
                $code[$k] = $this->dumpValue($v);
            }

            return $code;
        } elseif ($value instanceof Reference) {
            return $this->getServiceCall((string) $value, $value);
        } elseif ($value instanceof Parameter) {
            return $this->getParameterCall((string) $value);
        } elseif ($value instanceof Expression) {
            return $this->getExpressionCall((string) $value);
        } elseif ($value instanceof Definition) {
            return new TaggedValue('service', (new Parser())->parse("_:\n".$this->addService('_', $value), Yaml::PARSE_CUSTOM_TAGS)['_']['_']);
        } elseif ($value instanceof AbstractArgument) {
            return new TaggedValue('abstract', $value->getText());
        } elseif (\is_object($value) || \is_resource($value)) {
            throw new RuntimeException('Unable to dump a service container if a parameter is an object or a resource.');
        }

        return $value;
    }

    private function getServiceCall(string $id, Reference $reference = null): string
    {
        if (null !== $reference) {
            switch ($reference->getInvalidBehavior()) {
                case ContainerInterface::RUNTIME_EXCEPTION_ON_INVALID_REFERENCE: break;
                case ContainerInterface::EXCEPTION_ON_INVALID_REFERENCE: break;
                case ContainerInterface::IGNORE_ON_UNINITIALIZED_REFERENCE: return sprintf('@!%s', $id);
                default: return sprintf('@?%s', $id);
            }
        }

        return sprintf('@%s', $id);
    }

    private function getParameterCall(string $id): string
    {
        return sprintf('%%%s%%', $id);
    }

    private function getExpressionCall(string $expression): string
    {
        return sprintf('@=%s', $expression);
    }

    private function prepareParameters(array $parameters, bool $escape = true): array
    {
        $filtered = [];
        foreach ($parameters as $key => $value) {
            if (\is_array($value)) {
                $value = $this->prepareParameters($value, $escape);
            } elseif ($value instanceof Reference || \is_string($value) && 0 === strpos($value, '@')) {
                $value = '@'.$value;
            }

            $filtered[$key] = $value;
        }

        return $escape ? $this->escape($filtered) : $filtered;
    }

    private function escape(array $arguments): array
    {
        $args = [];
        foreach ($arguments as $k => $v) {
            if (\is_array($v)) {
                $args[$k] = $this->escape($v);
            } elseif (\is_string($v)) {
                $args[$k] = str_replace('%', '%%', $v);
            } else {
                $args[$k] = $v;
            }
        }

        return $args;
    }
}
PKϤ$Z2�gU��&dependency-injection/Dumper/Dumper.phpnu�[���<?php

/*
 * This file is part of the Symfony package.
 *
 * (c) Fabien Potencier <fabien@symfony.com>
 *
 * For the full copyright and license information, please view the LICENSE
 * file that was distributed with this source code.
 */

namespace Symfony\Component\DependencyInjection\Dumper;

use Symfony\Component\DependencyInjection\ContainerBuilder;

/**
 * Dumper is the abstract class for all built-in dumpers.
 *
 * @author Fabien Potencier <fabien@symfony.com>
 */
abstract class Dumper implements DumperInterface
{
    protected $container;

    public function __construct(ContainerBuilder $container)
    {
        $this->container = $container;
    }
}
PKϤ$Z��ٵ��/dependency-injection/Dumper/DumperInterface.phpnu�[���<?php

/*
 * This file is part of the Symfony package.
 *
 * (c) Fabien Potencier <fabien@symfony.com>
 *
 * For the full copyright and license information, please view the LICENSE
 * file that was distributed with this source code.
 */

namespace Symfony\Component\DependencyInjection\Dumper;

/**
 * DumperInterface is the interface implemented by service container dumper classes.
 *
 * @author Fabien Potencier <fabien@symfony.com>
 */
interface DumperInterface
{
    /**
     * Dumps the service container.
     *
     * @return string|array The representation of the service container
     */
    public function dump(array $options = []);
}
PKϤ$Zƈֲ>�>)dependency-injection/Dumper/XmlDumper.phpnu�[���<?php

/*
 * This file is part of the Symfony package.
 *
 * (c) Fabien Potencier <fabien@symfony.com>
 *
 * For the full copyright and license information, please view the LICENSE
 * file that was distributed with this source code.
 */

namespace Symfony\Component\DependencyInjection\Dumper;

use Symfony\Component\DependencyInjection\Alias;
use Symfony\Component\DependencyInjection\Argument\AbstractArgument;
use Symfony\Component\DependencyInjection\Argument\IteratorArgument;
use Symfony\Component\DependencyInjection\Argument\ServiceClosureArgument;
use Symfony\Component\DependencyInjection\Argument\ServiceLocatorArgument;
use Symfony\Component\DependencyInjection\Argument\TaggedIteratorArgument;
use Symfony\Component\DependencyInjection\ContainerInterface;
use Symfony\Component\DependencyInjection\Definition;
use Symfony\Component\DependencyInjection\Exception\RuntimeException;
use Symfony\Component\DependencyInjection\Parameter;
use Symfony\Component\DependencyInjection\Reference;
use Symfony\Component\ExpressionLanguage\Expression;

/**
 * XmlDumper dumps a service container as an XML string.
 *
 * @author Fabien Potencier <fabien@symfony.com>
 * @author Martin Hasoň <martin.hason@gmail.com>
 */
class XmlDumper extends Dumper
{
    /**
     * @var \DOMDocument
     */
    private $document;

    /**
     * Dumps the service container as an XML string.
     *
     * @return string An xml string representing of the service container
     */
    public function dump(array $options = [])
    {
        $this->document = new \DOMDocument('1.0', 'utf-8');
        $this->document->formatOutput = true;

        $container = $this->document->createElementNS('http://symfony.com/schema/dic/services', 'container');
        $container->setAttribute('xmlns:xsi', 'http://www.w3.org/2001/XMLSchema-instance');
        $container->setAttribute('xsi:schemaLocation', 'http://symfony.com/schema/dic/services https://symfony.com/schema/dic/services/services-1.0.xsd');

        $this->addParameters($container);
        $this->addServices($container);

        $this->document->appendChild($container);
        $xml = $this->document->saveXML();
        $this->document = null;

        return $this->container->resolveEnvPlaceholders($xml);
    }

    private function addParameters(\DOMElement $parent)
    {
        $data = $this->container->getParameterBag()->all();
        if (!$data) {
            return;
        }

        if ($this->container->isCompiled()) {
            $data = $this->escape($data);
        }

        $parameters = $this->document->createElement('parameters');
        $parent->appendChild($parameters);
        $this->convertParameters($data, 'parameter', $parameters);
    }

    private function addMethodCalls(array $methodcalls, \DOMElement $parent)
    {
        foreach ($methodcalls as $methodcall) {
            $call = $this->document->createElement('call');
            $call->setAttribute('method', $methodcall[0]);
            if (\count($methodcall[1])) {
                $this->convertParameters($methodcall[1], 'argument', $call);
            }
            if ($methodcall[2] ?? false) {
                $call->setAttribute('returns-clone', 'true');
            }
            $parent->appendChild($call);
        }
    }

    private function addService(Definition $definition, ?string $id, \DOMElement $parent)
    {
        $service = $this->document->createElement('service');
        if (null !== $id) {
            $service->setAttribute('id', $id);
        }
        if ($class = $definition->getClass()) {
            if ('\\' === substr($class, 0, 1)) {
                $class = substr($class, 1);
            }

            $service->setAttribute('class', $class);
        }
        if (!$definition->isShared()) {
            $service->setAttribute('shared', 'false');
        }
        if (!$definition->isPrivate()) {
            $service->setAttribute('public', $definition->isPublic() ? 'true' : 'false');
        }
        if ($definition->isSynthetic()) {
            $service->setAttribute('synthetic', 'true');
        }
        if ($definition->isLazy()) {
            $service->setAttribute('lazy', 'true');
        }
        if (null !== $decoratedService = $definition->getDecoratedService()) {
            list($decorated, $renamedId, $priority) = $decoratedService;
            $service->setAttribute('decorates', $decorated);

            $decorationOnInvalid = $decoratedService[3] ?? ContainerInterface::EXCEPTION_ON_INVALID_REFERENCE;
            if (\in_array($decorationOnInvalid, [ContainerInterface::IGNORE_ON_INVALID_REFERENCE, ContainerInterface::NULL_ON_INVALID_REFERENCE], true)) {
                $invalidBehavior = ContainerInterface::NULL_ON_INVALID_REFERENCE === $decorationOnInvalid ? 'null' : 'ignore';
                $service->setAttribute('decoration-on-invalid', $invalidBehavior);
            }
            if (null !== $renamedId) {
                $service->setAttribute('decoration-inner-name', $renamedId);
            }
            if (0 !== $priority) {
                $service->setAttribute('decoration-priority', $priority);
            }
        }

        foreach ($definition->getTags() as $name => $tags) {
            foreach ($tags as $attributes) {
                $tag = $this->document->createElement('tag');
                if (!\array_key_exists('name', $attributes)) {
                    $tag->setAttribute('name', $name);
                } else {
                    $tag->appendChild($this->document->createTextNode($name));
                }
                foreach ($attributes as $key => $value) {
                    $tag->setAttribute($key, $value);
                }
                $service->appendChild($tag);
            }
        }

        if ($definition->getFile()) {
            $file = $this->document->createElement('file');
            $file->appendChild($this->document->createTextNode($definition->getFile()));
            $service->appendChild($file);
        }

        if ($parameters = $definition->getArguments()) {
            $this->convertParameters($parameters, 'argument', $service);
        }

        if ($parameters = $definition->getProperties()) {
            $this->convertParameters($parameters, 'property', $service, 'name');
        }

        $this->addMethodCalls($definition->getMethodCalls(), $service);

        if ($callable = $definition->getFactory()) {
            $factory = $this->document->createElement('factory');

            if (\is_array($callable) && $callable[0] instanceof Definition) {
                $this->addService($callable[0], null, $factory);
                $factory->setAttribute('method', $callable[1]);
            } elseif (\is_array($callable)) {
                if (null !== $callable[0]) {
                    $factory->setAttribute($callable[0] instanceof Reference ? 'service' : 'class', $callable[0]);
                }
                $factory->setAttribute('method', $callable[1]);
            } else {
                $factory->setAttribute('function', $callable);
            }
            $service->appendChild($factory);
        }

        if ($definition->isDeprecated()) {
            $deprecation = $definition->getDeprecation('%service_id%');
            $deprecated = $this->document->createElement('deprecated');
            $deprecated->appendChild($this->document->createTextNode($definition->getDeprecation('%service_id%')['message']));
            $deprecated->setAttribute('package', $deprecation['package']);
            $deprecated->setAttribute('version', $deprecation['version']);

            $service->appendChild($deprecated);
        }

        if ($definition->isAutowired()) {
            $service->setAttribute('autowire', 'true');
        }

        if ($definition->isAutoconfigured()) {
            $service->setAttribute('autoconfigure', 'true');
        }

        if ($definition->isAbstract()) {
            $service->setAttribute('abstract', 'true');
        }

        if ($callable = $definition->getConfigurator()) {
            $configurator = $this->document->createElement('configurator');

            if (\is_array($callable) && $callable[0] instanceof Definition) {
                $this->addService($callable[0], null, $configurator);
                $configurator->setAttribute('method', $callable[1]);
            } elseif (\is_array($callable)) {
                $configurator->setAttribute($callable[0] instanceof Reference ? 'service' : 'class', $callable[0]);
                $configurator->setAttribute('method', $callable[1]);
            } else {
                $configurator->setAttribute('function', $callable);
            }
            $service->appendChild($configurator);
        }

        $parent->appendChild($service);
    }

    private function addServiceAlias(string $alias, Alias $id, \DOMElement $parent)
    {
        $service = $this->document->createElement('service');
        $service->setAttribute('id', $alias);
        $service->setAttribute('alias', $id);
        if (!$id->isPrivate()) {
            $service->setAttribute('public', $id->isPublic() ? 'true' : 'false');
        }

        if ($id->isDeprecated()) {
            $deprecation = $id->getDeprecation('%alias_id%');
            $deprecated = $this->document->createElement('deprecated');
            $deprecated->appendChild($this->document->createTextNode($deprecation['message']));
            $deprecated->setAttribute('package', $deprecation['package']);
            $deprecated->setAttribute('version', $deprecation['version']);

            $service->appendChild($deprecated);
        }

        $parent->appendChild($service);
    }

    private function addServices(\DOMElement $parent)
    {
        $definitions = $this->container->getDefinitions();
        if (!$definitions) {
            return;
        }

        $services = $this->document->createElement('services');
        foreach ($definitions as $id => $definition) {
            $this->addService($definition, $id, $services);
        }

        $aliases = $this->container->getAliases();
        foreach ($aliases as $alias => $id) {
            while (isset($aliases[(string) $id])) {
                $id = $aliases[(string) $id];
            }
            $this->addServiceAlias($alias, $id, $services);
        }
        $parent->appendChild($services);
    }

    private function convertParameters(array $parameters, string $type, \DOMElement $parent, string $keyAttribute = 'key')
    {
        $withKeys = array_keys($parameters) !== range(0, \count($parameters) - 1);
        foreach ($parameters as $key => $value) {
            $element = $this->document->createElement($type);
            if ($withKeys) {
                $element->setAttribute($keyAttribute, $key);
            }

            if ($value instanceof ServiceClosureArgument) {
                $value = $value->getValues()[0];
            }
            if (\is_array($tag = $value)) {
                $element->setAttribute('type', 'collection');
                $this->convertParameters($value, $type, $element, 'key');
            } elseif ($value instanceof TaggedIteratorArgument || ($value instanceof ServiceLocatorArgument && $tag = $value->getTaggedIteratorArgument())) {
                $element->setAttribute('type', $value instanceof TaggedIteratorArgument ? 'tagged_iterator' : 'tagged_locator');
                $element->setAttribute('tag', $tag->getTag());

                if (null !== $tag->getIndexAttribute()) {
                    $element->setAttribute('index-by', $tag->getIndexAttribute());

                    if (null !== $tag->getDefaultIndexMethod()) {
                        $element->setAttribute('default-index-method', $tag->getDefaultIndexMethod());
                    }
                    if (null !== $tag->getDefaultPriorityMethod()) {
                        $element->setAttribute('default-priority-method', $tag->getDefaultPriorityMethod());
                    }
                }
            } elseif ($value instanceof IteratorArgument) {
                $element->setAttribute('type', 'iterator');
                $this->convertParameters($value->getValues(), $type, $element, 'key');
            } elseif ($value instanceof ServiceLocatorArgument) {
                $element->setAttribute('type', 'service_locator');
                $this->convertParameters($value->getValues(), $type, $element, 'key');
            } elseif ($value instanceof Reference) {
                $element->setAttribute('type', 'service');
                $element->setAttribute('id', (string) $value);
                $behavior = $value->getInvalidBehavior();
                if (ContainerInterface::NULL_ON_INVALID_REFERENCE == $behavior) {
                    $element->setAttribute('on-invalid', 'null');
                } elseif (ContainerInterface::IGNORE_ON_INVALID_REFERENCE == $behavior) {
                    $element->setAttribute('on-invalid', 'ignore');
                } elseif (ContainerInterface::IGNORE_ON_UNINITIALIZED_REFERENCE == $behavior) {
                    $element->setAttribute('on-invalid', 'ignore_uninitialized');
                }
            } elseif ($value instanceof Definition) {
                $element->setAttribute('type', 'service');
                $this->addService($value, null, $element);
            } elseif ($value instanceof Expression) {
                $element->setAttribute('type', 'expression');
                $text = $this->document->createTextNode(self::phpToXml((string) $value));
                $element->appendChild($text);
            } elseif (\is_string($value) && !preg_match('/^[^\x00-\x08\x0B\x0E-\x1A\x1C-\x1F\x7F]*+$/u', $value)) {
                $element->setAttribute('type', 'binary');
                $text = $this->document->createTextNode(self::phpToXml(base64_encode($value)));
                $element->appendChild($text);
            } elseif ($value instanceof AbstractArgument) {
                $element->setAttribute('type', 'abstract');
                $text = $this->document->createTextNode(self::phpToXml($value->getText()));
                $element->appendChild($text);
            } else {
                if (\in_array($value, ['null', 'true', 'false'], true)) {
                    $element->setAttribute('type', 'string');
                }

                if (\is_string($value) && (is_numeric($value) || preg_match('/^0b[01]*$/', $value) || preg_match('/^0x[0-9a-f]++$/i', $value))) {
                    $element->setAttribute('type', 'string');
                }

                $text = $this->document->createTextNode(self::phpToXml($value));
                $element->appendChild($text);
            }
            $parent->appendChild($element);
        }
    }

    /**
     * Escapes arguments.
     */
    private function escape(array $arguments): array
    {
        $args = [];
        foreach ($arguments as $k => $v) {
            if (\is_array($v)) {
                $args[$k] = $this->escape($v);
            } elseif (\is_string($v)) {
                $args[$k] = str_replace('%', '%%', $v);
            } else {
                $args[$k] = $v;
            }
        }

        return $args;
    }

    /**
     * Converts php types to xml types.
     *
     * @param mixed $value Value to convert
     *
     * @throws RuntimeException When trying to dump object or resource
     */
    public static function phpToXml($value): string
    {
        switch (true) {
            case null === $value:
                return 'null';
            case true === $value:
                return 'true';
            case false === $value:
                return 'false';
            case $value instanceof Parameter:
                return '%'.$value.'%';
            case \is_object($value) || \is_resource($value):
                throw new RuntimeException('Unable to dump a service container if a parameter is an object or a resource.');
            default:
                return (string) $value;
        }
    }
}
PKϤ$Z��m|�$�$.dependency-injection/Dumper/GraphvizDumper.phpnu�[���<?php

/*
 * This file is part of the Symfony package.
 *
 * (c) Fabien Potencier <fabien@symfony.com>
 *
 * For the full copyright and license information, please view the LICENSE
 * file that was distributed with this source code.
 */

namespace Symfony\Component\DependencyInjection\Dumper;

use Symfony\Component\DependencyInjection\Argument\ArgumentInterface;
use Symfony\Component\DependencyInjection\ContainerBuilder;
use Symfony\Component\DependencyInjection\Definition;
use Symfony\Component\DependencyInjection\Exception\ParameterNotFoundException;
use Symfony\Component\DependencyInjection\Parameter;
use Symfony\Component\DependencyInjection\ParameterBag\ParameterBag;
use Symfony\Component\DependencyInjection\Reference;

/**
 * GraphvizDumper dumps a service container as a graphviz file.
 *
 * You can convert the generated dot file with the dot utility (http://www.graphviz.org/):
 *
 *   dot -Tpng container.dot > foo.png
 *
 * @author Fabien Potencier <fabien@symfony.com>
 */
class GraphvizDumper extends Dumper
{
    private $nodes;
    private $edges;
    // All values should be strings
    private $options = [
            'graph' => ['ratio' => 'compress'],
            'node' => ['fontsize' => '11', 'fontname' => 'Arial', 'shape' => 'record'],
            'edge' => ['fontsize' => '9', 'fontname' => 'Arial', 'color' => 'grey', 'arrowhead' => 'open', 'arrowsize' => '0.5'],
            'node.instance' => ['fillcolor' => '#9999ff', 'style' => 'filled'],
            'node.definition' => ['fillcolor' => '#eeeeee'],
            'node.missing' => ['fillcolor' => '#ff9999', 'style' => 'filled'],
        ];

    /**
     * Dumps the service container as a graphviz graph.
     *
     * Available options:
     *
     *  * graph: The default options for the whole graph
     *  * node: The default options for nodes
     *  * edge: The default options for edges
     *  * node.instance: The default options for services that are defined directly by object instances
     *  * node.definition: The default options for services that are defined via service definition instances
     *  * node.missing: The default options for missing services
     *
     * @return string The dot representation of the service container
     */
    public function dump(array $options = [])
    {
        foreach (['graph', 'node', 'edge', 'node.instance', 'node.definition', 'node.missing'] as $key) {
            if (isset($options[$key])) {
                $this->options[$key] = array_merge($this->options[$key], $options[$key]);
            }
        }

        $this->nodes = $this->findNodes();

        $this->edges = [];
        foreach ($this->container->getDefinitions() as $id => $definition) {
            $this->edges[$id] = array_merge(
                $this->findEdges($id, $definition->getArguments(), true, ''),
                $this->findEdges($id, $definition->getProperties(), false, '')
            );

            foreach ($definition->getMethodCalls() as $call) {
                $this->edges[$id] = array_merge(
                    $this->edges[$id],
                    $this->findEdges($id, $call[1], false, $call[0].'()')
                );
            }
        }

        return $this->container->resolveEnvPlaceholders($this->startDot().$this->addNodes().$this->addEdges().$this->endDot(), '__ENV_%s__');
    }

    private function addNodes(): string
    {
        $code = '';
        foreach ($this->nodes as $id => $node) {
            $aliases = $this->getAliases($id);

            $code .= sprintf("  node_%s [label=\"%s\\n%s\\n\", shape=%s%s];\n", $this->dotize($id), $id.($aliases ? ' ('.implode(', ', $aliases).')' : ''), $node['class'], $this->options['node']['shape'], $this->addAttributes($node['attributes']));
        }

        return $code;
    }

    private function addEdges(): string
    {
        $code = '';
        foreach ($this->edges as $id => $edges) {
            foreach ($edges as $edge) {
                $code .= sprintf("  node_%s -> node_%s [label=\"%s\" style=\"%s\"%s];\n", $this->dotize($id), $this->dotize($edge['to']), $edge['name'], $edge['required'] ? 'filled' : 'dashed', $edge['lazy'] ? ' color="#9999ff"' : '');
            }
        }

        return $code;
    }

    /**
     * Finds all edges belonging to a specific service id.
     */
    private function findEdges(string $id, array $arguments, bool $required, string $name, bool $lazy = false): array
    {
        $edges = [];
        foreach ($arguments as $argument) {
            if ($argument instanceof Parameter) {
                $argument = $this->container->hasParameter($argument) ? $this->container->getParameter($argument) : null;
            } elseif (\is_string($argument) && preg_match('/^%([^%]+)%$/', $argument, $match)) {
                $argument = $this->container->hasParameter($match[1]) ? $this->container->getParameter($match[1]) : null;
            }

            if ($argument instanceof Reference) {
                $lazyEdge = $lazy;

                if (!$this->container->has((string) $argument)) {
                    $this->nodes[(string) $argument] = ['name' => $name, 'required' => $required, 'class' => '', 'attributes' => $this->options['node.missing']];
                } elseif ('service_container' !== (string) $argument) {
                    $lazyEdge = $lazy || $this->container->getDefinition((string) $argument)->isLazy();
                }

                $edges[] = ['name' => $name, 'required' => $required, 'to' => $argument, 'lazy' => $lazyEdge];
            } elseif ($argument instanceof ArgumentInterface) {
                $edges = array_merge($edges, $this->findEdges($id, $argument->getValues(), $required, $name, true));
            } elseif ($argument instanceof Definition) {
                $edges = array_merge($edges,
                    $this->findEdges($id, $argument->getArguments(), $required, ''),
                    $this->findEdges($id, $argument->getProperties(), false, '')
                );
                foreach ($argument->getMethodCalls() as $call) {
                    $edges = array_merge($edges, $this->findEdges($id, $call[1], false, $call[0].'()'));
                }
            } elseif (\is_array($argument)) {
                $edges = array_merge($edges, $this->findEdges($id, $argument, $required, $name, $lazy));
            }
        }

        return $edges;
    }

    private function findNodes(): array
    {
        $nodes = [];

        $container = $this->cloneContainer();

        foreach ($container->getDefinitions() as $id => $definition) {
            $class = $definition->getClass();

            if ('\\' === substr($class, 0, 1)) {
                $class = substr($class, 1);
            }

            try {
                $class = $this->container->getParameterBag()->resolveValue($class);
            } catch (ParameterNotFoundException $e) {
            }

            $nodes[$id] = ['class' => str_replace('\\', '\\\\', $class), 'attributes' => array_merge($this->options['node.definition'], ['style' => $definition->isShared() ? 'filled' : 'dotted'])];
            $container->setDefinition($id, new Definition('stdClass'));
        }

        foreach ($container->getServiceIds() as $id) {
            if (\array_key_exists($id, $container->getAliases())) {
                continue;
            }

            if (!$container->hasDefinition($id)) {
                $nodes[$id] = ['class' => str_replace('\\', '\\\\', \get_class($container->get($id))), 'attributes' => $this->options['node.instance']];
            }
        }

        return $nodes;
    }

    private function cloneContainer(): ContainerBuilder
    {
        $parameterBag = new ParameterBag($this->container->getParameterBag()->all());

        $container = new ContainerBuilder($parameterBag);
        $container->setDefinitions($this->container->getDefinitions());
        $container->setAliases($this->container->getAliases());
        $container->setResources($this->container->getResources());
        foreach ($this->container->getExtensions() as $extension) {
            $container->registerExtension($extension);
        }

        return $container;
    }

    private function startDot(): string
    {
        return sprintf("digraph sc {\n  %s\n  node [%s];\n  edge [%s];\n\n",
            $this->addOptions($this->options['graph']),
            $this->addOptions($this->options['node']),
            $this->addOptions($this->options['edge'])
        );
    }

    private function endDot(): string
    {
        return "}\n";
    }

    private function addAttributes(array $attributes): string
    {
        $code = [];
        foreach ($attributes as $k => $v) {
            $code[] = sprintf('%s="%s"', $k, $v);
        }

        return $code ? ', '.implode(', ', $code) : '';
    }

    private function addOptions(array $options): string
    {
        $code = [];
        foreach ($options as $k => $v) {
            $code[] = sprintf('%s="%s"', $k, $v);
        }

        return implode(' ', $code);
    }

    private function dotize(string $id): string
    {
        return preg_replace('/\W/i', '_', $id);
    }

    private function getAliases(string $id): array
    {
        $aliases = [];
        foreach ($this->container->getAliases() as $alias => $origin) {
            if ($id == $origin) {
                $aliases[] = $alias;
            }
        }

        return $aliases;
    }
}
PKϤ$Z$��[[)dependency-injection/Dumper/PhpDumper.phpnu�[���<?php

/*
 * This file is part of the Symfony package.
 *
 * (c) Fabien Potencier <fabien@symfony.com>
 *
 * For the full copyright and license information, please view the LICENSE
 * file that was distributed with this source code.
 */

namespace Symfony\Component\DependencyInjection\Dumper;

use Composer\Autoload\ClassLoader;
use Symfony\Component\Debug\DebugClassLoader as LegacyDebugClassLoader;
use Symfony\Component\DependencyInjection\Argument\AbstractArgument;
use Symfony\Component\DependencyInjection\Argument\ArgumentInterface;
use Symfony\Component\DependencyInjection\Argument\IteratorArgument;
use Symfony\Component\DependencyInjection\Argument\ServiceClosureArgument;
use Symfony\Component\DependencyInjection\Argument\ServiceLocator;
use Symfony\Component\DependencyInjection\Argument\ServiceLocatorArgument;
use Symfony\Component\DependencyInjection\Compiler\AnalyzeServiceReferencesPass;
use Symfony\Component\DependencyInjection\Compiler\CheckCircularReferencesPass;
use Symfony\Component\DependencyInjection\Compiler\ServiceReferenceGraphEdge;
use Symfony\Component\DependencyInjection\Compiler\ServiceReferenceGraphNode;
use Symfony\Component\DependencyInjection\Container;
use Symfony\Component\DependencyInjection\ContainerBuilder;
use Symfony\Component\DependencyInjection\ContainerInterface;
use Symfony\Component\DependencyInjection\Definition;
use Symfony\Component\DependencyInjection\Exception\EnvParameterException;
use Symfony\Component\DependencyInjection\Exception\InvalidArgumentException;
use Symfony\Component\DependencyInjection\Exception\LogicException;
use Symfony\Component\DependencyInjection\Exception\RuntimeException;
use Symfony\Component\DependencyInjection\Exception\ServiceCircularReferenceException;
use Symfony\Component\DependencyInjection\ExpressionLanguage;
use Symfony\Component\DependencyInjection\LazyProxy\PhpDumper\DumperInterface as ProxyDumper;
use Symfony\Component\DependencyInjection\LazyProxy\PhpDumper\NullDumper;
use Symfony\Component\DependencyInjection\Loader\FileLoader;
use Symfony\Component\DependencyInjection\Parameter;
use Symfony\Component\DependencyInjection\Reference;
use Symfony\Component\DependencyInjection\ServiceLocator as BaseServiceLocator;
use Symfony\Component\DependencyInjection\TypedReference;
use Symfony\Component\DependencyInjection\Variable;
use Symfony\Component\ErrorHandler\DebugClassLoader;
use Symfony\Component\ExpressionLanguage\Expression;
use Symfony\Component\HttpKernel\Kernel;

/**
 * PhpDumper dumps a service container as a PHP class.
 *
 * @author Fabien Potencier <fabien@symfony.com>
 * @author Johannes M. Schmitt <schmittjoh@gmail.com>
 */
class PhpDumper extends Dumper
{
    /**
     * Characters that might appear in the generated variable name as first character.
     */
    const FIRST_CHARS = 'abcdefghijklmnopqrstuvwxyz';

    /**
     * Characters that might appear in the generated variable name as any but the first character.
     */
    const NON_FIRST_CHARS = 'abcdefghijklmnopqrstuvwxyz0123456789_';

    private $definitionVariables;
    private $referenceVariables;
    private $variableCount;
    private $inlinedDefinitions;
    private $serviceCalls;
    private $reservedVariables = ['instance', 'class', 'this', 'container'];
    private $expressionLanguage;
    private $targetDirRegex;
    private $targetDirMaxMatches;
    private $docStar;
    private $serviceIdToMethodNameMap;
    private $usedMethodNames;
    private $namespace;
    private $asFiles;
    private $hotPathTag;
    private $preloadTags;
    private $inlineFactories;
    private $inlineRequires;
    private $inlinedRequires = [];
    private $circularReferences = [];
    private $singleUsePrivateIds = [];
    private $preload = [];
    private $addThrow = false;
    private $addGetService = false;
    private $locatedIds = [];
    private $serviceLocatorTag;
    private $exportedVariables = [];
    private $baseClass;

    /**
     * @var ProxyDumper
     */
    private $proxyDumper;

    /**
     * {@inheritdoc}
     */
    public function __construct(ContainerBuilder $container)
    {
        if (!$container->isCompiled()) {
            throw new LogicException('Cannot dump an uncompiled container.');
        }

        parent::__construct($container);
    }

    /**
     * Sets the dumper to be used when dumping proxies in the generated container.
     */
    public function setProxyDumper(ProxyDumper $proxyDumper)
    {
        $this->proxyDumper = $proxyDumper;
    }

    /**
     * Dumps the service container as a PHP class.
     *
     * Available options:
     *
     *  * class:      The class name
     *  * base_class: The base class name
     *  * namespace:  The class namespace
     *  * as_files:   To split the container in several files
     *
     * @return string|array A PHP class representing the service container or an array of PHP files if the "as_files" option is set
     *
     * @throws EnvParameterException When an env var exists but has not been dumped
     */
    public function dump(array $options = [])
    {
        $this->locatedIds = [];
        $this->targetDirRegex = null;
        $this->inlinedRequires = [];
        $this->exportedVariables = [];
        $options = array_merge([
            'class' => 'ProjectServiceContainer',
            'base_class' => 'Container',
            'namespace' => '',
            'as_files' => false,
            'debug' => true,
            'hot_path_tag' => 'container.hot_path',
            'preload_tags' => ['container.preload', 'container.no_preload'],
            'inline_factories_parameter' => 'container.dumper.inline_factories',
            'inline_class_loader_parameter' => 'container.dumper.inline_class_loader',
            'preload_classes' => [],
            'service_locator_tag' => 'container.service_locator',
            'build_time' => time(),
        ], $options);

        $this->addThrow = $this->addGetService = false;
        $this->namespace = $options['namespace'];
        $this->asFiles = $options['as_files'];
        $this->hotPathTag = $options['hot_path_tag'];
        $this->preloadTags = $options['preload_tags'];
        $this->inlineFactories = $this->asFiles && $options['inline_factories_parameter'] && $this->container->hasParameter($options['inline_factories_parameter']) && $this->container->getParameter($options['inline_factories_parameter']);
        $this->inlineRequires = $options['inline_class_loader_parameter'] && ($this->container->hasParameter($options['inline_class_loader_parameter']) ? $this->container->getParameter($options['inline_class_loader_parameter']) : (\PHP_VERSION_ID < 70400 || $options['debug']));
        $this->serviceLocatorTag = $options['service_locator_tag'];

        if (0 !== strpos($baseClass = $options['base_class'], '\\') && 'Container' !== $baseClass) {
            $baseClass = sprintf('%s\%s', $options['namespace'] ? '\\'.$options['namespace'] : '', $baseClass);
            $this->baseClass = $baseClass;
        } elseif ('Container' === $baseClass) {
            $this->baseClass = Container::class;
        } else {
            $this->baseClass = $baseClass;
        }

        $this->initializeMethodNamesMap('Container' === $baseClass ? Container::class : $baseClass);

        if ($this->getProxyDumper() instanceof NullDumper) {
            (new AnalyzeServiceReferencesPass(true, false))->process($this->container);
            try {
                (new CheckCircularReferencesPass())->process($this->container);
            } catch (ServiceCircularReferenceException $e) {
                $path = $e->getPath();
                end($path);
                $path[key($path)] .= '". Try running "composer require symfony/proxy-manager-bridge';

                throw new ServiceCircularReferenceException($e->getServiceId(), $path);
            }
        }

        (new AnalyzeServiceReferencesPass(false, !$this->getProxyDumper() instanceof NullDumper))->process($this->container);
        $checkedNodes = [];
        $this->circularReferences = [];
        $this->singleUsePrivateIds = [];
        foreach ($this->container->getCompiler()->getServiceReferenceGraph()->getNodes() as $id => $node) {
            if (!$node->getValue() instanceof Definition) {
                continue;
            }
            if (!isset($checkedNodes[$id])) {
                $this->analyzeCircularReferences($id, $node->getOutEdges(), $checkedNodes);
            }
            if ($this->isSingleUsePrivateNode($node)) {
                $this->singleUsePrivateIds[$id] = $id;
            }
        }
        $this->container->getCompiler()->getServiceReferenceGraph()->clear();
        $checkedNodes = [];
        $this->singleUsePrivateIds = array_diff_key($this->singleUsePrivateIds, $this->circularReferences);

        $this->docStar = $options['debug'] ? '*' : '';

        if (!empty($options['file']) && is_dir($dir = \dirname($options['file']))) {
            // Build a regexp where the first root dirs are mandatory,
            // but every other sub-dir is optional up to the full path in $dir
            // Mandate at least 1 root dir and not more than 5 optional dirs.

            $dir = explode(\DIRECTORY_SEPARATOR, realpath($dir));
            $i = \count($dir);

            if (2 + (int) ('\\' === \DIRECTORY_SEPARATOR) <= $i) {
                $regex = '';
                $lastOptionalDir = $i > 8 ? $i - 5 : (2 + (int) ('\\' === \DIRECTORY_SEPARATOR));
                $this->targetDirMaxMatches = $i - $lastOptionalDir;

                while (--$i >= $lastOptionalDir) {
                    $regex = sprintf('(%s%s)?', preg_quote(\DIRECTORY_SEPARATOR.$dir[$i], '#'), $regex);
                }

                do {
                    $regex = preg_quote(\DIRECTORY_SEPARATOR.$dir[$i], '#').$regex;
                } while (0 < --$i);

                $this->targetDirRegex = '#(^|file://|[:;, \|\r\n])'.preg_quote($dir[0], '#').$regex.'#';
            }
        }

        $proxyClasses = $this->inlineFactories ? $this->generateProxyClasses() : null;

        if ($options['preload_classes']) {
            $this->preload = array_combine($options['preload_classes'], $options['preload_classes']);
        }

        $code =
            $this->startClass($options['class'], $baseClass).
            $this->addServices($services).
            $this->addDeprecatedAliases().
            $this->addDefaultParametersMethod()
        ;

        $proxyClasses = $proxyClasses ?? $this->generateProxyClasses();

        if ($this->addGetService) {
            $code = preg_replace(
                "/(\r?\n\r?\n    public function __construct.+?\\{\r?\n)/s",
                "\n    protected \$getService;$1        \$this->getService = \\Closure::fromCallable([\$this, 'getService']);\n",
                $code,
                1
            );
        }

        if ($this->asFiles) {
            $fileTemplate = <<<EOF
<?php

use Symfony\Component\DependencyInjection\Argument\RewindableGenerator;
use Symfony\Component\DependencyInjection\Exception\RuntimeException;

/*{$this->docStar}
 * @internal This class has been auto-generated by the Symfony Dependency Injection Component.
 */
class %s extends {$options['class']}
{%s}

EOF;
            $files = [];
            $preloadedFiles = [];
            $ids = $this->container->getRemovedIds();
            foreach ($this->container->getDefinitions() as $id => $definition) {
                if (!$definition->isPublic()) {
                    $ids[$id] = true;
                }
            }
            if ($ids = array_keys($ids)) {
                sort($ids);
                $c = "<?php\n\nreturn [\n";
                foreach ($ids as $id) {
                    $c .= '    '.$this->doExport($id)." => true,\n";
                }
                $files['removed-ids.php'] = $c."];\n";
            }

            if (!$this->inlineFactories) {
                foreach ($this->generateServiceFiles($services) as $file => [$c, $preload]) {
                    $files[$file] = sprintf($fileTemplate, substr($file, 0, -4), $c);

                    if ($preload) {
                        $preloadedFiles[$file] = $file;
                    }
                }
                foreach ($proxyClasses as $file => $c) {
                    $files[$file] = "<?php\n".$c;
                    $preloadedFiles[$file] = $file;
                }
            }

            $code .= $this->endClass();

            if ($this->inlineFactories) {
                foreach ($proxyClasses as $c) {
                    $code .= $c;
                }
            }

            $files[$options['class'].'.php'] = $code;
            $preloadedFiles[$options['class'].'.php'] = $options['class'].'.php';
            $hash = ucfirst(strtr(ContainerBuilder::hash($files), '._', 'xx'));
            $code = [];

            foreach ($files as $file => $c) {
                $code["Container{$hash}/{$file}"] = substr_replace($c, "<?php\n\nnamespace Container{$hash};\n", 0, 6);

                if (isset($preloadedFiles[$file])) {
                    $preloadedFiles[$file] = "Container{$hash}/{$file}";
                }
            }
            $namespaceLine = $this->namespace ? "\nnamespace {$this->namespace};\n" : '';
            $time = $options['build_time'];
            $id = hash('crc32', $hash.$time);
            $this->asFiles = false;

            if ($this->preload && null !== $autoloadFile = $this->getAutoloadFile()) {
                $autoloadFile = trim($this->export($autoloadFile), '()\\');

                $preloadedFiles = array_reverse($preloadedFiles);
                $preloadedFiles = implode("';\nrequire __DIR__.'/", $preloadedFiles);

                $code[$options['class'].'.preload.php'] = <<<EOF
<?php

// This file has been auto-generated by the Symfony Dependency Injection Component
// You can reference it in the "opcache.preload" php.ini setting on PHP >= 7.4 when preloading is desired

use Symfony\Component\DependencyInjection\Dumper\Preloader;

if (in_array(PHP_SAPI, ['cli', 'phpdbg'], true)) {
    return;
}

require $autoloadFile;
require __DIR__.'/$preloadedFiles';

\$classes = [];

EOF;

                foreach ($this->preload as $class) {
                    if (!$class || false !== strpos($class, '$') || \in_array($class, ['int', 'float', 'string', 'bool', 'resource', 'object', 'array', 'null', 'callable', 'iterable', 'mixed', 'void'], true)) {
                        continue;
                    }
                    if (!(class_exists($class, false) || interface_exists($class, false) || trait_exists($class, false)) || (new \ReflectionClass($class))->isUserDefined()) {
                        $code[$options['class'].'.preload.php'] .= sprintf("\$classes[] = '%s';\n", $class);
                    }
                }

                $code[$options['class'].'.preload.php'] .= <<<'EOF'

Preloader::preload($classes);

EOF;
            }

            $code[$options['class'].'.php'] = <<<EOF
<?php
{$namespaceLine}
// This file has been auto-generated by the Symfony Dependency Injection Component for internal use.

if (\\class_exists(\\Container{$hash}\\{$options['class']}::class, false)) {
    // no-op
} elseif (!include __DIR__.'/Container{$hash}/{$options['class']}.php') {
    touch(__DIR__.'/Container{$hash}.legacy');

    return;
}

if (!\\class_exists({$options['class']}::class, false)) {
    \\class_alias(\\Container{$hash}\\{$options['class']}::class, {$options['class']}::class, false);
}

return new \\Container{$hash}\\{$options['class']}([
    'container.build_hash' => '$hash',
    'container.build_id' => '$id',
    'container.build_time' => $time,
], __DIR__.\\DIRECTORY_SEPARATOR.'Container{$hash}');

EOF;
        } else {
            $code .= $this->endClass();
            foreach ($proxyClasses as $c) {
                $code .= $c;
            }
        }

        $this->targetDirRegex = null;
        $this->inlinedRequires = [];
        $this->circularReferences = [];
        $this->locatedIds = [];
        $this->exportedVariables = [];
        $this->preload = [];

        $unusedEnvs = [];
        foreach ($this->container->getEnvCounters() as $env => $use) {
            if (!$use) {
                $unusedEnvs[] = $env;
            }
        }
        if ($unusedEnvs) {
            throw new EnvParameterException($unusedEnvs, null, 'Environment variables "%s" are never used. Please, check your container\'s configuration.');
        }

        return $code;
    }

    /**
     * Retrieves the currently set proxy dumper or instantiates one.
     */
    private function getProxyDumper(): ProxyDumper
    {
        if (!$this->proxyDumper) {
            $this->proxyDumper = new NullDumper();
        }

        return $this->proxyDumper;
    }

    /**
     * @param ServiceReferenceGraphEdge[] $edges
     */
    private function analyzeCircularReferences(string $sourceId, array $edges, array &$checkedNodes, array &$currentPath = [], bool $byConstructor = true)
    {
        $checkedNodes[$sourceId] = true;
        $currentPath[$sourceId] = $byConstructor;

        foreach ($edges as $edge) {
            $node = $edge->getDestNode();
            $id = $node->getId();

            if (!$node->getValue() instanceof Definition || $sourceId === $id || $edge->isLazy() || $edge->isWeak()) {
                // no-op
            } elseif (isset($currentPath[$id])) {
                $this->addCircularReferences($id, $currentPath, $edge->isReferencedByConstructor());
            } elseif (!isset($checkedNodes[$id])) {
                $this->analyzeCircularReferences($id, $node->getOutEdges(), $checkedNodes, $currentPath, $edge->isReferencedByConstructor());
            } elseif (isset($this->circularReferences[$id])) {
                $this->connectCircularReferences($id, $currentPath, $edge->isReferencedByConstructor());
            }
        }
        unset($currentPath[$sourceId]);
    }

    private function connectCircularReferences(string $sourceId, array &$currentPath, bool $byConstructor, array &$subPath = [])
    {
        $currentPath[$sourceId] = $subPath[$sourceId] = $byConstructor;

        foreach ($this->circularReferences[$sourceId] as $id => $byConstructor) {
            if (isset($currentPath[$id])) {
                $this->addCircularReferences($id, $currentPath, $byConstructor);
            } elseif (!isset($subPath[$id]) && isset($this->circularReferences[$id])) {
                $this->connectCircularReferences($id, $currentPath, $byConstructor, $subPath);
            }
        }
        unset($currentPath[$sourceId], $subPath[$sourceId]);
    }

    private function addCircularReferences(string $id, array $currentPath, bool $byConstructor)
    {
        $currentPath[$id] = $byConstructor;
        $circularRefs = [];

        foreach (array_reverse($currentPath) as $parentId => $v) {
            $byConstructor = $byConstructor && $v;
            $circularRefs[] = $parentId;

            if ($parentId === $id) {
                break;
            }
        }

        $currentId = $id;
        foreach ($circularRefs as $parentId) {
            if (empty($this->circularReferences[$parentId][$currentId])) {
                $this->circularReferences[$parentId][$currentId] = $byConstructor;
            }

            $currentId = $parentId;
        }
    }

    private function collectLineage(string $class, array &$lineage)
    {
        if (isset($lineage[$class])) {
            return;
        }
        if (!$r = $this->container->getReflectionClass($class, false)) {
            return;
        }
        if (is_a($class, $this->baseClass, true)) {
            return;
        }
        $file = $r->getFileName();
        if (!$file || $this->doExport($file) === $exportedFile = $this->export($file)) {
            return;
        }

        $lineage[$class] = substr($exportedFile, 1, -1);

        if ($parent = $r->getParentClass()) {
            $this->collectLineage($parent->name, $lineage);
        }

        foreach ($r->getInterfaces() as $parent) {
            $this->collectLineage($parent->name, $lineage);
        }

        foreach ($r->getTraits() as $parent) {
            $this->collectLineage($parent->name, $lineage);
        }

        unset($lineage[$class]);
        $lineage[$class] = substr($exportedFile, 1, -1);
    }

    private function generateProxyClasses(): array
    {
        $proxyClasses = [];
        $alreadyGenerated = [];
        $definitions = $this->container->getDefinitions();
        $strip = '' === $this->docStar && method_exists('Symfony\Component\HttpKernel\Kernel', 'stripComments');
        $proxyDumper = $this->getProxyDumper();
        ksort($definitions);
        foreach ($definitions as $definition) {
            if (!$proxyDumper->isProxyCandidate($definition)) {
                continue;
            }
            if (isset($alreadyGenerated[$class = $definition->getClass()])) {
                continue;
            }
            $alreadyGenerated[$class] = true;
            // register class' reflector for resource tracking
            $this->container->getReflectionClass($class);
            if ("\n" === $proxyCode = "\n".$proxyDumper->getProxyCode($definition)) {
                continue;
            }

            if ($this->inlineRequires) {
                $lineage = [];
                $this->collectLineage($class, $lineage);

                $code = '';
                foreach (array_diff_key(array_flip($lineage), $this->inlinedRequires) as $file => $class) {
                    if ($this->inlineFactories) {
                        $this->inlinedRequires[$file] = true;
                    }
                    $code .= sprintf("include_once %s;\n", $file);
                }

                $proxyCode = $code.$proxyCode;
            }

            if ($strip) {
                $proxyCode = "<?php\n".$proxyCode;
                $proxyCode = substr(Kernel::stripComments($proxyCode), 5);
            }

            $proxyClass = explode(' ', $this->inlineRequires ? substr($proxyCode, \strlen($code)) : $proxyCode, 3)[1];

            if ($this->asFiles || $this->namespace) {
                $proxyCode .= "\nif (!\\class_exists('$proxyClass', false)) {\n    \\class_alias(__NAMESPACE__.'\\\\$proxyClass', '$proxyClass', false);\n}\n";
            }

            $proxyClasses[$proxyClass.'.php'] = $proxyCode;
        }

        return $proxyClasses;
    }

    private function addServiceInclude(string $cId, Definition $definition): string
    {
        $code = '';

        if ($this->inlineRequires && (!$this->isHotPath($definition) || $this->getProxyDumper()->isProxyCandidate($definition))) {
            $lineage = [];
            foreach ($this->inlinedDefinitions as $def) {
                if (!$def->isDeprecated()) {
                    foreach ($this->getClasses($def, $cId) as $class) {
                        $this->collectLineage($class, $lineage);
                    }
                }
            }

            foreach ($this->serviceCalls as $id => list($callCount, $behavior)) {
                if ('service_container' !== $id && $id !== $cId
                    && ContainerInterface::IGNORE_ON_UNINITIALIZED_REFERENCE !== $behavior
                    && $this->container->has($id)
                    && $this->isTrivialInstance($def = $this->container->findDefinition($id))
                ) {
                    foreach ($this->getClasses($def, $cId) as $class) {
                        $this->collectLineage($class, $lineage);
                    }
                }
            }

            foreach (array_diff_key(array_flip($lineage), $this->inlinedRequires) as $file => $class) {
                $code .= sprintf("        include_once %s;\n", $file);
            }
        }

        foreach ($this->inlinedDefinitions as $def) {
            if ($file = $def->getFile()) {
                $file = $this->dumpValue($file);
                $file = '(' === $file[0] ? substr($file, 1, -1) : $file;
                $code .= sprintf("        include_once %s;\n", $file);
            }
        }

        if ('' !== $code) {
            $code .= "\n";
        }

        return $code;
    }

    /**
     * @throws InvalidArgumentException
     * @throws RuntimeException
     */
    private function addServiceInstance(string $id, Definition $definition, bool $isSimpleInstance): string
    {
        $class = $this->dumpValue($definition->getClass());

        if (0 === strpos($class, "'") && false === strpos($class, '$') && !preg_match('/^\'(?:\\\{2})?[a-zA-Z_\x7f-\xff][a-zA-Z0-9_\x7f-\xff]*(?:\\\{2}[a-zA-Z_\x7f-\xff][a-zA-Z0-9_\x7f-\xff]*)*\'$/', $class)) {
            throw new InvalidArgumentException(sprintf('"%s" is not a valid class name for the "%s" service.', $class, $id));
        }

        $isProxyCandidate = $this->getProxyDumper()->isProxyCandidate($definition);
        $instantiation = '';

        $lastWitherIndex = null;
        foreach ($definition->getMethodCalls() as $k => $call) {
            if ($call[2] ?? false) {
                $lastWitherIndex = $k;
            }
        }

        if (!$isProxyCandidate && $definition->isShared() && !isset($this->singleUsePrivateIds[$id]) && null === $lastWitherIndex) {
            $instantiation = sprintf('$this->%s[%s] = %s', $this->container->getDefinition($id)->isPublic() ? 'services' : 'privates', $this->doExport($id), $isSimpleInstance ? '' : '$instance');
        } elseif (!$isSimpleInstance) {
            $instantiation = '$instance';
        }

        $return = '';
        if ($isSimpleInstance) {
            $return = 'return ';
        } else {
            $instantiation .= ' = ';
        }

        return $this->addNewInstance($definition, '        '.$return.$instantiation, $id);
    }

    private function isTrivialInstance(Definition $definition): bool
    {
        if ($definition->hasErrors()) {
            return true;
        }
        if ($definition->isSynthetic() || $definition->getFile() || $definition->getMethodCalls() || $definition->getProperties() || $definition->getConfigurator()) {
            return false;
        }
        if ($definition->isDeprecated() || $definition->isLazy() || $definition->getFactory() || 3 < \count($definition->getArguments())) {
            return false;
        }

        foreach ($definition->getArguments() as $arg) {
            if (!$arg || $arg instanceof Parameter) {
                continue;
            }
            if (\is_array($arg) && 3 >= \count($arg)) {
                foreach ($arg as $k => $v) {
                    if ($this->dumpValue($k) !== $this->dumpValue($k, false)) {
                        return false;
                    }
                    if (!$v || $v instanceof Parameter) {
                        continue;
                    }
                    if ($v instanceof Reference && $this->container->has($id = (string) $v) && $this->container->findDefinition($id)->isSynthetic()) {
                        continue;
                    }
                    if (!is_scalar($v) || $this->dumpValue($v) !== $this->dumpValue($v, false)) {
                        return false;
                    }
                }
            } elseif ($arg instanceof Reference && $this->container->has($id = (string) $arg) && $this->container->findDefinition($id)->isSynthetic()) {
                continue;
            } elseif (!is_scalar($arg) || $this->dumpValue($arg) !== $this->dumpValue($arg, false)) {
                return false;
            }
        }

        return true;
    }

    private function addServiceMethodCalls(Definition $definition, string $variableName, ?string $sharedNonLazyId): string
    {
        $lastWitherIndex = null;
        foreach ($definition->getMethodCalls() as $k => $call) {
            if ($call[2] ?? false) {
                $lastWitherIndex = $k;
            }
        }

        $calls = '';
        foreach ($definition->getMethodCalls() as $k => $call) {
            $arguments = [];
            foreach ($call[1] as $value) {
                $arguments[] = $this->dumpValue($value);
            }

            $witherAssignation = '';

            if ($call[2] ?? false) {
                if (null !== $sharedNonLazyId && $lastWitherIndex === $k) {
                    $witherAssignation = sprintf('$this->%s[\'%s\'] = ', $definition->isPublic() ? 'services' : 'privates', $sharedNonLazyId);
                }
                $witherAssignation .= sprintf('$%s = ', $variableName);
            }

            $calls .= $this->wrapServiceConditionals($call[1], sprintf("        %s\$%s->%s(%s);\n", $witherAssignation, $variableName, $call[0], implode(', ', $arguments)));
        }

        return $calls;
    }

    private function addServiceProperties(Definition $definition, string $variableName = 'instance'): string
    {
        $code = '';
        foreach ($definition->getProperties() as $name => $value) {
            $code .= sprintf("        \$%s->%s = %s;\n", $variableName, $name, $this->dumpValue($value));
        }

        return $code;
    }

    private function addServiceConfigurator(Definition $definition, string $variableName = 'instance'): string
    {
        if (!$callable = $definition->getConfigurator()) {
            return '';
        }

        if (\is_array($callable)) {
            if ($callable[0] instanceof Reference
                || ($callable[0] instanceof Definition && $this->definitionVariables->contains($callable[0]))
            ) {
                return sprintf("        %s->%s(\$%s);\n", $this->dumpValue($callable[0]), $callable[1], $variableName);
            }

            $class = $this->dumpValue($callable[0]);
            // If the class is a string we can optimize away
            if (0 === strpos($class, "'") && false === strpos($class, '$')) {
                return sprintf("        %s::%s(\$%s);\n", $this->dumpLiteralClass($class), $callable[1], $variableName);
            }

            if (0 === strpos($class, 'new ')) {
                return sprintf("        (%s)->%s(\$%s);\n", $this->dumpValue($callable[0]), $callable[1], $variableName);
            }

            return sprintf("        [%s, '%s'](\$%s);\n", $this->dumpValue($callable[0]), $callable[1], $variableName);
        }

        return sprintf("        %s(\$%s);\n", $callable, $variableName);
    }

    private function addService(string $id, Definition $definition): array
    {
        $this->definitionVariables = new \SplObjectStorage();
        $this->referenceVariables = [];
        $this->variableCount = 0;
        $this->referenceVariables[$id] = new Variable('instance');

        $return = [];

        if ($class = $definition->getClass()) {
            $class = $class instanceof Parameter ? '%'.$class.'%' : $this->container->resolveEnvPlaceholders($class);
            $return[] = sprintf(0 === strpos($class, '%') ? '@return object A %1$s instance' : '@return \%s', ltrim($class, '\\'));
        } elseif ($definition->getFactory()) {
            $factory = $definition->getFactory();
            if (\is_string($factory)) {
                $return[] = sprintf('@return object An instance returned by %s()', $factory);
            } elseif (\is_array($factory) && (\is_string($factory[0]) || $factory[0] instanceof Definition || $factory[0] instanceof Reference)) {
                $class = $factory[0] instanceof Definition ? $factory[0]->getClass() : (string) $factory[0];
                $class = $class instanceof Parameter ? '%'.$class.'%' : $this->container->resolveEnvPlaceholders($class);
                $return[] = sprintf('@return object An instance returned by %s::%s()', $class, $factory[1]);
            }
        }

        if ($definition->isDeprecated()) {
            if ($return && 0 === strpos($return[\count($return) - 1], '@return')) {
                $return[] = '';
            }

            $deprecation = $definition->getDeprecation($id);
            $return[] = sprintf('@deprecated %s', ($deprecation['package'] || $deprecation['version'] ? "Since {$deprecation['package']} {$deprecation['version']}: " : '').$deprecation['message']);
        }

        $return = str_replace("\n     * \n", "\n     *\n", implode("\n     * ", $return));
        $return = $this->container->resolveEnvPlaceholders($return);

        $shared = $definition->isShared() ? ' shared' : '';
        $public = $definition->isPublic() ? 'public' : 'private';
        $autowired = $definition->isAutowired() ? ' autowired' : '';
        $asFile = $this->asFiles && !$this->inlineFactories && !$this->isHotPath($definition);
        $methodName = $this->generateMethodName($id);

        if ($asFile || $definition->isLazy()) {
            $lazyInitialization = '$lazyLoad = true';
        } else {
            $lazyInitialization = '';
        }

        $code = <<<EOF

    /*{$this->docStar}
     * Gets the $public '$id'$shared$autowired service.
     *
     * $return
EOF;
        $code = str_replace('*/', ' ', $code).<<<EOF

     */
    protected function {$methodName}($lazyInitialization)
    {

EOF;

        if ($asFile) {
            $file = $methodName.'.php';
            $code = str_replace("protected function {$methodName}(", 'public static function do($container, ', $code);
        } else {
            $file = null;
        }

        if ($definition->hasErrors() && $e = $definition->getErrors()) {
            $this->addThrow = true;

            $code .= sprintf("        \$this->throw(%s);\n", $this->export(reset($e)));
        } else {
            $this->serviceCalls = [];
            $this->inlinedDefinitions = $this->getDefinitionsFromArguments([$definition], null, $this->serviceCalls);

            if ($definition->isDeprecated()) {
                $deprecation = $definition->getDeprecation($id);
                $code .= sprintf("        trigger_deprecation(%s, %s, %s);\n\n", $this->export($deprecation['package']), $this->export($deprecation['version']), $this->export($deprecation['message']));
            } elseif ($definition->hasTag($this->hotPathTag) || !$definition->hasTag($this->preloadTags[1])) {
                foreach ($this->inlinedDefinitions as $def) {
                    foreach ($this->getClasses($def, $id) as $class) {
                        $this->preload[$class] = $class;
                    }
                }
            }

            if (!$definition->isShared()) {
                $factory = sprintf('$this->factories%s[%s]', $definition->isPublic() ? '' : "['service_container']", $this->doExport($id));
            }

            if ($isProxyCandidate = $this->getProxyDumper()->isProxyCandidate($definition)) {
                if (!$definition->isShared()) {
                    $code .= sprintf('        %s = %1$s ?? ', $factory);

                    if ($asFile) {
                        $code .= "function () {\n";
                        $code .= "            return self::do(\$container);\n";
                        $code .= "        };\n\n";
                    } else {
                        $code .= sprintf("\\Closure::fromCallable([\$this, '%s']);\n\n", $methodName);
                    }
                }

                $factoryCode = $asFile ? 'self::do($container, false)' : sprintf('$this->%s(false)', $methodName);
                $factoryCode = $this->getProxyDumper()->getProxyFactoryCode($definition, $id, $factoryCode);
                $code .= $asFile ? preg_replace('/function \(([^)]*+)\) {/', 'function (\1) use ($container) {', $factoryCode) : $factoryCode;
            }

            $c = $this->addServiceInclude($id, $definition);

            if ('' !== $c && $isProxyCandidate && !$definition->isShared()) {
                $c = implode("\n", array_map(function ($line) { return $line ? '    '.$line : $line; }, explode("\n", $c)));
                $code .= "        static \$include = true;\n\n";
                $code .= "        if (\$include) {\n";
                $code .= $c;
                $code .= "            \$include = false;\n";
                $code .= "        }\n\n";
            } else {
                $code .= $c;
            }

            $c = $this->addInlineService($id, $definition);

            if (!$isProxyCandidate && !$definition->isShared()) {
                $c = implode("\n", array_map(function ($line) { return $line ? '    '.$line : $line; }, explode("\n", $c)));
                $lazyloadInitialization = $definition->isLazy() ? '$lazyLoad = true' : '';

                $c = sprintf("        %s = function (%s) {\n%s        };\n\n        return %1\$s();\n", $factory, $lazyloadInitialization, $c);
            }

            $code .= $c;
        }

        if ($asFile) {
            $code = str_replace('$this', '$container', $code);
            $code = str_replace('function () {', 'function () use ($container) {', $code);
            $code = str_replace('function ($lazyLoad = true) {', 'function ($lazyLoad = true) use ($container) {', $code);
        }

        $code .= "    }\n";

        $this->definitionVariables = $this->inlinedDefinitions = null;
        $this->referenceVariables = $this->serviceCalls = null;

        return [$file, $code];
    }

    private function addInlineVariables(string $id, Definition $definition, array $arguments, bool $forConstructor): string
    {
        $code = '';

        foreach ($arguments as $argument) {
            if (\is_array($argument)) {
                $code .= $this->addInlineVariables($id, $definition, $argument, $forConstructor);
            } elseif ($argument instanceof Reference) {
                $code .= $this->addInlineReference($id, $definition, $argument, $forConstructor);
            } elseif ($argument instanceof Definition) {
                $code .= $this->addInlineService($id, $definition, $argument, $forConstructor);
            }
        }

        return $code;
    }

    private function addInlineReference(string $id, Definition $definition, string $targetId, bool $forConstructor): string
    {
        while ($this->container->hasAlias($targetId)) {
            $targetId = (string) $this->container->getAlias($targetId);
        }

        list($callCount, $behavior) = $this->serviceCalls[$targetId];

        if ($id === $targetId) {
            return $this->addInlineService($id, $definition, $definition);
        }

        if ('service_container' === $targetId || isset($this->referenceVariables[$targetId])) {
            return '';
        }

        if ($this->container->hasDefinition($targetId) && ($def = $this->container->getDefinition($targetId)) && !$def->isShared()) {
            return '';
        }

        $hasSelfRef = isset($this->circularReferences[$id][$targetId]) && !isset($this->definitionVariables[$definition]);

        if ($hasSelfRef && !$forConstructor && !$forConstructor = !$this->circularReferences[$id][$targetId]) {
            $code = $this->addInlineService($id, $definition, $definition);
        } else {
            $code = '';
        }

        if (isset($this->referenceVariables[$targetId]) || (2 > $callCount && (!$hasSelfRef || !$forConstructor))) {
            return $code;
        }

        $name = $this->getNextVariableName();
        $this->referenceVariables[$targetId] = new Variable($name);

        $reference = ContainerInterface::EXCEPTION_ON_INVALID_REFERENCE >= $behavior ? new Reference($targetId, $behavior) : null;
        $code .= sprintf("        \$%s = %s;\n", $name, $this->getServiceCall($targetId, $reference));

        if (!$hasSelfRef || !$forConstructor) {
            return $code;
        }

        $code .= sprintf(<<<'EOTXT'

        if (isset($this->%s[%s])) {
            return $this->%1$s[%2$s];
        }

EOTXT
            ,
            $this->container->getDefinition($id)->isPublic() ? 'services' : 'privates',
            $this->doExport($id)
        );

        return $code;
    }

    private function addInlineService(string $id, Definition $definition, Definition $inlineDef = null, bool $forConstructor = true): string
    {
        $code = '';

        if ($isSimpleInstance = $isRootInstance = null === $inlineDef) {
            foreach ($this->serviceCalls as $targetId => list($callCount, $behavior, $byConstructor)) {
                if ($byConstructor && isset($this->circularReferences[$id][$targetId]) && !$this->circularReferences[$id][$targetId]) {
                    $code .= $this->addInlineReference($id, $definition, $targetId, $forConstructor);
                }
            }
        }

        if (isset($this->definitionVariables[$inlineDef = $inlineDef ?: $definition])) {
            return $code;
        }

        $arguments = [$inlineDef->getArguments(), $inlineDef->getFactory()];

        $code .= $this->addInlineVariables($id, $definition, $arguments, $forConstructor);

        if ($arguments = array_filter([$inlineDef->getProperties(), $inlineDef->getMethodCalls(), $inlineDef->getConfigurator()])) {
            $isSimpleInstance = false;
        } elseif ($definition !== $inlineDef && 2 > $this->inlinedDefinitions[$inlineDef]) {
            return $code;
        }

        if (isset($this->definitionVariables[$inlineDef])) {
            $isSimpleInstance = false;
        } else {
            $name = $definition === $inlineDef ? 'instance' : $this->getNextVariableName();
            $this->definitionVariables[$inlineDef] = new Variable($name);
            $code .= '' !== $code ? "\n" : '';

            if ('instance' === $name) {
                $code .= $this->addServiceInstance($id, $definition, $isSimpleInstance);
            } else {
                $code .= $this->addNewInstance($inlineDef, '        $'.$name.' = ', $id);
            }

            if ('' !== $inline = $this->addInlineVariables($id, $definition, $arguments, false)) {
                $code .= "\n".$inline."\n";
            } elseif ($arguments && 'instance' === $name) {
                $code .= "\n";
            }

            $code .= $this->addServiceProperties($inlineDef, $name);
            $code .= $this->addServiceMethodCalls($inlineDef, $name, !$this->getProxyDumper()->isProxyCandidate($inlineDef) && $inlineDef->isShared() && !isset($this->singleUsePrivateIds[$id]) ? $id : null);
            $code .= $this->addServiceConfigurator($inlineDef, $name);
        }

        if ($isRootInstance && !$isSimpleInstance) {
            $code .= "\n        return \$instance;\n";
        }

        return $code;
    }

    private function addServices(array &$services = null): string
    {
        $publicServices = $privateServices = '';
        $definitions = $this->container->getDefinitions();
        ksort($definitions);
        foreach ($definitions as $id => $definition) {
            if (!$definition->isSynthetic()) {
                $services[$id] = $this->addService($id, $definition);
            } elseif ($definition->hasTag($this->hotPathTag) || !$definition->hasTag($this->preloadTags[1])) {
                $services[$id] = null;

                foreach ($this->getClasses($definition, $id) as $class) {
                    $this->preload[$class] = $class;
                }
            }
        }

        foreach ($definitions as $id => $definition) {
            if (!(list($file, $code) = $services[$id]) || null !== $file) {
                continue;
            }
            if ($definition->isPublic()) {
                $publicServices .= $code;
            } elseif (!$this->isTrivialInstance($definition) || isset($this->locatedIds[$id])) {
                $privateServices .= $code;
            }
        }

        return $publicServices.$privateServices;
    }

    private function generateServiceFiles(array $services): iterable
    {
        $definitions = $this->container->getDefinitions();
        ksort($definitions);
        foreach ($definitions as $id => $definition) {
            if ((list($file, $code) = $services[$id]) && null !== $file && ($definition->isPublic() || !$this->isTrivialInstance($definition) || isset($this->locatedIds[$id]))) {
                yield $file => [$code, $definition->hasTag($this->hotPathTag) || !$definition->hasTag($this->preloadTags[1]) && !$definition->isDeprecated() && !$definition->hasErrors()];
            }
        }
    }

    private function addNewInstance(Definition $definition, string $return = '', string $id = null): string
    {
        $tail = $return ? ";\n" : '';

        if (BaseServiceLocator::class === $definition->getClass() && $definition->hasTag($this->serviceLocatorTag)) {
            $arguments = [];
            foreach ($definition->getArgument(0) as $k => $argument) {
                $arguments[$k] = $argument->getValues()[0];
            }

            return $return.$this->dumpValue(new ServiceLocatorArgument($arguments)).$tail;
        }

        $arguments = [];
        foreach ($definition->getArguments() as $value) {
            $arguments[] = $this->dumpValue($value);
        }

        if (null !== $definition->getFactory()) {
            $callable = $definition->getFactory();

            if (\is_array($callable)) {
                if (!preg_match('/^[a-zA-Z_\x7f-\xff][a-zA-Z0-9_\x7f-\xff]*$/', $callable[1])) {
                    throw new RuntimeException(sprintf('Cannot dump definition because of invalid factory method (%s).', $callable[1] ?: 'n/a'));
                }

                if ($callable[0] instanceof Reference
                    || ($callable[0] instanceof Definition && $this->definitionVariables->contains($callable[0]))) {
                    return $return.sprintf('%s->%s(%s)', $this->dumpValue($callable[0]), $callable[1], $arguments ? implode(', ', $arguments) : '').$tail;
                }

                $class = $this->dumpValue($callable[0]);
                // If the class is a string we can optimize away
                if (0 === strpos($class, "'") && false === strpos($class, '$')) {
                    if ("''" === $class) {
                        throw new RuntimeException(sprintf('Cannot dump definition: "%s" service is defined to be created by a factory but is missing the service reference, did you forget to define the factory service id or class?', $id ? 'The "'.$id.'"' : 'inline'));
                    }

                    return $return.sprintf('%s::%s(%s)', $this->dumpLiteralClass($class), $callable[1], $arguments ? implode(', ', $arguments) : '').$tail;
                }

                if (0 === strpos($class, 'new ')) {
                    return $return.sprintf('(%s)->%s(%s)', $class, $callable[1], $arguments ? implode(', ', $arguments) : '').$tail;
                }

                return $return.sprintf("[%s, '%s'](%s)", $class, $callable[1], $arguments ? implode(', ', $arguments) : '').$tail;
            }

            return $return.sprintf('%s(%s)', $this->dumpLiteralClass($this->dumpValue($callable)), $arguments ? implode(', ', $arguments) : '').$tail;
        }

        if (null === $class = $definition->getClass()) {
            throw new RuntimeException('Cannot dump definitions which have no class nor factory.');
        }

        return $return.sprintf('new %s(%s)', $this->dumpLiteralClass($this->dumpValue($class)), implode(', ', $arguments)).$tail;
    }

    private function startClass(string $class, string $baseClass): string
    {
        $namespaceLine = !$this->asFiles && $this->namespace ? "\nnamespace {$this->namespace};\n" : '';

        $code = <<<EOF
<?php
$namespaceLine
use Symfony\Component\DependencyInjection\Argument\RewindableGenerator;
use Symfony\Component\DependencyInjection\ContainerInterface;
use Symfony\Component\DependencyInjection\Container;
use Symfony\Component\DependencyInjection\Exception\InvalidArgumentException;
use Symfony\Component\DependencyInjection\Exception\LogicException;
use Symfony\Component\DependencyInjection\Exception\RuntimeException;
use Symfony\Component\DependencyInjection\ParameterBag\FrozenParameterBag;
use Symfony\Component\DependencyInjection\ParameterBag\ParameterBagInterface;

/*{$this->docStar}
 * @internal This class has been auto-generated by the Symfony Dependency Injection Component.
 */
class $class extends $baseClass
{
    protected \$parameters = [];

    public function __construct()
    {

EOF;
        if ($this->asFiles) {
            $code = str_replace('$parameters = []', "\$containerDir;\n    protected \$parameters = [];\n    private \$buildParameters", $code);
            $code = str_replace('__construct()', '__construct(array $buildParameters = [], $containerDir = __DIR__)', $code);
            $code .= "        \$this->buildParameters = \$buildParameters;\n";
            $code .= "        \$this->containerDir = \$containerDir;\n";

            if (null !== $this->targetDirRegex) {
                $code = str_replace('$parameters = []', "\$targetDir;\n    protected \$parameters = []", $code);
                $code .= '        $this->targetDir = \\dirname($containerDir);'."\n";
            }
        }

        if (Container::class !== $this->baseClass) {
            $r = $this->container->getReflectionClass($this->baseClass, false);
            if (null !== $r
                && (null !== $constructor = $r->getConstructor())
                && 0 === $constructor->getNumberOfRequiredParameters()
                && Container::class !== $constructor->getDeclaringClass()->name
            ) {
                $code .= "        parent::__construct();\n";
                $code .= "        \$this->parameterBag = null;\n\n";
            }
        }

        if ($this->container->getParameterBag()->all()) {
            $code .= "        \$this->parameters = \$this->getDefaultParameters();\n\n";
        }
        $code .= "        \$this->services = \$this->privates = [];\n";

        $code .= $this->addSyntheticIds();
        $code .= $this->addMethodMap();
        $code .= $this->asFiles && !$this->inlineFactories ? $this->addFileMap() : '';
        $code .= $this->addAliases();
        $code .= $this->addInlineRequires();
        $code .= <<<EOF
    }

    public function compile(): void
    {
        throw new LogicException('You cannot compile a dumped container that was already compiled.');
    }

    public function isCompiled(): bool
    {
        return true;
    }

EOF;
        $code .= $this->addRemovedIds();

        if ($this->asFiles && !$this->inlineFactories) {
            $code .= <<<'EOF'

    protected function load($file, $lazyLoad = true)
    {
        if (class_exists($class = __NAMESPACE__.'\\'.$file, false)) {
            return $class::do($this, $lazyLoad);
        }

        if ('.' === $file[-4]) {
            $class = substr($class, 0, -4);
        } else {
            $file .= '.php';
        }

        $service = require $this->containerDir.\DIRECTORY_SEPARATOR.$file;

        return class_exists($class, false) ? $class::do($this, $lazyLoad) : $service;
    }

EOF;
        }

        $proxyDumper = $this->getProxyDumper();
        foreach ($this->container->getDefinitions() as $definition) {
            if (!$proxyDumper->isProxyCandidate($definition)) {
                continue;
            }

            if ($this->asFiles && !$this->inlineFactories) {
                $proxyLoader = "class_exists(\$class, false) || require __DIR__.'/'.\$class.'.php';\n\n        ";
            } else {
                $proxyLoader = '';
            }

            $code .= <<<EOF

    protected function createProxy(\$class, \Closure \$factory)
    {
        {$proxyLoader}return \$factory();
    }

EOF;
            break;
        }

        return $code;
    }

    private function addSyntheticIds(): string
    {
        $code = '';
        $definitions = $this->container->getDefinitions();
        ksort($definitions);
        foreach ($definitions as $id => $definition) {
            if ($definition->isSynthetic() && 'service_container' !== $id) {
                $code .= '            '.$this->doExport($id)." => true,\n";
            }
        }

        return $code ? "        \$this->syntheticIds = [\n{$code}        ];\n" : '';
    }

    private function addRemovedIds(): string
    {
        $ids = $this->container->getRemovedIds();
        foreach ($this->container->getDefinitions() as $id => $definition) {
            if (!$definition->isPublic()) {
                $ids[$id] = true;
            }
        }
        if (!$ids) {
            return '';
        }
        if ($this->asFiles) {
            $code = "require \$this->containerDir.\\DIRECTORY_SEPARATOR.'removed-ids.php'";
        } else {
            $code = '';
            $ids = array_keys($ids);
            sort($ids);
            foreach ($ids as $id) {
                if (preg_match(FileLoader::ANONYMOUS_ID_REGEXP, $id)) {
                    continue;
                }
                $code .= '            '.$this->doExport($id)." => true,\n";
            }

            $code = "[\n{$code}        ]";
        }

        return <<<EOF

    public function getRemovedIds(): array
    {
        return {$code};
    }

EOF;
    }

    private function addMethodMap(): string
    {
        $code = '';
        $definitions = $this->container->getDefinitions();
        ksort($definitions);
        foreach ($definitions as $id => $definition) {
            if (!$definition->isSynthetic() && $definition->isPublic() && (!$this->asFiles || $this->inlineFactories || $this->isHotPath($definition))) {
                $code .= '            '.$this->doExport($id).' => '.$this->doExport($this->generateMethodName($id)).",\n";
            }
        }

        $aliases = $this->container->getAliases();
        foreach ($aliases as $alias => $id) {
            if (!$id->isDeprecated()) {
                continue;
            }
            $code .= '            '.$this->doExport($alias).' => '.$this->doExport($this->generateMethodName($alias)).",\n";
        }

        return $code ? "        \$this->methodMap = [\n{$code}        ];\n" : '';
    }

    private function addFileMap(): string
    {
        $code = '';
        $definitions = $this->container->getDefinitions();
        ksort($definitions);
        foreach ($definitions as $id => $definition) {
            if (!$definition->isSynthetic() && $definition->isPublic() && !$this->isHotPath($definition)) {
                $code .= sprintf("            %s => '%s',\n", $this->doExport($id), $this->generateMethodName($id));
            }
        }

        return $code ? "        \$this->fileMap = [\n{$code}        ];\n" : '';
    }

    private function addAliases(): string
    {
        if (!$aliases = $this->container->getAliases()) {
            return "\n        \$this->aliases = [];\n";
        }

        $code = "        \$this->aliases = [\n";
        ksort($aliases);
        foreach ($aliases as $alias => $id) {
            if ($id->isDeprecated()) {
                continue;
            }

            $id = (string) $id;
            while (isset($aliases[$id])) {
                $id = (string) $aliases[$id];
            }
            $code .= '            '.$this->doExport($alias).' => '.$this->doExport($id).",\n";
        }

        return $code."        ];\n";
    }

    private function addDeprecatedAliases(): string
    {
        $code = '';
        $aliases = $this->container->getAliases();
        foreach ($aliases as $alias => $definition) {
            if (!$definition->isDeprecated()) {
                continue;
            }
            $public = $definition->isPublic() ? 'public' : 'private';
            $id = (string) $definition;
            $methodNameAlias = $this->generateMethodName($alias);
            $idExported = $this->export($id);
            $deprecation = $definition->getDeprecation($alias);
            $packageExported = $this->export($deprecation['package']);
            $versionExported = $this->export($deprecation['version']);
            $messageExported = $this->export($deprecation['message']);
            $code .= <<<EOF

    /*{$this->docStar}
     * Gets the $public '$alias' alias.
     *
     * @return object The "$id" service.
     */
    protected function {$methodNameAlias}()
    {
        trigger_deprecation($packageExported, $versionExported, $messageExported);

        return \$this->get($idExported);
    }

EOF;
        }

        return $code;
    }

    private function addInlineRequires(): string
    {
        if (!$this->hotPathTag || !$this->inlineRequires) {
            return '';
        }

        $lineage = [];

        foreach ($this->container->findTaggedServiceIds($this->hotPathTag) as $id => $tags) {
            $definition = $this->container->getDefinition($id);

            if ($this->getProxyDumper()->isProxyCandidate($definition)) {
                continue;
            }

            $inlinedDefinitions = $this->getDefinitionsFromArguments([$definition]);

            foreach ($inlinedDefinitions as $def) {
                foreach ($this->getClasses($def, $id) as $class) {
                    $this->collectLineage($class, $lineage);
                }
            }
        }

        $code = '';

        foreach ($lineage as $file) {
            if (!isset($this->inlinedRequires[$file])) {
                $this->inlinedRequires[$file] = true;
                $code .= sprintf("\n            include_once %s;", $file);
            }
        }

        return $code ? sprintf("\n        \$this->privates['service_container'] = function () {%s\n        };\n", $code) : '';
    }

    private function addDefaultParametersMethod(): string
    {
        if (!$this->container->getParameterBag()->all()) {
            return '';
        }

        $php = [];
        $dynamicPhp = [];

        foreach ($this->container->getParameterBag()->all() as $key => $value) {
            if ($key !== $resolvedKey = $this->container->resolveEnvPlaceholders($key)) {
                throw new InvalidArgumentException(sprintf('Parameter name cannot use env parameters: "%s".', $resolvedKey));
            }
            $export = $this->exportParameters([$value]);
            $export = explode('0 => ', substr(rtrim($export, " ]\n"), 2, -1), 2);

            if (preg_match("/\\\$this->(?:getEnv\('(?:\w++:)*+\w++'\)|targetDir\.'')/", $export[1])) {
                $dynamicPhp[$key] = sprintf('%scase %s: $value = %s; break;', $export[0], $this->export($key), $export[1]);
            } else {
                $php[] = sprintf('%s%s => %s,', $export[0], $this->export($key), $export[1]);
            }
        }
        $parameters = sprintf("[\n%s\n%s]", implode("\n", $php), str_repeat(' ', 8));

        $code = <<<'EOF'

    public function getParameter(string $name)
    {
        if (isset($this->buildParameters[$name])) {
            return $this->buildParameters[$name];
        }

        if (!(isset($this->parameters[$name]) || isset($this->loadedDynamicParameters[$name]) || \array_key_exists($name, $this->parameters))) {
            throw new InvalidArgumentException(sprintf('The parameter "%s" must be defined.', $name));
        }
        if (isset($this->loadedDynamicParameters[$name])) {
            return $this->loadedDynamicParameters[$name] ? $this->dynamicParameters[$name] : $this->getDynamicParameter($name);
        }

        return $this->parameters[$name];
    }

    public function hasParameter(string $name): bool
    {
        if (isset($this->buildParameters[$name])) {
            return true;
        }

        return isset($this->parameters[$name]) || isset($this->loadedDynamicParameters[$name]) || \array_key_exists($name, $this->parameters);
    }

    public function setParameter(string $name, $value): void
    {
        throw new LogicException('Impossible to call set() on a frozen ParameterBag.');
    }

    public function getParameterBag(): ParameterBagInterface
    {
        if (null === $this->parameterBag) {
            $parameters = $this->parameters;
            foreach ($this->loadedDynamicParameters as $name => $loaded) {
                $parameters[$name] = $loaded ? $this->dynamicParameters[$name] : $this->getDynamicParameter($name);
            }
            foreach ($this->buildParameters as $name => $value) {
                $parameters[$name] = $value;
            }
            $this->parameterBag = new FrozenParameterBag($parameters);
        }

        return $this->parameterBag;
    }

EOF;
        if (!$this->asFiles) {
            $code = preg_replace('/^.*buildParameters.*\n.*\n.*\n\n?/m', '', $code);
        }

        if ($dynamicPhp) {
            $loadedDynamicParameters = $this->exportParameters(array_combine(array_keys($dynamicPhp), array_fill(0, \count($dynamicPhp), false)), '', 8);
            $getDynamicParameter = <<<'EOF'
        switch ($name) {
%s
            default: throw new InvalidArgumentException(sprintf('The dynamic parameter "%%s" must be defined.', $name));
        }
        $this->loadedDynamicParameters[$name] = true;

        return $this->dynamicParameters[$name] = $value;
EOF;
            $getDynamicParameter = sprintf($getDynamicParameter, implode("\n", $dynamicPhp));
        } else {
            $loadedDynamicParameters = '[]';
            $getDynamicParameter = str_repeat(' ', 8).'throw new InvalidArgumentException(sprintf(\'The dynamic parameter "%s" must be defined.\', $name));';
        }

        $code .= <<<EOF

    private \$loadedDynamicParameters = {$loadedDynamicParameters};
    private \$dynamicParameters = [];

    private function getDynamicParameter(string \$name)
    {
{$getDynamicParameter}
    }

    protected function getDefaultParameters(): array
    {
        return $parameters;
    }

EOF;

        return $code;
    }

    /**
     * @throws InvalidArgumentException
     */
    private function exportParameters(array $parameters, string $path = '', int $indent = 12): string
    {
        $php = [];
        foreach ($parameters as $key => $value) {
            if (\is_array($value)) {
                $value = $this->exportParameters($value, $path.'/'.$key, $indent + 4);
            } elseif ($value instanceof ArgumentInterface) {
                throw new InvalidArgumentException(sprintf('You cannot dump a container with parameters that contain special arguments. "%s" found in "%s".', get_debug_type($value), $path.'/'.$key));
            } elseif ($value instanceof Variable) {
                throw new InvalidArgumentException(sprintf('You cannot dump a container with parameters that contain variable references. Variable "%s" found in "%s".', $value, $path.'/'.$key));
            } elseif ($value instanceof Definition) {
                throw new InvalidArgumentException(sprintf('You cannot dump a container with parameters that contain service definitions. Definition for "%s" found in "%s".', $value->getClass(), $path.'/'.$key));
            } elseif ($value instanceof Reference) {
                throw new InvalidArgumentException(sprintf('You cannot dump a container with parameters that contain references to other services (reference to service "%s" found in "%s").', $value, $path.'/'.$key));
            } elseif ($value instanceof Expression) {
                throw new InvalidArgumentException(sprintf('You cannot dump a container with parameters that contain expressions. Expression "%s" found in "%s".', $value, $path.'/'.$key));
            } else {
                $value = $this->export($value);
            }

            $php[] = sprintf('%s%s => %s,', str_repeat(' ', $indent), $this->export($key), $value);
        }

        return sprintf("[\n%s\n%s]", implode("\n", $php), str_repeat(' ', $indent - 4));
    }

    private function endClass(): string
    {
        if ($this->addThrow) {
            return <<<'EOF'

    protected function throw($message)
    {
        throw new RuntimeException($message);
    }
}

EOF;
        }

        return <<<'EOF'
}

EOF;
    }

    private function wrapServiceConditionals($value, string $code): string
    {
        if (!$condition = $this->getServiceConditionals($value)) {
            return $code;
        }

        // re-indent the wrapped code
        $code = implode("\n", array_map(function ($line) { return $line ? '    '.$line : $line; }, explode("\n", $code)));

        return sprintf("        if (%s) {\n%s        }\n", $condition, $code);
    }

    private function getServiceConditionals($value): string
    {
        $conditions = [];
        foreach (ContainerBuilder::getInitializedConditionals($value) as $service) {
            if (!$this->container->hasDefinition($service)) {
                return 'false';
            }
            $conditions[] = sprintf('isset($this->%s[%s])', $this->container->getDefinition($service)->isPublic() ? 'services' : 'privates', $this->doExport($service));
        }
        foreach (ContainerBuilder::getServiceConditionals($value) as $service) {
            if ($this->container->hasDefinition($service) && !$this->container->getDefinition($service)->isPublic()) {
                continue;
            }

            $conditions[] = sprintf('$this->has(%s)', $this->doExport($service));
        }

        if (!$conditions) {
            return '';
        }

        return implode(' && ', $conditions);
    }

    private function getDefinitionsFromArguments(array $arguments, \SplObjectStorage $definitions = null, array &$calls = [], bool $byConstructor = null): \SplObjectStorage
    {
        if (null === $definitions) {
            $definitions = new \SplObjectStorage();
        }

        foreach ($arguments as $argument) {
            if (\is_array($argument)) {
                $this->getDefinitionsFromArguments($argument, $definitions, $calls, $byConstructor);
            } elseif ($argument instanceof Reference) {
                $id = (string) $argument;

                while ($this->container->hasAlias($id)) {
                    $id = (string) $this->container->getAlias($id);
                }

                if (!isset($calls[$id])) {
                    $calls[$id] = [0, $argument->getInvalidBehavior(), $byConstructor];
                } else {
                    $calls[$id][1] = min($calls[$id][1], $argument->getInvalidBehavior());
                }

                ++$calls[$id][0];
            } elseif (!$argument instanceof Definition) {
                // no-op
            } elseif (isset($definitions[$argument])) {
                $definitions[$argument] = 1 + $definitions[$argument];
            } else {
                $definitions[$argument] = 1;
                $arguments = [$argument->getArguments(), $argument->getFactory()];
                $this->getDefinitionsFromArguments($arguments, $definitions, $calls, null === $byConstructor || $byConstructor);
                $arguments = [$argument->getProperties(), $argument->getMethodCalls(), $argument->getConfigurator()];
                $this->getDefinitionsFromArguments($arguments, $definitions, $calls, null !== $byConstructor && $byConstructor);
            }
        }

        return $definitions;
    }

    /**
     * @throws RuntimeException
     */
    private function dumpValue($value, bool $interpolate = true): string
    {
        if (\is_array($value)) {
            if ($value && $interpolate && false !== $param = array_search($value, $this->container->getParameterBag()->all(), true)) {
                return $this->dumpValue("%$param%");
            }
            $code = [];
            foreach ($value as $k => $v) {
                $code[] = sprintf('%s => %s', $this->dumpValue($k, $interpolate), $this->dumpValue($v, $interpolate));
            }

            return sprintf('[%s]', implode(', ', $code));
        } elseif ($value instanceof ArgumentInterface) {
            $scope = [$this->definitionVariables, $this->referenceVariables];
            $this->definitionVariables = $this->referenceVariables = null;

            try {
                if ($value instanceof ServiceClosureArgument) {
                    $value = $value->getValues()[0];
                    $code = $this->dumpValue($value, $interpolate);

                    $returnedType = '';
                    if ($value instanceof TypedReference) {
                        $returnedType = sprintf(': %s\%s', ContainerInterface::EXCEPTION_ON_INVALID_REFERENCE >= $value->getInvalidBehavior() ? '' : '?', $value->getType());
                    }

                    $code = sprintf('return %s;', $code);

                    return sprintf("function ()%s {\n            %s\n        }", $returnedType, $code);
                }

                if ($value instanceof IteratorArgument) {
                    $operands = [0];
                    $code = [];
                    $code[] = 'new RewindableGenerator(function () {';

                    if (!$values = $value->getValues()) {
                        $code[] = '            return new \EmptyIterator();';
                    } else {
                        $countCode = [];
                        $countCode[] = 'function () {';

                        foreach ($values as $k => $v) {
                            ($c = $this->getServiceConditionals($v)) ? $operands[] = "(int) ($c)" : ++$operands[0];
                            $v = $this->wrapServiceConditionals($v, sprintf("        yield %s => %s;\n", $this->dumpValue($k, $interpolate), $this->dumpValue($v, $interpolate)));
                            foreach (explode("\n", $v) as $v) {
                                if ($v) {
                                    $code[] = '    '.$v;
                                }
                            }
                        }

                        $countCode[] = sprintf('            return %s;', implode(' + ', $operands));
                        $countCode[] = '        }';
                    }

                    $code[] = sprintf('        }, %s)', \count($operands) > 1 ? implode("\n", $countCode) : $operands[0]);

                    return implode("\n", $code);
                }

                if ($value instanceof ServiceLocatorArgument) {
                    $serviceMap = '';
                    $serviceTypes = '';
                    foreach ($value->getValues() as $k => $v) {
                        if (!$v) {
                            continue;
                        }
                        $id = (string) $v;
                        while ($this->container->hasAlias($id)) {
                            $id = (string) $this->container->getAlias($id);
                        }
                        $definition = $this->container->getDefinition($id);
                        $load = !($definition->hasErrors() && $e = $definition->getErrors()) ? $this->asFiles && !$this->inlineFactories && !$this->isHotPath($definition) : reset($e);
                        $serviceMap .= sprintf("\n            %s => [%s, %s, %s, %s],",
                            $this->export($k),
                            $this->export($definition->isShared() ? ($definition->isPublic() ? 'services' : 'privates') : false),
                            $this->doExport($id),
                            $this->export(ContainerInterface::IGNORE_ON_UNINITIALIZED_REFERENCE !== $v->getInvalidBehavior() && !\is_string($load) ? $this->generateMethodName($id) : null),
                            $this->export($load)
                        );
                        $serviceTypes .= sprintf("\n            %s => %s,", $this->export($k), $this->export($v instanceof TypedReference ? $v->getType() : '?'));
                        $this->locatedIds[$id] = true;
                    }
                    $this->addGetService = true;

                    return sprintf('new \%s($this->getService, [%s%s], [%s%s])', ServiceLocator::class, $serviceMap, $serviceMap ? "\n        " : '', $serviceTypes, $serviceTypes ? "\n        " : '');
                }
            } finally {
                list($this->definitionVariables, $this->referenceVariables) = $scope;
            }
        } elseif ($value instanceof Definition) {
            if ($value->hasErrors() && $e = $value->getErrors()) {
                $this->addThrow = true;

                return sprintf('$this->throw(%s)', $this->export(reset($e)));
            }
            if (null !== $this->definitionVariables && $this->definitionVariables->contains($value)) {
                return $this->dumpValue($this->definitionVariables[$value], $interpolate);
            }
            if ($value->getMethodCalls()) {
                throw new RuntimeException('Cannot dump definitions which have method calls.');
            }
            if ($value->getProperties()) {
                throw new RuntimeException('Cannot dump definitions which have properties.');
            }
            if (null !== $value->getConfigurator()) {
                throw new RuntimeException('Cannot dump definitions which have a configurator.');
            }

            return $this->addNewInstance($value);
        } elseif ($value instanceof Variable) {
            return '$'.$value;
        } elseif ($value instanceof Reference) {
            $id = (string) $value;

            while ($this->container->hasAlias($id)) {
                $id = (string) $this->container->getAlias($id);
            }

            if (null !== $this->referenceVariables && isset($this->referenceVariables[$id])) {
                return $this->dumpValue($this->referenceVariables[$id], $interpolate);
            }

            return $this->getServiceCall($id, $value);
        } elseif ($value instanceof Expression) {
            return $this->getExpressionLanguage()->compile((string) $value, ['this' => 'container']);
        } elseif ($value instanceof Parameter) {
            return $this->dumpParameter($value);
        } elseif (true === $interpolate && \is_string($value)) {
            if (preg_match('/^%([^%]+)%$/', $value, $match)) {
                // we do this to deal with non string values (Boolean, integer, ...)
                // the preg_replace_callback converts them to strings
                return $this->dumpParameter($match[1]);
            } else {
                $replaceParameters = function ($match) {
                    return "'.".$this->dumpParameter($match[2]).".'";
                };

                $code = str_replace('%%', '%', preg_replace_callback('/(?<!%)(%)([^%]+)\1/', $replaceParameters, $this->export($value)));

                return $code;
            }
        } elseif ($value instanceof AbstractArgument) {
            throw new RuntimeException($value->getTextWithContext());
        } elseif (\is_object($value) || \is_resource($value)) {
            throw new RuntimeException('Unable to dump a service container if a parameter is an object or a resource.');
        }

        return $this->export($value);
    }

    /**
     * Dumps a string to a literal (aka PHP Code) class value.
     *
     * @throws RuntimeException
     */
    private function dumpLiteralClass(string $class): string
    {
        if (false !== strpos($class, '$')) {
            return sprintf('${($_ = %s) && false ?: "_"}', $class);
        }
        if (0 !== strpos($class, "'") || !preg_match('/^\'(?:\\\{2})?[a-zA-Z_\x7f-\xff][a-zA-Z0-9_\x7f-\xff]*(?:\\\{2}[a-zA-Z_\x7f-\xff][a-zA-Z0-9_\x7f-\xff]*)*\'$/', $class)) {
            throw new RuntimeException(sprintf('Cannot dump definition because of invalid class name (%s).', $class ?: 'n/a'));
        }

        $class = substr(str_replace('\\\\', '\\', $class), 1, -1);

        return 0 === strpos($class, '\\') ? $class : '\\'.$class;
    }

    private function dumpParameter(string $name): string
    {
        if ($this->container->hasParameter($name)) {
            $value = $this->container->getParameter($name);
            $dumpedValue = $this->dumpValue($value, false);

            if (!$value || !\is_array($value)) {
                return $dumpedValue;
            }

            if (!preg_match("/\\\$this->(?:getEnv\('(?:\w++:)*+\w++'\)|targetDir\.'')/", $dumpedValue)) {
                return sprintf('$this->parameters[%s]', $this->doExport($name));
            }
        }

        return sprintf('$this->getParameter(%s)', $this->doExport($name));
    }

    private function getServiceCall(string $id, Reference $reference = null): string
    {
        while ($this->container->hasAlias($id)) {
            $id = (string) $this->container->getAlias($id);
        }

        if ('service_container' === $id) {
            return '$this';
        }

        if ($this->container->hasDefinition($id) && $definition = $this->container->getDefinition($id)) {
            if ($definition->isSynthetic()) {
                $code = sprintf('$this->get(%s%s)', $this->doExport($id), null !== $reference ? ', '.$reference->getInvalidBehavior() : '');
            } elseif (null !== $reference && ContainerInterface::IGNORE_ON_UNINITIALIZED_REFERENCE === $reference->getInvalidBehavior()) {
                $code = 'null';
                if (!$definition->isShared()) {
                    return $code;
                }
            } elseif ($this->isTrivialInstance($definition)) {
                if ($definition->hasErrors() && $e = $definition->getErrors()) {
                    $this->addThrow = true;

                    return sprintf('$this->throw(%s)', $this->export(reset($e)));
                }
                $code = $this->addNewInstance($definition, '', $id);
                if ($definition->isShared() && !isset($this->singleUsePrivateIds[$id])) {
                    $code = sprintf('$this->%s[%s] = %s', $definition->isPublic() ? 'services' : 'privates', $this->doExport($id), $code);
                }
                $code = "($code)";
            } else {
                $code = $this->asFiles && !$this->inlineFactories && !$this->isHotPath($definition) ? "\$this->load('%s')" : '$this->%s()';
                $code = sprintf($code, $this->generateMethodName($id));

                if (!$definition->isShared()) {
                    $factory = sprintf('$this->factories%s[%s]', $definition->isPublic() ? '' : "['service_container']", $this->doExport($id));
                    $code = sprintf('(isset(%s) ? %1$s() : %s)', $factory, $code);
                }
            }
            if ($definition->isShared() && !isset($this->singleUsePrivateIds[$id])) {
                $code = sprintf('($this->%s[%s] ?? %s)', $definition->isPublic() ? 'services' : 'privates', $this->doExport($id), $code);
            }

            return $code;
        }
        if (null !== $reference && ContainerInterface::IGNORE_ON_UNINITIALIZED_REFERENCE === $reference->getInvalidBehavior()) {
            return 'null';
        }
        if (null !== $reference && ContainerInterface::EXCEPTION_ON_INVALID_REFERENCE < $reference->getInvalidBehavior()) {
            $code = sprintf('$this->get(%s, /* ContainerInterface::NULL_ON_INVALID_REFERENCE */ %d)', $this->doExport($id), ContainerInterface::NULL_ON_INVALID_REFERENCE);
        } else {
            $code = sprintf('$this->get(%s)', $this->doExport($id));
        }

        return sprintf('($this->services[%s] ?? %s)', $this->doExport($id), $code);
    }

    /**
     * Initializes the method names map to avoid conflicts with the Container methods.
     */
    private function initializeMethodNamesMap(string $class)
    {
        $this->serviceIdToMethodNameMap = [];
        $this->usedMethodNames = [];

        if ($reflectionClass = $this->container->getReflectionClass($class)) {
            foreach ($reflectionClass->getMethods() as $method) {
                $this->usedMethodNames[strtolower($method->getName())] = true;
            }
        }
    }

    /**
     * @throws InvalidArgumentException
     */
    private function generateMethodName(string $id): string
    {
        if (isset($this->serviceIdToMethodNameMap[$id])) {
            return $this->serviceIdToMethodNameMap[$id];
        }

        $i = strrpos($id, '\\');
        $name = Container::camelize(false !== $i && isset($id[1 + $i]) ? substr($id, 1 + $i) : $id);
        $name = preg_replace('/[^a-zA-Z0-9_\x7f-\xff]/', '', $name);
        $methodName = 'get'.$name.'Service';
        $suffix = 1;

        while (isset($this->usedMethodNames[strtolower($methodName)])) {
            ++$suffix;
            $methodName = 'get'.$name.$suffix.'Service';
        }

        $this->serviceIdToMethodNameMap[$id] = $methodName;
        $this->usedMethodNames[strtolower($methodName)] = true;

        return $methodName;
    }

    private function getNextVariableName(): string
    {
        $firstChars = self::FIRST_CHARS;
        $firstCharsLength = \strlen($firstChars);
        $nonFirstChars = self::NON_FIRST_CHARS;
        $nonFirstCharsLength = \strlen($nonFirstChars);

        while (true) {
            $name = '';
            $i = $this->variableCount;

            if ('' === $name) {
                $name .= $firstChars[$i % $firstCharsLength];
                $i = (int) ($i / $firstCharsLength);
            }

            while ($i > 0) {
                --$i;
                $name .= $nonFirstChars[$i % $nonFirstCharsLength];
                $i = (int) ($i / $nonFirstCharsLength);
            }

            ++$this->variableCount;

            // check that the name is not reserved
            if (\in_array($name, $this->reservedVariables, true)) {
                continue;
            }

            return $name;
        }
    }

    private function getExpressionLanguage(): ExpressionLanguage
    {
        if (null === $this->expressionLanguage) {
            if (!class_exists('Symfony\Component\ExpressionLanguage\ExpressionLanguage')) {
                throw new LogicException('Unable to use expressions as the Symfony ExpressionLanguage component is not installed.');
            }
            $providers = $this->container->getExpressionLanguageProviders();
            $this->expressionLanguage = new ExpressionLanguage(null, $providers, function ($arg) {
                $id = '""' === substr_replace($arg, '', 1, -1) ? stripcslashes(substr($arg, 1, -1)) : null;

                if (null !== $id && ($this->container->hasAlias($id) || $this->container->hasDefinition($id))) {
                    return $this->getServiceCall($id);
                }

                return sprintf('$this->get(%s)', $arg);
            });

            if ($this->container->isTrackingResources()) {
                foreach ($providers as $provider) {
                    $this->container->addObjectResource($provider);
                }
            }
        }

        return $this->expressionLanguage;
    }

    private function isHotPath(Definition $definition): bool
    {
        return $this->hotPathTag && $definition->hasTag($this->hotPathTag) && !$definition->isDeprecated();
    }

    private function isSingleUsePrivateNode(ServiceReferenceGraphNode $node): bool
    {
        if ($node->getValue()->isPublic()) {
            return false;
        }
        $ids = [];
        foreach ($node->getInEdges() as $edge) {
            if (!$value = $edge->getSourceNode()->getValue()) {
                continue;
            }
            if ($edge->isLazy() || !$value instanceof Definition || !$value->isShared()) {
                return false;
            }
            $ids[$edge->getSourceNode()->getId()] = true;
        }

        return 1 === \count($ids);
    }

    /**
     * @return mixed
     */
    private function export($value)
    {
        if (null !== $this->targetDirRegex && \is_string($value) && preg_match($this->targetDirRegex, $value, $matches, \PREG_OFFSET_CAPTURE)) {
            $suffix = $matches[0][1] + \strlen($matches[0][0]);
            $matches[0][1] += \strlen($matches[1][0]);
            $prefix = $matches[0][1] ? $this->doExport(substr($value, 0, $matches[0][1]), true).'.' : '';

            if ('\\' === \DIRECTORY_SEPARATOR && isset($value[$suffix])) {
                $cookie = '\\'.random_int(100000, \PHP_INT_MAX);
                $suffix = '.'.$this->doExport(str_replace('\\', $cookie, substr($value, $suffix)), true);
                $suffix = str_replace('\\'.$cookie, "'.\\DIRECTORY_SEPARATOR.'", $suffix);
            } else {
                $suffix = isset($value[$suffix]) ? '.'.$this->doExport(substr($value, $suffix), true) : '';
            }

            $dirname = $this->asFiles ? '$this->containerDir' : '__DIR__';
            $offset = 2 + $this->targetDirMaxMatches - \count($matches);

            if (0 < $offset) {
                $dirname = sprintf('\dirname(__DIR__, %d)', $offset + (int) $this->asFiles);
            } elseif ($this->asFiles) {
                $dirname = "\$this->targetDir.''"; // empty string concatenation on purpose
            }

            if ($prefix || $suffix) {
                return sprintf('(%s%s%s)', $prefix, $dirname, $suffix);
            }

            return $dirname;
        }

        return $this->doExport($value, true);
    }

    /**
     * @return mixed
     */
    private function doExport($value, bool $resolveEnv = false)
    {
        $shouldCacheValue = $resolveEnv && \is_string($value);
        if ($shouldCacheValue && isset($this->exportedVariables[$value])) {
            return $this->exportedVariables[$value];
        }
        if (\is_string($value) && false !== strpos($value, "\n")) {
            $cleanParts = explode("\n", $value);
            $cleanParts = array_map(function ($part) { return var_export($part, true); }, $cleanParts);
            $export = implode('."\n".', $cleanParts);
        } else {
            $export = var_export($value, true);
        }
        if ($this->asFiles) {
            if (false !== strpos($export, '$this')) {
                $export = str_replace('$this', "$'.'this", $export);
            }
            if (false !== strpos($export, 'function () {')) {
                $export = str_replace('function () {', "function ('.') {", $export);
            }
        }

        if ($resolveEnv && "'" === $export[0] && $export !== $resolvedExport = $this->container->resolveEnvPlaceholders($export, "'.\$this->getEnv('string:%s').'")) {
            $export = $resolvedExport;
            if (".''" === substr($export, -3)) {
                $export = substr($export, 0, -3);
                if ("'" === $export[1]) {
                    $export = substr_replace($export, '', 18, 7);
                }
            }
            if ("'" === $export[1]) {
                $export = substr($export, 3);
            }
        }

        if ($shouldCacheValue) {
            $this->exportedVariables[$value] = $export;
        }

        return $export;
    }

    private function getAutoloadFile(): ?string
    {
        $file = null;

        foreach (spl_autoload_functions() as $autoloader) {
            if (!\is_array($autoloader)) {
                continue;
            }

            if ($autoloader[0] instanceof DebugClassLoader || $autoloader[0] instanceof LegacyDebugClassLoader) {
                $autoloader = $autoloader[0]->getClassLoader();
            }

            if (!\is_array($autoloader) || !$autoloader[0] instanceof ClassLoader || !$autoloader[0]->findFile(__CLASS__)) {
                continue;
            }

            foreach (get_declared_classes() as $class) {
                if (0 === strpos($class, 'ComposerAutoloaderInit') && $class::getLoader() === $autoloader[0]) {
                    $file = \dirname((new \ReflectionClass($class))->getFileName(), 2).'/autoload.php';

                    if (null !== $this->targetDirRegex && preg_match($this->targetDirRegex.'A', $file)) {
                        return $file;
                    }
                }
            }
        }

        return $file;
    }

    private function getClasses(Definition $definition, string $id): array
    {
        $classes = [];

        while ($definition instanceof Definition) {
            foreach ($definition->getTag($this->preloadTags[0]) as $tag) {
                if (!isset($tag['class'])) {
                    throw new InvalidArgumentException(sprintf('Missing attribute "class" on tag "%s" for service "%s".', $this->preloadTags[0], $id));
                }

                $classes[] = trim($tag['class'], '\\');
            }

            $classes[] = trim($definition->getClass(), '\\');
            $factory = $definition->getFactory();

            if (!\is_array($factory)) {
                $factory = [$factory];
            }

            if (\is_string($factory[0])) {
                if (false !== $i = strrpos($factory[0], '::')) {
                    $factory[0] = substr($factory[0], 0, $i);
                }
                $classes[] = trim($factory[0], '\\');
            }

            $definition = $factory[0];
        }

        return array_filter($classes);
    }
}
PKϤ$Z���b88)dependency-injection/Dumper/Preloader.phpnu�[���<?php

/*
 * This file is part of the Symfony package.
 *
 * (c) Fabien Potencier <fabien@symfony.com>
 *
 * For the full copyright and license information, please view the LICENSE
 * file that was distributed with this source code.
 */

namespace Symfony\Component\DependencyInjection\Dumper;

/**
 * @author Nicolas Grekas <p@tchwork.com>
 */
final class Preloader
{
    public static function append(string $file, array $list): void
    {
        if (!file_exists($file)) {
            throw new \LogicException(sprintf('File "%s" does not exist.', $file));
        }

        $cacheDir = \dirname($file);
        $classes = [];

        foreach ($list as $item) {
            if (0 === strpos($item, $cacheDir)) {
                file_put_contents($file, sprintf("require_once __DIR__.%s;\n", var_export(strtr(substr($item, \strlen($cacheDir)), \DIRECTORY_SEPARATOR, '/'), true)), \FILE_APPEND);
                continue;
            }

            $classes[] = sprintf("\$classes[] = %s;\n", var_export($item, true));
        }

        file_put_contents($file, sprintf("\n\$classes = [];\n%sPreloader::preload(\$classes);\n", implode('', $classes)), \FILE_APPEND);
    }

    public static function preload(array $classes): void
    {
        set_error_handler(function ($t, $m, $f, $l) {
            if (error_reporting() & $t) {
                if (__FILE__ !== $f) {
                    throw new \ErrorException($m, 0, $t, $f, $l);
                }

                throw new \ReflectionException($m);
            }
        });

        $prev = [];
        $preloaded = [];

        try {
            while ($prev !== $classes) {
                $prev = $classes;
                foreach ($classes as $c) {
                    if (!isset($preloaded[$c])) {
                        self::doPreload($c, $preloaded);
                    }
                }
                $classes = array_merge(get_declared_classes(), get_declared_interfaces(), get_declared_traits());
            }
        } finally {
            restore_error_handler();
        }
    }

    private static function doPreload(string $class, array &$preloaded): void
    {
        if (isset($preloaded[$class]) || \in_array($class, ['self', 'static', 'parent'], true)) {
            return;
        }

        $preloaded[$class] = true;

        try {
            $r = new \ReflectionClass($class);

            if ($r->isInternal()) {
                return;
            }

            $r->getConstants();
            $r->getDefaultProperties();

            if (\PHP_VERSION_ID >= 70400) {
                foreach ($r->getProperties(\ReflectionProperty::IS_PUBLIC) as $p) {
                    self::preloadType($p->getType(), $preloaded);
                }
            }

            foreach ($r->getMethods(\ReflectionMethod::IS_PUBLIC) as $m) {
                foreach ($m->getParameters() as $p) {
                    if ($p->isDefaultValueAvailable() && $p->isDefaultValueConstant()) {
                        $c = $p->getDefaultValueConstantName();

                        if ($i = strpos($c, '::')) {
                            self::doPreload(substr($c, 0, $i), $preloaded);
                        }
                    }

                    self::preloadType($p->getType(), $preloaded);
                }

                self::preloadType($m->getReturnType(), $preloaded);
            }
        } catch (\ReflectionException $e) {
            // ignore missing classes
        }
    }

    private static function preloadType(?\ReflectionType $t, array &$preloaded): void
    {
        if (!$t || $t->isBuiltin()) {
            return;
        }

        foreach ($t instanceof \ReflectionUnionType ? $t->getTypes() : [$t] as $t) {
            if (!$t->isBuiltin()) {
                self::doPreload($t instanceof \ReflectionNamedType ? $t->getName() : $t, $preloaded);
            }
        }
    }
}
PKϤ$Z����77+dependency-injection/ExpressionLanguage.phpnu�[���<?php

/*
 * This file is part of the Symfony package.
 *
 * (c) Fabien Potencier <fabien@symfony.com>
 *
 * For the full copyright and license information, please view the LICENSE
 * file that was distributed with this source code.
 */

namespace Symfony\Component\DependencyInjection;

use Psr\Cache\CacheItemPoolInterface;
use Symfony\Component\ExpressionLanguage\ExpressionLanguage as BaseExpressionLanguage;

if (!class_exists(BaseExpressionLanguage::class)) {
    return;
}

/**
 * Adds some function to the default ExpressionLanguage.
 *
 * @author Fabien Potencier <fabien@symfony.com>
 *
 * @see ExpressionLanguageProvider
 */
class ExpressionLanguage extends BaseExpressionLanguage
{
    /**
     * {@inheritdoc}
     */
    public function __construct(CacheItemPoolInterface $cache = null, array $providers = [], callable $serviceCompiler = null)
    {
        // prepend the default provider to let users override it easily
        array_unshift($providers, new ExpressionLanguageProvider($serviceCompiler));

        parent::__construct($cache, $providers);
    }
}
PKϤ$Z��E�HHdependency-injection/README.mdnu�[���DependencyInjection Component
=============================

The DependencyInjection component allows you to standardize and centralize the
way objects are constructed in your application.

Resources
---------

  * [Documentation](https://symfony.com/doc/current/components/dependency_injection.html)
  * [Contributing](https://symfony.com/doc/current/contributing/index.html)
  * [Report issues](https://github.com/symfony/symfony/issues) and
    [send Pull Requests](https://github.com/symfony/symfony/pulls)
    in the [main Symfony repository](https://github.com/symfony/symfony)
PKϤ$Zy$�f��?dependency-injection/Compiler/RemoveAbstractDefinitionsPass.phpnu�[���<?php

/*
 * This file is part of the Symfony package.
 *
 * (c) Fabien Potencier <fabien@symfony.com>
 *
 * For the full copyright and license information, please view the LICENSE
 * file that was distributed with this source code.
 */

namespace Symfony\Component\DependencyInjection\Compiler;

use Symfony\Component\DependencyInjection\ContainerBuilder;

/**
 * Removes abstract Definitions.
 */
class RemoveAbstractDefinitionsPass implements CompilerPassInterface
{
    /**
     * Removes abstract definitions from the ContainerBuilder.
     */
    public function process(ContainerBuilder $container)
    {
        foreach ($container->getDefinitions() as $id => $definition) {
            if ($definition->isAbstract()) {
                $container->removeDefinition($id);
                $container->log($this, sprintf('Removed service "%s"; reason: abstract.', $id));
            }
        }
    }
}
PKϤ$Zʶ�]];dependency-injection/Compiler/ResolveDecoratorStackPass.phpnu�[���<?php

/*
 * This file is part of the Symfony package.
 *
 * (c) Fabien Potencier <fabien@symfony.com>
 *
 * For the full copyright and license information, please view the LICENSE
 * file that was distributed with this source code.
 */

namespace Symfony\Component\DependencyInjection\Compiler;

use Symfony\Component\DependencyInjection\Alias;
use Symfony\Component\DependencyInjection\ChildDefinition;
use Symfony\Component\DependencyInjection\ContainerBuilder;
use Symfony\Component\DependencyInjection\Definition;
use Symfony\Component\DependencyInjection\Exception\InvalidArgumentException;
use Symfony\Component\DependencyInjection\Exception\ServiceCircularReferenceException;
use Symfony\Component\DependencyInjection\Reference;

/**
 * @author Nicolas Grekas <p@tchwork.com>
 */
class ResolveDecoratorStackPass implements CompilerPassInterface
{
    private $tag;

    public function __construct(string $tag = 'container.stack')
    {
        $this->tag = $tag;
    }

    public function process(ContainerBuilder $container)
    {
        $stacks = [];

        foreach ($container->findTaggedServiceIds($this->tag) as $id => $tags) {
            $definition = $container->getDefinition($id);

            if (!$definition instanceof ChildDefinition) {
                throw new InvalidArgumentException(sprintf('Invalid service "%s": only definitions with a "parent" can have the "%s" tag.', $id, $this->tag));
            }

            if (!$stack = $definition->getArguments()) {
                throw new InvalidArgumentException(sprintf('Invalid service "%s": the stack of decorators is empty.', $id));
            }

            $stacks[$id] = $stack;
        }

        if (!$stacks) {
            return;
        }

        $resolvedDefinitions = [];

        foreach ($container->getDefinitions() as $id => $definition) {
            if (!isset($stacks[$id])) {
                $resolvedDefinitions[$id] = $definition;
                continue;
            }

            foreach (array_reverse($this->resolveStack($stacks, [$id]), true) as $k => $v) {
                $resolvedDefinitions[$k] = $v;
            }

            $alias = $container->setAlias($id, $k);

            if ($definition->getChanges()['public'] ?? false) {
                $alias->setPublic($definition->isPublic());
            }

            if ($definition->isDeprecated()) {
                $alias->setDeprecated(...array_values($definition->getDeprecation('%alias_id%')));
            }
        }

        $container->setDefinitions($resolvedDefinitions);
    }

    private function resolveStack(array $stacks, array $path): array
    {
        $definitions = [];
        $id = end($path);
        $prefix = '.'.$id.'.';

        if (!isset($stacks[$id])) {
            return [$id => new ChildDefinition($id)];
        }

        if (key($path) !== $searchKey = array_search($id, $path)) {
            throw new ServiceCircularReferenceException($id, \array_slice($path, $searchKey));
        }

        foreach ($stacks[$id] as $k => $definition) {
            if ($definition instanceof ChildDefinition && isset($stacks[$definition->getParent()])) {
                $path[] = $definition->getParent();
                $definition = unserialize(serialize($definition)); // deep clone
            } elseif ($definition instanceof Definition) {
                $definitions[$decoratedId = $prefix.$k] = $definition;
                continue;
            } elseif ($definition instanceof Reference || $definition instanceof Alias) {
                $path[] = (string) $definition;
            } else {
                throw new InvalidArgumentException(sprintf('Invalid service "%s": unexpected value of type "%s" found in the stack of decorators.', $id, get_debug_type($definition)));
            }

            $p = $prefix.$k;

            foreach ($this->resolveStack($stacks, $path) as $k => $v) {
                $definitions[$decoratedId = $p.$k] = $definition instanceof ChildDefinition ? $definition->setParent($k) : new ChildDefinition($k);
                $definition = null;
            }
            array_pop($path);
        }

        if (1 === \count($path)) {
            foreach ($definitions as $k => $definition) {
                $definition->setPublic(false)->setTags([])->setDecoratedService($decoratedId);
            }
            $definition->setDecoratedService(null);
        }

        return $definitions;
    }
}
PKϤ$Zj�����5dependency-injection/Compiler/ResolvePrivatesPass.phpnu�[���<?php

/*
 * This file is part of the Symfony package.
 *
 * (c) Fabien Potencier <fabien@symfony.com>
 *
 * For the full copyright and license information, please view the LICENSE
 * file that was distributed with this source code.
 */

namespace Symfony\Component\DependencyInjection\Compiler;

use Symfony\Component\DependencyInjection\ContainerBuilder;

/**
 * @author Nicolas Grekas <p@tchwork.com>
 */
class ResolvePrivatesPass implements CompilerPassInterface
{
    /**
     * {@inheritdoc}
     */
    public function process(ContainerBuilder $container)
    {
        foreach ($container->getDefinitions() as $id => $definition) {
            if ($definition->isPrivate()) {
                $definition->setPublic(false);
                $definition->setPrivate(true);
            }
        }

        foreach ($container->getAliases() as $id => $alias) {
            if ($alias->isPrivate()) {
                $alias->setPublic(false);
                $alias->setPrivate(true);
            }
        }
    }
}
PKϤ$Z� ^^6dependency-injection/Compiler/AutoAliasServicePass.phpnu�[���<?php

/*
 * This file is part of the Symfony package.
 *
 * (c) Fabien Potencier <fabien@symfony.com>
 *
 * For the full copyright and license information, please view the LICENSE
 * file that was distributed with this source code.
 */

namespace Symfony\Component\DependencyInjection\Compiler;

use Symfony\Component\DependencyInjection\Alias;
use Symfony\Component\DependencyInjection\ContainerBuilder;
use Symfony\Component\DependencyInjection\Exception\InvalidArgumentException;

/**
 * Sets a service to be an alias of another one, given a format pattern.
 */
class AutoAliasServicePass implements CompilerPassInterface
{
    /**
     * {@inheritdoc}
     */
    public function process(ContainerBuilder $container)
    {
        foreach ($container->findTaggedServiceIds('auto_alias') as $serviceId => $tags) {
            foreach ($tags as $tag) {
                if (!isset($tag['format'])) {
                    throw new InvalidArgumentException(sprintf('Missing tag information "format" on auto_alias service "%s".', $serviceId));
                }

                $aliasId = $container->getParameterBag()->resolveValue($tag['format']);
                if ($container->hasDefinition($aliasId) || $container->hasAlias($aliasId)) {
                    $container->setAlias($serviceId, new Alias($aliasId, true));
                }
            }
        }
    }
}
PKϤ$Z��y���,dependency-injection/Compiler/PassConfig.phpnu�[���<?php

/*
 * This file is part of the Symfony package.
 *
 * (c) Fabien Potencier <fabien@symfony.com>
 *
 * For the full copyright and license information, please view the LICENSE
 * file that was distributed with this source code.
 */

namespace Symfony\Component\DependencyInjection\Compiler;

use Symfony\Component\DependencyInjection\Exception\InvalidArgumentException;

/**
 * Compiler Pass Configuration.
 *
 * This class has a default configuration embedded.
 *
 * @author Johannes M. Schmitt <schmittjoh@gmail.com>
 */
class PassConfig
{
    const TYPE_AFTER_REMOVING = 'afterRemoving';
    const TYPE_BEFORE_OPTIMIZATION = 'beforeOptimization';
    const TYPE_BEFORE_REMOVING = 'beforeRemoving';
    const TYPE_OPTIMIZE = 'optimization';
    const TYPE_REMOVE = 'removing';

    private $mergePass;
    private $afterRemovingPasses = [];
    private $beforeOptimizationPasses = [];
    private $beforeRemovingPasses = [];
    private $optimizationPasses;
    private $removingPasses;

    public function __construct()
    {
        $this->mergePass = new MergeExtensionConfigurationPass();

        $this->beforeOptimizationPasses = [
            100 => [
                new ResolveClassPass(),
                new ResolveInstanceofConditionalsPass(),
                new RegisterEnvVarProcessorsPass(),
            ],
            -1000 => [new ExtensionCompilerPass()],
        ];

        $this->optimizationPasses = [[
            new AutoAliasServicePass(),
            new ValidateEnvPlaceholdersPass(),
            new ResolveDecoratorStackPass(),
            new ResolveChildDefinitionsPass(),
            new RegisterServiceSubscribersPass(),
            new ResolveParameterPlaceHoldersPass(false, false),
            new ResolveFactoryClassPass(),
            new ResolveNamedArgumentsPass(),
            new AutowireRequiredMethodsPass(),
            new AutowireRequiredPropertiesPass(),
            new ResolveBindingsPass(),
            new ServiceLocatorTagPass(),
            new DecoratorServicePass(),
            new CheckDefinitionValidityPass(),
            new AutowirePass(false),
            new ResolveTaggedIteratorArgumentPass(),
            new ResolveServiceSubscribersPass(),
            new ResolveReferencesToAliasesPass(),
            new ResolveInvalidReferencesPass(),
            new AnalyzeServiceReferencesPass(true),
            new CheckCircularReferencesPass(),
            new CheckReferenceValidityPass(),
            new CheckArgumentsValidityPass(false),
        ]];

        $this->beforeRemovingPasses = [
            -100 => [
                new ResolvePrivatesPass(),
            ],
        ];

        $this->removingPasses = [[
            new RemovePrivateAliasesPass(),
            new ReplaceAliasByActualDefinitionPass(),
            new RemoveAbstractDefinitionsPass(),
            new RemoveUnusedDefinitionsPass(),
            new InlineServiceDefinitionsPass(new AnalyzeServiceReferencesPass()),
            new AnalyzeServiceReferencesPass(),
            new DefinitionErrorExceptionPass(),
        ]];

        $this->afterRemovingPasses = [[
            new CheckExceptionOnInvalidReferenceBehaviorPass(),
            new ResolveHotPathPass(),
            new ResolveNoPreloadPass(),
            new AliasDeprecatedPublicServicesPass(),
        ]];
    }

    /**
     * Returns all passes in order to be processed.
     *
     * @return CompilerPassInterface[]
     */
    public function getPasses()
    {
        return array_merge(
            [$this->mergePass],
            $this->getBeforeOptimizationPasses(),
            $this->getOptimizationPasses(),
            $this->getBeforeRemovingPasses(),
            $this->getRemovingPasses(),
            $this->getAfterRemovingPasses()
        );
    }

    /**
     * Adds a pass.
     *
     * @throws InvalidArgumentException when a pass type doesn't exist
     */
    public function addPass(CompilerPassInterface $pass, string $type = self::TYPE_BEFORE_OPTIMIZATION, int $priority = 0)
    {
        $property = $type.'Passes';
        if (!isset($this->$property)) {
            throw new InvalidArgumentException(sprintf('Invalid type "%s".', $type));
        }

        $passes = &$this->$property;

        if (!isset($passes[$priority])) {
            $passes[$priority] = [];
        }
        $passes[$priority][] = $pass;
    }

    /**
     * Gets all passes for the AfterRemoving pass.
     *
     * @return CompilerPassInterface[]
     */
    public function getAfterRemovingPasses()
    {
        return $this->sortPasses($this->afterRemovingPasses);
    }

    /**
     * Gets all passes for the BeforeOptimization pass.
     *
     * @return CompilerPassInterface[]
     */
    public function getBeforeOptimizationPasses()
    {
        return $this->sortPasses($this->beforeOptimizationPasses);
    }

    /**
     * Gets all passes for the BeforeRemoving pass.
     *
     * @return CompilerPassInterface[]
     */
    public function getBeforeRemovingPasses()
    {
        return $this->sortPasses($this->beforeRemovingPasses);
    }

    /**
     * Gets all passes for the Optimization pass.
     *
     * @return CompilerPassInterface[]
     */
    public function getOptimizationPasses()
    {
        return $this->sortPasses($this->optimizationPasses);
    }

    /**
     * Gets all passes for the Removing pass.
     *
     * @return CompilerPassInterface[]
     */
    public function getRemovingPasses()
    {
        return $this->sortPasses($this->removingPasses);
    }

    /**
     * Gets the Merge pass.
     *
     * @return CompilerPassInterface
     */
    public function getMergePass()
    {
        return $this->mergePass;
    }

    public function setMergePass(CompilerPassInterface $pass)
    {
        $this->mergePass = $pass;
    }

    /**
     * Sets the AfterRemoving passes.
     *
     * @param CompilerPassInterface[] $passes
     */
    public function setAfterRemovingPasses(array $passes)
    {
        $this->afterRemovingPasses = [$passes];
    }

    /**
     * Sets the BeforeOptimization passes.
     *
     * @param CompilerPassInterface[] $passes
     */
    public function setBeforeOptimizationPasses(array $passes)
    {
        $this->beforeOptimizationPasses = [$passes];
    }

    /**
     * Sets the BeforeRemoving passes.
     *
     * @param CompilerPassInterface[] $passes
     */
    public function setBeforeRemovingPasses(array $passes)
    {
        $this->beforeRemovingPasses = [$passes];
    }

    /**
     * Sets the Optimization passes.
     *
     * @param CompilerPassInterface[] $passes
     */
    public function setOptimizationPasses(array $passes)
    {
        $this->optimizationPasses = [$passes];
    }

    /**
     * Sets the Removing passes.
     *
     * @param CompilerPassInterface[] $passes
     */
    public function setRemovingPasses(array $passes)
    {
        $this->removingPasses = [$passes];
    }

    /**
     * Sort passes by priority.
     *
     * @param array $passes CompilerPassInterface instances with their priority as key
     *
     * @return CompilerPassInterface[]
     */
    private function sortPasses(array $passes): array
    {
        if (0 === \count($passes)) {
            return [];
        }

        krsort($passes);

        // Flatten the array
        return array_merge(...$passes);
    }
}
PKϤ$ZFZ�W	W	;dependency-injection/Compiler/ServiceReferenceGraphNode.phpnu�[���<?php

/*
 * This file is part of the Symfony package.
 *
 * (c) Fabien Potencier <fabien@symfony.com>
 *
 * For the full copyright and license information, please view the LICENSE
 * file that was distributed with this source code.
 */

namespace Symfony\Component\DependencyInjection\Compiler;

use Symfony\Component\DependencyInjection\Alias;
use Symfony\Component\DependencyInjection\Definition;

/**
 * Represents a node in your service graph.
 *
 * Value is typically a definition, or an alias.
 *
 * @author Johannes M. Schmitt <schmittjoh@gmail.com>
 */
class ServiceReferenceGraphNode
{
    private $id;
    private $inEdges = [];
    private $outEdges = [];
    private $value;

    /**
     * @param string $id    The node identifier
     * @param mixed  $value The node value
     */
    public function __construct(string $id, $value)
    {
        $this->id = $id;
        $this->value = $value;
    }

    public function addInEdge(ServiceReferenceGraphEdge $edge)
    {
        $this->inEdges[] = $edge;
    }

    public function addOutEdge(ServiceReferenceGraphEdge $edge)
    {
        $this->outEdges[] = $edge;
    }

    /**
     * Checks if the value of this node is an Alias.
     *
     * @return bool True if the value is an Alias instance
     */
    public function isAlias()
    {
        return $this->value instanceof Alias;
    }

    /**
     * Checks if the value of this node is a Definition.
     *
     * @return bool True if the value is a Definition instance
     */
    public function isDefinition()
    {
        return $this->value instanceof Definition;
    }

    /**
     * Returns the identifier.
     *
     * @return string
     */
    public function getId()
    {
        return $this->id;
    }

    /**
     * Returns the in edges.
     *
     * @return ServiceReferenceGraphEdge[]
     */
    public function getInEdges()
    {
        return $this->inEdges;
    }

    /**
     * Returns the out edges.
     *
     * @return ServiceReferenceGraphEdge[]
     */
    public function getOutEdges()
    {
        return $this->outEdges;
    }

    /**
     * Returns the value of this Node.
     *
     * @return mixed The value
     */
    public function getValue()
    {
        return $this->value;
    }

    /**
     * Clears all edges.
     */
    public function clear()
    {
        $this->inEdges = $this->outEdges = [];
    }
}
PKϤ$Z�;/�ee?dependency-injection/Compiler/ResolveServiceSubscribersPass.phpnu�[���<?php

/*
 * This file is part of the Symfony package.
 *
 * (c) Fabien Potencier <fabien@symfony.com>
 *
 * For the full copyright and license information, please view the LICENSE
 * file that was distributed with this source code.
 */

namespace Symfony\Component\DependencyInjection\Compiler;

use Psr\Container\ContainerInterface;
use Symfony\Component\DependencyInjection\Definition;
use Symfony\Component\DependencyInjection\Reference;
use Symfony\Contracts\Service\ServiceProviderInterface;

/**
 * Compiler pass to inject their service locator to service subscribers.
 *
 * @author Nicolas Grekas <p@tchwork.com>
 */
class ResolveServiceSubscribersPass extends AbstractRecursivePass
{
    private $serviceLocator;

    protected function processValue($value, bool $isRoot = false)
    {
        if ($value instanceof Reference && $this->serviceLocator && \in_array((string) $value, [ContainerInterface::class, ServiceProviderInterface::class], true)) {
            return new Reference($this->serviceLocator);
        }

        if (!$value instanceof Definition) {
            return parent::processValue($value, $isRoot);
        }

        $serviceLocator = $this->serviceLocator;
        $this->serviceLocator = null;

        if ($value->hasTag('container.service_subscriber.locator')) {
            $this->serviceLocator = $value->getTag('container.service_subscriber.locator')[0]['id'];
            $value->clearTag('container.service_subscriber.locator');
        }

        try {
            return parent::processValue($value);
        } finally {
            $this->serviceLocator = $serviceLocator;
        }
    }
}
PKϤ$Z�vu��Cdependency-injection/Compiler/ResolveTaggedIteratorArgumentPass.phpnu�[���<?php

/*
 * This file is part of the Symfony package.
 *
 * (c) Fabien Potencier <fabien@symfony.com>
 *
 * For the full copyright and license information, please view the LICENSE
 * file that was distributed with this source code.
 */

namespace Symfony\Component\DependencyInjection\Compiler;

use Symfony\Component\DependencyInjection\Argument\TaggedIteratorArgument;

/**
 * Resolves all TaggedIteratorArgument arguments.
 *
 * @author Roland Franssen <franssen.roland@gmail.com>
 */
class ResolveTaggedIteratorArgumentPass extends AbstractRecursivePass
{
    use PriorityTaggedServiceTrait;

    /**
     * {@inheritdoc}
     */
    protected function processValue($value, bool $isRoot = false)
    {
        if (!$value instanceof TaggedIteratorArgument) {
            return parent::processValue($value, $isRoot);
        }

        $value->setValues($this->findAndSortTaggedServices($value, $this->container));

        return $value;
    }
}
PKϤ$Z^����>dependency-injection/Compiler/ResolveInvalidReferencesPass.phpnu�[���<?php

/*
 * This file is part of the Symfony package.
 *
 * (c) Fabien Potencier <fabien@symfony.com>
 *
 * For the full copyright and license information, please view the LICENSE
 * file that was distributed with this source code.
 */

namespace Symfony\Component\DependencyInjection\Compiler;

use Symfony\Component\DependencyInjection\Argument\ArgumentInterface;
use Symfony\Component\DependencyInjection\Argument\ServiceClosureArgument;
use Symfony\Component\DependencyInjection\ContainerBuilder;
use Symfony\Component\DependencyInjection\ContainerInterface;
use Symfony\Component\DependencyInjection\Definition;
use Symfony\Component\DependencyInjection\Exception\RuntimeException;
use Symfony\Component\DependencyInjection\Exception\ServiceNotFoundException;
use Symfony\Component\DependencyInjection\Reference;
use Symfony\Component\DependencyInjection\TypedReference;

/**
 * Emulates the invalid behavior if the reference is not found within the
 * container.
 *
 * @author Johannes M. Schmitt <schmittjoh@gmail.com>
 */
class ResolveInvalidReferencesPass implements CompilerPassInterface
{
    private $container;
    private $signalingException;
    private $currentId;

    /**
     * Process the ContainerBuilder to resolve invalid references.
     */
    public function process(ContainerBuilder $container)
    {
        $this->container = $container;
        $this->signalingException = new RuntimeException('Invalid reference.');

        try {
            foreach ($container->getDefinitions() as $this->currentId => $definition) {
                $this->processValue($definition);
            }
        } finally {
            $this->container = $this->signalingException = null;
        }
    }

    /**
     * Processes arguments to determine invalid references.
     *
     * @return mixed
     *
     * @throws RuntimeException When an invalid reference is found
     */
    private function processValue($value, int $rootLevel = 0, int $level = 0)
    {
        if ($value instanceof ServiceClosureArgument) {
            $value->setValues($this->processValue($value->getValues(), 1, 1));
        } elseif ($value instanceof ArgumentInterface) {
            $value->setValues($this->processValue($value->getValues(), $rootLevel, 1 + $level));
        } elseif ($value instanceof Definition) {
            if ($value->isSynthetic() || $value->isAbstract()) {
                return $value;
            }
            $value->setArguments($this->processValue($value->getArguments(), 0));
            $value->setProperties($this->processValue($value->getProperties(), 1));
            $value->setMethodCalls($this->processValue($value->getMethodCalls(), 2));
        } elseif (\is_array($value)) {
            $i = 0;

            foreach ($value as $k => $v) {
                try {
                    if (false !== $i && $k !== $i++) {
                        $i = false;
                    }
                    if ($v !== $processedValue = $this->processValue($v, $rootLevel, 1 + $level)) {
                        $value[$k] = $processedValue;
                    }
                } catch (RuntimeException $e) {
                    if ($rootLevel < $level || ($rootLevel && !$level)) {
                        unset($value[$k]);
                    } elseif ($rootLevel) {
                        throw $e;
                    } else {
                        $value[$k] = null;
                    }
                }
            }

            // Ensure numerically indexed arguments have sequential numeric keys.
            if (false !== $i) {
                $value = array_values($value);
            }
        } elseif ($value instanceof Reference) {
            if ($this->container->has($id = (string) $value)) {
                return $value;
            }

            $currentDefinition = $this->container->getDefinition($this->currentId);

            // resolve decorated service behavior depending on decorator service
            if ($currentDefinition->innerServiceId === $id && ContainerInterface::NULL_ON_INVALID_REFERENCE === $currentDefinition->decorationOnInvalid) {
                return null;
            }

            $invalidBehavior = $value->getInvalidBehavior();

            if (ContainerInterface::RUNTIME_EXCEPTION_ON_INVALID_REFERENCE === $invalidBehavior && $value instanceof TypedReference && !$this->container->has($id)) {
                $e = new ServiceNotFoundException($id, $this->currentId);

                // since the error message varies by $id and $this->currentId, so should the id of the dummy errored definition
                $this->container->register($id = sprintf('.errored.%s.%s', $this->currentId, $id), $value->getType())
                    ->addError($e->getMessage());

                return new TypedReference($id, $value->getType(), $value->getInvalidBehavior());
            }

            // resolve invalid behavior
            if (ContainerInterface::NULL_ON_INVALID_REFERENCE === $invalidBehavior) {
                $value = null;
            } elseif (ContainerInterface::IGNORE_ON_INVALID_REFERENCE === $invalidBehavior) {
                if (0 < $level || $rootLevel) {
                    throw $this->signalingException;
                }
                $value = null;
            }
        }

        return $value;
    }
}
PKϤ$Z�s�B B 7dependency-injection/Compiler/AbstractRecursivePass.phpnu�[���<?php

/*
 * This file is part of the Symfony package.
 *
 * (c) Fabien Potencier <fabien@symfony.com>
 *
 * For the full copyright and license information, please view the LICENSE
 * file that was distributed with this source code.
 */

namespace Symfony\Component\DependencyInjection\Compiler;

use Symfony\Component\DependencyInjection\Argument\ArgumentInterface;
use Symfony\Component\DependencyInjection\ContainerBuilder;
use Symfony\Component\DependencyInjection\Definition;
use Symfony\Component\DependencyInjection\Exception\LogicException;
use Symfony\Component\DependencyInjection\Exception\RuntimeException;
use Symfony\Component\DependencyInjection\ExpressionLanguage;
use Symfony\Component\DependencyInjection\Reference;
use Symfony\Component\ExpressionLanguage\Expression;

/**
 * @author Nicolas Grekas <p@tchwork.com>
 */
abstract class AbstractRecursivePass implements CompilerPassInterface
{
    /**
     * @var ContainerBuilder
     */
    protected $container;
    protected $currentId;

    private $processExpressions = false;
    private $expressionLanguage;
    private $inExpression = false;

    /**
     * {@inheritdoc}
     */
    public function process(ContainerBuilder $container)
    {
        $this->container = $container;

        try {
            $this->processValue($container->getDefinitions(), true);
        } finally {
            $this->container = null;
        }
    }

    protected function enableExpressionProcessing()
    {
        $this->processExpressions = true;
    }

    protected function inExpression(bool $reset = true): bool
    {
        $inExpression = $this->inExpression;
        if ($reset) {
            $this->inExpression = false;
        }

        return $inExpression;
    }

    /**
     * Processes a value found in a definition tree.
     *
     * @param mixed $value
     *
     * @return mixed The processed value
     */
    protected function processValue($value, bool $isRoot = false)
    {
        if (\is_array($value)) {
            foreach ($value as $k => $v) {
                if ($isRoot) {
                    $this->currentId = $k;
                }
                if ($v !== $processedValue = $this->processValue($v, $isRoot)) {
                    $value[$k] = $processedValue;
                }
            }
        } elseif ($value instanceof ArgumentInterface) {
            $value->setValues($this->processValue($value->getValues()));
        } elseif ($value instanceof Expression && $this->processExpressions) {
            $this->getExpressionLanguage()->compile((string) $value, ['this' => 'container']);
        } elseif ($value instanceof Definition) {
            $value->setArguments($this->processValue($value->getArguments()));
            $value->setProperties($this->processValue($value->getProperties()));
            $value->setMethodCalls($this->processValue($value->getMethodCalls()));

            $changes = $value->getChanges();
            if (isset($changes['factory'])) {
                $value->setFactory($this->processValue($value->getFactory()));
            }
            if (isset($changes['configurator'])) {
                $value->setConfigurator($this->processValue($value->getConfigurator()));
            }
        }

        return $value;
    }

    /**
     * @return \ReflectionFunctionAbstract|null
     *
     * @throws RuntimeException
     */
    protected function getConstructor(Definition $definition, bool $required)
    {
        if ($definition->isSynthetic()) {
            return null;
        }

        if (\is_string($factory = $definition->getFactory())) {
            if (!\function_exists($factory)) {
                throw new RuntimeException(sprintf('Invalid service "%s": function "%s" does not exist.', $this->currentId, $factory));
            }
            $r = new \ReflectionFunction($factory);
            if (false !== $r->getFileName() && file_exists($r->getFileName())) {
                $this->container->fileExists($r->getFileName());
            }

            return $r;
        }

        if ($factory) {
            list($class, $method) = $factory;
            if ($class instanceof Reference) {
                $class = $this->container->findDefinition((string) $class)->getClass();
            } elseif ($class instanceof Definition) {
                $class = $class->getClass();
            } elseif (null === $class) {
                $class = $definition->getClass();
            }

            if ('__construct' === $method) {
                throw new RuntimeException(sprintf('Invalid service "%s": "__construct()" cannot be used as a factory method.', $this->currentId));
            }

            return $this->getReflectionMethod(new Definition($class), $method);
        }

        $class = $definition->getClass();

        try {
            if (!$r = $this->container->getReflectionClass($class)) {
                throw new RuntimeException(sprintf('Invalid service "%s": class "%s" does not exist.', $this->currentId, $class));
            }
        } catch (\ReflectionException $e) {
            throw new RuntimeException(sprintf('Invalid service "%s": ', $this->currentId).lcfirst($e->getMessage()));
        }
        if (!$r = $r->getConstructor()) {
            if ($required) {
                throw new RuntimeException(sprintf('Invalid service "%s": class%s has no constructor.', $this->currentId, sprintf($class !== $this->currentId ? ' "%s"' : '', $class)));
            }
        } elseif (!$r->isPublic()) {
            throw new RuntimeException(sprintf('Invalid service "%s": ', $this->currentId).sprintf($class !== $this->currentId ? 'constructor of class "%s"' : 'its constructor', $class).' must be public.');
        }

        return $r;
    }

    /**
     * @throws RuntimeException
     *
     * @return \ReflectionFunctionAbstract
     */
    protected function getReflectionMethod(Definition $definition, string $method)
    {
        if ('__construct' === $method) {
            return $this->getConstructor($definition, true);
        }

        if (!$class = $definition->getClass()) {
            throw new RuntimeException(sprintf('Invalid service "%s": the class is not set.', $this->currentId));
        }

        if (!$r = $this->container->getReflectionClass($class)) {
            throw new RuntimeException(sprintf('Invalid service "%s": class "%s" does not exist.', $this->currentId, $class));
        }

        if (!$r->hasMethod($method)) {
            throw new RuntimeException(sprintf('Invalid service "%s": method "%s()" does not exist.', $this->currentId, $class !== $this->currentId ? $class.'::'.$method : $method));
        }

        $r = $r->getMethod($method);
        if (!$r->isPublic()) {
            throw new RuntimeException(sprintf('Invalid service "%s": method "%s()" must be public.', $this->currentId, $class !== $this->currentId ? $class.'::'.$method : $method));
        }

        return $r;
    }

    private function getExpressionLanguage(): ExpressionLanguage
    {
        if (null === $this->expressionLanguage) {
            if (!class_exists(ExpressionLanguage::class)) {
                throw new LogicException('Unable to use expressions as the Symfony ExpressionLanguage component is not installed.');
            }

            $providers = $this->container->getExpressionLanguageProviders();
            $this->expressionLanguage = new ExpressionLanguage(null, $providers, function (string $arg): string {
                if ('""' === substr_replace($arg, '', 1, -1)) {
                    $id = stripcslashes(substr($arg, 1, -1));
                    $this->inExpression = true;
                    $arg = $this->processValue(new Reference($id));
                    $this->inExpression = false;
                    if (!$arg instanceof Reference) {
                        throw new RuntimeException(sprintf('"%s::processValue()" must return a Reference when processing an expression, "%s" returned for service("%s").', static::class, get_debug_type($arg), $id));
                    }
                    $arg = sprintf('"%s"', $arg);
                }

                return sprintf('$this->get(%s)', $arg);
            });
        }

        return $this->expressionLanguage;
    }
}
PKϤ$Z}I!NN>dependency-injection/Compiler/DefinitionErrorExceptionPass.phpnu�[���<?php

/*
 * This file is part of the Symfony package.
 *
 * (c) Fabien Potencier <fabien@symfony.com>
 *
 * For the full copyright and license information, please view the LICENSE
 * file that was distributed with this source code.
 */

namespace Symfony\Component\DependencyInjection\Compiler;

use Symfony\Component\DependencyInjection\ContainerInterface;
use Symfony\Component\DependencyInjection\Definition;
use Symfony\Component\DependencyInjection\Exception\RuntimeException;
use Symfony\Component\DependencyInjection\Reference;

/**
 * Throws an exception for any Definitions that have errors and still exist.
 *
 * @author Ryan Weaver <ryan@knpuniversity.com>
 */
class DefinitionErrorExceptionPass extends AbstractRecursivePass
{
    /**
     * {@inheritdoc}
     */
    protected function processValue($value, bool $isRoot = false)
    {
        if (!$value instanceof Definition || !$value->hasErrors()) {
            return parent::processValue($value, $isRoot);
        }

        if ($isRoot && !$value->isPublic()) {
            $graph = $this->container->getCompiler()->getServiceReferenceGraph();
            $runtimeException = false;
            foreach ($graph->getNode($this->currentId)->getInEdges() as $edge) {
                if (!$edge->getValue() instanceof Reference || ContainerInterface::RUNTIME_EXCEPTION_ON_INVALID_REFERENCE !== $edge->getValue()->getInvalidBehavior()) {
                    $runtimeException = false;
                    break;
                }
                $runtimeException = true;
            }
            if ($runtimeException) {
                return parent::processValue($value, $isRoot);
            }
        }

        // only show the first error so the user can focus on it
        $errors = $value->getErrors();
        $message = reset($errors);

        throw new RuntimeException($message);
    }
}
PKϤ$ZY�GQIQI.dependency-injection/Compiler/AutowirePass.phpnu�[���<?php

/*
 * This file is part of the Symfony package.
 *
 * (c) Fabien Potencier <fabien@symfony.com>
 *
 * For the full copyright and license information, please view the LICENSE
 * file that was distributed with this source code.
 */

namespace Symfony\Component\DependencyInjection\Compiler;

use Symfony\Component\Config\Resource\ClassExistenceResource;
use Symfony\Component\DependencyInjection\ContainerBuilder;
use Symfony\Component\DependencyInjection\Definition;
use Symfony\Component\DependencyInjection\Exception\AutowiringFailedException;
use Symfony\Component\DependencyInjection\Exception\RuntimeException;
use Symfony\Component\DependencyInjection\LazyProxy\ProxyHelper;
use Symfony\Component\DependencyInjection\TypedReference;

/**
 * Inspects existing service definitions and wires the autowired ones using the type hints of their classes.
 *
 * @author Kévin Dunglas <dunglas@gmail.com>
 * @author Nicolas Grekas <p@tchwork.com>
 */
class AutowirePass extends AbstractRecursivePass
{
    private $types;
    private $ambiguousServiceTypes;
    private $lastFailure;
    private $throwOnAutowiringException;
    private $decoratedClass;
    private $decoratedId;
    private $methodCalls;
    private $getPreviousValue;
    private $decoratedMethodIndex;
    private $decoratedMethodArgumentIndex;
    private $typesClone;

    public function __construct(bool $throwOnAutowireException = true)
    {
        $this->throwOnAutowiringException = $throwOnAutowireException;
    }

    /**
     * {@inheritdoc}
     */
    public function process(ContainerBuilder $container)
    {
        try {
            $this->typesClone = clone $this;
            parent::process($container);
        } finally {
            $this->decoratedClass = null;
            $this->decoratedId = null;
            $this->methodCalls = null;
            $this->getPreviousValue = null;
            $this->decoratedMethodIndex = null;
            $this->decoratedMethodArgumentIndex = null;
            $this->typesClone = null;
        }
    }

    /**
     * {@inheritdoc}
     */
    protected function processValue($value, bool $isRoot = false)
    {
        try {
            return $this->doProcessValue($value, $isRoot);
        } catch (AutowiringFailedException $e) {
            if ($this->throwOnAutowiringException) {
                throw $e;
            }

            $this->container->getDefinition($this->currentId)->addError($e->getMessageCallback() ?? $e->getMessage());

            return parent::processValue($value, $isRoot);
        }
    }

    /**
     * @return mixed
     */
    private function doProcessValue($value, bool $isRoot = false)
    {
        if ($value instanceof TypedReference) {
            if ($ref = $this->getAutowiredReference($value)) {
                return $ref;
            }
            if (ContainerBuilder::RUNTIME_EXCEPTION_ON_INVALID_REFERENCE === $value->getInvalidBehavior()) {
                $message = $this->createTypeNotFoundMessageCallback($value, 'it');

                // since the error message varies by referenced id and $this->currentId, so should the id of the dummy errored definition
                $this->container->register($id = sprintf('.errored.%s.%s', $this->currentId, (string) $value), $value->getType())
                    ->addError($message);

                return new TypedReference($id, $value->getType(), $value->getInvalidBehavior(), $value->getName());
            }
        }
        $value = parent::processValue($value, $isRoot);

        if (!$value instanceof Definition || !$value->isAutowired() || $value->isAbstract() || !$value->getClass()) {
            return $value;
        }
        if (!$reflectionClass = $this->container->getReflectionClass($value->getClass(), false)) {
            $this->container->log($this, sprintf('Skipping service "%s": Class or interface "%s" cannot be loaded.', $this->currentId, $value->getClass()));

            return $value;
        }

        $this->methodCalls = $value->getMethodCalls();

        try {
            $constructor = $this->getConstructor($value, false);
        } catch (RuntimeException $e) {
            throw new AutowiringFailedException($this->currentId, $e->getMessage(), 0, $e);
        }

        if ($constructor) {
            array_unshift($this->methodCalls, [$constructor, $value->getArguments()]);
        }

        $this->methodCalls = $this->autowireCalls($reflectionClass, $isRoot);

        if ($constructor) {
            list(, $arguments) = array_shift($this->methodCalls);

            if ($arguments !== $value->getArguments()) {
                $value->setArguments($arguments);
            }
        }

        if ($this->methodCalls !== $value->getMethodCalls()) {
            $value->setMethodCalls($this->methodCalls);
        }

        return $value;
    }

    private function autowireCalls(\ReflectionClass $reflectionClass, bool $isRoot): array
    {
        $this->decoratedId = null;
        $this->decoratedClass = null;
        $this->getPreviousValue = null;

        if ($isRoot && ($definition = $this->container->getDefinition($this->currentId)) && $this->container->has($this->decoratedId = $definition->innerServiceId)) {
            $this->decoratedClass = $this->container->findDefinition($this->decoratedId)->getClass();
        }

        foreach ($this->methodCalls as $i => $call) {
            $this->decoratedMethodIndex = $i;
            list($method, $arguments) = $call;

            if ($method instanceof \ReflectionFunctionAbstract) {
                $reflectionMethod = $method;
            } else {
                $definition = new Definition($reflectionClass->name);
                try {
                    $reflectionMethod = $this->getReflectionMethod($definition, $method);
                } catch (RuntimeException $e) {
                    if ($definition->getFactory()) {
                        continue;
                    }
                    throw $e;
                }
            }

            $arguments = $this->autowireMethod($reflectionMethod, $arguments);

            if ($arguments !== $call[1]) {
                $this->methodCalls[$i][1] = $arguments;
            }
        }

        return $this->methodCalls;
    }

    /**
     * Autowires the constructor or a method.
     *
     * @return array The autowired arguments
     *
     * @throws AutowiringFailedException
     */
    private function autowireMethod(\ReflectionFunctionAbstract $reflectionMethod, array $arguments): array
    {
        $class = $reflectionMethod instanceof \ReflectionMethod ? $reflectionMethod->class : $this->currentId;
        $method = $reflectionMethod->name;
        $parameters = $reflectionMethod->getParameters();
        if ($reflectionMethod->isVariadic()) {
            array_pop($parameters);
        }

        foreach ($parameters as $index => $parameter) {
            if (\array_key_exists($index, $arguments) && '' !== $arguments[$index]) {
                continue;
            }

            $type = ProxyHelper::getTypeHint($reflectionMethod, $parameter, true);

            if (!$type) {
                if (isset($arguments[$index])) {
                    continue;
                }

                // no default value? Then fail
                if (!$parameter->isDefaultValueAvailable()) {
                    // For core classes, isDefaultValueAvailable() can
                    // be false when isOptional() returns true. If the
                    // argument *is* optional, allow it to be missing
                    if ($parameter->isOptional()) {
                        continue;
                    }
                    $type = ProxyHelper::getTypeHint($reflectionMethod, $parameter, false);
                    $type = $type ? sprintf('is type-hinted "%s"', ltrim($type, '\\')) : 'has no type-hint';

                    throw new AutowiringFailedException($this->currentId, sprintf('Cannot autowire service "%s": argument "$%s" of method "%s()" %s, you should configure its value explicitly.', $this->currentId, $parameter->name, $class !== $this->currentId ? $class.'::'.$method : $method, $type));
                }

                // specifically pass the default value
                $arguments[$index] = $parameter->getDefaultValue();

                continue;
            }

            $getValue = function () use ($type, $parameter, $class, $method) {
                if (!$value = $this->getAutowiredReference($ref = new TypedReference($type, $type, ContainerBuilder::EXCEPTION_ON_INVALID_REFERENCE, $parameter->name))) {
                    $failureMessage = $this->createTypeNotFoundMessageCallback($ref, sprintf('argument "$%s" of method "%s()"', $parameter->name, $class !== $this->currentId ? $class.'::'.$method : $method));

                    if ($parameter->isDefaultValueAvailable()) {
                        $value = $parameter->getDefaultValue();
                    } elseif (!$parameter->allowsNull()) {
                        throw new AutowiringFailedException($this->currentId, $failureMessage);
                    }
                }

                return $value;
            };

            if ($this->decoratedClass && $isDecorated = is_a($this->decoratedClass, $type, true)) {
                if ($this->getPreviousValue) {
                    // The inner service is injected only if there is only 1 argument matching the type of the decorated class
                    // across all arguments of all autowired methods.
                    // If a second matching argument is found, the default behavior is restored.

                    $getPreviousValue = $this->getPreviousValue;
                    $this->methodCalls[$this->decoratedMethodIndex][1][$this->decoratedMethodArgumentIndex] = $getPreviousValue();
                    $this->decoratedClass = null; // Prevent further checks
                } else {
                    $arguments[$index] = new TypedReference($this->decoratedId, $this->decoratedClass);
                    $this->getPreviousValue = $getValue;
                    $this->decoratedMethodArgumentIndex = $index;

                    continue;
                }
            }

            $arguments[$index] = $getValue();
        }

        if ($parameters && !isset($arguments[++$index])) {
            while (0 <= --$index) {
                $parameter = $parameters[$index];
                if (!$parameter->isDefaultValueAvailable() || $parameter->getDefaultValue() !== $arguments[$index]) {
                    break;
                }
                unset($arguments[$index]);
            }
        }

        // it's possible index 1 was set, then index 0, then 2, etc
        // make sure that we re-order so they're injected as expected
        ksort($arguments);

        return $arguments;
    }

    /**
     * Returns a reference to the service matching the given type, if any.
     */
    private function getAutowiredReference(TypedReference $reference): ?TypedReference
    {
        $this->lastFailure = null;
        $type = $reference->getType();

        if ($type !== (string) $reference) {
            return $reference;
        }

        if (null !== $name = $reference->getName()) {
            if ($this->container->has($alias = $type.' $'.$name) && !$this->container->findDefinition($alias)->isAbstract()) {
                return new TypedReference($alias, $type, $reference->getInvalidBehavior());
            }

            if ($this->container->has($name) && !$this->container->findDefinition($name)->isAbstract()) {
                foreach ($this->container->getAliases() as $id => $alias) {
                    if ($name === (string) $alias && 0 === strpos($id, $type.' $')) {
                        return new TypedReference($name, $type, $reference->getInvalidBehavior());
                    }
                }
            }
        }

        if ($this->container->has($type) && !$this->container->findDefinition($type)->isAbstract()) {
            return new TypedReference($type, $type, $reference->getInvalidBehavior());
        }

        return null;
    }

    /**
     * Populates the list of available types.
     */
    private function populateAvailableTypes(ContainerBuilder $container)
    {
        $this->types = [];
        $this->ambiguousServiceTypes = [];

        foreach ($container->getDefinitions() as $id => $definition) {
            $this->populateAvailableType($container, $id, $definition);
        }
    }

    /**
     * Populates the list of available types for a given definition.
     */
    private function populateAvailableType(ContainerBuilder $container, string $id, Definition $definition)
    {
        // Never use abstract services
        if ($definition->isAbstract()) {
            return;
        }

        if ('' === $id || '.' === $id[0] || $definition->isDeprecated() || !$reflectionClass = $container->getReflectionClass($definition->getClass(), false)) {
            return;
        }

        foreach ($reflectionClass->getInterfaces() as $reflectionInterface) {
            $this->set($reflectionInterface->name, $id);
        }

        do {
            $this->set($reflectionClass->name, $id);
        } while ($reflectionClass = $reflectionClass->getParentClass());
    }

    /**
     * Associates a type and a service id if applicable.
     */
    private function set(string $type, string $id)
    {
        // is this already a type/class that is known to match multiple services?
        if (isset($this->ambiguousServiceTypes[$type])) {
            $this->ambiguousServiceTypes[$type][] = $id;

            return;
        }

        // check to make sure the type doesn't match multiple services
        if (!isset($this->types[$type]) || $this->types[$type] === $id) {
            $this->types[$type] = $id;

            return;
        }

        // keep an array of all services matching this type
        if (!isset($this->ambiguousServiceTypes[$type])) {
            $this->ambiguousServiceTypes[$type] = [$this->types[$type]];
            unset($this->types[$type]);
        }
        $this->ambiguousServiceTypes[$type][] = $id;
    }

    private function createTypeNotFoundMessageCallback(TypedReference $reference, string $label): callable
    {
        if (null === $this->typesClone->container) {
            $this->typesClone->container = new ContainerBuilder($this->container->getParameterBag());
            $this->typesClone->container->setAliases($this->container->getAliases());
            $this->typesClone->container->setDefinitions($this->container->getDefinitions());
            $this->typesClone->container->setResourceTracking(false);
        }
        $currentId = $this->currentId;

        return (function () use ($reference, $label, $currentId) {
            return $this->createTypeNotFoundMessage($reference, $label, $currentId);
        })->bindTo($this->typesClone);
    }

    private function createTypeNotFoundMessage(TypedReference $reference, string $label, string $currentId): string
    {
        if (!$r = $this->container->getReflectionClass($type = $reference->getType(), false)) {
            // either $type does not exist or a parent class does not exist
            try {
                $resource = new ClassExistenceResource($type, false);
                // isFresh() will explode ONLY if a parent class/trait does not exist
                $resource->isFresh(0);
                $parentMsg = false;
            } catch (\ReflectionException $e) {
                $parentMsg = $e->getMessage();
            }

            $message = sprintf('has type "%s" but this class %s.', $type, $parentMsg ? sprintf('is missing a parent class (%s)', $parentMsg) : 'was not found');
        } else {
            $alternatives = $this->createTypeAlternatives($this->container, $reference);
            $message = $this->container->has($type) ? 'this service is abstract' : 'no such service exists';
            $message = sprintf('references %s "%s" but %s.%s', $r->isInterface() ? 'interface' : 'class', $type, $message, $alternatives);

            if ($r->isInterface() && !$alternatives) {
                $message .= ' Did you create a class that implements this interface?';
            }
        }

        $message = sprintf('Cannot autowire service "%s": %s %s', $currentId, $label, $message);

        if (null !== $this->lastFailure) {
            $message = $this->lastFailure."\n".$message;
            $this->lastFailure = null;
        }

        return $message;
    }

    private function createTypeAlternatives(ContainerBuilder $container, TypedReference $reference): string
    {
        // try suggesting available aliases first
        if ($message = $this->getAliasesSuggestionForType($container, $type = $reference->getType())) {
            return ' '.$message;
        }
        if (null === $this->ambiguousServiceTypes) {
            $this->populateAvailableTypes($container);
        }

        $servicesAndAliases = $container->getServiceIds();
        if (!$container->has($type) && false !== $key = array_search(strtolower($type), array_map('strtolower', $servicesAndAliases))) {
            return sprintf(' Did you mean "%s"?', $servicesAndAliases[$key]);
        } elseif (isset($this->ambiguousServiceTypes[$type])) {
            $message = sprintf('one of these existing services: "%s"', implode('", "', $this->ambiguousServiceTypes[$type]));
        } elseif (isset($this->types[$type])) {
            $message = sprintf('the existing "%s" service', $this->types[$type]);
        } else {
            return '';
        }

        return sprintf(' You should maybe alias this %s to %s.', class_exists($type, false) ? 'class' : 'interface', $message);
    }

    private function getAliasesSuggestionForType(ContainerBuilder $container, string $type): ?string
    {
        $aliases = [];
        foreach (class_parents($type) + class_implements($type) as $parent) {
            if ($container->has($parent) && !$container->findDefinition($parent)->isAbstract()) {
                $aliases[] = $parent;
            }
        }

        if (1 < $len = \count($aliases)) {
            $message = 'Try changing the type-hint to one of its parents: ';
            for ($i = 0, --$len; $i < $len; ++$i) {
                $message .= sprintf('%s "%s", ', class_exists($aliases[$i], false) ? 'class' : 'interface', $aliases[$i]);
            }
            $message .= sprintf('or %s "%s".', class_exists($aliases[$i], false) ? 'class' : 'interface', $aliases[$i]);

            return $message;
        }

        if ($aliases) {
            return sprintf('Try changing the type-hint to "%s" instead.', $aliases[0]);
        }

        return null;
    }
}
PKϤ$Z��|F��<dependency-injection/Compiler/CheckArgumentsValidityPass.phpnu�[���<?php

/*
 * This file is part of the Symfony package.
 *
 * (c) Fabien Potencier <fabien@symfony.com>
 *
 * For the full copyright and license information, please view the LICENSE
 * file that was distributed with this source code.
 */

namespace Symfony\Component\DependencyInjection\Compiler;

use Symfony\Component\DependencyInjection\Definition;
use Symfony\Component\DependencyInjection\Exception\RuntimeException;

/**
 * Checks if arguments of methods are properly configured.
 *
 * @author Kévin Dunglas <dunglas@gmail.com>
 * @author Nicolas Grekas <p@tchwork.com>
 */
class CheckArgumentsValidityPass extends AbstractRecursivePass
{
    private $throwExceptions;

    public function __construct(bool $throwExceptions = true)
    {
        $this->throwExceptions = $throwExceptions;
    }

    /**
     * {@inheritdoc}
     */
    protected function processValue($value, bool $isRoot = false)
    {
        if (!$value instanceof Definition) {
            return parent::processValue($value, $isRoot);
        }

        $i = 0;
        foreach ($value->getArguments() as $k => $v) {
            if ($k !== $i++) {
                if (!\is_int($k)) {
                    $msg = sprintf('Invalid constructor argument for service "%s": integer expected but found string "%s". Check your service definition.', $this->currentId, $k);
                    $value->addError($msg);
                    if ($this->throwExceptions) {
                        throw new RuntimeException($msg);
                    }

                    break;
                }

                $msg = sprintf('Invalid constructor argument %d for service "%s": argument %d must be defined before. Check your service definition.', 1 + $k, $this->currentId, $i);
                $value->addError($msg);
                if ($this->throwExceptions) {
                    throw new RuntimeException($msg);
                }
            }
        }

        foreach ($value->getMethodCalls() as $methodCall) {
            $i = 0;
            foreach ($methodCall[1] as $k => $v) {
                if ($k !== $i++) {
                    if (!\is_int($k)) {
                        $msg = sprintf('Invalid argument for method call "%s" of service "%s": integer expected but found string "%s". Check your service definition.', $methodCall[0], $this->currentId, $k);
                        $value->addError($msg);
                        if ($this->throwExceptions) {
                            throw new RuntimeException($msg);
                        }

                        break;
                    }

                    $msg = sprintf('Invalid argument %d for method call "%s" of service "%s": argument %d must be defined before. Check your service definition.', 1 + $k, $methodCall[0], $this->currentId, $i);
                    $value->addError($msg);
                    if ($this->throwExceptions) {
                        throw new RuntimeException($msg);
                    }
                }
            }
        }

        return null;
    }
}
PKϤ$Z��q��;dependency-injection/Compiler/ServiceReferenceGraphEdge.phpnu�[���<?php

/*
 * This file is part of the Symfony package.
 *
 * (c) Fabien Potencier <fabien@symfony.com>
 *
 * For the full copyright and license information, please view the LICENSE
 * file that was distributed with this source code.
 */

namespace Symfony\Component\DependencyInjection\Compiler;

/**
 * Represents an edge in your service graph.
 *
 * Value is typically a reference.
 *
 * @author Johannes M. Schmitt <schmittjoh@gmail.com>
 */
class ServiceReferenceGraphEdge
{
    private $sourceNode;
    private $destNode;
    private $value;
    private $lazy;
    private $weak;
    private $byConstructor;

    public function __construct(ServiceReferenceGraphNode $sourceNode, ServiceReferenceGraphNode $destNode, $value = null, bool $lazy = false, bool $weak = false, bool $byConstructor = false)
    {
        $this->sourceNode = $sourceNode;
        $this->destNode = $destNode;
        $this->value = $value;
        $this->lazy = $lazy;
        $this->weak = $weak;
        $this->byConstructor = $byConstructor;
    }

    /**
     * Returns the value of the edge.
     *
     * @return mixed
     */
    public function getValue()
    {
        return $this->value;
    }

    /**
     * Returns the source node.
     *
     * @return ServiceReferenceGraphNode
     */
    public function getSourceNode()
    {
        return $this->sourceNode;
    }

    /**
     * Returns the destination node.
     *
     * @return ServiceReferenceGraphNode
     */
    public function getDestNode()
    {
        return $this->destNode;
    }

    /**
     * Returns true if the edge is lazy, meaning it's a dependency not requiring direct instantiation.
     *
     * @return bool
     */
    public function isLazy()
    {
        return $this->lazy;
    }

    /**
     * Returns true if the edge is weak, meaning it shouldn't prevent removing the target service.
     *
     * @return bool
     */
    public function isWeak()
    {
        return $this->weak;
    }

    /**
     * Returns true if the edge links with a constructor argument.
     *
     * @return bool
     */
    public function isReferencedByConstructor()
    {
        return $this->byConstructor;
    }
}
PKϤ$Z����MM=dependency-injection/Compiler/CheckDefinitionValidityPass.phpnu�[���<?php

/*
 * This file is part of the Symfony package.
 *
 * (c) Fabien Potencier <fabien@symfony.com>
 *
 * For the full copyright and license information, please view the LICENSE
 * file that was distributed with this source code.
 */

namespace Symfony\Component\DependencyInjection\Compiler;

use Symfony\Component\DependencyInjection\ContainerBuilder;
use Symfony\Component\DependencyInjection\Exception\EnvParameterException;
use Symfony\Component\DependencyInjection\Exception\RuntimeException;
use Symfony\Component\DependencyInjection\Loader\FileLoader;

/**
 * This pass validates each definition individually only taking the information
 * into account which is contained in the definition itself.
 *
 * Later passes can rely on the following, and specifically do not need to
 * perform these checks themselves:
 *
 * - non synthetic, non abstract services always have a class set
 * - synthetic services are always public
 *
 * @author Johannes M. Schmitt <schmittjoh@gmail.com>
 */
class CheckDefinitionValidityPass implements CompilerPassInterface
{
    /**
     * Processes the ContainerBuilder to validate the Definition.
     *
     * @throws RuntimeException When the Definition is invalid
     */
    public function process(ContainerBuilder $container)
    {
        foreach ($container->getDefinitions() as $id => $definition) {
            // synthetic service is public
            if ($definition->isSynthetic() && !$definition->isPublic()) {
                throw new RuntimeException(sprintf('A synthetic service ("%s") must be public.', $id));
            }

            // non-synthetic, non-abstract service has class
            if (!$definition->isAbstract() && !$definition->isSynthetic() && !$definition->getClass() && (!$definition->getFactory() || !preg_match(FileLoader::ANONYMOUS_ID_REGEXP, $id))) {
                if ($definition->getFactory()) {
                    throw new RuntimeException(sprintf('Please add the class to service "%s" even if it is constructed by a factory since we might need to add method calls based on compile-time checks.', $id));
                }
                if (class_exists($id) || interface_exists($id, false)) {
                    if (0 === strpos($id, '\\') && 1 < substr_count($id, '\\')) {
                        throw new RuntimeException(sprintf('The definition for "%s" has no class attribute, and appears to reference a class or interface. Please specify the class attribute explicitly or remove the leading backslash by renaming the service to "%s" to get rid of this error.', $id, substr($id, 1)));
                    }

                    throw new RuntimeException(sprintf('The definition for "%s" has no class attribute, and appears to reference a class or interface in the global namespace. Leaving out the "class" attribute is only allowed for namespaced classes. Please specify the class attribute explicitly to get rid of this error.', $id));
                }

                throw new RuntimeException(sprintf('The definition for "%s" has no class. If you intend to inject this service dynamically at runtime, please mark it as synthetic=true. If this is an abstract definition solely used by child definitions, please add abstract=true, otherwise specify a class to get rid of this error.', $id));
            }

            // tag attribute values must be scalars
            foreach ($definition->getTags() as $name => $tags) {
                foreach ($tags as $attributes) {
                    foreach ($attributes as $attribute => $value) {
                        if (!is_scalar($value) && null !== $value) {
                            throw new RuntimeException(sprintf('A "tags" attribute must be of a scalar-type for service "%s", tag "%s", attribute "%s".', $id, $name, $attribute));
                        }
                    }
                }
            }

            if ($definition->isPublic() && !$definition->isPrivate()) {
                $resolvedId = $container->resolveEnvPlaceholders($id, null, $usedEnvs);
                if (null !== $usedEnvs) {
                    throw new EnvParameterException([$resolvedId], null, 'A service name ("%s") cannot contain dynamic values.');
                }
            }
        }

        foreach ($container->getAliases() as $id => $alias) {
            if ($alias->isPublic() && !$alias->isPrivate()) {
                $resolvedId = $container->resolveEnvPlaceholders($id, null, $usedEnvs);
                if (null !== $usedEnvs) {
                    throw new EnvParameterException([$resolvedId], null, 'An alias name ("%s") cannot contain dynamic values.');
                }
            }
        }
    }
}
PKϤ$Z\���TT=dependency-injection/Compiler/ResolveChildDefinitionsPass.phpnu�[���<?php

/*
 * This file is part of the Symfony package.
 *
 * (c) Fabien Potencier <fabien@symfony.com>
 *
 * For the full copyright and license information, please view the LICENSE
 * file that was distributed with this source code.
 */

namespace Symfony\Component\DependencyInjection\Compiler;

use Symfony\Component\DependencyInjection\ChildDefinition;
use Symfony\Component\DependencyInjection\ContainerInterface;
use Symfony\Component\DependencyInjection\Definition;
use Symfony\Component\DependencyInjection\Exception\ExceptionInterface;
use Symfony\Component\DependencyInjection\Exception\RuntimeException;
use Symfony\Component\DependencyInjection\Exception\ServiceCircularReferenceException;

/**
 * This replaces all ChildDefinition instances with their equivalent fully
 * merged Definition instance.
 *
 * @author Johannes M. Schmitt <schmittjoh@gmail.com>
 * @author Nicolas Grekas <p@tchwork.com>
 */
class ResolveChildDefinitionsPass extends AbstractRecursivePass
{
    private $currentPath;

    protected function processValue($value, bool $isRoot = false)
    {
        if (!$value instanceof Definition) {
            return parent::processValue($value, $isRoot);
        }
        if ($isRoot) {
            // yes, we are specifically fetching the definition from the
            // container to ensure we are not operating on stale data
            $value = $this->container->getDefinition($this->currentId);
        }
        if ($value instanceof ChildDefinition) {
            $this->currentPath = [];
            $value = $this->resolveDefinition($value);
            if ($isRoot) {
                $this->container->setDefinition($this->currentId, $value);
            }
        }

        return parent::processValue($value, $isRoot);
    }

    /**
     * Resolves the definition.
     *
     * @throws RuntimeException When the definition is invalid
     */
    private function resolveDefinition(ChildDefinition $definition): Definition
    {
        try {
            return $this->doResolveDefinition($definition);
        } catch (ServiceCircularReferenceException $e) {
            throw $e;
        } catch (ExceptionInterface $e) {
            $r = new \ReflectionProperty($e, 'message');
            $r->setAccessible(true);
            $r->setValue($e, sprintf('Service "%s": %s', $this->currentId, $e->getMessage()));

            throw $e;
        }
    }

    private function doResolveDefinition(ChildDefinition $definition): Definition
    {
        if (!$this->container->has($parent = $definition->getParent())) {
            throw new RuntimeException(sprintf('Parent definition "%s" does not exist.', $parent));
        }

        $searchKey = array_search($parent, $this->currentPath);
        $this->currentPath[] = $parent;

        if (false !== $searchKey) {
            throw new ServiceCircularReferenceException($parent, \array_slice($this->currentPath, $searchKey));
        }

        $parentDef = $this->container->findDefinition($parent);
        if ($parentDef instanceof ChildDefinition) {
            $id = $this->currentId;
            $this->currentId = $parent;
            $parentDef = $this->resolveDefinition($parentDef);
            $this->container->setDefinition($parent, $parentDef);
            $this->currentId = $id;
        }

        $this->container->log($this, sprintf('Resolving inheritance for "%s" (parent: %s).', $this->currentId, $parent));
        $def = new Definition();

        // merge in parent definition
        // purposely ignored attributes: abstract, shared, tags, autoconfigured
        $def->setClass($parentDef->getClass());
        $def->setArguments($parentDef->getArguments());
        $def->setMethodCalls($parentDef->getMethodCalls());
        $def->setProperties($parentDef->getProperties());
        if ($parentDef->isDeprecated()) {
            $deprecation = $parentDef->getDeprecation('%service_id%');
            $def->setDeprecated($deprecation['package'], $deprecation['version'], $deprecation['message']);
        }
        $def->setFactory($parentDef->getFactory());
        $def->setConfigurator($parentDef->getConfigurator());
        $def->setFile($parentDef->getFile());
        $def->setPublic($parentDef->isPublic());
        $def->setLazy($parentDef->isLazy());
        $def->setAutowired($parentDef->isAutowired());
        $def->setChanges($parentDef->getChanges());

        $def->setBindings($definition->getBindings() + $parentDef->getBindings());

        // overwrite with values specified in the decorator
        $changes = $definition->getChanges();
        if (isset($changes['class'])) {
            $def->setClass($definition->getClass());
        }
        if (isset($changes['factory'])) {
            $def->setFactory($definition->getFactory());
        }
        if (isset($changes['configurator'])) {
            $def->setConfigurator($definition->getConfigurator());
        }
        if (isset($changes['file'])) {
            $def->setFile($definition->getFile());
        }
        if (isset($changes['public'])) {
            $def->setPublic($definition->isPublic());
        } else {
            $def->setPrivate($definition->isPrivate() || $parentDef->isPrivate());
        }
        if (isset($changes['lazy'])) {
            $def->setLazy($definition->isLazy());
        }
        if (isset($changes['deprecated'])) {
            if ($definition->isDeprecated()) {
                $deprecation = $definition->getDeprecation('%service_id%');
                $def->setDeprecated($deprecation['package'], $deprecation['version'], $deprecation['message']);
            } else {
                $def->setDeprecated(false);
            }
        }
        if (isset($changes['autowired'])) {
            $def->setAutowired($definition->isAutowired());
        }
        if (isset($changes['shared'])) {
            $def->setShared($definition->isShared());
        }
        if (isset($changes['decorated_service'])) {
            $decoratedService = $definition->getDecoratedService();
            if (null === $decoratedService) {
                $def->setDecoratedService($decoratedService);
            } else {
                $def->setDecoratedService($decoratedService[0], $decoratedService[1], $decoratedService[2], $decoratedService[3] ?? ContainerInterface::EXCEPTION_ON_INVALID_REFERENCE);
            }
        }

        // merge arguments
        foreach ($definition->getArguments() as $k => $v) {
            if (is_numeric($k)) {
                $def->addArgument($v);
            } elseif (0 === strpos($k, 'index_')) {
                $def->replaceArgument((int) substr($k, \strlen('index_')), $v);
            } else {
                $def->setArgument($k, $v);
            }
        }

        // merge properties
        foreach ($definition->getProperties() as $k => $v) {
            $def->setProperty($k, $v);
        }

        // append method calls
        if ($calls = $definition->getMethodCalls()) {
            $def->setMethodCalls(array_merge($def->getMethodCalls(), $calls));
        }

        $def->addError($parentDef);
        $def->addError($definition);

        // these attributes are always taken from the child
        $def->setAbstract($definition->isAbstract());
        $def->setTags($definition->getTags());
        // autoconfigure is never taken from parent (on purpose)
        // and it's not legal on an instanceof
        $def->setAutoconfigured($definition->isAutoconfigured());

        return $def;
    }
}
PKϤ$Zϛ�?--=dependency-injection/Compiler/ValidateEnvPlaceholdersPass.phpnu�[���<?php

/*
 * This file is part of the Symfony package.
 *
 * (c) Fabien Potencier <fabien@symfony.com>
 *
 * For the full copyright and license information, please view the LICENSE
 * file that was distributed with this source code.
 */

namespace Symfony\Component\DependencyInjection\Compiler;

use Symfony\Component\Config\Definition\BaseNode;
use Symfony\Component\Config\Definition\ConfigurationInterface;
use Symfony\Component\Config\Definition\Processor;
use Symfony\Component\DependencyInjection\ContainerBuilder;
use Symfony\Component\DependencyInjection\Extension\ConfigurationExtensionInterface;
use Symfony\Component\DependencyInjection\ParameterBag\EnvPlaceholderParameterBag;
use Symfony\Component\DependencyInjection\ParameterBag\ParameterBag;

/**
 * Validates environment variable placeholders used in extension configuration with dummy values.
 *
 * @author Roland Franssen <franssen.roland@gmail.com>
 */
class ValidateEnvPlaceholdersPass implements CompilerPassInterface
{
    private static $typeFixtures = ['array' => [], 'bool' => false, 'float' => 0.0, 'int' => 0, 'string' => ''];

    private $extensionConfig = [];

    /**
     * {@inheritdoc}
     */
    public function process(ContainerBuilder $container)
    {
        $this->extensionConfig = [];

        if (!class_exists(BaseNode::class) || !$extensions = $container->getExtensions()) {
            return;
        }

        $resolvingBag = $container->getParameterBag();
        if (!$resolvingBag instanceof EnvPlaceholderParameterBag) {
            return;
        }

        $defaultBag = new ParameterBag($resolvingBag->all());
        $envTypes = $resolvingBag->getProvidedTypes();
        try {
            foreach ($resolvingBag->getEnvPlaceholders() + $resolvingBag->getUnusedEnvPlaceholders() as $env => $placeholders) {
                $values = [];
                if (false === $i = strpos($env, ':')) {
                    $default = $defaultBag->has("env($env)") ? $defaultBag->get("env($env)") : self::$typeFixtures['string'];
                    $defaultType = null !== $default ? get_debug_type($default) : 'string';
                    $values[$defaultType] = $default;
                } else {
                    $prefix = substr($env, 0, $i);
                    foreach ($envTypes[$prefix] ?? ['string'] as $type) {
                        $values[$type] = self::$typeFixtures[$type] ?? null;
                    }
                }
                foreach ($placeholders as $placeholder) {
                    BaseNode::setPlaceholder($placeholder, $values);
                }
            }

            $processor = new Processor();

            foreach ($extensions as $name => $extension) {
                if (!($extension instanceof ConfigurationExtensionInterface || $extension instanceof ConfigurationInterface)
                    || !$config = array_filter($container->getExtensionConfig($name))
                ) {
                    // this extension has no semantic configuration or was not called
                    continue;
                }

                $config = $resolvingBag->resolveValue($config);

                if ($extension instanceof ConfigurationInterface) {
                    $configuration = $extension;
                } elseif (null === $configuration = $extension->getConfiguration($config, $container)) {
                    continue;
                }

                $this->extensionConfig[$name] = $processor->processConfiguration($configuration, $config);
            }
        } finally {
            BaseNode::resetPlaceholders();
        }

        $resolvingBag->clearUnusedEnvPlaceholders();
    }

    /**
     * @internal
     */
    public function getExtensionConfig(): array
    {
        try {
            return $this->extensionConfig;
        } finally {
            $this->extensionConfig = [];
        }
    }
}
PKϤ$Z���||7dependency-injection/Compiler/ExtensionCompilerPass.phpnu�[���<?php

/*
 * This file is part of the Symfony package.
 *
 * (c) Fabien Potencier <fabien@symfony.com>
 *
 * For the full copyright and license information, please view the LICENSE
 * file that was distributed with this source code.
 */

namespace Symfony\Component\DependencyInjection\Compiler;

use Symfony\Component\DependencyInjection\ContainerBuilder;

/**
 * A pass to automatically process extensions if they implement
 * CompilerPassInterface.
 *
 * @author Wouter J <wouter@wouterj.nl>
 */
class ExtensionCompilerPass implements CompilerPassInterface
{
    /**
     * {@inheritdoc}
     */
    public function process(ContainerBuilder $container)
    {
        foreach ($container->getExtensions() as $extension) {
            if (!$extension instanceof CompilerPassInterface) {
                continue;
            }

            $extension->process($container);
        }
    }
}
PKϤ$Z���MM<dependency-injection/Compiler/ResolveEnvPlaceholdersPass.phpnu�[���<?php

/*
 * This file is part of the Symfony package.
 *
 * (c) Fabien Potencier <fabien@symfony.com>
 *
 * For the full copyright and license information, please view the LICENSE
 * file that was distributed with this source code.
 */

namespace Symfony\Component\DependencyInjection\Compiler;

use Symfony\Component\DependencyInjection\Definition;

/**
 * Replaces env var placeholders by their current values.
 */
class ResolveEnvPlaceholdersPass extends AbstractRecursivePass
{
    protected function processValue($value, bool $isRoot = false)
    {
        if (\is_string($value)) {
            return $this->container->resolveEnvPlaceholders($value, true);
        }
        if ($value instanceof Definition) {
            $changes = $value->getChanges();
            if (isset($changes['class'])) {
                $value->setClass($this->container->resolveEnvPlaceholders($value->getClass(), true));
            }
            if (isset($changes['file'])) {
                $value->setFile($this->container->resolveEnvPlaceholders($value->getFile(), true));
            }
        }

        $value = parent::processValue($value, $isRoot);

        if ($value && \is_array($value) && !$isRoot) {
            $value = array_combine($this->container->resolveEnvPlaceholders(array_keys($value), true), $value);
        }

        return $value;
    }
}
PKϤ$Z�,҈

7dependency-injection/Compiler/ServiceReferenceGraph.phpnu�[���<?php

/*
 * This file is part of the Symfony package.
 *
 * (c) Fabien Potencier <fabien@symfony.com>
 *
 * For the full copyright and license information, please view the LICENSE
 * file that was distributed with this source code.
 */

namespace Symfony\Component\DependencyInjection\Compiler;

use Symfony\Component\DependencyInjection\Exception\InvalidArgumentException;

/**
 * This is a directed graph of your services.
 *
 * This information can be used by your compiler passes instead of collecting
 * it themselves which improves performance quite a lot.
 *
 * @author Johannes M. Schmitt <schmittjoh@gmail.com>
 *
 * @final
 */
class ServiceReferenceGraph
{
    /**
     * @var ServiceReferenceGraphNode[]
     */
    private $nodes = [];

    public function hasNode(string $id): bool
    {
        return isset($this->nodes[$id]);
    }

    /**
     * Gets a node by identifier.
     *
     * @throws InvalidArgumentException if no node matches the supplied identifier
     */
    public function getNode(string $id): ServiceReferenceGraphNode
    {
        if (!isset($this->nodes[$id])) {
            throw new InvalidArgumentException(sprintf('There is no node with id "%s".', $id));
        }

        return $this->nodes[$id];
    }

    /**
     * Returns all nodes.
     *
     * @return ServiceReferenceGraphNode[]
     */
    public function getNodes(): array
    {
        return $this->nodes;
    }

    /**
     * Clears all nodes.
     */
    public function clear()
    {
        foreach ($this->nodes as $node) {
            $node->clear();
        }
        $this->nodes = [];
    }

    /**
     * Connects 2 nodes together in the Graph.
     */
    public function connect(?string $sourceId, $sourceValue, ?string $destId, $destValue = null, $reference = null, bool $lazy = false, bool $weak = false, bool $byConstructor = false)
    {
        if (null === $sourceId || null === $destId) {
            return;
        }

        $sourceNode = $this->createNode($sourceId, $sourceValue);
        $destNode = $this->createNode($destId, $destValue);
        $edge = new ServiceReferenceGraphEdge($sourceNode, $destNode, $reference, $lazy, $weak, $byConstructor);

        $sourceNode->addOutEdge($edge);
        $destNode->addInEdge($edge);
    }

    private function createNode(string $id, $value): ServiceReferenceGraphNode
    {
        if (isset($this->nodes[$id]) && $this->nodes[$id]->getValue() === $value) {
            return $this->nodes[$id];
        }

        return $this->nodes[$id] = new ServiceReferenceGraphNode($id, $value);
    }
}
PKϤ$Zm����@dependency-injection/Compiler/ResolveDefinitionTemplatesPass.phpnu�[���<?php

/*
 * This file is part of the Symfony package.
 *
 * (c) Fabien Potencier <fabien@symfony.com>
 *
 * For the full copyright and license information, please view the LICENSE
 * file that was distributed with this source code.
 */

namespace Symfony\Component\DependencyInjection\Compiler;

use Symfony\Component\DependencyInjection\Definition;
use Symfony\Component\DependencyInjection\DefinitionDecorator;
use Symfony\Component\DependencyInjection\ContainerBuilder;
use Symfony\Component\DependencyInjection\Exception\RuntimeException;

/**
 * This replaces all DefinitionDecorator instances with their equivalent fully
 * merged Definition instance.
 *
 * @author Johannes M. Schmitt <schmittjoh@gmail.com>
 * @author Nicolas Grekas <p@tchwork.com>
 */
class ResolveDefinitionTemplatesPass implements CompilerPassInterface
{
    private $compiler;
    private $formatter;
    private $currentId;

    /**
     * Process the ContainerBuilder to replace DefinitionDecorator instances with their real Definition instances.
     *
     * @param ContainerBuilder $container
     */
    public function process(ContainerBuilder $container)
    {
        $this->compiler = $container->getCompiler();
        $this->formatter = $this->compiler->getLoggingFormatter();

        $container->setDefinitions($this->resolveArguments($container, $container->getDefinitions(), true));
    }

    /**
     * Resolves definition decorator arguments.
     *
     * @param ContainerBuilder $container The ContainerBuilder
     * @param array            $arguments An array of arguments
     * @param bool             $isRoot    If we are processing the root definitions or not
     *
     * @return array
     */
    private function resolveArguments(ContainerBuilder $container, array $arguments, $isRoot = false)
    {
        foreach ($arguments as $k => $argument) {
            if ($isRoot) {
                // yes, we are specifically fetching the definition from the
                // container to ensure we are not operating on stale data
                $arguments[$k] = $argument = $container->getDefinition($k);
                $this->currentId = $k;
            }
            if (is_array($argument)) {
                $arguments[$k] = $this->resolveArguments($container, $argument);
            } elseif ($argument instanceof Definition) {
                if ($argument instanceof DefinitionDecorator) {
                    $arguments[$k] = $argument = $this->resolveDefinition($container, $argument);
                    if ($isRoot) {
                        $container->setDefinition($k, $argument);
                    }
                }
                $argument->setArguments($this->resolveArguments($container, $argument->getArguments()));
                $argument->setMethodCalls($this->resolveArguments($container, $argument->getMethodCalls()));
                $argument->setProperties($this->resolveArguments($container, $argument->getProperties()));

                $configurator = $this->resolveArguments($container, array($argument->getConfigurator()));
                $argument->setConfigurator($configurator[0]);

                $factory = $this->resolveArguments($container, array($argument->getFactory()));
                $argument->setFactory($factory[0]);
            }
        }

        return $arguments;
    }

    /**
     * Resolves the definition.
     *
     * @param ContainerBuilder    $container  The ContainerBuilder
     * @param DefinitionDecorator $definition
     *
     * @return Definition
     *
     * @throws \RuntimeException When the definition is invalid
     */
    private function resolveDefinition(ContainerBuilder $container, DefinitionDecorator $definition)
    {
        if (!$container->has($parent = $definition->getParent())) {
            throw new RuntimeException(sprintf('The parent definition "%s" defined for definition "%s" does not exist.', $parent, $this->currentId));
        }

        $parentDef = $container->findDefinition($parent);
        if ($parentDef instanceof DefinitionDecorator) {
            $id = $this->currentId;
            $this->currentId = $parent;
            $parentDef = $this->resolveDefinition($container, $parentDef);
            $container->setDefinition($parent, $parentDef);
            $this->currentId = $id;
        }

        $this->compiler->addLogMessage($this->formatter->formatResolveInheritance($this, $this->currentId, $parent));
        $def = new Definition();

        // merge in parent definition
        // purposely ignored attributes: abstract, tags
        $def->setClass($parentDef->getClass());
        $def->setArguments($parentDef->getArguments());
        $def->setMethodCalls($parentDef->getMethodCalls());
        $def->setProperties($parentDef->getProperties());
        $def->setAutowiringTypes($parentDef->getAutowiringTypes());
        if ($parentDef->isDeprecated()) {
            $def->setDeprecated(true, $parentDef->getDeprecationMessage('%service_id%'));
        }
        $def->setFactory($parentDef->getFactory());
        $def->setConfigurator($parentDef->getConfigurator());
        $def->setFile($parentDef->getFile());
        $def->setPublic($parentDef->isPublic());
        $def->setLazy($parentDef->isLazy());
        $def->setAutowired($parentDef->isAutowired());

        // overwrite with values specified in the decorator
        $changes = $definition->getChanges();
        if (isset($changes['class'])) {
            $def->setClass($definition->getClass());
        }
        if (isset($changes['factory'])) {
            $def->setFactory($definition->getFactory());
        }
        if (isset($changes['configurator'])) {
            $def->setConfigurator($definition->getConfigurator());
        }
        if (isset($changes['file'])) {
            $def->setFile($definition->getFile());
        }
        if (isset($changes['public'])) {
            $def->setPublic($definition->isPublic());
        }
        if (isset($changes['lazy'])) {
            $def->setLazy($definition->isLazy());
        }
        if (isset($changes['deprecated'])) {
            $def->setDeprecated($definition->isDeprecated(), $definition->getDeprecationMessage('%service_id%'));
        }
        if (isset($changes['autowire'])) {
            $def->setAutowired($definition->isAutowired());
        }
        if (isset($changes['decorated_service'])) {
            $decoratedService = $definition->getDecoratedService();
            if (null === $decoratedService) {
                $def->setDecoratedService($decoratedService);
            } else {
                $def->setDecoratedService($decoratedService[0], $decoratedService[1], $decoratedService[2]);
            }
        }

        // merge arguments
        foreach ($definition->getArguments() as $k => $v) {
            if (is_numeric($k)) {
                $def->addArgument($v);
                continue;
            }

            if (0 !== strpos($k, 'index_')) {
                throw new RuntimeException(sprintf('Invalid argument key "%s" found.', $k));
            }

            $index = (int) substr($k, strlen('index_'));
            $def->replaceArgument($index, $v);
        }

        // merge properties
        foreach ($definition->getProperties() as $k => $v) {
            $def->setProperty($k, $v);
        }

        // append method calls
        if (count($calls = $definition->getMethodCalls()) > 0) {
            $def->setMethodCalls(array_merge($def->getMethodCalls(), $calls));
        }

        // merge autowiring types
        foreach ($definition->getAutowiringTypes() as $autowiringType) {
            $def->addAutowiringType($autowiringType);
        }

        // these attributes are always taken from the child
        $def->setAbstract($definition->isAbstract());
        $def->setShared($definition->isShared());
        $def->setTags($definition->getTags());

        return $def;
    }
}
PKϤ$Z�I���"�"5dependency-injection/Compiler/ResolveBindingsPass.phpnu�[���<?php

/*
 * This file is part of the Symfony package.
 *
 * (c) Fabien Potencier <fabien@symfony.com>
 *
 * For the full copyright and license information, please view the LICENSE
 * file that was distributed with this source code.
 */

namespace Symfony\Component\DependencyInjection\Compiler;

use Symfony\Component\DependencyInjection\Argument\BoundArgument;
use Symfony\Component\DependencyInjection\Argument\ServiceLocatorArgument;
use Symfony\Component\DependencyInjection\Argument\TaggedIteratorArgument;
use Symfony\Component\DependencyInjection\ContainerBuilder;
use Symfony\Component\DependencyInjection\Definition;
use Symfony\Component\DependencyInjection\Exception\InvalidArgumentException;
use Symfony\Component\DependencyInjection\Exception\RuntimeException;
use Symfony\Component\DependencyInjection\LazyProxy\ProxyHelper;
use Symfony\Component\DependencyInjection\Reference;
use Symfony\Component\DependencyInjection\TypedReference;

/**
 * @author Guilhem Niot <guilhem.niot@gmail.com>
 */
class ResolveBindingsPass extends AbstractRecursivePass
{
    private $usedBindings = [];
    private $unusedBindings = [];
    private $errorMessages = [];

    /**
     * {@inheritdoc}
     */
    public function process(ContainerBuilder $container)
    {
        $this->usedBindings = $container->getRemovedBindingIds();

        try {
            parent::process($container);

            foreach ($this->unusedBindings as list($key, $serviceId, $bindingType, $file)) {
                $argumentType = $argumentName = $message = null;

                if (false !== strpos($key, ' ')) {
                    list($argumentType, $argumentName) = explode(' ', $key, 2);
                } elseif ('$' === $key[0]) {
                    $argumentName = $key;
                } else {
                    $argumentType = $key;
                }

                if ($argumentType) {
                    $message .= sprintf('of type "%s" ', $argumentType);
                }

                if ($argumentName) {
                    $message .= sprintf('named "%s" ', $argumentName);
                }

                if (BoundArgument::DEFAULTS_BINDING === $bindingType) {
                    $message .= 'under "_defaults"';
                } elseif (BoundArgument::INSTANCEOF_BINDING === $bindingType) {
                    $message .= 'under "_instanceof"';
                } else {
                    $message .= sprintf('for service "%s"', $serviceId);
                }

                if ($file) {
                    $message .= sprintf(' in file "%s"', $file);
                }

                $message = sprintf('A binding is configured for an argument %s, but no corresponding argument has been found. It may be unused and should be removed, or it may have a typo.', $message);

                if ($this->errorMessages) {
                    $message .= sprintf("\nCould be related to%s:", 1 < \count($this->errorMessages) ? ' one of' : '');
                }
                foreach ($this->errorMessages as $m) {
                    $message .= "\n - ".$m;
                }
                throw new InvalidArgumentException($message);
            }
        } finally {
            $this->usedBindings = [];
            $this->unusedBindings = [];
            $this->errorMessages = [];
        }
    }

    /**
     * {@inheritdoc}
     */
    protected function processValue($value, bool $isRoot = false)
    {
        if ($value instanceof TypedReference && $value->getType() === (string) $value) {
            // Already checked
            $bindings = $this->container->getDefinition($this->currentId)->getBindings();
            $name = $value->getName();

            if (isset($name, $bindings[$name = $value.' $'.$name])) {
                return $this->getBindingValue($bindings[$name]);
            }

            if (isset($bindings[$value->getType()])) {
                return $this->getBindingValue($bindings[$value->getType()]);
            }

            return parent::processValue($value, $isRoot);
        }

        if (!$value instanceof Definition || !$bindings = $value->getBindings()) {
            return parent::processValue($value, $isRoot);
        }

        $bindingNames = [];

        foreach ($bindings as $key => $binding) {
            list($bindingValue, $bindingId, $used, $bindingType, $file) = $binding->getValues();
            if ($used) {
                $this->usedBindings[$bindingId] = true;
                unset($this->unusedBindings[$bindingId]);
            } elseif (!isset($this->usedBindings[$bindingId])) {
                $this->unusedBindings[$bindingId] = [$key, $this->currentId, $bindingType, $file];
            }

            if (preg_match('/^(?:(?:array|bool|float|int|string|([^ $]++)) )\$/', $key, $m)) {
                $bindingNames[substr($key, \strlen($m[0]))] = $binding;
            }

            if (!isset($m[1])) {
                continue;
            }

            if (null !== $bindingValue && !$bindingValue instanceof Reference && !$bindingValue instanceof Definition && !$bindingValue instanceof TaggedIteratorArgument && !$bindingValue instanceof ServiceLocatorArgument) {
                throw new InvalidArgumentException(sprintf('Invalid value for binding key "%s" for service "%s": expected null, "%s", "%s", "%s" or ServiceLocatorArgument, "%s" given.', $key, $this->currentId, Reference::class, Definition::class, TaggedIteratorArgument::class, get_debug_type($bindingValue)));
            }
        }

        if ($value->isAbstract()) {
            return parent::processValue($value, $isRoot);
        }

        $calls = $value->getMethodCalls();

        try {
            if ($constructor = $this->getConstructor($value, false)) {
                $calls[] = [$constructor, $value->getArguments()];
            }
        } catch (RuntimeException $e) {
            $this->errorMessages[] = $e->getMessage();
            $this->container->getDefinition($this->currentId)->addError($e->getMessage());

            return parent::processValue($value, $isRoot);
        }

        foreach ($calls as $i => $call) {
            list($method, $arguments) = $call;

            if ($method instanceof \ReflectionFunctionAbstract) {
                $reflectionMethod = $method;
            } else {
                try {
                    $reflectionMethod = $this->getReflectionMethod($value, $method);
                } catch (RuntimeException $e) {
                    if ($value->getFactory()) {
                        continue;
                    }
                    throw $e;
                }
            }

            foreach ($reflectionMethod->getParameters() as $key => $parameter) {
                if (\array_key_exists($key, $arguments) && '' !== $arguments[$key]) {
                    continue;
                }

                $typeHint = ProxyHelper::getTypeHint($reflectionMethod, $parameter);

                if (\array_key_exists($k = ltrim($typeHint, '\\').' $'.$parameter->name, $bindings)) {
                    $arguments[$key] = $this->getBindingValue($bindings[$k]);

                    continue;
                }

                if (\array_key_exists('$'.$parameter->name, $bindings)) {
                    $arguments[$key] = $this->getBindingValue($bindings['$'.$parameter->name]);

                    continue;
                }

                if ($typeHint && '\\' === $typeHint[0] && isset($bindings[$typeHint = substr($typeHint, 1)])) {
                    $arguments[$key] = $this->getBindingValue($bindings[$typeHint]);

                    continue;
                }

                if (isset($bindingNames[$parameter->name])) {
                    $bindingKey = array_search($binding, $bindings, true);
                    $argumentType = substr($bindingKey, 0, strpos($bindingKey, ' '));
                    $this->errorMessages[] = sprintf('Did you forget to add the type "%s" to argument "$%s" of method "%s::%s()"?', $argumentType, $parameter->name, $reflectionMethod->class, $reflectionMethod->name);
                }
            }

            if ($arguments !== $call[1]) {
                ksort($arguments);
                $calls[$i][1] = $arguments;
            }
        }

        if ($constructor) {
            list(, $arguments) = array_pop($calls);

            if ($arguments !== $value->getArguments()) {
                $value->setArguments($arguments);
            }
        }

        if ($calls !== $value->getMethodCalls()) {
            $value->setMethodCalls($calls);
        }

        return parent::processValue($value, $isRoot);
    }

    /**
     * @return mixed
     */
    private function getBindingValue(BoundArgument $binding)
    {
        list($bindingValue, $bindingId) = $binding->getValues();

        $this->usedBindings[$bindingId] = true;
        unset($this->unusedBindings[$bindingId]);

        return $bindingValue;
    }
}
PKϤ$Zw�(���>dependency-injection/Compiler/AnalyzeServiceReferencesPass.phpnu�[���<?php

/*
 * This file is part of the Symfony package.
 *
 * (c) Fabien Potencier <fabien@symfony.com>
 *
 * For the full copyright and license information, please view the LICENSE
 * file that was distributed with this source code.
 */

namespace Symfony\Component\DependencyInjection\Compiler;

use Symfony\Component\DependencyInjection\Argument\ArgumentInterface;
use Symfony\Component\DependencyInjection\ContainerBuilder;
use Symfony\Component\DependencyInjection\ContainerInterface;
use Symfony\Component\DependencyInjection\Definition;
use Symfony\Component\DependencyInjection\Reference;

/**
 * Run this pass before passes that need to know more about the relation of
 * your services.
 *
 * This class will populate the ServiceReferenceGraph with information. You can
 * retrieve the graph in other passes from the compiler.
 *
 * @author Johannes M. Schmitt <schmittjoh@gmail.com>
 * @author Nicolas Grekas <p@tchwork.com>
 */
class AnalyzeServiceReferencesPass extends AbstractRecursivePass
{
    private $graph;
    private $currentDefinition;
    private $onlyConstructorArguments;
    private $hasProxyDumper;
    private $lazy;
    private $byConstructor;
    private $definitions;
    private $aliases;

    /**
     * @param bool $onlyConstructorArguments Sets this Service Reference pass to ignore method calls
     */
    public function __construct(bool $onlyConstructorArguments = false, bool $hasProxyDumper = true)
    {
        $this->onlyConstructorArguments = $onlyConstructorArguments;
        $this->hasProxyDumper = $hasProxyDumper;
        $this->enableExpressionProcessing();
    }

    /**
     * Processes a ContainerBuilder object to populate the service reference graph.
     */
    public function process(ContainerBuilder $container)
    {
        $this->container = $container;
        $this->graph = $container->getCompiler()->getServiceReferenceGraph();
        $this->graph->clear();
        $this->lazy = false;
        $this->byConstructor = false;
        $this->definitions = $container->getDefinitions();
        $this->aliases = $container->getAliases();

        foreach ($this->aliases as $id => $alias) {
            $targetId = $this->getDefinitionId((string) $alias);
            $this->graph->connect($id, $alias, $targetId, null !== $targetId ? $this->container->getDefinition($targetId) : null, null);
        }

        try {
            parent::process($container);
        } finally {
            $this->aliases = $this->definitions = [];
        }
    }

    protected function processValue($value, bool $isRoot = false)
    {
        $lazy = $this->lazy;
        $inExpression = $this->inExpression();

        if ($value instanceof ArgumentInterface) {
            $this->lazy = true;
            parent::processValue($value->getValues());
            $this->lazy = $lazy;

            return $value;
        }
        if ($value instanceof Reference) {
            $targetId = $this->getDefinitionId((string) $value);
            $targetDefinition = null !== $targetId ? $this->container->getDefinition($targetId) : null;

            $this->graph->connect(
                $this->currentId,
                $this->currentDefinition,
                $targetId,
                $targetDefinition,
                $value,
                $this->lazy || ($this->hasProxyDumper && $targetDefinition && $targetDefinition->isLazy()),
                ContainerInterface::IGNORE_ON_UNINITIALIZED_REFERENCE === $value->getInvalidBehavior(),
                $this->byConstructor
            );

            if ($inExpression) {
                $this->graph->connect(
                    '.internal.reference_in_expression',
                    null,
                    $targetId,
                    $targetDefinition,
                    $value,
                    $this->lazy || ($targetDefinition && $targetDefinition->isLazy()),
                    true
               );
            }

            return $value;
        }
        if (!$value instanceof Definition) {
            return parent::processValue($value, $isRoot);
        }
        if ($isRoot) {
            if ($value->isSynthetic() || $value->isAbstract()) {
                return $value;
            }
            $this->currentDefinition = $value;
        } elseif ($this->currentDefinition === $value) {
            return $value;
        }
        $this->lazy = false;

        $byConstructor = $this->byConstructor;
        $this->byConstructor = $isRoot || $byConstructor;
        $this->processValue($value->getFactory());
        $this->processValue($value->getArguments());

        $properties = $value->getProperties();
        $setters = $value->getMethodCalls();

        // Any references before a "wither" are part of the constructor-instantiation graph
        $lastWitherIndex = null;
        foreach ($setters as $k => $call) {
            if ($call[2] ?? false) {
                $lastWitherIndex = $k;
            }
        }

        if (null !== $lastWitherIndex) {
            $this->processValue($properties);
            $setters = $properties = [];

            foreach ($value->getMethodCalls() as $k => $call) {
                if (null === $lastWitherIndex) {
                    $setters[] = $call;
                    continue;
                }

                if ($lastWitherIndex === $k) {
                    $lastWitherIndex = null;
                }

                $this->processValue($call);
            }
        }

        $this->byConstructor = $byConstructor;

        if (!$this->onlyConstructorArguments) {
            $this->processValue($properties);
            $this->processValue($setters);
            $this->processValue($value->getConfigurator());
        }
        $this->lazy = $lazy;

        return $value;
    }

    private function getDefinitionId(string $id): ?string
    {
        while (isset($this->aliases[$id])) {
            $id = (string) $this->aliases[$id];
        }

        return isset($this->definitions[$id]) ? $id : null;
    }
}
PKϤ$ZB��_��7dependency-injection/Compiler/CompilerPassInterface.phpnu�[���<?php

/*
 * This file is part of the Symfony package.
 *
 * (c) Fabien Potencier <fabien@symfony.com>
 *
 * For the full copyright and license information, please view the LICENSE
 * file that was distributed with this source code.
 */

namespace Symfony\Component\DependencyInjection\Compiler;

use Symfony\Component\DependencyInjection\ContainerBuilder;

/**
 * Interface that must be implemented by compilation passes.
 *
 * @author Johannes M. Schmitt <schmittjoh@gmail.com>
 */
interface CompilerPassInterface
{
    /**
     * You can modify the container here before it is dumped to PHP code.
     */
    public function process(ContainerBuilder $container);
}
PKϤ$Zz��>dependency-injection/Compiler/RegisterEnvVarProcessorsPass.phpnu�[���<?php

/*
 * This file is part of the Symfony package.
 *
 * (c) Fabien Potencier <fabien@symfony.com>
 *
 * For the full copyright and license information, please view the LICENSE
 * file that was distributed with this source code.
 */

namespace Symfony\Component\DependencyInjection\Compiler;

use Symfony\Component\DependencyInjection\ContainerBuilder;
use Symfony\Component\DependencyInjection\EnvVarProcessor;
use Symfony\Component\DependencyInjection\EnvVarProcessorInterface;
use Symfony\Component\DependencyInjection\Exception\InvalidArgumentException;
use Symfony\Component\DependencyInjection\ParameterBag\EnvPlaceholderParameterBag;
use Symfony\Component\DependencyInjection\Reference;

/**
 * Creates the container.env_var_processors_locator service.
 *
 * @author Nicolas Grekas <p@tchwork.com>
 */
class RegisterEnvVarProcessorsPass implements CompilerPassInterface
{
    private static $allowedTypes = ['array', 'bool', 'float', 'int', 'string'];

    public function process(ContainerBuilder $container)
    {
        $bag = $container->getParameterBag();
        $types = [];
        $processors = [];
        foreach ($container->findTaggedServiceIds('container.env_var_processor') as $id => $tags) {
            if (!$r = $container->getReflectionClass($class = $container->getDefinition($id)->getClass())) {
                throw new InvalidArgumentException(sprintf('Class "%s" used for service "%s" cannot be found.', $class, $id));
            } elseif (!$r->isSubclassOf(EnvVarProcessorInterface::class)) {
                throw new InvalidArgumentException(sprintf('Service "%s" must implement interface "%s".', $id, EnvVarProcessorInterface::class));
            }
            foreach ($class::getProvidedTypes() as $prefix => $type) {
                $processors[$prefix] = new Reference($id);
                $types[$prefix] = self::validateProvidedTypes($type, $class);
            }
        }

        if ($bag instanceof EnvPlaceholderParameterBag) {
            foreach (EnvVarProcessor::getProvidedTypes() as $prefix => $type) {
                if (!isset($types[$prefix])) {
                    $types[$prefix] = self::validateProvidedTypes($type, EnvVarProcessor::class);
                }
            }
            $bag->setProvidedTypes($types);
        }

        if ($processors) {
            $container->setAlias('container.env_var_processors_locator', (string) ServiceLocatorTagPass::register($container, $processors))
                ->setPublic(true)
            ;
        }
    }

    private static function validateProvidedTypes(string $types, string $class): array
    {
        $types = explode('|', $types);

        foreach ($types as $type) {
            if (!\in_array($type, self::$allowedTypes)) {
                throw new InvalidArgumentException(sprintf('Invalid type "%s" returned by "%s::getProvidedTypes()", expected one of "%s".', $type, $class, implode('", "', self::$allowedTypes)));
            }
        }

        return $types;
    }
}
PKϤ$ZӉ���9dependency-injection/Compiler/ResolveFactoryClassPass.phpnu�[���<?php

/*
 * This file is part of the Symfony package.
 *
 * (c) Fabien Potencier <fabien@symfony.com>
 *
 * For the full copyright and license information, please view the LICENSE
 * file that was distributed with this source code.
 */

namespace Symfony\Component\DependencyInjection\Compiler;

use Symfony\Component\DependencyInjection\Definition;
use Symfony\Component\DependencyInjection\Exception\RuntimeException;

/**
 * @author Maxime Steinhausser <maxime.steinhausser@gmail.com>
 */
class ResolveFactoryClassPass extends AbstractRecursivePass
{
    /**
     * {@inheritdoc}
     */
    protected function processValue($value, bool $isRoot = false)
    {
        if ($value instanceof Definition && \is_array($factory = $value->getFactory()) && null === $factory[0]) {
            if (null === $class = $value->getClass()) {
                throw new RuntimeException(sprintf('The "%s" service is defined to be created by a factory, but is missing the factory class. Did you forget to define the factory or service class?', $this->currentId));
            }

            $factory[0] = $class;
            $value->setFactory($factory);
        }

        return parent::processValue($value, $isRoot);
    }
}
PKϤ$Z��
�	�	Cdependency-injection/Compiler/AliasDeprecatedPublicServicesPass.phpnu�[���<?php

/*
 * This file is part of the Symfony package.
 *
 * (c) Fabien Potencier <fabien@symfony.com>
 *
 * For the full copyright and license information, please view the LICENSE
 * file that was distributed with this source code.
 */

namespace Symfony\Component\DependencyInjection\Compiler;

use Symfony\Component\DependencyInjection\ContainerBuilder;
use Symfony\Component\DependencyInjection\Exception\InvalidArgumentException;
use Symfony\Component\DependencyInjection\Reference;

final class AliasDeprecatedPublicServicesPass extends AbstractRecursivePass
{
    private $tagName;

    private $aliases = [];

    public function __construct(string $tagName = 'container.private')
    {
        $this->tagName = $tagName;
    }

    /**
     * {@inheritdoc}
     */
    protected function processValue($value, bool $isRoot = false)
    {
        if ($value instanceof Reference && isset($this->aliases[$id = (string) $value])) {
            return new Reference($this->aliases[$id], $value->getInvalidBehavior());
        }

        return parent::processValue($value, $isRoot);
    }

    /**
     * {@inheritdoc}
     */
    public function process(ContainerBuilder $container)
    {
        foreach ($container->findTaggedServiceIds($this->tagName) as $id => $tags) {
            if (null === $package = $tags[0]['package'] ?? null) {
                throw new InvalidArgumentException(sprintf('The "package" attribute is mandatory for the "%s" tag on the "%s" service.', $this->tagName, $id));
            }

            if (null === $version = $tags[0]['version'] ?? null) {
                throw new InvalidArgumentException(sprintf('The "version" attribute is mandatory for the "%s" tag on the "%s" service.', $this->tagName, $id));
            }

            $definition = $container->getDefinition($id);
            if (!$definition->isPublic() || $definition->isPrivate()) {
                throw new InvalidArgumentException(sprintf('The "%s" service is private: it cannot have the "%s" tag.', $id, $this->tagName));
            }

            $container
                ->setAlias($id, $aliasId = '.'.$this->tagName.'.'.$id)
                ->setPublic(true)
                ->setDeprecated($package, $version, 'Accessing the "%alias_id%" service directly from the container is deprecated, use dependency injection instead.');

            $container->setDefinition($aliasId, $definition);

            $this->aliases[$id] = $aliasId;
        }

        parent::process($container);
    }
}
PKϤ$ZW�-��2dependency-injection/Compiler/LoggingFormatter.phpnu�[���<?php

/*
 * This file is part of the Symfony package.
 *
 * (c) Fabien Potencier <fabien@symfony.com>
 *
 * For the full copyright and license information, please view the LICENSE
 * file that was distributed with this source code.
 */

namespace Symfony\Component\DependencyInjection\Compiler;

/**
 * Used to format logging messages during the compilation.
 *
 * @author Johannes M. Schmitt <schmittjoh@gmail.com>
 */
class LoggingFormatter
{
    public function formatRemoveService(CompilerPassInterface $pass, $id, $reason)
    {
        return $this->format($pass, sprintf('Removed service "%s"; reason: %s.', $id, $reason));
    }

    public function formatInlineService(CompilerPassInterface $pass, $id, $target)
    {
        return $this->format($pass, sprintf('Inlined service "%s" to "%s".', $id, $target));
    }

    public function formatUpdateReference(CompilerPassInterface $pass, $serviceId, $oldDestId, $newDestId)
    {
        return $this->format($pass, sprintf('Changed reference of service "%s" previously pointing to "%s" to "%s".', $serviceId, $oldDestId, $newDestId));
    }

    public function formatResolveInheritance(CompilerPassInterface $pass, $childId, $parentId)
    {
        return $this->format($pass, sprintf('Resolving inheritance for "%s" (parent: %s).', $childId, $parentId));
    }

    public function format(CompilerPassInterface $pass, $message)
    {
        return sprintf('%s: %s', get_class($pass), $message);
    }
}
PKϤ$Z���2dependency-injection/Compiler/ResolveClassPass.phpnu�[���<?php

/*
 * This file is part of the Symfony package.
 *
 * (c) Fabien Potencier <fabien@symfony.com>
 *
 * For the full copyright and license information, please view the LICENSE
 * file that was distributed with this source code.
 */

namespace Symfony\Component\DependencyInjection\Compiler;

use Symfony\Component\DependencyInjection\ChildDefinition;
use Symfony\Component\DependencyInjection\ContainerBuilder;
use Symfony\Component\DependencyInjection\Exception\InvalidArgumentException;

/**
 * @author Nicolas Grekas <p@tchwork.com>
 */
class ResolveClassPass implements CompilerPassInterface
{
    /**
     * {@inheritdoc}
     */
    public function process(ContainerBuilder $container)
    {
        foreach ($container->getDefinitions() as $id => $definition) {
            if ($definition->isSynthetic() || null !== $definition->getClass()) {
                continue;
            }
            if (preg_match('/^[a-zA-Z_\x7f-\xff][a-zA-Z0-9_\x7f-\xff]*+(?:\\\\[a-zA-Z_\x7f-\xff][a-zA-Z0-9_\x7f-\xff]*+)++$/', $id)) {
                if ($definition instanceof ChildDefinition && !class_exists($id)) {
                    throw new InvalidArgumentException(sprintf('Service definition "%s" has a parent but no class, and its name looks like a FQCN. Either the class is missing or you want to inherit it from the parent service. To resolve this ambiguity, please rename this service to a non-FQCN (e.g. using dots), or create the missing class.', $id));
                }
                $definition->setClass($id);
            }
        }
    }
}
PKϤ$Z��u
u
=dependency-injection/Compiler/AutowireRequiredMethodsPass.phpnu�[���<?php

/*
 * This file is part of the Symfony package.
 *
 * (c) Fabien Potencier <fabien@symfony.com>
 *
 * For the full copyright and license information, please view the LICENSE
 * file that was distributed with this source code.
 */

namespace Symfony\Component\DependencyInjection\Compiler;

use Symfony\Component\DependencyInjection\Definition;

/**
 * Looks for definitions with autowiring enabled and registers their corresponding "@required" methods as setters.
 *
 * @author Nicolas Grekas <p@tchwork.com>
 */
class AutowireRequiredMethodsPass extends AbstractRecursivePass
{
    /**
     * {@inheritdoc}
     */
    protected function processValue($value, bool $isRoot = false)
    {
        $value = parent::processValue($value, $isRoot);

        if (!$value instanceof Definition || !$value->isAutowired() || $value->isAbstract() || !$value->getClass()) {
            return $value;
        }
        if (!$reflectionClass = $this->container->getReflectionClass($value->getClass(), false)) {
            return $value;
        }

        $alreadyCalledMethods = [];
        $withers = [];

        foreach ($value->getMethodCalls() as list($method)) {
            $alreadyCalledMethods[strtolower($method)] = true;
        }

        foreach ($reflectionClass->getMethods() as $reflectionMethod) {
            $r = $reflectionMethod;

            if ($r->isConstructor() || isset($alreadyCalledMethods[strtolower($r->name)])) {
                continue;
            }

            while (true) {
                if (false !== $doc = $r->getDocComment()) {
                    if (false !== stripos($doc, '@required') && preg_match('#(?:^/\*\*|\n\s*+\*)\s*+@required(?:\s|\*/$)#i', $doc)) {
                        if ($this->isWither($reflectionMethod, $doc)) {
                            $withers[] = [$reflectionMethod->name, [], true];
                        } else {
                            $value->addMethodCall($reflectionMethod->name, []);
                        }
                        break;
                    }
                    if (false === stripos($doc, '@inheritdoc') || !preg_match('#(?:^/\*\*|\n\s*+\*)\s*+(?:\{@inheritdoc\}|@inheritdoc)(?:\s|\*/$)#i', $doc)) {
                        break;
                    }
                }
                try {
                    $r = $r->getPrototype();
                } catch (\ReflectionException $e) {
                    break; // method has no prototype
                }
            }
        }

        if ($withers) {
            // Prepend withers to prevent creating circular loops
            $setters = $value->getMethodCalls();
            $value->setMethodCalls($withers);
            foreach ($setters as $call) {
                $value->addMethodCall($call[0], $call[1], $call[2] ?? false);
            }
        }

        return $value;
    }

    private function isWither(\ReflectionMethod $reflectionMethod, string $doc): bool
    {
        $match = preg_match('#(?:^/\*\*|\n\s*+\*)\s*+@return\s++(static|\$this)[\s\*]#i', $doc, $matches);
        if ($match && 'static' === $matches[1]) {
            return true;
        }

        if ($match && '$this' === $matches[1]) {
            return false;
        }

        $reflectionType = $reflectionMethod->hasReturnType() ? $reflectionMethod->getReturnType() : null;

        return $reflectionType instanceof \ReflectionNamedType && 'static' === $reflectionType->getName();
    }
}
PKϤ$Z��.6``Cdependency-injection/Compiler/ResolveInstanceofConditionalsPass.phpnu�[���<?php

/*
 * This file is part of the Symfony package.
 *
 * (c) Fabien Potencier <fabien@symfony.com>
 *
 * For the full copyright and license information, please view the LICENSE
 * file that was distributed with this source code.
 */

namespace Symfony\Component\DependencyInjection\Compiler;

use Symfony\Component\DependencyInjection\ChildDefinition;
use Symfony\Component\DependencyInjection\ContainerBuilder;
use Symfony\Component\DependencyInjection\Definition;
use Symfony\Component\DependencyInjection\Exception\InvalidArgumentException;
use Symfony\Component\DependencyInjection\Exception\RuntimeException;

/**
 * Applies instanceof conditionals to definitions.
 *
 * @author Nicolas Grekas <p@tchwork.com>
 */
class ResolveInstanceofConditionalsPass implements CompilerPassInterface
{
    /**
     * {@inheritdoc}
     */
    public function process(ContainerBuilder $container)
    {
        foreach ($container->getAutoconfiguredInstanceof() as $interface => $definition) {
            if ($definition->getArguments()) {
                throw new InvalidArgumentException(sprintf('Autoconfigured instanceof for type "%s" defines arguments but these are not supported and should be removed.', $interface));
            }
        }

        foreach ($container->getDefinitions() as $id => $definition) {
            $container->setDefinition($id, $this->processDefinition($container, $id, $definition));
        }
    }

    private function processDefinition(ContainerBuilder $container, string $id, Definition $definition): Definition
    {
        $instanceofConditionals = $definition->getInstanceofConditionals();
        $autoconfiguredInstanceof = $definition->isAutoconfigured() ? $container->getAutoconfiguredInstanceof() : [];
        if (!$instanceofConditionals && !$autoconfiguredInstanceof) {
            return $definition;
        }

        if (!$class = $container->getParameterBag()->resolveValue($definition->getClass())) {
            return $definition;
        }

        $conditionals = $this->mergeConditionals($autoconfiguredInstanceof, $instanceofConditionals, $container);

        $definition->setInstanceofConditionals([]);
        $shared = null;
        $instanceofTags = [];
        $instanceofCalls = [];
        $instanceofBindings = [];
        $reflectionClass = null;
        $parent = $definition instanceof ChildDefinition ? $definition->getParent() : null;

        foreach ($conditionals as $interface => $instanceofDefs) {
            if ($interface !== $class && !(null === $reflectionClass ? $reflectionClass = ($container->getReflectionClass($class, false) ?: false) : $reflectionClass)) {
                continue;
            }

            if ($interface !== $class && !is_subclass_of($class, $interface)) {
                continue;
            }

            foreach ($instanceofDefs as $key => $instanceofDef) {
                /** @var ChildDefinition $instanceofDef */
                $instanceofDef = clone $instanceofDef;
                $instanceofDef->setAbstract(true)->setParent($parent ?: '.abstract.instanceof.'.$id);
                $parent = '.instanceof.'.$interface.'.'.$key.'.'.$id;
                $container->setDefinition($parent, $instanceofDef);
                $instanceofTags[] = $instanceofDef->getTags();
                $instanceofBindings = $instanceofDef->getBindings() + $instanceofBindings;

                foreach ($instanceofDef->getMethodCalls() as $methodCall) {
                    $instanceofCalls[] = $methodCall;
                }

                $instanceofDef->setTags([]);
                $instanceofDef->setMethodCalls([]);
                $instanceofDef->setBindings([]);

                if (isset($instanceofDef->getChanges()['shared'])) {
                    $shared = $instanceofDef->isShared();
                }
            }
        }

        if ($parent) {
            $bindings = $definition->getBindings();
            $abstract = $container->setDefinition('.abstract.instanceof.'.$id, $definition);
            $definition->setBindings([]);
            $definition = serialize($definition);

            if (Definition::class === \get_class($abstract)) {
                // cast Definition to ChildDefinition
                $definition = substr_replace($definition, '53', 2, 2);
                $definition = substr_replace($definition, 'Child', 44, 0);
            }
            /** @var ChildDefinition $definition */
            $definition = unserialize($definition);
            $definition->setParent($parent);

            if (null !== $shared && !isset($definition->getChanges()['shared'])) {
                $definition->setShared($shared);
            }

            // Don't add tags to service decorators
            if (null === $definition->getDecoratedService()) {
                $i = \count($instanceofTags);
                while (0 <= --$i) {
                    foreach ($instanceofTags[$i] as $k => $v) {
                        foreach ($v as $v) {
                            if ($definition->hasTag($k) && \in_array($v, $definition->getTag($k))) {
                                continue;
                            }
                            $definition->addTag($k, $v);
                        }
                    }
                }
            }

            $definition->setMethodCalls(array_merge($instanceofCalls, $definition->getMethodCalls()));
            $definition->setBindings($bindings + $instanceofBindings);

            // reset fields with "merge" behavior
            $abstract
                ->setBindings([])
                ->setArguments([])
                ->setMethodCalls([])
                ->setDecoratedService(null)
                ->setTags([])
                ->setAbstract(true);
        }

        return $definition;
    }

    private function mergeConditionals(array $autoconfiguredInstanceof, array $instanceofConditionals, ContainerBuilder $container): array
    {
        // make each value an array of ChildDefinition
        $conditionals = array_map(function ($childDef) { return [$childDef]; }, $autoconfiguredInstanceof);

        foreach ($instanceofConditionals as $interface => $instanceofDef) {
            // make sure the interface/class exists (but don't validate automaticInstanceofConditionals)
            if (!$container->getReflectionClass($interface)) {
                throw new RuntimeException(sprintf('"%s" is set as an "instanceof" conditional, but it does not exist.', $interface));
            }

            if (!isset($autoconfiguredInstanceof[$interface])) {
                $conditionals[$interface] = [];
            }

            $conditionals[$interface][] = $instanceofDef;
        }

        return $conditionals;
    }
}
PKϤ$ZW�g!��Bdependency-injection/Compiler/ResolveParameterPlaceHoldersPass.phpnu�[���<?php

/*
 * This file is part of the Symfony package.
 *
 * (c) Fabien Potencier <fabien@symfony.com>
 *
 * For the full copyright and license information, please view the LICENSE
 * file that was distributed with this source code.
 */

namespace Symfony\Component\DependencyInjection\Compiler;

use Symfony\Component\DependencyInjection\ContainerBuilder;
use Symfony\Component\DependencyInjection\Definition;
use Symfony\Component\DependencyInjection\Exception\ParameterNotFoundException;

/**
 * Resolves all parameter placeholders "%somevalue%" to their real values.
 *
 * @author Johannes M. Schmitt <schmittjoh@gmail.com>
 */
class ResolveParameterPlaceHoldersPass extends AbstractRecursivePass
{
    private $bag;
    private $resolveArrays;
    private $throwOnResolveException;

    public function __construct($resolveArrays = true, $throwOnResolveException = true)
    {
        $this->resolveArrays = $resolveArrays;
        $this->throwOnResolveException = $throwOnResolveException;
    }

    /**
     * {@inheritdoc}
     *
     * @throws ParameterNotFoundException
     */
    public function process(ContainerBuilder $container)
    {
        $this->bag = $container->getParameterBag();

        try {
            parent::process($container);

            $aliases = [];
            foreach ($container->getAliases() as $name => $target) {
                $this->currentId = $name;
                $aliases[$this->bag->resolveValue($name)] = $target;
            }
            $container->setAliases($aliases);
        } catch (ParameterNotFoundException $e) {
            $e->setSourceId($this->currentId);

            throw $e;
        }

        $this->bag->resolve();
        $this->bag = null;
    }

    protected function processValue($value, bool $isRoot = false)
    {
        if (\is_string($value)) {
            try {
                $v = $this->bag->resolveValue($value);
            } catch (ParameterNotFoundException $e) {
                if ($this->throwOnResolveException) {
                    throw $e;
                }

                $v = null;
                $this->container->getDefinition($this->currentId)->addError($e->getMessage());
            }

            return $this->resolveArrays || !$v || !\is_array($v) ? $v : $value;
        }
        if ($value instanceof Definition) {
            $value->setBindings($this->processValue($value->getBindings()));
            $changes = $value->getChanges();
            if (isset($changes['class'])) {
                $value->setClass($this->bag->resolveValue($value->getClass()));
            }
            if (isset($changes['file'])) {
                $value->setFile($this->bag->resolveValue($value->getFile()));
            }
        }

        $value = parent::processValue($value, $isRoot);

        if ($value && \is_array($value)) {
            $value = array_combine($this->bag->resolveValue(array_keys($value)), $value);
        }

        return $value;
    }
}
PKϤ$Z�<M��.dependency-injection/Compiler/RepeatedPass.phpnu�[���<?php

/*
 * This file is part of the Symfony package.
 *
 * (c) Fabien Potencier <fabien@symfony.com>
 *
 * For the full copyright and license information, please view the LICENSE
 * file that was distributed with this source code.
 */

namespace Symfony\Component\DependencyInjection\Compiler;

use Symfony\Component\DependencyInjection\ContainerBuilder;
use Symfony\Component\DependencyInjection\Exception\InvalidArgumentException;

/**
 * A pass that might be run repeatedly.
 *
 * @author Johannes M. Schmitt <schmittjoh@gmail.com>
 */
class RepeatedPass implements CompilerPassInterface
{
    /**
     * @var bool
     */
    private $repeat = false;

    /**
     * @var RepeatablePassInterface[]
     */
    private $passes;

    /**
     * @param RepeatablePassInterface[] $passes An array of RepeatablePassInterface objects
     *
     * @throws InvalidArgumentException when the passes don't implement RepeatablePassInterface
     */
    public function __construct(array $passes)
    {
        foreach ($passes as $pass) {
            if (!$pass instanceof RepeatablePassInterface) {
                throw new InvalidArgumentException('$passes must be an array of RepeatablePassInterface.');
            }

            $pass->setRepeatedPass($this);
        }

        $this->passes = $passes;
    }

    /**
     * Process the repeatable passes that run more than once.
     *
     * @param ContainerBuilder $container
     */
    public function process(ContainerBuilder $container)
    {
        do {
            $this->repeat = false;
            foreach ($this->passes as $pass) {
                $pass->process($container);
            }
        } while ($this->repeat);
    }

    /**
     * Sets if the pass should repeat.
     */
    public function setRepeat()
    {
        $this->repeat = true;
    }

    /**
     * Returns the passes.
     *
     * @return RepeatablePassInterface[] An array of RepeatablePassInterface objects
     */
    public function getPasses()
    {
        return $this->passes;
    }
}
PKϤ$Z��*DT	T	4dependency-injection/Compiler/ResolveHotPathPass.phpnu�[���<?php

/*
 * This file is part of the Symfony package.
 *
 * (c) Fabien Potencier <fabien@symfony.com>
 *
 * For the full copyright and license information, please view the LICENSE
 * file that was distributed with this source code.
 */

namespace Symfony\Component\DependencyInjection\Compiler;

use Symfony\Component\DependencyInjection\Argument\ArgumentInterface;
use Symfony\Component\DependencyInjection\ContainerBuilder;
use Symfony\Component\DependencyInjection\Definition;
use Symfony\Component\DependencyInjection\Reference;

/**
 * Propagate "container.hot_path" tags to referenced services.
 *
 * @author Nicolas Grekas <p@tchwork.com>
 */
class ResolveHotPathPass extends AbstractRecursivePass
{
    private $tagName;
    private $resolvedIds = [];

    public function __construct(string $tagName = 'container.hot_path')
    {
        $this->tagName = $tagName;
    }

    /**
     * {@inheritdoc}
     */
    public function process(ContainerBuilder $container)
    {
        try {
            parent::process($container);
            $container->getDefinition('service_container')->clearTag($this->tagName);
        } finally {
            $this->resolvedIds = [];
        }
    }

    /**
     * {@inheritdoc}
     */
    protected function processValue($value, bool $isRoot = false)
    {
        if ($value instanceof ArgumentInterface) {
            return $value;
        }

        if ($value instanceof Definition && $isRoot) {
            if ($value->isDeprecated()) {
                return $value->clearTag($this->tagName);
            }

            $this->resolvedIds[$this->currentId] = true;

            if (!$value->hasTag($this->tagName)) {
                return $value;
            }
        }

        if ($value instanceof Reference && ContainerBuilder::IGNORE_ON_UNINITIALIZED_REFERENCE !== $value->getInvalidBehavior() && $this->container->hasDefinition($id = (string) $value)) {
            $definition = $this->container->getDefinition($id);

            if ($definition->isDeprecated() || $definition->hasTag($this->tagName)) {
                return $value;
            }

            $definition->addTag($this->tagName);

            if (isset($this->resolvedIds[$id])) {
                parent::processValue($definition, false);
            }

            return $value;
        }

        return parent::processValue($value, $isRoot);
    }
}
PKϤ$ZéN�~~@dependency-injection/Compiler/AutowireRequiredPropertiesPass.phpnu�[���<?php

/*
 * This file is part of the Symfony package.
 *
 * (c) Fabien Potencier <fabien@symfony.com>
 *
 * For the full copyright and license information, please view the LICENSE
 * file that was distributed with this source code.
 */

namespace Symfony\Component\DependencyInjection\Compiler;

use Symfony\Component\DependencyInjection\ContainerInterface;
use Symfony\Component\DependencyInjection\Definition;
use Symfony\Component\DependencyInjection\TypedReference;

/**
 * Looks for definitions with autowiring enabled and registers their corresponding "@required" properties.
 *
 * @author Sebastien Morel (Plopix) <morel.seb@gmail.com>
 * @author Nicolas Grekas <p@tchwork.com>
 */
class AutowireRequiredPropertiesPass extends AbstractRecursivePass
{
    /**
     * {@inheritdoc}
     */
    protected function processValue($value, bool $isRoot = false)
    {
        if (\PHP_VERSION_ID < 70400) {
            return $value;
        }
        $value = parent::processValue($value, $isRoot);

        if (!$value instanceof Definition || !$value->isAutowired() || $value->isAbstract() || !$value->getClass()) {
            return $value;
        }
        if (!$reflectionClass = $this->container->getReflectionClass($value->getClass(), false)) {
            return $value;
        }

        $properties = $value->getProperties();
        foreach ($reflectionClass->getProperties() as $reflectionProperty) {
            if (!($type = $reflectionProperty->getType()) instanceof \ReflectionNamedType) {
                continue;
            }
            if (false === $doc = $reflectionProperty->getDocComment()) {
                continue;
            }
            if (false === stripos($doc, '@required') || !preg_match('#(?:^/\*\*|\n\s*+\*)\s*+@required(?:\s|\*/$)#i', $doc)) {
                continue;
            }
            if (\array_key_exists($name = $reflectionProperty->getName(), $properties)) {
                continue;
            }

            $type = $type->getName();
            $value->setProperty($name, new TypedReference($type, $type, ContainerInterface::EXCEPTION_ON_INVALID_REFERENCE, $name));
        }

        return $value;
    }
}
PKϤ$Zܖ�S��<dependency-injection/Compiler/PriorityTaggedServiceTrait.phpnu�[���<?php

/*
 * This file is part of the Symfony package.
 *
 * (c) Fabien Potencier <fabien@symfony.com>
 *
 * For the full copyright and license information, please view the LICENSE
 * file that was distributed with this source code.
 */

namespace Symfony\Component\DependencyInjection\Compiler;

use Symfony\Component\DependencyInjection\Argument\TaggedIteratorArgument;
use Symfony\Component\DependencyInjection\ContainerBuilder;
use Symfony\Component\DependencyInjection\Exception\InvalidArgumentException;
use Symfony\Component\DependencyInjection\Reference;
use Symfony\Component\DependencyInjection\TypedReference;

/**
 * Trait that allows a generic method to find and sort service by priority option in the tag.
 *
 * @author Iltar van der Berg <kjarli@gmail.com>
 */
trait PriorityTaggedServiceTrait
{
    /**
     * Finds all services with the given tag name and order them by their priority.
     *
     * The order of additions must be respected for services having the same priority,
     * and knowing that the \SplPriorityQueue class does not respect the FIFO method,
     * we should not use that class.
     *
     * @see https://bugs.php.net/53710
     * @see https://bugs.php.net/60926
     *
     * @param string|TaggedIteratorArgument $tagName
     *
     * @return Reference[]
     */
    private function findAndSortTaggedServices($tagName, ContainerBuilder $container): array
    {
        $indexAttribute = $defaultIndexMethod = $needsIndexes = $defaultPriorityMethod = null;

        if ($tagName instanceof TaggedIteratorArgument) {
            $indexAttribute = $tagName->getIndexAttribute();
            $defaultIndexMethod = $tagName->getDefaultIndexMethod();
            $needsIndexes = $tagName->needsIndexes();
            $defaultPriorityMethod = $tagName->getDefaultPriorityMethod();
            $tagName = $tagName->getTag();
        }

        $i = 0;
        $services = [];

        foreach ($container->findTaggedServiceIds($tagName, true) as $serviceId => $attributes) {
            $defaultPriority = null;
            $defaultIndex = null;
            $class = $container->getDefinition($serviceId)->getClass();
            $class = $container->getParameterBag()->resolveValue($class) ?: null;

            foreach ($attributes as $attribute) {
                $index = $priority = null;

                if (isset($attribute['priority'])) {
                    $priority = $attribute['priority'];
                } elseif (null === $defaultPriority && $defaultPriorityMethod && $class) {
                    $defaultPriority = PriorityTaggedServiceUtil::getDefaultPriority($container, $serviceId, $class, $defaultPriorityMethod, $tagName);
                }
                $priority = $priority ?? $defaultPriority ?? $defaultPriority = 0;

                if (null === $indexAttribute && !$needsIndexes) {
                    $services[] = [$priority, ++$i, null, $serviceId, null];
                    continue 2;
                }

                if (null !== $indexAttribute && isset($attribute[$indexAttribute])) {
                    $index = $attribute[$indexAttribute];
                } elseif (null === $defaultIndex && $defaultIndexMethod && $class) {
                    $defaultIndex = PriorityTaggedServiceUtil::getDefaultIndex($container, $serviceId, $class, $defaultIndexMethod, $tagName, $indexAttribute);
                }
                $index = $index ?? $defaultIndex ?? $defaultIndex = $serviceId;

                $services[] = [$priority, ++$i, $index, $serviceId, $class];
            }
        }

        uasort($services, static function ($a, $b) { return $b[0] <=> $a[0] ?: $a[1] <=> $b[1]; });

        $refs = [];
        foreach ($services as [, , $index, $serviceId, $class]) {
            if (!$class) {
                $reference = new Reference($serviceId);
            } elseif ($index === $serviceId) {
                $reference = new TypedReference($serviceId, $class);
            } else {
                $reference = new TypedReference($serviceId, $class, ContainerBuilder::EXCEPTION_ON_INVALID_REFERENCE, $index);
            }

            if (null === $index) {
                $refs[] = $reference;
            } else {
                $refs[$index] = $reference;
            }
        }

        return $refs;
    }
}

/**
 * @internal
 */
class PriorityTaggedServiceUtil
{
    /**
     * Gets the index defined by the default index method.
     */
    public static function getDefaultIndex(ContainerBuilder $container, string $serviceId, string $class, string $defaultIndexMethod, string $tagName, string $indexAttribute): ?string
    {
        if (!($r = $container->getReflectionClass($class)) || !$r->hasMethod($defaultIndexMethod)) {
            return null;
        }

        if (!($rm = $r->getMethod($defaultIndexMethod))->isStatic()) {
            throw new InvalidArgumentException(sprintf('Either method "%s::%s()" should be static or tag "%s" on service "%s" is missing attribute "%s".', $class, $defaultIndexMethod, $tagName, $serviceId, $indexAttribute));
        }

        if (!$rm->isPublic()) {
            throw new InvalidArgumentException(sprintf('Either method "%s::%s()" should be public or tag "%s" on service "%s" is missing attribute "%s".', $class, $defaultIndexMethod, $tagName, $serviceId, $indexAttribute));
        }

        $defaultIndex = $rm->invoke(null);

        if (!\is_string($defaultIndex)) {
            throw new InvalidArgumentException(sprintf('Either method "%s::%s()" should return a string (got "%s") or tag "%s" on service "%s" is missing attribute "%s".', $class, $defaultIndexMethod, get_debug_type($defaultIndex), $tagName, $serviceId, $indexAttribute));
        }

        return $defaultIndex;
    }

    /**
     * Gets the priority defined by the default priority method.
     */
    public static function getDefaultPriority(ContainerBuilder $container, string $serviceId, string $class, string $defaultPriorityMethod, string $tagName): ?int
    {
        if (!($r = $container->getReflectionClass($class)) || !$r->hasMethod($defaultPriorityMethod)) {
            return null;
        }

        if (!($rm = $r->getMethod($defaultPriorityMethod))->isStatic()) {
            throw new InvalidArgumentException(sprintf('Either method "%s::%s()" should be static or tag "%s" on service "%s" is missing attribute "priority".', $class, $defaultPriorityMethod, $tagName, $serviceId));
        }

        if (!$rm->isPublic()) {
            throw new InvalidArgumentException(sprintf('Either method "%s::%s()" should be public or tag "%s" on service "%s" is missing attribute "priority".', $class, $defaultPriorityMethod, $tagName, $serviceId));
        }

        $defaultPriority = $rm->invoke(null);

        if (!\is_int($defaultPriority)) {
            throw new InvalidArgumentException(sprintf('Method "%s::%s()" should return an integer (got "%s") or tag "%s" on service "%s" is missing attribute "priority".', $class, $defaultPriorityMethod, get_debug_type($defaultPriority), $tagName, $serviceId));
        }

        return $defaultPriority;
    }
}
PKϤ$Z��Eų�9dependency-injection/Compiler/RepeatablePassInterface.phpnu�[���<?php

/*
 * This file is part of the Symfony package.
 *
 * (c) Fabien Potencier <fabien@symfony.com>
 *
 * For the full copyright and license information, please view the LICENSE
 * file that was distributed with this source code.
 */

namespace Symfony\Component\DependencyInjection\Compiler;

/**
 * Interface that must be implemented by passes that are run as part of an
 * RepeatedPass.
 *
 * @author Johannes M. Schmitt <schmittjoh@gmail.com>
 */
interface RepeatablePassInterface extends CompilerPassInterface
{
    /**
     * Sets the RepeatedPass interface.
     *
     * @param RepeatedPass $repeatedPass
     */
    public function setRepeatedPass(RepeatedPass $repeatedPass);
}
PKϤ$Z���!�!Adependency-injection/Compiler/MergeExtensionConfigurationPass.phpnu�[���<?php

/*
 * This file is part of the Symfony package.
 *
 * (c) Fabien Potencier <fabien@symfony.com>
 *
 * For the full copyright and license information, please view the LICENSE
 * file that was distributed with this source code.
 */

namespace Symfony\Component\DependencyInjection\Compiler;

use Symfony\Component\Config\Definition\BaseNode;
use Symfony\Component\DependencyInjection\ContainerBuilder;
use Symfony\Component\DependencyInjection\Exception\LogicException;
use Symfony\Component\DependencyInjection\Exception\RuntimeException;
use Symfony\Component\DependencyInjection\Extension\ConfigurationExtensionInterface;
use Symfony\Component\DependencyInjection\Extension\Extension;
use Symfony\Component\DependencyInjection\Extension\ExtensionInterface;
use Symfony\Component\DependencyInjection\Extension\PrependExtensionInterface;
use Symfony\Component\DependencyInjection\ParameterBag\EnvPlaceholderParameterBag;
use Symfony\Component\DependencyInjection\ParameterBag\ParameterBagInterface;

/**
 * Merges extension configs into the container builder.
 *
 * @author Fabien Potencier <fabien@symfony.com>
 */
class MergeExtensionConfigurationPass implements CompilerPassInterface
{
    /**
     * {@inheritdoc}
     */
    public function process(ContainerBuilder $container)
    {
        $parameters = $container->getParameterBag()->all();
        $definitions = $container->getDefinitions();
        $aliases = $container->getAliases();
        $exprLangProviders = $container->getExpressionLanguageProviders();
        $configAvailable = class_exists(BaseNode::class);

        foreach ($container->getExtensions() as $extension) {
            if ($extension instanceof PrependExtensionInterface) {
                $extension->prepend($container);
            }
        }

        foreach ($container->getExtensions() as $name => $extension) {
            if (!$config = $container->getExtensionConfig($name)) {
                // this extension was not called
                continue;
            }
            $resolvingBag = $container->getParameterBag();
            if ($resolvingBag instanceof EnvPlaceholderParameterBag && $extension instanceof Extension) {
                // create a dedicated bag so that we can track env vars per-extension
                $resolvingBag = new MergeExtensionConfigurationParameterBag($resolvingBag);
                if ($configAvailable) {
                    BaseNode::setPlaceholderUniquePrefix($resolvingBag->getEnvPlaceholderUniquePrefix());
                }
            }
            $config = $resolvingBag->resolveValue($config);

            try {
                $tmpContainer = new MergeExtensionConfigurationContainerBuilder($extension, $resolvingBag);
                $tmpContainer->setResourceTracking($container->isTrackingResources());
                $tmpContainer->addObjectResource($extension);
                if ($extension instanceof ConfigurationExtensionInterface && null !== $configuration = $extension->getConfiguration($config, $tmpContainer)) {
                    $tmpContainer->addObjectResource($configuration);
                }

                foreach ($exprLangProviders as $provider) {
                    $tmpContainer->addExpressionLanguageProvider($provider);
                }

                $extension->load($config, $tmpContainer);
            } catch (\Exception $e) {
                if ($resolvingBag instanceof MergeExtensionConfigurationParameterBag) {
                    $container->getParameterBag()->mergeEnvPlaceholders($resolvingBag);
                }

                if ($configAvailable) {
                    BaseNode::resetPlaceholders();
                }

                throw $e;
            }

            if ($resolvingBag instanceof MergeExtensionConfigurationParameterBag) {
                // don't keep track of env vars that are *overridden* when configs are merged
                $resolvingBag->freezeAfterProcessing($extension, $tmpContainer);
            }

            $container->merge($tmpContainer);
            $container->getParameterBag()->add($parameters);
        }

        if ($configAvailable) {
            BaseNode::resetPlaceholders();
        }

        $container->addDefinitions($definitions);
        $container->addAliases($aliases);
    }
}

/**
 * @internal
 */
class MergeExtensionConfigurationParameterBag extends EnvPlaceholderParameterBag
{
    private $processedEnvPlaceholders;

    public function __construct(parent $parameterBag)
    {
        parent::__construct($parameterBag->all());
        $this->mergeEnvPlaceholders($parameterBag);
    }

    public function freezeAfterProcessing(Extension $extension, ContainerBuilder $container)
    {
        if (!$config = $extension->getProcessedConfigs()) {
            // Extension::processConfiguration() wasn't called, we cannot know how configs were merged
            return;
        }
        $this->processedEnvPlaceholders = [];

        // serialize config and container to catch env vars nested in object graphs
        $config = serialize($config).serialize($container->getDefinitions()).serialize($container->getAliases()).serialize($container->getParameterBag()->all());

        foreach (parent::getEnvPlaceholders() as $env => $placeholders) {
            foreach ($placeholders as $placeholder) {
                if (false !== stripos($config, $placeholder)) {
                    $this->processedEnvPlaceholders[$env] = $placeholders;
                    break;
                }
            }
        }
    }

    /**
     * {@inheritdoc}
     */
    public function getEnvPlaceholders(): array
    {
        return null !== $this->processedEnvPlaceholders ? $this->processedEnvPlaceholders : parent::getEnvPlaceholders();
    }

    public function getUnusedEnvPlaceholders(): array
    {
        return null === $this->processedEnvPlaceholders ? [] : array_diff_key(parent::getEnvPlaceholders(), $this->processedEnvPlaceholders);
    }
}

/**
 * A container builder preventing using methods that wouldn't have any effect from extensions.
 *
 * @internal
 */
class MergeExtensionConfigurationContainerBuilder extends ContainerBuilder
{
    private $extensionClass;

    public function __construct(ExtensionInterface $extension, ParameterBagInterface $parameterBag = null)
    {
        parent::__construct($parameterBag);

        $this->extensionClass = \get_class($extension);
    }

    /**
     * {@inheritdoc}
     */
    public function addCompilerPass(CompilerPassInterface $pass, string $type = PassConfig::TYPE_BEFORE_OPTIMIZATION, int $priority = 0): self
    {
        throw new LogicException(sprintf('You cannot add compiler pass "%s" from extension "%s". Compiler passes must be registered before the container is compiled.', get_debug_type($pass), $this->extensionClass));
    }

    /**
     * {@inheritdoc}
     */
    public function registerExtension(ExtensionInterface $extension)
    {
        throw new LogicException(sprintf('You cannot register extension "%s" from "%s". Extensions must be registered before the container is compiled.', get_debug_type($extension), $this->extensionClass));
    }

    /**
     * {@inheritdoc}
     */
    public function compile(bool $resolveEnvPlaceholders = false)
    {
        throw new LogicException(sprintf('Cannot compile the container in extension "%s".', $this->extensionClass));
    }

    /**
     * {@inheritdoc}
     */
    public function resolveEnvPlaceholders($value, $format = null, array &$usedEnvs = null)
    {
        if (true !== $format || !\is_string($value)) {
            return parent::resolveEnvPlaceholders($value, $format, $usedEnvs);
        }

        $bag = $this->getParameterBag();
        $value = $bag->resolveValue($value);

        if (!$bag instanceof EnvPlaceholderParameterBag) {
            return parent::resolveEnvPlaceholders($value, $format, $usedEnvs);
        }

        foreach ($bag->getEnvPlaceholders() as $env => $placeholders) {
            if (false === strpos($env, ':')) {
                continue;
            }
            foreach ($placeholders as $placeholder) {
                if (false !== stripos($value, $placeholder)) {
                    throw new RuntimeException(sprintf('Using a cast in "env(%s)" is incompatible with resolution at compile time in "%s". The logic in the extension should be moved to a compiler pass, or an env parameter with no cast should be used instead.', $env, $this->extensionClass));
                }
            }
        }

        return parent::resolveEnvPlaceholders($value, $format, $usedEnvs);
    }
}
PKϤ$Z�\�ZZ:dependency-injection/Compiler/RemovePrivateAliasesPass.phpnu�[���<?php

/*
 * This file is part of the Symfony package.
 *
 * (c) Fabien Potencier <fabien@symfony.com>
 *
 * For the full copyright and license information, please view the LICENSE
 * file that was distributed with this source code.
 */

namespace Symfony\Component\DependencyInjection\Compiler;

use Symfony\Component\DependencyInjection\ContainerBuilder;

/**
 * Remove private aliases from the container. They were only used to establish
 * dependencies between services, and these dependencies have been resolved in
 * one of the previous passes.
 *
 * @author Johannes M. Schmitt <schmittjoh@gmail.com>
 */
class RemovePrivateAliasesPass implements CompilerPassInterface
{
    /**
     * Removes private aliases from the ContainerBuilder.
     */
    public function process(ContainerBuilder $container)
    {
        foreach ($container->getAliases() as $id => $alias) {
            if ($alias->isPublic()) {
                continue;
            }

            $container->removeAlias($id);
            $container->log($this, sprintf('Removed service "%s"; reason: private alias.', $id));
        }
    }
}
PKϤ$Z��>6dependency-injection/Compiler/ResolveNoPreloadPass.phpnu�[���<?php

/*
 * This file is part of the Symfony package.
 *
 * (c) Fabien Potencier <fabien@symfony.com>
 *
 * For the full copyright and license information, please view the LICENSE
 * file that was distributed with this source code.
 */

namespace Symfony\Component\DependencyInjection\Compiler;

use Symfony\Component\DependencyInjection\ContainerBuilder;
use Symfony\Component\DependencyInjection\Definition;
use Symfony\Component\DependencyInjection\Reference;

/**
 * Propagate the "container.no_preload" tag.
 *
 * @author Nicolas Grekas <p@tchwork.com>
 */
class ResolveNoPreloadPass extends AbstractRecursivePass
{
    private const DO_PRELOAD_TAG = '.container.do_preload';

    private $tagName;
    private $resolvedIds = [];

    public function __construct(string $tagName = 'container.no_preload')
    {
        $this->tagName = $tagName;
    }

    /**
     * {@inheritdoc}
     */
    public function process(ContainerBuilder $container)
    {
        $this->container = $container;

        try {
            foreach ($container->getDefinitions() as $id => $definition) {
                if ($definition->isPublic() && !$definition->isPrivate() && !isset($this->resolvedIds[$id])) {
                    $this->resolvedIds[$id] = true;
                    $this->processValue($definition, true);
                }
            }

            foreach ($container->getAliases() as $alias) {
                if ($alias->isPublic() && !$alias->isPrivate() && !isset($this->resolvedIds[$id = (string) $alias]) && $container->hasDefinition($id)) {
                    $this->resolvedIds[$id] = true;
                    $this->processValue($container->getDefinition($id), true);
                }
            }
        } finally {
            $this->resolvedIds = [];
            $this->container = null;
        }

        foreach ($container->getDefinitions() as $definition) {
            if ($definition->hasTag(self::DO_PRELOAD_TAG)) {
                $definition->clearTag(self::DO_PRELOAD_TAG);
            } elseif (!$definition->isDeprecated() && !$definition->hasErrors()) {
                $definition->addTag($this->tagName);
            }
        }
    }

    /**
     * {@inheritdoc}
     */
    protected function processValue($value, bool $isRoot = false)
    {
        if ($value instanceof Reference && ContainerBuilder::IGNORE_ON_UNINITIALIZED_REFERENCE !== $value->getInvalidBehavior() && $this->container->hasDefinition($id = (string) $value)) {
            $definition = $this->container->getDefinition($id);

            if (!isset($this->resolvedIds[$id]) && (!$definition->isPublic() || $definition->isPrivate())) {
                $this->resolvedIds[$id] = true;
                $this->processValue($definition, true);
            }

            return $value;
        }

        if (!$value instanceof Definition) {
            return parent::processValue($value, $isRoot);
        }

        if ($value->hasTag($this->tagName) || $value->isDeprecated() || $value->hasErrors()) {
            return $value;
        }

        if ($isRoot) {
            $value->addTag(self::DO_PRELOAD_TAG);
        }

        return parent::processValue($value, $isRoot);
    }
}
PKϤ$Z��R%��<dependency-injection/Compiler/CheckReferenceValidityPass.phpnu�[���<?php

/*
 * This file is part of the Symfony package.
 *
 * (c) Fabien Potencier <fabien@symfony.com>
 *
 * For the full copyright and license information, please view the LICENSE
 * file that was distributed with this source code.
 */

namespace Symfony\Component\DependencyInjection\Compiler;

use Symfony\Component\DependencyInjection\Definition;
use Symfony\Component\DependencyInjection\Exception\RuntimeException;
use Symfony\Component\DependencyInjection\Reference;

/**
 * Checks the validity of references.
 *
 * The following checks are performed by this pass:
 * - target definitions are not abstract
 *
 * @author Johannes M. Schmitt <schmittjoh@gmail.com>
 */
class CheckReferenceValidityPass extends AbstractRecursivePass
{
    protected function processValue($value, bool $isRoot = false)
    {
        if ($isRoot && $value instanceof Definition && ($value->isSynthetic() || $value->isAbstract())) {
            return $value;
        }
        if ($value instanceof Reference && $this->container->hasDefinition((string) $value)) {
            $targetDefinition = $this->container->getDefinition((string) $value);

            if ($targetDefinition->isAbstract()) {
                throw new RuntimeException(sprintf('The definition "%s" has a reference to an abstract definition "%s". Abstract definitions cannot be the target of references.', $this->currentId, $value));
            }
        }

        return parent::processValue($value, $isRoot);
    }
}
PKϤ$Z�v�""Ndependency-injection/Compiler/CheckExceptionOnInvalidReferenceBehaviorPass.phpnu�[���<?php

/*
 * This file is part of the Symfony package.
 *
 * (c) Fabien Potencier <fabien@symfony.com>
 *
 * For the full copyright and license information, please view the LICENSE
 * file that was distributed with this source code.
 */

namespace Symfony\Component\DependencyInjection\Compiler;

use Symfony\Component\DependencyInjection\ContainerBuilder;
use Symfony\Component\DependencyInjection\ContainerInterface;
use Symfony\Component\DependencyInjection\Exception\ServiceNotFoundException;
use Symfony\Component\DependencyInjection\Reference;

/**
 * Checks that all references are pointing to a valid service.
 *
 * @author Johannes M. Schmitt <schmittjoh@gmail.com>
 */
class CheckExceptionOnInvalidReferenceBehaviorPass extends AbstractRecursivePass
{
    private $serviceLocatorContextIds = [];

    /**
     * {@inheritdoc}
     */
    public function process(ContainerBuilder $container)
    {
        $this->serviceLocatorContextIds = [];
        foreach ($container->findTaggedServiceIds('container.service_locator_context') as $id => $tags) {
            $this->serviceLocatorContextIds[$id] = $tags[0]['id'];
            $container->getDefinition($id)->clearTag('container.service_locator_context');
        }

        try {
            return parent::process($container);
        } finally {
            $this->serviceLocatorContextIds = [];
        }
    }

    protected function processValue($value, bool $isRoot = false)
    {
        if (!$value instanceof Reference) {
            return parent::processValue($value, $isRoot);
        }
        if (ContainerInterface::EXCEPTION_ON_INVALID_REFERENCE < $value->getInvalidBehavior() || $this->container->has($id = (string) $value)) {
            return $value;
        }

        $currentId = $this->currentId;
        $graph = $this->container->getCompiler()->getServiceReferenceGraph();

        if (isset($this->serviceLocatorContextIds[$currentId])) {
            $currentId = $this->serviceLocatorContextIds[$currentId];
            $locator = $this->container->getDefinition($this->currentId)->getFactory()[0];

            foreach ($locator->getArgument(0) as $k => $v) {
                if ($v->getValues()[0] === $value) {
                    if ($k !== $id) {
                        $currentId = $k.'" in the container provided to "'.$currentId;
                    }
                    throw new ServiceNotFoundException($id, $currentId);
                }
            }
        }

        if ('.' === $currentId[0] && $graph->hasNode($currentId)) {
            foreach ($graph->getNode($currentId)->getInEdges() as $edge) {
                if (!$edge->getValue() instanceof Reference || ContainerInterface::EXCEPTION_ON_INVALID_REFERENCE < $edge->getValue()->getInvalidBehavior()) {
                    continue;
                }
                $sourceId = $edge->getSourceNode()->getId();

                if ('.' !== $sourceId[0]) {
                    $currentId = $sourceId;
                    break;
                }
            }
        }

        throw new ServiceNotFoundException($id, $currentId);
    }
}
PKϤ$Z��(��*dependency-injection/Compiler/Compiler.phpnu�[���<?php

/*
 * This file is part of the Symfony package.
 *
 * (c) Fabien Potencier <fabien@symfony.com>
 *
 * For the full copyright and license information, please view the LICENSE
 * file that was distributed with this source code.
 */

namespace Symfony\Component\DependencyInjection\Compiler;

use Symfony\Component\DependencyInjection\ContainerBuilder;
use Symfony\Component\DependencyInjection\Exception\EnvParameterException;

/**
 * This class is used to remove circular dependencies between individual passes.
 *
 * @author Johannes M. Schmitt <schmittjoh@gmail.com>
 */
class Compiler
{
    private $passConfig;
    private $log = [];
    private $serviceReferenceGraph;

    public function __construct()
    {
        $this->passConfig = new PassConfig();
        $this->serviceReferenceGraph = new ServiceReferenceGraph();
    }

    /**
     * Returns the PassConfig.
     *
     * @return PassConfig The PassConfig instance
     */
    public function getPassConfig()
    {
        return $this->passConfig;
    }

    /**
     * Returns the ServiceReferenceGraph.
     *
     * @return ServiceReferenceGraph The ServiceReferenceGraph instance
     */
    public function getServiceReferenceGraph()
    {
        return $this->serviceReferenceGraph;
    }

    /**
     * Adds a pass to the PassConfig.
     */
    public function addPass(CompilerPassInterface $pass, string $type = PassConfig::TYPE_BEFORE_OPTIMIZATION, int $priority = 0)
    {
        $this->passConfig->addPass($pass, $type, $priority);
    }

    /**
     * @final
     */
    public function log(CompilerPassInterface $pass, string $message)
    {
        if (false !== strpos($message, "\n")) {
            $message = str_replace("\n", "\n".\get_class($pass).': ', trim($message));
        }

        $this->log[] = \get_class($pass).': '.$message;
    }

    /**
     * Returns the log.
     *
     * @return array Log array
     */
    public function getLog()
    {
        return $this->log;
    }

    /**
     * Run the Compiler and process all Passes.
     */
    public function compile(ContainerBuilder $container)
    {
        try {
            foreach ($this->passConfig->getPasses() as $pass) {
                $pass->process($container);
            }
        } catch (\Exception $e) {
            $usedEnvs = [];
            $prev = $e;

            do {
                $msg = $prev->getMessage();

                if ($msg !== $resolvedMsg = $container->resolveEnvPlaceholders($msg, null, $usedEnvs)) {
                    $r = new \ReflectionProperty($prev, 'message');
                    $r->setAccessible(true);
                    $r->setValue($prev, $resolvedMsg);
                }
            } while ($prev = $prev->getPrevious());

            if ($usedEnvs) {
                $e = new EnvParameterException($usedEnvs, $e);
            }

            throw $e;
        } finally {
            $this->getServiceReferenceGraph()->clear();
        }
    }
}
PKϤ$Z�__@dependency-injection/Compiler/RegisterServiceSubscribersPass.phpnu�[���<?php

/*
 * This file is part of the Symfony package.
 *
 * (c) Fabien Potencier <fabien@symfony.com>
 *
 * For the full copyright and license information, please view the LICENSE
 * file that was distributed with this source code.
 */

namespace Symfony\Component\DependencyInjection\Compiler;

use Psr\Container\ContainerInterface as PsrContainerInterface;
use Symfony\Component\DependencyInjection\Argument\BoundArgument;
use Symfony\Component\DependencyInjection\ContainerInterface;
use Symfony\Component\DependencyInjection\Definition;
use Symfony\Component\DependencyInjection\Exception\InvalidArgumentException;
use Symfony\Component\DependencyInjection\Reference;
use Symfony\Component\DependencyInjection\TypedReference;
use Symfony\Contracts\Service\ServiceProviderInterface;
use Symfony\Contracts\Service\ServiceSubscriberInterface;

/**
 * Compiler pass to register tagged services that require a service locator.
 *
 * @author Nicolas Grekas <p@tchwork.com>
 */
class RegisterServiceSubscribersPass extends AbstractRecursivePass
{
    protected function processValue($value, bool $isRoot = false)
    {
        if (!$value instanceof Definition || $value->isAbstract() || $value->isSynthetic() || !$value->hasTag('container.service_subscriber')) {
            return parent::processValue($value, $isRoot);
        }

        $serviceMap = [];
        $autowire = $value->isAutowired();

        foreach ($value->getTag('container.service_subscriber') as $attributes) {
            if (!$attributes) {
                $autowire = true;
                continue;
            }
            ksort($attributes);
            if ([] !== array_diff(array_keys($attributes), ['id', 'key'])) {
                throw new InvalidArgumentException(sprintf('The "container.service_subscriber" tag accepts only the "key" and "id" attributes, "%s" given for service "%s".', implode('", "', array_keys($attributes)), $this->currentId));
            }
            if (!\array_key_exists('id', $attributes)) {
                throw new InvalidArgumentException(sprintf('Missing "id" attribute on "container.service_subscriber" tag with key="%s" for service "%s".', $attributes['key'], $this->currentId));
            }
            if (!\array_key_exists('key', $attributes)) {
                $attributes['key'] = $attributes['id'];
            }
            if (isset($serviceMap[$attributes['key']])) {
                continue;
            }
            $serviceMap[$attributes['key']] = new Reference($attributes['id']);
        }
        $class = $value->getClass();

        if (!$r = $this->container->getReflectionClass($class)) {
            throw new InvalidArgumentException(sprintf('Class "%s" used for service "%s" cannot be found.', $class, $this->currentId));
        }
        if (!$r->isSubclassOf(ServiceSubscriberInterface::class)) {
            throw new InvalidArgumentException(sprintf('Service "%s" must implement interface "%s".', $this->currentId, ServiceSubscriberInterface::class));
        }
        $class = $r->name;

        $subscriberMap = [];

        foreach ($class::getSubscribedServices() as $key => $type) {
            if (!\is_string($type) || !preg_match('/^\??[a-zA-Z_\x7f-\xff][a-zA-Z0-9_\x7f-\xff]*+(?:\\\\[a-zA-Z_\x7f-\xff][a-zA-Z0-9_\x7f-\xff]*+)*+$/', $type)) {
                throw new InvalidArgumentException(sprintf('"%s::getSubscribedServices()" must return valid PHP types for service "%s" key "%s", "%s" returned.', $class, $this->currentId, $key, \is_string($type) ? $type : get_debug_type($type)));
            }
            if ($optionalBehavior = '?' === $type[0]) {
                $type = substr($type, 1);
                $optionalBehavior = ContainerInterface::IGNORE_ON_INVALID_REFERENCE;
            }
            if (\is_int($name = $key)) {
                $key = $type;
                $name = null;
            }
            if (!isset($serviceMap[$key])) {
                if (!$autowire) {
                    throw new InvalidArgumentException(sprintf('Service "%s" misses a "container.service_subscriber" tag with "key"/"id" attributes corresponding to entry "%s" as returned by "%s::getSubscribedServices()".', $this->currentId, $key, $class));
                }
                $serviceMap[$key] = new Reference($type);
            }

            if (false !== $i = strpos($name, '::get')) {
                $name = lcfirst(substr($name, 5 + $i));
            } elseif (false !== strpos($name, '::')) {
                $name = null;
            }

            if (null !== $name && !$this->container->has($name) && !$this->container->has($type.' $'.$name)) {
                $camelCaseName = lcfirst(str_replace(' ', '', ucwords(preg_replace('/[^a-zA-Z0-9\x7f-\xff]++/', ' ', $name))));
                $name = $this->container->has($type.' $'.$camelCaseName) ? $camelCaseName : $name;
            }

            $subscriberMap[$key] = new TypedReference((string) $serviceMap[$key], $type, $optionalBehavior ?: ContainerInterface::EXCEPTION_ON_INVALID_REFERENCE, $name);
            unset($serviceMap[$key]);
        }

        if ($serviceMap = array_keys($serviceMap)) {
            $message = sprintf(1 < \count($serviceMap) ? 'keys "%s" do' : 'key "%s" does', str_replace('%', '%%', implode('", "', $serviceMap)));
            throw new InvalidArgumentException(sprintf('Service %s not exist in the map returned by "%s::getSubscribedServices()" for service "%s".', $message, $class, $this->currentId));
        }

        $locatorRef = ServiceLocatorTagPass::register($this->container, $subscriberMap, $this->currentId);

        $value->addTag('container.service_subscriber.locator', ['id' => (string) $locatorRef]);

        $value->setBindings([
            PsrContainerInterface::class => new BoundArgument($locatorRef, false),
            ServiceProviderInterface::class => new BoundArgument($locatorRef, false),
        ] + $value->getBindings());

        return parent::processValue($value);
    }
}
PKϤ$Z���,,=dependency-injection/Compiler/RemoveUnusedDefinitionsPass.phpnu�[���<?php

/*
 * This file is part of the Symfony package.
 *
 * (c) Fabien Potencier <fabien@symfony.com>
 *
 * For the full copyright and license information, please view the LICENSE
 * file that was distributed with this source code.
 */

namespace Symfony\Component\DependencyInjection\Compiler;

use Symfony\Component\DependencyInjection\ContainerBuilder;
use Symfony\Component\DependencyInjection\Reference;

/**
 * Removes unused service definitions from the container.
 *
 * @author Johannes M. Schmitt <schmittjoh@gmail.com>
 * @author Nicolas Grekas <p@tchwork.com>
 */
class RemoveUnusedDefinitionsPass extends AbstractRecursivePass
{
    private $connectedIds = [];

    /**
     * Processes the ContainerBuilder to remove unused definitions.
     */
    public function process(ContainerBuilder $container)
    {
        try {
            $this->enableExpressionProcessing();
            $this->container = $container;
            $connectedIds = [];
            $aliases = $container->getAliases();

            foreach ($aliases as $id => $alias) {
                if ($alias->isPublic()) {
                    $this->connectedIds[] = (string) $aliases[$id];
                }
            }

            foreach ($container->getDefinitions() as $id => $definition) {
                if ($definition->isPublic()) {
                    $connectedIds[$id] = true;
                    $this->processValue($definition);
                }
            }

            while ($this->connectedIds) {
                $ids = $this->connectedIds;
                $this->connectedIds = [];
                foreach ($ids as $id) {
                    if (!isset($connectedIds[$id]) && $container->hasDefinition($id)) {
                        $connectedIds[$id] = true;
                        $this->processValue($container->getDefinition($id));
                    }
                }
            }

            foreach ($container->getDefinitions() as $id => $definition) {
                if (!isset($connectedIds[$id])) {
                    $container->removeDefinition($id);
                    $container->resolveEnvPlaceholders(!$definition->hasErrors() ? serialize($definition) : $definition);
                    $container->log($this, sprintf('Removed service "%s"; reason: unused.', $id));
                }
            }
        } finally {
            $this->container = null;
            $this->connectedIds = [];
        }
    }

    /**
     * {@inheritdoc}
     */
    protected function processValue($value, bool $isRoot = false)
    {
        if (!$value instanceof Reference) {
            return parent::processValue($value, $isRoot);
        }

        if (ContainerBuilder::IGNORE_ON_UNINITIALIZED_REFERENCE !== $value->getInvalidBehavior()) {
            $this->connectedIds[] = (string) $value;
        }

        return $value;
    }
}
PKϤ$Z���h�	�	@dependency-injection/Compiler/ResolveReferencesToAliasesPass.phpnu�[���<?php

/*
 * This file is part of the Symfony package.
 *
 * (c) Fabien Potencier <fabien@symfony.com>
 *
 * For the full copyright and license information, please view the LICENSE
 * file that was distributed with this source code.
 */

namespace Symfony\Component\DependencyInjection\Compiler;

use Symfony\Component\DependencyInjection\ContainerBuilder;
use Symfony\Component\DependencyInjection\Exception\ServiceCircularReferenceException;
use Symfony\Component\DependencyInjection\Reference;

/**
 * Replaces all references to aliases with references to the actual service.
 *
 * @author Johannes M. Schmitt <schmittjoh@gmail.com>
 */
class ResolveReferencesToAliasesPass extends AbstractRecursivePass
{
    /**
     * {@inheritdoc}
     */
    public function process(ContainerBuilder $container)
    {
        parent::process($container);

        foreach ($container->getAliases() as $id => $alias) {
            $aliasId = (string) $alias;
            $this->currentId = $id;

            if ($aliasId !== $defId = $this->getDefinitionId($aliasId, $container)) {
                $container->setAlias($id, $defId)->setPublic($alias->isPublic())->setPrivate($alias->isPrivate());
            }
        }
    }

    /**
     * {@inheritdoc}
     */
    protected function processValue($value, bool $isRoot = false)
    {
        if (!$value instanceof Reference) {
            return parent::processValue($value, $isRoot);
        }

        $defId = $this->getDefinitionId($id = (string) $value, $this->container);

        return $defId !== $id ? new Reference($defId, $value->getInvalidBehavior()) : $value;
    }

    private function getDefinitionId(string $id, ContainerBuilder $container): string
    {
        if (!$container->hasAlias($id)) {
            return $id;
        }

        $alias = $container->getAlias($id);

        if ($alias->isDeprecated()) {
            $deprecation = $alias->getDeprecation($id);
            trigger_deprecation($deprecation['package'], $deprecation['version'], rtrim($deprecation['message'], '. ').'. It is being referenced by the "%s" '.($container->hasDefinition($this->currentId) ? 'service.' : 'alias.'), $this->currentId);
        }

        $seen = [];
        do {
            if (isset($seen[$id])) {
                throw new ServiceCircularReferenceException($id, array_merge(array_keys($seen), [$id]));
            }

            $seen[$id] = true;
            $id = (string) $container->getAlias($id);
        } while ($container->hasAlias($id));

        return $id;
    }
}
PKϤ$Z;>�,,7dependency-injection/Compiler/ServiceLocatorTagPass.phpnu�[���<?php

/*
 * This file is part of the Symfony package.
 *
 * (c) Fabien Potencier <fabien@symfony.com>
 *
 * For the full copyright and license information, please view the LICENSE
 * file that was distributed with this source code.
 */

namespace Symfony\Component\DependencyInjection\Compiler;

use Symfony\Component\DependencyInjection\Alias;
use Symfony\Component\DependencyInjection\Argument\ServiceClosureArgument;
use Symfony\Component\DependencyInjection\Argument\ServiceLocatorArgument;
use Symfony\Component\DependencyInjection\ContainerBuilder;
use Symfony\Component\DependencyInjection\Definition;
use Symfony\Component\DependencyInjection\Exception\InvalidArgumentException;
use Symfony\Component\DependencyInjection\Reference;
use Symfony\Component\DependencyInjection\ServiceLocator;

/**
 * Applies the "container.service_locator" tag by wrapping references into ServiceClosureArgument instances.
 *
 * @author Nicolas Grekas <p@tchwork.com>
 */
final class ServiceLocatorTagPass extends AbstractRecursivePass
{
    use PriorityTaggedServiceTrait;

    protected function processValue($value, bool $isRoot = false)
    {
        if ($value instanceof ServiceLocatorArgument) {
            if ($value->getTaggedIteratorArgument()) {
                $value->setValues($this->findAndSortTaggedServices($value->getTaggedIteratorArgument(), $this->container));
            }

            return self::register($this->container, $value->getValues());
        }

        if (!$value instanceof Definition || !$value->hasTag('container.service_locator')) {
            return parent::processValue($value, $isRoot);
        }

        if (!$value->getClass()) {
            $value->setClass(ServiceLocator::class);
        }

        $arguments = $value->getArguments();
        if (!isset($arguments[0]) || !\is_array($arguments[0])) {
            throw new InvalidArgumentException(sprintf('Invalid definition for service "%s": an array of references is expected as first argument when the "container.service_locator" tag is set.', $this->currentId));
        }

        $i = 0;

        foreach ($arguments[0] as $k => $v) {
            if ($v instanceof ServiceClosureArgument) {
                continue;
            }
            if (!$v instanceof Reference) {
                throw new InvalidArgumentException(sprintf('Invalid definition for service "%s": an array of references is expected as first argument when the "container.service_locator" tag is set, "%s" found for key "%s".', $this->currentId, get_debug_type($v), $k));
            }

            if ($i === $k) {
                unset($arguments[0][$k]);

                $k = (string) $v;
                ++$i;
            } elseif (\is_int($k)) {
                $i = null;
            }
            $arguments[0][$k] = new ServiceClosureArgument($v);
        }
        ksort($arguments[0]);

        $value->setArguments($arguments);

        $id = '.service_locator.'.ContainerBuilder::hash($value);

        if ($isRoot) {
            if ($id !== $this->currentId) {
                $this->container->setAlias($id, new Alias($this->currentId, false));
            }

            return $value;
        }

        $this->container->setDefinition($id, $value->setPublic(false));

        return new Reference($id);
    }

    /**
     * @param Reference[] $refMap
     */
    public static function register(ContainerBuilder $container, array $refMap, string $callerId = null): Reference
    {
        foreach ($refMap as $id => $ref) {
            if (!$ref instanceof Reference) {
                throw new InvalidArgumentException(sprintf('Invalid service locator definition: only services can be referenced, "%s" found for key "%s". Inject parameter values using constructors instead.', get_debug_type($ref), $id));
            }
            $refMap[$id] = new ServiceClosureArgument($ref);
        }
        ksort($refMap);

        $locator = (new Definition(ServiceLocator::class))
            ->addArgument($refMap)
            ->setPublic(false)
            ->addTag('container.service_locator');

        if (null !== $callerId && $container->hasDefinition($callerId)) {
            $locator->setBindings($container->getDefinition($callerId)->getBindings());
        }

        if (!$container->hasDefinition($id = '.service_locator.'.ContainerBuilder::hash($locator))) {
            $container->setDefinition($id, $locator);
        }

        if (null !== $callerId) {
            $locatorId = $id;
            // Locators are shared when they hold the exact same list of factories;
            // to have them specialized per consumer service, we use a cloning factory
            // to derivate customized instances from the prototype one.
            $container->register($id .= '.'.$callerId, ServiceLocator::class)
                ->setPublic(false)
                ->setFactory([new Reference($locatorId), 'withContext'])
                ->addTag('container.service_locator_context', ['id' => $callerId])
                ->addArgument($callerId)
                ->addArgument(new Reference('service_container'));
        }

        return new Reference($id);
    }
}
PKϤ$Z$�;���>dependency-injection/Compiler/RegisterReverseContainerPass.phpnu�[���<?php

/*
 * This file is part of the Symfony package.
 *
 * (c) Fabien Potencier <fabien@symfony.com>
 *
 * For the full copyright and license information, please view the LICENSE
 * file that was distributed with this source code.
 */

namespace Symfony\Component\DependencyInjection\Compiler;

use Symfony\Component\DependencyInjection\Argument\ServiceClosureArgument;
use Symfony\Component\DependencyInjection\ContainerBuilder;
use Symfony\Component\DependencyInjection\ContainerInterface;
use Symfony\Component\DependencyInjection\Definition;
use Symfony\Component\DependencyInjection\Reference;

/**
 * @author Nicolas Grekas <p@tchwork.com>
 */
class RegisterReverseContainerPass implements CompilerPassInterface
{
    private $beforeRemoving;
    private $serviceId;
    private $tagName;

    public function __construct(bool $beforeRemoving, string $serviceId = 'reverse_container', string $tagName = 'container.reversible')
    {
        $this->beforeRemoving = $beforeRemoving;
        $this->serviceId = $serviceId;
        $this->tagName = $tagName;
    }

    public function process(ContainerBuilder $container)
    {
        if (!$container->hasDefinition($this->serviceId)) {
            return;
        }

        $refType = $this->beforeRemoving ? ContainerInterface::IGNORE_ON_UNINITIALIZED_REFERENCE : ContainerInterface::EXCEPTION_ON_INVALID_REFERENCE;
        $services = [];
        foreach ($container->findTaggedServiceIds($this->tagName) as $id => $tags) {
            $services[$id] = new Reference($id, $refType);
        }

        if ($this->beforeRemoving) {
            // prevent inlining of the reverse container
            $services[$this->serviceId] = new Reference($this->serviceId, $refType);
        }
        $locator = $container->getDefinition($this->serviceId)->getArgument(1);

        if ($locator instanceof Reference) {
            $locator = $container->getDefinition((string) $locator);
        }
        if ($locator instanceof Definition) {
            foreach ($services as $id => $ref) {
                $services[$id] = new ServiceClosureArgument($ref);
            }
            $locator->replaceArgument(0, $services);
        } else {
            $locator->setValues($services);
        }
    }
}
PKϤ$Z$�Ő	�	=dependency-injection/Compiler/CheckCircularReferencesPass.phpnu�[���<?php

/*
 * This file is part of the Symfony package.
 *
 * (c) Fabien Potencier <fabien@symfony.com>
 *
 * For the full copyright and license information, please view the LICENSE
 * file that was distributed with this source code.
 */

namespace Symfony\Component\DependencyInjection\Compiler;

use Symfony\Component\DependencyInjection\ContainerBuilder;
use Symfony\Component\DependencyInjection\Exception\ServiceCircularReferenceException;

/**
 * Checks your services for circular references.
 *
 * References from method calls are ignored since we might be able to resolve
 * these references depending on the order in which services are called.
 *
 * Circular reference from method calls will only be detected at run-time.
 *
 * @author Johannes M. Schmitt <schmittjoh@gmail.com>
 */
class CheckCircularReferencesPass implements CompilerPassInterface
{
    private $currentPath;
    private $checkedNodes;

    /**
     * Checks the ContainerBuilder object for circular references.
     */
    public function process(ContainerBuilder $container)
    {
        $graph = $container->getCompiler()->getServiceReferenceGraph();

        $this->checkedNodes = [];
        foreach ($graph->getNodes() as $id => $node) {
            $this->currentPath = [$id];

            $this->checkOutEdges($node->getOutEdges());
        }
    }

    /**
     * Checks for circular references.
     *
     * @param ServiceReferenceGraphEdge[] $edges An array of Edges
     *
     * @throws ServiceCircularReferenceException when a circular reference is found
     */
    private function checkOutEdges(array $edges)
    {
        foreach ($edges as $edge) {
            $node = $edge->getDestNode();
            $id = $node->getId();

            if (empty($this->checkedNodes[$id])) {
                // Don't check circular references for lazy edges
                if (!$node->getValue() || (!$edge->isLazy() && !$edge->isWeak())) {
                    $searchKey = array_search($id, $this->currentPath);
                    $this->currentPath[] = $id;

                    if (false !== $searchKey) {
                        throw new ServiceCircularReferenceException($id, \array_slice($this->currentPath, $searchKey));
                    }

                    $this->checkOutEdges($node->getOutEdges());
                }

                $this->checkedNodes[$id] = true;
                array_pop($this->currentPath);
            }
        }
    }
}
PKϤ$Z`2,c�
�
Ddependency-injection/Compiler/ReplaceAliasByActualDefinitionPass.phpnu�[���<?php

/*
 * This file is part of the Symfony package.
 *
 * (c) Fabien Potencier <fabien@symfony.com>
 *
 * For the full copyright and license information, please view the LICENSE
 * file that was distributed with this source code.
 */

namespace Symfony\Component\DependencyInjection\Compiler;

use Symfony\Component\DependencyInjection\ContainerBuilder;
use Symfony\Component\DependencyInjection\Exception\InvalidArgumentException;
use Symfony\Component\DependencyInjection\Exception\ServiceNotFoundException;
use Symfony\Component\DependencyInjection\Reference;

/**
 * Replaces aliases with actual service definitions, effectively removing these
 * aliases.
 *
 * @author Johannes M. Schmitt <schmittjoh@gmail.com>
 */
class ReplaceAliasByActualDefinitionPass extends AbstractRecursivePass
{
    private $replacements;

    /**
     * Process the Container to replace aliases with service definitions.
     *
     * @throws InvalidArgumentException if the service definition does not exist
     */
    public function process(ContainerBuilder $container)
    {
        // First collect all alias targets that need to be replaced
        $seenAliasTargets = [];
        $replacements = [];
        foreach ($container->getAliases() as $definitionId => $target) {
            $targetId = (string) $target;
            // Special case: leave this target alone
            if ('service_container' === $targetId) {
                continue;
            }
            // Check if target needs to be replaces
            if (isset($replacements[$targetId])) {
                $container->setAlias($definitionId, $replacements[$targetId])->setPublic($target->isPublic())->setPrivate($target->isPrivate());
            }
            // No need to process the same target twice
            if (isset($seenAliasTargets[$targetId])) {
                continue;
            }
            // Process new target
            $seenAliasTargets[$targetId] = true;
            try {
                $definition = $container->getDefinition($targetId);
            } catch (ServiceNotFoundException $e) {
                if ('' !== $e->getId() && '@' === $e->getId()[0]) {
                    throw new ServiceNotFoundException($e->getId(), $e->getSourceId(), null, [substr($e->getId(), 1)]);
                }

                throw $e;
            }
            if ($definition->isPublic()) {
                continue;
            }
            // Remove private definition and schedule for replacement
            $definition->setPublic(!$target->isPrivate());
            $definition->setPrivate($target->isPrivate());
            $container->setDefinition($definitionId, $definition);
            $container->removeDefinition($targetId);
            $replacements[$targetId] = $definitionId;
        }
        $this->replacements = $replacements;

        parent::process($container);
        $this->replacements = [];
    }

    /**
     * {@inheritdoc}
     */
    protected function processValue($value, bool $isRoot = false)
    {
        if ($value instanceof Reference && isset($this->replacements[$referenceId = (string) $value])) {
            // Perform the replacement
            $newId = $this->replacements[$referenceId];
            $value = new Reference($newId, $value->getInvalidBehavior());
            $this->container->log($this, sprintf('Changed reference of service "%s" previously pointing to "%s" to "%s".', $this->currentId, $referenceId, $newId));
        }

        return parent::processValue($value, $isRoot);
    }
}
PKϤ$Z�@�r>dependency-injection/Compiler/InlineServiceDefinitionsPass.phpnu�[���<?php

/*
 * This file is part of the Symfony package.
 *
 * (c) Fabien Potencier <fabien@symfony.com>
 *
 * For the full copyright and license information, please view the LICENSE
 * file that was distributed with this source code.
 */

namespace Symfony\Component\DependencyInjection\Compiler;

use Symfony\Component\DependencyInjection\Argument\ArgumentInterface;
use Symfony\Component\DependencyInjection\ContainerBuilder;
use Symfony\Component\DependencyInjection\Definition;
use Symfony\Component\DependencyInjection\Exception\ServiceCircularReferenceException;
use Symfony\Component\DependencyInjection\Reference;

/**
 * Inline service definitions where this is possible.
 *
 * @author Johannes M. Schmitt <schmittjoh@gmail.com>
 */
class InlineServiceDefinitionsPass extends AbstractRecursivePass
{
    private $analyzingPass;
    private $cloningIds = [];
    private $connectedIds = [];
    private $notInlinedIds = [];
    private $inlinedIds = [];
    private $notInlinableIds = [];
    private $graph;

    public function __construct(AnalyzeServiceReferencesPass $analyzingPass = null)
    {
        $this->analyzingPass = $analyzingPass;
    }

    public function process(ContainerBuilder $container)
    {
        $this->container = $container;
        if ($this->analyzingPass) {
            $analyzedContainer = new ContainerBuilder();
            $analyzedContainer->setAliases($container->getAliases());
            $analyzedContainer->setDefinitions($container->getDefinitions());
            foreach ($container->getExpressionLanguageProviders() as $provider) {
                $analyzedContainer->addExpressionLanguageProvider($provider);
            }
        } else {
            $analyzedContainer = $container;
        }
        try {
            $remainingInlinedIds = [];
            $this->connectedIds = $this->notInlinedIds = $container->getDefinitions();
            do {
                if ($this->analyzingPass) {
                    $analyzedContainer->setDefinitions(array_intersect_key($analyzedContainer->getDefinitions(), $this->connectedIds));
                    $this->analyzingPass->process($analyzedContainer);
                }
                $this->graph = $analyzedContainer->getCompiler()->getServiceReferenceGraph();
                $notInlinedIds = $this->notInlinedIds;
                $this->connectedIds = $this->notInlinedIds = $this->inlinedIds = [];

                foreach ($analyzedContainer->getDefinitions() as $id => $definition) {
                    if (!$this->graph->hasNode($id)) {
                        continue;
                    }
                    foreach ($this->graph->getNode($id)->getOutEdges() as $edge) {
                        if (isset($notInlinedIds[$edge->getSourceNode()->getId()])) {
                            $this->currentId = $id;
                            $this->processValue($definition, true);
                            break;
                        }
                    }
                }

                foreach ($this->inlinedIds as $id => $isPublicOrNotShared) {
                    if ($isPublicOrNotShared) {
                        $remainingInlinedIds[$id] = $id;
                    } else {
                        $container->removeDefinition($id);
                        $analyzedContainer->removeDefinition($id);
                    }
                }
            } while ($this->inlinedIds && $this->analyzingPass);

            foreach ($remainingInlinedIds as $id) {
                if (isset($this->notInlinableIds[$id])) {
                    continue;
                }

                $definition = $container->getDefinition($id);

                if (!$definition->isShared() && !$definition->isPublic()) {
                    $container->removeDefinition($id);
                }
            }
        } finally {
            $this->container = null;
            $this->connectedIds = $this->notInlinedIds = $this->inlinedIds = [];
            $this->notInlinableIds = [];
            $this->graph = null;
        }
    }

    /**
     * {@inheritdoc}
     */
    protected function processValue($value, bool $isRoot = false)
    {
        if ($value instanceof ArgumentInterface) {
            // Reference found in ArgumentInterface::getValues() are not inlineable
            return $value;
        }

        if ($value instanceof Definition && $this->cloningIds) {
            if ($value->isShared()) {
                return $value;
            }
            $value = clone $value;
        }

        if (!$value instanceof Reference) {
            return parent::processValue($value, $isRoot);
        } elseif (!$this->container->hasDefinition($id = (string) $value)) {
            return $value;
        }

        $definition = $this->container->getDefinition($id);

        if (!$this->isInlineableDefinition($id, $definition)) {
            $this->notInlinableIds[$id] = true;

            return $value;
        }

        $this->container->log($this, sprintf('Inlined service "%s" to "%s".', $id, $this->currentId));
        $this->inlinedIds[$id] = $definition->isPublic() || !$definition->isShared();
        $this->notInlinedIds[$this->currentId] = true;

        if ($definition->isShared()) {
            return $definition;
        }

        if (isset($this->cloningIds[$id])) {
            $ids = array_keys($this->cloningIds);
            $ids[] = $id;

            throw new ServiceCircularReferenceException($id, \array_slice($ids, array_search($id, $ids)));
        }

        $this->cloningIds[$id] = true;
        try {
            return $this->processValue($definition);
        } finally {
            unset($this->cloningIds[$id]);
        }
    }

    /**
     * Checks if the definition is inlineable.
     */
    private function isInlineableDefinition(string $id, Definition $definition): bool
    {
        if ($definition->hasErrors() || $definition->isDeprecated() || $definition->isLazy() || $definition->isSynthetic()) {
            return false;
        }

        if (!$definition->isShared()) {
            if (!$this->graph->hasNode($id)) {
                return true;
            }

            foreach ($this->graph->getNode($id)->getInEdges() as $edge) {
                $srcId = $edge->getSourceNode()->getId();
                $this->connectedIds[$srcId] = true;
                if ($edge->isWeak() || $edge->isLazy()) {
                    return false;
                }
            }

            return true;
        }

        if ($definition->isPublic()) {
            return false;
        }

        if (!$this->graph->hasNode($id)) {
            return true;
        }

        if ($this->currentId == $id) {
            return false;
        }
        $this->connectedIds[$id] = true;

        $srcIds = [];
        $srcCount = 0;
        $isReferencedByConstructor = false;
        foreach ($this->graph->getNode($id)->getInEdges() as $edge) {
            $isReferencedByConstructor = $isReferencedByConstructor || $edge->isReferencedByConstructor();
            $srcId = $edge->getSourceNode()->getId();
            $this->connectedIds[$srcId] = true;
            if ($edge->isWeak() || $edge->isLazy()) {
                return false;
            }
            $srcIds[$srcId] = true;
            ++$srcCount;
        }

        if (1 !== \count($srcIds)) {
            $this->notInlinedIds[$id] = true;

            return false;
        }

        if ($srcCount > 1 && \is_array($factory = $definition->getFactory()) && ($factory[0] instanceof Reference || $factory[0] instanceof Definition)) {
            return false;
        }

        return $this->container->getDefinition($srcId)->isShared();
    }
}
PKϤ$Z}H�w--;dependency-injection/Compiler/CheckTypeDeclarationsPass.phpnu�[���<?php

/*
 * This file is part of the Symfony package.
 *
 * (c) Fabien Potencier <fabien@symfony.com>
 *
 * For the full copyright and license information, please view the LICENSE
 * file that was distributed with this source code.
 */

namespace Symfony\Component\DependencyInjection\Compiler;

use Symfony\Component\DependencyInjection\Argument\IteratorArgument;
use Symfony\Component\DependencyInjection\Argument\RewindableGenerator;
use Symfony\Component\DependencyInjection\Argument\ServiceClosureArgument;
use Symfony\Component\DependencyInjection\Argument\ServiceLocatorArgument;
use Symfony\Component\DependencyInjection\Container;
use Symfony\Component\DependencyInjection\Definition;
use Symfony\Component\DependencyInjection\Exception\InvalidArgumentException;
use Symfony\Component\DependencyInjection\Exception\InvalidParameterTypeException;
use Symfony\Component\DependencyInjection\Exception\RuntimeException;
use Symfony\Component\DependencyInjection\ExpressionLanguage;
use Symfony\Component\DependencyInjection\Parameter;
use Symfony\Component\DependencyInjection\ParameterBag\EnvPlaceholderParameterBag;
use Symfony\Component\DependencyInjection\Reference;
use Symfony\Component\DependencyInjection\ServiceLocator;
use Symfony\Component\ExpressionLanguage\Expression;

/**
 * Checks whether injected parameters are compatible with type declarations.
 *
 * This pass should be run after all optimization passes.
 *
 * It can be added either:
 *  * before removing passes to check all services even if they are not currently used,
 *  * after removing passes to check only services are used in the app.
 *
 * @author Nicolas Grekas <p@tchwork.com>
 * @author Julien Maulny <jmaulny@darkmira.fr>
 */
final class CheckTypeDeclarationsPass extends AbstractRecursivePass
{
    private const SCALAR_TYPES = [
        'int' => true,
        'float' => true,
        'bool' => true,
        'string' => true,
    ];

    private const BUILTIN_TYPES = [
        'array' => true,
        'bool' => true,
        'callable' => true,
        'float' => true,
        'int' => true,
        'iterable' => true,
        'object' => true,
        'string' => true,
    ];

    private $autoload;
    private $skippedIds;

    private $expressionLanguage;

    /**
     * @param bool  $autoload   Whether services who's class in not loaded should be checked or not.
     *                          Defaults to false to save loading code during compilation.
     * @param array $skippedIds An array indexed by the service ids to skip
     */
    public function __construct(bool $autoload = false, array $skippedIds = [])
    {
        $this->autoload = $autoload;
        $this->skippedIds = $skippedIds;
    }

    /**
     * {@inheritdoc}
     */
    protected function processValue($value, $isRoot = false)
    {
        if (isset($this->skippedIds[$this->currentId])) {
            return $value;
        }

        if (!$value instanceof Definition || $value->hasErrors()) {
            return parent::processValue($value, $isRoot);
        }

        if (!$this->autoload && !class_exists($class = $value->getClass(), false) && !interface_exists($class, false)) {
            return parent::processValue($value, $isRoot);
        }

        if (ServiceLocator::class === $value->getClass()) {
            return parent::processValue($value, $isRoot);
        }

        if ($constructor = $this->getConstructor($value, false)) {
            $this->checkTypeDeclarations($value, $constructor, $value->getArguments());
        }

        foreach ($value->getMethodCalls() as $methodCall) {
            try {
                $reflectionMethod = $this->getReflectionMethod($value, $methodCall[0]);
            } catch (RuntimeException $e) {
                if ($value->getFactory()) {
                    continue;
                }

                throw $e;
            }

            $this->checkTypeDeclarations($value, $reflectionMethod, $methodCall[1]);
        }

        return parent::processValue($value, $isRoot);
    }

    /**
     * @throws InvalidArgumentException When not enough parameters are defined for the method
     */
    private function checkTypeDeclarations(Definition $checkedDefinition, \ReflectionFunctionAbstract $reflectionFunction, array $values): void
    {
        $numberOfRequiredParameters = $reflectionFunction->getNumberOfRequiredParameters();

        if (\count($values) < $numberOfRequiredParameters) {
            throw new InvalidArgumentException(sprintf('Invalid definition for service "%s": "%s::%s()" requires %d arguments, %d passed.', $this->currentId, $reflectionFunction->class, $reflectionFunction->name, $numberOfRequiredParameters, \count($values)));
        }

        $reflectionParameters = $reflectionFunction->getParameters();
        $checksCount = min($reflectionFunction->getNumberOfParameters(), \count($values));

        $envPlaceholderUniquePrefix = $this->container->getParameterBag() instanceof EnvPlaceholderParameterBag ? $this->container->getParameterBag()->getEnvPlaceholderUniquePrefix() : null;

        for ($i = 0; $i < $checksCount; ++$i) {
            if (!$reflectionParameters[$i]->hasType() || $reflectionParameters[$i]->isVariadic()) {
                continue;
            }

            $this->checkType($checkedDefinition, $values[$i], $reflectionParameters[$i], $envPlaceholderUniquePrefix);
        }

        if ($reflectionFunction->isVariadic() && ($lastParameter = end($reflectionParameters))->hasType()) {
            $variadicParameters = \array_slice($values, $lastParameter->getPosition());

            foreach ($variadicParameters as $variadicParameter) {
                $this->checkType($checkedDefinition, $variadicParameter, $lastParameter, $envPlaceholderUniquePrefix);
            }
        }
    }

    /**
     * @throws InvalidParameterTypeException When a parameter is not compatible with the declared type
     */
    private function checkType(Definition $checkedDefinition, $value, \ReflectionParameter $parameter, ?string $envPlaceholderUniquePrefix, string $type = null): void
    {
        if (null === $type) {
            $type = $parameter->getType();

            if ($type instanceof \ReflectionUnionType) {
                foreach ($type->getTypes() as $type) {
                    try {
                        $this->checkType($checkedDefinition, $value, $parameter, $envPlaceholderUniquePrefix, $type);

                        return;
                    } catch (InvalidParameterTypeException $e) {
                    }
                }

                throw new InvalidParameterTypeException($this->currentId, $e->getCode(), $parameter);
            }

            $type = $type->getName();
        }

        if ($value instanceof Reference) {
            if (!$this->container->has($value = (string) $value)) {
                return;
            }

            if ('service_container' === $value && is_a($type, Container::class, true)) {
                return;
            }

            $value = $this->container->findDefinition($value);
        }

        if ('self' === $type) {
            $type = $parameter->getDeclaringClass()->getName();
        }

        if ('static' === $type) {
            $type = $checkedDefinition->getClass();
        }

        $class = null;

        if ($value instanceof Definition) {
            $class = $value->getClass();

            if (isset(self::BUILTIN_TYPES[strtolower($class)])) {
                $class = strtolower($class);
            } elseif (!$class || (!$this->autoload && !class_exists($class, false) && !interface_exists($class, false))) {
                return;
            }
        } elseif ($value instanceof Parameter) {
            $value = $this->container->getParameter($value);
        } elseif ($value instanceof Expression) {
            try {
                $value = $this->getExpressionLanguage()->evaluate($value, ['container' => $this->container]);
            } catch (\Exception $e) {
                // If a service from the expression cannot be fetched from the container, we skip the validation.
                return;
            }
        } elseif (\is_string($value)) {
            if ('%' === ($value[0] ?? '') && preg_match('/^%([^%]+)%$/', $value, $match)) {
                $value = $this->container->getParameter(substr($value, 1, -1));
            }

            if ($envPlaceholderUniquePrefix && \is_string($value) && false !== strpos($value, 'env_')) {
                // If the value is an env placeholder that is either mixed with a string or with another env placeholder, then its resolved value will always be a string, so we don't need to resolve it.
                // We don't need to change the value because it is already a string.
                if ('' === preg_replace('/'.$envPlaceholderUniquePrefix.'_\w+_[a-f0-9]{32}/U', '', $value, -1, $c) && 1 === $c) {
                    try {
                        $value = $this->container->resolveEnvPlaceholders($value, true);
                    } catch (\Exception $e) {
                        // If an env placeholder cannot be resolved, we skip the validation.
                        return;
                    }
                }
            }
        }

        if (null === $value && $parameter->allowsNull()) {
            return;
        }

        if (null === $class) {
            if ($value instanceof IteratorArgument) {
                $class = RewindableGenerator::class;
            } elseif ($value instanceof ServiceClosureArgument) {
                $class = \Closure::class;
            } elseif ($value instanceof ServiceLocatorArgument) {
                $class = ServiceLocator::class;
            } elseif (\is_object($value)) {
                $class = \get_class($value);
            } else {
                $class = \gettype($value);
                $class = ['integer' => 'int', 'double' => 'float', 'boolean' => 'bool'][$class] ?? $class;
            }
        }

        if (isset(self::SCALAR_TYPES[$type]) && isset(self::SCALAR_TYPES[$class])) {
            return;
        }

        if ('string' === $type && method_exists($class, '__toString')) {
            return;
        }

        if ('callable' === $type && (\Closure::class === $class || method_exists($class, '__invoke'))) {
            return;
        }

        if ('callable' === $type && \is_array($value) && isset($value[0]) && ($value[0] instanceof Reference || $value[0] instanceof Definition || \is_string($value[0]))) {
            return;
        }

        if ('iterable' === $type && (\is_array($value) || 'array' === $class || is_subclass_of($class, \Traversable::class))) {
            return;
        }

        if ($type === $class) {
            return;
        }

        if ('object' === $type && !isset(self::BUILTIN_TYPES[$class])) {
            return;
        }

        if (is_a($class, $type, true)) {
            return;
        }

        $checkFunction = sprintf('is_%s', $type);

        if (!$parameter->getType()->isBuiltin() || !$checkFunction($value)) {
            throw new InvalidParameterTypeException($this->currentId, \is_object($value) ? $class : get_debug_type($value), $parameter);
        }
    }

    private function getExpressionLanguage(): ExpressionLanguage
    {
        if (null === $this->expressionLanguage) {
            $this->expressionLanguage = new ExpressionLanguage(null, $this->container->getExpressionLanguageProviders());
        }

        return $this->expressionLanguage;
    }
}
PKϤ$Z{>H��;dependency-injection/Compiler/ResolveNamedArgumentsPass.phpnu�[���<?php

/*
 * This file is part of the Symfony package.
 *
 * (c) Fabien Potencier <fabien@symfony.com>
 *
 * For the full copyright and license information, please view the LICENSE
 * file that was distributed with this source code.
 */

namespace Symfony\Component\DependencyInjection\Compiler;

use Symfony\Component\DependencyInjection\Argument\AbstractArgument;
use Symfony\Component\DependencyInjection\Definition;
use Symfony\Component\DependencyInjection\Exception\InvalidArgumentException;
use Symfony\Component\DependencyInjection\LazyProxy\ProxyHelper;
use Symfony\Component\DependencyInjection\Reference;

/**
 * Resolves named arguments to their corresponding numeric index.
 *
 * @author Kévin Dunglas <dunglas@gmail.com>
 */
class ResolveNamedArgumentsPass extends AbstractRecursivePass
{
    /**
     * {@inheritdoc}
     */
    protected function processValue($value, bool $isRoot = false)
    {
        if ($value instanceof AbstractArgument && $value->getText().'.' === $value->getTextWithContext()) {
            $value->setContext(sprintf('A value found in service "%s"', $this->currentId));
        }

        if (!$value instanceof Definition) {
            return parent::processValue($value, $isRoot);
        }

        $calls = $value->getMethodCalls();
        $calls[] = ['__construct', $value->getArguments()];

        foreach ($calls as $i => $call) {
            list($method, $arguments) = $call;
            $parameters = null;
            $resolvedArguments = [];

            foreach ($arguments as $key => $argument) {
                if ($argument instanceof AbstractArgument && $argument->getText().'.' === $argument->getTextWithContext()) {
                    $argument->setContext(sprintf('Argument '.(\is_int($key) ? 1 + $key : '"%3$s"').' of '.('__construct' === $method ? 'service "%s"' : 'method call "%s::%s()"'), $this->currentId, $method, $key));
                }

                if (\is_int($key)) {
                    $resolvedArguments[$key] = $argument;
                    continue;
                }

                if (null === $parameters) {
                    $r = $this->getReflectionMethod($value, $method);
                    $class = $r instanceof \ReflectionMethod ? $r->class : $this->currentId;
                    $method = $r->getName();
                    $parameters = $r->getParameters();
                }

                if (isset($key[0]) && '$' !== $key[0] && !class_exists($key) && !interface_exists($key, false)) {
                    throw new InvalidArgumentException(sprintf('Invalid service "%s": did you forget to add the "$" prefix to argument "%s"?', $this->currentId, $key));
                }

                if (isset($key[0]) && '$' === $key[0]) {
                    foreach ($parameters as $j => $p) {
                        if ($key === '$'.$p->name) {
                            if ($p->isVariadic() && \is_array($argument)) {
                                foreach ($argument as $variadicArgument) {
                                    $resolvedArguments[$j++] = $variadicArgument;
                                }
                            } else {
                                $resolvedArguments[$j] = $argument;
                            }

                            continue 2;
                        }
                    }

                    throw new InvalidArgumentException(sprintf('Invalid service "%s": method "%s()" has no argument named "%s". Check your service definition.', $this->currentId, $class !== $this->currentId ? $class.'::'.$method : $method, $key));
                }

                if (null !== $argument && !$argument instanceof Reference && !$argument instanceof Definition) {
                    throw new InvalidArgumentException(sprintf('Invalid service "%s": the value of argument "%s" of method "%s()" must be null, an instance of "%s" or an instance of "%s", "%s" given.', $this->currentId, $key, $class !== $this->currentId ? $class.'::'.$method : $method, Reference::class, Definition::class, get_debug_type($argument)));
                }

                $typeFound = false;
                foreach ($parameters as $j => $p) {
                    if (!\array_key_exists($j, $resolvedArguments) && ProxyHelper::getTypeHint($r, $p, true) === $key) {
                        $resolvedArguments[$j] = $argument;
                        $typeFound = true;
                    }
                }

                if (!$typeFound) {
                    throw new InvalidArgumentException(sprintf('Invalid service "%s": method "%s()" has no argument type-hinted as "%s". Check your service definition.', $this->currentId, $class !== $this->currentId ? $class.'::'.$method : $method, $key));
                }
            }

            if ($resolvedArguments !== $call[1]) {
                ksort($resolvedArguments);
                $calls[$i][1] = $resolvedArguments;
            }
        }

        list(, $arguments) = array_pop($calls);

        if ($arguments !== $value->getArguments()) {
            $value->setArguments($arguments);
        }
        if ($calls !== $value->getMethodCalls()) {
            $value->setMethodCalls($calls);
        }

        foreach ($value->getProperties() as $key => $argument) {
            if ($argument instanceof AbstractArgument && $argument->getText().'.' === $argument->getTextWithContext()) {
                $argument->setContext(sprintf('Property "%s" of service "%s"', $key, $this->currentId));
            }
        }

        return parent::processValue($value, $isRoot);
    }
}
PKϤ$Z��5�ww6dependency-injection/Compiler/DecoratorServicePass.phpnu�[���<?php

/*
 * This file is part of the Symfony package.
 *
 * (c) Fabien Potencier <fabien@symfony.com>
 *
 * For the full copyright and license information, please view the LICENSE
 * file that was distributed with this source code.
 */

namespace Symfony\Component\DependencyInjection\Compiler;

use Symfony\Component\DependencyInjection\Alias;
use Symfony\Component\DependencyInjection\ContainerBuilder;
use Symfony\Component\DependencyInjection\ContainerInterface;
use Symfony\Component\DependencyInjection\Exception\ServiceNotFoundException;
use Symfony\Component\DependencyInjection\Reference;

/**
 * Overwrites a service but keeps the overridden one.
 *
 * @author Christophe Coevoet <stof@notk.org>
 * @author Fabien Potencier <fabien@symfony.com>
 * @author Diego Saint Esteben <diego@saintesteben.me>
 */
class DecoratorServicePass extends AbstractRecursivePass
{
    private $innerId = '.inner';

    public function __construct(?string $innerId = '.inner')
    {
        $this->innerId = $innerId;
    }

    public function process(ContainerBuilder $container)
    {
        $definitions = new \SplPriorityQueue();
        $order = \PHP_INT_MAX;

        foreach ($container->getDefinitions() as $id => $definition) {
            if (!$decorated = $definition->getDecoratedService()) {
                continue;
            }
            $definitions->insert([$id, $definition], [$decorated[2], --$order]);
        }
        $decoratingDefinitions = [];

        foreach ($definitions as list($id, $definition)) {
            $decoratedService = $definition->getDecoratedService();
            list($inner, $renamedId) = $decoratedService;
            $invalidBehavior = $decoratedService[3] ?? ContainerInterface::EXCEPTION_ON_INVALID_REFERENCE;

            $definition->setDecoratedService(null);

            if (!$renamedId) {
                $renamedId = $id.'.inner';
            }

            $this->currentId = $renamedId;
            $this->processValue($definition);

            $definition->innerServiceId = $renamedId;
            $definition->decorationOnInvalid = $invalidBehavior;

            // we create a new alias/service for the service we are replacing
            // to be able to reference it in the new one
            if ($container->hasAlias($inner)) {
                $alias = $container->getAlias($inner);
                $public = $alias->isPublic();
                $private = $alias->isPrivate();
                $container->setAlias($renamedId, new Alias((string) $alias, false));
            } elseif ($container->hasDefinition($inner)) {
                $decoratedDefinition = $container->getDefinition($inner);
                $public = $decoratedDefinition->isPublic();
                $private = $decoratedDefinition->isPrivate();
                $decoratedDefinition->setPublic(false);
                $container->setDefinition($renamedId, $decoratedDefinition);
                $decoratingDefinitions[$inner] = $decoratedDefinition;
            } elseif (ContainerInterface::IGNORE_ON_INVALID_REFERENCE === $invalidBehavior) {
                $container->removeDefinition($id);
                continue;
            } elseif (ContainerInterface::NULL_ON_INVALID_REFERENCE === $invalidBehavior) {
                $public = $definition->isPublic();
                $private = $definition->isPrivate();
            } else {
                throw new ServiceNotFoundException($inner, $id);
            }

            if (isset($decoratingDefinitions[$inner])) {
                $decoratingDefinition = $decoratingDefinitions[$inner];

                $decoratingTags = $decoratingDefinition->getTags();
                $resetTags = [];

                if (isset($decoratingTags['container.service_locator'])) {
                    // container.service_locator has special logic and it must not be transferred out to decorators
                    $resetTags = ['container.service_locator' => $decoratingTags['container.service_locator']];
                    unset($decoratingTags['container.service_locator']);
                }

                $definition->setTags(array_merge($decoratingTags, $definition->getTags()));
                $decoratingDefinition->setTags($resetTags);
                $decoratingDefinitions[$inner] = $definition;
            }

            $container->setAlias($inner, $id)->setPublic($public)->setPrivate($private);
        }
    }

    protected function processValue($value, bool $isRoot = false)
    {
        if ($value instanceof Reference && $this->innerId === (string) $value) {
            return new Reference($this->currentId, $value->getInvalidBehavior());
        }

        return parent::processValue($value, $isRoot);
    }
}
PKϤ$Z�A���1dependency-injection/TaggedContainerInterface.phpnu�[���<?php

/*
 * This file is part of the Symfony package.
 *
 * (c) Fabien Potencier <fabien@symfony.com>
 *
 * For the full copyright and license information, please view the LICENSE
 * file that was distributed with this source code.
 */

namespace Symfony\Component\DependencyInjection;

/**
 * TaggedContainerInterface is the interface implemented when a container knows how to deals with tags.
 *
 * @author Fabien Potencier <fabien@symfony.com>
 */
interface TaggedContainerInterface extends ContainerInterface
{
    /**
     * Returns service ids for a given tag.
     *
     * @param string $name The tag name
     *
     * @return array An array of tags
     */
    public function findTaggedServiceIds(string $name);
}
PKϤ$Z����1dependency-injection/EnvVarProcessorInterface.phpnu�[���<?php

/*
 * This file is part of the Symfony package.
 *
 * (c) Fabien Potencier <fabien@symfony.com>
 *
 * For the full copyright and license information, please view the LICENSE
 * file that was distributed with this source code.
 */

namespace Symfony\Component\DependencyInjection;

use Symfony\Component\DependencyInjection\Exception\RuntimeException;

/**
 * The EnvVarProcessorInterface is implemented by objects that manage environment-like variables.
 *
 * @author Nicolas Grekas <p@tchwork.com>
 */
interface EnvVarProcessorInterface
{
    /**
     * Returns the value of the given variable as managed by the current instance.
     *
     * @param string   $prefix The namespace of the variable
     * @param string   $name   The name of the variable within the namespace
     * @param \Closure $getEnv A closure that allows fetching more env vars
     *
     * @return mixed
     *
     * @throws RuntimeException on error
     */
    public function getEnv(string $prefix, string $name, \Closure $getEnv);

    /**
     * @return string[] The PHP-types managed by getEnv(), keyed by prefixes
     */
    public static function getProvidedTypes();
}
PKϤ$Z���_��2dependency-injection/ParameterBag/ParameterBag.phpnu�[���<?php

/*
 * This file is part of the Symfony package.
 *
 * (c) Fabien Potencier <fabien@symfony.com>
 *
 * For the full copyright and license information, please view the LICENSE
 * file that was distributed with this source code.
 */

namespace Symfony\Component\DependencyInjection\ParameterBag;

use Symfony\Component\DependencyInjection\Exception\ParameterCircularReferenceException;
use Symfony\Component\DependencyInjection\Exception\ParameterNotFoundException;
use Symfony\Component\DependencyInjection\Exception\RuntimeException;

/**
 * Holds parameters.
 *
 * @author Fabien Potencier <fabien@symfony.com>
 */
class ParameterBag implements ParameterBagInterface
{
    protected $parameters = [];
    protected $resolved = false;

    /**
     * @param array $parameters An array of parameters
     */
    public function __construct(array $parameters = [])
    {
        $this->add($parameters);
    }

    /**
     * Clears all parameters.
     */
    public function clear()
    {
        $this->parameters = [];
    }

    /**
     * Adds parameters to the service container parameters.
     *
     * @param array $parameters An array of parameters
     */
    public function add(array $parameters)
    {
        foreach ($parameters as $key => $value) {
            $this->set($key, $value);
        }
    }

    /**
     * {@inheritdoc}
     */
    public function all()
    {
        return $this->parameters;
    }

    /**
     * {@inheritdoc}
     */
    public function get(string $name)
    {
        if (!\array_key_exists($name, $this->parameters)) {
            if (!$name) {
                throw new ParameterNotFoundException($name);
            }

            $alternatives = [];
            foreach ($this->parameters as $key => $parameterValue) {
                $lev = levenshtein($name, $key);
                if ($lev <= \strlen($name) / 3 || false !== strpos($key, $name)) {
                    $alternatives[] = $key;
                }
            }

            $nonNestedAlternative = null;
            if (!\count($alternatives) && false !== strpos($name, '.')) {
                $namePartsLength = array_map('strlen', explode('.', $name));
                $key = substr($name, 0, -1 * (1 + array_pop($namePartsLength)));
                while (\count($namePartsLength)) {
                    if ($this->has($key)) {
                        if (\is_array($this->get($key))) {
                            $nonNestedAlternative = $key;
                        }
                        break;
                    }

                    $key = substr($key, 0, -1 * (1 + array_pop($namePartsLength)));
                }
            }

            throw new ParameterNotFoundException($name, null, null, null, $alternatives, $nonNestedAlternative);
        }

        return $this->parameters[$name];
    }

    /**
     * Sets a service container parameter.
     *
     * @param string $name  The parameter name
     * @param mixed  $value The parameter value
     */
    public function set(string $name, $value)
    {
        $this->parameters[$name] = $value;
    }

    /**
     * {@inheritdoc}
     */
    public function has(string $name)
    {
        return \array_key_exists((string) $name, $this->parameters);
    }

    /**
     * Removes a parameter.
     *
     * @param string $name The parameter name
     */
    public function remove(string $name)
    {
        unset($this->parameters[$name]);
    }

    /**
     * {@inheritdoc}
     */
    public function resolve()
    {
        if ($this->resolved) {
            return;
        }

        $parameters = [];
        foreach ($this->parameters as $key => $value) {
            try {
                $value = $this->resolveValue($value);
                $parameters[$key] = $this->unescapeValue($value);
            } catch (ParameterNotFoundException $e) {
                $e->setSourceKey($key);

                throw $e;
            }
        }

        $this->parameters = $parameters;
        $this->resolved = true;
    }

    /**
     * Replaces parameter placeholders (%name%) by their values.
     *
     * @param mixed $value     A value
     * @param array $resolving An array of keys that are being resolved (used internally to detect circular references)
     *
     * @return mixed The resolved value
     *
     * @throws ParameterNotFoundException          if a placeholder references a parameter that does not exist
     * @throws ParameterCircularReferenceException if a circular reference if detected
     * @throws RuntimeException                    when a given parameter has a type problem
     */
    public function resolveValue($value, array $resolving = [])
    {
        if (\is_array($value)) {
            $args = [];
            foreach ($value as $k => $v) {
                $args[\is_string($k) ? $this->resolveValue($k, $resolving) : $k] = $this->resolveValue($v, $resolving);
            }

            return $args;
        }

        if (!\is_string($value) || 2 > \strlen($value)) {
            return $value;
        }

        return $this->resolveString($value, $resolving);
    }

    /**
     * Resolves parameters inside a string.
     *
     * @param array $resolving An array of keys that are being resolved (used internally to detect circular references)
     *
     * @return mixed The resolved string
     *
     * @throws ParameterNotFoundException          if a placeholder references a parameter that does not exist
     * @throws ParameterCircularReferenceException if a circular reference if detected
     * @throws RuntimeException                    when a given parameter has a type problem
     */
    public function resolveString(string $value, array $resolving = [])
    {
        // we do this to deal with non string values (Boolean, integer, ...)
        // as the preg_replace_callback throw an exception when trying
        // a non-string in a parameter value
        if (preg_match('/^%([^%\s]+)%$/', $value, $match)) {
            $key = $match[1];

            if (isset($resolving[$key])) {
                throw new ParameterCircularReferenceException(array_keys($resolving));
            }

            $resolving[$key] = true;

            return $this->resolved ? $this->get($key) : $this->resolveValue($this->get($key), $resolving);
        }

        return preg_replace_callback('/%%|%([^%\s]+)%/', function ($match) use ($resolving, $value) {
            // skip %%
            if (!isset($match[1])) {
                return '%%';
            }

            $key = $match[1];
            if (isset($resolving[$key])) {
                throw new ParameterCircularReferenceException(array_keys($resolving));
            }

            $resolved = $this->get($key);

            if (!\is_string($resolved) && !is_numeric($resolved)) {
                throw new RuntimeException(sprintf('A string value must be composed of strings and/or numbers, but found parameter "%s" of type "%s" inside string value "%s".', $key, get_debug_type($resolved), $value));
            }

            $resolved = (string) $resolved;
            $resolving[$key] = true;

            return $this->isResolved() ? $resolved : $this->resolveString($resolved, $resolving);
        }, $value);
    }

    public function isResolved()
    {
        return $this->resolved;
    }

    /**
     * {@inheritdoc}
     */
    public function escapeValue($value)
    {
        if (\is_string($value)) {
            return str_replace('%', '%%', $value);
        }

        if (\is_array($value)) {
            $result = [];
            foreach ($value as $k => $v) {
                $result[$k] = $this->escapeValue($v);
            }

            return $result;
        }

        return $value;
    }

    /**
     * {@inheritdoc}
     */
    public function unescapeValue($value)
    {
        if (\is_string($value)) {
            return str_replace('%%', '%', $value);
        }

        if (\is_array($value)) {
            $result = [];
            foreach ($value as $k => $v) {
                $result[$k] = $this->unescapeValue($v);
            }

            return $result;
        }

        return $value;
    }
}
PKϤ$Z�`ff;dependency-injection/ParameterBag/ContainerBagInterface.phpnu�[���<?php

/*
 * This file is part of the Symfony package.
 *
 * (c) Fabien Potencier <fabien@symfony.com>
 *
 * For the full copyright and license information, please view the LICENSE
 * file that was distributed with this source code.
 */

namespace Symfony\Component\DependencyInjection\ParameterBag;

use Psr\Container\ContainerInterface;
use Symfony\Component\DependencyInjection\Exception\ParameterNotFoundException;

/**
 * ContainerBagInterface is the interface implemented by objects that manage service container parameters.
 *
 * @author Nicolas Grekas <p@tchwork.com>
 */
interface ContainerBagInterface extends ContainerInterface
{
    /**
     * Gets the service container parameters.
     *
     * @return array An array of parameters
     */
    public function all();

    /**
     * Replaces parameter placeholders (%name%) by their values.
     *
     * @param mixed $value A value
     *
     * @throws ParameterNotFoundException if a placeholder references a parameter that does not exist
     */
    public function resolveValue($value);

    /**
     * Escape parameter placeholders %.
     *
     * @param mixed $value
     *
     * @return mixed
     */
    public function escapeValue($value);

    /**
     * Unescape parameter placeholders %.
     *
     * @param mixed $value
     *
     * @return mixed
     */
    public function unescapeValue($value);
}
PKϤ$Z��K��@dependency-injection/ParameterBag/EnvPlaceholderParameterBag.phpnu�[���<?php

/*
 * This file is part of the Symfony package.
 *
 * (c) Fabien Potencier <fabien@symfony.com>
 *
 * For the full copyright and license information, please view the LICENSE
 * file that was distributed with this source code.
 */

namespace Symfony\Component\DependencyInjection\ParameterBag;

use Symfony\Component\DependencyInjection\Exception\InvalidArgumentException;
use Symfony\Component\DependencyInjection\Exception\RuntimeException;

/**
 * @author Nicolas Grekas <p@tchwork.com>
 */
class EnvPlaceholderParameterBag extends ParameterBag
{
    private $envPlaceholderUniquePrefix;
    private $envPlaceholders = [];
    private $unusedEnvPlaceholders = [];
    private $providedTypes = [];

    private static $counter = 0;

    /**
     * {@inheritdoc}
     */
    public function get(string $name)
    {
        if (0 === strpos($name, 'env(') && ')' === substr($name, -1) && 'env()' !== $name) {
            $env = substr($name, 4, -1);

            if (isset($this->envPlaceholders[$env])) {
                foreach ($this->envPlaceholders[$env] as $placeholder) {
                    return $placeholder; // return first result
                }
            }
            if (isset($this->unusedEnvPlaceholders[$env])) {
                foreach ($this->unusedEnvPlaceholders[$env] as $placeholder) {
                    return $placeholder; // return first result
                }
            }
            if (!preg_match('/^(?:[-.\w]*+:)*+\w++$/', $env)) {
                throw new InvalidArgumentException(sprintf('Invalid %s name: only "word" characters are allowed.', $name));
            }
            if ($this->has($name) && null !== ($defaultValue = parent::get($name)) && !\is_string($defaultValue)) {
                throw new RuntimeException(sprintf('The default value of an env() parameter must be a string or null, but "%s" given to "%s".', get_debug_type($defaultValue), $name));
            }

            $uniqueName = md5($name.'_'.self::$counter++);
            $placeholder = sprintf('%s_%s_%s', $this->getEnvPlaceholderUniquePrefix(), strtr($env, ':-.', '___'), $uniqueName);
            $this->envPlaceholders[$env][$placeholder] = $placeholder;

            return $placeholder;
        }

        return parent::get($name);
    }

    /**
     * Gets the common env placeholder prefix for env vars created by this bag.
     */
    public function getEnvPlaceholderUniquePrefix(): string
    {
        if (null === $this->envPlaceholderUniquePrefix) {
            $reproducibleEntropy = unserialize(serialize($this->parameters));
            array_walk_recursive($reproducibleEntropy, function (&$v) { $v = null; });
            $this->envPlaceholderUniquePrefix = 'env_'.substr(md5(serialize($reproducibleEntropy)), -16);
        }

        return $this->envPlaceholderUniquePrefix;
    }

    /**
     * Returns the map of env vars used in the resolved parameter values to their placeholders.
     *
     * @return string[][] A map of env var names to their placeholders
     */
    public function getEnvPlaceholders()
    {
        return $this->envPlaceholders;
    }

    public function getUnusedEnvPlaceholders(): array
    {
        return $this->unusedEnvPlaceholders;
    }

    public function clearUnusedEnvPlaceholders()
    {
        $this->unusedEnvPlaceholders = [];
    }

    /**
     * Merges the env placeholders of another EnvPlaceholderParameterBag.
     */
    public function mergeEnvPlaceholders(self $bag)
    {
        if ($newPlaceholders = $bag->getEnvPlaceholders()) {
            $this->envPlaceholders += $newPlaceholders;

            foreach ($newPlaceholders as $env => $placeholders) {
                $this->envPlaceholders[$env] += $placeholders;
            }
        }

        if ($newUnusedPlaceholders = $bag->getUnusedEnvPlaceholders()) {
            $this->unusedEnvPlaceholders += $newUnusedPlaceholders;

            foreach ($newUnusedPlaceholders as $env => $placeholders) {
                $this->unusedEnvPlaceholders[$env] += $placeholders;
            }
        }
    }

    /**
     * Maps env prefixes to their corresponding PHP types.
     */
    public function setProvidedTypes(array $providedTypes)
    {
        $this->providedTypes = $providedTypes;
    }

    /**
     * Gets the PHP types corresponding to env() parameter prefixes.
     *
     * @return string[][]
     */
    public function getProvidedTypes()
    {
        return $this->providedTypes;
    }

    /**
     * {@inheritdoc}
     */
    public function resolve()
    {
        if ($this->resolved) {
            return;
        }
        parent::resolve();

        foreach ($this->envPlaceholders as $env => $placeholders) {
            if ($this->has($name = "env($env)") && null !== ($default = $this->parameters[$name]) && !\is_string($default)) {
                throw new RuntimeException(sprintf('The default value of env parameter "%s" must be a string or null, "%s" given.', $env, get_debug_type($default)));
            }
        }
    }
}
PKϤ$Zn�k�r
r
;dependency-injection/ParameterBag/ParameterBagInterface.phpnu�[���<?php

/*
 * This file is part of the Symfony package.
 *
 * (c) Fabien Potencier <fabien@symfony.com>
 *
 * For the full copyright and license information, please view the LICENSE
 * file that was distributed with this source code.
 */

namespace Symfony\Component\DependencyInjection\ParameterBag;

use Symfony\Component\DependencyInjection\Exception\LogicException;
use Symfony\Component\DependencyInjection\Exception\ParameterNotFoundException;

/**
 * ParameterBagInterface is the interface implemented by objects that manage service container parameters.
 *
 * @author Fabien Potencier <fabien@symfony.com>
 */
interface ParameterBagInterface
{
    /**
     * Clears all parameters.
     *
     * @throws LogicException if the ParameterBagInterface can not be cleared
     */
    public function clear();

    /**
     * Adds parameters to the service container parameters.
     *
     * @param array $parameters An array of parameters
     *
     * @throws LogicException if the parameter can not be added
     */
    public function add(array $parameters);

    /**
     * Gets the service container parameters.
     *
     * @return array An array of parameters
     */
    public function all();

    /**
     * Gets a service container parameter.
     *
     * @return mixed The parameter value
     *
     * @throws ParameterNotFoundException if the parameter is not defined
     */
    public function get(string $name);

    /**
     * Removes a parameter.
     */
    public function remove(string $name);

    /**
     * Sets a service container parameter.
     *
     * @param mixed $value The parameter value
     *
     * @throws LogicException if the parameter can not be set
     */
    public function set(string $name, $value);

    /**
     * Returns true if a parameter name is defined.
     *
     * @return bool true if the parameter name is defined, false otherwise
     */
    public function has(string $name);

    /**
     * Replaces parameter placeholders (%name%) by their values for all parameters.
     */
    public function resolve();

    /**
     * Replaces parameter placeholders (%name%) by their values.
     *
     * @param mixed $value A value
     *
     * @throws ParameterNotFoundException if a placeholder references a parameter that does not exist
     */
    public function resolveValue($value);

    /**
     * Escape parameter placeholders %.
     *
     * @param mixed $value
     *
     * @return mixed
     */
    public function escapeValue($value);

    /**
     * Unescape parameter placeholders %.
     *
     * @param mixed $value
     *
     * @return mixed
     */
    public function unescapeValue($value);
}
PKϤ$Z�I.eFF8dependency-injection/ParameterBag/FrozenParameterBag.phpnu�[���<?php

/*
 * This file is part of the Symfony package.
 *
 * (c) Fabien Potencier <fabien@symfony.com>
 *
 * For the full copyright and license information, please view the LICENSE
 * file that was distributed with this source code.
 */

namespace Symfony\Component\DependencyInjection\ParameterBag;

use Symfony\Component\DependencyInjection\Exception\LogicException;

/**
 * Holds read-only parameters.
 *
 * @author Fabien Potencier <fabien@symfony.com>
 */
class FrozenParameterBag extends ParameterBag
{
    /**
     * For performance reasons, the constructor assumes that
     * all keys are already lowercased.
     *
     * This is always the case when used internally.
     *
     * @param array $parameters An array of parameters
     */
    public function __construct(array $parameters = [])
    {
        $this->parameters = $parameters;
        $this->resolved = true;
    }

    /**
     * {@inheritdoc}
     */
    public function clear()
    {
        throw new LogicException('Impossible to call clear() on a frozen ParameterBag.');
    }

    /**
     * {@inheritdoc}
     */
    public function add(array $parameters)
    {
        throw new LogicException('Impossible to call add() on a frozen ParameterBag.');
    }

    /**
     * {@inheritdoc}
     */
    public function set(string $name, $value)
    {
        throw new LogicException('Impossible to call set() on a frozen ParameterBag.');
    }

    /**
     * {@inheritdoc}
     */
    public function remove(string $name)
    {
        throw new LogicException('Impossible to call remove() on a frozen ParameterBag.');
    }
}
PKϤ$Z�G��2dependency-injection/ParameterBag/ContainerBag.phpnu�[���<?php

/*
 * This file is part of the Symfony package.
 *
 * (c) Fabien Potencier <fabien@symfony.com>
 *
 * For the full copyright and license information, please view the LICENSE
 * file that was distributed with this source code.
 */

namespace Symfony\Component\DependencyInjection\ParameterBag;

use Symfony\Component\DependencyInjection\Container;

/**
 * @author Nicolas Grekas <p@tchwork.com>
 */
class ContainerBag extends FrozenParameterBag implements ContainerBagInterface
{
    private $container;

    public function __construct(Container $container)
    {
        $this->container = $container;
    }

    /**
     * {@inheritdoc}
     */
    public function all()
    {
        return $this->container->getParameterBag()->all();
    }

    /**
     * {@inheritdoc}
     */
    public function get($name)
    {
        return $this->container->getParameter($name);
    }

    /**
     * {@inheritdoc}
     */
    public function has($name)
    {
        return $this->container->hasParameter($name);
    }
}
PKϤ$Z���((+dependency-injection/ContainerInterface.phpnu�[���<?php

/*
 * This file is part of the Symfony package.
 *
 * (c) Fabien Potencier <fabien@symfony.com>
 *
 * For the full copyright and license information, please view the LICENSE
 * file that was distributed with this source code.
 */

namespace Symfony\Component\DependencyInjection;

use Psr\Container\ContainerInterface as PsrContainerInterface;
use Symfony\Component\DependencyInjection\Exception\InvalidArgumentException;
use Symfony\Component\DependencyInjection\Exception\ServiceCircularReferenceException;
use Symfony\Component\DependencyInjection\Exception\ServiceNotFoundException;

/**
 * ContainerInterface is the interface implemented by service container classes.
 *
 * @author Fabien Potencier <fabien@symfony.com>
 * @author Johannes M. Schmitt <schmittjoh@gmail.com>
 */
interface ContainerInterface extends PsrContainerInterface
{
    const RUNTIME_EXCEPTION_ON_INVALID_REFERENCE = 0;
    const EXCEPTION_ON_INVALID_REFERENCE = 1;
    const NULL_ON_INVALID_REFERENCE = 2;
    const IGNORE_ON_INVALID_REFERENCE = 3;
    const IGNORE_ON_UNINITIALIZED_REFERENCE = 4;

    /**
     * Sets a service.
     */
    public function set(string $id, ?object $service);

    /**
     * Gets a service.
     *
     * @param string $id              The service identifier
     * @param int    $invalidBehavior The behavior when the service does not exist
     *
     * @return object|null The associated service
     *
     * @throws ServiceCircularReferenceException When a circular reference is detected
     * @throws ServiceNotFoundException          When the service is not defined
     *
     * @see Reference
     */
    public function get($id, int $invalidBehavior = self::EXCEPTION_ON_INVALID_REFERENCE);

    /**
     * Returns true if the given service is defined.
     *
     * @param string $id The service identifier
     *
     * @return bool true if the service is defined, false otherwise
     */
    public function has($id);

    /**
     * Check for whether or not a service has been initialized.
     *
     * @return bool true if the service has been initialized, false otherwise
     */
    public function initialized(string $id);

    /**
     * Gets a parameter.
     *
     * @param string $name The parameter name
     *
     * @return mixed The parameter value
     *
     * @throws InvalidArgumentException if the parameter is not defined
     */
    public function getParameter(string $name);

    /**
     * Checks if a parameter exists.
     *
     * @param string $name The parameter name
     *
     * @return bool The presence of parameter in container
     */
    public function hasParameter(string $name);

    /**
     * Sets a parameter.
     *
     * @param string $name  The parameter name
     * @param mixed  $value The parameter value
     */
    public function setParameter(string $name, $value);
}
PKϤ$Z��GXNN0dependency-injection/ContainerAwareInterface.phpnu�[���<?php

/*
 * This file is part of the Symfony package.
 *
 * (c) Fabien Potencier <fabien@symfony.com>
 *
 * For the full copyright and license information, please view the LICENSE
 * file that was distributed with this source code.
 */

namespace Symfony\Component\DependencyInjection;

/**
 * ContainerAwareInterface should be implemented by classes that depends on a Container.
 *
 * @author Fabien Potencier <fabien@symfony.com>
 */
interface ContainerAwareInterface
{
    /**
     * Sets the container.
     */
    public function setContainer(ContainerInterface $container = null);
}
PKϤ$ZvBk���Ddependency-injection/Exception/ServiceCircularReferenceException.phpnu�[���<?php

/*
 * This file is part of the Symfony package.
 *
 * (c) Fabien Potencier <fabien@symfony.com>
 *
 * For the full copyright and license information, please view the LICENSE
 * file that was distributed with this source code.
 */

namespace Symfony\Component\DependencyInjection\Exception;

/**
 * This exception is thrown when a circular reference is detected.
 *
 * @author Johannes M. Schmitt <schmittjoh@gmail.com>
 */
class ServiceCircularReferenceException extends RuntimeException
{
    private $serviceId;
    private $path;

    public function __construct(string $serviceId, array $path, \Throwable $previous = null)
    {
        parent::__construct(sprintf('Circular reference detected for service "%s", path: "%s".', $serviceId, implode(' -> ', $path)), 0, $previous);

        $this->serviceId = $serviceId;
        $this->path = $path;
    }

    public function getServiceId()
    {
        return $this->serviceId;
    }

    public function getPath()
    {
        return $this->path;
    }
}
PKϤ$Zl.��1dependency-injection/Exception/LogicException.phpnu�[���<?php

/*
 * This file is part of the Symfony package.
 *
 * (c) Fabien Potencier <fabien@symfony.com>
 *
 * For the full copyright and license information, please view the LICENSE
 * file that was distributed with this source code.
 */

namespace Symfony\Component\DependencyInjection\Exception;

/**
 * Base LogicException for Dependency Injection component.
 */
class LogicException extends \LogicException implements ExceptionInterface
{
}
PKϤ$Zt�o���Fdependency-injection/Exception/ParameterCircularReferenceException.phpnu�[���<?php

/*
 * This file is part of the Symfony package.
 *
 * (c) Fabien Potencier <fabien@symfony.com>
 *
 * For the full copyright and license information, please view the LICENSE
 * file that was distributed with this source code.
 */

namespace Symfony\Component\DependencyInjection\Exception;

/**
 * This exception is thrown when a circular reference in a parameter is detected.
 *
 * @author Fabien Potencier <fabien@symfony.com>
 */
class ParameterCircularReferenceException extends RuntimeException
{
    private $parameters;

    public function __construct(array $parameters, \Throwable $previous = null)
    {
        parent::__construct(sprintf('Circular reference detected for parameter "%s" ("%s" > "%s").', $parameters[0], implode('" > "', $parameters), $parameters[0]), 0, $previous);

        $this->parameters = $parameters;
    }

    public function getParameters()
    {
        return $this->parameters;
    }
}
PKϤ$Z�-�_8dependency-injection/Exception/EnvParameterException.phpnu�[���<?php

/*
 * This file is part of the Symfony package.
 *
 * (c) Fabien Potencier <fabien@symfony.com>
 *
 * For the full copyright and license information, please view the LICENSE
 * file that was distributed with this source code.
 */

namespace Symfony\Component\DependencyInjection\Exception;

/**
 * This exception wraps exceptions whose messages contain a reference to an env parameter.
 *
 * @author Nicolas Grekas <p@tchwork.com>
 */
class EnvParameterException extends InvalidArgumentException
{
    public function __construct(array $envs, \Throwable $previous = null, string $message = 'Incompatible use of dynamic environment variables "%s" found in parameters.')
    {
        parent::__construct(sprintf($message, implode('", "', $envs)), 0, $previous);
    }
}
PKϤ$Z�dg݋�@dependency-injection/Exception/InvalidParameterTypeException.phpnu�[���<?php

/*
 * This file is part of the Symfony package.
 *
 * (c) Fabien Potencier <fabien@symfony.com>
 *
 * For the full copyright and license information, please view the LICENSE
 * file that was distributed with this source code.
 */

namespace Symfony\Component\DependencyInjection\Exception;

/**
 * Thrown when trying to inject a parameter into a constructor/method with an incompatible type.
 *
 * @author Nicolas Grekas <p@tchwork.com>
 * @author Julien Maulny <jmaulny@darkmira.fr>
 */
class InvalidParameterTypeException extends InvalidArgumentException
{
    public function __construct(string $serviceId, string $type, \ReflectionParameter $parameter)
    {
        $acceptedType = $parameter->getType();
        $acceptedType = $acceptedType instanceof \ReflectionNamedType ? $acceptedType->getName() : (string) $acceptedType;
        $this->code = $type;

        parent::__construct(sprintf('Invalid definition for service "%s": argument %d of "%s::%s" accepts "%s", "%s" passed.', $serviceId, 1 + $parameter->getPosition(), $parameter->getDeclaringClass()->getName(), $parameter->getDeclaringFunction()->getName(), $acceptedType, $type));
    }
}
PKϤ$Z�>��bb5dependency-injection/Exception/ExceptionInterface.phpnu�[���<?php

/*
 * This file is part of the Symfony package.
 *
 * (c) Fabien Potencier <fabien@symfony.com>
 *
 * For the full copyright and license information, please view the LICENSE
 * file that was distributed with this source code.
 */

namespace Symfony\Component\DependencyInjection\Exception;

use Psr\Container\ContainerExceptionInterface;

/**
 * Base ExceptionInterface for Dependency Injection component.
 *
 * @author Fabien Potencier <fabien@symfony.com>
 * @author Bulat Shakirzyanov <bulat@theopenskyproject.com>
 */
interface ExceptionInterface extends ContainerExceptionInterface, \Throwable
{
}
PKϤ$Z�ǁ

=dependency-injection/Exception/ParameterNotFoundException.phpnu�[���<?php

/*
 * This file is part of the Symfony package.
 *
 * (c) Fabien Potencier <fabien@symfony.com>
 *
 * For the full copyright and license information, please view the LICENSE
 * file that was distributed with this source code.
 */

namespace Symfony\Component\DependencyInjection\Exception;

use Psr\Container\NotFoundExceptionInterface;

/**
 * This exception is thrown when a non-existent parameter is used.
 *
 * @author Fabien Potencier <fabien@symfony.com>
 */
class ParameterNotFoundException extends InvalidArgumentException implements NotFoundExceptionInterface
{
    private $key;
    private $sourceId;
    private $sourceKey;
    private $alternatives;
    private $nonNestedAlternative;

    /**
     * @param string      $key                  The requested parameter key
     * @param string      $sourceId             The service id that references the non-existent parameter
     * @param string      $sourceKey            The parameter key that references the non-existent parameter
     * @param \Throwable  $previous             The previous exception
     * @param string[]    $alternatives         Some parameter name alternatives
     * @param string|null $nonNestedAlternative The alternative parameter name when the user expected dot notation for nested parameters
     */
    public function __construct(string $key, string $sourceId = null, string $sourceKey = null, \Throwable $previous = null, array $alternatives = [], string $nonNestedAlternative = null)
    {
        $this->key = $key;
        $this->sourceId = $sourceId;
        $this->sourceKey = $sourceKey;
        $this->alternatives = $alternatives;
        $this->nonNestedAlternative = $nonNestedAlternative;

        parent::__construct('', 0, $previous);

        $this->updateRepr();
    }

    public function updateRepr()
    {
        if (null !== $this->sourceId) {
            $this->message = sprintf('The service "%s" has a dependency on a non-existent parameter "%s".', $this->sourceId, $this->key);
        } elseif (null !== $this->sourceKey) {
            $this->message = sprintf('The parameter "%s" has a dependency on a non-existent parameter "%s".', $this->sourceKey, $this->key);
        } else {
            $this->message = sprintf('You have requested a non-existent parameter "%s".', $this->key);
        }

        if ($this->alternatives) {
            if (1 == \count($this->alternatives)) {
                $this->message .= ' Did you mean this: "';
            } else {
                $this->message .= ' Did you mean one of these: "';
            }
            $this->message .= implode('", "', $this->alternatives).'"?';
        } elseif (null !== $this->nonNestedAlternative) {
            $this->message .= ' You cannot access nested array items, do you want to inject "'.$this->nonNestedAlternative.'" instead?';
        }
    }

    public function getKey()
    {
        return $this->key;
    }

    public function getSourceId()
    {
        return $this->sourceId;
    }

    public function getSourceKey()
    {
        return $this->sourceKey;
    }

    public function setSourceId($sourceId)
    {
        $this->sourceId = $sourceId;

        $this->updateRepr();
    }

    public function setSourceKey($sourceKey)
    {
        $this->sourceKey = $sourceKey;

        $this->updateRepr();
    }
}
PKϤ$Z��;dependency-injection/Exception/InvalidArgumentException.phpnu�[���<?php

/*
 * This file is part of the Symfony package.
 *
 * (c) Fabien Potencier <fabien@symfony.com>
 *
 * For the full copyright and license information, please view the LICENSE
 * file that was distributed with this source code.
 */

namespace Symfony\Component\DependencyInjection\Exception;

/**
 * Base InvalidArgumentException for Dependency Injection component.
 *
 * @author Bulat Shakirzyanov <bulat@theopenskyproject.com>
 */
class InvalidArgumentException extends \InvalidArgumentException implements ExceptionInterface
{
}
PKϤ$Z��tB��<dependency-injection/Exception/AutowiringFailedException.phpnu�[���<?php

/*
 * This file is part of the Symfony package.
 *
 * (c) Fabien Potencier <fabien@symfony.com>
 *
 * For the full copyright and license information, please view the LICENSE
 * file that was distributed with this source code.
 */

namespace Symfony\Component\DependencyInjection\Exception;

/**
 * Thrown when a definition cannot be autowired.
 */
class AutowiringFailedException extends RuntimeException
{
    private $serviceId;
    private $messageCallback;

    public function __construct(string $serviceId, $message = '', int $code = 0, \Throwable $previous = null)
    {
        $this->serviceId = $serviceId;

        if ($message instanceof \Closure && \function_exists('xdebug_is_enabled') && xdebug_is_enabled()) {
            $message = $message();
        }

        if (!$message instanceof \Closure) {
            parent::__construct($message, $code, $previous);

            return;
        }

        $this->messageCallback = $message;
        parent::__construct('', $code, $previous);

        $this->message = new class($this->message, $this->messageCallback) {
            private $message;
            private $messageCallback;

            public function __construct(&$message, &$messageCallback)
            {
                $this->message = &$message;
                $this->messageCallback = &$messageCallback;
            }

            public function __toString(): string
            {
                $messageCallback = $this->messageCallback;
                $this->messageCallback = null;

                try {
                    return $this->message = $messageCallback();
                } catch (\Throwable $e) {
                    return $this->message = $e->getMessage();
                }
            }
        };
    }

    public function getMessageCallback(): ?\Closure
    {
        return $this->messageCallback;
    }

    public function getServiceId()
    {
        return $this->serviceId;
    }
}
PKϤ$Z.��Y;dependency-injection/Exception/ServiceNotFoundException.phpnu�[���<?php

/*
 * This file is part of the Symfony package.
 *
 * (c) Fabien Potencier <fabien@symfony.com>
 *
 * For the full copyright and license information, please view the LICENSE
 * file that was distributed with this source code.
 */

namespace Symfony\Component\DependencyInjection\Exception;

use Psr\Container\NotFoundExceptionInterface;

/**
 * This exception is thrown when a non-existent service is requested.
 *
 * @author Johannes M. Schmitt <schmittjoh@gmail.com>
 */
class ServiceNotFoundException extends InvalidArgumentException implements NotFoundExceptionInterface
{
    private $id;
    private $sourceId;
    private $alternatives;

    public function __construct(string $id, string $sourceId = null, \Throwable $previous = null, array $alternatives = [], string $msg = null)
    {
        if (null !== $msg) {
            // no-op
        } elseif (null === $sourceId) {
            $msg = sprintf('You have requested a non-existent service "%s".', $id);
        } else {
            $msg = sprintf('The service "%s" has a dependency on a non-existent service "%s".', $sourceId, $id);
        }

        if ($alternatives) {
            if (1 == \count($alternatives)) {
                $msg .= ' Did you mean this: "';
            } else {
                $msg .= ' Did you mean one of these: "';
            }
            $msg .= implode('", "', $alternatives).'"?';
        }

        parent::__construct($msg, 0, $previous);

        $this->id = $id;
        $this->sourceId = $sourceId;
        $this->alternatives = $alternatives;
    }

    public function getId()
    {
        return $this->id;
    }

    public function getSourceId()
    {
        return $this->sourceId;
    }

    public function getAlternatives()
    {
        return $this->alternatives;
    }
}
PKϤ$Z���>��7dependency-injection/Exception/EnvNotFoundException.phpnu�[���<?php

/*
 * This file is part of the Symfony package.
 *
 * (c) Fabien Potencier <fabien@symfony.com>
 *
 * For the full copyright and license information, please view the LICENSE
 * file that was distributed with this source code.
 */

namespace Symfony\Component\DependencyInjection\Exception;

/**
 * This exception is thrown when an environment variable is not found.
 *
 * @author Nicolas Grekas <p@tchwork.com>
 */
class EnvNotFoundException extends InvalidArgumentException
{
}
PKϤ$Z�{����7dependency-injection/Exception/OutOfBoundsException.phpnu�[���<?php

/*
 * This file is part of the Symfony package.
 *
 * (c) Fabien Potencier <fabien@symfony.com>
 *
 * For the full copyright and license information, please view the LICENSE
 * file that was distributed with this source code.
 */

namespace Symfony\Component\DependencyInjection\Exception;

/**
 * Base OutOfBoundsException for Dependency Injection component.
 */
class OutOfBoundsException extends \OutOfBoundsException implements ExceptionInterface
{
}
PKϤ$Z
O�,��9dependency-injection/Exception/BadMethodCallException.phpnu�[���<?php

/*
 * This file is part of the Symfony package.
 *
 * (c) Fabien Potencier <fabien@symfony.com>
 *
 * For the full copyright and license information, please view the LICENSE
 * file that was distributed with this source code.
 */

namespace Symfony\Component\DependencyInjection\Exception;

/**
 * Base BadMethodCallException for Dependency Injection component.
 */
class BadMethodCallException extends \BadMethodCallException implements ExceptionInterface
{
}
PKϤ$Z�
+��3dependency-injection/Exception/RuntimeException.phpnu�[���<?php

/*
 * This file is part of the Symfony package.
 *
 * (c) Fabien Potencier <fabien@symfony.com>
 *
 * For the full copyright and license information, please view the LICENSE
 * file that was distributed with this source code.
 */

namespace Symfony\Component\DependencyInjection\Exception;

/**
 * Base RuntimeException for Dependency Injection component.
 *
 * @author Johannes M. Schmitt <schmittjoh@gmail.com>
 */
class RuntimeException extends \RuntimeException implements ExceptionInterface
{
}
PKϤ$Z�!�L�3�3!dependency-injection/CHANGELOG.mdnu�[���CHANGELOG
=========

5.1.0
-----

 * deprecated `inline()` in favor of `inline_service()` and `ref()` in favor of `service()` when using the PHP-DSL
 * allow decorators to reference their decorated service using the special `.inner` id
 * added support to autowire public typed properties in php 7.4
 * added support for defining method calls, a configurator, and property setters in `InlineServiceConfigurator`
 * added possibility to define abstract service arguments
 * allowed mixing "parent" and instanceof-conditionals/defaults/bindings
 * updated the signature of method `Definition::setDeprecated()` to `Definition::setDeprecation(string $package, string $version, string $message)`
 * updated the signature of method `Alias::setDeprecated()` to `Alias::setDeprecation(string $package, string $version, string $message)`
 * updated the signature of method `DeprecateTrait::deprecate()` to `DeprecateTrait::deprecation(string $package, string $version, string $message)`
 * deprecated the `Psr\Container\ContainerInterface` and `Symfony\Component\DependencyInjection\ContainerInterface` aliases of the `service_container` service,
   configure them explicitly instead
 * added class `Symfony\Component\DependencyInjection\Dumper\Preloader` to help with preloading on PHP 7.4+
 * added tags `container.preload`/`.no_preload` to declare extra classes to preload/services to not preload
 * allowed loading and dumping tags with an attribute named "name"
 * deprecated `Definition::getDeprecationMessage()`, use `Definition::getDeprecation()` instead
 * deprecated `Alias::getDeprecationMessage()`, use `Alias::getDeprecation()` instead
 * added support of PHP8 static return type for withers
 * added `AliasDeprecatedPublicServicesPass` to deprecate public services to private

5.0.0
-----

 * removed support for auto-discovered extension configuration class which does not implement `ConfigurationInterface`
 * removed support for non-string default env() parameters
 * moved `ServiceSubscriberInterface` to the `Symfony\Contracts\Service` namespace
 * removed `RepeatedPass` and `RepeatablePassInterface`
 * removed support for short factory/configurator syntax from `YamlFileLoader`
 * removed `ResettableContainerInterface`, use `ResetInterface` instead
 * added argument `$returnsClone` to `Definition::addMethodCall()`
 * removed `tagged`, use `tagged_iterator` instead

4.4.0
-----

 * added `CheckTypeDeclarationsPass` to check injected parameters type during compilation
 * added support for opcache.preload by generating a preloading script in the cache folder
 * added support for dumping the container in one file instead of many files
 * deprecated support for short factories and short configurators in Yaml
 * added `tagged_iterator` alias for `tagged` which might be deprecated in a future version
 * deprecated passing an instance of `Symfony\Component\DependencyInjection\Parameter` as class name to `Symfony\Component\DependencyInjection\Definition`
 * added support for binding iterable and tagged services
 * made singly-implemented interfaces detection be scoped by file
 * added ability to define a static priority method for tagged service
 * added support for improved syntax to define method calls in Yaml
 * made the `%env(base64:...)%` processor able to decode base64url
 * added ability to choose behavior of decorations on non existent decorated services

4.3.0
-----

 * added `%env(trim:...)%` processor to trim a string value
 * added `%env(default:param_name:...)%` processor to fallback to a parameter or to null when using `%env(default::...)%`
 * added `%env(url:...)%` processor to convert an URL or DNS into an array of components
 * added `%env(query_string:...)%` processor to convert a query string into an array of key values
 * added support for deprecating aliases
 * made `ContainerParametersResource` final and not implement `Serializable` anymore
 * added `ReverseContainer`: a container that turns services back to their ids
 * added ability to define an index for a tagged collection
 * added ability to define an index for services in an injected service locator argument
 * made `ServiceLocator` implement `ServiceProviderInterface`
 * deprecated support for non-string default env() parameters
 * added `%env(require:...)%` processor to `require()` a PHP file and use the value returned from it

4.2.0
-----

 * added `ContainerBuilder::registerAliasForArgument()` to support autowiring by type+name
 * added support for binding by type+name
 * added `ServiceSubscriberTrait` to ease implementing `ServiceSubscriberInterface` using methods' return types
 * added `ServiceLocatorArgument` and `!service_locator` config tag for creating optimized service-locators
 * added support for autoconfiguring bindings
 * added `%env(key:...)%` processor to fetch a specific key from an array
 * deprecated `ServiceSubscriberInterface`, use the same interface from the `Symfony\Contracts\Service` namespace instead
 * deprecated `ResettableContainerInterface`, use `Symfony\Contracts\Service\ResetInterface` instead

4.1.0
-----

 * added support for variadics in named arguments
 * added PSR-11 `ContainerBagInterface` and its `ContainerBag` implementation to access parameters as-a-service
 * added support for service's decorators autowiring
 * deprecated the `TypedReference::canBeAutoregistered()` and  `TypedReference::getRequiringClass()` methods
 * environment variables are validated when used in extension configuration
 * deprecated support for auto-discovered extension configuration class which does not implement `ConfigurationInterface`

4.0.0
-----

 * Relying on service auto-registration while autowiring is not supported anymore.
   Explicitly inject your dependencies or create services whose ids are
   their fully-qualified class name.

   Before:

   ```php
   namespace App\Controller;

   use App\Mailer;

   class DefaultController
   {
       public function __construct(Mailer $mailer) {
           // ...
       }

       // ...
   }
   ```
   ```yml
   services:
       App\Controller\DefaultController:
           autowire: true
   ```

   After:

   ```php
   // same PHP code
   ```
   ```yml
   services:
       App\Controller\DefaultController:
           autowire: true

       # or
       # App\Controller\DefaultController:
       #     arguments: { $mailer: "@App\Mailer" }

       App\Mailer:
           autowire: true
    ```
 * removed autowiring services based on the types they implement
 * added a third `$methodName` argument to the `getProxyFactoryCode()` method
   of the `DumperInterface`
 * removed support for autowiring types
 * removed `Container::isFrozen`
 * removed support for dumping an ucompiled container in `PhpDumper`
 * removed support for generating a dumped `Container` without populating the method map
 * removed support for case insensitive service identifiers
 * removed the `DefinitionDecorator` class, replaced by `ChildDefinition`
 * removed the `AutowireServiceResource` class and related `AutowirePass::createResourceForClass()` method
 * removed `LoggingFormatter`, `Compiler::getLoggingFormatter()` and `addLogMessage()` class and methods, use the `ContainerBuilder::log()` method instead
 * removed `FactoryReturnTypePass`
 * removed `ContainerBuilder::addClassResource()`, use the `addObjectResource()` or the `getReflectionClass()` method instead.
 * removed support for top-level anonymous services
 * removed silent behavior for unused attributes and elements
 * removed support for setting and accessing private services in `Container`
 * removed support for setting pre-defined services in `Container`
 * removed support for case insensitivity of parameter names
 * removed `AutowireExceptionPass` and `AutowirePass::getAutowiringExceptions()`, use `Definition::addError()` and the `DefinitionErrorExceptionPass` instead

3.4.0
-----

 * moved the `ExtensionCompilerPass` to before-optimization passes with priority -1000
 * deprecated "public-by-default" definitions and aliases, the new default will be "private" in 4.0
 * added `EnvVarProcessorInterface` and corresponding "container.env_var_processor" tag for processing env vars
 * added support for ignore-on-uninitialized references
 * deprecated service auto-registration while autowiring
 * deprecated the ability to check for the initialization of a private service with the `Container::initialized()` method
 * deprecated support for top-level anonymous services in XML
 * deprecated case insensitivity of parameter names
 * deprecated the `ResolveDefinitionTemplatesPass` class in favor of `ResolveChildDefinitionsPass`
 * added `TaggedIteratorArgument` with YAML (`!tagged foo`) and XML (`<service type="tagged"/>`) support
 * deprecated `AutowireExceptionPass` and `AutowirePass::getAutowiringExceptions()`, use `Definition::addError()` and the `DefinitionErrorExceptionPass` instead


3.3.0
-----

 * deprecated autowiring services based on the types they implement;
   rename (or alias) your services to their FQCN id to make them autowirable
 * added "ServiceSubscriberInterface" - to allow for per-class explicit service-locator definitions
 * added "container.service_locator" tag for defining service-locator services
 * added anonymous services support in YAML configuration files using the `!service` tag.
 * added "TypedReference" and "ServiceClosureArgument" for creating service-locator services
 * added `ServiceLocator` - a PSR-11 container holding a set of services to be lazily loaded
 * added "instanceof" section for local interface-defined configs
 * added prototype services for PSR4-based discovery and registration
 * added `ContainerBuilder::getReflectionClass()` for retrieving and tracking reflection class info
 * deprecated `ContainerBuilder::getClassResource()`, use `ContainerBuilder::getReflectionClass()` or `ContainerBuilder::addObjectResource()` instead
 * added `ContainerBuilder::fileExists()` for checking and tracking file or directory existence
 * deprecated autowiring-types, use aliases instead
 * added support for omitting the factory class name in a service definition if the definition class is set
 * deprecated case insensitivity of service identifiers
 * added "iterator" argument type for lazy iteration over a set of values and services
 * added file-wide configurable defaults for service attributes "public", "tags",
   "autowire" and "autoconfigure"
 * made the "class" attribute optional, using the "id" as fallback
 * using the `PhpDumper` with an uncompiled `ContainerBuilder` is deprecated and
   will not be supported anymore in 4.0
 * deprecated the `DefinitionDecorator` class in favor of `ChildDefinition`
 * allow config files to be loaded using a glob pattern
 * [BC BREAK] the `NullDumper` class is now final

3.2.0
-----

 * allowed to prioritize compiler passes by introducing a third argument to `PassConfig::addPass()`, to `Compiler::addPass` and to `ContainerBuilder::addCompilerPass()`
 * added support for PHP constants in YAML configuration files
 * deprecated the ability to set or unset a private service with the `Container::set()` method
 * deprecated the ability to check for the existence of a private service with the `Container::has()` method
 * deprecated the ability to request a private service with the `Container::get()` method
 * deprecated support for generating a dumped `Container` without populating the method map

3.0.0
-----

 * removed all deprecated codes from 2.x versions

2.8.0
-----

 * deprecated the abstract ContainerAware class in favor of ContainerAwareTrait
 * deprecated IntrospectableContainerInterface, to be merged with ContainerInterface in 3.0
 * allowed specifying a directory to recursively load all configuration files it contains
 * deprecated the concept of scopes
 * added `Definition::setShared()` and `Definition::isShared()`
 * added ResettableContainerInterface to be able to reset the container to release memory on shutdown
 * added a way to define the priority of service decoration
 * added support for service autowiring

2.7.0
-----

 * deprecated synchronized services

2.6.0
-----

 * added new factory syntax and deprecated the old one

2.5.0
-----

* added DecoratorServicePass and a way to override a service definition (Definition::setDecoratedService())
* deprecated SimpleXMLElement class.

2.4.0
-----

 * added support for expressions in service definitions
 * added ContainerAwareTrait to add default container aware behavior to a class

2.2.0
-----

 * added Extension::isConfigEnabled() to ease working with enableable configurations
 * added an Extension base class with sensible defaults to be used in conjunction
   with the Config component.
 * added PrependExtensionInterface (to be able to allow extensions to prepend
   application configuration settings for any Bundle)

2.1.0
-----

 * added IntrospectableContainerInterface (to be able to check if a service
   has been initialized or not)
 * added ConfigurationExtensionInterface
 * added Definition::clearTag()
 * component exceptions that inherit base SPL classes are now used exclusively
   (this includes dumped containers)
 * [BC BREAK] fixed unescaping of class arguments, method
   ParameterBag::unescapeValue() was made public
PKϤ$Z��.t��.dependency-injection/LazyProxy/ProxyHelper.phpnu�[���<?php

/*
 * This file is part of the Symfony package.
 *
 * (c) Fabien Potencier <fabien@symfony.com>
 *
 * For the full copyright and license information, please view the LICENSE
 * file that was distributed with this source code.
 */

namespace Symfony\Component\DependencyInjection\LazyProxy;

/**
 * @author Nicolas Grekas <p@tchwork.com>
 *
 * @internal
 */
class ProxyHelper
{
    /**
     * @return string|null The FQCN or builtin name of the type hint, or null when the type hint references an invalid self|parent context
     */
    public static function getTypeHint(\ReflectionFunctionAbstract $r, \ReflectionParameter $p = null, bool $noBuiltin = false): ?string
    {
        if ($p instanceof \ReflectionParameter) {
            $type = $p->getType();
        } else {
            $type = $r->getReturnType();
        }
        if (!$type) {
            return null;
        }

        $types = [];

        foreach ($type instanceof \ReflectionUnionType ? $type->getTypes() : [$type] as $type) {
            $name = $type instanceof \ReflectionNamedType ? $type->getName() : (string) $type;

            if ($type->isBuiltin()) {
                if (!$noBuiltin) {
                    $types[] = $name;
                }
                continue;
            }

            $lcName = strtolower($name);
            $prefix = $noBuiltin ? '' : '\\';

            if ('self' !== $lcName && 'parent' !== $lcName) {
                $types[] = '' !== $prefix ? $prefix.$name : $name;
                continue;
            }
            if (!$r instanceof \ReflectionMethod) {
                continue;
            }
            if ('self' === $lcName) {
                $types[] = $prefix.$r->getDeclaringClass()->name;
            } else {
                $types[] = ($parent = $r->getDeclaringClass()->getParentClass()) ? $prefix.$parent->name : null;
            }
        }

        return $types ? implode('|', $types) : null;
    }
}
PKϤ$Z��{{<dependency-injection/LazyProxy/PhpDumper/DumperInterface.phpnu�[���<?php

/*
 * This file is part of the Symfony package.
 *
 * (c) Fabien Potencier <fabien@symfony.com>
 *
 * For the full copyright and license information, please view the LICENSE
 * file that was distributed with this source code.
 */

namespace Symfony\Component\DependencyInjection\LazyProxy\PhpDumper;

use Symfony\Component\DependencyInjection\Definition;

/**
 * Lazy proxy dumper capable of generating the instantiation logic PHP code for proxied services.
 *
 * @author Marco Pivetta <ocramius@gmail.com>
 */
interface DumperInterface
{
    /**
     * Inspects whether the given definitions should produce proxy instantiation logic in the dumped container.
     *
     * @return bool
     */
    public function isProxyCandidate(Definition $definition);

    /**
     * Generates the code to be used to instantiate a proxy in the dumped factory code.
     *
     * @return string
     */
    public function getProxyFactoryCode(Definition $definition, string $id, string $factoryCode);

    /**
     * Generates the code for the lazy proxy.
     *
     * @return string
     */
    public function getProxyCode(Definition $definition);
}
PKϤ$Z�?Q��7dependency-injection/LazyProxy/PhpDumper/NullDumper.phpnu�[���<?php

/*
 * This file is part of the Symfony package.
 *
 * (c) Fabien Potencier <fabien@symfony.com>
 *
 * For the full copyright and license information, please view the LICENSE
 * file that was distributed with this source code.
 */

namespace Symfony\Component\DependencyInjection\LazyProxy\PhpDumper;

use Symfony\Component\DependencyInjection\Definition;

/**
 * Null dumper, negates any proxy code generation for any given service definition.
 *
 * @author Marco Pivetta <ocramius@gmail.com>
 *
 * @final
 */
class NullDumper implements DumperInterface
{
    /**
     * {@inheritdoc}
     */
    public function isProxyCandidate(Definition $definition): bool
    {
        return false;
    }

    /**
     * {@inheritdoc}
     */
    public function getProxyFactoryCode(Definition $definition, string $id, string $factoryCode): string
    {
        return '';
    }

    /**
     * {@inheritdoc}
     */
    public function getProxyCode(Definition $definition): string
    {
        return '';
    }
}
PKϤ$Z@#�MMEdependency-injection/LazyProxy/Instantiator/InstantiatorInterface.phpnu�[���<?php

/*
 * This file is part of the Symfony package.
 *
 * (c) Fabien Potencier <fabien@symfony.com>
 *
 * For the full copyright and license information, please view the LICENSE
 * file that was distributed with this source code.
 */

namespace Symfony\Component\DependencyInjection\LazyProxy\Instantiator;

use Symfony\Component\DependencyInjection\ContainerInterface;
use Symfony\Component\DependencyInjection\Definition;

/**
 * Lazy proxy instantiator, capable of instantiating a proxy given a container, the
 * service definitions and a callback that produces the real service instance.
 *
 * @author Marco Pivetta <ocramius@gmail.com>
 */
interface InstantiatorInterface
{
    /**
     * Instantiates a proxy object.
     *
     * @param string   $id               Identifier of the requested service
     * @param callable $realInstantiator Zero-argument callback that is capable of producing the real service instance
     *
     * @return object
     */
    public function instantiateProxy(ContainerInterface $container, Definition $definition, string $id, callable $realInstantiator);
}
PKϤ$Z�<�iiGdependency-injection/LazyProxy/Instantiator/RealServiceInstantiator.phpnu�[���<?php

/*
 * This file is part of the Symfony package.
 *
 * (c) Fabien Potencier <fabien@symfony.com>
 *
 * For the full copyright and license information, please view the LICENSE
 * file that was distributed with this source code.
 */

namespace Symfony\Component\DependencyInjection\LazyProxy\Instantiator;

use Symfony\Component\DependencyInjection\ContainerInterface;
use Symfony\Component\DependencyInjection\Definition;

/**
 * {@inheritdoc}
 *
 * Noop proxy instantiator - produces the real service instead of a proxy instance.
 *
 * @author Marco Pivetta <ocramius@gmail.com>
 */
class RealServiceInstantiator implements InstantiatorInterface
{
    /**
     * {@inheritdoc}
     */
    public function instantiateProxy(ContainerInterface $container, Definition $definition, string $id, callable $realInstantiator)
    {
        return $realInstantiator();
    }
}
PKϤ$Z=��))dependency-injection/LICENSEnu�[���Copyright (c) 2004-2020 Fabien Potencier

Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is furnished
to do so, subject to the following conditions:

The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.

THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
THE SOFTWARE.
PKϤ$Z�u�dd'dependency-injection/ServiceLocator.phpnu�[���<?php

/*
 * This file is part of the Symfony package.
 *
 * (c) Fabien Potencier <fabien@symfony.com>
 *
 * For the full copyright and license information, please view the LICENSE
 * file that was distributed with this source code.
 */

namespace Symfony\Component\DependencyInjection;

use Psr\Container\ContainerExceptionInterface;
use Psr\Container\NotFoundExceptionInterface;
use Symfony\Component\DependencyInjection\Exception\RuntimeException;
use Symfony\Component\DependencyInjection\Exception\ServiceCircularReferenceException;
use Symfony\Component\DependencyInjection\Exception\ServiceNotFoundException;
use Symfony\Contracts\Service\ServiceLocatorTrait;
use Symfony\Contracts\Service\ServiceProviderInterface;
use Symfony\Contracts\Service\ServiceSubscriberInterface;

/**
 * @author Robin Chalas <robin.chalas@gmail.com>
 * @author Nicolas Grekas <p@tchwork.com>
 */
class ServiceLocator implements ServiceProviderInterface
{
    use ServiceLocatorTrait {
        get as private doGet;
    }

    private $externalId;
    private $container;

    public function get($id)
    {
        if (!$this->externalId) {
            return $this->doGet($id);
        }

        try {
            return $this->doGet($id);
        } catch (RuntimeException $e) {
            $what = sprintf('service "%s" required by "%s"', $id, $this->externalId);
            $message = preg_replace('/service "\.service_locator\.[^"]++"/', $what, $e->getMessage());

            if ($e->getMessage() === $message) {
                $message = sprintf('Cannot resolve %s: %s', $what, $message);
            }

            $r = new \ReflectionProperty($e, 'message');
            $r->setAccessible(true);
            $r->setValue($e, $message);

            throw $e;
        }
    }

    public function __invoke(string $id)
    {
        return isset($this->factories[$id]) ? $this->get($id) : null;
    }

    /**
     * @internal
     *
     * @return static
     */
    public function withContext(string $externalId, Container $container): self
    {
        $locator = clone $this;
        $locator->externalId = $externalId;
        $locator->container = $container;

        return $locator;
    }

    private function createNotFoundException(string $id): NotFoundExceptionInterface
    {
        if ($this->loading) {
            $msg = sprintf('The service "%s" has a dependency on a non-existent service "%s". This locator %s', end($this->loading), $id, $this->formatAlternatives());

            return new ServiceNotFoundException($id, end($this->loading) ?: null, null, [], $msg);
        }

        $class = debug_backtrace(\DEBUG_BACKTRACE_PROVIDE_OBJECT | \DEBUG_BACKTRACE_IGNORE_ARGS, 4);
        $class = isset($class[3]['object']) ? \get_class($class[3]['object']) : null;
        $externalId = $this->externalId ?: $class;

        $msg = [];
        $msg[] = sprintf('Service "%s" not found:', $id);

        if (!$this->container) {
            $class = null;
        } elseif ($this->container->has($id) || isset($this->container->getRemovedIds()[$id])) {
            $msg[] = 'even though it exists in the app\'s container,';
        } else {
            try {
                $this->container->get($id);
                $class = null;
            } catch (ServiceNotFoundException $e) {
                if ($e->getAlternatives()) {
                    $msg[] = sprintf('did you mean %s? Anyway,', $this->formatAlternatives($e->getAlternatives(), 'or'));
                } else {
                    $class = null;
                }
            }
        }
        if ($externalId) {
            $msg[] = sprintf('the container inside "%s" is a smaller service locator that %s', $externalId, $this->formatAlternatives());
        } else {
            $msg[] = sprintf('the current service locator %s', $this->formatAlternatives());
        }

        if (!$class) {
            // no-op
        } elseif (is_subclass_of($class, ServiceSubscriberInterface::class)) {
            $msg[] = sprintf('Unless you need extra laziness, try using dependency injection instead. Otherwise, you need to declare it using "%s::getSubscribedServices()".', preg_replace('/([^\\\\]++\\\\)++/', '', $class));
        } else {
            $msg[] = 'Try using dependency injection instead.';
        }

        return new ServiceNotFoundException($id, end($this->loading) ?: null, null, [], implode(' ', $msg));
    }

    private function createCircularReferenceException(string $id, array $path): ContainerExceptionInterface
    {
        return new ServiceCircularReferenceException($id, $path);
    }

    private function formatAlternatives(array $alternatives = null, string $separator = 'and'): string
    {
        $format = '"%s"%s';
        if (null === $alternatives) {
            if (!$alternatives = array_keys($this->factories)) {
                return 'is empty...';
            }
            $format = sprintf('only knows about the %s service%s.', $format, 1 < \count($alternatives) ? 's' : '');
        }
        $last = array_pop($alternatives);

        return sprintf($format, $alternatives ? implode('", "', $alternatives) : $last, $alternatives ? sprintf(' %s "%s"', $separator, $last) : '');
    }
}
PKϤ$Z����0
0
)dependency-injection/ReverseContainer.phpnu�[���<?php

/*
 * This file is part of the Symfony package.
 *
 * (c) Fabien Potencier <fabien@symfony.com>
 *
 * For the full copyright and license information, please view the LICENSE
 * file that was distributed with this source code.
 */

namespace Symfony\Component\DependencyInjection;

use Psr\Container\ContainerInterface;
use Symfony\Component\DependencyInjection\Exception\ServiceNotFoundException;

/**
 * Turns public and "container.reversible" services back to their ids.
 *
 * @author Nicolas Grekas <p@tchwork.com>
 */
final class ReverseContainer
{
    private $serviceContainer;
    private $reversibleLocator;
    private $tagName;
    private $getServiceId;

    public function __construct(Container $serviceContainer, ContainerInterface $reversibleLocator, string $tagName = 'container.reversible')
    {
        $this->serviceContainer = $serviceContainer;
        $this->reversibleLocator = $reversibleLocator;
        $this->tagName = $tagName;
        $this->getServiceId = \Closure::bind(function (object $service): ?string {
            return array_search($service, $this->services, true) ?: array_search($service, $this->privates, true) ?: null;
        }, $serviceContainer, Container::class);
    }

    /**
     * Returns the id of the passed object when it exists as a service.
     *
     * To be reversible, services need to be either public or be tagged with "container.reversible".
     */
    public function getId(object $service): ?string
    {
        if ($this->serviceContainer === $service) {
            return 'service_container';
        }

        if (null === $id = ($this->getServiceId)($service)) {
            return null;
        }

        if ($this->serviceContainer->has($id) || $this->reversibleLocator->has($id)) {
            return $id;
        }

        return null;
    }

    /**
     * @throws ServiceNotFoundException When the service is not reversible
     */
    public function getService(string $id): object
    {
        if ($this->serviceContainer->has($id)) {
            return $this->serviceContainer->get($id);
        }

        if ($this->reversibleLocator->has($id)) {
            return $this->reversibleLocator->get($id);
        }

        if (isset($this->serviceContainer->getRemovedIds()[$id])) {
            throw new ServiceNotFoundException($id, null, null, [], sprintf('The "%s" service is private and cannot be accessed by reference. You should either make it public, or tag it as "%s".', $id, $this->tagName));
        }

        // will throw a ServiceNotFoundException
        $this->serviceContainer->get($id);
    }
}
PKϤ$Z�=w�
�
(dependency-injection/ChildDefinition.phpnu�[���<?php

/*
 * This file is part of the Symfony package.
 *
 * (c) Fabien Potencier <fabien@symfony.com>
 *
 * For the full copyright and license information, please view the LICENSE
 * file that was distributed with this source code.
 */

namespace Symfony\Component\DependencyInjection;

use Symfony\Component\DependencyInjection\Exception\InvalidArgumentException;
use Symfony\Component\DependencyInjection\Exception\OutOfBoundsException;

/**
 * This definition extends another definition.
 *
 * @author Johannes M. Schmitt <schmittjoh@gmail.com>
 */
class ChildDefinition extends Definition
{
    private $parent;

    /**
     * @param string $parent The id of Definition instance to decorate
     */
    public function __construct(string $parent)
    {
        $this->parent = $parent;
        $this->setPrivate(false);
    }

    /**
     * Returns the Definition to inherit from.
     *
     * @return string
     */
    public function getParent()
    {
        return $this->parent;
    }

    /**
     * Sets the Definition to inherit from.
     *
     * @param string $parent
     *
     * @return $this
     */
    public function setParent($parent)
    {
        $this->parent = $parent;

        return $this;
    }

    /**
     * Gets an argument to pass to the service constructor/factory method.
     *
     * If replaceArgument() has been used to replace an argument, this method
     * will return the replacement value.
     *
     * @param int|string $index
     *
     * @return mixed The argument value
     *
     * @throws OutOfBoundsException When the argument does not exist
     */
    public function getArgument($index)
    {
        if (\array_key_exists('index_'.$index, $this->arguments)) {
            return $this->arguments['index_'.$index];
        }

        return parent::getArgument($index);
    }

    /**
     * You should always use this method when overwriting existing arguments
     * of the parent definition.
     *
     * If you directly call setArguments() keep in mind that you must follow
     * certain conventions when you want to overwrite the arguments of the
     * parent definition, otherwise your arguments will only be appended.
     *
     * @param int|string $index
     * @param mixed      $value
     *
     * @return $this
     *
     * @throws InvalidArgumentException when $index isn't an integer
     */
    public function replaceArgument($index, $value)
    {
        if (\is_int($index)) {
            $this->arguments['index_'.$index] = $value;
        } elseif (0 === strpos($index, '$')) {
            $this->arguments[$index] = $value;
        } else {
            throw new InvalidArgumentException('The argument must be an existing index or the name of a constructor\'s parameter.');
        }

        return $this;
    }
}
PKϤ$Z�W>O}}.dependency-injection/EnvVarLoaderInterface.phpnu�[���<?php

/*
 * This file is part of the Symfony package.
 *
 * (c) Fabien Potencier <fabien@symfony.com>
 *
 * For the full copyright and license information, please view the LICENSE
 * file that was distributed with this source code.
 */

namespace Symfony\Component\DependencyInjection;

/**
 * EnvVarLoaderInterface objects return key/value pairs that are added to the list of available env vars.
 *
 * @author Nicolas Grekas <p@tchwork.com>
 */
interface EnvVarLoaderInterface
{
    /**
     * @return string[] Key/value pairs that can be accessed using the regular "%env()%" syntax
     */
    public function loadEnvVars(): array;
}
PKϤ$Z��䎫X�X#dependency-injection/Definition.phpnu�[���<?php

/*
 * This file is part of the Symfony package.
 *
 * (c) Fabien Potencier <fabien@symfony.com>
 *
 * For the full copyright and license information, please view the LICENSE
 * file that was distributed with this source code.
 */

namespace Symfony\Component\DependencyInjection;

use Symfony\Component\DependencyInjection\Argument\BoundArgument;
use Symfony\Component\DependencyInjection\Exception\InvalidArgumentException;
use Symfony\Component\DependencyInjection\Exception\OutOfBoundsException;

/**
 * Definition represents a service definition.
 *
 * @author Fabien Potencier <fabien@symfony.com>
 */
class Definition
{
    private $class;
    private $file;
    private $factory;
    private $shared = true;
    private $deprecation = [];
    private $properties = [];
    private $calls = [];
    private $instanceof = [];
    private $autoconfigured = false;
    private $configurator;
    private $tags = [];
    private $public = true;
    private $private = true;
    private $synthetic = false;
    private $abstract = false;
    private $lazy = false;
    private $decoratedService;
    private $autowired = false;
    private $changes = [];
    private $bindings = [];
    private $errors = [];

    protected $arguments = [];

    private static $defaultDeprecationTemplate = 'The "%service_id%" service is deprecated. You should stop using it, as it will be removed in the future.';

    /**
     * @internal
     *
     * Used to store the name of the inner id when using service decoration together with autowiring
     */
    public $innerServiceId;

    /**
     * @internal
     *
     * Used to store the behavior to follow when using service decoration and the decorated service is invalid
     */
    public $decorationOnInvalid;

    public function __construct(string $class = null, array $arguments = [])
    {
        if (null !== $class) {
            $this->setClass($class);
        }
        $this->arguments = $arguments;
    }

    /**
     * Returns all changes tracked for the Definition object.
     *
     * @return array An array of changes for this Definition
     */
    public function getChanges()
    {
        return $this->changes;
    }

    /**
     * Sets the tracked changes for the Definition object.
     *
     * @param array $changes An array of changes for this Definition
     *
     * @return $this
     */
    public function setChanges(array $changes)
    {
        $this->changes = $changes;

        return $this;
    }

    /**
     * Sets a factory.
     *
     * @param string|array|Reference $factory A PHP function, reference or an array containing a class/Reference and a method to call
     *
     * @return $this
     */
    public function setFactory($factory)
    {
        $this->changes['factory'] = true;

        if (\is_string($factory) && false !== strpos($factory, '::')) {
            $factory = explode('::', $factory, 2);
        } elseif ($factory instanceof Reference) {
            $factory = [$factory, '__invoke'];
        }

        $this->factory = $factory;

        return $this;
    }

    /**
     * Gets the factory.
     *
     * @return string|array|null The PHP function or an array containing a class/Reference and a method to call
     */
    public function getFactory()
    {
        return $this->factory;
    }

    /**
     * Sets the service that this service is decorating.
     *
     * @param string|null $id        The decorated service id, use null to remove decoration
     * @param string|null $renamedId The new decorated service id
     *
     * @return $this
     *
     * @throws InvalidArgumentException in case the decorated service id and the new decorated service id are equals
     */
    public function setDecoratedService(?string $id, ?string $renamedId = null, int $priority = 0, int $invalidBehavior = ContainerInterface::EXCEPTION_ON_INVALID_REFERENCE)
    {
        if ($renamedId && $id === $renamedId) {
            throw new InvalidArgumentException(sprintf('The decorated service inner name for "%s" must be different than the service name itself.', $id));
        }

        $this->changes['decorated_service'] = true;

        if (null === $id) {
            $this->decoratedService = null;
        } else {
            $this->decoratedService = [$id, $renamedId, (int) $priority];

            if (ContainerInterface::EXCEPTION_ON_INVALID_REFERENCE !== $invalidBehavior) {
                $this->decoratedService[] = $invalidBehavior;
            }
        }

        return $this;
    }

    /**
     * Gets the service that this service is decorating.
     *
     * @return array|null An array composed of the decorated service id, the new id for it and the priority of decoration, null if no service is decorated
     */
    public function getDecoratedService()
    {
        return $this->decoratedService;
    }

    /**
     * Sets the service class.
     *
     * @return $this
     */
    public function setClass(?string $class)
    {
        $this->changes['class'] = true;

        $this->class = $class;

        return $this;
    }

    /**
     * Gets the service class.
     *
     * @return string|null The service class
     */
    public function getClass()
    {
        return $this->class;
    }

    /**
     * Sets the arguments to pass to the service constructor/factory method.
     *
     * @return $this
     */
    public function setArguments(array $arguments)
    {
        $this->arguments = $arguments;

        return $this;
    }

    /**
     * Sets the properties to define when creating the service.
     *
     * @return $this
     */
    public function setProperties(array $properties)
    {
        $this->properties = $properties;

        return $this;
    }

    /**
     * Gets the properties to define when creating the service.
     *
     * @return array
     */
    public function getProperties()
    {
        return $this->properties;
    }

    /**
     * Sets a specific property.
     *
     * @param mixed $value
     *
     * @return $this
     */
    public function setProperty(string $name, $value)
    {
        $this->properties[$name] = $value;

        return $this;
    }

    /**
     * Adds an argument to pass to the service constructor/factory method.
     *
     * @param mixed $argument An argument
     *
     * @return $this
     */
    public function addArgument($argument)
    {
        $this->arguments[] = $argument;

        return $this;
    }

    /**
     * Replaces a specific argument.
     *
     * @param int|string $index
     * @param mixed      $argument
     *
     * @return $this
     *
     * @throws OutOfBoundsException When the replaced argument does not exist
     */
    public function replaceArgument($index, $argument)
    {
        if (0 === \count($this->arguments)) {
            throw new OutOfBoundsException('Cannot replace arguments if none have been configured yet.');
        }

        if (\is_int($index) && ($index < 0 || $index > \count($this->arguments) - 1)) {
            throw new OutOfBoundsException(sprintf('The index "%d" is not in the range [0, %d].', $index, \count($this->arguments) - 1));
        }

        if (!\array_key_exists($index, $this->arguments)) {
            throw new OutOfBoundsException(sprintf('The argument "%s" doesn\'t exist.', $index));
        }

        $this->arguments[$index] = $argument;

        return $this;
    }

    /**
     * Sets a specific argument.
     *
     * @param int|string $key
     * @param mixed      $value
     *
     * @return $this
     */
    public function setArgument($key, $value)
    {
        $this->arguments[$key] = $value;

        return $this;
    }

    /**
     * Gets the arguments to pass to the service constructor/factory method.
     *
     * @return array The array of arguments
     */
    public function getArguments()
    {
        return $this->arguments;
    }

    /**
     * Gets an argument to pass to the service constructor/factory method.
     *
     * @param int|string $index
     *
     * @return mixed The argument value
     *
     * @throws OutOfBoundsException When the argument does not exist
     */
    public function getArgument($index)
    {
        if (!\array_key_exists($index, $this->arguments)) {
            throw new OutOfBoundsException(sprintf('The argument "%s" doesn\'t exist.', $index));
        }

        return $this->arguments[$index];
    }

    /**
     * Sets the methods to call after service initialization.
     *
     * @return $this
     */
    public function setMethodCalls(array $calls = [])
    {
        $this->calls = [];
        foreach ($calls as $call) {
            $this->addMethodCall($call[0], $call[1], $call[2] ?? false);
        }

        return $this;
    }

    /**
     * Adds a method to call after service initialization.
     *
     * @param string $method       The method name to call
     * @param array  $arguments    An array of arguments to pass to the method call
     * @param bool   $returnsClone Whether the call returns the service instance or not
     *
     * @return $this
     *
     * @throws InvalidArgumentException on empty $method param
     */
    public function addMethodCall(string $method, array $arguments = [], bool $returnsClone = false)
    {
        if (empty($method)) {
            throw new InvalidArgumentException('Method name cannot be empty.');
        }
        $this->calls[] = $returnsClone ? [$method, $arguments, true] : [$method, $arguments];

        return $this;
    }

    /**
     * Removes a method to call after service initialization.
     *
     * @return $this
     */
    public function removeMethodCall(string $method)
    {
        foreach ($this->calls as $i => $call) {
            if ($call[0] === $method) {
                unset($this->calls[$i]);
                break;
            }
        }

        return $this;
    }

    /**
     * Check if the current definition has a given method to call after service initialization.
     *
     * @return bool
     */
    public function hasMethodCall(string $method)
    {
        foreach ($this->calls as $call) {
            if ($call[0] === $method) {
                return true;
            }
        }

        return false;
    }

    /**
     * Gets the methods to call after service initialization.
     *
     * @return array An array of method calls
     */
    public function getMethodCalls()
    {
        return $this->calls;
    }

    /**
     * Sets the definition templates to conditionally apply on the current definition, keyed by parent interface/class.
     *
     * @param ChildDefinition[] $instanceof
     *
     * @return $this
     */
    public function setInstanceofConditionals(array $instanceof)
    {
        $this->instanceof = $instanceof;

        return $this;
    }

    /**
     * Gets the definition templates to conditionally apply on the current definition, keyed by parent interface/class.
     *
     * @return ChildDefinition[]
     */
    public function getInstanceofConditionals()
    {
        return $this->instanceof;
    }

    /**
     * Sets whether or not instanceof conditionals should be prepended with a global set.
     *
     * @return $this
     */
    public function setAutoconfigured(bool $autoconfigured)
    {
        $this->changes['autoconfigured'] = true;

        $this->autoconfigured = $autoconfigured;

        return $this;
    }

    /**
     * @return bool
     */
    public function isAutoconfigured()
    {
        return $this->autoconfigured;
    }

    /**
     * Sets tags for this definition.
     *
     * @return $this
     */
    public function setTags(array $tags)
    {
        $this->tags = $tags;

        return $this;
    }

    /**
     * Returns all tags.
     *
     * @return array An array of tags
     */
    public function getTags()
    {
        return $this->tags;
    }

    /**
     * Gets a tag by name.
     *
     * @return array An array of attributes
     */
    public function getTag(string $name)
    {
        return isset($this->tags[$name]) ? $this->tags[$name] : [];
    }

    /**
     * Adds a tag for this definition.
     *
     * @return $this
     */
    public function addTag(string $name, array $attributes = [])
    {
        $this->tags[$name][] = $attributes;

        return $this;
    }

    /**
     * Whether this definition has a tag with the given name.
     *
     * @return bool
     */
    public function hasTag(string $name)
    {
        return isset($this->tags[$name]);
    }

    /**
     * Clears all tags for a given name.
     *
     * @return $this
     */
    public function clearTag(string $name)
    {
        unset($this->tags[$name]);

        return $this;
    }

    /**
     * Clears the tags for this definition.
     *
     * @return $this
     */
    public function clearTags()
    {
        $this->tags = [];

        return $this;
    }

    /**
     * Sets a file to require before creating the service.
     *
     * @return $this
     */
    public function setFile(?string $file)
    {
        $this->changes['file'] = true;

        $this->file = $file;

        return $this;
    }

    /**
     * Gets the file to require before creating the service.
     *
     * @return string|null The full pathname to include
     */
    public function getFile()
    {
        return $this->file;
    }

    /**
     * Sets if the service must be shared or not.
     *
     * @return $this
     */
    public function setShared(bool $shared)
    {
        $this->changes['shared'] = true;

        $this->shared = $shared;

        return $this;
    }

    /**
     * Whether this service is shared.
     *
     * @return bool
     */
    public function isShared()
    {
        return $this->shared;
    }

    /**
     * Sets the visibility of this service.
     *
     * @return $this
     */
    public function setPublic(bool $boolean)
    {
        $this->changes['public'] = true;

        $this->public = $boolean;
        $this->private = false;

        return $this;
    }

    /**
     * Whether this service is public facing.
     *
     * @return bool
     */
    public function isPublic()
    {
        return $this->public;
    }

    /**
     * Sets if this service is private.
     *
     * When set, the "private" state has a higher precedence than "public".
     * In version 3.4, a "private" service always remains publicly accessible,
     * but triggers a deprecation notice when accessed from the container,
     * so that the service can be made really private in 4.0.
     *
     * @return $this
     */
    public function setPrivate(bool $boolean)
    {
        $this->private = $boolean;

        return $this;
    }

    /**
     * Whether this service is private.
     *
     * @return bool
     */
    public function isPrivate()
    {
        return $this->private;
    }

    /**
     * Sets the lazy flag of this service.
     *
     * @return $this
     */
    public function setLazy(bool $lazy)
    {
        $this->changes['lazy'] = true;

        $this->lazy = $lazy;

        return $this;
    }

    /**
     * Whether this service is lazy.
     *
     * @return bool
     */
    public function isLazy()
    {
        return $this->lazy;
    }

    /**
     * Sets whether this definition is synthetic, that is not constructed by the
     * container, but dynamically injected.
     *
     * @return $this
     */
    public function setSynthetic(bool $boolean)
    {
        $this->synthetic = $boolean;

        return $this;
    }

    /**
     * Whether this definition is synthetic, that is not constructed by the
     * container, but dynamically injected.
     *
     * @return bool
     */
    public function isSynthetic()
    {
        return $this->synthetic;
    }

    /**
     * Whether this definition is abstract, that means it merely serves as a
     * template for other definitions.
     *
     * @return $this
     */
    public function setAbstract(bool $boolean)
    {
        $this->abstract = $boolean;

        return $this;
    }

    /**
     * Whether this definition is abstract, that means it merely serves as a
     * template for other definitions.
     *
     * @return bool
     */
    public function isAbstract()
    {
        return $this->abstract;
    }

    /**
     * Whether this definition is deprecated, that means it should not be called
     * anymore.
     *
     * @param string $package The name of the composer package that is triggering the deprecation
     * @param string $version The version of the package that introduced the deprecation
     * @param string $message The deprecation message to use
     *
     * @return $this
     *
     * @throws InvalidArgumentException when the message template is invalid
     */
    public function setDeprecated(/* string $package, string $version, string $message */)
    {
        $args = \func_get_args();

        if (\func_num_args() < 3) {
            trigger_deprecation('symfony/dependency-injection', '5.1', 'The signature of method "%s()" requires 3 arguments: "string $package, string $version, string $message", not defining them is deprecated.', __METHOD__);

            $status = $args[0] ?? true;

            if (!$status) {
                trigger_deprecation('symfony/dependency-injection', '5.1', 'Passing a null message to un-deprecate a node is deprecated.');
            }

            $message = (string) ($args[1] ?? null);
            $package = $version = '';
        } else {
            $status = true;
            $package = (string) $args[0];
            $version = (string) $args[1];
            $message = (string) $args[2];
        }

        if ('' !== $message) {
            if (preg_match('#[\r\n]|\*/#', $message)) {
                throw new InvalidArgumentException('Invalid characters found in deprecation template.');
            }

            if (false === strpos($message, '%service_id%')) {
                throw new InvalidArgumentException('The deprecation template must contain the "%service_id%" placeholder.');
            }
        }

        $this->changes['deprecated'] = true;
        $this->deprecation = $status ? ['package' => $package, 'version' => $version, 'message' => $message ?: self::$defaultDeprecationTemplate] : [];

        return $this;
    }

    /**
     * Whether this definition is deprecated, that means it should not be called
     * anymore.
     *
     * @return bool
     */
    public function isDeprecated()
    {
        return (bool) $this->deprecation;
    }

    /**
     * Message to use if this definition is deprecated.
     *
     * @deprecated since Symfony 5.1, use "getDeprecation()" instead.
     *
     * @param string $id Service id relying on this definition
     *
     * @return string
     */
    public function getDeprecationMessage(string $id)
    {
        trigger_deprecation('symfony/dependency-injection', '5.1', 'The "%s()" method is deprecated, use "getDeprecation()" instead.', __METHOD__);

        return $this->getDeprecation($id)['message'];
    }

    /**
     * @param string $id Service id relying on this definition
     */
    public function getDeprecation(string $id): array
    {
        return [
            'package' => $this->deprecation['package'],
            'version' => $this->deprecation['version'],
            'message' => str_replace('%service_id%', $id, $this->deprecation['message']),
        ];
    }

    /**
     * Sets a configurator to call after the service is fully initialized.
     *
     * @param string|array|Reference $configurator A PHP function, reference or an array containing a class/Reference and a method to call
     *
     * @return $this
     */
    public function setConfigurator($configurator)
    {
        $this->changes['configurator'] = true;

        if (\is_string($configurator) && false !== strpos($configurator, '::')) {
            $configurator = explode('::', $configurator, 2);
        } elseif ($configurator instanceof Reference) {
            $configurator = [$configurator, '__invoke'];
        }

        $this->configurator = $configurator;

        return $this;
    }

    /**
     * Gets the configurator to call after the service is fully initialized.
     *
     * @return callable|array|null
     */
    public function getConfigurator()
    {
        return $this->configurator;
    }

    /**
     * Is the definition autowired?
     *
     * @return bool
     */
    public function isAutowired()
    {
        return $this->autowired;
    }

    /**
     * Enables/disables autowiring.
     *
     * @return $this
     */
    public function setAutowired(bool $autowired)
    {
        $this->changes['autowired'] = true;

        $this->autowired = $autowired;

        return $this;
    }

    /**
     * Gets bindings.
     *
     * @return array|BoundArgument[]
     */
    public function getBindings()
    {
        return $this->bindings;
    }

    /**
     * Sets bindings.
     *
     * Bindings map $named or FQCN arguments to values that should be
     * injected in the matching parameters (of the constructor, of methods
     * called and of controller actions).
     *
     * @return $this
     */
    public function setBindings(array $bindings)
    {
        foreach ($bindings as $key => $binding) {
            if (0 < strpos($key, '$') && $key !== $k = preg_replace('/[ \t]*\$/', ' $', $key)) {
                unset($bindings[$key]);
                $bindings[$key = $k] = $binding;
            }
            if (!$binding instanceof BoundArgument) {
                $bindings[$key] = new BoundArgument($binding);
            }
        }

        $this->bindings = $bindings;

        return $this;
    }

    /**
     * Add an error that occurred when building this Definition.
     *
     * @param string|\Closure|self $error
     *
     * @return $this
     */
    public function addError($error)
    {
        if ($error instanceof self) {
            $this->errors = array_merge($this->errors, $error->errors);
        } else {
            $this->errors[] = $error;
        }

        return $this;
    }

    /**
     * Returns any errors that occurred while building this Definition.
     *
     * @return array
     */
    public function getErrors()
    {
        foreach ($this->errors as $i => $error) {
            if ($error instanceof \Closure) {
                $this->errors[$i] = (string) $error();
            } elseif (!\is_string($error)) {
                $this->errors[$i] = (string) $error;
            }
        }

        return $this->errors;
    }

    public function hasErrors(): bool
    {
        return (bool) $this->errors;
    }
}
PKϤ$Z"�L+����)dependency-injection/ContainerBuilder.phpnu�[���<?php

/*
 * This file is part of the Symfony package.
 *
 * (c) Fabien Potencier <fabien@symfony.com>
 *
 * For the full copyright and license information, please view the LICENSE
 * file that was distributed with this source code.
 */

namespace Symfony\Component\DependencyInjection;

use Psr\Container\ContainerInterface as PsrContainerInterface;
use Symfony\Component\Config\Resource\ClassExistenceResource;
use Symfony\Component\Config\Resource\ComposerResource;
use Symfony\Component\Config\Resource\DirectoryResource;
use Symfony\Component\Config\Resource\FileExistenceResource;
use Symfony\Component\Config\Resource\FileResource;
use Symfony\Component\Config\Resource\GlobResource;
use Symfony\Component\Config\Resource\ReflectionClassResource;
use Symfony\Component\Config\Resource\ResourceInterface;
use Symfony\Component\DependencyInjection\Argument\AbstractArgument;
use Symfony\Component\DependencyInjection\Argument\IteratorArgument;
use Symfony\Component\DependencyInjection\Argument\RewindableGenerator;
use Symfony\Component\DependencyInjection\Argument\ServiceClosureArgument;
use Symfony\Component\DependencyInjection\Argument\ServiceLocator;
use Symfony\Component\DependencyInjection\Argument\ServiceLocatorArgument;
use Symfony\Component\DependencyInjection\Compiler\Compiler;
use Symfony\Component\DependencyInjection\Compiler\CompilerPassInterface;
use Symfony\Component\DependencyInjection\Compiler\PassConfig;
use Symfony\Component\DependencyInjection\Compiler\ResolveEnvPlaceholdersPass;
use Symfony\Component\DependencyInjection\Exception\BadMethodCallException;
use Symfony\Component\DependencyInjection\Exception\InvalidArgumentException;
use Symfony\Component\DependencyInjection\Exception\LogicException;
use Symfony\Component\DependencyInjection\Exception\RuntimeException;
use Symfony\Component\DependencyInjection\Exception\ServiceCircularReferenceException;
use Symfony\Component\DependencyInjection\Exception\ServiceNotFoundException;
use Symfony\Component\DependencyInjection\Extension\ExtensionInterface;
use Symfony\Component\DependencyInjection\LazyProxy\Instantiator\InstantiatorInterface;
use Symfony\Component\DependencyInjection\LazyProxy\Instantiator\RealServiceInstantiator;
use Symfony\Component\DependencyInjection\ParameterBag\EnvPlaceholderParameterBag;
use Symfony\Component\DependencyInjection\ParameterBag\ParameterBag;
use Symfony\Component\DependencyInjection\ParameterBag\ParameterBagInterface;
use Symfony\Component\ExpressionLanguage\Expression;
use Symfony\Component\ExpressionLanguage\ExpressionFunctionProviderInterface;

/**
 * ContainerBuilder is a DI container that provides an API to easily describe services.
 *
 * @author Fabien Potencier <fabien@symfony.com>
 */
class ContainerBuilder extends Container implements TaggedContainerInterface
{
    /**
     * @var ExtensionInterface[]
     */
    private $extensions = [];

    /**
     * @var ExtensionInterface[]
     */
    private $extensionsByNs = [];

    /**
     * @var Definition[]
     */
    private $definitions = [];

    /**
     * @var Alias[]
     */
    private $aliasDefinitions = [];

    /**
     * @var ResourceInterface[]
     */
    private $resources = [];

    private $extensionConfigs = [];

    /**
     * @var Compiler
     */
    private $compiler;

    private $trackResources;

    /**
     * @var InstantiatorInterface|null
     */
    private $proxyInstantiator;

    /**
     * @var ExpressionLanguage|null
     */
    private $expressionLanguage;

    /**
     * @var ExpressionFunctionProviderInterface[]
     */
    private $expressionLanguageProviders = [];

    /**
     * @var string[] with tag names used by findTaggedServiceIds
     */
    private $usedTags = [];

    /**
     * @var string[][] a map of env var names to their placeholders
     */
    private $envPlaceholders = [];

    /**
     * @var int[] a map of env vars to their resolution counter
     */
    private $envCounters = [];

    /**
     * @var string[] the list of vendor directories
     */
    private $vendors;

    private $autoconfiguredInstanceof = [];

    private $removedIds = [];

    private $removedBindingIds = [];

    private static $internalTypes = [
        'int' => true,
        'float' => true,
        'string' => true,
        'bool' => true,
        'resource' => true,
        'object' => true,
        'array' => true,
        'null' => true,
        'callable' => true,
        'iterable' => true,
        'mixed' => true,
    ];

    public function __construct(ParameterBagInterface $parameterBag = null)
    {
        parent::__construct($parameterBag);

        $this->trackResources = interface_exists('Symfony\Component\Config\Resource\ResourceInterface');
        $this->setDefinition('service_container', (new Definition(ContainerInterface::class))->setSynthetic(true)->setPublic(true));
        $this->setAlias(PsrContainerInterface::class, new Alias('service_container', false))->setDeprecated('symfony/dependency-injection', '5.1', $deprecationMessage = 'The "%alias_id%" autowiring alias is deprecated. Define it explicitly in your app if you want to keep using it.');
        $this->setAlias(ContainerInterface::class, new Alias('service_container', false))->setDeprecated('symfony/dependency-injection', '5.1', $deprecationMessage);
    }

    /**
     * @var \ReflectionClass[] a list of class reflectors
     */
    private $classReflectors;

    /**
     * Sets the track resources flag.
     *
     * If you are not using the loaders and therefore don't want
     * to depend on the Config component, set this flag to false.
     */
    public function setResourceTracking(bool $track)
    {
        $this->trackResources = $track;
    }

    /**
     * Checks if resources are tracked.
     *
     * @return bool true If resources are tracked, false otherwise
     */
    public function isTrackingResources()
    {
        return $this->trackResources;
    }

    /**
     * Sets the instantiator to be used when fetching proxies.
     */
    public function setProxyInstantiator(InstantiatorInterface $proxyInstantiator)
    {
        $this->proxyInstantiator = $proxyInstantiator;
    }

    public function registerExtension(ExtensionInterface $extension)
    {
        $this->extensions[$extension->getAlias()] = $extension;

        if (false !== $extension->getNamespace()) {
            $this->extensionsByNs[$extension->getNamespace()] = $extension;
        }
    }

    /**
     * Returns an extension by alias or namespace.
     *
     * @return ExtensionInterface An extension instance
     *
     * @throws LogicException if the extension is not registered
     */
    public function getExtension(string $name)
    {
        if (isset($this->extensions[$name])) {
            return $this->extensions[$name];
        }

        if (isset($this->extensionsByNs[$name])) {
            return $this->extensionsByNs[$name];
        }

        throw new LogicException(sprintf('Container extension "%s" is not registered.', $name));
    }

    /**
     * Returns all registered extensions.
     *
     * @return ExtensionInterface[] An array of ExtensionInterface
     */
    public function getExtensions()
    {
        return $this->extensions;
    }

    /**
     * Checks if we have an extension.
     *
     * @return bool If the extension exists
     */
    public function hasExtension(string $name)
    {
        return isset($this->extensions[$name]) || isset($this->extensionsByNs[$name]);
    }

    /**
     * Returns an array of resources loaded to build this configuration.
     *
     * @return ResourceInterface[] An array of resources
     */
    public function getResources()
    {
        return array_values($this->resources);
    }

    /**
     * @return $this
     */
    public function addResource(ResourceInterface $resource)
    {
        if (!$this->trackResources) {
            return $this;
        }

        if ($resource instanceof GlobResource && $this->inVendors($resource->getPrefix())) {
            return $this;
        }

        $this->resources[(string) $resource] = $resource;

        return $this;
    }

    /**
     * Sets the resources for this configuration.
     *
     * @param ResourceInterface[] $resources An array of resources
     *
     * @return $this
     */
    public function setResources(array $resources)
    {
        if (!$this->trackResources) {
            return $this;
        }

        $this->resources = $resources;

        return $this;
    }

    /**
     * Adds the object class hierarchy as resources.
     *
     * @param object|string $object An object instance or class name
     *
     * @return $this
     */
    public function addObjectResource($object)
    {
        if ($this->trackResources) {
            if (\is_object($object)) {
                $object = \get_class($object);
            }
            if (!isset($this->classReflectors[$object])) {
                $this->classReflectors[$object] = new \ReflectionClass($object);
            }
            $class = $this->classReflectors[$object];

            foreach ($class->getInterfaceNames() as $name) {
                if (null === $interface = &$this->classReflectors[$name]) {
                    $interface = new \ReflectionClass($name);
                }
                $file = $interface->getFileName();
                if (false !== $file && file_exists($file)) {
                    $this->fileExists($file);
                }
            }
            do {
                $file = $class->getFileName();
                if (false !== $file && file_exists($file)) {
                    $this->fileExists($file);
                }
                foreach ($class->getTraitNames() as $name) {
                    $this->addObjectResource($name);
                }
            } while ($class = $class->getParentClass());
        }

        return $this;
    }

    /**
     * Retrieves the requested reflection class and registers it for resource tracking.
     *
     * @throws \ReflectionException when a parent class/interface/trait is not found and $throw is true
     *
     * @final
     */
    public function getReflectionClass(?string $class, bool $throw = true): ?\ReflectionClass
    {
        if (!$class = $this->getParameterBag()->resolveValue($class)) {
            return null;
        }

        if (isset(self::$internalTypes[$class])) {
            return null;
        }

        $resource = $classReflector = null;

        try {
            if (isset($this->classReflectors[$class])) {
                $classReflector = $this->classReflectors[$class];
            } elseif (class_exists(ClassExistenceResource::class)) {
                $resource = new ClassExistenceResource($class, false);
                $classReflector = $resource->isFresh(0) ? false : new \ReflectionClass($class);
            } else {
                $classReflector = class_exists($class) ? new \ReflectionClass($class) : false;
            }
        } catch (\ReflectionException $e) {
            if ($throw) {
                throw $e;
            }
        }

        if ($this->trackResources) {
            if (!$classReflector) {
                $this->addResource($resource ?: new ClassExistenceResource($class, false));
            } elseif (!$classReflector->isInternal()) {
                $path = $classReflector->getFileName();

                if (!$this->inVendors($path)) {
                    $this->addResource(new ReflectionClassResource($classReflector, $this->vendors));
                }
            }
            $this->classReflectors[$class] = $classReflector;
        }

        return $classReflector ?: null;
    }

    /**
     * Checks whether the requested file or directory exists and registers the result for resource tracking.
     *
     * @param string      $path          The file or directory path for which to check the existence
     * @param bool|string $trackContents Whether to track contents of the given resource. If a string is passed,
     *                                   it will be used as pattern for tracking contents of the requested directory
     *
     * @final
     */
    public function fileExists(string $path, $trackContents = true): bool
    {
        $exists = file_exists($path);

        if (!$this->trackResources || $this->inVendors($path)) {
            return $exists;
        }

        if (!$exists) {
            $this->addResource(new FileExistenceResource($path));

            return $exists;
        }

        if (is_dir($path)) {
            if ($trackContents) {
                $this->addResource(new DirectoryResource($path, \is_string($trackContents) ? $trackContents : null));
            } else {
                $this->addResource(new GlobResource($path, '/*', false));
            }
        } elseif ($trackContents) {
            $this->addResource(new FileResource($path));
        }

        return $exists;
    }

    /**
     * Loads the configuration for an extension.
     *
     * @param string $extension The extension alias or namespace
     * @param array  $values    An array of values that customizes the extension
     *
     * @return $this
     *
     * @throws BadMethodCallException When this ContainerBuilder is compiled
     * @throws \LogicException        if the extension is not registered
     */
    public function loadFromExtension(string $extension, array $values = null)
    {
        if ($this->isCompiled()) {
            throw new BadMethodCallException('Cannot load from an extension on a compiled container.');
        }

        if (\func_num_args() < 2) {
            $values = [];
        }

        $namespace = $this->getExtension($extension)->getAlias();

        $this->extensionConfigs[$namespace][] = $values;

        return $this;
    }

    /**
     * Adds a compiler pass.
     *
     * @param string $type     The type of compiler pass
     * @param int    $priority Used to sort the passes
     *
     * @return $this
     */
    public function addCompilerPass(CompilerPassInterface $pass, string $type = PassConfig::TYPE_BEFORE_OPTIMIZATION, int $priority = 0)
    {
        $this->getCompiler()->addPass($pass, $type, $priority);

        $this->addObjectResource($pass);

        return $this;
    }

    /**
     * Returns the compiler pass config which can then be modified.
     *
     * @return PassConfig The compiler pass config
     */
    public function getCompilerPassConfig()
    {
        return $this->getCompiler()->getPassConfig();
    }

    /**
     * Returns the compiler.
     *
     * @return Compiler The compiler
     */
    public function getCompiler()
    {
        if (null === $this->compiler) {
            $this->compiler = new Compiler();
        }

        return $this->compiler;
    }

    /**
     * Sets a service.
     *
     * @throws BadMethodCallException When this ContainerBuilder is compiled
     */
    public function set(string $id, ?object $service)
    {
        if ($this->isCompiled() && (isset($this->definitions[$id]) && !$this->definitions[$id]->isSynthetic())) {
            // setting a synthetic service on a compiled container is alright
            throw new BadMethodCallException(sprintf('Setting service "%s" for an unknown or non-synthetic service definition on a compiled container is not allowed.', $id));
        }

        unset($this->definitions[$id], $this->aliasDefinitions[$id], $this->removedIds[$id]);

        parent::set($id, $service);
    }

    /**
     * Removes a service definition.
     */
    public function removeDefinition(string $id)
    {
        if (isset($this->definitions[$id])) {
            unset($this->definitions[$id]);
            $this->removedIds[$id] = true;
        }
    }

    /**
     * Returns true if the given service is defined.
     *
     * @param string $id The service identifier
     *
     * @return bool true if the service is defined, false otherwise
     */
    public function has($id)
    {
        $id = (string) $id;

        return isset($this->definitions[$id]) || isset($this->aliasDefinitions[$id]) || parent::has($id);
    }

    /**
     * Gets a service.
     *
     * @param string $id              The service identifier
     * @param int    $invalidBehavior The behavior when the service does not exist
     *
     * @return object|null The associated service
     *
     * @throws InvalidArgumentException          when no definitions are available
     * @throws ServiceCircularReferenceException When a circular reference is detected
     * @throws ServiceNotFoundException          When the service is not defined
     * @throws \Exception
     *
     * @see Reference
     */
    public function get($id, int $invalidBehavior = ContainerInterface::EXCEPTION_ON_INVALID_REFERENCE)
    {
        if ($this->isCompiled() && isset($this->removedIds[$id = (string) $id]) && ContainerInterface::EXCEPTION_ON_INVALID_REFERENCE >= $invalidBehavior) {
            return parent::get($id);
        }

        return $this->doGet($id, $invalidBehavior);
    }

    private function doGet(string $id, int $invalidBehavior = ContainerInterface::EXCEPTION_ON_INVALID_REFERENCE, array &$inlineServices = null, bool $isConstructorArgument = false)
    {
        if (isset($inlineServices[$id])) {
            return $inlineServices[$id];
        }
        if (null === $inlineServices) {
            $isConstructorArgument = true;
            $inlineServices = [];
        }
        try {
            if (ContainerInterface::IGNORE_ON_UNINITIALIZED_REFERENCE === $invalidBehavior) {
                return parent::get($id, $invalidBehavior);
            }
            if ($service = parent::get($id, ContainerInterface::NULL_ON_INVALID_REFERENCE)) {
                return $service;
            }
        } catch (ServiceCircularReferenceException $e) {
            if ($isConstructorArgument) {
                throw $e;
            }
        }

        if (!isset($this->definitions[$id]) && isset($this->aliasDefinitions[$id])) {
            $alias = $this->aliasDefinitions[$id];

            if ($alias->isDeprecated()) {
                $deprecation = $alias->getDeprecation($id);
                trigger_deprecation($deprecation['package'], $deprecation['version'], $deprecation['message']);
            }

            return $this->doGet((string) $alias, $invalidBehavior, $inlineServices, $isConstructorArgument);
        }

        try {
            $definition = $this->getDefinition($id);
        } catch (ServiceNotFoundException $e) {
            if (ContainerInterface::EXCEPTION_ON_INVALID_REFERENCE < $invalidBehavior) {
                return null;
            }

            throw $e;
        }

        if ($definition->hasErrors() && $e = $definition->getErrors()) {
            throw new RuntimeException(reset($e));
        }

        if ($isConstructorArgument) {
            $this->loading[$id] = true;
        }

        try {
            return $this->createService($definition, $inlineServices, $isConstructorArgument, $id);
        } finally {
            if ($isConstructorArgument) {
                unset($this->loading[$id]);
            }
        }
    }

    /**
     * Merges a ContainerBuilder with the current ContainerBuilder configuration.
     *
     * Service definitions overrides the current defined ones.
     *
     * But for parameters, they are overridden by the current ones. It allows
     * the parameters passed to the container constructor to have precedence
     * over the loaded ones.
     *
     *     $container = new ContainerBuilder(new ParameterBag(['foo' => 'bar']));
     *     $loader = new LoaderXXX($container);
     *     $loader->load('resource_name');
     *     $container->register('foo', 'stdClass');
     *
     * In the above example, even if the loaded resource defines a foo
     * parameter, the value will still be 'bar' as defined in the ContainerBuilder
     * constructor.
     *
     * @throws BadMethodCallException When this ContainerBuilder is compiled
     */
    public function merge(self $container)
    {
        if ($this->isCompiled()) {
            throw new BadMethodCallException('Cannot merge on a compiled container.');
        }

        $this->addDefinitions($container->getDefinitions());
        $this->addAliases($container->getAliases());
        $this->getParameterBag()->add($container->getParameterBag()->all());

        if ($this->trackResources) {
            foreach ($container->getResources() as $resource) {
                $this->addResource($resource);
            }
        }

        foreach ($this->extensions as $name => $extension) {
            if (!isset($this->extensionConfigs[$name])) {
                $this->extensionConfigs[$name] = [];
            }

            $this->extensionConfigs[$name] = array_merge($this->extensionConfigs[$name], $container->getExtensionConfig($name));
        }

        if ($this->getParameterBag() instanceof EnvPlaceholderParameterBag && $container->getParameterBag() instanceof EnvPlaceholderParameterBag) {
            $envPlaceholders = $container->getParameterBag()->getEnvPlaceholders();
            $this->getParameterBag()->mergeEnvPlaceholders($container->getParameterBag());
        } else {
            $envPlaceholders = [];
        }

        foreach ($container->envCounters as $env => $count) {
            if (!$count && !isset($envPlaceholders[$env])) {
                continue;
            }
            if (!isset($this->envCounters[$env])) {
                $this->envCounters[$env] = $count;
            } else {
                $this->envCounters[$env] += $count;
            }
        }

        foreach ($container->getAutoconfiguredInstanceof() as $interface => $childDefinition) {
            if (isset($this->autoconfiguredInstanceof[$interface])) {
                throw new InvalidArgumentException(sprintf('"%s" has already been autoconfigured and merge() does not support merging autoconfiguration for the same class/interface.', $interface));
            }

            $this->autoconfiguredInstanceof[$interface] = $childDefinition;
        }
    }

    /**
     * Returns the configuration array for the given extension.
     *
     * @return array An array of configuration
     */
    public function getExtensionConfig(string $name)
    {
        if (!isset($this->extensionConfigs[$name])) {
            $this->extensionConfigs[$name] = [];
        }

        return $this->extensionConfigs[$name];
    }

    /**
     * Prepends a config array to the configs of the given extension.
     */
    public function prependExtensionConfig(string $name, array $config)
    {
        if (!isset($this->extensionConfigs[$name])) {
            $this->extensionConfigs[$name] = [];
        }

        array_unshift($this->extensionConfigs[$name], $config);
    }

    /**
     * Compiles the container.
     *
     * This method passes the container to compiler
     * passes whose job is to manipulate and optimize
     * the container.
     *
     * The main compiler passes roughly do four things:
     *
     *  * The extension configurations are merged;
     *  * Parameter values are resolved;
     *  * The parameter bag is frozen;
     *  * Extension loading is disabled.
     *
     * @param bool $resolveEnvPlaceholders Whether %env()% parameters should be resolved using the current
     *                                     env vars or be replaced by uniquely identifiable placeholders.
     *                                     Set to "true" when you want to use the current ContainerBuilder
     *                                     directly, keep to "false" when the container is dumped instead.
     */
    public function compile(bool $resolveEnvPlaceholders = false)
    {
        $compiler = $this->getCompiler();

        if ($this->trackResources) {
            foreach ($compiler->getPassConfig()->getPasses() as $pass) {
                $this->addObjectResource($pass);
            }
        }
        $bag = $this->getParameterBag();

        if ($resolveEnvPlaceholders && $bag instanceof EnvPlaceholderParameterBag) {
            $compiler->addPass(new ResolveEnvPlaceholdersPass(), PassConfig::TYPE_AFTER_REMOVING, -1000);
        }

        $compiler->compile($this);

        foreach ($this->definitions as $id => $definition) {
            if ($this->trackResources && $definition->isLazy()) {
                $this->getReflectionClass($definition->getClass());
            }
        }

        $this->extensionConfigs = [];

        if ($bag instanceof EnvPlaceholderParameterBag) {
            if ($resolveEnvPlaceholders) {
                $this->parameterBag = new ParameterBag($this->resolveEnvPlaceholders($bag->all(), true));
            }

            $this->envPlaceholders = $bag->getEnvPlaceholders();
        }

        parent::compile();

        foreach ($this->definitions + $this->aliasDefinitions as $id => $definition) {
            if (!$definition->isPublic() || $definition->isPrivate()) {
                $this->removedIds[$id] = true;
            }
        }
    }

    /**
     * {@inheritdoc}
     */
    public function getServiceIds()
    {
        return array_map('strval', array_unique(array_merge(array_keys($this->getDefinitions()), array_keys($this->aliasDefinitions), parent::getServiceIds())));
    }

    /**
     * Gets removed service or alias ids.
     *
     * @return array
     */
    public function getRemovedIds()
    {
        return $this->removedIds;
    }

    /**
     * Adds the service aliases.
     */
    public function addAliases(array $aliases)
    {
        foreach ($aliases as $alias => $id) {
            $this->setAlias($alias, $id);
        }
    }

    /**
     * Sets the service aliases.
     */
    public function setAliases(array $aliases)
    {
        $this->aliasDefinitions = [];
        $this->addAliases($aliases);
    }

    /**
     * Sets an alias for an existing service.
     *
     * @param string       $alias The alias to create
     * @param string|Alias $id    The service to alias
     *
     * @return Alias
     *
     * @throws InvalidArgumentException if the id is not a string or an Alias
     * @throws InvalidArgumentException if the alias is for itself
     */
    public function setAlias(string $alias, $id)
    {
        if ('' === $alias || '\\' === $alias[-1] || \strlen($alias) !== strcspn($alias, "\0\r\n'")) {
            throw new InvalidArgumentException(sprintf('Invalid alias id: "%s".', $alias));
        }

        if (\is_string($id)) {
            $id = new Alias($id);
        } elseif (!$id instanceof Alias) {
            throw new InvalidArgumentException('$id must be a string, or an Alias object.');
        }

        if ($alias === (string) $id) {
            throw new InvalidArgumentException(sprintf('An alias can not reference itself, got a circular reference on "%s".', $alias));
        }

        unset($this->definitions[$alias], $this->removedIds[$alias]);

        return $this->aliasDefinitions[$alias] = $id;
    }

    /**
     * Removes an alias.
     *
     * @param string $alias The alias to remove
     */
    public function removeAlias(string $alias)
    {
        if (isset($this->aliasDefinitions[$alias])) {
            unset($this->aliasDefinitions[$alias]);
            $this->removedIds[$alias] = true;
        }
    }

    /**
     * Returns true if an alias exists under the given identifier.
     *
     * @return bool true if the alias exists, false otherwise
     */
    public function hasAlias(string $id)
    {
        return isset($this->aliasDefinitions[$id]);
    }

    /**
     * Gets all defined aliases.
     *
     * @return Alias[] An array of aliases
     */
    public function getAliases()
    {
        return $this->aliasDefinitions;
    }

    /**
     * Gets an alias.
     *
     * @return Alias An Alias instance
     *
     * @throws InvalidArgumentException if the alias does not exist
     */
    public function getAlias(string $id)
    {
        if (!isset($this->aliasDefinitions[$id])) {
            throw new InvalidArgumentException(sprintf('The service alias "%s" does not exist.', $id));
        }

        return $this->aliasDefinitions[$id];
    }

    /**
     * Registers a service definition.
     *
     * This methods allows for simple registration of service definition
     * with a fluid interface.
     *
     * @return Definition A Definition instance
     */
    public function register(string $id, string $class = null)
    {
        return $this->setDefinition($id, new Definition($class));
    }

    /**
     * Registers an autowired service definition.
     *
     * This method implements a shortcut for using setDefinition() with
     * an autowired definition.
     *
     * @return Definition The created definition
     */
    public function autowire(string $id, string $class = null)
    {
        return $this->setDefinition($id, (new Definition($class))->setAutowired(true));
    }

    /**
     * Adds the service definitions.
     *
     * @param Definition[] $definitions An array of service definitions
     */
    public function addDefinitions(array $definitions)
    {
        foreach ($definitions as $id => $definition) {
            $this->setDefinition($id, $definition);
        }
    }

    /**
     * Sets the service definitions.
     *
     * @param Definition[] $definitions An array of service definitions
     */
    public function setDefinitions(array $definitions)
    {
        $this->definitions = [];
        $this->addDefinitions($definitions);
    }

    /**
     * Gets all service definitions.
     *
     * @return Definition[] An array of Definition instances
     */
    public function getDefinitions()
    {
        return $this->definitions;
    }

    /**
     * Sets a service definition.
     *
     * @return Definition the service definition
     *
     * @throws BadMethodCallException When this ContainerBuilder is compiled
     */
    public function setDefinition(string $id, Definition $definition)
    {
        if ($this->isCompiled()) {
            throw new BadMethodCallException('Adding definition to a compiled container is not allowed.');
        }

        if ('' === $id || '\\' === $id[-1] || \strlen($id) !== strcspn($id, "\0\r\n'")) {
            throw new InvalidArgumentException(sprintf('Invalid service id: "%s".', $id));
        }

        unset($this->aliasDefinitions[$id], $this->removedIds[$id]);

        return $this->definitions[$id] = $definition;
    }

    /**
     * Returns true if a service definition exists under the given identifier.
     *
     * @return bool true if the service definition exists, false otherwise
     */
    public function hasDefinition(string $id)
    {
        return isset($this->definitions[$id]);
    }

    /**
     * Gets a service definition.
     *
     * @return Definition A Definition instance
     *
     * @throws ServiceNotFoundException if the service definition does not exist
     */
    public function getDefinition(string $id)
    {
        if (!isset($this->definitions[$id])) {
            throw new ServiceNotFoundException($id);
        }

        return $this->definitions[$id];
    }

    /**
     * Gets a service definition by id or alias.
     *
     * The method "unaliases" recursively to return a Definition instance.
     *
     * @return Definition A Definition instance
     *
     * @throws ServiceNotFoundException if the service definition does not exist
     */
    public function findDefinition(string $id)
    {
        $seen = [];
        while (isset($this->aliasDefinitions[$id])) {
            $id = (string) $this->aliasDefinitions[$id];

            if (isset($seen[$id])) {
                $seen = array_values($seen);
                $seen = \array_slice($seen, array_search($id, $seen));
                $seen[] = $id;

                throw new ServiceCircularReferenceException($id, $seen);
            }

            $seen[$id] = $id;
        }

        return $this->getDefinition($id);
    }

    /**
     * Creates a service for a service definition.
     *
     * @return mixed The service described by the service definition
     *
     * @throws RuntimeException         When the factory definition is incomplete
     * @throws RuntimeException         When the service is a synthetic service
     * @throws InvalidArgumentException When configure callable is not callable
     */
    private function createService(Definition $definition, array &$inlineServices, bool $isConstructorArgument = false, string $id = null, bool $tryProxy = true)
    {
        if (null === $id && isset($inlineServices[$h = spl_object_hash($definition)])) {
            return $inlineServices[$h];
        }

        if ($definition instanceof ChildDefinition) {
            throw new RuntimeException(sprintf('Constructing service "%s" from a parent definition is not supported at build time.', $id));
        }

        if ($definition->isSynthetic()) {
            throw new RuntimeException(sprintf('You have requested a synthetic service ("%s"). The DIC does not know how to construct this service.', $id));
        }

        if ($definition->isDeprecated()) {
            $deprecation = $definition->getDeprecation($id);
            trigger_deprecation($deprecation['package'], $deprecation['version'], $deprecation['message']);
        }

        if ($tryProxy && $definition->isLazy() && !$tryProxy = !($proxy = $this->proxyInstantiator) || $proxy instanceof RealServiceInstantiator) {
            $proxy = $proxy->instantiateProxy(
                $this,
                $definition,
                $id, function () use ($definition, &$inlineServices, $id) {
                    return $this->createService($definition, $inlineServices, true, $id, false);
                }
            );
            $this->shareService($definition, $proxy, $id, $inlineServices);

            return $proxy;
        }

        $parameterBag = $this->getParameterBag();

        if (null !== $definition->getFile()) {
            require_once $parameterBag->resolveValue($definition->getFile());
        }

        $arguments = $this->doResolveServices($parameterBag->unescapeValue($parameterBag->resolveValue($definition->getArguments())), $inlineServices, $isConstructorArgument);

        if (null !== $factory = $definition->getFactory()) {
            if (\is_array($factory)) {
                $factory = [$this->doResolveServices($parameterBag->resolveValue($factory[0]), $inlineServices, $isConstructorArgument), $factory[1]];
            } elseif (!\is_string($factory)) {
                throw new RuntimeException(sprintf('Cannot create service "%s" because of invalid factory.', $id));
            }
        }

        if (null !== $id && $definition->isShared() && isset($this->services[$id]) && ($tryProxy || !$definition->isLazy())) {
            return $this->services[$id];
        }

        if (null !== $factory) {
            $service = $factory(...$arguments);

            if (!$definition->isDeprecated() && \is_array($factory) && \is_string($factory[0])) {
                $r = new \ReflectionClass($factory[0]);

                if (0 < strpos($r->getDocComment(), "\n * @deprecated ")) {
                    trigger_deprecation('', '', 'The "%s" service relies on the deprecated "%s" factory class. It should either be deprecated or its factory upgraded.', $id, $r->name);
                }
            }
        } else {
            $r = new \ReflectionClass($parameterBag->resolveValue($definition->getClass()));

            $service = null === $r->getConstructor() ? $r->newInstance() : $r->newInstanceArgs(array_values($arguments));

            if (!$definition->isDeprecated() && 0 < strpos($r->getDocComment(), "\n * @deprecated ")) {
                trigger_deprecation('', '', 'The "%s" service relies on the deprecated "%s" class. It should either be deprecated or its implementation upgraded.', $id, $r->name);
            }
        }

        $lastWitherIndex = null;
        foreach ($definition->getMethodCalls() as $k => $call) {
            if ($call[2] ?? false) {
                $lastWitherIndex = $k;
            }
        }

        if (null === $lastWitherIndex && ($tryProxy || !$definition->isLazy())) {
            // share only if proxying failed, or if not a proxy, and if no withers are found
            $this->shareService($definition, $service, $id, $inlineServices);
        }

        $properties = $this->doResolveServices($parameterBag->unescapeValue($parameterBag->resolveValue($definition->getProperties())), $inlineServices);
        foreach ($properties as $name => $value) {
            $service->$name = $value;
        }

        foreach ($definition->getMethodCalls() as $k => $call) {
            $service = $this->callMethod($service, $call, $inlineServices);

            if ($lastWitherIndex === $k && ($tryProxy || !$definition->isLazy())) {
                // share only if proxying failed, or if not a proxy, and this is the last wither
                $this->shareService($definition, $service, $id, $inlineServices);
            }
        }

        if ($callable = $definition->getConfigurator()) {
            if (\is_array($callable)) {
                $callable[0] = $parameterBag->resolveValue($callable[0]);

                if ($callable[0] instanceof Reference) {
                    $callable[0] = $this->doGet((string) $callable[0], $callable[0]->getInvalidBehavior(), $inlineServices);
                } elseif ($callable[0] instanceof Definition) {
                    $callable[0] = $this->createService($callable[0], $inlineServices);
                }
            }

            if (!\is_callable($callable)) {
                throw new InvalidArgumentException(sprintf('The configure callable for class "%s" is not a callable.', get_debug_type($service)));
            }

            $callable($service);
        }

        return $service;
    }

    /**
     * Replaces service references by the real service instance and evaluates expressions.
     *
     * @param mixed $value A value
     *
     * @return mixed The same value with all service references replaced by
     *               the real service instances and all expressions evaluated
     */
    public function resolveServices($value)
    {
        return $this->doResolveServices($value);
    }

    private function doResolveServices($value, array &$inlineServices = [], bool $isConstructorArgument = false)
    {
        if (\is_array($value)) {
            foreach ($value as $k => $v) {
                $value[$k] = $this->doResolveServices($v, $inlineServices, $isConstructorArgument);
            }
        } elseif ($value instanceof ServiceClosureArgument) {
            $reference = $value->getValues()[0];
            $value = function () use ($reference) {
                return $this->resolveServices($reference);
            };
        } elseif ($value instanceof IteratorArgument) {
            $value = new RewindableGenerator(function () use ($value) {
                foreach ($value->getValues() as $k => $v) {
                    foreach (self::getServiceConditionals($v) as $s) {
                        if (!$this->has($s)) {
                            continue 2;
                        }
                    }
                    foreach (self::getInitializedConditionals($v) as $s) {
                        if (!$this->doGet($s, ContainerInterface::IGNORE_ON_UNINITIALIZED_REFERENCE)) {
                            continue 2;
                        }
                    }

                    yield $k => $this->resolveServices($v);
                }
            }, function () use ($value): int {
                $count = 0;
                foreach ($value->getValues() as $v) {
                    foreach (self::getServiceConditionals($v) as $s) {
                        if (!$this->has($s)) {
                            continue 2;
                        }
                    }
                    foreach (self::getInitializedConditionals($v) as $s) {
                        if (!$this->doGet($s, ContainerInterface::IGNORE_ON_UNINITIALIZED_REFERENCE)) {
                            continue 2;
                        }
                    }

                    ++$count;
                }

                return $count;
            });
        } elseif ($value instanceof ServiceLocatorArgument) {
            $refs = $types = [];
            foreach ($value->getValues() as $k => $v) {
                if ($v) {
                    $refs[$k] = [$v];
                    $types[$k] = $v instanceof TypedReference ? $v->getType() : '?';
                }
            }
            $value = new ServiceLocator(\Closure::fromCallable([$this, 'resolveServices']), $refs, $types);
        } elseif ($value instanceof Reference) {
            $value = $this->doGet((string) $value, $value->getInvalidBehavior(), $inlineServices, $isConstructorArgument);
        } elseif ($value instanceof Definition) {
            $value = $this->createService($value, $inlineServices, $isConstructorArgument);
        } elseif ($value instanceof Parameter) {
            $value = $this->getParameter((string) $value);
        } elseif ($value instanceof Expression) {
            $value = $this->getExpressionLanguage()->evaluate($value, ['container' => $this]);
        } elseif ($value instanceof AbstractArgument) {
            throw new RuntimeException($value->getTextWithContext());
        }

        return $value;
    }

    /**
     * Returns service ids for a given tag.
     *
     * Example:
     *
     *     $container->register('foo')->addTag('my.tag', ['hello' => 'world']);
     *
     *     $serviceIds = $container->findTaggedServiceIds('my.tag');
     *     foreach ($serviceIds as $serviceId => $tags) {
     *         foreach ($tags as $tag) {
     *             echo $tag['hello'];
     *         }
     *     }
     *
     * @return array An array of tags with the tagged service as key, holding a list of attribute arrays
     */
    public function findTaggedServiceIds(string $name, bool $throwOnAbstract = false)
    {
        $this->usedTags[] = $name;
        $tags = [];
        foreach ($this->getDefinitions() as $id => $definition) {
            if ($definition->hasTag($name)) {
                if ($throwOnAbstract && $definition->isAbstract()) {
                    throw new InvalidArgumentException(sprintf('The service "%s" tagged "%s" must not be abstract.', $id, $name));
                }
                $tags[$id] = $definition->getTag($name);
            }
        }

        return $tags;
    }

    /**
     * Returns all tags the defined services use.
     *
     * @return array An array of tags
     */
    public function findTags()
    {
        $tags = [];
        foreach ($this->getDefinitions() as $id => $definition) {
            $tags = array_merge(array_keys($definition->getTags()), $tags);
        }

        return array_unique($tags);
    }

    /**
     * Returns all tags not queried by findTaggedServiceIds.
     *
     * @return string[] An array of tags
     */
    public function findUnusedTags()
    {
        return array_values(array_diff($this->findTags(), $this->usedTags));
    }

    public function addExpressionLanguageProvider(ExpressionFunctionProviderInterface $provider)
    {
        $this->expressionLanguageProviders[] = $provider;
    }

    /**
     * @return ExpressionFunctionProviderInterface[]
     */
    public function getExpressionLanguageProviders()
    {
        return $this->expressionLanguageProviders;
    }

    /**
     * Returns a ChildDefinition that will be used for autoconfiguring the interface/class.
     *
     * @return ChildDefinition
     */
    public function registerForAutoconfiguration(string $interface)
    {
        if (!isset($this->autoconfiguredInstanceof[$interface])) {
            $this->autoconfiguredInstanceof[$interface] = new ChildDefinition('');
        }

        return $this->autoconfiguredInstanceof[$interface];
    }

    /**
     * Registers an autowiring alias that only binds to a specific argument name.
     *
     * The argument name is derived from $name if provided (from $id otherwise)
     * using camel case: "foo.bar" or "foo_bar" creates an alias bound to
     * "$fooBar"-named arguments with $type as type-hint. Such arguments will
     * receive the service $id when autowiring is used.
     */
    public function registerAliasForArgument(string $id, string $type, string $name = null): Alias
    {
        $name = lcfirst(str_replace(' ', '', ucwords(preg_replace('/[^a-zA-Z0-9\x7f-\xff]++/', ' ', $name ?? $id))));

        if (!preg_match('/^[a-zA-Z_\x7f-\xff]/', $name)) {
            throw new InvalidArgumentException(sprintf('Invalid argument name "%s" for service "%s": the first character must be a letter.', $name, $id));
        }

        return $this->setAlias($type.' $'.$name, $id);
    }

    /**
     * Returns an array of ChildDefinition[] keyed by interface.
     *
     * @return ChildDefinition[]
     */
    public function getAutoconfiguredInstanceof()
    {
        return $this->autoconfiguredInstanceof;
    }

    /**
     * Resolves env parameter placeholders in a string or an array.
     *
     * @param mixed            $value     The value to resolve
     * @param string|true|null $format    A sprintf() format returning the replacement for each env var name or
     *                                    null to resolve back to the original "%env(VAR)%" format or
     *                                    true to resolve to the actual values of the referenced env vars
     * @param array            &$usedEnvs Env vars found while resolving are added to this array
     *
     * @return mixed The value with env parameters resolved if a string or an array is passed
     */
    public function resolveEnvPlaceholders($value, $format = null, array &$usedEnvs = null)
    {
        if (null === $format) {
            $format = '%%env(%s)%%';
        }

        $bag = $this->getParameterBag();
        if (true === $format) {
            $value = $bag->resolveValue($value);
        }

        if ($value instanceof Definition) {
            $value = (array) $value;
        }

        if (\is_array($value)) {
            $result = [];
            foreach ($value as $k => $v) {
                $result[\is_string($k) ? $this->resolveEnvPlaceholders($k, $format, $usedEnvs) : $k] = $this->resolveEnvPlaceholders($v, $format, $usedEnvs);
            }

            return $result;
        }

        if (!\is_string($value) || 38 > \strlen($value)) {
            return $value;
        }
        $envPlaceholders = $bag instanceof EnvPlaceholderParameterBag ? $bag->getEnvPlaceholders() : $this->envPlaceholders;

        $completed = false;
        foreach ($envPlaceholders as $env => $placeholders) {
            foreach ($placeholders as $placeholder) {
                if (false !== stripos($value, $placeholder)) {
                    if (true === $format) {
                        $resolved = $bag->escapeValue($this->getEnv($env));
                    } else {
                        $resolved = sprintf($format, $env);
                    }
                    if ($placeholder === $value) {
                        $value = $resolved;
                        $completed = true;
                    } else {
                        if (!\is_string($resolved) && !is_numeric($resolved)) {
                            throw new RuntimeException(sprintf('A string value must be composed of strings and/or numbers, but found parameter "env(%s)" of type "%s" inside string value "%s".', $env, get_debug_type($resolved), $this->resolveEnvPlaceholders($value)));
                        }
                        $value = str_ireplace($placeholder, $resolved, $value);
                    }
                    $usedEnvs[$env] = $env;
                    $this->envCounters[$env] = isset($this->envCounters[$env]) ? 1 + $this->envCounters[$env] : 1;

                    if ($completed) {
                        break 2;
                    }
                }
            }
        }

        return $value;
    }

    /**
     * Get statistics about env usage.
     *
     * @return int[] The number of time each env vars has been resolved
     */
    public function getEnvCounters()
    {
        $bag = $this->getParameterBag();
        $envPlaceholders = $bag instanceof EnvPlaceholderParameterBag ? $bag->getEnvPlaceholders() : $this->envPlaceholders;

        foreach ($envPlaceholders as $env => $placeholders) {
            if (!isset($this->envCounters[$env])) {
                $this->envCounters[$env] = 0;
            }
        }

        return $this->envCounters;
    }

    /**
     * @final
     */
    public function log(CompilerPassInterface $pass, string $message)
    {
        $this->getCompiler()->log($pass, $this->resolveEnvPlaceholders($message));
    }

    /**
     * Gets removed binding ids.
     *
     * @internal
     */
    public function getRemovedBindingIds(): array
    {
        return $this->removedBindingIds;
    }

    /**
     * Removes bindings for a service.
     *
     * @internal
     */
    public function removeBindings(string $id)
    {
        if ($this->hasDefinition($id)) {
            foreach ($this->getDefinition($id)->getBindings() as $key => $binding) {
                list(, $bindingId) = $binding->getValues();
                $this->removedBindingIds[(int) $bindingId] = true;
            }
        }
    }

    /**
     * Returns the Service Conditionals.
     *
     * @param mixed $value An array of conditionals to return
     *
     * @internal
     */
    public static function getServiceConditionals($value): array
    {
        $services = [];

        if (\is_array($value)) {
            foreach ($value as $v) {
                $services = array_unique(array_merge($services, self::getServiceConditionals($v)));
            }
        } elseif ($value instanceof Reference && ContainerInterface::IGNORE_ON_INVALID_REFERENCE === $value->getInvalidBehavior()) {
            $services[] = (string) $value;
        }

        return $services;
    }

    /**
     * Returns the initialized conditionals.
     *
     * @param mixed $value An array of conditionals to return
     *
     * @internal
     */
    public static function getInitializedConditionals($value): array
    {
        $services = [];

        if (\is_array($value)) {
            foreach ($value as $v) {
                $services = array_unique(array_merge($services, self::getInitializedConditionals($v)));
            }
        } elseif ($value instanceof Reference && ContainerInterface::IGNORE_ON_UNINITIALIZED_REFERENCE === $value->getInvalidBehavior()) {
            $services[] = (string) $value;
        }

        return $services;
    }

    /**
     * Computes a reasonably unique hash of a value.
     *
     * @param mixed $value A serializable value
     *
     * @return string
     */
    public static function hash($value)
    {
        $hash = substr(base64_encode(hash('sha256', serialize($value), true)), 0, 7);

        return str_replace(['/', '+'], ['.', '_'], $hash);
    }

    /**
     * {@inheritdoc}
     */
    protected function getEnv($name)
    {
        $value = parent::getEnv($name);
        $bag = $this->getParameterBag();

        if (!\is_string($value) || !$bag instanceof EnvPlaceholderParameterBag) {
            return $value;
        }

        $envPlaceholders = $bag->getEnvPlaceholders();
        if (isset($envPlaceholders[$name][$value])) {
            $bag = new ParameterBag($bag->all());

            return $bag->unescapeValue($bag->get("env($name)"));
        }
        foreach ($envPlaceholders as $env => $placeholders) {
            if (isset($placeholders[$value])) {
                return $this->getEnv($env);
            }
        }

        $this->resolving["env($name)"] = true;
        try {
            return $bag->unescapeValue($this->resolveEnvPlaceholders($bag->escapeValue($value), true));
        } finally {
            unset($this->resolving["env($name)"]);
        }
    }

    private function callMethod($service, array $call, array &$inlineServices)
    {
        foreach (self::getServiceConditionals($call[1]) as $s) {
            if (!$this->has($s)) {
                return $service;
            }
        }
        foreach (self::getInitializedConditionals($call[1]) as $s) {
            if (!$this->doGet($s, ContainerInterface::IGNORE_ON_UNINITIALIZED_REFERENCE, $inlineServices)) {
                return $service;
            }
        }

        $result = $service->{$call[0]}(...$this->doResolveServices($this->getParameterBag()->unescapeValue($this->getParameterBag()->resolveValue($call[1])), $inlineServices));

        return empty($call[2]) ? $service : $result;
    }

    /**
     * Shares a given service in the container.
     *
     * @param mixed $service
     */
    private function shareService(Definition $definition, $service, ?string $id, array &$inlineServices)
    {
        $inlineServices[null !== $id ? $id : spl_object_hash($definition)] = $service;

        if (null !== $id && $definition->isShared()) {
            $this->services[$id] = $service;
            unset($this->loading[$id]);
        }
    }

    private function getExpressionLanguage(): ExpressionLanguage
    {
        if (null === $this->expressionLanguage) {
            if (!class_exists('Symfony\Component\ExpressionLanguage\ExpressionLanguage')) {
                throw new LogicException('Unable to use expressions as the Symfony ExpressionLanguage component is not installed.');
            }
            $this->expressionLanguage = new ExpressionLanguage(null, $this->expressionLanguageProviders);
        }

        return $this->expressionLanguage;
    }

    private function inVendors(string $path): bool
    {
        if (null === $this->vendors) {
            $resource = new ComposerResource();
            $this->vendors = $resource->getVendors();
            $this->addResource($resource);
        }
        $path = realpath($path) ?: $path;

        foreach ($this->vendors as $vendor) {
            if (0 === strpos($path, $vendor) && false !== strpbrk(substr($path, \strlen($vendor), 1), '/'.\DIRECTORY_SEPARATOR)) {
                return true;
            }
        }

        return false;
    }
}
PKϤ$ZL�EY,dependency-injection/DefinitionDecorator.phpnu�[���<?php

/*
 * This file is part of the Symfony package.
 *
 * (c) Fabien Potencier <fabien@symfony.com>
 *
 * For the full copyright and license information, please view the LICENSE
 * file that was distributed with this source code.
 */

namespace Symfony\Component\DependencyInjection;

use Symfony\Component\DependencyInjection\Exception\InvalidArgumentException;
use Symfony\Component\DependencyInjection\Exception\OutOfBoundsException;

/**
 * This definition decorates another definition.
 *
 * @author Johannes M. Schmitt <schmittjoh@gmail.com>
 */
class DefinitionDecorator extends Definition
{
    private $parent;
    private $changes = array();

    /**
     * @param string $parent The id of Definition instance to decorate
     */
    public function __construct($parent)
    {
        parent::__construct();

        $this->parent = $parent;
    }

    /**
     * Returns the Definition being decorated.
     *
     * @return string
     */
    public function getParent()
    {
        return $this->parent;
    }

    /**
     * Returns all changes tracked for the Definition object.
     *
     * @return array An array of changes for this Definition
     */
    public function getChanges()
    {
        return $this->changes;
    }

    /**
     * {@inheritdoc}
     */
    public function setClass($class)
    {
        $this->changes['class'] = true;

        return parent::setClass($class);
    }

    /**
     * {@inheritdoc}
     */
    public function setFactory($callable)
    {
        $this->changes['factory'] = true;

        return parent::setFactory($callable);
    }

    /**
     * {@inheritdoc}
     */
    public function setConfigurator($callable)
    {
        $this->changes['configurator'] = true;

        return parent::setConfigurator($callable);
    }

    /**
     * {@inheritdoc}
     */
    public function setFile($file)
    {
        $this->changes['file'] = true;

        return parent::setFile($file);
    }

    /**
     * {@inheritdoc}
     */
    public function setPublic($boolean)
    {
        $this->changes['public'] = true;

        return parent::setPublic($boolean);
    }

    /**
     * {@inheritdoc}
     */
    public function setLazy($boolean)
    {
        $this->changes['lazy'] = true;

        return parent::setLazy($boolean);
    }

    /**
     * {@inheritdoc}
     */
    public function setDecoratedService($id, $renamedId = null, $priority = 0)
    {
        $this->changes['decorated_service'] = true;

        return parent::setDecoratedService($id, $renamedId, $priority);
    }

    /**
     * {@inheritdoc}
     */
    public function setDeprecated($boolean = true, $template = null)
    {
        $this->changes['deprecated'] = true;

        return parent::setDeprecated($boolean, $template);
    }

    /**
     * {@inheritdoc}
     */
    public function setAutowired($autowired)
    {
        $this->changes['autowire'] = true;

        return parent::setAutowired($autowired);
    }

    /**
     * Gets an argument to pass to the service constructor/factory method.
     *
     * If replaceArgument() has been used to replace an argument, this method
     * will return the replacement value.
     *
     * @param int $index
     *
     * @return mixed The argument value
     *
     * @throws OutOfBoundsException When the argument does not exist
     */
    public function getArgument($index)
    {
        if (array_key_exists('index_'.$index, $this->arguments)) {
            return $this->arguments['index_'.$index];
        }

        $lastIndex = count(array_filter(array_keys($this->arguments), 'is_int')) - 1;

        if ($index < 0 || $index > $lastIndex) {
            throw new OutOfBoundsException(sprintf('The index "%d" is not in the range [0, %d].', $index, $lastIndex));
        }

        return $this->arguments[$index];
    }

    /**
     * You should always use this method when overwriting existing arguments
     * of the parent definition.
     *
     * If you directly call setArguments() keep in mind that you must follow
     * certain conventions when you want to overwrite the arguments of the
     * parent definition, otherwise your arguments will only be appended.
     *
     * @param int   $index
     * @param mixed $value
     *
     * @return $this
     *
     * @throws InvalidArgumentException when $index isn't an integer
     */
    public function replaceArgument($index, $value)
    {
        if (!is_int($index)) {
            throw new InvalidArgumentException('$index must be an integer.');
        }

        $this->arguments['index_'.$index] = $value;

        return $this;
    }
}
PKϤ$Z��c���polyfill-iconv/README.mdnu�[���Symfony Polyfill / Iconv
========================

This component provides a native PHP implementation of the
[php.net/iconv](https://php.net/iconv) functions
(short of [`ob_iconv_handler`](https://php.net/ob-iconv-handler)).

More information can be found in the
[main Polyfill README](https://github.com/symfony/polyfill/blob/master/README.md).

License
=======

This library is released under the [MIT license](LICENSE).
PKϤ$Z�b|��/polyfill-iconv/Resources/charset/from.cp855.phpnu�[���<?php

static $data = array (
  '' => '',
  '' => '',
  '' => '',
  '' => '',
  '' => '',
  '' => '',
  '' => '',
  '' => '',
  '' => '',
  '	' => '	',
  '
' => '
',
  '' => '',
  '' => '',
  '
' => '
',
  '' => '',
  '' => '',
  '' => '',
  '' => '',
  '' => '',
  '' => '',
  '' => '',
  '' => '',
  '' => '',
  '' => '',
  '' => '',
  '' => '',
  '' => '',
  '' => '',
  '' => '',
  '' => '',
  '' => '',
  '' => '',
  ' ' => ' ',
  '!' => '!',
  '"' => '"',
  '#' => '#',
  '$' => '$',
  '%' => '%',
  '&' => '&',
  '\'' => '\'',
  '(' => '(',
  ')' => ')',
  '*' => '*',
  '+' => '+',
  ',' => ',',
  '-' => '-',
  '.' => '.',
  '/' => '/',
  0 => '0',
  1 => '1',
  2 => '2',
  3 => '3',
  4 => '4',
  5 => '5',
  6 => '6',
  7 => '7',
  8 => '8',
  9 => '9',
  ':' => ':',
  ';' => ';',
  '<' => '<',
  '=' => '=',
  '>' => '>',
  '?' => '?',
  '@' => '@',
  'A' => 'A',
  'B' => 'B',
  'C' => 'C',
  'D' => 'D',
  'E' => 'E',
  'F' => 'F',
  'G' => 'G',
  'H' => 'H',
  'I' => 'I',
  'J' => 'J',
  'K' => 'K',
  'L' => 'L',
  'M' => 'M',
  'N' => 'N',
  'O' => 'O',
  'P' => 'P',
  'Q' => 'Q',
  'R' => 'R',
  'S' => 'S',
  'T' => 'T',
  'U' => 'U',
  'V' => 'V',
  'W' => 'W',
  'X' => 'X',
  'Y' => 'Y',
  'Z' => 'Z',
  '[' => '[',
  '\\' => '\\',
  ']' => ']',
  '^' => '^',
  '_' => '_',
  '`' => '`',
  'a' => 'a',
  'b' => 'b',
  'c' => 'c',
  'd' => 'd',
  'e' => 'e',
  'f' => 'f',
  'g' => 'g',
  'h' => 'h',
  'i' => 'i',
  'j' => 'j',
  'k' => 'k',
  'l' => 'l',
  'm' => 'm',
  'n' => 'n',
  'o' => 'o',
  'p' => 'p',
  'q' => 'q',
  'r' => 'r',
  's' => 's',
  't' => 't',
  'u' => 'u',
  'v' => 'v',
  'w' => 'w',
  'x' => 'x',
  'y' => 'y',
  'z' => 'z',
  '{' => '{',
  '|' => '|',
  '}' => '}',
  '~' => '~',
  '' => '',
  '�' => 'ђ',
  '�' => 'Ђ',
  '�' => 'ѓ',
  '�' => 'Ѓ',
  '�' => 'ё',
  '�' => 'Ё',
  '�' => 'є',
  '�' => 'Є',
  '�' => 'ѕ',
  '�' => 'Ѕ',
  '�' => 'і',
  '�' => 'І',
  '�' => 'ї',
  '�' => 'Ї',
  '�' => 'ј',
  '�' => 'Ј',
  '�' => 'љ',
  '�' => 'Љ',
  '�' => 'њ',
  '�' => 'Њ',
  '�' => 'ћ',
  '�' => 'Ћ',
  '�' => 'ќ',
  '�' => 'Ќ',
  '�' => 'ў',
  '�' => 'Ў',
  '�' => 'џ',
  '�' => 'Џ',
  '�' => 'ю',
  '�' => 'Ю',
  '�' => 'ъ',
  '�' => 'Ъ',
  '�' => 'а',
  '�' => 'А',
  '�' => 'б',
  '�' => 'Б',
  '�' => 'ц',
  '�' => 'Ц',
  '�' => 'д',
  '�' => 'Д',
  '�' => 'е',
  '�' => 'Е',
  '�' => 'ф',
  '�' => 'Ф',
  '�' => 'г',
  '�' => 'Г',
  '�' => '«',
  '�' => '»',
  '�' => '░',
  '�' => '▒',
  '�' => '▓',
  '�' => '│',
  '�' => '┤',
  '�' => 'х',
  '�' => 'Х',
  '�' => 'и',
  '�' => 'И',
  '�' => '╣',
  '�' => '║',
  '�' => '╗',
  '�' => '╝',
  '�' => 'й',
  '�' => 'Й',
  '�' => '┐',
  '�' => '└',
  '�' => '┴',
  '�' => '┬',
  '�' => '├',
  '�' => '─',
  '�' => '┼',
  '�' => 'к',
  '�' => 'К',
  '�' => '╚',
  '�' => '╔',
  '�' => '╩',
  '�' => '╦',
  '�' => '╠',
  '�' => '═',
  '�' => '╬',
  '�' => '¤',
  '�' => 'л',
  '�' => 'Л',
  '�' => 'м',
  '�' => 'М',
  '�' => 'н',
  '�' => 'Н',
  '�' => 'о',
  '�' => 'О',
  '�' => 'п',
  '�' => '┘',
  '�' => '┌',
  '�' => '█',
  '�' => '▄',
  '�' => 'П',
  '�' => 'я',
  '�' => '▀',
  '�' => 'Я',
  '�' => 'р',
  '�' => 'Р',
  '�' => 'с',
  '�' => 'С',
  '�' => 'т',
  '�' => 'Т',
  '�' => 'у',
  '�' => 'У',
  '�' => 'ж',
  '�' => 'Ж',
  '�' => 'в',
  '�' => 'В',
  '�' => 'ь',
  '�' => 'Ь',
  '�' => '№',
  '�' => '­',
  '�' => 'ы',
  '�' => 'Ы',
  '�' => 'з',
  '�' => 'З',
  '�' => 'ш',
  '�' => 'Ш',
  '�' => 'э',
  '�' => 'Э',
  '�' => 'щ',
  '�' => 'Щ',
  '�' => 'ч',
  '�' => 'Ч',
  '�' => '§',
  '�' => '■',
  '�' => ' ',
);

$result =& $data;
unset($data);

return $result;
PKϤ$Z
�����6polyfill-iconv/Resources/charset/from.windows-1250.phpnu�[���<?php

static $data = array (
  '' => '',
  '' => '',
  '' => '',
  '' => '',
  '' => '',
  '' => '',
  '' => '',
  '' => '',
  '' => '',
  '	' => '	',
  '
' => '
',
  '' => '',
  '' => '',
  '
' => '
',
  '' => '',
  '' => '',
  '' => '',
  '' => '',
  '' => '',
  '' => '',
  '' => '',
  '' => '',
  '' => '',
  '' => '',
  '' => '',
  '' => '',
  '' => '',
  '' => '',
  '' => '',
  '' => '',
  '' => '',
  '' => '',
  ' ' => ' ',
  '!' => '!',
  '"' => '"',
  '#' => '#',
  '$' => '$',
  '%' => '%',
  '&' => '&',
  '\'' => '\'',
  '(' => '(',
  ')' => ')',
  '*' => '*',
  '+' => '+',
  ',' => ',',
  '-' => '-',
  '.' => '.',
  '/' => '/',
  0 => '0',
  1 => '1',
  2 => '2',
  3 => '3',
  4 => '4',
  5 => '5',
  6 => '6',
  7 => '7',
  8 => '8',
  9 => '9',
  ':' => ':',
  ';' => ';',
  '<' => '<',
  '=' => '=',
  '>' => '>',
  '?' => '?',
  '@' => '@',
  'A' => 'A',
  'B' => 'B',
  'C' => 'C',
  'D' => 'D',
  'E' => 'E',
  'F' => 'F',
  'G' => 'G',
  'H' => 'H',
  'I' => 'I',
  'J' => 'J',
  'K' => 'K',
  'L' => 'L',
  'M' => 'M',
  'N' => 'N',
  'O' => 'O',
  'P' => 'P',
  'Q' => 'Q',
  'R' => 'R',
  'S' => 'S',
  'T' => 'T',
  'U' => 'U',
  'V' => 'V',
  'W' => 'W',
  'X' => 'X',
  'Y' => 'Y',
  'Z' => 'Z',
  '[' => '[',
  '\\' => '\\',
  ']' => ']',
  '^' => '^',
  '_' => '_',
  '`' => '`',
  'a' => 'a',
  'b' => 'b',
  'c' => 'c',
  'd' => 'd',
  'e' => 'e',
  'f' => 'f',
  'g' => 'g',
  'h' => 'h',
  'i' => 'i',
  'j' => 'j',
  'k' => 'k',
  'l' => 'l',
  'm' => 'm',
  'n' => 'n',
  'o' => 'o',
  'p' => 'p',
  'q' => 'q',
  'r' => 'r',
  's' => 's',
  't' => 't',
  'u' => 'u',
  'v' => 'v',
  'w' => 'w',
  'x' => 'x',
  'y' => 'y',
  'z' => 'z',
  '{' => '{',
  '|' => '|',
  '}' => '}',
  '~' => '~',
  '' => '',
  '�' => '€',
  '�' => '‚',
  '�' => '„',
  '�' => '…',
  '�' => '†',
  '�' => '‡',
  '�' => '‰',
  '�' => 'Š',
  '�' => '‹',
  '�' => 'Ś',
  '�' => 'Ť',
  '�' => 'Ž',
  '�' => 'Ź',
  '�' => '‘',
  '�' => '’',
  '�' => '“',
  '�' => '”',
  '�' => '•',
  '�' => '–',
  '�' => '—',
  '�' => '™',
  '�' => 'š',
  '�' => '›',
  '�' => 'ś',
  '�' => 'ť',
  '�' => 'ž',
  '�' => 'ź',
  '�' => ' ',
  '�' => 'ˇ',
  '�' => '˘',
  '�' => 'Ł',
  '�' => '¤',
  '�' => 'Ą',
  '�' => '¦',
  '�' => '§',
  '�' => '¨',
  '�' => '©',
  '�' => 'Ş',
  '�' => '«',
  '�' => '¬',
  '�' => '­',
  '�' => '®',
  '�' => 'Ż',
  '�' => '°',
  '�' => '±',
  '�' => '˛',
  '�' => 'ł',
  '�' => '´',
  '�' => 'µ',
  '�' => '¶',
  '�' => '·',
  '�' => '¸',
  '�' => 'ą',
  '�' => 'ş',
  '�' => '»',
  '�' => 'Ľ',
  '�' => '˝',
  '�' => 'ľ',
  '�' => 'ż',
  '�' => 'Ŕ',
  '�' => 'Á',
  '�' => 'Â',
  '�' => 'Ă',
  '�' => 'Ä',
  '�' => 'Ĺ',
  '�' => 'Ć',
  '�' => 'Ç',
  '�' => 'Č',
  '�' => 'É',
  '�' => 'Ę',
  '�' => 'Ë',
  '�' => 'Ě',
  '�' => 'Í',
  '�' => 'Î',
  '�' => 'Ď',
  '�' => 'Đ',
  '�' => 'Ń',
  '�' => 'Ň',
  '�' => 'Ó',
  '�' => 'Ô',
  '�' => 'Ő',
  '�' => 'Ö',
  '�' => '×',
  '�' => 'Ř',
  '�' => 'Ů',
  '�' => 'Ú',
  '�' => 'Ű',
  '�' => 'Ü',
  '�' => 'Ý',
  '�' => 'Ţ',
  '�' => 'ß',
  '�' => 'ŕ',
  '�' => 'á',
  '�' => 'â',
  '�' => 'ă',
  '�' => 'ä',
  '�' => 'ĺ',
  '�' => 'ć',
  '�' => 'ç',
  '�' => 'č',
  '�' => 'é',
  '�' => 'ę',
  '�' => 'ë',
  '�' => 'ě',
  '�' => 'í',
  '�' => 'î',
  '�' => 'ď',
  '�' => 'đ',
  '�' => 'ń',
  '�' => 'ň',
  '�' => 'ó',
  '�' => 'ô',
  '�' => 'ő',
  '�' => 'ö',
  '�' => '÷',
  '�' => 'ř',
  '�' => 'ů',
  '�' => 'ú',
  '�' => 'ű',
  '�' => 'ü',
  '�' => 'ý',
  '�' => 'ţ',
  '�' => '˙',
);

$result =& $data;
unset($data);

return $result;
PKϤ$Z�K��\\/polyfill-iconv/Resources/charset/from.cp869.phpnu�[���<?php

static $data = array (
  '' => '',
  '' => '',
  '' => '',
  '' => '',
  '' => '',
  '' => '',
  '' => '',
  '' => '',
  '' => '',
  '	' => '	',
  '
' => '
',
  '' => '',
  '' => '',
  '
' => '
',
  '' => '',
  '' => '',
  '' => '',
  '' => '',
  '' => '',
  '' => '',
  '' => '',
  '' => '',
  '' => '',
  '' => '',
  '' => '',
  '' => '',
  '' => '',
  '' => '',
  '' => '',
  '' => '',
  '' => '',
  '' => '',
  ' ' => ' ',
  '!' => '!',
  '"' => '"',
  '#' => '#',
  '$' => '$',
  '%' => '%',
  '&' => '&',
  '\'' => '\'',
  '(' => '(',
  ')' => ')',
  '*' => '*',
  '+' => '+',
  ',' => ',',
  '-' => '-',
  '.' => '.',
  '/' => '/',
  0 => '0',
  1 => '1',
  2 => '2',
  3 => '3',
  4 => '4',
  5 => '5',
  6 => '6',
  7 => '7',
  8 => '8',
  9 => '9',
  ':' => ':',
  ';' => ';',
  '<' => '<',
  '=' => '=',
  '>' => '>',
  '?' => '?',
  '@' => '@',
  'A' => 'A',
  'B' => 'B',
  'C' => 'C',
  'D' => 'D',
  'E' => 'E',
  'F' => 'F',
  'G' => 'G',
  'H' => 'H',
  'I' => 'I',
  'J' => 'J',
  'K' => 'K',
  'L' => 'L',
  'M' => 'M',
  'N' => 'N',
  'O' => 'O',
  'P' => 'P',
  'Q' => 'Q',
  'R' => 'R',
  'S' => 'S',
  'T' => 'T',
  'U' => 'U',
  'V' => 'V',
  'W' => 'W',
  'X' => 'X',
  'Y' => 'Y',
  'Z' => 'Z',
  '[' => '[',
  '\\' => '\\',
  ']' => ']',
  '^' => '^',
  '_' => '_',
  '`' => '`',
  'a' => 'a',
  'b' => 'b',
  'c' => 'c',
  'd' => 'd',
  'e' => 'e',
  'f' => 'f',
  'g' => 'g',
  'h' => 'h',
  'i' => 'i',
  'j' => 'j',
  'k' => 'k',
  'l' => 'l',
  'm' => 'm',
  'n' => 'n',
  'o' => 'o',
  'p' => 'p',
  'q' => 'q',
  'r' => 'r',
  's' => 's',
  't' => 't',
  'u' => 'u',
  'v' => 'v',
  'w' => 'w',
  'x' => 'x',
  'y' => 'y',
  'z' => 'z',
  '{' => '{',
  '|' => '|',
  '}' => '}',
  '~' => '~',
  '' => '',
  '�' => 'Ά',
  '�' => '·',
  '�' => '¬',
  '�' => '¦',
  '�' => '‘',
  '�' => '’',
  '�' => 'Έ',
  '�' => '―',
  '�' => 'Ή',
  '�' => 'Ί',
  '�' => 'Ϊ',
  '�' => 'Ό',
  '�' => 'Ύ',
  '�' => 'Ϋ',
  '�' => '©',
  '�' => 'Ώ',
  '�' => '²',
  '�' => '³',
  '�' => 'ά',
  '�' => '£',
  '�' => 'έ',
  '�' => 'ή',
  '�' => 'ί',
  '�' => 'ϊ',
  '�' => 'ΐ',
  '�' => 'ό',
  '�' => 'ύ',
  '�' => 'Α',
  '�' => 'Β',
  '�' => 'Γ',
  '�' => 'Δ',
  '�' => 'Ε',
  '�' => 'Ζ',
  '�' => 'Η',
  '�' => '½',
  '�' => 'Θ',
  '�' => 'Ι',
  '�' => '«',
  '�' => '»',
  '�' => '░',
  '�' => '▒',
  '�' => '▓',
  '�' => '│',
  '�' => '┤',
  '�' => 'Κ',
  '�' => 'Λ',
  '�' => 'Μ',
  '�' => 'Ν',
  '�' => '╣',
  '�' => '║',
  '�' => '╗',
  '�' => '╝',
  '�' => 'Ξ',
  '�' => 'Ο',
  '�' => '┐',
  '�' => '└',
  '�' => '┴',
  '�' => '┬',
  '�' => '├',
  '�' => '─',
  '�' => '┼',
  '�' => 'Π',
  '�' => 'Ρ',
  '�' => '╚',
  '�' => '╔',
  '�' => '╩',
  '�' => '╦',
  '�' => '╠',
  '�' => '═',
  '�' => '╬',
  '�' => 'Σ',
  '�' => 'Τ',
  '�' => 'Υ',
  '�' => 'Φ',
  '�' => 'Χ',
  '�' => 'Ψ',
  '�' => 'Ω',
  '�' => 'α',
  '�' => 'β',
  '�' => 'γ',
  '�' => '┘',
  '�' => '┌',
  '�' => '█',
  '�' => '▄',
  '�' => 'δ',
  '�' => 'ε',
  '�' => '▀',
  '�' => 'ζ',
  '�' => 'η',
  '�' => 'θ',
  '�' => 'ι',
  '�' => 'κ',
  '�' => 'λ',
  '�' => 'μ',
  '�' => 'ν',
  '�' => 'ξ',
  '�' => 'ο',
  '�' => 'π',
  '�' => 'ρ',
  '�' => 'σ',
  '�' => 'ς',
  '�' => 'τ',
  '�' => '΄',
  '�' => '­',
  '�' => '±',
  '�' => 'υ',
  '�' => 'φ',
  '�' => 'χ',
  '�' => '§',
  '�' => 'ψ',
  '�' => '΅',
  '�' => '°',
  '�' => '¨',
  '�' => 'ω',
  '�' => 'ϋ',
  '�' => 'ΰ',
  '�' => 'ώ',
  '�' => '■',
  '�' => ' ',
);

$result =& $data;
unset($data);

return $result;
PKϤ$Z�JT��6polyfill-iconv/Resources/charset/from.windows-1256.phpnu�[���<?php

static $data = array (
  '' => '',
  '' => '',
  '' => '',
  '' => '',
  '' => '',
  '' => '',
  '' => '',
  '' => '',
  '' => '',
  '	' => '	',
  '
' => '
',
  '' => '',
  '' => '',
  '
' => '
',
  '' => '',
  '' => '',
  '' => '',
  '' => '',
  '' => '',
  '' => '',
  '' => '',
  '' => '',
  '' => '',
  '' => '',
  '' => '',
  '' => '',
  '' => '',
  '' => '',
  '' => '',
  '' => '',
  '' => '',
  '' => '',
  ' ' => ' ',
  '!' => '!',
  '"' => '"',
  '#' => '#',
  '$' => '$',
  '%' => '%',
  '&' => '&',
  '\'' => '\'',
  '(' => '(',
  ')' => ')',
  '*' => '*',
  '+' => '+',
  ',' => ',',
  '-' => '-',
  '.' => '.',
  '/' => '/',
  0 => '0',
  1 => '1',
  2 => '2',
  3 => '3',
  4 => '4',
  5 => '5',
  6 => '6',
  7 => '7',
  8 => '8',
  9 => '9',
  ':' => ':',
  ';' => ';',
  '<' => '<',
  '=' => '=',
  '>' => '>',
  '?' => '?',
  '@' => '@',
  'A' => 'A',
  'B' => 'B',
  'C' => 'C',
  'D' => 'D',
  'E' => 'E',
  'F' => 'F',
  'G' => 'G',
  'H' => 'H',
  'I' => 'I',
  'J' => 'J',
  'K' => 'K',
  'L' => 'L',
  'M' => 'M',
  'N' => 'N',
  'O' => 'O',
  'P' => 'P',
  'Q' => 'Q',
  'R' => 'R',
  'S' => 'S',
  'T' => 'T',
  'U' => 'U',
  'V' => 'V',
  'W' => 'W',
  'X' => 'X',
  'Y' => 'Y',
  'Z' => 'Z',
  '[' => '[',
  '\\' => '\\',
  ']' => ']',
  '^' => '^',
  '_' => '_',
  '`' => '`',
  'a' => 'a',
  'b' => 'b',
  'c' => 'c',
  'd' => 'd',
  'e' => 'e',
  'f' => 'f',
  'g' => 'g',
  'h' => 'h',
  'i' => 'i',
  'j' => 'j',
  'k' => 'k',
  'l' => 'l',
  'm' => 'm',
  'n' => 'n',
  'o' => 'o',
  'p' => 'p',
  'q' => 'q',
  'r' => 'r',
  's' => 's',
  't' => 't',
  'u' => 'u',
  'v' => 'v',
  'w' => 'w',
  'x' => 'x',
  'y' => 'y',
  'z' => 'z',
  '{' => '{',
  '|' => '|',
  '}' => '}',
  '~' => '~',
  '' => '',
  '�' => '€',
  '�' => 'پ',
  '�' => '‚',
  '�' => 'ƒ',
  '�' => '„',
  '�' => '…',
  '�' => '†',
  '�' => '‡',
  '�' => 'ˆ',
  '�' => '‰',
  '�' => 'ٹ',
  '�' => '‹',
  '�' => 'Œ',
  '�' => 'چ',
  '�' => 'ژ',
  '�' => 'ڈ',
  '�' => 'گ',
  '�' => '‘',
  '�' => '’',
  '�' => '“',
  '�' => '”',
  '�' => '•',
  '�' => '–',
  '�' => '—',
  '�' => 'ک',
  '�' => '™',
  '�' => 'ڑ',
  '�' => '›',
  '�' => 'œ',
  '�' => '‌',
  '�' => '‍',
  '�' => 'ں',
  '�' => ' ',
  '�' => '،',
  '�' => '¢',
  '�' => '£',
  '�' => '¤',
  '�' => '¥',
  '�' => '¦',
  '�' => '§',
  '�' => '¨',
  '�' => '©',
  '�' => 'ھ',
  '�' => '«',
  '�' => '¬',
  '�' => '­',
  '�' => '®',
  '�' => '¯',
  '�' => '°',
  '�' => '±',
  '�' => '²',
  '�' => '³',
  '�' => '´',
  '�' => 'µ',
  '�' => '¶',
  '�' => '·',
  '�' => '¸',
  '�' => '¹',
  '�' => '؛',
  '�' => '»',
  '�' => '¼',
  '�' => '½',
  '�' => '¾',
  '�' => '؟',
  '�' => 'ہ',
  '�' => 'ء',
  '�' => 'آ',
  '�' => 'أ',
  '�' => 'ؤ',
  '�' => 'إ',
  '�' => 'ئ',
  '�' => 'ا',
  '�' => 'ب',
  '�' => 'ة',
  '�' => 'ت',
  '�' => 'ث',
  '�' => 'ج',
  '�' => 'ح',
  '�' => 'خ',
  '�' => 'د',
  '�' => 'ذ',
  '�' => 'ر',
  '�' => 'ز',
  '�' => 'س',
  '�' => 'ش',
  '�' => 'ص',
  '�' => 'ض',
  '�' => '×',
  '�' => 'ط',
  '�' => 'ظ',
  '�' => 'ع',
  '�' => 'غ',
  '�' => 'ـ',
  '�' => 'ف',
  '�' => 'ق',
  '�' => 'ك',
  '�' => 'à',
  '�' => 'ل',
  '�' => 'â',
  '�' => 'م',
  '�' => 'ن',
  '�' => 'ه',
  '�' => 'و',
  '�' => 'ç',
  '�' => 'è',
  '�' => 'é',
  '�' => 'ê',
  '�' => 'ë',
  '�' => 'ى',
  '�' => 'ي',
  '�' => 'î',
  '�' => 'ï',
  '�' => 'ً',
  '�' => 'ٌ',
  '�' => 'ٍ',
  '�' => 'َ',
  '�' => 'ô',
  '�' => 'ُ',
  '�' => 'ِ',
  '�' => '÷',
  '�' => 'ّ',
  '�' => 'ù',
  '�' => 'ْ',
  '�' => 'û',
  '�' => 'ü',
  '�' => '‎',
  '�' => '‏',
  '�' => 'ے',
);

$result =& $data;
unset($data);

return $result;
PKϤ$Z#�����0polyfill-iconv/Resources/charset/from.cp1026.phpnu�[���<?php

static $data = array (
  '' => '',
  '' => '',
  '' => '',
  '' => '',
  '' => 'œ',
  '' => '	',
  '' => '†',
  '' => '',
  '' => '—',
  '	' => '',
  '
' => 'Ž',
  '' => '',
  '' => '',
  '
' => '
',
  '' => '',
  '' => '',
  '' => '',
  '' => '',
  '' => '',
  '' => '',
  '' => '',
  '' => '…',
  '' => '',
  '' => '‡',
  '' => '',
  '' => '',
  '' => '’',
  '' => '',
  '' => '',
  '' => '',
  '' => '',
  '' => '',
  ' ' => '€',
  '!' => '',
  '"' => '‚',
  '#' => 'ƒ',
  '$' => '„',
  '%' => '
',
  '&' => '',
  '\'' => '',
  '(' => 'ˆ',
  ')' => '‰',
  '*' => 'Š',
  '+' => '‹',
  ',' => 'Œ',
  '-' => '',
  '.' => '',
  '/' => '',
  0 => '',
  1 => '‘',
  2 => '',
  3 => '“',
  4 => '”',
  5 => '•',
  6 => '–',
  7 => '',
  8 => '˜',
  9 => '™',
  ':' => 'š',
  ';' => '›',
  '<' => '',
  '=' => '',
  '>' => 'ž',
  '?' => '',
  '@' => ' ',
  'A' => ' ',
  'B' => 'â',
  'C' => 'ä',
  'D' => 'à',
  'E' => 'á',
  'F' => 'ã',
  'G' => 'å',
  'H' => '{',
  'I' => 'ñ',
  'J' => 'Ç',
  'K' => '.',
  'L' => '<',
  'M' => '(',
  'N' => '+',
  'O' => '!',
  'P' => '&',
  'Q' => 'é',
  'R' => 'ê',
  'S' => 'ë',
  'T' => 'è',
  'U' => 'í',
  'V' => 'î',
  'W' => 'ï',
  'X' => 'ì',
  'Y' => 'ß',
  'Z' => 'Ğ',
  '[' => 'İ',
  '\\' => '*',
  ']' => ')',
  '^' => ';',
  '_' => '^',
  '`' => '-',
  'a' => '/',
  'b' => 'Â',
  'c' => 'Ä',
  'd' => 'À',
  'e' => 'Á',
  'f' => 'Ã',
  'g' => 'Å',
  'h' => '[',
  'i' => 'Ñ',
  'j' => 'ş',
  'k' => ',',
  'l' => '%',
  'm' => '_',
  'n' => '>',
  'o' => '?',
  'p' => 'ø',
  'q' => 'É',
  'r' => 'Ê',
  's' => 'Ë',
  't' => 'È',
  'u' => 'Í',
  'v' => 'Î',
  'w' => 'Ï',
  'x' => 'Ì',
  'y' => 'ı',
  'z' => ':',
  '{' => 'Ö',
  '|' => 'Ş',
  '}' => '\'',
  '~' => '=',
  '' => 'Ü',
  '�' => 'Ø',
  '�' => 'a',
  '�' => 'b',
  '�' => 'c',
  '�' => 'd',
  '�' => 'e',
  '�' => 'f',
  '�' => 'g',
  '�' => 'h',
  '�' => 'i',
  '�' => '«',
  '�' => '»',
  '�' => '}',
  '�' => '`',
  '�' => '¦',
  '�' => '±',
  '�' => '°',
  '�' => 'j',
  '�' => 'k',
  '�' => 'l',
  '�' => 'm',
  '�' => 'n',
  '�' => 'o',
  '�' => 'p',
  '�' => 'q',
  '�' => 'r',
  '�' => 'ª',
  '�' => 'º',
  '�' => 'æ',
  '�' => '¸',
  '�' => 'Æ',
  '�' => '¤',
  '�' => 'µ',
  '�' => 'ö',
  '�' => 's',
  '�' => 't',
  '�' => 'u',
  '�' => 'v',
  '�' => 'w',
  '�' => 'x',
  '�' => 'y',
  '�' => 'z',
  '�' => '¡',
  '�' => '¿',
  '�' => ']',
  '�' => '$',
  '�' => '@',
  '�' => '®',
  '�' => '¢',
  '�' => '£',
  '�' => '¥',
  '�' => '·',
  '�' => '©',
  '�' => '§',
  '�' => '¶',
  '�' => '¼',
  '�' => '½',
  '�' => '¾',
  '�' => '¬',
  '�' => '|',
  '�' => '¯',
  '�' => '¨',
  '�' => '´',
  '�' => '×',
  '�' => 'ç',
  '�' => 'A',
  '�' => 'B',
  '�' => 'C',
  '�' => 'D',
  '�' => 'E',
  '�' => 'F',
  '�' => 'G',
  '�' => 'H',
  '�' => 'I',
  '�' => '­',
  '�' => 'ô',
  '�' => '~',
  '�' => 'ò',
  '�' => 'ó',
  '�' => 'õ',
  '�' => 'ğ',
  '�' => 'J',
  '�' => 'K',
  '�' => 'L',
  '�' => 'M',
  '�' => 'N',
  '�' => 'O',
  '�' => 'P',
  '�' => 'Q',
  '�' => 'R',
  '�' => '¹',
  '�' => 'û',
  '�' => '\\',
  '�' => 'ù',
  '�' => 'ú',
  '�' => 'ÿ',
  '�' => 'ü',
  '�' => '÷',
  '�' => 'S',
  '�' => 'T',
  '�' => 'U',
  '�' => 'V',
  '�' => 'W',
  '�' => 'X',
  '�' => 'Y',
  '�' => 'Z',
  '�' => '²',
  '�' => 'Ô',
  '�' => '#',
  '�' => 'Ò',
  '�' => 'Ó',
  '�' => 'Õ',
  '�' => '0',
  '�' => '1',
  '�' => '2',
  '�' => '3',
  '�' => '4',
  '�' => '5',
  '�' => '6',
  '�' => '7',
  '�' => '8',
  '�' => '9',
  '�' => '³',
  '�' => 'Û',
  '�' => '"',
  '�' => 'Ù',
  '�' => 'Ú',
  '�' => 'Ÿ',
);

$result =& $data;
unset($data);

return $result;
PKϤ$Z?��*/polyfill-iconv/Resources/charset/from.cp865.phpnu�[���<?php

static $data = array (
  '' => '',
  '' => '',
  '' => '',
  '' => '',
  '' => '',
  '' => '',
  '' => '',
  '' => '',
  '' => '',
  '	' => '	',
  '
' => '
',
  '' => '',
  '' => '',
  '
' => '
',
  '' => '',
  '' => '',
  '' => '',
  '' => '',
  '' => '',
  '' => '',
  '' => '',
  '' => '',
  '' => '',
  '' => '',
  '' => '',
  '' => '',
  '' => '',
  '' => '',
  '' => '',
  '' => '',
  '' => '',
  '' => '',
  ' ' => ' ',
  '!' => '!',
  '"' => '"',
  '#' => '#',
  '$' => '$',
  '%' => '%',
  '&' => '&',
  '\'' => '\'',
  '(' => '(',
  ')' => ')',
  '*' => '*',
  '+' => '+',
  ',' => ',',
  '-' => '-',
  '.' => '.',
  '/' => '/',
  0 => '0',
  1 => '1',
  2 => '2',
  3 => '3',
  4 => '4',
  5 => '5',
  6 => '6',
  7 => '7',
  8 => '8',
  9 => '9',
  ':' => ':',
  ';' => ';',
  '<' => '<',
  '=' => '=',
  '>' => '>',
  '?' => '?',
  '@' => '@',
  'A' => 'A',
  'B' => 'B',
  'C' => 'C',
  'D' => 'D',
  'E' => 'E',
  'F' => 'F',
  'G' => 'G',
  'H' => 'H',
  'I' => 'I',
  'J' => 'J',
  'K' => 'K',
  'L' => 'L',
  'M' => 'M',
  'N' => 'N',
  'O' => 'O',
  'P' => 'P',
  'Q' => 'Q',
  'R' => 'R',
  'S' => 'S',
  'T' => 'T',
  'U' => 'U',
  'V' => 'V',
  'W' => 'W',
  'X' => 'X',
  'Y' => 'Y',
  'Z' => 'Z',
  '[' => '[',
  '\\' => '\\',
  ']' => ']',
  '^' => '^',
  '_' => '_',
  '`' => '`',
  'a' => 'a',
  'b' => 'b',
  'c' => 'c',
  'd' => 'd',
  'e' => 'e',
  'f' => 'f',
  'g' => 'g',
  'h' => 'h',
  'i' => 'i',
  'j' => 'j',
  'k' => 'k',
  'l' => 'l',
  'm' => 'm',
  'n' => 'n',
  'o' => 'o',
  'p' => 'p',
  'q' => 'q',
  'r' => 'r',
  's' => 's',
  't' => 't',
  'u' => 'u',
  'v' => 'v',
  'w' => 'w',
  'x' => 'x',
  'y' => 'y',
  'z' => 'z',
  '{' => '{',
  '|' => '|',
  '}' => '}',
  '~' => '~',
  '' => '',
  '�' => 'Ç',
  '�' => 'ü',
  '�' => 'é',
  '�' => 'â',
  '�' => 'ä',
  '�' => 'à',
  '�' => 'å',
  '�' => 'ç',
  '�' => 'ê',
  '�' => 'ë',
  '�' => 'è',
  '�' => 'ï',
  '�' => 'î',
  '�' => 'ì',
  '�' => 'Ä',
  '�' => 'Å',
  '�' => 'É',
  '�' => 'æ',
  '�' => 'Æ',
  '�' => 'ô',
  '�' => 'ö',
  '�' => 'ò',
  '�' => 'û',
  '�' => 'ù',
  '�' => 'ÿ',
  '�' => 'Ö',
  '�' => 'Ü',
  '�' => 'ø',
  '�' => '£',
  '�' => 'Ø',
  '�' => '₧',
  '�' => 'ƒ',
  '�' => 'á',
  '�' => 'í',
  '�' => 'ó',
  '�' => 'ú',
  '�' => 'ñ',
  '�' => 'Ñ',
  '�' => 'ª',
  '�' => 'º',
  '�' => '¿',
  '�' => '⌐',
  '�' => '¬',
  '�' => '½',
  '�' => '¼',
  '�' => '¡',
  '�' => '«',
  '�' => '¤',
  '�' => '░',
  '�' => '▒',
  '�' => '▓',
  '�' => '│',
  '�' => '┤',
  '�' => '╡',
  '�' => '╢',
  '�' => '╖',
  '�' => '╕',
  '�' => '╣',
  '�' => '║',
  '�' => '╗',
  '�' => '╝',
  '�' => '╜',
  '�' => '╛',
  '�' => '┐',
  '�' => '└',
  '�' => '┴',
  '�' => '┬',
  '�' => '├',
  '�' => '─',
  '�' => '┼',
  '�' => '╞',
  '�' => '╟',
  '�' => '╚',
  '�' => '╔',
  '�' => '╩',
  '�' => '╦',
  '�' => '╠',
  '�' => '═',
  '�' => '╬',
  '�' => '╧',
  '�' => '╨',
  '�' => '╤',
  '�' => '╥',
  '�' => '╙',
  '�' => '╘',
  '�' => '╒',
  '�' => '╓',
  '�' => '╫',
  '�' => '╪',
  '�' => '┘',
  '�' => '┌',
  '�' => '█',
  '�' => '▄',
  '�' => '▌',
  '�' => '▐',
  '�' => '▀',
  '�' => 'α',
  '�' => 'ß',
  '�' => 'Γ',
  '�' => 'π',
  '�' => 'Σ',
  '�' => 'σ',
  '�' => 'µ',
  '�' => 'τ',
  '�' => 'Φ',
  '�' => 'Θ',
  '�' => 'Ω',
  '�' => 'δ',
  '�' => '∞',
  '�' => 'φ',
  '�' => 'ε',
  '�' => '∩',
  '�' => '≡',
  '�' => '±',
  '�' => '≥',
  '�' => '≤',
  '�' => '⌠',
  '�' => '⌡',
  '�' => '÷',
  '�' => '≈',
  '�' => '°',
  '�' => '∙',
  '�' => '·',
  '�' => '√',
  '�' => 'ⁿ',
  '�' => '²',
  '�' => '■',
  '�' => ' ',
);

$result =& $data;
unset($data);

return $result;
PKϤ$Z���|/polyfill-iconv/Resources/charset/from.cp862.phpnu�[���<?php

static $data = array (
  '' => '',
  '' => '',
  '' => '',
  '' => '',
  '' => '',
  '' => '',
  '' => '',
  '' => '',
  '' => '',
  '	' => '	',
  '
' => '
',
  '' => '',
  '' => '',
  '
' => '
',
  '' => '',
  '' => '',
  '' => '',
  '' => '',
  '' => '',
  '' => '',
  '' => '',
  '' => '',
  '' => '',
  '' => '',
  '' => '',
  '' => '',
  '' => '',
  '' => '',
  '' => '',
  '' => '',
  '' => '',
  '' => '',
  ' ' => ' ',
  '!' => '!',
  '"' => '"',
  '#' => '#',
  '$' => '$',
  '%' => '%',
  '&' => '&',
  '\'' => '\'',
  '(' => '(',
  ')' => ')',
  '*' => '*',
  '+' => '+',
  ',' => ',',
  '-' => '-',
  '.' => '.',
  '/' => '/',
  0 => '0',
  1 => '1',
  2 => '2',
  3 => '3',
  4 => '4',
  5 => '5',
  6 => '6',
  7 => '7',
  8 => '8',
  9 => '9',
  ':' => ':',
  ';' => ';',
  '<' => '<',
  '=' => '=',
  '>' => '>',
  '?' => '?',
  '@' => '@',
  'A' => 'A',
  'B' => 'B',
  'C' => 'C',
  'D' => 'D',
  'E' => 'E',
  'F' => 'F',
  'G' => 'G',
  'H' => 'H',
  'I' => 'I',
  'J' => 'J',
  'K' => 'K',
  'L' => 'L',
  'M' => 'M',
  'N' => 'N',
  'O' => 'O',
  'P' => 'P',
  'Q' => 'Q',
  'R' => 'R',
  'S' => 'S',
  'T' => 'T',
  'U' => 'U',
  'V' => 'V',
  'W' => 'W',
  'X' => 'X',
  'Y' => 'Y',
  'Z' => 'Z',
  '[' => '[',
  '\\' => '\\',
  ']' => ']',
  '^' => '^',
  '_' => '_',
  '`' => '`',
  'a' => 'a',
  'b' => 'b',
  'c' => 'c',
  'd' => 'd',
  'e' => 'e',
  'f' => 'f',
  'g' => 'g',
  'h' => 'h',
  'i' => 'i',
  'j' => 'j',
  'k' => 'k',
  'l' => 'l',
  'm' => 'm',
  'n' => 'n',
  'o' => 'o',
  'p' => 'p',
  'q' => 'q',
  'r' => 'r',
  's' => 's',
  't' => 't',
  'u' => 'u',
  'v' => 'v',
  'w' => 'w',
  'x' => 'x',
  'y' => 'y',
  'z' => 'z',
  '{' => '{',
  '|' => '|',
  '}' => '}',
  '~' => '~',
  '' => '',
  '�' => 'א',
  '�' => 'ב',
  '�' => 'ג',
  '�' => 'ד',
  '�' => 'ה',
  '�' => 'ו',
  '�' => 'ז',
  '�' => 'ח',
  '�' => 'ט',
  '�' => 'י',
  '�' => 'ך',
  '�' => 'כ',
  '�' => 'ל',
  '�' => 'ם',
  '�' => 'מ',
  '�' => 'ן',
  '�' => 'נ',
  '�' => 'ס',
  '�' => 'ע',
  '�' => 'ף',
  '�' => 'פ',
  '�' => 'ץ',
  '�' => 'צ',
  '�' => 'ק',
  '�' => 'ר',
  '�' => 'ש',
  '�' => 'ת',
  '�' => '¢',
  '�' => '£',
  '�' => '¥',
  '�' => '₧',
  '�' => 'ƒ',
  '�' => 'á',
  '�' => 'í',
  '�' => 'ó',
  '�' => 'ú',
  '�' => 'ñ',
  '�' => 'Ñ',
  '�' => 'ª',
  '�' => 'º',
  '�' => '¿',
  '�' => '⌐',
  '�' => '¬',
  '�' => '½',
  '�' => '¼',
  '�' => '¡',
  '�' => '«',
  '�' => '»',
  '�' => '░',
  '�' => '▒',
  '�' => '▓',
  '�' => '│',
  '�' => '┤',
  '�' => '╡',
  '�' => '╢',
  '�' => '╖',
  '�' => '╕',
  '�' => '╣',
  '�' => '║',
  '�' => '╗',
  '�' => '╝',
  '�' => '╜',
  '�' => '╛',
  '�' => '┐',
  '�' => '└',
  '�' => '┴',
  '�' => '┬',
  '�' => '├',
  '�' => '─',
  '�' => '┼',
  '�' => '╞',
  '�' => '╟',
  '�' => '╚',
  '�' => '╔',
  '�' => '╩',
  '�' => '╦',
  '�' => '╠',
  '�' => '═',
  '�' => '╬',
  '�' => '╧',
  '�' => '╨',
  '�' => '╤',
  '�' => '╥',
  '�' => '╙',
  '�' => '╘',
  '�' => '╒',
  '�' => '╓',
  '�' => '╫',
  '�' => '╪',
  '�' => '┘',
  '�' => '┌',
  '�' => '█',
  '�' => '▄',
  '�' => '▌',
  '�' => '▐',
  '�' => '▀',
  '�' => 'α',
  '�' => 'ß',
  '�' => 'Γ',
  '�' => 'π',
  '�' => 'Σ',
  '�' => 'σ',
  '�' => 'µ',
  '�' => 'τ',
  '�' => 'Φ',
  '�' => 'Θ',
  '�' => 'Ω',
  '�' => 'δ',
  '�' => '∞',
  '�' => 'φ',
  '�' => 'ε',
  '�' => '∩',
  '�' => '≡',
  '�' => '±',
  '�' => '≥',
  '�' => '≤',
  '�' => '⌠',
  '�' => '⌡',
  '�' => '÷',
  '�' => '≈',
  '�' => '°',
  '�' => '∙',
  '�' => '·',
  '�' => '√',
  '�' => 'ⁿ',
  '�' => '²',
  '�' => '■',
  '�' => ' ',
);

$result =& $data;
unset($data);

return $result;
PKϤ$Z����/polyfill-iconv/Resources/charset/from.cp424.phpnu�[���<?php

static $data = array (
  '' => '',
  '' => '',
  '' => '',
  '' => '',
  '' => 'œ',
  '' => '	',
  '' => '†',
  '' => '',
  '' => '—',
  '	' => '',
  '
' => 'Ž',
  '' => '',
  '' => '',
  '
' => '
',
  '' => '',
  '' => '',
  '' => '',
  '' => '',
  '' => '',
  '' => '',
  '' => '',
  '' => '…',
  '' => '',
  '' => '‡',
  '' => '',
  '' => '',
  '' => '’',
  '' => '',
  '' => '',
  '' => '',
  '' => '',
  '' => '',
  ' ' => '€',
  '!' => '',
  '"' => '‚',
  '#' => 'ƒ',
  '$' => '„',
  '%' => '
',
  '&' => '',
  '\'' => '',
  '(' => 'ˆ',
  ')' => '‰',
  '*' => 'Š',
  '+' => '‹',
  ',' => 'Œ',
  '-' => '',
  '.' => '',
  '/' => '',
  0 => '',
  1 => '‘',
  2 => '',
  3 => '“',
  4 => '”',
  5 => '•',
  6 => '–',
  7 => '',
  8 => '˜',
  9 => '™',
  ':' => 'š',
  ';' => '›',
  '<' => '',
  '=' => '',
  '>' => 'ž',
  '?' => '',
  '@' => ' ',
  'A' => 'א',
  'B' => 'ב',
  'C' => 'ג',
  'D' => 'ד',
  'E' => 'ה',
  'F' => 'ו',
  'G' => 'ז',
  'H' => 'ח',
  'I' => 'ט',
  'J' => '¢',
  'K' => '.',
  'L' => '<',
  'M' => '(',
  'N' => '+',
  'O' => '|',
  'P' => '&',
  'Q' => 'י',
  'R' => 'ך',
  'S' => 'כ',
  'T' => 'ל',
  'U' => 'ם',
  'V' => 'מ',
  'W' => 'ן',
  'X' => 'נ',
  'Y' => 'ס',
  'Z' => '!',
  '[' => '$',
  '\\' => '*',
  ']' => ')',
  '^' => ';',
  '_' => '¬',
  '`' => '-',
  'a' => '/',
  'b' => 'ע',
  'c' => 'ף',
  'd' => 'פ',
  'e' => 'ץ',
  'f' => 'צ',
  'g' => 'ק',
  'h' => 'ר',
  'i' => 'ש',
  'j' => '¦',
  'k' => ',',
  'l' => '%',
  'm' => '_',
  'n' => '>',
  'o' => '?',
  'q' => 'ת',
  't' => ' ',
  'x' => '‗',
  'y' => '`',
  'z' => ':',
  '{' => '#',
  '|' => '@',
  '}' => '\'',
  '~' => '=',
  '' => '"',
  '�' => 'a',
  '�' => 'b',
  '�' => 'c',
  '�' => 'd',
  '�' => 'e',
  '�' => 'f',
  '�' => 'g',
  '�' => 'h',
  '�' => 'i',
  '�' => '«',
  '�' => '»',
  '�' => '±',
  '�' => '°',
  '�' => 'j',
  '�' => 'k',
  '�' => 'l',
  '�' => 'm',
  '�' => 'n',
  '�' => 'o',
  '�' => 'p',
  '�' => 'q',
  '�' => 'r',
  '�' => '¸',
  '�' => '¤',
  '�' => 'µ',
  '�' => '~',
  '�' => 's',
  '�' => 't',
  '�' => 'u',
  '�' => 'v',
  '�' => 'w',
  '�' => 'x',
  '�' => 'y',
  '�' => 'z',
  '�' => '®',
  '�' => '^',
  '�' => '£',
  '�' => '¥',
  '�' => '·',
  '�' => '©',
  '�' => '§',
  '�' => '¶',
  '�' => '¼',
  '�' => '½',
  '�' => '¾',
  '�' => '[',
  '�' => ']',
  '�' => '¯',
  '�' => '¨',
  '�' => '´',
  '�' => '×',
  '�' => '{',
  '�' => 'A',
  '�' => 'B',
  '�' => 'C',
  '�' => 'D',
  '�' => 'E',
  '�' => 'F',
  '�' => 'G',
  '�' => 'H',
  '�' => 'I',
  '�' => '­',
  '�' => '}',
  '�' => 'J',
  '�' => 'K',
  '�' => 'L',
  '�' => 'M',
  '�' => 'N',
  '�' => 'O',
  '�' => 'P',
  '�' => 'Q',
  '�' => 'R',
  '�' => '¹',
  '�' => '\\',
  '�' => '÷',
  '�' => 'S',
  '�' => 'T',
  '�' => 'U',
  '�' => 'V',
  '�' => 'W',
  '�' => 'X',
  '�' => 'Y',
  '�' => 'Z',
  '�' => '²',
  '�' => '0',
  '�' => '1',
  '�' => '2',
  '�' => '3',
  '�' => '4',
  '�' => '5',
  '�' => '6',
  '�' => '7',
  '�' => '8',
  '�' => '9',
  '�' => '³',
  '�' => 'Ÿ',
);

$result =& $data;
unset($data);

return $result;
PKϤ$Zd�lAll4polyfill-iconv/Resources/charset/from.iso-8859-7.phpnu�[���<?php

static $data = array (
  '' => '',
  '' => '',
  '' => '',
  '' => '',
  '' => '',
  '' => '',
  '' => '',
  '' => '',
  '' => '',
  '	' => '	',
  '
' => '
',
  '' => '',
  '' => '',
  '
' => '
',
  '' => '',
  '' => '',
  '' => '',
  '' => '',
  '' => '',
  '' => '',
  '' => '',
  '' => '',
  '' => '',
  '' => '',
  '' => '',
  '' => '',
  '' => '',
  '' => '',
  '' => '',
  '' => '',
  '' => '',
  '' => '',
  ' ' => ' ',
  '!' => '!',
  '"' => '"',
  '#' => '#',
  '$' => '$',
  '%' => '%',
  '&' => '&',
  '\'' => '\'',
  '(' => '(',
  ')' => ')',
  '*' => '*',
  '+' => '+',
  ',' => ',',
  '-' => '-',
  '.' => '.',
  '/' => '/',
  0 => '0',
  1 => '1',
  2 => '2',
  3 => '3',
  4 => '4',
  5 => '5',
  6 => '6',
  7 => '7',
  8 => '8',
  9 => '9',
  ':' => ':',
  ';' => ';',
  '<' => '<',
  '=' => '=',
  '>' => '>',
  '?' => '?',
  '@' => '@',
  'A' => 'A',
  'B' => 'B',
  'C' => 'C',
  'D' => 'D',
  'E' => 'E',
  'F' => 'F',
  'G' => 'G',
  'H' => 'H',
  'I' => 'I',
  'J' => 'J',
  'K' => 'K',
  'L' => 'L',
  'M' => 'M',
  'N' => 'N',
  'O' => 'O',
  'P' => 'P',
  'Q' => 'Q',
  'R' => 'R',
  'S' => 'S',
  'T' => 'T',
  'U' => 'U',
  'V' => 'V',
  'W' => 'W',
  'X' => 'X',
  'Y' => 'Y',
  'Z' => 'Z',
  '[' => '[',
  '\\' => '\\',
  ']' => ']',
  '^' => '^',
  '_' => '_',
  '`' => '`',
  'a' => 'a',
  'b' => 'b',
  'c' => 'c',
  'd' => 'd',
  'e' => 'e',
  'f' => 'f',
  'g' => 'g',
  'h' => 'h',
  'i' => 'i',
  'j' => 'j',
  'k' => 'k',
  'l' => 'l',
  'm' => 'm',
  'n' => 'n',
  'o' => 'o',
  'p' => 'p',
  'q' => 'q',
  'r' => 'r',
  's' => 's',
  't' => 't',
  'u' => 'u',
  'v' => 'v',
  'w' => 'w',
  'x' => 'x',
  'y' => 'y',
  'z' => 'z',
  '{' => '{',
  '|' => '|',
  '}' => '}',
  '~' => '~',
  '' => '',
  '�' => '€',
  '�' => '',
  '�' => '‚',
  '�' => 'ƒ',
  '�' => '„',
  '�' => '…',
  '�' => '†',
  '�' => '‡',
  '�' => 'ˆ',
  '�' => '‰',
  '�' => 'Š',
  '�' => '‹',
  '�' => 'Œ',
  '�' => '',
  '�' => 'Ž',
  '�' => '',
  '�' => '',
  '�' => '‘',
  '�' => '’',
  '�' => '“',
  '�' => '”',
  '�' => '•',
  '�' => '–',
  '�' => '—',
  '�' => '˜',
  '�' => '™',
  '�' => 'š',
  '�' => '›',
  '�' => 'œ',
  '�' => '',
  '�' => 'ž',
  '�' => 'Ÿ',
  '�' => ' ',
  '�' => '‘',
  '�' => '’',
  '�' => '£',
  '�' => '¦',
  '�' => '§',
  '�' => '¨',
  '�' => '©',
  '�' => '«',
  '�' => '¬',
  '�' => '­',
  '�' => '―',
  '�' => '°',
  '�' => '±',
  '�' => '²',
  '�' => '³',
  '�' => '΄',
  '�' => '΅',
  '�' => 'Ά',
  '�' => '·',
  '�' => 'Έ',
  '�' => 'Ή',
  '�' => 'Ί',
  '�' => '»',
  '�' => 'Ό',
  '�' => '½',
  '�' => 'Ύ',
  '�' => 'Ώ',
  '�' => 'ΐ',
  '�' => 'Α',
  '�' => 'Β',
  '�' => 'Γ',
  '�' => 'Δ',
  '�' => 'Ε',
  '�' => 'Ζ',
  '�' => 'Η',
  '�' => 'Θ',
  '�' => 'Ι',
  '�' => 'Κ',
  '�' => 'Λ',
  '�' => 'Μ',
  '�' => 'Ν',
  '�' => 'Ξ',
  '�' => 'Ο',
  '�' => 'Π',
  '�' => 'Ρ',
  '�' => 'Σ',
  '�' => 'Τ',
  '�' => 'Υ',
  '�' => 'Φ',
  '�' => 'Χ',
  '�' => 'Ψ',
  '�' => 'Ω',
  '�' => 'Ϊ',
  '�' => 'Ϋ',
  '�' => 'ά',
  '�' => 'έ',
  '�' => 'ή',
  '�' => 'ί',
  '�' => 'ΰ',
  '�' => 'α',
  '�' => 'β',
  '�' => 'γ',
  '�' => 'δ',
  '�' => 'ε',
  '�' => 'ζ',
  '�' => 'η',
  '�' => 'θ',
  '�' => 'ι',
  '�' => 'κ',
  '�' => 'λ',
  '�' => 'μ',
  '�' => 'ν',
  '�' => 'ξ',
  '�' => 'ο',
  '�' => 'π',
  '�' => 'ρ',
  '�' => 'ς',
  '�' => 'σ',
  '�' => 'τ',
  '�' => 'υ',
  '�' => 'φ',
  '�' => 'χ',
  '�' => 'ψ',
  '�' => 'ω',
  '�' => 'ϊ',
  '�' => 'ϋ',
  '�' => 'ό',
  '�' => 'ύ',
  '�' => 'ώ',
);

$result =& $data;
unset($data);

return $result;
PKϤ$ZŬ�/polyfill-iconv/Resources/charset/from.cp863.phpnu�[���<?php

static $data = array (
  '' => '',
  '' => '',
  '' => '',
  '' => '',
  '' => '',
  '' => '',
  '' => '',
  '' => '',
  '' => '',
  '	' => '	',
  '
' => '
',
  '' => '',
  '' => '',
  '
' => '
',
  '' => '',
  '' => '',
  '' => '',
  '' => '',
  '' => '',
  '' => '',
  '' => '',
  '' => '',
  '' => '',
  '' => '',
  '' => '',
  '' => '',
  '' => '',
  '' => '',
  '' => '',
  '' => '',
  '' => '',
  '' => '',
  ' ' => ' ',
  '!' => '!',
  '"' => '"',
  '#' => '#',
  '$' => '$',
  '%' => '%',
  '&' => '&',
  '\'' => '\'',
  '(' => '(',
  ')' => ')',
  '*' => '*',
  '+' => '+',
  ',' => ',',
  '-' => '-',
  '.' => '.',
  '/' => '/',
  0 => '0',
  1 => '1',
  2 => '2',
  3 => '3',
  4 => '4',
  5 => '5',
  6 => '6',
  7 => '7',
  8 => '8',
  9 => '9',
  ':' => ':',
  ';' => ';',
  '<' => '<',
  '=' => '=',
  '>' => '>',
  '?' => '?',
  '@' => '@',
  'A' => 'A',
  'B' => 'B',
  'C' => 'C',
  'D' => 'D',
  'E' => 'E',
  'F' => 'F',
  'G' => 'G',
  'H' => 'H',
  'I' => 'I',
  'J' => 'J',
  'K' => 'K',
  'L' => 'L',
  'M' => 'M',
  'N' => 'N',
  'O' => 'O',
  'P' => 'P',
  'Q' => 'Q',
  'R' => 'R',
  'S' => 'S',
  'T' => 'T',
  'U' => 'U',
  'V' => 'V',
  'W' => 'W',
  'X' => 'X',
  'Y' => 'Y',
  'Z' => 'Z',
  '[' => '[',
  '\\' => '\\',
  ']' => ']',
  '^' => '^',
  '_' => '_',
  '`' => '`',
  'a' => 'a',
  'b' => 'b',
  'c' => 'c',
  'd' => 'd',
  'e' => 'e',
  'f' => 'f',
  'g' => 'g',
  'h' => 'h',
  'i' => 'i',
  'j' => 'j',
  'k' => 'k',
  'l' => 'l',
  'm' => 'm',
  'n' => 'n',
  'o' => 'o',
  'p' => 'p',
  'q' => 'q',
  'r' => 'r',
  's' => 's',
  't' => 't',
  'u' => 'u',
  'v' => 'v',
  'w' => 'w',
  'x' => 'x',
  'y' => 'y',
  'z' => 'z',
  '{' => '{',
  '|' => '|',
  '}' => '}',
  '~' => '~',
  '' => '',
  '�' => 'Ç',
  '�' => 'ü',
  '�' => 'é',
  '�' => 'â',
  '�' => 'Â',
  '�' => 'à',
  '�' => '¶',
  '�' => 'ç',
  '�' => 'ê',
  '�' => 'ë',
  '�' => 'è',
  '�' => 'ï',
  '�' => 'î',
  '�' => '‗',
  '�' => 'À',
  '�' => '§',
  '�' => 'É',
  '�' => 'È',
  '�' => 'Ê',
  '�' => 'ô',
  '�' => 'Ë',
  '�' => 'Ï',
  '�' => 'û',
  '�' => 'ù',
  '�' => '¤',
  '�' => 'Ô',
  '�' => 'Ü',
  '�' => '¢',
  '�' => '£',
  '�' => 'Ù',
  '�' => 'Û',
  '�' => 'ƒ',
  '�' => '¦',
  '�' => '´',
  '�' => 'ó',
  '�' => 'ú',
  '�' => '¨',
  '�' => '¸',
  '�' => '³',
  '�' => '¯',
  '�' => 'Î',
  '�' => '⌐',
  '�' => '¬',
  '�' => '½',
  '�' => '¼',
  '�' => '¾',
  '�' => '«',
  '�' => '»',
  '�' => '░',
  '�' => '▒',
  '�' => '▓',
  '�' => '│',
  '�' => '┤',
  '�' => '╡',
  '�' => '╢',
  '�' => '╖',
  '�' => '╕',
  '�' => '╣',
  '�' => '║',
  '�' => '╗',
  '�' => '╝',
  '�' => '╜',
  '�' => '╛',
  '�' => '┐',
  '�' => '└',
  '�' => '┴',
  '�' => '┬',
  '�' => '├',
  '�' => '─',
  '�' => '┼',
  '�' => '╞',
  '�' => '╟',
  '�' => '╚',
  '�' => '╔',
  '�' => '╩',
  '�' => '╦',
  '�' => '╠',
  '�' => '═',
  '�' => '╬',
  '�' => '╧',
  '�' => '╨',
  '�' => '╤',
  '�' => '╥',
  '�' => '╙',
  '�' => '╘',
  '�' => '╒',
  '�' => '╓',
  '�' => '╫',
  '�' => '╪',
  '�' => '┘',
  '�' => '┌',
  '�' => '█',
  '�' => '▄',
  '�' => '▌',
  '�' => '▐',
  '�' => '▀',
  '�' => 'α',
  '�' => 'ß',
  '�' => 'Γ',
  '�' => 'π',
  '�' => 'Σ',
  '�' => 'σ',
  '�' => 'µ',
  '�' => 'τ',
  '�' => 'Φ',
  '�' => 'Θ',
  '�' => 'Ω',
  '�' => 'δ',
  '�' => '∞',
  '�' => 'φ',
  '�' => 'ε',
  '�' => '∩',
  '�' => '≡',
  '�' => '±',
  '�' => '≥',
  '�' => '≤',
  '�' => '⌠',
  '�' => '⌡',
  '�' => '÷',
  '�' => '≈',
  '�' => '°',
  '�' => '∙',
  '�' => '·',
  '�' => '√',
  '�' => 'ⁿ',
  '�' => '²',
  '�' => '■',
  '�' => ' ',
);

$result =& $data;
unset($data);

return $result;
PKϤ$Z��c�ZZ4polyfill-iconv/Resources/charset/from.iso-8859-3.phpnu�[���<?php

static $data = array (
  '' => '',
  '' => '',
  '' => '',
  '' => '',
  '' => '',
  '' => '',
  '' => '',
  '' => '',
  '' => '',
  '	' => '	',
  '
' => '
',
  '' => '',
  '' => '',
  '
' => '
',
  '' => '',
  '' => '',
  '' => '',
  '' => '',
  '' => '',
  '' => '',
  '' => '',
  '' => '',
  '' => '',
  '' => '',
  '' => '',
  '' => '',
  '' => '',
  '' => '',
  '' => '',
  '' => '',
  '' => '',
  '' => '',
  ' ' => ' ',
  '!' => '!',
  '"' => '"',
  '#' => '#',
  '$' => '$',
  '%' => '%',
  '&' => '&',
  '\'' => '\'',
  '(' => '(',
  ')' => ')',
  '*' => '*',
  '+' => '+',
  ',' => ',',
  '-' => '-',
  '.' => '.',
  '/' => '/',
  0 => '0',
  1 => '1',
  2 => '2',
  3 => '3',
  4 => '4',
  5 => '5',
  6 => '6',
  7 => '7',
  8 => '8',
  9 => '9',
  ':' => ':',
  ';' => ';',
  '<' => '<',
  '=' => '=',
  '>' => '>',
  '?' => '?',
  '@' => '@',
  'A' => 'A',
  'B' => 'B',
  'C' => 'C',
  'D' => 'D',
  'E' => 'E',
  'F' => 'F',
  'G' => 'G',
  'H' => 'H',
  'I' => 'I',
  'J' => 'J',
  'K' => 'K',
  'L' => 'L',
  'M' => 'M',
  'N' => 'N',
  'O' => 'O',
  'P' => 'P',
  'Q' => 'Q',
  'R' => 'R',
  'S' => 'S',
  'T' => 'T',
  'U' => 'U',
  'V' => 'V',
  'W' => 'W',
  'X' => 'X',
  'Y' => 'Y',
  'Z' => 'Z',
  '[' => '[',
  '\\' => '\\',
  ']' => ']',
  '^' => '^',
  '_' => '_',
  '`' => '`',
  'a' => 'a',
  'b' => 'b',
  'c' => 'c',
  'd' => 'd',
  'e' => 'e',
  'f' => 'f',
  'g' => 'g',
  'h' => 'h',
  'i' => 'i',
  'j' => 'j',
  'k' => 'k',
  'l' => 'l',
  'm' => 'm',
  'n' => 'n',
  'o' => 'o',
  'p' => 'p',
  'q' => 'q',
  'r' => 'r',
  's' => 's',
  't' => 't',
  'u' => 'u',
  'v' => 'v',
  'w' => 'w',
  'x' => 'x',
  'y' => 'y',
  'z' => 'z',
  '{' => '{',
  '|' => '|',
  '}' => '}',
  '~' => '~',
  '' => '',
  '�' => '€',
  '�' => '',
  '�' => '‚',
  '�' => 'ƒ',
  '�' => '„',
  '�' => '…',
  '�' => '†',
  '�' => '‡',
  '�' => 'ˆ',
  '�' => '‰',
  '�' => 'Š',
  '�' => '‹',
  '�' => 'Œ',
  '�' => '',
  '�' => 'Ž',
  '�' => '',
  '�' => '',
  '�' => '‘',
  '�' => '’',
  '�' => '“',
  '�' => '”',
  '�' => '•',
  '�' => '–',
  '�' => '—',
  '�' => '˜',
  '�' => '™',
  '�' => 'š',
  '�' => '›',
  '�' => 'œ',
  '�' => '',
  '�' => 'ž',
  '�' => 'Ÿ',
  '�' => ' ',
  '�' => 'Ħ',
  '�' => '˘',
  '�' => '£',
  '�' => '¤',
  '�' => 'Ĥ',
  '�' => '§',
  '�' => '¨',
  '�' => 'İ',
  '�' => 'Ş',
  '�' => 'Ğ',
  '�' => 'Ĵ',
  '�' => '­',
  '�' => 'Ż',
  '�' => '°',
  '�' => 'ħ',
  '�' => '²',
  '�' => '³',
  '�' => '´',
  '�' => 'µ',
  '�' => 'ĥ',
  '�' => '·',
  '�' => '¸',
  '�' => 'ı',
  '�' => 'ş',
  '�' => 'ğ',
  '�' => 'ĵ',
  '�' => '½',
  '�' => 'ż',
  '�' => 'À',
  '�' => 'Á',
  '�' => 'Â',
  '�' => 'Ä',
  '�' => 'Ċ',
  '�' => 'Ĉ',
  '�' => 'Ç',
  '�' => 'È',
  '�' => 'É',
  '�' => 'Ê',
  '�' => 'Ë',
  '�' => 'Ì',
  '�' => 'Í',
  '�' => 'Î',
  '�' => 'Ï',
  '�' => 'Ñ',
  '�' => 'Ò',
  '�' => 'Ó',
  '�' => 'Ô',
  '�' => 'Ġ',
  '�' => 'Ö',
  '�' => '×',
  '�' => 'Ĝ',
  '�' => 'Ù',
  '�' => 'Ú',
  '�' => 'Û',
  '�' => 'Ü',
  '�' => 'Ŭ',
  '�' => 'Ŝ',
  '�' => 'ß',
  '�' => 'à',
  '�' => 'á',
  '�' => 'â',
  '�' => 'ä',
  '�' => 'ċ',
  '�' => 'ĉ',
  '�' => 'ç',
  '�' => 'è',
  '�' => 'é',
  '�' => 'ê',
  '�' => 'ë',
  '�' => 'ì',
  '�' => 'í',
  '�' => 'î',
  '�' => 'ï',
  '�' => 'ñ',
  '�' => 'ò',
  '�' => 'ó',
  '�' => 'ô',
  '�' => 'ġ',
  '�' => 'ö',
  '�' => '÷',
  '�' => 'ĝ',
  '�' => 'ù',
  '�' => 'ú',
  '�' => 'û',
  '�' => 'ü',
  '�' => 'ŭ',
  '�' => 'ŝ',
  '�' => '˙',
);

$result =& $data;
unset($data);

return $result;
PKϤ$Z�����4polyfill-iconv/Resources/charset/from.iso-8859-2.phpnu�[���<?php

static $data = array (
  '' => '',
  '' => '',
  '' => '',
  '' => '',
  '' => '',
  '' => '',
  '' => '',
  '' => '',
  '' => '',
  '	' => '	',
  '
' => '
',
  '' => '',
  '' => '',
  '
' => '
',
  '' => '',
  '' => '',
  '' => '',
  '' => '',
  '' => '',
  '' => '',
  '' => '',
  '' => '',
  '' => '',
  '' => '',
  '' => '',
  '' => '',
  '' => '',
  '' => '',
  '' => '',
  '' => '',
  '' => '',
  '' => '',
  ' ' => ' ',
  '!' => '!',
  '"' => '"',
  '#' => '#',
  '$' => '$',
  '%' => '%',
  '&' => '&',
  '\'' => '\'',
  '(' => '(',
  ')' => ')',
  '*' => '*',
  '+' => '+',
  ',' => ',',
  '-' => '-',
  '.' => '.',
  '/' => '/',
  0 => '0',
  1 => '1',
  2 => '2',
  3 => '3',
  4 => '4',
  5 => '5',
  6 => '6',
  7 => '7',
  8 => '8',
  9 => '9',
  ':' => ':',
  ';' => ';',
  '<' => '<',
  '=' => '=',
  '>' => '>',
  '?' => '?',
  '@' => '@',
  'A' => 'A',
  'B' => 'B',
  'C' => 'C',
  'D' => 'D',
  'E' => 'E',
  'F' => 'F',
  'G' => 'G',
  'H' => 'H',
  'I' => 'I',
  'J' => 'J',
  'K' => 'K',
  'L' => 'L',
  'M' => 'M',
  'N' => 'N',
  'O' => 'O',
  'P' => 'P',
  'Q' => 'Q',
  'R' => 'R',
  'S' => 'S',
  'T' => 'T',
  'U' => 'U',
  'V' => 'V',
  'W' => 'W',
  'X' => 'X',
  'Y' => 'Y',
  'Z' => 'Z',
  '[' => '[',
  '\\' => '\\',
  ']' => ']',
  '^' => '^',
  '_' => '_',
  '`' => '`',
  'a' => 'a',
  'b' => 'b',
  'c' => 'c',
  'd' => 'd',
  'e' => 'e',
  'f' => 'f',
  'g' => 'g',
  'h' => 'h',
  'i' => 'i',
  'j' => 'j',
  'k' => 'k',
  'l' => 'l',
  'm' => 'm',
  'n' => 'n',
  'o' => 'o',
  'p' => 'p',
  'q' => 'q',
  'r' => 'r',
  's' => 's',
  't' => 't',
  'u' => 'u',
  'v' => 'v',
  'w' => 'w',
  'x' => 'x',
  'y' => 'y',
  'z' => 'z',
  '{' => '{',
  '|' => '|',
  '}' => '}',
  '~' => '~',
  '' => '',
  '�' => '€',
  '�' => '',
  '�' => '‚',
  '�' => 'ƒ',
  '�' => '„',
  '�' => '…',
  '�' => '†',
  '�' => '‡',
  '�' => 'ˆ',
  '�' => '‰',
  '�' => 'Š',
  '�' => '‹',
  '�' => 'Œ',
  '�' => '',
  '�' => 'Ž',
  '�' => '',
  '�' => '',
  '�' => '‘',
  '�' => '’',
  '�' => '“',
  '�' => '”',
  '�' => '•',
  '�' => '–',
  '�' => '—',
  '�' => '˜',
  '�' => '™',
  '�' => 'š',
  '�' => '›',
  '�' => 'œ',
  '�' => '',
  '�' => 'ž',
  '�' => 'Ÿ',
  '�' => ' ',
  '�' => 'Ą',
  '�' => '˘',
  '�' => 'Ł',
  '�' => '¤',
  '�' => 'Ľ',
  '�' => 'Ś',
  '�' => '§',
  '�' => '¨',
  '�' => 'Š',
  '�' => 'Ş',
  '�' => 'Ť',
  '�' => 'Ź',
  '�' => '­',
  '�' => 'Ž',
  '�' => 'Ż',
  '�' => '°',
  '�' => 'ą',
  '�' => '˛',
  '�' => 'ł',
  '�' => '´',
  '�' => 'ľ',
  '�' => 'ś',
  '�' => 'ˇ',
  '�' => '¸',
  '�' => 'š',
  '�' => 'ş',
  '�' => 'ť',
  '�' => 'ź',
  '�' => '˝',
  '�' => 'ž',
  '�' => 'ż',
  '�' => 'Ŕ',
  '�' => 'Á',
  '�' => 'Â',
  '�' => 'Ă',
  '�' => 'Ä',
  '�' => 'Ĺ',
  '�' => 'Ć',
  '�' => 'Ç',
  '�' => 'Č',
  '�' => 'É',
  '�' => 'Ę',
  '�' => 'Ë',
  '�' => 'Ě',
  '�' => 'Í',
  '�' => 'Î',
  '�' => 'Ď',
  '�' => 'Đ',
  '�' => 'Ń',
  '�' => 'Ň',
  '�' => 'Ó',
  '�' => 'Ô',
  '�' => 'Ő',
  '�' => 'Ö',
  '�' => '×',
  '�' => 'Ř',
  '�' => 'Ů',
  '�' => 'Ú',
  '�' => 'Ű',
  '�' => 'Ü',
  '�' => 'Ý',
  '�' => 'Ţ',
  '�' => 'ß',
  '�' => 'ŕ',
  '�' => 'á',
  '�' => 'â',
  '�' => 'ă',
  '�' => 'ä',
  '�' => 'ĺ',
  '�' => 'ć',
  '�' => 'ç',
  '�' => 'č',
  '�' => 'é',
  '�' => 'ę',
  '�' => 'ë',
  '�' => 'ě',
  '�' => 'í',
  '�' => 'î',
  '�' => 'ď',
  '�' => 'đ',
  '�' => 'ń',
  '�' => 'ň',
  '�' => 'ó',
  '�' => 'ô',
  '�' => 'ő',
  '�' => 'ö',
  '�' => '÷',
  '�' => 'ř',
  '�' => 'ů',
  '�' => 'ú',
  '�' => 'ű',
  '�' => 'ü',
  '�' => 'ý',
  '�' => 'ţ',
  '�' => '˙',
);

$result =& $data;
unset($data);

return $result;
PKϤ$ZK��W/polyfill-iconv/Resources/charset/from.cp861.phpnu�[���<?php

static $data = array (
  '' => '',
  '' => '',
  '' => '',
  '' => '',
  '' => '',
  '' => '',
  '' => '',
  '' => '',
  '' => '',
  '	' => '	',
  '
' => '
',
  '' => '',
  '' => '',
  '
' => '
',
  '' => '',
  '' => '',
  '' => '',
  '' => '',
  '' => '',
  '' => '',
  '' => '',
  '' => '',
  '' => '',
  '' => '',
  '' => '',
  '' => '',
  '' => '',
  '' => '',
  '' => '',
  '' => '',
  '' => '',
  '' => '',
  ' ' => ' ',
  '!' => '!',
  '"' => '"',
  '#' => '#',
  '$' => '$',
  '%' => '%',
  '&' => '&',
  '\'' => '\'',
  '(' => '(',
  ')' => ')',
  '*' => '*',
  '+' => '+',
  ',' => ',',
  '-' => '-',
  '.' => '.',
  '/' => '/',
  0 => '0',
  1 => '1',
  2 => '2',
  3 => '3',
  4 => '4',
  5 => '5',
  6 => '6',
  7 => '7',
  8 => '8',
  9 => '9',
  ':' => ':',
  ';' => ';',
  '<' => '<',
  '=' => '=',
  '>' => '>',
  '?' => '?',
  '@' => '@',
  'A' => 'A',
  'B' => 'B',
  'C' => 'C',
  'D' => 'D',
  'E' => 'E',
  'F' => 'F',
  'G' => 'G',
  'H' => 'H',
  'I' => 'I',
  'J' => 'J',
  'K' => 'K',
  'L' => 'L',
  'M' => 'M',
  'N' => 'N',
  'O' => 'O',
  'P' => 'P',
  'Q' => 'Q',
  'R' => 'R',
  'S' => 'S',
  'T' => 'T',
  'U' => 'U',
  'V' => 'V',
  'W' => 'W',
  'X' => 'X',
  'Y' => 'Y',
  'Z' => 'Z',
  '[' => '[',
  '\\' => '\\',
  ']' => ']',
  '^' => '^',
  '_' => '_',
  '`' => '`',
  'a' => 'a',
  'b' => 'b',
  'c' => 'c',
  'd' => 'd',
  'e' => 'e',
  'f' => 'f',
  'g' => 'g',
  'h' => 'h',
  'i' => 'i',
  'j' => 'j',
  'k' => 'k',
  'l' => 'l',
  'm' => 'm',
  'n' => 'n',
  'o' => 'o',
  'p' => 'p',
  'q' => 'q',
  'r' => 'r',
  's' => 's',
  't' => 't',
  'u' => 'u',
  'v' => 'v',
  'w' => 'w',
  'x' => 'x',
  'y' => 'y',
  'z' => 'z',
  '{' => '{',
  '|' => '|',
  '}' => '}',
  '~' => '~',
  '' => '',
  '�' => 'Ç',
  '�' => 'ü',
  '�' => 'é',
  '�' => 'â',
  '�' => 'ä',
  '�' => 'à',
  '�' => 'å',
  '�' => 'ç',
  '�' => 'ê',
  '�' => 'ë',
  '�' => 'è',
  '�' => 'Ð',
  '�' => 'ð',
  '�' => 'Þ',
  '�' => 'Ä',
  '�' => 'Å',
  '�' => 'É',
  '�' => 'æ',
  '�' => 'Æ',
  '�' => 'ô',
  '�' => 'ö',
  '�' => 'þ',
  '�' => 'û',
  '�' => 'Ý',
  '�' => 'ý',
  '�' => 'Ö',
  '�' => 'Ü',
  '�' => 'ø',
  '�' => '£',
  '�' => 'Ø',
  '�' => '₧',
  '�' => 'ƒ',
  '�' => 'á',
  '�' => 'í',
  '�' => 'ó',
  '�' => 'ú',
  '�' => 'Á',
  '�' => 'Í',
  '�' => 'Ó',
  '�' => 'Ú',
  '�' => '¿',
  '�' => '⌐',
  '�' => '¬',
  '�' => '½',
  '�' => '¼',
  '�' => '¡',
  '�' => '«',
  '�' => '»',
  '�' => '░',
  '�' => '▒',
  '�' => '▓',
  '�' => '│',
  '�' => '┤',
  '�' => '╡',
  '�' => '╢',
  '�' => '╖',
  '�' => '╕',
  '�' => '╣',
  '�' => '║',
  '�' => '╗',
  '�' => '╝',
  '�' => '╜',
  '�' => '╛',
  '�' => '┐',
  '�' => '└',
  '�' => '┴',
  '�' => '┬',
  '�' => '├',
  '�' => '─',
  '�' => '┼',
  '�' => '╞',
  '�' => '╟',
  '�' => '╚',
  '�' => '╔',
  '�' => '╩',
  '�' => '╦',
  '�' => '╠',
  '�' => '═',
  '�' => '╬',
  '�' => '╧',
  '�' => '╨',
  '�' => '╤',
  '�' => '╥',
  '�' => '╙',
  '�' => '╘',
  '�' => '╒',
  '�' => '╓',
  '�' => '╫',
  '�' => '╪',
  '�' => '┘',
  '�' => '┌',
  '�' => '█',
  '�' => '▄',
  '�' => '▌',
  '�' => '▐',
  '�' => '▀',
  '�' => 'α',
  '�' => 'ß',
  '�' => 'Γ',
  '�' => 'π',
  '�' => 'Σ',
  '�' => 'σ',
  '�' => 'µ',
  '�' => 'τ',
  '�' => 'Φ',
  '�' => 'Θ',
  '�' => 'Ω',
  '�' => 'δ',
  '�' => '∞',
  '�' => 'φ',
  '�' => 'ε',
  '�' => '∩',
  '�' => '≡',
  '�' => '±',
  '�' => '≥',
  '�' => '≤',
  '�' => '⌠',
  '�' => '⌡',
  '�' => '÷',
  '�' => '≈',
  '�' => '°',
  '�' => '∙',
  '�' => '·',
  '�' => '√',
  '�' => 'ⁿ',
  '�' => '²',
  '�' => '■',
  '�' => ' ',
);

$result =& $data;
unset($data);

return $result;
PKϤ$Z���@~
~
6polyfill-iconv/Resources/charset/from.windows-1255.phpnu�[���<?php

static $data = array (
  '' => '',
  '' => '',
  '' => '',
  '' => '',
  '' => '',
  '' => '',
  '' => '',
  '' => '',
  '' => '',
  '	' => '	',
  '
' => '
',
  '' => '',
  '' => '',
  '
' => '
',
  '' => '',
  '' => '',
  '' => '',
  '' => '',
  '' => '',
  '' => '',
  '' => '',
  '' => '',
  '' => '',
  '' => '',
  '' => '',
  '' => '',
  '' => '',
  '' => '',
  '' => '',
  '' => '',
  '' => '',
  '' => '',
  ' ' => ' ',
  '!' => '!',
  '"' => '"',
  '#' => '#',
  '$' => '$',
  '%' => '%',
  '&' => '&',
  '\'' => '\'',
  '(' => '(',
  ')' => ')',
  '*' => '*',
  '+' => '+',
  ',' => ',',
  '-' => '-',
  '.' => '.',
  '/' => '/',
  0 => '0',
  1 => '1',
  2 => '2',
  3 => '3',
  4 => '4',
  5 => '5',
  6 => '6',
  7 => '7',
  8 => '8',
  9 => '9',
  ':' => ':',
  ';' => ';',
  '<' => '<',
  '=' => '=',
  '>' => '>',
  '?' => '?',
  '@' => '@',
  'A' => 'A',
  'B' => 'B',
  'C' => 'C',
  'D' => 'D',
  'E' => 'E',
  'F' => 'F',
  'G' => 'G',
  'H' => 'H',
  'I' => 'I',
  'J' => 'J',
  'K' => 'K',
  'L' => 'L',
  'M' => 'M',
  'N' => 'N',
  'O' => 'O',
  'P' => 'P',
  'Q' => 'Q',
  'R' => 'R',
  'S' => 'S',
  'T' => 'T',
  'U' => 'U',
  'V' => 'V',
  'W' => 'W',
  'X' => 'X',
  'Y' => 'Y',
  'Z' => 'Z',
  '[' => '[',
  '\\' => '\\',
  ']' => ']',
  '^' => '^',
  '_' => '_',
  '`' => '`',
  'a' => 'a',
  'b' => 'b',
  'c' => 'c',
  'd' => 'd',
  'e' => 'e',
  'f' => 'f',
  'g' => 'g',
  'h' => 'h',
  'i' => 'i',
  'j' => 'j',
  'k' => 'k',
  'l' => 'l',
  'm' => 'm',
  'n' => 'n',
  'o' => 'o',
  'p' => 'p',
  'q' => 'q',
  'r' => 'r',
  's' => 's',
  't' => 't',
  'u' => 'u',
  'v' => 'v',
  'w' => 'w',
  'x' => 'x',
  'y' => 'y',
  'z' => 'z',
  '{' => '{',
  '|' => '|',
  '}' => '}',
  '~' => '~',
  '' => '',
  '�' => '€',
  '�' => '‚',
  '�' => 'ƒ',
  '�' => '„',
  '�' => '…',
  '�' => '†',
  '�' => '‡',
  '�' => 'ˆ',
  '�' => '‰',
  '�' => '‹',
  '�' => '‘',
  '�' => '’',
  '�' => '“',
  '�' => '”',
  '�' => '•',
  '�' => '–',
  '�' => '—',
  '�' => '˜',
  '�' => '™',
  '�' => '›',
  '�' => ' ',
  '�' => '¡',
  '�' => '¢',
  '�' => '£',
  '�' => '₪',
  '�' => '¥',
  '�' => '¦',
  '�' => '§',
  '�' => '¨',
  '�' => '©',
  '�' => '×',
  '�' => '«',
  '�' => '¬',
  '�' => '­',
  '�' => '®',
  '�' => '¯',
  '�' => '°',
  '�' => '±',
  '�' => '²',
  '�' => '³',
  '�' => '´',
  '�' => 'µ',
  '�' => '¶',
  '�' => '·',
  '�' => '¸',
  '�' => '¹',
  '�' => '÷',
  '�' => '»',
  '�' => '¼',
  '�' => '½',
  '�' => '¾',
  '�' => '¿',
  '�' => 'ְ',
  '�' => 'ֱ',
  '�' => 'ֲ',
  '�' => 'ֳ',
  '�' => 'ִ',
  '�' => 'ֵ',
  '�' => 'ֶ',
  '�' => 'ַ',
  '�' => 'ָ',
  '�' => 'ֹ',
  '�' => 'ֻ',
  '�' => 'ּ',
  '�' => 'ֽ',
  '�' => '־',
  '�' => 'ֿ',
  '�' => '׀',
  '�' => 'ׁ',
  '�' => 'ׂ',
  '�' => '׃',
  '�' => 'װ',
  '�' => 'ױ',
  '�' => 'ײ',
  '�' => '׳',
  '�' => '״',
  '�' => 'א',
  '�' => 'ב',
  '�' => 'ג',
  '�' => 'ד',
  '�' => 'ה',
  '�' => 'ו',
  '�' => 'ז',
  '�' => 'ח',
  '�' => 'ט',
  '�' => 'י',
  '�' => 'ך',
  '�' => 'כ',
  '�' => 'ל',
  '�' => 'ם',
  '�' => 'מ',
  '�' => 'ן',
  '�' => 'נ',
  '�' => 'ס',
  '�' => 'ע',
  '�' => 'ף',
  '�' => 'פ',
  '�' => 'ץ',
  '�' => 'צ',
  '�' => 'ק',
  '�' => 'ר',
  '�' => 'ש',
  '�' => 'ת',
  '�' => '‎',
  '�' => '‏',
);

$result =& $data;
unset($data);

return $result;
PKϤ$Z�>��/polyfill-iconv/Resources/charset/from.cp860.phpnu�[���<?php

static $data = array (
  '' => '',
  '' => '',
  '' => '',
  '' => '',
  '' => '',
  '' => '',
  '' => '',
  '' => '',
  '' => '',
  '	' => '	',
  '
' => '
',
  '' => '',
  '' => '',
  '
' => '
',
  '' => '',
  '' => '',
  '' => '',
  '' => '',
  '' => '',
  '' => '',
  '' => '',
  '' => '',
  '' => '',
  '' => '',
  '' => '',
  '' => '',
  '' => '',
  '' => '',
  '' => '',
  '' => '',
  '' => '',
  '' => '',
  ' ' => ' ',
  '!' => '!',
  '"' => '"',
  '#' => '#',
  '$' => '$',
  '%' => '%',
  '&' => '&',
  '\'' => '\'',
  '(' => '(',
  ')' => ')',
  '*' => '*',
  '+' => '+',
  ',' => ',',
  '-' => '-',
  '.' => '.',
  '/' => '/',
  0 => '0',
  1 => '1',
  2 => '2',
  3 => '3',
  4 => '4',
  5 => '5',
  6 => '6',
  7 => '7',
  8 => '8',
  9 => '9',
  ':' => ':',
  ';' => ';',
  '<' => '<',
  '=' => '=',
  '>' => '>',
  '?' => '?',
  '@' => '@',
  'A' => 'A',
  'B' => 'B',
  'C' => 'C',
  'D' => 'D',
  'E' => 'E',
  'F' => 'F',
  'G' => 'G',
  'H' => 'H',
  'I' => 'I',
  'J' => 'J',
  'K' => 'K',
  'L' => 'L',
  'M' => 'M',
  'N' => 'N',
  'O' => 'O',
  'P' => 'P',
  'Q' => 'Q',
  'R' => 'R',
  'S' => 'S',
  'T' => 'T',
  'U' => 'U',
  'V' => 'V',
  'W' => 'W',
  'X' => 'X',
  'Y' => 'Y',
  'Z' => 'Z',
  '[' => '[',
  '\\' => '\\',
  ']' => ']',
  '^' => '^',
  '_' => '_',
  '`' => '`',
  'a' => 'a',
  'b' => 'b',
  'c' => 'c',
  'd' => 'd',
  'e' => 'e',
  'f' => 'f',
  'g' => 'g',
  'h' => 'h',
  'i' => 'i',
  'j' => 'j',
  'k' => 'k',
  'l' => 'l',
  'm' => 'm',
  'n' => 'n',
  'o' => 'o',
  'p' => 'p',
  'q' => 'q',
  'r' => 'r',
  's' => 's',
  't' => 't',
  'u' => 'u',
  'v' => 'v',
  'w' => 'w',
  'x' => 'x',
  'y' => 'y',
  'z' => 'z',
  '{' => '{',
  '|' => '|',
  '}' => '}',
  '~' => '~',
  '' => '',
  '�' => 'Ç',
  '�' => 'ü',
  '�' => 'é',
  '�' => 'â',
  '�' => 'ã',
  '�' => 'à',
  '�' => 'Á',
  '�' => 'ç',
  '�' => 'ê',
  '�' => 'Ê',
  '�' => 'è',
  '�' => 'Í',
  '�' => 'Ô',
  '�' => 'ì',
  '�' => 'Ã',
  '�' => 'Â',
  '�' => 'É',
  '�' => 'À',
  '�' => 'È',
  '�' => 'ô',
  '�' => 'õ',
  '�' => 'ò',
  '�' => 'Ú',
  '�' => 'ù',
  '�' => 'Ì',
  '�' => 'Õ',
  '�' => 'Ü',
  '�' => '¢',
  '�' => '£',
  '�' => 'Ù',
  '�' => '₧',
  '�' => 'Ó',
  '�' => 'á',
  '�' => 'í',
  '�' => 'ó',
  '�' => 'ú',
  '�' => 'ñ',
  '�' => 'Ñ',
  '�' => 'ª',
  '�' => 'º',
  '�' => '¿',
  '�' => 'Ò',
  '�' => '¬',
  '�' => '½',
  '�' => '¼',
  '�' => '¡',
  '�' => '«',
  '�' => '»',
  '�' => '░',
  '�' => '▒',
  '�' => '▓',
  '�' => '│',
  '�' => '┤',
  '�' => '╡',
  '�' => '╢',
  '�' => '╖',
  '�' => '╕',
  '�' => '╣',
  '�' => '║',
  '�' => '╗',
  '�' => '╝',
  '�' => '╜',
  '�' => '╛',
  '�' => '┐',
  '�' => '└',
  '�' => '┴',
  '�' => '┬',
  '�' => '├',
  '�' => '─',
  '�' => '┼',
  '�' => '╞',
  '�' => '╟',
  '�' => '╚',
  '�' => '╔',
  '�' => '╩',
  '�' => '╦',
  '�' => '╠',
  '�' => '═',
  '�' => '╬',
  '�' => '╧',
  '�' => '╨',
  '�' => '╤',
  '�' => '╥',
  '�' => '╙',
  '�' => '╘',
  '�' => '╒',
  '�' => '╓',
  '�' => '╫',
  '�' => '╪',
  '�' => '┘',
  '�' => '┌',
  '�' => '█',
  '�' => '▄',
  '�' => '▌',
  '�' => '▐',
  '�' => '▀',
  '�' => 'α',
  '�' => 'ß',
  '�' => 'Γ',
  '�' => 'π',
  '�' => 'Σ',
  '�' => 'σ',
  '�' => 'µ',
  '�' => 'τ',
  '�' => 'Φ',
  '�' => 'Θ',
  '�' => 'Ω',
  '�' => 'δ',
  '�' => '∞',
  '�' => 'φ',
  '�' => 'ε',
  '�' => '∩',
  '�' => '≡',
  '�' => '±',
  '�' => '≥',
  '�' => '≤',
  '�' => '⌠',
  '�' => '⌡',
  '�' => '÷',
  '�' => '≈',
  '�' => '°',
  '�' => '∙',
  '�' => '·',
  '�' => '√',
  '�' => 'ⁿ',
  '�' => '²',
  '�' => '■',
  '�' => ' ',
);

$result =& $data;
unset($data);

return $result;
PKϤ$Z�>2�!�!-polyfill-iconv/Resources/charset/translit.phpnu�[���<?php

return array (
  'µ' => 'μ',
  '¼' => ' 1⁄4 ',
  '½' => ' 1⁄2 ',
  '¾' => ' 3⁄4 ',
  'IJ' => 'IJ',
  'ij' => 'ij',
  'Ŀ' => 'L·',
  'ŀ' => 'l·',
  'ʼn' => 'ʼn',
  'ſ' => 's',
  'DŽ' => 'DŽ',
  'Dž' => 'Dž',
  'dž' => 'dž',
  'LJ' => 'LJ',
  'Lj' => 'Lj',
  'lj' => 'lj',
  'NJ' => 'NJ',
  'Nj' => 'Nj',
  'nj' => 'nj',
  'DZ' => 'DZ',
  'Dz' => 'Dz',
  'dz' => 'dz',
  'ϐ' => 'β',
  'ϑ' => 'θ',
  'ϒ' => 'Υ',
  'ϕ' => 'φ',
  'ϖ' => 'π',
  'ϰ' => 'κ',
  'ϱ' => 'ρ',
  'ϲ' => 'ς',
  'ϴ' => 'Θ',
  'ϵ' => 'ε',
  'Ϲ' => 'Σ',
  'և' => 'եւ',
  'ٵ' => 'اٴ',
  'ٶ' => 'وٴ',
  'ٷ' => 'ۇٴ',
  'ٸ' => 'يٴ',
  'ำ' => 'ํา',
  'ຳ' => 'ໍາ',
  'ໜ' => 'ຫນ',
  'ໝ' => 'ຫມ',
  'ཷ' => 'ྲཱྀ',
  'ཹ' => 'ླཱྀ',
  'ẚ' => 'aʾ',
  '․' => '.',
  '‥' => '..',
  '…' => '...',
  '″' => '′′',
  '‴' => '′′′',
  '‶' => '‵‵',
  '‷' => '‵‵‵',
  '‼' => '!!',
  '⁇' => '??',
  '⁈' => '?!',
  '⁉' => '!?',
  '⁗' => '′′′′',
  '₨' => 'Rs',
  '℀' => 'a/c',
  '℁' => 'a/s',
  'ℂ' => 'C',
  '℃' => '°C',
  '℅' => 'c/o',
  '℆' => 'c/u',
  'ℇ' => 'Ɛ',
  '℉' => '°F',
  'ℊ' => 'g',
  'ℋ' => 'H',
  'ℌ' => 'H',
  'ℍ' => 'H',
  'ℎ' => 'h',
  'ℏ' => 'ħ',
  'ℐ' => 'I',
  'ℑ' => 'I',
  'ℒ' => 'L',
  'ℓ' => 'l',
  'ℕ' => 'N',
  '№' => 'No',
  'ℙ' => 'P',
  'ℚ' => 'Q',
  'ℛ' => 'R',
  'ℜ' => 'R',
  'ℝ' => 'R',
  '℡' => 'TEL',
  'ℤ' => 'Z',
  'ℨ' => 'Z',
  'ℬ' => 'B',
  'ℭ' => 'C',
  'ℯ' => 'e',
  'ℰ' => 'E',
  'ℱ' => 'F',
  'ℳ' => 'M',
  'ℴ' => 'o',
  'ℵ' => 'א',
  'ℶ' => 'ב',
  'ℷ' => 'ג',
  'ℸ' => 'ד',
  'ℹ' => 'i',
  '℻' => 'FAX',
  'ℼ' => 'π',
  'ℽ' => 'γ',
  'ℾ' => 'Γ',
  'ℿ' => 'Π',
  '⅀' => '∑',
  'ⅅ' => 'D',
  'ⅆ' => 'd',
  'ⅇ' => 'e',
  'ⅈ' => 'i',
  'ⅉ' => 'j',
  '⅐' => ' 1⁄7 ',
  '⅑' => ' 1⁄9 ',
  '⅒' => ' 1⁄10 ',
  '⅓' => ' 1⁄3 ',
  '⅔' => ' 2⁄3 ',
  '⅕' => ' 1⁄5 ',
  '⅖' => ' 2⁄5 ',
  '⅗' => ' 3⁄5 ',
  '⅘' => ' 4⁄5 ',
  '⅙' => ' 1⁄6 ',
  '⅚' => ' 5⁄6 ',
  '⅛' => ' 1⁄8 ',
  '⅜' => ' 3⁄8 ',
  '⅝' => ' 5⁄8 ',
  '⅞' => ' 7⁄8 ',
  '⅟' => ' 1⁄ ',
  'Ⅰ' => 'I',
  'Ⅱ' => 'II',
  'Ⅲ' => 'III',
  'Ⅳ' => 'IV',
  'Ⅴ' => 'V',
  'Ⅵ' => 'VI',
  'Ⅶ' => 'VII',
  'Ⅷ' => 'VIII',
  'Ⅸ' => 'IX',
  'Ⅹ' => 'X',
  'Ⅺ' => 'XI',
  'Ⅻ' => 'XII',
  'Ⅼ' => 'L',
  'Ⅽ' => 'C',
  'Ⅾ' => 'D',
  'Ⅿ' => 'M',
  'ⅰ' => 'i',
  'ⅱ' => 'ii',
  'ⅲ' => 'iii',
  'ⅳ' => 'iv',
  'ⅴ' => 'v',
  'ⅵ' => 'vi',
  'ⅶ' => 'vii',
  'ⅷ' => 'viii',
  'ⅸ' => 'ix',
  'ⅹ' => 'x',
  'ⅺ' => 'xi',
  'ⅻ' => 'xii',
  'ⅼ' => 'l',
  'ⅽ' => 'c',
  'ⅾ' => 'd',
  'ⅿ' => 'm',
  '↉' => ' 0⁄3 ',
  '∬' => '∫∫',
  '∭' => '∫∫∫',
  '∯' => '∮∮',
  '∰' => '∮∮∮',
  '①' => '(1)',
  '②' => '(2)',
  '③' => '(3)',
  '④' => '(4)',
  '⑤' => '(5)',
  '⑥' => '(6)',
  '⑦' => '(7)',
  '⑧' => '(8)',
  '⑨' => '(9)',
  '⑩' => '(10)',
  '⑪' => '(11)',
  '⑫' => '(12)',
  '⑬' => '(13)',
  '⑭' => '(14)',
  '⑮' => '(15)',
  '⑯' => '(16)',
  '⑰' => '(17)',
  '⑱' => '(18)',
  '⑲' => '(19)',
  '⑳' => '(20)',
  '⑴' => '(1)',
  '⑵' => '(2)',
  '⑶' => '(3)',
  '⑷' => '(4)',
  '⑸' => '(5)',
  '⑹' => '(6)',
  '⑺' => '(7)',
  '⑻' => '(8)',
  '⑼' => '(9)',
  '⑽' => '(10)',
  '⑾' => '(11)',
  '⑿' => '(12)',
  '⒀' => '(13)',
  '⒁' => '(14)',
  '⒂' => '(15)',
  '⒃' => '(16)',
  '⒄' => '(17)',
  '⒅' => '(18)',
  '⒆' => '(19)',
  '⒇' => '(20)',
  '⒈' => '1.',
  '⒉' => '2.',
  '⒊' => '3.',
  '⒋' => '4.',
  '⒌' => '5.',
  '⒍' => '6.',
  '⒎' => '7.',
  '⒏' => '8.',
  '⒐' => '9.',
  '⒑' => '10.',
  '⒒' => '11.',
  '⒓' => '12.',
  '⒔' => '13.',
  '⒕' => '14.',
  '⒖' => '15.',
  '⒗' => '16.',
  '⒘' => '17.',
  '⒙' => '18.',
  '⒚' => '19.',
  '⒛' => '20.',
  '⒜' => '(a)',
  '⒝' => '(b)',
  '⒞' => '(c)',
  '⒟' => '(d)',
  '⒠' => '(e)',
  '⒡' => '(f)',
  '⒢' => '(g)',
  '⒣' => '(h)',
  '⒤' => '(i)',
  '⒥' => '(j)',
  '⒦' => '(k)',
  '⒧' => '(l)',
  '⒨' => '(m)',
  '⒩' => '(n)',
  '⒪' => '(o)',
  '⒫' => '(p)',
  '⒬' => '(q)',
  '⒭' => '(r)',
  '⒮' => '(s)',
  '⒯' => '(t)',
  '⒰' => '(u)',
  '⒱' => '(v)',
  '⒲' => '(w)',
  '⒳' => '(x)',
  '⒴' => '(y)',
  '⒵' => '(z)',
  'Ⓐ' => '(A)',
  'Ⓑ' => '(B)',
  'Ⓒ' => '(C)',
  'Ⓓ' => '(D)',
  'Ⓔ' => '(E)',
  'Ⓕ' => '(F)',
  'Ⓖ' => '(G)',
  'Ⓗ' => '(H)',
  'Ⓘ' => '(I)',
  'Ⓙ' => '(J)',
  'Ⓚ' => '(K)',
  'Ⓛ' => '(L)',
  'Ⓜ' => '(M)',
  'Ⓝ' => '(N)',
  'Ⓞ' => '(O)',
  'Ⓟ' => '(P)',
  'Ⓠ' => '(Q)',
  'Ⓡ' => '(R)',
  'Ⓢ' => '(S)',
  'Ⓣ' => '(T)',
  'Ⓤ' => '(U)',
  'Ⓥ' => '(V)',
  'Ⓦ' => '(W)',
  'Ⓧ' => '(X)',
  'Ⓨ' => '(Y)',
  'Ⓩ' => '(Z)',
  'ⓐ' => '(a)',
  'ⓑ' => '(b)',
  'ⓒ' => '(c)',
  'ⓓ' => '(d)',
  'ⓔ' => '(e)',
  'ⓕ' => '(f)',
  'ⓖ' => '(g)',
  'ⓗ' => '(h)',
  'ⓘ' => '(i)',
  'ⓙ' => '(j)',
  'ⓚ' => '(k)',
  'ⓛ' => '(l)',
  'ⓜ' => '(m)',
  'ⓝ' => '(n)',
  'ⓞ' => '(o)',
  'ⓟ' => '(p)',
  'ⓠ' => '(q)',
  'ⓡ' => '(r)',
  'ⓢ' => '(s)',
  'ⓣ' => '(t)',
  'ⓤ' => '(u)',
  'ⓥ' => '(v)',
  'ⓦ' => '(w)',
  'ⓧ' => '(x)',
  'ⓨ' => '(y)',
  'ⓩ' => '(z)',
  '⓪' => '(0)',
  '⨌' => '∫∫∫∫',
  '⩴' => '::=',
  '⩵' => '==',
  '⩶' => '===',
  '⺟' => '母',
  '⻳' => '龟',
  '⼀' => '一',
  '⼁' => '丨',
  '⼂' => '丶',
  '⼃' => '丿',
  '⼄' => '乙',
  '⼅' => '亅',
  '⼆' => '二',
  '⼇' => '亠',
  '⼈' => '人',
  '⼉' => '儿',
  '⼊' => '入',
  '⼋' => '八',
  '⼌' => '冂',
  '⼍' => '冖',
  '⼎' => '冫',
  '⼏' => '几',
  '⼐' => '凵',
  '⼑' => '刀',
  '⼒' => '力',
  '⼓' => '勹',
  '⼔' => '匕',
  '⼕' => '匚',
  '⼖' => '匸',
  '⼗' => '十',
  '⼘' => '卜',
  '⼙' => '卩',
  '⼚' => '厂',
  '⼛' => '厶',
  '⼜' => '又',
  '⼝' => '口',
  '⼞' => '囗',
  '⼟' => '土',
  '⼠' => '士',
  '⼡' => '夂',
  '⼢' => '夊',
  '⼣' => '夕',
  '⼤' => '大',
  '⼥' => '女',
  '⼦' => '子',
  '⼧' => '宀',
  '⼨' => '寸',
  '⼩' => '小',
  '⼪' => '尢',
  '⼫' => '尸',
  '⼬' => '屮',
  '⼭' => '山',
  '⼮' => '巛',
  '⼯' => '工',
  '⼰' => '己',
  '⼱' => '巾',
  '⼲' => '干',
  '⼳' => '幺',
  '⼴' => '广',
  '⼵' => '廴',
  '⼶' => '廾',
  '⼷' => '弋',
  '⼸' => '弓',
  '⼹' => '彐',
  '⼺' => '彡',
  '⼻' => '彳',
  '⼼' => '心',
  '⼽' => '戈',
  '⼾' => '戶',
  '⼿' => '手',
  '⽀' => '支',
  '⽁' => '攴',
  '⽂' => '文',
  '⽃' => '斗',
  '⽄' => '斤',
  '⽅' => '方',
  '⽆' => '无',
  '⽇' => '日',
  '⽈' => '曰',
  '⽉' => '月',
  '⽊' => '木',
  '⽋' => '欠',
  '⽌' => '止',
  '⽍' => '歹',
  '⽎' => '殳',
  '⽏' => '毋',
  '⽐' => '比',
  '⽑' => '毛',
  '⽒' => '氏',
  '⽓' => '气',
  '⽔' => '水',
  '⽕' => '火',
  '⽖' => '爪',
  '⽗' => '父',
  '⽘' => '爻',
  '⽙' => '爿',
  '⽚' => '片',
  '⽛' => '牙',
  '⽜' => '牛',
  '⽝' => '犬',
  '⽞' => '玄',
  '⽟' => '玉',
  '⽠' => '瓜',
  '⽡' => '瓦',
  '⽢' => '甘',
  '⽣' => '生',
  '⽤' => '用',
  '⽥' => '田',
  '⽦' => '疋',
  '⽧' => '疒',
  '⽨' => '癶',
  '⽩' => '白',
  '⽪' => '皮',
  '⽫' => '皿',
  '⽬' => '目',
  '⽭' => '矛',
  '⽮' => '矢',
  '⽯' => '石',
  '⽰' => '示',
  '⽱' => '禸',
  '⽲' => '禾',
  '⽳' => '穴',
  '⽴' => '立',
  '⽵' => '竹',
  '⽶' => '米',
  '⽷' => '糸',
  '⽸' => '缶',
  '⽹' => '网',
  '⽺' => '羊',
  '⽻' => '羽',
  '⽼' => '老',
  '⽽' => '而',
  '⽾' => '耒',
  '⽿' => '耳',
  '⾀' => '聿',
  '⾁' => '肉',
  '⾂' => '臣',
  '⾃' => '自',
  '⾄' => '至',
  '⾅' => '臼',
  '⾆' => '舌',
  '⾇' => '舛',
  '⾈' => '舟',
  '⾉' => '艮',
  '⾊' => '色',
  '⾋' => '艸',
  '⾌' => '虍',
  '⾍' => '虫',
  '⾎' => '血',
  '⾏' => '行',
  '⾐' => '衣',
  '⾑' => '襾',
  '⾒' => '見',
  '⾓' => '角',
  '⾔' => '言',
  '⾕' => '谷',
  '⾖' => '豆',
  '⾗' => '豕',
  '⾘' => '豸',
  '⾙' => '貝',
  '⾚' => '赤',
  '⾛' => '走',
  '⾜' => '足',
  '⾝' => '身',
  '⾞' => '車',
  '⾟' => '辛',
  '⾠' => '辰',
  '⾡' => '辵',
  '⾢' => '邑',
  '⾣' => '酉',
  '⾤' => '釆',
  '⾥' => '里',
  '⾦' => '金',
  '⾧' => '長',
  '⾨' => '門',
  '⾩' => '阜',
  '⾪' => '隶',
  '⾫' => '隹',
  '⾬' => '雨',
  '⾭' => '靑',
  '⾮' => '非',
  '⾯' => '面',
  '⾰' => '革',
  '⾱' => '韋',
  '⾲' => '韭',
  '⾳' => '音',
  '⾴' => '頁',
  '⾵' => '風',
  '⾶' => '飛',
  '⾷' => '食',
  '⾸' => '首',
  '⾹' => '香',
  '⾺' => '馬',
  '⾻' => '骨',
  '⾼' => '高',
  '⾽' => '髟',
  '⾾' => '鬥',
  '⾿' => '鬯',
  '⿀' => '鬲',
  '⿁' => '鬼',
  '⿂' => '魚',
  '⿃' => '鳥',
  '⿄' => '鹵',
  '⿅' => '鹿',
  '⿆' => '麥',
  '⿇' => '麻',
  '⿈' => '黃',
  '⿉' => '黍',
  '⿊' => '黑',
  '⿋' => '黹',
  '⿌' => '黽',
  '⿍' => '鼎',
  '⿎' => '鼓',
  '⿏' => '鼠',
  '⿐' => '鼻',
  '⿑' => '齊',
  '⿒' => '齒',
  '⿓' => '龍',
  '⿔' => '龜',
  '⿕' => '龠',
  ' ' => ' ',
  '〶' => '〒',
  '〸' => '十',
  '〹' => '卄',
  '〺' => '卅',
  'ㄱ' => 'ᄀ',
  'ㄲ' => 'ᄁ',
  'ㄳ' => 'ᆪ',
  'ㄴ' => 'ᄂ',
  'ㄵ' => 'ᆬ',
  'ㄶ' => 'ᆭ',
  'ㄷ' => 'ᄃ',
  'ㄸ' => 'ᄄ',
  'ㄹ' => 'ᄅ',
  'ㄺ' => 'ᆰ',
  'ㄻ' => 'ᆱ',
  'ㄼ' => 'ᆲ',
  'ㄽ' => 'ᆳ',
  'ㄾ' => 'ᆴ',
  'ㄿ' => 'ᆵ',
  'ㅀ' => 'ᄚ',
  'ㅁ' => 'ᄆ',
  'ㅂ' => 'ᄇ',
  'ㅃ' => 'ᄈ',
  'ㅄ' => 'ᄡ',
  'ㅅ' => 'ᄉ',
  'ㅆ' => 'ᄊ',
  'ㅇ' => 'ᄋ',
  'ㅈ' => 'ᄌ',
  'ㅉ' => 'ᄍ',
  'ㅊ' => 'ᄎ',
  'ㅋ' => 'ᄏ',
  'ㅌ' => 'ᄐ',
  'ㅍ' => 'ᄑ',
  'ㅎ' => 'ᄒ',
  'ㅏ' => 'ᅡ',
  'ㅐ' => 'ᅢ',
  'ㅑ' => 'ᅣ',
  'ㅒ' => 'ᅤ',
  'ㅓ' => 'ᅥ',
  'ㅔ' => 'ᅦ',
  'ㅕ' => 'ᅧ',
  'ㅖ' => 'ᅨ',
  'ㅗ' => 'ᅩ',
  'ㅘ' => 'ᅪ',
  'ㅙ' => 'ᅫ',
  'ㅚ' => 'ᅬ',
  'ㅛ' => 'ᅭ',
  'ㅜ' => 'ᅮ',
  'ㅝ' => 'ᅯ',
  'ㅞ' => 'ᅰ',
  'ㅟ' => 'ᅱ',
  'ㅠ' => 'ᅲ',
  'ㅡ' => 'ᅳ',
  'ㅢ' => 'ᅴ',
  'ㅣ' => 'ᅵ',
  'ㅤ' => 'ᅠ',
  'ㅥ' => 'ᄔ',
  'ㅦ' => 'ᄕ',
  'ㅧ' => 'ᇇ',
  'ㅨ' => 'ᇈ',
  'ㅩ' => 'ᇌ',
  'ㅪ' => 'ᇎ',
  'ㅫ' => 'ᇓ',
  'ㅬ' => 'ᇗ',
  'ㅭ' => 'ᇙ',
  'ㅮ' => 'ᄜ',
  'ㅯ' => 'ᇝ',
  'ㅰ' => 'ᇟ',
  'ㅱ' => 'ᄝ',
  'ㅲ' => 'ᄞ',
  'ㅳ' => 'ᄠ',
  'ㅴ' => 'ᄢ',
  'ㅵ' => 'ᄣ',
  'ㅶ' => 'ᄧ',
  'ㅷ' => 'ᄩ',
  'ㅸ' => 'ᄫ',
  'ㅹ' => 'ᄬ',
  'ㅺ' => 'ᄭ',
  'ㅻ' => 'ᄮ',
  'ㅼ' => 'ᄯ',
  'ㅽ' => 'ᄲ',
  'ㅾ' => 'ᄶ',
  'ㅿ' => 'ᅀ',
  'ㆀ' => 'ᅇ',
  'ㆁ' => 'ᅌ',
  'ㆂ' => 'ᇱ',
  'ㆃ' => 'ᇲ',
  'ㆄ' => 'ᅗ',
  'ㆅ' => 'ᅘ',
  'ㆆ' => 'ᅙ',
  'ㆇ' => 'ᆄ',
  'ㆈ' => 'ᆅ',
  'ㆉ' => 'ᆈ',
  'ㆊ' => 'ᆑ',
  'ㆋ' => 'ᆒ',
  'ㆌ' => 'ᆔ',
  'ㆍ' => 'ᆞ',
  'ㆎ' => 'ᆡ',
  '㈀' => '(ᄀ)',
  '㈁' => '(ᄂ)',
  '㈂' => '(ᄃ)',
  '㈃' => '(ᄅ)',
  '㈄' => '(ᄆ)',
  '㈅' => '(ᄇ)',
  '㈆' => '(ᄉ)',
  '㈇' => '(ᄋ)',
  '㈈' => '(ᄌ)',
  '㈉' => '(ᄎ)',
  '㈊' => '(ᄏ)',
  '㈋' => '(ᄐ)',
  '㈌' => '(ᄑ)',
  '㈍' => '(ᄒ)',
  '㈎' => '(가)',
  '㈏' => '(나)',
  '㈐' => '(다)',
  '㈑' => '(라)',
  '㈒' => '(마)',
  '㈓' => '(바)',
  '㈔' => '(사)',
  '㈕' => '(아)',
  '㈖' => '(자)',
  '㈗' => '(차)',
  '㈘' => '(카)',
  '㈙' => '(타)',
  '㈚' => '(파)',
  '㈛' => '(하)',
  '㈜' => '(주)',
  '㈝' => '(오전)',
  '㈞' => '(오후)',
  '㈠' => '(一)',
  '㈡' => '(二)',
  '㈢' => '(三)',
  '㈣' => '(四)',
  '㈤' => '(五)',
  '㈥' => '(六)',
  '㈦' => '(七)',
  '㈧' => '(八)',
  '㈨' => '(九)',
  '㈩' => '(十)',
  '㈪' => '(月)',
  '㈫' => '(火)',
  '㈬' => '(水)',
  '㈭' => '(木)',
  '㈮' => '(金)',
  '㈯' => '(土)',
  '㈰' => '(日)',
  '㈱' => '(株)',
  '㈲' => '(有)',
  '㈳' => '(社)',
  '㈴' => '(名)',
  '㈵' => '(特)',
  '㈶' => '(財)',
  '㈷' => '(祝)',
  '㈸' => '(労)',
  '㈹' => '(代)',
  '㈺' => '(呼)',
  '㈻' => '(学)',
  '㈼' => '(監)',
  '㈽' => '(企)',
  '㈾' => '(資)',
  '㈿' => '(協)',
  '㉀' => '(祭)',
  '㉁' => '(休)',
  '㉂' => '(自)',
  '㉃' => '(至)',
  '㉄' => '(問)',
  '㉅' => '(幼)',
  '㉆' => '(文)',
  '㉇' => '(箏)',
  '㉐' => 'PTE',
  '㉑' => '(21)',
  '㉒' => '(22)',
  '㉓' => '(23)',
  '㉔' => '(24)',
  '㉕' => '(25)',
  '㉖' => '(26)',
  '㉗' => '(27)',
  '㉘' => '(28)',
  '㉙' => '(29)',
  '㉚' => '(30)',
  '㉛' => '(31)',
  '㉜' => '(32)',
  '㉝' => '(33)',
  '㉞' => '(34)',
  '㉟' => '(35)',
  '㉠' => '(ᄀ)',
  '㉡' => '(ᄂ)',
  '㉢' => '(ᄃ)',
  '㉣' => '(ᄅ)',
  '㉤' => '(ᄆ)',
  '㉥' => '(ᄇ)',
  '㉦' => '(ᄉ)',
  '㉧' => '(ᄋ)',
  '㉨' => '(ᄌ)',
  '㉩' => '(ᄎ)',
  '㉪' => '(ᄏ)',
  '㉫' => '(ᄐ)',
  '㉬' => '(ᄑ)',
  '㉭' => '(ᄒ)',
  '㉮' => '(가)',
  '㉯' => '(나)',
  '㉰' => '(다)',
  '㉱' => '(라)',
  '㉲' => '(마)',
  '㉳' => '(바)',
  '㉴' => '(사)',
  '㉵' => '(아)',
  '㉶' => '(자)',
  '㉷' => '(차)',
  '㉸' => '(카)',
  '㉹' => '(타)',
  '㉺' => '(파)',
  '㉻' => '(하)',
  '㉼' => '(참고)',
  '㉽' => '(주의)',
  '㉾' => '(우)',
  '㊀' => '(一)',
  '㊁' => '(二)',
  '㊂' => '(三)',
  '㊃' => '(四)',
  '㊄' => '(五)',
  '㊅' => '(六)',
  '㊆' => '(七)',
  '㊇' => '(八)',
  '㊈' => '(九)',
  '㊉' => '(十)',
  '㊊' => '(月)',
  '㊋' => '(火)',
  '㊌' => '(水)',
  '㊍' => '(木)',
  '㊎' => '(金)',
  '㊏' => '(土)',
  '㊐' => '(日)',
  '㊑' => '(株)',
  '㊒' => '(有)',
  '㊓' => '(社)',
  '㊔' => '(名)',
  '㊕' => '(特)',
  '㊖' => '(財)',
  '㊗' => '(祝)',
  '㊘' => '(労)',
  '㊙' => '(秘)',
  '㊚' => '(男)',
  '㊛' => '(女)',
  '㊜' => '(適)',
  '㊝' => '(優)',
  '㊞' => '(印)',
  '㊟' => '(注)',
  '㊠' => '(項)',
  '㊡' => '(休)',
  '㊢' => '(写)',
  '㊣' => '(正)',
  '㊤' => '(上)',
  '㊥' => '(中)',
  '㊦' => '(下)',
  '㊧' => '(左)',
  '㊨' => '(右)',
  '㊩' => '(医)',
  '㊪' => '(宗)',
  '㊫' => '(学)',
  '㊬' => '(監)',
  '㊭' => '(企)',
  '㊮' => '(資)',
  '㊯' => '(協)',
  '㊰' => '(夜)',
  '㊱' => '(36)',
  '㊲' => '(37)',
  '㊳' => '(38)',
  '㊴' => '(39)',
  '㊵' => '(40)',
  '㊶' => '(41)',
  '㊷' => '(42)',
  '㊸' => '(43)',
  '㊹' => '(44)',
  '㊺' => '(45)',
  '㊻' => '(46)',
  '㊼' => '(47)',
  '㊽' => '(48)',
  '㊾' => '(49)',
  '㊿' => '(50)',
  '㋀' => '1月',
  '㋁' => '2月',
  '㋂' => '3月',
  '㋃' => '4月',
  '㋄' => '5月',
  '㋅' => '6月',
  '㋆' => '7月',
  '㋇' => '8月',
  '㋈' => '9月',
  '㋉' => '10月',
  '㋊' => '11月',
  '㋋' => '12月',
  '㋌' => 'Hg',
  '㋍' => 'erg',
  '㋎' => 'eV',
  '㋏' => 'LTD',
  '㋐' => '(ア)',
  '㋑' => '(イ)',
  '㋒' => '(ウ)',
  '㋓' => '(エ)',
  '㋔' => '(オ)',
  '㋕' => '(カ)',
  '㋖' => '(キ)',
  '㋗' => '(ク)',
  '㋘' => '(ケ)',
  '㋙' => '(コ)',
  '㋚' => '(サ)',
  '㋛' => '(シ)',
  '㋜' => '(ス)',
  '㋝' => '(セ)',
  '㋞' => '(ソ)',
  '㋟' => '(タ)',
  '㋠' => '(チ)',
  '㋡' => '(ツ)',
  '㋢' => '(テ)',
  '㋣' => '(ト)',
  '㋤' => '(ナ)',
  '㋥' => '(ニ)',
  '㋦' => '(ヌ)',
  '㋧' => '(ネ)',
  '㋨' => '(ノ)',
  '㋩' => '(ハ)',
  '㋪' => '(ヒ)',
  '㋫' => '(フ)',
  '㋬' => '(ヘ)',
  '㋭' => '(ホ)',
  '㋮' => '(マ)',
  '㋯' => '(ミ)',
  '㋰' => '(ム)',
  '㋱' => '(メ)',
  '㋲' => '(モ)',
  '㋳' => '(ヤ)',
  '㋴' => '(ユ)',
  '㋵' => '(ヨ)',
  '㋶' => '(ラ)',
  '㋷' => '(リ)',
  '㋸' => '(ル)',
  '㋹' => '(レ)',
  '㋺' => '(ロ)',
  '㋻' => '(ワ)',
  '㋼' => '(ヰ)',
  '㋽' => '(ヱ)',
  '㋾' => '(ヲ)',
  '㋿' => '令和',
  '㌀' => 'アパート',
  '㌁' => 'アルファ',
  '㌂' => 'アンペア',
  '㌃' => 'アール',
  '㌄' => 'イニング',
  '㌅' => 'インチ',
  '㌆' => 'ウォン',
  '㌇' => 'エスクード',
  '㌈' => 'エーカー',
  '㌉' => 'オンス',
  '㌊' => 'オーム',
  '㌋' => 'カイリ',
  '㌌' => 'カラット',
  '㌍' => 'カロリー',
  '㌎' => 'ガロン',
  '㌏' => 'ガンマ',
  '㌐' => 'ギガ',
  '㌑' => 'ギニー',
  '㌒' => 'キュリー',
  '㌓' => 'ギルダー',
  '㌔' => 'キロ',
  '㌕' => 'キログラム',
  '㌖' => 'キロメートル',
  '㌗' => 'キロワット',
  '㌘' => 'グラム',
  '㌙' => 'グラムトン',
  '㌚' => 'クルゼイロ',
  '㌛' => 'クローネ',
  '㌜' => 'ケース',
  '㌝' => 'コルナ',
  '㌞' => 'コーポ',
  '㌟' => 'サイクル',
  '㌠' => 'サンチーム',
  '㌡' => 'シリング',
  '㌢' => 'センチ',
  '㌣' => 'セント',
  '㌤' => 'ダース',
  '㌥' => 'デシ',
  '㌦' => 'ドル',
  '㌧' => 'トン',
  '㌨' => 'ナノ',
  '㌩' => 'ノット',
  '㌪' => 'ハイツ',
  '㌫' => 'パーセント',
  '㌬' => 'パーツ',
  '㌭' => 'バーレル',
  '㌮' => 'ピアストル',
  '㌯' => 'ピクル',
  '㌰' => 'ピコ',
  '㌱' => 'ビル',
  '㌲' => 'ファラッド',
  '㌳' => 'フィート',
  '㌴' => 'ブッシェル',
  '㌵' => 'フラン',
  '㌶' => 'ヘクタール',
  '㌷' => 'ペソ',
  '㌸' => 'ペニヒ',
  '㌹' => 'ヘルツ',
  '㌺' => 'ペンス',
  '㌻' => 'ページ',
  '㌼' => 'ベータ',
  '㌽' => 'ポイント',
  '㌾' => 'ボルト',
  '㌿' => 'ホン',
  '㍀' => 'ポンド',
  '㍁' => 'ホール',
  '㍂' => 'ホーン',
  '㍃' => 'マイクロ',
  '㍄' => 'マイル',
  '㍅' => 'マッハ',
  '㍆' => 'マルク',
  '㍇' => 'マンション',
  '㍈' => 'ミクロン',
  '㍉' => 'ミリ',
  '㍊' => 'ミリバール',
  '㍋' => 'メガ',
  '㍌' => 'メガトン',
  '㍍' => 'メートル',
  '㍎' => 'ヤード',
  '㍏' => 'ヤール',
  '㍐' => 'ユアン',
  '㍑' => 'リットル',
  '㍒' => 'リラ',
  '㍓' => 'ルピー',
  '㍔' => 'ルーブル',
  '㍕' => 'レム',
  '㍖' => 'レントゲン',
  '㍗' => 'ワット',
  '㍘' => '0点',
  '㍙' => '1点',
  '㍚' => '2点',
  '㍛' => '3点',
  '㍜' => '4点',
  '㍝' => '5点',
  '㍞' => '6点',
  '㍟' => '7点',
  '㍠' => '8点',
  '㍡' => '9点',
  '㍢' => '10点',
  '㍣' => '11点',
  '㍤' => '12点',
  '㍥' => '13点',
  '㍦' => '14点',
  '㍧' => '15点',
  '㍨' => '16点',
  '㍩' => '17点',
  '㍪' => '18点',
  '㍫' => '19点',
  '㍬' => '20点',
  '㍭' => '21点',
  '㍮' => '22点',
  '㍯' => '23点',
  '㍰' => '24点',
  '㍱' => 'hPa',
  '㍲' => 'da',
  '㍳' => 'AU',
  '㍴' => 'bar',
  '㍵' => 'oV',
  '㍶' => 'pc',
  '㍷' => 'dm',
  '㍸' => 'dm²',
  '㍹' => 'dm³',
  '㍺' => 'IU',
  '㍻' => '平成',
  '㍼' => '昭和',
  '㍽' => '大正',
  '㍾' => '明治',
  '㍿' => '株式会社',
  '㎀' => 'pA',
  '㎁' => 'nA',
  '㎂' => 'μA',
  '㎃' => 'mA',
  '㎄' => 'kA',
  '㎅' => 'KB',
  '㎆' => 'MB',
  '㎇' => 'GB',
  '㎈' => 'cal',
  '㎉' => 'kcal',
  '㎊' => 'pF',
  '㎋' => 'nF',
  '㎌' => 'μF',
  '㎍' => 'μg',
  '㎎' => 'mg',
  '㎏' => 'kg',
  '㎐' => 'Hz',
  '㎑' => 'kHz',
  '㎒' => 'MHz',
  '㎓' => 'GHz',
  '㎔' => 'THz',
  '㎕' => 'μℓ',
  '㎖' => 'mℓ',
  '㎗' => 'dℓ',
  '㎘' => 'kℓ',
  '㎙' => 'fm',
  '㎚' => 'nm',
  '㎛' => 'μm',
  '㎜' => 'mm',
  '㎝' => 'cm',
  '㎞' => 'km',
  '㎟' => 'mm²',
  '㎠' => 'cm²',
  '㎡' => 'm²',
  '㎢' => 'km²',
  '㎣' => 'mm³',
  '㎤' => 'cm³',
  '㎥' => 'm³',
  '㎦' => 'km³',
  '㎧' => 'm∕s',
  '㎨' => 'm∕s²',
  '㎩' => 'Pa',
  '㎪' => 'kPa',
  '㎫' => 'MPa',
  '㎬' => 'GPa',
  '㎭' => 'rad',
  '㎮' => 'rad∕s',
  '㎯' => 'rad∕s²',
  '㎰' => 'ps',
  '㎱' => 'ns',
  '㎲' => 'μs',
  '㎳' => 'ms',
  '㎴' => 'pV',
  '㎵' => 'nV',
  '㎶' => 'μV',
  '㎷' => 'mV',
  '㎸' => 'kV',
  '㎹' => 'MV',
  '㎺' => 'pW',
  '㎻' => 'nW',
  '㎼' => 'μW',
  '㎽' => 'mW',
  '㎾' => 'kW',
  '㎿' => 'MW',
  '㏀' => 'kΩ',
  '㏁' => 'MΩ',
  '㏂' => 'a.m.',
  '㏃' => 'Bq',
  '㏄' => 'cc',
  '㏅' => 'cd',
  '㏆' => 'C∕kg',
  '㏇' => 'Co.',
  '㏈' => 'dB',
  '㏉' => 'Gy',
  '㏊' => 'ha',
  '㏋' => 'HP',
  '㏌' => 'in',
  '㏍' => 'KK',
  '㏎' => 'KM',
  '㏏' => 'kt',
  '㏐' => 'lm',
  '㏑' => 'ln',
  '㏒' => 'log',
  '㏓' => 'lx',
  '㏔' => 'mb',
  '㏕' => 'mil',
  '㏖' => 'mol',
  '㏗' => 'PH',
  '㏘' => 'p.m.',
  '㏙' => 'PPM',
  '㏚' => 'PR',
  '㏛' => 'sr',
  '㏜' => 'Sv',
  '㏝' => 'Wb',
  '㏞' => 'V∕m',
  '㏟' => 'A∕m',
  '㏠' => '1日',
  '㏡' => '2日',
  '㏢' => '3日',
  '㏣' => '4日',
  '㏤' => '5日',
  '㏥' => '6日',
  '㏦' => '7日',
  '㏧' => '8日',
  '㏨' => '9日',
  '㏩' => '10日',
  '㏪' => '11日',
  '㏫' => '12日',
  '㏬' => '13日',
  '㏭' => '14日',
  '㏮' => '15日',
  '㏯' => '16日',
  '㏰' => '17日',
  '㏱' => '18日',
  '㏲' => '19日',
  '㏳' => '20日',
  '㏴' => '21日',
  '㏵' => '22日',
  '㏶' => '23日',
  '㏷' => '24日',
  '㏸' => '25日',
  '㏹' => '26日',
  '㏺' => '27日',
  '㏻' => '28日',
  '㏼' => '29日',
  '㏽' => '30日',
  '㏾' => '31日',
  '㏿' => 'gal',
  '豈' => '豈',
  '更' => '更',
  '車' => '車',
  '賈' => '賈',
  '滑' => '滑',
  '串' => '串',
  '句' => '句',
  '龜' => '龜',
  '龜' => '龜',
  '契' => '契',
  '金' => '金',
  '喇' => '喇',
  '奈' => '奈',
  '懶' => '懶',
  '癩' => '癩',
  '羅' => '羅',
  '蘿' => '蘿',
  '螺' => '螺',
  '裸' => '裸',
  '邏' => '邏',
  '樂' => '樂',
  '洛' => '洛',
  '烙' => '烙',
  '珞' => '珞',
  '落' => '落',
  '酪' => '酪',
  '駱' => '駱',
  '亂' => '亂',
  '卵' => '卵',
  '欄' => '欄',
  '爛' => '爛',
  '蘭' => '蘭',
  '鸞' => '鸞',
  '嵐' => '嵐',
  '濫' => '濫',
  '藍' => '藍',
  '襤' => '襤',
  '拉' => '拉',
  '臘' => '臘',
  '蠟' => '蠟',
  '廊' => '廊',
  '朗' => '朗',
  '浪' => '浪',
  '狼' => '狼',
  '郎' => '郎',
  '來' => '來',
  '冷' => '冷',
  '勞' => '勞',
  '擄' => '擄',
  '櫓' => '櫓',
  '爐' => '爐',
  '盧' => '盧',
  '老' => '老',
  '蘆' => '蘆',
  '虜' => '虜',
  '路' => '路',
  '露' => '露',
  '魯' => '魯',
  '鷺' => '鷺',
  '碌' => '碌',
  '祿' => '祿',
  '綠' => '綠',
  '菉' => '菉',
  '錄' => '錄',
  '鹿' => '鹿',
  '論' => '論',
  '壟' => '壟',
  '弄' => '弄',
  '籠' => '籠',
  '聾' => '聾',
  '牢' => '牢',
  '磊' => '磊',
  '賂' => '賂',
  '雷' => '雷',
  '壘' => '壘',
  '屢' => '屢',
  '樓' => '樓',
  '淚' => '淚',
  '漏' => '漏',
  '累' => '累',
  '縷' => '縷',
  '陋' => '陋',
  '勒' => '勒',
  '肋' => '肋',
  '凜' => '凜',
  '凌' => '凌',
  '稜' => '稜',
  '綾' => '綾',
  '菱' => '菱',
  '陵' => '陵',
  '讀' => '讀',
  '拏' => '拏',
  '樂' => '樂',
  '諾' => '諾',
  '丹' => '丹',
  '寧' => '寧',
  '怒' => '怒',
  '率' => '率',
  '異' => '異',
  '北' => '北',
  '磻' => '磻',
  '便' => '便',
  '復' => '復',
  '不' => '不',
  '泌' => '泌',
  '數' => '數',
  '索' => '索',
  '參' => '參',
  '塞' => '塞',
  '省' => '省',
  '葉' => '葉',
  '說' => '說',
  '殺' => '殺',
  '辰' => '辰',
  '沈' => '沈',
  '拾' => '拾',
  '若' => '若',
  '掠' => '掠',
  '略' => '略',
  '亮' => '亮',
  '兩' => '兩',
  '凉' => '凉',
  '梁' => '梁',
  '糧' => '糧',
  '良' => '良',
  '諒' => '諒',
  '量' => '量',
  '勵' => '勵',
  '呂' => '呂',
  '女' => '女',
  '廬' => '廬',
  '旅' => '旅',
  '濾' => '濾',
  '礪' => '礪',
  '閭' => '閭',
  '驪' => '驪',
  '麗' => '麗',
  '黎' => '黎',
  '力' => '力',
  '曆' => '曆',
  '歷' => '歷',
  '轢' => '轢',
  '年' => '年',
  '憐' => '憐',
  '戀' => '戀',
  '撚' => '撚',
  '漣' => '漣',
  '煉' => '煉',
  '璉' => '璉',
  '秊' => '秊',
  '練' => '練',
  '聯' => '聯',
  '輦' => '輦',
  '蓮' => '蓮',
  '連' => '連',
  '鍊' => '鍊',
  '列' => '列',
  '劣' => '劣',
  '咽' => '咽',
  '烈' => '烈',
  '裂' => '裂',
  '說' => '說',
  '廉' => '廉',
  '念' => '念',
  '捻' => '捻',
  '殮' => '殮',
  '簾' => '簾',
  '獵' => '獵',
  '令' => '令',
  '囹' => '囹',
  '寧' => '寧',
  '嶺' => '嶺',
  '怜' => '怜',
  '玲' => '玲',
  '瑩' => '瑩',
  '羚' => '羚',
  '聆' => '聆',
  '鈴' => '鈴',
  '零' => '零',
  '靈' => '靈',
  '領' => '領',
  '例' => '例',
  '禮' => '禮',
  '醴' => '醴',
  '隸' => '隸',
  '惡' => '惡',
  '了' => '了',
  '僚' => '僚',
  '寮' => '寮',
  '尿' => '尿',
  '料' => '料',
  '樂' => '樂',
  '燎' => '燎',
  '療' => '療',
  '蓼' => '蓼',
  '遼' => '遼',
  '龍' => '龍',
  '暈' => '暈',
  '阮' => '阮',
  '劉' => '劉',
  '杻' => '杻',
  '柳' => '柳',
  '流' => '流',
  '溜' => '溜',
  '琉' => '琉',
  '留' => '留',
  '硫' => '硫',
  '紐' => '紐',
  '類' => '類',
  '六' => '六',
  '戮' => '戮',
  '陸' => '陸',
  '倫' => '倫',
  '崙' => '崙',
  '淪' => '淪',
  '輪' => '輪',
  '律' => '律',
  '慄' => '慄',
  '栗' => '栗',
  '率' => '率',
  '隆' => '隆',
  '利' => '利',
  '吏' => '吏',
  '履' => '履',
  '易' => '易',
  '李' => '李',
  '梨' => '梨',
  '泥' => '泥',
  '理' => '理',
  '痢' => '痢',
  '罹' => '罹',
  '裏' => '裏',
  '裡' => '裡',
  '里' => '里',
  '離' => '離',
  '匿' => '匿',
  '溺' => '溺',
  '吝' => '吝',
  '燐' => '燐',
  '璘' => '璘',
  '藺' => '藺',
  '隣' => '隣',
  '鱗' => '鱗',
  '麟' => '麟',
  '林' => '林',
  '淋' => '淋',
  '臨' => '臨',
  '立' => '立',
  '笠' => '笠',
  '粒' => '粒',
  '狀' => '狀',
  '炙' => '炙',
  '識' => '識',
  '什' => '什',
  '茶' => '茶',
  '刺' => '刺',
  '切' => '切',
  '度' => '度',
  '拓' => '拓',
  '糖' => '糖',
  '宅' => '宅',
  '洞' => '洞',
  '暴' => '暴',
  '輻' => '輻',
  '行' => '行',
  '降' => '降',
  '見' => '見',
  '廓' => '廓',
  '兀' => '兀',
  '嗀' => '嗀',
  '﨎' => '' . "\0" . '',
  '﨏' => '' . "\0" . '',
  '塚' => '塚',
  '﨑' => '' . "\0" . '',
  '晴' => '晴',
  '﨓' => '' . "\0" . '',
  '﨔' => '' . "\0" . '',
  '凞' => '凞',
  '猪' => '猪',
  '益' => '益',
  '礼' => '礼',
  '神' => '神',
  '祥' => '祥',
  '福' => '福',
  '靖' => '靖',
  '精' => '精',
  '羽' => '羽',
  '﨟' => '' . "\0" . '',
  '蘒' => '蘒',
  '﨡' => '' . "\0" . '',
  '諸' => '諸',
  '﨣' => '' . "\0" . '',
  '﨤' => '' . "\0" . '',
  '逸' => '逸',
  '都' => '都',
  '﨧' => '' . "\0" . '',
  '﨨' => '' . "\0" . '',
  '﨩' => '' . "\0" . '',
  '飯' => '飯',
  '飼' => '飼',
  '館' => '館',
  '鶴' => '鶴',
  '郞' => '郞',
  '隷' => '隷',
  '侮' => '侮',
  '僧' => '僧',
  '免' => '免',
  '勉' => '勉',
  '勤' => '勤',
  '卑' => '卑',
  '喝' => '喝',
  '嘆' => '嘆',
  '器' => '器',
  '塀' => '塀',
  '墨' => '墨',
  '層' => '層',
  '屮' => '屮',
  '悔' => '悔',
  '慨' => '慨',
  '憎' => '憎',
  '懲' => '懲',
  '敏' => '敏',
  '既' => '既',
  '暑' => '暑',
  '梅' => '梅',
  '海' => '海',
  '渚' => '渚',
  '漢' => '漢',
  '煮' => '煮',
  '爫' => '爫',
  '琢' => '琢',
  '碑' => '碑',
  '社' => '社',
  '祉' => '祉',
  '祈' => '祈',
  '祐' => '祐',
  '祖' => '祖',
  '祝' => '祝',
  '禍' => '禍',
  '禎' => '禎',
  '穀' => '穀',
  '突' => '突',
  '節' => '節',
  '練' => '練',
  '縉' => '縉',
  '繁' => '繁',
  '署' => '署',
  '者' => '者',
  '臭' => '臭',
  '艹' => '艹',
  '艹' => '艹',
  '著' => '著',
  '褐' => '褐',
  '視' => '視',
  '謁' => '謁',
  '謹' => '謹',
  '賓' => '賓',
  '贈' => '贈',
  '辶' => '辶',
  '逸' => '逸',
  '難' => '難',
  '響' => '響',
  '頻' => '頻',
  '恵' => '恵',
  '𤋮' => '𤋮',
  '舘' => '舘',
  '並' => '並',
  '况' => '况',
  '全' => '全',
  '侀' => '侀',
  '充' => '充',
  '冀' => '冀',
  '勇' => '勇',
  '勺' => '勺',
  '喝' => '喝',
  '啕' => '啕',
  '喙' => '喙',
  '嗢' => '嗢',
  '塚' => '塚',
  '墳' => '墳',
  '奄' => '奄',
  '奔' => '奔',
  '婢' => '婢',
  '嬨' => '嬨',
  '廒' => '廒',
  '廙' => '廙',
  '彩' => '彩',
  '徭' => '徭',
  '惘' => '惘',
  '慎' => '慎',
  '愈' => '愈',
  '憎' => '憎',
  '慠' => '慠',
  '懲' => '懲',
  '戴' => '戴',
  '揄' => '揄',
  '搜' => '搜',
  '摒' => '摒',
  '敖' => '敖',
  '晴' => '晴',
  '朗' => '朗',
  '望' => '望',
  '杖' => '杖',
  '歹' => '歹',
  '殺' => '殺',
  '流' => '流',
  '滛' => '滛',
  '滋' => '滋',
  '漢' => '漢',
  '瀞' => '瀞',
  '煮' => '煮',
  '瞧' => '瞧',
  '爵' => '爵',
  '犯' => '犯',
  '猪' => '猪',
  '瑱' => '瑱',
  '甆' => '甆',
  '画' => '画',
  '瘝' => '瘝',
  '瘟' => '瘟',
  '益' => '益',
  '盛' => '盛',
  '直' => '直',
  '睊' => '睊',
  '着' => '着',
  '磌' => '磌',
  '窱' => '窱',
  '節' => '節',
  '类' => '类',
  '絛' => '絛',
  '練' => '練',
  '缾' => '缾',
  '者' => '者',
  '荒' => '荒',
  '華' => '華',
  '蝹' => '蝹',
  '襁' => '襁',
  '覆' => '覆',
  '視' => '視',
  '調' => '調',
  '諸' => '諸',
  '請' => '請',
  '謁' => '謁',
  '諾' => '諾',
  '諭' => '諭',
  '謹' => '謹',
  '變' => '變',
  '贈' => '贈',
  '輸' => '輸',
  '遲' => '遲',
  '醙' => '醙',
  '鉶' => '鉶',
  '陼' => '陼',
  '難' => '難',
  '靖' => '靖',
  '韛' => '韛',
  '響' => '響',
  '頋' => '頋',
  '頻' => '頻',
  '鬒' => '鬒',
  '龜' => '龜',
  '𢡊' => '𢡊',
  '𢡄' => '𢡄',
  '𣏕' => '𣏕',
  '㮝' => '㮝',
  '䀘' => '䀘',
  '䀹' => '䀹',
  '𥉉' => '𥉉',
  '𥳐' => '𥳐',
  '𧻓' => '𧻓',
  '齃' => '齃',
  '龎' => '龎',
  'ff' => 'ff',
  'fi' => 'fi',
  'fl' => 'fl',
  'ffi' => 'ffi',
  'ffl' => 'ffl',
  'ſt' => 'ſt',
  'st' => 'st',
  'ﬓ' => 'մն',
  'ﬔ' => 'մե',
  'ﬕ' => 'մի',
  'ﬖ' => 'վն',
  'ﬗ' => 'մխ',
  'ﬠ' => 'ע',
  'ﬡ' => 'א',
  'ﬢ' => 'ד',
  'ﬣ' => 'ה',
  'ﬤ' => 'כ',
  'ﬥ' => 'ל',
  'ﬦ' => 'ם',
  'ﬧ' => 'ר',
  'ﬨ' => 'ת',
  '﬩' => '+',
  'ﭏ' => 'אל',
  '﹉' => '‾',
  '﹊' => '‾',
  '﹋' => '‾',
  '﹌' => '‾',
  '﹍' => '_',
  '﹎' => '_',
  '﹏' => '_',
  '﹐' => ',',
  '﹑' => '、',
  '﹒' => '.',
  '﹔' => ';',
  '﹕' => ':',
  '﹖' => '?',
  '﹗' => '!',
  '﹘' => '—',
  '﹙' => '(',
  '﹚' => ')',
  '﹛' => '{',
  '﹜' => '}',
  '﹝' => '〔',
  '﹞' => '〕',
  '﹟' => '#',
  '﹠' => '&',
  '﹡' => '*',
  '﹢' => '+',
  '﹣' => '-',
  '﹤' => '<',
  '﹥' => '>',
  '﹦' => '=',
  '﹨' => '\\',
  '﹩' => '$',
  '﹪' => '%',
  '﹫' => '@',
  '!' => '!',
  '"' => '"',
  '#' => '#',
  '$' => '$',
  '%' => '%',
  '&' => '&',
  ''' => '\'',
  '(' => '(',
  ')' => ')',
  '*' => '*',
  '+' => '+',
  ',' => ',',
  '-' => '-',
  '.' => '.',
  '/' => '/',
  '0' => '0',
  '1' => '1',
  '2' => '2',
  '3' => '3',
  '4' => '4',
  '5' => '5',
  '6' => '6',
  '7' => '7',
  '8' => '8',
  '9' => '9',
  ':' => ':',
  ';' => ';',
  '<' => '<',
  '=' => '=',
  '>' => '>',
  '?' => '?',
  '@' => '@',
  'A' => 'A',
  'B' => 'B',
  'C' => 'C',
  'D' => 'D',
  'E' => 'E',
  'F' => 'F',
  'G' => 'G',
  'H' => 'H',
  'I' => 'I',
  'J' => 'J',
  'K' => 'K',
  'L' => 'L',
  'M' => 'M',
  'N' => 'N',
  'O' => 'O',
  'P' => 'P',
  'Q' => 'Q',
  'R' => 'R',
  'S' => 'S',
  'T' => 'T',
  'U' => 'U',
  'V' => 'V',
  'W' => 'W',
  'X' => 'X',
  'Y' => 'Y',
  'Z' => 'Z',
  '[' => '[',
  '\' => '\\',
  ']' => ']',
  '^' => '^',
  '_' => '_',
  '`' => '`',
  'a' => 'a',
  'b' => 'b',
  'c' => 'c',
  'd' => 'd',
  'e' => 'e',
  'f' => 'f',
  'g' => 'g',
  'h' => 'h',
  'i' => 'i',
  'j' => 'j',
  'k' => 'k',
  'l' => 'l',
  'm' => 'm',
  'n' => 'n',
  'o' => 'o',
  'p' => 'p',
  'q' => 'q',
  'r' => 'r',
  's' => 's',
  't' => 't',
  'u' => 'u',
  'v' => 'v',
  'w' => 'w',
  'x' => 'x',
  'y' => 'y',
  'z' => 'z',
  '{' => '{',
  '|' => '|',
  '}' => '}',
  '~' => '~',
  '⦅' => '⦅',
  '⦆' => '⦆',
  '。' => '。',
  '「' => '「',
  '」' => '」',
  '、' => '、',
  '・' => '・',
  'ヲ' => 'ヲ',
  'ァ' => 'ァ',
  'ィ' => 'ィ',
  'ゥ' => 'ゥ',
  'ェ' => 'ェ',
  'ォ' => 'ォ',
  'ャ' => 'ャ',
  'ュ' => 'ュ',
  'ョ' => 'ョ',
  'ッ' => 'ッ',
  'ー' => 'ー',
  'ア' => 'ア',
  'イ' => 'イ',
  'ウ' => 'ウ',
  'エ' => 'エ',
  'オ' => 'オ',
  'カ' => 'カ',
  'キ' => 'キ',
  'ク' => 'ク',
  'ケ' => 'ケ',
  'コ' => 'コ',
  'サ' => 'サ',
  'シ' => 'シ',
  'ス' => 'ス',
  'セ' => 'セ',
  'ソ' => 'ソ',
  'タ' => 'タ',
  'チ' => 'チ',
  'ツ' => 'ツ',
  'テ' => 'テ',
  'ト' => 'ト',
  'ナ' => 'ナ',
  'ニ' => 'ニ',
  'ヌ' => 'ヌ',
  'ネ' => 'ネ',
  'ノ' => 'ノ',
  'ハ' => 'ハ',
  'ヒ' => 'ヒ',
  'フ' => 'フ',
  'ヘ' => 'ヘ',
  'ホ' => 'ホ',
  'マ' => 'マ',
  'ミ' => 'ミ',
  'ム' => 'ム',
  'メ' => 'メ',
  'モ' => 'モ',
  'ヤ' => 'ヤ',
  'ユ' => 'ユ',
  'ヨ' => 'ヨ',
  'ラ' => 'ラ',
  'リ' => 'リ',
  'ル' => 'ル',
  'レ' => 'レ',
  'ロ' => 'ロ',
  'ワ' => 'ワ',
  'ン' => 'ン',
  '゙' => '゙',
  '゚' => '゚',
  'ᅠ' => 'ㅤ',
  'ᄀ' => 'ㄱ',
  'ᄁ' => 'ㄲ',
  'ᆪ' => 'ㄳ',
  'ᄂ' => 'ㄴ',
  'ᆬ' => 'ㄵ',
  'ᆭ' => 'ㄶ',
  'ᄃ' => 'ㄷ',
  'ᄄ' => 'ㄸ',
  'ᄅ' => 'ㄹ',
  'ᆰ' => 'ㄺ',
  'ᆱ' => 'ㄻ',
  'ᆲ' => 'ㄼ',
  'ᆳ' => 'ㄽ',
  'ᆴ' => 'ㄾ',
  'ᆵ' => 'ㄿ',
  'ᄚ' => 'ㅀ',
  'ᄆ' => 'ㅁ',
  'ᄇ' => 'ㅂ',
  'ᄈ' => 'ㅃ',
  'ᄡ' => 'ㅄ',
  'ᄉ' => 'ㅅ',
  'ᄊ' => 'ㅆ',
  'ᄋ' => 'ㅇ',
  'ᄌ' => 'ㅈ',
  'ᄍ' => 'ㅉ',
  'ᄎ' => 'ㅊ',
  'ᄏ' => 'ㅋ',
  'ᄐ' => 'ㅌ',
  'ᄑ' => 'ㅍ',
  'ᄒ' => 'ㅎ',
  'ᅡ' => 'ㅏ',
  'ᅢ' => 'ㅐ',
  'ᅣ' => 'ㅑ',
  'ᅤ' => 'ㅒ',
  'ᅥ' => 'ㅓ',
  'ᅦ' => 'ㅔ',
  'ᅧ' => 'ㅕ',
  'ᅨ' => 'ㅖ',
  'ᅩ' => 'ㅗ',
  'ᅪ' => 'ㅘ',
  'ᅫ' => 'ㅙ',
  'ᅬ' => 'ㅚ',
  'ᅭ' => 'ㅛ',
  'ᅮ' => 'ㅜ',
  'ᅯ' => 'ㅝ',
  'ᅰ' => 'ㅞ',
  'ᅱ' => 'ㅟ',
  'ᅲ' => 'ㅠ',
  'ᅳ' => 'ㅡ',
  'ᅴ' => 'ㅢ',
  'ᅵ' => 'ㅣ',
  '¢' => '¢',
  '£' => '£',
  '¬' => '¬',
  ' ̄' => '¯',
  '¦' => '¦',
  '¥' => '¥',
  '₩' => '₩',
  '│' => '│',
  '←' => '←',
  '↑' => '↑',
  '→' => '→',
  '↓' => '↓',
  '■' => '■',
  '○' => '○',
  '𝐀' => 'A',
  '𝐁' => 'B',
  '𝐂' => 'C',
  '𝐃' => 'D',
  '𝐄' => 'E',
  '𝐅' => 'F',
  '𝐆' => 'G',
  '𝐇' => 'H',
  '𝐈' => 'I',
  '𝐉' => 'J',
  '𝐊' => 'K',
  '𝐋' => 'L',
  '𝐌' => 'M',
  '𝐍' => 'N',
  '𝐎' => 'O',
  '𝐏' => 'P',
  '𝐐' => 'Q',
  '𝐑' => 'R',
  '𝐒' => 'S',
  '𝐓' => 'T',
  '𝐔' => 'U',
  '𝐕' => 'V',
  '𝐖' => 'W',
  '𝐗' => 'X',
  '𝐘' => 'Y',
  '𝐙' => 'Z',
  '𝐚' => 'a',
  '𝐛' => 'b',
  '𝐜' => 'c',
  '𝐝' => 'd',
  '𝐞' => 'e',
  '𝐟' => 'f',
  '𝐠' => 'g',
  '𝐡' => 'h',
  '𝐢' => 'i',
  '𝐣' => 'j',
  '𝐤' => 'k',
  '𝐥' => 'l',
  '𝐦' => 'm',
  '𝐧' => 'n',
  '𝐨' => 'o',
  '𝐩' => 'p',
  '𝐪' => 'q',
  '𝐫' => 'r',
  '𝐬' => 's',
  '𝐭' => 't',
  '𝐮' => 'u',
  '𝐯' => 'v',
  '𝐰' => 'w',
  '𝐱' => 'x',
  '𝐲' => 'y',
  '𝐳' => 'z',
  '𝐴' => 'A',
  '𝐵' => 'B',
  '𝐶' => 'C',
  '𝐷' => 'D',
  '𝐸' => 'E',
  '𝐹' => 'F',
  '𝐺' => 'G',
  '𝐻' => 'H',
  '𝐼' => 'I',
  '𝐽' => 'J',
  '𝐾' => 'K',
  '𝐿' => 'L',
  '𝑀' => 'M',
  '𝑁' => 'N',
  '𝑂' => 'O',
  '𝑃' => 'P',
  '𝑄' => 'Q',
  '𝑅' => 'R',
  '𝑆' => 'S',
  '𝑇' => 'T',
  '𝑈' => 'U',
  '𝑉' => 'V',
  '𝑊' => 'W',
  '𝑋' => 'X',
  '𝑌' => 'Y',
  '𝑍' => 'Z',
  '𝑎' => 'a',
  '𝑏' => 'b',
  '𝑐' => 'c',
  '𝑑' => 'd',
  '𝑒' => 'e',
  '𝑓' => 'f',
  '𝑔' => 'g',
  '𝑖' => 'i',
  '𝑗' => 'j',
  '𝑘' => 'k',
  '𝑙' => 'l',
  '𝑚' => 'm',
  '𝑛' => 'n',
  '𝑜' => 'o',
  '𝑝' => 'p',
  '𝑞' => 'q',
  '𝑟' => 'r',
  '𝑠' => 's',
  '𝑡' => 't',
  '𝑢' => 'u',
  '𝑣' => 'v',
  '𝑤' => 'w',
  '𝑥' => 'x',
  '𝑦' => 'y',
  '𝑧' => 'z',
  '𝑨' => 'A',
  '𝑩' => 'B',
  '𝑪' => 'C',
  '𝑫' => 'D',
  '𝑬' => 'E',
  '𝑭' => 'F',
  '𝑮' => 'G',
  '𝑯' => 'H',
  '𝑰' => 'I',
  '𝑱' => 'J',
  '𝑲' => 'K',
  '𝑳' => 'L',
  '𝑴' => 'M',
  '𝑵' => 'N',
  '𝑶' => 'O',
  '𝑷' => 'P',
  '𝑸' => 'Q',
  '𝑹' => 'R',
  '𝑺' => 'S',
  '𝑻' => 'T',
  '𝑼' => 'U',
  '𝑽' => 'V',
  '𝑾' => 'W',
  '𝑿' => 'X',
  '𝒀' => 'Y',
  '𝒁' => 'Z',
  '𝒂' => 'a',
  '𝒃' => 'b',
  '𝒄' => 'c',
  '𝒅' => 'd',
  '𝒆' => 'e',
  '𝒇' => 'f',
  '𝒈' => 'g',
  '𝒉' => 'h',
  '𝒊' => 'i',
  '𝒋' => 'j',
  '𝒌' => 'k',
  '𝒍' => 'l',
  '𝒎' => 'm',
  '𝒏' => 'n',
  '𝒐' => 'o',
  '𝒑' => 'p',
  '𝒒' => 'q',
  '𝒓' => 'r',
  '𝒔' => 's',
  '𝒕' => 't',
  '𝒖' => 'u',
  '𝒗' => 'v',
  '𝒘' => 'w',
  '𝒙' => 'x',
  '𝒚' => 'y',
  '𝒛' => 'z',
  '𝒜' => 'A',
  '𝒞' => 'C',
  '𝒟' => 'D',
  '𝒢' => 'G',
  '𝒥' => 'J',
  '𝒦' => 'K',
  '𝒩' => 'N',
  '𝒪' => 'O',
  '𝒫' => 'P',
  '𝒬' => 'Q',
  '𝒮' => 'S',
  '𝒯' => 'T',
  '𝒰' => 'U',
  '𝒱' => 'V',
  '𝒲' => 'W',
  '𝒳' => 'X',
  '𝒴' => 'Y',
  '𝒵' => 'Z',
  '𝒶' => 'a',
  '𝒷' => 'b',
  '𝒸' => 'c',
  '𝒹' => 'd',
  '𝒻' => 'f',
  '𝒽' => 'h',
  '𝒾' => 'i',
  '𝒿' => 'j',
  '𝓀' => 'k',
  '𝓁' => 'l',
  '𝓂' => 'm',
  '𝓃' => 'n',
  '𝓅' => 'p',
  '𝓆' => 'q',
  '𝓇' => 'r',
  '𝓈' => 's',
  '𝓉' => 't',
  '𝓊' => 'u',
  '𝓋' => 'v',
  '𝓌' => 'w',
  '𝓍' => 'x',
  '𝓎' => 'y',
  '𝓏' => 'z',
  '𝓐' => 'A',
  '𝓑' => 'B',
  '𝓒' => 'C',
  '𝓓' => 'D',
  '𝓔' => 'E',
  '𝓕' => 'F',
  '𝓖' => 'G',
  '𝓗' => 'H',
  '𝓘' => 'I',
  '𝓙' => 'J',
  '𝓚' => 'K',
  '𝓛' => 'L',
  '𝓜' => 'M',
  '𝓝' => 'N',
  '𝓞' => 'O',
  '𝓟' => 'P',
  '𝓠' => 'Q',
  '𝓡' => 'R',
  '𝓢' => 'S',
  '𝓣' => 'T',
  '𝓤' => 'U',
  '𝓥' => 'V',
  '𝓦' => 'W',
  '𝓧' => 'X',
  '𝓨' => 'Y',
  '𝓩' => 'Z',
  '𝓪' => 'a',
  '𝓫' => 'b',
  '𝓬' => 'c',
  '𝓭' => 'd',
  '𝓮' => 'e',
  '𝓯' => 'f',
  '𝓰' => 'g',
  '𝓱' => 'h',
  '𝓲' => 'i',
  '𝓳' => 'j',
  '𝓴' => 'k',
  '𝓵' => 'l',
  '𝓶' => 'm',
  '𝓷' => 'n',
  '𝓸' => 'o',
  '𝓹' => 'p',
  '𝓺' => 'q',
  '𝓻' => 'r',
  '𝓼' => 's',
  '𝓽' => 't',
  '𝓾' => 'u',
  '𝓿' => 'v',
  '𝔀' => 'w',
  '𝔁' => 'x',
  '𝔂' => 'y',
  '𝔃' => 'z',
  '𝔄' => 'A',
  '𝔅' => 'B',
  '𝔇' => 'D',
  '𝔈' => 'E',
  '𝔉' => 'F',
  '𝔊' => 'G',
  '𝔍' => 'J',
  '𝔎' => 'K',
  '𝔏' => 'L',
  '𝔐' => 'M',
  '𝔑' => 'N',
  '𝔒' => 'O',
  '𝔓' => 'P',
  '𝔔' => 'Q',
  '𝔖' => 'S',
  '𝔗' => 'T',
  '𝔘' => 'U',
  '𝔙' => 'V',
  '𝔚' => 'W',
  '𝔛' => 'X',
  '𝔜' => 'Y',
  '𝔞' => 'a',
  '𝔟' => 'b',
  '𝔠' => 'c',
  '𝔡' => 'd',
  '𝔢' => 'e',
  '𝔣' => 'f',
  '𝔤' => 'g',
  '𝔥' => 'h',
  '𝔦' => 'i',
  '𝔧' => 'j',
  '𝔨' => 'k',
  '𝔩' => 'l',
  '𝔪' => 'm',
  '𝔫' => 'n',
  '𝔬' => 'o',
  '𝔭' => 'p',
  '𝔮' => 'q',
  '𝔯' => 'r',
  '𝔰' => 's',
  '𝔱' => 't',
  '𝔲' => 'u',
  '𝔳' => 'v',
  '𝔴' => 'w',
  '𝔵' => 'x',
  '𝔶' => 'y',
  '𝔷' => 'z',
  '𝔸' => 'A',
  '𝔹' => 'B',
  '𝔻' => 'D',
  '𝔼' => 'E',
  '𝔽' => 'F',
  '𝔾' => 'G',
  '𝕀' => 'I',
  '𝕁' => 'J',
  '𝕂' => 'K',
  '𝕃' => 'L',
  '𝕄' => 'M',
  '𝕆' => 'O',
  '𝕊' => 'S',
  '𝕋' => 'T',
  '𝕌' => 'U',
  '𝕍' => 'V',
  '𝕎' => 'W',
  '𝕏' => 'X',
  '𝕐' => 'Y',
  '𝕒' => 'a',
  '𝕓' => 'b',
  '𝕔' => 'c',
  '𝕕' => 'd',
  '𝕖' => 'e',
  '𝕗' => 'f',
  '𝕘' => 'g',
  '𝕙' => 'h',
  '𝕚' => 'i',
  '𝕛' => 'j',
  '𝕜' => 'k',
  '𝕝' => 'l',
  '𝕞' => 'm',
  '𝕟' => 'n',
  '𝕠' => 'o',
  '𝕡' => 'p',
  '𝕢' => 'q',
  '𝕣' => 'r',
  '𝕤' => 's',
  '𝕥' => 't',
  '𝕦' => 'u',
  '𝕧' => 'v',
  '𝕨' => 'w',
  '𝕩' => 'x',
  '𝕪' => 'y',
  '𝕫' => 'z',
  '𝕬' => 'A',
  '𝕭' => 'B',
  '𝕮' => 'C',
  '𝕯' => 'D',
  '𝕰' => 'E',
  '𝕱' => 'F',
  '𝕲' => 'G',
  '𝕳' => 'H',
  '𝕴' => 'I',
  '𝕵' => 'J',
  '𝕶' => 'K',
  '𝕷' => 'L',
  '𝕸' => 'M',
  '𝕹' => 'N',
  '𝕺' => 'O',
  '𝕻' => 'P',
  '𝕼' => 'Q',
  '𝕽' => 'R',
  '𝕾' => 'S',
  '𝕿' => 'T',
  '𝖀' => 'U',
  '𝖁' => 'V',
  '𝖂' => 'W',
  '𝖃' => 'X',
  '𝖄' => 'Y',
  '𝖅' => 'Z',
  '𝖆' => 'a',
  '𝖇' => 'b',
  '𝖈' => 'c',
  '𝖉' => 'd',
  '𝖊' => 'e',
  '𝖋' => 'f',
  '𝖌' => 'g',
  '𝖍' => 'h',
  '𝖎' => 'i',
  '𝖏' => 'j',
  '𝖐' => 'k',
  '𝖑' => 'l',
  '𝖒' => 'm',
  '𝖓' => 'n',
  '𝖔' => 'o',
  '𝖕' => 'p',
  '𝖖' => 'q',
  '𝖗' => 'r',
  '𝖘' => 's',
  '𝖙' => 't',
  '𝖚' => 'u',
  '𝖛' => 'v',
  '𝖜' => 'w',
  '𝖝' => 'x',
  '𝖞' => 'y',
  '𝖟' => 'z',
  '𝖠' => 'A',
  '𝖡' => 'B',
  '𝖢' => 'C',
  '𝖣' => 'D',
  '𝖤' => 'E',
  '𝖥' => 'F',
  '𝖦' => 'G',
  '𝖧' => 'H',
  '𝖨' => 'I',
  '𝖩' => 'J',
  '𝖪' => 'K',
  '𝖫' => 'L',
  '𝖬' => 'M',
  '𝖭' => 'N',
  '𝖮' => 'O',
  '𝖯' => 'P',
  '𝖰' => 'Q',
  '𝖱' => 'R',
  '𝖲' => 'S',
  '𝖳' => 'T',
  '𝖴' => 'U',
  '𝖵' => 'V',
  '𝖶' => 'W',
  '𝖷' => 'X',
  '𝖸' => 'Y',
  '𝖹' => 'Z',
  '𝖺' => 'a',
  '𝖻' => 'b',
  '𝖼' => 'c',
  '𝖽' => 'd',
  '𝖾' => 'e',
  '𝖿' => 'f',
  '𝗀' => 'g',
  '𝗁' => 'h',
  '𝗂' => 'i',
  '𝗃' => 'j',
  '𝗄' => 'k',
  '𝗅' => 'l',
  '𝗆' => 'm',
  '𝗇' => 'n',
  '𝗈' => 'o',
  '𝗉' => 'p',
  '𝗊' => 'q',
  '𝗋' => 'r',
  '𝗌' => 's',
  '𝗍' => 't',
  '𝗎' => 'u',
  '𝗏' => 'v',
  '𝗐' => 'w',
  '𝗑' => 'x',
  '𝗒' => 'y',
  '𝗓' => 'z',
  '𝗔' => 'A',
  '𝗕' => 'B',
  '𝗖' => 'C',
  '𝗗' => 'D',
  '𝗘' => 'E',
  '𝗙' => 'F',
  '𝗚' => 'G',
  '𝗛' => 'H',
  '𝗜' => 'I',
  '𝗝' => 'J',
  '𝗞' => 'K',
  '𝗟' => 'L',
  '𝗠' => 'M',
  '𝗡' => 'N',
  '𝗢' => 'O',
  '𝗣' => 'P',
  '𝗤' => 'Q',
  '𝗥' => 'R',
  '𝗦' => 'S',
  '𝗧' => 'T',
  '𝗨' => 'U',
  '𝗩' => 'V',
  '𝗪' => 'W',
  '𝗫' => 'X',
  '𝗬' => 'Y',
  '𝗭' => 'Z',
  '𝗮' => 'a',
  '𝗯' => 'b',
  '𝗰' => 'c',
  '𝗱' => 'd',
  '𝗲' => 'e',
  '𝗳' => 'f',
  '𝗴' => 'g',
  '𝗵' => 'h',
  '𝗶' => 'i',
  '𝗷' => 'j',
  '𝗸' => 'k',
  '𝗹' => 'l',
  '𝗺' => 'm',
  '𝗻' => 'n',
  '𝗼' => 'o',
  '𝗽' => 'p',
  '𝗾' => 'q',
  '𝗿' => 'r',
  '𝘀' => 's',
  '𝘁' => 't',
  '𝘂' => 'u',
  '𝘃' => 'v',
  '𝘄' => 'w',
  '𝘅' => 'x',
  '𝘆' => 'y',
  '𝘇' => 'z',
  '𝘈' => 'A',
  '𝘉' => 'B',
  '𝘊' => 'C',
  '𝘋' => 'D',
  '𝘌' => 'E',
  '𝘍' => 'F',
  '𝘎' => 'G',
  '𝘏' => 'H',
  '𝘐' => 'I',
  '𝘑' => 'J',
  '𝘒' => 'K',
  '𝘓' => 'L',
  '𝘔' => 'M',
  '𝘕' => 'N',
  '𝘖' => 'O',
  '𝘗' => 'P',
  '𝘘' => 'Q',
  '𝘙' => 'R',
  '𝘚' => 'S',
  '𝘛' => 'T',
  '𝘜' => 'U',
  '𝘝' => 'V',
  '𝘞' => 'W',
  '𝘟' => 'X',
  '𝘠' => 'Y',
  '𝘡' => 'Z',
  '𝘢' => 'a',
  '𝘣' => 'b',
  '𝘤' => 'c',
  '𝘥' => 'd',
  '𝘦' => 'e',
  '𝘧' => 'f',
  '𝘨' => 'g',
  '𝘩' => 'h',
  '𝘪' => 'i',
  '𝘫' => 'j',
  '𝘬' => 'k',
  '𝘭' => 'l',
  '𝘮' => 'm',
  '𝘯' => 'n',
  '𝘰' => 'o',
  '𝘱' => 'p',
  '𝘲' => 'q',
  '𝘳' => 'r',
  '𝘴' => 's',
  '𝘵' => 't',
  '𝘶' => 'u',
  '𝘷' => 'v',
  '𝘸' => 'w',
  '𝘹' => 'x',
  '𝘺' => 'y',
  '𝘻' => 'z',
  '𝘼' => 'A',
  '𝘽' => 'B',
  '𝘾' => 'C',
  '𝘿' => 'D',
  '𝙀' => 'E',
  '𝙁' => 'F',
  '𝙂' => 'G',
  '𝙃' => 'H',
  '𝙄' => 'I',
  '𝙅' => 'J',
  '𝙆' => 'K',
  '𝙇' => 'L',
  '𝙈' => 'M',
  '𝙉' => 'N',
  '𝙊' => 'O',
  '𝙋' => 'P',
  '𝙌' => 'Q',
  '𝙍' => 'R',
  '𝙎' => 'S',
  '𝙏' => 'T',
  '𝙐' => 'U',
  '𝙑' => 'V',
  '𝙒' => 'W',
  '𝙓' => 'X',
  '𝙔' => 'Y',
  '𝙕' => 'Z',
  '𝙖' => 'a',
  '𝙗' => 'b',
  '𝙘' => 'c',
  '𝙙' => 'd',
  '𝙚' => 'e',
  '𝙛' => 'f',
  '𝙜' => 'g',
  '𝙝' => 'h',
  '𝙞' => 'i',
  '𝙟' => 'j',
  '𝙠' => 'k',
  '𝙡' => 'l',
  '𝙢' => 'm',
  '𝙣' => 'n',
  '𝙤' => 'o',
  '𝙥' => 'p',
  '𝙦' => 'q',
  '𝙧' => 'r',
  '𝙨' => 's',
  '𝙩' => 't',
  '𝙪' => 'u',
  '𝙫' => 'v',
  '𝙬' => 'w',
  '𝙭' => 'x',
  '𝙮' => 'y',
  '𝙯' => 'z',
  '𝙰' => 'A',
  '𝙱' => 'B',
  '𝙲' => 'C',
  '𝙳' => 'D',
  '𝙴' => 'E',
  '𝙵' => 'F',
  '𝙶' => 'G',
  '𝙷' => 'H',
  '𝙸' => 'I',
  '𝙹' => 'J',
  '𝙺' => 'K',
  '𝙻' => 'L',
  '𝙼' => 'M',
  '𝙽' => 'N',
  '𝙾' => 'O',
  '𝙿' => 'P',
  '𝚀' => 'Q',
  '𝚁' => 'R',
  '𝚂' => 'S',
  '𝚃' => 'T',
  '𝚄' => 'U',
  '𝚅' => 'V',
  '𝚆' => 'W',
  '𝚇' => 'X',
  '𝚈' => 'Y',
  '𝚉' => 'Z',
  '𝚊' => 'a',
  '𝚋' => 'b',
  '𝚌' => 'c',
  '𝚍' => 'd',
  '𝚎' => 'e',
  '𝚏' => 'f',
  '𝚐' => 'g',
  '𝚑' => 'h',
  '𝚒' => 'i',
  '𝚓' => 'j',
  '𝚔' => 'k',
  '𝚕' => 'l',
  '𝚖' => 'm',
  '𝚗' => 'n',
  '𝚘' => 'o',
  '𝚙' => 'p',
  '𝚚' => 'q',
  '𝚛' => 'r',
  '𝚜' => 's',
  '𝚝' => 't',
  '𝚞' => 'u',
  '𝚟' => 'v',
  '𝚠' => 'w',
  '𝚡' => 'x',
  '𝚢' => 'y',
  '𝚣' => 'z',
  '𝚤' => 'ı',
  '𝚥' => 'ȷ',
  '𝚨' => 'Α',
  '𝚩' => 'Β',
  '𝚪' => 'Γ',
  '𝚫' => 'Δ',
  '𝚬' => 'Ε',
  '𝚭' => 'Ζ',
  '𝚮' => 'Η',
  '𝚯' => 'Θ',
  '𝚰' => 'Ι',
  '𝚱' => 'Κ',
  '𝚲' => 'Λ',
  '𝚳' => 'Μ',
  '𝚴' => 'Ν',
  '𝚵' => 'Ξ',
  '𝚶' => 'Ο',
  '𝚷' => 'Π',
  '𝚸' => 'Ρ',
  '𝚹' => 'ϴ',
  '𝚺' => 'Σ',
  '𝚻' => 'Τ',
  '𝚼' => 'Υ',
  '𝚽' => 'Φ',
  '𝚾' => 'Χ',
  '𝚿' => 'Ψ',
  '𝛀' => 'Ω',
  '𝛁' => '∇',
  '𝛂' => 'α',
  '𝛃' => 'β',
  '𝛄' => 'γ',
  '𝛅' => 'δ',
  '𝛆' => 'ε',
  '𝛇' => 'ζ',
  '𝛈' => 'η',
  '𝛉' => 'θ',
  '𝛊' => 'ι',
  '𝛋' => 'κ',
  '𝛌' => 'λ',
  '𝛍' => 'μ',
  '𝛎' => 'ν',
  '𝛏' => 'ξ',
  '𝛐' => 'ο',
  '𝛑' => 'π',
  '𝛒' => 'ρ',
  '𝛓' => 'ς',
  '𝛔' => 'σ',
  '𝛕' => 'τ',
  '𝛖' => 'υ',
  '𝛗' => 'φ',
  '𝛘' => 'χ',
  '𝛙' => 'ψ',
  '𝛚' => 'ω',
  '𝛛' => '∂',
  '𝛜' => 'ϵ',
  '𝛝' => 'ϑ',
  '𝛞' => 'ϰ',
  '𝛟' => 'ϕ',
  '𝛠' => 'ϱ',
  '𝛡' => 'ϖ',
  '𝛢' => 'Α',
  '𝛣' => 'Β',
  '𝛤' => 'Γ',
  '𝛥' => 'Δ',
  '𝛦' => 'Ε',
  '𝛧' => 'Ζ',
  '𝛨' => 'Η',
  '𝛩' => 'Θ',
  '𝛪' => 'Ι',
  '𝛫' => 'Κ',
  '𝛬' => 'Λ',
  '𝛭' => 'Μ',
  '𝛮' => 'Ν',
  '𝛯' => 'Ξ',
  '𝛰' => 'Ο',
  '𝛱' => 'Π',
  '𝛲' => 'Ρ',
  '𝛳' => 'ϴ',
  '𝛴' => 'Σ',
  '𝛵' => 'Τ',
  '𝛶' => 'Υ',
  '𝛷' => 'Φ',
  '𝛸' => 'Χ',
  '𝛹' => 'Ψ',
  '𝛺' => 'Ω',
  '𝛻' => '∇',
  '𝛼' => 'α',
  '𝛽' => 'β',
  '𝛾' => 'γ',
  '𝛿' => 'δ',
  '𝜀' => 'ε',
  '𝜁' => 'ζ',
  '𝜂' => 'η',
  '𝜃' => 'θ',
  '𝜄' => 'ι',
  '𝜅' => 'κ',
  '𝜆' => 'λ',
  '𝜇' => 'μ',
  '𝜈' => 'ν',
  '𝜉' => 'ξ',
  '𝜊' => 'ο',
  '𝜋' => 'π',
  '𝜌' => 'ρ',
  '𝜍' => 'ς',
  '𝜎' => 'σ',
  '𝜏' => 'τ',
  '𝜐' => 'υ',
  '𝜑' => 'φ',
  '𝜒' => 'χ',
  '𝜓' => 'ψ',
  '𝜔' => 'ω',
  '𝜕' => '∂',
  '𝜖' => 'ϵ',
  '𝜗' => 'ϑ',
  '𝜘' => 'ϰ',
  '𝜙' => 'ϕ',
  '𝜚' => 'ϱ',
  '𝜛' => 'ϖ',
  '𝜜' => 'Α',
  '𝜝' => 'Β',
  '𝜞' => 'Γ',
  '𝜟' => 'Δ',
  '𝜠' => 'Ε',
  '𝜡' => 'Ζ',
  '𝜢' => 'Η',
  '𝜣' => 'Θ',
  '𝜤' => 'Ι',
  '𝜥' => 'Κ',
  '𝜦' => 'Λ',
  '𝜧' => 'Μ',
  '𝜨' => 'Ν',
  '𝜩' => 'Ξ',
  '𝜪' => 'Ο',
  '𝜫' => 'Π',
  '𝜬' => 'Ρ',
  '𝜭' => 'ϴ',
  '𝜮' => 'Σ',
  '𝜯' => 'Τ',
  '𝜰' => 'Υ',
  '𝜱' => 'Φ',
  '𝜲' => 'Χ',
  '𝜳' => 'Ψ',
  '𝜴' => 'Ω',
  '𝜵' => '∇',
  '𝜶' => 'α',
  '𝜷' => 'β',
  '𝜸' => 'γ',
  '𝜹' => 'δ',
  '𝜺' => 'ε',
  '𝜻' => 'ζ',
  '𝜼' => 'η',
  '𝜽' => 'θ',
  '𝜾' => 'ι',
  '𝜿' => 'κ',
  '𝝀' => 'λ',
  '𝝁' => 'μ',
  '𝝂' => 'ν',
  '𝝃' => 'ξ',
  '𝝄' => 'ο',
  '𝝅' => 'π',
  '𝝆' => 'ρ',
  '𝝇' => 'ς',
  '𝝈' => 'σ',
  '𝝉' => 'τ',
  '𝝊' => 'υ',
  '𝝋' => 'φ',
  '𝝌' => 'χ',
  '𝝍' => 'ψ',
  '𝝎' => 'ω',
  '𝝏' => '∂',
  '𝝐' => 'ϵ',
  '𝝑' => 'ϑ',
  '𝝒' => 'ϰ',
  '𝝓' => 'ϕ',
  '𝝔' => 'ϱ',
  '𝝕' => 'ϖ',
  '𝝖' => 'Α',
  '𝝗' => 'Β',
  '𝝘' => 'Γ',
  '𝝙' => 'Δ',
  '𝝚' => 'Ε',
  '𝝛' => 'Ζ',
  '𝝜' => 'Η',
  '𝝝' => 'Θ',
  '𝝞' => 'Ι',
  '𝝟' => 'Κ',
  '𝝠' => 'Λ',
  '𝝡' => 'Μ',
  '𝝢' => 'Ν',
  '𝝣' => 'Ξ',
  '𝝤' => 'Ο',
  '𝝥' => 'Π',
  '𝝦' => 'Ρ',
  '𝝧' => 'ϴ',
  '𝝨' => 'Σ',
  '𝝩' => 'Τ',
  '𝝪' => 'Υ',
  '𝝫' => 'Φ',
  '𝝬' => 'Χ',
  '𝝭' => 'Ψ',
  '𝝮' => 'Ω',
  '𝝯' => '∇',
  '𝝰' => 'α',
  '𝝱' => 'β',
  '𝝲' => 'γ',
  '𝝳' => 'δ',
  '𝝴' => 'ε',
  '𝝵' => 'ζ',
  '𝝶' => 'η',
  '𝝷' => 'θ',
  '𝝸' => 'ι',
  '𝝹' => 'κ',
  '𝝺' => 'λ',
  '𝝻' => 'μ',
  '𝝼' => 'ν',
  '𝝽' => 'ξ',
  '𝝾' => 'ο',
  '𝝿' => 'π',
  '𝞀' => 'ρ',
  '𝞁' => 'ς',
  '𝞂' => 'σ',
  '𝞃' => 'τ',
  '𝞄' => 'υ',
  '𝞅' => 'φ',
  '𝞆' => 'χ',
  '𝞇' => 'ψ',
  '𝞈' => 'ω',
  '𝞉' => '∂',
  '𝞊' => 'ϵ',
  '𝞋' => 'ϑ',
  '𝞌' => 'ϰ',
  '𝞍' => 'ϕ',
  '𝞎' => 'ϱ',
  '𝞏' => 'ϖ',
  '𝞐' => 'Α',
  '𝞑' => 'Β',
  '𝞒' => 'Γ',
  '𝞓' => 'Δ',
  '𝞔' => 'Ε',
  '𝞕' => 'Ζ',
  '𝞖' => 'Η',
  '𝞗' => 'Θ',
  '𝞘' => 'Ι',
  '𝞙' => 'Κ',
  '𝞚' => 'Λ',
  '𝞛' => 'Μ',
  '𝞜' => 'Ν',
  '𝞝' => 'Ξ',
  '𝞞' => 'Ο',
  '𝞟' => 'Π',
  '𝞠' => 'Ρ',
  '𝞡' => 'ϴ',
  '𝞢' => 'Σ',
  '𝞣' => 'Τ',
  '𝞤' => 'Υ',
  '𝞥' => 'Φ',
  '𝞦' => 'Χ',
  '𝞧' => 'Ψ',
  '𝞨' => 'Ω',
  '𝞩' => '∇',
  '𝞪' => 'α',
  '𝞫' => 'β',
  '𝞬' => 'γ',
  '𝞭' => 'δ',
  '𝞮' => 'ε',
  '𝞯' => 'ζ',
  '𝞰' => 'η',
  '𝞱' => 'θ',
  '𝞲' => 'ι',
  '𝞳' => 'κ',
  '𝞴' => 'λ',
  '𝞵' => 'μ',
  '𝞶' => 'ν',
  '𝞷' => 'ξ',
  '𝞸' => 'ο',
  '𝞹' => 'π',
  '𝞺' => 'ρ',
  '𝞻' => 'ς',
  '𝞼' => 'σ',
  '𝞽' => 'τ',
  '𝞾' => 'υ',
  '𝞿' => 'φ',
  '𝟀' => 'χ',
  '𝟁' => 'ψ',
  '𝟂' => 'ω',
  '𝟃' => '∂',
  '𝟄' => 'ϵ',
  '𝟅' => 'ϑ',
  '𝟆' => 'ϰ',
  '𝟇' => 'ϕ',
  '𝟈' => 'ϱ',
  '𝟉' => 'ϖ',
  '𝟊' => 'Ϝ',
  '𝟋' => 'ϝ',
  '𝟎' => '0',
  '𝟏' => '1',
  '𝟐' => '2',
  '𝟑' => '3',
  '𝟒' => '4',
  '𝟓' => '5',
  '𝟔' => '6',
  '𝟕' => '7',
  '𝟖' => '8',
  '𝟗' => '9',
  '𝟘' => '0',
  '𝟙' => '1',
  '𝟚' => '2',
  '𝟛' => '3',
  '𝟜' => '4',
  '𝟝' => '5',
  '𝟞' => '6',
  '𝟟' => '7',
  '𝟠' => '8',
  '𝟡' => '9',
  '𝟢' => '0',
  '𝟣' => '1',
  '𝟤' => '2',
  '𝟥' => '3',
  '𝟦' => '4',
  '𝟧' => '5',
  '𝟨' => '6',
  '𝟩' => '7',
  '𝟪' => '8',
  '𝟫' => '9',
  '𝟬' => '0',
  '𝟭' => '1',
  '𝟮' => '2',
  '𝟯' => '3',
  '𝟰' => '4',
  '𝟱' => '5',
  '𝟲' => '6',
  '𝟳' => '7',
  '𝟴' => '8',
  '𝟵' => '9',
  '𝟶' => '0',
  '𝟷' => '1',
  '𝟸' => '2',
  '𝟹' => '3',
  '𝟺' => '4',
  '𝟻' => '5',
  '𝟼' => '6',
  '𝟽' => '7',
  '𝟾' => '8',
  '𝟿' => '9',
  '𞸀' => 'ا',
  '𞸁' => 'ب',
  '𞸂' => 'ج',
  '𞸃' => 'د',
  '𞸅' => 'و',
  '𞸆' => 'ز',
  '𞸇' => 'ح',
  '𞸈' => 'ط',
  '𞸉' => 'ي',
  '𞸊' => 'ك',
  '𞸋' => 'ل',
  '𞸌' => 'م',
  '𞸍' => 'ن',
  '𞸎' => 'س',
  '𞸏' => 'ع',
  '𞸐' => 'ف',
  '𞸑' => 'ص',
  '𞸒' => 'ق',
  '𞸓' => 'ر',
  '𞸔' => 'ش',
  '𞸕' => 'ت',
  '𞸖' => 'ث',
  '𞸗' => 'خ',
  '𞸘' => 'ذ',
  '𞸙' => 'ض',
  '𞸚' => 'ظ',
  '𞸛' => 'غ',
  '𞸜' => 'ٮ',
  '𞸝' => 'ں',
  '𞸞' => 'ڡ',
  '𞸟' => 'ٯ',
  '𞸡' => 'ب',
  '𞸢' => 'ج',
  '𞸤' => 'ه',
  '𞸧' => 'ح',
  '𞸩' => 'ي',
  '𞸪' => 'ك',
  '𞸫' => 'ل',
  '𞸬' => 'م',
  '𞸭' => 'ن',
  '𞸮' => 'س',
  '𞸯' => 'ع',
  '𞸰' => 'ف',
  '𞸱' => 'ص',
  '𞸲' => 'ق',
  '𞸴' => 'ش',
  '𞸵' => 'ت',
  '𞸶' => 'ث',
  '𞸷' => 'خ',
  '𞸹' => 'ض',
  '𞸻' => 'غ',
  '𞹂' => 'ج',
  '𞹇' => 'ح',
  '𞹉' => 'ي',
  '𞹋' => 'ل',
  '𞹍' => 'ن',
  '𞹎' => 'س',
  '𞹏' => 'ع',
  '𞹑' => 'ص',
  '𞹒' => 'ق',
  '𞹔' => 'ش',
  '𞹗' => 'خ',
  '𞹙' => 'ض',
  '𞹛' => 'غ',
  '𞹝' => 'ں',
  '𞹟' => 'ٯ',
  '𞹡' => 'ب',
  '𞹢' => 'ج',
  '𞹤' => 'ه',
  '𞹧' => 'ح',
  '𞹨' => 'ط',
  '𞹩' => 'ي',
  '𞹪' => 'ك',
  '𞹬' => 'م',
  '𞹭' => 'ن',
  '𞹮' => 'س',
  '𞹯' => 'ع',
  '𞹰' => 'ف',
  '𞹱' => 'ص',
  '𞹲' => 'ق',
  '𞹴' => 'ش',
  '𞹵' => 'ت',
  '𞹶' => 'ث',
  '𞹷' => 'خ',
  '𞹹' => 'ض',
  '𞹺' => 'ظ',
  '𞹻' => 'غ',
  '𞹼' => 'ٮ',
  '𞹾' => 'ڡ',
  '𞺀' => 'ا',
  '𞺁' => 'ب',
  '𞺂' => 'ج',
  '𞺃' => 'د',
  '𞺄' => 'ه',
  '𞺅' => 'و',
  '𞺆' => 'ز',
  '𞺇' => 'ح',
  '𞺈' => 'ط',
  '𞺉' => 'ي',
  '𞺋' => 'ل',
  '𞺌' => 'م',
  '𞺍' => 'ن',
  '𞺎' => 'س',
  '𞺏' => 'ع',
  '𞺐' => 'ف',
  '𞺑' => 'ص',
  '𞺒' => 'ق',
  '𞺓' => 'ر',
  '𞺔' => 'ش',
  '𞺕' => 'ت',
  '𞺖' => 'ث',
  '𞺗' => 'خ',
  '𞺘' => 'ذ',
  '𞺙' => 'ض',
  '𞺚' => 'ظ',
  '𞺛' => 'غ',
  '𞺡' => 'ب',
  '𞺢' => 'ج',
  '𞺣' => 'د',
  '𞺥' => 'و',
  '𞺦' => 'ز',
  '𞺧' => 'ح',
  '𞺨' => 'ط',
  '𞺩' => 'ي',
  '𞺫' => 'ل',
  '𞺬' => 'م',
  '𞺭' => 'ن',
  '𞺮' => 'س',
  '𞺯' => 'ع',
  '𞺰' => 'ف',
  '𞺱' => 'ص',
  '𞺲' => 'ق',
  '𞺳' => 'ر',
  '𞺴' => 'ش',
  '𞺵' => 'ت',
  '𞺶' => 'ث',
  '𞺷' => 'خ',
  '𞺸' => 'ذ',
  '𞺹' => 'ض',
  '𞺺' => 'ظ',
  '𞺻' => 'غ',
  '🄀' => '0.',
  '🄁' => '0,',
  '🄂' => '1,',
  '🄃' => '2,',
  '🄄' => '3,',
  '🄅' => '4,',
  '🄆' => '5,',
  '🄇' => '6,',
  '🄈' => '7,',
  '🄉' => '8,',
  '🄊' => '9,',
  '🄐' => '(A)',
  '🄑' => '(B)',
  '🄒' => '(C)',
  '🄓' => '(D)',
  '🄔' => '(E)',
  '🄕' => '(F)',
  '🄖' => '(G)',
  '🄗' => '(H)',
  '🄘' => '(I)',
  '🄙' => '(J)',
  '🄚' => '(K)',
  '🄛' => '(L)',
  '🄜' => '(M)',
  '🄝' => '(N)',
  '🄞' => '(O)',
  '🄟' => '(P)',
  '🄠' => '(Q)',
  '🄡' => '(R)',
  '🄢' => '(S)',
  '🄣' => '(T)',
  '🄤' => '(U)',
  '🄥' => '(V)',
  '🄦' => '(W)',
  '🄧' => '(X)',
  '🄨' => '(Y)',
  '🄩' => '(Z)',
  '🄪' => '〔S〕',
  '🄫' => '(C)',
  '🄬' => '(R)',
  '🄭' => '(CD)',
  '🄮' => '(WZ)',
  '🄰' => 'A',
  '🄱' => 'B',
  '🄲' => 'C',
  '🄳' => 'D',
  '🄴' => 'E',
  '🄵' => 'F',
  '🄶' => 'G',
  '🄷' => 'H',
  '🄸' => 'I',
  '🄹' => 'J',
  '🄺' => 'K',
  '🄻' => 'L',
  '🄼' => 'M',
  '🄽' => 'N',
  '🄾' => 'O',
  '🄿' => 'P',
  '🅀' => 'Q',
  '🅁' => 'R',
  '🅂' => 'S',
  '🅃' => 'T',
  '🅄' => 'U',
  '🅅' => 'V',
  '🅆' => 'W',
  '🅇' => 'X',
  '🅈' => 'Y',
  '🅉' => 'Z',
  '🅊' => 'HV',
  '🅋' => 'MV',
  '🅌' => 'SD',
  '🅍' => 'SS',
  '🅎' => 'PPV',
  '🅏' => 'WC',
  '🆐' => 'DJ',
  '🈀' => 'ほか',
  '🈁' => 'ココ',
  '🈂' => 'サ',
  '🈐' => '手',
  '🈑' => '字',
  '🈒' => '双',
  '🈓' => 'デ',
  '🈔' => '二',
  '🈕' => '多',
  '🈖' => '解',
  '🈗' => '天',
  '🈘' => '交',
  '🈙' => '映',
  '🈚' => '無',
  '🈛' => '料',
  '🈜' => '前',
  '🈝' => '後',
  '🈞' => '再',
  '🈟' => '新',
  '🈠' => '初',
  '🈡' => '終',
  '🈢' => '生',
  '🈣' => '販',
  '🈤' => '声',
  '🈥' => '吹',
  '🈦' => '演',
  '🈧' => '投',
  '🈨' => '捕',
  '🈩' => '一',
  '🈪' => '三',
  '🈫' => '遊',
  '🈬' => '左',
  '🈭' => '中',
  '🈮' => '右',
  '🈯' => '指',
  '🈰' => '走',
  '🈱' => '打',
  '🈲' => '禁',
  '🈳' => '空',
  '🈴' => '合',
  '🈵' => '満',
  '🈶' => '有',
  '🈷' => '月',
  '🈸' => '申',
  '🈹' => '割',
  '🈺' => '営',
  '🈻' => '配',
  '🉀' => '〔本〕',
  '🉁' => '〔三〕',
  '🉂' => '〔二〕',
  '🉃' => '〔安〕',
  '🉄' => '〔点〕',
  '🉅' => '〔打〕',
  '🉆' => '〔盗〕',
  '🉇' => '〔勝〕',
  '🉈' => '〔敗〕',
  '🉐' => '(得)',
  '🉑' => '(可)',
  '🯰' => '0',
  '🯱' => '1',
  '🯲' => '2',
  '🯳' => '3',
  '🯴' => '4',
  '🯵' => '5',
  '🯶' => '6',
  '🯷' => '7',
  '🯸' => '8',
  '🯹' => '9',
  '丽' => '丽',
  '丸' => '丸',
  '乁' => '乁',
  '𠄢' => '𠄢',
  '你' => '你',
  '侮' => '侮',
  '侻' => '侻',
  '倂' => '倂',
  '偺' => '偺',
  '備' => '備',
  '僧' => '僧',
  '像' => '像',
  '㒞' => '㒞',
  '𠘺' => '𠘺',
  '免' => '免',
  '兔' => '兔',
  '兤' => '兤',
  '具' => '具',
  '𠔜' => '𠔜',
  '㒹' => '㒹',
  '內' => '內',
  '再' => '再',
  '𠕋' => '𠕋',
  '冗' => '冗',
  '冤' => '冤',
  '仌' => '仌',
  '冬' => '冬',
  '况' => '况',
  '𩇟' => '𩇟',
  '凵' => '凵',
  '刃' => '刃',
  '㓟' => '㓟',
  '刻' => '刻',
  '剆' => '剆',
  '割' => '割',
  '剷' => '剷',
  '㔕' => '㔕',
  '勇' => '勇',
  '勉' => '勉',
  '勤' => '勤',
  '勺' => '勺',
  '包' => '包',
  '匆' => '匆',
  '北' => '北',
  '卉' => '卉',
  '卑' => '卑',
  '博' => '博',
  '即' => '即',
  '卽' => '卽',
  '卿' => '卿',
  '卿' => '卿',
  '卿' => '卿',
  '𠨬' => '𠨬',
  '灰' => '灰',
  '及' => '及',
  '叟' => '叟',
  '𠭣' => '𠭣',
  '叫' => '叫',
  '叱' => '叱',
  '吆' => '吆',
  '咞' => '咞',
  '吸' => '吸',
  '呈' => '呈',
  '周' => '周',
  '咢' => '咢',
  '哶' => '哶',
  '唐' => '唐',
  '啓' => '啓',
  '啣' => '啣',
  '善' => '善',
  '善' => '善',
  '喙' => '喙',
  '喫' => '喫',
  '喳' => '喳',
  '嗂' => '嗂',
  '圖' => '圖',
  '嘆' => '嘆',
  '圗' => '圗',
  '噑' => '噑',
  '噴' => '噴',
  '切' => '切',
  '壮' => '壮',
  '城' => '城',
  '埴' => '埴',
  '堍' => '堍',
  '型' => '型',
  '堲' => '堲',
  '報' => '報',
  '墬' => '墬',
  '𡓤' => '𡓤',
  '売' => '売',
  '壷' => '壷',
  '夆' => '夆',
  '多' => '多',
  '夢' => '夢',
  '奢' => '奢',
  '𡚨' => '𡚨',
  '𡛪' => '𡛪',
  '姬' => '姬',
  '娛' => '娛',
  '娧' => '娧',
  '姘' => '姘',
  '婦' => '婦',
  '㛮' => '㛮',
  '㛼' => '㛼',
  '嬈' => '嬈',
  '嬾' => '嬾',
  '嬾' => '嬾',
  '𡧈' => '𡧈',
  '寃' => '寃',
  '寘' => '寘',
  '寧' => '寧',
  '寳' => '寳',
  '𡬘' => '𡬘',
  '寿' => '寿',
  '将' => '将',
  '当' => '当',
  '尢' => '尢',
  '㞁' => '㞁',
  '屠' => '屠',
  '屮' => '屮',
  '峀' => '峀',
  '岍' => '岍',
  '𡷤' => '𡷤',
  '嵃' => '嵃',
  '𡷦' => '𡷦',
  '嵮' => '嵮',
  '嵫' => '嵫',
  '嵼' => '嵼',
  '巡' => '巡',
  '巢' => '巢',
  '㠯' => '㠯',
  '巽' => '巽',
  '帨' => '帨',
  '帽' => '帽',
  '幩' => '幩',
  '㡢' => '㡢',
  '𢆃' => '𢆃',
  '㡼' => '㡼',
  '庰' => '庰',
  '庳' => '庳',
  '庶' => '庶',
  '廊' => '廊',
  '𪎒' => '𪎒',
  '廾' => '廾',
  '𢌱' => '𢌱',
  '𢌱' => '𢌱',
  '舁' => '舁',
  '弢' => '弢',
  '弢' => '弢',
  '㣇' => '㣇',
  '𣊸' => '𣊸',
  '𦇚' => '𦇚',
  '形' => '形',
  '彫' => '彫',
  '㣣' => '㣣',
  '徚' => '徚',
  '忍' => '忍',
  '志' => '志',
  '忹' => '忹',
  '悁' => '悁',
  '㤺' => '㤺',
  '㤜' => '㤜',
  '悔' => '悔',
  '𢛔' => '𢛔',
  '惇' => '惇',
  '慈' => '慈',
  '慌' => '慌',
  '慎' => '慎',
  '慌' => '慌',
  '慺' => '慺',
  '憎' => '憎',
  '憲' => '憲',
  '憤' => '憤',
  '憯' => '憯',
  '懞' => '懞',
  '懲' => '懲',
  '懶' => '懶',
  '成' => '成',
  '戛' => '戛',
  '扝' => '扝',
  '抱' => '抱',
  '拔' => '拔',
  '捐' => '捐',
  '𢬌' => '𢬌',
  '挽' => '挽',
  '拼' => '拼',
  '捨' => '捨',
  '掃' => '掃',
  '揤' => '揤',
  '𢯱' => '𢯱',
  '搢' => '搢',
  '揅' => '揅',
  '掩' => '掩',
  '㨮' => '㨮',
  '摩' => '摩',
  '摾' => '摾',
  '撝' => '撝',
  '摷' => '摷',
  '㩬' => '㩬',
  '敏' => '敏',
  '敬' => '敬',
  '𣀊' => '𣀊',
  '旣' => '旣',
  '書' => '書',
  '晉' => '晉',
  '㬙' => '㬙',
  '暑' => '暑',
  '㬈' => '㬈',
  '㫤' => '㫤',
  '冒' => '冒',
  '冕' => '冕',
  '最' => '最',
  '暜' => '暜',
  '肭' => '肭',
  '䏙' => '䏙',
  '朗' => '朗',
  '望' => '望',
  '朡' => '朡',
  '杞' => '杞',
  '杓' => '杓',
  '𣏃' => '𣏃',
  '㭉' => '㭉',
  '柺' => '柺',
  '枅' => '枅',
  '桒' => '桒',
  '梅' => '梅',
  '𣑭' => '𣑭',
  '梎' => '梎',
  '栟' => '栟',
  '椔' => '椔',
  '㮝' => '㮝',
  '楂' => '楂',
  '榣' => '榣',
  '槪' => '槪',
  '檨' => '檨',
  '𣚣' => '𣚣',
  '櫛' => '櫛',
  '㰘' => '㰘',
  '次' => '次',
  '𣢧' => '𣢧',
  '歔' => '歔',
  '㱎' => '㱎',
  '歲' => '歲',
  '殟' => '殟',
  '殺' => '殺',
  '殻' => '殻',
  '𣪍' => '𣪍',
  '𡴋' => '𡴋',
  '𣫺' => '𣫺',
  '汎' => '汎',
  '𣲼' => '𣲼',
  '沿' => '沿',
  '泍' => '泍',
  '汧' => '汧',
  '洖' => '洖',
  '派' => '派',
  '海' => '海',
  '流' => '流',
  '浩' => '浩',
  '浸' => '浸',
  '涅' => '涅',
  '𣴞' => '𣴞',
  '洴' => '洴',
  '港' => '港',
  '湮' => '湮',
  '㴳' => '㴳',
  '滋' => '滋',
  '滇' => '滇',
  '𣻑' => '𣻑',
  '淹' => '淹',
  '潮' => '潮',
  '𣽞' => '𣽞',
  '𣾎' => '𣾎',
  '濆' => '濆',
  '瀹' => '瀹',
  '瀞' => '瀞',
  '瀛' => '瀛',
  '㶖' => '㶖',
  '灊' => '灊',
  '災' => '災',
  '灷' => '灷',
  '炭' => '炭',
  '𠔥' => '𠔥',
  '煅' => '煅',
  '𤉣' => '𤉣',
  '熜' => '熜',
  '𤎫' => '𤎫',
  '爨' => '爨',
  '爵' => '爵',
  '牐' => '牐',
  '𤘈' => '𤘈',
  '犀' => '犀',
  '犕' => '犕',
  '𤜵' => '𤜵',
  '𤠔' => '𤠔',
  '獺' => '獺',
  '王' => '王',
  '㺬' => '㺬',
  '玥' => '玥',
  '㺸' => '㺸',
  '㺸' => '㺸',
  '瑇' => '瑇',
  '瑜' => '瑜',
  '瑱' => '瑱',
  '璅' => '璅',
  '瓊' => '瓊',
  '㼛' => '㼛',
  '甤' => '甤',
  '𤰶' => '𤰶',
  '甾' => '甾',
  '𤲒' => '𤲒',
  '異' => '異',
  '𢆟' => '𢆟',
  '瘐' => '瘐',
  '𤾡' => '𤾡',
  '𤾸' => '𤾸',
  '𥁄' => '𥁄',
  '㿼' => '㿼',
  '䀈' => '䀈',
  '直' => '直',
  '𥃳' => '𥃳',
  '𥃲' => '𥃲',
  '𥄙' => '𥄙',
  '𥄳' => '𥄳',
  '眞' => '眞',
  '真' => '真',
  '真' => '真',
  '睊' => '睊',
  '䀹' => '䀹',
  '瞋' => '瞋',
  '䁆' => '䁆',
  '䂖' => '䂖',
  '𥐝' => '𥐝',
  '硎' => '硎',
  '碌' => '碌',
  '磌' => '磌',
  '䃣' => '䃣',
  '𥘦' => '𥘦',
  '祖' => '祖',
  '𥚚' => '𥚚',
  '𥛅' => '𥛅',
  '福' => '福',
  '秫' => '秫',
  '䄯' => '䄯',
  '穀' => '穀',
  '穊' => '穊',
  '穏' => '穏',
  '𥥼' => '𥥼',
  '𥪧' => '𥪧',
  '𥪧' => '𥪧',
  '竮' => '竮',
  '䈂' => '䈂',
  '𥮫' => '𥮫',
  '篆' => '篆',
  '築' => '築',
  '䈧' => '䈧',
  '𥲀' => '𥲀',
  '糒' => '糒',
  '䊠' => '䊠',
  '糨' => '糨',
  '糣' => '糣',
  '紀' => '紀',
  '𥾆' => '𥾆',
  '絣' => '絣',
  '䌁' => '䌁',
  '緇' => '緇',
  '縂' => '縂',
  '繅' => '繅',
  '䌴' => '䌴',
  '𦈨' => '𦈨',
  '𦉇' => '𦉇',
  '䍙' => '䍙',
  '𦋙' => '𦋙',
  '罺' => '罺',
  '𦌾' => '𦌾',
  '羕' => '羕',
  '翺' => '翺',
  '者' => '者',
  '𦓚' => '𦓚',
  '𦔣' => '𦔣',
  '聠' => '聠',
  '𦖨' => '𦖨',
  '聰' => '聰',
  '𣍟' => '𣍟',
  '䏕' => '䏕',
  '育' => '育',
  '脃' => '脃',
  '䐋' => '䐋',
  '脾' => '脾',
  '媵' => '媵',
  '𦞧' => '𦞧',
  '𦞵' => '𦞵',
  '𣎓' => '𣎓',
  '𣎜' => '𣎜',
  '舁' => '舁',
  '舄' => '舄',
  '辞' => '辞',
  '䑫' => '䑫',
  '芑' => '芑',
  '芋' => '芋',
  '芝' => '芝',
  '劳' => '劳',
  '花' => '花',
  '芳' => '芳',
  '芽' => '芽',
  '苦' => '苦',
  '𦬼' => '𦬼',
  '若' => '若',
  '茝' => '茝',
  '荣' => '荣',
  '莭' => '莭',
  '茣' => '茣',
  '莽' => '莽',
  '菧' => '菧',
  '著' => '著',
  '荓' => '荓',
  '菊' => '菊',
  '菌' => '菌',
  '菜' => '菜',
  '𦰶' => '𦰶',
  '𦵫' => '𦵫',
  '𦳕' => '𦳕',
  '䔫' => '䔫',
  '蓱' => '蓱',
  '蓳' => '蓳',
  '蔖' => '蔖',
  '𧏊' => '𧏊',
  '蕤' => '蕤',
  '𦼬' => '𦼬',
  '䕝' => '䕝',
  '䕡' => '䕡',
  '𦾱' => '𦾱',
  '𧃒' => '𧃒',
  '䕫' => '䕫',
  '虐' => '虐',
  '虜' => '虜',
  '虧' => '虧',
  '虩' => '虩',
  '蚩' => '蚩',
  '蚈' => '蚈',
  '蜎' => '蜎',
  '蛢' => '蛢',
  '蝹' => '蝹',
  '蜨' => '蜨',
  '蝫' => '蝫',
  '螆' => '螆',
  '䗗' => '䗗',
  '蟡' => '蟡',
  '蠁' => '蠁',
  '䗹' => '䗹',
  '衠' => '衠',
  '衣' => '衣',
  '𧙧' => '𧙧',
  '裗' => '裗',
  '裞' => '裞',
  '䘵' => '䘵',
  '裺' => '裺',
  '㒻' => '㒻',
  '𧢮' => '𧢮',
  '𧥦' => '𧥦',
  '䚾' => '䚾',
  '䛇' => '䛇',
  '誠' => '誠',
  '諭' => '諭',
  '變' => '變',
  '豕' => '豕',
  '𧲨' => '𧲨',
  '貫' => '貫',
  '賁' => '賁',
  '贛' => '贛',
  '起' => '起',
  '𧼯' => '𧼯',
  '𠠄' => '𠠄',
  '跋' => '跋',
  '趼' => '趼',
  '跰' => '跰',
  '𠣞' => '𠣞',
  '軔' => '軔',
  '輸' => '輸',
  '𨗒' => '𨗒',
  '𨗭' => '𨗭',
  '邔' => '邔',
  '郱' => '郱',
  '鄑' => '鄑',
  '𨜮' => '𨜮',
  '鄛' => '鄛',
  '鈸' => '鈸',
  '鋗' => '鋗',
  '鋘' => '鋘',
  '鉼' => '鉼',
  '鏹' => '鏹',
  '鐕' => '鐕',
  '𨯺' => '𨯺',
  '開' => '開',
  '䦕' => '䦕',
  '閷' => '閷',
  '𨵷' => '𨵷',
  '䧦' => '䧦',
  '雃' => '雃',
  '嶲' => '嶲',
  '霣' => '霣',
  '𩅅' => '𩅅',
  '𩈚' => '𩈚',
  '䩮' => '䩮',
  '䩶' => '䩶',
  '韠' => '韠',
  '𩐊' => '𩐊',
  '䪲' => '䪲',
  '𩒖' => '𩒖',
  '頋' => '頋',
  '頋' => '頋',
  '頩' => '頩',
  '𩖶' => '𩖶',
  '飢' => '飢',
  '䬳' => '䬳',
  '餩' => '餩',
  '馧' => '馧',
  '駂' => '駂',
  '駾' => '駾',
  '䯎' => '䯎',
  '𩬰' => '𩬰',
  '鬒' => '鬒',
  '鱀' => '鱀',
  '鳽' => '鳽',
  '䳎' => '䳎',
  '䳭' => '䳭',
  '鵧' => '鵧',
  '𪃎' => '𪃎',
  '䳸' => '䳸',
  '𪄅' => '𪄅',
  '𪈎' => '𪈎',
  '𪊑' => '𪊑',
  '麻' => '麻',
  '䵖' => '䵖',
  '黹' => '黹',
  '黾' => '黾',
  '鼅' => '鼅',
  '鼏' => '鼏',
  '鼖' => '鼖',
  '鼻' => '鼻',
  '𪘀' => '𪘀',
  'Æ' => 'AE',
  'Ð' => 'D',
  'Ø' => 'O',
  'Þ' => 'TH',
  'ß' => 'ss',
  'æ' => 'ae',
  'ð' => 'd',
  'ø' => 'o',
  'þ' => 'th',
  'Đ' => 'D',
  'đ' => 'd',
  'Ħ' => 'H',
  'ħ' => 'h',
  'ı' => 'i',
  'ĸ' => 'q',
  'Ł' => 'L',
  'ł' => 'l',
  'Ŋ' => 'N',
  'ŋ' => 'n',
  'Œ' => 'OE',
  'œ' => 'oe',
  'Ŧ' => 'T',
  'ŧ' => 't',
  'ƀ' => 'b',
  'Ɓ' => 'B',
  'Ƃ' => 'B',
  'ƃ' => 'b',
  'Ƈ' => 'C',
  'ƈ' => 'c',
  'Ɖ' => 'D',
  'Ɗ' => 'D',
  'Ƌ' => 'D',
  'ƌ' => 'd',
  'Ɛ' => 'E',
  'Ƒ' => 'F',
  'ƒ' => 'f',
  'Ɠ' => 'G',
  'ƕ' => 'hv',
  'Ɩ' => 'I',
  'Ɨ' => 'I',
  'Ƙ' => 'K',
  'ƙ' => 'k',
  'ƚ' => 'l',
  'Ɲ' => 'N',
  'ƞ' => 'n',
  'Ƣ' => 'OI',
  'ƣ' => 'oi',
  'Ƥ' => 'P',
  'ƥ' => 'p',
  'ƫ' => 't',
  'Ƭ' => 'T',
  'ƭ' => 't',
  'Ʈ' => 'T',
  'Ʋ' => 'V',
  'Ƴ' => 'Y',
  'ƴ' => 'y',
  'Ƶ' => 'Z',
  'ƶ' => 'z',
  'Ǥ' => 'G',
  'ǥ' => 'g',
  'ȡ' => 'd',
  'Ȥ' => 'Z',
  'ȥ' => 'z',
  'ȴ' => 'l',
  'ȵ' => 'n',
  'ȶ' => 't',
  'ȷ' => 'j',
  'ȸ' => 'db',
  'ȹ' => 'qp',
  'Ⱥ' => 'A',
  'Ȼ' => 'C',
  'ȼ' => 'c',
  'Ƚ' => 'L',
  'Ⱦ' => 'T',
  'ȿ' => 's',
  'ɀ' => 'z',
  'Ƀ' => 'B',
  'Ʉ' => 'U',
  'Ɇ' => 'E',
  'ɇ' => 'e',
  'Ɉ' => 'J',
  'ɉ' => 'j',
  'Ɍ' => 'R',
  'ɍ' => 'r',
  'Ɏ' => 'Y',
  'ɏ' => 'y',
  'ɓ' => 'b',
  'ɕ' => 'c',
  'ɖ' => 'd',
  'ɗ' => 'd',
  'ɛ' => 'e',
  'ɟ' => 'j',
  'ɠ' => 'g',
  'ɡ' => 'g',
  'ɢ' => 'G',
  'ɦ' => 'h',
  'ɧ' => 'h',
  'ɨ' => 'i',
  'ɪ' => 'I',
  'ɫ' => 'l',
  'ɬ' => 'l',
  'ɭ' => 'l',
  'ɱ' => 'm',
  'ɲ' => 'n',
  'ɳ' => 'n',
  'ɴ' => 'N',
  'ɶ' => 'OE',
  'ɼ' => 'r',
  'ɽ' => 'r',
  'ɾ' => 'r',
  'ʀ' => 'R',
  'ʂ' => 's',
  'ʈ' => 't',
  'ʉ' => 'u',
  'ʋ' => 'v',
  'ʏ' => 'Y',
  'ʐ' => 'z',
  'ʑ' => 'z',
  'ʙ' => 'B',
  'ʛ' => 'G',
  'ʜ' => 'H',
  'ʝ' => 'j',
  'ʟ' => 'L',
  'ʠ' => 'q',
  'ʣ' => 'dz',
  'ʥ' => 'dz',
  'ʦ' => 'ts',
  'ʪ' => 'ls',
  'ʫ' => 'lz',
  'ᴀ' => 'A',
  'ᴁ' => 'AE',
  'ᴃ' => 'B',
  'ᴄ' => 'C',
  'ᴅ' => 'D',
  'ᴆ' => 'D',
  'ᴇ' => 'E',
  'ᴊ' => 'J',
  'ᴋ' => 'K',
  'ᴌ' => 'L',
  'ᴍ' => 'M',
  'ᴏ' => 'O',
  'ᴘ' => 'P',
  'ᴛ' => 'T',
  'ᴜ' => 'U',
  'ᴠ' => 'V',
  'ᴡ' => 'W',
  'ᴢ' => 'Z',
  'ᵫ' => 'ue',
  'ᵬ' => 'b',
  'ᵭ' => 'd',
  'ᵮ' => 'f',
  'ᵯ' => 'm',
  'ᵰ' => 'n',
  'ᵱ' => 'p',
  'ᵲ' => 'r',
  'ᵳ' => 'r',
  'ᵴ' => 's',
  'ᵵ' => 't',
  'ᵶ' => 'z',
  'ᵺ' => 'th',
  'ᵻ' => 'I',
  'ᵽ' => 'p',
  'ᵾ' => 'U',
  'ᶀ' => 'b',
  'ᶁ' => 'd',
  'ᶂ' => 'f',
  'ᶃ' => 'g',
  'ᶄ' => 'k',
  'ᶅ' => 'l',
  'ᶆ' => 'm',
  'ᶇ' => 'n',
  'ᶈ' => 'p',
  'ᶉ' => 'r',
  'ᶊ' => 's',
  'ᶌ' => 'v',
  'ᶍ' => 'x',
  'ᶎ' => 'z',
  'ᶏ' => 'a',
  'ᶑ' => 'd',
  'ᶒ' => 'e',
  'ᶓ' => 'e',
  'ᶖ' => 'i',
  'ᶙ' => 'u',
  'ẜ' => 's',
  'ẝ' => 's',
  'ẞ' => 'SS',
  'Ỻ' => 'LL',
  'ỻ' => 'll',
  'Ỽ' => 'V',
  'ỽ' => 'v',
  'Ỿ' => 'Y',
  'ỿ' => 'y',
  'Ⱡ' => 'L',
  'ⱡ' => 'l',
  'Ɫ' => 'L',
  'Ᵽ' => 'P',
  'Ɽ' => 'R',
  'ⱥ' => 'a',
  'ⱦ' => 't',
  'Ⱨ' => 'H',
  'ⱨ' => 'h',
  'Ⱪ' => 'K',
  'ⱪ' => 'k',
  'Ⱬ' => 'Z',
  'ⱬ' => 'z',
  'Ɱ' => 'M',
  'ⱱ' => 'v',
  'Ⱳ' => 'W',
  'ⱳ' => 'w',
  'ⱴ' => 'v',
  'ⱸ' => 'e',
  'ⱺ' => 'o',
  'Ȿ' => 'S',
  'Ɀ' => 'Z',
  'ꜰ' => 'F',
  'ꜱ' => 'S',
  'Ꜳ' => 'AA',
  'ꜳ' => 'aa',
  'Ꜵ' => 'AO',
  'ꜵ' => 'ao',
  'Ꜷ' => 'AU',
  'ꜷ' => 'au',
  'Ꜹ' => 'AV',
  'ꜹ' => 'av',
  'Ꜻ' => 'AV',
  'ꜻ' => 'av',
  'Ꜽ' => 'AY',
  'ꜽ' => 'ay',
  'Ꝁ' => 'K',
  'ꝁ' => 'k',
  'Ꝃ' => 'K',
  'ꝃ' => 'k',
  'Ꝅ' => 'K',
  'ꝅ' => 'k',
  'Ꝇ' => 'L',
  'ꝇ' => 'l',
  'Ꝉ' => 'L',
  'ꝉ' => 'l',
  'Ꝋ' => 'O',
  'ꝋ' => 'o',
  'Ꝍ' => 'O',
  'ꝍ' => 'o',
  'Ꝏ' => 'OO',
  'ꝏ' => 'oo',
  'Ꝑ' => 'P',
  'ꝑ' => 'p',
  'Ꝓ' => 'P',
  'ꝓ' => 'p',
  'Ꝕ' => 'P',
  'ꝕ' => 'p',
  'Ꝗ' => 'Q',
  'ꝗ' => 'q',
  'Ꝙ' => 'Q',
  'ꝙ' => 'q',
  'Ꝟ' => 'V',
  'ꝟ' => 'v',
  'Ꝡ' => 'VY',
  'ꝡ' => 'vy',
  'Ꝥ' => 'TH',
  'ꝥ' => 'th',
  'Ꝧ' => 'TH',
  'ꝧ' => 'th',
  'ꝱ' => 'd',
  'ꝲ' => 'l',
  'ꝳ' => 'm',
  'ꝴ' => 'n',
  'ꝵ' => 'r',
  'ꝶ' => 'R',
  'ꝷ' => 't',
  'Ꝺ' => 'D',
  'ꝺ' => 'd',
  'Ꝼ' => 'F',
  'ꝼ' => 'f',
  'Ꞇ' => 'T',
  'ꞇ' => 't',
  'Ꞑ' => 'N',
  'ꞑ' => 'n',
  'Ꞓ' => 'C',
  'ꞓ' => 'c',
  'Ꞡ' => 'G',
  'ꞡ' => 'g',
  'Ꞣ' => 'K',
  'ꞣ' => 'k',
  'Ꞥ' => 'N',
  'ꞥ' => 'n',
  'Ꞧ' => 'R',
  'ꞧ' => 'r',
  'Ꞩ' => 'S',
  'ꞩ' => 's',
  'Ɦ' => 'H',
  '©' => '(C)',
  '®' => '(R)',
  '₠' => 'CE',
  '₢' => 'Cr',
  '₣' => 'Fr.',
  '₤' => 'L.',
  '₧' => 'Pts',
  '₺' => 'TL',
  '₹' => 'Rs',
  '℗' => '(P)',
  '℘' => 'P',
  '℞' => 'Rx',
  '〇' => '0',
  ' ' => ' ',
  ' ' => ' ',
  ' ' => ' ',
  ' ' => ' ',
  ' ' => ' ',
  ' ' => ' ',
  ' ' => ' ',
  ' ' => ' ',
  ' ' => ' ',
  ' ' => ' ',
  ' ' => ' ',
  'ʹ' => '\'',
  'ʺ' => '"',
  'ʻ' => '\'',
  'ʼ' => '\'',
  'ʽ' => '\'',
  'ˈ' => '\'',
  'ˋ' => '`',
  '‘' => '\'',
  '’' => '\'',
  '‚' => ',',
  '‛' => '\'',
  '“' => '"',
  '”' => '"',
  '„' => ',,',
  '‟' => '"',
  '′' => '\'',
  '〝' => '"',
  '〞' => '"',
  '«' => '<<',
  '»' => '>>',
  '‹' => '<',
  '›' => '>',
  '­' => '-',
  '‐' => '-',
  '‑' => '-',
  '‒' => '-',
  '–' => '-',
  '—' => '-',
  '―' => '-',
  '︱' => '-',
  '︲' => '-',
  '˂' => '<',
  '˃' => '>',
  '˄' => '^',
  'ˆ' => '^',
  'ː' => ':',
  '˜' => '~',
  '‖' => '||',
  '⁄' => '/',
  '⁅' => '[',
  '⁆' => ']',
  '⁎' => '*',
  '、' => ',',
  '。' => '.',
  '〈' => '<',
  '〉' => '>',
  '《' => '<<',
  '》' => '>>',
  '〔' => '[',
  '〕' => ']',
  '〘' => '[',
  '〙' => ']',
  '〚' => '[',
  '〛' => ']',
  '︐' => ',',
  '︑' => ',',
  '︒' => '.',
  '︓' => ':',
  '︔' => ';',
  '︕' => '!',
  '︖' => '?',
  '︙' => '...',
  '︰' => '..',
  '︵' => '(',
  '︶' => ')',
  '︷' => '{',
  '︸' => '}',
  '︹' => '[',
  '︺' => ']',
  '︽' => '<<',
  '︾' => '>>',
  '︿' => '<',
  '﹀' => '>',
  '﹇' => '[',
  '﹈' => ']',
  '×' => '*',
  '÷' => '/',
  '˖' => '+',
  '˗' => '-',
  '−' => '-',
  '∕' => '/',
  '∖' => '\\',
  '∣' => '|',
  '∥' => '||',
  '≪' => '<<',
  '≫' => '>>',
  '⦅' => '((',
  '⦆' => '))',
);
PKϤ$Z0pIq��/polyfill-iconv/Resources/charset/from.cp500.phpnu�[���<?php

static $data = array (
  '' => '',
  '' => '',
  '' => '',
  '' => '',
  '' => 'œ',
  '' => '	',
  '' => '†',
  '' => '',
  '' => '—',
  '	' => '',
  '
' => 'Ž',
  '' => '',
  '' => '',
  '
' => '
',
  '' => '',
  '' => '',
  '' => '',
  '' => '',
  '' => '',
  '' => '',
  '' => '',
  '' => '…',
  '' => '',
  '' => '‡',
  '' => '',
  '' => '',
  '' => '’',
  '' => '',
  '' => '',
  '' => '',
  '' => '',
  '' => '',
  ' ' => '€',
  '!' => '',
  '"' => '‚',
  '#' => 'ƒ',
  '$' => '„',
  '%' => '
',
  '&' => '',
  '\'' => '',
  '(' => 'ˆ',
  ')' => '‰',
  '*' => 'Š',
  '+' => '‹',
  ',' => 'Œ',
  '-' => '',
  '.' => '',
  '/' => '',
  0 => '',
  1 => '‘',
  2 => '',
  3 => '“',
  4 => '”',
  5 => '•',
  6 => '–',
  7 => '',
  8 => '˜',
  9 => '™',
  ':' => 'š',
  ';' => '›',
  '<' => '',
  '=' => '',
  '>' => 'ž',
  '?' => '',
  '@' => ' ',
  'A' => ' ',
  'B' => 'â',
  'C' => 'ä',
  'D' => 'à',
  'E' => 'á',
  'F' => 'ã',
  'G' => 'å',
  'H' => 'ç',
  'I' => 'ñ',
  'J' => '[',
  'K' => '.',
  'L' => '<',
  'M' => '(',
  'N' => '+',
  'O' => '!',
  'P' => '&',
  'Q' => 'é',
  'R' => 'ê',
  'S' => 'ë',
  'T' => 'è',
  'U' => 'í',
  'V' => 'î',
  'W' => 'ï',
  'X' => 'ì',
  'Y' => 'ß',
  'Z' => ']',
  '[' => '$',
  '\\' => '*',
  ']' => ')',
  '^' => ';',
  '_' => '^',
  '`' => '-',
  'a' => '/',
  'b' => 'Â',
  'c' => 'Ä',
  'd' => 'À',
  'e' => 'Á',
  'f' => 'Ã',
  'g' => 'Å',
  'h' => 'Ç',
  'i' => 'Ñ',
  'j' => '¦',
  'k' => ',',
  'l' => '%',
  'm' => '_',
  'n' => '>',
  'o' => '?',
  'p' => 'ø',
  'q' => 'É',
  'r' => 'Ê',
  's' => 'Ë',
  't' => 'È',
  'u' => 'Í',
  'v' => 'Î',
  'w' => 'Ï',
  'x' => 'Ì',
  'y' => '`',
  'z' => ':',
  '{' => '#',
  '|' => '@',
  '}' => '\'',
  '~' => '=',
  '' => '"',
  '�' => 'Ø',
  '�' => 'a',
  '�' => 'b',
  '�' => 'c',
  '�' => 'd',
  '�' => 'e',
  '�' => 'f',
  '�' => 'g',
  '�' => 'h',
  '�' => 'i',
  '�' => '«',
  '�' => '»',
  '�' => 'ð',
  '�' => 'ý',
  '�' => 'þ',
  '�' => '±',
  '�' => '°',
  '�' => 'j',
  '�' => 'k',
  '�' => 'l',
  '�' => 'm',
  '�' => 'n',
  '�' => 'o',
  '�' => 'p',
  '�' => 'q',
  '�' => 'r',
  '�' => 'ª',
  '�' => 'º',
  '�' => 'æ',
  '�' => '¸',
  '�' => 'Æ',
  '�' => '¤',
  '�' => 'µ',
  '�' => '~',
  '�' => 's',
  '�' => 't',
  '�' => 'u',
  '�' => 'v',
  '�' => 'w',
  '�' => 'x',
  '�' => 'y',
  '�' => 'z',
  '�' => '¡',
  '�' => '¿',
  '�' => 'Ð',
  '�' => 'Ý',
  '�' => 'Þ',
  '�' => '®',
  '�' => '¢',
  '�' => '£',
  '�' => '¥',
  '�' => '·',
  '�' => '©',
  '�' => '§',
  '�' => '¶',
  '�' => '¼',
  '�' => '½',
  '�' => '¾',
  '�' => '¬',
  '�' => '|',
  '�' => '¯',
  '�' => '¨',
  '�' => '´',
  '�' => '×',
  '�' => '{',
  '�' => 'A',
  '�' => 'B',
  '�' => 'C',
  '�' => 'D',
  '�' => 'E',
  '�' => 'F',
  '�' => 'G',
  '�' => 'H',
  '�' => 'I',
  '�' => '­',
  '�' => 'ô',
  '�' => 'ö',
  '�' => 'ò',
  '�' => 'ó',
  '�' => 'õ',
  '�' => '}',
  '�' => 'J',
  '�' => 'K',
  '�' => 'L',
  '�' => 'M',
  '�' => 'N',
  '�' => 'O',
  '�' => 'P',
  '�' => 'Q',
  '�' => 'R',
  '�' => '¹',
  '�' => 'û',
  '�' => 'ü',
  '�' => 'ù',
  '�' => 'ú',
  '�' => 'ÿ',
  '�' => '\\',
  '�' => '÷',
  '�' => 'S',
  '�' => 'T',
  '�' => 'U',
  '�' => 'V',
  '�' => 'W',
  '�' => 'X',
  '�' => 'Y',
  '�' => 'Z',
  '�' => '²',
  '�' => 'Ô',
  '�' => 'Ö',
  '�' => 'Ò',
  '�' => 'Ó',
  '�' => 'Õ',
  '�' => '0',
  '�' => '1',
  '�' => '2',
  '�' => '3',
  '�' => '4',
  '�' => '5',
  '�' => '6',
  '�' => '7',
  '�' => '8',
  '�' => '9',
  '�' => '³',
  '�' => 'Û',
  '�' => 'Ü',
  '�' => 'Ù',
  '�' => 'Ú',
  '�' => 'Ÿ',
);

$result =& $data;
unset($data);

return $result;
PKϤ$Z�D�H;�;�/polyfill-iconv/Resources/charset/from.cp936.phpnu�[���<?php

static $data = array (
  '' => '',
  '' => '',
  '' => '',
  '' => '',
  '' => '',
  '' => '',
  '' => '',
  '' => '',
  '' => '',
  '	' => '	',
  '
' => '
',
  '' => '',
  '' => '',
  '
' => '
',
  '' => '',
  '' => '',
  '' => '',
  '' => '',
  '' => '',
  '' => '',
  '' => '',
  '' => '',
  '' => '',
  '' => '',
  '' => '',
  '' => '',
  '' => '',
  '' => '',
  '' => '',
  '' => '',
  '' => '',
  '' => '',
  ' ' => ' ',
  '!' => '!',
  '"' => '"',
  '#' => '#',
  '$' => '$',
  '%' => '%',
  '&' => '&',
  '\'' => '\'',
  '(' => '(',
  ')' => ')',
  '*' => '*',
  '+' => '+',
  ',' => ',',
  '-' => '-',
  '.' => '.',
  '/' => '/',
  0 => '0',
  1 => '1',
  2 => '2',
  3 => '3',
  4 => '4',
  5 => '5',
  6 => '6',
  7 => '7',
  8 => '8',
  9 => '9',
  ':' => ':',
  ';' => ';',
  '<' => '<',
  '=' => '=',
  '>' => '>',
  '?' => '?',
  '@' => '@',
  'A' => 'A',
  'B' => 'B',
  'C' => 'C',
  'D' => 'D',
  'E' => 'E',
  'F' => 'F',
  'G' => 'G',
  'H' => 'H',
  'I' => 'I',
  'J' => 'J',
  'K' => 'K',
  'L' => 'L',
  'M' => 'M',
  'N' => 'N',
  'O' => 'O',
  'P' => 'P',
  'Q' => 'Q',
  'R' => 'R',
  'S' => 'S',
  'T' => 'T',
  'U' => 'U',
  'V' => 'V',
  'W' => 'W',
  'X' => 'X',
  'Y' => 'Y',
  'Z' => 'Z',
  '[' => '[',
  '\\' => '\\',
  ']' => ']',
  '^' => '^',
  '_' => '_',
  '`' => '`',
  'a' => 'a',
  'b' => 'b',
  'c' => 'c',
  'd' => 'd',
  'e' => 'e',
  'f' => 'f',
  'g' => 'g',
  'h' => 'h',
  'i' => 'i',
  'j' => 'j',
  'k' => 'k',
  'l' => 'l',
  'm' => 'm',
  'n' => 'n',
  'o' => 'o',
  'p' => 'p',
  'q' => 'q',
  'r' => 'r',
  's' => 's',
  't' => 't',
  'u' => 'u',
  'v' => 'v',
  'w' => 'w',
  'x' => 'x',
  'y' => 'y',
  'z' => 'z',
  '{' => '{',
  '|' => '|',
  '}' => '}',
  '~' => '~',
  '' => '',
  '�' => '€',
  '�@' => '丂',
  '�A' => '丄',
  '�B' => '丅',
  '�C' => '丆',
  '�D' => '丏',
  '�E' => '丒',
  '�F' => '丗',
  '�G' => '丟',
  '�H' => '丠',
  '�I' => '両',
  '�J' => '丣',
  '�K' => '並',
  '�L' => '丩',
  '�M' => '丮',
  '�N' => '丯',
  '�O' => '丱',
  '�P' => '丳',
  '�Q' => '丵',
  '�R' => '丷',
  '�S' => '丼',
  '�T' => '乀',
  '�U' => '乁',
  '�V' => '乂',
  '�W' => '乄',
  '�X' => '乆',
  '�Y' => '乊',
  '�Z' => '乑',
  '�[' => '乕',
  '�\\' => '乗',
  '�]' => '乚',
  '�^' => '乛',
  '�_' => '乢',
  '�`' => '乣',
  '�a' => '乤',
  '�b' => '乥',
  '�c' => '乧',
  '�d' => '乨',
  '�e' => '乪',
  '�f' => '乫',
  '�g' => '乬',
  '�h' => '乭',
  '�i' => '乮',
  '�j' => '乯',
  '�k' => '乲',
  '�l' => '乴',
  '�m' => '乵',
  '�n' => '乶',
  '�o' => '乷',
  '�p' => '乸',
  '�q' => '乹',
  '�r' => '乺',
  '�s' => '乻',
  '�t' => '乼',
  '�u' => '乽',
  '�v' => '乿',
  '�w' => '亀',
  '�x' => '亁',
  '�y' => '亂',
  '�z' => '亃',
  '�{' => '亄',
  '�|' => '亅',
  '�}' => '亇',
  '�~' => '亊',
  '��' => '亐',
  '��' => '亖',
  '��' => '亗',
  '��' => '亙',
  '��' => '亜',
  '��' => '亝',
  '��' => '亞',
  '��' => '亣',
  '��' => '亪',
  '��' => '亯',
  '��' => '亰',
  '��' => '亱',
  '��' => '亴',
  '��' => '亶',
  '��' => '亷',
  '��' => '亸',
  '��' => '亹',
  '��' => '亼',
  '��' => '亽',
  '��' => '亾',
  '��' => '仈',
  '��' => '仌',
  '��' => '仏',
  '��' => '仐',
  '��' => '仒',
  '��' => '仚',
  '��' => '仛',
  '��' => '仜',
  '��' => '仠',
  '��' => '仢',
  '��' => '仦',
  '��' => '仧',
  '��' => '仩',
  '��' => '仭',
  '��' => '仮',
  '��' => '仯',
  '��' => '仱',
  '��' => '仴',
  '��' => '仸',
  '��' => '仹',
  '��' => '仺',
  '��' => '仼',
  '��' => '仾',
  '��' => '伀',
  '��' => '伂',
  '��' => '伃',
  '��' => '伄',
  '��' => '伅',
  '��' => '伆',
  '��' => '伇',
  '��' => '伈',
  '��' => '伋',
  '��' => '伌',
  '��' => '伒',
  '��' => '伓',
  '��' => '伔',
  '��' => '伕',
  '��' => '伖',
  '��' => '伜',
  '��' => '伝',
  '��' => '伡',
  '��' => '伣',
  '��' => '伨',
  '��' => '伩',
  '��' => '伬',
  '��' => '伭',
  '��' => '伮',
  '��' => '伱',
  '��' => '伳',
  '��' => '伵',
  '��' => '伷',
  '��' => '伹',
  '��' => '伻',
  '��' => '伾',
  '��' => '伿',
  '��' => '佀',
  '��' => '佁',
  '��' => '佂',
  '��' => '佄',
  '��' => '佅',
  '��' => '佇',
  '��' => '佈',
  '��' => '佉',
  '��' => '佊',
  '��' => '佋',
  '��' => '佌',
  '��' => '佒',
  '��' => '佔',
  '��' => '佖',
  '��' => '佡',
  '��' => '佢',
  '��' => '佦',
  '��' => '佨',
  '��' => '佪',
  '��' => '佫',
  '��' => '佭',
  '��' => '佮',
  '��' => '佱',
  '��' => '佲',
  '��' => '併',
  '��' => '佷',
  '��' => '佸',
  '��' => '佹',
  '��' => '佺',
  '��' => '佽',
  '��' => '侀',
  '��' => '侁',
  '��' => '侂',
  '��' => '侅',
  '��' => '來',
  '��' => '侇',
  '��' => '侊',
  '��' => '侌',
  '��' => '侎',
  '��' => '侐',
  '��' => '侒',
  '��' => '侓',
  '��' => '侕',
  '��' => '侖',
  '��' => '侘',
  '��' => '侙',
  '��' => '侚',
  '��' => '侜',
  '��' => '侞',
  '��' => '侟',
  '��' => '価',
  '��' => '侢',
  '�@' => '侤',
  '�A' => '侫',
  '�B' => '侭',
  '�C' => '侰',
  '�D' => '侱',
  '�E' => '侲',
  '�F' => '侳',
  '�G' => '侴',
  '�H' => '侶',
  '�I' => '侷',
  '�J' => '侸',
  '�K' => '侹',
  '�L' => '侺',
  '�M' => '侻',
  '�N' => '侼',
  '�O' => '侽',
  '�P' => '侾',
  '�Q' => '俀',
  '�R' => '俁',
  '�S' => '係',
  '�T' => '俆',
  '�U' => '俇',
  '�V' => '俈',
  '�W' => '俉',
  '�X' => '俋',
  '�Y' => '俌',
  '�Z' => '俍',
  '�[' => '俒',
  '�\\' => '俓',
  '�]' => '俔',
  '�^' => '俕',
  '�_' => '俖',
  '�`' => '俙',
  '�a' => '俛',
  '�b' => '俠',
  '�c' => '俢',
  '�d' => '俤',
  '�e' => '俥',
  '�f' => '俧',
  '�g' => '俫',
  '�h' => '俬',
  '�i' => '俰',
  '�j' => '俲',
  '�k' => '俴',
  '�l' => '俵',
  '�m' => '俶',
  '�n' => '俷',
  '�o' => '俹',
  '�p' => '俻',
  '�q' => '俼',
  '�r' => '俽',
  '�s' => '俿',
  '�t' => '倀',
  '�u' => '倁',
  '�v' => '倂',
  '�w' => '倃',
  '�x' => '倄',
  '�y' => '倅',
  '�z' => '倆',
  '�{' => '倇',
  '�|' => '倈',
  '�}' => '倉',
  '�~' => '倊',
  '��' => '個',
  '��' => '倎',
  '��' => '倐',
  '��' => '們',
  '��' => '倓',
  '��' => '倕',
  '��' => '倖',
  '��' => '倗',
  '��' => '倛',
  '��' => '倝',
  '��' => '倞',
  '��' => '倠',
  '��' => '倢',
  '��' => '倣',
  '��' => '値',
  '��' => '倧',
  '��' => '倫',
  '��' => '倯',
  '��' => '倰',
  '��' => '倱',
  '��' => '倲',
  '��' => '倳',
  '��' => '倴',
  '��' => '倵',
  '��' => '倶',
  '��' => '倷',
  '��' => '倸',
  '��' => '倹',
  '��' => '倻',
  '��' => '倽',
  '��' => '倿',
  '��' => '偀',
  '��' => '偁',
  '��' => '偂',
  '��' => '偄',
  '��' => '偅',
  '��' => '偆',
  '��' => '偉',
  '��' => '偊',
  '��' => '偋',
  '��' => '偍',
  '��' => '偐',
  '��' => '偑',
  '��' => '偒',
  '��' => '偓',
  '��' => '偔',
  '��' => '偖',
  '��' => '偗',
  '��' => '偘',
  '��' => '偙',
  '��' => '偛',
  '��' => '偝',
  '��' => '偞',
  '��' => '偟',
  '��' => '偠',
  '��' => '偡',
  '��' => '偢',
  '��' => '偣',
  '��' => '偤',
  '��' => '偦',
  '��' => '偧',
  '��' => '偨',
  '��' => '偩',
  '��' => '偪',
  '��' => '偫',
  '��' => '偭',
  '��' => '偮',
  '��' => '偯',
  '��' => '偰',
  '��' => '偱',
  '��' => '偲',
  '��' => '偳',
  '��' => '側',
  '��' => '偵',
  '��' => '偸',
  '��' => '偹',
  '��' => '偺',
  '��' => '偼',
  '��' => '偽',
  '��' => '傁',
  '��' => '傂',
  '��' => '傃',
  '��' => '傄',
  '��' => '傆',
  '��' => '傇',
  '��' => '傉',
  '��' => '傊',
  '��' => '傋',
  '��' => '傌',
  '��' => '傎',
  '��' => '傏',
  '��' => '傐',
  '��' => '傑',
  '��' => '傒',
  '��' => '傓',
  '��' => '傔',
  '��' => '傕',
  '��' => '傖',
  '��' => '傗',
  '��' => '傘',
  '��' => '備',
  '��' => '傚',
  '��' => '傛',
  '��' => '傜',
  '��' => '傝',
  '��' => '傞',
  '��' => '傟',
  '��' => '傠',
  '��' => '傡',
  '��' => '傢',
  '��' => '傤',
  '��' => '傦',
  '��' => '傪',
  '��' => '傫',
  '��' => '傭',
  '��' => '傮',
  '��' => '傯',
  '��' => '傰',
  '��' => '傱',
  '��' => '傳',
  '��' => '傴',
  '��' => '債',
  '��' => '傶',
  '��' => '傷',
  '��' => '傸',
  '��' => '傹',
  '��' => '傼',
  '�@' => '傽',
  '�A' => '傾',
  '�B' => '傿',
  '�C' => '僀',
  '�D' => '僁',
  '�E' => '僂',
  '�F' => '僃',
  '�G' => '僄',
  '�H' => '僅',
  '�I' => '僆',
  '�J' => '僇',
  '�K' => '僈',
  '�L' => '僉',
  '�M' => '僊',
  '�N' => '僋',
  '�O' => '僌',
  '�P' => '働',
  '�Q' => '僎',
  '�R' => '僐',
  '�S' => '僑',
  '�T' => '僒',
  '�U' => '僓',
  '�V' => '僔',
  '�W' => '僕',
  '�X' => '僗',
  '�Y' => '僘',
  '�Z' => '僙',
  '�[' => '僛',
  '�\\' => '僜',
  '�]' => '僝',
  '�^' => '僞',
  '�_' => '僟',
  '�`' => '僠',
  '�a' => '僡',
  '�b' => '僢',
  '�c' => '僣',
  '�d' => '僤',
  '�e' => '僥',
  '�f' => '僨',
  '�g' => '僩',
  '�h' => '僪',
  '�i' => '僫',
  '�j' => '僯',
  '�k' => '僰',
  '�l' => '僱',
  '�m' => '僲',
  '�n' => '僴',
  '�o' => '僶',
  '�p' => '僷',
  '�q' => '僸',
  '�r' => '價',
  '�s' => '僺',
  '�t' => '僼',
  '�u' => '僽',
  '�v' => '僾',
  '�w' => '僿',
  '�x' => '儀',
  '�y' => '儁',
  '�z' => '儂',
  '�{' => '儃',
  '�|' => '億',
  '�}' => '儅',
  '�~' => '儈',
  '��' => '儉',
  '��' => '儊',
  '��' => '儌',
  '��' => '儍',
  '��' => '儎',
  '��' => '儏',
  '��' => '儐',
  '��' => '儑',
  '��' => '儓',
  '��' => '儔',
  '��' => '儕',
  '��' => '儖',
  '��' => '儗',
  '��' => '儘',
  '��' => '儙',
  '��' => '儚',
  '��' => '儛',
  '��' => '儜',
  '��' => '儝',
  '��' => '儞',
  '��' => '償',
  '��' => '儠',
  '��' => '儢',
  '��' => '儣',
  '��' => '儤',
  '��' => '儥',
  '��' => '儦',
  '��' => '儧',
  '��' => '儨',
  '��' => '儩',
  '��' => '優',
  '��' => '儫',
  '��' => '儬',
  '��' => '儭',
  '��' => '儮',
  '��' => '儯',
  '��' => '儰',
  '��' => '儱',
  '��' => '儲',
  '��' => '儳',
  '��' => '儴',
  '��' => '儵',
  '��' => '儶',
  '��' => '儷',
  '��' => '儸',
  '��' => '儹',
  '��' => '儺',
  '��' => '儻',
  '��' => '儼',
  '��' => '儽',
  '��' => '儾',
  '��' => '兂',
  '��' => '兇',
  '��' => '兊',
  '��' => '兌',
  '��' => '兎',
  '��' => '兏',
  '��' => '児',
  '��' => '兒',
  '��' => '兓',
  '��' => '兗',
  '��' => '兘',
  '��' => '兙',
  '��' => '兛',
  '��' => '兝',
  '��' => '兞',
  '��' => '兟',
  '��' => '兠',
  '��' => '兡',
  '��' => '兣',
  '��' => '兤',
  '��' => '兦',
  '��' => '內',
  '��' => '兩',
  '��' => '兪',
  '��' => '兯',
  '��' => '兲',
  '��' => '兺',
  '��' => '兾',
  '��' => '兿',
  '��' => '冃',
  '��' => '冄',
  '��' => '円',
  '��' => '冇',
  '��' => '冊',
  '��' => '冋',
  '��' => '冎',
  '��' => '冏',
  '��' => '冐',
  '��' => '冑',
  '��' => '冓',
  '��' => '冔',
  '��' => '冘',
  '��' => '冚',
  '��' => '冝',
  '��' => '冞',
  '��' => '冟',
  '��' => '冡',
  '��' => '冣',
  '��' => '冦',
  '��' => '冧',
  '��' => '冨',
  '��' => '冩',
  '��' => '冪',
  '��' => '冭',
  '��' => '冮',
  '��' => '冴',
  '��' => '冸',
  '��' => '冹',
  '��' => '冺',
  '��' => '冾',
  '��' => '冿',
  '��' => '凁',
  '��' => '凂',
  '��' => '凃',
  '��' => '凅',
  '��' => '凈',
  '��' => '凊',
  '��' => '凍',
  '��' => '凎',
  '��' => '凐',
  '��' => '凒',
  '��' => '凓',
  '��' => '凔',
  '��' => '凕',
  '��' => '凖',
  '��' => '凗',
  '�@' => '凘',
  '�A' => '凙',
  '�B' => '凚',
  '�C' => '凜',
  '�D' => '凞',
  '�E' => '凟',
  '�F' => '凢',
  '�G' => '凣',
  '�H' => '凥',
  '�I' => '処',
  '�J' => '凧',
  '�K' => '凨',
  '�L' => '凩',
  '�M' => '凪',
  '�N' => '凬',
  '�O' => '凮',
  '�P' => '凱',
  '�Q' => '凲',
  '�R' => '凴',
  '�S' => '凷',
  '�T' => '凾',
  '�U' => '刄',
  '�V' => '刅',
  '�W' => '刉',
  '�X' => '刋',
  '�Y' => '刌',
  '�Z' => '刏',
  '�[' => '刐',
  '�\\' => '刓',
  '�]' => '刔',
  '�^' => '刕',
  '�_' => '刜',
  '�`' => '刞',
  '�a' => '刟',
  '�b' => '刡',
  '�c' => '刢',
  '�d' => '刣',
  '�e' => '別',
  '�f' => '刦',
  '�g' => '刧',
  '�h' => '刪',
  '�i' => '刬',
  '�j' => '刯',
  '�k' => '刱',
  '�l' => '刲',
  '�m' => '刴',
  '�n' => '刵',
  '�o' => '刼',
  '�p' => '刾',
  '�q' => '剄',
  '�r' => '剅',
  '�s' => '剆',
  '�t' => '則',
  '�u' => '剈',
  '�v' => '剉',
  '�w' => '剋',
  '�x' => '剎',
  '�y' => '剏',
  '�z' => '剒',
  '�{' => '剓',
  '�|' => '剕',
  '�}' => '剗',
  '�~' => '剘',
  '��' => '剙',
  '��' => '剚',
  '��' => '剛',
  '��' => '剝',
  '��' => '剟',
  '��' => '剠',
  '��' => '剢',
  '��' => '剣',
  '��' => '剤',
  '��' => '剦',
  '��' => '剨',
  '��' => '剫',
  '��' => '剬',
  '��' => '剭',
  '��' => '剮',
  '��' => '剰',
  '��' => '剱',
  '��' => '剳',
  '��' => '剴',
  '��' => '創',
  '��' => '剶',
  '��' => '剷',
  '��' => '剸',
  '��' => '剹',
  '��' => '剺',
  '��' => '剻',
  '��' => '剼',
  '��' => '剾',
  '��' => '劀',
  '��' => '劃',
  '��' => '劄',
  '��' => '劅',
  '��' => '劆',
  '��' => '劇',
  '��' => '劉',
  '��' => '劊',
  '��' => '劋',
  '��' => '劌',
  '��' => '劍',
  '��' => '劎',
  '��' => '劏',
  '��' => '劑',
  '��' => '劒',
  '��' => '劔',
  '��' => '劕',
  '��' => '劖',
  '��' => '劗',
  '��' => '劘',
  '��' => '劙',
  '��' => '劚',
  '��' => '劜',
  '��' => '劤',
  '��' => '劥',
  '��' => '劦',
  '��' => '劧',
  '��' => '劮',
  '��' => '劯',
  '��' => '劰',
  '��' => '労',
  '��' => '劵',
  '��' => '劶',
  '��' => '劷',
  '��' => '劸',
  '��' => '効',
  '��' => '劺',
  '��' => '劻',
  '��' => '劼',
  '��' => '劽',
  '��' => '勀',
  '��' => '勁',
  '��' => '勂',
  '��' => '勄',
  '��' => '勅',
  '��' => '勆',
  '��' => '勈',
  '��' => '勊',
  '��' => '勌',
  '��' => '勍',
  '��' => '勎',
  '��' => '勏',
  '��' => '勑',
  '��' => '勓',
  '��' => '勔',
  '��' => '動',
  '��' => '勗',
  '��' => '務',
  '��' => '勚',
  '��' => '勛',
  '��' => '勜',
  '��' => '勝',
  '��' => '勞',
  '��' => '勠',
  '��' => '勡',
  '��' => '勢',
  '��' => '勣',
  '��' => '勥',
  '��' => '勦',
  '��' => '勧',
  '��' => '勨',
  '��' => '勩',
  '��' => '勪',
  '��' => '勫',
  '��' => '勬',
  '��' => '勭',
  '��' => '勮',
  '��' => '勯',
  '��' => '勱',
  '��' => '勲',
  '��' => '勳',
  '��' => '勴',
  '��' => '勵',
  '��' => '勶',
  '��' => '勷',
  '��' => '勸',
  '��' => '勻',
  '��' => '勼',
  '��' => '勽',
  '��' => '匁',
  '��' => '匂',
  '��' => '匃',
  '��' => '匄',
  '��' => '匇',
  '��' => '匉',
  '��' => '匊',
  '��' => '匋',
  '��' => '匌',
  '��' => '匎',
  '�@' => '匑',
  '�A' => '匒',
  '�B' => '匓',
  '�C' => '匔',
  '�D' => '匘',
  '�E' => '匛',
  '�F' => '匜',
  '�G' => '匞',
  '�H' => '匟',
  '�I' => '匢',
  '�J' => '匤',
  '�K' => '匥',
  '�L' => '匧',
  '�M' => '匨',
  '�N' => '匩',
  '�O' => '匫',
  '�P' => '匬',
  '�Q' => '匭',
  '�R' => '匯',
  '�S' => '匰',
  '�T' => '匱',
  '�U' => '匲',
  '�V' => '匳',
  '�W' => '匴',
  '�X' => '匵',
  '�Y' => '匶',
  '�Z' => '匷',
  '�[' => '匸',
  '�\\' => '匼',
  '�]' => '匽',
  '�^' => '區',
  '�_' => '卂',
  '�`' => '卄',
  '�a' => '卆',
  '�b' => '卋',
  '�c' => '卌',
  '�d' => '卍',
  '�e' => '卐',
  '�f' => '協',
  '�g' => '単',
  '�h' => '卙',
  '�i' => '卛',
  '�j' => '卝',
  '�k' => '卥',
  '�l' => '卨',
  '�m' => '卪',
  '�n' => '卬',
  '�o' => '卭',
  '�p' => '卲',
  '�q' => '卶',
  '�r' => '卹',
  '�s' => '卻',
  '�t' => '卼',
  '�u' => '卽',
  '�v' => '卾',
  '�w' => '厀',
  '�x' => '厁',
  '�y' => '厃',
  '�z' => '厇',
  '�{' => '厈',
  '�|' => '厊',
  '�}' => '厎',
  '�~' => '厏',
  '��' => '厐',
  '��' => '厑',
  '��' => '厒',
  '��' => '厓',
  '��' => '厔',
  '��' => '厖',
  '��' => '厗',
  '��' => '厙',
  '��' => '厛',
  '��' => '厜',
  '��' => '厞',
  '��' => '厠',
  '��' => '厡',
  '��' => '厤',
  '��' => '厧',
  '��' => '厪',
  '��' => '厫',
  '��' => '厬',
  '��' => '厭',
  '��' => '厯',
  '��' => '厰',
  '��' => '厱',
  '��' => '厲',
  '��' => '厳',
  '��' => '厴',
  '��' => '厵',
  '��' => '厷',
  '��' => '厸',
  '��' => '厹',
  '��' => '厺',
  '��' => '厼',
  '��' => '厽',
  '��' => '厾',
  '��' => '叀',
  '��' => '參',
  '��' => '叄',
  '��' => '叅',
  '��' => '叆',
  '��' => '叇',
  '��' => '収',
  '��' => '叏',
  '��' => '叐',
  '��' => '叒',
  '��' => '叓',
  '��' => '叕',
  '��' => '叚',
  '��' => '叜',
  '��' => '叝',
  '��' => '叞',
  '��' => '叡',
  '��' => '叢',
  '��' => '叧',
  '��' => '叴',
  '��' => '叺',
  '��' => '叾',
  '��' => '叿',
  '��' => '吀',
  '��' => '吂',
  '��' => '吅',
  '��' => '吇',
  '��' => '吋',
  '��' => '吔',
  '��' => '吘',
  '��' => '吙',
  '��' => '吚',
  '��' => '吜',
  '��' => '吢',
  '��' => '吤',
  '��' => '吥',
  '��' => '吪',
  '��' => '吰',
  '��' => '吳',
  '��' => '吶',
  '��' => '吷',
  '��' => '吺',
  '��' => '吽',
  '��' => '吿',
  '��' => '呁',
  '��' => '呂',
  '��' => '呄',
  '��' => '呅',
  '��' => '呇',
  '��' => '呉',
  '��' => '呌',
  '��' => '呍',
  '��' => '呎',
  '��' => '呏',
  '��' => '呑',
  '��' => '呚',
  '��' => '呝',
  '��' => '呞',
  '��' => '呟',
  '��' => '呠',
  '��' => '呡',
  '��' => '呣',
  '��' => '呥',
  '��' => '呧',
  '��' => '呩',
  '��' => '呪',
  '��' => '呫',
  '��' => '呬',
  '��' => '呭',
  '��' => '呮',
  '��' => '呯',
  '��' => '呰',
  '��' => '呴',
  '��' => '呹',
  '��' => '呺',
  '��' => '呾',
  '��' => '呿',
  '��' => '咁',
  '��' => '咃',
  '��' => '咅',
  '��' => '咇',
  '��' => '咈',
  '��' => '咉',
  '��' => '咊',
  '��' => '咍',
  '��' => '咑',
  '��' => '咓',
  '��' => '咗',
  '��' => '咘',
  '��' => '咜',
  '��' => '咞',
  '��' => '咟',
  '��' => '咠',
  '��' => '咡',
  '�@' => '咢',
  '�A' => '咥',
  '�B' => '咮',
  '�C' => '咰',
  '�D' => '咲',
  '�E' => '咵',
  '�F' => '咶',
  '�G' => '咷',
  '�H' => '咹',
  '�I' => '咺',
  '�J' => '咼',
  '�K' => '咾',
  '�L' => '哃',
  '�M' => '哅',
  '�N' => '哊',
  '�O' => '哋',
  '�P' => '哖',
  '�Q' => '哘',
  '�R' => '哛',
  '�S' => '哠',
  '�T' => '員',
  '�U' => '哢',
  '�V' => '哣',
  '�W' => '哤',
  '�X' => '哫',
  '�Y' => '哬',
  '�Z' => '哯',
  '�[' => '哰',
  '�\\' => '哱',
  '�]' => '哴',
  '�^' => '哵',
  '�_' => '哶',
  '�`' => '哷',
  '�a' => '哸',
  '�b' => '哹',
  '�c' => '哻',
  '�d' => '哾',
  '�e' => '唀',
  '�f' => '唂',
  '�g' => '唃',
  '�h' => '唄',
  '�i' => '唅',
  '�j' => '唈',
  '�k' => '唊',
  '�l' => '唋',
  '�m' => '唌',
  '�n' => '唍',
  '�o' => '唎',
  '�p' => '唒',
  '�q' => '唓',
  '�r' => '唕',
  '�s' => '唖',
  '�t' => '唗',
  '�u' => '唘',
  '�v' => '唙',
  '�w' => '唚',
  '�x' => '唜',
  '�y' => '唝',
  '�z' => '唞',
  '�{' => '唟',
  '�|' => '唡',
  '�}' => '唥',
  '�~' => '唦',
  '��' => '唨',
  '��' => '唩',
  '��' => '唫',
  '��' => '唭',
  '��' => '唲',
  '��' => '唴',
  '��' => '唵',
  '��' => '唶',
  '��' => '唸',
  '��' => '唹',
  '��' => '唺',
  '��' => '唻',
  '��' => '唽',
  '��' => '啀',
  '��' => '啂',
  '��' => '啅',
  '��' => '啇',
  '��' => '啈',
  '��' => '啋',
  '��' => '啌',
  '��' => '啍',
  '��' => '啎',
  '��' => '問',
  '��' => '啑',
  '��' => '啒',
  '��' => '啓',
  '��' => '啔',
  '��' => '啗',
  '��' => '啘',
  '��' => '啙',
  '��' => '啚',
  '��' => '啛',
  '��' => '啝',
  '��' => '啞',
  '��' => '啟',
  '��' => '啠',
  '��' => '啢',
  '��' => '啣',
  '��' => '啨',
  '��' => '啩',
  '��' => '啫',
  '��' => '啯',
  '��' => '啰',
  '��' => '啱',
  '��' => '啲',
  '��' => '啳',
  '��' => '啴',
  '��' => '啹',
  '��' => '啺',
  '��' => '啽',
  '��' => '啿',
  '��' => '喅',
  '��' => '喆',
  '��' => '喌',
  '��' => '喍',
  '��' => '喎',
  '��' => '喐',
  '��' => '喒',
  '��' => '喓',
  '��' => '喕',
  '��' => '喖',
  '��' => '喗',
  '��' => '喚',
  '��' => '喛',
  '��' => '喞',
  '��' => '喠',
  '��' => '喡',
  '��' => '喢',
  '��' => '喣',
  '��' => '喤',
  '��' => '喥',
  '��' => '喦',
  '��' => '喨',
  '��' => '喩',
  '��' => '喪',
  '��' => '喫',
  '��' => '喬',
  '��' => '喭',
  '��' => '單',
  '��' => '喯',
  '��' => '喰',
  '��' => '喲',
  '��' => '喴',
  '��' => '営',
  '��' => '喸',
  '��' => '喺',
  '��' => '喼',
  '��' => '喿',
  '��' => '嗀',
  '��' => '嗁',
  '��' => '嗂',
  '��' => '嗃',
  '��' => '嗆',
  '��' => '嗇',
  '��' => '嗈',
  '��' => '嗊',
  '��' => '嗋',
  '��' => '嗎',
  '��' => '嗏',
  '��' => '嗐',
  '��' => '嗕',
  '��' => '嗗',
  '��' => '嗘',
  '��' => '嗙',
  '��' => '嗚',
  '��' => '嗛',
  '��' => '嗞',
  '��' => '嗠',
  '��' => '嗢',
  '��' => '嗧',
  '��' => '嗩',
  '��' => '嗭',
  '��' => '嗮',
  '��' => '嗰',
  '��' => '嗱',
  '��' => '嗴',
  '��' => '嗶',
  '��' => '嗸',
  '��' => '嗹',
  '��' => '嗺',
  '��' => '嗻',
  '��' => '嗼',
  '��' => '嗿',
  '��' => '嘂',
  '��' => '嘃',
  '��' => '嘄',
  '��' => '嘅',
  '�@' => '嘆',
  '�A' => '嘇',
  '�B' => '嘊',
  '�C' => '嘋',
  '�D' => '嘍',
  '�E' => '嘐',
  '�F' => '嘑',
  '�G' => '嘒',
  '�H' => '嘓',
  '�I' => '嘔',
  '�J' => '嘕',
  '�K' => '嘖',
  '�L' => '嘗',
  '�M' => '嘙',
  '�N' => '嘚',
  '�O' => '嘜',
  '�P' => '嘝',
  '�Q' => '嘠',
  '�R' => '嘡',
  '�S' => '嘢',
  '�T' => '嘥',
  '�U' => '嘦',
  '�V' => '嘨',
  '�W' => '嘩',
  '�X' => '嘪',
  '�Y' => '嘫',
  '�Z' => '嘮',
  '�[' => '嘯',
  '�\\' => '嘰',
  '�]' => '嘳',
  '�^' => '嘵',
  '�_' => '嘷',
  '�`' => '嘸',
  '�a' => '嘺',
  '�b' => '嘼',
  '�c' => '嘽',
  '�d' => '嘾',
  '�e' => '噀',
  '�f' => '噁',
  '�g' => '噂',
  '�h' => '噃',
  '�i' => '噄',
  '�j' => '噅',
  '�k' => '噆',
  '�l' => '噇',
  '�m' => '噈',
  '�n' => '噉',
  '�o' => '噊',
  '�p' => '噋',
  '�q' => '噏',
  '�r' => '噐',
  '�s' => '噑',
  '�t' => '噒',
  '�u' => '噓',
  '�v' => '噕',
  '�w' => '噖',
  '�x' => '噚',
  '�y' => '噛',
  '�z' => '噝',
  '�{' => '噞',
  '�|' => '噟',
  '�}' => '噠',
  '�~' => '噡',
  '��' => '噣',
  '��' => '噥',
  '��' => '噦',
  '��' => '噧',
  '��' => '噭',
  '��' => '噮',
  '��' => '噯',
  '��' => '噰',
  '��' => '噲',
  '��' => '噳',
  '��' => '噴',
  '��' => '噵',
  '��' => '噷',
  '��' => '噸',
  '��' => '噹',
  '��' => '噺',
  '��' => '噽',
  '��' => '噾',
  '��' => '噿',
  '��' => '嚀',
  '��' => '嚁',
  '��' => '嚂',
  '��' => '嚃',
  '��' => '嚄',
  '��' => '嚇',
  '��' => '嚈',
  '��' => '嚉',
  '��' => '嚊',
  '��' => '嚋',
  '��' => '嚌',
  '��' => '嚍',
  '��' => '嚐',
  '��' => '嚑',
  '��' => '嚒',
  '��' => '嚔',
  '��' => '嚕',
  '��' => '嚖',
  '��' => '嚗',
  '��' => '嚘',
  '��' => '嚙',
  '��' => '嚚',
  '��' => '嚛',
  '��' => '嚜',
  '��' => '嚝',
  '��' => '嚞',
  '��' => '嚟',
  '��' => '嚠',
  '��' => '嚡',
  '��' => '嚢',
  '��' => '嚤',
  '��' => '嚥',
  '��' => '嚦',
  '��' => '嚧',
  '��' => '嚨',
  '��' => '嚩',
  '��' => '嚪',
  '��' => '嚫',
  '��' => '嚬',
  '��' => '嚭',
  '��' => '嚮',
  '��' => '嚰',
  '��' => '嚱',
  '��' => '嚲',
  '��' => '嚳',
  '��' => '嚴',
  '��' => '嚵',
  '��' => '嚶',
  '��' => '嚸',
  '��' => '嚹',
  '��' => '嚺',
  '��' => '嚻',
  '��' => '嚽',
  '��' => '嚾',
  '��' => '嚿',
  '��' => '囀',
  '��' => '囁',
  '��' => '囂',
  '��' => '囃',
  '��' => '囄',
  '��' => '囅',
  '��' => '囆',
  '��' => '囇',
  '��' => '囈',
  '��' => '囉',
  '��' => '囋',
  '��' => '囌',
  '��' => '囍',
  '��' => '囎',
  '��' => '囏',
  '��' => '囐',
  '��' => '囑',
  '��' => '囒',
  '��' => '囓',
  '��' => '囕',
  '��' => '囖',
  '��' => '囘',
  '��' => '囙',
  '��' => '囜',
  '��' => '団',
  '��' => '囥',
  '��' => '囦',
  '��' => '囧',
  '��' => '囨',
  '��' => '囩',
  '��' => '囪',
  '��' => '囬',
  '��' => '囮',
  '��' => '囯',
  '��' => '囲',
  '��' => '図',
  '��' => '囶',
  '��' => '囷',
  '��' => '囸',
  '��' => '囻',
  '��' => '囼',
  '��' => '圀',
  '��' => '圁',
  '��' => '圂',
  '��' => '圅',
  '��' => '圇',
  '��' => '國',
  '��' => '圌',
  '��' => '圍',
  '��' => '圎',
  '��' => '圏',
  '��' => '圐',
  '��' => '圑',
  '�@' => '園',
  '�A' => '圓',
  '�B' => '圔',
  '�C' => '圕',
  '�D' => '圖',
  '�E' => '圗',
  '�F' => '團',
  '�G' => '圙',
  '�H' => '圚',
  '�I' => '圛',
  '�J' => '圝',
  '�K' => '圞',
  '�L' => '圠',
  '�M' => '圡',
  '�N' => '圢',
  '�O' => '圤',
  '�P' => '圥',
  '�Q' => '圦',
  '�R' => '圧',
  '�S' => '圫',
  '�T' => '圱',
  '�U' => '圲',
  '�V' => '圴',
  '�W' => '圵',
  '�X' => '圶',
  '�Y' => '圷',
  '�Z' => '圸',
  '�[' => '圼',
  '�\\' => '圽',
  '�]' => '圿',
  '�^' => '坁',
  '�_' => '坃',
  '�`' => '坄',
  '�a' => '坅',
  '�b' => '坆',
  '�c' => '坈',
  '�d' => '坉',
  '�e' => '坋',
  '�f' => '坒',
  '�g' => '坓',
  '�h' => '坔',
  '�i' => '坕',
  '�j' => '坖',
  '�k' => '坘',
  '�l' => '坙',
  '�m' => '坢',
  '�n' => '坣',
  '�o' => '坥',
  '�p' => '坧',
  '�q' => '坬',
  '�r' => '坮',
  '�s' => '坰',
  '�t' => '坱',
  '�u' => '坲',
  '�v' => '坴',
  '�w' => '坵',
  '�x' => '坸',
  '�y' => '坹',
  '�z' => '坺',
  '�{' => '坽',
  '�|' => '坾',
  '�}' => '坿',
  '�~' => '垀',
  '��' => '垁',
  '��' => '垇',
  '��' => '垈',
  '��' => '垉',
  '��' => '垊',
  '��' => '垍',
  '��' => '垎',
  '��' => '垏',
  '��' => '垐',
  '��' => '垑',
  '��' => '垔',
  '��' => '垕',
  '��' => '垖',
  '��' => '垗',
  '��' => '垘',
  '��' => '垙',
  '��' => '垚',
  '��' => '垜',
  '��' => '垝',
  '��' => '垞',
  '��' => '垟',
  '��' => '垥',
  '��' => '垨',
  '��' => '垪',
  '��' => '垬',
  '��' => '垯',
  '��' => '垰',
  '��' => '垱',
  '��' => '垳',
  '��' => '垵',
  '��' => '垶',
  '��' => '垷',
  '��' => '垹',
  '��' => '垺',
  '��' => '垻',
  '��' => '垼',
  '��' => '垽',
  '��' => '垾',
  '��' => '垿',
  '��' => '埀',
  '��' => '埁',
  '��' => '埄',
  '��' => '埅',
  '��' => '埆',
  '��' => '埇',
  '��' => '埈',
  '��' => '埉',
  '��' => '埊',
  '��' => '埌',
  '��' => '埍',
  '��' => '埐',
  '��' => '埑',
  '��' => '埓',
  '��' => '埖',
  '��' => '埗',
  '��' => '埛',
  '��' => '埜',
  '��' => '埞',
  '��' => '埡',
  '��' => '埢',
  '��' => '埣',
  '��' => '埥',
  '��' => '埦',
  '��' => '埧',
  '��' => '埨',
  '��' => '埩',
  '��' => '埪',
  '��' => '埫',
  '��' => '埬',
  '��' => '埮',
  '��' => '埰',
  '��' => '埱',
  '��' => '埲',
  '��' => '埳',
  '��' => '埵',
  '��' => '埶',
  '��' => '執',
  '��' => '埻',
  '��' => '埼',
  '��' => '埾',
  '��' => '埿',
  '��' => '堁',
  '��' => '堃',
  '��' => '堄',
  '��' => '堅',
  '��' => '堈',
  '��' => '堉',
  '��' => '堊',
  '��' => '堌',
  '��' => '堎',
  '��' => '堏',
  '��' => '堐',
  '��' => '堒',
  '��' => '堓',
  '��' => '堔',
  '��' => '堖',
  '��' => '堗',
  '��' => '堘',
  '��' => '堚',
  '��' => '堛',
  '��' => '堜',
  '��' => '堝',
  '��' => '堟',
  '��' => '堢',
  '��' => '堣',
  '��' => '堥',
  '��' => '堦',
  '��' => '堧',
  '��' => '堨',
  '��' => '堩',
  '��' => '堫',
  '��' => '堬',
  '��' => '堭',
  '��' => '堮',
  '��' => '堯',
  '��' => '報',
  '��' => '堲',
  '��' => '堳',
  '��' => '場',
  '��' => '堶',
  '��' => '堷',
  '��' => '堸',
  '��' => '堹',
  '��' => '堺',
  '��' => '堻',
  '��' => '堼',
  '��' => '堽',
  '�@' => '堾',
  '�A' => '堿',
  '�B' => '塀',
  '�C' => '塁',
  '�D' => '塂',
  '�E' => '塃',
  '�F' => '塅',
  '�G' => '塆',
  '�H' => '塇',
  '�I' => '塈',
  '�J' => '塉',
  '�K' => '塊',
  '�L' => '塋',
  '�M' => '塎',
  '�N' => '塏',
  '�O' => '塐',
  '�P' => '塒',
  '�Q' => '塓',
  '�R' => '塕',
  '�S' => '塖',
  '�T' => '塗',
  '�U' => '塙',
  '�V' => '塚',
  '�W' => '塛',
  '�X' => '塜',
  '�Y' => '塝',
  '�Z' => '塟',
  '�[' => '塠',
  '�\\' => '塡',
  '�]' => '塢',
  '�^' => '塣',
  '�_' => '塤',
  '�`' => '塦',
  '�a' => '塧',
  '�b' => '塨',
  '�c' => '塩',
  '�d' => '塪',
  '�e' => '塭',
  '�f' => '塮',
  '�g' => '塯',
  '�h' => '塰',
  '�i' => '塱',
  '�j' => '塲',
  '�k' => '塳',
  '�l' => '塴',
  '�m' => '塵',
  '�n' => '塶',
  '�o' => '塷',
  '�p' => '塸',
  '�q' => '塹',
  '�r' => '塺',
  '�s' => '塻',
  '�t' => '塼',
  '�u' => '塽',
  '�v' => '塿',
  '�w' => '墂',
  '�x' => '墄',
  '�y' => '墆',
  '�z' => '墇',
  '�{' => '墈',
  '�|' => '墊',
  '�}' => '墋',
  '�~' => '墌',
  '��' => '墍',
  '��' => '墎',
  '��' => '墏',
  '��' => '墐',
  '��' => '墑',
  '��' => '墔',
  '��' => '墕',
  '��' => '墖',
  '��' => '増',
  '��' => '墘',
  '��' => '墛',
  '��' => '墜',
  '��' => '墝',
  '��' => '墠',
  '��' => '墡',
  '��' => '墢',
  '��' => '墣',
  '��' => '墤',
  '��' => '墥',
  '��' => '墦',
  '��' => '墧',
  '��' => '墪',
  '��' => '墫',
  '��' => '墬',
  '��' => '墭',
  '��' => '墮',
  '��' => '墯',
  '��' => '墰',
  '��' => '墱',
  '��' => '墲',
  '��' => '墳',
  '��' => '墴',
  '��' => '墵',
  '��' => '墶',
  '��' => '墷',
  '��' => '墸',
  '��' => '墹',
  '��' => '墺',
  '��' => '墻',
  '��' => '墽',
  '��' => '墾',
  '��' => '墿',
  '��' => '壀',
  '��' => '壂',
  '��' => '壃',
  '��' => '壄',
  '��' => '壆',
  '��' => '壇',
  '��' => '壈',
  '��' => '壉',
  '��' => '壊',
  '��' => '壋',
  '��' => '壌',
  '��' => '壍',
  '��' => '壎',
  '��' => '壏',
  '��' => '壐',
  '��' => '壒',
  '��' => '壓',
  '��' => '壔',
  '��' => '壖',
  '��' => '壗',
  '��' => '壘',
  '��' => '壙',
  '��' => '壚',
  '��' => '壛',
  '��' => '壜',
  '��' => '壝',
  '��' => '壞',
  '��' => '壟',
  '��' => '壠',
  '��' => '壡',
  '��' => '壢',
  '��' => '壣',
  '��' => '壥',
  '��' => '壦',
  '��' => '壧',
  '��' => '壨',
  '��' => '壩',
  '��' => '壪',
  '��' => '壭',
  '��' => '壯',
  '��' => '壱',
  '��' => '売',
  '��' => '壴',
  '��' => '壵',
  '��' => '壷',
  '��' => '壸',
  '��' => '壺',
  '��' => '壻',
  '��' => '壼',
  '��' => '壽',
  '��' => '壾',
  '��' => '壿',
  '��' => '夀',
  '��' => '夁',
  '��' => '夃',
  '��' => '夅',
  '��' => '夆',
  '��' => '夈',
  '��' => '変',
  '��' => '夊',
  '��' => '夋',
  '��' => '夌',
  '��' => '夎',
  '��' => '夐',
  '��' => '夑',
  '��' => '夒',
  '��' => '夓',
  '��' => '夗',
  '��' => '夘',
  '��' => '夛',
  '��' => '夝',
  '��' => '夞',
  '��' => '夠',
  '��' => '夡',
  '��' => '夢',
  '��' => '夣',
  '��' => '夦',
  '��' => '夨',
  '��' => '夬',
  '��' => '夰',
  '��' => '夲',
  '��' => '夳',
  '��' => '夵',
  '��' => '夶',
  '��' => '夻',
  '�@' => '夽',
  '�A' => '夾',
  '�B' => '夿',
  '�C' => '奀',
  '�D' => '奃',
  '�E' => '奅',
  '�F' => '奆',
  '�G' => '奊',
  '�H' => '奌',
  '�I' => '奍',
  '�J' => '奐',
  '�K' => '奒',
  '�L' => '奓',
  '�M' => '奙',
  '�N' => '奛',
  '�O' => '奜',
  '�P' => '奝',
  '�Q' => '奞',
  '�R' => '奟',
  '�S' => '奡',
  '�T' => '奣',
  '�U' => '奤',
  '�V' => '奦',
  '�W' => '奧',
  '�X' => '奨',
  '�Y' => '奩',
  '�Z' => '奪',
  '�[' => '奫',
  '�\\' => '奬',
  '�]' => '奭',
  '�^' => '奮',
  '�_' => '奯',
  '�`' => '奰',
  '�a' => '奱',
  '�b' => '奲',
  '�c' => '奵',
  '�d' => '奷',
  '�e' => '奺',
  '�f' => '奻',
  '�g' => '奼',
  '�h' => '奾',
  '�i' => '奿',
  '�j' => '妀',
  '�k' => '妅',
  '�l' => '妉',
  '�m' => '妋',
  '�n' => '妌',
  '�o' => '妎',
  '�p' => '妏',
  '�q' => '妐',
  '�r' => '妑',
  '�s' => '妔',
  '�t' => '妕',
  '�u' => '妘',
  '�v' => '妚',
  '�w' => '妛',
  '�x' => '妜',
  '�y' => '妝',
  '�z' => '妟',
  '�{' => '妠',
  '�|' => '妡',
  '�}' => '妢',
  '�~' => '妦',
  '��' => '妧',
  '��' => '妬',
  '��' => '妭',
  '��' => '妰',
  '��' => '妱',
  '��' => '妳',
  '��' => '妴',
  '��' => '妵',
  '��' => '妶',
  '��' => '妷',
  '��' => '妸',
  '��' => '妺',
  '��' => '妼',
  '��' => '妽',
  '��' => '妿',
  '��' => '姀',
  '��' => '姁',
  '��' => '姂',
  '��' => '姃',
  '��' => '姄',
  '��' => '姅',
  '��' => '姇',
  '��' => '姈',
  '��' => '姉',
  '��' => '姌',
  '��' => '姍',
  '��' => '姎',
  '��' => '姏',
  '��' => '姕',
  '��' => '姖',
  '��' => '姙',
  '��' => '姛',
  '��' => '姞',
  '��' => '姟',
  '��' => '姠',
  '��' => '姡',
  '��' => '姢',
  '��' => '姤',
  '��' => '姦',
  '��' => '姧',
  '��' => '姩',
  '��' => '姪',
  '��' => '姫',
  '��' => '姭',
  '��' => '姮',
  '��' => '姯',
  '��' => '姰',
  '��' => '姱',
  '��' => '姲',
  '��' => '姳',
  '��' => '姴',
  '��' => '姵',
  '��' => '姶',
  '��' => '姷',
  '��' => '姸',
  '��' => '姺',
  '��' => '姼',
  '��' => '姽',
  '��' => '姾',
  '��' => '娀',
  '��' => '娂',
  '��' => '娊',
  '��' => '娋',
  '��' => '娍',
  '��' => '娎',
  '��' => '娏',
  '��' => '娐',
  '��' => '娒',
  '��' => '娔',
  '��' => '娕',
  '��' => '娖',
  '��' => '娗',
  '��' => '娙',
  '��' => '娚',
  '��' => '娛',
  '��' => '娝',
  '��' => '娞',
  '��' => '娡',
  '��' => '娢',
  '��' => '娤',
  '��' => '娦',
  '��' => '娧',
  '��' => '娨',
  '��' => '娪',
  '��' => '娫',
  '��' => '娬',
  '��' => '娭',
  '��' => '娮',
  '��' => '娯',
  '��' => '娰',
  '��' => '娳',
  '��' => '娵',
  '��' => '娷',
  '��' => '娸',
  '��' => '娹',
  '��' => '娺',
  '��' => '娻',
  '��' => '娽',
  '��' => '娾',
  '��' => '娿',
  '��' => '婁',
  '��' => '婂',
  '��' => '婃',
  '��' => '婄',
  '��' => '婅',
  '��' => '婇',
  '��' => '婈',
  '��' => '婋',
  '��' => '婌',
  '��' => '婍',
  '��' => '婎',
  '��' => '婏',
  '��' => '婐',
  '��' => '婑',
  '��' => '婒',
  '��' => '婓',
  '��' => '婔',
  '��' => '婖',
  '��' => '婗',
  '��' => '婘',
  '��' => '婙',
  '��' => '婛',
  '��' => '婜',
  '��' => '婝',
  '��' => '婞',
  '��' => '婟',
  '��' => '婠',
  '�@' => '婡',
  '�A' => '婣',
  '�B' => '婤',
  '�C' => '婥',
  '�D' => '婦',
  '�E' => '婨',
  '�F' => '婩',
  '�G' => '婫',
  '�H' => '婬',
  '�I' => '婭',
  '�J' => '婮',
  '�K' => '婯',
  '�L' => '婰',
  '�M' => '婱',
  '�N' => '婲',
  '�O' => '婳',
  '�P' => '婸',
  '�Q' => '婹',
  '�R' => '婻',
  '�S' => '婼',
  '�T' => '婽',
  '�U' => '婾',
  '�V' => '媀',
  '�W' => '媁',
  '�X' => '媂',
  '�Y' => '媃',
  '�Z' => '媄',
  '�[' => '媅',
  '�\\' => '媆',
  '�]' => '媇',
  '�^' => '媈',
  '�_' => '媉',
  '�`' => '媊',
  '�a' => '媋',
  '�b' => '媌',
  '�c' => '媍',
  '�d' => '媎',
  '�e' => '媏',
  '�f' => '媐',
  '�g' => '媑',
  '�h' => '媓',
  '�i' => '媔',
  '�j' => '媕',
  '�k' => '媖',
  '�l' => '媗',
  '�m' => '媘',
  '�n' => '媙',
  '�o' => '媜',
  '�p' => '媝',
  '�q' => '媞',
  '�r' => '媟',
  '�s' => '媠',
  '�t' => '媡',
  '�u' => '媢',
  '�v' => '媣',
  '�w' => '媤',
  '�x' => '媥',
  '�y' => '媦',
  '�z' => '媧',
  '�{' => '媨',
  '�|' => '媩',
  '�}' => '媫',
  '�~' => '媬',
  '��' => '媭',
  '��' => '媮',
  '��' => '媯',
  '��' => '媰',
  '��' => '媱',
  '��' => '媴',
  '��' => '媶',
  '��' => '媷',
  '��' => '媹',
  '��' => '媺',
  '��' => '媻',
  '��' => '媼',
  '��' => '媽',
  '��' => '媿',
  '��' => '嫀',
  '��' => '嫃',
  '��' => '嫄',
  '��' => '嫅',
  '��' => '嫆',
  '��' => '嫇',
  '��' => '嫈',
  '��' => '嫊',
  '��' => '嫋',
  '��' => '嫍',
  '��' => '嫎',
  '��' => '嫏',
  '��' => '嫐',
  '��' => '嫑',
  '��' => '嫓',
  '��' => '嫕',
  '��' => '嫗',
  '��' => '嫙',
  '��' => '嫚',
  '��' => '嫛',
  '��' => '嫝',
  '��' => '嫞',
  '��' => '嫟',
  '��' => '嫢',
  '��' => '嫤',
  '��' => '嫥',
  '��' => '嫧',
  '��' => '嫨',
  '��' => '嫪',
  '��' => '嫬',
  '��' => '嫭',
  '��' => '嫮',
  '��' => '嫯',
  '��' => '嫰',
  '��' => '嫲',
  '��' => '嫳',
  '��' => '嫴',
  '��' => '嫵',
  '��' => '嫶',
  '��' => '嫷',
  '��' => '嫸',
  '��' => '嫹',
  '��' => '嫺',
  '��' => '嫻',
  '��' => '嫼',
  '��' => '嫽',
  '��' => '嫾',
  '��' => '嫿',
  '��' => '嬀',
  '��' => '嬁',
  '��' => '嬂',
  '��' => '嬃',
  '��' => '嬄',
  '��' => '嬅',
  '��' => '嬆',
  '��' => '嬇',
  '��' => '嬈',
  '��' => '嬊',
  '��' => '嬋',
  '��' => '嬌',
  '��' => '嬍',
  '��' => '嬎',
  '��' => '嬏',
  '��' => '嬐',
  '��' => '嬑',
  '��' => '嬒',
  '��' => '嬓',
  '��' => '嬔',
  '��' => '嬕',
  '��' => '嬘',
  '��' => '嬙',
  '��' => '嬚',
  '��' => '嬛',
  '��' => '嬜',
  '��' => '嬝',
  '��' => '嬞',
  '��' => '嬟',
  '��' => '嬠',
  '��' => '嬡',
  '��' => '嬢',
  '��' => '嬣',
  '��' => '嬤',
  '��' => '嬥',
  '��' => '嬦',
  '��' => '嬧',
  '��' => '嬨',
  '��' => '嬩',
  '��' => '嬪',
  '��' => '嬫',
  '��' => '嬬',
  '��' => '嬭',
  '��' => '嬮',
  '��' => '嬯',
  '��' => '嬰',
  '��' => '嬱',
  '��' => '嬳',
  '��' => '嬵',
  '��' => '嬶',
  '��' => '嬸',
  '��' => '嬹',
  '��' => '嬺',
  '��' => '嬻',
  '��' => '嬼',
  '��' => '嬽',
  '��' => '嬾',
  '��' => '嬿',
  '��' => '孁',
  '��' => '孂',
  '��' => '孃',
  '��' => '孄',
  '��' => '孅',
  '��' => '孆',
  '��' => '孇',
  '�@' => '孈',
  '�A' => '孉',
  '�B' => '孊',
  '�C' => '孋',
  '�D' => '孌',
  '�E' => '孍',
  '�F' => '孎',
  '�G' => '孏',
  '�H' => '孒',
  '�I' => '孖',
  '�J' => '孞',
  '�K' => '孠',
  '�L' => '孡',
  '�M' => '孧',
  '�N' => '孨',
  '�O' => '孫',
  '�P' => '孭',
  '�Q' => '孮',
  '�R' => '孯',
  '�S' => '孲',
  '�T' => '孴',
  '�U' => '孶',
  '�V' => '孷',
  '�W' => '學',
  '�X' => '孹',
  '�Y' => '孻',
  '�Z' => '孼',
  '�[' => '孾',
  '�\\' => '孿',
  '�]' => '宂',
  '�^' => '宆',
  '�_' => '宊',
  '�`' => '宍',
  '�a' => '宎',
  '�b' => '宐',
  '�c' => '宑',
  '�d' => '宒',
  '�e' => '宔',
  '�f' => '宖',
  '�g' => '実',
  '�h' => '宧',
  '�i' => '宨',
  '�j' => '宩',
  '�k' => '宬',
  '�l' => '宭',
  '�m' => '宮',
  '�n' => '宯',
  '�o' => '宱',
  '�p' => '宲',
  '�q' => '宷',
  '�r' => '宺',
  '�s' => '宻',
  '�t' => '宼',
  '�u' => '寀',
  '�v' => '寁',
  '�w' => '寃',
  '�x' => '寈',
  '�y' => '寉',
  '�z' => '寊',
  '�{' => '寋',
  '�|' => '寍',
  '�}' => '寎',
  '�~' => '寏',
  '��' => '寑',
  '��' => '寔',
  '��' => '寕',
  '��' => '寖',
  '��' => '寗',
  '��' => '寘',
  '��' => '寙',
  '��' => '寚',
  '��' => '寛',
  '��' => '寜',
  '��' => '寠',
  '��' => '寢',
  '��' => '寣',
  '��' => '實',
  '��' => '寧',
  '��' => '審',
  '��' => '寪',
  '��' => '寫',
  '��' => '寬',
  '��' => '寭',
  '��' => '寯',
  '��' => '寱',
  '��' => '寲',
  '��' => '寳',
  '��' => '寴',
  '��' => '寵',
  '��' => '寶',
  '��' => '寷',
  '��' => '寽',
  '��' => '対',
  '��' => '尀',
  '��' => '専',
  '��' => '尃',
  '��' => '尅',
  '��' => '將',
  '��' => '專',
  '��' => '尋',
  '��' => '尌',
  '��' => '對',
  '��' => '導',
  '��' => '尐',
  '��' => '尒',
  '��' => '尓',
  '��' => '尗',
  '��' => '尙',
  '��' => '尛',
  '��' => '尞',
  '��' => '尟',
  '��' => '尠',
  '��' => '尡',
  '��' => '尣',
  '��' => '尦',
  '��' => '尨',
  '��' => '尩',
  '��' => '尪',
  '��' => '尫',
  '��' => '尭',
  '��' => '尮',
  '��' => '尯',
  '��' => '尰',
  '��' => '尲',
  '��' => '尳',
  '��' => '尵',
  '��' => '尶',
  '��' => '尷',
  '��' => '屃',
  '��' => '屄',
  '��' => '屆',
  '��' => '屇',
  '��' => '屌',
  '��' => '屍',
  '��' => '屒',
  '��' => '屓',
  '��' => '屔',
  '��' => '屖',
  '��' => '屗',
  '��' => '屘',
  '��' => '屚',
  '��' => '屛',
  '��' => '屜',
  '��' => '屝',
  '��' => '屟',
  '��' => '屢',
  '��' => '層',
  '��' => '屧',
  '��' => '屨',
  '��' => '屩',
  '��' => '屪',
  '��' => '屫',
  '��' => '屬',
  '��' => '屭',
  '��' => '屰',
  '��' => '屲',
  '��' => '屳',
  '��' => '屴',
  '��' => '屵',
  '��' => '屶',
  '��' => '屷',
  '��' => '屸',
  '��' => '屻',
  '��' => '屼',
  '��' => '屽',
  '��' => '屾',
  '��' => '岀',
  '��' => '岃',
  '��' => '岄',
  '��' => '岅',
  '��' => '岆',
  '��' => '岇',
  '��' => '岉',
  '��' => '岊',
  '��' => '岋',
  '��' => '岎',
  '��' => '岏',
  '��' => '岒',
  '��' => '岓',
  '��' => '岕',
  '��' => '岝',
  '��' => '岞',
  '��' => '岟',
  '��' => '岠',
  '��' => '岡',
  '��' => '岤',
  '��' => '岥',
  '��' => '岦',
  '��' => '岧',
  '��' => '岨',
  '�@' => '岪',
  '�A' => '岮',
  '�B' => '岯',
  '�C' => '岰',
  '�D' => '岲',
  '�E' => '岴',
  '�F' => '岶',
  '�G' => '岹',
  '�H' => '岺',
  '�I' => '岻',
  '�J' => '岼',
  '�K' => '岾',
  '�L' => '峀',
  '�M' => '峂',
  '�N' => '峃',
  '�O' => '峅',
  '�P' => '峆',
  '�Q' => '峇',
  '�R' => '峈',
  '�S' => '峉',
  '�T' => '峊',
  '�U' => '峌',
  '�V' => '峍',
  '�W' => '峎',
  '�X' => '峏',
  '�Y' => '峐',
  '�Z' => '峑',
  '�[' => '峓',
  '�\\' => '峔',
  '�]' => '峕',
  '�^' => '峖',
  '�_' => '峗',
  '�`' => '峘',
  '�a' => '峚',
  '�b' => '峛',
  '�c' => '峜',
  '�d' => '峝',
  '�e' => '峞',
  '�f' => '峟',
  '�g' => '峠',
  '�h' => '峢',
  '�i' => '峣',
  '�j' => '峧',
  '�k' => '峩',
  '�l' => '峫',
  '�m' => '峬',
  '�n' => '峮',
  '�o' => '峯',
  '�p' => '峱',
  '�q' => '峲',
  '�r' => '峳',
  '�s' => '峴',
  '�t' => '峵',
  '�u' => '島',
  '�v' => '峷',
  '�w' => '峸',
  '�x' => '峹',
  '�y' => '峺',
  '�z' => '峼',
  '�{' => '峽',
  '�|' => '峾',
  '�}' => '峿',
  '�~' => '崀',
  '��' => '崁',
  '��' => '崄',
  '��' => '崅',
  '��' => '崈',
  '��' => '崉',
  '��' => '崊',
  '��' => '崋',
  '��' => '崌',
  '��' => '崍',
  '��' => '崏',
  '��' => '崐',
  '��' => '崑',
  '��' => '崒',
  '��' => '崓',
  '��' => '崕',
  '��' => '崗',
  '��' => '崘',
  '��' => '崙',
  '��' => '崚',
  '��' => '崜',
  '��' => '崝',
  '��' => '崟',
  '��' => '崠',
  '��' => '崡',
  '��' => '崢',
  '��' => '崣',
  '��' => '崥',
  '��' => '崨',
  '��' => '崪',
  '��' => '崫',
  '��' => '崬',
  '��' => '崯',
  '��' => '崰',
  '��' => '崱',
  '��' => '崲',
  '��' => '崳',
  '��' => '崵',
  '��' => '崶',
  '��' => '崷',
  '��' => '崸',
  '��' => '崹',
  '��' => '崺',
  '��' => '崻',
  '��' => '崼',
  '��' => '崿',
  '��' => '嵀',
  '��' => '嵁',
  '��' => '嵂',
  '��' => '嵃',
  '��' => '嵄',
  '��' => '嵅',
  '��' => '嵆',
  '��' => '嵈',
  '��' => '嵉',
  '��' => '嵍',
  '��' => '嵎',
  '��' => '嵏',
  '��' => '嵐',
  '��' => '嵑',
  '��' => '嵒',
  '��' => '嵓',
  '��' => '嵔',
  '��' => '嵕',
  '��' => '嵖',
  '��' => '嵗',
  '��' => '嵙',
  '��' => '嵚',
  '��' => '嵜',
  '��' => '嵞',
  '��' => '嵟',
  '��' => '嵠',
  '��' => '嵡',
  '��' => '嵢',
  '��' => '嵣',
  '��' => '嵤',
  '��' => '嵥',
  '��' => '嵦',
  '��' => '嵧',
  '��' => '嵨',
  '��' => '嵪',
  '��' => '嵭',
  '��' => '嵮',
  '��' => '嵰',
  '��' => '嵱',
  '��' => '嵲',
  '��' => '嵳',
  '��' => '嵵',
  '��' => '嵶',
  '��' => '嵷',
  '��' => '嵸',
  '��' => '嵹',
  '��' => '嵺',
  '��' => '嵻',
  '��' => '嵼',
  '��' => '嵽',
  '��' => '嵾',
  '��' => '嵿',
  '��' => '嶀',
  '��' => '嶁',
  '��' => '嶃',
  '��' => '嶄',
  '��' => '嶅',
  '��' => '嶆',
  '��' => '嶇',
  '��' => '嶈',
  '��' => '嶉',
  '��' => '嶊',
  '��' => '嶋',
  '��' => '嶌',
  '��' => '嶍',
  '��' => '嶎',
  '��' => '嶏',
  '��' => '嶐',
  '��' => '嶑',
  '��' => '嶒',
  '��' => '嶓',
  '��' => '嶔',
  '��' => '嶕',
  '��' => '嶖',
  '��' => '嶗',
  '��' => '嶘',
  '��' => '嶚',
  '��' => '嶛',
  '��' => '嶜',
  '��' => '嶞',
  '��' => '嶟',
  '��' => '嶠',
  '�@' => '嶡',
  '�A' => '嶢',
  '�B' => '嶣',
  '�C' => '嶤',
  '�D' => '嶥',
  '�E' => '嶦',
  '�F' => '嶧',
  '�G' => '嶨',
  '�H' => '嶩',
  '�I' => '嶪',
  '�J' => '嶫',
  '�K' => '嶬',
  '�L' => '嶭',
  '�M' => '嶮',
  '�N' => '嶯',
  '�O' => '嶰',
  '�P' => '嶱',
  '�Q' => '嶲',
  '�R' => '嶳',
  '�S' => '嶴',
  '�T' => '嶵',
  '�U' => '嶶',
  '�V' => '嶸',
  '�W' => '嶹',
  '�X' => '嶺',
  '�Y' => '嶻',
  '�Z' => '嶼',
  '�[' => '嶽',
  '�\\' => '嶾',
  '�]' => '嶿',
  '�^' => '巀',
  '�_' => '巁',
  '�`' => '巂',
  '�a' => '巃',
  '�b' => '巄',
  '�c' => '巆',
  '�d' => '巇',
  '�e' => '巈',
  '�f' => '巉',
  '�g' => '巊',
  '�h' => '巋',
  '�i' => '巌',
  '�j' => '巎',
  '�k' => '巏',
  '�l' => '巐',
  '�m' => '巑',
  '�n' => '巒',
  '�o' => '巓',
  '�p' => '巔',
  '�q' => '巕',
  '�r' => '巖',
  '�s' => '巗',
  '�t' => '巘',
  '�u' => '巙',
  '�v' => '巚',
  '�w' => '巜',
  '�x' => '巟',
  '�y' => '巠',
  '�z' => '巣',
  '�{' => '巤',
  '�|' => '巪',
  '�}' => '巬',
  '�~' => '巭',
  '��' => '巰',
  '��' => '巵',
  '��' => '巶',
  '��' => '巸',
  '��' => '巹',
  '��' => '巺',
  '��' => '巻',
  '��' => '巼',
  '��' => '巿',
  '��' => '帀',
  '��' => '帄',
  '��' => '帇',
  '��' => '帉',
  '��' => '帊',
  '��' => '帋',
  '��' => '帍',
  '��' => '帎',
  '��' => '帒',
  '��' => '帓',
  '��' => '帗',
  '��' => '帞',
  '��' => '帟',
  '��' => '帠',
  '��' => '帡',
  '��' => '帢',
  '��' => '帣',
  '��' => '帤',
  '��' => '帥',
  '��' => '帨',
  '��' => '帩',
  '��' => '帪',
  '��' => '師',
  '��' => '帬',
  '��' => '帯',
  '��' => '帰',
  '��' => '帲',
  '��' => '帳',
  '��' => '帴',
  '��' => '帵',
  '��' => '帶',
  '��' => '帹',
  '��' => '帺',
  '��' => '帾',
  '��' => '帿',
  '��' => '幀',
  '��' => '幁',
  '��' => '幃',
  '��' => '幆',
  '��' => '幇',
  '��' => '幈',
  '��' => '幉',
  '��' => '幊',
  '��' => '幋',
  '��' => '幍',
  '��' => '幎',
  '��' => '幏',
  '��' => '幐',
  '��' => '幑',
  '��' => '幒',
  '��' => '幓',
  '��' => '幖',
  '��' => '幗',
  '��' => '幘',
  '��' => '幙',
  '��' => '幚',
  '��' => '幜',
  '��' => '幝',
  '��' => '幟',
  '��' => '幠',
  '��' => '幣',
  '��' => '幤',
  '��' => '幥',
  '��' => '幦',
  '��' => '幧',
  '��' => '幨',
  '��' => '幩',
  '��' => '幪',
  '��' => '幫',
  '��' => '幬',
  '��' => '幭',
  '��' => '幮',
  '��' => '幯',
  '��' => '幰',
  '��' => '幱',
  '��' => '幵',
  '��' => '幷',
  '��' => '幹',
  '��' => '幾',
  '��' => '庁',
  '��' => '庂',
  '��' => '広',
  '��' => '庅',
  '��' => '庈',
  '��' => '庉',
  '��' => '庌',
  '��' => '庍',
  '��' => '庎',
  '��' => '庒',
  '��' => '庘',
  '��' => '庛',
  '��' => '庝',
  '��' => '庡',
  '��' => '庢',
  '��' => '庣',
  '��' => '庤',
  '��' => '庨',
  '��' => '庩',
  '��' => '庪',
  '��' => '庫',
  '��' => '庬',
  '��' => '庮',
  '��' => '庯',
  '��' => '庰',
  '��' => '庱',
  '��' => '庲',
  '��' => '庴',
  '��' => '庺',
  '��' => '庻',
  '��' => '庼',
  '��' => '庽',
  '��' => '庿',
  '��' => '廀',
  '��' => '廁',
  '��' => '廂',
  '��' => '廃',
  '��' => '廄',
  '��' => '廅',
  '�@' => '廆',
  '�A' => '廇',
  '�B' => '廈',
  '�C' => '廋',
  '�D' => '廌',
  '�E' => '廍',
  '�F' => '廎',
  '�G' => '廏',
  '�H' => '廐',
  '�I' => '廔',
  '�J' => '廕',
  '�K' => '廗',
  '�L' => '廘',
  '�M' => '廙',
  '�N' => '廚',
  '�O' => '廜',
  '�P' => '廝',
  '�Q' => '廞',
  '�R' => '廟',
  '�S' => '廠',
  '�T' => '廡',
  '�U' => '廢',
  '�V' => '廣',
  '�W' => '廤',
  '�X' => '廥',
  '�Y' => '廦',
  '�Z' => '廧',
  '�[' => '廩',
  '�\\' => '廫',
  '�]' => '廬',
  '�^' => '廭',
  '�_' => '廮',
  '�`' => '廯',
  '�a' => '廰',
  '�b' => '廱',
  '�c' => '廲',
  '�d' => '廳',
  '�e' => '廵',
  '�f' => '廸',
  '�g' => '廹',
  '�h' => '廻',
  '�i' => '廼',
  '�j' => '廽',
  '�k' => '弅',
  '�l' => '弆',
  '�m' => '弇',
  '�n' => '弉',
  '�o' => '弌',
  '�p' => '弍',
  '�q' => '弎',
  '�r' => '弐',
  '�s' => '弒',
  '�t' => '弔',
  '�u' => '弖',
  '�v' => '弙',
  '�w' => '弚',
  '�x' => '弜',
  '�y' => '弝',
  '�z' => '弞',
  '�{' => '弡',
  '�|' => '弢',
  '�}' => '弣',
  '�~' => '弤',
  '��' => '弨',
  '��' => '弫',
  '��' => '弬',
  '��' => '弮',
  '��' => '弰',
  '��' => '弲',
  '��' => '弳',
  '��' => '弴',
  '��' => '張',
  '��' => '弶',
  '��' => '強',
  '��' => '弸',
  '��' => '弻',
  '��' => '弽',
  '��' => '弾',
  '��' => '弿',
  '��' => '彁',
  '��' => '彂',
  '��' => '彃',
  '��' => '彄',
  '��' => '彅',
  '��' => '彆',
  '��' => '彇',
  '��' => '彈',
  '��' => '彉',
  '��' => '彊',
  '��' => '彋',
  '��' => '彌',
  '��' => '彍',
  '��' => '彎',
  '��' => '彏',
  '��' => '彑',
  '��' => '彔',
  '��' => '彙',
  '��' => '彚',
  '��' => '彛',
  '��' => '彜',
  '��' => '彞',
  '��' => '彟',
  '��' => '彠',
  '��' => '彣',
  '��' => '彥',
  '��' => '彧',
  '��' => '彨',
  '��' => '彫',
  '��' => '彮',
  '��' => '彯',
  '��' => '彲',
  '��' => '彴',
  '��' => '彵',
  '��' => '彶',
  '��' => '彸',
  '��' => '彺',
  '��' => '彽',
  '��' => '彾',
  '��' => '彿',
  '��' => '徃',
  '��' => '徆',
  '��' => '徍',
  '��' => '徎',
  '��' => '徏',
  '��' => '徑',
  '��' => '従',
  '��' => '徔',
  '��' => '徖',
  '��' => '徚',
  '��' => '徛',
  '��' => '徝',
  '��' => '從',
  '��' => '徟',
  '��' => '徠',
  '��' => '徢',
  '��' => '徣',
  '��' => '徤',
  '��' => '徥',
  '��' => '徦',
  '��' => '徧',
  '��' => '復',
  '��' => '徫',
  '��' => '徬',
  '��' => '徯',
  '��' => '徰',
  '��' => '徱',
  '��' => '徲',
  '��' => '徳',
  '��' => '徴',
  '��' => '徶',
  '��' => '徸',
  '��' => '徹',
  '��' => '徺',
  '��' => '徻',
  '��' => '徾',
  '��' => '徿',
  '��' => '忀',
  '��' => '忁',
  '��' => '忂',
  '��' => '忇',
  '��' => '忈',
  '��' => '忊',
  '��' => '忋',
  '��' => '忎',
  '��' => '忓',
  '��' => '忔',
  '��' => '忕',
  '��' => '忚',
  '��' => '忛',
  '��' => '応',
  '��' => '忞',
  '��' => '忟',
  '��' => '忢',
  '��' => '忣',
  '��' => '忥',
  '��' => '忦',
  '��' => '忨',
  '��' => '忩',
  '��' => '忬',
  '��' => '忯',
  '��' => '忰',
  '��' => '忲',
  '��' => '忳',
  '��' => '忴',
  '��' => '忶',
  '��' => '忷',
  '��' => '忹',
  '��' => '忺',
  '��' => '忼',
  '��' => '怇',
  '�@' => '怈',
  '�A' => '怉',
  '�B' => '怋',
  '�C' => '怌',
  '�D' => '怐',
  '�E' => '怑',
  '�F' => '怓',
  '�G' => '怗',
  '�H' => '怘',
  '�I' => '怚',
  '�J' => '怞',
  '�K' => '怟',
  '�L' => '怢',
  '�M' => '怣',
  '�N' => '怤',
  '�O' => '怬',
  '�P' => '怭',
  '�Q' => '怮',
  '�R' => '怰',
  '�S' => '怱',
  '�T' => '怲',
  '�U' => '怳',
  '�V' => '怴',
  '�W' => '怶',
  '�X' => '怷',
  '�Y' => '怸',
  '�Z' => '怹',
  '�[' => '怺',
  '�\\' => '怽',
  '�]' => '怾',
  '�^' => '恀',
  '�_' => '恄',
  '�`' => '恅',
  '�a' => '恆',
  '�b' => '恇',
  '�c' => '恈',
  '�d' => '恉',
  '�e' => '恊',
  '�f' => '恌',
  '�g' => '恎',
  '�h' => '恏',
  '�i' => '恑',
  '�j' => '恓',
  '�k' => '恔',
  '�l' => '恖',
  '�m' => '恗',
  '�n' => '恘',
  '�o' => '恛',
  '�p' => '恜',
  '�q' => '恞',
  '�r' => '恟',
  '�s' => '恠',
  '�t' => '恡',
  '�u' => '恥',
  '�v' => '恦',
  '�w' => '恮',
  '�x' => '恱',
  '�y' => '恲',
  '�z' => '恴',
  '�{' => '恵',
  '�|' => '恷',
  '�}' => '恾',
  '�~' => '悀',
  '��' => '悁',
  '��' => '悂',
  '��' => '悅',
  '��' => '悆',
  '��' => '悇',
  '��' => '悈',
  '��' => '悊',
  '��' => '悋',
  '��' => '悎',
  '��' => '悏',
  '��' => '悐',
  '��' => '悑',
  '��' => '悓',
  '��' => '悕',
  '��' => '悗',
  '��' => '悘',
  '��' => '悙',
  '��' => '悜',
  '��' => '悞',
  '��' => '悡',
  '��' => '悢',
  '��' => '悤',
  '��' => '悥',
  '��' => '悧',
  '��' => '悩',
  '��' => '悪',
  '��' => '悮',
  '��' => '悰',
  '��' => '悳',
  '��' => '悵',
  '��' => '悶',
  '��' => '悷',
  '��' => '悹',
  '��' => '悺',
  '��' => '悽',
  '��' => '悾',
  '��' => '悿',
  '��' => '惀',
  '��' => '惁',
  '��' => '惂',
  '��' => '惃',
  '��' => '惄',
  '��' => '惇',
  '��' => '惈',
  '��' => '惉',
  '��' => '惌',
  '��' => '惍',
  '��' => '惎',
  '��' => '惏',
  '��' => '惐',
  '��' => '惒',
  '��' => '惓',
  '��' => '惔',
  '��' => '惖',
  '��' => '惗',
  '��' => '惙',
  '��' => '惛',
  '��' => '惞',
  '��' => '惡',
  '��' => '惢',
  '��' => '惣',
  '��' => '惤',
  '��' => '惥',
  '��' => '惪',
  '��' => '惱',
  '��' => '惲',
  '��' => '惵',
  '��' => '惷',
  '��' => '惸',
  '��' => '惻',
  '��' => '惼',
  '��' => '惽',
  '��' => '惾',
  '��' => '惿',
  '��' => '愂',
  '��' => '愃',
  '��' => '愄',
  '��' => '愅',
  '��' => '愇',
  '��' => '愊',
  '��' => '愋',
  '��' => '愌',
  '��' => '愐',
  '��' => '愑',
  '��' => '愒',
  '��' => '愓',
  '��' => '愔',
  '��' => '愖',
  '��' => '愗',
  '��' => '愘',
  '��' => '愙',
  '��' => '愛',
  '��' => '愜',
  '��' => '愝',
  '��' => '愞',
  '��' => '愡',
  '��' => '愢',
  '��' => '愥',
  '��' => '愨',
  '��' => '愩',
  '��' => '愪',
  '��' => '愬',
  '��' => '愭',
  '��' => '愮',
  '��' => '愯',
  '��' => '愰',
  '��' => '愱',
  '��' => '愲',
  '��' => '愳',
  '��' => '愴',
  '��' => '愵',
  '��' => '愶',
  '��' => '愷',
  '��' => '愸',
  '��' => '愹',
  '��' => '愺',
  '��' => '愻',
  '��' => '愼',
  '��' => '愽',
  '��' => '愾',
  '��' => '慀',
  '��' => '慁',
  '��' => '慂',
  '��' => '慃',
  '��' => '慄',
  '��' => '慅',
  '��' => '慆',
  '�@' => '慇',
  '�A' => '慉',
  '�B' => '態',
  '�C' => '慍',
  '�D' => '慏',
  '�E' => '慐',
  '�F' => '慒',
  '�G' => '慓',
  '�H' => '慔',
  '�I' => '慖',
  '�J' => '慗',
  '�K' => '慘',
  '�L' => '慙',
  '�M' => '慚',
  '�N' => '慛',
  '�O' => '慜',
  '�P' => '慞',
  '�Q' => '慟',
  '�R' => '慠',
  '�S' => '慡',
  '�T' => '慣',
  '�U' => '慤',
  '�V' => '慥',
  '�W' => '慦',
  '�X' => '慩',
  '�Y' => '慪',
  '�Z' => '慫',
  '�[' => '慬',
  '�\\' => '慭',
  '�]' => '慮',
  '�^' => '慯',
  '�_' => '慱',
  '�`' => '慲',
  '�a' => '慳',
  '�b' => '慴',
  '�c' => '慶',
  '�d' => '慸',
  '�e' => '慹',
  '�f' => '慺',
  '�g' => '慻',
  '�h' => '慼',
  '�i' => '慽',
  '�j' => '慾',
  '�k' => '慿',
  '�l' => '憀',
  '�m' => '憁',
  '�n' => '憂',
  '�o' => '憃',
  '�p' => '憄',
  '�q' => '憅',
  '�r' => '憆',
  '�s' => '憇',
  '�t' => '憈',
  '�u' => '憉',
  '�v' => '憊',
  '�w' => '憌',
  '�x' => '憍',
  '�y' => '憏',
  '�z' => '憐',
  '�{' => '憑',
  '�|' => '憒',
  '�}' => '憓',
  '�~' => '憕',
  '��' => '憖',
  '��' => '憗',
  '��' => '憘',
  '��' => '憙',
  '��' => '憚',
  '��' => '憛',
  '��' => '憜',
  '��' => '憞',
  '��' => '憟',
  '��' => '憠',
  '��' => '憡',
  '��' => '憢',
  '��' => '憣',
  '��' => '憤',
  '��' => '憥',
  '��' => '憦',
  '��' => '憪',
  '��' => '憫',
  '��' => '憭',
  '��' => '憮',
  '��' => '憯',
  '��' => '憰',
  '��' => '憱',
  '��' => '憲',
  '��' => '憳',
  '��' => '憴',
  '��' => '憵',
  '��' => '憶',
  '��' => '憸',
  '��' => '憹',
  '��' => '憺',
  '��' => '憻',
  '��' => '憼',
  '��' => '憽',
  '��' => '憿',
  '��' => '懀',
  '��' => '懁',
  '��' => '懃',
  '��' => '懄',
  '��' => '懅',
  '��' => '懆',
  '��' => '懇',
  '��' => '應',
  '��' => '懌',
  '��' => '懍',
  '��' => '懎',
  '��' => '懏',
  '��' => '懐',
  '��' => '懓',
  '��' => '懕',
  '��' => '懖',
  '��' => '懗',
  '��' => '懘',
  '��' => '懙',
  '��' => '懚',
  '��' => '懛',
  '��' => '懜',
  '��' => '懝',
  '��' => '懞',
  '��' => '懟',
  '��' => '懠',
  '��' => '懡',
  '��' => '懢',
  '��' => '懣',
  '��' => '懤',
  '��' => '懥',
  '��' => '懧',
  '��' => '懨',
  '��' => '懩',
  '��' => '懪',
  '��' => '懫',
  '��' => '懬',
  '��' => '懭',
  '��' => '懮',
  '��' => '懯',
  '��' => '懰',
  '��' => '懱',
  '��' => '懲',
  '��' => '懳',
  '��' => '懴',
  '��' => '懶',
  '��' => '懷',
  '��' => '懸',
  '��' => '懹',
  '��' => '懺',
  '��' => '懻',
  '��' => '懼',
  '��' => '懽',
  '��' => '懾',
  '��' => '戀',
  '��' => '戁',
  '��' => '戂',
  '��' => '戃',
  '��' => '戄',
  '��' => '戅',
  '��' => '戇',
  '��' => '戉',
  '��' => '戓',
  '��' => '戔',
  '��' => '戙',
  '��' => '戜',
  '��' => '戝',
  '��' => '戞',
  '��' => '戠',
  '��' => '戣',
  '��' => '戦',
  '��' => '戧',
  '��' => '戨',
  '��' => '戩',
  '��' => '戫',
  '��' => '戭',
  '��' => '戯',
  '��' => '戰',
  '��' => '戱',
  '��' => '戲',
  '��' => '戵',
  '��' => '戶',
  '��' => '戸',
  '��' => '戹',
  '��' => '戺',
  '��' => '戻',
  '��' => '戼',
  '��' => '扂',
  '��' => '扄',
  '��' => '扅',
  '��' => '扆',
  '��' => '扊',
  '�@' => '扏',
  '�A' => '扐',
  '�B' => '払',
  '�C' => '扖',
  '�D' => '扗',
  '�E' => '扙',
  '�F' => '扚',
  '�G' => '扜',
  '�H' => '扝',
  '�I' => '扞',
  '�J' => '扟',
  '�K' => '扠',
  '�L' => '扡',
  '�M' => '扢',
  '�N' => '扤',
  '�O' => '扥',
  '�P' => '扨',
  '�Q' => '扱',
  '�R' => '扲',
  '�S' => '扴',
  '�T' => '扵',
  '�U' => '扷',
  '�V' => '扸',
  '�W' => '扺',
  '�X' => '扻',
  '�Y' => '扽',
  '�Z' => '抁',
  '�[' => '抂',
  '�\\' => '抃',
  '�]' => '抅',
  '�^' => '抆',
  '�_' => '抇',
  '�`' => '抈',
  '�a' => '抋',
  '�b' => '抌',
  '�c' => '抍',
  '�d' => '抎',
  '�e' => '抏',
  '�f' => '抐',
  '�g' => '抔',
  '�h' => '抙',
  '�i' => '抜',
  '�j' => '抝',
  '�k' => '択',
  '�l' => '抣',
  '�m' => '抦',
  '�n' => '抧',
  '�o' => '抩',
  '�p' => '抪',
  '�q' => '抭',
  '�r' => '抮',
  '�s' => '抯',
  '�t' => '抰',
  '�u' => '抲',
  '�v' => '抳',
  '�w' => '抴',
  '�x' => '抶',
  '�y' => '抷',
  '�z' => '抸',
  '�{' => '抺',
  '�|' => '抾',
  '�}' => '拀',
  '�~' => '拁',
  '��' => '拃',
  '��' => '拋',
  '��' => '拏',
  '��' => '拑',
  '��' => '拕',
  '��' => '拝',
  '��' => '拞',
  '��' => '拠',
  '��' => '拡',
  '��' => '拤',
  '��' => '拪',
  '��' => '拫',
  '��' => '拰',
  '��' => '拲',
  '��' => '拵',
  '��' => '拸',
  '��' => '拹',
  '��' => '拺',
  '��' => '拻',
  '��' => '挀',
  '��' => '挃',
  '��' => '挄',
  '��' => '挅',
  '��' => '挆',
  '��' => '挊',
  '��' => '挋',
  '��' => '挌',
  '��' => '挍',
  '��' => '挏',
  '��' => '挐',
  '��' => '挒',
  '��' => '挓',
  '��' => '挔',
  '��' => '挕',
  '��' => '挗',
  '��' => '挘',
  '��' => '挙',
  '��' => '挜',
  '��' => '挦',
  '��' => '挧',
  '��' => '挩',
  '��' => '挬',
  '��' => '挭',
  '��' => '挮',
  '��' => '挰',
  '��' => '挱',
  '��' => '挳',
  '��' => '挴',
  '��' => '挵',
  '��' => '挶',
  '��' => '挷',
  '��' => '挸',
  '��' => '挻',
  '��' => '挼',
  '��' => '挾',
  '��' => '挿',
  '��' => '捀',
  '��' => '捁',
  '��' => '捄',
  '��' => '捇',
  '��' => '捈',
  '��' => '捊',
  '��' => '捑',
  '��' => '捒',
  '��' => '捓',
  '��' => '捔',
  '��' => '捖',
  '��' => '捗',
  '��' => '捘',
  '��' => '捙',
  '��' => '捚',
  '��' => '捛',
  '��' => '捜',
  '��' => '捝',
  '��' => '捠',
  '��' => '捤',
  '��' => '捥',
  '��' => '捦',
  '��' => '捨',
  '��' => '捪',
  '��' => '捫',
  '��' => '捬',
  '��' => '捯',
  '��' => '捰',
  '��' => '捲',
  '��' => '捳',
  '��' => '捴',
  '��' => '捵',
  '��' => '捸',
  '��' => '捹',
  '��' => '捼',
  '��' => '捽',
  '��' => '捾',
  '��' => '捿',
  '��' => '掁',
  '��' => '掃',
  '��' => '掄',
  '��' => '掅',
  '��' => '掆',
  '��' => '掋',
  '��' => '掍',
  '��' => '掑',
  '��' => '掓',
  '��' => '掔',
  '��' => '掕',
  '��' => '掗',
  '��' => '掙',
  '��' => '掚',
  '��' => '掛',
  '��' => '掜',
  '��' => '掝',
  '��' => '掞',
  '��' => '掟',
  '��' => '採',
  '��' => '掤',
  '��' => '掦',
  '��' => '掫',
  '��' => '掯',
  '��' => '掱',
  '��' => '掲',
  '��' => '掵',
  '��' => '掶',
  '��' => '掹',
  '��' => '掻',
  '��' => '掽',
  '��' => '掿',
  '��' => '揀',
  '�@' => '揁',
  '�A' => '揂',
  '�B' => '揃',
  '�C' => '揅',
  '�D' => '揇',
  '�E' => '揈',
  '�F' => '揊',
  '�G' => '揋',
  '�H' => '揌',
  '�I' => '揑',
  '�J' => '揓',
  '�K' => '揔',
  '�L' => '揕',
  '�M' => '揗',
  '�N' => '揘',
  '�O' => '揙',
  '�P' => '揚',
  '�Q' => '換',
  '�R' => '揜',
  '�S' => '揝',
  '�T' => '揟',
  '�U' => '揢',
  '�V' => '揤',
  '�W' => '揥',
  '�X' => '揦',
  '�Y' => '揧',
  '�Z' => '揨',
  '�[' => '揫',
  '�\\' => '揬',
  '�]' => '揮',
  '�^' => '揯',
  '�_' => '揰',
  '�`' => '揱',
  '�a' => '揳',
  '�b' => '揵',
  '�c' => '揷',
  '�d' => '揹',
  '�e' => '揺',
  '�f' => '揻',
  '�g' => '揼',
  '�h' => '揾',
  '�i' => '搃',
  '�j' => '搄',
  '�k' => '搆',
  '�l' => '搇',
  '�m' => '搈',
  '�n' => '搉',
  '�o' => '搊',
  '�p' => '損',
  '�q' => '搎',
  '�r' => '搑',
  '�s' => '搒',
  '�t' => '搕',
  '�u' => '搖',
  '�v' => '搗',
  '�w' => '搘',
  '�x' => '搙',
  '�y' => '搚',
  '�z' => '搝',
  '�{' => '搟',
  '�|' => '搢',
  '�}' => '搣',
  '�~' => '搤',
  '��' => '搥',
  '��' => '搧',
  '��' => '搨',
  '��' => '搩',
  '��' => '搫',
  '��' => '搮',
  '��' => '搯',
  '��' => '搰',
  '��' => '搱',
  '��' => '搲',
  '��' => '搳',
  '��' => '搵',
  '��' => '搶',
  '��' => '搷',
  '��' => '搸',
  '��' => '搹',
  '��' => '搻',
  '��' => '搼',
  '��' => '搾',
  '��' => '摀',
  '��' => '摂',
  '��' => '摃',
  '��' => '摉',
  '��' => '摋',
  '��' => '摌',
  '��' => '摍',
  '��' => '摎',
  '��' => '摏',
  '��' => '摐',
  '��' => '摑',
  '��' => '摓',
  '��' => '摕',
  '��' => '摖',
  '��' => '摗',
  '��' => '摙',
  '��' => '摚',
  '��' => '摛',
  '��' => '摜',
  '��' => '摝',
  '��' => '摟',
  '��' => '摠',
  '��' => '摡',
  '��' => '摢',
  '��' => '摣',
  '��' => '摤',
  '��' => '摥',
  '��' => '摦',
  '��' => '摨',
  '��' => '摪',
  '��' => '摫',
  '��' => '摬',
  '��' => '摮',
  '��' => '摯',
  '��' => '摰',
  '��' => '摱',
  '��' => '摲',
  '��' => '摳',
  '��' => '摴',
  '��' => '摵',
  '��' => '摶',
  '��' => '摷',
  '��' => '摻',
  '��' => '摼',
  '��' => '摽',
  '��' => '摾',
  '��' => '摿',
  '��' => '撀',
  '��' => '撁',
  '��' => '撃',
  '��' => '撆',
  '��' => '撈',
  '��' => '撉',
  '��' => '撊',
  '��' => '撋',
  '��' => '撌',
  '��' => '撍',
  '��' => '撎',
  '��' => '撏',
  '��' => '撐',
  '��' => '撓',
  '��' => '撔',
  '��' => '撗',
  '��' => '撘',
  '��' => '撚',
  '��' => '撛',
  '��' => '撜',
  '��' => '撝',
  '��' => '撟',
  '��' => '撠',
  '��' => '撡',
  '��' => '撢',
  '��' => '撣',
  '��' => '撥',
  '��' => '撦',
  '��' => '撧',
  '��' => '撨',
  '��' => '撪',
  '��' => '撫',
  '��' => '撯',
  '��' => '撱',
  '��' => '撲',
  '��' => '撳',
  '��' => '撴',
  '��' => '撶',
  '��' => '撹',
  '��' => '撻',
  '��' => '撽',
  '��' => '撾',
  '��' => '撿',
  '��' => '擁',
  '��' => '擃',
  '��' => '擄',
  '��' => '擆',
  '��' => '擇',
  '��' => '擈',
  '��' => '擉',
  '��' => '擊',
  '��' => '擋',
  '��' => '擌',
  '��' => '擏',
  '��' => '擑',
  '��' => '擓',
  '��' => '擔',
  '��' => '擕',
  '��' => '擖',
  '��' => '擙',
  '��' => '據',
  '�@' => '擛',
  '�A' => '擜',
  '�B' => '擝',
  '�C' => '擟',
  '�D' => '擠',
  '�E' => '擡',
  '�F' => '擣',
  '�G' => '擥',
  '�H' => '擧',
  '�I' => '擨',
  '�J' => '擩',
  '�K' => '擪',
  '�L' => '擫',
  '�M' => '擬',
  '�N' => '擭',
  '�O' => '擮',
  '�P' => '擯',
  '�Q' => '擰',
  '�R' => '擱',
  '�S' => '擲',
  '�T' => '擳',
  '�U' => '擴',
  '�V' => '擵',
  '�W' => '擶',
  '�X' => '擷',
  '�Y' => '擸',
  '�Z' => '擹',
  '�[' => '擺',
  '�\\' => '擻',
  '�]' => '擼',
  '�^' => '擽',
  '�_' => '擾',
  '�`' => '擿',
  '�a' => '攁',
  '�b' => '攂',
  '�c' => '攃',
  '�d' => '攄',
  '�e' => '攅',
  '�f' => '攆',
  '�g' => '攇',
  '�h' => '攈',
  '�i' => '攊',
  '�j' => '攋',
  '�k' => '攌',
  '�l' => '攍',
  '�m' => '攎',
  '�n' => '攏',
  '�o' => '攐',
  '�p' => '攑',
  '�q' => '攓',
  '�r' => '攔',
  '�s' => '攕',
  '�t' => '攖',
  '�u' => '攗',
  '�v' => '攙',
  '�w' => '攚',
  '�x' => '攛',
  '�y' => '攜',
  '�z' => '攝',
  '�{' => '攞',
  '�|' => '攟',
  '�}' => '攠',
  '�~' => '攡',
  '��' => '攢',
  '��' => '攣',
  '��' => '攤',
  '��' => '攦',
  '��' => '攧',
  '��' => '攨',
  '��' => '攩',
  '��' => '攪',
  '��' => '攬',
  '��' => '攭',
  '��' => '攰',
  '��' => '攱',
  '��' => '攲',
  '��' => '攳',
  '��' => '攷',
  '��' => '攺',
  '��' => '攼',
  '��' => '攽',
  '��' => '敀',
  '��' => '敁',
  '��' => '敂',
  '��' => '敃',
  '��' => '敄',
  '��' => '敆',
  '��' => '敇',
  '��' => '敊',
  '��' => '敋',
  '��' => '敍',
  '��' => '敎',
  '��' => '敐',
  '��' => '敒',
  '��' => '敓',
  '��' => '敔',
  '��' => '敗',
  '��' => '敘',
  '��' => '敚',
  '��' => '敜',
  '��' => '敟',
  '��' => '敠',
  '��' => '敡',
  '��' => '敤',
  '��' => '敥',
  '��' => '敧',
  '��' => '敨',
  '��' => '敩',
  '��' => '敪',
  '��' => '敭',
  '��' => '敮',
  '��' => '敯',
  '��' => '敱',
  '��' => '敳',
  '��' => '敵',
  '��' => '敶',
  '��' => '數',
  '��' => '敹',
  '��' => '敺',
  '��' => '敻',
  '��' => '敼',
  '��' => '敽',
  '��' => '敾',
  '��' => '敿',
  '��' => '斀',
  '��' => '斁',
  '��' => '斂',
  '��' => '斃',
  '��' => '斄',
  '��' => '斅',
  '��' => '斆',
  '��' => '斈',
  '��' => '斉',
  '��' => '斊',
  '��' => '斍',
  '��' => '斎',
  '��' => '斏',
  '��' => '斒',
  '��' => '斔',
  '��' => '斕',
  '��' => '斖',
  '��' => '斘',
  '��' => '斚',
  '��' => '斝',
  '��' => '斞',
  '��' => '斠',
  '��' => '斢',
  '��' => '斣',
  '��' => '斦',
  '��' => '斨',
  '��' => '斪',
  '��' => '斬',
  '��' => '斮',
  '��' => '斱',
  '��' => '斲',
  '��' => '斳',
  '��' => '斴',
  '��' => '斵',
  '��' => '斶',
  '��' => '斷',
  '��' => '斸',
  '��' => '斺',
  '��' => '斻',
  '��' => '斾',
  '��' => '斿',
  '��' => '旀',
  '��' => '旂',
  '��' => '旇',
  '��' => '旈',
  '��' => '旉',
  '��' => '旊',
  '��' => '旍',
  '��' => '旐',
  '��' => '旑',
  '��' => '旓',
  '��' => '旔',
  '��' => '旕',
  '��' => '旘',
  '��' => '旙',
  '��' => '旚',
  '��' => '旛',
  '��' => '旜',
  '��' => '旝',
  '��' => '旞',
  '��' => '旟',
  '��' => '旡',
  '��' => '旣',
  '��' => '旤',
  '��' => '旪',
  '��' => '旫',
  '�@' => '旲',
  '�A' => '旳',
  '�B' => '旴',
  '�C' => '旵',
  '�D' => '旸',
  '�E' => '旹',
  '�F' => '旻',
  '�G' => '旼',
  '�H' => '旽',
  '�I' => '旾',
  '�J' => '旿',
  '�K' => '昁',
  '�L' => '昄',
  '�M' => '昅',
  '�N' => '昇',
  '�O' => '昈',
  '�P' => '昉',
  '�Q' => '昋',
  '�R' => '昍',
  '�S' => '昐',
  '�T' => '昑',
  '�U' => '昒',
  '�V' => '昖',
  '�W' => '昗',
  '�X' => '昘',
  '�Y' => '昚',
  '�Z' => '昛',
  '�[' => '昜',
  '�\\' => '昞',
  '�]' => '昡',
  '�^' => '昢',
  '�_' => '昣',
  '�`' => '昤',
  '�a' => '昦',
  '�b' => '昩',
  '�c' => '昪',
  '�d' => '昫',
  '�e' => '昬',
  '�f' => '昮',
  '�g' => '昰',
  '�h' => '昲',
  '�i' => '昳',
  '�j' => '昷',
  '�k' => '昸',
  '�l' => '昹',
  '�m' => '昺',
  '�n' => '昻',
  '�o' => '昽',
  '�p' => '昿',
  '�q' => '晀',
  '�r' => '時',
  '�s' => '晄',
  '�t' => '晅',
  '�u' => '晆',
  '�v' => '晇',
  '�w' => '晈',
  '�x' => '晉',
  '�y' => '晊',
  '�z' => '晍',
  '�{' => '晎',
  '�|' => '晐',
  '�}' => '晑',
  '�~' => '晘',
  '��' => '晙',
  '��' => '晛',
  '��' => '晜',
  '��' => '晝',
  '��' => '晞',
  '��' => '晠',
  '��' => '晢',
  '��' => '晣',
  '��' => '晥',
  '��' => '晧',
  '��' => '晩',
  '��' => '晪',
  '��' => '晫',
  '��' => '晬',
  '��' => '晭',
  '��' => '晱',
  '��' => '晲',
  '��' => '晳',
  '��' => '晵',
  '��' => '晸',
  '��' => '晹',
  '��' => '晻',
  '��' => '晼',
  '��' => '晽',
  '��' => '晿',
  '��' => '暀',
  '��' => '暁',
  '��' => '暃',
  '��' => '暅',
  '��' => '暆',
  '��' => '暈',
  '��' => '暉',
  '��' => '暊',
  '��' => '暋',
  '��' => '暍',
  '��' => '暎',
  '��' => '暏',
  '��' => '暐',
  '��' => '暒',
  '��' => '暓',
  '��' => '暔',
  '��' => '暕',
  '��' => '暘',
  '��' => '暙',
  '��' => '暚',
  '��' => '暛',
  '��' => '暜',
  '��' => '暞',
  '��' => '暟',
  '��' => '暠',
  '��' => '暡',
  '��' => '暢',
  '��' => '暣',
  '��' => '暤',
  '��' => '暥',
  '��' => '暦',
  '��' => '暩',
  '��' => '暪',
  '��' => '暫',
  '��' => '暬',
  '��' => '暭',
  '��' => '暯',
  '��' => '暰',
  '��' => '暱',
  '��' => '暲',
  '��' => '暳',
  '��' => '暵',
  '��' => '暶',
  '��' => '暷',
  '��' => '暸',
  '��' => '暺',
  '��' => '暻',
  '��' => '暼',
  '��' => '暽',
  '��' => '暿',
  '��' => '曀',
  '��' => '曁',
  '��' => '曂',
  '��' => '曃',
  '��' => '曄',
  '��' => '曅',
  '��' => '曆',
  '��' => '曇',
  '��' => '曈',
  '��' => '曉',
  '��' => '曊',
  '��' => '曋',
  '��' => '曌',
  '��' => '曍',
  '��' => '曎',
  '��' => '曏',
  '��' => '曐',
  '��' => '曑',
  '��' => '曒',
  '��' => '曓',
  '��' => '曔',
  '��' => '曕',
  '��' => '曖',
  '��' => '曗',
  '��' => '曘',
  '��' => '曚',
  '��' => '曞',
  '��' => '曟',
  '��' => '曠',
  '��' => '曡',
  '��' => '曢',
  '��' => '曣',
  '��' => '曤',
  '��' => '曥',
  '��' => '曧',
  '��' => '曨',
  '��' => '曪',
  '��' => '曫',
  '��' => '曬',
  '��' => '曭',
  '��' => '曮',
  '��' => '曯',
  '��' => '曱',
  '��' => '曵',
  '��' => '曶',
  '��' => '書',
  '��' => '曺',
  '��' => '曻',
  '��' => '曽',
  '��' => '朁',
  '��' => '朂',
  '��' => '會',
  '�@' => '朄',
  '�A' => '朅',
  '�B' => '朆',
  '�C' => '朇',
  '�D' => '朌',
  '�E' => '朎',
  '�F' => '朏',
  '�G' => '朑',
  '�H' => '朒',
  '�I' => '朓',
  '�J' => '朖',
  '�K' => '朘',
  '�L' => '朙',
  '�M' => '朚',
  '�N' => '朜',
  '�O' => '朞',
  '�P' => '朠',
  '�Q' => '朡',
  '�R' => '朢',
  '�S' => '朣',
  '�T' => '朤',
  '�U' => '朥',
  '�V' => '朧',
  '�W' => '朩',
  '�X' => '朮',
  '�Y' => '朰',
  '�Z' => '朲',
  '�[' => '朳',
  '�\\' => '朶',
  '�]' => '朷',
  '�^' => '朸',
  '�_' => '朹',
  '�`' => '朻',
  '�a' => '朼',
  '�b' => '朾',
  '�c' => '朿',
  '�d' => '杁',
  '�e' => '杄',
  '�f' => '杅',
  '�g' => '杇',
  '�h' => '杊',
  '�i' => '杋',
  '�j' => '杍',
  '�k' => '杒',
  '�l' => '杔',
  '�m' => '杕',
  '�n' => '杗',
  '�o' => '杘',
  '�p' => '杙',
  '�q' => '杚',
  '�r' => '杛',
  '�s' => '杝',
  '�t' => '杢',
  '�u' => '杣',
  '�v' => '杤',
  '�w' => '杦',
  '�x' => '杧',
  '�y' => '杫',
  '�z' => '杬',
  '�{' => '杮',
  '�|' => '東',
  '�}' => '杴',
  '�~' => '杶',
  '��' => '杸',
  '��' => '杹',
  '��' => '杺',
  '��' => '杻',
  '��' => '杽',
  '��' => '枀',
  '��' => '枂',
  '��' => '枃',
  '��' => '枅',
  '��' => '枆',
  '��' => '枈',
  '��' => '枊',
  '��' => '枌',
  '��' => '枍',
  '��' => '枎',
  '��' => '枏',
  '��' => '枑',
  '��' => '枒',
  '��' => '枓',
  '��' => '枔',
  '��' => '枖',
  '��' => '枙',
  '��' => '枛',
  '��' => '枟',
  '��' => '枠',
  '��' => '枡',
  '��' => '枤',
  '��' => '枦',
  '��' => '枩',
  '��' => '枬',
  '��' => '枮',
  '��' => '枱',
  '��' => '枲',
  '��' => '枴',
  '��' => '枹',
  '��' => '枺',
  '��' => '枻',
  '��' => '枼',
  '��' => '枽',
  '��' => '枾',
  '��' => '枿',
  '��' => '柀',
  '��' => '柂',
  '��' => '柅',
  '��' => '柆',
  '��' => '柇',
  '��' => '柈',
  '��' => '柉',
  '��' => '柊',
  '��' => '柋',
  '��' => '柌',
  '��' => '柍',
  '��' => '柎',
  '��' => '柕',
  '��' => '柖',
  '��' => '柗',
  '��' => '柛',
  '��' => '柟',
  '��' => '柡',
  '��' => '柣',
  '��' => '柤',
  '��' => '柦',
  '��' => '柧',
  '��' => '柨',
  '��' => '柪',
  '��' => '柫',
  '��' => '柭',
  '��' => '柮',
  '��' => '柲',
  '��' => '柵',
  '��' => '柶',
  '��' => '柷',
  '��' => '柸',
  '��' => '柹',
  '��' => '柺',
  '��' => '査',
  '��' => '柼',
  '��' => '柾',
  '��' => '栁',
  '��' => '栂',
  '��' => '栃',
  '��' => '栄',
  '��' => '栆',
  '��' => '栍',
  '��' => '栐',
  '��' => '栒',
  '��' => '栔',
  '��' => '栕',
  '��' => '栘',
  '��' => '栙',
  '��' => '栚',
  '��' => '栛',
  '��' => '栜',
  '��' => '栞',
  '��' => '栟',
  '��' => '栠',
  '��' => '栢',
  '��' => '栣',
  '��' => '栤',
  '��' => '栥',
  '��' => '栦',
  '��' => '栧',
  '��' => '栨',
  '��' => '栫',
  '��' => '栬',
  '��' => '栭',
  '��' => '栮',
  '��' => '栯',
  '��' => '栰',
  '��' => '栱',
  '��' => '栴',
  '��' => '栵',
  '��' => '栶',
  '��' => '栺',
  '��' => '栻',
  '��' => '栿',
  '��' => '桇',
  '��' => '桋',
  '��' => '桍',
  '��' => '桏',
  '��' => '桒',
  '��' => '桖',
  '��' => '桗',
  '��' => '桘',
  '��' => '桙',
  '��' => '桚',
  '��' => '桛',
  '�@' => '桜',
  '�A' => '桝',
  '�B' => '桞',
  '�C' => '桟',
  '�D' => '桪',
  '�E' => '桬',
  '�F' => '桭',
  '�G' => '桮',
  '�H' => '桯',
  '�I' => '桰',
  '�J' => '桱',
  '�K' => '桲',
  '�L' => '桳',
  '�M' => '桵',
  '�N' => '桸',
  '�O' => '桹',
  '�P' => '桺',
  '�Q' => '桻',
  '�R' => '桼',
  '�S' => '桽',
  '�T' => '桾',
  '�U' => '桿',
  '�V' => '梀',
  '�W' => '梂',
  '�X' => '梄',
  '�Y' => '梇',
  '�Z' => '梈',
  '�[' => '梉',
  '�\\' => '梊',
  '�]' => '梋',
  '�^' => '梌',
  '�_' => '梍',
  '�`' => '梎',
  '�a' => '梐',
  '�b' => '梑',
  '�c' => '梒',
  '�d' => '梔',
  '�e' => '梕',
  '�f' => '梖',
  '�g' => '梘',
  '�h' => '梙',
  '�i' => '梚',
  '�j' => '梛',
  '�k' => '梜',
  '�l' => '條',
  '�m' => '梞',
  '�n' => '梟',
  '�o' => '梠',
  '�p' => '梡',
  '�q' => '梣',
  '�r' => '梤',
  '�s' => '梥',
  '�t' => '梩',
  '�u' => '梪',
  '�v' => '梫',
  '�w' => '梬',
  '�x' => '梮',
  '�y' => '梱',
  '�z' => '梲',
  '�{' => '梴',
  '�|' => '梶',
  '�}' => '梷',
  '�~' => '梸',
  '��' => '梹',
  '��' => '梺',
  '��' => '梻',
  '��' => '梼',
  '��' => '梽',
  '��' => '梾',
  '��' => '梿',
  '��' => '棁',
  '��' => '棃',
  '��' => '棄',
  '��' => '棅',
  '��' => '棆',
  '��' => '棇',
  '��' => '棈',
  '��' => '棊',
  '��' => '棌',
  '��' => '棎',
  '��' => '棏',
  '��' => '棐',
  '��' => '棑',
  '��' => '棓',
  '��' => '棔',
  '��' => '棖',
  '��' => '棗',
  '��' => '棙',
  '��' => '棛',
  '��' => '棜',
  '��' => '棝',
  '��' => '棞',
  '��' => '棟',
  '��' => '棡',
  '��' => '棢',
  '��' => '棤',
  '��' => '棥',
  '��' => '棦',
  '��' => '棧',
  '��' => '棨',
  '��' => '棩',
  '��' => '棪',
  '��' => '棫',
  '��' => '棬',
  '��' => '棭',
  '��' => '棯',
  '��' => '棲',
  '��' => '棳',
  '��' => '棴',
  '��' => '棶',
  '��' => '棷',
  '��' => '棸',
  '��' => '棻',
  '��' => '棽',
  '��' => '棾',
  '��' => '棿',
  '��' => '椀',
  '��' => '椂',
  '��' => '椃',
  '��' => '椄',
  '��' => '椆',
  '��' => '椇',
  '��' => '椈',
  '��' => '椉',
  '��' => '椊',
  '��' => '椌',
  '��' => '椏',
  '��' => '椑',
  '��' => '椓',
  '��' => '椔',
  '��' => '椕',
  '��' => '椖',
  '��' => '椗',
  '��' => '椘',
  '��' => '椙',
  '��' => '椚',
  '��' => '椛',
  '��' => '検',
  '��' => '椝',
  '��' => '椞',
  '��' => '椡',
  '��' => '椢',
  '��' => '椣',
  '��' => '椥',
  '��' => '椦',
  '��' => '椧',
  '��' => '椨',
  '��' => '椩',
  '��' => '椪',
  '��' => '椫',
  '��' => '椬',
  '��' => '椮',
  '��' => '椯',
  '��' => '椱',
  '��' => '椲',
  '��' => '椳',
  '��' => '椵',
  '��' => '椶',
  '��' => '椷',
  '��' => '椸',
  '��' => '椺',
  '��' => '椻',
  '��' => '椼',
  '��' => '椾',
  '��' => '楀',
  '��' => '楁',
  '��' => '楃',
  '��' => '楄',
  '��' => '楅',
  '��' => '楆',
  '��' => '楇',
  '��' => '楈',
  '��' => '楉',
  '��' => '楊',
  '��' => '楋',
  '��' => '楌',
  '��' => '楍',
  '��' => '楎',
  '��' => '楏',
  '��' => '楐',
  '��' => '楑',
  '��' => '楒',
  '��' => '楓',
  '��' => '楕',
  '��' => '楖',
  '��' => '楘',
  '��' => '楙',
  '��' => '楛',
  '��' => '楜',
  '��' => '楟',
  '�@' => '楡',
  '�A' => '楢',
  '�B' => '楤',
  '�C' => '楥',
  '�D' => '楧',
  '�E' => '楨',
  '�F' => '楩',
  '�G' => '楪',
  '�H' => '楬',
  '�I' => '業',
  '�J' => '楯',
  '�K' => '楰',
  '�L' => '楲',
  '�M' => '楳',
  '�N' => '楴',
  '�O' => '極',
  '�P' => '楶',
  '�Q' => '楺',
  '�R' => '楻',
  '�S' => '楽',
  '�T' => '楾',
  '�U' => '楿',
  '�V' => '榁',
  '�W' => '榃',
  '�X' => '榅',
  '�Y' => '榊',
  '�Z' => '榋',
  '�[' => '榌',
  '�\\' => '榎',
  '�]' => '榏',
  '�^' => '榐',
  '�_' => '榑',
  '�`' => '榒',
  '�a' => '榓',
  '�b' => '榖',
  '�c' => '榗',
  '�d' => '榙',
  '�e' => '榚',
  '�f' => '榝',
  '�g' => '榞',
  '�h' => '榟',
  '�i' => '榠',
  '�j' => '榡',
  '�k' => '榢',
  '�l' => '榣',
  '�m' => '榤',
  '�n' => '榥',
  '�o' => '榦',
  '�p' => '榩',
  '�q' => '榪',
  '�r' => '榬',
  '�s' => '榮',
  '�t' => '榯',
  '�u' => '榰',
  '�v' => '榲',
  '�w' => '榳',
  '�x' => '榵',
  '�y' => '榶',
  '�z' => '榸',
  '�{' => '榹',
  '�|' => '榺',
  '�}' => '榼',
  '�~' => '榽',
  '��' => '榾',
  '��' => '榿',
  '��' => '槀',
  '��' => '槂',
  '��' => '槃',
  '��' => '槄',
  '��' => '槅',
  '��' => '槆',
  '��' => '槇',
  '��' => '槈',
  '��' => '槉',
  '��' => '構',
  '��' => '槍',
  '��' => '槏',
  '��' => '槑',
  '��' => '槒',
  '��' => '槓',
  '��' => '槕',
  '��' => '槖',
  '��' => '槗',
  '��' => '様',
  '��' => '槙',
  '��' => '槚',
  '��' => '槜',
  '��' => '槝',
  '��' => '槞',
  '��' => '槡',
  '��' => '槢',
  '��' => '槣',
  '��' => '槤',
  '��' => '槥',
  '��' => '槦',
  '��' => '槧',
  '��' => '槨',
  '��' => '槩',
  '��' => '槪',
  '��' => '槫',
  '��' => '槬',
  '��' => '槮',
  '��' => '槯',
  '��' => '槰',
  '��' => '槱',
  '��' => '槳',
  '��' => '槴',
  '��' => '槵',
  '��' => '槶',
  '��' => '槷',
  '��' => '槸',
  '��' => '槹',
  '��' => '槺',
  '��' => '槻',
  '��' => '槼',
  '��' => '槾',
  '��' => '樀',
  '��' => '樁',
  '��' => '樂',
  '��' => '樃',
  '��' => '樄',
  '��' => '樅',
  '��' => '樆',
  '��' => '樇',
  '��' => '樈',
  '��' => '樉',
  '��' => '樋',
  '��' => '樌',
  '��' => '樍',
  '��' => '樎',
  '��' => '樏',
  '��' => '樐',
  '��' => '樑',
  '��' => '樒',
  '��' => '樓',
  '��' => '樔',
  '��' => '樕',
  '��' => '樖',
  '��' => '標',
  '��' => '樚',
  '��' => '樛',
  '��' => '樜',
  '��' => '樝',
  '��' => '樞',
  '��' => '樠',
  '��' => '樢',
  '��' => '樣',
  '��' => '樤',
  '��' => '樥',
  '��' => '樦',
  '��' => '樧',
  '��' => '権',
  '��' => '樫',
  '��' => '樬',
  '��' => '樭',
  '��' => '樮',
  '��' => '樰',
  '��' => '樲',
  '��' => '樳',
  '��' => '樴',
  '��' => '樶',
  '��' => '樷',
  '��' => '樸',
  '��' => '樹',
  '��' => '樺',
  '��' => '樻',
  '��' => '樼',
  '��' => '樿',
  '��' => '橀',
  '��' => '橁',
  '��' => '橂',
  '��' => '橃',
  '��' => '橅',
  '��' => '橆',
  '��' => '橈',
  '��' => '橉',
  '��' => '橊',
  '��' => '橋',
  '��' => '橌',
  '��' => '橍',
  '��' => '橎',
  '��' => '橏',
  '��' => '橑',
  '��' => '橒',
  '��' => '橓',
  '��' => '橔',
  '��' => '橕',
  '��' => '橖',
  '��' => '橗',
  '��' => '橚',
  '�@' => '橜',
  '�A' => '橝',
  '�B' => '橞',
  '�C' => '機',
  '�D' => '橠',
  '�E' => '橢',
  '�F' => '橣',
  '�G' => '橤',
  '�H' => '橦',
  '�I' => '橧',
  '�J' => '橨',
  '�K' => '橩',
  '�L' => '橪',
  '�M' => '橫',
  '�N' => '橬',
  '�O' => '橭',
  '�P' => '橮',
  '�Q' => '橯',
  '�R' => '橰',
  '�S' => '橲',
  '�T' => '橳',
  '�U' => '橴',
  '�V' => '橵',
  '�W' => '橶',
  '�X' => '橷',
  '�Y' => '橸',
  '�Z' => '橺',
  '�[' => '橻',
  '�\\' => '橽',
  '�]' => '橾',
  '�^' => '橿',
  '�_' => '檁',
  '�`' => '檂',
  '�a' => '檃',
  '�b' => '檅',
  '�c' => '檆',
  '�d' => '檇',
  '�e' => '檈',
  '�f' => '檉',
  '�g' => '檊',
  '�h' => '檋',
  '�i' => '檌',
  '�j' => '檍',
  '�k' => '檏',
  '�l' => '檒',
  '�m' => '檓',
  '�n' => '檔',
  '�o' => '檕',
  '�p' => '檖',
  '�q' => '檘',
  '�r' => '檙',
  '�s' => '檚',
  '�t' => '檛',
  '�u' => '檜',
  '�v' => '檝',
  '�w' => '檞',
  '�x' => '檟',
  '�y' => '檡',
  '�z' => '檢',
  '�{' => '檣',
  '�|' => '檤',
  '�}' => '檥',
  '�~' => '檦',
  '��' => '檧',
  '��' => '檨',
  '��' => '檪',
  '��' => '檭',
  '��' => '檮',
  '��' => '檯',
  '��' => '檰',
  '��' => '檱',
  '��' => '檲',
  '��' => '檳',
  '��' => '檴',
  '��' => '檵',
  '��' => '檶',
  '��' => '檷',
  '��' => '檸',
  '��' => '檹',
  '��' => '檺',
  '��' => '檻',
  '��' => '檼',
  '��' => '檽',
  '��' => '檾',
  '��' => '檿',
  '��' => '櫀',
  '��' => '櫁',
  '��' => '櫂',
  '��' => '櫃',
  '��' => '櫄',
  '��' => '櫅',
  '��' => '櫆',
  '��' => '櫇',
  '��' => '櫈',
  '��' => '櫉',
  '��' => '櫊',
  '��' => '櫋',
  '��' => '櫌',
  '��' => '櫍',
  '��' => '櫎',
  '��' => '櫏',
  '��' => '櫐',
  '��' => '櫑',
  '��' => '櫒',
  '��' => '櫓',
  '��' => '櫔',
  '��' => '櫕',
  '��' => '櫖',
  '��' => '櫗',
  '��' => '櫘',
  '��' => '櫙',
  '��' => '櫚',
  '��' => '櫛',
  '��' => '櫜',
  '��' => '櫝',
  '��' => '櫞',
  '��' => '櫟',
  '��' => '櫠',
  '��' => '櫡',
  '��' => '櫢',
  '��' => '櫣',
  '��' => '櫤',
  '��' => '櫥',
  '��' => '櫦',
  '��' => '櫧',
  '��' => '櫨',
  '��' => '櫩',
  '��' => '櫪',
  '��' => '櫫',
  '��' => '櫬',
  '��' => '櫭',
  '��' => '櫮',
  '��' => '櫯',
  '��' => '櫰',
  '��' => '櫱',
  '��' => '櫲',
  '��' => '櫳',
  '��' => '櫴',
  '��' => '櫵',
  '��' => '櫶',
  '��' => '櫷',
  '��' => '櫸',
  '��' => '櫹',
  '��' => '櫺',
  '��' => '櫻',
  '��' => '櫼',
  '��' => '櫽',
  '��' => '櫾',
  '��' => '櫿',
  '��' => '欀',
  '��' => '欁',
  '��' => '欂',
  '��' => '欃',
  '��' => '欄',
  '��' => '欅',
  '��' => '欆',
  '��' => '欇',
  '��' => '欈',
  '��' => '欉',
  '��' => '權',
  '��' => '欋',
  '��' => '欌',
  '��' => '欍',
  '��' => '欎',
  '��' => '欏',
  '��' => '欐',
  '��' => '欑',
  '��' => '欒',
  '��' => '欓',
  '��' => '欔',
  '��' => '欕',
  '��' => '欖',
  '��' => '欗',
  '��' => '欘',
  '��' => '欙',
  '��' => '欚',
  '��' => '欛',
  '��' => '欜',
  '��' => '欝',
  '��' => '欞',
  '��' => '欟',
  '��' => '欥',
  '��' => '欦',
  '��' => '欨',
  '��' => '欩',
  '��' => '欪',
  '��' => '欫',
  '��' => '欬',
  '��' => '欭',
  '��' => '欮',
  '�@' => '欯',
  '�A' => '欰',
  '�B' => '欱',
  '�C' => '欳',
  '�D' => '欴',
  '�E' => '欵',
  '�F' => '欶',
  '�G' => '欸',
  '�H' => '欻',
  '�I' => '欼',
  '�J' => '欽',
  '�K' => '欿',
  '�L' => '歀',
  '�M' => '歁',
  '�N' => '歂',
  '�O' => '歄',
  '�P' => '歅',
  '�Q' => '歈',
  '�R' => '歊',
  '�S' => '歋',
  '�T' => '歍',
  '�U' => '歎',
  '�V' => '歏',
  '�W' => '歐',
  '�X' => '歑',
  '�Y' => '歒',
  '�Z' => '歓',
  '�[' => '歔',
  '�\\' => '歕',
  '�]' => '歖',
  '�^' => '歗',
  '�_' => '歘',
  '�`' => '歚',
  '�a' => '歛',
  '�b' => '歜',
  '�c' => '歝',
  '�d' => '歞',
  '�e' => '歟',
  '�f' => '歠',
  '�g' => '歡',
  '�h' => '歨',
  '�i' => '歩',
  '�j' => '歫',
  '�k' => '歬',
  '�l' => '歭',
  '�m' => '歮',
  '�n' => '歯',
  '�o' => '歰',
  '�p' => '歱',
  '�q' => '歲',
  '�r' => '歳',
  '�s' => '歴',
  '�t' => '歵',
  '�u' => '歶',
  '�v' => '歷',
  '�w' => '歸',
  '�x' => '歺',
  '�y' => '歽',
  '�z' => '歾',
  '�{' => '歿',
  '�|' => '殀',
  '�}' => '殅',
  '�~' => '殈',
  '��' => '殌',
  '��' => '殎',
  '��' => '殏',
  '��' => '殐',
  '��' => '殑',
  '��' => '殔',
  '��' => '殕',
  '��' => '殗',
  '��' => '殘',
  '��' => '殙',
  '��' => '殜',
  '��' => '殝',
  '��' => '殞',
  '��' => '殟',
  '��' => '殠',
  '��' => '殢',
  '��' => '殣',
  '��' => '殤',
  '��' => '殥',
  '��' => '殦',
  '��' => '殧',
  '��' => '殨',
  '��' => '殩',
  '��' => '殫',
  '��' => '殬',
  '��' => '殭',
  '��' => '殮',
  '��' => '殯',
  '��' => '殰',
  '��' => '殱',
  '��' => '殲',
  '��' => '殶',
  '��' => '殸',
  '��' => '殹',
  '��' => '殺',
  '��' => '殻',
  '��' => '殼',
  '��' => '殽',
  '��' => '殾',
  '��' => '毀',
  '��' => '毃',
  '��' => '毄',
  '��' => '毆',
  '��' => '毇',
  '��' => '毈',
  '��' => '毉',
  '��' => '毊',
  '��' => '毌',
  '��' => '毎',
  '��' => '毐',
  '��' => '毑',
  '��' => '毘',
  '��' => '毚',
  '��' => '毜',
  '��' => '毝',
  '��' => '毞',
  '��' => '毟',
  '��' => '毠',
  '��' => '毢',
  '��' => '毣',
  '��' => '毤',
  '��' => '毥',
  '��' => '毦',
  '��' => '毧',
  '��' => '毨',
  '��' => '毩',
  '��' => '毬',
  '��' => '毭',
  '��' => '毮',
  '��' => '毰',
  '��' => '毱',
  '��' => '毲',
  '��' => '毴',
  '��' => '毶',
  '��' => '毷',
  '��' => '毸',
  '��' => '毺',
  '��' => '毻',
  '��' => '毼',
  '��' => '毾',
  '��' => '毿',
  '��' => '氀',
  '��' => '氁',
  '��' => '氂',
  '��' => '氃',
  '��' => '氄',
  '��' => '氈',
  '��' => '氉',
  '��' => '氊',
  '��' => '氋',
  '��' => '氌',
  '��' => '氎',
  '��' => '氒',
  '��' => '気',
  '��' => '氜',
  '��' => '氝',
  '��' => '氞',
  '��' => '氠',
  '��' => '氣',
  '��' => '氥',
  '��' => '氫',
  '��' => '氬',
  '��' => '氭',
  '��' => '氱',
  '��' => '氳',
  '��' => '氶',
  '��' => '氷',
  '��' => '氹',
  '��' => '氺',
  '��' => '氻',
  '��' => '氼',
  '��' => '氾',
  '��' => '氿',
  '��' => '汃',
  '��' => '汄',
  '��' => '汅',
  '��' => '汈',
  '��' => '汋',
  '��' => '汌',
  '��' => '汍',
  '��' => '汎',
  '��' => '汏',
  '��' => '汑',
  '��' => '汒',
  '��' => '汓',
  '��' => '汖',
  '��' => '汘',
  '�@' => '汙',
  '�A' => '汚',
  '�B' => '汢',
  '�C' => '汣',
  '�D' => '汥',
  '�E' => '汦',
  '�F' => '汧',
  '�G' => '汫',
  '�H' => '汬',
  '�I' => '汭',
  '�J' => '汮',
  '�K' => '汯',
  '�L' => '汱',
  '�M' => '汳',
  '�N' => '汵',
  '�O' => '汷',
  '�P' => '汸',
  '�Q' => '決',
  '�R' => '汻',
  '�S' => '汼',
  '�T' => '汿',
  '�U' => '沀',
  '�V' => '沄',
  '�W' => '沇',
  '�X' => '沊',
  '�Y' => '沋',
  '�Z' => '沍',
  '�[' => '沎',
  '�\\' => '沑',
  '�]' => '沒',
  '�^' => '沕',
  '�_' => '沖',
  '�`' => '沗',
  '�a' => '沘',
  '�b' => '沚',
  '�c' => '沜',
  '�d' => '沝',
  '�e' => '沞',
  '�f' => '沠',
  '�g' => '沢',
  '�h' => '沨',
  '�i' => '沬',
  '�j' => '沯',
  '�k' => '沰',
  '�l' => '沴',
  '�m' => '沵',
  '�n' => '沶',
  '�o' => '沷',
  '�p' => '沺',
  '�q' => '泀',
  '�r' => '況',
  '�s' => '泂',
  '�t' => '泃',
  '�u' => '泆',
  '�v' => '泇',
  '�w' => '泈',
  '�x' => '泋',
  '�y' => '泍',
  '�z' => '泎',
  '�{' => '泏',
  '�|' => '泑',
  '�}' => '泒',
  '�~' => '泘',
  '��' => '泙',
  '��' => '泚',
  '��' => '泜',
  '��' => '泝',
  '��' => '泟',
  '��' => '泤',
  '��' => '泦',
  '��' => '泧',
  '��' => '泩',
  '��' => '泬',
  '��' => '泭',
  '��' => '泲',
  '��' => '泴',
  '��' => '泹',
  '��' => '泿',
  '��' => '洀',
  '��' => '洂',
  '��' => '洃',
  '��' => '洅',
  '��' => '洆',
  '��' => '洈',
  '��' => '洉',
  '��' => '洊',
  '��' => '洍',
  '��' => '洏',
  '��' => '洐',
  '��' => '洑',
  '��' => '洓',
  '��' => '洔',
  '��' => '洕',
  '��' => '洖',
  '��' => '洘',
  '��' => '洜',
  '��' => '洝',
  '��' => '洟',
  '��' => '洠',
  '��' => '洡',
  '��' => '洢',
  '��' => '洣',
  '��' => '洤',
  '��' => '洦',
  '��' => '洨',
  '��' => '洩',
  '��' => '洬',
  '��' => '洭',
  '��' => '洯',
  '��' => '洰',
  '��' => '洴',
  '��' => '洶',
  '��' => '洷',
  '��' => '洸',
  '��' => '洺',
  '��' => '洿',
  '��' => '浀',
  '��' => '浂',
  '��' => '浄',
  '��' => '浉',
  '��' => '浌',
  '��' => '浐',
  '��' => '浕',
  '��' => '浖',
  '��' => '浗',
  '��' => '浘',
  '��' => '浛',
  '��' => '浝',
  '��' => '浟',
  '��' => '浡',
  '��' => '浢',
  '��' => '浤',
  '��' => '浥',
  '��' => '浧',
  '��' => '浨',
  '��' => '浫',
  '��' => '浬',
  '��' => '浭',
  '��' => '浰',
  '��' => '浱',
  '��' => '浲',
  '��' => '浳',
  '��' => '浵',
  '��' => '浶',
  '��' => '浹',
  '��' => '浺',
  '��' => '浻',
  '��' => '浽',
  '��' => '浾',
  '��' => '浿',
  '��' => '涀',
  '��' => '涁',
  '��' => '涃',
  '��' => '涄',
  '��' => '涆',
  '��' => '涇',
  '��' => '涊',
  '��' => '涋',
  '��' => '涍',
  '��' => '涏',
  '��' => '涐',
  '��' => '涒',
  '��' => '涖',
  '��' => '涗',
  '��' => '涘',
  '��' => '涙',
  '��' => '涚',
  '��' => '涜',
  '��' => '涢',
  '��' => '涥',
  '��' => '涬',
  '��' => '涭',
  '��' => '涰',
  '��' => '涱',
  '��' => '涳',
  '��' => '涴',
  '��' => '涶',
  '��' => '涷',
  '��' => '涹',
  '��' => '涺',
  '��' => '涻',
  '��' => '涼',
  '��' => '涽',
  '��' => '涾',
  '��' => '淁',
  '��' => '淂',
  '��' => '淃',
  '��' => '淈',
  '��' => '淉',
  '��' => '淊',
  '�@' => '淍',
  '�A' => '淎',
  '�B' => '淏',
  '�C' => '淐',
  '�D' => '淒',
  '�E' => '淓',
  '�F' => '淔',
  '�G' => '淕',
  '�H' => '淗',
  '�I' => '淚',
  '�J' => '淛',
  '�K' => '淜',
  '�L' => '淟',
  '�M' => '淢',
  '�N' => '淣',
  '�O' => '淥',
  '�P' => '淧',
  '�Q' => '淨',
  '�R' => '淩',
  '�S' => '淪',
  '�T' => '淭',
  '�U' => '淯',
  '�V' => '淰',
  '�W' => '淲',
  '�X' => '淴',
  '�Y' => '淵',
  '�Z' => '淶',
  '�[' => '淸',
  '�\\' => '淺',
  '�]' => '淽',
  '�^' => '淾',
  '�_' => '淿',
  '�`' => '渀',
  '�a' => '渁',
  '�b' => '渂',
  '�c' => '渃',
  '�d' => '渄',
  '�e' => '渆',
  '�f' => '渇',
  '�g' => '済',
  '�h' => '渉',
  '�i' => '渋',
  '�j' => '渏',
  '�k' => '渒',
  '�l' => '渓',
  '�m' => '渕',
  '�n' => '渘',
  '�o' => '渙',
  '�p' => '減',
  '�q' => '渜',
  '�r' => '渞',
  '�s' => '渟',
  '�t' => '渢',
  '�u' => '渦',
  '�v' => '渧',
  '�w' => '渨',
  '�x' => '渪',
  '�y' => '測',
  '�z' => '渮',
  '�{' => '渰',
  '�|' => '渱',
  '�}' => '渳',
  '�~' => '渵',
  '��' => '渶',
  '��' => '渷',
  '��' => '渹',
  '��' => '渻',
  '��' => '渼',
  '��' => '渽',
  '��' => '渾',
  '��' => '渿',
  '��' => '湀',
  '��' => '湁',
  '��' => '湂',
  '��' => '湅',
  '��' => '湆',
  '��' => '湇',
  '��' => '湈',
  '��' => '湉',
  '��' => '湊',
  '��' => '湋',
  '��' => '湌',
  '��' => '湏',
  '��' => '湐',
  '��' => '湑',
  '��' => '湒',
  '��' => '湕',
  '��' => '湗',
  '��' => '湙',
  '��' => '湚',
  '��' => '湜',
  '��' => '湝',
  '��' => '湞',
  '��' => '湠',
  '��' => '湡',
  '��' => '湢',
  '��' => '湣',
  '��' => '湤',
  '��' => '湥',
  '��' => '湦',
  '��' => '湧',
  '��' => '湨',
  '��' => '湩',
  '��' => '湪',
  '��' => '湬',
  '��' => '湭',
  '��' => '湯',
  '��' => '湰',
  '��' => '湱',
  '��' => '湲',
  '��' => '湳',
  '��' => '湴',
  '��' => '湵',
  '��' => '湶',
  '��' => '湷',
  '��' => '湸',
  '��' => '湹',
  '��' => '湺',
  '��' => '湻',
  '��' => '湼',
  '��' => '湽',
  '��' => '満',
  '��' => '溁',
  '��' => '溂',
  '��' => '溄',
  '��' => '溇',
  '��' => '溈',
  '��' => '溊',
  '��' => '溋',
  '��' => '溌',
  '��' => '溍',
  '��' => '溎',
  '��' => '溑',
  '��' => '溒',
  '��' => '溓',
  '��' => '溔',
  '��' => '溕',
  '��' => '準',
  '��' => '溗',
  '��' => '溙',
  '��' => '溚',
  '��' => '溛',
  '��' => '溝',
  '��' => '溞',
  '��' => '溠',
  '��' => '溡',
  '��' => '溣',
  '��' => '溤',
  '��' => '溦',
  '��' => '溨',
  '��' => '溩',
  '��' => '溫',
  '��' => '溬',
  '��' => '溭',
  '��' => '溮',
  '��' => '溰',
  '��' => '溳',
  '��' => '溵',
  '��' => '溸',
  '��' => '溹',
  '��' => '溼',
  '��' => '溾',
  '��' => '溿',
  '��' => '滀',
  '��' => '滃',
  '��' => '滄',
  '��' => '滅',
  '��' => '滆',
  '��' => '滈',
  '��' => '滉',
  '��' => '滊',
  '��' => '滌',
  '��' => '滍',
  '��' => '滎',
  '��' => '滐',
  '��' => '滒',
  '��' => '滖',
  '��' => '滘',
  '��' => '滙',
  '��' => '滛',
  '��' => '滜',
  '��' => '滝',
  '��' => '滣',
  '��' => '滧',
  '��' => '滪',
  '��' => '滫',
  '��' => '滬',
  '��' => '滭',
  '��' => '滮',
  '��' => '滯',
  '�@' => '滰',
  '�A' => '滱',
  '�B' => '滲',
  '�C' => '滳',
  '�D' => '滵',
  '�E' => '滶',
  '�F' => '滷',
  '�G' => '滸',
  '�H' => '滺',
  '�I' => '滻',
  '�J' => '滼',
  '�K' => '滽',
  '�L' => '滾',
  '�M' => '滿',
  '�N' => '漀',
  '�O' => '漁',
  '�P' => '漃',
  '�Q' => '漄',
  '�R' => '漅',
  '�S' => '漇',
  '�T' => '漈',
  '�U' => '漊',
  '�V' => '漋',
  '�W' => '漌',
  '�X' => '漍',
  '�Y' => '漎',
  '�Z' => '漐',
  '�[' => '漑',
  '�\\' => '漒',
  '�]' => '漖',
  '�^' => '漗',
  '�_' => '漘',
  '�`' => '漙',
  '�a' => '漚',
  '�b' => '漛',
  '�c' => '漜',
  '�d' => '漝',
  '�e' => '漞',
  '�f' => '漟',
  '�g' => '漡',
  '�h' => '漢',
  '�i' => '漣',
  '�j' => '漥',
  '�k' => '漦',
  '�l' => '漧',
  '�m' => '漨',
  '�n' => '漬',
  '�o' => '漮',
  '�p' => '漰',
  '�q' => '漲',
  '�r' => '漴',
  '�s' => '漵',
  '�t' => '漷',
  '�u' => '漸',
  '�v' => '漹',
  '�w' => '漺',
  '�x' => '漻',
  '�y' => '漼',
  '�z' => '漽',
  '�{' => '漿',
  '�|' => '潀',
  '�}' => '潁',
  '�~' => '潂',
  '��' => '潃',
  '��' => '潄',
  '��' => '潅',
  '��' => '潈',
  '��' => '潉',
  '��' => '潊',
  '��' => '潌',
  '��' => '潎',
  '��' => '潏',
  '��' => '潐',
  '��' => '潑',
  '��' => '潒',
  '��' => '潓',
  '��' => '潔',
  '��' => '潕',
  '��' => '潖',
  '��' => '潗',
  '��' => '潙',
  '��' => '潚',
  '��' => '潛',
  '��' => '潝',
  '��' => '潟',
  '��' => '潠',
  '��' => '潡',
  '��' => '潣',
  '��' => '潤',
  '��' => '潥',
  '��' => '潧',
  '��' => '潨',
  '��' => '潩',
  '��' => '潪',
  '��' => '潫',
  '��' => '潬',
  '��' => '潯',
  '��' => '潰',
  '��' => '潱',
  '��' => '潳',
  '��' => '潵',
  '��' => '潶',
  '��' => '潷',
  '��' => '潹',
  '��' => '潻',
  '��' => '潽',
  '��' => '潾',
  '��' => '潿',
  '��' => '澀',
  '��' => '澁',
  '��' => '澂',
  '��' => '澃',
  '��' => '澅',
  '��' => '澆',
  '��' => '澇',
  '��' => '澊',
  '��' => '澋',
  '��' => '澏',
  '��' => '澐',
  '��' => '澑',
  '��' => '澒',
  '��' => '澓',
  '��' => '澔',
  '��' => '澕',
  '��' => '澖',
  '��' => '澗',
  '��' => '澘',
  '��' => '澙',
  '��' => '澚',
  '��' => '澛',
  '��' => '澝',
  '��' => '澞',
  '��' => '澟',
  '��' => '澠',
  '��' => '澢',
  '��' => '澣',
  '��' => '澤',
  '��' => '澥',
  '��' => '澦',
  '��' => '澨',
  '��' => '澩',
  '��' => '澪',
  '��' => '澫',
  '��' => '澬',
  '��' => '澭',
  '��' => '澮',
  '��' => '澯',
  '��' => '澰',
  '��' => '澱',
  '��' => '澲',
  '��' => '澴',
  '��' => '澵',
  '��' => '澷',
  '��' => '澸',
  '��' => '澺',
  '��' => '澻',
  '��' => '澼',
  '��' => '澽',
  '��' => '澾',
  '��' => '澿',
  '��' => '濁',
  '��' => '濃',
  '��' => '濄',
  '��' => '濅',
  '��' => '濆',
  '��' => '濇',
  '��' => '濈',
  '��' => '濊',
  '��' => '濋',
  '��' => '濌',
  '��' => '濍',
  '��' => '濎',
  '��' => '濏',
  '��' => '濐',
  '��' => '濓',
  '��' => '濔',
  '��' => '濕',
  '��' => '濖',
  '��' => '濗',
  '��' => '濘',
  '��' => '濙',
  '��' => '濚',
  '��' => '濛',
  '��' => '濜',
  '��' => '濝',
  '��' => '濟',
  '��' => '濢',
  '��' => '濣',
  '��' => '濤',
  '��' => '濥',
  '�@' => '濦',
  '�A' => '濧',
  '�B' => '濨',
  '�C' => '濩',
  '�D' => '濪',
  '�E' => '濫',
  '�F' => '濬',
  '�G' => '濭',
  '�H' => '濰',
  '�I' => '濱',
  '�J' => '濲',
  '�K' => '濳',
  '�L' => '濴',
  '�M' => '濵',
  '�N' => '濶',
  '�O' => '濷',
  '�P' => '濸',
  '�Q' => '濹',
  '�R' => '濺',
  '�S' => '濻',
  '�T' => '濼',
  '�U' => '濽',
  '�V' => '濾',
  '�W' => '濿',
  '�X' => '瀀',
  '�Y' => '瀁',
  '�Z' => '瀂',
  '�[' => '瀃',
  '�\\' => '瀄',
  '�]' => '瀅',
  '�^' => '瀆',
  '�_' => '瀇',
  '�`' => '瀈',
  '�a' => '瀉',
  '�b' => '瀊',
  '�c' => '瀋',
  '�d' => '瀌',
  '�e' => '瀍',
  '�f' => '瀎',
  '�g' => '瀏',
  '�h' => '瀐',
  '�i' => '瀒',
  '�j' => '瀓',
  '�k' => '瀔',
  '�l' => '瀕',
  '�m' => '瀖',
  '�n' => '瀗',
  '�o' => '瀘',
  '�p' => '瀙',
  '�q' => '瀜',
  '�r' => '瀝',
  '�s' => '瀞',
  '�t' => '瀟',
  '�u' => '瀠',
  '�v' => '瀡',
  '�w' => '瀢',
  '�x' => '瀤',
  '�y' => '瀥',
  '�z' => '瀦',
  '�{' => '瀧',
  '�|' => '瀨',
  '�}' => '瀩',
  '�~' => '瀪',
  '��' => '瀫',
  '��' => '瀬',
  '��' => '瀭',
  '��' => '瀮',
  '��' => '瀯',
  '��' => '瀰',
  '��' => '瀱',
  '��' => '瀲',
  '��' => '瀳',
  '��' => '瀴',
  '��' => '瀶',
  '��' => '瀷',
  '��' => '瀸',
  '��' => '瀺',
  '��' => '瀻',
  '��' => '瀼',
  '��' => '瀽',
  '��' => '瀾',
  '��' => '瀿',
  '��' => '灀',
  '��' => '灁',
  '��' => '灂',
  '��' => '灃',
  '��' => '灄',
  '��' => '灅',
  '��' => '灆',
  '��' => '灇',
  '��' => '灈',
  '��' => '灉',
  '��' => '灊',
  '��' => '灋',
  '��' => '灍',
  '��' => '灎',
  '��' => '灐',
  '��' => '灑',
  '��' => '灒',
  '��' => '灓',
  '��' => '灔',
  '��' => '灕',
  '��' => '灖',
  '��' => '灗',
  '��' => '灘',
  '��' => '灙',
  '��' => '灚',
  '��' => '灛',
  '��' => '灜',
  '��' => '灝',
  '��' => '灟',
  '��' => '灠',
  '��' => '灡',
  '��' => '灢',
  '��' => '灣',
  '��' => '灤',
  '��' => '灥',
  '��' => '灦',
  '��' => '灧',
  '��' => '灨',
  '��' => '灩',
  '��' => '灪',
  '��' => '灮',
  '��' => '灱',
  '��' => '灲',
  '��' => '灳',
  '��' => '灴',
  '��' => '灷',
  '��' => '灹',
  '��' => '灺',
  '��' => '灻',
  '��' => '災',
  '��' => '炁',
  '��' => '炂',
  '��' => '炃',
  '��' => '炄',
  '��' => '炆',
  '��' => '炇',
  '��' => '炈',
  '��' => '炋',
  '��' => '炌',
  '��' => '炍',
  '��' => '炏',
  '��' => '炐',
  '��' => '炑',
  '��' => '炓',
  '��' => '炗',
  '��' => '炘',
  '��' => '炚',
  '��' => '炛',
  '��' => '炞',
  '��' => '炟',
  '��' => '炠',
  '��' => '炡',
  '��' => '炢',
  '��' => '炣',
  '��' => '炤',
  '��' => '炥',
  '��' => '炦',
  '��' => '炧',
  '��' => '炨',
  '��' => '炩',
  '��' => '炪',
  '��' => '炰',
  '��' => '炲',
  '��' => '炴',
  '��' => '炵',
  '��' => '炶',
  '��' => '為',
  '��' => '炾',
  '��' => '炿',
  '��' => '烄',
  '��' => '烅',
  '��' => '烆',
  '��' => '烇',
  '��' => '烉',
  '��' => '烋',
  '��' => '烌',
  '��' => '烍',
  '��' => '烎',
  '��' => '烏',
  '��' => '烐',
  '��' => '烑',
  '��' => '烒',
  '��' => '烓',
  '��' => '烔',
  '��' => '烕',
  '��' => '烖',
  '��' => '烗',
  '��' => '烚',
  '�@' => '烜',
  '�A' => '烝',
  '�B' => '烞',
  '�C' => '烠',
  '�D' => '烡',
  '�E' => '烢',
  '�F' => '烣',
  '�G' => '烥',
  '�H' => '烪',
  '�I' => '烮',
  '�J' => '烰',
  '�K' => '烱',
  '�L' => '烲',
  '�M' => '烳',
  '�N' => '烴',
  '�O' => '烵',
  '�P' => '烶',
  '�Q' => '烸',
  '�R' => '烺',
  '�S' => '烻',
  '�T' => '烼',
  '�U' => '烾',
  '�V' => '烿',
  '�W' => '焀',
  '�X' => '焁',
  '�Y' => '焂',
  '�Z' => '焃',
  '�[' => '焄',
  '�\\' => '焅',
  '�]' => '焆',
  '�^' => '焇',
  '�_' => '焈',
  '�`' => '焋',
  '�a' => '焌',
  '�b' => '焍',
  '�c' => '焎',
  '�d' => '焏',
  '�e' => '焑',
  '�f' => '焒',
  '�g' => '焔',
  '�h' => '焗',
  '�i' => '焛',
  '�j' => '焜',
  '�k' => '焝',
  '�l' => '焞',
  '�m' => '焟',
  '�n' => '焠',
  '�o' => '無',
  '�p' => '焢',
  '�q' => '焣',
  '�r' => '焤',
  '�s' => '焥',
  '�t' => '焧',
  '�u' => '焨',
  '�v' => '焩',
  '�w' => '焪',
  '�x' => '焫',
  '�y' => '焬',
  '�z' => '焭',
  '�{' => '焮',
  '�|' => '焲',
  '�}' => '焳',
  '�~' => '焴',
  '��' => '焵',
  '��' => '焷',
  '��' => '焸',
  '��' => '焹',
  '��' => '焺',
  '��' => '焻',
  '��' => '焼',
  '��' => '焽',
  '��' => '焾',
  '��' => '焿',
  '��' => '煀',
  '��' => '煁',
  '��' => '煂',
  '��' => '煃',
  '��' => '煄',
  '��' => '煆',
  '��' => '煇',
  '��' => '煈',
  '��' => '煉',
  '��' => '煋',
  '��' => '煍',
  '��' => '煏',
  '��' => '煐',
  '��' => '煑',
  '��' => '煒',
  '��' => '煓',
  '��' => '煔',
  '��' => '煕',
  '��' => '煖',
  '��' => '煗',
  '��' => '煘',
  '��' => '煙',
  '��' => '煚',
  '��' => '煛',
  '��' => '煝',
  '��' => '煟',
  '��' => '煠',
  '��' => '煡',
  '��' => '煢',
  '��' => '煣',
  '��' => '煥',
  '��' => '煩',
  '��' => '煪',
  '��' => '煫',
  '��' => '煬',
  '��' => '煭',
  '��' => '煯',
  '��' => '煰',
  '��' => '煱',
  '��' => '煴',
  '��' => '煵',
  '��' => '煶',
  '��' => '煷',
  '��' => '煹',
  '��' => '煻',
  '��' => '煼',
  '��' => '煾',
  '��' => '煿',
  '��' => '熀',
  '��' => '熁',
  '��' => '熂',
  '��' => '熃',
  '��' => '熅',
  '��' => '熆',
  '��' => '熇',
  '��' => '熈',
  '��' => '熉',
  '��' => '熋',
  '��' => '熌',
  '��' => '熍',
  '��' => '熎',
  '��' => '熐',
  '��' => '熑',
  '��' => '熒',
  '��' => '熓',
  '��' => '熕',
  '��' => '熖',
  '��' => '熗',
  '��' => '熚',
  '��' => '熛',
  '��' => '熜',
  '��' => '熝',
  '��' => '熞',
  '��' => '熡',
  '��' => '熢',
  '��' => '熣',
  '��' => '熤',
  '��' => '熥',
  '��' => '熦',
  '��' => '熧',
  '��' => '熩',
  '��' => '熪',
  '��' => '熫',
  '��' => '熭',
  '��' => '熮',
  '��' => '熯',
  '��' => '熰',
  '��' => '熱',
  '��' => '熲',
  '��' => '熴',
  '��' => '熶',
  '��' => '熷',
  '��' => '熸',
  '��' => '熺',
  '��' => '熻',
  '��' => '熼',
  '��' => '熽',
  '��' => '熾',
  '��' => '熿',
  '��' => '燀',
  '��' => '燁',
  '��' => '燂',
  '��' => '燄',
  '��' => '燅',
  '��' => '燆',
  '��' => '燇',
  '��' => '燈',
  '��' => '燉',
  '��' => '燊',
  '��' => '燋',
  '��' => '燌',
  '��' => '燍',
  '��' => '燏',
  '��' => '燐',
  '��' => '燑',
  '��' => '燒',
  '��' => '燓',
  '�@' => '燖',
  '�A' => '燗',
  '�B' => '燘',
  '�C' => '燙',
  '�D' => '燚',
  '�E' => '燛',
  '�F' => '燜',
  '�G' => '燝',
  '�H' => '燞',
  '�I' => '營',
  '�J' => '燡',
  '�K' => '燢',
  '�L' => '燣',
  '�M' => '燤',
  '�N' => '燦',
  '�O' => '燨',
  '�P' => '燩',
  '�Q' => '燪',
  '�R' => '燫',
  '�S' => '燬',
  '�T' => '燭',
  '�U' => '燯',
  '�V' => '燰',
  '�W' => '燱',
  '�X' => '燲',
  '�Y' => '燳',
  '�Z' => '燴',
  '�[' => '燵',
  '�\\' => '燶',
  '�]' => '燷',
  '�^' => '燸',
  '�_' => '燺',
  '�`' => '燻',
  '�a' => '燼',
  '�b' => '燽',
  '�c' => '燾',
  '�d' => '燿',
  '�e' => '爀',
  '�f' => '爁',
  '�g' => '爂',
  '�h' => '爃',
  '�i' => '爄',
  '�j' => '爅',
  '�k' => '爇',
  '�l' => '爈',
  '�m' => '爉',
  '�n' => '爊',
  '�o' => '爋',
  '�p' => '爌',
  '�q' => '爍',
  '�r' => '爎',
  '�s' => '爏',
  '�t' => '爐',
  '�u' => '爑',
  '�v' => '爒',
  '�w' => '爓',
  '�x' => '爔',
  '�y' => '爕',
  '�z' => '爖',
  '�{' => '爗',
  '�|' => '爘',
  '�}' => '爙',
  '�~' => '爚',
  '��' => '爛',
  '��' => '爜',
  '��' => '爞',
  '��' => '爟',
  '��' => '爠',
  '��' => '爡',
  '��' => '爢',
  '��' => '爣',
  '��' => '爤',
  '��' => '爥',
  '��' => '爦',
  '��' => '爧',
  '��' => '爩',
  '��' => '爫',
  '��' => '爭',
  '��' => '爮',
  '��' => '爯',
  '��' => '爲',
  '��' => '爳',
  '��' => '爴',
  '��' => '爺',
  '��' => '爼',
  '��' => '爾',
  '��' => '牀',
  '��' => '牁',
  '��' => '牂',
  '��' => '牃',
  '��' => '牄',
  '��' => '牅',
  '��' => '牆',
  '��' => '牉',
  '��' => '牊',
  '��' => '牋',
  '��' => '牎',
  '��' => '牏',
  '��' => '牐',
  '��' => '牑',
  '��' => '牓',
  '��' => '牔',
  '��' => '牕',
  '��' => '牗',
  '��' => '牘',
  '��' => '牚',
  '��' => '牜',
  '��' => '牞',
  '��' => '牠',
  '��' => '牣',
  '��' => '牤',
  '��' => '牥',
  '��' => '牨',
  '��' => '牪',
  '��' => '牫',
  '��' => '牬',
  '��' => '牭',
  '��' => '牰',
  '��' => '牱',
  '��' => '牳',
  '��' => '牴',
  '��' => '牶',
  '��' => '牷',
  '��' => '牸',
  '��' => '牻',
  '��' => '牼',
  '��' => '牽',
  '��' => '犂',
  '��' => '犃',
  '��' => '犅',
  '��' => '犆',
  '��' => '犇',
  '��' => '犈',
  '��' => '犉',
  '��' => '犌',
  '��' => '犎',
  '��' => '犐',
  '��' => '犑',
  '��' => '犓',
  '��' => '犔',
  '��' => '犕',
  '��' => '犖',
  '��' => '犗',
  '��' => '犘',
  '��' => '犙',
  '��' => '犚',
  '��' => '犛',
  '��' => '犜',
  '��' => '犝',
  '��' => '犞',
  '��' => '犠',
  '��' => '犡',
  '��' => '犢',
  '��' => '犣',
  '��' => '犤',
  '��' => '犥',
  '��' => '犦',
  '��' => '犧',
  '��' => '犨',
  '��' => '犩',
  '��' => '犪',
  '��' => '犫',
  '��' => '犮',
  '��' => '犱',
  '��' => '犲',
  '��' => '犳',
  '��' => '犵',
  '��' => '犺',
  '��' => '犻',
  '��' => '犼',
  '��' => '犽',
  '��' => '犾',
  '��' => '犿',
  '��' => '狀',
  '��' => '狅',
  '��' => '狆',
  '��' => '狇',
  '��' => '狉',
  '��' => '狊',
  '��' => '狋',
  '��' => '狌',
  '��' => '狏',
  '��' => '狑',
  '��' => '狓',
  '��' => '狔',
  '��' => '狕',
  '��' => '狖',
  '��' => '狘',
  '��' => '狚',
  '��' => '狛',
  '��' => ' ',
  '��' => '、',
  '��' => '。',
  '��' => '·',
  '��' => 'ˉ',
  '��' => 'ˇ',
  '��' => '¨',
  '��' => '〃',
  '��' => '々',
  '��' => '—',
  '��' => '~',
  '��' => '‖',
  '��' => '…',
  '��' => '‘',
  '��' => '’',
  '��' => '“',
  '��' => '”',
  '��' => '〔',
  '��' => '〕',
  '��' => '〈',
  '��' => '〉',
  '��' => '《',
  '��' => '》',
  '��' => '「',
  '��' => '」',
  '��' => '『',
  '��' => '』',
  '��' => '〖',
  '��' => '〗',
  '��' => '【',
  '��' => '】',
  '��' => '±',
  '��' => '×',
  '��' => '÷',
  '��' => '∶',
  '��' => '∧',
  '��' => '∨',
  '��' => '∑',
  '��' => '∏',
  '��' => '∪',
  '��' => '∩',
  '��' => '∈',
  '��' => '∷',
  '��' => '√',
  '��' => '⊥',
  '��' => '∥',
  '��' => '∠',
  '��' => '⌒',
  '��' => '⊙',
  '��' => '∫',
  '��' => '∮',
  '��' => '≡',
  '��' => '≌',
  '��' => '≈',
  '��' => '∽',
  '��' => '∝',
  '��' => '≠',
  '��' => '≮',
  '��' => '≯',
  '��' => '≤',
  '��' => '≥',
  '��' => '∞',
  '��' => '∵',
  '��' => '∴',
  '��' => '♂',
  '��' => '♀',
  '��' => '°',
  '��' => '′',
  '��' => '″',
  '��' => '℃',
  '��' => '$',
  '��' => '¤',
  '��' => '¢',
  '��' => '£',
  '��' => '‰',
  '��' => '§',
  '��' => '№',
  '��' => '☆',
  '��' => '★',
  '��' => '○',
  '��' => '●',
  '��' => '◎',
  '��' => '◇',
  '��' => '◆',
  '��' => '□',
  '��' => '■',
  '��' => '△',
  '��' => '▲',
  '��' => '※',
  '��' => '→',
  '��' => '←',
  '��' => '↑',
  '��' => '↓',
  '��' => '〓',
  '��' => 'ⅰ',
  '��' => 'ⅱ',
  '��' => 'ⅲ',
  '��' => 'ⅳ',
  '��' => 'ⅴ',
  '��' => 'ⅵ',
  '��' => 'ⅶ',
  '��' => 'ⅷ',
  '��' => 'ⅸ',
  '��' => 'ⅹ',
  '��' => '⒈',
  '��' => '⒉',
  '��' => '⒊',
  '��' => '⒋',
  '��' => '⒌',
  '��' => '⒍',
  '��' => '⒎',
  '��' => '⒏',
  '��' => '⒐',
  '��' => '⒑',
  '��' => '⒒',
  '��' => '⒓',
  '��' => '⒔',
  '��' => '⒕',
  '��' => '⒖',
  '��' => '⒗',
  '��' => '⒘',
  '��' => '⒙',
  '��' => '⒚',
  '��' => '⒛',
  '��' => '⑴',
  '��' => '⑵',
  '��' => '⑶',
  '��' => '⑷',
  '��' => '⑸',
  '��' => '⑹',
  '��' => '⑺',
  '��' => '⑻',
  '��' => '⑼',
  '��' => '⑽',
  '��' => '⑾',
  '��' => '⑿',
  '��' => '⒀',
  '��' => '⒁',
  '��' => '⒂',
  '��' => '⒃',
  '��' => '⒄',
  '��' => '⒅',
  '��' => '⒆',
  '��' => '⒇',
  '��' => '①',
  '��' => '②',
  '��' => '③',
  '��' => '④',
  '��' => '⑤',
  '��' => '⑥',
  '��' => '⑦',
  '��' => '⑧',
  '��' => '⑨',
  '��' => '⑩',
  '��' => '㈠',
  '��' => '㈡',
  '��' => '㈢',
  '��' => '㈣',
  '��' => '㈤',
  '��' => '㈥',
  '��' => '㈦',
  '��' => '㈧',
  '��' => '㈨',
  '��' => '㈩',
  '��' => 'Ⅰ',
  '��' => 'Ⅱ',
  '��' => 'Ⅲ',
  '��' => 'Ⅳ',
  '��' => 'Ⅴ',
  '��' => 'Ⅵ',
  '��' => 'Ⅶ',
  '��' => 'Ⅷ',
  '��' => 'Ⅸ',
  '��' => 'Ⅹ',
  '��' => 'Ⅺ',
  '��' => 'Ⅻ',
  '��' => '!',
  '��' => '"',
  '��' => '#',
  '��' => '¥',
  '��' => '%',
  '��' => '&',
  '��' => ''',
  '��' => '(',
  '��' => ')',
  '��' => '*',
  '��' => '+',
  '��' => ',',
  '��' => '-',
  '��' => '.',
  '��' => '/',
  '��' => '0',
  '��' => '1',
  '��' => '2',
  '��' => '3',
  '��' => '4',
  '��' => '5',
  '��' => '6',
  '��' => '7',
  '��' => '8',
  '��' => '9',
  '��' => ':',
  '��' => ';',
  '��' => '<',
  '��' => '=',
  '��' => '>',
  '��' => '?',
  '��' => '@',
  '��' => 'A',
  '��' => 'B',
  '��' => 'C',
  '��' => 'D',
  '��' => 'E',
  '��' => 'F',
  '��' => 'G',
  '��' => 'H',
  '��' => 'I',
  '��' => 'J',
  '��' => 'K',
  '��' => 'L',
  '��' => 'M',
  '��' => 'N',
  '��' => 'O',
  '��' => 'P',
  '��' => 'Q',
  '��' => 'R',
  '��' => 'S',
  '��' => 'T',
  '��' => 'U',
  '��' => 'V',
  '��' => 'W',
  '��' => 'X',
  '��' => 'Y',
  '��' => 'Z',
  '��' => '[',
  '��' => '\',
  '��' => ']',
  '��' => '^',
  '��' => '_',
  '��' => '`',
  '��' => 'a',
  '��' => 'b',
  '��' => 'c',
  '��' => 'd',
  '��' => 'e',
  '��' => 'f',
  '��' => 'g',
  '��' => 'h',
  '��' => 'i',
  '��' => 'j',
  '��' => 'k',
  '��' => 'l',
  '��' => 'm',
  '��' => 'n',
  '��' => 'o',
  '��' => 'p',
  '��' => 'q',
  '��' => 'r',
  '��' => 's',
  '��' => 't',
  '��' => 'u',
  '��' => 'v',
  '��' => 'w',
  '��' => 'x',
  '��' => 'y',
  '��' => 'z',
  '��' => '{',
  '��' => '|',
  '��' => '}',
  '��' => ' ̄',
  '��' => 'ぁ',
  '��' => 'あ',
  '��' => 'ぃ',
  '��' => 'い',
  '��' => 'ぅ',
  '��' => 'う',
  '��' => 'ぇ',
  '��' => 'え',
  '��' => 'ぉ',
  '��' => 'お',
  '��' => 'か',
  '��' => 'が',
  '��' => 'き',
  '��' => 'ぎ',
  '��' => 'く',
  '��' => 'ぐ',
  '��' => 'け',
  '��' => 'げ',
  '��' => 'こ',
  '��' => 'ご',
  '��' => 'さ',
  '��' => 'ざ',
  '��' => 'し',
  '��' => 'じ',
  '��' => 'す',
  '��' => 'ず',
  '��' => 'せ',
  '��' => 'ぜ',
  '��' => 'そ',
  '��' => 'ぞ',
  '��' => 'た',
  '��' => 'だ',
  '��' => 'ち',
  '��' => 'ぢ',
  '��' => 'っ',
  '��' => 'つ',
  '��' => 'づ',
  '��' => 'て',
  '��' => 'で',
  '��' => 'と',
  '��' => 'ど',
  '��' => 'な',
  '��' => 'に',
  '��' => 'ぬ',
  '��' => 'ね',
  '��' => 'の',
  '��' => 'は',
  '��' => 'ば',
  '��' => 'ぱ',
  '��' => 'ひ',
  '��' => 'び',
  '��' => 'ぴ',
  '��' => 'ふ',
  '��' => 'ぶ',
  '��' => 'ぷ',
  '��' => 'へ',
  '��' => 'べ',
  '��' => 'ぺ',
  '��' => 'ほ',
  '��' => 'ぼ',
  '��' => 'ぽ',
  '��' => 'ま',
  '��' => 'み',
  '��' => 'む',
  '��' => 'め',
  '��' => 'も',
  '��' => 'ゃ',
  '��' => 'や',
  '��' => 'ゅ',
  '��' => 'ゆ',
  '��' => 'ょ',
  '��' => 'よ',
  '��' => 'ら',
  '��' => 'り',
  '��' => 'る',
  '��' => 'れ',
  '��' => 'ろ',
  '��' => 'ゎ',
  '��' => 'わ',
  '��' => 'ゐ',
  '��' => 'ゑ',
  '��' => 'を',
  '��' => 'ん',
  '��' => 'ァ',
  '��' => 'ア',
  '��' => 'ィ',
  '��' => 'イ',
  '��' => 'ゥ',
  '��' => 'ウ',
  '��' => 'ェ',
  '��' => 'エ',
  '��' => 'ォ',
  '��' => 'オ',
  '��' => 'カ',
  '��' => 'ガ',
  '��' => 'キ',
  '��' => 'ギ',
  '��' => 'ク',
  '��' => 'グ',
  '��' => 'ケ',
  '��' => 'ゲ',
  '��' => 'コ',
  '��' => 'ゴ',
  '��' => 'サ',
  '��' => 'ザ',
  '��' => 'シ',
  '��' => 'ジ',
  '��' => 'ス',
  '��' => 'ズ',
  '��' => 'セ',
  '��' => 'ゼ',
  '��' => 'ソ',
  '��' => 'ゾ',
  '��' => 'タ',
  '��' => 'ダ',
  '��' => 'チ',
  '��' => 'ヂ',
  '��' => 'ッ',
  '��' => 'ツ',
  '��' => 'ヅ',
  '��' => 'テ',
  '��' => 'デ',
  '��' => 'ト',
  '��' => 'ド',
  '��' => 'ナ',
  '��' => 'ニ',
  '��' => 'ヌ',
  '��' => 'ネ',
  '��' => 'ノ',
  '��' => 'ハ',
  '��' => 'バ',
  '��' => 'パ',
  '��' => 'ヒ',
  '��' => 'ビ',
  '��' => 'ピ',
  '��' => 'フ',
  '��' => 'ブ',
  '��' => 'プ',
  '��' => 'ヘ',
  '��' => 'ベ',
  '��' => 'ペ',
  '��' => 'ホ',
  '��' => 'ボ',
  '��' => 'ポ',
  '��' => 'マ',
  '��' => 'ミ',
  '��' => 'ム',
  '��' => 'メ',
  '��' => 'モ',
  '��' => 'ャ',
  '��' => 'ヤ',
  '��' => 'ュ',
  '��' => 'ユ',
  '��' => 'ョ',
  '��' => 'ヨ',
  '��' => 'ラ',
  '��' => 'リ',
  '��' => 'ル',
  '��' => 'レ',
  '��' => 'ロ',
  '��' => 'ヮ',
  '��' => 'ワ',
  '��' => 'ヰ',
  '��' => 'ヱ',
  '��' => 'ヲ',
  '��' => 'ン',
  '��' => 'ヴ',
  '��' => 'ヵ',
  '��' => 'ヶ',
  '��' => 'Α',
  '��' => 'Β',
  '��' => 'Γ',
  '��' => 'Δ',
  '��' => 'Ε',
  '��' => 'Ζ',
  '��' => 'Η',
  '��' => 'Θ',
  '��' => 'Ι',
  '��' => 'Κ',
  '��' => 'Λ',
  '��' => 'Μ',
  '��' => 'Ν',
  '��' => 'Ξ',
  '��' => 'Ο',
  '��' => 'Π',
  '��' => 'Ρ',
  '��' => 'Σ',
  '��' => 'Τ',
  '��' => 'Υ',
  '��' => 'Φ',
  '��' => 'Χ',
  '��' => 'Ψ',
  '��' => 'Ω',
  '��' => 'α',
  '��' => 'β',
  '��' => 'γ',
  '��' => 'δ',
  '��' => 'ε',
  '��' => 'ζ',
  '��' => 'η',
  '��' => 'θ',
  '��' => 'ι',
  '��' => 'κ',
  '��' => 'λ',
  '��' => 'μ',
  '��' => 'ν',
  '��' => 'ξ',
  '��' => 'ο',
  '��' => 'π',
  '��' => 'ρ',
  '��' => 'σ',
  '��' => 'τ',
  '��' => 'υ',
  '��' => 'φ',
  '��' => 'χ',
  '��' => 'ψ',
  '��' => 'ω',
  '��' => '︵',
  '��' => '︶',
  '��' => '︹',
  '��' => '︺',
  '��' => '︿',
  '��' => '﹀',
  '��' => '︽',
  '��' => '︾',
  '��' => '﹁',
  '��' => '﹂',
  '��' => '﹃',
  '��' => '﹄',
  '��' => '︻',
  '��' => '︼',
  '��' => '︷',
  '��' => '︸',
  '��' => '︱',
  '��' => '︳',
  '��' => '︴',
  '��' => 'А',
  '��' => 'Б',
  '��' => 'В',
  '��' => 'Г',
  '��' => 'Д',
  '��' => 'Е',
  '��' => 'Ё',
  '��' => 'Ж',
  '��' => 'З',
  '��' => 'И',
  '��' => 'Й',
  '��' => 'К',
  '��' => 'Л',
  '��' => 'М',
  '��' => 'Н',
  '��' => 'О',
  '��' => 'П',
  '��' => 'Р',
  '��' => 'С',
  '��' => 'Т',
  '��' => 'У',
  '��' => 'Ф',
  '��' => 'Х',
  '��' => 'Ц',
  '��' => 'Ч',
  '��' => 'Ш',
  '��' => 'Щ',
  '��' => 'Ъ',
  '��' => 'Ы',
  '��' => 'Ь',
  '��' => 'Э',
  '��' => 'Ю',
  '��' => 'Я',
  '��' => 'а',
  '��' => 'б',
  '��' => 'в',
  '��' => 'г',
  '��' => 'д',
  '��' => 'е',
  '��' => 'ё',
  '��' => 'ж',
  '��' => 'з',
  '��' => 'и',
  '��' => 'й',
  '��' => 'к',
  '��' => 'л',
  '��' => 'м',
  '��' => 'н',
  '��' => 'о',
  '��' => 'п',
  '��' => 'р',
  '��' => 'с',
  '��' => 'т',
  '��' => 'у',
  '��' => 'ф',
  '��' => 'х',
  '��' => 'ц',
  '��' => 'ч',
  '��' => 'ш',
  '��' => 'щ',
  '��' => 'ъ',
  '��' => 'ы',
  '��' => 'ь',
  '��' => 'э',
  '��' => 'ю',
  '��' => 'я',
  '�@' => 'ˊ',
  '�A' => 'ˋ',
  '�B' => '˙',
  '�C' => '–',
  '�D' => '―',
  '�E' => '‥',
  '�F' => '‵',
  '�G' => '℅',
  '�H' => '℉',
  '�I' => '↖',
  '�J' => '↗',
  '�K' => '↘',
  '�L' => '↙',
  '�M' => '∕',
  '�N' => '∟',
  '�O' => '∣',
  '�P' => '≒',
  '�Q' => '≦',
  '�R' => '≧',
  '�S' => '⊿',
  '�T' => '═',
  '�U' => '║',
  '�V' => '╒',
  '�W' => '╓',
  '�X' => '╔',
  '�Y' => '╕',
  '�Z' => '╖',
  '�[' => '╗',
  '�\\' => '╘',
  '�]' => '╙',
  '�^' => '╚',
  '�_' => '╛',
  '�`' => '╜',
  '�a' => '╝',
  '�b' => '╞',
  '�c' => '╟',
  '�d' => '╠',
  '�e' => '╡',
  '�f' => '╢',
  '�g' => '╣',
  '�h' => '╤',
  '�i' => '╥',
  '�j' => '╦',
  '�k' => '╧',
  '�l' => '╨',
  '�m' => '╩',
  '�n' => '╪',
  '�o' => '╫',
  '�p' => '╬',
  '�q' => '╭',
  '�r' => '╮',
  '�s' => '╯',
  '�t' => '╰',
  '�u' => '╱',
  '�v' => '╲',
  '�w' => '╳',
  '�x' => '▁',
  '�y' => '▂',
  '�z' => '▃',
  '�{' => '▄',
  '�|' => '▅',
  '�}' => '▆',
  '�~' => '▇',
  '��' => '█',
  '��' => '▉',
  '��' => '▊',
  '��' => '▋',
  '��' => '▌',
  '��' => '▍',
  '��' => '▎',
  '��' => '▏',
  '��' => '▓',
  '��' => '▔',
  '��' => '▕',
  '��' => '▼',
  '��' => '▽',
  '��' => '◢',
  '��' => '◣',
  '��' => '◤',
  '��' => '◥',
  '��' => '☉',
  '��' => '⊕',
  '��' => '〒',
  '��' => '〝',
  '��' => '〞',
  '��' => 'ā',
  '��' => 'á',
  '��' => 'ǎ',
  '��' => 'à',
  '��' => 'ē',
  '��' => 'é',
  '��' => 'ě',
  '��' => 'è',
  '��' => 'ī',
  '��' => 'í',
  '��' => 'ǐ',
  '��' => 'ì',
  '��' => 'ō',
  '��' => 'ó',
  '��' => 'ǒ',
  '��' => 'ò',
  '��' => 'ū',
  '��' => 'ú',
  '��' => 'ǔ',
  '��' => 'ù',
  '��' => 'ǖ',
  '��' => 'ǘ',
  '��' => 'ǚ',
  '��' => 'ǜ',
  '��' => 'ü',
  '��' => 'ê',
  '��' => 'ɑ',
  '��' => 'ń',
  '��' => 'ň',
  '��' => 'ɡ',
  '��' => 'ㄅ',
  '��' => 'ㄆ',
  '��' => 'ㄇ',
  '��' => 'ㄈ',
  '��' => 'ㄉ',
  '��' => 'ㄊ',
  '��' => 'ㄋ',
  '��' => 'ㄌ',
  '��' => 'ㄍ',
  '��' => 'ㄎ',
  '��' => 'ㄏ',
  '��' => 'ㄐ',
  '��' => 'ㄑ',
  '��' => 'ㄒ',
  '��' => 'ㄓ',
  '��' => 'ㄔ',
  '��' => 'ㄕ',
  '��' => 'ㄖ',
  '��' => 'ㄗ',
  '��' => 'ㄘ',
  '��' => 'ㄙ',
  '��' => 'ㄚ',
  '��' => 'ㄛ',
  '��' => 'ㄜ',
  '��' => 'ㄝ',
  '��' => 'ㄞ',
  '��' => 'ㄟ',
  '��' => 'ㄠ',
  '��' => 'ㄡ',
  '��' => 'ㄢ',
  '��' => 'ㄣ',
  '��' => 'ㄤ',
  '��' => 'ㄥ',
  '��' => 'ㄦ',
  '��' => 'ㄧ',
  '��' => 'ㄨ',
  '��' => 'ㄩ',
  '�@' => '〡',
  '�A' => '〢',
  '�B' => '〣',
  '�C' => '〤',
  '�D' => '〥',
  '�E' => '〦',
  '�F' => '〧',
  '�G' => '〨',
  '�H' => '〩',
  '�I' => '㊣',
  '�J' => '㎎',
  '�K' => '㎏',
  '�L' => '㎜',
  '�M' => '㎝',
  '�N' => '㎞',
  '�O' => '㎡',
  '�P' => '㏄',
  '�Q' => '㏎',
  '�R' => '㏑',
  '�S' => '㏒',
  '�T' => '㏕',
  '�U' => '︰',
  '�V' => '¬',
  '�W' => '¦',
  '�Y' => '℡',
  '�Z' => '㈱',
  '�\\' => '‐',
  '�`' => 'ー',
  '�a' => '゛',
  '�b' => '゜',
  '�c' => 'ヽ',
  '�d' => 'ヾ',
  '�e' => '〆',
  '�f' => 'ゝ',
  '�g' => 'ゞ',
  '�h' => '﹉',
  '�i' => '﹊',
  '�j' => '﹋',
  '�k' => '﹌',
  '�l' => '﹍',
  '�m' => '﹎',
  '�n' => '﹏',
  '�o' => '﹐',
  '�p' => '﹑',
  '�q' => '﹒',
  '�r' => '﹔',
  '�s' => '﹕',
  '�t' => '﹖',
  '�u' => '﹗',
  '�v' => '﹙',
  '�w' => '﹚',
  '�x' => '﹛',
  '�y' => '﹜',
  '�z' => '﹝',
  '�{' => '﹞',
  '�|' => '﹟',
  '�}' => '﹠',
  '�~' => '﹡',
  '��' => '﹢',
  '��' => '﹣',
  '��' => '﹤',
  '��' => '﹥',
  '��' => '﹦',
  '��' => '﹨',
  '��' => '﹩',
  '��' => '﹪',
  '��' => '﹫',
  '��' => '〇',
  '��' => '─',
  '��' => '━',
  '��' => '│',
  '��' => '┃',
  '��' => '┄',
  '��' => '┅',
  '��' => '┆',
  '��' => '┇',
  '��' => '┈',
  '��' => '┉',
  '��' => '┊',
  '��' => '┋',
  '��' => '┌',
  '��' => '┍',
  '��' => '┎',
  '��' => '┏',
  '��' => '┐',
  '��' => '┑',
  '��' => '┒',
  '��' => '┓',
  '��' => '└',
  '��' => '┕',
  '��' => '┖',
  '��' => '┗',
  '��' => '┘',
  '��' => '┙',
  '��' => '┚',
  '��' => '┛',
  '��' => '├',
  '��' => '┝',
  '��' => '┞',
  '��' => '┟',
  '��' => '┠',
  '��' => '┡',
  '��' => '┢',
  '��' => '┣',
  '��' => '┤',
  '��' => '┥',
  '��' => '┦',
  '��' => '┧',
  '��' => '┨',
  '��' => '┩',
  '��' => '┪',
  '��' => '┫',
  '��' => '┬',
  '��' => '┭',
  '��' => '┮',
  '��' => '┯',
  '��' => '┰',
  '��' => '┱',
  '��' => '┲',
  '��' => '┳',
  '��' => '┴',
  '��' => '┵',
  '��' => '┶',
  '��' => '┷',
  '��' => '┸',
  '��' => '┹',
  '��' => '┺',
  '��' => '┻',
  '��' => '┼',
  '��' => '┽',
  '��' => '┾',
  '��' => '┿',
  '��' => '╀',
  '��' => '╁',
  '��' => '╂',
  '��' => '╃',
  '��' => '╄',
  '��' => '╅',
  '��' => '╆',
  '��' => '╇',
  '��' => '╈',
  '��' => '╉',
  '��' => '╊',
  '��' => '╋',
  '�@' => '狜',
  '�A' => '狝',
  '�B' => '狟',
  '�C' => '狢',
  '�D' => '狣',
  '�E' => '狤',
  '�F' => '狥',
  '�G' => '狦',
  '�H' => '狧',
  '�I' => '狪',
  '�J' => '狫',
  '�K' => '狵',
  '�L' => '狶',
  '�M' => '狹',
  '�N' => '狽',
  '�O' => '狾',
  '�P' => '狿',
  '�Q' => '猀',
  '�R' => '猂',
  '�S' => '猄',
  '�T' => '猅',
  '�U' => '猆',
  '�V' => '猇',
  '�W' => '猈',
  '�X' => '猉',
  '�Y' => '猋',
  '�Z' => '猌',
  '�[' => '猍',
  '�\\' => '猏',
  '�]' => '猐',
  '�^' => '猑',
  '�_' => '猒',
  '�`' => '猔',
  '�a' => '猘',
  '�b' => '猙',
  '�c' => '猚',
  '�d' => '猟',
  '�e' => '猠',
  '�f' => '猣',
  '�g' => '猤',
  '�h' => '猦',
  '�i' => '猧',
  '�j' => '猨',
  '�k' => '猭',
  '�l' => '猯',
  '�m' => '猰',
  '�n' => '猲',
  '�o' => '猳',
  '�p' => '猵',
  '�q' => '猶',
  '�r' => '猺',
  '�s' => '猻',
  '�t' => '猼',
  '�u' => '猽',
  '�v' => '獀',
  '�w' => '獁',
  '�x' => '獂',
  '�y' => '獃',
  '�z' => '獄',
  '�{' => '獅',
  '�|' => '獆',
  '�}' => '獇',
  '�~' => '獈',
  '��' => '獉',
  '��' => '獊',
  '��' => '獋',
  '��' => '獌',
  '��' => '獎',
  '��' => '獏',
  '��' => '獑',
  '��' => '獓',
  '��' => '獔',
  '��' => '獕',
  '��' => '獖',
  '��' => '獘',
  '��' => '獙',
  '��' => '獚',
  '��' => '獛',
  '��' => '獜',
  '��' => '獝',
  '��' => '獞',
  '��' => '獟',
  '��' => '獡',
  '��' => '獢',
  '��' => '獣',
  '��' => '獤',
  '��' => '獥',
  '��' => '獦',
  '��' => '獧',
  '��' => '獨',
  '��' => '獩',
  '��' => '獪',
  '��' => '獫',
  '��' => '獮',
  '��' => '獰',
  '��' => '獱',
  '�@' => '獲',
  '�A' => '獳',
  '�B' => '獴',
  '�C' => '獵',
  '�D' => '獶',
  '�E' => '獷',
  '�F' => '獸',
  '�G' => '獹',
  '�H' => '獺',
  '�I' => '獻',
  '�J' => '獼',
  '�K' => '獽',
  '�L' => '獿',
  '�M' => '玀',
  '�N' => '玁',
  '�O' => '玂',
  '�P' => '玃',
  '�Q' => '玅',
  '�R' => '玆',
  '�S' => '玈',
  '�T' => '玊',
  '�U' => '玌',
  '�V' => '玍',
  '�W' => '玏',
  '�X' => '玐',
  '�Y' => '玒',
  '�Z' => '玓',
  '�[' => '玔',
  '�\\' => '玕',
  '�]' => '玗',
  '�^' => '玘',
  '�_' => '玙',
  '�`' => '玚',
  '�a' => '玜',
  '�b' => '玝',
  '�c' => '玞',
  '�d' => '玠',
  '�e' => '玡',
  '�f' => '玣',
  '�g' => '玤',
  '�h' => '玥',
  '�i' => '玦',
  '�j' => '玧',
  '�k' => '玨',
  '�l' => '玪',
  '�m' => '玬',
  '�n' => '玭',
  '�o' => '玱',
  '�p' => '玴',
  '�q' => '玵',
  '�r' => '玶',
  '�s' => '玸',
  '�t' => '玹',
  '�u' => '玼',
  '�v' => '玽',
  '�w' => '玾',
  '�x' => '玿',
  '�y' => '珁',
  '�z' => '珃',
  '�{' => '珄',
  '�|' => '珅',
  '�}' => '珆',
  '�~' => '珇',
  '��' => '珋',
  '��' => '珌',
  '��' => '珎',
  '��' => '珒',
  '��' => '珓',
  '��' => '珔',
  '��' => '珕',
  '��' => '珖',
  '��' => '珗',
  '��' => '珘',
  '��' => '珚',
  '��' => '珛',
  '��' => '珜',
  '��' => '珝',
  '��' => '珟',
  '��' => '珡',
  '��' => '珢',
  '��' => '珣',
  '��' => '珤',
  '��' => '珦',
  '��' => '珨',
  '��' => '珪',
  '��' => '珫',
  '��' => '珬',
  '��' => '珮',
  '��' => '珯',
  '��' => '珰',
  '��' => '珱',
  '��' => '珳',
  '��' => '珴',
  '��' => '珵',
  '��' => '珶',
  '��' => '珷',
  '�@' => '珸',
  '�A' => '珹',
  '�B' => '珺',
  '�C' => '珻',
  '�D' => '珼',
  '�E' => '珽',
  '�F' => '現',
  '�G' => '珿',
  '�H' => '琀',
  '�I' => '琁',
  '�J' => '琂',
  '�K' => '琄',
  '�L' => '琇',
  '�M' => '琈',
  '�N' => '琋',
  '�O' => '琌',
  '�P' => '琍',
  '�Q' => '琎',
  '�R' => '琑',
  '�S' => '琒',
  '�T' => '琓',
  '�U' => '琔',
  '�V' => '琕',
  '�W' => '琖',
  '�X' => '琗',
  '�Y' => '琘',
  '�Z' => '琙',
  '�[' => '琜',
  '�\\' => '琝',
  '�]' => '琞',
  '�^' => '琟',
  '�_' => '琠',
  '�`' => '琡',
  '�a' => '琣',
  '�b' => '琤',
  '�c' => '琧',
  '�d' => '琩',
  '�e' => '琫',
  '�f' => '琭',
  '�g' => '琯',
  '�h' => '琱',
  '�i' => '琲',
  '�j' => '琷',
  '�k' => '琸',
  '�l' => '琹',
  '�m' => '琺',
  '�n' => '琻',
  '�o' => '琽',
  '�p' => '琾',
  '�q' => '琿',
  '�r' => '瑀',
  '�s' => '瑂',
  '�t' => '瑃',
  '�u' => '瑄',
  '�v' => '瑅',
  '�w' => '瑆',
  '�x' => '瑇',
  '�y' => '瑈',
  '�z' => '瑉',
  '�{' => '瑊',
  '�|' => '瑋',
  '�}' => '瑌',
  '�~' => '瑍',
  '��' => '瑎',
  '��' => '瑏',
  '��' => '瑐',
  '��' => '瑑',
  '��' => '瑒',
  '��' => '瑓',
  '��' => '瑔',
  '��' => '瑖',
  '��' => '瑘',
  '��' => '瑝',
  '��' => '瑠',
  '��' => '瑡',
  '��' => '瑢',
  '��' => '瑣',
  '��' => '瑤',
  '��' => '瑥',
  '��' => '瑦',
  '��' => '瑧',
  '��' => '瑨',
  '��' => '瑩',
  '��' => '瑪',
  '��' => '瑫',
  '��' => '瑬',
  '��' => '瑮',
  '��' => '瑯',
  '��' => '瑱',
  '��' => '瑲',
  '��' => '瑳',
  '��' => '瑴',
  '��' => '瑵',
  '��' => '瑸',
  '��' => '瑹',
  '��' => '瑺',
  '�@' => '瑻',
  '�A' => '瑼',
  '�B' => '瑽',
  '�C' => '瑿',
  '�D' => '璂',
  '�E' => '璄',
  '�F' => '璅',
  '�G' => '璆',
  '�H' => '璈',
  '�I' => '璉',
  '�J' => '璊',
  '�K' => '璌',
  '�L' => '璍',
  '�M' => '璏',
  '�N' => '璑',
  '�O' => '璒',
  '�P' => '璓',
  '�Q' => '璔',
  '�R' => '璕',
  '�S' => '璖',
  '�T' => '璗',
  '�U' => '璘',
  '�V' => '璙',
  '�W' => '璚',
  '�X' => '璛',
  '�Y' => '璝',
  '�Z' => '璟',
  '�[' => '璠',
  '�\\' => '璡',
  '�]' => '璢',
  '�^' => '璣',
  '�_' => '璤',
  '�`' => '璥',
  '�a' => '璦',
  '�b' => '璪',
  '�c' => '璫',
  '�d' => '璬',
  '�e' => '璭',
  '�f' => '璮',
  '�g' => '璯',
  '�h' => '環',
  '�i' => '璱',
  '�j' => '璲',
  '�k' => '璳',
  '�l' => '璴',
  '�m' => '璵',
  '�n' => '璶',
  '�o' => '璷',
  '�p' => '璸',
  '�q' => '璹',
  '�r' => '璻',
  '�s' => '璼',
  '�t' => '璽',
  '�u' => '璾',
  '�v' => '璿',
  '�w' => '瓀',
  '�x' => '瓁',
  '�y' => '瓂',
  '�z' => '瓃',
  '�{' => '瓄',
  '�|' => '瓅',
  '�}' => '瓆',
  '�~' => '瓇',
  '��' => '瓈',
  '��' => '瓉',
  '��' => '瓊',
  '��' => '瓋',
  '��' => '瓌',
  '��' => '瓍',
  '��' => '瓎',
  '��' => '瓏',
  '��' => '瓐',
  '��' => '瓑',
  '��' => '瓓',
  '��' => '瓔',
  '��' => '瓕',
  '��' => '瓖',
  '��' => '瓗',
  '��' => '瓘',
  '��' => '瓙',
  '��' => '瓚',
  '��' => '瓛',
  '��' => '瓝',
  '��' => '瓟',
  '��' => '瓡',
  '��' => '瓥',
  '��' => '瓧',
  '��' => '瓨',
  '��' => '瓩',
  '��' => '瓪',
  '��' => '瓫',
  '��' => '瓬',
  '��' => '瓭',
  '��' => '瓰',
  '��' => '瓱',
  '��' => '瓲',
  '�@' => '瓳',
  '�A' => '瓵',
  '�B' => '瓸',
  '�C' => '瓹',
  '�D' => '瓺',
  '�E' => '瓻',
  '�F' => '瓼',
  '�G' => '瓽',
  '�H' => '瓾',
  '�I' => '甀',
  '�J' => '甁',
  '�K' => '甂',
  '�L' => '甃',
  '�M' => '甅',
  '�N' => '甆',
  '�O' => '甇',
  '�P' => '甈',
  '�Q' => '甉',
  '�R' => '甊',
  '�S' => '甋',
  '�T' => '甌',
  '�U' => '甎',
  '�V' => '甐',
  '�W' => '甒',
  '�X' => '甔',
  '�Y' => '甕',
  '�Z' => '甖',
  '�[' => '甗',
  '�\\' => '甛',
  '�]' => '甝',
  '�^' => '甞',
  '�_' => '甠',
  '�`' => '甡',
  '�a' => '產',
  '�b' => '産',
  '�c' => '甤',
  '�d' => '甦',
  '�e' => '甧',
  '�f' => '甪',
  '�g' => '甮',
  '�h' => '甴',
  '�i' => '甶',
  '�j' => '甹',
  '�k' => '甼',
  '�l' => '甽',
  '�m' => '甿',
  '�n' => '畁',
  '�o' => '畂',
  '�p' => '畃',
  '�q' => '畄',
  '�r' => '畆',
  '�s' => '畇',
  '�t' => '畉',
  '�u' => '畊',
  '�v' => '畍',
  '�w' => '畐',
  '�x' => '畑',
  '�y' => '畒',
  '�z' => '畓',
  '�{' => '畕',
  '�|' => '畖',
  '�}' => '畗',
  '�~' => '畘',
  '��' => '畝',
  '��' => '畞',
  '��' => '畟',
  '��' => '畠',
  '��' => '畡',
  '��' => '畢',
  '��' => '畣',
  '��' => '畤',
  '��' => '畧',
  '��' => '畨',
  '��' => '畩',
  '��' => '畫',
  '��' => '畬',
  '��' => '畭',
  '��' => '畮',
  '��' => '畯',
  '��' => '異',
  '��' => '畱',
  '��' => '畳',
  '��' => '畵',
  '��' => '當',
  '��' => '畷',
  '��' => '畺',
  '��' => '畻',
  '��' => '畼',
  '��' => '畽',
  '��' => '畾',
  '��' => '疀',
  '��' => '疁',
  '��' => '疂',
  '��' => '疄',
  '��' => '疅',
  '��' => '疇',
  '�@' => '疈',
  '�A' => '疉',
  '�B' => '疊',
  '�C' => '疌',
  '�D' => '疍',
  '�E' => '疎',
  '�F' => '疐',
  '�G' => '疓',
  '�H' => '疕',
  '�I' => '疘',
  '�J' => '疛',
  '�K' => '疜',
  '�L' => '疞',
  '�M' => '疢',
  '�N' => '疦',
  '�O' => '疧',
  '�P' => '疨',
  '�Q' => '疩',
  '�R' => '疪',
  '�S' => '疭',
  '�T' => '疶',
  '�U' => '疷',
  '�V' => '疺',
  '�W' => '疻',
  '�X' => '疿',
  '�Y' => '痀',
  '�Z' => '痁',
  '�[' => '痆',
  '�\\' => '痋',
  '�]' => '痌',
  '�^' => '痎',
  '�_' => '痏',
  '�`' => '痐',
  '�a' => '痑',
  '�b' => '痓',
  '�c' => '痗',
  '�d' => '痙',
  '�e' => '痚',
  '�f' => '痜',
  '�g' => '痝',
  '�h' => '痟',
  '�i' => '痠',
  '�j' => '痡',
  '�k' => '痥',
  '�l' => '痩',
  '�m' => '痬',
  '�n' => '痭',
  '�o' => '痮',
  '�p' => '痯',
  '�q' => '痲',
  '�r' => '痳',
  '�s' => '痵',
  '�t' => '痶',
  '�u' => '痷',
  '�v' => '痸',
  '�w' => '痺',
  '�x' => '痻',
  '�y' => '痽',
  '�z' => '痾',
  '�{' => '瘂',
  '�|' => '瘄',
  '�}' => '瘆',
  '�~' => '瘇',
  '��' => '瘈',
  '��' => '瘉',
  '��' => '瘋',
  '��' => '瘍',
  '��' => '瘎',
  '��' => '瘏',
  '��' => '瘑',
  '��' => '瘒',
  '��' => '瘓',
  '��' => '瘔',
  '��' => '瘖',
  '��' => '瘚',
  '��' => '瘜',
  '��' => '瘝',
  '��' => '瘞',
  '��' => '瘡',
  '��' => '瘣',
  '��' => '瘧',
  '��' => '瘨',
  '��' => '瘬',
  '��' => '瘮',
  '��' => '瘯',
  '��' => '瘱',
  '��' => '瘲',
  '��' => '瘶',
  '��' => '瘷',
  '��' => '瘹',
  '��' => '瘺',
  '��' => '瘻',
  '��' => '瘽',
  '��' => '癁',
  '��' => '療',
  '��' => '癄',
  '�@' => '癅',
  '�A' => '癆',
  '�B' => '癇',
  '�C' => '癈',
  '�D' => '癉',
  '�E' => '癊',
  '�F' => '癋',
  '�G' => '癎',
  '�H' => '癏',
  '�I' => '癐',
  '�J' => '癑',
  '�K' => '癒',
  '�L' => '癓',
  '�M' => '癕',
  '�N' => '癗',
  '�O' => '癘',
  '�P' => '癙',
  '�Q' => '癚',
  '�R' => '癛',
  '�S' => '癝',
  '�T' => '癟',
  '�U' => '癠',
  '�V' => '癡',
  '�W' => '癢',
  '�X' => '癤',
  '�Y' => '癥',
  '�Z' => '癦',
  '�[' => '癧',
  '�\\' => '癨',
  '�]' => '癩',
  '�^' => '癪',
  '�_' => '癬',
  '�`' => '癭',
  '�a' => '癮',
  '�b' => '癰',
  '�c' => '癱',
  '�d' => '癲',
  '�e' => '癳',
  '�f' => '癴',
  '�g' => '癵',
  '�h' => '癶',
  '�i' => '癷',
  '�j' => '癹',
  '�k' => '発',
  '�l' => '發',
  '�m' => '癿',
  '�n' => '皀',
  '�o' => '皁',
  '�p' => '皃',
  '�q' => '皅',
  '�r' => '皉',
  '�s' => '皊',
  '�t' => '皌',
  '�u' => '皍',
  '�v' => '皏',
  '�w' => '皐',
  '�x' => '皒',
  '�y' => '皔',
  '�z' => '皕',
  '�{' => '皗',
  '�|' => '皘',
  '�}' => '皚',
  '�~' => '皛',
  '��' => '皜',
  '��' => '皝',
  '��' => '皞',
  '��' => '皟',
  '��' => '皠',
  '��' => '皡',
  '��' => '皢',
  '��' => '皣',
  '��' => '皥',
  '��' => '皦',
  '��' => '皧',
  '��' => '皨',
  '��' => '皩',
  '��' => '皪',
  '��' => '皫',
  '��' => '皬',
  '��' => '皭',
  '��' => '皯',
  '��' => '皰',
  '��' => '皳',
  '��' => '皵',
  '��' => '皶',
  '��' => '皷',
  '��' => '皸',
  '��' => '皹',
  '��' => '皺',
  '��' => '皻',
  '��' => '皼',
  '��' => '皽',
  '��' => '皾',
  '��' => '盀',
  '��' => '盁',
  '��' => '盃',
  '��' => '啊',
  '��' => '阿',
  '��' => '埃',
  '��' => '挨',
  '��' => '哎',
  '��' => '唉',
  '��' => '哀',
  '��' => '皑',
  '��' => '癌',
  '��' => '蔼',
  '��' => '矮',
  '��' => '艾',
  '��' => '碍',
  '��' => '爱',
  '��' => '隘',
  '��' => '鞍',
  '��' => '氨',
  '��' => '安',
  '��' => '俺',
  '��' => '按',
  '��' => '暗',
  '��' => '岸',
  '��' => '胺',
  '��' => '案',
  '��' => '肮',
  '��' => '昂',
  '��' => '盎',
  '��' => '凹',
  '��' => '敖',
  '��' => '熬',
  '��' => '翱',
  '��' => '袄',
  '��' => '傲',
  '��' => '奥',
  '��' => '懊',
  '��' => '澳',
  '��' => '芭',
  '��' => '捌',
  '��' => '扒',
  '��' => '叭',
  '��' => '吧',
  '��' => '笆',
  '��' => '八',
  '��' => '疤',
  '��' => '巴',
  '��' => '拔',
  '��' => '跋',
  '��' => '靶',
  '��' => '把',
  '��' => '耙',
  '��' => '坝',
  '��' => '霸',
  '��' => '罢',
  '��' => '爸',
  '��' => '白',
  '��' => '柏',
  '��' => '百',
  '��' => '摆',
  '��' => '佰',
  '��' => '败',
  '��' => '拜',
  '��' => '稗',
  '��' => '斑',
  '��' => '班',
  '��' => '搬',
  '��' => '扳',
  '��' => '般',
  '��' => '颁',
  '��' => '板',
  '��' => '版',
  '��' => '扮',
  '��' => '拌',
  '��' => '伴',
  '��' => '瓣',
  '��' => '半',
  '��' => '办',
  '��' => '绊',
  '��' => '邦',
  '��' => '帮',
  '��' => '梆',
  '��' => '榜',
  '��' => '膀',
  '��' => '绑',
  '��' => '棒',
  '��' => '磅',
  '��' => '蚌',
  '��' => '镑',
  '��' => '傍',
  '��' => '谤',
  '��' => '苞',
  '��' => '胞',
  '��' => '包',
  '��' => '褒',
  '��' => '剥',
  '�@' => '盄',
  '�A' => '盇',
  '�B' => '盉',
  '�C' => '盋',
  '�D' => '盌',
  '�E' => '盓',
  '�F' => '盕',
  '�G' => '盙',
  '�H' => '盚',
  '�I' => '盜',
  '�J' => '盝',
  '�K' => '盞',
  '�L' => '盠',
  '�M' => '盡',
  '�N' => '盢',
  '�O' => '監',
  '�P' => '盤',
  '�Q' => '盦',
  '�R' => '盧',
  '�S' => '盨',
  '�T' => '盩',
  '�U' => '盪',
  '�V' => '盫',
  '�W' => '盬',
  '�X' => '盭',
  '�Y' => '盰',
  '�Z' => '盳',
  '�[' => '盵',
  '�\\' => '盶',
  '�]' => '盷',
  '�^' => '盺',
  '�_' => '盻',
  '�`' => '盽',
  '�a' => '盿',
  '�b' => '眀',
  '�c' => '眂',
  '�d' => '眃',
  '�e' => '眅',
  '�f' => '眆',
  '�g' => '眊',
  '�h' => '県',
  '�i' => '眎',
  '�j' => '眏',
  '�k' => '眐',
  '�l' => '眑',
  '�m' => '眒',
  '�n' => '眓',
  '�o' => '眔',
  '�p' => '眕',
  '�q' => '眖',
  '�r' => '眗',
  '�s' => '眘',
  '�t' => '眛',
  '�u' => '眜',
  '�v' => '眝',
  '�w' => '眞',
  '�x' => '眡',
  '�y' => '眣',
  '�z' => '眤',
  '�{' => '眥',
  '�|' => '眧',
  '�}' => '眪',
  '�~' => '眫',
  '��' => '眬',
  '��' => '眮',
  '��' => '眰',
  '��' => '眱',
  '��' => '眲',
  '��' => '眳',
  '��' => '眴',
  '��' => '眹',
  '��' => '眻',
  '��' => '眽',
  '��' => '眾',
  '��' => '眿',
  '��' => '睂',
  '��' => '睄',
  '��' => '睅',
  '��' => '睆',
  '��' => '睈',
  '��' => '睉',
  '��' => '睊',
  '��' => '睋',
  '��' => '睌',
  '��' => '睍',
  '��' => '睎',
  '��' => '睏',
  '��' => '睒',
  '��' => '睓',
  '��' => '睔',
  '��' => '睕',
  '��' => '睖',
  '��' => '睗',
  '��' => '睘',
  '��' => '睙',
  '��' => '睜',
  '��' => '薄',
  '��' => '雹',
  '��' => '保',
  '��' => '堡',
  '��' => '饱',
  '��' => '宝',
  '��' => '抱',
  '��' => '报',
  '��' => '暴',
  '��' => '豹',
  '��' => '鲍',
  '��' => '爆',
  '��' => '杯',
  '��' => '碑',
  '��' => '悲',
  '��' => '卑',
  '��' => '北',
  '��' => '辈',
  '��' => '背',
  '��' => '贝',
  '��' => '钡',
  '��' => '倍',
  '��' => '狈',
  '��' => '备',
  '��' => '惫',
  '��' => '焙',
  '��' => '被',
  '��' => '奔',
  '��' => '苯',
  '��' => '本',
  '��' => '笨',
  '��' => '崩',
  '��' => '绷',
  '��' => '甭',
  '��' => '泵',
  '��' => '蹦',
  '��' => '迸',
  '��' => '逼',
  '��' => '鼻',
  '��' => '比',
  '��' => '鄙',
  '��' => '笔',
  '��' => '彼',
  '��' => '碧',
  '��' => '蓖',
  '��' => '蔽',
  '��' => '毕',
  '��' => '毙',
  '��' => '毖',
  '��' => '币',
  '��' => '庇',
  '��' => '痹',
  '��' => '闭',
  '��' => '敝',
  '��' => '弊',
  '��' => '必',
  '��' => '辟',
  '��' => '壁',
  '��' => '臂',
  '��' => '避',
  '��' => '陛',
  '��' => '鞭',
  '��' => '边',
  '��' => '编',
  '��' => '贬',
  '��' => '扁',
  '��' => '便',
  '��' => '变',
  '��' => '卞',
  '��' => '辨',
  '��' => '辩',
  '��' => '辫',
  '��' => '遍',
  '��' => '标',
  '��' => '彪',
  '��' => '膘',
  '��' => '表',
  '��' => '鳖',
  '��' => '憋',
  '��' => '别',
  '��' => '瘪',
  '��' => '彬',
  '��' => '斌',
  '��' => '濒',
  '��' => '滨',
  '��' => '宾',
  '��' => '摈',
  '��' => '兵',
  '��' => '冰',
  '��' => '柄',
  '��' => '丙',
  '��' => '秉',
  '��' => '饼',
  '��' => '炳',
  '�@' => '睝',
  '�A' => '睞',
  '�B' => '睟',
  '�C' => '睠',
  '�D' => '睤',
  '�E' => '睧',
  '�F' => '睩',
  '�G' => '睪',
  '�H' => '睭',
  '�I' => '睮',
  '�J' => '睯',
  '�K' => '睰',
  '�L' => '睱',
  '�M' => '睲',
  '�N' => '睳',
  '�O' => '睴',
  '�P' => '睵',
  '�Q' => '睶',
  '�R' => '睷',
  '�S' => '睸',
  '�T' => '睺',
  '�U' => '睻',
  '�V' => '睼',
  '�W' => '瞁',
  '�X' => '瞂',
  '�Y' => '瞃',
  '�Z' => '瞆',
  '�[' => '瞇',
  '�\\' => '瞈',
  '�]' => '瞉',
  '�^' => '瞊',
  '�_' => '瞋',
  '�`' => '瞏',
  '�a' => '瞐',
  '�b' => '瞓',
  '�c' => '瞔',
  '�d' => '瞕',
  '�e' => '瞖',
  '�f' => '瞗',
  '�g' => '瞘',
  '�h' => '瞙',
  '�i' => '瞚',
  '�j' => '瞛',
  '�k' => '瞜',
  '�l' => '瞝',
  '�m' => '瞞',
  '�n' => '瞡',
  '�o' => '瞣',
  '�p' => '瞤',
  '�q' => '瞦',
  '�r' => '瞨',
  '�s' => '瞫',
  '�t' => '瞭',
  '�u' => '瞮',
  '�v' => '瞯',
  '�w' => '瞱',
  '�x' => '瞲',
  '�y' => '瞴',
  '�z' => '瞶',
  '�{' => '瞷',
  '�|' => '瞸',
  '�}' => '瞹',
  '�~' => '瞺',
  '��' => '瞼',
  '��' => '瞾',
  '��' => '矀',
  '��' => '矁',
  '��' => '矂',
  '��' => '矃',
  '��' => '矄',
  '��' => '矅',
  '��' => '矆',
  '��' => '矇',
  '��' => '矈',
  '��' => '矉',
  '��' => '矊',
  '��' => '矋',
  '��' => '矌',
  '��' => '矎',
  '��' => '矏',
  '��' => '矐',
  '��' => '矑',
  '��' => '矒',
  '��' => '矓',
  '��' => '矔',
  '��' => '矕',
  '��' => '矖',
  '��' => '矘',
  '��' => '矙',
  '��' => '矚',
  '��' => '矝',
  '��' => '矞',
  '��' => '矟',
  '��' => '矠',
  '��' => '矡',
  '��' => '矤',
  '��' => '病',
  '��' => '并',
  '��' => '玻',
  '��' => '菠',
  '��' => '播',
  '��' => '拨',
  '��' => '钵',
  '��' => '波',
  '��' => '博',
  '��' => '勃',
  '��' => '搏',
  '��' => '铂',
  '��' => '箔',
  '��' => '伯',
  '��' => '帛',
  '��' => '舶',
  '��' => '脖',
  '��' => '膊',
  '��' => '渤',
  '��' => '泊',
  '��' => '驳',
  '��' => '捕',
  '��' => '卜',
  '��' => '哺',
  '��' => '补',
  '��' => '埠',
  '��' => '不',
  '��' => '布',
  '��' => '步',
  '��' => '簿',
  '��' => '部',
  '��' => '怖',
  '��' => '擦',
  '��' => '猜',
  '��' => '裁',
  '��' => '材',
  '��' => '才',
  '��' => '财',
  '��' => '睬',
  '��' => '踩',
  '��' => '采',
  '��' => '彩',
  '��' => '菜',
  '��' => '蔡',
  '��' => '餐',
  '��' => '参',
  '��' => '蚕',
  '��' => '残',
  '��' => '惭',
  '��' => '惨',
  '��' => '灿',
  '��' => '苍',
  '��' => '舱',
  '��' => '仓',
  '��' => '沧',
  '��' => '藏',
  '��' => '操',
  '��' => '糙',
  '��' => '槽',
  '��' => '曹',
  '��' => '草',
  '��' => '厕',
  '��' => '策',
  '��' => '侧',
  '��' => '册',
  '��' => '测',
  '��' => '层',
  '��' => '蹭',
  '��' => '插',
  '��' => '叉',
  '��' => '茬',
  '��' => '茶',
  '��' => '查',
  '��' => '碴',
  '��' => '搽',
  '��' => '察',
  '��' => '岔',
  '��' => '差',
  '��' => '诧',
  '��' => '拆',
  '��' => '柴',
  '��' => '豺',
  '��' => '搀',
  '��' => '掺',
  '��' => '蝉',
  '��' => '馋',
  '��' => '谗',
  '��' => '缠',
  '��' => '铲',
  '��' => '产',
  '��' => '阐',
  '��' => '颤',
  '��' => '昌',
  '��' => '猖',
  '�@' => '矦',
  '�A' => '矨',
  '�B' => '矪',
  '�C' => '矯',
  '�D' => '矰',
  '�E' => '矱',
  '�F' => '矲',
  '�G' => '矴',
  '�H' => '矵',
  '�I' => '矷',
  '�J' => '矹',
  '�K' => '矺',
  '�L' => '矻',
  '�M' => '矼',
  '�N' => '砃',
  '�O' => '砄',
  '�P' => '砅',
  '�Q' => '砆',
  '�R' => '砇',
  '�S' => '砈',
  '�T' => '砊',
  '�U' => '砋',
  '�V' => '砎',
  '�W' => '砏',
  '�X' => '砐',
  '�Y' => '砓',
  '�Z' => '砕',
  '�[' => '砙',
  '�\\' => '砛',
  '�]' => '砞',
  '�^' => '砠',
  '�_' => '砡',
  '�`' => '砢',
  '�a' => '砤',
  '�b' => '砨',
  '�c' => '砪',
  '�d' => '砫',
  '�e' => '砮',
  '�f' => '砯',
  '�g' => '砱',
  '�h' => '砲',
  '�i' => '砳',
  '�j' => '砵',
  '�k' => '砶',
  '�l' => '砽',
  '�m' => '砿',
  '�n' => '硁',
  '�o' => '硂',
  '�p' => '硃',
  '�q' => '硄',
  '�r' => '硆',
  '�s' => '硈',
  '�t' => '硉',
  '�u' => '硊',
  '�v' => '硋',
  '�w' => '硍',
  '�x' => '硏',
  '�y' => '硑',
  '�z' => '硓',
  '�{' => '硔',
  '�|' => '硘',
  '�}' => '硙',
  '�~' => '硚',
  '��' => '硛',
  '��' => '硜',
  '��' => '硞',
  '��' => '硟',
  '��' => '硠',
  '��' => '硡',
  '��' => '硢',
  '��' => '硣',
  '��' => '硤',
  '��' => '硥',
  '��' => '硦',
  '��' => '硧',
  '��' => '硨',
  '��' => '硩',
  '��' => '硯',
  '��' => '硰',
  '��' => '硱',
  '��' => '硲',
  '��' => '硳',
  '��' => '硴',
  '��' => '硵',
  '��' => '硶',
  '��' => '硸',
  '��' => '硹',
  '��' => '硺',
  '��' => '硻',
  '��' => '硽',
  '��' => '硾',
  '��' => '硿',
  '��' => '碀',
  '��' => '碁',
  '��' => '碂',
  '��' => '碃',
  '��' => '场',
  '��' => '尝',
  '��' => '常',
  '��' => '长',
  '��' => '偿',
  '��' => '肠',
  '��' => '厂',
  '��' => '敞',
  '��' => '畅',
  '��' => '唱',
  '��' => '倡',
  '��' => '超',
  '��' => '抄',
  '��' => '钞',
  '��' => '朝',
  '��' => '嘲',
  '��' => '潮',
  '��' => '巢',
  '��' => '吵',
  '��' => '炒',
  '��' => '车',
  '��' => '扯',
  '��' => '撤',
  '��' => '掣',
  '��' => '彻',
  '��' => '澈',
  '��' => '郴',
  '��' => '臣',
  '��' => '辰',
  '��' => '尘',
  '��' => '晨',
  '��' => '忱',
  '��' => '沉',
  '��' => '陈',
  '��' => '趁',
  '��' => '衬',
  '��' => '撑',
  '��' => '称',
  '��' => '城',
  '��' => '橙',
  '��' => '成',
  '��' => '呈',
  '��' => '乘',
  '��' => '程',
  '��' => '惩',
  '��' => '澄',
  '��' => '诚',
  '��' => '承',
  '��' => '逞',
  '��' => '骋',
  '��' => '秤',
  '��' => '吃',
  '��' => '痴',
  '��' => '持',
  '��' => '匙',
  '��' => '池',
  '��' => '迟',
  '��' => '弛',
  '��' => '驰',
  '��' => '耻',
  '��' => '齿',
  '��' => '侈',
  '��' => '尺',
  '��' => '赤',
  '��' => '翅',
  '��' => '斥',
  '��' => '炽',
  '��' => '充',
  '��' => '冲',
  '��' => '虫',
  '��' => '崇',
  '��' => '宠',
  '��' => '抽',
  '��' => '酬',
  '��' => '畴',
  '��' => '踌',
  '��' => '稠',
  '��' => '愁',
  '��' => '筹',
  '��' => '仇',
  '��' => '绸',
  '��' => '瞅',
  '��' => '丑',
  '��' => '臭',
  '��' => '初',
  '��' => '出',
  '��' => '橱',
  '��' => '厨',
  '��' => '躇',
  '��' => '锄',
  '��' => '雏',
  '��' => '滁',
  '��' => '除',
  '��' => '楚',
  '�@' => '碄',
  '�A' => '碅',
  '�B' => '碆',
  '�C' => '碈',
  '�D' => '碊',
  '�E' => '碋',
  '�F' => '碏',
  '�G' => '碐',
  '�H' => '碒',
  '�I' => '碔',
  '�J' => '碕',
  '�K' => '碖',
  '�L' => '碙',
  '�M' => '碝',
  '�N' => '碞',
  '�O' => '碠',
  '�P' => '碢',
  '�Q' => '碤',
  '�R' => '碦',
  '�S' => '碨',
  '�T' => '碩',
  '�U' => '碪',
  '�V' => '碫',
  '�W' => '碬',
  '�X' => '碭',
  '�Y' => '碮',
  '�Z' => '碯',
  '�[' => '碵',
  '�\\' => '碶',
  '�]' => '碷',
  '�^' => '碸',
  '�_' => '確',
  '�`' => '碻',
  '�a' => '碼',
  '�b' => '碽',
  '�c' => '碿',
  '�d' => '磀',
  '�e' => '磂',
  '�f' => '磃',
  '�g' => '磄',
  '�h' => '磆',
  '�i' => '磇',
  '�j' => '磈',
  '�k' => '磌',
  '�l' => '磍',
  '�m' => '磎',
  '�n' => '磏',
  '�o' => '磑',
  '�p' => '磒',
  '�q' => '磓',
  '�r' => '磖',
  '�s' => '磗',
  '�t' => '磘',
  '�u' => '磚',
  '�v' => '磛',
  '�w' => '磜',
  '�x' => '磝',
  '�y' => '磞',
  '�z' => '磟',
  '�{' => '磠',
  '�|' => '磡',
  '�}' => '磢',
  '�~' => '磣',
  '��' => '磤',
  '��' => '磥',
  '��' => '磦',
  '��' => '磧',
  '��' => '磩',
  '��' => '磪',
  '��' => '磫',
  '��' => '磭',
  '��' => '磮',
  '��' => '磯',
  '��' => '磰',
  '��' => '磱',
  '��' => '磳',
  '��' => '磵',
  '��' => '磶',
  '��' => '磸',
  '��' => '磹',
  '��' => '磻',
  '��' => '磼',
  '��' => '磽',
  '��' => '磾',
  '��' => '磿',
  '��' => '礀',
  '��' => '礂',
  '��' => '礃',
  '��' => '礄',
  '��' => '礆',
  '��' => '礇',
  '��' => '礈',
  '��' => '礉',
  '��' => '礊',
  '��' => '礋',
  '��' => '礌',
  '��' => '础',
  '��' => '储',
  '��' => '矗',
  '��' => '搐',
  '��' => '触',
  '��' => '处',
  '��' => '揣',
  '��' => '川',
  '��' => '穿',
  '��' => '椽',
  '��' => '传',
  '��' => '船',
  '��' => '喘',
  '��' => '串',
  '��' => '疮',
  '��' => '窗',
  '��' => '幢',
  '��' => '床',
  '��' => '闯',
  '��' => '创',
  '��' => '吹',
  '��' => '炊',
  '��' => '捶',
  '��' => '锤',
  '��' => '垂',
  '��' => '春',
  '��' => '椿',
  '��' => '醇',
  '��' => '唇',
  '��' => '淳',
  '��' => '纯',
  '��' => '蠢',
  '��' => '戳',
  '��' => '绰',
  '��' => '疵',
  '��' => '茨',
  '��' => '磁',
  '��' => '雌',
  '��' => '辞',
  '��' => '慈',
  '��' => '瓷',
  '��' => '词',
  '��' => '此',
  '��' => '刺',
  '��' => '赐',
  '��' => '次',
  '��' => '聪',
  '��' => '葱',
  '��' => '囱',
  '��' => '匆',
  '��' => '从',
  '��' => '丛',
  '��' => '凑',
  '��' => '粗',
  '��' => '醋',
  '��' => '簇',
  '��' => '促',
  '��' => '蹿',
  '��' => '篡',
  '��' => '窜',
  '��' => '摧',
  '��' => '崔',
  '��' => '催',
  '��' => '脆',
  '��' => '瘁',
  '��' => '粹',
  '��' => '淬',
  '��' => '翠',
  '��' => '村',
  '��' => '存',
  '��' => '寸',
  '��' => '磋',
  '��' => '撮',
  '��' => '搓',
  '��' => '措',
  '��' => '挫',
  '��' => '错',
  '��' => '搭',
  '��' => '达',
  '��' => '答',
  '��' => '瘩',
  '��' => '打',
  '��' => '大',
  '��' => '呆',
  '��' => '歹',
  '��' => '傣',
  '��' => '戴',
  '��' => '带',
  '��' => '殆',
  '��' => '代',
  '��' => '贷',
  '��' => '袋',
  '��' => '待',
  '��' => '逮',
  '�@' => '礍',
  '�A' => '礎',
  '�B' => '礏',
  '�C' => '礐',
  '�D' => '礑',
  '�E' => '礒',
  '�F' => '礔',
  '�G' => '礕',
  '�H' => '礖',
  '�I' => '礗',
  '�J' => '礘',
  '�K' => '礙',
  '�L' => '礚',
  '�M' => '礛',
  '�N' => '礜',
  '�O' => '礝',
  '�P' => '礟',
  '�Q' => '礠',
  '�R' => '礡',
  '�S' => '礢',
  '�T' => '礣',
  '�U' => '礥',
  '�V' => '礦',
  '�W' => '礧',
  '�X' => '礨',
  '�Y' => '礩',
  '�Z' => '礪',
  '�[' => '礫',
  '�\\' => '礬',
  '�]' => '礭',
  '�^' => '礮',
  '�_' => '礯',
  '�`' => '礰',
  '�a' => '礱',
  '�b' => '礲',
  '�c' => '礳',
  '�d' => '礵',
  '�e' => '礶',
  '�f' => '礷',
  '�g' => '礸',
  '�h' => '礹',
  '�i' => '礽',
  '�j' => '礿',
  '�k' => '祂',
  '�l' => '祃',
  '�m' => '祄',
  '�n' => '祅',
  '�o' => '祇',
  '�p' => '祊',
  '�q' => '祋',
  '�r' => '祌',
  '�s' => '祍',
  '�t' => '祎',
  '�u' => '祏',
  '�v' => '祐',
  '�w' => '祑',
  '�x' => '祒',
  '�y' => '祔',
  '�z' => '祕',
  '�{' => '祘',
  '�|' => '祙',
  '�}' => '祡',
  '�~' => '祣',
  '��' => '祤',
  '��' => '祦',
  '��' => '祩',
  '��' => '祪',
  '��' => '祫',
  '��' => '祬',
  '��' => '祮',
  '��' => '祰',
  '��' => '祱',
  '��' => '祲',
  '��' => '祳',
  '��' => '祴',
  '��' => '祵',
  '��' => '祶',
  '��' => '祹',
  '��' => '祻',
  '��' => '祼',
  '��' => '祽',
  '��' => '祾',
  '��' => '祿',
  '��' => '禂',
  '��' => '禃',
  '��' => '禆',
  '��' => '禇',
  '��' => '禈',
  '��' => '禉',
  '��' => '禋',
  '��' => '禌',
  '��' => '禍',
  '��' => '禎',
  '��' => '禐',
  '��' => '禑',
  '��' => '禒',
  '��' => '怠',
  '��' => '耽',
  '��' => '担',
  '��' => '丹',
  '��' => '单',
  '��' => '郸',
  '��' => '掸',
  '��' => '胆',
  '��' => '旦',
  '��' => '氮',
  '��' => '但',
  '��' => '惮',
  '��' => '淡',
  '��' => '诞',
  '��' => '弹',
  '��' => '蛋',
  '��' => '当',
  '��' => '挡',
  '��' => '党',
  '��' => '荡',
  '��' => '档',
  '��' => '刀',
  '��' => '捣',
  '��' => '蹈',
  '��' => '倒',
  '��' => '岛',
  '��' => '祷',
  '��' => '导',
  '��' => '到',
  '��' => '稻',
  '��' => '悼',
  '��' => '道',
  '��' => '盗',
  '��' => '德',
  '��' => '得',
  '��' => '的',
  '��' => '蹬',
  '��' => '灯',
  '��' => '登',
  '��' => '等',
  '��' => '瞪',
  '��' => '凳',
  '��' => '邓',
  '��' => '堤',
  '��' => '低',
  '��' => '滴',
  '��' => '迪',
  '��' => '敌',
  '��' => '笛',
  '��' => '狄',
  '��' => '涤',
  '��' => '翟',
  '��' => '嫡',
  '��' => '抵',
  '��' => '底',
  '��' => '地',
  '��' => '蒂',
  '��' => '第',
  '��' => '帝',
  '��' => '弟',
  '��' => '递',
  '��' => '缔',
  '��' => '颠',
  '��' => '掂',
  '��' => '滇',
  '��' => '碘',
  '��' => '点',
  '��' => '典',
  '��' => '靛',
  '��' => '垫',
  '��' => '电',
  '��' => '佃',
  '��' => '甸',
  '��' => '店',
  '��' => '惦',
  '��' => '奠',
  '��' => '淀',
  '��' => '殿',
  '��' => '碉',
  '��' => '叼',
  '��' => '雕',
  '��' => '凋',
  '��' => '刁',
  '��' => '掉',
  '��' => '吊',
  '��' => '钓',
  '��' => '调',
  '��' => '跌',
  '��' => '爹',
  '��' => '碟',
  '��' => '蝶',
  '��' => '迭',
  '��' => '谍',
  '��' => '叠',
  '�@' => '禓',
  '�A' => '禔',
  '�B' => '禕',
  '�C' => '禖',
  '�D' => '禗',
  '�E' => '禘',
  '�F' => '禙',
  '�G' => '禛',
  '�H' => '禜',
  '�I' => '禝',
  '�J' => '禞',
  '�K' => '禟',
  '�L' => '禠',
  '�M' => '禡',
  '�N' => '禢',
  '�O' => '禣',
  '�P' => '禤',
  '�Q' => '禥',
  '�R' => '禦',
  '�S' => '禨',
  '�T' => '禩',
  '�U' => '禪',
  '�V' => '禫',
  '�W' => '禬',
  '�X' => '禭',
  '�Y' => '禮',
  '�Z' => '禯',
  '�[' => '禰',
  '�\\' => '禱',
  '�]' => '禲',
  '�^' => '禴',
  '�_' => '禵',
  '�`' => '禶',
  '�a' => '禷',
  '�b' => '禸',
  '�c' => '禼',
  '�d' => '禿',
  '�e' => '秂',
  '�f' => '秄',
  '�g' => '秅',
  '�h' => '秇',
  '�i' => '秈',
  '�j' => '秊',
  '�k' => '秌',
  '�l' => '秎',
  '�m' => '秏',
  '�n' => '秐',
  '�o' => '秓',
  '�p' => '秔',
  '�q' => '秖',
  '�r' => '秗',
  '�s' => '秙',
  '�t' => '秚',
  '�u' => '秛',
  '�v' => '秜',
  '�w' => '秝',
  '�x' => '秞',
  '�y' => '秠',
  '�z' => '秡',
  '�{' => '秢',
  '�|' => '秥',
  '�}' => '秨',
  '�~' => '秪',
  '��' => '秬',
  '��' => '秮',
  '��' => '秱',
  '��' => '秲',
  '��' => '秳',
  '��' => '秴',
  '��' => '秵',
  '��' => '秶',
  '��' => '秷',
  '��' => '秹',
  '��' => '秺',
  '��' => '秼',
  '��' => '秾',
  '��' => '秿',
  '��' => '稁',
  '��' => '稄',
  '��' => '稅',
  '��' => '稇',
  '��' => '稈',
  '��' => '稉',
  '��' => '稊',
  '��' => '稌',
  '��' => '稏',
  '��' => '稐',
  '��' => '稑',
  '��' => '稒',
  '��' => '稓',
  '��' => '稕',
  '��' => '稖',
  '��' => '稘',
  '��' => '稙',
  '��' => '稛',
  '��' => '稜',
  '��' => '丁',
  '��' => '盯',
  '��' => '叮',
  '��' => '钉',
  '��' => '顶',
  '��' => '鼎',
  '��' => '锭',
  '��' => '定',
  '��' => '订',
  '��' => '丢',
  '��' => '东',
  '��' => '冬',
  '��' => '董',
  '��' => '懂',
  '��' => '动',
  '��' => '栋',
  '��' => '侗',
  '��' => '恫',
  '��' => '冻',
  '��' => '洞',
  '��' => '兜',
  '��' => '抖',
  '��' => '斗',
  '��' => '陡',
  '��' => '豆',
  '��' => '逗',
  '��' => '痘',
  '��' => '都',
  '��' => '督',
  '��' => '毒',
  '��' => '犊',
  '��' => '独',
  '��' => '读',
  '��' => '堵',
  '��' => '睹',
  '��' => '赌',
  '��' => '杜',
  '��' => '镀',
  '��' => '肚',
  '��' => '度',
  '��' => '渡',
  '��' => '妒',
  '��' => '端',
  '��' => '短',
  '��' => '锻',
  '��' => '段',
  '��' => '断',
  '��' => '缎',
  '��' => '堆',
  '��' => '兑',
  '��' => '队',
  '��' => '对',
  '��' => '墩',
  '��' => '吨',
  '��' => '蹲',
  '��' => '敦',
  '��' => '顿',
  '��' => '囤',
  '��' => '钝',
  '��' => '盾',
  '��' => '遁',
  '��' => '掇',
  '��' => '哆',
  '��' => '多',
  '��' => '夺',
  '��' => '垛',
  '��' => '躲',
  '��' => '朵',
  '��' => '跺',
  '��' => '舵',
  '��' => '剁',
  '��' => '惰',
  '��' => '堕',
  '��' => '蛾',
  '��' => '峨',
  '��' => '鹅',
  '��' => '俄',
  '��' => '额',
  '��' => '讹',
  '��' => '娥',
  '��' => '恶',
  '��' => '厄',
  '��' => '扼',
  '��' => '遏',
  '��' => '鄂',
  '��' => '饿',
  '��' => '恩',
  '��' => '而',
  '��' => '儿',
  '��' => '耳',
  '��' => '尔',
  '��' => '饵',
  '��' => '洱',
  '��' => '二',
  '�@' => '稝',
  '�A' => '稟',
  '�B' => '稡',
  '�C' => '稢',
  '�D' => '稤',
  '�E' => '稥',
  '�F' => '稦',
  '�G' => '稧',
  '�H' => '稨',
  '�I' => '稩',
  '�J' => '稪',
  '�K' => '稫',
  '�L' => '稬',
  '�M' => '稭',
  '�N' => '種',
  '�O' => '稯',
  '�P' => '稰',
  '�Q' => '稱',
  '�R' => '稲',
  '�S' => '稴',
  '�T' => '稵',
  '�U' => '稶',
  '�V' => '稸',
  '�W' => '稺',
  '�X' => '稾',
  '�Y' => '穀',
  '�Z' => '穁',
  '�[' => '穂',
  '�\\' => '穃',
  '�]' => '穄',
  '�^' => '穅',
  '�_' => '穇',
  '�`' => '穈',
  '�a' => '穉',
  '�b' => '穊',
  '�c' => '穋',
  '�d' => '穌',
  '�e' => '積',
  '�f' => '穎',
  '�g' => '穏',
  '�h' => '穐',
  '�i' => '穒',
  '�j' => '穓',
  '�k' => '穔',
  '�l' => '穕',
  '�m' => '穖',
  '�n' => '穘',
  '�o' => '穙',
  '�p' => '穚',
  '�q' => '穛',
  '�r' => '穜',
  '�s' => '穝',
  '�t' => '穞',
  '�u' => '穟',
  '�v' => '穠',
  '�w' => '穡',
  '�x' => '穢',
  '�y' => '穣',
  '�z' => '穤',
  '�{' => '穥',
  '�|' => '穦',
  '�}' => '穧',
  '�~' => '穨',
  '��' => '穩',
  '��' => '穪',
  '��' => '穫',
  '��' => '穬',
  '��' => '穭',
  '��' => '穮',
  '��' => '穯',
  '��' => '穱',
  '��' => '穲',
  '��' => '穳',
  '��' => '穵',
  '��' => '穻',
  '��' => '穼',
  '��' => '穽',
  '��' => '穾',
  '��' => '窂',
  '��' => '窅',
  '��' => '窇',
  '��' => '窉',
  '��' => '窊',
  '��' => '窋',
  '��' => '窌',
  '��' => '窎',
  '��' => '窏',
  '��' => '窐',
  '��' => '窓',
  '��' => '窔',
  '��' => '窙',
  '��' => '窚',
  '��' => '窛',
  '��' => '窞',
  '��' => '窡',
  '��' => '窢',
  '��' => '贰',
  '��' => '发',
  '��' => '罚',
  '��' => '筏',
  '��' => '伐',
  '��' => '乏',
  '��' => '阀',
  '��' => '法',
  '��' => '珐',
  '��' => '藩',
  '��' => '帆',
  '��' => '番',
  '��' => '翻',
  '��' => '樊',
  '��' => '矾',
  '��' => '钒',
  '��' => '繁',
  '��' => '凡',
  '��' => '烦',
  '��' => '反',
  '��' => '返',
  '��' => '范',
  '��' => '贩',
  '��' => '犯',
  '��' => '饭',
  '��' => '泛',
  '��' => '坊',
  '��' => '芳',
  '��' => '方',
  '��' => '肪',
  '��' => '房',
  '��' => '防',
  '��' => '妨',
  '��' => '仿',
  '��' => '访',
  '��' => '纺',
  '��' => '放',
  '��' => '菲',
  '��' => '非',
  '��' => '啡',
  '��' => '飞',
  '��' => '肥',
  '��' => '匪',
  '��' => '诽',
  '��' => '吠',
  '��' => '肺',
  '��' => '废',
  '��' => '沸',
  '��' => '费',
  '��' => '芬',
  '��' => '酚',
  '��' => '吩',
  '��' => '氛',
  '��' => '分',
  '��' => '纷',
  '��' => '坟',
  '��' => '焚',
  '��' => '汾',
  '��' => '粉',
  '��' => '奋',
  '��' => '份',
  '��' => '忿',
  '��' => '愤',
  '��' => '粪',
  '��' => '丰',
  '��' => '封',
  '��' => '枫',
  '��' => '蜂',
  '��' => '峰',
  '��' => '锋',
  '��' => '风',
  '��' => '疯',
  '��' => '烽',
  '��' => '逢',
  '��' => '冯',
  '��' => '缝',
  '��' => '讽',
  '��' => '奉',
  '��' => '凤',
  '��' => '佛',
  '��' => '否',
  '��' => '夫',
  '��' => '敷',
  '��' => '肤',
  '��' => '孵',
  '��' => '扶',
  '��' => '拂',
  '��' => '辐',
  '��' => '幅',
  '��' => '氟',
  '��' => '符',
  '��' => '伏',
  '��' => '俘',
  '��' => '服',
  '�@' => '窣',
  '�A' => '窤',
  '�B' => '窧',
  '�C' => '窩',
  '�D' => '窪',
  '�E' => '窫',
  '�F' => '窮',
  '�G' => '窯',
  '�H' => '窰',
  '�I' => '窱',
  '�J' => '窲',
  '�K' => '窴',
  '�L' => '窵',
  '�M' => '窶',
  '�N' => '窷',
  '�O' => '窸',
  '�P' => '窹',
  '�Q' => '窺',
  '�R' => '窻',
  '�S' => '窼',
  '�T' => '窽',
  '�U' => '窾',
  '�V' => '竀',
  '�W' => '竁',
  '�X' => '竂',
  '�Y' => '竃',
  '�Z' => '竄',
  '�[' => '竅',
  '�\\' => '竆',
  '�]' => '竇',
  '�^' => '竈',
  '�_' => '竉',
  '�`' => '竊',
  '�a' => '竌',
  '�b' => '竍',
  '�c' => '竎',
  '�d' => '竏',
  '�e' => '竐',
  '�f' => '竑',
  '�g' => '竒',
  '�h' => '竓',
  '�i' => '竔',
  '�j' => '竕',
  '�k' => '竗',
  '�l' => '竘',
  '�m' => '竚',
  '�n' => '竛',
  '�o' => '竜',
  '�p' => '竝',
  '�q' => '竡',
  '�r' => '竢',
  '�s' => '竤',
  '�t' => '竧',
  '�u' => '竨',
  '�v' => '竩',
  '�w' => '竪',
  '�x' => '竫',
  '�y' => '竬',
  '�z' => '竮',
  '�{' => '竰',
  '�|' => '竱',
  '�}' => '竲',
  '�~' => '竳',
  '��' => '竴',
  '��' => '竵',
  '��' => '競',
  '��' => '竷',
  '��' => '竸',
  '��' => '竻',
  '��' => '竼',
  '��' => '竾',
  '��' => '笀',
  '��' => '笁',
  '��' => '笂',
  '��' => '笅',
  '��' => '笇',
  '��' => '笉',
  '��' => '笌',
  '��' => '笍',
  '��' => '笎',
  '��' => '笐',
  '��' => '笒',
  '��' => '笓',
  '��' => '笖',
  '��' => '笗',
  '��' => '笘',
  '��' => '笚',
  '��' => '笜',
  '��' => '笝',
  '��' => '笟',
  '��' => '笡',
  '��' => '笢',
  '��' => '笣',
  '��' => '笧',
  '��' => '笩',
  '��' => '笭',
  '��' => '浮',
  '��' => '涪',
  '��' => '福',
  '��' => '袱',
  '��' => '弗',
  '��' => '甫',
  '��' => '抚',
  '��' => '辅',
  '��' => '俯',
  '��' => '釜',
  '��' => '斧',
  '��' => '脯',
  '��' => '腑',
  '��' => '府',
  '��' => '腐',
  '��' => '赴',
  '��' => '副',
  '��' => '覆',
  '��' => '赋',
  '��' => '复',
  '��' => '傅',
  '��' => '付',
  '��' => '阜',
  '��' => '父',
  '��' => '腹',
  '��' => '负',
  '��' => '富',
  '��' => '讣',
  '��' => '附',
  '��' => '妇',
  '��' => '缚',
  '��' => '咐',
  '��' => '噶',
  '��' => '嘎',
  '��' => '该',
  '��' => '改',
  '��' => '概',
  '��' => '钙',
  '��' => '盖',
  '��' => '溉',
  '��' => '干',
  '��' => '甘',
  '��' => '杆',
  '��' => '柑',
  '��' => '竿',
  '��' => '肝',
  '��' => '赶',
  '��' => '感',
  '��' => '秆',
  '��' => '敢',
  '��' => '赣',
  '��' => '冈',
  '��' => '刚',
  '��' => '钢',
  '��' => '缸',
  '��' => '肛',
  '��' => '纲',
  '��' => '岗',
  '��' => '港',
  '��' => '杠',
  '��' => '篙',
  '��' => '皋',
  '��' => '高',
  '��' => '膏',
  '��' => '羔',
  '��' => '糕',
  '��' => '搞',
  '��' => '镐',
  '��' => '稿',
  '��' => '告',
  '��' => '哥',
  '��' => '歌',
  '��' => '搁',
  '��' => '戈',
  '��' => '鸽',
  '��' => '胳',
  '��' => '疙',
  '��' => '割',
  '��' => '革',
  '��' => '葛',
  '��' => '格',
  '��' => '蛤',
  '��' => '阁',
  '��' => '隔',
  '��' => '铬',
  '��' => '个',
  '��' => '各',
  '��' => '给',
  '��' => '根',
  '��' => '跟',
  '��' => '耕',
  '��' => '更',
  '��' => '庚',
  '��' => '羹',
  '�@' => '笯',
  '�A' => '笰',
  '�B' => '笲',
  '�C' => '笴',
  '�D' => '笵',
  '�E' => '笶',
  '�F' => '笷',
  '�G' => '笹',
  '�H' => '笻',
  '�I' => '笽',
  '�J' => '笿',
  '�K' => '筀',
  '�L' => '筁',
  '�M' => '筂',
  '�N' => '筃',
  '�O' => '筄',
  '�P' => '筆',
  '�Q' => '筈',
  '�R' => '筊',
  '�S' => '筍',
  '�T' => '筎',
  '�U' => '筓',
  '�V' => '筕',
  '�W' => '筗',
  '�X' => '筙',
  '�Y' => '筜',
  '�Z' => '筞',
  '�[' => '筟',
  '�\\' => '筡',
  '�]' => '筣',
  '�^' => '筤',
  '�_' => '筥',
  '�`' => '筦',
  '�a' => '筧',
  '�b' => '筨',
  '�c' => '筩',
  '�d' => '筪',
  '�e' => '筫',
  '�f' => '筬',
  '�g' => '筭',
  '�h' => '筯',
  '�i' => '筰',
  '�j' => '筳',
  '�k' => '筴',
  '�l' => '筶',
  '�m' => '筸',
  '�n' => '筺',
  '�o' => '筼',
  '�p' => '筽',
  '�q' => '筿',
  '�r' => '箁',
  '�s' => '箂',
  '�t' => '箃',
  '�u' => '箄',
  '�v' => '箆',
  '�w' => '箇',
  '�x' => '箈',
  '�y' => '箉',
  '�z' => '箊',
  '�{' => '箋',
  '�|' => '箌',
  '�}' => '箎',
  '�~' => '箏',
  '��' => '箑',
  '��' => '箒',
  '��' => '箓',
  '��' => '箖',
  '��' => '箘',
  '��' => '箙',
  '��' => '箚',
  '��' => '箛',
  '��' => '箞',
  '��' => '箟',
  '��' => '箠',
  '��' => '箣',
  '��' => '箤',
  '��' => '箥',
  '��' => '箮',
  '��' => '箯',
  '��' => '箰',
  '��' => '箲',
  '��' => '箳',
  '��' => '箵',
  '��' => '箶',
  '��' => '箷',
  '��' => '箹',
  '��' => '箺',
  '��' => '箻',
  '��' => '箼',
  '��' => '箽',
  '��' => '箾',
  '��' => '箿',
  '��' => '節',
  '��' => '篂',
  '��' => '篃',
  '��' => '範',
  '��' => '埂',
  '��' => '耿',
  '��' => '梗',
  '��' => '工',
  '��' => '攻',
  '��' => '功',
  '��' => '恭',
  '��' => '龚',
  '��' => '供',
  '��' => '躬',
  '��' => '公',
  '��' => '宫',
  '��' => '弓',
  '��' => '巩',
  '��' => '汞',
  '��' => '拱',
  '��' => '贡',
  '��' => '共',
  '��' => '钩',
  '��' => '勾',
  '��' => '沟',
  '��' => '苟',
  '��' => '狗',
  '��' => '垢',
  '��' => '构',
  '��' => '购',
  '��' => '够',
  '��' => '辜',
  '��' => '菇',
  '��' => '咕',
  '��' => '箍',
  '��' => '估',
  '��' => '沽',
  '��' => '孤',
  '��' => '姑',
  '��' => '鼓',
  '��' => '古',
  '��' => '蛊',
  '��' => '骨',
  '��' => '谷',
  '��' => '股',
  '��' => '故',
  '��' => '顾',
  '��' => '固',
  '��' => '雇',
  '��' => '刮',
  '��' => '瓜',
  '��' => '剐',
  '��' => '寡',
  '��' => '挂',
  '��' => '褂',
  '��' => '乖',
  '��' => '拐',
  '��' => '怪',
  '��' => '棺',
  '��' => '关',
  '��' => '官',
  '��' => '冠',
  '��' => '观',
  '��' => '管',
  '��' => '馆',
  '��' => '罐',
  '��' => '惯',
  '��' => '灌',
  '��' => '贯',
  '��' => '光',
  '��' => '广',
  '��' => '逛',
  '��' => '瑰',
  '��' => '规',
  '��' => '圭',
  '��' => '硅',
  '��' => '归',
  '��' => '龟',
  '��' => '闺',
  '��' => '轨',
  '��' => '鬼',
  '��' => '诡',
  '��' => '癸',
  '��' => '桂',
  '��' => '柜',
  '��' => '跪',
  '��' => '贵',
  '��' => '刽',
  '��' => '辊',
  '��' => '滚',
  '��' => '棍',
  '��' => '锅',
  '��' => '郭',
  '��' => '国',
  '��' => '果',
  '��' => '裹',
  '��' => '过',
  '��' => '哈',
  '�@' => '篅',
  '�A' => '篈',
  '�B' => '築',
  '�C' => '篊',
  '�D' => '篋',
  '�E' => '篍',
  '�F' => '篎',
  '�G' => '篏',
  '�H' => '篐',
  '�I' => '篒',
  '�J' => '篔',
  '�K' => '篕',
  '�L' => '篖',
  '�M' => '篗',
  '�N' => '篘',
  '�O' => '篛',
  '�P' => '篜',
  '�Q' => '篞',
  '�R' => '篟',
  '�S' => '篠',
  '�T' => '篢',
  '�U' => '篣',
  '�V' => '篤',
  '�W' => '篧',
  '�X' => '篨',
  '�Y' => '篩',
  '�Z' => '篫',
  '�[' => '篬',
  '�\\' => '篭',
  '�]' => '篯',
  '�^' => '篰',
  '�_' => '篲',
  '�`' => '篳',
  '�a' => '篴',
  '�b' => '篵',
  '�c' => '篶',
  '�d' => '篸',
  '�e' => '篹',
  '�f' => '篺',
  '�g' => '篻',
  '�h' => '篽',
  '�i' => '篿',
  '�j' => '簀',
  '�k' => '簁',
  '�l' => '簂',
  '�m' => '簃',
  '�n' => '簄',
  '�o' => '簅',
  '�p' => '簆',
  '�q' => '簈',
  '�r' => '簉',
  '�s' => '簊',
  '�t' => '簍',
  '�u' => '簎',
  '�v' => '簐',
  '�w' => '簑',
  '�x' => '簒',
  '�y' => '簓',
  '�z' => '簔',
  '�{' => '簕',
  '�|' => '簗',
  '�}' => '簘',
  '�~' => '簙',
  '��' => '簚',
  '��' => '簛',
  '��' => '簜',
  '��' => '簝',
  '��' => '簞',
  '��' => '簠',
  '��' => '簡',
  '��' => '簢',
  '��' => '簣',
  '��' => '簤',
  '��' => '簥',
  '��' => '簨',
  '��' => '簩',
  '��' => '簫',
  '��' => '簬',
  '��' => '簭',
  '��' => '簮',
  '��' => '簯',
  '��' => '簰',
  '��' => '簱',
  '��' => '簲',
  '��' => '簳',
  '��' => '簴',
  '��' => '簵',
  '��' => '簶',
  '��' => '簷',
  '��' => '簹',
  '��' => '簺',
  '��' => '簻',
  '��' => '簼',
  '��' => '簽',
  '��' => '簾',
  '��' => '籂',
  '��' => '骸',
  '��' => '孩',
  '��' => '海',
  '��' => '氦',
  '��' => '亥',
  '��' => '害',
  '��' => '骇',
  '��' => '酣',
  '��' => '憨',
  '��' => '邯',
  '��' => '韩',
  '��' => '含',
  '��' => '涵',
  '��' => '寒',
  '��' => '函',
  '��' => '喊',
  '��' => '罕',
  '��' => '翰',
  '��' => '撼',
  '��' => '捍',
  '��' => '旱',
  '��' => '憾',
  '��' => '悍',
  '��' => '焊',
  '��' => '汗',
  '��' => '汉',
  '��' => '夯',
  '��' => '杭',
  '��' => '航',
  '��' => '壕',
  '��' => '嚎',
  '��' => '豪',
  '��' => '毫',
  '��' => '郝',
  '��' => '好',
  '��' => '耗',
  '��' => '号',
  '��' => '浩',
  '��' => '呵',
  '��' => '喝',
  '��' => '荷',
  '��' => '菏',
  '��' => '核',
  '��' => '禾',
  '��' => '和',
  '��' => '何',
  '��' => '合',
  '��' => '盒',
  '��' => '貉',
  '��' => '阂',
  '��' => '河',
  '��' => '涸',
  '��' => '赫',
  '��' => '褐',
  '��' => '鹤',
  '��' => '贺',
  '��' => '嘿',
  '��' => '黑',
  '��' => '痕',
  '��' => '很',
  '��' => '狠',
  '��' => '恨',
  '��' => '哼',
  '��' => '亨',
  '��' => '横',
  '��' => '衡',
  '��' => '恒',
  '��' => '轰',
  '��' => '哄',
  '��' => '烘',
  '��' => '虹',
  '��' => '鸿',
  '��' => '洪',
  '��' => '宏',
  '��' => '弘',
  '��' => '红',
  '��' => '喉',
  '��' => '侯',
  '��' => '猴',
  '��' => '吼',
  '��' => '厚',
  '��' => '候',
  '��' => '后',
  '��' => '呼',
  '��' => '乎',
  '��' => '忽',
  '��' => '瑚',
  '��' => '壶',
  '��' => '葫',
  '��' => '胡',
  '��' => '蝴',
  '��' => '狐',
  '��' => '糊',
  '��' => '湖',
  '�@' => '籃',
  '�A' => '籄',
  '�B' => '籅',
  '�C' => '籆',
  '�D' => '籇',
  '�E' => '籈',
  '�F' => '籉',
  '�G' => '籊',
  '�H' => '籋',
  '�I' => '籌',
  '�J' => '籎',
  '�K' => '籏',
  '�L' => '籐',
  '�M' => '籑',
  '�N' => '籒',
  '�O' => '籓',
  '�P' => '籔',
  '�Q' => '籕',
  '�R' => '籖',
  '�S' => '籗',
  '�T' => '籘',
  '�U' => '籙',
  '�V' => '籚',
  '�W' => '籛',
  '�X' => '籜',
  '�Y' => '籝',
  '�Z' => '籞',
  '�[' => '籟',
  '�\\' => '籠',
  '�]' => '籡',
  '�^' => '籢',
  '�_' => '籣',
  '�`' => '籤',
  '�a' => '籥',
  '�b' => '籦',
  '�c' => '籧',
  '�d' => '籨',
  '�e' => '籩',
  '�f' => '籪',
  '�g' => '籫',
  '�h' => '籬',
  '�i' => '籭',
  '�j' => '籮',
  '�k' => '籯',
  '�l' => '籰',
  '�m' => '籱',
  '�n' => '籲',
  '�o' => '籵',
  '�p' => '籶',
  '�q' => '籷',
  '�r' => '籸',
  '�s' => '籹',
  '�t' => '籺',
  '�u' => '籾',
  '�v' => '籿',
  '�w' => '粀',
  '�x' => '粁',
  '�y' => '粂',
  '�z' => '粃',
  '�{' => '粄',
  '�|' => '粅',
  '�}' => '粆',
  '�~' => '粇',
  '��' => '粈',
  '��' => '粊',
  '��' => '粋',
  '��' => '粌',
  '��' => '粍',
  '��' => '粎',
  '��' => '粏',
  '��' => '粐',
  '��' => '粓',
  '��' => '粔',
  '��' => '粖',
  '��' => '粙',
  '��' => '粚',
  '��' => '粛',
  '��' => '粠',
  '��' => '粡',
  '��' => '粣',
  '��' => '粦',
  '��' => '粧',
  '��' => '粨',
  '��' => '粩',
  '��' => '粫',
  '��' => '粬',
  '��' => '粭',
  '��' => '粯',
  '��' => '粰',
  '��' => '粴',
  '��' => '粵',
  '��' => '粶',
  '��' => '粷',
  '��' => '粸',
  '��' => '粺',
  '��' => '粻',
  '��' => '弧',
  '��' => '虎',
  '��' => '唬',
  '��' => '护',
  '��' => '互',
  '��' => '沪',
  '��' => '户',
  '��' => '花',
  '��' => '哗',
  '��' => '华',
  '��' => '猾',
  '��' => '滑',
  '��' => '画',
  '��' => '划',
  '��' => '化',
  '��' => '话',
  '��' => '槐',
  '��' => '徊',
  '��' => '怀',
  '��' => '淮',
  '��' => '坏',
  '��' => '欢',
  '��' => '环',
  '��' => '桓',
  '��' => '还',
  '��' => '缓',
  '��' => '换',
  '��' => '患',
  '��' => '唤',
  '��' => '痪',
  '��' => '豢',
  '��' => '焕',
  '��' => '涣',
  '��' => '宦',
  '��' => '幻',
  '��' => '荒',
  '��' => '慌',
  '��' => '黄',
  '��' => '磺',
  '��' => '蝗',
  '��' => '簧',
  '��' => '皇',
  '��' => '凰',
  '��' => '惶',
  '��' => '煌',
  '��' => '晃',
  '��' => '幌',
  '��' => '恍',
  '��' => '谎',
  '��' => '灰',
  '��' => '挥',
  '��' => '辉',
  '��' => '徽',
  '��' => '恢',
  '��' => '蛔',
  '��' => '回',
  '��' => '毁',
  '��' => '悔',
  '��' => '慧',
  '��' => '卉',
  '��' => '惠',
  '��' => '晦',
  '��' => '贿',
  '��' => '秽',
  '��' => '会',
  '��' => '烩',
  '��' => '汇',
  '��' => '讳',
  '��' => '诲',
  '��' => '绘',
  '��' => '荤',
  '��' => '昏',
  '��' => '婚',
  '��' => '魂',
  '��' => '浑',
  '��' => '混',
  '��' => '豁',
  '��' => '活',
  '��' => '伙',
  '��' => '火',
  '��' => '获',
  '��' => '或',
  '��' => '惑',
  '��' => '霍',
  '��' => '货',
  '��' => '祸',
  '��' => '击',
  '��' => '圾',
  '��' => '基',
  '��' => '机',
  '��' => '畸',
  '��' => '稽',
  '��' => '积',
  '��' => '箕',
  '�@' => '粿',
  '�A' => '糀',
  '�B' => '糂',
  '�C' => '糃',
  '�D' => '糄',
  '�E' => '糆',
  '�F' => '糉',
  '�G' => '糋',
  '�H' => '糎',
  '�I' => '糏',
  '�J' => '糐',
  '�K' => '糑',
  '�L' => '糒',
  '�M' => '糓',
  '�N' => '糔',
  '�O' => '糘',
  '�P' => '糚',
  '�Q' => '糛',
  '�R' => '糝',
  '�S' => '糞',
  '�T' => '糡',
  '�U' => '糢',
  '�V' => '糣',
  '�W' => '糤',
  '�X' => '糥',
  '�Y' => '糦',
  '�Z' => '糧',
  '�[' => '糩',
  '�\\' => '糪',
  '�]' => '糫',
  '�^' => '糬',
  '�_' => '糭',
  '�`' => '糮',
  '�a' => '糰',
  '�b' => '糱',
  '�c' => '糲',
  '�d' => '糳',
  '�e' => '糴',
  '�f' => '糵',
  '�g' => '糶',
  '�h' => '糷',
  '�i' => '糹',
  '�j' => '糺',
  '�k' => '糼',
  '�l' => '糽',
  '�m' => '糾',
  '�n' => '糿',
  '�o' => '紀',
  '�p' => '紁',
  '�q' => '紂',
  '�r' => '紃',
  '�s' => '約',
  '�t' => '紅',
  '�u' => '紆',
  '�v' => '紇',
  '�w' => '紈',
  '�x' => '紉',
  '�y' => '紋',
  '�z' => '紌',
  '�{' => '納',
  '�|' => '紎',
  '�}' => '紏',
  '�~' => '紐',
  '��' => '紑',
  '��' => '紒',
  '��' => '紓',
  '��' => '純',
  '��' => '紕',
  '��' => '紖',
  '��' => '紗',
  '��' => '紘',
  '��' => '紙',
  '��' => '級',
  '��' => '紛',
  '��' => '紜',
  '��' => '紝',
  '��' => '紞',
  '��' => '紟',
  '��' => '紡',
  '��' => '紣',
  '��' => '紤',
  '��' => '紥',
  '��' => '紦',
  '��' => '紨',
  '��' => '紩',
  '��' => '紪',
  '��' => '紬',
  '��' => '紭',
  '��' => '紮',
  '��' => '細',
  '��' => '紱',
  '��' => '紲',
  '��' => '紳',
  '��' => '紴',
  '��' => '紵',
  '��' => '紶',
  '��' => '肌',
  '��' => '饥',
  '��' => '迹',
  '��' => '激',
  '��' => '讥',
  '��' => '鸡',
  '��' => '姬',
  '��' => '绩',
  '��' => '缉',
  '��' => '吉',
  '��' => '极',
  '��' => '棘',
  '��' => '辑',
  '��' => '籍',
  '��' => '集',
  '��' => '及',
  '��' => '急',
  '��' => '疾',
  '��' => '汲',
  '��' => '即',
  '��' => '嫉',
  '��' => '级',
  '��' => '挤',
  '��' => '几',
  '��' => '脊',
  '��' => '己',
  '��' => '蓟',
  '��' => '技',
  '��' => '冀',
  '��' => '季',
  '��' => '伎',
  '��' => '祭',
  '��' => '剂',
  '��' => '悸',
  '��' => '济',
  '��' => '寄',
  '��' => '寂',
  '��' => '计',
  '��' => '记',
  '��' => '既',
  '��' => '忌',
  '��' => '际',
  '��' => '妓',
  '��' => '继',
  '��' => '纪',
  '��' => '嘉',
  '��' => '枷',
  '��' => '夹',
  '��' => '佳',
  '��' => '家',
  '��' => '加',
  '��' => '荚',
  '��' => '颊',
  '��' => '贾',
  '��' => '甲',
  '��' => '钾',
  '��' => '假',
  '��' => '稼',
  '��' => '价',
  '��' => '架',
  '��' => '驾',
  '��' => '嫁',
  '��' => '歼',
  '��' => '监',
  '��' => '坚',
  '��' => '尖',
  '��' => '笺',
  '��' => '间',
  '��' => '煎',
  '��' => '兼',
  '��' => '肩',
  '��' => '艰',
  '��' => '奸',
  '��' => '缄',
  '��' => '茧',
  '��' => '检',
  '��' => '柬',
  '��' => '碱',
  '��' => '硷',
  '��' => '拣',
  '��' => '捡',
  '��' => '简',
  '��' => '俭',
  '��' => '剪',
  '��' => '减',
  '��' => '荐',
  '��' => '槛',
  '��' => '鉴',
  '��' => '践',
  '��' => '贱',
  '��' => '见',
  '��' => '键',
  '��' => '箭',
  '��' => '件',
  '�@' => '紷',
  '�A' => '紸',
  '�B' => '紹',
  '�C' => '紺',
  '�D' => '紻',
  '�E' => '紼',
  '�F' => '紽',
  '�G' => '紾',
  '�H' => '紿',
  '�I' => '絀',
  '�J' => '絁',
  '�K' => '終',
  '�L' => '絃',
  '�M' => '組',
  '�N' => '絅',
  '�O' => '絆',
  '�P' => '絇',
  '�Q' => '絈',
  '�R' => '絉',
  '�S' => '絊',
  '�T' => '絋',
  '�U' => '経',
  '�V' => '絍',
  '�W' => '絎',
  '�X' => '絏',
  '�Y' => '結',
  '�Z' => '絑',
  '�[' => '絒',
  '�\\' => '絓',
  '�]' => '絔',
  '�^' => '絕',
  '�_' => '絖',
  '�`' => '絗',
  '�a' => '絘',
  '�b' => '絙',
  '�c' => '絚',
  '�d' => '絛',
  '�e' => '絜',
  '�f' => '絝',
  '�g' => '絞',
  '�h' => '絟',
  '�i' => '絠',
  '�j' => '絡',
  '�k' => '絢',
  '�l' => '絣',
  '�m' => '絤',
  '�n' => '絥',
  '�o' => '給',
  '�p' => '絧',
  '�q' => '絨',
  '�r' => '絩',
  '�s' => '絪',
  '�t' => '絫',
  '�u' => '絬',
  '�v' => '絭',
  '�w' => '絯',
  '�x' => '絰',
  '�y' => '統',
  '�z' => '絲',
  '�{' => '絳',
  '�|' => '絴',
  '�}' => '絵',
  '�~' => '絶',
  '��' => '絸',
  '��' => '絹',
  '��' => '絺',
  '��' => '絻',
  '��' => '絼',
  '��' => '絽',
  '��' => '絾',
  '��' => '絿',
  '��' => '綀',
  '��' => '綁',
  '��' => '綂',
  '��' => '綃',
  '��' => '綄',
  '��' => '綅',
  '��' => '綆',
  '��' => '綇',
  '��' => '綈',
  '��' => '綉',
  '��' => '綊',
  '��' => '綋',
  '��' => '綌',
  '��' => '綍',
  '��' => '綎',
  '��' => '綏',
  '��' => '綐',
  '��' => '綑',
  '��' => '綒',
  '��' => '經',
  '��' => '綔',
  '��' => '綕',
  '��' => '綖',
  '��' => '綗',
  '��' => '綘',
  '��' => '健',
  '��' => '舰',
  '��' => '剑',
  '��' => '饯',
  '��' => '渐',
  '��' => '溅',
  '��' => '涧',
  '��' => '建',
  '��' => '僵',
  '��' => '姜',
  '��' => '将',
  '��' => '浆',
  '��' => '江',
  '��' => '疆',
  '��' => '蒋',
  '��' => '桨',
  '��' => '奖',
  '��' => '讲',
  '��' => '匠',
  '��' => '酱',
  '��' => '降',
  '��' => '蕉',
  '��' => '椒',
  '��' => '礁',
  '��' => '焦',
  '��' => '胶',
  '��' => '交',
  '��' => '郊',
  '��' => '浇',
  '��' => '骄',
  '��' => '娇',
  '��' => '嚼',
  '��' => '搅',
  '��' => '铰',
  '��' => '矫',
  '��' => '侥',
  '��' => '脚',
  '��' => '狡',
  '��' => '角',
  '��' => '饺',
  '��' => '缴',
  '��' => '绞',
  '��' => '剿',
  '��' => '教',
  '��' => '酵',
  '��' => '轿',
  '��' => '较',
  '��' => '叫',
  '��' => '窖',
  '��' => '揭',
  '��' => '接',
  '��' => '皆',
  '��' => '秸',
  '��' => '街',
  '��' => '阶',
  '��' => '截',
  '��' => '劫',
  '��' => '节',
  '��' => '桔',
  '��' => '杰',
  '��' => '捷',
  '��' => '睫',
  '��' => '竭',
  '��' => '洁',
  '��' => '结',
  '��' => '解',
  '��' => '姐',
  '��' => '戒',
  '��' => '藉',
  '��' => '芥',
  '��' => '界',
  '��' => '借',
  '��' => '介',
  '��' => '疥',
  '��' => '诫',
  '��' => '届',
  '��' => '巾',
  '��' => '筋',
  '��' => '斤',
  '��' => '金',
  '��' => '今',
  '��' => '津',
  '��' => '襟',
  '��' => '紧',
  '��' => '锦',
  '��' => '仅',
  '��' => '谨',
  '��' => '进',
  '��' => '靳',
  '��' => '晋',
  '��' => '禁',
  '��' => '近',
  '��' => '烬',
  '��' => '浸',
  '�@' => '継',
  '�A' => '続',
  '�B' => '綛',
  '�C' => '綜',
  '�D' => '綝',
  '�E' => '綞',
  '�F' => '綟',
  '�G' => '綠',
  '�H' => '綡',
  '�I' => '綢',
  '�J' => '綣',
  '�K' => '綤',
  '�L' => '綥',
  '�M' => '綧',
  '�N' => '綨',
  '�O' => '綩',
  '�P' => '綪',
  '�Q' => '綫',
  '�R' => '綬',
  '�S' => '維',
  '�T' => '綯',
  '�U' => '綰',
  '�V' => '綱',
  '�W' => '網',
  '�X' => '綳',
  '�Y' => '綴',
  '�Z' => '綵',
  '�[' => '綶',
  '�\\' => '綷',
  '�]' => '綸',
  '�^' => '綹',
  '�_' => '綺',
  '�`' => '綻',
  '�a' => '綼',
  '�b' => '綽',
  '�c' => '綾',
  '�d' => '綿',
  '�e' => '緀',
  '�f' => '緁',
  '�g' => '緂',
  '�h' => '緃',
  '�i' => '緄',
  '�j' => '緅',
  '�k' => '緆',
  '�l' => '緇',
  '�m' => '緈',
  '�n' => '緉',
  '�o' => '緊',
  '�p' => '緋',
  '�q' => '緌',
  '�r' => '緍',
  '�s' => '緎',
  '�t' => '総',
  '�u' => '緐',
  '�v' => '緑',
  '�w' => '緒',
  '�x' => '緓',
  '�y' => '緔',
  '�z' => '緕',
  '�{' => '緖',
  '�|' => '緗',
  '�}' => '緘',
  '�~' => '緙',
  '��' => '線',
  '��' => '緛',
  '��' => '緜',
  '��' => '緝',
  '��' => '緞',
  '��' => '緟',
  '��' => '締',
  '��' => '緡',
  '��' => '緢',
  '��' => '緣',
  '��' => '緤',
  '��' => '緥',
  '��' => '緦',
  '��' => '緧',
  '��' => '編',
  '��' => '緩',
  '��' => '緪',
  '��' => '緫',
  '��' => '緬',
  '��' => '緭',
  '��' => '緮',
  '��' => '緯',
  '��' => '緰',
  '��' => '緱',
  '��' => '緲',
  '��' => '緳',
  '��' => '練',
  '��' => '緵',
  '��' => '緶',
  '��' => '緷',
  '��' => '緸',
  '��' => '緹',
  '��' => '緺',
  '��' => '尽',
  '��' => '劲',
  '��' => '荆',
  '��' => '兢',
  '��' => '茎',
  '��' => '睛',
  '��' => '晶',
  '��' => '鲸',
  '��' => '京',
  '��' => '惊',
  '��' => '精',
  '��' => '粳',
  '��' => '经',
  '��' => '井',
  '��' => '警',
  '��' => '景',
  '��' => '颈',
  '��' => '静',
  '��' => '境',
  '��' => '敬',
  '��' => '镜',
  '��' => '径',
  '��' => '痉',
  '��' => '靖',
  '��' => '竟',
  '��' => '竞',
  '��' => '净',
  '��' => '炯',
  '��' => '窘',
  '��' => '揪',
  '��' => '究',
  '��' => '纠',
  '��' => '玖',
  '��' => '韭',
  '��' => '久',
  '��' => '灸',
  '��' => '九',
  '��' => '酒',
  '��' => '厩',
  '��' => '救',
  '��' => '旧',
  '��' => '臼',
  '��' => '舅',
  '��' => '咎',
  '��' => '就',
  '��' => '疚',
  '��' => '鞠',
  '��' => '拘',
  '��' => '狙',
  '��' => '疽',
  '��' => '居',
  '��' => '驹',
  '��' => '菊',
  '��' => '局',
  '��' => '咀',
  '��' => '矩',
  '��' => '举',
  '��' => '沮',
  '��' => '聚',
  '��' => '拒',
  '��' => '据',
  '��' => '巨',
  '��' => '具',
  '��' => '距',
  '��' => '踞',
  '��' => '锯',
  '��' => '俱',
  '��' => '句',
  '��' => '惧',
  '��' => '炬',
  '��' => '剧',
  '��' => '捐',
  '��' => '鹃',
  '��' => '娟',
  '��' => '倦',
  '��' => '眷',
  '��' => '卷',
  '��' => '绢',
  '��' => '撅',
  '��' => '攫',
  '��' => '抉',
  '��' => '掘',
  '��' => '倔',
  '��' => '爵',
  '��' => '觉',
  '��' => '决',
  '��' => '诀',
  '��' => '绝',
  '��' => '均',
  '��' => '菌',
  '��' => '钧',
  '��' => '军',
  '��' => '君',
  '��' => '峻',
  '�@' => '緻',
  '�A' => '緼',
  '�B' => '緽',
  '�C' => '緾',
  '�D' => '緿',
  '�E' => '縀',
  '�F' => '縁',
  '�G' => '縂',
  '�H' => '縃',
  '�I' => '縄',
  '�J' => '縅',
  '�K' => '縆',
  '�L' => '縇',
  '�M' => '縈',
  '�N' => '縉',
  '�O' => '縊',
  '�P' => '縋',
  '�Q' => '縌',
  '�R' => '縍',
  '�S' => '縎',
  '�T' => '縏',
  '�U' => '縐',
  '�V' => '縑',
  '�W' => '縒',
  '�X' => '縓',
  '�Y' => '縔',
  '�Z' => '縕',
  '�[' => '縖',
  '�\\' => '縗',
  '�]' => '縘',
  '�^' => '縙',
  '�_' => '縚',
  '�`' => '縛',
  '�a' => '縜',
  '�b' => '縝',
  '�c' => '縞',
  '�d' => '縟',
  '�e' => '縠',
  '�f' => '縡',
  '�g' => '縢',
  '�h' => '縣',
  '�i' => '縤',
  '�j' => '縥',
  '�k' => '縦',
  '�l' => '縧',
  '�m' => '縨',
  '�n' => '縩',
  '�o' => '縪',
  '�p' => '縫',
  '�q' => '縬',
  '�r' => '縭',
  '�s' => '縮',
  '�t' => '縯',
  '�u' => '縰',
  '�v' => '縱',
  '�w' => '縲',
  '�x' => '縳',
  '�y' => '縴',
  '�z' => '縵',
  '�{' => '縶',
  '�|' => '縷',
  '�}' => '縸',
  '�~' => '縹',
  '��' => '縺',
  '��' => '縼',
  '��' => '總',
  '��' => '績',
  '��' => '縿',
  '��' => '繀',
  '��' => '繂',
  '��' => '繃',
  '��' => '繄',
  '��' => '繅',
  '��' => '繆',
  '��' => '繈',
  '��' => '繉',
  '��' => '繊',
  '��' => '繋',
  '��' => '繌',
  '��' => '繍',
  '��' => '繎',
  '��' => '繏',
  '��' => '繐',
  '��' => '繑',
  '��' => '繒',
  '��' => '繓',
  '��' => '織',
  '��' => '繕',
  '��' => '繖',
  '��' => '繗',
  '��' => '繘',
  '��' => '繙',
  '��' => '繚',
  '��' => '繛',
  '��' => '繜',
  '��' => '繝',
  '��' => '俊',
  '��' => '竣',
  '��' => '浚',
  '��' => '郡',
  '��' => '骏',
  '��' => '喀',
  '��' => '咖',
  '��' => '卡',
  '��' => '咯',
  '��' => '开',
  '��' => '揩',
  '��' => '楷',
  '��' => '凯',
  '��' => '慨',
  '��' => '刊',
  '��' => '堪',
  '��' => '勘',
  '��' => '坎',
  '��' => '砍',
  '��' => '看',
  '��' => '康',
  '��' => '慷',
  '��' => '糠',
  '��' => '扛',
  '��' => '抗',
  '��' => '亢',
  '��' => '炕',
  '��' => '考',
  '��' => '拷',
  '��' => '烤',
  '��' => '靠',
  '��' => '坷',
  '��' => '苛',
  '��' => '柯',
  '��' => '棵',
  '��' => '磕',
  '��' => '颗',
  '��' => '科',
  '��' => '壳',
  '��' => '咳',
  '��' => '可',
  '��' => '渴',
  '��' => '克',
  '��' => '刻',
  '��' => '客',
  '��' => '课',
  '��' => '肯',
  '��' => '啃',
  '��' => '垦',
  '��' => '恳',
  '��' => '坑',
  '��' => '吭',
  '��' => '空',
  '��' => '恐',
  '��' => '孔',
  '��' => '控',
  '��' => '抠',
  '��' => '口',
  '��' => '扣',
  '��' => '寇',
  '��' => '枯',
  '��' => '哭',
  '��' => '窟',
  '��' => '苦',
  '��' => '酷',
  '��' => '库',
  '��' => '裤',
  '��' => '夸',
  '��' => '垮',
  '��' => '挎',
  '��' => '跨',
  '��' => '胯',
  '��' => '块',
  '��' => '筷',
  '��' => '侩',
  '��' => '快',
  '��' => '宽',
  '��' => '款',
  '��' => '匡',
  '��' => '筐',
  '��' => '狂',
  '��' => '框',
  '��' => '矿',
  '��' => '眶',
  '��' => '旷',
  '��' => '况',
  '��' => '亏',
  '��' => '盔',
  '��' => '岿',
  '��' => '窥',
  '��' => '葵',
  '��' => '奎',
  '��' => '魁',
  '��' => '傀',
  '�@' => '繞',
  '�A' => '繟',
  '�B' => '繠',
  '�C' => '繡',
  '�D' => '繢',
  '�E' => '繣',
  '�F' => '繤',
  '�G' => '繥',
  '�H' => '繦',
  '�I' => '繧',
  '�J' => '繨',
  '�K' => '繩',
  '�L' => '繪',
  '�M' => '繫',
  '�N' => '繬',
  '�O' => '繭',
  '�P' => '繮',
  '�Q' => '繯',
  '�R' => '繰',
  '�S' => '繱',
  '�T' => '繲',
  '�U' => '繳',
  '�V' => '繴',
  '�W' => '繵',
  '�X' => '繶',
  '�Y' => '繷',
  '�Z' => '繸',
  '�[' => '繹',
  '�\\' => '繺',
  '�]' => '繻',
  '�^' => '繼',
  '�_' => '繽',
  '�`' => '繾',
  '�a' => '繿',
  '�b' => '纀',
  '�c' => '纁',
  '�d' => '纃',
  '�e' => '纄',
  '�f' => '纅',
  '�g' => '纆',
  '�h' => '纇',
  '�i' => '纈',
  '�j' => '纉',
  '�k' => '纊',
  '�l' => '纋',
  '�m' => '續',
  '�n' => '纍',
  '�o' => '纎',
  '�p' => '纏',
  '�q' => '纐',
  '�r' => '纑',
  '�s' => '纒',
  '�t' => '纓',
  '�u' => '纔',
  '�v' => '纕',
  '�w' => '纖',
  '�x' => '纗',
  '�y' => '纘',
  '�z' => '纙',
  '�{' => '纚',
  '�|' => '纜',
  '�}' => '纝',
  '�~' => '纞',
  '��' => '纮',
  '��' => '纴',
  '��' => '纻',
  '��' => '纼',
  '��' => '绖',
  '��' => '绤',
  '��' => '绬',
  '��' => '绹',
  '��' => '缊',
  '��' => '缐',
  '��' => '缞',
  '��' => '缷',
  '��' => '缹',
  '��' => '缻',
  '��' => '缼',
  '��' => '缽',
  '��' => '缾',
  '��' => '缿',
  '��' => '罀',
  '��' => '罁',
  '��' => '罃',
  '��' => '罆',
  '��' => '罇',
  '��' => '罈',
  '��' => '罉',
  '��' => '罊',
  '��' => '罋',
  '��' => '罌',
  '��' => '罍',
  '��' => '罎',
  '��' => '罏',
  '��' => '罒',
  '��' => '罓',
  '��' => '馈',
  '��' => '愧',
  '��' => '溃',
  '��' => '坤',
  '��' => '昆',
  '��' => '捆',
  '��' => '困',
  '��' => '括',
  '��' => '扩',
  '��' => '廓',
  '��' => '阔',
  '��' => '垃',
  '��' => '拉',
  '��' => '喇',
  '��' => '蜡',
  '��' => '腊',
  '��' => '辣',
  '��' => '啦',
  '��' => '莱',
  '��' => '来',
  '��' => '赖',
  '��' => '蓝',
  '��' => '婪',
  '��' => '栏',
  '��' => '拦',
  '��' => '篮',
  '��' => '阑',
  '��' => '兰',
  '��' => '澜',
  '��' => '谰',
  '��' => '揽',
  '��' => '览',
  '��' => '懒',
  '��' => '缆',
  '��' => '烂',
  '��' => '滥',
  '��' => '琅',
  '��' => '榔',
  '��' => '狼',
  '��' => '廊',
  '��' => '郎',
  '��' => '朗',
  '��' => '浪',
  '��' => '捞',
  '��' => '劳',
  '��' => '牢',
  '��' => '老',
  '��' => '佬',
  '��' => '姥',
  '��' => '酪',
  '��' => '烙',
  '��' => '涝',
  '��' => '勒',
  '��' => '乐',
  '��' => '雷',
  '��' => '镭',
  '��' => '蕾',
  '��' => '磊',
  '��' => '累',
  '��' => '儡',
  '��' => '垒',
  '��' => '擂',
  '��' => '肋',
  '��' => '类',
  '��' => '泪',
  '��' => '棱',
  '��' => '楞',
  '��' => '冷',
  '��' => '厘',
  '��' => '梨',
  '��' => '犁',
  '��' => '黎',
  '��' => '篱',
  '��' => '狸',
  '��' => '离',
  '��' => '漓',
  '��' => '理',
  '��' => '李',
  '��' => '里',
  '��' => '鲤',
  '��' => '礼',
  '��' => '莉',
  '��' => '荔',
  '��' => '吏',
  '��' => '栗',
  '��' => '丽',
  '��' => '厉',
  '��' => '励',
  '��' => '砾',
  '��' => '历',
  '��' => '利',
  '��' => '傈',
  '��' => '例',
  '��' => '俐',
  '�@' => '罖',
  '�A' => '罙',
  '�B' => '罛',
  '�C' => '罜',
  '�D' => '罝',
  '�E' => '罞',
  '�F' => '罠',
  '�G' => '罣',
  '�H' => '罤',
  '�I' => '罥',
  '�J' => '罦',
  '�K' => '罧',
  '�L' => '罫',
  '�M' => '罬',
  '�N' => '罭',
  '�O' => '罯',
  '�P' => '罰',
  '�Q' => '罳',
  '�R' => '罵',
  '�S' => '罶',
  '�T' => '罷',
  '�U' => '罸',
  '�V' => '罺',
  '�W' => '罻',
  '�X' => '罼',
  '�Y' => '罽',
  '�Z' => '罿',
  '�[' => '羀',
  '�\\' => '羂',
  '�]' => '羃',
  '�^' => '羄',
  '�_' => '羅',
  '�`' => '羆',
  '�a' => '羇',
  '�b' => '羈',
  '�c' => '羉',
  '�d' => '羋',
  '�e' => '羍',
  '�f' => '羏',
  '�g' => '羐',
  '�h' => '羑',
  '�i' => '羒',
  '�j' => '羓',
  '�k' => '羕',
  '�l' => '羖',
  '�m' => '羗',
  '�n' => '羘',
  '�o' => '羙',
  '�p' => '羛',
  '�q' => '羜',
  '�r' => '羠',
  '�s' => '羢',
  '�t' => '羣',
  '�u' => '羥',
  '�v' => '羦',
  '�w' => '羨',
  '�x' => '義',
  '�y' => '羪',
  '�z' => '羫',
  '�{' => '羬',
  '�|' => '羭',
  '�}' => '羮',
  '�~' => '羱',
  '��' => '羳',
  '��' => '羴',
  '��' => '羵',
  '��' => '羶',
  '��' => '羷',
  '��' => '羺',
  '��' => '羻',
  '��' => '羾',
  '��' => '翀',
  '��' => '翂',
  '��' => '翃',
  '��' => '翄',
  '��' => '翆',
  '��' => '翇',
  '��' => '翈',
  '��' => '翉',
  '��' => '翋',
  '��' => '翍',
  '��' => '翏',
  '��' => '翐',
  '��' => '翑',
  '��' => '習',
  '��' => '翓',
  '��' => '翖',
  '��' => '翗',
  '��' => '翙',
  '��' => '翚',
  '��' => '翛',
  '��' => '翜',
  '��' => '翝',
  '��' => '翞',
  '��' => '翢',
  '��' => '翣',
  '��' => '痢',
  '��' => '立',
  '��' => '粒',
  '��' => '沥',
  '��' => '隶',
  '��' => '力',
  '��' => '璃',
  '��' => '哩',
  '��' => '俩',
  '��' => '联',
  '��' => '莲',
  '��' => '连',
  '��' => '镰',
  '��' => '廉',
  '��' => '怜',
  '��' => '涟',
  '��' => '帘',
  '��' => '敛',
  '��' => '脸',
  '��' => '链',
  '��' => '恋',
  '��' => '炼',
  '��' => '练',
  '��' => '粮',
  '��' => '凉',
  '��' => '梁',
  '��' => '粱',
  '��' => '良',
  '��' => '两',
  '��' => '辆',
  '��' => '量',
  '��' => '晾',
  '��' => '亮',
  '��' => '谅',
  '��' => '撩',
  '��' => '聊',
  '��' => '僚',
  '��' => '疗',
  '��' => '燎',
  '��' => '寥',
  '��' => '辽',
  '��' => '潦',
  '��' => '了',
  '��' => '撂',
  '��' => '镣',
  '��' => '廖',
  '��' => '料',
  '��' => '列',
  '��' => '裂',
  '��' => '烈',
  '��' => '劣',
  '��' => '猎',
  '��' => '琳',
  '��' => '林',
  '��' => '磷',
  '��' => '霖',
  '��' => '临',
  '��' => '邻',
  '��' => '鳞',
  '��' => '淋',
  '��' => '凛',
  '��' => '赁',
  '��' => '吝',
  '��' => '拎',
  '��' => '玲',
  '��' => '菱',
  '��' => '零',
  '��' => '龄',
  '��' => '铃',
  '��' => '伶',
  '��' => '羚',
  '��' => '凌',
  '��' => '灵',
  '��' => '陵',
  '��' => '岭',
  '��' => '领',
  '��' => '另',
  '��' => '令',
  '��' => '溜',
  '��' => '琉',
  '��' => '榴',
  '��' => '硫',
  '��' => '馏',
  '��' => '留',
  '��' => '刘',
  '��' => '瘤',
  '��' => '流',
  '��' => '柳',
  '��' => '六',
  '��' => '龙',
  '��' => '聋',
  '��' => '咙',
  '��' => '笼',
  '��' => '窿',
  '�@' => '翤',
  '�A' => '翧',
  '�B' => '翨',
  '�C' => '翪',
  '�D' => '翫',
  '�E' => '翬',
  '�F' => '翭',
  '�G' => '翯',
  '�H' => '翲',
  '�I' => '翴',
  '�J' => '翵',
  '�K' => '翶',
  '�L' => '翷',
  '�M' => '翸',
  '�N' => '翹',
  '�O' => '翺',
  '�P' => '翽',
  '�Q' => '翾',
  '�R' => '翿',
  '�S' => '耂',
  '�T' => '耇',
  '�U' => '耈',
  '�V' => '耉',
  '�W' => '耊',
  '�X' => '耎',
  '�Y' => '耏',
  '�Z' => '耑',
  '�[' => '耓',
  '�\\' => '耚',
  '�]' => '耛',
  '�^' => '耝',
  '�_' => '耞',
  '�`' => '耟',
  '�a' => '耡',
  '�b' => '耣',
  '�c' => '耤',
  '�d' => '耫',
  '�e' => '耬',
  '�f' => '耭',
  '�g' => '耮',
  '�h' => '耯',
  '�i' => '耰',
  '�j' => '耲',
  '�k' => '耴',
  '�l' => '耹',
  '�m' => '耺',
  '�n' => '耼',
  '�o' => '耾',
  '�p' => '聀',
  '�q' => '聁',
  '�r' => '聄',
  '�s' => '聅',
  '�t' => '聇',
  '�u' => '聈',
  '�v' => '聉',
  '�w' => '聎',
  '�x' => '聏',
  '�y' => '聐',
  '�z' => '聑',
  '�{' => '聓',
  '�|' => '聕',
  '�}' => '聖',
  '�~' => '聗',
  '€' => '聙',
  '' => '聛',
  '‚' => '聜',
  'ƒ' => '聝',
  '„' => '聞',
  '…' => '聟',
  '†' => '聠',
  '‡' => '聡',
  'ˆ' => '聢',
  '‰' => '聣',
  'Š' => '聤',
  '‹' => '聥',
  'Œ' => '聦',
  '' => '聧',
  'Ž' => '聨',
  '' => '聫',
  '' => '聬',
  '‘' => '聭',
  '’' => '聮',
  '“' => '聯',
  '”' => '聰',
  '•' => '聲',
  '–' => '聳',
  '—' => '聴',
  '˜' => '聵',
  '™' => '聶',
  'š' => '職',
  '›' => '聸',
  'œ' => '聹',
  '' => '聺',
  'ž' => '聻',
  'Ÿ' => '聼',
  ' ' => '聽',
  '¡' => '隆',
  '¢' => '垄',
  '£' => '拢',
  '¤' => '陇',
  '¥' => '楼',
  '¦' => '娄',
  '§' => '搂',
  '¨' => '篓',
  '©' => '漏',
  'ª' => '陋',
  '«' => '芦',
  '¬' => '卢',
  '­' => '颅',
  '®' => '庐',
  '¯' => '炉',
  '°' => '掳',
  '±' => '卤',
  '²' => '虏',
  '³' => '鲁',
  '´' => '麓',
  'µ' => '碌',
  '¶' => '露',
  '·' => '路',
  '¸' => '赂',
  '¹' => '鹿',
  'º' => '潞',
  '»' => '禄',
  '¼' => '录',
  '½' => '陆',
  '¾' => '戮',
  '¿' => '驴',
  '�' => '吕',
  '�' => '铝',
  '��' => '侣',
  '��' => '旅',
  '��' => '履',
  '��' => '屡',
  '��' => '缕',
  '��' => '虑',
  '��' => '氯',
  '��' => '律',
  '��' => '率',
  '��' => '滤',
  '��' => '绿',
  '��' => '峦',
  '��' => '挛',
  '��' => '孪',
  '��' => '滦',
  '��' => '卵',
  '��' => '乱',
  '��' => '掠',
  '��' => '略',
  '��' => '抡',
  '��' => '轮',
  '��' => '伦',
  '��' => '仑',
  '��' => '沦',
  '��' => '纶',
  '��' => '论',
  '��' => '萝',
  '��' => '螺',
  '��' => '罗',
  '��' => '逻',
  '��' => '锣',
  '��' => '箩',
  '��' => '骡',
  '��' => '裸',
  '��' => '落',
  '��' => '洛',
  '��' => '骆',
  '��' => '络',
  '��' => '妈',
  '��' => '麻',
  '��' => '玛',
  '��' => '码',
  '��' => '蚂',
  '��' => '马',
  '��' => '骂',
  '��' => '嘛',
  '��' => '吗',
  '��' => '埋',
  '��' => '买',
  '��' => '麦',
  '��' => '卖',
  '�' => '迈',
  '�' => '脉',
  '�' => '瞒',
  '�' => '馒',
  '�' => '蛮',
  '�' => '满',
  '�' => '蔓',
  '�' => '曼',
  '�' => '慢',
  '�' => '漫',
  '�@' => '聾',
  '�A' => '肁',
  '�B' => '肂',
  '�C' => '肅',
  '�D' => '肈',
  '�E' => '肊',
  '�F' => '肍',
  '�G' => '肎',
  '�H' => '肏',
  '�I' => '肐',
  '�J' => '肑',
  '�K' => '肒',
  '�L' => '肔',
  '�M' => '肕',
  '�N' => '肗',
  '�O' => '肙',
  '�P' => '肞',
  '�Q' => '肣',
  '�R' => '肦',
  '�S' => '肧',
  '�T' => '肨',
  '�U' => '肬',
  '�V' => '肰',
  '�W' => '肳',
  '�X' => '肵',
  '�Y' => '肶',
  '�Z' => '肸',
  '�[' => '肹',
  '�\\' => '肻',
  '�]' => '胅',
  '�^' => '胇',
  '�_' => '胈',
  '�`' => '胉',
  '�a' => '胊',
  '�b' => '胋',
  '�c' => '胏',
  '�d' => '胐',
  '�e' => '胑',
  '�f' => '胒',
  '�g' => '胓',
  '�h' => '胔',
  '�i' => '胕',
  '�j' => '胘',
  '�k' => '胟',
  '�l' => '胠',
  '�m' => '胢',
  '�n' => '胣',
  '�o' => '胦',
  '�p' => '胮',
  '�q' => '胵',
  '�r' => '胷',
  '�s' => '胹',
  '�t' => '胻',
  '�u' => '胾',
  '�v' => '胿',
  '�w' => '脀',
  '�x' => '脁',
  '�y' => '脃',
  '�z' => '脄',
  '�{' => '脅',
  '�|' => '脇',
  '�}' => '脈',
  '�~' => '脋',
  'À' => '脌',
  'Á' => '脕',
  'Â' => '脗',
  'Ã' => '脙',
  'Ä' => '脛',
  'Å' => '脜',
  'Æ' => '脝',
  'Ç' => '脟',
  'È' => '脠',
  'É' => '脡',
  'Ê' => '脢',
  'Ë' => '脣',
  'Ì' => '脤',
  'Í' => '脥',
  'Î' => '脦',
  'Ï' => '脧',
  'Ð' => '脨',
  'Ñ' => '脩',
  'Ò' => '脪',
  'Ó' => '脫',
  'Ô' => '脭',
  'Õ' => '脮',
  'Ö' => '脰',
  '×' => '脳',
  'Ø' => '脴',
  'Ù' => '脵',
  'Ú' => '脷',
  'Û' => '脹',
  'Ü' => '脺',
  'Ý' => '脻',
  'Þ' => '脼',
  'ß' => '脽',
  'à' => '脿',
  'á' => '谩',
  'â' => '芒',
  'ã' => '茫',
  'ä' => '盲',
  'å' => '氓',
  'æ' => '忙',
  'ç' => '莽',
  'è' => '猫',
  'é' => '茅',
  'ê' => '锚',
  'ë' => '毛',
  'ì' => '矛',
  'í' => '铆',
  'î' => '卯',
  'ï' => '茂',
  'ð' => '冒',
  'ñ' => '帽',
  'ò' => '貌',
  'ó' => '贸',
  'ô' => '么',
  'õ' => '玫',
  'ö' => '枚',
  '÷' => '梅',
  'ø' => '酶',
  'ù' => '霉',
  'ú' => '煤',
  'û' => '没',
  'ü' => '眉',
  'ý' => '媒',
  'þ' => '镁',
  'ÿ' => '每',
  '�' => '美',
  '�' => '昧',
  '��' => '寐',
  '��' => '妹',
  '��' => '媚',
  '��' => '门',
  '��' => '闷',
  '��' => '们',
  '��' => '萌',
  '��' => '蒙',
  '��' => '檬',
  '��' => '盟',
  '��' => '锰',
  '��' => '猛',
  '��' => '梦',
  '��' => '孟',
  '��' => '眯',
  '��' => '醚',
  '��' => '靡',
  '��' => '糜',
  '��' => '迷',
  '��' => '谜',
  '��' => '弥',
  '��' => '米',
  '��' => '秘',
  '��' => '觅',
  '��' => '泌',
  '��' => '蜜',
  '��' => '密',
  '��' => '幂',
  '��' => '棉',
  '��' => '眠',
  '��' => '绵',
  '��' => '冕',
  '��' => '免',
  '��' => '勉',
  '��' => '娩',
  '��' => '缅',
  '��' => '面',
  '��' => '苗',
  '��' => '描',
  '��' => '瞄',
  '��' => '藐',
  '��' => '秒',
  '��' => '渺',
  '��' => '庙',
  '��' => '妙',
  '��' => '蔑',
  '��' => '灭',
  '��' => '民',
  '��' => '抿',
  '��' => '皿',
  '��' => '敏',
  '�' => '悯',
  '�' => '闽',
  '�' => '明',
  '�' => '螟',
  '�' => '鸣',
  '�' => '铭',
  '�' => '名',
  '�' => '命',
  '�' => '谬',
  '�' => '摸',
  '�@' => '腀',
  '�A' => '腁',
  '�B' => '腂',
  '�C' => '腃',
  '�D' => '腄',
  '�E' => '腅',
  '�F' => '腇',
  '�G' => '腉',
  '�H' => '腍',
  '�I' => '腎',
  '�J' => '腏',
  '�K' => '腒',
  '�L' => '腖',
  '�M' => '腗',
  '�N' => '腘',
  '�O' => '腛',
  '�P' => '腜',
  '�Q' => '腝',
  '�R' => '腞',
  '�S' => '腟',
  '�T' => '腡',
  '�U' => '腢',
  '�V' => '腣',
  '�W' => '腤',
  '�X' => '腦',
  '�Y' => '腨',
  '�Z' => '腪',
  '�[' => '腫',
  '�\\' => '腬',
  '�]' => '腯',
  '�^' => '腲',
  '�_' => '腳',
  '�`' => '腵',
  '�a' => '腶',
  '�b' => '腷',
  '�c' => '腸',
  '�d' => '膁',
  '�e' => '膃',
  '�f' => '膄',
  '�g' => '膅',
  '�h' => '膆',
  '�i' => '膇',
  '�j' => '膉',
  '�k' => '膋',
  '�l' => '膌',
  '�m' => '膍',
  '�n' => '膎',
  '�o' => '膐',
  '�p' => '膒',
  '�q' => '膓',
  '�r' => '膔',
  '�s' => '膕',
  '�t' => '膖',
  '�u' => '膗',
  '�v' => '膙',
  '�w' => '膚',
  '�x' => '膞',
  '�y' => '膟',
  '�z' => '膠',
  '�{' => '膡',
  '�|' => '膢',
  '�}' => '膤',
  '�~' => '膥',
  'Ā' => '膧',
  'ā' => '膩',
  'Ă' => '膫',
  'ă' => '膬',
  'Ą' => '膭',
  'ą' => '膮',
  'Ć' => '膯',
  'ć' => '膰',
  'Ĉ' => '膱',
  'ĉ' => '膲',
  'Ċ' => '膴',
  'ċ' => '膵',
  'Č' => '膶',
  'č' => '膷',
  'Ď' => '膸',
  'ď' => '膹',
  'Đ' => '膼',
  'đ' => '膽',
  'Ē' => '膾',
  'ē' => '膿',
  'Ĕ' => '臄',
  'ĕ' => '臅',
  'Ė' => '臇',
  'ė' => '臈',
  'Ę' => '臉',
  'ę' => '臋',
  'Ě' => '臍',
  'ě' => '臎',
  'Ĝ' => '臏',
  'ĝ' => '臐',
  'Ğ' => '臑',
  'ğ' => '臒',
  'Ġ' => '臓',
  'ġ' => '摹',
  'Ģ' => '蘑',
  'ģ' => '模',
  'Ĥ' => '膜',
  'ĥ' => '磨',
  'Ħ' => '摩',
  'ħ' => '魔',
  'Ĩ' => '抹',
  'ĩ' => '末',
  'Ī' => '莫',
  'ī' => '墨',
  'Ĭ' => '默',
  'ĭ' => '沫',
  'Į' => '漠',
  'į' => '寞',
  'İ' => '陌',
  'ı' => '谋',
  'IJ' => '牟',
  'ij' => '某',
  'Ĵ' => '拇',
  'ĵ' => '牡',
  'Ķ' => '亩',
  'ķ' => '姆',
  'ĸ' => '母',
  'Ĺ' => '墓',
  'ĺ' => '暮',
  'Ļ' => '幕',
  'ļ' => '募',
  'Ľ' => '慕',
  'ľ' => '木',
  'Ŀ' => '目',
  '�' => '睦',
  '�' => '牧',
  '��' => '穆',
  '��' => '拿',
  '��' => '哪',
  '��' => '呐',
  '��' => '钠',
  '��' => '那',
  '��' => '娜',
  '��' => '纳',
  '��' => '氖',
  '��' => '乃',
  '��' => '奶',
  '��' => '耐',
  '��' => '奈',
  '��' => '南',
  '��' => '男',
  '��' => '难',
  '��' => '囊',
  '��' => '挠',
  '��' => '脑',
  '��' => '恼',
  '��' => '闹',
  '��' => '淖',
  '��' => '呢',
  '��' => '馁',
  '��' => '内',
  '��' => '嫩',
  '��' => '能',
  '��' => '妮',
  '��' => '霓',
  '��' => '倪',
  '��' => '泥',
  '��' => '尼',
  '��' => '拟',
  '��' => '你',
  '��' => '匿',
  '��' => '腻',
  '��' => '逆',
  '��' => '溺',
  '��' => '蔫',
  '��' => '拈',
  '��' => '年',
  '��' => '碾',
  '��' => '撵',
  '��' => '捻',
  '��' => '念',
  '��' => '娘',
  '��' => '酿',
  '��' => '鸟',
  '��' => '尿',
  '��' => '捏',
  '��' => '聂',
  '�' => '孽',
  '�' => '啮',
  '�' => '镊',
  '�' => '镍',
  '�' => '涅',
  '�' => '您',
  '�' => '柠',
  '�' => '狞',
  '�' => '凝',
  '�' => '宁',
  '�@' => '臔',
  '�A' => '臕',
  '�B' => '臖',
  '�C' => '臗',
  '�D' => '臘',
  '�E' => '臙',
  '�F' => '臚',
  '�G' => '臛',
  '�H' => '臜',
  '�I' => '臝',
  '�J' => '臞',
  '�K' => '臟',
  '�L' => '臠',
  '�M' => '臡',
  '�N' => '臢',
  '�O' => '臤',
  '�P' => '臥',
  '�Q' => '臦',
  '�R' => '臨',
  '�S' => '臩',
  '�T' => '臫',
  '�U' => '臮',
  '�V' => '臯',
  '�W' => '臰',
  '�X' => '臱',
  '�Y' => '臲',
  '�Z' => '臵',
  '�[' => '臶',
  '�\\' => '臷',
  '�]' => '臸',
  '�^' => '臹',
  '�_' => '臺',
  '�`' => '臽',
  '�a' => '臿',
  '�b' => '舃',
  '�c' => '與',
  '�d' => '興',
  '�e' => '舉',
  '�f' => '舊',
  '�g' => '舋',
  '�h' => '舎',
  '�i' => '舏',
  '�j' => '舑',
  '�k' => '舓',
  '�l' => '舕',
  '�m' => '舖',
  '�n' => '舗',
  '�o' => '舘',
  '�p' => '舙',
  '�q' => '舚',
  '�r' => '舝',
  '�s' => '舠',
  '�t' => '舤',
  '�u' => '舥',
  '�v' => '舦',
  '�w' => '舧',
  '�x' => '舩',
  '�y' => '舮',
  '�z' => '舲',
  '�{' => '舺',
  '�|' => '舼',
  '�}' => '舽',
  '�~' => '舿',
  'ŀ' => '艀',
  'Ł' => '艁',
  'ł' => '艂',
  'Ń' => '艃',
  'ń' => '艅',
  'Ņ' => '艆',
  'ņ' => '艈',
  'Ň' => '艊',
  'ň' => '艌',
  'ʼn' => '艍',
  'Ŋ' => '艎',
  'ŋ' => '艐',
  'Ō' => '艑',
  'ō' => '艒',
  'Ŏ' => '艓',
  'ŏ' => '艔',
  'Ő' => '艕',
  'ő' => '艖',
  'Œ' => '艗',
  'œ' => '艙',
  'Ŕ' => '艛',
  'ŕ' => '艜',
  'Ŗ' => '艝',
  'ŗ' => '艞',
  'Ř' => '艠',
  'ř' => '艡',
  'Ś' => '艢',
  'ś' => '艣',
  'Ŝ' => '艤',
  'ŝ' => '艥',
  'Ş' => '艦',
  'ş' => '艧',
  'Š' => '艩',
  'š' => '拧',
  'Ţ' => '泞',
  'ţ' => '牛',
  'Ť' => '扭',
  'ť' => '钮',
  'Ŧ' => '纽',
  'ŧ' => '脓',
  'Ũ' => '浓',
  'ũ' => '农',
  'Ū' => '弄',
  'ū' => '奴',
  'Ŭ' => '努',
  'ŭ' => '怒',
  'Ů' => '女',
  'ů' => '暖',
  'Ű' => '虐',
  'ű' => '疟',
  'Ų' => '挪',
  'ų' => '懦',
  'Ŵ' => '糯',
  'ŵ' => '诺',
  'Ŷ' => '哦',
  'ŷ' => '欧',
  'Ÿ' => '鸥',
  'Ź' => '殴',
  'ź' => '藕',
  'Ż' => '呕',
  'ż' => '偶',
  'Ž' => '沤',
  'ž' => '啪',
  'ſ' => '趴',
  '�' => '爬',
  '�' => '帕',
  '��' => '怕',
  '��' => '琶',
  '��' => '拍',
  '��' => '排',
  '��' => '牌',
  '��' => '徘',
  '��' => '湃',
  '��' => '派',
  '��' => '攀',
  '��' => '潘',
  '��' => '盘',
  '��' => '磐',
  '��' => '盼',
  '��' => '畔',
  '��' => '判',
  '��' => '叛',
  '��' => '乓',
  '��' => '庞',
  '��' => '旁',
  '��' => '耪',
  '��' => '胖',
  '��' => '抛',
  '��' => '咆',
  '��' => '刨',
  '��' => '炮',
  '��' => '袍',
  '��' => '跑',
  '��' => '泡',
  '��' => '呸',
  '��' => '胚',
  '��' => '培',
  '��' => '裴',
  '��' => '赔',
  '��' => '陪',
  '��' => '配',
  '��' => '佩',
  '��' => '沛',
  '��' => '喷',
  '��' => '盆',
  '��' => '砰',
  '��' => '抨',
  '��' => '烹',
  '��' => '澎',
  '��' => '彭',
  '��' => '蓬',
  '��' => '棚',
  '��' => '硼',
  '��' => '篷',
  '��' => '膨',
  '��' => '朋',
  '��' => '鹏',
  '�' => '捧',
  '�' => '碰',
  '�' => '坯',
  '�' => '砒',
  '�' => '霹',
  '�' => '批',
  '�' => '披',
  '�' => '劈',
  '�' => '琵',
  '�' => '毗',
  '�@' => '艪',
  '�A' => '艫',
  '�B' => '艬',
  '�C' => '艭',
  '�D' => '艱',
  '�E' => '艵',
  '�F' => '艶',
  '�G' => '艷',
  '�H' => '艸',
  '�I' => '艻',
  '�J' => '艼',
  '�K' => '芀',
  '�L' => '芁',
  '�M' => '芃',
  '�N' => '芅',
  '�O' => '芆',
  '�P' => '芇',
  '�Q' => '芉',
  '�R' => '芌',
  '�S' => '芐',
  '�T' => '芓',
  '�U' => '芔',
  '�V' => '芕',
  '�W' => '芖',
  '�X' => '芚',
  '�Y' => '芛',
  '�Z' => '芞',
  '�[' => '芠',
  '�\\' => '芢',
  '�]' => '芣',
  '�^' => '芧',
  '�_' => '芲',
  '�`' => '芵',
  '�a' => '芶',
  '�b' => '芺',
  '�c' => '芻',
  '�d' => '芼',
  '�e' => '芿',
  '�f' => '苀',
  '�g' => '苂',
  '�h' => '苃',
  '�i' => '苅',
  '�j' => '苆',
  '�k' => '苉',
  '�l' => '苐',
  '�m' => '苖',
  '�n' => '苙',
  '�o' => '苚',
  '�p' => '苝',
  '�q' => '苢',
  '�r' => '苧',
  '�s' => '苨',
  '�t' => '苩',
  '�u' => '苪',
  '�v' => '苬',
  '�w' => '苭',
  '�x' => '苮',
  '�y' => '苰',
  '�z' => '苲',
  '�{' => '苳',
  '�|' => '苵',
  '�}' => '苶',
  '�~' => '苸',
  'ƀ' => '苺',
  'Ɓ' => '苼',
  'Ƃ' => '苽',
  'ƃ' => '苾',
  'Ƅ' => '苿',
  'ƅ' => '茀',
  'Ɔ' => '茊',
  'Ƈ' => '茋',
  'ƈ' => '茍',
  'Ɖ' => '茐',
  'Ɗ' => '茒',
  'Ƌ' => '茓',
  'ƌ' => '茖',
  'ƍ' => '茘',
  'Ǝ' => '茙',
  'Ə' => '茝',
  'Ɛ' => '茞',
  'Ƒ' => '茟',
  'ƒ' => '茠',
  'Ɠ' => '茡',
  'Ɣ' => '茢',
  'ƕ' => '茣',
  'Ɩ' => '茤',
  'Ɨ' => '茥',
  'Ƙ' => '茦',
  'ƙ' => '茩',
  'ƚ' => '茪',
  'ƛ' => '茮',
  'Ɯ' => '茰',
  'Ɲ' => '茲',
  'ƞ' => '茷',
  'Ɵ' => '茻',
  'Ơ' => '茽',
  'ơ' => '啤',
  'Ƣ' => '脾',
  'ƣ' => '疲',
  'Ƥ' => '皮',
  'ƥ' => '匹',
  'Ʀ' => '痞',
  'Ƨ' => '僻',
  'ƨ' => '屁',
  'Ʃ' => '譬',
  'ƪ' => '篇',
  'ƫ' => '偏',
  'Ƭ' => '片',
  'ƭ' => '骗',
  'Ʈ' => '飘',
  'Ư' => '漂',
  'ư' => '瓢',
  'Ʊ' => '票',
  'Ʋ' => '撇',
  'Ƴ' => '瞥',
  'ƴ' => '拼',
  'Ƶ' => '频',
  'ƶ' => '贫',
  'Ʒ' => '品',
  'Ƹ' => '聘',
  'ƹ' => '乒',
  'ƺ' => '坪',
  'ƻ' => '苹',
  'Ƽ' => '萍',
  'ƽ' => '平',
  'ƾ' => '凭',
  'ƿ' => '瓶',
  '�' => '评',
  '�' => '屏',
  '��' => '坡',
  '��' => '泼',
  '��' => '颇',
  '��' => '婆',
  '��' => '破',
  '��' => '魄',
  '��' => '迫',
  '��' => '粕',
  '��' => '剖',
  '��' => '扑',
  '��' => '铺',
  '��' => '仆',
  '��' => '莆',
  '��' => '葡',
  '��' => '菩',
  '��' => '蒲',
  '��' => '埔',
  '��' => '朴',
  '��' => '圃',
  '��' => '普',
  '��' => '浦',
  '��' => '谱',
  '��' => '曝',
  '��' => '瀑',
  '��' => '期',
  '��' => '欺',
  '��' => '栖',
  '��' => '戚',
  '��' => '妻',
  '��' => '七',
  '��' => '凄',
  '��' => '漆',
  '��' => '柒',
  '��' => '沏',
  '��' => '其',
  '��' => '棋',
  '��' => '奇',
  '��' => '歧',
  '��' => '畦',
  '��' => '崎',
  '��' => '脐',
  '��' => '齐',
  '��' => '旗',
  '��' => '祈',
  '��' => '祁',
  '��' => '骑',
  '��' => '起',
  '��' => '岂',
  '��' => '乞',
  '��' => '企',
  '��' => '启',
  '�' => '契',
  '�' => '砌',
  '�' => '器',
  '�' => '气',
  '�' => '迄',
  '�' => '弃',
  '�' => '汽',
  '�' => '泣',
  '�' => '讫',
  '�' => '掐',
  '�@' => '茾',
  '�A' => '茿',
  '�B' => '荁',
  '�C' => '荂',
  '�D' => '荄',
  '�E' => '荅',
  '�F' => '荈',
  '�G' => '荊',
  '�H' => '荋',
  '�I' => '荌',
  '�J' => '荍',
  '�K' => '荎',
  '�L' => '荓',
  '�M' => '荕',
  '�N' => '荖',
  '�O' => '荗',
  '�P' => '荘',
  '�Q' => '荙',
  '�R' => '荝',
  '�S' => '荢',
  '�T' => '荰',
  '�U' => '荱',
  '�V' => '荲',
  '�W' => '荳',
  '�X' => '荴',
  '�Y' => '荵',
  '�Z' => '荶',
  '�[' => '荹',
  '�\\' => '荺',
  '�]' => '荾',
  '�^' => '荿',
  '�_' => '莀',
  '�`' => '莁',
  '�a' => '莂',
  '�b' => '莃',
  '�c' => '莄',
  '�d' => '莇',
  '�e' => '莈',
  '�f' => '莊',
  '�g' => '莋',
  '�h' => '莌',
  '�i' => '莍',
  '�j' => '莏',
  '�k' => '莐',
  '�l' => '莑',
  '�m' => '莔',
  '�n' => '莕',
  '�o' => '莖',
  '�p' => '莗',
  '�q' => '莙',
  '�r' => '莚',
  '�s' => '莝',
  '�t' => '莟',
  '�u' => '莡',
  '�v' => '莢',
  '�w' => '莣',
  '�x' => '莤',
  '�y' => '莥',
  '�z' => '莦',
  '�{' => '莧',
  '�|' => '莬',
  '�}' => '莭',
  '�~' => '莮',
  'ǀ' => '莯',
  'ǁ' => '莵',
  'ǂ' => '莻',
  'ǃ' => '莾',
  'DŽ' => '莿',
  'Dž' => '菂',
  'dž' => '菃',
  'LJ' => '菄',
  'Lj' => '菆',
  'lj' => '菈',
  'NJ' => '菉',
  'Nj' => '菋',
  'nj' => '菍',
  'Ǎ' => '菎',
  'ǎ' => '菐',
  'Ǐ' => '菑',
  'ǐ' => '菒',
  'Ǒ' => '菓',
  'ǒ' => '菕',
  'Ǔ' => '菗',
  'ǔ' => '菙',
  'Ǖ' => '菚',
  'ǖ' => '菛',
  'Ǘ' => '菞',
  'ǘ' => '菢',
  'Ǚ' => '菣',
  'ǚ' => '菤',
  'Ǜ' => '菦',
  'ǜ' => '菧',
  'ǝ' => '菨',
  'Ǟ' => '菫',
  'ǟ' => '菬',
  'Ǡ' => '菭',
  'ǡ' => '恰',
  'Ǣ' => '洽',
  'ǣ' => '牵',
  'Ǥ' => '扦',
  'ǥ' => '钎',
  'Ǧ' => '铅',
  'ǧ' => '千',
  'Ǩ' => '迁',
  'ǩ' => '签',
  'Ǫ' => '仟',
  'ǫ' => '谦',
  'Ǭ' => '乾',
  'ǭ' => '黔',
  'Ǯ' => '钱',
  'ǯ' => '钳',
  'ǰ' => '前',
  'DZ' => '潜',
  'Dz' => '遣',
  'dz' => '浅',
  'Ǵ' => '谴',
  'ǵ' => '堑',
  'Ƕ' => '嵌',
  'Ƿ' => '欠',
  'Ǹ' => '歉',
  'ǹ' => '枪',
  'Ǻ' => '呛',
  'ǻ' => '腔',
  'Ǽ' => '羌',
  'ǽ' => '墙',
  'Ǿ' => '蔷',
  'ǿ' => '强',
  '�' => '抢',
  '�' => '橇',
  '��' => '锹',
  '��' => '敲',
  '��' => '悄',
  '��' => '桥',
  '��' => '瞧',
  '��' => '乔',
  '��' => '侨',
  '��' => '巧',
  '��' => '鞘',
  '��' => '撬',
  '��' => '翘',
  '��' => '峭',
  '��' => '俏',
  '��' => '窍',
  '��' => '切',
  '��' => '茄',
  '��' => '且',
  '��' => '怯',
  '��' => '窃',
  '��' => '钦',
  '��' => '侵',
  '��' => '亲',
  '��' => '秦',
  '��' => '琴',
  '��' => '勤',
  '��' => '芹',
  '��' => '擒',
  '��' => '禽',
  '��' => '寝',
  '��' => '沁',
  '��' => '青',
  '��' => '轻',
  '��' => '氢',
  '��' => '倾',
  '��' => '卿',
  '��' => '清',
  '��' => '擎',
  '��' => '晴',
  '��' => '氰',
  '��' => '情',
  '��' => '顷',
  '��' => '请',
  '��' => '庆',
  '��' => '琼',
  '��' => '穷',
  '��' => '秋',
  '��' => '丘',
  '��' => '邱',
  '��' => '球',
  '��' => '求',
  '��' => '囚',
  '�' => '酋',
  '�' => '泅',
  '�' => '趋',
  '�' => '区',
  '�' => '蛆',
  '�' => '曲',
  '�' => '躯',
  '�' => '屈',
  '�' => '驱',
  '�' => '渠',
  '�@' => '菮',
  '�A' => '華',
  '�B' => '菳',
  '�C' => '菴',
  '�D' => '菵',
  '�E' => '菶',
  '�F' => '菷',
  '�G' => '菺',
  '�H' => '菻',
  '�I' => '菼',
  '�J' => '菾',
  '�K' => '菿',
  '�L' => '萀',
  '�M' => '萂',
  '�N' => '萅',
  '�O' => '萇',
  '�P' => '萈',
  '�Q' => '萉',
  '�R' => '萊',
  '�S' => '萐',
  '�T' => '萒',
  '�U' => '萓',
  '�V' => '萔',
  '�W' => '萕',
  '�X' => '萖',
  '�Y' => '萗',
  '�Z' => '萙',
  '�[' => '萚',
  '�\\' => '萛',
  '�]' => '萞',
  '�^' => '萟',
  '�_' => '萠',
  '�`' => '萡',
  '�a' => '萢',
  '�b' => '萣',
  '�c' => '萩',
  '�d' => '萪',
  '�e' => '萫',
  '�f' => '萬',
  '�g' => '萭',
  '�h' => '萮',
  '�i' => '萯',
  '�j' => '萰',
  '�k' => '萲',
  '�l' => '萳',
  '�m' => '萴',
  '�n' => '萵',
  '�o' => '萶',
  '�p' => '萷',
  '�q' => '萹',
  '�r' => '萺',
  '�s' => '萻',
  '�t' => '萾',
  '�u' => '萿',
  '�v' => '葀',
  '�w' => '葁',
  '�x' => '葂',
  '�y' => '葃',
  '�z' => '葄',
  '�{' => '葅',
  '�|' => '葇',
  '�}' => '葈',
  '�~' => '葉',
  'Ȁ' => '葊',
  'ȁ' => '葋',
  'Ȃ' => '葌',
  'ȃ' => '葍',
  'Ȅ' => '葎',
  'ȅ' => '葏',
  'Ȇ' => '葐',
  'ȇ' => '葒',
  'Ȉ' => '葓',
  'ȉ' => '葔',
  'Ȋ' => '葕',
  'ȋ' => '葖',
  'Ȍ' => '葘',
  'ȍ' => '葝',
  'Ȏ' => '葞',
  'ȏ' => '葟',
  'Ȑ' => '葠',
  'ȑ' => '葢',
  'Ȓ' => '葤',
  'ȓ' => '葥',
  'Ȕ' => '葦',
  'ȕ' => '葧',
  'Ȗ' => '葨',
  'ȗ' => '葪',
  'Ș' => '葮',
  'ș' => '葯',
  'Ț' => '葰',
  'ț' => '葲',
  'Ȝ' => '葴',
  'ȝ' => '葷',
  'Ȟ' => '葹',
  'ȟ' => '葻',
  'Ƞ' => '葼',
  'ȡ' => '取',
  'Ȣ' => '娶',
  'ȣ' => '龋',
  'Ȥ' => '趣',
  'ȥ' => '去',
  'Ȧ' => '圈',
  'ȧ' => '颧',
  'Ȩ' => '权',
  'ȩ' => '醛',
  'Ȫ' => '泉',
  'ȫ' => '全',
  'Ȭ' => '痊',
  'ȭ' => '拳',
  'Ȯ' => '犬',
  'ȯ' => '券',
  'Ȱ' => '劝',
  'ȱ' => '缺',
  'Ȳ' => '炔',
  'ȳ' => '瘸',
  'ȴ' => '却',
  'ȵ' => '鹊',
  'ȶ' => '榷',
  'ȷ' => '确',
  'ȸ' => '雀',
  'ȹ' => '裙',
  'Ⱥ' => '群',
  'Ȼ' => '然',
  'ȼ' => '燃',
  'Ƚ' => '冉',
  'Ⱦ' => '染',
  'ȿ' => '瓤',
  '�' => '壤',
  '�' => '攘',
  '��' => '嚷',
  '��' => '让',
  '��' => '饶',
  '��' => '扰',
  '��' => '绕',
  '��' => '惹',
  '��' => '热',
  '��' => '壬',
  '��' => '仁',
  '��' => '人',
  '��' => '忍',
  '��' => '韧',
  '��' => '任',
  '��' => '认',
  '��' => '刃',
  '��' => '妊',
  '��' => '纫',
  '��' => '扔',
  '��' => '仍',
  '��' => '日',
  '��' => '戎',
  '��' => '茸',
  '��' => '蓉',
  '��' => '荣',
  '��' => '融',
  '��' => '熔',
  '��' => '溶',
  '��' => '容',
  '��' => '绒',
  '��' => '冗',
  '��' => '揉',
  '��' => '柔',
  '��' => '肉',
  '��' => '茹',
  '��' => '蠕',
  '��' => '儒',
  '��' => '孺',
  '��' => '如',
  '��' => '辱',
  '��' => '乳',
  '��' => '汝',
  '��' => '入',
  '��' => '褥',
  '��' => '软',
  '��' => '阮',
  '��' => '蕊',
  '��' => '瑞',
  '��' => '锐',
  '��' => '闰',
  '��' => '润',
  '��' => '若',
  '�' => '弱',
  '�' => '撒',
  '�' => '洒',
  '�' => '萨',
  '�' => '腮',
  '�' => '鳃',
  '�' => '塞',
  '�' => '赛',
  '�' => '三',
  '�' => '叁',
  '�@' => '葽',
  '�A' => '葾',
  '�B' => '葿',
  '�C' => '蒀',
  '�D' => '蒁',
  '�E' => '蒃',
  '�F' => '蒄',
  '�G' => '蒅',
  '�H' => '蒆',
  '�I' => '蒊',
  '�J' => '蒍',
  '�K' => '蒏',
  '�L' => '蒐',
  '�M' => '蒑',
  '�N' => '蒒',
  '�O' => '蒓',
  '�P' => '蒔',
  '�Q' => '蒕',
  '�R' => '蒖',
  '�S' => '蒘',
  '�T' => '蒚',
  '�U' => '蒛',
  '�V' => '蒝',
  '�W' => '蒞',
  '�X' => '蒟',
  '�Y' => '蒠',
  '�Z' => '蒢',
  '�[' => '蒣',
  '�\\' => '蒤',
  '�]' => '蒥',
  '�^' => '蒦',
  '�_' => '蒧',
  '�`' => '蒨',
  '�a' => '蒩',
  '�b' => '蒪',
  '�c' => '蒫',
  '�d' => '蒬',
  '�e' => '蒭',
  '�f' => '蒮',
  '�g' => '蒰',
  '�h' => '蒱',
  '�i' => '蒳',
  '�j' => '蒵',
  '�k' => '蒶',
  '�l' => '蒷',
  '�m' => '蒻',
  '�n' => '蒼',
  '�o' => '蒾',
  '�p' => '蓀',
  '�q' => '蓂',
  '�r' => '蓃',
  '�s' => '蓅',
  '�t' => '蓆',
  '�u' => '蓇',
  '�v' => '蓈',
  '�w' => '蓋',
  '�x' => '蓌',
  '�y' => '蓎',
  '�z' => '蓏',
  '�{' => '蓒',
  '�|' => '蓔',
  '�}' => '蓕',
  '�~' => '蓗',
  'ɀ' => '蓘',
  'Ɂ' => '蓙',
  'ɂ' => '蓚',
  'Ƀ' => '蓛',
  'Ʉ' => '蓜',
  'Ʌ' => '蓞',
  'Ɇ' => '蓡',
  'ɇ' => '蓢',
  'Ɉ' => '蓤',
  'ɉ' => '蓧',
  'Ɋ' => '蓨',
  'ɋ' => '蓩',
  'Ɍ' => '蓪',
  'ɍ' => '蓫',
  'Ɏ' => '蓭',
  'ɏ' => '蓮',
  'ɐ' => '蓯',
  'ɑ' => '蓱',
  'ɒ' => '蓲',
  'ɓ' => '蓳',
  'ɔ' => '蓴',
  'ɕ' => '蓵',
  'ɖ' => '蓶',
  'ɗ' => '蓷',
  'ɘ' => '蓸',
  'ə' => '蓹',
  'ɚ' => '蓺',
  'ɛ' => '蓻',
  'ɜ' => '蓽',
  'ɝ' => '蓾',
  'ɞ' => '蔀',
  'ɟ' => '蔁',
  'ɠ' => '蔂',
  'ɡ' => '伞',
  'ɢ' => '散',
  'ɣ' => '桑',
  'ɤ' => '嗓',
  'ɥ' => '丧',
  'ɦ' => '搔',
  'ɧ' => '骚',
  'ɨ' => '扫',
  'ɩ' => '嫂',
  'ɪ' => '瑟',
  'ɫ' => '色',
  'ɬ' => '涩',
  'ɭ' => '森',
  'ɮ' => '僧',
  'ɯ' => '莎',
  'ɰ' => '砂',
  'ɱ' => '杀',
  'ɲ' => '刹',
  'ɳ' => '沙',
  'ɴ' => '纱',
  'ɵ' => '傻',
  'ɶ' => '啥',
  'ɷ' => '煞',
  'ɸ' => '筛',
  'ɹ' => '晒',
  'ɺ' => '珊',
  'ɻ' => '苫',
  'ɼ' => '杉',
  'ɽ' => '山',
  'ɾ' => '删',
  'ɿ' => '煽',
  '�' => '衫',
  '�' => '闪',
  '��' => '陕',
  '��' => '擅',
  '��' => '赡',
  '��' => '膳',
  '��' => '善',
  '��' => '汕',
  '��' => '扇',
  '��' => '缮',
  '��' => '墒',
  '��' => '伤',
  '��' => '商',
  '��' => '赏',
  '��' => '晌',
  '��' => '上',
  '��' => '尚',
  '��' => '裳',
  '��' => '梢',
  '��' => '捎',
  '��' => '稍',
  '��' => '烧',
  '��' => '芍',
  '��' => '勺',
  '��' => '韶',
  '��' => '少',
  '��' => '哨',
  '��' => '邵',
  '��' => '绍',
  '��' => '奢',
  '��' => '赊',
  '��' => '蛇',
  '��' => '舌',
  '��' => '舍',
  '��' => '赦',
  '��' => '摄',
  '��' => '射',
  '��' => '慑',
  '��' => '涉',
  '��' => '社',
  '��' => '设',
  '��' => '砷',
  '��' => '申',
  '��' => '呻',
  '��' => '伸',
  '��' => '身',
  '��' => '深',
  '��' => '娠',
  '��' => '绅',
  '��' => '神',
  '��' => '沈',
  '��' => '审',
  '��' => '婶',
  '�' => '甚',
  '�' => '肾',
  '�' => '慎',
  '�' => '渗',
  '�' => '声',
  '�' => '生',
  '�' => '甥',
  '�' => '牲',
  '�' => '升',
  '�' => '绳',
  '�@' => '蔃',
  '�A' => '蔄',
  '�B' => '蔅',
  '�C' => '蔆',
  '�D' => '蔇',
  '�E' => '蔈',
  '�F' => '蔉',
  '�G' => '蔊',
  '�H' => '蔋',
  '�I' => '蔍',
  '�J' => '蔎',
  '�K' => '蔏',
  '�L' => '蔐',
  '�M' => '蔒',
  '�N' => '蔔',
  '�O' => '蔕',
  '�P' => '蔖',
  '�Q' => '蔘',
  '�R' => '蔙',
  '�S' => '蔛',
  '�T' => '蔜',
  '�U' => '蔝',
  '�V' => '蔞',
  '�W' => '蔠',
  '�X' => '蔢',
  '�Y' => '蔣',
  '�Z' => '蔤',
  '�[' => '蔥',
  '�\\' => '蔦',
  '�]' => '蔧',
  '�^' => '蔨',
  '�_' => '蔩',
  '�`' => '蔪',
  '�a' => '蔭',
  '�b' => '蔮',
  '�c' => '蔯',
  '�d' => '蔰',
  '�e' => '蔱',
  '�f' => '蔲',
  '�g' => '蔳',
  '�h' => '蔴',
  '�i' => '蔵',
  '�j' => '蔶',
  '�k' => '蔾',
  '�l' => '蔿',
  '�m' => '蕀',
  '�n' => '蕁',
  '�o' => '蕂',
  '�p' => '蕄',
  '�q' => '蕅',
  '�r' => '蕆',
  '�s' => '蕇',
  '�t' => '蕋',
  '�u' => '蕌',
  '�v' => '蕍',
  '�w' => '蕎',
  '�x' => '蕏',
  '�y' => '蕐',
  '�z' => '蕑',
  '�{' => '蕒',
  '�|' => '蕓',
  '�}' => '蕔',
  '�~' => '蕕',
  'ʀ' => '蕗',
  'ʁ' => '蕘',
  'ʂ' => '蕚',
  'ʃ' => '蕛',
  'ʄ' => '蕜',
  'ʅ' => '蕝',
  'ʆ' => '蕟',
  'ʇ' => '蕠',
  'ʈ' => '蕡',
  'ʉ' => '蕢',
  'ʊ' => '蕣',
  'ʋ' => '蕥',
  'ʌ' => '蕦',
  'ʍ' => '蕧',
  'ʎ' => '蕩',
  'ʏ' => '蕪',
  'ʐ' => '蕫',
  'ʑ' => '蕬',
  'ʒ' => '蕭',
  'ʓ' => '蕮',
  'ʔ' => '蕯',
  'ʕ' => '蕰',
  'ʖ' => '蕱',
  'ʗ' => '蕳',
  'ʘ' => '蕵',
  'ʙ' => '蕶',
  'ʚ' => '蕷',
  'ʛ' => '蕸',
  'ʜ' => '蕼',
  'ʝ' => '蕽',
  'ʞ' => '蕿',
  'ʟ' => '薀',
  'ʠ' => '薁',
  'ʡ' => '省',
  'ʢ' => '盛',
  'ʣ' => '剩',
  'ʤ' => '胜',
  'ʥ' => '圣',
  'ʦ' => '师',
  'ʧ' => '失',
  'ʨ' => '狮',
  'ʩ' => '施',
  'ʪ' => '湿',
  'ʫ' => '诗',
  'ʬ' => '尸',
  'ʭ' => '虱',
  'ʮ' => '十',
  'ʯ' => '石',
  'ʰ' => '拾',
  'ʱ' => '时',
  'ʲ' => '什',
  'ʳ' => '食',
  'ʴ' => '蚀',
  'ʵ' => '实',
  'ʶ' => '识',
  'ʷ' => '史',
  'ʸ' => '矢',
  'ʹ' => '使',
  'ʺ' => '屎',
  'ʻ' => '驶',
  'ʼ' => '始',
  'ʽ' => '式',
  'ʾ' => '示',
  'ʿ' => '士',
  '�' => '世',
  '�' => '柿',
  '��' => '事',
  '��' => '拭',
  '��' => '誓',
  '��' => '逝',
  '��' => '势',
  '��' => '是',
  '��' => '嗜',
  '��' => '噬',
  '��' => '适',
  '��' => '仕',
  '��' => '侍',
  '��' => '释',
  '��' => '饰',
  '��' => '氏',
  '��' => '市',
  '��' => '恃',
  '��' => '室',
  '��' => '视',
  '��' => '试',
  '��' => '收',
  '��' => '手',
  '��' => '首',
  '��' => '守',
  '��' => '寿',
  '��' => '授',
  '��' => '售',
  '��' => '受',
  '��' => '瘦',
  '��' => '兽',
  '��' => '蔬',
  '��' => '枢',
  '��' => '梳',
  '��' => '殊',
  '��' => '抒',
  '��' => '输',
  '��' => '叔',
  '��' => '舒',
  '��' => '淑',
  '��' => '疏',
  '��' => '书',
  '��' => '赎',
  '��' => '孰',
  '��' => '熟',
  '��' => '薯',
  '��' => '暑',
  '��' => '曙',
  '��' => '署',
  '��' => '蜀',
  '��' => '黍',
  '��' => '鼠',
  '��' => '属',
  '�' => '术',
  '�' => '述',
  '�' => '树',
  '�' => '束',
  '�' => '戍',
  '�' => '竖',
  '�' => '墅',
  '�' => '庶',
  '�' => '数',
  '�' => '漱',
  '�@' => '薂',
  '�A' => '薃',
  '�B' => '薆',
  '�C' => '薈',
  '�D' => '薉',
  '�E' => '薊',
  '�F' => '薋',
  '�G' => '薌',
  '�H' => '薍',
  '�I' => '薎',
  '�J' => '薐',
  '�K' => '薑',
  '�L' => '薒',
  '�M' => '薓',
  '�N' => '薔',
  '�O' => '薕',
  '�P' => '薖',
  '�Q' => '薗',
  '�R' => '薘',
  '�S' => '薙',
  '�T' => '薚',
  '�U' => '薝',
  '�V' => '薞',
  '�W' => '薟',
  '�X' => '薠',
  '�Y' => '薡',
  '�Z' => '薢',
  '�[' => '薣',
  '�\\' => '薥',
  '�]' => '薦',
  '�^' => '薧',
  '�_' => '薩',
  '�`' => '薫',
  '�a' => '薬',
  '�b' => '薭',
  '�c' => '薱',
  '�d' => '薲',
  '�e' => '薳',
  '�f' => '薴',
  '�g' => '薵',
  '�h' => '薶',
  '�i' => '薸',
  '�j' => '薺',
  '�k' => '薻',
  '�l' => '薼',
  '�m' => '薽',
  '�n' => '薾',
  '�o' => '薿',
  '�p' => '藀',
  '�q' => '藂',
  '�r' => '藃',
  '�s' => '藄',
  '�t' => '藅',
  '�u' => '藆',
  '�v' => '藇',
  '�w' => '藈',
  '�x' => '藊',
  '�y' => '藋',
  '�z' => '藌',
  '�{' => '藍',
  '�|' => '藎',
  '�}' => '藑',
  '�~' => '藒',
  'ˀ' => '藔',
  'ˁ' => '藖',
  '˂' => '藗',
  '˃' => '藘',
  '˄' => '藙',
  '˅' => '藚',
  'ˆ' => '藛',
  'ˇ' => '藝',
  'ˈ' => '藞',
  'ˉ' => '藟',
  'ˊ' => '藠',
  'ˋ' => '藡',
  'ˌ' => '藢',
  'ˍ' => '藣',
  'ˎ' => '藥',
  'ˏ' => '藦',
  'ː' => '藧',
  'ˑ' => '藨',
  '˒' => '藪',
  '˓' => '藫',
  '˔' => '藬',
  '˕' => '藭',
  '˖' => '藮',
  '˗' => '藯',
  '˘' => '藰',
  '˙' => '藱',
  '˚' => '藲',
  '˛' => '藳',
  '˜' => '藴',
  '˝' => '藵',
  '˞' => '藶',
  '˟' => '藷',
  'ˠ' => '藸',
  'ˡ' => '恕',
  'ˢ' => '刷',
  'ˣ' => '耍',
  'ˤ' => '摔',
  '˥' => '衰',
  '˦' => '甩',
  '˧' => '帅',
  '˨' => '栓',
  '˩' => '拴',
  '˪' => '霜',
  '˫' => '双',
  'ˬ' => '爽',
  '˭' => '谁',
  'ˮ' => '水',
  '˯' => '睡',
  '˰' => '税',
  '˱' => '吮',
  '˲' => '瞬',
  '˳' => '顺',
  '˴' => '舜',
  '˵' => '说',
  '˶' => '硕',
  '˷' => '朔',
  '˸' => '烁',
  '˹' => '斯',
  '˺' => '撕',
  '˻' => '嘶',
  '˼' => '思',
  '˽' => '私',
  '˾' => '司',
  '˿' => '丝',
  '�' => '死',
  '�' => '肆',
  '��' => '寺',
  '��' => '嗣',
  '��' => '四',
  '��' => '伺',
  '��' => '似',
  '��' => '饲',
  '��' => '巳',
  '��' => '松',
  '��' => '耸',
  '��' => '怂',
  '��' => '颂',
  '��' => '送',
  '��' => '宋',
  '��' => '讼',
  '��' => '诵',
  '��' => '搜',
  '��' => '艘',
  '��' => '擞',
  '��' => '嗽',
  '��' => '苏',
  '��' => '酥',
  '��' => '俗',
  '��' => '素',
  '��' => '速',
  '��' => '粟',
  '��' => '僳',
  '��' => '塑',
  '��' => '溯',
  '��' => '宿',
  '��' => '诉',
  '��' => '肃',
  '��' => '酸',
  '��' => '蒜',
  '��' => '算',
  '��' => '虽',
  '��' => '隋',
  '��' => '随',
  '��' => '绥',
  '��' => '髓',
  '��' => '碎',
  '��' => '岁',
  '��' => '穗',
  '��' => '遂',
  '��' => '隧',
  '��' => '祟',
  '��' => '孙',
  '��' => '损',
  '��' => '笋',
  '��' => '蓑',
  '��' => '梭',
  '��' => '唆',
  '�' => '缩',
  '�' => '琐',
  '�' => '索',
  '�' => '锁',
  '�' => '所',
  '�' => '塌',
  '�' => '他',
  '�' => '它',
  '�' => '她',
  '�' => '塔',
  '�@' => '藹',
  '�A' => '藺',
  '�B' => '藼',
  '�C' => '藽',
  '�D' => '藾',
  '�E' => '蘀',
  '�F' => '蘁',
  '�G' => '蘂',
  '�H' => '蘃',
  '�I' => '蘄',
  '�J' => '蘆',
  '�K' => '蘇',
  '�L' => '蘈',
  '�M' => '蘉',
  '�N' => '蘊',
  '�O' => '蘋',
  '�P' => '蘌',
  '�Q' => '蘍',
  '�R' => '蘎',
  '�S' => '蘏',
  '�T' => '蘐',
  '�U' => '蘒',
  '�V' => '蘓',
  '�W' => '蘔',
  '�X' => '蘕',
  '�Y' => '蘗',
  '�Z' => '蘘',
  '�[' => '蘙',
  '�\\' => '蘚',
  '�]' => '蘛',
  '�^' => '蘜',
  '�_' => '蘝',
  '�`' => '蘞',
  '�a' => '蘟',
  '�b' => '蘠',
  '�c' => '蘡',
  '�d' => '蘢',
  '�e' => '蘣',
  '�f' => '蘤',
  '�g' => '蘥',
  '�h' => '蘦',
  '�i' => '蘨',
  '�j' => '蘪',
  '�k' => '蘫',
  '�l' => '蘬',
  '�m' => '蘭',
  '�n' => '蘮',
  '�o' => '蘯',
  '�p' => '蘰',
  '�q' => '蘱',
  '�r' => '蘲',
  '�s' => '蘳',
  '�t' => '蘴',
  '�u' => '蘵',
  '�v' => '蘶',
  '�w' => '蘷',
  '�x' => '蘹',
  '�y' => '蘺',
  '�z' => '蘻',
  '�{' => '蘽',
  '�|' => '蘾',
  '�}' => '蘿',
  '�~' => '虀',
  '̀' => '虁',
  '́' => '虂',
  '̂' => '虃',
  '̃' => '虄',
  '̄' => '虅',
  '̅' => '虆',
  '̆' => '虇',
  '̇' => '虈',
  '̈' => '虉',
  '̉' => '虊',
  '̊' => '虋',
  '̋' => '虌',
  '̌' => '虒',
  '̍' => '虓',
  '̎' => '處',
  '̏' => '虖',
  '̐' => '虗',
  '̑' => '虘',
  '̒' => '虙',
  '̓' => '虛',
  '̔' => '虜',
  '̕' => '虝',
  '̖' => '號',
  '̗' => '虠',
  '̘' => '虡',
  '̙' => '虣',
  '̚' => '虤',
  '̛' => '虥',
  '̜' => '虦',
  '̝' => '虧',
  '̞' => '虨',
  '̟' => '虩',
  '̠' => '虪',
  '̡' => '獭',
  '̢' => '挞',
  '̣' => '蹋',
  '̤' => '踏',
  '̥' => '胎',
  '̦' => '苔',
  '̧' => '抬',
  '̨' => '台',
  '̩' => '泰',
  '̪' => '酞',
  '̫' => '太',
  '̬' => '态',
  '̭' => '汰',
  '̮' => '坍',
  '̯' => '摊',
  '̰' => '贪',
  '̱' => '瘫',
  '̲' => '滩',
  '̳' => '坛',
  '̴' => '檀',
  '̵' => '痰',
  '̶' => '潭',
  '̷' => '谭',
  '̸' => '谈',
  '̹' => '坦',
  '̺' => '毯',
  '̻' => '袒',
  '̼' => '碳',
  '̽' => '探',
  '̾' => '叹',
  '̿' => '炭',
  '�' => '汤',
  '�' => '塘',
  '��' => '搪',
  '��' => '堂',
  '��' => '棠',
  '��' => '膛',
  '��' => '唐',
  '��' => '糖',
  '��' => '倘',
  '��' => '躺',
  '��' => '淌',
  '��' => '趟',
  '��' => '烫',
  '��' => '掏',
  '��' => '涛',
  '��' => '滔',
  '��' => '绦',
  '��' => '萄',
  '��' => '桃',
  '��' => '逃',
  '��' => '淘',
  '��' => '陶',
  '��' => '讨',
  '��' => '套',
  '��' => '特',
  '��' => '藤',
  '��' => '腾',
  '��' => '疼',
  '��' => '誊',
  '��' => '梯',
  '��' => '剔',
  '��' => '踢',
  '��' => '锑',
  '��' => '提',
  '��' => '题',
  '��' => '蹄',
  '��' => '啼',
  '��' => '体',
  '��' => '替',
  '��' => '嚏',
  '��' => '惕',
  '��' => '涕',
  '��' => '剃',
  '��' => '屉',
  '��' => '天',
  '��' => '添',
  '��' => '填',
  '��' => '田',
  '��' => '甜',
  '��' => '恬',
  '��' => '舔',
  '��' => '腆',
  '��' => '挑',
  '�' => '条',
  '�' => '迢',
  '�' => '眺',
  '�' => '跳',
  '�' => '贴',
  '�' => '铁',
  '�' => '帖',
  '�' => '厅',
  '�' => '听',
  '�' => '烃',
  '�@' => '虭',
  '�A' => '虯',
  '�B' => '虰',
  '�C' => '虲',
  '�D' => '虳',
  '�E' => '虴',
  '�F' => '虵',
  '�G' => '虶',
  '�H' => '虷',
  '�I' => '虸',
  '�J' => '蚃',
  '�K' => '蚄',
  '�L' => '蚅',
  '�M' => '蚆',
  '�N' => '蚇',
  '�O' => '蚈',
  '�P' => '蚉',
  '�Q' => '蚎',
  '�R' => '蚏',
  '�S' => '蚐',
  '�T' => '蚑',
  '�U' => '蚒',
  '�V' => '蚔',
  '�W' => '蚖',
  '�X' => '蚗',
  '�Y' => '蚘',
  '�Z' => '蚙',
  '�[' => '蚚',
  '�\\' => '蚛',
  '�]' => '蚞',
  '�^' => '蚟',
  '�_' => '蚠',
  '�`' => '蚡',
  '�a' => '蚢',
  '�b' => '蚥',
  '�c' => '蚦',
  '�d' => '蚫',
  '�e' => '蚭',
  '�f' => '蚮',
  '�g' => '蚲',
  '�h' => '蚳',
  '�i' => '蚷',
  '�j' => '蚸',
  '�k' => '蚹',
  '�l' => '蚻',
  '�m' => '蚼',
  '�n' => '蚽',
  '�o' => '蚾',
  '�p' => '蚿',
  '�q' => '蛁',
  '�r' => '蛂',
  '�s' => '蛃',
  '�t' => '蛅',
  '�u' => '蛈',
  '�v' => '蛌',
  '�w' => '蛍',
  '�x' => '蛒',
  '�y' => '蛓',
  '�z' => '蛕',
  '�{' => '蛖',
  '�|' => '蛗',
  '�}' => '蛚',
  '�~' => '蛜',
  '̀' => '蛝',
  '́' => '蛠',
  '͂' => '蛡',
  '̓' => '蛢',
  '̈́' => '蛣',
  'ͅ' => '蛥',
  '͆' => '蛦',
  '͇' => '蛧',
  '͈' => '蛨',
  '͉' => '蛪',
  '͊' => '蛫',
  '͋' => '蛬',
  '͌' => '蛯',
  '͍' => '蛵',
  '͎' => '蛶',
  '͏' => '蛷',
  '͐' => '蛺',
  '͑' => '蛻',
  '͒' => '蛼',
  '͓' => '蛽',
  '͔' => '蛿',
  '͕' => '蜁',
  '͖' => '蜄',
  '͗' => '蜅',
  '͘' => '蜆',
  '͙' => '蜋',
  '͚' => '蜌',
  '͛' => '蜎',
  '͜' => '蜏',
  '͝' => '蜐',
  '͞' => '蜑',
  '͟' => '蜔',
  '͠' => '蜖',
  '͡' => '汀',
  '͢' => '廷',
  'ͣ' => '停',
  'ͤ' => '亭',
  'ͥ' => '庭',
  'ͦ' => '挺',
  'ͧ' => '艇',
  'ͨ' => '通',
  'ͩ' => '桐',
  'ͪ' => '酮',
  'ͫ' => '瞳',
  'ͬ' => '同',
  'ͭ' => '铜',
  'ͮ' => '彤',
  'ͯ' => '童',
  'Ͱ' => '桶',
  'ͱ' => '捅',
  'Ͳ' => '筒',
  'ͳ' => '统',
  'ʹ' => '痛',
  '͵' => '偷',
  'Ͷ' => '投',
  'ͷ' => '头',
  '͸' => '透',
  '͹' => '凸',
  'ͺ' => '秃',
  'ͻ' => '突',
  'ͼ' => '图',
  'ͽ' => '徒',
  ';' => '途',
  'Ϳ' => '涂',
  '�' => '屠',
  '�' => '土',
  '��' => '吐',
  '��' => '兔',
  '��' => '湍',
  '��' => '团',
  '��' => '推',
  '��' => '颓',
  '��' => '腿',
  '��' => '蜕',
  '��' => '褪',
  '��' => '退',
  '��' => '吞',
  '��' => '屯',
  '��' => '臀',
  '��' => '拖',
  '��' => '托',
  '��' => '脱',
  '��' => '鸵',
  '��' => '陀',
  '��' => '驮',
  '��' => '驼',
  '��' => '椭',
  '��' => '妥',
  '��' => '拓',
  '��' => '唾',
  '��' => '挖',
  '��' => '哇',
  '��' => '蛙',
  '��' => '洼',
  '��' => '娃',
  '��' => '瓦',
  '��' => '袜',
  '��' => '歪',
  '��' => '外',
  '��' => '豌',
  '��' => '弯',
  '��' => '湾',
  '��' => '玩',
  '��' => '顽',
  '��' => '丸',
  '��' => '烷',
  '��' => '完',
  '��' => '碗',
  '��' => '挽',
  '��' => '晚',
  '��' => '皖',
  '��' => '惋',
  '��' => '宛',
  '��' => '婉',
  '��' => '万',
  '��' => '腕',
  '��' => '汪',
  '�' => '王',
  '�' => '亡',
  '�' => '枉',
  '�' => '网',
  '�' => '往',
  '�' => '旺',
  '�' => '望',
  '�' => '忘',
  '�' => '妄',
  '�' => '威',
  '�@' => '蜙',
  '�A' => '蜛',
  '�B' => '蜝',
  '�C' => '蜟',
  '�D' => '蜠',
  '�E' => '蜤',
  '�F' => '蜦',
  '�G' => '蜧',
  '�H' => '蜨',
  '�I' => '蜪',
  '�J' => '蜫',
  '�K' => '蜬',
  '�L' => '蜭',
  '�M' => '蜯',
  '�N' => '蜰',
  '�O' => '蜲',
  '�P' => '蜳',
  '�Q' => '蜵',
  '�R' => '蜶',
  '�S' => '蜸',
  '�T' => '蜹',
  '�U' => '蜺',
  '�V' => '蜼',
  '�W' => '蜽',
  '�X' => '蝀',
  '�Y' => '蝁',
  '�Z' => '蝂',
  '�[' => '蝃',
  '�\\' => '蝄',
  '�]' => '蝅',
  '�^' => '蝆',
  '�_' => '蝊',
  '�`' => '蝋',
  '�a' => '蝍',
  '�b' => '蝏',
  '�c' => '蝐',
  '�d' => '蝑',
  '�e' => '蝒',
  '�f' => '蝔',
  '�g' => '蝕',
  '�h' => '蝖',
  '�i' => '蝘',
  '�j' => '蝚',
  '�k' => '蝛',
  '�l' => '蝜',
  '�m' => '蝝',
  '�n' => '蝞',
  '�o' => '蝟',
  '�p' => '蝡',
  '�q' => '蝢',
  '�r' => '蝦',
  '�s' => '蝧',
  '�t' => '蝨',
  '�u' => '蝩',
  '�v' => '蝪',
  '�w' => '蝫',
  '�x' => '蝬',
  '�y' => '蝭',
  '�z' => '蝯',
  '�{' => '蝱',
  '�|' => '蝲',
  '�}' => '蝳',
  '�~' => '蝵',
  '΀' => '蝷',
  '΁' => '蝸',
  '΂' => '蝹',
  '΃' => '蝺',
  '΄' => '蝿',
  '΅' => '螀',
  'Ά' => '螁',
  '·' => '螄',
  'Έ' => '螆',
  'Ή' => '螇',
  'Ί' => '螉',
  '΋' => '螊',
  'Ό' => '螌',
  '΍' => '螎',
  'Ύ' => '螏',
  'Ώ' => '螐',
  'ΐ' => '螑',
  'Α' => '螒',
  'Β' => '螔',
  'Γ' => '螕',
  'Δ' => '螖',
  'Ε' => '螘',
  'Ζ' => '螙',
  'Η' => '螚',
  'Θ' => '螛',
  'Ι' => '螜',
  'Κ' => '螝',
  'Λ' => '螞',
  'Μ' => '螠',
  'Ν' => '螡',
  'Ξ' => '螢',
  'Ο' => '螣',
  'Π' => '螤',
  'Ρ' => '巍',
  '΢' => '微',
  'Σ' => '危',
  'Τ' => '韦',
  'Υ' => '违',
  'Φ' => '桅',
  'Χ' => '围',
  'Ψ' => '唯',
  'Ω' => '惟',
  'Ϊ' => '为',
  'Ϋ' => '潍',
  'ά' => '维',
  'έ' => '苇',
  'ή' => '萎',
  'ί' => '委',
  'ΰ' => '伟',
  'α' => '伪',
  'β' => '尾',
  'γ' => '纬',
  'δ' => '未',
  'ε' => '蔚',
  'ζ' => '味',
  'η' => '畏',
  'θ' => '胃',
  'ι' => '喂',
  'κ' => '魏',
  'λ' => '位',
  'μ' => '渭',
  'ν' => '谓',
  'ξ' => '尉',
  'ο' => '慰',
  '�' => '卫',
  '�' => '瘟',
  '��' => '温',
  '��' => '蚊',
  '��' => '文',
  '��' => '闻',
  '��' => '纹',
  '��' => '吻',
  '��' => '稳',
  '��' => '紊',
  '��' => '问',
  '��' => '嗡',
  '��' => '翁',
  '��' => '瓮',
  '��' => '挝',
  '��' => '蜗',
  '��' => '涡',
  '��' => '窝',
  '��' => '我',
  '��' => '斡',
  '��' => '卧',
  '��' => '握',
  '��' => '沃',
  '��' => '巫',
  '��' => '呜',
  '��' => '钨',
  '��' => '乌',
  '��' => '污',
  '��' => '诬',
  '��' => '屋',
  '��' => '无',
  '��' => '芜',
  '��' => '梧',
  '��' => '吾',
  '��' => '吴',
  '��' => '毋',
  '��' => '武',
  '��' => '五',
  '��' => '捂',
  '��' => '午',
  '��' => '舞',
  '��' => '伍',
  '��' => '侮',
  '��' => '坞',
  '��' => '戊',
  '��' => '雾',
  '��' => '晤',
  '��' => '物',
  '��' => '勿',
  '��' => '务',
  '��' => '悟',
  '��' => '误',
  '��' => '昔',
  '�' => '熙',
  '�' => '析',
  '�' => '西',
  '�' => '硒',
  '�' => '矽',
  '�' => '晰',
  '�' => '嘻',
  '�' => '吸',
  '�' => '锡',
  '�' => '牺',
  '�@' => '螥',
  '�A' => '螦',
  '�B' => '螧',
  '�C' => '螩',
  '�D' => '螪',
  '�E' => '螮',
  '�F' => '螰',
  '�G' => '螱',
  '�H' => '螲',
  '�I' => '螴',
  '�J' => '螶',
  '�K' => '螷',
  '�L' => '螸',
  '�M' => '螹',
  '�N' => '螻',
  '�O' => '螼',
  '�P' => '螾',
  '�Q' => '螿',
  '�R' => '蟁',
  '�S' => '蟂',
  '�T' => '蟃',
  '�U' => '蟄',
  '�V' => '蟅',
  '�W' => '蟇',
  '�X' => '蟈',
  '�Y' => '蟉',
  '�Z' => '蟌',
  '�[' => '蟍',
  '�\\' => '蟎',
  '�]' => '蟏',
  '�^' => '蟐',
  '�_' => '蟔',
  '�`' => '蟕',
  '�a' => '蟖',
  '�b' => '蟗',
  '�c' => '蟘',
  '�d' => '蟙',
  '�e' => '蟚',
  '�f' => '蟜',
  '�g' => '蟝',
  '�h' => '蟞',
  '�i' => '蟟',
  '�j' => '蟡',
  '�k' => '蟢',
  '�l' => '蟣',
  '�m' => '蟤',
  '�n' => '蟦',
  '�o' => '蟧',
  '�p' => '蟨',
  '�q' => '蟩',
  '�r' => '蟫',
  '�s' => '蟬',
  '�t' => '蟭',
  '�u' => '蟯',
  '�v' => '蟰',
  '�w' => '蟱',
  '�x' => '蟲',
  '�y' => '蟳',
  '�z' => '蟴',
  '�{' => '蟵',
  '�|' => '蟶',
  '�}' => '蟷',
  '�~' => '蟸',
  'π' => '蟺',
  'ρ' => '蟻',
  'ς' => '蟼',
  'σ' => '蟽',
  'τ' => '蟿',
  'υ' => '蠀',
  'φ' => '蠁',
  'χ' => '蠂',
  'ψ' => '蠄',
  'ω' => '蠅',
  'ϊ' => '蠆',
  'ϋ' => '蠇',
  'ό' => '蠈',
  'ύ' => '蠉',
  'ώ' => '蠋',
  'Ϗ' => '蠌',
  'ϐ' => '蠍',
  'ϑ' => '蠎',
  'ϒ' => '蠏',
  'ϓ' => '蠐',
  'ϔ' => '蠑',
  'ϕ' => '蠒',
  'ϖ' => '蠔',
  'ϗ' => '蠗',
  'Ϙ' => '蠘',
  'ϙ' => '蠙',
  'Ϛ' => '蠚',
  'ϛ' => '蠜',
  'Ϝ' => '蠝',
  'ϝ' => '蠞',
  'Ϟ' => '蠟',
  'ϟ' => '蠠',
  'Ϡ' => '蠣',
  'ϡ' => '稀',
  'Ϣ' => '息',
  'ϣ' => '希',
  'Ϥ' => '悉',
  'ϥ' => '膝',
  'Ϧ' => '夕',
  'ϧ' => '惜',
  'Ϩ' => '熄',
  'ϩ' => '烯',
  'Ϫ' => '溪',
  'ϫ' => '汐',
  'Ϭ' => '犀',
  'ϭ' => '檄',
  'Ϯ' => '袭',
  'ϯ' => '席',
  'ϰ' => '习',
  'ϱ' => '媳',
  'ϲ' => '喜',
  'ϳ' => '铣',
  'ϴ' => '洗',
  'ϵ' => '系',
  '϶' => '隙',
  'Ϸ' => '戏',
  'ϸ' => '细',
  'Ϲ' => '瞎',
  'Ϻ' => '虾',
  'ϻ' => '匣',
  'ϼ' => '霞',
  'Ͻ' => '辖',
  'Ͼ' => '暇',
  'Ͽ' => '峡',
  '�' => '侠',
  '�' => '狭',
  '��' => '下',
  '��' => '厦',
  '��' => '夏',
  '��' => '吓',
  '��' => '掀',
  '��' => '锨',
  '��' => '先',
  '��' => '仙',
  '��' => '鲜',
  '��' => '纤',
  '��' => '咸',
  '��' => '贤',
  '��' => '衔',
  '��' => '舷',
  '��' => '闲',
  '��' => '涎',
  '��' => '弦',
  '��' => '嫌',
  '��' => '显',
  '��' => '险',
  '��' => '现',
  '��' => '献',
  '��' => '县',
  '��' => '腺',
  '��' => '馅',
  '��' => '羡',
  '��' => '宪',
  '��' => '陷',
  '��' => '限',
  '��' => '线',
  '��' => '相',
  '��' => '厢',
  '��' => '镶',
  '��' => '香',
  '��' => '箱',
  '��' => '襄',
  '��' => '湘',
  '��' => '乡',
  '��' => '翔',
  '��' => '祥',
  '��' => '详',
  '��' => '想',
  '��' => '响',
  '��' => '享',
  '��' => '项',
  '��' => '巷',
  '��' => '橡',
  '��' => '像',
  '��' => '向',
  '��' => '象',
  '��' => '萧',
  '�' => '硝',
  '�' => '霄',
  '�' => '削',
  '�' => '哮',
  '�' => '嚣',
  '�' => '销',
  '�' => '消',
  '�' => '宵',
  '�' => '淆',
  '�' => '晓',
  '�@' => '蠤',
  '�A' => '蠥',
  '�B' => '蠦',
  '�C' => '蠧',
  '�D' => '蠨',
  '�E' => '蠩',
  '�F' => '蠪',
  '�G' => '蠫',
  '�H' => '蠬',
  '�I' => '蠭',
  '�J' => '蠮',
  '�K' => '蠯',
  '�L' => '蠰',
  '�M' => '蠱',
  '�N' => '蠳',
  '�O' => '蠴',
  '�P' => '蠵',
  '�Q' => '蠶',
  '�R' => '蠷',
  '�S' => '蠸',
  '�T' => '蠺',
  '�U' => '蠻',
  '�V' => '蠽',
  '�W' => '蠾',
  '�X' => '蠿',
  '�Y' => '衁',
  '�Z' => '衂',
  '�[' => '衃',
  '�\\' => '衆',
  '�]' => '衇',
  '�^' => '衈',
  '�_' => '衉',
  '�`' => '衊',
  '�a' => '衋',
  '�b' => '衎',
  '�c' => '衏',
  '�d' => '衐',
  '�e' => '衑',
  '�f' => '衒',
  '�g' => '術',
  '�h' => '衕',
  '�i' => '衖',
  '�j' => '衘',
  '�k' => '衚',
  '�l' => '衛',
  '�m' => '衜',
  '�n' => '衝',
  '�o' => '衞',
  '�p' => '衟',
  '�q' => '衠',
  '�r' => '衦',
  '�s' => '衧',
  '�t' => '衪',
  '�u' => '衭',
  '�v' => '衯',
  '�w' => '衱',
  '�x' => '衳',
  '�y' => '衴',
  '�z' => '衵',
  '�{' => '衶',
  '�|' => '衸',
  '�}' => '衹',
  '�~' => '衺',
  'Ѐ' => '衻',
  'Ё' => '衼',
  'Ђ' => '袀',
  'Ѓ' => '袃',
  'Є' => '袆',
  'Ѕ' => '袇',
  'І' => '袉',
  'Ї' => '袊',
  'Ј' => '袌',
  'Љ' => '袎',
  'Њ' => '袏',
  'Ћ' => '袐',
  'Ќ' => '袑',
  'Ѝ' => '袓',
  'Ў' => '袔',
  'Џ' => '袕',
  'А' => '袗',
  'Б' => '袘',
  'В' => '袙',
  'Г' => '袚',
  'Д' => '袛',
  'Е' => '袝',
  'Ж' => '袞',
  'З' => '袟',
  'И' => '袠',
  'Й' => '袡',
  'К' => '袣',
  'Л' => '袥',
  'М' => '袦',
  'Н' => '袧',
  'О' => '袨',
  'П' => '袩',
  'Р' => '袪',
  'С' => '小',
  'Т' => '孝',
  'У' => '校',
  'Ф' => '肖',
  'Х' => '啸',
  'Ц' => '笑',
  'Ч' => '效',
  'Ш' => '楔',
  'Щ' => '些',
  'Ъ' => '歇',
  'Ы' => '蝎',
  'Ь' => '鞋',
  'Э' => '协',
  'Ю' => '挟',
  'Я' => '携',
  'а' => '邪',
  'б' => '斜',
  'в' => '胁',
  'г' => '谐',
  'д' => '写',
  'е' => '械',
  'ж' => '卸',
  'з' => '蟹',
  'и' => '懈',
  'й' => '泄',
  'к' => '泻',
  'л' => '谢',
  'м' => '屑',
  'н' => '薪',
  'о' => '芯',
  'п' => '锌',
  '�' => '欣',
  '�' => '辛',
  '��' => '新',
  '��' => '忻',
  '��' => '心',
  '��' => '信',
  '��' => '衅',
  '��' => '星',
  '��' => '腥',
  '��' => '猩',
  '��' => '惺',
  '��' => '兴',
  '��' => '刑',
  '��' => '型',
  '��' => '形',
  '��' => '邢',
  '��' => '行',
  '��' => '醒',
  '��' => '幸',
  '��' => '杏',
  '��' => '性',
  '��' => '姓',
  '��' => '兄',
  '��' => '凶',
  '��' => '胸',
  '��' => '匈',
  '��' => '汹',
  '��' => '雄',
  '��' => '熊',
  '��' => '休',
  '��' => '修',
  '��' => '羞',
  '��' => '朽',
  '��' => '嗅',
  '��' => '锈',
  '��' => '秀',
  '��' => '袖',
  '��' => '绣',
  '��' => '墟',
  '��' => '戌',
  '��' => '需',
  '��' => '虚',
  '��' => '嘘',
  '��' => '须',
  '��' => '徐',
  '��' => '许',
  '��' => '蓄',
  '��' => '酗',
  '��' => '叙',
  '��' => '旭',
  '��' => '序',
  '��' => '畜',
  '��' => '恤',
  '�' => '絮',
  '�' => '婿',
  '�' => '绪',
  '�' => '续',
  '�' => '轩',
  '�' => '喧',
  '�' => '宣',
  '�' => '悬',
  '�' => '旋',
  '�' => '玄',
  '�@' => '袬',
  '�A' => '袮',
  '�B' => '袯',
  '�C' => '袰',
  '�D' => '袲',
  '�E' => '袳',
  '�F' => '袴',
  '�G' => '袵',
  '�H' => '袶',
  '�I' => '袸',
  '�J' => '袹',
  '�K' => '袺',
  '�L' => '袻',
  '�M' => '袽',
  '�N' => '袾',
  '�O' => '袿',
  '�P' => '裀',
  '�Q' => '裃',
  '�R' => '裄',
  '�S' => '裇',
  '�T' => '裈',
  '�U' => '裊',
  '�V' => '裋',
  '�W' => '裌',
  '�X' => '裍',
  '�Y' => '裏',
  '�Z' => '裐',
  '�[' => '裑',
  '�\\' => '裓',
  '�]' => '裖',
  '�^' => '裗',
  '�_' => '裚',
  '�`' => '裛',
  '�a' => '補',
  '�b' => '裝',
  '�c' => '裞',
  '�d' => '裠',
  '�e' => '裡',
  '�f' => '裦',
  '�g' => '裧',
  '�h' => '裩',
  '�i' => '裪',
  '�j' => '裫',
  '�k' => '裬',
  '�l' => '裭',
  '�m' => '裮',
  '�n' => '裯',
  '�o' => '裲',
  '�p' => '裵',
  '�q' => '裶',
  '�r' => '裷',
  '�s' => '裺',
  '�t' => '裻',
  '�u' => '製',
  '�v' => '裿',
  '�w' => '褀',
  '�x' => '褁',
  '�y' => '褃',
  '�z' => '褄',
  '�{' => '褅',
  '�|' => '褆',
  '�}' => '複',
  '�~' => '褈',
  'р' => '褉',
  'с' => '褋',
  'т' => '褌',
  'у' => '褍',
  'ф' => '褎',
  'х' => '褏',
  'ц' => '褑',
  'ч' => '褔',
  'ш' => '褕',
  'щ' => '褖',
  'ъ' => '褗',
  'ы' => '褘',
  'ь' => '褜',
  'э' => '褝',
  'ю' => '褞',
  'я' => '褟',
  'ѐ' => '褠',
  'ё' => '褢',
  'ђ' => '褣',
  'ѓ' => '褤',
  'є' => '褦',
  'ѕ' => '褧',
  'і' => '褨',
  'ї' => '褩',
  'ј' => '褬',
  'љ' => '褭',
  'њ' => '褮',
  'ћ' => '褯',
  'ќ' => '褱',
  'ѝ' => '褲',
  'ў' => '褳',
  'џ' => '褵',
  'Ѡ' => '褷',
  'ѡ' => '选',
  'Ѣ' => '癣',
  'ѣ' => '眩',
  'Ѥ' => '绚',
  'ѥ' => '靴',
  'Ѧ' => '薛',
  'ѧ' => '学',
  'Ѩ' => '穴',
  'ѩ' => '雪',
  'Ѫ' => '血',
  'ѫ' => '勋',
  'Ѭ' => '熏',
  'ѭ' => '循',
  'Ѯ' => '旬',
  'ѯ' => '询',
  'Ѱ' => '寻',
  'ѱ' => '驯',
  'Ѳ' => '巡',
  'ѳ' => '殉',
  'Ѵ' => '汛',
  'ѵ' => '训',
  'Ѷ' => '讯',
  'ѷ' => '逊',
  'Ѹ' => '迅',
  'ѹ' => '压',
  'Ѻ' => '押',
  'ѻ' => '鸦',
  'Ѽ' => '鸭',
  'ѽ' => '呀',
  'Ѿ' => '丫',
  'ѿ' => '芽',
  '�' => '牙',
  '�' => '蚜',
  '��' => '崖',
  '��' => '衙',
  '��' => '涯',
  '��' => '雅',
  '��' => '哑',
  '��' => '亚',
  '��' => '讶',
  '��' => '焉',
  '��' => '咽',
  '��' => '阉',
  '��' => '烟',
  '��' => '淹',
  '��' => '盐',
  '��' => '严',
  '��' => '研',
  '��' => '蜒',
  '��' => '岩',
  '��' => '延',
  '��' => '言',
  '��' => '颜',
  '��' => '阎',
  '��' => '炎',
  '��' => '沿',
  '��' => '奄',
  '��' => '掩',
  '��' => '眼',
  '��' => '衍',
  '��' => '演',
  '��' => '艳',
  '��' => '堰',
  '��' => '燕',
  '��' => '厌',
  '��' => '砚',
  '��' => '雁',
  '��' => '唁',
  '��' => '彦',
  '��' => '焰',
  '��' => '宴',
  '��' => '谚',
  '��' => '验',
  '��' => '殃',
  '��' => '央',
  '��' => '鸯',
  '��' => '秧',
  '��' => '杨',
  '��' => '扬',
  '��' => '佯',
  '��' => '疡',
  '��' => '羊',
  '��' => '洋',
  '��' => '阳',
  '�' => '氧',
  '�' => '仰',
  '�' => '痒',
  '�' => '养',
  '�' => '样',
  '�' => '漾',
  '�' => '邀',
  '�' => '腰',
  '�' => '妖',
  '�' => '瑶',
  '�@' => '褸',
  '�A' => '褹',
  '�B' => '褺',
  '�C' => '褻',
  '�D' => '褼',
  '�E' => '褽',
  '�F' => '褾',
  '�G' => '褿',
  '�H' => '襀',
  '�I' => '襂',
  '�J' => '襃',
  '�K' => '襅',
  '�L' => '襆',
  '�M' => '襇',
  '�N' => '襈',
  '�O' => '襉',
  '�P' => '襊',
  '�Q' => '襋',
  '�R' => '襌',
  '�S' => '襍',
  '�T' => '襎',
  '�U' => '襏',
  '�V' => '襐',
  '�W' => '襑',
  '�X' => '襒',
  '�Y' => '襓',
  '�Z' => '襔',
  '�[' => '襕',
  '�\\' => '襖',
  '�]' => '襗',
  '�^' => '襘',
  '�_' => '襙',
  '�`' => '襚',
  '�a' => '襛',
  '�b' => '襜',
  '�c' => '襝',
  '�d' => '襠',
  '�e' => '襡',
  '�f' => '襢',
  '�g' => '襣',
  '�h' => '襤',
  '�i' => '襥',
  '�j' => '襧',
  '�k' => '襨',
  '�l' => '襩',
  '�m' => '襪',
  '�n' => '襫',
  '�o' => '襬',
  '�p' => '襭',
  '�q' => '襮',
  '�r' => '襯',
  '�s' => '襰',
  '�t' => '襱',
  '�u' => '襲',
  '�v' => '襳',
  '�w' => '襴',
  '�x' => '襵',
  '�y' => '襶',
  '�z' => '襷',
  '�{' => '襸',
  '�|' => '襹',
  '�}' => '襺',
  '�~' => '襼',
  'Ҁ' => '襽',
  'ҁ' => '襾',
  '҂' => '覀',
  '҃' => '覂',
  '҄' => '覄',
  '҅' => '覅',
  '҆' => '覇',
  '҇' => '覈',
  '҈' => '覉',
  '҉' => '覊',
  'Ҋ' => '見',
  'ҋ' => '覌',
  'Ҍ' => '覍',
  'ҍ' => '覎',
  'Ҏ' => '規',
  'ҏ' => '覐',
  'Ґ' => '覑',
  'ґ' => '覒',
  'Ғ' => '覓',
  'ғ' => '覔',
  'Ҕ' => '覕',
  'ҕ' => '視',
  'Җ' => '覗',
  'җ' => '覘',
  'Ҙ' => '覙',
  'ҙ' => '覚',
  'Қ' => '覛',
  'қ' => '覜',
  'Ҝ' => '覝',
  'ҝ' => '覞',
  'Ҟ' => '覟',
  'ҟ' => '覠',
  'Ҡ' => '覡',
  'ҡ' => '摇',
  'Ң' => '尧',
  'ң' => '遥',
  'Ҥ' => '窑',
  'ҥ' => '谣',
  'Ҧ' => '姚',
  'ҧ' => '咬',
  'Ҩ' => '舀',
  'ҩ' => '药',
  'Ҫ' => '要',
  'ҫ' => '耀',
  'Ҭ' => '椰',
  'ҭ' => '噎',
  'Ү' => '耶',
  'ү' => '爷',
  'Ұ' => '野',
  'ұ' => '冶',
  'Ҳ' => '也',
  'ҳ' => '页',
  'Ҵ' => '掖',
  'ҵ' => '业',
  'Ҷ' => '叶',
  'ҷ' => '曳',
  'Ҹ' => '腋',
  'ҹ' => '夜',
  'Һ' => '液',
  'һ' => '一',
  'Ҽ' => '壹',
  'ҽ' => '医',
  'Ҿ' => '揖',
  'ҿ' => '铱',
  '�' => '依',
  '�' => '伊',
  '��' => '衣',
  '��' => '颐',
  '��' => '夷',
  '��' => '遗',
  '��' => '移',
  '��' => '仪',
  '��' => '胰',
  '��' => '疑',
  '��' => '沂',
  '��' => '宜',
  '��' => '姨',
  '��' => '彝',
  '��' => '椅',
  '��' => '蚁',
  '��' => '倚',
  '��' => '已',
  '��' => '乙',
  '��' => '矣',
  '��' => '以',
  '��' => '艺',
  '��' => '抑',
  '��' => '易',
  '��' => '邑',
  '��' => '屹',
  '��' => '亿',
  '��' => '役',
  '��' => '臆',
  '��' => '逸',
  '��' => '肄',
  '��' => '疫',
  '��' => '亦',
  '��' => '裔',
  '��' => '意',
  '��' => '毅',
  '��' => '忆',
  '��' => '义',
  '��' => '益',
  '��' => '溢',
  '��' => '诣',
  '��' => '议',
  '��' => '谊',
  '��' => '译',
  '��' => '异',
  '��' => '翼',
  '��' => '翌',
  '��' => '绎',
  '��' => '茵',
  '��' => '荫',
  '��' => '因',
  '��' => '殷',
  '��' => '音',
  '�' => '阴',
  '�' => '姻',
  '�' => '吟',
  '�' => '银',
  '�' => '淫',
  '�' => '寅',
  '�' => '饮',
  '�' => '尹',
  '�' => '引',
  '�' => '隐',
  '�@' => '覢',
  '�A' => '覣',
  '�B' => '覤',
  '�C' => '覥',
  '�D' => '覦',
  '�E' => '覧',
  '�F' => '覨',
  '�G' => '覩',
  '�H' => '親',
  '�I' => '覫',
  '�J' => '覬',
  '�K' => '覭',
  '�L' => '覮',
  '�M' => '覯',
  '�N' => '覰',
  '�O' => '覱',
  '�P' => '覲',
  '�Q' => '観',
  '�R' => '覴',
  '�S' => '覵',
  '�T' => '覶',
  '�U' => '覷',
  '�V' => '覸',
  '�W' => '覹',
  '�X' => '覺',
  '�Y' => '覻',
  '�Z' => '覼',
  '�[' => '覽',
  '�\\' => '覾',
  '�]' => '覿',
  '�^' => '觀',
  '�_' => '觃',
  '�`' => '觍',
  '�a' => '觓',
  '�b' => '觔',
  '�c' => '觕',
  '�d' => '觗',
  '�e' => '觘',
  '�f' => '觙',
  '�g' => '觛',
  '�h' => '觝',
  '�i' => '觟',
  '�j' => '觠',
  '�k' => '觡',
  '�l' => '觢',
  '�m' => '觤',
  '�n' => '觧',
  '�o' => '觨',
  '�p' => '觩',
  '�q' => '觪',
  '�r' => '觬',
  '�s' => '觭',
  '�t' => '觮',
  '�u' => '觰',
  '�v' => '觱',
  '�w' => '觲',
  '�x' => '觴',
  '�y' => '觵',
  '�z' => '觶',
  '�{' => '觷',
  '�|' => '觸',
  '�}' => '觹',
  '�~' => '觺',
  'Ӏ' => '觻',
  'Ӂ' => '觼',
  'ӂ' => '觽',
  'Ӄ' => '觾',
  'ӄ' => '觿',
  'Ӆ' => '訁',
  'ӆ' => '訂',
  'Ӈ' => '訃',
  'ӈ' => '訄',
  'Ӊ' => '訅',
  'ӊ' => '訆',
  'Ӌ' => '計',
  'ӌ' => '訉',
  'Ӎ' => '訊',
  'ӎ' => '訋',
  'ӏ' => '訌',
  'Ӑ' => '訍',
  'ӑ' => '討',
  'Ӓ' => '訏',
  'ӓ' => '訐',
  'Ӕ' => '訑',
  'ӕ' => '訒',
  'Ӗ' => '訓',
  'ӗ' => '訔',
  'Ә' => '訕',
  'ә' => '訖',
  'Ӛ' => '託',
  'ӛ' => '記',
  'Ӝ' => '訙',
  'ӝ' => '訚',
  'Ӟ' => '訛',
  'ӟ' => '訜',
  'Ӡ' => '訝',
  'ӡ' => '印',
  'Ӣ' => '英',
  'ӣ' => '樱',
  'Ӥ' => '婴',
  'ӥ' => '鹰',
  'Ӧ' => '应',
  'ӧ' => '缨',
  'Ө' => '莹',
  'ө' => '萤',
  'Ӫ' => '营',
  'ӫ' => '荧',
  'Ӭ' => '蝇',
  'ӭ' => '迎',
  'Ӯ' => '赢',
  'ӯ' => '盈',
  'Ӱ' => '影',
  'ӱ' => '颖',
  'Ӳ' => '硬',
  'ӳ' => '映',
  'Ӵ' => '哟',
  'ӵ' => '拥',
  'Ӷ' => '佣',
  'ӷ' => '臃',
  'Ӹ' => '痈',
  'ӹ' => '庸',
  'Ӻ' => '雍',
  'ӻ' => '踊',
  'Ӽ' => '蛹',
  'ӽ' => '咏',
  'Ӿ' => '泳',
  'ӿ' => '涌',
  '�' => '永',
  '�' => '恿',
  '��' => '勇',
  '��' => '用',
  '��' => '幽',
  '��' => '优',
  '��' => '悠',
  '��' => '忧',
  '��' => '尤',
  '��' => '由',
  '��' => '邮',
  '��' => '铀',
  '��' => '犹',
  '��' => '油',
  '��' => '游',
  '��' => '酉',
  '��' => '有',
  '��' => '友',
  '��' => '右',
  '��' => '佑',
  '��' => '釉',
  '��' => '诱',
  '��' => '又',
  '��' => '幼',
  '��' => '迂',
  '��' => '淤',
  '��' => '于',
  '��' => '盂',
  '��' => '榆',
  '��' => '虞',
  '��' => '愚',
  '��' => '舆',
  '��' => '余',
  '��' => '俞',
  '��' => '逾',
  '��' => '鱼',
  '��' => '愉',
  '��' => '渝',
  '��' => '渔',
  '��' => '隅',
  '��' => '予',
  '��' => '娱',
  '��' => '雨',
  '��' => '与',
  '��' => '屿',
  '��' => '禹',
  '��' => '宇',
  '��' => '语',
  '��' => '羽',
  '��' => '玉',
  '��' => '域',
  '��' => '芋',
  '��' => '郁',
  '�' => '吁',
  '�' => '遇',
  '�' => '喻',
  '�' => '峪',
  '�' => '御',
  '�' => '愈',
  '�' => '欲',
  '�' => '狱',
  '�' => '育',
  '�' => '誉',
  '�@' => '訞',
  '�A' => '訟',
  '�B' => '訠',
  '�C' => '訡',
  '�D' => '訢',
  '�E' => '訣',
  '�F' => '訤',
  '�G' => '訥',
  '�H' => '訦',
  '�I' => '訧',
  '�J' => '訨',
  '�K' => '訩',
  '�L' => '訪',
  '�M' => '訫',
  '�N' => '訬',
  '�O' => '設',
  '�P' => '訮',
  '�Q' => '訯',
  '�R' => '訰',
  '�S' => '許',
  '�T' => '訲',
  '�U' => '訳',
  '�V' => '訴',
  '�W' => '訵',
  '�X' => '訶',
  '�Y' => '訷',
  '�Z' => '訸',
  '�[' => '訹',
  '�\\' => '診',
  '�]' => '註',
  '�^' => '証',
  '�_' => '訽',
  '�`' => '訿',
  '�a' => '詀',
  '�b' => '詁',
  '�c' => '詂',
  '�d' => '詃',
  '�e' => '詄',
  '�f' => '詅',
  '�g' => '詆',
  '�h' => '詇',
  '�i' => '詉',
  '�j' => '詊',
  '�k' => '詋',
  '�l' => '詌',
  '�m' => '詍',
  '�n' => '詎',
  '�o' => '詏',
  '�p' => '詐',
  '�q' => '詑',
  '�r' => '詒',
  '�s' => '詓',
  '�t' => '詔',
  '�u' => '評',
  '�v' => '詖',
  '�w' => '詗',
  '�x' => '詘',
  '�y' => '詙',
  '�z' => '詚',
  '�{' => '詛',
  '�|' => '詜',
  '�}' => '詝',
  '�~' => '詞',
  'Ԁ' => '詟',
  'ԁ' => '詠',
  'Ԃ' => '詡',
  'ԃ' => '詢',
  'Ԅ' => '詣',
  'ԅ' => '詤',
  'Ԇ' => '詥',
  'ԇ' => '試',
  'Ԉ' => '詧',
  'ԉ' => '詨',
  'Ԋ' => '詩',
  'ԋ' => '詪',
  'Ԍ' => '詫',
  'ԍ' => '詬',
  'Ԏ' => '詭',
  'ԏ' => '詮',
  'Ԑ' => '詯',
  'ԑ' => '詰',
  'Ԓ' => '話',
  'ԓ' => '該',
  'Ԕ' => '詳',
  'ԕ' => '詴',
  'Ԗ' => '詵',
  'ԗ' => '詶',
  'Ԙ' => '詷',
  'ԙ' => '詸',
  'Ԛ' => '詺',
  'ԛ' => '詻',
  'Ԝ' => '詼',
  'ԝ' => '詽',
  'Ԟ' => '詾',
  'ԟ' => '詿',
  'Ԡ' => '誀',
  'ԡ' => '浴',
  'Ԣ' => '寓',
  'ԣ' => '裕',
  'Ԥ' => '预',
  'ԥ' => '豫',
  'Ԧ' => '驭',
  'ԧ' => '鸳',
  'Ԩ' => '渊',
  'ԩ' => '冤',
  'Ԫ' => '元',
  'ԫ' => '垣',
  'Ԭ' => '袁',
  'ԭ' => '原',
  'Ԯ' => '援',
  'ԯ' => '辕',
  '԰' => '园',
  'Ա' => '员',
  'Բ' => '圆',
  'Գ' => '猿',
  'Դ' => '源',
  'Ե' => '缘',
  'Զ' => '远',
  'Է' => '苑',
  'Ը' => '愿',
  'Թ' => '怨',
  'Ժ' => '院',
  'Ի' => '曰',
  'Լ' => '约',
  'Խ' => '越',
  'Ծ' => '跃',
  'Կ' => '钥',
  '�' => '岳',
  '�' => '粤',
  '��' => '月',
  '��' => '悦',
  '��' => '阅',
  '��' => '耘',
  '��' => '云',
  '��' => '郧',
  '��' => '匀',
  '��' => '陨',
  '��' => '允',
  '��' => '运',
  '��' => '蕴',
  '��' => '酝',
  '��' => '晕',
  '��' => '韵',
  '��' => '孕',
  '��' => '匝',
  '��' => '砸',
  '��' => '杂',
  '��' => '栽',
  '��' => '哉',
  '��' => '灾',
  '��' => '宰',
  '��' => '载',
  '��' => '再',
  '��' => '在',
  '��' => '咱',
  '��' => '攒',
  '��' => '暂',
  '��' => '赞',
  '��' => '赃',
  '��' => '脏',
  '��' => '葬',
  '��' => '遭',
  '��' => '糟',
  '��' => '凿',
  '��' => '藻',
  '��' => '枣',
  '��' => '早',
  '��' => '澡',
  '��' => '蚤',
  '��' => '躁',
  '��' => '噪',
  '��' => '造',
  '��' => '皂',
  '��' => '灶',
  '��' => '燥',
  '��' => '责',
  '��' => '择',
  '��' => '则',
  '��' => '泽',
  '��' => '贼',
  '�' => '怎',
  '�' => '增',
  '�' => '憎',
  '�' => '曾',
  '�' => '赠',
  '�' => '扎',
  '�' => '喳',
  '�' => '渣',
  '�' => '札',
  '�' => '轧',
  '�@' => '誁',
  '�A' => '誂',
  '�B' => '誃',
  '�C' => '誄',
  '�D' => '誅',
  '�E' => '誆',
  '�F' => '誇',
  '�G' => '誈',
  '�H' => '誋',
  '�I' => '誌',
  '�J' => '認',
  '�K' => '誎',
  '�L' => '誏',
  '�M' => '誐',
  '�N' => '誑',
  '�O' => '誒',
  '�P' => '誔',
  '�Q' => '誕',
  '�R' => '誖',
  '�S' => '誗',
  '�T' => '誘',
  '�U' => '誙',
  '�V' => '誚',
  '�W' => '誛',
  '�X' => '誜',
  '�Y' => '誝',
  '�Z' => '語',
  '�[' => '誟',
  '�\\' => '誠',
  '�]' => '誡',
  '�^' => '誢',
  '�_' => '誣',
  '�`' => '誤',
  '�a' => '誥',
  '�b' => '誦',
  '�c' => '誧',
  '�d' => '誨',
  '�e' => '誩',
  '�f' => '說',
  '�g' => '誫',
  '�h' => '説',
  '�i' => '読',
  '�j' => '誮',
  '�k' => '誯',
  '�l' => '誰',
  '�m' => '誱',
  '�n' => '課',
  '�o' => '誳',
  '�p' => '誴',
  '�q' => '誵',
  '�r' => '誶',
  '�s' => '誷',
  '�t' => '誸',
  '�u' => '誹',
  '�v' => '誺',
  '�w' => '誻',
  '�x' => '誼',
  '�y' => '誽',
  '�z' => '誾',
  '�{' => '調',
  '�|' => '諀',
  '�}' => '諁',
  '�~' => '諂',
  'Հ' => '諃',
  'Ձ' => '諄',
  'Ղ' => '諅',
  'Ճ' => '諆',
  'Մ' => '談',
  'Յ' => '諈',
  'Ն' => '諉',
  'Շ' => '諊',
  'Ո' => '請',
  'Չ' => '諌',
  'Պ' => '諍',
  'Ջ' => '諎',
  'Ռ' => '諏',
  'Ս' => '諐',
  'Վ' => '諑',
  'Տ' => '諒',
  'Ր' => '諓',
  'Ց' => '諔',
  'Ւ' => '諕',
  'Փ' => '論',
  'Ք' => '諗',
  'Օ' => '諘',
  'Ֆ' => '諙',
  '՗' => '諚',
  '՘' => '諛',
  'ՙ' => '諜',
  '՚' => '諝',
  '՛' => '諞',
  '՜' => '諟',
  '՝' => '諠',
  '՞' => '諡',
  '՟' => '諢',
  'ՠ' => '諣',
  'ա' => '铡',
  'բ' => '闸',
  'գ' => '眨',
  'դ' => '栅',
  'ե' => '榨',
  'զ' => '咋',
  'է' => '乍',
  'ը' => '炸',
  'թ' => '诈',
  'ժ' => '摘',
  'ի' => '斋',
  'լ' => '宅',
  'խ' => '窄',
  'ծ' => '债',
  'կ' => '寨',
  'հ' => '瞻',
  'ձ' => '毡',
  'ղ' => '詹',
  'ճ' => '粘',
  'մ' => '沾',
  'յ' => '盏',
  'ն' => '斩',
  'շ' => '辗',
  'ո' => '崭',
  'չ' => '展',
  'պ' => '蘸',
  'ջ' => '栈',
  'ռ' => '占',
  'ս' => '战',
  'վ' => '站',
  'տ' => '湛',
  '�' => '绽',
  '�' => '樟',
  '��' => '章',
  '��' => '彰',
  '��' => '漳',
  '��' => '张',
  '��' => '掌',
  '��' => '涨',
  '��' => '杖',
  '��' => '丈',
  '��' => '帐',
  '��' => '账',
  '��' => '仗',
  '��' => '胀',
  '��' => '瘴',
  '��' => '障',
  '��' => '招',
  '��' => '昭',
  '��' => '找',
  '��' => '沼',
  '��' => '赵',
  '��' => '照',
  '��' => '罩',
  '��' => '兆',
  '��' => '肇',
  '��' => '召',
  '��' => '遮',
  '��' => '折',
  '��' => '哲',
  '��' => '蛰',
  '��' => '辙',
  '��' => '者',
  '��' => '锗',
  '��' => '蔗',
  '��' => '这',
  '��' => '浙',
  '��' => '珍',
  '��' => '斟',
  '��' => '真',
  '��' => '甄',
  '��' => '砧',
  '��' => '臻',
  '��' => '贞',
  '��' => '针',
  '��' => '侦',
  '��' => '枕',
  '��' => '疹',
  '��' => '诊',
  '��' => '震',
  '��' => '振',
  '��' => '镇',
  '��' => '阵',
  '��' => '蒸',
  '�' => '挣',
  '�' => '睁',
  '�' => '征',
  '�' => '狰',
  '�' => '争',
  '�' => '怔',
  '�' => '整',
  '�' => '拯',
  '�' => '正',
  '�' => '政',
  '�@' => '諤',
  '�A' => '諥',
  '�B' => '諦',
  '�C' => '諧',
  '�D' => '諨',
  '�E' => '諩',
  '�F' => '諪',
  '�G' => '諫',
  '�H' => '諬',
  '�I' => '諭',
  '�J' => '諮',
  '�K' => '諯',
  '�L' => '諰',
  '�M' => '諱',
  '�N' => '諲',
  '�O' => '諳',
  '�P' => '諴',
  '�Q' => '諵',
  '�R' => '諶',
  '�S' => '諷',
  '�T' => '諸',
  '�U' => '諹',
  '�V' => '諺',
  '�W' => '諻',
  '�X' => '諼',
  '�Y' => '諽',
  '�Z' => '諾',
  '�[' => '諿',
  '�\\' => '謀',
  '�]' => '謁',
  '�^' => '謂',
  '�_' => '謃',
  '�`' => '謄',
  '�a' => '謅',
  '�b' => '謆',
  '�c' => '謈',
  '�d' => '謉',
  '�e' => '謊',
  '�f' => '謋',
  '�g' => '謌',
  '�h' => '謍',
  '�i' => '謎',
  '�j' => '謏',
  '�k' => '謐',
  '�l' => '謑',
  '�m' => '謒',
  '�n' => '謓',
  '�o' => '謔',
  '�p' => '謕',
  '�q' => '謖',
  '�r' => '謗',
  '�s' => '謘',
  '�t' => '謙',
  '�u' => '謚',
  '�v' => '講',
  '�w' => '謜',
  '�x' => '謝',
  '�y' => '謞',
  '�z' => '謟',
  '�{' => '謠',
  '�|' => '謡',
  '�}' => '謢',
  '�~' => '謣',
  'ր' => '謤',
  'ց' => '謥',
  'ւ' => '謧',
  'փ' => '謨',
  'ք' => '謩',
  'օ' => '謪',
  'ֆ' => '謫',
  'և' => '謬',
  'ֈ' => '謭',
  '։' => '謮',
  '֊' => '謯',
  '֋' => '謰',
  '֌' => '謱',
  '֍' => '謲',
  '֎' => '謳',
  '֏' => '謴',
  '֐' => '謵',
  '֑' => '謶',
  '֒' => '謷',
  '֓' => '謸',
  '֔' => '謹',
  '֕' => '謺',
  '֖' => '謻',
  '֗' => '謼',
  '֘' => '謽',
  '֙' => '謾',
  '֚' => '謿',
  '֛' => '譀',
  '֜' => '譁',
  '֝' => '譂',
  '֞' => '譃',
  '֟' => '譄',
  '֠' => '譅',
  '֡' => '帧',
  '֢' => '症',
  '֣' => '郑',
  '֤' => '证',
  '֥' => '芝',
  '֦' => '枝',
  '֧' => '支',
  '֨' => '吱',
  '֩' => '蜘',
  '֪' => '知',
  '֫' => '肢',
  '֬' => '脂',
  '֭' => '汁',
  '֮' => '之',
  '֯' => '织',
  'ְ' => '职',
  'ֱ' => '直',
  'ֲ' => '植',
  'ֳ' => '殖',
  'ִ' => '执',
  'ֵ' => '值',
  'ֶ' => '侄',
  'ַ' => '址',
  'ָ' => '指',
  'ֹ' => '止',
  'ֺ' => '趾',
  'ֻ' => '只',
  'ּ' => '旨',
  'ֽ' => '纸',
  '־' => '志',
  'ֿ' => '挚',
  '�' => '掷',
  '�' => '至',
  '��' => '致',
  '��' => '置',
  '��' => '帜',
  '��' => '峙',
  '��' => '制',
  '��' => '智',
  '��' => '秩',
  '��' => '稚',
  '��' => '质',
  '��' => '炙',
  '��' => '痔',
  '��' => '滞',
  '��' => '治',
  '��' => '窒',
  '��' => '中',
  '��' => '盅',
  '��' => '忠',
  '��' => '钟',
  '��' => '衷',
  '��' => '终',
  '��' => '种',
  '��' => '肿',
  '��' => '重',
  '��' => '仲',
  '��' => '众',
  '��' => '舟',
  '��' => '周',
  '��' => '州',
  '��' => '洲',
  '��' => '诌',
  '��' => '粥',
  '��' => '轴',
  '��' => '肘',
  '��' => '帚',
  '��' => '咒',
  '��' => '皱',
  '��' => '宙',
  '��' => '昼',
  '��' => '骤',
  '��' => '珠',
  '��' => '株',
  '��' => '蛛',
  '��' => '朱',
  '��' => '猪',
  '��' => '诸',
  '��' => '诛',
  '��' => '逐',
  '��' => '竹',
  '��' => '烛',
  '��' => '煮',
  '��' => '拄',
  '�' => '瞩',
  '�' => '嘱',
  '�' => '主',
  '�' => '著',
  '�' => '柱',
  '�' => '助',
  '�' => '蛀',
  '�' => '贮',
  '�' => '铸',
  '�' => '筑',
  '�@' => '譆',
  '�A' => '譇',
  '�B' => '譈',
  '�C' => '證',
  '�D' => '譊',
  '�E' => '譋',
  '�F' => '譌',
  '�G' => '譍',
  '�H' => '譎',
  '�I' => '譏',
  '�J' => '譐',
  '�K' => '譑',
  '�L' => '譒',
  '�M' => '譓',
  '�N' => '譔',
  '�O' => '譕',
  '�P' => '譖',
  '�Q' => '譗',
  '�R' => '識',
  '�S' => '譙',
  '�T' => '譚',
  '�U' => '譛',
  '�V' => '譜',
  '�W' => '譝',
  '�X' => '譞',
  '�Y' => '譟',
  '�Z' => '譠',
  '�[' => '譡',
  '�\\' => '譢',
  '�]' => '譣',
  '�^' => '譤',
  '�_' => '譥',
  '�`' => '譧',
  '�a' => '譨',
  '�b' => '譩',
  '�c' => '譪',
  '�d' => '譫',
  '�e' => '譭',
  '�f' => '譮',
  '�g' => '譯',
  '�h' => '議',
  '�i' => '譱',
  '�j' => '譲',
  '�k' => '譳',
  '�l' => '譴',
  '�m' => '譵',
  '�n' => '譶',
  '�o' => '護',
  '�p' => '譸',
  '�q' => '譹',
  '�r' => '譺',
  '�s' => '譻',
  '�t' => '譼',
  '�u' => '譽',
  '�v' => '譾',
  '�w' => '譿',
  '�x' => '讀',
  '�y' => '讁',
  '�z' => '讂',
  '�{' => '讃',
  '�|' => '讄',
  '�}' => '讅',
  '�~' => '讆',
  '׀' => '讇',
  'ׁ' => '讈',
  'ׂ' => '讉',
  '׃' => '變',
  'ׄ' => '讋',
  'ׅ' => '讌',
  '׆' => '讍',
  'ׇ' => '讎',
  '׈' => '讏',
  '׉' => '讐',
  '׊' => '讑',
  '׋' => '讒',
  '׌' => '讓',
  '׍' => '讔',
  '׎' => '讕',
  '׏' => '讖',
  'א' => '讗',
  'ב' => '讘',
  'ג' => '讙',
  'ד' => '讚',
  'ה' => '讛',
  'ו' => '讜',
  'ז' => '讝',
  'ח' => '讞',
  'ט' => '讟',
  'י' => '讬',
  'ך' => '讱',
  'כ' => '讻',
  'ל' => '诇',
  'ם' => '诐',
  'מ' => '诪',
  'ן' => '谉',
  'נ' => '谞',
  'ס' => '住',
  'ע' => '注',
  'ף' => '祝',
  'פ' => '驻',
  'ץ' => '抓',
  'צ' => '爪',
  'ק' => '拽',
  'ר' => '专',
  'ש' => '砖',
  'ת' => '转',
  '׫' => '撰',
  '׬' => '赚',
  '׭' => '篆',
  '׮' => '桩',
  'ׯ' => '庄',
  'װ' => '装',
  'ױ' => '妆',
  'ײ' => '撞',
  '׳' => '壮',
  '״' => '状',
  '׵' => '椎',
  '׶' => '锥',
  '׷' => '追',
  '׸' => '赘',
  '׹' => '坠',
  '׺' => '缀',
  '׻' => '谆',
  '׼' => '准',
  '׽' => '捉',
  '׾' => '拙',
  '׿' => '卓',
  '�' => '桌',
  '�' => '琢',
  '��' => '茁',
  '��' => '酌',
  '��' => '啄',
  '��' => '着',
  '��' => '灼',
  '��' => '浊',
  '��' => '兹',
  '��' => '咨',
  '��' => '资',
  '��' => '姿',
  '��' => '滋',
  '��' => '淄',
  '��' => '孜',
  '��' => '紫',
  '��' => '仔',
  '��' => '籽',
  '��' => '滓',
  '��' => '子',
  '��' => '自',
  '��' => '渍',
  '��' => '字',
  '��' => '鬃',
  '��' => '棕',
  '��' => '踪',
  '��' => '宗',
  '��' => '综',
  '��' => '总',
  '��' => '纵',
  '��' => '邹',
  '��' => '走',
  '��' => '奏',
  '��' => '揍',
  '��' => '租',
  '��' => '足',
  '��' => '卒',
  '��' => '族',
  '��' => '祖',
  '��' => '诅',
  '��' => '阻',
  '��' => '组',
  '��' => '钻',
  '��' => '纂',
  '��' => '嘴',
  '��' => '醉',
  '��' => '最',
  '��' => '罪',
  '��' => '尊',
  '��' => '遵',
  '��' => '昨',
  '��' => '左',
  '��' => '佐',
  '�' => '柞',
  '�' => '做',
  '�' => '作',
  '�' => '坐',
  '�' => '座',
  '�@' => '谸',
  '�A' => '谹',
  '�B' => '谺',
  '�C' => '谻',
  '�D' => '谼',
  '�E' => '谽',
  '�F' => '谾',
  '�G' => '谿',
  '�H' => '豀',
  '�I' => '豂',
  '�J' => '豃',
  '�K' => '豄',
  '�L' => '豅',
  '�M' => '豈',
  '�N' => '豊',
  '�O' => '豋',
  '�P' => '豍',
  '�Q' => '豎',
  '�R' => '豏',
  '�S' => '豐',
  '�T' => '豑',
  '�U' => '豒',
  '�V' => '豓',
  '�W' => '豔',
  '�X' => '豖',
  '�Y' => '豗',
  '�Z' => '豘',
  '�[' => '豙',
  '�\\' => '豛',
  '�]' => '豜',
  '�^' => '豝',
  '�_' => '豞',
  '�`' => '豟',
  '�a' => '豠',
  '�b' => '豣',
  '�c' => '豤',
  '�d' => '豥',
  '�e' => '豦',
  '�f' => '豧',
  '�g' => '豨',
  '�h' => '豩',
  '�i' => '豬',
  '�j' => '豭',
  '�k' => '豮',
  '�l' => '豯',
  '�m' => '豰',
  '�n' => '豱',
  '�o' => '豲',
  '�p' => '豴',
  '�q' => '豵',
  '�r' => '豶',
  '�s' => '豷',
  '�t' => '豻',
  '�u' => '豼',
  '�v' => '豽',
  '�w' => '豾',
  '�x' => '豿',
  '�y' => '貀',
  '�z' => '貁',
  '�{' => '貃',
  '�|' => '貄',
  '�}' => '貆',
  '�~' => '貇',
  '؀' => '貈',
  '؁' => '貋',
  '؂' => '貍',
  '؃' => '貎',
  '؄' => '貏',
  '؅' => '貐',
  '؆' => '貑',
  '؇' => '貒',
  '؈' => '貓',
  '؉' => '貕',
  '؊' => '貖',
  '؋' => '貗',
  '،' => '貙',
  '؍' => '貚',
  '؎' => '貛',
  '؏' => '貜',
  'ؐ' => '貝',
  'ؑ' => '貞',
  'ؒ' => '貟',
  'ؓ' => '負',
  'ؔ' => '財',
  'ؕ' => '貢',
  'ؖ' => '貣',
  'ؗ' => '貤',
  'ؘ' => '貥',
  'ؙ' => '貦',
  'ؚ' => '貧',
  '؛' => '貨',
  '؜' => '販',
  '؝' => '貪',
  '؞' => '貫',
  '؟' => '責',
  'ؠ' => '貭',
  'ء' => '亍',
  'آ' => '丌',
  'أ' => '兀',
  'ؤ' => '丐',
  'إ' => '廿',
  'ئ' => '卅',
  'ا' => '丕',
  'ب' => '亘',
  'ة' => '丞',
  'ت' => '鬲',
  'ث' => '孬',
  'ج' => '噩',
  'ح' => '丨',
  'خ' => '禺',
  'د' => '丿',
  'ذ' => '匕',
  'ر' => '乇',
  'ز' => '夭',
  'س' => '爻',
  'ش' => '卮',
  'ص' => '氐',
  'ض' => '囟',
  'ط' => '胤',
  'ظ' => '馗',
  'ع' => '毓',
  'غ' => '睾',
  'ػ' => '鼗',
  'ؼ' => '丶',
  'ؽ' => '亟',
  'ؾ' => '鼐',
  'ؿ' => '乜',
  '�' => '乩',
  '�' => '亓',
  '��' => '芈',
  '��' => '孛',
  '��' => '啬',
  '��' => '嘏',
  '��' => '仄',
  '��' => '厍',
  '��' => '厝',
  '��' => '厣',
  '��' => '厥',
  '��' => '厮',
  '��' => '靥',
  '��' => '赝',
  '��' => '匚',
  '��' => '叵',
  '��' => '匦',
  '��' => '匮',
  '��' => '匾',
  '��' => '赜',
  '��' => '卦',
  '��' => '卣',
  '��' => '刂',
  '��' => '刈',
  '��' => '刎',
  '��' => '刭',
  '��' => '刳',
  '��' => '刿',
  '��' => '剀',
  '��' => '剌',
  '��' => '剞',
  '��' => '剡',
  '��' => '剜',
  '��' => '蒯',
  '��' => '剽',
  '��' => '劂',
  '��' => '劁',
  '��' => '劐',
  '��' => '劓',
  '��' => '冂',
  '��' => '罔',
  '��' => '亻',
  '��' => '仃',
  '��' => '仉',
  '��' => '仂',
  '��' => '仨',
  '��' => '仡',
  '��' => '仫',
  '��' => '仞',
  '��' => '伛',
  '��' => '仳',
  '��' => '伢',
  '��' => '佤',
  '�' => '仵',
  '�' => '伥',
  '�' => '伧',
  '�' => '伉',
  '�' => '伫',
  '�' => '佞',
  '�' => '佧',
  '�' => '攸',
  '�' => '佚',
  '�' => '佝',
  '�@' => '貮',
  '�A' => '貯',
  '�B' => '貰',
  '�C' => '貱',
  '�D' => '貲',
  '�E' => '貳',
  '�F' => '貴',
  '�G' => '貵',
  '�H' => '貶',
  '�I' => '買',
  '�J' => '貸',
  '�K' => '貹',
  '�L' => '貺',
  '�M' => '費',
  '�N' => '貼',
  '�O' => '貽',
  '�P' => '貾',
  '�Q' => '貿',
  '�R' => '賀',
  '�S' => '賁',
  '�T' => '賂',
  '�U' => '賃',
  '�V' => '賄',
  '�W' => '賅',
  '�X' => '賆',
  '�Y' => '資',
  '�Z' => '賈',
  '�[' => '賉',
  '�\\' => '賊',
  '�]' => '賋',
  '�^' => '賌',
  '�_' => '賍',
  '�`' => '賎',
  '�a' => '賏',
  '�b' => '賐',
  '�c' => '賑',
  '�d' => '賒',
  '�e' => '賓',
  '�f' => '賔',
  '�g' => '賕',
  '�h' => '賖',
  '�i' => '賗',
  '�j' => '賘',
  '�k' => '賙',
  '�l' => '賚',
  '�m' => '賛',
  '�n' => '賜',
  '�o' => '賝',
  '�p' => '賞',
  '�q' => '賟',
  '�r' => '賠',
  '�s' => '賡',
  '�t' => '賢',
  '�u' => '賣',
  '�v' => '賤',
  '�w' => '賥',
  '�x' => '賦',
  '�y' => '賧',
  '�z' => '賨',
  '�{' => '賩',
  '�|' => '質',
  '�}' => '賫',
  '�~' => '賬',
  'ـ' => '賭',
  'ف' => '賮',
  'ق' => '賯',
  'ك' => '賰',
  'ل' => '賱',
  'م' => '賲',
  'ن' => '賳',
  'ه' => '賴',
  'و' => '賵',
  'ى' => '賶',
  'ي' => '賷',
  'ً' => '賸',
  'ٌ' => '賹',
  'ٍ' => '賺',
  'َ' => '賻',
  'ُ' => '購',
  'ِ' => '賽',
  'ّ' => '賾',
  'ْ' => '賿',
  'ٓ' => '贀',
  'ٔ' => '贁',
  'ٕ' => '贂',
  'ٖ' => '贃',
  'ٗ' => '贄',
  '٘' => '贅',
  'ٙ' => '贆',
  'ٚ' => '贇',
  'ٛ' => '贈',
  'ٜ' => '贉',
  'ٝ' => '贊',
  'ٞ' => '贋',
  'ٟ' => '贌',
  '٠' => '贍',
  '١' => '佟',
  '٢' => '佗',
  '٣' => '伲',
  '٤' => '伽',
  '٥' => '佶',
  '٦' => '佴',
  '٧' => '侑',
  '٨' => '侉',
  '٩' => '侃',
  '٪' => '侏',
  '٫' => '佾',
  '٬' => '佻',
  '٭' => '侪',
  'ٮ' => '佼',
  'ٯ' => '侬',
  'ٰ' => '侔',
  'ٱ' => '俦',
  'ٲ' => '俨',
  'ٳ' => '俪',
  'ٴ' => '俅',
  'ٵ' => '俚',
  'ٶ' => '俣',
  'ٷ' => '俜',
  'ٸ' => '俑',
  'ٹ' => '俟',
  'ٺ' => '俸',
  'ٻ' => '倩',
  'ټ' => '偌',
  'ٽ' => '俳',
  'پ' => '倬',
  'ٿ' => '倏',
  '�' => '倮',
  '�' => '倭',
  '��' => '俾',
  '��' => '倜',
  '��' => '倌',
  '��' => '倥',
  '��' => '倨',
  '��' => '偾',
  '��' => '偃',
  '��' => '偕',
  '��' => '偈',
  '��' => '偎',
  '��' => '偬',
  '��' => '偻',
  '��' => '傥',
  '��' => '傧',
  '��' => '傩',
  '��' => '傺',
  '��' => '僖',
  '��' => '儆',
  '��' => '僭',
  '��' => '僬',
  '��' => '僦',
  '��' => '僮',
  '��' => '儇',
  '��' => '儋',
  '��' => '仝',
  '��' => '氽',
  '��' => '佘',
  '��' => '佥',
  '��' => '俎',
  '��' => '龠',
  '��' => '汆',
  '��' => '籴',
  '��' => '兮',
  '��' => '巽',
  '��' => '黉',
  '��' => '馘',
  '��' => '冁',
  '��' => '夔',
  '��' => '勹',
  '��' => '匍',
  '��' => '訇',
  '��' => '匐',
  '��' => '凫',
  '��' => '夙',
  '��' => '兕',
  '��' => '亠',
  '��' => '兖',
  '��' => '亳',
  '��' => '衮',
  '��' => '袤',
  '��' => '亵',
  '�' => '脔',
  '�' => '裒',
  '�' => '禀',
  '�' => '嬴',
  '�' => '蠃',
  '�' => '羸',
  '�' => '冫',
  '�' => '冱',
  '�' => '冽',
  '�' => '冼',
  '�@' => '贎',
  '�A' => '贏',
  '�B' => '贐',
  '�C' => '贑',
  '�D' => '贒',
  '�E' => '贓',
  '�F' => '贔',
  '�G' => '贕',
  '�H' => '贖',
  '�I' => '贗',
  '�J' => '贘',
  '�K' => '贙',
  '�L' => '贚',
  '�M' => '贛',
  '�N' => '贜',
  '�O' => '贠',
  '�P' => '赑',
  '�Q' => '赒',
  '�R' => '赗',
  '�S' => '赟',
  '�T' => '赥',
  '�U' => '赨',
  '�V' => '赩',
  '�W' => '赪',
  '�X' => '赬',
  '�Y' => '赮',
  '�Z' => '赯',
  '�[' => '赱',
  '�\\' => '赲',
  '�]' => '赸',
  '�^' => '赹',
  '�_' => '赺',
  '�`' => '赻',
  '�a' => '赼',
  '�b' => '赽',
  '�c' => '赾',
  '�d' => '赿',
  '�e' => '趀',
  '�f' => '趂',
  '�g' => '趃',
  '�h' => '趆',
  '�i' => '趇',
  '�j' => '趈',
  '�k' => '趉',
  '�l' => '趌',
  '�m' => '趍',
  '�n' => '趎',
  '�o' => '趏',
  '�p' => '趐',
  '�q' => '趒',
  '�r' => '趓',
  '�s' => '趕',
  '�t' => '趖',
  '�u' => '趗',
  '�v' => '趘',
  '�w' => '趙',
  '�x' => '趚',
  '�y' => '趛',
  '�z' => '趜',
  '�{' => '趝',
  '�|' => '趞',
  '�}' => '趠',
  '�~' => '趡',
  'ڀ' => '趢',
  'ځ' => '趤',
  'ڂ' => '趥',
  'ڃ' => '趦',
  'ڄ' => '趧',
  'څ' => '趨',
  'چ' => '趩',
  'ڇ' => '趪',
  'ڈ' => '趫',
  'ډ' => '趬',
  'ڊ' => '趭',
  'ڋ' => '趮',
  'ڌ' => '趯',
  'ڍ' => '趰',
  'ڎ' => '趲',
  'ڏ' => '趶',
  'ڐ' => '趷',
  'ڑ' => '趹',
  'ڒ' => '趻',
  'ړ' => '趽',
  'ڔ' => '跀',
  'ڕ' => '跁',
  'ږ' => '跂',
  'ڗ' => '跅',
  'ژ' => '跇',
  'ڙ' => '跈',
  'ښ' => '跉',
  'ڛ' => '跊',
  'ڜ' => '跍',
  'ڝ' => '跐',
  'ڞ' => '跒',
  'ڟ' => '跓',
  'ڠ' => '跔',
  'ڡ' => '凇',
  'ڢ' => '冖',
  'ڣ' => '冢',
  'ڤ' => '冥',
  'ڥ' => '讠',
  'ڦ' => '讦',
  'ڧ' => '讧',
  'ڨ' => '讪',
  'ک' => '讴',
  'ڪ' => '讵',
  'ګ' => '讷',
  'ڬ' => '诂',
  'ڭ' => '诃',
  'ڮ' => '诋',
  'گ' => '诏',
  'ڰ' => '诎',
  'ڱ' => '诒',
  'ڲ' => '诓',
  'ڳ' => '诔',
  'ڴ' => '诖',
  'ڵ' => '诘',
  'ڶ' => '诙',
  'ڷ' => '诜',
  'ڸ' => '诟',
  'ڹ' => '诠',
  'ں' => '诤',
  'ڻ' => '诨',
  'ڼ' => '诩',
  'ڽ' => '诮',
  'ھ' => '诰',
  'ڿ' => '诳',
  '�' => '诶',
  '�' => '诹',
  '��' => '诼',
  '��' => '诿',
  '��' => '谀',
  '��' => '谂',
  '��' => '谄',
  '��' => '谇',
  '��' => '谌',
  '��' => '谏',
  '��' => '谑',
  '��' => '谒',
  '��' => '谔',
  '��' => '谕',
  '��' => '谖',
  '��' => '谙',
  '��' => '谛',
  '��' => '谘',
  '��' => '谝',
  '��' => '谟',
  '��' => '谠',
  '��' => '谡',
  '��' => '谥',
  '��' => '谧',
  '��' => '谪',
  '��' => '谫',
  '��' => '谮',
  '��' => '谯',
  '��' => '谲',
  '��' => '谳',
  '��' => '谵',
  '��' => '谶',
  '��' => '卩',
  '��' => '卺',
  '��' => '阝',
  '��' => '阢',
  '��' => '阡',
  '��' => '阱',
  '��' => '阪',
  '��' => '阽',
  '��' => '阼',
  '��' => '陂',
  '��' => '陉',
  '��' => '陔',
  '��' => '陟',
  '��' => '陧',
  '��' => '陬',
  '��' => '陲',
  '��' => '陴',
  '��' => '隈',
  '��' => '隍',
  '��' => '隗',
  '��' => '隰',
  '�' => '邗',
  '�' => '邛',
  '�' => '邝',
  '�' => '邙',
  '�' => '邬',
  '�' => '邡',
  '�' => '邴',
  '�' => '邳',
  '�' => '邶',
  '�' => '邺',
  '�@' => '跕',
  '�A' => '跘',
  '�B' => '跙',
  '�C' => '跜',
  '�D' => '跠',
  '�E' => '跡',
  '�F' => '跢',
  '�G' => '跥',
  '�H' => '跦',
  '�I' => '跧',
  '�J' => '跩',
  '�K' => '跭',
  '�L' => '跮',
  '�M' => '跰',
  '�N' => '跱',
  '�O' => '跲',
  '�P' => '跴',
  '�Q' => '跶',
  '�R' => '跼',
  '�S' => '跾',
  '�T' => '跿',
  '�U' => '踀',
  '�V' => '踁',
  '�W' => '踂',
  '�X' => '踃',
  '�Y' => '踄',
  '�Z' => '踆',
  '�[' => '踇',
  '�\\' => '踈',
  '�]' => '踋',
  '�^' => '踍',
  '�_' => '踎',
  '�`' => '踐',
  '�a' => '踑',
  '�b' => '踒',
  '�c' => '踓',
  '�d' => '踕',
  '�e' => '踖',
  '�f' => '踗',
  '�g' => '踘',
  '�h' => '踙',
  '�i' => '踚',
  '�j' => '踛',
  '�k' => '踜',
  '�l' => '踠',
  '�m' => '踡',
  '�n' => '踤',
  '�o' => '踥',
  '�p' => '踦',
  '�q' => '踧',
  '�r' => '踨',
  '�s' => '踫',
  '�t' => '踭',
  '�u' => '踰',
  '�v' => '踲',
  '�w' => '踳',
  '�x' => '踴',
  '�y' => '踶',
  '�z' => '踷',
  '�{' => '踸',
  '�|' => '踻',
  '�}' => '踼',
  '�~' => '踾',
  'ۀ' => '踿',
  'ہ' => '蹃',
  'ۂ' => '蹅',
  'ۃ' => '蹆',
  'ۄ' => '蹌',
  'ۅ' => '蹍',
  'ۆ' => '蹎',
  'ۇ' => '蹏',
  'ۈ' => '蹐',
  'ۉ' => '蹓',
  'ۊ' => '蹔',
  'ۋ' => '蹕',
  'ی' => '蹖',
  'ۍ' => '蹗',
  'ێ' => '蹘',
  'ۏ' => '蹚',
  'ې' => '蹛',
  'ۑ' => '蹜',
  'ے' => '蹝',
  'ۓ' => '蹞',
  '۔' => '蹟',
  'ە' => '蹠',
  'ۖ' => '蹡',
  'ۗ' => '蹢',
  'ۘ' => '蹣',
  'ۙ' => '蹤',
  'ۚ' => '蹥',
  'ۛ' => '蹧',
  'ۜ' => '蹨',
  '۝' => '蹪',
  '۞' => '蹫',
  '۟' => '蹮',
  '۠' => '蹱',
  'ۡ' => '邸',
  'ۢ' => '邰',
  'ۣ' => '郏',
  'ۤ' => '郅',
  'ۥ' => '邾',
  'ۦ' => '郐',
  'ۧ' => '郄',
  'ۨ' => '郇',
  '۩' => '郓',
  '۪' => '郦',
  '۫' => '郢',
  '۬' => '郜',
  'ۭ' => '郗',
  'ۮ' => '郛',
  'ۯ' => '郫',
  '۰' => '郯',
  '۱' => '郾',
  '۲' => '鄄',
  '۳' => '鄢',
  '۴' => '鄞',
  '۵' => '鄣',
  '۶' => '鄱',
  '۷' => '鄯',
  '۸' => '鄹',
  '۹' => '酃',
  'ۺ' => '酆',
  'ۻ' => '刍',
  'ۼ' => '奂',
  '۽' => '劢',
  '۾' => '劬',
  'ۿ' => '劭',
  '�' => '劾',
  '�' => '哿',
  '��' => '勐',
  '��' => '勖',
  '��' => '勰',
  '��' => '叟',
  '��' => '燮',
  '��' => '矍',
  '��' => '廴',
  '��' => '凵',
  '��' => '凼',
  '��' => '鬯',
  '��' => '厶',
  '��' => '弁',
  '��' => '畚',
  '��' => '巯',
  '��' => '坌',
  '��' => '垩',
  '��' => '垡',
  '��' => '塾',
  '��' => '墼',
  '��' => '壅',
  '��' => '壑',
  '��' => '圩',
  '��' => '圬',
  '��' => '圪',
  '��' => '圳',
  '��' => '圹',
  '��' => '圮',
  '��' => '圯',
  '��' => '坜',
  '��' => '圻',
  '��' => '坂',
  '��' => '坩',
  '��' => '垅',
  '��' => '坫',
  '��' => '垆',
  '��' => '坼',
  '��' => '坻',
  '��' => '坨',
  '��' => '坭',
  '��' => '坶',
  '��' => '坳',
  '��' => '垭',
  '��' => '垤',
  '��' => '垌',
  '��' => '垲',
  '��' => '埏',
  '��' => '垧',
  '��' => '垴',
  '��' => '垓',
  '��' => '垠',
  '��' => '埕',
  '�' => '埘',
  '�' => '埚',
  '�' => '埙',
  '�' => '埒',
  '�' => '垸',
  '�' => '埴',
  '�' => '埯',
  '�' => '埸',
  '�' => '埤',
  '�' => '埝',
  '�@' => '蹳',
  '�A' => '蹵',
  '�B' => '蹷',
  '�C' => '蹸',
  '�D' => '蹹',
  '�E' => '蹺',
  '�F' => '蹻',
  '�G' => '蹽',
  '�H' => '蹾',
  '�I' => '躀',
  '�J' => '躂',
  '�K' => '躃',
  '�L' => '躄',
  '�M' => '躆',
  '�N' => '躈',
  '�O' => '躉',
  '�P' => '躊',
  '�Q' => '躋',
  '�R' => '躌',
  '�S' => '躍',
  '�T' => '躎',
  '�U' => '躑',
  '�V' => '躒',
  '�W' => '躓',
  '�X' => '躕',
  '�Y' => '躖',
  '�Z' => '躗',
  '�[' => '躘',
  '�\\' => '躙',
  '�]' => '躚',
  '�^' => '躛',
  '�_' => '躝',
  '�`' => '躟',
  '�a' => '躠',
  '�b' => '躡',
  '�c' => '躢',
  '�d' => '躣',
  '�e' => '躤',
  '�f' => '躥',
  '�g' => '躦',
  '�h' => '躧',
  '�i' => '躨',
  '�j' => '躩',
  '�k' => '躪',
  '�l' => '躭',
  '�m' => '躮',
  '�n' => '躰',
  '�o' => '躱',
  '�p' => '躳',
  '�q' => '躴',
  '�r' => '躵',
  '�s' => '躶',
  '�t' => '躷',
  '�u' => '躸',
  '�v' => '躹',
  '�w' => '躻',
  '�x' => '躼',
  '�y' => '躽',
  '�z' => '躾',
  '�{' => '躿',
  '�|' => '軀',
  '�}' => '軁',
  '�~' => '軂',
  '܀' => '軃',
  '܁' => '軄',
  '܂' => '軅',
  '܃' => '軆',
  '܄' => '軇',
  '܅' => '軈',
  '܆' => '軉',
  '܇' => '車',
  '܈' => '軋',
  '܉' => '軌',
  '܊' => '軍',
  '܋' => '軏',
  '܌' => '軐',
  '܍' => '軑',
  '܎' => '軒',
  '܏' => '軓',
  'ܐ' => '軔',
  'ܑ' => '軕',
  'ܒ' => '軖',
  'ܓ' => '軗',
  'ܔ' => '軘',
  'ܕ' => '軙',
  'ܖ' => '軚',
  'ܗ' => '軛',
  'ܘ' => '軜',
  'ܙ' => '軝',
  'ܚ' => '軞',
  'ܛ' => '軟',
  'ܜ' => '軠',
  'ܝ' => '軡',
  'ܞ' => '転',
  'ܟ' => '軣',
  'ܠ' => '軤',
  'ܡ' => '堋',
  'ܢ' => '堍',
  'ܣ' => '埽',
  'ܤ' => '埭',
  'ܥ' => '堀',
  'ܦ' => '堞',
  'ܧ' => '堙',
  'ܨ' => '塄',
  'ܩ' => '堠',
  'ܪ' => '塥',
  'ܫ' => '塬',
  'ܬ' => '墁',
  'ܭ' => '墉',
  'ܮ' => '墚',
  'ܯ' => '墀',
  'ܰ' => '馨',
  'ܱ' => '鼙',
  'ܲ' => '懿',
  'ܳ' => '艹',
  'ܴ' => '艽',
  'ܵ' => '艿',
  'ܶ' => '芏',
  'ܷ' => '芊',
  'ܸ' => '芨',
  'ܹ' => '芄',
  'ܺ' => '芎',
  'ܻ' => '芑',
  'ܼ' => '芗',
  'ܽ' => '芙',
  'ܾ' => '芫',
  'ܿ' => '芸',
  '�' => '芾',
  '�' => '芰',
  '��' => '苈',
  '��' => '苊',
  '��' => '苣',
  '��' => '芘',
  '��' => '芷',
  '��' => '芮',
  '��' => '苋',
  '��' => '苌',
  '��' => '苁',
  '��' => '芩',
  '��' => '芴',
  '��' => '芡',
  '��' => '芪',
  '��' => '芟',
  '��' => '苄',
  '��' => '苎',
  '��' => '芤',
  '��' => '苡',
  '��' => '茉',
  '��' => '苷',
  '��' => '苤',
  '��' => '茏',
  '��' => '茇',
  '��' => '苜',
  '��' => '苴',
  '��' => '苒',
  '��' => '苘',
  '��' => '茌',
  '��' => '苻',
  '��' => '苓',
  '��' => '茑',
  '��' => '茚',
  '��' => '茆',
  '��' => '茔',
  '��' => '茕',
  '��' => '苠',
  '��' => '苕',
  '��' => '茜',
  '��' => '荑',
  '��' => '荛',
  '��' => '荜',
  '��' => '茈',
  '��' => '莒',
  '��' => '茼',
  '��' => '茴',
  '��' => '茱',
  '��' => '莛',
  '��' => '荞',
  '��' => '茯',
  '��' => '荏',
  '��' => '荇',
  '�' => '荃',
  '�' => '荟',
  '�' => '荀',
  '�' => '茗',
  '�' => '荠',
  '�' => '茭',
  '�' => '茺',
  '�' => '茳',
  '�' => '荦',
  '�' => '荥',
  '�@' => '軥',
  '�A' => '軦',
  '�B' => '軧',
  '�C' => '軨',
  '�D' => '軩',
  '�E' => '軪',
  '�F' => '軫',
  '�G' => '軬',
  '�H' => '軭',
  '�I' => '軮',
  '�J' => '軯',
  '�K' => '軰',
  '�L' => '軱',
  '�M' => '軲',
  '�N' => '軳',
  '�O' => '軴',
  '�P' => '軵',
  '�Q' => '軶',
  '�R' => '軷',
  '�S' => '軸',
  '�T' => '軹',
  '�U' => '軺',
  '�V' => '軻',
  '�W' => '軼',
  '�X' => '軽',
  '�Y' => '軾',
  '�Z' => '軿',
  '�[' => '輀',
  '�\\' => '輁',
  '�]' => '輂',
  '�^' => '較',
  '�_' => '輄',
  '�`' => '輅',
  '�a' => '輆',
  '�b' => '輇',
  '�c' => '輈',
  '�d' => '載',
  '�e' => '輊',
  '�f' => '輋',
  '�g' => '輌',
  '�h' => '輍',
  '�i' => '輎',
  '�j' => '輏',
  '�k' => '輐',
  '�l' => '輑',
  '�m' => '輒',
  '�n' => '輓',
  '�o' => '輔',
  '�p' => '輕',
  '�q' => '輖',
  '�r' => '輗',
  '�s' => '輘',
  '�t' => '輙',
  '�u' => '輚',
  '�v' => '輛',
  '�w' => '輜',
  '�x' => '輝',
  '�y' => '輞',
  '�z' => '輟',
  '�{' => '輠',
  '�|' => '輡',
  '�}' => '輢',
  '�~' => '輣',
  '݀' => '輤',
  '݁' => '輥',
  '݂' => '輦',
  '݃' => '輧',
  '݄' => '輨',
  '݅' => '輩',
  '݆' => '輪',
  '݇' => '輫',
  '݈' => '輬',
  '݉' => '輭',
  '݊' => '輮',
  '݋' => '輯',
  '݌' => '輰',
  'ݍ' => '輱',
  'ݎ' => '輲',
  'ݏ' => '輳',
  'ݐ' => '輴',
  'ݑ' => '輵',
  'ݒ' => '輶',
  'ݓ' => '輷',
  'ݔ' => '輸',
  'ݕ' => '輹',
  'ݖ' => '輺',
  'ݗ' => '輻',
  'ݘ' => '輼',
  'ݙ' => '輽',
  'ݚ' => '輾',
  'ݛ' => '輿',
  'ݜ' => '轀',
  'ݝ' => '轁',
  'ݞ' => '轂',
  'ݟ' => '轃',
  'ݠ' => '轄',
  'ݡ' => '荨',
  'ݢ' => '茛',
  'ݣ' => '荩',
  'ݤ' => '荬',
  'ݥ' => '荪',
  'ݦ' => '荭',
  'ݧ' => '荮',
  'ݨ' => '莰',
  'ݩ' => '荸',
  'ݪ' => '莳',
  'ݫ' => '莴',
  'ݬ' => '莠',
  'ݭ' => '莪',
  'ݮ' => '莓',
  'ݯ' => '莜',
  'ݰ' => '莅',
  'ݱ' => '荼',
  'ݲ' => '莶',
  'ݳ' => '莩',
  'ݴ' => '荽',
  'ݵ' => '莸',
  'ݶ' => '荻',
  'ݷ' => '莘',
  'ݸ' => '莞',
  'ݹ' => '莨',
  'ݺ' => '莺',
  'ݻ' => '莼',
  'ݼ' => '菁',
  'ݽ' => '萁',
  'ݾ' => '菥',
  'ݿ' => '菘',
  '�' => '堇',
  '�' => '萘',
  '��' => '萋',
  '��' => '菝',
  '��' => '菽',
  '��' => '菖',
  '��' => '萜',
  '��' => '萸',
  '��' => '萑',
  '��' => '萆',
  '��' => '菔',
  '��' => '菟',
  '��' => '萏',
  '��' => '萃',
  '��' => '菸',
  '��' => '菹',
  '��' => '菪',
  '��' => '菅',
  '��' => '菀',
  '��' => '萦',
  '��' => '菰',
  '��' => '菡',
  '��' => '葜',
  '��' => '葑',
  '��' => '葚',
  '��' => '葙',
  '��' => '葳',
  '��' => '蒇',
  '��' => '蒈',
  '��' => '葺',
  '��' => '蒉',
  '��' => '葸',
  '��' => '萼',
  '��' => '葆',
  '��' => '葩',
  '��' => '葶',
  '��' => '蒌',
  '��' => '蒎',
  '��' => '萱',
  '��' => '葭',
  '��' => '蓁',
  '��' => '蓍',
  '��' => '蓐',
  '��' => '蓦',
  '��' => '蒽',
  '��' => '蓓',
  '��' => '蓊',
  '��' => '蒿',
  '��' => '蒺',
  '��' => '蓠',
  '��' => '蒡',
  '��' => '蒹',
  '��' => '蒴',
  '�' => '蒗',
  '�' => '蓥',
  '�' => '蓣',
  '�' => '蔌',
  '�' => '甍',
  '�' => '蔸',
  '�' => '蓰',
  '�' => '蔹',
  '�' => '蔟',
  '�' => '蔺',
  '�@' => '轅',
  '�A' => '轆',
  '�B' => '轇',
  '�C' => '轈',
  '�D' => '轉',
  '�E' => '轊',
  '�F' => '轋',
  '�G' => '轌',
  '�H' => '轍',
  '�I' => '轎',
  '�J' => '轏',
  '�K' => '轐',
  '�L' => '轑',
  '�M' => '轒',
  '�N' => '轓',
  '�O' => '轔',
  '�P' => '轕',
  '�Q' => '轖',
  '�R' => '轗',
  '�S' => '轘',
  '�T' => '轙',
  '�U' => '轚',
  '�V' => '轛',
  '�W' => '轜',
  '�X' => '轝',
  '�Y' => '轞',
  '�Z' => '轟',
  '�[' => '轠',
  '�\\' => '轡',
  '�]' => '轢',
  '�^' => '轣',
  '�_' => '轤',
  '�`' => '轥',
  '�a' => '轪',
  '�b' => '辀',
  '�c' => '辌',
  '�d' => '辒',
  '�e' => '辝',
  '�f' => '辠',
  '�g' => '辡',
  '�h' => '辢',
  '�i' => '辤',
  '�j' => '辥',
  '�k' => '辦',
  '�l' => '辧',
  '�m' => '辪',
  '�n' => '辬',
  '�o' => '辭',
  '�p' => '辮',
  '�q' => '辯',
  '�r' => '農',
  '�s' => '辳',
  '�t' => '辴',
  '�u' => '辵',
  '�v' => '辷',
  '�w' => '辸',
  '�x' => '辺',
  '�y' => '辻',
  '�z' => '込',
  '�{' => '辿',
  '�|' => '迀',
  '�}' => '迃',
  '�~' => '迆',
  'ހ' => '迉',
  'ށ' => '迊',
  'ނ' => '迋',
  'ރ' => '迌',
  'ބ' => '迍',
  'ޅ' => '迏',
  'ކ' => '迒',
  'އ' => '迖',
  'ވ' => '迗',
  'މ' => '迚',
  'ފ' => '迠',
  'ދ' => '迡',
  'ތ' => '迣',
  'ލ' => '迧',
  'ގ' => '迬',
  'ޏ' => '迯',
  'ސ' => '迱',
  'ޑ' => '迲',
  'ޒ' => '迴',
  'ޓ' => '迵',
  'ޔ' => '迶',
  'ޕ' => '迺',
  'ޖ' => '迻',
  'ޗ' => '迼',
  'ޘ' => '迾',
  'ޙ' => '迿',
  'ޚ' => '逇',
  'ޛ' => '逈',
  'ޜ' => '逌',
  'ޝ' => '逎',
  'ޞ' => '逓',
  'ޟ' => '逕',
  'ޠ' => '逘',
  'ޡ' => '蕖',
  'ޢ' => '蔻',
  'ޣ' => '蓿',
  'ޤ' => '蓼',
  'ޥ' => '蕙',
  'ަ' => '蕈',
  'ާ' => '蕨',
  'ި' => '蕤',
  'ީ' => '蕞',
  'ު' => '蕺',
  'ޫ' => '瞢',
  'ެ' => '蕃',
  'ޭ' => '蕲',
  'ޮ' => '蕻',
  'ޯ' => '薤',
  'ް' => '薨',
  'ޱ' => '薇',
  '޲' => '薏',
  '޳' => '蕹',
  '޴' => '薮',
  '޵' => '薜',
  '޶' => '薅',
  '޷' => '薹',
  '޸' => '薷',
  '޹' => '薰',
  '޺' => '藓',
  '޻' => '藁',
  '޼' => '藜',
  '޽' => '藿',
  '޾' => '蘧',
  '޿' => '蘅',
  '�' => '蘩',
  '�' => '蘖',
  '��' => '蘼',
  '��' => '廾',
  '��' => '弈',
  '��' => '夼',
  '��' => '奁',
  '��' => '耷',
  '��' => '奕',
  '��' => '奚',
  '��' => '奘',
  '��' => '匏',
  '��' => '尢',
  '��' => '尥',
  '��' => '尬',
  '��' => '尴',
  '��' => '扌',
  '��' => '扪',
  '��' => '抟',
  '��' => '抻',
  '��' => '拊',
  '��' => '拚',
  '��' => '拗',
  '��' => '拮',
  '��' => '挢',
  '��' => '拶',
  '��' => '挹',
  '��' => '捋',
  '��' => '捃',
  '��' => '掭',
  '��' => '揶',
  '��' => '捱',
  '��' => '捺',
  '��' => '掎',
  '��' => '掴',
  '��' => '捭',
  '��' => '掬',
  '��' => '掊',
  '��' => '捩',
  '��' => '掮',
  '��' => '掼',
  '��' => '揲',
  '��' => '揸',
  '��' => '揠',
  '��' => '揿',
  '��' => '揄',
  '��' => '揞',
  '��' => '揎',
  '��' => '摒',
  '��' => '揆',
  '��' => '掾',
  '��' => '摅',
  '��' => '摁',
  '�' => '搋',
  '�' => '搛',
  '�' => '搠',
  '�' => '搌',
  '�' => '搦',
  '�' => '搡',
  '�' => '摞',
  '�' => '撄',
  '�' => '摭',
  '�' => '撖',
  '�@' => '這',
  '�A' => '逜',
  '�B' => '連',
  '�C' => '逤',
  '�D' => '逥',
  '�E' => '逧',
  '�F' => '逨',
  '�G' => '逩',
  '�H' => '逪',
  '�I' => '逫',
  '�J' => '逬',
  '�K' => '逰',
  '�L' => '週',
  '�M' => '進',
  '�N' => '逳',
  '�O' => '逴',
  '�P' => '逷',
  '�Q' => '逹',
  '�R' => '逺',
  '�S' => '逽',
  '�T' => '逿',
  '�U' => '遀',
  '�V' => '遃',
  '�W' => '遅',
  '�X' => '遆',
  '�Y' => '遈',
  '�Z' => '遉',
  '�[' => '遊',
  '�\\' => '運',
  '�]' => '遌',
  '�^' => '過',
  '�_' => '達',
  '�`' => '違',
  '�a' => '遖',
  '�b' => '遙',
  '�c' => '遚',
  '�d' => '遜',
  '�e' => '遝',
  '�f' => '遞',
  '�g' => '遟',
  '�h' => '遠',
  '�i' => '遡',
  '�j' => '遤',
  '�k' => '遦',
  '�l' => '遧',
  '�m' => '適',
  '�n' => '遪',
  '�o' => '遫',
  '�p' => '遬',
  '�q' => '遯',
  '�r' => '遰',
  '�s' => '遱',
  '�t' => '遲',
  '�u' => '遳',
  '�v' => '遶',
  '�w' => '遷',
  '�x' => '選',
  '�y' => '遹',
  '�z' => '遺',
  '�{' => '遻',
  '�|' => '遼',
  '�}' => '遾',
  '�~' => '邁',
  '߀' => '還',
  '߁' => '邅',
  '߂' => '邆',
  '߃' => '邇',
  '߄' => '邉',
  '߅' => '邊',
  '߆' => '邌',
  '߇' => '邍',
  '߈' => '邎',
  '߉' => '邏',
  'ߊ' => '邐',
  'ߋ' => '邒',
  'ߌ' => '邔',
  'ߍ' => '邖',
  'ߎ' => '邘',
  'ߏ' => '邚',
  'ߐ' => '邜',
  'ߑ' => '邞',
  'ߒ' => '邟',
  'ߓ' => '邠',
  'ߔ' => '邤',
  'ߕ' => '邥',
  'ߖ' => '邧',
  'ߗ' => '邨',
  'ߘ' => '邩',
  'ߙ' => '邫',
  'ߚ' => '邭',
  'ߛ' => '邲',
  'ߜ' => '邷',
  'ߝ' => '邼',
  'ߞ' => '邽',
  'ߟ' => '邿',
  'ߠ' => '郀',
  'ߡ' => '摺',
  'ߢ' => '撷',
  'ߣ' => '撸',
  'ߤ' => '撙',
  'ߥ' => '撺',
  'ߦ' => '擀',
  'ߧ' => '擐',
  'ߨ' => '擗',
  'ߩ' => '擤',
  'ߪ' => '擢',
  '߫' => '攉',
  '߬' => '攥',
  '߭' => '攮',
  '߮' => '弋',
  '߯' => '忒',
  '߰' => '甙',
  '߱' => '弑',
  '߲' => '卟',
  '߳' => '叱',
  'ߴ' => '叽',
  'ߵ' => '叩',
  '߶' => '叨',
  '߷' => '叻',
  '߸' => '吒',
  '߹' => '吖',
  'ߺ' => '吆',
  '߻' => '呋',
  '߼' => '呒',
  '߽' => '呓',
  '߾' => '呔',
  '߿' => '呖',
  '�' => '呃',
  '�' => '吡',
  '��' => '呗',
  '��' => '呙',
  '��' => '吣',
  '��' => '吲',
  '��' => '咂',
  '��' => '咔',
  '��' => '呷',
  '��' => '呱',
  '��' => '呤',
  '��' => '咚',
  '��' => '咛',
  '��' => '咄',
  '��' => '呶',
  '��' => '呦',
  '��' => '咝',
  '��' => '哐',
  '��' => '咭',
  '��' => '哂',
  '��' => '咴',
  '��' => '哒',
  '��' => '咧',
  '��' => '咦',
  '��' => '哓',
  '��' => '哔',
  '��' => '呲',
  '��' => '咣',
  '��' => '哕',
  '��' => '咻',
  '��' => '咿',
  '��' => '哌',
  '��' => '哙',
  '��' => '哚',
  '��' => '哜',
  '��' => '咩',
  '��' => '咪',
  '��' => '咤',
  '��' => '哝',
  '��' => '哏',
  '��' => '哞',
  '��' => '唛',
  '��' => '哧',
  '��' => '唠',
  '��' => '哽',
  '��' => '唔',
  '��' => '哳',
  '��' => '唢',
  '��' => '唣',
  '��' => '唏',
  '��' => '唑',
  '��' => '唧',
  '��' => '唪',
  '�' => '啧',
  '�' => '喏',
  '�' => '喵',
  '�' => '啉',
  '�' => '啭',
  '�' => '啁',
  '�' => '啕',
  '�' => '唿',
  '�' => '啐',
  '�' => '唼',
  '�@' => '郂',
  '�A' => '郃',
  '�B' => '郆',
  '�C' => '郈',
  '�D' => '郉',
  '�E' => '郋',
  '�F' => '郌',
  '�G' => '郍',
  '�H' => '郒',
  '�I' => '郔',
  '�J' => '郕',
  '�K' => '郖',
  '�L' => '郘',
  '�M' => '郙',
  '�N' => '郚',
  '�O' => '郞',
  '�P' => '郟',
  '�Q' => '郠',
  '�R' => '郣',
  '�S' => '郤',
  '�T' => '郥',
  '�U' => '郩',
  '�V' => '郪',
  '�W' => '郬',
  '�X' => '郮',
  '�Y' => '郰',
  '�Z' => '郱',
  '�[' => '郲',
  '�\\' => '郳',
  '�]' => '郵',
  '�^' => '郶',
  '�_' => '郷',
  '�`' => '郹',
  '�a' => '郺',
  '�b' => '郻',
  '�c' => '郼',
  '�d' => '郿',
  '�e' => '鄀',
  '�f' => '鄁',
  '�g' => '鄃',
  '�h' => '鄅',
  '�i' => '鄆',
  '�j' => '鄇',
  '�k' => '鄈',
  '�l' => '鄉',
  '�m' => '鄊',
  '�n' => '鄋',
  '�o' => '鄌',
  '�p' => '鄍',
  '�q' => '鄎',
  '�r' => '鄏',
  '�s' => '鄐',
  '�t' => '鄑',
  '�u' => '鄒',
  '�v' => '鄓',
  '�w' => '鄔',
  '�x' => '鄕',
  '�y' => '鄖',
  '�z' => '鄗',
  '�{' => '鄘',
  '�|' => '鄚',
  '�}' => '鄛',
  '�~' => '鄜',
  '�' => '鄝',
  '�' => '鄟',
  '�' => '鄠',
  '�' => '鄡',
  '�' => '鄤',
  '�' => '鄥',
  '�' => '鄦',
  '�' => '鄧',
  '�' => '鄨',
  '�' => '鄩',
  '�' => '鄪',
  '�' => '鄫',
  '�' => '鄬',
  '�' => '鄭',
  '�' => '鄮',
  '�' => '鄰',
  '�' => '鄲',
  '�' => '鄳',
  '�' => '鄴',
  '�' => '鄵',
  '�' => '鄶',
  '�' => '鄷',
  '�' => '鄸',
  '�' => '鄺',
  '�' => '鄻',
  '�' => '鄼',
  '�' => '鄽',
  '�' => '鄾',
  '�' => '鄿',
  '�' => '酀',
  '�' => '酁',
  '�' => '酂',
  '�' => '酄',
  '�' => '唷',
  '�' => '啖',
  '�' => '啵',
  '�' => '啶',
  '�' => '啷',
  '�' => '唳',
  '�' => '唰',
  '�' => '啜',
  '�' => '喋',
  '�' => '嗒',
  '�' => '喃',
  '�' => '喱',
  '�' => '喹',
  '�' => '喈',
  '�' => '喁',
  '�' => '喟',
  '�' => '啾',
  '�' => '嗖',
  '�' => '喑',
  '�' => '啻',
  '�' => '嗟',
  '�' => '喽',
  '�' => '喾',
  '�' => '喔',
  '�' => '喙',
  '�' => '嗪',
  '�' => '嗷',
  '�' => '嗉',
  '�' => '嘟',
  '�' => '嗑',
  '�' => '嗫',
  '�' => '嗬',
  '�' => '嗔',
  '��' => '嗦',
  '��' => '嗝',
  '��' => '嗄',
  '��' => '嗯',
  '��' => '嗥',
  '��' => '嗲',
  '��' => '嗳',
  '��' => '嗌',
  '��' => '嗍',
  '��' => '嗨',
  '��' => '嗵',
  '��' => '嗤',
  '��' => '辔',
  '��' => '嘞',
  '��' => '嘈',
  '��' => '嘌',
  '��' => '嘁',
  '��' => '嘤',
  '��' => '嘣',
  '��' => '嗾',
  '��' => '嘀',
  '��' => '嘧',
  '��' => '嘭',
  '��' => '噘',
  '��' => '嘹',
  '��' => '噗',
  '��' => '嘬',
  '��' => '噍',
  '��' => '噢',
  '��' => '噙',
  '��' => '噜',
  '��' => '噌',
  '��' => '噔',
  '��' => '嚆',
  '��' => '噤',
  '��' => '噱',
  '��' => '噫',
  '��' => '噻',
  '��' => '噼',
  '��' => '嚅',
  '��' => '嚓',
  '��' => '嚯',
  '��' => '囔',
  '��' => '囗',
  '��' => '囝',
  '��' => '囡',
  '��' => '囵',
  '��' => '囫',
  '��' => '囹',
  '��' => '囿',
  '��' => '圄',
  '�' => '圊',
  '�' => '圉',
  '�' => '圜',
  '�' => '帏',
  '�' => '帙',
  '�' => '帔',
  '�' => '帑',
  '�' => '帱',
  '�' => '帻',
  '�' => '帼',
  '�@' => '酅',
  '�A' => '酇',
  '�B' => '酈',
  '�C' => '酑',
  '�D' => '酓',
  '�E' => '酔',
  '�F' => '酕',
  '�G' => '酖',
  '�H' => '酘',
  '�I' => '酙',
  '�J' => '酛',
  '�K' => '酜',
  '�L' => '酟',
  '�M' => '酠',
  '�N' => '酦',
  '�O' => '酧',
  '�P' => '酨',
  '�Q' => '酫',
  '�R' => '酭',
  '�S' => '酳',
  '�T' => '酺',
  '�U' => '酻',
  '�V' => '酼',
  '�W' => '醀',
  '�X' => '醁',
  '�Y' => '醂',
  '�Z' => '醃',
  '�[' => '醄',
  '�\\' => '醆',
  '�]' => '醈',
  '�^' => '醊',
  '�_' => '醎',
  '�`' => '醏',
  '�a' => '醓',
  '�b' => '醔',
  '�c' => '醕',
  '�d' => '醖',
  '�e' => '醗',
  '�f' => '醘',
  '�g' => '醙',
  '�h' => '醜',
  '�i' => '醝',
  '�j' => '醞',
  '�k' => '醟',
  '�l' => '醠',
  '�m' => '醡',
  '�n' => '醤',
  '�o' => '醥',
  '�p' => '醦',
  '�q' => '醧',
  '�r' => '醨',
  '�s' => '醩',
  '�t' => '醫',
  '�u' => '醬',
  '�v' => '醰',
  '�w' => '醱',
  '�x' => '醲',
  '�y' => '醳',
  '�z' => '醶',
  '�{' => '醷',
  '�|' => '醸',
  '�}' => '醹',
  '�~' => '醻',
  '�' => '醼',
  '�' => '醽',
  '�' => '醾',
  '�' => '醿',
  '�' => '釀',
  '�' => '釁',
  '�' => '釂',
  '�' => '釃',
  '�' => '釄',
  '�' => '釅',
  '�' => '釆',
  '�' => '釈',
  '�' => '釋',
  '�' => '釐',
  '�' => '釒',
  '�' => '釓',
  '�' => '釔',
  '�' => '釕',
  '�' => '釖',
  '�' => '釗',
  '�' => '釘',
  '�' => '釙',
  '�' => '釚',
  '�' => '釛',
  '�' => '針',
  '�' => '釞',
  '�' => '釟',
  '�' => '釠',
  '�' => '釡',
  '�' => '釢',
  '�' => '釣',
  '�' => '釤',
  '�' => '釥',
  '�' => '帷',
  '�' => '幄',
  '�' => '幔',
  '�' => '幛',
  '�' => '幞',
  '�' => '幡',
  '�' => '岌',
  '�' => '屺',
  '�' => '岍',
  '�' => '岐',
  '�' => '岖',
  '�' => '岈',
  '�' => '岘',
  '�' => '岙',
  '�' => '岑',
  '�' => '岚',
  '�' => '岜',
  '�' => '岵',
  '�' => '岢',
  '�' => '岽',
  '�' => '岬',
  '�' => '岫',
  '�' => '岱',
  '�' => '岣',
  '�' => '峁',
  '�' => '岷',
  '�' => '峄',
  '�' => '峒',
  '�' => '峤',
  '�' => '峋',
  '�' => '峥',
  '�' => '崂',
  '�' => '崃',
  '��' => '崧',
  '��' => '崦',
  '��' => '崮',
  '��' => '崤',
  '��' => '崞',
  '��' => '崆',
  '��' => '崛',
  '��' => '嵘',
  '��' => '崾',
  '��' => '崴',
  '��' => '崽',
  '��' => '嵬',
  '��' => '嵛',
  '��' => '嵯',
  '��' => '嵝',
  '��' => '嵫',
  '��' => '嵋',
  '��' => '嵊',
  '��' => '嵩',
  '��' => '嵴',
  '��' => '嶂',
  '��' => '嶙',
  '��' => '嶝',
  '��' => '豳',
  '��' => '嶷',
  '��' => '巅',
  '��' => '彳',
  '��' => '彷',
  '��' => '徂',
  '��' => '徇',
  '��' => '徉',
  '��' => '後',
  '��' => '徕',
  '��' => '徙',
  '��' => '徜',
  '��' => '徨',
  '��' => '徭',
  '��' => '徵',
  '��' => '徼',
  '��' => '衢',
  '��' => '彡',
  '��' => '犭',
  '��' => '犰',
  '��' => '犴',
  '��' => '犷',
  '��' => '犸',
  '��' => '狃',
  '��' => '狁',
  '��' => '狎',
  '��' => '狍',
  '��' => '狒',
  '�' => '狨',
  '�' => '狯',
  '�' => '狩',
  '�' => '狲',
  '�' => '狴',
  '�' => '狷',
  '�' => '猁',
  '�' => '狳',
  '�' => '猃',
  '�' => '狺',
  '�@' => '釦',
  '�A' => '釧',
  '�B' => '釨',
  '�C' => '釩',
  '�D' => '釪',
  '�E' => '釫',
  '�F' => '釬',
  '�G' => '釭',
  '�H' => '釮',
  '�I' => '釯',
  '�J' => '釰',
  '�K' => '釱',
  '�L' => '釲',
  '�M' => '釳',
  '�N' => '釴',
  '�O' => '釵',
  '�P' => '釶',
  '�Q' => '釷',
  '�R' => '釸',
  '�S' => '釹',
  '�T' => '釺',
  '�U' => '釻',
  '�V' => '釼',
  '�W' => '釽',
  '�X' => '釾',
  '�Y' => '釿',
  '�Z' => '鈀',
  '�[' => '鈁',
  '�\\' => '鈂',
  '�]' => '鈃',
  '�^' => '鈄',
  '�_' => '鈅',
  '�`' => '鈆',
  '�a' => '鈇',
  '�b' => '鈈',
  '�c' => '鈉',
  '�d' => '鈊',
  '�e' => '鈋',
  '�f' => '鈌',
  '�g' => '鈍',
  '�h' => '鈎',
  '�i' => '鈏',
  '�j' => '鈐',
  '�k' => '鈑',
  '�l' => '鈒',
  '�m' => '鈓',
  '�n' => '鈔',
  '�o' => '鈕',
  '�p' => '鈖',
  '�q' => '鈗',
  '�r' => '鈘',
  '�s' => '鈙',
  '�t' => '鈚',
  '�u' => '鈛',
  '�v' => '鈜',
  '�w' => '鈝',
  '�x' => '鈞',
  '�y' => '鈟',
  '�z' => '鈠',
  '�{' => '鈡',
  '�|' => '鈢',
  '�}' => '鈣',
  '�~' => '鈤',
  '�' => '鈥',
  '�' => '鈦',
  '�' => '鈧',
  '�' => '鈨',
  '�' => '鈩',
  '�' => '鈪',
  '�' => '鈫',
  '�' => '鈬',
  '�' => '鈭',
  '�' => '鈮',
  '�' => '鈯',
  '�' => '鈰',
  '�' => '鈱',
  '�' => '鈲',
  '�' => '鈳',
  '�' => '鈴',
  '�' => '鈵',
  '�' => '鈶',
  '�' => '鈷',
  '�' => '鈸',
  '�' => '鈹',
  '�' => '鈺',
  '�' => '鈻',
  '�' => '鈼',
  '�' => '鈽',
  '�' => '鈾',
  '�' => '鈿',
  '�' => '鉀',
  '�' => '鉁',
  '�' => '鉂',
  '�' => '鉃',
  '�' => '鉄',
  '�' => '鉅',
  '�' => '狻',
  '�' => '猗',
  '�' => '猓',
  '�' => '猡',
  '�' => '猊',
  '�' => '猞',
  '�' => '猝',
  '�' => '猕',
  '�' => '猢',
  '�' => '猹',
  '�' => '猥',
  '�' => '猬',
  '�' => '猸',
  '�' => '猱',
  '�' => '獐',
  '�' => '獍',
  '�' => '獗',
  '�' => '獠',
  '�' => '獬',
  '�' => '獯',
  '�' => '獾',
  '�' => '舛',
  '�' => '夥',
  '�' => '飧',
  '�' => '夤',
  '�' => '夂',
  '�' => '饣',
  '�' => '饧',
  '�' => '饨',
  '�' => '饩',
  '�' => '饪',
  '�' => '饫',
  '�' => '饬',
  '��' => '饴',
  '��' => '饷',
  '��' => '饽',
  '��' => '馀',
  '��' => '馄',
  '��' => '馇',
  '��' => '馊',
  '��' => '馍',
  '��' => '馐',
  '��' => '馑',
  '��' => '馓',
  '��' => '馔',
  '��' => '馕',
  '��' => '庀',
  '��' => '庑',
  '��' => '庋',
  '��' => '庖',
  '��' => '庥',
  '��' => '庠',
  '��' => '庹',
  '��' => '庵',
  '��' => '庾',
  '��' => '庳',
  '��' => '赓',
  '��' => '廒',
  '��' => '廑',
  '��' => '廛',
  '��' => '廨',
  '��' => '廪',
  '��' => '膺',
  '��' => '忄',
  '��' => '忉',
  '��' => '忖',
  '��' => '忏',
  '��' => '怃',
  '��' => '忮',
  '��' => '怄',
  '��' => '忡',
  '��' => '忤',
  '��' => '忾',
  '��' => '怅',
  '��' => '怆',
  '��' => '忪',
  '��' => '忭',
  '��' => '忸',
  '��' => '怙',
  '��' => '怵',
  '��' => '怦',
  '��' => '怛',
  '��' => '怏',
  '��' => '怍',
  '�' => '怩',
  '�' => '怫',
  '�' => '怊',
  '�' => '怿',
  '�' => '怡',
  '�' => '恸',
  '�' => '恹',
  '�' => '恻',
  '�' => '恺',
  '�' => '恂',
  '�@' => '鉆',
  '�A' => '鉇',
  '�B' => '鉈',
  '�C' => '鉉',
  '�D' => '鉊',
  '�E' => '鉋',
  '�F' => '鉌',
  '�G' => '鉍',
  '�H' => '鉎',
  '�I' => '鉏',
  '�J' => '鉐',
  '�K' => '鉑',
  '�L' => '鉒',
  '�M' => '鉓',
  '�N' => '鉔',
  '�O' => '鉕',
  '�P' => '鉖',
  '�Q' => '鉗',
  '�R' => '鉘',
  '�S' => '鉙',
  '�T' => '鉚',
  '�U' => '鉛',
  '�V' => '鉜',
  '�W' => '鉝',
  '�X' => '鉞',
  '�Y' => '鉟',
  '�Z' => '鉠',
  '�[' => '鉡',
  '�\\' => '鉢',
  '�]' => '鉣',
  '�^' => '鉤',
  '�_' => '鉥',
  '�`' => '鉦',
  '�a' => '鉧',
  '�b' => '鉨',
  '�c' => '鉩',
  '�d' => '鉪',
  '�e' => '鉫',
  '�f' => '鉬',
  '�g' => '鉭',
  '�h' => '鉮',
  '�i' => '鉯',
  '�j' => '鉰',
  '�k' => '鉱',
  '�l' => '鉲',
  '�m' => '鉳',
  '�n' => '鉵',
  '�o' => '鉶',
  '�p' => '鉷',
  '�q' => '鉸',
  '�r' => '鉹',
  '�s' => '鉺',
  '�t' => '鉻',
  '�u' => '鉼',
  '�v' => '鉽',
  '�w' => '鉾',
  '�x' => '鉿',
  '�y' => '銀',
  '�z' => '銁',
  '�{' => '銂',
  '�|' => '銃',
  '�}' => '銄',
  '�~' => '銅',
  '�' => '銆',
  '�' => '銇',
  '�' => '銈',
  '�' => '銉',
  '�' => '銊',
  '�' => '銋',
  '�' => '銌',
  '�' => '銍',
  '�' => '銏',
  '�' => '銐',
  '�' => '銑',
  '�' => '銒',
  '�' => '銓',
  '�' => '銔',
  '�' => '銕',
  '�' => '銖',
  '�' => '銗',
  '�' => '銘',
  '�' => '銙',
  '�' => '銚',
  '�' => '銛',
  '�' => '銜',
  '�' => '銝',
  '�' => '銞',
  '�' => '銟',
  '�' => '銠',
  '�' => '銡',
  '�' => '銢',
  '�' => '銣',
  '�' => '銤',
  '�' => '銥',
  '�' => '銦',
  '�' => '銧',
  '�' => '恪',
  '�' => '恽',
  '�' => '悖',
  '�' => '悚',
  '�' => '悭',
  '�' => '悝',
  '�' => '悃',
  '�' => '悒',
  '�' => '悌',
  '�' => '悛',
  '�' => '惬',
  '�' => '悻',
  '�' => '悱',
  '�' => '惝',
  '�' => '惘',
  '�' => '惆',
  '�' => '惚',
  '�' => '悴',
  '�' => '愠',
  '�' => '愦',
  '�' => '愕',
  '�' => '愣',
  '�' => '惴',
  '�' => '愀',
  '�' => '愎',
  '�' => '愫',
  '�' => '慊',
  '�' => '慵',
  '�' => '憬',
  '�' => '憔',
  '�' => '憧',
  '�' => '憷',
  '�' => '懔',
  '��' => '懵',
  '��' => '忝',
  '��' => '隳',
  '��' => '闩',
  '��' => '闫',
  '��' => '闱',
  '��' => '闳',
  '��' => '闵',
  '��' => '闶',
  '��' => '闼',
  '��' => '闾',
  '��' => '阃',
  '��' => '阄',
  '��' => '阆',
  '��' => '阈',
  '��' => '阊',
  '��' => '阋',
  '��' => '阌',
  '��' => '阍',
  '��' => '阏',
  '��' => '阒',
  '��' => '阕',
  '��' => '阖',
  '��' => '阗',
  '��' => '阙',
  '��' => '阚',
  '��' => '丬',
  '��' => '爿',
  '��' => '戕',
  '��' => '氵',
  '��' => '汔',
  '��' => '汜',
  '��' => '汊',
  '��' => '沣',
  '��' => '沅',
  '��' => '沐',
  '��' => '沔',
  '��' => '沌',
  '��' => '汨',
  '��' => '汩',
  '��' => '汴',
  '��' => '汶',
  '��' => '沆',
  '��' => '沩',
  '��' => '泐',
  '��' => '泔',
  '��' => '沭',
  '��' => '泷',
  '��' => '泸',
  '��' => '泱',
  '��' => '泗',
  '�' => '沲',
  '�' => '泠',
  '�' => '泖',
  '�' => '泺',
  '�' => '泫',
  '�' => '泮',
  '�' => '沱',
  '�' => '泓',
  '�' => '泯',
  '�' => '泾',
  '�@' => '銨',
  '�A' => '銩',
  '�B' => '銪',
  '�C' => '銫',
  '�D' => '銬',
  '�E' => '銭',
  '�F' => '銯',
  '�G' => '銰',
  '�H' => '銱',
  '�I' => '銲',
  '�J' => '銳',
  '�K' => '銴',
  '�L' => '銵',
  '�M' => '銶',
  '�N' => '銷',
  '�O' => '銸',
  '�P' => '銹',
  '�Q' => '銺',
  '�R' => '銻',
  '�S' => '銼',
  '�T' => '銽',
  '�U' => '銾',
  '�V' => '銿',
  '�W' => '鋀',
  '�X' => '鋁',
  '�Y' => '鋂',
  '�Z' => '鋃',
  '�[' => '鋄',
  '�\\' => '鋅',
  '�]' => '鋆',
  '�^' => '鋇',
  '�_' => '鋉',
  '�`' => '鋊',
  '�a' => '鋋',
  '�b' => '鋌',
  '�c' => '鋍',
  '�d' => '鋎',
  '�e' => '鋏',
  '�f' => '鋐',
  '�g' => '鋑',
  '�h' => '鋒',
  '�i' => '鋓',
  '�j' => '鋔',
  '�k' => '鋕',
  '�l' => '鋖',
  '�m' => '鋗',
  '�n' => '鋘',
  '�o' => '鋙',
  '�p' => '鋚',
  '�q' => '鋛',
  '�r' => '鋜',
  '�s' => '鋝',
  '�t' => '鋞',
  '�u' => '鋟',
  '�v' => '鋠',
  '�w' => '鋡',
  '�x' => '鋢',
  '�y' => '鋣',
  '�z' => '鋤',
  '�{' => '鋥',
  '�|' => '鋦',
  '�}' => '鋧',
  '�~' => '鋨',
  '�' => '鋩',
  '�' => '鋪',
  '�' => '鋫',
  '�' => '鋬',
  '�' => '鋭',
  '�' => '鋮',
  '�' => '鋯',
  '�' => '鋰',
  '�' => '鋱',
  '�' => '鋲',
  '�' => '鋳',
  '�' => '鋴',
  '�' => '鋵',
  '�' => '鋶',
  '�' => '鋷',
  '�' => '鋸',
  '�' => '鋹',
  '�' => '鋺',
  '�' => '鋻',
  '�' => '鋼',
  '�' => '鋽',
  '�' => '鋾',
  '�' => '鋿',
  '�' => '錀',
  '�' => '錁',
  '�' => '錂',
  '�' => '錃',
  '�' => '錄',
  '�' => '錅',
  '�' => '錆',
  '�' => '錇',
  '�' => '錈',
  '�' => '錉',
  '�' => '洹',
  '�' => '洧',
  '�' => '洌',
  '�' => '浃',
  '�' => '浈',
  '�' => '洇',
  '�' => '洄',
  '�' => '洙',
  '�' => '洎',
  '�' => '洫',
  '�' => '浍',
  '�' => '洮',
  '�' => '洵',
  '�' => '洚',
  '�' => '浏',
  '�' => '浒',
  '�' => '浔',
  '�' => '洳',
  '�' => '涑',
  '�' => '浯',
  '�' => '涞',
  '�' => '涠',
  '�' => '浞',
  '�' => '涓',
  '�' => '涔',
  '�' => '浜',
  '�' => '浠',
  '�' => '浼',
  '�' => '浣',
  '�' => '渚',
  '�' => '淇',
  '�' => '淅',
  '�' => '淞',
  '��' => '渎',
  '��' => '涿',
  '��' => '淠',
  '��' => '渑',
  '��' => '淦',
  '��' => '淝',
  '��' => '淙',
  '��' => '渖',
  '��' => '涫',
  '��' => '渌',
  '��' => '涮',
  '��' => '渫',
  '��' => '湮',
  '��' => '湎',
  '��' => '湫',
  '��' => '溲',
  '��' => '湟',
  '��' => '溆',
  '��' => '湓',
  '��' => '湔',
  '��' => '渲',
  '��' => '渥',
  '��' => '湄',
  '��' => '滟',
  '��' => '溱',
  '��' => '溘',
  '��' => '滠',
  '��' => '漭',
  '��' => '滢',
  '��' => '溥',
  '��' => '溧',
  '��' => '溽',
  '��' => '溻',
  '��' => '溷',
  '��' => '滗',
  '��' => '溴',
  '��' => '滏',
  '��' => '溏',
  '��' => '滂',
  '��' => '溟',
  '��' => '潢',
  '��' => '潆',
  '��' => '潇',
  '��' => '漤',
  '��' => '漕',
  '��' => '滹',
  '��' => '漯',
  '��' => '漶',
  '��' => '潋',
  '��' => '潴',
  '��' => '漪',
  '�' => '漉',
  '�' => '漩',
  '�' => '澉',
  '�' => '澍',
  '�' => '澌',
  '�' => '潸',
  '�' => '潲',
  '�' => '潼',
  '�' => '潺',
  '�' => '濑',
  '�@' => '錊',
  '�A' => '錋',
  '�B' => '錌',
  '�C' => '錍',
  '�D' => '錎',
  '�E' => '錏',
  '�F' => '錐',
  '�G' => '錑',
  '�H' => '錒',
  '�I' => '錓',
  '�J' => '錔',
  '�K' => '錕',
  '�L' => '錖',
  '�M' => '錗',
  '�N' => '錘',
  '�O' => '錙',
  '�P' => '錚',
  '�Q' => '錛',
  '�R' => '錜',
  '�S' => '錝',
  '�T' => '錞',
  '�U' => '錟',
  '�V' => '錠',
  '�W' => '錡',
  '�X' => '錢',
  '�Y' => '錣',
  '�Z' => '錤',
  '�[' => '錥',
  '�\\' => '錦',
  '�]' => '錧',
  '�^' => '錨',
  '�_' => '錩',
  '�`' => '錪',
  '�a' => '錫',
  '�b' => '錬',
  '�c' => '錭',
  '�d' => '錮',
  '�e' => '錯',
  '�f' => '錰',
  '�g' => '錱',
  '�h' => '録',
  '�i' => '錳',
  '�j' => '錴',
  '�k' => '錵',
  '�l' => '錶',
  '�m' => '錷',
  '�n' => '錸',
  '�o' => '錹',
  '�p' => '錺',
  '�q' => '錻',
  '�r' => '錼',
  '�s' => '錽',
  '�t' => '錿',
  '�u' => '鍀',
  '�v' => '鍁',
  '�w' => '鍂',
  '�x' => '鍃',
  '�y' => '鍄',
  '�z' => '鍅',
  '�{' => '鍆',
  '�|' => '鍇',
  '�}' => '鍈',
  '�~' => '鍉',
  '�' => '鍊',
  '�' => '鍋',
  '�' => '鍌',
  '�' => '鍍',
  '�' => '鍎',
  '�' => '鍏',
  '�' => '鍐',
  '�' => '鍑',
  '�' => '鍒',
  '�' => '鍓',
  '�' => '鍔',
  '�' => '鍕',
  '�' => '鍖',
  '�' => '鍗',
  '�' => '鍘',
  '�' => '鍙',
  '�' => '鍚',
  '�' => '鍛',
  '�' => '鍜',
  '�' => '鍝',
  '�' => '鍞',
  '�' => '鍟',
  '�' => '鍠',
  '�' => '鍡',
  '�' => '鍢',
  '�' => '鍣',
  '�' => '鍤',
  '�' => '鍥',
  '�' => '鍦',
  '�' => '鍧',
  '�' => '鍨',
  '�' => '鍩',
  '�' => '鍫',
  '�' => '濉',
  '�' => '澧',
  '�' => '澹',
  '�' => '澶',
  '�' => '濂',
  '�' => '濡',
  '�' => '濮',
  '�' => '濞',
  '�' => '濠',
  '�' => '濯',
  '�' => '瀚',
  '�' => '瀣',
  '�' => '瀛',
  '�' => '瀹',
  '�' => '瀵',
  '�' => '灏',
  '�' => '灞',
  '�' => '宀',
  '�' => '宄',
  '�' => '宕',
  '�' => '宓',
  '�' => '宥',
  '�' => '宸',
  '�' => '甯',
  '�' => '骞',
  '�' => '搴',
  '�' => '寤',
  '�' => '寮',
  '�' => '褰',
  '�' => '寰',
  '�' => '蹇',
  '�' => '謇',
  '�' => '辶',
  '��' => '迓',
  '��' => '迕',
  '��' => '迥',
  '��' => '迮',
  '��' => '迤',
  '��' => '迩',
  '��' => '迦',
  '��' => '迳',
  '��' => '迨',
  '��' => '逅',
  '��' => '逄',
  '��' => '逋',
  '��' => '逦',
  '��' => '逑',
  '��' => '逍',
  '��' => '逖',
  '��' => '逡',
  '��' => '逵',
  '��' => '逶',
  '��' => '逭',
  '��' => '逯',
  '��' => '遄',
  '��' => '遑',
  '��' => '遒',
  '��' => '遐',
  '��' => '遨',
  '��' => '遘',
  '��' => '遢',
  '��' => '遛',
  '��' => '暹',
  '��' => '遴',
  '��' => '遽',
  '��' => '邂',
  '��' => '邈',
  '��' => '邃',
  '��' => '邋',
  '��' => '彐',
  '��' => '彗',
  '��' => '彖',
  '��' => '彘',
  '��' => '尻',
  '��' => '咫',
  '��' => '屐',
  '��' => '屙',
  '��' => '孱',
  '��' => '屣',
  '��' => '屦',
  '��' => '羼',
  '��' => '弪',
  '��' => '弩',
  '��' => '弭',
  '�' => '艴',
  '�' => '弼',
  '�' => '鬻',
  '�' => '屮',
  '�' => '妁',
  '�' => '妃',
  '�' => '妍',
  '�' => '妩',
  '�' => '妪',
  '�' => '妣',
  '�@' => '鍬',
  '�A' => '鍭',
  '�B' => '鍮',
  '�C' => '鍯',
  '�D' => '鍰',
  '�E' => '鍱',
  '�F' => '鍲',
  '�G' => '鍳',
  '�H' => '鍴',
  '�I' => '鍵',
  '�J' => '鍶',
  '�K' => '鍷',
  '�L' => '鍸',
  '�M' => '鍹',
  '�N' => '鍺',
  '�O' => '鍻',
  '�P' => '鍼',
  '�Q' => '鍽',
  '�R' => '鍾',
  '�S' => '鍿',
  '�T' => '鎀',
  '�U' => '鎁',
  '�V' => '鎂',
  '�W' => '鎃',
  '�X' => '鎄',
  '�Y' => '鎅',
  '�Z' => '鎆',
  '�[' => '鎇',
  '�\\' => '鎈',
  '�]' => '鎉',
  '�^' => '鎊',
  '�_' => '鎋',
  '�`' => '鎌',
  '�a' => '鎍',
  '�b' => '鎎',
  '�c' => '鎐',
  '�d' => '鎑',
  '�e' => '鎒',
  '�f' => '鎓',
  '�g' => '鎔',
  '�h' => '鎕',
  '�i' => '鎖',
  '�j' => '鎗',
  '�k' => '鎘',
  '�l' => '鎙',
  '�m' => '鎚',
  '�n' => '鎛',
  '�o' => '鎜',
  '�p' => '鎝',
  '�q' => '鎞',
  '�r' => '鎟',
  '�s' => '鎠',
  '�t' => '鎡',
  '�u' => '鎢',
  '�v' => '鎣',
  '�w' => '鎤',
  '�x' => '鎥',
  '�y' => '鎦',
  '�z' => '鎧',
  '�{' => '鎨',
  '�|' => '鎩',
  '�}' => '鎪',
  '�~' => '鎫',
  '�' => '鎬',
  '�' => '鎭',
  '�' => '鎮',
  '�' => '鎯',
  '�' => '鎰',
  '�' => '鎱',
  '�' => '鎲',
  '�' => '鎳',
  '�' => '鎴',
  '�' => '鎵',
  '�' => '鎶',
  '�' => '鎷',
  '�' => '鎸',
  '�' => '鎹',
  '�' => '鎺',
  '�' => '鎻',
  '�' => '鎼',
  '�' => '鎽',
  '�' => '鎾',
  '�' => '鎿',
  '�' => '鏀',
  '�' => '鏁',
  '�' => '鏂',
  '�' => '鏃',
  '�' => '鏄',
  '�' => '鏅',
  '�' => '鏆',
  '�' => '鏇',
  '�' => '鏈',
  '�' => '鏉',
  '�' => '鏋',
  '�' => '鏌',
  '�' => '鏍',
  '�' => '妗',
  '�' => '姊',
  '�' => '妫',
  '�' => '妞',
  '�' => '妤',
  '�' => '姒',
  '�' => '妲',
  '�' => '妯',
  '�' => '姗',
  '�' => '妾',
  '�' => '娅',
  '�' => '娆',
  '�' => '姝',
  '�' => '娈',
  '�' => '姣',
  '�' => '姘',
  '�' => '姹',
  '�' => '娌',
  '�' => '娉',
  '�' => '娲',
  '�' => '娴',
  '�' => '娑',
  '�' => '娣',
  '�' => '娓',
  '�' => '婀',
  '�' => '婧',
  '�' => '婊',
  '�' => '婕',
  '�' => '娼',
  '�' => '婢',
  '�' => '婵',
  '�' => '胬',
  '�' => '媪',
  '��' => '媛',
  '��' => '婷',
  '��' => '婺',
  '��' => '媾',
  '��' => '嫫',
  '��' => '媲',
  '��' => '嫒',
  '��' => '嫔',
  '��' => '媸',
  '��' => '嫠',
  '��' => '嫣',
  '��' => '嫱',
  '��' => '嫖',
  '��' => '嫦',
  '��' => '嫘',
  '��' => '嫜',
  '��' => '嬉',
  '��' => '嬗',
  '��' => '嬖',
  '��' => '嬲',
  '��' => '嬷',
  '��' => '孀',
  '��' => '尕',
  '��' => '尜',
  '��' => '孚',
  '��' => '孥',
  '��' => '孳',
  '��' => '孑',
  '��' => '孓',
  '��' => '孢',
  '��' => '驵',
  '��' => '驷',
  '��' => '驸',
  '��' => '驺',
  '��' => '驿',
  '��' => '驽',
  '��' => '骀',
  '��' => '骁',
  '��' => '骅',
  '��' => '骈',
  '��' => '骊',
  '��' => '骐',
  '��' => '骒',
  '��' => '骓',
  '��' => '骖',
  '��' => '骘',
  '��' => '骛',
  '��' => '骜',
  '��' => '骝',
  '��' => '骟',
  '��' => '骠',
  '�' => '骢',
  '�' => '骣',
  '�' => '骥',
  '�' => '骧',
  '�' => '纟',
  '�' => '纡',
  '�' => '纣',
  '�' => '纥',
  '�' => '纨',
  '�' => '纩',
  '�@' => '鏎',
  '�A' => '鏏',
  '�B' => '鏐',
  '�C' => '鏑',
  '�D' => '鏒',
  '�E' => '鏓',
  '�F' => '鏔',
  '�G' => '鏕',
  '�H' => '鏗',
  '�I' => '鏘',
  '�J' => '鏙',
  '�K' => '鏚',
  '�L' => '鏛',
  '�M' => '鏜',
  '�N' => '鏝',
  '�O' => '鏞',
  '�P' => '鏟',
  '�Q' => '鏠',
  '�R' => '鏡',
  '�S' => '鏢',
  '�T' => '鏣',
  '�U' => '鏤',
  '�V' => '鏥',
  '�W' => '鏦',
  '�X' => '鏧',
  '�Y' => '鏨',
  '�Z' => '鏩',
  '�[' => '鏪',
  '�\\' => '鏫',
  '�]' => '鏬',
  '�^' => '鏭',
  '�_' => '鏮',
  '�`' => '鏯',
  '�a' => '鏰',
  '�b' => '鏱',
  '�c' => '鏲',
  '�d' => '鏳',
  '�e' => '鏴',
  '�f' => '鏵',
  '�g' => '鏶',
  '�h' => '鏷',
  '�i' => '鏸',
  '�j' => '鏹',
  '�k' => '鏺',
  '�l' => '鏻',
  '�m' => '鏼',
  '�n' => '鏽',
  '�o' => '鏾',
  '�p' => '鏿',
  '�q' => '鐀',
  '�r' => '鐁',
  '�s' => '鐂',
  '�t' => '鐃',
  '�u' => '鐄',
  '�v' => '鐅',
  '�w' => '鐆',
  '�x' => '鐇',
  '�y' => '鐈',
  '�z' => '鐉',
  '�{' => '鐊',
  '�|' => '鐋',
  '�}' => '鐌',
  '�~' => '鐍',
  '�' => '鐎',
  '�' => '鐏',
  '�' => '鐐',
  '�' => '鐑',
  '�' => '鐒',
  '�' => '鐓',
  '�' => '鐔',
  '�' => '鐕',
  '�' => '鐖',
  '�' => '鐗',
  '�' => '鐘',
  '�' => '鐙',
  '�' => '鐚',
  '�' => '鐛',
  '�' => '鐜',
  '�' => '鐝',
  '�' => '鐞',
  '�' => '鐟',
  '�' => '鐠',
  '�' => '鐡',
  '�' => '鐢',
  '�' => '鐣',
  '�' => '鐤',
  '�' => '鐥',
  '�' => '鐦',
  '�' => '鐧',
  '�' => '鐨',
  '�' => '鐩',
  '�' => '鐪',
  '�' => '鐫',
  '�' => '鐬',
  '�' => '鐭',
  '�' => '鐮',
  '�' => '纭',
  '�' => '纰',
  '�' => '纾',
  '�' => '绀',
  '�' => '绁',
  '�' => '绂',
  '�' => '绉',
  '�' => '绋',
  '�' => '绌',
  '�' => '绐',
  '�' => '绔',
  '�' => '绗',
  '�' => '绛',
  '�' => '绠',
  '�' => '绡',
  '�' => '绨',
  '�' => '绫',
  '�' => '绮',
  '�' => '绯',
  '�' => '绱',
  '�' => '绲',
  '�' => '缍',
  '�' => '绶',
  '�' => '绺',
  '�' => '绻',
  '�' => '绾',
  '�' => '缁',
  '�' => '缂',
  '�' => '缃',
  '�' => '缇',
  '�' => '缈',
  '�' => '缋',
  '�' => '缌',
  '��' => '缏',
  '��' => '缑',
  '��' => '缒',
  '��' => '缗',
  '��' => '缙',
  '��' => '缜',
  '��' => '缛',
  '��' => '缟',
  '��' => '缡',
  '��' => '缢',
  '��' => '缣',
  '��' => '缤',
  '��' => '缥',
  '��' => '缦',
  '��' => '缧',
  '��' => '缪',
  '��' => '缫',
  '��' => '缬',
  '��' => '缭',
  '��' => '缯',
  '��' => '缰',
  '��' => '缱',
  '��' => '缲',
  '��' => '缳',
  '��' => '缵',
  '��' => '幺',
  '��' => '畿',
  '��' => '巛',
  '��' => '甾',
  '��' => '邕',
  '��' => '玎',
  '��' => '玑',
  '��' => '玮',
  '��' => '玢',
  '��' => '玟',
  '��' => '珏',
  '��' => '珂',
  '��' => '珑',
  '��' => '玷',
  '��' => '玳',
  '��' => '珀',
  '��' => '珉',
  '��' => '珈',
  '��' => '珥',
  '��' => '珙',
  '��' => '顼',
  '��' => '琊',
  '��' => '珩',
  '��' => '珧',
  '��' => '珞',
  '��' => '玺',
  '�' => '珲',
  '�' => '琏',
  '�' => '琪',
  '�' => '瑛',
  '�' => '琦',
  '�' => '琥',
  '�' => '琨',
  '�' => '琰',
  '�' => '琮',
  '�' => '琬',
  '�@' => '鐯',
  '�A' => '鐰',
  '�B' => '鐱',
  '�C' => '鐲',
  '�D' => '鐳',
  '�E' => '鐴',
  '�F' => '鐵',
  '�G' => '鐶',
  '�H' => '鐷',
  '�I' => '鐸',
  '�J' => '鐹',
  '�K' => '鐺',
  '�L' => '鐻',
  '�M' => '鐼',
  '�N' => '鐽',
  '�O' => '鐿',
  '�P' => '鑀',
  '�Q' => '鑁',
  '�R' => '鑂',
  '�S' => '鑃',
  '�T' => '鑄',
  '�U' => '鑅',
  '�V' => '鑆',
  '�W' => '鑇',
  '�X' => '鑈',
  '�Y' => '鑉',
  '�Z' => '鑊',
  '�[' => '鑋',
  '�\\' => '鑌',
  '�]' => '鑍',
  '�^' => '鑎',
  '�_' => '鑏',
  '�`' => '鑐',
  '�a' => '鑑',
  '�b' => '鑒',
  '�c' => '鑓',
  '�d' => '鑔',
  '�e' => '鑕',
  '�f' => '鑖',
  '�g' => '鑗',
  '�h' => '鑘',
  '�i' => '鑙',
  '�j' => '鑚',
  '�k' => '鑛',
  '�l' => '鑜',
  '�m' => '鑝',
  '�n' => '鑞',
  '�o' => '鑟',
  '�p' => '鑠',
  '�q' => '鑡',
  '�r' => '鑢',
  '�s' => '鑣',
  '�t' => '鑤',
  '�u' => '鑥',
  '�v' => '鑦',
  '�w' => '鑧',
  '�x' => '鑨',
  '�y' => '鑩',
  '�z' => '鑪',
  '�{' => '鑬',
  '�|' => '鑭',
  '�}' => '鑮',
  '�~' => '鑯',
  '�' => '鑰',
  '�' => '鑱',
  '�' => '鑲',
  '�' => '鑳',
  '�' => '鑴',
  '�' => '鑵',
  '�' => '鑶',
  '�' => '鑷',
  '�' => '鑸',
  '�' => '鑹',
  '�' => '鑺',
  '�' => '鑻',
  '�' => '鑼',
  '�' => '鑽',
  '�' => '鑾',
  '�' => '鑿',
  '�' => '钀',
  '�' => '钁',
  '�' => '钂',
  '�' => '钃',
  '�' => '钄',
  '�' => '钑',
  '�' => '钖',
  '�' => '钘',
  '�' => '铇',
  '�' => '铏',
  '�' => '铓',
  '�' => '铔',
  '�' => '铚',
  '�' => '铦',
  '�' => '铻',
  '�' => '锜',
  '�' => '锠',
  '�' => '琛',
  '�' => '琚',
  '�' => '瑁',
  '�' => '瑜',
  '�' => '瑗',
  '�' => '瑕',
  '�' => '瑙',
  '�' => '瑷',
  '�' => '瑭',
  '�' => '瑾',
  '�' => '璜',
  '�' => '璎',
  '�' => '璀',
  '�' => '璁',
  '�' => '璇',
  '�' => '璋',
  '�' => '璞',
  '�' => '璨',
  '�' => '璩',
  '�' => '璐',
  '�' => '璧',
  '�' => '瓒',
  '�' => '璺',
  '�' => '韪',
  '�' => '韫',
  '�' => '韬',
  '�' => '杌',
  '�' => '杓',
  '�' => '杞',
  '�' => '杈',
  '�' => '杩',
  '�' => '枥',
  '�' => '枇',
  '��' => '杪',
  '��' => '杳',
  '��' => '枘',
  '��' => '枧',
  '��' => '杵',
  '��' => '枨',
  '��' => '枞',
  '��' => '枭',
  '��' => '枋',
  '��' => '杷',
  '��' => '杼',
  '��' => '柰',
  '��' => '栉',
  '��' => '柘',
  '��' => '栊',
  '��' => '柩',
  '��' => '枰',
  '��' => '栌',
  '��' => '柙',
  '��' => '枵',
  '��' => '柚',
  '��' => '枳',
  '��' => '柝',
  '��' => '栀',
  '��' => '柃',
  '��' => '枸',
  '��' => '柢',
  '��' => '栎',
  '��' => '柁',
  '��' => '柽',
  '��' => '栲',
  '��' => '栳',
  '��' => '桠',
  '��' => '桡',
  '��' => '桎',
  '��' => '桢',
  '��' => '桄',
  '��' => '桤',
  '��' => '梃',
  '��' => '栝',
  '��' => '桕',
  '��' => '桦',
  '��' => '桁',
  '��' => '桧',
  '��' => '桀',
  '��' => '栾',
  '��' => '桊',
  '��' => '桉',
  '��' => '栩',
  '��' => '梵',
  '��' => '梏',
  '�' => '桴',
  '�' => '桷',
  '�' => '梓',
  '�' => '桫',
  '�' => '棂',
  '�' => '楮',
  '�' => '棼',
  '�' => '椟',
  '�' => '椠',
  '�' => '棹',
  '�@' => '锧',
  '�A' => '锳',
  '�B' => '锽',
  '�C' => '镃',
  '�D' => '镈',
  '�E' => '镋',
  '�F' => '镕',
  '�G' => '镚',
  '�H' => '镠',
  '�I' => '镮',
  '�J' => '镴',
  '�K' => '镵',
  '�L' => '長',
  '�M' => '镸',
  '�N' => '镹',
  '�O' => '镺',
  '�P' => '镻',
  '�Q' => '镼',
  '�R' => '镽',
  '�S' => '镾',
  '�T' => '門',
  '�U' => '閁',
  '�V' => '閂',
  '�W' => '閃',
  '�X' => '閄',
  '�Y' => '閅',
  '�Z' => '閆',
  '�[' => '閇',
  '�\\' => '閈',
  '�]' => '閉',
  '�^' => '閊',
  '�_' => '開',
  '�`' => '閌',
  '�a' => '閍',
  '�b' => '閎',
  '�c' => '閏',
  '�d' => '閐',
  '�e' => '閑',
  '�f' => '閒',
  '�g' => '間',
  '�h' => '閔',
  '�i' => '閕',
  '�j' => '閖',
  '�k' => '閗',
  '�l' => '閘',
  '�m' => '閙',
  '�n' => '閚',
  '�o' => '閛',
  '�p' => '閜',
  '�q' => '閝',
  '�r' => '閞',
  '�s' => '閟',
  '�t' => '閠',
  '�u' => '閡',
  '�v' => '関',
  '�w' => '閣',
  '�x' => '閤',
  '�y' => '閥',
  '�z' => '閦',
  '�{' => '閧',
  '�|' => '閨',
  '�}' => '閩',
  '�~' => '閪',
  '�' => '閫',
  '�' => '閬',
  '�' => '閭',
  '�' => '閮',
  '�' => '閯',
  '�' => '閰',
  '�' => '閱',
  '�' => '閲',
  '�' => '閳',
  '�' => '閴',
  '�' => '閵',
  '�' => '閶',
  '�' => '閷',
  '�' => '閸',
  '�' => '閹',
  '�' => '閺',
  '�' => '閻',
  '�' => '閼',
  '�' => '閽',
  '�' => '閾',
  '�' => '閿',
  '�' => '闀',
  '�' => '闁',
  '�' => '闂',
  '�' => '闃',
  '�' => '闄',
  '�' => '闅',
  '�' => '闆',
  '�' => '闇',
  '�' => '闈',
  '�' => '闉',
  '�' => '闊',
  '�' => '闋',
  '�' => '椤',
  '�' => '棰',
  '�' => '椋',
  '�' => '椁',
  '�' => '楗',
  '�' => '棣',
  '�' => '椐',
  '�' => '楱',
  '�' => '椹',
  '�' => '楠',
  '�' => '楂',
  '�' => '楝',
  '�' => '榄',
  '�' => '楫',
  '�' => '榀',
  '�' => '榘',
  '�' => '楸',
  '�' => '椴',
  '�' => '槌',
  '�' => '榇',
  '�' => '榈',
  '�' => '槎',
  '�' => '榉',
  '�' => '楦',
  '�' => '楣',
  '�' => '楹',
  '�' => '榛',
  '�' => '榧',
  '�' => '榻',
  '�' => '榫',
  '�' => '榭',
  '�' => '槔',
  '�' => '榱',
  '��' => '槁',
  '��' => '槊',
  '��' => '槟',
  '��' => '榕',
  '��' => '槠',
  '��' => '榍',
  '��' => '槿',
  '��' => '樯',
  '��' => '槭',
  '��' => '樗',
  '��' => '樘',
  '��' => '橥',
  '��' => '槲',
  '��' => '橄',
  '��' => '樾',
  '��' => '檠',
  '��' => '橐',
  '��' => '橛',
  '��' => '樵',
  '��' => '檎',
  '��' => '橹',
  '��' => '樽',
  '��' => '樨',
  '��' => '橘',
  '��' => '橼',
  '��' => '檑',
  '��' => '檐',
  '��' => '檩',
  '��' => '檗',
  '��' => '檫',
  '��' => '猷',
  '��' => '獒',
  '��' => '殁',
  '��' => '殂',
  '��' => '殇',
  '��' => '殄',
  '��' => '殒',
  '��' => '殓',
  '��' => '殍',
  '��' => '殚',
  '��' => '殛',
  '��' => '殡',
  '��' => '殪',
  '��' => '轫',
  '��' => '轭',
  '��' => '轱',
  '��' => '轲',
  '��' => '轳',
  '��' => '轵',
  '��' => '轶',
  '��' => '轸',
  '�' => '轷',
  '�' => '轹',
  '�' => '轺',
  '�' => '轼',
  '�' => '轾',
  '�' => '辁',
  '�' => '辂',
  '�' => '辄',
  '�' => '辇',
  '�' => '辋',
  '�@' => '闌',
  '�A' => '闍',
  '�B' => '闎',
  '�C' => '闏',
  '�D' => '闐',
  '�E' => '闑',
  '�F' => '闒',
  '�G' => '闓',
  '�H' => '闔',
  '�I' => '闕',
  '�J' => '闖',
  '�K' => '闗',
  '�L' => '闘',
  '�M' => '闙',
  '�N' => '闚',
  '�O' => '闛',
  '�P' => '關',
  '�Q' => '闝',
  '�R' => '闞',
  '�S' => '闟',
  '�T' => '闠',
  '�U' => '闡',
  '�V' => '闢',
  '�W' => '闣',
  '�X' => '闤',
  '�Y' => '闥',
  '�Z' => '闦',
  '�[' => '闧',
  '�\\' => '闬',
  '�]' => '闿',
  '�^' => '阇',
  '�_' => '阓',
  '�`' => '阘',
  '�a' => '阛',
  '�b' => '阞',
  '�c' => '阠',
  '�d' => '阣',
  '�e' => '阤',
  '�f' => '阥',
  '�g' => '阦',
  '�h' => '阧',
  '�i' => '阨',
  '�j' => '阩',
  '�k' => '阫',
  '�l' => '阬',
  '�m' => '阭',
  '�n' => '阯',
  '�o' => '阰',
  '�p' => '阷',
  '�q' => '阸',
  '�r' => '阹',
  '�s' => '阺',
  '�t' => '阾',
  '�u' => '陁',
  '�v' => '陃',
  '�w' => '陊',
  '�x' => '陎',
  '�y' => '陏',
  '�z' => '陑',
  '�{' => '陒',
  '�|' => '陓',
  '�}' => '陖',
  '�~' => '陗',
  '�' => '陘',
  '�' => '陙',
  '�' => '陚',
  '�' => '陜',
  '�' => '陝',
  '�' => '陞',
  '�' => '陠',
  '�' => '陣',
  '�' => '陥',
  '�' => '陦',
  '�' => '陫',
  '�' => '陭',
  '�' => '陮',
  '�' => '陯',
  '�' => '陰',
  '�' => '陱',
  '�' => '陳',
  '�' => '陸',
  '�' => '陹',
  '�' => '険',
  '�' => '陻',
  '�' => '陼',
  '�' => '陽',
  '�' => '陾',
  '�' => '陿',
  '�' => '隀',
  '�' => '隁',
  '�' => '隂',
  '�' => '隃',
  '�' => '隄',
  '�' => '隇',
  '�' => '隉',
  '�' => '隊',
  '�' => '辍',
  '�' => '辎',
  '�' => '辏',
  '�' => '辘',
  '�' => '辚',
  '�' => '軎',
  '�' => '戋',
  '�' => '戗',
  '�' => '戛',
  '�' => '戟',
  '�' => '戢',
  '�' => '戡',
  '�' => '戥',
  '�' => '戤',
  '�' => '戬',
  '�' => '臧',
  '�' => '瓯',
  '�' => '瓴',
  '�' => '瓿',
  '�' => '甏',
  '�' => '甑',
  '�' => '甓',
  '�' => '攴',
  '�' => '旮',
  '�' => '旯',
  '�' => '旰',
  '�' => '昊',
  '�' => '昙',
  '�' => '杲',
  '�' => '昃',
  '�' => '昕',
  '�' => '昀',
  '�' => '炅',
  '��' => '曷',
  '��' => '昝',
  '��' => '昴',
  '��' => '昱',
  '��' => '昶',
  '��' => '昵',
  '��' => '耆',
  '��' => '晟',
  '��' => '晔',
  '��' => '晁',
  '��' => '晏',
  '��' => '晖',
  '��' => '晡',
  '��' => '晗',
  '��' => '晷',
  '��' => '暄',
  '��' => '暌',
  '��' => '暧',
  '��' => '暝',
  '��' => '暾',
  '��' => '曛',
  '��' => '曜',
  '��' => '曦',
  '��' => '曩',
  '��' => '贲',
  '��' => '贳',
  '��' => '贶',
  '��' => '贻',
  '��' => '贽',
  '��' => '赀',
  '��' => '赅',
  '��' => '赆',
  '��' => '赈',
  '��' => '赉',
  '��' => '赇',
  '��' => '赍',
  '��' => '赕',
  '��' => '赙',
  '��' => '觇',
  '��' => '觊',
  '��' => '觋',
  '��' => '觌',
  '��' => '觎',
  '��' => '觏',
  '��' => '觐',
  '��' => '觑',
  '��' => '牮',
  '��' => '犟',
  '��' => '牝',
  '��' => '牦',
  '��' => '牯',
  '�' => '牾',
  '�' => '牿',
  '�' => '犄',
  '�' => '犋',
  '�' => '犍',
  '�' => '犏',
  '�' => '犒',
  '�' => '挈',
  '�' => '挲',
  '�' => '掰',
  '�@' => '隌',
  '�A' => '階',
  '�B' => '隑',
  '�C' => '隒',
  '�D' => '隓',
  '�E' => '隕',
  '�F' => '隖',
  '�G' => '隚',
  '�H' => '際',
  '�I' => '隝',
  '�J' => '隞',
  '�K' => '隟',
  '�L' => '隠',
  '�M' => '隡',
  '�N' => '隢',
  '�O' => '隣',
  '�P' => '隤',
  '�Q' => '隥',
  '�R' => '隦',
  '�S' => '隨',
  '�T' => '隩',
  '�U' => '險',
  '�V' => '隫',
  '�W' => '隬',
  '�X' => '隭',
  '�Y' => '隮',
  '�Z' => '隯',
  '�[' => '隱',
  '�\\' => '隲',
  '�]' => '隴',
  '�^' => '隵',
  '�_' => '隷',
  '�`' => '隸',
  '�a' => '隺',
  '�b' => '隻',
  '�c' => '隿',
  '�d' => '雂',
  '�e' => '雃',
  '�f' => '雈',
  '�g' => '雊',
  '�h' => '雋',
  '�i' => '雐',
  '�j' => '雑',
  '�k' => '雓',
  '�l' => '雔',
  '�m' => '雖',
  '�n' => '雗',
  '�o' => '雘',
  '�p' => '雙',
  '�q' => '雚',
  '�r' => '雛',
  '�s' => '雜',
  '�t' => '雝',
  '�u' => '雞',
  '�v' => '雟',
  '�w' => '雡',
  '�x' => '離',
  '�y' => '難',
  '�z' => '雤',
  '�{' => '雥',
  '�|' => '雦',
  '�}' => '雧',
  '�~' => '雫',
  '�' => '雬',
  '�' => '雭',
  '�' => '雮',
  '�' => '雰',
  '�' => '雱',
  '�' => '雲',
  '�' => '雴',
  '�' => '雵',
  '�' => '雸',
  '�' => '雺',
  '�' => '電',
  '�' => '雼',
  '�' => '雽',
  '�' => '雿',
  '�' => '霂',
  '�' => '霃',
  '�' => '霅',
  '�' => '霊',
  '�' => '霋',
  '�' => '霌',
  '�' => '霐',
  '�' => '霑',
  '�' => '霒',
  '�' => '霔',
  '�' => '霕',
  '�' => '霗',
  '�' => '霘',
  '�' => '霙',
  '�' => '霚',
  '�' => '霛',
  '�' => '霝',
  '�' => '霟',
  '�' => '霠',
  '�' => '搿',
  '�' => '擘',
  '�' => '耄',
  '�' => '毪',
  '�' => '毳',
  '�' => '毽',
  '�' => '毵',
  '�' => '毹',
  '�' => '氅',
  '�' => '氇',
  '�' => '氆',
  '�' => '氍',
  '�' => '氕',
  '�' => '氘',
  '�' => '氙',
  '�' => '氚',
  '�' => '氡',
  '�' => '氩',
  '�' => '氤',
  '�' => '氪',
  '�' => '氲',
  '�' => '攵',
  '�' => '敕',
  '�' => '敫',
  '�' => '牍',
  '�' => '牒',
  '�' => '牖',
  '�' => '爰',
  '�' => '虢',
  '�' => '刖',
  '�' => '肟',
  '�' => '肜',
  '�' => '肓',
  '��' => '肼',
  '��' => '朊',
  '��' => '肽',
  '��' => '肱',
  '��' => '肫',
  '��' => '肭',
  '��' => '肴',
  '��' => '肷',
  '��' => '胧',
  '��' => '胨',
  '��' => '胩',
  '��' => '胪',
  '��' => '胛',
  '��' => '胂',
  '��' => '胄',
  '��' => '胙',
  '��' => '胍',
  '��' => '胗',
  '��' => '朐',
  '��' => '胝',
  '��' => '胫',
  '��' => '胱',
  '��' => '胴',
  '��' => '胭',
  '��' => '脍',
  '��' => '脎',
  '��' => '胲',
  '��' => '胼',
  '��' => '朕',
  '��' => '脒',
  '��' => '豚',
  '��' => '脶',
  '��' => '脞',
  '��' => '脬',
  '��' => '脘',
  '��' => '脲',
  '��' => '腈',
  '��' => '腌',
  '��' => '腓',
  '��' => '腴',
  '��' => '腙',
  '��' => '腚',
  '��' => '腱',
  '��' => '腠',
  '��' => '腩',
  '��' => '腼',
  '��' => '腽',
  '��' => '腭',
  '��' => '腧',
  '��' => '塍',
  '��' => '媵',
  '�' => '膈',
  '�' => '膂',
  '�' => '膑',
  '�' => '滕',
  '�' => '膣',
  '�' => '膪',
  '�' => '臌',
  '�' => '朦',
  '�' => '臊',
  '�' => '膻',
  '�@' => '霡',
  '�A' => '霢',
  '�B' => '霣',
  '�C' => '霤',
  '�D' => '霥',
  '�E' => '霦',
  '�F' => '霧',
  '�G' => '霨',
  '�H' => '霩',
  '�I' => '霫',
  '�J' => '霬',
  '�K' => '霮',
  '�L' => '霯',
  '�M' => '霱',
  '�N' => '霳',
  '�O' => '霴',
  '�P' => '霵',
  '�Q' => '霶',
  '�R' => '霷',
  '�S' => '霺',
  '�T' => '霻',
  '�U' => '霼',
  '�V' => '霽',
  '�W' => '霿',
  '�X' => '靀',
  '�Y' => '靁',
  '�Z' => '靂',
  '�[' => '靃',
  '�\\' => '靄',
  '�]' => '靅',
  '�^' => '靆',
  '�_' => '靇',
  '�`' => '靈',
  '�a' => '靉',
  '�b' => '靊',
  '�c' => '靋',
  '�d' => '靌',
  '�e' => '靍',
  '�f' => '靎',
  '�g' => '靏',
  '�h' => '靐',
  '�i' => '靑',
  '�j' => '靔',
  '�k' => '靕',
  '�l' => '靗',
  '�m' => '靘',
  '�n' => '靚',
  '�o' => '靜',
  '�p' => '靝',
  '�q' => '靟',
  '�r' => '靣',
  '�s' => '靤',
  '�t' => '靦',
  '�u' => '靧',
  '�v' => '靨',
  '�w' => '靪',
  '�x' => '靫',
  '�y' => '靬',
  '�z' => '靭',
  '�{' => '靮',
  '�|' => '靯',
  '�}' => '靰',
  '�~' => '靱',
  '�' => '靲',
  '�' => '靵',
  '�' => '靷',
  '�' => '靸',
  '�' => '靹',
  '�' => '靺',
  '�' => '靻',
  '�' => '靽',
  '�' => '靾',
  '�' => '靿',
  '�' => '鞀',
  '�' => '鞁',
  '�' => '鞂',
  '�' => '鞃',
  '�' => '鞄',
  '�' => '鞆',
  '�' => '鞇',
  '�' => '鞈',
  '�' => '鞉',
  '�' => '鞊',
  '�' => '鞌',
  '�' => '鞎',
  '�' => '鞏',
  '�' => '鞐',
  '�' => '鞓',
  '�' => '鞕',
  '�' => '鞖',
  '�' => '鞗',
  '�' => '鞙',
  '�' => '鞚',
  '�' => '鞛',
  '�' => '鞜',
  '�' => '鞝',
  '�' => '臁',
  '�' => '膦',
  '�' => '欤',
  '�' => '欷',
  '�' => '欹',
  '�' => '歃',
  '�' => '歆',
  '�' => '歙',
  '�' => '飑',
  '�' => '飒',
  '�' => '飓',
  '�' => '飕',
  '�' => '飙',
  '�' => '飚',
  '�' => '殳',
  '�' => '彀',
  '�' => '毂',
  '�' => '觳',
  '�' => '斐',
  '�' => '齑',
  '�' => '斓',
  '�' => '於',
  '�' => '旆',
  '�' => '旄',
  '�' => '旃',
  '�' => '旌',
  '�' => '旎',
  '�' => '旒',
  '�' => '旖',
  '�' => '炀',
  '�' => '炜',
  '�' => '炖',
  '�' => '炝',
  '��' => '炻',
  '��' => '烀',
  '��' => '炷',
  '��' => '炫',
  '��' => '炱',
  '��' => '烨',
  '��' => '烊',
  '��' => '焐',
  '��' => '焓',
  '��' => '焖',
  '��' => '焯',
  '��' => '焱',
  '��' => '煳',
  '��' => '煜',
  '��' => '煨',
  '��' => '煅',
  '��' => '煲',
  '��' => '煊',
  '��' => '煸',
  '��' => '煺',
  '��' => '熘',
  '��' => '熳',
  '��' => '熵',
  '��' => '熨',
  '��' => '熠',
  '��' => '燠',
  '��' => '燔',
  '��' => '燧',
  '��' => '燹',
  '��' => '爝',
  '��' => '爨',
  '��' => '灬',
  '��' => '焘',
  '��' => '煦',
  '��' => '熹',
  '��' => '戾',
  '��' => '戽',
  '��' => '扃',
  '��' => '扈',
  '��' => '扉',
  '��' => '礻',
  '��' => '祀',
  '��' => '祆',
  '��' => '祉',
  '��' => '祛',
  '��' => '祜',
  '��' => '祓',
  '��' => '祚',
  '��' => '祢',
  '��' => '祗',
  '��' => '祠',
  '�' => '祯',
  '�' => '祧',
  '�' => '祺',
  '�' => '禅',
  '�' => '禊',
  '�' => '禚',
  '�' => '禧',
  '�' => '禳',
  '�' => '忑',
  '�' => '忐',
  '�@' => '鞞',
  '�A' => '鞟',
  '�B' => '鞡',
  '�C' => '鞢',
  '�D' => '鞤',
  '�E' => '鞥',
  '�F' => '鞦',
  '�G' => '鞧',
  '�H' => '鞨',
  '�I' => '鞩',
  '�J' => '鞪',
  '�K' => '鞬',
  '�L' => '鞮',
  '�M' => '鞰',
  '�N' => '鞱',
  '�O' => '鞳',
  '�P' => '鞵',
  '�Q' => '鞶',
  '�R' => '鞷',
  '�S' => '鞸',
  '�T' => '鞹',
  '�U' => '鞺',
  '�V' => '鞻',
  '�W' => '鞼',
  '�X' => '鞽',
  '�Y' => '鞾',
  '�Z' => '鞿',
  '�[' => '韀',
  '�\\' => '韁',
  '�]' => '韂',
  '�^' => '韃',
  '�_' => '韄',
  '�`' => '韅',
  '�a' => '韆',
  '�b' => '韇',
  '�c' => '韈',
  '�d' => '韉',
  '�e' => '韊',
  '�f' => '韋',
  '�g' => '韌',
  '�h' => '韍',
  '�i' => '韎',
  '�j' => '韏',
  '�k' => '韐',
  '�l' => '韑',
  '�m' => '韒',
  '�n' => '韓',
  '�o' => '韔',
  '�p' => '韕',
  '�q' => '韖',
  '�r' => '韗',
  '�s' => '韘',
  '�t' => '韙',
  '�u' => '韚',
  '�v' => '韛',
  '�w' => '韜',
  '�x' => '韝',
  '�y' => '韞',
  '�z' => '韟',
  '�{' => '韠',
  '�|' => '韡',
  '�}' => '韢',
  '�~' => '韣',
  '�' => '韤',
  '�' => '韥',
  '�' => '韨',
  '�' => '韮',
  '�' => '韯',
  '�' => '韰',
  '�' => '韱',
  '�' => '韲',
  '�' => '韴',
  '�' => '韷',
  '�' => '韸',
  '�' => '韹',
  '�' => '韺',
  '�' => '韻',
  '�' => '韼',
  '�' => '韽',
  '�' => '韾',
  '�' => '響',
  '�' => '頀',
  '�' => '頁',
  '�' => '頂',
  '�' => '頃',
  '�' => '頄',
  '�' => '項',
  '�' => '順',
  '�' => '頇',
  '�' => '須',
  '�' => '頉',
  '�' => '頊',
  '�' => '頋',
  '�' => '頌',
  '�' => '頍',
  '�' => '頎',
  '�' => '怼',
  '�' => '恝',
  '�' => '恚',
  '�' => '恧',
  '�' => '恁',
  '�' => '恙',
  '�' => '恣',
  '�' => '悫',
  '�' => '愆',
  '�' => '愍',
  '�' => '慝',
  '�' => '憩',
  '�' => '憝',
  '�' => '懋',
  '�' => '懑',
  '�' => '戆',
  '�' => '肀',
  '�' => '聿',
  '�' => '沓',
  '�' => '泶',
  '�' => '淼',
  '�' => '矶',
  '�' => '矸',
  '�' => '砀',
  '�' => '砉',
  '�' => '砗',
  '�' => '砘',
  '�' => '砑',
  '�' => '斫',
  '�' => '砭',
  '�' => '砜',
  '�' => '砝',
  '�' => '砹',
  '��' => '砺',
  '��' => '砻',
  '��' => '砟',
  '��' => '砼',
  '��' => '砥',
  '��' => '砬',
  '��' => '砣',
  '��' => '砩',
  '��' => '硎',
  '��' => '硭',
  '��' => '硖',
  '��' => '硗',
  '��' => '砦',
  '��' => '硐',
  '��' => '硇',
  '��' => '硌',
  '��' => '硪',
  '��' => '碛',
  '��' => '碓',
  '��' => '碚',
  '��' => '碇',
  '��' => '碜',
  '��' => '碡',
  '��' => '碣',
  '��' => '碲',
  '��' => '碹',
  '��' => '碥',
  '��' => '磔',
  '��' => '磙',
  '��' => '磉',
  '��' => '磬',
  '��' => '磲',
  '��' => '礅',
  '��' => '磴',
  '��' => '礓',
  '��' => '礤',
  '��' => '礞',
  '��' => '礴',
  '��' => '龛',
  '��' => '黹',
  '��' => '黻',
  '��' => '黼',
  '��' => '盱',
  '��' => '眄',
  '��' => '眍',
  '��' => '盹',
  '��' => '眇',
  '��' => '眈',
  '��' => '眚',
  '��' => '眢',
  '��' => '眙',
  '�' => '眭',
  '�' => '眦',
  '�' => '眵',
  '�' => '眸',
  '�' => '睐',
  '�' => '睑',
  '�' => '睇',
  '�' => '睃',
  '�' => '睚',
  '�' => '睨',
  '�@' => '頏',
  '�A' => '預',
  '�B' => '頑',
  '�C' => '頒',
  '�D' => '頓',
  '�E' => '頔',
  '�F' => '頕',
  '�G' => '頖',
  '�H' => '頗',
  '�I' => '領',
  '�J' => '頙',
  '�K' => '頚',
  '�L' => '頛',
  '�M' => '頜',
  '�N' => '頝',
  '�O' => '頞',
  '�P' => '頟',
  '�Q' => '頠',
  '�R' => '頡',
  '�S' => '頢',
  '�T' => '頣',
  '�U' => '頤',
  '�V' => '頥',
  '�W' => '頦',
  '�X' => '頧',
  '�Y' => '頨',
  '�Z' => '頩',
  '�[' => '頪',
  '�\\' => '頫',
  '�]' => '頬',
  '�^' => '頭',
  '�_' => '頮',
  '�`' => '頯',
  '�a' => '頰',
  '�b' => '頱',
  '�c' => '頲',
  '�d' => '頳',
  '�e' => '頴',
  '�f' => '頵',
  '�g' => '頶',
  '�h' => '頷',
  '�i' => '頸',
  '�j' => '頹',
  '�k' => '頺',
  '�l' => '頻',
  '�m' => '頼',
  '�n' => '頽',
  '�o' => '頾',
  '�p' => '頿',
  '�q' => '顀',
  '�r' => '顁',
  '�s' => '顂',
  '�t' => '顃',
  '�u' => '顄',
  '�v' => '顅',
  '�w' => '顆',
  '�x' => '顇',
  '�y' => '顈',
  '�z' => '顉',
  '�{' => '顊',
  '�|' => '顋',
  '�}' => '題',
  '�~' => '額',
  '�' => '顎',
  '�' => '顏',
  '�' => '顐',
  '�' => '顑',
  '�' => '顒',
  '�' => '顓',
  '�' => '顔',
  '�' => '顕',
  '�' => '顖',
  '�' => '顗',
  '�' => '願',
  '�' => '顙',
  '�' => '顚',
  '�' => '顛',
  '�' => '顜',
  '�' => '顝',
  '�' => '類',
  '�' => '顟',
  '�' => '顠',
  '�' => '顡',
  '�' => '顢',
  '�' => '顣',
  '�' => '顤',
  '�' => '顥',
  '�' => '顦',
  '�' => '顧',
  '�' => '顨',
  '�' => '顩',
  '�' => '顪',
  '�' => '顫',
  '�' => '顬',
  '�' => '顭',
  '�' => '顮',
  '�' => '睢',
  '�' => '睥',
  '�' => '睿',
  '�' => '瞍',
  '�' => '睽',
  '�' => '瞀',
  '�' => '瞌',
  '�' => '瞑',
  '�' => '瞟',
  '�' => '瞠',
  '�' => '瞰',
  '�' => '瞵',
  '�' => '瞽',
  '�' => '町',
  '�' => '畀',
  '�' => '畎',
  '�' => '畋',
  '�' => '畈',
  '�' => '畛',
  '�' => '畲',
  '�' => '畹',
  '�' => '疃',
  '�' => '罘',
  '�' => '罡',
  '�' => '罟',
  '�' => '詈',
  '�' => '罨',
  '�' => '罴',
  '�' => '罱',
  '�' => '罹',
  '�' => '羁',
  '�' => '罾',
  '�' => '盍',
  '��' => '盥',
  '��' => '蠲',
  '��' => '钅',
  '��' => '钆',
  '��' => '钇',
  '��' => '钋',
  '��' => '钊',
  '��' => '钌',
  '��' => '钍',
  '��' => '钏',
  '��' => '钐',
  '��' => '钔',
  '��' => '钗',
  '��' => '钕',
  '��' => '钚',
  '��' => '钛',
  '��' => '钜',
  '��' => '钣',
  '��' => '钤',
  '��' => '钫',
  '��' => '钪',
  '��' => '钭',
  '��' => '钬',
  '��' => '钯',
  '��' => '钰',
  '��' => '钲',
  '��' => '钴',
  '��' => '钶',
  '��' => '钷',
  '��' => '钸',
  '��' => '钹',
  '��' => '钺',
  '��' => '钼',
  '��' => '钽',
  '��' => '钿',
  '��' => '铄',
  '��' => '铈',
  '��' => '铉',
  '��' => '铊',
  '��' => '铋',
  '��' => '铌',
  '��' => '铍',
  '��' => '铎',
  '��' => '铐',
  '��' => '铑',
  '��' => '铒',
  '��' => '铕',
  '��' => '铖',
  '��' => '铗',
  '��' => '铙',
  '��' => '铘',
  '�' => '铛',
  '�' => '铞',
  '�' => '铟',
  '�' => '铠',
  '�' => '铢',
  '�' => '铤',
  '�' => '铥',
  '�' => '铧',
  '�' => '铨',
  '�' => '铪',
  '�@' => '顯',
  '�A' => '顰',
  '�B' => '顱',
  '�C' => '顲',
  '�D' => '顳',
  '�E' => '顴',
  '�F' => '颋',
  '�G' => '颎',
  '�H' => '颒',
  '�I' => '颕',
  '�J' => '颙',
  '�K' => '颣',
  '�L' => '風',
  '�M' => '颩',
  '�N' => '颪',
  '�O' => '颫',
  '�P' => '颬',
  '�Q' => '颭',
  '�R' => '颮',
  '�S' => '颯',
  '�T' => '颰',
  '�U' => '颱',
  '�V' => '颲',
  '�W' => '颳',
  '�X' => '颴',
  '�Y' => '颵',
  '�Z' => '颶',
  '�[' => '颷',
  '�\\' => '颸',
  '�]' => '颹',
  '�^' => '颺',
  '�_' => '颻',
  '�`' => '颼',
  '�a' => '颽',
  '�b' => '颾',
  '�c' => '颿',
  '�d' => '飀',
  '�e' => '飁',
  '�f' => '飂',
  '�g' => '飃',
  '�h' => '飄',
  '�i' => '飅',
  '�j' => '飆',
  '�k' => '飇',
  '�l' => '飈',
  '�m' => '飉',
  '�n' => '飊',
  '�o' => '飋',
  '�p' => '飌',
  '�q' => '飍',
  '�r' => '飏',
  '�s' => '飐',
  '�t' => '飔',
  '�u' => '飖',
  '�v' => '飗',
  '�w' => '飛',
  '�x' => '飜',
  '�y' => '飝',
  '�z' => '飠',
  '�{' => '飡',
  '�|' => '飢',
  '�}' => '飣',
  '�~' => '飤',
  '�' => '飥',
  '�' => '飦',
  '�' => '飩',
  '�' => '飪',
  '�' => '飫',
  '�' => '飬',
  '�' => '飭',
  '�' => '飮',
  '�' => '飯',
  '�' => '飰',
  '�' => '飱',
  '�' => '飲',
  '�' => '飳',
  '�' => '飴',
  '�' => '飵',
  '�' => '飶',
  '�' => '飷',
  '�' => '飸',
  '�' => '飹',
  '�' => '飺',
  '�' => '飻',
  '�' => '飼',
  '�' => '飽',
  '�' => '飾',
  '�' => '飿',
  '�' => '餀',
  '�' => '餁',
  '�' => '餂',
  '�' => '餃',
  '�' => '餄',
  '�' => '餅',
  '�' => '餆',
  '�' => '餇',
  '�' => '铩',
  '�' => '铫',
  '�' => '铮',
  '�' => '铯',
  '�' => '铳',
  '�' => '铴',
  '�' => '铵',
  '�' => '铷',
  '�' => '铹',
  '�' => '铼',
  '�' => '铽',
  '�' => '铿',
  '�' => '锃',
  '�' => '锂',
  '�' => '锆',
  '�' => '锇',
  '�' => '锉',
  '�' => '锊',
  '�' => '锍',
  '�' => '锎',
  '�' => '锏',
  '�' => '锒',
  '�' => '锓',
  '�' => '锔',
  '�' => '锕',
  '�' => '锖',
  '�' => '锘',
  '�' => '锛',
  '�' => '锝',
  '�' => '锞',
  '�' => '锟',
  '�' => '锢',
  '�' => '锪',
  '��' => '锫',
  '��' => '锩',
  '��' => '锬',
  '��' => '锱',
  '��' => '锲',
  '��' => '锴',
  '��' => '锶',
  '��' => '锷',
  '��' => '锸',
  '��' => '锼',
  '��' => '锾',
  '��' => '锿',
  '��' => '镂',
  '��' => '锵',
  '��' => '镄',
  '��' => '镅',
  '��' => '镆',
  '��' => '镉',
  '��' => '镌',
  '��' => '镎',
  '��' => '镏',
  '��' => '镒',
  '��' => '镓',
  '��' => '镔',
  '��' => '镖',
  '��' => '镗',
  '��' => '镘',
  '��' => '镙',
  '��' => '镛',
  '��' => '镞',
  '��' => '镟',
  '��' => '镝',
  '��' => '镡',
  '��' => '镢',
  '��' => '镤',
  '��' => '镥',
  '��' => '镦',
  '��' => '镧',
  '��' => '镨',
  '��' => '镩',
  '��' => '镪',
  '��' => '镫',
  '��' => '镬',
  '��' => '镯',
  '��' => '镱',
  '��' => '镲',
  '��' => '镳',
  '��' => '锺',
  '��' => '矧',
  '��' => '矬',
  '��' => '雉',
  '�' => '秕',
  '�' => '秭',
  '�' => '秣',
  '�' => '秫',
  '�' => '稆',
  '�' => '嵇',
  '�' => '稃',
  '�' => '稂',
  '�' => '稞',
  '�' => '稔',
  '�@' => '餈',
  '�A' => '餉',
  '�B' => '養',
  '�C' => '餋',
  '�D' => '餌',
  '�E' => '餎',
  '�F' => '餏',
  '�G' => '餑',
  '�H' => '餒',
  '�I' => '餓',
  '�J' => '餔',
  '�K' => '餕',
  '�L' => '餖',
  '�M' => '餗',
  '�N' => '餘',
  '�O' => '餙',
  '�P' => '餚',
  '�Q' => '餛',
  '�R' => '餜',
  '�S' => '餝',
  '�T' => '餞',
  '�U' => '餟',
  '�V' => '餠',
  '�W' => '餡',
  '�X' => '餢',
  '�Y' => '餣',
  '�Z' => '餤',
  '�[' => '餥',
  '�\\' => '餦',
  '�]' => '餧',
  '�^' => '館',
  '�_' => '餩',
  '�`' => '餪',
  '�a' => '餫',
  '�b' => '餬',
  '�c' => '餭',
  '�d' => '餯',
  '�e' => '餰',
  '�f' => '餱',
  '�g' => '餲',
  '�h' => '餳',
  '�i' => '餴',
  '�j' => '餵',
  '�k' => '餶',
  '�l' => '餷',
  '�m' => '餸',
  '�n' => '餹',
  '�o' => '餺',
  '�p' => '餻',
  '�q' => '餼',
  '�r' => '餽',
  '�s' => '餾',
  '�t' => '餿',
  '�u' => '饀',
  '�v' => '饁',
  '�w' => '饂',
  '�x' => '饃',
  '�y' => '饄',
  '�z' => '饅',
  '�{' => '饆',
  '�|' => '饇',
  '�}' => '饈',
  '�~' => '饉',
  '�' => '饊',
  '�' => '饋',
  '�' => '饌',
  '�' => '饍',
  '�' => '饎',
  '�' => '饏',
  '�' => '饐',
  '�' => '饑',
  '�' => '饒',
  '�' => '饓',
  '�' => '饖',
  '�' => '饗',
  '�' => '饘',
  '�' => '饙',
  '�' => '饚',
  '�' => '饛',
  '�' => '饜',
  '�' => '饝',
  '�' => '饞',
  '�' => '饟',
  '�' => '饠',
  '�' => '饡',
  '�' => '饢',
  '�' => '饤',
  '�' => '饦',
  '�' => '饳',
  '�' => '饸',
  '�' => '饹',
  '�' => '饻',
  '�' => '饾',
  '�' => '馂',
  '�' => '馃',
  '�' => '馉',
  '�' => '稹',
  '�' => '稷',
  '�' => '穑',
  '�' => '黏',
  '�' => '馥',
  '�' => '穰',
  '�' => '皈',
  '�' => '皎',
  '�' => '皓',
  '�' => '皙',
  '�' => '皤',
  '�' => '瓞',
  '�' => '瓠',
  '�' => '甬',
  '�' => '鸠',
  '�' => '鸢',
  '�' => '鸨',
  '�' => '鸩',
  '�' => '鸪',
  '�' => '鸫',
  '�' => '鸬',
  '�' => '鸲',
  '�' => '鸱',
  '�' => '鸶',
  '�' => '鸸',
  '�' => '鸷',
  '�' => '鸹',
  '�' => '鸺',
  '�' => '鸾',
  '�' => '鹁',
  '�' => '鹂',
  '�' => '鹄',
  '�' => '鹆',
  '��' => '鹇',
  '��' => '鹈',
  '��' => '鹉',
  '��' => '鹋',
  '��' => '鹌',
  '��' => '鹎',
  '��' => '鹑',
  '��' => '鹕',
  '��' => '鹗',
  '��' => '鹚',
  '��' => '鹛',
  '��' => '鹜',
  '��' => '鹞',
  '��' => '鹣',
  '��' => '鹦',
  '��' => '鹧',
  '��' => '鹨',
  '��' => '鹩',
  '��' => '鹪',
  '��' => '鹫',
  '��' => '鹬',
  '��' => '鹱',
  '��' => '鹭',
  '��' => '鹳',
  '��' => '疒',
  '��' => '疔',
  '��' => '疖',
  '��' => '疠',
  '��' => '疝',
  '��' => '疬',
  '��' => '疣',
  '��' => '疳',
  '��' => '疴',
  '��' => '疸',
  '��' => '痄',
  '��' => '疱',
  '��' => '疰',
  '��' => '痃',
  '��' => '痂',
  '��' => '痖',
  '��' => '痍',
  '��' => '痣',
  '��' => '痨',
  '��' => '痦',
  '��' => '痤',
  '��' => '痫',
  '��' => '痧',
  '��' => '瘃',
  '��' => '痱',
  '��' => '痼',
  '��' => '痿',
  '�' => '瘐',
  '�' => '瘀',
  '�' => '瘅',
  '�' => '瘌',
  '�' => '瘗',
  '�' => '瘊',
  '�' => '瘥',
  '�' => '瘘',
  '�' => '瘕',
  '�' => '瘙',
  '�@' => '馌',
  '�A' => '馎',
  '�B' => '馚',
  '�C' => '馛',
  '�D' => '馜',
  '�E' => '馝',
  '�F' => '馞',
  '�G' => '馟',
  '�H' => '馠',
  '�I' => '馡',
  '�J' => '馢',
  '�K' => '馣',
  '�L' => '馤',
  '�M' => '馦',
  '�N' => '馧',
  '�O' => '馩',
  '�P' => '馪',
  '�Q' => '馫',
  '�R' => '馬',
  '�S' => '馭',
  '�T' => '馮',
  '�U' => '馯',
  '�V' => '馰',
  '�W' => '馱',
  '�X' => '馲',
  '�Y' => '馳',
  '�Z' => '馴',
  '�[' => '馵',
  '�\\' => '馶',
  '�]' => '馷',
  '�^' => '馸',
  '�_' => '馹',
  '�`' => '馺',
  '�a' => '馻',
  '�b' => '馼',
  '�c' => '馽',
  '�d' => '馾',
  '�e' => '馿',
  '�f' => '駀',
  '�g' => '駁',
  '�h' => '駂',
  '�i' => '駃',
  '�j' => '駄',
  '�k' => '駅',
  '�l' => '駆',
  '�m' => '駇',
  '�n' => '駈',
  '�o' => '駉',
  '�p' => '駊',
  '�q' => '駋',
  '�r' => '駌',
  '�s' => '駍',
  '�t' => '駎',
  '�u' => '駏',
  '�v' => '駐',
  '�w' => '駑',
  '�x' => '駒',
  '�y' => '駓',
  '�z' => '駔',
  '�{' => '駕',
  '�|' => '駖',
  '�}' => '駗',
  '�~' => '駘',
  '�' => '駙',
  '�' => '駚',
  '�' => '駛',
  '�' => '駜',
  '�' => '駝',
  '�' => '駞',
  '�' => '駟',
  '�' => '駠',
  '�' => '駡',
  '�' => '駢',
  '�' => '駣',
  '�' => '駤',
  '�' => '駥',
  '�' => '駦',
  '�' => '駧',
  '�' => '駨',
  '�' => '駩',
  '�' => '駪',
  '�' => '駫',
  '�' => '駬',
  '�' => '駭',
  '�' => '駮',
  '�' => '駯',
  '�' => '駰',
  '�' => '駱',
  '�' => '駲',
  '�' => '駳',
  '�' => '駴',
  '�' => '駵',
  '�' => '駶',
  '�' => '駷',
  '�' => '駸',
  '�' => '駹',
  '�' => '瘛',
  '�' => '瘼',
  '�' => '瘢',
  '�' => '瘠',
  '�' => '癀',
  '�' => '瘭',
  '�' => '瘰',
  '�' => '瘿',
  '�' => '瘵',
  '�' => '癃',
  '�' => '瘾',
  '�' => '瘳',
  '�' => '癍',
  '�' => '癞',
  '�' => '癔',
  '�' => '癜',
  '�' => '癖',
  '�' => '癫',
  '�' => '癯',
  '�' => '翊',
  '�' => '竦',
  '�' => '穸',
  '�' => '穹',
  '�' => '窀',
  '�' => '窆',
  '�' => '窈',
  '�' => '窕',
  '�' => '窦',
  '�' => '窠',
  '�' => '窬',
  '�' => '窨',
  '�' => '窭',
  '�' => '窳',
  '��' => '衤',
  '��' => '衩',
  '��' => '衲',
  '��' => '衽',
  '��' => '衿',
  '��' => '袂',
  '��' => '袢',
  '��' => '裆',
  '��' => '袷',
  '��' => '袼',
  '��' => '裉',
  '��' => '裢',
  '��' => '裎',
  '��' => '裣',
  '��' => '裥',
  '��' => '裱',
  '��' => '褚',
  '��' => '裼',
  '��' => '裨',
  '��' => '裾',
  '��' => '裰',
  '��' => '褡',
  '��' => '褙',
  '��' => '褓',
  '��' => '褛',
  '��' => '褊',
  '��' => '褴',
  '��' => '褫',
  '��' => '褶',
  '��' => '襁',
  '��' => '襦',
  '��' => '襻',
  '��' => '疋',
  '��' => '胥',
  '��' => '皲',
  '��' => '皴',
  '��' => '矜',
  '��' => '耒',
  '��' => '耔',
  '��' => '耖',
  '��' => '耜',
  '��' => '耠',
  '��' => '耢',
  '��' => '耥',
  '��' => '耦',
  '��' => '耧',
  '��' => '耩',
  '��' => '耨',
  '��' => '耱',
  '��' => '耋',
  '��' => '耵',
  '�' => '聃',
  '�' => '聆',
  '�' => '聍',
  '�' => '聒',
  '�' => '聩',
  '�' => '聱',
  '�' => '覃',
  '�' => '顸',
  '�' => '颀',
  '�' => '颃',
  '�@' => '駺',
  '�A' => '駻',
  '�B' => '駼',
  '�C' => '駽',
  '�D' => '駾',
  '�E' => '駿',
  '�F' => '騀',
  '�G' => '騁',
  '�H' => '騂',
  '�I' => '騃',
  '�J' => '騄',
  '�K' => '騅',
  '�L' => '騆',
  '�M' => '騇',
  '�N' => '騈',
  '�O' => '騉',
  '�P' => '騊',
  '�Q' => '騋',
  '�R' => '騌',
  '�S' => '騍',
  '�T' => '騎',
  '�U' => '騏',
  '�V' => '騐',
  '�W' => '騑',
  '�X' => '騒',
  '�Y' => '験',
  '�Z' => '騔',
  '�[' => '騕',
  '�\\' => '騖',
  '�]' => '騗',
  '�^' => '騘',
  '�_' => '騙',
  '�`' => '騚',
  '�a' => '騛',
  '�b' => '騜',
  '�c' => '騝',
  '�d' => '騞',
  '�e' => '騟',
  '�f' => '騠',
  '�g' => '騡',
  '�h' => '騢',
  '�i' => '騣',
  '�j' => '騤',
  '�k' => '騥',
  '�l' => '騦',
  '�m' => '騧',
  '�n' => '騨',
  '�o' => '騩',
  '�p' => '騪',
  '�q' => '騫',
  '�r' => '騬',
  '�s' => '騭',
  '�t' => '騮',
  '�u' => '騯',
  '�v' => '騰',
  '�w' => '騱',
  '�x' => '騲',
  '�y' => '騳',
  '�z' => '騴',
  '�{' => '騵',
  '�|' => '騶',
  '�}' => '騷',
  '�~' => '騸',
  '�' => '騹',
  '�' => '騺',
  '�' => '騻',
  '�' => '騼',
  '�' => '騽',
  '�' => '騾',
  '�' => '騿',
  '�' => '驀',
  '�' => '驁',
  '�' => '驂',
  '�' => '驃',
  '�' => '驄',
  '�' => '驅',
  '�' => '驆',
  '�' => '驇',
  '�' => '驈',
  '�' => '驉',
  '�' => '驊',
  '�' => '驋',
  '�' => '驌',
  '�' => '驍',
  '�' => '驎',
  '�' => '驏',
  '�' => '驐',
  '�' => '驑',
  '�' => '驒',
  '�' => '驓',
  '�' => '驔',
  '�' => '驕',
  '�' => '驖',
  '�' => '驗',
  '�' => '驘',
  '�' => '驙',
  '�' => '颉',
  '�' => '颌',
  '�' => '颍',
  '�' => '颏',
  '�' => '颔',
  '�' => '颚',
  '�' => '颛',
  '�' => '颞',
  '�' => '颟',
  '�' => '颡',
  '�' => '颢',
  '�' => '颥',
  '�' => '颦',
  '�' => '虍',
  '�' => '虔',
  '�' => '虬',
  '�' => '虮',
  '�' => '虿',
  '�' => '虺',
  '�' => '虼',
  '�' => '虻',
  '�' => '蚨',
  '�' => '蚍',
  '�' => '蚋',
  '�' => '蚬',
  '�' => '蚝',
  '�' => '蚧',
  '�' => '蚣',
  '�' => '蚪',
  '�' => '蚓',
  '�' => '蚩',
  '�' => '蚶',
  '�' => '蛄',
  '��' => '蚵',
  '��' => '蛎',
  '��' => '蚰',
  '��' => '蚺',
  '��' => '蚱',
  '��' => '蚯',
  '��' => '蛉',
  '��' => '蛏',
  '��' => '蚴',
  '��' => '蛩',
  '��' => '蛱',
  '��' => '蛲',
  '��' => '蛭',
  '��' => '蛳',
  '��' => '蛐',
  '��' => '蜓',
  '��' => '蛞',
  '��' => '蛴',
  '��' => '蛟',
  '��' => '蛘',
  '��' => '蛑',
  '��' => '蜃',
  '��' => '蜇',
  '��' => '蛸',
  '��' => '蜈',
  '��' => '蜊',
  '��' => '蜍',
  '��' => '蜉',
  '��' => '蜣',
  '��' => '蜻',
  '��' => '蜞',
  '��' => '蜥',
  '��' => '蜮',
  '��' => '蜚',
  '��' => '蜾',
  '��' => '蝈',
  '��' => '蜴',
  '��' => '蜱',
  '��' => '蜩',
  '��' => '蜷',
  '��' => '蜿',
  '��' => '螂',
  '��' => '蜢',
  '��' => '蝽',
  '��' => '蝾',
  '��' => '蝻',
  '��' => '蝠',
  '��' => '蝰',
  '��' => '蝌',
  '��' => '蝮',
  '��' => '螋',
  '�' => '蝓',
  '�' => '蝣',
  '�' => '蝼',
  '�' => '蝤',
  '�' => '蝙',
  '�' => '蝥',
  '�' => '螓',
  '�' => '螯',
  '�' => '螨',
  '�' => '蟒',
  '�@' => '驚',
  '�A' => '驛',
  '�B' => '驜',
  '�C' => '驝',
  '�D' => '驞',
  '�E' => '驟',
  '�F' => '驠',
  '�G' => '驡',
  '�H' => '驢',
  '�I' => '驣',
  '�J' => '驤',
  '�K' => '驥',
  '�L' => '驦',
  '�M' => '驧',
  '�N' => '驨',
  '�O' => '驩',
  '�P' => '驪',
  '�Q' => '驫',
  '�R' => '驲',
  '�S' => '骃',
  '�T' => '骉',
  '�U' => '骍',
  '�V' => '骎',
  '�W' => '骔',
  '�X' => '骕',
  '�Y' => '骙',
  '�Z' => '骦',
  '�[' => '骩',
  '�\\' => '骪',
  '�]' => '骫',
  '�^' => '骬',
  '�_' => '骭',
  '�`' => '骮',
  '�a' => '骯',
  '�b' => '骲',
  '�c' => '骳',
  '�d' => '骴',
  '�e' => '骵',
  '�f' => '骹',
  '�g' => '骻',
  '�h' => '骽',
  '�i' => '骾',
  '�j' => '骿',
  '�k' => '髃',
  '�l' => '髄',
  '�m' => '髆',
  '�n' => '髇',
  '�o' => '髈',
  '�p' => '髉',
  '�q' => '髊',
  '�r' => '髍',
  '�s' => '髎',
  '�t' => '髏',
  '�u' => '髐',
  '�v' => '髒',
  '�w' => '體',
  '�x' => '髕',
  '�y' => '髖',
  '�z' => '髗',
  '�{' => '髙',
  '�|' => '髚',
  '�}' => '髛',
  '�~' => '髜',
  '�' => '髝',
  '�' => '髞',
  '�' => '髠',
  '�' => '髢',
  '�' => '髣',
  '�' => '髤',
  '�' => '髥',
  '�' => '髧',
  '�' => '髨',
  '�' => '髩',
  '�' => '髪',
  '�' => '髬',
  '�' => '髮',
  '�' => '髰',
  '�' => '髱',
  '�' => '髲',
  '�' => '髳',
  '�' => '髴',
  '�' => '髵',
  '�' => '髶',
  '�' => '髷',
  '�' => '髸',
  '�' => '髺',
  '�' => '髼',
  '�' => '髽',
  '�' => '髾',
  '�' => '髿',
  '�' => '鬀',
  '�' => '鬁',
  '�' => '鬂',
  '�' => '鬄',
  '�' => '鬅',
  '�' => '鬆',
  '�' => '蟆',
  '�' => '螈',
  '�' => '螅',
  '�' => '螭',
  '�' => '螗',
  '�' => '螃',
  '�' => '螫',
  '�' => '蟥',
  '�' => '螬',
  '�' => '螵',
  '�' => '螳',
  '�' => '蟋',
  '�' => '蟓',
  '�' => '螽',
  '�' => '蟑',
  '�' => '蟀',
  '�' => '蟊',
  '�' => '蟛',
  '�' => '蟪',
  '�' => '蟠',
  '�' => '蟮',
  '�' => '蠖',
  '�' => '蠓',
  '�' => '蟾',
  '�' => '蠊',
  '�' => '蠛',
  '�' => '蠡',
  '�' => '蠹',
  '�' => '蠼',
  '�' => '缶',
  '�' => '罂',
  '�' => '罄',
  '�' => '罅',
  '��' => '舐',
  '��' => '竺',
  '��' => '竽',
  '��' => '笈',
  '��' => '笃',
  '��' => '笄',
  '��' => '笕',
  '��' => '笊',
  '��' => '笫',
  '��' => '笏',
  '��' => '筇',
  '��' => '笸',
  '��' => '笪',
  '��' => '笙',
  '��' => '笮',
  '��' => '笱',
  '��' => '笠',
  '��' => '笥',
  '��' => '笤',
  '��' => '笳',
  '��' => '笾',
  '��' => '笞',
  '��' => '筘',
  '��' => '筚',
  '��' => '筅',
  '��' => '筵',
  '��' => '筌',
  '��' => '筝',
  '��' => '筠',
  '��' => '筮',
  '��' => '筻',
  '��' => '筢',
  '��' => '筲',
  '��' => '筱',
  '��' => '箐',
  '��' => '箦',
  '��' => '箧',
  '��' => '箸',
  '��' => '箬',
  '��' => '箝',
  '��' => '箨',
  '��' => '箅',
  '��' => '箪',
  '��' => '箜',
  '��' => '箢',
  '��' => '箫',
  '��' => '箴',
  '��' => '篑',
  '��' => '篁',
  '��' => '篌',
  '��' => '篝',
  '�' => '篚',
  '�' => '篥',
  '�' => '篦',
  '�' => '篪',
  '�' => '簌',
  '�' => '篾',
  '�' => '篼',
  '�' => '簏',
  '�' => '簖',
  '�' => '簋',
  '�@' => '鬇',
  '�A' => '鬉',
  '�B' => '鬊',
  '�C' => '鬋',
  '�D' => '鬌',
  '�E' => '鬍',
  '�F' => '鬎',
  '�G' => '鬐',
  '�H' => '鬑',
  '�I' => '鬒',
  '�J' => '鬔',
  '�K' => '鬕',
  '�L' => '鬖',
  '�M' => '鬗',
  '�N' => '鬘',
  '�O' => '鬙',
  '�P' => '鬚',
  '�Q' => '鬛',
  '�R' => '鬜',
  '�S' => '鬝',
  '�T' => '鬞',
  '�U' => '鬠',
  '�V' => '鬡',
  '�W' => '鬢',
  '�X' => '鬤',
  '�Y' => '鬥',
  '�Z' => '鬦',
  '�[' => '鬧',
  '�\\' => '鬨',
  '�]' => '鬩',
  '�^' => '鬪',
  '�_' => '鬫',
  '�`' => '鬬',
  '�a' => '鬭',
  '�b' => '鬮',
  '�c' => '鬰',
  '�d' => '鬱',
  '�e' => '鬳',
  '�f' => '鬴',
  '�g' => '鬵',
  '�h' => '鬶',
  '�i' => '鬷',
  '�j' => '鬸',
  '�k' => '鬹',
  '�l' => '鬺',
  '�m' => '鬽',
  '�n' => '鬾',
  '�o' => '鬿',
  '�p' => '魀',
  '�q' => '魆',
  '�r' => '魊',
  '�s' => '魋',
  '�t' => '魌',
  '�u' => '魎',
  '�v' => '魐',
  '�w' => '魒',
  '�x' => '魓',
  '�y' => '魕',
  '�z' => '魖',
  '�{' => '魗',
  '�|' => '魘',
  '�}' => '魙',
  '�~' => '魚',
  '�' => '魛',
  '�' => '魜',
  '�' => '魝',
  '�' => '魞',
  '�' => '魟',
  '�' => '魠',
  '�' => '魡',
  '�' => '魢',
  '�' => '魣',
  '�' => '魤',
  '�' => '魥',
  '�' => '魦',
  '�' => '魧',
  '�' => '魨',
  '�' => '魩',
  '�' => '魪',
  '�' => '魫',
  '�' => '魬',
  '�' => '魭',
  '�' => '魮',
  '�' => '魯',
  '�' => '魰',
  '�' => '魱',
  '�' => '魲',
  '�' => '魳',
  '�' => '魴',
  '�' => '魵',
  '�' => '魶',
  '�' => '魷',
  '�' => '魸',
  '�' => '魹',
  '�' => '魺',
  '�' => '魻',
  '�' => '簟',
  '�' => '簪',
  '�' => '簦',
  '�' => '簸',
  '�' => '籁',
  '�' => '籀',
  '�' => '臾',
  '�' => '舁',
  '�' => '舂',
  '�' => '舄',
  '�' => '臬',
  '�' => '衄',
  '�' => '舡',
  '�' => '舢',
  '�' => '舣',
  '�' => '舭',
  '�' => '舯',
  '�' => '舨',
  '�' => '舫',
  '�' => '舸',
  '�' => '舻',
  '�' => '舳',
  '�' => '舴',
  '�' => '舾',
  '�' => '艄',
  '�' => '艉',
  '�' => '艋',
  '�' => '艏',
  '�' => '艚',
  '�' => '艟',
  '�' => '艨',
  '�' => '衾',
  '�' => '袅',
  '��' => '袈',
  '��' => '裘',
  '��' => '裟',
  '��' => '襞',
  '��' => '羝',
  '��' => '羟',
  '��' => '羧',
  '��' => '羯',
  '��' => '羰',
  '��' => '羲',
  '��' => '籼',
  '��' => '敉',
  '��' => '粑',
  '��' => '粝',
  '��' => '粜',
  '��' => '粞',
  '��' => '粢',
  '��' => '粲',
  '��' => '粼',
  '��' => '粽',
  '��' => '糁',
  '��' => '糇',
  '��' => '糌',
  '��' => '糍',
  '��' => '糈',
  '��' => '糅',
  '��' => '糗',
  '��' => '糨',
  '��' => '艮',
  '��' => '暨',
  '��' => '羿',
  '��' => '翎',
  '��' => '翕',
  '��' => '翥',
  '��' => '翡',
  '��' => '翦',
  '��' => '翩',
  '��' => '翮',
  '��' => '翳',
  '��' => '糸',
  '��' => '絷',
  '��' => '綦',
  '��' => '綮',
  '��' => '繇',
  '��' => '纛',
  '��' => '麸',
  '��' => '麴',
  '��' => '赳',
  '��' => '趄',
  '��' => '趔',
  '��' => '趑',
  '�' => '趱',
  '�' => '赧',
  '�' => '赭',
  '�' => '豇',
  '�' => '豉',
  '�' => '酊',
  '�' => '酐',
  '�' => '酎',
  '�' => '酏',
  '�' => '酤',
  '�@' => '魼',
  '�A' => '魽',
  '�B' => '魾',
  '�C' => '魿',
  '�D' => '鮀',
  '�E' => '鮁',
  '�F' => '鮂',
  '�G' => '鮃',
  '�H' => '鮄',
  '�I' => '鮅',
  '�J' => '鮆',
  '�K' => '鮇',
  '�L' => '鮈',
  '�M' => '鮉',
  '�N' => '鮊',
  '�O' => '鮋',
  '�P' => '鮌',
  '�Q' => '鮍',
  '�R' => '鮎',
  '�S' => '鮏',
  '�T' => '鮐',
  '�U' => '鮑',
  '�V' => '鮒',
  '�W' => '鮓',
  '�X' => '鮔',
  '�Y' => '鮕',
  '�Z' => '鮖',
  '�[' => '鮗',
  '�\\' => '鮘',
  '�]' => '鮙',
  '�^' => '鮚',
  '�_' => '鮛',
  '�`' => '鮜',
  '�a' => '鮝',
  '�b' => '鮞',
  '�c' => '鮟',
  '�d' => '鮠',
  '�e' => '鮡',
  '�f' => '鮢',
  '�g' => '鮣',
  '�h' => '鮤',
  '�i' => '鮥',
  '�j' => '鮦',
  '�k' => '鮧',
  '�l' => '鮨',
  '�m' => '鮩',
  '�n' => '鮪',
  '�o' => '鮫',
  '�p' => '鮬',
  '�q' => '鮭',
  '�r' => '鮮',
  '�s' => '鮯',
  '�t' => '鮰',
  '�u' => '鮱',
  '�v' => '鮲',
  '�w' => '鮳',
  '�x' => '鮴',
  '�y' => '鮵',
  '�z' => '鮶',
  '�{' => '鮷',
  '�|' => '鮸',
  '�}' => '鮹',
  '�~' => '鮺',
  '��' => '鮻',
  '��' => '鮼',
  '��' => '鮽',
  '��' => '鮾',
  '��' => '鮿',
  '��' => '鯀',
  '��' => '鯁',
  '��' => '鯂',
  '��' => '鯃',
  '��' => '鯄',
  '��' => '鯅',
  '��' => '鯆',
  '��' => '鯇',
  '��' => '鯈',
  '��' => '鯉',
  '��' => '鯊',
  '��' => '鯋',
  '��' => '鯌',
  '��' => '鯍',
  '��' => '鯎',
  '��' => '鯏',
  '��' => '鯐',
  '��' => '鯑',
  '��' => '鯒',
  '��' => '鯓',
  '��' => '鯔',
  '��' => '鯕',
  '��' => '鯖',
  '��' => '鯗',
  '��' => '鯘',
  '��' => '鯙',
  '��' => '鯚',
  '��' => '鯛',
  '��' => '酢',
  '��' => '酡',
  '��' => '酰',
  '��' => '酩',
  '��' => '酯',
  '��' => '酽',
  '��' => '酾',
  '��' => '酲',
  '��' => '酴',
  '��' => '酹',
  '��' => '醌',
  '��' => '醅',
  '��' => '醐',
  '��' => '醍',
  '��' => '醑',
  '��' => '醢',
  '��' => '醣',
  '��' => '醪',
  '��' => '醭',
  '��' => '醮',
  '��' => '醯',
  '��' => '醵',
  '��' => '醴',
  '��' => '醺',
  '��' => '豕',
  '��' => '鹾',
  '��' => '趸',
  '��' => '跫',
  '��' => '踅',
  '��' => '蹙',
  '��' => '蹩',
  '��' => '趵',
  '��' => '趿',
  '��' => '趼',
  '��' => '趺',
  '��' => '跄',
  '��' => '跖',
  '��' => '跗',
  '��' => '跚',
  '��' => '跞',
  '��' => '跎',
  '��' => '跏',
  '��' => '跛',
  '��' => '跆',
  '��' => '跬',
  '��' => '跷',
  '��' => '跸',
  '��' => '跣',
  '��' => '跹',
  '��' => '跻',
  '��' => '跤',
  '��' => '踉',
  '��' => '跽',
  '��' => '踔',
  '��' => '踝',
  '��' => '踟',
  '��' => '踬',
  '��' => '踮',
  '��' => '踣',
  '��' => '踯',
  '��' => '踺',
  '��' => '蹀',
  '��' => '踹',
  '��' => '踵',
  '��' => '踽',
  '��' => '踱',
  '��' => '蹉',
  '��' => '蹁',
  '��' => '蹂',
  '��' => '蹑',
  '��' => '蹒',
  '��' => '蹊',
  '��' => '蹰',
  '��' => '蹶',
  '��' => '蹼',
  '��' => '蹯',
  '��' => '蹴',
  '��' => '躅',
  '��' => '躏',
  '��' => '躔',
  '��' => '躐',
  '��' => '躜',
  '��' => '躞',
  '��' => '豸',
  '��' => '貂',
  '��' => '貊',
  '��' => '貅',
  '��' => '貘',
  '��' => '貔',
  '��' => '斛',
  '��' => '觖',
  '��' => '觞',
  '��' => '觚',
  '��' => '觜',
  '�@' => '鯜',
  '�A' => '鯝',
  '�B' => '鯞',
  '�C' => '鯟',
  '�D' => '鯠',
  '�E' => '鯡',
  '�F' => '鯢',
  '�G' => '鯣',
  '�H' => '鯤',
  '�I' => '鯥',
  '�J' => '鯦',
  '�K' => '鯧',
  '�L' => '鯨',
  '�M' => '鯩',
  '�N' => '鯪',
  '�O' => '鯫',
  '�P' => '鯬',
  '�Q' => '鯭',
  '�R' => '鯮',
  '�S' => '鯯',
  '�T' => '鯰',
  '�U' => '鯱',
  '�V' => '鯲',
  '�W' => '鯳',
  '�X' => '鯴',
  '�Y' => '鯵',
  '�Z' => '鯶',
  '�[' => '鯷',
  '�\\' => '鯸',
  '�]' => '鯹',
  '�^' => '鯺',
  '�_' => '鯻',
  '�`' => '鯼',
  '�a' => '鯽',
  '�b' => '鯾',
  '�c' => '鯿',
  '�d' => '鰀',
  '�e' => '鰁',
  '�f' => '鰂',
  '�g' => '鰃',
  '�h' => '鰄',
  '�i' => '鰅',
  '�j' => '鰆',
  '�k' => '鰇',
  '�l' => '鰈',
  '�m' => '鰉',
  '�n' => '鰊',
  '�o' => '鰋',
  '�p' => '鰌',
  '�q' => '鰍',
  '�r' => '鰎',
  '�s' => '鰏',
  '�t' => '鰐',
  '�u' => '鰑',
  '�v' => '鰒',
  '�w' => '鰓',
  '�x' => '鰔',
  '�y' => '鰕',
  '�z' => '鰖',
  '�{' => '鰗',
  '�|' => '鰘',
  '�}' => '鰙',
  '�~' => '鰚',
  '��' => '鰛',
  '��' => '鰜',
  '��' => '鰝',
  '��' => '鰞',
  '��' => '鰟',
  '��' => '鰠',
  '��' => '鰡',
  '��' => '鰢',
  '��' => '鰣',
  '��' => '鰤',
  '��' => '鰥',
  '��' => '鰦',
  '��' => '鰧',
  '��' => '鰨',
  '��' => '鰩',
  '��' => '鰪',
  '��' => '鰫',
  '��' => '鰬',
  '��' => '鰭',
  '��' => '鰮',
  '��' => '鰯',
  '��' => '鰰',
  '��' => '鰱',
  '��' => '鰲',
  '��' => '鰳',
  '��' => '鰴',
  '��' => '鰵',
  '��' => '鰶',
  '��' => '鰷',
  '��' => '鰸',
  '��' => '鰹',
  '��' => '鰺',
  '��' => '鰻',
  '��' => '觥',
  '��' => '觫',
  '��' => '觯',
  '��' => '訾',
  '��' => '謦',
  '��' => '靓',
  '��' => '雩',
  '��' => '雳',
  '��' => '雯',
  '��' => '霆',
  '��' => '霁',
  '��' => '霈',
  '��' => '霏',
  '��' => '霎',
  '��' => '霪',
  '��' => '霭',
  '��' => '霰',
  '��' => '霾',
  '��' => '龀',
  '��' => '龃',
  '��' => '龅',
  '��' => '龆',
  '��' => '龇',
  '��' => '龈',
  '��' => '龉',
  '��' => '龊',
  '��' => '龌',
  '��' => '黾',
  '��' => '鼋',
  '��' => '鼍',
  '��' => '隹',
  '��' => '隼',
  '��' => '隽',
  '��' => '雎',
  '��' => '雒',
  '��' => '瞿',
  '��' => '雠',
  '��' => '銎',
  '��' => '銮',
  '��' => '鋈',
  '��' => '錾',
  '��' => '鍪',
  '��' => '鏊',
  '��' => '鎏',
  '��' => '鐾',
  '��' => '鑫',
  '��' => '鱿',
  '��' => '鲂',
  '��' => '鲅',
  '��' => '鲆',
  '��' => '鲇',
  '��' => '鲈',
  '��' => '稣',
  '��' => '鲋',
  '��' => '鲎',
  '��' => '鲐',
  '��' => '鲑',
  '��' => '鲒',
  '��' => '鲔',
  '��' => '鲕',
  '��' => '鲚',
  '��' => '鲛',
  '��' => '鲞',
  '��' => '鲟',
  '��' => '鲠',
  '��' => '鲡',
  '��' => '鲢',
  '��' => '鲣',
  '��' => '鲥',
  '��' => '鲦',
  '��' => '鲧',
  '��' => '鲨',
  '��' => '鲩',
  '��' => '鲫',
  '��' => '鲭',
  '��' => '鲮',
  '��' => '鲰',
  '��' => '鲱',
  '��' => '鲲',
  '��' => '鲳',
  '��' => '鲴',
  '��' => '鲵',
  '��' => '鲶',
  '��' => '鲷',
  '��' => '鲺',
  '��' => '鲻',
  '��' => '鲼',
  '��' => '鲽',
  '��' => '鳄',
  '��' => '鳅',
  '��' => '鳆',
  '��' => '鳇',
  '��' => '鳊',
  '��' => '鳋',
  '�@' => '鰼',
  '�A' => '鰽',
  '�B' => '鰾',
  '�C' => '鰿',
  '�D' => '鱀',
  '�E' => '鱁',
  '�F' => '鱂',
  '�G' => '鱃',
  '�H' => '鱄',
  '�I' => '鱅',
  '�J' => '鱆',
  '�K' => '鱇',
  '�L' => '鱈',
  '�M' => '鱉',
  '�N' => '鱊',
  '�O' => '鱋',
  '�P' => '鱌',
  '�Q' => '鱍',
  '�R' => '鱎',
  '�S' => '鱏',
  '�T' => '鱐',
  '�U' => '鱑',
  '�V' => '鱒',
  '�W' => '鱓',
  '�X' => '鱔',
  '�Y' => '鱕',
  '�Z' => '鱖',
  '�[' => '鱗',
  '�\\' => '鱘',
  '�]' => '鱙',
  '�^' => '鱚',
  '�_' => '鱛',
  '�`' => '鱜',
  '�a' => '鱝',
  '�b' => '鱞',
  '�c' => '鱟',
  '�d' => '鱠',
  '�e' => '鱡',
  '�f' => '鱢',
  '�g' => '鱣',
  '�h' => '鱤',
  '�i' => '鱥',
  '�j' => '鱦',
  '�k' => '鱧',
  '�l' => '鱨',
  '�m' => '鱩',
  '�n' => '鱪',
  '�o' => '鱫',
  '�p' => '鱬',
  '�q' => '鱭',
  '�r' => '鱮',
  '�s' => '鱯',
  '�t' => '鱰',
  '�u' => '鱱',
  '�v' => '鱲',
  '�w' => '鱳',
  '�x' => '鱴',
  '�y' => '鱵',
  '�z' => '鱶',
  '�{' => '鱷',
  '�|' => '鱸',
  '�}' => '鱹',
  '�~' => '鱺',
  '��' => '鱻',
  '��' => '鱽',
  '��' => '鱾',
  '��' => '鲀',
  '��' => '鲃',
  '��' => '鲄',
  '��' => '鲉',
  '��' => '鲊',
  '��' => '鲌',
  '��' => '鲏',
  '��' => '鲓',
  '��' => '鲖',
  '��' => '鲗',
  '��' => '鲘',
  '��' => '鲙',
  '��' => '鲝',
  '��' => '鲪',
  '��' => '鲬',
  '��' => '鲯',
  '��' => '鲹',
  '��' => '鲾',
  '��' => '鲿',
  '��' => '鳀',
  '��' => '鳁',
  '��' => '鳂',
  '��' => '鳈',
  '��' => '鳉',
  '��' => '鳑',
  '��' => '鳒',
  '��' => '鳚',
  '��' => '鳛',
  '��' => '鳠',
  '��' => '鳡',
  '��' => '鳌',
  '��' => '鳍',
  '��' => '鳎',
  '��' => '鳏',
  '��' => '鳐',
  '��' => '鳓',
  '��' => '鳔',
  '��' => '鳕',
  '��' => '鳗',
  '��' => '鳘',
  '��' => '鳙',
  '��' => '鳜',
  '��' => '鳝',
  '��' => '鳟',
  '��' => '鳢',
  '��' => '靼',
  '��' => '鞅',
  '��' => '鞑',
  '��' => '鞒',
  '��' => '鞔',
  '��' => '鞯',
  '��' => '鞫',
  '��' => '鞣',
  '��' => '鞲',
  '��' => '鞴',
  '��' => '骱',
  '��' => '骰',
  '��' => '骷',
  '��' => '鹘',
  '��' => '骶',
  '��' => '骺',
  '��' => '骼',
  '��' => '髁',
  '��' => '髀',
  '��' => '髅',
  '��' => '髂',
  '��' => '髋',
  '��' => '髌',
  '��' => '髑',
  '��' => '魅',
  '��' => '魃',
  '��' => '魇',
  '��' => '魉',
  '��' => '魈',
  '��' => '魍',
  '��' => '魑',
  '��' => '飨',
  '��' => '餍',
  '��' => '餮',
  '��' => '饕',
  '��' => '饔',
  '��' => '髟',
  '��' => '髡',
  '��' => '髦',
  '��' => '髯',
  '��' => '髫',
  '��' => '髻',
  '��' => '髭',
  '��' => '髹',
  '��' => '鬈',
  '��' => '鬏',
  '��' => '鬓',
  '��' => '鬟',
  '��' => '鬣',
  '��' => '麽',
  '��' => '麾',
  '��' => '縻',
  '��' => '麂',
  '��' => '麇',
  '��' => '麈',
  '��' => '麋',
  '��' => '麒',
  '��' => '鏖',
  '��' => '麝',
  '��' => '麟',
  '��' => '黛',
  '��' => '黜',
  '��' => '黝',
  '��' => '黠',
  '��' => '黟',
  '��' => '黢',
  '��' => '黩',
  '��' => '黧',
  '��' => '黥',
  '��' => '黪',
  '��' => '黯',
  '��' => '鼢',
  '��' => '鼬',
  '��' => '鼯',
  '��' => '鼹',
  '��' => '鼷',
  '��' => '鼽',
  '��' => '鼾',
  '��' => '齄',
  '�@' => '鳣',
  '�A' => '鳤',
  '�B' => '鳥',
  '�C' => '鳦',
  '�D' => '鳧',
  '�E' => '鳨',
  '�F' => '鳩',
  '�G' => '鳪',
  '�H' => '鳫',
  '�I' => '鳬',
  '�J' => '鳭',
  '�K' => '鳮',
  '�L' => '鳯',
  '�M' => '鳰',
  '�N' => '鳱',
  '�O' => '鳲',
  '�P' => '鳳',
  '�Q' => '鳴',
  '�R' => '鳵',
  '�S' => '鳶',
  '�T' => '鳷',
  '�U' => '鳸',
  '�V' => '鳹',
  '�W' => '鳺',
  '�X' => '鳻',
  '�Y' => '鳼',
  '�Z' => '鳽',
  '�[' => '鳾',
  '�\\' => '鳿',
  '�]' => '鴀',
  '�^' => '鴁',
  '�_' => '鴂',
  '�`' => '鴃',
  '�a' => '鴄',
  '�b' => '鴅',
  '�c' => '鴆',
  '�d' => '鴇',
  '�e' => '鴈',
  '�f' => '鴉',
  '�g' => '鴊',
  '�h' => '鴋',
  '�i' => '鴌',
  '�j' => '鴍',
  '�k' => '鴎',
  '�l' => '鴏',
  '�m' => '鴐',
  '�n' => '鴑',
  '�o' => '鴒',
  '�p' => '鴓',
  '�q' => '鴔',
  '�r' => '鴕',
  '�s' => '鴖',
  '�t' => '鴗',
  '�u' => '鴘',
  '�v' => '鴙',
  '�w' => '鴚',
  '�x' => '鴛',
  '�y' => '鴜',
  '�z' => '鴝',
  '�{' => '鴞',
  '�|' => '鴟',
  '�}' => '鴠',
  '�~' => '鴡',
  '��' => '鴢',
  '��' => '鴣',
  '��' => '鴤',
  '��' => '鴥',
  '��' => '鴦',
  '��' => '鴧',
  '��' => '鴨',
  '��' => '鴩',
  '��' => '鴪',
  '��' => '鴫',
  '��' => '鴬',
  '��' => '鴭',
  '��' => '鴮',
  '��' => '鴯',
  '��' => '鴰',
  '��' => '鴱',
  '��' => '鴲',
  '��' => '鴳',
  '��' => '鴴',
  '��' => '鴵',
  '��' => '鴶',
  '��' => '鴷',
  '��' => '鴸',
  '��' => '鴹',
  '��' => '鴺',
  '��' => '鴻',
  '��' => '鴼',
  '��' => '鴽',
  '��' => '鴾',
  '��' => '鴿',
  '��' => '鵀',
  '��' => '鵁',
  '��' => '鵂',
  '�@' => '鵃',
  '�A' => '鵄',
  '�B' => '鵅',
  '�C' => '鵆',
  '�D' => '鵇',
  '�E' => '鵈',
  '�F' => '鵉',
  '�G' => '鵊',
  '�H' => '鵋',
  '�I' => '鵌',
  '�J' => '鵍',
  '�K' => '鵎',
  '�L' => '鵏',
  '�M' => '鵐',
  '�N' => '鵑',
  '�O' => '鵒',
  '�P' => '鵓',
  '�Q' => '鵔',
  '�R' => '鵕',
  '�S' => '鵖',
  '�T' => '鵗',
  '�U' => '鵘',
  '�V' => '鵙',
  '�W' => '鵚',
  '�X' => '鵛',
  '�Y' => '鵜',
  '�Z' => '鵝',
  '�[' => '鵞',
  '�\\' => '鵟',
  '�]' => '鵠',
  '�^' => '鵡',
  '�_' => '鵢',
  '�`' => '鵣',
  '�a' => '鵤',
  '�b' => '鵥',
  '�c' => '鵦',
  '�d' => '鵧',
  '�e' => '鵨',
  '�f' => '鵩',
  '�g' => '鵪',
  '�h' => '鵫',
  '�i' => '鵬',
  '�j' => '鵭',
  '�k' => '鵮',
  '�l' => '鵯',
  '�m' => '鵰',
  '�n' => '鵱',
  '�o' => '鵲',
  '�p' => '鵳',
  '�q' => '鵴',
  '�r' => '鵵',
  '�s' => '鵶',
  '�t' => '鵷',
  '�u' => '鵸',
  '�v' => '鵹',
  '�w' => '鵺',
  '�x' => '鵻',
  '�y' => '鵼',
  '�z' => '鵽',
  '�{' => '鵾',
  '�|' => '鵿',
  '�}' => '鶀',
  '�~' => '鶁',
  '��' => '鶂',
  '��' => '鶃',
  '��' => '鶄',
  '��' => '鶅',
  '��' => '鶆',
  '��' => '鶇',
  '��' => '鶈',
  '��' => '鶉',
  '��' => '鶊',
  '��' => '鶋',
  '��' => '鶌',
  '��' => '鶍',
  '��' => '鶎',
  '��' => '鶏',
  '��' => '鶐',
  '��' => '鶑',
  '��' => '鶒',
  '��' => '鶓',
  '��' => '鶔',
  '��' => '鶕',
  '��' => '鶖',
  '��' => '鶗',
  '��' => '鶘',
  '��' => '鶙',
  '��' => '鶚',
  '��' => '鶛',
  '��' => '鶜',
  '��' => '鶝',
  '��' => '鶞',
  '��' => '鶟',
  '��' => '鶠',
  '��' => '鶡',
  '��' => '鶢',
  '�@' => '鶣',
  '�A' => '鶤',
  '�B' => '鶥',
  '�C' => '鶦',
  '�D' => '鶧',
  '�E' => '鶨',
  '�F' => '鶩',
  '�G' => '鶪',
  '�H' => '鶫',
  '�I' => '鶬',
  '�J' => '鶭',
  '�K' => '鶮',
  '�L' => '鶯',
  '�M' => '鶰',
  '�N' => '鶱',
  '�O' => '鶲',
  '�P' => '鶳',
  '�Q' => '鶴',
  '�R' => '鶵',
  '�S' => '鶶',
  '�T' => '鶷',
  '�U' => '鶸',
  '�V' => '鶹',
  '�W' => '鶺',
  '�X' => '鶻',
  '�Y' => '鶼',
  '�Z' => '鶽',
  '�[' => '鶾',
  '�\\' => '鶿',
  '�]' => '鷀',
  '�^' => '鷁',
  '�_' => '鷂',
  '�`' => '鷃',
  '�a' => '鷄',
  '�b' => '鷅',
  '�c' => '鷆',
  '�d' => '鷇',
  '�e' => '鷈',
  '�f' => '鷉',
  '�g' => '鷊',
  '�h' => '鷋',
  '�i' => '鷌',
  '�j' => '鷍',
  '�k' => '鷎',
  '�l' => '鷏',
  '�m' => '鷐',
  '�n' => '鷑',
  '�o' => '鷒',
  '�p' => '鷓',
  '�q' => '鷔',
  '�r' => '鷕',
  '�s' => '鷖',
  '�t' => '鷗',
  '�u' => '鷘',
  '�v' => '鷙',
  '�w' => '鷚',
  '�x' => '鷛',
  '�y' => '鷜',
  '�z' => '鷝',
  '�{' => '鷞',
  '�|' => '鷟',
  '�}' => '鷠',
  '�~' => '鷡',
  '��' => '鷢',
  '��' => '鷣',
  '��' => '鷤',
  '��' => '鷥',
  '��' => '鷦',
  '��' => '鷧',
  '��' => '鷨',
  '��' => '鷩',
  '��' => '鷪',
  '��' => '鷫',
  '��' => '鷬',
  '��' => '鷭',
  '��' => '鷮',
  '��' => '鷯',
  '��' => '鷰',
  '��' => '鷱',
  '��' => '鷲',
  '��' => '鷳',
  '��' => '鷴',
  '��' => '鷵',
  '��' => '鷶',
  '��' => '鷷',
  '��' => '鷸',
  '��' => '鷹',
  '��' => '鷺',
  '��' => '鷻',
  '��' => '鷼',
  '��' => '鷽',
  '��' => '鷾',
  '��' => '鷿',
  '��' => '鸀',
  '��' => '鸁',
  '��' => '鸂',
  '�@' => '鸃',
  '�A' => '鸄',
  '�B' => '鸅',
  '�C' => '鸆',
  '�D' => '鸇',
  '�E' => '鸈',
  '�F' => '鸉',
  '�G' => '鸊',
  '�H' => '鸋',
  '�I' => '鸌',
  '�J' => '鸍',
  '�K' => '鸎',
  '�L' => '鸏',
  '�M' => '鸐',
  '�N' => '鸑',
  '�O' => '鸒',
  '�P' => '鸓',
  '�Q' => '鸔',
  '�R' => '鸕',
  '�S' => '鸖',
  '�T' => '鸗',
  '�U' => '鸘',
  '�V' => '鸙',
  '�W' => '鸚',
  '�X' => '鸛',
  '�Y' => '鸜',
  '�Z' => '鸝',
  '�[' => '鸞',
  '�\\' => '鸤',
  '�]' => '鸧',
  '�^' => '鸮',
  '�_' => '鸰',
  '�`' => '鸴',
  '�a' => '鸻',
  '�b' => '鸼',
  '�c' => '鹀',
  '�d' => '鹍',
  '�e' => '鹐',
  '�f' => '鹒',
  '�g' => '鹓',
  '�h' => '鹔',
  '�i' => '鹖',
  '�j' => '鹙',
  '�k' => '鹝',
  '�l' => '鹟',
  '�m' => '鹠',
  '�n' => '鹡',
  '�o' => '鹢',
  '�p' => '鹥',
  '�q' => '鹮',
  '�r' => '鹯',
  '�s' => '鹲',
  '�t' => '鹴',
  '�u' => '鹵',
  '�v' => '鹶',
  '�w' => '鹷',
  '�x' => '鹸',
  '�y' => '鹹',
  '�z' => '鹺',
  '�{' => '鹻',
  '�|' => '鹼',
  '�}' => '鹽',
  '�~' => '麀',
  '��' => '麁',
  '��' => '麃',
  '��' => '麄',
  '��' => '麅',
  '��' => '麆',
  '��' => '麉',
  '��' => '麊',
  '��' => '麌',
  '��' => '麍',
  '��' => '麎',
  '��' => '麏',
  '��' => '麐',
  '��' => '麑',
  '��' => '麔',
  '��' => '麕',
  '��' => '麖',
  '��' => '麗',
  '��' => '麘',
  '��' => '麙',
  '��' => '麚',
  '��' => '麛',
  '��' => '麜',
  '��' => '麞',
  '��' => '麠',
  '��' => '麡',
  '��' => '麢',
  '��' => '麣',
  '��' => '麤',
  '��' => '麥',
  '��' => '麧',
  '��' => '麨',
  '��' => '麩',
  '��' => '麪',
  '�@' => '麫',
  '�A' => '麬',
  '�B' => '麭',
  '�C' => '麮',
  '�D' => '麯',
  '�E' => '麰',
  '�F' => '麱',
  '�G' => '麲',
  '�H' => '麳',
  '�I' => '麵',
  '�J' => '麶',
  '�K' => '麷',
  '�L' => '麹',
  '�M' => '麺',
  '�N' => '麼',
  '�O' => '麿',
  '�P' => '黀',
  '�Q' => '黁',
  '�R' => '黂',
  '�S' => '黃',
  '�T' => '黅',
  '�U' => '黆',
  '�V' => '黇',
  '�W' => '黈',
  '�X' => '黊',
  '�Y' => '黋',
  '�Z' => '黌',
  '�[' => '黐',
  '�\\' => '黒',
  '�]' => '黓',
  '�^' => '黕',
  '�_' => '黖',
  '�`' => '黗',
  '�a' => '黙',
  '�b' => '黚',
  '�c' => '點',
  '�d' => '黡',
  '�e' => '黣',
  '�f' => '黤',
  '�g' => '黦',
  '�h' => '黨',
  '�i' => '黫',
  '�j' => '黬',
  '�k' => '黭',
  '�l' => '黮',
  '�m' => '黰',
  '�n' => '黱',
  '�o' => '黲',
  '�p' => '黳',
  '�q' => '黴',
  '�r' => '黵',
  '�s' => '黶',
  '�t' => '黷',
  '�u' => '黸',
  '�v' => '黺',
  '�w' => '黽',
  '�x' => '黿',
  '�y' => '鼀',
  '�z' => '鼁',
  '�{' => '鼂',
  '�|' => '鼃',
  '�}' => '鼄',
  '�~' => '鼅',
  '��' => '鼆',
  '��' => '鼇',
  '��' => '鼈',
  '��' => '鼉',
  '��' => '鼊',
  '��' => '鼌',
  '��' => '鼏',
  '��' => '鼑',
  '��' => '鼒',
  '��' => '鼔',
  '��' => '鼕',
  '��' => '鼖',
  '��' => '鼘',
  '��' => '鼚',
  '��' => '鼛',
  '��' => '鼜',
  '��' => '鼝',
  '��' => '鼞',
  '��' => '鼟',
  '��' => '鼡',
  '��' => '鼣',
  '��' => '鼤',
  '��' => '鼥',
  '��' => '鼦',
  '��' => '鼧',
  '��' => '鼨',
  '��' => '鼩',
  '��' => '鼪',
  '��' => '鼫',
  '��' => '鼭',
  '��' => '鼮',
  '��' => '鼰',
  '��' => '鼱',
  '�@' => '鼲',
  '�A' => '鼳',
  '�B' => '鼴',
  '�C' => '鼵',
  '�D' => '鼶',
  '�E' => '鼸',
  '�F' => '鼺',
  '�G' => '鼼',
  '�H' => '鼿',
  '�I' => '齀',
  '�J' => '齁',
  '�K' => '齂',
  '�L' => '齃',
  '�M' => '齅',
  '�N' => '齆',
  '�O' => '齇',
  '�P' => '齈',
  '�Q' => '齉',
  '�R' => '齊',
  '�S' => '齋',
  '�T' => '齌',
  '�U' => '齍',
  '�V' => '齎',
  '�W' => '齏',
  '�X' => '齒',
  '�Y' => '齓',
  '�Z' => '齔',
  '�[' => '齕',
  '�\\' => '齖',
  '�]' => '齗',
  '�^' => '齘',
  '�_' => '齙',
  '�`' => '齚',
  '�a' => '齛',
  '�b' => '齜',
  '�c' => '齝',
  '�d' => '齞',
  '�e' => '齟',
  '�f' => '齠',
  '�g' => '齡',
  '�h' => '齢',
  '�i' => '齣',
  '�j' => '齤',
  '�k' => '齥',
  '�l' => '齦',
  '�m' => '齧',
  '�n' => '齨',
  '�o' => '齩',
  '�p' => '齪',
  '�q' => '齫',
  '�r' => '齬',
  '�s' => '齭',
  '�t' => '齮',
  '�u' => '齯',
  '�v' => '齰',
  '�w' => '齱',
  '�x' => '齲',
  '�y' => '齳',
  '�z' => '齴',
  '�{' => '齵',
  '�|' => '齶',
  '�}' => '齷',
  '�~' => '齸',
  '��' => '齹',
  '��' => '齺',
  '��' => '齻',
  '��' => '齼',
  '��' => '齽',
  '��' => '齾',
  '��' => '龁',
  '��' => '龂',
  '��' => '龍',
  '��' => '龎',
  '��' => '龏',
  '��' => '龐',
  '��' => '龑',
  '��' => '龒',
  '��' => '龓',
  '��' => '龔',
  '��' => '龕',
  '��' => '龖',
  '��' => '龗',
  '��' => '龘',
  '��' => '龜',
  '��' => '龝',
  '��' => '龞',
  '��' => '龡',
  '��' => '龢',
  '��' => '龣',
  '��' => '龤',
  '��' => '龥',
  '��' => '郎',
  '��' => '凉',
  '��' => '秊',
  '��' => '裏',
  '��' => '隣',
  '�@' => '兀',
  '�A' => '嗀',
  '�B' => '﨎',
  '�C' => '﨏',
  '�D' => '﨑',
  '�E' => '﨓',
  '�F' => '﨔',
  '�G' => '礼',
  '�H' => '﨟',
  '�I' => '蘒',
  '�J' => '﨡',
  '�K' => '﨣',
  '�L' => '﨤',
  '�M' => '﨧',
  '�N' => '﨨',
  '�O' => '﨩',
);

$result =& $data;
unset($data);

return $result;
PKϤ$Z�`i���/polyfill-iconv/Resources/charset/from.cp852.phpnu�[���<?php

static $data = array (
  '' => '',
  '' => '',
  '' => '',
  '' => '',
  '' => '',
  '' => '',
  '' => '',
  '' => '',
  '' => '',
  '	' => '	',
  '
' => '
',
  '' => '',
  '' => '',
  '
' => '
',
  '' => '',
  '' => '',
  '' => '',
  '' => '',
  '' => '',
  '' => '',
  '' => '',
  '' => '',
  '' => '',
  '' => '',
  '' => '',
  '' => '',
  '' => '',
  '' => '',
  '' => '',
  '' => '',
  '' => '',
  '' => '',
  ' ' => ' ',
  '!' => '!',
  '"' => '"',
  '#' => '#',
  '$' => '$',
  '%' => '%',
  '&' => '&',
  '\'' => '\'',
  '(' => '(',
  ')' => ')',
  '*' => '*',
  '+' => '+',
  ',' => ',',
  '-' => '-',
  '.' => '.',
  '/' => '/',
  0 => '0',
  1 => '1',
  2 => '2',
  3 => '3',
  4 => '4',
  5 => '5',
  6 => '6',
  7 => '7',
  8 => '8',
  9 => '9',
  ':' => ':',
  ';' => ';',
  '<' => '<',
  '=' => '=',
  '>' => '>',
  '?' => '?',
  '@' => '@',
  'A' => 'A',
  'B' => 'B',
  'C' => 'C',
  'D' => 'D',
  'E' => 'E',
  'F' => 'F',
  'G' => 'G',
  'H' => 'H',
  'I' => 'I',
  'J' => 'J',
  'K' => 'K',
  'L' => 'L',
  'M' => 'M',
  'N' => 'N',
  'O' => 'O',
  'P' => 'P',
  'Q' => 'Q',
  'R' => 'R',
  'S' => 'S',
  'T' => 'T',
  'U' => 'U',
  'V' => 'V',
  'W' => 'W',
  'X' => 'X',
  'Y' => 'Y',
  'Z' => 'Z',
  '[' => '[',
  '\\' => '\\',
  ']' => ']',
  '^' => '^',
  '_' => '_',
  '`' => '`',
  'a' => 'a',
  'b' => 'b',
  'c' => 'c',
  'd' => 'd',
  'e' => 'e',
  'f' => 'f',
  'g' => 'g',
  'h' => 'h',
  'i' => 'i',
  'j' => 'j',
  'k' => 'k',
  'l' => 'l',
  'm' => 'm',
  'n' => 'n',
  'o' => 'o',
  'p' => 'p',
  'q' => 'q',
  'r' => 'r',
  's' => 's',
  't' => 't',
  'u' => 'u',
  'v' => 'v',
  'w' => 'w',
  'x' => 'x',
  'y' => 'y',
  'z' => 'z',
  '{' => '{',
  '|' => '|',
  '}' => '}',
  '~' => '~',
  '' => '',
  '�' => 'Ç',
  '�' => 'ü',
  '�' => 'é',
  '�' => 'â',
  '�' => 'ä',
  '�' => 'ů',
  '�' => 'ć',
  '�' => 'ç',
  '�' => 'ł',
  '�' => 'ë',
  '�' => 'Ő',
  '�' => 'ő',
  '�' => 'î',
  '�' => 'Ź',
  '�' => 'Ä',
  '�' => 'Ć',
  '�' => 'É',
  '�' => 'Ĺ',
  '�' => 'ĺ',
  '�' => 'ô',
  '�' => 'ö',
  '�' => 'Ľ',
  '�' => 'ľ',
  '�' => 'Ś',
  '�' => 'ś',
  '�' => 'Ö',
  '�' => 'Ü',
  '�' => 'Ť',
  '�' => 'ť',
  '�' => 'Ł',
  '�' => '×',
  '�' => 'č',
  '�' => 'á',
  '�' => 'í',
  '�' => 'ó',
  '�' => 'ú',
  '�' => 'Ą',
  '�' => 'ą',
  '�' => 'Ž',
  '�' => 'ž',
  '�' => 'Ę',
  '�' => 'ę',
  '�' => '¬',
  '�' => 'ź',
  '�' => 'Č',
  '�' => 'ş',
  '�' => '«',
  '�' => '»',
  '�' => '░',
  '�' => '▒',
  '�' => '▓',
  '�' => '│',
  '�' => '┤',
  '�' => 'Á',
  '�' => 'Â',
  '�' => 'Ě',
  '�' => 'Ş',
  '�' => '╣',
  '�' => '║',
  '�' => '╗',
  '�' => '╝',
  '�' => 'Ż',
  '�' => 'ż',
  '�' => '┐',
  '�' => '└',
  '�' => '┴',
  '�' => '┬',
  '�' => '├',
  '�' => '─',
  '�' => '┼',
  '�' => 'Ă',
  '�' => 'ă',
  '�' => '╚',
  '�' => '╔',
  '�' => '╩',
  '�' => '╦',
  '�' => '╠',
  '�' => '═',
  '�' => '╬',
  '�' => '¤',
  '�' => 'đ',
  '�' => 'Đ',
  '�' => 'Ď',
  '�' => 'Ë',
  '�' => 'ď',
  '�' => 'Ň',
  '�' => 'Í',
  '�' => 'Î',
  '�' => 'ě',
  '�' => '┘',
  '�' => '┌',
  '�' => '█',
  '�' => '▄',
  '�' => 'Ţ',
  '�' => 'Ů',
  '�' => '▀',
  '�' => 'Ó',
  '�' => 'ß',
  '�' => 'Ô',
  '�' => 'Ń',
  '�' => 'ń',
  '�' => 'ň',
  '�' => 'Š',
  '�' => 'š',
  '�' => 'Ŕ',
  '�' => 'Ú',
  '�' => 'ŕ',
  '�' => 'Ű',
  '�' => 'ý',
  '�' => 'Ý',
  '�' => 'ţ',
  '�' => '´',
  '�' => '­',
  '�' => '˝',
  '�' => '˛',
  '�' => 'ˇ',
  '�' => '˘',
  '�' => '§',
  '�' => '÷',
  '�' => '¸',
  '�' => '°',
  '�' => '¨',
  '�' => '˙',
  '�' => 'ű',
  '�' => 'Ř',
  '�' => 'ř',
  '�' => '■',
  '�' => ' ',
);

$result =& $data;
unset($data);

return $result;
PKϤ$ZxB
�0polyfill-iconv/Resources/charset/from.cp1006.phpnu�[���<?php

static $data = array (
  '' => '',
  '' => '',
  '' => '',
  '' => '',
  '' => '',
  '' => '',
  '' => '',
  '' => '',
  '' => '',
  '	' => '	',
  '
' => '
',
  '' => '',
  '' => '',
  '
' => '
',
  '' => '',
  '' => '',
  '' => '',
  '' => '',
  '' => '',
  '' => '',
  '' => '',
  '' => '',
  '' => '',
  '' => '',
  '' => '',
  '' => '',
  '' => '',
  '' => '',
  '' => '',
  '' => '',
  '' => '',
  '' => '',
  ' ' => ' ',
  '!' => '!',
  '"' => '"',
  '#' => '#',
  '$' => '$',
  '%' => '%',
  '&' => '&',
  '\'' => '\'',
  '(' => '(',
  ')' => ')',
  '*' => '*',
  '+' => '+',
  ',' => ',',
  '-' => '-',
  '.' => '.',
  '/' => '/',
  0 => '0',
  1 => '1',
  2 => '2',
  3 => '3',
  4 => '4',
  5 => '5',
  6 => '6',
  7 => '7',
  8 => '8',
  9 => '9',
  ':' => ':',
  ';' => ';',
  '<' => '<',
  '=' => '=',
  '>' => '>',
  '?' => '?',
  '@' => '@',
  'A' => 'A',
  'B' => 'B',
  'C' => 'C',
  'D' => 'D',
  'E' => 'E',
  'F' => 'F',
  'G' => 'G',
  'H' => 'H',
  'I' => 'I',
  'J' => 'J',
  'K' => 'K',
  'L' => 'L',
  'M' => 'M',
  'N' => 'N',
  'O' => 'O',
  'P' => 'P',
  'Q' => 'Q',
  'R' => 'R',
  'S' => 'S',
  'T' => 'T',
  'U' => 'U',
  'V' => 'V',
  'W' => 'W',
  'X' => 'X',
  'Y' => 'Y',
  'Z' => 'Z',
  '[' => '[',
  '\\' => '\\',
  ']' => ']',
  '^' => '^',
  '_' => '_',
  '`' => '`',
  'a' => 'a',
  'b' => 'b',
  'c' => 'c',
  'd' => 'd',
  'e' => 'e',
  'f' => 'f',
  'g' => 'g',
  'h' => 'h',
  'i' => 'i',
  'j' => 'j',
  'k' => 'k',
  'l' => 'l',
  'm' => 'm',
  'n' => 'n',
  'o' => 'o',
  'p' => 'p',
  'q' => 'q',
  'r' => 'r',
  's' => 's',
  't' => 't',
  'u' => 'u',
  'v' => 'v',
  'w' => 'w',
  'x' => 'x',
  'y' => 'y',
  'z' => 'z',
  '{' => '{',
  '|' => '|',
  '}' => '}',
  '~' => '~',
  '' => '',
  '�' => '€',
  '�' => '',
  '�' => '‚',
  '�' => 'ƒ',
  '�' => '„',
  '�' => '…',
  '�' => '†',
  '�' => '‡',
  '�' => 'ˆ',
  '�' => '‰',
  '�' => 'Š',
  '�' => '‹',
  '�' => 'Œ',
  '�' => '',
  '�' => 'Ž',
  '�' => '',
  '�' => '',
  '�' => '‘',
  '�' => '’',
  '�' => '“',
  '�' => '”',
  '�' => '•',
  '�' => '–',
  '�' => '—',
  '�' => '˜',
  '�' => '™',
  '�' => 'š',
  '�' => '›',
  '�' => 'œ',
  '�' => '',
  '�' => 'ž',
  '�' => 'Ÿ',
  '�' => ' ',
  '�' => '۰',
  '�' => '۱',
  '�' => '۲',
  '�' => '۳',
  '�' => '۴',
  '�' => '۵',
  '�' => '۶',
  '�' => '۷',
  '�' => '۸',
  '�' => '۹',
  '�' => '،',
  '�' => '؛',
  '�' => '­',
  '�' => '؟',
  '�' => 'ﺁ',
  '�' => 'ﺍ',
  '�' => 'ﺎ',
  '�' => 'ﺎ',
  '�' => 'ﺏ',
  '�' => 'ﺑ',
  '�' => 'ﭖ',
  '�' => 'ﭘ',
  '�' => 'ﺓ',
  '�' => 'ﺕ',
  '�' => 'ﺗ',
  '�' => 'ﭦ',
  '�' => 'ﭨ',
  '�' => 'ﺙ',
  '�' => 'ﺛ',
  '�' => 'ﺝ',
  '�' => 'ﺟ',
  '�' => 'ﭺ',
  '�' => 'ﭼ',
  '�' => 'ﺡ',
  '�' => 'ﺣ',
  '�' => 'ﺥ',
  '�' => 'ﺧ',
  '�' => 'ﺩ',
  '�' => 'ﮄ',
  '�' => 'ﺫ',
  '�' => 'ﺭ',
  '�' => 'ﮌ',
  '�' => 'ﺯ',
  '�' => 'ﮊ',
  '�' => 'ﺱ',
  '�' => 'ﺳ',
  '�' => 'ﺵ',
  '�' => 'ﺷ',
  '�' => 'ﺹ',
  '�' => 'ﺻ',
  '�' => 'ﺽ',
  '�' => 'ﺿ',
  '�' => 'ﻁ',
  '�' => 'ﻅ',
  '�' => 'ﻉ',
  '�' => 'ﻊ',
  '�' => 'ﻋ',
  '�' => 'ﻌ',
  '�' => 'ﻍ',
  '�' => 'ﻎ',
  '�' => 'ﻏ',
  '�' => 'ﻐ',
  '�' => 'ﻑ',
  '�' => 'ﻓ',
  '�' => 'ﻕ',
  '�' => 'ﻗ',
  '�' => 'ﻙ',
  '�' => 'ﻛ',
  '�' => 'ﮒ',
  '�' => 'ﮔ',
  '�' => 'ﻝ',
  '�' => 'ﻟ',
  '�' => 'ﻠ',
  '�' => 'ﻡ',
  '�' => 'ﻣ',
  '�' => 'ﮞ',
  '�' => 'ﻥ',
  '�' => 'ﻧ',
  '�' => 'ﺅ',
  '�' => 'ﻭ',
  '�' => 'ﮦ',
  '�' => 'ﮨ',
  '�' => 'ﮩ',
  '�' => 'ﮪ',
  '�' => 'ﺀ',
  '�' => 'ﺉ',
  '�' => 'ﺊ',
  '�' => 'ﺋ',
  '�' => 'ﻱ',
  '�' => 'ﻲ',
  '�' => 'ﻳ',
  '�' => 'ﮰ',
  '�' => 'ﮮ',
  '�' => 'ﹼ',
  '�' => 'ﹽ',
);

$result =& $data;
unset($data);

return $result;
PKϤ$Z	uň��0polyfill-iconv/Resources/charset/from.koi8-r.phpnu�[���<?php

static $data = array (
  '' => '',
  '' => '',
  '' => '',
  '' => '',
  '' => '',
  '' => '',
  '' => '',
  '' => '',
  '' => '',
  '	' => '	',
  '
' => '
',
  '' => '',
  '' => '',
  '
' => '
',
  '' => '',
  '' => '',
  '' => '',
  '' => '',
  '' => '',
  '' => '',
  '' => '',
  '' => '',
  '' => '',
  '' => '',
  '' => '',
  '' => '',
  '' => '',
  '' => '',
  '' => '',
  '' => '',
  '' => '',
  '' => '',
  ' ' => ' ',
  '!' => '!',
  '"' => '"',
  '#' => '#',
  '$' => '$',
  '%' => '%',
  '&' => '&',
  '\'' => '\'',
  '(' => '(',
  ')' => ')',
  '*' => '*',
  '+' => '+',
  ',' => ',',
  '-' => '-',
  '.' => '.',
  '/' => '/',
  0 => '0',
  1 => '1',
  2 => '2',
  3 => '3',
  4 => '4',
  5 => '5',
  6 => '6',
  7 => '7',
  8 => '8',
  9 => '9',
  ':' => ':',
  ';' => ';',
  '<' => '<',
  '=' => '=',
  '>' => '>',
  '?' => '?',
  '@' => '@',
  'A' => 'A',
  'B' => 'B',
  'C' => 'C',
  'D' => 'D',
  'E' => 'E',
  'F' => 'F',
  'G' => 'G',
  'H' => 'H',
  'I' => 'I',
  'J' => 'J',
  'K' => 'K',
  'L' => 'L',
  'M' => 'M',
  'N' => 'N',
  'O' => 'O',
  'P' => 'P',
  'Q' => 'Q',
  'R' => 'R',
  'S' => 'S',
  'T' => 'T',
  'U' => 'U',
  'V' => 'V',
  'W' => 'W',
  'X' => 'X',
  'Y' => 'Y',
  'Z' => 'Z',
  '[' => '[',
  '\\' => '\\',
  ']' => ']',
  '^' => '^',
  '_' => '_',
  '`' => '`',
  'a' => 'a',
  'b' => 'b',
  'c' => 'c',
  'd' => 'd',
  'e' => 'e',
  'f' => 'f',
  'g' => 'g',
  'h' => 'h',
  'i' => 'i',
  'j' => 'j',
  'k' => 'k',
  'l' => 'l',
  'm' => 'm',
  'n' => 'n',
  'o' => 'o',
  'p' => 'p',
  'q' => 'q',
  'r' => 'r',
  's' => 's',
  't' => 't',
  'u' => 'u',
  'v' => 'v',
  'w' => 'w',
  'x' => 'x',
  'y' => 'y',
  'z' => 'z',
  '{' => '{',
  '|' => '|',
  '}' => '}',
  '~' => '~',
  '' => '',
  '�' => '─',
  '�' => '│',
  '�' => '┌',
  '�' => '┐',
  '�' => '└',
  '�' => '┘',
  '�' => '├',
  '�' => '┤',
  '�' => '┬',
  '�' => '┴',
  '�' => '┼',
  '�' => '▀',
  '�' => '▄',
  '�' => '█',
  '�' => '▌',
  '�' => '▐',
  '�' => '░',
  '�' => '▒',
  '�' => '▓',
  '�' => '⌠',
  '�' => '■',
  '�' => '∙',
  '�' => '√',
  '�' => '≈',
  '�' => '≤',
  '�' => '≥',
  '�' => ' ',
  '�' => '⌡',
  '�' => '°',
  '�' => '²',
  '�' => '·',
  '�' => '÷',
  '�' => '═',
  '�' => '║',
  '�' => '╒',
  '�' => 'ё',
  '�' => '╓',
  '�' => '╔',
  '�' => '╕',
  '�' => '╖',
  '�' => '╗',
  '�' => '╘',
  '�' => '╙',
  '�' => '╚',
  '�' => '╛',
  '�' => '╜',
  '�' => '╝',
  '�' => '╞',
  '�' => '╟',
  '�' => '╠',
  '�' => '╡',
  '�' => 'Ё',
  '�' => '╢',
  '�' => '╣',
  '�' => '╤',
  '�' => '╥',
  '�' => '╦',
  '�' => '╧',
  '�' => '╨',
  '�' => '╩',
  '�' => '╪',
  '�' => '╫',
  '�' => '╬',
  '�' => '©',
  '�' => 'ю',
  '�' => 'а',
  '�' => 'б',
  '�' => 'ц',
  '�' => 'д',
  '�' => 'е',
  '�' => 'ф',
  '�' => 'г',
  '�' => 'х',
  '�' => 'и',
  '�' => 'й',
  '�' => 'к',
  '�' => 'л',
  '�' => 'м',
  '�' => 'н',
  '�' => 'о',
  '�' => 'п',
  '�' => 'я',
  '�' => 'р',
  '�' => 'с',
  '�' => 'т',
  '�' => 'у',
  '�' => 'ж',
  '�' => 'в',
  '�' => 'ь',
  '�' => 'ы',
  '�' => 'з',
  '�' => 'ш',
  '�' => 'э',
  '�' => 'щ',
  '�' => 'ч',
  '�' => 'ъ',
  '�' => 'Ю',
  '�' => 'А',
  '�' => 'Б',
  '�' => 'Ц',
  '�' => 'Д',
  '�' => 'Е',
  '�' => 'Ф',
  '�' => 'Г',
  '�' => 'Х',
  '�' => 'И',
  '�' => 'Й',
  '�' => 'К',
  '�' => 'Л',
  '�' => 'М',
  '�' => 'Н',
  '�' => 'О',
  '�' => 'П',
  '�' => 'Я',
  '�' => 'Р',
  '�' => 'С',
  '�' => 'Т',
  '�' => 'У',
  '�' => 'Ж',
  '�' => 'В',
  '�' => 'Ь',
  '�' => 'Ы',
  '�' => 'З',
  '�' => 'Ш',
  '�' => 'Э',
  '�' => 'Щ',
  '�' => 'Ч',
  '�' => 'Ъ',
);

$result =& $data;
unset($data);

return $result;
PKϤ$Z\���  4polyfill-iconv/Resources/charset/from.iso-8859-6.phpnu�[���<?php

static $data = array (
  '' => '',
  '' => '',
  '' => '',
  '' => '',
  '' => '',
  '' => '',
  '' => '',
  '' => '',
  '' => '',
  '	' => '	',
  '
' => '
',
  '' => '',
  '' => '',
  '
' => '
',
  '' => '',
  '' => '',
  '' => '',
  '' => '',
  '' => '',
  '' => '',
  '' => '',
  '' => '',
  '' => '',
  '' => '',
  '' => '',
  '' => '',
  '' => '',
  '' => '',
  '' => '',
  '' => '',
  '' => '',
  '' => '',
  ' ' => ' ',
  '!' => '!',
  '"' => '"',
  '#' => '#',
  '$' => '$',
  '%' => '%',
  '&' => '&',
  '\'' => '\'',
  '(' => '(',
  ')' => ')',
  '*' => '*',
  '+' => '+',
  ',' => ',',
  '-' => '-',
  '.' => '.',
  '/' => '/',
  0 => '0',
  1 => '1',
  2 => '2',
  3 => '3',
  4 => '4',
  5 => '5',
  6 => '6',
  7 => '7',
  8 => '8',
  9 => '9',
  ':' => ':',
  ';' => ';',
  '<' => '<',
  '=' => '=',
  '>' => '>',
  '?' => '?',
  '@' => '@',
  'A' => 'A',
  'B' => 'B',
  'C' => 'C',
  'D' => 'D',
  'E' => 'E',
  'F' => 'F',
  'G' => 'G',
  'H' => 'H',
  'I' => 'I',
  'J' => 'J',
  'K' => 'K',
  'L' => 'L',
  'M' => 'M',
  'N' => 'N',
  'O' => 'O',
  'P' => 'P',
  'Q' => 'Q',
  'R' => 'R',
  'S' => 'S',
  'T' => 'T',
  'U' => 'U',
  'V' => 'V',
  'W' => 'W',
  'X' => 'X',
  'Y' => 'Y',
  'Z' => 'Z',
  '[' => '[',
  '\\' => '\\',
  ']' => ']',
  '^' => '^',
  '_' => '_',
  '`' => '`',
  'a' => 'a',
  'b' => 'b',
  'c' => 'c',
  'd' => 'd',
  'e' => 'e',
  'f' => 'f',
  'g' => 'g',
  'h' => 'h',
  'i' => 'i',
  'j' => 'j',
  'k' => 'k',
  'l' => 'l',
  'm' => 'm',
  'n' => 'n',
  'o' => 'o',
  'p' => 'p',
  'q' => 'q',
  'r' => 'r',
  's' => 's',
  't' => 't',
  'u' => 'u',
  'v' => 'v',
  'w' => 'w',
  'x' => 'x',
  'y' => 'y',
  'z' => 'z',
  '{' => '{',
  '|' => '|',
  '}' => '}',
  '~' => '~',
  '' => '',
  '�' => '€',
  '�' => '',
  '�' => '‚',
  '�' => 'ƒ',
  '�' => '„',
  '�' => '…',
  '�' => '†',
  '�' => '‡',
  '�' => 'ˆ',
  '�' => '‰',
  '�' => 'Š',
  '�' => '‹',
  '�' => 'Œ',
  '�' => '',
  '�' => 'Ž',
  '�' => '',
  '�' => '',
  '�' => '‘',
  '�' => '’',
  '�' => '“',
  '�' => '”',
  '�' => '•',
  '�' => '–',
  '�' => '—',
  '�' => '˜',
  '�' => '™',
  '�' => 'š',
  '�' => '›',
  '�' => 'œ',
  '�' => '',
  '�' => 'ž',
  '�' => 'Ÿ',
  '�' => ' ',
  '�' => '¤',
  '�' => '،',
  '�' => '­',
  '�' => '؛',
  '�' => '؟',
  '�' => 'ء',
  '�' => 'آ',
  '�' => 'أ',
  '�' => 'ؤ',
  '�' => 'إ',
  '�' => 'ئ',
  '�' => 'ا',
  '�' => 'ب',
  '�' => 'ة',
  '�' => 'ت',
  '�' => 'ث',
  '�' => 'ج',
  '�' => 'ح',
  '�' => 'خ',
  '�' => 'د',
  '�' => 'ذ',
  '�' => 'ر',
  '�' => 'ز',
  '�' => 'س',
  '�' => 'ش',
  '�' => 'ص',
  '�' => 'ض',
  '�' => 'ط',
  '�' => 'ظ',
  '�' => 'ع',
  '�' => 'غ',
  '�' => 'ـ',
  '�' => 'ف',
  '�' => 'ق',
  '�' => 'ك',
  '�' => 'ل',
  '�' => 'م',
  '�' => 'ن',
  '�' => 'ه',
  '�' => 'و',
  '�' => 'ى',
  '�' => 'ي',
  '�' => 'ً',
  '�' => 'ٌ',
  '�' => 'ٍ',
  '�' => 'َ',
  '�' => 'ُ',
  '�' => 'ِ',
  '�' => 'ّ',
  '�' => 'ْ',
);

$result =& $data;
unset($data);

return $result;
PKϤ$ZXQ����5polyfill-iconv/Resources/charset/from.iso-8859-15.phpnu�[���<?php

static $data = array (
  '' => '',
  '' => '',
  '' => '',
  '' => '',
  '' => '',
  '' => '',
  '' => '',
  '' => '',
  '' => '',
  '	' => '	',
  '
' => '
',
  '' => '',
  '' => '',
  '
' => '
',
  '' => '',
  '' => '',
  '' => '',
  '' => '',
  '' => '',
  '' => '',
  '' => '',
  '' => '',
  '' => '',
  '' => '',
  '' => '',
  '' => '',
  '' => '',
  '' => '',
  '' => '',
  '' => '',
  '' => '',
  '' => '',
  ' ' => ' ',
  '!' => '!',
  '"' => '"',
  '#' => '#',
  '$' => '$',
  '%' => '%',
  '&' => '&',
  '\'' => '\'',
  '(' => '(',
  ')' => ')',
  '*' => '*',
  '+' => '+',
  ',' => ',',
  '-' => '-',
  '.' => '.',
  '/' => '/',
  0 => '0',
  1 => '1',
  2 => '2',
  3 => '3',
  4 => '4',
  5 => '5',
  6 => '6',
  7 => '7',
  8 => '8',
  9 => '9',
  ':' => ':',
  ';' => ';',
  '<' => '<',
  '=' => '=',
  '>' => '>',
  '?' => '?',
  '@' => '@',
  'A' => 'A',
  'B' => 'B',
  'C' => 'C',
  'D' => 'D',
  'E' => 'E',
  'F' => 'F',
  'G' => 'G',
  'H' => 'H',
  'I' => 'I',
  'J' => 'J',
  'K' => 'K',
  'L' => 'L',
  'M' => 'M',
  'N' => 'N',
  'O' => 'O',
  'P' => 'P',
  'Q' => 'Q',
  'R' => 'R',
  'S' => 'S',
  'T' => 'T',
  'U' => 'U',
  'V' => 'V',
  'W' => 'W',
  'X' => 'X',
  'Y' => 'Y',
  'Z' => 'Z',
  '[' => '[',
  '\\' => '\\',
  ']' => ']',
  '^' => '^',
  '_' => '_',
  '`' => '`',
  'a' => 'a',
  'b' => 'b',
  'c' => 'c',
  'd' => 'd',
  'e' => 'e',
  'f' => 'f',
  'g' => 'g',
  'h' => 'h',
  'i' => 'i',
  'j' => 'j',
  'k' => 'k',
  'l' => 'l',
  'm' => 'm',
  'n' => 'n',
  'o' => 'o',
  'p' => 'p',
  'q' => 'q',
  'r' => 'r',
  's' => 's',
  't' => 't',
  'u' => 'u',
  'v' => 'v',
  'w' => 'w',
  'x' => 'x',
  'y' => 'y',
  'z' => 'z',
  '{' => '{',
  '|' => '|',
  '}' => '}',
  '~' => '~',
  '' => '',
  '�' => '€',
  '�' => '',
  '�' => '‚',
  '�' => 'ƒ',
  '�' => '„',
  '�' => '…',
  '�' => '†',
  '�' => '‡',
  '�' => 'ˆ',
  '�' => '‰',
  '�' => 'Š',
  '�' => '‹',
  '�' => 'Œ',
  '�' => '',
  '�' => 'Ž',
  '�' => '',
  '�' => '',
  '�' => '‘',
  '�' => '’',
  '�' => '“',
  '�' => '”',
  '�' => '•',
  '�' => '–',
  '�' => '—',
  '�' => '˜',
  '�' => '™',
  '�' => 'š',
  '�' => '›',
  '�' => 'œ',
  '�' => '',
  '�' => 'ž',
  '�' => 'Ÿ',
  '�' => ' ',
  '�' => '¡',
  '�' => '¢',
  '�' => '£',
  '�' => '€',
  '�' => '¥',
  '�' => 'Š',
  '�' => '§',
  '�' => 'š',
  '�' => '©',
  '�' => 'ª',
  '�' => '«',
  '�' => '¬',
  '�' => '­',
  '�' => '®',
  '�' => '¯',
  '�' => '°',
  '�' => '±',
  '�' => '²',
  '�' => '³',
  '�' => 'Ž',
  '�' => 'µ',
  '�' => '¶',
  '�' => '·',
  '�' => 'ž',
  '�' => '¹',
  '�' => 'º',
  '�' => '»',
  '�' => 'Œ',
  '�' => 'œ',
  '�' => 'Ÿ',
  '�' => '¿',
  '�' => 'À',
  '�' => 'Á',
  '�' => 'Â',
  '�' => 'Ã',
  '�' => 'Ä',
  '�' => 'Å',
  '�' => 'Æ',
  '�' => 'Ç',
  '�' => 'È',
  '�' => 'É',
  '�' => 'Ê',
  '�' => 'Ë',
  '�' => 'Ì',
  '�' => 'Í',
  '�' => 'Î',
  '�' => 'Ï',
  '�' => 'Ð',
  '�' => 'Ñ',
  '�' => 'Ò',
  '�' => 'Ó',
  '�' => 'Ô',
  '�' => 'Õ',
  '�' => 'Ö',
  '�' => '×',
  '�' => 'Ø',
  '�' => 'Ù',
  '�' => 'Ú',
  '�' => 'Û',
  '�' => 'Ü',
  '�' => 'Ý',
  '�' => 'Þ',
  '�' => 'ß',
  '�' => 'à',
  '�' => 'á',
  '�' => 'â',
  '�' => 'ã',
  '�' => 'ä',
  '�' => 'å',
  '�' => 'æ',
  '�' => 'ç',
  '�' => 'è',
  '�' => 'é',
  '�' => 'ê',
  '�' => 'ë',
  '�' => 'ì',
  '�' => 'í',
  '�' => 'î',
  '�' => 'ï',
  '�' => 'ð',
  '�' => 'ñ',
  '�' => 'ò',
  '�' => 'ó',
  '�' => 'ô',
  '�' => 'õ',
  '�' => 'ö',
  '�' => '÷',
  '�' => 'ø',
  '�' => 'ù',
  '�' => 'ú',
  '�' => 'û',
  '�' => 'ü',
  '�' => 'ý',
  '�' => 'þ',
  '�' => 'ÿ',
);

$result =& $data;
unset($data);

return $result;
PKϤ$Z��D;��/polyfill-iconv/Resources/charset/from.cp866.phpnu�[���<?php

static $data = array (
  '' => '',
  '' => '',
  '' => '',
  '' => '',
  '' => '',
  '' => '',
  '' => '',
  '' => '',
  '' => '',
  '	' => '	',
  '
' => '
',
  '' => '',
  '' => '',
  '
' => '
',
  '' => '',
  '' => '',
  '' => '',
  '' => '',
  '' => '',
  '' => '',
  '' => '',
  '' => '',
  '' => '',
  '' => '',
  '' => '',
  '' => '',
  '' => '',
  '' => '',
  '' => '',
  '' => '',
  '' => '',
  '' => '',
  ' ' => ' ',
  '!' => '!',
  '"' => '"',
  '#' => '#',
  '$' => '$',
  '%' => '%',
  '&' => '&',
  '\'' => '\'',
  '(' => '(',
  ')' => ')',
  '*' => '*',
  '+' => '+',
  ',' => ',',
  '-' => '-',
  '.' => '.',
  '/' => '/',
  0 => '0',
  1 => '1',
  2 => '2',
  3 => '3',
  4 => '4',
  5 => '5',
  6 => '6',
  7 => '7',
  8 => '8',
  9 => '9',
  ':' => ':',
  ';' => ';',
  '<' => '<',
  '=' => '=',
  '>' => '>',
  '?' => '?',
  '@' => '@',
  'A' => 'A',
  'B' => 'B',
  'C' => 'C',
  'D' => 'D',
  'E' => 'E',
  'F' => 'F',
  'G' => 'G',
  'H' => 'H',
  'I' => 'I',
  'J' => 'J',
  'K' => 'K',
  'L' => 'L',
  'M' => 'M',
  'N' => 'N',
  'O' => 'O',
  'P' => 'P',
  'Q' => 'Q',
  'R' => 'R',
  'S' => 'S',
  'T' => 'T',
  'U' => 'U',
  'V' => 'V',
  'W' => 'W',
  'X' => 'X',
  'Y' => 'Y',
  'Z' => 'Z',
  '[' => '[',
  '\\' => '\\',
  ']' => ']',
  '^' => '^',
  '_' => '_',
  '`' => '`',
  'a' => 'a',
  'b' => 'b',
  'c' => 'c',
  'd' => 'd',
  'e' => 'e',
  'f' => 'f',
  'g' => 'g',
  'h' => 'h',
  'i' => 'i',
  'j' => 'j',
  'k' => 'k',
  'l' => 'l',
  'm' => 'm',
  'n' => 'n',
  'o' => 'o',
  'p' => 'p',
  'q' => 'q',
  'r' => 'r',
  's' => 's',
  't' => 't',
  'u' => 'u',
  'v' => 'v',
  'w' => 'w',
  'x' => 'x',
  'y' => 'y',
  'z' => 'z',
  '{' => '{',
  '|' => '|',
  '}' => '}',
  '~' => '~',
  '' => '',
  '�' => 'А',
  '�' => 'Б',
  '�' => 'В',
  '�' => 'Г',
  '�' => 'Д',
  '�' => 'Е',
  '�' => 'Ж',
  '�' => 'З',
  '�' => 'И',
  '�' => 'Й',
  '�' => 'К',
  '�' => 'Л',
  '�' => 'М',
  '�' => 'Н',
  '�' => 'О',
  '�' => 'П',
  '�' => 'Р',
  '�' => 'С',
  '�' => 'Т',
  '�' => 'У',
  '�' => 'Ф',
  '�' => 'Х',
  '�' => 'Ц',
  '�' => 'Ч',
  '�' => 'Ш',
  '�' => 'Щ',
  '�' => 'Ъ',
  '�' => 'Ы',
  '�' => 'Ь',
  '�' => 'Э',
  '�' => 'Ю',
  '�' => 'Я',
  '�' => 'а',
  '�' => 'б',
  '�' => 'в',
  '�' => 'г',
  '�' => 'д',
  '�' => 'е',
  '�' => 'ж',
  '�' => 'з',
  '�' => 'и',
  '�' => 'й',
  '�' => 'к',
  '�' => 'л',
  '�' => 'м',
  '�' => 'н',
  '�' => 'о',
  '�' => 'п',
  '�' => '░',
  '�' => '▒',
  '�' => '▓',
  '�' => '│',
  '�' => '┤',
  '�' => '╡',
  '�' => '╢',
  '�' => '╖',
  '�' => '╕',
  '�' => '╣',
  '�' => '║',
  '�' => '╗',
  '�' => '╝',
  '�' => '╜',
  '�' => '╛',
  '�' => '┐',
  '�' => '└',
  '�' => '┴',
  '�' => '┬',
  '�' => '├',
  '�' => '─',
  '�' => '┼',
  '�' => '╞',
  '�' => '╟',
  '�' => '╚',
  '�' => '╔',
  '�' => '╩',
  '�' => '╦',
  '�' => '╠',
  '�' => '═',
  '�' => '╬',
  '�' => '╧',
  '�' => '╨',
  '�' => '╤',
  '�' => '╥',
  '�' => '╙',
  '�' => '╘',
  '�' => '╒',
  '�' => '╓',
  '�' => '╫',
  '�' => '╪',
  '�' => '┘',
  '�' => '┌',
  '�' => '█',
  '�' => '▄',
  '�' => '▌',
  '�' => '▐',
  '�' => '▀',
  '�' => 'р',
  '�' => 'с',
  '�' => 'т',
  '�' => 'у',
  '�' => 'ф',
  '�' => 'х',
  '�' => 'ц',
  '�' => 'ч',
  '�' => 'ш',
  '�' => 'щ',
  '�' => 'ъ',
  '�' => 'ы',
  '�' => 'ь',
  '�' => 'э',
  '�' => 'ю',
  '�' => 'я',
  '�' => 'Ё',
  '�' => 'ё',
  '�' => 'Є',
  '�' => 'є',
  '�' => 'Ї',
  '�' => 'ї',
  '�' => 'Ў',
  '�' => 'ў',
  '�' => '°',
  '�' => '∙',
  '�' => '·',
  '�' => '√',
  '�' => '№',
  '�' => '¤',
  '�' => '■',
  '�' => ' ',
);

$result =& $data;
unset($data);

return $result;
PKϤ$Z0��/��/polyfill-iconv/Resources/charset/from.cp850.phpnu�[���<?php

static $data = array (
  '' => '',
  '' => '',
  '' => '',
  '' => '',
  '' => '',
  '' => '',
  '' => '',
  '' => '',
  '' => '',
  '	' => '	',
  '
' => '
',
  '' => '',
  '' => '',
  '
' => '
',
  '' => '',
  '' => '',
  '' => '',
  '' => '',
  '' => '',
  '' => '',
  '' => '',
  '' => '',
  '' => '',
  '' => '',
  '' => '',
  '' => '',
  '' => '',
  '' => '',
  '' => '',
  '' => '',
  '' => '',
  '' => '',
  ' ' => ' ',
  '!' => '!',
  '"' => '"',
  '#' => '#',
  '$' => '$',
  '%' => '%',
  '&' => '&',
  '\'' => '\'',
  '(' => '(',
  ')' => ')',
  '*' => '*',
  '+' => '+',
  ',' => ',',
  '-' => '-',
  '.' => '.',
  '/' => '/',
  0 => '0',
  1 => '1',
  2 => '2',
  3 => '3',
  4 => '4',
  5 => '5',
  6 => '6',
  7 => '7',
  8 => '8',
  9 => '9',
  ':' => ':',
  ';' => ';',
  '<' => '<',
  '=' => '=',
  '>' => '>',
  '?' => '?',
  '@' => '@',
  'A' => 'A',
  'B' => 'B',
  'C' => 'C',
  'D' => 'D',
  'E' => 'E',
  'F' => 'F',
  'G' => 'G',
  'H' => 'H',
  'I' => 'I',
  'J' => 'J',
  'K' => 'K',
  'L' => 'L',
  'M' => 'M',
  'N' => 'N',
  'O' => 'O',
  'P' => 'P',
  'Q' => 'Q',
  'R' => 'R',
  'S' => 'S',
  'T' => 'T',
  'U' => 'U',
  'V' => 'V',
  'W' => 'W',
  'X' => 'X',
  'Y' => 'Y',
  'Z' => 'Z',
  '[' => '[',
  '\\' => '\\',
  ']' => ']',
  '^' => '^',
  '_' => '_',
  '`' => '`',
  'a' => 'a',
  'b' => 'b',
  'c' => 'c',
  'd' => 'd',
  'e' => 'e',
  'f' => 'f',
  'g' => 'g',
  'h' => 'h',
  'i' => 'i',
  'j' => 'j',
  'k' => 'k',
  'l' => 'l',
  'm' => 'm',
  'n' => 'n',
  'o' => 'o',
  'p' => 'p',
  'q' => 'q',
  'r' => 'r',
  's' => 's',
  't' => 't',
  'u' => 'u',
  'v' => 'v',
  'w' => 'w',
  'x' => 'x',
  'y' => 'y',
  'z' => 'z',
  '{' => '{',
  '|' => '|',
  '}' => '}',
  '~' => '~',
  '' => '',
  '�' => 'Ç',
  '�' => 'ü',
  '�' => 'é',
  '�' => 'â',
  '�' => 'ä',
  '�' => 'à',
  '�' => 'å',
  '�' => 'ç',
  '�' => 'ê',
  '�' => 'ë',
  '�' => 'è',
  '�' => 'ï',
  '�' => 'î',
  '�' => 'ì',
  '�' => 'Ä',
  '�' => 'Å',
  '�' => 'É',
  '�' => 'æ',
  '�' => 'Æ',
  '�' => 'ô',
  '�' => 'ö',
  '�' => 'ò',
  '�' => 'û',
  '�' => 'ù',
  '�' => 'ÿ',
  '�' => 'Ö',
  '�' => 'Ü',
  '�' => 'ø',
  '�' => '£',
  '�' => 'Ø',
  '�' => '×',
  '�' => 'ƒ',
  '�' => 'á',
  '�' => 'í',
  '�' => 'ó',
  '�' => 'ú',
  '�' => 'ñ',
  '�' => 'Ñ',
  '�' => 'ª',
  '�' => 'º',
  '�' => '¿',
  '�' => '®',
  '�' => '¬',
  '�' => '½',
  '�' => '¼',
  '�' => '¡',
  '�' => '«',
  '�' => '»',
  '�' => '░',
  '�' => '▒',
  '�' => '▓',
  '�' => '│',
  '�' => '┤',
  '�' => 'Á',
  '�' => 'Â',
  '�' => 'À',
  '�' => '©',
  '�' => '╣',
  '�' => '║',
  '�' => '╗',
  '�' => '╝',
  '�' => '¢',
  '�' => '¥',
  '�' => '┐',
  '�' => '└',
  '�' => '┴',
  '�' => '┬',
  '�' => '├',
  '�' => '─',
  '�' => '┼',
  '�' => 'ã',
  '�' => 'Ã',
  '�' => '╚',
  '�' => '╔',
  '�' => '╩',
  '�' => '╦',
  '�' => '╠',
  '�' => '═',
  '�' => '╬',
  '�' => '¤',
  '�' => 'ð',
  '�' => 'Ð',
  '�' => 'Ê',
  '�' => 'Ë',
  '�' => 'È',
  '�' => 'ı',
  '�' => 'Í',
  '�' => 'Î',
  '�' => 'Ï',
  '�' => '┘',
  '�' => '┌',
  '�' => '█',
  '�' => '▄',
  '�' => '¦',
  '�' => 'Ì',
  '�' => '▀',
  '�' => 'Ó',
  '�' => 'ß',
  '�' => 'Ô',
  '�' => 'Ò',
  '�' => 'õ',
  '�' => 'Õ',
  '�' => 'µ',
  '�' => 'þ',
  '�' => 'Þ',
  '�' => 'Ú',
  '�' => 'Û',
  '�' => 'Ù',
  '�' => 'ý',
  '�' => 'Ý',
  '�' => '¯',
  '�' => '´',
  '�' => '­',
  '�' => '±',
  '�' => '‗',
  '�' => '¾',
  '�' => '¶',
  '�' => '§',
  '�' => '÷',
  '�' => '¸',
  '�' => '°',
  '�' => '¨',
  '�' => '·',
  '�' => '¹',
  '�' => '³',
  '�' => '²',
  '�' => '■',
  '�' => ' ',
);

$result =& $data;
unset($data);

return $result;
PKϤ$Z��kk6polyfill-iconv/Resources/charset/from.windows-1254.phpnu�[���<?php

static $data = array (
  '' => '',
  '' => '',
  '' => '',
  '' => '',
  '' => '',
  '' => '',
  '' => '',
  '' => '',
  '' => '',
  '	' => '	',
  '
' => '
',
  '' => '',
  '' => '',
  '
' => '
',
  '' => '',
  '' => '',
  '' => '',
  '' => '',
  '' => '',
  '' => '',
  '' => '',
  '' => '',
  '' => '',
  '' => '',
  '' => '',
  '' => '',
  '' => '',
  '' => '',
  '' => '',
  '' => '',
  '' => '',
  '' => '',
  ' ' => ' ',
  '!' => '!',
  '"' => '"',
  '#' => '#',
  '$' => '$',
  '%' => '%',
  '&' => '&',
  '\'' => '\'',
  '(' => '(',
  ')' => ')',
  '*' => '*',
  '+' => '+',
  ',' => ',',
  '-' => '-',
  '.' => '.',
  '/' => '/',
  0 => '0',
  1 => '1',
  2 => '2',
  3 => '3',
  4 => '4',
  5 => '5',
  6 => '6',
  7 => '7',
  8 => '8',
  9 => '9',
  ':' => ':',
  ';' => ';',
  '<' => '<',
  '=' => '=',
  '>' => '>',
  '?' => '?',
  '@' => '@',
  'A' => 'A',
  'B' => 'B',
  'C' => 'C',
  'D' => 'D',
  'E' => 'E',
  'F' => 'F',
  'G' => 'G',
  'H' => 'H',
  'I' => 'I',
  'J' => 'J',
  'K' => 'K',
  'L' => 'L',
  'M' => 'M',
  'N' => 'N',
  'O' => 'O',
  'P' => 'P',
  'Q' => 'Q',
  'R' => 'R',
  'S' => 'S',
  'T' => 'T',
  'U' => 'U',
  'V' => 'V',
  'W' => 'W',
  'X' => 'X',
  'Y' => 'Y',
  'Z' => 'Z',
  '[' => '[',
  '\\' => '\\',
  ']' => ']',
  '^' => '^',
  '_' => '_',
  '`' => '`',
  'a' => 'a',
  'b' => 'b',
  'c' => 'c',
  'd' => 'd',
  'e' => 'e',
  'f' => 'f',
  'g' => 'g',
  'h' => 'h',
  'i' => 'i',
  'j' => 'j',
  'k' => 'k',
  'l' => 'l',
  'm' => 'm',
  'n' => 'n',
  'o' => 'o',
  'p' => 'p',
  'q' => 'q',
  'r' => 'r',
  's' => 's',
  't' => 't',
  'u' => 'u',
  'v' => 'v',
  'w' => 'w',
  'x' => 'x',
  'y' => 'y',
  'z' => 'z',
  '{' => '{',
  '|' => '|',
  '}' => '}',
  '~' => '~',
  '' => '',
  '�' => '€',
  '�' => '‚',
  '�' => 'ƒ',
  '�' => '„',
  '�' => '…',
  '�' => '†',
  '�' => '‡',
  '�' => 'ˆ',
  '�' => '‰',
  '�' => 'Š',
  '�' => '‹',
  '�' => 'Œ',
  '�' => '‘',
  '�' => '’',
  '�' => '“',
  '�' => '”',
  '�' => '•',
  '�' => '–',
  '�' => '—',
  '�' => '˜',
  '�' => '™',
  '�' => 'š',
  '�' => '›',
  '�' => 'œ',
  '�' => 'Ÿ',
  '�' => ' ',
  '�' => '¡',
  '�' => '¢',
  '�' => '£',
  '�' => '¤',
  '�' => '¥',
  '�' => '¦',
  '�' => '§',
  '�' => '¨',
  '�' => '©',
  '�' => 'ª',
  '�' => '«',
  '�' => '¬',
  '�' => '­',
  '�' => '®',
  '�' => '¯',
  '�' => '°',
  '�' => '±',
  '�' => '²',
  '�' => '³',
  '�' => '´',
  '�' => 'µ',
  '�' => '¶',
  '�' => '·',
  '�' => '¸',
  '�' => '¹',
  '�' => 'º',
  '�' => '»',
  '�' => '¼',
  '�' => '½',
  '�' => '¾',
  '�' => '¿',
  '�' => 'À',
  '�' => 'Á',
  '�' => 'Â',
  '�' => 'Ã',
  '�' => 'Ä',
  '�' => 'Å',
  '�' => 'Æ',
  '�' => 'Ç',
  '�' => 'È',
  '�' => 'É',
  '�' => 'Ê',
  '�' => 'Ë',
  '�' => 'Ì',
  '�' => 'Í',
  '�' => 'Î',
  '�' => 'Ï',
  '�' => 'Ğ',
  '�' => 'Ñ',
  '�' => 'Ò',
  '�' => 'Ó',
  '�' => 'Ô',
  '�' => 'Õ',
  '�' => 'Ö',
  '�' => '×',
  '�' => 'Ø',
  '�' => 'Ù',
  '�' => 'Ú',
  '�' => 'Û',
  '�' => 'Ü',
  '�' => 'İ',
  '�' => 'Ş',
  '�' => 'ß',
  '�' => 'à',
  '�' => 'á',
  '�' => 'â',
  '�' => 'ã',
  '�' => 'ä',
  '�' => 'å',
  '�' => 'æ',
  '�' => 'ç',
  '�' => 'è',
  '�' => 'é',
  '�' => 'ê',
  '�' => 'ë',
  '�' => 'ì',
  '�' => 'í',
  '�' => 'î',
  '�' => 'ï',
  '�' => 'ğ',
  '�' => 'ñ',
  '�' => 'ò',
  '�' => 'ó',
  '�' => 'ô',
  '�' => 'õ',
  '�' => 'ö',
  '�' => '÷',
  '�' => 'ø',
  '�' => 'ù',
  '�' => 'ú',
  '�' => 'û',
  '�' => 'ü',
  '�' => 'ı',
  '�' => 'ş',
  '�' => 'ÿ',
);

$result =& $data;
unset($data);

return $result;
PKϤ$ZOP�gCC2polyfill-iconv/Resources/charset/from.us-ascii.phpnu�[���<?php

static $data = array (
  '' => '',
  '' => '',
  '' => '',
  '' => '',
  '' => '',
  '' => '',
  '' => '',
  '' => '',
  '' => '',
  '	' => '	',
  '
' => '
',
  '' => '',
  '' => '',
  '
' => '
',
  '' => '',
  '' => '',
  '' => '',
  '' => '',
  '' => '',
  '' => '',
  '' => '',
  '' => '',
  '' => '',
  '' => '',
  '' => '',
  '' => '',
  '' => '',
  '' => '',
  '' => '',
  '' => '',
  '' => '',
  '' => '',
  ' ' => ' ',
  '!' => '!',
  '"' => '"',
  '#' => '#',
  '$' => '$',
  '%' => '%',
  '&' => '&',
  '\'' => '\'',
  '(' => '(',
  ')' => ')',
  '*' => '*',
  '+' => '+',
  ',' => ',',
  '-' => '-',
  '.' => '.',
  '/' => '/',
  0 => '0',
  1 => '1',
  2 => '2',
  3 => '3',
  4 => '4',
  5 => '5',
  6 => '6',
  7 => '7',
  8 => '8',
  9 => '9',
  ':' => ':',
  ';' => ';',
  '<' => '<',
  '=' => '=',
  '>' => '>',
  '?' => '?',
  '@' => '@',
  'A' => 'A',
  'B' => 'B',
  'C' => 'C',
  'D' => 'D',
  'E' => 'E',
  'F' => 'F',
  'G' => 'G',
  'H' => 'H',
  'I' => 'I',
  'J' => 'J',
  'K' => 'K',
  'L' => 'L',
  'M' => 'M',
  'N' => 'N',
  'O' => 'O',
  'P' => 'P',
  'Q' => 'Q',
  'R' => 'R',
  'S' => 'S',
  'T' => 'T',
  'U' => 'U',
  'V' => 'V',
  'W' => 'W',
  'X' => 'X',
  'Y' => 'Y',
  'Z' => 'Z',
  '[' => '[',
  '\\' => '\\',
  ']' => ']',
  '^' => '^',
  '_' => '_',
  '`' => '`',
  'a' => 'a',
  'b' => 'b',
  'c' => 'c',
  'd' => 'd',
  'e' => 'e',
  'f' => 'f',
  'g' => 'g',
  'h' => 'h',
  'i' => 'i',
  'j' => 'j',
  'k' => 'k',
  'l' => 'l',
  'm' => 'm',
  'n' => 'n',
  'o' => 'o',
  'p' => 'p',
  'q' => 'q',
  'r' => 'r',
  's' => 's',
  't' => 't',
  'u' => 'u',
  'v' => 'v',
  'w' => 'w',
  'x' => 'x',
  'y' => 'y',
  'z' => 'z',
  '{' => '{',
  '|' => '|',
  '}' => '}',
  '~' => '~',
  '' => '',
);

$result =& $data;
unset($data);

return $result;
PKϤ$Z�R��5polyfill-iconv/Resources/charset/from.iso-8859-10.phpnu�[���<?php

static $data = array (
  '' => '',
  '' => '',
  '' => '',
  '' => '',
  '' => '',
  '' => '',
  '' => '',
  '' => '',
  '' => '',
  '	' => '	',
  '
' => '
',
  '' => '',
  '' => '',
  '
' => '
',
  '' => '',
  '' => '',
  '' => '',
  '' => '',
  '' => '',
  '' => '',
  '' => '',
  '' => '',
  '' => '',
  '' => '',
  '' => '',
  '' => '',
  '' => '',
  '' => '',
  '' => '',
  '' => '',
  '' => '',
  '' => '',
  ' ' => ' ',
  '!' => '!',
  '"' => '"',
  '#' => '#',
  '$' => '$',
  '%' => '%',
  '&' => '&',
  '\'' => '\'',
  '(' => '(',
  ')' => ')',
  '*' => '*',
  '+' => '+',
  ',' => ',',
  '-' => '-',
  '.' => '.',
  '/' => '/',
  0 => '0',
  1 => '1',
  2 => '2',
  3 => '3',
  4 => '4',
  5 => '5',
  6 => '6',
  7 => '7',
  8 => '8',
  9 => '9',
  ':' => ':',
  ';' => ';',
  '<' => '<',
  '=' => '=',
  '>' => '>',
  '?' => '?',
  '@' => '@',
  'A' => 'A',
  'B' => 'B',
  'C' => 'C',
  'D' => 'D',
  'E' => 'E',
  'F' => 'F',
  'G' => 'G',
  'H' => 'H',
  'I' => 'I',
  'J' => 'J',
  'K' => 'K',
  'L' => 'L',
  'M' => 'M',
  'N' => 'N',
  'O' => 'O',
  'P' => 'P',
  'Q' => 'Q',
  'R' => 'R',
  'S' => 'S',
  'T' => 'T',
  'U' => 'U',
  'V' => 'V',
  'W' => 'W',
  'X' => 'X',
  'Y' => 'Y',
  'Z' => 'Z',
  '[' => '[',
  '\\' => '\\',
  ']' => ']',
  '^' => '^',
  '_' => '_',
  '`' => '`',
  'a' => 'a',
  'b' => 'b',
  'c' => 'c',
  'd' => 'd',
  'e' => 'e',
  'f' => 'f',
  'g' => 'g',
  'h' => 'h',
  'i' => 'i',
  'j' => 'j',
  'k' => 'k',
  'l' => 'l',
  'm' => 'm',
  'n' => 'n',
  'o' => 'o',
  'p' => 'p',
  'q' => 'q',
  'r' => 'r',
  's' => 's',
  't' => 't',
  'u' => 'u',
  'v' => 'v',
  'w' => 'w',
  'x' => 'x',
  'y' => 'y',
  'z' => 'z',
  '{' => '{',
  '|' => '|',
  '}' => '}',
  '~' => '~',
  '' => '',
  '�' => '€',
  '�' => '',
  '�' => '‚',
  '�' => 'ƒ',
  '�' => '„',
  '�' => '…',
  '�' => '†',
  '�' => '‡',
  '�' => 'ˆ',
  '�' => '‰',
  '�' => 'Š',
  '�' => '‹',
  '�' => 'Œ',
  '�' => '',
  '�' => 'Ž',
  '�' => '',
  '�' => '',
  '�' => '‘',
  '�' => '’',
  '�' => '“',
  '�' => '”',
  '�' => '•',
  '�' => '–',
  '�' => '—',
  '�' => '˜',
  '�' => '™',
  '�' => 'š',
  '�' => '›',
  '�' => 'œ',
  '�' => '',
  '�' => 'ž',
  '�' => 'Ÿ',
  '�' => ' ',
  '�' => 'Ą',
  '�' => 'Ē',
  '�' => 'Ģ',
  '�' => 'Ī',
  '�' => 'Ĩ',
  '�' => 'Ķ',
  '�' => '§',
  '�' => 'Ļ',
  '�' => 'Đ',
  '�' => 'Š',
  '�' => 'Ŧ',
  '�' => 'Ž',
  '�' => '­',
  '�' => 'Ū',
  '�' => 'Ŋ',
  '�' => '°',
  '�' => 'ą',
  '�' => 'ē',
  '�' => 'ģ',
  '�' => 'ī',
  '�' => 'ĩ',
  '�' => 'ķ',
  '�' => '·',
  '�' => 'ļ',
  '�' => 'đ',
  '�' => 'š',
  '�' => 'ŧ',
  '�' => 'ž',
  '�' => '―',
  '�' => 'ū',
  '�' => 'ŋ',
  '�' => 'Ā',
  '�' => 'Á',
  '�' => 'Â',
  '�' => 'Ã',
  '�' => 'Ä',
  '�' => 'Å',
  '�' => 'Æ',
  '�' => 'Į',
  '�' => 'Č',
  '�' => 'É',
  '�' => 'Ę',
  '�' => 'Ë',
  '�' => 'Ė',
  '�' => 'Í',
  '�' => 'Î',
  '�' => 'Ï',
  '�' => 'Ð',
  '�' => 'Ņ',
  '�' => 'Ō',
  '�' => 'Ó',
  '�' => 'Ô',
  '�' => 'Õ',
  '�' => 'Ö',
  '�' => 'Ũ',
  '�' => 'Ø',
  '�' => 'Ų',
  '�' => 'Ú',
  '�' => 'Û',
  '�' => 'Ü',
  '�' => 'Ý',
  '�' => 'Þ',
  '�' => 'ß',
  '�' => 'ā',
  '�' => 'á',
  '�' => 'â',
  '�' => 'ã',
  '�' => 'ä',
  '�' => 'å',
  '�' => 'æ',
  '�' => 'į',
  '�' => 'č',
  '�' => 'é',
  '�' => 'ę',
  '�' => 'ë',
  '�' => 'ė',
  '�' => 'í',
  '�' => 'î',
  '�' => 'ï',
  '�' => 'ð',
  '�' => 'ņ',
  '�' => 'ō',
  '�' => 'ó',
  '�' => 'ô',
  '�' => 'õ',
  '�' => 'ö',
  '�' => 'ũ',
  '�' => 'ø',
  '�' => 'ų',
  '�' => 'ú',
  '�' => 'û',
  '�' => 'ü',
  '�' => 'ý',
  '�' => 'þ',
  '�' => 'ĸ',
);

$result =& $data;
unset($data);

return $result;
PKϤ$ZB4���0polyfill-iconv/Resources/charset/from.koi8-u.phpnu�[���<?php

static $data = array (
  '' => '',
  '' => '',
  '' => '',
  '' => '',
  '' => '',
  '' => '',
  '' => '',
  '' => '',
  '' => '',
  '	' => '	',
  '
' => '
',
  '' => '',
  '' => '',
  '
' => '
',
  '' => '',
  '' => '',
  '' => '',
  '' => '',
  '' => '',
  '' => '',
  '' => '',
  '' => '',
  '' => '',
  '' => '',
  '' => '',
  '' => '',
  '' => '',
  '' => '',
  '' => '',
  '' => '',
  '' => '',
  '' => '',
  ' ' => ' ',
  '!' => '!',
  '"' => '"',
  '#' => '#',
  '$' => '$',
  '%' => '%',
  '&' => '&',
  '\'' => '\'',
  '(' => '(',
  ')' => ')',
  '*' => '*',
  '+' => '+',
  ',' => ',',
  '-' => '-',
  '.' => '.',
  '/' => '/',
  0 => '0',
  1 => '1',
  2 => '2',
  3 => '3',
  4 => '4',
  5 => '5',
  6 => '6',
  7 => '7',
  8 => '8',
  9 => '9',
  ':' => ':',
  ';' => ';',
  '<' => '<',
  '=' => '=',
  '>' => '>',
  '?' => '?',
  '@' => '@',
  'A' => 'A',
  'B' => 'B',
  'C' => 'C',
  'D' => 'D',
  'E' => 'E',
  'F' => 'F',
  'G' => 'G',
  'H' => 'H',
  'I' => 'I',
  'J' => 'J',
  'K' => 'K',
  'L' => 'L',
  'M' => 'M',
  'N' => 'N',
  'O' => 'O',
  'P' => 'P',
  'Q' => 'Q',
  'R' => 'R',
  'S' => 'S',
  'T' => 'T',
  'U' => 'U',
  'V' => 'V',
  'W' => 'W',
  'X' => 'X',
  'Y' => 'Y',
  'Z' => 'Z',
  '[' => '[',
  '\\' => '\\',
  ']' => ']',
  '^' => '^',
  '_' => '_',
  '`' => '`',
  'a' => 'a',
  'b' => 'b',
  'c' => 'c',
  'd' => 'd',
  'e' => 'e',
  'f' => 'f',
  'g' => 'g',
  'h' => 'h',
  'i' => 'i',
  'j' => 'j',
  'k' => 'k',
  'l' => 'l',
  'm' => 'm',
  'n' => 'n',
  'o' => 'o',
  'p' => 'p',
  'q' => 'q',
  'r' => 'r',
  's' => 's',
  't' => 't',
  'u' => 'u',
  'v' => 'v',
  'w' => 'w',
  'x' => 'x',
  'y' => 'y',
  'z' => 'z',
  '{' => '{',
  '|' => '|',
  '}' => '}',
  '~' => '~',
  '' => '',
  '�' => '─',
  '�' => '│',
  '�' => '┌',
  '�' => '┐',
  '�' => '└',
  '�' => '┘',
  '�' => '├',
  '�' => '┤',
  '�' => '┬',
  '�' => '┴',
  '�' => '┼',
  '�' => '▀',
  '�' => '▄',
  '�' => '█',
  '�' => '▌',
  '�' => '▐',
  '�' => '░',
  '�' => '▒',
  '�' => '▓',
  '�' => '⌠',
  '�' => '■',
  '�' => '•',
  '�' => '√',
  '�' => '≈',
  '�' => '≤',
  '�' => '≥',
  '�' => ' ',
  '�' => '⌡',
  '�' => '°',
  '�' => '²',
  '�' => '·',
  '�' => '÷',
  '�' => '═',
  '�' => '║',
  '�' => '╒',
  '�' => 'ё',
  '�' => 'є',
  '�' => '╔',
  '�' => 'і',
  '�' => 'ї',
  '�' => '╗',
  '�' => '╘',
  '�' => '╙',
  '�' => '╚',
  '�' => '╛',
  '�' => 'ґ',
  '�' => '╝',
  '�' => '╞',
  '�' => '╟',
  '�' => '╠',
  '�' => '╡',
  '�' => 'Ё',
  '�' => 'Ѓ',
  '�' => '╣',
  '�' => 'І',
  '�' => 'Ї',
  '�' => '╦',
  '�' => '╧',
  '�' => '╨',
  '�' => '╩',
  '�' => '╪',
  '�' => 'Ґ',
  '�' => '╬',
  '�' => '©',
  '�' => 'ю',
  '�' => 'а',
  '�' => 'б',
  '�' => 'ц',
  '�' => 'д',
  '�' => 'е',
  '�' => 'ф',
  '�' => 'г',
  '�' => 'х',
  '�' => 'и',
  '�' => 'й',
  '�' => 'к',
  '�' => 'л',
  '�' => 'м',
  '�' => 'н',
  '�' => 'о',
  '�' => 'п',
  '�' => 'я',
  '�' => 'р',
  '�' => 'с',
  '�' => 'т',
  '�' => 'у',
  '�' => 'ж',
  '�' => 'в',
  '�' => 'ь',
  '�' => 'ы',
  '�' => 'з',
  '�' => 'ш',
  '�' => 'э',
  '�' => 'щ',
  '�' => 'ч',
  '�' => 'ъ',
  '�' => 'Ю',
  '�' => 'А',
  '�' => 'Б',
  '�' => 'Ц',
  '�' => 'Д',
  '�' => 'Е',
  '�' => 'Ф',
  '�' => 'Г',
  '�' => 'Х',
  '�' => 'И',
  '�' => 'Й',
  '�' => 'К',
  '�' => 'Л',
  '�' => 'М',
  '�' => 'Н',
  '�' => 'О',
  '�' => 'П',
  '�' => 'Я',
  '�' => 'Р',
  '�' => 'С',
  '�' => 'Т',
  '�' => 'У',
  '�' => 'Ж',
  '�' => 'В',
  '�' => 'Ь',
  '�' => 'Ы',
  '�' => 'З',
  '�' => 'Ш',
  '�' => 'Э',
  '�' => 'Щ',
  '�' => 'Ч',
  '�' => 'Ъ',
);

$result =& $data;
unset($data);

return $result;
PKϤ$Z��U(/polyfill-iconv/Resources/charset/from.cp437.phpnu�[���<?php

static $data = array (
  '' => '',
  '' => '',
  '' => '',
  '' => '',
  '' => '',
  '' => '',
  '' => '',
  '' => '',
  '' => '',
  '	' => '	',
  '
' => '
',
  '' => '',
  '' => '',
  '
' => '
',
  '' => '',
  '' => '',
  '' => '',
  '' => '',
  '' => '',
  '' => '',
  '' => '',
  '' => '',
  '' => '',
  '' => '',
  '' => '',
  '' => '',
  '' => '',
  '' => '',
  '' => '',
  '' => '',
  '' => '',
  '' => '',
  ' ' => ' ',
  '!' => '!',
  '"' => '"',
  '#' => '#',
  '$' => '$',
  '%' => '%',
  '&' => '&',
  '\'' => '\'',
  '(' => '(',
  ')' => ')',
  '*' => '*',
  '+' => '+',
  ',' => ',',
  '-' => '-',
  '.' => '.',
  '/' => '/',
  0 => '0',
  1 => '1',
  2 => '2',
  3 => '3',
  4 => '4',
  5 => '5',
  6 => '6',
  7 => '7',
  8 => '8',
  9 => '9',
  ':' => ':',
  ';' => ';',
  '<' => '<',
  '=' => '=',
  '>' => '>',
  '?' => '?',
  '@' => '@',
  'A' => 'A',
  'B' => 'B',
  'C' => 'C',
  'D' => 'D',
  'E' => 'E',
  'F' => 'F',
  'G' => 'G',
  'H' => 'H',
  'I' => 'I',
  'J' => 'J',
  'K' => 'K',
  'L' => 'L',
  'M' => 'M',
  'N' => 'N',
  'O' => 'O',
  'P' => 'P',
  'Q' => 'Q',
  'R' => 'R',
  'S' => 'S',
  'T' => 'T',
  'U' => 'U',
  'V' => 'V',
  'W' => 'W',
  'X' => 'X',
  'Y' => 'Y',
  'Z' => 'Z',
  '[' => '[',
  '\\' => '\\',
  ']' => ']',
  '^' => '^',
  '_' => '_',
  '`' => '`',
  'a' => 'a',
  'b' => 'b',
  'c' => 'c',
  'd' => 'd',
  'e' => 'e',
  'f' => 'f',
  'g' => 'g',
  'h' => 'h',
  'i' => 'i',
  'j' => 'j',
  'k' => 'k',
  'l' => 'l',
  'm' => 'm',
  'n' => 'n',
  'o' => 'o',
  'p' => 'p',
  'q' => 'q',
  'r' => 'r',
  's' => 's',
  't' => 't',
  'u' => 'u',
  'v' => 'v',
  'w' => 'w',
  'x' => 'x',
  'y' => 'y',
  'z' => 'z',
  '{' => '{',
  '|' => '|',
  '}' => '}',
  '~' => '~',
  '' => '',
  '�' => 'Ç',
  '�' => 'ü',
  '�' => 'é',
  '�' => 'â',
  '�' => 'ä',
  '�' => 'à',
  '�' => 'å',
  '�' => 'ç',
  '�' => 'ê',
  '�' => 'ë',
  '�' => 'è',
  '�' => 'ï',
  '�' => 'î',
  '�' => 'ì',
  '�' => 'Ä',
  '�' => 'Å',
  '�' => 'É',
  '�' => 'æ',
  '�' => 'Æ',
  '�' => 'ô',
  '�' => 'ö',
  '�' => 'ò',
  '�' => 'û',
  '�' => 'ù',
  '�' => 'ÿ',
  '�' => 'Ö',
  '�' => 'Ü',
  '�' => '¢',
  '�' => '£',
  '�' => '¥',
  '�' => '₧',
  '�' => 'ƒ',
  '�' => 'á',
  '�' => 'í',
  '�' => 'ó',
  '�' => 'ú',
  '�' => 'ñ',
  '�' => 'Ñ',
  '�' => 'ª',
  '�' => 'º',
  '�' => '¿',
  '�' => '⌐',
  '�' => '¬',
  '�' => '½',
  '�' => '¼',
  '�' => '¡',
  '�' => '«',
  '�' => '»',
  '�' => '░',
  '�' => '▒',
  '�' => '▓',
  '�' => '│',
  '�' => '┤',
  '�' => '╡',
  '�' => '╢',
  '�' => '╖',
  '�' => '╕',
  '�' => '╣',
  '�' => '║',
  '�' => '╗',
  '�' => '╝',
  '�' => '╜',
  '�' => '╛',
  '�' => '┐',
  '�' => '└',
  '�' => '┴',
  '�' => '┬',
  '�' => '├',
  '�' => '─',
  '�' => '┼',
  '�' => '╞',
  '�' => '╟',
  '�' => '╚',
  '�' => '╔',
  '�' => '╩',
  '�' => '╦',
  '�' => '╠',
  '�' => '═',
  '�' => '╬',
  '�' => '╧',
  '�' => '╨',
  '�' => '╤',
  '�' => '╥',
  '�' => '╙',
  '�' => '╘',
  '�' => '╒',
  '�' => '╓',
  '�' => '╫',
  '�' => '╪',
  '�' => '┘',
  '�' => '┌',
  '�' => '█',
  '�' => '▄',
  '�' => '▌',
  '�' => '▐',
  '�' => '▀',
  '�' => 'α',
  '�' => 'ß',
  '�' => 'Γ',
  '�' => 'π',
  '�' => 'Σ',
  '�' => 'σ',
  '�' => 'µ',
  '�' => 'τ',
  '�' => 'Φ',
  '�' => 'Θ',
  '�' => 'Ω',
  '�' => 'δ',
  '�' => '∞',
  '�' => 'φ',
  '�' => 'ε',
  '�' => '∩',
  '�' => '≡',
  '�' => '±',
  '�' => '≥',
  '�' => '≤',
  '�' => '⌠',
  '�' => '⌡',
  '�' => '÷',
  '�' => '≈',
  '�' => '°',
  '�' => '∙',
  '�' => '·',
  '�' => '√',
  '�' => 'ⁿ',
  '�' => '²',
  '�' => '■',
  '�' => ' ',
);

$result =& $data;
unset($data);

return $result;
PKϤ$Z�r�P��/polyfill-iconv/Resources/charset/from.cp857.phpnu�[���<?php

static $data = array (
  '' => '',
  '' => '',
  '' => '',
  '' => '',
  '' => '',
  '' => '',
  '' => '',
  '' => '',
  '' => '',
  '	' => '	',
  '
' => '
',
  '' => '',
  '' => '',
  '
' => '
',
  '' => '',
  '' => '',
  '' => '',
  '' => '',
  '' => '',
  '' => '',
  '' => '',
  '' => '',
  '' => '',
  '' => '',
  '' => '',
  '' => '',
  '' => '',
  '' => '',
  '' => '',
  '' => '',
  '' => '',
  '' => '',
  ' ' => ' ',
  '!' => '!',
  '"' => '"',
  '#' => '#',
  '$' => '$',
  '%' => '%',
  '&' => '&',
  '\'' => '\'',
  '(' => '(',
  ')' => ')',
  '*' => '*',
  '+' => '+',
  ',' => ',',
  '-' => '-',
  '.' => '.',
  '/' => '/',
  0 => '0',
  1 => '1',
  2 => '2',
  3 => '3',
  4 => '4',
  5 => '5',
  6 => '6',
  7 => '7',
  8 => '8',
  9 => '9',
  ':' => ':',
  ';' => ';',
  '<' => '<',
  '=' => '=',
  '>' => '>',
  '?' => '?',
  '@' => '@',
  'A' => 'A',
  'B' => 'B',
  'C' => 'C',
  'D' => 'D',
  'E' => 'E',
  'F' => 'F',
  'G' => 'G',
  'H' => 'H',
  'I' => 'I',
  'J' => 'J',
  'K' => 'K',
  'L' => 'L',
  'M' => 'M',
  'N' => 'N',
  'O' => 'O',
  'P' => 'P',
  'Q' => 'Q',
  'R' => 'R',
  'S' => 'S',
  'T' => 'T',
  'U' => 'U',
  'V' => 'V',
  'W' => 'W',
  'X' => 'X',
  'Y' => 'Y',
  'Z' => 'Z',
  '[' => '[',
  '\\' => '\\',
  ']' => ']',
  '^' => '^',
  '_' => '_',
  '`' => '`',
  'a' => 'a',
  'b' => 'b',
  'c' => 'c',
  'd' => 'd',
  'e' => 'e',
  'f' => 'f',
  'g' => 'g',
  'h' => 'h',
  'i' => 'i',
  'j' => 'j',
  'k' => 'k',
  'l' => 'l',
  'm' => 'm',
  'n' => 'n',
  'o' => 'o',
  'p' => 'p',
  'q' => 'q',
  'r' => 'r',
  's' => 's',
  't' => 't',
  'u' => 'u',
  'v' => 'v',
  'w' => 'w',
  'x' => 'x',
  'y' => 'y',
  'z' => 'z',
  '{' => '{',
  '|' => '|',
  '}' => '}',
  '~' => '~',
  '' => '',
  '�' => 'Ç',
  '�' => 'ü',
  '�' => 'é',
  '�' => 'â',
  '�' => 'ä',
  '�' => 'à',
  '�' => 'å',
  '�' => 'ç',
  '�' => 'ê',
  '�' => 'ë',
  '�' => 'è',
  '�' => 'ï',
  '�' => 'î',
  '�' => 'ı',
  '�' => 'Ä',
  '�' => 'Å',
  '�' => 'É',
  '�' => 'æ',
  '�' => 'Æ',
  '�' => 'ô',
  '�' => 'ö',
  '�' => 'ò',
  '�' => 'û',
  '�' => 'ù',
  '�' => 'İ',
  '�' => 'Ö',
  '�' => 'Ü',
  '�' => 'ø',
  '�' => '£',
  '�' => 'Ø',
  '�' => 'Ş',
  '�' => 'ş',
  '�' => 'á',
  '�' => 'í',
  '�' => 'ó',
  '�' => 'ú',
  '�' => 'ñ',
  '�' => 'Ñ',
  '�' => 'Ğ',
  '�' => 'ğ',
  '�' => '¿',
  '�' => '®',
  '�' => '¬',
  '�' => '½',
  '�' => '¼',
  '�' => '¡',
  '�' => '«',
  '�' => '»',
  '�' => '░',
  '�' => '▒',
  '�' => '▓',
  '�' => '│',
  '�' => '┤',
  '�' => 'Á',
  '�' => 'Â',
  '�' => 'À',
  '�' => '©',
  '�' => '╣',
  '�' => '║',
  '�' => '╗',
  '�' => '╝',
  '�' => '¢',
  '�' => '¥',
  '�' => '┐',
  '�' => '└',
  '�' => '┴',
  '�' => '┬',
  '�' => '├',
  '�' => '─',
  '�' => '┼',
  '�' => 'ã',
  '�' => 'Ã',
  '�' => '╚',
  '�' => '╔',
  '�' => '╩',
  '�' => '╦',
  '�' => '╠',
  '�' => '═',
  '�' => '╬',
  '�' => '¤',
  '�' => 'º',
  '�' => 'ª',
  '�' => 'Ê',
  '�' => 'Ë',
  '�' => 'È',
  '�' => 'Í',
  '�' => 'Î',
  '�' => 'Ï',
  '�' => '┘',
  '�' => '┌',
  '�' => '█',
  '�' => '▄',
  '�' => '¦',
  '�' => 'Ì',
  '�' => '▀',
  '�' => 'Ó',
  '�' => 'ß',
  '�' => 'Ô',
  '�' => 'Ò',
  '�' => 'õ',
  '�' => 'Õ',
  '�' => 'µ',
  '�' => '×',
  '�' => 'Ú',
  '�' => 'Û',
  '�' => 'Ù',
  '�' => 'ì',
  '�' => 'ÿ',
  '�' => '¯',
  '�' => '´',
  '�' => '­',
  '�' => '±',
  '�' => '¾',
  '�' => '¶',
  '�' => '§',
  '�' => '÷',
  '�' => '¸',
  '�' => '°',
  '�' => '¨',
  '�' => '·',
  '�' => '¹',
  '�' => '³',
  '�' => '²',
  '�' => '■',
  '�' => ' ',
);

$result =& $data;
unset($data);

return $result;
PKϤ$Z�~V��/polyfill-iconv/Resources/charset/from.cp950.phpnu�[���<?php

static $data = array (
  '' => '',
  '' => '',
  '' => '',
  '' => '',
  '' => '',
  '' => '',
  '' => '',
  '' => '',
  '' => '',
  '	' => '	',
  '
' => '
',
  '' => '',
  '' => '',
  '
' => '
',
  '' => '',
  '' => '',
  '' => '',
  '' => '',
  '' => '',
  '' => '',
  '' => '',
  '' => '',
  '' => '',
  '' => '',
  '' => '',
  '' => '',
  '' => '',
  '' => '',
  '' => '',
  '' => '',
  '' => '',
  '' => '',
  ' ' => ' ',
  '!' => '!',
  '"' => '"',
  '#' => '#',
  '$' => '$',
  '%' => '%',
  '&' => '&',
  '\'' => '\'',
  '(' => '(',
  ')' => ')',
  '*' => '*',
  '+' => '+',
  ',' => ',',
  '-' => '-',
  '.' => '.',
  '/' => '/',
  0 => '0',
  1 => '1',
  2 => '2',
  3 => '3',
  4 => '4',
  5 => '5',
  6 => '6',
  7 => '7',
  8 => '8',
  9 => '9',
  ':' => ':',
  ';' => ';',
  '<' => '<',
  '=' => '=',
  '>' => '>',
  '?' => '?',
  '@' => '@',
  'A' => 'A',
  'B' => 'B',
  'C' => 'C',
  'D' => 'D',
  'E' => 'E',
  'F' => 'F',
  'G' => 'G',
  'H' => 'H',
  'I' => 'I',
  'J' => 'J',
  'K' => 'K',
  'L' => 'L',
  'M' => 'M',
  'N' => 'N',
  'O' => 'O',
  'P' => 'P',
  'Q' => 'Q',
  'R' => 'R',
  'S' => 'S',
  'T' => 'T',
  'U' => 'U',
  'V' => 'V',
  'W' => 'W',
  'X' => 'X',
  'Y' => 'Y',
  'Z' => 'Z',
  '[' => '[',
  '\\' => '\\',
  ']' => ']',
  '^' => '^',
  '_' => '_',
  '`' => '`',
  'a' => 'a',
  'b' => 'b',
  'c' => 'c',
  'd' => 'd',
  'e' => 'e',
  'f' => 'f',
  'g' => 'g',
  'h' => 'h',
  'i' => 'i',
  'j' => 'j',
  'k' => 'k',
  'l' => 'l',
  'm' => 'm',
  'n' => 'n',
  'o' => 'o',
  'p' => 'p',
  'q' => 'q',
  'r' => 'r',
  's' => 's',
  't' => 't',
  'u' => 'u',
  'v' => 'v',
  'w' => 'w',
  'x' => 'x',
  'y' => 'y',
  'z' => 'z',
  '{' => '{',
  '|' => '|',
  '}' => '}',
  '~' => '~',
  '' => '',
  '�@' => ' ',
  '�A' => ',',
  '�B' => '、',
  '�C' => '。',
  '�D' => '.',
  '�E' => '‧',
  '�F' => ';',
  '�G' => ':',
  '�H' => '?',
  '�I' => '!',
  '�J' => '︰',
  '�K' => '…',
  '�L' => '‥',
  '�M' => '﹐',
  '�N' => '﹑',
  '�O' => '﹒',
  '�P' => '·',
  '�Q' => '﹔',
  '�R' => '﹕',
  '�S' => '﹖',
  '�T' => '﹗',
  '�U' => '|',
  '�V' => '–',
  '�W' => '︱',
  '�X' => '—',
  '�Y' => '︳',
  '�Z' => '╴',
  '�[' => '︴',
  '�\\' => '﹏',
  '�]' => '(',
  '�^' => ')',
  '�_' => '︵',
  '�`' => '︶',
  '�a' => '{',
  '�b' => '}',
  '�c' => '︷',
  '�d' => '︸',
  '�e' => '〔',
  '�f' => '〕',
  '�g' => '︹',
  '�h' => '︺',
  '�i' => '【',
  '�j' => '】',
  '�k' => '︻',
  '�l' => '︼',
  '�m' => '《',
  '�n' => '》',
  '�o' => '︽',
  '�p' => '︾',
  '�q' => '〈',
  '�r' => '〉',
  '�s' => '︿',
  '�t' => '﹀',
  '�u' => '「',
  '�v' => '」',
  '�w' => '﹁',
  '�x' => '﹂',
  '�y' => '『',
  '�z' => '』',
  '�{' => '﹃',
  '�|' => '﹄',
  '�}' => '﹙',
  '�~' => '﹚',
  '��' => '﹛',
  '��' => '﹜',
  '��' => '﹝',
  '��' => '﹞',
  '��' => '‘',
  '��' => '’',
  '��' => '“',
  '��' => '”',
  '��' => '〝',
  '��' => '〞',
  '��' => '‵',
  '��' => '′',
  '��' => '#',
  '��' => '&',
  '��' => '*',
  '��' => '※',
  '��' => '§',
  '��' => '〃',
  '��' => '○',
  '��' => '●',
  '��' => '△',
  '��' => '▲',
  '��' => '◎',
  '��' => '☆',
  '��' => '★',
  '��' => '◇',
  '��' => '◆',
  '��' => '□',
  '��' => '■',
  '��' => '▽',
  '��' => '▼',
  '��' => '㊣',
  '��' => '℅',
  '��' => '¯',
  '��' => ' ̄',
  '��' => '_',
  '��' => 'ˍ',
  '��' => '﹉',
  '��' => '﹊',
  '��' => '﹍',
  '��' => '﹎',
  '��' => '﹋',
  '��' => '﹌',
  '��' => '﹟',
  '��' => '﹠',
  '��' => '﹡',
  '��' => '+',
  '��' => '-',
  '��' => '×',
  '��' => '÷',
  '��' => '±',
  '��' => '√',
  '��' => '<',
  '��' => '>',
  '��' => '=',
  '��' => '≦',
  '��' => '≧',
  '��' => '≠',
  '��' => '∞',
  '��' => '≒',
  '��' => '≡',
  '��' => '﹢',
  '��' => '﹣',
  '��' => '﹤',
  '��' => '﹥',
  '��' => '﹦',
  '��' => '~',
  '��' => '∩',
  '��' => '∪',
  '��' => '⊥',
  '��' => '∠',
  '��' => '∟',
  '��' => '⊿',
  '��' => '㏒',
  '��' => '㏑',
  '��' => '∫',
  '��' => '∮',
  '��' => '∵',
  '��' => '∴',
  '��' => '♀',
  '��' => '♂',
  '��' => '⊕',
  '��' => '⊙',
  '��' => '↑',
  '��' => '↓',
  '��' => '←',
  '��' => '→',
  '��' => '↖',
  '��' => '↗',
  '��' => '↙',
  '��' => '↘',
  '��' => '∥',
  '��' => '∣',
  '��' => '/',
  '�@' => '\',
  '�A' => '∕',
  '�B' => '﹨',
  '�C' => '$',
  '�D' => '¥',
  '�E' => '〒',
  '�F' => '¢',
  '�G' => '£',
  '�H' => '%',
  '�I' => '@',
  '�J' => '℃',
  '�K' => '℉',
  '�L' => '﹩',
  '�M' => '﹪',
  '�N' => '﹫',
  '�O' => '㏕',
  '�P' => '㎜',
  '�Q' => '㎝',
  '�R' => '㎞',
  '�S' => '㏎',
  '�T' => '㎡',
  '�U' => '㎎',
  '�V' => '㎏',
  '�W' => '㏄',
  '�X' => '°',
  '�Y' => '兙',
  '�Z' => '兛',
  '�[' => '兞',
  '�\\' => '兝',
  '�]' => '兡',
  '�^' => '兣',
  '�_' => '嗧',
  '�`' => '瓩',
  '�a' => '糎',
  '�b' => '▁',
  '�c' => '▂',
  '�d' => '▃',
  '�e' => '▄',
  '�f' => '▅',
  '�g' => '▆',
  '�h' => '▇',
  '�i' => '█',
  '�j' => '▏',
  '�k' => '▎',
  '�l' => '▍',
  '�m' => '▌',
  '�n' => '▋',
  '�o' => '▊',
  '�p' => '▉',
  '�q' => '┼',
  '�r' => '┴',
  '�s' => '┬',
  '�t' => '┤',
  '�u' => '├',
  '�v' => '▔',
  '�w' => '─',
  '�x' => '│',
  '�y' => '▕',
  '�z' => '┌',
  '�{' => '┐',
  '�|' => '└',
  '�}' => '┘',
  '�~' => '╭',
  '��' => '╮',
  '��' => '╰',
  '��' => '╯',
  '��' => '═',
  '��' => '╞',
  '��' => '╪',
  '��' => '╡',
  '��' => '◢',
  '��' => '◣',
  '��' => '◥',
  '��' => '◤',
  '��' => '╱',
  '��' => '╲',
  '��' => '╳',
  '��' => '0',
  '��' => '1',
  '��' => '2',
  '��' => '3',
  '��' => '4',
  '��' => '5',
  '��' => '6',
  '��' => '7',
  '��' => '8',
  '��' => '9',
  '��' => 'Ⅰ',
  '��' => 'Ⅱ',
  '��' => 'Ⅲ',
  '��' => 'Ⅳ',
  '��' => 'Ⅴ',
  '��' => 'Ⅵ',
  '��' => 'Ⅶ',
  '��' => 'Ⅷ',
  '��' => 'Ⅸ',
  '��' => 'Ⅹ',
  '��' => '〡',
  '��' => '〢',
  '��' => '〣',
  '��' => '〤',
  '��' => '〥',
  '��' => '〦',
  '��' => '〧',
  '��' => '〨',
  '��' => '〩',
  '��' => '十',
  '��' => '卄',
  '��' => '卅',
  '��' => 'A',
  '��' => 'B',
  '��' => 'C',
  '��' => 'D',
  '��' => 'E',
  '��' => 'F',
  '��' => 'G',
  '��' => 'H',
  '��' => 'I',
  '��' => 'J',
  '��' => 'K',
  '��' => 'L',
  '��' => 'M',
  '��' => 'N',
  '��' => 'O',
  '��' => 'P',
  '��' => 'Q',
  '��' => 'R',
  '��' => 'S',
  '��' => 'T',
  '��' => 'U',
  '��' => 'V',
  '��' => 'W',
  '��' => 'X',
  '��' => 'Y',
  '��' => 'Z',
  '��' => 'a',
  '��' => 'b',
  '��' => 'c',
  '��' => 'd',
  '��' => 'e',
  '��' => 'f',
  '��' => 'g',
  '��' => 'h',
  '��' => 'i',
  '��' => 'j',
  '��' => 'k',
  '��' => 'l',
  '��' => 'm',
  '��' => 'n',
  '��' => 'o',
  '��' => 'p',
  '��' => 'q',
  '��' => 'r',
  '��' => 's',
  '��' => 't',
  '��' => 'u',
  '��' => 'v',
  '�@' => 'w',
  '�A' => 'x',
  '�B' => 'y',
  '�C' => 'z',
  '�D' => 'Α',
  '�E' => 'Β',
  '�F' => 'Γ',
  '�G' => 'Δ',
  '�H' => 'Ε',
  '�I' => 'Ζ',
  '�J' => 'Η',
  '�K' => 'Θ',
  '�L' => 'Ι',
  '�M' => 'Κ',
  '�N' => 'Λ',
  '�O' => 'Μ',
  '�P' => 'Ν',
  '�Q' => 'Ξ',
  '�R' => 'Ο',
  '�S' => 'Π',
  '�T' => 'Ρ',
  '�U' => 'Σ',
  '�V' => 'Τ',
  '�W' => 'Υ',
  '�X' => 'Φ',
  '�Y' => 'Χ',
  '�Z' => 'Ψ',
  '�[' => 'Ω',
  '�\\' => 'α',
  '�]' => 'β',
  '�^' => 'γ',
  '�_' => 'δ',
  '�`' => 'ε',
  '�a' => 'ζ',
  '�b' => 'η',
  '�c' => 'θ',
  '�d' => 'ι',
  '�e' => 'κ',
  '�f' => 'λ',
  '�g' => 'μ',
  '�h' => 'ν',
  '�i' => 'ξ',
  '�j' => 'ο',
  '�k' => 'π',
  '�l' => 'ρ',
  '�m' => 'σ',
  '�n' => 'τ',
  '�o' => 'υ',
  '�p' => 'φ',
  '�q' => 'χ',
  '�r' => 'ψ',
  '�s' => 'ω',
  '�t' => 'ㄅ',
  '�u' => 'ㄆ',
  '�v' => 'ㄇ',
  '�w' => 'ㄈ',
  '�x' => 'ㄉ',
  '�y' => 'ㄊ',
  '�z' => 'ㄋ',
  '�{' => 'ㄌ',
  '�|' => 'ㄍ',
  '�}' => 'ㄎ',
  '�~' => 'ㄏ',
  '��' => 'ㄐ',
  '��' => 'ㄑ',
  '��' => 'ㄒ',
  '��' => 'ㄓ',
  '��' => 'ㄔ',
  '��' => 'ㄕ',
  '��' => 'ㄖ',
  '��' => 'ㄗ',
  '��' => 'ㄘ',
  '��' => 'ㄙ',
  '��' => 'ㄚ',
  '��' => 'ㄛ',
  '��' => 'ㄜ',
  '��' => 'ㄝ',
  '��' => 'ㄞ',
  '��' => 'ㄟ',
  '��' => 'ㄠ',
  '��' => 'ㄡ',
  '��' => 'ㄢ',
  '��' => 'ㄣ',
  '��' => 'ㄤ',
  '��' => 'ㄥ',
  '��' => 'ㄦ',
  '��' => 'ㄧ',
  '��' => 'ㄨ',
  '��' => 'ㄩ',
  '��' => '˙',
  '��' => 'ˉ',
  '��' => 'ˊ',
  '��' => 'ˇ',
  '��' => 'ˋ',
  '��' => '€',
  '�@' => '一',
  '�A' => '乙',
  '�B' => '丁',
  '�C' => '七',
  '�D' => '乃',
  '�E' => '九',
  '�F' => '了',
  '�G' => '二',
  '�H' => '人',
  '�I' => '儿',
  '�J' => '入',
  '�K' => '八',
  '�L' => '几',
  '�M' => '刀',
  '�N' => '刁',
  '�O' => '力',
  '�P' => '匕',
  '�Q' => '十',
  '�R' => '卜',
  '�S' => '又',
  '�T' => '三',
  '�U' => '下',
  '�V' => '丈',
  '�W' => '上',
  '�X' => '丫',
  '�Y' => '丸',
  '�Z' => '凡',
  '�[' => '久',
  '�\\' => '么',
  '�]' => '也',
  '�^' => '乞',
  '�_' => '于',
  '�`' => '亡',
  '�a' => '兀',
  '�b' => '刃',
  '�c' => '勺',
  '�d' => '千',
  '�e' => '叉',
  '�f' => '口',
  '�g' => '土',
  '�h' => '士',
  '�i' => '夕',
  '�j' => '大',
  '�k' => '女',
  '�l' => '子',
  '�m' => '孑',
  '�n' => '孓',
  '�o' => '寸',
  '�p' => '小',
  '�q' => '尢',
  '�r' => '尸',
  '�s' => '山',
  '�t' => '川',
  '�u' => '工',
  '�v' => '己',
  '�w' => '已',
  '�x' => '巳',
  '�y' => '巾',
  '�z' => '干',
  '�{' => '廾',
  '�|' => '弋',
  '�}' => '弓',
  '�~' => '才',
  '��' => '丑',
  '��' => '丐',
  '��' => '不',
  '��' => '中',
  '��' => '丰',
  '��' => '丹',
  '��' => '之',
  '��' => '尹',
  '��' => '予',
  '��' => '云',
  '��' => '井',
  '��' => '互',
  '��' => '五',
  '��' => '亢',
  '��' => '仁',
  '��' => '什',
  '��' => '仃',
  '��' => '仆',
  '��' => '仇',
  '��' => '仍',
  '��' => '今',
  '��' => '介',
  '��' => '仄',
  '��' => '元',
  '��' => '允',
  '��' => '內',
  '��' => '六',
  '��' => '兮',
  '��' => '公',
  '��' => '冗',
  '��' => '凶',
  '��' => '分',
  '��' => '切',
  '��' => '刈',
  '��' => '勻',
  '��' => '勾',
  '��' => '勿',
  '��' => '化',
  '��' => '匹',
  '��' => '午',
  '��' => '升',
  '��' => '卅',
  '��' => '卞',
  '��' => '厄',
  '��' => '友',
  '��' => '及',
  '��' => '反',
  '��' => '壬',
  '��' => '天',
  '��' => '夫',
  '��' => '太',
  '��' => '夭',
  '��' => '孔',
  '��' => '少',
  '��' => '尤',
  '��' => '尺',
  '��' => '屯',
  '��' => '巴',
  '��' => '幻',
  '��' => '廿',
  '��' => '弔',
  '��' => '引',
  '��' => '心',
  '��' => '戈',
  '��' => '戶',
  '��' => '手',
  '��' => '扎',
  '��' => '支',
  '��' => '文',
  '��' => '斗',
  '��' => '斤',
  '��' => '方',
  '��' => '日',
  '��' => '曰',
  '��' => '月',
  '��' => '木',
  '��' => '欠',
  '��' => '止',
  '��' => '歹',
  '��' => '毋',
  '��' => '比',
  '��' => '毛',
  '��' => '氏',
  '��' => '水',
  '��' => '火',
  '��' => '爪',
  '��' => '父',
  '��' => '爻',
  '��' => '片',
  '��' => '牙',
  '��' => '牛',
  '��' => '犬',
  '��' => '王',
  '��' => '丙',
  '�@' => '世',
  '�A' => '丕',
  '�B' => '且',
  '�C' => '丘',
  '�D' => '主',
  '�E' => '乍',
  '�F' => '乏',
  '�G' => '乎',
  '�H' => '以',
  '�I' => '付',
  '�J' => '仔',
  '�K' => '仕',
  '�L' => '他',
  '�M' => '仗',
  '�N' => '代',
  '�O' => '令',
  '�P' => '仙',
  '�Q' => '仞',
  '�R' => '充',
  '�S' => '兄',
  '�T' => '冉',
  '�U' => '冊',
  '�V' => '冬',
  '�W' => '凹',
  '�X' => '出',
  '�Y' => '凸',
  '�Z' => '刊',
  '�[' => '加',
  '�\\' => '功',
  '�]' => '包',
  '�^' => '匆',
  '�_' => '北',
  '�`' => '匝',
  '�a' => '仟',
  '�b' => '半',
  '�c' => '卉',
  '�d' => '卡',
  '�e' => '占',
  '�f' => '卯',
  '�g' => '卮',
  '�h' => '去',
  '�i' => '可',
  '�j' => '古',
  '�k' => '右',
  '�l' => '召',
  '�m' => '叮',
  '�n' => '叩',
  '�o' => '叨',
  '�p' => '叼',
  '�q' => '司',
  '�r' => '叵',
  '�s' => '叫',
  '�t' => '另',
  '�u' => '只',
  '�v' => '史',
  '�w' => '叱',
  '�x' => '台',
  '�y' => '句',
  '�z' => '叭',
  '�{' => '叻',
  '�|' => '四',
  '�}' => '囚',
  '�~' => '外',
  '��' => '央',
  '��' => '失',
  '��' => '奴',
  '��' => '奶',
  '��' => '孕',
  '��' => '它',
  '��' => '尼',
  '��' => '巨',
  '��' => '巧',
  '��' => '左',
  '��' => '市',
  '��' => '布',
  '��' => '平',
  '��' => '幼',
  '��' => '弁',
  '��' => '弘',
  '��' => '弗',
  '��' => '必',
  '��' => '戊',
  '��' => '打',
  '��' => '扔',
  '��' => '扒',
  '��' => '扑',
  '��' => '斥',
  '��' => '旦',
  '��' => '朮',
  '��' => '本',
  '��' => '未',
  '��' => '末',
  '��' => '札',
  '��' => '正',
  '��' => '母',
  '��' => '民',
  '��' => '氐',
  '��' => '永',
  '��' => '汁',
  '��' => '汀',
  '��' => '氾',
  '��' => '犯',
  '��' => '玄',
  '��' => '玉',
  '��' => '瓜',
  '��' => '瓦',
  '��' => '甘',
  '��' => '生',
  '��' => '用',
  '��' => '甩',
  '��' => '田',
  '��' => '由',
  '��' => '甲',
  '��' => '申',
  '��' => '疋',
  '��' => '白',
  '��' => '皮',
  '��' => '皿',
  '��' => '目',
  '��' => '矛',
  '��' => '矢',
  '��' => '石',
  '��' => '示',
  '��' => '禾',
  '��' => '穴',
  '��' => '立',
  '��' => '丞',
  '��' => '丟',
  '��' => '乒',
  '��' => '乓',
  '��' => '乩',
  '��' => '亙',
  '��' => '交',
  '��' => '亦',
  '��' => '亥',
  '��' => '仿',
  '��' => '伉',
  '��' => '伙',
  '��' => '伊',
  '��' => '伕',
  '��' => '伍',
  '��' => '伐',
  '��' => '休',
  '��' => '伏',
  '��' => '仲',
  '��' => '件',
  '��' => '任',
  '��' => '仰',
  '��' => '仳',
  '��' => '份',
  '��' => '企',
  '��' => '伋',
  '��' => '光',
  '��' => '兇',
  '��' => '兆',
  '��' => '先',
  '��' => '全',
  '�@' => '共',
  '�A' => '再',
  '�B' => '冰',
  '�C' => '列',
  '�D' => '刑',
  '�E' => '划',
  '�F' => '刎',
  '�G' => '刖',
  '�H' => '劣',
  '�I' => '匈',
  '�J' => '匡',
  '�K' => '匠',
  '�L' => '印',
  '�M' => '危',
  '�N' => '吉',
  '�O' => '吏',
  '�P' => '同',
  '�Q' => '吊',
  '�R' => '吐',
  '�S' => '吁',
  '�T' => '吋',
  '�U' => '各',
  '�V' => '向',
  '�W' => '名',
  '�X' => '合',
  '�Y' => '吃',
  '�Z' => '后',
  '�[' => '吆',
  '�\\' => '吒',
  '�]' => '因',
  '�^' => '回',
  '�_' => '囝',
  '�`' => '圳',
  '�a' => '地',
  '�b' => '在',
  '�c' => '圭',
  '�d' => '圬',
  '�e' => '圯',
  '�f' => '圩',
  '�g' => '夙',
  '�h' => '多',
  '�i' => '夷',
  '�j' => '夸',
  '�k' => '妄',
  '�l' => '奸',
  '�m' => '妃',
  '�n' => '好',
  '�o' => '她',
  '�p' => '如',
  '�q' => '妁',
  '�r' => '字',
  '�s' => '存',
  '�t' => '宇',
  '�u' => '守',
  '�v' => '宅',
  '�w' => '安',
  '�x' => '寺',
  '�y' => '尖',
  '�z' => '屹',
  '�{' => '州',
  '�|' => '帆',
  '�}' => '并',
  '�~' => '年',
  '��' => '式',
  '��' => '弛',
  '��' => '忙',
  '��' => '忖',
  '��' => '戎',
  '��' => '戌',
  '��' => '戍',
  '��' => '成',
  '��' => '扣',
  '��' => '扛',
  '��' => '托',
  '��' => '收',
  '��' => '早',
  '��' => '旨',
  '��' => '旬',
  '��' => '旭',
  '��' => '曲',
  '��' => '曳',
  '��' => '有',
  '��' => '朽',
  '��' => '朴',
  '��' => '朱',
  '��' => '朵',
  '��' => '次',
  '��' => '此',
  '��' => '死',
  '��' => '氖',
  '��' => '汝',
  '��' => '汗',
  '��' => '汙',
  '��' => '江',
  '��' => '池',
  '��' => '汐',
  '��' => '汕',
  '��' => '污',
  '��' => '汛',
  '��' => '汍',
  '��' => '汎',
  '��' => '灰',
  '��' => '牟',
  '��' => '牝',
  '��' => '百',
  '��' => '竹',
  '��' => '米',
  '��' => '糸',
  '��' => '缶',
  '��' => '羊',
  '��' => '羽',
  '��' => '老',
  '��' => '考',
  '��' => '而',
  '��' => '耒',
  '��' => '耳',
  '��' => '聿',
  '��' => '肉',
  '��' => '肋',
  '��' => '肌',
  '��' => '臣',
  '��' => '自',
  '��' => '至',
  '��' => '臼',
  '��' => '舌',
  '��' => '舛',
  '��' => '舟',
  '��' => '艮',
  '��' => '色',
  '��' => '艾',
  '��' => '虫',
  '��' => '血',
  '��' => '行',
  '��' => '衣',
  '��' => '西',
  '��' => '阡',
  '��' => '串',
  '��' => '亨',
  '��' => '位',
  '��' => '住',
  '��' => '佇',
  '��' => '佗',
  '��' => '佞',
  '��' => '伴',
  '��' => '佛',
  '��' => '何',
  '��' => '估',
  '��' => '佐',
  '��' => '佑',
  '��' => '伽',
  '��' => '伺',
  '��' => '伸',
  '��' => '佃',
  '��' => '佔',
  '��' => '似',
  '��' => '但',
  '��' => '佣',
  '�@' => '作',
  '�A' => '你',
  '�B' => '伯',
  '�C' => '低',
  '�D' => '伶',
  '�E' => '余',
  '�F' => '佝',
  '�G' => '佈',
  '�H' => '佚',
  '�I' => '兌',
  '�J' => '克',
  '�K' => '免',
  '�L' => '兵',
  '�M' => '冶',
  '�N' => '冷',
  '�O' => '別',
  '�P' => '判',
  '�Q' => '利',
  '�R' => '刪',
  '�S' => '刨',
  '�T' => '劫',
  '�U' => '助',
  '�V' => '努',
  '�W' => '劬',
  '�X' => '匣',
  '�Y' => '即',
  '�Z' => '卵',
  '�[' => '吝',
  '�\\' => '吭',
  '�]' => '吞',
  '�^' => '吾',
  '�_' => '否',
  '�`' => '呎',
  '�a' => '吧',
  '�b' => '呆',
  '�c' => '呃',
  '�d' => '吳',
  '�e' => '呈',
  '�f' => '呂',
  '�g' => '君',
  '�h' => '吩',
  '�i' => '告',
  '�j' => '吹',
  '�k' => '吻',
  '�l' => '吸',
  '�m' => '吮',
  '�n' => '吵',
  '�o' => '吶',
  '�p' => '吠',
  '�q' => '吼',
  '�r' => '呀',
  '�s' => '吱',
  '�t' => '含',
  '�u' => '吟',
  '�v' => '听',
  '�w' => '囪',
  '�x' => '困',
  '�y' => '囤',
  '�z' => '囫',
  '�{' => '坊',
  '�|' => '坑',
  '�}' => '址',
  '�~' => '坍',
  '��' => '均',
  '��' => '坎',
  '��' => '圾',
  '��' => '坐',
  '��' => '坏',
  '��' => '圻',
  '��' => '壯',
  '��' => '夾',
  '��' => '妝',
  '��' => '妒',
  '��' => '妨',
  '��' => '妞',
  '��' => '妣',
  '��' => '妙',
  '��' => '妖',
  '��' => '妍',
  '��' => '妤',
  '��' => '妓',
  '��' => '妊',
  '��' => '妥',
  '��' => '孝',
  '��' => '孜',
  '��' => '孚',
  '��' => '孛',
  '��' => '完',
  '��' => '宋',
  '��' => '宏',
  '��' => '尬',
  '��' => '局',
  '��' => '屁',
  '��' => '尿',
  '��' => '尾',
  '��' => '岐',
  '��' => '岑',
  '��' => '岔',
  '��' => '岌',
  '��' => '巫',
  '��' => '希',
  '��' => '序',
  '��' => '庇',
  '��' => '床',
  '��' => '廷',
  '��' => '弄',
  '��' => '弟',
  '��' => '彤',
  '��' => '形',
  '��' => '彷',
  '��' => '役',
  '��' => '忘',
  '��' => '忌',
  '��' => '志',
  '��' => '忍',
  '��' => '忱',
  '��' => '快',
  '��' => '忸',
  '��' => '忪',
  '��' => '戒',
  '��' => '我',
  '��' => '抄',
  '��' => '抗',
  '��' => '抖',
  '��' => '技',
  '��' => '扶',
  '��' => '抉',
  '��' => '扭',
  '��' => '把',
  '��' => '扼',
  '��' => '找',
  '��' => '批',
  '��' => '扳',
  '��' => '抒',
  '��' => '扯',
  '��' => '折',
  '��' => '扮',
  '��' => '投',
  '��' => '抓',
  '��' => '抑',
  '��' => '抆',
  '��' => '改',
  '��' => '攻',
  '��' => '攸',
  '��' => '旱',
  '��' => '更',
  '��' => '束',
  '��' => '李',
  '��' => '杏',
  '��' => '材',
  '��' => '村',
  '��' => '杜',
  '��' => '杖',
  '��' => '杞',
  '��' => '杉',
  '��' => '杆',
  '��' => '杠',
  '�@' => '杓',
  '�A' => '杗',
  '�B' => '步',
  '�C' => '每',
  '�D' => '求',
  '�E' => '汞',
  '�F' => '沙',
  '�G' => '沁',
  '�H' => '沈',
  '�I' => '沉',
  '�J' => '沅',
  '�K' => '沛',
  '�L' => '汪',
  '�M' => '決',
  '�N' => '沐',
  '�O' => '汰',
  '�P' => '沌',
  '�Q' => '汨',
  '�R' => '沖',
  '�S' => '沒',
  '�T' => '汽',
  '�U' => '沃',
  '�V' => '汲',
  '�W' => '汾',
  '�X' => '汴',
  '�Y' => '沆',
  '�Z' => '汶',
  '�[' => '沍',
  '�\\' => '沔',
  '�]' => '沘',
  '�^' => '沂',
  '�_' => '灶',
  '�`' => '灼',
  '�a' => '災',
  '�b' => '灸',
  '�c' => '牢',
  '�d' => '牡',
  '�e' => '牠',
  '�f' => '狄',
  '�g' => '狂',
  '�h' => '玖',
  '�i' => '甬',
  '�j' => '甫',
  '�k' => '男',
  '�l' => '甸',
  '�m' => '皂',
  '�n' => '盯',
  '�o' => '矣',
  '�p' => '私',
  '�q' => '秀',
  '�r' => '禿',
  '�s' => '究',
  '�t' => '系',
  '�u' => '罕',
  '�v' => '肖',
  '�w' => '肓',
  '�x' => '肝',
  '�y' => '肘',
  '�z' => '肛',
  '�{' => '肚',
  '�|' => '育',
  '�}' => '良',
  '�~' => '芒',
  '��' => '芋',
  '��' => '芍',
  '��' => '見',
  '��' => '角',
  '��' => '言',
  '��' => '谷',
  '��' => '豆',
  '��' => '豕',
  '��' => '貝',
  '��' => '赤',
  '��' => '走',
  '��' => '足',
  '��' => '身',
  '��' => '車',
  '��' => '辛',
  '��' => '辰',
  '��' => '迂',
  '��' => '迆',
  '��' => '迅',
  '��' => '迄',
  '��' => '巡',
  '��' => '邑',
  '��' => '邢',
  '��' => '邪',
  '��' => '邦',
  '��' => '那',
  '��' => '酉',
  '��' => '釆',
  '��' => '里',
  '��' => '防',
  '��' => '阮',
  '��' => '阱',
  '��' => '阪',
  '��' => '阬',
  '��' => '並',
  '��' => '乖',
  '��' => '乳',
  '��' => '事',
  '��' => '些',
  '��' => '亞',
  '��' => '享',
  '��' => '京',
  '��' => '佯',
  '��' => '依',
  '��' => '侍',
  '��' => '佳',
  '��' => '使',
  '��' => '佬',
  '��' => '供',
  '��' => '例',
  '��' => '來',
  '��' => '侃',
  '��' => '佰',
  '��' => '併',
  '��' => '侈',
  '��' => '佩',
  '��' => '佻',
  '��' => '侖',
  '��' => '佾',
  '��' => '侏',
  '��' => '侑',
  '��' => '佺',
  '��' => '兔',
  '��' => '兒',
  '��' => '兕',
  '��' => '兩',
  '��' => '具',
  '��' => '其',
  '��' => '典',
  '��' => '冽',
  '��' => '函',
  '��' => '刻',
  '��' => '券',
  '��' => '刷',
  '��' => '刺',
  '��' => '到',
  '��' => '刮',
  '��' => '制',
  '��' => '剁',
  '��' => '劾',
  '��' => '劻',
  '��' => '卒',
  '��' => '協',
  '��' => '卓',
  '��' => '卑',
  '��' => '卦',
  '��' => '卷',
  '��' => '卸',
  '��' => '卹',
  '��' => '取',
  '��' => '叔',
  '��' => '受',
  '��' => '味',
  '��' => '呵',
  '�@' => '咖',
  '�A' => '呸',
  '�B' => '咕',
  '�C' => '咀',
  '�D' => '呻',
  '�E' => '呷',
  '�F' => '咄',
  '�G' => '咒',
  '�H' => '咆',
  '�I' => '呼',
  '�J' => '咐',
  '�K' => '呱',
  '�L' => '呶',
  '�M' => '和',
  '�N' => '咚',
  '�O' => '呢',
  '�P' => '周',
  '�Q' => '咋',
  '�R' => '命',
  '�S' => '咎',
  '�T' => '固',
  '�U' => '垃',
  '�V' => '坷',
  '�W' => '坪',
  '�X' => '坩',
  '�Y' => '坡',
  '�Z' => '坦',
  '�[' => '坤',
  '�\\' => '坼',
  '�]' => '夜',
  '�^' => '奉',
  '�_' => '奇',
  '�`' => '奈',
  '�a' => '奄',
  '�b' => '奔',
  '�c' => '妾',
  '�d' => '妻',
  '�e' => '委',
  '�f' => '妹',
  '�g' => '妮',
  '�h' => '姑',
  '�i' => '姆',
  '�j' => '姐',
  '�k' => '姍',
  '�l' => '始',
  '�m' => '姓',
  '�n' => '姊',
  '�o' => '妯',
  '�p' => '妳',
  '�q' => '姒',
  '�r' => '姅',
  '�s' => '孟',
  '�t' => '孤',
  '�u' => '季',
  '�v' => '宗',
  '�w' => '定',
  '�x' => '官',
  '�y' => '宜',
  '�z' => '宙',
  '�{' => '宛',
  '�|' => '尚',
  '�}' => '屈',
  '�~' => '居',
  '��' => '屆',
  '��' => '岷',
  '��' => '岡',
  '��' => '岸',
  '��' => '岩',
  '��' => '岫',
  '��' => '岱',
  '��' => '岳',
  '��' => '帘',
  '��' => '帚',
  '��' => '帖',
  '��' => '帕',
  '��' => '帛',
  '��' => '帑',
  '��' => '幸',
  '��' => '庚',
  '��' => '店',
  '��' => '府',
  '��' => '底',
  '��' => '庖',
  '��' => '延',
  '��' => '弦',
  '��' => '弧',
  '��' => '弩',
  '��' => '往',
  '��' => '征',
  '��' => '彿',
  '��' => '彼',
  '��' => '忝',
  '��' => '忠',
  '��' => '忽',
  '��' => '念',
  '��' => '忿',
  '��' => '怏',
  '��' => '怔',
  '��' => '怯',
  '��' => '怵',
  '��' => '怖',
  '��' => '怪',
  '��' => '怕',
  '��' => '怡',
  '��' => '性',
  '��' => '怩',
  '��' => '怫',
  '��' => '怛',
  '��' => '或',
  '��' => '戕',
  '��' => '房',
  '��' => '戾',
  '��' => '所',
  '��' => '承',
  '��' => '拉',
  '��' => '拌',
  '��' => '拄',
  '��' => '抿',
  '��' => '拂',
  '��' => '抹',
  '��' => '拒',
  '��' => '招',
  '��' => '披',
  '��' => '拓',
  '��' => '拔',
  '��' => '拋',
  '��' => '拈',
  '��' => '抨',
  '��' => '抽',
  '��' => '押',
  '��' => '拐',
  '��' => '拙',
  '��' => '拇',
  '��' => '拍',
  '��' => '抵',
  '��' => '拚',
  '��' => '抱',
  '��' => '拘',
  '��' => '拖',
  '��' => '拗',
  '��' => '拆',
  '��' => '抬',
  '��' => '拎',
  '��' => '放',
  '��' => '斧',
  '��' => '於',
  '��' => '旺',
  '��' => '昔',
  '��' => '易',
  '��' => '昌',
  '��' => '昆',
  '��' => '昂',
  '��' => '明',
  '��' => '昀',
  '��' => '昏',
  '��' => '昕',
  '��' => '昊',
  '�@' => '昇',
  '�A' => '服',
  '�B' => '朋',
  '�C' => '杭',
  '�D' => '枋',
  '�E' => '枕',
  '�F' => '東',
  '�G' => '果',
  '�H' => '杳',
  '�I' => '杷',
  '�J' => '枇',
  '�K' => '枝',
  '�L' => '林',
  '�M' => '杯',
  '�N' => '杰',
  '�O' => '板',
  '�P' => '枉',
  '�Q' => '松',
  '�R' => '析',
  '�S' => '杵',
  '�T' => '枚',
  '�U' => '枓',
  '�V' => '杼',
  '�W' => '杪',
  '�X' => '杲',
  '�Y' => '欣',
  '�Z' => '武',
  '�[' => '歧',
  '�\\' => '歿',
  '�]' => '氓',
  '�^' => '氛',
  '�_' => '泣',
  '�`' => '注',
  '�a' => '泳',
  '�b' => '沱',
  '�c' => '泌',
  '�d' => '泥',
  '�e' => '河',
  '�f' => '沽',
  '�g' => '沾',
  '�h' => '沼',
  '�i' => '波',
  '�j' => '沫',
  '�k' => '法',
  '�l' => '泓',
  '�m' => '沸',
  '�n' => '泄',
  '�o' => '油',
  '�p' => '況',
  '�q' => '沮',
  '�r' => '泗',
  '�s' => '泅',
  '�t' => '泱',
  '�u' => '沿',
  '�v' => '治',
  '�w' => '泡',
  '�x' => '泛',
  '�y' => '泊',
  '�z' => '沬',
  '�{' => '泯',
  '�|' => '泜',
  '�}' => '泖',
  '�~' => '泠',
  '��' => '炕',
  '��' => '炎',
  '��' => '炒',
  '��' => '炊',
  '��' => '炙',
  '��' => '爬',
  '��' => '爭',
  '��' => '爸',
  '��' => '版',
  '��' => '牧',
  '��' => '物',
  '��' => '狀',
  '��' => '狎',
  '��' => '狙',
  '��' => '狗',
  '��' => '狐',
  '��' => '玩',
  '��' => '玨',
  '��' => '玟',
  '��' => '玫',
  '��' => '玥',
  '��' => '甽',
  '��' => '疝',
  '��' => '疙',
  '��' => '疚',
  '��' => '的',
  '��' => '盂',
  '��' => '盲',
  '��' => '直',
  '��' => '知',
  '��' => '矽',
  '��' => '社',
  '��' => '祀',
  '��' => '祁',
  '��' => '秉',
  '��' => '秈',
  '��' => '空',
  '��' => '穹',
  '��' => '竺',
  '��' => '糾',
  '��' => '罔',
  '��' => '羌',
  '��' => '羋',
  '��' => '者',
  '��' => '肺',
  '��' => '肥',
  '��' => '肢',
  '��' => '肱',
  '��' => '股',
  '��' => '肫',
  '��' => '肩',
  '��' => '肴',
  '��' => '肪',
  '��' => '肯',
  '��' => '臥',
  '��' => '臾',
  '��' => '舍',
  '��' => '芳',
  '��' => '芝',
  '��' => '芙',
  '��' => '芭',
  '��' => '芽',
  '��' => '芟',
  '��' => '芹',
  '��' => '花',
  '��' => '芬',
  '��' => '芥',
  '��' => '芯',
  '��' => '芸',
  '��' => '芣',
  '��' => '芰',
  '��' => '芾',
  '��' => '芷',
  '��' => '虎',
  '��' => '虱',
  '��' => '初',
  '��' => '表',
  '��' => '軋',
  '��' => '迎',
  '��' => '返',
  '��' => '近',
  '��' => '邵',
  '��' => '邸',
  '��' => '邱',
  '��' => '邶',
  '��' => '采',
  '��' => '金',
  '��' => '長',
  '��' => '門',
  '��' => '阜',
  '��' => '陀',
  '��' => '阿',
  '��' => '阻',
  '��' => '附',
  '�@' => '陂',
  '�A' => '隹',
  '�B' => '雨',
  '�C' => '青',
  '�D' => '非',
  '�E' => '亟',
  '�F' => '亭',
  '�G' => '亮',
  '�H' => '信',
  '�I' => '侵',
  '�J' => '侯',
  '�K' => '便',
  '�L' => '俠',
  '�M' => '俑',
  '�N' => '俏',
  '�O' => '保',
  '�P' => '促',
  '�Q' => '侶',
  '�R' => '俘',
  '�S' => '俟',
  '�T' => '俊',
  '�U' => '俗',
  '�V' => '侮',
  '�W' => '俐',
  '�X' => '俄',
  '�Y' => '係',
  '�Z' => '俚',
  '�[' => '俎',
  '�\\' => '俞',
  '�]' => '侷',
  '�^' => '兗',
  '�_' => '冒',
  '�`' => '冑',
  '�a' => '冠',
  '�b' => '剎',
  '�c' => '剃',
  '�d' => '削',
  '�e' => '前',
  '�f' => '剌',
  '�g' => '剋',
  '�h' => '則',
  '�i' => '勇',
  '�j' => '勉',
  '�k' => '勃',
  '�l' => '勁',
  '�m' => '匍',
  '�n' => '南',
  '�o' => '卻',
  '�p' => '厚',
  '�q' => '叛',
  '�r' => '咬',
  '�s' => '哀',
  '�t' => '咨',
  '�u' => '哎',
  '�v' => '哉',
  '�w' => '咸',
  '�x' => '咦',
  '�y' => '咳',
  '�z' => '哇',
  '�{' => '哂',
  '�|' => '咽',
  '�}' => '咪',
  '�~' => '品',
  '��' => '哄',
  '��' => '哈',
  '��' => '咯',
  '��' => '咫',
  '��' => '咱',
  '��' => '咻',
  '��' => '咩',
  '��' => '咧',
  '��' => '咿',
  '��' => '囿',
  '��' => '垂',
  '��' => '型',
  '��' => '垠',
  '��' => '垣',
  '��' => '垢',
  '��' => '城',
  '��' => '垮',
  '��' => '垓',
  '��' => '奕',
  '��' => '契',
  '��' => '奏',
  '��' => '奎',
  '��' => '奐',
  '��' => '姜',
  '��' => '姘',
  '��' => '姿',
  '��' => '姣',
  '��' => '姨',
  '��' => '娃',
  '��' => '姥',
  '��' => '姪',
  '��' => '姚',
  '��' => '姦',
  '��' => '威',
  '��' => '姻',
  '��' => '孩',
  '��' => '宣',
  '��' => '宦',
  '��' => '室',
  '��' => '客',
  '��' => '宥',
  '��' => '封',
  '��' => '屎',
  '��' => '屏',
  '��' => '屍',
  '��' => '屋',
  '��' => '峙',
  '��' => '峒',
  '��' => '巷',
  '��' => '帝',
  '��' => '帥',
  '��' => '帟',
  '��' => '幽',
  '��' => '庠',
  '��' => '度',
  '��' => '建',
  '��' => '弈',
  '��' => '弭',
  '��' => '彥',
  '��' => '很',
  '��' => '待',
  '��' => '徊',
  '��' => '律',
  '��' => '徇',
  '��' => '後',
  '��' => '徉',
  '��' => '怒',
  '��' => '思',
  '��' => '怠',
  '��' => '急',
  '��' => '怎',
  '��' => '怨',
  '��' => '恍',
  '��' => '恰',
  '��' => '恨',
  '��' => '恢',
  '��' => '恆',
  '��' => '恃',
  '��' => '恬',
  '��' => '恫',
  '��' => '恪',
  '��' => '恤',
  '��' => '扁',
  '��' => '拜',
  '��' => '挖',
  '��' => '按',
  '��' => '拼',
  '��' => '拭',
  '��' => '持',
  '��' => '拮',
  '��' => '拽',
  '��' => '指',
  '��' => '拱',
  '��' => '拷',
  '�@' => '拯',
  '�A' => '括',
  '�B' => '拾',
  '�C' => '拴',
  '�D' => '挑',
  '�E' => '挂',
  '�F' => '政',
  '�G' => '故',
  '�H' => '斫',
  '�I' => '施',
  '�J' => '既',
  '�K' => '春',
  '�L' => '昭',
  '�M' => '映',
  '�N' => '昧',
  '�O' => '是',
  '�P' => '星',
  '�Q' => '昨',
  '�R' => '昱',
  '�S' => '昤',
  '�T' => '曷',
  '�U' => '柿',
  '�V' => '染',
  '�W' => '柱',
  '�X' => '柔',
  '�Y' => '某',
  '�Z' => '柬',
  '�[' => '架',
  '�\\' => '枯',
  '�]' => '柵',
  '�^' => '柩',
  '�_' => '柯',
  '�`' => '柄',
  '�a' => '柑',
  '�b' => '枴',
  '�c' => '柚',
  '�d' => '查',
  '�e' => '枸',
  '�f' => '柏',
  '�g' => '柞',
  '�h' => '柳',
  '�i' => '枰',
  '�j' => '柙',
  '�k' => '柢',
  '�l' => '柝',
  '�m' => '柒',
  '�n' => '歪',
  '�o' => '殃',
  '�p' => '殆',
  '�q' => '段',
  '�r' => '毒',
  '�s' => '毗',
  '�t' => '氟',
  '�u' => '泉',
  '�v' => '洋',
  '�w' => '洲',
  '�x' => '洪',
  '�y' => '流',
  '�z' => '津',
  '�{' => '洌',
  '�|' => '洱',
  '�}' => '洞',
  '�~' => '洗',
  '��' => '活',
  '��' => '洽',
  '��' => '派',
  '��' => '洶',
  '��' => '洛',
  '��' => '泵',
  '��' => '洹',
  '��' => '洧',
  '��' => '洸',
  '��' => '洩',
  '��' => '洮',
  '��' => '洵',
  '��' => '洎',
  '��' => '洫',
  '��' => '炫',
  '��' => '為',
  '��' => '炳',
  '��' => '炬',
  '��' => '炯',
  '��' => '炭',
  '��' => '炸',
  '��' => '炮',
  '��' => '炤',
  '��' => '爰',
  '��' => '牲',
  '��' => '牯',
  '��' => '牴',
  '��' => '狩',
  '��' => '狠',
  '��' => '狡',
  '��' => '玷',
  '��' => '珊',
  '��' => '玻',
  '��' => '玲',
  '��' => '珍',
  '��' => '珀',
  '��' => '玳',
  '��' => '甚',
  '��' => '甭',
  '��' => '畏',
  '��' => '界',
  '��' => '畎',
  '��' => '畋',
  '��' => '疫',
  '��' => '疤',
  '��' => '疥',
  '��' => '疢',
  '��' => '疣',
  '��' => '癸',
  '��' => '皆',
  '��' => '皇',
  '��' => '皈',
  '��' => '盈',
  '��' => '盆',
  '��' => '盃',
  '��' => '盅',
  '��' => '省',
  '��' => '盹',
  '��' => '相',
  '��' => '眉',
  '��' => '看',
  '��' => '盾',
  '��' => '盼',
  '��' => '眇',
  '��' => '矜',
  '��' => '砂',
  '��' => '研',
  '��' => '砌',
  '��' => '砍',
  '��' => '祆',
  '��' => '祉',
  '��' => '祈',
  '��' => '祇',
  '��' => '禹',
  '��' => '禺',
  '��' => '科',
  '��' => '秒',
  '��' => '秋',
  '��' => '穿',
  '��' => '突',
  '��' => '竿',
  '��' => '竽',
  '��' => '籽',
  '��' => '紂',
  '��' => '紅',
  '��' => '紀',
  '��' => '紉',
  '��' => '紇',
  '��' => '約',
  '��' => '紆',
  '��' => '缸',
  '��' => '美',
  '��' => '羿',
  '��' => '耄',
  '�@' => '耐',
  '�A' => '耍',
  '�B' => '耑',
  '�C' => '耶',
  '�D' => '胖',
  '�E' => '胥',
  '�F' => '胚',
  '�G' => '胃',
  '�H' => '胄',
  '�I' => '背',
  '�J' => '胡',
  '�K' => '胛',
  '�L' => '胎',
  '�M' => '胞',
  '�N' => '胤',
  '�O' => '胝',
  '�P' => '致',
  '�Q' => '舢',
  '�R' => '苧',
  '�S' => '范',
  '�T' => '茅',
  '�U' => '苣',
  '�V' => '苛',
  '�W' => '苦',
  '�X' => '茄',
  '�Y' => '若',
  '�Z' => '茂',
  '�[' => '茉',
  '�\\' => '苒',
  '�]' => '苗',
  '�^' => '英',
  '�_' => '茁',
  '�`' => '苜',
  '�a' => '苔',
  '�b' => '苑',
  '�c' => '苞',
  '�d' => '苓',
  '�e' => '苟',
  '�f' => '苯',
  '�g' => '茆',
  '�h' => '虐',
  '�i' => '虹',
  '�j' => '虻',
  '�k' => '虺',
  '�l' => '衍',
  '�m' => '衫',
  '�n' => '要',
  '�o' => '觔',
  '�p' => '計',
  '�q' => '訂',
  '�r' => '訃',
  '�s' => '貞',
  '�t' => '負',
  '�u' => '赴',
  '�v' => '赳',
  '�w' => '趴',
  '�x' => '軍',
  '�y' => '軌',
  '�z' => '述',
  '�{' => '迦',
  '�|' => '迢',
  '�}' => '迪',
  '�~' => '迥',
  '��' => '迭',
  '��' => '迫',
  '��' => '迤',
  '��' => '迨',
  '��' => '郊',
  '��' => '郎',
  '��' => '郁',
  '��' => '郃',
  '��' => '酋',
  '��' => '酊',
  '��' => '重',
  '��' => '閂',
  '��' => '限',
  '��' => '陋',
  '��' => '陌',
  '��' => '降',
  '��' => '面',
  '��' => '革',
  '��' => '韋',
  '��' => '韭',
  '��' => '音',
  '��' => '頁',
  '��' => '風',
  '��' => '飛',
  '��' => '食',
  '��' => '首',
  '��' => '香',
  '��' => '乘',
  '��' => '亳',
  '��' => '倌',
  '��' => '倍',
  '��' => '倣',
  '��' => '俯',
  '��' => '倦',
  '��' => '倥',
  '��' => '俸',
  '��' => '倩',
  '��' => '倖',
  '��' => '倆',
  '��' => '值',
  '��' => '借',
  '��' => '倚',
  '��' => '倒',
  '��' => '們',
  '��' => '俺',
  '��' => '倀',
  '��' => '倔',
  '��' => '倨',
  '��' => '俱',
  '��' => '倡',
  '��' => '個',
  '��' => '候',
  '��' => '倘',
  '��' => '俳',
  '��' => '修',
  '��' => '倭',
  '��' => '倪',
  '��' => '俾',
  '��' => '倫',
  '��' => '倉',
  '��' => '兼',
  '��' => '冤',
  '��' => '冥',
  '��' => '冢',
  '��' => '凍',
  '��' => '凌',
  '��' => '准',
  '��' => '凋',
  '��' => '剖',
  '��' => '剜',
  '��' => '剔',
  '��' => '剛',
  '��' => '剝',
  '��' => '匪',
  '��' => '卿',
  '��' => '原',
  '��' => '厝',
  '��' => '叟',
  '��' => '哨',
  '��' => '唐',
  '��' => '唁',
  '��' => '唷',
  '��' => '哼',
  '��' => '哥',
  '��' => '哲',
  '��' => '唆',
  '��' => '哺',
  '��' => '唔',
  '��' => '哩',
  '��' => '哭',
  '��' => '員',
  '��' => '唉',
  '��' => '哮',
  '��' => '哪',
  '�@' => '哦',
  '�A' => '唧',
  '�B' => '唇',
  '�C' => '哽',
  '�D' => '唏',
  '�E' => '圃',
  '�F' => '圄',
  '�G' => '埂',
  '�H' => '埔',
  '�I' => '埋',
  '�J' => '埃',
  '�K' => '堉',
  '�L' => '夏',
  '�M' => '套',
  '�N' => '奘',
  '�O' => '奚',
  '�P' => '娑',
  '�Q' => '娘',
  '�R' => '娜',
  '�S' => '娟',
  '�T' => '娛',
  '�U' => '娓',
  '�V' => '姬',
  '�W' => '娠',
  '�X' => '娣',
  '�Y' => '娩',
  '�Z' => '娥',
  '�[' => '娌',
  '�\\' => '娉',
  '�]' => '孫',
  '�^' => '屘',
  '�_' => '宰',
  '�`' => '害',
  '�a' => '家',
  '�b' => '宴',
  '�c' => '宮',
  '�d' => '宵',
  '�e' => '容',
  '�f' => '宸',
  '�g' => '射',
  '�h' => '屑',
  '�i' => '展',
  '�j' => '屐',
  '�k' => '峭',
  '�l' => '峽',
  '�m' => '峻',
  '�n' => '峪',
  '�o' => '峨',
  '�p' => '峰',
  '�q' => '島',
  '�r' => '崁',
  '�s' => '峴',
  '�t' => '差',
  '�u' => '席',
  '�v' => '師',
  '�w' => '庫',
  '�x' => '庭',
  '�y' => '座',
  '�z' => '弱',
  '�{' => '徒',
  '�|' => '徑',
  '�}' => '徐',
  '�~' => '恙',
  '��' => '恣',
  '��' => '恥',
  '��' => '恐',
  '��' => '恕',
  '��' => '恭',
  '��' => '恩',
  '��' => '息',
  '��' => '悄',
  '��' => '悟',
  '��' => '悚',
  '��' => '悍',
  '��' => '悔',
  '��' => '悌',
  '��' => '悅',
  '��' => '悖',
  '��' => '扇',
  '��' => '拳',
  '��' => '挈',
  '��' => '拿',
  '��' => '捎',
  '��' => '挾',
  '��' => '振',
  '��' => '捕',
  '��' => '捂',
  '��' => '捆',
  '��' => '捏',
  '��' => '捉',
  '��' => '挺',
  '��' => '捐',
  '��' => '挽',
  '��' => '挪',
  '��' => '挫',
  '��' => '挨',
  '��' => '捍',
  '��' => '捌',
  '��' => '效',
  '��' => '敉',
  '��' => '料',
  '��' => '旁',
  '��' => '旅',
  '��' => '時',
  '��' => '晉',
  '��' => '晏',
  '��' => '晃',
  '��' => '晒',
  '��' => '晌',
  '��' => '晅',
  '��' => '晁',
  '��' => '書',
  '��' => '朔',
  '��' => '朕',
  '��' => '朗',
  '��' => '校',
  '��' => '核',
  '��' => '案',
  '��' => '框',
  '��' => '桓',
  '��' => '根',
  '��' => '桂',
  '��' => '桔',
  '��' => '栩',
  '��' => '梳',
  '��' => '栗',
  '��' => '桌',
  '��' => '桑',
  '��' => '栽',
  '��' => '柴',
  '��' => '桐',
  '��' => '桀',
  '��' => '格',
  '��' => '桃',
  '��' => '株',
  '��' => '桅',
  '��' => '栓',
  '��' => '栘',
  '��' => '桁',
  '��' => '殊',
  '��' => '殉',
  '��' => '殷',
  '��' => '氣',
  '��' => '氧',
  '��' => '氨',
  '��' => '氦',
  '��' => '氤',
  '��' => '泰',
  '��' => '浪',
  '��' => '涕',
  '��' => '消',
  '��' => '涇',
  '��' => '浦',
  '��' => '浸',
  '��' => '海',
  '��' => '浙',
  '��' => '涓',
  '�@' => '浬',
  '�A' => '涉',
  '�B' => '浮',
  '�C' => '浚',
  '�D' => '浴',
  '�E' => '浩',
  '�F' => '涌',
  '�G' => '涊',
  '�H' => '浹',
  '�I' => '涅',
  '�J' => '浥',
  '�K' => '涔',
  '�L' => '烊',
  '�M' => '烘',
  '�N' => '烤',
  '�O' => '烙',
  '�P' => '烈',
  '�Q' => '烏',
  '�R' => '爹',
  '�S' => '特',
  '�T' => '狼',
  '�U' => '狹',
  '�V' => '狽',
  '�W' => '狸',
  '�X' => '狷',
  '�Y' => '玆',
  '�Z' => '班',
  '�[' => '琉',
  '�\\' => '珮',
  '�]' => '珠',
  '�^' => '珪',
  '�_' => '珞',
  '�`' => '畔',
  '�a' => '畝',
  '�b' => '畜',
  '�c' => '畚',
  '�d' => '留',
  '�e' => '疾',
  '�f' => '病',
  '�g' => '症',
  '�h' => '疲',
  '�i' => '疳',
  '�j' => '疽',
  '�k' => '疼',
  '�l' => '疹',
  '�m' => '痂',
  '�n' => '疸',
  '�o' => '皋',
  '�p' => '皰',
  '�q' => '益',
  '�r' => '盍',
  '�s' => '盎',
  '�t' => '眩',
  '�u' => '真',
  '�v' => '眠',
  '�w' => '眨',
  '�x' => '矩',
  '�y' => '砰',
  '�z' => '砧',
  '�{' => '砸',
  '�|' => '砝',
  '�}' => '破',
  '�~' => '砷',
  '��' => '砥',
  '��' => '砭',
  '��' => '砠',
  '��' => '砟',
  '��' => '砲',
  '��' => '祕',
  '��' => '祐',
  '��' => '祠',
  '��' => '祟',
  '��' => '祖',
  '��' => '神',
  '��' => '祝',
  '��' => '祗',
  '��' => '祚',
  '��' => '秤',
  '��' => '秣',
  '��' => '秧',
  '��' => '租',
  '��' => '秦',
  '��' => '秩',
  '��' => '秘',
  '��' => '窄',
  '��' => '窈',
  '��' => '站',
  '��' => '笆',
  '��' => '笑',
  '��' => '粉',
  '��' => '紡',
  '��' => '紗',
  '��' => '紋',
  '��' => '紊',
  '��' => '素',
  '��' => '索',
  '��' => '純',
  '��' => '紐',
  '��' => '紕',
  '��' => '級',
  '��' => '紜',
  '��' => '納',
  '��' => '紙',
  '��' => '紛',
  '��' => '缺',
  '��' => '罟',
  '��' => '羔',
  '��' => '翅',
  '��' => '翁',
  '��' => '耆',
  '��' => '耘',
  '��' => '耕',
  '��' => '耙',
  '��' => '耗',
  '��' => '耽',
  '��' => '耿',
  '��' => '胱',
  '��' => '脂',
  '��' => '胰',
  '��' => '脅',
  '��' => '胭',
  '��' => '胴',
  '��' => '脆',
  '��' => '胸',
  '��' => '胳',
  '��' => '脈',
  '��' => '能',
  '��' => '脊',
  '��' => '胼',
  '��' => '胯',
  '��' => '臭',
  '��' => '臬',
  '��' => '舀',
  '��' => '舐',
  '��' => '航',
  '��' => '舫',
  '��' => '舨',
  '��' => '般',
  '��' => '芻',
  '��' => '茫',
  '��' => '荒',
  '��' => '荔',
  '��' => '荊',
  '��' => '茸',
  '��' => '荐',
  '��' => '草',
  '��' => '茵',
  '��' => '茴',
  '��' => '荏',
  '��' => '茲',
  '��' => '茹',
  '��' => '茶',
  '��' => '茗',
  '��' => '荀',
  '��' => '茱',
  '��' => '茨',
  '��' => '荃',
  '�@' => '虔',
  '�A' => '蚊',
  '�B' => '蚪',
  '�C' => '蚓',
  '�D' => '蚤',
  '�E' => '蚩',
  '�F' => '蚌',
  '�G' => '蚣',
  '�H' => '蚜',
  '�I' => '衰',
  '�J' => '衷',
  '�K' => '袁',
  '�L' => '袂',
  '�M' => '衽',
  '�N' => '衹',
  '�O' => '記',
  '�P' => '訐',
  '�Q' => '討',
  '�R' => '訌',
  '�S' => '訕',
  '�T' => '訊',
  '�U' => '託',
  '�V' => '訓',
  '�W' => '訖',
  '�X' => '訏',
  '�Y' => '訑',
  '�Z' => '豈',
  '�[' => '豺',
  '�\\' => '豹',
  '�]' => '財',
  '�^' => '貢',
  '�_' => '起',
  '�`' => '躬',
  '�a' => '軒',
  '�b' => '軔',
  '�c' => '軏',
  '�d' => '辱',
  '�e' => '送',
  '�f' => '逆',
  '�g' => '迷',
  '�h' => '退',
  '�i' => '迺',
  '�j' => '迴',
  '�k' => '逃',
  '�l' => '追',
  '�m' => '逅',
  '�n' => '迸',
  '�o' => '邕',
  '�p' => '郡',
  '�q' => '郝',
  '�r' => '郢',
  '�s' => '酒',
  '�t' => '配',
  '�u' => '酌',
  '�v' => '釘',
  '�w' => '針',
  '�x' => '釗',
  '�y' => '釜',
  '�z' => '釙',
  '�{' => '閃',
  '�|' => '院',
  '�}' => '陣',
  '�~' => '陡',
  '��' => '陛',
  '��' => '陝',
  '��' => '除',
  '��' => '陘',
  '��' => '陞',
  '��' => '隻',
  '��' => '飢',
  '��' => '馬',
  '��' => '骨',
  '��' => '高',
  '��' => '鬥',
  '��' => '鬲',
  '��' => '鬼',
  '��' => '乾',
  '��' => '偺',
  '��' => '偽',
  '��' => '停',
  '��' => '假',
  '��' => '偃',
  '��' => '偌',
  '��' => '做',
  '��' => '偉',
  '��' => '健',
  '��' => '偶',
  '��' => '偎',
  '��' => '偕',
  '��' => '偵',
  '��' => '側',
  '��' => '偷',
  '��' => '偏',
  '��' => '倏',
  '��' => '偯',
  '��' => '偭',
  '��' => '兜',
  '��' => '冕',
  '��' => '凰',
  '��' => '剪',
  '��' => '副',
  '��' => '勒',
  '��' => '務',
  '��' => '勘',
  '��' => '動',
  '��' => '匐',
  '��' => '匏',
  '��' => '匙',
  '��' => '匿',
  '��' => '區',
  '��' => '匾',
  '��' => '參',
  '��' => '曼',
  '��' => '商',
  '��' => '啪',
  '��' => '啦',
  '��' => '啄',
  '��' => '啞',
  '��' => '啡',
  '��' => '啃',
  '��' => '啊',
  '��' => '唱',
  '��' => '啖',
  '��' => '問',
  '��' => '啕',
  '��' => '唯',
  '��' => '啤',
  '��' => '唸',
  '��' => '售',
  '��' => '啜',
  '��' => '唬',
  '��' => '啣',
  '��' => '唳',
  '��' => '啁',
  '��' => '啗',
  '��' => '圈',
  '��' => '國',
  '��' => '圉',
  '��' => '域',
  '��' => '堅',
  '��' => '堊',
  '��' => '堆',
  '��' => '埠',
  '��' => '埤',
  '��' => '基',
  '��' => '堂',
  '��' => '堵',
  '��' => '執',
  '��' => '培',
  '��' => '夠',
  '��' => '奢',
  '��' => '娶',
  '��' => '婁',
  '��' => '婉',
  '��' => '婦',
  '��' => '婪',
  '��' => '婀',
  '�@' => '娼',
  '�A' => '婢',
  '�B' => '婚',
  '�C' => '婆',
  '�D' => '婊',
  '�E' => '孰',
  '�F' => '寇',
  '�G' => '寅',
  '�H' => '寄',
  '�I' => '寂',
  '�J' => '宿',
  '�K' => '密',
  '�L' => '尉',
  '�M' => '專',
  '�N' => '將',
  '�O' => '屠',
  '�P' => '屜',
  '�Q' => '屝',
  '�R' => '崇',
  '�S' => '崆',
  '�T' => '崎',
  '�U' => '崛',
  '�V' => '崖',
  '�W' => '崢',
  '�X' => '崑',
  '�Y' => '崩',
  '�Z' => '崔',
  '�[' => '崙',
  '�\\' => '崤',
  '�]' => '崧',
  '�^' => '崗',
  '�_' => '巢',
  '�`' => '常',
  '�a' => '帶',
  '�b' => '帳',
  '�c' => '帷',
  '�d' => '康',
  '�e' => '庸',
  '�f' => '庶',
  '�g' => '庵',
  '�h' => '庾',
  '�i' => '張',
  '�j' => '強',
  '�k' => '彗',
  '�l' => '彬',
  '�m' => '彩',
  '�n' => '彫',
  '�o' => '得',
  '�p' => '徙',
  '�q' => '從',
  '�r' => '徘',
  '�s' => '御',
  '�t' => '徠',
  '�u' => '徜',
  '�v' => '恿',
  '�w' => '患',
  '�x' => '悉',
  '�y' => '悠',
  '�z' => '您',
  '�{' => '惋',
  '�|' => '悴',
  '�}' => '惦',
  '�~' => '悽',
  '��' => '情',
  '��' => '悻',
  '��' => '悵',
  '��' => '惜',
  '��' => '悼',
  '��' => '惘',
  '��' => '惕',
  '��' => '惆',
  '��' => '惟',
  '��' => '悸',
  '��' => '惚',
  '��' => '惇',
  '��' => '戚',
  '��' => '戛',
  '��' => '扈',
  '��' => '掠',
  '��' => '控',
  '��' => '捲',
  '��' => '掖',
  '��' => '探',
  '��' => '接',
  '��' => '捷',
  '��' => '捧',
  '��' => '掘',
  '��' => '措',
  '��' => '捱',
  '��' => '掩',
  '��' => '掉',
  '��' => '掃',
  '��' => '掛',
  '��' => '捫',
  '��' => '推',
  '��' => '掄',
  '��' => '授',
  '��' => '掙',
  '��' => '採',
  '��' => '掬',
  '��' => '排',
  '��' => '掏',
  '��' => '掀',
  '��' => '捻',
  '��' => '捩',
  '��' => '捨',
  '��' => '捺',
  '��' => '敝',
  '��' => '敖',
  '��' => '救',
  '��' => '教',
  '��' => '敗',
  '��' => '啟',
  '��' => '敏',
  '��' => '敘',
  '��' => '敕',
  '��' => '敔',
  '��' => '斜',
  '��' => '斛',
  '��' => '斬',
  '��' => '族',
  '��' => '旋',
  '��' => '旌',
  '��' => '旎',
  '��' => '晝',
  '��' => '晚',
  '��' => '晤',
  '��' => '晨',
  '��' => '晦',
  '��' => '晞',
  '��' => '曹',
  '��' => '勗',
  '��' => '望',
  '��' => '梁',
  '��' => '梯',
  '��' => '梢',
  '��' => '梓',
  '��' => '梵',
  '��' => '桿',
  '��' => '桶',
  '��' => '梱',
  '��' => '梧',
  '��' => '梗',
  '��' => '械',
  '��' => '梃',
  '��' => '棄',
  '��' => '梭',
  '��' => '梆',
  '��' => '梅',
  '��' => '梔',
  '��' => '條',
  '��' => '梨',
  '��' => '梟',
  '��' => '梡',
  '��' => '梂',
  '��' => '欲',
  '��' => '殺',
  '�@' => '毫',
  '�A' => '毬',
  '�B' => '氫',
  '�C' => '涎',
  '�D' => '涼',
  '�E' => '淳',
  '�F' => '淙',
  '�G' => '液',
  '�H' => '淡',
  '�I' => '淌',
  '�J' => '淤',
  '�K' => '添',
  '�L' => '淺',
  '�M' => '清',
  '�N' => '淇',
  '�O' => '淋',
  '�P' => '涯',
  '�Q' => '淑',
  '�R' => '涮',
  '�S' => '淞',
  '�T' => '淹',
  '�U' => '涸',
  '�V' => '混',
  '�W' => '淵',
  '�X' => '淅',
  '�Y' => '淒',
  '�Z' => '渚',
  '�[' => '涵',
  '�\\' => '淚',
  '�]' => '淫',
  '�^' => '淘',
  '�_' => '淪',
  '�`' => '深',
  '�a' => '淮',
  '�b' => '淨',
  '�c' => '淆',
  '�d' => '淄',
  '�e' => '涪',
  '�f' => '淬',
  '�g' => '涿',
  '�h' => '淦',
  '�i' => '烹',
  '�j' => '焉',
  '�k' => '焊',
  '�l' => '烽',
  '�m' => '烯',
  '�n' => '爽',
  '�o' => '牽',
  '�p' => '犁',
  '�q' => '猜',
  '�r' => '猛',
  '�s' => '猖',
  '�t' => '猓',
  '�u' => '猙',
  '�v' => '率',
  '�w' => '琅',
  '�x' => '琊',
  '�y' => '球',
  '�z' => '理',
  '�{' => '現',
  '�|' => '琍',
  '�}' => '瓠',
  '�~' => '瓶',
  '��' => '瓷',
  '��' => '甜',
  '��' => '產',
  '��' => '略',
  '��' => '畦',
  '��' => '畢',
  '��' => '異',
  '��' => '疏',
  '��' => '痔',
  '��' => '痕',
  '��' => '疵',
  '��' => '痊',
  '��' => '痍',
  '��' => '皎',
  '��' => '盔',
  '��' => '盒',
  '��' => '盛',
  '��' => '眷',
  '��' => '眾',
  '��' => '眼',
  '��' => '眶',
  '��' => '眸',
  '��' => '眺',
  '��' => '硫',
  '��' => '硃',
  '��' => '硎',
  '��' => '祥',
  '��' => '票',
  '��' => '祭',
  '��' => '移',
  '��' => '窒',
  '��' => '窕',
  '��' => '笠',
  '��' => '笨',
  '��' => '笛',
  '��' => '第',
  '��' => '符',
  '��' => '笙',
  '��' => '笞',
  '��' => '笮',
  '��' => '粒',
  '��' => '粗',
  '��' => '粕',
  '��' => '絆',
  '��' => '絃',
  '��' => '統',
  '��' => '紮',
  '��' => '紹',
  '��' => '紼',
  '��' => '絀',
  '��' => '細',
  '��' => '紳',
  '��' => '組',
  '��' => '累',
  '��' => '終',
  '��' => '紲',
  '��' => '紱',
  '��' => '缽',
  '��' => '羞',
  '��' => '羚',
  '��' => '翌',
  '��' => '翎',
  '��' => '習',
  '��' => '耜',
  '��' => '聊',
  '��' => '聆',
  '��' => '脯',
  '��' => '脖',
  '��' => '脣',
  '��' => '脫',
  '��' => '脩',
  '��' => '脰',
  '��' => '脤',
  '��' => '舂',
  '��' => '舵',
  '��' => '舷',
  '��' => '舶',
  '��' => '船',
  '��' => '莎',
  '��' => '莞',
  '��' => '莘',
  '��' => '荸',
  '��' => '莢',
  '��' => '莖',
  '��' => '莽',
  '��' => '莫',
  '��' => '莒',
  '��' => '莊',
  '��' => '莓',
  '��' => '莉',
  '��' => '莠',
  '��' => '荷',
  '��' => '荻',
  '��' => '荼',
  '�@' => '莆',
  '�A' => '莧',
  '�B' => '處',
  '�C' => '彪',
  '�D' => '蛇',
  '�E' => '蛀',
  '�F' => '蚶',
  '�G' => '蛄',
  '�H' => '蚵',
  '�I' => '蛆',
  '�J' => '蛋',
  '�K' => '蚱',
  '�L' => '蚯',
  '�M' => '蛉',
  '�N' => '術',
  '�O' => '袞',
  '�P' => '袈',
  '�Q' => '被',
  '�R' => '袒',
  '�S' => '袖',
  '�T' => '袍',
  '�U' => '袋',
  '�V' => '覓',
  '�W' => '規',
  '�X' => '訪',
  '�Y' => '訝',
  '�Z' => '訣',
  '�[' => '訥',
  '�\\' => '許',
  '�]' => '設',
  '�^' => '訟',
  '�_' => '訛',
  '�`' => '訢',
  '�a' => '豉',
  '�b' => '豚',
  '�c' => '販',
  '�d' => '責',
  '�e' => '貫',
  '�f' => '貨',
  '�g' => '貪',
  '�h' => '貧',
  '�i' => '赧',
  '�j' => '赦',
  '�k' => '趾',
  '�l' => '趺',
  '�m' => '軛',
  '�n' => '軟',
  '�o' => '這',
  '�p' => '逍',
  '�q' => '通',
  '�r' => '逗',
  '�s' => '連',
  '�t' => '速',
  '�u' => '逝',
  '�v' => '逐',
  '�w' => '逕',
  '�x' => '逞',
  '�y' => '造',
  '�z' => '透',
  '�{' => '逢',
  '�|' => '逖',
  '�}' => '逛',
  '�~' => '途',
  '��' => '部',
  '��' => '郭',
  '��' => '都',
  '��' => '酗',
  '��' => '野',
  '��' => '釵',
  '��' => '釦',
  '��' => '釣',
  '��' => '釧',
  '��' => '釭',
  '��' => '釩',
  '��' => '閉',
  '��' => '陪',
  '��' => '陵',
  '��' => '陳',
  '��' => '陸',
  '��' => '陰',
  '��' => '陴',
  '��' => '陶',
  '��' => '陷',
  '��' => '陬',
  '��' => '雀',
  '��' => '雪',
  '��' => '雩',
  '��' => '章',
  '��' => '竟',
  '��' => '頂',
  '��' => '頃',
  '��' => '魚',
  '��' => '鳥',
  '��' => '鹵',
  '��' => '鹿',
  '��' => '麥',
  '��' => '麻',
  '��' => '傢',
  '��' => '傍',
  '��' => '傅',
  '��' => '備',
  '��' => '傑',
  '��' => '傀',
  '��' => '傖',
  '��' => '傘',
  '��' => '傚',
  '��' => '最',
  '��' => '凱',
  '��' => '割',
  '��' => '剴',
  '��' => '創',
  '��' => '剩',
  '��' => '勞',
  '��' => '勝',
  '��' => '勛',
  '��' => '博',
  '��' => '厥',
  '��' => '啻',
  '��' => '喀',
  '��' => '喧',
  '��' => '啼',
  '��' => '喊',
  '��' => '喝',
  '��' => '喘',
  '��' => '喂',
  '��' => '喜',
  '��' => '喪',
  '��' => '喔',
  '��' => '喇',
  '��' => '喋',
  '��' => '喃',
  '��' => '喳',
  '��' => '單',
  '��' => '喟',
  '��' => '唾',
  '��' => '喲',
  '��' => '喚',
  '��' => '喻',
  '��' => '喬',
  '��' => '喱',
  '��' => '啾',
  '��' => '喉',
  '��' => '喫',
  '��' => '喙',
  '��' => '圍',
  '��' => '堯',
  '��' => '堪',
  '��' => '場',
  '��' => '堤',
  '��' => '堰',
  '��' => '報',
  '��' => '堡',
  '��' => '堝',
  '��' => '堠',
  '��' => '壹',
  '��' => '壺',
  '��' => '奠',
  '�@' => '婷',
  '�A' => '媚',
  '�B' => '婿',
  '�C' => '媒',
  '�D' => '媛',
  '�E' => '媧',
  '�F' => '孳',
  '�G' => '孱',
  '�H' => '寒',
  '�I' => '富',
  '�J' => '寓',
  '�K' => '寐',
  '�L' => '尊',
  '�M' => '尋',
  '�N' => '就',
  '�O' => '嵌',
  '�P' => '嵐',
  '�Q' => '崴',
  '�R' => '嵇',
  '�S' => '巽',
  '�T' => '幅',
  '�U' => '帽',
  '�V' => '幀',
  '�W' => '幃',
  '�X' => '幾',
  '�Y' => '廊',
  '�Z' => '廁',
  '�[' => '廂',
  '�\\' => '廄',
  '�]' => '弼',
  '�^' => '彭',
  '�_' => '復',
  '�`' => '循',
  '�a' => '徨',
  '�b' => '惑',
  '�c' => '惡',
  '�d' => '悲',
  '�e' => '悶',
  '�f' => '惠',
  '�g' => '愜',
  '�h' => '愣',
  '�i' => '惺',
  '�j' => '愕',
  '�k' => '惰',
  '�l' => '惻',
  '�m' => '惴',
  '�n' => '慨',
  '�o' => '惱',
  '�p' => '愎',
  '�q' => '惶',
  '�r' => '愉',
  '�s' => '愀',
  '�t' => '愒',
  '�u' => '戟',
  '�v' => '扉',
  '�w' => '掣',
  '�x' => '掌',
  '�y' => '描',
  '�z' => '揀',
  '�{' => '揩',
  '�|' => '揉',
  '�}' => '揆',
  '�~' => '揍',
  '��' => '插',
  '��' => '揣',
  '��' => '提',
  '��' => '握',
  '��' => '揖',
  '��' => '揭',
  '��' => '揮',
  '��' => '捶',
  '��' => '援',
  '��' => '揪',
  '��' => '換',
  '��' => '摒',
  '��' => '揚',
  '��' => '揹',
  '��' => '敞',
  '��' => '敦',
  '��' => '敢',
  '��' => '散',
  '��' => '斑',
  '��' => '斐',
  '��' => '斯',
  '��' => '普',
  '��' => '晰',
  '��' => '晴',
  '��' => '晶',
  '��' => '景',
  '��' => '暑',
  '��' => '智',
  '��' => '晾',
  '��' => '晷',
  '��' => '曾',
  '��' => '替',
  '��' => '期',
  '��' => '朝',
  '��' => '棺',
  '��' => '棕',
  '��' => '棠',
  '��' => '棘',
  '��' => '棗',
  '��' => '椅',
  '��' => '棟',
  '��' => '棵',
  '��' => '森',
  '��' => '棧',
  '��' => '棹',
  '��' => '棒',
  '��' => '棲',
  '��' => '棣',
  '��' => '棋',
  '��' => '棍',
  '��' => '植',
  '��' => '椒',
  '��' => '椎',
  '��' => '棉',
  '��' => '棚',
  '��' => '楮',
  '��' => '棻',
  '��' => '款',
  '��' => '欺',
  '��' => '欽',
  '��' => '殘',
  '��' => '殖',
  '��' => '殼',
  '��' => '毯',
  '��' => '氮',
  '��' => '氯',
  '��' => '氬',
  '��' => '港',
  '��' => '游',
  '��' => '湔',
  '��' => '渡',
  '��' => '渲',
  '��' => '湧',
  '��' => '湊',
  '��' => '渠',
  '��' => '渥',
  '��' => '渣',
  '��' => '減',
  '��' => '湛',
  '��' => '湘',
  '��' => '渤',
  '��' => '湖',
  '��' => '湮',
  '��' => '渭',
  '��' => '渦',
  '��' => '湯',
  '��' => '渴',
  '��' => '湍',
  '��' => '渺',
  '��' => '測',
  '��' => '湃',
  '��' => '渝',
  '��' => '渾',
  '��' => '滋',
  '�@' => '溉',
  '�A' => '渙',
  '�B' => '湎',
  '�C' => '湣',
  '�D' => '湄',
  '�E' => '湲',
  '�F' => '湩',
  '�G' => '湟',
  '�H' => '焙',
  '�I' => '焚',
  '�J' => '焦',
  '�K' => '焰',
  '�L' => '無',
  '�M' => '然',
  '�N' => '煮',
  '�O' => '焜',
  '�P' => '牌',
  '�Q' => '犄',
  '�R' => '犀',
  '�S' => '猶',
  '�T' => '猥',
  '�U' => '猴',
  '�V' => '猩',
  '�W' => '琺',
  '�X' => '琪',
  '�Y' => '琳',
  '�Z' => '琢',
  '�[' => '琥',
  '�\\' => '琵',
  '�]' => '琶',
  '�^' => '琴',
  '�_' => '琯',
  '�`' => '琛',
  '�a' => '琦',
  '�b' => '琨',
  '�c' => '甥',
  '�d' => '甦',
  '�e' => '畫',
  '�f' => '番',
  '�g' => '痢',
  '�h' => '痛',
  '�i' => '痣',
  '�j' => '痙',
  '�k' => '痘',
  '�l' => '痞',
  '�m' => '痠',
  '�n' => '登',
  '�o' => '發',
  '�p' => '皖',
  '�q' => '皓',
  '�r' => '皴',
  '�s' => '盜',
  '�t' => '睏',
  '�u' => '短',
  '�v' => '硝',
  '�w' => '硬',
  '�x' => '硯',
  '�y' => '稍',
  '�z' => '稈',
  '�{' => '程',
  '�|' => '稅',
  '�}' => '稀',
  '�~' => '窘',
  '��' => '窗',
  '��' => '窖',
  '��' => '童',
  '��' => '竣',
  '��' => '等',
  '��' => '策',
  '��' => '筆',
  '��' => '筐',
  '��' => '筒',
  '��' => '答',
  '��' => '筍',
  '��' => '筋',
  '��' => '筏',
  '��' => '筑',
  '��' => '粟',
  '��' => '粥',
  '��' => '絞',
  '��' => '結',
  '��' => '絨',
  '��' => '絕',
  '��' => '紫',
  '��' => '絮',
  '��' => '絲',
  '��' => '絡',
  '��' => '給',
  '��' => '絢',
  '��' => '絰',
  '��' => '絳',
  '��' => '善',
  '��' => '翔',
  '��' => '翕',
  '��' => '耋',
  '��' => '聒',
  '��' => '肅',
  '��' => '腕',
  '��' => '腔',
  '��' => '腋',
  '��' => '腑',
  '��' => '腎',
  '��' => '脹',
  '��' => '腆',
  '��' => '脾',
  '��' => '腌',
  '��' => '腓',
  '��' => '腴',
  '��' => '舒',
  '��' => '舜',
  '��' => '菩',
  '��' => '萃',
  '��' => '菸',
  '��' => '萍',
  '��' => '菠',
  '��' => '菅',
  '��' => '萋',
  '��' => '菁',
  '��' => '華',
  '��' => '菱',
  '��' => '菴',
  '��' => '著',
  '��' => '萊',
  '��' => '菰',
  '��' => '萌',
  '��' => '菌',
  '��' => '菽',
  '��' => '菲',
  '��' => '菊',
  '��' => '萸',
  '��' => '萎',
  '��' => '萄',
  '��' => '菜',
  '��' => '萇',
  '��' => '菔',
  '��' => '菟',
  '��' => '虛',
  '��' => '蛟',
  '��' => '蛙',
  '��' => '蛭',
  '��' => '蛔',
  '��' => '蛛',
  '��' => '蛤',
  '��' => '蛐',
  '��' => '蛞',
  '��' => '街',
  '��' => '裁',
  '��' => '裂',
  '��' => '袱',
  '��' => '覃',
  '��' => '視',
  '��' => '註',
  '��' => '詠',
  '��' => '評',
  '��' => '詞',
  '��' => '証',
  '��' => '詁',
  '�@' => '詔',
  '�A' => '詛',
  '�B' => '詐',
  '�C' => '詆',
  '�D' => '訴',
  '�E' => '診',
  '�F' => '訶',
  '�G' => '詖',
  '�H' => '象',
  '�I' => '貂',
  '�J' => '貯',
  '�K' => '貼',
  '�L' => '貳',
  '�M' => '貽',
  '�N' => '賁',
  '�O' => '費',
  '�P' => '賀',
  '�Q' => '貴',
  '�R' => '買',
  '�S' => '貶',
  '�T' => '貿',
  '�U' => '貸',
  '�V' => '越',
  '�W' => '超',
  '�X' => '趁',
  '�Y' => '跎',
  '�Z' => '距',
  '�[' => '跋',
  '�\\' => '跚',
  '�]' => '跑',
  '�^' => '跌',
  '�_' => '跛',
  '�`' => '跆',
  '�a' => '軻',
  '�b' => '軸',
  '�c' => '軼',
  '�d' => '辜',
  '�e' => '逮',
  '�f' => '逵',
  '�g' => '週',
  '�h' => '逸',
  '�i' => '進',
  '�j' => '逶',
  '�k' => '鄂',
  '�l' => '郵',
  '�m' => '鄉',
  '�n' => '郾',
  '�o' => '酣',
  '�p' => '酥',
  '�q' => '量',
  '�r' => '鈔',
  '�s' => '鈕',
  '�t' => '鈣',
  '�u' => '鈉',
  '�v' => '鈞',
  '�w' => '鈍',
  '�x' => '鈐',
  '�y' => '鈇',
  '�z' => '鈑',
  '�{' => '閔',
  '�|' => '閏',
  '�}' => '開',
  '�~' => '閑',
  '��' => '間',
  '��' => '閒',
  '��' => '閎',
  '��' => '隊',
  '��' => '階',
  '��' => '隋',
  '��' => '陽',
  '��' => '隅',
  '��' => '隆',
  '��' => '隍',
  '��' => '陲',
  '��' => '隄',
  '��' => '雁',
  '��' => '雅',
  '��' => '雄',
  '��' => '集',
  '��' => '雇',
  '��' => '雯',
  '��' => '雲',
  '��' => '韌',
  '��' => '項',
  '��' => '順',
  '��' => '須',
  '��' => '飧',
  '��' => '飪',
  '��' => '飯',
  '��' => '飩',
  '��' => '飲',
  '��' => '飭',
  '��' => '馮',
  '��' => '馭',
  '��' => '黃',
  '��' => '黍',
  '��' => '黑',
  '��' => '亂',
  '��' => '傭',
  '��' => '債',
  '��' => '傲',
  '��' => '傳',
  '��' => '僅',
  '��' => '傾',
  '��' => '催',
  '��' => '傷',
  '��' => '傻',
  '��' => '傯',
  '��' => '僇',
  '��' => '剿',
  '��' => '剷',
  '��' => '剽',
  '��' => '募',
  '��' => '勦',
  '��' => '勤',
  '��' => '勢',
  '��' => '勣',
  '��' => '匯',
  '��' => '嗟',
  '��' => '嗨',
  '��' => '嗓',
  '��' => '嗦',
  '��' => '嗎',
  '��' => '嗜',
  '��' => '嗇',
  '��' => '嗑',
  '��' => '嗣',
  '��' => '嗤',
  '��' => '嗯',
  '��' => '嗚',
  '��' => '嗡',
  '��' => '嗅',
  '��' => '嗆',
  '��' => '嗥',
  '��' => '嗉',
  '��' => '園',
  '��' => '圓',
  '��' => '塞',
  '��' => '塑',
  '��' => '塘',
  '��' => '塗',
  '��' => '塚',
  '��' => '塔',
  '��' => '填',
  '��' => '塌',
  '��' => '塭',
  '��' => '塊',
  '��' => '塢',
  '��' => '塒',
  '��' => '塋',
  '��' => '奧',
  '��' => '嫁',
  '��' => '嫉',
  '��' => '嫌',
  '��' => '媾',
  '��' => '媽',
  '��' => '媼',
  '�@' => '媳',
  '�A' => '嫂',
  '�B' => '媲',
  '�C' => '嵩',
  '�D' => '嵯',
  '�E' => '幌',
  '�F' => '幹',
  '�G' => '廉',
  '�H' => '廈',
  '�I' => '弒',
  '�J' => '彙',
  '�K' => '徬',
  '�L' => '微',
  '�M' => '愚',
  '�N' => '意',
  '�O' => '慈',
  '�P' => '感',
  '�Q' => '想',
  '�R' => '愛',
  '�S' => '惹',
  '�T' => '愁',
  '�U' => '愈',
  '�V' => '慎',
  '�W' => '慌',
  '�X' => '慄',
  '�Y' => '慍',
  '�Z' => '愾',
  '�[' => '愴',
  '�\\' => '愧',
  '�]' => '愍',
  '�^' => '愆',
  '�_' => '愷',
  '�`' => '戡',
  '�a' => '戢',
  '�b' => '搓',
  '�c' => '搾',
  '�d' => '搞',
  '�e' => '搪',
  '�f' => '搭',
  '�g' => '搽',
  '�h' => '搬',
  '�i' => '搏',
  '�j' => '搜',
  '�k' => '搔',
  '�l' => '損',
  '�m' => '搶',
  '�n' => '搖',
  '�o' => '搗',
  '�p' => '搆',
  '�q' => '敬',
  '�r' => '斟',
  '�s' => '新',
  '�t' => '暗',
  '�u' => '暉',
  '�v' => '暇',
  '�w' => '暈',
  '�x' => '暖',
  '�y' => '暄',
  '�z' => '暘',
  '�{' => '暍',
  '�|' => '會',
  '�}' => '榔',
  '�~' => '業',
  '��' => '楚',
  '��' => '楷',
  '��' => '楠',
  '��' => '楔',
  '��' => '極',
  '��' => '椰',
  '��' => '概',
  '��' => '楊',
  '��' => '楨',
  '��' => '楫',
  '��' => '楞',
  '��' => '楓',
  '��' => '楹',
  '��' => '榆',
  '��' => '楝',
  '��' => '楣',
  '��' => '楛',
  '��' => '歇',
  '��' => '歲',
  '��' => '毀',
  '��' => '殿',
  '��' => '毓',
  '��' => '毽',
  '��' => '溢',
  '��' => '溯',
  '��' => '滓',
  '��' => '溶',
  '��' => '滂',
  '��' => '源',
  '��' => '溝',
  '��' => '滇',
  '��' => '滅',
  '��' => '溥',
  '��' => '溘',
  '��' => '溼',
  '��' => '溺',
  '��' => '溫',
  '��' => '滑',
  '��' => '準',
  '��' => '溜',
  '��' => '滄',
  '��' => '滔',
  '��' => '溪',
  '��' => '溧',
  '��' => '溴',
  '��' => '煎',
  '��' => '煙',
  '��' => '煩',
  '��' => '煤',
  '��' => '煉',
  '��' => '照',
  '��' => '煜',
  '��' => '煬',
  '��' => '煦',
  '��' => '煌',
  '��' => '煥',
  '��' => '煞',
  '��' => '煆',
  '��' => '煨',
  '��' => '煖',
  '��' => '爺',
  '��' => '牒',
  '��' => '猷',
  '��' => '獅',
  '��' => '猿',
  '��' => '猾',
  '��' => '瑯',
  '��' => '瑚',
  '��' => '瑕',
  '��' => '瑟',
  '��' => '瑞',
  '��' => '瑁',
  '��' => '琿',
  '��' => '瑙',
  '��' => '瑛',
  '��' => '瑜',
  '��' => '當',
  '��' => '畸',
  '��' => '瘀',
  '��' => '痰',
  '��' => '瘁',
  '��' => '痲',
  '��' => '痱',
  '��' => '痺',
  '��' => '痿',
  '��' => '痴',
  '��' => '痳',
  '��' => '盞',
  '��' => '盟',
  '��' => '睛',
  '��' => '睫',
  '��' => '睦',
  '��' => '睞',
  '��' => '督',
  '�@' => '睹',
  '�A' => '睪',
  '�B' => '睬',
  '�C' => '睜',
  '�D' => '睥',
  '�E' => '睨',
  '�F' => '睢',
  '�G' => '矮',
  '�H' => '碎',
  '�I' => '碰',
  '�J' => '碗',
  '�K' => '碘',
  '�L' => '碌',
  '�M' => '碉',
  '�N' => '硼',
  '�O' => '碑',
  '�P' => '碓',
  '�Q' => '硿',
  '�R' => '祺',
  '�S' => '祿',
  '�T' => '禁',
  '�U' => '萬',
  '�V' => '禽',
  '�W' => '稜',
  '�X' => '稚',
  '�Y' => '稠',
  '�Z' => '稔',
  '�[' => '稟',
  '�\\' => '稞',
  '�]' => '窟',
  '�^' => '窠',
  '�_' => '筷',
  '�`' => '節',
  '�a' => '筠',
  '�b' => '筮',
  '�c' => '筧',
  '�d' => '粱',
  '�e' => '粳',
  '�f' => '粵',
  '�g' => '經',
  '�h' => '絹',
  '�i' => '綑',
  '�j' => '綁',
  '�k' => '綏',
  '�l' => '絛',
  '�m' => '置',
  '�n' => '罩',
  '�o' => '罪',
  '�p' => '署',
  '�q' => '義',
  '�r' => '羨',
  '�s' => '群',
  '�t' => '聖',
  '�u' => '聘',
  '�v' => '肆',
  '�w' => '肄',
  '�x' => '腱',
  '�y' => '腰',
  '�z' => '腸',
  '�{' => '腥',
  '�|' => '腮',
  '�}' => '腳',
  '�~' => '腫',
  '��' => '腹',
  '��' => '腺',
  '��' => '腦',
  '��' => '舅',
  '��' => '艇',
  '��' => '蒂',
  '��' => '葷',
  '��' => '落',
  '��' => '萱',
  '��' => '葵',
  '��' => '葦',
  '��' => '葫',
  '��' => '葉',
  '��' => '葬',
  '��' => '葛',
  '��' => '萼',
  '��' => '萵',
  '��' => '葡',
  '��' => '董',
  '��' => '葩',
  '��' => '葭',
  '��' => '葆',
  '��' => '虞',
  '��' => '虜',
  '��' => '號',
  '��' => '蛹',
  '��' => '蜓',
  '��' => '蜈',
  '��' => '蜇',
  '��' => '蜀',
  '��' => '蛾',
  '��' => '蛻',
  '��' => '蜂',
  '��' => '蜃',
  '��' => '蜆',
  '��' => '蜊',
  '��' => '衙',
  '��' => '裟',
  '��' => '裔',
  '��' => '裙',
  '��' => '補',
  '��' => '裘',
  '��' => '裝',
  '��' => '裡',
  '��' => '裊',
  '��' => '裕',
  '��' => '裒',
  '��' => '覜',
  '��' => '解',
  '��' => '詫',
  '��' => '該',
  '��' => '詳',
  '��' => '試',
  '��' => '詩',
  '��' => '詰',
  '��' => '誇',
  '��' => '詼',
  '��' => '詣',
  '��' => '誠',
  '��' => '話',
  '��' => '誅',
  '��' => '詭',
  '��' => '詢',
  '��' => '詮',
  '��' => '詬',
  '��' => '詹',
  '��' => '詻',
  '��' => '訾',
  '��' => '詨',
  '��' => '豢',
  '��' => '貊',
  '��' => '貉',
  '��' => '賊',
  '��' => '資',
  '��' => '賈',
  '��' => '賄',
  '��' => '貲',
  '��' => '賃',
  '��' => '賂',
  '��' => '賅',
  '��' => '跡',
  '��' => '跟',
  '��' => '跨',
  '��' => '路',
  '��' => '跳',
  '��' => '跺',
  '��' => '跪',
  '��' => '跤',
  '��' => '跦',
  '��' => '躲',
  '��' => '較',
  '��' => '載',
  '��' => '軾',
  '��' => '輊',
  '�@' => '辟',
  '�A' => '農',
  '�B' => '運',
  '�C' => '遊',
  '�D' => '道',
  '�E' => '遂',
  '�F' => '達',
  '�G' => '逼',
  '�H' => '違',
  '�I' => '遐',
  '�J' => '遇',
  '�K' => '遏',
  '�L' => '過',
  '�M' => '遍',
  '�N' => '遑',
  '�O' => '逾',
  '�P' => '遁',
  '�Q' => '鄒',
  '�R' => '鄗',
  '�S' => '酬',
  '�T' => '酪',
  '�U' => '酩',
  '�V' => '釉',
  '�W' => '鈷',
  '�X' => '鉗',
  '�Y' => '鈸',
  '�Z' => '鈽',
  '�[' => '鉀',
  '�\\' => '鈾',
  '�]' => '鉛',
  '�^' => '鉋',
  '�_' => '鉤',
  '�`' => '鉑',
  '�a' => '鈴',
  '�b' => '鉉',
  '�c' => '鉍',
  '�d' => '鉅',
  '�e' => '鈹',
  '�f' => '鈿',
  '�g' => '鉚',
  '�h' => '閘',
  '�i' => '隘',
  '�j' => '隔',
  '�k' => '隕',
  '�l' => '雍',
  '�m' => '雋',
  '�n' => '雉',
  '�o' => '雊',
  '�p' => '雷',
  '�q' => '電',
  '�r' => '雹',
  '�s' => '零',
  '�t' => '靖',
  '�u' => '靴',
  '�v' => '靶',
  '�w' => '預',
  '�x' => '頑',
  '�y' => '頓',
  '�z' => '頊',
  '�{' => '頒',
  '�|' => '頌',
  '�}' => '飼',
  '�~' => '飴',
  '��' => '飽',
  '��' => '飾',
  '��' => '馳',
  '��' => '馱',
  '��' => '馴',
  '��' => '髡',
  '��' => '鳩',
  '��' => '麂',
  '��' => '鼎',
  '��' => '鼓',
  '��' => '鼠',
  '��' => '僧',
  '��' => '僮',
  '��' => '僥',
  '��' => '僖',
  '��' => '僭',
  '��' => '僚',
  '��' => '僕',
  '��' => '像',
  '��' => '僑',
  '��' => '僱',
  '��' => '僎',
  '��' => '僩',
  '��' => '兢',
  '��' => '凳',
  '��' => '劃',
  '��' => '劂',
  '��' => '匱',
  '��' => '厭',
  '��' => '嗾',
  '��' => '嘀',
  '��' => '嘛',
  '��' => '嘗',
  '��' => '嗽',
  '��' => '嘔',
  '��' => '嘆',
  '��' => '嘉',
  '��' => '嘍',
  '��' => '嘎',
  '��' => '嗷',
  '��' => '嘖',
  '��' => '嘟',
  '��' => '嘈',
  '��' => '嘐',
  '��' => '嗶',
  '��' => '團',
  '��' => '圖',
  '��' => '塵',
  '��' => '塾',
  '��' => '境',
  '��' => '墓',
  '��' => '墊',
  '��' => '塹',
  '��' => '墅',
  '��' => '塽',
  '��' => '壽',
  '��' => '夥',
  '��' => '夢',
  '��' => '夤',
  '��' => '奪',
  '��' => '奩',
  '��' => '嫡',
  '��' => '嫦',
  '��' => '嫩',
  '��' => '嫗',
  '��' => '嫖',
  '��' => '嫘',
  '��' => '嫣',
  '��' => '孵',
  '��' => '寞',
  '��' => '寧',
  '��' => '寡',
  '��' => '寥',
  '��' => '實',
  '��' => '寨',
  '��' => '寢',
  '��' => '寤',
  '��' => '察',
  '��' => '對',
  '��' => '屢',
  '��' => '嶄',
  '��' => '嶇',
  '��' => '幛',
  '��' => '幣',
  '��' => '幕',
  '��' => '幗',
  '��' => '幔',
  '��' => '廓',
  '��' => '廖',
  '��' => '弊',
  '��' => '彆',
  '��' => '彰',
  '��' => '徹',
  '��' => '慇',
  '�@' => '愿',
  '�A' => '態',
  '�B' => '慷',
  '�C' => '慢',
  '�D' => '慣',
  '�E' => '慟',
  '�F' => '慚',
  '�G' => '慘',
  '�H' => '慵',
  '�I' => '截',
  '�J' => '撇',
  '�K' => '摘',
  '�L' => '摔',
  '�M' => '撤',
  '�N' => '摸',
  '�O' => '摟',
  '�P' => '摺',
  '�Q' => '摑',
  '�R' => '摧',
  '�S' => '搴',
  '�T' => '摭',
  '�U' => '摻',
  '�V' => '敲',
  '�W' => '斡',
  '�X' => '旗',
  '�Y' => '旖',
  '�Z' => '暢',
  '�[' => '暨',
  '�\\' => '暝',
  '�]' => '榜',
  '�^' => '榨',
  '�_' => '榕',
  '�`' => '槁',
  '�a' => '榮',
  '�b' => '槓',
  '�c' => '構',
  '�d' => '榛',
  '�e' => '榷',
  '�f' => '榻',
  '�g' => '榫',
  '�h' => '榴',
  '�i' => '槐',
  '�j' => '槍',
  '�k' => '榭',
  '�l' => '槌',
  '�m' => '榦',
  '�n' => '槃',
  '�o' => '榣',
  '�p' => '歉',
  '�q' => '歌',
  '�r' => '氳',
  '�s' => '漳',
  '�t' => '演',
  '�u' => '滾',
  '�v' => '漓',
  '�w' => '滴',
  '�x' => '漩',
  '�y' => '漾',
  '�z' => '漠',
  '�{' => '漬',
  '�|' => '漏',
  '�}' => '漂',
  '�~' => '漢',
  '��' => '滿',
  '��' => '滯',
  '��' => '漆',
  '��' => '漱',
  '��' => '漸',
  '��' => '漲',
  '��' => '漣',
  '��' => '漕',
  '��' => '漫',
  '��' => '漯',
  '��' => '澈',
  '��' => '漪',
  '��' => '滬',
  '��' => '漁',
  '��' => '滲',
  '��' => '滌',
  '��' => '滷',
  '��' => '熔',
  '��' => '熙',
  '��' => '煽',
  '��' => '熊',
  '��' => '熄',
  '��' => '熒',
  '��' => '爾',
  '��' => '犒',
  '��' => '犖',
  '��' => '獄',
  '��' => '獐',
  '��' => '瑤',
  '��' => '瑣',
  '��' => '瑪',
  '��' => '瑰',
  '��' => '瑭',
  '��' => '甄',
  '��' => '疑',
  '��' => '瘧',
  '��' => '瘍',
  '��' => '瘋',
  '��' => '瘉',
  '��' => '瘓',
  '��' => '盡',
  '��' => '監',
  '��' => '瞄',
  '��' => '睽',
  '��' => '睿',
  '��' => '睡',
  '��' => '磁',
  '��' => '碟',
  '��' => '碧',
  '��' => '碳',
  '��' => '碩',
  '��' => '碣',
  '��' => '禎',
  '��' => '福',
  '��' => '禍',
  '��' => '種',
  '��' => '稱',
  '��' => '窪',
  '��' => '窩',
  '��' => '竭',
  '��' => '端',
  '��' => '管',
  '��' => '箕',
  '��' => '箋',
  '��' => '筵',
  '��' => '算',
  '��' => '箝',
  '��' => '箔',
  '��' => '箏',
  '��' => '箸',
  '��' => '箇',
  '��' => '箄',
  '��' => '粹',
  '��' => '粽',
  '��' => '精',
  '��' => '綻',
  '��' => '綰',
  '��' => '綜',
  '��' => '綽',
  '��' => '綾',
  '��' => '綠',
  '��' => '緊',
  '��' => '綴',
  '��' => '網',
  '��' => '綱',
  '��' => '綺',
  '��' => '綢',
  '��' => '綿',
  '��' => '綵',
  '��' => '綸',
  '��' => '維',
  '��' => '緒',
  '��' => '緇',
  '��' => '綬',
  '�@' => '罰',
  '�A' => '翠',
  '�B' => '翡',
  '�C' => '翟',
  '�D' => '聞',
  '�E' => '聚',
  '�F' => '肇',
  '�G' => '腐',
  '�H' => '膀',
  '�I' => '膏',
  '�J' => '膈',
  '�K' => '膊',
  '�L' => '腿',
  '�M' => '膂',
  '�N' => '臧',
  '�O' => '臺',
  '�P' => '與',
  '�Q' => '舔',
  '�R' => '舞',
  '�S' => '艋',
  '�T' => '蓉',
  '�U' => '蒿',
  '�V' => '蓆',
  '�W' => '蓄',
  '�X' => '蒙',
  '�Y' => '蒞',
  '�Z' => '蒲',
  '�[' => '蒜',
  '�\\' => '蓋',
  '�]' => '蒸',
  '�^' => '蓀',
  '�_' => '蓓',
  '�`' => '蒐',
  '�a' => '蒼',
  '�b' => '蓑',
  '�c' => '蓊',
  '�d' => '蜿',
  '�e' => '蜜',
  '�f' => '蜻',
  '�g' => '蜢',
  '�h' => '蜥',
  '�i' => '蜴',
  '�j' => '蜘',
  '�k' => '蝕',
  '�l' => '蜷',
  '�m' => '蜩',
  '�n' => '裳',
  '�o' => '褂',
  '�p' => '裴',
  '�q' => '裹',
  '�r' => '裸',
  '�s' => '製',
  '�t' => '裨',
  '�u' => '褚',
  '�v' => '裯',
  '�w' => '誦',
  '�x' => '誌',
  '�y' => '語',
  '�z' => '誣',
  '�{' => '認',
  '�|' => '誡',
  '�}' => '誓',
  '�~' => '誤',
  '��' => '說',
  '��' => '誥',
  '��' => '誨',
  '��' => '誘',
  '��' => '誑',
  '��' => '誚',
  '��' => '誧',
  '��' => '豪',
  '��' => '貍',
  '��' => '貌',
  '��' => '賓',
  '��' => '賑',
  '��' => '賒',
  '��' => '赫',
  '��' => '趙',
  '��' => '趕',
  '��' => '跼',
  '��' => '輔',
  '��' => '輒',
  '��' => '輕',
  '��' => '輓',
  '��' => '辣',
  '��' => '遠',
  '��' => '遘',
  '��' => '遜',
  '��' => '遣',
  '��' => '遙',
  '��' => '遞',
  '��' => '遢',
  '��' => '遝',
  '��' => '遛',
  '��' => '鄙',
  '��' => '鄘',
  '��' => '鄞',
  '��' => '酵',
  '��' => '酸',
  '��' => '酷',
  '��' => '酴',
  '��' => '鉸',
  '��' => '銀',
  '��' => '銅',
  '��' => '銘',
  '��' => '銖',
  '��' => '鉻',
  '��' => '銓',
  '��' => '銜',
  '��' => '銨',
  '��' => '鉼',
  '��' => '銑',
  '��' => '閡',
  '��' => '閨',
  '��' => '閩',
  '��' => '閣',
  '��' => '閥',
  '��' => '閤',
  '��' => '隙',
  '��' => '障',
  '��' => '際',
  '��' => '雌',
  '��' => '雒',
  '��' => '需',
  '��' => '靼',
  '��' => '鞅',
  '��' => '韶',
  '��' => '頗',
  '��' => '領',
  '��' => '颯',
  '��' => '颱',
  '��' => '餃',
  '��' => '餅',
  '��' => '餌',
  '��' => '餉',
  '��' => '駁',
  '��' => '骯',
  '��' => '骰',
  '��' => '髦',
  '��' => '魁',
  '��' => '魂',
  '��' => '鳴',
  '��' => '鳶',
  '��' => '鳳',
  '��' => '麼',
  '��' => '鼻',
  '��' => '齊',
  '��' => '億',
  '��' => '儀',
  '��' => '僻',
  '��' => '僵',
  '��' => '價',
  '��' => '儂',
  '��' => '儈',
  '��' => '儉',
  '��' => '儅',
  '��' => '凜',
  '�@' => '劇',
  '�A' => '劈',
  '�B' => '劉',
  '�C' => '劍',
  '�D' => '劊',
  '�E' => '勰',
  '�F' => '厲',
  '�G' => '嘮',
  '�H' => '嘻',
  '�I' => '嘹',
  '�J' => '嘲',
  '�K' => '嘿',
  '�L' => '嘴',
  '�M' => '嘩',
  '�N' => '噓',
  '�O' => '噎',
  '�P' => '噗',
  '�Q' => '噴',
  '�R' => '嘶',
  '�S' => '嘯',
  '�T' => '嘰',
  '�U' => '墀',
  '�V' => '墟',
  '�W' => '增',
  '�X' => '墳',
  '�Y' => '墜',
  '�Z' => '墮',
  '�[' => '墩',
  '�\\' => '墦',
  '�]' => '奭',
  '�^' => '嬉',
  '�_' => '嫻',
  '�`' => '嬋',
  '�a' => '嫵',
  '�b' => '嬌',
  '�c' => '嬈',
  '�d' => '寮',
  '�e' => '寬',
  '�f' => '審',
  '�g' => '寫',
  '�h' => '層',
  '�i' => '履',
  '�j' => '嶝',
  '�k' => '嶔',
  '�l' => '幢',
  '�m' => '幟',
  '�n' => '幡',
  '�o' => '廢',
  '�p' => '廚',
  '�q' => '廟',
  '�r' => '廝',
  '�s' => '廣',
  '�t' => '廠',
  '�u' => '彈',
  '�v' => '影',
  '�w' => '德',
  '�x' => '徵',
  '�y' => '慶',
  '�z' => '慧',
  '�{' => '慮',
  '�|' => '慝',
  '�}' => '慕',
  '�~' => '憂',
  '��' => '慼',
  '��' => '慰',
  '��' => '慫',
  '��' => '慾',
  '��' => '憧',
  '��' => '憐',
  '��' => '憫',
  '��' => '憎',
  '��' => '憬',
  '��' => '憚',
  '��' => '憤',
  '��' => '憔',
  '��' => '憮',
  '��' => '戮',
  '��' => '摩',
  '��' => '摯',
  '��' => '摹',
  '��' => '撞',
  '��' => '撲',
  '��' => '撈',
  '��' => '撐',
  '��' => '撰',
  '��' => '撥',
  '��' => '撓',
  '��' => '撕',
  '��' => '撩',
  '��' => '撒',
  '��' => '撮',
  '��' => '播',
  '��' => '撫',
  '��' => '撚',
  '��' => '撬',
  '��' => '撙',
  '��' => '撢',
  '��' => '撳',
  '��' => '敵',
  '��' => '敷',
  '��' => '數',
  '��' => '暮',
  '��' => '暫',
  '��' => '暴',
  '��' => '暱',
  '��' => '樣',
  '��' => '樟',
  '��' => '槨',
  '��' => '樁',
  '��' => '樞',
  '��' => '標',
  '��' => '槽',
  '��' => '模',
  '��' => '樓',
  '��' => '樊',
  '��' => '槳',
  '��' => '樂',
  '��' => '樅',
  '��' => '槭',
  '��' => '樑',
  '��' => '歐',
  '��' => '歎',
  '��' => '殤',
  '��' => '毅',
  '��' => '毆',
  '��' => '漿',
  '��' => '潼',
  '��' => '澄',
  '��' => '潑',
  '��' => '潦',
  '��' => '潔',
  '��' => '澆',
  '��' => '潭',
  '��' => '潛',
  '��' => '潸',
  '��' => '潮',
  '��' => '澎',
  '��' => '潺',
  '��' => '潰',
  '��' => '潤',
  '��' => '澗',
  '��' => '潘',
  '��' => '滕',
  '��' => '潯',
  '��' => '潠',
  '��' => '潟',
  '��' => '熟',
  '��' => '熬',
  '��' => '熱',
  '��' => '熨',
  '��' => '牖',
  '��' => '犛',
  '��' => '獎',
  '��' => '獗',
  '��' => '瑩',
  '��' => '璋',
  '��' => '璃',
  '�@' => '瑾',
  '�A' => '璀',
  '�B' => '畿',
  '�C' => '瘠',
  '�D' => '瘩',
  '�E' => '瘟',
  '�F' => '瘤',
  '�G' => '瘦',
  '�H' => '瘡',
  '�I' => '瘢',
  '�J' => '皚',
  '�K' => '皺',
  '�L' => '盤',
  '�M' => '瞎',
  '�N' => '瞇',
  '�O' => '瞌',
  '�P' => '瞑',
  '�Q' => '瞋',
  '�R' => '磋',
  '�S' => '磅',
  '�T' => '確',
  '�U' => '磊',
  '�V' => '碾',
  '�W' => '磕',
  '�X' => '碼',
  '�Y' => '磐',
  '�Z' => '稿',
  '�[' => '稼',
  '�\\' => '穀',
  '�]' => '稽',
  '�^' => '稷',
  '�_' => '稻',
  '�`' => '窯',
  '�a' => '窮',
  '�b' => '箭',
  '�c' => '箱',
  '�d' => '範',
  '�e' => '箴',
  '�f' => '篆',
  '�g' => '篇',
  '�h' => '篁',
  '�i' => '箠',
  '�j' => '篌',
  '�k' => '糊',
  '�l' => '締',
  '�m' => '練',
  '�n' => '緯',
  '�o' => '緻',
  '�p' => '緘',
  '�q' => '緬',
  '�r' => '緝',
  '�s' => '編',
  '�t' => '緣',
  '�u' => '線',
  '�v' => '緞',
  '�w' => '緩',
  '�x' => '綞',
  '�y' => '緙',
  '�z' => '緲',
  '�{' => '緹',
  '�|' => '罵',
  '�}' => '罷',
  '�~' => '羯',
  '��' => '翩',
  '��' => '耦',
  '��' => '膛',
  '��' => '膜',
  '��' => '膝',
  '��' => '膠',
  '��' => '膚',
  '��' => '膘',
  '��' => '蔗',
  '��' => '蔽',
  '��' => '蔚',
  '��' => '蓮',
  '��' => '蔬',
  '��' => '蔭',
  '��' => '蔓',
  '��' => '蔑',
  '��' => '蔣',
  '��' => '蔡',
  '��' => '蔔',
  '��' => '蓬',
  '��' => '蔥',
  '��' => '蓿',
  '��' => '蔆',
  '��' => '螂',
  '��' => '蝴',
  '��' => '蝶',
  '��' => '蝠',
  '��' => '蝦',
  '��' => '蝸',
  '��' => '蝨',
  '��' => '蝙',
  '��' => '蝗',
  '��' => '蝌',
  '��' => '蝓',
  '��' => '衛',
  '��' => '衝',
  '��' => '褐',
  '��' => '複',
  '��' => '褒',
  '��' => '褓',
  '��' => '褕',
  '��' => '褊',
  '��' => '誼',
  '��' => '諒',
  '��' => '談',
  '��' => '諄',
  '��' => '誕',
  '��' => '請',
  '��' => '諸',
  '��' => '課',
  '��' => '諉',
  '��' => '諂',
  '��' => '調',
  '��' => '誰',
  '��' => '論',
  '��' => '諍',
  '��' => '誶',
  '��' => '誹',
  '��' => '諛',
  '��' => '豌',
  '��' => '豎',
  '��' => '豬',
  '��' => '賠',
  '��' => '賞',
  '��' => '賦',
  '��' => '賤',
  '��' => '賬',
  '��' => '賭',
  '��' => '賢',
  '��' => '賣',
  '��' => '賜',
  '��' => '質',
  '��' => '賡',
  '��' => '赭',
  '��' => '趟',
  '��' => '趣',
  '��' => '踫',
  '��' => '踐',
  '��' => '踝',
  '��' => '踢',
  '��' => '踏',
  '��' => '踩',
  '��' => '踟',
  '��' => '踡',
  '��' => '踞',
  '��' => '躺',
  '��' => '輝',
  '��' => '輛',
  '��' => '輟',
  '��' => '輩',
  '��' => '輦',
  '��' => '輪',
  '��' => '輜',
  '��' => '輞',
  '�@' => '輥',
  '�A' => '適',
  '�B' => '遮',
  '�C' => '遨',
  '�D' => '遭',
  '�E' => '遷',
  '�F' => '鄰',
  '�G' => '鄭',
  '�H' => '鄧',
  '�I' => '鄱',
  '�J' => '醇',
  '�K' => '醉',
  '�L' => '醋',
  '�M' => '醃',
  '�N' => '鋅',
  '�O' => '銻',
  '�P' => '銷',
  '�Q' => '鋪',
  '�R' => '銬',
  '�S' => '鋤',
  '�T' => '鋁',
  '�U' => '銳',
  '�V' => '銼',
  '�W' => '鋒',
  '�X' => '鋇',
  '�Y' => '鋰',
  '�Z' => '銲',
  '�[' => '閭',
  '�\\' => '閱',
  '�]' => '霄',
  '�^' => '霆',
  '�_' => '震',
  '�`' => '霉',
  '�a' => '靠',
  '�b' => '鞍',
  '�c' => '鞋',
  '�d' => '鞏',
  '�e' => '頡',
  '�f' => '頫',
  '�g' => '頜',
  '�h' => '颳',
  '�i' => '養',
  '�j' => '餓',
  '�k' => '餒',
  '�l' => '餘',
  '�m' => '駝',
  '�n' => '駐',
  '�o' => '駟',
  '�p' => '駛',
  '�q' => '駑',
  '�r' => '駕',
  '�s' => '駒',
  '�t' => '駙',
  '�u' => '骷',
  '�v' => '髮',
  '�w' => '髯',
  '�x' => '鬧',
  '�y' => '魅',
  '�z' => '魄',
  '�{' => '魷',
  '�|' => '魯',
  '�}' => '鴆',
  '�~' => '鴉',
  '��' => '鴃',
  '��' => '麩',
  '��' => '麾',
  '��' => '黎',
  '��' => '墨',
  '��' => '齒',
  '��' => '儒',
  '��' => '儘',
  '��' => '儔',
  '��' => '儐',
  '��' => '儕',
  '��' => '冀',
  '��' => '冪',
  '��' => '凝',
  '��' => '劑',
  '��' => '劓',
  '��' => '勳',
  '��' => '噙',
  '��' => '噫',
  '��' => '噹',
  '��' => '噩',
  '��' => '噤',
  '��' => '噸',
  '��' => '噪',
  '��' => '器',
  '��' => '噥',
  '��' => '噱',
  '��' => '噯',
  '��' => '噬',
  '��' => '噢',
  '��' => '噶',
  '��' => '壁',
  '��' => '墾',
  '��' => '壇',
  '��' => '壅',
  '��' => '奮',
  '��' => '嬝',
  '��' => '嬴',
  '��' => '學',
  '��' => '寰',
  '��' => '導',
  '��' => '彊',
  '��' => '憲',
  '��' => '憑',
  '��' => '憩',
  '��' => '憊',
  '��' => '懍',
  '��' => '憶',
  '��' => '憾',
  '��' => '懊',
  '��' => '懈',
  '��' => '戰',
  '��' => '擅',
  '��' => '擁',
  '��' => '擋',
  '��' => '撻',
  '��' => '撼',
  '��' => '據',
  '��' => '擄',
  '��' => '擇',
  '��' => '擂',
  '��' => '操',
  '��' => '撿',
  '��' => '擒',
  '��' => '擔',
  '��' => '撾',
  '��' => '整',
  '��' => '曆',
  '��' => '曉',
  '��' => '暹',
  '��' => '曄',
  '��' => '曇',
  '��' => '暸',
  '��' => '樽',
  '��' => '樸',
  '��' => '樺',
  '��' => '橙',
  '��' => '橫',
  '��' => '橘',
  '��' => '樹',
  '��' => '橄',
  '��' => '橢',
  '��' => '橡',
  '��' => '橋',
  '��' => '橇',
  '��' => '樵',
  '��' => '機',
  '��' => '橈',
  '��' => '歙',
  '��' => '歷',
  '��' => '氅',
  '��' => '濂',
  '��' => '澱',
  '��' => '澡',
  '�@' => '濃',
  '�A' => '澤',
  '�B' => '濁',
  '�C' => '澧',
  '�D' => '澳',
  '�E' => '激',
  '�F' => '澹',
  '�G' => '澶',
  '�H' => '澦',
  '�I' => '澠',
  '�J' => '澴',
  '�K' => '熾',
  '�L' => '燉',
  '�M' => '燐',
  '�N' => '燒',
  '�O' => '燈',
  '�P' => '燕',
  '�Q' => '熹',
  '�R' => '燎',
  '�S' => '燙',
  '�T' => '燜',
  '�U' => '燃',
  '�V' => '燄',
  '�W' => '獨',
  '�X' => '璜',
  '�Y' => '璣',
  '�Z' => '璘',
  '�[' => '璟',
  '�\\' => '璞',
  '�]' => '瓢',
  '�^' => '甌',
  '�_' => '甍',
  '�`' => '瘴',
  '�a' => '瘸',
  '�b' => '瘺',
  '�c' => '盧',
  '�d' => '盥',
  '�e' => '瞠',
  '�f' => '瞞',
  '�g' => '瞟',
  '�h' => '瞥',
  '�i' => '磨',
  '�j' => '磚',
  '�k' => '磬',
  '�l' => '磧',
  '�m' => '禦',
  '�n' => '積',
  '�o' => '穎',
  '�p' => '穆',
  '�q' => '穌',
  '�r' => '穋',
  '�s' => '窺',
  '�t' => '篙',
  '�u' => '簑',
  '�v' => '築',
  '�w' => '篤',
  '�x' => '篛',
  '�y' => '篡',
  '�z' => '篩',
  '�{' => '篦',
  '�|' => '糕',
  '�}' => '糖',
  '�~' => '縊',
  '��' => '縑',
  '��' => '縈',
  '��' => '縛',
  '��' => '縣',
  '��' => '縞',
  '��' => '縝',
  '��' => '縉',
  '��' => '縐',
  '��' => '罹',
  '��' => '羲',
  '��' => '翰',
  '��' => '翱',
  '��' => '翮',
  '��' => '耨',
  '��' => '膳',
  '��' => '膩',
  '��' => '膨',
  '��' => '臻',
  '��' => '興',
  '��' => '艘',
  '��' => '艙',
  '��' => '蕊',
  '��' => '蕙',
  '��' => '蕈',
  '��' => '蕨',
  '��' => '蕩',
  '��' => '蕃',
  '��' => '蕉',
  '��' => '蕭',
  '��' => '蕪',
  '��' => '蕞',
  '��' => '螃',
  '��' => '螟',
  '��' => '螞',
  '��' => '螢',
  '��' => '融',
  '��' => '衡',
  '��' => '褪',
  '��' => '褲',
  '��' => '褥',
  '��' => '褫',
  '��' => '褡',
  '��' => '親',
  '��' => '覦',
  '��' => '諦',
  '��' => '諺',
  '��' => '諫',
  '��' => '諱',
  '��' => '謀',
  '��' => '諜',
  '��' => '諧',
  '��' => '諮',
  '��' => '諾',
  '��' => '謁',
  '��' => '謂',
  '��' => '諷',
  '��' => '諭',
  '��' => '諳',
  '��' => '諶',
  '��' => '諼',
  '��' => '豫',
  '��' => '豭',
  '��' => '貓',
  '��' => '賴',
  '��' => '蹄',
  '��' => '踱',
  '��' => '踴',
  '��' => '蹂',
  '��' => '踹',
  '��' => '踵',
  '��' => '輻',
  '��' => '輯',
  '��' => '輸',
  '��' => '輳',
  '��' => '辨',
  '��' => '辦',
  '��' => '遵',
  '��' => '遴',
  '��' => '選',
  '��' => '遲',
  '��' => '遼',
  '��' => '遺',
  '��' => '鄴',
  '��' => '醒',
  '��' => '錠',
  '��' => '錶',
  '��' => '鋸',
  '��' => '錳',
  '��' => '錯',
  '��' => '錢',
  '��' => '鋼',
  '��' => '錫',
  '��' => '錄',
  '��' => '錚',
  '�@' => '錐',
  '�A' => '錦',
  '�B' => '錡',
  '�C' => '錕',
  '�D' => '錮',
  '�E' => '錙',
  '�F' => '閻',
  '�G' => '隧',
  '�H' => '隨',
  '�I' => '險',
  '�J' => '雕',
  '�K' => '霎',
  '�L' => '霑',
  '�M' => '霖',
  '�N' => '霍',
  '�O' => '霓',
  '�P' => '霏',
  '�Q' => '靛',
  '�R' => '靜',
  '�S' => '靦',
  '�T' => '鞘',
  '�U' => '頰',
  '�V' => '頸',
  '�W' => '頻',
  '�X' => '頷',
  '�Y' => '頭',
  '�Z' => '頹',
  '�[' => '頤',
  '�\\' => '餐',
  '�]' => '館',
  '�^' => '餞',
  '�_' => '餛',
  '�`' => '餡',
  '�a' => '餚',
  '�b' => '駭',
  '�c' => '駢',
  '�d' => '駱',
  '�e' => '骸',
  '�f' => '骼',
  '�g' => '髻',
  '�h' => '髭',
  '�i' => '鬨',
  '�j' => '鮑',
  '�k' => '鴕',
  '�l' => '鴣',
  '�m' => '鴦',
  '�n' => '鴨',
  '�o' => '鴒',
  '�p' => '鴛',
  '�q' => '默',
  '�r' => '黔',
  '�s' => '龍',
  '�t' => '龜',
  '�u' => '優',
  '�v' => '償',
  '�w' => '儡',
  '�x' => '儲',
  '�y' => '勵',
  '�z' => '嚎',
  '�{' => '嚀',
  '�|' => '嚐',
  '�}' => '嚅',
  '�~' => '嚇',
  '��' => '嚏',
  '��' => '壕',
  '��' => '壓',
  '��' => '壑',
  '��' => '壎',
  '��' => '嬰',
  '��' => '嬪',
  '��' => '嬤',
  '��' => '孺',
  '��' => '尷',
  '��' => '屨',
  '��' => '嶼',
  '��' => '嶺',
  '��' => '嶽',
  '��' => '嶸',
  '��' => '幫',
  '��' => '彌',
  '��' => '徽',
  '��' => '應',
  '��' => '懂',
  '��' => '懇',
  '��' => '懦',
  '��' => '懋',
  '��' => '戲',
  '��' => '戴',
  '��' => '擎',
  '��' => '擊',
  '��' => '擘',
  '��' => '擠',
  '��' => '擰',
  '��' => '擦',
  '��' => '擬',
  '��' => '擱',
  '��' => '擢',
  '��' => '擭',
  '��' => '斂',
  '��' => '斃',
  '��' => '曙',
  '��' => '曖',
  '��' => '檀',
  '��' => '檔',
  '��' => '檄',
  '��' => '檢',
  '��' => '檜',
  '��' => '櫛',
  '��' => '檣',
  '��' => '橾',
  '��' => '檗',
  '��' => '檐',
  '��' => '檠',
  '��' => '歜',
  '��' => '殮',
  '��' => '毚',
  '��' => '氈',
  '��' => '濘',
  '��' => '濱',
  '��' => '濟',
  '��' => '濠',
  '��' => '濛',
  '��' => '濤',
  '��' => '濫',
  '��' => '濯',
  '��' => '澀',
  '��' => '濬',
  '��' => '濡',
  '��' => '濩',
  '��' => '濕',
  '��' => '濮',
  '��' => '濰',
  '��' => '燧',
  '��' => '營',
  '��' => '燮',
  '��' => '燦',
  '��' => '燥',
  '��' => '燭',
  '��' => '燬',
  '��' => '燴',
  '��' => '燠',
  '��' => '爵',
  '��' => '牆',
  '��' => '獰',
  '��' => '獲',
  '��' => '璩',
  '��' => '環',
  '��' => '璦',
  '��' => '璨',
  '��' => '癆',
  '��' => '療',
  '��' => '癌',
  '��' => '盪',
  '��' => '瞳',
  '��' => '瞪',
  '��' => '瞰',
  '��' => '瞬',
  '�@' => '瞧',
  '�A' => '瞭',
  '�B' => '矯',
  '�C' => '磷',
  '�D' => '磺',
  '�E' => '磴',
  '�F' => '磯',
  '�G' => '礁',
  '�H' => '禧',
  '�I' => '禪',
  '�J' => '穗',
  '�K' => '窿',
  '�L' => '簇',
  '�M' => '簍',
  '�N' => '篾',
  '�O' => '篷',
  '�P' => '簌',
  '�Q' => '篠',
  '�R' => '糠',
  '�S' => '糜',
  '�T' => '糞',
  '�U' => '糢',
  '�V' => '糟',
  '�W' => '糙',
  '�X' => '糝',
  '�Y' => '縮',
  '�Z' => '績',
  '�[' => '繆',
  '�\\' => '縷',
  '�]' => '縲',
  '�^' => '繃',
  '�_' => '縫',
  '�`' => '總',
  '�a' => '縱',
  '�b' => '繅',
  '�c' => '繁',
  '�d' => '縴',
  '�e' => '縹',
  '�f' => '繈',
  '�g' => '縵',
  '�h' => '縿',
  '�i' => '縯',
  '�j' => '罄',
  '�k' => '翳',
  '�l' => '翼',
  '�m' => '聱',
  '�n' => '聲',
  '�o' => '聰',
  '�p' => '聯',
  '�q' => '聳',
  '�r' => '臆',
  '�s' => '臃',
  '�t' => '膺',
  '�u' => '臂',
  '�v' => '臀',
  '�w' => '膿',
  '�x' => '膽',
  '�y' => '臉',
  '�z' => '膾',
  '�{' => '臨',
  '�|' => '舉',
  '�}' => '艱',
  '�~' => '薪',
  '��' => '薄',
  '��' => '蕾',
  '��' => '薜',
  '��' => '薑',
  '��' => '薔',
  '��' => '薯',
  '��' => '薛',
  '��' => '薇',
  '��' => '薨',
  '��' => '薊',
  '��' => '虧',
  '��' => '蟀',
  '��' => '蟑',
  '��' => '螳',
  '��' => '蟒',
  '��' => '蟆',
  '��' => '螫',
  '��' => '螻',
  '��' => '螺',
  '��' => '蟈',
  '��' => '蟋',
  '��' => '褻',
  '��' => '褶',
  '��' => '襄',
  '��' => '褸',
  '��' => '褽',
  '��' => '覬',
  '��' => '謎',
  '��' => '謗',
  '��' => '謙',
  '��' => '講',
  '��' => '謊',
  '��' => '謠',
  '��' => '謝',
  '��' => '謄',
  '��' => '謐',
  '��' => '豁',
  '��' => '谿',
  '��' => '豳',
  '��' => '賺',
  '��' => '賽',
  '��' => '購',
  '��' => '賸',
  '��' => '賻',
  '��' => '趨',
  '��' => '蹉',
  '��' => '蹋',
  '��' => '蹈',
  '��' => '蹊',
  '��' => '轄',
  '��' => '輾',
  '��' => '轂',
  '��' => '轅',
  '��' => '輿',
  '��' => '避',
  '��' => '遽',
  '��' => '還',
  '��' => '邁',
  '��' => '邂',
  '��' => '邀',
  '��' => '鄹',
  '��' => '醣',
  '��' => '醞',
  '��' => '醜',
  '��' => '鍍',
  '��' => '鎂',
  '��' => '錨',
  '��' => '鍵',
  '��' => '鍊',
  '��' => '鍥',
  '��' => '鍋',
  '��' => '錘',
  '��' => '鍾',
  '��' => '鍬',
  '��' => '鍛',
  '��' => '鍰',
  '��' => '鍚',
  '��' => '鍔',
  '��' => '闊',
  '��' => '闋',
  '��' => '闌',
  '��' => '闈',
  '��' => '闆',
  '��' => '隱',
  '��' => '隸',
  '��' => '雖',
  '��' => '霜',
  '��' => '霞',
  '��' => '鞠',
  '��' => '韓',
  '��' => '顆',
  '��' => '颶',
  '��' => '餵',
  '��' => '騁',
  '�@' => '駿',
  '�A' => '鮮',
  '�B' => '鮫',
  '�C' => '鮪',
  '�D' => '鮭',
  '�E' => '鴻',
  '�F' => '鴿',
  '�G' => '麋',
  '�H' => '黏',
  '�I' => '點',
  '�J' => '黜',
  '�K' => '黝',
  '�L' => '黛',
  '�M' => '鼾',
  '�N' => '齋',
  '�O' => '叢',
  '�P' => '嚕',
  '�Q' => '嚮',
  '�R' => '壙',
  '�S' => '壘',
  '�T' => '嬸',
  '�U' => '彝',
  '�V' => '懣',
  '�W' => '戳',
  '�X' => '擴',
  '�Y' => '擲',
  '�Z' => '擾',
  '�[' => '攆',
  '�\\' => '擺',
  '�]' => '擻',
  '�^' => '擷',
  '�_' => '斷',
  '�`' => '曜',
  '�a' => '朦',
  '�b' => '檳',
  '�c' => '檬',
  '�d' => '櫃',
  '�e' => '檻',
  '�f' => '檸',
  '�g' => '櫂',
  '�h' => '檮',
  '�i' => '檯',
  '�j' => '歟',
  '�k' => '歸',
  '�l' => '殯',
  '�m' => '瀉',
  '�n' => '瀋',
  '�o' => '濾',
  '�p' => '瀆',
  '�q' => '濺',
  '�r' => '瀑',
  '�s' => '瀏',
  '�t' => '燻',
  '�u' => '燼',
  '�v' => '燾',
  '�w' => '燸',
  '�x' => '獷',
  '�y' => '獵',
  '�z' => '璧',
  '�{' => '璿',
  '�|' => '甕',
  '�}' => '癖',
  '�~' => '癘',
  '¡' => '癒',
  '¢' => '瞽',
  '£' => '瞿',
  '¤' => '瞻',
  '¥' => '瞼',
  '¦' => '礎',
  '§' => '禮',
  '¨' => '穡',
  '©' => '穢',
  'ª' => '穠',
  '«' => '竄',
  '¬' => '竅',
  '­' => '簫',
  '®' => '簧',
  '¯' => '簪',
  '°' => '簞',
  '±' => '簣',
  '²' => '簡',
  '³' => '糧',
  '´' => '織',
  'µ' => '繕',
  '¶' => '繞',
  '·' => '繚',
  '¸' => '繡',
  '¹' => '繒',
  'º' => '繙',
  '»' => '罈',
  '¼' => '翹',
  '½' => '翻',
  '¾' => '職',
  '¿' => '聶',
  '�' => '臍',
  '�' => '臏',
  '��' => '舊',
  '��' => '藏',
  '��' => '薩',
  '��' => '藍',
  '��' => '藐',
  '��' => '藉',
  '��' => '薰',
  '��' => '薺',
  '��' => '薹',
  '��' => '薦',
  '��' => '蟯',
  '��' => '蟬',
  '��' => '蟲',
  '��' => '蟠',
  '��' => '覆',
  '��' => '覲',
  '��' => '觴',
  '��' => '謨',
  '��' => '謹',
  '��' => '謬',
  '��' => '謫',
  '��' => '豐',
  '��' => '贅',
  '��' => '蹙',
  '��' => '蹣',
  '��' => '蹦',
  '��' => '蹤',
  '��' => '蹟',
  '��' => '蹕',
  '��' => '軀',
  '��' => '轉',
  '��' => '轍',
  '��' => '邇',
  '��' => '邃',
  '��' => '邈',
  '��' => '醫',
  '��' => '醬',
  '��' => '釐',
  '��' => '鎔',
  '��' => '鎊',
  '��' => '鎖',
  '��' => '鎢',
  '��' => '鎳',
  '��' => '鎮',
  '��' => '鎬',
  '��' => '鎰',
  '��' => '鎘',
  '��' => '鎚',
  '��' => '鎗',
  '��' => '闔',
  '��' => '闖',
  '�' => '闐',
  '�' => '闕',
  '�' => '離',
  '�' => '雜',
  '�' => '雙',
  '�' => '雛',
  '�' => '雞',
  '�' => '霤',
  '�' => '鞣',
  '�' => '鞦',
  '�@' => '鞭',
  '�A' => '韹',
  '�B' => '額',
  '�C' => '顏',
  '�D' => '題',
  '�E' => '顎',
  '�F' => '顓',
  '�G' => '颺',
  '�H' => '餾',
  '�I' => '餿',
  '�J' => '餽',
  '�K' => '餮',
  '�L' => '馥',
  '�M' => '騎',
  '�N' => '髁',
  '�O' => '鬃',
  '�P' => '鬆',
  '�Q' => '魏',
  '�R' => '魎',
  '�S' => '魍',
  '�T' => '鯊',
  '�U' => '鯉',
  '�V' => '鯽',
  '�W' => '鯈',
  '�X' => '鯀',
  '�Y' => '鵑',
  '�Z' => '鵝',
  '�[' => '鵠',
  '�\\' => '黠',
  '�]' => '鼕',
  '�^' => '鼬',
  '�_' => '儳',
  '�`' => '嚥',
  '�a' => '壞',
  '�b' => '壟',
  '�c' => '壢',
  '�d' => '寵',
  '�e' => '龐',
  '�f' => '廬',
  '�g' => '懲',
  '�h' => '懷',
  '�i' => '懶',
  '�j' => '懵',
  '�k' => '攀',
  '�l' => '攏',
  '�m' => '曠',
  '�n' => '曝',
  '�o' => '櫥',
  '�p' => '櫝',
  '�q' => '櫚',
  '�r' => '櫓',
  '�s' => '瀛',
  '�t' => '瀟',
  '�u' => '瀨',
  '�v' => '瀚',
  '�w' => '瀝',
  '�x' => '瀕',
  '�y' => '瀘',
  '�z' => '爆',
  '�{' => '爍',
  '�|' => '牘',
  '�}' => '犢',
  '�~' => '獸',
  'á' => '獺',
  'â' => '璽',
  'ã' => '瓊',
  'ä' => '瓣',
  'å' => '疇',
  'æ' => '疆',
  'ç' => '癟',
  'è' => '癡',
  'é' => '矇',
  'ê' => '礙',
  'ë' => '禱',
  'ì' => '穫',
  'í' => '穩',
  'î' => '簾',
  'ï' => '簿',
  'ð' => '簸',
  'ñ' => '簽',
  'ò' => '簷',
  'ó' => '籀',
  'ô' => '繫',
  'õ' => '繭',
  'ö' => '繹',
  '÷' => '繩',
  'ø' => '繪',
  'ù' => '羅',
  'ú' => '繳',
  'û' => '羶',
  'ü' => '羹',
  'ý' => '羸',
  'þ' => '臘',
  'ÿ' => '藩',
  '�' => '藝',
  '�' => '藪',
  '��' => '藕',
  '��' => '藤',
  '��' => '藥',
  '��' => '藷',
  '��' => '蟻',
  '��' => '蠅',
  '��' => '蠍',
  '��' => '蟹',
  '��' => '蟾',
  '��' => '襠',
  '��' => '襟',
  '��' => '襖',
  '��' => '襞',
  '��' => '譁',
  '��' => '譜',
  '��' => '識',
  '��' => '證',
  '��' => '譚',
  '��' => '譎',
  '��' => '譏',
  '��' => '譆',
  '��' => '譙',
  '��' => '贈',
  '��' => '贊',
  '��' => '蹼',
  '��' => '蹲',
  '��' => '躇',
  '��' => '蹶',
  '��' => '蹬',
  '��' => '蹺',
  '��' => '蹴',
  '��' => '轔',
  '��' => '轎',
  '��' => '辭',
  '��' => '邊',
  '��' => '邋',
  '��' => '醱',
  '��' => '醮',
  '��' => '鏡',
  '��' => '鏑',
  '��' => '鏟',
  '��' => '鏃',
  '��' => '鏈',
  '��' => '鏜',
  '��' => '鏝',
  '��' => '鏖',
  '��' => '鏢',
  '��' => '鏍',
  '��' => '鏘',
  '��' => '鏤',
  '��' => '鏗',
  '�' => '鏨',
  '�' => '關',
  '�' => '隴',
  '�' => '難',
  '�' => '霪',
  '�' => '霧',
  '�' => '靡',
  '�' => '韜',
  '�' => '韻',
  '�' => '類',
  '�@' => '願',
  '�A' => '顛',
  '�B' => '颼',
  '�C' => '饅',
  '�D' => '饉',
  '�E' => '騖',
  '�F' => '騙',
  '�G' => '鬍',
  '�H' => '鯨',
  '�I' => '鯧',
  '�J' => '鯖',
  '�K' => '鯛',
  '�L' => '鶉',
  '�M' => '鵡',
  '�N' => '鵲',
  '�O' => '鵪',
  '�P' => '鵬',
  '�Q' => '麒',
  '�R' => '麗',
  '�S' => '麓',
  '�T' => '麴',
  '�U' => '勸',
  '�V' => '嚨',
  '�W' => '嚷',
  '�X' => '嚶',
  '�Y' => '嚴',
  '�Z' => '嚼',
  '�[' => '壤',
  '�\\' => '孀',
  '�]' => '孃',
  '�^' => '孽',
  '�_' => '寶',
  '�`' => '巉',
  '�a' => '懸',
  '�b' => '懺',
  '�c' => '攘',
  '�d' => '攔',
  '�e' => '攙',
  '�f' => '曦',
  '�g' => '朧',
  '�h' => '櫬',
  '�i' => '瀾',
  '�j' => '瀰',
  '�k' => '瀲',
  '�l' => '爐',
  '�m' => '獻',
  '�n' => '瓏',
  '�o' => '癢',
  '�p' => '癥',
  '�q' => '礦',
  '�r' => '礪',
  '�s' => '礬',
  '�t' => '礫',
  '�u' => '竇',
  '�v' => '競',
  '�w' => '籌',
  '�x' => '籃',
  '�y' => '籍',
  '�z' => '糯',
  '�{' => '糰',
  '�|' => '辮',
  '�}' => '繽',
  '�~' => '繼',
  'ġ' => '纂',
  'Ģ' => '罌',
  'ģ' => '耀',
  'Ĥ' => '臚',
  'ĥ' => '艦',
  'Ħ' => '藻',
  'ħ' => '藹',
  'Ĩ' => '蘑',
  'ĩ' => '藺',
  'Ī' => '蘆',
  'ī' => '蘋',
  'Ĭ' => '蘇',
  'ĭ' => '蘊',
  'Į' => '蠔',
  'į' => '蠕',
  'İ' => '襤',
  'ı' => '覺',
  'IJ' => '觸',
  'ij' => '議',
  'Ĵ' => '譬',
  'ĵ' => '警',
  'Ķ' => '譯',
  'ķ' => '譟',
  'ĸ' => '譫',
  'Ĺ' => '贏',
  'ĺ' => '贍',
  'Ļ' => '躉',
  'ļ' => '躁',
  'Ľ' => '躅',
  'ľ' => '躂',
  'Ŀ' => '醴',
  '�' => '釋',
  '�' => '鐘',
  '��' => '鐃',
  '��' => '鏽',
  '��' => '闡',
  '��' => '霰',
  '��' => '飄',
  '��' => '饒',
  '��' => '饑',
  '��' => '馨',
  '��' => '騫',
  '��' => '騰',
  '��' => '騷',
  '��' => '騵',
  '��' => '鰓',
  '��' => '鰍',
  '��' => '鹹',
  '��' => '麵',
  '��' => '黨',
  '��' => '鼯',
  '��' => '齟',
  '��' => '齣',
  '��' => '齡',
  '��' => '儷',
  '��' => '儸',
  '��' => '囁',
  '��' => '囀',
  '��' => '囂',
  '��' => '夔',
  '��' => '屬',
  '��' => '巍',
  '��' => '懼',
  '��' => '懾',
  '��' => '攝',
  '��' => '攜',
  '��' => '斕',
  '��' => '曩',
  '��' => '櫻',
  '��' => '欄',
  '��' => '櫺',
  '��' => '殲',
  '��' => '灌',
  '��' => '爛',
  '��' => '犧',
  '��' => '瓖',
  '��' => '瓔',
  '��' => '癩',
  '��' => '矓',
  '��' => '籐',
  '��' => '纏',
  '��' => '續',
  '��' => '羼',
  '��' => '蘗',
  '�' => '蘭',
  '�' => '蘚',
  '�' => '蠣',
  '�' => '蠢',
  '�' => '蠡',
  '�' => '蠟',
  '�' => '襪',
  '�' => '襬',
  '�' => '覽',
  '�' => '譴',
  '�@' => '護',
  '�A' => '譽',
  '�B' => '贓',
  '�C' => '躊',
  '�D' => '躍',
  '�E' => '躋',
  '�F' => '轟',
  '�G' => '辯',
  '�H' => '醺',
  '�I' => '鐮',
  '�J' => '鐳',
  '�K' => '鐵',
  '�L' => '鐺',
  '�M' => '鐸',
  '�N' => '鐲',
  '�O' => '鐫',
  '�P' => '闢',
  '�Q' => '霸',
  '�R' => '霹',
  '�S' => '露',
  '�T' => '響',
  '�U' => '顧',
  '�V' => '顥',
  '�W' => '饗',
  '�X' => '驅',
  '�Y' => '驃',
  '�Z' => '驀',
  '�[' => '騾',
  '�\\' => '髏',
  '�]' => '魔',
  '�^' => '魑',
  '�_' => '鰭',
  '�`' => '鰥',
  '�a' => '鶯',
  '�b' => '鶴',
  '�c' => '鷂',
  '�d' => '鶸',
  '�e' => '麝',
  '�f' => '黯',
  '�g' => '鼙',
  '�h' => '齜',
  '�i' => '齦',
  '�j' => '齧',
  '�k' => '儼',
  '�l' => '儻',
  '�m' => '囈',
  '�n' => '囊',
  '�o' => '囉',
  '�p' => '孿',
  '�q' => '巔',
  '�r' => '巒',
  '�s' => '彎',
  '�t' => '懿',
  '�u' => '攤',
  '�v' => '權',
  '�w' => '歡',
  '�x' => '灑',
  '�y' => '灘',
  '�z' => '玀',
  '�{' => '瓤',
  '�|' => '疊',
  '�}' => '癮',
  '�~' => '癬',
  'š' => '禳',
  'Ţ' => '籠',
  'ţ' => '籟',
  'Ť' => '聾',
  'ť' => '聽',
  'Ŧ' => '臟',
  'ŧ' => '襲',
  'Ũ' => '襯',
  'ũ' => '觼',
  'Ū' => '讀',
  'ū' => '贖',
  'Ŭ' => '贗',
  'ŭ' => '躑',
  'Ů' => '躓',
  'ů' => '轡',
  'Ű' => '酈',
  'ű' => '鑄',
  'Ų' => '鑑',
  'ų' => '鑒',
  'Ŵ' => '霽',
  'ŵ' => '霾',
  'Ŷ' => '韃',
  'ŷ' => '韁',
  'Ÿ' => '顫',
  'Ź' => '饕',
  'ź' => '驕',
  'Ż' => '驍',
  'ż' => '髒',
  'Ž' => '鬚',
  'ž' => '鱉',
  'ſ' => '鰱',
  '�' => '鰾',
  '�' => '鰻',
  '��' => '鷓',
  '��' => '鷗',
  '��' => '鼴',
  '��' => '齬',
  '��' => '齪',
  '��' => '龔',
  '��' => '囌',
  '��' => '巖',
  '��' => '戀',
  '��' => '攣',
  '��' => '攫',
  '��' => '攪',
  '��' => '曬',
  '��' => '欐',
  '��' => '瓚',
  '��' => '竊',
  '��' => '籤',
  '��' => '籣',
  '��' => '籥',
  '��' => '纓',
  '��' => '纖',
  '��' => '纔',
  '��' => '臢',
  '��' => '蘸',
  '��' => '蘿',
  '��' => '蠱',
  '��' => '變',
  '��' => '邐',
  '��' => '邏',
  '��' => '鑣',
  '��' => '鑠',
  '��' => '鑤',
  '��' => '靨',
  '��' => '顯',
  '��' => '饜',
  '��' => '驚',
  '��' => '驛',
  '��' => '驗',
  '��' => '髓',
  '��' => '體',
  '��' => '髑',
  '��' => '鱔',
  '��' => '鱗',
  '��' => '鱖',
  '��' => '鷥',
  '��' => '麟',
  '��' => '黴',
  '��' => '囑',
  '��' => '壩',
  '��' => '攬',
  '��' => '灞',
  '�' => '癱',
  '�' => '癲',
  '�' => '矗',
  '�' => '罐',
  '�' => '羈',
  '�' => '蠶',
  '�' => '蠹',
  '�' => '衢',
  '�' => '讓',
  '�' => '讒',
  '�@' => '讖',
  '�A' => '艷',
  '�B' => '贛',
  '�C' => '釀',
  '�D' => '鑪',
  '�E' => '靂',
  '�F' => '靈',
  '�G' => '靄',
  '�H' => '韆',
  '�I' => '顰',
  '�J' => '驟',
  '�K' => '鬢',
  '�L' => '魘',
  '�M' => '鱟',
  '�N' => '鷹',
  '�O' => '鷺',
  '�P' => '鹼',
  '�Q' => '鹽',
  '�R' => '鼇',
  '�S' => '齷',
  '�T' => '齲',
  '�U' => '廳',
  '�V' => '欖',
  '�W' => '灣',
  '�X' => '籬',
  '�Y' => '籮',
  '�Z' => '蠻',
  '�[' => '觀',
  '�\\' => '躡',
  '�]' => '釁',
  '�^' => '鑲',
  '�_' => '鑰',
  '�`' => '顱',
  '�a' => '饞',
  '�b' => '髖',
  '�c' => '鬣',
  '�d' => '黌',
  '�e' => '灤',
  '�f' => '矚',
  '�g' => '讚',
  '�h' => '鑷',
  '�i' => '韉',
  '�j' => '驢',
  '�k' => '驥',
  '�l' => '纜',
  '�m' => '讜',
  '�n' => '躪',
  '�o' => '釅',
  '�p' => '鑽',
  '�q' => '鑾',
  '�r' => '鑼',
  '�s' => '鱷',
  '�t' => '鱸',
  '�u' => '黷',
  '�v' => '豔',
  '�w' => '鑿',
  '�x' => '鸚',
  '�y' => '爨',
  '�z' => '驪',
  '�{' => '鬱',
  '�|' => '鸛',
  '�}' => '鸞',
  '�~' => '籲',
  '�@' => '乂',
  '�A' => '乜',
  '�B' => '凵',
  '�C' => '匚',
  '�D' => '厂',
  '�E' => '万',
  '�F' => '丌',
  '�G' => '乇',
  '�H' => '亍',
  '�I' => '囗',
  '�J' => '兀',
  '�K' => '屮',
  '�L' => '彳',
  '�M' => '丏',
  '�N' => '冇',
  '�O' => '与',
  '�P' => '丮',
  '�Q' => '亓',
  '�R' => '仂',
  '�S' => '仉',
  '�T' => '仈',
  '�U' => '冘',
  '�V' => '勼',
  '�W' => '卬',
  '�X' => '厹',
  '�Y' => '圠',
  '�Z' => '夃',
  '�[' => '夬',
  '�\\' => '尐',
  '�]' => '巿',
  '�^' => '旡',
  '�_' => '殳',
  '�`' => '毌',
  '�a' => '气',
  '�b' => '爿',
  '�c' => '丱',
  '�d' => '丼',
  '�e' => '仨',
  '�f' => '仜',
  '�g' => '仩',
  '�h' => '仡',
  '�i' => '仝',
  '�j' => '仚',
  '�k' => '刌',
  '�l' => '匜',
  '�m' => '卌',
  '�n' => '圢',
  '�o' => '圣',
  '�p' => '夗',
  '�q' => '夯',
  '�r' => '宁',
  '�s' => '宄',
  '�t' => '尒',
  '�u' => '尻',
  '�v' => '屴',
  '�w' => '屳',
  '�x' => '帄',
  '�y' => '庀',
  '�z' => '庂',
  '�{' => '忉',
  '�|' => '戉',
  '�}' => '扐',
  '�~' => '氕',
  'ɡ' => '氶',
  'ɢ' => '汃',
  'ɣ' => '氿',
  'ɤ' => '氻',
  'ɥ' => '犮',
  'ɦ' => '犰',
  'ɧ' => '玊',
  'ɨ' => '禸',
  'ɩ' => '肊',
  'ɪ' => '阞',
  'ɫ' => '伎',
  'ɬ' => '优',
  'ɭ' => '伬',
  'ɮ' => '仵',
  'ɯ' => '伔',
  'ɰ' => '仱',
  'ɱ' => '伀',
  'ɲ' => '价',
  'ɳ' => '伈',
  'ɴ' => '伝',
  'ɵ' => '伂',
  'ɶ' => '伅',
  'ɷ' => '伢',
  'ɸ' => '伓',
  'ɹ' => '伄',
  'ɺ' => '仴',
  'ɻ' => '伒',
  'ɼ' => '冱',
  'ɽ' => '刓',
  'ɾ' => '刉',
  'ɿ' => '刐',
  '�' => '劦',
  '�' => '匢',
  '��' => '匟',
  '��' => '卍',
  '��' => '厊',
  '��' => '吇',
  '��' => '囡',
  '��' => '囟',
  '��' => '圮',
  '��' => '圪',
  '��' => '圴',
  '��' => '夼',
  '��' => '妀',
  '��' => '奼',
  '��' => '妅',
  '��' => '奻',
  '��' => '奾',
  '��' => '奷',
  '��' => '奿',
  '��' => '孖',
  '��' => '尕',
  '��' => '尥',
  '��' => '屼',
  '��' => '屺',
  '��' => '屻',
  '��' => '屾',
  '��' => '巟',
  '��' => '幵',
  '��' => '庄',
  '��' => '异',
  '��' => '弚',
  '��' => '彴',
  '��' => '忕',
  '��' => '忔',
  '��' => '忏',
  '��' => '扜',
  '��' => '扞',
  '��' => '扤',
  '��' => '扡',
  '��' => '扦',
  '��' => '扢',
  '��' => '扙',
  '��' => '扠',
  '��' => '扚',
  '��' => '扥',
  '��' => '旯',
  '��' => '旮',
  '��' => '朾',
  '��' => '朹',
  '��' => '朸',
  '��' => '朻',
  '��' => '机',
  '��' => '朿',
  '�' => '朼',
  '�' => '朳',
  '�' => '氘',
  '�' => '汆',
  '�' => '汒',
  '�' => '汜',
  '�' => '汏',
  '�' => '汊',
  '�' => '汔',
  '�' => '汋',
  '�@' => '汌',
  '�A' => '灱',
  '�B' => '牞',
  '�C' => '犴',
  '�D' => '犵',
  '�E' => '玎',
  '�F' => '甪',
  '�G' => '癿',
  '�H' => '穵',
  '�I' => '网',
  '�J' => '艸',
  '�K' => '艼',
  '�L' => '芀',
  '�M' => '艽',
  '�N' => '艿',
  '�O' => '虍',
  '�P' => '襾',
  '�Q' => '邙',
  '�R' => '邗',
  '�S' => '邘',
  '�T' => '邛',
  '�U' => '邔',
  '�V' => '阢',
  '�W' => '阤',
  '�X' => '阠',
  '�Y' => '阣',
  '�Z' => '佖',
  '�[' => '伻',
  '�\\' => '佢',
  '�]' => '佉',
  '�^' => '体',
  '�_' => '佤',
  '�`' => '伾',
  '�a' => '佧',
  '�b' => '佒',
  '�c' => '佟',
  '�d' => '佁',
  '�e' => '佘',
  '�f' => '伭',
  '�g' => '伳',
  '�h' => '伿',
  '�i' => '佡',
  '�j' => '冏',
  '�k' => '冹',
  '�l' => '刜',
  '�m' => '刞',
  '�n' => '刡',
  '�o' => '劭',
  '�p' => '劮',
  '�q' => '匉',
  '�r' => '卣',
  '�s' => '卲',
  '�t' => '厎',
  '�u' => '厏',
  '�v' => '吰',
  '�w' => '吷',
  '�x' => '吪',
  '�y' => '呔',
  '�z' => '呅',
  '�{' => '吙',
  '�|' => '吜',
  '�}' => '吥',
  '�~' => '吘',
  'ʡ' => '吽',
  'ʢ' => '呏',
  'ʣ' => '呁',
  'ʤ' => '吨',
  'ʥ' => '吤',
  'ʦ' => '呇',
  'ʧ' => '囮',
  'ʨ' => '囧',
  'ʩ' => '囥',
  'ʪ' => '坁',
  'ʫ' => '坅',
  'ʬ' => '坌',
  'ʭ' => '坉',
  'ʮ' => '坋',
  'ʯ' => '坒',
  'ʰ' => '夆',
  'ʱ' => '奀',
  'ʲ' => '妦',
  'ʳ' => '妘',
  'ʴ' => '妠',
  'ʵ' => '妗',
  'ʶ' => '妎',
  'ʷ' => '妢',
  'ʸ' => '妐',
  'ʹ' => '妏',
  'ʺ' => '妧',
  'ʻ' => '妡',
  'ʼ' => '宎',
  'ʽ' => '宒',
  'ʾ' => '尨',
  'ʿ' => '尪',
  '�' => '岍',
  '�' => '岏',
  '��' => '岈',
  '��' => '岋',
  '��' => '岉',
  '��' => '岒',
  '��' => '岊',
  '��' => '岆',
  '��' => '岓',
  '��' => '岕',
  '��' => '巠',
  '��' => '帊',
  '��' => '帎',
  '��' => '庋',
  '��' => '庉',
  '��' => '庌',
  '��' => '庈',
  '��' => '庍',
  '��' => '弅',
  '��' => '弝',
  '��' => '彸',
  '��' => '彶',
  '��' => '忒',
  '��' => '忑',
  '��' => '忐',
  '��' => '忭',
  '��' => '忨',
  '��' => '忮',
  '��' => '忳',
  '��' => '忡',
  '��' => '忤',
  '��' => '忣',
  '��' => '忺',
  '��' => '忯',
  '��' => '忷',
  '��' => '忻',
  '��' => '怀',
  '��' => '忴',
  '��' => '戺',
  '��' => '抃',
  '��' => '抌',
  '��' => '抎',
  '��' => '抏',
  '��' => '抔',
  '��' => '抇',
  '��' => '扱',
  '��' => '扻',
  '��' => '扺',
  '��' => '扰',
  '��' => '抁',
  '��' => '抈',
  '��' => '扷',
  '��' => '扽',
  '�' => '扲',
  '�' => '扴',
  '�' => '攷',
  '�' => '旰',
  '�' => '旴',
  '�' => '旳',
  '�' => '旲',
  '�' => '旵',
  '�' => '杅',
  '�' => '杇',
  '�@' => '杙',
  '�A' => '杕',
  '�B' => '杌',
  '�C' => '杈',
  '�D' => '杝',
  '�E' => '杍',
  '�F' => '杚',
  '�G' => '杋',
  '�H' => '毐',
  '�I' => '氙',
  '�J' => '氚',
  '�K' => '汸',
  '�L' => '汧',
  '�M' => '汫',
  '�N' => '沄',
  '�O' => '沋',
  '�P' => '沏',
  '�Q' => '汱',
  '�R' => '汯',
  '�S' => '汩',
  '�T' => '沚',
  '�U' => '汭',
  '�V' => '沇',
  '�W' => '沕',
  '�X' => '沜',
  '�Y' => '汦',
  '�Z' => '汳',
  '�[' => '汥',
  '�\\' => '汻',
  '�]' => '沎',
  '�^' => '灴',
  '�_' => '灺',
  '�`' => '牣',
  '�a' => '犿',
  '�b' => '犽',
  '�c' => '狃',
  '�d' => '狆',
  '�e' => '狁',
  '�f' => '犺',
  '�g' => '狅',
  '�h' => '玕',
  '�i' => '玗',
  '�j' => '玓',
  '�k' => '玔',
  '�l' => '玒',
  '�m' => '町',
  '�n' => '甹',
  '�o' => '疔',
  '�p' => '疕',
  '�q' => '皁',
  '�r' => '礽',
  '�s' => '耴',
  '�t' => '肕',
  '�u' => '肙',
  '�v' => '肐',
  '�w' => '肒',
  '�x' => '肜',
  '�y' => '芐',
  '�z' => '芏',
  '�{' => '芅',
  '�|' => '芎',
  '�}' => '芑',
  '�~' => '芓',
  'ˡ' => '芊',
  'ˢ' => '芃',
  'ˣ' => '芄',
  'ˤ' => '豸',
  '˥' => '迉',
  '˦' => '辿',
  '˧' => '邟',
  '˨' => '邡',
  '˩' => '邥',
  '˪' => '邞',
  '˫' => '邧',
  'ˬ' => '邠',
  '˭' => '阰',
  'ˮ' => '阨',
  '˯' => '阯',
  '˰' => '阭',
  '˱' => '丳',
  '˲' => '侘',
  '˳' => '佼',
  '˴' => '侅',
  '˵' => '佽',
  '˶' => '侀',
  '˷' => '侇',
  '˸' => '佶',
  '˹' => '佴',
  '˺' => '侉',
  '˻' => '侄',
  '˼' => '佷',
  '˽' => '佌',
  '˾' => '侗',
  '˿' => '佪',
  '�' => '侚',
  '�' => '佹',
  '��' => '侁',
  '��' => '佸',
  '��' => '侐',
  '��' => '侜',
  '��' => '侔',
  '��' => '侞',
  '��' => '侒',
  '��' => '侂',
  '��' => '侕',
  '��' => '佫',
  '��' => '佮',
  '��' => '冞',
  '��' => '冼',
  '��' => '冾',
  '��' => '刵',
  '��' => '刲',
  '��' => '刳',
  '��' => '剆',
  '��' => '刱',
  '��' => '劼',
  '��' => '匊',
  '��' => '匋',
  '��' => '匼',
  '��' => '厒',
  '��' => '厔',
  '��' => '咇',
  '��' => '呿',
  '��' => '咁',
  '��' => '咑',
  '��' => '咂',
  '��' => '咈',
  '��' => '呫',
  '��' => '呺',
  '��' => '呾',
  '��' => '呥',
  '��' => '呬',
  '��' => '呴',
  '��' => '呦',
  '��' => '咍',
  '��' => '呯',
  '��' => '呡',
  '��' => '呠',
  '��' => '咘',
  '��' => '呣',
  '��' => '呧',
  '��' => '呤',
  '��' => '囷',
  '��' => '囹',
  '��' => '坯',
  '��' => '坲',
  '��' => '坭',
  '�' => '坫',
  '�' => '坱',
  '�' => '坰',
  '�' => '坶',
  '�' => '垀',
  '�' => '坵',
  '�' => '坻',
  '�' => '坳',
  '�' => '坴',
  '�' => '坢',
  '�@' => '坨',
  '�A' => '坽',
  '�B' => '夌',
  '�C' => '奅',
  '�D' => '妵',
  '�E' => '妺',
  '�F' => '姏',
  '�G' => '姎',
  '�H' => '妲',
  '�I' => '姌',
  '�J' => '姁',
  '�K' => '妶',
  '�L' => '妼',
  '�M' => '姃',
  '�N' => '姖',
  '�O' => '妱',
  '�P' => '妽',
  '�Q' => '姀',
  '�R' => '姈',
  '�S' => '妴',
  '�T' => '姇',
  '�U' => '孢',
  '�V' => '孥',
  '�W' => '宓',
  '�X' => '宕',
  '�Y' => '屄',
  '�Z' => '屇',
  '�[' => '岮',
  '�\\' => '岤',
  '�]' => '岠',
  '�^' => '岵',
  '�_' => '岯',
  '�`' => '岨',
  '�a' => '岬',
  '�b' => '岟',
  '�c' => '岣',
  '�d' => '岭',
  '�e' => '岢',
  '�f' => '岪',
  '�g' => '岧',
  '�h' => '岝',
  '�i' => '岥',
  '�j' => '岶',
  '�k' => '岰',
  '�l' => '岦',
  '�m' => '帗',
  '�n' => '帔',
  '�o' => '帙',
  '�p' => '弨',
  '�q' => '弢',
  '�r' => '弣',
  '�s' => '弤',
  '�t' => '彔',
  '�u' => '徂',
  '�v' => '彾',
  '�w' => '彽',
  '�x' => '忞',
  '�y' => '忥',
  '�z' => '怭',
  '�{' => '怦',
  '�|' => '怙',
  '�}' => '怲',
  '�~' => '怋',
  '̡' => '怴',
  '̢' => '怊',
  '̣' => '怗',
  '̤' => '怳',
  '̥' => '怚',
  '̦' => '怞',
  '̧' => '怬',
  '̨' => '怢',
  '̩' => '怍',
  '̪' => '怐',
  '̫' => '怮',
  '̬' => '怓',
  '̭' => '怑',
  '̮' => '怌',
  '̯' => '怉',
  '̰' => '怜',
  '̱' => '戔',
  '̲' => '戽',
  '̳' => '抭',
  '̴' => '抴',
  '̵' => '拑',
  '̶' => '抾',
  '̷' => '抪',
  '̸' => '抶',
  '̹' => '拊',
  '̺' => '抮',
  '̻' => '抳',
  '̼' => '抯',
  '̽' => '抻',
  '̾' => '抩',
  '̿' => '抰',
  '�' => '抸',
  '�' => '攽',
  '��' => '斨',
  '��' => '斻',
  '��' => '昉',
  '��' => '旼',
  '��' => '昄',
  '��' => '昒',
  '��' => '昈',
  '��' => '旻',
  '��' => '昃',
  '��' => '昋',
  '��' => '昍',
  '��' => '昅',
  '��' => '旽',
  '��' => '昑',
  '��' => '昐',
  '��' => '曶',
  '��' => '朊',
  '��' => '枅',
  '��' => '杬',
  '��' => '枎',
  '��' => '枒',
  '��' => '杶',
  '��' => '杻',
  '��' => '枘',
  '��' => '枆',
  '��' => '构',
  '��' => '杴',
  '��' => '枍',
  '��' => '枌',
  '��' => '杺',
  '��' => '枟',
  '��' => '枑',
  '��' => '枙',
  '��' => '枃',
  '��' => '杽',
  '��' => '极',
  '��' => '杸',
  '��' => '杹',
  '��' => '枔',
  '��' => '欥',
  '��' => '殀',
  '��' => '歾',
  '��' => '毞',
  '��' => '氝',
  '��' => '沓',
  '��' => '泬',
  '��' => '泫',
  '��' => '泮',
  '��' => '泙',
  '��' => '沶',
  '��' => '泔',
  '�' => '沭',
  '�' => '泧',
  '�' => '沷',
  '�' => '泐',
  '�' => '泂',
  '�' => '沺',
  '�' => '泃',
  '�' => '泆',
  '�' => '泭',
  '�' => '泲',
  '�@' => '泒',
  '�A' => '泝',
  '�B' => '沴',
  '�C' => '沊',
  '�D' => '沝',
  '�E' => '沀',
  '�F' => '泞',
  '�G' => '泀',
  '�H' => '洰',
  '�I' => '泍',
  '�J' => '泇',
  '�K' => '沰',
  '�L' => '泹',
  '�M' => '泏',
  '�N' => '泩',
  '�O' => '泑',
  '�P' => '炔',
  '�Q' => '炘',
  '�R' => '炅',
  '�S' => '炓',
  '�T' => '炆',
  '�U' => '炄',
  '�V' => '炑',
  '�W' => '炖',
  '�X' => '炂',
  '�Y' => '炚',
  '�Z' => '炃',
  '�[' => '牪',
  '�\\' => '狖',
  '�]' => '狋',
  '�^' => '狘',
  '�_' => '狉',
  '�`' => '狜',
  '�a' => '狒',
  '�b' => '狔',
  '�c' => '狚',
  '�d' => '狌',
  '�e' => '狑',
  '�f' => '玤',
  '�g' => '玡',
  '�h' => '玭',
  '�i' => '玦',
  '�j' => '玢',
  '�k' => '玠',
  '�l' => '玬',
  '�m' => '玝',
  '�n' => '瓝',
  '�o' => '瓨',
  '�p' => '甿',
  '�q' => '畀',
  '�r' => '甾',
  '�s' => '疌',
  '�t' => '疘',
  '�u' => '皯',
  '�v' => '盳',
  '�w' => '盱',
  '�x' => '盰',
  '�y' => '盵',
  '�z' => '矸',
  '�{' => '矼',
  '�|' => '矹',
  '�}' => '矻',
  '�~' => '矺',
  '͡' => '矷',
  '͢' => '祂',
  'ͣ' => '礿',
  'ͤ' => '秅',
  'ͥ' => '穸',
  'ͦ' => '穻',
  'ͧ' => '竻',
  'ͨ' => '籵',
  'ͩ' => '糽',
  'ͪ' => '耵',
  'ͫ' => '肏',
  'ͬ' => '肮',
  'ͭ' => '肣',
  'ͮ' => '肸',
  'ͯ' => '肵',
  'Ͱ' => '肭',
  'ͱ' => '舠',
  'Ͳ' => '芠',
  'ͳ' => '苀',
  'ʹ' => '芫',
  '͵' => '芚',
  'Ͷ' => '芘',
  'ͷ' => '芛',
  '͸' => '芵',
  '͹' => '芧',
  'ͺ' => '芮',
  'ͻ' => '芼',
  'ͼ' => '芞',
  'ͽ' => '芺',
  ';' => '芴',
  'Ϳ' => '芨',
  '�' => '芡',
  '�' => '芩',
  '��' => '苂',
  '��' => '芤',
  '��' => '苃',
  '��' => '芶',
  '��' => '芢',
  '��' => '虰',
  '��' => '虯',
  '��' => '虭',
  '��' => '虮',
  '��' => '豖',
  '��' => '迒',
  '��' => '迋',
  '��' => '迓',
  '��' => '迍',
  '��' => '迖',
  '��' => '迕',
  '��' => '迗',
  '��' => '邲',
  '��' => '邴',
  '��' => '邯',
  '��' => '邳',
  '��' => '邰',
  '��' => '阹',
  '��' => '阽',
  '��' => '阼',
  '��' => '阺',
  '��' => '陃',
  '��' => '俍',
  '��' => '俅',
  '��' => '俓',
  '��' => '侲',
  '��' => '俉',
  '��' => '俋',
  '��' => '俁',
  '��' => '俔',
  '��' => '俜',
  '��' => '俙',
  '��' => '侻',
  '��' => '侳',
  '��' => '俛',
  '��' => '俇',
  '��' => '俖',
  '��' => '侺',
  '��' => '俀',
  '��' => '侹',
  '��' => '俬',
  '��' => '剄',
  '��' => '剉',
  '��' => '勀',
  '��' => '勂',
  '��' => '匽',
  '�' => '卼',
  '�' => '厗',
  '�' => '厖',
  '�' => '厙',
  '�' => '厘',
  '�' => '咺',
  '�' => '咡',
  '�' => '咭',
  '�' => '咥',
  '�' => '哏',
  '�@' => '哃',
  '�A' => '茍',
  '�B' => '咷',
  '�C' => '咮',
  '�D' => '哖',
  '�E' => '咶',
  '�F' => '哅',
  '�G' => '哆',
  '�H' => '咠',
  '�I' => '呰',
  '�J' => '咼',
  '�K' => '咢',
  '�L' => '咾',
  '�M' => '呲',
  '�N' => '哞',
  '�O' => '咰',
  '�P' => '垵',
  '�Q' => '垞',
  '�R' => '垟',
  '�S' => '垤',
  '�T' => '垌',
  '�U' => '垗',
  '�V' => '垝',
  '�W' => '垛',
  '�X' => '垔',
  '�Y' => '垘',
  '�Z' => '垏',
  '�[' => '垙',
  '�\\' => '垥',
  '�]' => '垚',
  '�^' => '垕',
  '�_' => '壴',
  '�`' => '复',
  '�a' => '奓',
  '�b' => '姡',
  '�c' => '姞',
  '�d' => '姮',
  '�e' => '娀',
  '�f' => '姱',
  '�g' => '姝',
  '�h' => '姺',
  '�i' => '姽',
  '�j' => '姼',
  '�k' => '姶',
  '�l' => '姤',
  '�m' => '姲',
  '�n' => '姷',
  '�o' => '姛',
  '�p' => '姩',
  '�q' => '姳',
  '�r' => '姵',
  '�s' => '姠',
  '�t' => '姾',
  '�u' => '姴',
  '�v' => '姭',
  '�w' => '宨',
  '�x' => '屌',
  '�y' => '峐',
  '�z' => '峘',
  '�{' => '峌',
  '�|' => '峗',
  '�}' => '峋',
  '�~' => '峛',
  'Ρ' => '峞',
  '΢' => '峚',
  'Σ' => '峉',
  'Τ' => '峇',
  'Υ' => '峊',
  'Φ' => '峖',
  'Χ' => '峓',
  'Ψ' => '峔',
  'Ω' => '峏',
  'Ϊ' => '峈',
  'Ϋ' => '峆',
  'ά' => '峎',
  'έ' => '峟',
  'ή' => '峸',
  'ί' => '巹',
  'ΰ' => '帡',
  'α' => '帢',
  'β' => '帣',
  'γ' => '帠',
  'δ' => '帤',
  'ε' => '庰',
  'ζ' => '庤',
  'η' => '庢',
  'θ' => '庛',
  'ι' => '庣',
  'κ' => '庥',
  'λ' => '弇',
  'μ' => '弮',
  'ν' => '彖',
  'ξ' => '徆',
  'ο' => '怷',
  '�' => '怹',
  '�' => '恔',
  '��' => '恲',
  '��' => '恞',
  '��' => '恅',
  '��' => '恓',
  '��' => '恇',
  '��' => '恉',
  '��' => '恛',
  '��' => '恌',
  '��' => '恀',
  '��' => '恂',
  '��' => '恟',
  '��' => '怤',
  '��' => '恄',
  '��' => '恘',
  '��' => '恦',
  '��' => '恮',
  '��' => '扂',
  '��' => '扃',
  '��' => '拏',
  '��' => '挍',
  '��' => '挋',
  '��' => '拵',
  '��' => '挎',
  '��' => '挃',
  '��' => '拫',
  '��' => '拹',
  '��' => '挏',
  '��' => '挌',
  '��' => '拸',
  '��' => '拶',
  '��' => '挀',
  '��' => '挓',
  '��' => '挔',
  '��' => '拺',
  '��' => '挕',
  '��' => '拻',
  '��' => '拰',
  '��' => '敁',
  '��' => '敃',
  '��' => '斪',
  '��' => '斿',
  '��' => '昶',
  '��' => '昡',
  '��' => '昲',
  '��' => '昵',
  '��' => '昜',
  '��' => '昦',
  '��' => '昢',
  '��' => '昳',
  '��' => '昫',
  '��' => '昺',
  '�' => '昝',
  '�' => '昴',
  '�' => '昹',
  '�' => '昮',
  '�' => '朏',
  '�' => '朐',
  '�' => '柁',
  '�' => '柲',
  '�' => '柈',
  '�' => '枺',
  '�@' => '柜',
  '�A' => '枻',
  '�B' => '柸',
  '�C' => '柘',
  '�D' => '柀',
  '�E' => '枷',
  '�F' => '柅',
  '�G' => '柫',
  '�H' => '柤',
  '�I' => '柟',
  '�J' => '枵',
  '�K' => '柍',
  '�L' => '枳',
  '�M' => '柷',
  '�N' => '柶',
  '�O' => '柮',
  '�P' => '柣',
  '�Q' => '柂',
  '�R' => '枹',
  '�S' => '柎',
  '�T' => '柧',
  '�U' => '柰',
  '�V' => '枲',
  '�W' => '柼',
  '�X' => '柆',
  '�Y' => '柭',
  '�Z' => '柌',
  '�[' => '枮',
  '�\\' => '柦',
  '�]' => '柛',
  '�^' => '柺',
  '�_' => '柉',
  '�`' => '柊',
  '�a' => '柃',
  '�b' => '柪',
  '�c' => '柋',
  '�d' => '欨',
  '�e' => '殂',
  '�f' => '殄',
  '�g' => '殶',
  '�h' => '毖',
  '�i' => '毘',
  '�j' => '毠',
  '�k' => '氠',
  '�l' => '氡',
  '�m' => '洨',
  '�n' => '洴',
  '�o' => '洭',
  '�p' => '洟',
  '�q' => '洼',
  '�r' => '洿',
  '�s' => '洒',
  '�t' => '洊',
  '�u' => '泚',
  '�v' => '洳',
  '�w' => '洄',
  '�x' => '洙',
  '�y' => '洺',
  '�z' => '洚',
  '�{' => '洑',
  '�|' => '洀',
  '�}' => '洝',
  '�~' => '浂',
  'ϡ' => '洁',
  'Ϣ' => '洘',
  'ϣ' => '洷',
  'Ϥ' => '洃',
  'ϥ' => '洏',
  'Ϧ' => '浀',
  'ϧ' => '洇',
  'Ϩ' => '洠',
  'ϩ' => '洬',
  'Ϫ' => '洈',
  'ϫ' => '洢',
  'Ϭ' => '洉',
  'ϭ' => '洐',
  'Ϯ' => '炷',
  'ϯ' => '炟',
  'ϰ' => '炾',
  'ϱ' => '炱',
  'ϲ' => '炰',
  'ϳ' => '炡',
  'ϴ' => '炴',
  'ϵ' => '炵',
  '϶' => '炩',
  'Ϸ' => '牁',
  'ϸ' => '牉',
  'Ϲ' => '牊',
  'Ϻ' => '牬',
  'ϻ' => '牰',
  'ϼ' => '牳',
  'Ͻ' => '牮',
  'Ͼ' => '狊',
  'Ͽ' => '狤',
  '�' => '狨',
  '�' => '狫',
  '��' => '狟',
  '��' => '狪',
  '��' => '狦',
  '��' => '狣',
  '��' => '玅',
  '��' => '珌',
  '��' => '珂',
  '��' => '珈',
  '��' => '珅',
  '��' => '玹',
  '��' => '玶',
  '��' => '玵',
  '��' => '玴',
  '��' => '珫',
  '��' => '玿',
  '��' => '珇',
  '��' => '玾',
  '��' => '珃',
  '��' => '珆',
  '��' => '玸',
  '��' => '珋',
  '��' => '瓬',
  '��' => '瓮',
  '��' => '甮',
  '��' => '畇',
  '��' => '畈',
  '��' => '疧',
  '��' => '疪',
  '��' => '癹',
  '��' => '盄',
  '��' => '眈',
  '��' => '眃',
  '��' => '眄',
  '��' => '眅',
  '��' => '眊',
  '��' => '盷',
  '��' => '盻',
  '��' => '盺',
  '��' => '矧',
  '��' => '矨',
  '��' => '砆',
  '��' => '砑',
  '��' => '砒',
  '��' => '砅',
  '��' => '砐',
  '��' => '砏',
  '��' => '砎',
  '��' => '砉',
  '��' => '砃',
  '��' => '砓',
  '��' => '祊',
  '�' => '祌',
  '�' => '祋',
  '�' => '祅',
  '�' => '祄',
  '�' => '秕',
  '�' => '种',
  '�' => '秏',
  '�' => '秖',
  '�' => '秎',
  '�' => '窀',
  '�@' => '穾',
  '�A' => '竑',
  '�B' => '笀',
  '�C' => '笁',
  '�D' => '籺',
  '�E' => '籸',
  '�F' => '籹',
  '�G' => '籿',
  '�H' => '粀',
  '�I' => '粁',
  '�J' => '紃',
  '�K' => '紈',
  '�L' => '紁',
  '�M' => '罘',
  '�N' => '羑',
  '�O' => '羍',
  '�P' => '羾',
  '�Q' => '耇',
  '�R' => '耎',
  '�S' => '耏',
  '�T' => '耔',
  '�U' => '耷',
  '�V' => '胘',
  '�W' => '胇',
  '�X' => '胠',
  '�Y' => '胑',
  '�Z' => '胈',
  '�[' => '胂',
  '�\\' => '胐',
  '�]' => '胅',
  '�^' => '胣',
  '�_' => '胙',
  '�`' => '胜',
  '�a' => '胊',
  '�b' => '胕',
  '�c' => '胉',
  '�d' => '胏',
  '�e' => '胗',
  '�f' => '胦',
  '�g' => '胍',
  '�h' => '臿',
  '�i' => '舡',
  '�j' => '芔',
  '�k' => '苙',
  '�l' => '苾',
  '�m' => '苹',
  '�n' => '茇',
  '�o' => '苨',
  '�p' => '茀',
  '�q' => '苕',
  '�r' => '茺',
  '�s' => '苫',
  '�t' => '苖',
  '�u' => '苴',
  '�v' => '苬',
  '�w' => '苡',
  '�x' => '苲',
  '�y' => '苵',
  '�z' => '茌',
  '�{' => '苻',
  '�|' => '苶',
  '�}' => '苰',
  '�~' => '苪',
  'С' => '苤',
  'Т' => '苠',
  'У' => '苺',
  'Ф' => '苳',
  'Х' => '苭',
  'Ц' => '虷',
  'Ч' => '虴',
  'Ш' => '虼',
  'Щ' => '虳',
  'Ъ' => '衁',
  'Ы' => '衎',
  'Ь' => '衧',
  'Э' => '衪',
  'Ю' => '衩',
  'Я' => '觓',
  'а' => '訄',
  'б' => '訇',
  'в' => '赲',
  'г' => '迣',
  'д' => '迡',
  'е' => '迮',
  'ж' => '迠',
  'з' => '郱',
  'и' => '邽',
  'й' => '邿',
  'к' => '郕',
  'л' => '郅',
  'м' => '邾',
  'н' => '郇',
  'о' => '郋',
  'п' => '郈',
  '�' => '釔',
  '�' => '釓',
  '��' => '陔',
  '��' => '陏',
  '��' => '陑',
  '��' => '陓',
  '��' => '陊',
  '��' => '陎',
  '��' => '倞',
  '��' => '倅',
  '��' => '倇',
  '��' => '倓',
  '��' => '倢',
  '��' => '倰',
  '��' => '倛',
  '��' => '俵',
  '��' => '俴',
  '��' => '倳',
  '��' => '倷',
  '��' => '倬',
  '��' => '俶',
  '��' => '俷',
  '��' => '倗',
  '��' => '倜',
  '��' => '倠',
  '��' => '倧',
  '��' => '倵',
  '��' => '倯',
  '��' => '倱',
  '��' => '倎',
  '��' => '党',
  '��' => '冔',
  '��' => '冓',
  '��' => '凊',
  '��' => '凄',
  '��' => '凅',
  '��' => '凈',
  '��' => '凎',
  '��' => '剡',
  '��' => '剚',
  '��' => '剒',
  '��' => '剞',
  '��' => '剟',
  '��' => '剕',
  '��' => '剢',
  '��' => '勍',
  '��' => '匎',
  '��' => '厞',
  '��' => '唦',
  '��' => '哢',
  '��' => '唗',
  '��' => '唒',
  '��' => '哧',
  '�' => '哳',
  '�' => '哤',
  '�' => '唚',
  '�' => '哿',
  '�' => '唄',
  '�' => '唈',
  '�' => '哫',
  '�' => '唑',
  '�' => '唅',
  '�' => '哱',
  '�@' => '唊',
  '�A' => '哻',
  '�B' => '哷',
  '�C' => '哸',
  '�D' => '哠',
  '�E' => '唎',
  '�F' => '唃',
  '�G' => '唋',
  '�H' => '圁',
  '�I' => '圂',
  '�J' => '埌',
  '�K' => '堲',
  '�L' => '埕',
  '�M' => '埒',
  '�N' => '垺',
  '�O' => '埆',
  '�P' => '垽',
  '�Q' => '垼',
  '�R' => '垸',
  '�S' => '垶',
  '�T' => '垿',
  '�U' => '埇',
  '�V' => '埐',
  '�W' => '垹',
  '�X' => '埁',
  '�Y' => '夎',
  '�Z' => '奊',
  '�[' => '娙',
  '�\\' => '娖',
  '�]' => '娭',
  '�^' => '娮',
  '�_' => '娕',
  '�`' => '娏',
  '�a' => '娗',
  '�b' => '娊',
  '�c' => '娞',
  '�d' => '娳',
  '�e' => '孬',
  '�f' => '宧',
  '�g' => '宭',
  '�h' => '宬',
  '�i' => '尃',
  '�j' => '屖',
  '�k' => '屔',
  '�l' => '峬',
  '�m' => '峿',
  '�n' => '峮',
  '�o' => '峱',
  '�p' => '峷',
  '�q' => '崀',
  '�r' => '峹',
  '�s' => '帩',
  '�t' => '帨',
  '�u' => '庨',
  '�v' => '庮',
  '�w' => '庪',
  '�x' => '庬',
  '�y' => '弳',
  '�z' => '弰',
  '�{' => '彧',
  '�|' => '恝',
  '�}' => '恚',
  '�~' => '恧',
  'ѡ' => '恁',
  'Ѣ' => '悢',
  'ѣ' => '悈',
  'Ѥ' => '悀',
  'ѥ' => '悒',
  'Ѧ' => '悁',
  'ѧ' => '悝',
  'Ѩ' => '悃',
  'ѩ' => '悕',
  'Ѫ' => '悛',
  'ѫ' => '悗',
  'Ѭ' => '悇',
  'ѭ' => '悜',
  'Ѯ' => '悎',
  'ѯ' => '戙',
  'Ѱ' => '扆',
  'ѱ' => '拲',
  'Ѳ' => '挐',
  'ѳ' => '捖',
  'Ѵ' => '挬',
  'ѵ' => '捄',
  'Ѷ' => '捅',
  'ѷ' => '挶',
  'Ѹ' => '捃',
  'ѹ' => '揤',
  'Ѻ' => '挹',
  'ѻ' => '捋',
  'Ѽ' => '捊',
  'ѽ' => '挼',
  'Ѿ' => '挩',
  'ѿ' => '捁',
  '�' => '挴',
  '�' => '捘',
  '��' => '捔',
  '��' => '捙',
  '��' => '挭',
  '��' => '捇',
  '��' => '挳',
  '��' => '捚',
  '��' => '捑',
  '��' => '挸',
  '��' => '捗',
  '��' => '捀',
  '��' => '捈',
  '��' => '敊',
  '��' => '敆',
  '��' => '旆',
  '��' => '旃',
  '��' => '旄',
  '��' => '旂',
  '��' => '晊',
  '��' => '晟',
  '��' => '晇',
  '��' => '晑',
  '��' => '朒',
  '��' => '朓',
  '��' => '栟',
  '��' => '栚',
  '��' => '桉',
  '��' => '栲',
  '��' => '栳',
  '��' => '栻',
  '��' => '桋',
  '��' => '桏',
  '��' => '栖',
  '��' => '栱',
  '��' => '栜',
  '��' => '栵',
  '��' => '栫',
  '��' => '栭',
  '��' => '栯',
  '��' => '桎',
  '��' => '桄',
  '��' => '栴',
  '��' => '栝',
  '��' => '栒',
  '��' => '栔',
  '��' => '栦',
  '��' => '栨',
  '��' => '栮',
  '��' => '桍',
  '��' => '栺',
  '��' => '栥',
  '��' => '栠',
  '�' => '欬',
  '�' => '欯',
  '�' => '欭',
  '�' => '欱',
  '�' => '欴',
  '�' => '歭',
  '�' => '肂',
  '�' => '殈',
  '�' => '毦',
  '�' => '毤',
  '�@' => '毨',
  '�A' => '毣',
  '�B' => '毢',
  '�C' => '毧',
  '�D' => '氥',
  '�E' => '浺',
  '�F' => '浣',
  '�G' => '浤',
  '�H' => '浶',
  '�I' => '洍',
  '�J' => '浡',
  '�K' => '涒',
  '�L' => '浘',
  '�M' => '浢',
  '�N' => '浭',
  '�O' => '浯',
  '�P' => '涑',
  '�Q' => '涍',
  '�R' => '淯',
  '�S' => '浿',
  '�T' => '涆',
  '�U' => '浞',
  '�V' => '浧',
  '�W' => '浠',
  '�X' => '涗',
  '�Y' => '浰',
  '�Z' => '浼',
  '�[' => '浟',
  '�\\' => '涂',
  '�]' => '涘',
  '�^' => '洯',
  '�_' => '浨',
  '�`' => '涋',
  '�a' => '浾',
  '�b' => '涀',
  '�c' => '涄',
  '�d' => '洖',
  '�e' => '涃',
  '�f' => '浻',
  '�g' => '浽',
  '�h' => '浵',
  '�i' => '涐',
  '�j' => '烜',
  '�k' => '烓',
  '�l' => '烑',
  '�m' => '烝',
  '�n' => '烋',
  '�o' => '缹',
  '�p' => '烢',
  '�q' => '烗',
  '�r' => '烒',
  '�s' => '烞',
  '�t' => '烠',
  '�u' => '烔',
  '�v' => '烍',
  '�w' => '烅',
  '�x' => '烆',
  '�y' => '烇',
  '�z' => '烚',
  '�{' => '烎',
  '�|' => '烡',
  '�}' => '牂',
  '�~' => '牸',
  'ҡ' => '牷',
  'Ң' => '牶',
  'ң' => '猀',
  'Ҥ' => '狺',
  'ҥ' => '狴',
  'Ҧ' => '狾',
  'ҧ' => '狶',
  'Ҩ' => '狳',
  'ҩ' => '狻',
  'Ҫ' => '猁',
  'ҫ' => '珓',
  'Ҭ' => '珙',
  'ҭ' => '珥',
  'Ү' => '珖',
  'ү' => '玼',
  'Ұ' => '珧',
  'ұ' => '珣',
  'Ҳ' => '珩',
  'ҳ' => '珜',
  'Ҵ' => '珒',
  'ҵ' => '珛',
  'Ҷ' => '珔',
  'ҷ' => '珝',
  'Ҹ' => '珚',
  'ҹ' => '珗',
  'Һ' => '珘',
  'һ' => '珨',
  'Ҽ' => '瓞',
  'ҽ' => '瓟',
  'Ҿ' => '瓴',
  'ҿ' => '瓵',
  '�' => '甡',
  '�' => '畛',
  '��' => '畟',
  '��' => '疰',
  '��' => '痁',
  '��' => '疻',
  '��' => '痄',
  '��' => '痀',
  '��' => '疿',
  '��' => '疶',
  '��' => '疺',
  '��' => '皊',
  '��' => '盉',
  '��' => '眝',
  '��' => '眛',
  '��' => '眐',
  '��' => '眓',
  '��' => '眒',
  '��' => '眣',
  '��' => '眑',
  '��' => '眕',
  '��' => '眙',
  '��' => '眚',
  '��' => '眢',
  '��' => '眧',
  '��' => '砣',
  '��' => '砬',
  '��' => '砢',
  '��' => '砵',
  '��' => '砯',
  '��' => '砨',
  '��' => '砮',
  '��' => '砫',
  '��' => '砡',
  '��' => '砩',
  '��' => '砳',
  '��' => '砪',
  '��' => '砱',
  '��' => '祔',
  '��' => '祛',
  '��' => '祏',
  '��' => '祜',
  '��' => '祓',
  '��' => '祒',
  '��' => '祑',
  '��' => '秫',
  '��' => '秬',
  '��' => '秠',
  '��' => '秮',
  '��' => '秭',
  '��' => '秪',
  '��' => '秜',
  '��' => '秞',
  '�' => '秝',
  '�' => '窆',
  '�' => '窉',
  '�' => '窅',
  '�' => '窋',
  '�' => '窌',
  '�' => '窊',
  '�' => '窇',
  '�' => '竘',
  '�' => '笐',
  '�@' => '笄',
  '�A' => '笓',
  '�B' => '笅',
  '�C' => '笏',
  '�D' => '笈',
  '�E' => '笊',
  '�F' => '笎',
  '�G' => '笉',
  '�H' => '笒',
  '�I' => '粄',
  '�J' => '粑',
  '�K' => '粊',
  '�L' => '粌',
  '�M' => '粈',
  '�N' => '粍',
  '�O' => '粅',
  '�P' => '紞',
  '�Q' => '紝',
  '�R' => '紑',
  '�S' => '紎',
  '�T' => '紘',
  '�U' => '紖',
  '�V' => '紓',
  '�W' => '紟',
  '�X' => '紒',
  '�Y' => '紏',
  '�Z' => '紌',
  '�[' => '罜',
  '�\\' => '罡',
  '�]' => '罞',
  '�^' => '罠',
  '�_' => '罝',
  '�`' => '罛',
  '�a' => '羖',
  '�b' => '羒',
  '�c' => '翃',
  '�d' => '翂',
  '�e' => '翀',
  '�f' => '耖',
  '�g' => '耾',
  '�h' => '耹',
  '�i' => '胺',
  '�j' => '胲',
  '�k' => '胹',
  '�l' => '胵',
  '�m' => '脁',
  '�n' => '胻',
  '�o' => '脀',
  '�p' => '舁',
  '�q' => '舯',
  '�r' => '舥',
  '�s' => '茳',
  '�t' => '茭',
  '�u' => '荄',
  '�v' => '茙',
  '�w' => '荑',
  '�x' => '茥',
  '�y' => '荖',
  '�z' => '茿',
  '�{' => '荁',
  '�|' => '茦',
  '�}' => '茜',
  '�~' => '茢',
  'ӡ' => '荂',
  'Ӣ' => '荎',
  'ӣ' => '茛',
  'Ӥ' => '茪',
  'ӥ' => '茈',
  'Ӧ' => '茼',
  'ӧ' => '荍',
  'Ө' => '茖',
  'ө' => '茤',
  'Ӫ' => '茠',
  'ӫ' => '茷',
  'Ӭ' => '茯',
  'ӭ' => '茩',
  'Ӯ' => '荇',
  'ӯ' => '荅',
  'Ӱ' => '荌',
  'ӱ' => '荓',
  'Ӳ' => '茞',
  'ӳ' => '茬',
  'Ӵ' => '荋',
  'ӵ' => '茧',
  'Ӷ' => '荈',
  'ӷ' => '虓',
  'Ӹ' => '虒',
  'ӹ' => '蚢',
  'Ӻ' => '蚨',
  'ӻ' => '蚖',
  'Ӽ' => '蚍',
  'ӽ' => '蚑',
  'Ӿ' => '蚞',
  'ӿ' => '蚇',
  '�' => '蚗',
  '�' => '蚆',
  '��' => '蚋',
  '��' => '蚚',
  '��' => '蚅',
  '��' => '蚥',
  '��' => '蚙',
  '��' => '蚡',
  '��' => '蚧',
  '��' => '蚕',
  '��' => '蚘',
  '��' => '蚎',
  '��' => '蚝',
  '��' => '蚐',
  '��' => '蚔',
  '��' => '衃',
  '��' => '衄',
  '��' => '衭',
  '��' => '衵',
  '��' => '衶',
  '��' => '衲',
  '��' => '袀',
  '��' => '衱',
  '��' => '衿',
  '��' => '衯',
  '��' => '袃',
  '��' => '衾',
  '��' => '衴',
  '��' => '衼',
  '��' => '訒',
  '��' => '豇',
  '��' => '豗',
  '��' => '豻',
  '��' => '貤',
  '��' => '貣',
  '��' => '赶',
  '��' => '赸',
  '��' => '趵',
  '��' => '趷',
  '��' => '趶',
  '��' => '軑',
  '��' => '軓',
  '��' => '迾',
  '��' => '迵',
  '��' => '适',
  '��' => '迿',
  '��' => '迻',
  '��' => '逄',
  '��' => '迼',
  '��' => '迶',
  '��' => '郖',
  '��' => '郠',
  '��' => '郙',
  '�' => '郚',
  '�' => '郣',
  '�' => '郟',
  '�' => '郥',
  '�' => '郘',
  '�' => '郛',
  '�' => '郗',
  '�' => '郜',
  '�' => '郤',
  '�' => '酐',
  '�@' => '酎',
  '�A' => '酏',
  '�B' => '釕',
  '�C' => '釢',
  '�D' => '釚',
  '�E' => '陜',
  '�F' => '陟',
  '�G' => '隼',
  '�H' => '飣',
  '�I' => '髟',
  '�J' => '鬯',
  '�K' => '乿',
  '�L' => '偰',
  '�M' => '偪',
  '�N' => '偡',
  '�O' => '偞',
  '�P' => '偠',
  '�Q' => '偓',
  '�R' => '偋',
  '�S' => '偝',
  '�T' => '偲',
  '�U' => '偈',
  '�V' => '偍',
  '�W' => '偁',
  '�X' => '偛',
  '�Y' => '偊',
  '�Z' => '偢',
  '�[' => '倕',
  '�\\' => '偅',
  '�]' => '偟',
  '�^' => '偩',
  '�_' => '偫',
  '�`' => '偣',
  '�a' => '偤',
  '�b' => '偆',
  '�c' => '偀',
  '�d' => '偮',
  '�e' => '偳',
  '�f' => '偗',
  '�g' => '偑',
  '�h' => '凐',
  '�i' => '剫',
  '�j' => '剭',
  '�k' => '剬',
  '�l' => '剮',
  '�m' => '勖',
  '�n' => '勓',
  '�o' => '匭',
  '�p' => '厜',
  '�q' => '啵',
  '�r' => '啶',
  '�s' => '唼',
  '�t' => '啍',
  '�u' => '啐',
  '�v' => '唴',
  '�w' => '唪',
  '�x' => '啑',
  '�y' => '啢',
  '�z' => '唶',
  '�{' => '唵',
  '�|' => '唰',
  '�}' => '啒',
  '�~' => '啅',
  'ԡ' => '唌',
  'Ԣ' => '唲',
  'ԣ' => '啥',
  'Ԥ' => '啎',
  'ԥ' => '唹',
  'Ԧ' => '啈',
  'ԧ' => '唭',
  'Ԩ' => '唻',
  'ԩ' => '啀',
  'Ԫ' => '啋',
  'ԫ' => '圊',
  'Ԭ' => '圇',
  'ԭ' => '埻',
  'Ԯ' => '堔',
  'ԯ' => '埢',
  '԰' => '埶',
  'Ա' => '埜',
  'Բ' => '埴',
  'Գ' => '堀',
  'Դ' => '埭',
  'Ե' => '埽',
  'Զ' => '堈',
  'Է' => '埸',
  'Ը' => '堋',
  'Թ' => '埳',
  'Ժ' => '埏',
  'Ի' => '堇',
  'Լ' => '埮',
  'Խ' => '埣',
  'Ծ' => '埲',
  'Կ' => '埥',
  '�' => '埬',
  '�' => '埡',
  '��' => '堎',
  '��' => '埼',
  '��' => '堐',
  '��' => '埧',
  '��' => '堁',
  '��' => '堌',
  '��' => '埱',
  '��' => '埩',
  '��' => '埰',
  '��' => '堍',
  '��' => '堄',
  '��' => '奜',
  '��' => '婠',
  '��' => '婘',
  '��' => '婕',
  '��' => '婧',
  '��' => '婞',
  '��' => '娸',
  '��' => '娵',
  '��' => '婭',
  '��' => '婐',
  '��' => '婟',
  '��' => '婥',
  '��' => '婬',
  '��' => '婓',
  '��' => '婤',
  '��' => '婗',
  '��' => '婃',
  '��' => '婝',
  '��' => '婒',
  '��' => '婄',
  '��' => '婛',
  '��' => '婈',
  '��' => '媎',
  '��' => '娾',
  '��' => '婍',
  '��' => '娹',
  '��' => '婌',
  '��' => '婰',
  '��' => '婩',
  '��' => '婇',
  '��' => '婑',
  '��' => '婖',
  '��' => '婂',
  '��' => '婜',
  '��' => '孲',
  '��' => '孮',
  '��' => '寁',
  '��' => '寀',
  '��' => '屙',
  '��' => '崞',
  '�' => '崋',
  '�' => '崝',
  '�' => '崚',
  '�' => '崠',
  '�' => '崌',
  '�' => '崨',
  '�' => '崍',
  '�' => '崦',
  '�' => '崥',
  '�' => '崏',
  '�@' => '崰',
  '�A' => '崒',
  '�B' => '崣',
  '�C' => '崟',
  '�D' => '崮',
  '�E' => '帾',
  '�F' => '帴',
  '�G' => '庱',
  '�H' => '庴',
  '�I' => '庹',
  '�J' => '庲',
  '�K' => '庳',
  '�L' => '弶',
  '�M' => '弸',
  '�N' => '徛',
  '�O' => '徖',
  '�P' => '徟',
  '�Q' => '悊',
  '�R' => '悐',
  '�S' => '悆',
  '�T' => '悾',
  '�U' => '悰',
  '�V' => '悺',
  '�W' => '惓',
  '�X' => '惔',
  '�Y' => '惏',
  '�Z' => '惤',
  '�[' => '惙',
  '�\\' => '惝',
  '�]' => '惈',
  '�^' => '悱',
  '�_' => '惛',
  '�`' => '悷',
  '�a' => '惊',
  '�b' => '悿',
  '�c' => '惃',
  '�d' => '惍',
  '�e' => '惀',
  '�f' => '挲',
  '�g' => '捥',
  '�h' => '掊',
  '�i' => '掂',
  '�j' => '捽',
  '�k' => '掽',
  '�l' => '掞',
  '�m' => '掭',
  '�n' => '掝',
  '�o' => '掗',
  '�p' => '掫',
  '�q' => '掎',
  '�r' => '捯',
  '�s' => '掇',
  '�t' => '掐',
  '�u' => '据',
  '�v' => '掯',
  '�w' => '捵',
  '�x' => '掜',
  '�y' => '捭',
  '�z' => '掮',
  '�{' => '捼',
  '�|' => '掤',
  '�}' => '挻',
  '�~' => '掟',
  'ա' => '捸',
  'բ' => '掅',
  'գ' => '掁',
  'դ' => '掑',
  'ե' => '掍',
  'զ' => '捰',
  'է' => '敓',
  'ը' => '旍',
  'թ' => '晥',
  'ժ' => '晡',
  'ի' => '晛',
  'լ' => '晙',
  'խ' => '晜',
  'ծ' => '晢',
  'կ' => '朘',
  'հ' => '桹',
  'ձ' => '梇',
  'ղ' => '梐',
  'ճ' => '梜',
  'մ' => '桭',
  'յ' => '桮',
  'ն' => '梮',
  'շ' => '梫',
  'ո' => '楖',
  'չ' => '桯',
  'պ' => '梣',
  'ջ' => '梬',
  'ռ' => '梩',
  'ս' => '桵',
  'վ' => '桴',
  'տ' => '梲',
  '�' => '梏',
  '�' => '桷',
  '��' => '梒',
  '��' => '桼',
  '��' => '桫',
  '��' => '桲',
  '��' => '梪',
  '��' => '梀',
  '��' => '桱',
  '��' => '桾',
  '��' => '梛',
  '��' => '梖',
  '��' => '梋',
  '��' => '梠',
  '��' => '梉',
  '��' => '梤',
  '��' => '桸',
  '��' => '桻',
  '��' => '梑',
  '��' => '梌',
  '��' => '梊',
  '��' => '桽',
  '��' => '欶',
  '��' => '欳',
  '��' => '欷',
  '��' => '欸',
  '��' => '殑',
  '��' => '殏',
  '��' => '殍',
  '��' => '殎',
  '��' => '殌',
  '��' => '氪',
  '��' => '淀',
  '��' => '涫',
  '��' => '涴',
  '��' => '涳',
  '��' => '湴',
  '��' => '涬',
  '��' => '淩',
  '��' => '淢',
  '��' => '涷',
  '��' => '淶',
  '��' => '淔',
  '��' => '渀',
  '��' => '淈',
  '��' => '淠',
  '��' => '淟',
  '��' => '淖',
  '��' => '涾',
  '��' => '淥',
  '��' => '淜',
  '��' => '淝',
  '��' => '淛',
  '�' => '淴',
  '�' => '淊',
  '�' => '涽',
  '�' => '淭',
  '�' => '淰',
  '�' => '涺',
  '�' => '淕',
  '�' => '淂',
  '�' => '淏',
  '�' => '淉',
  '�@' => '淐',
  '�A' => '淲',
  '�B' => '淓',
  '�C' => '淽',
  '�D' => '淗',
  '�E' => '淍',
  '�F' => '淣',
  '�G' => '涻',
  '�H' => '烺',
  '�I' => '焍',
  '�J' => '烷',
  '�K' => '焗',
  '�L' => '烴',
  '�M' => '焌',
  '�N' => '烰',
  '�O' => '焄',
  '�P' => '烳',
  '�Q' => '焐',
  '�R' => '烼',
  '�S' => '烿',
  '�T' => '焆',
  '�U' => '焓',
  '�V' => '焀',
  '�W' => '烸',
  '�X' => '烶',
  '�Y' => '焋',
  '�Z' => '焂',
  '�[' => '焎',
  '�\\' => '牾',
  '�]' => '牻',
  '�^' => '牼',
  '�_' => '牿',
  '�`' => '猝',
  '�a' => '猗',
  '�b' => '猇',
  '�c' => '猑',
  '�d' => '猘',
  '�e' => '猊',
  '�f' => '猈',
  '�g' => '狿',
  '�h' => '猏',
  '�i' => '猞',
  '�j' => '玈',
  '�k' => '珶',
  '�l' => '珸',
  '�m' => '珵',
  '�n' => '琄',
  '�o' => '琁',
  '�p' => '珽',
  '�q' => '琇',
  '�r' => '琀',
  '�s' => '珺',
  '�t' => '珼',
  '�u' => '珿',
  '�v' => '琌',
  '�w' => '琋',
  '�x' => '珴',
  '�y' => '琈',
  '�z' => '畤',
  '�{' => '畣',
  '�|' => '痎',
  '�}' => '痒',
  '�~' => '痏',
  '֡' => '痋',
  '֢' => '痌',
  '֣' => '痑',
  '֤' => '痐',
  '֥' => '皏',
  '֦' => '皉',
  '֧' => '盓',
  '֨' => '眹',
  '֩' => '眯',
  '֪' => '眭',
  '֫' => '眱',
  '֬' => '眲',
  '֭' => '眴',
  '֮' => '眳',
  '֯' => '眽',
  'ְ' => '眥',
  'ֱ' => '眻',
  'ֲ' => '眵',
  'ֳ' => '硈',
  'ִ' => '硒',
  'ֵ' => '硉',
  'ֶ' => '硍',
  'ַ' => '硊',
  'ָ' => '硌',
  'ֹ' => '砦',
  'ֺ' => '硅',
  'ֻ' => '硐',
  'ּ' => '祤',
  'ֽ' => '祧',
  '־' => '祩',
  'ֿ' => '祪',
  '�' => '祣',
  '�' => '祫',
  '��' => '祡',
  '��' => '离',
  '��' => '秺',
  '��' => '秸',
  '��' => '秶',
  '��' => '秷',
  '��' => '窏',
  '��' => '窔',
  '��' => '窐',
  '��' => '笵',
  '��' => '筇',
  '��' => '笴',
  '��' => '笥',
  '��' => '笰',
  '��' => '笢',
  '��' => '笤',
  '��' => '笳',
  '��' => '笘',
  '��' => '笪',
  '��' => '笝',
  '��' => '笱',
  '��' => '笫',
  '��' => '笭',
  '��' => '笯',
  '��' => '笲',
  '��' => '笸',
  '��' => '笚',
  '��' => '笣',
  '��' => '粔',
  '��' => '粘',
  '��' => '粖',
  '��' => '粣',
  '��' => '紵',
  '��' => '紽',
  '��' => '紸',
  '��' => '紶',
  '��' => '紺',
  '��' => '絅',
  '��' => '紬',
  '��' => '紩',
  '��' => '絁',
  '��' => '絇',
  '��' => '紾',
  '��' => '紿',
  '��' => '絊',
  '��' => '紻',
  '��' => '紨',
  '��' => '罣',
  '��' => '羕',
  '��' => '羜',
  '��' => '羝',
  '�' => '羛',
  '�' => '翊',
  '�' => '翋',
  '�' => '翍',
  '�' => '翐',
  '�' => '翑',
  '�' => '翇',
  '�' => '翏',
  '�' => '翉',
  '�' => '耟',
  '�@' => '耞',
  '�A' => '耛',
  '�B' => '聇',
  '�C' => '聃',
  '�D' => '聈',
  '�E' => '脘',
  '�F' => '脥',
  '�G' => '脙',
  '�H' => '脛',
  '�I' => '脭',
  '�J' => '脟',
  '�K' => '脬',
  '�L' => '脞',
  '�M' => '脡',
  '�N' => '脕',
  '�O' => '脧',
  '�P' => '脝',
  '�Q' => '脢',
  '�R' => '舑',
  '�S' => '舸',
  '�T' => '舳',
  '�U' => '舺',
  '�V' => '舴',
  '�W' => '舲',
  '�X' => '艴',
  '�Y' => '莐',
  '�Z' => '莣',
  '�[' => '莨',
  '�\\' => '莍',
  '�]' => '荺',
  '�^' => '荳',
  '�_' => '莤',
  '�`' => '荴',
  '�a' => '莏',
  '�b' => '莁',
  '�c' => '莕',
  '�d' => '莙',
  '�e' => '荵',
  '�f' => '莔',
  '�g' => '莩',
  '�h' => '荽',
  '�i' => '莃',
  '�j' => '莌',
  '�k' => '莝',
  '�l' => '莛',
  '�m' => '莪',
  '�n' => '莋',
  '�o' => '荾',
  '�p' => '莥',
  '�q' => '莯',
  '�r' => '莈',
  '�s' => '莗',
  '�t' => '莰',
  '�u' => '荿',
  '�v' => '莦',
  '�w' => '莇',
  '�x' => '莮',
  '�y' => '荶',
  '�z' => '莚',
  '�{' => '虙',
  '�|' => '虖',
  '�}' => '蚿',
  '�~' => '蚷',
  'ס' => '蛂',
  'ע' => '蛁',
  'ף' => '蛅',
  'פ' => '蚺',
  'ץ' => '蚰',
  'צ' => '蛈',
  'ק' => '蚹',
  'ר' => '蚳',
  'ש' => '蚸',
  'ת' => '蛌',
  '׫' => '蚴',
  '׬' => '蚻',
  '׭' => '蚼',
  '׮' => '蛃',
  'ׯ' => '蚽',
  'װ' => '蚾',
  'ױ' => '衒',
  'ײ' => '袉',
  '׳' => '袕',
  '״' => '袨',
  '׵' => '袢',
  '׶' => '袪',
  '׷' => '袚',
  '׸' => '袑',
  '׹' => '袡',
  '׺' => '袟',
  '׻' => '袘',
  '׼' => '袧',
  '׽' => '袙',
  '׾' => '袛',
  '׿' => '袗',
  '�' => '袤',
  '�' => '袬',
  '��' => '袌',
  '��' => '袓',
  '��' => '袎',
  '��' => '覂',
  '��' => '觖',
  '��' => '觙',
  '��' => '觕',
  '��' => '訰',
  '��' => '訧',
  '��' => '訬',
  '��' => '訞',
  '��' => '谹',
  '��' => '谻',
  '��' => '豜',
  '��' => '豝',
  '��' => '豽',
  '��' => '貥',
  '��' => '赽',
  '��' => '赻',
  '��' => '赹',
  '��' => '趼',
  '��' => '跂',
  '��' => '趹',
  '��' => '趿',
  '��' => '跁',
  '��' => '軘',
  '��' => '軞',
  '��' => '軝',
  '��' => '軜',
  '��' => '軗',
  '��' => '軠',
  '��' => '軡',
  '��' => '逤',
  '��' => '逋',
  '��' => '逑',
  '��' => '逜',
  '��' => '逌',
  '��' => '逡',
  '��' => '郯',
  '��' => '郪',
  '��' => '郰',
  '��' => '郴',
  '��' => '郲',
  '��' => '郳',
  '��' => '郔',
  '��' => '郫',
  '��' => '郬',
  '��' => '郩',
  '��' => '酖',
  '��' => '酘',
  '��' => '酚',
  '�' => '酓',
  '�' => '酕',
  '�' => '釬',
  '�' => '釴',
  '�' => '釱',
  '�' => '釳',
  '�' => '釸',
  '�' => '釤',
  '�' => '釹',
  '�' => '釪',
  '�@' => '釫',
  '�A' => '釷',
  '�B' => '釨',
  '�C' => '釮',
  '�D' => '镺',
  '�E' => '閆',
  '�F' => '閈',
  '�G' => '陼',
  '�H' => '陭',
  '�I' => '陫',
  '�J' => '陱',
  '�K' => '陯',
  '�L' => '隿',
  '�M' => '靪',
  '�N' => '頄',
  '�O' => '飥',
  '�P' => '馗',
  '�Q' => '傛',
  '�R' => '傕',
  '�S' => '傔',
  '�T' => '傞',
  '�U' => '傋',
  '�V' => '傣',
  '�W' => '傃',
  '�X' => '傌',
  '�Y' => '傎',
  '�Z' => '傝',
  '�[' => '偨',
  '�\\' => '傜',
  '�]' => '傒',
  '�^' => '傂',
  '�_' => '傇',
  '�`' => '兟',
  '�a' => '凔',
  '�b' => '匒',
  '�c' => '匑',
  '�d' => '厤',
  '�e' => '厧',
  '�f' => '喑',
  '�g' => '喨',
  '�h' => '喥',
  '�i' => '喭',
  '�j' => '啷',
  '�k' => '噅',
  '�l' => '喢',
  '�m' => '喓',
  '�n' => '喈',
  '�o' => '喏',
  '�p' => '喵',
  '�q' => '喁',
  '�r' => '喣',
  '�s' => '喒',
  '�t' => '喤',
  '�u' => '啽',
  '�v' => '喌',
  '�w' => '喦',
  '�x' => '啿',
  '�y' => '喕',
  '�z' => '喡',
  '�{' => '喎',
  '�|' => '圌',
  '�}' => '堩',
  '�~' => '堷',
  'ء' => '堙',
  'آ' => '堞',
  'أ' => '堧',
  'ؤ' => '堣',
  'إ' => '堨',
  'ئ' => '埵',
  'ا' => '塈',
  'ب' => '堥',
  'ة' => '堜',
  'ت' => '堛',
  'ث' => '堳',
  'ج' => '堿',
  'ح' => '堶',
  'خ' => '堮',
  'د' => '堹',
  'ذ' => '堸',
  'ر' => '堭',
  'ز' => '堬',
  'س' => '堻',
  'ش' => '奡',
  'ص' => '媯',
  'ض' => '媔',
  'ط' => '媟',
  'ظ' => '婺',
  'ع' => '媢',
  'غ' => '媞',
  'ػ' => '婸',
  'ؼ' => '媦',
  'ؽ' => '婼',
  'ؾ' => '媥',
  'ؿ' => '媬',
  '�' => '媕',
  '�' => '媮',
  '��' => '娷',
  '��' => '媄',
  '��' => '媊',
  '��' => '媗',
  '��' => '媃',
  '��' => '媋',
  '��' => '媩',
  '��' => '婻',
  '��' => '婽',
  '��' => '媌',
  '��' => '媜',
  '��' => '媏',
  '��' => '媓',
  '��' => '媝',
  '��' => '寪',
  '��' => '寍',
  '��' => '寋',
  '��' => '寔',
  '��' => '寑',
  '��' => '寊',
  '��' => '寎',
  '��' => '尌',
  '��' => '尰',
  '��' => '崷',
  '��' => '嵃',
  '��' => '嵫',
  '��' => '嵁',
  '��' => '嵋',
  '��' => '崿',
  '��' => '崵',
  '��' => '嵑',
  '��' => '嵎',
  '��' => '嵕',
  '��' => '崳',
  '��' => '崺',
  '��' => '嵒',
  '��' => '崽',
  '��' => '崱',
  '��' => '嵙',
  '��' => '嵂',
  '��' => '崹',
  '��' => '嵉',
  '��' => '崸',
  '��' => '崼',
  '��' => '崲',
  '��' => '崶',
  '��' => '嵀',
  '��' => '嵅',
  '��' => '幄',
  '��' => '幁',
  '��' => '彘',
  '�' => '徦',
  '�' => '徥',
  '�' => '徫',
  '�' => '惉',
  '�' => '悹',
  '�' => '惌',
  '�' => '惢',
  '�' => '惎',
  '�' => '惄',
  '�' => '愔',
  '�@' => '惲',
  '�A' => '愊',
  '�B' => '愖',
  '�C' => '愅',
  '�D' => '惵',
  '�E' => '愓',
  '�F' => '惸',
  '�G' => '惼',
  '�H' => '惾',
  '�I' => '惁',
  '�J' => '愃',
  '�K' => '愘',
  '�L' => '愝',
  '�M' => '愐',
  '�N' => '惿',
  '�O' => '愄',
  '�P' => '愋',
  '�Q' => '扊',
  '�R' => '掔',
  '�S' => '掱',
  '�T' => '掰',
  '�U' => '揎',
  '�V' => '揥',
  '�W' => '揨',
  '�X' => '揯',
  '�Y' => '揃',
  '�Z' => '撝',
  '�[' => '揳',
  '�\\' => '揊',
  '�]' => '揠',
  '�^' => '揶',
  '�_' => '揕',
  '�`' => '揲',
  '�a' => '揵',
  '�b' => '摡',
  '�c' => '揟',
  '�d' => '掾',
  '�e' => '揝',
  '�f' => '揜',
  '�g' => '揄',
  '�h' => '揘',
  '�i' => '揓',
  '�j' => '揂',
  '�k' => '揇',
  '�l' => '揌',
  '�m' => '揋',
  '�n' => '揈',
  '�o' => '揰',
  '�p' => '揗',
  '�q' => '揙',
  '�r' => '攲',
  '�s' => '敧',
  '�t' => '敪',
  '�u' => '敤',
  '�v' => '敜',
  '�w' => '敨',
  '�x' => '敥',
  '�y' => '斌',
  '�z' => '斝',
  '�{' => '斞',
  '�|' => '斮',
  '�}' => '旐',
  '�~' => '旒',
  '١' => '晼',
  '٢' => '晬',
  '٣' => '晻',
  '٤' => '暀',
  '٥' => '晱',
  '٦' => '晹',
  '٧' => '晪',
  '٨' => '晲',
  '٩' => '朁',
  '٪' => '椌',
  '٫' => '棓',
  '٬' => '椄',
  '٭' => '棜',
  'ٮ' => '椪',
  'ٯ' => '棬',
  'ٰ' => '棪',
  'ٱ' => '棱',
  'ٲ' => '椏',
  'ٳ' => '棖',
  'ٴ' => '棷',
  'ٵ' => '棫',
  'ٶ' => '棤',
  'ٷ' => '棶',
  'ٸ' => '椓',
  'ٹ' => '椐',
  'ٺ' => '棳',
  'ٻ' => '棡',
  'ټ' => '椇',
  'ٽ' => '棌',
  'پ' => '椈',
  'ٿ' => '楰',
  '�' => '梴',
  '�' => '椑',
  '��' => '棯',
  '��' => '棆',
  '��' => '椔',
  '��' => '棸',
  '��' => '棐',
  '��' => '棽',
  '��' => '棼',
  '��' => '棨',
  '��' => '椋',
  '��' => '椊',
  '��' => '椗',
  '��' => '棎',
  '��' => '棈',
  '��' => '棝',
  '��' => '棞',
  '��' => '棦',
  '��' => '棴',
  '��' => '棑',
  '��' => '椆',
  '��' => '棔',
  '��' => '棩',
  '��' => '椕',
  '��' => '椥',
  '��' => '棇',
  '��' => '欹',
  '��' => '欻',
  '��' => '欿',
  '��' => '欼',
  '��' => '殔',
  '��' => '殗',
  '��' => '殙',
  '��' => '殕',
  '��' => '殽',
  '��' => '毰',
  '��' => '毲',
  '��' => '毳',
  '��' => '氰',
  '��' => '淼',
  '��' => '湆',
  '��' => '湇',
  '��' => '渟',
  '��' => '湉',
  '��' => '溈',
  '��' => '渼',
  '��' => '渽',
  '��' => '湅',
  '��' => '湢',
  '��' => '渫',
  '��' => '渿',
  '��' => '湁',
  '��' => '湝',
  '�' => '湳',
  '�' => '渜',
  '�' => '渳',
  '�' => '湋',
  '�' => '湀',
  '�' => '湑',
  '�' => '渻',
  '�' => '渃',
  '�' => '渮',
  '�' => '湞',
  '�@' => '湨',
  '�A' => '湜',
  '�B' => '湡',
  '�C' => '渱',
  '�D' => '渨',
  '�E' => '湠',
  '�F' => '湱',
  '�G' => '湫',
  '�H' => '渹',
  '�I' => '渢',
  '�J' => '渰',
  '�K' => '湓',
  '�L' => '湥',
  '�M' => '渧',
  '�N' => '湸',
  '�O' => '湤',
  '�P' => '湷',
  '�Q' => '湕',
  '�R' => '湹',
  '�S' => '湒',
  '�T' => '湦',
  '�U' => '渵',
  '�V' => '渶',
  '�W' => '湚',
  '�X' => '焠',
  '�Y' => '焞',
  '�Z' => '焯',
  '�[' => '烻',
  '�\\' => '焮',
  '�]' => '焱',
  '�^' => '焣',
  '�_' => '焥',
  '�`' => '焢',
  '�a' => '焲',
  '�b' => '焟',
  '�c' => '焨',
  '�d' => '焺',
  '�e' => '焛',
  '�f' => '牋',
  '�g' => '牚',
  '�h' => '犈',
  '�i' => '犉',
  '�j' => '犆',
  '�k' => '犅',
  '�l' => '犋',
  '�m' => '猒',
  '�n' => '猋',
  '�o' => '猰',
  '�p' => '猢',
  '�q' => '猱',
  '�r' => '猳',
  '�s' => '猧',
  '�t' => '猲',
  '�u' => '猭',
  '�v' => '猦',
  '�w' => '猣',
  '�x' => '猵',
  '�y' => '猌',
  '�z' => '琮',
  '�{' => '琬',
  '�|' => '琰',
  '�}' => '琫',
  '�~' => '琖',
  'ڡ' => '琚',
  'ڢ' => '琡',
  'ڣ' => '琭',
  'ڤ' => '琱',
  'ڥ' => '琤',
  'ڦ' => '琣',
  'ڧ' => '琝',
  'ڨ' => '琩',
  'ک' => '琠',
  'ڪ' => '琲',
  'ګ' => '瓻',
  'ڬ' => '甯',
  'ڭ' => '畯',
  'ڮ' => '畬',
  'گ' => '痧',
  'ڰ' => '痚',
  'ڱ' => '痡',
  'ڲ' => '痦',
  'ڳ' => '痝',
  'ڴ' => '痟',
  'ڵ' => '痤',
  'ڶ' => '痗',
  'ڷ' => '皕',
  'ڸ' => '皒',
  'ڹ' => '盚',
  'ں' => '睆',
  'ڻ' => '睇',
  'ڼ' => '睄',
  'ڽ' => '睍',
  'ھ' => '睅',
  'ڿ' => '睊',
  '�' => '睎',
  '�' => '睋',
  '��' => '睌',
  '��' => '矞',
  '��' => '矬',
  '��' => '硠',
  '��' => '硤',
  '��' => '硥',
  '��' => '硜',
  '��' => '硭',
  '��' => '硱',
  '��' => '硪',
  '��' => '确',
  '��' => '硰',
  '��' => '硩',
  '��' => '硨',
  '��' => '硞',
  '��' => '硢',
  '��' => '祴',
  '��' => '祳',
  '��' => '祲',
  '��' => '祰',
  '��' => '稂',
  '��' => '稊',
  '��' => '稃',
  '��' => '稌',
  '��' => '稄',
  '��' => '窙',
  '��' => '竦',
  '��' => '竤',
  '��' => '筊',
  '��' => '笻',
  '��' => '筄',
  '��' => '筈',
  '��' => '筌',
  '��' => '筎',
  '��' => '筀',
  '��' => '筘',
  '��' => '筅',
  '��' => '粢',
  '��' => '粞',
  '��' => '粨',
  '��' => '粡',
  '��' => '絘',
  '��' => '絯',
  '��' => '絣',
  '��' => '絓',
  '��' => '絖',
  '��' => '絧',
  '��' => '絪',
  '��' => '絏',
  '��' => '絭',
  '��' => '絜',
  '�' => '絫',
  '�' => '絒',
  '�' => '絔',
  '�' => '絩',
  '�' => '絑',
  '�' => '絟',
  '�' => '絎',
  '�' => '缾',
  '�' => '缿',
  '�' => '罥',
  '�@' => '罦',
  '�A' => '羢',
  '�B' => '羠',
  '�C' => '羡',
  '�D' => '翗',
  '�E' => '聑',
  '�F' => '聏',
  '�G' => '聐',
  '�H' => '胾',
  '�I' => '胔',
  '�J' => '腃',
  '�K' => '腊',
  '�L' => '腒',
  '�M' => '腏',
  '�N' => '腇',
  '�O' => '脽',
  '�P' => '腍',
  '�Q' => '脺',
  '�R' => '臦',
  '�S' => '臮',
  '�T' => '臷',
  '�U' => '臸',
  '�V' => '臹',
  '�W' => '舄',
  '�X' => '舼',
  '�Y' => '舽',
  '�Z' => '舿',
  '�[' => '艵',
  '�\\' => '茻',
  '�]' => '菏',
  '�^' => '菹',
  '�_' => '萣',
  '�`' => '菀',
  '�a' => '菨',
  '�b' => '萒',
  '�c' => '菧',
  '�d' => '菤',
  '�e' => '菼',
  '�f' => '菶',
  '�g' => '萐',
  '�h' => '菆',
  '�i' => '菈',
  '�j' => '菫',
  '�k' => '菣',
  '�l' => '莿',
  '�m' => '萁',
  '�n' => '菝',
  '�o' => '菥',
  '�p' => '菘',
  '�q' => '菿',
  '�r' => '菡',
  '�s' => '菋',
  '�t' => '菎',
  '�u' => '菖',
  '�v' => '菵',
  '�w' => '菉',
  '�x' => '萉',
  '�y' => '萏',
  '�z' => '菞',
  '�{' => '萑',
  '�|' => '萆',
  '�}' => '菂',
  '�~' => '菳',
  'ۡ' => '菕',
  'ۢ' => '菺',
  'ۣ' => '菇',
  'ۤ' => '菑',
  'ۥ' => '菪',
  'ۦ' => '萓',
  'ۧ' => '菃',
  'ۨ' => '菬',
  '۩' => '菮',
  '۪' => '菄',
  '۫' => '菻',
  '۬' => '菗',
  'ۭ' => '菢',
  'ۮ' => '萛',
  'ۯ' => '菛',
  '۰' => '菾',
  '۱' => '蛘',
  '۲' => '蛢',
  '۳' => '蛦',
  '۴' => '蛓',
  '۵' => '蛣',
  '۶' => '蛚',
  '۷' => '蛪',
  '۸' => '蛝',
  '۹' => '蛫',
  'ۺ' => '蛜',
  'ۻ' => '蛬',
  'ۼ' => '蛩',
  '۽' => '蛗',
  '۾' => '蛨',
  'ۿ' => '蛑',
  '�' => '衈',
  '�' => '衖',
  '��' => '衕',
  '��' => '袺',
  '��' => '裗',
  '��' => '袹',
  '��' => '袸',
  '��' => '裀',
  '��' => '袾',
  '��' => '袶',
  '��' => '袼',
  '��' => '袷',
  '��' => '袽',
  '��' => '袲',
  '��' => '褁',
  '��' => '裉',
  '��' => '覕',
  '��' => '覘',
  '��' => '覗',
  '��' => '觝',
  '��' => '觚',
  '��' => '觛',
  '��' => '詎',
  '��' => '詍',
  '��' => '訹',
  '��' => '詙',
  '��' => '詀',
  '��' => '詗',
  '��' => '詘',
  '��' => '詄',
  '��' => '詅',
  '��' => '詒',
  '��' => '詈',
  '��' => '詑',
  '��' => '詊',
  '��' => '詌',
  '��' => '詏',
  '��' => '豟',
  '��' => '貁',
  '��' => '貀',
  '��' => '貺',
  '��' => '貾',
  '��' => '貰',
  '��' => '貹',
  '��' => '貵',
  '��' => '趄',
  '��' => '趀',
  '��' => '趉',
  '��' => '跘',
  '��' => '跓',
  '��' => '跍',
  '��' => '跇',
  '��' => '跖',
  '�' => '跜',
  '�' => '跏',
  '�' => '跕',
  '�' => '跙',
  '�' => '跈',
  '�' => '跗',
  '�' => '跅',
  '�' => '軯',
  '�' => '軷',
  '�' => '軺',
  '�@' => '軹',
  '�A' => '軦',
  '�B' => '軮',
  '�C' => '軥',
  '�D' => '軵',
  '�E' => '軧',
  '�F' => '軨',
  '�G' => '軶',
  '�H' => '軫',
  '�I' => '軱',
  '�J' => '軬',
  '�K' => '軴',
  '�L' => '軩',
  '�M' => '逭',
  '�N' => '逴',
  '�O' => '逯',
  '�P' => '鄆',
  '�Q' => '鄬',
  '�R' => '鄄',
  '�S' => '郿',
  '�T' => '郼',
  '�U' => '鄈',
  '�V' => '郹',
  '�W' => '郻',
  '�X' => '鄁',
  '�Y' => '鄀',
  '�Z' => '鄇',
  '�[' => '鄅',
  '�\\' => '鄃',
  '�]' => '酡',
  '�^' => '酤',
  '�_' => '酟',
  '�`' => '酢',
  '�a' => '酠',
  '�b' => '鈁',
  '�c' => '鈊',
  '�d' => '鈥',
  '�e' => '鈃',
  '�f' => '鈚',
  '�g' => '鈦',
  '�h' => '鈏',
  '�i' => '鈌',
  '�j' => '鈀',
  '�k' => '鈒',
  '�l' => '釿',
  '�m' => '釽',
  '�n' => '鈆',
  '�o' => '鈄',
  '�p' => '鈧',
  '�q' => '鈂',
  '�r' => '鈜',
  '�s' => '鈤',
  '�t' => '鈙',
  '�u' => '鈗',
  '�v' => '鈅',
  '�w' => '鈖',
  '�x' => '镻',
  '�y' => '閍',
  '�z' => '閌',
  '�{' => '閐',
  '�|' => '隇',
  '�}' => '陾',
  '�~' => '隈',
  'ܡ' => '隉',
  'ܢ' => '隃',
  'ܣ' => '隀',
  'ܤ' => '雂',
  'ܥ' => '雈',
  'ܦ' => '雃',
  'ܧ' => '雱',
  'ܨ' => '雰',
  'ܩ' => '靬',
  'ܪ' => '靰',
  'ܫ' => '靮',
  'ܬ' => '頇',
  'ܭ' => '颩',
  'ܮ' => '飫',
  'ܯ' => '鳦',
  'ܰ' => '黹',
  'ܱ' => '亃',
  'ܲ' => '亄',
  'ܳ' => '亶',
  'ܴ' => '傽',
  'ܵ' => '傿',
  'ܶ' => '僆',
  'ܷ' => '傮',
  'ܸ' => '僄',
  'ܹ' => '僊',
  'ܺ' => '傴',
  'ܻ' => '僈',
  'ܼ' => '僂',
  'ܽ' => '傰',
  'ܾ' => '僁',
  'ܿ' => '傺',
  '�' => '傱',
  '�' => '僋',
  '��' => '僉',
  '��' => '傶',
  '��' => '傸',
  '��' => '凗',
  '��' => '剺',
  '��' => '剸',
  '��' => '剻',
  '��' => '剼',
  '��' => '嗃',
  '��' => '嗛',
  '��' => '嗌',
  '��' => '嗐',
  '��' => '嗋',
  '��' => '嗊',
  '��' => '嗝',
  '��' => '嗀',
  '��' => '嗔',
  '��' => '嗄',
  '��' => '嗩',
  '��' => '喿',
  '��' => '嗒',
  '��' => '喍',
  '��' => '嗏',
  '��' => '嗕',
  '��' => '嗢',
  '��' => '嗖',
  '��' => '嗈',
  '��' => '嗲',
  '��' => '嗍',
  '��' => '嗙',
  '��' => '嗂',
  '��' => '圔',
  '��' => '塓',
  '��' => '塨',
  '��' => '塤',
  '��' => '塏',
  '��' => '塍',
  '��' => '塉',
  '��' => '塯',
  '��' => '塕',
  '��' => '塎',
  '��' => '塝',
  '��' => '塙',
  '��' => '塥',
  '��' => '塛',
  '��' => '堽',
  '��' => '塣',
  '��' => '塱',
  '��' => '壼',
  '��' => '嫇',
  '��' => '嫄',
  '�' => '嫋',
  '�' => '媺',
  '�' => '媸',
  '�' => '媱',
  '�' => '媵',
  '�' => '媰',
  '�' => '媿',
  '�' => '嫈',
  '�' => '媻',
  '�' => '嫆',
  '�@' => '媷',
  '�A' => '嫀',
  '�B' => '嫊',
  '�C' => '媴',
  '�D' => '媶',
  '�E' => '嫍',
  '�F' => '媹',
  '�G' => '媐',
  '�H' => '寖',
  '�I' => '寘',
  '�J' => '寙',
  '�K' => '尟',
  '�L' => '尳',
  '�M' => '嵱',
  '�N' => '嵣',
  '�O' => '嵊',
  '�P' => '嵥',
  '�Q' => '嵲',
  '�R' => '嵬',
  '�S' => '嵞',
  '�T' => '嵨',
  '�U' => '嵧',
  '�V' => '嵢',
  '�W' => '巰',
  '�X' => '幏',
  '�Y' => '幎',
  '�Z' => '幊',
  '�[' => '幍',
  '�\\' => '幋',
  '�]' => '廅',
  '�^' => '廌',
  '�_' => '廆',
  '�`' => '廋',
  '�a' => '廇',
  '�b' => '彀',
  '�c' => '徯',
  '�d' => '徭',
  '�e' => '惷',
  '�f' => '慉',
  '�g' => '慊',
  '�h' => '愫',
  '�i' => '慅',
  '�j' => '愶',
  '�k' => '愲',
  '�l' => '愮',
  '�m' => '慆',
  '�n' => '愯',
  '�o' => '慏',
  '�p' => '愩',
  '�q' => '慀',
  '�r' => '戠',
  '�s' => '酨',
  '�t' => '戣',
  '�u' => '戥',
  '�v' => '戤',
  '�w' => '揅',
  '�x' => '揱',
  '�y' => '揫',
  '�z' => '搐',
  '�{' => '搒',
  '�|' => '搉',
  '�}' => '搠',
  '�~' => '搤',
  'ݡ' => '搳',
  'ݢ' => '摃',
  'ݣ' => '搟',
  'ݤ' => '搕',
  'ݥ' => '搘',
  'ݦ' => '搹',
  'ݧ' => '搷',
  'ݨ' => '搢',
  'ݩ' => '搣',
  'ݪ' => '搌',
  'ݫ' => '搦',
  'ݬ' => '搰',
  'ݭ' => '搨',
  'ݮ' => '摁',
  'ݯ' => '搵',
  'ݰ' => '搯',
  'ݱ' => '搊',
  'ݲ' => '搚',
  'ݳ' => '摀',
  'ݴ' => '搥',
  'ݵ' => '搧',
  'ݶ' => '搋',
  'ݷ' => '揧',
  'ݸ' => '搛',
  'ݹ' => '搮',
  'ݺ' => '搡',
  'ݻ' => '搎',
  'ݼ' => '敯',
  'ݽ' => '斒',
  'ݾ' => '旓',
  'ݿ' => '暆',
  '�' => '暌',
  '�' => '暕',
  '��' => '暐',
  '��' => '暋',
  '��' => '暊',
  '��' => '暙',
  '��' => '暔',
  '��' => '晸',
  '��' => '朠',
  '��' => '楦',
  '��' => '楟',
  '��' => '椸',
  '��' => '楎',
  '��' => '楢',
  '��' => '楱',
  '��' => '椿',
  '��' => '楅',
  '��' => '楪',
  '��' => '椹',
  '��' => '楂',
  '��' => '楗',
  '��' => '楙',
  '��' => '楺',
  '��' => '楈',
  '��' => '楉',
  '��' => '椵',
  '��' => '楬',
  '��' => '椳',
  '��' => '椽',
  '��' => '楥',
  '��' => '棰',
  '��' => '楸',
  '��' => '椴',
  '��' => '楩',
  '��' => '楀',
  '��' => '楯',
  '��' => '楄',
  '��' => '楶',
  '��' => '楘',
  '��' => '楁',
  '��' => '楴',
  '��' => '楌',
  '��' => '椻',
  '��' => '楋',
  '��' => '椷',
  '��' => '楜',
  '��' => '楏',
  '��' => '楑',
  '��' => '椲',
  '��' => '楒',
  '��' => '椯',
  '��' => '楻',
  '��' => '椼',
  '�' => '歆',
  '�' => '歅',
  '�' => '歃',
  '�' => '歂',
  '�' => '歈',
  '�' => '歁',
  '�' => '殛',
  '�' => '嗀',
  '�' => '毻',
  '�' => '毼',
  '�@' => '毹',
  '�A' => '毷',
  '�B' => '毸',
  '�C' => '溛',
  '�D' => '滖',
  '�E' => '滈',
  '�F' => '溏',
  '�G' => '滀',
  '�H' => '溟',
  '�I' => '溓',
  '�J' => '溔',
  '�K' => '溠',
  '�L' => '溱',
  '�M' => '溹',
  '�N' => '滆',
  '�O' => '滒',
  '�P' => '溽',
  '�Q' => '滁',
  '�R' => '溞',
  '�S' => '滉',
  '�T' => '溷',
  '�U' => '溰',
  '�V' => '滍',
  '�W' => '溦',
  '�X' => '滏',
  '�Y' => '溲',
  '�Z' => '溾',
  '�[' => '滃',
  '�\\' => '滜',
  '�]' => '滘',
  '�^' => '溙',
  '�_' => '溒',
  '�`' => '溎',
  '�a' => '溍',
  '�b' => '溤',
  '�c' => '溡',
  '�d' => '溿',
  '�e' => '溳',
  '�f' => '滐',
  '�g' => '滊',
  '�h' => '溗',
  '�i' => '溮',
  '�j' => '溣',
  '�k' => '煇',
  '�l' => '煔',
  '�m' => '煒',
  '�n' => '煣',
  '�o' => '煠',
  '�p' => '煁',
  '�q' => '煝',
  '�r' => '煢',
  '�s' => '煲',
  '�t' => '煸',
  '�u' => '煪',
  '�v' => '煡',
  '�w' => '煂',
  '�x' => '煘',
  '�y' => '煃',
  '�z' => '煋',
  '�{' => '煰',
  '�|' => '煟',
  '�}' => '煐',
  '�~' => '煓',
  'ޡ' => '煄',
  'ޢ' => '煍',
  'ޣ' => '煚',
  'ޤ' => '牏',
  'ޥ' => '犍',
  'ަ' => '犌',
  'ާ' => '犑',
  'ި' => '犐',
  'ީ' => '犎',
  'ު' => '猼',
  'ޫ' => '獂',
  'ެ' => '猻',
  'ޭ' => '猺',
  'ޮ' => '獀',
  'ޯ' => '獊',
  'ް' => '獉',
  'ޱ' => '瑄',
  '޲' => '瑊',
  '޳' => '瑋',
  '޴' => '瑒',
  '޵' => '瑑',
  '޶' => '瑗',
  '޷' => '瑀',
  '޸' => '瑏',
  '޹' => '瑐',
  '޺' => '瑎',
  '޻' => '瑂',
  '޼' => '瑆',
  '޽' => '瑍',
  '޾' => '瑔',
  '޿' => '瓡',
  '�' => '瓿',
  '�' => '瓾',
  '��' => '瓽',
  '��' => '甝',
  '��' => '畹',
  '��' => '畷',
  '��' => '榃',
  '��' => '痯',
  '��' => '瘏',
  '��' => '瘃',
  '��' => '痷',
  '��' => '痾',
  '��' => '痼',
  '��' => '痹',
  '��' => '痸',
  '��' => '瘐',
  '��' => '痻',
  '��' => '痶',
  '��' => '痭',
  '��' => '痵',
  '��' => '痽',
  '��' => '皙',
  '��' => '皵',
  '��' => '盝',
  '��' => '睕',
  '��' => '睟',
  '��' => '睠',
  '��' => '睒',
  '��' => '睖',
  '��' => '睚',
  '��' => '睩',
  '��' => '睧',
  '��' => '睔',
  '��' => '睙',
  '��' => '睭',
  '��' => '矠',
  '��' => '碇',
  '��' => '碚',
  '��' => '碔',
  '��' => '碏',
  '��' => '碄',
  '��' => '碕',
  '��' => '碅',
  '��' => '碆',
  '��' => '碡',
  '��' => '碃',
  '��' => '硹',
  '��' => '碙',
  '��' => '碀',
  '��' => '碖',
  '��' => '硻',
  '��' => '祼',
  '��' => '禂',
  '�' => '祽',
  '�' => '祹',
  '�' => '稑',
  '�' => '稘',
  '�' => '稙',
  '�' => '稒',
  '�' => '稗',
  '�' => '稕',
  '�' => '稢',
  '�' => '稓',
  '�@' => '稛',
  '�A' => '稐',
  '�B' => '窣',
  '�C' => '窢',
  '�D' => '窞',
  '�E' => '竫',
  '�F' => '筦',
  '�G' => '筤',
  '�H' => '筭',
  '�I' => '筴',
  '�J' => '筩',
  '�K' => '筲',
  '�L' => '筥',
  '�M' => '筳',
  '�N' => '筱',
  '�O' => '筰',
  '�P' => '筡',
  '�Q' => '筸',
  '�R' => '筶',
  '�S' => '筣',
  '�T' => '粲',
  '�U' => '粴',
  '�V' => '粯',
  '�W' => '綈',
  '�X' => '綆',
  '�Y' => '綀',
  '�Z' => '綍',
  '�[' => '絿',
  '�\\' => '綅',
  '�]' => '絺',
  '�^' => '綎',
  '�_' => '絻',
  '�`' => '綃',
  '�a' => '絼',
  '�b' => '綌',
  '�c' => '綔',
  '�d' => '綄',
  '�e' => '絽',
  '�f' => '綒',
  '�g' => '罭',
  '�h' => '罫',
  '�i' => '罧',
  '�j' => '罨',
  '�k' => '罬',
  '�l' => '羦',
  '�m' => '羥',
  '�n' => '羧',
  '�o' => '翛',
  '�p' => '翜',
  '�q' => '耡',
  '�r' => '腤',
  '�s' => '腠',
  '�t' => '腷',
  '�u' => '腜',
  '�v' => '腩',
  '�w' => '腛',
  '�x' => '腢',
  '�y' => '腲',
  '�z' => '朡',
  '�{' => '腞',
  '�|' => '腶',
  '�}' => '腧',
  '�~' => '腯',
  'ߡ' => '腄',
  'ߢ' => '腡',
  'ߣ' => '舝',
  'ߤ' => '艉',
  'ߥ' => '艄',
  'ߦ' => '艀',
  'ߧ' => '艂',
  'ߨ' => '艅',
  'ߩ' => '蓱',
  'ߪ' => '萿',
  '߫' => '葖',
  '߬' => '葶',
  '߭' => '葹',
  '߮' => '蒏',
  '߯' => '蒍',
  '߰' => '葥',
  '߱' => '葑',
  '߲' => '葀',
  '߳' => '蒆',
  'ߴ' => '葧',
  'ߵ' => '萰',
  '߶' => '葍',
  '߷' => '葽',
  '߸' => '葚',
  '߹' => '葙',
  'ߺ' => '葴',
  '߻' => '葳',
  '߼' => '葝',
  '߽' => '蔇',
  '߾' => '葞',
  '߿' => '萷',
  '�' => '萺',
  '�' => '萴',
  '��' => '葺',
  '��' => '葃',
  '��' => '葸',
  '��' => '萲',
  '��' => '葅',
  '��' => '萩',
  '��' => '菙',
  '��' => '葋',
  '��' => '萯',
  '��' => '葂',
  '��' => '萭',
  '��' => '葟',
  '��' => '葰',
  '��' => '萹',
  '��' => '葎',
  '��' => '葌',
  '��' => '葒',
  '��' => '葯',
  '��' => '蓅',
  '��' => '蒎',
  '��' => '萻',
  '��' => '葇',
  '��' => '萶',
  '��' => '萳',
  '��' => '葨',
  '��' => '葾',
  '��' => '葄',
  '��' => '萫',
  '��' => '葠',
  '��' => '葔',
  '��' => '葮',
  '��' => '葐',
  '��' => '蜋',
  '��' => '蜄',
  '��' => '蛷',
  '��' => '蜌',
  '��' => '蛺',
  '��' => '蛖',
  '��' => '蛵',
  '��' => '蝍',
  '��' => '蛸',
  '��' => '蜎',
  '��' => '蜉',
  '��' => '蜁',
  '��' => '蛶',
  '��' => '蜍',
  '��' => '蜅',
  '��' => '裖',
  '��' => '裋',
  '��' => '裍',
  '��' => '裎',
  '�' => '裞',
  '�' => '裛',
  '�' => '裚',
  '�' => '裌',
  '�' => '裐',
  '�' => '覅',
  '�' => '覛',
  '�' => '觟',
  '�' => '觥',
  '�' => '觤',
  '�@' => '觡',
  '�A' => '觠',
  '�B' => '觢',
  '�C' => '觜',
  '�D' => '触',
  '�E' => '詶',
  '�F' => '誆',
  '�G' => '詿',
  '�H' => '詡',
  '�I' => '訿',
  '�J' => '詷',
  '�K' => '誂',
  '�L' => '誄',
  '�M' => '詵',
  '�N' => '誃',
  '�O' => '誁',
  '�P' => '詴',
  '�Q' => '詺',
  '�R' => '谼',
  '�S' => '豋',
  '�T' => '豊',
  '�U' => '豥',
  '�V' => '豤',
  '�W' => '豦',
  '�X' => '貆',
  '�Y' => '貄',
  '�Z' => '貅',
  '�[' => '賌',
  '�\\' => '赨',
  '�]' => '赩',
  '�^' => '趑',
  '�_' => '趌',
  '�`' => '趎',
  '�a' => '趏',
  '�b' => '趍',
  '�c' => '趓',
  '�d' => '趔',
  '�e' => '趐',
  '�f' => '趒',
  '�g' => '跰',
  '�h' => '跠',
  '�i' => '跬',
  '�j' => '跱',
  '�k' => '跮',
  '�l' => '跐',
  '�m' => '跩',
  '�n' => '跣',
  '�o' => '跢',
  '�p' => '跧',
  '�q' => '跲',
  '�r' => '跫',
  '�s' => '跴',
  '�t' => '輆',
  '�u' => '軿',
  '�v' => '輁',
  '�w' => '輀',
  '�x' => '輅',
  '�y' => '輇',
  '�z' => '輈',
  '�{' => '輂',
  '�|' => '輋',
  '�}' => '遒',
  '�~' => '逿',
  '�' => '遄',
  '�' => '遉',
  '�' => '逽',
  '�' => '鄐',
  '�' => '鄍',
  '�' => '鄏',
  '�' => '鄑',
  '�' => '鄖',
  '�' => '鄔',
  '�' => '鄋',
  '�' => '鄎',
  '�' => '酮',
  '�' => '酯',
  '�' => '鉈',
  '�' => '鉒',
  '�' => '鈰',
  '�' => '鈺',
  '�' => '鉦',
  '�' => '鈳',
  '�' => '鉥',
  '�' => '鉞',
  '�' => '銃',
  '�' => '鈮',
  '�' => '鉊',
  '�' => '鉆',
  '�' => '鉭',
  '�' => '鉬',
  '�' => '鉏',
  '�' => '鉠',
  '�' => '鉧',
  '�' => '鉯',
  '�' => '鈶',
  '�' => '鉡',
  '��' => '鉰',
  '��' => '鈱',
  '��' => '鉔',
  '��' => '鉣',
  '��' => '鉐',
  '��' => '鉲',
  '��' => '鉎',
  '��' => '鉓',
  '��' => '鉌',
  '��' => '鉖',
  '��' => '鈲',
  '��' => '閟',
  '��' => '閜',
  '��' => '閞',
  '��' => '閛',
  '��' => '隒',
  '��' => '隓',
  '��' => '隑',
  '��' => '隗',
  '��' => '雎',
  '��' => '雺',
  '��' => '雽',
  '��' => '雸',
  '��' => '雵',
  '��' => '靳',
  '��' => '靷',
  '��' => '靸',
  '��' => '靲',
  '��' => '頏',
  '��' => '頍',
  '��' => '頎',
  '��' => '颬',
  '��' => '飶',
  '��' => '飹',
  '��' => '馯',
  '��' => '馲',
  '��' => '馰',
  '��' => '馵',
  '��' => '骭',
  '��' => '骫',
  '��' => '魛',
  '��' => '鳪',
  '��' => '鳭',
  '��' => '鳧',
  '��' => '麀',
  '��' => '黽',
  '��' => '僦',
  '��' => '僔',
  '��' => '僗',
  '��' => '僨',
  '��' => '僳',
  '�' => '僛',
  '�' => '僪',
  '�' => '僝',
  '�' => '僤',
  '�' => '僓',
  '�' => '僬',
  '�' => '僰',
  '�' => '僯',
  '�' => '僣',
  '�' => '僠',
  '�@' => '凘',
  '�A' => '劀',
  '�B' => '劁',
  '�C' => '勩',
  '�D' => '勫',
  '�E' => '匰',
  '�F' => '厬',
  '�G' => '嘧',
  '�H' => '嘕',
  '�I' => '嘌',
  '�J' => '嘒',
  '�K' => '嗼',
  '�L' => '嘏',
  '�M' => '嘜',
  '�N' => '嘁',
  '�O' => '嘓',
  '�P' => '嘂',
  '�Q' => '嗺',
  '�R' => '嘝',
  '�S' => '嘄',
  '�T' => '嗿',
  '�U' => '嗹',
  '�V' => '墉',
  '�W' => '塼',
  '�X' => '墐',
  '�Y' => '墘',
  '�Z' => '墆',
  '�[' => '墁',
  '�\\' => '塿',
  '�]' => '塴',
  '�^' => '墋',
  '�_' => '塺',
  '�`' => '墇',
  '�a' => '墑',
  '�b' => '墎',
  '�c' => '塶',
  '�d' => '墂',
  '�e' => '墈',
  '�f' => '塻',
  '�g' => '墔',
  '�h' => '墏',
  '�i' => '壾',
  '�j' => '奫',
  '�k' => '嫜',
  '�l' => '嫮',
  '�m' => '嫥',
  '�n' => '嫕',
  '�o' => '嫪',
  '�p' => '嫚',
  '�q' => '嫭',
  '�r' => '嫫',
  '�s' => '嫳',
  '�t' => '嫢',
  '�u' => '嫠',
  '�v' => '嫛',
  '�w' => '嫬',
  '�x' => '嫞',
  '�y' => '嫝',
  '�z' => '嫙',
  '�{' => '嫨',
  '�|' => '嫟',
  '�}' => '孷',
  '�~' => '寠',
  '�' => '寣',
  '�' => '屣',
  '�' => '嶂',
  '�' => '嶀',
  '�' => '嵽',
  '�' => '嶆',
  '�' => '嵺',
  '�' => '嶁',
  '�' => '嵷',
  '�' => '嶊',
  '�' => '嶉',
  '�' => '嶈',
  '�' => '嵾',
  '�' => '嵼',
  '�' => '嶍',
  '�' => '嵹',
  '�' => '嵿',
  '�' => '幘',
  '�' => '幙',
  '�' => '幓',
  '�' => '廘',
  '�' => '廑',
  '�' => '廗',
  '�' => '廎',
  '�' => '廜',
  '�' => '廕',
  '�' => '廙',
  '�' => '廒',
  '�' => '廔',
  '�' => '彄',
  '�' => '彃',
  '�' => '彯',
  '�' => '徶',
  '��' => '愬',
  '��' => '愨',
  '��' => '慁',
  '��' => '慞',
  '��' => '慱',
  '��' => '慳',
  '��' => '慒',
  '��' => '慓',
  '��' => '慲',
  '��' => '慬',
  '��' => '憀',
  '��' => '慴',
  '��' => '慔',
  '��' => '慺',
  '��' => '慛',
  '��' => '慥',
  '��' => '愻',
  '��' => '慪',
  '��' => '慡',
  '��' => '慖',
  '��' => '戩',
  '��' => '戧',
  '��' => '戫',
  '��' => '搫',
  '��' => '摍',
  '��' => '摛',
  '��' => '摝',
  '��' => '摴',
  '��' => '摶',
  '��' => '摲',
  '��' => '摳',
  '��' => '摽',
  '��' => '摵',
  '��' => '摦',
  '��' => '撦',
  '��' => '摎',
  '��' => '撂',
  '��' => '摞',
  '��' => '摜',
  '��' => '摋',
  '��' => '摓',
  '��' => '摠',
  '��' => '摐',
  '��' => '摿',
  '��' => '搿',
  '��' => '摬',
  '��' => '摫',
  '��' => '摙',
  '��' => '摥',
  '��' => '摷',
  '��' => '敳',
  '�' => '斠',
  '�' => '暡',
  '�' => '暠',
  '�' => '暟',
  '�' => '朅',
  '�' => '朄',
  '�' => '朢',
  '�' => '榱',
  '�' => '榶',
  '�' => '槉',
  '�@' => '榠',
  '�A' => '槎',
  '�B' => '榖',
  '�C' => '榰',
  '�D' => '榬',
  '�E' => '榼',
  '�F' => '榑',
  '�G' => '榙',
  '�H' => '榎',
  '�I' => '榧',
  '�J' => '榍',
  '�K' => '榩',
  '�L' => '榾',
  '�M' => '榯',
  '�N' => '榿',
  '�O' => '槄',
  '�P' => '榽',
  '�Q' => '榤',
  '�R' => '槔',
  '�S' => '榹',
  '�T' => '槊',
  '�U' => '榚',
  '�V' => '槏',
  '�W' => '榳',
  '�X' => '榓',
  '�Y' => '榪',
  '�Z' => '榡',
  '�[' => '榞',
  '�\\' => '槙',
  '�]' => '榗',
  '�^' => '榐',
  '�_' => '槂',
  '�`' => '榵',
  '�a' => '榥',
  '�b' => '槆',
  '�c' => '歊',
  '�d' => '歍',
  '�e' => '歋',
  '�f' => '殞',
  '�g' => '殟',
  '�h' => '殠',
  '�i' => '毃',
  '�j' => '毄',
  '�k' => '毾',
  '�l' => '滎',
  '�m' => '滵',
  '�n' => '滱',
  '�o' => '漃',
  '�p' => '漥',
  '�q' => '滸',
  '�r' => '漷',
  '�s' => '滻',
  '�t' => '漮',
  '�u' => '漉',
  '�v' => '潎',
  '�w' => '漙',
  '�x' => '漚',
  '�y' => '漧',
  '�z' => '漘',
  '�{' => '漻',
  '�|' => '漒',
  '�}' => '滭',
  '�~' => '漊',
  '�' => '漶',
  '�' => '潳',
  '�' => '滹',
  '�' => '滮',
  '�' => '漭',
  '�' => '潀',
  '�' => '漰',
  '�' => '漼',
  '�' => '漵',
  '�' => '滫',
  '�' => '漇',
  '�' => '漎',
  '�' => '潃',
  '�' => '漅',
  '�' => '滽',
  '�' => '滶',
  '�' => '漹',
  '�' => '漜',
  '�' => '滼',
  '�' => '漺',
  '�' => '漟',
  '�' => '漍',
  '�' => '漞',
  '�' => '漈',
  '�' => '漡',
  '�' => '熇',
  '�' => '熐',
  '�' => '熉',
  '�' => '熀',
  '�' => '熅',
  '�' => '熂',
  '�' => '熏',
  '�' => '煻',
  '��' => '熆',
  '��' => '熁',
  '��' => '熗',
  '��' => '牄',
  '��' => '牓',
  '��' => '犗',
  '��' => '犕',
  '��' => '犓',
  '��' => '獃',
  '��' => '獍',
  '��' => '獑',
  '��' => '獌',
  '��' => '瑢',
  '��' => '瑳',
  '��' => '瑱',
  '��' => '瑵',
  '��' => '瑲',
  '��' => '瑧',
  '��' => '瑮',
  '��' => '甀',
  '��' => '甂',
  '��' => '甃',
  '��' => '畽',
  '��' => '疐',
  '��' => '瘖',
  '��' => '瘈',
  '��' => '瘌',
  '��' => '瘕',
  '��' => '瘑',
  '��' => '瘊',
  '��' => '瘔',
  '��' => '皸',
  '��' => '瞁',
  '��' => '睼',
  '��' => '瞅',
  '��' => '瞂',
  '��' => '睮',
  '��' => '瞀',
  '��' => '睯',
  '��' => '睾',
  '��' => '瞃',
  '��' => '碲',
  '��' => '碪',
  '��' => '碴',
  '��' => '碭',
  '��' => '碨',
  '��' => '硾',
  '��' => '碫',
  '��' => '碞',
  '��' => '碥',
  '��' => '碠',
  '�' => '碬',
  '�' => '碢',
  '�' => '碤',
  '�' => '禘',
  '�' => '禊',
  '�' => '禋',
  '�' => '禖',
  '�' => '禕',
  '�' => '禔',
  '�' => '禓',
  '�@' => '禗',
  '�A' => '禈',
  '�B' => '禒',
  '�C' => '禐',
  '�D' => '稫',
  '�E' => '穊',
  '�F' => '稰',
  '�G' => '稯',
  '�H' => '稨',
  '�I' => '稦',
  '�J' => '窨',
  '�K' => '窫',
  '�L' => '窬',
  '�M' => '竮',
  '�N' => '箈',
  '�O' => '箜',
  '�P' => '箊',
  '�Q' => '箑',
  '�R' => '箐',
  '�S' => '箖',
  '�T' => '箍',
  '�U' => '箌',
  '�V' => '箛',
  '�W' => '箎',
  '�X' => '箅',
  '�Y' => '箘',
  '�Z' => '劄',
  '�[' => '箙',
  '�\\' => '箤',
  '�]' => '箂',
  '�^' => '粻',
  '�_' => '粿',
  '�`' => '粼',
  '�a' => '粺',
  '�b' => '綧',
  '�c' => '綷',
  '�d' => '緂',
  '�e' => '綣',
  '�f' => '綪',
  '�g' => '緁',
  '�h' => '緀',
  '�i' => '緅',
  '�j' => '綝',
  '�k' => '緎',
  '�l' => '緄',
  '�m' => '緆',
  '�n' => '緋',
  '�o' => '緌',
  '�p' => '綯',
  '�q' => '綹',
  '�r' => '綖',
  '�s' => '綼',
  '�t' => '綟',
  '�u' => '綦',
  '�v' => '綮',
  '�w' => '綩',
  '�x' => '綡',
  '�y' => '緉',
  '�z' => '罳',
  '�{' => '翢',
  '�|' => '翣',
  '�}' => '翥',
  '�~' => '翞',
  '�' => '耤',
  '�' => '聝',
  '�' => '聜',
  '�' => '膉',
  '�' => '膆',
  '�' => '膃',
  '�' => '膇',
  '�' => '膍',
  '�' => '膌',
  '�' => '膋',
  '�' => '舕',
  '�' => '蒗',
  '�' => '蒤',
  '�' => '蒡',
  '�' => '蒟',
  '�' => '蒺',
  '�' => '蓎',
  '�' => '蓂',
  '�' => '蒬',
  '�' => '蒮',
  '�' => '蒫',
  '�' => '蒹',
  '�' => '蒴',
  '�' => '蓁',
  '�' => '蓍',
  '�' => '蒪',
  '�' => '蒚',
  '�' => '蒱',
  '�' => '蓐',
  '�' => '蒝',
  '�' => '蒧',
  '�' => '蒻',
  '�' => '蒢',
  '��' => '蒔',
  '��' => '蓇',
  '��' => '蓌',
  '��' => '蒛',
  '��' => '蒩',
  '��' => '蒯',
  '��' => '蒨',
  '��' => '蓖',
  '��' => '蒘',
  '��' => '蒶',
  '��' => '蓏',
  '��' => '蒠',
  '��' => '蓗',
  '��' => '蓔',
  '��' => '蓒',
  '��' => '蓛',
  '��' => '蒰',
  '��' => '蒑',
  '��' => '虡',
  '��' => '蜳',
  '��' => '蜣',
  '��' => '蜨',
  '��' => '蝫',
  '��' => '蝀',
  '��' => '蜮',
  '��' => '蜞',
  '��' => '蜡',
  '��' => '蜙',
  '��' => '蜛',
  '��' => '蝃',
  '��' => '蜬',
  '��' => '蝁',
  '��' => '蜾',
  '��' => '蝆',
  '��' => '蜠',
  '��' => '蜲',
  '��' => '蜪',
  '��' => '蜭',
  '��' => '蜼',
  '��' => '蜒',
  '��' => '蜺',
  '��' => '蜱',
  '��' => '蜵',
  '��' => '蝂',
  '��' => '蜦',
  '��' => '蜧',
  '��' => '蜸',
  '��' => '蜤',
  '��' => '蜚',
  '��' => '蜰',
  '��' => '蜑',
  '�' => '裷',
  '�' => '裧',
  '�' => '裱',
  '�' => '裲',
  '�' => '裺',
  '�' => '裾',
  '�' => '裮',
  '�' => '裼',
  '�' => '裶',
  '�' => '裻',
  '�@' => '裰',
  '�A' => '裬',
  '�B' => '裫',
  '�C' => '覝',
  '�D' => '覡',
  '�E' => '覟',
  '�F' => '覞',
  '�G' => '觩',
  '�H' => '觫',
  '�I' => '觨',
  '�J' => '誫',
  '�K' => '誙',
  '�L' => '誋',
  '�M' => '誒',
  '�N' => '誏',
  '�O' => '誖',
  '�P' => '谽',
  '�Q' => '豨',
  '�R' => '豩',
  '�S' => '賕',
  '�T' => '賏',
  '�U' => '賗',
  '�V' => '趖',
  '�W' => '踉',
  '�X' => '踂',
  '�Y' => '跿',
  '�Z' => '踍',
  '�[' => '跽',
  '�\\' => '踊',
  '�]' => '踃',
  '�^' => '踇',
  '�_' => '踆',
  '�`' => '踅',
  '�a' => '跾',
  '�b' => '踀',
  '�c' => '踄',
  '�d' => '輐',
  '�e' => '輑',
  '�f' => '輎',
  '�g' => '輍',
  '�h' => '鄣',
  '�i' => '鄜',
  '�j' => '鄠',
  '�k' => '鄢',
  '�l' => '鄟',
  '�m' => '鄝',
  '�n' => '鄚',
  '�o' => '鄤',
  '�p' => '鄡',
  '�q' => '鄛',
  '�r' => '酺',
  '�s' => '酲',
  '�t' => '酹',
  '�u' => '酳',
  '�v' => '銥',
  '�w' => '銤',
  '�x' => '鉶',
  '�y' => '銛',
  '�z' => '鉺',
  '�{' => '銠',
  '�|' => '銔',
  '�}' => '銪',
  '�~' => '銍',
  '�' => '銦',
  '�' => '銚',
  '�' => '銫',
  '�' => '鉹',
  '�' => '銗',
  '�' => '鉿',
  '�' => '銣',
  '�' => '鋮',
  '�' => '銎',
  '�' => '銂',
  '�' => '銕',
  '�' => '銢',
  '�' => '鉽',
  '�' => '銈',
  '�' => '銡',
  '�' => '銊',
  '�' => '銆',
  '�' => '銌',
  '�' => '銙',
  '�' => '銧',
  '�' => '鉾',
  '�' => '銇',
  '�' => '銩',
  '�' => '銝',
  '�' => '銋',
  '�' => '鈭',
  '�' => '隞',
  '�' => '隡',
  '�' => '雿',
  '�' => '靘',
  '�' => '靽',
  '�' => '靺',
  '�' => '靾',
  '��' => '鞃',
  '��' => '鞀',
  '��' => '鞂',
  '��' => '靻',
  '��' => '鞄',
  '��' => '鞁',
  '��' => '靿',
  '��' => '韎',
  '��' => '韍',
  '��' => '頖',
  '��' => '颭',
  '��' => '颮',
  '��' => '餂',
  '��' => '餀',
  '��' => '餇',
  '��' => '馝',
  '��' => '馜',
  '��' => '駃',
  '��' => '馹',
  '��' => '馻',
  '��' => '馺',
  '��' => '駂',
  '��' => '馽',
  '��' => '駇',
  '��' => '骱',
  '��' => '髣',
  '��' => '髧',
  '��' => '鬾',
  '��' => '鬿',
  '��' => '魠',
  '��' => '魡',
  '��' => '魟',
  '��' => '鳱',
  '��' => '鳲',
  '��' => '鳵',
  '��' => '麧',
  '��' => '僿',
  '��' => '儃',
  '��' => '儰',
  '��' => '僸',
  '��' => '儆',
  '��' => '儇',
  '��' => '僶',
  '��' => '僾',
  '��' => '儋',
  '��' => '儌',
  '��' => '僽',
  '��' => '儊',
  '��' => '劋',
  '��' => '劌',
  '��' => '勱',
  '�' => '勯',
  '�' => '噈',
  '�' => '噂',
  '�' => '噌',
  '�' => '嘵',
  '�' => '噁',
  '�' => '噊',
  '�' => '噉',
  '�' => '噆',
  '�' => '噘',
  '�@' => '噚',
  '�A' => '噀',
  '�B' => '嘳',
  '�C' => '嘽',
  '�D' => '嘬',
  '�E' => '嘾',
  '�F' => '嘸',
  '�G' => '嘪',
  '�H' => '嘺',
  '�I' => '圚',
  '�J' => '墫',
  '�K' => '墝',
  '�L' => '墱',
  '�M' => '墠',
  '�N' => '墣',
  '�O' => '墯',
  '�P' => '墬',
  '�Q' => '墥',
  '�R' => '墡',
  '�S' => '壿',
  '�T' => '嫿',
  '�U' => '嫴',
  '�V' => '嫽',
  '�W' => '嫷',
  '�X' => '嫶',
  '�Y' => '嬃',
  '�Z' => '嫸',
  '�[' => '嬂',
  '�\\' => '嫹',
  '�]' => '嬁',
  '�^' => '嬇',
  '�_' => '嬅',
  '�`' => '嬏',
  '�a' => '屧',
  '�b' => '嶙',
  '�c' => '嶗',
  '�d' => '嶟',
  '�e' => '嶒',
  '�f' => '嶢',
  '�g' => '嶓',
  '�h' => '嶕',
  '�i' => '嶠',
  '�j' => '嶜',
  '�k' => '嶡',
  '�l' => '嶚',
  '�m' => '嶞',
  '�n' => '幩',
  '�o' => '幝',
  '�p' => '幠',
  '�q' => '幜',
  '�r' => '緳',
  '�s' => '廛',
  '�t' => '廞',
  '�u' => '廡',
  '�v' => '彉',
  '�w' => '徲',
  '�x' => '憋',
  '�y' => '憃',
  '�z' => '慹',
  '�{' => '憱',
  '�|' => '憰',
  '�}' => '憢',
  '�~' => '憉',
  '�' => '憛',
  '�' => '憓',
  '�' => '憯',
  '�' => '憭',
  '�' => '憟',
  '�' => '憒',
  '�' => '憪',
  '�' => '憡',
  '�' => '憍',
  '�' => '慦',
  '�' => '憳',
  '�' => '戭',
  '�' => '摮',
  '�' => '摰',
  '�' => '撖',
  '�' => '撠',
  '�' => '撅',
  '�' => '撗',
  '�' => '撜',
  '�' => '撏',
  '�' => '撋',
  '�' => '撊',
  '�' => '撌',
  '�' => '撣',
  '�' => '撟',
  '�' => '摨',
  '�' => '撱',
  '�' => '撘',
  '�' => '敶',
  '�' => '敺',
  '�' => '敹',
  '�' => '敻',
  '�' => '斲',
  '��' => '斳',
  '��' => '暵',
  '��' => '暰',
  '��' => '暩',
  '��' => '暲',
  '��' => '暷',
  '��' => '暪',
  '��' => '暯',
  '��' => '樀',
  '��' => '樆',
  '��' => '樗',
  '��' => '槥',
  '��' => '槸',
  '��' => '樕',
  '��' => '槱',
  '��' => '槤',
  '��' => '樠',
  '��' => '槿',
  '��' => '槬',
  '��' => '槢',
  '��' => '樛',
  '��' => '樝',
  '��' => '槾',
  '��' => '樧',
  '��' => '槲',
  '��' => '槮',
  '��' => '樔',
  '��' => '槷',
  '��' => '槧',
  '��' => '橀',
  '��' => '樈',
  '��' => '槦',
  '��' => '槻',
  '��' => '樍',
  '��' => '槼',
  '��' => '槫',
  '��' => '樉',
  '��' => '樄',
  '��' => '樘',
  '��' => '樥',
  '��' => '樏',
  '��' => '槶',
  '��' => '樦',
  '��' => '樇',
  '��' => '槴',
  '��' => '樖',
  '��' => '歑',
  '��' => '殥',
  '��' => '殣',
  '��' => '殢',
  '��' => '殦',
  '�' => '氁',
  '�' => '氀',
  '�' => '毿',
  '�' => '氂',
  '�' => '潁',
  '�' => '漦',
  '�' => '潾',
  '�' => '澇',
  '�' => '濆',
  '�' => '澒',
  '�@' => '澍',
  '�A' => '澉',
  '�B' => '澌',
  '�C' => '潢',
  '�D' => '潏',
  '�E' => '澅',
  '�F' => '潚',
  '�G' => '澖',
  '�H' => '潶',
  '�I' => '潬',
  '�J' => '澂',
  '�K' => '潕',
  '�L' => '潲',
  '�M' => '潒',
  '�N' => '潐',
  '�O' => '潗',
  '�P' => '澔',
  '�Q' => '澓',
  '�R' => '潝',
  '�S' => '漀',
  '�T' => '潡',
  '�U' => '潫',
  '�V' => '潽',
  '�W' => '潧',
  '�X' => '澐',
  '�Y' => '潓',
  '�Z' => '澋',
  '�[' => '潩',
  '�\\' => '潿',
  '�]' => '澕',
  '�^' => '潣',
  '�_' => '潷',
  '�`' => '潪',
  '�a' => '潻',
  '�b' => '熲',
  '�c' => '熯',
  '�d' => '熛',
  '�e' => '熰',
  '�f' => '熠',
  '�g' => '熚',
  '�h' => '熩',
  '�i' => '熵',
  '�j' => '熝',
  '�k' => '熥',
  '�l' => '熞',
  '�m' => '熤',
  '�n' => '熡',
  '�o' => '熪',
  '�p' => '熜',
  '�q' => '熧',
  '�r' => '熳',
  '�s' => '犘',
  '�t' => '犚',
  '�u' => '獘',
  '�v' => '獒',
  '�w' => '獞',
  '�x' => '獟',
  '�y' => '獠',
  '�z' => '獝',
  '�{' => '獛',
  '�|' => '獡',
  '�}' => '獚',
  '�~' => '獙',
  '�' => '獢',
  '�' => '璇',
  '�' => '璉',
  '�' => '璊',
  '�' => '璆',
  '�' => '璁',
  '�' => '瑽',
  '�' => '璅',
  '�' => '璈',
  '�' => '瑼',
  '�' => '瑹',
  '�' => '甈',
  '�' => '甇',
  '�' => '畾',
  '�' => '瘥',
  '�' => '瘞',
  '�' => '瘙',
  '�' => '瘝',
  '�' => '瘜',
  '�' => '瘣',
  '�' => '瘚',
  '�' => '瘨',
  '�' => '瘛',
  '�' => '皜',
  '�' => '皝',
  '�' => '皞',
  '�' => '皛',
  '�' => '瞍',
  '�' => '瞏',
  '�' => '瞉',
  '�' => '瞈',
  '�' => '磍',
  '�' => '碻',
  '��' => '磏',
  '��' => '磌',
  '��' => '磑',
  '��' => '磎',
  '��' => '磔',
  '��' => '磈',
  '��' => '磃',
  '��' => '磄',
  '��' => '磉',
  '��' => '禚',
  '��' => '禡',
  '��' => '禠',
  '��' => '禜',
  '��' => '禢',
  '��' => '禛',
  '��' => '歶',
  '��' => '稹',
  '��' => '窲',
  '��' => '窴',
  '��' => '窳',
  '��' => '箷',
  '��' => '篋',
  '��' => '箾',
  '��' => '箬',
  '��' => '篎',
  '��' => '箯',
  '��' => '箹',
  '��' => '篊',
  '��' => '箵',
  '��' => '糅',
  '��' => '糈',
  '��' => '糌',
  '��' => '糋',
  '��' => '緷',
  '��' => '緛',
  '��' => '緪',
  '��' => '緧',
  '��' => '緗',
  '��' => '緡',
  '��' => '縃',
  '��' => '緺',
  '��' => '緦',
  '��' => '緶',
  '��' => '緱',
  '��' => '緰',
  '��' => '緮',
  '��' => '緟',
  '��' => '罶',
  '��' => '羬',
  '��' => '羰',
  '��' => '羭',
  '�' => '翭',
  '�' => '翫',
  '�' => '翪',
  '�' => '翬',
  '�' => '翦',
  '�' => '翨',
  '�' => '聤',
  '�' => '聧',
  '�' => '膣',
  '�' => '膟',
  '�@' => '膞',
  '�A' => '膕',
  '�B' => '膢',
  '�C' => '膙',
  '�D' => '膗',
  '�E' => '舖',
  '�F' => '艏',
  '�G' => '艓',
  '�H' => '艒',
  '�I' => '艐',
  '�J' => '艎',
  '�K' => '艑',
  '�L' => '蔤',
  '�M' => '蔻',
  '�N' => '蔏',
  '�O' => '蔀',
  '�P' => '蔩',
  '�Q' => '蔎',
  '�R' => '蔉',
  '�S' => '蔍',
  '�T' => '蔟',
  '�U' => '蔊',
  '�V' => '蔧',
  '�W' => '蔜',
  '�X' => '蓻',
  '�Y' => '蔫',
  '�Z' => '蓺',
  '�[' => '蔈',
  '�\\' => '蔌',
  '�]' => '蓴',
  '�^' => '蔪',
  '�_' => '蓲',
  '�`' => '蔕',
  '�a' => '蓷',
  '�b' => '蓫',
  '�c' => '蓳',
  '�d' => '蓼',
  '�e' => '蔒',
  '�f' => '蓪',
  '�g' => '蓩',
  '�h' => '蔖',
  '�i' => '蓾',
  '�j' => '蔨',
  '�k' => '蔝',
  '�l' => '蔮',
  '�m' => '蔂',
  '�n' => '蓽',
  '�o' => '蔞',
  '�p' => '蓶',
  '�q' => '蔱',
  '�r' => '蔦',
  '�s' => '蓧',
  '�t' => '蓨',
  '�u' => '蓰',
  '�v' => '蓯',
  '�w' => '蓹',
  '�x' => '蔘',
  '�y' => '蔠',
  '�z' => '蔰',
  '�{' => '蔋',
  '�|' => '蔙',
  '�}' => '蔯',
  '�~' => '虢',
  '�' => '蝖',
  '�' => '蝣',
  '�' => '蝤',
  '�' => '蝷',
  '�' => '蟡',
  '�' => '蝳',
  '�' => '蝘',
  '�' => '蝔',
  '�' => '蝛',
  '�' => '蝒',
  '�' => '蝡',
  '�' => '蝚',
  '�' => '蝑',
  '�' => '蝞',
  '�' => '蝭',
  '�' => '蝪',
  '�' => '蝐',
  '�' => '蝎',
  '�' => '蝟',
  '�' => '蝝',
  '�' => '蝯',
  '�' => '蝬',
  '�' => '蝺',
  '�' => '蝮',
  '�' => '蝜',
  '�' => '蝥',
  '�' => '蝏',
  '�' => '蝻',
  '�' => '蝵',
  '�' => '蝢',
  '�' => '蝧',
  '�' => '蝩',
  '�' => '衚',
  '��' => '褅',
  '��' => '褌',
  '��' => '褔',
  '��' => '褋',
  '��' => '褗',
  '��' => '褘',
  '��' => '褙',
  '��' => '褆',
  '��' => '褖',
  '��' => '褑',
  '��' => '褎',
  '��' => '褉',
  '��' => '覢',
  '��' => '覤',
  '��' => '覣',
  '��' => '觭',
  '��' => '觰',
  '��' => '觬',
  '��' => '諏',
  '��' => '諆',
  '��' => '誸',
  '��' => '諓',
  '��' => '諑',
  '��' => '諔',
  '��' => '諕',
  '��' => '誻',
  '��' => '諗',
  '��' => '誾',
  '��' => '諀',
  '��' => '諅',
  '��' => '諘',
  '��' => '諃',
  '��' => '誺',
  '��' => '誽',
  '��' => '諙',
  '��' => '谾',
  '��' => '豍',
  '��' => '貏',
  '��' => '賥',
  '��' => '賟',
  '��' => '賙',
  '��' => '賨',
  '��' => '賚',
  '��' => '賝',
  '��' => '賧',
  '��' => '趠',
  '��' => '趜',
  '��' => '趡',
  '��' => '趛',
  '��' => '踠',
  '��' => '踣',
  '�' => '踥',
  '�' => '踤',
  '�' => '踮',
  '�' => '踕',
  '�' => '踛',
  '�' => '踖',
  '�' => '踑',
  '�' => '踙',
  '�' => '踦',
  '�' => '踧',
  '�@' => '踔',
  '�A' => '踒',
  '�B' => '踘',
  '�C' => '踓',
  '�D' => '踜',
  '�E' => '踗',
  '�F' => '踚',
  '�G' => '輬',
  '�H' => '輤',
  '�I' => '輘',
  '�J' => '輚',
  '�K' => '輠',
  '�L' => '輣',
  '�M' => '輖',
  '�N' => '輗',
  '�O' => '遳',
  '�P' => '遰',
  '�Q' => '遯',
  '�R' => '遧',
  '�S' => '遫',
  '�T' => '鄯',
  '�U' => '鄫',
  '�V' => '鄩',
  '�W' => '鄪',
  '�X' => '鄲',
  '�Y' => '鄦',
  '�Z' => '鄮',
  '�[' => '醅',
  '�\\' => '醆',
  '�]' => '醊',
  '�^' => '醁',
  '�_' => '醂',
  '�`' => '醄',
  '�a' => '醀',
  '�b' => '鋐',
  '�c' => '鋃',
  '�d' => '鋄',
  '�e' => '鋀',
  '�f' => '鋙',
  '�g' => '銶',
  '�h' => '鋏',
  '�i' => '鋱',
  '�j' => '鋟',
  '�k' => '鋘',
  '�l' => '鋩',
  '�m' => '鋗',
  '�n' => '鋝',
  '�o' => '鋌',
  '�p' => '鋯',
  '�q' => '鋂',
  '�r' => '鋨',
  '�s' => '鋊',
  '�t' => '鋈',
  '�u' => '鋎',
  '�v' => '鋦',
  '�w' => '鋍',
  '�x' => '鋕',
  '�y' => '鋉',
  '�z' => '鋠',
  '�{' => '鋞',
  '�|' => '鋧',
  '�}' => '鋑',
  '�~' => '鋓',
  '�' => '銵',
  '�' => '鋡',
  '�' => '鋆',
  '�' => '銴',
  '�' => '镼',
  '�' => '閬',
  '�' => '閫',
  '�' => '閮',
  '�' => '閰',
  '�' => '隤',
  '�' => '隢',
  '�' => '雓',
  '�' => '霅',
  '�' => '霈',
  '�' => '霂',
  '�' => '靚',
  '�' => '鞊',
  '�' => '鞎',
  '�' => '鞈',
  '�' => '韐',
  '�' => '韏',
  '�' => '頞',
  '�' => '頝',
  '�' => '頦',
  '�' => '頩',
  '�' => '頨',
  '�' => '頠',
  '�' => '頛',
  '�' => '頧',
  '�' => '颲',
  '�' => '餈',
  '�' => '飺',
  '�' => '餑',
  '��' => '餔',
  '��' => '餖',
  '��' => '餗',
  '��' => '餕',
  '��' => '駜',
  '��' => '駍',
  '��' => '駏',
  '��' => '駓',
  '��' => '駔',
  '��' => '駎',
  '��' => '駉',
  '��' => '駖',
  '��' => '駘',
  '��' => '駋',
  '��' => '駗',
  '��' => '駌',
  '��' => '骳',
  '��' => '髬',
  '��' => '髫',
  '��' => '髳',
  '��' => '髲',
  '��' => '髱',
  '��' => '魆',
  '��' => '魃',
  '��' => '魧',
  '��' => '魴',
  '��' => '魱',
  '��' => '魦',
  '��' => '魶',
  '��' => '魵',
  '��' => '魰',
  '��' => '魨',
  '��' => '魤',
  '��' => '魬',
  '��' => '鳼',
  '��' => '鳺',
  '��' => '鳽',
  '��' => '鳿',
  '��' => '鳷',
  '��' => '鴇',
  '��' => '鴀',
  '��' => '鳹',
  '��' => '鳻',
  '��' => '鴈',
  '��' => '鴅',
  '��' => '鴄',
  '��' => '麃',
  '��' => '黓',
  '��' => '鼏',
  '��' => '鼐',
  '��' => '儜',
  '�' => '儓',
  '�' => '儗',
  '�' => '儚',
  '�' => '儑',
  '�' => '凞',
  '�' => '匴',
  '�' => '叡',
  '�' => '噰',
  '�' => '噠',
  '�' => '噮',
  '�@' => '噳',
  '�A' => '噦',
  '�B' => '噣',
  '�C' => '噭',
  '�D' => '噲',
  '�E' => '噞',
  '�F' => '噷',
  '�G' => '圜',
  '�H' => '圛',
  '�I' => '壈',
  '�J' => '墽',
  '�K' => '壉',
  '�L' => '墿',
  '�M' => '墺',
  '�N' => '壂',
  '�O' => '墼',
  '�P' => '壆',
  '�Q' => '嬗',
  '�R' => '嬙',
  '�S' => '嬛',
  '�T' => '嬡',
  '�U' => '嬔',
  '�V' => '嬓',
  '�W' => '嬐',
  '�X' => '嬖',
  '�Y' => '嬨',
  '�Z' => '嬚',
  '�[' => '嬠',
  '�\\' => '嬞',
  '�]' => '寯',
  '�^' => '嶬',
  '�_' => '嶱',
  '�`' => '嶩',
  '�a' => '嶧',
  '�b' => '嶵',
  '�c' => '嶰',
  '�d' => '嶮',
  '�e' => '嶪',
  '�f' => '嶨',
  '�g' => '嶲',
  '�h' => '嶭',
  '�i' => '嶯',
  '�j' => '嶴',
  '�k' => '幧',
  '�l' => '幨',
  '�m' => '幦',
  '�n' => '幯',
  '�o' => '廩',
  '�p' => '廧',
  '�q' => '廦',
  '�r' => '廨',
  '�s' => '廥',
  '�t' => '彋',
  '�u' => '徼',
  '�v' => '憝',
  '�w' => '憨',
  '�x' => '憖',
  '�y' => '懅',
  '�z' => '憴',
  '�{' => '懆',
  '�|' => '懁',
  '�}' => '懌',
  '�~' => '憺',
  '�' => '憿',
  '�' => '憸',
  '�' => '憌',
  '�' => '擗',
  '�' => '擖',
  '�' => '擐',
  '�' => '擏',
  '�' => '擉',
  '�' => '撽',
  '�' => '撉',
  '�' => '擃',
  '�' => '擛',
  '�' => '擳',
  '�' => '擙',
  '�' => '攳',
  '�' => '敿',
  '�' => '敼',
  '�' => '斢',
  '�' => '曈',
  '�' => '暾',
  '�' => '曀',
  '�' => '曊',
  '�' => '曋',
  '�' => '曏',
  '�' => '暽',
  '�' => '暻',
  '�' => '暺',
  '�' => '曌',
  '�' => '朣',
  '�' => '樴',
  '�' => '橦',
  '�' => '橉',
  '�' => '橧',
  '��' => '樲',
  '��' => '橨',
  '��' => '樾',
  '��' => '橝',
  '��' => '橭',
  '��' => '橶',
  '��' => '橛',
  '��' => '橑',
  '��' => '樨',
  '��' => '橚',
  '��' => '樻',
  '��' => '樿',
  '��' => '橁',
  '��' => '橪',
  '��' => '橤',
  '��' => '橐',
  '��' => '橏',
  '��' => '橔',
  '��' => '橯',
  '��' => '橩',
  '��' => '橠',
  '��' => '樼',
  '��' => '橞',
  '��' => '橖',
  '��' => '橕',
  '��' => '橍',
  '��' => '橎',
  '��' => '橆',
  '��' => '歕',
  '��' => '歔',
  '��' => '歖',
  '��' => '殧',
  '��' => '殪',
  '��' => '殫',
  '��' => '毈',
  '��' => '毇',
  '��' => '氄',
  '��' => '氃',
  '��' => '氆',
  '��' => '澭',
  '��' => '濋',
  '��' => '澣',
  '��' => '濇',
  '��' => '澼',
  '��' => '濎',
  '��' => '濈',
  '��' => '潞',
  '��' => '濄',
  '��' => '澽',
  '��' => '澞',
  '��' => '濊',
  '�' => '澨',
  '�' => '瀄',
  '�' => '澥',
  '�' => '澮',
  '�' => '澺',
  '�' => '澬',
  '�' => '澪',
  '�' => '濏',
  '�' => '澿',
  '�' => '澸',
  '�@' => '澢',
  '�A' => '濉',
  '�B' => '澫',
  '�C' => '濍',
  '�D' => '澯',
  '�E' => '澲',
  '�F' => '澰',
  '�G' => '燅',
  '�H' => '燂',
  '�I' => '熿',
  '�J' => '熸',
  '�K' => '燖',
  '�L' => '燀',
  '�M' => '燁',
  '�N' => '燋',
  '�O' => '燔',
  '�P' => '燊',
  '�Q' => '燇',
  '�R' => '燏',
  '�S' => '熽',
  '�T' => '燘',
  '�U' => '熼',
  '�V' => '燆',
  '�W' => '燚',
  '�X' => '燛',
  '�Y' => '犝',
  '�Z' => '犞',
  '�[' => '獩',
  '�\\' => '獦',
  '�]' => '獧',
  '�^' => '獬',
  '�_' => '獥',
  '�`' => '獫',
  '�a' => '獪',
  '�b' => '瑿',
  '�c' => '璚',
  '�d' => '璠',
  '�e' => '璔',
  '�f' => '璒',
  '�g' => '璕',
  '�h' => '璡',
  '�i' => '甋',
  '�j' => '疀',
  '�k' => '瘯',
  '�l' => '瘭',
  '�m' => '瘱',
  '�n' => '瘽',
  '�o' => '瘳',
  '�p' => '瘼',
  '�q' => '瘵',
  '�r' => '瘲',
  '�s' => '瘰',
  '�t' => '皻',
  '�u' => '盦',
  '�v' => '瞚',
  '�w' => '瞝',
  '�x' => '瞡',
  '�y' => '瞜',
  '�z' => '瞛',
  '�{' => '瞢',
  '�|' => '瞣',
  '�}' => '瞕',
  '�~' => '瞙',
  '�' => '瞗',
  '�' => '磝',
  '�' => '磩',
  '�' => '磥',
  '�' => '磪',
  '�' => '磞',
  '�' => '磣',
  '�' => '磛',
  '�' => '磡',
  '�' => '磢',
  '�' => '磭',
  '�' => '磟',
  '�' => '磠',
  '�' => '禤',
  '�' => '穄',
  '�' => '穈',
  '�' => '穇',
  '�' => '窶',
  '�' => '窸',
  '�' => '窵',
  '�' => '窱',
  '�' => '窷',
  '�' => '篞',
  '�' => '篣',
  '�' => '篧',
  '�' => '篝',
  '�' => '篕',
  '�' => '篥',
  '�' => '篚',
  '�' => '篨',
  '�' => '篹',
  '�' => '篔',
  '�' => '篪',
  '��' => '篢',
  '��' => '篜',
  '��' => '篫',
  '��' => '篘',
  '��' => '篟',
  '��' => '糒',
  '��' => '糔',
  '��' => '糗',
  '��' => '糐',
  '��' => '糑',
  '��' => '縒',
  '��' => '縡',
  '��' => '縗',
  '��' => '縌',
  '��' => '縟',
  '��' => '縠',
  '��' => '縓',
  '��' => '縎',
  '��' => '縜',
  '��' => '縕',
  '��' => '縚',
  '��' => '縢',
  '��' => '縋',
  '��' => '縏',
  '��' => '縖',
  '��' => '縍',
  '��' => '縔',
  '��' => '縥',
  '��' => '縤',
  '��' => '罃',
  '��' => '罻',
  '��' => '罼',
  '��' => '罺',
  '��' => '羱',
  '��' => '翯',
  '��' => '耪',
  '��' => '耩',
  '��' => '聬',
  '��' => '膱',
  '��' => '膦',
  '��' => '膮',
  '��' => '膹',
  '��' => '膵',
  '��' => '膫',
  '��' => '膰',
  '��' => '膬',
  '��' => '膴',
  '��' => '膲',
  '��' => '膷',
  '��' => '膧',
  '��' => '臲',
  '�' => '艕',
  '�' => '艖',
  '�' => '艗',
  '�' => '蕖',
  '�' => '蕅',
  '�' => '蕫',
  '�' => '蕍',
  '�' => '蕓',
  '�' => '蕡',
  '�' => '蕘',
  '�@' => '蕀',
  '�A' => '蕆',
  '�B' => '蕤',
  '�C' => '蕁',
  '�D' => '蕢',
  '�E' => '蕄',
  '�F' => '蕑',
  '�G' => '蕇',
  '�H' => '蕣',
  '�I' => '蔾',
  '�J' => '蕛',
  '�K' => '蕱',
  '�L' => '蕎',
  '�M' => '蕮',
  '�N' => '蕵',
  '�O' => '蕕',
  '�P' => '蕧',
  '�Q' => '蕠',
  '�R' => '薌',
  '�S' => '蕦',
  '�T' => '蕝',
  '�U' => '蕔',
  '�V' => '蕥',
  '�W' => '蕬',
  '�X' => '虣',
  '�Y' => '虥',
  '�Z' => '虤',
  '�[' => '螛',
  '�\\' => '螏',
  '�]' => '螗',
  '�^' => '螓',
  '�_' => '螒',
  '�`' => '螈',
  '�a' => '螁',
  '�b' => '螖',
  '�c' => '螘',
  '�d' => '蝹',
  '�e' => '螇',
  '�f' => '螣',
  '�g' => '螅',
  '�h' => '螐',
  '�i' => '螑',
  '�j' => '螝',
  '�k' => '螄',
  '�l' => '螔',
  '�m' => '螜',
  '�n' => '螚',
  '�o' => '螉',
  '�p' => '褞',
  '�q' => '褦',
  '�r' => '褰',
  '�s' => '褭',
  '�t' => '褮',
  '�u' => '褧',
  '�v' => '褱',
  '�w' => '褢',
  '�x' => '褩',
  '�y' => '褣',
  '�z' => '褯',
  '�{' => '褬',
  '�|' => '褟',
  '�}' => '觱',
  '�~' => '諠',
  '�' => '諢',
  '�' => '諲',
  '�' => '諴',
  '�' => '諵',
  '�' => '諝',
  '�' => '謔',
  '�' => '諤',
  '�' => '諟',
  '�' => '諰',
  '�' => '諈',
  '�' => '諞',
  '�' => '諡',
  '�' => '諨',
  '�' => '諿',
  '�' => '諯',
  '�' => '諻',
  '�' => '貑',
  '�' => '貒',
  '�' => '貐',
  '�' => '賵',
  '�' => '賮',
  '�' => '賱',
  '�' => '賰',
  '�' => '賳',
  '�' => '赬',
  '�' => '赮',
  '�' => '趥',
  '�' => '趧',
  '�' => '踳',
  '�' => '踾',
  '�' => '踸',
  '�' => '蹀',
  '�' => '蹅',
  '��' => '踶',
  '��' => '踼',
  '��' => '踽',
  '��' => '蹁',
  '��' => '踰',
  '��' => '踿',
  '��' => '躽',
  '��' => '輶',
  '��' => '輮',
  '��' => '輵',
  '��' => '輲',
  '��' => '輹',
  '��' => '輷',
  '��' => '輴',
  '��' => '遶',
  '��' => '遹',
  '��' => '遻',
  '��' => '邆',
  '��' => '郺',
  '��' => '鄳',
  '��' => '鄵',
  '��' => '鄶',
  '��' => '醓',
  '��' => '醐',
  '��' => '醑',
  '��' => '醍',
  '��' => '醏',
  '��' => '錧',
  '��' => '錞',
  '��' => '錈',
  '��' => '錟',
  '��' => '錆',
  '��' => '錏',
  '��' => '鍺',
  '��' => '錸',
  '��' => '錼',
  '��' => '錛',
  '��' => '錣',
  '��' => '錒',
  '��' => '錁',
  '��' => '鍆',
  '��' => '錭',
  '��' => '錎',
  '��' => '錍',
  '��' => '鋋',
  '��' => '錝',
  '��' => '鋺',
  '��' => '錥',
  '��' => '錓',
  '��' => '鋹',
  '��' => '鋷',
  '�' => '錴',
  '�' => '錂',
  '�' => '錤',
  '�' => '鋿',
  '�' => '錩',
  '�' => '錹',
  '�' => '錵',
  '�' => '錪',
  '�' => '錔',
  '�' => '錌',
  '�@' => '錋',
  '�A' => '鋾',
  '�B' => '錉',
  '�C' => '錀',
  '�D' => '鋻',
  '�E' => '錖',
  '�F' => '閼',
  '�G' => '闍',
  '�H' => '閾',
  '�I' => '閹',
  '�J' => '閺',
  '�K' => '閶',
  '�L' => '閿',
  '�M' => '閵',
  '�N' => '閽',
  '�O' => '隩',
  '�P' => '雔',
  '�Q' => '霋',
  '�R' => '霒',
  '�S' => '霐',
  '�T' => '鞙',
  '�U' => '鞗',
  '�V' => '鞔',
  '�W' => '韰',
  '�X' => '韸',
  '�Y' => '頵',
  '�Z' => '頯',
  '�[' => '頲',
  '�\\' => '餤',
  '�]' => '餟',
  '�^' => '餧',
  '�_' => '餩',
  '�`' => '馞',
  '�a' => '駮',
  '�b' => '駬',
  '�c' => '駥',
  '�d' => '駤',
  '�e' => '駰',
  '�f' => '駣',
  '�g' => '駪',
  '�h' => '駩',
  '�i' => '駧',
  '�j' => '骹',
  '�k' => '骿',
  '�l' => '骴',
  '�m' => '骻',
  '�n' => '髶',
  '�o' => '髺',
  '�p' => '髹',
  '�q' => '髷',
  '�r' => '鬳',
  '�s' => '鮀',
  '�t' => '鮅',
  '�u' => '鮇',
  '�v' => '魼',
  '�w' => '魾',
  '�x' => '魻',
  '�y' => '鮂',
  '�z' => '鮓',
  '�{' => '鮒',
  '�|' => '鮐',
  '�}' => '魺',
  '�~' => '鮕',
  '�' => '魽',
  '�' => '鮈',
  '�' => '鴥',
  '�' => '鴗',
  '�' => '鴠',
  '�' => '鴞',
  '�' => '鴔',
  '�' => '鴩',
  '�' => '鴝',
  '�' => '鴘',
  '�' => '鴢',
  '�' => '鴐',
  '�' => '鴙',
  '�' => '鴟',
  '�' => '麈',
  '�' => '麆',
  '�' => '麇',
  '�' => '麮',
  '�' => '麭',
  '�' => '黕',
  '�' => '黖',
  '�' => '黺',
  '�' => '鼒',
  '�' => '鼽',
  '�' => '儦',
  '�' => '儥',
  '�' => '儢',
  '�' => '儤',
  '�' => '儠',
  '�' => '儩',
  '�' => '勴',
  '�' => '嚓',
  '�' => '嚌',
  '��' => '嚍',
  '��' => '嚆',
  '��' => '嚄',
  '��' => '嚃',
  '��' => '噾',
  '��' => '嚂',
  '��' => '噿',
  '��' => '嚁',
  '��' => '壖',
  '��' => '壔',
  '��' => '壏',
  '��' => '壒',
  '��' => '嬭',
  '��' => '嬥',
  '��' => '嬲',
  '��' => '嬣',
  '��' => '嬬',
  '��' => '嬧',
  '��' => '嬦',
  '��' => '嬯',
  '��' => '嬮',
  '��' => '孻',
  '��' => '寱',
  '��' => '寲',
  '��' => '嶷',
  '��' => '幬',
  '��' => '幪',
  '��' => '徾',
  '��' => '徻',
  '��' => '懃',
  '��' => '憵',
  '��' => '憼',
  '��' => '懧',
  '��' => '懠',
  '��' => '懥',
  '��' => '懤',
  '��' => '懨',
  '��' => '懞',
  '��' => '擯',
  '��' => '擩',
  '��' => '擣',
  '��' => '擫',
  '��' => '擤',
  '��' => '擨',
  '��' => '斁',
  '��' => '斀',
  '��' => '斶',
  '��' => '旚',
  '��' => '曒',
  '��' => '檍',
  '��' => '檖',
  '�' => '檁',
  '�' => '檥',
  '�' => '檉',
  '�' => '檟',
  '�' => '檛',
  '�' => '檡',
  '�' => '檞',
  '�' => '檇',
  '�' => '檓',
  '�' => '檎',
  '�@' => '檕',
  '�A' => '檃',
  '�B' => '檨',
  '�C' => '檤',
  '�D' => '檑',
  '�E' => '橿',
  '�F' => '檦',
  '�G' => '檚',
  '�H' => '檅',
  '�I' => '檌',
  '�J' => '檒',
  '�K' => '歛',
  '�L' => '殭',
  '�M' => '氉',
  '�N' => '濌',
  '�O' => '澩',
  '�P' => '濴',
  '�Q' => '濔',
  '�R' => '濣',
  '�S' => '濜',
  '�T' => '濭',
  '�U' => '濧',
  '�V' => '濦',
  '�W' => '濞',
  '�X' => '濲',
  '�Y' => '濝',
  '�Z' => '濢',
  '�[' => '濨',
  '�\\' => '燡',
  '�]' => '燱',
  '�^' => '燨',
  '�_' => '燲',
  '�`' => '燤',
  '�a' => '燰',
  '�b' => '燢',
  '�c' => '獳',
  '�d' => '獮',
  '�e' => '獯',
  '�f' => '璗',
  '�g' => '璲',
  '�h' => '璫',
  '�i' => '璐',
  '�j' => '璪',
  '�k' => '璭',
  '�l' => '璱',
  '�m' => '璥',
  '�n' => '璯',
  '�o' => '甐',
  '�p' => '甑',
  '�q' => '甒',
  '�r' => '甏',
  '�s' => '疄',
  '�t' => '癃',
  '�u' => '癈',
  '�v' => '癉',
  '�w' => '癇',
  '�x' => '皤',
  '�y' => '盩',
  '�z' => '瞵',
  '�{' => '瞫',
  '�|' => '瞲',
  '�}' => '瞷',
  '�~' => '瞶',
  '�' => '瞴',
  '�' => '瞱',
  '�' => '瞨',
  '�' => '矰',
  '�' => '磳',
  '�' => '磽',
  '�' => '礂',
  '�' => '磻',
  '�' => '磼',
  '�' => '磲',
  '�' => '礅',
  '�' => '磹',
  '�' => '磾',
  '�' => '礄',
  '�' => '禫',
  '�' => '禨',
  '�' => '穜',
  '�' => '穛',
  '�' => '穖',
  '�' => '穘',
  '�' => '穔',
  '�' => '穚',
  '�' => '窾',
  '�' => '竀',
  '�' => '竁',
  '�' => '簅',
  '�' => '簏',
  '�' => '篲',
  '�' => '簀',
  '�' => '篿',
  '�' => '篻',
  '�' => '簎',
  '�' => '篴',
  '��' => '簋',
  '��' => '篳',
  '��' => '簂',
  '��' => '簉',
  '��' => '簃',
  '��' => '簁',
  '��' => '篸',
  '��' => '篽',
  '��' => '簆',
  '��' => '篰',
  '��' => '篱',
  '��' => '簐',
  '��' => '簊',
  '��' => '糨',
  '��' => '縭',
  '��' => '縼',
  '��' => '繂',
  '��' => '縳',
  '��' => '顈',
  '��' => '縸',
  '��' => '縪',
  '��' => '繉',
  '��' => '繀',
  '��' => '繇',
  '��' => '縩',
  '��' => '繌',
  '��' => '縰',
  '��' => '縻',
  '��' => '縶',
  '��' => '繄',
  '��' => '縺',
  '��' => '罅',
  '��' => '罿',
  '��' => '罾',
  '��' => '罽',
  '��' => '翴',
  '��' => '翲',
  '��' => '耬',
  '��' => '膻',
  '��' => '臄',
  '��' => '臌',
  '��' => '臊',
  '��' => '臅',
  '��' => '臇',
  '��' => '膼',
  '��' => '臩',
  '��' => '艛',
  '��' => '艚',
  '��' => '艜',
  '��' => '薃',
  '��' => '薀',
  '�' => '薏',
  '�' => '薧',
  '�' => '薕',
  '�' => '薠',
  '�' => '薋',
  '�' => '薣',
  '�' => '蕻',
  '�' => '薤',
  '�' => '薚',
  '�' => '薞',
  '�@' => '蕷',
  '�A' => '蕼',
  '�B' => '薉',
  '�C' => '薡',
  '�D' => '蕺',
  '�E' => '蕸',
  '�F' => '蕗',
  '�G' => '薎',
  '�H' => '薖',
  '�I' => '薆',
  '�J' => '薍',
  '�K' => '薙',
  '�L' => '薝',
  '�M' => '薁',
  '�N' => '薢',
  '�O' => '薂',
  '�P' => '薈',
  '�Q' => '薅',
  '�R' => '蕹',
  '�S' => '蕶',
  '�T' => '薘',
  '�U' => '薐',
  '�V' => '薟',
  '�W' => '虨',
  '�X' => '螾',
  '�Y' => '螪',
  '�Z' => '螭',
  '�[' => '蟅',
  '�\\' => '螰',
  '�]' => '螬',
  '�^' => '螹',
  '�_' => '螵',
  '�`' => '螼',
  '�a' => '螮',
  '�b' => '蟉',
  '�c' => '蟃',
  '�d' => '蟂',
  '�e' => '蟌',
  '�f' => '螷',
  '�g' => '螯',
  '�h' => '蟄',
  '�i' => '蟊',
  '�j' => '螴',
  '�k' => '螶',
  '�l' => '螿',
  '�m' => '螸',
  '�n' => '螽',
  '�o' => '蟞',
  '�p' => '螲',
  '�q' => '褵',
  '�r' => '褳',
  '�s' => '褼',
  '�t' => '褾',
  '�u' => '襁',
  '�v' => '襒',
  '�w' => '褷',
  '�x' => '襂',
  '�y' => '覭',
  '�z' => '覯',
  '�{' => '覮',
  '�|' => '觲',
  '�}' => '觳',
  '�~' => '謞',
  '�' => '謘',
  '�' => '謖',
  '�' => '謑',
  '�' => '謅',
  '�' => '謋',
  '�' => '謢',
  '�' => '謏',
  '�' => '謒',
  '�' => '謕',
  '�' => '謇',
  '�' => '謍',
  '�' => '謈',
  '�' => '謆',
  '�' => '謜',
  '�' => '謓',
  '�' => '謚',
  '�' => '豏',
  '�' => '豰',
  '�' => '豲',
  '�' => '豱',
  '�' => '豯',
  '�' => '貕',
  '�' => '貔',
  '�' => '賹',
  '�' => '赯',
  '�' => '蹎',
  '�' => '蹍',
  '�' => '蹓',
  '�' => '蹐',
  '�' => '蹌',
  '�' => '蹇',
  '�' => '轃',
  '�' => '轀',
  '��' => '邅',
  '��' => '遾',
  '��' => '鄸',
  '��' => '醚',
  '��' => '醢',
  '��' => '醛',
  '��' => '醙',
  '��' => '醟',
  '��' => '醡',
  '��' => '醝',
  '��' => '醠',
  '��' => '鎡',
  '��' => '鎃',
  '��' => '鎯',
  '��' => '鍤',
  '��' => '鍖',
  '��' => '鍇',
  '��' => '鍼',
  '��' => '鍘',
  '��' => '鍜',
  '��' => '鍶',
  '��' => '鍉',
  '��' => '鍐',
  '��' => '鍑',
  '��' => '鍠',
  '��' => '鍭',
  '��' => '鎏',
  '��' => '鍌',
  '��' => '鍪',
  '��' => '鍹',
  '��' => '鍗',
  '��' => '鍕',
  '��' => '鍒',
  '��' => '鍏',
  '��' => '鍱',
  '��' => '鍷',
  '��' => '鍻',
  '��' => '鍡',
  '��' => '鍞',
  '��' => '鍣',
  '��' => '鍧',
  '��' => '鎀',
  '��' => '鍎',
  '��' => '鍙',
  '��' => '闇',
  '��' => '闀',
  '��' => '闉',
  '��' => '闃',
  '��' => '闅',
  '��' => '閷',
  '��' => '隮',
  '�' => '隰',
  '�' => '隬',
  '�' => '霠',
  '�' => '霟',
  '�' => '霘',
  '�' => '霝',
  '�' => '霙',
  '�' => '鞚',
  '�' => '鞡',
  '�' => '鞜',
  '�@' => '鞞',
  '�A' => '鞝',
  '�B' => '韕',
  '�C' => '韔',
  '�D' => '韱',
  '�E' => '顁',
  '�F' => '顄',
  '�G' => '顊',
  '�H' => '顉',
  '�I' => '顅',
  '�J' => '顃',
  '�K' => '餥',
  '�L' => '餫',
  '�M' => '餬',
  '�N' => '餪',
  '�O' => '餳',
  '�P' => '餲',
  '�Q' => '餯',
  '�R' => '餭',
  '�S' => '餱',
  '�T' => '餰',
  '�U' => '馘',
  '�V' => '馣',
  '�W' => '馡',
  '�X' => '騂',
  '�Y' => '駺',
  '�Z' => '駴',
  '�[' => '駷',
  '�\\' => '駹',
  '�]' => '駸',
  '�^' => '駶',
  '�_' => '駻',
  '�`' => '駽',
  '�a' => '駾',
  '�b' => '駼',
  '�c' => '騃',
  '�d' => '骾',
  '�e' => '髾',
  '�f' => '髽',
  '�g' => '鬁',
  '�h' => '髼',
  '�i' => '魈',
  '�j' => '鮚',
  '�k' => '鮨',
  '�l' => '鮞',
  '�m' => '鮛',
  '�n' => '鮦',
  '�o' => '鮡',
  '�p' => '鮥',
  '�q' => '鮤',
  '�r' => '鮆',
  '�s' => '鮢',
  '�t' => '鮠',
  '�u' => '鮯',
  '�v' => '鴳',
  '�w' => '鵁',
  '�x' => '鵧',
  '�y' => '鴶',
  '�z' => '鴮',
  '�{' => '鴯',
  '�|' => '鴱',
  '�}' => '鴸',
  '�~' => '鴰',
  '�' => '鵅',
  '�' => '鵂',
  '�' => '鵃',
  '�' => '鴾',
  '�' => '鴷',
  '�' => '鵀',
  '�' => '鴽',
  '�' => '翵',
  '�' => '鴭',
  '�' => '麊',
  '�' => '麉',
  '�' => '麍',
  '�' => '麰',
  '�' => '黈',
  '�' => '黚',
  '�' => '黻',
  '�' => '黿',
  '�' => '鼤',
  '�' => '鼣',
  '�' => '鼢',
  '�' => '齔',
  '�' => '龠',
  '�' => '儱',
  '�' => '儭',
  '�' => '儮',
  '�' => '嚘',
  '�' => '嚜',
  '�' => '嚗',
  '�' => '嚚',
  '�' => '嚝',
  '�' => '嚙',
  '�' => '奰',
  '�' => '嬼',
  '��' => '屩',
  '��' => '屪',
  '��' => '巀',
  '��' => '幭',
  '��' => '幮',
  '��' => '懘',
  '��' => '懟',
  '��' => '懭',
  '��' => '懮',
  '��' => '懱',
  '��' => '懪',
  '��' => '懰',
  '��' => '懫',
  '��' => '懖',
  '��' => '懩',
  '��' => '擿',
  '��' => '攄',
  '��' => '擽',
  '��' => '擸',
  '��' => '攁',
  '��' => '攃',
  '��' => '擼',
  '��' => '斔',
  '��' => '旛',
  '��' => '曚',
  '��' => '曛',
  '��' => '曘',
  '��' => '櫅',
  '��' => '檹',
  '��' => '檽',
  '��' => '櫡',
  '��' => '櫆',
  '��' => '檺',
  '��' => '檶',
  '��' => '檷',
  '��' => '櫇',
  '��' => '檴',
  '��' => '檭',
  '��' => '歞',
  '��' => '毉',
  '��' => '氋',
  '��' => '瀇',
  '��' => '瀌',
  '��' => '瀍',
  '��' => '瀁',
  '��' => '瀅',
  '��' => '瀔',
  '��' => '瀎',
  '��' => '濿',
  '��' => '瀀',
  '��' => '濻',
  '�' => '瀦',
  '�' => '濼',
  '�' => '濷',
  '�' => '瀊',
  '�' => '爁',
  '�' => '燿',
  '�' => '燹',
  '�' => '爃',
  '�' => '燽',
  '�' => '獶',
  '�@' => '璸',
  '�A' => '瓀',
  '�B' => '璵',
  '�C' => '瓁',
  '�D' => '璾',
  '�E' => '璶',
  '�F' => '璻',
  '�G' => '瓂',
  '�H' => '甔',
  '�I' => '甓',
  '�J' => '癜',
  '�K' => '癤',
  '�L' => '癙',
  '�M' => '癐',
  '�N' => '癓',
  '�O' => '癗',
  '�P' => '癚',
  '�Q' => '皦',
  '�R' => '皽',
  '�S' => '盬',
  '�T' => '矂',
  '�U' => '瞺',
  '�V' => '磿',
  '�W' => '礌',
  '�X' => '礓',
  '�Y' => '礔',
  '�Z' => '礉',
  '�[' => '礐',
  '�\\' => '礒',
  '�]' => '礑',
  '�^' => '禭',
  '�_' => '禬',
  '�`' => '穟',
  '�a' => '簜',
  '�b' => '簩',
  '�c' => '簙',
  '�d' => '簠',
  '�e' => '簟',
  '�f' => '簭',
  '�g' => '簝',
  '�h' => '簦',
  '�i' => '簨',
  '�j' => '簢',
  '�k' => '簥',
  '�l' => '簰',
  '�m' => '繜',
  '�n' => '繐',
  '�o' => '繖',
  '�p' => '繣',
  '�q' => '繘',
  '�r' => '繢',
  '�s' => '繟',
  '�t' => '繑',
  '�u' => '繠',
  '�v' => '繗',
  '�w' => '繓',
  '�x' => '羵',
  '�y' => '羳',
  '�z' => '翷',
  '�{' => '翸',
  '�|' => '聵',
  '�}' => '臑',
  '�~' => '臒',
  '�' => '臐',
  '�' => '艟',
  '�' => '艞',
  '�' => '薴',
  '�' => '藆',
  '�' => '藀',
  '�' => '藃',
  '�' => '藂',
  '�' => '薳',
  '�' => '薵',
  '�' => '薽',
  '�' => '藇',
  '�' => '藄',
  '�' => '薿',
  '�' => '藋',
  '�' => '藎',
  '�' => '藈',
  '�' => '藅',
  '�' => '薱',
  '�' => '薶',
  '�' => '藒',
  '�' => '蘤',
  '�' => '薸',
  '�' => '薷',
  '�' => '薾',
  '�' => '虩',
  '�' => '蟧',
  '�' => '蟦',
  '�' => '蟢',
  '�' => '蟛',
  '�' => '蟫',
  '�' => '蟪',
  '�' => '蟥',
  '��' => '蟟',
  '��' => '蟳',
  '��' => '蟤',
  '��' => '蟔',
  '��' => '蟜',
  '��' => '蟓',
  '��' => '蟭',
  '��' => '蟘',
  '��' => '蟣',
  '��' => '螤',
  '��' => '蟗',
  '��' => '蟙',
  '��' => '蠁',
  '��' => '蟴',
  '��' => '蟨',
  '��' => '蟝',
  '��' => '襓',
  '��' => '襋',
  '��' => '襏',
  '��' => '襌',
  '��' => '襆',
  '��' => '襐',
  '��' => '襑',
  '��' => '襉',
  '��' => '謪',
  '��' => '謧',
  '��' => '謣',
  '��' => '謳',
  '��' => '謰',
  '��' => '謵',
  '��' => '譇',
  '��' => '謯',
  '��' => '謼',
  '��' => '謾',
  '��' => '謱',
  '��' => '謥',
  '��' => '謷',
  '��' => '謦',
  '��' => '謶',
  '��' => '謮',
  '��' => '謤',
  '��' => '謻',
  '��' => '謽',
  '��' => '謺',
  '��' => '豂',
  '��' => '豵',
  '��' => '貙',
  '��' => '貘',
  '��' => '貗',
  '��' => '賾',
  '��' => '贄',
  '�' => '贂',
  '�' => '贀',
  '�' => '蹜',
  '�' => '蹢',
  '�' => '蹠',
  '�' => '蹗',
  '�' => '蹖',
  '�' => '蹞',
  '�' => '蹥',
  '�' => '蹧',
  '�@' => '蹛',
  '�A' => '蹚',
  '�B' => '蹡',
  '�C' => '蹝',
  '�D' => '蹩',
  '�E' => '蹔',
  '�F' => '轆',
  '�G' => '轇',
  '�H' => '轈',
  '�I' => '轋',
  '�J' => '鄨',
  '�K' => '鄺',
  '�L' => '鄻',
  '�M' => '鄾',
  '�N' => '醨',
  '�O' => '醥',
  '�P' => '醧',
  '�Q' => '醯',
  '�R' => '醪',
  '�S' => '鎵',
  '�T' => '鎌',
  '�U' => '鎒',
  '�V' => '鎷',
  '�W' => '鎛',
  '�X' => '鎝',
  '�Y' => '鎉',
  '�Z' => '鎧',
  '�[' => '鎎',
  '�\\' => '鎪',
  '�]' => '鎞',
  '�^' => '鎦',
  '�_' => '鎕',
  '�`' => '鎈',
  '�a' => '鎙',
  '�b' => '鎟',
  '�c' => '鎍',
  '�d' => '鎱',
  '�e' => '鎑',
  '�f' => '鎲',
  '�g' => '鎤',
  '�h' => '鎨',
  '�i' => '鎴',
  '�j' => '鎣',
  '�k' => '鎥',
  '�l' => '闒',
  '�m' => '闓',
  '�n' => '闑',
  '�o' => '隳',
  '�p' => '雗',
  '�q' => '雚',
  '�r' => '巂',
  '�s' => '雟',
  '�t' => '雘',
  '�u' => '雝',
  '�v' => '霣',
  '�w' => '霢',
  '�x' => '霥',
  '�y' => '鞬',
  '�z' => '鞮',
  '�{' => '鞨',
  '�|' => '鞫',
  '�}' => '鞤',
  '�~' => '鞪',
  '�' => '鞢',
  '�' => '鞥',
  '�' => '韗',
  '�' => '韙',
  '�' => '韖',
  '�' => '韘',
  '�' => '韺',
  '�' => '顐',
  '�' => '顑',
  '�' => '顒',
  '�' => '颸',
  '�' => '饁',
  '�' => '餼',
  '�' => '餺',
  '�' => '騏',
  '�' => '騋',
  '�' => '騉',
  '�' => '騍',
  '�' => '騄',
  '�' => '騑',
  '�' => '騊',
  '�' => '騅',
  '�' => '騇',
  '�' => '騆',
  '�' => '髀',
  '�' => '髜',
  '�' => '鬈',
  '�' => '鬄',
  '�' => '鬅',
  '�' => '鬩',
  '�' => '鬵',
  '�' => '魊',
  '�' => '魌',
  '��' => '魋',
  '��' => '鯇',
  '��' => '鯆',
  '��' => '鯃',
  '��' => '鮿',
  '��' => '鯁',
  '��' => '鮵',
  '��' => '鮸',
  '��' => '鯓',
  '��' => '鮶',
  '��' => '鯄',
  '��' => '鮹',
  '��' => '鮽',
  '��' => '鵜',
  '��' => '鵓',
  '��' => '鵏',
  '��' => '鵊',
  '��' => '鵛',
  '��' => '鵋',
  '��' => '鵙',
  '��' => '鵖',
  '��' => '鵌',
  '��' => '鵗',
  '��' => '鵒',
  '��' => '鵔',
  '��' => '鵟',
  '��' => '鵘',
  '��' => '鵚',
  '��' => '麎',
  '��' => '麌',
  '��' => '黟',
  '��' => '鼁',
  '��' => '鼀',
  '��' => '鼖',
  '��' => '鼥',
  '��' => '鼫',
  '��' => '鼪',
  '��' => '鼩',
  '��' => '鼨',
  '��' => '齌',
  '��' => '齕',
  '��' => '儴',
  '��' => '儵',
  '��' => '劖',
  '��' => '勷',
  '��' => '厴',
  '��' => '嚫',
  '��' => '嚭',
  '��' => '嚦',
  '��' => '嚧',
  '��' => '嚪',
  '�' => '嚬',
  '�' => '壚',
  '�' => '壝',
  '�' => '壛',
  '�' => '夒',
  '�' => '嬽',
  '�' => '嬾',
  '�' => '嬿',
  '�' => '巃',
  '�' => '幰',
  '�@' => '徿',
  '�A' => '懻',
  '�B' => '攇',
  '�C' => '攐',
  '�D' => '攍',
  '�E' => '攉',
  '�F' => '攌',
  '�G' => '攎',
  '�H' => '斄',
  '�I' => '旞',
  '�J' => '旝',
  '�K' => '曞',
  '�L' => '櫧',
  '�M' => '櫠',
  '�N' => '櫌',
  '�O' => '櫑',
  '�P' => '櫙',
  '�Q' => '櫋',
  '�R' => '櫟',
  '�S' => '櫜',
  '�T' => '櫐',
  '�U' => '櫫',
  '�V' => '櫏',
  '�W' => '櫍',
  '�X' => '櫞',
  '�Y' => '歠',
  '�Z' => '殰',
  '�[' => '氌',
  '�\\' => '瀙',
  '�]' => '瀧',
  '�^' => '瀠',
  '�_' => '瀖',
  '�`' => '瀫',
  '�a' => '瀡',
  '�b' => '瀢',
  '�c' => '瀣',
  '�d' => '瀩',
  '�e' => '瀗',
  '�f' => '瀤',
  '�g' => '瀜',
  '�h' => '瀪',
  '�i' => '爌',
  '�j' => '爊',
  '�k' => '爇',
  '�l' => '爂',
  '�m' => '爅',
  '�n' => '犥',
  '�o' => '犦',
  '�p' => '犤',
  '�q' => '犣',
  '�r' => '犡',
  '�s' => '瓋',
  '�t' => '瓅',
  '�u' => '璷',
  '�v' => '瓃',
  '�w' => '甖',
  '�x' => '癠',
  '�y' => '矉',
  '�z' => '矊',
  '�{' => '矄',
  '�|' => '矱',
  '�}' => '礝',
  '�~' => '礛',
  '�' => '礡',
  '�' => '礜',
  '�' => '礗',
  '�' => '礞',
  '�' => '禰',
  '�' => '穧',
  '�' => '穨',
  '�' => '簳',
  '�' => '簼',
  '�' => '簹',
  '�' => '簬',
  '�' => '簻',
  '�' => '糬',
  '�' => '糪',
  '�' => '繶',
  '�' => '繵',
  '�' => '繸',
  '�' => '繰',
  '�' => '繷',
  '�' => '繯',
  '�' => '繺',
  '�' => '繲',
  '�' => '繴',
  '�' => '繨',
  '�' => '罋',
  '�' => '罊',
  '�' => '羃',
  '�' => '羆',
  '�' => '羷',
  '�' => '翽',
  '�' => '翾',
  '�' => '聸',
  '�' => '臗',
  '��' => '臕',
  '��' => '艤',
  '��' => '艡',
  '��' => '艣',
  '��' => '藫',
  '��' => '藱',
  '��' => '藭',
  '��' => '藙',
  '��' => '藡',
  '��' => '藨',
  '��' => '藚',
  '��' => '藗',
  '��' => '藬',
  '��' => '藲',
  '��' => '藸',
  '��' => '藘',
  '��' => '藟',
  '��' => '藣',
  '��' => '藜',
  '��' => '藑',
  '��' => '藰',
  '��' => '藦',
  '��' => '藯',
  '��' => '藞',
  '��' => '藢',
  '��' => '蠀',
  '��' => '蟺',
  '��' => '蠃',
  '��' => '蟶',
  '��' => '蟷',
  '��' => '蠉',
  '��' => '蠌',
  '��' => '蠋',
  '��' => '蠆',
  '��' => '蟼',
  '��' => '蠈',
  '��' => '蟿',
  '��' => '蠊',
  '��' => '蠂',
  '��' => '襢',
  '��' => '襚',
  '��' => '襛',
  '��' => '襗',
  '��' => '襡',
  '��' => '襜',
  '��' => '襘',
  '��' => '襝',
  '��' => '襙',
  '��' => '覈',
  '��' => '覷',
  '��' => '覶',
  '�' => '觶',
  '�' => '譐',
  '�' => '譈',
  '�' => '譊',
  '�' => '譀',
  '�' => '譓',
  '�' => '譖',
  '�' => '譔',
  '�' => '譋',
  '�' => '譕',
  '�@' => '譑',
  '�A' => '譂',
  '�B' => '譒',
  '�C' => '譗',
  '�D' => '豃',
  '�E' => '豷',
  '�F' => '豶',
  '�G' => '貚',
  '�H' => '贆',
  '�I' => '贇',
  '�J' => '贉',
  '�K' => '趬',
  '�L' => '趪',
  '�M' => '趭',
  '�N' => '趫',
  '�O' => '蹭',
  '�P' => '蹸',
  '�Q' => '蹳',
  '�R' => '蹪',
  '�S' => '蹯',
  '�T' => '蹻',
  '�U' => '軂',
  '�V' => '轒',
  '�W' => '轑',
  '�X' => '轏',
  '�Y' => '轐',
  '�Z' => '轓',
  '�[' => '辴',
  '�\\' => '酀',
  '�]' => '鄿',
  '�^' => '醰',
  '�_' => '醭',
  '�`' => '鏞',
  '�a' => '鏇',
  '�b' => '鏏',
  '�c' => '鏂',
  '�d' => '鏚',
  '�e' => '鏐',
  '�f' => '鏹',
  '�g' => '鏬',
  '�h' => '鏌',
  '�i' => '鏙',
  '�j' => '鎩',
  '�k' => '鏦',
  '�l' => '鏊',
  '�m' => '鏔',
  '�n' => '鏮',
  '�o' => '鏣',
  '�p' => '鏕',
  '�q' => '鏄',
  '�r' => '鏎',
  '�s' => '鏀',
  '�t' => '鏒',
  '�u' => '鏧',
  '�v' => '镽',
  '�w' => '闚',
  '�x' => '闛',
  '�y' => '雡',
  '�z' => '霩',
  '�{' => '霫',
  '�|' => '霬',
  '�}' => '霨',
  '�~' => '霦',
  '�' => '鞳',
  '�' => '鞷',
  '�' => '鞶',
  '�' => '韝',
  '�' => '韞',
  '�' => '韟',
  '�' => '顜',
  '�' => '顙',
  '�' => '顝',
  '�' => '顗',
  '�' => '颿',
  '�' => '颽',
  '�' => '颻',
  '�' => '颾',
  '�' => '饈',
  '�' => '饇',
  '�' => '饃',
  '�' => '馦',
  '�' => '馧',
  '�' => '騚',
  '�' => '騕',
  '�' => '騥',
  '�' => '騝',
  '�' => '騤',
  '�' => '騛',
  '�' => '騢',
  '�' => '騠',
  '�' => '騧',
  '�' => '騣',
  '�' => '騞',
  '�' => '騜',
  '�' => '騔',
  '�' => '髂',
  '��' => '鬋',
  '��' => '鬊',
  '��' => '鬎',
  '��' => '鬌',
  '��' => '鬷',
  '��' => '鯪',
  '��' => '鯫',
  '��' => '鯠',
  '��' => '鯞',
  '��' => '鯤',
  '��' => '鯦',
  '��' => '鯢',
  '��' => '鯰',
  '��' => '鯔',
  '��' => '鯗',
  '��' => '鯬',
  '��' => '鯜',
  '��' => '鯙',
  '��' => '鯥',
  '��' => '鯕',
  '��' => '鯡',
  '��' => '鯚',
  '��' => '鵷',
  '��' => '鶁',
  '��' => '鶊',
  '��' => '鶄',
  '��' => '鶈',
  '��' => '鵱',
  '��' => '鶀',
  '��' => '鵸',
  '��' => '鶆',
  '��' => '鶋',
  '��' => '鶌',
  '��' => '鵽',
  '��' => '鵫',
  '��' => '鵴',
  '��' => '鵵',
  '��' => '鵰',
  '��' => '鵩',
  '��' => '鶅',
  '��' => '鵳',
  '��' => '鵻',
  '��' => '鶂',
  '��' => '鵯',
  '��' => '鵹',
  '��' => '鵿',
  '��' => '鶇',
  '��' => '鵨',
  '��' => '麔',
  '��' => '麑',
  '��' => '黀',
  '�' => '黼',
  '�' => '鼭',
  '�' => '齀',
  '�' => '齁',
  '�' => '齍',
  '�' => '齖',
  '�' => '齗',
  '�' => '齘',
  '�' => '匷',
  '�' => '嚲',
  '�@' => '嚵',
  '�A' => '嚳',
  '�B' => '壣',
  '�C' => '孅',
  '�D' => '巆',
  '�E' => '巇',
  '�F' => '廮',
  '�G' => '廯',
  '�H' => '忀',
  '�I' => '忁',
  '�J' => '懹',
  '�K' => '攗',
  '�L' => '攖',
  '�M' => '攕',
  '�N' => '攓',
  '�O' => '旟',
  '�P' => '曨',
  '�Q' => '曣',
  '�R' => '曤',
  '�S' => '櫳',
  '�T' => '櫰',
  '�U' => '櫪',
  '�V' => '櫨',
  '�W' => '櫹',
  '�X' => '櫱',
  '�Y' => '櫮',
  '�Z' => '櫯',
  '�[' => '瀼',
  '�\\' => '瀵',
  '�]' => '瀯',
  '�^' => '瀷',
  '�_' => '瀴',
  '�`' => '瀱',
  '�a' => '灂',
  '�b' => '瀸',
  '�c' => '瀿',
  '�d' => '瀺',
  '�e' => '瀹',
  '�f' => '灀',
  '�g' => '瀻',
  '�h' => '瀳',
  '�i' => '灁',
  '�j' => '爓',
  '�k' => '爔',
  '�l' => '犨',
  '�m' => '獽',
  '�n' => '獼',
  '�o' => '璺',
  '�p' => '皫',
  '�q' => '皪',
  '�r' => '皾',
  '�s' => '盭',
  '�t' => '矌',
  '�u' => '矎',
  '�v' => '矏',
  '�w' => '矍',
  '�x' => '矲',
  '�y' => '礥',
  '�z' => '礣',
  '�{' => '礧',
  '�|' => '礨',
  '�}' => '礤',
  '�~' => '礩',
  '�' => '禲',
  '�' => '穮',
  '�' => '穬',
  '�' => '穭',
  '�' => '竷',
  '�' => '籉',
  '�' => '籈',
  '�' => '籊',
  '�' => '籇',
  '�' => '籅',
  '�' => '糮',
  '�' => '繻',
  '�' => '繾',
  '�' => '纁',
  '�' => '纀',
  '�' => '羺',
  '�' => '翿',
  '�' => '聹',
  '�' => '臛',
  '�' => '臙',
  '�' => '舋',
  '�' => '艨',
  '�' => '艩',
  '�' => '蘢',
  '�' => '藿',
  '�' => '蘁',
  '�' => '藾',
  '�' => '蘛',
  '�' => '蘀',
  '�' => '藶',
  '�' => '蘄',
  '�' => '蘉',
  '�' => '蘅',
  '��' => '蘌',
  '��' => '藽',
  '��' => '蠙',
  '��' => '蠐',
  '��' => '蠑',
  '��' => '蠗',
  '��' => '蠓',
  '��' => '蠖',
  '��' => '襣',
  '��' => '襦',
  '��' => '覹',
  '��' => '觷',
  '��' => '譠',
  '��' => '譪',
  '��' => '譝',
  '��' => '譨',
  '��' => '譣',
  '��' => '譥',
  '��' => '譧',
  '��' => '譭',
  '��' => '趮',
  '��' => '躆',
  '��' => '躈',
  '��' => '躄',
  '��' => '轙',
  '��' => '轖',
  '��' => '轗',
  '��' => '轕',
  '��' => '轘',
  '��' => '轚',
  '��' => '邍',
  '��' => '酃',
  '��' => '酁',
  '��' => '醷',
  '��' => '醵',
  '��' => '醲',
  '��' => '醳',
  '��' => '鐋',
  '��' => '鐓',
  '��' => '鏻',
  '��' => '鐠',
  '��' => '鐏',
  '��' => '鐔',
  '��' => '鏾',
  '��' => '鐕',
  '��' => '鐐',
  '��' => '鐨',
  '��' => '鐙',
  '��' => '鐍',
  '��' => '鏵',
  '��' => '鐀',
  '�' => '鏷',
  '�' => '鐇',
  '�' => '鐎',
  '�' => '鐖',
  '�' => '鐒',
  '�' => '鏺',
  '�' => '鐉',
  '�' => '鏸',
  '�' => '鐊',
  '�' => '鏿',
  '�@' => '鏼',
  '�A' => '鐌',
  '�B' => '鏶',
  '�C' => '鐑',
  '�D' => '鐆',
  '�E' => '闞',
  '�F' => '闠',
  '�G' => '闟',
  '�H' => '霮',
  '�I' => '霯',
  '�J' => '鞹',
  '�K' => '鞻',
  '�L' => '韽',
  '�M' => '韾',
  '�N' => '顠',
  '�O' => '顢',
  '�P' => '顣',
  '�Q' => '顟',
  '�R' => '飁',
  '�S' => '飂',
  '�T' => '饐',
  '�U' => '饎',
  '�V' => '饙',
  '�W' => '饌',
  '�X' => '饋',
  '�Y' => '饓',
  '�Z' => '騲',
  '�[' => '騴',
  '�\\' => '騱',
  '�]' => '騬',
  '�^' => '騪',
  '�_' => '騶',
  '�`' => '騩',
  '�a' => '騮',
  '�b' => '騸',
  '�c' => '騭',
  '�d' => '髇',
  '�e' => '髊',
  '�f' => '髆',
  '�g' => '鬐',
  '�h' => '鬒',
  '�i' => '鬑',
  '�j' => '鰋',
  '�k' => '鰈',
  '�l' => '鯷',
  '�m' => '鰅',
  '�n' => '鰒',
  '�o' => '鯸',
  '�p' => '鱀',
  '�q' => '鰇',
  '�r' => '鰎',
  '�s' => '鰆',
  '�t' => '鰗',
  '�u' => '鰔',
  '�v' => '鰉',
  '�w' => '鶟',
  '�x' => '鶙',
  '�y' => '鶤',
  '�z' => '鶝',
  '�{' => '鶒',
  '�|' => '鶘',
  '�}' => '鶐',
  '�~' => '鶛',
  '��' => '鶠',
  '��' => '鶔',
  '��' => '鶜',
  '��' => '鶪',
  '��' => '鶗',
  '��' => '鶡',
  '��' => '鶚',
  '��' => '鶢',
  '��' => '鶨',
  '��' => '鶞',
  '��' => '鶣',
  '��' => '鶿',
  '��' => '鶩',
  '��' => '鶖',
  '��' => '鶦',
  '��' => '鶧',
  '��' => '麙',
  '��' => '麛',
  '��' => '麚',
  '��' => '黥',
  '��' => '黤',
  '��' => '黧',
  '��' => '黦',
  '��' => '鼰',
  '��' => '鼮',
  '��' => '齛',
  '��' => '齠',
  '��' => '齞',
  '��' => '齝',
  '��' => '齙',
  '��' => '龑',
  '��' => '儺',
  '��' => '儹',
  '��' => '劘',
  '��' => '劗',
  '��' => '囃',
  '��' => '嚽',
  '��' => '嚾',
  '��' => '孈',
  '��' => '孇',
  '��' => '巋',
  '��' => '巏',
  '��' => '廱',
  '��' => '懽',
  '��' => '攛',
  '��' => '欂',
  '��' => '櫼',
  '��' => '欃',
  '��' => '櫸',
  '��' => '欀',
  '��' => '灃',
  '��' => '灄',
  '��' => '灊',
  '��' => '灈',
  '��' => '灉',
  '��' => '灅',
  '��' => '灆',
  '��' => '爝',
  '��' => '爚',
  '��' => '爙',
  '��' => '獾',
  '��' => '甗',
  '��' => '癪',
  '��' => '矐',
  '��' => '礭',
  '��' => '礱',
  '��' => '礯',
  '��' => '籔',
  '��' => '籓',
  '��' => '糲',
  '��' => '纊',
  '��' => '纇',
  '��' => '纈',
  '��' => '纋',
  '��' => '纆',
  '��' => '纍',
  '��' => '罍',
  '��' => '羻',
  '��' => '耰',
  '��' => '臝',
  '��' => '蘘',
  '��' => '蘪',
  '��' => '蘦',
  '��' => '蘟',
  '��' => '蘣',
  '��' => '蘜',
  '��' => '蘙',
  '��' => '蘧',
  '��' => '蘮',
  '��' => '蘡',
  '��' => '蘠',
  '��' => '蘩',
  '��' => '蘞',
  '��' => '蘥',
  '�@' => '蠩',
  '�A' => '蠝',
  '�B' => '蠛',
  '�C' => '蠠',
  '�D' => '蠤',
  '�E' => '蠜',
  '�F' => '蠫',
  '�G' => '衊',
  '�H' => '襭',
  '�I' => '襩',
  '�J' => '襮',
  '�K' => '襫',
  '�L' => '觺',
  '�M' => '譹',
  '�N' => '譸',
  '�O' => '譅',
  '�P' => '譺',
  '�Q' => '譻',
  '�R' => '贐',
  '�S' => '贔',
  '�T' => '趯',
  '�U' => '躎',
  '�V' => '躌',
  '�W' => '轞',
  '�X' => '轛',
  '�Y' => '轝',
  '�Z' => '酆',
  '�[' => '酄',
  '�\\' => '酅',
  '�]' => '醹',
  '�^' => '鐿',
  '�_' => '鐻',
  '�`' => '鐶',
  '�a' => '鐩',
  '�b' => '鐽',
  '�c' => '鐼',
  '�d' => '鐰',
  '�e' => '鐹',
  '�f' => '鐪',
  '�g' => '鐷',
  '�h' => '鐬',
  '�i' => '鑀',
  '�j' => '鐱',
  '�k' => '闥',
  '�l' => '闤',
  '�m' => '闣',
  '�n' => '霵',
  '�o' => '霺',
  '�p' => '鞿',
  '�q' => '韡',
  '�r' => '顤',
  '�s' => '飉',
  '�t' => '飆',
  '�u' => '飀',
  '�v' => '饘',
  '�w' => '饖',
  '�x' => '騹',
  '�y' => '騽',
  '�z' => '驆',
  '�{' => '驄',
  '�|' => '驂',
  '�}' => '驁',
  '�~' => '騺',
  '��' => '騿',
  '��' => '髍',
  '��' => '鬕',
  '��' => '鬗',
  '��' => '鬘',
  '��' => '鬖',
  '��' => '鬺',
  '��' => '魒',
  '��' => '鰫',
  '��' => '鰝',
  '��' => '鰜',
  '��' => '鰬',
  '��' => '鰣',
  '��' => '鰨',
  '��' => '鰩',
  '��' => '鰤',
  '��' => '鰡',
  '��' => '鶷',
  '��' => '鶶',
  '��' => '鶼',
  '��' => '鷁',
  '��' => '鷇',
  '��' => '鷊',
  '��' => '鷏',
  '��' => '鶾',
  '��' => '鷅',
  '��' => '鷃',
  '��' => '鶻',
  '��' => '鶵',
  '��' => '鷎',
  '��' => '鶹',
  '��' => '鶺',
  '��' => '鶬',
  '��' => '鷈',
  '��' => '鶱',
  '��' => '鶭',
  '��' => '鷌',
  '��' => '鶳',
  '��' => '鷍',
  '��' => '鶲',
  '��' => '鹺',
  '��' => '麜',
  '��' => '黫',
  '��' => '黮',
  '��' => '黭',
  '��' => '鼛',
  '��' => '鼘',
  '��' => '鼚',
  '��' => '鼱',
  '��' => '齎',
  '��' => '齥',
  '��' => '齤',
  '��' => '龒',
  '��' => '亹',
  '��' => '囆',
  '��' => '囅',
  '��' => '囋',
  '��' => '奱',
  '��' => '孋',
  '��' => '孌',
  '��' => '巕',
  '��' => '巑',
  '��' => '廲',
  '��' => '攡',
  '��' => '攠',
  '��' => '攦',
  '��' => '攢',
  '��' => '欋',
  '��' => '欈',
  '��' => '欉',
  '��' => '氍',
  '��' => '灕',
  '��' => '灖',
  '��' => '灗',
  '��' => '灒',
  '��' => '爞',
  '��' => '爟',
  '��' => '犩',
  '��' => '獿',
  '��' => '瓘',
  '��' => '瓕',
  '��' => '瓙',
  '��' => '瓗',
  '��' => '癭',
  '��' => '皭',
  '��' => '礵',
  '��' => '禴',
  '��' => '穰',
  '��' => '穱',
  '��' => '籗',
  '��' => '籜',
  '��' => '籙',
  '��' => '籛',
  '��' => '籚',
  '�@' => '糴',
  '�A' => '糱',
  '�B' => '纑',
  '�C' => '罏',
  '�D' => '羇',
  '�E' => '臞',
  '�F' => '艫',
  '�G' => '蘴',
  '�H' => '蘵',
  '�I' => '蘳',
  '�J' => '蘬',
  '�K' => '蘲',
  '�L' => '蘶',
  '�M' => '蠬',
  '�N' => '蠨',
  '�O' => '蠦',
  '�P' => '蠪',
  '�Q' => '蠥',
  '�R' => '襱',
  '�S' => '覿',
  '�T' => '覾',
  '�U' => '觻',
  '�V' => '譾',
  '�W' => '讄',
  '�X' => '讂',
  '�Y' => '讆',
  '�Z' => '讅',
  '�[' => '譿',
  '�\\' => '贕',
  '�]' => '躕',
  '�^' => '躔',
  '�_' => '躚',
  '�`' => '躒',
  '�a' => '躐',
  '�b' => '躖',
  '�c' => '躗',
  '�d' => '轠',
  '�e' => '轢',
  '�f' => '酇',
  '�g' => '鑌',
  '�h' => '鑐',
  '�i' => '鑊',
  '�j' => '鑋',
  '�k' => '鑏',
  '�l' => '鑇',
  '�m' => '鑅',
  '�n' => '鑈',
  '�o' => '鑉',
  '�p' => '鑆',
  '�q' => '霿',
  '�r' => '韣',
  '�s' => '顪',
  '�t' => '顩',
  '�u' => '飋',
  '�v' => '饔',
  '�w' => '饛',
  '�x' => '驎',
  '�y' => '驓',
  '�z' => '驔',
  '�{' => '驌',
  '�|' => '驏',
  '�}' => '驈',
  '�~' => '驊',
  '��' => '驉',
  '��' => '驒',
  '��' => '驐',
  '��' => '髐',
  '��' => '鬙',
  '��' => '鬫',
  '��' => '鬻',
  '��' => '魖',
  '��' => '魕',
  '��' => '鱆',
  '��' => '鱈',
  '��' => '鰿',
  '��' => '鱄',
  '��' => '鰹',
  '��' => '鰳',
  '��' => '鱁',
  '��' => '鰼',
  '��' => '鰷',
  '��' => '鰴',
  '��' => '鰲',
  '��' => '鰽',
  '��' => '鰶',
  '��' => '鷛',
  '��' => '鷒',
  '��' => '鷞',
  '��' => '鷚',
  '��' => '鷋',
  '��' => '鷐',
  '��' => '鷜',
  '��' => '鷑',
  '��' => '鷟',
  '��' => '鷩',
  '��' => '鷙',
  '��' => '鷘',
  '��' => '鷖',
  '��' => '鷵',
  '��' => '鷕',
  '��' => '鷝',
  '��' => '麶',
  '��' => '黰',
  '��' => '鼵',
  '��' => '鼳',
  '��' => '鼲',
  '��' => '齂',
  '��' => '齫',
  '��' => '龕',
  '��' => '龢',
  '��' => '儽',
  '��' => '劙',
  '��' => '壨',
  '��' => '壧',
  '��' => '奲',
  '��' => '孍',
  '��' => '巘',
  '��' => '蠯',
  '��' => '彏',
  '��' => '戁',
  '��' => '戃',
  '��' => '戄',
  '��' => '攩',
  '��' => '攥',
  '��' => '斖',
  '��' => '曫',
  '��' => '欑',
  '��' => '欒',
  '��' => '欏',
  '��' => '毊',
  '��' => '灛',
  '��' => '灚',
  '��' => '爢',
  '��' => '玂',
  '��' => '玁',
  '��' => '玃',
  '��' => '癰',
  '��' => '矔',
  '��' => '籧',
  '��' => '籦',
  '��' => '纕',
  '��' => '艬',
  '��' => '蘺',
  '��' => '虀',
  '��' => '蘹',
  '��' => '蘼',
  '��' => '蘱',
  '��' => '蘻',
  '��' => '蘾',
  '��' => '蠰',
  '��' => '蠲',
  '��' => '蠮',
  '��' => '蠳',
  '��' => '襶',
  '��' => '襴',
  '��' => '襳',
  '��' => '觾',
  '�@' => '讌',
  '�A' => '讎',
  '�B' => '讋',
  '�C' => '讈',
  '�D' => '豅',
  '�E' => '贙',
  '�F' => '躘',
  '�G' => '轤',
  '�H' => '轣',
  '�I' => '醼',
  '�J' => '鑢',
  '�K' => '鑕',
  '�L' => '鑝',
  '�M' => '鑗',
  '�N' => '鑞',
  '�O' => '韄',
  '�P' => '韅',
  '�Q' => '頀',
  '�R' => '驖',
  '�S' => '驙',
  '�T' => '鬞',
  '�U' => '鬟',
  '�V' => '鬠',
  '�W' => '鱒',
  '�X' => '鱘',
  '�Y' => '鱐',
  '�Z' => '鱊',
  '�[' => '鱍',
  '�\\' => '鱋',
  '�]' => '鱕',
  '�^' => '鱙',
  '�_' => '鱌',
  '�`' => '鱎',
  '�a' => '鷻',
  '�b' => '鷷',
  '�c' => '鷯',
  '�d' => '鷣',
  '�e' => '鷫',
  '�f' => '鷸',
  '�g' => '鷤',
  '�h' => '鷶',
  '�i' => '鷡',
  '�j' => '鷮',
  '�k' => '鷦',
  '�l' => '鷲',
  '�m' => '鷰',
  '�n' => '鷢',
  '�o' => '鷬',
  '�p' => '鷴',
  '�q' => '鷳',
  '�r' => '鷨',
  '�s' => '鷭',
  '�t' => '黂',
  '�u' => '黐',
  '�v' => '黲',
  '�w' => '黳',
  '�x' => '鼆',
  '�y' => '鼜',
  '�z' => '鼸',
  '�{' => '鼷',
  '�|' => '鼶',
  '�}' => '齃',
  '�~' => '齏',
  '��' => '齱',
  '��' => '齰',
  '��' => '齮',
  '��' => '齯',
  '��' => '囓',
  '��' => '囍',
  '��' => '孎',
  '��' => '屭',
  '��' => '攭',
  '��' => '曭',
  '��' => '曮',
  '��' => '欓',
  '��' => '灟',
  '��' => '灡',
  '��' => '灝',
  '��' => '灠',
  '��' => '爣',
  '��' => '瓛',
  '��' => '瓥',
  '��' => '矕',
  '��' => '礸',
  '��' => '禷',
  '��' => '禶',
  '��' => '籪',
  '��' => '纗',
  '��' => '羉',
  '��' => '艭',
  '��' => '虃',
  '��' => '蠸',
  '��' => '蠷',
  '��' => '蠵',
  '��' => '衋',
  '��' => '讔',
  '��' => '讕',
  '��' => '躞',
  '��' => '躟',
  '��' => '躠',
  '��' => '躝',
  '��' => '醾',
  '��' => '醽',
  '��' => '釂',
  '��' => '鑫',
  '��' => '鑨',
  '��' => '鑩',
  '��' => '雥',
  '��' => '靆',
  '��' => '靃',
  '��' => '靇',
  '��' => '韇',
  '��' => '韥',
  '��' => '驞',
  '��' => '髕',
  '��' => '魙',
  '��' => '鱣',
  '��' => '鱧',
  '��' => '鱦',
  '��' => '鱢',
  '��' => '鱞',
  '��' => '鱠',
  '��' => '鸂',
  '��' => '鷾',
  '��' => '鸇',
  '��' => '鸃',
  '��' => '鸆',
  '��' => '鸅',
  '��' => '鸀',
  '��' => '鸁',
  '��' => '鸉',
  '��' => '鷿',
  '��' => '鷽',
  '��' => '鸄',
  '��' => '麠',
  '��' => '鼞',
  '��' => '齆',
  '��' => '齴',
  '��' => '齵',
  '��' => '齶',
  '��' => '囔',
  '��' => '攮',
  '��' => '斸',
  '��' => '欘',
  '��' => '欙',
  '��' => '欗',
  '��' => '欚',
  '��' => '灢',
  '��' => '爦',
  '��' => '犪',
  '��' => '矘',
  '��' => '矙',
  '��' => '礹',
  '��' => '籩',
  '��' => '籫',
  '��' => '糶',
  '��' => '纚',
  '�@' => '纘',
  '�A' => '纛',
  '�B' => '纙',
  '�C' => '臠',
  '�D' => '臡',
  '�E' => '虆',
  '�F' => '虇',
  '�G' => '虈',
  '�H' => '襹',
  '�I' => '襺',
  '�J' => '襼',
  '�K' => '襻',
  '�L' => '觿',
  '�M' => '讘',
  '�N' => '讙',
  '�O' => '躥',
  '�P' => '躤',
  '�Q' => '躣',
  '�R' => '鑮',
  '�S' => '鑭',
  '�T' => '鑯',
  '�U' => '鑱',
  '�V' => '鑳',
  '�W' => '靉',
  '�X' => '顲',
  '�Y' => '饟',
  '�Z' => '鱨',
  '�[' => '鱮',
  '�\\' => '鱭',
  '�]' => '鸋',
  '�^' => '鸍',
  '�_' => '鸐',
  '�`' => '鸏',
  '�a' => '鸒',
  '�b' => '鸑',
  '�c' => '麡',
  '�d' => '黵',
  '�e' => '鼉',
  '�f' => '齇',
  '�g' => '齸',
  '�h' => '齻',
  '�i' => '齺',
  '�j' => '齹',
  '�k' => '圞',
  '�l' => '灦',
  '�m' => '籯',
  '�n' => '蠼',
  '�o' => '趲',
  '�p' => '躦',
  '�q' => '釃',
  '�r' => '鑴',
  '�s' => '鑸',
  '�t' => '鑶',
  '�u' => '鑵',
  '�v' => '驠',
  '�w' => '鱴',
  '�x' => '鱳',
  '�y' => '鱱',
  '�z' => '鱵',
  '�{' => '鸔',
  '�|' => '鸓',
  '�}' => '黶',
  '�~' => '鼊',
  '��' => '龤',
  '��' => '灨',
  '��' => '灥',
  '��' => '糷',
  '��' => '虪',
  '��' => '蠾',
  '��' => '蠽',
  '��' => '蠿',
  '��' => '讞',
  '��' => '貜',
  '��' => '躩',
  '��' => '軉',
  '��' => '靋',
  '��' => '顳',
  '��' => '顴',
  '��' => '飌',
  '��' => '饡',
  '��' => '馫',
  '��' => '驤',
  '��' => '驦',
  '��' => '驧',
  '��' => '鬤',
  '��' => '鸕',
  '��' => '鸗',
  '��' => '齈',
  '��' => '戇',
  '��' => '欞',
  '��' => '爧',
  '��' => '虌',
  '��' => '躨',
  '��' => '钂',
  '��' => '钀',
  '��' => '钁',
  '��' => '驩',
  '��' => '驨',
  '��' => '鬮',
  '��' => '鸙',
  '��' => '爩',
  '��' => '虋',
  '��' => '讟',
  '��' => '钃',
  '��' => '鱹',
  '��' => '麷',
  '��' => '癵',
  '��' => '驫',
  '��' => '鱺',
  '��' => '鸝',
  '��' => '灩',
  '��' => '灪',
  '��' => '麤',
  '��' => '齾',
  '��' => '齉',
  '��' => '龘',
  '��' => '碁',
  '��' => '銹',
  '��' => '裏',
  '��' => '墻',
  '��' => '恒',
  '��' => '粧',
  '��' => '嫺',
  '��' => '╔',
  '��' => '╦',
  '��' => '╗',
  '��' => '╠',
  '��' => '╬',
  '��' => '╣',
  '��' => '╚',
  '��' => '╩',
  '��' => '╝',
  '��' => '╒',
  '��' => '╤',
  '��' => '╕',
  '��' => '╞',
  '��' => '╪',
  '��' => '╡',
  '��' => '╘',
  '��' => '╧',
  '��' => '╛',
  '��' => '╓',
  '��' => '╥',
  '��' => '╖',
  '��' => '╟',
  '��' => '╫',
  '��' => '╢',
  '��' => '╙',
  '��' => '╨',
  '��' => '╜',
  '��' => '║',
  '��' => '═',
  '��' => '╭',
  '��' => '╮',
  '��' => '╰',
  '��' => '╯',
  '��' => '▓',
);

$result =& $data;
unset($data);

return $result;
PKϤ$Zz;�7��4polyfill-iconv/Resources/charset/from.iso-8859-1.phpnu�[���<?php

static $data = array (
  '' => '',
  '' => '',
  '' => '',
  '' => '',
  '' => '',
  '' => '',
  '' => '',
  '' => '',
  '' => '',
  '	' => '	',
  '
' => '
',
  '' => '',
  '' => '',
  '
' => '
',
  '' => '',
  '' => '',
  '' => '',
  '' => '',
  '' => '',
  '' => '',
  '' => '',
  '' => '',
  '' => '',
  '' => '',
  '' => '',
  '' => '',
  '' => '',
  '' => '',
  '' => '',
  '' => '',
  '' => '',
  '' => '',
  ' ' => ' ',
  '!' => '!',
  '"' => '"',
  '#' => '#',
  '$' => '$',
  '%' => '%',
  '&' => '&',
  '\'' => '\'',
  '(' => '(',
  ')' => ')',
  '*' => '*',
  '+' => '+',
  ',' => ',',
  '-' => '-',
  '.' => '.',
  '/' => '/',
  0 => '0',
  1 => '1',
  2 => '2',
  3 => '3',
  4 => '4',
  5 => '5',
  6 => '6',
  7 => '7',
  8 => '8',
  9 => '9',
  ':' => ':',
  ';' => ';',
  '<' => '<',
  '=' => '=',
  '>' => '>',
  '?' => '?',
  '@' => '@',
  'A' => 'A',
  'B' => 'B',
  'C' => 'C',
  'D' => 'D',
  'E' => 'E',
  'F' => 'F',
  'G' => 'G',
  'H' => 'H',
  'I' => 'I',
  'J' => 'J',
  'K' => 'K',
  'L' => 'L',
  'M' => 'M',
  'N' => 'N',
  'O' => 'O',
  'P' => 'P',
  'Q' => 'Q',
  'R' => 'R',
  'S' => 'S',
  'T' => 'T',
  'U' => 'U',
  'V' => 'V',
  'W' => 'W',
  'X' => 'X',
  'Y' => 'Y',
  'Z' => 'Z',
  '[' => '[',
  '\\' => '\\',
  ']' => ']',
  '^' => '^',
  '_' => '_',
  '`' => '`',
  'a' => 'a',
  'b' => 'b',
  'c' => 'c',
  'd' => 'd',
  'e' => 'e',
  'f' => 'f',
  'g' => 'g',
  'h' => 'h',
  'i' => 'i',
  'j' => 'j',
  'k' => 'k',
  'l' => 'l',
  'm' => 'm',
  'n' => 'n',
  'o' => 'o',
  'p' => 'p',
  'q' => 'q',
  'r' => 'r',
  's' => 's',
  't' => 't',
  'u' => 'u',
  'v' => 'v',
  'w' => 'w',
  'x' => 'x',
  'y' => 'y',
  'z' => 'z',
  '{' => '{',
  '|' => '|',
  '}' => '}',
  '~' => '~',
  '' => '',
  '�' => '€',
  '�' => '',
  '�' => '‚',
  '�' => 'ƒ',
  '�' => '„',
  '�' => '…',
  '�' => '†',
  '�' => '‡',
  '�' => 'ˆ',
  '�' => '‰',
  '�' => 'Š',
  '�' => '‹',
  '�' => 'Œ',
  '�' => '',
  '�' => 'Ž',
  '�' => '',
  '�' => '',
  '�' => '‘',
  '�' => '’',
  '�' => '“',
  '�' => '”',
  '�' => '•',
  '�' => '–',
  '�' => '—',
  '�' => '˜',
  '�' => '™',
  '�' => 'š',
  '�' => '›',
  '�' => 'œ',
  '�' => '',
  '�' => 'ž',
  '�' => 'Ÿ',
  '�' => ' ',
  '�' => '¡',
  '�' => '¢',
  '�' => '£',
  '�' => '¤',
  '�' => '¥',
  '�' => '¦',
  '�' => '§',
  '�' => '¨',
  '�' => '©',
  '�' => 'ª',
  '�' => '«',
  '�' => '¬',
  '�' => '­',
  '�' => '®',
  '�' => '¯',
  '�' => '°',
  '�' => '±',
  '�' => '²',
  '�' => '³',
  '�' => '´',
  '�' => 'µ',
  '�' => '¶',
  '�' => '·',
  '�' => '¸',
  '�' => '¹',
  '�' => 'º',
  '�' => '»',
  '�' => '¼',
  '�' => '½',
  '�' => '¾',
  '�' => '¿',
  '�' => 'À',
  '�' => 'Á',
  '�' => 'Â',
  '�' => 'Ã',
  '�' => 'Ä',
  '�' => 'Å',
  '�' => 'Æ',
  '�' => 'Ç',
  '�' => 'È',
  '�' => 'É',
  '�' => 'Ê',
  '�' => 'Ë',
  '�' => 'Ì',
  '�' => 'Í',
  '�' => 'Î',
  '�' => 'Ï',
  '�' => 'Ð',
  '�' => 'Ñ',
  '�' => 'Ò',
  '�' => 'Ó',
  '�' => 'Ô',
  '�' => 'Õ',
  '�' => 'Ö',
  '�' => '×',
  '�' => 'Ø',
  '�' => 'Ù',
  '�' => 'Ú',
  '�' => 'Û',
  '�' => 'Ü',
  '�' => 'Ý',
  '�' => 'Þ',
  '�' => 'ß',
  '�' => 'à',
  '�' => 'á',
  '�' => 'â',
  '�' => 'ã',
  '�' => 'ä',
  '�' => 'å',
  '�' => 'æ',
  '�' => 'ç',
  '�' => 'è',
  '�' => 'é',
  '�' => 'ê',
  '�' => 'ë',
  '�' => 'ì',
  '�' => 'í',
  '�' => 'î',
  '�' => 'ï',
  '�' => 'ð',
  '�' => 'ñ',
  '�' => 'ò',
  '�' => 'ó',
  '�' => 'ô',
  '�' => 'õ',
  '�' => 'ö',
  '�' => '÷',
  '�' => 'ø',
  '�' => 'ù',
  '�' => 'ú',
  '�' => 'û',
  '�' => 'ü',
  '�' => 'ý',
  '�' => 'þ',
  '�' => 'ÿ',
);

$result =& $data;
unset($data);

return $result;
PKϤ$Zg�CG��/polyfill-iconv/Resources/charset/from.cp932.phpnu�[���<?php

static $data = array (
  '' => '',
  '' => '',
  '' => '',
  '' => '',
  '' => '',
  '' => '',
  '' => '',
  '' => '',
  '' => '',
  '	' => '	',
  '
' => '
',
  '' => '',
  '' => '',
  '
' => '
',
  '' => '',
  '' => '',
  '' => '',
  '' => '',
  '' => '',
  '' => '',
  '' => '',
  '' => '',
  '' => '',
  '' => '',
  '' => '',
  '' => '',
  '' => '',
  '' => '',
  '' => '',
  '' => '',
  '' => '',
  '' => '',
  ' ' => ' ',
  '!' => '!',
  '"' => '"',
  '#' => '#',
  '$' => '$',
  '%' => '%',
  '&' => '&',
  '\'' => '\'',
  '(' => '(',
  ')' => ')',
  '*' => '*',
  '+' => '+',
  ',' => ',',
  '-' => '-',
  '.' => '.',
  '/' => '/',
  0 => '0',
  1 => '1',
  2 => '2',
  3 => '3',
  4 => '4',
  5 => '5',
  6 => '6',
  7 => '7',
  8 => '8',
  9 => '9',
  ':' => ':',
  ';' => ';',
  '<' => '<',
  '=' => '=',
  '>' => '>',
  '?' => '?',
  '@' => '@',
  'A' => 'A',
  'B' => 'B',
  'C' => 'C',
  'D' => 'D',
  'E' => 'E',
  'F' => 'F',
  'G' => 'G',
  'H' => 'H',
  'I' => 'I',
  'J' => 'J',
  'K' => 'K',
  'L' => 'L',
  'M' => 'M',
  'N' => 'N',
  'O' => 'O',
  'P' => 'P',
  'Q' => 'Q',
  'R' => 'R',
  'S' => 'S',
  'T' => 'T',
  'U' => 'U',
  'V' => 'V',
  'W' => 'W',
  'X' => 'X',
  'Y' => 'Y',
  'Z' => 'Z',
  '[' => '[',
  '\\' => '\\',
  ']' => ']',
  '^' => '^',
  '_' => '_',
  '`' => '`',
  'a' => 'a',
  'b' => 'b',
  'c' => 'c',
  'd' => 'd',
  'e' => 'e',
  'f' => 'f',
  'g' => 'g',
  'h' => 'h',
  'i' => 'i',
  'j' => 'j',
  'k' => 'k',
  'l' => 'l',
  'm' => 'm',
  'n' => 'n',
  'o' => 'o',
  'p' => 'p',
  'q' => 'q',
  'r' => 'r',
  's' => 's',
  't' => 't',
  'u' => 'u',
  'v' => 'v',
  'w' => 'w',
  'x' => 'x',
  'y' => 'y',
  'z' => 'z',
  '{' => '{',
  '|' => '|',
  '}' => '}',
  '~' => '~',
  '' => '',
  '�' => '。',
  '�' => '「',
  '�' => '」',
  '�' => '、',
  '�' => '・',
  '�' => 'ヲ',
  '�' => 'ァ',
  '�' => 'ィ',
  '�' => 'ゥ',
  '�' => 'ェ',
  '�' => 'ォ',
  '�' => 'ャ',
  '�' => 'ュ',
  '�' => 'ョ',
  '�' => 'ッ',
  '�' => 'ー',
  '�' => 'ア',
  '�' => 'イ',
  '�' => 'ウ',
  '�' => 'エ',
  '�' => 'オ',
  '�' => 'カ',
  '�' => 'キ',
  '�' => 'ク',
  '�' => 'ケ',
  '�' => 'コ',
  '�' => 'サ',
  '�' => 'シ',
  '�' => 'ス',
  '�' => 'セ',
  '�' => 'ソ',
  '�' => 'タ',
  '�' => 'チ',
  '�' => 'ツ',
  '�' => 'テ',
  '�' => 'ト',
  '�' => 'ナ',
  '�' => 'ニ',
  '�' => 'ヌ',
  '�' => 'ネ',
  '�' => 'ノ',
  '�' => 'ハ',
  '�' => 'ヒ',
  '�' => 'フ',
  '�' => 'ヘ',
  '�' => 'ホ',
  '�' => 'マ',
  '�' => 'ミ',
  '�' => 'ム',
  '�' => 'メ',
  '�' => 'モ',
  '�' => 'ヤ',
  '�' => 'ユ',
  '�' => 'ヨ',
  '�' => 'ラ',
  '�' => 'リ',
  '�' => 'ル',
  '�' => 'レ',
  '�' => 'ロ',
  '�' => 'ワ',
  '�' => 'ン',
  '�' => '゙',
  '�' => '゚',
  '�@' => ' ',
  '�A' => '、',
  '�B' => '。',
  '�C' => ',',
  '�D' => '.',
  '�E' => '・',
  '�F' => ':',
  '�G' => ';',
  '�H' => '?',
  '�I' => '!',
  '�J' => '゛',
  '�K' => '゜',
  '�L' => '´',
  '�M' => '`',
  '�N' => '¨',
  '�O' => '^',
  '�P' => ' ̄',
  '�Q' => '_',
  '�R' => 'ヽ',
  '�S' => 'ヾ',
  '�T' => 'ゝ',
  '�U' => 'ゞ',
  '�V' => '〃',
  '�W' => '仝',
  '�X' => '々',
  '�Y' => '〆',
  '�Z' => '〇',
  '�[' => 'ー',
  '�\\' => '―',
  '�]' => '‐',
  '�^' => '/',
  '�_' => '\',
  '�`' => '~',
  '�a' => '∥',
  '�b' => '|',
  '�c' => '…',
  '�d' => '‥',
  '�e' => '‘',
  '�f' => '’',
  '�g' => '“',
  '�h' => '”',
  '�i' => '(',
  '�j' => ')',
  '�k' => '〔',
  '�l' => '〕',
  '�m' => '[',
  '�n' => ']',
  '�o' => '{',
  '�p' => '}',
  '�q' => '〈',
  '�r' => '〉',
  '�s' => '《',
  '�t' => '》',
  '�u' => '「',
  '�v' => '」',
  '�w' => '『',
  '�x' => '』',
  '�y' => '【',
  '�z' => '】',
  '�{' => '+',
  '�|' => '-',
  '�}' => '±',
  '�~' => '×',
  '��' => '÷',
  '��' => '=',
  '��' => '≠',
  '��' => '<',
  '��' => '>',
  '��' => '≦',
  '��' => '≧',
  '��' => '∞',
  '��' => '∴',
  '��' => '♂',
  '��' => '♀',
  '��' => '°',
  '��' => '′',
  '��' => '″',
  '��' => '℃',
  '��' => '¥',
  '��' => '$',
  '��' => '¢',
  '��' => '£',
  '��' => '%',
  '��' => '#',
  '��' => '&',
  '��' => '*',
  '��' => '@',
  '��' => '§',
  '��' => '☆',
  '��' => '★',
  '��' => '○',
  '��' => '●',
  '��' => '◎',
  '��' => '◇',
  '��' => '◆',
  '��' => '□',
  '��' => '■',
  '��' => '△',
  '��' => '▲',
  '��' => '▽',
  '��' => '▼',
  '��' => '※',
  '��' => '〒',
  '��' => '→',
  '��' => '←',
  '��' => '↑',
  '��' => '↓',
  '��' => '〓',
  '��' => '∈',
  '��' => '∋',
  '��' => '⊆',
  '��' => '⊇',
  '��' => '⊂',
  '��' => '⊃',
  '��' => '∪',
  '��' => '∩',
  '��' => '∧',
  '��' => '∨',
  '��' => '¬',
  '��' => '⇒',
  '��' => '⇔',
  '��' => '∀',
  '��' => '∃',
  '��' => '∠',
  '��' => '⊥',
  '��' => '⌒',
  '��' => '∂',
  '��' => '∇',
  '��' => '≡',
  '��' => '≒',
  '��' => '≪',
  '��' => '≫',
  '��' => '√',
  '��' => '∽',
  '��' => '∝',
  '��' => '∵',
  '��' => '∫',
  '��' => '∬',
  '��' => 'Å',
  '��' => '‰',
  '��' => '♯',
  '��' => '♭',
  '��' => '♪',
  '��' => '†',
  '��' => '‡',
  '��' => '¶',
  '��' => '◯',
  '�O' => '0',
  '�P' => '1',
  '�Q' => '2',
  '�R' => '3',
  '�S' => '4',
  '�T' => '5',
  '�U' => '6',
  '�V' => '7',
  '�W' => '8',
  '�X' => '9',
  '�`' => 'A',
  '�a' => 'B',
  '�b' => 'C',
  '�c' => 'D',
  '�d' => 'E',
  '�e' => 'F',
  '�f' => 'G',
  '�g' => 'H',
  '�h' => 'I',
  '�i' => 'J',
  '�j' => 'K',
  '�k' => 'L',
  '�l' => 'M',
  '�m' => 'N',
  '�n' => 'O',
  '�o' => 'P',
  '�p' => 'Q',
  '�q' => 'R',
  '�r' => 'S',
  '�s' => 'T',
  '�t' => 'U',
  '�u' => 'V',
  '�v' => 'W',
  '�w' => 'X',
  '�x' => 'Y',
  '�y' => 'Z',
  '��' => 'a',
  '��' => 'b',
  '��' => 'c',
  '��' => 'd',
  '��' => 'e',
  '��' => 'f',
  '��' => 'g',
  '��' => 'h',
  '��' => 'i',
  '��' => 'j',
  '��' => 'k',
  '��' => 'l',
  '��' => 'm',
  '��' => 'n',
  '��' => 'o',
  '��' => 'p',
  '��' => 'q',
  '��' => 'r',
  '��' => 's',
  '��' => 't',
  '��' => 'u',
  '��' => 'v',
  '��' => 'w',
  '��' => 'x',
  '��' => 'y',
  '��' => 'z',
  '��' => 'ぁ',
  '��' => 'あ',
  '��' => 'ぃ',
  '��' => 'い',
  '��' => 'ぅ',
  '��' => 'う',
  '��' => 'ぇ',
  '��' => 'え',
  '��' => 'ぉ',
  '��' => 'お',
  '��' => 'か',
  '��' => 'が',
  '��' => 'き',
  '��' => 'ぎ',
  '��' => 'く',
  '��' => 'ぐ',
  '��' => 'け',
  '��' => 'げ',
  '��' => 'こ',
  '��' => 'ご',
  '��' => 'さ',
  '��' => 'ざ',
  '��' => 'し',
  '��' => 'じ',
  '��' => 'す',
  '��' => 'ず',
  '��' => 'せ',
  '��' => 'ぜ',
  '��' => 'そ',
  '��' => 'ぞ',
  '��' => 'た',
  '��' => 'だ',
  '��' => 'ち',
  '��' => 'ぢ',
  '��' => 'っ',
  '��' => 'つ',
  '��' => 'づ',
  '��' => 'て',
  '��' => 'で',
  '��' => 'と',
  '��' => 'ど',
  '��' => 'な',
  '��' => 'に',
  '��' => 'ぬ',
  '��' => 'ね',
  '��' => 'の',
  '��' => 'は',
  '��' => 'ば',
  '��' => 'ぱ',
  '��' => 'ひ',
  '��' => 'び',
  '��' => 'ぴ',
  '��' => 'ふ',
  '��' => 'ぶ',
  '��' => 'ぷ',
  '��' => 'へ',
  '��' => 'べ',
  '��' => 'ぺ',
  '��' => 'ほ',
  '��' => 'ぼ',
  '��' => 'ぽ',
  '��' => 'ま',
  '��' => 'み',
  '��' => 'む',
  '��' => 'め',
  '��' => 'も',
  '��' => 'ゃ',
  '��' => 'や',
  '��' => 'ゅ',
  '��' => 'ゆ',
  '��' => 'ょ',
  '��' => 'よ',
  '��' => 'ら',
  '��' => 'り',
  '��' => 'る',
  '��' => 'れ',
  '��' => 'ろ',
  '��' => 'ゎ',
  '��' => 'わ',
  '��' => 'ゐ',
  '��' => 'ゑ',
  '��' => 'を',
  '��' => 'ん',
  '�@' => 'ァ',
  '�A' => 'ア',
  '�B' => 'ィ',
  '�C' => 'イ',
  '�D' => 'ゥ',
  '�E' => 'ウ',
  '�F' => 'ェ',
  '�G' => 'エ',
  '�H' => 'ォ',
  '�I' => 'オ',
  '�J' => 'カ',
  '�K' => 'ガ',
  '�L' => 'キ',
  '�M' => 'ギ',
  '�N' => 'ク',
  '�O' => 'グ',
  '�P' => 'ケ',
  '�Q' => 'ゲ',
  '�R' => 'コ',
  '�S' => 'ゴ',
  '�T' => 'サ',
  '�U' => 'ザ',
  '�V' => 'シ',
  '�W' => 'ジ',
  '�X' => 'ス',
  '�Y' => 'ズ',
  '�Z' => 'セ',
  '�[' => 'ゼ',
  '�\\' => 'ソ',
  '�]' => 'ゾ',
  '�^' => 'タ',
  '�_' => 'ダ',
  '�`' => 'チ',
  '�a' => 'ヂ',
  '�b' => 'ッ',
  '�c' => 'ツ',
  '�d' => 'ヅ',
  '�e' => 'テ',
  '�f' => 'デ',
  '�g' => 'ト',
  '�h' => 'ド',
  '�i' => 'ナ',
  '�j' => 'ニ',
  '�k' => 'ヌ',
  '�l' => 'ネ',
  '�m' => 'ノ',
  '�n' => 'ハ',
  '�o' => 'バ',
  '�p' => 'パ',
  '�q' => 'ヒ',
  '�r' => 'ビ',
  '�s' => 'ピ',
  '�t' => 'フ',
  '�u' => 'ブ',
  '�v' => 'プ',
  '�w' => 'ヘ',
  '�x' => 'ベ',
  '�y' => 'ペ',
  '�z' => 'ホ',
  '�{' => 'ボ',
  '�|' => 'ポ',
  '�}' => 'マ',
  '�~' => 'ミ',
  '��' => 'ム',
  '��' => 'メ',
  '��' => 'モ',
  '��' => 'ャ',
  '��' => 'ヤ',
  '��' => 'ュ',
  '��' => 'ユ',
  '��' => 'ョ',
  '��' => 'ヨ',
  '��' => 'ラ',
  '��' => 'リ',
  '��' => 'ル',
  '��' => 'レ',
  '��' => 'ロ',
  '��' => 'ヮ',
  '��' => 'ワ',
  '��' => 'ヰ',
  '��' => 'ヱ',
  '��' => 'ヲ',
  '��' => 'ン',
  '��' => 'ヴ',
  '��' => 'ヵ',
  '��' => 'ヶ',
  '��' => 'Α',
  '��' => 'Β',
  '��' => 'Γ',
  '��' => 'Δ',
  '��' => 'Ε',
  '��' => 'Ζ',
  '��' => 'Η',
  '��' => 'Θ',
  '��' => 'Ι',
  '��' => 'Κ',
  '��' => 'Λ',
  '��' => 'Μ',
  '��' => 'Ν',
  '��' => 'Ξ',
  '��' => 'Ο',
  '��' => 'Π',
  '��' => 'Ρ',
  '��' => 'Σ',
  '��' => 'Τ',
  '��' => 'Υ',
  '��' => 'Φ',
  '��' => 'Χ',
  '��' => 'Ψ',
  '��' => 'Ω',
  '��' => 'α',
  '��' => 'β',
  '��' => 'γ',
  '��' => 'δ',
  '��' => 'ε',
  '��' => 'ζ',
  '��' => 'η',
  '��' => 'θ',
  '��' => 'ι',
  '��' => 'κ',
  '��' => 'λ',
  '��' => 'μ',
  '��' => 'ν',
  '��' => 'ξ',
  '��' => 'ο',
  '��' => 'π',
  '��' => 'ρ',
  '��' => 'σ',
  '��' => 'τ',
  '��' => 'υ',
  '��' => 'φ',
  '��' => 'χ',
  '��' => 'ψ',
  '��' => 'ω',
  '�@' => 'А',
  '�A' => 'Б',
  '�B' => 'В',
  '�C' => 'Г',
  '�D' => 'Д',
  '�E' => 'Е',
  '�F' => 'Ё',
  '�G' => 'Ж',
  '�H' => 'З',
  '�I' => 'И',
  '�J' => 'Й',
  '�K' => 'К',
  '�L' => 'Л',
  '�M' => 'М',
  '�N' => 'Н',
  '�O' => 'О',
  '�P' => 'П',
  '�Q' => 'Р',
  '�R' => 'С',
  '�S' => 'Т',
  '�T' => 'У',
  '�U' => 'Ф',
  '�V' => 'Х',
  '�W' => 'Ц',
  '�X' => 'Ч',
  '�Y' => 'Ш',
  '�Z' => 'Щ',
  '�[' => 'Ъ',
  '�\\' => 'Ы',
  '�]' => 'Ь',
  '�^' => 'Э',
  '�_' => 'Ю',
  '�`' => 'Я',
  '�p' => 'а',
  '�q' => 'б',
  '�r' => 'в',
  '�s' => 'г',
  '�t' => 'д',
  '�u' => 'е',
  '�v' => 'ё',
  '�w' => 'ж',
  '�x' => 'з',
  '�y' => 'и',
  '�z' => 'й',
  '�{' => 'к',
  '�|' => 'л',
  '�}' => 'м',
  '�~' => 'н',
  '��' => 'о',
  '��' => 'п',
  '��' => 'р',
  '��' => 'с',
  '��' => 'т',
  '��' => 'у',
  '��' => 'ф',
  '��' => 'х',
  '��' => 'ц',
  '��' => 'ч',
  '��' => 'ш',
  '��' => 'щ',
  '��' => 'ъ',
  '��' => 'ы',
  '��' => 'ь',
  '��' => 'э',
  '��' => 'ю',
  '��' => 'я',
  '��' => '─',
  '��' => '│',
  '��' => '┌',
  '��' => '┐',
  '��' => '┘',
  '��' => '└',
  '��' => '├',
  '��' => '┬',
  '��' => '┤',
  '��' => '┴',
  '��' => '┼',
  '��' => '━',
  '��' => '┃',
  '��' => '┏',
  '��' => '┓',
  '��' => '┛',
  '��' => '┗',
  '��' => '┣',
  '��' => '┳',
  '��' => '┫',
  '��' => '┻',
  '��' => '╋',
  '��' => '┠',
  '��' => '┯',
  '��' => '┨',
  '��' => '┷',
  '��' => '┿',
  '��' => '┝',
  '��' => '┰',
  '��' => '┥',
  '��' => '┸',
  '��' => '╂',
  '�@' => '①',
  '�A' => '②',
  '�B' => '③',
  '�C' => '④',
  '�D' => '⑤',
  '�E' => '⑥',
  '�F' => '⑦',
  '�G' => '⑧',
  '�H' => '⑨',
  '�I' => '⑩',
  '�J' => '⑪',
  '�K' => '⑫',
  '�L' => '⑬',
  '�M' => '⑭',
  '�N' => '⑮',
  '�O' => '⑯',
  '�P' => '⑰',
  '�Q' => '⑱',
  '�R' => '⑲',
  '�S' => '⑳',
  '�T' => 'Ⅰ',
  '�U' => 'Ⅱ',
  '�V' => 'Ⅲ',
  '�W' => 'Ⅳ',
  '�X' => 'Ⅴ',
  '�Y' => 'Ⅵ',
  '�Z' => 'Ⅶ',
  '�[' => 'Ⅷ',
  '�\\' => 'Ⅸ',
  '�]' => 'Ⅹ',
  '�_' => '㍉',
  '�`' => '㌔',
  '�a' => '㌢',
  '�b' => '㍍',
  '�c' => '㌘',
  '�d' => '㌧',
  '�e' => '㌃',
  '�f' => '㌶',
  '�g' => '㍑',
  '�h' => '㍗',
  '�i' => '㌍',
  '�j' => '㌦',
  '�k' => '㌣',
  '�l' => '㌫',
  '�m' => '㍊',
  '�n' => '㌻',
  '�o' => '㎜',
  '�p' => '㎝',
  '�q' => '㎞',
  '�r' => '㎎',
  '�s' => '㎏',
  '�t' => '㏄',
  '�u' => '㎡',
  '�~' => '㍻',
  '��' => '〝',
  '��' => '〟',
  '��' => '№',
  '��' => '㏍',
  '��' => '℡',
  '��' => '㊤',
  '��' => '㊥',
  '��' => '㊦',
  '��' => '㊧',
  '��' => '㊨',
  '��' => '㈱',
  '��' => '㈲',
  '��' => '㈹',
  '��' => '㍾',
  '��' => '㍽',
  '��' => '㍼',
  '��' => '≒',
  '��' => '≡',
  '��' => '∫',
  '��' => '∮',
  '��' => '∑',
  '��' => '√',
  '��' => '⊥',
  '��' => '∠',
  '��' => '∟',
  '��' => '⊿',
  '��' => '∵',
  '��' => '∩',
  '��' => '∪',
  '��' => '亜',
  '��' => '唖',
  '��' => '娃',
  '��' => '阿',
  '��' => '哀',
  '��' => '愛',
  '��' => '挨',
  '��' => '姶',
  '��' => '逢',
  '��' => '葵',
  '��' => '茜',
  '��' => '穐',
  '��' => '悪',
  '��' => '握',
  '��' => '渥',
  '��' => '旭',
  '��' => '葦',
  '��' => '芦',
  '��' => '鯵',
  '��' => '梓',
  '��' => '圧',
  '��' => '斡',
  '��' => '扱',
  '��' => '宛',
  '��' => '姐',
  '��' => '虻',
  '��' => '飴',
  '��' => '絢',
  '��' => '綾',
  '��' => '鮎',
  '��' => '或',
  '��' => '粟',
  '��' => '袷',
  '��' => '安',
  '��' => '庵',
  '��' => '按',
  '��' => '暗',
  '��' => '案',
  '��' => '闇',
  '��' => '鞍',
  '��' => '杏',
  '��' => '以',
  '��' => '伊',
  '��' => '位',
  '��' => '依',
  '��' => '偉',
  '��' => '囲',
  '��' => '夷',
  '��' => '委',
  '��' => '威',
  '��' => '尉',
  '��' => '惟',
  '��' => '意',
  '��' => '慰',
  '��' => '易',
  '��' => '椅',
  '��' => '為',
  '��' => '畏',
  '��' => '異',
  '��' => '移',
  '��' => '維',
  '��' => '緯',
  '��' => '胃',
  '��' => '萎',
  '��' => '衣',
  '��' => '謂',
  '��' => '違',
  '��' => '遺',
  '��' => '医',
  '��' => '井',
  '��' => '亥',
  '��' => '域',
  '��' => '育',
  '��' => '郁',
  '��' => '磯',
  '��' => '一',
  '��' => '壱',
  '��' => '溢',
  '��' => '逸',
  '��' => '稲',
  '��' => '茨',
  '��' => '芋',
  '��' => '鰯',
  '��' => '允',
  '��' => '印',
  '��' => '咽',
  '��' => '員',
  '��' => '因',
  '��' => '姻',
  '��' => '引',
  '��' => '飲',
  '��' => '淫',
  '��' => '胤',
  '��' => '蔭',
  '�@' => '院',
  '�A' => '陰',
  '�B' => '隠',
  '�C' => '韻',
  '�D' => '吋',
  '�E' => '右',
  '�F' => '宇',
  '�G' => '烏',
  '�H' => '羽',
  '�I' => '迂',
  '�J' => '雨',
  '�K' => '卯',
  '�L' => '鵜',
  '�M' => '窺',
  '�N' => '丑',
  '�O' => '碓',
  '�P' => '臼',
  '�Q' => '渦',
  '�R' => '嘘',
  '�S' => '唄',
  '�T' => '欝',
  '�U' => '蔚',
  '�V' => '鰻',
  '�W' => '姥',
  '�X' => '厩',
  '�Y' => '浦',
  '�Z' => '瓜',
  '�[' => '閏',
  '�\\' => '噂',
  '�]' => '云',
  '�^' => '運',
  '�_' => '雲',
  '�`' => '荏',
  '�a' => '餌',
  '�b' => '叡',
  '�c' => '営',
  '�d' => '嬰',
  '�e' => '影',
  '�f' => '映',
  '�g' => '曳',
  '�h' => '栄',
  '�i' => '永',
  '�j' => '泳',
  '�k' => '洩',
  '�l' => '瑛',
  '�m' => '盈',
  '�n' => '穎',
  '�o' => '頴',
  '�p' => '英',
  '�q' => '衛',
  '�r' => '詠',
  '�s' => '鋭',
  '�t' => '液',
  '�u' => '疫',
  '�v' => '益',
  '�w' => '駅',
  '�x' => '悦',
  '�y' => '謁',
  '�z' => '越',
  '�{' => '閲',
  '�|' => '榎',
  '�}' => '厭',
  '�~' => '円',
  '��' => '園',
  '��' => '堰',
  '��' => '奄',
  '��' => '宴',
  '��' => '延',
  '��' => '怨',
  '��' => '掩',
  '��' => '援',
  '��' => '沿',
  '��' => '演',
  '��' => '炎',
  '��' => '焔',
  '��' => '煙',
  '��' => '燕',
  '��' => '猿',
  '��' => '縁',
  '��' => '艶',
  '��' => '苑',
  '��' => '薗',
  '��' => '遠',
  '��' => '鉛',
  '��' => '鴛',
  '��' => '塩',
  '��' => '於',
  '��' => '汚',
  '��' => '甥',
  '��' => '凹',
  '��' => '央',
  '��' => '奥',
  '��' => '往',
  '��' => '応',
  '��' => '押',
  '��' => '旺',
  '��' => '横',
  '��' => '欧',
  '��' => '殴',
  '��' => '王',
  '��' => '翁',
  '��' => '襖',
  '��' => '鴬',
  '��' => '鴎',
  '��' => '黄',
  '��' => '岡',
  '��' => '沖',
  '��' => '荻',
  '��' => '億',
  '��' => '屋',
  '��' => '憶',
  '��' => '臆',
  '��' => '桶',
  '��' => '牡',
  '��' => '乙',
  '��' => '俺',
  '��' => '卸',
  '��' => '恩',
  '��' => '温',
  '��' => '穏',
  '��' => '音',
  '��' => '下',
  '��' => '化',
  '��' => '仮',
  '��' => '何',
  '��' => '伽',
  '��' => '価',
  '��' => '佳',
  '��' => '加',
  '��' => '可',
  '��' => '嘉',
  '��' => '夏',
  '��' => '嫁',
  '��' => '家',
  '��' => '寡',
  '��' => '科',
  '��' => '暇',
  '��' => '果',
  '��' => '架',
  '��' => '歌',
  '��' => '河',
  '��' => '火',
  '��' => '珂',
  '��' => '禍',
  '��' => '禾',
  '��' => '稼',
  '��' => '箇',
  '��' => '花',
  '��' => '苛',
  '��' => '茄',
  '��' => '荷',
  '��' => '華',
  '��' => '菓',
  '��' => '蝦',
  '��' => '課',
  '��' => '嘩',
  '��' => '貨',
  '��' => '迦',
  '��' => '過',
  '��' => '霞',
  '��' => '蚊',
  '��' => '俄',
  '��' => '峨',
  '��' => '我',
  '��' => '牙',
  '��' => '画',
  '��' => '臥',
  '��' => '芽',
  '��' => '蛾',
  '��' => '賀',
  '��' => '雅',
  '��' => '餓',
  '��' => '駕',
  '��' => '介',
  '��' => '会',
  '��' => '解',
  '��' => '回',
  '��' => '塊',
  '��' => '壊',
  '��' => '廻',
  '��' => '快',
  '��' => '怪',
  '��' => '悔',
  '��' => '恢',
  '��' => '懐',
  '��' => '戒',
  '��' => '拐',
  '��' => '改',
  '�@' => '魁',
  '�A' => '晦',
  '�B' => '械',
  '�C' => '海',
  '�D' => '灰',
  '�E' => '界',
  '�F' => '皆',
  '�G' => '絵',
  '�H' => '芥',
  '�I' => '蟹',
  '�J' => '開',
  '�K' => '階',
  '�L' => '貝',
  '�M' => '凱',
  '�N' => '劾',
  '�O' => '外',
  '�P' => '咳',
  '�Q' => '害',
  '�R' => '崖',
  '�S' => '慨',
  '�T' => '概',
  '�U' => '涯',
  '�V' => '碍',
  '�W' => '蓋',
  '�X' => '街',
  '�Y' => '該',
  '�Z' => '鎧',
  '�[' => '骸',
  '�\\' => '浬',
  '�]' => '馨',
  '�^' => '蛙',
  '�_' => '垣',
  '�`' => '柿',
  '�a' => '蛎',
  '�b' => '鈎',
  '�c' => '劃',
  '�d' => '嚇',
  '�e' => '各',
  '�f' => '廓',
  '�g' => '拡',
  '�h' => '撹',
  '�i' => '格',
  '�j' => '核',
  '�k' => '殻',
  '�l' => '獲',
  '�m' => '確',
  '�n' => '穫',
  '�o' => '覚',
  '�p' => '角',
  '�q' => '赫',
  '�r' => '較',
  '�s' => '郭',
  '�t' => '閣',
  '�u' => '隔',
  '�v' => '革',
  '�w' => '学',
  '�x' => '岳',
  '�y' => '楽',
  '�z' => '額',
  '�{' => '顎',
  '�|' => '掛',
  '�}' => '笠',
  '�~' => '樫',
  '��' => '橿',
  '��' => '梶',
  '��' => '鰍',
  '��' => '潟',
  '��' => '割',
  '��' => '喝',
  '��' => '恰',
  '��' => '括',
  '��' => '活',
  '��' => '渇',
  '��' => '滑',
  '��' => '葛',
  '��' => '褐',
  '��' => '轄',
  '��' => '且',
  '��' => '鰹',
  '��' => '叶',
  '��' => '椛',
  '��' => '樺',
  '��' => '鞄',
  '��' => '株',
  '��' => '兜',
  '��' => '竃',
  '��' => '蒲',
  '��' => '釜',
  '��' => '鎌',
  '��' => '噛',
  '��' => '鴨',
  '��' => '栢',
  '��' => '茅',
  '��' => '萱',
  '��' => '粥',
  '��' => '刈',
  '��' => '苅',
  '��' => '瓦',
  '��' => '乾',
  '��' => '侃',
  '��' => '冠',
  '��' => '寒',
  '��' => '刊',
  '��' => '勘',
  '��' => '勧',
  '��' => '巻',
  '��' => '喚',
  '��' => '堪',
  '��' => '姦',
  '��' => '完',
  '��' => '官',
  '��' => '寛',
  '��' => '干',
  '��' => '幹',
  '��' => '患',
  '��' => '感',
  '��' => '慣',
  '��' => '憾',
  '��' => '換',
  '��' => '敢',
  '��' => '柑',
  '��' => '桓',
  '��' => '棺',
  '��' => '款',
  '��' => '歓',
  '��' => '汗',
  '��' => '漢',
  '��' => '澗',
  '��' => '潅',
  '��' => '環',
  '��' => '甘',
  '��' => '監',
  '��' => '看',
  '��' => '竿',
  '��' => '管',
  '��' => '簡',
  '��' => '緩',
  '��' => '缶',
  '��' => '翰',
  '��' => '肝',
  '��' => '艦',
  '��' => '莞',
  '��' => '観',
  '��' => '諌',
  '��' => '貫',
  '��' => '還',
  '��' => '鑑',
  '��' => '間',
  '��' => '閑',
  '��' => '関',
  '��' => '陥',
  '��' => '韓',
  '��' => '館',
  '��' => '舘',
  '��' => '丸',
  '��' => '含',
  '��' => '岸',
  '��' => '巌',
  '��' => '玩',
  '��' => '癌',
  '��' => '眼',
  '��' => '岩',
  '��' => '翫',
  '��' => '贋',
  '��' => '雁',
  '��' => '頑',
  '��' => '顔',
  '��' => '願',
  '��' => '企',
  '��' => '伎',
  '��' => '危',
  '��' => '喜',
  '��' => '器',
  '��' => '基',
  '��' => '奇',
  '��' => '嬉',
  '��' => '寄',
  '��' => '岐',
  '��' => '希',
  '��' => '幾',
  '��' => '忌',
  '��' => '揮',
  '��' => '机',
  '��' => '旗',
  '��' => '既',
  '��' => '期',
  '��' => '棋',
  '��' => '棄',
  '�@' => '機',
  '�A' => '帰',
  '�B' => '毅',
  '�C' => '気',
  '�D' => '汽',
  '�E' => '畿',
  '�F' => '祈',
  '�G' => '季',
  '�H' => '稀',
  '�I' => '紀',
  '�J' => '徽',
  '�K' => '規',
  '�L' => '記',
  '�M' => '貴',
  '�N' => '起',
  '�O' => '軌',
  '�P' => '輝',
  '�Q' => '飢',
  '�R' => '騎',
  '�S' => '鬼',
  '�T' => '亀',
  '�U' => '偽',
  '�V' => '儀',
  '�W' => '妓',
  '�X' => '宜',
  '�Y' => '戯',
  '�Z' => '技',
  '�[' => '擬',
  '�\\' => '欺',
  '�]' => '犠',
  '�^' => '疑',
  '�_' => '祇',
  '�`' => '義',
  '�a' => '蟻',
  '�b' => '誼',
  '�c' => '議',
  '�d' => '掬',
  '�e' => '菊',
  '�f' => '鞠',
  '�g' => '吉',
  '�h' => '吃',
  '�i' => '喫',
  '�j' => '桔',
  '�k' => '橘',
  '�l' => '詰',
  '�m' => '砧',
  '�n' => '杵',
  '�o' => '黍',
  '�p' => '却',
  '�q' => '客',
  '�r' => '脚',
  '�s' => '虐',
  '�t' => '逆',
  '�u' => '丘',
  '�v' => '久',
  '�w' => '仇',
  '�x' => '休',
  '�y' => '及',
  '�z' => '吸',
  '�{' => '宮',
  '�|' => '弓',
  '�}' => '急',
  '�~' => '救',
  '��' => '朽',
  '��' => '求',
  '��' => '汲',
  '��' => '泣',
  '��' => '灸',
  '��' => '球',
  '��' => '究',
  '��' => '窮',
  '��' => '笈',
  '��' => '級',
  '��' => '糾',
  '��' => '給',
  '��' => '旧',
  '��' => '牛',
  '��' => '去',
  '��' => '居',
  '��' => '巨',
  '��' => '拒',
  '��' => '拠',
  '��' => '挙',
  '��' => '渠',
  '��' => '虚',
  '��' => '許',
  '��' => '距',
  '��' => '鋸',
  '��' => '漁',
  '��' => '禦',
  '��' => '魚',
  '��' => '亨',
  '��' => '享',
  '��' => '京',
  '��' => '供',
  '��' => '侠',
  '��' => '僑',
  '��' => '兇',
  '��' => '競',
  '��' => '共',
  '��' => '凶',
  '��' => '協',
  '��' => '匡',
  '��' => '卿',
  '��' => '叫',
  '��' => '喬',
  '��' => '境',
  '��' => '峡',
  '��' => '強',
  '��' => '彊',
  '��' => '怯',
  '��' => '恐',
  '��' => '恭',
  '��' => '挟',
  '��' => '教',
  '��' => '橋',
  '��' => '況',
  '��' => '狂',
  '��' => '狭',
  '��' => '矯',
  '��' => '胸',
  '��' => '脅',
  '��' => '興',
  '��' => '蕎',
  '��' => '郷',
  '��' => '鏡',
  '��' => '響',
  '��' => '饗',
  '��' => '驚',
  '��' => '仰',
  '��' => '凝',
  '��' => '尭',
  '��' => '暁',
  '��' => '業',
  '��' => '局',
  '��' => '曲',
  '��' => '極',
  '��' => '玉',
  '��' => '桐',
  '��' => '粁',
  '��' => '僅',
  '��' => '勤',
  '��' => '均',
  '��' => '巾',
  '��' => '錦',
  '��' => '斤',
  '��' => '欣',
  '��' => '欽',
  '��' => '琴',
  '��' => '禁',
  '��' => '禽',
  '��' => '筋',
  '��' => '緊',
  '��' => '芹',
  '��' => '菌',
  '��' => '衿',
  '��' => '襟',
  '��' => '謹',
  '��' => '近',
  '��' => '金',
  '��' => '吟',
  '��' => '銀',
  '��' => '九',
  '��' => '倶',
  '��' => '句',
  '��' => '区',
  '��' => '狗',
  '��' => '玖',
  '��' => '矩',
  '��' => '苦',
  '��' => '躯',
  '��' => '駆',
  '��' => '駈',
  '��' => '駒',
  '��' => '具',
  '��' => '愚',
  '��' => '虞',
  '��' => '喰',
  '��' => '空',
  '��' => '偶',
  '��' => '寓',
  '��' => '遇',
  '��' => '隅',
  '��' => '串',
  '��' => '櫛',
  '��' => '釧',
  '��' => '屑',
  '��' => '屈',
  '�@' => '掘',
  '�A' => '窟',
  '�B' => '沓',
  '�C' => '靴',
  '�D' => '轡',
  '�E' => '窪',
  '�F' => '熊',
  '�G' => '隈',
  '�H' => '粂',
  '�I' => '栗',
  '�J' => '繰',
  '�K' => '桑',
  '�L' => '鍬',
  '�M' => '勲',
  '�N' => '君',
  '�O' => '薫',
  '�P' => '訓',
  '�Q' => '群',
  '�R' => '軍',
  '�S' => '郡',
  '�T' => '卦',
  '�U' => '袈',
  '�V' => '祁',
  '�W' => '係',
  '�X' => '傾',
  '�Y' => '刑',
  '�Z' => '兄',
  '�[' => '啓',
  '�\\' => '圭',
  '�]' => '珪',
  '�^' => '型',
  '�_' => '契',
  '�`' => '形',
  '�a' => '径',
  '�b' => '恵',
  '�c' => '慶',
  '�d' => '慧',
  '�e' => '憩',
  '�f' => '掲',
  '�g' => '携',
  '�h' => '敬',
  '�i' => '景',
  '�j' => '桂',
  '�k' => '渓',
  '�l' => '畦',
  '�m' => '稽',
  '�n' => '系',
  '�o' => '経',
  '�p' => '継',
  '�q' => '繋',
  '�r' => '罫',
  '�s' => '茎',
  '�t' => '荊',
  '�u' => '蛍',
  '�v' => '計',
  '�w' => '詣',
  '�x' => '警',
  '�y' => '軽',
  '�z' => '頚',
  '�{' => '鶏',
  '�|' => '芸',
  '�}' => '迎',
  '�~' => '鯨',
  '��' => '劇',
  '��' => '戟',
  '��' => '撃',
  '��' => '激',
  '��' => '隙',
  '��' => '桁',
  '��' => '傑',
  '��' => '欠',
  '��' => '決',
  '��' => '潔',
  '��' => '穴',
  '��' => '結',
  '��' => '血',
  '��' => '訣',
  '��' => '月',
  '��' => '件',
  '��' => '倹',
  '��' => '倦',
  '��' => '健',
  '��' => '兼',
  '��' => '券',
  '��' => '剣',
  '��' => '喧',
  '��' => '圏',
  '��' => '堅',
  '��' => '嫌',
  '��' => '建',
  '��' => '憲',
  '��' => '懸',
  '��' => '拳',
  '��' => '捲',
  '��' => '検',
  '��' => '権',
  '��' => '牽',
  '��' => '犬',
  '��' => '献',
  '��' => '研',
  '��' => '硯',
  '��' => '絹',
  '��' => '県',
  '��' => '肩',
  '��' => '見',
  '��' => '謙',
  '��' => '賢',
  '��' => '軒',
  '��' => '遣',
  '��' => '鍵',
  '��' => '険',
  '��' => '顕',
  '��' => '験',
  '��' => '鹸',
  '��' => '元',
  '��' => '原',
  '��' => '厳',
  '��' => '幻',
  '��' => '弦',
  '��' => '減',
  '��' => '源',
  '��' => '玄',
  '��' => '現',
  '��' => '絃',
  '��' => '舷',
  '��' => '言',
  '��' => '諺',
  '��' => '限',
  '��' => '乎',
  '��' => '個',
  '��' => '古',
  '��' => '呼',
  '��' => '固',
  '��' => '姑',
  '��' => '孤',
  '��' => '己',
  '��' => '庫',
  '��' => '弧',
  '��' => '戸',
  '��' => '故',
  '��' => '枯',
  '��' => '湖',
  '��' => '狐',
  '��' => '糊',
  '��' => '袴',
  '��' => '股',
  '��' => '胡',
  '��' => '菰',
  '��' => '虎',
  '��' => '誇',
  '��' => '跨',
  '��' => '鈷',
  '��' => '雇',
  '��' => '顧',
  '��' => '鼓',
  '��' => '五',
  '��' => '互',
  '��' => '伍',
  '��' => '午',
  '��' => '呉',
  '��' => '吾',
  '��' => '娯',
  '��' => '後',
  '��' => '御',
  '��' => '悟',
  '��' => '梧',
  '��' => '檎',
  '��' => '瑚',
  '��' => '碁',
  '��' => '語',
  '��' => '誤',
  '��' => '護',
  '��' => '醐',
  '��' => '乞',
  '��' => '鯉',
  '��' => '交',
  '��' => '佼',
  '��' => '侯',
  '��' => '候',
  '��' => '倖',
  '��' => '光',
  '��' => '公',
  '��' => '功',
  '��' => '効',
  '��' => '勾',
  '��' => '厚',
  '��' => '口',
  '��' => '向',
  '�@' => '后',
  '�A' => '喉',
  '�B' => '坑',
  '�C' => '垢',
  '�D' => '好',
  '�E' => '孔',
  '�F' => '孝',
  '�G' => '宏',
  '�H' => '工',
  '�I' => '巧',
  '�J' => '巷',
  '�K' => '幸',
  '�L' => '広',
  '�M' => '庚',
  '�N' => '康',
  '�O' => '弘',
  '�P' => '恒',
  '�Q' => '慌',
  '�R' => '抗',
  '�S' => '拘',
  '�T' => '控',
  '�U' => '攻',
  '�V' => '昂',
  '�W' => '晃',
  '�X' => '更',
  '�Y' => '杭',
  '�Z' => '校',
  '�[' => '梗',
  '�\\' => '構',
  '�]' => '江',
  '�^' => '洪',
  '�_' => '浩',
  '�`' => '港',
  '�a' => '溝',
  '�b' => '甲',
  '�c' => '皇',
  '�d' => '硬',
  '�e' => '稿',
  '�f' => '糠',
  '�g' => '紅',
  '�h' => '紘',
  '�i' => '絞',
  '�j' => '綱',
  '�k' => '耕',
  '�l' => '考',
  '�m' => '肯',
  '�n' => '肱',
  '�o' => '腔',
  '�p' => '膏',
  '�q' => '航',
  '�r' => '荒',
  '�s' => '行',
  '�t' => '衡',
  '�u' => '講',
  '�v' => '貢',
  '�w' => '購',
  '�x' => '郊',
  '�y' => '酵',
  '�z' => '鉱',
  '�{' => '砿',
  '�|' => '鋼',
  '�}' => '閤',
  '�~' => '降',
  '��' => '項',
  '��' => '香',
  '��' => '高',
  '��' => '鴻',
  '��' => '剛',
  '��' => '劫',
  '��' => '号',
  '��' => '合',
  '��' => '壕',
  '��' => '拷',
  '��' => '濠',
  '��' => '豪',
  '��' => '轟',
  '��' => '麹',
  '��' => '克',
  '��' => '刻',
  '��' => '告',
  '��' => '国',
  '��' => '穀',
  '��' => '酷',
  '��' => '鵠',
  '��' => '黒',
  '��' => '獄',
  '��' => '漉',
  '��' => '腰',
  '��' => '甑',
  '��' => '忽',
  '��' => '惚',
  '��' => '骨',
  '��' => '狛',
  '��' => '込',
  '��' => '此',
  '��' => '頃',
  '��' => '今',
  '��' => '困',
  '��' => '坤',
  '��' => '墾',
  '��' => '婚',
  '��' => '恨',
  '��' => '懇',
  '��' => '昏',
  '��' => '昆',
  '��' => '根',
  '��' => '梱',
  '��' => '混',
  '��' => '痕',
  '��' => '紺',
  '��' => '艮',
  '��' => '魂',
  '��' => '些',
  '��' => '佐',
  '��' => '叉',
  '��' => '唆',
  '��' => '嵯',
  '��' => '左',
  '��' => '差',
  '��' => '査',
  '��' => '沙',
  '��' => '瑳',
  '��' => '砂',
  '��' => '詐',
  '��' => '鎖',
  '��' => '裟',
  '��' => '坐',
  '��' => '座',
  '��' => '挫',
  '��' => '債',
  '��' => '催',
  '��' => '再',
  '��' => '最',
  '��' => '哉',
  '��' => '塞',
  '��' => '妻',
  '��' => '宰',
  '��' => '彩',
  '��' => '才',
  '��' => '採',
  '��' => '栽',
  '��' => '歳',
  '��' => '済',
  '��' => '災',
  '��' => '采',
  '��' => '犀',
  '��' => '砕',
  '��' => '砦',
  '��' => '祭',
  '��' => '斎',
  '��' => '細',
  '��' => '菜',
  '��' => '裁',
  '��' => '載',
  '��' => '際',
  '��' => '剤',
  '��' => '在',
  '��' => '材',
  '��' => '罪',
  '��' => '財',
  '��' => '冴',
  '��' => '坂',
  '��' => '阪',
  '��' => '堺',
  '��' => '榊',
  '��' => '肴',
  '��' => '咲',
  '��' => '崎',
  '��' => '埼',
  '��' => '碕',
  '��' => '鷺',
  '��' => '作',
  '��' => '削',
  '��' => '咋',
  '��' => '搾',
  '��' => '昨',
  '��' => '朔',
  '��' => '柵',
  '��' => '窄',
  '��' => '策',
  '��' => '索',
  '��' => '錯',
  '��' => '桜',
  '��' => '鮭',
  '��' => '笹',
  '��' => '匙',
  '��' => '冊',
  '��' => '刷',
  '�@' => '察',
  '�A' => '拶',
  '�B' => '撮',
  '�C' => '擦',
  '�D' => '札',
  '�E' => '殺',
  '�F' => '薩',
  '�G' => '雑',
  '�H' => '皐',
  '�I' => '鯖',
  '�J' => '捌',
  '�K' => '錆',
  '�L' => '鮫',
  '�M' => '皿',
  '�N' => '晒',
  '�O' => '三',
  '�P' => '傘',
  '�Q' => '参',
  '�R' => '山',
  '�S' => '惨',
  '�T' => '撒',
  '�U' => '散',
  '�V' => '桟',
  '�W' => '燦',
  '�X' => '珊',
  '�Y' => '産',
  '�Z' => '算',
  '�[' => '纂',
  '�\\' => '蚕',
  '�]' => '讃',
  '�^' => '賛',
  '�_' => '酸',
  '�`' => '餐',
  '�a' => '斬',
  '�b' => '暫',
  '�c' => '残',
  '�d' => '仕',
  '�e' => '仔',
  '�f' => '伺',
  '�g' => '使',
  '�h' => '刺',
  '�i' => '司',
  '�j' => '史',
  '�k' => '嗣',
  '�l' => '四',
  '�m' => '士',
  '�n' => '始',
  '�o' => '姉',
  '�p' => '姿',
  '�q' => '子',
  '�r' => '屍',
  '�s' => '市',
  '�t' => '師',
  '�u' => '志',
  '�v' => '思',
  '�w' => '指',
  '�x' => '支',
  '�y' => '孜',
  '�z' => '斯',
  '�{' => '施',
  '�|' => '旨',
  '�}' => '枝',
  '�~' => '止',
  '��' => '死',
  '��' => '氏',
  '��' => '獅',
  '��' => '祉',
  '��' => '私',
  '��' => '糸',
  '��' => '紙',
  '��' => '紫',
  '��' => '肢',
  '��' => '脂',
  '��' => '至',
  '��' => '視',
  '��' => '詞',
  '��' => '詩',
  '��' => '試',
  '��' => '誌',
  '��' => '諮',
  '��' => '資',
  '��' => '賜',
  '��' => '雌',
  '��' => '飼',
  '��' => '歯',
  '��' => '事',
  '��' => '似',
  '��' => '侍',
  '��' => '児',
  '��' => '字',
  '��' => '寺',
  '��' => '慈',
  '��' => '持',
  '��' => '時',
  '��' => '次',
  '��' => '滋',
  '��' => '治',
  '��' => '爾',
  '��' => '璽',
  '��' => '痔',
  '��' => '磁',
  '��' => '示',
  '��' => '而',
  '��' => '耳',
  '��' => '自',
  '��' => '蒔',
  '��' => '辞',
  '��' => '汐',
  '��' => '鹿',
  '��' => '式',
  '��' => '識',
  '��' => '鴫',
  '��' => '竺',
  '��' => '軸',
  '��' => '宍',
  '��' => '雫',
  '��' => '七',
  '��' => '叱',
  '��' => '執',
  '��' => '失',
  '��' => '嫉',
  '��' => '室',
  '��' => '悉',
  '��' => '湿',
  '��' => '漆',
  '��' => '疾',
  '��' => '質',
  '��' => '実',
  '��' => '蔀',
  '��' => '篠',
  '��' => '偲',
  '��' => '柴',
  '��' => '芝',
  '��' => '屡',
  '��' => '蕊',
  '��' => '縞',
  '��' => '舎',
  '��' => '写',
  '��' => '射',
  '��' => '捨',
  '��' => '赦',
  '��' => '斜',
  '��' => '煮',
  '��' => '社',
  '��' => '紗',
  '��' => '者',
  '��' => '謝',
  '��' => '車',
  '��' => '遮',
  '��' => '蛇',
  '��' => '邪',
  '��' => '借',
  '��' => '勺',
  '��' => '尺',
  '��' => '杓',
  '��' => '灼',
  '��' => '爵',
  '��' => '酌',
  '��' => '釈',
  '��' => '錫',
  '��' => '若',
  '��' => '寂',
  '��' => '弱',
  '��' => '惹',
  '��' => '主',
  '��' => '取',
  '��' => '守',
  '��' => '手',
  '��' => '朱',
  '��' => '殊',
  '��' => '狩',
  '��' => '珠',
  '��' => '種',
  '��' => '腫',
  '��' => '趣',
  '��' => '酒',
  '��' => '首',
  '��' => '儒',
  '��' => '受',
  '��' => '呪',
  '��' => '寿',
  '��' => '授',
  '��' => '樹',
  '��' => '綬',
  '��' => '需',
  '��' => '囚',
  '��' => '収',
  '��' => '周',
  '�@' => '宗',
  '�A' => '就',
  '�B' => '州',
  '�C' => '修',
  '�D' => '愁',
  '�E' => '拾',
  '�F' => '洲',
  '�G' => '秀',
  '�H' => '秋',
  '�I' => '終',
  '�J' => '繍',
  '�K' => '習',
  '�L' => '臭',
  '�M' => '舟',
  '�N' => '蒐',
  '�O' => '衆',
  '�P' => '襲',
  '�Q' => '讐',
  '�R' => '蹴',
  '�S' => '輯',
  '�T' => '週',
  '�U' => '酋',
  '�V' => '酬',
  '�W' => '集',
  '�X' => '醜',
  '�Y' => '什',
  '�Z' => '住',
  '�[' => '充',
  '�\\' => '十',
  '�]' => '従',
  '�^' => '戎',
  '�_' => '柔',
  '�`' => '汁',
  '�a' => '渋',
  '�b' => '獣',
  '�c' => '縦',
  '�d' => '重',
  '�e' => '銃',
  '�f' => '叔',
  '�g' => '夙',
  '�h' => '宿',
  '�i' => '淑',
  '�j' => '祝',
  '�k' => '縮',
  '�l' => '粛',
  '�m' => '塾',
  '�n' => '熟',
  '�o' => '出',
  '�p' => '術',
  '�q' => '述',
  '�r' => '俊',
  '�s' => '峻',
  '�t' => '春',
  '�u' => '瞬',
  '�v' => '竣',
  '�w' => '舜',
  '�x' => '駿',
  '�y' => '准',
  '�z' => '循',
  '�{' => '旬',
  '�|' => '楯',
  '�}' => '殉',
  '�~' => '淳',
  '��' => '準',
  '��' => '潤',
  '��' => '盾',
  '��' => '純',
  '��' => '巡',
  '��' => '遵',
  '��' => '醇',
  '��' => '順',
  '��' => '処',
  '��' => '初',
  '��' => '所',
  '��' => '暑',
  '��' => '曙',
  '��' => '渚',
  '��' => '庶',
  '��' => '緒',
  '��' => '署',
  '��' => '書',
  '��' => '薯',
  '��' => '藷',
  '��' => '諸',
  '��' => '助',
  '��' => '叙',
  '��' => '女',
  '��' => '序',
  '��' => '徐',
  '��' => '恕',
  '��' => '鋤',
  '��' => '除',
  '��' => '傷',
  '��' => '償',
  '��' => '勝',
  '��' => '匠',
  '��' => '升',
  '��' => '召',
  '��' => '哨',
  '��' => '商',
  '��' => '唱',
  '��' => '嘗',
  '��' => '奨',
  '��' => '妾',
  '��' => '娼',
  '��' => '宵',
  '��' => '将',
  '��' => '小',
  '��' => '少',
  '��' => '尚',
  '��' => '庄',
  '��' => '床',
  '��' => '廠',
  '��' => '彰',
  '��' => '承',
  '��' => '抄',
  '��' => '招',
  '��' => '掌',
  '��' => '捷',
  '��' => '昇',
  '��' => '昌',
  '��' => '昭',
  '��' => '晶',
  '��' => '松',
  '��' => '梢',
  '��' => '樟',
  '��' => '樵',
  '��' => '沼',
  '��' => '消',
  '��' => '渉',
  '��' => '湘',
  '��' => '焼',
  '��' => '焦',
  '��' => '照',
  '��' => '症',
  '��' => '省',
  '��' => '硝',
  '��' => '礁',
  '��' => '祥',
  '��' => '称',
  '��' => '章',
  '��' => '笑',
  '��' => '粧',
  '��' => '紹',
  '��' => '肖',
  '��' => '菖',
  '��' => '蒋',
  '��' => '蕉',
  '��' => '衝',
  '��' => '裳',
  '��' => '訟',
  '��' => '証',
  '��' => '詔',
  '��' => '詳',
  '��' => '象',
  '��' => '賞',
  '��' => '醤',
  '��' => '鉦',
  '��' => '鍾',
  '��' => '鐘',
  '��' => '障',
  '��' => '鞘',
  '��' => '上',
  '��' => '丈',
  '��' => '丞',
  '��' => '乗',
  '��' => '冗',
  '��' => '剰',
  '��' => '城',
  '��' => '場',
  '��' => '壌',
  '��' => '嬢',
  '��' => '常',
  '��' => '情',
  '��' => '擾',
  '��' => '条',
  '��' => '杖',
  '��' => '浄',
  '��' => '状',
  '��' => '畳',
  '��' => '穣',
  '��' => '蒸',
  '��' => '譲',
  '��' => '醸',
  '��' => '錠',
  '��' => '嘱',
  '��' => '埴',
  '��' => '飾',
  '�@' => '拭',
  '�A' => '植',
  '�B' => '殖',
  '�C' => '燭',
  '�D' => '織',
  '�E' => '職',
  '�F' => '色',
  '�G' => '触',
  '�H' => '食',
  '�I' => '蝕',
  '�J' => '辱',
  '�K' => '尻',
  '�L' => '伸',
  '�M' => '信',
  '�N' => '侵',
  '�O' => '唇',
  '�P' => '娠',
  '�Q' => '寝',
  '�R' => '審',
  '�S' => '心',
  '�T' => '慎',
  '�U' => '振',
  '�V' => '新',
  '�W' => '晋',
  '�X' => '森',
  '�Y' => '榛',
  '�Z' => '浸',
  '�[' => '深',
  '�\\' => '申',
  '�]' => '疹',
  '�^' => '真',
  '�_' => '神',
  '�`' => '秦',
  '�a' => '紳',
  '�b' => '臣',
  '�c' => '芯',
  '�d' => '薪',
  '�e' => '親',
  '�f' => '診',
  '�g' => '身',
  '�h' => '辛',
  '�i' => '進',
  '�j' => '針',
  '�k' => '震',
  '�l' => '人',
  '�m' => '仁',
  '�n' => '刃',
  '�o' => '塵',
  '�p' => '壬',
  '�q' => '尋',
  '�r' => '甚',
  '�s' => '尽',
  '�t' => '腎',
  '�u' => '訊',
  '�v' => '迅',
  '�w' => '陣',
  '�x' => '靭',
  '�y' => '笥',
  '�z' => '諏',
  '�{' => '須',
  '�|' => '酢',
  '�}' => '図',
  '�~' => '厨',
  '��' => '逗',
  '��' => '吹',
  '��' => '垂',
  '��' => '帥',
  '��' => '推',
  '��' => '水',
  '��' => '炊',
  '��' => '睡',
  '��' => '粋',
  '��' => '翠',
  '��' => '衰',
  '��' => '遂',
  '��' => '酔',
  '��' => '錐',
  '��' => '錘',
  '��' => '随',
  '��' => '瑞',
  '��' => '髄',
  '��' => '崇',
  '��' => '嵩',
  '��' => '数',
  '��' => '枢',
  '��' => '趨',
  '��' => '雛',
  '��' => '据',
  '��' => '杉',
  '��' => '椙',
  '��' => '菅',
  '��' => '頗',
  '��' => '雀',
  '��' => '裾',
  '��' => '澄',
  '��' => '摺',
  '��' => '寸',
  '��' => '世',
  '��' => '瀬',
  '��' => '畝',
  '��' => '是',
  '��' => '凄',
  '��' => '制',
  '��' => '勢',
  '��' => '姓',
  '��' => '征',
  '��' => '性',
  '��' => '成',
  '��' => '政',
  '��' => '整',
  '��' => '星',
  '��' => '晴',
  '��' => '棲',
  '��' => '栖',
  '��' => '正',
  '��' => '清',
  '��' => '牲',
  '��' => '生',
  '��' => '盛',
  '��' => '精',
  '��' => '聖',
  '��' => '声',
  '��' => '製',
  '��' => '西',
  '��' => '誠',
  '��' => '誓',
  '��' => '請',
  '��' => '逝',
  '��' => '醒',
  '��' => '青',
  '��' => '静',
  '��' => '斉',
  '��' => '税',
  '��' => '脆',
  '��' => '隻',
  '��' => '席',
  '��' => '惜',
  '��' => '戚',
  '��' => '斥',
  '��' => '昔',
  '��' => '析',
  '��' => '石',
  '��' => '積',
  '��' => '籍',
  '��' => '績',
  '��' => '脊',
  '��' => '責',
  '��' => '赤',
  '��' => '跡',
  '��' => '蹟',
  '��' => '碩',
  '��' => '切',
  '��' => '拙',
  '��' => '接',
  '��' => '摂',
  '��' => '折',
  '��' => '設',
  '��' => '窃',
  '��' => '節',
  '��' => '説',
  '��' => '雪',
  '��' => '絶',
  '��' => '舌',
  '��' => '蝉',
  '��' => '仙',
  '��' => '先',
  '��' => '千',
  '��' => '占',
  '��' => '宣',
  '��' => '専',
  '��' => '尖',
  '��' => '川',
  '��' => '戦',
  '��' => '扇',
  '��' => '撰',
  '��' => '栓',
  '��' => '栴',
  '��' => '泉',
  '��' => '浅',
  '��' => '洗',
  '��' => '染',
  '��' => '潜',
  '��' => '煎',
  '��' => '煽',
  '��' => '旋',
  '��' => '穿',
  '��' => '箭',
  '��' => '線',
  '�@' => '繊',
  '�A' => '羨',
  '�B' => '腺',
  '�C' => '舛',
  '�D' => '船',
  '�E' => '薦',
  '�F' => '詮',
  '�G' => '賎',
  '�H' => '践',
  '�I' => '選',
  '�J' => '遷',
  '�K' => '銭',
  '�L' => '銑',
  '�M' => '閃',
  '�N' => '鮮',
  '�O' => '前',
  '�P' => '善',
  '�Q' => '漸',
  '�R' => '然',
  '�S' => '全',
  '�T' => '禅',
  '�U' => '繕',
  '�V' => '膳',
  '�W' => '糎',
  '�X' => '噌',
  '�Y' => '塑',
  '�Z' => '岨',
  '�[' => '措',
  '�\\' => '曾',
  '�]' => '曽',
  '�^' => '楚',
  '�_' => '狙',
  '�`' => '疏',
  '�a' => '疎',
  '�b' => '礎',
  '�c' => '祖',
  '�d' => '租',
  '�e' => '粗',
  '�f' => '素',
  '�g' => '組',
  '�h' => '蘇',
  '�i' => '訴',
  '�j' => '阻',
  '�k' => '遡',
  '�l' => '鼠',
  '�m' => '僧',
  '�n' => '創',
  '�o' => '双',
  '�p' => '叢',
  '�q' => '倉',
  '�r' => '喪',
  '�s' => '壮',
  '�t' => '奏',
  '�u' => '爽',
  '�v' => '宋',
  '�w' => '層',
  '�x' => '匝',
  '�y' => '惣',
  '�z' => '想',
  '�{' => '捜',
  '�|' => '掃',
  '�}' => '挿',
  '�~' => '掻',
  '��' => '操',
  '��' => '早',
  '��' => '曹',
  '��' => '巣',
  '��' => '槍',
  '��' => '槽',
  '��' => '漕',
  '��' => '燥',
  '��' => '争',
  '��' => '痩',
  '��' => '相',
  '��' => '窓',
  '��' => '糟',
  '��' => '総',
  '��' => '綜',
  '��' => '聡',
  '��' => '草',
  '��' => '荘',
  '��' => '葬',
  '��' => '蒼',
  '��' => '藻',
  '��' => '装',
  '��' => '走',
  '��' => '送',
  '��' => '遭',
  '��' => '鎗',
  '��' => '霜',
  '��' => '騒',
  '��' => '像',
  '��' => '増',
  '��' => '憎',
  '��' => '臓',
  '��' => '蔵',
  '��' => '贈',
  '��' => '造',
  '��' => '促',
  '��' => '側',
  '��' => '則',
  '��' => '即',
  '��' => '息',
  '��' => '捉',
  '��' => '束',
  '��' => '測',
  '��' => '足',
  '��' => '速',
  '��' => '俗',
  '��' => '属',
  '��' => '賊',
  '��' => '族',
  '��' => '続',
  '��' => '卒',
  '��' => '袖',
  '��' => '其',
  '��' => '揃',
  '��' => '存',
  '��' => '孫',
  '��' => '尊',
  '��' => '損',
  '��' => '村',
  '��' => '遜',
  '��' => '他',
  '��' => '多',
  '��' => '太',
  '��' => '汰',
  '��' => '詑',
  '��' => '唾',
  '��' => '堕',
  '��' => '妥',
  '��' => '惰',
  '��' => '打',
  '��' => '柁',
  '��' => '舵',
  '��' => '楕',
  '��' => '陀',
  '��' => '駄',
  '��' => '騨',
  '��' => '体',
  '��' => '堆',
  '��' => '対',
  '��' => '耐',
  '��' => '岱',
  '��' => '帯',
  '��' => '待',
  '��' => '怠',
  '��' => '態',
  '��' => '戴',
  '��' => '替',
  '��' => '泰',
  '��' => '滞',
  '��' => '胎',
  '��' => '腿',
  '��' => '苔',
  '��' => '袋',
  '��' => '貸',
  '��' => '退',
  '��' => '逮',
  '��' => '隊',
  '��' => '黛',
  '��' => '鯛',
  '��' => '代',
  '��' => '台',
  '��' => '大',
  '��' => '第',
  '��' => '醍',
  '��' => '題',
  '��' => '鷹',
  '��' => '滝',
  '��' => '瀧',
  '��' => '卓',
  '��' => '啄',
  '��' => '宅',
  '��' => '托',
  '��' => '択',
  '��' => '拓',
  '��' => '沢',
  '��' => '濯',
  '��' => '琢',
  '��' => '託',
  '��' => '鐸',
  '��' => '濁',
  '��' => '諾',
  '��' => '茸',
  '��' => '凧',
  '��' => '蛸',
  '��' => '只',
  '�@' => '叩',
  '�A' => '但',
  '�B' => '達',
  '�C' => '辰',
  '�D' => '奪',
  '�E' => '脱',
  '�F' => '巽',
  '�G' => '竪',
  '�H' => '辿',
  '�I' => '棚',
  '�J' => '谷',
  '�K' => '狸',
  '�L' => '鱈',
  '�M' => '樽',
  '�N' => '誰',
  '�O' => '丹',
  '�P' => '単',
  '�Q' => '嘆',
  '�R' => '坦',
  '�S' => '担',
  '�T' => '探',
  '�U' => '旦',
  '�V' => '歎',
  '�W' => '淡',
  '�X' => '湛',
  '�Y' => '炭',
  '�Z' => '短',
  '�[' => '端',
  '�\\' => '箪',
  '�]' => '綻',
  '�^' => '耽',
  '�_' => '胆',
  '�`' => '蛋',
  '�a' => '誕',
  '�b' => '鍛',
  '�c' => '団',
  '�d' => '壇',
  '�e' => '弾',
  '�f' => '断',
  '�g' => '暖',
  '�h' => '檀',
  '�i' => '段',
  '�j' => '男',
  '�k' => '談',
  '�l' => '値',
  '�m' => '知',
  '�n' => '地',
  '�o' => '弛',
  '�p' => '恥',
  '�q' => '智',
  '�r' => '池',
  '�s' => '痴',
  '�t' => '稚',
  '�u' => '置',
  '�v' => '致',
  '�w' => '蜘',
  '�x' => '遅',
  '�y' => '馳',
  '�z' => '築',
  '�{' => '畜',
  '�|' => '竹',
  '�}' => '筑',
  '�~' => '蓄',
  '��' => '逐',
  '��' => '秩',
  '��' => '窒',
  '��' => '茶',
  '��' => '嫡',
  '��' => '着',
  '��' => '中',
  '��' => '仲',
  '��' => '宙',
  '��' => '忠',
  '��' => '抽',
  '��' => '昼',
  '��' => '柱',
  '��' => '注',
  '��' => '虫',
  '��' => '衷',
  '��' => '註',
  '��' => '酎',
  '��' => '鋳',
  '��' => '駐',
  '��' => '樗',
  '��' => '瀦',
  '��' => '猪',
  '��' => '苧',
  '��' => '著',
  '��' => '貯',
  '��' => '丁',
  '��' => '兆',
  '��' => '凋',
  '��' => '喋',
  '��' => '寵',
  '��' => '帖',
  '��' => '帳',
  '��' => '庁',
  '��' => '弔',
  '��' => '張',
  '��' => '彫',
  '��' => '徴',
  '��' => '懲',
  '��' => '挑',
  '��' => '暢',
  '��' => '朝',
  '��' => '潮',
  '��' => '牒',
  '��' => '町',
  '��' => '眺',
  '��' => '聴',
  '��' => '脹',
  '��' => '腸',
  '��' => '蝶',
  '��' => '調',
  '��' => '諜',
  '��' => '超',
  '��' => '跳',
  '��' => '銚',
  '��' => '長',
  '��' => '頂',
  '��' => '鳥',
  '��' => '勅',
  '��' => '捗',
  '��' => '直',
  '��' => '朕',
  '��' => '沈',
  '��' => '珍',
  '��' => '賃',
  '��' => '鎮',
  '��' => '陳',
  '��' => '津',
  '��' => '墜',
  '��' => '椎',
  '��' => '槌',
  '��' => '追',
  '��' => '鎚',
  '��' => '痛',
  '��' => '通',
  '��' => '塚',
  '��' => '栂',
  '��' => '掴',
  '��' => '槻',
  '��' => '佃',
  '��' => '漬',
  '��' => '柘',
  '��' => '辻',
  '��' => '蔦',
  '��' => '綴',
  '��' => '鍔',
  '��' => '椿',
  '��' => '潰',
  '��' => '坪',
  '��' => '壷',
  '��' => '嬬',
  '��' => '紬',
  '��' => '爪',
  '��' => '吊',
  '��' => '釣',
  '��' => '鶴',
  '��' => '亭',
  '��' => '低',
  '��' => '停',
  '��' => '偵',
  '��' => '剃',
  '��' => '貞',
  '��' => '呈',
  '��' => '堤',
  '��' => '定',
  '��' => '帝',
  '��' => '底',
  '��' => '庭',
  '��' => '廷',
  '��' => '弟',
  '��' => '悌',
  '��' => '抵',
  '��' => '挺',
  '��' => '提',
  '��' => '梯',
  '��' => '汀',
  '��' => '碇',
  '��' => '禎',
  '��' => '程',
  '��' => '締',
  '��' => '艇',
  '��' => '訂',
  '��' => '諦',
  '��' => '蹄',
  '��' => '逓',
  '�@' => '邸',
  '�A' => '鄭',
  '�B' => '釘',
  '�C' => '鼎',
  '�D' => '泥',
  '�E' => '摘',
  '�F' => '擢',
  '�G' => '敵',
  '�H' => '滴',
  '�I' => '的',
  '�J' => '笛',
  '�K' => '適',
  '�L' => '鏑',
  '�M' => '溺',
  '�N' => '哲',
  '�O' => '徹',
  '�P' => '撤',
  '�Q' => '轍',
  '�R' => '迭',
  '�S' => '鉄',
  '�T' => '典',
  '�U' => '填',
  '�V' => '天',
  '�W' => '展',
  '�X' => '店',
  '�Y' => '添',
  '�Z' => '纏',
  '�[' => '甜',
  '�\\' => '貼',
  '�]' => '転',
  '�^' => '顛',
  '�_' => '点',
  '�`' => '伝',
  '�a' => '殿',
  '�b' => '澱',
  '�c' => '田',
  '�d' => '電',
  '�e' => '兎',
  '�f' => '吐',
  '�g' => '堵',
  '�h' => '塗',
  '�i' => '妬',
  '�j' => '屠',
  '�k' => '徒',
  '�l' => '斗',
  '�m' => '杜',
  '�n' => '渡',
  '�o' => '登',
  '�p' => '菟',
  '�q' => '賭',
  '�r' => '途',
  '�s' => '都',
  '�t' => '鍍',
  '�u' => '砥',
  '�v' => '砺',
  '�w' => '努',
  '�x' => '度',
  '�y' => '土',
  '�z' => '奴',
  '�{' => '怒',
  '�|' => '倒',
  '�}' => '党',
  '�~' => '冬',
  '��' => '凍',
  '��' => '刀',
  '��' => '唐',
  '��' => '塔',
  '��' => '塘',
  '��' => '套',
  '��' => '宕',
  '��' => '島',
  '��' => '嶋',
  '��' => '悼',
  '��' => '投',
  '��' => '搭',
  '��' => '東',
  '��' => '桃',
  '��' => '梼',
  '��' => '棟',
  '��' => '盗',
  '��' => '淘',
  '��' => '湯',
  '��' => '涛',
  '��' => '灯',
  '��' => '燈',
  '��' => '当',
  '��' => '痘',
  '��' => '祷',
  '��' => '等',
  '��' => '答',
  '��' => '筒',
  '��' => '糖',
  '��' => '統',
  '��' => '到',
  '��' => '董',
  '��' => '蕩',
  '��' => '藤',
  '��' => '討',
  '��' => '謄',
  '��' => '豆',
  '��' => '踏',
  '��' => '逃',
  '��' => '透',
  '��' => '鐙',
  '��' => '陶',
  '��' => '頭',
  '��' => '騰',
  '��' => '闘',
  '��' => '働',
  '��' => '動',
  '��' => '同',
  '��' => '堂',
  '��' => '導',
  '��' => '憧',
  '��' => '撞',
  '��' => '洞',
  '��' => '瞳',
  '��' => '童',
  '��' => '胴',
  '��' => '萄',
  '��' => '道',
  '��' => '銅',
  '��' => '峠',
  '��' => '鴇',
  '��' => '匿',
  '��' => '得',
  '��' => '徳',
  '��' => '涜',
  '��' => '特',
  '��' => '督',
  '��' => '禿',
  '��' => '篤',
  '��' => '毒',
  '��' => '独',
  '��' => '読',
  '��' => '栃',
  '��' => '橡',
  '��' => '凸',
  '��' => '突',
  '��' => '椴',
  '��' => '届',
  '��' => '鳶',
  '��' => '苫',
  '��' => '寅',
  '��' => '酉',
  '��' => '瀞',
  '��' => '噸',
  '��' => '屯',
  '��' => '惇',
  '��' => '敦',
  '��' => '沌',
  '��' => '豚',
  '��' => '遁',
  '��' => '頓',
  '��' => '呑',
  '��' => '曇',
  '��' => '鈍',
  '��' => '奈',
  '��' => '那',
  '��' => '内',
  '��' => '乍',
  '��' => '凪',
  '��' => '薙',
  '��' => '謎',
  '��' => '灘',
  '��' => '捺',
  '��' => '鍋',
  '��' => '楢',
  '��' => '馴',
  '��' => '縄',
  '��' => '畷',
  '��' => '南',
  '��' => '楠',
  '��' => '軟',
  '��' => '難',
  '��' => '汝',
  '��' => '二',
  '��' => '尼',
  '��' => '弐',
  '��' => '迩',
  '��' => '匂',
  '��' => '賑',
  '��' => '肉',
  '��' => '虹',
  '��' => '廿',
  '��' => '日',
  '��' => '乳',
  '��' => '入',
  '�@' => '如',
  '�A' => '尿',
  '�B' => '韮',
  '�C' => '任',
  '�D' => '妊',
  '�E' => '忍',
  '�F' => '認',
  '�G' => '濡',
  '�H' => '禰',
  '�I' => '祢',
  '�J' => '寧',
  '�K' => '葱',
  '�L' => '猫',
  '�M' => '熱',
  '�N' => '年',
  '�O' => '念',
  '�P' => '捻',
  '�Q' => '撚',
  '�R' => '燃',
  '�S' => '粘',
  '�T' => '乃',
  '�U' => '廼',
  '�V' => '之',
  '�W' => '埜',
  '�X' => '嚢',
  '�Y' => '悩',
  '�Z' => '濃',
  '�[' => '納',
  '�\\' => '能',
  '�]' => '脳',
  '�^' => '膿',
  '�_' => '農',
  '�`' => '覗',
  '�a' => '蚤',
  '�b' => '巴',
  '�c' => '把',
  '�d' => '播',
  '�e' => '覇',
  '�f' => '杷',
  '�g' => '波',
  '�h' => '派',
  '�i' => '琶',
  '�j' => '破',
  '�k' => '婆',
  '�l' => '罵',
  '�m' => '芭',
  '�n' => '馬',
  '�o' => '俳',
  '�p' => '廃',
  '�q' => '拝',
  '�r' => '排',
  '�s' => '敗',
  '�t' => '杯',
  '�u' => '盃',
  '�v' => '牌',
  '�w' => '背',
  '�x' => '肺',
  '�y' => '輩',
  '�z' => '配',
  '�{' => '倍',
  '�|' => '培',
  '�}' => '媒',
  '�~' => '梅',
  '��' => '楳',
  '��' => '煤',
  '��' => '狽',
  '��' => '買',
  '��' => '売',
  '��' => '賠',
  '��' => '陪',
  '��' => '這',
  '��' => '蝿',
  '��' => '秤',
  '��' => '矧',
  '��' => '萩',
  '��' => '伯',
  '��' => '剥',
  '��' => '博',
  '��' => '拍',
  '��' => '柏',
  '��' => '泊',
  '��' => '白',
  '��' => '箔',
  '��' => '粕',
  '��' => '舶',
  '��' => '薄',
  '��' => '迫',
  '��' => '曝',
  '��' => '漠',
  '��' => '爆',
  '��' => '縛',
  '��' => '莫',
  '��' => '駁',
  '��' => '麦',
  '��' => '函',
  '��' => '箱',
  '��' => '硲',
  '��' => '箸',
  '��' => '肇',
  '��' => '筈',
  '��' => '櫨',
  '��' => '幡',
  '��' => '肌',
  '��' => '畑',
  '��' => '畠',
  '��' => '八',
  '��' => '鉢',
  '��' => '溌',
  '��' => '発',
  '��' => '醗',
  '��' => '髪',
  '��' => '伐',
  '��' => '罰',
  '��' => '抜',
  '��' => '筏',
  '��' => '閥',
  '��' => '鳩',
  '��' => '噺',
  '��' => '塙',
  '��' => '蛤',
  '��' => '隼',
  '��' => '伴',
  '��' => '判',
  '��' => '半',
  '��' => '反',
  '��' => '叛',
  '��' => '帆',
  '��' => '搬',
  '��' => '斑',
  '��' => '板',
  '��' => '氾',
  '��' => '汎',
  '��' => '版',
  '��' => '犯',
  '��' => '班',
  '��' => '畔',
  '��' => '繁',
  '��' => '般',
  '��' => '藩',
  '��' => '販',
  '��' => '範',
  '��' => '釆',
  '��' => '煩',
  '��' => '頒',
  '��' => '飯',
  '��' => '挽',
  '��' => '晩',
  '��' => '番',
  '��' => '盤',
  '��' => '磐',
  '��' => '蕃',
  '��' => '蛮',
  '��' => '匪',
  '��' => '卑',
  '��' => '否',
  '��' => '妃',
  '��' => '庇',
  '��' => '彼',
  '��' => '悲',
  '��' => '扉',
  '��' => '批',
  '��' => '披',
  '��' => '斐',
  '��' => '比',
  '��' => '泌',
  '��' => '疲',
  '��' => '皮',
  '��' => '碑',
  '��' => '秘',
  '��' => '緋',
  '��' => '罷',
  '��' => '肥',
  '��' => '被',
  '��' => '誹',
  '��' => '費',
  '��' => '避',
  '��' => '非',
  '��' => '飛',
  '��' => '樋',
  '��' => '簸',
  '��' => '備',
  '��' => '尾',
  '��' => '微',
  '��' => '枇',
  '��' => '毘',
  '��' => '琵',
  '��' => '眉',
  '��' => '美',
  '�@' => '鼻',
  '�A' => '柊',
  '�B' => '稗',
  '�C' => '匹',
  '�D' => '疋',
  '�E' => '髭',
  '�F' => '彦',
  '�G' => '膝',
  '�H' => '菱',
  '�I' => '肘',
  '�J' => '弼',
  '�K' => '必',
  '�L' => '畢',
  '�M' => '筆',
  '�N' => '逼',
  '�O' => '桧',
  '�P' => '姫',
  '�Q' => '媛',
  '�R' => '紐',
  '�S' => '百',
  '�T' => '謬',
  '�U' => '俵',
  '�V' => '彪',
  '�W' => '標',
  '�X' => '氷',
  '�Y' => '漂',
  '�Z' => '瓢',
  '�[' => '票',
  '�\\' => '表',
  '�]' => '評',
  '�^' => '豹',
  '�_' => '廟',
  '�`' => '描',
  '�a' => '病',
  '�b' => '秒',
  '�c' => '苗',
  '�d' => '錨',
  '�e' => '鋲',
  '�f' => '蒜',
  '�g' => '蛭',
  '�h' => '鰭',
  '�i' => '品',
  '�j' => '彬',
  '�k' => '斌',
  '�l' => '浜',
  '�m' => '瀕',
  '�n' => '貧',
  '�o' => '賓',
  '�p' => '頻',
  '�q' => '敏',
  '�r' => '瓶',
  '�s' => '不',
  '�t' => '付',
  '�u' => '埠',
  '�v' => '夫',
  '�w' => '婦',
  '�x' => '富',
  '�y' => '冨',
  '�z' => '布',
  '�{' => '府',
  '�|' => '怖',
  '�}' => '扶',
  '�~' => '敷',
  '��' => '斧',
  '��' => '普',
  '��' => '浮',
  '��' => '父',
  '��' => '符',
  '��' => '腐',
  '��' => '膚',
  '��' => '芙',
  '��' => '譜',
  '��' => '負',
  '��' => '賦',
  '��' => '赴',
  '��' => '阜',
  '��' => '附',
  '��' => '侮',
  '��' => '撫',
  '��' => '武',
  '��' => '舞',
  '��' => '葡',
  '��' => '蕪',
  '��' => '部',
  '��' => '封',
  '��' => '楓',
  '��' => '風',
  '��' => '葺',
  '��' => '蕗',
  '��' => '伏',
  '��' => '副',
  '��' => '復',
  '��' => '幅',
  '��' => '服',
  '��' => '福',
  '��' => '腹',
  '��' => '複',
  '��' => '覆',
  '��' => '淵',
  '��' => '弗',
  '��' => '払',
  '��' => '沸',
  '��' => '仏',
  '��' => '物',
  '��' => '鮒',
  '��' => '分',
  '��' => '吻',
  '��' => '噴',
  '��' => '墳',
  '��' => '憤',
  '��' => '扮',
  '��' => '焚',
  '��' => '奮',
  '��' => '粉',
  '��' => '糞',
  '��' => '紛',
  '��' => '雰',
  '��' => '文',
  '��' => '聞',
  '��' => '丙',
  '��' => '併',
  '��' => '兵',
  '��' => '塀',
  '��' => '幣',
  '��' => '平',
  '��' => '弊',
  '��' => '柄',
  '��' => '並',
  '��' => '蔽',
  '��' => '閉',
  '��' => '陛',
  '��' => '米',
  '��' => '頁',
  '��' => '僻',
  '��' => '壁',
  '��' => '癖',
  '��' => '碧',
  '��' => '別',
  '��' => '瞥',
  '��' => '蔑',
  '��' => '箆',
  '��' => '偏',
  '��' => '変',
  '��' => '片',
  '��' => '篇',
  '��' => '編',
  '��' => '辺',
  '��' => '返',
  '��' => '遍',
  '��' => '便',
  '��' => '勉',
  '��' => '娩',
  '��' => '弁',
  '��' => '鞭',
  '��' => '保',
  '��' => '舗',
  '��' => '鋪',
  '��' => '圃',
  '��' => '捕',
  '��' => '歩',
  '��' => '甫',
  '��' => '補',
  '��' => '輔',
  '��' => '穂',
  '��' => '募',
  '��' => '墓',
  '��' => '慕',
  '��' => '戊',
  '��' => '暮',
  '��' => '母',
  '��' => '簿',
  '��' => '菩',
  '��' => '倣',
  '��' => '俸',
  '��' => '包',
  '��' => '呆',
  '��' => '報',
  '��' => '奉',
  '��' => '宝',
  '��' => '峰',
  '��' => '峯',
  '��' => '崩',
  '��' => '庖',
  '��' => '抱',
  '��' => '捧',
  '��' => '放',
  '��' => '方',
  '��' => '朋',
  '�@' => '法',
  '�A' => '泡',
  '�B' => '烹',
  '�C' => '砲',
  '�D' => '縫',
  '�E' => '胞',
  '�F' => '芳',
  '�G' => '萌',
  '�H' => '蓬',
  '�I' => '蜂',
  '�J' => '褒',
  '�K' => '訪',
  '�L' => '豊',
  '�M' => '邦',
  '�N' => '鋒',
  '�O' => '飽',
  '�P' => '鳳',
  '�Q' => '鵬',
  '�R' => '乏',
  '�S' => '亡',
  '�T' => '傍',
  '�U' => '剖',
  '�V' => '坊',
  '�W' => '妨',
  '�X' => '帽',
  '�Y' => '忘',
  '�Z' => '忙',
  '�[' => '房',
  '�\\' => '暴',
  '�]' => '望',
  '�^' => '某',
  '�_' => '棒',
  '�`' => '冒',
  '�a' => '紡',
  '�b' => '肪',
  '�c' => '膨',
  '�d' => '謀',
  '�e' => '貌',
  '�f' => '貿',
  '�g' => '鉾',
  '�h' => '防',
  '�i' => '吠',
  '�j' => '頬',
  '�k' => '北',
  '�l' => '僕',
  '�m' => '卜',
  '�n' => '墨',
  '�o' => '撲',
  '�p' => '朴',
  '�q' => '牧',
  '�r' => '睦',
  '�s' => '穆',
  '�t' => '釦',
  '�u' => '勃',
  '�v' => '没',
  '�w' => '殆',
  '�x' => '堀',
  '�y' => '幌',
  '�z' => '奔',
  '�{' => '本',
  '�|' => '翻',
  '�}' => '凡',
  '�~' => '盆',
  '��' => '摩',
  '��' => '磨',
  '��' => '魔',
  '��' => '麻',
  '��' => '埋',
  '��' => '妹',
  '��' => '昧',
  '��' => '枚',
  '��' => '毎',
  '��' => '哩',
  '��' => '槙',
  '��' => '幕',
  '��' => '膜',
  '��' => '枕',
  '��' => '鮪',
  '��' => '柾',
  '��' => '鱒',
  '��' => '桝',
  '��' => '亦',
  '��' => '俣',
  '��' => '又',
  '��' => '抹',
  '��' => '末',
  '��' => '沫',
  '��' => '迄',
  '��' => '侭',
  '��' => '繭',
  '��' => '麿',
  '��' => '万',
  '��' => '慢',
  '��' => '満',
  '��' => '漫',
  '��' => '蔓',
  '��' => '味',
  '��' => '未',
  '��' => '魅',
  '��' => '巳',
  '��' => '箕',
  '��' => '岬',
  '��' => '密',
  '��' => '蜜',
  '��' => '湊',
  '��' => '蓑',
  '��' => '稔',
  '��' => '脈',
  '��' => '妙',
  '��' => '粍',
  '��' => '民',
  '��' => '眠',
  '��' => '務',
  '��' => '夢',
  '��' => '無',
  '��' => '牟',
  '��' => '矛',
  '��' => '霧',
  '��' => '鵡',
  '��' => '椋',
  '��' => '婿',
  '��' => '娘',
  '��' => '冥',
  '��' => '名',
  '��' => '命',
  '��' => '明',
  '��' => '盟',
  '��' => '迷',
  '��' => '銘',
  '��' => '鳴',
  '��' => '姪',
  '��' => '牝',
  '��' => '滅',
  '��' => '免',
  '��' => '棉',
  '��' => '綿',
  '��' => '緬',
  '��' => '面',
  '��' => '麺',
  '��' => '摸',
  '��' => '模',
  '��' => '茂',
  '��' => '妄',
  '��' => '孟',
  '��' => '毛',
  '��' => '猛',
  '��' => '盲',
  '��' => '網',
  '��' => '耗',
  '��' => '蒙',
  '��' => '儲',
  '��' => '木',
  '��' => '黙',
  '��' => '目',
  '��' => '杢',
  '��' => '勿',
  '��' => '餅',
  '��' => '尤',
  '��' => '戻',
  '��' => '籾',
  '��' => '貰',
  '��' => '問',
  '��' => '悶',
  '��' => '紋',
  '��' => '門',
  '��' => '匁',
  '��' => '也',
  '��' => '冶',
  '��' => '夜',
  '��' => '爺',
  '��' => '耶',
  '��' => '野',
  '��' => '弥',
  '��' => '矢',
  '��' => '厄',
  '��' => '役',
  '��' => '約',
  '��' => '薬',
  '��' => '訳',
  '��' => '躍',
  '��' => '靖',
  '��' => '柳',
  '��' => '薮',
  '��' => '鑓',
  '��' => '愉',
  '��' => '愈',
  '��' => '油',
  '��' => '癒',
  '�@' => '諭',
  '�A' => '輸',
  '�B' => '唯',
  '�C' => '佑',
  '�D' => '優',
  '�E' => '勇',
  '�F' => '友',
  '�G' => '宥',
  '�H' => '幽',
  '�I' => '悠',
  '�J' => '憂',
  '�K' => '揖',
  '�L' => '有',
  '�M' => '柚',
  '�N' => '湧',
  '�O' => '涌',
  '�P' => '猶',
  '�Q' => '猷',
  '�R' => '由',
  '�S' => '祐',
  '�T' => '裕',
  '�U' => '誘',
  '�V' => '遊',
  '�W' => '邑',
  '�X' => '郵',
  '�Y' => '雄',
  '�Z' => '融',
  '�[' => '夕',
  '�\\' => '予',
  '�]' => '余',
  '�^' => '与',
  '�_' => '誉',
  '�`' => '輿',
  '�a' => '預',
  '�b' => '傭',
  '�c' => '幼',
  '�d' => '妖',
  '�e' => '容',
  '�f' => '庸',
  '�g' => '揚',
  '�h' => '揺',
  '�i' => '擁',
  '�j' => '曜',
  '�k' => '楊',
  '�l' => '様',
  '�m' => '洋',
  '�n' => '溶',
  '�o' => '熔',
  '�p' => '用',
  '�q' => '窯',
  '�r' => '羊',
  '�s' => '耀',
  '�t' => '葉',
  '�u' => '蓉',
  '�v' => '要',
  '�w' => '謡',
  '�x' => '踊',
  '�y' => '遥',
  '�z' => '陽',
  '�{' => '養',
  '�|' => '慾',
  '�}' => '抑',
  '�~' => '欲',
  '��' => '沃',
  '��' => '浴',
  '��' => '翌',
  '��' => '翼',
  '��' => '淀',
  '��' => '羅',
  '��' => '螺',
  '��' => '裸',
  '��' => '来',
  '��' => '莱',
  '��' => '頼',
  '��' => '雷',
  '��' => '洛',
  '��' => '絡',
  '��' => '落',
  '��' => '酪',
  '��' => '乱',
  '��' => '卵',
  '��' => '嵐',
  '��' => '欄',
  '��' => '濫',
  '��' => '藍',
  '��' => '蘭',
  '��' => '覧',
  '��' => '利',
  '��' => '吏',
  '��' => '履',
  '��' => '李',
  '��' => '梨',
  '��' => '理',
  '��' => '璃',
  '��' => '痢',
  '��' => '裏',
  '��' => '裡',
  '��' => '里',
  '��' => '離',
  '��' => '陸',
  '��' => '律',
  '��' => '率',
  '��' => '立',
  '��' => '葎',
  '��' => '掠',
  '��' => '略',
  '��' => '劉',
  '��' => '流',
  '��' => '溜',
  '��' => '琉',
  '��' => '留',
  '��' => '硫',
  '��' => '粒',
  '��' => '隆',
  '��' => '竜',
  '��' => '龍',
  '��' => '侶',
  '��' => '慮',
  '��' => '旅',
  '��' => '虜',
  '��' => '了',
  '��' => '亮',
  '��' => '僚',
  '��' => '両',
  '��' => '凌',
  '��' => '寮',
  '��' => '料',
  '��' => '梁',
  '��' => '涼',
  '��' => '猟',
  '��' => '療',
  '��' => '瞭',
  '��' => '稜',
  '��' => '糧',
  '��' => '良',
  '��' => '諒',
  '��' => '遼',
  '��' => '量',
  '��' => '陵',
  '��' => '領',
  '��' => '力',
  '��' => '緑',
  '��' => '倫',
  '��' => '厘',
  '��' => '林',
  '��' => '淋',
  '��' => '燐',
  '��' => '琳',
  '��' => '臨',
  '��' => '輪',
  '��' => '隣',
  '��' => '鱗',
  '��' => '麟',
  '��' => '瑠',
  '��' => '塁',
  '��' => '涙',
  '��' => '累',
  '��' => '類',
  '��' => '令',
  '��' => '伶',
  '��' => '例',
  '��' => '冷',
  '��' => '励',
  '��' => '嶺',
  '��' => '怜',
  '��' => '玲',
  '��' => '礼',
  '��' => '苓',
  '��' => '鈴',
  '��' => '隷',
  '��' => '零',
  '��' => '霊',
  '��' => '麗',
  '��' => '齢',
  '��' => '暦',
  '��' => '歴',
  '��' => '列',
  '��' => '劣',
  '��' => '烈',
  '��' => '裂',
  '��' => '廉',
  '��' => '恋',
  '��' => '憐',
  '��' => '漣',
  '��' => '煉',
  '��' => '簾',
  '��' => '練',
  '��' => '聯',
  '�@' => '蓮',
  '�A' => '連',
  '�B' => '錬',
  '�C' => '呂',
  '�D' => '魯',
  '�E' => '櫓',
  '�F' => '炉',
  '�G' => '賂',
  '�H' => '路',
  '�I' => '露',
  '�J' => '労',
  '�K' => '婁',
  '�L' => '廊',
  '�M' => '弄',
  '�N' => '朗',
  '�O' => '楼',
  '�P' => '榔',
  '�Q' => '浪',
  '�R' => '漏',
  '�S' => '牢',
  '�T' => '狼',
  '�U' => '篭',
  '�V' => '老',
  '�W' => '聾',
  '�X' => '蝋',
  '�Y' => '郎',
  '�Z' => '六',
  '�[' => '麓',
  '�\\' => '禄',
  '�]' => '肋',
  '�^' => '録',
  '�_' => '論',
  '�`' => '倭',
  '�a' => '和',
  '�b' => '話',
  '�c' => '歪',
  '�d' => '賄',
  '�e' => '脇',
  '�f' => '惑',
  '�g' => '枠',
  '�h' => '鷲',
  '�i' => '亙',
  '�j' => '亘',
  '�k' => '鰐',
  '�l' => '詫',
  '�m' => '藁',
  '�n' => '蕨',
  '�o' => '椀',
  '�p' => '湾',
  '�q' => '碗',
  '�r' => '腕',
  '��' => '弌',
  '��' => '丐',
  '��' => '丕',
  '��' => '个',
  '��' => '丱',
  '��' => '丶',
  '��' => '丼',
  '��' => '丿',
  '��' => '乂',
  '��' => '乖',
  '��' => '乘',
  '��' => '亂',
  '��' => '亅',
  '��' => '豫',
  '��' => '亊',
  '��' => '舒',
  '��' => '弍',
  '��' => '于',
  '��' => '亞',
  '��' => '亟',
  '��' => '亠',
  '��' => '亢',
  '��' => '亰',
  '��' => '亳',
  '��' => '亶',
  '��' => '从',
  '��' => '仍',
  '��' => '仄',
  '��' => '仆',
  '��' => '仂',
  '��' => '仗',
  '��' => '仞',
  '��' => '仭',
  '��' => '仟',
  '��' => '价',
  '��' => '伉',
  '��' => '佚',
  '��' => '估',
  '��' => '佛',
  '��' => '佝',
  '��' => '佗',
  '��' => '佇',
  '��' => '佶',
  '��' => '侈',
  '��' => '侏',
  '��' => '侘',
  '��' => '佻',
  '��' => '佩',
  '��' => '佰',
  '��' => '侑',
  '��' => '佯',
  '��' => '來',
  '��' => '侖',
  '��' => '儘',
  '��' => '俔',
  '��' => '俟',
  '��' => '俎',
  '��' => '俘',
  '��' => '俛',
  '��' => '俑',
  '��' => '俚',
  '��' => '俐',
  '��' => '俤',
  '��' => '俥',
  '��' => '倚',
  '��' => '倨',
  '��' => '倔',
  '��' => '倪',
  '��' => '倥',
  '��' => '倅',
  '��' => '伜',
  '��' => '俶',
  '��' => '倡',
  '��' => '倩',
  '��' => '倬',
  '��' => '俾',
  '��' => '俯',
  '��' => '們',
  '��' => '倆',
  '��' => '偃',
  '��' => '假',
  '��' => '會',
  '��' => '偕',
  '��' => '偐',
  '��' => '偈',
  '��' => '做',
  '��' => '偖',
  '��' => '偬',
  '��' => '偸',
  '��' => '傀',
  '��' => '傚',
  '��' => '傅',
  '��' => '傴',
  '��' => '傲',
  '�@' => '僉',
  '�A' => '僊',
  '�B' => '傳',
  '�C' => '僂',
  '�D' => '僖',
  '�E' => '僞',
  '�F' => '僥',
  '�G' => '僭',
  '�H' => '僣',
  '�I' => '僮',
  '�J' => '價',
  '�K' => '僵',
  '�L' => '儉',
  '�M' => '儁',
  '�N' => '儂',
  '�O' => '儖',
  '�P' => '儕',
  '�Q' => '儔',
  '�R' => '儚',
  '�S' => '儡',
  '�T' => '儺',
  '�U' => '儷',
  '�V' => '儼',
  '�W' => '儻',
  '�X' => '儿',
  '�Y' => '兀',
  '�Z' => '兒',
  '�[' => '兌',
  '�\\' => '兔',
  '�]' => '兢',
  '�^' => '竸',
  '�_' => '兩',
  '�`' => '兪',
  '�a' => '兮',
  '�b' => '冀',
  '�c' => '冂',
  '�d' => '囘',
  '�e' => '册',
  '�f' => '冉',
  '�g' => '冏',
  '�h' => '冑',
  '�i' => '冓',
  '�j' => '冕',
  '�k' => '冖',
  '�l' => '冤',
  '�m' => '冦',
  '�n' => '冢',
  '�o' => '冩',
  '�p' => '冪',
  '�q' => '冫',
  '�r' => '决',
  '�s' => '冱',
  '�t' => '冲',
  '�u' => '冰',
  '�v' => '况',
  '�w' => '冽',
  '�x' => '凅',
  '�y' => '凉',
  '�z' => '凛',
  '�{' => '几',
  '�|' => '處',
  '�}' => '凩',
  '�~' => '凭',
  '��' => '凰',
  '��' => '凵',
  '��' => '凾',
  '��' => '刄',
  '��' => '刋',
  '��' => '刔',
  '��' => '刎',
  '��' => '刧',
  '��' => '刪',
  '��' => '刮',
  '��' => '刳',
  '��' => '刹',
  '��' => '剏',
  '��' => '剄',
  '��' => '剋',
  '��' => '剌',
  '��' => '剞',
  '��' => '剔',
  '��' => '剪',
  '��' => '剴',
  '��' => '剩',
  '��' => '剳',
  '��' => '剿',
  '��' => '剽',
  '��' => '劍',
  '��' => '劔',
  '��' => '劒',
  '��' => '剱',
  '��' => '劈',
  '��' => '劑',
  '��' => '辨',
  '��' => '辧',
  '��' => '劬',
  '��' => '劭',
  '��' => '劼',
  '��' => '劵',
  '��' => '勁',
  '��' => '勍',
  '��' => '勗',
  '��' => '勞',
  '��' => '勣',
  '��' => '勦',
  '��' => '飭',
  '��' => '勠',
  '��' => '勳',
  '��' => '勵',
  '��' => '勸',
  '��' => '勹',
  '��' => '匆',
  '��' => '匈',
  '��' => '甸',
  '��' => '匍',
  '��' => '匐',
  '��' => '匏',
  '��' => '匕',
  '��' => '匚',
  '��' => '匣',
  '��' => '匯',
  '��' => '匱',
  '��' => '匳',
  '��' => '匸',
  '��' => '區',
  '��' => '卆',
  '��' => '卅',
  '��' => '丗',
  '��' => '卉',
  '��' => '卍',
  '��' => '凖',
  '��' => '卞',
  '��' => '卩',
  '��' => '卮',
  '��' => '夘',
  '��' => '卻',
  '��' => '卷',
  '��' => '厂',
  '��' => '厖',
  '��' => '厠',
  '��' => '厦',
  '��' => '厥',
  '��' => '厮',
  '��' => '厰',
  '��' => '厶',
  '��' => '參',
  '��' => '簒',
  '��' => '雙',
  '��' => '叟',
  '��' => '曼',
  '��' => '燮',
  '��' => '叮',
  '��' => '叨',
  '��' => '叭',
  '��' => '叺',
  '��' => '吁',
  '��' => '吽',
  '��' => '呀',
  '��' => '听',
  '��' => '吭',
  '��' => '吼',
  '��' => '吮',
  '��' => '吶',
  '��' => '吩',
  '��' => '吝',
  '��' => '呎',
  '��' => '咏',
  '��' => '呵',
  '��' => '咎',
  '��' => '呟',
  '��' => '呱',
  '��' => '呷',
  '��' => '呰',
  '��' => '咒',
  '��' => '呻',
  '��' => '咀',
  '��' => '呶',
  '��' => '咄',
  '��' => '咐',
  '��' => '咆',
  '��' => '哇',
  '��' => '咢',
  '��' => '咸',
  '��' => '咥',
  '��' => '咬',
  '��' => '哄',
  '��' => '哈',
  '��' => '咨',
  '�@' => '咫',
  '�A' => '哂',
  '�B' => '咤',
  '�C' => '咾',
  '�D' => '咼',
  '�E' => '哘',
  '�F' => '哥',
  '�G' => '哦',
  '�H' => '唏',
  '�I' => '唔',
  '�J' => '哽',
  '�K' => '哮',
  '�L' => '哭',
  '�M' => '哺',
  '�N' => '哢',
  '�O' => '唹',
  '�P' => '啀',
  '�Q' => '啣',
  '�R' => '啌',
  '�S' => '售',
  '�T' => '啜',
  '�U' => '啅',
  '�V' => '啖',
  '�W' => '啗',
  '�X' => '唸',
  '�Y' => '唳',
  '�Z' => '啝',
  '�[' => '喙',
  '�\\' => '喀',
  '�]' => '咯',
  '�^' => '喊',
  '�_' => '喟',
  '�`' => '啻',
  '�a' => '啾',
  '�b' => '喘',
  '�c' => '喞',
  '�d' => '單',
  '�e' => '啼',
  '�f' => '喃',
  '�g' => '喩',
  '�h' => '喇',
  '�i' => '喨',
  '�j' => '嗚',
  '�k' => '嗅',
  '�l' => '嗟',
  '�m' => '嗄',
  '�n' => '嗜',
  '�o' => '嗤',
  '�p' => '嗔',
  '�q' => '嘔',
  '�r' => '嗷',
  '�s' => '嘖',
  '�t' => '嗾',
  '�u' => '嗽',
  '�v' => '嘛',
  '�w' => '嗹',
  '�x' => '噎',
  '�y' => '噐',
  '�z' => '營',
  '�{' => '嘴',
  '�|' => '嘶',
  '�}' => '嘲',
  '�~' => '嘸',
  '��' => '噫',
  '��' => '噤',
  '��' => '嘯',
  '��' => '噬',
  '��' => '噪',
  '��' => '嚆',
  '��' => '嚀',
  '��' => '嚊',
  '��' => '嚠',
  '��' => '嚔',
  '��' => '嚏',
  '��' => '嚥',
  '��' => '嚮',
  '��' => '嚶',
  '��' => '嚴',
  '��' => '囂',
  '��' => '嚼',
  '��' => '囁',
  '��' => '囃',
  '��' => '囀',
  '��' => '囈',
  '��' => '囎',
  '��' => '囑',
  '��' => '囓',
  '��' => '囗',
  '��' => '囮',
  '��' => '囹',
  '��' => '圀',
  '��' => '囿',
  '��' => '圄',
  '��' => '圉',
  '��' => '圈',
  '��' => '國',
  '��' => '圍',
  '��' => '圓',
  '��' => '團',
  '��' => '圖',
  '��' => '嗇',
  '��' => '圜',
  '��' => '圦',
  '��' => '圷',
  '��' => '圸',
  '��' => '坎',
  '��' => '圻',
  '��' => '址',
  '��' => '坏',
  '��' => '坩',
  '��' => '埀',
  '��' => '垈',
  '��' => '坡',
  '��' => '坿',
  '��' => '垉',
  '��' => '垓',
  '��' => '垠',
  '��' => '垳',
  '��' => '垤',
  '��' => '垪',
  '��' => '垰',
  '��' => '埃',
  '��' => '埆',
  '��' => '埔',
  '��' => '埒',
  '��' => '埓',
  '��' => '堊',
  '��' => '埖',
  '��' => '埣',
  '��' => '堋',
  '��' => '堙',
  '��' => '堝',
  '��' => '塲',
  '��' => '堡',
  '��' => '塢',
  '��' => '塋',
  '��' => '塰',
  '��' => '毀',
  '��' => '塒',
  '��' => '堽',
  '��' => '塹',
  '��' => '墅',
  '��' => '墹',
  '��' => '墟',
  '��' => '墫',
  '��' => '墺',
  '��' => '壞',
  '��' => '墻',
  '��' => '墸',
  '��' => '墮',
  '��' => '壅',
  '��' => '壓',
  '��' => '壑',
  '��' => '壗',
  '��' => '壙',
  '��' => '壘',
  '��' => '壥',
  '��' => '壜',
  '��' => '壤',
  '��' => '壟',
  '��' => '壯',
  '��' => '壺',
  '��' => '壹',
  '��' => '壻',
  '��' => '壼',
  '��' => '壽',
  '��' => '夂',
  '��' => '夊',
  '��' => '夐',
  '��' => '夛',
  '��' => '梦',
  '��' => '夥',
  '��' => '夬',
  '��' => '夭',
  '��' => '夲',
  '��' => '夸',
  '��' => '夾',
  '��' => '竒',
  '��' => '奕',
  '��' => '奐',
  '��' => '奎',
  '��' => '奚',
  '��' => '奘',
  '��' => '奢',
  '��' => '奠',
  '��' => '奧',
  '��' => '奬',
  '��' => '奩',
  '�@' => '奸',
  '�A' => '妁',
  '�B' => '妝',
  '�C' => '佞',
  '�D' => '侫',
  '�E' => '妣',
  '�F' => '妲',
  '�G' => '姆',
  '�H' => '姨',
  '�I' => '姜',
  '�J' => '妍',
  '�K' => '姙',
  '�L' => '姚',
  '�M' => '娥',
  '�N' => '娟',
  '�O' => '娑',
  '�P' => '娜',
  '�Q' => '娉',
  '�R' => '娚',
  '�S' => '婀',
  '�T' => '婬',
  '�U' => '婉',
  '�V' => '娵',
  '�W' => '娶',
  '�X' => '婢',
  '�Y' => '婪',
  '�Z' => '媚',
  '�[' => '媼',
  '�\\' => '媾',
  '�]' => '嫋',
  '�^' => '嫂',
  '�_' => '媽',
  '�`' => '嫣',
  '�a' => '嫗',
  '�b' => '嫦',
  '�c' => '嫩',
  '�d' => '嫖',
  '�e' => '嫺',
  '�f' => '嫻',
  '�g' => '嬌',
  '�h' => '嬋',
  '�i' => '嬖',
  '�j' => '嬲',
  '�k' => '嫐',
  '�l' => '嬪',
  '�m' => '嬶',
  '�n' => '嬾',
  '�o' => '孃',
  '�p' => '孅',
  '�q' => '孀',
  '�r' => '孑',
  '�s' => '孕',
  '�t' => '孚',
  '�u' => '孛',
  '�v' => '孥',
  '�w' => '孩',
  '�x' => '孰',
  '�y' => '孳',
  '�z' => '孵',
  '�{' => '學',
  '�|' => '斈',
  '�}' => '孺',
  '�~' => '宀',
  '��' => '它',
  '��' => '宦',
  '��' => '宸',
  '��' => '寃',
  '��' => '寇',
  '��' => '寉',
  '��' => '寔',
  '��' => '寐',
  '��' => '寤',
  '��' => '實',
  '��' => '寢',
  '��' => '寞',
  '��' => '寥',
  '��' => '寫',
  '��' => '寰',
  '��' => '寶',
  '��' => '寳',
  '��' => '尅',
  '��' => '將',
  '��' => '專',
  '��' => '對',
  '��' => '尓',
  '��' => '尠',
  '��' => '尢',
  '��' => '尨',
  '��' => '尸',
  '��' => '尹',
  '��' => '屁',
  '��' => '屆',
  '��' => '屎',
  '��' => '屓',
  '��' => '屐',
  '��' => '屏',
  '��' => '孱',
  '��' => '屬',
  '��' => '屮',
  '��' => '乢',
  '��' => '屶',
  '��' => '屹',
  '��' => '岌',
  '��' => '岑',
  '��' => '岔',
  '��' => '妛',
  '��' => '岫',
  '��' => '岻',
  '��' => '岶',
  '��' => '岼',
  '��' => '岷',
  '��' => '峅',
  '��' => '岾',
  '��' => '峇',
  '��' => '峙',
  '��' => '峩',
  '��' => '峽',
  '��' => '峺',
  '��' => '峭',
  '��' => '嶌',
  '��' => '峪',
  '��' => '崋',
  '��' => '崕',
  '��' => '崗',
  '��' => '嵜',
  '��' => '崟',
  '��' => '崛',
  '��' => '崑',
  '��' => '崔',
  '��' => '崢',
  '��' => '崚',
  '��' => '崙',
  '��' => '崘',
  '��' => '嵌',
  '��' => '嵒',
  '��' => '嵎',
  '��' => '嵋',
  '��' => '嵬',
  '��' => '嵳',
  '��' => '嵶',
  '��' => '嶇',
  '��' => '嶄',
  '��' => '嶂',
  '��' => '嶢',
  '��' => '嶝',
  '��' => '嶬',
  '��' => '嶮',
  '��' => '嶽',
  '��' => '嶐',
  '��' => '嶷',
  '��' => '嶼',
  '��' => '巉',
  '��' => '巍',
  '��' => '巓',
  '��' => '巒',
  '��' => '巖',
  '��' => '巛',
  '��' => '巫',
  '��' => '已',
  '��' => '巵',
  '��' => '帋',
  '��' => '帚',
  '��' => '帙',
  '��' => '帑',
  '��' => '帛',
  '��' => '帶',
  '��' => '帷',
  '��' => '幄',
  '��' => '幃',
  '��' => '幀',
  '��' => '幎',
  '��' => '幗',
  '��' => '幔',
  '��' => '幟',
  '��' => '幢',
  '��' => '幤',
  '��' => '幇',
  '��' => '幵',
  '��' => '并',
  '��' => '幺',
  '��' => '麼',
  '��' => '广',
  '��' => '庠',
  '��' => '廁',
  '��' => '廂',
  '��' => '廈',
  '��' => '廐',
  '��' => '廏',
  '�@' => '廖',
  '�A' => '廣',
  '�B' => '廝',
  '�C' => '廚',
  '�D' => '廛',
  '�E' => '廢',
  '�F' => '廡',
  '�G' => '廨',
  '�H' => '廩',
  '�I' => '廬',
  '�J' => '廱',
  '�K' => '廳',
  '�L' => '廰',
  '�M' => '廴',
  '�N' => '廸',
  '�O' => '廾',
  '�P' => '弃',
  '�Q' => '弉',
  '�R' => '彝',
  '�S' => '彜',
  '�T' => '弋',
  '�U' => '弑',
  '�V' => '弖',
  '�W' => '弩',
  '�X' => '弭',
  '�Y' => '弸',
  '�Z' => '彁',
  '�[' => '彈',
  '�\\' => '彌',
  '�]' => '彎',
  '�^' => '弯',
  '�_' => '彑',
  '�`' => '彖',
  '�a' => '彗',
  '�b' => '彙',
  '�c' => '彡',
  '�d' => '彭',
  '�e' => '彳',
  '�f' => '彷',
  '�g' => '徃',
  '�h' => '徂',
  '�i' => '彿',
  '�j' => '徊',
  '�k' => '很',
  '�l' => '徑',
  '�m' => '徇',
  '�n' => '從',
  '�o' => '徙',
  '�p' => '徘',
  '�q' => '徠',
  '�r' => '徨',
  '�s' => '徭',
  '�t' => '徼',
  '�u' => '忖',
  '�v' => '忻',
  '�w' => '忤',
  '�x' => '忸',
  '�y' => '忱',
  '�z' => '忝',
  '�{' => '悳',
  '�|' => '忿',
  '�}' => '怡',
  '�~' => '恠',
  '��' => '怙',
  '��' => '怐',
  '��' => '怩',
  '��' => '怎',
  '��' => '怱',
  '��' => '怛',
  '��' => '怕',
  '��' => '怫',
  '��' => '怦',
  '��' => '怏',
  '��' => '怺',
  '��' => '恚',
  '��' => '恁',
  '��' => '恪',
  '��' => '恷',
  '��' => '恟',
  '��' => '恊',
  '��' => '恆',
  '��' => '恍',
  '��' => '恣',
  '��' => '恃',
  '��' => '恤',
  '��' => '恂',
  '��' => '恬',
  '��' => '恫',
  '��' => '恙',
  '��' => '悁',
  '��' => '悍',
  '��' => '惧',
  '��' => '悃',
  '��' => '悚',
  '��' => '悄',
  '��' => '悛',
  '��' => '悖',
  '��' => '悗',
  '��' => '悒',
  '��' => '悧',
  '��' => '悋',
  '��' => '惡',
  '��' => '悸',
  '��' => '惠',
  '��' => '惓',
  '��' => '悴',
  '��' => '忰',
  '��' => '悽',
  '��' => '惆',
  '��' => '悵',
  '��' => '惘',
  '��' => '慍',
  '��' => '愕',
  '��' => '愆',
  '��' => '惶',
  '��' => '惷',
  '��' => '愀',
  '��' => '惴',
  '��' => '惺',
  '��' => '愃',
  '��' => '愡',
  '��' => '惻',
  '��' => '惱',
  '��' => '愍',
  '��' => '愎',
  '��' => '慇',
  '��' => '愾',
  '��' => '愨',
  '��' => '愧',
  '��' => '慊',
  '��' => '愿',
  '��' => '愼',
  '��' => '愬',
  '��' => '愴',
  '��' => '愽',
  '��' => '慂',
  '��' => '慄',
  '��' => '慳',
  '��' => '慷',
  '��' => '慘',
  '��' => '慙',
  '��' => '慚',
  '��' => '慫',
  '��' => '慴',
  '��' => '慯',
  '��' => '慥',
  '��' => '慱',
  '��' => '慟',
  '��' => '慝',
  '��' => '慓',
  '��' => '慵',
  '��' => '憙',
  '��' => '憖',
  '��' => '憇',
  '��' => '憬',
  '��' => '憔',
  '��' => '憚',
  '��' => '憊',
  '��' => '憑',
  '��' => '憫',
  '��' => '憮',
  '��' => '懌',
  '��' => '懊',
  '��' => '應',
  '��' => '懷',
  '��' => '懈',
  '��' => '懃',
  '��' => '懆',
  '��' => '憺',
  '��' => '懋',
  '��' => '罹',
  '��' => '懍',
  '��' => '懦',
  '��' => '懣',
  '��' => '懶',
  '��' => '懺',
  '��' => '懴',
  '��' => '懿',
  '��' => '懽',
  '��' => '懼',
  '��' => '懾',
  '��' => '戀',
  '��' => '戈',
  '��' => '戉',
  '��' => '戍',
  '��' => '戌',
  '��' => '戔',
  '��' => '戛',
  '�@' => '戞',
  '�A' => '戡',
  '�B' => '截',
  '�C' => '戮',
  '�D' => '戰',
  '�E' => '戲',
  '�F' => '戳',
  '�G' => '扁',
  '�H' => '扎',
  '�I' => '扞',
  '�J' => '扣',
  '�K' => '扛',
  '�L' => '扠',
  '�M' => '扨',
  '�N' => '扼',
  '�O' => '抂',
  '�P' => '抉',
  '�Q' => '找',
  '�R' => '抒',
  '�S' => '抓',
  '�T' => '抖',
  '�U' => '拔',
  '�V' => '抃',
  '�W' => '抔',
  '�X' => '拗',
  '�Y' => '拑',
  '�Z' => '抻',
  '�[' => '拏',
  '�\\' => '拿',
  '�]' => '拆',
  '�^' => '擔',
  '�_' => '拈',
  '�`' => '拜',
  '�a' => '拌',
  '�b' => '拊',
  '�c' => '拂',
  '�d' => '拇',
  '�e' => '抛',
  '�f' => '拉',
  '�g' => '挌',
  '�h' => '拮',
  '�i' => '拱',
  '�j' => '挧',
  '�k' => '挂',
  '�l' => '挈',
  '�m' => '拯',
  '�n' => '拵',
  '�o' => '捐',
  '�p' => '挾',
  '�q' => '捍',
  '�r' => '搜',
  '�s' => '捏',
  '�t' => '掖',
  '�u' => '掎',
  '�v' => '掀',
  '�w' => '掫',
  '�x' => '捶',
  '�y' => '掣',
  '�z' => '掏',
  '�{' => '掉',
  '�|' => '掟',
  '�}' => '掵',
  '�~' => '捫',
  '��' => '捩',
  '��' => '掾',
  '��' => '揩',
  '��' => '揀',
  '��' => '揆',
  '��' => '揣',
  '��' => '揉',
  '��' => '插',
  '��' => '揶',
  '��' => '揄',
  '��' => '搖',
  '��' => '搴',
  '��' => '搆',
  '��' => '搓',
  '��' => '搦',
  '��' => '搶',
  '��' => '攝',
  '��' => '搗',
  '��' => '搨',
  '��' => '搏',
  '��' => '摧',
  '��' => '摯',
  '��' => '摶',
  '��' => '摎',
  '��' => '攪',
  '��' => '撕',
  '��' => '撓',
  '��' => '撥',
  '��' => '撩',
  '��' => '撈',
  '��' => '撼',
  '��' => '據',
  '��' => '擒',
  '��' => '擅',
  '��' => '擇',
  '��' => '撻',
  '��' => '擘',
  '��' => '擂',
  '��' => '擱',
  '��' => '擧',
  '��' => '舉',
  '��' => '擠',
  '��' => '擡',
  '��' => '抬',
  '��' => '擣',
  '��' => '擯',
  '��' => '攬',
  '��' => '擶',
  '��' => '擴',
  '��' => '擲',
  '��' => '擺',
  '��' => '攀',
  '��' => '擽',
  '��' => '攘',
  '��' => '攜',
  '��' => '攅',
  '��' => '攤',
  '��' => '攣',
  '��' => '攫',
  '��' => '攴',
  '��' => '攵',
  '��' => '攷',
  '��' => '收',
  '��' => '攸',
  '��' => '畋',
  '��' => '效',
  '��' => '敖',
  '��' => '敕',
  '��' => '敍',
  '��' => '敘',
  '��' => '敞',
  '��' => '敝',
  '��' => '敲',
  '��' => '數',
  '��' => '斂',
  '��' => '斃',
  '��' => '變',
  '��' => '斛',
  '��' => '斟',
  '��' => '斫',
  '��' => '斷',
  '��' => '旃',
  '��' => '旆',
  '��' => '旁',
  '��' => '旄',
  '��' => '旌',
  '��' => '旒',
  '��' => '旛',
  '��' => '旙',
  '��' => '无',
  '��' => '旡',
  '��' => '旱',
  '��' => '杲',
  '��' => '昊',
  '��' => '昃',
  '��' => '旻',
  '��' => '杳',
  '��' => '昵',
  '��' => '昶',
  '��' => '昴',
  '��' => '昜',
  '��' => '晏',
  '��' => '晄',
  '��' => '晉',
  '��' => '晁',
  '��' => '晞',
  '��' => '晝',
  '��' => '晤',
  '��' => '晧',
  '��' => '晨',
  '��' => '晟',
  '��' => '晢',
  '��' => '晰',
  '��' => '暃',
  '��' => '暈',
  '��' => '暎',
  '��' => '暉',
  '��' => '暄',
  '��' => '暘',
  '��' => '暝',
  '��' => '曁',
  '��' => '暹',
  '��' => '曉',
  '��' => '暾',
  '��' => '暼',
  '�@' => '曄',
  '�A' => '暸',
  '�B' => '曖',
  '�C' => '曚',
  '�D' => '曠',
  '�E' => '昿',
  '�F' => '曦',
  '�G' => '曩',
  '�H' => '曰',
  '�I' => '曵',
  '�J' => '曷',
  '�K' => '朏',
  '�L' => '朖',
  '�M' => '朞',
  '�N' => '朦',
  '�O' => '朧',
  '�P' => '霸',
  '�Q' => '朮',
  '�R' => '朿',
  '�S' => '朶',
  '�T' => '杁',
  '�U' => '朸',
  '�V' => '朷',
  '�W' => '杆',
  '�X' => '杞',
  '�Y' => '杠',
  '�Z' => '杙',
  '�[' => '杣',
  '�\\' => '杤',
  '�]' => '枉',
  '�^' => '杰',
  '�_' => '枩',
  '�`' => '杼',
  '�a' => '杪',
  '�b' => '枌',
  '�c' => '枋',
  '�d' => '枦',
  '�e' => '枡',
  '�f' => '枅',
  '�g' => '枷',
  '�h' => '柯',
  '�i' => '枴',
  '�j' => '柬',
  '�k' => '枳',
  '�l' => '柩',
  '�m' => '枸',
  '�n' => '柤',
  '�o' => '柞',
  '�p' => '柝',
  '�q' => '柢',
  '�r' => '柮',
  '�s' => '枹',
  '�t' => '柎',
  '�u' => '柆',
  '�v' => '柧',
  '�w' => '檜',
  '�x' => '栞',
  '�y' => '框',
  '�z' => '栩',
  '�{' => '桀',
  '�|' => '桍',
  '�}' => '栲',
  '�~' => '桎',
  '��' => '梳',
  '��' => '栫',
  '��' => '桙',
  '��' => '档',
  '��' => '桷',
  '��' => '桿',
  '��' => '梟',
  '��' => '梏',
  '��' => '梭',
  '��' => '梔',
  '��' => '條',
  '��' => '梛',
  '��' => '梃',
  '��' => '檮',
  '��' => '梹',
  '��' => '桴',
  '��' => '梵',
  '��' => '梠',
  '��' => '梺',
  '��' => '椏',
  '��' => '梍',
  '��' => '桾',
  '��' => '椁',
  '��' => '棊',
  '��' => '椈',
  '��' => '棘',
  '��' => '椢',
  '��' => '椦',
  '��' => '棡',
  '��' => '椌',
  '��' => '棍',
  '��' => '棔',
  '��' => '棧',
  '��' => '棕',
  '��' => '椶',
  '��' => '椒',
  '��' => '椄',
  '��' => '棗',
  '��' => '棣',
  '��' => '椥',
  '��' => '棹',
  '��' => '棠',
  '��' => '棯',
  '��' => '椨',
  '��' => '椪',
  '��' => '椚',
  '��' => '椣',
  '��' => '椡',
  '��' => '棆',
  '��' => '楹',
  '��' => '楷',
  '��' => '楜',
  '��' => '楸',
  '��' => '楫',
  '��' => '楔',
  '��' => '楾',
  '��' => '楮',
  '��' => '椹',
  '��' => '楴',
  '��' => '椽',
  '��' => '楙',
  '��' => '椰',
  '��' => '楡',
  '��' => '楞',
  '��' => '楝',
  '��' => '榁',
  '��' => '楪',
  '��' => '榲',
  '��' => '榮',
  '��' => '槐',
  '��' => '榿',
  '��' => '槁',
  '��' => '槓',
  '��' => '榾',
  '��' => '槎',
  '��' => '寨',
  '��' => '槊',
  '��' => '槝',
  '��' => '榻',
  '��' => '槃',
  '��' => '榧',
  '��' => '樮',
  '��' => '榑',
  '��' => '榠',
  '��' => '榜',
  '��' => '榕',
  '��' => '榴',
  '��' => '槞',
  '��' => '槨',
  '��' => '樂',
  '��' => '樛',
  '��' => '槿',
  '��' => '權',
  '��' => '槹',
  '��' => '槲',
  '��' => '槧',
  '��' => '樅',
  '��' => '榱',
  '��' => '樞',
  '��' => '槭',
  '��' => '樔',
  '��' => '槫',
  '��' => '樊',
  '��' => '樒',
  '��' => '櫁',
  '��' => '樣',
  '��' => '樓',
  '��' => '橄',
  '��' => '樌',
  '��' => '橲',
  '��' => '樶',
  '��' => '橸',
  '��' => '橇',
  '��' => '橢',
  '��' => '橙',
  '��' => '橦',
  '��' => '橈',
  '��' => '樸',
  '��' => '樢',
  '��' => '檐',
  '��' => '檍',
  '��' => '檠',
  '��' => '檄',
  '��' => '檢',
  '��' => '檣',
  '�@' => '檗',
  '�A' => '蘗',
  '�B' => '檻',
  '�C' => '櫃',
  '�D' => '櫂',
  '�E' => '檸',
  '�F' => '檳',
  '�G' => '檬',
  '�H' => '櫞',
  '�I' => '櫑',
  '�J' => '櫟',
  '�K' => '檪',
  '�L' => '櫚',
  '�M' => '櫪',
  '�N' => '櫻',
  '�O' => '欅',
  '�P' => '蘖',
  '�Q' => '櫺',
  '�R' => '欒',
  '�S' => '欖',
  '�T' => '鬱',
  '�U' => '欟',
  '�V' => '欸',
  '�W' => '欷',
  '�X' => '盜',
  '�Y' => '欹',
  '�Z' => '飮',
  '�[' => '歇',
  '�\\' => '歃',
  '�]' => '歉',
  '�^' => '歐',
  '�_' => '歙',
  '�`' => '歔',
  '�a' => '歛',
  '�b' => '歟',
  '�c' => '歡',
  '�d' => '歸',
  '�e' => '歹',
  '�f' => '歿',
  '�g' => '殀',
  '�h' => '殄',
  '�i' => '殃',
  '�j' => '殍',
  '�k' => '殘',
  '�l' => '殕',
  '�m' => '殞',
  '�n' => '殤',
  '�o' => '殪',
  '�p' => '殫',
  '�q' => '殯',
  '�r' => '殲',
  '�s' => '殱',
  '�t' => '殳',
  '�u' => '殷',
  '�v' => '殼',
  '�w' => '毆',
  '�x' => '毋',
  '�y' => '毓',
  '�z' => '毟',
  '�{' => '毬',
  '�|' => '毫',
  '�}' => '毳',
  '�~' => '毯',
  '��' => '麾',
  '��' => '氈',
  '��' => '氓',
  '��' => '气',
  '��' => '氛',
  '��' => '氤',
  '��' => '氣',
  '��' => '汞',
  '��' => '汕',
  '��' => '汢',
  '��' => '汪',
  '��' => '沂',
  '��' => '沍',
  '��' => '沚',
  '��' => '沁',
  '��' => '沛',
  '��' => '汾',
  '��' => '汨',
  '��' => '汳',
  '��' => '沒',
  '��' => '沐',
  '��' => '泄',
  '��' => '泱',
  '��' => '泓',
  '��' => '沽',
  '��' => '泗',
  '��' => '泅',
  '��' => '泝',
  '��' => '沮',
  '��' => '沱',
  '��' => '沾',
  '��' => '沺',
  '��' => '泛',
  '��' => '泯',
  '��' => '泙',
  '��' => '泪',
  '��' => '洟',
  '��' => '衍',
  '��' => '洶',
  '��' => '洫',
  '��' => '洽',
  '��' => '洸',
  '��' => '洙',
  '��' => '洵',
  '��' => '洳',
  '��' => '洒',
  '��' => '洌',
  '��' => '浣',
  '��' => '涓',
  '��' => '浤',
  '��' => '浚',
  '��' => '浹',
  '��' => '浙',
  '��' => '涎',
  '��' => '涕',
  '��' => '濤',
  '��' => '涅',
  '��' => '淹',
  '��' => '渕',
  '��' => '渊',
  '��' => '涵',
  '��' => '淇',
  '��' => '淦',
  '��' => '涸',
  '��' => '淆',
  '��' => '淬',
  '��' => '淞',
  '��' => '淌',
  '��' => '淨',
  '��' => '淒',
  '��' => '淅',
  '��' => '淺',
  '��' => '淙',
  '��' => '淤',
  '��' => '淕',
  '��' => '淪',
  '��' => '淮',
  '��' => '渭',
  '��' => '湮',
  '��' => '渮',
  '��' => '渙',
  '��' => '湲',
  '��' => '湟',
  '��' => '渾',
  '��' => '渣',
  '��' => '湫',
  '��' => '渫',
  '��' => '湶',
  '��' => '湍',
  '��' => '渟',
  '��' => '湃',
  '��' => '渺',
  '��' => '湎',
  '��' => '渤',
  '��' => '滿',
  '��' => '渝',
  '��' => '游',
  '��' => '溂',
  '��' => '溪',
  '��' => '溘',
  '��' => '滉',
  '��' => '溷',
  '��' => '滓',
  '��' => '溽',
  '��' => '溯',
  '��' => '滄',
  '��' => '溲',
  '��' => '滔',
  '��' => '滕',
  '��' => '溏',
  '��' => '溥',
  '��' => '滂',
  '��' => '溟',
  '��' => '潁',
  '��' => '漑',
  '��' => '灌',
  '��' => '滬',
  '��' => '滸',
  '��' => '滾',
  '��' => '漿',
  '��' => '滲',
  '��' => '漱',
  '��' => '滯',
  '��' => '漲',
  '��' => '滌',
  '�@' => '漾',
  '�A' => '漓',
  '�B' => '滷',
  '�C' => '澆',
  '�D' => '潺',
  '�E' => '潸',
  '�F' => '澁',
  '�G' => '澀',
  '�H' => '潯',
  '�I' => '潛',
  '�J' => '濳',
  '�K' => '潭',
  '�L' => '澂',
  '�M' => '潼',
  '�N' => '潘',
  '�O' => '澎',
  '�P' => '澑',
  '�Q' => '濂',
  '�R' => '潦',
  '�S' => '澳',
  '�T' => '澣',
  '�U' => '澡',
  '�V' => '澤',
  '�W' => '澹',
  '�X' => '濆',
  '�Y' => '澪',
  '�Z' => '濟',
  '�[' => '濕',
  '�\\' => '濬',
  '�]' => '濔',
  '�^' => '濘',
  '�_' => '濱',
  '�`' => '濮',
  '�a' => '濛',
  '�b' => '瀉',
  '�c' => '瀋',
  '�d' => '濺',
  '�e' => '瀑',
  '�f' => '瀁',
  '�g' => '瀏',
  '�h' => '濾',
  '�i' => '瀛',
  '�j' => '瀚',
  '�k' => '潴',
  '�l' => '瀝',
  '�m' => '瀘',
  '�n' => '瀟',
  '�o' => '瀰',
  '�p' => '瀾',
  '�q' => '瀲',
  '�r' => '灑',
  '�s' => '灣',
  '�t' => '炙',
  '�u' => '炒',
  '�v' => '炯',
  '�w' => '烱',
  '�x' => '炬',
  '�y' => '炸',
  '�z' => '炳',
  '�{' => '炮',
  '�|' => '烟',
  '�}' => '烋',
  '�~' => '烝',
  '�' => '烙',
  '�' => '焉',
  '�' => '烽',
  '�' => '焜',
  '�' => '焙',
  '�' => '煥',
  '�' => '煕',
  '�' => '熈',
  '�' => '煦',
  '�' => '煢',
  '�' => '煌',
  '�' => '煖',
  '�' => '煬',
  '�' => '熏',
  '�' => '燻',
  '�' => '熄',
  '�' => '熕',
  '�' => '熨',
  '�' => '熬',
  '�' => '燗',
  '�' => '熹',
  '�' => '熾',
  '�' => '燒',
  '�' => '燉',
  '�' => '燔',
  '�' => '燎',
  '�' => '燠',
  '�' => '燬',
  '�' => '燧',
  '�' => '燵',
  '�' => '燼',
  '�' => '燹',
  '�' => '燿',
  '�' => '爍',
  '�' => '爐',
  '�' => '爛',
  '�' => '爨',
  '�' => '爭',
  '�' => '爬',
  '�' => '爰',
  '�' => '爲',
  '�' => '爻',
  '�' => '爼',
  '�' => '爿',
  '�' => '牀',
  '�' => '牆',
  '�' => '牋',
  '�' => '牘',
  '�' => '牴',
  '�' => '牾',
  '�' => '犂',
  '�' => '犁',
  '�' => '犇',
  '�' => '犒',
  '�' => '犖',
  '�' => '犢',
  '�' => '犧',
  '�' => '犹',
  '�' => '犲',
  '�' => '狃',
  '�' => '狆',
  '�' => '狄',
  '�' => '狎',
  '�' => '狒',
  '�' => '狢',
  '�' => '狠',
  '��' => '狡',
  '��' => '狹',
  '��' => '狷',
  '��' => '倏',
  '��' => '猗',
  '��' => '猊',
  '��' => '猜',
  '��' => '猖',
  '��' => '猝',
  '��' => '猴',
  '��' => '猯',
  '��' => '猩',
  '��' => '猥',
  '��' => '猾',
  '��' => '獎',
  '��' => '獏',
  '��' => '默',
  '��' => '獗',
  '��' => '獪',
  '��' => '獨',
  '��' => '獰',
  '��' => '獸',
  '��' => '獵',
  '��' => '獻',
  '��' => '獺',
  '��' => '珈',
  '��' => '玳',
  '��' => '珎',
  '��' => '玻',
  '��' => '珀',
  '��' => '珥',
  '��' => '珮',
  '��' => '珞',
  '��' => '璢',
  '��' => '琅',
  '��' => '瑯',
  '��' => '琥',
  '��' => '珸',
  '��' => '琲',
  '��' => '琺',
  '��' => '瑕',
  '��' => '琿',
  '��' => '瑟',
  '��' => '瑙',
  '��' => '瑁',
  '��' => '瑜',
  '��' => '瑩',
  '��' => '瑰',
  '��' => '瑣',
  '��' => '瑪',
  '��' => '瑶',
  '�' => '瑾',
  '�' => '璋',
  '�' => '璞',
  '�' => '璧',
  '�' => '瓊',
  '�' => '瓏',
  '�' => '瓔',
  '�' => '珱',
  '�@' => '瓠',
  '�A' => '瓣',
  '�B' => '瓧',
  '�C' => '瓩',
  '�D' => '瓮',
  '�E' => '瓲',
  '�F' => '瓰',
  '�G' => '瓱',
  '�H' => '瓸',
  '�I' => '瓷',
  '�J' => '甄',
  '�K' => '甃',
  '�L' => '甅',
  '�M' => '甌',
  '�N' => '甎',
  '�O' => '甍',
  '�P' => '甕',
  '�Q' => '甓',
  '�R' => '甞',
  '�S' => '甦',
  '�T' => '甬',
  '�U' => '甼',
  '�V' => '畄',
  '�W' => '畍',
  '�X' => '畊',
  '�Y' => '畉',
  '�Z' => '畛',
  '�[' => '畆',
  '�\\' => '畚',
  '�]' => '畩',
  '�^' => '畤',
  '�_' => '畧',
  '�`' => '畫',
  '�a' => '畭',
  '�b' => '畸',
  '�c' => '當',
  '�d' => '疆',
  '�e' => '疇',
  '�f' => '畴',
  '�g' => '疊',
  '�h' => '疉',
  '�i' => '疂',
  '�j' => '疔',
  '�k' => '疚',
  '�l' => '疝',
  '�m' => '疥',
  '�n' => '疣',
  '�o' => '痂',
  '�p' => '疳',
  '�q' => '痃',
  '�r' => '疵',
  '�s' => '疽',
  '�t' => '疸',
  '�u' => '疼',
  '�v' => '疱',
  '�w' => '痍',
  '�x' => '痊',
  '�y' => '痒',
  '�z' => '痙',
  '�{' => '痣',
  '�|' => '痞',
  '�}' => '痾',
  '�~' => '痿',
  '�' => '痼',
  '�' => '瘁',
  '�' => '痰',
  '�' => '痺',
  '�' => '痲',
  '�' => '痳',
  '�' => '瘋',
  '�' => '瘍',
  '�' => '瘉',
  '�' => '瘟',
  '�' => '瘧',
  '�' => '瘠',
  '�' => '瘡',
  '�' => '瘢',
  '�' => '瘤',
  '�' => '瘴',
  '�' => '瘰',
  '�' => '瘻',
  '�' => '癇',
  '�' => '癈',
  '�' => '癆',
  '�' => '癜',
  '�' => '癘',
  '�' => '癡',
  '�' => '癢',
  '�' => '癨',
  '�' => '癩',
  '�' => '癪',
  '�' => '癧',
  '�' => '癬',
  '�' => '癰',
  '�' => '癲',
  '�' => '癶',
  '�' => '癸',
  '�' => '發',
  '�' => '皀',
  '�' => '皃',
  '�' => '皈',
  '�' => '皋',
  '�' => '皎',
  '�' => '皖',
  '�' => '皓',
  '�' => '皙',
  '�' => '皚',
  '�' => '皰',
  '�' => '皴',
  '�' => '皸',
  '�' => '皹',
  '�' => '皺',
  '�' => '盂',
  '�' => '盍',
  '�' => '盖',
  '�' => '盒',
  '�' => '盞',
  '�' => '盡',
  '�' => '盥',
  '�' => '盧',
  '�' => '盪',
  '�' => '蘯',
  '�' => '盻',
  '�' => '眈',
  '�' => '眇',
  '�' => '眄',
  '�' => '眩',
  '�' => '眤',
  '�' => '眞',
  '��' => '眥',
  '��' => '眦',
  '��' => '眛',
  '��' => '眷',
  '��' => '眸',
  '��' => '睇',
  '��' => '睚',
  '��' => '睨',
  '��' => '睫',
  '��' => '睛',
  '��' => '睥',
  '��' => '睿',
  '��' => '睾',
  '��' => '睹',
  '��' => '瞎',
  '��' => '瞋',
  '��' => '瞑',
  '��' => '瞠',
  '��' => '瞞',
  '��' => '瞰',
  '��' => '瞶',
  '��' => '瞹',
  '��' => '瞿',
  '��' => '瞼',
  '��' => '瞽',
  '��' => '瞻',
  '��' => '矇',
  '��' => '矍',
  '��' => '矗',
  '��' => '矚',
  '��' => '矜',
  '��' => '矣',
  '��' => '矮',
  '��' => '矼',
  '��' => '砌',
  '��' => '砒',
  '��' => '礦',
  '��' => '砠',
  '��' => '礪',
  '��' => '硅',
  '��' => '碎',
  '��' => '硴',
  '��' => '碆',
  '��' => '硼',
  '��' => '碚',
  '��' => '碌',
  '��' => '碣',
  '��' => '碵',
  '��' => '碪',
  '��' => '碯',
  '��' => '磑',
  '�' => '磆',
  '�' => '磋',
  '�' => '磔',
  '�' => '碾',
  '�' => '碼',
  '�' => '磅',
  '�' => '磊',
  '�' => '磬',
  '�@' => '磧',
  '�A' => '磚',
  '�B' => '磽',
  '�C' => '磴',
  '�D' => '礇',
  '�E' => '礒',
  '�F' => '礑',
  '�G' => '礙',
  '�H' => '礬',
  '�I' => '礫',
  '�J' => '祀',
  '�K' => '祠',
  '�L' => '祗',
  '�M' => '祟',
  '�N' => '祚',
  '�O' => '祕',
  '�P' => '祓',
  '�Q' => '祺',
  '�R' => '祿',
  '�S' => '禊',
  '�T' => '禝',
  '�U' => '禧',
  '�V' => '齋',
  '�W' => '禪',
  '�X' => '禮',
  '�Y' => '禳',
  '�Z' => '禹',
  '�[' => '禺',
  '�\\' => '秉',
  '�]' => '秕',
  '�^' => '秧',
  '�_' => '秬',
  '�`' => '秡',
  '�a' => '秣',
  '�b' => '稈',
  '�c' => '稍',
  '�d' => '稘',
  '�e' => '稙',
  '�f' => '稠',
  '�g' => '稟',
  '�h' => '禀',
  '�i' => '稱',
  '�j' => '稻',
  '�k' => '稾',
  '�l' => '稷',
  '�m' => '穃',
  '�n' => '穗',
  '�o' => '穉',
  '�p' => '穡',
  '�q' => '穢',
  '�r' => '穩',
  '�s' => '龝',
  '�t' => '穰',
  '�u' => '穹',
  '�v' => '穽',
  '�w' => '窈',
  '�x' => '窗',
  '�y' => '窕',
  '�z' => '窘',
  '�{' => '窖',
  '�|' => '窩',
  '�}' => '竈',
  '�~' => '窰',
  '�' => '窶',
  '�' => '竅',
  '�' => '竄',
  '�' => '窿',
  '�' => '邃',
  '�' => '竇',
  '�' => '竊',
  '�' => '竍',
  '�' => '竏',
  '�' => '竕',
  '�' => '竓',
  '�' => '站',
  '�' => '竚',
  '�' => '竝',
  '�' => '竡',
  '�' => '竢',
  '�' => '竦',
  '�' => '竭',
  '�' => '竰',
  '�' => '笂',
  '�' => '笏',
  '�' => '笊',
  '�' => '笆',
  '�' => '笳',
  '�' => '笘',
  '�' => '笙',
  '�' => '笞',
  '�' => '笵',
  '�' => '笨',
  '�' => '笶',
  '�' => '筐',
  '�' => '筺',
  '�' => '笄',
  '�' => '筍',
  '�' => '笋',
  '�' => '筌',
  '�' => '筅',
  '�' => '筵',
  '�' => '筥',
  '�' => '筴',
  '�' => '筧',
  '�' => '筰',
  '�' => '筱',
  '�' => '筬',
  '�' => '筮',
  '�' => '箝',
  '�' => '箘',
  '�' => '箟',
  '�' => '箍',
  '�' => '箜',
  '�' => '箚',
  '�' => '箋',
  '�' => '箒',
  '�' => '箏',
  '�' => '筝',
  '�' => '箙',
  '�' => '篋',
  '�' => '篁',
  '�' => '篌',
  '�' => '篏',
  '�' => '箴',
  '�' => '篆',
  '�' => '篝',
  '�' => '篩',
  '�' => '簑',
  '�' => '簔',
  '��' => '篦',
  '��' => '篥',
  '��' => '籠',
  '��' => '簀',
  '��' => '簇',
  '��' => '簓',
  '��' => '篳',
  '��' => '篷',
  '��' => '簗',
  '��' => '簍',
  '��' => '篶',
  '��' => '簣',
  '��' => '簧',
  '��' => '簪',
  '��' => '簟',
  '��' => '簷',
  '��' => '簫',
  '��' => '簽',
  '��' => '籌',
  '��' => '籃',
  '��' => '籔',
  '��' => '籏',
  '��' => '籀',
  '��' => '籐',
  '��' => '籘',
  '��' => '籟',
  '��' => '籤',
  '��' => '籖',
  '��' => '籥',
  '��' => '籬',
  '��' => '籵',
  '��' => '粃',
  '��' => '粐',
  '��' => '粤',
  '��' => '粭',
  '��' => '粢',
  '��' => '粫',
  '��' => '粡',
  '��' => '粨',
  '��' => '粳',
  '��' => '粲',
  '��' => '粱',
  '��' => '粮',
  '��' => '粹',
  '��' => '粽',
  '��' => '糀',
  '��' => '糅',
  '��' => '糂',
  '��' => '糘',
  '��' => '糒',
  '��' => '糜',
  '�' => '糢',
  '�' => '鬻',
  '�' => '糯',
  '�' => '糲',
  '�' => '糴',
  '�' => '糶',
  '�' => '糺',
  '�' => '紆',
  '�@' => '紂',
  '�A' => '紜',
  '�B' => '紕',
  '�C' => '紊',
  '�D' => '絅',
  '�E' => '絋',
  '�F' => '紮',
  '�G' => '紲',
  '�H' => '紿',
  '�I' => '紵',
  '�J' => '絆',
  '�K' => '絳',
  '�L' => '絖',
  '�M' => '絎',
  '�N' => '絲',
  '�O' => '絨',
  '�P' => '絮',
  '�Q' => '絏',
  '�R' => '絣',
  '�S' => '經',
  '�T' => '綉',
  '�U' => '絛',
  '�V' => '綏',
  '�W' => '絽',
  '�X' => '綛',
  '�Y' => '綺',
  '�Z' => '綮',
  '�[' => '綣',
  '�\\' => '綵',
  '�]' => '緇',
  '�^' => '綽',
  '�_' => '綫',
  '�`' => '總',
  '�a' => '綢',
  '�b' => '綯',
  '�c' => '緜',
  '�d' => '綸',
  '�e' => '綟',
  '�f' => '綰',
  '�g' => '緘',
  '�h' => '緝',
  '�i' => '緤',
  '�j' => '緞',
  '�k' => '緻',
  '�l' => '緲',
  '�m' => '緡',
  '�n' => '縅',
  '�o' => '縊',
  '�p' => '縣',
  '�q' => '縡',
  '�r' => '縒',
  '�s' => '縱',
  '�t' => '縟',
  '�u' => '縉',
  '�v' => '縋',
  '�w' => '縢',
  '�x' => '繆',
  '�y' => '繦',
  '�z' => '縻',
  '�{' => '縵',
  '�|' => '縹',
  '�}' => '繃',
  '�~' => '縷',
  '�' => '縲',
  '�' => '縺',
  '�' => '繧',
  '�' => '繝',
  '�' => '繖',
  '�' => '繞',
  '�' => '繙',
  '�' => '繚',
  '�' => '繹',
  '�' => '繪',
  '�' => '繩',
  '�' => '繼',
  '�' => '繻',
  '�' => '纃',
  '�' => '緕',
  '�' => '繽',
  '�' => '辮',
  '�' => '繿',
  '�' => '纈',
  '�' => '纉',
  '�' => '續',
  '�' => '纒',
  '�' => '纐',
  '�' => '纓',
  '�' => '纔',
  '�' => '纖',
  '�' => '纎',
  '�' => '纛',
  '�' => '纜',
  '�' => '缸',
  '�' => '缺',
  '�' => '罅',
  '�' => '罌',
  '�' => '罍',
  '�' => '罎',
  '�' => '罐',
  '�' => '网',
  '�' => '罕',
  '�' => '罔',
  '�' => '罘',
  '�' => '罟',
  '�' => '罠',
  '�' => '罨',
  '�' => '罩',
  '�' => '罧',
  '�' => '罸',
  '�' => '羂',
  '�' => '羆',
  '�' => '羃',
  '�' => '羈',
  '�' => '羇',
  '�' => '羌',
  '�' => '羔',
  '�' => '羞',
  '�' => '羝',
  '�' => '羚',
  '�' => '羣',
  '�' => '羯',
  '�' => '羲',
  '�' => '羹',
  '�' => '羮',
  '�' => '羶',
  '�' => '羸',
  '�' => '譱',
  '�' => '翅',
  '�' => '翆',
  '��' => '翊',
  '��' => '翕',
  '��' => '翔',
  '��' => '翡',
  '��' => '翦',
  '��' => '翩',
  '��' => '翳',
  '��' => '翹',
  '��' => '飜',
  '��' => '耆',
  '��' => '耄',
  '��' => '耋',
  '��' => '耒',
  '��' => '耘',
  '��' => '耙',
  '��' => '耜',
  '��' => '耡',
  '��' => '耨',
  '��' => '耿',
  '��' => '耻',
  '��' => '聊',
  '��' => '聆',
  '��' => '聒',
  '��' => '聘',
  '��' => '聚',
  '��' => '聟',
  '��' => '聢',
  '��' => '聨',
  '��' => '聳',
  '��' => '聲',
  '��' => '聰',
  '��' => '聶',
  '��' => '聹',
  '��' => '聽',
  '��' => '聿',
  '��' => '肄',
  '��' => '肆',
  '��' => '肅',
  '��' => '肛',
  '��' => '肓',
  '��' => '肚',
  '��' => '肭',
  '��' => '冐',
  '��' => '肬',
  '��' => '胛',
  '��' => '胥',
  '��' => '胙',
  '��' => '胝',
  '��' => '胄',
  '��' => '胚',
  '��' => '胖',
  '�' => '脉',
  '�' => '胯',
  '�' => '胱',
  '�' => '脛',
  '�' => '脩',
  '�' => '脣',
  '�' => '脯',
  '�' => '腋',
  '�@' => '隋',
  '�A' => '腆',
  '�B' => '脾',
  '�C' => '腓',
  '�D' => '腑',
  '�E' => '胼',
  '�F' => '腱',
  '�G' => '腮',
  '�H' => '腥',
  '�I' => '腦',
  '�J' => '腴',
  '�K' => '膃',
  '�L' => '膈',
  '�M' => '膊',
  '�N' => '膀',
  '�O' => '膂',
  '�P' => '膠',
  '�Q' => '膕',
  '�R' => '膤',
  '�S' => '膣',
  '�T' => '腟',
  '�U' => '膓',
  '�V' => '膩',
  '�W' => '膰',
  '�X' => '膵',
  '�Y' => '膾',
  '�Z' => '膸',
  '�[' => '膽',
  '�\\' => '臀',
  '�]' => '臂',
  '�^' => '膺',
  '�_' => '臉',
  '�`' => '臍',
  '�a' => '臑',
  '�b' => '臙',
  '�c' => '臘',
  '�d' => '臈',
  '�e' => '臚',
  '�f' => '臟',
  '�g' => '臠',
  '�h' => '臧',
  '�i' => '臺',
  '�j' => '臻',
  '�k' => '臾',
  '�l' => '舁',
  '�m' => '舂',
  '�n' => '舅',
  '�o' => '與',
  '�p' => '舊',
  '�q' => '舍',
  '�r' => '舐',
  '�s' => '舖',
  '�t' => '舩',
  '�u' => '舫',
  '�v' => '舸',
  '�w' => '舳',
  '�x' => '艀',
  '�y' => '艙',
  '�z' => '艘',
  '�{' => '艝',
  '�|' => '艚',
  '�}' => '艟',
  '�~' => '艤',
  '�' => '艢',
  '�' => '艨',
  '�' => '艪',
  '�' => '艫',
  '�' => '舮',
  '�' => '艱',
  '�' => '艷',
  '�' => '艸',
  '�' => '艾',
  '�' => '芍',
  '�' => '芒',
  '�' => '芫',
  '�' => '芟',
  '�' => '芻',
  '�' => '芬',
  '�' => '苡',
  '�' => '苣',
  '�' => '苟',
  '�' => '苒',
  '�' => '苴',
  '�' => '苳',
  '�' => '苺',
  '�' => '莓',
  '�' => '范',
  '�' => '苻',
  '�' => '苹',
  '�' => '苞',
  '�' => '茆',
  '�' => '苜',
  '�' => '茉',
  '�' => '苙',
  '�' => '茵',
  '�' => '茴',
  '�' => '茖',
  '�' => '茲',
  '�' => '茱',
  '�' => '荀',
  '�' => '茹',
  '�' => '荐',
  '�' => '荅',
  '�' => '茯',
  '�' => '茫',
  '�' => '茗',
  '�' => '茘',
  '�' => '莅',
  '�' => '莚',
  '�' => '莪',
  '�' => '莟',
  '�' => '莢',
  '�' => '莖',
  '�' => '茣',
  '�' => '莎',
  '�' => '莇',
  '�' => '莊',
  '�' => '荼',
  '�' => '莵',
  '�' => '荳',
  '�' => '荵',
  '�' => '莠',
  '�' => '莉',
  '�' => '莨',
  '�' => '菴',
  '�' => '萓',
  '�' => '菫',
  '�' => '菎',
  '�' => '菽',
  '��' => '萃',
  '��' => '菘',
  '��' => '萋',
  '��' => '菁',
  '��' => '菷',
  '��' => '萇',
  '��' => '菠',
  '��' => '菲',
  '��' => '萍',
  '��' => '萢',
  '��' => '萠',
  '��' => '莽',
  '��' => '萸',
  '��' => '蔆',
  '��' => '菻',
  '��' => '葭',
  '��' => '萪',
  '��' => '萼',
  '��' => '蕚',
  '��' => '蒄',
  '��' => '葷',
  '��' => '葫',
  '��' => '蒭',
  '��' => '葮',
  '��' => '蒂',
  '��' => '葩',
  '��' => '葆',
  '��' => '萬',
  '��' => '葯',
  '��' => '葹',
  '��' => '萵',
  '��' => '蓊',
  '��' => '葢',
  '��' => '蒹',
  '��' => '蒿',
  '��' => '蒟',
  '��' => '蓙',
  '��' => '蓍',
  '��' => '蒻',
  '��' => '蓚',
  '��' => '蓐',
  '��' => '蓁',
  '��' => '蓆',
  '��' => '蓖',
  '��' => '蒡',
  '��' => '蔡',
  '��' => '蓿',
  '��' => '蓴',
  '��' => '蔗',
  '��' => '蔘',
  '��' => '蔬',
  '�' => '蔟',
  '�' => '蔕',
  '�' => '蔔',
  '�' => '蓼',
  '�' => '蕀',
  '�' => '蕣',
  '�' => '蕘',
  '�' => '蕈',
  '�@' => '蕁',
  '�A' => '蘂',
  '�B' => '蕋',
  '�C' => '蕕',
  '�D' => '薀',
  '�E' => '薤',
  '�F' => '薈',
  '�G' => '薑',
  '�H' => '薊',
  '�I' => '薨',
  '�J' => '蕭',
  '�K' => '薔',
  '�L' => '薛',
  '�M' => '藪',
  '�N' => '薇',
  '�O' => '薜',
  '�P' => '蕷',
  '�Q' => '蕾',
  '�R' => '薐',
  '�S' => '藉',
  '�T' => '薺',
  '�U' => '藏',
  '�V' => '薹',
  '�W' => '藐',
  '�X' => '藕',
  '�Y' => '藝',
  '�Z' => '藥',
  '�[' => '藜',
  '�\\' => '藹',
  '�]' => '蘊',
  '�^' => '蘓',
  '�_' => '蘋',
  '�`' => '藾',
  '�a' => '藺',
  '�b' => '蘆',
  '�c' => '蘢',
  '�d' => '蘚',
  '�e' => '蘰',
  '�f' => '蘿',
  '�g' => '虍',
  '�h' => '乕',
  '�i' => '虔',
  '�j' => '號',
  '�k' => '虧',
  '�l' => '虱',
  '�m' => '蚓',
  '�n' => '蚣',
  '�o' => '蚩',
  '�p' => '蚪',
  '�q' => '蚋',
  '�r' => '蚌',
  '�s' => '蚶',
  '�t' => '蚯',
  '�u' => '蛄',
  '�v' => '蛆',
  '�w' => '蚰',
  '�x' => '蛉',
  '�y' => '蠣',
  '�z' => '蚫',
  '�{' => '蛔',
  '�|' => '蛞',
  '�}' => '蛩',
  '�~' => '蛬',
  '�' => '蛟',
  '�' => '蛛',
  '�' => '蛯',
  '�' => '蜒',
  '�' => '蜆',
  '�' => '蜈',
  '�' => '蜀',
  '�' => '蜃',
  '�' => '蛻',
  '�' => '蜑',
  '�' => '蜉',
  '�' => '蜍',
  '�' => '蛹',
  '�' => '蜊',
  '�' => '蜴',
  '�' => '蜿',
  '�' => '蜷',
  '�' => '蜻',
  '�' => '蜥',
  '�' => '蜩',
  '�' => '蜚',
  '�' => '蝠',
  '�' => '蝟',
  '�' => '蝸',
  '�' => '蝌',
  '�' => '蝎',
  '�' => '蝴',
  '�' => '蝗',
  '�' => '蝨',
  '�' => '蝮',
  '�' => '蝙',
  '�' => '蝓',
  '�' => '蝣',
  '�' => '蝪',
  '�' => '蠅',
  '�' => '螢',
  '�' => '螟',
  '�' => '螂',
  '�' => '螯',
  '�' => '蟋',
  '�' => '螽',
  '�' => '蟀',
  '�' => '蟐',
  '�' => '雖',
  '�' => '螫',
  '�' => '蟄',
  '�' => '螳',
  '�' => '蟇',
  '�' => '蟆',
  '�' => '螻',
  '�' => '蟯',
  '�' => '蟲',
  '�' => '蟠',
  '�' => '蠏',
  '�' => '蠍',
  '�' => '蟾',
  '�' => '蟶',
  '�' => '蟷',
  '�' => '蠎',
  '�' => '蟒',
  '�' => '蠑',
  '�' => '蠖',
  '�' => '蠕',
  '�' => '蠢',
  '�' => '蠡',
  '�' => '蠱',
  '��' => '蠶',
  '��' => '蠹',
  '��' => '蠧',
  '��' => '蠻',
  '��' => '衄',
  '��' => '衂',
  '��' => '衒',
  '��' => '衙',
  '��' => '衞',
  '��' => '衢',
  '��' => '衫',
  '��' => '袁',
  '��' => '衾',
  '��' => '袞',
  '��' => '衵',
  '��' => '衽',
  '��' => '袵',
  '��' => '衲',
  '��' => '袂',
  '��' => '袗',
  '��' => '袒',
  '��' => '袮',
  '��' => '袙',
  '��' => '袢',
  '��' => '袍',
  '��' => '袤',
  '��' => '袰',
  '��' => '袿',
  '��' => '袱',
  '��' => '裃',
  '��' => '裄',
  '��' => '裔',
  '��' => '裘',
  '��' => '裙',
  '��' => '裝',
  '��' => '裹',
  '��' => '褂',
  '��' => '裼',
  '��' => '裴',
  '��' => '裨',
  '��' => '裲',
  '��' => '褄',
  '��' => '褌',
  '��' => '褊',
  '��' => '褓',
  '��' => '襃',
  '��' => '褞',
  '��' => '褥',
  '��' => '褪',
  '��' => '褫',
  '��' => '襁',
  '�' => '襄',
  '�' => '褻',
  '�' => '褶',
  '�' => '褸',
  '�' => '襌',
  '�' => '褝',
  '�' => '襠',
  '�' => '襞',
  '�@' => '襦',
  '�A' => '襤',
  '�B' => '襭',
  '�C' => '襪',
  '�D' => '襯',
  '�E' => '襴',
  '�F' => '襷',
  '�G' => '襾',
  '�H' => '覃',
  '�I' => '覈',
  '�J' => '覊',
  '�K' => '覓',
  '�L' => '覘',
  '�M' => '覡',
  '�N' => '覩',
  '�O' => '覦',
  '�P' => '覬',
  '�Q' => '覯',
  '�R' => '覲',
  '�S' => '覺',
  '�T' => '覽',
  '�U' => '覿',
  '�V' => '觀',
  '�W' => '觚',
  '�X' => '觜',
  '�Y' => '觝',
  '�Z' => '觧',
  '�[' => '觴',
  '�\\' => '觸',
  '�]' => '訃',
  '�^' => '訖',
  '�_' => '訐',
  '�`' => '訌',
  '�a' => '訛',
  '�b' => '訝',
  '�c' => '訥',
  '�d' => '訶',
  '�e' => '詁',
  '�f' => '詛',
  '�g' => '詒',
  '�h' => '詆',
  '�i' => '詈',
  '�j' => '詼',
  '�k' => '詭',
  '�l' => '詬',
  '�m' => '詢',
  '�n' => '誅',
  '�o' => '誂',
  '�p' => '誄',
  '�q' => '誨',
  '�r' => '誡',
  '�s' => '誑',
  '�t' => '誥',
  '�u' => '誦',
  '�v' => '誚',
  '�w' => '誣',
  '�x' => '諄',
  '�y' => '諍',
  '�z' => '諂',
  '�{' => '諚',
  '�|' => '諫',
  '�}' => '諳',
  '�~' => '諧',
  '�' => '諤',
  '�' => '諱',
  '�' => '謔',
  '�' => '諠',
  '�' => '諢',
  '�' => '諷',
  '�' => '諞',
  '�' => '諛',
  '�' => '謌',
  '�' => '謇',
  '�' => '謚',
  '�' => '諡',
  '�' => '謖',
  '�' => '謐',
  '�' => '謗',
  '�' => '謠',
  '�' => '謳',
  '�' => '鞫',
  '�' => '謦',
  '�' => '謫',
  '�' => '謾',
  '�' => '謨',
  '�' => '譁',
  '�' => '譌',
  '�' => '譏',
  '�' => '譎',
  '�' => '證',
  '�' => '譖',
  '�' => '譛',
  '�' => '譚',
  '�' => '譫',
  '�' => '譟',
  '�' => '譬',
  '�' => '譯',
  '�' => '譴',
  '�' => '譽',
  '�' => '讀',
  '�' => '讌',
  '�' => '讎',
  '�' => '讒',
  '�' => '讓',
  '�' => '讖',
  '�' => '讙',
  '�' => '讚',
  '�' => '谺',
  '�' => '豁',
  '�' => '谿',
  '�' => '豈',
  '�' => '豌',
  '�' => '豎',
  '�' => '豐',
  '�' => '豕',
  '�' => '豢',
  '�' => '豬',
  '�' => '豸',
  '�' => '豺',
  '�' => '貂',
  '�' => '貉',
  '�' => '貅',
  '�' => '貊',
  '�' => '貍',
  '�' => '貎',
  '�' => '貔',
  '�' => '豼',
  '�' => '貘',
  '�' => '戝',
  '��' => '貭',
  '��' => '貪',
  '��' => '貽',
  '��' => '貲',
  '��' => '貳',
  '��' => '貮',
  '��' => '貶',
  '��' => '賈',
  '��' => '賁',
  '��' => '賤',
  '��' => '賣',
  '��' => '賚',
  '��' => '賽',
  '��' => '賺',
  '��' => '賻',
  '��' => '贄',
  '��' => '贅',
  '��' => '贊',
  '��' => '贇',
  '��' => '贏',
  '��' => '贍',
  '��' => '贐',
  '��' => '齎',
  '��' => '贓',
  '��' => '賍',
  '��' => '贔',
  '��' => '贖',
  '��' => '赧',
  '��' => '赭',
  '��' => '赱',
  '��' => '赳',
  '��' => '趁',
  '��' => '趙',
  '��' => '跂',
  '��' => '趾',
  '��' => '趺',
  '��' => '跏',
  '��' => '跚',
  '��' => '跖',
  '��' => '跌',
  '��' => '跛',
  '��' => '跋',
  '��' => '跪',
  '��' => '跫',
  '��' => '跟',
  '��' => '跣',
  '��' => '跼',
  '��' => '踈',
  '��' => '踉',
  '��' => '跿',
  '��' => '踝',
  '�' => '踞',
  '�' => '踐',
  '�' => '踟',
  '�' => '蹂',
  '�' => '踵',
  '�' => '踰',
  '�' => '踴',
  '�' => '蹊',
  '�@' => '蹇',
  '�A' => '蹉',
  '�B' => '蹌',
  '�C' => '蹐',
  '�D' => '蹈',
  '�E' => '蹙',
  '�F' => '蹤',
  '�G' => '蹠',
  '�H' => '踪',
  '�I' => '蹣',
  '�J' => '蹕',
  '�K' => '蹶',
  '�L' => '蹲',
  '�M' => '蹼',
  '�N' => '躁',
  '�O' => '躇',
  '�P' => '躅',
  '�Q' => '躄',
  '�R' => '躋',
  '�S' => '躊',
  '�T' => '躓',
  '�U' => '躑',
  '�V' => '躔',
  '�W' => '躙',
  '�X' => '躪',
  '�Y' => '躡',
  '�Z' => '躬',
  '�[' => '躰',
  '�\\' => '軆',
  '�]' => '躱',
  '�^' => '躾',
  '�_' => '軅',
  '�`' => '軈',
  '�a' => '軋',
  '�b' => '軛',
  '�c' => '軣',
  '�d' => '軼',
  '�e' => '軻',
  '�f' => '軫',
  '�g' => '軾',
  '�h' => '輊',
  '�i' => '輅',
  '�j' => '輕',
  '�k' => '輒',
  '�l' => '輙',
  '�m' => '輓',
  '�n' => '輜',
  '�o' => '輟',
  '�p' => '輛',
  '�q' => '輌',
  '�r' => '輦',
  '�s' => '輳',
  '�t' => '輻',
  '�u' => '輹',
  '�v' => '轅',
  '�w' => '轂',
  '�x' => '輾',
  '�y' => '轌',
  '�z' => '轉',
  '�{' => '轆',
  '�|' => '轎',
  '�}' => '轗',
  '�~' => '轜',
  '�' => '轢',
  '�' => '轣',
  '�' => '轤',
  '�' => '辜',
  '�' => '辟',
  '�' => '辣',
  '�' => '辭',
  '�' => '辯',
  '�' => '辷',
  '�' => '迚',
  '�' => '迥',
  '�' => '迢',
  '�' => '迪',
  '�' => '迯',
  '�' => '邇',
  '�' => '迴',
  '�' => '逅',
  '�' => '迹',
  '�' => '迺',
  '�' => '逑',
  '�' => '逕',
  '�' => '逡',
  '�' => '逍',
  '�' => '逞',
  '�' => '逖',
  '�' => '逋',
  '�' => '逧',
  '�' => '逶',
  '�' => '逵',
  '�' => '逹',
  '�' => '迸',
  '�' => '遏',
  '�' => '遐',
  '�' => '遑',
  '�' => '遒',
  '�' => '逎',
  '�' => '遉',
  '�' => '逾',
  '�' => '遖',
  '�' => '遘',
  '�' => '遞',
  '�' => '遨',
  '�' => '遯',
  '�' => '遶',
  '�' => '隨',
  '�' => '遲',
  '�' => '邂',
  '�' => '遽',
  '�' => '邁',
  '�' => '邀',
  '�' => '邊',
  '�' => '邉',
  '�' => '邏',
  '�' => '邨',
  '�' => '邯',
  '�' => '邱',
  '�' => '邵',
  '�' => '郢',
  '�' => '郤',
  '�' => '扈',
  '�' => '郛',
  '�' => '鄂',
  '�' => '鄒',
  '�' => '鄙',
  '�' => '鄲',
  '�' => '鄰',
  '��' => '酊',
  '��' => '酖',
  '��' => '酘',
  '��' => '酣',
  '��' => '酥',
  '��' => '酩',
  '��' => '酳',
  '��' => '酲',
  '��' => '醋',
  '��' => '醉',
  '��' => '醂',
  '��' => '醢',
  '��' => '醫',
  '��' => '醯',
  '��' => '醪',
  '��' => '醵',
  '��' => '醴',
  '��' => '醺',
  '��' => '釀',
  '��' => '釁',
  '��' => '釉',
  '��' => '釋',
  '��' => '釐',
  '��' => '釖',
  '��' => '釟',
  '��' => '釡',
  '��' => '釛',
  '��' => '釼',
  '��' => '釵',
  '��' => '釶',
  '��' => '鈞',
  '��' => '釿',
  '��' => '鈔',
  '��' => '鈬',
  '��' => '鈕',
  '��' => '鈑',
  '��' => '鉞',
  '��' => '鉗',
  '��' => '鉅',
  '��' => '鉉',
  '��' => '鉤',
  '��' => '鉈',
  '��' => '銕',
  '��' => '鈿',
  '��' => '鉋',
  '��' => '鉐',
  '��' => '銜',
  '��' => '銖',
  '��' => '銓',
  '��' => '銛',
  '��' => '鉚',
  '�' => '鋏',
  '�' => '銹',
  '�' => '銷',
  '�' => '鋩',
  '�' => '錏',
  '�' => '鋺',
  '�' => '鍄',
  '�' => '錮',
  '�@' => '錙',
  '�A' => '錢',
  '�B' => '錚',
  '�C' => '錣',
  '�D' => '錺',
  '�E' => '錵',
  '�F' => '錻',
  '�G' => '鍜',
  '�H' => '鍠',
  '�I' => '鍼',
  '�J' => '鍮',
  '�K' => '鍖',
  '�L' => '鎰',
  '�M' => '鎬',
  '�N' => '鎭',
  '�O' => '鎔',
  '�P' => '鎹',
  '�Q' => '鏖',
  '�R' => '鏗',
  '�S' => '鏨',
  '�T' => '鏥',
  '�U' => '鏘',
  '�V' => '鏃',
  '�W' => '鏝',
  '�X' => '鏐',
  '�Y' => '鏈',
  '�Z' => '鏤',
  '�[' => '鐚',
  '�\\' => '鐔',
  '�]' => '鐓',
  '�^' => '鐃',
  '�_' => '鐇',
  '�`' => '鐐',
  '�a' => '鐶',
  '�b' => '鐫',
  '�c' => '鐵',
  '�d' => '鐡',
  '�e' => '鐺',
  '�f' => '鑁',
  '�g' => '鑒',
  '�h' => '鑄',
  '�i' => '鑛',
  '�j' => '鑠',
  '�k' => '鑢',
  '�l' => '鑞',
  '�m' => '鑪',
  '�n' => '鈩',
  '�o' => '鑰',
  '�p' => '鑵',
  '�q' => '鑷',
  '�r' => '鑽',
  '�s' => '鑚',
  '�t' => '鑼',
  '�u' => '鑾',
  '�v' => '钁',
  '�w' => '鑿',
  '�x' => '閂',
  '�y' => '閇',
  '�z' => '閊',
  '�{' => '閔',
  '�|' => '閖',
  '�}' => '閘',
  '�~' => '閙',
  '�' => '閠',
  '�' => '閨',
  '�' => '閧',
  '�' => '閭',
  '�' => '閼',
  '�' => '閻',
  '�' => '閹',
  '�' => '閾',
  '�' => '闊',
  '�' => '濶',
  '�' => '闃',
  '�' => '闍',
  '�' => '闌',
  '�' => '闕',
  '�' => '闔',
  '�' => '闖',
  '�' => '關',
  '�' => '闡',
  '�' => '闥',
  '�' => '闢',
  '�' => '阡',
  '�' => '阨',
  '�' => '阮',
  '�' => '阯',
  '�' => '陂',
  '�' => '陌',
  '�' => '陏',
  '�' => '陋',
  '�' => '陷',
  '�' => '陜',
  '�' => '陞',
  '�' => '陝',
  '�' => '陟',
  '�' => '陦',
  '�' => '陲',
  '�' => '陬',
  '�' => '隍',
  '�' => '隘',
  '�' => '隕',
  '�' => '隗',
  '�' => '險',
  '�' => '隧',
  '�' => '隱',
  '�' => '隲',
  '�' => '隰',
  '�' => '隴',
  '�' => '隶',
  '�' => '隸',
  '�' => '隹',
  '�' => '雎',
  '�' => '雋',
  '�' => '雉',
  '�' => '雍',
  '�' => '襍',
  '�' => '雜',
  '�' => '霍',
  '�' => '雕',
  '�' => '雹',
  '�' => '霄',
  '�' => '霆',
  '�' => '霈',
  '�' => '霓',
  '�' => '霎',
  '�' => '霑',
  '�' => '霏',
  '�' => '霖',
  '��' => '霙',
  '��' => '霤',
  '��' => '霪',
  '��' => '霰',
  '��' => '霹',
  '��' => '霽',
  '��' => '霾',
  '��' => '靄',
  '��' => '靆',
  '��' => '靈',
  '��' => '靂',
  '��' => '靉',
  '��' => '靜',
  '��' => '靠',
  '��' => '靤',
  '��' => '靦',
  '��' => '靨',
  '��' => '勒',
  '��' => '靫',
  '��' => '靱',
  '��' => '靹',
  '��' => '鞅',
  '��' => '靼',
  '��' => '鞁',
  '��' => '靺',
  '��' => '鞆',
  '��' => '鞋',
  '��' => '鞏',
  '��' => '鞐',
  '��' => '鞜',
  '��' => '鞨',
  '��' => '鞦',
  '��' => '鞣',
  '��' => '鞳',
  '��' => '鞴',
  '��' => '韃',
  '��' => '韆',
  '��' => '韈',
  '��' => '韋',
  '��' => '韜',
  '��' => '韭',
  '��' => '齏',
  '��' => '韲',
  '��' => '竟',
  '��' => '韶',
  '��' => '韵',
  '��' => '頏',
  '��' => '頌',
  '��' => '頸',
  '��' => '頤',
  '��' => '頡',
  '�' => '頷',
  '�' => '頽',
  '�' => '顆',
  '�' => '顏',
  '�' => '顋',
  '�' => '顫',
  '�' => '顯',
  '�' => '顰',
  '�@' => '顱',
  '�A' => '顴',
  '�B' => '顳',
  '�C' => '颪',
  '�D' => '颯',
  '�E' => '颱',
  '�F' => '颶',
  '�G' => '飄',
  '�H' => '飃',
  '�I' => '飆',
  '�J' => '飩',
  '�K' => '飫',
  '�L' => '餃',
  '�M' => '餉',
  '�N' => '餒',
  '�O' => '餔',
  '�P' => '餘',
  '�Q' => '餡',
  '�R' => '餝',
  '�S' => '餞',
  '�T' => '餤',
  '�U' => '餠',
  '�V' => '餬',
  '�W' => '餮',
  '�X' => '餽',
  '�Y' => '餾',
  '�Z' => '饂',
  '�[' => '饉',
  '�\\' => '饅',
  '�]' => '饐',
  '�^' => '饋',
  '�_' => '饑',
  '�`' => '饒',
  '�a' => '饌',
  '�b' => '饕',
  '�c' => '馗',
  '�d' => '馘',
  '�e' => '馥',
  '�f' => '馭',
  '�g' => '馮',
  '�h' => '馼',
  '�i' => '駟',
  '�j' => '駛',
  '�k' => '駝',
  '�l' => '駘',
  '�m' => '駑',
  '�n' => '駭',
  '�o' => '駮',
  '�p' => '駱',
  '�q' => '駲',
  '�r' => '駻',
  '�s' => '駸',
  '�t' => '騁',
  '�u' => '騏',
  '�v' => '騅',
  '�w' => '駢',
  '�x' => '騙',
  '�y' => '騫',
  '�z' => '騷',
  '�{' => '驅',
  '�|' => '驂',
  '�}' => '驀',
  '�~' => '驃',
  '�' => '騾',
  '�' => '驕',
  '�' => '驍',
  '�' => '驛',
  '�' => '驗',
  '�' => '驟',
  '�' => '驢',
  '�' => '驥',
  '�' => '驤',
  '�' => '驩',
  '�' => '驫',
  '�' => '驪',
  '�' => '骭',
  '�' => '骰',
  '�' => '骼',
  '�' => '髀',
  '�' => '髏',
  '�' => '髑',
  '�' => '髓',
  '�' => '體',
  '�' => '髞',
  '�' => '髟',
  '�' => '髢',
  '�' => '髣',
  '�' => '髦',
  '�' => '髯',
  '�' => '髫',
  '�' => '髮',
  '�' => '髴',
  '�' => '髱',
  '�' => '髷',
  '�' => '髻',
  '�' => '鬆',
  '�' => '鬘',
  '�' => '鬚',
  '�' => '鬟',
  '�' => '鬢',
  '�' => '鬣',
  '�' => '鬥',
  '�' => '鬧',
  '�' => '鬨',
  '�' => '鬩',
  '�' => '鬪',
  '�' => '鬮',
  '�' => '鬯',
  '�' => '鬲',
  '�' => '魄',
  '�' => '魃',
  '�' => '魏',
  '�' => '魍',
  '�' => '魎',
  '�' => '魑',
  '�' => '魘',
  '�' => '魴',
  '�' => '鮓',
  '�' => '鮃',
  '�' => '鮑',
  '�' => '鮖',
  '�' => '鮗',
  '�' => '鮟',
  '�' => '鮠',
  '�' => '鮨',
  '�' => '鮴',
  '�' => '鯀',
  '�' => '鯊',
  '�' => '鮹',
  '��' => '鯆',
  '��' => '鯏',
  '��' => '鯑',
  '��' => '鯒',
  '��' => '鯣',
  '��' => '鯢',
  '��' => '鯤',
  '��' => '鯔',
  '��' => '鯡',
  '��' => '鰺',
  '��' => '鯲',
  '��' => '鯱',
  '��' => '鯰',
  '��' => '鰕',
  '��' => '鰔',
  '��' => '鰉',
  '��' => '鰓',
  '��' => '鰌',
  '��' => '鰆',
  '��' => '鰈',
  '��' => '鰒',
  '��' => '鰊',
  '��' => '鰄',
  '��' => '鰮',
  '��' => '鰛',
  '��' => '鰥',
  '��' => '鰤',
  '��' => '鰡',
  '��' => '鰰',
  '��' => '鱇',
  '��' => '鰲',
  '��' => '鱆',
  '��' => '鰾',
  '��' => '鱚',
  '��' => '鱠',
  '��' => '鱧',
  '��' => '鱶',
  '��' => '鱸',
  '��' => '鳧',
  '��' => '鳬',
  '��' => '鳰',
  '��' => '鴉',
  '��' => '鴈',
  '��' => '鳫',
  '��' => '鴃',
  '��' => '鴆',
  '��' => '鴪',
  '��' => '鴦',
  '��' => '鶯',
  '��' => '鴣',
  '��' => '鴟',
  '�' => '鵄',
  '�' => '鴕',
  '�' => '鴒',
  '�' => '鵁',
  '�' => '鴿',
  '�' => '鴾',
  '�' => '鵆',
  '�' => '鵈',
  '�@' => '鵝',
  '�A' => '鵞',
  '�B' => '鵤',
  '�C' => '鵑',
  '�D' => '鵐',
  '�E' => '鵙',
  '�F' => '鵲',
  '�G' => '鶉',
  '�H' => '鶇',
  '�I' => '鶫',
  '�J' => '鵯',
  '�K' => '鵺',
  '�L' => '鶚',
  '�M' => '鶤',
  '�N' => '鶩',
  '�O' => '鶲',
  '�P' => '鷄',
  '�Q' => '鷁',
  '�R' => '鶻',
  '�S' => '鶸',
  '�T' => '鶺',
  '�U' => '鷆',
  '�V' => '鷏',
  '�W' => '鷂',
  '�X' => '鷙',
  '�Y' => '鷓',
  '�Z' => '鷸',
  '�[' => '鷦',
  '�\\' => '鷭',
  '�]' => '鷯',
  '�^' => '鷽',
  '�_' => '鸚',
  '�`' => '鸛',
  '�a' => '鸞',
  '�b' => '鹵',
  '�c' => '鹹',
  '�d' => '鹽',
  '�e' => '麁',
  '�f' => '麈',
  '�g' => '麋',
  '�h' => '麌',
  '�i' => '麒',
  '�j' => '麕',
  '�k' => '麑',
  '�l' => '麝',
  '�m' => '麥',
  '�n' => '麩',
  '�o' => '麸',
  '�p' => '麪',
  '�q' => '麭',
  '�r' => '靡',
  '�s' => '黌',
  '�t' => '黎',
  '�u' => '黏',
  '�v' => '黐',
  '�w' => '黔',
  '�x' => '黜',
  '�y' => '點',
  '�z' => '黝',
  '�{' => '黠',
  '�|' => '黥',
  '�}' => '黨',
  '�~' => '黯',
  '�' => '黴',
  '�' => '黶',
  '�' => '黷',
  '�' => '黹',
  '�' => '黻',
  '�' => '黼',
  '�' => '黽',
  '�' => '鼇',
  '�' => '鼈',
  '�' => '皷',
  '�' => '鼕',
  '�' => '鼡',
  '�' => '鼬',
  '�' => '鼾',
  '�' => '齊',
  '�' => '齒',
  '�' => '齔',
  '�' => '齣',
  '�' => '齟',
  '�' => '齠',
  '�' => '齡',
  '�' => '齦',
  '�' => '齧',
  '�' => '齬',
  '�' => '齪',
  '�' => '齷',
  '�' => '齲',
  '�' => '齶',
  '�' => '龕',
  '�' => '龜',
  '�' => '龠',
  '�' => '堯',
  '�' => '槇',
  '�' => '遙',
  '�' => '瑤',
  '�' => '凜',
  '�' => '熙',
  '�@' => '纊',
  '�A' => '褜',
  '�B' => '鍈',
  '�C' => '銈',
  '�D' => '蓜',
  '�E' => '俉',
  '�F' => '炻',
  '�G' => '昱',
  '�H' => '棈',
  '�I' => '鋹',
  '�J' => '曻',
  '�K' => '彅',
  '�L' => '丨',
  '�M' => '仡',
  '�N' => '仼',
  '�O' => '伀',
  '�P' => '伃',
  '�Q' => '伹',
  '�R' => '佖',
  '�S' => '侒',
  '�T' => '侊',
  '�U' => '侚',
  '�V' => '侔',
  '�W' => '俍',
  '�X' => '偀',
  '�Y' => '倢',
  '�Z' => '俿',
  '�[' => '倞',
  '�\\' => '偆',
  '�]' => '偰',
  '�^' => '偂',
  '�_' => '傔',
  '�`' => '僴',
  '�a' => '僘',
  '�b' => '兊',
  '�c' => '兤',
  '�d' => '冝',
  '�e' => '冾',
  '�f' => '凬',
  '�g' => '刕',
  '�h' => '劜',
  '�i' => '劦',
  '�j' => '勀',
  '�k' => '勛',
  '�l' => '匀',
  '�m' => '匇',
  '�n' => '匤',
  '�o' => '卲',
  '�p' => '厓',
  '�q' => '厲',
  '�r' => '叝',
  '�s' => '﨎',
  '�t' => '咜',
  '�u' => '咊',
  '�v' => '咩',
  '�w' => '哿',
  '�x' => '喆',
  '�y' => '坙',
  '�z' => '坥',
  '�{' => '垬',
  '�|' => '埈',
  '�}' => '埇',
  '�~' => '﨏',
  '�' => '塚',
  '�' => '增',
  '�' => '墲',
  '�' => '夋',
  '�' => '奓',
  '�' => '奛',
  '�' => '奝',
  '�' => '奣',
  '�' => '妤',
  '�' => '妺',
  '�' => '孖',
  '�' => '寀',
  '�' => '甯',
  '�' => '寘',
  '�' => '寬',
  '�' => '尞',
  '�' => '岦',
  '�' => '岺',
  '�' => '峵',
  '�' => '崧',
  '�' => '嵓',
  '�' => '﨑',
  '�' => '嵂',
  '�' => '嵭',
  '�' => '嶸',
  '�' => '嶹',
  '�' => '巐',
  '�' => '弡',
  '�' => '弴',
  '�' => '彧',
  '�' => '德',
  '�' => '忞',
  '�' => '恝',
  '�' => '悅',
  '�' => '悊',
  '�' => '惞',
  '�' => '惕',
  '�' => '愠',
  '�' => '惲',
  '�' => '愑',
  '�' => '愷',
  '�' => '愰',
  '�' => '憘',
  '�' => '戓',
  '�' => '抦',
  '�' => '揵',
  '�' => '摠',
  '�' => '撝',
  '�' => '擎',
  '�' => '敎',
  '�' => '昀',
  '�' => '昕',
  '�' => '昻',
  '�' => '昉',
  '�' => '昮',
  '�' => '昞',
  '�' => '昤',
  '�' => '晥',
  '�' => '晗',
  '�' => '晙',
  '�' => '晴',
  '�' => '晳',
  '�' => '暙',
  '�' => '暠',
  '�' => '暲',
  '�' => '暿',
  '��' => '曺',
  '��' => '朎',
  '��' => '朗',
  '��' => '杦',
  '��' => '枻',
  '��' => '桒',
  '��' => '柀',
  '��' => '栁',
  '��' => '桄',
  '��' => '棏',
  '��' => '﨓',
  '��' => '楨',
  '��' => '﨔',
  '��' => '榘',
  '��' => '槢',
  '��' => '樰',
  '��' => '橫',
  '��' => '橆',
  '��' => '橳',
  '��' => '橾',
  '��' => '櫢',
  '��' => '櫤',
  '��' => '毖',
  '��' => '氿',
  '��' => '汜',
  '��' => '沆',
  '��' => '汯',
  '��' => '泚',
  '��' => '洄',
  '��' => '涇',
  '��' => '浯',
  '��' => '涖',
  '��' => '涬',
  '��' => '淏',
  '��' => '淸',
  '��' => '淲',
  '��' => '淼',
  '��' => '渹',
  '��' => '湜',
  '��' => '渧',
  '��' => '渼',
  '��' => '溿',
  '��' => '澈',
  '��' => '澵',
  '��' => '濵',
  '��' => '瀅',
  '��' => '瀇',
  '��' => '瀨',
  '��' => '炅',
  '��' => '炫',
  '��' => '焏',
  '�' => '焄',
  '�' => '煜',
  '�' => '煆',
  '�' => '煇',
  '�' => '凞',
  '�' => '燁',
  '�' => '燾',
  '�' => '犱',
  '�@' => '犾',
  '�A' => '猤',
  '�B' => '猪',
  '�C' => '獷',
  '�D' => '玽',
  '�E' => '珉',
  '�F' => '珖',
  '�G' => '珣',
  '�H' => '珒',
  '�I' => '琇',
  '�J' => '珵',
  '�K' => '琦',
  '�L' => '琪',
  '�M' => '琩',
  '�N' => '琮',
  '�O' => '瑢',
  '�P' => '璉',
  '�Q' => '璟',
  '�R' => '甁',
  '�S' => '畯',
  '�T' => '皂',
  '�U' => '皜',
  '�V' => '皞',
  '�W' => '皛',
  '�X' => '皦',
  '�Y' => '益',
  '�Z' => '睆',
  '�[' => '劯',
  '�\\' => '砡',
  '�]' => '硎',
  '�^' => '硤',
  '�_' => '硺',
  '�`' => '礰',
  '�a' => '礼',
  '�b' => '神',
  '�c' => '祥',
  '�d' => '禔',
  '�e' => '福',
  '�f' => '禛',
  '�g' => '竑',
  '�h' => '竧',
  '�i' => '靖',
  '�j' => '竫',
  '�k' => '箞',
  '�l' => '精',
  '�m' => '絈',
  '�n' => '絜',
  '�o' => '綷',
  '�p' => '綠',
  '�q' => '緖',
  '�r' => '繒',
  '�s' => '罇',
  '�t' => '羡',
  '�u' => '羽',
  '�v' => '茁',
  '�w' => '荢',
  '�x' => '荿',
  '�y' => '菇',
  '�z' => '菶',
  '�{' => '葈',
  '�|' => '蒴',
  '�}' => '蕓',
  '�~' => '蕙',
  '�' => '蕫',
  '�' => '﨟',
  '�' => '薰',
  '�' => '蘒',
  '�' => '﨡',
  '�' => '蠇',
  '�' => '裵',
  '�' => '訒',
  '�' => '訷',
  '�' => '詹',
  '�' => '誧',
  '�' => '誾',
  '�' => '諟',
  '�' => '諸',
  '�' => '諶',
  '�' => '譓',
  '�' => '譿',
  '�' => '賰',
  '�' => '賴',
  '�' => '贒',
  '�' => '赶',
  '�' => '﨣',
  '�' => '軏',
  '�' => '﨤',
  '�' => '逸',
  '�' => '遧',
  '�' => '郞',
  '�' => '都',
  '�' => '鄕',
  '�' => '鄧',
  '�' => '釚',
  '�' => '釗',
  '�' => '釞',
  '�' => '釭',
  '�' => '釮',
  '�' => '釤',
  '�' => '釥',
  '�' => '鈆',
  '�' => '鈐',
  '�' => '鈊',
  '�' => '鈺',
  '�' => '鉀',
  '�' => '鈼',
  '�' => '鉎',
  '�' => '鉙',
  '�' => '鉑',
  '�' => '鈹',
  '�' => '鉧',
  '�' => '銧',
  '�' => '鉷',
  '�' => '鉸',
  '�' => '鋧',
  '�' => '鋗',
  '�' => '鋙',
  '�' => '鋐',
  '�' => '﨧',
  '�' => '鋕',
  '�' => '鋠',
  '�' => '鋓',
  '�' => '錥',
  '�' => '錡',
  '�' => '鋻',
  '�' => '﨨',
  '�' => '錞',
  '�' => '鋿',
  '�' => '錝',
  '��' => '錂',
  '��' => '鍰',
  '��' => '鍗',
  '��' => '鎤',
  '��' => '鏆',
  '��' => '鏞',
  '��' => '鏸',
  '��' => '鐱',
  '��' => '鑅',
  '��' => '鑈',
  '��' => '閒',
  '��' => '隆',
  '��' => '﨩',
  '��' => '隝',
  '��' => '隯',
  '��' => '霳',
  '��' => '霻',
  '��' => '靃',
  '��' => '靍',
  '��' => '靏',
  '��' => '靑',
  '��' => '靕',
  '��' => '顗',
  '��' => '顥',
  '��' => '飯',
  '��' => '飼',
  '��' => '餧',
  '��' => '館',
  '��' => '馞',
  '��' => '驎',
  '��' => '髙',
  '��' => '髜',
  '��' => '魵',
  '��' => '魲',
  '��' => '鮏',
  '��' => '鮱',
  '��' => '鮻',
  '��' => '鰀',
  '��' => '鵰',
  '��' => '鵫',
  '��' => '鶴',
  '��' => '鸙',
  '��' => '黑',
  '��' => 'ⅰ',
  '��' => 'ⅱ',
  '��' => 'ⅲ',
  '��' => 'ⅳ',
  '��' => 'ⅴ',
  '��' => 'ⅵ',
  '�' => 'ⅶ',
  '�' => 'ⅷ',
  '�' => 'ⅸ',
  '�' => 'ⅹ',
  '�' => '¬',
  '�' => '¦',
  '�' => ''',
  '�' => '"',
  '�@' => 'ⅰ',
  '�A' => 'ⅱ',
  '�B' => 'ⅲ',
  '�C' => 'ⅳ',
  '�D' => 'ⅴ',
  '�E' => 'ⅵ',
  '�F' => 'ⅶ',
  '�G' => 'ⅷ',
  '�H' => 'ⅸ',
  '�I' => 'ⅹ',
  '�J' => 'Ⅰ',
  '�K' => 'Ⅱ',
  '�L' => 'Ⅲ',
  '�M' => 'Ⅳ',
  '�N' => 'Ⅴ',
  '�O' => 'Ⅵ',
  '�P' => 'Ⅶ',
  '�Q' => 'Ⅷ',
  '�R' => 'Ⅸ',
  '�S' => 'Ⅹ',
  '�T' => '¬',
  '�U' => '¦',
  '�V' => ''',
  '�W' => '"',
  '�X' => '㈱',
  '�Y' => '№',
  '�Z' => '℡',
  '�[' => '∵',
  '�\\' => '纊',
  '�]' => '褜',
  '�^' => '鍈',
  '�_' => '銈',
  '�`' => '蓜',
  '�a' => '俉',
  '�b' => '炻',
  '�c' => '昱',
  '�d' => '棈',
  '�e' => '鋹',
  '�f' => '曻',
  '�g' => '彅',
  '�h' => '丨',
  '�i' => '仡',
  '�j' => '仼',
  '�k' => '伀',
  '�l' => '伃',
  '�m' => '伹',
  '�n' => '佖',
  '�o' => '侒',
  '�p' => '侊',
  '�q' => '侚',
  '�r' => '侔',
  '�s' => '俍',
  '�t' => '偀',
  '�u' => '倢',
  '�v' => '俿',
  '�w' => '倞',
  '�x' => '偆',
  '�y' => '偰',
  '�z' => '偂',
  '�{' => '傔',
  '�|' => '僴',
  '�}' => '僘',
  '�~' => '兊',
  '��' => '兤',
  '��' => '冝',
  '��' => '冾',
  '��' => '凬',
  '��' => '刕',
  '��' => '劜',
  '��' => '劦',
  '��' => '勀',
  '��' => '勛',
  '��' => '匀',
  '��' => '匇',
  '��' => '匤',
  '��' => '卲',
  '��' => '厓',
  '��' => '厲',
  '��' => '叝',
  '��' => '﨎',
  '��' => '咜',
  '��' => '咊',
  '��' => '咩',
  '��' => '哿',
  '��' => '喆',
  '��' => '坙',
  '��' => '坥',
  '��' => '垬',
  '��' => '埈',
  '��' => '埇',
  '��' => '﨏',
  '��' => '塚',
  '��' => '增',
  '��' => '墲',
  '��' => '夋',
  '��' => '奓',
  '��' => '奛',
  '��' => '奝',
  '��' => '奣',
  '��' => '妤',
  '��' => '妺',
  '��' => '孖',
  '��' => '寀',
  '��' => '甯',
  '��' => '寘',
  '��' => '寬',
  '��' => '尞',
  '��' => '岦',
  '��' => '岺',
  '��' => '峵',
  '��' => '崧',
  '��' => '嵓',
  '��' => '﨑',
  '��' => '嵂',
  '��' => '嵭',
  '��' => '嶸',
  '��' => '嶹',
  '��' => '巐',
  '��' => '弡',
  '��' => '弴',
  '��' => '彧',
  '��' => '德',
  '��' => '忞',
  '��' => '恝',
  '��' => '悅',
  '��' => '悊',
  '��' => '惞',
  '��' => '惕',
  '��' => '愠',
  '��' => '惲',
  '��' => '愑',
  '��' => '愷',
  '��' => '愰',
  '��' => '憘',
  '��' => '戓',
  '��' => '抦',
  '��' => '揵',
  '��' => '摠',
  '��' => '撝',
  '��' => '擎',
  '��' => '敎',
  '��' => '昀',
  '��' => '昕',
  '��' => '昻',
  '��' => '昉',
  '��' => '昮',
  '��' => '昞',
  '��' => '昤',
  '��' => '晥',
  '��' => '晗',
  '��' => '晙',
  '��' => '晴',
  '��' => '晳',
  '��' => '暙',
  '��' => '暠',
  '��' => '暲',
  '��' => '暿',
  '��' => '曺',
  '��' => '朎',
  '��' => '朗',
  '��' => '杦',
  '��' => '枻',
  '��' => '桒',
  '��' => '柀',
  '��' => '栁',
  '��' => '桄',
  '��' => '棏',
  '��' => '﨓',
  '��' => '楨',
  '��' => '﨔',
  '��' => '榘',
  '��' => '槢',
  '��' => '樰',
  '��' => '橫',
  '��' => '橆',
  '��' => '橳',
  '��' => '橾',
  '��' => '櫢',
  '��' => '櫤',
  '��' => '毖',
  '��' => '氿',
  '��' => '汜',
  '��' => '沆',
  '��' => '汯',
  '��' => '泚',
  '��' => '洄',
  '��' => '涇',
  '��' => '浯',
  '�@' => '涖',
  '�A' => '涬',
  '�B' => '淏',
  '�C' => '淸',
  '�D' => '淲',
  '�E' => '淼',
  '�F' => '渹',
  '�G' => '湜',
  '�H' => '渧',
  '�I' => '渼',
  '�J' => '溿',
  '�K' => '澈',
  '�L' => '澵',
  '�M' => '濵',
  '�N' => '瀅',
  '�O' => '瀇',
  '�P' => '瀨',
  '�Q' => '炅',
  '�R' => '炫',
  '�S' => '焏',
  '�T' => '焄',
  '�U' => '煜',
  '�V' => '煆',
  '�W' => '煇',
  '�X' => '凞',
  '�Y' => '燁',
  '�Z' => '燾',
  '�[' => '犱',
  '�\\' => '犾',
  '�]' => '猤',
  '�^' => '猪',
  '�_' => '獷',
  '�`' => '玽',
  '�a' => '珉',
  '�b' => '珖',
  '�c' => '珣',
  '�d' => '珒',
  '�e' => '琇',
  '�f' => '珵',
  '�g' => '琦',
  '�h' => '琪',
  '�i' => '琩',
  '�j' => '琮',
  '�k' => '瑢',
  '�l' => '璉',
  '�m' => '璟',
  '�n' => '甁',
  '�o' => '畯',
  '�p' => '皂',
  '�q' => '皜',
  '�r' => '皞',
  '�s' => '皛',
  '�t' => '皦',
  '�u' => '益',
  '�v' => '睆',
  '�w' => '劯',
  '�x' => '砡',
  '�y' => '硎',
  '�z' => '硤',
  '�{' => '硺',
  '�|' => '礰',
  '�}' => '礼',
  '�~' => '神',
  '��' => '祥',
  '��' => '禔',
  '��' => '福',
  '��' => '禛',
  '��' => '竑',
  '��' => '竧',
  '��' => '靖',
  '��' => '竫',
  '��' => '箞',
  '��' => '精',
  '��' => '絈',
  '��' => '絜',
  '��' => '綷',
  '��' => '綠',
  '��' => '緖',
  '��' => '繒',
  '��' => '罇',
  '��' => '羡',
  '��' => '羽',
  '��' => '茁',
  '��' => '荢',
  '��' => '荿',
  '��' => '菇',
  '��' => '菶',
  '��' => '葈',
  '��' => '蒴',
  '��' => '蕓',
  '��' => '蕙',
  '��' => '蕫',
  '��' => '﨟',
  '��' => '薰',
  '��' => '蘒',
  '��' => '﨡',
  '��' => '蠇',
  '��' => '裵',
  '��' => '訒',
  '��' => '訷',
  '��' => '詹',
  '��' => '誧',
  '��' => '誾',
  '��' => '諟',
  '��' => '諸',
  '��' => '諶',
  '��' => '譓',
  '��' => '譿',
  '��' => '賰',
  '��' => '賴',
  '��' => '贒',
  '��' => '赶',
  '��' => '﨣',
  '��' => '軏',
  '��' => '﨤',
  '��' => '逸',
  '��' => '遧',
  '��' => '郞',
  '��' => '都',
  '��' => '鄕',
  '��' => '鄧',
  '��' => '釚',
  '��' => '釗',
  '��' => '釞',
  '��' => '釭',
  '��' => '釮',
  '��' => '釤',
  '��' => '釥',
  '��' => '鈆',
  '��' => '鈐',
  '��' => '鈊',
  '��' => '鈺',
  '��' => '鉀',
  '��' => '鈼',
  '��' => '鉎',
  '��' => '鉙',
  '��' => '鉑',
  '��' => '鈹',
  '��' => '鉧',
  '��' => '銧',
  '��' => '鉷',
  '��' => '鉸',
  '��' => '鋧',
  '��' => '鋗',
  '��' => '鋙',
  '��' => '鋐',
  '��' => '﨧',
  '��' => '鋕',
  '��' => '鋠',
  '��' => '鋓',
  '��' => '錥',
  '��' => '錡',
  '��' => '鋻',
  '��' => '﨨',
  '��' => '錞',
  '��' => '鋿',
  '��' => '錝',
  '��' => '錂',
  '��' => '鍰',
  '��' => '鍗',
  '��' => '鎤',
  '��' => '鏆',
  '��' => '鏞',
  '��' => '鏸',
  '��' => '鐱',
  '��' => '鑅',
  '��' => '鑈',
  '��' => '閒',
  '��' => '隆',
  '��' => '﨩',
  '��' => '隝',
  '��' => '隯',
  '��' => '霳',
  '��' => '霻',
  '��' => '靃',
  '��' => '靍',
  '��' => '靏',
  '��' => '靑',
  '��' => '靕',
  '��' => '顗',
  '��' => '顥',
  '��' => '飯',
  '��' => '飼',
  '��' => '餧',
  '��' => '館',
  '��' => '馞',
  '��' => '驎',
  '��' => '髙',
  '�@' => '髜',
  '�A' => '魵',
  '�B' => '魲',
  '�C' => '鮏',
  '�D' => '鮱',
  '�E' => '鮻',
  '�F' => '鰀',
  '�G' => '鵰',
  '�H' => '鵫',
  '�I' => '鶴',
  '�J' => '鸙',
  '�K' => '黑',
);

$result =& $data;
unset($data);

return $result;
PKϤ$Z�*��/polyfill-iconv/Resources/charset/from.cp875.phpnu�[���<?php

static $data = array (
  '' => '',
  '' => '',
  '' => '',
  '' => '',
  '' => 'œ',
  '' => '	',
  '' => '†',
  '' => '',
  '' => '—',
  '	' => '',
  '
' => 'Ž',
  '' => '',
  '' => '',
  '
' => '
',
  '' => '',
  '' => '',
  '' => '',
  '' => '',
  '' => '',
  '' => '',
  '' => '',
  '' => '…',
  '' => '',
  '' => '‡',
  '' => '',
  '' => '',
  '' => '’',
  '' => '',
  '' => '',
  '' => '',
  '' => '',
  '' => '',
  ' ' => '€',
  '!' => '',
  '"' => '‚',
  '#' => 'ƒ',
  '$' => '„',
  '%' => '
',
  '&' => '',
  '\'' => '',
  '(' => 'ˆ',
  ')' => '‰',
  '*' => 'Š',
  '+' => '‹',
  ',' => 'Œ',
  '-' => '',
  '.' => '',
  '/' => '',
  0 => '',
  1 => '‘',
  2 => '',
  3 => '“',
  4 => '”',
  5 => '•',
  6 => '–',
  7 => '',
  8 => '˜',
  9 => '™',
  ':' => 'š',
  ';' => '›',
  '<' => '',
  '=' => '',
  '>' => 'ž',
  '?' => '',
  '@' => ' ',
  'A' => 'Α',
  'B' => 'Β',
  'C' => 'Γ',
  'D' => 'Δ',
  'E' => 'Ε',
  'F' => 'Ζ',
  'G' => 'Η',
  'H' => 'Θ',
  'I' => 'Ι',
  'J' => '[',
  'K' => '.',
  'L' => '<',
  'M' => '(',
  'N' => '+',
  'O' => '!',
  'P' => '&',
  'Q' => 'Κ',
  'R' => 'Λ',
  'S' => 'Μ',
  'T' => 'Ν',
  'U' => 'Ξ',
  'V' => 'Ο',
  'W' => 'Π',
  'X' => 'Ρ',
  'Y' => 'Σ',
  'Z' => ']',
  '[' => '$',
  '\\' => '*',
  ']' => ')',
  '^' => ';',
  '_' => '^',
  '`' => '-',
  'a' => '/',
  'b' => 'Τ',
  'c' => 'Υ',
  'd' => 'Φ',
  'e' => 'Χ',
  'f' => 'Ψ',
  'g' => 'Ω',
  'h' => 'Ϊ',
  'i' => 'Ϋ',
  'j' => '|',
  'k' => ',',
  'l' => '%',
  'm' => '_',
  'n' => '>',
  'o' => '?',
  'p' => '¨',
  'q' => 'Ά',
  'r' => 'Έ',
  's' => 'Ή',
  't' => ' ',
  'u' => 'Ί',
  'v' => 'Ό',
  'w' => 'Ύ',
  'x' => 'Ώ',
  'y' => '`',
  'z' => ':',
  '{' => '#',
  '|' => '@',
  '}' => '\'',
  '~' => '=',
  '' => '"',
  '�' => '΅',
  '�' => 'a',
  '�' => 'b',
  '�' => 'c',
  '�' => 'd',
  '�' => 'e',
  '�' => 'f',
  '�' => 'g',
  '�' => 'h',
  '�' => 'i',
  '�' => 'α',
  '�' => 'β',
  '�' => 'γ',
  '�' => 'δ',
  '�' => 'ε',
  '�' => 'ζ',
  '�' => '°',
  '�' => 'j',
  '�' => 'k',
  '�' => 'l',
  '�' => 'm',
  '�' => 'n',
  '�' => 'o',
  '�' => 'p',
  '�' => 'q',
  '�' => 'r',
  '�' => 'η',
  '�' => 'θ',
  '�' => 'ι',
  '�' => 'κ',
  '�' => 'λ',
  '�' => 'μ',
  '�' => '´',
  '�' => '~',
  '�' => 's',
  '�' => 't',
  '�' => 'u',
  '�' => 'v',
  '�' => 'w',
  '�' => 'x',
  '�' => 'y',
  '�' => 'z',
  '�' => 'ν',
  '�' => 'ξ',
  '�' => 'ο',
  '�' => 'π',
  '�' => 'ρ',
  '�' => 'σ',
  '�' => '£',
  '�' => 'ά',
  '�' => 'έ',
  '�' => 'ή',
  '�' => 'ϊ',
  '�' => 'ί',
  '�' => 'ό',
  '�' => 'ύ',
  '�' => 'ϋ',
  '�' => 'ώ',
  '�' => 'ς',
  '�' => 'τ',
  '�' => 'υ',
  '�' => 'φ',
  '�' => 'χ',
  '�' => 'ψ',
  '�' => '{',
  '�' => 'A',
  '�' => 'B',
  '�' => 'C',
  '�' => 'D',
  '�' => 'E',
  '�' => 'F',
  '�' => 'G',
  '�' => 'H',
  '�' => 'I',
  '�' => '­',
  '�' => 'ω',
  '�' => 'ΐ',
  '�' => 'ΰ',
  '�' => '‘',
  '�' => '―',
  '�' => '}',
  '�' => 'J',
  '�' => 'K',
  '�' => 'L',
  '�' => 'M',
  '�' => 'N',
  '�' => 'O',
  '�' => 'P',
  '�' => 'Q',
  '�' => 'R',
  '�' => '±',
  '�' => '½',
  '�' => '',
  '�' => '·',
  '�' => '’',
  '�' => '¦',
  '�' => '\\',
  '�' => '',
  '�' => 'S',
  '�' => 'T',
  '�' => 'U',
  '�' => 'V',
  '�' => 'W',
  '�' => 'X',
  '�' => 'Y',
  '�' => 'Z',
  '�' => '²',
  '�' => '§',
  '�' => '',
  '�' => '',
  '�' => '«',
  '�' => '¬',
  '�' => '0',
  '�' => '1',
  '�' => '2',
  '�' => '3',
  '�' => '4',
  '�' => '5',
  '�' => '6',
  '�' => '7',
  '�' => '8',
  '�' => '9',
  '�' => '³',
  '�' => '©',
  '�' => '',
  '�' => '',
  '�' => '»',
  '�' => 'Ÿ',
);

$result =& $data;
unset($data);

return $result;
PKϤ$Z��i�R
R
/polyfill-iconv/Resources/charset/from.cp874.phpnu�[���<?php

static $data = array (
  '' => '',
  '' => '',
  '' => '',
  '' => '',
  '' => '',
  '' => '',
  '' => '',
  '' => '',
  '' => '',
  '	' => '	',
  '
' => '
',
  '' => '',
  '' => '',
  '
' => '
',
  '' => '',
  '' => '',
  '' => '',
  '' => '',
  '' => '',
  '' => '',
  '' => '',
  '' => '',
  '' => '',
  '' => '',
  '' => '',
  '' => '',
  '' => '',
  '' => '',
  '' => '',
  '' => '',
  '' => '',
  '' => '',
  ' ' => ' ',
  '!' => '!',
  '"' => '"',
  '#' => '#',
  '$' => '$',
  '%' => '%',
  '&' => '&',
  '\'' => '\'',
  '(' => '(',
  ')' => ')',
  '*' => '*',
  '+' => '+',
  ',' => ',',
  '-' => '-',
  '.' => '.',
  '/' => '/',
  0 => '0',
  1 => '1',
  2 => '2',
  3 => '3',
  4 => '4',
  5 => '5',
  6 => '6',
  7 => '7',
  8 => '8',
  9 => '9',
  ':' => ':',
  ';' => ';',
  '<' => '<',
  '=' => '=',
  '>' => '>',
  '?' => '?',
  '@' => '@',
  'A' => 'A',
  'B' => 'B',
  'C' => 'C',
  'D' => 'D',
  'E' => 'E',
  'F' => 'F',
  'G' => 'G',
  'H' => 'H',
  'I' => 'I',
  'J' => 'J',
  'K' => 'K',
  'L' => 'L',
  'M' => 'M',
  'N' => 'N',
  'O' => 'O',
  'P' => 'P',
  'Q' => 'Q',
  'R' => 'R',
  'S' => 'S',
  'T' => 'T',
  'U' => 'U',
  'V' => 'V',
  'W' => 'W',
  'X' => 'X',
  'Y' => 'Y',
  'Z' => 'Z',
  '[' => '[',
  '\\' => '\\',
  ']' => ']',
  '^' => '^',
  '_' => '_',
  '`' => '`',
  'a' => 'a',
  'b' => 'b',
  'c' => 'c',
  'd' => 'd',
  'e' => 'e',
  'f' => 'f',
  'g' => 'g',
  'h' => 'h',
  'i' => 'i',
  'j' => 'j',
  'k' => 'k',
  'l' => 'l',
  'm' => 'm',
  'n' => 'n',
  'o' => 'o',
  'p' => 'p',
  'q' => 'q',
  'r' => 'r',
  's' => 's',
  't' => 't',
  'u' => 'u',
  'v' => 'v',
  'w' => 'w',
  'x' => 'x',
  'y' => 'y',
  'z' => 'z',
  '{' => '{',
  '|' => '|',
  '}' => '}',
  '~' => '~',
  '' => '',
  '�' => '€',
  '�' => '…',
  '�' => '‘',
  '�' => '’',
  '�' => '“',
  '�' => '”',
  '�' => '•',
  '�' => '–',
  '�' => '—',
  '�' => ' ',
  '�' => 'ก',
  '�' => 'ข',
  '�' => 'ฃ',
  '�' => 'ค',
  '�' => 'ฅ',
  '�' => 'ฆ',
  '�' => 'ง',
  '�' => 'จ',
  '�' => 'ฉ',
  '�' => 'ช',
  '�' => 'ซ',
  '�' => 'ฌ',
  '�' => 'ญ',
  '�' => 'ฎ',
  '�' => 'ฏ',
  '�' => 'ฐ',
  '�' => 'ฑ',
  '�' => 'ฒ',
  '�' => 'ณ',
  '�' => 'ด',
  '�' => 'ต',
  '�' => 'ถ',
  '�' => 'ท',
  '�' => 'ธ',
  '�' => 'น',
  '�' => 'บ',
  '�' => 'ป',
  '�' => 'ผ',
  '�' => 'ฝ',
  '�' => 'พ',
  '�' => 'ฟ',
  '�' => 'ภ',
  '�' => 'ม',
  '�' => 'ย',
  '�' => 'ร',
  '�' => 'ฤ',
  '�' => 'ล',
  '�' => 'ฦ',
  '�' => 'ว',
  '�' => 'ศ',
  '�' => 'ษ',
  '�' => 'ส',
  '�' => 'ห',
  '�' => 'ฬ',
  '�' => 'อ',
  '�' => 'ฮ',
  '�' => 'ฯ',
  '�' => 'ะ',
  '�' => 'ั',
  '�' => 'า',
  '�' => 'ำ',
  '�' => 'ิ',
  '�' => 'ี',
  '�' => 'ึ',
  '�' => 'ื',
  '�' => 'ุ',
  '�' => 'ู',
  '�' => 'ฺ',
  '�' => '฿',
  '�' => 'เ',
  '�' => 'แ',
  '�' => 'โ',
  '�' => 'ใ',
  '�' => 'ไ',
  '�' => 'ๅ',
  '�' => 'ๆ',
  '�' => '็',
  '�' => '่',
  '�' => '้',
  '�' => '๊',
  '�' => '๋',
  '�' => '์',
  '�' => 'ํ',
  '�' => '๎',
  '�' => '๏',
  '�' => '๐',
  '�' => '๑',
  '�' => '๒',
  '�' => '๓',
  '�' => '๔',
  '�' => '๕',
  '�' => '๖',
  '�' => '๗',
  '�' => '๘',
  '�' => '๙',
  '�' => '๚',
  '�' => '๛',
);

$result =& $data;
unset($data);

return $result;
PKϤ$Z��&��4polyfill-iconv/Resources/charset/from.iso-8859-5.phpnu�[���<?php

static $data = array (
  '' => '',
  '' => '',
  '' => '',
  '' => '',
  '' => '',
  '' => '',
  '' => '',
  '' => '',
  '' => '',
  '	' => '	',
  '
' => '
',
  '' => '',
  '' => '',
  '
' => '
',
  '' => '',
  '' => '',
  '' => '',
  '' => '',
  '' => '',
  '' => '',
  '' => '',
  '' => '',
  '' => '',
  '' => '',
  '' => '',
  '' => '',
  '' => '',
  '' => '',
  '' => '',
  '' => '',
  '' => '',
  '' => '',
  ' ' => ' ',
  '!' => '!',
  '"' => '"',
  '#' => '#',
  '$' => '$',
  '%' => '%',
  '&' => '&',
  '\'' => '\'',
  '(' => '(',
  ')' => ')',
  '*' => '*',
  '+' => '+',
  ',' => ',',
  '-' => '-',
  '.' => '.',
  '/' => '/',
  0 => '0',
  1 => '1',
  2 => '2',
  3 => '3',
  4 => '4',
  5 => '5',
  6 => '6',
  7 => '7',
  8 => '8',
  9 => '9',
  ':' => ':',
  ';' => ';',
  '<' => '<',
  '=' => '=',
  '>' => '>',
  '?' => '?',
  '@' => '@',
  'A' => 'A',
  'B' => 'B',
  'C' => 'C',
  'D' => 'D',
  'E' => 'E',
  'F' => 'F',
  'G' => 'G',
  'H' => 'H',
  'I' => 'I',
  'J' => 'J',
  'K' => 'K',
  'L' => 'L',
  'M' => 'M',
  'N' => 'N',
  'O' => 'O',
  'P' => 'P',
  'Q' => 'Q',
  'R' => 'R',
  'S' => 'S',
  'T' => 'T',
  'U' => 'U',
  'V' => 'V',
  'W' => 'W',
  'X' => 'X',
  'Y' => 'Y',
  'Z' => 'Z',
  '[' => '[',
  '\\' => '\\',
  ']' => ']',
  '^' => '^',
  '_' => '_',
  '`' => '`',
  'a' => 'a',
  'b' => 'b',
  'c' => 'c',
  'd' => 'd',
  'e' => 'e',
  'f' => 'f',
  'g' => 'g',
  'h' => 'h',
  'i' => 'i',
  'j' => 'j',
  'k' => 'k',
  'l' => 'l',
  'm' => 'm',
  'n' => 'n',
  'o' => 'o',
  'p' => 'p',
  'q' => 'q',
  'r' => 'r',
  's' => 's',
  't' => 't',
  'u' => 'u',
  'v' => 'v',
  'w' => 'w',
  'x' => 'x',
  'y' => 'y',
  'z' => 'z',
  '{' => '{',
  '|' => '|',
  '}' => '}',
  '~' => '~',
  '' => '',
  '�' => '€',
  '�' => '',
  '�' => '‚',
  '�' => 'ƒ',
  '�' => '„',
  '�' => '…',
  '�' => '†',
  '�' => '‡',
  '�' => 'ˆ',
  '�' => '‰',
  '�' => 'Š',
  '�' => '‹',
  '�' => 'Œ',
  '�' => '',
  '�' => 'Ž',
  '�' => '',
  '�' => '',
  '�' => '‘',
  '�' => '’',
  '�' => '“',
  '�' => '”',
  '�' => '•',
  '�' => '–',
  '�' => '—',
  '�' => '˜',
  '�' => '™',
  '�' => 'š',
  '�' => '›',
  '�' => 'œ',
  '�' => '',
  '�' => 'ž',
  '�' => 'Ÿ',
  '�' => ' ',
  '�' => 'Ё',
  '�' => 'Ђ',
  '�' => 'Ѓ',
  '�' => 'Є',
  '�' => 'Ѕ',
  '�' => 'І',
  '�' => 'Ї',
  '�' => 'Ј',
  '�' => 'Љ',
  '�' => 'Њ',
  '�' => 'Ћ',
  '�' => 'Ќ',
  '�' => '­',
  '�' => 'Ў',
  '�' => 'Џ',
  '�' => 'А',
  '�' => 'Б',
  '�' => 'В',
  '�' => 'Г',
  '�' => 'Д',
  '�' => 'Е',
  '�' => 'Ж',
  '�' => 'З',
  '�' => 'И',
  '�' => 'Й',
  '�' => 'К',
  '�' => 'Л',
  '�' => 'М',
  '�' => 'Н',
  '�' => 'О',
  '�' => 'П',
  '�' => 'Р',
  '�' => 'С',
  '�' => 'Т',
  '�' => 'У',
  '�' => 'Ф',
  '�' => 'Х',
  '�' => 'Ц',
  '�' => 'Ч',
  '�' => 'Ш',
  '�' => 'Щ',
  '�' => 'Ъ',
  '�' => 'Ы',
  '�' => 'Ь',
  '�' => 'Э',
  '�' => 'Ю',
  '�' => 'Я',
  '�' => 'а',
  '�' => 'б',
  '�' => 'в',
  '�' => 'г',
  '�' => 'д',
  '�' => 'е',
  '�' => 'ж',
  '�' => 'з',
  '�' => 'и',
  '�' => 'й',
  '�' => 'к',
  '�' => 'л',
  '�' => 'м',
  '�' => 'н',
  '�' => 'о',
  '�' => 'п',
  '�' => 'р',
  '�' => 'с',
  '�' => 'т',
  '�' => 'у',
  '�' => 'ф',
  '�' => 'х',
  '�' => 'ц',
  '�' => 'ч',
  '�' => 'ш',
  '�' => 'щ',
  '�' => 'ъ',
  '�' => 'ы',
  '�' => 'ь',
  '�' => 'э',
  '�' => 'ю',
  '�' => 'я',
  '�' => '№',
  '�' => 'ё',
  '�' => 'ђ',
  '�' => 'ѓ',
  '�' => 'є',
  '�' => 'ѕ',
  '�' => 'і',
  '�' => 'ї',
  '�' => 'ј',
  '�' => 'љ',
  '�' => 'њ',
  '�' => 'ћ',
  '�' => 'ќ',
  '�' => '§',
  '�' => 'ў',
  '�' => 'џ',
);

$result =& $data;
unset($data);

return $result;
PKϤ$Z�O�NN6polyfill-iconv/Resources/charset/from.windows-1258.phpnu�[���<?php

static $data = array (
  '' => '',
  '' => '',
  '' => '',
  '' => '',
  '' => '',
  '' => '',
  '' => '',
  '' => '',
  '' => '',
  '	' => '	',
  '
' => '
',
  '' => '',
  '' => '',
  '
' => '
',
  '' => '',
  '' => '',
  '' => '',
  '' => '',
  '' => '',
  '' => '',
  '' => '',
  '' => '',
  '' => '',
  '' => '',
  '' => '',
  '' => '',
  '' => '',
  '' => '',
  '' => '',
  '' => '',
  '' => '',
  '' => '',
  ' ' => ' ',
  '!' => '!',
  '"' => '"',
  '#' => '#',
  '$' => '$',
  '%' => '%',
  '&' => '&',
  '\'' => '\'',
  '(' => '(',
  ')' => ')',
  '*' => '*',
  '+' => '+',
  ',' => ',',
  '-' => '-',
  '.' => '.',
  '/' => '/',
  0 => '0',
  1 => '1',
  2 => '2',
  3 => '3',
  4 => '4',
  5 => '5',
  6 => '6',
  7 => '7',
  8 => '8',
  9 => '9',
  ':' => ':',
  ';' => ';',
  '<' => '<',
  '=' => '=',
  '>' => '>',
  '?' => '?',
  '@' => '@',
  'A' => 'A',
  'B' => 'B',
  'C' => 'C',
  'D' => 'D',
  'E' => 'E',
  'F' => 'F',
  'G' => 'G',
  'H' => 'H',
  'I' => 'I',
  'J' => 'J',
  'K' => 'K',
  'L' => 'L',
  'M' => 'M',
  'N' => 'N',
  'O' => 'O',
  'P' => 'P',
  'Q' => 'Q',
  'R' => 'R',
  'S' => 'S',
  'T' => 'T',
  'U' => 'U',
  'V' => 'V',
  'W' => 'W',
  'X' => 'X',
  'Y' => 'Y',
  'Z' => 'Z',
  '[' => '[',
  '\\' => '\\',
  ']' => ']',
  '^' => '^',
  '_' => '_',
  '`' => '`',
  'a' => 'a',
  'b' => 'b',
  'c' => 'c',
  'd' => 'd',
  'e' => 'e',
  'f' => 'f',
  'g' => 'g',
  'h' => 'h',
  'i' => 'i',
  'j' => 'j',
  'k' => 'k',
  'l' => 'l',
  'm' => 'm',
  'n' => 'n',
  'o' => 'o',
  'p' => 'p',
  'q' => 'q',
  'r' => 'r',
  's' => 's',
  't' => 't',
  'u' => 'u',
  'v' => 'v',
  'w' => 'w',
  'x' => 'x',
  'y' => 'y',
  'z' => 'z',
  '{' => '{',
  '|' => '|',
  '}' => '}',
  '~' => '~',
  '' => '',
  '�' => '€',
  '�' => '‚',
  '�' => 'ƒ',
  '�' => '„',
  '�' => '…',
  '�' => '†',
  '�' => '‡',
  '�' => 'ˆ',
  '�' => '‰',
  '�' => '‹',
  '�' => 'Œ',
  '�' => '‘',
  '�' => '’',
  '�' => '“',
  '�' => '”',
  '�' => '•',
  '�' => '–',
  '�' => '—',
  '�' => '˜',
  '�' => '™',
  '�' => '›',
  '�' => 'œ',
  '�' => 'Ÿ',
  '�' => ' ',
  '�' => '¡',
  '�' => '¢',
  '�' => '£',
  '�' => '¤',
  '�' => '¥',
  '�' => '¦',
  '�' => '§',
  '�' => '¨',
  '�' => '©',
  '�' => 'ª',
  '�' => '«',
  '�' => '¬',
  '�' => '­',
  '�' => '®',
  '�' => '¯',
  '�' => '°',
  '�' => '±',
  '�' => '²',
  '�' => '³',
  '�' => '´',
  '�' => 'µ',
  '�' => '¶',
  '�' => '·',
  '�' => '¸',
  '�' => '¹',
  '�' => 'º',
  '�' => '»',
  '�' => '¼',
  '�' => '½',
  '�' => '¾',
  '�' => '¿',
  '�' => 'À',
  '�' => 'Á',
  '�' => 'Â',
  '�' => 'Ă',
  '�' => 'Ä',
  '�' => 'Å',
  '�' => 'Æ',
  '�' => 'Ç',
  '�' => 'È',
  '�' => 'É',
  '�' => 'Ê',
  '�' => 'Ë',
  '�' => '̀',
  '�' => 'Í',
  '�' => 'Î',
  '�' => 'Ï',
  '�' => 'Đ',
  '�' => 'Ñ',
  '�' => '̉',
  '�' => 'Ó',
  '�' => 'Ô',
  '�' => 'Ơ',
  '�' => 'Ö',
  '�' => '×',
  '�' => 'Ø',
  '�' => 'Ù',
  '�' => 'Ú',
  '�' => 'Û',
  '�' => 'Ü',
  '�' => 'Ư',
  '�' => '̃',
  '�' => 'ß',
  '�' => 'à',
  '�' => 'á',
  '�' => 'â',
  '�' => 'ă',
  '�' => 'ä',
  '�' => 'å',
  '�' => 'æ',
  '�' => 'ç',
  '�' => 'è',
  '�' => 'é',
  '�' => 'ê',
  '�' => 'ë',
  '�' => '́',
  '�' => 'í',
  '�' => 'î',
  '�' => 'ï',
  '�' => 'đ',
  '�' => 'ñ',
  '�' => '̣',
  '�' => 'ó',
  '�' => 'ô',
  '�' => 'ơ',
  '�' => 'ö',
  '�' => '÷',
  '�' => 'ø',
  '�' => 'ù',
  '�' => 'ú',
  '�' => 'û',
  '�' => 'ü',
  '�' => 'ư',
  '�' => '₫',
  '�' => 'ÿ',
);

$result =& $data;
unset($data);

return $result;
PKϤ$Zͩ�Ū�4polyfill-iconv/Resources/charset/from.iso-8859-8.phpnu�[���<?php

static $data = array (
  '' => '',
  '' => '',
  '' => '',
  '' => '',
  '' => '',
  '' => '',
  '' => '',
  '' => '',
  '' => '',
  '	' => '	',
  '
' => '
',
  '' => '',
  '' => '',
  '
' => '
',
  '' => '',
  '' => '',
  '' => '',
  '' => '',
  '' => '',
  '' => '',
  '' => '',
  '' => '',
  '' => '',
  '' => '',
  '' => '',
  '' => '',
  '' => '',
  '' => '',
  '' => '',
  '' => '',
  '' => '',
  '' => '',
  ' ' => ' ',
  '!' => '!',
  '"' => '"',
  '#' => '#',
  '$' => '$',
  '%' => '%',
  '&' => '&',
  '\'' => '\'',
  '(' => '(',
  ')' => ')',
  '*' => '*',
  '+' => '+',
  ',' => ',',
  '-' => '-',
  '.' => '.',
  '/' => '/',
  0 => '0',
  1 => '1',
  2 => '2',
  3 => '3',
  4 => '4',
  5 => '5',
  6 => '6',
  7 => '7',
  8 => '8',
  9 => '9',
  ':' => ':',
  ';' => ';',
  '<' => '<',
  '=' => '=',
  '>' => '>',
  '?' => '?',
  '@' => '@',
  'A' => 'A',
  'B' => 'B',
  'C' => 'C',
  'D' => 'D',
  'E' => 'E',
  'F' => 'F',
  'G' => 'G',
  'H' => 'H',
  'I' => 'I',
  'J' => 'J',
  'K' => 'K',
  'L' => 'L',
  'M' => 'M',
  'N' => 'N',
  'O' => 'O',
  'P' => 'P',
  'Q' => 'Q',
  'R' => 'R',
  'S' => 'S',
  'T' => 'T',
  'U' => 'U',
  'V' => 'V',
  'W' => 'W',
  'X' => 'X',
  'Y' => 'Y',
  'Z' => 'Z',
  '[' => '[',
  '\\' => '\\',
  ']' => ']',
  '^' => '^',
  '_' => '_',
  '`' => '`',
  'a' => 'a',
  'b' => 'b',
  'c' => 'c',
  'd' => 'd',
  'e' => 'e',
  'f' => 'f',
  'g' => 'g',
  'h' => 'h',
  'i' => 'i',
  'j' => 'j',
  'k' => 'k',
  'l' => 'l',
  'm' => 'm',
  'n' => 'n',
  'o' => 'o',
  'p' => 'p',
  'q' => 'q',
  'r' => 'r',
  's' => 's',
  't' => 't',
  'u' => 'u',
  'v' => 'v',
  'w' => 'w',
  'x' => 'x',
  'y' => 'y',
  'z' => 'z',
  '{' => '{',
  '|' => '|',
  '}' => '}',
  '~' => '~',
  '' => '',
  '�' => '€',
  '�' => '',
  '�' => '‚',
  '�' => 'ƒ',
  '�' => '„',
  '�' => '…',
  '�' => '†',
  '�' => '‡',
  '�' => 'ˆ',
  '�' => '‰',
  '�' => 'Š',
  '�' => '‹',
  '�' => 'Œ',
  '�' => '',
  '�' => 'Ž',
  '�' => '',
  '�' => '',
  '�' => '‘',
  '�' => '’',
  '�' => '“',
  '�' => '”',
  '�' => '•',
  '�' => '–',
  '�' => '—',
  '�' => '˜',
  '�' => '™',
  '�' => 'š',
  '�' => '›',
  '�' => 'œ',
  '�' => '',
  '�' => 'ž',
  '�' => 'Ÿ',
  '�' => ' ',
  '�' => '¢',
  '�' => '£',
  '�' => '¤',
  '�' => '¥',
  '�' => '¦',
  '�' => '§',
  '�' => '¨',
  '�' => '©',
  '�' => '×',
  '�' => '«',
  '�' => '¬',
  '�' => '­',
  '�' => '®',
  '�' => '¯',
  '�' => '°',
  '�' => '±',
  '�' => '²',
  '�' => '³',
  '�' => '´',
  '�' => 'µ',
  '�' => '¶',
  '�' => '·',
  '�' => '¸',
  '�' => '¹',
  '�' => '÷',
  '�' => '»',
  '�' => '¼',
  '�' => '½',
  '�' => '¾',
  '�' => '‗',
  '�' => 'א',
  '�' => 'ב',
  '�' => 'ג',
  '�' => 'ד',
  '�' => 'ה',
  '�' => 'ו',
  '�' => 'ז',
  '�' => 'ח',
  '�' => 'ט',
  '�' => 'י',
  '�' => 'ך',
  '�' => 'כ',
  '�' => 'ל',
  '�' => 'ם',
  '�' => 'מ',
  '�' => 'ן',
  '�' => 'נ',
  '�' => 'ס',
  '�' => 'ע',
  '�' => 'ף',
  '�' => 'פ',
  '�' => 'ץ',
  '�' => 'צ',
  '�' => 'ק',
  '�' => 'ר',
  '�' => 'ש',
  '�' => 'ת',
  '�' => '‎',
  '�' => '‏',
);

$result =& $data;
unset($data);

return $result;
PKϤ$Zl����5polyfill-iconv/Resources/charset/from.iso-8859-14.phpnu�[���<?php

static $data = array (
  '' => '',
  '' => '',
  '' => '',
  '' => '',
  '' => '',
  '' => '',
  '' => '',
  '' => '',
  '' => '',
  '	' => '	',
  '
' => '
',
  '' => '',
  '' => '',
  '
' => '
',
  '' => '',
  '' => '',
  '' => '',
  '' => '',
  '' => '',
  '' => '',
  '' => '',
  '' => '',
  '' => '',
  '' => '',
  '' => '',
  '' => '',
  '' => '',
  '' => '',
  '' => '',
  '' => '',
  '' => '',
  '' => '',
  ' ' => ' ',
  '!' => '!',
  '"' => '"',
  '#' => '#',
  '$' => '$',
  '%' => '%',
  '&' => '&',
  '\'' => '\'',
  '(' => '(',
  ')' => ')',
  '*' => '*',
  '+' => '+',
  ',' => ',',
  '-' => '-',
  '.' => '.',
  '/' => '/',
  0 => '0',
  1 => '1',
  2 => '2',
  3 => '3',
  4 => '4',
  5 => '5',
  6 => '6',
  7 => '7',
  8 => '8',
  9 => '9',
  ':' => ':',
  ';' => ';',
  '<' => '<',
  '=' => '=',
  '>' => '>',
  '?' => '?',
  '@' => '@',
  'A' => 'A',
  'B' => 'B',
  'C' => 'C',
  'D' => 'D',
  'E' => 'E',
  'F' => 'F',
  'G' => 'G',
  'H' => 'H',
  'I' => 'I',
  'J' => 'J',
  'K' => 'K',
  'L' => 'L',
  'M' => 'M',
  'N' => 'N',
  'O' => 'O',
  'P' => 'P',
  'Q' => 'Q',
  'R' => 'R',
  'S' => 'S',
  'T' => 'T',
  'U' => 'U',
  'V' => 'V',
  'W' => 'W',
  'X' => 'X',
  'Y' => 'Y',
  'Z' => 'Z',
  '[' => '[',
  '\\' => '\\',
  ']' => ']',
  '^' => '^',
  '_' => '_',
  '`' => '`',
  'a' => 'a',
  'b' => 'b',
  'c' => 'c',
  'd' => 'd',
  'e' => 'e',
  'f' => 'f',
  'g' => 'g',
  'h' => 'h',
  'i' => 'i',
  'j' => 'j',
  'k' => 'k',
  'l' => 'l',
  'm' => 'm',
  'n' => 'n',
  'o' => 'o',
  'p' => 'p',
  'q' => 'q',
  'r' => 'r',
  's' => 's',
  't' => 't',
  'u' => 'u',
  'v' => 'v',
  'w' => 'w',
  'x' => 'x',
  'y' => 'y',
  'z' => 'z',
  '{' => '{',
  '|' => '|',
  '}' => '}',
  '~' => '~',
  '' => '',
  '�' => '€',
  '�' => '',
  '�' => '‚',
  '�' => 'ƒ',
  '�' => '„',
  '�' => '…',
  '�' => '†',
  '�' => '‡',
  '�' => 'ˆ',
  '�' => '‰',
  '�' => 'Š',
  '�' => '‹',
  '�' => 'Œ',
  '�' => '',
  '�' => 'Ž',
  '�' => '',
  '�' => '',
  '�' => '‘',
  '�' => '’',
  '�' => '“',
  '�' => '”',
  '�' => '•',
  '�' => '–',
  '�' => '—',
  '�' => '˜',
  '�' => '™',
  '�' => 'š',
  '�' => '›',
  '�' => 'œ',
  '�' => '',
  '�' => 'ž',
  '�' => 'Ÿ',
  '�' => ' ',
  '�' => 'Ḃ',
  '�' => 'ḃ',
  '�' => '£',
  '�' => 'Ċ',
  '�' => 'ċ',
  '�' => 'Ḋ',
  '�' => '§',
  '�' => 'Ẁ',
  '�' => '©',
  '�' => 'Ẃ',
  '�' => 'ḋ',
  '�' => 'Ỳ',
  '�' => '­',
  '�' => '®',
  '�' => 'Ÿ',
  '�' => 'Ḟ',
  '�' => 'ḟ',
  '�' => 'Ġ',
  '�' => 'ġ',
  '�' => 'Ṁ',
  '�' => 'ṁ',
  '�' => '¶',
  '�' => 'Ṗ',
  '�' => 'ẁ',
  '�' => 'ṗ',
  '�' => 'ẃ',
  '�' => 'Ṡ',
  '�' => 'ỳ',
  '�' => 'Ẅ',
  '�' => 'ẅ',
  '�' => 'ṡ',
  '�' => 'À',
  '�' => 'Á',
  '�' => 'Â',
  '�' => 'Ã',
  '�' => 'Ä',
  '�' => 'Å',
  '�' => 'Æ',
  '�' => 'Ç',
  '�' => 'È',
  '�' => 'É',
  '�' => 'Ê',
  '�' => 'Ë',
  '�' => 'Ì',
  '�' => 'Í',
  '�' => 'Î',
  '�' => 'Ï',
  '�' => 'Ŵ',
  '�' => 'Ñ',
  '�' => 'Ò',
  '�' => 'Ó',
  '�' => 'Ô',
  '�' => 'Õ',
  '�' => 'Ö',
  '�' => 'Ṫ',
  '�' => 'Ø',
  '�' => 'Ù',
  '�' => 'Ú',
  '�' => 'Û',
  '�' => 'Ü',
  '�' => 'Ý',
  '�' => 'Ŷ',
  '�' => 'ß',
  '�' => 'à',
  '�' => 'á',
  '�' => 'â',
  '�' => 'ã',
  '�' => 'ä',
  '�' => 'å',
  '�' => 'æ',
  '�' => 'ç',
  '�' => 'è',
  '�' => 'é',
  '�' => 'ê',
  '�' => 'ë',
  '�' => 'ì',
  '�' => 'í',
  '�' => 'î',
  '�' => 'ï',
  '�' => 'ŵ',
  '�' => 'ñ',
  '�' => 'ò',
  '�' => 'ó',
  '�' => 'ô',
  '�' => 'õ',
  '�' => 'ö',
  '�' => 'ṫ',
  '�' => 'ø',
  '�' => 'ù',
  '�' => 'ú',
  '�' => 'û',
  '�' => 'ü',
  '�' => 'ý',
  '�' => 'ŷ',
  '�' => 'ÿ',
);

$result =& $data;
unset($data);

return $result;
PKϤ$ZZ�����6polyfill-iconv/Resources/charset/from.windows-1251.phpnu�[���<?php

static $data = array (
  '' => '',
  '' => '',
  '' => '',
  '' => '',
  '' => '',
  '' => '',
  '' => '',
  '' => '',
  '' => '',
  '	' => '	',
  '
' => '
',
  '' => '',
  '' => '',
  '
' => '
',
  '' => '',
  '' => '',
  '' => '',
  '' => '',
  '' => '',
  '' => '',
  '' => '',
  '' => '',
  '' => '',
  '' => '',
  '' => '',
  '' => '',
  '' => '',
  '' => '',
  '' => '',
  '' => '',
  '' => '',
  '' => '',
  ' ' => ' ',
  '!' => '!',
  '"' => '"',
  '#' => '#',
  '$' => '$',
  '%' => '%',
  '&' => '&',
  '\'' => '\'',
  '(' => '(',
  ')' => ')',
  '*' => '*',
  '+' => '+',
  ',' => ',',
  '-' => '-',
  '.' => '.',
  '/' => '/',
  0 => '0',
  1 => '1',
  2 => '2',
  3 => '3',
  4 => '4',
  5 => '5',
  6 => '6',
  7 => '7',
  8 => '8',
  9 => '9',
  ':' => ':',
  ';' => ';',
  '<' => '<',
  '=' => '=',
  '>' => '>',
  '?' => '?',
  '@' => '@',
  'A' => 'A',
  'B' => 'B',
  'C' => 'C',
  'D' => 'D',
  'E' => 'E',
  'F' => 'F',
  'G' => 'G',
  'H' => 'H',
  'I' => 'I',
  'J' => 'J',
  'K' => 'K',
  'L' => 'L',
  'M' => 'M',
  'N' => 'N',
  'O' => 'O',
  'P' => 'P',
  'Q' => 'Q',
  'R' => 'R',
  'S' => 'S',
  'T' => 'T',
  'U' => 'U',
  'V' => 'V',
  'W' => 'W',
  'X' => 'X',
  'Y' => 'Y',
  'Z' => 'Z',
  '[' => '[',
  '\\' => '\\',
  ']' => ']',
  '^' => '^',
  '_' => '_',
  '`' => '`',
  'a' => 'a',
  'b' => 'b',
  'c' => 'c',
  'd' => 'd',
  'e' => 'e',
  'f' => 'f',
  'g' => 'g',
  'h' => 'h',
  'i' => 'i',
  'j' => 'j',
  'k' => 'k',
  'l' => 'l',
  'm' => 'm',
  'n' => 'n',
  'o' => 'o',
  'p' => 'p',
  'q' => 'q',
  'r' => 'r',
  's' => 's',
  't' => 't',
  'u' => 'u',
  'v' => 'v',
  'w' => 'w',
  'x' => 'x',
  'y' => 'y',
  'z' => 'z',
  '{' => '{',
  '|' => '|',
  '}' => '}',
  '~' => '~',
  '' => '',
  '�' => 'Ђ',
  '�' => 'Ѓ',
  '�' => '‚',
  '�' => 'ѓ',
  '�' => '„',
  '�' => '…',
  '�' => '†',
  '�' => '‡',
  '�' => '€',
  '�' => '‰',
  '�' => 'Љ',
  '�' => '‹',
  '�' => 'Њ',
  '�' => 'Ќ',
  '�' => 'Ћ',
  '�' => 'Џ',
  '�' => 'ђ',
  '�' => '‘',
  '�' => '’',
  '�' => '“',
  '�' => '”',
  '�' => '•',
  '�' => '–',
  '�' => '—',
  '�' => '™',
  '�' => 'љ',
  '�' => '›',
  '�' => 'њ',
  '�' => 'ќ',
  '�' => 'ћ',
  '�' => 'џ',
  '�' => ' ',
  '�' => 'Ў',
  '�' => 'ў',
  '�' => 'Ј',
  '�' => '¤',
  '�' => 'Ґ',
  '�' => '¦',
  '�' => '§',
  '�' => 'Ё',
  '�' => '©',
  '�' => 'Є',
  '�' => '«',
  '�' => '¬',
  '�' => '­',
  '�' => '®',
  '�' => 'Ї',
  '�' => '°',
  '�' => '±',
  '�' => 'І',
  '�' => 'і',
  '�' => 'ґ',
  '�' => 'µ',
  '�' => '¶',
  '�' => '·',
  '�' => 'ё',
  '�' => '№',
  '�' => 'є',
  '�' => '»',
  '�' => 'ј',
  '�' => 'Ѕ',
  '�' => 'ѕ',
  '�' => 'ї',
  '�' => 'А',
  '�' => 'Б',
  '�' => 'В',
  '�' => 'Г',
  '�' => 'Д',
  '�' => 'Е',
  '�' => 'Ж',
  '�' => 'З',
  '�' => 'И',
  '�' => 'Й',
  '�' => 'К',
  '�' => 'Л',
  '�' => 'М',
  '�' => 'Н',
  '�' => 'О',
  '�' => 'П',
  '�' => 'Р',
  '�' => 'С',
  '�' => 'Т',
  '�' => 'У',
  '�' => 'Ф',
  '�' => 'Х',
  '�' => 'Ц',
  '�' => 'Ч',
  '�' => 'Ш',
  '�' => 'Щ',
  '�' => 'Ъ',
  '�' => 'Ы',
  '�' => 'Ь',
  '�' => 'Э',
  '�' => 'Ю',
  '�' => 'Я',
  '�' => 'а',
  '�' => 'б',
  '�' => 'в',
  '�' => 'г',
  '�' => 'д',
  '�' => 'е',
  '�' => 'ж',
  '�' => 'з',
  '�' => 'и',
  '�' => 'й',
  '�' => 'к',
  '�' => 'л',
  '�' => 'м',
  '�' => 'н',
  '�' => 'о',
  '�' => 'п',
  '�' => 'р',
  '�' => 'с',
  '�' => 'т',
  '�' => 'у',
  '�' => 'ф',
  '�' => 'х',
  '�' => 'ц',
  '�' => 'ч',
  '�' => 'ш',
  '�' => 'щ',
  '�' => 'ъ',
  '�' => 'ы',
  '�' => 'ь',
  '�' => 'э',
  '�' => 'ю',
  '�' => 'я',
);

$result =& $data;
unset($data);

return $result;
PKϤ$ZL�tw��/polyfill-iconv/Resources/charset/from.cp864.phpnu�[���<?php

static $data = array (
  '' => '',
  '' => '',
  '' => '',
  '' => '',
  '' => '',
  '' => '',
  '' => '',
  '' => '',
  '' => '',
  '	' => '	',
  '
' => '
',
  '' => '',
  '' => '',
  '
' => '
',
  '' => '',
  '' => '',
  '' => '',
  '' => '',
  '' => '',
  '' => '',
  '' => '',
  '' => '',
  '' => '',
  '' => '',
  '' => '',
  '' => '',
  '' => '',
  '' => '',
  '' => '',
  '' => '',
  '' => '',
  '' => '',
  ' ' => ' ',
  '!' => '!',
  '"' => '"',
  '#' => '#',
  '$' => '$',
  '%' => '٪',
  '&' => '&',
  '\'' => '\'',
  '(' => '(',
  ')' => ')',
  '*' => '*',
  '+' => '+',
  ',' => ',',
  '-' => '-',
  '.' => '.',
  '/' => '/',
  0 => '0',
  1 => '1',
  2 => '2',
  3 => '3',
  4 => '4',
  5 => '5',
  6 => '6',
  7 => '7',
  8 => '8',
  9 => '9',
  ':' => ':',
  ';' => ';',
  '<' => '<',
  '=' => '=',
  '>' => '>',
  '?' => '?',
  '@' => '@',
  'A' => 'A',
  'B' => 'B',
  'C' => 'C',
  'D' => 'D',
  'E' => 'E',
  'F' => 'F',
  'G' => 'G',
  'H' => 'H',
  'I' => 'I',
  'J' => 'J',
  'K' => 'K',
  'L' => 'L',
  'M' => 'M',
  'N' => 'N',
  'O' => 'O',
  'P' => 'P',
  'Q' => 'Q',
  'R' => 'R',
  'S' => 'S',
  'T' => 'T',
  'U' => 'U',
  'V' => 'V',
  'W' => 'W',
  'X' => 'X',
  'Y' => 'Y',
  'Z' => 'Z',
  '[' => '[',
  '\\' => '\\',
  ']' => ']',
  '^' => '^',
  '_' => '_',
  '`' => '`',
  'a' => 'a',
  'b' => 'b',
  'c' => 'c',
  'd' => 'd',
  'e' => 'e',
  'f' => 'f',
  'g' => 'g',
  'h' => 'h',
  'i' => 'i',
  'j' => 'j',
  'k' => 'k',
  'l' => 'l',
  'm' => 'm',
  'n' => 'n',
  'o' => 'o',
  'p' => 'p',
  'q' => 'q',
  'r' => 'r',
  's' => 's',
  't' => 't',
  'u' => 'u',
  'v' => 'v',
  'w' => 'w',
  'x' => 'x',
  'y' => 'y',
  'z' => 'z',
  '{' => '{',
  '|' => '|',
  '}' => '}',
  '~' => '~',
  '' => '',
  '�' => '°',
  '�' => '·',
  '�' => '∙',
  '�' => '√',
  '�' => '▒',
  '�' => '─',
  '�' => '│',
  '�' => '┼',
  '�' => '┤',
  '�' => '┬',
  '�' => '├',
  '�' => '┴',
  '�' => '┐',
  '�' => '┌',
  '�' => '└',
  '�' => '┘',
  '�' => 'β',
  '�' => '∞',
  '�' => 'φ',
  '�' => '±',
  '�' => '½',
  '�' => '¼',
  '�' => '≈',
  '�' => '«',
  '�' => '»',
  '�' => 'ﻷ',
  '�' => 'ﻸ',
  '�' => 'ﻻ',
  '�' => 'ﻼ',
  '�' => ' ',
  '�' => '­',
  '�' => 'ﺂ',
  '�' => '£',
  '�' => '¤',
  '�' => 'ﺄ',
  '�' => 'ﺎ',
  '�' => 'ﺏ',
  '�' => 'ﺕ',
  '�' => 'ﺙ',
  '�' => '،',
  '�' => 'ﺝ',
  '�' => 'ﺡ',
  '�' => 'ﺥ',
  '�' => '٠',
  '�' => '١',
  '�' => '٢',
  '�' => '٣',
  '�' => '٤',
  '�' => '٥',
  '�' => '٦',
  '�' => '٧',
  '�' => '٨',
  '�' => '٩',
  '�' => 'ﻑ',
  '�' => '؛',
  '�' => 'ﺱ',
  '�' => 'ﺵ',
  '�' => 'ﺹ',
  '�' => '؟',
  '�' => '¢',
  '�' => 'ﺀ',
  '�' => 'ﺁ',
  '�' => 'ﺃ',
  '�' => 'ﺅ',
  '�' => 'ﻊ',
  '�' => 'ﺋ',
  '�' => 'ﺍ',
  '�' => 'ﺑ',
  '�' => 'ﺓ',
  '�' => 'ﺗ',
  '�' => 'ﺛ',
  '�' => 'ﺟ',
  '�' => 'ﺣ',
  '�' => 'ﺧ',
  '�' => 'ﺩ',
  '�' => 'ﺫ',
  '�' => 'ﺭ',
  '�' => 'ﺯ',
  '�' => 'ﺳ',
  '�' => 'ﺷ',
  '�' => 'ﺻ',
  '�' => 'ﺿ',
  '�' => 'ﻁ',
  '�' => 'ﻅ',
  '�' => 'ﻋ',
  '�' => 'ﻏ',
  '�' => '¦',
  '�' => '¬',
  '�' => '÷',
  '�' => '×',
  '�' => 'ﻉ',
  '�' => 'ـ',
  '�' => 'ﻓ',
  '�' => 'ﻗ',
  '�' => 'ﻛ',
  '�' => 'ﻟ',
  '�' => 'ﻣ',
  '�' => 'ﻧ',
  '�' => 'ﻫ',
  '�' => 'ﻭ',
  '�' => 'ﻯ',
  '�' => 'ﻳ',
  '�' => 'ﺽ',
  '�' => 'ﻌ',
  '�' => 'ﻎ',
  '�' => 'ﻍ',
  '�' => 'ﻡ',
  '�' => 'ﹽ',
  '�' => 'ّ',
  '�' => 'ﻥ',
  '�' => 'ﻩ',
  '�' => 'ﻬ',
  '�' => 'ﻰ',
  '�' => 'ﻲ',
  '�' => 'ﻐ',
  '�' => 'ﻕ',
  '�' => 'ﻵ',
  '�' => 'ﻶ',
  '�' => 'ﻝ',
  '�' => 'ﻙ',
  '�' => 'ﻱ',
  '�' => '■',
);

$result =& $data;
unset($data);

return $result;
PKϤ$Zȫ�ˉ�6polyfill-iconv/Resources/charset/from.windows-1252.phpnu�[���<?php

static $data = array (
  '' => '',
  '' => '',
  '' => '',
  '' => '',
  '' => '',
  '' => '',
  '' => '',
  '' => '',
  '' => '',
  '	' => '	',
  '
' => '
',
  '' => '',
  '' => '',
  '
' => '
',
  '' => '',
  '' => '',
  '' => '',
  '' => '',
  '' => '',
  '' => '',
  '' => '',
  '' => '',
  '' => '',
  '' => '',
  '' => '',
  '' => '',
  '' => '',
  '' => '',
  '' => '',
  '' => '',
  '' => '',
  '' => '',
  ' ' => ' ',
  '!' => '!',
  '"' => '"',
  '#' => '#',
  '$' => '$',
  '%' => '%',
  '&' => '&',
  '\'' => '\'',
  '(' => '(',
  ')' => ')',
  '*' => '*',
  '+' => '+',
  ',' => ',',
  '-' => '-',
  '.' => '.',
  '/' => '/',
  0 => '0',
  1 => '1',
  2 => '2',
  3 => '3',
  4 => '4',
  5 => '5',
  6 => '6',
  7 => '7',
  8 => '8',
  9 => '9',
  ':' => ':',
  ';' => ';',
  '<' => '<',
  '=' => '=',
  '>' => '>',
  '?' => '?',
  '@' => '@',
  'A' => 'A',
  'B' => 'B',
  'C' => 'C',
  'D' => 'D',
  'E' => 'E',
  'F' => 'F',
  'G' => 'G',
  'H' => 'H',
  'I' => 'I',
  'J' => 'J',
  'K' => 'K',
  'L' => 'L',
  'M' => 'M',
  'N' => 'N',
  'O' => 'O',
  'P' => 'P',
  'Q' => 'Q',
  'R' => 'R',
  'S' => 'S',
  'T' => 'T',
  'U' => 'U',
  'V' => 'V',
  'W' => 'W',
  'X' => 'X',
  'Y' => 'Y',
  'Z' => 'Z',
  '[' => '[',
  '\\' => '\\',
  ']' => ']',
  '^' => '^',
  '_' => '_',
  '`' => '`',
  'a' => 'a',
  'b' => 'b',
  'c' => 'c',
  'd' => 'd',
  'e' => 'e',
  'f' => 'f',
  'g' => 'g',
  'h' => 'h',
  'i' => 'i',
  'j' => 'j',
  'k' => 'k',
  'l' => 'l',
  'm' => 'm',
  'n' => 'n',
  'o' => 'o',
  'p' => 'p',
  'q' => 'q',
  'r' => 'r',
  's' => 's',
  't' => 't',
  'u' => 'u',
  'v' => 'v',
  'w' => 'w',
  'x' => 'x',
  'y' => 'y',
  'z' => 'z',
  '{' => '{',
  '|' => '|',
  '}' => '}',
  '~' => '~',
  '' => '',
  '�' => '€',
  '�' => '‚',
  '�' => 'ƒ',
  '�' => '„',
  '�' => '…',
  '�' => '†',
  '�' => '‡',
  '�' => 'ˆ',
  '�' => '‰',
  '�' => 'Š',
  '�' => '‹',
  '�' => 'Œ',
  '�' => 'Ž',
  '�' => '‘',
  '�' => '’',
  '�' => '“',
  '�' => '”',
  '�' => '•',
  '�' => '–',
  '�' => '—',
  '�' => '˜',
  '�' => '™',
  '�' => 'š',
  '�' => '›',
  '�' => 'œ',
  '�' => 'ž',
  '�' => 'Ÿ',
  '�' => ' ',
  '�' => '¡',
  '�' => '¢',
  '�' => '£',
  '�' => '¤',
  '�' => '¥',
  '�' => '¦',
  '�' => '§',
  '�' => '¨',
  '�' => '©',
  '�' => 'ª',
  '�' => '«',
  '�' => '¬',
  '�' => '­',
  '�' => '®',
  '�' => '¯',
  '�' => '°',
  '�' => '±',
  '�' => '²',
  '�' => '³',
  '�' => '´',
  '�' => 'µ',
  '�' => '¶',
  '�' => '·',
  '�' => '¸',
  '�' => '¹',
  '�' => 'º',
  '�' => '»',
  '�' => '¼',
  '�' => '½',
  '�' => '¾',
  '�' => '¿',
  '�' => 'À',
  '�' => 'Á',
  '�' => 'Â',
  '�' => 'Ã',
  '�' => 'Ä',
  '�' => 'Å',
  '�' => 'Æ',
  '�' => 'Ç',
  '�' => 'È',
  '�' => 'É',
  '�' => 'Ê',
  '�' => 'Ë',
  '�' => 'Ì',
  '�' => 'Í',
  '�' => 'Î',
  '�' => 'Ï',
  '�' => 'Ð',
  '�' => 'Ñ',
  '�' => 'Ò',
  '�' => 'Ó',
  '�' => 'Ô',
  '�' => 'Õ',
  '�' => 'Ö',
  '�' => '×',
  '�' => 'Ø',
  '�' => 'Ù',
  '�' => 'Ú',
  '�' => 'Û',
  '�' => 'Ü',
  '�' => 'Ý',
  '�' => 'Þ',
  '�' => 'ß',
  '�' => 'à',
  '�' => 'á',
  '�' => 'â',
  '�' => 'ã',
  '�' => 'ä',
  '�' => 'å',
  '�' => 'æ',
  '�' => 'ç',
  '�' => 'è',
  '�' => 'é',
  '�' => 'ê',
  '�' => 'ë',
  '�' => 'ì',
  '�' => 'í',
  '�' => 'î',
  '�' => 'ï',
  '�' => 'ð',
  '�' => 'ñ',
  '�' => 'ò',
  '�' => 'ó',
  '�' => 'ô',
  '�' => 'õ',
  '�' => 'ö',
  '�' => '÷',
  '�' => 'ø',
  '�' => 'ù',
  '�' => 'ú',
  '�' => 'û',
  '�' => 'ü',
  '�' => 'ý',
  '�' => 'þ',
  '�' => 'ÿ',
);

$result =& $data;
unset($data);

return $result;
PKϤ$Z�꣎��.polyfill-iconv/Resources/charset/from.big5.phpnu�[���<?php

static $data = array (
  '�@' => ' ',
  '�A' => ',',
  '�B' => '、',
  '�C' => '。',
  '�D' => '.',
  '�E' => '•',
  '�F' => ';',
  '�G' => ':',
  '�H' => '?',
  '�I' => '!',
  '�J' => '︰',
  '�K' => '…',
  '�L' => '‥',
  '�M' => '﹐',
  '�N' => '、',
  '�O' => '﹒',
  '�P' => '·',
  '�Q' => '﹔',
  '�R' => '﹕',
  '�S' => '﹖',
  '�T' => '﹗',
  '�U' => '|',
  '�V' => '–',
  '�W' => '︱',
  '�X' => '—',
  '�Y' => '︳',
  '�Z' => '�',
  '�[' => '︴',
  '�\\' => '﹏',
  '�]' => '(',
  '�^' => ')',
  '�_' => '︵',
  '�`' => '︶',
  '�a' => '{',
  '�b' => '}',
  '�c' => '︷',
  '�d' => '︸',
  '�e' => '〔',
  '�f' => '〕',
  '�g' => '︹',
  '�h' => '︺',
  '�i' => '【',
  '�j' => '】',
  '�k' => '︻',
  '�l' => '︼',
  '�m' => '《',
  '�n' => '》',
  '�o' => '︽',
  '�p' => '︾',
  '�q' => '〈',
  '�r' => '〉',
  '�s' => '︿',
  '�t' => '﹀',
  '�u' => '「',
  '�v' => '」',
  '�w' => '﹁',
  '�x' => '﹂',
  '�y' => '『',
  '�z' => '』',
  '�{' => '﹃',
  '�|' => '﹄',
  '�}' => '﹙',
  '�~' => '﹚',
  '��' => '﹛',
  '��' => '﹜',
  '��' => '﹝',
  '��' => '﹞',
  '��' => '‘',
  '��' => '’',
  '��' => '“',
  '��' => '”',
  '��' => '〝',
  '��' => '〞',
  '��' => '‵',
  '��' => '′',
  '��' => '#',
  '��' => '&',
  '��' => '*',
  '��' => '※',
  '��' => '§',
  '��' => '〃',
  '��' => '○',
  '��' => '●',
  '��' => '△',
  '��' => '▲',
  '��' => '◎',
  '��' => '☆',
  '��' => '★',
  '��' => '◇',
  '��' => '◆',
  '��' => '□',
  '��' => '■',
  '��' => '▽',
  '��' => '▼',
  '��' => '㊣',
  '��' => '℅',
  '��' => '‾',
  '��' => '�',
  '��' => '_',
  '��' => '�',
  '��' => '﹉',
  '��' => '﹊',
  '��' => '﹍',
  '��' => '﹎',
  '��' => '﹋',
  '��' => '﹌',
  '��' => '﹟',
  '��' => '﹠',
  '��' => '﹡',
  '��' => '+',
  '��' => '-',
  '��' => '×',
  '��' => '÷',
  '��' => '±',
  '��' => '√',
  '��' => '<',
  '��' => '>',
  '��' => '=',
  '��' => '≦',
  '��' => '≧',
  '��' => '≠',
  '��' => '∞',
  '��' => '≒',
  '��' => '≡',
  '��' => '﹢',
  '��' => '﹣',
  '��' => '﹤',
  '��' => '﹥',
  '��' => '﹦',
  '��' => '∼',
  '��' => '∩',
  '��' => '∪',
  '��' => '⊥',
  '��' => '∠',
  '��' => '∟',
  '��' => '⊿',
  '��' => '㏒',
  '��' => '㏑',
  '��' => '∫',
  '��' => '∮',
  '��' => '∵',
  '��' => '∴',
  '��' => '♀',
  '��' => '♂',
  '��' => '♁',
  '��' => '☉',
  '��' => '↑',
  '��' => '↓',
  '��' => '←',
  '��' => '→',
  '��' => '↖',
  '��' => '↗',
  '��' => '↙',
  '��' => '↘',
  '��' => '∥',
  '��' => '∣',
  '��' => '�',
  '�@' => '�',
  '�A' => '/',
  '�B' => '\',
  '�C' => '$',
  '�D' => '¥',
  '�E' => '〒',
  '�F' => '¢',
  '�G' => '£',
  '�H' => '%',
  '�I' => '@',
  '�J' => '℃',
  '�K' => '℉',
  '�L' => '﹩',
  '�M' => '﹪',
  '�N' => '﹫',
  '�O' => '㏕',
  '�P' => '㎜',
  '�Q' => '㎝',
  '�R' => '㎞',
  '�S' => '㏎',
  '�T' => '㎡',
  '�U' => '㎎',
  '�V' => '㎏',
  '�W' => '㏄',
  '�X' => '°',
  '�Y' => '兙',
  '�Z' => '兛',
  '�[' => '兞',
  '�\\' => '兝',
  '�]' => '兡',
  '�^' => '兣',
  '�_' => '嗧',
  '�`' => '瓩',
  '�a' => '糎',
  '�b' => '▁',
  '�c' => '▂',
  '�d' => '▃',
  '�e' => '▄',
  '�f' => '▅',
  '�g' => '▆',
  '�h' => '▇',
  '�i' => '█',
  '�j' => '▏',
  '�k' => '▎',
  '�l' => '▍',
  '�m' => '▌',
  '�n' => '▋',
  '�o' => '▊',
  '�p' => '▉',
  '�q' => '┼',
  '�r' => '┴',
  '�s' => '┬',
  '�t' => '┤',
  '�u' => '├',
  '�v' => '▔',
  '�w' => '─',
  '�x' => '│',
  '�y' => '▕',
  '�z' => '┌',
  '�{' => '┐',
  '�|' => '└',
  '�}' => '┘',
  '�~' => '╭',
  '��' => '╮',
  '��' => '╰',
  '��' => '╯',
  '��' => '═',
  '��' => '╞',
  '��' => '╪',
  '��' => '╡',
  '��' => '◢',
  '��' => '◣',
  '��' => '◥',
  '��' => '◤',
  '��' => '╱',
  '��' => '╲',
  '��' => '╳',
  '��' => '0',
  '��' => '1',
  '��' => '2',
  '��' => '3',
  '��' => '4',
  '��' => '5',
  '��' => '6',
  '��' => '7',
  '��' => '8',
  '��' => '9',
  '��' => 'Ⅰ',
  '��' => 'Ⅱ',
  '��' => 'Ⅲ',
  '��' => 'Ⅳ',
  '��' => 'Ⅴ',
  '��' => 'Ⅵ',
  '��' => 'Ⅶ',
  '��' => 'Ⅷ',
  '��' => 'Ⅸ',
  '��' => 'Ⅹ',
  '��' => '〡',
  '��' => '〢',
  '��' => '〣',
  '��' => '〤',
  '��' => '〥',
  '��' => '〦',
  '��' => '〧',
  '��' => '〨',
  '��' => '〩',
  '��' => '�',
  '��' => '卄',
  '��' => '�',
  '��' => 'A',
  '��' => 'B',
  '��' => 'C',
  '��' => 'D',
  '��' => 'E',
  '��' => 'F',
  '��' => 'G',
  '��' => 'H',
  '��' => 'I',
  '��' => 'J',
  '��' => 'K',
  '��' => 'L',
  '��' => 'M',
  '��' => 'N',
  '��' => 'O',
  '��' => 'P',
  '��' => 'Q',
  '��' => 'R',
  '��' => 'S',
  '��' => 'T',
  '��' => 'U',
  '��' => 'V',
  '��' => 'W',
  '��' => 'X',
  '��' => 'Y',
  '��' => 'Z',
  '��' => 'a',
  '��' => 'b',
  '��' => 'c',
  '��' => 'd',
  '��' => 'e',
  '��' => 'f',
  '��' => 'g',
  '��' => 'h',
  '��' => 'i',
  '��' => 'j',
  '��' => 'k',
  '��' => 'l',
  '��' => 'm',
  '��' => 'n',
  '��' => 'o',
  '��' => 'p',
  '��' => 'q',
  '��' => 'r',
  '��' => 's',
  '��' => 't',
  '��' => 'u',
  '��' => 'v',
  '�@' => 'w',
  '�A' => 'x',
  '�B' => 'y',
  '�C' => 'z',
  '�D' => 'Α',
  '�E' => 'Β',
  '�F' => 'Γ',
  '�G' => 'Δ',
  '�H' => 'Ε',
  '�I' => 'Ζ',
  '�J' => 'Η',
  '�K' => 'Θ',
  '�L' => 'Ι',
  '�M' => 'Κ',
  '�N' => 'Λ',
  '�O' => 'Μ',
  '�P' => 'Ν',
  '�Q' => 'Ξ',
  '�R' => 'Ο',
  '�S' => 'Π',
  '�T' => 'Ρ',
  '�U' => 'Σ',
  '�V' => 'Τ',
  '�W' => 'Υ',
  '�X' => 'Φ',
  '�Y' => 'Χ',
  '�Z' => 'Ψ',
  '�[' => 'Ω',
  '�\\' => 'α',
  '�]' => 'β',
  '�^' => 'γ',
  '�_' => 'δ',
  '�`' => 'ε',
  '�a' => 'ζ',
  '�b' => 'η',
  '�c' => 'θ',
  '�d' => 'ι',
  '�e' => 'κ',
  '�f' => 'λ',
  '�g' => 'μ',
  '�h' => 'ν',
  '�i' => 'ξ',
  '�j' => 'ο',
  '�k' => 'π',
  '�l' => 'ρ',
  '�m' => 'σ',
  '�n' => 'τ',
  '�o' => 'υ',
  '�p' => 'φ',
  '�q' => 'χ',
  '�r' => 'ψ',
  '�s' => 'ω',
  '�t' => 'ㄅ',
  '�u' => 'ㄆ',
  '�v' => 'ㄇ',
  '�w' => 'ㄈ',
  '�x' => 'ㄉ',
  '�y' => 'ㄊ',
  '�z' => 'ㄋ',
  '�{' => 'ㄌ',
  '�|' => 'ㄍ',
  '�}' => 'ㄎ',
  '�~' => 'ㄏ',
  '��' => 'ㄐ',
  '��' => 'ㄑ',
  '��' => 'ㄒ',
  '��' => 'ㄓ',
  '��' => 'ㄔ',
  '��' => 'ㄕ',
  '��' => 'ㄖ',
  '��' => 'ㄗ',
  '��' => 'ㄘ',
  '��' => 'ㄙ',
  '��' => 'ㄚ',
  '��' => 'ㄛ',
  '��' => 'ㄜ',
  '��' => 'ㄝ',
  '��' => 'ㄞ',
  '��' => 'ㄟ',
  '��' => 'ㄠ',
  '��' => 'ㄡ',
  '��' => 'ㄢ',
  '��' => 'ㄣ',
  '��' => 'ㄤ',
  '��' => 'ㄥ',
  '��' => 'ㄦ',
  '��' => 'ㄧ',
  '��' => 'ㄨ',
  '��' => 'ㄩ',
  '��' => '˙',
  '��' => 'ˉ',
  '��' => 'ˊ',
  '��' => 'ˇ',
  '��' => 'ˋ',
  '�@' => '一',
  '�A' => '乙',
  '�B' => '丁',
  '�C' => '七',
  '�D' => '乃',
  '�E' => '九',
  '�F' => '了',
  '�G' => '二',
  '�H' => '人',
  '�I' => '儿',
  '�J' => '入',
  '�K' => '八',
  '�L' => '几',
  '�M' => '刀',
  '�N' => '刁',
  '�O' => '力',
  '�P' => '匕',
  '�Q' => '十',
  '�R' => '卜',
  '�S' => '又',
  '�T' => '三',
  '�U' => '下',
  '�V' => '丈',
  '�W' => '上',
  '�X' => '丫',
  '�Y' => '丸',
  '�Z' => '凡',
  '�[' => '久',
  '�\\' => '么',
  '�]' => '也',
  '�^' => '乞',
  '�_' => '于',
  '�`' => '亡',
  '�a' => '兀',
  '�b' => '刃',
  '�c' => '勺',
  '�d' => '千',
  '�e' => '叉',
  '�f' => '口',
  '�g' => '土',
  '�h' => '士',
  '�i' => '夕',
  '�j' => '大',
  '�k' => '女',
  '�l' => '子',
  '�m' => '孑',
  '�n' => '孓',
  '�o' => '寸',
  '�p' => '小',
  '�q' => '尢',
  '�r' => '尸',
  '�s' => '山',
  '�t' => '川',
  '�u' => '工',
  '�v' => '己',
  '�w' => '已',
  '�x' => '巳',
  '�y' => '巾',
  '�z' => '干',
  '�{' => '廾',
  '�|' => '弋',
  '�}' => '弓',
  '�~' => '才',
  '��' => '丑',
  '��' => '丐',
  '��' => '不',
  '��' => '中',
  '��' => '丰',
  '��' => '丹',
  '��' => '之',
  '��' => '尹',
  '��' => '予',
  '��' => '云',
  '��' => '井',
  '��' => '互',
  '��' => '五',
  '��' => '亢',
  '��' => '仁',
  '��' => '什',
  '��' => '仃',
  '��' => '仆',
  '��' => '仇',
  '��' => '仍',
  '��' => '今',
  '��' => '介',
  '��' => '仄',
  '��' => '元',
  '��' => '允',
  '��' => '內',
  '��' => '六',
  '��' => '兮',
  '��' => '公',
  '��' => '冗',
  '��' => '凶',
  '��' => '分',
  '��' => '切',
  '��' => '刈',
  '��' => '勻',
  '��' => '勾',
  '��' => '勿',
  '��' => '化',
  '��' => '匹',
  '��' => '午',
  '��' => '升',
  '��' => '卅',
  '��' => '卞',
  '��' => '厄',
  '��' => '友',
  '��' => '及',
  '��' => '反',
  '��' => '壬',
  '��' => '天',
  '��' => '夫',
  '��' => '太',
  '��' => '夭',
  '��' => '孔',
  '��' => '少',
  '��' => '尤',
  '��' => '尺',
  '��' => '屯',
  '��' => '巴',
  '��' => '幻',
  '��' => '廿',
  '��' => '弔',
  '��' => '引',
  '��' => '心',
  '��' => '戈',
  '��' => '戶',
  '��' => '手',
  '��' => '扎',
  '��' => '支',
  '��' => '文',
  '��' => '斗',
  '��' => '斤',
  '��' => '方',
  '��' => '日',
  '��' => '曰',
  '��' => '月',
  '��' => '木',
  '��' => '欠',
  '��' => '止',
  '��' => '歹',
  '��' => '毋',
  '��' => '比',
  '��' => '毛',
  '��' => '氏',
  '��' => '水',
  '��' => '火',
  '��' => '爪',
  '��' => '父',
  '��' => '爻',
  '��' => '片',
  '��' => '牙',
  '��' => '牛',
  '��' => '犬',
  '��' => '王',
  '��' => '丙',
  '�@' => '世',
  '�A' => '丕',
  '�B' => '且',
  '�C' => '丘',
  '�D' => '主',
  '�E' => '乍',
  '�F' => '乏',
  '�G' => '乎',
  '�H' => '以',
  '�I' => '付',
  '�J' => '仔',
  '�K' => '仕',
  '�L' => '他',
  '�M' => '仗',
  '�N' => '代',
  '�O' => '令',
  '�P' => '仙',
  '�Q' => '仞',
  '�R' => '充',
  '�S' => '兄',
  '�T' => '冉',
  '�U' => '冊',
  '�V' => '冬',
  '�W' => '凹',
  '�X' => '出',
  '�Y' => '凸',
  '�Z' => '刊',
  '�[' => '加',
  '�\\' => '功',
  '�]' => '包',
  '�^' => '匆',
  '�_' => '北',
  '�`' => '匝',
  '�a' => '仟',
  '�b' => '半',
  '�c' => '卉',
  '�d' => '卡',
  '�e' => '占',
  '�f' => '卯',
  '�g' => '卮',
  '�h' => '去',
  '�i' => '可',
  '�j' => '古',
  '�k' => '右',
  '�l' => '召',
  '�m' => '叮',
  '�n' => '叩',
  '�o' => '叨',
  '�p' => '叼',
  '�q' => '司',
  '�r' => '叵',
  '�s' => '叫',
  '�t' => '另',
  '�u' => '只',
  '�v' => '史',
  '�w' => '叱',
  '�x' => '台',
  '�y' => '句',
  '�z' => '叭',
  '�{' => '叻',
  '�|' => '四',
  '�}' => '囚',
  '�~' => '外',
  '��' => '央',
  '��' => '失',
  '��' => '奴',
  '��' => '奶',
  '��' => '孕',
  '��' => '它',
  '��' => '尼',
  '��' => '巨',
  '��' => '巧',
  '��' => '左',
  '��' => '市',
  '��' => '布',
  '��' => '平',
  '��' => '幼',
  '��' => '弁',
  '��' => '弘',
  '��' => '弗',
  '��' => '必',
  '��' => '戊',
  '��' => '打',
  '��' => '扔',
  '��' => '扒',
  '��' => '扑',
  '��' => '斥',
  '��' => '旦',
  '��' => '朮',
  '��' => '本',
  '��' => '未',
  '��' => '末',
  '��' => '札',
  '��' => '正',
  '��' => '母',
  '��' => '民',
  '��' => '氐',
  '��' => '永',
  '��' => '汁',
  '��' => '汀',
  '��' => '氾',
  '��' => '犯',
  '��' => '玄',
  '��' => '玉',
  '��' => '瓜',
  '��' => '瓦',
  '��' => '甘',
  '��' => '生',
  '��' => '用',
  '��' => '甩',
  '��' => '田',
  '��' => '由',
  '��' => '甲',
  '��' => '申',
  '��' => '疋',
  '��' => '白',
  '��' => '皮',
  '��' => '皿',
  '��' => '目',
  '��' => '矛',
  '��' => '矢',
  '��' => '石',
  '��' => '示',
  '��' => '禾',
  '��' => '穴',
  '��' => '立',
  '��' => '丞',
  '��' => '丟',
  '��' => '乒',
  '��' => '乓',
  '��' => '乩',
  '��' => '亙',
  '��' => '交',
  '��' => '亦',
  '��' => '亥',
  '��' => '仿',
  '��' => '伉',
  '��' => '伙',
  '��' => '伊',
  '��' => '伕',
  '��' => '伍',
  '��' => '伐',
  '��' => '休',
  '��' => '伏',
  '��' => '仲',
  '��' => '件',
  '��' => '任',
  '��' => '仰',
  '��' => '仳',
  '��' => '份',
  '��' => '企',
  '��' => '伋',
  '��' => '光',
  '��' => '兇',
  '��' => '兆',
  '��' => '先',
  '��' => '全',
  '�@' => '共',
  '�A' => '再',
  '�B' => '冰',
  '�C' => '列',
  '�D' => '刑',
  '�E' => '划',
  '�F' => '刎',
  '�G' => '刖',
  '�H' => '劣',
  '�I' => '匈',
  '�J' => '匡',
  '�K' => '匠',
  '�L' => '印',
  '�M' => '危',
  '�N' => '吉',
  '�O' => '吏',
  '�P' => '同',
  '�Q' => '吊',
  '�R' => '吐',
  '�S' => '吁',
  '�T' => '吋',
  '�U' => '各',
  '�V' => '向',
  '�W' => '名',
  '�X' => '合',
  '�Y' => '吃',
  '�Z' => '后',
  '�[' => '吆',
  '�\\' => '吒',
  '�]' => '因',
  '�^' => '回',
  '�_' => '囝',
  '�`' => '圳',
  '�a' => '地',
  '�b' => '在',
  '�c' => '圭',
  '�d' => '圬',
  '�e' => '圯',
  '�f' => '圩',
  '�g' => '夙',
  '�h' => '多',
  '�i' => '夷',
  '�j' => '夸',
  '�k' => '妄',
  '�l' => '奸',
  '�m' => '妃',
  '�n' => '好',
  '�o' => '她',
  '�p' => '如',
  '�q' => '妁',
  '�r' => '字',
  '�s' => '存',
  '�t' => '宇',
  '�u' => '守',
  '�v' => '宅',
  '�w' => '安',
  '�x' => '寺',
  '�y' => '尖',
  '�z' => '屹',
  '�{' => '州',
  '�|' => '帆',
  '�}' => '并',
  '�~' => '年',
  '��' => '式',
  '��' => '弛',
  '��' => '忙',
  '��' => '忖',
  '��' => '戎',
  '��' => '戌',
  '��' => '戍',
  '��' => '成',
  '��' => '扣',
  '��' => '扛',
  '��' => '托',
  '��' => '收',
  '��' => '早',
  '��' => '旨',
  '��' => '旬',
  '��' => '旭',
  '��' => '曲',
  '��' => '曳',
  '��' => '有',
  '��' => '朽',
  '��' => '朴',
  '��' => '朱',
  '��' => '朵',
  '��' => '次',
  '��' => '此',
  '��' => '死',
  '��' => '氖',
  '��' => '汝',
  '��' => '汗',
  '��' => '汙',
  '��' => '江',
  '��' => '池',
  '��' => '汐',
  '��' => '汕',
  '��' => '污',
  '��' => '汛',
  '��' => '汍',
  '��' => '汎',
  '��' => '灰',
  '��' => '牟',
  '��' => '牝',
  '��' => '百',
  '��' => '竹',
  '��' => '米',
  '��' => '糸',
  '��' => '缶',
  '��' => '羊',
  '��' => '羽',
  '��' => '老',
  '��' => '考',
  '��' => '而',
  '��' => '耒',
  '��' => '耳',
  '��' => '聿',
  '��' => '肉',
  '��' => '肋',
  '��' => '肌',
  '��' => '臣',
  '��' => '自',
  '��' => '至',
  '��' => '臼',
  '��' => '舌',
  '��' => '舛',
  '��' => '舟',
  '��' => '艮',
  '��' => '色',
  '��' => '艾',
  '��' => '虫',
  '��' => '血',
  '��' => '行',
  '��' => '衣',
  '��' => '西',
  '��' => '阡',
  '��' => '串',
  '��' => '亨',
  '��' => '位',
  '��' => '住',
  '��' => '佇',
  '��' => '佗',
  '��' => '佞',
  '��' => '伴',
  '��' => '佛',
  '��' => '何',
  '��' => '估',
  '��' => '佐',
  '��' => '佑',
  '��' => '伽',
  '��' => '伺',
  '��' => '伸',
  '��' => '佃',
  '��' => '佔',
  '��' => '似',
  '��' => '但',
  '��' => '佣',
  '�@' => '作',
  '�A' => '你',
  '�B' => '伯',
  '�C' => '低',
  '�D' => '伶',
  '�E' => '余',
  '�F' => '佝',
  '�G' => '佈',
  '�H' => '佚',
  '�I' => '兌',
  '�J' => '克',
  '�K' => '免',
  '�L' => '兵',
  '�M' => '冶',
  '�N' => '冷',
  '�O' => '別',
  '�P' => '判',
  '�Q' => '利',
  '�R' => '刪',
  '�S' => '刨',
  '�T' => '劫',
  '�U' => '助',
  '�V' => '努',
  '�W' => '劬',
  '�X' => '匣',
  '�Y' => '即',
  '�Z' => '卵',
  '�[' => '吝',
  '�\\' => '吭',
  '�]' => '吞',
  '�^' => '吾',
  '�_' => '否',
  '�`' => '呎',
  '�a' => '吧',
  '�b' => '呆',
  '�c' => '呃',
  '�d' => '吳',
  '�e' => '呈',
  '�f' => '呂',
  '�g' => '君',
  '�h' => '吩',
  '�i' => '告',
  '�j' => '吹',
  '�k' => '吻',
  '�l' => '吸',
  '�m' => '吮',
  '�n' => '吵',
  '�o' => '吶',
  '�p' => '吠',
  '�q' => '吼',
  '�r' => '呀',
  '�s' => '吱',
  '�t' => '含',
  '�u' => '吟',
  '�v' => '听',
  '�w' => '囪',
  '�x' => '困',
  '�y' => '囤',
  '�z' => '囫',
  '�{' => '坊',
  '�|' => '坑',
  '�}' => '址',
  '�~' => '坍',
  '��' => '均',
  '��' => '坎',
  '��' => '圾',
  '��' => '坐',
  '��' => '坏',
  '��' => '圻',
  '��' => '壯',
  '��' => '夾',
  '��' => '妝',
  '��' => '妒',
  '��' => '妨',
  '��' => '妞',
  '��' => '妣',
  '��' => '妙',
  '��' => '妖',
  '��' => '妍',
  '��' => '妤',
  '��' => '妓',
  '��' => '妊',
  '��' => '妥',
  '��' => '孝',
  '��' => '孜',
  '��' => '孚',
  '��' => '孛',
  '��' => '完',
  '��' => '宋',
  '��' => '宏',
  '��' => '尬',
  '��' => '局',
  '��' => '屁',
  '��' => '尿',
  '��' => '尾',
  '��' => '岐',
  '��' => '岑',
  '��' => '岔',
  '��' => '岌',
  '��' => '巫',
  '��' => '希',
  '��' => '序',
  '��' => '庇',
  '��' => '床',
  '��' => '廷',
  '��' => '弄',
  '��' => '弟',
  '��' => '彤',
  '��' => '形',
  '��' => '彷',
  '��' => '役',
  '��' => '忘',
  '��' => '忌',
  '��' => '志',
  '��' => '忍',
  '��' => '忱',
  '��' => '快',
  '��' => '忸',
  '��' => '忪',
  '��' => '戒',
  '��' => '我',
  '��' => '抄',
  '��' => '抗',
  '��' => '抖',
  '��' => '技',
  '��' => '扶',
  '��' => '抉',
  '��' => '扭',
  '��' => '把',
  '��' => '扼',
  '��' => '找',
  '��' => '批',
  '��' => '扳',
  '��' => '抒',
  '��' => '扯',
  '��' => '折',
  '��' => '扮',
  '��' => '投',
  '��' => '抓',
  '��' => '抑',
  '��' => '抆',
  '��' => '改',
  '��' => '攻',
  '��' => '攸',
  '��' => '旱',
  '��' => '更',
  '��' => '束',
  '��' => '李',
  '��' => '杏',
  '��' => '材',
  '��' => '村',
  '��' => '杜',
  '��' => '杖',
  '��' => '杞',
  '��' => '杉',
  '��' => '杆',
  '��' => '杠',
  '�@' => '杓',
  '�A' => '杗',
  '�B' => '步',
  '�C' => '每',
  '�D' => '求',
  '�E' => '汞',
  '�F' => '沙',
  '�G' => '沁',
  '�H' => '沈',
  '�I' => '沉',
  '�J' => '沅',
  '�K' => '沛',
  '�L' => '汪',
  '�M' => '決',
  '�N' => '沐',
  '�O' => '汰',
  '�P' => '沌',
  '�Q' => '汨',
  '�R' => '沖',
  '�S' => '沒',
  '�T' => '汽',
  '�U' => '沃',
  '�V' => '汲',
  '�W' => '汾',
  '�X' => '汴',
  '�Y' => '沆',
  '�Z' => '汶',
  '�[' => '沍',
  '�\\' => '沔',
  '�]' => '沘',
  '�^' => '沂',
  '�_' => '灶',
  '�`' => '灼',
  '�a' => '災',
  '�b' => '灸',
  '�c' => '牢',
  '�d' => '牡',
  '�e' => '牠',
  '�f' => '狄',
  '�g' => '狂',
  '�h' => '玖',
  '�i' => '甬',
  '�j' => '甫',
  '�k' => '男',
  '�l' => '甸',
  '�m' => '皂',
  '�n' => '盯',
  '�o' => '矣',
  '�p' => '私',
  '�q' => '秀',
  '�r' => '禿',
  '�s' => '究',
  '�t' => '系',
  '�u' => '罕',
  '�v' => '肖',
  '�w' => '肓',
  '�x' => '肝',
  '�y' => '肘',
  '�z' => '肛',
  '�{' => '肚',
  '�|' => '育',
  '�}' => '良',
  '�~' => '芒',
  '��' => '芋',
  '��' => '芍',
  '��' => '見',
  '��' => '角',
  '��' => '言',
  '��' => '谷',
  '��' => '豆',
  '��' => '豕',
  '��' => '貝',
  '��' => '赤',
  '��' => '走',
  '��' => '足',
  '��' => '身',
  '��' => '車',
  '��' => '辛',
  '��' => '辰',
  '��' => '迂',
  '��' => '迆',
  '��' => '迅',
  '��' => '迄',
  '��' => '巡',
  '��' => '邑',
  '��' => '邢',
  '��' => '邪',
  '��' => '邦',
  '��' => '那',
  '��' => '酉',
  '��' => '釆',
  '��' => '里',
  '��' => '防',
  '��' => '阮',
  '��' => '阱',
  '��' => '阪',
  '��' => '阬',
  '��' => '並',
  '��' => '乖',
  '��' => '乳',
  '��' => '事',
  '��' => '些',
  '��' => '亞',
  '��' => '享',
  '��' => '京',
  '��' => '佯',
  '��' => '依',
  '��' => '侍',
  '��' => '佳',
  '��' => '使',
  '��' => '佬',
  '��' => '供',
  '��' => '例',
  '��' => '來',
  '��' => '侃',
  '��' => '佰',
  '��' => '併',
  '��' => '侈',
  '��' => '佩',
  '��' => '佻',
  '��' => '侖',
  '��' => '佾',
  '��' => '侏',
  '��' => '侑',
  '��' => '佺',
  '��' => '兔',
  '��' => '兒',
  '��' => '兕',
  '��' => '兩',
  '��' => '具',
  '��' => '其',
  '��' => '典',
  '��' => '冽',
  '��' => '函',
  '��' => '刻',
  '��' => '券',
  '��' => '刷',
  '��' => '刺',
  '��' => '到',
  '��' => '刮',
  '��' => '制',
  '��' => '剁',
  '��' => '劾',
  '��' => '劻',
  '��' => '卒',
  '��' => '協',
  '��' => '卓',
  '��' => '卑',
  '��' => '卦',
  '��' => '卷',
  '��' => '卸',
  '��' => '卹',
  '��' => '取',
  '��' => '叔',
  '��' => '受',
  '��' => '味',
  '��' => '呵',
  '�@' => '咖',
  '�A' => '呸',
  '�B' => '咕',
  '�C' => '咀',
  '�D' => '呻',
  '�E' => '呷',
  '�F' => '咄',
  '�G' => '咒',
  '�H' => '咆',
  '�I' => '呼',
  '�J' => '咐',
  '�K' => '呱',
  '�L' => '呶',
  '�M' => '和',
  '�N' => '咚',
  '�O' => '呢',
  '�P' => '周',
  '�Q' => '咋',
  '�R' => '命',
  '�S' => '咎',
  '�T' => '固',
  '�U' => '垃',
  '�V' => '坷',
  '�W' => '坪',
  '�X' => '坩',
  '�Y' => '坡',
  '�Z' => '坦',
  '�[' => '坤',
  '�\\' => '坼',
  '�]' => '夜',
  '�^' => '奉',
  '�_' => '奇',
  '�`' => '奈',
  '�a' => '奄',
  '�b' => '奔',
  '�c' => '妾',
  '�d' => '妻',
  '�e' => '委',
  '�f' => '妹',
  '�g' => '妮',
  '�h' => '姑',
  '�i' => '姆',
  '�j' => '姐',
  '�k' => '姍',
  '�l' => '始',
  '�m' => '姓',
  '�n' => '姊',
  '�o' => '妯',
  '�p' => '妳',
  '�q' => '姒',
  '�r' => '姅',
  '�s' => '孟',
  '�t' => '孤',
  '�u' => '季',
  '�v' => '宗',
  '�w' => '定',
  '�x' => '官',
  '�y' => '宜',
  '�z' => '宙',
  '�{' => '宛',
  '�|' => '尚',
  '�}' => '屈',
  '�~' => '居',
  '��' => '屆',
  '��' => '岷',
  '��' => '岡',
  '��' => '岸',
  '��' => '岩',
  '��' => '岫',
  '��' => '岱',
  '��' => '岳',
  '��' => '帘',
  '��' => '帚',
  '��' => '帖',
  '��' => '帕',
  '��' => '帛',
  '��' => '帑',
  '��' => '幸',
  '��' => '庚',
  '��' => '店',
  '��' => '府',
  '��' => '底',
  '��' => '庖',
  '��' => '延',
  '��' => '弦',
  '��' => '弧',
  '��' => '弩',
  '��' => '往',
  '��' => '征',
  '��' => '彿',
  '��' => '彼',
  '��' => '忝',
  '��' => '忠',
  '��' => '忽',
  '��' => '念',
  '��' => '忿',
  '��' => '怏',
  '��' => '怔',
  '��' => '怯',
  '��' => '怵',
  '��' => '怖',
  '��' => '怪',
  '��' => '怕',
  '��' => '怡',
  '��' => '性',
  '��' => '怩',
  '��' => '怫',
  '��' => '怛',
  '��' => '或',
  '��' => '戕',
  '��' => '房',
  '��' => '戾',
  '��' => '所',
  '��' => '承',
  '��' => '拉',
  '��' => '拌',
  '��' => '拄',
  '��' => '抿',
  '��' => '拂',
  '��' => '抹',
  '��' => '拒',
  '��' => '招',
  '��' => '披',
  '��' => '拓',
  '��' => '拔',
  '��' => '拋',
  '��' => '拈',
  '��' => '抨',
  '��' => '抽',
  '��' => '押',
  '��' => '拐',
  '��' => '拙',
  '��' => '拇',
  '��' => '拍',
  '��' => '抵',
  '��' => '拚',
  '��' => '抱',
  '��' => '拘',
  '��' => '拖',
  '��' => '拗',
  '��' => '拆',
  '��' => '抬',
  '��' => '拎',
  '��' => '放',
  '��' => '斧',
  '��' => '於',
  '��' => '旺',
  '��' => '昔',
  '��' => '易',
  '��' => '昌',
  '��' => '昆',
  '��' => '昂',
  '��' => '明',
  '��' => '昀',
  '��' => '昏',
  '��' => '昕',
  '��' => '昊',
  '�@' => '昇',
  '�A' => '服',
  '�B' => '朋',
  '�C' => '杭',
  '�D' => '枋',
  '�E' => '枕',
  '�F' => '東',
  '�G' => '果',
  '�H' => '杳',
  '�I' => '杷',
  '�J' => '枇',
  '�K' => '枝',
  '�L' => '林',
  '�M' => '杯',
  '�N' => '杰',
  '�O' => '板',
  '�P' => '枉',
  '�Q' => '松',
  '�R' => '析',
  '�S' => '杵',
  '�T' => '枚',
  '�U' => '枓',
  '�V' => '杼',
  '�W' => '杪',
  '�X' => '杲',
  '�Y' => '欣',
  '�Z' => '武',
  '�[' => '歧',
  '�\\' => '歿',
  '�]' => '氓',
  '�^' => '氛',
  '�_' => '泣',
  '�`' => '注',
  '�a' => '泳',
  '�b' => '沱',
  '�c' => '泌',
  '�d' => '泥',
  '�e' => '河',
  '�f' => '沽',
  '�g' => '沾',
  '�h' => '沼',
  '�i' => '波',
  '�j' => '沫',
  '�k' => '法',
  '�l' => '泓',
  '�m' => '沸',
  '�n' => '泄',
  '�o' => '油',
  '�p' => '況',
  '�q' => '沮',
  '�r' => '泗',
  '�s' => '泅',
  '�t' => '泱',
  '�u' => '沿',
  '�v' => '治',
  '�w' => '泡',
  '�x' => '泛',
  '�y' => '泊',
  '�z' => '沬',
  '�{' => '泯',
  '�|' => '泜',
  '�}' => '泖',
  '�~' => '泠',
  '��' => '炕',
  '��' => '炎',
  '��' => '炒',
  '��' => '炊',
  '��' => '炙',
  '��' => '爬',
  '��' => '爭',
  '��' => '爸',
  '��' => '版',
  '��' => '牧',
  '��' => '物',
  '��' => '狀',
  '��' => '狎',
  '��' => '狙',
  '��' => '狗',
  '��' => '狐',
  '��' => '玩',
  '��' => '玨',
  '��' => '玟',
  '��' => '玫',
  '��' => '玥',
  '��' => '甽',
  '��' => '疝',
  '��' => '疙',
  '��' => '疚',
  '��' => '的',
  '��' => '盂',
  '��' => '盲',
  '��' => '直',
  '��' => '知',
  '��' => '矽',
  '��' => '社',
  '��' => '祀',
  '��' => '祁',
  '��' => '秉',
  '��' => '秈',
  '��' => '空',
  '��' => '穹',
  '��' => '竺',
  '��' => '糾',
  '��' => '罔',
  '��' => '羌',
  '��' => '羋',
  '��' => '者',
  '��' => '肺',
  '��' => '肥',
  '��' => '肢',
  '��' => '肱',
  '��' => '股',
  '��' => '肫',
  '��' => '肩',
  '��' => '肴',
  '��' => '肪',
  '��' => '肯',
  '��' => '臥',
  '��' => '臾',
  '��' => '舍',
  '��' => '芳',
  '��' => '芝',
  '��' => '芙',
  '��' => '芭',
  '��' => '芽',
  '��' => '芟',
  '��' => '芹',
  '��' => '花',
  '��' => '芬',
  '��' => '芥',
  '��' => '芯',
  '��' => '芸',
  '��' => '芣',
  '��' => '芰',
  '��' => '芾',
  '��' => '芷',
  '��' => '虎',
  '��' => '虱',
  '��' => '初',
  '��' => '表',
  '��' => '軋',
  '��' => '迎',
  '��' => '返',
  '��' => '近',
  '��' => '邵',
  '��' => '邸',
  '��' => '邱',
  '��' => '邶',
  '��' => '采',
  '��' => '金',
  '��' => '長',
  '��' => '門',
  '��' => '阜',
  '��' => '陀',
  '��' => '阿',
  '��' => '阻',
  '��' => '附',
  '�@' => '陂',
  '�A' => '隹',
  '�B' => '雨',
  '�C' => '青',
  '�D' => '非',
  '�E' => '亟',
  '�F' => '亭',
  '�G' => '亮',
  '�H' => '信',
  '�I' => '侵',
  '�J' => '侯',
  '�K' => '便',
  '�L' => '俠',
  '�M' => '俑',
  '�N' => '俏',
  '�O' => '保',
  '�P' => '促',
  '�Q' => '侶',
  '�R' => '俘',
  '�S' => '俟',
  '�T' => '俊',
  '�U' => '俗',
  '�V' => '侮',
  '�W' => '俐',
  '�X' => '俄',
  '�Y' => '係',
  '�Z' => '俚',
  '�[' => '俎',
  '�\\' => '俞',
  '�]' => '侷',
  '�^' => '兗',
  '�_' => '冒',
  '�`' => '冑',
  '�a' => '冠',
  '�b' => '剎',
  '�c' => '剃',
  '�d' => '削',
  '�e' => '前',
  '�f' => '剌',
  '�g' => '剋',
  '�h' => '則',
  '�i' => '勇',
  '�j' => '勉',
  '�k' => '勃',
  '�l' => '勁',
  '�m' => '匍',
  '�n' => '南',
  '�o' => '卻',
  '�p' => '厚',
  '�q' => '叛',
  '�r' => '咬',
  '�s' => '哀',
  '�t' => '咨',
  '�u' => '哎',
  '�v' => '哉',
  '�w' => '咸',
  '�x' => '咦',
  '�y' => '咳',
  '�z' => '哇',
  '�{' => '哂',
  '�|' => '咽',
  '�}' => '咪',
  '�~' => '品',
  '��' => '哄',
  '��' => '哈',
  '��' => '咯',
  '��' => '咫',
  '��' => '咱',
  '��' => '咻',
  '��' => '咩',
  '��' => '咧',
  '��' => '咿',
  '��' => '囿',
  '��' => '垂',
  '��' => '型',
  '��' => '垠',
  '��' => '垣',
  '��' => '垢',
  '��' => '城',
  '��' => '垮',
  '��' => '垓',
  '��' => '奕',
  '��' => '契',
  '��' => '奏',
  '��' => '奎',
  '��' => '奐',
  '��' => '姜',
  '��' => '姘',
  '��' => '姿',
  '��' => '姣',
  '��' => '姨',
  '��' => '娃',
  '��' => '姥',
  '��' => '姪',
  '��' => '姚',
  '��' => '姦',
  '��' => '威',
  '��' => '姻',
  '��' => '孩',
  '��' => '宣',
  '��' => '宦',
  '��' => '室',
  '��' => '客',
  '��' => '宥',
  '��' => '封',
  '��' => '屎',
  '��' => '屏',
  '��' => '屍',
  '��' => '屋',
  '��' => '峙',
  '��' => '峒',
  '��' => '巷',
  '��' => '帝',
  '��' => '帥',
  '��' => '帟',
  '��' => '幽',
  '��' => '庠',
  '��' => '度',
  '��' => '建',
  '��' => '弈',
  '��' => '弭',
  '��' => '彥',
  '��' => '很',
  '��' => '待',
  '��' => '徊',
  '��' => '律',
  '��' => '徇',
  '��' => '後',
  '��' => '徉',
  '��' => '怒',
  '��' => '思',
  '��' => '怠',
  '��' => '急',
  '��' => '怎',
  '��' => '怨',
  '��' => '恍',
  '��' => '恰',
  '��' => '恨',
  '��' => '恢',
  '��' => '恆',
  '��' => '恃',
  '��' => '恬',
  '��' => '恫',
  '��' => '恪',
  '��' => '恤',
  '��' => '扁',
  '��' => '拜',
  '��' => '挖',
  '��' => '按',
  '��' => '拼',
  '��' => '拭',
  '��' => '持',
  '��' => '拮',
  '��' => '拽',
  '��' => '指',
  '��' => '拱',
  '��' => '拷',
  '�@' => '拯',
  '�A' => '括',
  '�B' => '拾',
  '�C' => '拴',
  '�D' => '挑',
  '�E' => '挂',
  '�F' => '政',
  '�G' => '故',
  '�H' => '斫',
  '�I' => '施',
  '�J' => '既',
  '�K' => '春',
  '�L' => '昭',
  '�M' => '映',
  '�N' => '昧',
  '�O' => '是',
  '�P' => '星',
  '�Q' => '昨',
  '�R' => '昱',
  '�S' => '昤',
  '�T' => '曷',
  '�U' => '柿',
  '�V' => '染',
  '�W' => '柱',
  '�X' => '柔',
  '�Y' => '某',
  '�Z' => '柬',
  '�[' => '架',
  '�\\' => '枯',
  '�]' => '柵',
  '�^' => '柩',
  '�_' => '柯',
  '�`' => '柄',
  '�a' => '柑',
  '�b' => '枴',
  '�c' => '柚',
  '�d' => '查',
  '�e' => '枸',
  '�f' => '柏',
  '�g' => '柞',
  '�h' => '柳',
  '�i' => '枰',
  '�j' => '柙',
  '�k' => '柢',
  '�l' => '柝',
  '�m' => '柒',
  '�n' => '歪',
  '�o' => '殃',
  '�p' => '殆',
  '�q' => '段',
  '�r' => '毒',
  '�s' => '毗',
  '�t' => '氟',
  '�u' => '泉',
  '�v' => '洋',
  '�w' => '洲',
  '�x' => '洪',
  '�y' => '流',
  '�z' => '津',
  '�{' => '洌',
  '�|' => '洱',
  '�}' => '洞',
  '�~' => '洗',
  '��' => '活',
  '��' => '洽',
  '��' => '派',
  '��' => '洶',
  '��' => '洛',
  '��' => '泵',
  '��' => '洹',
  '��' => '洧',
  '��' => '洸',
  '��' => '洩',
  '��' => '洮',
  '��' => '洵',
  '��' => '洎',
  '��' => '洫',
  '��' => '炫',
  '��' => '為',
  '��' => '炳',
  '��' => '炬',
  '��' => '炯',
  '��' => '炭',
  '��' => '炸',
  '��' => '炮',
  '��' => '炤',
  '��' => '爰',
  '��' => '牲',
  '��' => '牯',
  '��' => '牴',
  '��' => '狩',
  '��' => '狠',
  '��' => '狡',
  '��' => '玷',
  '��' => '珊',
  '��' => '玻',
  '��' => '玲',
  '��' => '珍',
  '��' => '珀',
  '��' => '玳',
  '��' => '甚',
  '��' => '甭',
  '��' => '畏',
  '��' => '界',
  '��' => '畎',
  '��' => '畋',
  '��' => '疫',
  '��' => '疤',
  '��' => '疥',
  '��' => '疢',
  '��' => '疣',
  '��' => '癸',
  '��' => '皆',
  '��' => '皇',
  '��' => '皈',
  '��' => '盈',
  '��' => '盆',
  '��' => '盃',
  '��' => '盅',
  '��' => '省',
  '��' => '盹',
  '��' => '相',
  '��' => '眉',
  '��' => '看',
  '��' => '盾',
  '��' => '盼',
  '��' => '眇',
  '��' => '矜',
  '��' => '砂',
  '��' => '研',
  '��' => '砌',
  '��' => '砍',
  '��' => '祆',
  '��' => '祉',
  '��' => '祈',
  '��' => '祇',
  '��' => '禹',
  '��' => '禺',
  '��' => '科',
  '��' => '秒',
  '��' => '秋',
  '��' => '穿',
  '��' => '突',
  '��' => '竿',
  '��' => '竽',
  '��' => '籽',
  '��' => '紂',
  '��' => '紅',
  '��' => '紀',
  '��' => '紉',
  '��' => '紇',
  '��' => '約',
  '��' => '紆',
  '��' => '缸',
  '��' => '美',
  '��' => '羿',
  '��' => '耄',
  '�@' => '耐',
  '�A' => '耍',
  '�B' => '耑',
  '�C' => '耶',
  '�D' => '胖',
  '�E' => '胥',
  '�F' => '胚',
  '�G' => '胃',
  '�H' => '胄',
  '�I' => '背',
  '�J' => '胡',
  '�K' => '胛',
  '�L' => '胎',
  '�M' => '胞',
  '�N' => '胤',
  '�O' => '胝',
  '�P' => '致',
  '�Q' => '舢',
  '�R' => '苧',
  '�S' => '范',
  '�T' => '茅',
  '�U' => '苣',
  '�V' => '苛',
  '�W' => '苦',
  '�X' => '茄',
  '�Y' => '若',
  '�Z' => '茂',
  '�[' => '茉',
  '�\\' => '苒',
  '�]' => '苗',
  '�^' => '英',
  '�_' => '茁',
  '�`' => '苜',
  '�a' => '苔',
  '�b' => '苑',
  '�c' => '苞',
  '�d' => '苓',
  '�e' => '苟',
  '�f' => '苯',
  '�g' => '茆',
  '�h' => '虐',
  '�i' => '虹',
  '�j' => '虻',
  '�k' => '虺',
  '�l' => '衍',
  '�m' => '衫',
  '�n' => '要',
  '�o' => '觔',
  '�p' => '計',
  '�q' => '訂',
  '�r' => '訃',
  '�s' => '貞',
  '�t' => '負',
  '�u' => '赴',
  '�v' => '赳',
  '�w' => '趴',
  '�x' => '軍',
  '�y' => '軌',
  '�z' => '述',
  '�{' => '迦',
  '�|' => '迢',
  '�}' => '迪',
  '�~' => '迥',
  '��' => '迭',
  '��' => '迫',
  '��' => '迤',
  '��' => '迨',
  '��' => '郊',
  '��' => '郎',
  '��' => '郁',
  '��' => '郃',
  '��' => '酋',
  '��' => '酊',
  '��' => '重',
  '��' => '閂',
  '��' => '限',
  '��' => '陋',
  '��' => '陌',
  '��' => '降',
  '��' => '面',
  '��' => '革',
  '��' => '韋',
  '��' => '韭',
  '��' => '音',
  '��' => '頁',
  '��' => '風',
  '��' => '飛',
  '��' => '食',
  '��' => '首',
  '��' => '香',
  '��' => '乘',
  '��' => '亳',
  '��' => '倌',
  '��' => '倍',
  '��' => '倣',
  '��' => '俯',
  '��' => '倦',
  '��' => '倥',
  '��' => '俸',
  '��' => '倩',
  '��' => '倖',
  '��' => '倆',
  '��' => '值',
  '��' => '借',
  '��' => '倚',
  '��' => '倒',
  '��' => '們',
  '��' => '俺',
  '��' => '倀',
  '��' => '倔',
  '��' => '倨',
  '��' => '俱',
  '��' => '倡',
  '��' => '個',
  '��' => '候',
  '��' => '倘',
  '��' => '俳',
  '��' => '修',
  '��' => '倭',
  '��' => '倪',
  '��' => '俾',
  '��' => '倫',
  '��' => '倉',
  '��' => '兼',
  '��' => '冤',
  '��' => '冥',
  '��' => '冢',
  '��' => '凍',
  '��' => '凌',
  '��' => '准',
  '��' => '凋',
  '��' => '剖',
  '��' => '剜',
  '��' => '剔',
  '��' => '剛',
  '��' => '剝',
  '��' => '匪',
  '��' => '卿',
  '��' => '原',
  '��' => '厝',
  '��' => '叟',
  '��' => '哨',
  '��' => '唐',
  '��' => '唁',
  '��' => '唷',
  '��' => '哼',
  '��' => '哥',
  '��' => '哲',
  '��' => '唆',
  '��' => '哺',
  '��' => '唔',
  '��' => '哩',
  '��' => '哭',
  '��' => '員',
  '��' => '唉',
  '��' => '哮',
  '��' => '哪',
  '�@' => '哦',
  '�A' => '唧',
  '�B' => '唇',
  '�C' => '哽',
  '�D' => '唏',
  '�E' => '圃',
  '�F' => '圄',
  '�G' => '埂',
  '�H' => '埔',
  '�I' => '埋',
  '�J' => '埃',
  '�K' => '堉',
  '�L' => '夏',
  '�M' => '套',
  '�N' => '奘',
  '�O' => '奚',
  '�P' => '娑',
  '�Q' => '娘',
  '�R' => '娜',
  '�S' => '娟',
  '�T' => '娛',
  '�U' => '娓',
  '�V' => '姬',
  '�W' => '娠',
  '�X' => '娣',
  '�Y' => '娩',
  '�Z' => '娥',
  '�[' => '娌',
  '�\\' => '娉',
  '�]' => '孫',
  '�^' => '屘',
  '�_' => '宰',
  '�`' => '害',
  '�a' => '家',
  '�b' => '宴',
  '�c' => '宮',
  '�d' => '宵',
  '�e' => '容',
  '�f' => '宸',
  '�g' => '射',
  '�h' => '屑',
  '�i' => '展',
  '�j' => '屐',
  '�k' => '峭',
  '�l' => '峽',
  '�m' => '峻',
  '�n' => '峪',
  '�o' => '峨',
  '�p' => '峰',
  '�q' => '島',
  '�r' => '崁',
  '�s' => '峴',
  '�t' => '差',
  '�u' => '席',
  '�v' => '師',
  '�w' => '庫',
  '�x' => '庭',
  '�y' => '座',
  '�z' => '弱',
  '�{' => '徒',
  '�|' => '徑',
  '�}' => '徐',
  '�~' => '恙',
  '��' => '恣',
  '��' => '恥',
  '��' => '恐',
  '��' => '恕',
  '��' => '恭',
  '��' => '恩',
  '��' => '息',
  '��' => '悄',
  '��' => '悟',
  '��' => '悚',
  '��' => '悍',
  '��' => '悔',
  '��' => '悌',
  '��' => '悅',
  '��' => '悖',
  '��' => '扇',
  '��' => '拳',
  '��' => '挈',
  '��' => '拿',
  '��' => '捎',
  '��' => '挾',
  '��' => '振',
  '��' => '捕',
  '��' => '捂',
  '��' => '捆',
  '��' => '捏',
  '��' => '捉',
  '��' => '挺',
  '��' => '捐',
  '��' => '挽',
  '��' => '挪',
  '��' => '挫',
  '��' => '挨',
  '��' => '捍',
  '��' => '捌',
  '��' => '效',
  '��' => '敉',
  '��' => '料',
  '��' => '旁',
  '��' => '旅',
  '��' => '時',
  '��' => '晉',
  '��' => '晏',
  '��' => '晃',
  '��' => '晒',
  '��' => '晌',
  '��' => '晅',
  '��' => '晁',
  '��' => '書',
  '��' => '朔',
  '��' => '朕',
  '��' => '朗',
  '��' => '校',
  '��' => '核',
  '��' => '案',
  '��' => '框',
  '��' => '桓',
  '��' => '根',
  '��' => '桂',
  '��' => '桔',
  '��' => '栩',
  '��' => '梳',
  '��' => '栗',
  '��' => '桌',
  '��' => '桑',
  '��' => '栽',
  '��' => '柴',
  '��' => '桐',
  '��' => '桀',
  '��' => '格',
  '��' => '桃',
  '��' => '株',
  '��' => '桅',
  '��' => '栓',
  '��' => '栘',
  '��' => '桁',
  '��' => '殊',
  '��' => '殉',
  '��' => '殷',
  '��' => '氣',
  '��' => '氧',
  '��' => '氨',
  '��' => '氦',
  '��' => '氤',
  '��' => '泰',
  '��' => '浪',
  '��' => '涕',
  '��' => '消',
  '��' => '涇',
  '��' => '浦',
  '��' => '浸',
  '��' => '海',
  '��' => '浙',
  '��' => '涓',
  '�@' => '浬',
  '�A' => '涉',
  '�B' => '浮',
  '�C' => '浚',
  '�D' => '浴',
  '�E' => '浩',
  '�F' => '涌',
  '�G' => '涊',
  '�H' => '浹',
  '�I' => '涅',
  '�J' => '浥',
  '�K' => '涔',
  '�L' => '烊',
  '�M' => '烘',
  '�N' => '烤',
  '�O' => '烙',
  '�P' => '烈',
  '�Q' => '烏',
  '�R' => '爹',
  '�S' => '特',
  '�T' => '狼',
  '�U' => '狹',
  '�V' => '狽',
  '�W' => '狸',
  '�X' => '狷',
  '�Y' => '玆',
  '�Z' => '班',
  '�[' => '琉',
  '�\\' => '珮',
  '�]' => '珠',
  '�^' => '珪',
  '�_' => '珞',
  '�`' => '畔',
  '�a' => '畝',
  '�b' => '畜',
  '�c' => '畚',
  '�d' => '留',
  '�e' => '疾',
  '�f' => '病',
  '�g' => '症',
  '�h' => '疲',
  '�i' => '疳',
  '�j' => '疽',
  '�k' => '疼',
  '�l' => '疹',
  '�m' => '痂',
  '�n' => '疸',
  '�o' => '皋',
  '�p' => '皰',
  '�q' => '益',
  '�r' => '盍',
  '�s' => '盎',
  '�t' => '眩',
  '�u' => '真',
  '�v' => '眠',
  '�w' => '眨',
  '�x' => '矩',
  '�y' => '砰',
  '�z' => '砧',
  '�{' => '砸',
  '�|' => '砝',
  '�}' => '破',
  '�~' => '砷',
  '��' => '砥',
  '��' => '砭',
  '��' => '砠',
  '��' => '砟',
  '��' => '砲',
  '��' => '祕',
  '��' => '祐',
  '��' => '祠',
  '��' => '祟',
  '��' => '祖',
  '��' => '神',
  '��' => '祝',
  '��' => '祗',
  '��' => '祚',
  '��' => '秤',
  '��' => '秣',
  '��' => '秧',
  '��' => '租',
  '��' => '秦',
  '��' => '秩',
  '��' => '秘',
  '��' => '窄',
  '��' => '窈',
  '��' => '站',
  '��' => '笆',
  '��' => '笑',
  '��' => '粉',
  '��' => '紡',
  '��' => '紗',
  '��' => '紋',
  '��' => '紊',
  '��' => '素',
  '��' => '索',
  '��' => '純',
  '��' => '紐',
  '��' => '紕',
  '��' => '級',
  '��' => '紜',
  '��' => '納',
  '��' => '紙',
  '��' => '紛',
  '��' => '缺',
  '��' => '罟',
  '��' => '羔',
  '��' => '翅',
  '��' => '翁',
  '��' => '耆',
  '��' => '耘',
  '��' => '耕',
  '��' => '耙',
  '��' => '耗',
  '��' => '耽',
  '��' => '耿',
  '��' => '胱',
  '��' => '脂',
  '��' => '胰',
  '��' => '脅',
  '��' => '胭',
  '��' => '胴',
  '��' => '脆',
  '��' => '胸',
  '��' => '胳',
  '��' => '脈',
  '��' => '能',
  '��' => '脊',
  '��' => '胼',
  '��' => '胯',
  '��' => '臭',
  '��' => '臬',
  '��' => '舀',
  '��' => '舐',
  '��' => '航',
  '��' => '舫',
  '��' => '舨',
  '��' => '般',
  '��' => '芻',
  '��' => '茫',
  '��' => '荒',
  '��' => '荔',
  '��' => '荊',
  '��' => '茸',
  '��' => '荐',
  '��' => '草',
  '��' => '茵',
  '��' => '茴',
  '��' => '荏',
  '��' => '茲',
  '��' => '茹',
  '��' => '茶',
  '��' => '茗',
  '��' => '荀',
  '��' => '茱',
  '��' => '茨',
  '��' => '荃',
  '�@' => '虔',
  '�A' => '蚊',
  '�B' => '蚪',
  '�C' => '蚓',
  '�D' => '蚤',
  '�E' => '蚩',
  '�F' => '蚌',
  '�G' => '蚣',
  '�H' => '蚜',
  '�I' => '衰',
  '�J' => '衷',
  '�K' => '袁',
  '�L' => '袂',
  '�M' => '衽',
  '�N' => '衹',
  '�O' => '記',
  '�P' => '訐',
  '�Q' => '討',
  '�R' => '訌',
  '�S' => '訕',
  '�T' => '訊',
  '�U' => '託',
  '�V' => '訓',
  '�W' => '訖',
  '�X' => '訏',
  '�Y' => '訑',
  '�Z' => '豈',
  '�[' => '豺',
  '�\\' => '豹',
  '�]' => '財',
  '�^' => '貢',
  '�_' => '起',
  '�`' => '躬',
  '�a' => '軒',
  '�b' => '軔',
  '�c' => '軏',
  '�d' => '辱',
  '�e' => '送',
  '�f' => '逆',
  '�g' => '迷',
  '�h' => '退',
  '�i' => '迺',
  '�j' => '迴',
  '�k' => '逃',
  '�l' => '追',
  '�m' => '逅',
  '�n' => '迸',
  '�o' => '邕',
  '�p' => '郡',
  '�q' => '郝',
  '�r' => '郢',
  '�s' => '酒',
  '�t' => '配',
  '�u' => '酌',
  '�v' => '釘',
  '�w' => '針',
  '�x' => '釗',
  '�y' => '釜',
  '�z' => '釙',
  '�{' => '閃',
  '�|' => '院',
  '�}' => '陣',
  '�~' => '陡',
  '��' => '陛',
  '��' => '陝',
  '��' => '除',
  '��' => '陘',
  '��' => '陞',
  '��' => '隻',
  '��' => '飢',
  '��' => '馬',
  '��' => '骨',
  '��' => '高',
  '��' => '鬥',
  '��' => '鬲',
  '��' => '鬼',
  '��' => '乾',
  '��' => '偺',
  '��' => '偽',
  '��' => '停',
  '��' => '假',
  '��' => '偃',
  '��' => '偌',
  '��' => '做',
  '��' => '偉',
  '��' => '健',
  '��' => '偶',
  '��' => '偎',
  '��' => '偕',
  '��' => '偵',
  '��' => '側',
  '��' => '偷',
  '��' => '偏',
  '��' => '倏',
  '��' => '偯',
  '��' => '偭',
  '��' => '兜',
  '��' => '冕',
  '��' => '凰',
  '��' => '剪',
  '��' => '副',
  '��' => '勒',
  '��' => '務',
  '��' => '勘',
  '��' => '動',
  '��' => '匐',
  '��' => '匏',
  '��' => '匙',
  '��' => '匿',
  '��' => '區',
  '��' => '匾',
  '��' => '參',
  '��' => '曼',
  '��' => '商',
  '��' => '啪',
  '��' => '啦',
  '��' => '啄',
  '��' => '啞',
  '��' => '啡',
  '��' => '啃',
  '��' => '啊',
  '��' => '唱',
  '��' => '啖',
  '��' => '問',
  '��' => '啕',
  '��' => '唯',
  '��' => '啤',
  '��' => '唸',
  '��' => '售',
  '��' => '啜',
  '��' => '唬',
  '��' => '啣',
  '��' => '唳',
  '��' => '啁',
  '��' => '啗',
  '��' => '圈',
  '��' => '國',
  '��' => '圉',
  '��' => '域',
  '��' => '堅',
  '��' => '堊',
  '��' => '堆',
  '��' => '埠',
  '��' => '埤',
  '��' => '基',
  '��' => '堂',
  '��' => '堵',
  '��' => '執',
  '��' => '培',
  '��' => '夠',
  '��' => '奢',
  '��' => '娶',
  '��' => '婁',
  '��' => '婉',
  '��' => '婦',
  '��' => '婪',
  '��' => '婀',
  '�@' => '娼',
  '�A' => '婢',
  '�B' => '婚',
  '�C' => '婆',
  '�D' => '婊',
  '�E' => '孰',
  '�F' => '寇',
  '�G' => '寅',
  '�H' => '寄',
  '�I' => '寂',
  '�J' => '宿',
  '�K' => '密',
  '�L' => '尉',
  '�M' => '專',
  '�N' => '將',
  '�O' => '屠',
  '�P' => '屜',
  '�Q' => '屝',
  '�R' => '崇',
  '�S' => '崆',
  '�T' => '崎',
  '�U' => '崛',
  '�V' => '崖',
  '�W' => '崢',
  '�X' => '崑',
  '�Y' => '崩',
  '�Z' => '崔',
  '�[' => '崙',
  '�\\' => '崤',
  '�]' => '崧',
  '�^' => '崗',
  '�_' => '巢',
  '�`' => '常',
  '�a' => '帶',
  '�b' => '帳',
  '�c' => '帷',
  '�d' => '康',
  '�e' => '庸',
  '�f' => '庶',
  '�g' => '庵',
  '�h' => '庾',
  '�i' => '張',
  '�j' => '強',
  '�k' => '彗',
  '�l' => '彬',
  '�m' => '彩',
  '�n' => '彫',
  '�o' => '得',
  '�p' => '徙',
  '�q' => '從',
  '�r' => '徘',
  '�s' => '御',
  '�t' => '徠',
  '�u' => '徜',
  '�v' => '恿',
  '�w' => '患',
  '�x' => '悉',
  '�y' => '悠',
  '�z' => '您',
  '�{' => '惋',
  '�|' => '悴',
  '�}' => '惦',
  '�~' => '悽',
  '��' => '情',
  '��' => '悻',
  '��' => '悵',
  '��' => '惜',
  '��' => '悼',
  '��' => '惘',
  '��' => '惕',
  '��' => '惆',
  '��' => '惟',
  '��' => '悸',
  '��' => '惚',
  '��' => '惇',
  '��' => '戚',
  '��' => '戛',
  '��' => '扈',
  '��' => '掠',
  '��' => '控',
  '��' => '捲',
  '��' => '掖',
  '��' => '探',
  '��' => '接',
  '��' => '捷',
  '��' => '捧',
  '��' => '掘',
  '��' => '措',
  '��' => '捱',
  '��' => '掩',
  '��' => '掉',
  '��' => '掃',
  '��' => '掛',
  '��' => '捫',
  '��' => '推',
  '��' => '掄',
  '��' => '授',
  '��' => '掙',
  '��' => '採',
  '��' => '掬',
  '��' => '排',
  '��' => '掏',
  '��' => '掀',
  '��' => '捻',
  '��' => '捩',
  '��' => '捨',
  '��' => '捺',
  '��' => '敝',
  '��' => '敖',
  '��' => '救',
  '��' => '教',
  '��' => '敗',
  '��' => '啟',
  '��' => '敏',
  '��' => '敘',
  '��' => '敕',
  '��' => '敔',
  '��' => '斜',
  '��' => '斛',
  '��' => '斬',
  '��' => '族',
  '��' => '旋',
  '��' => '旌',
  '��' => '旎',
  '��' => '晝',
  '��' => '晚',
  '��' => '晤',
  '��' => '晨',
  '��' => '晦',
  '��' => '晞',
  '��' => '曹',
  '��' => '勗',
  '��' => '望',
  '��' => '梁',
  '��' => '梯',
  '��' => '梢',
  '��' => '梓',
  '��' => '梵',
  '��' => '桿',
  '��' => '桶',
  '��' => '梱',
  '��' => '梧',
  '��' => '梗',
  '��' => '械',
  '��' => '梃',
  '��' => '棄',
  '��' => '梭',
  '��' => '梆',
  '��' => '梅',
  '��' => '梔',
  '��' => '條',
  '��' => '梨',
  '��' => '梟',
  '��' => '梡',
  '��' => '梂',
  '��' => '欲',
  '��' => '殺',
  '�@' => '毫',
  '�A' => '毬',
  '�B' => '氫',
  '�C' => '涎',
  '�D' => '涼',
  '�E' => '淳',
  '�F' => '淙',
  '�G' => '液',
  '�H' => '淡',
  '�I' => '淌',
  '�J' => '淤',
  '�K' => '添',
  '�L' => '淺',
  '�M' => '清',
  '�N' => '淇',
  '�O' => '淋',
  '�P' => '涯',
  '�Q' => '淑',
  '�R' => '涮',
  '�S' => '淞',
  '�T' => '淹',
  '�U' => '涸',
  '�V' => '混',
  '�W' => '淵',
  '�X' => '淅',
  '�Y' => '淒',
  '�Z' => '渚',
  '�[' => '涵',
  '�\\' => '淚',
  '�]' => '淫',
  '�^' => '淘',
  '�_' => '淪',
  '�`' => '深',
  '�a' => '淮',
  '�b' => '淨',
  '�c' => '淆',
  '�d' => '淄',
  '�e' => '涪',
  '�f' => '淬',
  '�g' => '涿',
  '�h' => '淦',
  '�i' => '烹',
  '�j' => '焉',
  '�k' => '焊',
  '�l' => '烽',
  '�m' => '烯',
  '�n' => '爽',
  '�o' => '牽',
  '�p' => '犁',
  '�q' => '猜',
  '�r' => '猛',
  '�s' => '猖',
  '�t' => '猓',
  '�u' => '猙',
  '�v' => '率',
  '�w' => '琅',
  '�x' => '琊',
  '�y' => '球',
  '�z' => '理',
  '�{' => '現',
  '�|' => '琍',
  '�}' => '瓠',
  '�~' => '瓶',
  '��' => '瓷',
  '��' => '甜',
  '��' => '產',
  '��' => '略',
  '��' => '畦',
  '��' => '畢',
  '��' => '異',
  '��' => '疏',
  '��' => '痔',
  '��' => '痕',
  '��' => '疵',
  '��' => '痊',
  '��' => '痍',
  '��' => '皎',
  '��' => '盔',
  '��' => '盒',
  '��' => '盛',
  '��' => '眷',
  '��' => '眾',
  '��' => '眼',
  '��' => '眶',
  '��' => '眸',
  '��' => '眺',
  '��' => '硫',
  '��' => '硃',
  '��' => '硎',
  '��' => '祥',
  '��' => '票',
  '��' => '祭',
  '��' => '移',
  '��' => '窒',
  '��' => '窕',
  '��' => '笠',
  '��' => '笨',
  '��' => '笛',
  '��' => '第',
  '��' => '符',
  '��' => '笙',
  '��' => '笞',
  '��' => '笮',
  '��' => '粒',
  '��' => '粗',
  '��' => '粕',
  '��' => '絆',
  '��' => '絃',
  '��' => '統',
  '��' => '紮',
  '��' => '紹',
  '��' => '紼',
  '��' => '絀',
  '��' => '細',
  '��' => '紳',
  '��' => '組',
  '��' => '累',
  '��' => '終',
  '��' => '紲',
  '��' => '紱',
  '��' => '缽',
  '��' => '羞',
  '��' => '羚',
  '��' => '翌',
  '��' => '翎',
  '��' => '習',
  '��' => '耜',
  '��' => '聊',
  '��' => '聆',
  '��' => '脯',
  '��' => '脖',
  '��' => '脣',
  '��' => '脫',
  '��' => '脩',
  '��' => '脰',
  '��' => '脤',
  '��' => '舂',
  '��' => '舵',
  '��' => '舷',
  '��' => '舶',
  '��' => '船',
  '��' => '莎',
  '��' => '莞',
  '��' => '莘',
  '��' => '荸',
  '��' => '莢',
  '��' => '莖',
  '��' => '莽',
  '��' => '莫',
  '��' => '莒',
  '��' => '莊',
  '��' => '莓',
  '��' => '莉',
  '��' => '莠',
  '��' => '荷',
  '��' => '荻',
  '��' => '荼',
  '�@' => '莆',
  '�A' => '莧',
  '�B' => '處',
  '�C' => '彪',
  '�D' => '蛇',
  '�E' => '蛀',
  '�F' => '蚶',
  '�G' => '蛄',
  '�H' => '蚵',
  '�I' => '蛆',
  '�J' => '蛋',
  '�K' => '蚱',
  '�L' => '蚯',
  '�M' => '蛉',
  '�N' => '術',
  '�O' => '袞',
  '�P' => '袈',
  '�Q' => '被',
  '�R' => '袒',
  '�S' => '袖',
  '�T' => '袍',
  '�U' => '袋',
  '�V' => '覓',
  '�W' => '規',
  '�X' => '訪',
  '�Y' => '訝',
  '�Z' => '訣',
  '�[' => '訥',
  '�\\' => '許',
  '�]' => '設',
  '�^' => '訟',
  '�_' => '訛',
  '�`' => '訢',
  '�a' => '豉',
  '�b' => '豚',
  '�c' => '販',
  '�d' => '責',
  '�e' => '貫',
  '�f' => '貨',
  '�g' => '貪',
  '�h' => '貧',
  '�i' => '赧',
  '�j' => '赦',
  '�k' => '趾',
  '�l' => '趺',
  '�m' => '軛',
  '�n' => '軟',
  '�o' => '這',
  '�p' => '逍',
  '�q' => '通',
  '�r' => '逗',
  '�s' => '連',
  '�t' => '速',
  '�u' => '逝',
  '�v' => '逐',
  '�w' => '逕',
  '�x' => '逞',
  '�y' => '造',
  '�z' => '透',
  '�{' => '逢',
  '�|' => '逖',
  '�}' => '逛',
  '�~' => '途',
  '��' => '部',
  '��' => '郭',
  '��' => '都',
  '��' => '酗',
  '��' => '野',
  '��' => '釵',
  '��' => '釦',
  '��' => '釣',
  '��' => '釧',
  '��' => '釭',
  '��' => '釩',
  '��' => '閉',
  '��' => '陪',
  '��' => '陵',
  '��' => '陳',
  '��' => '陸',
  '��' => '陰',
  '��' => '陴',
  '��' => '陶',
  '��' => '陷',
  '��' => '陬',
  '��' => '雀',
  '��' => '雪',
  '��' => '雩',
  '��' => '章',
  '��' => '竟',
  '��' => '頂',
  '��' => '頃',
  '��' => '魚',
  '��' => '鳥',
  '��' => '鹵',
  '��' => '鹿',
  '��' => '麥',
  '��' => '麻',
  '��' => '傢',
  '��' => '傍',
  '��' => '傅',
  '��' => '備',
  '��' => '傑',
  '��' => '傀',
  '��' => '傖',
  '��' => '傘',
  '��' => '傚',
  '��' => '最',
  '��' => '凱',
  '��' => '割',
  '��' => '剴',
  '��' => '創',
  '��' => '剩',
  '��' => '勞',
  '��' => '勝',
  '��' => '勛',
  '��' => '博',
  '��' => '厥',
  '��' => '啻',
  '��' => '喀',
  '��' => '喧',
  '��' => '啼',
  '��' => '喊',
  '��' => '喝',
  '��' => '喘',
  '��' => '喂',
  '��' => '喜',
  '��' => '喪',
  '��' => '喔',
  '��' => '喇',
  '��' => '喋',
  '��' => '喃',
  '��' => '喳',
  '��' => '單',
  '��' => '喟',
  '��' => '唾',
  '��' => '喲',
  '��' => '喚',
  '��' => '喻',
  '��' => '喬',
  '��' => '喱',
  '��' => '啾',
  '��' => '喉',
  '��' => '喫',
  '��' => '喙',
  '��' => '圍',
  '��' => '堯',
  '��' => '堪',
  '��' => '場',
  '��' => '堤',
  '��' => '堰',
  '��' => '報',
  '��' => '堡',
  '��' => '堝',
  '��' => '堠',
  '��' => '壹',
  '��' => '壺',
  '��' => '奠',
  '�@' => '婷',
  '�A' => '媚',
  '�B' => '婿',
  '�C' => '媒',
  '�D' => '媛',
  '�E' => '媧',
  '�F' => '孳',
  '�G' => '孱',
  '�H' => '寒',
  '�I' => '富',
  '�J' => '寓',
  '�K' => '寐',
  '�L' => '尊',
  '�M' => '尋',
  '�N' => '就',
  '�O' => '嵌',
  '�P' => '嵐',
  '�Q' => '崴',
  '�R' => '嵇',
  '�S' => '巽',
  '�T' => '幅',
  '�U' => '帽',
  '�V' => '幀',
  '�W' => '幃',
  '�X' => '幾',
  '�Y' => '廊',
  '�Z' => '廁',
  '�[' => '廂',
  '�\\' => '廄',
  '�]' => '弼',
  '�^' => '彭',
  '�_' => '復',
  '�`' => '循',
  '�a' => '徨',
  '�b' => '惑',
  '�c' => '惡',
  '�d' => '悲',
  '�e' => '悶',
  '�f' => '惠',
  '�g' => '愜',
  '�h' => '愣',
  '�i' => '惺',
  '�j' => '愕',
  '�k' => '惰',
  '�l' => '惻',
  '�m' => '惴',
  '�n' => '慨',
  '�o' => '惱',
  '�p' => '愎',
  '�q' => '惶',
  '�r' => '愉',
  '�s' => '愀',
  '�t' => '愒',
  '�u' => '戟',
  '�v' => '扉',
  '�w' => '掣',
  '�x' => '掌',
  '�y' => '描',
  '�z' => '揀',
  '�{' => '揩',
  '�|' => '揉',
  '�}' => '揆',
  '�~' => '揍',
  '��' => '插',
  '��' => '揣',
  '��' => '提',
  '��' => '握',
  '��' => '揖',
  '��' => '揭',
  '��' => '揮',
  '��' => '捶',
  '��' => '援',
  '��' => '揪',
  '��' => '換',
  '��' => '摒',
  '��' => '揚',
  '��' => '揹',
  '��' => '敞',
  '��' => '敦',
  '��' => '敢',
  '��' => '散',
  '��' => '斑',
  '��' => '斐',
  '��' => '斯',
  '��' => '普',
  '��' => '晰',
  '��' => '晴',
  '��' => '晶',
  '��' => '景',
  '��' => '暑',
  '��' => '智',
  '��' => '晾',
  '��' => '晷',
  '��' => '曾',
  '��' => '替',
  '��' => '期',
  '��' => '朝',
  '��' => '棺',
  '��' => '棕',
  '��' => '棠',
  '��' => '棘',
  '��' => '棗',
  '��' => '椅',
  '��' => '棟',
  '��' => '棵',
  '��' => '森',
  '��' => '棧',
  '��' => '棹',
  '��' => '棒',
  '��' => '棲',
  '��' => '棣',
  '��' => '棋',
  '��' => '棍',
  '��' => '植',
  '��' => '椒',
  '��' => '椎',
  '��' => '棉',
  '��' => '棚',
  '��' => '楮',
  '��' => '棻',
  '��' => '款',
  '��' => '欺',
  '��' => '欽',
  '��' => '殘',
  '��' => '殖',
  '��' => '殼',
  '��' => '毯',
  '��' => '氮',
  '��' => '氯',
  '��' => '氬',
  '��' => '港',
  '��' => '游',
  '��' => '湔',
  '��' => '渡',
  '��' => '渲',
  '��' => '湧',
  '��' => '湊',
  '��' => '渠',
  '��' => '渥',
  '��' => '渣',
  '��' => '減',
  '��' => '湛',
  '��' => '湘',
  '��' => '渤',
  '��' => '湖',
  '��' => '湮',
  '��' => '渭',
  '��' => '渦',
  '��' => '湯',
  '��' => '渴',
  '��' => '湍',
  '��' => '渺',
  '��' => '測',
  '��' => '湃',
  '��' => '渝',
  '��' => '渾',
  '��' => '滋',
  '�@' => '溉',
  '�A' => '渙',
  '�B' => '湎',
  '�C' => '湣',
  '�D' => '湄',
  '�E' => '湲',
  '�F' => '湩',
  '�G' => '湟',
  '�H' => '焙',
  '�I' => '焚',
  '�J' => '焦',
  '�K' => '焰',
  '�L' => '無',
  '�M' => '然',
  '�N' => '煮',
  '�O' => '焜',
  '�P' => '牌',
  '�Q' => '犄',
  '�R' => '犀',
  '�S' => '猶',
  '�T' => '猥',
  '�U' => '猴',
  '�V' => '猩',
  '�W' => '琺',
  '�X' => '琪',
  '�Y' => '琳',
  '�Z' => '琢',
  '�[' => '琥',
  '�\\' => '琵',
  '�]' => '琶',
  '�^' => '琴',
  '�_' => '琯',
  '�`' => '琛',
  '�a' => '琦',
  '�b' => '琨',
  '�c' => '甥',
  '�d' => '甦',
  '�e' => '畫',
  '�f' => '番',
  '�g' => '痢',
  '�h' => '痛',
  '�i' => '痣',
  '�j' => '痙',
  '�k' => '痘',
  '�l' => '痞',
  '�m' => '痠',
  '�n' => '登',
  '�o' => '發',
  '�p' => '皖',
  '�q' => '皓',
  '�r' => '皴',
  '�s' => '盜',
  '�t' => '睏',
  '�u' => '短',
  '�v' => '硝',
  '�w' => '硬',
  '�x' => '硯',
  '�y' => '稍',
  '�z' => '稈',
  '�{' => '程',
  '�|' => '稅',
  '�}' => '稀',
  '�~' => '窘',
  '��' => '窗',
  '��' => '窖',
  '��' => '童',
  '��' => '竣',
  '��' => '等',
  '��' => '策',
  '��' => '筆',
  '��' => '筐',
  '��' => '筒',
  '��' => '答',
  '��' => '筍',
  '��' => '筋',
  '��' => '筏',
  '��' => '筑',
  '��' => '粟',
  '��' => '粥',
  '��' => '絞',
  '��' => '結',
  '��' => '絨',
  '��' => '絕',
  '��' => '紫',
  '��' => '絮',
  '��' => '絲',
  '��' => '絡',
  '��' => '給',
  '��' => '絢',
  '��' => '絰',
  '��' => '絳',
  '��' => '善',
  '��' => '翔',
  '��' => '翕',
  '��' => '耋',
  '��' => '聒',
  '��' => '肅',
  '��' => '腕',
  '��' => '腔',
  '��' => '腋',
  '��' => '腑',
  '��' => '腎',
  '��' => '脹',
  '��' => '腆',
  '��' => '脾',
  '��' => '腌',
  '��' => '腓',
  '��' => '腴',
  '��' => '舒',
  '��' => '舜',
  '��' => '菩',
  '��' => '萃',
  '��' => '菸',
  '��' => '萍',
  '��' => '菠',
  '��' => '菅',
  '��' => '萋',
  '��' => '菁',
  '��' => '華',
  '��' => '菱',
  '��' => '菴',
  '��' => '著',
  '��' => '萊',
  '��' => '菰',
  '��' => '萌',
  '��' => '菌',
  '��' => '菽',
  '��' => '菲',
  '��' => '菊',
  '��' => '萸',
  '��' => '萎',
  '��' => '萄',
  '��' => '菜',
  '��' => '萇',
  '��' => '菔',
  '��' => '菟',
  '��' => '虛',
  '��' => '蛟',
  '��' => '蛙',
  '��' => '蛭',
  '��' => '蛔',
  '��' => '蛛',
  '��' => '蛤',
  '��' => '蛐',
  '��' => '蛞',
  '��' => '街',
  '��' => '裁',
  '��' => '裂',
  '��' => '袱',
  '��' => '覃',
  '��' => '視',
  '��' => '註',
  '��' => '詠',
  '��' => '評',
  '��' => '詞',
  '��' => '証',
  '��' => '詁',
  '�@' => '詔',
  '�A' => '詛',
  '�B' => '詐',
  '�C' => '詆',
  '�D' => '訴',
  '�E' => '診',
  '�F' => '訶',
  '�G' => '詖',
  '�H' => '象',
  '�I' => '貂',
  '�J' => '貯',
  '�K' => '貼',
  '�L' => '貳',
  '�M' => '貽',
  '�N' => '賁',
  '�O' => '費',
  '�P' => '賀',
  '�Q' => '貴',
  '�R' => '買',
  '�S' => '貶',
  '�T' => '貿',
  '�U' => '貸',
  '�V' => '越',
  '�W' => '超',
  '�X' => '趁',
  '�Y' => '跎',
  '�Z' => '距',
  '�[' => '跋',
  '�\\' => '跚',
  '�]' => '跑',
  '�^' => '跌',
  '�_' => '跛',
  '�`' => '跆',
  '�a' => '軻',
  '�b' => '軸',
  '�c' => '軼',
  '�d' => '辜',
  '�e' => '逮',
  '�f' => '逵',
  '�g' => '週',
  '�h' => '逸',
  '�i' => '進',
  '�j' => '逶',
  '�k' => '鄂',
  '�l' => '郵',
  '�m' => '鄉',
  '�n' => '郾',
  '�o' => '酣',
  '�p' => '酥',
  '�q' => '量',
  '�r' => '鈔',
  '�s' => '鈕',
  '�t' => '鈣',
  '�u' => '鈉',
  '�v' => '鈞',
  '�w' => '鈍',
  '�x' => '鈐',
  '�y' => '鈇',
  '�z' => '鈑',
  '�{' => '閔',
  '�|' => '閏',
  '�}' => '開',
  '�~' => '閑',
  '��' => '間',
  '��' => '閒',
  '��' => '閎',
  '��' => '隊',
  '��' => '階',
  '��' => '隋',
  '��' => '陽',
  '��' => '隅',
  '��' => '隆',
  '��' => '隍',
  '��' => '陲',
  '��' => '隄',
  '��' => '雁',
  '��' => '雅',
  '��' => '雄',
  '��' => '集',
  '��' => '雇',
  '��' => '雯',
  '��' => '雲',
  '��' => '韌',
  '��' => '項',
  '��' => '順',
  '��' => '須',
  '��' => '飧',
  '��' => '飪',
  '��' => '飯',
  '��' => '飩',
  '��' => '飲',
  '��' => '飭',
  '��' => '馮',
  '��' => '馭',
  '��' => '黃',
  '��' => '黍',
  '��' => '黑',
  '��' => '亂',
  '��' => '傭',
  '��' => '債',
  '��' => '傲',
  '��' => '傳',
  '��' => '僅',
  '��' => '傾',
  '��' => '催',
  '��' => '傷',
  '��' => '傻',
  '��' => '傯',
  '��' => '僇',
  '��' => '剿',
  '��' => '剷',
  '��' => '剽',
  '��' => '募',
  '��' => '勦',
  '��' => '勤',
  '��' => '勢',
  '��' => '勣',
  '��' => '匯',
  '��' => '嗟',
  '��' => '嗨',
  '��' => '嗓',
  '��' => '嗦',
  '��' => '嗎',
  '��' => '嗜',
  '��' => '嗇',
  '��' => '嗑',
  '��' => '嗣',
  '��' => '嗤',
  '��' => '嗯',
  '��' => '嗚',
  '��' => '嗡',
  '��' => '嗅',
  '��' => '嗆',
  '��' => '嗥',
  '��' => '嗉',
  '��' => '園',
  '��' => '圓',
  '��' => '塞',
  '��' => '塑',
  '��' => '塘',
  '��' => '塗',
  '��' => '塚',
  '��' => '塔',
  '��' => '填',
  '��' => '塌',
  '��' => '塭',
  '��' => '塊',
  '��' => '塢',
  '��' => '塒',
  '��' => '塋',
  '��' => '奧',
  '��' => '嫁',
  '��' => '嫉',
  '��' => '嫌',
  '��' => '媾',
  '��' => '媽',
  '��' => '媼',
  '�@' => '媳',
  '�A' => '嫂',
  '�B' => '媲',
  '�C' => '嵩',
  '�D' => '嵯',
  '�E' => '幌',
  '�F' => '幹',
  '�G' => '廉',
  '�H' => '廈',
  '�I' => '弒',
  '�J' => '彙',
  '�K' => '徬',
  '�L' => '微',
  '�M' => '愚',
  '�N' => '意',
  '�O' => '慈',
  '�P' => '感',
  '�Q' => '想',
  '�R' => '愛',
  '�S' => '惹',
  '�T' => '愁',
  '�U' => '愈',
  '�V' => '慎',
  '�W' => '慌',
  '�X' => '慄',
  '�Y' => '慍',
  '�Z' => '愾',
  '�[' => '愴',
  '�\\' => '愧',
  '�]' => '愍',
  '�^' => '愆',
  '�_' => '愷',
  '�`' => '戡',
  '�a' => '戢',
  '�b' => '搓',
  '�c' => '搾',
  '�d' => '搞',
  '�e' => '搪',
  '�f' => '搭',
  '�g' => '搽',
  '�h' => '搬',
  '�i' => '搏',
  '�j' => '搜',
  '�k' => '搔',
  '�l' => '損',
  '�m' => '搶',
  '�n' => '搖',
  '�o' => '搗',
  '�p' => '搆',
  '�q' => '敬',
  '�r' => '斟',
  '�s' => '新',
  '�t' => '暗',
  '�u' => '暉',
  '�v' => '暇',
  '�w' => '暈',
  '�x' => '暖',
  '�y' => '暄',
  '�z' => '暘',
  '�{' => '暍',
  '�|' => '會',
  '�}' => '榔',
  '�~' => '業',
  '��' => '楚',
  '��' => '楷',
  '��' => '楠',
  '��' => '楔',
  '��' => '極',
  '��' => '椰',
  '��' => '概',
  '��' => '楊',
  '��' => '楨',
  '��' => '楫',
  '��' => '楞',
  '��' => '楓',
  '��' => '楹',
  '��' => '榆',
  '��' => '楝',
  '��' => '楣',
  '��' => '楛',
  '��' => '歇',
  '��' => '歲',
  '��' => '毀',
  '��' => '殿',
  '��' => '毓',
  '��' => '毽',
  '��' => '溢',
  '��' => '溯',
  '��' => '滓',
  '��' => '溶',
  '��' => '滂',
  '��' => '源',
  '��' => '溝',
  '��' => '滇',
  '��' => '滅',
  '��' => '溥',
  '��' => '溘',
  '��' => '溼',
  '��' => '溺',
  '��' => '溫',
  '��' => '滑',
  '��' => '準',
  '��' => '溜',
  '��' => '滄',
  '��' => '滔',
  '��' => '溪',
  '��' => '溧',
  '��' => '溴',
  '��' => '煎',
  '��' => '煙',
  '��' => '煩',
  '��' => '煤',
  '��' => '煉',
  '��' => '照',
  '��' => '煜',
  '��' => '煬',
  '��' => '煦',
  '��' => '煌',
  '��' => '煥',
  '��' => '煞',
  '��' => '煆',
  '��' => '煨',
  '��' => '煖',
  '��' => '爺',
  '��' => '牒',
  '��' => '猷',
  '��' => '獅',
  '��' => '猿',
  '��' => '猾',
  '��' => '瑯',
  '��' => '瑚',
  '��' => '瑕',
  '��' => '瑟',
  '��' => '瑞',
  '��' => '瑁',
  '��' => '琿',
  '��' => '瑙',
  '��' => '瑛',
  '��' => '瑜',
  '��' => '當',
  '��' => '畸',
  '��' => '瘀',
  '��' => '痰',
  '��' => '瘁',
  '��' => '痲',
  '��' => '痱',
  '��' => '痺',
  '��' => '痿',
  '��' => '痴',
  '��' => '痳',
  '��' => '盞',
  '��' => '盟',
  '��' => '睛',
  '��' => '睫',
  '��' => '睦',
  '��' => '睞',
  '��' => '督',
  '�@' => '睹',
  '�A' => '睪',
  '�B' => '睬',
  '�C' => '睜',
  '�D' => '睥',
  '�E' => '睨',
  '�F' => '睢',
  '�G' => '矮',
  '�H' => '碎',
  '�I' => '碰',
  '�J' => '碗',
  '�K' => '碘',
  '�L' => '碌',
  '�M' => '碉',
  '�N' => '硼',
  '�O' => '碑',
  '�P' => '碓',
  '�Q' => '硿',
  '�R' => '祺',
  '�S' => '祿',
  '�T' => '禁',
  '�U' => '萬',
  '�V' => '禽',
  '�W' => '稜',
  '�X' => '稚',
  '�Y' => '稠',
  '�Z' => '稔',
  '�[' => '稟',
  '�\\' => '稞',
  '�]' => '窟',
  '�^' => '窠',
  '�_' => '筷',
  '�`' => '節',
  '�a' => '筠',
  '�b' => '筮',
  '�c' => '筧',
  '�d' => '粱',
  '�e' => '粳',
  '�f' => '粵',
  '�g' => '經',
  '�h' => '絹',
  '�i' => '綑',
  '�j' => '綁',
  '�k' => '綏',
  '�l' => '絛',
  '�m' => '置',
  '�n' => '罩',
  '�o' => '罪',
  '�p' => '署',
  '�q' => '義',
  '�r' => '羨',
  '�s' => '群',
  '�t' => '聖',
  '�u' => '聘',
  '�v' => '肆',
  '�w' => '肄',
  '�x' => '腱',
  '�y' => '腰',
  '�z' => '腸',
  '�{' => '腥',
  '�|' => '腮',
  '�}' => '腳',
  '�~' => '腫',
  '��' => '腹',
  '��' => '腺',
  '��' => '腦',
  '��' => '舅',
  '��' => '艇',
  '��' => '蒂',
  '��' => '葷',
  '��' => '落',
  '��' => '萱',
  '��' => '葵',
  '��' => '葦',
  '��' => '葫',
  '��' => '葉',
  '��' => '葬',
  '��' => '葛',
  '��' => '萼',
  '��' => '萵',
  '��' => '葡',
  '��' => '董',
  '��' => '葩',
  '��' => '葭',
  '��' => '葆',
  '��' => '虞',
  '��' => '虜',
  '��' => '號',
  '��' => '蛹',
  '��' => '蜓',
  '��' => '蜈',
  '��' => '蜇',
  '��' => '蜀',
  '��' => '蛾',
  '��' => '蛻',
  '��' => '蜂',
  '��' => '蜃',
  '��' => '蜆',
  '��' => '蜊',
  '��' => '衙',
  '��' => '裟',
  '��' => '裔',
  '��' => '裙',
  '��' => '補',
  '��' => '裘',
  '��' => '裝',
  '��' => '裡',
  '��' => '裊',
  '��' => '裕',
  '��' => '裒',
  '��' => '覜',
  '��' => '解',
  '��' => '詫',
  '��' => '該',
  '��' => '詳',
  '��' => '試',
  '��' => '詩',
  '��' => '詰',
  '��' => '誇',
  '��' => '詼',
  '��' => '詣',
  '��' => '誠',
  '��' => '話',
  '��' => '誅',
  '��' => '詭',
  '��' => '詢',
  '��' => '詮',
  '��' => '詬',
  '��' => '詹',
  '��' => '詻',
  '��' => '訾',
  '��' => '詨',
  '��' => '豢',
  '��' => '貊',
  '��' => '貉',
  '��' => '賊',
  '��' => '資',
  '��' => '賈',
  '��' => '賄',
  '��' => '貲',
  '��' => '賃',
  '��' => '賂',
  '��' => '賅',
  '��' => '跡',
  '��' => '跟',
  '��' => '跨',
  '��' => '路',
  '��' => '跳',
  '��' => '跺',
  '��' => '跪',
  '��' => '跤',
  '��' => '跦',
  '��' => '躲',
  '��' => '較',
  '��' => '載',
  '��' => '軾',
  '��' => '輊',
  '�@' => '辟',
  '�A' => '農',
  '�B' => '運',
  '�C' => '遊',
  '�D' => '道',
  '�E' => '遂',
  '�F' => '達',
  '�G' => '逼',
  '�H' => '違',
  '�I' => '遐',
  '�J' => '遇',
  '�K' => '遏',
  '�L' => '過',
  '�M' => '遍',
  '�N' => '遑',
  '�O' => '逾',
  '�P' => '遁',
  '�Q' => '鄒',
  '�R' => '鄗',
  '�S' => '酬',
  '�T' => '酪',
  '�U' => '酩',
  '�V' => '釉',
  '�W' => '鈷',
  '�X' => '鉗',
  '�Y' => '鈸',
  '�Z' => '鈽',
  '�[' => '鉀',
  '�\\' => '鈾',
  '�]' => '鉛',
  '�^' => '鉋',
  '�_' => '鉤',
  '�`' => '鉑',
  '�a' => '鈴',
  '�b' => '鉉',
  '�c' => '鉍',
  '�d' => '鉅',
  '�e' => '鈹',
  '�f' => '鈿',
  '�g' => '鉚',
  '�h' => '閘',
  '�i' => '隘',
  '�j' => '隔',
  '�k' => '隕',
  '�l' => '雍',
  '�m' => '雋',
  '�n' => '雉',
  '�o' => '雊',
  '�p' => '雷',
  '�q' => '電',
  '�r' => '雹',
  '�s' => '零',
  '�t' => '靖',
  '�u' => '靴',
  '�v' => '靶',
  '�w' => '預',
  '�x' => '頑',
  '�y' => '頓',
  '�z' => '頊',
  '�{' => '頒',
  '�|' => '頌',
  '�}' => '飼',
  '�~' => '飴',
  '��' => '飽',
  '��' => '飾',
  '��' => '馳',
  '��' => '馱',
  '��' => '馴',
  '��' => '髡',
  '��' => '鳩',
  '��' => '麂',
  '��' => '鼎',
  '��' => '鼓',
  '��' => '鼠',
  '��' => '僧',
  '��' => '僮',
  '��' => '僥',
  '��' => '僖',
  '��' => '僭',
  '��' => '僚',
  '��' => '僕',
  '��' => '像',
  '��' => '僑',
  '��' => '僱',
  '��' => '僎',
  '��' => '僩',
  '��' => '兢',
  '��' => '凳',
  '��' => '劃',
  '��' => '劂',
  '��' => '匱',
  '��' => '厭',
  '��' => '嗾',
  '��' => '嘀',
  '��' => '嘛',
  '��' => '嘗',
  '��' => '嗽',
  '��' => '嘔',
  '��' => '嘆',
  '��' => '嘉',
  '��' => '嘍',
  '��' => '嘎',
  '��' => '嗷',
  '��' => '嘖',
  '��' => '嘟',
  '��' => '嘈',
  '��' => '嘐',
  '��' => '嗶',
  '��' => '團',
  '��' => '圖',
  '��' => '塵',
  '��' => '塾',
  '��' => '境',
  '��' => '墓',
  '��' => '墊',
  '��' => '塹',
  '��' => '墅',
  '��' => '塽',
  '��' => '壽',
  '��' => '夥',
  '��' => '夢',
  '��' => '夤',
  '��' => '奪',
  '��' => '奩',
  '��' => '嫡',
  '��' => '嫦',
  '��' => '嫩',
  '��' => '嫗',
  '��' => '嫖',
  '��' => '嫘',
  '��' => '嫣',
  '��' => '孵',
  '��' => '寞',
  '��' => '寧',
  '��' => '寡',
  '��' => '寥',
  '��' => '實',
  '��' => '寨',
  '��' => '寢',
  '��' => '寤',
  '��' => '察',
  '��' => '對',
  '��' => '屢',
  '��' => '嶄',
  '��' => '嶇',
  '��' => '幛',
  '��' => '幣',
  '��' => '幕',
  '��' => '幗',
  '��' => '幔',
  '��' => '廓',
  '��' => '廖',
  '��' => '弊',
  '��' => '彆',
  '��' => '彰',
  '��' => '徹',
  '��' => '慇',
  '�@' => '愿',
  '�A' => '態',
  '�B' => '慷',
  '�C' => '慢',
  '�D' => '慣',
  '�E' => '慟',
  '�F' => '慚',
  '�G' => '慘',
  '�H' => '慵',
  '�I' => '截',
  '�J' => '撇',
  '�K' => '摘',
  '�L' => '摔',
  '�M' => '撤',
  '�N' => '摸',
  '�O' => '摟',
  '�P' => '摺',
  '�Q' => '摑',
  '�R' => '摧',
  '�S' => '搴',
  '�T' => '摭',
  '�U' => '摻',
  '�V' => '敲',
  '�W' => '斡',
  '�X' => '旗',
  '�Y' => '旖',
  '�Z' => '暢',
  '�[' => '暨',
  '�\\' => '暝',
  '�]' => '榜',
  '�^' => '榨',
  '�_' => '榕',
  '�`' => '槁',
  '�a' => '榮',
  '�b' => '槓',
  '�c' => '構',
  '�d' => '榛',
  '�e' => '榷',
  '�f' => '榻',
  '�g' => '榫',
  '�h' => '榴',
  '�i' => '槐',
  '�j' => '槍',
  '�k' => '榭',
  '�l' => '槌',
  '�m' => '榦',
  '�n' => '槃',
  '�o' => '榣',
  '�p' => '歉',
  '�q' => '歌',
  '�r' => '氳',
  '�s' => '漳',
  '�t' => '演',
  '�u' => '滾',
  '�v' => '漓',
  '�w' => '滴',
  '�x' => '漩',
  '�y' => '漾',
  '�z' => '漠',
  '�{' => '漬',
  '�|' => '漏',
  '�}' => '漂',
  '�~' => '漢',
  '��' => '滿',
  '��' => '滯',
  '��' => '漆',
  '��' => '漱',
  '��' => '漸',
  '��' => '漲',
  '��' => '漣',
  '��' => '漕',
  '��' => '漫',
  '��' => '漯',
  '��' => '澈',
  '��' => '漪',
  '��' => '滬',
  '��' => '漁',
  '��' => '滲',
  '��' => '滌',
  '��' => '滷',
  '��' => '熔',
  '��' => '熙',
  '��' => '煽',
  '��' => '熊',
  '��' => '熄',
  '��' => '熒',
  '��' => '爾',
  '��' => '犒',
  '��' => '犖',
  '��' => '獄',
  '��' => '獐',
  '��' => '瑤',
  '��' => '瑣',
  '��' => '瑪',
  '��' => '瑰',
  '��' => '瑭',
  '��' => '甄',
  '��' => '疑',
  '��' => '瘧',
  '��' => '瘍',
  '��' => '瘋',
  '��' => '瘉',
  '��' => '瘓',
  '��' => '盡',
  '��' => '監',
  '��' => '瞄',
  '��' => '睽',
  '��' => '睿',
  '��' => '睡',
  '��' => '磁',
  '��' => '碟',
  '��' => '碧',
  '��' => '碳',
  '��' => '碩',
  '��' => '碣',
  '��' => '禎',
  '��' => '福',
  '��' => '禍',
  '��' => '種',
  '��' => '稱',
  '��' => '窪',
  '��' => '窩',
  '��' => '竭',
  '��' => '端',
  '��' => '管',
  '��' => '箕',
  '��' => '箋',
  '��' => '筵',
  '��' => '算',
  '��' => '箝',
  '��' => '箔',
  '��' => '箏',
  '��' => '箸',
  '��' => '箇',
  '��' => '箄',
  '��' => '粹',
  '��' => '粽',
  '��' => '精',
  '��' => '綻',
  '��' => '綰',
  '��' => '綜',
  '��' => '綽',
  '��' => '綾',
  '��' => '綠',
  '��' => '緊',
  '��' => '綴',
  '��' => '網',
  '��' => '綱',
  '��' => '綺',
  '��' => '綢',
  '��' => '綿',
  '��' => '綵',
  '��' => '綸',
  '��' => '維',
  '��' => '緒',
  '��' => '緇',
  '��' => '綬',
  '�@' => '罰',
  '�A' => '翠',
  '�B' => '翡',
  '�C' => '翟',
  '�D' => '聞',
  '�E' => '聚',
  '�F' => '肇',
  '�G' => '腐',
  '�H' => '膀',
  '�I' => '膏',
  '�J' => '膈',
  '�K' => '膊',
  '�L' => '腿',
  '�M' => '膂',
  '�N' => '臧',
  '�O' => '臺',
  '�P' => '與',
  '�Q' => '舔',
  '�R' => '舞',
  '�S' => '艋',
  '�T' => '蓉',
  '�U' => '蒿',
  '�V' => '蓆',
  '�W' => '蓄',
  '�X' => '蒙',
  '�Y' => '蒞',
  '�Z' => '蒲',
  '�[' => '蒜',
  '�\\' => '蓋',
  '�]' => '蒸',
  '�^' => '蓀',
  '�_' => '蓓',
  '�`' => '蒐',
  '�a' => '蒼',
  '�b' => '蓑',
  '�c' => '蓊',
  '�d' => '蜿',
  '�e' => '蜜',
  '�f' => '蜻',
  '�g' => '蜢',
  '�h' => '蜥',
  '�i' => '蜴',
  '�j' => '蜘',
  '�k' => '蝕',
  '�l' => '蜷',
  '�m' => '蜩',
  '�n' => '裳',
  '�o' => '褂',
  '�p' => '裴',
  '�q' => '裹',
  '�r' => '裸',
  '�s' => '製',
  '�t' => '裨',
  '�u' => '褚',
  '�v' => '裯',
  '�w' => '誦',
  '�x' => '誌',
  '�y' => '語',
  '�z' => '誣',
  '�{' => '認',
  '�|' => '誡',
  '�}' => '誓',
  '�~' => '誤',
  '��' => '說',
  '��' => '誥',
  '��' => '誨',
  '��' => '誘',
  '��' => '誑',
  '��' => '誚',
  '��' => '誧',
  '��' => '豪',
  '��' => '貍',
  '��' => '貌',
  '��' => '賓',
  '��' => '賑',
  '��' => '賒',
  '��' => '赫',
  '��' => '趙',
  '��' => '趕',
  '��' => '跼',
  '��' => '輔',
  '��' => '輒',
  '��' => '輕',
  '��' => '輓',
  '��' => '辣',
  '��' => '遠',
  '��' => '遘',
  '��' => '遜',
  '��' => '遣',
  '��' => '遙',
  '��' => '遞',
  '��' => '遢',
  '��' => '遝',
  '��' => '遛',
  '��' => '鄙',
  '��' => '鄘',
  '��' => '鄞',
  '��' => '酵',
  '��' => '酸',
  '��' => '酷',
  '��' => '酴',
  '��' => '鉸',
  '��' => '銀',
  '��' => '銅',
  '��' => '銘',
  '��' => '銖',
  '��' => '鉻',
  '��' => '銓',
  '��' => '銜',
  '��' => '銨',
  '��' => '鉼',
  '��' => '銑',
  '��' => '閡',
  '��' => '閨',
  '��' => '閩',
  '��' => '閣',
  '��' => '閥',
  '��' => '閤',
  '��' => '隙',
  '��' => '障',
  '��' => '際',
  '��' => '雌',
  '��' => '雒',
  '��' => '需',
  '��' => '靼',
  '��' => '鞅',
  '��' => '韶',
  '��' => '頗',
  '��' => '領',
  '��' => '颯',
  '��' => '颱',
  '��' => '餃',
  '��' => '餅',
  '��' => '餌',
  '��' => '餉',
  '��' => '駁',
  '��' => '骯',
  '��' => '骰',
  '��' => '髦',
  '��' => '魁',
  '��' => '魂',
  '��' => '鳴',
  '��' => '鳶',
  '��' => '鳳',
  '��' => '麼',
  '��' => '鼻',
  '��' => '齊',
  '��' => '億',
  '��' => '儀',
  '��' => '僻',
  '��' => '僵',
  '��' => '價',
  '��' => '儂',
  '��' => '儈',
  '��' => '儉',
  '��' => '儅',
  '��' => '凜',
  '�@' => '劇',
  '�A' => '劈',
  '�B' => '劉',
  '�C' => '劍',
  '�D' => '劊',
  '�E' => '勰',
  '�F' => '厲',
  '�G' => '嘮',
  '�H' => '嘻',
  '�I' => '嘹',
  '�J' => '嘲',
  '�K' => '嘿',
  '�L' => '嘴',
  '�M' => '嘩',
  '�N' => '噓',
  '�O' => '噎',
  '�P' => '噗',
  '�Q' => '噴',
  '�R' => '嘶',
  '�S' => '嘯',
  '�T' => '嘰',
  '�U' => '墀',
  '�V' => '墟',
  '�W' => '增',
  '�X' => '墳',
  '�Y' => '墜',
  '�Z' => '墮',
  '�[' => '墩',
  '�\\' => '墦',
  '�]' => '奭',
  '�^' => '嬉',
  '�_' => '嫻',
  '�`' => '嬋',
  '�a' => '嫵',
  '�b' => '嬌',
  '�c' => '嬈',
  '�d' => '寮',
  '�e' => '寬',
  '�f' => '審',
  '�g' => '寫',
  '�h' => '層',
  '�i' => '履',
  '�j' => '嶝',
  '�k' => '嶔',
  '�l' => '幢',
  '�m' => '幟',
  '�n' => '幡',
  '�o' => '廢',
  '�p' => '廚',
  '�q' => '廟',
  '�r' => '廝',
  '�s' => '廣',
  '�t' => '廠',
  '�u' => '彈',
  '�v' => '影',
  '�w' => '德',
  '�x' => '徵',
  '�y' => '慶',
  '�z' => '慧',
  '�{' => '慮',
  '�|' => '慝',
  '�}' => '慕',
  '�~' => '憂',
  '��' => '慼',
  '��' => '慰',
  '��' => '慫',
  '��' => '慾',
  '��' => '憧',
  '��' => '憐',
  '��' => '憫',
  '��' => '憎',
  '��' => '憬',
  '��' => '憚',
  '��' => '憤',
  '��' => '憔',
  '��' => '憮',
  '��' => '戮',
  '��' => '摩',
  '��' => '摯',
  '��' => '摹',
  '��' => '撞',
  '��' => '撲',
  '��' => '撈',
  '��' => '撐',
  '��' => '撰',
  '��' => '撥',
  '��' => '撓',
  '��' => '撕',
  '��' => '撩',
  '��' => '撒',
  '��' => '撮',
  '��' => '播',
  '��' => '撫',
  '��' => '撚',
  '��' => '撬',
  '��' => '撙',
  '��' => '撢',
  '��' => '撳',
  '��' => '敵',
  '��' => '敷',
  '��' => '數',
  '��' => '暮',
  '��' => '暫',
  '��' => '暴',
  '��' => '暱',
  '��' => '樣',
  '��' => '樟',
  '��' => '槨',
  '��' => '樁',
  '��' => '樞',
  '��' => '標',
  '��' => '槽',
  '��' => '模',
  '��' => '樓',
  '��' => '樊',
  '��' => '槳',
  '��' => '樂',
  '��' => '樅',
  '��' => '槭',
  '��' => '樑',
  '��' => '歐',
  '��' => '歎',
  '��' => '殤',
  '��' => '毅',
  '��' => '毆',
  '��' => '漿',
  '��' => '潼',
  '��' => '澄',
  '��' => '潑',
  '��' => '潦',
  '��' => '潔',
  '��' => '澆',
  '��' => '潭',
  '��' => '潛',
  '��' => '潸',
  '��' => '潮',
  '��' => '澎',
  '��' => '潺',
  '��' => '潰',
  '��' => '潤',
  '��' => '澗',
  '��' => '潘',
  '��' => '滕',
  '��' => '潯',
  '��' => '潠',
  '��' => '潟',
  '��' => '熟',
  '��' => '熬',
  '��' => '熱',
  '��' => '熨',
  '��' => '牖',
  '��' => '犛',
  '��' => '獎',
  '��' => '獗',
  '��' => '瑩',
  '��' => '璋',
  '��' => '璃',
  '�@' => '瑾',
  '�A' => '璀',
  '�B' => '畿',
  '�C' => '瘠',
  '�D' => '瘩',
  '�E' => '瘟',
  '�F' => '瘤',
  '�G' => '瘦',
  '�H' => '瘡',
  '�I' => '瘢',
  '�J' => '皚',
  '�K' => '皺',
  '�L' => '盤',
  '�M' => '瞎',
  '�N' => '瞇',
  '�O' => '瞌',
  '�P' => '瞑',
  '�Q' => '瞋',
  '�R' => '磋',
  '�S' => '磅',
  '�T' => '確',
  '�U' => '磊',
  '�V' => '碾',
  '�W' => '磕',
  '�X' => '碼',
  '�Y' => '磐',
  '�Z' => '稿',
  '�[' => '稼',
  '�\\' => '穀',
  '�]' => '稽',
  '�^' => '稷',
  '�_' => '稻',
  '�`' => '窯',
  '�a' => '窮',
  '�b' => '箭',
  '�c' => '箱',
  '�d' => '範',
  '�e' => '箴',
  '�f' => '篆',
  '�g' => '篇',
  '�h' => '篁',
  '�i' => '箠',
  '�j' => '篌',
  '�k' => '糊',
  '�l' => '締',
  '�m' => '練',
  '�n' => '緯',
  '�o' => '緻',
  '�p' => '緘',
  '�q' => '緬',
  '�r' => '緝',
  '�s' => '編',
  '�t' => '緣',
  '�u' => '線',
  '�v' => '緞',
  '�w' => '緩',
  '�x' => '綞',
  '�y' => '緙',
  '�z' => '緲',
  '�{' => '緹',
  '�|' => '罵',
  '�}' => '罷',
  '�~' => '羯',
  '��' => '翩',
  '��' => '耦',
  '��' => '膛',
  '��' => '膜',
  '��' => '膝',
  '��' => '膠',
  '��' => '膚',
  '��' => '膘',
  '��' => '蔗',
  '��' => '蔽',
  '��' => '蔚',
  '��' => '蓮',
  '��' => '蔬',
  '��' => '蔭',
  '��' => '蔓',
  '��' => '蔑',
  '��' => '蔣',
  '��' => '蔡',
  '��' => '蔔',
  '��' => '蓬',
  '��' => '蔥',
  '��' => '蓿',
  '��' => '蔆',
  '��' => '螂',
  '��' => '蝴',
  '��' => '蝶',
  '��' => '蝠',
  '��' => '蝦',
  '��' => '蝸',
  '��' => '蝨',
  '��' => '蝙',
  '��' => '蝗',
  '��' => '蝌',
  '��' => '蝓',
  '��' => '衛',
  '��' => '衝',
  '��' => '褐',
  '��' => '複',
  '��' => '褒',
  '��' => '褓',
  '��' => '褕',
  '��' => '褊',
  '��' => '誼',
  '��' => '諒',
  '��' => '談',
  '��' => '諄',
  '��' => '誕',
  '��' => '請',
  '��' => '諸',
  '��' => '課',
  '��' => '諉',
  '��' => '諂',
  '��' => '調',
  '��' => '誰',
  '��' => '論',
  '��' => '諍',
  '��' => '誶',
  '��' => '誹',
  '��' => '諛',
  '��' => '豌',
  '��' => '豎',
  '��' => '豬',
  '��' => '賠',
  '��' => '賞',
  '��' => '賦',
  '��' => '賤',
  '��' => '賬',
  '��' => '賭',
  '��' => '賢',
  '��' => '賣',
  '��' => '賜',
  '��' => '質',
  '��' => '賡',
  '��' => '赭',
  '��' => '趟',
  '��' => '趣',
  '��' => '踫',
  '��' => '踐',
  '��' => '踝',
  '��' => '踢',
  '��' => '踏',
  '��' => '踩',
  '��' => '踟',
  '��' => '踡',
  '��' => '踞',
  '��' => '躺',
  '��' => '輝',
  '��' => '輛',
  '��' => '輟',
  '��' => '輩',
  '��' => '輦',
  '��' => '輪',
  '��' => '輜',
  '��' => '輞',
  '�@' => '輥',
  '�A' => '適',
  '�B' => '遮',
  '�C' => '遨',
  '�D' => '遭',
  '�E' => '遷',
  '�F' => '鄰',
  '�G' => '鄭',
  '�H' => '鄧',
  '�I' => '鄱',
  '�J' => '醇',
  '�K' => '醉',
  '�L' => '醋',
  '�M' => '醃',
  '�N' => '鋅',
  '�O' => '銻',
  '�P' => '銷',
  '�Q' => '鋪',
  '�R' => '銬',
  '�S' => '鋤',
  '�T' => '鋁',
  '�U' => '銳',
  '�V' => '銼',
  '�W' => '鋒',
  '�X' => '鋇',
  '�Y' => '鋰',
  '�Z' => '銲',
  '�[' => '閭',
  '�\\' => '閱',
  '�]' => '霄',
  '�^' => '霆',
  '�_' => '震',
  '�`' => '霉',
  '�a' => '靠',
  '�b' => '鞍',
  '�c' => '鞋',
  '�d' => '鞏',
  '�e' => '頡',
  '�f' => '頫',
  '�g' => '頜',
  '�h' => '颳',
  '�i' => '養',
  '�j' => '餓',
  '�k' => '餒',
  '�l' => '餘',
  '�m' => '駝',
  '�n' => '駐',
  '�o' => '駟',
  '�p' => '駛',
  '�q' => '駑',
  '�r' => '駕',
  '�s' => '駒',
  '�t' => '駙',
  '�u' => '骷',
  '�v' => '髮',
  '�w' => '髯',
  '�x' => '鬧',
  '�y' => '魅',
  '�z' => '魄',
  '�{' => '魷',
  '�|' => '魯',
  '�}' => '鴆',
  '�~' => '鴉',
  '��' => '鴃',
  '��' => '麩',
  '��' => '麾',
  '��' => '黎',
  '��' => '墨',
  '��' => '齒',
  '��' => '儒',
  '��' => '儘',
  '��' => '儔',
  '��' => '儐',
  '��' => '儕',
  '��' => '冀',
  '��' => '冪',
  '��' => '凝',
  '��' => '劑',
  '��' => '劓',
  '��' => '勳',
  '��' => '噙',
  '��' => '噫',
  '��' => '噹',
  '��' => '噩',
  '��' => '噤',
  '��' => '噸',
  '��' => '噪',
  '��' => '器',
  '��' => '噥',
  '��' => '噱',
  '��' => '噯',
  '��' => '噬',
  '��' => '噢',
  '��' => '噶',
  '��' => '壁',
  '��' => '墾',
  '��' => '壇',
  '��' => '壅',
  '��' => '奮',
  '��' => '嬝',
  '��' => '嬴',
  '��' => '學',
  '��' => '寰',
  '��' => '導',
  '��' => '彊',
  '��' => '憲',
  '��' => '憑',
  '��' => '憩',
  '��' => '憊',
  '��' => '懍',
  '��' => '憶',
  '��' => '憾',
  '��' => '懊',
  '��' => '懈',
  '��' => '戰',
  '��' => '擅',
  '��' => '擁',
  '��' => '擋',
  '��' => '撻',
  '��' => '撼',
  '��' => '據',
  '��' => '擄',
  '��' => '擇',
  '��' => '擂',
  '��' => '操',
  '��' => '撿',
  '��' => '擒',
  '��' => '擔',
  '��' => '撾',
  '��' => '整',
  '��' => '曆',
  '��' => '曉',
  '��' => '暹',
  '��' => '曄',
  '��' => '曇',
  '��' => '暸',
  '��' => '樽',
  '��' => '樸',
  '��' => '樺',
  '��' => '橙',
  '��' => '橫',
  '��' => '橘',
  '��' => '樹',
  '��' => '橄',
  '��' => '橢',
  '��' => '橡',
  '��' => '橋',
  '��' => '橇',
  '��' => '樵',
  '��' => '機',
  '��' => '橈',
  '��' => '歙',
  '��' => '歷',
  '��' => '氅',
  '��' => '濂',
  '��' => '澱',
  '��' => '澡',
  '�@' => '濃',
  '�A' => '澤',
  '�B' => '濁',
  '�C' => '澧',
  '�D' => '澳',
  '�E' => '激',
  '�F' => '澹',
  '�G' => '澶',
  '�H' => '澦',
  '�I' => '澠',
  '�J' => '澴',
  '�K' => '熾',
  '�L' => '燉',
  '�M' => '燐',
  '�N' => '燒',
  '�O' => '燈',
  '�P' => '燕',
  '�Q' => '熹',
  '�R' => '燎',
  '�S' => '燙',
  '�T' => '燜',
  '�U' => '燃',
  '�V' => '燄',
  '�W' => '獨',
  '�X' => '璜',
  '�Y' => '璣',
  '�Z' => '璘',
  '�[' => '璟',
  '�\\' => '璞',
  '�]' => '瓢',
  '�^' => '甌',
  '�_' => '甍',
  '�`' => '瘴',
  '�a' => '瘸',
  '�b' => '瘺',
  '�c' => '盧',
  '�d' => '盥',
  '�e' => '瞠',
  '�f' => '瞞',
  '�g' => '瞟',
  '�h' => '瞥',
  '�i' => '磨',
  '�j' => '磚',
  '�k' => '磬',
  '�l' => '磧',
  '�m' => '禦',
  '�n' => '積',
  '�o' => '穎',
  '�p' => '穆',
  '�q' => '穌',
  '�r' => '穋',
  '�s' => '窺',
  '�t' => '篙',
  '�u' => '簑',
  '�v' => '築',
  '�w' => '篤',
  '�x' => '篛',
  '�y' => '篡',
  '�z' => '篩',
  '�{' => '篦',
  '�|' => '糕',
  '�}' => '糖',
  '�~' => '縊',
  '��' => '縑',
  '��' => '縈',
  '��' => '縛',
  '��' => '縣',
  '��' => '縞',
  '��' => '縝',
  '��' => '縉',
  '��' => '縐',
  '��' => '罹',
  '��' => '羲',
  '��' => '翰',
  '��' => '翱',
  '��' => '翮',
  '��' => '耨',
  '��' => '膳',
  '��' => '膩',
  '��' => '膨',
  '��' => '臻',
  '��' => '興',
  '��' => '艘',
  '��' => '艙',
  '��' => '蕊',
  '��' => '蕙',
  '��' => '蕈',
  '��' => '蕨',
  '��' => '蕩',
  '��' => '蕃',
  '��' => '蕉',
  '��' => '蕭',
  '��' => '蕪',
  '��' => '蕞',
  '��' => '螃',
  '��' => '螟',
  '��' => '螞',
  '��' => '螢',
  '��' => '融',
  '��' => '衡',
  '��' => '褪',
  '��' => '褲',
  '��' => '褥',
  '��' => '褫',
  '��' => '褡',
  '��' => '親',
  '��' => '覦',
  '��' => '諦',
  '��' => '諺',
  '��' => '諫',
  '��' => '諱',
  '��' => '謀',
  '��' => '諜',
  '��' => '諧',
  '��' => '諮',
  '��' => '諾',
  '��' => '謁',
  '��' => '謂',
  '��' => '諷',
  '��' => '諭',
  '��' => '諳',
  '��' => '諶',
  '��' => '諼',
  '��' => '豫',
  '��' => '豭',
  '��' => '貓',
  '��' => '賴',
  '��' => '蹄',
  '��' => '踱',
  '��' => '踴',
  '��' => '蹂',
  '��' => '踹',
  '��' => '踵',
  '��' => '輻',
  '��' => '輯',
  '��' => '輸',
  '��' => '輳',
  '��' => '辨',
  '��' => '辦',
  '��' => '遵',
  '��' => '遴',
  '��' => '選',
  '��' => '遲',
  '��' => '遼',
  '��' => '遺',
  '��' => '鄴',
  '��' => '醒',
  '��' => '錠',
  '��' => '錶',
  '��' => '鋸',
  '��' => '錳',
  '��' => '錯',
  '��' => '錢',
  '��' => '鋼',
  '��' => '錫',
  '��' => '錄',
  '��' => '錚',
  '�@' => '錐',
  '�A' => '錦',
  '�B' => '錡',
  '�C' => '錕',
  '�D' => '錮',
  '�E' => '錙',
  '�F' => '閻',
  '�G' => '隧',
  '�H' => '隨',
  '�I' => '險',
  '�J' => '雕',
  '�K' => '霎',
  '�L' => '霑',
  '�M' => '霖',
  '�N' => '霍',
  '�O' => '霓',
  '�P' => '霏',
  '�Q' => '靛',
  '�R' => '靜',
  '�S' => '靦',
  '�T' => '鞘',
  '�U' => '頰',
  '�V' => '頸',
  '�W' => '頻',
  '�X' => '頷',
  '�Y' => '頭',
  '�Z' => '頹',
  '�[' => '頤',
  '�\\' => '餐',
  '�]' => '館',
  '�^' => '餞',
  '�_' => '餛',
  '�`' => '餡',
  '�a' => '餚',
  '�b' => '駭',
  '�c' => '駢',
  '�d' => '駱',
  '�e' => '骸',
  '�f' => '骼',
  '�g' => '髻',
  '�h' => '髭',
  '�i' => '鬨',
  '�j' => '鮑',
  '�k' => '鴕',
  '�l' => '鴣',
  '�m' => '鴦',
  '�n' => '鴨',
  '�o' => '鴒',
  '�p' => '鴛',
  '�q' => '默',
  '�r' => '黔',
  '�s' => '龍',
  '�t' => '龜',
  '�u' => '優',
  '�v' => '償',
  '�w' => '儡',
  '�x' => '儲',
  '�y' => '勵',
  '�z' => '嚎',
  '�{' => '嚀',
  '�|' => '嚐',
  '�}' => '嚅',
  '�~' => '嚇',
  '��' => '嚏',
  '��' => '壕',
  '��' => '壓',
  '��' => '壑',
  '��' => '壎',
  '��' => '嬰',
  '��' => '嬪',
  '��' => '嬤',
  '��' => '孺',
  '��' => '尷',
  '��' => '屨',
  '��' => '嶼',
  '��' => '嶺',
  '��' => '嶽',
  '��' => '嶸',
  '��' => '幫',
  '��' => '彌',
  '��' => '徽',
  '��' => '應',
  '��' => '懂',
  '��' => '懇',
  '��' => '懦',
  '��' => '懋',
  '��' => '戲',
  '��' => '戴',
  '��' => '擎',
  '��' => '擊',
  '��' => '擘',
  '��' => '擠',
  '��' => '擰',
  '��' => '擦',
  '��' => '擬',
  '��' => '擱',
  '��' => '擢',
  '��' => '擭',
  '��' => '斂',
  '��' => '斃',
  '��' => '曙',
  '��' => '曖',
  '��' => '檀',
  '��' => '檔',
  '��' => '檄',
  '��' => '檢',
  '��' => '檜',
  '��' => '櫛',
  '��' => '檣',
  '��' => '橾',
  '��' => '檗',
  '��' => '檐',
  '��' => '檠',
  '��' => '歜',
  '��' => '殮',
  '��' => '毚',
  '��' => '氈',
  '��' => '濘',
  '��' => '濱',
  '��' => '濟',
  '��' => '濠',
  '��' => '濛',
  '��' => '濤',
  '��' => '濫',
  '��' => '濯',
  '��' => '澀',
  '��' => '濬',
  '��' => '濡',
  '��' => '濩',
  '��' => '濕',
  '��' => '濮',
  '��' => '濰',
  '��' => '燧',
  '��' => '營',
  '��' => '燮',
  '��' => '燦',
  '��' => '燥',
  '��' => '燭',
  '��' => '燬',
  '��' => '燴',
  '��' => '燠',
  '��' => '爵',
  '��' => '牆',
  '��' => '獰',
  '��' => '獲',
  '��' => '璩',
  '��' => '環',
  '��' => '璦',
  '��' => '璨',
  '��' => '癆',
  '��' => '療',
  '��' => '癌',
  '��' => '盪',
  '��' => '瞳',
  '��' => '瞪',
  '��' => '瞰',
  '��' => '瞬',
  '�@' => '瞧',
  '�A' => '瞭',
  '�B' => '矯',
  '�C' => '磷',
  '�D' => '磺',
  '�E' => '磴',
  '�F' => '磯',
  '�G' => '礁',
  '�H' => '禧',
  '�I' => '禪',
  '�J' => '穗',
  '�K' => '窿',
  '�L' => '簇',
  '�M' => '簍',
  '�N' => '篾',
  '�O' => '篷',
  '�P' => '簌',
  '�Q' => '篠',
  '�R' => '糠',
  '�S' => '糜',
  '�T' => '糞',
  '�U' => '糢',
  '�V' => '糟',
  '�W' => '糙',
  '�X' => '糝',
  '�Y' => '縮',
  '�Z' => '績',
  '�[' => '繆',
  '�\\' => '縷',
  '�]' => '縲',
  '�^' => '繃',
  '�_' => '縫',
  '�`' => '總',
  '�a' => '縱',
  '�b' => '繅',
  '�c' => '繁',
  '�d' => '縴',
  '�e' => '縹',
  '�f' => '繈',
  '�g' => '縵',
  '�h' => '縿',
  '�i' => '縯',
  '�j' => '罄',
  '�k' => '翳',
  '�l' => '翼',
  '�m' => '聱',
  '�n' => '聲',
  '�o' => '聰',
  '�p' => '聯',
  '�q' => '聳',
  '�r' => '臆',
  '�s' => '臃',
  '�t' => '膺',
  '�u' => '臂',
  '�v' => '臀',
  '�w' => '膿',
  '�x' => '膽',
  '�y' => '臉',
  '�z' => '膾',
  '�{' => '臨',
  '�|' => '舉',
  '�}' => '艱',
  '�~' => '薪',
  '��' => '薄',
  '��' => '蕾',
  '��' => '薜',
  '��' => '薑',
  '��' => '薔',
  '��' => '薯',
  '��' => '薛',
  '��' => '薇',
  '��' => '薨',
  '��' => '薊',
  '��' => '虧',
  '��' => '蟀',
  '��' => '蟑',
  '��' => '螳',
  '��' => '蟒',
  '��' => '蟆',
  '��' => '螫',
  '��' => '螻',
  '��' => '螺',
  '��' => '蟈',
  '��' => '蟋',
  '��' => '褻',
  '��' => '褶',
  '��' => '襄',
  '��' => '褸',
  '��' => '褽',
  '��' => '覬',
  '��' => '謎',
  '��' => '謗',
  '��' => '謙',
  '��' => '講',
  '��' => '謊',
  '��' => '謠',
  '��' => '謝',
  '��' => '謄',
  '��' => '謐',
  '��' => '豁',
  '��' => '谿',
  '��' => '豳',
  '��' => '賺',
  '��' => '賽',
  '��' => '購',
  '��' => '賸',
  '��' => '賻',
  '��' => '趨',
  '��' => '蹉',
  '��' => '蹋',
  '��' => '蹈',
  '��' => '蹊',
  '��' => '轄',
  '��' => '輾',
  '��' => '轂',
  '��' => '轅',
  '��' => '輿',
  '��' => '避',
  '��' => '遽',
  '��' => '還',
  '��' => '邁',
  '��' => '邂',
  '��' => '邀',
  '��' => '鄹',
  '��' => '醣',
  '��' => '醞',
  '��' => '醜',
  '��' => '鍍',
  '��' => '鎂',
  '��' => '錨',
  '��' => '鍵',
  '��' => '鍊',
  '��' => '鍥',
  '��' => '鍋',
  '��' => '錘',
  '��' => '鍾',
  '��' => '鍬',
  '��' => '鍛',
  '��' => '鍰',
  '��' => '鍚',
  '��' => '鍔',
  '��' => '闊',
  '��' => '闋',
  '��' => '闌',
  '��' => '闈',
  '��' => '闆',
  '��' => '隱',
  '��' => '隸',
  '��' => '雖',
  '��' => '霜',
  '��' => '霞',
  '��' => '鞠',
  '��' => '韓',
  '��' => '顆',
  '��' => '颶',
  '��' => '餵',
  '��' => '騁',
  '�@' => '駿',
  '�A' => '鮮',
  '�B' => '鮫',
  '�C' => '鮪',
  '�D' => '鮭',
  '�E' => '鴻',
  '�F' => '鴿',
  '�G' => '麋',
  '�H' => '黏',
  '�I' => '點',
  '�J' => '黜',
  '�K' => '黝',
  '�L' => '黛',
  '�M' => '鼾',
  '�N' => '齋',
  '�O' => '叢',
  '�P' => '嚕',
  '�Q' => '嚮',
  '�R' => '壙',
  '�S' => '壘',
  '�T' => '嬸',
  '�U' => '彝',
  '�V' => '懣',
  '�W' => '戳',
  '�X' => '擴',
  '�Y' => '擲',
  '�Z' => '擾',
  '�[' => '攆',
  '�\\' => '擺',
  '�]' => '擻',
  '�^' => '擷',
  '�_' => '斷',
  '�`' => '曜',
  '�a' => '朦',
  '�b' => '檳',
  '�c' => '檬',
  '�d' => '櫃',
  '�e' => '檻',
  '�f' => '檸',
  '�g' => '櫂',
  '�h' => '檮',
  '�i' => '檯',
  '�j' => '歟',
  '�k' => '歸',
  '�l' => '殯',
  '�m' => '瀉',
  '�n' => '瀋',
  '�o' => '濾',
  '�p' => '瀆',
  '�q' => '濺',
  '�r' => '瀑',
  '�s' => '瀏',
  '�t' => '燻',
  '�u' => '燼',
  '�v' => '燾',
  '�w' => '燸',
  '�x' => '獷',
  '�y' => '獵',
  '�z' => '璧',
  '�{' => '璿',
  '�|' => '甕',
  '�}' => '癖',
  '�~' => '癘',
  '¡' => '癒',
  '¢' => '瞽',
  '£' => '瞿',
  '¤' => '瞻',
  '¥' => '瞼',
  '¦' => '礎',
  '§' => '禮',
  '¨' => '穡',
  '©' => '穢',
  'ª' => '穠',
  '«' => '竄',
  '¬' => '竅',
  '­' => '簫',
  '®' => '簧',
  '¯' => '簪',
  '°' => '簞',
  '±' => '簣',
  '²' => '簡',
  '³' => '糧',
  '´' => '織',
  'µ' => '繕',
  '¶' => '繞',
  '·' => '繚',
  '¸' => '繡',
  '¹' => '繒',
  'º' => '繙',
  '»' => '罈',
  '¼' => '翹',
  '½' => '翻',
  '¾' => '職',
  '¿' => '聶',
  '�' => '臍',
  '�' => '臏',
  '��' => '舊',
  '��' => '藏',
  '��' => '薩',
  '��' => '藍',
  '��' => '藐',
  '��' => '藉',
  '��' => '薰',
  '��' => '薺',
  '��' => '薹',
  '��' => '薦',
  '��' => '蟯',
  '��' => '蟬',
  '��' => '蟲',
  '��' => '蟠',
  '��' => '覆',
  '��' => '覲',
  '��' => '觴',
  '��' => '謨',
  '��' => '謹',
  '��' => '謬',
  '��' => '謫',
  '��' => '豐',
  '��' => '贅',
  '��' => '蹙',
  '��' => '蹣',
  '��' => '蹦',
  '��' => '蹤',
  '��' => '蹟',
  '��' => '蹕',
  '��' => '軀',
  '��' => '轉',
  '��' => '轍',
  '��' => '邇',
  '��' => '邃',
  '��' => '邈',
  '��' => '醫',
  '��' => '醬',
  '��' => '釐',
  '��' => '鎔',
  '��' => '鎊',
  '��' => '鎖',
  '��' => '鎢',
  '��' => '鎳',
  '��' => '鎮',
  '��' => '鎬',
  '��' => '鎰',
  '��' => '鎘',
  '��' => '鎚',
  '��' => '鎗',
  '��' => '闔',
  '��' => '闖',
  '�' => '闐',
  '�' => '闕',
  '�' => '離',
  '�' => '雜',
  '�' => '雙',
  '�' => '雛',
  '�' => '雞',
  '�' => '霤',
  '�' => '鞣',
  '�' => '鞦',
  '�@' => '鞭',
  '�A' => '韹',
  '�B' => '額',
  '�C' => '顏',
  '�D' => '題',
  '�E' => '顎',
  '�F' => '顓',
  '�G' => '颺',
  '�H' => '餾',
  '�I' => '餿',
  '�J' => '餽',
  '�K' => '餮',
  '�L' => '馥',
  '�M' => '騎',
  '�N' => '髁',
  '�O' => '鬃',
  '�P' => '鬆',
  '�Q' => '魏',
  '�R' => '魎',
  '�S' => '魍',
  '�T' => '鯊',
  '�U' => '鯉',
  '�V' => '鯽',
  '�W' => '鯈',
  '�X' => '鯀',
  '�Y' => '鵑',
  '�Z' => '鵝',
  '�[' => '鵠',
  '�\\' => '黠',
  '�]' => '鼕',
  '�^' => '鼬',
  '�_' => '儳',
  '�`' => '嚥',
  '�a' => '壞',
  '�b' => '壟',
  '�c' => '壢',
  '�d' => '寵',
  '�e' => '龐',
  '�f' => '廬',
  '�g' => '懲',
  '�h' => '懷',
  '�i' => '懶',
  '�j' => '懵',
  '�k' => '攀',
  '�l' => '攏',
  '�m' => '曠',
  '�n' => '曝',
  '�o' => '櫥',
  '�p' => '櫝',
  '�q' => '櫚',
  '�r' => '櫓',
  '�s' => '瀛',
  '�t' => '瀟',
  '�u' => '瀨',
  '�v' => '瀚',
  '�w' => '瀝',
  '�x' => '瀕',
  '�y' => '瀘',
  '�z' => '爆',
  '�{' => '爍',
  '�|' => '牘',
  '�}' => '犢',
  '�~' => '獸',
  'á' => '獺',
  'â' => '璽',
  'ã' => '瓊',
  'ä' => '瓣',
  'å' => '疇',
  'æ' => '疆',
  'ç' => '癟',
  'è' => '癡',
  'é' => '矇',
  'ê' => '礙',
  'ë' => '禱',
  'ì' => '穫',
  'í' => '穩',
  'î' => '簾',
  'ï' => '簿',
  'ð' => '簸',
  'ñ' => '簽',
  'ò' => '簷',
  'ó' => '籀',
  'ô' => '繫',
  'õ' => '繭',
  'ö' => '繹',
  '÷' => '繩',
  'ø' => '繪',
  'ù' => '羅',
  'ú' => '繳',
  'û' => '羶',
  'ü' => '羹',
  'ý' => '羸',
  'þ' => '臘',
  'ÿ' => '藩',
  '�' => '藝',
  '�' => '藪',
  '��' => '藕',
  '��' => '藤',
  '��' => '藥',
  '��' => '藷',
  '��' => '蟻',
  '��' => '蠅',
  '��' => '蠍',
  '��' => '蟹',
  '��' => '蟾',
  '��' => '襠',
  '��' => '襟',
  '��' => '襖',
  '��' => '襞',
  '��' => '譁',
  '��' => '譜',
  '��' => '識',
  '��' => '證',
  '��' => '譚',
  '��' => '譎',
  '��' => '譏',
  '��' => '譆',
  '��' => '譙',
  '��' => '贈',
  '��' => '贊',
  '��' => '蹼',
  '��' => '蹲',
  '��' => '躇',
  '��' => '蹶',
  '��' => '蹬',
  '��' => '蹺',
  '��' => '蹴',
  '��' => '轔',
  '��' => '轎',
  '��' => '辭',
  '��' => '邊',
  '��' => '邋',
  '��' => '醱',
  '��' => '醮',
  '��' => '鏡',
  '��' => '鏑',
  '��' => '鏟',
  '��' => '鏃',
  '��' => '鏈',
  '��' => '鏜',
  '��' => '鏝',
  '��' => '鏖',
  '��' => '鏢',
  '��' => '鏍',
  '��' => '鏘',
  '��' => '鏤',
  '��' => '鏗',
  '�' => '鏨',
  '�' => '關',
  '�' => '隴',
  '�' => '難',
  '�' => '霪',
  '�' => '霧',
  '�' => '靡',
  '�' => '韜',
  '�' => '韻',
  '�' => '類',
  '�@' => '願',
  '�A' => '顛',
  '�B' => '颼',
  '�C' => '饅',
  '�D' => '饉',
  '�E' => '騖',
  '�F' => '騙',
  '�G' => '鬍',
  '�H' => '鯨',
  '�I' => '鯧',
  '�J' => '鯖',
  '�K' => '鯛',
  '�L' => '鶉',
  '�M' => '鵡',
  '�N' => '鵲',
  '�O' => '鵪',
  '�P' => '鵬',
  '�Q' => '麒',
  '�R' => '麗',
  '�S' => '麓',
  '�T' => '麴',
  '�U' => '勸',
  '�V' => '嚨',
  '�W' => '嚷',
  '�X' => '嚶',
  '�Y' => '嚴',
  '�Z' => '嚼',
  '�[' => '壤',
  '�\\' => '孀',
  '�]' => '孃',
  '�^' => '孽',
  '�_' => '寶',
  '�`' => '巉',
  '�a' => '懸',
  '�b' => '懺',
  '�c' => '攘',
  '�d' => '攔',
  '�e' => '攙',
  '�f' => '曦',
  '�g' => '朧',
  '�h' => '櫬',
  '�i' => '瀾',
  '�j' => '瀰',
  '�k' => '瀲',
  '�l' => '爐',
  '�m' => '獻',
  '�n' => '瓏',
  '�o' => '癢',
  '�p' => '癥',
  '�q' => '礦',
  '�r' => '礪',
  '�s' => '礬',
  '�t' => '礫',
  '�u' => '竇',
  '�v' => '競',
  '�w' => '籌',
  '�x' => '籃',
  '�y' => '籍',
  '�z' => '糯',
  '�{' => '糰',
  '�|' => '辮',
  '�}' => '繽',
  '�~' => '繼',
  'ġ' => '纂',
  'Ģ' => '罌',
  'ģ' => '耀',
  'Ĥ' => '臚',
  'ĥ' => '艦',
  'Ħ' => '藻',
  'ħ' => '藹',
  'Ĩ' => '蘑',
  'ĩ' => '藺',
  'Ī' => '蘆',
  'ī' => '蘋',
  'Ĭ' => '蘇',
  'ĭ' => '蘊',
  'Į' => '蠔',
  'į' => '蠕',
  'İ' => '襤',
  'ı' => '覺',
  'IJ' => '觸',
  'ij' => '議',
  'Ĵ' => '譬',
  'ĵ' => '警',
  'Ķ' => '譯',
  'ķ' => '譟',
  'ĸ' => '譫',
  'Ĺ' => '贏',
  'ĺ' => '贍',
  'Ļ' => '躉',
  'ļ' => '躁',
  'Ľ' => '躅',
  'ľ' => '躂',
  'Ŀ' => '醴',
  '�' => '釋',
  '�' => '鐘',
  '��' => '鐃',
  '��' => '鏽',
  '��' => '闡',
  '��' => '霰',
  '��' => '飄',
  '��' => '饒',
  '��' => '饑',
  '��' => '馨',
  '��' => '騫',
  '��' => '騰',
  '��' => '騷',
  '��' => '騵',
  '��' => '鰓',
  '��' => '鰍',
  '��' => '鹹',
  '��' => '麵',
  '��' => '黨',
  '��' => '鼯',
  '��' => '齟',
  '��' => '齣',
  '��' => '齡',
  '��' => '儷',
  '��' => '儸',
  '��' => '囁',
  '��' => '囀',
  '��' => '囂',
  '��' => '夔',
  '��' => '屬',
  '��' => '巍',
  '��' => '懼',
  '��' => '懾',
  '��' => '攝',
  '��' => '攜',
  '��' => '斕',
  '��' => '曩',
  '��' => '櫻',
  '��' => '欄',
  '��' => '櫺',
  '��' => '殲',
  '��' => '灌',
  '��' => '爛',
  '��' => '犧',
  '��' => '瓖',
  '��' => '瓔',
  '��' => '癩',
  '��' => '矓',
  '��' => '籐',
  '��' => '纏',
  '��' => '續',
  '��' => '羼',
  '��' => '蘗',
  '�' => '蘭',
  '�' => '蘚',
  '�' => '蠣',
  '�' => '蠢',
  '�' => '蠡',
  '�' => '蠟',
  '�' => '襪',
  '�' => '襬',
  '�' => '覽',
  '�' => '譴',
  '�@' => '護',
  '�A' => '譽',
  '�B' => '贓',
  '�C' => '躊',
  '�D' => '躍',
  '�E' => '躋',
  '�F' => '轟',
  '�G' => '辯',
  '�H' => '醺',
  '�I' => '鐮',
  '�J' => '鐳',
  '�K' => '鐵',
  '�L' => '鐺',
  '�M' => '鐸',
  '�N' => '鐲',
  '�O' => '鐫',
  '�P' => '闢',
  '�Q' => '霸',
  '�R' => '霹',
  '�S' => '露',
  '�T' => '響',
  '�U' => '顧',
  '�V' => '顥',
  '�W' => '饗',
  '�X' => '驅',
  '�Y' => '驃',
  '�Z' => '驀',
  '�[' => '騾',
  '�\\' => '髏',
  '�]' => '魔',
  '�^' => '魑',
  '�_' => '鰭',
  '�`' => '鰥',
  '�a' => '鶯',
  '�b' => '鶴',
  '�c' => '鷂',
  '�d' => '鶸',
  '�e' => '麝',
  '�f' => '黯',
  '�g' => '鼙',
  '�h' => '齜',
  '�i' => '齦',
  '�j' => '齧',
  '�k' => '儼',
  '�l' => '儻',
  '�m' => '囈',
  '�n' => '囊',
  '�o' => '囉',
  '�p' => '孿',
  '�q' => '巔',
  '�r' => '巒',
  '�s' => '彎',
  '�t' => '懿',
  '�u' => '攤',
  '�v' => '權',
  '�w' => '歡',
  '�x' => '灑',
  '�y' => '灘',
  '�z' => '玀',
  '�{' => '瓤',
  '�|' => '疊',
  '�}' => '癮',
  '�~' => '癬',
  'š' => '禳',
  'Ţ' => '籠',
  'ţ' => '籟',
  'Ť' => '聾',
  'ť' => '聽',
  'Ŧ' => '臟',
  'ŧ' => '襲',
  'Ũ' => '襯',
  'ũ' => '觼',
  'Ū' => '讀',
  'ū' => '贖',
  'Ŭ' => '贗',
  'ŭ' => '躑',
  'Ů' => '躓',
  'ů' => '轡',
  'Ű' => '酈',
  'ű' => '鑄',
  'Ų' => '鑑',
  'ų' => '鑒',
  'Ŵ' => '霽',
  'ŵ' => '霾',
  'Ŷ' => '韃',
  'ŷ' => '韁',
  'Ÿ' => '顫',
  'Ź' => '饕',
  'ź' => '驕',
  'Ż' => '驍',
  'ż' => '髒',
  'Ž' => '鬚',
  'ž' => '鱉',
  'ſ' => '鰱',
  '�' => '鰾',
  '�' => '鰻',
  '��' => '鷓',
  '��' => '鷗',
  '��' => '鼴',
  '��' => '齬',
  '��' => '齪',
  '��' => '龔',
  '��' => '囌',
  '��' => '巖',
  '��' => '戀',
  '��' => '攣',
  '��' => '攫',
  '��' => '攪',
  '��' => '曬',
  '��' => '欐',
  '��' => '瓚',
  '��' => '竊',
  '��' => '籤',
  '��' => '籣',
  '��' => '籥',
  '��' => '纓',
  '��' => '纖',
  '��' => '纔',
  '��' => '臢',
  '��' => '蘸',
  '��' => '蘿',
  '��' => '蠱',
  '��' => '變',
  '��' => '邐',
  '��' => '邏',
  '��' => '鑣',
  '��' => '鑠',
  '��' => '鑤',
  '��' => '靨',
  '��' => '顯',
  '��' => '饜',
  '��' => '驚',
  '��' => '驛',
  '��' => '驗',
  '��' => '髓',
  '��' => '體',
  '��' => '髑',
  '��' => '鱔',
  '��' => '鱗',
  '��' => '鱖',
  '��' => '鷥',
  '��' => '麟',
  '��' => '黴',
  '��' => '囑',
  '��' => '壩',
  '��' => '攬',
  '��' => '灞',
  '�' => '癱',
  '�' => '癲',
  '�' => '矗',
  '�' => '罐',
  '�' => '羈',
  '�' => '蠶',
  '�' => '蠹',
  '�' => '衢',
  '�' => '讓',
  '�' => '讒',
  '�@' => '讖',
  '�A' => '艷',
  '�B' => '贛',
  '�C' => '釀',
  '�D' => '鑪',
  '�E' => '靂',
  '�F' => '靈',
  '�G' => '靄',
  '�H' => '韆',
  '�I' => '顰',
  '�J' => '驟',
  '�K' => '鬢',
  '�L' => '魘',
  '�M' => '鱟',
  '�N' => '鷹',
  '�O' => '鷺',
  '�P' => '鹼',
  '�Q' => '鹽',
  '�R' => '鼇',
  '�S' => '齷',
  '�T' => '齲',
  '�U' => '廳',
  '�V' => '欖',
  '�W' => '灣',
  '�X' => '籬',
  '�Y' => '籮',
  '�Z' => '蠻',
  '�[' => '觀',
  '�\\' => '躡',
  '�]' => '釁',
  '�^' => '鑲',
  '�_' => '鑰',
  '�`' => '顱',
  '�a' => '饞',
  '�b' => '髖',
  '�c' => '鬣',
  '�d' => '黌',
  '�e' => '灤',
  '�f' => '矚',
  '�g' => '讚',
  '�h' => '鑷',
  '�i' => '韉',
  '�j' => '驢',
  '�k' => '驥',
  '�l' => '纜',
  '�m' => '讜',
  '�n' => '躪',
  '�o' => '釅',
  '�p' => '鑽',
  '�q' => '鑾',
  '�r' => '鑼',
  '�s' => '鱷',
  '�t' => '鱸',
  '�u' => '黷',
  '�v' => '豔',
  '�w' => '鑿',
  '�x' => '鸚',
  '�y' => '爨',
  '�z' => '驪',
  '�{' => '鬱',
  '�|' => '鸛',
  '�}' => '鸞',
  '�~' => '籲',
  'ơ' => 'ヾ',
  'Ƣ' => 'ゝ',
  'ƣ' => 'ゞ',
  'Ƥ' => '々',
  'ƥ' => 'ぁ',
  'Ʀ' => 'あ',
  'Ƨ' => 'ぃ',
  'ƨ' => 'い',
  'Ʃ' => 'ぅ',
  'ƪ' => 'う',
  'ƫ' => 'ぇ',
  'Ƭ' => 'え',
  'ƭ' => 'ぉ',
  'Ʈ' => 'お',
  'Ư' => 'か',
  'ư' => 'が',
  'Ʊ' => 'き',
  'Ʋ' => 'ぎ',
  'Ƴ' => 'く',
  'ƴ' => 'ぐ',
  'Ƶ' => 'け',
  'ƶ' => 'げ',
  'Ʒ' => 'こ',
  'Ƹ' => 'ご',
  'ƹ' => 'さ',
  'ƺ' => 'ざ',
  'ƻ' => 'し',
  'Ƽ' => 'じ',
  'ƽ' => 'す',
  'ƾ' => 'ず',
  'ƿ' => 'せ',
  '�' => 'ぜ',
  '�' => 'そ',
  '��' => 'ぞ',
  '��' => 'た',
  '��' => 'だ',
  '��' => 'ち',
  '��' => 'ぢ',
  '��' => 'っ',
  '��' => 'つ',
  '��' => 'づ',
  '��' => 'て',
  '��' => 'で',
  '��' => 'と',
  '��' => 'ど',
  '��' => 'な',
  '��' => 'に',
  '��' => 'ぬ',
  '��' => 'ね',
  '��' => 'の',
  '��' => 'は',
  '��' => 'ば',
  '��' => 'ぱ',
  '��' => 'ひ',
  '��' => 'び',
  '��' => 'ぴ',
  '��' => 'ふ',
  '��' => 'ぶ',
  '��' => 'ぷ',
  '��' => 'へ',
  '��' => 'べ',
  '��' => 'ぺ',
  '��' => 'ほ',
  '��' => 'ぼ',
  '��' => 'ぽ',
  '��' => 'ま',
  '��' => 'み',
  '��' => 'む',
  '��' => 'め',
  '��' => 'も',
  '��' => 'ゃ',
  '��' => 'や',
  '��' => 'ゅ',
  '��' => 'ゆ',
  '��' => 'ょ',
  '��' => 'よ',
  '��' => 'ら',
  '��' => 'り',
  '��' => 'る',
  '��' => 'れ',
  '��' => 'ろ',
  '��' => 'ゎ',
  '��' => 'わ',
  '��' => 'ゐ',
  '�' => 'ゑ',
  '�' => 'を',
  '�' => 'ん',
  '�' => 'ァ',
  '�' => 'ア',
  '�' => 'ィ',
  '�' => 'イ',
  '�' => 'ゥ',
  '�' => 'ウ',
  '�' => 'ェ',
  '�@' => 'エ',
  '�A' => 'ォ',
  '�B' => 'オ',
  '�C' => 'カ',
  '�D' => 'ガ',
  '�E' => 'キ',
  '�F' => 'ギ',
  '�G' => 'ク',
  '�H' => 'グ',
  '�I' => 'ケ',
  '�J' => 'ゲ',
  '�K' => 'コ',
  '�L' => 'ゴ',
  '�M' => 'サ',
  '�N' => 'ザ',
  '�O' => 'シ',
  '�P' => 'ジ',
  '�Q' => 'ス',
  '�R' => 'ズ',
  '�S' => 'セ',
  '�T' => 'ゼ',
  '�U' => 'ソ',
  '�V' => 'ゾ',
  '�W' => 'タ',
  '�X' => 'ダ',
  '�Y' => 'チ',
  '�Z' => 'ヂ',
  '�[' => 'ッ',
  '�\\' => 'ツ',
  '�]' => 'ヅ',
  '�^' => 'テ',
  '�_' => 'デ',
  '�`' => 'ト',
  '�a' => 'ド',
  '�b' => 'ナ',
  '�c' => 'ニ',
  '�d' => 'ヌ',
  '�e' => 'ネ',
  '�f' => 'ノ',
  '�g' => 'ハ',
  '�h' => 'バ',
  '�i' => 'パ',
  '�j' => 'ヒ',
  '�k' => 'ビ',
  '�l' => 'ピ',
  '�m' => 'フ',
  '�n' => 'ブ',
  '�o' => 'プ',
  '�p' => 'ヘ',
  '�q' => 'ベ',
  '�r' => 'ペ',
  '�s' => 'ホ',
  '�t' => 'ボ',
  '�u' => 'ポ',
  '�v' => 'マ',
  '�w' => 'ミ',
  '�x' => 'ム',
  '�y' => 'メ',
  '�z' => 'モ',
  '�{' => 'ャ',
  '�|' => 'ヤ',
  '�}' => 'ュ',
  '�~' => 'ユ',
  'ǡ' => 'ョ',
  'Ǣ' => 'ヨ',
  'ǣ' => 'ラ',
  'Ǥ' => 'リ',
  'ǥ' => 'ル',
  'Ǧ' => 'レ',
  'ǧ' => 'ロ',
  'Ǩ' => 'ヮ',
  'ǩ' => 'ワ',
  'Ǫ' => 'ヰ',
  'ǫ' => 'ヱ',
  'Ǭ' => 'ヲ',
  'ǭ' => 'ン',
  'Ǯ' => 'ヴ',
  'ǯ' => 'ヵ',
  'ǰ' => 'ヶ',
  'DZ' => 'Д',
  'Dz' => 'Е',
  'dz' => 'Ё',
  'Ǵ' => 'Ж',
  'ǵ' => 'З',
  'Ƕ' => 'И',
  'Ƿ' => 'Й',
  'Ǹ' => 'К',
  'ǹ' => 'Л',
  'Ǻ' => 'М',
  'ǻ' => 'У',
  'Ǽ' => 'Ф',
  'ǽ' => 'Х',
  'Ǿ' => 'Ц',
  'ǿ' => 'Ч',
  '�' => 'Ш',
  '�' => 'Щ',
  '��' => 'Ъ',
  '��' => 'Ы',
  '��' => 'Ь',
  '��' => 'Э',
  '��' => 'Ю',
  '��' => 'Я',
  '��' => 'а',
  '��' => 'б',
  '��' => 'в',
  '��' => 'г',
  '��' => 'д',
  '��' => 'е',
  '��' => 'ё',
  '��' => 'ж',
  '��' => 'з',
  '��' => 'и',
  '��' => 'й',
  '��' => 'к',
  '��' => 'л',
  '��' => 'м',
  '��' => 'н',
  '��' => 'о',
  '��' => 'п',
  '��' => 'р',
  '��' => 'с',
  '��' => 'т',
  '��' => 'у',
  '��' => 'ф',
  '��' => 'х',
  '��' => 'ц',
  '��' => 'ч',
  '��' => 'ш',
  '��' => 'щ',
  '��' => 'ъ',
  '��' => 'ы',
  '��' => 'ь',
  '��' => 'э',
  '��' => 'ю',
  '��' => 'я',
  '��' => '①',
  '��' => '②',
  '��' => '③',
  '��' => '④',
  '��' => '⑤',
  '��' => '⑥',
  '��' => '⑦',
  '��' => '⑧',
  '��' => '⑨',
  '��' => '⑩',
  '��' => '⑴',
  '��' => '⑵',
  '�' => '⑶',
  '�' => '⑷',
  '�' => '⑸',
  '�' => '⑹',
  '�' => '⑺',
  '�' => '⑻',
  '�' => '⑼',
  '�' => '⑽',
  '�@' => '乂',
  '�A' => '乜',
  '�B' => '凵',
  '�C' => '匚',
  '�D' => '厂',
  '�E' => '万',
  '�F' => '丌',
  '�G' => '乇',
  '�H' => '亍',
  '�I' => '囗',
  '�J' => '兀',
  '�K' => '屮',
  '�L' => '彳',
  '�M' => '丏',
  '�N' => '冇',
  '�O' => '与',
  '�P' => '丮',
  '�Q' => '亓',
  '�R' => '仂',
  '�S' => '仉',
  '�T' => '仈',
  '�U' => '冘',
  '�V' => '勼',
  '�W' => '卬',
  '�X' => '厹',
  '�Y' => '圠',
  '�Z' => '夃',
  '�[' => '夬',
  '�\\' => '尐',
  '�]' => '巿',
  '�^' => '旡',
  '�_' => '殳',
  '�`' => '毌',
  '�a' => '气',
  '�b' => '爿',
  '�c' => '丱',
  '�d' => '丼',
  '�e' => '仨',
  '�f' => '仜',
  '�g' => '仩',
  '�h' => '仡',
  '�i' => '仝',
  '�j' => '仚',
  '�k' => '刌',
  '�l' => '匜',
  '�m' => '卌',
  '�n' => '圢',
  '�o' => '圣',
  '�p' => '夗',
  '�q' => '夯',
  '�r' => '宁',
  '�s' => '宄',
  '�t' => '尒',
  '�u' => '尻',
  '�v' => '屴',
  '�w' => '屳',
  '�x' => '帄',
  '�y' => '庀',
  '�z' => '庂',
  '�{' => '忉',
  '�|' => '戉',
  '�}' => '扐',
  '�~' => '氕',
  'ɡ' => '氶',
  'ɢ' => '汃',
  'ɣ' => '氿',
  'ɤ' => '氻',
  'ɥ' => '犮',
  'ɦ' => '犰',
  'ɧ' => '玊',
  'ɨ' => '禸',
  'ɩ' => '肊',
  'ɪ' => '阞',
  'ɫ' => '伎',
  'ɬ' => '优',
  'ɭ' => '伬',
  'ɮ' => '仵',
  'ɯ' => '伔',
  'ɰ' => '仱',
  'ɱ' => '伀',
  'ɲ' => '价',
  'ɳ' => '伈',
  'ɴ' => '伝',
  'ɵ' => '伂',
  'ɶ' => '伅',
  'ɷ' => '伢',
  'ɸ' => '伓',
  'ɹ' => '伄',
  'ɺ' => '仴',
  'ɻ' => '伒',
  'ɼ' => '冱',
  'ɽ' => '刓',
  'ɾ' => '刉',
  'ɿ' => '刐',
  '�' => '劦',
  '�' => '匢',
  '��' => '匟',
  '��' => '卍',
  '��' => '厊',
  '��' => '吇',
  '��' => '囡',
  '��' => '囟',
  '��' => '圮',
  '��' => '圪',
  '��' => '圴',
  '��' => '夼',
  '��' => '妀',
  '��' => '奼',
  '��' => '妅',
  '��' => '奻',
  '��' => '奾',
  '��' => '奷',
  '��' => '奿',
  '��' => '孖',
  '��' => '尕',
  '��' => '尥',
  '��' => '屼',
  '��' => '屺',
  '��' => '屻',
  '��' => '屾',
  '��' => '巟',
  '��' => '幵',
  '��' => '庄',
  '��' => '异',
  '��' => '弚',
  '��' => '彴',
  '��' => '忕',
  '��' => '忔',
  '��' => '忏',
  '��' => '扜',
  '��' => '扞',
  '��' => '扤',
  '��' => '扡',
  '��' => '扦',
  '��' => '扢',
  '��' => '扙',
  '��' => '扠',
  '��' => '扚',
  '��' => '扥',
  '��' => '旯',
  '��' => '旮',
  '��' => '朾',
  '��' => '朹',
  '��' => '朸',
  '��' => '朻',
  '��' => '机',
  '��' => '朿',
  '�' => '朼',
  '�' => '朳',
  '�' => '氘',
  '�' => '汆',
  '�' => '汒',
  '�' => '汜',
  '�' => '汏',
  '�' => '汊',
  '�' => '汔',
  '�' => '汋',
  '�@' => '汌',
  '�A' => '灱',
  '�B' => '牞',
  '�C' => '犴',
  '�D' => '犵',
  '�E' => '玎',
  '�F' => '甪',
  '�G' => '癿',
  '�H' => '穵',
  '�I' => '网',
  '�J' => '艸',
  '�K' => '艼',
  '�L' => '芀',
  '�M' => '艽',
  '�N' => '艿',
  '�O' => '虍',
  '�P' => '襾',
  '�Q' => '邙',
  '�R' => '邗',
  '�S' => '邘',
  '�T' => '邛',
  '�U' => '邔',
  '�V' => '阢',
  '�W' => '阤',
  '�X' => '阠',
  '�Y' => '阣',
  '�Z' => '佖',
  '�[' => '伻',
  '�\\' => '佢',
  '�]' => '佉',
  '�^' => '体',
  '�_' => '佤',
  '�`' => '伾',
  '�a' => '佧',
  '�b' => '佒',
  '�c' => '佟',
  '�d' => '佁',
  '�e' => '佘',
  '�f' => '伭',
  '�g' => '伳',
  '�h' => '伿',
  '�i' => '佡',
  '�j' => '冏',
  '�k' => '冹',
  '�l' => '刜',
  '�m' => '刞',
  '�n' => '刡',
  '�o' => '劭',
  '�p' => '劮',
  '�q' => '匉',
  '�r' => '卣',
  '�s' => '卲',
  '�t' => '厎',
  '�u' => '厏',
  '�v' => '吰',
  '�w' => '吷',
  '�x' => '吪',
  '�y' => '呔',
  '�z' => '呅',
  '�{' => '吙',
  '�|' => '吜',
  '�}' => '吥',
  '�~' => '吘',
  'ʡ' => '吽',
  'ʢ' => '呏',
  'ʣ' => '呁',
  'ʤ' => '吨',
  'ʥ' => '吤',
  'ʦ' => '呇',
  'ʧ' => '囮',
  'ʨ' => '囧',
  'ʩ' => '囥',
  'ʪ' => '坁',
  'ʫ' => '坅',
  'ʬ' => '坌',
  'ʭ' => '坉',
  'ʮ' => '坋',
  'ʯ' => '坒',
  'ʰ' => '夆',
  'ʱ' => '奀',
  'ʲ' => '妦',
  'ʳ' => '妘',
  'ʴ' => '妠',
  'ʵ' => '妗',
  'ʶ' => '妎',
  'ʷ' => '妢',
  'ʸ' => '妐',
  'ʹ' => '妏',
  'ʺ' => '妧',
  'ʻ' => '妡',
  'ʼ' => '宎',
  'ʽ' => '宒',
  'ʾ' => '尨',
  'ʿ' => '尪',
  '�' => '岍',
  '�' => '岏',
  '��' => '岈',
  '��' => '岋',
  '��' => '岉',
  '��' => '岒',
  '��' => '岊',
  '��' => '岆',
  '��' => '岓',
  '��' => '岕',
  '��' => '巠',
  '��' => '帊',
  '��' => '帎',
  '��' => '庋',
  '��' => '庉',
  '��' => '庌',
  '��' => '庈',
  '��' => '庍',
  '��' => '弅',
  '��' => '弝',
  '��' => '彸',
  '��' => '彶',
  '��' => '忒',
  '��' => '忑',
  '��' => '忐',
  '��' => '忭',
  '��' => '忨',
  '��' => '忮',
  '��' => '忳',
  '��' => '忡',
  '��' => '忤',
  '��' => '忣',
  '��' => '忺',
  '��' => '忯',
  '��' => '忷',
  '��' => '忻',
  '��' => '怀',
  '��' => '忴',
  '��' => '戺',
  '��' => '抃',
  '��' => '抌',
  '��' => '抎',
  '��' => '抏',
  '��' => '抔',
  '��' => '抇',
  '��' => '扱',
  '��' => '扻',
  '��' => '扺',
  '��' => '扰',
  '��' => '抁',
  '��' => '抈',
  '��' => '扷',
  '��' => '扽',
  '�' => '扲',
  '�' => '扴',
  '�' => '攷',
  '�' => '旰',
  '�' => '旴',
  '�' => '旳',
  '�' => '旲',
  '�' => '旵',
  '�' => '杅',
  '�' => '杇',
  '�@' => '杙',
  '�A' => '杕',
  '�B' => '杌',
  '�C' => '杈',
  '�D' => '杝',
  '�E' => '杍',
  '�F' => '杚',
  '�G' => '杋',
  '�H' => '毐',
  '�I' => '氙',
  '�J' => '氚',
  '�K' => '汸',
  '�L' => '汧',
  '�M' => '汫',
  '�N' => '沄',
  '�O' => '沋',
  '�P' => '沏',
  '�Q' => '汱',
  '�R' => '汯',
  '�S' => '汩',
  '�T' => '沚',
  '�U' => '汭',
  '�V' => '沇',
  '�W' => '沕',
  '�X' => '沜',
  '�Y' => '汦',
  '�Z' => '汳',
  '�[' => '汥',
  '�\\' => '汻',
  '�]' => '沎',
  '�^' => '灴',
  '�_' => '灺',
  '�`' => '牣',
  '�a' => '犿',
  '�b' => '犽',
  '�c' => '狃',
  '�d' => '狆',
  '�e' => '狁',
  '�f' => '犺',
  '�g' => '狅',
  '�h' => '玕',
  '�i' => '玗',
  '�j' => '玓',
  '�k' => '玔',
  '�l' => '玒',
  '�m' => '町',
  '�n' => '甹',
  '�o' => '疔',
  '�p' => '疕',
  '�q' => '皁',
  '�r' => '礽',
  '�s' => '耴',
  '�t' => '肕',
  '�u' => '肙',
  '�v' => '肐',
  '�w' => '肒',
  '�x' => '肜',
  '�y' => '芐',
  '�z' => '芏',
  '�{' => '芅',
  '�|' => '芎',
  '�}' => '芑',
  '�~' => '芓',
  'ˡ' => '芊',
  'ˢ' => '芃',
  'ˣ' => '芄',
  'ˤ' => '豸',
  '˥' => '迉',
  '˦' => '辿',
  '˧' => '邟',
  '˨' => '邡',
  '˩' => '邥',
  '˪' => '邞',
  '˫' => '邧',
  'ˬ' => '邠',
  '˭' => '阰',
  'ˮ' => '阨',
  '˯' => '阯',
  '˰' => '阭',
  '˱' => '丳',
  '˲' => '侘',
  '˳' => '佼',
  '˴' => '侅',
  '˵' => '佽',
  '˶' => '侀',
  '˷' => '侇',
  '˸' => '佶',
  '˹' => '佴',
  '˺' => '侉',
  '˻' => '侄',
  '˼' => '佷',
  '˽' => '佌',
  '˾' => '侗',
  '˿' => '佪',
  '�' => '侚',
  '�' => '佹',
  '��' => '侁',
  '��' => '佸',
  '��' => '侐',
  '��' => '侜',
  '��' => '侔',
  '��' => '侞',
  '��' => '侒',
  '��' => '侂',
  '��' => '侕',
  '��' => '佫',
  '��' => '佮',
  '��' => '冞',
  '��' => '冼',
  '��' => '冾',
  '��' => '刵',
  '��' => '刲',
  '��' => '刳',
  '��' => '剆',
  '��' => '刱',
  '��' => '劼',
  '��' => '匊',
  '��' => '匋',
  '��' => '匼',
  '��' => '厒',
  '��' => '厔',
  '��' => '咇',
  '��' => '呿',
  '��' => '咁',
  '��' => '咑',
  '��' => '咂',
  '��' => '咈',
  '��' => '呫',
  '��' => '呺',
  '��' => '呾',
  '��' => '呥',
  '��' => '呬',
  '��' => '呴',
  '��' => '呦',
  '��' => '咍',
  '��' => '呯',
  '��' => '呡',
  '��' => '呠',
  '��' => '咘',
  '��' => '呣',
  '��' => '呧',
  '��' => '呤',
  '��' => '囷',
  '��' => '囹',
  '��' => '坯',
  '��' => '坲',
  '��' => '坭',
  '�' => '坫',
  '�' => '坱',
  '�' => '坰',
  '�' => '坶',
  '�' => '垀',
  '�' => '坵',
  '�' => '坻',
  '�' => '坳',
  '�' => '坴',
  '�' => '坢',
  '�@' => '坨',
  '�A' => '坽',
  '�B' => '夌',
  '�C' => '奅',
  '�D' => '妵',
  '�E' => '妺',
  '�F' => '姏',
  '�G' => '姎',
  '�H' => '妲',
  '�I' => '姌',
  '�J' => '姁',
  '�K' => '妶',
  '�L' => '妼',
  '�M' => '姃',
  '�N' => '姖',
  '�O' => '妱',
  '�P' => '妽',
  '�Q' => '姀',
  '�R' => '姈',
  '�S' => '妴',
  '�T' => '姇',
  '�U' => '孢',
  '�V' => '孥',
  '�W' => '宓',
  '�X' => '宕',
  '�Y' => '屄',
  '�Z' => '屇',
  '�[' => '岮',
  '�\\' => '岤',
  '�]' => '岠',
  '�^' => '岵',
  '�_' => '岯',
  '�`' => '岨',
  '�a' => '岬',
  '�b' => '岟',
  '�c' => '岣',
  '�d' => '岭',
  '�e' => '岢',
  '�f' => '岪',
  '�g' => '岧',
  '�h' => '岝',
  '�i' => '岥',
  '�j' => '岶',
  '�k' => '岰',
  '�l' => '岦',
  '�m' => '帗',
  '�n' => '帔',
  '�o' => '帙',
  '�p' => '弨',
  '�q' => '弢',
  '�r' => '弣',
  '�s' => '弤',
  '�t' => '彔',
  '�u' => '徂',
  '�v' => '彾',
  '�w' => '彽',
  '�x' => '忞',
  '�y' => '忥',
  '�z' => '怭',
  '�{' => '怦',
  '�|' => '怙',
  '�}' => '怲',
  '�~' => '怋',
  '̡' => '怴',
  '̢' => '怊',
  '̣' => '怗',
  '̤' => '怳',
  '̥' => '怚',
  '̦' => '怞',
  '̧' => '怬',
  '̨' => '怢',
  '̩' => '怍',
  '̪' => '怐',
  '̫' => '怮',
  '̬' => '怓',
  '̭' => '怑',
  '̮' => '怌',
  '̯' => '怉',
  '̰' => '怜',
  '̱' => '戔',
  '̲' => '戽',
  '̳' => '抭',
  '̴' => '抴',
  '̵' => '拑',
  '̶' => '抾',
  '̷' => '抪',
  '̸' => '抶',
  '̹' => '拊',
  '̺' => '抮',
  '̻' => '抳',
  '̼' => '抯',
  '̽' => '抻',
  '̾' => '抩',
  '̿' => '抰',
  '�' => '抸',
  '�' => '攽',
  '��' => '斨',
  '��' => '斻',
  '��' => '昉',
  '��' => '旼',
  '��' => '昄',
  '��' => '昒',
  '��' => '昈',
  '��' => '旻',
  '��' => '昃',
  '��' => '昋',
  '��' => '昍',
  '��' => '昅',
  '��' => '旽',
  '��' => '昑',
  '��' => '昐',
  '��' => '曶',
  '��' => '朊',
  '��' => '枅',
  '��' => '杬',
  '��' => '枎',
  '��' => '枒',
  '��' => '杶',
  '��' => '杻',
  '��' => '枘',
  '��' => '枆',
  '��' => '构',
  '��' => '杴',
  '��' => '枍',
  '��' => '枌',
  '��' => '杺',
  '��' => '枟',
  '��' => '枑',
  '��' => '枙',
  '��' => '枃',
  '��' => '杽',
  '��' => '极',
  '��' => '杸',
  '��' => '杹',
  '��' => '枔',
  '��' => '欥',
  '��' => '殀',
  '��' => '歾',
  '��' => '毞',
  '��' => '氝',
  '��' => '沓',
  '��' => '泬',
  '��' => '泫',
  '��' => '泮',
  '��' => '泙',
  '��' => '沶',
  '��' => '泔',
  '�' => '沭',
  '�' => '泧',
  '�' => '沷',
  '�' => '泐',
  '�' => '泂',
  '�' => '沺',
  '�' => '泃',
  '�' => '泆',
  '�' => '泭',
  '�' => '泲',
  '�@' => '泒',
  '�A' => '泝',
  '�B' => '沴',
  '�C' => '沊',
  '�D' => '沝',
  '�E' => '沀',
  '�F' => '泞',
  '�G' => '泀',
  '�H' => '洰',
  '�I' => '泍',
  '�J' => '泇',
  '�K' => '沰',
  '�L' => '泹',
  '�M' => '泏',
  '�N' => '泩',
  '�O' => '泑',
  '�P' => '炔',
  '�Q' => '炘',
  '�R' => '炅',
  '�S' => '炓',
  '�T' => '炆',
  '�U' => '炄',
  '�V' => '炑',
  '�W' => '炖',
  '�X' => '炂',
  '�Y' => '炚',
  '�Z' => '炃',
  '�[' => '牪',
  '�\\' => '狖',
  '�]' => '狋',
  '�^' => '狘',
  '�_' => '狉',
  '�`' => '狜',
  '�a' => '狒',
  '�b' => '狔',
  '�c' => '狚',
  '�d' => '狌',
  '�e' => '狑',
  '�f' => '玤',
  '�g' => '玡',
  '�h' => '玭',
  '�i' => '玦',
  '�j' => '玢',
  '�k' => '玠',
  '�l' => '玬',
  '�m' => '玝',
  '�n' => '瓝',
  '�o' => '瓨',
  '�p' => '甿',
  '�q' => '畀',
  '�r' => '甾',
  '�s' => '疌',
  '�t' => '疘',
  '�u' => '皯',
  '�v' => '盳',
  '�w' => '盱',
  '�x' => '盰',
  '�y' => '盵',
  '�z' => '矸',
  '�{' => '矼',
  '�|' => '矹',
  '�}' => '矻',
  '�~' => '矺',
  '͡' => '矷',
  '͢' => '祂',
  'ͣ' => '礿',
  'ͤ' => '秅',
  'ͥ' => '穸',
  'ͦ' => '穻',
  'ͧ' => '竻',
  'ͨ' => '籵',
  'ͩ' => '糽',
  'ͪ' => '耵',
  'ͫ' => '肏',
  'ͬ' => '肮',
  'ͭ' => '肣',
  'ͮ' => '肸',
  'ͯ' => '肵',
  'Ͱ' => '肭',
  'ͱ' => '舠',
  'Ͳ' => '芠',
  'ͳ' => '苀',
  'ʹ' => '芫',
  '͵' => '芚',
  'Ͷ' => '芘',
  'ͷ' => '芛',
  '͸' => '芵',
  '͹' => '芧',
  'ͺ' => '芮',
  'ͻ' => '芼',
  'ͼ' => '芞',
  'ͽ' => '芺',
  ';' => '芴',
  'Ϳ' => '芨',
  '�' => '芡',
  '�' => '芩',
  '��' => '苂',
  '��' => '芤',
  '��' => '苃',
  '��' => '芶',
  '��' => '芢',
  '��' => '虰',
  '��' => '虯',
  '��' => '虭',
  '��' => '虮',
  '��' => '豖',
  '��' => '迒',
  '��' => '迋',
  '��' => '迓',
  '��' => '迍',
  '��' => '迖',
  '��' => '迕',
  '��' => '迗',
  '��' => '邲',
  '��' => '邴',
  '��' => '邯',
  '��' => '邳',
  '��' => '邰',
  '��' => '阹',
  '��' => '阽',
  '��' => '阼',
  '��' => '阺',
  '��' => '陃',
  '��' => '俍',
  '��' => '俅',
  '��' => '俓',
  '��' => '侲',
  '��' => '俉',
  '��' => '俋',
  '��' => '俁',
  '��' => '俔',
  '��' => '俜',
  '��' => '俙',
  '��' => '侻',
  '��' => '侳',
  '��' => '俛',
  '��' => '俇',
  '��' => '俖',
  '��' => '侺',
  '��' => '俀',
  '��' => '侹',
  '��' => '俬',
  '��' => '剄',
  '��' => '剉',
  '��' => '勀',
  '��' => '勂',
  '��' => '匽',
  '�' => '卼',
  '�' => '厗',
  '�' => '厖',
  '�' => '厙',
  '�' => '厘',
  '�' => '咺',
  '�' => '咡',
  '�' => '咭',
  '�' => '咥',
  '�' => '哏',
  '�@' => '哃',
  '�A' => '茍',
  '�B' => '咷',
  '�C' => '咮',
  '�D' => '哖',
  '�E' => '咶',
  '�F' => '哅',
  '�G' => '哆',
  '�H' => '咠',
  '�I' => '呰',
  '�J' => '咼',
  '�K' => '咢',
  '�L' => '咾',
  '�M' => '呲',
  '�N' => '哞',
  '�O' => '咰',
  '�P' => '垵',
  '�Q' => '垞',
  '�R' => '垟',
  '�S' => '垤',
  '�T' => '垌',
  '�U' => '垗',
  '�V' => '垝',
  '�W' => '垛',
  '�X' => '垔',
  '�Y' => '垘',
  '�Z' => '垏',
  '�[' => '垙',
  '�\\' => '垥',
  '�]' => '垚',
  '�^' => '垕',
  '�_' => '壴',
  '�`' => '复',
  '�a' => '奓',
  '�b' => '姡',
  '�c' => '姞',
  '�d' => '姮',
  '�e' => '娀',
  '�f' => '姱',
  '�g' => '姝',
  '�h' => '姺',
  '�i' => '姽',
  '�j' => '姼',
  '�k' => '姶',
  '�l' => '姤',
  '�m' => '姲',
  '�n' => '姷',
  '�o' => '姛',
  '�p' => '姩',
  '�q' => '姳',
  '�r' => '姵',
  '�s' => '姠',
  '�t' => '姾',
  '�u' => '姴',
  '�v' => '姭',
  '�w' => '宨',
  '�x' => '屌',
  '�y' => '峐',
  '�z' => '峘',
  '�{' => '峌',
  '�|' => '峗',
  '�}' => '峋',
  '�~' => '峛',
  'Ρ' => '峞',
  '΢' => '峚',
  'Σ' => '峉',
  'Τ' => '峇',
  'Υ' => '峊',
  'Φ' => '峖',
  'Χ' => '峓',
  'Ψ' => '峔',
  'Ω' => '峏',
  'Ϊ' => '峈',
  'Ϋ' => '峆',
  'ά' => '峎',
  'έ' => '峟',
  'ή' => '峸',
  'ί' => '巹',
  'ΰ' => '帡',
  'α' => '帢',
  'β' => '帣',
  'γ' => '帠',
  'δ' => '帤',
  'ε' => '庰',
  'ζ' => '庤',
  'η' => '庢',
  'θ' => '庛',
  'ι' => '庣',
  'κ' => '庥',
  'λ' => '弇',
  'μ' => '弮',
  'ν' => '彖',
  'ξ' => '徆',
  'ο' => '怷',
  '�' => '怹',
  '�' => '恔',
  '��' => '恲',
  '��' => '恞',
  '��' => '恅',
  '��' => '恓',
  '��' => '恇',
  '��' => '恉',
  '��' => '恛',
  '��' => '恌',
  '��' => '恀',
  '��' => '恂',
  '��' => '恟',
  '��' => '怤',
  '��' => '恄',
  '��' => '恘',
  '��' => '恦',
  '��' => '恮',
  '��' => '扂',
  '��' => '扃',
  '��' => '拏',
  '��' => '挍',
  '��' => '挋',
  '��' => '拵',
  '��' => '挎',
  '��' => '挃',
  '��' => '拫',
  '��' => '拹',
  '��' => '挏',
  '��' => '挌',
  '��' => '拸',
  '��' => '拶',
  '��' => '挀',
  '��' => '挓',
  '��' => '挔',
  '��' => '拺',
  '��' => '挕',
  '��' => '拻',
  '��' => '拰',
  '��' => '敁',
  '��' => '敃',
  '��' => '斪',
  '��' => '斿',
  '��' => '昶',
  '��' => '昡',
  '��' => '昲',
  '��' => '昵',
  '��' => '昜',
  '��' => '昦',
  '��' => '昢',
  '��' => '昳',
  '��' => '昫',
  '��' => '昺',
  '�' => '昝',
  '�' => '昴',
  '�' => '昹',
  '�' => '昮',
  '�' => '朏',
  '�' => '朐',
  '�' => '柁',
  '�' => '柲',
  '�' => '柈',
  '�' => '枺',
  '�@' => '柜',
  '�A' => '枻',
  '�B' => '柸',
  '�C' => '柘',
  '�D' => '柀',
  '�E' => '枷',
  '�F' => '柅',
  '�G' => '柫',
  '�H' => '柤',
  '�I' => '柟',
  '�J' => '枵',
  '�K' => '柍',
  '�L' => '枳',
  '�M' => '柷',
  '�N' => '柶',
  '�O' => '柮',
  '�P' => '柣',
  '�Q' => '柂',
  '�R' => '枹',
  '�S' => '柎',
  '�T' => '柧',
  '�U' => '柰',
  '�V' => '枲',
  '�W' => '柼',
  '�X' => '柆',
  '�Y' => '柭',
  '�Z' => '柌',
  '�[' => '枮',
  '�\\' => '柦',
  '�]' => '柛',
  '�^' => '柺',
  '�_' => '柉',
  '�`' => '柊',
  '�a' => '柃',
  '�b' => '柪',
  '�c' => '柋',
  '�d' => '欨',
  '�e' => '殂',
  '�f' => '殄',
  '�g' => '殶',
  '�h' => '毖',
  '�i' => '毘',
  '�j' => '毠',
  '�k' => '氠',
  '�l' => '氡',
  '�m' => '洨',
  '�n' => '洴',
  '�o' => '洭',
  '�p' => '洟',
  '�q' => '洼',
  '�r' => '洿',
  '�s' => '洒',
  '�t' => '洊',
  '�u' => '泚',
  '�v' => '洳',
  '�w' => '洄',
  '�x' => '洙',
  '�y' => '洺',
  '�z' => '洚',
  '�{' => '洑',
  '�|' => '洀',
  '�}' => '洝',
  '�~' => '浂',
  'ϡ' => '洁',
  'Ϣ' => '洘',
  'ϣ' => '洷',
  'Ϥ' => '洃',
  'ϥ' => '洏',
  'Ϧ' => '浀',
  'ϧ' => '洇',
  'Ϩ' => '洠',
  'ϩ' => '洬',
  'Ϫ' => '洈',
  'ϫ' => '洢',
  'Ϭ' => '洉',
  'ϭ' => '洐',
  'Ϯ' => '炷',
  'ϯ' => '炟',
  'ϰ' => '炾',
  'ϱ' => '炱',
  'ϲ' => '炰',
  'ϳ' => '炡',
  'ϴ' => '炴',
  'ϵ' => '炵',
  '϶' => '炩',
  'Ϸ' => '牁',
  'ϸ' => '牉',
  'Ϲ' => '牊',
  'Ϻ' => '牬',
  'ϻ' => '牰',
  'ϼ' => '牳',
  'Ͻ' => '牮',
  'Ͼ' => '狊',
  'Ͽ' => '狤',
  '�' => '狨',
  '�' => '狫',
  '��' => '狟',
  '��' => '狪',
  '��' => '狦',
  '��' => '狣',
  '��' => '玅',
  '��' => '珌',
  '��' => '珂',
  '��' => '珈',
  '��' => '珅',
  '��' => '玹',
  '��' => '玶',
  '��' => '玵',
  '��' => '玴',
  '��' => '珫',
  '��' => '玿',
  '��' => '珇',
  '��' => '玾',
  '��' => '珃',
  '��' => '珆',
  '��' => '玸',
  '��' => '珋',
  '��' => '瓬',
  '��' => '瓮',
  '��' => '甮',
  '��' => '畇',
  '��' => '畈',
  '��' => '疧',
  '��' => '疪',
  '��' => '癹',
  '��' => '盄',
  '��' => '眈',
  '��' => '眃',
  '��' => '眄',
  '��' => '眅',
  '��' => '眊',
  '��' => '盷',
  '��' => '盻',
  '��' => '盺',
  '��' => '矧',
  '��' => '矨',
  '��' => '砆',
  '��' => '砑',
  '��' => '砒',
  '��' => '砅',
  '��' => '砐',
  '��' => '砏',
  '��' => '砎',
  '��' => '砉',
  '��' => '砃',
  '��' => '砓',
  '��' => '祊',
  '�' => '祌',
  '�' => '祋',
  '�' => '祅',
  '�' => '祄',
  '�' => '秕',
  '�' => '种',
  '�' => '秏',
  '�' => '秖',
  '�' => '秎',
  '�' => '窀',
  '�@' => '穾',
  '�A' => '竑',
  '�B' => '笀',
  '�C' => '笁',
  '�D' => '籺',
  '�E' => '籸',
  '�F' => '籹',
  '�G' => '籿',
  '�H' => '粀',
  '�I' => '粁',
  '�J' => '紃',
  '�K' => '紈',
  '�L' => '紁',
  '�M' => '罘',
  '�N' => '羑',
  '�O' => '羍',
  '�P' => '羾',
  '�Q' => '耇',
  '�R' => '耎',
  '�S' => '耏',
  '�T' => '耔',
  '�U' => '耷',
  '�V' => '胘',
  '�W' => '胇',
  '�X' => '胠',
  '�Y' => '胑',
  '�Z' => '胈',
  '�[' => '胂',
  '�\\' => '胐',
  '�]' => '胅',
  '�^' => '胣',
  '�_' => '胙',
  '�`' => '胜',
  '�a' => '胊',
  '�b' => '胕',
  '�c' => '胉',
  '�d' => '胏',
  '�e' => '胗',
  '�f' => '胦',
  '�g' => '胍',
  '�h' => '臿',
  '�i' => '舡',
  '�j' => '芔',
  '�k' => '苙',
  '�l' => '苾',
  '�m' => '苹',
  '�n' => '茇',
  '�o' => '苨',
  '�p' => '茀',
  '�q' => '苕',
  '�r' => '茺',
  '�s' => '苫',
  '�t' => '苖',
  '�u' => '苴',
  '�v' => '苬',
  '�w' => '苡',
  '�x' => '苲',
  '�y' => '苵',
  '�z' => '茌',
  '�{' => '苻',
  '�|' => '苶',
  '�}' => '苰',
  '�~' => '苪',
  'С' => '苤',
  'Т' => '苠',
  'У' => '苺',
  'Ф' => '苳',
  'Х' => '苭',
  'Ц' => '虷',
  'Ч' => '虴',
  'Ш' => '虼',
  'Щ' => '虳',
  'Ъ' => '衁',
  'Ы' => '衎',
  'Ь' => '衧',
  'Э' => '衪',
  'Ю' => '衩',
  'Я' => '觓',
  'а' => '訄',
  'б' => '訇',
  'в' => '赲',
  'г' => '迣',
  'д' => '迡',
  'е' => '迮',
  'ж' => '迠',
  'з' => '郱',
  'и' => '邽',
  'й' => '邿',
  'к' => '郕',
  'л' => '郅',
  'м' => '邾',
  'н' => '郇',
  'о' => '郋',
  'п' => '郈',
  '�' => '釔',
  '�' => '釓',
  '��' => '陔',
  '��' => '陏',
  '��' => '陑',
  '��' => '陓',
  '��' => '陊',
  '��' => '陎',
  '��' => '倞',
  '��' => '倅',
  '��' => '倇',
  '��' => '倓',
  '��' => '倢',
  '��' => '倰',
  '��' => '倛',
  '��' => '俵',
  '��' => '俴',
  '��' => '倳',
  '��' => '倷',
  '��' => '倬',
  '��' => '俶',
  '��' => '俷',
  '��' => '倗',
  '��' => '倜',
  '��' => '倠',
  '��' => '倧',
  '��' => '倵',
  '��' => '倯',
  '��' => '倱',
  '��' => '倎',
  '��' => '党',
  '��' => '冔',
  '��' => '冓',
  '��' => '凊',
  '��' => '凄',
  '��' => '凅',
  '��' => '凈',
  '��' => '凎',
  '��' => '剡',
  '��' => '剚',
  '��' => '剒',
  '��' => '剞',
  '��' => '剟',
  '��' => '剕',
  '��' => '剢',
  '��' => '勍',
  '��' => '匎',
  '��' => '厞',
  '��' => '唦',
  '��' => '哢',
  '��' => '唗',
  '��' => '唒',
  '��' => '哧',
  '�' => '哳',
  '�' => '哤',
  '�' => '唚',
  '�' => '哿',
  '�' => '唄',
  '�' => '唈',
  '�' => '哫',
  '�' => '唑',
  '�' => '唅',
  '�' => '哱',
  '�@' => '唊',
  '�A' => '哻',
  '�B' => '哷',
  '�C' => '哸',
  '�D' => '哠',
  '�E' => '唎',
  '�F' => '唃',
  '�G' => '唋',
  '�H' => '圁',
  '�I' => '圂',
  '�J' => '埌',
  '�K' => '堲',
  '�L' => '埕',
  '�M' => '埒',
  '�N' => '垺',
  '�O' => '埆',
  '�P' => '垽',
  '�Q' => '垼',
  '�R' => '垸',
  '�S' => '垶',
  '�T' => '垿',
  '�U' => '埇',
  '�V' => '埐',
  '�W' => '垹',
  '�X' => '埁',
  '�Y' => '夎',
  '�Z' => '奊',
  '�[' => '娙',
  '�\\' => '娖',
  '�]' => '娭',
  '�^' => '娮',
  '�_' => '娕',
  '�`' => '娏',
  '�a' => '娗',
  '�b' => '娊',
  '�c' => '娞',
  '�d' => '娳',
  '�e' => '孬',
  '�f' => '宧',
  '�g' => '宭',
  '�h' => '宬',
  '�i' => '尃',
  '�j' => '屖',
  '�k' => '屔',
  '�l' => '峬',
  '�m' => '峿',
  '�n' => '峮',
  '�o' => '峱',
  '�p' => '峷',
  '�q' => '崀',
  '�r' => '峹',
  '�s' => '帩',
  '�t' => '帨',
  '�u' => '庨',
  '�v' => '庮',
  '�w' => '庪',
  '�x' => '庬',
  '�y' => '弳',
  '�z' => '弰',
  '�{' => '彧',
  '�|' => '恝',
  '�}' => '恚',
  '�~' => '恧',
  'ѡ' => '恁',
  'Ѣ' => '悢',
  'ѣ' => '悈',
  'Ѥ' => '悀',
  'ѥ' => '悒',
  'Ѧ' => '悁',
  'ѧ' => '悝',
  'Ѩ' => '悃',
  'ѩ' => '悕',
  'Ѫ' => '悛',
  'ѫ' => '悗',
  'Ѭ' => '悇',
  'ѭ' => '悜',
  'Ѯ' => '悎',
  'ѯ' => '戙',
  'Ѱ' => '扆',
  'ѱ' => '拲',
  'Ѳ' => '挐',
  'ѳ' => '捖',
  'Ѵ' => '挬',
  'ѵ' => '捄',
  'Ѷ' => '捅',
  'ѷ' => '挶',
  'Ѹ' => '捃',
  'ѹ' => '揤',
  'Ѻ' => '挹',
  'ѻ' => '捋',
  'Ѽ' => '捊',
  'ѽ' => '挼',
  'Ѿ' => '挩',
  'ѿ' => '捁',
  '�' => '挴',
  '�' => '捘',
  '��' => '捔',
  '��' => '捙',
  '��' => '挭',
  '��' => '捇',
  '��' => '挳',
  '��' => '捚',
  '��' => '捑',
  '��' => '挸',
  '��' => '捗',
  '��' => '捀',
  '��' => '捈',
  '��' => '敊',
  '��' => '敆',
  '��' => '旆',
  '��' => '旃',
  '��' => '旄',
  '��' => '旂',
  '��' => '晊',
  '��' => '晟',
  '��' => '晇',
  '��' => '晑',
  '��' => '朒',
  '��' => '朓',
  '��' => '栟',
  '��' => '栚',
  '��' => '桉',
  '��' => '栲',
  '��' => '栳',
  '��' => '栻',
  '��' => '桋',
  '��' => '桏',
  '��' => '栖',
  '��' => '栱',
  '��' => '栜',
  '��' => '栵',
  '��' => '栫',
  '��' => '栭',
  '��' => '栯',
  '��' => '桎',
  '��' => '桄',
  '��' => '栴',
  '��' => '栝',
  '��' => '栒',
  '��' => '栔',
  '��' => '栦',
  '��' => '栨',
  '��' => '栮',
  '��' => '桍',
  '��' => '栺',
  '��' => '栥',
  '��' => '栠',
  '�' => '欬',
  '�' => '欯',
  '�' => '欭',
  '�' => '欱',
  '�' => '欴',
  '�' => '歭',
  '�' => '肂',
  '�' => '殈',
  '�' => '毦',
  '�' => '毤',
  '�@' => '毨',
  '�A' => '毣',
  '�B' => '毢',
  '�C' => '毧',
  '�D' => '氥',
  '�E' => '浺',
  '�F' => '浣',
  '�G' => '浤',
  '�H' => '浶',
  '�I' => '洍',
  '�J' => '浡',
  '�K' => '涒',
  '�L' => '浘',
  '�M' => '浢',
  '�N' => '浭',
  '�O' => '浯',
  '�P' => '涑',
  '�Q' => '涍',
  '�R' => '淯',
  '�S' => '浿',
  '�T' => '涆',
  '�U' => '浞',
  '�V' => '浧',
  '�W' => '浠',
  '�X' => '涗',
  '�Y' => '浰',
  '�Z' => '浼',
  '�[' => '浟',
  '�\\' => '涂',
  '�]' => '涘',
  '�^' => '洯',
  '�_' => '浨',
  '�`' => '涋',
  '�a' => '浾',
  '�b' => '涀',
  '�c' => '涄',
  '�d' => '洖',
  '�e' => '涃',
  '�f' => '浻',
  '�g' => '浽',
  '�h' => '浵',
  '�i' => '涐',
  '�j' => '烜',
  '�k' => '烓',
  '�l' => '烑',
  '�m' => '烝',
  '�n' => '烋',
  '�o' => '缹',
  '�p' => '烢',
  '�q' => '烗',
  '�r' => '烒',
  '�s' => '烞',
  '�t' => '烠',
  '�u' => '烔',
  '�v' => '烍',
  '�w' => '烅',
  '�x' => '烆',
  '�y' => '烇',
  '�z' => '烚',
  '�{' => '烎',
  '�|' => '烡',
  '�}' => '牂',
  '�~' => '牸',
  'ҡ' => '牷',
  'Ң' => '牶',
  'ң' => '猀',
  'Ҥ' => '狺',
  'ҥ' => '狴',
  'Ҧ' => '狾',
  'ҧ' => '狶',
  'Ҩ' => '狳',
  'ҩ' => '狻',
  'Ҫ' => '猁',
  'ҫ' => '珓',
  'Ҭ' => '珙',
  'ҭ' => '珥',
  'Ү' => '珖',
  'ү' => '玼',
  'Ұ' => '珧',
  'ұ' => '珣',
  'Ҳ' => '珩',
  'ҳ' => '珜',
  'Ҵ' => '珒',
  'ҵ' => '珛',
  'Ҷ' => '珔',
  'ҷ' => '珝',
  'Ҹ' => '珚',
  'ҹ' => '珗',
  'Һ' => '珘',
  'һ' => '珨',
  'Ҽ' => '瓞',
  'ҽ' => '瓟',
  'Ҿ' => '瓴',
  'ҿ' => '瓵',
  '�' => '甡',
  '�' => '畛',
  '��' => '畟',
  '��' => '疰',
  '��' => '痁',
  '��' => '疻',
  '��' => '痄',
  '��' => '痀',
  '��' => '疿',
  '��' => '疶',
  '��' => '疺',
  '��' => '皊',
  '��' => '盉',
  '��' => '眝',
  '��' => '眛',
  '��' => '眐',
  '��' => '眓',
  '��' => '眒',
  '��' => '眣',
  '��' => '眑',
  '��' => '眕',
  '��' => '眙',
  '��' => '眚',
  '��' => '眢',
  '��' => '眧',
  '��' => '砣',
  '��' => '砬',
  '��' => '砢',
  '��' => '砵',
  '��' => '砯',
  '��' => '砨',
  '��' => '砮',
  '��' => '砫',
  '��' => '砡',
  '��' => '砩',
  '��' => '砳',
  '��' => '砪',
  '��' => '砱',
  '��' => '祔',
  '��' => '祛',
  '��' => '祏',
  '��' => '祜',
  '��' => '祓',
  '��' => '祒',
  '��' => '祑',
  '��' => '秫',
  '��' => '秬',
  '��' => '秠',
  '��' => '秮',
  '��' => '秭',
  '��' => '秪',
  '��' => '秜',
  '��' => '秞',
  '�' => '秝',
  '�' => '窆',
  '�' => '窉',
  '�' => '窅',
  '�' => '窋',
  '�' => '窌',
  '�' => '窊',
  '�' => '窇',
  '�' => '竘',
  '�' => '笐',
  '�@' => '笄',
  '�A' => '笓',
  '�B' => '笅',
  '�C' => '笏',
  '�D' => '笈',
  '�E' => '笊',
  '�F' => '笎',
  '�G' => '笉',
  '�H' => '笒',
  '�I' => '粄',
  '�J' => '粑',
  '�K' => '粊',
  '�L' => '粌',
  '�M' => '粈',
  '�N' => '粍',
  '�O' => '粅',
  '�P' => '紞',
  '�Q' => '紝',
  '�R' => '紑',
  '�S' => '紎',
  '�T' => '紘',
  '�U' => '紖',
  '�V' => '紓',
  '�W' => '紟',
  '�X' => '紒',
  '�Y' => '紏',
  '�Z' => '紌',
  '�[' => '罜',
  '�\\' => '罡',
  '�]' => '罞',
  '�^' => '罠',
  '�_' => '罝',
  '�`' => '罛',
  '�a' => '羖',
  '�b' => '羒',
  '�c' => '翃',
  '�d' => '翂',
  '�e' => '翀',
  '�f' => '耖',
  '�g' => '耾',
  '�h' => '耹',
  '�i' => '胺',
  '�j' => '胲',
  '�k' => '胹',
  '�l' => '胵',
  '�m' => '脁',
  '�n' => '胻',
  '�o' => '脀',
  '�p' => '舁',
  '�q' => '舯',
  '�r' => '舥',
  '�s' => '茳',
  '�t' => '茭',
  '�u' => '荄',
  '�v' => '茙',
  '�w' => '荑',
  '�x' => '茥',
  '�y' => '荖',
  '�z' => '茿',
  '�{' => '荁',
  '�|' => '茦',
  '�}' => '茜',
  '�~' => '茢',
  'ӡ' => '荂',
  'Ӣ' => '荎',
  'ӣ' => '茛',
  'Ӥ' => '茪',
  'ӥ' => '茈',
  'Ӧ' => '茼',
  'ӧ' => '荍',
  'Ө' => '茖',
  'ө' => '茤',
  'Ӫ' => '茠',
  'ӫ' => '茷',
  'Ӭ' => '茯',
  'ӭ' => '茩',
  'Ӯ' => '荇',
  'ӯ' => '荅',
  'Ӱ' => '荌',
  'ӱ' => '荓',
  'Ӳ' => '茞',
  'ӳ' => '茬',
  'Ӵ' => '荋',
  'ӵ' => '茧',
  'Ӷ' => '荈',
  'ӷ' => '虓',
  'Ӹ' => '虒',
  'ӹ' => '蚢',
  'Ӻ' => '蚨',
  'ӻ' => '蚖',
  'Ӽ' => '蚍',
  'ӽ' => '蚑',
  'Ӿ' => '蚞',
  'ӿ' => '蚇',
  '�' => '蚗',
  '�' => '蚆',
  '��' => '蚋',
  '��' => '蚚',
  '��' => '蚅',
  '��' => '蚥',
  '��' => '蚙',
  '��' => '蚡',
  '��' => '蚧',
  '��' => '蚕',
  '��' => '蚘',
  '��' => '蚎',
  '��' => '蚝',
  '��' => '蚐',
  '��' => '蚔',
  '��' => '衃',
  '��' => '衄',
  '��' => '衭',
  '��' => '衵',
  '��' => '衶',
  '��' => '衲',
  '��' => '袀',
  '��' => '衱',
  '��' => '衿',
  '��' => '衯',
  '��' => '袃',
  '��' => '衾',
  '��' => '衴',
  '��' => '衼',
  '��' => '訒',
  '��' => '豇',
  '��' => '豗',
  '��' => '豻',
  '��' => '貤',
  '��' => '貣',
  '��' => '赶',
  '��' => '赸',
  '��' => '趵',
  '��' => '趷',
  '��' => '趶',
  '��' => '軑',
  '��' => '軓',
  '��' => '迾',
  '��' => '迵',
  '��' => '适',
  '��' => '迿',
  '��' => '迻',
  '��' => '逄',
  '��' => '迼',
  '��' => '迶',
  '��' => '郖',
  '��' => '郠',
  '��' => '郙',
  '�' => '郚',
  '�' => '郣',
  '�' => '郟',
  '�' => '郥',
  '�' => '郘',
  '�' => '郛',
  '�' => '郗',
  '�' => '郜',
  '�' => '郤',
  '�' => '酐',
  '�@' => '酎',
  '�A' => '酏',
  '�B' => '釕',
  '�C' => '釢',
  '�D' => '釚',
  '�E' => '陜',
  '�F' => '陟',
  '�G' => '隼',
  '�H' => '飣',
  '�I' => '髟',
  '�J' => '鬯',
  '�K' => '乿',
  '�L' => '偰',
  '�M' => '偪',
  '�N' => '偡',
  '�O' => '偞',
  '�P' => '偠',
  '�Q' => '偓',
  '�R' => '偋',
  '�S' => '偝',
  '�T' => '偲',
  '�U' => '偈',
  '�V' => '偍',
  '�W' => '偁',
  '�X' => '偛',
  '�Y' => '偊',
  '�Z' => '偢',
  '�[' => '倕',
  '�\\' => '偅',
  '�]' => '偟',
  '�^' => '偩',
  '�_' => '偫',
  '�`' => '偣',
  '�a' => '偤',
  '�b' => '偆',
  '�c' => '偀',
  '�d' => '偮',
  '�e' => '偳',
  '�f' => '偗',
  '�g' => '偑',
  '�h' => '凐',
  '�i' => '剫',
  '�j' => '剭',
  '�k' => '剬',
  '�l' => '剮',
  '�m' => '勖',
  '�n' => '勓',
  '�o' => '匭',
  '�p' => '厜',
  '�q' => '啵',
  '�r' => '啶',
  '�s' => '唼',
  '�t' => '啍',
  '�u' => '啐',
  '�v' => '唴',
  '�w' => '唪',
  '�x' => '啑',
  '�y' => '啢',
  '�z' => '唶',
  '�{' => '唵',
  '�|' => '唰',
  '�}' => '啒',
  '�~' => '啅',
  'ԡ' => '唌',
  'Ԣ' => '唲',
  'ԣ' => '啥',
  'Ԥ' => '啎',
  'ԥ' => '唹',
  'Ԧ' => '啈',
  'ԧ' => '唭',
  'Ԩ' => '唻',
  'ԩ' => '啀',
  'Ԫ' => '啋',
  'ԫ' => '圊',
  'Ԭ' => '圇',
  'ԭ' => '埻',
  'Ԯ' => '堔',
  'ԯ' => '埢',
  '԰' => '埶',
  'Ա' => '埜',
  'Բ' => '埴',
  'Գ' => '堀',
  'Դ' => '埭',
  'Ե' => '埽',
  'Զ' => '堈',
  'Է' => '埸',
  'Ը' => '堋',
  'Թ' => '埳',
  'Ժ' => '埏',
  'Ի' => '堇',
  'Լ' => '埮',
  'Խ' => '埣',
  'Ծ' => '埲',
  'Կ' => '埥',
  '�' => '埬',
  '�' => '埡',
  '��' => '堎',
  '��' => '埼',
  '��' => '堐',
  '��' => '埧',
  '��' => '堁',
  '��' => '堌',
  '��' => '埱',
  '��' => '埩',
  '��' => '埰',
  '��' => '堍',
  '��' => '堄',
  '��' => '奜',
  '��' => '婠',
  '��' => '婘',
  '��' => '婕',
  '��' => '婧',
  '��' => '婞',
  '��' => '娸',
  '��' => '娵',
  '��' => '婭',
  '��' => '婐',
  '��' => '婟',
  '��' => '婥',
  '��' => '婬',
  '��' => '婓',
  '��' => '婤',
  '��' => '婗',
  '��' => '婃',
  '��' => '婝',
  '��' => '婒',
  '��' => '婄',
  '��' => '婛',
  '��' => '婈',
  '��' => '媎',
  '��' => '娾',
  '��' => '婍',
  '��' => '娹',
  '��' => '婌',
  '��' => '婰',
  '��' => '婩',
  '��' => '婇',
  '��' => '婑',
  '��' => '婖',
  '��' => '婂',
  '��' => '婜',
  '��' => '孲',
  '��' => '孮',
  '��' => '寁',
  '��' => '寀',
  '��' => '屙',
  '��' => '崞',
  '�' => '崋',
  '�' => '崝',
  '�' => '崚',
  '�' => '崠',
  '�' => '崌',
  '�' => '崨',
  '�' => '崍',
  '�' => '崦',
  '�' => '崥',
  '�' => '崏',
  '�@' => '崰',
  '�A' => '崒',
  '�B' => '崣',
  '�C' => '崟',
  '�D' => '崮',
  '�E' => '帾',
  '�F' => '帴',
  '�G' => '庱',
  '�H' => '庴',
  '�I' => '庹',
  '�J' => '庲',
  '�K' => '庳',
  '�L' => '弶',
  '�M' => '弸',
  '�N' => '徛',
  '�O' => '徖',
  '�P' => '徟',
  '�Q' => '悊',
  '�R' => '悐',
  '�S' => '悆',
  '�T' => '悾',
  '�U' => '悰',
  '�V' => '悺',
  '�W' => '惓',
  '�X' => '惔',
  '�Y' => '惏',
  '�Z' => '惤',
  '�[' => '惙',
  '�\\' => '惝',
  '�]' => '惈',
  '�^' => '悱',
  '�_' => '惛',
  '�`' => '悷',
  '�a' => '惊',
  '�b' => '悿',
  '�c' => '惃',
  '�d' => '惍',
  '�e' => '惀',
  '�f' => '挲',
  '�g' => '捥',
  '�h' => '掊',
  '�i' => '掂',
  '�j' => '捽',
  '�k' => '掽',
  '�l' => '掞',
  '�m' => '掭',
  '�n' => '掝',
  '�o' => '掗',
  '�p' => '掫',
  '�q' => '掎',
  '�r' => '捯',
  '�s' => '掇',
  '�t' => '掐',
  '�u' => '据',
  '�v' => '掯',
  '�w' => '捵',
  '�x' => '掜',
  '�y' => '捭',
  '�z' => '掮',
  '�{' => '捼',
  '�|' => '掤',
  '�}' => '挻',
  '�~' => '掟',
  'ա' => '捸',
  'բ' => '掅',
  'գ' => '掁',
  'դ' => '掑',
  'ե' => '掍',
  'զ' => '捰',
  'է' => '敓',
  'ը' => '旍',
  'թ' => '晥',
  'ժ' => '晡',
  'ի' => '晛',
  'լ' => '晙',
  'խ' => '晜',
  'ծ' => '晢',
  'կ' => '朘',
  'հ' => '桹',
  'ձ' => '梇',
  'ղ' => '梐',
  'ճ' => '梜',
  'մ' => '桭',
  'յ' => '桮',
  'ն' => '梮',
  'շ' => '梫',
  'ո' => '楖',
  'չ' => '桯',
  'պ' => '梣',
  'ջ' => '梬',
  'ռ' => '梩',
  'ս' => '桵',
  'վ' => '桴',
  'տ' => '梲',
  '�' => '梏',
  '�' => '桷',
  '��' => '梒',
  '��' => '桼',
  '��' => '桫',
  '��' => '桲',
  '��' => '梪',
  '��' => '梀',
  '��' => '桱',
  '��' => '桾',
  '��' => '梛',
  '��' => '梖',
  '��' => '梋',
  '��' => '梠',
  '��' => '梉',
  '��' => '梤',
  '��' => '桸',
  '��' => '桻',
  '��' => '梑',
  '��' => '梌',
  '��' => '梊',
  '��' => '桽',
  '��' => '欶',
  '��' => '欳',
  '��' => '欷',
  '��' => '欸',
  '��' => '殑',
  '��' => '殏',
  '��' => '殍',
  '��' => '殎',
  '��' => '殌',
  '��' => '氪',
  '��' => '淀',
  '��' => '涫',
  '��' => '涴',
  '��' => '涳',
  '��' => '湴',
  '��' => '涬',
  '��' => '淩',
  '��' => '淢',
  '��' => '涷',
  '��' => '淶',
  '��' => '淔',
  '��' => '渀',
  '��' => '淈',
  '��' => '淠',
  '��' => '淟',
  '��' => '淖',
  '��' => '涾',
  '��' => '淥',
  '��' => '淜',
  '��' => '淝',
  '��' => '淛',
  '�' => '淴',
  '�' => '淊',
  '�' => '涽',
  '�' => '淭',
  '�' => '淰',
  '�' => '涺',
  '�' => '淕',
  '�' => '淂',
  '�' => '淏',
  '�' => '淉',
  '�@' => '淐',
  '�A' => '淲',
  '�B' => '淓',
  '�C' => '淽',
  '�D' => '淗',
  '�E' => '淍',
  '�F' => '淣',
  '�G' => '涻',
  '�H' => '烺',
  '�I' => '焍',
  '�J' => '烷',
  '�K' => '焗',
  '�L' => '烴',
  '�M' => '焌',
  '�N' => '烰',
  '�O' => '焄',
  '�P' => '烳',
  '�Q' => '焐',
  '�R' => '烼',
  '�S' => '烿',
  '�T' => '焆',
  '�U' => '焓',
  '�V' => '焀',
  '�W' => '烸',
  '�X' => '烶',
  '�Y' => '焋',
  '�Z' => '焂',
  '�[' => '焎',
  '�\\' => '牾',
  '�]' => '牻',
  '�^' => '牼',
  '�_' => '牿',
  '�`' => '猝',
  '�a' => '猗',
  '�b' => '猇',
  '�c' => '猑',
  '�d' => '猘',
  '�e' => '猊',
  '�f' => '猈',
  '�g' => '狿',
  '�h' => '猏',
  '�i' => '猞',
  '�j' => '玈',
  '�k' => '珶',
  '�l' => '珸',
  '�m' => '珵',
  '�n' => '琄',
  '�o' => '琁',
  '�p' => '珽',
  '�q' => '琇',
  '�r' => '琀',
  '�s' => '珺',
  '�t' => '珼',
  '�u' => '珿',
  '�v' => '琌',
  '�w' => '琋',
  '�x' => '珴',
  '�y' => '琈',
  '�z' => '畤',
  '�{' => '畣',
  '�|' => '痎',
  '�}' => '痒',
  '�~' => '痏',
  '֡' => '痋',
  '֢' => '痌',
  '֣' => '痑',
  '֤' => '痐',
  '֥' => '皏',
  '֦' => '皉',
  '֧' => '盓',
  '֨' => '眹',
  '֩' => '眯',
  '֪' => '眭',
  '֫' => '眱',
  '֬' => '眲',
  '֭' => '眴',
  '֮' => '眳',
  '֯' => '眽',
  'ְ' => '眥',
  'ֱ' => '眻',
  'ֲ' => '眵',
  'ֳ' => '硈',
  'ִ' => '硒',
  'ֵ' => '硉',
  'ֶ' => '硍',
  'ַ' => '硊',
  'ָ' => '硌',
  'ֹ' => '砦',
  'ֺ' => '硅',
  'ֻ' => '硐',
  'ּ' => '祤',
  'ֽ' => '祧',
  '־' => '祩',
  'ֿ' => '祪',
  '�' => '祣',
  '�' => '祫',
  '��' => '祡',
  '��' => '离',
  '��' => '秺',
  '��' => '秸',
  '��' => '秶',
  '��' => '秷',
  '��' => '窏',
  '��' => '窔',
  '��' => '窐',
  '��' => '笵',
  '��' => '筇',
  '��' => '笴',
  '��' => '笥',
  '��' => '笰',
  '��' => '笢',
  '��' => '笤',
  '��' => '笳',
  '��' => '笘',
  '��' => '笪',
  '��' => '笝',
  '��' => '笱',
  '��' => '笫',
  '��' => '笭',
  '��' => '笯',
  '��' => '笲',
  '��' => '笸',
  '��' => '笚',
  '��' => '笣',
  '��' => '粔',
  '��' => '粘',
  '��' => '粖',
  '��' => '粣',
  '��' => '紵',
  '��' => '紽',
  '��' => '紸',
  '��' => '紶',
  '��' => '紺',
  '��' => '絅',
  '��' => '紬',
  '��' => '紩',
  '��' => '絁',
  '��' => '絇',
  '��' => '紾',
  '��' => '紿',
  '��' => '絊',
  '��' => '紻',
  '��' => '紨',
  '��' => '罣',
  '��' => '羕',
  '��' => '羜',
  '��' => '羝',
  '�' => '羛',
  '�' => '翊',
  '�' => '翋',
  '�' => '翍',
  '�' => '翐',
  '�' => '翑',
  '�' => '翇',
  '�' => '翏',
  '�' => '翉',
  '�' => '耟',
  '�@' => '耞',
  '�A' => '耛',
  '�B' => '聇',
  '�C' => '聃',
  '�D' => '聈',
  '�E' => '脘',
  '�F' => '脥',
  '�G' => '脙',
  '�H' => '脛',
  '�I' => '脭',
  '�J' => '脟',
  '�K' => '脬',
  '�L' => '脞',
  '�M' => '脡',
  '�N' => '脕',
  '�O' => '脧',
  '�P' => '脝',
  '�Q' => '脢',
  '�R' => '舑',
  '�S' => '舸',
  '�T' => '舳',
  '�U' => '舺',
  '�V' => '舴',
  '�W' => '舲',
  '�X' => '艴',
  '�Y' => '莐',
  '�Z' => '莣',
  '�[' => '莨',
  '�\\' => '莍',
  '�]' => '荺',
  '�^' => '荳',
  '�_' => '莤',
  '�`' => '荴',
  '�a' => '莏',
  '�b' => '莁',
  '�c' => '莕',
  '�d' => '莙',
  '�e' => '荵',
  '�f' => '莔',
  '�g' => '莩',
  '�h' => '荽',
  '�i' => '莃',
  '�j' => '莌',
  '�k' => '莝',
  '�l' => '莛',
  '�m' => '莪',
  '�n' => '莋',
  '�o' => '荾',
  '�p' => '莥',
  '�q' => '莯',
  '�r' => '莈',
  '�s' => '莗',
  '�t' => '莰',
  '�u' => '荿',
  '�v' => '莦',
  '�w' => '莇',
  '�x' => '莮',
  '�y' => '荶',
  '�z' => '莚',
  '�{' => '虙',
  '�|' => '虖',
  '�}' => '蚿',
  '�~' => '蚷',
  'ס' => '蛂',
  'ע' => '蛁',
  'ף' => '蛅',
  'פ' => '蚺',
  'ץ' => '蚰',
  'צ' => '蛈',
  'ק' => '蚹',
  'ר' => '蚳',
  'ש' => '蚸',
  'ת' => '蛌',
  '׫' => '蚴',
  '׬' => '蚻',
  '׭' => '蚼',
  '׮' => '蛃',
  'ׯ' => '蚽',
  'װ' => '蚾',
  'ױ' => '衒',
  'ײ' => '袉',
  '׳' => '袕',
  '״' => '袨',
  '׵' => '袢',
  '׶' => '袪',
  '׷' => '袚',
  '׸' => '袑',
  '׹' => '袡',
  '׺' => '袟',
  '׻' => '袘',
  '׼' => '袧',
  '׽' => '袙',
  '׾' => '袛',
  '׿' => '袗',
  '�' => '袤',
  '�' => '袬',
  '��' => '袌',
  '��' => '袓',
  '��' => '袎',
  '��' => '覂',
  '��' => '觖',
  '��' => '觙',
  '��' => '觕',
  '��' => '訰',
  '��' => '訧',
  '��' => '訬',
  '��' => '訞',
  '��' => '谹',
  '��' => '谻',
  '��' => '豜',
  '��' => '豝',
  '��' => '豽',
  '��' => '貥',
  '��' => '赽',
  '��' => '赻',
  '��' => '赹',
  '��' => '趼',
  '��' => '跂',
  '��' => '趹',
  '��' => '趿',
  '��' => '跁',
  '��' => '軘',
  '��' => '軞',
  '��' => '軝',
  '��' => '軜',
  '��' => '軗',
  '��' => '軠',
  '��' => '軡',
  '��' => '逤',
  '��' => '逋',
  '��' => '逑',
  '��' => '逜',
  '��' => '逌',
  '��' => '逡',
  '��' => '郯',
  '��' => '郪',
  '��' => '郰',
  '��' => '郴',
  '��' => '郲',
  '��' => '郳',
  '��' => '郔',
  '��' => '郫',
  '��' => '郬',
  '��' => '郩',
  '��' => '酖',
  '��' => '酘',
  '��' => '酚',
  '�' => '酓',
  '�' => '酕',
  '�' => '釬',
  '�' => '釴',
  '�' => '釱',
  '�' => '釳',
  '�' => '釸',
  '�' => '釤',
  '�' => '釹',
  '�' => '釪',
  '�@' => '釫',
  '�A' => '釷',
  '�B' => '釨',
  '�C' => '釮',
  '�D' => '镺',
  '�E' => '閆',
  '�F' => '閈',
  '�G' => '陼',
  '�H' => '陭',
  '�I' => '陫',
  '�J' => '陱',
  '�K' => '陯',
  '�L' => '隿',
  '�M' => '靪',
  '�N' => '頄',
  '�O' => '飥',
  '�P' => '馗',
  '�Q' => '傛',
  '�R' => '傕',
  '�S' => '傔',
  '�T' => '傞',
  '�U' => '傋',
  '�V' => '傣',
  '�W' => '傃',
  '�X' => '傌',
  '�Y' => '傎',
  '�Z' => '傝',
  '�[' => '偨',
  '�\\' => '傜',
  '�]' => '傒',
  '�^' => '傂',
  '�_' => '傇',
  '�`' => '兟',
  '�a' => '凔',
  '�b' => '匒',
  '�c' => '匑',
  '�d' => '厤',
  '�e' => '厧',
  '�f' => '喑',
  '�g' => '喨',
  '�h' => '喥',
  '�i' => '喭',
  '�j' => '啷',
  '�k' => '噅',
  '�l' => '喢',
  '�m' => '喓',
  '�n' => '喈',
  '�o' => '喏',
  '�p' => '喵',
  '�q' => '喁',
  '�r' => '喣',
  '�s' => '喒',
  '�t' => '喤',
  '�u' => '啽',
  '�v' => '喌',
  '�w' => '喦',
  '�x' => '啿',
  '�y' => '喕',
  '�z' => '喡',
  '�{' => '喎',
  '�|' => '圌',
  '�}' => '堩',
  '�~' => '堷',
  'ء' => '堙',
  'آ' => '堞',
  'أ' => '堧',
  'ؤ' => '堣',
  'إ' => '堨',
  'ئ' => '埵',
  'ا' => '塈',
  'ب' => '堥',
  'ة' => '堜',
  'ت' => '堛',
  'ث' => '堳',
  'ج' => '堿',
  'ح' => '堶',
  'خ' => '堮',
  'د' => '堹',
  'ذ' => '堸',
  'ر' => '堭',
  'ز' => '堬',
  'س' => '堻',
  'ش' => '奡',
  'ص' => '媯',
  'ض' => '媔',
  'ط' => '媟',
  'ظ' => '婺',
  'ع' => '媢',
  'غ' => '媞',
  'ػ' => '婸',
  'ؼ' => '媦',
  'ؽ' => '婼',
  'ؾ' => '媥',
  'ؿ' => '媬',
  '�' => '媕',
  '�' => '媮',
  '��' => '娷',
  '��' => '媄',
  '��' => '媊',
  '��' => '媗',
  '��' => '媃',
  '��' => '媋',
  '��' => '媩',
  '��' => '婻',
  '��' => '婽',
  '��' => '媌',
  '��' => '媜',
  '��' => '媏',
  '��' => '媓',
  '��' => '媝',
  '��' => '寪',
  '��' => '寍',
  '��' => '寋',
  '��' => '寔',
  '��' => '寑',
  '��' => '寊',
  '��' => '寎',
  '��' => '尌',
  '��' => '尰',
  '��' => '崷',
  '��' => '嵃',
  '��' => '嵫',
  '��' => '嵁',
  '��' => '嵋',
  '��' => '崿',
  '��' => '崵',
  '��' => '嵑',
  '��' => '嵎',
  '��' => '嵕',
  '��' => '崳',
  '��' => '崺',
  '��' => '嵒',
  '��' => '崽',
  '��' => '崱',
  '��' => '嵙',
  '��' => '嵂',
  '��' => '崹',
  '��' => '嵉',
  '��' => '崸',
  '��' => '崼',
  '��' => '崲',
  '��' => '崶',
  '��' => '嵀',
  '��' => '嵅',
  '��' => '幄',
  '��' => '幁',
  '��' => '彘',
  '�' => '徦',
  '�' => '徥',
  '�' => '徫',
  '�' => '惉',
  '�' => '悹',
  '�' => '惌',
  '�' => '惢',
  '�' => '惎',
  '�' => '惄',
  '�' => '愔',
  '�@' => '惲',
  '�A' => '愊',
  '�B' => '愖',
  '�C' => '愅',
  '�D' => '惵',
  '�E' => '愓',
  '�F' => '惸',
  '�G' => '惼',
  '�H' => '惾',
  '�I' => '惁',
  '�J' => '愃',
  '�K' => '愘',
  '�L' => '愝',
  '�M' => '愐',
  '�N' => '惿',
  '�O' => '愄',
  '�P' => '愋',
  '�Q' => '扊',
  '�R' => '掔',
  '�S' => '掱',
  '�T' => '掰',
  '�U' => '揎',
  '�V' => '揥',
  '�W' => '揨',
  '�X' => '揯',
  '�Y' => '揃',
  '�Z' => '撝',
  '�[' => '揳',
  '�\\' => '揊',
  '�]' => '揠',
  '�^' => '揶',
  '�_' => '揕',
  '�`' => '揲',
  '�a' => '揵',
  '�b' => '摡',
  '�c' => '揟',
  '�d' => '掾',
  '�e' => '揝',
  '�f' => '揜',
  '�g' => '揄',
  '�h' => '揘',
  '�i' => '揓',
  '�j' => '揂',
  '�k' => '揇',
  '�l' => '揌',
  '�m' => '揋',
  '�n' => '揈',
  '�o' => '揰',
  '�p' => '揗',
  '�q' => '揙',
  '�r' => '攲',
  '�s' => '敧',
  '�t' => '敪',
  '�u' => '敤',
  '�v' => '敜',
  '�w' => '敨',
  '�x' => '敥',
  '�y' => '斌',
  '�z' => '斝',
  '�{' => '斞',
  '�|' => '斮',
  '�}' => '旐',
  '�~' => '旒',
  '١' => '晼',
  '٢' => '晬',
  '٣' => '晻',
  '٤' => '暀',
  '٥' => '晱',
  '٦' => '晹',
  '٧' => '晪',
  '٨' => '晲',
  '٩' => '朁',
  '٪' => '椌',
  '٫' => '棓',
  '٬' => '椄',
  '٭' => '棜',
  'ٮ' => '椪',
  'ٯ' => '棬',
  'ٰ' => '棪',
  'ٱ' => '棱',
  'ٲ' => '椏',
  'ٳ' => '棖',
  'ٴ' => '棷',
  'ٵ' => '棫',
  'ٶ' => '棤',
  'ٷ' => '棶',
  'ٸ' => '椓',
  'ٹ' => '椐',
  'ٺ' => '棳',
  'ٻ' => '棡',
  'ټ' => '椇',
  'ٽ' => '棌',
  'پ' => '椈',
  'ٿ' => '楰',
  '�' => '梴',
  '�' => '椑',
  '��' => '棯',
  '��' => '棆',
  '��' => '椔',
  '��' => '棸',
  '��' => '棐',
  '��' => '棽',
  '��' => '棼',
  '��' => '棨',
  '��' => '椋',
  '��' => '椊',
  '��' => '椗',
  '��' => '棎',
  '��' => '棈',
  '��' => '棝',
  '��' => '棞',
  '��' => '棦',
  '��' => '棴',
  '��' => '棑',
  '��' => '椆',
  '��' => '棔',
  '��' => '棩',
  '��' => '椕',
  '��' => '椥',
  '��' => '棇',
  '��' => '欹',
  '��' => '欻',
  '��' => '欿',
  '��' => '欼',
  '��' => '殔',
  '��' => '殗',
  '��' => '殙',
  '��' => '殕',
  '��' => '殽',
  '��' => '毰',
  '��' => '毲',
  '��' => '毳',
  '��' => '氰',
  '��' => '淼',
  '��' => '湆',
  '��' => '湇',
  '��' => '渟',
  '��' => '湉',
  '��' => '溈',
  '��' => '渼',
  '��' => '渽',
  '��' => '湅',
  '��' => '湢',
  '��' => '渫',
  '��' => '渿',
  '��' => '湁',
  '��' => '湝',
  '�' => '湳',
  '�' => '渜',
  '�' => '渳',
  '�' => '湋',
  '�' => '湀',
  '�' => '湑',
  '�' => '渻',
  '�' => '渃',
  '�' => '渮',
  '�' => '湞',
  '�@' => '湨',
  '�A' => '湜',
  '�B' => '湡',
  '�C' => '渱',
  '�D' => '渨',
  '�E' => '湠',
  '�F' => '湱',
  '�G' => '湫',
  '�H' => '渹',
  '�I' => '渢',
  '�J' => '渰',
  '�K' => '湓',
  '�L' => '湥',
  '�M' => '渧',
  '�N' => '湸',
  '�O' => '湤',
  '�P' => '湷',
  '�Q' => '湕',
  '�R' => '湹',
  '�S' => '湒',
  '�T' => '湦',
  '�U' => '渵',
  '�V' => '渶',
  '�W' => '湚',
  '�X' => '焠',
  '�Y' => '焞',
  '�Z' => '焯',
  '�[' => '烻',
  '�\\' => '焮',
  '�]' => '焱',
  '�^' => '焣',
  '�_' => '焥',
  '�`' => '焢',
  '�a' => '焲',
  '�b' => '焟',
  '�c' => '焨',
  '�d' => '焺',
  '�e' => '焛',
  '�f' => '牋',
  '�g' => '牚',
  '�h' => '犈',
  '�i' => '犉',
  '�j' => '犆',
  '�k' => '犅',
  '�l' => '犋',
  '�m' => '猒',
  '�n' => '猋',
  '�o' => '猰',
  '�p' => '猢',
  '�q' => '猱',
  '�r' => '猳',
  '�s' => '猧',
  '�t' => '猲',
  '�u' => '猭',
  '�v' => '猦',
  '�w' => '猣',
  '�x' => '猵',
  '�y' => '猌',
  '�z' => '琮',
  '�{' => '琬',
  '�|' => '琰',
  '�}' => '琫',
  '�~' => '琖',
  'ڡ' => '琚',
  'ڢ' => '琡',
  'ڣ' => '琭',
  'ڤ' => '琱',
  'ڥ' => '琤',
  'ڦ' => '琣',
  'ڧ' => '琝',
  'ڨ' => '琩',
  'ک' => '琠',
  'ڪ' => '琲',
  'ګ' => '瓻',
  'ڬ' => '甯',
  'ڭ' => '畯',
  'ڮ' => '畬',
  'گ' => '痧',
  'ڰ' => '痚',
  'ڱ' => '痡',
  'ڲ' => '痦',
  'ڳ' => '痝',
  'ڴ' => '痟',
  'ڵ' => '痤',
  'ڶ' => '痗',
  'ڷ' => '皕',
  'ڸ' => '皒',
  'ڹ' => '盚',
  'ں' => '睆',
  'ڻ' => '睇',
  'ڼ' => '睄',
  'ڽ' => '睍',
  'ھ' => '睅',
  'ڿ' => '睊',
  '�' => '睎',
  '�' => '睋',
  '��' => '睌',
  '��' => '矞',
  '��' => '矬',
  '��' => '硠',
  '��' => '硤',
  '��' => '硥',
  '��' => '硜',
  '��' => '硭',
  '��' => '硱',
  '��' => '硪',
  '��' => '确',
  '��' => '硰',
  '��' => '硩',
  '��' => '硨',
  '��' => '硞',
  '��' => '硢',
  '��' => '祴',
  '��' => '祳',
  '��' => '祲',
  '��' => '祰',
  '��' => '稂',
  '��' => '稊',
  '��' => '稃',
  '��' => '稌',
  '��' => '稄',
  '��' => '窙',
  '��' => '竦',
  '��' => '竤',
  '��' => '筊',
  '��' => '笻',
  '��' => '筄',
  '��' => '筈',
  '��' => '筌',
  '��' => '筎',
  '��' => '筀',
  '��' => '筘',
  '��' => '筅',
  '��' => '粢',
  '��' => '粞',
  '��' => '粨',
  '��' => '粡',
  '��' => '絘',
  '��' => '絯',
  '��' => '絣',
  '��' => '絓',
  '��' => '絖',
  '��' => '絧',
  '��' => '絪',
  '��' => '絏',
  '��' => '絭',
  '��' => '絜',
  '�' => '絫',
  '�' => '絒',
  '�' => '絔',
  '�' => '絩',
  '�' => '絑',
  '�' => '絟',
  '�' => '絎',
  '�' => '缾',
  '�' => '缿',
  '�' => '罥',
  '�@' => '罦',
  '�A' => '羢',
  '�B' => '羠',
  '�C' => '羡',
  '�D' => '翗',
  '�E' => '聑',
  '�F' => '聏',
  '�G' => '聐',
  '�H' => '胾',
  '�I' => '胔',
  '�J' => '腃',
  '�K' => '腊',
  '�L' => '腒',
  '�M' => '腏',
  '�N' => '腇',
  '�O' => '脽',
  '�P' => '腍',
  '�Q' => '脺',
  '�R' => '臦',
  '�S' => '臮',
  '�T' => '臷',
  '�U' => '臸',
  '�V' => '臹',
  '�W' => '舄',
  '�X' => '舼',
  '�Y' => '舽',
  '�Z' => '舿',
  '�[' => '艵',
  '�\\' => '茻',
  '�]' => '菏',
  '�^' => '菹',
  '�_' => '萣',
  '�`' => '菀',
  '�a' => '菨',
  '�b' => '萒',
  '�c' => '菧',
  '�d' => '菤',
  '�e' => '菼',
  '�f' => '菶',
  '�g' => '萐',
  '�h' => '菆',
  '�i' => '菈',
  '�j' => '菫',
  '�k' => '菣',
  '�l' => '莿',
  '�m' => '萁',
  '�n' => '菝',
  '�o' => '菥',
  '�p' => '菘',
  '�q' => '菿',
  '�r' => '菡',
  '�s' => '菋',
  '�t' => '菎',
  '�u' => '菖',
  '�v' => '菵',
  '�w' => '菉',
  '�x' => '萉',
  '�y' => '萏',
  '�z' => '菞',
  '�{' => '萑',
  '�|' => '萆',
  '�}' => '菂',
  '�~' => '菳',
  'ۡ' => '菕',
  'ۢ' => '菺',
  'ۣ' => '菇',
  'ۤ' => '菑',
  'ۥ' => '菪',
  'ۦ' => '萓',
  'ۧ' => '菃',
  'ۨ' => '菬',
  '۩' => '菮',
  '۪' => '菄',
  '۫' => '菻',
  '۬' => '菗',
  'ۭ' => '菢',
  'ۮ' => '萛',
  'ۯ' => '菛',
  '۰' => '菾',
  '۱' => '蛘',
  '۲' => '蛢',
  '۳' => '蛦',
  '۴' => '蛓',
  '۵' => '蛣',
  '۶' => '蛚',
  '۷' => '蛪',
  '۸' => '蛝',
  '۹' => '蛫',
  'ۺ' => '蛜',
  'ۻ' => '蛬',
  'ۼ' => '蛩',
  '۽' => '蛗',
  '۾' => '蛨',
  'ۿ' => '蛑',
  '�' => '衈',
  '�' => '衖',
  '��' => '衕',
  '��' => '袺',
  '��' => '裗',
  '��' => '袹',
  '��' => '袸',
  '��' => '裀',
  '��' => '袾',
  '��' => '袶',
  '��' => '袼',
  '��' => '袷',
  '��' => '袽',
  '��' => '袲',
  '��' => '褁',
  '��' => '裉',
  '��' => '覕',
  '��' => '覘',
  '��' => '覗',
  '��' => '觝',
  '��' => '觚',
  '��' => '觛',
  '��' => '詎',
  '��' => '詍',
  '��' => '訹',
  '��' => '詙',
  '��' => '詀',
  '��' => '詗',
  '��' => '詘',
  '��' => '詄',
  '��' => '詅',
  '��' => '詒',
  '��' => '詈',
  '��' => '詑',
  '��' => '詊',
  '��' => '詌',
  '��' => '詏',
  '��' => '豟',
  '��' => '貁',
  '��' => '貀',
  '��' => '貺',
  '��' => '貾',
  '��' => '貰',
  '��' => '貹',
  '��' => '貵',
  '��' => '趄',
  '��' => '趀',
  '��' => '趉',
  '��' => '跘',
  '��' => '跓',
  '��' => '跍',
  '��' => '跇',
  '��' => '跖',
  '�' => '跜',
  '�' => '跏',
  '�' => '跕',
  '�' => '跙',
  '�' => '跈',
  '�' => '跗',
  '�' => '跅',
  '�' => '軯',
  '�' => '軷',
  '�' => '軺',
  '�@' => '軹',
  '�A' => '軦',
  '�B' => '軮',
  '�C' => '軥',
  '�D' => '軵',
  '�E' => '軧',
  '�F' => '軨',
  '�G' => '軶',
  '�H' => '軫',
  '�I' => '軱',
  '�J' => '軬',
  '�K' => '軴',
  '�L' => '軩',
  '�M' => '逭',
  '�N' => '逴',
  '�O' => '逯',
  '�P' => '鄆',
  '�Q' => '鄬',
  '�R' => '鄄',
  '�S' => '郿',
  '�T' => '郼',
  '�U' => '鄈',
  '�V' => '郹',
  '�W' => '郻',
  '�X' => '鄁',
  '�Y' => '鄀',
  '�Z' => '鄇',
  '�[' => '鄅',
  '�\\' => '鄃',
  '�]' => '酡',
  '�^' => '酤',
  '�_' => '酟',
  '�`' => '酢',
  '�a' => '酠',
  '�b' => '鈁',
  '�c' => '鈊',
  '�d' => '鈥',
  '�e' => '鈃',
  '�f' => '鈚',
  '�g' => '鈦',
  '�h' => '鈏',
  '�i' => '鈌',
  '�j' => '鈀',
  '�k' => '鈒',
  '�l' => '釿',
  '�m' => '釽',
  '�n' => '鈆',
  '�o' => '鈄',
  '�p' => '鈧',
  '�q' => '鈂',
  '�r' => '鈜',
  '�s' => '鈤',
  '�t' => '鈙',
  '�u' => '鈗',
  '�v' => '鈅',
  '�w' => '鈖',
  '�x' => '镻',
  '�y' => '閍',
  '�z' => '閌',
  '�{' => '閐',
  '�|' => '隇',
  '�}' => '陾',
  '�~' => '隈',
  'ܡ' => '隉',
  'ܢ' => '隃',
  'ܣ' => '隀',
  'ܤ' => '雂',
  'ܥ' => '雈',
  'ܦ' => '雃',
  'ܧ' => '雱',
  'ܨ' => '雰',
  'ܩ' => '靬',
  'ܪ' => '靰',
  'ܫ' => '靮',
  'ܬ' => '頇',
  'ܭ' => '颩',
  'ܮ' => '飫',
  'ܯ' => '鳦',
  'ܰ' => '黹',
  'ܱ' => '亃',
  'ܲ' => '亄',
  'ܳ' => '亶',
  'ܴ' => '傽',
  'ܵ' => '傿',
  'ܶ' => '僆',
  'ܷ' => '傮',
  'ܸ' => '僄',
  'ܹ' => '僊',
  'ܺ' => '傴',
  'ܻ' => '僈',
  'ܼ' => '僂',
  'ܽ' => '傰',
  'ܾ' => '僁',
  'ܿ' => '傺',
  '�' => '傱',
  '�' => '僋',
  '��' => '僉',
  '��' => '傶',
  '��' => '傸',
  '��' => '凗',
  '��' => '剺',
  '��' => '剸',
  '��' => '剻',
  '��' => '剼',
  '��' => '嗃',
  '��' => '嗛',
  '��' => '嗌',
  '��' => '嗐',
  '��' => '嗋',
  '��' => '嗊',
  '��' => '嗝',
  '��' => '嗀',
  '��' => '嗔',
  '��' => '嗄',
  '��' => '嗩',
  '��' => '喿',
  '��' => '嗒',
  '��' => '喍',
  '��' => '嗏',
  '��' => '嗕',
  '��' => '嗢',
  '��' => '嗖',
  '��' => '嗈',
  '��' => '嗲',
  '��' => '嗍',
  '��' => '嗙',
  '��' => '嗂',
  '��' => '圔',
  '��' => '塓',
  '��' => '塨',
  '��' => '塤',
  '��' => '塏',
  '��' => '塍',
  '��' => '塉',
  '��' => '塯',
  '��' => '塕',
  '��' => '塎',
  '��' => '塝',
  '��' => '塙',
  '��' => '塥',
  '��' => '塛',
  '��' => '堽',
  '��' => '塣',
  '��' => '塱',
  '��' => '壼',
  '��' => '嫇',
  '��' => '嫄',
  '�' => '嫋',
  '�' => '媺',
  '�' => '媸',
  '�' => '媱',
  '�' => '媵',
  '�' => '媰',
  '�' => '媿',
  '�' => '嫈',
  '�' => '媻',
  '�' => '嫆',
  '�@' => '媷',
  '�A' => '嫀',
  '�B' => '嫊',
  '�C' => '媴',
  '�D' => '媶',
  '�E' => '嫍',
  '�F' => '媹',
  '�G' => '媐',
  '�H' => '寖',
  '�I' => '寘',
  '�J' => '寙',
  '�K' => '尟',
  '�L' => '尳',
  '�M' => '嵱',
  '�N' => '嵣',
  '�O' => '嵊',
  '�P' => '嵥',
  '�Q' => '嵲',
  '�R' => '嵬',
  '�S' => '嵞',
  '�T' => '嵨',
  '�U' => '嵧',
  '�V' => '嵢',
  '�W' => '巰',
  '�X' => '幏',
  '�Y' => '幎',
  '�Z' => '幊',
  '�[' => '幍',
  '�\\' => '幋',
  '�]' => '廅',
  '�^' => '廌',
  '�_' => '廆',
  '�`' => '廋',
  '�a' => '廇',
  '�b' => '彀',
  '�c' => '徯',
  '�d' => '徭',
  '�e' => '惷',
  '�f' => '慉',
  '�g' => '慊',
  '�h' => '愫',
  '�i' => '慅',
  '�j' => '愶',
  '�k' => '愲',
  '�l' => '愮',
  '�m' => '慆',
  '�n' => '愯',
  '�o' => '慏',
  '�p' => '愩',
  '�q' => '慀',
  '�r' => '戠',
  '�s' => '酨',
  '�t' => '戣',
  '�u' => '戥',
  '�v' => '戤',
  '�w' => '揅',
  '�x' => '揱',
  '�y' => '揫',
  '�z' => '搐',
  '�{' => '搒',
  '�|' => '搉',
  '�}' => '搠',
  '�~' => '搤',
  'ݡ' => '搳',
  'ݢ' => '摃',
  'ݣ' => '搟',
  'ݤ' => '搕',
  'ݥ' => '搘',
  'ݦ' => '搹',
  'ݧ' => '搷',
  'ݨ' => '搢',
  'ݩ' => '搣',
  'ݪ' => '搌',
  'ݫ' => '搦',
  'ݬ' => '搰',
  'ݭ' => '搨',
  'ݮ' => '摁',
  'ݯ' => '搵',
  'ݰ' => '搯',
  'ݱ' => '搊',
  'ݲ' => '搚',
  'ݳ' => '摀',
  'ݴ' => '搥',
  'ݵ' => '搧',
  'ݶ' => '搋',
  'ݷ' => '揧',
  'ݸ' => '搛',
  'ݹ' => '搮',
  'ݺ' => '搡',
  'ݻ' => '搎',
  'ݼ' => '敯',
  'ݽ' => '斒',
  'ݾ' => '旓',
  'ݿ' => '暆',
  '�' => '暌',
  '�' => '暕',
  '��' => '暐',
  '��' => '暋',
  '��' => '暊',
  '��' => '暙',
  '��' => '暔',
  '��' => '晸',
  '��' => '朠',
  '��' => '楦',
  '��' => '楟',
  '��' => '椸',
  '��' => '楎',
  '��' => '楢',
  '��' => '楱',
  '��' => '椿',
  '��' => '楅',
  '��' => '楪',
  '��' => '椹',
  '��' => '楂',
  '��' => '楗',
  '��' => '楙',
  '��' => '楺',
  '��' => '楈',
  '��' => '楉',
  '��' => '椵',
  '��' => '楬',
  '��' => '椳',
  '��' => '椽',
  '��' => '楥',
  '��' => '棰',
  '��' => '楸',
  '��' => '椴',
  '��' => '楩',
  '��' => '楀',
  '��' => '楯',
  '��' => '楄',
  '��' => '楶',
  '��' => '楘',
  '��' => '楁',
  '��' => '楴',
  '��' => '楌',
  '��' => '椻',
  '��' => '楋',
  '��' => '椷',
  '��' => '楜',
  '��' => '楏',
  '��' => '楑',
  '��' => '椲',
  '��' => '楒',
  '��' => '椯',
  '��' => '楻',
  '��' => '椼',
  '�' => '歆',
  '�' => '歅',
  '�' => '歃',
  '�' => '歂',
  '�' => '歈',
  '�' => '歁',
  '�' => '殛',
  '�' => '嗀',
  '�' => '毻',
  '�' => '毼',
  '�@' => '毹',
  '�A' => '毷',
  '�B' => '毸',
  '�C' => '溛',
  '�D' => '滖',
  '�E' => '滈',
  '�F' => '溏',
  '�G' => '滀',
  '�H' => '溟',
  '�I' => '溓',
  '�J' => '溔',
  '�K' => '溠',
  '�L' => '溱',
  '�M' => '溹',
  '�N' => '滆',
  '�O' => '滒',
  '�P' => '溽',
  '�Q' => '滁',
  '�R' => '溞',
  '�S' => '滉',
  '�T' => '溷',
  '�U' => '溰',
  '�V' => '滍',
  '�W' => '溦',
  '�X' => '滏',
  '�Y' => '溲',
  '�Z' => '溾',
  '�[' => '滃',
  '�\\' => '滜',
  '�]' => '滘',
  '�^' => '溙',
  '�_' => '溒',
  '�`' => '溎',
  '�a' => '溍',
  '�b' => '溤',
  '�c' => '溡',
  '�d' => '溿',
  '�e' => '溳',
  '�f' => '滐',
  '�g' => '滊',
  '�h' => '溗',
  '�i' => '溮',
  '�j' => '溣',
  '�k' => '煇',
  '�l' => '煔',
  '�m' => '煒',
  '�n' => '煣',
  '�o' => '煠',
  '�p' => '煁',
  '�q' => '煝',
  '�r' => '煢',
  '�s' => '煲',
  '�t' => '煸',
  '�u' => '煪',
  '�v' => '煡',
  '�w' => '煂',
  '�x' => '煘',
  '�y' => '煃',
  '�z' => '煋',
  '�{' => '煰',
  '�|' => '煟',
  '�}' => '煐',
  '�~' => '煓',
  'ޡ' => '煄',
  'ޢ' => '煍',
  'ޣ' => '煚',
  'ޤ' => '牏',
  'ޥ' => '犍',
  'ަ' => '犌',
  'ާ' => '犑',
  'ި' => '犐',
  'ީ' => '犎',
  'ު' => '猼',
  'ޫ' => '獂',
  'ެ' => '猻',
  'ޭ' => '猺',
  'ޮ' => '獀',
  'ޯ' => '獊',
  'ް' => '獉',
  'ޱ' => '瑄',
  '޲' => '瑊',
  '޳' => '瑋',
  '޴' => '瑒',
  '޵' => '瑑',
  '޶' => '瑗',
  '޷' => '瑀',
  '޸' => '瑏',
  '޹' => '瑐',
  '޺' => '瑎',
  '޻' => '瑂',
  '޼' => '瑆',
  '޽' => '瑍',
  '޾' => '瑔',
  '޿' => '瓡',
  '�' => '瓿',
  '�' => '瓾',
  '��' => '瓽',
  '��' => '甝',
  '��' => '畹',
  '��' => '畷',
  '��' => '榃',
  '��' => '痯',
  '��' => '瘏',
  '��' => '瘃',
  '��' => '痷',
  '��' => '痾',
  '��' => '痼',
  '��' => '痹',
  '��' => '痸',
  '��' => '瘐',
  '��' => '痻',
  '��' => '痶',
  '��' => '痭',
  '��' => '痵',
  '��' => '痽',
  '��' => '皙',
  '��' => '皵',
  '��' => '盝',
  '��' => '睕',
  '��' => '睟',
  '��' => '睠',
  '��' => '睒',
  '��' => '睖',
  '��' => '睚',
  '��' => '睩',
  '��' => '睧',
  '��' => '睔',
  '��' => '睙',
  '��' => '睭',
  '��' => '矠',
  '��' => '碇',
  '��' => '碚',
  '��' => '碔',
  '��' => '碏',
  '��' => '碄',
  '��' => '碕',
  '��' => '碅',
  '��' => '碆',
  '��' => '碡',
  '��' => '碃',
  '��' => '硹',
  '��' => '碙',
  '��' => '碀',
  '��' => '碖',
  '��' => '硻',
  '��' => '祼',
  '��' => '禂',
  '�' => '祽',
  '�' => '祹',
  '�' => '稑',
  '�' => '稘',
  '�' => '稙',
  '�' => '稒',
  '�' => '稗',
  '�' => '稕',
  '�' => '稢',
  '�' => '稓',
  '�@' => '稛',
  '�A' => '稐',
  '�B' => '窣',
  '�C' => '窢',
  '�D' => '窞',
  '�E' => '竫',
  '�F' => '筦',
  '�G' => '筤',
  '�H' => '筭',
  '�I' => '筴',
  '�J' => '筩',
  '�K' => '筲',
  '�L' => '筥',
  '�M' => '筳',
  '�N' => '筱',
  '�O' => '筰',
  '�P' => '筡',
  '�Q' => '筸',
  '�R' => '筶',
  '�S' => '筣',
  '�T' => '粲',
  '�U' => '粴',
  '�V' => '粯',
  '�W' => '綈',
  '�X' => '綆',
  '�Y' => '綀',
  '�Z' => '綍',
  '�[' => '絿',
  '�\\' => '綅',
  '�]' => '絺',
  '�^' => '綎',
  '�_' => '絻',
  '�`' => '綃',
  '�a' => '絼',
  '�b' => '綌',
  '�c' => '綔',
  '�d' => '綄',
  '�e' => '絽',
  '�f' => '綒',
  '�g' => '罭',
  '�h' => '罫',
  '�i' => '罧',
  '�j' => '罨',
  '�k' => '罬',
  '�l' => '羦',
  '�m' => '羥',
  '�n' => '羧',
  '�o' => '翛',
  '�p' => '翜',
  '�q' => '耡',
  '�r' => '腤',
  '�s' => '腠',
  '�t' => '腷',
  '�u' => '腜',
  '�v' => '腩',
  '�w' => '腛',
  '�x' => '腢',
  '�y' => '腲',
  '�z' => '朡',
  '�{' => '腞',
  '�|' => '腶',
  '�}' => '腧',
  '�~' => '腯',
  'ߡ' => '腄',
  'ߢ' => '腡',
  'ߣ' => '舝',
  'ߤ' => '艉',
  'ߥ' => '艄',
  'ߦ' => '艀',
  'ߧ' => '艂',
  'ߨ' => '艅',
  'ߩ' => '蓱',
  'ߪ' => '萿',
  '߫' => '葖',
  '߬' => '葶',
  '߭' => '葹',
  '߮' => '蒏',
  '߯' => '蒍',
  '߰' => '葥',
  '߱' => '葑',
  '߲' => '葀',
  '߳' => '蒆',
  'ߴ' => '葧',
  'ߵ' => '萰',
  '߶' => '葍',
  '߷' => '葽',
  '߸' => '葚',
  '߹' => '葙',
  'ߺ' => '葴',
  '߻' => '葳',
  '߼' => '葝',
  '߽' => '蔇',
  '߾' => '葞',
  '߿' => '萷',
  '�' => '萺',
  '�' => '萴',
  '��' => '葺',
  '��' => '葃',
  '��' => '葸',
  '��' => '萲',
  '��' => '葅',
  '��' => '萩',
  '��' => '菙',
  '��' => '葋',
  '��' => '萯',
  '��' => '葂',
  '��' => '萭',
  '��' => '葟',
  '��' => '葰',
  '��' => '萹',
  '��' => '葎',
  '��' => '葌',
  '��' => '葒',
  '��' => '葯',
  '��' => '蓅',
  '��' => '蒎',
  '��' => '萻',
  '��' => '葇',
  '��' => '萶',
  '��' => '萳',
  '��' => '葨',
  '��' => '葾',
  '��' => '葄',
  '��' => '萫',
  '��' => '葠',
  '��' => '葔',
  '��' => '葮',
  '��' => '葐',
  '��' => '蜋',
  '��' => '蜄',
  '��' => '蛷',
  '��' => '蜌',
  '��' => '蛺',
  '��' => '蛖',
  '��' => '蛵',
  '��' => '蝍',
  '��' => '蛸',
  '��' => '蜎',
  '��' => '蜉',
  '��' => '蜁',
  '��' => '蛶',
  '��' => '蜍',
  '��' => '蜅',
  '��' => '裖',
  '��' => '裋',
  '��' => '裍',
  '��' => '裎',
  '�' => '裞',
  '�' => '裛',
  '�' => '裚',
  '�' => '裌',
  '�' => '裐',
  '�' => '覅',
  '�' => '覛',
  '�' => '觟',
  '�' => '觥',
  '�' => '觤',
  '�@' => '觡',
  '�A' => '觠',
  '�B' => '觢',
  '�C' => '觜',
  '�D' => '触',
  '�E' => '詶',
  '�F' => '誆',
  '�G' => '詿',
  '�H' => '詡',
  '�I' => '訿',
  '�J' => '詷',
  '�K' => '誂',
  '�L' => '誄',
  '�M' => '詵',
  '�N' => '誃',
  '�O' => '誁',
  '�P' => '詴',
  '�Q' => '詺',
  '�R' => '谼',
  '�S' => '豋',
  '�T' => '豊',
  '�U' => '豥',
  '�V' => '豤',
  '�W' => '豦',
  '�X' => '貆',
  '�Y' => '貄',
  '�Z' => '貅',
  '�[' => '賌',
  '�\\' => '赨',
  '�]' => '赩',
  '�^' => '趑',
  '�_' => '趌',
  '�`' => '趎',
  '�a' => '趏',
  '�b' => '趍',
  '�c' => '趓',
  '�d' => '趔',
  '�e' => '趐',
  '�f' => '趒',
  '�g' => '跰',
  '�h' => '跠',
  '�i' => '跬',
  '�j' => '跱',
  '�k' => '跮',
  '�l' => '跐',
  '�m' => '跩',
  '�n' => '跣',
  '�o' => '跢',
  '�p' => '跧',
  '�q' => '跲',
  '�r' => '跫',
  '�s' => '跴',
  '�t' => '輆',
  '�u' => '軿',
  '�v' => '輁',
  '�w' => '輀',
  '�x' => '輅',
  '�y' => '輇',
  '�z' => '輈',
  '�{' => '輂',
  '�|' => '輋',
  '�}' => '遒',
  '�~' => '逿',
  '�' => '遄',
  '�' => '遉',
  '�' => '逽',
  '�' => '鄐',
  '�' => '鄍',
  '�' => '鄏',
  '�' => '鄑',
  '�' => '鄖',
  '�' => '鄔',
  '�' => '鄋',
  '�' => '鄎',
  '�' => '酮',
  '�' => '酯',
  '�' => '鉈',
  '�' => '鉒',
  '�' => '鈰',
  '�' => '鈺',
  '�' => '鉦',
  '�' => '鈳',
  '�' => '鉥',
  '�' => '鉞',
  '�' => '銃',
  '�' => '鈮',
  '�' => '鉊',
  '�' => '鉆',
  '�' => '鉭',
  '�' => '鉬',
  '�' => '鉏',
  '�' => '鉠',
  '�' => '鉧',
  '�' => '鉯',
  '�' => '鈶',
  '�' => '鉡',
  '��' => '鉰',
  '��' => '鈱',
  '��' => '鉔',
  '��' => '鉣',
  '��' => '鉐',
  '��' => '鉲',
  '��' => '鉎',
  '��' => '鉓',
  '��' => '鉌',
  '��' => '鉖',
  '��' => '鈲',
  '��' => '閟',
  '��' => '閜',
  '��' => '閞',
  '��' => '閛',
  '��' => '隒',
  '��' => '隓',
  '��' => '隑',
  '��' => '隗',
  '��' => '雎',
  '��' => '雺',
  '��' => '雽',
  '��' => '雸',
  '��' => '雵',
  '��' => '靳',
  '��' => '靷',
  '��' => '靸',
  '��' => '靲',
  '��' => '頏',
  '��' => '頍',
  '��' => '頎',
  '��' => '颬',
  '��' => '飶',
  '��' => '飹',
  '��' => '馯',
  '��' => '馲',
  '��' => '馰',
  '��' => '馵',
  '��' => '骭',
  '��' => '骫',
  '��' => '魛',
  '��' => '鳪',
  '��' => '鳭',
  '��' => '鳧',
  '��' => '麀',
  '��' => '黽',
  '��' => '僦',
  '��' => '僔',
  '��' => '僗',
  '��' => '僨',
  '��' => '僳',
  '�' => '僛',
  '�' => '僪',
  '�' => '僝',
  '�' => '僤',
  '�' => '僓',
  '�' => '僬',
  '�' => '僰',
  '�' => '僯',
  '�' => '僣',
  '�' => '僠',
  '�@' => '凘',
  '�A' => '劀',
  '�B' => '劁',
  '�C' => '勩',
  '�D' => '勫',
  '�E' => '匰',
  '�F' => '厬',
  '�G' => '嘧',
  '�H' => '嘕',
  '�I' => '嘌',
  '�J' => '嘒',
  '�K' => '嗼',
  '�L' => '嘏',
  '�M' => '嘜',
  '�N' => '嘁',
  '�O' => '嘓',
  '�P' => '嘂',
  '�Q' => '嗺',
  '�R' => '嘝',
  '�S' => '嘄',
  '�T' => '嗿',
  '�U' => '嗹',
  '�V' => '墉',
  '�W' => '塼',
  '�X' => '墐',
  '�Y' => '墘',
  '�Z' => '墆',
  '�[' => '墁',
  '�\\' => '塿',
  '�]' => '塴',
  '�^' => '墋',
  '�_' => '塺',
  '�`' => '墇',
  '�a' => '墑',
  '�b' => '墎',
  '�c' => '塶',
  '�d' => '墂',
  '�e' => '墈',
  '�f' => '塻',
  '�g' => '墔',
  '�h' => '墏',
  '�i' => '壾',
  '�j' => '奫',
  '�k' => '嫜',
  '�l' => '嫮',
  '�m' => '嫥',
  '�n' => '嫕',
  '�o' => '嫪',
  '�p' => '嫚',
  '�q' => '嫭',
  '�r' => '嫫',
  '�s' => '嫳',
  '�t' => '嫢',
  '�u' => '嫠',
  '�v' => '嫛',
  '�w' => '嫬',
  '�x' => '嫞',
  '�y' => '嫝',
  '�z' => '嫙',
  '�{' => '嫨',
  '�|' => '嫟',
  '�}' => '孷',
  '�~' => '寠',
  '�' => '寣',
  '�' => '屣',
  '�' => '嶂',
  '�' => '嶀',
  '�' => '嵽',
  '�' => '嶆',
  '�' => '嵺',
  '�' => '嶁',
  '�' => '嵷',
  '�' => '嶊',
  '�' => '嶉',
  '�' => '嶈',
  '�' => '嵾',
  '�' => '嵼',
  '�' => '嶍',
  '�' => '嵹',
  '�' => '嵿',
  '�' => '幘',
  '�' => '幙',
  '�' => '幓',
  '�' => '廘',
  '�' => '廑',
  '�' => '廗',
  '�' => '廎',
  '�' => '廜',
  '�' => '廕',
  '�' => '廙',
  '�' => '廒',
  '�' => '廔',
  '�' => '彄',
  '�' => '彃',
  '�' => '彯',
  '�' => '徶',
  '��' => '愬',
  '��' => '愨',
  '��' => '慁',
  '��' => '慞',
  '��' => '慱',
  '��' => '慳',
  '��' => '慒',
  '��' => '慓',
  '��' => '慲',
  '��' => '慬',
  '��' => '憀',
  '��' => '慴',
  '��' => '慔',
  '��' => '慺',
  '��' => '慛',
  '��' => '慥',
  '��' => '愻',
  '��' => '慪',
  '��' => '慡',
  '��' => '慖',
  '��' => '戩',
  '��' => '戧',
  '��' => '戫',
  '��' => '搫',
  '��' => '摍',
  '��' => '摛',
  '��' => '摝',
  '��' => '摴',
  '��' => '摶',
  '��' => '摲',
  '��' => '摳',
  '��' => '摽',
  '��' => '摵',
  '��' => '摦',
  '��' => '撦',
  '��' => '摎',
  '��' => '撂',
  '��' => '摞',
  '��' => '摜',
  '��' => '摋',
  '��' => '摓',
  '��' => '摠',
  '��' => '摐',
  '��' => '摿',
  '��' => '搿',
  '��' => '摬',
  '��' => '摫',
  '��' => '摙',
  '��' => '摥',
  '��' => '摷',
  '��' => '敳',
  '�' => '斠',
  '�' => '暡',
  '�' => '暠',
  '�' => '暟',
  '�' => '朅',
  '�' => '朄',
  '�' => '朢',
  '�' => '榱',
  '�' => '榶',
  '�' => '槉',
  '�@' => '榠',
  '�A' => '槎',
  '�B' => '榖',
  '�C' => '榰',
  '�D' => '榬',
  '�E' => '榼',
  '�F' => '榑',
  '�G' => '榙',
  '�H' => '榎',
  '�I' => '榧',
  '�J' => '榍',
  '�K' => '榩',
  '�L' => '榾',
  '�M' => '榯',
  '�N' => '榿',
  '�O' => '槄',
  '�P' => '榽',
  '�Q' => '榤',
  '�R' => '槔',
  '�S' => '榹',
  '�T' => '槊',
  '�U' => '榚',
  '�V' => '槏',
  '�W' => '榳',
  '�X' => '榓',
  '�Y' => '榪',
  '�Z' => '榡',
  '�[' => '榞',
  '�\\' => '槙',
  '�]' => '榗',
  '�^' => '榐',
  '�_' => '槂',
  '�`' => '榵',
  '�a' => '榥',
  '�b' => '槆',
  '�c' => '歊',
  '�d' => '歍',
  '�e' => '歋',
  '�f' => '殞',
  '�g' => '殟',
  '�h' => '殠',
  '�i' => '毃',
  '�j' => '毄',
  '�k' => '毾',
  '�l' => '滎',
  '�m' => '滵',
  '�n' => '滱',
  '�o' => '漃',
  '�p' => '漥',
  '�q' => '滸',
  '�r' => '漷',
  '�s' => '滻',
  '�t' => '漮',
  '�u' => '漉',
  '�v' => '潎',
  '�w' => '漙',
  '�x' => '漚',
  '�y' => '漧',
  '�z' => '漘',
  '�{' => '漻',
  '�|' => '漒',
  '�}' => '滭',
  '�~' => '漊',
  '�' => '漶',
  '�' => '潳',
  '�' => '滹',
  '�' => '滮',
  '�' => '漭',
  '�' => '潀',
  '�' => '漰',
  '�' => '漼',
  '�' => '漵',
  '�' => '滫',
  '�' => '漇',
  '�' => '漎',
  '�' => '潃',
  '�' => '漅',
  '�' => '滽',
  '�' => '滶',
  '�' => '漹',
  '�' => '漜',
  '�' => '滼',
  '�' => '漺',
  '�' => '漟',
  '�' => '漍',
  '�' => '漞',
  '�' => '漈',
  '�' => '漡',
  '�' => '熇',
  '�' => '熐',
  '�' => '熉',
  '�' => '熀',
  '�' => '熅',
  '�' => '熂',
  '�' => '熏',
  '�' => '煻',
  '��' => '熆',
  '��' => '熁',
  '��' => '熗',
  '��' => '牄',
  '��' => '牓',
  '��' => '犗',
  '��' => '犕',
  '��' => '犓',
  '��' => '獃',
  '��' => '獍',
  '��' => '獑',
  '��' => '獌',
  '��' => '瑢',
  '��' => '瑳',
  '��' => '瑱',
  '��' => '瑵',
  '��' => '瑲',
  '��' => '瑧',
  '��' => '瑮',
  '��' => '甀',
  '��' => '甂',
  '��' => '甃',
  '��' => '畽',
  '��' => '疐',
  '��' => '瘖',
  '��' => '瘈',
  '��' => '瘌',
  '��' => '瘕',
  '��' => '瘑',
  '��' => '瘊',
  '��' => '瘔',
  '��' => '皸',
  '��' => '瞁',
  '��' => '睼',
  '��' => '瞅',
  '��' => '瞂',
  '��' => '睮',
  '��' => '瞀',
  '��' => '睯',
  '��' => '睾',
  '��' => '瞃',
  '��' => '碲',
  '��' => '碪',
  '��' => '碴',
  '��' => '碭',
  '��' => '碨',
  '��' => '硾',
  '��' => '碫',
  '��' => '碞',
  '��' => '碥',
  '��' => '碠',
  '�' => '碬',
  '�' => '碢',
  '�' => '碤',
  '�' => '禘',
  '�' => '禊',
  '�' => '禋',
  '�' => '禖',
  '�' => '禕',
  '�' => '禔',
  '�' => '禓',
  '�@' => '禗',
  '�A' => '禈',
  '�B' => '禒',
  '�C' => '禐',
  '�D' => '稫',
  '�E' => '穊',
  '�F' => '稰',
  '�G' => '稯',
  '�H' => '稨',
  '�I' => '稦',
  '�J' => '窨',
  '�K' => '窫',
  '�L' => '窬',
  '�M' => '竮',
  '�N' => '箈',
  '�O' => '箜',
  '�P' => '箊',
  '�Q' => '箑',
  '�R' => '箐',
  '�S' => '箖',
  '�T' => '箍',
  '�U' => '箌',
  '�V' => '箛',
  '�W' => '箎',
  '�X' => '箅',
  '�Y' => '箘',
  '�Z' => '劄',
  '�[' => '箙',
  '�\\' => '箤',
  '�]' => '箂',
  '�^' => '粻',
  '�_' => '粿',
  '�`' => '粼',
  '�a' => '粺',
  '�b' => '綧',
  '�c' => '綷',
  '�d' => '緂',
  '�e' => '綣',
  '�f' => '綪',
  '�g' => '緁',
  '�h' => '緀',
  '�i' => '緅',
  '�j' => '綝',
  '�k' => '緎',
  '�l' => '緄',
  '�m' => '緆',
  '�n' => '緋',
  '�o' => '緌',
  '�p' => '綯',
  '�q' => '綹',
  '�r' => '綖',
  '�s' => '綼',
  '�t' => '綟',
  '�u' => '綦',
  '�v' => '綮',
  '�w' => '綩',
  '�x' => '綡',
  '�y' => '緉',
  '�z' => '罳',
  '�{' => '翢',
  '�|' => '翣',
  '�}' => '翥',
  '�~' => '翞',
  '�' => '耤',
  '�' => '聝',
  '�' => '聜',
  '�' => '膉',
  '�' => '膆',
  '�' => '膃',
  '�' => '膇',
  '�' => '膍',
  '�' => '膌',
  '�' => '膋',
  '�' => '舕',
  '�' => '蒗',
  '�' => '蒤',
  '�' => '蒡',
  '�' => '蒟',
  '�' => '蒺',
  '�' => '蓎',
  '�' => '蓂',
  '�' => '蒬',
  '�' => '蒮',
  '�' => '蒫',
  '�' => '蒹',
  '�' => '蒴',
  '�' => '蓁',
  '�' => '蓍',
  '�' => '蒪',
  '�' => '蒚',
  '�' => '蒱',
  '�' => '蓐',
  '�' => '蒝',
  '�' => '蒧',
  '�' => '蒻',
  '�' => '蒢',
  '��' => '蒔',
  '��' => '蓇',
  '��' => '蓌',
  '��' => '蒛',
  '��' => '蒩',
  '��' => '蒯',
  '��' => '蒨',
  '��' => '蓖',
  '��' => '蒘',
  '��' => '蒶',
  '��' => '蓏',
  '��' => '蒠',
  '��' => '蓗',
  '��' => '蓔',
  '��' => '蓒',
  '��' => '蓛',
  '��' => '蒰',
  '��' => '蒑',
  '��' => '虡',
  '��' => '蜳',
  '��' => '蜣',
  '��' => '蜨',
  '��' => '蝫',
  '��' => '蝀',
  '��' => '蜮',
  '��' => '蜞',
  '��' => '蜡',
  '��' => '蜙',
  '��' => '蜛',
  '��' => '蝃',
  '��' => '蜬',
  '��' => '蝁',
  '��' => '蜾',
  '��' => '蝆',
  '��' => '蜠',
  '��' => '蜲',
  '��' => '蜪',
  '��' => '蜭',
  '��' => '蜼',
  '��' => '蜒',
  '��' => '蜺',
  '��' => '蜱',
  '��' => '蜵',
  '��' => '蝂',
  '��' => '蜦',
  '��' => '蜧',
  '��' => '蜸',
  '��' => '蜤',
  '��' => '蜚',
  '��' => '蜰',
  '��' => '蜑',
  '�' => '裷',
  '�' => '裧',
  '�' => '裱',
  '�' => '裲',
  '�' => '裺',
  '�' => '裾',
  '�' => '裮',
  '�' => '裼',
  '�' => '裶',
  '�' => '裻',
  '�@' => '裰',
  '�A' => '裬',
  '�B' => '裫',
  '�C' => '覝',
  '�D' => '覡',
  '�E' => '覟',
  '�F' => '覞',
  '�G' => '觩',
  '�H' => '觫',
  '�I' => '觨',
  '�J' => '誫',
  '�K' => '誙',
  '�L' => '誋',
  '�M' => '誒',
  '�N' => '誏',
  '�O' => '誖',
  '�P' => '谽',
  '�Q' => '豨',
  '�R' => '豩',
  '�S' => '賕',
  '�T' => '賏',
  '�U' => '賗',
  '�V' => '趖',
  '�W' => '踉',
  '�X' => '踂',
  '�Y' => '跿',
  '�Z' => '踍',
  '�[' => '跽',
  '�\\' => '踊',
  '�]' => '踃',
  '�^' => '踇',
  '�_' => '踆',
  '�`' => '踅',
  '�a' => '跾',
  '�b' => '踀',
  '�c' => '踄',
  '�d' => '輐',
  '�e' => '輑',
  '�f' => '輎',
  '�g' => '輍',
  '�h' => '鄣',
  '�i' => '鄜',
  '�j' => '鄠',
  '�k' => '鄢',
  '�l' => '鄟',
  '�m' => '鄝',
  '�n' => '鄚',
  '�o' => '鄤',
  '�p' => '鄡',
  '�q' => '鄛',
  '�r' => '酺',
  '�s' => '酲',
  '�t' => '酹',
  '�u' => '酳',
  '�v' => '銥',
  '�w' => '銤',
  '�x' => '鉶',
  '�y' => '銛',
  '�z' => '鉺',
  '�{' => '銠',
  '�|' => '銔',
  '�}' => '銪',
  '�~' => '銍',
  '�' => '銦',
  '�' => '銚',
  '�' => '銫',
  '�' => '鉹',
  '�' => '銗',
  '�' => '鉿',
  '�' => '銣',
  '�' => '鋮',
  '�' => '銎',
  '�' => '銂',
  '�' => '銕',
  '�' => '銢',
  '�' => '鉽',
  '�' => '銈',
  '�' => '銡',
  '�' => '銊',
  '�' => '銆',
  '�' => '銌',
  '�' => '銙',
  '�' => '銧',
  '�' => '鉾',
  '�' => '銇',
  '�' => '銩',
  '�' => '銝',
  '�' => '銋',
  '�' => '鈭',
  '�' => '隞',
  '�' => '隡',
  '�' => '雿',
  '�' => '靘',
  '�' => '靽',
  '�' => '靺',
  '�' => '靾',
  '��' => '鞃',
  '��' => '鞀',
  '��' => '鞂',
  '��' => '靻',
  '��' => '鞄',
  '��' => '鞁',
  '��' => '靿',
  '��' => '韎',
  '��' => '韍',
  '��' => '頖',
  '��' => '颭',
  '��' => '颮',
  '��' => '餂',
  '��' => '餀',
  '��' => '餇',
  '��' => '馝',
  '��' => '馜',
  '��' => '駃',
  '��' => '馹',
  '��' => '馻',
  '��' => '馺',
  '��' => '駂',
  '��' => '馽',
  '��' => '駇',
  '��' => '骱',
  '��' => '髣',
  '��' => '髧',
  '��' => '鬾',
  '��' => '鬿',
  '��' => '魠',
  '��' => '魡',
  '��' => '魟',
  '��' => '鳱',
  '��' => '鳲',
  '��' => '鳵',
  '��' => '麧',
  '��' => '僿',
  '��' => '儃',
  '��' => '儰',
  '��' => '僸',
  '��' => '儆',
  '��' => '儇',
  '��' => '僶',
  '��' => '僾',
  '��' => '儋',
  '��' => '儌',
  '��' => '僽',
  '��' => '儊',
  '��' => '劋',
  '��' => '劌',
  '��' => '勱',
  '�' => '勯',
  '�' => '噈',
  '�' => '噂',
  '�' => '噌',
  '�' => '嘵',
  '�' => '噁',
  '�' => '噊',
  '�' => '噉',
  '�' => '噆',
  '�' => '噘',
  '�@' => '噚',
  '�A' => '噀',
  '�B' => '嘳',
  '�C' => '嘽',
  '�D' => '嘬',
  '�E' => '嘾',
  '�F' => '嘸',
  '�G' => '嘪',
  '�H' => '嘺',
  '�I' => '圚',
  '�J' => '墫',
  '�K' => '墝',
  '�L' => '墱',
  '�M' => '墠',
  '�N' => '墣',
  '�O' => '墯',
  '�P' => '墬',
  '�Q' => '墥',
  '�R' => '墡',
  '�S' => '壿',
  '�T' => '嫿',
  '�U' => '嫴',
  '�V' => '嫽',
  '�W' => '嫷',
  '�X' => '嫶',
  '�Y' => '嬃',
  '�Z' => '嫸',
  '�[' => '嬂',
  '�\\' => '嫹',
  '�]' => '嬁',
  '�^' => '嬇',
  '�_' => '嬅',
  '�`' => '嬏',
  '�a' => '屧',
  '�b' => '嶙',
  '�c' => '嶗',
  '�d' => '嶟',
  '�e' => '嶒',
  '�f' => '嶢',
  '�g' => '嶓',
  '�h' => '嶕',
  '�i' => '嶠',
  '�j' => '嶜',
  '�k' => '嶡',
  '�l' => '嶚',
  '�m' => '嶞',
  '�n' => '幩',
  '�o' => '幝',
  '�p' => '幠',
  '�q' => '幜',
  '�r' => '緳',
  '�s' => '廛',
  '�t' => '廞',
  '�u' => '廡',
  '�v' => '彉',
  '�w' => '徲',
  '�x' => '憋',
  '�y' => '憃',
  '�z' => '慹',
  '�{' => '憱',
  '�|' => '憰',
  '�}' => '憢',
  '�~' => '憉',
  '�' => '憛',
  '�' => '憓',
  '�' => '憯',
  '�' => '憭',
  '�' => '憟',
  '�' => '憒',
  '�' => '憪',
  '�' => '憡',
  '�' => '憍',
  '�' => '慦',
  '�' => '憳',
  '�' => '戭',
  '�' => '摮',
  '�' => '摰',
  '�' => '撖',
  '�' => '撠',
  '�' => '撅',
  '�' => '撗',
  '�' => '撜',
  '�' => '撏',
  '�' => '撋',
  '�' => '撊',
  '�' => '撌',
  '�' => '撣',
  '�' => '撟',
  '�' => '摨',
  '�' => '撱',
  '�' => '撘',
  '�' => '敶',
  '�' => '敺',
  '�' => '敹',
  '�' => '敻',
  '�' => '斲',
  '��' => '斳',
  '��' => '暵',
  '��' => '暰',
  '��' => '暩',
  '��' => '暲',
  '��' => '暷',
  '��' => '暪',
  '��' => '暯',
  '��' => '樀',
  '��' => '樆',
  '��' => '樗',
  '��' => '槥',
  '��' => '槸',
  '��' => '樕',
  '��' => '槱',
  '��' => '槤',
  '��' => '樠',
  '��' => '槿',
  '��' => '槬',
  '��' => '槢',
  '��' => '樛',
  '��' => '樝',
  '��' => '槾',
  '��' => '樧',
  '��' => '槲',
  '��' => '槮',
  '��' => '樔',
  '��' => '槷',
  '��' => '槧',
  '��' => '橀',
  '��' => '樈',
  '��' => '槦',
  '��' => '槻',
  '��' => '樍',
  '��' => '槼',
  '��' => '槫',
  '��' => '樉',
  '��' => '樄',
  '��' => '樘',
  '��' => '樥',
  '��' => '樏',
  '��' => '槶',
  '��' => '樦',
  '��' => '樇',
  '��' => '槴',
  '��' => '樖',
  '��' => '歑',
  '��' => '殥',
  '��' => '殣',
  '��' => '殢',
  '��' => '殦',
  '�' => '氁',
  '�' => '氀',
  '�' => '毿',
  '�' => '氂',
  '�' => '潁',
  '�' => '漦',
  '�' => '潾',
  '�' => '澇',
  '�' => '濆',
  '�' => '澒',
  '�@' => '澍',
  '�A' => '澉',
  '�B' => '澌',
  '�C' => '潢',
  '�D' => '潏',
  '�E' => '澅',
  '�F' => '潚',
  '�G' => '澖',
  '�H' => '潶',
  '�I' => '潬',
  '�J' => '澂',
  '�K' => '潕',
  '�L' => '潲',
  '�M' => '潒',
  '�N' => '潐',
  '�O' => '潗',
  '�P' => '澔',
  '�Q' => '澓',
  '�R' => '潝',
  '�S' => '漀',
  '�T' => '潡',
  '�U' => '潫',
  '�V' => '潽',
  '�W' => '潧',
  '�X' => '澐',
  '�Y' => '潓',
  '�Z' => '澋',
  '�[' => '潩',
  '�\\' => '潿',
  '�]' => '澕',
  '�^' => '潣',
  '�_' => '潷',
  '�`' => '潪',
  '�a' => '潻',
  '�b' => '熲',
  '�c' => '熯',
  '�d' => '熛',
  '�e' => '熰',
  '�f' => '熠',
  '�g' => '熚',
  '�h' => '熩',
  '�i' => '熵',
  '�j' => '熝',
  '�k' => '熥',
  '�l' => '熞',
  '�m' => '熤',
  '�n' => '熡',
  '�o' => '熪',
  '�p' => '熜',
  '�q' => '熧',
  '�r' => '熳',
  '�s' => '犘',
  '�t' => '犚',
  '�u' => '獘',
  '�v' => '獒',
  '�w' => '獞',
  '�x' => '獟',
  '�y' => '獠',
  '�z' => '獝',
  '�{' => '獛',
  '�|' => '獡',
  '�}' => '獚',
  '�~' => '獙',
  '�' => '獢',
  '�' => '璇',
  '�' => '璉',
  '�' => '璊',
  '�' => '璆',
  '�' => '璁',
  '�' => '瑽',
  '�' => '璅',
  '�' => '璈',
  '�' => '瑼',
  '�' => '瑹',
  '�' => '甈',
  '�' => '甇',
  '�' => '畾',
  '�' => '瘥',
  '�' => '瘞',
  '�' => '瘙',
  '�' => '瘝',
  '�' => '瘜',
  '�' => '瘣',
  '�' => '瘚',
  '�' => '瘨',
  '�' => '瘛',
  '�' => '皜',
  '�' => '皝',
  '�' => '皞',
  '�' => '皛',
  '�' => '瞍',
  '�' => '瞏',
  '�' => '瞉',
  '�' => '瞈',
  '�' => '磍',
  '�' => '碻',
  '��' => '磏',
  '��' => '磌',
  '��' => '磑',
  '��' => '磎',
  '��' => '磔',
  '��' => '磈',
  '��' => '磃',
  '��' => '磄',
  '��' => '磉',
  '��' => '禚',
  '��' => '禡',
  '��' => '禠',
  '��' => '禜',
  '��' => '禢',
  '��' => '禛',
  '��' => '歶',
  '��' => '稹',
  '��' => '窲',
  '��' => '窴',
  '��' => '窳',
  '��' => '箷',
  '��' => '篋',
  '��' => '箾',
  '��' => '箬',
  '��' => '篎',
  '��' => '箯',
  '��' => '箹',
  '��' => '篊',
  '��' => '箵',
  '��' => '糅',
  '��' => '糈',
  '��' => '糌',
  '��' => '糋',
  '��' => '緷',
  '��' => '緛',
  '��' => '緪',
  '��' => '緧',
  '��' => '緗',
  '��' => '緡',
  '��' => '縃',
  '��' => '緺',
  '��' => '緦',
  '��' => '緶',
  '��' => '緱',
  '��' => '緰',
  '��' => '緮',
  '��' => '緟',
  '��' => '罶',
  '��' => '羬',
  '��' => '羰',
  '��' => '羭',
  '�' => '翭',
  '�' => '翫',
  '�' => '翪',
  '�' => '翬',
  '�' => '翦',
  '�' => '翨',
  '�' => '聤',
  '�' => '聧',
  '�' => '膣',
  '�' => '膟',
  '�@' => '膞',
  '�A' => '膕',
  '�B' => '膢',
  '�C' => '膙',
  '�D' => '膗',
  '�E' => '舖',
  '�F' => '艏',
  '�G' => '艓',
  '�H' => '艒',
  '�I' => '艐',
  '�J' => '艎',
  '�K' => '艑',
  '�L' => '蔤',
  '�M' => '蔻',
  '�N' => '蔏',
  '�O' => '蔀',
  '�P' => '蔩',
  '�Q' => '蔎',
  '�R' => '蔉',
  '�S' => '蔍',
  '�T' => '蔟',
  '�U' => '蔊',
  '�V' => '蔧',
  '�W' => '蔜',
  '�X' => '蓻',
  '�Y' => '蔫',
  '�Z' => '蓺',
  '�[' => '蔈',
  '�\\' => '蔌',
  '�]' => '蓴',
  '�^' => '蔪',
  '�_' => '蓲',
  '�`' => '蔕',
  '�a' => '蓷',
  '�b' => '蓫',
  '�c' => '蓳',
  '�d' => '蓼',
  '�e' => '蔒',
  '�f' => '蓪',
  '�g' => '蓩',
  '�h' => '蔖',
  '�i' => '蓾',
  '�j' => '蔨',
  '�k' => '蔝',
  '�l' => '蔮',
  '�m' => '蔂',
  '�n' => '蓽',
  '�o' => '蔞',
  '�p' => '蓶',
  '�q' => '蔱',
  '�r' => '蔦',
  '�s' => '蓧',
  '�t' => '蓨',
  '�u' => '蓰',
  '�v' => '蓯',
  '�w' => '蓹',
  '�x' => '蔘',
  '�y' => '蔠',
  '�z' => '蔰',
  '�{' => '蔋',
  '�|' => '蔙',
  '�}' => '蔯',
  '�~' => '虢',
  '�' => '蝖',
  '�' => '蝣',
  '�' => '蝤',
  '�' => '蝷',
  '�' => '蟡',
  '�' => '蝳',
  '�' => '蝘',
  '�' => '蝔',
  '�' => '蝛',
  '�' => '蝒',
  '�' => '蝡',
  '�' => '蝚',
  '�' => '蝑',
  '�' => '蝞',
  '�' => '蝭',
  '�' => '蝪',
  '�' => '蝐',
  '�' => '蝎',
  '�' => '蝟',
  '�' => '蝝',
  '�' => '蝯',
  '�' => '蝬',
  '�' => '蝺',
  '�' => '蝮',
  '�' => '蝜',
  '�' => '蝥',
  '�' => '蝏',
  '�' => '蝻',
  '�' => '蝵',
  '�' => '蝢',
  '�' => '蝧',
  '�' => '蝩',
  '�' => '衚',
  '��' => '褅',
  '��' => '褌',
  '��' => '褔',
  '��' => '褋',
  '��' => '褗',
  '��' => '褘',
  '��' => '褙',
  '��' => '褆',
  '��' => '褖',
  '��' => '褑',
  '��' => '褎',
  '��' => '褉',
  '��' => '覢',
  '��' => '覤',
  '��' => '覣',
  '��' => '觭',
  '��' => '觰',
  '��' => '觬',
  '��' => '諏',
  '��' => '諆',
  '��' => '誸',
  '��' => '諓',
  '��' => '諑',
  '��' => '諔',
  '��' => '諕',
  '��' => '誻',
  '��' => '諗',
  '��' => '誾',
  '��' => '諀',
  '��' => '諅',
  '��' => '諘',
  '��' => '諃',
  '��' => '誺',
  '��' => '誽',
  '��' => '諙',
  '��' => '谾',
  '��' => '豍',
  '��' => '貏',
  '��' => '賥',
  '��' => '賟',
  '��' => '賙',
  '��' => '賨',
  '��' => '賚',
  '��' => '賝',
  '��' => '賧',
  '��' => '趠',
  '��' => '趜',
  '��' => '趡',
  '��' => '趛',
  '��' => '踠',
  '��' => '踣',
  '�' => '踥',
  '�' => '踤',
  '�' => '踮',
  '�' => '踕',
  '�' => '踛',
  '�' => '踖',
  '�' => '踑',
  '�' => '踙',
  '�' => '踦',
  '�' => '踧',
  '�@' => '踔',
  '�A' => '踒',
  '�B' => '踘',
  '�C' => '踓',
  '�D' => '踜',
  '�E' => '踗',
  '�F' => '踚',
  '�G' => '輬',
  '�H' => '輤',
  '�I' => '輘',
  '�J' => '輚',
  '�K' => '輠',
  '�L' => '輣',
  '�M' => '輖',
  '�N' => '輗',
  '�O' => '遳',
  '�P' => '遰',
  '�Q' => '遯',
  '�R' => '遧',
  '�S' => '遫',
  '�T' => '鄯',
  '�U' => '鄫',
  '�V' => '鄩',
  '�W' => '鄪',
  '�X' => '鄲',
  '�Y' => '鄦',
  '�Z' => '鄮',
  '�[' => '醅',
  '�\\' => '醆',
  '�]' => '醊',
  '�^' => '醁',
  '�_' => '醂',
  '�`' => '醄',
  '�a' => '醀',
  '�b' => '鋐',
  '�c' => '鋃',
  '�d' => '鋄',
  '�e' => '鋀',
  '�f' => '鋙',
  '�g' => '銶',
  '�h' => '鋏',
  '�i' => '鋱',
  '�j' => '鋟',
  '�k' => '鋘',
  '�l' => '鋩',
  '�m' => '鋗',
  '�n' => '鋝',
  '�o' => '鋌',
  '�p' => '鋯',
  '�q' => '鋂',
  '�r' => '鋨',
  '�s' => '鋊',
  '�t' => '鋈',
  '�u' => '鋎',
  '�v' => '鋦',
  '�w' => '鋍',
  '�x' => '鋕',
  '�y' => '鋉',
  '�z' => '鋠',
  '�{' => '鋞',
  '�|' => '鋧',
  '�}' => '鋑',
  '�~' => '鋓',
  '�' => '銵',
  '�' => '鋡',
  '�' => '鋆',
  '�' => '銴',
  '�' => '镼',
  '�' => '閬',
  '�' => '閫',
  '�' => '閮',
  '�' => '閰',
  '�' => '隤',
  '�' => '隢',
  '�' => '雓',
  '�' => '霅',
  '�' => '霈',
  '�' => '霂',
  '�' => '靚',
  '�' => '鞊',
  '�' => '鞎',
  '�' => '鞈',
  '�' => '韐',
  '�' => '韏',
  '�' => '頞',
  '�' => '頝',
  '�' => '頦',
  '�' => '頩',
  '�' => '頨',
  '�' => '頠',
  '�' => '頛',
  '�' => '頧',
  '�' => '颲',
  '�' => '餈',
  '�' => '飺',
  '�' => '餑',
  '��' => '餔',
  '��' => '餖',
  '��' => '餗',
  '��' => '餕',
  '��' => '駜',
  '��' => '駍',
  '��' => '駏',
  '��' => '駓',
  '��' => '駔',
  '��' => '駎',
  '��' => '駉',
  '��' => '駖',
  '��' => '駘',
  '��' => '駋',
  '��' => '駗',
  '��' => '駌',
  '��' => '骳',
  '��' => '髬',
  '��' => '髫',
  '��' => '髳',
  '��' => '髲',
  '��' => '髱',
  '��' => '魆',
  '��' => '魃',
  '��' => '魧',
  '��' => '魴',
  '��' => '魱',
  '��' => '魦',
  '��' => '魶',
  '��' => '魵',
  '��' => '魰',
  '��' => '魨',
  '��' => '魤',
  '��' => '魬',
  '��' => '鳼',
  '��' => '鳺',
  '��' => '鳽',
  '��' => '鳿',
  '��' => '鳷',
  '��' => '鴇',
  '��' => '鴀',
  '��' => '鳹',
  '��' => '鳻',
  '��' => '鴈',
  '��' => '鴅',
  '��' => '鴄',
  '��' => '麃',
  '��' => '黓',
  '��' => '鼏',
  '��' => '鼐',
  '��' => '儜',
  '�' => '儓',
  '�' => '儗',
  '�' => '儚',
  '�' => '儑',
  '�' => '凞',
  '�' => '匴',
  '�' => '叡',
  '�' => '噰',
  '�' => '噠',
  '�' => '噮',
  '�@' => '噳',
  '�A' => '噦',
  '�B' => '噣',
  '�C' => '噭',
  '�D' => '噲',
  '�E' => '噞',
  '�F' => '噷',
  '�G' => '圜',
  '�H' => '圛',
  '�I' => '壈',
  '�J' => '墽',
  '�K' => '壉',
  '�L' => '墿',
  '�M' => '墺',
  '�N' => '壂',
  '�O' => '墼',
  '�P' => '壆',
  '�Q' => '嬗',
  '�R' => '嬙',
  '�S' => '嬛',
  '�T' => '嬡',
  '�U' => '嬔',
  '�V' => '嬓',
  '�W' => '嬐',
  '�X' => '嬖',
  '�Y' => '嬨',
  '�Z' => '嬚',
  '�[' => '嬠',
  '�\\' => '嬞',
  '�]' => '寯',
  '�^' => '嶬',
  '�_' => '嶱',
  '�`' => '嶩',
  '�a' => '嶧',
  '�b' => '嶵',
  '�c' => '嶰',
  '�d' => '嶮',
  '�e' => '嶪',
  '�f' => '嶨',
  '�g' => '嶲',
  '�h' => '嶭',
  '�i' => '嶯',
  '�j' => '嶴',
  '�k' => '幧',
  '�l' => '幨',
  '�m' => '幦',
  '�n' => '幯',
  '�o' => '廩',
  '�p' => '廧',
  '�q' => '廦',
  '�r' => '廨',
  '�s' => '廥',
  '�t' => '彋',
  '�u' => '徼',
  '�v' => '憝',
  '�w' => '憨',
  '�x' => '憖',
  '�y' => '懅',
  '�z' => '憴',
  '�{' => '懆',
  '�|' => '懁',
  '�}' => '懌',
  '�~' => '憺',
  '�' => '憿',
  '�' => '憸',
  '�' => '憌',
  '�' => '擗',
  '�' => '擖',
  '�' => '擐',
  '�' => '擏',
  '�' => '擉',
  '�' => '撽',
  '�' => '撉',
  '�' => '擃',
  '�' => '擛',
  '�' => '擳',
  '�' => '擙',
  '�' => '攳',
  '�' => '敿',
  '�' => '敼',
  '�' => '斢',
  '�' => '曈',
  '�' => '暾',
  '�' => '曀',
  '�' => '曊',
  '�' => '曋',
  '�' => '曏',
  '�' => '暽',
  '�' => '暻',
  '�' => '暺',
  '�' => '曌',
  '�' => '朣',
  '�' => '樴',
  '�' => '橦',
  '�' => '橉',
  '�' => '橧',
  '��' => '樲',
  '��' => '橨',
  '��' => '樾',
  '��' => '橝',
  '��' => '橭',
  '��' => '橶',
  '��' => '橛',
  '��' => '橑',
  '��' => '樨',
  '��' => '橚',
  '��' => '樻',
  '��' => '樿',
  '��' => '橁',
  '��' => '橪',
  '��' => '橤',
  '��' => '橐',
  '��' => '橏',
  '��' => '橔',
  '��' => '橯',
  '��' => '橩',
  '��' => '橠',
  '��' => '樼',
  '��' => '橞',
  '��' => '橖',
  '��' => '橕',
  '��' => '橍',
  '��' => '橎',
  '��' => '橆',
  '��' => '歕',
  '��' => '歔',
  '��' => '歖',
  '��' => '殧',
  '��' => '殪',
  '��' => '殫',
  '��' => '毈',
  '��' => '毇',
  '��' => '氄',
  '��' => '氃',
  '��' => '氆',
  '��' => '澭',
  '��' => '濋',
  '��' => '澣',
  '��' => '濇',
  '��' => '澼',
  '��' => '濎',
  '��' => '濈',
  '��' => '潞',
  '��' => '濄',
  '��' => '澽',
  '��' => '澞',
  '��' => '濊',
  '�' => '澨',
  '�' => '瀄',
  '�' => '澥',
  '�' => '澮',
  '�' => '澺',
  '�' => '澬',
  '�' => '澪',
  '�' => '濏',
  '�' => '澿',
  '�' => '澸',
  '�@' => '澢',
  '�A' => '濉',
  '�B' => '澫',
  '�C' => '濍',
  '�D' => '澯',
  '�E' => '澲',
  '�F' => '澰',
  '�G' => '燅',
  '�H' => '燂',
  '�I' => '熿',
  '�J' => '熸',
  '�K' => '燖',
  '�L' => '燀',
  '�M' => '燁',
  '�N' => '燋',
  '�O' => '燔',
  '�P' => '燊',
  '�Q' => '燇',
  '�R' => '燏',
  '�S' => '熽',
  '�T' => '燘',
  '�U' => '熼',
  '�V' => '燆',
  '�W' => '燚',
  '�X' => '燛',
  '�Y' => '犝',
  '�Z' => '犞',
  '�[' => '獩',
  '�\\' => '獦',
  '�]' => '獧',
  '�^' => '獬',
  '�_' => '獥',
  '�`' => '獫',
  '�a' => '獪',
  '�b' => '瑿',
  '�c' => '璚',
  '�d' => '璠',
  '�e' => '璔',
  '�f' => '璒',
  '�g' => '璕',
  '�h' => '璡',
  '�i' => '甋',
  '�j' => '疀',
  '�k' => '瘯',
  '�l' => '瘭',
  '�m' => '瘱',
  '�n' => '瘽',
  '�o' => '瘳',
  '�p' => '瘼',
  '�q' => '瘵',
  '�r' => '瘲',
  '�s' => '瘰',
  '�t' => '皻',
  '�u' => '盦',
  '�v' => '瞚',
  '�w' => '瞝',
  '�x' => '瞡',
  '�y' => '瞜',
  '�z' => '瞛',
  '�{' => '瞢',
  '�|' => '瞣',
  '�}' => '瞕',
  '�~' => '瞙',
  '�' => '瞗',
  '�' => '磝',
  '�' => '磩',
  '�' => '磥',
  '�' => '磪',
  '�' => '磞',
  '�' => '磣',
  '�' => '磛',
  '�' => '磡',
  '�' => '磢',
  '�' => '磭',
  '�' => '磟',
  '�' => '磠',
  '�' => '禤',
  '�' => '穄',
  '�' => '穈',
  '�' => '穇',
  '�' => '窶',
  '�' => '窸',
  '�' => '窵',
  '�' => '窱',
  '�' => '窷',
  '�' => '篞',
  '�' => '篣',
  '�' => '篧',
  '�' => '篝',
  '�' => '篕',
  '�' => '篥',
  '�' => '篚',
  '�' => '篨',
  '�' => '篹',
  '�' => '篔',
  '�' => '篪',
  '��' => '篢',
  '��' => '篜',
  '��' => '篫',
  '��' => '篘',
  '��' => '篟',
  '��' => '糒',
  '��' => '糔',
  '��' => '糗',
  '��' => '糐',
  '��' => '糑',
  '��' => '縒',
  '��' => '縡',
  '��' => '縗',
  '��' => '縌',
  '��' => '縟',
  '��' => '縠',
  '��' => '縓',
  '��' => '縎',
  '��' => '縜',
  '��' => '縕',
  '��' => '縚',
  '��' => '縢',
  '��' => '縋',
  '��' => '縏',
  '��' => '縖',
  '��' => '縍',
  '��' => '縔',
  '��' => '縥',
  '��' => '縤',
  '��' => '罃',
  '��' => '罻',
  '��' => '罼',
  '��' => '罺',
  '��' => '羱',
  '��' => '翯',
  '��' => '耪',
  '��' => '耩',
  '��' => '聬',
  '��' => '膱',
  '��' => '膦',
  '��' => '膮',
  '��' => '膹',
  '��' => '膵',
  '��' => '膫',
  '��' => '膰',
  '��' => '膬',
  '��' => '膴',
  '��' => '膲',
  '��' => '膷',
  '��' => '膧',
  '��' => '臲',
  '�' => '艕',
  '�' => '艖',
  '�' => '艗',
  '�' => '蕖',
  '�' => '蕅',
  '�' => '蕫',
  '�' => '蕍',
  '�' => '蕓',
  '�' => '蕡',
  '�' => '蕘',
  '�@' => '蕀',
  '�A' => '蕆',
  '�B' => '蕤',
  '�C' => '蕁',
  '�D' => '蕢',
  '�E' => '蕄',
  '�F' => '蕑',
  '�G' => '蕇',
  '�H' => '蕣',
  '�I' => '蔾',
  '�J' => '蕛',
  '�K' => '蕱',
  '�L' => '蕎',
  '�M' => '蕮',
  '�N' => '蕵',
  '�O' => '蕕',
  '�P' => '蕧',
  '�Q' => '蕠',
  '�R' => '薌',
  '�S' => '蕦',
  '�T' => '蕝',
  '�U' => '蕔',
  '�V' => '蕥',
  '�W' => '蕬',
  '�X' => '虣',
  '�Y' => '虥',
  '�Z' => '虤',
  '�[' => '螛',
  '�\\' => '螏',
  '�]' => '螗',
  '�^' => '螓',
  '�_' => '螒',
  '�`' => '螈',
  '�a' => '螁',
  '�b' => '螖',
  '�c' => '螘',
  '�d' => '蝹',
  '�e' => '螇',
  '�f' => '螣',
  '�g' => '螅',
  '�h' => '螐',
  '�i' => '螑',
  '�j' => '螝',
  '�k' => '螄',
  '�l' => '螔',
  '�m' => '螜',
  '�n' => '螚',
  '�o' => '螉',
  '�p' => '褞',
  '�q' => '褦',
  '�r' => '褰',
  '�s' => '褭',
  '�t' => '褮',
  '�u' => '褧',
  '�v' => '褱',
  '�w' => '褢',
  '�x' => '褩',
  '�y' => '褣',
  '�z' => '褯',
  '�{' => '褬',
  '�|' => '褟',
  '�}' => '觱',
  '�~' => '諠',
  '�' => '諢',
  '�' => '諲',
  '�' => '諴',
  '�' => '諵',
  '�' => '諝',
  '�' => '謔',
  '�' => '諤',
  '�' => '諟',
  '�' => '諰',
  '�' => '諈',
  '�' => '諞',
  '�' => '諡',
  '�' => '諨',
  '�' => '諿',
  '�' => '諯',
  '�' => '諻',
  '�' => '貑',
  '�' => '貒',
  '�' => '貐',
  '�' => '賵',
  '�' => '賮',
  '�' => '賱',
  '�' => '賰',
  '�' => '賳',
  '�' => '赬',
  '�' => '赮',
  '�' => '趥',
  '�' => '趧',
  '�' => '踳',
  '�' => '踾',
  '�' => '踸',
  '�' => '蹀',
  '�' => '蹅',
  '��' => '踶',
  '��' => '踼',
  '��' => '踽',
  '��' => '蹁',
  '��' => '踰',
  '��' => '踿',
  '��' => '躽',
  '��' => '輶',
  '��' => '輮',
  '��' => '輵',
  '��' => '輲',
  '��' => '輹',
  '��' => '輷',
  '��' => '輴',
  '��' => '遶',
  '��' => '遹',
  '��' => '遻',
  '��' => '邆',
  '��' => '郺',
  '��' => '鄳',
  '��' => '鄵',
  '��' => '鄶',
  '��' => '醓',
  '��' => '醐',
  '��' => '醑',
  '��' => '醍',
  '��' => '醏',
  '��' => '錧',
  '��' => '錞',
  '��' => '錈',
  '��' => '錟',
  '��' => '錆',
  '��' => '錏',
  '��' => '鍺',
  '��' => '錸',
  '��' => '錼',
  '��' => '錛',
  '��' => '錣',
  '��' => '錒',
  '��' => '錁',
  '��' => '鍆',
  '��' => '錭',
  '��' => '錎',
  '��' => '錍',
  '��' => '鋋',
  '��' => '錝',
  '��' => '鋺',
  '��' => '錥',
  '��' => '錓',
  '��' => '鋹',
  '��' => '鋷',
  '�' => '錴',
  '�' => '錂',
  '�' => '錤',
  '�' => '鋿',
  '�' => '錩',
  '�' => '錹',
  '�' => '錵',
  '�' => '錪',
  '�' => '錔',
  '�' => '錌',
  '�@' => '錋',
  '�A' => '鋾',
  '�B' => '錉',
  '�C' => '錀',
  '�D' => '鋻',
  '�E' => '錖',
  '�F' => '閼',
  '�G' => '闍',
  '�H' => '閾',
  '�I' => '閹',
  '�J' => '閺',
  '�K' => '閶',
  '�L' => '閿',
  '�M' => '閵',
  '�N' => '閽',
  '�O' => '隩',
  '�P' => '雔',
  '�Q' => '霋',
  '�R' => '霒',
  '�S' => '霐',
  '�T' => '鞙',
  '�U' => '鞗',
  '�V' => '鞔',
  '�W' => '韰',
  '�X' => '韸',
  '�Y' => '頵',
  '�Z' => '頯',
  '�[' => '頲',
  '�\\' => '餤',
  '�]' => '餟',
  '�^' => '餧',
  '�_' => '餩',
  '�`' => '馞',
  '�a' => '駮',
  '�b' => '駬',
  '�c' => '駥',
  '�d' => '駤',
  '�e' => '駰',
  '�f' => '駣',
  '�g' => '駪',
  '�h' => '駩',
  '�i' => '駧',
  '�j' => '骹',
  '�k' => '骿',
  '�l' => '骴',
  '�m' => '骻',
  '�n' => '髶',
  '�o' => '髺',
  '�p' => '髹',
  '�q' => '髷',
  '�r' => '鬳',
  '�s' => '鮀',
  '�t' => '鮅',
  '�u' => '鮇',
  '�v' => '魼',
  '�w' => '魾',
  '�x' => '魻',
  '�y' => '鮂',
  '�z' => '鮓',
  '�{' => '鮒',
  '�|' => '鮐',
  '�}' => '魺',
  '�~' => '鮕',
  '�' => '魽',
  '�' => '鮈',
  '�' => '鴥',
  '�' => '鴗',
  '�' => '鴠',
  '�' => '鴞',
  '�' => '鴔',
  '�' => '鴩',
  '�' => '鴝',
  '�' => '鴘',
  '�' => '鴢',
  '�' => '鴐',
  '�' => '鴙',
  '�' => '鴟',
  '�' => '麈',
  '�' => '麆',
  '�' => '麇',
  '�' => '麮',
  '�' => '麭',
  '�' => '黕',
  '�' => '黖',
  '�' => '黺',
  '�' => '鼒',
  '�' => '鼽',
  '�' => '儦',
  '�' => '儥',
  '�' => '儢',
  '�' => '儤',
  '�' => '儠',
  '�' => '儩',
  '�' => '勴',
  '�' => '嚓',
  '�' => '嚌',
  '��' => '嚍',
  '��' => '嚆',
  '��' => '嚄',
  '��' => '嚃',
  '��' => '噾',
  '��' => '嚂',
  '��' => '噿',
  '��' => '嚁',
  '��' => '壖',
  '��' => '壔',
  '��' => '壏',
  '��' => '壒',
  '��' => '嬭',
  '��' => '嬥',
  '��' => '嬲',
  '��' => '嬣',
  '��' => '嬬',
  '��' => '嬧',
  '��' => '嬦',
  '��' => '嬯',
  '��' => '嬮',
  '��' => '孻',
  '��' => '寱',
  '��' => '寲',
  '��' => '嶷',
  '��' => '幬',
  '��' => '幪',
  '��' => '徾',
  '��' => '徻',
  '��' => '懃',
  '��' => '憵',
  '��' => '憼',
  '��' => '懧',
  '��' => '懠',
  '��' => '懥',
  '��' => '懤',
  '��' => '懨',
  '��' => '懞',
  '��' => '擯',
  '��' => '擩',
  '��' => '擣',
  '��' => '擫',
  '��' => '擤',
  '��' => '擨',
  '��' => '斁',
  '��' => '斀',
  '��' => '斶',
  '��' => '旚',
  '��' => '曒',
  '��' => '檍',
  '��' => '檖',
  '�' => '檁',
  '�' => '檥',
  '�' => '檉',
  '�' => '檟',
  '�' => '檛',
  '�' => '檡',
  '�' => '檞',
  '�' => '檇',
  '�' => '檓',
  '�' => '檎',
  '�@' => '檕',
  '�A' => '檃',
  '�B' => '檨',
  '�C' => '檤',
  '�D' => '檑',
  '�E' => '橿',
  '�F' => '檦',
  '�G' => '檚',
  '�H' => '檅',
  '�I' => '檌',
  '�J' => '檒',
  '�K' => '歛',
  '�L' => '殭',
  '�M' => '氉',
  '�N' => '濌',
  '�O' => '澩',
  '�P' => '濴',
  '�Q' => '濔',
  '�R' => '濣',
  '�S' => '濜',
  '�T' => '濭',
  '�U' => '濧',
  '�V' => '濦',
  '�W' => '濞',
  '�X' => '濲',
  '�Y' => '濝',
  '�Z' => '濢',
  '�[' => '濨',
  '�\\' => '燡',
  '�]' => '燱',
  '�^' => '燨',
  '�_' => '燲',
  '�`' => '燤',
  '�a' => '燰',
  '�b' => '燢',
  '�c' => '獳',
  '�d' => '獮',
  '�e' => '獯',
  '�f' => '璗',
  '�g' => '璲',
  '�h' => '璫',
  '�i' => '璐',
  '�j' => '璪',
  '�k' => '璭',
  '�l' => '璱',
  '�m' => '璥',
  '�n' => '璯',
  '�o' => '甐',
  '�p' => '甑',
  '�q' => '甒',
  '�r' => '甏',
  '�s' => '疄',
  '�t' => '癃',
  '�u' => '癈',
  '�v' => '癉',
  '�w' => '癇',
  '�x' => '皤',
  '�y' => '盩',
  '�z' => '瞵',
  '�{' => '瞫',
  '�|' => '瞲',
  '�}' => '瞷',
  '�~' => '瞶',
  '�' => '瞴',
  '�' => '瞱',
  '�' => '瞨',
  '�' => '矰',
  '�' => '磳',
  '�' => '磽',
  '�' => '礂',
  '�' => '磻',
  '�' => '磼',
  '�' => '磲',
  '�' => '礅',
  '�' => '磹',
  '�' => '磾',
  '�' => '礄',
  '�' => '禫',
  '�' => '禨',
  '�' => '穜',
  '�' => '穛',
  '�' => '穖',
  '�' => '穘',
  '�' => '穔',
  '�' => '穚',
  '�' => '窾',
  '�' => '竀',
  '�' => '竁',
  '�' => '簅',
  '�' => '簏',
  '�' => '篲',
  '�' => '簀',
  '�' => '篿',
  '�' => '篻',
  '�' => '簎',
  '�' => '篴',
  '��' => '簋',
  '��' => '篳',
  '��' => '簂',
  '��' => '簉',
  '��' => '簃',
  '��' => '簁',
  '��' => '篸',
  '��' => '篽',
  '��' => '簆',
  '��' => '篰',
  '��' => '篱',
  '��' => '簐',
  '��' => '簊',
  '��' => '糨',
  '��' => '縭',
  '��' => '縼',
  '��' => '繂',
  '��' => '縳',
  '��' => '顈',
  '��' => '縸',
  '��' => '縪',
  '��' => '繉',
  '��' => '繀',
  '��' => '繇',
  '��' => '縩',
  '��' => '繌',
  '��' => '縰',
  '��' => '縻',
  '��' => '縶',
  '��' => '繄',
  '��' => '縺',
  '��' => '罅',
  '��' => '罿',
  '��' => '罾',
  '��' => '罽',
  '��' => '翴',
  '��' => '翲',
  '��' => '耬',
  '��' => '膻',
  '��' => '臄',
  '��' => '臌',
  '��' => '臊',
  '��' => '臅',
  '��' => '臇',
  '��' => '膼',
  '��' => '臩',
  '��' => '艛',
  '��' => '艚',
  '��' => '艜',
  '��' => '薃',
  '��' => '薀',
  '�' => '薏',
  '�' => '薧',
  '�' => '薕',
  '�' => '薠',
  '�' => '薋',
  '�' => '薣',
  '�' => '蕻',
  '�' => '薤',
  '�' => '薚',
  '�' => '薞',
  '�@' => '蕷',
  '�A' => '蕼',
  '�B' => '薉',
  '�C' => '薡',
  '�D' => '蕺',
  '�E' => '蕸',
  '�F' => '蕗',
  '�G' => '薎',
  '�H' => '薖',
  '�I' => '薆',
  '�J' => '薍',
  '�K' => '薙',
  '�L' => '薝',
  '�M' => '薁',
  '�N' => '薢',
  '�O' => '薂',
  '�P' => '薈',
  '�Q' => '薅',
  '�R' => '蕹',
  '�S' => '蕶',
  '�T' => '薘',
  '�U' => '薐',
  '�V' => '薟',
  '�W' => '虨',
  '�X' => '螾',
  '�Y' => '螪',
  '�Z' => '螭',
  '�[' => '蟅',
  '�\\' => '螰',
  '�]' => '螬',
  '�^' => '螹',
  '�_' => '螵',
  '�`' => '螼',
  '�a' => '螮',
  '�b' => '蟉',
  '�c' => '蟃',
  '�d' => '蟂',
  '�e' => '蟌',
  '�f' => '螷',
  '�g' => '螯',
  '�h' => '蟄',
  '�i' => '蟊',
  '�j' => '螴',
  '�k' => '螶',
  '�l' => '螿',
  '�m' => '螸',
  '�n' => '螽',
  '�o' => '蟞',
  '�p' => '螲',
  '�q' => '褵',
  '�r' => '褳',
  '�s' => '褼',
  '�t' => '褾',
  '�u' => '襁',
  '�v' => '襒',
  '�w' => '褷',
  '�x' => '襂',
  '�y' => '覭',
  '�z' => '覯',
  '�{' => '覮',
  '�|' => '觲',
  '�}' => '觳',
  '�~' => '謞',
  '�' => '謘',
  '�' => '謖',
  '�' => '謑',
  '�' => '謅',
  '�' => '謋',
  '�' => '謢',
  '�' => '謏',
  '�' => '謒',
  '�' => '謕',
  '�' => '謇',
  '�' => '謍',
  '�' => '謈',
  '�' => '謆',
  '�' => '謜',
  '�' => '謓',
  '�' => '謚',
  '�' => '豏',
  '�' => '豰',
  '�' => '豲',
  '�' => '豱',
  '�' => '豯',
  '�' => '貕',
  '�' => '貔',
  '�' => '賹',
  '�' => '赯',
  '�' => '蹎',
  '�' => '蹍',
  '�' => '蹓',
  '�' => '蹐',
  '�' => '蹌',
  '�' => '蹇',
  '�' => '轃',
  '�' => '轀',
  '��' => '邅',
  '��' => '遾',
  '��' => '鄸',
  '��' => '醚',
  '��' => '醢',
  '��' => '醛',
  '��' => '醙',
  '��' => '醟',
  '��' => '醡',
  '��' => '醝',
  '��' => '醠',
  '��' => '鎡',
  '��' => '鎃',
  '��' => '鎯',
  '��' => '鍤',
  '��' => '鍖',
  '��' => '鍇',
  '��' => '鍼',
  '��' => '鍘',
  '��' => '鍜',
  '��' => '鍶',
  '��' => '鍉',
  '��' => '鍐',
  '��' => '鍑',
  '��' => '鍠',
  '��' => '鍭',
  '��' => '鎏',
  '��' => '鍌',
  '��' => '鍪',
  '��' => '鍹',
  '��' => '鍗',
  '��' => '鍕',
  '��' => '鍒',
  '��' => '鍏',
  '��' => '鍱',
  '��' => '鍷',
  '��' => '鍻',
  '��' => '鍡',
  '��' => '鍞',
  '��' => '鍣',
  '��' => '鍧',
  '��' => '鎀',
  '��' => '鍎',
  '��' => '鍙',
  '��' => '闇',
  '��' => '闀',
  '��' => '闉',
  '��' => '闃',
  '��' => '闅',
  '��' => '閷',
  '��' => '隮',
  '�' => '隰',
  '�' => '隬',
  '�' => '霠',
  '�' => '霟',
  '�' => '霘',
  '�' => '霝',
  '�' => '霙',
  '�' => '鞚',
  '�' => '鞡',
  '�' => '鞜',
  '�@' => '鞞',
  '�A' => '鞝',
  '�B' => '韕',
  '�C' => '韔',
  '�D' => '韱',
  '�E' => '顁',
  '�F' => '顄',
  '�G' => '顊',
  '�H' => '顉',
  '�I' => '顅',
  '�J' => '顃',
  '�K' => '餥',
  '�L' => '餫',
  '�M' => '餬',
  '�N' => '餪',
  '�O' => '餳',
  '�P' => '餲',
  '�Q' => '餯',
  '�R' => '餭',
  '�S' => '餱',
  '�T' => '餰',
  '�U' => '馘',
  '�V' => '馣',
  '�W' => '馡',
  '�X' => '騂',
  '�Y' => '駺',
  '�Z' => '駴',
  '�[' => '駷',
  '�\\' => '駹',
  '�]' => '駸',
  '�^' => '駶',
  '�_' => '駻',
  '�`' => '駽',
  '�a' => '駾',
  '�b' => '駼',
  '�c' => '騃',
  '�d' => '骾',
  '�e' => '髾',
  '�f' => '髽',
  '�g' => '鬁',
  '�h' => '髼',
  '�i' => '魈',
  '�j' => '鮚',
  '�k' => '鮨',
  '�l' => '鮞',
  '�m' => '鮛',
  '�n' => '鮦',
  '�o' => '鮡',
  '�p' => '鮥',
  '�q' => '鮤',
  '�r' => '鮆',
  '�s' => '鮢',
  '�t' => '鮠',
  '�u' => '鮯',
  '�v' => '鴳',
  '�w' => '鵁',
  '�x' => '鵧',
  '�y' => '鴶',
  '�z' => '鴮',
  '�{' => '鴯',
  '�|' => '鴱',
  '�}' => '鴸',
  '�~' => '鴰',
  '�' => '鵅',
  '�' => '鵂',
  '�' => '鵃',
  '�' => '鴾',
  '�' => '鴷',
  '�' => '鵀',
  '�' => '鴽',
  '�' => '翵',
  '�' => '鴭',
  '�' => '麊',
  '�' => '麉',
  '�' => '麍',
  '�' => '麰',
  '�' => '黈',
  '�' => '黚',
  '�' => '黻',
  '�' => '黿',
  '�' => '鼤',
  '�' => '鼣',
  '�' => '鼢',
  '�' => '齔',
  '�' => '龠',
  '�' => '儱',
  '�' => '儭',
  '�' => '儮',
  '�' => '嚘',
  '�' => '嚜',
  '�' => '嚗',
  '�' => '嚚',
  '�' => '嚝',
  '�' => '嚙',
  '�' => '奰',
  '�' => '嬼',
  '��' => '屩',
  '��' => '屪',
  '��' => '巀',
  '��' => '幭',
  '��' => '幮',
  '��' => '懘',
  '��' => '懟',
  '��' => '懭',
  '��' => '懮',
  '��' => '懱',
  '��' => '懪',
  '��' => '懰',
  '��' => '懫',
  '��' => '懖',
  '��' => '懩',
  '��' => '擿',
  '��' => '攄',
  '��' => '擽',
  '��' => '擸',
  '��' => '攁',
  '��' => '攃',
  '��' => '擼',
  '��' => '斔',
  '��' => '旛',
  '��' => '曚',
  '��' => '曛',
  '��' => '曘',
  '��' => '櫅',
  '��' => '檹',
  '��' => '檽',
  '��' => '櫡',
  '��' => '櫆',
  '��' => '檺',
  '��' => '檶',
  '��' => '檷',
  '��' => '櫇',
  '��' => '檴',
  '��' => '檭',
  '��' => '歞',
  '��' => '毉',
  '��' => '氋',
  '��' => '瀇',
  '��' => '瀌',
  '��' => '瀍',
  '��' => '瀁',
  '��' => '瀅',
  '��' => '瀔',
  '��' => '瀎',
  '��' => '濿',
  '��' => '瀀',
  '��' => '濻',
  '�' => '瀦',
  '�' => '濼',
  '�' => '濷',
  '�' => '瀊',
  '�' => '爁',
  '�' => '燿',
  '�' => '燹',
  '�' => '爃',
  '�' => '燽',
  '�' => '獶',
  '�@' => '璸',
  '�A' => '瓀',
  '�B' => '璵',
  '�C' => '瓁',
  '�D' => '璾',
  '�E' => '璶',
  '�F' => '璻',
  '�G' => '瓂',
  '�H' => '甔',
  '�I' => '甓',
  '�J' => '癜',
  '�K' => '癤',
  '�L' => '癙',
  '�M' => '癐',
  '�N' => '癓',
  '�O' => '癗',
  '�P' => '癚',
  '�Q' => '皦',
  '�R' => '皽',
  '�S' => '盬',
  '�T' => '矂',
  '�U' => '瞺',
  '�V' => '磿',
  '�W' => '礌',
  '�X' => '礓',
  '�Y' => '礔',
  '�Z' => '礉',
  '�[' => '礐',
  '�\\' => '礒',
  '�]' => '礑',
  '�^' => '禭',
  '�_' => '禬',
  '�`' => '穟',
  '�a' => '簜',
  '�b' => '簩',
  '�c' => '簙',
  '�d' => '簠',
  '�e' => '簟',
  '�f' => '簭',
  '�g' => '簝',
  '�h' => '簦',
  '�i' => '簨',
  '�j' => '簢',
  '�k' => '簥',
  '�l' => '簰',
  '�m' => '繜',
  '�n' => '繐',
  '�o' => '繖',
  '�p' => '繣',
  '�q' => '繘',
  '�r' => '繢',
  '�s' => '繟',
  '�t' => '繑',
  '�u' => '繠',
  '�v' => '繗',
  '�w' => '繓',
  '�x' => '羵',
  '�y' => '羳',
  '�z' => '翷',
  '�{' => '翸',
  '�|' => '聵',
  '�}' => '臑',
  '�~' => '臒',
  '�' => '臐',
  '�' => '艟',
  '�' => '艞',
  '�' => '薴',
  '�' => '藆',
  '�' => '藀',
  '�' => '藃',
  '�' => '藂',
  '�' => '薳',
  '�' => '薵',
  '�' => '薽',
  '�' => '藇',
  '�' => '藄',
  '�' => '薿',
  '�' => '藋',
  '�' => '藎',
  '�' => '藈',
  '�' => '藅',
  '�' => '薱',
  '�' => '薶',
  '�' => '藒',
  '�' => '蘤',
  '�' => '薸',
  '�' => '薷',
  '�' => '薾',
  '�' => '虩',
  '�' => '蟧',
  '�' => '蟦',
  '�' => '蟢',
  '�' => '蟛',
  '�' => '蟫',
  '�' => '蟪',
  '�' => '蟥',
  '��' => '蟟',
  '��' => '蟳',
  '��' => '蟤',
  '��' => '蟔',
  '��' => '蟜',
  '��' => '蟓',
  '��' => '蟭',
  '��' => '蟘',
  '��' => '蟣',
  '��' => '螤',
  '��' => '蟗',
  '��' => '蟙',
  '��' => '蠁',
  '��' => '蟴',
  '��' => '蟨',
  '��' => '蟝',
  '��' => '襓',
  '��' => '襋',
  '��' => '襏',
  '��' => '襌',
  '��' => '襆',
  '��' => '襐',
  '��' => '襑',
  '��' => '襉',
  '��' => '謪',
  '��' => '謧',
  '��' => '謣',
  '��' => '謳',
  '��' => '謰',
  '��' => '謵',
  '��' => '譇',
  '��' => '謯',
  '��' => '謼',
  '��' => '謾',
  '��' => '謱',
  '��' => '謥',
  '��' => '謷',
  '��' => '謦',
  '��' => '謶',
  '��' => '謮',
  '��' => '謤',
  '��' => '謻',
  '��' => '謽',
  '��' => '謺',
  '��' => '豂',
  '��' => '豵',
  '��' => '貙',
  '��' => '貘',
  '��' => '貗',
  '��' => '賾',
  '��' => '贄',
  '�' => '贂',
  '�' => '贀',
  '�' => '蹜',
  '�' => '蹢',
  '�' => '蹠',
  '�' => '蹗',
  '�' => '蹖',
  '�' => '蹞',
  '�' => '蹥',
  '�' => '蹧',
  '�@' => '蹛',
  '�A' => '蹚',
  '�B' => '蹡',
  '�C' => '蹝',
  '�D' => '蹩',
  '�E' => '蹔',
  '�F' => '轆',
  '�G' => '轇',
  '�H' => '轈',
  '�I' => '轋',
  '�J' => '鄨',
  '�K' => '鄺',
  '�L' => '鄻',
  '�M' => '鄾',
  '�N' => '醨',
  '�O' => '醥',
  '�P' => '醧',
  '�Q' => '醯',
  '�R' => '醪',
  '�S' => '鎵',
  '�T' => '鎌',
  '�U' => '鎒',
  '�V' => '鎷',
  '�W' => '鎛',
  '�X' => '鎝',
  '�Y' => '鎉',
  '�Z' => '鎧',
  '�[' => '鎎',
  '�\\' => '鎪',
  '�]' => '鎞',
  '�^' => '鎦',
  '�_' => '鎕',
  '�`' => '鎈',
  '�a' => '鎙',
  '�b' => '鎟',
  '�c' => '鎍',
  '�d' => '鎱',
  '�e' => '鎑',
  '�f' => '鎲',
  '�g' => '鎤',
  '�h' => '鎨',
  '�i' => '鎴',
  '�j' => '鎣',
  '�k' => '鎥',
  '�l' => '闒',
  '�m' => '闓',
  '�n' => '闑',
  '�o' => '隳',
  '�p' => '雗',
  '�q' => '雚',
  '�r' => '巂',
  '�s' => '雟',
  '�t' => '雘',
  '�u' => '雝',
  '�v' => '霣',
  '�w' => '霢',
  '�x' => '霥',
  '�y' => '鞬',
  '�z' => '鞮',
  '�{' => '鞨',
  '�|' => '鞫',
  '�}' => '鞤',
  '�~' => '鞪',
  '�' => '鞢',
  '�' => '鞥',
  '�' => '韗',
  '�' => '韙',
  '�' => '韖',
  '�' => '韘',
  '�' => '韺',
  '�' => '顐',
  '�' => '顑',
  '�' => '顒',
  '�' => '颸',
  '�' => '饁',
  '�' => '餼',
  '�' => '餺',
  '�' => '騏',
  '�' => '騋',
  '�' => '騉',
  '�' => '騍',
  '�' => '騄',
  '�' => '騑',
  '�' => '騊',
  '�' => '騅',
  '�' => '騇',
  '�' => '騆',
  '�' => '髀',
  '�' => '髜',
  '�' => '鬈',
  '�' => '鬄',
  '�' => '鬅',
  '�' => '鬩',
  '�' => '鬵',
  '�' => '魊',
  '�' => '魌',
  '��' => '魋',
  '��' => '鯇',
  '��' => '鯆',
  '��' => '鯃',
  '��' => '鮿',
  '��' => '鯁',
  '��' => '鮵',
  '��' => '鮸',
  '��' => '鯓',
  '��' => '鮶',
  '��' => '鯄',
  '��' => '鮹',
  '��' => '鮽',
  '��' => '鵜',
  '��' => '鵓',
  '��' => '鵏',
  '��' => '鵊',
  '��' => '鵛',
  '��' => '鵋',
  '��' => '鵙',
  '��' => '鵖',
  '��' => '鵌',
  '��' => '鵗',
  '��' => '鵒',
  '��' => '鵔',
  '��' => '鵟',
  '��' => '鵘',
  '��' => '鵚',
  '��' => '麎',
  '��' => '麌',
  '��' => '黟',
  '��' => '鼁',
  '��' => '鼀',
  '��' => '鼖',
  '��' => '鼥',
  '��' => '鼫',
  '��' => '鼪',
  '��' => '鼩',
  '��' => '鼨',
  '��' => '齌',
  '��' => '齕',
  '��' => '儴',
  '��' => '儵',
  '��' => '劖',
  '��' => '勷',
  '��' => '厴',
  '��' => '嚫',
  '��' => '嚭',
  '��' => '嚦',
  '��' => '嚧',
  '��' => '嚪',
  '�' => '嚬',
  '�' => '壚',
  '�' => '壝',
  '�' => '壛',
  '�' => '夒',
  '�' => '嬽',
  '�' => '嬾',
  '�' => '嬿',
  '�' => '巃',
  '�' => '幰',
  '�@' => '徿',
  '�A' => '懻',
  '�B' => '攇',
  '�C' => '攐',
  '�D' => '攍',
  '�E' => '攉',
  '�F' => '攌',
  '�G' => '攎',
  '�H' => '斄',
  '�I' => '旞',
  '�J' => '旝',
  '�K' => '曞',
  '�L' => '櫧',
  '�M' => '櫠',
  '�N' => '櫌',
  '�O' => '櫑',
  '�P' => '櫙',
  '�Q' => '櫋',
  '�R' => '櫟',
  '�S' => '櫜',
  '�T' => '櫐',
  '�U' => '櫫',
  '�V' => '櫏',
  '�W' => '櫍',
  '�X' => '櫞',
  '�Y' => '歠',
  '�Z' => '殰',
  '�[' => '氌',
  '�\\' => '瀙',
  '�]' => '瀧',
  '�^' => '瀠',
  '�_' => '瀖',
  '�`' => '瀫',
  '�a' => '瀡',
  '�b' => '瀢',
  '�c' => '瀣',
  '�d' => '瀩',
  '�e' => '瀗',
  '�f' => '瀤',
  '�g' => '瀜',
  '�h' => '瀪',
  '�i' => '爌',
  '�j' => '爊',
  '�k' => '爇',
  '�l' => '爂',
  '�m' => '爅',
  '�n' => '犥',
  '�o' => '犦',
  '�p' => '犤',
  '�q' => '犣',
  '�r' => '犡',
  '�s' => '瓋',
  '�t' => '瓅',
  '�u' => '璷',
  '�v' => '瓃',
  '�w' => '甖',
  '�x' => '癠',
  '�y' => '矉',
  '�z' => '矊',
  '�{' => '矄',
  '�|' => '矱',
  '�}' => '礝',
  '�~' => '礛',
  '�' => '礡',
  '�' => '礜',
  '�' => '礗',
  '�' => '礞',
  '�' => '禰',
  '�' => '穧',
  '�' => '穨',
  '�' => '簳',
  '�' => '簼',
  '�' => '簹',
  '�' => '簬',
  '�' => '簻',
  '�' => '糬',
  '�' => '糪',
  '�' => '繶',
  '�' => '繵',
  '�' => '繸',
  '�' => '繰',
  '�' => '繷',
  '�' => '繯',
  '�' => '繺',
  '�' => '繲',
  '�' => '繴',
  '�' => '繨',
  '�' => '罋',
  '�' => '罊',
  '�' => '羃',
  '�' => '羆',
  '�' => '羷',
  '�' => '翽',
  '�' => '翾',
  '�' => '聸',
  '�' => '臗',
  '��' => '臕',
  '��' => '艤',
  '��' => '艡',
  '��' => '艣',
  '��' => '藫',
  '��' => '藱',
  '��' => '藭',
  '��' => '藙',
  '��' => '藡',
  '��' => '藨',
  '��' => '藚',
  '��' => '藗',
  '��' => '藬',
  '��' => '藲',
  '��' => '藸',
  '��' => '藘',
  '��' => '藟',
  '��' => '藣',
  '��' => '藜',
  '��' => '藑',
  '��' => '藰',
  '��' => '藦',
  '��' => '藯',
  '��' => '藞',
  '��' => '藢',
  '��' => '蠀',
  '��' => '蟺',
  '��' => '蠃',
  '��' => '蟶',
  '��' => '蟷',
  '��' => '蠉',
  '��' => '蠌',
  '��' => '蠋',
  '��' => '蠆',
  '��' => '蟼',
  '��' => '蠈',
  '��' => '蟿',
  '��' => '蠊',
  '��' => '蠂',
  '��' => '襢',
  '��' => '襚',
  '��' => '襛',
  '��' => '襗',
  '��' => '襡',
  '��' => '襜',
  '��' => '襘',
  '��' => '襝',
  '��' => '襙',
  '��' => '覈',
  '��' => '覷',
  '��' => '覶',
  '�' => '觶',
  '�' => '譐',
  '�' => '譈',
  '�' => '譊',
  '�' => '譀',
  '�' => '譓',
  '�' => '譖',
  '�' => '譔',
  '�' => '譋',
  '�' => '譕',
  '�@' => '譑',
  '�A' => '譂',
  '�B' => '譒',
  '�C' => '譗',
  '�D' => '豃',
  '�E' => '豷',
  '�F' => '豶',
  '�G' => '貚',
  '�H' => '贆',
  '�I' => '贇',
  '�J' => '贉',
  '�K' => '趬',
  '�L' => '趪',
  '�M' => '趭',
  '�N' => '趫',
  '�O' => '蹭',
  '�P' => '蹸',
  '�Q' => '蹳',
  '�R' => '蹪',
  '�S' => '蹯',
  '�T' => '蹻',
  '�U' => '軂',
  '�V' => '轒',
  '�W' => '轑',
  '�X' => '轏',
  '�Y' => '轐',
  '�Z' => '轓',
  '�[' => '辴',
  '�\\' => '酀',
  '�]' => '鄿',
  '�^' => '醰',
  '�_' => '醭',
  '�`' => '鏞',
  '�a' => '鏇',
  '�b' => '鏏',
  '�c' => '鏂',
  '�d' => '鏚',
  '�e' => '鏐',
  '�f' => '鏹',
  '�g' => '鏬',
  '�h' => '鏌',
  '�i' => '鏙',
  '�j' => '鎩',
  '�k' => '鏦',
  '�l' => '鏊',
  '�m' => '鏔',
  '�n' => '鏮',
  '�o' => '鏣',
  '�p' => '鏕',
  '�q' => '鏄',
  '�r' => '鏎',
  '�s' => '鏀',
  '�t' => '鏒',
  '�u' => '鏧',
  '�v' => '镽',
  '�w' => '闚',
  '�x' => '闛',
  '�y' => '雡',
  '�z' => '霩',
  '�{' => '霫',
  '�|' => '霬',
  '�}' => '霨',
  '�~' => '霦',
  '�' => '鞳',
  '�' => '鞷',
  '�' => '鞶',
  '�' => '韝',
  '�' => '韞',
  '�' => '韟',
  '�' => '顜',
  '�' => '顙',
  '�' => '顝',
  '�' => '顗',
  '�' => '颿',
  '�' => '颽',
  '�' => '颻',
  '�' => '颾',
  '�' => '饈',
  '�' => '饇',
  '�' => '饃',
  '�' => '馦',
  '�' => '馧',
  '�' => '騚',
  '�' => '騕',
  '�' => '騥',
  '�' => '騝',
  '�' => '騤',
  '�' => '騛',
  '�' => '騢',
  '�' => '騠',
  '�' => '騧',
  '�' => '騣',
  '�' => '騞',
  '�' => '騜',
  '�' => '騔',
  '�' => '髂',
  '��' => '鬋',
  '��' => '鬊',
  '��' => '鬎',
  '��' => '鬌',
  '��' => '鬷',
  '��' => '鯪',
  '��' => '鯫',
  '��' => '鯠',
  '��' => '鯞',
  '��' => '鯤',
  '��' => '鯦',
  '��' => '鯢',
  '��' => '鯰',
  '��' => '鯔',
  '��' => '鯗',
  '��' => '鯬',
  '��' => '鯜',
  '��' => '鯙',
  '��' => '鯥',
  '��' => '鯕',
  '��' => '鯡',
  '��' => '鯚',
  '��' => '鵷',
  '��' => '鶁',
  '��' => '鶊',
  '��' => '鶄',
  '��' => '鶈',
  '��' => '鵱',
  '��' => '鶀',
  '��' => '鵸',
  '��' => '鶆',
  '��' => '鶋',
  '��' => '鶌',
  '��' => '鵽',
  '��' => '鵫',
  '��' => '鵴',
  '��' => '鵵',
  '��' => '鵰',
  '��' => '鵩',
  '��' => '鶅',
  '��' => '鵳',
  '��' => '鵻',
  '��' => '鶂',
  '��' => '鵯',
  '��' => '鵹',
  '��' => '鵿',
  '��' => '鶇',
  '��' => '鵨',
  '��' => '麔',
  '��' => '麑',
  '��' => '黀',
  '�' => '黼',
  '�' => '鼭',
  '�' => '齀',
  '�' => '齁',
  '�' => '齍',
  '�' => '齖',
  '�' => '齗',
  '�' => '齘',
  '�' => '匷',
  '�' => '嚲',
  '�@' => '嚵',
  '�A' => '嚳',
  '�B' => '壣',
  '�C' => '孅',
  '�D' => '巆',
  '�E' => '巇',
  '�F' => '廮',
  '�G' => '廯',
  '�H' => '忀',
  '�I' => '忁',
  '�J' => '懹',
  '�K' => '攗',
  '�L' => '攖',
  '�M' => '攕',
  '�N' => '攓',
  '�O' => '旟',
  '�P' => '曨',
  '�Q' => '曣',
  '�R' => '曤',
  '�S' => '櫳',
  '�T' => '櫰',
  '�U' => '櫪',
  '�V' => '櫨',
  '�W' => '櫹',
  '�X' => '櫱',
  '�Y' => '櫮',
  '�Z' => '櫯',
  '�[' => '瀼',
  '�\\' => '瀵',
  '�]' => '瀯',
  '�^' => '瀷',
  '�_' => '瀴',
  '�`' => '瀱',
  '�a' => '灂',
  '�b' => '瀸',
  '�c' => '瀿',
  '�d' => '瀺',
  '�e' => '瀹',
  '�f' => '灀',
  '�g' => '瀻',
  '�h' => '瀳',
  '�i' => '灁',
  '�j' => '爓',
  '�k' => '爔',
  '�l' => '犨',
  '�m' => '獽',
  '�n' => '獼',
  '�o' => '璺',
  '�p' => '皫',
  '�q' => '皪',
  '�r' => '皾',
  '�s' => '盭',
  '�t' => '矌',
  '�u' => '矎',
  '�v' => '矏',
  '�w' => '矍',
  '�x' => '矲',
  '�y' => '礥',
  '�z' => '礣',
  '�{' => '礧',
  '�|' => '礨',
  '�}' => '礤',
  '�~' => '礩',
  '�' => '禲',
  '�' => '穮',
  '�' => '穬',
  '�' => '穭',
  '�' => '竷',
  '�' => '籉',
  '�' => '籈',
  '�' => '籊',
  '�' => '籇',
  '�' => '籅',
  '�' => '糮',
  '�' => '繻',
  '�' => '繾',
  '�' => '纁',
  '�' => '纀',
  '�' => '羺',
  '�' => '翿',
  '�' => '聹',
  '�' => '臛',
  '�' => '臙',
  '�' => '舋',
  '�' => '艨',
  '�' => '艩',
  '�' => '蘢',
  '�' => '藿',
  '�' => '蘁',
  '�' => '藾',
  '�' => '蘛',
  '�' => '蘀',
  '�' => '藶',
  '�' => '蘄',
  '�' => '蘉',
  '�' => '蘅',
  '��' => '蘌',
  '��' => '藽',
  '��' => '蠙',
  '��' => '蠐',
  '��' => '蠑',
  '��' => '蠗',
  '��' => '蠓',
  '��' => '蠖',
  '��' => '襣',
  '��' => '襦',
  '��' => '覹',
  '��' => '觷',
  '��' => '譠',
  '��' => '譪',
  '��' => '譝',
  '��' => '譨',
  '��' => '譣',
  '��' => '譥',
  '��' => '譧',
  '��' => '譭',
  '��' => '趮',
  '��' => '躆',
  '��' => '躈',
  '��' => '躄',
  '��' => '轙',
  '��' => '轖',
  '��' => '轗',
  '��' => '轕',
  '��' => '轘',
  '��' => '轚',
  '��' => '邍',
  '��' => '酃',
  '��' => '酁',
  '��' => '醷',
  '��' => '醵',
  '��' => '醲',
  '��' => '醳',
  '��' => '鐋',
  '��' => '鐓',
  '��' => '鏻',
  '��' => '鐠',
  '��' => '鐏',
  '��' => '鐔',
  '��' => '鏾',
  '��' => '鐕',
  '��' => '鐐',
  '��' => '鐨',
  '��' => '鐙',
  '��' => '鐍',
  '��' => '鏵',
  '��' => '鐀',
  '�' => '鏷',
  '�' => '鐇',
  '�' => '鐎',
  '�' => '鐖',
  '�' => '鐒',
  '�' => '鏺',
  '�' => '鐉',
  '�' => '鏸',
  '�' => '鐊',
  '�' => '鏿',
  '�@' => '鏼',
  '�A' => '鐌',
  '�B' => '鏶',
  '�C' => '鐑',
  '�D' => '鐆',
  '�E' => '闞',
  '�F' => '闠',
  '�G' => '闟',
  '�H' => '霮',
  '�I' => '霯',
  '�J' => '鞹',
  '�K' => '鞻',
  '�L' => '韽',
  '�M' => '韾',
  '�N' => '顠',
  '�O' => '顢',
  '�P' => '顣',
  '�Q' => '顟',
  '�R' => '飁',
  '�S' => '飂',
  '�T' => '饐',
  '�U' => '饎',
  '�V' => '饙',
  '�W' => '饌',
  '�X' => '饋',
  '�Y' => '饓',
  '�Z' => '騲',
  '�[' => '騴',
  '�\\' => '騱',
  '�]' => '騬',
  '�^' => '騪',
  '�_' => '騶',
  '�`' => '騩',
  '�a' => '騮',
  '�b' => '騸',
  '�c' => '騭',
  '�d' => '髇',
  '�e' => '髊',
  '�f' => '髆',
  '�g' => '鬐',
  '�h' => '鬒',
  '�i' => '鬑',
  '�j' => '鰋',
  '�k' => '鰈',
  '�l' => '鯷',
  '�m' => '鰅',
  '�n' => '鰒',
  '�o' => '鯸',
  '�p' => '鱀',
  '�q' => '鰇',
  '�r' => '鰎',
  '�s' => '鰆',
  '�t' => '鰗',
  '�u' => '鰔',
  '�v' => '鰉',
  '�w' => '鶟',
  '�x' => '鶙',
  '�y' => '鶤',
  '�z' => '鶝',
  '�{' => '鶒',
  '�|' => '鶘',
  '�}' => '鶐',
  '�~' => '鶛',
  '��' => '鶠',
  '��' => '鶔',
  '��' => '鶜',
  '��' => '鶪',
  '��' => '鶗',
  '��' => '鶡',
  '��' => '鶚',
  '��' => '鶢',
  '��' => '鶨',
  '��' => '鶞',
  '��' => '鶣',
  '��' => '鶿',
  '��' => '鶩',
  '��' => '鶖',
  '��' => '鶦',
  '��' => '鶧',
  '��' => '麙',
  '��' => '麛',
  '��' => '麚',
  '��' => '黥',
  '��' => '黤',
  '��' => '黧',
  '��' => '黦',
  '��' => '鼰',
  '��' => '鼮',
  '��' => '齛',
  '��' => '齠',
  '��' => '齞',
  '��' => '齝',
  '��' => '齙',
  '��' => '龑',
  '��' => '儺',
  '��' => '儹',
  '��' => '劘',
  '��' => '劗',
  '��' => '囃',
  '��' => '嚽',
  '��' => '嚾',
  '��' => '孈',
  '��' => '孇',
  '��' => '巋',
  '��' => '巏',
  '��' => '廱',
  '��' => '懽',
  '��' => '攛',
  '��' => '欂',
  '��' => '櫼',
  '��' => '欃',
  '��' => '櫸',
  '��' => '欀',
  '��' => '灃',
  '��' => '灄',
  '��' => '灊',
  '��' => '灈',
  '��' => '灉',
  '��' => '灅',
  '��' => '灆',
  '��' => '爝',
  '��' => '爚',
  '��' => '爙',
  '��' => '獾',
  '��' => '甗',
  '��' => '癪',
  '��' => '矐',
  '��' => '礭',
  '��' => '礱',
  '��' => '礯',
  '��' => '籔',
  '��' => '籓',
  '��' => '糲',
  '��' => '纊',
  '��' => '纇',
  '��' => '纈',
  '��' => '纋',
  '��' => '纆',
  '��' => '纍',
  '��' => '罍',
  '��' => '羻',
  '��' => '耰',
  '��' => '臝',
  '��' => '蘘',
  '��' => '蘪',
  '��' => '蘦',
  '��' => '蘟',
  '��' => '蘣',
  '��' => '蘜',
  '��' => '蘙',
  '��' => '蘧',
  '��' => '蘮',
  '��' => '蘡',
  '��' => '蘠',
  '��' => '蘩',
  '��' => '蘞',
  '��' => '蘥',
  '�@' => '蠩',
  '�A' => '蠝',
  '�B' => '蠛',
  '�C' => '蠠',
  '�D' => '蠤',
  '�E' => '蠜',
  '�F' => '蠫',
  '�G' => '衊',
  '�H' => '襭',
  '�I' => '襩',
  '�J' => '襮',
  '�K' => '襫',
  '�L' => '觺',
  '�M' => '譹',
  '�N' => '譸',
  '�O' => '譅',
  '�P' => '譺',
  '�Q' => '譻',
  '�R' => '贐',
  '�S' => '贔',
  '�T' => '趯',
  '�U' => '躎',
  '�V' => '躌',
  '�W' => '轞',
  '�X' => '轛',
  '�Y' => '轝',
  '�Z' => '酆',
  '�[' => '酄',
  '�\\' => '酅',
  '�]' => '醹',
  '�^' => '鐿',
  '�_' => '鐻',
  '�`' => '鐶',
  '�a' => '鐩',
  '�b' => '鐽',
  '�c' => '鐼',
  '�d' => '鐰',
  '�e' => '鐹',
  '�f' => '鐪',
  '�g' => '鐷',
  '�h' => '鐬',
  '�i' => '鑀',
  '�j' => '鐱',
  '�k' => '闥',
  '�l' => '闤',
  '�m' => '闣',
  '�n' => '霵',
  '�o' => '霺',
  '�p' => '鞿',
  '�q' => '韡',
  '�r' => '顤',
  '�s' => '飉',
  '�t' => '飆',
  '�u' => '飀',
  '�v' => '饘',
  '�w' => '饖',
  '�x' => '騹',
  '�y' => '騽',
  '�z' => '驆',
  '�{' => '驄',
  '�|' => '驂',
  '�}' => '驁',
  '�~' => '騺',
  '��' => '騿',
  '��' => '髍',
  '��' => '鬕',
  '��' => '鬗',
  '��' => '鬘',
  '��' => '鬖',
  '��' => '鬺',
  '��' => '魒',
  '��' => '鰫',
  '��' => '鰝',
  '��' => '鰜',
  '��' => '鰬',
  '��' => '鰣',
  '��' => '鰨',
  '��' => '鰩',
  '��' => '鰤',
  '��' => '鰡',
  '��' => '鶷',
  '��' => '鶶',
  '��' => '鶼',
  '��' => '鷁',
  '��' => '鷇',
  '��' => '鷊',
  '��' => '鷏',
  '��' => '鶾',
  '��' => '鷅',
  '��' => '鷃',
  '��' => '鶻',
  '��' => '鶵',
  '��' => '鷎',
  '��' => '鶹',
  '��' => '鶺',
  '��' => '鶬',
  '��' => '鷈',
  '��' => '鶱',
  '��' => '鶭',
  '��' => '鷌',
  '��' => '鶳',
  '��' => '鷍',
  '��' => '鶲',
  '��' => '鹺',
  '��' => '麜',
  '��' => '黫',
  '��' => '黮',
  '��' => '黭',
  '��' => '鼛',
  '��' => '鼘',
  '��' => '鼚',
  '��' => '鼱',
  '��' => '齎',
  '��' => '齥',
  '��' => '齤',
  '��' => '龒',
  '��' => '亹',
  '��' => '囆',
  '��' => '囅',
  '��' => '囋',
  '��' => '奱',
  '��' => '孋',
  '��' => '孌',
  '��' => '巕',
  '��' => '巑',
  '��' => '廲',
  '��' => '攡',
  '��' => '攠',
  '��' => '攦',
  '��' => '攢',
  '��' => '欋',
  '��' => '欈',
  '��' => '欉',
  '��' => '氍',
  '��' => '灕',
  '��' => '灖',
  '��' => '灗',
  '��' => '灒',
  '��' => '爞',
  '��' => '爟',
  '��' => '犩',
  '��' => '獿',
  '��' => '瓘',
  '��' => '瓕',
  '��' => '瓙',
  '��' => '瓗',
  '��' => '癭',
  '��' => '皭',
  '��' => '礵',
  '��' => '禴',
  '��' => '穰',
  '��' => '穱',
  '��' => '籗',
  '��' => '籜',
  '��' => '籙',
  '��' => '籛',
  '��' => '籚',
  '�@' => '糴',
  '�A' => '糱',
  '�B' => '纑',
  '�C' => '罏',
  '�D' => '羇',
  '�E' => '臞',
  '�F' => '艫',
  '�G' => '蘴',
  '�H' => '蘵',
  '�I' => '蘳',
  '�J' => '蘬',
  '�K' => '蘲',
  '�L' => '蘶',
  '�M' => '蠬',
  '�N' => '蠨',
  '�O' => '蠦',
  '�P' => '蠪',
  '�Q' => '蠥',
  '�R' => '襱',
  '�S' => '覿',
  '�T' => '覾',
  '�U' => '觻',
  '�V' => '譾',
  '�W' => '讄',
  '�X' => '讂',
  '�Y' => '讆',
  '�Z' => '讅',
  '�[' => '譿',
  '�\\' => '贕',
  '�]' => '躕',
  '�^' => '躔',
  '�_' => '躚',
  '�`' => '躒',
  '�a' => '躐',
  '�b' => '躖',
  '�c' => '躗',
  '�d' => '轠',
  '�e' => '轢',
  '�f' => '酇',
  '�g' => '鑌',
  '�h' => '鑐',
  '�i' => '鑊',
  '�j' => '鑋',
  '�k' => '鑏',
  '�l' => '鑇',
  '�m' => '鑅',
  '�n' => '鑈',
  '�o' => '鑉',
  '�p' => '鑆',
  '�q' => '霿',
  '�r' => '韣',
  '�s' => '顪',
  '�t' => '顩',
  '�u' => '飋',
  '�v' => '饔',
  '�w' => '饛',
  '�x' => '驎',
  '�y' => '驓',
  '�z' => '驔',
  '�{' => '驌',
  '�|' => '驏',
  '�}' => '驈',
  '�~' => '驊',
  '��' => '驉',
  '��' => '驒',
  '��' => '驐',
  '��' => '髐',
  '��' => '鬙',
  '��' => '鬫',
  '��' => '鬻',
  '��' => '魖',
  '��' => '魕',
  '��' => '鱆',
  '��' => '鱈',
  '��' => '鰿',
  '��' => '鱄',
  '��' => '鰹',
  '��' => '鰳',
  '��' => '鱁',
  '��' => '鰼',
  '��' => '鰷',
  '��' => '鰴',
  '��' => '鰲',
  '��' => '鰽',
  '��' => '鰶',
  '��' => '鷛',
  '��' => '鷒',
  '��' => '鷞',
  '��' => '鷚',
  '��' => '鷋',
  '��' => '鷐',
  '��' => '鷜',
  '��' => '鷑',
  '��' => '鷟',
  '��' => '鷩',
  '��' => '鷙',
  '��' => '鷘',
  '��' => '鷖',
  '��' => '鷵',
  '��' => '鷕',
  '��' => '鷝',
  '��' => '麶',
  '��' => '黰',
  '��' => '鼵',
  '��' => '鼳',
  '��' => '鼲',
  '��' => '齂',
  '��' => '齫',
  '��' => '龕',
  '��' => '龢',
  '��' => '儽',
  '��' => '劙',
  '��' => '壨',
  '��' => '壧',
  '��' => '奲',
  '��' => '孍',
  '��' => '巘',
  '��' => '蠯',
  '��' => '彏',
  '��' => '戁',
  '��' => '戃',
  '��' => '戄',
  '��' => '攩',
  '��' => '攥',
  '��' => '斖',
  '��' => '曫',
  '��' => '欑',
  '��' => '欒',
  '��' => '欏',
  '��' => '毊',
  '��' => '灛',
  '��' => '灚',
  '��' => '爢',
  '��' => '玂',
  '��' => '玁',
  '��' => '玃',
  '��' => '癰',
  '��' => '矔',
  '��' => '籧',
  '��' => '籦',
  '��' => '纕',
  '��' => '艬',
  '��' => '蘺',
  '��' => '虀',
  '��' => '蘹',
  '��' => '蘼',
  '��' => '蘱',
  '��' => '蘻',
  '��' => '蘾',
  '��' => '蠰',
  '��' => '蠲',
  '��' => '蠮',
  '��' => '蠳',
  '��' => '襶',
  '��' => '襴',
  '��' => '襳',
  '��' => '觾',
  '�@' => '讌',
  '�A' => '讎',
  '�B' => '讋',
  '�C' => '讈',
  '�D' => '豅',
  '�E' => '贙',
  '�F' => '躘',
  '�G' => '轤',
  '�H' => '轣',
  '�I' => '醼',
  '�J' => '鑢',
  '�K' => '鑕',
  '�L' => '鑝',
  '�M' => '鑗',
  '�N' => '鑞',
  '�O' => '韄',
  '�P' => '韅',
  '�Q' => '頀',
  '�R' => '驖',
  '�S' => '驙',
  '�T' => '鬞',
  '�U' => '鬟',
  '�V' => '鬠',
  '�W' => '鱒',
  '�X' => '鱘',
  '�Y' => '鱐',
  '�Z' => '鱊',
  '�[' => '鱍',
  '�\\' => '鱋',
  '�]' => '鱕',
  '�^' => '鱙',
  '�_' => '鱌',
  '�`' => '鱎',
  '�a' => '鷻',
  '�b' => '鷷',
  '�c' => '鷯',
  '�d' => '鷣',
  '�e' => '鷫',
  '�f' => '鷸',
  '�g' => '鷤',
  '�h' => '鷶',
  '�i' => '鷡',
  '�j' => '鷮',
  '�k' => '鷦',
  '�l' => '鷲',
  '�m' => '鷰',
  '�n' => '鷢',
  '�o' => '鷬',
  '�p' => '鷴',
  '�q' => '鷳',
  '�r' => '鷨',
  '�s' => '鷭',
  '�t' => '黂',
  '�u' => '黐',
  '�v' => '黲',
  '�w' => '黳',
  '�x' => '鼆',
  '�y' => '鼜',
  '�z' => '鼸',
  '�{' => '鼷',
  '�|' => '鼶',
  '�}' => '齃',
  '�~' => '齏',
  '��' => '齱',
  '��' => '齰',
  '��' => '齮',
  '��' => '齯',
  '��' => '囓',
  '��' => '囍',
  '��' => '孎',
  '��' => '屭',
  '��' => '攭',
  '��' => '曭',
  '��' => '曮',
  '��' => '欓',
  '��' => '灟',
  '��' => '灡',
  '��' => '灝',
  '��' => '灠',
  '��' => '爣',
  '��' => '瓛',
  '��' => '瓥',
  '��' => '矕',
  '��' => '礸',
  '��' => '禷',
  '��' => '禶',
  '��' => '籪',
  '��' => '纗',
  '��' => '羉',
  '��' => '艭',
  '��' => '虃',
  '��' => '蠸',
  '��' => '蠷',
  '��' => '蠵',
  '��' => '衋',
  '��' => '讔',
  '��' => '讕',
  '��' => '躞',
  '��' => '躟',
  '��' => '躠',
  '��' => '躝',
  '��' => '醾',
  '��' => '醽',
  '��' => '釂',
  '��' => '鑫',
  '��' => '鑨',
  '��' => '鑩',
  '��' => '雥',
  '��' => '靆',
  '��' => '靃',
  '��' => '靇',
  '��' => '韇',
  '��' => '韥',
  '��' => '驞',
  '��' => '髕',
  '��' => '魙',
  '��' => '鱣',
  '��' => '鱧',
  '��' => '鱦',
  '��' => '鱢',
  '��' => '鱞',
  '��' => '鱠',
  '��' => '鸂',
  '��' => '鷾',
  '��' => '鸇',
  '��' => '鸃',
  '��' => '鸆',
  '��' => '鸅',
  '��' => '鸀',
  '��' => '鸁',
  '��' => '鸉',
  '��' => '鷿',
  '��' => '鷽',
  '��' => '鸄',
  '��' => '麠',
  '��' => '鼞',
  '��' => '齆',
  '��' => '齴',
  '��' => '齵',
  '��' => '齶',
  '��' => '囔',
  '��' => '攮',
  '��' => '斸',
  '��' => '欘',
  '��' => '欙',
  '��' => '欗',
  '��' => '欚',
  '��' => '灢',
  '��' => '爦',
  '��' => '犪',
  '��' => '矘',
  '��' => '矙',
  '��' => '礹',
  '��' => '籩',
  '��' => '籫',
  '��' => '糶',
  '��' => '纚',
  '�@' => '纘',
  '�A' => '纛',
  '�B' => '纙',
  '�C' => '臠',
  '�D' => '臡',
  '�E' => '虆',
  '�F' => '虇',
  '�G' => '虈',
  '�H' => '襹',
  '�I' => '襺',
  '�J' => '襼',
  '�K' => '襻',
  '�L' => '觿',
  '�M' => '讘',
  '�N' => '讙',
  '�O' => '躥',
  '�P' => '躤',
  '�Q' => '躣',
  '�R' => '鑮',
  '�S' => '鑭',
  '�T' => '鑯',
  '�U' => '鑱',
  '�V' => '鑳',
  '�W' => '靉',
  '�X' => '顲',
  '�Y' => '饟',
  '�Z' => '鱨',
  '�[' => '鱮',
  '�\\' => '鱭',
  '�]' => '鸋',
  '�^' => '鸍',
  '�_' => '鸐',
  '�`' => '鸏',
  '�a' => '鸒',
  '�b' => '鸑',
  '�c' => '麡',
  '�d' => '黵',
  '�e' => '鼉',
  '�f' => '齇',
  '�g' => '齸',
  '�h' => '齻',
  '�i' => '齺',
  '�j' => '齹',
  '�k' => '圞',
  '�l' => '灦',
  '�m' => '籯',
  '�n' => '蠼',
  '�o' => '趲',
  '�p' => '躦',
  '�q' => '釃',
  '�r' => '鑴',
  '�s' => '鑸',
  '�t' => '鑶',
  '�u' => '鑵',
  '�v' => '驠',
  '�w' => '鱴',
  '�x' => '鱳',
  '�y' => '鱱',
  '�z' => '鱵',
  '�{' => '鸔',
  '�|' => '鸓',
  '�}' => '黶',
  '�~' => '鼊',
  '��' => '龤',
  '��' => '灨',
  '��' => '灥',
  '��' => '糷',
  '��' => '虪',
  '��' => '蠾',
  '��' => '蠽',
  '��' => '蠿',
  '��' => '讞',
  '��' => '貜',
  '��' => '躩',
  '��' => '軉',
  '��' => '靋',
  '��' => '顳',
  '��' => '顴',
  '��' => '飌',
  '��' => '饡',
  '��' => '馫',
  '��' => '驤',
  '��' => '驦',
  '��' => '驧',
  '��' => '鬤',
  '��' => '鸕',
  '��' => '鸗',
  '��' => '齈',
  '��' => '戇',
  '��' => '欞',
  '��' => '爧',
  '��' => '虌',
  '��' => '躨',
  '��' => '钂',
  '��' => '钀',
  '��' => '钁',
  '��' => '驩',
  '��' => '驨',
  '��' => '鬮',
  '��' => '鸙',
  '��' => '爩',
  '��' => '虋',
  '��' => '讟',
  '��' => '钃',
  '��' => '鱹',
  '��' => '麷',
  '��' => '癵',
  '��' => '驫',
  '��' => '鱺',
  '��' => '鸝',
  '��' => '灩',
  '��' => '灪',
  '��' => '麤',
  '��' => '齾',
  '��' => '齉',
  '��' => '龘',
);

$result =& $data;
unset($data);

return $result;
PKϤ$Z1M���5polyfill-iconv/Resources/charset/from.iso-8859-16.phpnu�[���<?php

static $data = array (
  '' => '',
  '' => '',
  '' => '',
  '' => '',
  '' => '',
  '' => '',
  '' => '',
  '' => '',
  '' => '',
  '	' => '	',
  '
' => '
',
  '' => '',
  '' => '',
  '
' => '
',
  '' => '',
  '' => '',
  '' => '',
  '' => '',
  '' => '',
  '' => '',
  '' => '',
  '' => '',
  '' => '',
  '' => '',
  '' => '',
  '' => '',
  '' => '',
  '' => '',
  '' => '',
  '' => '',
  '' => '',
  '' => '',
  ' ' => ' ',
  '!' => '!',
  '"' => '"',
  '#' => '#',
  '$' => '$',
  '%' => '%',
  '&' => '&',
  '\'' => '\'',
  '(' => '(',
  ')' => ')',
  '*' => '*',
  '+' => '+',
  ',' => ',',
  '-' => '-',
  '.' => '.',
  '/' => '/',
  0 => '0',
  1 => '1',
  2 => '2',
  3 => '3',
  4 => '4',
  5 => '5',
  6 => '6',
  7 => '7',
  8 => '8',
  9 => '9',
  ':' => ':',
  ';' => ';',
  '<' => '<',
  '=' => '=',
  '>' => '>',
  '?' => '?',
  '@' => '@',
  'A' => 'A',
  'B' => 'B',
  'C' => 'C',
  'D' => 'D',
  'E' => 'E',
  'F' => 'F',
  'G' => 'G',
  'H' => 'H',
  'I' => 'I',
  'J' => 'J',
  'K' => 'K',
  'L' => 'L',
  'M' => 'M',
  'N' => 'N',
  'O' => 'O',
  'P' => 'P',
  'Q' => 'Q',
  'R' => 'R',
  'S' => 'S',
  'T' => 'T',
  'U' => 'U',
  'V' => 'V',
  'W' => 'W',
  'X' => 'X',
  'Y' => 'Y',
  'Z' => 'Z',
  '[' => '[',
  '\\' => '\\',
  ']' => ']',
  '^' => '^',
  '_' => '_',
  '`' => '`',
  'a' => 'a',
  'b' => 'b',
  'c' => 'c',
  'd' => 'd',
  'e' => 'e',
  'f' => 'f',
  'g' => 'g',
  'h' => 'h',
  'i' => 'i',
  'j' => 'j',
  'k' => 'k',
  'l' => 'l',
  'm' => 'm',
  'n' => 'n',
  'o' => 'o',
  'p' => 'p',
  'q' => 'q',
  'r' => 'r',
  's' => 's',
  't' => 't',
  'u' => 'u',
  'v' => 'v',
  'w' => 'w',
  'x' => 'x',
  'y' => 'y',
  'z' => 'z',
  '{' => '{',
  '|' => '|',
  '}' => '}',
  '~' => '~',
  '' => '',
  '�' => '€',
  '�' => '',
  '�' => '‚',
  '�' => 'ƒ',
  '�' => '„',
  '�' => '…',
  '�' => '†',
  '�' => '‡',
  '�' => 'ˆ',
  '�' => '‰',
  '�' => 'Š',
  '�' => '‹',
  '�' => 'Œ',
  '�' => '',
  '�' => 'Ž',
  '�' => '',
  '�' => '',
  '�' => '‘',
  '�' => '’',
  '�' => '“',
  '�' => '”',
  '�' => '•',
  '�' => '–',
  '�' => '—',
  '�' => '˜',
  '�' => '™',
  '�' => 'š',
  '�' => '›',
  '�' => 'œ',
  '�' => '',
  '�' => 'ž',
  '�' => 'Ÿ',
  '�' => ' ',
  '�' => 'Ą',
  '�' => 'ą',
  '�' => 'Ł',
  '�' => '€',
  '�' => '„',
  '�' => 'Š',
  '�' => '§',
  '�' => 'š',
  '�' => '©',
  '�' => 'Ș',
  '�' => '«',
  '�' => 'Ź',
  '�' => '­',
  '�' => 'ź',
  '�' => 'Ż',
  '�' => '°',
  '�' => '±',
  '�' => 'Č',
  '�' => 'ł',
  '�' => 'Ž',
  '�' => '”',
  '�' => '¶',
  '�' => '·',
  '�' => 'ž',
  '�' => 'č',
  '�' => 'ș',
  '�' => '»',
  '�' => 'Œ',
  '�' => 'œ',
  '�' => 'Ÿ',
  '�' => 'ż',
  '�' => 'À',
  '�' => 'Á',
  '�' => 'Â',
  '�' => 'Ă',
  '�' => 'Ä',
  '�' => 'Ć',
  '�' => 'Æ',
  '�' => 'Ç',
  '�' => 'È',
  '�' => 'É',
  '�' => 'Ê',
  '�' => 'Ë',
  '�' => 'Ì',
  '�' => 'Í',
  '�' => 'Î',
  '�' => 'Ï',
  '�' => 'Đ',
  '�' => 'Ń',
  '�' => 'Ò',
  '�' => 'Ó',
  '�' => 'Ô',
  '�' => 'Ő',
  '�' => 'Ö',
  '�' => 'Ś',
  '�' => 'Ű',
  '�' => 'Ù',
  '�' => 'Ú',
  '�' => 'Û',
  '�' => 'Ü',
  '�' => 'Ę',
  '�' => 'Ț',
  '�' => 'ß',
  '�' => 'à',
  '�' => 'á',
  '�' => 'â',
  '�' => 'ă',
  '�' => 'ä',
  '�' => 'ć',
  '�' => 'æ',
  '�' => 'ç',
  '�' => 'è',
  '�' => 'é',
  '�' => 'ê',
  '�' => 'ë',
  '�' => 'ì',
  '�' => 'í',
  '�' => 'î',
  '�' => 'ï',
  '�' => 'đ',
  '�' => 'ń',
  '�' => 'ò',
  '�' => 'ó',
  '�' => 'ô',
  '�' => 'ő',
  '�' => 'ö',
  '�' => 'ś',
  '�' => 'ű',
  '�' => 'ù',
  '�' => 'ú',
  '�' => 'û',
  '�' => 'ü',
  '�' => 'ę',
  '�' => 'ț',
  '�' => 'ÿ',
);

$result =& $data;
unset($data);

return $result;
PKϤ$Zs1
���/polyfill-iconv/Resources/charset/from.cp037.phpnu�[���<?php

static $data = array (
  '' => '',
  '' => '',
  '' => '',
  '' => '',
  '' => 'œ',
  '' => '	',
  '' => '†',
  '' => '',
  '' => '—',
  '	' => '',
  '
' => 'Ž',
  '' => '',
  '' => '',
  '
' => '
',
  '' => '',
  '' => '',
  '' => '',
  '' => '',
  '' => '',
  '' => '',
  '' => '',
  '' => '…',
  '' => '',
  '' => '‡',
  '' => '',
  '' => '',
  '' => '’',
  '' => '',
  '' => '',
  '' => '',
  '' => '',
  '' => '',
  ' ' => '€',
  '!' => '',
  '"' => '‚',
  '#' => 'ƒ',
  '$' => '„',
  '%' => '
',
  '&' => '',
  '\'' => '',
  '(' => 'ˆ',
  ')' => '‰',
  '*' => 'Š',
  '+' => '‹',
  ',' => 'Œ',
  '-' => '',
  '.' => '',
  '/' => '',
  0 => '',
  1 => '‘',
  2 => '',
  3 => '“',
  4 => '”',
  5 => '•',
  6 => '–',
  7 => '',
  8 => '˜',
  9 => '™',
  ':' => 'š',
  ';' => '›',
  '<' => '',
  '=' => '',
  '>' => 'ž',
  '?' => '',
  '@' => ' ',
  'A' => ' ',
  'B' => 'â',
  'C' => 'ä',
  'D' => 'à',
  'E' => 'á',
  'F' => 'ã',
  'G' => 'å',
  'H' => 'ç',
  'I' => 'ñ',
  'J' => '¢',
  'K' => '.',
  'L' => '<',
  'M' => '(',
  'N' => '+',
  'O' => '|',
  'P' => '&',
  'Q' => 'é',
  'R' => 'ê',
  'S' => 'ë',
  'T' => 'è',
  'U' => 'í',
  'V' => 'î',
  'W' => 'ï',
  'X' => 'ì',
  'Y' => 'ß',
  'Z' => '!',
  '[' => '$',
  '\\' => '*',
  ']' => ')',
  '^' => ';',
  '_' => '¬',
  '`' => '-',
  'a' => '/',
  'b' => 'Â',
  'c' => 'Ä',
  'd' => 'À',
  'e' => 'Á',
  'f' => 'Ã',
  'g' => 'Å',
  'h' => 'Ç',
  'i' => 'Ñ',
  'j' => '¦',
  'k' => ',',
  'l' => '%',
  'm' => '_',
  'n' => '>',
  'o' => '?',
  'p' => 'ø',
  'q' => 'É',
  'r' => 'Ê',
  's' => 'Ë',
  't' => 'È',
  'u' => 'Í',
  'v' => 'Î',
  'w' => 'Ï',
  'x' => 'Ì',
  'y' => '`',
  'z' => ':',
  '{' => '#',
  '|' => '@',
  '}' => '\'',
  '~' => '=',
  '' => '"',
  '�' => 'Ø',
  '�' => 'a',
  '�' => 'b',
  '�' => 'c',
  '�' => 'd',
  '�' => 'e',
  '�' => 'f',
  '�' => 'g',
  '�' => 'h',
  '�' => 'i',
  '�' => '«',
  '�' => '»',
  '�' => 'ð',
  '�' => 'ý',
  '�' => 'þ',
  '�' => '±',
  '�' => '°',
  '�' => 'j',
  '�' => 'k',
  '�' => 'l',
  '�' => 'm',
  '�' => 'n',
  '�' => 'o',
  '�' => 'p',
  '�' => 'q',
  '�' => 'r',
  '�' => 'ª',
  '�' => 'º',
  '�' => 'æ',
  '�' => '¸',
  '�' => 'Æ',
  '�' => '¤',
  '�' => 'µ',
  '�' => '~',
  '�' => 's',
  '�' => 't',
  '�' => 'u',
  '�' => 'v',
  '�' => 'w',
  '�' => 'x',
  '�' => 'y',
  '�' => 'z',
  '�' => '¡',
  '�' => '¿',
  '�' => 'Ð',
  '�' => 'Ý',
  '�' => 'Þ',
  '�' => '®',
  '�' => '^',
  '�' => '£',
  '�' => '¥',
  '�' => '·',
  '�' => '©',
  '�' => '§',
  '�' => '¶',
  '�' => '¼',
  '�' => '½',
  '�' => '¾',
  '�' => '[',
  '�' => ']',
  '�' => '¯',
  '�' => '¨',
  '�' => '´',
  '�' => '×',
  '�' => '{',
  '�' => 'A',
  '�' => 'B',
  '�' => 'C',
  '�' => 'D',
  '�' => 'E',
  '�' => 'F',
  '�' => 'G',
  '�' => 'H',
  '�' => 'I',
  '�' => '­',
  '�' => 'ô',
  '�' => 'ö',
  '�' => 'ò',
  '�' => 'ó',
  '�' => 'õ',
  '�' => '}',
  '�' => 'J',
  '�' => 'K',
  '�' => 'L',
  '�' => 'M',
  '�' => 'N',
  '�' => 'O',
  '�' => 'P',
  '�' => 'Q',
  '�' => 'R',
  '�' => '¹',
  '�' => 'û',
  '�' => 'ü',
  '�' => 'ù',
  '�' => 'ú',
  '�' => 'ÿ',
  '�' => '\\',
  '�' => '÷',
  '�' => 'S',
  '�' => 'T',
  '�' => 'U',
  '�' => 'V',
  '�' => 'W',
  '�' => 'X',
  '�' => 'Y',
  '�' => 'Z',
  '�' => '²',
  '�' => 'Ô',
  '�' => 'Ö',
  '�' => 'Ò',
  '�' => 'Ó',
  '�' => 'Õ',
  '�' => '0',
  '�' => '1',
  '�' => '2',
  '�' => '3',
  '�' => '4',
  '�' => '5',
  '�' => '6',
  '�' => '7',
  '�' => '8',
  '�' => '9',
  '�' => '³',
  '�' => 'Û',
  '�' => 'Ü',
  '�' => 'Ù',
  '�' => 'Ú',
  '�' => 'Ÿ',
);

$result =& $data;
unset($data);

return $result;
PKϤ$Z�94|��5polyfill-iconv/Resources/charset/from.iso-8859-13.phpnu�[���<?php

static $data = array (
  '' => '',
  '' => '',
  '' => '',
  '' => '',
  '' => '',
  '' => '',
  '' => '',
  '' => '',
  '' => '',
  '	' => '	',
  '
' => '
',
  '' => '',
  '' => '',
  '
' => '
',
  '' => '',
  '' => '',
  '' => '',
  '' => '',
  '' => '',
  '' => '',
  '' => '',
  '' => '',
  '' => '',
  '' => '',
  '' => '',
  '' => '',
  '' => '',
  '' => '',
  '' => '',
  '' => '',
  '' => '',
  '' => '',
  ' ' => ' ',
  '!' => '!',
  '"' => '"',
  '#' => '#',
  '$' => '$',
  '%' => '%',
  '&' => '&',
  '\'' => '\'',
  '(' => '(',
  ')' => ')',
  '*' => '*',
  '+' => '+',
  ',' => ',',
  '-' => '-',
  '.' => '.',
  '/' => '/',
  0 => '0',
  1 => '1',
  2 => '2',
  3 => '3',
  4 => '4',
  5 => '5',
  6 => '6',
  7 => '7',
  8 => '8',
  9 => '9',
  ':' => ':',
  ';' => ';',
  '<' => '<',
  '=' => '=',
  '>' => '>',
  '?' => '?',
  '@' => '@',
  'A' => 'A',
  'B' => 'B',
  'C' => 'C',
  'D' => 'D',
  'E' => 'E',
  'F' => 'F',
  'G' => 'G',
  'H' => 'H',
  'I' => 'I',
  'J' => 'J',
  'K' => 'K',
  'L' => 'L',
  'M' => 'M',
  'N' => 'N',
  'O' => 'O',
  'P' => 'P',
  'Q' => 'Q',
  'R' => 'R',
  'S' => 'S',
  'T' => 'T',
  'U' => 'U',
  'V' => 'V',
  'W' => 'W',
  'X' => 'X',
  'Y' => 'Y',
  'Z' => 'Z',
  '[' => '[',
  '\\' => '\\',
  ']' => ']',
  '^' => '^',
  '_' => '_',
  '`' => '`',
  'a' => 'a',
  'b' => 'b',
  'c' => 'c',
  'd' => 'd',
  'e' => 'e',
  'f' => 'f',
  'g' => 'g',
  'h' => 'h',
  'i' => 'i',
  'j' => 'j',
  'k' => 'k',
  'l' => 'l',
  'm' => 'm',
  'n' => 'n',
  'o' => 'o',
  'p' => 'p',
  'q' => 'q',
  'r' => 'r',
  's' => 's',
  't' => 't',
  'u' => 'u',
  'v' => 'v',
  'w' => 'w',
  'x' => 'x',
  'y' => 'y',
  'z' => 'z',
  '{' => '{',
  '|' => '|',
  '}' => '}',
  '~' => '~',
  '' => '',
  '�' => '€',
  '�' => '',
  '�' => '‚',
  '�' => 'ƒ',
  '�' => '„',
  '�' => '…',
  '�' => '†',
  '�' => '‡',
  '�' => 'ˆ',
  '�' => '‰',
  '�' => 'Š',
  '�' => '‹',
  '�' => 'Œ',
  '�' => '',
  '�' => 'Ž',
  '�' => '',
  '�' => '',
  '�' => '‘',
  '�' => '’',
  '�' => '“',
  '�' => '”',
  '�' => '•',
  '�' => '–',
  '�' => '—',
  '�' => '˜',
  '�' => '™',
  '�' => 'š',
  '�' => '›',
  '�' => 'œ',
  '�' => '',
  '�' => 'ž',
  '�' => 'Ÿ',
  '�' => ' ',
  '�' => '”',
  '�' => '¢',
  '�' => '£',
  '�' => '¤',
  '�' => '„',
  '�' => '¦',
  '�' => '§',
  '�' => 'Ø',
  '�' => '©',
  '�' => 'Ŗ',
  '�' => '«',
  '�' => '¬',
  '�' => '­',
  '�' => '®',
  '�' => 'Æ',
  '�' => '°',
  '�' => '±',
  '�' => '²',
  '�' => '³',
  '�' => '“',
  '�' => 'µ',
  '�' => '¶',
  '�' => '·',
  '�' => 'ø',
  '�' => '¹',
  '�' => 'ŗ',
  '�' => '»',
  '�' => '¼',
  '�' => '½',
  '�' => '¾',
  '�' => 'æ',
  '�' => 'Ą',
  '�' => 'Į',
  '�' => 'Ā',
  '�' => 'Ć',
  '�' => 'Ä',
  '�' => 'Å',
  '�' => 'Ę',
  '�' => 'Ē',
  '�' => 'Č',
  '�' => 'É',
  '�' => 'Ź',
  '�' => 'Ė',
  '�' => 'Ģ',
  '�' => 'Ķ',
  '�' => 'Ī',
  '�' => 'Ļ',
  '�' => 'Š',
  '�' => 'Ń',
  '�' => 'Ņ',
  '�' => 'Ó',
  '�' => 'Ō',
  '�' => 'Õ',
  '�' => 'Ö',
  '�' => '×',
  '�' => 'Ų',
  '�' => 'Ł',
  '�' => 'Ś',
  '�' => 'Ū',
  '�' => 'Ü',
  '�' => 'Ż',
  '�' => 'Ž',
  '�' => 'ß',
  '�' => 'ą',
  '�' => 'į',
  '�' => 'ā',
  '�' => 'ć',
  '�' => 'ä',
  '�' => 'å',
  '�' => 'ę',
  '�' => 'ē',
  '�' => 'č',
  '�' => 'é',
  '�' => 'ź',
  '�' => 'ė',
  '�' => 'ģ',
  '�' => 'ķ',
  '�' => 'ī',
  '�' => 'ļ',
  '�' => 'š',
  '�' => 'ń',
  '�' => 'ņ',
  '�' => 'ó',
  '�' => 'ō',
  '�' => 'õ',
  '�' => 'ö',
  '�' => '÷',
  '�' => 'ų',
  '�' => 'ł',
  '�' => 'ś',
  '�' => 'ū',
  '�' => 'ü',
  '�' => 'ż',
  '�' => 'ž',
  '�' => '’',
);

$result =& $data;
unset($data);

return $result;
PKϤ$Z2���5polyfill-iconv/Resources/charset/from.iso-8859-11.phpnu�[���<?php

static $data = array (
  '' => '',
  '' => '',
  '' => '',
  '' => '',
  '' => '',
  '' => '',
  '' => '',
  '' => '',
  '' => '',
  '	' => '	',
  '
' => '
',
  '' => '',
  '' => '',
  '
' => '
',
  '' => '',
  '' => '',
  '' => '',
  '' => '',
  '' => '',
  '' => '',
  '' => '',
  '' => '',
  '' => '',
  '' => '',
  '' => '',
  '' => '',
  '' => '',
  '' => '',
  '' => '',
  '' => '',
  '' => '',
  '' => '',
  ' ' => ' ',
  '!' => '!',
  '"' => '"',
  '#' => '#',
  '$' => '$',
  '%' => '%',
  '&' => '&',
  '\'' => '\'',
  '(' => '(',
  ')' => ')',
  '*' => '*',
  '+' => '+',
  ',' => ',',
  '-' => '-',
  '.' => '.',
  '/' => '/',
  0 => '0',
  1 => '1',
  2 => '2',
  3 => '3',
  4 => '4',
  5 => '5',
  6 => '6',
  7 => '7',
  8 => '8',
  9 => '9',
  ':' => ':',
  ';' => ';',
  '<' => '<',
  '=' => '=',
  '>' => '>',
  '?' => '?',
  '@' => '@',
  'A' => 'A',
  'B' => 'B',
  'C' => 'C',
  'D' => 'D',
  'E' => 'E',
  'F' => 'F',
  'G' => 'G',
  'H' => 'H',
  'I' => 'I',
  'J' => 'J',
  'K' => 'K',
  'L' => 'L',
  'M' => 'M',
  'N' => 'N',
  'O' => 'O',
  'P' => 'P',
  'Q' => 'Q',
  'R' => 'R',
  'S' => 'S',
  'T' => 'T',
  'U' => 'U',
  'V' => 'V',
  'W' => 'W',
  'X' => 'X',
  'Y' => 'Y',
  'Z' => 'Z',
  '[' => '[',
  '\\' => '\\',
  ']' => ']',
  '^' => '^',
  '_' => '_',
  '`' => '`',
  'a' => 'a',
  'b' => 'b',
  'c' => 'c',
  'd' => 'd',
  'e' => 'e',
  'f' => 'f',
  'g' => 'g',
  'h' => 'h',
  'i' => 'i',
  'j' => 'j',
  'k' => 'k',
  'l' => 'l',
  'm' => 'm',
  'n' => 'n',
  'o' => 'o',
  'p' => 'p',
  'q' => 'q',
  'r' => 'r',
  's' => 's',
  't' => 't',
  'u' => 'u',
  'v' => 'v',
  'w' => 'w',
  'x' => 'x',
  'y' => 'y',
  'z' => 'z',
  '{' => '{',
  '|' => '|',
  '}' => '}',
  '~' => '~',
  '' => '',
  '�' => '€',
  '�' => '',
  '�' => '‚',
  '�' => 'ƒ',
  '�' => '„',
  '�' => '…',
  '�' => '†',
  '�' => '‡',
  '�' => 'ˆ',
  '�' => '‰',
  '�' => 'Š',
  '�' => '‹',
  '�' => 'Œ',
  '�' => '',
  '�' => 'Ž',
  '�' => '',
  '�' => '',
  '�' => '‘',
  '�' => '’',
  '�' => '“',
  '�' => '”',
  '�' => '•',
  '�' => '–',
  '�' => '—',
  '�' => '˜',
  '�' => '™',
  '�' => 'š',
  '�' => '›',
  '�' => 'œ',
  '�' => '',
  '�' => 'ž',
  '�' => 'Ÿ',
  '�' => ' ',
  '�' => 'ก',
  '�' => 'ข',
  '�' => 'ฃ',
  '�' => 'ค',
  '�' => 'ฅ',
  '�' => 'ฆ',
  '�' => 'ง',
  '�' => 'จ',
  '�' => 'ฉ',
  '�' => 'ช',
  '�' => 'ซ',
  '�' => 'ฌ',
  '�' => 'ญ',
  '�' => 'ฎ',
  '�' => 'ฏ',
  '�' => 'ฐ',
  '�' => 'ฑ',
  '�' => 'ฒ',
  '�' => 'ณ',
  '�' => 'ด',
  '�' => 'ต',
  '�' => 'ถ',
  '�' => 'ท',
  '�' => 'ธ',
  '�' => 'น',
  '�' => 'บ',
  '�' => 'ป',
  '�' => 'ผ',
  '�' => 'ฝ',
  '�' => 'พ',
  '�' => 'ฟ',
  '�' => 'ภ',
  '�' => 'ม',
  '�' => 'ย',
  '�' => 'ร',
  '�' => 'ฤ',
  '�' => 'ล',
  '�' => 'ฦ',
  '�' => 'ว',
  '�' => 'ศ',
  '�' => 'ษ',
  '�' => 'ส',
  '�' => 'ห',
  '�' => 'ฬ',
  '�' => 'อ',
  '�' => 'ฮ',
  '�' => 'ฯ',
  '�' => 'ะ',
  '�' => 'ั',
  '�' => 'า',
  '�' => 'ำ',
  '�' => 'ิ',
  '�' => 'ี',
  '�' => 'ึ',
  '�' => 'ื',
  '�' => 'ุ',
  '�' => 'ู',
  '�' => 'ฺ',
  '�' => '฿',
  '�' => 'เ',
  '�' => 'แ',
  '�' => 'โ',
  '�' => 'ใ',
  '�' => 'ไ',
  '�' => 'ๅ',
  '�' => 'ๆ',
  '�' => '็',
  '�' => '่',
  '�' => '้',
  '�' => '๊',
  '�' => '๋',
  '�' => '์',
  '�' => 'ํ',
  '�' => '๎',
  '�' => '๏',
  '�' => '๐',
  '�' => '๑',
  '�' => '๒',
  '�' => '๓',
  '�' => '๔',
  '�' => '๕',
  '�' => '๖',
  '�' => '๗',
  '�' => '๘',
  '�' => '๙',
  '�' => '๚',
  '�' => '๛',
);

$result =& $data;
unset($data);

return $result;
PKϤ$Z�wg���/polyfill-iconv/Resources/charset/from.cp775.phpnu�[���<?php

static $data = array (
  '' => '',
  '' => '',
  '' => '',
  '' => '',
  '' => '',
  '' => '',
  '' => '',
  '' => '',
  '' => '',
  '	' => '	',
  '
' => '
',
  '' => '',
  '' => '',
  '
' => '
',
  '' => '',
  '' => '',
  '' => '',
  '' => '',
  '' => '',
  '' => '',
  '' => '',
  '' => '',
  '' => '',
  '' => '',
  '' => '',
  '' => '',
  '' => '',
  '' => '',
  '' => '',
  '' => '',
  '' => '',
  '' => '',
  ' ' => ' ',
  '!' => '!',
  '"' => '"',
  '#' => '#',
  '$' => '$',
  '%' => '%',
  '&' => '&',
  '\'' => '\'',
  '(' => '(',
  ')' => ')',
  '*' => '*',
  '+' => '+',
  ',' => ',',
  '-' => '-',
  '.' => '.',
  '/' => '/',
  0 => '0',
  1 => '1',
  2 => '2',
  3 => '3',
  4 => '4',
  5 => '5',
  6 => '6',
  7 => '7',
  8 => '8',
  9 => '9',
  ':' => ':',
  ';' => ';',
  '<' => '<',
  '=' => '=',
  '>' => '>',
  '?' => '?',
  '@' => '@',
  'A' => 'A',
  'B' => 'B',
  'C' => 'C',
  'D' => 'D',
  'E' => 'E',
  'F' => 'F',
  'G' => 'G',
  'H' => 'H',
  'I' => 'I',
  'J' => 'J',
  'K' => 'K',
  'L' => 'L',
  'M' => 'M',
  'N' => 'N',
  'O' => 'O',
  'P' => 'P',
  'Q' => 'Q',
  'R' => 'R',
  'S' => 'S',
  'T' => 'T',
  'U' => 'U',
  'V' => 'V',
  'W' => 'W',
  'X' => 'X',
  'Y' => 'Y',
  'Z' => 'Z',
  '[' => '[',
  '\\' => '\\',
  ']' => ']',
  '^' => '^',
  '_' => '_',
  '`' => '`',
  'a' => 'a',
  'b' => 'b',
  'c' => 'c',
  'd' => 'd',
  'e' => 'e',
  'f' => 'f',
  'g' => 'g',
  'h' => 'h',
  'i' => 'i',
  'j' => 'j',
  'k' => 'k',
  'l' => 'l',
  'm' => 'm',
  'n' => 'n',
  'o' => 'o',
  'p' => 'p',
  'q' => 'q',
  'r' => 'r',
  's' => 's',
  't' => 't',
  'u' => 'u',
  'v' => 'v',
  'w' => 'w',
  'x' => 'x',
  'y' => 'y',
  'z' => 'z',
  '{' => '{',
  '|' => '|',
  '}' => '}',
  '~' => '~',
  '' => '',
  '�' => 'Ć',
  '�' => 'ü',
  '�' => 'é',
  '�' => 'ā',
  '�' => 'ä',
  '�' => 'ģ',
  '�' => 'å',
  '�' => 'ć',
  '�' => 'ł',
  '�' => 'ē',
  '�' => 'Ŗ',
  '�' => 'ŗ',
  '�' => 'ī',
  '�' => 'Ź',
  '�' => 'Ä',
  '�' => 'Å',
  '�' => 'É',
  '�' => 'æ',
  '�' => 'Æ',
  '�' => 'ō',
  '�' => 'ö',
  '�' => 'Ģ',
  '�' => '¢',
  '�' => 'Ś',
  '�' => 'ś',
  '�' => 'Ö',
  '�' => 'Ü',
  '�' => 'ø',
  '�' => '£',
  '�' => 'Ø',
  '�' => '×',
  '�' => '¤',
  '�' => 'Ā',
  '�' => 'Ī',
  '�' => 'ó',
  '�' => 'Ż',
  '�' => 'ż',
  '�' => 'ź',
  '�' => '”',
  '�' => '¦',
  '�' => '©',
  '�' => '®',
  '�' => '¬',
  '�' => '½',
  '�' => '¼',
  '�' => 'Ł',
  '�' => '«',
  '�' => '»',
  '�' => '░',
  '�' => '▒',
  '�' => '▓',
  '�' => '│',
  '�' => '┤',
  '�' => 'Ą',
  '�' => 'Č',
  '�' => 'Ę',
  '�' => 'Ė',
  '�' => '╣',
  '�' => '║',
  '�' => '╗',
  '�' => '╝',
  '�' => 'Į',
  '�' => 'Š',
  '�' => '┐',
  '�' => '└',
  '�' => '┴',
  '�' => '┬',
  '�' => '├',
  '�' => '─',
  '�' => '┼',
  '�' => 'Ų',
  '�' => 'Ū',
  '�' => '╚',
  '�' => '╔',
  '�' => '╩',
  '�' => '╦',
  '�' => '╠',
  '�' => '═',
  '�' => '╬',
  '�' => 'Ž',
  '�' => 'ą',
  '�' => 'č',
  '�' => 'ę',
  '�' => 'ė',
  '�' => 'į',
  '�' => 'š',
  '�' => 'ų',
  '�' => 'ū',
  '�' => 'ž',
  '�' => '┘',
  '�' => '┌',
  '�' => '█',
  '�' => '▄',
  '�' => '▌',
  '�' => '▐',
  '�' => '▀',
  '�' => 'Ó',
  '�' => 'ß',
  '�' => 'Ō',
  '�' => 'Ń',
  '�' => 'õ',
  '�' => 'Õ',
  '�' => 'µ',
  '�' => 'ń',
  '�' => 'Ķ',
  '�' => 'ķ',
  '�' => 'Ļ',
  '�' => 'ļ',
  '�' => 'ņ',
  '�' => 'Ē',
  '�' => 'Ņ',
  '�' => '’',
  '�' => '­',
  '�' => '±',
  '�' => '“',
  '�' => '¾',
  '�' => '¶',
  '�' => '§',
  '�' => '÷',
  '�' => '„',
  '�' => '°',
  '�' => '∙',
  '�' => '·',
  '�' => '¹',
  '�' => '³',
  '�' => '²',
  '�' => '■',
  '�' => ' ',
);

$result =& $data;
unset($data);

return $result;
PKϤ$ZU���zz/polyfill-iconv/Resources/charset/from.cp856.phpnu�[���<?php

static $data = array (
  '' => '',
  '' => '',
  '' => '',
  '' => '',
  '' => '',
  '' => '',
  '' => '',
  '' => '',
  '' => '',
  '	' => '	',
  '
' => '
',
  '' => '',
  '' => '',
  '
' => '
',
  '' => '',
  '' => '',
  '' => '',
  '' => '',
  '' => '',
  '' => '',
  '' => '',
  '' => '',
  '' => '',
  '' => '',
  '' => '',
  '' => '',
  '' => '',
  '' => '',
  '' => '',
  '' => '',
  '' => '',
  '' => '',
  ' ' => ' ',
  '!' => '!',
  '"' => '"',
  '#' => '#',
  '$' => '$',
  '%' => '%',
  '&' => '&',
  '\'' => '\'',
  '(' => '(',
  ')' => ')',
  '*' => '*',
  '+' => '+',
  ',' => ',',
  '-' => '-',
  '.' => '.',
  '/' => '/',
  0 => '0',
  1 => '1',
  2 => '2',
  3 => '3',
  4 => '4',
  5 => '5',
  6 => '6',
  7 => '7',
  8 => '8',
  9 => '9',
  ':' => ':',
  ';' => ';',
  '<' => '<',
  '=' => '=',
  '>' => '>',
  '?' => '?',
  '@' => '@',
  'A' => 'A',
  'B' => 'B',
  'C' => 'C',
  'D' => 'D',
  'E' => 'E',
  'F' => 'F',
  'G' => 'G',
  'H' => 'H',
  'I' => 'I',
  'J' => 'J',
  'K' => 'K',
  'L' => 'L',
  'M' => 'M',
  'N' => 'N',
  'O' => 'O',
  'P' => 'P',
  'Q' => 'Q',
  'R' => 'R',
  'S' => 'S',
  'T' => 'T',
  'U' => 'U',
  'V' => 'V',
  'W' => 'W',
  'X' => 'X',
  'Y' => 'Y',
  'Z' => 'Z',
  '[' => '[',
  '\\' => '\\',
  ']' => ']',
  '^' => '^',
  '_' => '_',
  '`' => '`',
  'a' => 'a',
  'b' => 'b',
  'c' => 'c',
  'd' => 'd',
  'e' => 'e',
  'f' => 'f',
  'g' => 'g',
  'h' => 'h',
  'i' => 'i',
  'j' => 'j',
  'k' => 'k',
  'l' => 'l',
  'm' => 'm',
  'n' => 'n',
  'o' => 'o',
  'p' => 'p',
  'q' => 'q',
  'r' => 'r',
  's' => 's',
  't' => 't',
  'u' => 'u',
  'v' => 'v',
  'w' => 'w',
  'x' => 'x',
  'y' => 'y',
  'z' => 'z',
  '{' => '{',
  '|' => '|',
  '}' => '}',
  '~' => '~',
  '' => '',
  '�' => 'א',
  '�' => 'ב',
  '�' => 'ג',
  '�' => 'ד',
  '�' => 'ה',
  '�' => 'ו',
  '�' => 'ז',
  '�' => 'ח',
  '�' => 'ט',
  '�' => 'י',
  '�' => 'ך',
  '�' => 'כ',
  '�' => 'ל',
  '�' => 'ם',
  '�' => 'מ',
  '�' => 'ן',
  '�' => 'נ',
  '�' => 'ס',
  '�' => 'ע',
  '�' => 'ף',
  '�' => 'פ',
  '�' => 'ץ',
  '�' => 'צ',
  '�' => 'ק',
  '�' => 'ר',
  '�' => 'ש',
  '�' => 'ת',
  '�' => '£',
  '�' => '×',
  '�' => '®',
  '�' => '¬',
  '�' => '½',
  '�' => '¼',
  '�' => '«',
  '�' => '»',
  '�' => '░',
  '�' => '▒',
  '�' => '▓',
  '�' => '│',
  '�' => '┤',
  '�' => '©',
  '�' => '╣',
  '�' => '║',
  '�' => '╗',
  '�' => '╝',
  '�' => '¢',
  '�' => '¥',
  '�' => '┐',
  '�' => '└',
  '�' => '┴',
  '�' => '┬',
  '�' => '├',
  '�' => '─',
  '�' => '┼',
  '�' => '╚',
  '�' => '╔',
  '�' => '╩',
  '�' => '╦',
  '�' => '╠',
  '�' => '═',
  '�' => '╬',
  '�' => '¤',
  '�' => '┘',
  '�' => '┌',
  '�' => '█',
  '�' => '▄',
  '�' => '¦',
  '�' => '▀',
  '�' => 'µ',
  '�' => '¯',
  '�' => '´',
  '�' => '­',
  '�' => '±',
  '�' => '‗',
  '�' => '¾',
  '�' => '¶',
  '�' => '§',
  '�' => '÷',
  '�' => '¸',
  '�' => '°',
  '�' => '¨',
  '�' => '·',
  '�' => '¹',
  '�' => '³',
  '�' => '²',
  '�' => '■',
  '�' => ' ',
);

$result =& $data;
unset($data);

return $result;
PKϤ$Z,�  6polyfill-iconv/Resources/charset/from.windows-1257.phpnu�[���<?php

static $data = array (
  '' => '',
  '' => '',
  '' => '',
  '' => '',
  '' => '',
  '' => '',
  '' => '',
  '' => '',
  '' => '',
  '	' => '	',
  '
' => '
',
  '' => '',
  '' => '',
  '
' => '
',
  '' => '',
  '' => '',
  '' => '',
  '' => '',
  '' => '',
  '' => '',
  '' => '',
  '' => '',
  '' => '',
  '' => '',
  '' => '',
  '' => '',
  '' => '',
  '' => '',
  '' => '',
  '' => '',
  '' => '',
  '' => '',
  ' ' => ' ',
  '!' => '!',
  '"' => '"',
  '#' => '#',
  '$' => '$',
  '%' => '%',
  '&' => '&',
  '\'' => '\'',
  '(' => '(',
  ')' => ')',
  '*' => '*',
  '+' => '+',
  ',' => ',',
  '-' => '-',
  '.' => '.',
  '/' => '/',
  0 => '0',
  1 => '1',
  2 => '2',
  3 => '3',
  4 => '4',
  5 => '5',
  6 => '6',
  7 => '7',
  8 => '8',
  9 => '9',
  ':' => ':',
  ';' => ';',
  '<' => '<',
  '=' => '=',
  '>' => '>',
  '?' => '?',
  '@' => '@',
  'A' => 'A',
  'B' => 'B',
  'C' => 'C',
  'D' => 'D',
  'E' => 'E',
  'F' => 'F',
  'G' => 'G',
  'H' => 'H',
  'I' => 'I',
  'J' => 'J',
  'K' => 'K',
  'L' => 'L',
  'M' => 'M',
  'N' => 'N',
  'O' => 'O',
  'P' => 'P',
  'Q' => 'Q',
  'R' => 'R',
  'S' => 'S',
  'T' => 'T',
  'U' => 'U',
  'V' => 'V',
  'W' => 'W',
  'X' => 'X',
  'Y' => 'Y',
  'Z' => 'Z',
  '[' => '[',
  '\\' => '\\',
  ']' => ']',
  '^' => '^',
  '_' => '_',
  '`' => '`',
  'a' => 'a',
  'b' => 'b',
  'c' => 'c',
  'd' => 'd',
  'e' => 'e',
  'f' => 'f',
  'g' => 'g',
  'h' => 'h',
  'i' => 'i',
  'j' => 'j',
  'k' => 'k',
  'l' => 'l',
  'm' => 'm',
  'n' => 'n',
  'o' => 'o',
  'p' => 'p',
  'q' => 'q',
  'r' => 'r',
  's' => 's',
  't' => 't',
  'u' => 'u',
  'v' => 'v',
  'w' => 'w',
  'x' => 'x',
  'y' => 'y',
  'z' => 'z',
  '{' => '{',
  '|' => '|',
  '}' => '}',
  '~' => '~',
  '' => '',
  '�' => '€',
  '�' => '‚',
  '�' => '„',
  '�' => '…',
  '�' => '†',
  '�' => '‡',
  '�' => '‰',
  '�' => '‹',
  '�' => '¨',
  '�' => 'ˇ',
  '�' => '¸',
  '�' => '‘',
  '�' => '’',
  '�' => '“',
  '�' => '”',
  '�' => '•',
  '�' => '–',
  '�' => '—',
  '�' => '™',
  '�' => '›',
  '�' => '¯',
  '�' => '˛',
  '�' => ' ',
  '�' => '¢',
  '�' => '£',
  '�' => '¤',
  '�' => '¦',
  '�' => '§',
  '�' => 'Ø',
  '�' => '©',
  '�' => 'Ŗ',
  '�' => '«',
  '�' => '¬',
  '�' => '­',
  '�' => '®',
  '�' => 'Æ',
  '�' => '°',
  '�' => '±',
  '�' => '²',
  '�' => '³',
  '�' => '´',
  '�' => 'µ',
  '�' => '¶',
  '�' => '·',
  '�' => 'ø',
  '�' => '¹',
  '�' => 'ŗ',
  '�' => '»',
  '�' => '¼',
  '�' => '½',
  '�' => '¾',
  '�' => 'æ',
  '�' => 'Ą',
  '�' => 'Į',
  '�' => 'Ā',
  '�' => 'Ć',
  '�' => 'Ä',
  '�' => 'Å',
  '�' => 'Ę',
  '�' => 'Ē',
  '�' => 'Č',
  '�' => 'É',
  '�' => 'Ź',
  '�' => 'Ė',
  '�' => 'Ģ',
  '�' => 'Ķ',
  '�' => 'Ī',
  '�' => 'Ļ',
  '�' => 'Š',
  '�' => 'Ń',
  '�' => 'Ņ',
  '�' => 'Ó',
  '�' => 'Ō',
  '�' => 'Õ',
  '�' => 'Ö',
  '�' => '×',
  '�' => 'Ų',
  '�' => 'Ł',
  '�' => 'Ś',
  '�' => 'Ū',
  '�' => 'Ü',
  '�' => 'Ż',
  '�' => 'Ž',
  '�' => 'ß',
  '�' => 'ą',
  '�' => 'į',
  '�' => 'ā',
  '�' => 'ć',
  '�' => 'ä',
  '�' => 'å',
  '�' => 'ę',
  '�' => 'ē',
  '�' => 'č',
  '�' => 'é',
  '�' => 'ź',
  '�' => 'ė',
  '�' => 'ģ',
  '�' => 'ķ',
  '�' => 'ī',
  '�' => 'ļ',
  '�' => 'š',
  '�' => 'ń',
  '�' => 'ņ',
  '�' => 'ó',
  '�' => 'ō',
  '�' => 'õ',
  '�' => 'ö',
  '�' => '÷',
  '�' => 'ų',
  '�' => 'ł',
  '�' => 'ś',
  '�' => 'ū',
  '�' => 'ü',
  '�' => 'ż',
  '�' => 'ž',
  '�' => '˙',
);

$result =& $data;
unset($data);

return $result;
PKϤ$Zx�z���4polyfill-iconv/Resources/charset/from.iso-8859-9.phpnu�[���<?php

static $data = array (
  '' => '',
  '' => '',
  '' => '',
  '' => '',
  '' => '',
  '' => '',
  '' => '',
  '' => '',
  '' => '',
  '	' => '	',
  '
' => '
',
  '' => '',
  '' => '',
  '
' => '
',
  '' => '',
  '' => '',
  '' => '',
  '' => '',
  '' => '',
  '' => '',
  '' => '',
  '' => '',
  '' => '',
  '' => '',
  '' => '',
  '' => '',
  '' => '',
  '' => '',
  '' => '',
  '' => '',
  '' => '',
  '' => '',
  ' ' => ' ',
  '!' => '!',
  '"' => '"',
  '#' => '#',
  '$' => '$',
  '%' => '%',
  '&' => '&',
  '\'' => '\'',
  '(' => '(',
  ')' => ')',
  '*' => '*',
  '+' => '+',
  ',' => ',',
  '-' => '-',
  '.' => '.',
  '/' => '/',
  0 => '0',
  1 => '1',
  2 => '2',
  3 => '3',
  4 => '4',
  5 => '5',
  6 => '6',
  7 => '7',
  8 => '8',
  9 => '9',
  ':' => ':',
  ';' => ';',
  '<' => '<',
  '=' => '=',
  '>' => '>',
  '?' => '?',
  '@' => '@',
  'A' => 'A',
  'B' => 'B',
  'C' => 'C',
  'D' => 'D',
  'E' => 'E',
  'F' => 'F',
  'G' => 'G',
  'H' => 'H',
  'I' => 'I',
  'J' => 'J',
  'K' => 'K',
  'L' => 'L',
  'M' => 'M',
  'N' => 'N',
  'O' => 'O',
  'P' => 'P',
  'Q' => 'Q',
  'R' => 'R',
  'S' => 'S',
  'T' => 'T',
  'U' => 'U',
  'V' => 'V',
  'W' => 'W',
  'X' => 'X',
  'Y' => 'Y',
  'Z' => 'Z',
  '[' => '[',
  '\\' => '\\',
  ']' => ']',
  '^' => '^',
  '_' => '_',
  '`' => '`',
  'a' => 'a',
  'b' => 'b',
  'c' => 'c',
  'd' => 'd',
  'e' => 'e',
  'f' => 'f',
  'g' => 'g',
  'h' => 'h',
  'i' => 'i',
  'j' => 'j',
  'k' => 'k',
  'l' => 'l',
  'm' => 'm',
  'n' => 'n',
  'o' => 'o',
  'p' => 'p',
  'q' => 'q',
  'r' => 'r',
  's' => 's',
  't' => 't',
  'u' => 'u',
  'v' => 'v',
  'w' => 'w',
  'x' => 'x',
  'y' => 'y',
  'z' => 'z',
  '{' => '{',
  '|' => '|',
  '}' => '}',
  '~' => '~',
  '' => '',
  '�' => '€',
  '�' => '',
  '�' => '‚',
  '�' => 'ƒ',
  '�' => '„',
  '�' => '…',
  '�' => '†',
  '�' => '‡',
  '�' => 'ˆ',
  '�' => '‰',
  '�' => 'Š',
  '�' => '‹',
  '�' => 'Œ',
  '�' => '',
  '�' => 'Ž',
  '�' => '',
  '�' => '',
  '�' => '‘',
  '�' => '’',
  '�' => '“',
  '�' => '”',
  '�' => '•',
  '�' => '–',
  '�' => '—',
  '�' => '˜',
  '�' => '™',
  '�' => 'š',
  '�' => '›',
  '�' => 'œ',
  '�' => '',
  '�' => 'ž',
  '�' => 'Ÿ',
  '�' => ' ',
  '�' => '¡',
  '�' => '¢',
  '�' => '£',
  '�' => '¤',
  '�' => '¥',
  '�' => '¦',
  '�' => '§',
  '�' => '¨',
  '�' => '©',
  '�' => 'ª',
  '�' => '«',
  '�' => '¬',
  '�' => '­',
  '�' => '®',
  '�' => '¯',
  '�' => '°',
  '�' => '±',
  '�' => '²',
  '�' => '³',
  '�' => '´',
  '�' => 'µ',
  '�' => '¶',
  '�' => '·',
  '�' => '¸',
  '�' => '¹',
  '�' => 'º',
  '�' => '»',
  '�' => '¼',
  '�' => '½',
  '�' => '¾',
  '�' => '¿',
  '�' => 'À',
  '�' => 'Á',
  '�' => 'Â',
  '�' => 'Ã',
  '�' => 'Ä',
  '�' => 'Å',
  '�' => 'Æ',
  '�' => 'Ç',
  '�' => 'È',
  '�' => 'É',
  '�' => 'Ê',
  '�' => 'Ë',
  '�' => 'Ì',
  '�' => 'Í',
  '�' => 'Î',
  '�' => 'Ï',
  '�' => 'Ğ',
  '�' => 'Ñ',
  '�' => 'Ò',
  '�' => 'Ó',
  '�' => 'Ô',
  '�' => 'Õ',
  '�' => 'Ö',
  '�' => '×',
  '�' => 'Ø',
  '�' => 'Ù',
  '�' => 'Ú',
  '�' => 'Û',
  '�' => 'Ü',
  '�' => 'İ',
  '�' => 'Ş',
  '�' => 'ß',
  '�' => 'à',
  '�' => 'á',
  '�' => 'â',
  '�' => 'ã',
  '�' => 'ä',
  '�' => 'å',
  '�' => 'æ',
  '�' => 'ç',
  '�' => 'è',
  '�' => 'é',
  '�' => 'ê',
  '�' => 'ë',
  '�' => 'ì',
  '�' => 'í',
  '�' => 'î',
  '�' => 'ï',
  '�' => 'ğ',
  '�' => 'ñ',
  '�' => 'ò',
  '�' => 'ó',
  '�' => 'ô',
  '�' => 'õ',
  '�' => 'ö',
  '�' => '÷',
  '�' => 'ø',
  '�' => 'ù',
  '�' => 'ú',
  '�' => 'û',
  '�' => 'ü',
  '�' => 'ı',
  '�' => 'ş',
  '�' => 'ÿ',
);

$result =& $data;
unset($data);

return $result;
PKϤ$Z�C��
�
6polyfill-iconv/Resources/charset/from.windows-1253.phpnu�[���<?php

static $data = array (
  '' => '',
  '' => '',
  '' => '',
  '' => '',
  '' => '',
  '' => '',
  '' => '',
  '' => '',
  '' => '',
  '	' => '	',
  '
' => '
',
  '' => '',
  '' => '',
  '
' => '
',
  '' => '',
  '' => '',
  '' => '',
  '' => '',
  '' => '',
  '' => '',
  '' => '',
  '' => '',
  '' => '',
  '' => '',
  '' => '',
  '' => '',
  '' => '',
  '' => '',
  '' => '',
  '' => '',
  '' => '',
  '' => '',
  ' ' => ' ',
  '!' => '!',
  '"' => '"',
  '#' => '#',
  '$' => '$',
  '%' => '%',
  '&' => '&',
  '\'' => '\'',
  '(' => '(',
  ')' => ')',
  '*' => '*',
  '+' => '+',
  ',' => ',',
  '-' => '-',
  '.' => '.',
  '/' => '/',
  0 => '0',
  1 => '1',
  2 => '2',
  3 => '3',
  4 => '4',
  5 => '5',
  6 => '6',
  7 => '7',
  8 => '8',
  9 => '9',
  ':' => ':',
  ';' => ';',
  '<' => '<',
  '=' => '=',
  '>' => '>',
  '?' => '?',
  '@' => '@',
  'A' => 'A',
  'B' => 'B',
  'C' => 'C',
  'D' => 'D',
  'E' => 'E',
  'F' => 'F',
  'G' => 'G',
  'H' => 'H',
  'I' => 'I',
  'J' => 'J',
  'K' => 'K',
  'L' => 'L',
  'M' => 'M',
  'N' => 'N',
  'O' => 'O',
  'P' => 'P',
  'Q' => 'Q',
  'R' => 'R',
  'S' => 'S',
  'T' => 'T',
  'U' => 'U',
  'V' => 'V',
  'W' => 'W',
  'X' => 'X',
  'Y' => 'Y',
  'Z' => 'Z',
  '[' => '[',
  '\\' => '\\',
  ']' => ']',
  '^' => '^',
  '_' => '_',
  '`' => '`',
  'a' => 'a',
  'b' => 'b',
  'c' => 'c',
  'd' => 'd',
  'e' => 'e',
  'f' => 'f',
  'g' => 'g',
  'h' => 'h',
  'i' => 'i',
  'j' => 'j',
  'k' => 'k',
  'l' => 'l',
  'm' => 'm',
  'n' => 'n',
  'o' => 'o',
  'p' => 'p',
  'q' => 'q',
  'r' => 'r',
  's' => 's',
  't' => 't',
  'u' => 'u',
  'v' => 'v',
  'w' => 'w',
  'x' => 'x',
  'y' => 'y',
  'z' => 'z',
  '{' => '{',
  '|' => '|',
  '}' => '}',
  '~' => '~',
  '' => '',
  '�' => '€',
  '�' => '‚',
  '�' => 'ƒ',
  '�' => '„',
  '�' => '…',
  '�' => '†',
  '�' => '‡',
  '�' => '‰',
  '�' => '‹',
  '�' => '‘',
  '�' => '’',
  '�' => '“',
  '�' => '”',
  '�' => '•',
  '�' => '–',
  '�' => '—',
  '�' => '™',
  '�' => '›',
  '�' => ' ',
  '�' => '΅',
  '�' => 'Ά',
  '�' => '£',
  '�' => '¤',
  '�' => '¥',
  '�' => '¦',
  '�' => '§',
  '�' => '¨',
  '�' => '©',
  '�' => '«',
  '�' => '¬',
  '�' => '­',
  '�' => '®',
  '�' => '―',
  '�' => '°',
  '�' => '±',
  '�' => '²',
  '�' => '³',
  '�' => '΄',
  '�' => 'µ',
  '�' => '¶',
  '�' => '·',
  '�' => 'Έ',
  '�' => 'Ή',
  '�' => 'Ί',
  '�' => '»',
  '�' => 'Ό',
  '�' => '½',
  '�' => 'Ύ',
  '�' => 'Ώ',
  '�' => 'ΐ',
  '�' => 'Α',
  '�' => 'Β',
  '�' => 'Γ',
  '�' => 'Δ',
  '�' => 'Ε',
  '�' => 'Ζ',
  '�' => 'Η',
  '�' => 'Θ',
  '�' => 'Ι',
  '�' => 'Κ',
  '�' => 'Λ',
  '�' => 'Μ',
  '�' => 'Ν',
  '�' => 'Ξ',
  '�' => 'Ο',
  '�' => 'Π',
  '�' => 'Ρ',
  '�' => 'Σ',
  '�' => 'Τ',
  '�' => 'Υ',
  '�' => 'Φ',
  '�' => 'Χ',
  '�' => 'Ψ',
  '�' => 'Ω',
  '�' => 'Ϊ',
  '�' => 'Ϋ',
  '�' => 'ά',
  '�' => 'έ',
  '�' => 'ή',
  '�' => 'ί',
  '�' => 'ΰ',
  '�' => 'α',
  '�' => 'β',
  '�' => 'γ',
  '�' => 'δ',
  '�' => 'ε',
  '�' => 'ζ',
  '�' => 'η',
  '�' => 'θ',
  '�' => 'ι',
  '�' => 'κ',
  '�' => 'λ',
  '�' => 'μ',
  '�' => 'ν',
  '�' => 'ξ',
  '�' => 'ο',
  '�' => 'π',
  '�' => 'ρ',
  '�' => 'ς',
  '�' => 'σ',
  '�' => 'τ',
  '�' => 'υ',
  '�' => 'φ',
  '�' => 'χ',
  '�' => 'ψ',
  '�' => 'ω',
  '�' => 'ϊ',
  '�' => 'ϋ',
  '�' => 'ό',
  '�' => 'ύ',
  '�' => 'ώ',
);

$result =& $data;
unset($data);

return $result;
PKϤ$Zj� ���4polyfill-iconv/Resources/charset/from.iso-8859-4.phpnu�[���<?php

static $data = array (
  '' => '',
  '' => '',
  '' => '',
  '' => '',
  '' => '',
  '' => '',
  '' => '',
  '' => '',
  '' => '',
  '	' => '	',
  '
' => '
',
  '' => '',
  '' => '',
  '
' => '
',
  '' => '',
  '' => '',
  '' => '',
  '' => '',
  '' => '',
  '' => '',
  '' => '',
  '' => '',
  '' => '',
  '' => '',
  '' => '',
  '' => '',
  '' => '',
  '' => '',
  '' => '',
  '' => '',
  '' => '',
  '' => '',
  ' ' => ' ',
  '!' => '!',
  '"' => '"',
  '#' => '#',
  '$' => '$',
  '%' => '%',
  '&' => '&',
  '\'' => '\'',
  '(' => '(',
  ')' => ')',
  '*' => '*',
  '+' => '+',
  ',' => ',',
  '-' => '-',
  '.' => '.',
  '/' => '/',
  0 => '0',
  1 => '1',
  2 => '2',
  3 => '3',
  4 => '4',
  5 => '5',
  6 => '6',
  7 => '7',
  8 => '8',
  9 => '9',
  ':' => ':',
  ';' => ';',
  '<' => '<',
  '=' => '=',
  '>' => '>',
  '?' => '?',
  '@' => '@',
  'A' => 'A',
  'B' => 'B',
  'C' => 'C',
  'D' => 'D',
  'E' => 'E',
  'F' => 'F',
  'G' => 'G',
  'H' => 'H',
  'I' => 'I',
  'J' => 'J',
  'K' => 'K',
  'L' => 'L',
  'M' => 'M',
  'N' => 'N',
  'O' => 'O',
  'P' => 'P',
  'Q' => 'Q',
  'R' => 'R',
  'S' => 'S',
  'T' => 'T',
  'U' => 'U',
  'V' => 'V',
  'W' => 'W',
  'X' => 'X',
  'Y' => 'Y',
  'Z' => 'Z',
  '[' => '[',
  '\\' => '\\',
  ']' => ']',
  '^' => '^',
  '_' => '_',
  '`' => '`',
  'a' => 'a',
  'b' => 'b',
  'c' => 'c',
  'd' => 'd',
  'e' => 'e',
  'f' => 'f',
  'g' => 'g',
  'h' => 'h',
  'i' => 'i',
  'j' => 'j',
  'k' => 'k',
  'l' => 'l',
  'm' => 'm',
  'n' => 'n',
  'o' => 'o',
  'p' => 'p',
  'q' => 'q',
  'r' => 'r',
  's' => 's',
  't' => 't',
  'u' => 'u',
  'v' => 'v',
  'w' => 'w',
  'x' => 'x',
  'y' => 'y',
  'z' => 'z',
  '{' => '{',
  '|' => '|',
  '}' => '}',
  '~' => '~',
  '' => '',
  '�' => '€',
  '�' => '',
  '�' => '‚',
  '�' => 'ƒ',
  '�' => '„',
  '�' => '…',
  '�' => '†',
  '�' => '‡',
  '�' => 'ˆ',
  '�' => '‰',
  '�' => 'Š',
  '�' => '‹',
  '�' => 'Œ',
  '�' => '',
  '�' => 'Ž',
  '�' => '',
  '�' => '',
  '�' => '‘',
  '�' => '’',
  '�' => '“',
  '�' => '”',
  '�' => '•',
  '�' => '–',
  '�' => '—',
  '�' => '˜',
  '�' => '™',
  '�' => 'š',
  '�' => '›',
  '�' => 'œ',
  '�' => '',
  '�' => 'ž',
  '�' => 'Ÿ',
  '�' => ' ',
  '�' => 'Ą',
  '�' => 'ĸ',
  '�' => 'Ŗ',
  '�' => '¤',
  '�' => 'Ĩ',
  '�' => 'Ļ',
  '�' => '§',
  '�' => '¨',
  '�' => 'Š',
  '�' => 'Ē',
  '�' => 'Ģ',
  '�' => 'Ŧ',
  '�' => '­',
  '�' => 'Ž',
  '�' => '¯',
  '�' => '°',
  '�' => 'ą',
  '�' => '˛',
  '�' => 'ŗ',
  '�' => '´',
  '�' => 'ĩ',
  '�' => 'ļ',
  '�' => 'ˇ',
  '�' => '¸',
  '�' => 'š',
  '�' => 'ē',
  '�' => 'ģ',
  '�' => 'ŧ',
  '�' => 'Ŋ',
  '�' => 'ž',
  '�' => 'ŋ',
  '�' => 'Ā',
  '�' => 'Á',
  '�' => 'Â',
  '�' => 'Ã',
  '�' => 'Ä',
  '�' => 'Å',
  '�' => 'Æ',
  '�' => 'Į',
  '�' => 'Č',
  '�' => 'É',
  '�' => 'Ę',
  '�' => 'Ë',
  '�' => 'Ė',
  '�' => 'Í',
  '�' => 'Î',
  '�' => 'Ī',
  '�' => 'Đ',
  '�' => 'Ņ',
  '�' => 'Ō',
  '�' => 'Ķ',
  '�' => 'Ô',
  '�' => 'Õ',
  '�' => 'Ö',
  '�' => '×',
  '�' => 'Ø',
  '�' => 'Ų',
  '�' => 'Ú',
  '�' => 'Û',
  '�' => 'Ü',
  '�' => 'Ũ',
  '�' => 'Ū',
  '�' => 'ß',
  '�' => 'ā',
  '�' => 'á',
  '�' => 'â',
  '�' => 'ã',
  '�' => 'ä',
  '�' => 'å',
  '�' => 'æ',
  '�' => 'į',
  '�' => 'č',
  '�' => 'é',
  '�' => 'ę',
  '�' => 'ë',
  '�' => 'ė',
  '�' => 'í',
  '�' => 'î',
  '�' => 'ī',
  '�' => 'đ',
  '�' => 'ņ',
  '�' => 'ō',
  '�' => 'ķ',
  '�' => 'ô',
  '�' => 'õ',
  '�' => 'ö',
  '�' => '÷',
  '�' => 'ø',
  '�' => 'ų',
  '�' => 'ú',
  '�' => 'û',
  '�' => 'ü',
  '�' => 'ũ',
  '�' => 'ū',
  '�' => '˙',
);

$result =& $data;
unset($data);

return $result;
PKϤ$Z
��r�r/polyfill-iconv/Resources/charset/from.cp949.phpnu�[���<?php

static $data = array (
  '' => '',
  '' => '',
  '' => '',
  '' => '',
  '' => '',
  '' => '',
  '' => '',
  '' => '',
  '' => '',
  '	' => '	',
  '
' => '
',
  '' => '',
  '' => '',
  '
' => '
',
  '' => '',
  '' => '',
  '' => '',
  '' => '',
  '' => '',
  '' => '',
  '' => '',
  '' => '',
  '' => '',
  '' => '',
  '' => '',
  '' => '',
  '' => '',
  '' => '',
  '' => '',
  '' => '',
  '' => '',
  '' => '',
  ' ' => ' ',
  '!' => '!',
  '"' => '"',
  '#' => '#',
  '$' => '$',
  '%' => '%',
  '&' => '&',
  '\'' => '\'',
  '(' => '(',
  ')' => ')',
  '*' => '*',
  '+' => '+',
  ',' => ',',
  '-' => '-',
  '.' => '.',
  '/' => '/',
  0 => '0',
  1 => '1',
  2 => '2',
  3 => '3',
  4 => '4',
  5 => '5',
  6 => '6',
  7 => '7',
  8 => '8',
  9 => '9',
  ':' => ':',
  ';' => ';',
  '<' => '<',
  '=' => '=',
  '>' => '>',
  '?' => '?',
  '@' => '@',
  'A' => 'A',
  'B' => 'B',
  'C' => 'C',
  'D' => 'D',
  'E' => 'E',
  'F' => 'F',
  'G' => 'G',
  'H' => 'H',
  'I' => 'I',
  'J' => 'J',
  'K' => 'K',
  'L' => 'L',
  'M' => 'M',
  'N' => 'N',
  'O' => 'O',
  'P' => 'P',
  'Q' => 'Q',
  'R' => 'R',
  'S' => 'S',
  'T' => 'T',
  'U' => 'U',
  'V' => 'V',
  'W' => 'W',
  'X' => 'X',
  'Y' => 'Y',
  'Z' => 'Z',
  '[' => '[',
  '\\' => '\\',
  ']' => ']',
  '^' => '^',
  '_' => '_',
  '`' => '`',
  'a' => 'a',
  'b' => 'b',
  'c' => 'c',
  'd' => 'd',
  'e' => 'e',
  'f' => 'f',
  'g' => 'g',
  'h' => 'h',
  'i' => 'i',
  'j' => 'j',
  'k' => 'k',
  'l' => 'l',
  'm' => 'm',
  'n' => 'n',
  'o' => 'o',
  'p' => 'p',
  'q' => 'q',
  'r' => 'r',
  's' => 's',
  't' => 't',
  'u' => 'u',
  'v' => 'v',
  'w' => 'w',
  'x' => 'x',
  'y' => 'y',
  'z' => 'z',
  '{' => '{',
  '|' => '|',
  '}' => '}',
  '~' => '~',
  '' => '',
  '�A' => '갂',
  '�B' => '갃',
  '�C' => '갅',
  '�D' => '갆',
  '�E' => '갋',
  '�F' => '갌',
  '�G' => '갍',
  '�H' => '갎',
  '�I' => '갏',
  '�J' => '갘',
  '�K' => '갞',
  '�L' => '갟',
  '�M' => '갡',
  '�N' => '갢',
  '�O' => '갣',
  '�P' => '갥',
  '�Q' => '갦',
  '�R' => '갧',
  '�S' => '갨',
  '�T' => '갩',
  '�U' => '갪',
  '�V' => '갫',
  '�W' => '갮',
  '�X' => '갲',
  '�Y' => '갳',
  '�Z' => '갴',
  '�a' => '갵',
  '�b' => '갶',
  '�c' => '갷',
  '�d' => '갺',
  '�e' => '갻',
  '�f' => '갽',
  '�g' => '갾',
  '�h' => '갿',
  '�i' => '걁',
  '�j' => '걂',
  '�k' => '걃',
  '�l' => '걄',
  '�m' => '걅',
  '�n' => '걆',
  '�o' => '걇',
  '�p' => '걈',
  '�q' => '걉',
  '�r' => '걊',
  '�s' => '걌',
  '�t' => '걎',
  '�u' => '걏',
  '�v' => '걐',
  '�w' => '걑',
  '�x' => '걒',
  '�y' => '걓',
  '�z' => '걕',
  '��' => '걖',
  '��' => '걗',
  '��' => '걙',
  '��' => '걚',
  '��' => '걛',
  '��' => '걝',
  '��' => '걞',
  '��' => '걟',
  '��' => '걠',
  '��' => '걡',
  '��' => '걢',
  '��' => '걣',
  '��' => '걤',
  '��' => '걥',
  '��' => '걦',
  '��' => '걧',
  '��' => '걨',
  '��' => '걩',
  '��' => '걪',
  '��' => '걫',
  '��' => '걬',
  '��' => '걭',
  '��' => '걮',
  '��' => '걯',
  '��' => '걲',
  '��' => '걳',
  '��' => '걵',
  '��' => '걶',
  '��' => '걹',
  '��' => '걻',
  '��' => '걼',
  '��' => '걽',
  '��' => '걾',
  '��' => '걿',
  '��' => '겂',
  '��' => '겇',
  '��' => '겈',
  '��' => '겍',
  '��' => '겎',
  '��' => '겏',
  '��' => '겑',
  '��' => '겒',
  '��' => '겓',
  '��' => '겕',
  '��' => '겖',
  '��' => '겗',
  '��' => '겘',
  '��' => '겙',
  '��' => '겚',
  '��' => '겛',
  '��' => '겞',
  '��' => '겢',
  '��' => '겣',
  '��' => '겤',
  '��' => '겥',
  '��' => '겦',
  '��' => '겧',
  '��' => '겫',
  '��' => '겭',
  '��' => '겮',
  '��' => '겱',
  '��' => '겲',
  '��' => '겳',
  '��' => '겴',
  '��' => '겵',
  '��' => '겶',
  '��' => '겷',
  '��' => '겺',
  '��' => '겾',
  '��' => '겿',
  '��' => '곀',
  '��' => '곂',
  '��' => '곃',
  '��' => '곅',
  '��' => '곆',
  '��' => '곇',
  '��' => '곉',
  '��' => '곊',
  '��' => '곋',
  '��' => '곍',
  '��' => '곎',
  '��' => '곏',
  '��' => '곐',
  '��' => '곑',
  '��' => '곒',
  '��' => '곓',
  '��' => '곔',
  '��' => '곖',
  '��' => '곘',
  '��' => '곙',
  '��' => '곚',
  '��' => '곛',
  '��' => '곜',
  '��' => '곝',
  '��' => '곞',
  '��' => '곟',
  '��' => '곢',
  '��' => '곣',
  '��' => '곥',
  '��' => '곦',
  '��' => '곩',
  '��' => '곫',
  '��' => '곭',
  '��' => '곮',
  '��' => '곲',
  '��' => '곴',
  '��' => '곷',
  '��' => '곸',
  '��' => '곹',
  '��' => '곺',
  '��' => '곻',
  '��' => '곾',
  '��' => '곿',
  '��' => '괁',
  '��' => '괂',
  '��' => '괃',
  '��' => '괅',
  '��' => '괇',
  '��' => '괈',
  '��' => '괉',
  '��' => '괊',
  '��' => '괋',
  '��' => '괎',
  '��' => '괐',
  '��' => '괒',
  '��' => '괓',
  '�A' => '괔',
  '�B' => '괕',
  '�C' => '괖',
  '�D' => '괗',
  '�E' => '괙',
  '�F' => '괚',
  '�G' => '괛',
  '�H' => '괝',
  '�I' => '괞',
  '�J' => '괟',
  '�K' => '괡',
  '�L' => '괢',
  '�M' => '괣',
  '�N' => '괤',
  '�O' => '괥',
  '�P' => '괦',
  '�Q' => '괧',
  '�R' => '괨',
  '�S' => '괪',
  '�T' => '괫',
  '�U' => '괮',
  '�V' => '괯',
  '�W' => '괰',
  '�X' => '괱',
  '�Y' => '괲',
  '�Z' => '괳',
  '�a' => '괶',
  '�b' => '괷',
  '�c' => '괹',
  '�d' => '괺',
  '�e' => '괻',
  '�f' => '괽',
  '�g' => '괾',
  '�h' => '괿',
  '�i' => '굀',
  '�j' => '굁',
  '�k' => '굂',
  '�l' => '굃',
  '�m' => '굆',
  '�n' => '굈',
  '�o' => '굊',
  '�p' => '굋',
  '�q' => '굌',
  '�r' => '굍',
  '�s' => '굎',
  '�t' => '굏',
  '�u' => '굑',
  '�v' => '굒',
  '�w' => '굓',
  '�x' => '굕',
  '�y' => '굖',
  '�z' => '굗',
  '��' => '굙',
  '��' => '굚',
  '��' => '굛',
  '��' => '굜',
  '��' => '굝',
  '��' => '굞',
  '��' => '굟',
  '��' => '굠',
  '��' => '굢',
  '��' => '굤',
  '��' => '굥',
  '��' => '굦',
  '��' => '굧',
  '��' => '굨',
  '��' => '굩',
  '��' => '굪',
  '��' => '굫',
  '��' => '굮',
  '��' => '굯',
  '��' => '굱',
  '��' => '굲',
  '��' => '굷',
  '��' => '굸',
  '��' => '굹',
  '��' => '굺',
  '��' => '굾',
  '��' => '궀',
  '��' => '궃',
  '��' => '궄',
  '��' => '궅',
  '��' => '궆',
  '��' => '궇',
  '��' => '궊',
  '��' => '궋',
  '��' => '궍',
  '��' => '궎',
  '��' => '궏',
  '��' => '궑',
  '��' => '궒',
  '��' => '궓',
  '��' => '궔',
  '��' => '궕',
  '��' => '궖',
  '��' => '궗',
  '��' => '궘',
  '��' => '궙',
  '��' => '궚',
  '��' => '궛',
  '��' => '궞',
  '��' => '궟',
  '��' => '궠',
  '��' => '궡',
  '��' => '궢',
  '��' => '궣',
  '��' => '궥',
  '��' => '궦',
  '��' => '궧',
  '��' => '궨',
  '��' => '궩',
  '��' => '궪',
  '��' => '궫',
  '��' => '궬',
  '��' => '궭',
  '��' => '궮',
  '��' => '궯',
  '��' => '궰',
  '��' => '궱',
  '��' => '궲',
  '��' => '궳',
  '��' => '궴',
  '��' => '궵',
  '��' => '궶',
  '��' => '궸',
  '��' => '궹',
  '��' => '궺',
  '��' => '궻',
  '��' => '궼',
  '��' => '궽',
  '��' => '궾',
  '��' => '궿',
  '��' => '귂',
  '��' => '귃',
  '��' => '귅',
  '��' => '귆',
  '��' => '귇',
  '��' => '귉',
  '��' => '귊',
  '��' => '귋',
  '��' => '귌',
  '��' => '귍',
  '��' => '귎',
  '��' => '귏',
  '��' => '귒',
  '��' => '귔',
  '��' => '귕',
  '��' => '귖',
  '��' => '귗',
  '��' => '귘',
  '��' => '귙',
  '��' => '귚',
  '��' => '귛',
  '��' => '귝',
  '��' => '귞',
  '��' => '귟',
  '��' => '귡',
  '��' => '귢',
  '��' => '귣',
  '��' => '귥',
  '��' => '귦',
  '��' => '귧',
  '��' => '귨',
  '��' => '귩',
  '��' => '귪',
  '��' => '귫',
  '��' => '귬',
  '��' => '귭',
  '��' => '귮',
  '��' => '귯',
  '��' => '귰',
  '��' => '귱',
  '��' => '귲',
  '��' => '귳',
  '��' => '귴',
  '��' => '귵',
  '��' => '귶',
  '��' => '귷',
  '�A' => '귺',
  '�B' => '귻',
  '�C' => '귽',
  '�D' => '귾',
  '�E' => '긂',
  '�F' => '긃',
  '�G' => '긄',
  '�H' => '긅',
  '�I' => '긆',
  '�J' => '긇',
  '�K' => '긊',
  '�L' => '긌',
  '�M' => '긎',
  '�N' => '긏',
  '�O' => '긐',
  '�P' => '긑',
  '�Q' => '긒',
  '�R' => '긓',
  '�S' => '긕',
  '�T' => '긖',
  '�U' => '긗',
  '�V' => '긘',
  '�W' => '긙',
  '�X' => '긚',
  '�Y' => '긛',
  '�Z' => '긜',
  '�a' => '긝',
  '�b' => '긞',
  '�c' => '긟',
  '�d' => '긠',
  '�e' => '긡',
  '�f' => '긢',
  '�g' => '긣',
  '�h' => '긤',
  '�i' => '긥',
  '�j' => '긦',
  '�k' => '긧',
  '�l' => '긨',
  '�m' => '긩',
  '�n' => '긪',
  '�o' => '긫',
  '�p' => '긬',
  '�q' => '긭',
  '�r' => '긮',
  '�s' => '긯',
  '�t' => '긲',
  '�u' => '긳',
  '�v' => '긵',
  '�w' => '긶',
  '�x' => '긹',
  '�y' => '긻',
  '�z' => '긼',
  '��' => '긽',
  '��' => '긾',
  '��' => '긿',
  '��' => '깂',
  '��' => '깄',
  '��' => '깇',
  '��' => '깈',
  '��' => '깉',
  '��' => '깋',
  '��' => '깏',
  '��' => '깑',
  '��' => '깒',
  '��' => '깓',
  '��' => '깕',
  '��' => '깗',
  '��' => '깘',
  '��' => '깙',
  '��' => '깚',
  '��' => '깛',
  '��' => '깞',
  '��' => '깢',
  '��' => '깣',
  '��' => '깤',
  '��' => '깦',
  '��' => '깧',
  '��' => '깪',
  '��' => '깫',
  '��' => '깭',
  '��' => '깮',
  '��' => '깯',
  '��' => '깱',
  '��' => '깲',
  '��' => '깳',
  '��' => '깴',
  '��' => '깵',
  '��' => '깶',
  '��' => '깷',
  '��' => '깺',
  '��' => '깾',
  '��' => '깿',
  '��' => '꺀',
  '��' => '꺁',
  '��' => '꺂',
  '��' => '꺃',
  '��' => '꺆',
  '��' => '꺇',
  '��' => '꺈',
  '��' => '꺉',
  '��' => '꺊',
  '��' => '꺋',
  '��' => '꺍',
  '��' => '꺎',
  '��' => '꺏',
  '��' => '꺐',
  '��' => '꺑',
  '��' => '꺒',
  '��' => '꺓',
  '��' => '꺔',
  '��' => '꺕',
  '��' => '꺖',
  '��' => '꺗',
  '��' => '꺘',
  '��' => '꺙',
  '��' => '꺚',
  '��' => '꺛',
  '��' => '꺜',
  '��' => '꺝',
  '��' => '꺞',
  '��' => '꺟',
  '��' => '꺠',
  '��' => '꺡',
  '��' => '꺢',
  '��' => '꺣',
  '��' => '꺤',
  '��' => '꺥',
  '��' => '꺦',
  '��' => '꺧',
  '��' => '꺨',
  '��' => '꺩',
  '��' => '꺪',
  '��' => '꺫',
  '��' => '꺬',
  '��' => '꺭',
  '��' => '꺮',
  '��' => '꺯',
  '��' => '꺰',
  '��' => '꺱',
  '��' => '꺲',
  '��' => '꺳',
  '��' => '꺴',
  '��' => '꺵',
  '��' => '꺶',
  '��' => '꺷',
  '��' => '꺸',
  '��' => '꺹',
  '��' => '꺺',
  '��' => '꺻',
  '��' => '꺿',
  '��' => '껁',
  '��' => '껂',
  '��' => '껃',
  '��' => '껅',
  '��' => '껆',
  '��' => '껇',
  '��' => '껈',
  '��' => '껉',
  '��' => '껊',
  '��' => '껋',
  '��' => '껎',
  '��' => '껒',
  '��' => '껓',
  '��' => '껔',
  '��' => '껕',
  '��' => '껖',
  '��' => '껗',
  '��' => '껚',
  '��' => '껛',
  '��' => '껝',
  '��' => '껞',
  '��' => '껟',
  '��' => '껠',
  '��' => '껡',
  '��' => '껢',
  '��' => '껣',
  '��' => '껤',
  '��' => '껥',
  '�A' => '껦',
  '�B' => '껧',
  '�C' => '껩',
  '�D' => '껪',
  '�E' => '껬',
  '�F' => '껮',
  '�G' => '껯',
  '�H' => '껰',
  '�I' => '껱',
  '�J' => '껲',
  '�K' => '껳',
  '�L' => '껵',
  '�M' => '껶',
  '�N' => '껷',
  '�O' => '껹',
  '�P' => '껺',
  '�Q' => '껻',
  '�R' => '껽',
  '�S' => '껾',
  '�T' => '껿',
  '�U' => '꼀',
  '�V' => '꼁',
  '�W' => '꼂',
  '�X' => '꼃',
  '�Y' => '꼄',
  '�Z' => '꼅',
  '�a' => '꼆',
  '�b' => '꼉',
  '�c' => '꼊',
  '�d' => '꼋',
  '�e' => '꼌',
  '�f' => '꼎',
  '�g' => '꼏',
  '�h' => '꼑',
  '�i' => '꼒',
  '�j' => '꼓',
  '�k' => '꼔',
  '�l' => '꼕',
  '�m' => '꼖',
  '�n' => '꼗',
  '�o' => '꼘',
  '�p' => '꼙',
  '�q' => '꼚',
  '�r' => '꼛',
  '�s' => '꼜',
  '�t' => '꼝',
  '�u' => '꼞',
  '�v' => '꼟',
  '�w' => '꼠',
  '�x' => '꼡',
  '�y' => '꼢',
  '�z' => '꼣',
  '��' => '꼤',
  '��' => '꼥',
  '��' => '꼦',
  '��' => '꼧',
  '��' => '꼨',
  '��' => '꼩',
  '��' => '꼪',
  '��' => '꼫',
  '��' => '꼮',
  '��' => '꼯',
  '��' => '꼱',
  '��' => '꼳',
  '��' => '꼵',
  '��' => '꼶',
  '��' => '꼷',
  '��' => '꼸',
  '��' => '꼹',
  '��' => '꼺',
  '��' => '꼻',
  '��' => '꼾',
  '��' => '꽀',
  '��' => '꽄',
  '��' => '꽅',
  '��' => '꽆',
  '��' => '꽇',
  '��' => '꽊',
  '��' => '꽋',
  '��' => '꽌',
  '��' => '꽍',
  '��' => '꽎',
  '��' => '꽏',
  '��' => '꽑',
  '��' => '꽒',
  '��' => '꽓',
  '��' => '꽔',
  '��' => '꽕',
  '��' => '꽖',
  '��' => '꽗',
  '��' => '꽘',
  '��' => '꽙',
  '��' => '꽚',
  '��' => '꽛',
  '��' => '꽞',
  '��' => '꽟',
  '��' => '꽠',
  '��' => '꽡',
  '��' => '꽢',
  '��' => '꽣',
  '��' => '꽦',
  '��' => '꽧',
  '��' => '꽨',
  '��' => '꽩',
  '��' => '꽪',
  '��' => '꽫',
  '��' => '꽬',
  '��' => '꽭',
  '��' => '꽮',
  '��' => '꽯',
  '��' => '꽰',
  '��' => '꽱',
  '��' => '꽲',
  '��' => '꽳',
  '��' => '꽴',
  '��' => '꽵',
  '��' => '꽶',
  '��' => '꽷',
  '��' => '꽸',
  '��' => '꽺',
  '��' => '꽻',
  '��' => '꽼',
  '��' => '꽽',
  '��' => '꽾',
  '��' => '꽿',
  '��' => '꾁',
  '��' => '꾂',
  '��' => '꾃',
  '��' => '꾅',
  '��' => '꾆',
  '��' => '꾇',
  '��' => '꾉',
  '��' => '꾊',
  '��' => '꾋',
  '��' => '꾌',
  '��' => '꾍',
  '��' => '꾎',
  '��' => '꾏',
  '��' => '꾒',
  '��' => '꾓',
  '��' => '꾔',
  '��' => '꾖',
  '��' => '꾗',
  '��' => '꾘',
  '��' => '꾙',
  '��' => '꾚',
  '��' => '꾛',
  '��' => '꾝',
  '��' => '꾞',
  '��' => '꾟',
  '��' => '꾠',
  '��' => '꾡',
  '��' => '꾢',
  '��' => '꾣',
  '��' => '꾤',
  '��' => '꾥',
  '��' => '꾦',
  '��' => '꾧',
  '��' => '꾨',
  '��' => '꾩',
  '��' => '꾪',
  '��' => '꾫',
  '��' => '꾬',
  '��' => '꾭',
  '��' => '꾮',
  '��' => '꾯',
  '��' => '꾰',
  '��' => '꾱',
  '��' => '꾲',
  '��' => '꾳',
  '��' => '꾴',
  '��' => '꾵',
  '��' => '꾶',
  '��' => '꾷',
  '��' => '꾺',
  '��' => '꾻',
  '��' => '꾽',
  '��' => '꾾',
  '�A' => '꾿',
  '�B' => '꿁',
  '�C' => '꿂',
  '�D' => '꿃',
  '�E' => '꿄',
  '�F' => '꿅',
  '�G' => '꿆',
  '�H' => '꿊',
  '�I' => '꿌',
  '�J' => '꿏',
  '�K' => '꿐',
  '�L' => '꿑',
  '�M' => '꿒',
  '�N' => '꿓',
  '�O' => '꿕',
  '�P' => '꿖',
  '�Q' => '꿗',
  '�R' => '꿘',
  '�S' => '꿙',
  '�T' => '꿚',
  '�U' => '꿛',
  '�V' => '꿝',
  '�W' => '꿞',
  '�X' => '꿟',
  '�Y' => '꿠',
  '�Z' => '꿡',
  '�a' => '꿢',
  '�b' => '꿣',
  '�c' => '꿤',
  '�d' => '꿥',
  '�e' => '꿦',
  '�f' => '꿧',
  '�g' => '꿪',
  '�h' => '꿫',
  '�i' => '꿬',
  '�j' => '꿭',
  '�k' => '꿮',
  '�l' => '꿯',
  '�m' => '꿲',
  '�n' => '꿳',
  '�o' => '꿵',
  '�p' => '꿶',
  '�q' => '꿷',
  '�r' => '꿹',
  '�s' => '꿺',
  '�t' => '꿻',
  '�u' => '꿼',
  '�v' => '꿽',
  '�w' => '꿾',
  '�x' => '꿿',
  '�y' => '뀂',
  '�z' => '뀃',
  '��' => '뀅',
  '��' => '뀆',
  '��' => '뀇',
  '��' => '뀈',
  '��' => '뀉',
  '��' => '뀊',
  '��' => '뀋',
  '��' => '뀍',
  '��' => '뀎',
  '��' => '뀏',
  '��' => '뀑',
  '��' => '뀒',
  '��' => '뀓',
  '��' => '뀕',
  '��' => '뀖',
  '��' => '뀗',
  '��' => '뀘',
  '��' => '뀙',
  '��' => '뀚',
  '��' => '뀛',
  '��' => '뀞',
  '��' => '뀟',
  '��' => '뀠',
  '��' => '뀡',
  '��' => '뀢',
  '��' => '뀣',
  '��' => '뀤',
  '��' => '뀥',
  '��' => '뀦',
  '��' => '뀧',
  '��' => '뀩',
  '��' => '뀪',
  '��' => '뀫',
  '��' => '뀬',
  '��' => '뀭',
  '��' => '뀮',
  '��' => '뀯',
  '��' => '뀰',
  '��' => '뀱',
  '��' => '뀲',
  '��' => '뀳',
  '��' => '뀴',
  '��' => '뀵',
  '��' => '뀶',
  '��' => '뀷',
  '��' => '뀸',
  '��' => '뀹',
  '��' => '뀺',
  '��' => '뀻',
  '��' => '뀼',
  '��' => '뀽',
  '��' => '뀾',
  '��' => '뀿',
  '��' => '끀',
  '��' => '끁',
  '��' => '끂',
  '��' => '끃',
  '��' => '끆',
  '��' => '끇',
  '��' => '끉',
  '��' => '끋',
  '��' => '끍',
  '��' => '끏',
  '��' => '끐',
  '��' => '끑',
  '��' => '끒',
  '��' => '끖',
  '��' => '끘',
  '��' => '끚',
  '��' => '끛',
  '��' => '끜',
  '��' => '끞',
  '��' => '끟',
  '��' => '끠',
  '��' => '끡',
  '��' => '끢',
  '��' => '끣',
  '��' => '끤',
  '��' => '끥',
  '��' => '끦',
  '��' => '끧',
  '��' => '끨',
  '��' => '끩',
  '��' => '끪',
  '��' => '끫',
  '��' => '끬',
  '��' => '끭',
  '��' => '끮',
  '��' => '끯',
  '��' => '끰',
  '��' => '끱',
  '��' => '끲',
  '��' => '끳',
  '��' => '끴',
  '��' => '끵',
  '��' => '끶',
  '��' => '끷',
  '��' => '끸',
  '��' => '끹',
  '��' => '끺',
  '��' => '끻',
  '��' => '끾',
  '��' => '끿',
  '��' => '낁',
  '��' => '낂',
  '��' => '낃',
  '��' => '낅',
  '��' => '낆',
  '��' => '낇',
  '��' => '낈',
  '��' => '낉',
  '��' => '낊',
  '��' => '낋',
  '��' => '낎',
  '��' => '낐',
  '��' => '낒',
  '��' => '낓',
  '��' => '낔',
  '��' => '낕',
  '��' => '낖',
  '��' => '낗',
  '��' => '낛',
  '��' => '낝',
  '��' => '낞',
  '��' => '낣',
  '��' => '낤',
  '�A' => '낥',
  '�B' => '낦',
  '�C' => '낧',
  '�D' => '낪',
  '�E' => '낰',
  '�F' => '낲',
  '�G' => '낶',
  '�H' => '낷',
  '�I' => '낹',
  '�J' => '낺',
  '�K' => '낻',
  '�L' => '낽',
  '�M' => '낾',
  '�N' => '낿',
  '�O' => '냀',
  '�P' => '냁',
  '�Q' => '냂',
  '�R' => '냃',
  '�S' => '냆',
  '�T' => '냊',
  '�U' => '냋',
  '�V' => '냌',
  '�W' => '냍',
  '�X' => '냎',
  '�Y' => '냏',
  '�Z' => '냒',
  '�a' => '냓',
  '�b' => '냕',
  '�c' => '냖',
  '�d' => '냗',
  '�e' => '냙',
  '�f' => '냚',
  '�g' => '냛',
  '�h' => '냜',
  '�i' => '냝',
  '�j' => '냞',
  '�k' => '냟',
  '�l' => '냡',
  '�m' => '냢',
  '�n' => '냣',
  '�o' => '냤',
  '�p' => '냦',
  '�q' => '냧',
  '�r' => '냨',
  '�s' => '냩',
  '�t' => '냪',
  '�u' => '냫',
  '�v' => '냬',
  '�w' => '냭',
  '�x' => '냮',
  '�y' => '냯',
  '�z' => '냰',
  '��' => '냱',
  '��' => '냲',
  '��' => '냳',
  '��' => '냴',
  '��' => '냵',
  '��' => '냶',
  '��' => '냷',
  '��' => '냸',
  '��' => '냹',
  '��' => '냺',
  '��' => '냻',
  '��' => '냼',
  '��' => '냽',
  '��' => '냾',
  '��' => '냿',
  '��' => '넀',
  '��' => '넁',
  '��' => '넂',
  '��' => '넃',
  '��' => '넄',
  '��' => '넅',
  '��' => '넆',
  '��' => '넇',
  '��' => '넊',
  '��' => '넍',
  '��' => '넎',
  '��' => '넏',
  '��' => '넑',
  '��' => '넔',
  '��' => '넕',
  '��' => '넖',
  '��' => '넗',
  '��' => '넚',
  '��' => '넞',
  '��' => '넟',
  '��' => '넠',
  '��' => '넡',
  '��' => '넢',
  '��' => '넦',
  '��' => '넧',
  '��' => '넩',
  '��' => '넪',
  '��' => '넫',
  '��' => '넭',
  '��' => '넮',
  '��' => '넯',
  '��' => '넰',
  '��' => '넱',
  '��' => '넲',
  '��' => '넳',
  '��' => '넶',
  '��' => '넺',
  '��' => '넻',
  '��' => '넼',
  '��' => '넽',
  '��' => '넾',
  '��' => '넿',
  '��' => '녂',
  '��' => '녃',
  '��' => '녅',
  '��' => '녆',
  '��' => '녇',
  '��' => '녉',
  '��' => '녊',
  '��' => '녋',
  '��' => '녌',
  '��' => '녍',
  '��' => '녎',
  '��' => '녏',
  '��' => '녒',
  '��' => '녓',
  '��' => '녖',
  '��' => '녗',
  '��' => '녙',
  '��' => '녚',
  '��' => '녛',
  '��' => '녝',
  '��' => '녞',
  '��' => '녟',
  '��' => '녡',
  '��' => '녢',
  '��' => '녣',
  '��' => '녤',
  '��' => '녥',
  '��' => '녦',
  '��' => '녧',
  '��' => '녨',
  '��' => '녩',
  '��' => '녪',
  '��' => '녫',
  '��' => '녬',
  '��' => '녭',
  '��' => '녮',
  '��' => '녯',
  '��' => '녰',
  '��' => '녱',
  '��' => '녲',
  '��' => '녳',
  '��' => '녴',
  '��' => '녵',
  '��' => '녶',
  '��' => '녷',
  '��' => '녺',
  '��' => '녻',
  '��' => '녽',
  '��' => '녾',
  '��' => '녿',
  '��' => '놁',
  '��' => '놃',
  '��' => '놄',
  '��' => '놅',
  '��' => '놆',
  '��' => '놇',
  '��' => '놊',
  '��' => '놌',
  '��' => '놎',
  '��' => '놏',
  '��' => '놐',
  '��' => '놑',
  '��' => '놕',
  '��' => '놖',
  '��' => '놗',
  '��' => '놙',
  '��' => '놚',
  '��' => '놛',
  '��' => '놝',
  '�A' => '놞',
  '�B' => '놟',
  '�C' => '놠',
  '�D' => '놡',
  '�E' => '놢',
  '�F' => '놣',
  '�G' => '놤',
  '�H' => '놥',
  '�I' => '놦',
  '�J' => '놧',
  '�K' => '놩',
  '�L' => '놪',
  '�M' => '놫',
  '�N' => '놬',
  '�O' => '놭',
  '�P' => '놮',
  '�Q' => '놯',
  '�R' => '놰',
  '�S' => '놱',
  '�T' => '놲',
  '�U' => '놳',
  '�V' => '놴',
  '�W' => '놵',
  '�X' => '놶',
  '�Y' => '놷',
  '�Z' => '놸',
  '�a' => '놹',
  '�b' => '놺',
  '�c' => '놻',
  '�d' => '놼',
  '�e' => '놽',
  '�f' => '놾',
  '�g' => '놿',
  '�h' => '뇀',
  '�i' => '뇁',
  '�j' => '뇂',
  '�k' => '뇃',
  '�l' => '뇄',
  '�m' => '뇅',
  '�n' => '뇆',
  '�o' => '뇇',
  '�p' => '뇈',
  '�q' => '뇉',
  '�r' => '뇊',
  '�s' => '뇋',
  '�t' => '뇍',
  '�u' => '뇎',
  '�v' => '뇏',
  '�w' => '뇑',
  '�x' => '뇒',
  '�y' => '뇓',
  '�z' => '뇕',
  '��' => '뇖',
  '��' => '뇗',
  '��' => '뇘',
  '��' => '뇙',
  '��' => '뇚',
  '��' => '뇛',
  '��' => '뇞',
  '��' => '뇠',
  '��' => '뇡',
  '��' => '뇢',
  '��' => '뇣',
  '��' => '뇤',
  '��' => '뇥',
  '��' => '뇦',
  '��' => '뇧',
  '��' => '뇪',
  '��' => '뇫',
  '��' => '뇭',
  '��' => '뇮',
  '��' => '뇯',
  '��' => '뇱',
  '��' => '뇲',
  '��' => '뇳',
  '��' => '뇴',
  '��' => '뇵',
  '��' => '뇶',
  '��' => '뇷',
  '��' => '뇸',
  '��' => '뇺',
  '��' => '뇼',
  '��' => '뇾',
  '��' => '뇿',
  '��' => '눀',
  '��' => '눁',
  '��' => '눂',
  '��' => '눃',
  '��' => '눆',
  '��' => '눇',
  '��' => '눉',
  '��' => '눊',
  '��' => '눍',
  '��' => '눎',
  '��' => '눏',
  '��' => '눐',
  '��' => '눑',
  '��' => '눒',
  '��' => '눓',
  '��' => '눖',
  '��' => '눘',
  '��' => '눚',
  '��' => '눛',
  '��' => '눜',
  '��' => '눝',
  '��' => '눞',
  '��' => '눟',
  '��' => '눡',
  '��' => '눢',
  '��' => '눣',
  '��' => '눤',
  '��' => '눥',
  '��' => '눦',
  '��' => '눧',
  '��' => '눨',
  '��' => '눩',
  '��' => '눪',
  '��' => '눫',
  '��' => '눬',
  '��' => '눭',
  '��' => '눮',
  '��' => '눯',
  '��' => '눰',
  '��' => '눱',
  '��' => '눲',
  '��' => '눳',
  '��' => '눵',
  '��' => '눶',
  '��' => '눷',
  '��' => '눸',
  '��' => '눹',
  '��' => '눺',
  '��' => '눻',
  '��' => '눽',
  '��' => '눾',
  '��' => '눿',
  '��' => '뉀',
  '��' => '뉁',
  '��' => '뉂',
  '��' => '뉃',
  '��' => '뉄',
  '��' => '뉅',
  '��' => '뉆',
  '��' => '뉇',
  '��' => '뉈',
  '��' => '뉉',
  '��' => '뉊',
  '��' => '뉋',
  '��' => '뉌',
  '��' => '뉍',
  '��' => '뉎',
  '��' => '뉏',
  '��' => '뉐',
  '��' => '뉑',
  '��' => '뉒',
  '��' => '뉓',
  '��' => '뉔',
  '��' => '뉕',
  '��' => '뉖',
  '��' => '뉗',
  '��' => '뉙',
  '��' => '뉚',
  '��' => '뉛',
  '��' => '뉝',
  '��' => '뉞',
  '��' => '뉟',
  '��' => '뉡',
  '��' => '뉢',
  '��' => '뉣',
  '��' => '뉤',
  '��' => '뉥',
  '��' => '뉦',
  '��' => '뉧',
  '��' => '뉪',
  '��' => '뉫',
  '��' => '뉬',
  '��' => '뉭',
  '��' => '뉮',
  '�A' => '뉯',
  '�B' => '뉰',
  '�C' => '뉱',
  '�D' => '뉲',
  '�E' => '뉳',
  '�F' => '뉶',
  '�G' => '뉷',
  '�H' => '뉸',
  '�I' => '뉹',
  '�J' => '뉺',
  '�K' => '뉻',
  '�L' => '뉽',
  '�M' => '뉾',
  '�N' => '뉿',
  '�O' => '늀',
  '�P' => '늁',
  '�Q' => '늂',
  '�R' => '늃',
  '�S' => '늆',
  '�T' => '늇',
  '�U' => '늈',
  '�V' => '늊',
  '�W' => '늋',
  '�X' => '늌',
  '�Y' => '늍',
  '�Z' => '늎',
  '�a' => '늏',
  '�b' => '늒',
  '�c' => '늓',
  '�d' => '늕',
  '�e' => '늖',
  '�f' => '늗',
  '�g' => '늛',
  '�h' => '늜',
  '�i' => '늝',
  '�j' => '늞',
  '�k' => '늟',
  '�l' => '늢',
  '�m' => '늤',
  '�n' => '늧',
  '�o' => '늨',
  '�p' => '늩',
  '�q' => '늫',
  '�r' => '늭',
  '�s' => '늮',
  '�t' => '늯',
  '�u' => '늱',
  '�v' => '늲',
  '�w' => '늳',
  '�x' => '늵',
  '�y' => '늶',
  '�z' => '늷',
  '��' => '늸',
  '��' => '늹',
  '��' => '늺',
  '��' => '늻',
  '��' => '늼',
  '��' => '늽',
  '��' => '늾',
  '��' => '늿',
  '��' => '닀',
  '��' => '닁',
  '��' => '닂',
  '��' => '닃',
  '��' => '닄',
  '��' => '닅',
  '��' => '닆',
  '��' => '닇',
  '��' => '닊',
  '��' => '닋',
  '��' => '닍',
  '��' => '닎',
  '��' => '닏',
  '��' => '닑',
  '��' => '닓',
  '��' => '닔',
  '��' => '닕',
  '��' => '닖',
  '��' => '닗',
  '��' => '닚',
  '��' => '닜',
  '��' => '닞',
  '��' => '닟',
  '��' => '닠',
  '��' => '닡',
  '��' => '닣',
  '��' => '닧',
  '��' => '닩',
  '��' => '닪',
  '��' => '닰',
  '��' => '닱',
  '��' => '닲',
  '��' => '닶',
  '��' => '닼',
  '��' => '닽',
  '��' => '닾',
  '��' => '댂',
  '��' => '댃',
  '��' => '댅',
  '��' => '댆',
  '��' => '댇',
  '��' => '댉',
  '��' => '댊',
  '��' => '댋',
  '��' => '댌',
  '��' => '댍',
  '��' => '댎',
  '��' => '댏',
  '��' => '댒',
  '��' => '댖',
  '��' => '댗',
  '��' => '댘',
  '��' => '댙',
  '��' => '댚',
  '��' => '댛',
  '��' => '댝',
  '��' => '댞',
  '��' => '댟',
  '��' => '댠',
  '��' => '댡',
  '��' => '댢',
  '��' => '댣',
  '��' => '댤',
  '��' => '댥',
  '��' => '댦',
  '��' => '댧',
  '��' => '댨',
  '��' => '댩',
  '��' => '댪',
  '��' => '댫',
  '��' => '댬',
  '��' => '댭',
  '��' => '댮',
  '��' => '댯',
  '��' => '댰',
  '��' => '댱',
  '��' => '댲',
  '��' => '댳',
  '��' => '댴',
  '��' => '댵',
  '��' => '댶',
  '��' => '댷',
  '��' => '댸',
  '��' => '댹',
  '��' => '댺',
  '��' => '댻',
  '��' => '댼',
  '��' => '댽',
  '��' => '댾',
  '��' => '댿',
  '��' => '덀',
  '��' => '덁',
  '��' => '덂',
  '��' => '덃',
  '��' => '덄',
  '��' => '덅',
  '��' => '덆',
  '��' => '덇',
  '��' => '덈',
  '��' => '덉',
  '��' => '덊',
  '��' => '덋',
  '��' => '덌',
  '��' => '덍',
  '��' => '덎',
  '��' => '덏',
  '��' => '덐',
  '��' => '덑',
  '��' => '덒',
  '��' => '덓',
  '��' => '덗',
  '��' => '덙',
  '��' => '덚',
  '��' => '덝',
  '��' => '덠',
  '��' => '덡',
  '��' => '덢',
  '��' => '덣',
  '�A' => '덦',
  '�B' => '덨',
  '�C' => '덪',
  '�D' => '덬',
  '�E' => '덭',
  '�F' => '덯',
  '�G' => '덲',
  '�H' => '덳',
  '�I' => '덵',
  '�J' => '덶',
  '�K' => '덷',
  '�L' => '덹',
  '�M' => '덺',
  '�N' => '덻',
  '�O' => '덼',
  '�P' => '덽',
  '�Q' => '덾',
  '�R' => '덿',
  '�S' => '뎂',
  '�T' => '뎆',
  '�U' => '뎇',
  '�V' => '뎈',
  '�W' => '뎉',
  '�X' => '뎊',
  '�Y' => '뎋',
  '�Z' => '뎍',
  '�a' => '뎎',
  '�b' => '뎏',
  '�c' => '뎑',
  '�d' => '뎒',
  '�e' => '뎓',
  '�f' => '뎕',
  '�g' => '뎖',
  '�h' => '뎗',
  '�i' => '뎘',
  '�j' => '뎙',
  '�k' => '뎚',
  '�l' => '뎛',
  '�m' => '뎜',
  '�n' => '뎝',
  '�o' => '뎞',
  '�p' => '뎟',
  '�q' => '뎢',
  '�r' => '뎣',
  '�s' => '뎤',
  '�t' => '뎥',
  '�u' => '뎦',
  '�v' => '뎧',
  '�w' => '뎩',
  '�x' => '뎪',
  '�y' => '뎫',
  '�z' => '뎭',
  '��' => '뎮',
  '��' => '뎯',
  '��' => '뎰',
  '��' => '뎱',
  '��' => '뎲',
  '��' => '뎳',
  '��' => '뎴',
  '��' => '뎵',
  '��' => '뎶',
  '��' => '뎷',
  '��' => '뎸',
  '��' => '뎹',
  '��' => '뎺',
  '��' => '뎻',
  '��' => '뎼',
  '��' => '뎽',
  '��' => '뎾',
  '��' => '뎿',
  '��' => '돀',
  '��' => '돁',
  '��' => '돂',
  '��' => '돃',
  '��' => '돆',
  '��' => '돇',
  '��' => '돉',
  '��' => '돊',
  '��' => '돍',
  '��' => '돏',
  '��' => '돑',
  '��' => '돒',
  '��' => '돓',
  '��' => '돖',
  '��' => '돘',
  '��' => '돚',
  '��' => '돜',
  '��' => '돞',
  '��' => '돟',
  '��' => '돡',
  '��' => '돢',
  '��' => '돣',
  '��' => '돥',
  '��' => '돦',
  '��' => '돧',
  '��' => '돩',
  '��' => '돪',
  '��' => '돫',
  '��' => '돬',
  '��' => '돭',
  '��' => '돮',
  '��' => '돯',
  '��' => '돰',
  '��' => '돱',
  '��' => '돲',
  '��' => '돳',
  '��' => '돴',
  '��' => '돵',
  '��' => '돶',
  '��' => '돷',
  '��' => '돸',
  '��' => '돹',
  '��' => '돺',
  '��' => '돻',
  '��' => '돽',
  '��' => '돾',
  '��' => '돿',
  '��' => '됀',
  '��' => '됁',
  '��' => '됂',
  '��' => '됃',
  '��' => '됄',
  '��' => '됅',
  '��' => '됆',
  '��' => '됇',
  '��' => '됈',
  '��' => '됉',
  '��' => '됊',
  '��' => '됋',
  '��' => '됌',
  '��' => '됍',
  '��' => '됎',
  '��' => '됏',
  '��' => '됑',
  '��' => '됒',
  '��' => '됓',
  '��' => '됔',
  '��' => '됕',
  '��' => '됖',
  '��' => '됗',
  '��' => '됙',
  '��' => '됚',
  '��' => '됛',
  '��' => '됝',
  '��' => '됞',
  '��' => '됟',
  '��' => '됡',
  '��' => '됢',
  '��' => '됣',
  '��' => '됤',
  '��' => '됥',
  '��' => '됦',
  '��' => '됧',
  '��' => '됪',
  '��' => '됬',
  '��' => '됭',
  '��' => '됮',
  '��' => '됯',
  '��' => '됰',
  '��' => '됱',
  '��' => '됲',
  '��' => '됳',
  '��' => '됵',
  '��' => '됶',
  '��' => '됷',
  '��' => '됸',
  '��' => '됹',
  '��' => '됺',
  '��' => '됻',
  '��' => '됼',
  '��' => '됽',
  '��' => '됾',
  '��' => '됿',
  '��' => '둀',
  '��' => '둁',
  '��' => '둂',
  '��' => '둃',
  '��' => '둄',
  '�A' => '둅',
  '�B' => '둆',
  '�C' => '둇',
  '�D' => '둈',
  '�E' => '둉',
  '�F' => '둊',
  '�G' => '둋',
  '�H' => '둌',
  '�I' => '둍',
  '�J' => '둎',
  '�K' => '둏',
  '�L' => '둒',
  '�M' => '둓',
  '�N' => '둕',
  '�O' => '둖',
  '�P' => '둗',
  '�Q' => '둙',
  '�R' => '둚',
  '�S' => '둛',
  '�T' => '둜',
  '�U' => '둝',
  '�V' => '둞',
  '�W' => '둟',
  '�X' => '둢',
  '�Y' => '둤',
  '�Z' => '둦',
  '�a' => '둧',
  '�b' => '둨',
  '�c' => '둩',
  '�d' => '둪',
  '�e' => '둫',
  '�f' => '둭',
  '�g' => '둮',
  '�h' => '둯',
  '�i' => '둰',
  '�j' => '둱',
  '�k' => '둲',
  '�l' => '둳',
  '�m' => '둴',
  '�n' => '둵',
  '�o' => '둶',
  '�p' => '둷',
  '�q' => '둸',
  '�r' => '둹',
  '�s' => '둺',
  '�t' => '둻',
  '�u' => '둼',
  '�v' => '둽',
  '�w' => '둾',
  '�x' => '둿',
  '�y' => '뒁',
  '�z' => '뒂',
  '��' => '뒃',
  '��' => '뒄',
  '��' => '뒅',
  '��' => '뒆',
  '��' => '뒇',
  '��' => '뒉',
  '��' => '뒊',
  '��' => '뒋',
  '��' => '뒌',
  '��' => '뒍',
  '��' => '뒎',
  '��' => '뒏',
  '��' => '뒐',
  '��' => '뒑',
  '��' => '뒒',
  '��' => '뒓',
  '��' => '뒔',
  '��' => '뒕',
  '��' => '뒖',
  '��' => '뒗',
  '��' => '뒘',
  '��' => '뒙',
  '��' => '뒚',
  '��' => '뒛',
  '��' => '뒜',
  '��' => '뒞',
  '��' => '뒟',
  '��' => '뒠',
  '��' => '뒡',
  '��' => '뒢',
  '��' => '뒣',
  '��' => '뒥',
  '��' => '뒦',
  '��' => '뒧',
  '��' => '뒩',
  '��' => '뒪',
  '��' => '뒫',
  '��' => '뒭',
  '��' => '뒮',
  '��' => '뒯',
  '��' => '뒰',
  '��' => '뒱',
  '��' => '뒲',
  '��' => '뒳',
  '��' => '뒴',
  '��' => '뒶',
  '��' => '뒸',
  '��' => '뒺',
  '��' => '뒻',
  '��' => '뒼',
  '��' => '뒽',
  '��' => '뒾',
  '��' => '뒿',
  '��' => '듁',
  '��' => '듂',
  '��' => '듃',
  '��' => '듅',
  '��' => '듆',
  '��' => '듇',
  '��' => '듉',
  '��' => '듊',
  '��' => '듋',
  '��' => '듌',
  '��' => '듍',
  '��' => '듎',
  '��' => '듏',
  '��' => '듑',
  '��' => '듒',
  '��' => '듓',
  '��' => '듔',
  '��' => '듖',
  '��' => '듗',
  '��' => '듘',
  '��' => '듙',
  '��' => '듚',
  '��' => '듛',
  '��' => '듞',
  '��' => '듟',
  '��' => '듡',
  '��' => '듢',
  '��' => '듥',
  '��' => '듧',
  '��' => '듨',
  '��' => '듩',
  '��' => '듪',
  '��' => '듫',
  '��' => '듮',
  '��' => '듰',
  '��' => '듲',
  '��' => '듳',
  '��' => '듴',
  '��' => '듵',
  '��' => '듶',
  '��' => '듷',
  '��' => '듹',
  '��' => '듺',
  '��' => '듻',
  '��' => '듼',
  '��' => '듽',
  '��' => '듾',
  '��' => '듿',
  '��' => '딀',
  '��' => '딁',
  '��' => '딂',
  '��' => '딃',
  '��' => '딄',
  '��' => '딅',
  '��' => '딆',
  '��' => '딇',
  '��' => '딈',
  '��' => '딉',
  '��' => '딊',
  '��' => '딋',
  '��' => '딌',
  '��' => '딍',
  '��' => '딎',
  '��' => '딏',
  '��' => '딐',
  '��' => '딑',
  '��' => '딒',
  '��' => '딓',
  '��' => '딖',
  '��' => '딗',
  '��' => '딙',
  '��' => '딚',
  '��' => '딝',
  '�A' => '딞',
  '�B' => '딟',
  '�C' => '딠',
  '�D' => '딡',
  '�E' => '딢',
  '�F' => '딣',
  '�G' => '딦',
  '�H' => '딫',
  '�I' => '딬',
  '�J' => '딭',
  '�K' => '딮',
  '�L' => '딯',
  '�M' => '딲',
  '�N' => '딳',
  '�O' => '딵',
  '�P' => '딶',
  '�Q' => '딷',
  '�R' => '딹',
  '�S' => '딺',
  '�T' => '딻',
  '�U' => '딼',
  '�V' => '딽',
  '�W' => '딾',
  '�X' => '딿',
  '�Y' => '땂',
  '�Z' => '땆',
  '�a' => '땇',
  '�b' => '땈',
  '�c' => '땉',
  '�d' => '땊',
  '�e' => '땎',
  '�f' => '땏',
  '�g' => '땑',
  '�h' => '땒',
  '�i' => '땓',
  '�j' => '땕',
  '�k' => '땖',
  '�l' => '땗',
  '�m' => '땘',
  '�n' => '땙',
  '�o' => '땚',
  '�p' => '땛',
  '�q' => '땞',
  '�r' => '땢',
  '�s' => '땣',
  '�t' => '땤',
  '�u' => '땥',
  '�v' => '땦',
  '�w' => '땧',
  '�x' => '땨',
  '�y' => '땩',
  '�z' => '땪',
  '��' => '땫',
  '��' => '땬',
  '��' => '땭',
  '��' => '땮',
  '��' => '땯',
  '��' => '땰',
  '��' => '땱',
  '��' => '땲',
  '��' => '땳',
  '��' => '땴',
  '��' => '땵',
  '��' => '땶',
  '��' => '땷',
  '��' => '땸',
  '��' => '땹',
  '��' => '땺',
  '��' => '땻',
  '��' => '땼',
  '��' => '땽',
  '��' => '땾',
  '��' => '땿',
  '��' => '떀',
  '��' => '떁',
  '��' => '떂',
  '��' => '떃',
  '��' => '떄',
  '��' => '떅',
  '��' => '떆',
  '��' => '떇',
  '��' => '떈',
  '��' => '떉',
  '��' => '떊',
  '��' => '떋',
  '��' => '떌',
  '��' => '떍',
  '��' => '떎',
  '��' => '떏',
  '��' => '떐',
  '��' => '떑',
  '��' => '떒',
  '��' => '떓',
  '��' => '떔',
  '��' => '떕',
  '��' => '떖',
  '��' => '떗',
  '��' => '떘',
  '��' => '떙',
  '��' => '떚',
  '��' => '떛',
  '��' => '떜',
  '��' => '떝',
  '��' => '떞',
  '��' => '떟',
  '��' => '떢',
  '��' => '떣',
  '��' => '떥',
  '��' => '떦',
  '��' => '떧',
  '��' => '떩',
  '��' => '떬',
  '��' => '떭',
  '��' => '떮',
  '��' => '떯',
  '��' => '떲',
  '��' => '떶',
  '��' => '떷',
  '��' => '떸',
  '��' => '떹',
  '��' => '떺',
  '��' => '떾',
  '��' => '떿',
  '��' => '뗁',
  '��' => '뗂',
  '��' => '뗃',
  '��' => '뗅',
  '��' => '뗆',
  '��' => '뗇',
  '��' => '뗈',
  '��' => '뗉',
  '��' => '뗊',
  '��' => '뗋',
  '��' => '뗎',
  '��' => '뗒',
  '��' => '뗓',
  '��' => '뗔',
  '��' => '뗕',
  '��' => '뗖',
  '��' => '뗗',
  '��' => '뗙',
  '��' => '뗚',
  '��' => '뗛',
  '��' => '뗜',
  '��' => '뗝',
  '��' => '뗞',
  '��' => '뗟',
  '��' => '뗠',
  '��' => '뗡',
  '��' => '뗢',
  '��' => '뗣',
  '��' => '뗤',
  '��' => '뗥',
  '��' => '뗦',
  '��' => '뗧',
  '��' => '뗨',
  '��' => '뗩',
  '��' => '뗪',
  '��' => '뗫',
  '��' => '뗭',
  '��' => '뗮',
  '��' => '뗯',
  '��' => '뗰',
  '��' => '뗱',
  '��' => '뗲',
  '��' => '뗳',
  '��' => '뗴',
  '��' => '뗵',
  '��' => '뗶',
  '��' => '뗷',
  '��' => '뗸',
  '��' => '뗹',
  '��' => '뗺',
  '��' => '뗻',
  '��' => '뗼',
  '��' => '뗽',
  '��' => '뗾',
  '��' => '뗿',
  '�A' => '똀',
  '�B' => '똁',
  '�C' => '똂',
  '�D' => '똃',
  '�E' => '똄',
  '�F' => '똅',
  '�G' => '똆',
  '�H' => '똇',
  '�I' => '똈',
  '�J' => '똉',
  '�K' => '똊',
  '�L' => '똋',
  '�M' => '똌',
  '�N' => '똍',
  '�O' => '똎',
  '�P' => '똏',
  '�Q' => '똒',
  '�R' => '똓',
  '�S' => '똕',
  '�T' => '똖',
  '�U' => '똗',
  '�V' => '똙',
  '�W' => '똚',
  '�X' => '똛',
  '�Y' => '똜',
  '�Z' => '똝',
  '�a' => '똞',
  '�b' => '똟',
  '�c' => '똠',
  '�d' => '똡',
  '�e' => '똢',
  '�f' => '똣',
  '�g' => '똤',
  '�h' => '똦',
  '�i' => '똧',
  '�j' => '똨',
  '�k' => '똩',
  '�l' => '똪',
  '�m' => '똫',
  '�n' => '똭',
  '�o' => '똮',
  '�p' => '똯',
  '�q' => '똰',
  '�r' => '똱',
  '�s' => '똲',
  '�t' => '똳',
  '�u' => '똵',
  '�v' => '똶',
  '�w' => '똷',
  '�x' => '똸',
  '�y' => '똹',
  '�z' => '똺',
  '��' => '똻',
  '��' => '똼',
  '��' => '똽',
  '��' => '똾',
  '��' => '똿',
  '��' => '뙀',
  '��' => '뙁',
  '��' => '뙂',
  '��' => '뙃',
  '��' => '뙄',
  '��' => '뙅',
  '��' => '뙆',
  '��' => '뙇',
  '��' => '뙉',
  '��' => '뙊',
  '��' => '뙋',
  '��' => '뙌',
  '��' => '뙍',
  '��' => '뙎',
  '��' => '뙏',
  '��' => '뙐',
  '��' => '뙑',
  '��' => '뙒',
  '��' => '뙓',
  '��' => '뙔',
  '��' => '뙕',
  '��' => '뙖',
  '��' => '뙗',
  '��' => '뙘',
  '��' => '뙙',
  '��' => '뙚',
  '��' => '뙛',
  '��' => '뙜',
  '��' => '뙝',
  '��' => '뙞',
  '��' => '뙟',
  '��' => '뙠',
  '��' => '뙡',
  '��' => '뙢',
  '��' => '뙣',
  '��' => '뙥',
  '��' => '뙦',
  '��' => '뙧',
  '��' => '뙩',
  '��' => '뙪',
  '��' => '뙫',
  '��' => '뙬',
  '��' => '뙭',
  '��' => '뙮',
  '��' => '뙯',
  '��' => '뙰',
  '��' => '뙱',
  '��' => '뙲',
  '��' => '뙳',
  '��' => '뙴',
  '��' => '뙵',
  '��' => '뙶',
  '��' => '뙷',
  '��' => '뙸',
  '��' => '뙹',
  '��' => '뙺',
  '��' => '뙻',
  '��' => '뙼',
  '��' => '뙽',
  '��' => '뙾',
  '��' => '뙿',
  '��' => '뚀',
  '��' => '뚁',
  '��' => '뚂',
  '��' => '뚃',
  '��' => '뚄',
  '��' => '뚅',
  '��' => '뚆',
  '��' => '뚇',
  '��' => '뚈',
  '��' => '뚉',
  '��' => '뚊',
  '��' => '뚋',
  '��' => '뚌',
  '��' => '뚍',
  '��' => '뚎',
  '��' => '뚏',
  '��' => '뚐',
  '��' => '뚑',
  '��' => '뚒',
  '��' => '뚓',
  '��' => '뚔',
  '��' => '뚕',
  '��' => '뚖',
  '��' => '뚗',
  '��' => '뚘',
  '��' => '뚙',
  '��' => '뚚',
  '��' => '뚛',
  '��' => '뚞',
  '��' => '뚟',
  '��' => '뚡',
  '��' => '뚢',
  '��' => '뚣',
  '��' => '뚥',
  '��' => '뚦',
  '��' => '뚧',
  '��' => '뚨',
  '��' => '뚩',
  '��' => '뚪',
  '��' => '뚭',
  '��' => '뚮',
  '��' => '뚯',
  '��' => '뚰',
  '��' => '뚲',
  '��' => '뚳',
  '��' => '뚴',
  '��' => '뚵',
  '��' => '뚶',
  '��' => '뚷',
  '��' => '뚸',
  '��' => '뚹',
  '��' => '뚺',
  '��' => '뚻',
  '��' => '뚼',
  '��' => '뚽',
  '��' => '뚾',
  '��' => '뚿',
  '��' => '뛀',
  '��' => '뛁',
  '��' => '뛂',
  '�A' => '뛃',
  '�B' => '뛄',
  '�C' => '뛅',
  '�D' => '뛆',
  '�E' => '뛇',
  '�F' => '뛈',
  '�G' => '뛉',
  '�H' => '뛊',
  '�I' => '뛋',
  '�J' => '뛌',
  '�K' => '뛍',
  '�L' => '뛎',
  '�M' => '뛏',
  '�N' => '뛐',
  '�O' => '뛑',
  '�P' => '뛒',
  '�Q' => '뛓',
  '�R' => '뛕',
  '�S' => '뛖',
  '�T' => '뛗',
  '�U' => '뛘',
  '�V' => '뛙',
  '�W' => '뛚',
  '�X' => '뛛',
  '�Y' => '뛜',
  '�Z' => '뛝',
  '�a' => '뛞',
  '�b' => '뛟',
  '�c' => '뛠',
  '�d' => '뛡',
  '�e' => '뛢',
  '�f' => '뛣',
  '�g' => '뛤',
  '�h' => '뛥',
  '�i' => '뛦',
  '�j' => '뛧',
  '�k' => '뛨',
  '�l' => '뛩',
  '�m' => '뛪',
  '�n' => '뛫',
  '�o' => '뛬',
  '�p' => '뛭',
  '�q' => '뛮',
  '�r' => '뛯',
  '�s' => '뛱',
  '�t' => '뛲',
  '�u' => '뛳',
  '�v' => '뛵',
  '�w' => '뛶',
  '�x' => '뛷',
  '�y' => '뛹',
  '�z' => '뛺',
  '��' => '뛻',
  '��' => '뛼',
  '��' => '뛽',
  '��' => '뛾',
  '��' => '뛿',
  '��' => '뜂',
  '��' => '뜃',
  '��' => '뜄',
  '��' => '뜆',
  '��' => '뜇',
  '��' => '뜈',
  '��' => '뜉',
  '��' => '뜊',
  '��' => '뜋',
  '��' => '뜌',
  '��' => '뜍',
  '��' => '뜎',
  '��' => '뜏',
  '��' => '뜐',
  '��' => '뜑',
  '��' => '뜒',
  '��' => '뜓',
  '��' => '뜔',
  '��' => '뜕',
  '��' => '뜖',
  '��' => '뜗',
  '��' => '뜘',
  '��' => '뜙',
  '��' => '뜚',
  '��' => '뜛',
  '��' => '뜜',
  '��' => '뜝',
  '��' => '뜞',
  '��' => '뜟',
  '��' => '뜠',
  '��' => '뜡',
  '��' => '뜢',
  '��' => '뜣',
  '��' => '뜤',
  '��' => '뜥',
  '��' => '뜦',
  '��' => '뜧',
  '��' => '뜪',
  '��' => '뜫',
  '��' => '뜭',
  '��' => '뜮',
  '��' => '뜱',
  '��' => '뜲',
  '��' => '뜳',
  '��' => '뜴',
  '��' => '뜵',
  '��' => '뜶',
  '��' => '뜷',
  '��' => '뜺',
  '��' => '뜼',
  '��' => '뜽',
  '��' => '뜾',
  '��' => '뜿',
  '��' => '띀',
  '��' => '띁',
  '��' => '띂',
  '��' => '띃',
  '��' => '띅',
  '��' => '띆',
  '��' => '띇',
  '��' => '띉',
  '��' => '띊',
  '��' => '띋',
  '��' => '띍',
  '��' => '띎',
  '��' => '띏',
  '��' => '띐',
  '��' => '띑',
  '��' => '띒',
  '��' => '띓',
  '��' => '띖',
  '��' => '띗',
  '��' => '띘',
  '��' => '띙',
  '��' => '띚',
  '��' => '띛',
  '��' => '띜',
  '��' => '띝',
  '��' => '띞',
  '��' => '띟',
  '��' => '띡',
  '��' => '띢',
  '��' => '띣',
  '��' => '띥',
  '��' => '띦',
  '��' => '띧',
  '��' => '띩',
  '��' => '띪',
  '��' => '띫',
  '��' => '띬',
  '��' => '띭',
  '��' => '띮',
  '��' => '띯',
  '��' => '띲',
  '��' => '띴',
  '��' => '띶',
  '��' => '띷',
  '��' => '띸',
  '��' => '띹',
  '��' => '띺',
  '��' => '띻',
  '��' => '띾',
  '��' => '띿',
  '��' => '랁',
  '��' => '랂',
  '��' => '랃',
  '��' => '랅',
  '��' => '랆',
  '��' => '랇',
  '��' => '랈',
  '��' => '랉',
  '��' => '랊',
  '��' => '랋',
  '��' => '랎',
  '��' => '랓',
  '��' => '랔',
  '��' => '랕',
  '��' => '랚',
  '��' => '랛',
  '��' => '랝',
  '��' => '랞',
  '�A' => '랟',
  '�B' => '랡',
  '�C' => '랢',
  '�D' => '랣',
  '�E' => '랤',
  '�F' => '랥',
  '�G' => '랦',
  '�H' => '랧',
  '�I' => '랪',
  '�J' => '랮',
  '�K' => '랯',
  '�L' => '랰',
  '�M' => '랱',
  '�N' => '랲',
  '�O' => '랳',
  '�P' => '랶',
  '�Q' => '랷',
  '�R' => '랹',
  '�S' => '랺',
  '�T' => '랻',
  '�U' => '랼',
  '�V' => '랽',
  '�W' => '랾',
  '�X' => '랿',
  '�Y' => '럀',
  '�Z' => '럁',
  '�a' => '럂',
  '�b' => '럃',
  '�c' => '럄',
  '�d' => '럅',
  '�e' => '럆',
  '�f' => '럈',
  '�g' => '럊',
  '�h' => '럋',
  '�i' => '럌',
  '�j' => '럍',
  '�k' => '럎',
  '�l' => '럏',
  '�m' => '럐',
  '�n' => '럑',
  '�o' => '럒',
  '�p' => '럓',
  '�q' => '럔',
  '�r' => '럕',
  '�s' => '럖',
  '�t' => '럗',
  '�u' => '럘',
  '�v' => '럙',
  '�w' => '럚',
  '�x' => '럛',
  '�y' => '럜',
  '�z' => '럝',
  '��' => '럞',
  '��' => '럟',
  '��' => '럠',
  '��' => '럡',
  '��' => '럢',
  '��' => '럣',
  '��' => '럤',
  '��' => '럥',
  '��' => '럦',
  '��' => '럧',
  '��' => '럨',
  '��' => '럩',
  '��' => '럪',
  '��' => '럫',
  '��' => '럮',
  '��' => '럯',
  '��' => '럱',
  '��' => '럲',
  '��' => '럳',
  '��' => '럵',
  '��' => '럶',
  '��' => '럷',
  '��' => '럸',
  '��' => '럹',
  '��' => '럺',
  '��' => '럻',
  '��' => '럾',
  '��' => '렂',
  '��' => '렃',
  '��' => '렄',
  '��' => '렅',
  '��' => '렆',
  '��' => '렊',
  '��' => '렋',
  '��' => '렍',
  '��' => '렎',
  '��' => '렏',
  '��' => '렑',
  '��' => '렒',
  '��' => '렓',
  '��' => '렔',
  '��' => '렕',
  '��' => '렖',
  '��' => '렗',
  '��' => '렚',
  '��' => '렜',
  '��' => '렞',
  '��' => '렟',
  '��' => '렠',
  '��' => '렡',
  '��' => '렢',
  '��' => '렣',
  '��' => '렦',
  '��' => '렧',
  '��' => '렩',
  '��' => '렪',
  '��' => '렫',
  '��' => '렭',
  '��' => '렮',
  '��' => '렯',
  '��' => '렰',
  '��' => '렱',
  '��' => '렲',
  '��' => '렳',
  '��' => '렶',
  '��' => '렺',
  '��' => '렻',
  '��' => '렼',
  '��' => '렽',
  '��' => '렾',
  '��' => '렿',
  '��' => '롁',
  '��' => '롂',
  '��' => '롃',
  '��' => '롅',
  '��' => '롆',
  '��' => '롇',
  '��' => '롈',
  '��' => '롉',
  '��' => '롊',
  '��' => '롋',
  '��' => '롌',
  '��' => '롍',
  '��' => '롎',
  '��' => '롏',
  '��' => '롐',
  '��' => '롒',
  '��' => '롔',
  '��' => '롕',
  '��' => '롖',
  '��' => '롗',
  '��' => '롘',
  '��' => '롙',
  '��' => '롚',
  '��' => '롛',
  '��' => '롞',
  '��' => '롟',
  '��' => '롡',
  '��' => '롢',
  '��' => '롣',
  '��' => '롥',
  '��' => '롦',
  '��' => '롧',
  '��' => '롨',
  '��' => '롩',
  '��' => '롪',
  '��' => '롫',
  '��' => '롮',
  '��' => '롰',
  '��' => '롲',
  '��' => '롳',
  '��' => '롴',
  '��' => '롵',
  '��' => '롶',
  '��' => '롷',
  '��' => '롹',
  '��' => '롺',
  '��' => '롻',
  '��' => '롽',
  '��' => '롾',
  '��' => '롿',
  '��' => '뢀',
  '��' => '뢁',
  '��' => '뢂',
  '��' => '뢃',
  '��' => '뢄',
  '�A' => '뢅',
  '�B' => '뢆',
  '�C' => '뢇',
  '�D' => '뢈',
  '�E' => '뢉',
  '�F' => '뢊',
  '�G' => '뢋',
  '�H' => '뢌',
  '�I' => '뢎',
  '�J' => '뢏',
  '�K' => '뢐',
  '�L' => '뢑',
  '�M' => '뢒',
  '�N' => '뢓',
  '�O' => '뢔',
  '�P' => '뢕',
  '�Q' => '뢖',
  '�R' => '뢗',
  '�S' => '뢘',
  '�T' => '뢙',
  '�U' => '뢚',
  '�V' => '뢛',
  '�W' => '뢜',
  '�X' => '뢝',
  '�Y' => '뢞',
  '�Z' => '뢟',
  '�a' => '뢠',
  '�b' => '뢡',
  '�c' => '뢢',
  '�d' => '뢣',
  '�e' => '뢤',
  '�f' => '뢥',
  '�g' => '뢦',
  '�h' => '뢧',
  '�i' => '뢩',
  '�j' => '뢪',
  '�k' => '뢫',
  '�l' => '뢬',
  '�m' => '뢭',
  '�n' => '뢮',
  '�o' => '뢯',
  '�p' => '뢱',
  '�q' => '뢲',
  '�r' => '뢳',
  '�s' => '뢵',
  '�t' => '뢶',
  '�u' => '뢷',
  '�v' => '뢹',
  '�w' => '뢺',
  '�x' => '뢻',
  '�y' => '뢼',
  '�z' => '뢽',
  '��' => '뢾',
  '��' => '뢿',
  '��' => '룂',
  '��' => '룄',
  '��' => '룆',
  '��' => '룇',
  '��' => '룈',
  '��' => '룉',
  '��' => '룊',
  '��' => '룋',
  '��' => '룍',
  '��' => '룎',
  '��' => '룏',
  '��' => '룑',
  '��' => '룒',
  '��' => '룓',
  '��' => '룕',
  '��' => '룖',
  '��' => '룗',
  '��' => '룘',
  '��' => '룙',
  '��' => '룚',
  '��' => '룛',
  '��' => '룜',
  '��' => '룞',
  '��' => '룠',
  '��' => '룢',
  '��' => '룣',
  '��' => '룤',
  '��' => '룥',
  '��' => '룦',
  '��' => '룧',
  '��' => '룪',
  '��' => '룫',
  '��' => '룭',
  '��' => '룮',
  '��' => '룯',
  '��' => '룱',
  '��' => '룲',
  '��' => '룳',
  '��' => '룴',
  '��' => '룵',
  '��' => '룶',
  '��' => '룷',
  '��' => '룺',
  '��' => '룼',
  '��' => '룾',
  '��' => '룿',
  '��' => '뤀',
  '��' => '뤁',
  '��' => '뤂',
  '��' => '뤃',
  '��' => '뤅',
  '��' => '뤆',
  '��' => '뤇',
  '��' => '뤈',
  '��' => '뤉',
  '��' => '뤊',
  '��' => '뤋',
  '��' => '뤌',
  '��' => '뤍',
  '��' => '뤎',
  '��' => '뤏',
  '��' => '뤐',
  '��' => '뤑',
  '��' => '뤒',
  '��' => '뤓',
  '��' => '뤔',
  '��' => '뤕',
  '��' => '뤖',
  '��' => '뤗',
  '��' => '뤙',
  '��' => '뤚',
  '��' => '뤛',
  '��' => '뤜',
  '��' => '뤝',
  '��' => '뤞',
  '��' => '뤟',
  '��' => '뤡',
  '��' => '뤢',
  '��' => '뤣',
  '��' => '뤤',
  '��' => '뤥',
  '��' => '뤦',
  '��' => '뤧',
  '��' => '뤨',
  '��' => '뤩',
  '��' => '뤪',
  '��' => '뤫',
  '��' => '뤬',
  '��' => '뤭',
  '��' => '뤮',
  '��' => '뤯',
  '��' => '뤰',
  '��' => '뤱',
  '��' => '뤲',
  '��' => '뤳',
  '��' => '뤴',
  '��' => '뤵',
  '��' => '뤶',
  '��' => '뤷',
  '��' => '뤸',
  '��' => '뤹',
  '��' => '뤺',
  '��' => '뤻',
  '��' => '뤾',
  '��' => '뤿',
  '��' => '륁',
  '��' => '륂',
  '��' => '륃',
  '��' => '륅',
  '��' => '륆',
  '��' => '륇',
  '��' => '륈',
  '��' => '륉',
  '��' => '륊',
  '��' => '륋',
  '��' => '륍',
  '��' => '륎',
  '��' => '륐',
  '��' => '륒',
  '��' => '륓',
  '��' => '륔',
  '��' => '륕',
  '��' => '륖',
  '��' => '륗',
  '�A' => '륚',
  '�B' => '륛',
  '�C' => '륝',
  '�D' => '륞',
  '�E' => '륟',
  '�F' => '륡',
  '�G' => '륢',
  '�H' => '륣',
  '�I' => '륤',
  '�J' => '륥',
  '�K' => '륦',
  '�L' => '륧',
  '�M' => '륪',
  '�N' => '륬',
  '�O' => '륮',
  '�P' => '륯',
  '�Q' => '륰',
  '�R' => '륱',
  '�S' => '륲',
  '�T' => '륳',
  '�U' => '륶',
  '�V' => '륷',
  '�W' => '륹',
  '�X' => '륺',
  '�Y' => '륻',
  '�Z' => '륽',
  '�a' => '륾',
  '�b' => '륿',
  '�c' => '릀',
  '�d' => '릁',
  '�e' => '릂',
  '�f' => '릃',
  '�g' => '릆',
  '�h' => '릈',
  '�i' => '릋',
  '�j' => '릌',
  '�k' => '릏',
  '�l' => '릐',
  '�m' => '릑',
  '�n' => '릒',
  '�o' => '릓',
  '�p' => '릔',
  '�q' => '릕',
  '�r' => '릖',
  '�s' => '릗',
  '�t' => '릘',
  '�u' => '릙',
  '�v' => '릚',
  '�w' => '릛',
  '�x' => '릜',
  '�y' => '릝',
  '�z' => '릞',
  '��' => '릟',
  '��' => '릠',
  '��' => '릡',
  '��' => '릢',
  '��' => '릣',
  '��' => '릤',
  '��' => '릥',
  '��' => '릦',
  '��' => '릧',
  '��' => '릨',
  '��' => '릩',
  '��' => '릪',
  '��' => '릫',
  '��' => '릮',
  '��' => '릯',
  '��' => '릱',
  '��' => '릲',
  '��' => '릳',
  '��' => '릵',
  '��' => '릶',
  '��' => '릷',
  '��' => '릸',
  '��' => '릹',
  '��' => '릺',
  '��' => '릻',
  '��' => '릾',
  '��' => '맀',
  '��' => '맂',
  '��' => '맃',
  '��' => '맄',
  '��' => '맅',
  '��' => '맆',
  '��' => '맇',
  '��' => '맊',
  '��' => '맋',
  '��' => '맍',
  '��' => '맓',
  '��' => '맔',
  '��' => '맕',
  '��' => '맖',
  '��' => '맗',
  '��' => '맚',
  '��' => '맜',
  '��' => '맟',
  '��' => '맠',
  '��' => '맢',
  '��' => '맦',
  '��' => '맧',
  '��' => '맩',
  '��' => '맪',
  '��' => '맫',
  '��' => '맭',
  '��' => '맮',
  '��' => '맯',
  '��' => '맰',
  '��' => '맱',
  '��' => '맲',
  '��' => '맳',
  '��' => '맶',
  '��' => '맻',
  '��' => '맼',
  '��' => '맽',
  '��' => '맾',
  '��' => '맿',
  '��' => '먂',
  '��' => '먃',
  '��' => '먄',
  '��' => '먅',
  '��' => '먆',
  '��' => '먇',
  '��' => '먉',
  '��' => '먊',
  '��' => '먋',
  '��' => '먌',
  '��' => '먍',
  '��' => '먎',
  '��' => '먏',
  '��' => '먐',
  '��' => '먑',
  '��' => '먒',
  '��' => '먓',
  '��' => '먔',
  '��' => '먖',
  '��' => '먗',
  '��' => '먘',
  '��' => '먙',
  '��' => '먚',
  '��' => '먛',
  '��' => '먜',
  '��' => '먝',
  '��' => '먞',
  '��' => '먟',
  '��' => '먠',
  '��' => '먡',
  '��' => '먢',
  '��' => '먣',
  '��' => '먤',
  '��' => '먥',
  '��' => '먦',
  '��' => '먧',
  '��' => '먨',
  '��' => '먩',
  '��' => '먪',
  '��' => '먫',
  '��' => '먬',
  '��' => '먭',
  '��' => '먮',
  '��' => '먯',
  '��' => '먰',
  '��' => '먱',
  '��' => '먲',
  '��' => '먳',
  '��' => '먴',
  '��' => '먵',
  '��' => '먶',
  '��' => '먷',
  '��' => '먺',
  '��' => '먻',
  '��' => '먽',
  '��' => '먾',
  '��' => '먿',
  '��' => '멁',
  '��' => '멃',
  '��' => '멄',
  '��' => '멅',
  '��' => '멆',
  '�A' => '멇',
  '�B' => '멊',
  '�C' => '멌',
  '�D' => '멏',
  '�E' => '멐',
  '�F' => '멑',
  '�G' => '멒',
  '�H' => '멖',
  '�I' => '멗',
  '�J' => '멙',
  '�K' => '멚',
  '�L' => '멛',
  '�M' => '멝',
  '�N' => '멞',
  '�O' => '멟',
  '�P' => '멠',
  '�Q' => '멡',
  '�R' => '멢',
  '�S' => '멣',
  '�T' => '멦',
  '�U' => '멪',
  '�V' => '멫',
  '�W' => '멬',
  '�X' => '멭',
  '�Y' => '멮',
  '�Z' => '멯',
  '�a' => '멲',
  '�b' => '멳',
  '�c' => '멵',
  '�d' => '멶',
  '�e' => '멷',
  '�f' => '멹',
  '�g' => '멺',
  '�h' => '멻',
  '�i' => '멼',
  '�j' => '멽',
  '�k' => '멾',
  '�l' => '멿',
  '�m' => '몀',
  '�n' => '몁',
  '�o' => '몂',
  '�p' => '몆',
  '�q' => '몈',
  '�r' => '몉',
  '�s' => '몊',
  '�t' => '몋',
  '�u' => '몍',
  '�v' => '몎',
  '�w' => '몏',
  '�x' => '몐',
  '�y' => '몑',
  '�z' => '몒',
  '��' => '몓',
  '��' => '몔',
  '��' => '몕',
  '��' => '몖',
  '��' => '몗',
  '��' => '몘',
  '��' => '몙',
  '��' => '몚',
  '��' => '몛',
  '��' => '몜',
  '��' => '몝',
  '��' => '몞',
  '��' => '몟',
  '��' => '몠',
  '��' => '몡',
  '��' => '몢',
  '��' => '몣',
  '��' => '몤',
  '��' => '몥',
  '��' => '몦',
  '��' => '몧',
  '��' => '몪',
  '��' => '몭',
  '��' => '몮',
  '��' => '몯',
  '��' => '몱',
  '��' => '몳',
  '��' => '몴',
  '��' => '몵',
  '��' => '몶',
  '��' => '몷',
  '��' => '몺',
  '��' => '몼',
  '��' => '몾',
  '��' => '몿',
  '��' => '뫀',
  '��' => '뫁',
  '��' => '뫂',
  '��' => '뫃',
  '��' => '뫅',
  '��' => '뫆',
  '��' => '뫇',
  '��' => '뫉',
  '��' => '뫊',
  '��' => '뫋',
  '��' => '뫌',
  '��' => '뫍',
  '��' => '뫎',
  '��' => '뫏',
  '��' => '뫐',
  '��' => '뫑',
  '��' => '뫒',
  '��' => '뫓',
  '��' => '뫔',
  '��' => '뫕',
  '��' => '뫖',
  '��' => '뫗',
  '��' => '뫚',
  '��' => '뫛',
  '��' => '뫜',
  '��' => '뫝',
  '��' => '뫞',
  '��' => '뫟',
  '��' => '뫠',
  '��' => '뫡',
  '��' => '뫢',
  '��' => '뫣',
  '��' => '뫤',
  '��' => '뫥',
  '��' => '뫦',
  '��' => '뫧',
  '��' => '뫨',
  '��' => '뫩',
  '��' => '뫪',
  '��' => '뫫',
  '��' => '뫬',
  '��' => '뫭',
  '��' => '뫮',
  '��' => '뫯',
  '��' => '뫰',
  '��' => '뫱',
  '��' => '뫲',
  '��' => '뫳',
  '��' => '뫴',
  '��' => '뫵',
  '��' => '뫶',
  '��' => '뫷',
  '��' => '뫸',
  '��' => '뫹',
  '��' => '뫺',
  '��' => '뫻',
  '��' => '뫽',
  '��' => '뫾',
  '��' => '뫿',
  '��' => '묁',
  '��' => '묂',
  '��' => '묃',
  '��' => '묅',
  '��' => '묆',
  '��' => '묇',
  '��' => '묈',
  '��' => '묉',
  '��' => '묊',
  '��' => '묋',
  '��' => '묌',
  '��' => '묎',
  '��' => '묐',
  '��' => '묒',
  '��' => '묓',
  '��' => '묔',
  '��' => '묕',
  '��' => '묖',
  '��' => '묗',
  '��' => '묙',
  '��' => '묚',
  '��' => '묛',
  '��' => '묝',
  '��' => '묞',
  '��' => '묟',
  '��' => '묡',
  '��' => '묢',
  '��' => '묣',
  '��' => '묤',
  '��' => '묥',
  '��' => '묦',
  '��' => '묧',
  '�A' => '묨',
  '�B' => '묪',
  '�C' => '묬',
  '�D' => '묭',
  '�E' => '묮',
  '�F' => '묯',
  '�G' => '묰',
  '�H' => '묱',
  '�I' => '묲',
  '�J' => '묳',
  '�K' => '묷',
  '�L' => '묹',
  '�M' => '묺',
  '�N' => '묿',
  '�O' => '뭀',
  '�P' => '뭁',
  '�Q' => '뭂',
  '�R' => '뭃',
  '�S' => '뭆',
  '�T' => '뭈',
  '�U' => '뭊',
  '�V' => '뭋',
  '�W' => '뭌',
  '�X' => '뭎',
  '�Y' => '뭑',
  '�Z' => '뭒',
  '�a' => '뭓',
  '�b' => '뭕',
  '�c' => '뭖',
  '�d' => '뭗',
  '�e' => '뭙',
  '�f' => '뭚',
  '�g' => '뭛',
  '�h' => '뭜',
  '�i' => '뭝',
  '�j' => '뭞',
  '�k' => '뭟',
  '�l' => '뭠',
  '�m' => '뭢',
  '�n' => '뭤',
  '�o' => '뭥',
  '�p' => '뭦',
  '�q' => '뭧',
  '�r' => '뭨',
  '�s' => '뭩',
  '�t' => '뭪',
  '�u' => '뭫',
  '�v' => '뭭',
  '�w' => '뭮',
  '�x' => '뭯',
  '�y' => '뭰',
  '�z' => '뭱',
  '��' => '뭲',
  '��' => '뭳',
  '��' => '뭴',
  '��' => '뭵',
  '��' => '뭶',
  '��' => '뭷',
  '��' => '뭸',
  '��' => '뭹',
  '��' => '뭺',
  '��' => '뭻',
  '��' => '뭼',
  '��' => '뭽',
  '��' => '뭾',
  '��' => '뭿',
  '��' => '뮀',
  '��' => '뮁',
  '��' => '뮂',
  '��' => '뮃',
  '��' => '뮄',
  '��' => '뮅',
  '��' => '뮆',
  '��' => '뮇',
  '��' => '뮉',
  '��' => '뮊',
  '��' => '뮋',
  '��' => '뮍',
  '��' => '뮎',
  '��' => '뮏',
  '��' => '뮑',
  '��' => '뮒',
  '��' => '뮓',
  '��' => '뮔',
  '��' => '뮕',
  '��' => '뮖',
  '��' => '뮗',
  '��' => '뮘',
  '��' => '뮙',
  '��' => '뮚',
  '��' => '뮛',
  '��' => '뮜',
  '��' => '뮝',
  '��' => '뮞',
  '��' => '뮟',
  '��' => '뮠',
  '��' => '뮡',
  '��' => '뮢',
  '��' => '뮣',
  '��' => '뮥',
  '��' => '뮦',
  '��' => '뮧',
  '��' => '뮩',
  '��' => '뮪',
  '��' => '뮫',
  '��' => '뮭',
  '��' => '뮮',
  '��' => '뮯',
  '��' => '뮰',
  '��' => '뮱',
  '��' => '뮲',
  '��' => '뮳',
  '��' => '뮵',
  '��' => '뮶',
  '��' => '뮸',
  '��' => '뮹',
  '��' => '뮺',
  '��' => '뮻',
  '��' => '뮼',
  '��' => '뮽',
  '��' => '뮾',
  '��' => '뮿',
  '��' => '믁',
  '��' => '믂',
  '��' => '믃',
  '��' => '믅',
  '��' => '믆',
  '��' => '믇',
  '��' => '믉',
  '��' => '믊',
  '��' => '믋',
  '��' => '믌',
  '��' => '믍',
  '��' => '믎',
  '��' => '믏',
  '��' => '믑',
  '��' => '믒',
  '��' => '믔',
  '��' => '믕',
  '��' => '믖',
  '��' => '믗',
  '��' => '믘',
  '��' => '믙',
  '��' => '믚',
  '��' => '믛',
  '��' => '믜',
  '��' => '믝',
  '��' => '믞',
  '��' => '믟',
  '��' => '믠',
  '��' => '믡',
  '��' => '믢',
  '��' => '믣',
  '��' => '믤',
  '��' => '믥',
  '��' => '믦',
  '��' => '믧',
  '��' => '믨',
  '��' => '믩',
  '��' => '믪',
  '��' => '믫',
  '��' => '믬',
  '��' => '믭',
  '��' => '믮',
  '��' => '믯',
  '��' => '믰',
  '��' => '믱',
  '��' => '믲',
  '��' => '믳',
  '��' => '믴',
  '��' => '믵',
  '��' => '믶',
  '��' => '믷',
  '��' => '믺',
  '��' => '믻',
  '��' => '믽',
  '��' => '믾',
  '��' => '밁',
  '�A' => '밃',
  '�B' => '밄',
  '�C' => '밅',
  '�D' => '밆',
  '�E' => '밇',
  '�F' => '밊',
  '�G' => '밎',
  '�H' => '밐',
  '�I' => '밒',
  '�J' => '밓',
  '�K' => '밙',
  '�L' => '밚',
  '�M' => '밠',
  '�N' => '밡',
  '�O' => '밢',
  '�P' => '밣',
  '�Q' => '밦',
  '�R' => '밨',
  '�S' => '밪',
  '�T' => '밫',
  '�U' => '밬',
  '�V' => '밮',
  '�W' => '밯',
  '�X' => '밲',
  '�Y' => '밳',
  '�Z' => '밵',
  '�a' => '밶',
  '�b' => '밷',
  '�c' => '밹',
  '�d' => '밺',
  '�e' => '밻',
  '�f' => '밼',
  '�g' => '밽',
  '�h' => '밾',
  '�i' => '밿',
  '�j' => '뱂',
  '�k' => '뱆',
  '�l' => '뱇',
  '�m' => '뱈',
  '�n' => '뱊',
  '�o' => '뱋',
  '�p' => '뱎',
  '�q' => '뱏',
  '�r' => '뱑',
  '�s' => '뱒',
  '�t' => '뱓',
  '�u' => '뱔',
  '�v' => '뱕',
  '�w' => '뱖',
  '�x' => '뱗',
  '�y' => '뱘',
  '�z' => '뱙',
  '��' => '뱚',
  '��' => '뱛',
  '��' => '뱜',
  '��' => '뱞',
  '��' => '뱟',
  '��' => '뱠',
  '��' => '뱡',
  '��' => '뱢',
  '��' => '뱣',
  '��' => '뱤',
  '��' => '뱥',
  '��' => '뱦',
  '��' => '뱧',
  '��' => '뱨',
  '��' => '뱩',
  '��' => '뱪',
  '��' => '뱫',
  '��' => '뱬',
  '��' => '뱭',
  '��' => '뱮',
  '��' => '뱯',
  '��' => '뱰',
  '��' => '뱱',
  '��' => '뱲',
  '��' => '뱳',
  '��' => '뱴',
  '��' => '뱵',
  '��' => '뱶',
  '��' => '뱷',
  '��' => '뱸',
  '��' => '뱹',
  '��' => '뱺',
  '��' => '뱻',
  '��' => '뱼',
  '��' => '뱽',
  '��' => '뱾',
  '��' => '뱿',
  '��' => '벀',
  '��' => '벁',
  '��' => '벂',
  '��' => '벃',
  '��' => '벆',
  '��' => '벇',
  '��' => '벉',
  '��' => '벊',
  '��' => '벍',
  '��' => '벏',
  '��' => '벐',
  '��' => '벑',
  '��' => '벒',
  '��' => '벓',
  '��' => '벖',
  '��' => '벘',
  '��' => '벛',
  '��' => '벜',
  '��' => '벝',
  '��' => '벞',
  '��' => '벟',
  '��' => '벢',
  '��' => '벣',
  '��' => '벥',
  '��' => '벦',
  '��' => '벩',
  '��' => '벪',
  '��' => '벫',
  '��' => '벬',
  '��' => '벭',
  '��' => '벮',
  '��' => '벯',
  '��' => '벲',
  '��' => '벶',
  '��' => '벷',
  '��' => '벸',
  '��' => '벹',
  '��' => '벺',
  '��' => '벻',
  '��' => '벾',
  '��' => '벿',
  '��' => '볁',
  '��' => '볂',
  '��' => '볃',
  '��' => '볅',
  '��' => '볆',
  '��' => '볇',
  '��' => '볈',
  '��' => '볉',
  '��' => '볊',
  '��' => '볋',
  '��' => '볌',
  '��' => '볎',
  '��' => '볒',
  '��' => '볓',
  '��' => '볔',
  '��' => '볖',
  '��' => '볗',
  '��' => '볙',
  '��' => '볚',
  '��' => '볛',
  '��' => '볝',
  '��' => '볞',
  '��' => '볟',
  '��' => '볠',
  '��' => '볡',
  '��' => '볢',
  '��' => '볣',
  '��' => '볤',
  '��' => '볥',
  '��' => '볦',
  '��' => '볧',
  '��' => '볨',
  '��' => '볩',
  '��' => '볪',
  '��' => '볫',
  '��' => '볬',
  '��' => '볭',
  '��' => '볮',
  '��' => '볯',
  '��' => '볰',
  '��' => '볱',
  '��' => '볲',
  '��' => '볳',
  '��' => '볷',
  '��' => '볹',
  '��' => '볺',
  '��' => '볻',
  '��' => '볽',
  '�A' => '볾',
  '�B' => '볿',
  '�C' => '봀',
  '�D' => '봁',
  '�E' => '봂',
  '�F' => '봃',
  '�G' => '봆',
  '�H' => '봈',
  '�I' => '봊',
  '�J' => '봋',
  '�K' => '봌',
  '�L' => '봍',
  '�M' => '봎',
  '�N' => '봏',
  '�O' => '봑',
  '�P' => '봒',
  '�Q' => '봓',
  '�R' => '봕',
  '�S' => '봖',
  '�T' => '봗',
  '�U' => '봘',
  '�V' => '봙',
  '�W' => '봚',
  '�X' => '봛',
  '�Y' => '봜',
  '�Z' => '봝',
  '�a' => '봞',
  '�b' => '봟',
  '�c' => '봠',
  '�d' => '봡',
  '�e' => '봢',
  '�f' => '봣',
  '�g' => '봥',
  '�h' => '봦',
  '�i' => '봧',
  '�j' => '봨',
  '�k' => '봩',
  '�l' => '봪',
  '�m' => '봫',
  '�n' => '봭',
  '�o' => '봮',
  '�p' => '봯',
  '�q' => '봰',
  '�r' => '봱',
  '�s' => '봲',
  '�t' => '봳',
  '�u' => '봴',
  '�v' => '봵',
  '�w' => '봶',
  '�x' => '봷',
  '�y' => '봸',
  '�z' => '봹',
  '��' => '봺',
  '��' => '봻',
  '��' => '봼',
  '��' => '봽',
  '��' => '봾',
  '��' => '봿',
  '��' => '뵁',
  '��' => '뵂',
  '��' => '뵃',
  '��' => '뵄',
  '��' => '뵅',
  '��' => '뵆',
  '��' => '뵇',
  '��' => '뵊',
  '��' => '뵋',
  '��' => '뵍',
  '��' => '뵎',
  '��' => '뵏',
  '��' => '뵑',
  '��' => '뵒',
  '��' => '뵓',
  '��' => '뵔',
  '��' => '뵕',
  '��' => '뵖',
  '��' => '뵗',
  '��' => '뵚',
  '��' => '뵛',
  '��' => '뵜',
  '��' => '뵝',
  '��' => '뵞',
  '��' => '뵟',
  '��' => '뵠',
  '��' => '뵡',
  '��' => '뵢',
  '��' => '뵣',
  '��' => '뵥',
  '��' => '뵦',
  '��' => '뵧',
  '��' => '뵩',
  '��' => '뵪',
  '��' => '뵫',
  '��' => '뵬',
  '��' => '뵭',
  '��' => '뵮',
  '��' => '뵯',
  '��' => '뵰',
  '��' => '뵱',
  '��' => '뵲',
  '��' => '뵳',
  '��' => '뵴',
  '��' => '뵵',
  '��' => '뵶',
  '��' => '뵷',
  '��' => '뵸',
  '��' => '뵹',
  '��' => '뵺',
  '��' => '뵻',
  '��' => '뵼',
  '��' => '뵽',
  '��' => '뵾',
  '��' => '뵿',
  '��' => '붂',
  '��' => '붃',
  '��' => '붅',
  '��' => '붆',
  '��' => '붋',
  '��' => '붌',
  '��' => '붍',
  '��' => '붎',
  '��' => '붏',
  '��' => '붒',
  '��' => '붔',
  '��' => '붖',
  '��' => '붗',
  '��' => '붘',
  '��' => '붛',
  '��' => '붝',
  '��' => '붞',
  '��' => '붟',
  '��' => '붠',
  '��' => '붡',
  '��' => '붢',
  '��' => '붣',
  '��' => '붥',
  '��' => '붦',
  '��' => '붧',
  '��' => '붨',
  '��' => '붩',
  '��' => '붪',
  '��' => '붫',
  '��' => '붬',
  '��' => '붭',
  '��' => '붮',
  '��' => '붯',
  '��' => '붱',
  '��' => '붲',
  '��' => '붳',
  '��' => '붴',
  '��' => '붵',
  '��' => '붶',
  '��' => '붷',
  '��' => '붹',
  '��' => '붺',
  '��' => '붻',
  '��' => '붼',
  '��' => '붽',
  '��' => '붾',
  '��' => '붿',
  '��' => '뷀',
  '��' => '뷁',
  '��' => '뷂',
  '��' => '뷃',
  '��' => '뷄',
  '��' => '뷅',
  '��' => '뷆',
  '��' => '뷇',
  '��' => '뷈',
  '��' => '뷉',
  '��' => '뷊',
  '��' => '뷋',
  '��' => '뷌',
  '��' => '뷍',
  '��' => '뷎',
  '��' => '뷏',
  '��' => '뷐',
  '��' => '뷑',
  '�A' => '뷒',
  '�B' => '뷓',
  '�C' => '뷖',
  '�D' => '뷗',
  '�E' => '뷙',
  '�F' => '뷚',
  '�G' => '뷛',
  '�H' => '뷝',
  '�I' => '뷞',
  '�J' => '뷟',
  '�K' => '뷠',
  '�L' => '뷡',
  '�M' => '뷢',
  '�N' => '뷣',
  '�O' => '뷤',
  '�P' => '뷥',
  '�Q' => '뷦',
  '�R' => '뷧',
  '�S' => '뷨',
  '�T' => '뷪',
  '�U' => '뷫',
  '�V' => '뷬',
  '�W' => '뷭',
  '�X' => '뷮',
  '�Y' => '뷯',
  '�Z' => '뷱',
  '�a' => '뷲',
  '�b' => '뷳',
  '�c' => '뷵',
  '�d' => '뷶',
  '�e' => '뷷',
  '�f' => '뷹',
  '�g' => '뷺',
  '�h' => '뷻',
  '�i' => '뷼',
  '�j' => '뷽',
  '�k' => '뷾',
  '�l' => '뷿',
  '�m' => '븁',
  '�n' => '븂',
  '�o' => '븄',
  '�p' => '븆',
  '�q' => '븇',
  '�r' => '븈',
  '�s' => '븉',
  '�t' => '븊',
  '�u' => '븋',
  '�v' => '븎',
  '�w' => '븏',
  '�x' => '븑',
  '�y' => '븒',
  '�z' => '븓',
  '��' => '븕',
  '��' => '븖',
  '��' => '븗',
  '��' => '븘',
  '��' => '븙',
  '��' => '븚',
  '��' => '븛',
  '��' => '븞',
  '��' => '븠',
  '��' => '븡',
  '��' => '븢',
  '��' => '븣',
  '��' => '븤',
  '��' => '븥',
  '��' => '븦',
  '��' => '븧',
  '��' => '븨',
  '��' => '븩',
  '��' => '븪',
  '��' => '븫',
  '��' => '븬',
  '��' => '븭',
  '��' => '븮',
  '��' => '븯',
  '��' => '븰',
  '��' => '븱',
  '��' => '븲',
  '��' => '븳',
  '��' => '븴',
  '��' => '븵',
  '��' => '븶',
  '��' => '븷',
  '��' => '븸',
  '��' => '븹',
  '��' => '븺',
  '��' => '븻',
  '��' => '븼',
  '��' => '븽',
  '��' => '븾',
  '��' => '븿',
  '��' => '빀',
  '��' => '빁',
  '��' => '빂',
  '��' => '빃',
  '��' => '빆',
  '��' => '빇',
  '��' => '빉',
  '��' => '빊',
  '��' => '빋',
  '��' => '빍',
  '��' => '빏',
  '��' => '빐',
  '��' => '빑',
  '��' => '빒',
  '��' => '빓',
  '��' => '빖',
  '��' => '빘',
  '��' => '빜',
  '��' => '빝',
  '��' => '빞',
  '��' => '빟',
  '��' => '빢',
  '��' => '빣',
  '��' => '빥',
  '��' => '빦',
  '��' => '빧',
  '��' => '빩',
  '��' => '빫',
  '��' => '빬',
  '��' => '빭',
  '��' => '빮',
  '��' => '빯',
  '��' => '빲',
  '��' => '빶',
  '��' => '빷',
  '��' => '빸',
  '��' => '빹',
  '��' => '빺',
  '��' => '빾',
  '��' => '빿',
  '��' => '뺁',
  '��' => '뺂',
  '��' => '뺃',
  '��' => '뺅',
  '��' => '뺆',
  '��' => '뺇',
  '��' => '뺈',
  '��' => '뺉',
  '��' => '뺊',
  '��' => '뺋',
  '��' => '뺎',
  '��' => '뺒',
  '��' => '뺓',
  '��' => '뺔',
  '��' => '뺕',
  '��' => '뺖',
  '��' => '뺗',
  '��' => '뺚',
  '��' => '뺛',
  '��' => '뺜',
  '��' => '뺝',
  '��' => '뺞',
  '��' => '뺟',
  '��' => '뺠',
  '��' => '뺡',
  '��' => '뺢',
  '��' => '뺣',
  '��' => '뺤',
  '��' => '뺥',
  '��' => '뺦',
  '��' => '뺧',
  '��' => '뺩',
  '��' => '뺪',
  '��' => '뺫',
  '��' => '뺬',
  '��' => '뺭',
  '��' => '뺮',
  '��' => '뺯',
  '��' => '뺰',
  '��' => '뺱',
  '��' => '뺲',
  '��' => '뺳',
  '��' => '뺴',
  '��' => '뺵',
  '��' => '뺶',
  '��' => '뺷',
  '�A' => '뺸',
  '�B' => '뺹',
  '�C' => '뺺',
  '�D' => '뺻',
  '�E' => '뺼',
  '�F' => '뺽',
  '�G' => '뺾',
  '�H' => '뺿',
  '�I' => '뻀',
  '�J' => '뻁',
  '�K' => '뻂',
  '�L' => '뻃',
  '�M' => '뻄',
  '�N' => '뻅',
  '�O' => '뻆',
  '�P' => '뻇',
  '�Q' => '뻈',
  '�R' => '뻉',
  '�S' => '뻊',
  '�T' => '뻋',
  '�U' => '뻌',
  '�V' => '뻍',
  '�W' => '뻎',
  '�X' => '뻏',
  '�Y' => '뻒',
  '�Z' => '뻓',
  '�a' => '뻕',
  '�b' => '뻖',
  '�c' => '뻙',
  '�d' => '뻚',
  '�e' => '뻛',
  '�f' => '뻜',
  '�g' => '뻝',
  '�h' => '뻞',
  '�i' => '뻟',
  '�j' => '뻡',
  '�k' => '뻢',
  '�l' => '뻦',
  '�m' => '뻧',
  '�n' => '뻨',
  '�o' => '뻩',
  '�p' => '뻪',
  '�q' => '뻫',
  '�r' => '뻭',
  '�s' => '뻮',
  '�t' => '뻯',
  '�u' => '뻰',
  '�v' => '뻱',
  '�w' => '뻲',
  '�x' => '뻳',
  '�y' => '뻴',
  '�z' => '뻵',
  '��' => '뻶',
  '��' => '뻷',
  '��' => '뻸',
  '��' => '뻹',
  '��' => '뻺',
  '��' => '뻻',
  '��' => '뻼',
  '��' => '뻽',
  '��' => '뻾',
  '��' => '뻿',
  '��' => '뼀',
  '��' => '뼂',
  '��' => '뼃',
  '��' => '뼄',
  '��' => '뼅',
  '��' => '뼆',
  '��' => '뼇',
  '��' => '뼊',
  '��' => '뼋',
  '��' => '뼌',
  '��' => '뼍',
  '��' => '뼎',
  '��' => '뼏',
  '��' => '뼐',
  '��' => '뼑',
  '��' => '뼒',
  '��' => '뼓',
  '��' => '뼔',
  '��' => '뼕',
  '��' => '뼖',
  '��' => '뼗',
  '��' => '뼚',
  '��' => '뼞',
  '��' => '뼟',
  '��' => '뼠',
  '��' => '뼡',
  '��' => '뼢',
  '��' => '뼣',
  '��' => '뼤',
  '��' => '뼥',
  '��' => '뼦',
  '��' => '뼧',
  '��' => '뼨',
  '��' => '뼩',
  '��' => '뼪',
  '��' => '뼫',
  '��' => '뼬',
  '��' => '뼭',
  '��' => '뼮',
  '��' => '뼯',
  '��' => '뼰',
  '��' => '뼱',
  '��' => '뼲',
  '��' => '뼳',
  '��' => '뼴',
  '��' => '뼵',
  '��' => '뼶',
  '��' => '뼷',
  '��' => '뼸',
  '��' => '뼹',
  '��' => '뼺',
  '��' => '뼻',
  '��' => '뼼',
  '��' => '뼽',
  '��' => '뼾',
  '��' => '뼿',
  '��' => '뽂',
  '��' => '뽃',
  '��' => '뽅',
  '��' => '뽆',
  '��' => '뽇',
  '��' => '뽉',
  '��' => '뽊',
  '��' => '뽋',
  '��' => '뽌',
  '��' => '뽍',
  '��' => '뽎',
  '��' => '뽏',
  '��' => '뽒',
  '��' => '뽓',
  '��' => '뽔',
  '��' => '뽖',
  '��' => '뽗',
  '��' => '뽘',
  '��' => '뽙',
  '��' => '뽚',
  '��' => '뽛',
  '��' => '뽜',
  '��' => '뽝',
  '��' => '뽞',
  '��' => '뽟',
  '��' => '뽠',
  '��' => '뽡',
  '��' => '뽢',
  '��' => '뽣',
  '��' => '뽤',
  '��' => '뽥',
  '��' => '뽦',
  '��' => '뽧',
  '��' => '뽨',
  '��' => '뽩',
  '��' => '뽪',
  '��' => '뽫',
  '��' => '뽬',
  '��' => '뽭',
  '��' => '뽮',
  '��' => '뽯',
  '��' => '뽰',
  '��' => '뽱',
  '��' => '뽲',
  '��' => '뽳',
  '��' => '뽴',
  '��' => '뽵',
  '��' => '뽶',
  '��' => '뽷',
  '��' => '뽸',
  '��' => '뽹',
  '��' => '뽺',
  '��' => '뽻',
  '��' => '뽼',
  '��' => '뽽',
  '��' => '뽾',
  '��' => '뽿',
  '��' => '뾀',
  '��' => '뾁',
  '��' => '뾂',
  '�A' => '뾃',
  '�B' => '뾄',
  '�C' => '뾅',
  '�D' => '뾆',
  '�E' => '뾇',
  '�F' => '뾈',
  '�G' => '뾉',
  '�H' => '뾊',
  '�I' => '뾋',
  '�J' => '뾌',
  '�K' => '뾍',
  '�L' => '뾎',
  '�M' => '뾏',
  '�N' => '뾐',
  '�O' => '뾑',
  '�P' => '뾒',
  '�Q' => '뾓',
  '�R' => '뾕',
  '�S' => '뾖',
  '�T' => '뾗',
  '�U' => '뾘',
  '�V' => '뾙',
  '�W' => '뾚',
  '�X' => '뾛',
  '�Y' => '뾜',
  '�Z' => '뾝',
  '�a' => '뾞',
  '�b' => '뾟',
  '�c' => '뾠',
  '�d' => '뾡',
  '�e' => '뾢',
  '�f' => '뾣',
  '�g' => '뾤',
  '�h' => '뾥',
  '�i' => '뾦',
  '�j' => '뾧',
  '�k' => '뾨',
  '�l' => '뾩',
  '�m' => '뾪',
  '�n' => '뾫',
  '�o' => '뾬',
  '�p' => '뾭',
  '�q' => '뾮',
  '�r' => '뾯',
  '�s' => '뾱',
  '�t' => '뾲',
  '�u' => '뾳',
  '�v' => '뾴',
  '�w' => '뾵',
  '�x' => '뾶',
  '�y' => '뾷',
  '�z' => '뾸',
  '��' => '뾹',
  '��' => '뾺',
  '��' => '뾻',
  '��' => '뾼',
  '��' => '뾽',
  '��' => '뾾',
  '��' => '뾿',
  '��' => '뿀',
  '��' => '뿁',
  '��' => '뿂',
  '��' => '뿃',
  '��' => '뿄',
  '��' => '뿆',
  '��' => '뿇',
  '��' => '뿈',
  '��' => '뿉',
  '��' => '뿊',
  '��' => '뿋',
  '��' => '뿎',
  '��' => '뿏',
  '��' => '뿑',
  '��' => '뿒',
  '��' => '뿓',
  '��' => '뿕',
  '��' => '뿖',
  '��' => '뿗',
  '��' => '뿘',
  '��' => '뿙',
  '��' => '뿚',
  '��' => '뿛',
  '��' => '뿝',
  '��' => '뿞',
  '��' => '뿠',
  '��' => '뿢',
  '��' => '뿣',
  '��' => '뿤',
  '��' => '뿥',
  '��' => '뿦',
  '��' => '뿧',
  '��' => '뿨',
  '��' => '뿩',
  '��' => '뿪',
  '��' => '뿫',
  '��' => '뿬',
  '��' => '뿭',
  '��' => '뿮',
  '��' => '뿯',
  '��' => '뿰',
  '��' => '뿱',
  '��' => '뿲',
  '��' => '뿳',
  '��' => '뿴',
  '��' => '뿵',
  '��' => '뿶',
  '��' => '뿷',
  '��' => '뿸',
  '��' => '뿹',
  '��' => '뿺',
  '��' => '뿻',
  '��' => '뿼',
  '��' => '뿽',
  '��' => '뿾',
  '��' => '뿿',
  '��' => '쀀',
  '��' => '쀁',
  '��' => '쀂',
  '��' => '쀃',
  '��' => '쀄',
  '��' => '쀅',
  '��' => '쀆',
  '��' => '쀇',
  '��' => '쀈',
  '��' => '쀉',
  '��' => '쀊',
  '��' => '쀋',
  '��' => '쀌',
  '��' => '쀍',
  '��' => '쀎',
  '��' => '쀏',
  '��' => '쀐',
  '��' => '쀑',
  '��' => '쀒',
  '��' => '쀓',
  '��' => '쀔',
  '��' => '쀕',
  '��' => '쀖',
  '��' => '쀗',
  '��' => '쀘',
  '��' => '쀙',
  '��' => '쀚',
  '��' => '쀛',
  '��' => '쀜',
  '��' => '쀝',
  '��' => '쀞',
  '��' => '쀟',
  '��' => '쀠',
  '��' => '쀡',
  '��' => '쀢',
  '��' => '쀣',
  '��' => '쀤',
  '��' => '쀥',
  '��' => '쀦',
  '��' => '쀧',
  '��' => '쀨',
  '��' => '쀩',
  '��' => '쀪',
  '��' => '쀫',
  '��' => '쀬',
  '��' => '쀭',
  '��' => '쀮',
  '��' => '쀯',
  '��' => '쀰',
  '��' => '쀱',
  '��' => '쀲',
  '��' => '쀳',
  '��' => '쀴',
  '��' => '쀵',
  '��' => '쀶',
  '��' => '쀷',
  '��' => '쀸',
  '��' => '쀹',
  '��' => '쀺',
  '��' => '쀻',
  '��' => '쀽',
  '��' => '쀾',
  '��' => '쀿',
  '�A' => '쁀',
  '�B' => '쁁',
  '�C' => '쁂',
  '�D' => '쁃',
  '�E' => '쁄',
  '�F' => '쁅',
  '�G' => '쁆',
  '�H' => '쁇',
  '�I' => '쁈',
  '�J' => '쁉',
  '�K' => '쁊',
  '�L' => '쁋',
  '�M' => '쁌',
  '�N' => '쁍',
  '�O' => '쁎',
  '�P' => '쁏',
  '�Q' => '쁐',
  '�R' => '쁒',
  '�S' => '쁓',
  '�T' => '쁔',
  '�U' => '쁕',
  '�V' => '쁖',
  '�W' => '쁗',
  '�X' => '쁙',
  '�Y' => '쁚',
  '�Z' => '쁛',
  '�a' => '쁝',
  '�b' => '쁞',
  '�c' => '쁟',
  '�d' => '쁡',
  '�e' => '쁢',
  '�f' => '쁣',
  '�g' => '쁤',
  '�h' => '쁥',
  '�i' => '쁦',
  '�j' => '쁧',
  '�k' => '쁪',
  '�l' => '쁫',
  '�m' => '쁬',
  '�n' => '쁭',
  '�o' => '쁮',
  '�p' => '쁯',
  '�q' => '쁰',
  '�r' => '쁱',
  '�s' => '쁲',
  '�t' => '쁳',
  '�u' => '쁴',
  '�v' => '쁵',
  '�w' => '쁶',
  '�x' => '쁷',
  '�y' => '쁸',
  '�z' => '쁹',
  '��' => '쁺',
  '��' => '쁻',
  '��' => '쁼',
  '��' => '쁽',
  '��' => '쁾',
  '��' => '쁿',
  '��' => '삀',
  '��' => '삁',
  '��' => '삂',
  '��' => '삃',
  '��' => '삄',
  '��' => '삅',
  '��' => '삆',
  '��' => '삇',
  '��' => '삈',
  '��' => '삉',
  '��' => '삊',
  '��' => '삋',
  '��' => '삌',
  '��' => '삍',
  '��' => '삎',
  '��' => '삏',
  '��' => '삒',
  '��' => '삓',
  '��' => '삕',
  '��' => '삖',
  '��' => '삗',
  '��' => '삙',
  '��' => '삚',
  '��' => '삛',
  '��' => '삜',
  '��' => '삝',
  '��' => '삞',
  '��' => '삟',
  '��' => '삢',
  '��' => '삤',
  '��' => '삦',
  '��' => '삧',
  '��' => '삨',
  '��' => '삩',
  '��' => '삪',
  '��' => '삫',
  '��' => '삮',
  '��' => '삱',
  '��' => '삲',
  '��' => '삷',
  '��' => '삸',
  '��' => '삹',
  '��' => '삺',
  '��' => '삻',
  '��' => '삾',
  '��' => '샂',
  '��' => '샃',
  '��' => '샄',
  '��' => '샆',
  '��' => '샇',
  '��' => '샊',
  '��' => '샋',
  '��' => '샍',
  '��' => '샎',
  '��' => '샏',
  '��' => '샑',
  '��' => '샒',
  '��' => '샓',
  '��' => '샔',
  '��' => '샕',
  '��' => '샖',
  '��' => '샗',
  '��' => '샚',
  '��' => '샞',
  '��' => '샟',
  '��' => '샠',
  '��' => '샡',
  '��' => '샢',
  '��' => '샣',
  '��' => '샦',
  '��' => '샧',
  '��' => '샩',
  '��' => '샪',
  '��' => '샫',
  '��' => '샭',
  '��' => '샮',
  '��' => '샯',
  '��' => '샰',
  '��' => '샱',
  '��' => '샲',
  '��' => '샳',
  '��' => '샶',
  '��' => '샸',
  '��' => '샺',
  '��' => '샻',
  '��' => '샼',
  '��' => '샽',
  '��' => '샾',
  '��' => '샿',
  '��' => '섁',
  '��' => '섂',
  '��' => '섃',
  '��' => '섅',
  '��' => '섆',
  '��' => '섇',
  '��' => '섉',
  '��' => '섊',
  '��' => '섋',
  '��' => '섌',
  '��' => '섍',
  '��' => '섎',
  '��' => '섏',
  '��' => '섑',
  '��' => '섒',
  '��' => '섓',
  '��' => '섔',
  '��' => '섖',
  '��' => '섗',
  '��' => '섘',
  '��' => '섙',
  '��' => '섚',
  '��' => '섛',
  '��' => '섡',
  '��' => '섢',
  '��' => '섥',
  '��' => '섨',
  '��' => '섩',
  '��' => '섪',
  '��' => '섫',
  '��' => '섮',
  '�A' => '섲',
  '�B' => '섳',
  '�C' => '섴',
  '�D' => '섵',
  '�E' => '섷',
  '�F' => '섺',
  '�G' => '섻',
  '�H' => '섽',
  '�I' => '섾',
  '�J' => '섿',
  '�K' => '셁',
  '�L' => '셂',
  '�M' => '셃',
  '�N' => '셄',
  '�O' => '셅',
  '�P' => '셆',
  '�Q' => '셇',
  '�R' => '셊',
  '�S' => '셎',
  '�T' => '셏',
  '�U' => '셐',
  '�V' => '셑',
  '�W' => '셒',
  '�X' => '셓',
  '�Y' => '셖',
  '�Z' => '셗',
  '�a' => '셙',
  '�b' => '셚',
  '�c' => '셛',
  '�d' => '셝',
  '�e' => '셞',
  '�f' => '셟',
  '�g' => '셠',
  '�h' => '셡',
  '�i' => '셢',
  '�j' => '셣',
  '�k' => '셦',
  '�l' => '셪',
  '�m' => '셫',
  '�n' => '셬',
  '�o' => '셭',
  '�p' => '셮',
  '�q' => '셯',
  '�r' => '셱',
  '�s' => '셲',
  '�t' => '셳',
  '�u' => '셵',
  '�v' => '셶',
  '�w' => '셷',
  '�x' => '셹',
  '�y' => '셺',
  '�z' => '셻',
  '��' => '셼',
  '��' => '셽',
  '��' => '셾',
  '��' => '셿',
  '��' => '솀',
  '��' => '솁',
  '��' => '솂',
  '��' => '솃',
  '��' => '솄',
  '��' => '솆',
  '��' => '솇',
  '��' => '솈',
  '��' => '솉',
  '��' => '솊',
  '��' => '솋',
  '��' => '솏',
  '��' => '솑',
  '��' => '솒',
  '��' => '솓',
  '��' => '솕',
  '��' => '솗',
  '��' => '솘',
  '��' => '솙',
  '��' => '솚',
  '��' => '솛',
  '��' => '솞',
  '��' => '솠',
  '��' => '솢',
  '��' => '솣',
  '��' => '솤',
  '��' => '솦',
  '��' => '솧',
  '��' => '솪',
  '��' => '솫',
  '��' => '솭',
  '��' => '솮',
  '��' => '솯',
  '��' => '솱',
  '��' => '솲',
  '��' => '솳',
  '��' => '솴',
  '��' => '솵',
  '��' => '솶',
  '��' => '솷',
  '��' => '솸',
  '��' => '솹',
  '��' => '솺',
  '��' => '솻',
  '��' => '솼',
  '��' => '솾',
  '��' => '솿',
  '��' => '쇀',
  '��' => '쇁',
  '��' => '쇂',
  '��' => '쇃',
  '��' => '쇅',
  '��' => '쇆',
  '��' => '쇇',
  '��' => '쇉',
  '��' => '쇊',
  '��' => '쇋',
  '��' => '쇍',
  '��' => '쇎',
  '��' => '쇏',
  '��' => '쇐',
  '��' => '쇑',
  '��' => '쇒',
  '��' => '쇓',
  '��' => '쇕',
  '��' => '쇖',
  '��' => '쇙',
  '��' => '쇚',
  '��' => '쇛',
  '��' => '쇜',
  '��' => '쇝',
  '��' => '쇞',
  '��' => '쇟',
  '��' => '쇡',
  '��' => '쇢',
  '��' => '쇣',
  '��' => '쇥',
  '��' => '쇦',
  '��' => '쇧',
  '��' => '쇩',
  '��' => '쇪',
  '��' => '쇫',
  '��' => '쇬',
  '��' => '쇭',
  '��' => '쇮',
  '��' => '쇯',
  '��' => '쇲',
  '��' => '쇴',
  '��' => '쇵',
  '��' => '쇶',
  '��' => '쇷',
  '��' => '쇸',
  '��' => '쇹',
  '��' => '쇺',
  '��' => '쇻',
  '��' => '쇾',
  '��' => '쇿',
  '��' => '숁',
  '��' => '숂',
  '��' => '숃',
  '��' => '숅',
  '��' => '숆',
  '��' => '숇',
  '��' => '숈',
  '��' => '숉',
  '��' => '숊',
  '��' => '숋',
  '��' => '숎',
  '��' => '숐',
  '��' => '숒',
  '��' => '숓',
  '��' => '숔',
  '��' => '숕',
  '��' => '숖',
  '��' => '숗',
  '��' => '숚',
  '��' => '숛',
  '��' => '숝',
  '��' => '숞',
  '��' => '숡',
  '��' => '숢',
  '��' => '숣',
  '�A' => '숤',
  '�B' => '숥',
  '�C' => '숦',
  '�D' => '숧',
  '�E' => '숪',
  '�F' => '숬',
  '�G' => '숮',
  '�H' => '숰',
  '�I' => '숳',
  '�J' => '숵',
  '�K' => '숶',
  '�L' => '숷',
  '�M' => '숸',
  '�N' => '숹',
  '�O' => '숺',
  '�P' => '숻',
  '�Q' => '숼',
  '�R' => '숽',
  '�S' => '숾',
  '�T' => '숿',
  '�U' => '쉀',
  '�V' => '쉁',
  '�W' => '쉂',
  '�X' => '쉃',
  '�Y' => '쉄',
  '�Z' => '쉅',
  '�a' => '쉆',
  '�b' => '쉇',
  '�c' => '쉉',
  '�d' => '쉊',
  '�e' => '쉋',
  '�f' => '쉌',
  '�g' => '쉍',
  '�h' => '쉎',
  '�i' => '쉏',
  '�j' => '쉒',
  '�k' => '쉓',
  '�l' => '쉕',
  '�m' => '쉖',
  '�n' => '쉗',
  '�o' => '쉙',
  '�p' => '쉚',
  '�q' => '쉛',
  '�r' => '쉜',
  '�s' => '쉝',
  '�t' => '쉞',
  '�u' => '쉟',
  '�v' => '쉡',
  '�w' => '쉢',
  '�x' => '쉣',
  '�y' => '쉤',
  '�z' => '쉦',
  '��' => '쉧',
  '��' => '쉨',
  '��' => '쉩',
  '��' => '쉪',
  '��' => '쉫',
  '��' => '쉮',
  '��' => '쉯',
  '��' => '쉱',
  '��' => '쉲',
  '��' => '쉳',
  '��' => '쉵',
  '��' => '쉶',
  '��' => '쉷',
  '��' => '쉸',
  '��' => '쉹',
  '��' => '쉺',
  '��' => '쉻',
  '��' => '쉾',
  '��' => '슀',
  '��' => '슂',
  '��' => '슃',
  '��' => '슄',
  '��' => '슅',
  '��' => '슆',
  '��' => '슇',
  '��' => '슊',
  '��' => '슋',
  '��' => '슌',
  '��' => '슍',
  '��' => '슎',
  '��' => '슏',
  '��' => '슑',
  '��' => '슒',
  '��' => '슓',
  '��' => '슔',
  '��' => '슕',
  '��' => '슖',
  '��' => '슗',
  '��' => '슙',
  '��' => '슚',
  '��' => '슜',
  '��' => '슞',
  '��' => '슟',
  '��' => '슠',
  '��' => '슡',
  '��' => '슢',
  '��' => '슣',
  '��' => '슦',
  '��' => '슧',
  '��' => '슩',
  '��' => '슪',
  '��' => '슫',
  '��' => '슮',
  '��' => '슯',
  '��' => '슰',
  '��' => '슱',
  '��' => '슲',
  '��' => '슳',
  '��' => '슶',
  '��' => '슸',
  '��' => '슺',
  '��' => '슻',
  '��' => '슼',
  '��' => '슽',
  '��' => '슾',
  '��' => '슿',
  '��' => '싀',
  '��' => '싁',
  '��' => '싂',
  '��' => '싃',
  '��' => '싄',
  '��' => '싅',
  '��' => '싆',
  '��' => '싇',
  '��' => '싈',
  '��' => '싉',
  '��' => '싊',
  '��' => '싋',
  '��' => '싌',
  '��' => '싍',
  '��' => '싎',
  '��' => '싏',
  '��' => '싐',
  '��' => '싑',
  '��' => '싒',
  '��' => '싓',
  '��' => '싔',
  '��' => '싕',
  '��' => '싖',
  '��' => '싗',
  '��' => '싘',
  '��' => '싙',
  '��' => '싚',
  '��' => '싛',
  '��' => '싞',
  '��' => '싟',
  '��' => '싡',
  '��' => '싢',
  '��' => '싥',
  '��' => '싦',
  '��' => '싧',
  '��' => '싨',
  '��' => '싩',
  '��' => '싪',
  '��' => '싮',
  '��' => '싰',
  '��' => '싲',
  '��' => '싳',
  '��' => '싴',
  '��' => '싵',
  '��' => '싷',
  '��' => '싺',
  '��' => '싽',
  '��' => '싾',
  '��' => '싿',
  '��' => '쌁',
  '��' => '쌂',
  '��' => '쌃',
  '��' => '쌄',
  '��' => '쌅',
  '��' => '쌆',
  '��' => '쌇',
  '��' => '쌊',
  '��' => '쌋',
  '��' => '쌎',
  '��' => '쌏',
  '�A' => '쌐',
  '�B' => '쌑',
  '�C' => '쌒',
  '�D' => '쌖',
  '�E' => '쌗',
  '�F' => '쌙',
  '�G' => '쌚',
  '�H' => '쌛',
  '�I' => '쌝',
  '�J' => '쌞',
  '�K' => '쌟',
  '�L' => '쌠',
  '�M' => '쌡',
  '�N' => '쌢',
  '�O' => '쌣',
  '�P' => '쌦',
  '�Q' => '쌧',
  '�R' => '쌪',
  '�S' => '쌫',
  '�T' => '쌬',
  '�U' => '쌭',
  '�V' => '쌮',
  '�W' => '쌯',
  '�X' => '쌰',
  '�Y' => '쌱',
  '�Z' => '쌲',
  '�a' => '쌳',
  '�b' => '쌴',
  '�c' => '쌵',
  '�d' => '쌶',
  '�e' => '쌷',
  '�f' => '쌸',
  '�g' => '쌹',
  '�h' => '쌺',
  '�i' => '쌻',
  '�j' => '쌼',
  '�k' => '쌽',
  '�l' => '쌾',
  '�m' => '쌿',
  '�n' => '썀',
  '�o' => '썁',
  '�p' => '썂',
  '�q' => '썃',
  '�r' => '썄',
  '�s' => '썆',
  '�t' => '썇',
  '�u' => '썈',
  '�v' => '썉',
  '�w' => '썊',
  '�x' => '썋',
  '�y' => '썌',
  '�z' => '썍',
  '��' => '썎',
  '��' => '썏',
  '��' => '썐',
  '��' => '썑',
  '��' => '썒',
  '��' => '썓',
  '��' => '썔',
  '��' => '썕',
  '��' => '썖',
  '��' => '썗',
  '��' => '썘',
  '��' => '썙',
  '��' => '썚',
  '��' => '썛',
  '��' => '썜',
  '��' => '썝',
  '��' => '썞',
  '��' => '썟',
  '��' => '썠',
  '��' => '썡',
  '��' => '썢',
  '��' => '썣',
  '��' => '썤',
  '��' => '썥',
  '��' => '썦',
  '��' => '썧',
  '��' => '썪',
  '��' => '썫',
  '��' => '썭',
  '��' => '썮',
  '��' => '썯',
  '��' => '썱',
  '��' => '썳',
  '��' => '썴',
  '��' => '썵',
  '��' => '썶',
  '��' => '썷',
  '��' => '썺',
  '��' => '썻',
  '��' => '썾',
  '��' => '썿',
  '��' => '쎀',
  '��' => '쎁',
  '��' => '쎂',
  '��' => '쎃',
  '��' => '쎅',
  '��' => '쎆',
  '��' => '쎇',
  '��' => '쎉',
  '��' => '쎊',
  '��' => '쎋',
  '��' => '쎍',
  '��' => '쎎',
  '��' => '쎏',
  '��' => '쎐',
  '��' => '쎑',
  '��' => '쎒',
  '��' => '쎓',
  '��' => '쎔',
  '��' => '쎕',
  '��' => '쎖',
  '��' => '쎗',
  '��' => '쎘',
  '��' => '쎙',
  '��' => '쎚',
  '��' => '쎛',
  '��' => '쎜',
  '��' => '쎝',
  '��' => '쎞',
  '��' => '쎟',
  '��' => '쎠',
  '��' => '쎡',
  '��' => '쎢',
  '��' => '쎣',
  '��' => '쎤',
  '��' => '쎥',
  '��' => '쎦',
  '��' => '쎧',
  '��' => '쎨',
  '��' => '쎩',
  '��' => '쎪',
  '��' => '쎫',
  '��' => '쎬',
  '��' => '쎭',
  '��' => '쎮',
  '��' => '쎯',
  '��' => '쎰',
  '��' => '쎱',
  '��' => '쎲',
  '��' => '쎳',
  '��' => '쎴',
  '��' => '쎵',
  '��' => '쎶',
  '��' => '쎷',
  '��' => '쎸',
  '��' => '쎹',
  '��' => '쎺',
  '��' => '쎻',
  '��' => '쎼',
  '��' => '쎽',
  '��' => '쎾',
  '��' => '쎿',
  '��' => '쏁',
  '��' => '쏂',
  '��' => '쏃',
  '��' => '쏄',
  '��' => '쏅',
  '��' => '쏆',
  '��' => '쏇',
  '��' => '쏈',
  '��' => '쏉',
  '��' => '쏊',
  '��' => '쏋',
  '��' => '쏌',
  '��' => '쏍',
  '��' => '쏎',
  '��' => '쏏',
  '��' => '쏐',
  '��' => '쏑',
  '��' => '쏒',
  '��' => '쏓',
  '��' => '쏔',
  '��' => '쏕',
  '��' => '쏖',
  '��' => '쏗',
  '��' => '쏚',
  '�A' => '쏛',
  '�B' => '쏝',
  '�C' => '쏞',
  '�D' => '쏡',
  '�E' => '쏣',
  '�F' => '쏤',
  '�G' => '쏥',
  '�H' => '쏦',
  '�I' => '쏧',
  '�J' => '쏪',
  '�K' => '쏫',
  '�L' => '쏬',
  '�M' => '쏮',
  '�N' => '쏯',
  '�O' => '쏰',
  '�P' => '쏱',
  '�Q' => '쏲',
  '�R' => '쏳',
  '�S' => '쏶',
  '�T' => '쏷',
  '�U' => '쏹',
  '�V' => '쏺',
  '�W' => '쏻',
  '�X' => '쏼',
  '�Y' => '쏽',
  '�Z' => '쏾',
  '�a' => '쏿',
  '�b' => '쐀',
  '�c' => '쐁',
  '�d' => '쐂',
  '�e' => '쐃',
  '�f' => '쐄',
  '�g' => '쐅',
  '�h' => '쐆',
  '�i' => '쐇',
  '�j' => '쐉',
  '�k' => '쐊',
  '�l' => '쐋',
  '�m' => '쐌',
  '�n' => '쐍',
  '�o' => '쐎',
  '�p' => '쐏',
  '�q' => '쐑',
  '�r' => '쐒',
  '�s' => '쐓',
  '�t' => '쐔',
  '�u' => '쐕',
  '�v' => '쐖',
  '�w' => '쐗',
  '�x' => '쐘',
  '�y' => '쐙',
  '�z' => '쐚',
  '��' => '쐛',
  '��' => '쐜',
  '��' => '쐝',
  '��' => '쐞',
  '��' => '쐟',
  '��' => '쐠',
  '��' => '쐡',
  '��' => '쐢',
  '��' => '쐣',
  '��' => '쐥',
  '��' => '쐦',
  '��' => '쐧',
  '��' => '쐨',
  '��' => '쐩',
  '��' => '쐪',
  '��' => '쐫',
  '��' => '쐭',
  '��' => '쐮',
  '��' => '쐯',
  '��' => '쐱',
  '��' => '쐲',
  '��' => '쐳',
  '��' => '쐵',
  '��' => '쐶',
  '��' => '쐷',
  '��' => '쐸',
  '��' => '쐹',
  '��' => '쐺',
  '��' => '쐻',
  '��' => '쐾',
  '��' => '쐿',
  '��' => '쑀',
  '��' => '쑁',
  '��' => '쑂',
  '��' => '쑃',
  '��' => '쑄',
  '��' => '쑅',
  '��' => '쑆',
  '��' => '쑇',
  '��' => '쑉',
  '��' => '쑊',
  '��' => '쑋',
  '��' => '쑌',
  '��' => '쑍',
  '��' => '쑎',
  '��' => '쑏',
  '��' => '쑐',
  '��' => '쑑',
  '��' => '쑒',
  '��' => '쑓',
  '��' => '쑔',
  '��' => '쑕',
  '��' => '쑖',
  '��' => '쑗',
  '��' => '쑘',
  '��' => '쑙',
  '��' => '쑚',
  '��' => '쑛',
  '��' => '쑜',
  '��' => '쑝',
  '��' => '쑞',
  '��' => '쑟',
  '��' => '쑠',
  '��' => '쑡',
  '��' => '쑢',
  '��' => '쑣',
  '��' => '쑦',
  '��' => '쑧',
  '��' => '쑩',
  '��' => '쑪',
  '��' => '쑫',
  '��' => '쑭',
  '��' => '쑮',
  '��' => '쑯',
  '��' => '쑰',
  '��' => '쑱',
  '��' => '쑲',
  '��' => '쑳',
  '��' => '쑶',
  '��' => '쑷',
  '��' => '쑸',
  '��' => '쑺',
  '��' => '쑻',
  '��' => '쑼',
  '��' => '쑽',
  '��' => '쑾',
  '��' => '쑿',
  '��' => '쒁',
  '��' => '쒂',
  '��' => '쒃',
  '��' => '쒄',
  '��' => '쒅',
  '��' => '쒆',
  '��' => '쒇',
  '��' => '쒈',
  '��' => '쒉',
  '��' => '쒊',
  '��' => '쒋',
  '��' => '쒌',
  '��' => '쒍',
  '��' => '쒎',
  '��' => '쒏',
  '��' => '쒐',
  '��' => '쒑',
  '��' => '쒒',
  '��' => '쒓',
  '��' => '쒕',
  '��' => '쒖',
  '��' => '쒗',
  '��' => '쒘',
  '��' => '쒙',
  '��' => '쒚',
  '��' => '쒛',
  '��' => '쒝',
  '��' => '쒞',
  '��' => '쒟',
  '��' => '쒠',
  '��' => '쒡',
  '��' => '쒢',
  '��' => '쒣',
  '��' => '쒤',
  '��' => '쒥',
  '��' => '쒦',
  '��' => '쒧',
  '��' => '쒨',
  '��' => '쒩',
  '�A' => '쒪',
  '�B' => '쒫',
  '�C' => '쒬',
  '�D' => '쒭',
  '�E' => '쒮',
  '�F' => '쒯',
  '�G' => '쒰',
  '�H' => '쒱',
  '�I' => '쒲',
  '�J' => '쒳',
  '�K' => '쒴',
  '�L' => '쒵',
  '�M' => '쒶',
  '�N' => '쒷',
  '�O' => '쒹',
  '�P' => '쒺',
  '�Q' => '쒻',
  '�R' => '쒽',
  '�S' => '쒾',
  '�T' => '쒿',
  '�U' => '쓀',
  '�V' => '쓁',
  '�W' => '쓂',
  '�X' => '쓃',
  '�Y' => '쓄',
  '�Z' => '쓅',
  '�a' => '쓆',
  '�b' => '쓇',
  '�c' => '쓈',
  '�d' => '쓉',
  '�e' => '쓊',
  '�f' => '쓋',
  '�g' => '쓌',
  '�h' => '쓍',
  '�i' => '쓎',
  '�j' => '쓏',
  '�k' => '쓐',
  '�l' => '쓑',
  '�m' => '쓒',
  '�n' => '쓓',
  '�o' => '쓔',
  '�p' => '쓕',
  '�q' => '쓖',
  '�r' => '쓗',
  '�s' => '쓘',
  '�t' => '쓙',
  '�u' => '쓚',
  '�v' => '쓛',
  '�w' => '쓜',
  '�x' => '쓝',
  '�y' => '쓞',
  '�z' => '쓟',
  '��' => '쓠',
  '��' => '쓡',
  '��' => '쓢',
  '��' => '쓣',
  '��' => '쓤',
  '��' => '쓥',
  '��' => '쓦',
  '��' => '쓧',
  '��' => '쓨',
  '��' => '쓪',
  '��' => '쓫',
  '��' => '쓬',
  '��' => '쓭',
  '��' => '쓮',
  '��' => '쓯',
  '��' => '쓲',
  '��' => '쓳',
  '��' => '쓵',
  '��' => '쓶',
  '��' => '쓷',
  '��' => '쓹',
  '��' => '쓻',
  '��' => '쓼',
  '��' => '쓽',
  '��' => '쓾',
  '��' => '씂',
  '��' => '씃',
  '��' => '씄',
  '��' => '씅',
  '��' => '씆',
  '��' => '씇',
  '��' => '씈',
  '��' => '씉',
  '��' => '씊',
  '��' => '씋',
  '��' => '씍',
  '��' => '씎',
  '��' => '씏',
  '��' => '씑',
  '��' => '씒',
  '��' => '씓',
  '��' => '씕',
  '��' => '씖',
  '��' => '씗',
  '��' => '씘',
  '��' => '씙',
  '��' => '씚',
  '��' => '씛',
  '��' => '씝',
  '��' => '씞',
  '��' => '씟',
  '��' => '씠',
  '��' => '씡',
  '��' => '씢',
  '��' => '씣',
  '��' => '씤',
  '��' => '씥',
  '��' => '씦',
  '��' => '씧',
  '��' => '씪',
  '��' => '씫',
  '��' => '씭',
  '��' => '씮',
  '��' => '씯',
  '��' => '씱',
  '��' => '씲',
  '��' => '씳',
  '��' => '씴',
  '��' => '씵',
  '��' => '씶',
  '��' => '씷',
  '��' => '씺',
  '��' => '씼',
  '��' => '씾',
  '��' => '씿',
  '��' => '앀',
  '��' => '앁',
  '��' => '앂',
  '��' => '앃',
  '��' => '앆',
  '��' => '앇',
  '��' => '앋',
  '��' => '앏',
  '��' => '앐',
  '��' => '앑',
  '��' => '앒',
  '��' => '앖',
  '��' => '앚',
  '��' => '앛',
  '��' => '앜',
  '��' => '앟',
  '��' => '앢',
  '��' => '앣',
  '��' => '앥',
  '��' => '앦',
  '��' => '앧',
  '��' => '앩',
  '��' => '앪',
  '��' => '앫',
  '��' => '앬',
  '��' => '앭',
  '��' => '앮',
  '��' => '앯',
  '��' => '앲',
  '��' => '앶',
  '��' => '앷',
  '��' => '앸',
  '��' => '앹',
  '��' => '앺',
  '��' => '앻',
  '��' => '앾',
  '��' => '앿',
  '��' => '얁',
  '��' => '얂',
  '��' => '얃',
  '��' => '얅',
  '��' => '얆',
  '��' => '얈',
  '��' => '얉',
  '��' => '얊',
  '��' => '얋',
  '��' => '얎',
  '��' => '얐',
  '��' => '얒',
  '��' => '얓',
  '��' => '얔',
  '�A' => '얖',
  '�B' => '얙',
  '�C' => '얚',
  '�D' => '얛',
  '�E' => '얝',
  '�F' => '얞',
  '�G' => '얟',
  '�H' => '얡',
  '�I' => '얢',
  '�J' => '얣',
  '�K' => '얤',
  '�L' => '얥',
  '�M' => '얦',
  '�N' => '얧',
  '�O' => '얨',
  '�P' => '얪',
  '�Q' => '얫',
  '�R' => '얬',
  '�S' => '얭',
  '�T' => '얮',
  '�U' => '얯',
  '�V' => '얰',
  '�W' => '얱',
  '�X' => '얲',
  '�Y' => '얳',
  '�Z' => '얶',
  '�a' => '얷',
  '�b' => '얺',
  '�c' => '얿',
  '�d' => '엀',
  '�e' => '엁',
  '�f' => '엂',
  '�g' => '엃',
  '�h' => '엋',
  '�i' => '엍',
  '�j' => '엏',
  '�k' => '엒',
  '�l' => '엓',
  '�m' => '엕',
  '�n' => '엖',
  '�o' => '엗',
  '�p' => '엙',
  '�q' => '엚',
  '�r' => '엛',
  '�s' => '엜',
  '�t' => '엝',
  '�u' => '엞',
  '�v' => '엟',
  '�w' => '엢',
  '�x' => '엤',
  '�y' => '엦',
  '�z' => '엧',
  '��' => '엨',
  '��' => '엩',
  '��' => '엪',
  '��' => '엫',
  '��' => '엯',
  '��' => '엱',
  '��' => '엲',
  '��' => '엳',
  '��' => '엵',
  '��' => '엸',
  '��' => '엹',
  '��' => '엺',
  '��' => '엻',
  '��' => '옂',
  '��' => '옃',
  '��' => '옄',
  '��' => '옉',
  '��' => '옊',
  '��' => '옋',
  '��' => '옍',
  '��' => '옎',
  '��' => '옏',
  '��' => '옑',
  '��' => '옒',
  '��' => '옓',
  '��' => '옔',
  '��' => '옕',
  '��' => '옖',
  '��' => '옗',
  '��' => '옚',
  '��' => '옝',
  '��' => '옞',
  '��' => '옟',
  '��' => '옠',
  '��' => '옡',
  '��' => '옢',
  '��' => '옣',
  '��' => '옦',
  '��' => '옧',
  '��' => '옩',
  '��' => '옪',
  '��' => '옫',
  '��' => '옯',
  '��' => '옱',
  '��' => '옲',
  '��' => '옶',
  '��' => '옸',
  '��' => '옺',
  '��' => '옼',
  '��' => '옽',
  '��' => '옾',
  '��' => '옿',
  '��' => '왂',
  '��' => '왃',
  '��' => '왅',
  '��' => '왆',
  '��' => '왇',
  '��' => '왉',
  '��' => '왊',
  '��' => '왋',
  '��' => '왌',
  '��' => '왍',
  '��' => '왎',
  '��' => '왏',
  '��' => '왒',
  '��' => '왖',
  '��' => '왗',
  '��' => '왘',
  '��' => '왙',
  '��' => '왚',
  '��' => '왛',
  '��' => '왞',
  '��' => '왟',
  '��' => '왡',
  '��' => '왢',
  '��' => '왣',
  '��' => '왤',
  '��' => '왥',
  '��' => '왦',
  '��' => '왧',
  '��' => '왨',
  '��' => '왩',
  '��' => '왪',
  '��' => '왫',
  '��' => '왭',
  '��' => '왮',
  '��' => '왰',
  '��' => '왲',
  '��' => '왳',
  '��' => '왴',
  '��' => '왵',
  '��' => '왶',
  '��' => '왷',
  '��' => '왺',
  '��' => '왻',
  '��' => '왽',
  '��' => '왾',
  '��' => '왿',
  '��' => '욁',
  '��' => '욂',
  '��' => '욃',
  '��' => '욄',
  '��' => '욅',
  '��' => '욆',
  '��' => '욇',
  '��' => '욊',
  '��' => '욌',
  '��' => '욎',
  '��' => '욏',
  '��' => '욐',
  '��' => '욑',
  '��' => '욒',
  '��' => '욓',
  '��' => '욖',
  '��' => '욗',
  '��' => '욙',
  '��' => '욚',
  '��' => '욛',
  '��' => '욝',
  '��' => '욞',
  '��' => '욟',
  '��' => '욠',
  '��' => '욡',
  '��' => '욢',
  '��' => '욣',
  '��' => '욦',
  '�A' => '욨',
  '�B' => '욪',
  '�C' => '욫',
  '�D' => '욬',
  '�E' => '욭',
  '�F' => '욮',
  '�G' => '욯',
  '�H' => '욲',
  '�I' => '욳',
  '�J' => '욵',
  '�K' => '욶',
  '�L' => '욷',
  '�M' => '욻',
  '�N' => '욼',
  '�O' => '욽',
  '�P' => '욾',
  '�Q' => '욿',
  '�R' => '웂',
  '�S' => '웄',
  '�T' => '웆',
  '�U' => '웇',
  '�V' => '웈',
  '�W' => '웉',
  '�X' => '웊',
  '�Y' => '웋',
  '�Z' => '웎',
  '�a' => '웏',
  '�b' => '웑',
  '�c' => '웒',
  '�d' => '웓',
  '�e' => '웕',
  '�f' => '웖',
  '�g' => '웗',
  '�h' => '웘',
  '�i' => '웙',
  '�j' => '웚',
  '�k' => '웛',
  '�l' => '웞',
  '�m' => '웟',
  '�n' => '웢',
  '�o' => '웣',
  '�p' => '웤',
  '�q' => '웥',
  '�r' => '웦',
  '�s' => '웧',
  '�t' => '웪',
  '�u' => '웫',
  '�v' => '웭',
  '�w' => '웮',
  '�x' => '웯',
  '�y' => '웱',
  '�z' => '웲',
  '��' => '웳',
  '��' => '웴',
  '��' => '웵',
  '��' => '웶',
  '��' => '웷',
  '��' => '웺',
  '��' => '웻',
  '��' => '웼',
  '��' => '웾',
  '��' => '웿',
  '��' => '윀',
  '��' => '윁',
  '��' => '윂',
  '��' => '윃',
  '��' => '윆',
  '��' => '윇',
  '��' => '윉',
  '��' => '윊',
  '��' => '윋',
  '��' => '윍',
  '��' => '윎',
  '��' => '윏',
  '��' => '윐',
  '��' => '윑',
  '��' => '윒',
  '��' => '윓',
  '��' => '윖',
  '��' => '윘',
  '��' => '윚',
  '��' => '윛',
  '��' => '윜',
  '��' => '윝',
  '��' => '윞',
  '��' => '윟',
  '��' => '윢',
  '��' => '윣',
  '��' => '윥',
  '��' => '윦',
  '��' => '윧',
  '��' => '윩',
  '��' => '윪',
  '��' => '윫',
  '��' => '윬',
  '��' => '윭',
  '��' => '윮',
  '��' => '윯',
  '��' => '윲',
  '��' => '윴',
  '��' => '윶',
  '��' => '윸',
  '��' => '윹',
  '��' => '윺',
  '��' => '윻',
  '��' => '윾',
  '��' => '윿',
  '��' => '읁',
  '��' => '읂',
  '��' => '읃',
  '��' => '읅',
  '��' => '읆',
  '��' => '읇',
  '��' => '읈',
  '��' => '읉',
  '��' => '읋',
  '��' => '읎',
  '��' => '읐',
  '��' => '읙',
  '��' => '읚',
  '��' => '읛',
  '��' => '읝',
  '��' => '읞',
  '��' => '읟',
  '��' => '읡',
  '��' => '읢',
  '��' => '읣',
  '��' => '읤',
  '��' => '읥',
  '��' => '읦',
  '��' => '읧',
  '��' => '읩',
  '��' => '읪',
  '��' => '읬',
  '��' => '읭',
  '��' => '읮',
  '��' => '읯',
  '��' => '읰',
  '��' => '읱',
  '��' => '읲',
  '��' => '읳',
  '��' => '읶',
  '��' => '읷',
  '��' => '읹',
  '��' => '읺',
  '��' => '읻',
  '��' => '읿',
  '��' => '잀',
  '��' => '잁',
  '��' => '잂',
  '��' => '잆',
  '��' => '잋',
  '��' => '잌',
  '��' => '잍',
  '��' => '잏',
  '��' => '잒',
  '��' => '잓',
  '��' => '잕',
  '��' => '잙',
  '��' => '잛',
  '��' => '잜',
  '��' => '잝',
  '��' => '잞',
  '��' => '잟',
  '��' => '잢',
  '��' => '잧',
  '��' => '잨',
  '��' => '잩',
  '��' => '잪',
  '��' => '잫',
  '��' => '잮',
  '��' => '잯',
  '��' => '잱',
  '��' => '잲',
  '��' => '잳',
  '��' => '잵',
  '��' => '잶',
  '��' => '잷',
  '�A' => '잸',
  '�B' => '잹',
  '�C' => '잺',
  '�D' => '잻',
  '�E' => '잾',
  '�F' => '쟂',
  '�G' => '쟃',
  '�H' => '쟄',
  '�I' => '쟅',
  '�J' => '쟆',
  '�K' => '쟇',
  '�L' => '쟊',
  '�M' => '쟋',
  '�N' => '쟍',
  '�O' => '쟏',
  '�P' => '쟑',
  '�Q' => '쟒',
  '�R' => '쟓',
  '�S' => '쟔',
  '�T' => '쟕',
  '�U' => '쟖',
  '�V' => '쟗',
  '�W' => '쟙',
  '�X' => '쟚',
  '�Y' => '쟛',
  '�Z' => '쟜',
  '�a' => '쟞',
  '�b' => '쟟',
  '�c' => '쟠',
  '�d' => '쟡',
  '�e' => '쟢',
  '�f' => '쟣',
  '�g' => '쟥',
  '�h' => '쟦',
  '�i' => '쟧',
  '�j' => '쟩',
  '�k' => '쟪',
  '�l' => '쟫',
  '�m' => '쟭',
  '�n' => '쟮',
  '�o' => '쟯',
  '�p' => '쟰',
  '�q' => '쟱',
  '�r' => '쟲',
  '�s' => '쟳',
  '�t' => '쟴',
  '�u' => '쟵',
  '�v' => '쟶',
  '�w' => '쟷',
  '�x' => '쟸',
  '�y' => '쟹',
  '�z' => '쟺',
  '��' => '쟻',
  '��' => '쟼',
  '��' => '쟽',
  '��' => '쟾',
  '��' => '쟿',
  '��' => '젂',
  '��' => '젃',
  '��' => '젅',
  '��' => '젆',
  '��' => '젇',
  '��' => '젉',
  '��' => '젋',
  '��' => '젌',
  '��' => '젍',
  '��' => '젎',
  '��' => '젏',
  '��' => '젒',
  '��' => '젔',
  '��' => '젗',
  '��' => '젘',
  '��' => '젙',
  '��' => '젚',
  '��' => '젛',
  '��' => '젞',
  '��' => '젟',
  '��' => '젡',
  '��' => '젢',
  '��' => '젣',
  '��' => '젥',
  '��' => '젦',
  '��' => '젧',
  '��' => '젨',
  '��' => '젩',
  '��' => '젪',
  '��' => '젫',
  '��' => '젮',
  '��' => '젰',
  '��' => '젲',
  '��' => '젳',
  '��' => '젴',
  '��' => '젵',
  '��' => '젶',
  '��' => '젷',
  '��' => '젹',
  '��' => '젺',
  '��' => '젻',
  '��' => '젽',
  '��' => '젾',
  '��' => '젿',
  '��' => '졁',
  '��' => '졂',
  '��' => '졃',
  '��' => '졄',
  '��' => '졅',
  '��' => '졆',
  '��' => '졇',
  '��' => '졊',
  '��' => '졋',
  '��' => '졎',
  '��' => '졏',
  '��' => '졐',
  '��' => '졑',
  '��' => '졒',
  '��' => '졓',
  '��' => '졕',
  '��' => '졖',
  '��' => '졗',
  '��' => '졘',
  '��' => '졙',
  '��' => '졚',
  '��' => '졛',
  '��' => '졜',
  '��' => '졝',
  '��' => '졞',
  '��' => '졟',
  '��' => '졠',
  '��' => '졡',
  '��' => '졢',
  '��' => '졣',
  '��' => '졤',
  '��' => '졥',
  '��' => '졦',
  '��' => '졧',
  '��' => '졨',
  '��' => '졩',
  '��' => '졪',
  '��' => '졫',
  '��' => '졬',
  '��' => '졭',
  '��' => '졮',
  '��' => '졯',
  '��' => '졲',
  '��' => '졳',
  '��' => '졵',
  '��' => '졶',
  '��' => '졷',
  '��' => '졹',
  '��' => '졻',
  '��' => '졼',
  '��' => '졽',
  '��' => '졾',
  '��' => '졿',
  '��' => '좂',
  '��' => '좄',
  '��' => '좈',
  '��' => '좉',
  '��' => '좊',
  '��' => '좎',
  '��' => '좏',
  '��' => '좐',
  '��' => '좑',
  '��' => '좒',
  '��' => '좓',
  '��' => '좕',
  '��' => '좖',
  '��' => '좗',
  '��' => '좘',
  '��' => '좙',
  '��' => '좚',
  '��' => '좛',
  '��' => '좜',
  '��' => '좞',
  '��' => '좠',
  '��' => '좢',
  '��' => '좣',
  '��' => '좤',
  '�A' => '좥',
  '�B' => '좦',
  '�C' => '좧',
  '�D' => '좩',
  '�E' => '좪',
  '�F' => '좫',
  '�G' => '좬',
  '�H' => '좭',
  '�I' => '좮',
  '�J' => '좯',
  '�K' => '좰',
  '�L' => '좱',
  '�M' => '좲',
  '�N' => '좳',
  '�O' => '좴',
  '�P' => '좵',
  '�Q' => '좶',
  '�R' => '좷',
  '�S' => '좸',
  '�T' => '좹',
  '�U' => '좺',
  '�V' => '좻',
  '�W' => '좾',
  '�X' => '좿',
  '�Y' => '죀',
  '�Z' => '죁',
  '�a' => '죂',
  '�b' => '죃',
  '�c' => '죅',
  '�d' => '죆',
  '�e' => '죇',
  '�f' => '죉',
  '�g' => '죊',
  '�h' => '죋',
  '�i' => '죍',
  '�j' => '죎',
  '�k' => '죏',
  '�l' => '죐',
  '�m' => '죑',
  '�n' => '죒',
  '�o' => '죓',
  '�p' => '죖',
  '�q' => '죘',
  '�r' => '죚',
  '�s' => '죛',
  '�t' => '죜',
  '�u' => '죝',
  '�v' => '죞',
  '�w' => '죟',
  '�x' => '죢',
  '�y' => '죣',
  '�z' => '죥',
  '��' => '죦',
  '��' => '죧',
  '��' => '죨',
  '��' => '죩',
  '��' => '죪',
  '��' => '죫',
  '��' => '죬',
  '��' => '죭',
  '��' => '죮',
  '��' => '죯',
  '��' => '죰',
  '��' => '죱',
  '��' => '죲',
  '��' => '죳',
  '��' => '죴',
  '��' => '죶',
  '��' => '죷',
  '��' => '죸',
  '��' => '죹',
  '��' => '죺',
  '��' => '죻',
  '��' => '죾',
  '��' => '죿',
  '��' => '줁',
  '��' => '줂',
  '��' => '줃',
  '��' => '줇',
  '��' => '줈',
  '��' => '줉',
  '��' => '줊',
  '��' => '줋',
  '��' => '줎',
  '��' => ' ',
  '��' => '、',
  '��' => '。',
  '��' => '·',
  '��' => '‥',
  '��' => '…',
  '��' => '¨',
  '��' => '〃',
  '��' => '­',
  '��' => '―',
  '��' => '∥',
  '��' => '\',
  '��' => '∼',
  '��' => '‘',
  '��' => '’',
  '��' => '“',
  '��' => '”',
  '��' => '〔',
  '��' => '〕',
  '��' => '〈',
  '��' => '〉',
  '��' => '《',
  '��' => '》',
  '��' => '「',
  '��' => '」',
  '��' => '『',
  '��' => '』',
  '��' => '【',
  '��' => '】',
  '��' => '±',
  '��' => '×',
  '��' => '÷',
  '��' => '≠',
  '��' => '≤',
  '��' => '≥',
  '��' => '∞',
  '��' => '∴',
  '��' => '°',
  '��' => '′',
  '��' => '″',
  '��' => '℃',
  '��' => 'Å',
  '��' => '¢',
  '��' => '£',
  '��' => '¥',
  '��' => '♂',
  '��' => '♀',
  '��' => '∠',
  '��' => '⊥',
  '��' => '⌒',
  '��' => '∂',
  '��' => '∇',
  '��' => '≡',
  '��' => '≒',
  '��' => '§',
  '��' => '※',
  '��' => '☆',
  '��' => '★',
  '��' => '○',
  '��' => '●',
  '��' => '◎',
  '��' => '◇',
  '��' => '◆',
  '��' => '□',
  '��' => '■',
  '��' => '△',
  '��' => '▲',
  '��' => '▽',
  '��' => '▼',
  '��' => '→',
  '��' => '←',
  '��' => '↑',
  '��' => '↓',
  '��' => '↔',
  '��' => '〓',
  '��' => '≪',
  '��' => '≫',
  '��' => '√',
  '��' => '∽',
  '��' => '∝',
  '��' => '∵',
  '��' => '∫',
  '��' => '∬',
  '��' => '∈',
  '��' => '∋',
  '��' => '⊆',
  '��' => '⊇',
  '��' => '⊂',
  '��' => '⊃',
  '��' => '∪',
  '��' => '∩',
  '��' => '∧',
  '��' => '∨',
  '��' => '¬',
  '�A' => '줐',
  '�B' => '줒',
  '�C' => '줓',
  '�D' => '줔',
  '�E' => '줕',
  '�F' => '줖',
  '�G' => '줗',
  '�H' => '줙',
  '�I' => '줚',
  '�J' => '줛',
  '�K' => '줜',
  '�L' => '줝',
  '�M' => '줞',
  '�N' => '줟',
  '�O' => '줠',
  '�P' => '줡',
  '�Q' => '줢',
  '�R' => '줣',
  '�S' => '줤',
  '�T' => '줥',
  '�U' => '줦',
  '�V' => '줧',
  '�W' => '줨',
  '�X' => '줩',
  '�Y' => '줪',
  '�Z' => '줫',
  '�a' => '줭',
  '�b' => '줮',
  '�c' => '줯',
  '�d' => '줰',
  '�e' => '줱',
  '�f' => '줲',
  '�g' => '줳',
  '�h' => '줵',
  '�i' => '줶',
  '�j' => '줷',
  '�k' => '줸',
  '�l' => '줹',
  '�m' => '줺',
  '�n' => '줻',
  '�o' => '줼',
  '�p' => '줽',
  '�q' => '줾',
  '�r' => '줿',
  '�s' => '쥀',
  '�t' => '쥁',
  '�u' => '쥂',
  '�v' => '쥃',
  '�w' => '쥄',
  '�x' => '쥅',
  '�y' => '쥆',
  '�z' => '쥇',
  '��' => '쥈',
  '��' => '쥉',
  '��' => '쥊',
  '��' => '쥋',
  '��' => '쥌',
  '��' => '쥍',
  '��' => '쥎',
  '��' => '쥏',
  '��' => '쥒',
  '��' => '쥓',
  '��' => '쥕',
  '��' => '쥖',
  '��' => '쥗',
  '��' => '쥙',
  '��' => '쥚',
  '��' => '쥛',
  '��' => '쥜',
  '��' => '쥝',
  '��' => '쥞',
  '��' => '쥟',
  '��' => '쥢',
  '��' => '쥤',
  '��' => '쥥',
  '��' => '쥦',
  '��' => '쥧',
  '��' => '쥨',
  '��' => '쥩',
  '��' => '쥪',
  '��' => '쥫',
  '��' => '쥭',
  '��' => '쥮',
  '��' => '쥯',
  '��' => '⇒',
  '��' => '⇔',
  '��' => '∀',
  '��' => '∃',
  '��' => '´',
  '��' => '~',
  '��' => 'ˇ',
  '��' => '˘',
  '��' => '˝',
  '��' => '˚',
  '��' => '˙',
  '��' => '¸',
  '��' => '˛',
  '��' => '¡',
  '��' => '¿',
  '��' => 'ː',
  '��' => '∮',
  '��' => '∑',
  '��' => '∏',
  '��' => '¤',
  '��' => '℉',
  '��' => '‰',
  '��' => '◁',
  '��' => '◀',
  '��' => '▷',
  '��' => '▶',
  '��' => '♤',
  '��' => '♠',
  '��' => '♡',
  '��' => '♥',
  '��' => '♧',
  '��' => '♣',
  '��' => '⊙',
  '��' => '◈',
  '��' => '▣',
  '��' => '◐',
  '��' => '◑',
  '��' => '▒',
  '��' => '▤',
  '��' => '▥',
  '��' => '▨',
  '��' => '▧',
  '��' => '▦',
  '��' => '▩',
  '��' => '♨',
  '��' => '☏',
  '��' => '☎',
  '��' => '☜',
  '��' => '☞',
  '��' => '¶',
  '��' => '†',
  '��' => '‡',
  '��' => '↕',
  '��' => '↗',
  '��' => '↙',
  '��' => '↖',
  '��' => '↘',
  '��' => '♭',
  '��' => '♩',
  '��' => '♪',
  '��' => '♬',
  '��' => '㉿',
  '��' => '㈜',
  '��' => '№',
  '��' => '㏇',
  '��' => '™',
  '��' => '㏂',
  '��' => '㏘',
  '��' => '℡',
  '��' => '€',
  '��' => '®',
  '�A' => '쥱',
  '�B' => '쥲',
  '�C' => '쥳',
  '�D' => '쥵',
  '�E' => '쥶',
  '�F' => '쥷',
  '�G' => '쥸',
  '�H' => '쥹',
  '�I' => '쥺',
  '�J' => '쥻',
  '�K' => '쥽',
  '�L' => '쥾',
  '�M' => '쥿',
  '�N' => '즀',
  '�O' => '즁',
  '�P' => '즂',
  '�Q' => '즃',
  '�R' => '즄',
  '�S' => '즅',
  '�T' => '즆',
  '�U' => '즇',
  '�V' => '즊',
  '�W' => '즋',
  '�X' => '즍',
  '�Y' => '즎',
  '�Z' => '즏',
  '�a' => '즑',
  '�b' => '즒',
  '�c' => '즓',
  '�d' => '즔',
  '�e' => '즕',
  '�f' => '즖',
  '�g' => '즗',
  '�h' => '즚',
  '�i' => '즜',
  '�j' => '즞',
  '�k' => '즟',
  '�l' => '즠',
  '�m' => '즡',
  '�n' => '즢',
  '�o' => '즣',
  '�p' => '즤',
  '�q' => '즥',
  '�r' => '즦',
  '�s' => '즧',
  '�t' => '즨',
  '�u' => '즩',
  '�v' => '즪',
  '�w' => '즫',
  '�x' => '즬',
  '�y' => '즭',
  '�z' => '즮',
  '��' => '즯',
  '��' => '즰',
  '��' => '즱',
  '��' => '즲',
  '��' => '즳',
  '��' => '즴',
  '��' => '즵',
  '��' => '즶',
  '��' => '즷',
  '��' => '즸',
  '��' => '즹',
  '��' => '즺',
  '��' => '즻',
  '��' => '즼',
  '��' => '즽',
  '��' => '즾',
  '��' => '즿',
  '��' => '짂',
  '��' => '짃',
  '��' => '짅',
  '��' => '짆',
  '��' => '짉',
  '��' => '짋',
  '��' => '짌',
  '��' => '짍',
  '��' => '짎',
  '��' => '짏',
  '��' => '짒',
  '��' => '짔',
  '��' => '짗',
  '��' => '짘',
  '��' => '짛',
  '��' => '!',
  '��' => '"',
  '��' => '#',
  '��' => '$',
  '��' => '%',
  '��' => '&',
  '��' => ''',
  '��' => '(',
  '��' => ')',
  '��' => '*',
  '��' => '+',
  '��' => ',',
  '��' => '-',
  '��' => '.',
  '��' => '/',
  '��' => '0',
  '��' => '1',
  '��' => '2',
  '��' => '3',
  '��' => '4',
  '��' => '5',
  '��' => '6',
  '��' => '7',
  '��' => '8',
  '��' => '9',
  '��' => ':',
  '��' => ';',
  '��' => '<',
  '��' => '=',
  '��' => '>',
  '��' => '?',
  '��' => '@',
  '��' => 'A',
  '��' => 'B',
  '��' => 'C',
  '��' => 'D',
  '��' => 'E',
  '��' => 'F',
  '��' => 'G',
  '��' => 'H',
  '��' => 'I',
  '��' => 'J',
  '��' => 'K',
  '��' => 'L',
  '��' => 'M',
  '��' => 'N',
  '��' => 'O',
  '��' => 'P',
  '��' => 'Q',
  '��' => 'R',
  '��' => 'S',
  '��' => 'T',
  '��' => 'U',
  '��' => 'V',
  '��' => 'W',
  '��' => 'X',
  '��' => 'Y',
  '��' => 'Z',
  '��' => '[',
  '��' => '₩',
  '��' => ']',
  '��' => '^',
  '��' => '_',
  '��' => '`',
  '��' => 'a',
  '��' => 'b',
  '��' => 'c',
  '��' => 'd',
  '��' => 'e',
  '��' => 'f',
  '��' => 'g',
  '��' => 'h',
  '��' => 'i',
  '��' => 'j',
  '��' => 'k',
  '��' => 'l',
  '��' => 'm',
  '��' => 'n',
  '��' => 'o',
  '��' => 'p',
  '��' => 'q',
  '��' => 'r',
  '��' => 's',
  '��' => 't',
  '��' => 'u',
  '��' => 'v',
  '��' => 'w',
  '��' => 'x',
  '��' => 'y',
  '��' => 'z',
  '��' => '{',
  '��' => '|',
  '��' => '}',
  '��' => ' ̄',
  '�A' => '짞',
  '�B' => '짟',
  '�C' => '짡',
  '�D' => '짣',
  '�E' => '짥',
  '�F' => '짦',
  '�G' => '짨',
  '�H' => '짩',
  '�I' => '짪',
  '�J' => '짫',
  '�K' => '짮',
  '�L' => '짲',
  '�M' => '짳',
  '�N' => '짴',
  '�O' => '짵',
  '�P' => '짶',
  '�Q' => '짷',
  '�R' => '짺',
  '�S' => '짻',
  '�T' => '짽',
  '�U' => '짾',
  '�V' => '짿',
  '�W' => '쨁',
  '�X' => '쨂',
  '�Y' => '쨃',
  '�Z' => '쨄',
  '�a' => '쨅',
  '�b' => '쨆',
  '�c' => '쨇',
  '�d' => '쨊',
  '�e' => '쨎',
  '�f' => '쨏',
  '�g' => '쨐',
  '�h' => '쨑',
  '�i' => '쨒',
  '�j' => '쨓',
  '�k' => '쨕',
  '�l' => '쨖',
  '�m' => '쨗',
  '�n' => '쨙',
  '�o' => '쨚',
  '�p' => '쨛',
  '�q' => '쨜',
  '�r' => '쨝',
  '�s' => '쨞',
  '�t' => '쨟',
  '�u' => '쨠',
  '�v' => '쨡',
  '�w' => '쨢',
  '�x' => '쨣',
  '�y' => '쨤',
  '�z' => '쨥',
  '��' => '쨦',
  '��' => '쨧',
  '��' => '쨨',
  '��' => '쨪',
  '��' => '쨫',
  '��' => '쨬',
  '��' => '쨭',
  '��' => '쨮',
  '��' => '쨯',
  '��' => '쨰',
  '��' => '쨱',
  '��' => '쨲',
  '��' => '쨳',
  '��' => '쨴',
  '��' => '쨵',
  '��' => '쨶',
  '��' => '쨷',
  '��' => '쨸',
  '��' => '쨹',
  '��' => '쨺',
  '��' => '쨻',
  '��' => '쨼',
  '��' => '쨽',
  '��' => '쨾',
  '��' => '쨿',
  '��' => '쩀',
  '��' => '쩁',
  '��' => '쩂',
  '��' => '쩃',
  '��' => '쩄',
  '��' => '쩅',
  '��' => '쩆',
  '��' => 'ㄱ',
  '��' => 'ㄲ',
  '��' => 'ㄳ',
  '��' => 'ㄴ',
  '��' => 'ㄵ',
  '��' => 'ㄶ',
  '��' => 'ㄷ',
  '��' => 'ㄸ',
  '��' => 'ㄹ',
  '��' => 'ㄺ',
  '��' => 'ㄻ',
  '��' => 'ㄼ',
  '��' => 'ㄽ',
  '��' => 'ㄾ',
  '��' => 'ㄿ',
  '��' => 'ㅀ',
  '��' => 'ㅁ',
  '��' => 'ㅂ',
  '��' => 'ㅃ',
  '��' => 'ㅄ',
  '��' => 'ㅅ',
  '��' => 'ㅆ',
  '��' => 'ㅇ',
  '��' => 'ㅈ',
  '��' => 'ㅉ',
  '��' => 'ㅊ',
  '��' => 'ㅋ',
  '��' => 'ㅌ',
  '��' => 'ㅍ',
  '��' => 'ㅎ',
  '��' => 'ㅏ',
  '��' => 'ㅐ',
  '��' => 'ㅑ',
  '��' => 'ㅒ',
  '��' => 'ㅓ',
  '��' => 'ㅔ',
  '��' => 'ㅕ',
  '��' => 'ㅖ',
  '��' => 'ㅗ',
  '��' => 'ㅘ',
  '��' => 'ㅙ',
  '��' => 'ㅚ',
  '��' => 'ㅛ',
  '��' => 'ㅜ',
  '��' => 'ㅝ',
  '��' => 'ㅞ',
  '��' => 'ㅟ',
  '��' => 'ㅠ',
  '��' => 'ㅡ',
  '��' => 'ㅢ',
  '��' => 'ㅣ',
  '��' => 'ㅤ',
  '��' => 'ㅥ',
  '��' => 'ㅦ',
  '��' => 'ㅧ',
  '��' => 'ㅨ',
  '��' => 'ㅩ',
  '��' => 'ㅪ',
  '��' => 'ㅫ',
  '��' => 'ㅬ',
  '��' => 'ㅭ',
  '��' => 'ㅮ',
  '��' => 'ㅯ',
  '��' => 'ㅰ',
  '��' => 'ㅱ',
  '��' => 'ㅲ',
  '��' => 'ㅳ',
  '��' => 'ㅴ',
  '��' => 'ㅵ',
  '��' => 'ㅶ',
  '��' => 'ㅷ',
  '��' => 'ㅸ',
  '��' => 'ㅹ',
  '��' => 'ㅺ',
  '��' => 'ㅻ',
  '��' => 'ㅼ',
  '��' => 'ㅽ',
  '��' => 'ㅾ',
  '��' => 'ㅿ',
  '��' => 'ㆀ',
  '��' => 'ㆁ',
  '��' => 'ㆂ',
  '��' => 'ㆃ',
  '��' => 'ㆄ',
  '��' => 'ㆅ',
  '��' => 'ㆆ',
  '��' => 'ㆇ',
  '��' => 'ㆈ',
  '��' => 'ㆉ',
  '��' => 'ㆊ',
  '��' => 'ㆋ',
  '��' => 'ㆌ',
  '��' => 'ㆍ',
  '��' => 'ㆎ',
  '�A' => '쩇',
  '�B' => '쩈',
  '�C' => '쩉',
  '�D' => '쩊',
  '�E' => '쩋',
  '�F' => '쩎',
  '�G' => '쩏',
  '�H' => '쩑',
  '�I' => '쩒',
  '�J' => '쩓',
  '�K' => '쩕',
  '�L' => '쩖',
  '�M' => '쩗',
  '�N' => '쩘',
  '�O' => '쩙',
  '�P' => '쩚',
  '�Q' => '쩛',
  '�R' => '쩞',
  '�S' => '쩢',
  '�T' => '쩣',
  '�U' => '쩤',
  '�V' => '쩥',
  '�W' => '쩦',
  '�X' => '쩧',
  '�Y' => '쩩',
  '�Z' => '쩪',
  '�a' => '쩫',
  '�b' => '쩬',
  '�c' => '쩭',
  '�d' => '쩮',
  '�e' => '쩯',
  '�f' => '쩰',
  '�g' => '쩱',
  '�h' => '쩲',
  '�i' => '쩳',
  '�j' => '쩴',
  '�k' => '쩵',
  '�l' => '쩶',
  '�m' => '쩷',
  '�n' => '쩸',
  '�o' => '쩹',
  '�p' => '쩺',
  '�q' => '쩻',
  '�r' => '쩼',
  '�s' => '쩾',
  '�t' => '쩿',
  '�u' => '쪀',
  '�v' => '쪁',
  '�w' => '쪂',
  '�x' => '쪃',
  '�y' => '쪅',
  '�z' => '쪆',
  '��' => '쪇',
  '��' => '쪈',
  '��' => '쪉',
  '��' => '쪊',
  '��' => '쪋',
  '��' => '쪌',
  '��' => '쪍',
  '��' => '쪎',
  '��' => '쪏',
  '��' => '쪐',
  '��' => '쪑',
  '��' => '쪒',
  '��' => '쪓',
  '��' => '쪔',
  '��' => '쪕',
  '��' => '쪖',
  '��' => '쪗',
  '��' => '쪙',
  '��' => '쪚',
  '��' => '쪛',
  '��' => '쪜',
  '��' => '쪝',
  '��' => '쪞',
  '��' => '쪟',
  '��' => '쪠',
  '��' => '쪡',
  '��' => '쪢',
  '��' => '쪣',
  '��' => '쪤',
  '��' => '쪥',
  '��' => '쪦',
  '��' => '쪧',
  '��' => 'ⅰ',
  '��' => 'ⅱ',
  '��' => 'ⅲ',
  '��' => 'ⅳ',
  '��' => 'ⅴ',
  '��' => 'ⅵ',
  '��' => 'ⅶ',
  '��' => 'ⅷ',
  '��' => 'ⅸ',
  '��' => 'ⅹ',
  '��' => 'Ⅰ',
  '��' => 'Ⅱ',
  '��' => 'Ⅲ',
  '��' => 'Ⅳ',
  '��' => 'Ⅴ',
  '��' => 'Ⅵ',
  '��' => 'Ⅶ',
  '��' => 'Ⅷ',
  '��' => 'Ⅸ',
  '��' => 'Ⅹ',
  '��' => 'Α',
  '��' => 'Β',
  '��' => 'Γ',
  '��' => 'Δ',
  '��' => 'Ε',
  '��' => 'Ζ',
  '��' => 'Η',
  '��' => 'Θ',
  '��' => 'Ι',
  '��' => 'Κ',
  '��' => 'Λ',
  '��' => 'Μ',
  '��' => 'Ν',
  '��' => 'Ξ',
  '��' => 'Ο',
  '��' => 'Π',
  '��' => 'Ρ',
  '��' => 'Σ',
  '��' => 'Τ',
  '��' => 'Υ',
  '��' => 'Φ',
  '��' => 'Χ',
  '��' => 'Ψ',
  '��' => 'Ω',
  '��' => 'α',
  '��' => 'β',
  '��' => 'γ',
  '��' => 'δ',
  '��' => 'ε',
  '��' => 'ζ',
  '��' => 'η',
  '��' => 'θ',
  '��' => 'ι',
  '��' => 'κ',
  '��' => 'λ',
  '��' => 'μ',
  '��' => 'ν',
  '��' => 'ξ',
  '��' => 'ο',
  '��' => 'π',
  '��' => 'ρ',
  '��' => 'σ',
  '��' => 'τ',
  '��' => 'υ',
  '��' => 'φ',
  '��' => 'χ',
  '��' => 'ψ',
  '��' => 'ω',
  '�A' => '쪨',
  '�B' => '쪩',
  '�C' => '쪪',
  '�D' => '쪫',
  '�E' => '쪬',
  '�F' => '쪭',
  '�G' => '쪮',
  '�H' => '쪯',
  '�I' => '쪰',
  '�J' => '쪱',
  '�K' => '쪲',
  '�L' => '쪳',
  '�M' => '쪴',
  '�N' => '쪵',
  '�O' => '쪶',
  '�P' => '쪷',
  '�Q' => '쪸',
  '�R' => '쪹',
  '�S' => '쪺',
  '�T' => '쪻',
  '�U' => '쪾',
  '�V' => '쪿',
  '�W' => '쫁',
  '�X' => '쫂',
  '�Y' => '쫃',
  '�Z' => '쫅',
  '�a' => '쫆',
  '�b' => '쫇',
  '�c' => '쫈',
  '�d' => '쫉',
  '�e' => '쫊',
  '�f' => '쫋',
  '�g' => '쫎',
  '�h' => '쫐',
  '�i' => '쫒',
  '�j' => '쫔',
  '�k' => '쫕',
  '�l' => '쫖',
  '�m' => '쫗',
  '�n' => '쫚',
  '�o' => '쫛',
  '�p' => '쫜',
  '�q' => '쫝',
  '�r' => '쫞',
  '�s' => '쫟',
  '�t' => '쫡',
  '�u' => '쫢',
  '�v' => '쫣',
  '�w' => '쫤',
  '�x' => '쫥',
  '�y' => '쫦',
  '�z' => '쫧',
  '��' => '쫨',
  '��' => '쫩',
  '��' => '쫪',
  '��' => '쫫',
  '��' => '쫭',
  '��' => '쫮',
  '��' => '쫯',
  '��' => '쫰',
  '��' => '쫱',
  '��' => '쫲',
  '��' => '쫳',
  '��' => '쫵',
  '��' => '쫶',
  '��' => '쫷',
  '��' => '쫸',
  '��' => '쫹',
  '��' => '쫺',
  '��' => '쫻',
  '��' => '쫼',
  '��' => '쫽',
  '��' => '쫾',
  '��' => '쫿',
  '��' => '쬀',
  '��' => '쬁',
  '��' => '쬂',
  '��' => '쬃',
  '��' => '쬄',
  '��' => '쬅',
  '��' => '쬆',
  '��' => '쬇',
  '��' => '쬉',
  '��' => '쬊',
  '��' => '─',
  '��' => '│',
  '��' => '┌',
  '��' => '┐',
  '��' => '┘',
  '��' => '└',
  '��' => '├',
  '��' => '┬',
  '��' => '┤',
  '��' => '┴',
  '��' => '┼',
  '��' => '━',
  '��' => '┃',
  '��' => '┏',
  '��' => '┓',
  '��' => '┛',
  '��' => '┗',
  '��' => '┣',
  '��' => '┳',
  '��' => '┫',
  '��' => '┻',
  '��' => '╋',
  '��' => '┠',
  '��' => '┯',
  '��' => '┨',
  '��' => '┷',
  '��' => '┿',
  '��' => '┝',
  '��' => '┰',
  '��' => '┥',
  '��' => '┸',
  '��' => '╂',
  '��' => '┒',
  '��' => '┑',
  '��' => '┚',
  '��' => '┙',
  '��' => '┖',
  '��' => '┕',
  '��' => '┎',
  '��' => '┍',
  '��' => '┞',
  '��' => '┟',
  '��' => '┡',
  '��' => '┢',
  '��' => '┦',
  '��' => '┧',
  '��' => '┩',
  '��' => '┪',
  '��' => '┭',
  '��' => '┮',
  '��' => '┱',
  '��' => '┲',
  '��' => '┵',
  '��' => '┶',
  '��' => '┹',
  '��' => '┺',
  '��' => '┽',
  '��' => '┾',
  '��' => '╀',
  '��' => '╁',
  '��' => '╃',
  '��' => '╄',
  '��' => '╅',
  '��' => '╆',
  '��' => '╇',
  '��' => '╈',
  '��' => '╉',
  '��' => '╊',
  '�A' => '쬋',
  '�B' => '쬌',
  '�C' => '쬍',
  '�D' => '쬎',
  '�E' => '쬏',
  '�F' => '쬑',
  '�G' => '쬒',
  '�H' => '쬓',
  '�I' => '쬕',
  '�J' => '쬖',
  '�K' => '쬗',
  '�L' => '쬙',
  '�M' => '쬚',
  '�N' => '쬛',
  '�O' => '쬜',
  '�P' => '쬝',
  '�Q' => '쬞',
  '�R' => '쬟',
  '�S' => '쬢',
  '�T' => '쬣',
  '�U' => '쬤',
  '�V' => '쬥',
  '�W' => '쬦',
  '�X' => '쬧',
  '�Y' => '쬨',
  '�Z' => '쬩',
  '�a' => '쬪',
  '�b' => '쬫',
  '�c' => '쬬',
  '�d' => '쬭',
  '�e' => '쬮',
  '�f' => '쬯',
  '�g' => '쬰',
  '�h' => '쬱',
  '�i' => '쬲',
  '�j' => '쬳',
  '�k' => '쬴',
  '�l' => '쬵',
  '�m' => '쬶',
  '�n' => '쬷',
  '�o' => '쬸',
  '�p' => '쬹',
  '�q' => '쬺',
  '�r' => '쬻',
  '�s' => '쬼',
  '�t' => '쬽',
  '�u' => '쬾',
  '�v' => '쬿',
  '�w' => '쭀',
  '�x' => '쭂',
  '�y' => '쭃',
  '�z' => '쭄',
  '��' => '쭅',
  '��' => '쭆',
  '��' => '쭇',
  '��' => '쭊',
  '��' => '쭋',
  '��' => '쭍',
  '��' => '쭎',
  '��' => '쭏',
  '��' => '쭑',
  '��' => '쭒',
  '��' => '쭓',
  '��' => '쭔',
  '��' => '쭕',
  '��' => '쭖',
  '��' => '쭗',
  '��' => '쭚',
  '��' => '쭛',
  '��' => '쭜',
  '��' => '쭞',
  '��' => '쭟',
  '��' => '쭠',
  '��' => '쭡',
  '��' => '쭢',
  '��' => '쭣',
  '��' => '쭥',
  '��' => '쭦',
  '��' => '쭧',
  '��' => '쭨',
  '��' => '쭩',
  '��' => '쭪',
  '��' => '쭫',
  '��' => '쭬',
  '��' => '㎕',
  '��' => '㎖',
  '��' => '㎗',
  '��' => 'ℓ',
  '��' => '㎘',
  '��' => '㏄',
  '��' => '㎣',
  '��' => '㎤',
  '��' => '㎥',
  '��' => '㎦',
  '��' => '㎙',
  '��' => '㎚',
  '��' => '㎛',
  '��' => '㎜',
  '��' => '㎝',
  '��' => '㎞',
  '��' => '㎟',
  '��' => '㎠',
  '��' => '㎡',
  '��' => '㎢',
  '��' => '㏊',
  '��' => '㎍',
  '��' => '㎎',
  '��' => '㎏',
  '��' => '㏏',
  '��' => '㎈',
  '��' => '㎉',
  '��' => '㏈',
  '��' => '㎧',
  '��' => '㎨',
  '��' => '㎰',
  '��' => '㎱',
  '��' => '㎲',
  '��' => '㎳',
  '��' => '㎴',
  '��' => '㎵',
  '��' => '㎶',
  '��' => '㎷',
  '��' => '㎸',
  '��' => '㎹',
  '��' => '㎀',
  '��' => '㎁',
  '��' => '㎂',
  '��' => '㎃',
  '��' => '㎄',
  '��' => '㎺',
  '��' => '㎻',
  '��' => '㎼',
  '��' => '㎽',
  '��' => '㎾',
  '��' => '㎿',
  '��' => '㎐',
  '��' => '㎑',
  '��' => '㎒',
  '��' => '㎓',
  '��' => '㎔',
  '��' => 'Ω',
  '��' => '㏀',
  '��' => '㏁',
  '��' => '㎊',
  '��' => '㎋',
  '��' => '㎌',
  '��' => '㏖',
  '��' => '㏅',
  '��' => '㎭',
  '��' => '㎮',
  '��' => '㎯',
  '��' => '㏛',
  '��' => '㎩',
  '��' => '㎪',
  '��' => '㎫',
  '��' => '㎬',
  '��' => '㏝',
  '��' => '㏐',
  '��' => '㏓',
  '��' => '㏃',
  '��' => '㏉',
  '��' => '㏜',
  '��' => '㏆',
  '�A' => '쭭',
  '�B' => '쭮',
  '�C' => '쭯',
  '�D' => '쭰',
  '�E' => '쭱',
  '�F' => '쭲',
  '�G' => '쭳',
  '�H' => '쭴',
  '�I' => '쭵',
  '�J' => '쭶',
  '�K' => '쭷',
  '�L' => '쭺',
  '�M' => '쭻',
  '�N' => '쭼',
  '�O' => '쭽',
  '�P' => '쭾',
  '�Q' => '쭿',
  '�R' => '쮀',
  '�S' => '쮁',
  '�T' => '쮂',
  '�U' => '쮃',
  '�V' => '쮄',
  '�W' => '쮅',
  '�X' => '쮆',
  '�Y' => '쮇',
  '�Z' => '쮈',
  '�a' => '쮉',
  '�b' => '쮊',
  '�c' => '쮋',
  '�d' => '쮌',
  '�e' => '쮍',
  '�f' => '쮎',
  '�g' => '쮏',
  '�h' => '쮐',
  '�i' => '쮑',
  '�j' => '쮒',
  '�k' => '쮓',
  '�l' => '쮔',
  '�m' => '쮕',
  '�n' => '쮖',
  '�o' => '쮗',
  '�p' => '쮘',
  '�q' => '쮙',
  '�r' => '쮚',
  '�s' => '쮛',
  '�t' => '쮝',
  '�u' => '쮞',
  '�v' => '쮟',
  '�w' => '쮠',
  '�x' => '쮡',
  '�y' => '쮢',
  '�z' => '쮣',
  '��' => '쮤',
  '��' => '쮥',
  '��' => '쮦',
  '��' => '쮧',
  '��' => '쮨',
  '��' => '쮩',
  '��' => '쮪',
  '��' => '쮫',
  '��' => '쮬',
  '��' => '쮭',
  '��' => '쮮',
  '��' => '쮯',
  '��' => '쮰',
  '��' => '쮱',
  '��' => '쮲',
  '��' => '쮳',
  '��' => '쮴',
  '��' => '쮵',
  '��' => '쮶',
  '��' => '쮷',
  '��' => '쮹',
  '��' => '쮺',
  '��' => '쮻',
  '��' => '쮼',
  '��' => '쮽',
  '��' => '쮾',
  '��' => '쮿',
  '��' => '쯀',
  '��' => '쯁',
  '��' => '쯂',
  '��' => '쯃',
  '��' => '쯄',
  '��' => 'Æ',
  '��' => 'Ð',
  '��' => 'ª',
  '��' => 'Ħ',
  '��' => 'IJ',
  '��' => 'Ŀ',
  '��' => 'Ł',
  '��' => 'Ø',
  '��' => 'Œ',
  '��' => 'º',
  '��' => 'Þ',
  '��' => 'Ŧ',
  '��' => 'Ŋ',
  '��' => '㉠',
  '��' => '㉡',
  '��' => '㉢',
  '��' => '㉣',
  '��' => '㉤',
  '��' => '㉥',
  '��' => '㉦',
  '��' => '㉧',
  '��' => '㉨',
  '��' => '㉩',
  '��' => '㉪',
  '��' => '㉫',
  '��' => '㉬',
  '��' => '㉭',
  '��' => '㉮',
  '��' => '㉯',
  '��' => '㉰',
  '��' => '㉱',
  '��' => '㉲',
  '��' => '㉳',
  '��' => '㉴',
  '��' => '㉵',
  '��' => '㉶',
  '��' => '㉷',
  '��' => '㉸',
  '��' => '㉹',
  '��' => '㉺',
  '��' => '㉻',
  '��' => 'ⓐ',
  '��' => 'ⓑ',
  '��' => 'ⓒ',
  '��' => 'ⓓ',
  '��' => 'ⓔ',
  '��' => 'ⓕ',
  '��' => 'ⓖ',
  '��' => 'ⓗ',
  '��' => 'ⓘ',
  '��' => 'ⓙ',
  '��' => 'ⓚ',
  '��' => 'ⓛ',
  '��' => 'ⓜ',
  '��' => 'ⓝ',
  '��' => 'ⓞ',
  '��' => 'ⓟ',
  '��' => 'ⓠ',
  '��' => 'ⓡ',
  '��' => 'ⓢ',
  '��' => 'ⓣ',
  '��' => 'ⓤ',
  '��' => 'ⓥ',
  '��' => 'ⓦ',
  '��' => 'ⓧ',
  '��' => 'ⓨ',
  '��' => 'ⓩ',
  '��' => '①',
  '��' => '②',
  '��' => '③',
  '��' => '④',
  '��' => '⑤',
  '��' => '⑥',
  '��' => '⑦',
  '��' => '⑧',
  '��' => '⑨',
  '��' => '⑩',
  '��' => '⑪',
  '��' => '⑫',
  '��' => '⑬',
  '��' => '⑭',
  '��' => '⑮',
  '��' => '½',
  '��' => '⅓',
  '��' => '⅔',
  '��' => '¼',
  '��' => '¾',
  '��' => '⅛',
  '��' => '⅜',
  '��' => '⅝',
  '��' => '⅞',
  '�A' => '쯅',
  '�B' => '쯆',
  '�C' => '쯇',
  '�D' => '쯈',
  '�E' => '쯉',
  '�F' => '쯊',
  '�G' => '쯋',
  '�H' => '쯌',
  '�I' => '쯍',
  '�J' => '쯎',
  '�K' => '쯏',
  '�L' => '쯐',
  '�M' => '쯑',
  '�N' => '쯒',
  '�O' => '쯓',
  '�P' => '쯕',
  '�Q' => '쯖',
  '�R' => '쯗',
  '�S' => '쯘',
  '�T' => '쯙',
  '�U' => '쯚',
  '�V' => '쯛',
  '�W' => '쯜',
  '�X' => '쯝',
  '�Y' => '쯞',
  '�Z' => '쯟',
  '�a' => '쯠',
  '�b' => '쯡',
  '�c' => '쯢',
  '�d' => '쯣',
  '�e' => '쯥',
  '�f' => '쯦',
  '�g' => '쯨',
  '�h' => '쯪',
  '�i' => '쯫',
  '�j' => '쯬',
  '�k' => '쯭',
  '�l' => '쯮',
  '�m' => '쯯',
  '�n' => '쯰',
  '�o' => '쯱',
  '�p' => '쯲',
  '�q' => '쯳',
  '�r' => '쯴',
  '�s' => '쯵',
  '�t' => '쯶',
  '�u' => '쯷',
  '�v' => '쯸',
  '�w' => '쯹',
  '�x' => '쯺',
  '�y' => '쯻',
  '�z' => '쯼',
  '��' => '쯽',
  '��' => '쯾',
  '��' => '쯿',
  '��' => '찀',
  '��' => '찁',
  '��' => '찂',
  '��' => '찃',
  '��' => '찄',
  '��' => '찅',
  '��' => '찆',
  '��' => '찇',
  '��' => '찈',
  '��' => '찉',
  '��' => '찊',
  '��' => '찋',
  '��' => '찎',
  '��' => '찏',
  '��' => '찑',
  '��' => '찒',
  '��' => '찓',
  '��' => '찕',
  '��' => '찖',
  '��' => '찗',
  '��' => '찘',
  '��' => '찙',
  '��' => '찚',
  '��' => '찛',
  '��' => '찞',
  '��' => '찟',
  '��' => '찠',
  '��' => '찣',
  '��' => '찤',
  '��' => 'æ',
  '��' => 'đ',
  '��' => 'ð',
  '��' => 'ħ',
  '��' => 'ı',
  '��' => 'ij',
  '��' => 'ĸ',
  '��' => 'ŀ',
  '��' => 'ł',
  '��' => 'ø',
  '��' => 'œ',
  '��' => 'ß',
  '��' => 'þ',
  '��' => 'ŧ',
  '��' => 'ŋ',
  '��' => 'ʼn',
  '��' => '㈀',
  '��' => '㈁',
  '��' => '㈂',
  '��' => '㈃',
  '��' => '㈄',
  '��' => '㈅',
  '��' => '㈆',
  '��' => '㈇',
  '��' => '㈈',
  '��' => '㈉',
  '��' => '㈊',
  '��' => '㈋',
  '��' => '㈌',
  '��' => '㈍',
  '��' => '㈎',
  '��' => '㈏',
  '��' => '㈐',
  '��' => '㈑',
  '��' => '㈒',
  '��' => '㈓',
  '��' => '㈔',
  '��' => '㈕',
  '��' => '㈖',
  '��' => '㈗',
  '��' => '㈘',
  '��' => '㈙',
  '��' => '㈚',
  '��' => '㈛',
  '��' => '⒜',
  '��' => '⒝',
  '��' => '⒞',
  '��' => '⒟',
  '��' => '⒠',
  '��' => '⒡',
  '��' => '⒢',
  '��' => '⒣',
  '��' => '⒤',
  '��' => '⒥',
  '��' => '⒦',
  '��' => '⒧',
  '��' => '⒨',
  '��' => '⒩',
  '��' => '⒪',
  '��' => '⒫',
  '��' => '⒬',
  '��' => '⒭',
  '��' => '⒮',
  '��' => '⒯',
  '��' => '⒰',
  '��' => '⒱',
  '��' => '⒲',
  '��' => '⒳',
  '��' => '⒴',
  '��' => '⒵',
  '��' => '⑴',
  '��' => '⑵',
  '��' => '⑶',
  '��' => '⑷',
  '��' => '⑸',
  '��' => '⑹',
  '��' => '⑺',
  '��' => '⑻',
  '��' => '⑼',
  '��' => '⑽',
  '��' => '⑾',
  '��' => '⑿',
  '��' => '⒀',
  '��' => '⒁',
  '��' => '⒂',
  '��' => '¹',
  '��' => '²',
  '��' => '³',
  '��' => '⁴',
  '��' => 'ⁿ',
  '��' => '₁',
  '��' => '₂',
  '��' => '₃',
  '��' => '₄',
  '�A' => '찥',
  '�B' => '찦',
  '�C' => '찪',
  '�D' => '찫',
  '�E' => '찭',
  '�F' => '찯',
  '�G' => '찱',
  '�H' => '찲',
  '�I' => '찳',
  '�J' => '찴',
  '�K' => '찵',
  '�L' => '찶',
  '�M' => '찷',
  '�N' => '찺',
  '�O' => '찿',
  '�P' => '챀',
  '�Q' => '챁',
  '�R' => '챂',
  '�S' => '챃',
  '�T' => '챆',
  '�U' => '챇',
  '�V' => '챉',
  '�W' => '챊',
  '�X' => '챋',
  '�Y' => '챍',
  '�Z' => '챎',
  '�a' => '챏',
  '�b' => '챐',
  '�c' => '챑',
  '�d' => '챒',
  '�e' => '챓',
  '�f' => '챖',
  '�g' => '챚',
  '�h' => '챛',
  '�i' => '챜',
  '�j' => '챝',
  '�k' => '챞',
  '�l' => '챟',
  '�m' => '챡',
  '�n' => '챢',
  '�o' => '챣',
  '�p' => '챥',
  '�q' => '챧',
  '�r' => '챩',
  '�s' => '챪',
  '�t' => '챫',
  '�u' => '챬',
  '�v' => '챭',
  '�w' => '챮',
  '�x' => '챯',
  '�y' => '챱',
  '�z' => '챲',
  '��' => '챳',
  '��' => '챴',
  '��' => '챶',
  '��' => '챷',
  '��' => '챸',
  '��' => '챹',
  '��' => '챺',
  '��' => '챻',
  '��' => '챼',
  '��' => '챽',
  '��' => '챾',
  '��' => '챿',
  '��' => '첀',
  '��' => '첁',
  '��' => '첂',
  '��' => '첃',
  '��' => '첄',
  '��' => '첅',
  '��' => '첆',
  '��' => '첇',
  '��' => '첈',
  '��' => '첉',
  '��' => '첊',
  '��' => '첋',
  '��' => '첌',
  '��' => '첍',
  '��' => '첎',
  '��' => '첏',
  '��' => '첐',
  '��' => '첑',
  '��' => '첒',
  '��' => '첓',
  '��' => 'ぁ',
  '��' => 'あ',
  '��' => 'ぃ',
  '��' => 'い',
  '��' => 'ぅ',
  '��' => 'う',
  '��' => 'ぇ',
  '��' => 'え',
  '��' => 'ぉ',
  '��' => 'お',
  '��' => 'か',
  '��' => 'が',
  '��' => 'き',
  '��' => 'ぎ',
  '��' => 'く',
  '��' => 'ぐ',
  '��' => 'け',
  '��' => 'げ',
  '��' => 'こ',
  '��' => 'ご',
  '��' => 'さ',
  '��' => 'ざ',
  '��' => 'し',
  '��' => 'じ',
  '��' => 'す',
  '��' => 'ず',
  '��' => 'せ',
  '��' => 'ぜ',
  '��' => 'そ',
  '��' => 'ぞ',
  '��' => 'た',
  '��' => 'だ',
  '��' => 'ち',
  '��' => 'ぢ',
  '��' => 'っ',
  '��' => 'つ',
  '��' => 'づ',
  '��' => 'て',
  '��' => 'で',
  '��' => 'と',
  '��' => 'ど',
  '��' => 'な',
  '��' => 'に',
  '��' => 'ぬ',
  '��' => 'ね',
  '��' => 'の',
  '��' => 'は',
  '��' => 'ば',
  '��' => 'ぱ',
  '��' => 'ひ',
  '��' => 'び',
  '��' => 'ぴ',
  '��' => 'ふ',
  '��' => 'ぶ',
  '��' => 'ぷ',
  '��' => 'へ',
  '��' => 'べ',
  '��' => 'ぺ',
  '��' => 'ほ',
  '��' => 'ぼ',
  '��' => 'ぽ',
  '��' => 'ま',
  '��' => 'み',
  '��' => 'む',
  '��' => 'め',
  '��' => 'も',
  '��' => 'ゃ',
  '��' => 'や',
  '��' => 'ゅ',
  '��' => 'ゆ',
  '��' => 'ょ',
  '��' => 'よ',
  '��' => 'ら',
  '��' => 'り',
  '��' => 'る',
  '��' => 'れ',
  '��' => 'ろ',
  '��' => 'ゎ',
  '��' => 'わ',
  '��' => 'ゐ',
  '��' => 'ゑ',
  '��' => 'を',
  '��' => 'ん',
  '�A' => '첔',
  '�B' => '첕',
  '�C' => '첖',
  '�D' => '첗',
  '�E' => '첚',
  '�F' => '첛',
  '�G' => '첝',
  '�H' => '첞',
  '�I' => '첟',
  '�J' => '첡',
  '�K' => '첢',
  '�L' => '첣',
  '�M' => '첤',
  '�N' => '첥',
  '�O' => '첦',
  '�P' => '첧',
  '�Q' => '첪',
  '�R' => '첮',
  '�S' => '첯',
  '�T' => '첰',
  '�U' => '첱',
  '�V' => '첲',
  '�W' => '첳',
  '�X' => '첶',
  '�Y' => '첷',
  '�Z' => '첹',
  '�a' => '첺',
  '�b' => '첻',
  '�c' => '첽',
  '�d' => '첾',
  '�e' => '첿',
  '�f' => '쳀',
  '�g' => '쳁',
  '�h' => '쳂',
  '�i' => '쳃',
  '�j' => '쳆',
  '�k' => '쳈',
  '�l' => '쳊',
  '�m' => '쳋',
  '�n' => '쳌',
  '�o' => '쳍',
  '�p' => '쳎',
  '�q' => '쳏',
  '�r' => '쳑',
  '�s' => '쳒',
  '�t' => '쳓',
  '�u' => '쳕',
  '�v' => '쳖',
  '�w' => '쳗',
  '�x' => '쳘',
  '�y' => '쳙',
  '�z' => '쳚',
  '��' => '쳛',
  '��' => '쳜',
  '��' => '쳝',
  '��' => '쳞',
  '��' => '쳟',
  '��' => '쳠',
  '��' => '쳡',
  '��' => '쳢',
  '��' => '쳣',
  '��' => '쳥',
  '��' => '쳦',
  '��' => '쳧',
  '��' => '쳨',
  '��' => '쳩',
  '��' => '쳪',
  '��' => '쳫',
  '��' => '쳭',
  '��' => '쳮',
  '��' => '쳯',
  '��' => '쳱',
  '��' => '쳲',
  '��' => '쳳',
  '��' => '쳴',
  '��' => '쳵',
  '��' => '쳶',
  '��' => '쳷',
  '��' => '쳸',
  '��' => '쳹',
  '��' => '쳺',
  '��' => '쳻',
  '��' => '쳼',
  '��' => '쳽',
  '��' => 'ァ',
  '��' => 'ア',
  '��' => 'ィ',
  '��' => 'イ',
  '��' => 'ゥ',
  '��' => 'ウ',
  '��' => 'ェ',
  '��' => 'エ',
  '��' => 'ォ',
  '��' => 'オ',
  '��' => 'カ',
  '��' => 'ガ',
  '��' => 'キ',
  '��' => 'ギ',
  '��' => 'ク',
  '��' => 'グ',
  '��' => 'ケ',
  '��' => 'ゲ',
  '��' => 'コ',
  '��' => 'ゴ',
  '��' => 'サ',
  '��' => 'ザ',
  '��' => 'シ',
  '��' => 'ジ',
  '��' => 'ス',
  '��' => 'ズ',
  '��' => 'セ',
  '��' => 'ゼ',
  '��' => 'ソ',
  '��' => 'ゾ',
  '��' => 'タ',
  '��' => 'ダ',
  '��' => 'チ',
  '��' => 'ヂ',
  '��' => 'ッ',
  '��' => 'ツ',
  '��' => 'ヅ',
  '��' => 'テ',
  '��' => 'デ',
  '��' => 'ト',
  '��' => 'ド',
  '��' => 'ナ',
  '��' => 'ニ',
  '��' => 'ヌ',
  '��' => 'ネ',
  '��' => 'ノ',
  '��' => 'ハ',
  '��' => 'バ',
  '��' => 'パ',
  '��' => 'ヒ',
  '��' => 'ビ',
  '��' => 'ピ',
  '��' => 'フ',
  '��' => 'ブ',
  '��' => 'プ',
  '��' => 'ヘ',
  '��' => 'ベ',
  '��' => 'ペ',
  '��' => 'ホ',
  '��' => 'ボ',
  '��' => 'ポ',
  '��' => 'マ',
  '��' => 'ミ',
  '��' => 'ム',
  '��' => 'メ',
  '��' => 'モ',
  '��' => 'ャ',
  '��' => 'ヤ',
  '��' => 'ュ',
  '��' => 'ユ',
  '��' => 'ョ',
  '��' => 'ヨ',
  '��' => 'ラ',
  '��' => 'リ',
  '��' => 'ル',
  '��' => 'レ',
  '��' => 'ロ',
  '��' => 'ヮ',
  '��' => 'ワ',
  '��' => 'ヰ',
  '��' => 'ヱ',
  '��' => 'ヲ',
  '��' => 'ン',
  '��' => 'ヴ',
  '��' => 'ヵ',
  '��' => 'ヶ',
  '�A' => '쳾',
  '�B' => '쳿',
  '�C' => '촀',
  '�D' => '촂',
  '�E' => '촃',
  '�F' => '촄',
  '�G' => '촅',
  '�H' => '촆',
  '�I' => '촇',
  '�J' => '촊',
  '�K' => '촋',
  '�L' => '촍',
  '�M' => '촎',
  '�N' => '촏',
  '�O' => '촑',
  '�P' => '촒',
  '�Q' => '촓',
  '�R' => '촔',
  '�S' => '촕',
  '�T' => '촖',
  '�U' => '촗',
  '�V' => '촚',
  '�W' => '촜',
  '�X' => '촞',
  '�Y' => '촟',
  '�Z' => '촠',
  '�a' => '촡',
  '�b' => '촢',
  '�c' => '촣',
  '�d' => '촥',
  '�e' => '촦',
  '�f' => '촧',
  '�g' => '촩',
  '�h' => '촪',
  '�i' => '촫',
  '�j' => '촭',
  '�k' => '촮',
  '�l' => '촯',
  '�m' => '촰',
  '�n' => '촱',
  '�o' => '촲',
  '�p' => '촳',
  '�q' => '촴',
  '�r' => '촵',
  '�s' => '촶',
  '�t' => '촷',
  '�u' => '촸',
  '�v' => '촺',
  '�w' => '촻',
  '�x' => '촼',
  '�y' => '촽',
  '�z' => '촾',
  '��' => '촿',
  '��' => '쵀',
  '��' => '쵁',
  '��' => '쵂',
  '��' => '쵃',
  '��' => '쵄',
  '��' => '쵅',
  '��' => '쵆',
  '��' => '쵇',
  '��' => '쵈',
  '��' => '쵉',
  '��' => '쵊',
  '��' => '쵋',
  '��' => '쵌',
  '��' => '쵍',
  '��' => '쵎',
  '��' => '쵏',
  '��' => '쵐',
  '��' => '쵑',
  '��' => '쵒',
  '��' => '쵓',
  '��' => '쵔',
  '��' => '쵕',
  '��' => '쵖',
  '��' => '쵗',
  '��' => '쵘',
  '��' => '쵙',
  '��' => '쵚',
  '��' => '쵛',
  '��' => '쵝',
  '��' => '쵞',
  '��' => '쵟',
  '��' => 'А',
  '��' => 'Б',
  '��' => 'В',
  '��' => 'Г',
  '��' => 'Д',
  '��' => 'Е',
  '��' => 'Ё',
  '��' => 'Ж',
  '��' => 'З',
  '��' => 'И',
  '��' => 'Й',
  '��' => 'К',
  '��' => 'Л',
  '��' => 'М',
  '��' => 'Н',
  '��' => 'О',
  '��' => 'П',
  '��' => 'Р',
  '��' => 'С',
  '��' => 'Т',
  '��' => 'У',
  '��' => 'Ф',
  '��' => 'Х',
  '��' => 'Ц',
  '��' => 'Ч',
  '��' => 'Ш',
  '��' => 'Щ',
  '��' => 'Ъ',
  '��' => 'Ы',
  '��' => 'Ь',
  '��' => 'Э',
  '��' => 'Ю',
  '��' => 'Я',
  '��' => 'а',
  '��' => 'б',
  '��' => 'в',
  '��' => 'г',
  '��' => 'д',
  '��' => 'е',
  '��' => 'ё',
  '��' => 'ж',
  '��' => 'з',
  '��' => 'и',
  '��' => 'й',
  '��' => 'к',
  '��' => 'л',
  '��' => 'м',
  '��' => 'н',
  '��' => 'о',
  '��' => 'п',
  '��' => 'р',
  '��' => 'с',
  '��' => 'т',
  '��' => 'у',
  '��' => 'ф',
  '��' => 'х',
  '��' => 'ц',
  '��' => 'ч',
  '��' => 'ш',
  '��' => 'щ',
  '��' => 'ъ',
  '��' => 'ы',
  '��' => 'ь',
  '��' => 'э',
  '��' => 'ю',
  '��' => 'я',
  '�A' => '쵡',
  '�B' => '쵢',
  '�C' => '쵣',
  '�D' => '쵥',
  '�E' => '쵦',
  '�F' => '쵧',
  '�G' => '쵨',
  '�H' => '쵩',
  '�I' => '쵪',
  '�J' => '쵫',
  '�K' => '쵮',
  '�L' => '쵰',
  '�M' => '쵲',
  '�N' => '쵳',
  '�O' => '쵴',
  '�P' => '쵵',
  '�Q' => '쵶',
  '�R' => '쵷',
  '�S' => '쵹',
  '�T' => '쵺',
  '�U' => '쵻',
  '�V' => '쵼',
  '�W' => '쵽',
  '�X' => '쵾',
  '�Y' => '쵿',
  '�Z' => '춀',
  '�a' => '춁',
  '�b' => '춂',
  '�c' => '춃',
  '�d' => '춄',
  '�e' => '춅',
  '�f' => '춆',
  '�g' => '춇',
  '�h' => '춉',
  '�i' => '춊',
  '�j' => '춋',
  '�k' => '춌',
  '�l' => '춍',
  '�m' => '춎',
  '�n' => '춏',
  '�o' => '춐',
  '�p' => '춑',
  '�q' => '춒',
  '�r' => '춓',
  '�s' => '춖',
  '�t' => '춗',
  '�u' => '춙',
  '�v' => '춚',
  '�w' => '춛',
  '�x' => '춝',
  '�y' => '춞',
  '�z' => '춟',
  '��' => '춠',
  '��' => '춡',
  '��' => '춢',
  '��' => '춣',
  '��' => '춦',
  '��' => '춨',
  '��' => '춪',
  '��' => '춫',
  '��' => '춬',
  '��' => '춭',
  '��' => '춮',
  '��' => '춯',
  '��' => '춱',
  '��' => '춲',
  '��' => '춳',
  '��' => '춴',
  '��' => '춵',
  '��' => '춶',
  '��' => '춷',
  '��' => '춸',
  '��' => '춹',
  '��' => '춺',
  '��' => '춻',
  '��' => '춼',
  '��' => '춽',
  '��' => '춾',
  '��' => '춿',
  '��' => '췀',
  '��' => '췁',
  '��' => '췂',
  '��' => '췃',
  '��' => '췅',
  '�A' => '췆',
  '�B' => '췇',
  '�C' => '췈',
  '�D' => '췉',
  '�E' => '췊',
  '�F' => '췋',
  '�G' => '췍',
  '�H' => '췎',
  '�I' => '췏',
  '�J' => '췑',
  '�K' => '췒',
  '�L' => '췓',
  '�M' => '췔',
  '�N' => '췕',
  '�O' => '췖',
  '�P' => '췗',
  '�Q' => '췘',
  '�R' => '췙',
  '�S' => '췚',
  '�T' => '췛',
  '�U' => '췜',
  '�V' => '췝',
  '�W' => '췞',
  '�X' => '췟',
  '�Y' => '췠',
  '�Z' => '췡',
  '�a' => '췢',
  '�b' => '췣',
  '�c' => '췤',
  '�d' => '췥',
  '�e' => '췦',
  '�f' => '췧',
  '�g' => '췩',
  '�h' => '췪',
  '�i' => '췫',
  '�j' => '췭',
  '�k' => '췮',
  '�l' => '췯',
  '�m' => '췱',
  '�n' => '췲',
  '�o' => '췳',
  '�p' => '췴',
  '�q' => '췵',
  '�r' => '췶',
  '�s' => '췷',
  '�t' => '췺',
  '�u' => '췼',
  '�v' => '췾',
  '�w' => '췿',
  '�x' => '츀',
  '�y' => '츁',
  '�z' => '츂',
  '��' => '츃',
  '��' => '츅',
  '��' => '츆',
  '��' => '츇',
  '��' => '츉',
  '��' => '츊',
  '��' => '츋',
  '��' => '츍',
  '��' => '츎',
  '��' => '츏',
  '��' => '츐',
  '��' => '츑',
  '��' => '츒',
  '��' => '츓',
  '��' => '츕',
  '��' => '츖',
  '��' => '츗',
  '��' => '츘',
  '��' => '츚',
  '��' => '츛',
  '��' => '츜',
  '��' => '츝',
  '��' => '츞',
  '��' => '츟',
  '��' => '츢',
  '��' => '츣',
  '��' => '츥',
  '��' => '츦',
  '��' => '츧',
  '��' => '츩',
  '��' => '츪',
  '��' => '츫',
  '�A' => '츬',
  '�B' => '츭',
  '�C' => '츮',
  '�D' => '츯',
  '�E' => '츲',
  '�F' => '츴',
  '�G' => '츶',
  '�H' => '츷',
  '�I' => '츸',
  '�J' => '츹',
  '�K' => '츺',
  '�L' => '츻',
  '�M' => '츼',
  '�N' => '츽',
  '�O' => '츾',
  '�P' => '츿',
  '�Q' => '칀',
  '�R' => '칁',
  '�S' => '칂',
  '�T' => '칃',
  '�U' => '칄',
  '�V' => '칅',
  '�W' => '칆',
  '�X' => '칇',
  '�Y' => '칈',
  '�Z' => '칉',
  '�a' => '칊',
  '�b' => '칋',
  '�c' => '칌',
  '�d' => '칍',
  '�e' => '칎',
  '�f' => '칏',
  '�g' => '칐',
  '�h' => '칑',
  '�i' => '칒',
  '�j' => '칓',
  '�k' => '칔',
  '�l' => '칕',
  '�m' => '칖',
  '�n' => '칗',
  '�o' => '칚',
  '�p' => '칛',
  '�q' => '칝',
  '�r' => '칞',
  '�s' => '칢',
  '�t' => '칣',
  '�u' => '칤',
  '�v' => '칥',
  '�w' => '칦',
  '�x' => '칧',
  '�y' => '칪',
  '�z' => '칬',
  '��' => '칮',
  '��' => '칯',
  '��' => '칰',
  '��' => '칱',
  '��' => '칲',
  '��' => '칳',
  '��' => '칶',
  '��' => '칷',
  '��' => '칹',
  '��' => '칺',
  '��' => '칻',
  '��' => '칽',
  '��' => '칾',
  '��' => '칿',
  '��' => '캀',
  '��' => '캁',
  '��' => '캂',
  '��' => '캃',
  '��' => '캆',
  '��' => '캈',
  '��' => '캊',
  '��' => '캋',
  '��' => '캌',
  '��' => '캍',
  '��' => '캎',
  '��' => '캏',
  '��' => '캒',
  '��' => '캓',
  '��' => '캕',
  '��' => '캖',
  '��' => '캗',
  '��' => '캙',
  '�A' => '캚',
  '�B' => '캛',
  '�C' => '캜',
  '�D' => '캝',
  '�E' => '캞',
  '�F' => '캟',
  '�G' => '캢',
  '�H' => '캦',
  '�I' => '캧',
  '�J' => '캨',
  '�K' => '캩',
  '�L' => '캪',
  '�M' => '캫',
  '�N' => '캮',
  '�O' => '캯',
  '�P' => '캰',
  '�Q' => '캱',
  '�R' => '캲',
  '�S' => '캳',
  '�T' => '캴',
  '�U' => '캵',
  '�V' => '캶',
  '�W' => '캷',
  '�X' => '캸',
  '�Y' => '캹',
  '�Z' => '캺',
  '�a' => '캻',
  '�b' => '캼',
  '�c' => '캽',
  '�d' => '캾',
  '�e' => '캿',
  '�f' => '컀',
  '�g' => '컂',
  '�h' => '컃',
  '�i' => '컄',
  '�j' => '컅',
  '�k' => '컆',
  '�l' => '컇',
  '�m' => '컈',
  '�n' => '컉',
  '�o' => '컊',
  '�p' => '컋',
  '�q' => '컌',
  '�r' => '컍',
  '�s' => '컎',
  '�t' => '컏',
  '�u' => '컐',
  '�v' => '컑',
  '�w' => '컒',
  '�x' => '컓',
  '�y' => '컔',
  '�z' => '컕',
  '��' => '컖',
  '��' => '컗',
  '��' => '컘',
  '��' => '컙',
  '��' => '컚',
  '��' => '컛',
  '��' => '컜',
  '��' => '컝',
  '��' => '컞',
  '��' => '컟',
  '��' => '컠',
  '��' => '컡',
  '��' => '컢',
  '��' => '컣',
  '��' => '컦',
  '��' => '컧',
  '��' => '컩',
  '��' => '컪',
  '��' => '컭',
  '��' => '컮',
  '��' => '컯',
  '��' => '컰',
  '��' => '컱',
  '��' => '컲',
  '��' => '컳',
  '��' => '컶',
  '��' => '컺',
  '��' => '컻',
  '��' => '컼',
  '��' => '컽',
  '��' => '컾',
  '��' => '컿',
  '��' => '가',
  '��' => '각',
  '��' => '간',
  '��' => '갇',
  '��' => '갈',
  '��' => '갉',
  '��' => '갊',
  '��' => '감',
  '��' => '갑',
  '��' => '값',
  '��' => '갓',
  '��' => '갔',
  '��' => '강',
  '��' => '갖',
  '��' => '갗',
  '��' => '같',
  '��' => '갚',
  '��' => '갛',
  '��' => '개',
  '��' => '객',
  '��' => '갠',
  '��' => '갤',
  '��' => '갬',
  '��' => '갭',
  '��' => '갯',
  '��' => '갰',
  '��' => '갱',
  '��' => '갸',
  '��' => '갹',
  '��' => '갼',
  '��' => '걀',
  '��' => '걋',
  '��' => '걍',
  '��' => '걔',
  '��' => '걘',
  '��' => '걜',
  '��' => '거',
  '��' => '걱',
  '��' => '건',
  '��' => '걷',
  '��' => '걸',
  '��' => '걺',
  '��' => '검',
  '��' => '겁',
  '��' => '것',
  '��' => '겄',
  '��' => '겅',
  '��' => '겆',
  '��' => '겉',
  '��' => '겊',
  '��' => '겋',
  '��' => '게',
  '��' => '겐',
  '��' => '겔',
  '��' => '겜',
  '��' => '겝',
  '��' => '겟',
  '��' => '겠',
  '��' => '겡',
  '��' => '겨',
  '��' => '격',
  '��' => '겪',
  '��' => '견',
  '��' => '겯',
  '��' => '결',
  '��' => '겸',
  '��' => '겹',
  '��' => '겻',
  '��' => '겼',
  '��' => '경',
  '��' => '곁',
  '��' => '계',
  '��' => '곈',
  '��' => '곌',
  '��' => '곕',
  '��' => '곗',
  '��' => '고',
  '��' => '곡',
  '��' => '곤',
  '��' => '곧',
  '��' => '골',
  '��' => '곪',
  '��' => '곬',
  '��' => '곯',
  '��' => '곰',
  '��' => '곱',
  '��' => '곳',
  '��' => '공',
  '��' => '곶',
  '��' => '과',
  '��' => '곽',
  '��' => '관',
  '��' => '괄',
  '��' => '괆',
  '�A' => '켂',
  '�B' => '켃',
  '�C' => '켅',
  '�D' => '켆',
  '�E' => '켇',
  '�F' => '켉',
  '�G' => '켊',
  '�H' => '켋',
  '�I' => '켌',
  '�J' => '켍',
  '�K' => '켎',
  '�L' => '켏',
  '�M' => '켒',
  '�N' => '켔',
  '�O' => '켖',
  '�P' => '켗',
  '�Q' => '켘',
  '�R' => '켙',
  '�S' => '켚',
  '�T' => '켛',
  '�U' => '켝',
  '�V' => '켞',
  '�W' => '켟',
  '�X' => '켡',
  '�Y' => '켢',
  '�Z' => '켣',
  '�a' => '켥',
  '�b' => '켦',
  '�c' => '켧',
  '�d' => '켨',
  '�e' => '켩',
  '�f' => '켪',
  '�g' => '켫',
  '�h' => '켮',
  '�i' => '켲',
  '�j' => '켳',
  '�k' => '켴',
  '�l' => '켵',
  '�m' => '켶',
  '�n' => '켷',
  '�o' => '켹',
  '�p' => '켺',
  '�q' => '켻',
  '�r' => '켼',
  '�s' => '켽',
  '�t' => '켾',
  '�u' => '켿',
  '�v' => '콀',
  '�w' => '콁',
  '�x' => '콂',
  '�y' => '콃',
  '�z' => '콄',
  '��' => '콅',
  '��' => '콆',
  '��' => '콇',
  '��' => '콈',
  '��' => '콉',
  '��' => '콊',
  '��' => '콋',
  '��' => '콌',
  '��' => '콍',
  '��' => '콎',
  '��' => '콏',
  '��' => '콐',
  '��' => '콑',
  '��' => '콒',
  '��' => '콓',
  '��' => '콖',
  '��' => '콗',
  '��' => '콙',
  '��' => '콚',
  '��' => '콛',
  '��' => '콝',
  '��' => '콞',
  '��' => '콟',
  '��' => '콠',
  '��' => '콡',
  '��' => '콢',
  '��' => '콣',
  '��' => '콦',
  '��' => '콨',
  '��' => '콪',
  '��' => '콫',
  '��' => '콬',
  '��' => '괌',
  '��' => '괍',
  '��' => '괏',
  '��' => '광',
  '��' => '괘',
  '��' => '괜',
  '��' => '괠',
  '��' => '괩',
  '��' => '괬',
  '��' => '괭',
  '��' => '괴',
  '��' => '괵',
  '��' => '괸',
  '��' => '괼',
  '��' => '굄',
  '��' => '굅',
  '��' => '굇',
  '��' => '굉',
  '��' => '교',
  '��' => '굔',
  '��' => '굘',
  '��' => '굡',
  '��' => '굣',
  '��' => '구',
  '��' => '국',
  '��' => '군',
  '��' => '굳',
  '��' => '굴',
  '��' => '굵',
  '��' => '굶',
  '��' => '굻',
  '��' => '굼',
  '��' => '굽',
  '��' => '굿',
  '��' => '궁',
  '��' => '궂',
  '��' => '궈',
  '��' => '궉',
  '��' => '권',
  '��' => '궐',
  '��' => '궜',
  '��' => '궝',
  '��' => '궤',
  '��' => '궷',
  '��' => '귀',
  '��' => '귁',
  '��' => '귄',
  '��' => '귈',
  '��' => '귐',
  '��' => '귑',
  '��' => '귓',
  '��' => '규',
  '��' => '균',
  '��' => '귤',
  '��' => '그',
  '��' => '극',
  '��' => '근',
  '��' => '귿',
  '��' => '글',
  '��' => '긁',
  '��' => '금',
  '��' => '급',
  '��' => '긋',
  '��' => '긍',
  '��' => '긔',
  '��' => '기',
  '��' => '긱',
  '��' => '긴',
  '��' => '긷',
  '��' => '길',
  '��' => '긺',
  '��' => '김',
  '��' => '깁',
  '��' => '깃',
  '��' => '깅',
  '��' => '깆',
  '��' => '깊',
  '��' => '까',
  '��' => '깍',
  '��' => '깎',
  '��' => '깐',
  '��' => '깔',
  '��' => '깖',
  '��' => '깜',
  '��' => '깝',
  '��' => '깟',
  '��' => '깠',
  '��' => '깡',
  '��' => '깥',
  '��' => '깨',
  '��' => '깩',
  '��' => '깬',
  '��' => '깰',
  '��' => '깸',
  '�A' => '콭',
  '�B' => '콮',
  '�C' => '콯',
  '�D' => '콲',
  '�E' => '콳',
  '�F' => '콵',
  '�G' => '콶',
  '�H' => '콷',
  '�I' => '콹',
  '�J' => '콺',
  '�K' => '콻',
  '�L' => '콼',
  '�M' => '콽',
  '�N' => '콾',
  '�O' => '콿',
  '�P' => '쾁',
  '�Q' => '쾂',
  '�R' => '쾃',
  '�S' => '쾄',
  '�T' => '쾆',
  '�U' => '쾇',
  '�V' => '쾈',
  '�W' => '쾉',
  '�X' => '쾊',
  '�Y' => '쾋',
  '�Z' => '쾍',
  '�a' => '쾎',
  '�b' => '쾏',
  '�c' => '쾐',
  '�d' => '쾑',
  '�e' => '쾒',
  '�f' => '쾓',
  '�g' => '쾔',
  '�h' => '쾕',
  '�i' => '쾖',
  '�j' => '쾗',
  '�k' => '쾘',
  '�l' => '쾙',
  '�m' => '쾚',
  '�n' => '쾛',
  '�o' => '쾜',
  '�p' => '쾝',
  '�q' => '쾞',
  '�r' => '쾟',
  '�s' => '쾠',
  '�t' => '쾢',
  '�u' => '쾣',
  '�v' => '쾤',
  '�w' => '쾥',
  '�x' => '쾦',
  '�y' => '쾧',
  '�z' => '쾩',
  '��' => '쾪',
  '��' => '쾫',
  '��' => '쾬',
  '��' => '쾭',
  '��' => '쾮',
  '��' => '쾯',
  '��' => '쾱',
  '��' => '쾲',
  '��' => '쾳',
  '��' => '쾴',
  '��' => '쾵',
  '��' => '쾶',
  '��' => '쾷',
  '��' => '쾸',
  '��' => '쾹',
  '��' => '쾺',
  '��' => '쾻',
  '��' => '쾼',
  '��' => '쾽',
  '��' => '쾾',
  '��' => '쾿',
  '��' => '쿀',
  '��' => '쿁',
  '��' => '쿂',
  '��' => '쿃',
  '��' => '쿅',
  '��' => '쿆',
  '��' => '쿇',
  '��' => '쿈',
  '��' => '쿉',
  '��' => '쿊',
  '��' => '쿋',
  '��' => '깹',
  '��' => '깻',
  '��' => '깼',
  '��' => '깽',
  '��' => '꺄',
  '��' => '꺅',
  '��' => '꺌',
  '��' => '꺼',
  '��' => '꺽',
  '��' => '꺾',
  '��' => '껀',
  '��' => '껄',
  '��' => '껌',
  '��' => '껍',
  '��' => '껏',
  '��' => '껐',
  '��' => '껑',
  '��' => '께',
  '��' => '껙',
  '��' => '껜',
  '��' => '껨',
  '��' => '껫',
  '��' => '껭',
  '��' => '껴',
  '��' => '껸',
  '��' => '껼',
  '��' => '꼇',
  '��' => '꼈',
  '��' => '꼍',
  '��' => '꼐',
  '��' => '꼬',
  '��' => '꼭',
  '��' => '꼰',
  '��' => '꼲',
  '��' => '꼴',
  '��' => '꼼',
  '��' => '꼽',
  '��' => '꼿',
  '��' => '꽁',
  '��' => '꽂',
  '��' => '꽃',
  '��' => '꽈',
  '��' => '꽉',
  '��' => '꽐',
  '��' => '꽜',
  '��' => '꽝',
  '��' => '꽤',
  '��' => '꽥',
  '��' => '꽹',
  '��' => '꾀',
  '��' => '꾄',
  '��' => '꾈',
  '��' => '꾐',
  '��' => '꾑',
  '��' => '꾕',
  '��' => '꾜',
  '��' => '꾸',
  '��' => '꾹',
  '��' => '꾼',
  '��' => '꿀',
  '��' => '꿇',
  '��' => '꿈',
  '��' => '꿉',
  '��' => '꿋',
  '��' => '꿍',
  '��' => '꿎',
  '��' => '꿔',
  '��' => '꿜',
  '��' => '꿨',
  '��' => '꿩',
  '��' => '꿰',
  '��' => '꿱',
  '��' => '꿴',
  '��' => '꿸',
  '��' => '뀀',
  '��' => '뀁',
  '��' => '뀄',
  '��' => '뀌',
  '��' => '뀐',
  '��' => '뀔',
  '��' => '뀜',
  '��' => '뀝',
  '��' => '뀨',
  '��' => '끄',
  '��' => '끅',
  '��' => '끈',
  '��' => '끊',
  '��' => '끌',
  '��' => '끎',
  '��' => '끓',
  '��' => '끔',
  '��' => '끕',
  '��' => '끗',
  '��' => '끙',
  '�A' => '쿌',
  '�B' => '쿍',
  '�C' => '쿎',
  '�D' => '쿏',
  '�E' => '쿐',
  '�F' => '쿑',
  '�G' => '쿒',
  '�H' => '쿓',
  '�I' => '쿔',
  '�J' => '쿕',
  '�K' => '쿖',
  '�L' => '쿗',
  '�M' => '쿘',
  '�N' => '쿙',
  '�O' => '쿚',
  '�P' => '쿛',
  '�Q' => '쿜',
  '�R' => '쿝',
  '�S' => '쿞',
  '�T' => '쿟',
  '�U' => '쿢',
  '�V' => '쿣',
  '�W' => '쿥',
  '�X' => '쿦',
  '�Y' => '쿧',
  '�Z' => '쿩',
  '�a' => '쿪',
  '�b' => '쿫',
  '�c' => '쿬',
  '�d' => '쿭',
  '�e' => '쿮',
  '�f' => '쿯',
  '�g' => '쿲',
  '�h' => '쿴',
  '�i' => '쿶',
  '�j' => '쿷',
  '�k' => '쿸',
  '�l' => '쿹',
  '�m' => '쿺',
  '�n' => '쿻',
  '�o' => '쿽',
  '�p' => '쿾',
  '�q' => '쿿',
  '�r' => '퀁',
  '�s' => '퀂',
  '�t' => '퀃',
  '�u' => '퀅',
  '�v' => '퀆',
  '�w' => '퀇',
  '�x' => '퀈',
  '�y' => '퀉',
  '�z' => '퀊',
  '��' => '퀋',
  '��' => '퀌',
  '��' => '퀍',
  '��' => '퀎',
  '��' => '퀏',
  '��' => '퀐',
  '��' => '퀒',
  '��' => '퀓',
  '��' => '퀔',
  '��' => '퀕',
  '��' => '퀖',
  '��' => '퀗',
  '��' => '퀙',
  '��' => '퀚',
  '��' => '퀛',
  '��' => '퀜',
  '��' => '퀝',
  '��' => '퀞',
  '��' => '퀟',
  '��' => '퀠',
  '��' => '퀡',
  '��' => '퀢',
  '��' => '퀣',
  '��' => '퀤',
  '��' => '퀥',
  '��' => '퀦',
  '��' => '퀧',
  '��' => '퀨',
  '��' => '퀩',
  '��' => '퀪',
  '��' => '퀫',
  '��' => '퀬',
  '��' => '끝',
  '��' => '끼',
  '��' => '끽',
  '��' => '낀',
  '��' => '낄',
  '��' => '낌',
  '��' => '낍',
  '��' => '낏',
  '��' => '낑',
  '��' => '나',
  '��' => '낙',
  '��' => '낚',
  '��' => '난',
  '��' => '낟',
  '��' => '날',
  '��' => '낡',
  '��' => '낢',
  '��' => '남',
  '��' => '납',
  '��' => '낫',
  '��' => '났',
  '��' => '낭',
  '��' => '낮',
  '��' => '낯',
  '��' => '낱',
  '��' => '낳',
  '��' => '내',
  '��' => '낵',
  '��' => '낸',
  '��' => '낼',
  '��' => '냄',
  '��' => '냅',
  '��' => '냇',
  '��' => '냈',
  '��' => '냉',
  '��' => '냐',
  '��' => '냑',
  '��' => '냔',
  '��' => '냘',
  '��' => '냠',
  '��' => '냥',
  '��' => '너',
  '��' => '넉',
  '��' => '넋',
  '��' => '넌',
  '��' => '널',
  '��' => '넒',
  '��' => '넓',
  '��' => '넘',
  '��' => '넙',
  '��' => '넛',
  '��' => '넜',
  '��' => '넝',
  '��' => '넣',
  '��' => '네',
  '��' => '넥',
  '��' => '넨',
  '��' => '넬',
  '��' => '넴',
  '��' => '넵',
  '��' => '넷',
  '��' => '넸',
  '��' => '넹',
  '��' => '녀',
  '��' => '녁',
  '��' => '년',
  '��' => '녈',
  '��' => '념',
  '��' => '녑',
  '��' => '녔',
  '��' => '녕',
  '��' => '녘',
  '��' => '녜',
  '��' => '녠',
  '��' => '노',
  '��' => '녹',
  '��' => '논',
  '��' => '놀',
  '��' => '놂',
  '��' => '놈',
  '��' => '놉',
  '��' => '놋',
  '��' => '농',
  '��' => '높',
  '��' => '놓',
  '��' => '놔',
  '��' => '놘',
  '��' => '놜',
  '��' => '놨',
  '��' => '뇌',
  '��' => '뇐',
  '��' => '뇔',
  '��' => '뇜',
  '��' => '뇝',
  '�A' => '퀮',
  '�B' => '퀯',
  '�C' => '퀰',
  '�D' => '퀱',
  '�E' => '퀲',
  '�F' => '퀳',
  '�G' => '퀶',
  '�H' => '퀷',
  '�I' => '퀹',
  '�J' => '퀺',
  '�K' => '퀻',
  '�L' => '퀽',
  '�M' => '퀾',
  '�N' => '퀿',
  '�O' => '큀',
  '�P' => '큁',
  '�Q' => '큂',
  '�R' => '큃',
  '�S' => '큆',
  '�T' => '큈',
  '�U' => '큊',
  '�V' => '큋',
  '�W' => '큌',
  '�X' => '큍',
  '�Y' => '큎',
  '�Z' => '큏',
  '�a' => '큑',
  '�b' => '큒',
  '�c' => '큓',
  '�d' => '큕',
  '�e' => '큖',
  '�f' => '큗',
  '�g' => '큙',
  '�h' => '큚',
  '�i' => '큛',
  '�j' => '큜',
  '�k' => '큝',
  '�l' => '큞',
  '�m' => '큟',
  '�n' => '큡',
  '�o' => '큢',
  '�p' => '큣',
  '�q' => '큤',
  '�r' => '큥',
  '�s' => '큦',
  '�t' => '큧',
  '�u' => '큨',
  '�v' => '큩',
  '�w' => '큪',
  '�x' => '큫',
  '�y' => '큮',
  '�z' => '큯',
  '��' => '큱',
  '��' => '큲',
  '��' => '큳',
  '��' => '큵',
  '��' => '큶',
  '��' => '큷',
  '��' => '큸',
  '��' => '큹',
  '��' => '큺',
  '��' => '큻',
  '��' => '큾',
  '��' => '큿',
  '��' => '킀',
  '��' => '킂',
  '��' => '킃',
  '��' => '킄',
  '��' => '킅',
  '��' => '킆',
  '��' => '킇',
  '��' => '킈',
  '��' => '킉',
  '��' => '킊',
  '��' => '킋',
  '��' => '킌',
  '��' => '킍',
  '��' => '킎',
  '��' => '킏',
  '��' => '킐',
  '��' => '킑',
  '��' => '킒',
  '��' => '킓',
  '��' => '킔',
  '��' => '뇟',
  '��' => '뇨',
  '��' => '뇩',
  '��' => '뇬',
  '��' => '뇰',
  '��' => '뇹',
  '��' => '뇻',
  '��' => '뇽',
  '��' => '누',
  '��' => '눅',
  '��' => '눈',
  '��' => '눋',
  '��' => '눌',
  '��' => '눔',
  '��' => '눕',
  '��' => '눗',
  '��' => '눙',
  '��' => '눠',
  '��' => '눴',
  '��' => '눼',
  '��' => '뉘',
  '��' => '뉜',
  '��' => '뉠',
  '��' => '뉨',
  '��' => '뉩',
  '��' => '뉴',
  '��' => '뉵',
  '��' => '뉼',
  '��' => '늄',
  '��' => '늅',
  '��' => '늉',
  '��' => '느',
  '��' => '늑',
  '��' => '는',
  '��' => '늘',
  '��' => '늙',
  '��' => '늚',
  '��' => '늠',
  '��' => '늡',
  '��' => '늣',
  '��' => '능',
  '��' => '늦',
  '��' => '늪',
  '��' => '늬',
  '��' => '늰',
  '��' => '늴',
  '��' => '니',
  '��' => '닉',
  '��' => '닌',
  '��' => '닐',
  '��' => '닒',
  '��' => '님',
  '��' => '닙',
  '��' => '닛',
  '��' => '닝',
  '��' => '닢',
  '��' => '다',
  '��' => '닥',
  '��' => '닦',
  '��' => '단',
  '��' => '닫',
  '��' => '달',
  '��' => '닭',
  '��' => '닮',
  '��' => '닯',
  '��' => '닳',
  '��' => '담',
  '��' => '답',
  '��' => '닷',
  '��' => '닸',
  '��' => '당',
  '��' => '닺',
  '��' => '닻',
  '��' => '닿',
  '��' => '대',
  '��' => '댁',
  '��' => '댄',
  '��' => '댈',
  '��' => '댐',
  '��' => '댑',
  '��' => '댓',
  '��' => '댔',
  '��' => '댕',
  '��' => '댜',
  '��' => '더',
  '��' => '덕',
  '��' => '덖',
  '��' => '던',
  '��' => '덛',
  '��' => '덜',
  '��' => '덞',
  '��' => '덟',
  '��' => '덤',
  '��' => '덥',
  '�A' => '킕',
  '�B' => '킖',
  '�C' => '킗',
  '�D' => '킘',
  '�E' => '킙',
  '�F' => '킚',
  '�G' => '킛',
  '�H' => '킜',
  '�I' => '킝',
  '�J' => '킞',
  '�K' => '킟',
  '�L' => '킠',
  '�M' => '킡',
  '�N' => '킢',
  '�O' => '킣',
  '�P' => '킦',
  '�Q' => '킧',
  '�R' => '킩',
  '�S' => '킪',
  '�T' => '킫',
  '�U' => '킭',
  '�V' => '킮',
  '�W' => '킯',
  '�X' => '킰',
  '�Y' => '킱',
  '�Z' => '킲',
  '�a' => '킳',
  '�b' => '킶',
  '�c' => '킸',
  '�d' => '킺',
  '�e' => '킻',
  '�f' => '킼',
  '�g' => '킽',
  '�h' => '킾',
  '�i' => '킿',
  '�j' => '탂',
  '�k' => '탃',
  '�l' => '탅',
  '�m' => '탆',
  '�n' => '탇',
  '�o' => '탊',
  '�p' => '탋',
  '�q' => '탌',
  '�r' => '탍',
  '�s' => '탎',
  '�t' => '탏',
  '�u' => '탒',
  '�v' => '탖',
  '�w' => '탗',
  '�x' => '탘',
  '�y' => '탙',
  '�z' => '탚',
  '��' => '탛',
  '��' => '탞',
  '��' => '탟',
  '��' => '탡',
  '��' => '탢',
  '��' => '탣',
  '��' => '탥',
  '��' => '탦',
  '��' => '탧',
  '��' => '탨',
  '��' => '탩',
  '��' => '탪',
  '��' => '탫',
  '��' => '탮',
  '��' => '탲',
  '��' => '탳',
  '��' => '탴',
  '��' => '탵',
  '��' => '탶',
  '��' => '탷',
  '��' => '탹',
  '��' => '탺',
  '��' => '탻',
  '��' => '탼',
  '��' => '탽',
  '��' => '탾',
  '��' => '탿',
  '��' => '턀',
  '��' => '턁',
  '��' => '턂',
  '��' => '턃',
  '��' => '턄',
  '��' => '덧',
  '��' => '덩',
  '��' => '덫',
  '��' => '덮',
  '��' => '데',
  '��' => '덱',
  '��' => '덴',
  '��' => '델',
  '��' => '뎀',
  '��' => '뎁',
  '��' => '뎃',
  '��' => '뎄',
  '��' => '뎅',
  '��' => '뎌',
  '��' => '뎐',
  '��' => '뎔',
  '��' => '뎠',
  '��' => '뎡',
  '��' => '뎨',
  '��' => '뎬',
  '��' => '도',
  '��' => '독',
  '��' => '돈',
  '��' => '돋',
  '��' => '돌',
  '��' => '돎',
  '��' => '돐',
  '��' => '돔',
  '��' => '돕',
  '��' => '돗',
  '��' => '동',
  '��' => '돛',
  '��' => '돝',
  '��' => '돠',
  '��' => '돤',
  '��' => '돨',
  '��' => '돼',
  '��' => '됐',
  '��' => '되',
  '��' => '된',
  '��' => '될',
  '��' => '됨',
  '��' => '됩',
  '��' => '됫',
  '��' => '됴',
  '��' => '두',
  '��' => '둑',
  '��' => '둔',
  '��' => '둘',
  '��' => '둠',
  '��' => '둡',
  '��' => '둣',
  '��' => '둥',
  '��' => '둬',
  '��' => '뒀',
  '��' => '뒈',
  '��' => '뒝',
  '��' => '뒤',
  '��' => '뒨',
  '��' => '뒬',
  '��' => '뒵',
  '��' => '뒷',
  '��' => '뒹',
  '��' => '듀',
  '��' => '듄',
  '��' => '듈',
  '��' => '듐',
  '��' => '듕',
  '��' => '드',
  '��' => '득',
  '��' => '든',
  '��' => '듣',
  '��' => '들',
  '��' => '듦',
  '��' => '듬',
  '��' => '듭',
  '��' => '듯',
  '��' => '등',
  '��' => '듸',
  '��' => '디',
  '��' => '딕',
  '��' => '딘',
  '��' => '딛',
  '��' => '딜',
  '��' => '딤',
  '��' => '딥',
  '��' => '딧',
  '��' => '딨',
  '��' => '딩',
  '��' => '딪',
  '��' => '따',
  '��' => '딱',
  '��' => '딴',
  '��' => '딸',
  '�A' => '턅',
  '�B' => '턆',
  '�C' => '턇',
  '�D' => '턈',
  '�E' => '턉',
  '�F' => '턊',
  '�G' => '턋',
  '�H' => '턌',
  '�I' => '턎',
  '�J' => '턏',
  '�K' => '턐',
  '�L' => '턑',
  '�M' => '턒',
  '�N' => '턓',
  '�O' => '턔',
  '�P' => '턕',
  '�Q' => '턖',
  '�R' => '턗',
  '�S' => '턘',
  '�T' => '턙',
  '�U' => '턚',
  '�V' => '턛',
  '�W' => '턜',
  '�X' => '턝',
  '�Y' => '턞',
  '�Z' => '턟',
  '�a' => '턠',
  '�b' => '턡',
  '�c' => '턢',
  '�d' => '턣',
  '�e' => '턤',
  '�f' => '턥',
  '�g' => '턦',
  '�h' => '턧',
  '�i' => '턨',
  '�j' => '턩',
  '�k' => '턪',
  '�l' => '턫',
  '�m' => '턬',
  '�n' => '턭',
  '�o' => '턮',
  '�p' => '턯',
  '�q' => '턲',
  '�r' => '턳',
  '�s' => '턵',
  '�t' => '턶',
  '�u' => '턷',
  '�v' => '턹',
  '�w' => '턻',
  '�x' => '턼',
  '�y' => '턽',
  '�z' => '턾',
  '��' => '턿',
  '��' => '텂',
  '��' => '텆',
  '��' => '텇',
  '��' => '텈',
  '��' => '텉',
  '��' => '텊',
  '��' => '텋',
  '��' => '텎',
  '��' => '텏',
  '��' => '텑',
  '��' => '텒',
  '��' => '텓',
  '��' => '텕',
  '��' => '텖',
  '��' => '텗',
  '��' => '텘',
  '��' => '텙',
  '��' => '텚',
  '��' => '텛',
  '��' => '텞',
  '��' => '텠',
  '��' => '텢',
  '��' => '텣',
  '��' => '텤',
  '��' => '텥',
  '��' => '텦',
  '��' => '텧',
  '��' => '텩',
  '��' => '텪',
  '��' => '텫',
  '��' => '텭',
  '��' => '땀',
  '��' => '땁',
  '��' => '땃',
  '��' => '땄',
  '��' => '땅',
  '��' => '땋',
  '��' => '때',
  '��' => '땍',
  '��' => '땐',
  '��' => '땔',
  '��' => '땜',
  '��' => '땝',
  '��' => '땟',
  '��' => '땠',
  '��' => '땡',
  '��' => '떠',
  '��' => '떡',
  '��' => '떤',
  '��' => '떨',
  '��' => '떪',
  '��' => '떫',
  '��' => '떰',
  '��' => '떱',
  '��' => '떳',
  '��' => '떴',
  '��' => '떵',
  '��' => '떻',
  '��' => '떼',
  '��' => '떽',
  '��' => '뗀',
  '��' => '뗄',
  '��' => '뗌',
  '��' => '뗍',
  '��' => '뗏',
  '��' => '뗐',
  '��' => '뗑',
  '��' => '뗘',
  '��' => '뗬',
  '��' => '또',
  '��' => '똑',
  '��' => '똔',
  '��' => '똘',
  '��' => '똥',
  '��' => '똬',
  '��' => '똴',
  '��' => '뙈',
  '��' => '뙤',
  '��' => '뙨',
  '��' => '뚜',
  '��' => '뚝',
  '��' => '뚠',
  '��' => '뚤',
  '��' => '뚫',
  '��' => '뚬',
  '��' => '뚱',
  '��' => '뛔',
  '��' => '뛰',
  '��' => '뛴',
  '��' => '뛸',
  '��' => '뜀',
  '��' => '뜁',
  '��' => '뜅',
  '��' => '뜨',
  '��' => '뜩',
  '��' => '뜬',
  '��' => '뜯',
  '��' => '뜰',
  '��' => '뜸',
  '��' => '뜹',
  '��' => '뜻',
  '��' => '띄',
  '��' => '띈',
  '��' => '띌',
  '��' => '띔',
  '��' => '띕',
  '��' => '띠',
  '��' => '띤',
  '��' => '띨',
  '��' => '띰',
  '��' => '띱',
  '��' => '띳',
  '��' => '띵',
  '��' => '라',
  '��' => '락',
  '��' => '란',
  '��' => '랄',
  '��' => '람',
  '��' => '랍',
  '��' => '랏',
  '��' => '랐',
  '��' => '랑',
  '��' => '랒',
  '��' => '랖',
  '��' => '랗',
  '�A' => '텮',
  '�B' => '텯',
  '�C' => '텰',
  '�D' => '텱',
  '�E' => '텲',
  '�F' => '텳',
  '�G' => '텴',
  '�H' => '텵',
  '�I' => '텶',
  '�J' => '텷',
  '�K' => '텸',
  '�L' => '텹',
  '�M' => '텺',
  '�N' => '텻',
  '�O' => '텽',
  '�P' => '텾',
  '�Q' => '텿',
  '�R' => '톀',
  '�S' => '톁',
  '�T' => '톂',
  '�U' => '톃',
  '�V' => '톅',
  '�W' => '톆',
  '�X' => '톇',
  '�Y' => '톉',
  '�Z' => '톊',
  '�a' => '톋',
  '�b' => '톌',
  '�c' => '톍',
  '�d' => '톎',
  '�e' => '톏',
  '�f' => '톐',
  '�g' => '톑',
  '�h' => '톒',
  '�i' => '톓',
  '�j' => '톔',
  '�k' => '톕',
  '�l' => '톖',
  '�m' => '톗',
  '�n' => '톘',
  '�o' => '톙',
  '�p' => '톚',
  '�q' => '톛',
  '�r' => '톜',
  '�s' => '톝',
  '�t' => '톞',
  '�u' => '톟',
  '�v' => '톢',
  '�w' => '톣',
  '�x' => '톥',
  '�y' => '톦',
  '�z' => '톧',
  '��' => '톩',
  '��' => '톪',
  '��' => '톫',
  '��' => '톬',
  '��' => '톭',
  '��' => '톮',
  '��' => '톯',
  '��' => '톲',
  '��' => '톴',
  '��' => '톶',
  '��' => '톷',
  '��' => '톸',
  '��' => '톹',
  '��' => '톻',
  '��' => '톽',
  '��' => '톾',
  '��' => '톿',
  '��' => '퇁',
  '��' => '퇂',
  '��' => '퇃',
  '��' => '퇄',
  '��' => '퇅',
  '��' => '퇆',
  '��' => '퇇',
  '��' => '퇈',
  '��' => '퇉',
  '��' => '퇊',
  '��' => '퇋',
  '��' => '퇌',
  '��' => '퇍',
  '��' => '퇎',
  '��' => '퇏',
  '��' => '래',
  '��' => '랙',
  '��' => '랜',
  '��' => '랠',
  '��' => '램',
  '��' => '랩',
  '��' => '랫',
  '��' => '랬',
  '��' => '랭',
  '��' => '랴',
  '��' => '략',
  '��' => '랸',
  '��' => '럇',
  '��' => '량',
  '��' => '러',
  '��' => '럭',
  '��' => '런',
  '��' => '럴',
  '��' => '럼',
  '��' => '럽',
  '��' => '럿',
  '��' => '렀',
  '��' => '렁',
  '��' => '렇',
  '��' => '레',
  '��' => '렉',
  '��' => '렌',
  '��' => '렐',
  '��' => '렘',
  '��' => '렙',
  '��' => '렛',
  '��' => '렝',
  '��' => '려',
  '��' => '력',
  '��' => '련',
  '��' => '렬',
  '��' => '렴',
  '��' => '렵',
  '��' => '렷',
  '��' => '렸',
  '��' => '령',
  '��' => '례',
  '��' => '롄',
  '��' => '롑',
  '��' => '롓',
  '��' => '로',
  '��' => '록',
  '��' => '론',
  '��' => '롤',
  '��' => '롬',
  '��' => '롭',
  '��' => '롯',
  '��' => '롱',
  '��' => '롸',
  '��' => '롼',
  '��' => '뢍',
  '��' => '뢨',
  '��' => '뢰',
  '��' => '뢴',
  '��' => '뢸',
  '��' => '룀',
  '��' => '룁',
  '��' => '룃',
  '��' => '룅',
  '��' => '료',
  '��' => '룐',
  '��' => '룔',
  '��' => '룝',
  '��' => '룟',
  '��' => '룡',
  '��' => '루',
  '��' => '룩',
  '��' => '룬',
  '��' => '룰',
  '��' => '룸',
  '��' => '룹',
  '��' => '룻',
  '��' => '룽',
  '��' => '뤄',
  '��' => '뤘',
  '��' => '뤠',
  '��' => '뤼',
  '��' => '뤽',
  '��' => '륀',
  '��' => '륄',
  '��' => '륌',
  '��' => '륏',
  '��' => '륑',
  '��' => '류',
  '��' => '륙',
  '��' => '륜',
  '��' => '률',
  '��' => '륨',
  '��' => '륩',
  '�A' => '퇐',
  '�B' => '퇑',
  '�C' => '퇒',
  '�D' => '퇓',
  '�E' => '퇔',
  '�F' => '퇕',
  '�G' => '퇖',
  '�H' => '퇗',
  '�I' => '퇙',
  '�J' => '퇚',
  '�K' => '퇛',
  '�L' => '퇜',
  '�M' => '퇝',
  '�N' => '퇞',
  '�O' => '퇟',
  '�P' => '퇠',
  '�Q' => '퇡',
  '�R' => '퇢',
  '�S' => '퇣',
  '�T' => '퇤',
  '�U' => '퇥',
  '�V' => '퇦',
  '�W' => '퇧',
  '�X' => '퇨',
  '�Y' => '퇩',
  '�Z' => '퇪',
  '�a' => '퇫',
  '�b' => '퇬',
  '�c' => '퇭',
  '�d' => '퇮',
  '�e' => '퇯',
  '�f' => '퇰',
  '�g' => '퇱',
  '�h' => '퇲',
  '�i' => '퇳',
  '�j' => '퇵',
  '�k' => '퇶',
  '�l' => '퇷',
  '�m' => '퇹',
  '�n' => '퇺',
  '�o' => '퇻',
  '�p' => '퇼',
  '�q' => '퇽',
  '�r' => '퇾',
  '�s' => '퇿',
  '�t' => '툀',
  '�u' => '툁',
  '�v' => '툂',
  '�w' => '툃',
  '�x' => '툄',
  '�y' => '툅',
  '�z' => '툆',
  '��' => '툈',
  '��' => '툊',
  '��' => '툋',
  '��' => '툌',
  '��' => '툍',
  '��' => '툎',
  '��' => '툏',
  '��' => '툑',
  '��' => '툒',
  '��' => '툓',
  '��' => '툔',
  '��' => '툕',
  '��' => '툖',
  '��' => '툗',
  '��' => '툘',
  '��' => '툙',
  '��' => '툚',
  '��' => '툛',
  '��' => '툜',
  '��' => '툝',
  '��' => '툞',
  '��' => '툟',
  '��' => '툠',
  '��' => '툡',
  '��' => '툢',
  '��' => '툣',
  '��' => '툤',
  '��' => '툥',
  '��' => '툦',
  '��' => '툧',
  '��' => '툨',
  '��' => '툩',
  '��' => '륫',
  '��' => '륭',
  '��' => '르',
  '��' => '륵',
  '��' => '른',
  '��' => '를',
  '��' => '름',
  '��' => '릅',
  '��' => '릇',
  '��' => '릉',
  '��' => '릊',
  '��' => '릍',
  '��' => '릎',
  '��' => '리',
  '��' => '릭',
  '��' => '린',
  '��' => '릴',
  '��' => '림',
  '��' => '립',
  '��' => '릿',
  '��' => '링',
  '��' => '마',
  '��' => '막',
  '��' => '만',
  '��' => '많',
  '��' => '맏',
  '��' => '말',
  '��' => '맑',
  '��' => '맒',
  '��' => '맘',
  '��' => '맙',
  '��' => '맛',
  '��' => '망',
  '��' => '맞',
  '��' => '맡',
  '��' => '맣',
  '��' => '매',
  '��' => '맥',
  '��' => '맨',
  '��' => '맬',
  '��' => '맴',
  '��' => '맵',
  '��' => '맷',
  '��' => '맸',
  '��' => '맹',
  '��' => '맺',
  '��' => '먀',
  '��' => '먁',
  '��' => '먈',
  '��' => '먕',
  '��' => '머',
  '��' => '먹',
  '��' => '먼',
  '��' => '멀',
  '��' => '멂',
  '��' => '멈',
  '��' => '멉',
  '��' => '멋',
  '��' => '멍',
  '��' => '멎',
  '��' => '멓',
  '��' => '메',
  '��' => '멕',
  '��' => '멘',
  '��' => '멜',
  '��' => '멤',
  '��' => '멥',
  '��' => '멧',
  '��' => '멨',
  '��' => '멩',
  '��' => '며',
  '��' => '멱',
  '��' => '면',
  '��' => '멸',
  '��' => '몃',
  '��' => '몄',
  '��' => '명',
  '��' => '몇',
  '��' => '몌',
  '��' => '모',
  '��' => '목',
  '��' => '몫',
  '��' => '몬',
  '��' => '몰',
  '��' => '몲',
  '��' => '몸',
  '��' => '몹',
  '��' => '못',
  '��' => '몽',
  '��' => '뫄',
  '��' => '뫈',
  '��' => '뫘',
  '��' => '뫙',
  '��' => '뫼',
  '�A' => '툪',
  '�B' => '툫',
  '�C' => '툮',
  '�D' => '툯',
  '�E' => '툱',
  '�F' => '툲',
  '�G' => '툳',
  '�H' => '툵',
  '�I' => '툶',
  '�J' => '툷',
  '�K' => '툸',
  '�L' => '툹',
  '�M' => '툺',
  '�N' => '툻',
  '�O' => '툾',
  '�P' => '퉀',
  '�Q' => '퉂',
  '�R' => '퉃',
  '�S' => '퉄',
  '�T' => '퉅',
  '�U' => '퉆',
  '�V' => '퉇',
  '�W' => '퉉',
  '�X' => '퉊',
  '�Y' => '퉋',
  '�Z' => '퉌',
  '�a' => '퉍',
  '�b' => '퉎',
  '�c' => '퉏',
  '�d' => '퉐',
  '�e' => '퉑',
  '�f' => '퉒',
  '�g' => '퉓',
  '�h' => '퉔',
  '�i' => '퉕',
  '�j' => '퉖',
  '�k' => '퉗',
  '�l' => '퉘',
  '�m' => '퉙',
  '�n' => '퉚',
  '�o' => '퉛',
  '�p' => '퉝',
  '�q' => '퉞',
  '�r' => '퉟',
  '�s' => '퉠',
  '�t' => '퉡',
  '�u' => '퉢',
  '�v' => '퉣',
  '�w' => '퉥',
  '�x' => '퉦',
  '�y' => '퉧',
  '�z' => '퉨',
  '��' => '퉩',
  '��' => '퉪',
  '��' => '퉫',
  '��' => '퉬',
  '��' => '퉭',
  '��' => '퉮',
  '��' => '퉯',
  '��' => '퉰',
  '��' => '퉱',
  '��' => '퉲',
  '��' => '퉳',
  '��' => '퉴',
  '��' => '퉵',
  '��' => '퉶',
  '��' => '퉷',
  '��' => '퉸',
  '��' => '퉹',
  '��' => '퉺',
  '��' => '퉻',
  '��' => '퉼',
  '��' => '퉽',
  '��' => '퉾',
  '��' => '퉿',
  '��' => '튂',
  '��' => '튃',
  '��' => '튅',
  '��' => '튆',
  '��' => '튇',
  '��' => '튉',
  '��' => '튊',
  '��' => '튋',
  '��' => '튌',
  '��' => '묀',
  '��' => '묄',
  '��' => '묍',
  '��' => '묏',
  '��' => '묑',
  '��' => '묘',
  '��' => '묜',
  '��' => '묠',
  '��' => '묩',
  '��' => '묫',
  '��' => '무',
  '��' => '묵',
  '��' => '묶',
  '��' => '문',
  '��' => '묻',
  '��' => '물',
  '��' => '묽',
  '��' => '묾',
  '��' => '뭄',
  '��' => '뭅',
  '��' => '뭇',
  '��' => '뭉',
  '��' => '뭍',
  '��' => '뭏',
  '��' => '뭐',
  '��' => '뭔',
  '��' => '뭘',
  '��' => '뭡',
  '��' => '뭣',
  '��' => '뭬',
  '��' => '뮈',
  '��' => '뮌',
  '��' => '뮐',
  '��' => '뮤',
  '��' => '뮨',
  '��' => '뮬',
  '��' => '뮴',
  '��' => '뮷',
  '��' => '므',
  '��' => '믄',
  '��' => '믈',
  '��' => '믐',
  '��' => '믓',
  '��' => '미',
  '��' => '믹',
  '��' => '민',
  '��' => '믿',
  '��' => '밀',
  '��' => '밂',
  '��' => '밈',
  '��' => '밉',
  '��' => '밋',
  '��' => '밌',
  '��' => '밍',
  '��' => '및',
  '��' => '밑',
  '��' => '바',
  '��' => '박',
  '��' => '밖',
  '��' => '밗',
  '��' => '반',
  '��' => '받',
  '��' => '발',
  '��' => '밝',
  '��' => '밞',
  '��' => '밟',
  '��' => '밤',
  '��' => '밥',
  '��' => '밧',
  '��' => '방',
  '��' => '밭',
  '��' => '배',
  '��' => '백',
  '��' => '밴',
  '��' => '밸',
  '��' => '뱀',
  '��' => '뱁',
  '��' => '뱃',
  '��' => '뱄',
  '��' => '뱅',
  '��' => '뱉',
  '��' => '뱌',
  '��' => '뱍',
  '��' => '뱐',
  '��' => '뱝',
  '��' => '버',
  '��' => '벅',
  '��' => '번',
  '��' => '벋',
  '��' => '벌',
  '��' => '벎',
  '��' => '범',
  '��' => '법',
  '��' => '벗',
  '�A' => '튍',
  '�B' => '튎',
  '�C' => '튏',
  '�D' => '튒',
  '�E' => '튓',
  '�F' => '튔',
  '�G' => '튖',
  '�H' => '튗',
  '�I' => '튘',
  '�J' => '튙',
  '�K' => '튚',
  '�L' => '튛',
  '�M' => '튝',
  '�N' => '튞',
  '�O' => '튟',
  '�P' => '튡',
  '�Q' => '튢',
  '�R' => '튣',
  '�S' => '튥',
  '�T' => '튦',
  '�U' => '튧',
  '�V' => '튨',
  '�W' => '튩',
  '�X' => '튪',
  '�Y' => '튫',
  '�Z' => '튭',
  '�a' => '튮',
  '�b' => '튯',
  '�c' => '튰',
  '�d' => '튲',
  '�e' => '튳',
  '�f' => '튴',
  '�g' => '튵',
  '�h' => '튶',
  '�i' => '튷',
  '�j' => '튺',
  '�k' => '튻',
  '�l' => '튽',
  '�m' => '튾',
  '�n' => '틁',
  '�o' => '틃',
  '�p' => '틄',
  '�q' => '틅',
  '�r' => '틆',
  '�s' => '틇',
  '�t' => '틊',
  '�u' => '틌',
  '�v' => '틍',
  '�w' => '틎',
  '�x' => '틏',
  '�y' => '틐',
  '�z' => '틑',
  '��' => '틒',
  '��' => '틓',
  '��' => '틕',
  '��' => '틖',
  '��' => '틗',
  '��' => '틙',
  '��' => '틚',
  '��' => '틛',
  '��' => '틝',
  '��' => '틞',
  '��' => '틟',
  '��' => '틠',
  '��' => '틡',
  '��' => '틢',
  '��' => '틣',
  '��' => '틦',
  '��' => '틧',
  '��' => '틨',
  '��' => '틩',
  '��' => '틪',
  '��' => '틫',
  '��' => '틬',
  '��' => '틭',
  '��' => '틮',
  '��' => '틯',
  '��' => '틲',
  '��' => '틳',
  '��' => '틵',
  '��' => '틶',
  '��' => '틷',
  '��' => '틹',
  '��' => '틺',
  '��' => '벙',
  '��' => '벚',
  '��' => '베',
  '��' => '벡',
  '��' => '벤',
  '��' => '벧',
  '��' => '벨',
  '��' => '벰',
  '��' => '벱',
  '��' => '벳',
  '��' => '벴',
  '��' => '벵',
  '��' => '벼',
  '��' => '벽',
  '��' => '변',
  '��' => '별',
  '��' => '볍',
  '��' => '볏',
  '��' => '볐',
  '��' => '병',
  '��' => '볕',
  '��' => '볘',
  '��' => '볜',
  '��' => '보',
  '��' => '복',
  '��' => '볶',
  '��' => '본',
  '��' => '볼',
  '��' => '봄',
  '��' => '봅',
  '��' => '봇',
  '��' => '봉',
  '��' => '봐',
  '��' => '봔',
  '��' => '봤',
  '��' => '봬',
  '��' => '뵀',
  '��' => '뵈',
  '��' => '뵉',
  '��' => '뵌',
  '��' => '뵐',
  '��' => '뵘',
  '��' => '뵙',
  '��' => '뵤',
  '��' => '뵨',
  '��' => '부',
  '��' => '북',
  '��' => '분',
  '��' => '붇',
  '��' => '불',
  '��' => '붉',
  '��' => '붊',
  '��' => '붐',
  '��' => '붑',
  '��' => '붓',
  '��' => '붕',
  '��' => '붙',
  '��' => '붚',
  '��' => '붜',
  '��' => '붤',
  '��' => '붰',
  '��' => '붸',
  '��' => '뷔',
  '��' => '뷕',
  '��' => '뷘',
  '��' => '뷜',
  '��' => '뷩',
  '��' => '뷰',
  '��' => '뷴',
  '��' => '뷸',
  '��' => '븀',
  '��' => '븃',
  '��' => '븅',
  '��' => '브',
  '��' => '븍',
  '��' => '븐',
  '��' => '블',
  '��' => '븜',
  '��' => '븝',
  '��' => '븟',
  '��' => '비',
  '��' => '빅',
  '��' => '빈',
  '��' => '빌',
  '��' => '빎',
  '��' => '빔',
  '��' => '빕',
  '��' => '빗',
  '��' => '빙',
  '��' => '빚',
  '��' => '빛',
  '��' => '빠',
  '��' => '빡',
  '��' => '빤',
  '�A' => '틻',
  '�B' => '틼',
  '�C' => '틽',
  '�D' => '틾',
  '�E' => '틿',
  '�F' => '팂',
  '�G' => '팄',
  '�H' => '팆',
  '�I' => '팇',
  '�J' => '팈',
  '�K' => '팉',
  '�L' => '팊',
  '�M' => '팋',
  '�N' => '팏',
  '�O' => '팑',
  '�P' => '팒',
  '�Q' => '팓',
  '�R' => '팕',
  '�S' => '팗',
  '�T' => '팘',
  '�U' => '팙',
  '�V' => '팚',
  '�W' => '팛',
  '�X' => '팞',
  '�Y' => '팢',
  '�Z' => '팣',
  '�a' => '팤',
  '�b' => '팦',
  '�c' => '팧',
  '�d' => '팪',
  '�e' => '팫',
  '�f' => '팭',
  '�g' => '팮',
  '�h' => '팯',
  '�i' => '팱',
  '�j' => '팲',
  '�k' => '팳',
  '�l' => '팴',
  '�m' => '팵',
  '�n' => '팶',
  '�o' => '팷',
  '�p' => '팺',
  '�q' => '팾',
  '�r' => '팿',
  '�s' => '퍀',
  '�t' => '퍁',
  '�u' => '퍂',
  '�v' => '퍃',
  '�w' => '퍆',
  '�x' => '퍇',
  '�y' => '퍈',
  '�z' => '퍉',
  '��' => '퍊',
  '��' => '퍋',
  '��' => '퍌',
  '��' => '퍍',
  '��' => '퍎',
  '��' => '퍏',
  '��' => '퍐',
  '��' => '퍑',
  '��' => '퍒',
  '��' => '퍓',
  '��' => '퍔',
  '��' => '퍕',
  '��' => '퍖',
  '��' => '퍗',
  '��' => '퍘',
  '��' => '퍙',
  '��' => '퍚',
  '��' => '퍛',
  '��' => '퍜',
  '��' => '퍝',
  '��' => '퍞',
  '��' => '퍟',
  '��' => '퍠',
  '��' => '퍡',
  '��' => '퍢',
  '��' => '퍣',
  '��' => '퍤',
  '��' => '퍥',
  '��' => '퍦',
  '��' => '퍧',
  '��' => '퍨',
  '��' => '퍩',
  '��' => '빨',
  '��' => '빪',
  '��' => '빰',
  '��' => '빱',
  '��' => '빳',
  '��' => '빴',
  '��' => '빵',
  '��' => '빻',
  '��' => '빼',
  '��' => '빽',
  '��' => '뺀',
  '��' => '뺄',
  '��' => '뺌',
  '��' => '뺍',
  '��' => '뺏',
  '��' => '뺐',
  '��' => '뺑',
  '��' => '뺘',
  '��' => '뺙',
  '��' => '뺨',
  '��' => '뻐',
  '��' => '뻑',
  '��' => '뻔',
  '��' => '뻗',
  '��' => '뻘',
  '��' => '뻠',
  '��' => '뻣',
  '��' => '뻤',
  '��' => '뻥',
  '��' => '뻬',
  '��' => '뼁',
  '��' => '뼈',
  '��' => '뼉',
  '��' => '뼘',
  '��' => '뼙',
  '��' => '뼛',
  '��' => '뼜',
  '��' => '뼝',
  '��' => '뽀',
  '��' => '뽁',
  '��' => '뽄',
  '��' => '뽈',
  '��' => '뽐',
  '��' => '뽑',
  '��' => '뽕',
  '��' => '뾔',
  '��' => '뾰',
  '��' => '뿅',
  '��' => '뿌',
  '��' => '뿍',
  '��' => '뿐',
  '��' => '뿔',
  '��' => '뿜',
  '��' => '뿟',
  '��' => '뿡',
  '��' => '쀼',
  '��' => '쁑',
  '��' => '쁘',
  '��' => '쁜',
  '��' => '쁠',
  '��' => '쁨',
  '��' => '쁩',
  '��' => '삐',
  '��' => '삑',
  '��' => '삔',
  '��' => '삘',
  '��' => '삠',
  '��' => '삡',
  '��' => '삣',
  '��' => '삥',
  '��' => '사',
  '��' => '삭',
  '��' => '삯',
  '��' => '산',
  '��' => '삳',
  '��' => '살',
  '��' => '삵',
  '��' => '삶',
  '��' => '삼',
  '��' => '삽',
  '��' => '삿',
  '��' => '샀',
  '��' => '상',
  '��' => '샅',
  '��' => '새',
  '��' => '색',
  '��' => '샌',
  '��' => '샐',
  '��' => '샘',
  '��' => '샙',
  '��' => '샛',
  '��' => '샜',
  '��' => '생',
  '��' => '샤',
  '�A' => '퍪',
  '�B' => '퍫',
  '�C' => '퍬',
  '�D' => '퍭',
  '�E' => '퍮',
  '�F' => '퍯',
  '�G' => '퍰',
  '�H' => '퍱',
  '�I' => '퍲',
  '�J' => '퍳',
  '�K' => '퍴',
  '�L' => '퍵',
  '�M' => '퍶',
  '�N' => '퍷',
  '�O' => '퍸',
  '�P' => '퍹',
  '�Q' => '퍺',
  '�R' => '퍻',
  '�S' => '퍾',
  '�T' => '퍿',
  '�U' => '펁',
  '�V' => '펂',
  '�W' => '펃',
  '�X' => '펅',
  '�Y' => '펆',
  '�Z' => '펇',
  '�a' => '펈',
  '�b' => '펉',
  '�c' => '펊',
  '�d' => '펋',
  '�e' => '펎',
  '�f' => '펒',
  '�g' => '펓',
  '�h' => '펔',
  '�i' => '펕',
  '�j' => '펖',
  '�k' => '펗',
  '�l' => '펚',
  '�m' => '펛',
  '�n' => '펝',
  '�o' => '펞',
  '�p' => '펟',
  '�q' => '펡',
  '�r' => '펢',
  '�s' => '펣',
  '�t' => '펤',
  '�u' => '펥',
  '�v' => '펦',
  '�w' => '펧',
  '�x' => '펪',
  '�y' => '펬',
  '�z' => '펮',
  '��' => '펯',
  '��' => '펰',
  '��' => '펱',
  '��' => '펲',
  '��' => '펳',
  '��' => '펵',
  '��' => '펶',
  '��' => '펷',
  '��' => '펹',
  '��' => '펺',
  '��' => '펻',
  '��' => '펽',
  '��' => '펾',
  '��' => '펿',
  '��' => '폀',
  '��' => '폁',
  '��' => '폂',
  '��' => '폃',
  '��' => '폆',
  '��' => '폇',
  '��' => '폊',
  '��' => '폋',
  '��' => '폌',
  '��' => '폍',
  '��' => '폎',
  '��' => '폏',
  '��' => '폑',
  '��' => '폒',
  '��' => '폓',
  '��' => '폔',
  '��' => '폕',
  '��' => '폖',
  '��' => '샥',
  '��' => '샨',
  '��' => '샬',
  '��' => '샴',
  '��' => '샵',
  '��' => '샷',
  '��' => '샹',
  '��' => '섀',
  '��' => '섄',
  '��' => '섈',
  '��' => '섐',
  '��' => '섕',
  '��' => '서',
  '��' => '석',
  '��' => '섞',
  '��' => '섟',
  '��' => '선',
  '��' => '섣',
  '��' => '설',
  '��' => '섦',
  '��' => '섧',
  '��' => '섬',
  '��' => '섭',
  '��' => '섯',
  '��' => '섰',
  '��' => '성',
  '��' => '섶',
  '��' => '세',
  '��' => '섹',
  '��' => '센',
  '��' => '셀',
  '��' => '셈',
  '��' => '셉',
  '��' => '셋',
  '��' => '셌',
  '��' => '셍',
  '��' => '셔',
  '��' => '셕',
  '��' => '션',
  '��' => '셜',
  '��' => '셤',
  '��' => '셥',
  '��' => '셧',
  '��' => '셨',
  '��' => '셩',
  '��' => '셰',
  '��' => '셴',
  '��' => '셸',
  '��' => '솅',
  '��' => '소',
  '��' => '속',
  '��' => '솎',
  '��' => '손',
  '��' => '솔',
  '��' => '솖',
  '��' => '솜',
  '��' => '솝',
  '��' => '솟',
  '��' => '송',
  '��' => '솥',
  '��' => '솨',
  '��' => '솩',
  '��' => '솬',
  '��' => '솰',
  '��' => '솽',
  '��' => '쇄',
  '��' => '쇈',
  '��' => '쇌',
  '��' => '쇔',
  '��' => '쇗',
  '��' => '쇘',
  '��' => '쇠',
  '��' => '쇤',
  '��' => '쇨',
  '��' => '쇰',
  '��' => '쇱',
  '��' => '쇳',
  '��' => '쇼',
  '��' => '쇽',
  '��' => '숀',
  '��' => '숄',
  '��' => '숌',
  '��' => '숍',
  '��' => '숏',
  '��' => '숑',
  '��' => '수',
  '��' => '숙',
  '��' => '순',
  '��' => '숟',
  '��' => '술',
  '��' => '숨',
  '��' => '숩',
  '��' => '숫',
  '��' => '숭',
  '�A' => '폗',
  '�B' => '폙',
  '�C' => '폚',
  '�D' => '폛',
  '�E' => '폜',
  '�F' => '폝',
  '�G' => '폞',
  '�H' => '폟',
  '�I' => '폠',
  '�J' => '폢',
  '�K' => '폤',
  '�L' => '폥',
  '�M' => '폦',
  '�N' => '폧',
  '�O' => '폨',
  '�P' => '폩',
  '�Q' => '폪',
  '�R' => '폫',
  '�S' => '폮',
  '�T' => '폯',
  '�U' => '폱',
  '�V' => '폲',
  '�W' => '폳',
  '�X' => '폵',
  '�Y' => '폶',
  '�Z' => '폷',
  '�a' => '폸',
  '�b' => '폹',
  '�c' => '폺',
  '�d' => '폻',
  '�e' => '폾',
  '�f' => '퐀',
  '�g' => '퐂',
  '�h' => '퐃',
  '�i' => '퐄',
  '�j' => '퐅',
  '�k' => '퐆',
  '�l' => '퐇',
  '�m' => '퐉',
  '�n' => '퐊',
  '�o' => '퐋',
  '�p' => '퐌',
  '�q' => '퐍',
  '�r' => '퐎',
  '�s' => '퐏',
  '�t' => '퐐',
  '�u' => '퐑',
  '�v' => '퐒',
  '�w' => '퐓',
  '�x' => '퐔',
  '�y' => '퐕',
  '�z' => '퐖',
  '��' => '퐗',
  '��' => '퐘',
  '��' => '퐙',
  '��' => '퐚',
  '��' => '퐛',
  '��' => '퐜',
  '��' => '퐞',
  '��' => '퐟',
  '��' => '퐠',
  '��' => '퐡',
  '��' => '퐢',
  '��' => '퐣',
  '��' => '퐤',
  '��' => '퐥',
  '��' => '퐦',
  '��' => '퐧',
  '��' => '퐨',
  '��' => '퐩',
  '��' => '퐪',
  '��' => '퐫',
  '��' => '퐬',
  '��' => '퐭',
  '��' => '퐮',
  '��' => '퐯',
  '��' => '퐰',
  '��' => '퐱',
  '��' => '퐲',
  '��' => '퐳',
  '��' => '퐴',
  '��' => '퐵',
  '��' => '퐶',
  '��' => '퐷',
  '��' => '숯',
  '��' => '숱',
  '��' => '숲',
  '��' => '숴',
  '��' => '쉈',
  '��' => '쉐',
  '��' => '쉑',
  '��' => '쉔',
  '��' => '쉘',
  '��' => '쉠',
  '��' => '쉥',
  '��' => '쉬',
  '��' => '쉭',
  '��' => '쉰',
  '��' => '쉴',
  '��' => '쉼',
  '��' => '쉽',
  '��' => '쉿',
  '��' => '슁',
  '��' => '슈',
  '��' => '슉',
  '��' => '슐',
  '��' => '슘',
  '��' => '슛',
  '��' => '슝',
  '��' => '스',
  '��' => '슥',
  '��' => '슨',
  '��' => '슬',
  '��' => '슭',
  '��' => '슴',
  '��' => '습',
  '��' => '슷',
  '��' => '승',
  '��' => '시',
  '��' => '식',
  '��' => '신',
  '��' => '싣',
  '��' => '실',
  '��' => '싫',
  '��' => '심',
  '��' => '십',
  '��' => '싯',
  '��' => '싱',
  '��' => '싶',
  '��' => '싸',
  '��' => '싹',
  '��' => '싻',
  '��' => '싼',
  '��' => '쌀',
  '��' => '쌈',
  '��' => '쌉',
  '��' => '쌌',
  '��' => '쌍',
  '��' => '쌓',
  '��' => '쌔',
  '��' => '쌕',
  '��' => '쌘',
  '��' => '쌜',
  '��' => '쌤',
  '��' => '쌥',
  '��' => '쌨',
  '��' => '쌩',
  '��' => '썅',
  '��' => '써',
  '��' => '썩',
  '��' => '썬',
  '��' => '썰',
  '��' => '썲',
  '��' => '썸',
  '��' => '썹',
  '��' => '썼',
  '��' => '썽',
  '��' => '쎄',
  '��' => '쎈',
  '��' => '쎌',
  '��' => '쏀',
  '��' => '쏘',
  '��' => '쏙',
  '��' => '쏜',
  '��' => '쏟',
  '��' => '쏠',
  '��' => '쏢',
  '��' => '쏨',
  '��' => '쏩',
  '��' => '쏭',
  '��' => '쏴',
  '��' => '쏵',
  '��' => '쏸',
  '��' => '쐈',
  '��' => '쐐',
  '��' => '쐤',
  '��' => '쐬',
  '��' => '쐰',
  '�A' => '퐸',
  '�B' => '퐹',
  '�C' => '퐺',
  '�D' => '퐻',
  '�E' => '퐼',
  '�F' => '퐽',
  '�G' => '퐾',
  '�H' => '퐿',
  '�I' => '푁',
  '�J' => '푂',
  '�K' => '푃',
  '�L' => '푅',
  '�M' => '푆',
  '�N' => '푇',
  '�O' => '푈',
  '�P' => '푉',
  '�Q' => '푊',
  '�R' => '푋',
  '�S' => '푌',
  '�T' => '푍',
  '�U' => '푎',
  '�V' => '푏',
  '�W' => '푐',
  '�X' => '푑',
  '�Y' => '푒',
  '�Z' => '푓',
  '�a' => '푔',
  '�b' => '푕',
  '�c' => '푖',
  '�d' => '푗',
  '�e' => '푘',
  '�f' => '푙',
  '�g' => '푚',
  '�h' => '푛',
  '�i' => '푝',
  '�j' => '푞',
  '�k' => '푟',
  '�l' => '푡',
  '�m' => '푢',
  '�n' => '푣',
  '�o' => '푥',
  '�p' => '푦',
  '�q' => '푧',
  '�r' => '푨',
  '�s' => '푩',
  '�t' => '푪',
  '�u' => '푫',
  '�v' => '푬',
  '�w' => '푮',
  '�x' => '푰',
  '�y' => '푱',
  '�z' => '푲',
  '��' => '푳',
  '��' => '푴',
  '��' => '푵',
  '��' => '푶',
  '��' => '푷',
  '��' => '푺',
  '��' => '푻',
  '��' => '푽',
  '��' => '푾',
  '��' => '풁',
  '��' => '풃',
  '��' => '풄',
  '��' => '풅',
  '��' => '풆',
  '��' => '풇',
  '��' => '풊',
  '��' => '풌',
  '��' => '풎',
  '��' => '풏',
  '��' => '풐',
  '��' => '풑',
  '��' => '풒',
  '��' => '풓',
  '��' => '풕',
  '��' => '풖',
  '��' => '풗',
  '��' => '풘',
  '��' => '풙',
  '��' => '풚',
  '��' => '풛',
  '��' => '풜',
  '��' => '풝',
  '��' => '쐴',
  '��' => '쐼',
  '��' => '쐽',
  '��' => '쑈',
  '��' => '쑤',
  '��' => '쑥',
  '��' => '쑨',
  '��' => '쑬',
  '��' => '쑴',
  '��' => '쑵',
  '��' => '쑹',
  '��' => '쒀',
  '��' => '쒔',
  '��' => '쒜',
  '��' => '쒸',
  '��' => '쒼',
  '��' => '쓩',
  '��' => '쓰',
  '��' => '쓱',
  '��' => '쓴',
  '��' => '쓸',
  '��' => '쓺',
  '��' => '쓿',
  '��' => '씀',
  '��' => '씁',
  '��' => '씌',
  '��' => '씐',
  '��' => '씔',
  '��' => '씜',
  '��' => '씨',
  '��' => '씩',
  '��' => '씬',
  '��' => '씰',
  '��' => '씸',
  '��' => '씹',
  '��' => '씻',
  '��' => '씽',
  '��' => '아',
  '��' => '악',
  '��' => '안',
  '��' => '앉',
  '��' => '않',
  '��' => '알',
  '��' => '앍',
  '��' => '앎',
  '��' => '앓',
  '��' => '암',
  '��' => '압',
  '��' => '앗',
  '��' => '았',
  '��' => '앙',
  '��' => '앝',
  '��' => '앞',
  '��' => '애',
  '��' => '액',
  '��' => '앤',
  '��' => '앨',
  '��' => '앰',
  '��' => '앱',
  '��' => '앳',
  '��' => '앴',
  '��' => '앵',
  '��' => '야',
  '��' => '약',
  '��' => '얀',
  '��' => '얄',
  '��' => '얇',
  '��' => '얌',
  '��' => '얍',
  '��' => '얏',
  '��' => '양',
  '��' => '얕',
  '��' => '얗',
  '��' => '얘',
  '��' => '얜',
  '��' => '얠',
  '��' => '얩',
  '��' => '어',
  '��' => '억',
  '��' => '언',
  '��' => '얹',
  '��' => '얻',
  '��' => '얼',
  '��' => '얽',
  '��' => '얾',
  '��' => '엄',
  '��' => '업',
  '��' => '없',
  '��' => '엇',
  '��' => '었',
  '��' => '엉',
  '��' => '엊',
  '��' => '엌',
  '��' => '엎',
  '�A' => '풞',
  '�B' => '풟',
  '�C' => '풠',
  '�D' => '풡',
  '�E' => '풢',
  '�F' => '풣',
  '�G' => '풤',
  '�H' => '풥',
  '�I' => '풦',
  '�J' => '풧',
  '�K' => '풨',
  '�L' => '풪',
  '�M' => '풫',
  '�N' => '풬',
  '�O' => '풭',
  '�P' => '풮',
  '�Q' => '풯',
  '�R' => '풰',
  '�S' => '풱',
  '�T' => '풲',
  '�U' => '풳',
  '�V' => '풴',
  '�W' => '풵',
  '�X' => '풶',
  '�Y' => '풷',
  '�Z' => '풸',
  '�a' => '풹',
  '�b' => '풺',
  '�c' => '풻',
  '�d' => '풼',
  '�e' => '풽',
  '�f' => '풾',
  '�g' => '풿',
  '�h' => '퓀',
  '�i' => '퓁',
  '�j' => '퓂',
  '�k' => '퓃',
  '�l' => '퓄',
  '�m' => '퓅',
  '�n' => '퓆',
  '�o' => '퓇',
  '�p' => '퓈',
  '�q' => '퓉',
  '�r' => '퓊',
  '�s' => '퓋',
  '�t' => '퓍',
  '�u' => '퓎',
  '�v' => '퓏',
  '�w' => '퓑',
  '�x' => '퓒',
  '�y' => '퓓',
  '�z' => '퓕',
  '��' => '퓖',
  '��' => '퓗',
  '��' => '퓘',
  '��' => '퓙',
  '��' => '퓚',
  '��' => '퓛',
  '��' => '퓝',
  '��' => '퓞',
  '��' => '퓠',
  '��' => '퓡',
  '��' => '퓢',
  '��' => '퓣',
  '��' => '퓤',
  '��' => '퓥',
  '��' => '퓦',
  '��' => '퓧',
  '��' => '퓩',
  '��' => '퓪',
  '��' => '퓫',
  '��' => '퓭',
  '��' => '퓮',
  '��' => '퓯',
  '��' => '퓱',
  '��' => '퓲',
  '��' => '퓳',
  '��' => '퓴',
  '��' => '퓵',
  '��' => '퓶',
  '��' => '퓷',
  '��' => '퓹',
  '��' => '퓺',
  '��' => '퓼',
  '��' => '에',
  '��' => '엑',
  '��' => '엔',
  '��' => '엘',
  '��' => '엠',
  '��' => '엡',
  '��' => '엣',
  '��' => '엥',
  '��' => '여',
  '��' => '역',
  '��' => '엮',
  '��' => '연',
  '��' => '열',
  '��' => '엶',
  '��' => '엷',
  '��' => '염',
  '��' => '엽',
  '��' => '엾',
  '��' => '엿',
  '��' => '였',
  '��' => '영',
  '��' => '옅',
  '��' => '옆',
  '��' => '옇',
  '��' => '예',
  '��' => '옌',
  '��' => '옐',
  '��' => '옘',
  '��' => '옙',
  '��' => '옛',
  '��' => '옜',
  '��' => '오',
  '��' => '옥',
  '��' => '온',
  '��' => '올',
  '��' => '옭',
  '��' => '옮',
  '��' => '옰',
  '��' => '옳',
  '��' => '옴',
  '��' => '옵',
  '��' => '옷',
  '��' => '옹',
  '��' => '옻',
  '��' => '와',
  '��' => '왁',
  '��' => '완',
  '��' => '왈',
  '��' => '왐',
  '��' => '왑',
  '��' => '왓',
  '��' => '왔',
  '��' => '왕',
  '��' => '왜',
  '��' => '왝',
  '��' => '왠',
  '��' => '왬',
  '��' => '왯',
  '��' => '왱',
  '��' => '외',
  '��' => '왹',
  '��' => '왼',
  '��' => '욀',
  '��' => '욈',
  '��' => '욉',
  '��' => '욋',
  '��' => '욍',
  '��' => '요',
  '��' => '욕',
  '��' => '욘',
  '��' => '욜',
  '��' => '욤',
  '��' => '욥',
  '��' => '욧',
  '��' => '용',
  '��' => '우',
  '��' => '욱',
  '��' => '운',
  '��' => '울',
  '��' => '욹',
  '��' => '욺',
  '��' => '움',
  '��' => '웁',
  '��' => '웃',
  '��' => '웅',
  '��' => '워',
  '��' => '웍',
  '��' => '원',
  '��' => '월',
  '��' => '웜',
  '��' => '웝',
  '��' => '웠',
  '��' => '웡',
  '��' => '웨',
  '�A' => '퓾',
  '�B' => '퓿',
  '�C' => '픀',
  '�D' => '픁',
  '�E' => '픂',
  '�F' => '픃',
  '�G' => '픅',
  '�H' => '픆',
  '�I' => '픇',
  '�J' => '픉',
  '�K' => '픊',
  '�L' => '픋',
  '�M' => '픍',
  '�N' => '픎',
  '�O' => '픏',
  '�P' => '픐',
  '�Q' => '픑',
  '�R' => '픒',
  '�S' => '픓',
  '�T' => '픖',
  '�U' => '픘',
  '�V' => '픙',
  '�W' => '픚',
  '�X' => '픛',
  '�Y' => '픜',
  '�Z' => '픝',
  '�a' => '픞',
  '�b' => '픟',
  '�c' => '픠',
  '�d' => '픡',
  '�e' => '픢',
  '�f' => '픣',
  '�g' => '픤',
  '�h' => '픥',
  '�i' => '픦',
  '�j' => '픧',
  '�k' => '픨',
  '�l' => '픩',
  '�m' => '픪',
  '�n' => '픫',
  '�o' => '픬',
  '�p' => '픭',
  '�q' => '픮',
  '�r' => '픯',
  '�s' => '픰',
  '�t' => '픱',
  '�u' => '픲',
  '�v' => '픳',
  '�w' => '픴',
  '�x' => '픵',
  '�y' => '픶',
  '�z' => '픷',
  '��' => '픸',
  '��' => '픹',
  '��' => '픺',
  '��' => '픻',
  '��' => '픾',
  '��' => '픿',
  '��' => '핁',
  '��' => '핂',
  '��' => '핃',
  '��' => '핅',
  '��' => '핆',
  '��' => '핇',
  '��' => '핈',
  '��' => '핉',
  '��' => '핊',
  '��' => '핋',
  '��' => '핎',
  '��' => '핐',
  '��' => '핒',
  '��' => '핓',
  '��' => '핔',
  '��' => '핕',
  '��' => '핖',
  '��' => '핗',
  '��' => '핚',
  '��' => '핛',
  '��' => '핝',
  '��' => '핞',
  '��' => '핟',
  '��' => '핡',
  '��' => '핢',
  '��' => '핣',
  '��' => '웩',
  '��' => '웬',
  '��' => '웰',
  '��' => '웸',
  '��' => '웹',
  '��' => '웽',
  '��' => '위',
  '��' => '윅',
  '��' => '윈',
  '��' => '윌',
  '��' => '윔',
  '��' => '윕',
  '��' => '윗',
  '��' => '윙',
  '��' => '유',
  '��' => '육',
  '��' => '윤',
  '��' => '율',
  '��' => '윰',
  '��' => '윱',
  '��' => '윳',
  '��' => '융',
  '��' => '윷',
  '��' => '으',
  '��' => '윽',
  '��' => '은',
  '��' => '을',
  '��' => '읊',
  '��' => '음',
  '��' => '읍',
  '��' => '읏',
  '��' => '응',
  '��' => '읒',
  '��' => '읓',
  '��' => '읔',
  '��' => '읕',
  '��' => '읖',
  '��' => '읗',
  '��' => '의',
  '��' => '읜',
  '��' => '읠',
  '��' => '읨',
  '��' => '읫',
  '��' => '이',
  '��' => '익',
  '��' => '인',
  '��' => '일',
  '��' => '읽',
  '��' => '읾',
  '��' => '잃',
  '��' => '임',
  '��' => '입',
  '��' => '잇',
  '��' => '있',
  '��' => '잉',
  '��' => '잊',
  '��' => '잎',
  '��' => '자',
  '��' => '작',
  '��' => '잔',
  '��' => '잖',
  '��' => '잗',
  '��' => '잘',
  '��' => '잚',
  '��' => '잠',
  '��' => '잡',
  '��' => '잣',
  '��' => '잤',
  '��' => '장',
  '��' => '잦',
  '��' => '재',
  '��' => '잭',
  '��' => '잰',
  '��' => '잴',
  '��' => '잼',
  '��' => '잽',
  '��' => '잿',
  '��' => '쟀',
  '��' => '쟁',
  '��' => '쟈',
  '��' => '쟉',
  '��' => '쟌',
  '��' => '쟎',
  '��' => '쟐',
  '��' => '쟘',
  '��' => '쟝',
  '��' => '쟤',
  '��' => '쟨',
  '��' => '쟬',
  '��' => '저',
  '��' => '적',
  '��' => '전',
  '��' => '절',
  '��' => '젊',
  '�A' => '핤',
  '�B' => '핦',
  '�C' => '핧',
  '�D' => '핪',
  '�E' => '핬',
  '�F' => '핮',
  '�G' => '핯',
  '�H' => '핰',
  '�I' => '핱',
  '�J' => '핲',
  '�K' => '핳',
  '�L' => '핶',
  '�M' => '핷',
  '�N' => '핹',
  '�O' => '핺',
  '�P' => '핻',
  '�Q' => '핽',
  '�R' => '핾',
  '�S' => '핿',
  '�T' => '햀',
  '�U' => '햁',
  '�V' => '햂',
  '�W' => '햃',
  '�X' => '햆',
  '�Y' => '햊',
  '�Z' => '햋',
  '�a' => '햌',
  '�b' => '햍',
  '�c' => '햎',
  '�d' => '햏',
  '�e' => '햑',
  '�f' => '햒',
  '�g' => '햓',
  '�h' => '햔',
  '�i' => '햕',
  '�j' => '햖',
  '�k' => '햗',
  '�l' => '햘',
  '�m' => '햙',
  '�n' => '햚',
  '�o' => '햛',
  '�p' => '햜',
  '�q' => '햝',
  '�r' => '햞',
  '�s' => '햟',
  '�t' => '햠',
  '�u' => '햡',
  '�v' => '햢',
  '�w' => '햣',
  '�x' => '햤',
  '�y' => '햦',
  '�z' => '햧',
  '��' => '햨',
  '��' => '햩',
  '��' => '햪',
  '��' => '햫',
  '��' => '햬',
  '��' => '햭',
  '��' => '햮',
  '��' => '햯',
  '��' => '햰',
  '��' => '햱',
  '��' => '햲',
  '��' => '햳',
  '��' => '햴',
  '��' => '햵',
  '��' => '햶',
  '��' => '햷',
  '��' => '햸',
  '��' => '햹',
  '��' => '햺',
  '��' => '햻',
  '��' => '햼',
  '��' => '햽',
  '��' => '햾',
  '��' => '햿',
  '��' => '헀',
  '��' => '헁',
  '��' => '헂',
  '��' => '헃',
  '��' => '헄',
  '��' => '헅',
  '��' => '헆',
  '��' => '헇',
  '��' => '점',
  '��' => '접',
  '��' => '젓',
  '��' => '정',
  '��' => '젖',
  '��' => '제',
  '��' => '젝',
  '��' => '젠',
  '��' => '젤',
  '��' => '젬',
  '��' => '젭',
  '��' => '젯',
  '��' => '젱',
  '��' => '져',
  '��' => '젼',
  '��' => '졀',
  '��' => '졈',
  '��' => '졉',
  '��' => '졌',
  '��' => '졍',
  '��' => '졔',
  '��' => '조',
  '��' => '족',
  '��' => '존',
  '��' => '졸',
  '��' => '졺',
  '��' => '좀',
  '��' => '좁',
  '��' => '좃',
  '��' => '종',
  '��' => '좆',
  '��' => '좇',
  '��' => '좋',
  '��' => '좌',
  '��' => '좍',
  '��' => '좔',
  '��' => '좝',
  '��' => '좟',
  '��' => '좡',
  '��' => '좨',
  '��' => '좼',
  '��' => '좽',
  '��' => '죄',
  '��' => '죈',
  '��' => '죌',
  '��' => '죔',
  '��' => '죕',
  '��' => '죗',
  '��' => '죙',
  '��' => '죠',
  '��' => '죡',
  '��' => '죤',
  '��' => '죵',
  '��' => '주',
  '��' => '죽',
  '��' => '준',
  '��' => '줄',
  '��' => '줅',
  '��' => '줆',
  '��' => '줌',
  '��' => '줍',
  '��' => '줏',
  '��' => '중',
  '��' => '줘',
  '��' => '줬',
  '��' => '줴',
  '��' => '쥐',
  '��' => '쥑',
  '��' => '쥔',
  '��' => '쥘',
  '��' => '쥠',
  '��' => '쥡',
  '��' => '쥣',
  '��' => '쥬',
  '��' => '쥰',
  '��' => '쥴',
  '��' => '쥼',
  '��' => '즈',
  '��' => '즉',
  '��' => '즌',
  '��' => '즐',
  '��' => '즘',
  '��' => '즙',
  '��' => '즛',
  '��' => '증',
  '��' => '지',
  '��' => '직',
  '��' => '진',
  '��' => '짇',
  '��' => '질',
  '��' => '짊',
  '��' => '짐',
  '��' => '집',
  '��' => '짓',
  '�A' => '헊',
  '�B' => '헋',
  '�C' => '헍',
  '�D' => '헎',
  '�E' => '헏',
  '�F' => '헑',
  '�G' => '헓',
  '�H' => '헔',
  '�I' => '헕',
  '�J' => '헖',
  '�K' => '헗',
  '�L' => '헚',
  '�M' => '헜',
  '�N' => '헞',
  '�O' => '헟',
  '�P' => '헠',
  '�Q' => '헡',
  '�R' => '헢',
  '�S' => '헣',
  '�T' => '헦',
  '�U' => '헧',
  '�V' => '헩',
  '�W' => '헪',
  '�X' => '헫',
  '�Y' => '헭',
  '�Z' => '헮',
  '�a' => '헯',
  '�b' => '헰',
  '�c' => '헱',
  '�d' => '헲',
  '�e' => '헳',
  '�f' => '헶',
  '�g' => '헸',
  '�h' => '헺',
  '�i' => '헻',
  '�j' => '헼',
  '�k' => '헽',
  '�l' => '헾',
  '�m' => '헿',
  '�n' => '혂',
  '�o' => '혃',
  '�p' => '혅',
  '�q' => '혆',
  '�r' => '혇',
  '�s' => '혉',
  '�t' => '혊',
  '�u' => '혋',
  '�v' => '혌',
  '�w' => '혍',
  '�x' => '혎',
  '�y' => '혏',
  '�z' => '혒',
  '' => '혖',
  '‚' => '혗',
  'ƒ' => '혘',
  '„' => '혙',
  '…' => '혚',
  '†' => '혛',
  '‡' => '혝',
  'ˆ' => '혞',
  '‰' => '혟',
  'Š' => '혡',
  '‹' => '혢',
  'Œ' => '혣',
  '' => '혥',
  'Ž' => '혦',
  '' => '혧',
  '' => '혨',
  '‘' => '혩',
  '’' => '혪',
  '“' => '혫',
  '”' => '혬',
  '•' => '혮',
  '–' => '혯',
  '—' => '혰',
  '˜' => '혱',
  '™' => '혲',
  'š' => '혳',
  '›' => '혴',
  'œ' => '혵',
  '' => '혶',
  'ž' => '혷',
  'Ÿ' => '혺',
  ' ' => '혻',
  '¡' => '징',
  '¢' => '짖',
  '£' => '짙',
  '¤' => '짚',
  '¥' => '짜',
  '¦' => '짝',
  '§' => '짠',
  '¨' => '짢',
  '©' => '짤',
  'ª' => '짧',
  '«' => '짬',
  '¬' => '짭',
  '­' => '짯',
  '®' => '짰',
  '¯' => '짱',
  '°' => '째',
  '±' => '짹',
  '²' => '짼',
  '³' => '쨀',
  '´' => '쨈',
  'µ' => '쨉',
  '¶' => '쨋',
  '·' => '쨌',
  '¸' => '쨍',
  '¹' => '쨔',
  'º' => '쨘',
  '»' => '쨩',
  '¼' => '쩌',
  '½' => '쩍',
  '¾' => '쩐',
  '¿' => '쩔',
  '�' => '쩜',
  '�' => '쩝',
  '��' => '쩟',
  '��' => '쩠',
  '��' => '쩡',
  '��' => '쩨',
  '��' => '쩽',
  '��' => '쪄',
  '��' => '쪘',
  '��' => '쪼',
  '��' => '쪽',
  '��' => '쫀',
  '��' => '쫄',
  '��' => '쫌',
  '��' => '쫍',
  '��' => '쫏',
  '��' => '쫑',
  '��' => '쫓',
  '��' => '쫘',
  '��' => '쫙',
  '��' => '쫠',
  '��' => '쫬',
  '��' => '쫴',
  '��' => '쬈',
  '��' => '쬐',
  '��' => '쬔',
  '��' => '쬘',
  '��' => '쬠',
  '��' => '쬡',
  '��' => '쭁',
  '��' => '쭈',
  '��' => '쭉',
  '��' => '쭌',
  '��' => '쭐',
  '��' => '쭘',
  '��' => '쭙',
  '��' => '쭝',
  '��' => '쭤',
  '��' => '쭸',
  '��' => '쭹',
  '��' => '쮜',
  '��' => '쮸',
  '��' => '쯔',
  '��' => '쯤',
  '��' => '쯧',
  '��' => '쯩',
  '��' => '찌',
  '��' => '찍',
  '��' => '찐',
  '��' => '찔',
  '��' => '찜',
  '��' => '찝',
  '��' => '찡',
  '�' => '찢',
  '�' => '찧',
  '�' => '차',
  '�' => '착',
  '�' => '찬',
  '�' => '찮',
  '�' => '찰',
  '�' => '참',
  '�' => '찹',
  '�' => '찻',
  '�A' => '혽',
  '�B' => '혾',
  '�C' => '혿',
  '�D' => '홁',
  '�E' => '홂',
  '�F' => '홃',
  '�G' => '홄',
  '�H' => '홆',
  '�I' => '홇',
  '�J' => '홊',
  '�K' => '홌',
  '�L' => '홎',
  '�M' => '홏',
  '�N' => '홐',
  '�O' => '홒',
  '�P' => '홓',
  '�Q' => '홖',
  '�R' => '홗',
  '�S' => '홙',
  '�T' => '홚',
  '�U' => '홛',
  '�V' => '홝',
  '�W' => '홞',
  '�X' => '홟',
  '�Y' => '홠',
  '�Z' => '홡',
  '�a' => '홢',
  '�b' => '홣',
  '�c' => '홤',
  '�d' => '홥',
  '�e' => '홦',
  '�f' => '홨',
  '�g' => '홪',
  '�h' => '홫',
  '�i' => '홬',
  '�j' => '홭',
  '�k' => '홮',
  '�l' => '홯',
  '�m' => '홲',
  '�n' => '홳',
  '�o' => '홵',
  '�p' => '홶',
  '�q' => '홷',
  '�r' => '홸',
  '�s' => '홹',
  '�t' => '홺',
  '�u' => '홻',
  '�v' => '홼',
  '�w' => '홽',
  '�x' => '홾',
  '�y' => '홿',
  '�z' => '횀',
  'Á' => '횁',
  'Â' => '횂',
  'Ã' => '횄',
  'Ä' => '횆',
  'Å' => '횇',
  'Æ' => '횈',
  'Ç' => '횉',
  'È' => '횊',
  'É' => '횋',
  'Ê' => '횎',
  'Ë' => '횏',
  'Ì' => '횑',
  'Í' => '횒',
  'Î' => '횓',
  'Ï' => '횕',
  'Ð' => '횖',
  'Ñ' => '횗',
  'Ò' => '횘',
  'Ó' => '횙',
  'Ô' => '횚',
  'Õ' => '횛',
  'Ö' => '횜',
  '×' => '횞',
  'Ø' => '횠',
  'Ù' => '횢',
  'Ú' => '횣',
  'Û' => '횤',
  'Ü' => '횥',
  'Ý' => '횦',
  'Þ' => '횧',
  'ß' => '횩',
  'à' => '횪',
  'á' => '찼',
  'â' => '창',
  'ã' => '찾',
  'ä' => '채',
  'å' => '책',
  'æ' => '챈',
  'ç' => '챌',
  'è' => '챔',
  'é' => '챕',
  'ê' => '챗',
  'ë' => '챘',
  'ì' => '챙',
  'í' => '챠',
  'î' => '챤',
  'ï' => '챦',
  'ð' => '챨',
  'ñ' => '챰',
  'ò' => '챵',
  'ó' => '처',
  'ô' => '척',
  'õ' => '천',
  'ö' => '철',
  '÷' => '첨',
  'ø' => '첩',
  'ù' => '첫',
  'ú' => '첬',
  'û' => '청',
  'ü' => '체',
  'ý' => '첵',
  'þ' => '첸',
  'ÿ' => '첼',
  '�' => '쳄',
  '�' => '쳅',
  '��' => '쳇',
  '��' => '쳉',
  '��' => '쳐',
  '��' => '쳔',
  '��' => '쳤',
  '��' => '쳬',
  '��' => '쳰',
  '��' => '촁',
  '��' => '초',
  '��' => '촉',
  '��' => '촌',
  '��' => '촐',
  '��' => '촘',
  '��' => '촙',
  '��' => '촛',
  '��' => '총',
  '��' => '촤',
  '��' => '촨',
  '��' => '촬',
  '��' => '촹',
  '��' => '최',
  '��' => '쵠',
  '��' => '쵤',
  '��' => '쵬',
  '��' => '쵭',
  '��' => '쵯',
  '��' => '쵱',
  '��' => '쵸',
  '��' => '춈',
  '��' => '추',
  '��' => '축',
  '��' => '춘',
  '��' => '출',
  '��' => '춤',
  '��' => '춥',
  '��' => '춧',
  '��' => '충',
  '��' => '춰',
  '��' => '췄',
  '��' => '췌',
  '��' => '췐',
  '��' => '취',
  '��' => '췬',
  '��' => '췰',
  '��' => '췸',
  '��' => '췹',
  '��' => '췻',
  '��' => '췽',
  '��' => '츄',
  '��' => '츈',
  '��' => '츌',
  '�' => '츔',
  '�' => '츙',
  '�' => '츠',
  '�' => '측',
  '�' => '츤',
  '�' => '츨',
  '�' => '츰',
  '�' => '츱',
  '�' => '츳',
  '�' => '층',
  '�A' => '횫',
  '�B' => '횭',
  '�C' => '횮',
  '�D' => '횯',
  '�E' => '횱',
  '�F' => '횲',
  '�G' => '횳',
  '�H' => '횴',
  '�I' => '횵',
  '�J' => '횶',
  '�K' => '횷',
  '�L' => '횸',
  '�M' => '횺',
  '�N' => '횼',
  '�O' => '횽',
  '�P' => '횾',
  '�Q' => '횿',
  '�R' => '훀',
  '�S' => '훁',
  '�T' => '훂',
  '�U' => '훃',
  '�V' => '훆',
  '�W' => '훇',
  '�X' => '훉',
  '�Y' => '훊',
  '�Z' => '훋',
  '�a' => '훍',
  '�b' => '훎',
  '�c' => '훏',
  '�d' => '훐',
  '�e' => '훒',
  '�f' => '훓',
  '�g' => '훕',
  '�h' => '훖',
  '�i' => '훘',
  '�j' => '훚',
  '�k' => '훛',
  '�l' => '훜',
  '�m' => '훝',
  '�n' => '훞',
  '�o' => '훟',
  '�p' => '훡',
  '�q' => '훢',
  '�r' => '훣',
  '�s' => '훥',
  '�t' => '훦',
  '�u' => '훧',
  '�v' => '훩',
  '�w' => '훪',
  '�x' => '훫',
  '�y' => '훬',
  '�z' => '훭',
  'ā' => '훮',
  'Ă' => '훯',
  'ă' => '훱',
  'Ą' => '훲',
  'ą' => '훳',
  'Ć' => '훴',
  'ć' => '훶',
  'Ĉ' => '훷',
  'ĉ' => '훸',
  'Ċ' => '훹',
  'ċ' => '훺',
  'Č' => '훻',
  'č' => '훾',
  'Ď' => '훿',
  'ď' => '휁',
  'Đ' => '휂',
  'đ' => '휃',
  'Ē' => '휅',
  'ē' => '휆',
  'Ĕ' => '휇',
  'ĕ' => '휈',
  'Ė' => '휉',
  'ė' => '휊',
  'Ę' => '휋',
  'ę' => '휌',
  'Ě' => '휍',
  'ě' => '휎',
  'Ĝ' => '휏',
  'ĝ' => '휐',
  'Ğ' => '휒',
  'ğ' => '휓',
  'Ġ' => '휔',
  'ġ' => '치',
  'Ģ' => '칙',
  'ģ' => '친',
  'Ĥ' => '칟',
  'ĥ' => '칠',
  'Ħ' => '칡',
  'ħ' => '침',
  'Ĩ' => '칩',
  'ĩ' => '칫',
  'Ī' => '칭',
  'ī' => '카',
  'Ĭ' => '칵',
  'ĭ' => '칸',
  'Į' => '칼',
  'į' => '캄',
  'İ' => '캅',
  'ı' => '캇',
  'IJ' => '캉',
  'ij' => '캐',
  'Ĵ' => '캑',
  'ĵ' => '캔',
  'Ķ' => '캘',
  'ķ' => '캠',
  'ĸ' => '캡',
  'Ĺ' => '캣',
  'ĺ' => '캤',
  'Ļ' => '캥',
  'ļ' => '캬',
  'Ľ' => '캭',
  'ľ' => '컁',
  'Ŀ' => '커',
  '�' => '컥',
  '�' => '컨',
  '��' => '컫',
  '��' => '컬',
  '��' => '컴',
  '��' => '컵',
  '��' => '컷',
  '��' => '컸',
  '��' => '컹',
  '��' => '케',
  '��' => '켁',
  '��' => '켄',
  '��' => '켈',
  '��' => '켐',
  '��' => '켑',
  '��' => '켓',
  '��' => '켕',
  '��' => '켜',
  '��' => '켠',
  '��' => '켤',
  '��' => '켬',
  '��' => '켭',
  '��' => '켯',
  '��' => '켰',
  '��' => '켱',
  '��' => '켸',
  '��' => '코',
  '��' => '콕',
  '��' => '콘',
  '��' => '콜',
  '��' => '콤',
  '��' => '콥',
  '��' => '콧',
  '��' => '콩',
  '��' => '콰',
  '��' => '콱',
  '��' => '콴',
  '��' => '콸',
  '��' => '쾀',
  '��' => '쾅',
  '��' => '쾌',
  '��' => '쾡',
  '��' => '쾨',
  '��' => '쾰',
  '��' => '쿄',
  '��' => '쿠',
  '��' => '쿡',
  '��' => '쿤',
  '��' => '쿨',
  '��' => '쿰',
  '��' => '쿱',
  '��' => '쿳',
  '��' => '쿵',
  '�' => '쿼',
  '�' => '퀀',
  '�' => '퀄',
  '�' => '퀑',
  '�' => '퀘',
  '�' => '퀭',
  '�' => '퀴',
  '�' => '퀵',
  '�' => '퀸',
  '�' => '퀼',
  '�A' => '휕',
  '�B' => '휖',
  '�C' => '휗',
  '�D' => '휚',
  '�E' => '휛',
  '�F' => '휝',
  '�G' => '휞',
  '�H' => '휟',
  '�I' => '휡',
  '�J' => '휢',
  '�K' => '휣',
  '�L' => '휤',
  '�M' => '휥',
  '�N' => '휦',
  '�O' => '휧',
  '�P' => '휪',
  '�Q' => '휬',
  '�R' => '휮',
  '�S' => '휯',
  '�T' => '휰',
  '�U' => '휱',
  '�V' => '휲',
  '�W' => '휳',
  '�X' => '휶',
  '�Y' => '휷',
  '�Z' => '휹',
  '�a' => '휺',
  '�b' => '휻',
  '�c' => '휽',
  '�d' => '휾',
  '�e' => '휿',
  '�f' => '흀',
  '�g' => '흁',
  '�h' => '흂',
  '�i' => '흃',
  '�j' => '흅',
  '�k' => '흆',
  '�l' => '흈',
  '�m' => '흊',
  '�n' => '흋',
  '�o' => '흌',
  '�p' => '흍',
  '�q' => '흎',
  '�r' => '흏',
  '�s' => '흒',
  '�t' => '흓',
  '�u' => '흕',
  '�v' => '흚',
  '�w' => '흛',
  '�x' => '흜',
  '�y' => '흝',
  '�z' => '흞',
  'Ł' => '흟',
  'ł' => '흢',
  'Ń' => '흤',
  'ń' => '흦',
  'Ņ' => '흧',
  'ņ' => '흨',
  'Ň' => '흪',
  'ň' => '흫',
  'ʼn' => '흭',
  'Ŋ' => '흮',
  'ŋ' => '흯',
  'Ō' => '흱',
  'ō' => '흲',
  'Ŏ' => '흳',
  'ŏ' => '흵',
  'Ő' => '흶',
  'ő' => '흷',
  'Œ' => '흸',
  'œ' => '흹',
  'Ŕ' => '흺',
  'ŕ' => '흻',
  'Ŗ' => '흾',
  'ŗ' => '흿',
  'Ř' => '힀',
  'ř' => '힂',
  'Ś' => '힃',
  'ś' => '힄',
  'Ŝ' => '힅',
  'ŝ' => '힆',
  'Ş' => '힇',
  'ş' => '힊',
  'Š' => '힋',
  'š' => '큄',
  'Ţ' => '큅',
  'ţ' => '큇',
  'Ť' => '큉',
  'ť' => '큐',
  'Ŧ' => '큔',
  'ŧ' => '큘',
  'Ũ' => '큠',
  'ũ' => '크',
  'Ū' => '큭',
  'ū' => '큰',
  'Ŭ' => '클',
  'ŭ' => '큼',
  'Ů' => '큽',
  'ů' => '킁',
  'Ű' => '키',
  'ű' => '킥',
  'Ų' => '킨',
  'ų' => '킬',
  'Ŵ' => '킴',
  'ŵ' => '킵',
  'Ŷ' => '킷',
  'ŷ' => '킹',
  'Ÿ' => '타',
  'Ź' => '탁',
  'ź' => '탄',
  'Ż' => '탈',
  'ż' => '탉',
  'Ž' => '탐',
  'ž' => '탑',
  'ſ' => '탓',
  '�' => '탔',
  '�' => '탕',
  '��' => '태',
  '��' => '택',
  '��' => '탠',
  '��' => '탤',
  '��' => '탬',
  '��' => '탭',
  '��' => '탯',
  '��' => '탰',
  '��' => '탱',
  '��' => '탸',
  '��' => '턍',
  '��' => '터',
  '��' => '턱',
  '��' => '턴',
  '��' => '털',
  '��' => '턺',
  '��' => '텀',
  '��' => '텁',
  '��' => '텃',
  '��' => '텄',
  '��' => '텅',
  '��' => '테',
  '��' => '텍',
  '��' => '텐',
  '��' => '텔',
  '��' => '템',
  '��' => '텝',
  '��' => '텟',
  '��' => '텡',
  '��' => '텨',
  '��' => '텬',
  '��' => '텼',
  '��' => '톄',
  '��' => '톈',
  '��' => '토',
  '��' => '톡',
  '��' => '톤',
  '��' => '톨',
  '��' => '톰',
  '��' => '톱',
  '��' => '톳',
  '��' => '통',
  '��' => '톺',
  '��' => '톼',
  '��' => '퇀',
  '��' => '퇘',
  '��' => '퇴',
  '��' => '퇸',
  '��' => '툇',
  '��' => '툉',
  '��' => '툐',
  '�' => '투',
  '�' => '툭',
  '�' => '툰',
  '�' => '툴',
  '�' => '툼',
  '�' => '툽',
  '�' => '툿',
  '�' => '퉁',
  '�' => '퉈',
  '�' => '퉜',
  '�A' => '힍',
  '�B' => '힎',
  '�C' => '힏',
  '�D' => '힑',
  '�E' => '힒',
  '�F' => '힓',
  '�G' => '힔',
  '�H' => '힕',
  '�I' => '힖',
  '�J' => '힗',
  '�K' => '힚',
  '�L' => '힜',
  '�M' => '힞',
  '�N' => '힟',
  '�O' => '힠',
  '�P' => '힡',
  '�Q' => '힢',
  '�R' => '힣',
  'ơ' => '퉤',
  'Ƣ' => '튀',
  'ƣ' => '튁',
  'Ƥ' => '튄',
  'ƥ' => '튈',
  'Ʀ' => '튐',
  'Ƨ' => '튑',
  'ƨ' => '튕',
  'Ʃ' => '튜',
  'ƪ' => '튠',
  'ƫ' => '튤',
  'Ƭ' => '튬',
  'ƭ' => '튱',
  'Ʈ' => '트',
  'Ư' => '특',
  'ư' => '튼',
  'Ʊ' => '튿',
  'Ʋ' => '틀',
  'Ƴ' => '틂',
  'ƴ' => '틈',
  'Ƶ' => '틉',
  'ƶ' => '틋',
  'Ʒ' => '틔',
  'Ƹ' => '틘',
  'ƹ' => '틜',
  'ƺ' => '틤',
  'ƻ' => '틥',
  'Ƽ' => '티',
  'ƽ' => '틱',
  'ƾ' => '틴',
  'ƿ' => '틸',
  '�' => '팀',
  '�' => '팁',
  '��' => '팃',
  '��' => '팅',
  '��' => '파',
  '��' => '팍',
  '��' => '팎',
  '��' => '판',
  '��' => '팔',
  '��' => '팖',
  '��' => '팜',
  '��' => '팝',
  '��' => '팟',
  '��' => '팠',
  '��' => '팡',
  '��' => '팥',
  '��' => '패',
  '��' => '팩',
  '��' => '팬',
  '��' => '팰',
  '��' => '팸',
  '��' => '팹',
  '��' => '팻',
  '��' => '팼',
  '��' => '팽',
  '��' => '퍄',
  '��' => '퍅',
  '��' => '퍼',
  '��' => '퍽',
  '��' => '펀',
  '��' => '펄',
  '��' => '펌',
  '��' => '펍',
  '��' => '펏',
  '��' => '펐',
  '��' => '펑',
  '��' => '페',
  '��' => '펙',
  '��' => '펜',
  '��' => '펠',
  '��' => '펨',
  '��' => '펩',
  '��' => '펫',
  '��' => '펭',
  '��' => '펴',
  '��' => '편',
  '��' => '펼',
  '��' => '폄',
  '��' => '폅',
  '��' => '폈',
  '��' => '평',
  '��' => '폐',
  '��' => '폘',
  '�' => '폡',
  '�' => '폣',
  '�' => '포',
  '�' => '폭',
  '�' => '폰',
  '�' => '폴',
  '�' => '폼',
  '�' => '폽',
  '�' => '폿',
  '�' => '퐁',
  'ǡ' => '퐈',
  'Ǣ' => '퐝',
  'ǣ' => '푀',
  'Ǥ' => '푄',
  'ǥ' => '표',
  'Ǧ' => '푠',
  'ǧ' => '푤',
  'Ǩ' => '푭',
  'ǩ' => '푯',
  'Ǫ' => '푸',
  'ǫ' => '푹',
  'Ǭ' => '푼',
  'ǭ' => '푿',
  'Ǯ' => '풀',
  'ǯ' => '풂',
  'ǰ' => '품',
  'DZ' => '풉',
  'Dz' => '풋',
  'dz' => '풍',
  'Ǵ' => '풔',
  'ǵ' => '풩',
  'Ƕ' => '퓌',
  'Ƿ' => '퓐',
  'Ǹ' => '퓔',
  'ǹ' => '퓜',
  'Ǻ' => '퓟',
  'ǻ' => '퓨',
  'Ǽ' => '퓬',
  'ǽ' => '퓰',
  'Ǿ' => '퓸',
  'ǿ' => '퓻',
  '�' => '퓽',
  '�' => '프',
  '��' => '픈',
  '��' => '플',
  '��' => '픔',
  '��' => '픕',
  '��' => '픗',
  '��' => '피',
  '��' => '픽',
  '��' => '핀',
  '��' => '필',
  '��' => '핌',
  '��' => '핍',
  '��' => '핏',
  '��' => '핑',
  '��' => '하',
  '��' => '학',
  '��' => '한',
  '��' => '할',
  '��' => '핥',
  '��' => '함',
  '��' => '합',
  '��' => '핫',
  '��' => '항',
  '��' => '해',
  '��' => '핵',
  '��' => '핸',
  '��' => '핼',
  '��' => '햄',
  '��' => '햅',
  '��' => '햇',
  '��' => '했',
  '��' => '행',
  '��' => '햐',
  '��' => '향',
  '��' => '허',
  '��' => '헉',
  '��' => '헌',
  '��' => '헐',
  '��' => '헒',
  '��' => '험',
  '��' => '헙',
  '��' => '헛',
  '��' => '헝',
  '��' => '헤',
  '��' => '헥',
  '��' => '헨',
  '��' => '헬',
  '��' => '헴',
  '��' => '헵',
  '��' => '헷',
  '��' => '헹',
  '��' => '혀',
  '�' => '혁',
  '�' => '현',
  '�' => '혈',
  '�' => '혐',
  '�' => '협',
  '�' => '혓',
  '�' => '혔',
  '�' => '형',
  '�' => '혜',
  '�' => '혠',
  'ȡ' => '혤',
  'Ȣ' => '혭',
  'ȣ' => '호',
  'Ȥ' => '혹',
  'ȥ' => '혼',
  'Ȧ' => '홀',
  'ȧ' => '홅',
  'Ȩ' => '홈',
  'ȩ' => '홉',
  'Ȫ' => '홋',
  'ȫ' => '홍',
  'Ȭ' => '홑',
  'ȭ' => '화',
  'Ȯ' => '확',
  'ȯ' => '환',
  'Ȱ' => '활',
  'ȱ' => '홧',
  'Ȳ' => '황',
  'ȳ' => '홰',
  'ȴ' => '홱',
  'ȵ' => '홴',
  'ȶ' => '횃',
  'ȷ' => '횅',
  'ȸ' => '회',
  'ȹ' => '획',
  'Ⱥ' => '횐',
  'Ȼ' => '횔',
  'ȼ' => '횝',
  'Ƚ' => '횟',
  'Ⱦ' => '횡',
  'ȿ' => '효',
  '�' => '횬',
  '�' => '횰',
  '��' => '횹',
  '��' => '횻',
  '��' => '후',
  '��' => '훅',
  '��' => '훈',
  '��' => '훌',
  '��' => '훑',
  '��' => '훔',
  '��' => '훗',
  '��' => '훙',
  '��' => '훠',
  '��' => '훤',
  '��' => '훨',
  '��' => '훰',
  '��' => '훵',
  '��' => '훼',
  '��' => '훽',
  '��' => '휀',
  '��' => '휄',
  '��' => '휑',
  '��' => '휘',
  '��' => '휙',
  '��' => '휜',
  '��' => '휠',
  '��' => '휨',
  '��' => '휩',
  '��' => '휫',
  '��' => '휭',
  '��' => '휴',
  '��' => '휵',
  '��' => '휸',
  '��' => '휼',
  '��' => '흄',
  '��' => '흇',
  '��' => '흉',
  '��' => '흐',
  '��' => '흑',
  '��' => '흔',
  '��' => '흖',
  '��' => '흗',
  '��' => '흘',
  '��' => '흙',
  '��' => '흠',
  '��' => '흡',
  '��' => '흣',
  '��' => '흥',
  '��' => '흩',
  '��' => '희',
  '��' => '흰',
  '��' => '흴',
  '��' => '흼',
  '�' => '흽',
  '�' => '힁',
  '�' => '히',
  '�' => '힉',
  '�' => '힌',
  '�' => '힐',
  '�' => '힘',
  '�' => '힙',
  '�' => '힛',
  '�' => '힝',
  'ʡ' => '伽',
  'ʢ' => '佳',
  'ʣ' => '假',
  'ʤ' => '價',
  'ʥ' => '加',
  'ʦ' => '可',
  'ʧ' => '呵',
  'ʨ' => '哥',
  'ʩ' => '嘉',
  'ʪ' => '嫁',
  'ʫ' => '家',
  'ʬ' => '暇',
  'ʭ' => '架',
  'ʮ' => '枷',
  'ʯ' => '柯',
  'ʰ' => '歌',
  'ʱ' => '珂',
  'ʲ' => '痂',
  'ʳ' => '稼',
  'ʴ' => '苛',
  'ʵ' => '茄',
  'ʶ' => '街',
  'ʷ' => '袈',
  'ʸ' => '訶',
  'ʹ' => '賈',
  'ʺ' => '跏',
  'ʻ' => '軻',
  'ʼ' => '迦',
  'ʽ' => '駕',
  'ʾ' => '刻',
  'ʿ' => '却',
  '�' => '各',
  '�' => '恪',
  '��' => '慤',
  '��' => '殼',
  '��' => '珏',
  '��' => '脚',
  '��' => '覺',
  '��' => '角',
  '��' => '閣',
  '��' => '侃',
  '��' => '刊',
  '��' => '墾',
  '��' => '奸',
  '��' => '姦',
  '��' => '干',
  '��' => '幹',
  '��' => '懇',
  '��' => '揀',
  '��' => '杆',
  '��' => '柬',
  '��' => '桿',
  '��' => '澗',
  '��' => '癎',
  '��' => '看',
  '��' => '磵',
  '��' => '稈',
  '��' => '竿',
  '��' => '簡',
  '��' => '肝',
  '��' => '艮',
  '��' => '艱',
  '��' => '諫',
  '��' => '間',
  '��' => '乫',
  '��' => '喝',
  '��' => '曷',
  '��' => '渴',
  '��' => '碣',
  '��' => '竭',
  '��' => '葛',
  '��' => '褐',
  '��' => '蝎',
  '��' => '鞨',
  '��' => '勘',
  '��' => '坎',
  '��' => '堪',
  '��' => '嵌',
  '��' => '感',
  '��' => '憾',
  '��' => '戡',
  '��' => '敢',
  '��' => '柑',
  '��' => '橄',
  '�' => '減',
  '�' => '甘',
  '�' => '疳',
  '�' => '監',
  '�' => '瞰',
  '�' => '紺',
  '�' => '邯',
  '�' => '鑑',
  '�' => '鑒',
  '�' => '龕',
  'ˡ' => '匣',
  'ˢ' => '岬',
  'ˣ' => '甲',
  'ˤ' => '胛',
  '˥' => '鉀',
  '˦' => '閘',
  '˧' => '剛',
  '˨' => '堈',
  '˩' => '姜',
  '˪' => '岡',
  '˫' => '崗',
  'ˬ' => '康',
  '˭' => '强',
  'ˮ' => '彊',
  '˯' => '慷',
  '˰' => '江',
  '˱' => '畺',
  '˲' => '疆',
  '˳' => '糠',
  '˴' => '絳',
  '˵' => '綱',
  '˶' => '羌',
  '˷' => '腔',
  '˸' => '舡',
  '˹' => '薑',
  '˺' => '襁',
  '˻' => '講',
  '˼' => '鋼',
  '˽' => '降',
  '˾' => '鱇',
  '˿' => '介',
  '�' => '价',
  '�' => '個',
  '��' => '凱',
  '��' => '塏',
  '��' => '愷',
  '��' => '愾',
  '��' => '慨',
  '��' => '改',
  '��' => '槪',
  '��' => '漑',
  '��' => '疥',
  '��' => '皆',
  '��' => '盖',
  '��' => '箇',
  '��' => '芥',
  '��' => '蓋',
  '��' => '豈',
  '��' => '鎧',
  '��' => '開',
  '��' => '喀',
  '��' => '客',
  '��' => '坑',
  '��' => '更',
  '��' => '粳',
  '��' => '羹',
  '��' => '醵',
  '��' => '倨',
  '��' => '去',
  '��' => '居',
  '��' => '巨',
  '��' => '拒',
  '��' => '据',
  '��' => '據',
  '��' => '擧',
  '��' => '渠',
  '��' => '炬',
  '��' => '祛',
  '��' => '距',
  '��' => '踞',
  '��' => '車',
  '��' => '遽',
  '��' => '鉅',
  '��' => '鋸',
  '��' => '乾',
  '��' => '件',
  '��' => '健',
  '��' => '巾',
  '��' => '建',
  '��' => '愆',
  '��' => '楗',
  '��' => '腱',
  '��' => '虔',
  '��' => '蹇',
  '�' => '鍵',
  '�' => '騫',
  '�' => '乞',
  '�' => '傑',
  '�' => '杰',
  '�' => '桀',
  '�' => '儉',
  '�' => '劍',
  '�' => '劒',
  '�' => '檢',
  '̡' => '瞼',
  '̢' => '鈐',
  '̣' => '黔',
  '̤' => '劫',
  '̥' => '怯',
  '̦' => '迲',
  '̧' => '偈',
  '̨' => '憩',
  '̩' => '揭',
  '̪' => '擊',
  '̫' => '格',
  '̬' => '檄',
  '̭' => '激',
  '̮' => '膈',
  '̯' => '覡',
  '̰' => '隔',
  '̱' => '堅',
  '̲' => '牽',
  '̳' => '犬',
  '̴' => '甄',
  '̵' => '絹',
  '̶' => '繭',
  '̷' => '肩',
  '̸' => '見',
  '̹' => '譴',
  '̺' => '遣',
  '̻' => '鵑',
  '̼' => '抉',
  '̽' => '決',
  '̾' => '潔',
  '̿' => '結',
  '�' => '缺',
  '�' => '訣',
  '��' => '兼',
  '��' => '慊',
  '��' => '箝',
  '��' => '謙',
  '��' => '鉗',
  '��' => '鎌',
  '��' => '京',
  '��' => '俓',
  '��' => '倞',
  '��' => '傾',
  '��' => '儆',
  '��' => '勁',
  '��' => '勍',
  '��' => '卿',
  '��' => '坰',
  '��' => '境',
  '��' => '庚',
  '��' => '徑',
  '��' => '慶',
  '��' => '憬',
  '��' => '擎',
  '��' => '敬',
  '��' => '景',
  '��' => '暻',
  '��' => '更',
  '��' => '梗',
  '��' => '涇',
  '��' => '炅',
  '��' => '烱',
  '��' => '璟',
  '��' => '璥',
  '��' => '瓊',
  '��' => '痙',
  '��' => '硬',
  '��' => '磬',
  '��' => '竟',
  '��' => '競',
  '��' => '絅',
  '��' => '經',
  '��' => '耕',
  '��' => '耿',
  '��' => '脛',
  '��' => '莖',
  '��' => '警',
  '��' => '輕',
  '��' => '逕',
  '��' => '鏡',
  '��' => '頃',
  '��' => '頸',
  '��' => '驚',
  '��' => '鯨',
  '�' => '係',
  '�' => '啓',
  '�' => '堺',
  '�' => '契',
  '�' => '季',
  '�' => '屆',
  '�' => '悸',
  '�' => '戒',
  '�' => '桂',
  '�' => '械',
  '͡' => '棨',
  '͢' => '溪',
  'ͣ' => '界',
  'ͤ' => '癸',
  'ͥ' => '磎',
  'ͦ' => '稽',
  'ͧ' => '系',
  'ͨ' => '繫',
  'ͩ' => '繼',
  'ͪ' => '計',
  'ͫ' => '誡',
  'ͬ' => '谿',
  'ͭ' => '階',
  'ͮ' => '鷄',
  'ͯ' => '古',
  'Ͱ' => '叩',
  'ͱ' => '告',
  'Ͳ' => '呱',
  'ͳ' => '固',
  'ʹ' => '姑',
  '͵' => '孤',
  'Ͷ' => '尻',
  'ͷ' => '庫',
  '͸' => '拷',
  '͹' => '攷',
  'ͺ' => '故',
  'ͻ' => '敲',
  'ͼ' => '暠',
  'ͽ' => '枯',
  ';' => '槁',
  'Ϳ' => '沽',
  '�' => '痼',
  '�' => '皐',
  '��' => '睾',
  '��' => '稿',
  '��' => '羔',
  '��' => '考',
  '��' => '股',
  '��' => '膏',
  '��' => '苦',
  '��' => '苽',
  '��' => '菰',
  '��' => '藁',
  '��' => '蠱',
  '��' => '袴',
  '��' => '誥',
  '��' => '賈',
  '��' => '辜',
  '��' => '錮',
  '��' => '雇',
  '��' => '顧',
  '��' => '高',
  '��' => '鼓',
  '��' => '哭',
  '��' => '斛',
  '��' => '曲',
  '��' => '梏',
  '��' => '穀',
  '��' => '谷',
  '��' => '鵠',
  '��' => '困',
  '��' => '坤',
  '��' => '崑',
  '��' => '昆',
  '��' => '梱',
  '��' => '棍',
  '��' => '滾',
  '��' => '琨',
  '��' => '袞',
  '��' => '鯤',
  '��' => '汨',
  '��' => '滑',
  '��' => '骨',
  '��' => '供',
  '��' => '公',
  '��' => '共',
  '��' => '功',
  '��' => '孔',
  '��' => '工',
  '��' => '恐',
  '��' => '恭',
  '��' => '拱',
  '��' => '控',
  '��' => '攻',
  '�' => '珙',
  '�' => '空',
  '�' => '蚣',
  '�' => '貢',
  '�' => '鞏',
  '�' => '串',
  '�' => '寡',
  '�' => '戈',
  '�' => '果',
  '�' => '瓜',
  'Ρ' => '科',
  '΢' => '菓',
  'Σ' => '誇',
  'Τ' => '課',
  'Υ' => '跨',
  'Φ' => '過',
  'Χ' => '鍋',
  'Ψ' => '顆',
  'Ω' => '廓',
  'Ϊ' => '槨',
  'Ϋ' => '藿',
  'ά' => '郭',
  'έ' => '串',
  'ή' => '冠',
  'ί' => '官',
  'ΰ' => '寬',
  'α' => '慣',
  'β' => '棺',
  'γ' => '款',
  'δ' => '灌',
  'ε' => '琯',
  'ζ' => '瓘',
  'η' => '管',
  'θ' => '罐',
  'ι' => '菅',
  'κ' => '觀',
  'λ' => '貫',
  'μ' => '關',
  'ν' => '館',
  'ξ' => '刮',
  'ο' => '恝',
  '�' => '括',
  '�' => '适',
  '��' => '侊',
  '��' => '光',
  '��' => '匡',
  '��' => '壙',
  '��' => '廣',
  '��' => '曠',
  '��' => '洸',
  '��' => '炚',
  '��' => '狂',
  '��' => '珖',
  '��' => '筐',
  '��' => '胱',
  '��' => '鑛',
  '��' => '卦',
  '��' => '掛',
  '��' => '罫',
  '��' => '乖',
  '��' => '傀',
  '��' => '塊',
  '��' => '壞',
  '��' => '怪',
  '��' => '愧',
  '��' => '拐',
  '��' => '槐',
  '��' => '魁',
  '��' => '宏',
  '��' => '紘',
  '��' => '肱',
  '��' => '轟',
  '��' => '交',
  '��' => '僑',
  '��' => '咬',
  '��' => '喬',
  '��' => '嬌',
  '��' => '嶠',
  '��' => '巧',
  '��' => '攪',
  '��' => '敎',
  '��' => '校',
  '��' => '橋',
  '��' => '狡',
  '��' => '皎',
  '��' => '矯',
  '��' => '絞',
  '��' => '翹',
  '��' => '膠',
  '��' => '蕎',
  '��' => '蛟',
  '��' => '較',
  '��' => '轎',
  '��' => '郊',
  '�' => '餃',
  '�' => '驕',
  '�' => '鮫',
  '�' => '丘',
  '�' => '久',
  '�' => '九',
  '�' => '仇',
  '�' => '俱',
  '�' => '具',
  '�' => '勾',
  'ϡ' => '區',
  'Ϣ' => '口',
  'ϣ' => '句',
  'Ϥ' => '咎',
  'ϥ' => '嘔',
  'Ϧ' => '坵',
  'ϧ' => '垢',
  'Ϩ' => '寇',
  'ϩ' => '嶇',
  'Ϫ' => '廐',
  'ϫ' => '懼',
  'Ϭ' => '拘',
  'ϭ' => '救',
  'Ϯ' => '枸',
  'ϯ' => '柩',
  'ϰ' => '構',
  'ϱ' => '歐',
  'ϲ' => '毆',
  'ϳ' => '毬',
  'ϴ' => '求',
  'ϵ' => '溝',
  '϶' => '灸',
  'Ϸ' => '狗',
  'ϸ' => '玖',
  'Ϲ' => '球',
  'Ϻ' => '瞿',
  'ϻ' => '矩',
  'ϼ' => '究',
  'Ͻ' => '絿',
  'Ͼ' => '耉',
  'Ͽ' => '臼',
  '�' => '舅',
  '�' => '舊',
  '��' => '苟',
  '��' => '衢',
  '��' => '謳',
  '��' => '購',
  '��' => '軀',
  '��' => '逑',
  '��' => '邱',
  '��' => '鉤',
  '��' => '銶',
  '��' => '駒',
  '��' => '驅',
  '��' => '鳩',
  '��' => '鷗',
  '��' => '龜',
  '��' => '國',
  '��' => '局',
  '��' => '菊',
  '��' => '鞠',
  '��' => '鞫',
  '��' => '麴',
  '��' => '君',
  '��' => '窘',
  '��' => '群',
  '��' => '裙',
  '��' => '軍',
  '��' => '郡',
  '��' => '堀',
  '��' => '屈',
  '��' => '掘',
  '��' => '窟',
  '��' => '宮',
  '��' => '弓',
  '��' => '穹',
  '��' => '窮',
  '��' => '芎',
  '��' => '躬',
  '��' => '倦',
  '��' => '券',
  '��' => '勸',
  '��' => '卷',
  '��' => '圈',
  '��' => '拳',
  '��' => '捲',
  '��' => '權',
  '��' => '淃',
  '��' => '眷',
  '��' => '厥',
  '��' => '獗',
  '��' => '蕨',
  '��' => '蹶',
  '��' => '闕',
  '�' => '机',
  '�' => '櫃',
  '�' => '潰',
  '�' => '詭',
  '�' => '軌',
  '�' => '饋',
  '�' => '句',
  '�' => '晷',
  '�' => '歸',
  '�' => '貴',
  'С' => '鬼',
  'Т' => '龜',
  'У' => '叫',
  'Ф' => '圭',
  'Х' => '奎',
  'Ц' => '揆',
  'Ч' => '槻',
  'Ш' => '珪',
  'Щ' => '硅',
  'Ъ' => '窺',
  'Ы' => '竅',
  'Ь' => '糾',
  'Э' => '葵',
  'Ю' => '規',
  'Я' => '赳',
  'а' => '逵',
  'б' => '閨',
  'в' => '勻',
  'г' => '均',
  'д' => '畇',
  'е' => '筠',
  'ж' => '菌',
  'з' => '鈞',
  'и' => '龜',
  'й' => '橘',
  'к' => '克',
  'л' => '剋',
  'м' => '劇',
  'н' => '戟',
  'о' => '棘',
  'п' => '極',
  '�' => '隙',
  '�' => '僅',
  '��' => '劤',
  '��' => '勤',
  '��' => '懃',
  '��' => '斤',
  '��' => '根',
  '��' => '槿',
  '��' => '瑾',
  '��' => '筋',
  '��' => '芹',
  '��' => '菫',
  '��' => '覲',
  '��' => '謹',
  '��' => '近',
  '��' => '饉',
  '��' => '契',
  '��' => '今',
  '��' => '妗',
  '��' => '擒',
  '��' => '昑',
  '��' => '檎',
  '��' => '琴',
  '��' => '禁',
  '��' => '禽',
  '��' => '芩',
  '��' => '衾',
  '��' => '衿',
  '��' => '襟',
  '��' => '金',
  '��' => '錦',
  '��' => '伋',
  '��' => '及',
  '��' => '急',
  '��' => '扱',
  '��' => '汲',
  '��' => '級',
  '��' => '給',
  '��' => '亘',
  '��' => '兢',
  '��' => '矜',
  '��' => '肯',
  '��' => '企',
  '��' => '伎',
  '��' => '其',
  '��' => '冀',
  '��' => '嗜',
  '��' => '器',
  '��' => '圻',
  '��' => '基',
  '��' => '埼',
  '��' => '夔',
  '��' => '奇',
  '�' => '妓',
  '�' => '寄',
  '�' => '岐',
  '�' => '崎',
  '�' => '己',
  '�' => '幾',
  '�' => '忌',
  '�' => '技',
  '�' => '旗',
  '�' => '旣',
  'ѡ' => '朞',
  'Ѣ' => '期',
  'ѣ' => '杞',
  'Ѥ' => '棋',
  'ѥ' => '棄',
  'Ѧ' => '機',
  'ѧ' => '欺',
  'Ѩ' => '氣',
  'ѩ' => '汽',
  'Ѫ' => '沂',
  'ѫ' => '淇',
  'Ѭ' => '玘',
  'ѭ' => '琦',
  'Ѯ' => '琪',
  'ѯ' => '璂',
  'Ѱ' => '璣',
  'ѱ' => '畸',
  'Ѳ' => '畿',
  'ѳ' => '碁',
  'Ѵ' => '磯',
  'ѵ' => '祁',
  'Ѷ' => '祇',
  'ѷ' => '祈',
  'Ѹ' => '祺',
  'ѹ' => '箕',
  'Ѻ' => '紀',
  'ѻ' => '綺',
  'Ѽ' => '羈',
  'ѽ' => '耆',
  'Ѿ' => '耭',
  'ѿ' => '肌',
  '�' => '記',
  '�' => '譏',
  '��' => '豈',
  '��' => '起',
  '��' => '錡',
  '��' => '錤',
  '��' => '飢',
  '��' => '饑',
  '��' => '騎',
  '��' => '騏',
  '��' => '驥',
  '��' => '麒',
  '��' => '緊',
  '��' => '佶',
  '��' => '吉',
  '��' => '拮',
  '��' => '桔',
  '��' => '金',
  '��' => '喫',
  '��' => '儺',
  '��' => '喇',
  '��' => '奈',
  '��' => '娜',
  '��' => '懦',
  '��' => '懶',
  '��' => '拏',
  '��' => '拿',
  '��' => '癩',
  '��' => '羅',
  '��' => '蘿',
  '��' => '螺',
  '��' => '裸',
  '��' => '邏',
  '��' => '那',
  '��' => '樂',
  '��' => '洛',
  '��' => '烙',
  '��' => '珞',
  '��' => '落',
  '��' => '諾',
  '��' => '酪',
  '��' => '駱',
  '��' => '亂',
  '��' => '卵',
  '��' => '暖',
  '��' => '欄',
  '��' => '煖',
  '��' => '爛',
  '��' => '蘭',
  '��' => '難',
  '��' => '鸞',
  '��' => '捏',
  '��' => '捺',
  '�' => '南',
  '�' => '嵐',
  '�' => '枏',
  '�' => '楠',
  '�' => '湳',
  '�' => '濫',
  '�' => '男',
  '�' => '藍',
  '�' => '襤',
  '�' => '拉',
  'ҡ' => '納',
  'Ң' => '臘',
  'ң' => '蠟',
  'Ҥ' => '衲',
  'ҥ' => '囊',
  'Ҧ' => '娘',
  'ҧ' => '廊',
  'Ҩ' => '朗',
  'ҩ' => '浪',
  'Ҫ' => '狼',
  'ҫ' => '郎',
  'Ҭ' => '乃',
  'ҭ' => '來',
  'Ү' => '內',
  'ү' => '奈',
  'Ұ' => '柰',
  'ұ' => '耐',
  'Ҳ' => '冷',
  'ҳ' => '女',
  'Ҵ' => '年',
  'ҵ' => '撚',
  'Ҷ' => '秊',
  'ҷ' => '念',
  'Ҹ' => '恬',
  'ҹ' => '拈',
  'Һ' => '捻',
  'һ' => '寧',
  'Ҽ' => '寗',
  'ҽ' => '努',
  'Ҿ' => '勞',
  'ҿ' => '奴',
  '�' => '弩',
  '�' => '怒',
  '��' => '擄',
  '��' => '櫓',
  '��' => '爐',
  '��' => '瑙',
  '��' => '盧',
  '��' => '老',
  '��' => '蘆',
  '��' => '虜',
  '��' => '路',
  '��' => '露',
  '��' => '駑',
  '��' => '魯',
  '��' => '鷺',
  '��' => '碌',
  '��' => '祿',
  '��' => '綠',
  '��' => '菉',
  '��' => '錄',
  '��' => '鹿',
  '��' => '論',
  '��' => '壟',
  '��' => '弄',
  '��' => '濃',
  '��' => '籠',
  '��' => '聾',
  '��' => '膿',
  '��' => '農',
  '��' => '惱',
  '��' => '牢',
  '��' => '磊',
  '��' => '腦',
  '��' => '賂',
  '��' => '雷',
  '��' => '尿',
  '��' => '壘',
  '��' => '屢',
  '��' => '樓',
  '��' => '淚',
  '��' => '漏',
  '��' => '累',
  '��' => '縷',
  '��' => '陋',
  '��' => '嫩',
  '��' => '訥',
  '��' => '杻',
  '��' => '紐',
  '��' => '勒',
  '��' => '肋',
  '��' => '凜',
  '��' => '凌',
  '��' => '稜',
  '�' => '綾',
  '�' => '能',
  '�' => '菱',
  '�' => '陵',
  '�' => '尼',
  '�' => '泥',
  '�' => '匿',
  '�' => '溺',
  '�' => '多',
  '�' => '茶',
  'ӡ' => '丹',
  'Ӣ' => '亶',
  'ӣ' => '但',
  'Ӥ' => '單',
  'ӥ' => '團',
  'Ӧ' => '壇',
  'ӧ' => '彖',
  'Ө' => '斷',
  'ө' => '旦',
  'Ӫ' => '檀',
  'ӫ' => '段',
  'Ӭ' => '湍',
  'ӭ' => '短',
  'Ӯ' => '端',
  'ӯ' => '簞',
  'Ӱ' => '緞',
  'ӱ' => '蛋',
  'Ӳ' => '袒',
  'ӳ' => '鄲',
  'Ӵ' => '鍛',
  'ӵ' => '撻',
  'Ӷ' => '澾',
  'ӷ' => '獺',
  'Ӹ' => '疸',
  'ӹ' => '達',
  'Ӻ' => '啖',
  'ӻ' => '坍',
  'Ӽ' => '憺',
  'ӽ' => '擔',
  'Ӿ' => '曇',
  'ӿ' => '淡',
  '�' => '湛',
  '�' => '潭',
  '��' => '澹',
  '��' => '痰',
  '��' => '聃',
  '��' => '膽',
  '��' => '蕁',
  '��' => '覃',
  '��' => '談',
  '��' => '譚',
  '��' => '錟',
  '��' => '沓',
  '��' => '畓',
  '��' => '答',
  '��' => '踏',
  '��' => '遝',
  '��' => '唐',
  '��' => '堂',
  '��' => '塘',
  '��' => '幢',
  '��' => '戇',
  '��' => '撞',
  '��' => '棠',
  '��' => '當',
  '��' => '糖',
  '��' => '螳',
  '��' => '黨',
  '��' => '代',
  '��' => '垈',
  '��' => '坮',
  '��' => '大',
  '��' => '對',
  '��' => '岱',
  '��' => '帶',
  '��' => '待',
  '��' => '戴',
  '��' => '擡',
  '��' => '玳',
  '��' => '臺',
  '��' => '袋',
  '��' => '貸',
  '��' => '隊',
  '��' => '黛',
  '��' => '宅',
  '��' => '德',
  '��' => '悳',
  '��' => '倒',
  '��' => '刀',
  '��' => '到',
  '��' => '圖',
  '��' => '堵',
  '��' => '塗',
  '��' => '導',
  '�' => '屠',
  '�' => '島',
  '�' => '嶋',
  '�' => '度',
  '�' => '徒',
  '�' => '悼',
  '�' => '挑',
  '�' => '掉',
  '�' => '搗',
  '�' => '桃',
  'ԡ' => '棹',
  'Ԣ' => '櫂',
  'ԣ' => '淘',
  'Ԥ' => '渡',
  'ԥ' => '滔',
  'Ԧ' => '濤',
  'ԧ' => '燾',
  'Ԩ' => '盜',
  'ԩ' => '睹',
  'Ԫ' => '禱',
  'ԫ' => '稻',
  'Ԭ' => '萄',
  'ԭ' => '覩',
  'Ԯ' => '賭',
  'ԯ' => '跳',
  '԰' => '蹈',
  'Ա' => '逃',
  'Բ' => '途',
  'Գ' => '道',
  'Դ' => '都',
  'Ե' => '鍍',
  'Զ' => '陶',
  'Է' => '韜',
  'Ը' => '毒',
  'Թ' => '瀆',
  'Ժ' => '牘',
  'Ի' => '犢',
  'Լ' => '獨',
  'Խ' => '督',
  'Ծ' => '禿',
  'Կ' => '篤',
  '�' => '纛',
  '�' => '讀',
  '��' => '墩',
  '��' => '惇',
  '��' => '敦',
  '��' => '旽',
  '��' => '暾',
  '��' => '沌',
  '��' => '焞',
  '��' => '燉',
  '��' => '豚',
  '��' => '頓',
  '��' => '乭',
  '��' => '突',
  '��' => '仝',
  '��' => '冬',
  '��' => '凍',
  '��' => '動',
  '��' => '同',
  '��' => '憧',
  '��' => '東',
  '��' => '桐',
  '��' => '棟',
  '��' => '洞',
  '��' => '潼',
  '��' => '疼',
  '��' => '瞳',
  '��' => '童',
  '��' => '胴',
  '��' => '董',
  '��' => '銅',
  '��' => '兜',
  '��' => '斗',
  '��' => '杜',
  '��' => '枓',
  '��' => '痘',
  '��' => '竇',
  '��' => '荳',
  '��' => '讀',
  '��' => '豆',
  '��' => '逗',
  '��' => '頭',
  '��' => '屯',
  '��' => '臀',
  '��' => '芚',
  '��' => '遁',
  '��' => '遯',
  '��' => '鈍',
  '��' => '得',
  '��' => '嶝',
  '��' => '橙',
  '��' => '燈',
  '��' => '登',
  '�' => '等',
  '�' => '藤',
  '�' => '謄',
  '�' => '鄧',
  '�' => '騰',
  '�' => '喇',
  '�' => '懶',
  '�' => '拏',
  '�' => '癩',
  '�' => '羅',
  'ա' => '蘿',
  'բ' => '螺',
  'գ' => '裸',
  'դ' => '邏',
  'ե' => '樂',
  'զ' => '洛',
  'է' => '烙',
  'ը' => '珞',
  'թ' => '絡',
  'ժ' => '落',
  'ի' => '諾',
  'լ' => '酪',
  'խ' => '駱',
  'ծ' => '丹',
  'կ' => '亂',
  'հ' => '卵',
  'ձ' => '欄',
  'ղ' => '欒',
  'ճ' => '瀾',
  'մ' => '爛',
  'յ' => '蘭',
  'ն' => '鸞',
  'շ' => '剌',
  'ո' => '辣',
  'չ' => '嵐',
  'պ' => '擥',
  'ջ' => '攬',
  'ռ' => '欖',
  'ս' => '濫',
  'վ' => '籃',
  'տ' => '纜',
  '�' => '藍',
  '�' => '襤',
  '��' => '覽',
  '��' => '拉',
  '��' => '臘',
  '��' => '蠟',
  '��' => '廊',
  '��' => '朗',
  '��' => '浪',
  '��' => '狼',
  '��' => '琅',
  '��' => '瑯',
  '��' => '螂',
  '��' => '郞',
  '��' => '來',
  '��' => '崍',
  '��' => '徠',
  '��' => '萊',
  '��' => '冷',
  '��' => '掠',
  '��' => '略',
  '��' => '亮',
  '��' => '倆',
  '��' => '兩',
  '��' => '凉',
  '��' => '梁',
  '��' => '樑',
  '��' => '粮',
  '��' => '粱',
  '��' => '糧',
  '��' => '良',
  '��' => '諒',
  '��' => '輛',
  '��' => '量',
  '��' => '侶',
  '��' => '儷',
  '��' => '勵',
  '��' => '呂',
  '��' => '廬',
  '��' => '慮',
  '��' => '戾',
  '��' => '旅',
  '��' => '櫚',
  '��' => '濾',
  '��' => '礪',
  '��' => '藜',
  '��' => '蠣',
  '��' => '閭',
  '��' => '驢',
  '��' => '驪',
  '��' => '麗',
  '��' => '黎',
  '��' => '力',
  '�' => '曆',
  '�' => '歷',
  '�' => '瀝',
  '�' => '礫',
  '�' => '轢',
  '�' => '靂',
  '�' => '憐',
  '�' => '戀',
  '�' => '攣',
  '�' => '漣',
  '֡' => '煉',
  '֢' => '璉',
  '֣' => '練',
  '֤' => '聯',
  '֥' => '蓮',
  '֦' => '輦',
  '֧' => '連',
  '֨' => '鍊',
  '֩' => '冽',
  '֪' => '列',
  '֫' => '劣',
  '֬' => '洌',
  '֭' => '烈',
  '֮' => '裂',
  '֯' => '廉',
  'ְ' => '斂',
  'ֱ' => '殮',
  'ֲ' => '濂',
  'ֳ' => '簾',
  'ִ' => '獵',
  'ֵ' => '令',
  'ֶ' => '伶',
  'ַ' => '囹',
  'ָ' => '寧',
  'ֹ' => '岺',
  'ֺ' => '嶺',
  'ֻ' => '怜',
  'ּ' => '玲',
  'ֽ' => '笭',
  '־' => '羚',
  'ֿ' => '翎',
  '�' => '聆',
  '�' => '逞',
  '��' => '鈴',
  '��' => '零',
  '��' => '靈',
  '��' => '領',
  '��' => '齡',
  '��' => '例',
  '��' => '澧',
  '��' => '禮',
  '��' => '醴',
  '��' => '隷',
  '��' => '勞',
  '��' => '怒',
  '��' => '撈',
  '��' => '擄',
  '��' => '櫓',
  '��' => '潞',
  '��' => '瀘',
  '��' => '爐',
  '��' => '盧',
  '��' => '老',
  '��' => '蘆',
  '��' => '虜',
  '��' => '路',
  '��' => '輅',
  '��' => '露',
  '��' => '魯',
  '��' => '鷺',
  '��' => '鹵',
  '��' => '碌',
  '��' => '祿',
  '��' => '綠',
  '��' => '菉',
  '��' => '錄',
  '��' => '鹿',
  '��' => '麓',
  '��' => '論',
  '��' => '壟',
  '��' => '弄',
  '��' => '朧',
  '��' => '瀧',
  '��' => '瓏',
  '��' => '籠',
  '��' => '聾',
  '��' => '儡',
  '��' => '瀨',
  '��' => '牢',
  '��' => '磊',
  '��' => '賂',
  '��' => '賚',
  '��' => '賴',
  '��' => '雷',
  '�' => '了',
  '�' => '僚',
  '�' => '寮',
  '�' => '廖',
  '�' => '料',
  '�' => '燎',
  '�' => '療',
  '�' => '瞭',
  '�' => '聊',
  '�' => '蓼',
  'ס' => '遼',
  'ע' => '鬧',
  'ף' => '龍',
  'פ' => '壘',
  'ץ' => '婁',
  'צ' => '屢',
  'ק' => '樓',
  'ר' => '淚',
  'ש' => '漏',
  'ת' => '瘻',
  '׫' => '累',
  '׬' => '縷',
  '׭' => '蔞',
  '׮' => '褸',
  'ׯ' => '鏤',
  'װ' => '陋',
  'ױ' => '劉',
  'ײ' => '旒',
  '׳' => '柳',
  '״' => '榴',
  '׵' => '流',
  '׶' => '溜',
  '׷' => '瀏',
  '׸' => '琉',
  '׹' => '瑠',
  '׺' => '留',
  '׻' => '瘤',
  '׼' => '硫',
  '׽' => '謬',
  '׾' => '類',
  '׿' => '六',
  '�' => '戮',
  '�' => '陸',
  '��' => '侖',
  '��' => '倫',
  '��' => '崙',
  '��' => '淪',
  '��' => '綸',
  '��' => '輪',
  '��' => '律',
  '��' => '慄',
  '��' => '栗',
  '��' => '率',
  '��' => '隆',
  '��' => '勒',
  '��' => '肋',
  '��' => '凜',
  '��' => '凌',
  '��' => '楞',
  '��' => '稜',
  '��' => '綾',
  '��' => '菱',
  '��' => '陵',
  '��' => '俚',
  '��' => '利',
  '��' => '厘',
  '��' => '吏',
  '��' => '唎',
  '��' => '履',
  '��' => '悧',
  '��' => '李',
  '��' => '梨',
  '��' => '浬',
  '��' => '犁',
  '��' => '狸',
  '��' => '理',
  '��' => '璃',
  '��' => '異',
  '��' => '痢',
  '��' => '籬',
  '��' => '罹',
  '��' => '羸',
  '��' => '莉',
  '��' => '裏',
  '��' => '裡',
  '��' => '里',
  '��' => '釐',
  '��' => '離',
  '��' => '鯉',
  '��' => '吝',
  '��' => '潾',
  '��' => '燐',
  '��' => '璘',
  '��' => '藺',
  '�' => '躪',
  '�' => '隣',
  '�' => '鱗',
  '�' => '麟',
  '�' => '林',
  '�' => '淋',
  '�' => '琳',
  '�' => '臨',
  '�' => '霖',
  '�' => '砬',
  'ء' => '立',
  'آ' => '笠',
  'أ' => '粒',
  'ؤ' => '摩',
  'إ' => '瑪',
  'ئ' => '痲',
  'ا' => '碼',
  'ب' => '磨',
  'ة' => '馬',
  'ت' => '魔',
  'ث' => '麻',
  'ج' => '寞',
  'ح' => '幕',
  'خ' => '漠',
  'د' => '膜',
  'ذ' => '莫',
  'ر' => '邈',
  'ز' => '万',
  'س' => '卍',
  'ش' => '娩',
  'ص' => '巒',
  'ض' => '彎',
  'ط' => '慢',
  'ظ' => '挽',
  'ع' => '晩',
  'غ' => '曼',
  'ػ' => '滿',
  'ؼ' => '漫',
  'ؽ' => '灣',
  'ؾ' => '瞞',
  'ؿ' => '萬',
  '�' => '蔓',
  '�' => '蠻',
  '��' => '輓',
  '��' => '饅',
  '��' => '鰻',
  '��' => '唜',
  '��' => '抹',
  '��' => '末',
  '��' => '沫',
  '��' => '茉',
  '��' => '襪',
  '��' => '靺',
  '��' => '亡',
  '��' => '妄',
  '��' => '忘',
  '��' => '忙',
  '��' => '望',
  '��' => '網',
  '��' => '罔',
  '��' => '芒',
  '��' => '茫',
  '��' => '莽',
  '��' => '輞',
  '��' => '邙',
  '��' => '埋',
  '��' => '妹',
  '��' => '媒',
  '��' => '寐',
  '��' => '昧',
  '��' => '枚',
  '��' => '梅',
  '��' => '每',
  '��' => '煤',
  '��' => '罵',
  '��' => '買',
  '��' => '賣',
  '��' => '邁',
  '��' => '魅',
  '��' => '脈',
  '��' => '貊',
  '��' => '陌',
  '��' => '驀',
  '��' => '麥',
  '��' => '孟',
  '��' => '氓',
  '��' => '猛',
  '��' => '盲',
  '��' => '盟',
  '��' => '萌',
  '��' => '冪',
  '��' => '覓',
  '��' => '免',
  '��' => '冕',
  '�' => '勉',
  '�' => '棉',
  '�' => '沔',
  '�' => '眄',
  '�' => '眠',
  '�' => '綿',
  '�' => '緬',
  '�' => '面',
  '�' => '麵',
  '�' => '滅',
  '١' => '蔑',
  '٢' => '冥',
  '٣' => '名',
  '٤' => '命',
  '٥' => '明',
  '٦' => '暝',
  '٧' => '椧',
  '٨' => '溟',
  '٩' => '皿',
  '٪' => '瞑',
  '٫' => '茗',
  '٬' => '蓂',
  '٭' => '螟',
  'ٮ' => '酩',
  'ٯ' => '銘',
  'ٰ' => '鳴',
  'ٱ' => '袂',
  'ٲ' => '侮',
  'ٳ' => '冒',
  'ٴ' => '募',
  'ٵ' => '姆',
  'ٶ' => '帽',
  'ٷ' => '慕',
  'ٸ' => '摸',
  'ٹ' => '摹',
  'ٺ' => '暮',
  'ٻ' => '某',
  'ټ' => '模',
  'ٽ' => '母',
  'پ' => '毛',
  'ٿ' => '牟',
  '�' => '牡',
  '�' => '瑁',
  '��' => '眸',
  '��' => '矛',
  '��' => '耗',
  '��' => '芼',
  '��' => '茅',
  '��' => '謀',
  '��' => '謨',
  '��' => '貌',
  '��' => '木',
  '��' => '沐',
  '��' => '牧',
  '��' => '目',
  '��' => '睦',
  '��' => '穆',
  '��' => '鶩',
  '��' => '歿',
  '��' => '沒',
  '��' => '夢',
  '��' => '朦',
  '��' => '蒙',
  '��' => '卯',
  '��' => '墓',
  '��' => '妙',
  '��' => '廟',
  '��' => '描',
  '��' => '昴',
  '��' => '杳',
  '��' => '渺',
  '��' => '猫',
  '��' => '竗',
  '��' => '苗',
  '��' => '錨',
  '��' => '務',
  '��' => '巫',
  '��' => '憮',
  '��' => '懋',
  '��' => '戊',
  '��' => '拇',
  '��' => '撫',
  '��' => '无',
  '��' => '楙',
  '��' => '武',
  '��' => '毋',
  '��' => '無',
  '��' => '珷',
  '��' => '畝',
  '��' => '繆',
  '��' => '舞',
  '��' => '茂',
  '��' => '蕪',
  '��' => '誣',
  '�' => '貿',
  '�' => '霧',
  '�' => '鵡',
  '�' => '墨',
  '�' => '默',
  '�' => '們',
  '�' => '刎',
  '�' => '吻',
  '�' => '問',
  '�' => '文',
  'ڡ' => '汶',
  'ڢ' => '紊',
  'ڣ' => '紋',
  'ڤ' => '聞',
  'ڥ' => '蚊',
  'ڦ' => '門',
  'ڧ' => '雯',
  'ڨ' => '勿',
  'ک' => '沕',
  'ڪ' => '物',
  'ګ' => '味',
  'ڬ' => '媚',
  'ڭ' => '尾',
  'ڮ' => '嵋',
  'گ' => '彌',
  'ڰ' => '微',
  'ڱ' => '未',
  'ڲ' => '梶',
  'ڳ' => '楣',
  'ڴ' => '渼',
  'ڵ' => '湄',
  'ڶ' => '眉',
  'ڷ' => '米',
  'ڸ' => '美',
  'ڹ' => '薇',
  'ں' => '謎',
  'ڻ' => '迷',
  'ڼ' => '靡',
  'ڽ' => '黴',
  'ھ' => '岷',
  'ڿ' => '悶',
  '�' => '愍',
  '�' => '憫',
  '��' => '敏',
  '��' => '旻',
  '��' => '旼',
  '��' => '民',
  '��' => '泯',
  '��' => '玟',
  '��' => '珉',
  '��' => '緡',
  '��' => '閔',
  '��' => '密',
  '��' => '蜜',
  '��' => '謐',
  '��' => '剝',
  '��' => '博',
  '��' => '拍',
  '��' => '搏',
  '��' => '撲',
  '��' => '朴',
  '��' => '樸',
  '��' => '泊',
  '��' => '珀',
  '��' => '璞',
  '��' => '箔',
  '��' => '粕',
  '��' => '縛',
  '��' => '膊',
  '��' => '舶',
  '��' => '薄',
  '��' => '迫',
  '��' => '雹',
  '��' => '駁',
  '��' => '伴',
  '��' => '半',
  '��' => '反',
  '��' => '叛',
  '��' => '拌',
  '��' => '搬',
  '��' => '攀',
  '��' => '斑',
  '��' => '槃',
  '��' => '泮',
  '��' => '潘',
  '��' => '班',
  '��' => '畔',
  '��' => '瘢',
  '��' => '盤',
  '��' => '盼',
  '��' => '磐',
  '��' => '磻',
  '��' => '礬',
  '��' => '絆',
  '�' => '般',
  '�' => '蟠',
  '�' => '返',
  '�' => '頒',
  '�' => '飯',
  '�' => '勃',
  '�' => '拔',
  '�' => '撥',
  '�' => '渤',
  '�' => '潑',
  'ۡ' => '發',
  'ۢ' => '跋',
  'ۣ' => '醱',
  'ۤ' => '鉢',
  'ۥ' => '髮',
  'ۦ' => '魃',
  'ۧ' => '倣',
  'ۨ' => '傍',
  '۩' => '坊',
  '۪' => '妨',
  '۫' => '尨',
  '۬' => '幇',
  'ۭ' => '彷',
  'ۮ' => '房',
  'ۯ' => '放',
  '۰' => '方',
  '۱' => '旁',
  '۲' => '昉',
  '۳' => '枋',
  '۴' => '榜',
  '۵' => '滂',
  '۶' => '磅',
  '۷' => '紡',
  '۸' => '肪',
  '۹' => '膀',
  'ۺ' => '舫',
  'ۻ' => '芳',
  'ۼ' => '蒡',
  '۽' => '蚌',
  '۾' => '訪',
  'ۿ' => '謗',
  '�' => '邦',
  '�' => '防',
  '��' => '龐',
  '��' => '倍',
  '��' => '俳',
  '��' => '北',
  '��' => '培',
  '��' => '徘',
  '��' => '拜',
  '��' => '排',
  '��' => '杯',
  '��' => '湃',
  '��' => '焙',
  '��' => '盃',
  '��' => '背',
  '��' => '胚',
  '��' => '裴',
  '��' => '裵',
  '��' => '褙',
  '��' => '賠',
  '��' => '輩',
  '��' => '配',
  '��' => '陪',
  '��' => '伯',
  '��' => '佰',
  '��' => '帛',
  '��' => '柏',
  '��' => '栢',
  '��' => '白',
  '��' => '百',
  '��' => '魄',
  '��' => '幡',
  '��' => '樊',
  '��' => '煩',
  '��' => '燔',
  '��' => '番',
  '��' => '磻',
  '��' => '繁',
  '��' => '蕃',
  '��' => '藩',
  '��' => '飜',
  '��' => '伐',
  '��' => '筏',
  '��' => '罰',
  '��' => '閥',
  '��' => '凡',
  '��' => '帆',
  '��' => '梵',
  '��' => '氾',
  '��' => '汎',
  '��' => '泛',
  '��' => '犯',
  '��' => '範',
  '�' => '范',
  '�' => '法',
  '�' => '琺',
  '�' => '僻',
  '�' => '劈',
  '�' => '壁',
  '�' => '擘',
  '�' => '檗',
  '�' => '璧',
  '�' => '癖',
  'ܡ' => '碧',
  'ܢ' => '蘗',
  'ܣ' => '闢',
  'ܤ' => '霹',
  'ܥ' => '便',
  'ܦ' => '卞',
  'ܧ' => '弁',
  'ܨ' => '變',
  'ܩ' => '辨',
  'ܪ' => '辯',
  'ܫ' => '邊',
  'ܬ' => '別',
  'ܭ' => '瞥',
  'ܮ' => '鱉',
  'ܯ' => '鼈',
  'ܰ' => '丙',
  'ܱ' => '倂',
  'ܲ' => '兵',
  'ܳ' => '屛',
  'ܴ' => '幷',
  'ܵ' => '昞',
  'ܶ' => '昺',
  'ܷ' => '柄',
  'ܸ' => '棅',
  'ܹ' => '炳',
  'ܺ' => '甁',
  'ܻ' => '病',
  'ܼ' => '秉',
  'ܽ' => '竝',
  'ܾ' => '輧',
  'ܿ' => '餠',
  '�' => '騈',
  '�' => '保',
  '��' => '堡',
  '��' => '報',
  '��' => '寶',
  '��' => '普',
  '��' => '步',
  '��' => '洑',
  '��' => '湺',
  '��' => '潽',
  '��' => '珤',
  '��' => '甫',
  '��' => '菩',
  '��' => '補',
  '��' => '褓',
  '��' => '譜',
  '��' => '輔',
  '��' => '伏',
  '��' => '僕',
  '��' => '匐',
  '��' => '卜',
  '��' => '宓',
  '��' => '復',
  '��' => '服',
  '��' => '福',
  '��' => '腹',
  '��' => '茯',
  '��' => '蔔',
  '��' => '複',
  '��' => '覆',
  '��' => '輹',
  '��' => '輻',
  '��' => '馥',
  '��' => '鰒',
  '��' => '本',
  '��' => '乶',
  '��' => '俸',
  '��' => '奉',
  '��' => '封',
  '��' => '峯',
  '��' => '峰',
  '��' => '捧',
  '��' => '棒',
  '��' => '烽',
  '��' => '熢',
  '��' => '琫',
  '��' => '縫',
  '��' => '蓬',
  '��' => '蜂',
  '��' => '逢',
  '��' => '鋒',
  '��' => '鳳',
  '��' => '不',
  '�' => '付',
  '�' => '俯',
  '�' => '傅',
  '�' => '剖',
  '�' => '副',
  '�' => '否',
  '�' => '咐',
  '�' => '埠',
  '�' => '夫',
  '�' => '婦',
  'ݡ' => '孚',
  'ݢ' => '孵',
  'ݣ' => '富',
  'ݤ' => '府',
  'ݥ' => '復',
  'ݦ' => '扶',
  'ݧ' => '敷',
  'ݨ' => '斧',
  'ݩ' => '浮',
  'ݪ' => '溥',
  'ݫ' => '父',
  'ݬ' => '符',
  'ݭ' => '簿',
  'ݮ' => '缶',
  'ݯ' => '腐',
  'ݰ' => '腑',
  'ݱ' => '膚',
  'ݲ' => '艀',
  'ݳ' => '芙',
  'ݴ' => '莩',
  'ݵ' => '訃',
  'ݶ' => '負',
  'ݷ' => '賦',
  'ݸ' => '賻',
  'ݹ' => '赴',
  'ݺ' => '趺',
  'ݻ' => '部',
  'ݼ' => '釜',
  'ݽ' => '阜',
  'ݾ' => '附',
  'ݿ' => '駙',
  '�' => '鳧',
  '�' => '北',
  '��' => '分',
  '��' => '吩',
  '��' => '噴',
  '��' => '墳',
  '��' => '奔',
  '��' => '奮',
  '��' => '忿',
  '��' => '憤',
  '��' => '扮',
  '��' => '昐',
  '��' => '汾',
  '��' => '焚',
  '��' => '盆',
  '��' => '粉',
  '��' => '糞',
  '��' => '紛',
  '��' => '芬',
  '��' => '賁',
  '��' => '雰',
  '��' => '不',
  '��' => '佛',
  '��' => '弗',
  '��' => '彿',
  '��' => '拂',
  '��' => '崩',
  '��' => '朋',
  '��' => '棚',
  '��' => '硼',
  '��' => '繃',
  '��' => '鵬',
  '��' => '丕',
  '��' => '備',
  '��' => '匕',
  '��' => '匪',
  '��' => '卑',
  '��' => '妃',
  '��' => '婢',
  '��' => '庇',
  '��' => '悲',
  '��' => '憊',
  '��' => '扉',
  '��' => '批',
  '��' => '斐',
  '��' => '枇',
  '��' => '榧',
  '��' => '比',
  '��' => '毖',
  '��' => '毗',
  '��' => '毘',
  '��' => '沸',
  '��' => '泌',
  '�' => '琵',
  '�' => '痺',
  '�' => '砒',
  '�' => '碑',
  '�' => '秕',
  '�' => '秘',
  '�' => '粃',
  '�' => '緋',
  '�' => '翡',
  '�' => '肥',
  'ޡ' => '脾',
  'ޢ' => '臂',
  'ޣ' => '菲',
  'ޤ' => '蜚',
  'ޥ' => '裨',
  'ަ' => '誹',
  'ާ' => '譬',
  'ި' => '費',
  'ީ' => '鄙',
  'ު' => '非',
  'ޫ' => '飛',
  'ެ' => '鼻',
  'ޭ' => '嚬',
  'ޮ' => '嬪',
  'ޯ' => '彬',
  'ް' => '斌',
  'ޱ' => '檳',
  '޲' => '殯',
  '޳' => '浜',
  '޴' => '濱',
  '޵' => '瀕',
  '޶' => '牝',
  '޷' => '玭',
  '޸' => '貧',
  '޹' => '賓',
  '޺' => '頻',
  '޻' => '憑',
  '޼' => '氷',
  '޽' => '聘',
  '޾' => '騁',
  '޿' => '乍',
  '�' => '事',
  '�' => '些',
  '��' => '仕',
  '��' => '伺',
  '��' => '似',
  '��' => '使',
  '��' => '俟',
  '��' => '僿',
  '��' => '史',
  '��' => '司',
  '��' => '唆',
  '��' => '嗣',
  '��' => '四',
  '��' => '士',
  '��' => '奢',
  '��' => '娑',
  '��' => '寫',
  '��' => '寺',
  '��' => '射',
  '��' => '巳',
  '��' => '師',
  '��' => '徙',
  '��' => '思',
  '��' => '捨',
  '��' => '斜',
  '��' => '斯',
  '��' => '柶',
  '��' => '査',
  '��' => '梭',
  '��' => '死',
  '��' => '沙',
  '��' => '泗',
  '��' => '渣',
  '��' => '瀉',
  '��' => '獅',
  '��' => '砂',
  '��' => '社',
  '��' => '祀',
  '��' => '祠',
  '��' => '私',
  '��' => '篩',
  '��' => '紗',
  '��' => '絲',
  '��' => '肆',
  '��' => '舍',
  '��' => '莎',
  '��' => '蓑',
  '��' => '蛇',
  '��' => '裟',
  '��' => '詐',
  '��' => '詞',
  '��' => '謝',
  '��' => '賜',
  '�' => '赦',
  '�' => '辭',
  '�' => '邪',
  '�' => '飼',
  '�' => '駟',
  '�' => '麝',
  '�' => '削',
  '�' => '數',
  '�' => '朔',
  '�' => '索',
  'ߡ' => '傘',
  'ߢ' => '刪',
  'ߣ' => '山',
  'ߤ' => '散',
  'ߥ' => '汕',
  'ߦ' => '珊',
  'ߧ' => '産',
  'ߨ' => '疝',
  'ߩ' => '算',
  'ߪ' => '蒜',
  '߫' => '酸',
  '߬' => '霰',
  '߭' => '乷',
  '߮' => '撒',
  '߯' => '殺',
  '߰' => '煞',
  '߱' => '薩',
  '߲' => '三',
  '߳' => '參',
  'ߴ' => '杉',
  'ߵ' => '森',
  '߶' => '渗',
  '߷' => '芟',
  '߸' => '蔘',
  '߹' => '衫',
  'ߺ' => '揷',
  '߻' => '澁',
  '߼' => '鈒',
  '߽' => '颯',
  '߾' => '上',
  '߿' => '傷',
  '�' => '像',
  '�' => '償',
  '��' => '商',
  '��' => '喪',
  '��' => '嘗',
  '��' => '孀',
  '��' => '尙',
  '��' => '峠',
  '��' => '常',
  '��' => '床',
  '��' => '庠',
  '��' => '廂',
  '��' => '想',
  '��' => '桑',
  '��' => '橡',
  '��' => '湘',
  '��' => '爽',
  '��' => '牀',
  '��' => '狀',
  '��' => '相',
  '��' => '祥',
  '��' => '箱',
  '��' => '翔',
  '��' => '裳',
  '��' => '觴',
  '��' => '詳',
  '��' => '象',
  '��' => '賞',
  '��' => '霜',
  '��' => '塞',
  '��' => '璽',
  '��' => '賽',
  '��' => '嗇',
  '��' => '塞',
  '��' => '穡',
  '��' => '索',
  '��' => '色',
  '��' => '牲',
  '��' => '生',
  '��' => '甥',
  '��' => '省',
  '��' => '笙',
  '��' => '墅',
  '��' => '壻',
  '��' => '嶼',
  '��' => '序',
  '��' => '庶',
  '��' => '徐',
  '��' => '恕',
  '��' => '抒',
  '��' => '捿',
  '��' => '敍',
  '��' => '暑',
  '�' => '曙',
  '�' => '書',
  '�' => '栖',
  '�' => '棲',
  '�' => '犀',
  '�' => '瑞',
  '�' => '筮',
  '�' => '絮',
  '�' => '緖',
  '�' => '署',
  '�' => '胥',
  '�' => '舒',
  '�' => '薯',
  '�' => '西',
  '�' => '誓',
  '�' => '逝',
  '�' => '鋤',
  '�' => '黍',
  '�' => '鼠',
  '�' => '夕',
  '�' => '奭',
  '�' => '席',
  '�' => '惜',
  '�' => '昔',
  '�' => '晳',
  '�' => '析',
  '�' => '汐',
  '�' => '淅',
  '�' => '潟',
  '�' => '石',
  '�' => '碩',
  '�' => '蓆',
  '�' => '釋',
  '�' => '錫',
  '�' => '仙',
  '�' => '僊',
  '�' => '先',
  '�' => '善',
  '�' => '嬋',
  '�' => '宣',
  '�' => '扇',
  '�' => '敾',
  '�' => '旋',
  '��' => '渲',
  '��' => '煽',
  '��' => '琁',
  '��' => '瑄',
  '��' => '璇',
  '��' => '璿',
  '��' => '癬',
  '��' => '禪',
  '��' => '線',
  '��' => '繕',
  '��' => '羨',
  '��' => '腺',
  '��' => '膳',
  '��' => '船',
  '��' => '蘚',
  '��' => '蟬',
  '��' => '詵',
  '��' => '跣',
  '��' => '選',
  '��' => '銑',
  '��' => '鐥',
  '��' => '饍',
  '��' => '鮮',
  '��' => '卨',
  '��' => '屑',
  '��' => '楔',
  '��' => '泄',
  '��' => '洩',
  '��' => '渫',
  '��' => '舌',
  '��' => '薛',
  '��' => '褻',
  '��' => '設',
  '��' => '說',
  '��' => '雪',
  '��' => '齧',
  '��' => '剡',
  '��' => '暹',
  '��' => '殲',
  '��' => '纖',
  '��' => '蟾',
  '��' => '贍',
  '��' => '閃',
  '��' => '陝',
  '��' => '攝',
  '��' => '涉',
  '��' => '燮',
  '��' => '葉',
  '��' => '城',
  '��' => '姓',
  '��' => '宬',
  '�' => '性',
  '�' => '惺',
  '�' => '成',
  '�' => '星',
  '�' => '晟',
  '�' => '猩',
  '�' => '珹',
  '�' => '盛',
  '�' => '省',
  '�' => '筬',
  '�' => '聖',
  '�' => '聲',
  '�' => '腥',
  '�' => '誠',
  '�' => '醒',
  '�' => '世',
  '�' => '勢',
  '�' => '歲',
  '�' => '洗',
  '�' => '稅',
  '�' => '笹',
  '�' => '細',
  '�' => '說',
  '�' => '貰',
  '�' => '召',
  '�' => '嘯',
  '�' => '塑',
  '�' => '宵',
  '�' => '小',
  '�' => '少',
  '�' => '巢',
  '�' => '所',
  '�' => '掃',
  '�' => '搔',
  '�' => '昭',
  '�' => '梳',
  '�' => '沼',
  '�' => '消',
  '�' => '溯',
  '�' => '瀟',
  '�' => '炤',
  '�' => '燒',
  '�' => '甦',
  '��' => '疏',
  '��' => '疎',
  '��' => '瘙',
  '��' => '笑',
  '��' => '篠',
  '��' => '簫',
  '��' => '素',
  '��' => '紹',
  '��' => '蔬',
  '��' => '蕭',
  '��' => '蘇',
  '��' => '訴',
  '��' => '逍',
  '��' => '遡',
  '��' => '邵',
  '��' => '銷',
  '��' => '韶',
  '��' => '騷',
  '��' => '俗',
  '��' => '屬',
  '��' => '束',
  '��' => '涑',
  '��' => '粟',
  '��' => '續',
  '��' => '謖',
  '��' => '贖',
  '��' => '速',
  '��' => '孫',
  '��' => '巽',
  '��' => '損',
  '��' => '蓀',
  '��' => '遜',
  '��' => '飡',
  '��' => '率',
  '��' => '宋',
  '��' => '悚',
  '��' => '松',
  '��' => '淞',
  '��' => '訟',
  '��' => '誦',
  '��' => '送',
  '��' => '頌',
  '��' => '刷',
  '��' => '殺',
  '��' => '灑',
  '��' => '碎',
  '��' => '鎖',
  '��' => '衰',
  '��' => '釗',
  '��' => '修',
  '��' => '受',
  '�' => '嗽',
  '�' => '囚',
  '�' => '垂',
  '�' => '壽',
  '�' => '嫂',
  '�' => '守',
  '�' => '岫',
  '�' => '峀',
  '�' => '帥',
  '�' => '愁',
  '�' => '戍',
  '�' => '手',
  '�' => '授',
  '�' => '搜',
  '�' => '收',
  '�' => '數',
  '�' => '樹',
  '�' => '殊',
  '�' => '水',
  '�' => '洙',
  '�' => '漱',
  '�' => '燧',
  '�' => '狩',
  '�' => '獸',
  '�' => '琇',
  '�' => '璲',
  '�' => '瘦',
  '�' => '睡',
  '�' => '秀',
  '�' => '穗',
  '�' => '竪',
  '�' => '粹',
  '�' => '綏',
  '�' => '綬',
  '�' => '繡',
  '�' => '羞',
  '�' => '脩',
  '�' => '茱',
  '�' => '蒐',
  '�' => '蓚',
  '�' => '藪',
  '�' => '袖',
  '�' => '誰',
  '��' => '讐',
  '��' => '輸',
  '��' => '遂',
  '��' => '邃',
  '��' => '酬',
  '��' => '銖',
  '��' => '銹',
  '��' => '隋',
  '��' => '隧',
  '��' => '隨',
  '��' => '雖',
  '��' => '需',
  '��' => '須',
  '��' => '首',
  '��' => '髓',
  '��' => '鬚',
  '��' => '叔',
  '��' => '塾',
  '��' => '夙',
  '��' => '孰',
  '��' => '宿',
  '��' => '淑',
  '��' => '潚',
  '��' => '熟',
  '��' => '琡',
  '��' => '璹',
  '��' => '肅',
  '��' => '菽',
  '��' => '巡',
  '��' => '徇',
  '��' => '循',
  '��' => '恂',
  '��' => '旬',
  '��' => '栒',
  '��' => '楯',
  '��' => '橓',
  '��' => '殉',
  '��' => '洵',
  '��' => '淳',
  '��' => '珣',
  '��' => '盾',
  '��' => '瞬',
  '��' => '筍',
  '��' => '純',
  '��' => '脣',
  '��' => '舜',
  '��' => '荀',
  '��' => '蓴',
  '��' => '蕣',
  '��' => '詢',
  '��' => '諄',
  '�' => '醇',
  '�' => '錞',
  '�' => '順',
  '�' => '馴',
  '�' => '戌',
  '�' => '術',
  '�' => '述',
  '�' => '鉥',
  '�' => '崇',
  '�' => '崧',
  '�' => '嵩',
  '�' => '瑟',
  '�' => '膝',
  '�' => '蝨',
  '�' => '濕',
  '�' => '拾',
  '�' => '習',
  '�' => '褶',
  '�' => '襲',
  '�' => '丞',
  '�' => '乘',
  '�' => '僧',
  '�' => '勝',
  '�' => '升',
  '�' => '承',
  '�' => '昇',
  '�' => '繩',
  '�' => '蠅',
  '�' => '陞',
  '�' => '侍',
  '�' => '匙',
  '�' => '嘶',
  '�' => '始',
  '�' => '媤',
  '�' => '尸',
  '�' => '屎',
  '�' => '屍',
  '�' => '市',
  '�' => '弑',
  '�' => '恃',
  '�' => '施',
  '�' => '是',
  '�' => '時',
  '��' => '枾',
  '��' => '柴',
  '��' => '猜',
  '��' => '矢',
  '��' => '示',
  '��' => '翅',
  '��' => '蒔',
  '��' => '蓍',
  '��' => '視',
  '��' => '試',
  '��' => '詩',
  '��' => '諡',
  '��' => '豕',
  '��' => '豺',
  '��' => '埴',
  '��' => '寔',
  '��' => '式',
  '��' => '息',
  '��' => '拭',
  '��' => '植',
  '��' => '殖',
  '��' => '湜',
  '��' => '熄',
  '��' => '篒',
  '��' => '蝕',
  '��' => '識',
  '��' => '軾',
  '��' => '食',
  '��' => '飾',
  '��' => '伸',
  '��' => '侁',
  '��' => '信',
  '��' => '呻',
  '��' => '娠',
  '��' => '宸',
  '��' => '愼',
  '��' => '新',
  '��' => '晨',
  '��' => '燼',
  '��' => '申',
  '��' => '神',
  '��' => '紳',
  '��' => '腎',
  '��' => '臣',
  '��' => '莘',
  '��' => '薪',
  '��' => '藎',
  '��' => '蜃',
  '��' => '訊',
  '��' => '身',
  '��' => '辛',
  '�' => '辰',
  '�' => '迅',
  '�' => '失',
  '�' => '室',
  '�' => '實',
  '�' => '悉',
  '�' => '審',
  '�' => '尋',
  '�' => '心',
  '�' => '沁',
  '�' => '沈',
  '�' => '深',
  '�' => '瀋',
  '�' => '甚',
  '�' => '芯',
  '�' => '諶',
  '�' => '什',
  '�' => '十',
  '�' => '拾',
  '�' => '雙',
  '�' => '氏',
  '�' => '亞',
  '�' => '俄',
  '�' => '兒',
  '�' => '啞',
  '�' => '娥',
  '�' => '峨',
  '�' => '我',
  '�' => '牙',
  '�' => '芽',
  '�' => '莪',
  '�' => '蛾',
  '�' => '衙',
  '�' => '訝',
  '�' => '阿',
  '�' => '雅',
  '�' => '餓',
  '�' => '鴉',
  '�' => '鵝',
  '�' => '堊',
  '�' => '岳',
  '�' => '嶽',
  '�' => '幄',
  '��' => '惡',
  '��' => '愕',
  '��' => '握',
  '��' => '樂',
  '��' => '渥',
  '��' => '鄂',
  '��' => '鍔',
  '��' => '顎',
  '��' => '鰐',
  '��' => '齷',
  '��' => '安',
  '��' => '岸',
  '��' => '按',
  '��' => '晏',
  '��' => '案',
  '��' => '眼',
  '��' => '雁',
  '��' => '鞍',
  '��' => '顔',
  '��' => '鮟',
  '��' => '斡',
  '��' => '謁',
  '��' => '軋',
  '��' => '閼',
  '��' => '唵',
  '��' => '岩',
  '��' => '巖',
  '��' => '庵',
  '��' => '暗',
  '��' => '癌',
  '��' => '菴',
  '��' => '闇',
  '��' => '壓',
  '��' => '押',
  '��' => '狎',
  '��' => '鴨',
  '��' => '仰',
  '��' => '央',
  '��' => '怏',
  '��' => '昻',
  '��' => '殃',
  '��' => '秧',
  '��' => '鴦',
  '��' => '厓',
  '��' => '哀',
  '��' => '埃',
  '��' => '崖',
  '��' => '愛',
  '��' => '曖',
  '��' => '涯',
  '��' => '碍',
  '�' => '艾',
  '�' => '隘',
  '�' => '靄',
  '�' => '厄',
  '�' => '扼',
  '�' => '掖',
  '�' => '液',
  '�' => '縊',
  '�' => '腋',
  '�' => '額',
  '�' => '櫻',
  '�' => '罌',
  '�' => '鶯',
  '�' => '鸚',
  '�' => '也',
  '�' => '倻',
  '�' => '冶',
  '�' => '夜',
  '�' => '惹',
  '�' => '揶',
  '�' => '椰',
  '�' => '爺',
  '�' => '耶',
  '�' => '若',
  '�' => '野',
  '�' => '弱',
  '�' => '掠',
  '�' => '略',
  '�' => '約',
  '�' => '若',
  '�' => '葯',
  '�' => '蒻',
  '�' => '藥',
  '�' => '躍',
  '�' => '亮',
  '�' => '佯',
  '�' => '兩',
  '�' => '凉',
  '�' => '壤',
  '�' => '孃',
  '�' => '恙',
  '�' => '揚',
  '�' => '攘',
  '��' => '敭',
  '��' => '暘',
  '��' => '梁',
  '��' => '楊',
  '��' => '樣',
  '��' => '洋',
  '��' => '瀁',
  '��' => '煬',
  '��' => '痒',
  '��' => '瘍',
  '��' => '禳',
  '��' => '穰',
  '��' => '糧',
  '��' => '羊',
  '��' => '良',
  '��' => '襄',
  '��' => '諒',
  '��' => '讓',
  '��' => '釀',
  '��' => '陽',
  '��' => '量',
  '��' => '養',
  '��' => '圄',
  '��' => '御',
  '��' => '於',
  '��' => '漁',
  '��' => '瘀',
  '��' => '禦',
  '��' => '語',
  '��' => '馭',
  '��' => '魚',
  '��' => '齬',
  '��' => '億',
  '��' => '憶',
  '��' => '抑',
  '��' => '檍',
  '��' => '臆',
  '��' => '偃',
  '��' => '堰',
  '��' => '彦',
  '��' => '焉',
  '��' => '言',
  '��' => '諺',
  '��' => '孼',
  '��' => '蘖',
  '��' => '俺',
  '��' => '儼',
  '��' => '嚴',
  '��' => '奄',
  '��' => '掩',
  '��' => '淹',
  '�' => '嶪',
  '�' => '業',
  '�' => '円',
  '�' => '予',
  '�' => '余',
  '�' => '勵',
  '�' => '呂',
  '�' => '女',
  '�' => '如',
  '�' => '廬',
  '�' => '旅',
  '�' => '歟',
  '�' => '汝',
  '�' => '濾',
  '�' => '璵',
  '�' => '礖',
  '�' => '礪',
  '�' => '與',
  '�' => '艅',
  '�' => '茹',
  '�' => '輿',
  '�' => '轝',
  '�' => '閭',
  '�' => '餘',
  '�' => '驪',
  '�' => '麗',
  '�' => '黎',
  '�' => '亦',
  '�' => '力',
  '�' => '域',
  '�' => '役',
  '�' => '易',
  '�' => '曆',
  '�' => '歷',
  '�' => '疫',
  '�' => '繹',
  '�' => '譯',
  '�' => '轢',
  '�' => '逆',
  '�' => '驛',
  '�' => '嚥',
  '�' => '堧',
  '�' => '姸',
  '��' => '娟',
  '��' => '宴',
  '��' => '年',
  '��' => '延',
  '��' => '憐',
  '��' => '戀',
  '��' => '捐',
  '��' => '挻',
  '��' => '撚',
  '��' => '椽',
  '��' => '沇',
  '��' => '沿',
  '��' => '涎',
  '��' => '涓',
  '��' => '淵',
  '��' => '演',
  '��' => '漣',
  '��' => '烟',
  '��' => '然',
  '��' => '煙',
  '��' => '煉',
  '��' => '燃',
  '��' => '燕',
  '��' => '璉',
  '��' => '硏',
  '��' => '硯',
  '��' => '秊',
  '��' => '筵',
  '��' => '緣',
  '��' => '練',
  '��' => '縯',
  '��' => '聯',
  '��' => '衍',
  '��' => '軟',
  '��' => '輦',
  '��' => '蓮',
  '��' => '連',
  '��' => '鉛',
  '��' => '鍊',
  '��' => '鳶',
  '��' => '列',
  '��' => '劣',
  '��' => '咽',
  '��' => '悅',
  '��' => '涅',
  '��' => '烈',
  '��' => '熱',
  '��' => '裂',
  '��' => '說',
  '��' => '閱',
  '��' => '厭',
  '�' => '廉',
  '�' => '念',
  '�' => '捻',
  '�' => '染',
  '�' => '殮',
  '�' => '炎',
  '�' => '焰',
  '�' => '琰',
  '�' => '艶',
  '�' => '苒',
  '�' => '簾',
  '�' => '閻',
  '�' => '髥',
  '�' => '鹽',
  '�' => '曄',
  '�' => '獵',
  '�' => '燁',
  '�' => '葉',
  '�' => '令',
  '�' => '囹',
  '�' => '塋',
  '�' => '寧',
  '�' => '嶺',
  '�' => '嶸',
  '�' => '影',
  '�' => '怜',
  '�' => '映',
  '�' => '暎',
  '�' => '楹',
  '�' => '榮',
  '�' => '永',
  '�' => '泳',
  '�' => '渶',
  '�' => '潁',
  '�' => '濚',
  '�' => '瀛',
  '�' => '瀯',
  '�' => '煐',
  '�' => '營',
  '�' => '獰',
  '�' => '玲',
  '�' => '瑛',
  '�' => '瑩',
  '��' => '瓔',
  '��' => '盈',
  '��' => '穎',
  '��' => '纓',
  '��' => '羚',
  '��' => '聆',
  '��' => '英',
  '��' => '詠',
  '��' => '迎',
  '��' => '鈴',
  '��' => '鍈',
  '��' => '零',
  '��' => '霙',
  '��' => '靈',
  '��' => '領',
  '��' => '乂',
  '��' => '倪',
  '��' => '例',
  '��' => '刈',
  '��' => '叡',
  '��' => '曳',
  '��' => '汭',
  '��' => '濊',
  '��' => '猊',
  '��' => '睿',
  '��' => '穢',
  '��' => '芮',
  '��' => '藝',
  '��' => '蘂',
  '��' => '禮',
  '��' => '裔',
  '��' => '詣',
  '��' => '譽',
  '��' => '豫',
  '��' => '醴',
  '��' => '銳',
  '��' => '隸',
  '��' => '霓',
  '��' => '預',
  '��' => '五',
  '��' => '伍',
  '��' => '俉',
  '��' => '傲',
  '��' => '午',
  '��' => '吾',
  '��' => '吳',
  '��' => '嗚',
  '��' => '塢',
  '��' => '墺',
  '��' => '奧',
  '��' => '娛',
  '�' => '寤',
  '�' => '悟',
  '�' => '惡',
  '�' => '懊',
  '�' => '敖',
  '�' => '旿',
  '�' => '晤',
  '�' => '梧',
  '�' => '汚',
  '�' => '澳',
  '�' => '烏',
  '�' => '熬',
  '�' => '獒',
  '�' => '筽',
  '�' => '蜈',
  '�' => '誤',
  '�' => '鰲',
  '�' => '鼇',
  '�' => '屋',
  '�' => '沃',
  '�' => '獄',
  '�' => '玉',
  '�' => '鈺',
  '�' => '溫',
  '�' => '瑥',
  '�' => '瘟',
  '�' => '穩',
  '�' => '縕',
  '�' => '蘊',
  '�' => '兀',
  '�' => '壅',
  '�' => '擁',
  '�' => '瓮',
  '�' => '甕',
  '�' => '癰',
  '�' => '翁',
  '�' => '邕',
  '�' => '雍',
  '�' => '饔',
  '�' => '渦',
  '�' => '瓦',
  '�' => '窩',
  '�' => '窪',
  '��' => '臥',
  '��' => '蛙',
  '��' => '蝸',
  '��' => '訛',
  '��' => '婉',
  '��' => '完',
  '��' => '宛',
  '��' => '梡',
  '��' => '椀',
  '��' => '浣',
  '��' => '玩',
  '��' => '琓',
  '��' => '琬',
  '��' => '碗',
  '��' => '緩',
  '��' => '翫',
  '��' => '脘',
  '��' => '腕',
  '��' => '莞',
  '��' => '豌',
  '��' => '阮',
  '��' => '頑',
  '��' => '曰',
  '��' => '往',
  '��' => '旺',
  '��' => '枉',
  '��' => '汪',
  '��' => '王',
  '��' => '倭',
  '��' => '娃',
  '��' => '歪',
  '��' => '矮',
  '��' => '外',
  '��' => '嵬',
  '��' => '巍',
  '��' => '猥',
  '��' => '畏',
  '��' => '了',
  '��' => '僚',
  '��' => '僥',
  '��' => '凹',
  '��' => '堯',
  '��' => '夭',
  '��' => '妖',
  '��' => '姚',
  '��' => '寥',
  '��' => '寮',
  '��' => '尿',
  '��' => '嶢',
  '��' => '拗',
  '��' => '搖',
  '�' => '撓',
  '�' => '擾',
  '�' => '料',
  '�' => '曜',
  '�' => '樂',
  '�' => '橈',
  '�' => '燎',
  '�' => '燿',
  '�' => '瑤',
  '�' => '療',
  '�' => '窈',
  '�' => '窯',
  '�' => '繇',
  '�' => '繞',
  '�' => '耀',
  '�' => '腰',
  '�' => '蓼',
  '�' => '蟯',
  '�' => '要',
  '�' => '謠',
  '�' => '遙',
  '�' => '遼',
  '�' => '邀',
  '�' => '饒',
  '�' => '慾',
  '�' => '欲',
  '�' => '浴',
  '�' => '縟',
  '�' => '褥',
  '�' => '辱',
  '�' => '俑',
  '�' => '傭',
  '�' => '冗',
  '�' => '勇',
  '�' => '埇',
  '�' => '墉',
  '�' => '容',
  '�' => '庸',
  '�' => '慂',
  '�' => '榕',
  '�' => '涌',
  '�' => '湧',
  '�' => '溶',
  '��' => '熔',
  '��' => '瑢',
  '��' => '用',
  '��' => '甬',
  '��' => '聳',
  '��' => '茸',
  '��' => '蓉',
  '��' => '踊',
  '��' => '鎔',
  '��' => '鏞',
  '��' => '龍',
  '��' => '于',
  '��' => '佑',
  '��' => '偶',
  '��' => '優',
  '��' => '又',
  '��' => '友',
  '��' => '右',
  '��' => '宇',
  '��' => '寓',
  '��' => '尤',
  '��' => '愚',
  '��' => '憂',
  '��' => '旴',
  '��' => '牛',
  '��' => '玗',
  '��' => '瑀',
  '��' => '盂',
  '��' => '祐',
  '��' => '禑',
  '��' => '禹',
  '��' => '紆',
  '��' => '羽',
  '��' => '芋',
  '��' => '藕',
  '��' => '虞',
  '��' => '迂',
  '��' => '遇',
  '��' => '郵',
  '��' => '釪',
  '��' => '隅',
  '��' => '雨',
  '��' => '雩',
  '��' => '勖',
  '��' => '彧',
  '��' => '旭',
  '��' => '昱',
  '��' => '栯',
  '��' => '煜',
  '��' => '稶',
  '��' => '郁',
  '�' => '頊',
  '�' => '云',
  '�' => '暈',
  '�' => '橒',
  '�' => '殞',
  '�' => '澐',
  '�' => '熉',
  '�' => '耘',
  '�' => '芸',
  '�' => '蕓',
  '�' => '運',
  '�' => '隕',
  '�' => '雲',
  '�' => '韻',
  '�' => '蔚',
  '�' => '鬱',
  '�' => '亐',
  '�' => '熊',
  '�' => '雄',
  '�' => '元',
  '�' => '原',
  '�' => '員',
  '�' => '圓',
  '�' => '園',
  '�' => '垣',
  '�' => '媛',
  '�' => '嫄',
  '�' => '寃',
  '�' => '怨',
  '�' => '愿',
  '�' => '援',
  '�' => '沅',
  '�' => '洹',
  '�' => '湲',
  '�' => '源',
  '�' => '爰',
  '�' => '猿',
  '�' => '瑗',
  '�' => '苑',
  '�' => '袁',
  '�' => '轅',
  '�' => '遠',
  '�' => '阮',
  '��' => '院',
  '��' => '願',
  '��' => '鴛',
  '��' => '月',
  '��' => '越',
  '��' => '鉞',
  '��' => '位',
  '��' => '偉',
  '��' => '僞',
  '��' => '危',
  '��' => '圍',
  '��' => '委',
  '��' => '威',
  '��' => '尉',
  '��' => '慰',
  '��' => '暐',
  '��' => '渭',
  '��' => '爲',
  '��' => '瑋',
  '��' => '緯',
  '��' => '胃',
  '��' => '萎',
  '��' => '葦',
  '��' => '蔿',
  '��' => '蝟',
  '��' => '衛',
  '��' => '褘',
  '��' => '謂',
  '��' => '違',
  '��' => '韋',
  '��' => '魏',
  '��' => '乳',
  '��' => '侑',
  '��' => '儒',
  '��' => '兪',
  '��' => '劉',
  '��' => '唯',
  '��' => '喩',
  '��' => '孺',
  '��' => '宥',
  '��' => '幼',
  '��' => '幽',
  '��' => '庾',
  '��' => '悠',
  '��' => '惟',
  '��' => '愈',
  '��' => '愉',
  '��' => '揄',
  '��' => '攸',
  '��' => '有',
  '��' => '杻',
  '�' => '柔',
  '�' => '柚',
  '�' => '柳',
  '�' => '楡',
  '�' => '楢',
  '�' => '油',
  '�' => '洧',
  '�' => '流',
  '�' => '游',
  '�' => '溜',
  '�' => '濡',
  '�' => '猶',
  '�' => '猷',
  '�' => '琉',
  '�' => '瑜',
  '�' => '由',
  '�' => '留',
  '�' => '癒',
  '�' => '硫',
  '�' => '紐',
  '�' => '維',
  '�' => '臾',
  '�' => '萸',
  '�' => '裕',
  '�' => '誘',
  '�' => '諛',
  '�' => '諭',
  '�' => '踰',
  '�' => '蹂',
  '�' => '遊',
  '�' => '逾',
  '�' => '遺',
  '�' => '酉',
  '�' => '釉',
  '�' => '鍮',
  '�' => '類',
  '�' => '六',
  '�' => '堉',
  '�' => '戮',
  '�' => '毓',
  '�' => '肉',
  '�' => '育',
  '�' => '陸',
  '��' => '倫',
  '��' => '允',
  '��' => '奫',
  '��' => '尹',
  '��' => '崙',
  '��' => '淪',
  '��' => '潤',
  '��' => '玧',
  '��' => '胤',
  '��' => '贇',
  '��' => '輪',
  '��' => '鈗',
  '��' => '閏',
  '��' => '律',
  '��' => '慄',
  '��' => '栗',
  '��' => '率',
  '��' => '聿',
  '��' => '戎',
  '��' => '瀜',
  '��' => '絨',
  '��' => '融',
  '��' => '隆',
  '��' => '垠',
  '��' => '恩',
  '��' => '慇',
  '��' => '殷',
  '��' => '誾',
  '��' => '銀',
  '��' => '隱',
  '��' => '乙',
  '��' => '吟',
  '��' => '淫',
  '��' => '蔭',
  '��' => '陰',
  '��' => '音',
  '��' => '飮',
  '��' => '揖',
  '��' => '泣',
  '��' => '邑',
  '��' => '凝',
  '��' => '應',
  '��' => '膺',
  '��' => '鷹',
  '��' => '依',
  '��' => '倚',
  '��' => '儀',
  '��' => '宜',
  '��' => '意',
  '��' => '懿',
  '��' => '擬',
  '�' => '椅',
  '�' => '毅',
  '�' => '疑',
  '�' => '矣',
  '�' => '義',
  '�' => '艤',
  '�' => '薏',
  '�' => '蟻',
  '�' => '衣',
  '�' => '誼',
  '�' => '議',
  '�' => '醫',
  '�' => '二',
  '�' => '以',
  '�' => '伊',
  '�' => '利',
  '�' => '吏',
  '�' => '夷',
  '�' => '姨',
  '�' => '履',
  '�' => '已',
  '�' => '弛',
  '�' => '彛',
  '�' => '怡',
  '�' => '易',
  '�' => '李',
  '�' => '梨',
  '�' => '泥',
  '�' => '爾',
  '�' => '珥',
  '�' => '理',
  '�' => '異',
  '�' => '痍',
  '�' => '痢',
  '�' => '移',
  '�' => '罹',
  '�' => '而',
  '�' => '耳',
  '�' => '肄',
  '�' => '苡',
  '�' => '荑',
  '�' => '裏',
  '�' => '裡',
  '��' => '貽',
  '��' => '貳',
  '��' => '邇',
  '��' => '里',
  '��' => '離',
  '��' => '飴',
  '��' => '餌',
  '��' => '匿',
  '��' => '溺',
  '��' => '瀷',
  '��' => '益',
  '��' => '翊',
  '��' => '翌',
  '��' => '翼',
  '��' => '謚',
  '��' => '人',
  '��' => '仁',
  '��' => '刃',
  '��' => '印',
  '��' => '吝',
  '��' => '咽',
  '��' => '因',
  '��' => '姻',
  '��' => '寅',
  '��' => '引',
  '��' => '忍',
  '��' => '湮',
  '��' => '燐',
  '��' => '璘',
  '��' => '絪',
  '��' => '茵',
  '��' => '藺',
  '��' => '蚓',
  '��' => '認',
  '��' => '隣',
  '��' => '靭',
  '��' => '靷',
  '��' => '鱗',
  '��' => '麟',
  '��' => '一',
  '��' => '佚',
  '��' => '佾',
  '��' => '壹',
  '��' => '日',
  '��' => '溢',
  '��' => '逸',
  '��' => '鎰',
  '��' => '馹',
  '��' => '任',
  '��' => '壬',
  '��' => '妊',
  '�' => '姙',
  '�' => '恁',
  '�' => '林',
  '�' => '淋',
  '�' => '稔',
  '�' => '臨',
  '�' => '荏',
  '�' => '賃',
  '�' => '入',
  '�' => '卄',
  '�' => '立',
  '�' => '笠',
  '�' => '粒',
  '�' => '仍',
  '�' => '剩',
  '�' => '孕',
  '�' => '芿',
  '�' => '仔',
  '�' => '刺',
  '�' => '咨',
  '�' => '姉',
  '�' => '姿',
  '�' => '子',
  '�' => '字',
  '�' => '孜',
  '�' => '恣',
  '�' => '慈',
  '�' => '滋',
  '�' => '炙',
  '�' => '煮',
  '�' => '玆',
  '�' => '瓷',
  '�' => '疵',
  '�' => '磁',
  '�' => '紫',
  '�' => '者',
  '�' => '自',
  '�' => '茨',
  '�' => '蔗',
  '�' => '藉',
  '�' => '諮',
  '�' => '資',
  '�' => '雌',
  '��' => '作',
  '��' => '勺',
  '��' => '嚼',
  '��' => '斫',
  '��' => '昨',
  '��' => '灼',
  '��' => '炸',
  '��' => '爵',
  '��' => '綽',
  '��' => '芍',
  '��' => '酌',
  '��' => '雀',
  '��' => '鵲',
  '��' => '孱',
  '��' => '棧',
  '��' => '殘',
  '��' => '潺',
  '��' => '盞',
  '��' => '岑',
  '��' => '暫',
  '��' => '潛',
  '��' => '箴',
  '��' => '簪',
  '��' => '蠶',
  '��' => '雜',
  '��' => '丈',
  '��' => '仗',
  '��' => '匠',
  '��' => '場',
  '��' => '墻',
  '��' => '壯',
  '��' => '奬',
  '��' => '將',
  '��' => '帳',
  '��' => '庄',
  '��' => '張',
  '��' => '掌',
  '��' => '暲',
  '��' => '杖',
  '��' => '樟',
  '��' => '檣',
  '��' => '欌',
  '��' => '漿',
  '��' => '牆',
  '��' => '狀',
  '��' => '獐',
  '��' => '璋',
  '��' => '章',
  '��' => '粧',
  '��' => '腸',
  '��' => '臟',
  '�' => '臧',
  '�' => '莊',
  '�' => '葬',
  '�' => '蔣',
  '�' => '薔',
  '�' => '藏',
  '�' => '裝',
  '�' => '贓',
  '�' => '醬',
  '�' => '長',
  '�' => '障',
  '�' => '再',
  '�' => '哉',
  '�' => '在',
  '�' => '宰',
  '�' => '才',
  '�' => '材',
  '�' => '栽',
  '�' => '梓',
  '�' => '渽',
  '�' => '滓',
  '�' => '災',
  '�' => '縡',
  '�' => '裁',
  '�' => '財',
  '�' => '載',
  '�' => '齋',
  '�' => '齎',
  '�' => '爭',
  '�' => '箏',
  '�' => '諍',
  '�' => '錚',
  '�' => '佇',
  '�' => '低',
  '�' => '儲',
  '�' => '咀',
  '�' => '姐',
  '�' => '底',
  '�' => '抵',
  '�' => '杵',
  '�' => '楮',
  '�' => '樗',
  '�' => '沮',
  '��' => '渚',
  '��' => '狙',
  '��' => '猪',
  '��' => '疽',
  '��' => '箸',
  '��' => '紵',
  '��' => '苧',
  '��' => '菹',
  '��' => '著',
  '��' => '藷',
  '��' => '詛',
  '��' => '貯',
  '��' => '躇',
  '��' => '這',
  '��' => '邸',
  '��' => '雎',
  '��' => '齟',
  '��' => '勣',
  '��' => '吊',
  '��' => '嫡',
  '��' => '寂',
  '��' => '摘',
  '��' => '敵',
  '��' => '滴',
  '��' => '狄',
  '��' => '炙',
  '��' => '的',
  '��' => '積',
  '��' => '笛',
  '��' => '籍',
  '��' => '績',
  '��' => '翟',
  '��' => '荻',
  '��' => '謫',
  '��' => '賊',
  '��' => '赤',
  '��' => '跡',
  '��' => '蹟',
  '��' => '迪',
  '��' => '迹',
  '��' => '適',
  '��' => '鏑',
  '��' => '佃',
  '��' => '佺',
  '��' => '傳',
  '��' => '全',
  '��' => '典',
  '��' => '前',
  '��' => '剪',
  '��' => '塡',
  '��' => '塼',
  '�' => '奠',
  '�' => '專',
  '�' => '展',
  '�' => '廛',
  '�' => '悛',
  '�' => '戰',
  '�' => '栓',
  '�' => '殿',
  '�' => '氈',
  '�' => '澱',
  '�' => '煎',
  '�' => '琠',
  '�' => '田',
  '�' => '甸',
  '�' => '畑',
  '�' => '癲',
  '�' => '筌',
  '�' => '箋',
  '�' => '箭',
  '�' => '篆',
  '�' => '纏',
  '�' => '詮',
  '�' => '輾',
  '�' => '轉',
  '�' => '鈿',
  '�' => '銓',
  '�' => '錢',
  '�' => '鐫',
  '�' => '電',
  '�' => '顚',
  '�' => '顫',
  '�' => '餞',
  '�' => '切',
  '�' => '截',
  '�' => '折',
  '�' => '浙',
  '�' => '癤',
  '�' => '竊',
  '�' => '節',
  '�' => '絶',
  '�' => '占',
  '�' => '岾',
  '�' => '店',
  '��' => '漸',
  '��' => '点',
  '��' => '粘',
  '��' => '霑',
  '��' => '鮎',
  '��' => '點',
  '��' => '接',
  '��' => '摺',
  '��' => '蝶',
  '��' => '丁',
  '��' => '井',
  '��' => '亭',
  '��' => '停',
  '��' => '偵',
  '��' => '呈',
  '��' => '姃',
  '��' => '定',
  '��' => '幀',
  '��' => '庭',
  '��' => '廷',
  '��' => '征',
  '��' => '情',
  '��' => '挺',
  '��' => '政',
  '��' => '整',
  '��' => '旌',
  '��' => '晶',
  '��' => '晸',
  '��' => '柾',
  '��' => '楨',
  '��' => '檉',
  '��' => '正',
  '��' => '汀',
  '��' => '淀',
  '��' => '淨',
  '��' => '渟',
  '��' => '湞',
  '��' => '瀞',
  '��' => '炡',
  '��' => '玎',
  '��' => '珽',
  '��' => '町',
  '��' => '睛',
  '��' => '碇',
  '��' => '禎',
  '��' => '程',
  '��' => '穽',
  '��' => '精',
  '��' => '綎',
  '��' => '艇',
  '��' => '訂',
  '�' => '諪',
  '�' => '貞',
  '�' => '鄭',
  '�' => '酊',
  '�' => '釘',
  '�' => '鉦',
  '�' => '鋌',
  '�' => '錠',
  '�' => '霆',
  '�' => '靖',
  '�' => '靜',
  '�' => '頂',
  '�' => '鼎',
  '�' => '制',
  '�' => '劑',
  '�' => '啼',
  '�' => '堤',
  '�' => '帝',
  '�' => '弟',
  '�' => '悌',
  '�' => '提',
  '�' => '梯',
  '�' => '濟',
  '�' => '祭',
  '�' => '第',
  '�' => '臍',
  '�' => '薺',
  '�' => '製',
  '�' => '諸',
  '�' => '蹄',
  '�' => '醍',
  '�' => '除',
  '�' => '際',
  '�' => '霽',
  '�' => '題',
  '�' => '齊',
  '�' => '俎',
  '�' => '兆',
  '�' => '凋',
  '�' => '助',
  '�' => '嘲',
  '�' => '弔',
  '�' => '彫',
  '��' => '措',
  '��' => '操',
  '��' => '早',
  '��' => '晁',
  '��' => '曺',
  '��' => '曹',
  '��' => '朝',
  '��' => '條',
  '��' => '棗',
  '��' => '槽',
  '��' => '漕',
  '��' => '潮',
  '��' => '照',
  '��' => '燥',
  '��' => '爪',
  '��' => '璪',
  '��' => '眺',
  '��' => '祖',
  '��' => '祚',
  '��' => '租',
  '��' => '稠',
  '��' => '窕',
  '��' => '粗',
  '��' => '糟',
  '��' => '組',
  '��' => '繰',
  '��' => '肇',
  '��' => '藻',
  '��' => '蚤',
  '��' => '詔',
  '��' => '調',
  '��' => '趙',
  '��' => '躁',
  '��' => '造',
  '��' => '遭',
  '��' => '釣',
  '��' => '阻',
  '��' => '雕',
  '��' => '鳥',
  '��' => '族',
  '��' => '簇',
  '��' => '足',
  '��' => '鏃',
  '��' => '存',
  '��' => '尊',
  '��' => '卒',
  '��' => '拙',
  '��' => '猝',
  '��' => '倧',
  '��' => '宗',
  '��' => '從',
  '�' => '悰',
  '�' => '慫',
  '�' => '棕',
  '�' => '淙',
  '�' => '琮',
  '�' => '種',
  '�' => '終',
  '�' => '綜',
  '�' => '縱',
  '�' => '腫',
  '�' => '踪',
  '�' => '踵',
  '�' => '鍾',
  '�' => '鐘',
  '�' => '佐',
  '�' => '坐',
  '�' => '左',
  '�' => '座',
  '�' => '挫',
  '�' => '罪',
  '�' => '主',
  '�' => '住',
  '�' => '侏',
  '�' => '做',
  '�' => '姝',
  '�' => '胄',
  '�' => '呪',
  '�' => '周',
  '�' => '嗾',
  '�' => '奏',
  '�' => '宙',
  '�' => '州',
  '�' => '廚',
  '�' => '晝',
  '�' => '朱',
  '�' => '柱',
  '�' => '株',
  '�' => '注',
  '�' => '洲',
  '�' => '湊',
  '�' => '澍',
  '�' => '炷',
  '�' => '珠',
  '��' => '疇',
  '��' => '籌',
  '��' => '紂',
  '��' => '紬',
  '��' => '綢',
  '��' => '舟',
  '��' => '蛛',
  '��' => '註',
  '��' => '誅',
  '��' => '走',
  '��' => '躊',
  '��' => '輳',
  '��' => '週',
  '��' => '酎',
  '��' => '酒',
  '��' => '鑄',
  '��' => '駐',
  '��' => '竹',
  '��' => '粥',
  '��' => '俊',
  '��' => '儁',
  '��' => '准',
  '��' => '埈',
  '��' => '寯',
  '��' => '峻',
  '��' => '晙',
  '��' => '樽',
  '��' => '浚',
  '��' => '準',
  '��' => '濬',
  '��' => '焌',
  '��' => '畯',
  '��' => '竣',
  '��' => '蠢',
  '��' => '逡',
  '��' => '遵',
  '��' => '雋',
  '��' => '駿',
  '��' => '茁',
  '��' => '中',
  '��' => '仲',
  '��' => '衆',
  '��' => '重',
  '��' => '卽',
  '��' => '櫛',
  '��' => '楫',
  '��' => '汁',
  '��' => '葺',
  '��' => '增',
  '��' => '憎',
  '��' => '曾',
  '�' => '拯',
  '�' => '烝',
  '�' => '甑',
  '�' => '症',
  '�' => '繒',
  '�' => '蒸',
  '�' => '證',
  '�' => '贈',
  '�' => '之',
  '�' => '只',
  '�' => '咫',
  '�' => '地',
  '�' => '址',
  '�' => '志',
  '�' => '持',
  '�' => '指',
  '�' => '摯',
  '�' => '支',
  '�' => '旨',
  '�' => '智',
  '�' => '枝',
  '�' => '枳',
  '�' => '止',
  '�' => '池',
  '�' => '沚',
  '�' => '漬',
  '�' => '知',
  '�' => '砥',
  '�' => '祉',
  '�' => '祗',
  '�' => '紙',
  '�' => '肢',
  '�' => '脂',
  '�' => '至',
  '�' => '芝',
  '�' => '芷',
  '�' => '蜘',
  '�' => '誌',
  '�' => '識',
  '�' => '贄',
  '�' => '趾',
  '�' => '遲',
  '�' => '直',
  '��' => '稙',
  '��' => '稷',
  '��' => '織',
  '��' => '職',
  '��' => '唇',
  '��' => '嗔',
  '��' => '塵',
  '��' => '振',
  '��' => '搢',
  '��' => '晉',
  '��' => '晋',
  '��' => '桭',
  '��' => '榛',
  '��' => '殄',
  '��' => '津',
  '��' => '溱',
  '��' => '珍',
  '��' => '瑨',
  '��' => '璡',
  '��' => '畛',
  '��' => '疹',
  '��' => '盡',
  '��' => '眞',
  '��' => '瞋',
  '��' => '秦',
  '��' => '縉',
  '��' => '縝',
  '��' => '臻',
  '��' => '蔯',
  '��' => '袗',
  '��' => '診',
  '��' => '賑',
  '��' => '軫',
  '��' => '辰',
  '��' => '進',
  '��' => '鎭',
  '��' => '陣',
  '��' => '陳',
  '��' => '震',
  '��' => '侄',
  '��' => '叱',
  '��' => '姪',
  '��' => '嫉',
  '��' => '帙',
  '��' => '桎',
  '��' => '瓆',
  '��' => '疾',
  '��' => '秩',
  '��' => '窒',
  '��' => '膣',
  '��' => '蛭',
  '�' => '質',
  '�' => '跌',
  '�' => '迭',
  '�' => '斟',
  '�' => '朕',
  '�' => '什',
  '�' => '執',
  '�' => '潗',
  '�' => '緝',
  '�' => '輯',
  '�' => '鏶',
  '�' => '集',
  '�' => '徵',
  '�' => '懲',
  '�' => '澄',
  '�' => '且',
  '�' => '侘',
  '�' => '借',
  '�' => '叉',
  '�' => '嗟',
  '�' => '嵯',
  '�' => '差',
  '�' => '次',
  '�' => '此',
  '�' => '磋',
  '�' => '箚',
  '�' => '茶',
  '�' => '蹉',
  '�' => '車',
  '�' => '遮',
  '�' => '捉',
  '�' => '搾',
  '�' => '着',
  '�' => '窄',
  '�' => '錯',
  '�' => '鑿',
  '�' => '齪',
  '�' => '撰',
  '�' => '澯',
  '�' => '燦',
  '�' => '璨',
  '�' => '瓚',
  '�' => '竄',
  '��' => '簒',
  '��' => '纂',
  '��' => '粲',
  '��' => '纘',
  '��' => '讚',
  '��' => '贊',
  '��' => '鑽',
  '��' => '餐',
  '��' => '饌',
  '��' => '刹',
  '��' => '察',
  '��' => '擦',
  '��' => '札',
  '��' => '紮',
  '��' => '僭',
  '��' => '參',
  '��' => '塹',
  '��' => '慘',
  '��' => '慙',
  '��' => '懺',
  '��' => '斬',
  '��' => '站',
  '��' => '讒',
  '��' => '讖',
  '��' => '倉',
  '��' => '倡',
  '��' => '創',
  '��' => '唱',
  '��' => '娼',
  '��' => '廠',
  '��' => '彰',
  '��' => '愴',
  '��' => '敞',
  '��' => '昌',
  '��' => '昶',
  '��' => '暢',
  '��' => '槍',
  '��' => '滄',
  '��' => '漲',
  '��' => '猖',
  '��' => '瘡',
  '��' => '窓',
  '��' => '脹',
  '��' => '艙',
  '��' => '菖',
  '��' => '蒼',
  '��' => '債',
  '��' => '埰',
  '��' => '寀',
  '��' => '寨',
  '��' => '彩',
  '�' => '採',
  '�' => '砦',
  '�' => '綵',
  '�' => '菜',
  '�' => '蔡',
  '�' => '采',
  '�' => '釵',
  '�' => '冊',
  '�' => '柵',
  '�' => '策',
  '�' => '責',
  '�' => '凄',
  '�' => '妻',
  '�' => '悽',
  '�' => '處',
  '�' => '倜',
  '�' => '刺',
  '�' => '剔',
  '�' => '尺',
  '�' => '慽',
  '�' => '戚',
  '�' => '拓',
  '�' => '擲',
  '�' => '斥',
  '�' => '滌',
  '�' => '瘠',
  '�' => '脊',
  '�' => '蹠',
  '�' => '陟',
  '�' => '隻',
  '�' => '仟',
  '�' => '千',
  '�' => '喘',
  '�' => '天',
  '�' => '川',
  '�' => '擅',
  '�' => '泉',
  '�' => '淺',
  '�' => '玔',
  '�' => '穿',
  '�' => '舛',
  '�' => '薦',
  '�' => '賤',
  '��' => '踐',
  '��' => '遷',
  '��' => '釧',
  '��' => '闡',
  '��' => '阡',
  '��' => '韆',
  '��' => '凸',
  '��' => '哲',
  '��' => '喆',
  '��' => '徹',
  '��' => '撤',
  '��' => '澈',
  '��' => '綴',
  '��' => '輟',
  '��' => '轍',
  '��' => '鐵',
  '��' => '僉',
  '��' => '尖',
  '��' => '沾',
  '��' => '添',
  '��' => '甛',
  '��' => '瞻',
  '��' => '簽',
  '��' => '籤',
  '��' => '詹',
  '��' => '諂',
  '��' => '堞',
  '��' => '妾',
  '��' => '帖',
  '��' => '捷',
  '��' => '牒',
  '��' => '疊',
  '��' => '睫',
  '��' => '諜',
  '��' => '貼',
  '��' => '輒',
  '��' => '廳',
  '��' => '晴',
  '��' => '淸',
  '��' => '聽',
  '��' => '菁',
  '��' => '請',
  '��' => '靑',
  '��' => '鯖',
  '��' => '切',
  '��' => '剃',
  '��' => '替',
  '��' => '涕',
  '��' => '滯',
  '��' => '締',
  '��' => '諦',
  '�' => '逮',
  '�' => '遞',
  '�' => '體',
  '�' => '初',
  '�' => '剿',
  '�' => '哨',
  '�' => '憔',
  '�' => '抄',
  '�' => '招',
  '�' => '梢',
  '��' => '椒',
  '��' => '楚',
  '��' => '樵',
  '��' => '炒',
  '��' => '焦',
  '��' => '硝',
  '��' => '礁',
  '��' => '礎',
  '��' => '秒',
  '��' => '稍',
  '��' => '肖',
  '��' => '艸',
  '��' => '苕',
  '��' => '草',
  '��' => '蕉',
  '��' => '貂',
  '��' => '超',
  '��' => '酢',
  '��' => '醋',
  '��' => '醮',
  '��' => '促',
  '��' => '囑',
  '��' => '燭',
  '��' => '矗',
  '��' => '蜀',
  '��' => '觸',
  '��' => '寸',
  '��' => '忖',
  '��' => '村',
  '��' => '邨',
  '��' => '叢',
  '��' => '塚',
  '��' => '寵',
  '��' => '悤',
  '��' => '憁',
  '��' => '摠',
  '��' => '總',
  '��' => '聰',
  '��' => '蔥',
  '��' => '銃',
  '��' => '撮',
  '��' => '催',
  '��' => '崔',
  '��' => '最',
  '��' => '墜',
  '��' => '抽',
  '��' => '推',
  '��' => '椎',
  '��' => '楸',
  '��' => '樞',
  '��' => '湫',
  '��' => '皺',
  '��' => '秋',
  '��' => '芻',
  '��' => '萩',
  '��' => '諏',
  '��' => '趨',
  '��' => '追',
  '��' => '鄒',
  '��' => '酋',
  '��' => '醜',
  '��' => '錐',
  '��' => '錘',
  '��' => '鎚',
  '��' => '雛',
  '��' => '騶',
  '��' => '鰍',
  '��' => '丑',
  '��' => '畜',
  '��' => '祝',
  '��' => '竺',
  '��' => '筑',
  '��' => '築',
  '��' => '縮',
  '��' => '蓄',
  '��' => '蹙',
  '��' => '蹴',
  '��' => '軸',
  '��' => '逐',
  '��' => '春',
  '��' => '椿',
  '��' => '瑃',
  '��' => '出',
  '��' => '朮',
  '��' => '黜',
  '��' => '充',
  '��' => '忠',
  '��' => '沖',
  '��' => '蟲',
  '��' => '衝',
  '��' => '衷',
  '��' => '悴',
  '��' => '膵',
  '��' => '萃',
  '��' => '贅',
  '��' => '取',
  '��' => '吹',
  '��' => '嘴',
  '��' => '娶',
  '��' => '就',
  '��' => '炊',
  '��' => '翠',
  '��' => '聚',
  '��' => '脆',
  '��' => '臭',
  '��' => '趣',
  '��' => '醉',
  '��' => '驟',
  '��' => '鷲',
  '��' => '側',
  '��' => '仄',
  '��' => '厠',
  '��' => '惻',
  '��' => '測',
  '��' => '層',
  '��' => '侈',
  '��' => '値',
  '��' => '嗤',
  '��' => '峙',
  '��' => '幟',
  '��' => '恥',
  '��' => '梔',
  '��' => '治',
  '��' => '淄',
  '��' => '熾',
  '��' => '痔',
  '��' => '痴',
  '��' => '癡',
  '��' => '稚',
  '��' => '穉',
  '��' => '緇',
  '��' => '緻',
  '��' => '置',
  '��' => '致',
  '��' => '蚩',
  '��' => '輜',
  '��' => '雉',
  '��' => '馳',
  '��' => '齒',
  '��' => '則',
  '��' => '勅',
  '��' => '飭',
  '��' => '親',
  '��' => '七',
  '��' => '柒',
  '��' => '漆',
  '��' => '侵',
  '��' => '寢',
  '��' => '枕',
  '��' => '沈',
  '��' => '浸',
  '��' => '琛',
  '��' => '砧',
  '��' => '針',
  '��' => '鍼',
  '��' => '蟄',
  '��' => '秤',
  '��' => '稱',
  '��' => '快',
  '��' => '他',
  '��' => '咤',
  '��' => '唾',
  '��' => '墮',
  '��' => '妥',
  '��' => '惰',
  '��' => '打',
  '��' => '拖',
  '��' => '朶',
  '��' => '楕',
  '��' => '舵',
  '��' => '陀',
  '��' => '馱',
  '��' => '駝',
  '��' => '倬',
  '��' => '卓',
  '��' => '啄',
  '��' => '坼',
  '��' => '度',
  '��' => '托',
  '��' => '拓',
  '��' => '擢',
  '��' => '晫',
  '��' => '柝',
  '��' => '濁',
  '��' => '濯',
  '��' => '琢',
  '��' => '琸',
  '��' => '託',
  '��' => '鐸',
  '��' => '呑',
  '��' => '嘆',
  '��' => '坦',
  '��' => '彈',
  '��' => '憚',
  '��' => '歎',
  '��' => '灘',
  '��' => '炭',
  '��' => '綻',
  '��' => '誕',
  '��' => '奪',
  '��' => '脫',
  '��' => '探',
  '��' => '眈',
  '��' => '耽',
  '��' => '貪',
  '��' => '塔',
  '��' => '搭',
  '��' => '榻',
  '��' => '宕',
  '��' => '帑',
  '��' => '湯',
  '��' => '糖',
  '��' => '蕩',
  '��' => '兌',
  '��' => '台',
  '��' => '太',
  '��' => '怠',
  '��' => '態',
  '��' => '殆',
  '��' => '汰',
  '��' => '泰',
  '��' => '笞',
  '��' => '胎',
  '��' => '苔',
  '��' => '跆',
  '��' => '邰',
  '��' => '颱',
  '��' => '宅',
  '��' => '擇',
  '��' => '澤',
  '��' => '撑',
  '��' => '攄',
  '��' => '兎',
  '��' => '吐',
  '��' => '土',
  '��' => '討',
  '��' => '慟',
  '��' => '桶',
  '��' => '洞',
  '��' => '痛',
  '��' => '筒',
  '��' => '統',
  '��' => '通',
  '��' => '堆',
  '��' => '槌',
  '��' => '腿',
  '��' => '褪',
  '��' => '退',
  '��' => '頹',
  '��' => '偸',
  '��' => '套',
  '��' => '妬',
  '��' => '投',
  '��' => '透',
  '��' => '鬪',
  '��' => '慝',
  '��' => '特',
  '��' => '闖',
  '��' => '坡',
  '��' => '婆',
  '��' => '巴',
  '��' => '把',
  '��' => '播',
  '��' => '擺',
  '��' => '杷',
  '��' => '波',
  '��' => '派',
  '��' => '爬',
  '��' => '琶',
  '��' => '破',
  '��' => '罷',
  '��' => '芭',
  '��' => '跛',
  '��' => '頗',
  '��' => '判',
  '��' => '坂',
  '��' => '板',
  '��' => '版',
  '��' => '瓣',
  '��' => '販',
  '��' => '辦',
  '��' => '鈑',
  '��' => '阪',
  '��' => '八',
  '��' => '叭',
  '��' => '捌',
  '��' => '佩',
  '��' => '唄',
  '��' => '悖',
  '��' => '敗',
  '��' => '沛',
  '��' => '浿',
  '��' => '牌',
  '��' => '狽',
  '��' => '稗',
  '��' => '覇',
  '��' => '貝',
  '��' => '彭',
  '��' => '澎',
  '��' => '烹',
  '��' => '膨',
  '��' => '愎',
  '��' => '便',
  '��' => '偏',
  '��' => '扁',
  '��' => '片',
  '��' => '篇',
  '��' => '編',
  '��' => '翩',
  '��' => '遍',
  '��' => '鞭',
  '��' => '騙',
  '��' => '貶',
  '��' => '坪',
  '��' => '平',
  '��' => '枰',
  '��' => '萍',
  '��' => '評',
  '��' => '吠',
  '��' => '嬖',
  '��' => '幣',
  '��' => '廢',
  '��' => '弊',
  '��' => '斃',
  '��' => '肺',
  '��' => '蔽',
  '��' => '閉',
  '��' => '陛',
  '��' => '佈',
  '��' => '包',
  '��' => '匍',
  '��' => '匏',
  '��' => '咆',
  '��' => '哺',
  '��' => '圃',
  '��' => '布',
  '��' => '怖',
  '��' => '抛',
  '��' => '抱',
  '��' => '捕',
  '��' => '暴',
  '��' => '泡',
  '��' => '浦',
  '��' => '疱',
  '��' => '砲',
  '��' => '胞',
  '��' => '脯',
  '��' => '苞',
  '��' => '葡',
  '��' => '蒲',
  '��' => '袍',
  '��' => '褒',
  '��' => '逋',
  '��' => '鋪',
  '��' => '飽',
  '��' => '鮑',
  '��' => '幅',
  '��' => '暴',
  '��' => '曝',
  '��' => '瀑',
  '��' => '爆',
  '��' => '輻',
  '��' => '俵',
  '��' => '剽',
  '��' => '彪',
  '��' => '慓',
  '��' => '杓',
  '��' => '標',
  '��' => '漂',
  '��' => '瓢',
  '��' => '票',
  '��' => '表',
  '��' => '豹',
  '��' => '飇',
  '��' => '飄',
  '��' => '驃',
  '��' => '品',
  '��' => '稟',
  '��' => '楓',
  '��' => '諷',
  '��' => '豊',
  '��' => '風',
  '��' => '馮',
  '��' => '彼',
  '��' => '披',
  '��' => '疲',
  '��' => '皮',
  '��' => '被',
  '��' => '避',
  '��' => '陂',
  '��' => '匹',
  '��' => '弼',
  '��' => '必',
  '��' => '泌',
  '��' => '珌',
  '��' => '畢',
  '��' => '疋',
  '��' => '筆',
  '��' => '苾',
  '��' => '馝',
  '��' => '乏',
  '��' => '逼',
  '��' => '下',
  '��' => '何',
  '��' => '厦',
  '��' => '夏',
  '��' => '廈',
  '��' => '昰',
  '��' => '河',
  '��' => '瑕',
  '��' => '荷',
  '��' => '蝦',
  '��' => '賀',
  '��' => '遐',
  '��' => '霞',
  '��' => '鰕',
  '��' => '壑',
  '��' => '學',
  '��' => '虐',
  '��' => '謔',
  '��' => '鶴',
  '��' => '寒',
  '��' => '恨',
  '��' => '悍',
  '��' => '旱',
  '��' => '汗',
  '��' => '漢',
  '��' => '澣',
  '��' => '瀚',
  '��' => '罕',
  '��' => '翰',
  '��' => '閑',
  '��' => '閒',
  '��' => '限',
  '��' => '韓',
  '��' => '割',
  '��' => '轄',
  '��' => '函',
  '��' => '含',
  '��' => '咸',
  '��' => '啣',
  '��' => '喊',
  '��' => '檻',
  '��' => '涵',
  '��' => '緘',
  '��' => '艦',
  '��' => '銜',
  '��' => '陷',
  '��' => '鹹',
  '��' => '合',
  '��' => '哈',
  '��' => '盒',
  '��' => '蛤',
  '��' => '閤',
  '��' => '闔',
  '��' => '陜',
  '��' => '亢',
  '��' => '伉',
  '��' => '姮',
  '��' => '嫦',
  '��' => '巷',
  '��' => '恒',
  '��' => '抗',
  '��' => '杭',
  '��' => '桁',
  '��' => '沆',
  '��' => '港',
  '��' => '缸',
  '��' => '肛',
  '��' => '航',
  '��' => '行',
  '��' => '降',
  '��' => '項',
  '��' => '亥',
  '��' => '偕',
  '��' => '咳',
  '��' => '垓',
  '��' => '奚',
  '��' => '孩',
  '��' => '害',
  '��' => '懈',
  '��' => '楷',
  '��' => '海',
  '��' => '瀣',
  '��' => '蟹',
  '��' => '解',
  '��' => '該',
  '��' => '諧',
  '��' => '邂',
  '��' => '駭',
  '��' => '骸',
  '��' => '劾',
  '��' => '核',
  '��' => '倖',
  '��' => '幸',
  '��' => '杏',
  '��' => '荇',
  '��' => '行',
  '��' => '享',
  '��' => '向',
  '��' => '嚮',
  '��' => '珦',
  '��' => '鄕',
  '��' => '響',
  '��' => '餉',
  '��' => '饗',
  '��' => '香',
  '��' => '噓',
  '��' => '墟',
  '��' => '虛',
  '��' => '許',
  '��' => '憲',
  '��' => '櫶',
  '��' => '獻',
  '��' => '軒',
  '��' => '歇',
  '��' => '險',
  '��' => '驗',
  '��' => '奕',
  '��' => '爀',
  '��' => '赫',
  '��' => '革',
  '��' => '俔',
  '��' => '峴',
  '��' => '弦',
  '��' => '懸',
  '��' => '晛',
  '��' => '泫',
  '��' => '炫',
  '��' => '玄',
  '��' => '玹',
  '��' => '現',
  '��' => '眩',
  '��' => '睍',
  '��' => '絃',
  '��' => '絢',
  '��' => '縣',
  '��' => '舷',
  '��' => '衒',
  '��' => '見',
  '��' => '賢',
  '��' => '鉉',
  '��' => '顯',
  '��' => '孑',
  '��' => '穴',
  '��' => '血',
  '��' => '頁',
  '��' => '嫌',
  '��' => '俠',
  '��' => '協',
  '��' => '夾',
  '��' => '峽',
  '��' => '挾',
  '��' => '浹',
  '��' => '狹',
  '��' => '脅',
  '��' => '脇',
  '��' => '莢',
  '��' => '鋏',
  '��' => '頰',
  '��' => '亨',
  '��' => '兄',
  '��' => '刑',
  '��' => '型',
  '��' => '形',
  '��' => '泂',
  '��' => '滎',
  '��' => '瀅',
  '��' => '灐',
  '��' => '炯',
  '��' => '熒',
  '��' => '珩',
  '��' => '瑩',
  '��' => '荊',
  '��' => '螢',
  '��' => '衡',
  '��' => '逈',
  '��' => '邢',
  '��' => '鎣',
  '��' => '馨',
  '��' => '兮',
  '��' => '彗',
  '��' => '惠',
  '��' => '慧',
  '��' => '暳',
  '��' => '蕙',
  '��' => '蹊',
  '��' => '醯',
  '��' => '鞋',
  '��' => '乎',
  '��' => '互',
  '��' => '呼',
  '��' => '壕',
  '��' => '壺',
  '��' => '好',
  '��' => '岵',
  '��' => '弧',
  '��' => '戶',
  '��' => '扈',
  '��' => '昊',
  '��' => '晧',
  '��' => '毫',
  '��' => '浩',
  '��' => '淏',
  '��' => '湖',
  '��' => '滸',
  '��' => '澔',
  '��' => '濠',
  '��' => '濩',
  '��' => '灝',
  '��' => '狐',
  '��' => '琥',
  '��' => '瑚',
  '��' => '瓠',
  '��' => '皓',
  '��' => '祜',
  '��' => '糊',
  '��' => '縞',
  '��' => '胡',
  '��' => '芦',
  '��' => '葫',
  '��' => '蒿',
  '��' => '虎',
  '��' => '號',
  '��' => '蝴',
  '��' => '護',
  '��' => '豪',
  '��' => '鎬',
  '��' => '頀',
  '��' => '顥',
  '��' => '惑',
  '��' => '或',
  '��' => '酷',
  '��' => '婚',
  '��' => '昏',
  '��' => '混',
  '��' => '渾',
  '��' => '琿',
  '��' => '魂',
  '��' => '忽',
  '��' => '惚',
  '��' => '笏',
  '��' => '哄',
  '��' => '弘',
  '��' => '汞',
  '��' => '泓',
  '��' => '洪',
  '��' => '烘',
  '��' => '紅',
  '��' => '虹',
  '��' => '訌',
  '��' => '鴻',
  '��' => '化',
  '��' => '和',
  '��' => '嬅',
  '��' => '樺',
  '��' => '火',
  '��' => '畵',
  '��' => '禍',
  '��' => '禾',
  '��' => '花',
  '��' => '華',
  '��' => '話',
  '��' => '譁',
  '��' => '貨',
  '��' => '靴',
  '��' => '廓',
  '��' => '擴',
  '��' => '攫',
  '��' => '確',
  '��' => '碻',
  '��' => '穫',
  '��' => '丸',
  '��' => '喚',
  '��' => '奐',
  '��' => '宦',
  '��' => '幻',
  '��' => '患',
  '��' => '換',
  '��' => '歡',
  '��' => '晥',
  '��' => '桓',
  '��' => '渙',
  '��' => '煥',
  '��' => '環',
  '��' => '紈',
  '��' => '還',
  '��' => '驩',
  '��' => '鰥',
  '��' => '活',
  '��' => '滑',
  '��' => '猾',
  '��' => '豁',
  '��' => '闊',
  '��' => '凰',
  '��' => '幌',
  '��' => '徨',
  '��' => '恍',
  '��' => '惶',
  '��' => '愰',
  '��' => '慌',
  '��' => '晃',
  '��' => '晄',
  '��' => '榥',
  '��' => '況',
  '��' => '湟',
  '��' => '滉',
  '��' => '潢',
  '��' => '煌',
  '��' => '璜',
  '��' => '皇',
  '��' => '篁',
  '��' => '簧',
  '��' => '荒',
  '��' => '蝗',
  '��' => '遑',
  '��' => '隍',
  '��' => '黃',
  '��' => '匯',
  '��' => '回',
  '��' => '廻',
  '��' => '徊',
  '��' => '恢',
  '��' => '悔',
  '��' => '懷',
  '��' => '晦',
  '��' => '會',
  '��' => '檜',
  '��' => '淮',
  '��' => '澮',
  '��' => '灰',
  '��' => '獪',
  '��' => '繪',
  '��' => '膾',
  '��' => '茴',
  '��' => '蛔',
  '��' => '誨',
  '��' => '賄',
  '��' => '劃',
  '��' => '獲',
  '��' => '宖',
  '��' => '橫',
  '��' => '鐄',
  '��' => '哮',
  '��' => '嚆',
  '��' => '孝',
  '��' => '效',
  '��' => '斅',
  '��' => '曉',
  '��' => '梟',
  '��' => '涍',
  '��' => '淆',
  '��' => '爻',
  '��' => '肴',
  '��' => '酵',
  '��' => '驍',
  '��' => '侯',
  '��' => '候',
  '��' => '厚',
  '��' => '后',
  '��' => '吼',
  '��' => '喉',
  '��' => '嗅',
  '��' => '帿',
  '��' => '後',
  '��' => '朽',
  '��' => '煦',
  '��' => '珝',
  '��' => '逅',
  '��' => '勛',
  '��' => '勳',
  '��' => '塤',
  '��' => '壎',
  '��' => '焄',
  '��' => '熏',
  '��' => '燻',
  '��' => '薰',
  '��' => '訓',
  '��' => '暈',
  '��' => '薨',
  '��' => '喧',
  '��' => '暄',
  '��' => '煊',
  '��' => '萱',
  '��' => '卉',
  '��' => '喙',
  '��' => '毁',
  '��' => '彙',
  '��' => '徽',
  '��' => '揮',
  '��' => '暉',
  '��' => '煇',
  '��' => '諱',
  '��' => '輝',
  '��' => '麾',
  '��' => '休',
  '��' => '携',
  '��' => '烋',
  '��' => '畦',
  '��' => '虧',
  '��' => '恤',
  '��' => '譎',
  '��' => '鷸',
  '��' => '兇',
  '��' => '凶',
  '��' => '匈',
  '��' => '洶',
  '��' => '胸',
  '��' => '黑',
  '��' => '昕',
  '��' => '欣',
  '��' => '炘',
  '��' => '痕',
  '��' => '吃',
  '��' => '屹',
  '��' => '紇',
  '��' => '訖',
  '��' => '欠',
  '��' => '欽',
  '��' => '歆',
  '��' => '吸',
  '��' => '恰',
  '��' => '洽',
  '��' => '翕',
  '��' => '興',
  '��' => '僖',
  '��' => '凞',
  '��' => '喜',
  '��' => '噫',
  '��' => '囍',
  '��' => '姬',
  '��' => '嬉',
  '��' => '希',
  '��' => '憙',
  '��' => '憘',
  '��' => '戱',
  '��' => '晞',
  '��' => '曦',
  '��' => '熙',
  '��' => '熹',
  '��' => '熺',
  '��' => '犧',
  '��' => '禧',
  '��' => '稀',
  '��' => '羲',
  '��' => '詰',
);

$result =& $data;
unset($data);

return $result;
PKϤ$Z�A���/polyfill-iconv/Resources/charset/from.cp737.phpnu�[���<?php

static $data = array (
  '' => '',
  '' => '',
  '' => '',
  '' => '',
  '' => '',
  '' => '',
  '' => '',
  '' => '',
  '' => '',
  '	' => '	',
  '
' => '
',
  '' => '',
  '' => '',
  '
' => '
',
  '' => '',
  '' => '',
  '' => '',
  '' => '',
  '' => '',
  '' => '',
  '' => '',
  '' => '',
  '' => '',
  '' => '',
  '' => '',
  '' => '',
  '' => '',
  '' => '',
  '' => '',
  '' => '',
  '' => '',
  '' => '',
  ' ' => ' ',
  '!' => '!',
  '"' => '"',
  '#' => '#',
  '$' => '$',
  '%' => '%',
  '&' => '&',
  '\'' => '\'',
  '(' => '(',
  ')' => ')',
  '*' => '*',
  '+' => '+',
  ',' => ',',
  '-' => '-',
  '.' => '.',
  '/' => '/',
  0 => '0',
  1 => '1',
  2 => '2',
  3 => '3',
  4 => '4',
  5 => '5',
  6 => '6',
  7 => '7',
  8 => '8',
  9 => '9',
  ':' => ':',
  ';' => ';',
  '<' => '<',
  '=' => '=',
  '>' => '>',
  '?' => '?',
  '@' => '@',
  'A' => 'A',
  'B' => 'B',
  'C' => 'C',
  'D' => 'D',
  'E' => 'E',
  'F' => 'F',
  'G' => 'G',
  'H' => 'H',
  'I' => 'I',
  'J' => 'J',
  'K' => 'K',
  'L' => 'L',
  'M' => 'M',
  'N' => 'N',
  'O' => 'O',
  'P' => 'P',
  'Q' => 'Q',
  'R' => 'R',
  'S' => 'S',
  'T' => 'T',
  'U' => 'U',
  'V' => 'V',
  'W' => 'W',
  'X' => 'X',
  'Y' => 'Y',
  'Z' => 'Z',
  '[' => '[',
  '\\' => '\\',
  ']' => ']',
  '^' => '^',
  '_' => '_',
  '`' => '`',
  'a' => 'a',
  'b' => 'b',
  'c' => 'c',
  'd' => 'd',
  'e' => 'e',
  'f' => 'f',
  'g' => 'g',
  'h' => 'h',
  'i' => 'i',
  'j' => 'j',
  'k' => 'k',
  'l' => 'l',
  'm' => 'm',
  'n' => 'n',
  'o' => 'o',
  'p' => 'p',
  'q' => 'q',
  'r' => 'r',
  's' => 's',
  't' => 't',
  'u' => 'u',
  'v' => 'v',
  'w' => 'w',
  'x' => 'x',
  'y' => 'y',
  'z' => 'z',
  '{' => '{',
  '|' => '|',
  '}' => '}',
  '~' => '~',
  '' => '',
  '�' => 'Α',
  '�' => 'Β',
  '�' => 'Γ',
  '�' => 'Δ',
  '�' => 'Ε',
  '�' => 'Ζ',
  '�' => 'Η',
  '�' => 'Θ',
  '�' => 'Ι',
  '�' => 'Κ',
  '�' => 'Λ',
  '�' => 'Μ',
  '�' => 'Ν',
  '�' => 'Ξ',
  '�' => 'Ο',
  '�' => 'Π',
  '�' => 'Ρ',
  '�' => 'Σ',
  '�' => 'Τ',
  '�' => 'Υ',
  '�' => 'Φ',
  '�' => 'Χ',
  '�' => 'Ψ',
  '�' => 'Ω',
  '�' => 'α',
  '�' => 'β',
  '�' => 'γ',
  '�' => 'δ',
  '�' => 'ε',
  '�' => 'ζ',
  '�' => 'η',
  '�' => 'θ',
  '�' => 'ι',
  '�' => 'κ',
  '�' => 'λ',
  '�' => 'μ',
  '�' => 'ν',
  '�' => 'ξ',
  '�' => 'ο',
  '�' => 'π',
  '�' => 'ρ',
  '�' => 'σ',
  '�' => 'ς',
  '�' => 'τ',
  '�' => 'υ',
  '�' => 'φ',
  '�' => 'χ',
  '�' => 'ψ',
  '�' => '░',
  '�' => '▒',
  '�' => '▓',
  '�' => '│',
  '�' => '┤',
  '�' => '╡',
  '�' => '╢',
  '�' => '╖',
  '�' => '╕',
  '�' => '╣',
  '�' => '║',
  '�' => '╗',
  '�' => '╝',
  '�' => '╜',
  '�' => '╛',
  '�' => '┐',
  '�' => '└',
  '�' => '┴',
  '�' => '┬',
  '�' => '├',
  '�' => '─',
  '�' => '┼',
  '�' => '╞',
  '�' => '╟',
  '�' => '╚',
  '�' => '╔',
  '�' => '╩',
  '�' => '╦',
  '�' => '╠',
  '�' => '═',
  '�' => '╬',
  '�' => '╧',
  '�' => '╨',
  '�' => '╤',
  '�' => '╥',
  '�' => '╙',
  '�' => '╘',
  '�' => '╒',
  '�' => '╓',
  '�' => '╫',
  '�' => '╪',
  '�' => '┘',
  '�' => '┌',
  '�' => '█',
  '�' => '▄',
  '�' => '▌',
  '�' => '▐',
  '�' => '▀',
  '�' => 'ω',
  '�' => 'ά',
  '�' => 'έ',
  '�' => 'ή',
  '�' => 'ϊ',
  '�' => 'ί',
  '�' => 'ό',
  '�' => 'ύ',
  '�' => 'ϋ',
  '�' => 'ώ',
  '�' => 'Ά',
  '�' => 'Έ',
  '�' => 'Ή',
  '�' => 'Ί',
  '�' => 'Ό',
  '�' => 'Ύ',
  '�' => 'Ώ',
  '�' => '±',
  '�' => '≥',
  '�' => '≤',
  '�' => 'Ϊ',
  '�' => 'Ϋ',
  '�' => '÷',
  '�' => '≈',
  '�' => '°',
  '�' => '∙',
  '�' => '·',
  '�' => '√',
  '�' => 'ⁿ',
  '�' => '²',
  '�' => '■',
  '�' => ' ',
);

$result =& $data;
unset($data);

return $result;
PKϤ$Z���spolyfill-iconv/bootstrap.phpnu�[���<?php

/*
 * This file is part of the Symfony package.
 *
 * (c) Fabien Potencier <fabien@symfony.com>
 *
 * For the full copyright and license information, please view the LICENSE
 * file that was distributed with this source code.
 */

use Symfony\Polyfill\Iconv as p;

if (extension_loaded('iconv')) {
    return;
}

if (!defined('ICONV_IMPL')) {
    define('ICONV_IMPL', 'Symfony');
}
if (!defined('ICONV_VERSION')) {
    define('ICONV_VERSION', '1.0');
}
if (!defined('ICONV_MIME_DECODE_STRICT')) {
    define('ICONV_MIME_DECODE_STRICT', 1);
}
if (!defined('ICONV_MIME_DECODE_CONTINUE_ON_ERROR')) {
    define('ICONV_MIME_DECODE_CONTINUE_ON_ERROR', 2);
}

if (!function_exists('iconv')) {
    function iconv($from, $to, $s) { return p\Iconv::iconv($from, $to, $s); }
}
if (!function_exists('iconv_get_encoding')) {
    function iconv_get_encoding($type = 'all') { return p\Iconv::iconv_get_encoding($type); }
}
if (!function_exists('iconv_set_encoding')) {
    function iconv_set_encoding($type, $charset) { return p\Iconv::iconv_set_encoding($type, $charset); }
}
if (!function_exists('iconv_mime_encode')) {
    function iconv_mime_encode($name, $value, $pref = null) { return p\Iconv::iconv_mime_encode($name, $value, $pref); }
}
if (!function_exists('iconv_mime_decode_headers')) {
    function iconv_mime_decode_headers($encodedHeaders, $mode = 0, $enc = null) { return p\Iconv::iconv_mime_decode_headers($encodedHeaders, $mode, $enc); }
}

if (extension_loaded('mbstring')) {
    if (!function_exists('iconv_strlen')) {
        function iconv_strlen($s, $enc = null) { null === $enc and $enc = p\Iconv::$internalEncoding; return mb_strlen($s, $enc); }
    }
    if (!function_exists('iconv_strpos')) {
        function iconv_strpos($s, $needle, $offset = 0, $enc = null) { null === $enc and $enc = p\Iconv::$internalEncoding; return mb_strpos($s, $needle, $offset, $enc); }
    }
    if (!function_exists('iconv_strrpos')) {
        function iconv_strrpos($s, $needle, $enc = null) { null === $enc and $enc = p\Iconv::$internalEncoding; return mb_strrpos($s, $needle, 0, $enc); }
    }
    if (!function_exists('iconv_substr')) {
        function iconv_substr($s, $start, $length = 2147483647, $enc = null) { null === $enc and $enc = p\Iconv::$internalEncoding; return mb_substr($s, $start, $length, $enc); }
    }
    if (!function_exists('iconv_mime_decode')) {
        function iconv_mime_decode($encodedHeaders, $mode = 0, $enc = null) { null === $enc and $enc = p\Iconv::$internalEncoding; return mb_decode_mimeheader($encodedHeaders, $mode, $enc); }
    }
} else {
    if (!function_exists('iconv_strlen')) {
        if (extension_loaded('xml')) {
            function iconv_strlen($s, $enc = null) { return p\Iconv::strlen1($s, $enc); }
        } else {
            function iconv_strlen($s, $enc = null) { return p\Iconv::strlen2($s, $enc); }
        }
    }

    if (!function_exists('iconv_strpos')) {
        function iconv_strpos($s, $needle, $offset = 0, $enc = null) { return p\Iconv::iconv_strpos($s, $needle, $offset, $enc); }
    }
    if (!function_exists('iconv_strrpos')) {
        function iconv_strrpos($s, $needle, $enc = null) { return p\Iconv::iconv_strrpos($s, $needle, $enc); }
    }
    if (!function_exists('iconv_substr')) {
        function iconv_substr($s, $start, $length = 2147483647, $enc = null) { return p\Iconv::iconv_substr($s, $start, $length, $enc); }
    }
    if (!function_exists('iconv_mime_decode')) {
        function iconv_mime_decode($encodedHeaders, $mode = 0, $enc = null) { return p\Iconv::iconv_mime_decode($encodedHeaders, $mode, $enc); }
    }
}
PKϤ$Z~�Ʊ�X�Xpolyfill-iconv/Iconv.phpnu�[���<?php

/*
 * This file is part of the Symfony package.
 *
 * (c) Fabien Potencier <fabien@symfony.com>
 *
 * For the full copyright and license information, please view the LICENSE
 * file that was distributed with this source code.
 */

namespace Symfony\Polyfill\Iconv;

/**
 * iconv implementation in pure PHP, UTF-8 centric.
 *
 * Implemented:
 * - iconv              - Convert string to requested character encoding
 * - iconv_mime_decode  - Decodes a MIME header field
 * - iconv_mime_decode_headers - Decodes multiple MIME header fields at once
 * - iconv_get_encoding - Retrieve internal configuration variables of iconv extension
 * - iconv_set_encoding - Set current setting for character encoding conversion
 * - iconv_mime_encode  - Composes a MIME header field
 * - iconv_strlen       - Returns the character count of string
 * - iconv_strpos       - Finds position of first occurrence of a needle within a haystack
 * - iconv_strrpos      - Finds the last occurrence of a needle within a haystack
 * - iconv_substr       - Cut out part of a string
 *
 * Charsets available for conversion are defined by files
 * in the charset/ directory and by Iconv::$alias below.
 * You're welcome to send back any addition you make.
 *
 * @author Nicolas Grekas <p@tchwork.com>
 *
 * @internal
 */
final class Iconv
{
    const ERROR_ILLEGAL_CHARACTER = 'iconv(): Detected an illegal character in input string';
    const ERROR_WRONG_CHARSET = 'iconv(): Wrong charset, conversion from `%s\' to `%s\' is not allowed';

    public static $inputEncoding = 'utf-8';
    public static $outputEncoding = 'utf-8';
    public static $internalEncoding = 'utf-8';

    private static $alias = array(
        'utf8' => 'utf-8',
        'ascii' => 'us-ascii',
        'tis-620' => 'iso-8859-11',
        'cp1250' => 'windows-1250',
        'cp1251' => 'windows-1251',
        'cp1252' => 'windows-1252',
        'cp1253' => 'windows-1253',
        'cp1254' => 'windows-1254',
        'cp1255' => 'windows-1255',
        'cp1256' => 'windows-1256',
        'cp1257' => 'windows-1257',
        'cp1258' => 'windows-1258',
        'shift-jis' => 'cp932',
        'shift_jis' => 'cp932',
        'latin1' => 'iso-8859-1',
        'latin2' => 'iso-8859-2',
        'latin3' => 'iso-8859-3',
        'latin4' => 'iso-8859-4',
        'latin5' => 'iso-8859-9',
        'latin6' => 'iso-8859-10',
        'latin7' => 'iso-8859-13',
        'latin8' => 'iso-8859-14',
        'latin9' => 'iso-8859-15',
        'latin10' => 'iso-8859-16',
        'iso8859-1' => 'iso-8859-1',
        'iso8859-2' => 'iso-8859-2',
        'iso8859-3' => 'iso-8859-3',
        'iso8859-4' => 'iso-8859-4',
        'iso8859-5' => 'iso-8859-5',
        'iso8859-6' => 'iso-8859-6',
        'iso8859-7' => 'iso-8859-7',
        'iso8859-8' => 'iso-8859-8',
        'iso8859-9' => 'iso-8859-9',
        'iso8859-10' => 'iso-8859-10',
        'iso8859-11' => 'iso-8859-11',
        'iso8859-12' => 'iso-8859-12',
        'iso8859-13' => 'iso-8859-13',
        'iso8859-14' => 'iso-8859-14',
        'iso8859-15' => 'iso-8859-15',
        'iso8859-16' => 'iso-8859-16',
        'iso_8859-1' => 'iso-8859-1',
        'iso_8859-2' => 'iso-8859-2',
        'iso_8859-3' => 'iso-8859-3',
        'iso_8859-4' => 'iso-8859-4',
        'iso_8859-5' => 'iso-8859-5',
        'iso_8859-6' => 'iso-8859-6',
        'iso_8859-7' => 'iso-8859-7',
        'iso_8859-8' => 'iso-8859-8',
        'iso_8859-9' => 'iso-8859-9',
        'iso_8859-10' => 'iso-8859-10',
        'iso_8859-11' => 'iso-8859-11',
        'iso_8859-12' => 'iso-8859-12',
        'iso_8859-13' => 'iso-8859-13',
        'iso_8859-14' => 'iso-8859-14',
        'iso_8859-15' => 'iso-8859-15',
        'iso_8859-16' => 'iso-8859-16',
        'iso88591' => 'iso-8859-1',
        'iso88592' => 'iso-8859-2',
        'iso88593' => 'iso-8859-3',
        'iso88594' => 'iso-8859-4',
        'iso88595' => 'iso-8859-5',
        'iso88596' => 'iso-8859-6',
        'iso88597' => 'iso-8859-7',
        'iso88598' => 'iso-8859-8',
        'iso88599' => 'iso-8859-9',
        'iso885910' => 'iso-8859-10',
        'iso885911' => 'iso-8859-11',
        'iso885912' => 'iso-8859-12',
        'iso885913' => 'iso-8859-13',
        'iso885914' => 'iso-8859-14',
        'iso885915' => 'iso-8859-15',
        'iso885916' => 'iso-8859-16',
    );
    private static $translitMap = array();
    private static $convertMap = array();
    private static $errorHandler;
    private static $lastError;

    private static $ulenMask = array("\xC0" => 2, "\xD0" => 2, "\xE0" => 3, "\xF0" => 4);
    private static $isValidUtf8;

    public static function iconv($inCharset, $outCharset, $str)
    {
        $str = (string) $str;
        if ('' === $str) {
            return '';
        }

        // Prepare for //IGNORE and //TRANSLIT

        $translit = $ignore = '';

        $outCharset = strtolower($outCharset);
        $inCharset = strtolower($inCharset);

        if ('' === $outCharset) {
            $outCharset = 'iso-8859-1';
        }
        if ('' === $inCharset) {
            $inCharset = 'iso-8859-1';
        }

        do {
            $loop = false;

            if ('//translit' === substr($outCharset, -10)) {
                $loop = $translit = true;
                $outCharset = substr($outCharset, 0, -10);
            }

            if ('//ignore' === substr($outCharset, -8)) {
                $loop = $ignore = true;
                $outCharset = substr($outCharset, 0, -8);
            }
        } while ($loop);

        do {
            $loop = false;

            if ('//translit' === substr($inCharset, -10)) {
                $loop = true;
                $inCharset = substr($inCharset, 0, -10);
            }

            if ('//ignore' === substr($inCharset, -8)) {
                $loop = true;
                $inCharset = substr($inCharset, 0, -8);
            }
        } while ($loop);

        if (isset(self::$alias[$inCharset])) {
            $inCharset = self::$alias[$inCharset];
        }
        if (isset(self::$alias[$outCharset])) {
            $outCharset = self::$alias[$outCharset];
        }

        // Load charset maps

        if (('utf-8' !== $inCharset && !self::loadMap('from.', $inCharset, $inMap))
          || ('utf-8' !== $outCharset && !self::loadMap('to.', $outCharset, $outMap))) {
            trigger_error(sprintf(self::ERROR_WRONG_CHARSET, $inCharset, $outCharset));

            return false;
        }

        if ('utf-8' !== $inCharset) {
            // Convert input to UTF-8
            $result = '';
            if (self::mapToUtf8($result, $inMap, $str, $ignore)) {
                $str = $result;
            } else {
                $str = false;
            }
            self::$isValidUtf8 = true;
        } else {
            self::$isValidUtf8 = preg_match('//u', $str);

            if (!self::$isValidUtf8 && !$ignore) {
                trigger_error(self::ERROR_ILLEGAL_CHARACTER);

                return false;
            }

            if ('utf-8' === $outCharset) {
                // UTF-8 validation
                $str = self::utf8ToUtf8($str, $ignore);
            }
        }

        if ('utf-8' !== $outCharset && false !== $str) {
            // Convert output to UTF-8
            $result = '';
            if (self::mapFromUtf8($result, $outMap, $str, $ignore, $translit)) {
                return $result;
            }

            return false;
        }

        return $str;
    }

    public static function iconv_mime_decode_headers($str, $mode = 0, $charset = null)
    {
        if (null === $charset) {
            $charset = self::$internalEncoding;
        }

        if (false !== strpos($str, "\r")) {
            $str = strtr(str_replace("\r\n", "\n", $str), "\r", "\n");
        }
        $str = explode("\n\n", $str, 2);

        $headers = array();

        $str = preg_split('/\n(?![ \t])/', $str[0]);
        foreach ($str as $str) {
            $str = self::iconv_mime_decode($str, $mode, $charset);
            if (false === $str) {
                return false;
            }
            $str = explode(':', $str, 2);

            if (2 === \count($str)) {
                if (isset($headers[$str[0]])) {
                    if (!\is_array($headers[$str[0]])) {
                        $headers[$str[0]] = array($headers[$str[0]]);
                    }
                    $headers[$str[0]][] = ltrim($str[1]);
                } else {
                    $headers[$str[0]] = ltrim($str[1]);
                }
            }
        }

        return $headers;
    }

    public static function iconv_mime_decode($str, $mode = 0, $charset = null)
    {
        if (null === $charset) {
            $charset = self::$internalEncoding;
        }
        if (ICONV_MIME_DECODE_CONTINUE_ON_ERROR & $mode) {
            $charset .= '//IGNORE';
        }

        if (false !== strpos($str, "\r")) {
            $str = strtr(str_replace("\r\n", "\n", $str), "\r", "\n");
        }
        $str = preg_split('/\n(?![ \t])/', rtrim($str), 2);
        $str = preg_replace('/[ \t]*\n[ \t]+/', ' ', rtrim($str[0]));
        $str = preg_split('/=\?([^?]+)\?([bqBQ])\?(.*?)\?=/', $str, -1, PREG_SPLIT_DELIM_CAPTURE);

        $result = self::iconv('utf-8', $charset, $str[0]);
        if (false === $result) {
            return false;
        }

        $i = 1;
        $len = \count($str);

        while ($i < $len) {
            $c = strtolower($str[$i]);
            if ((ICONV_MIME_DECODE_CONTINUE_ON_ERROR & $mode)
              && 'utf-8' !== $c
              && !isset(self::$alias[$c])
              && !self::loadMap('from.', $c, $d)) {
                $d = false;
            } elseif ('B' === strtoupper($str[$i + 1])) {
                $d = base64_decode($str[$i + 2]);
            } else {
                $d = rawurldecode(strtr(str_replace('%', '%25', $str[$i + 2]), '=_', '% '));
            }

            if (false !== $d) {
                if ('' !== $d) {
                    if ('' === $d = self::iconv($c, $charset, $d)) {
                        $str[$i + 3] = substr($str[$i + 3], 1);
                    } else {
                        $result .= $d;
                    }
                }
                $d = self::iconv('utf-8', $charset, $str[$i + 3]);
                if ('' !== trim($d)) {
                    $result .= $d;
                }
            } elseif (ICONV_MIME_DECODE_CONTINUE_ON_ERROR & $mode) {
                $result .= "=?{$str[$i]}?{$str[$i + 1]}?{$str[$i + 2]}?={$str[$i + 3]}";
            } else {
                $result = false;
                break;
            }

            $i += 4;
        }

        return $result;
    }

    public static function iconv_get_encoding($type = 'all')
    {
        switch ($type) {
            case 'input_encoding': return self::$inputEncoding;
            case 'output_encoding': return self::$outputEncoding;
            case 'internal_encoding': return self::$internalEncoding;
        }

        return array(
            'input_encoding' => self::$inputEncoding,
            'output_encoding' => self::$outputEncoding,
            'internal_encoding' => self::$internalEncoding,
        );
    }

    public static function iconv_set_encoding($type, $charset)
    {
        switch ($type) {
            case 'input_encoding': self::$inputEncoding = $charset; break;
            case 'output_encoding': self::$outputEncoding = $charset; break;
            case 'internal_encoding': self::$internalEncoding = $charset; break;

            default: return false;
        }

        return true;
    }

    public static function iconv_mime_encode($fieldName, $fieldValue, $pref = null)
    {
        if (!\is_array($pref)) {
            $pref = array();
        }

        $pref += array(
            'scheme' => 'B',
            'input-charset' => self::$internalEncoding,
            'output-charset' => self::$internalEncoding,
            'line-length' => 76,
            'line-break-chars' => "\r\n",
        );

        if (preg_match('/[\x80-\xFF]/', $fieldName)) {
            $fieldName = '';
        }

        $scheme = strtoupper(substr($pref['scheme'], 0, 1));
        $in = strtolower($pref['input-charset']);
        $out = strtolower($pref['output-charset']);

        if ('utf-8' !== $in && false === $fieldValue = self::iconv($in, 'utf-8', $fieldValue)) {
            return false;
        }

        preg_match_all('/./us', $fieldValue, $chars);

        $chars = isset($chars[0]) ? $chars[0] : array();

        $lineBreak = (int) $pref['line-length'];
        $lineStart = "=?{$pref['output-charset']}?{$scheme}?";
        $lineLength = \strlen($fieldName) + 2 + \strlen($lineStart) + 2;
        $lineOffset = \strlen($lineStart) + 3;
        $lineData = '';

        $fieldValue = array();

        $Q = 'Q' === $scheme;

        foreach ($chars as $c) {
            if ('utf-8' !== $out && false === $c = self::iconv('utf-8', $out, $c)) {
                return false;
            }

            $o = $Q
                ? $c = preg_replace_callback(
                    '/[=_\?\x00-\x1F\x80-\xFF]/',
                    array(__CLASS__, 'qpByteCallback'),
                    $c
                )
                : base64_encode($lineData.$c);

            if (isset($o[$lineBreak - $lineLength])) {
                if (!$Q) {
                    $lineData = base64_encode($lineData);
                }
                $fieldValue[] = $lineStart.$lineData.'?=';
                $lineLength = $lineOffset;
                $lineData = '';
            }

            $lineData .= $c;
            $Q && $lineLength += \strlen($c);
        }

        if ('' !== $lineData) {
            if (!$Q) {
                $lineData = base64_encode($lineData);
            }
            $fieldValue[] = $lineStart.$lineData.'?=';
        }

        return $fieldName.': '.implode($pref['line-break-chars'].' ', $fieldValue);
    }

    public static function iconv_strlen($s, $encoding = null)
    {
        static $hasXml = null;
        if (null === $hasXml) {
            $hasXml = \extension_loaded('xml');
        }

        if ($hasXml) {
            return self::strlen1($s, $encoding);
        }

        return self::strlen2($s, $encoding);
    }

    public static function strlen1($s, $encoding = null)
    {
        if (null === $encoding) {
            $encoding = self::$internalEncoding;
        }
        if (0 !== stripos($encoding, 'utf-8') && false === $s = self::iconv($encoding, 'utf-8', $s)) {
            return false;
        }

        return \strlen(utf8_decode($s));
    }

    public static function strlen2($s, $encoding = null)
    {
        if (null === $encoding) {
            $encoding = self::$internalEncoding;
        }
        if (0 !== stripos($encoding, 'utf-8') && false === $s = self::iconv($encoding, 'utf-8', $s)) {
            return false;
        }

        $ulenMask = self::$ulenMask;

        $i = 0;
        $j = 0;
        $len = \strlen($s);

        while ($i < $len) {
            $u = $s[$i] & "\xF0";
            $i += isset($ulenMask[$u]) ? $ulenMask[$u] : 1;
            ++$j;
        }

        return $j;
    }

    public static function iconv_strpos($haystack, $needle, $offset = 0, $encoding = null)
    {
        if (null === $encoding) {
            $encoding = self::$internalEncoding;
        }

        if (0 !== stripos($encoding, 'utf-8')) {
            if (false === $haystack = self::iconv($encoding, 'utf-8', $haystack)) {
                return false;
            }
            if (false === $needle = self::iconv($encoding, 'utf-8', $needle)) {
                return false;
            }
        }

        if ($offset = (int) $offset) {
            $haystack = self::iconv_substr($haystack, $offset, 2147483647, 'utf-8');
        }
        $pos = strpos($haystack, $needle);

        return false === $pos ? false : ($offset + ($pos ? self::iconv_strlen(substr($haystack, 0, $pos), 'utf-8') : 0));
    }

    public static function iconv_strrpos($haystack, $needle, $encoding = null)
    {
        if (null === $encoding) {
            $encoding = self::$internalEncoding;
        }

        if (0 !== stripos($encoding, 'utf-8')) {
            if (false === $haystack = self::iconv($encoding, 'utf-8', $haystack)) {
                return false;
            }
            if (false === $needle = self::iconv($encoding, 'utf-8', $needle)) {
                return false;
            }
        }

        $pos = isset($needle[0]) ? strrpos($haystack, $needle) : false;

        return false === $pos ? false : self::iconv_strlen($pos ? substr($haystack, 0, $pos) : $haystack, 'utf-8');
    }

    public static function iconv_substr($s, $start, $length = 2147483647, $encoding = null)
    {
        if (null === $encoding) {
            $encoding = self::$internalEncoding;
        }
        if (0 !== stripos($encoding, 'utf-8')) {
            $encoding = null;
        } elseif (false === $s = self::iconv($encoding, 'utf-8', $s)) {
            return false;
        }

        $s = (string) $s;
        $slen = self::iconv_strlen($s, 'utf-8');
        $start = (int) $start;

        if (0 > $start) {
            $start += $slen;
        }
        if (0 > $start) {
            return false;
        }
        if ($start >= $slen) {
            return false;
        }

        $rx = $slen - $start;

        if (0 > $length) {
            $length += $rx;
        }
        if (0 === $length) {
            return '';
        }
        if (0 > $length) {
            return false;
        }

        if ($length > $rx) {
            $length = $rx;
        }

        $rx = '/^'.($start ? self::pregOffset($start) : '').'('.self::pregOffset($length).')/u';

        $s = preg_match($rx, $s, $s) ? $s[1] : '';

        if (null === $encoding) {
            return $s;
        }

        return self::iconv('utf-8', $encoding, $s);
    }

    private static function loadMap($type, $charset, &$map)
    {
        if (!isset(self::$convertMap[$type.$charset])) {
            if (false === $map = self::getData($type.$charset)) {
                if ('to.' === $type && self::loadMap('from.', $charset, $map)) {
                    $map = array_flip($map);
                } else {
                    return false;
                }
            }

            self::$convertMap[$type.$charset] = $map;
        } else {
            $map = self::$convertMap[$type.$charset];
        }

        return true;
    }

    private static function utf8ToUtf8($str, $ignore)
    {
        $ulenMask = self::$ulenMask;
        $valid = self::$isValidUtf8;

        $u = $str;
        $i = $j = 0;
        $len = \strlen($str);

        while ($i < $len) {
            if ($str[$i] < "\x80") {
                $u[$j++] = $str[$i++];
            } else {
                $ulen = $str[$i] & "\xF0";
                $ulen = isset($ulenMask[$ulen]) ? $ulenMask[$ulen] : 1;
                $uchr = substr($str, $i, $ulen);

                if (1 === $ulen || !($valid || preg_match('/^.$/us', $uchr))) {
                    if ($ignore) {
                        ++$i;
                        continue;
                    }

                    trigger_error(self::ERROR_ILLEGAL_CHARACTER);

                    return false;
                } else {
                    $i += $ulen;
                }

                $u[$j++] = $uchr[0];

                isset($uchr[1]) && 0 !== ($u[$j++] = $uchr[1])
                    && isset($uchr[2]) && 0 !== ($u[$j++] = $uchr[2])
                    && isset($uchr[3]) && 0 !== ($u[$j++] = $uchr[3]);
            }
        }

        return substr($u, 0, $j);
    }

    private static function mapToUtf8(&$result, array $map, $str, $ignore)
    {
        $len = \strlen($str);
        for ($i = 0; $i < $len; ++$i) {
            if (isset($str[$i + 1], $map[$str[$i].$str[$i + 1]])) {
                $result .= $map[$str[$i].$str[++$i]];
            } elseif (isset($map[$str[$i]])) {
                $result .= $map[$str[$i]];
            } elseif (!$ignore) {
                trigger_error(self::ERROR_ILLEGAL_CHARACTER);

                return false;
            }
        }

        return true;
    }

    private static function mapFromUtf8(&$result, array $map, $str, $ignore, $translit)
    {
        $ulenMask = self::$ulenMask;
        $valid = self::$isValidUtf8;

        if ($translit && !self::$translitMap) {
            self::$translitMap = self::getData('translit');
        }

        $i = 0;
        $len = \strlen($str);

        while ($i < $len) {
            if ($str[$i] < "\x80") {
                $uchr = $str[$i++];
            } else {
                $ulen = $str[$i] & "\xF0";
                $ulen = isset($ulenMask[$ulen]) ? $ulenMask[$ulen] : 1;
                $uchr = substr($str, $i, $ulen);

                if ($ignore && (1 === $ulen || !($valid || preg_match('/^.$/us', $uchr)))) {
                    ++$i;
                    continue;
                } else {
                    $i += $ulen;
                }
            }

            if (isset($map[$uchr])) {
                $result .= $map[$uchr];
            } elseif ($translit) {
                if (isset(self::$translitMap[$uchr])) {
                    $uchr = self::$translitMap[$uchr];
                } elseif ($uchr >= "\xC3\x80") {
                    $uchr = \Normalizer::normalize($uchr, \Normalizer::NFD);

                    if ($uchr[0] < "\x80") {
                        $uchr = $uchr[0];
                    } elseif ($ignore) {
                        continue;
                    } else {
                        return false;
                    }
                } elseif ($ignore) {
                    continue;
                } else {
                    return false;
                }

                $str = $uchr.substr($str, $i);
                $len = \strlen($str);
                $i = 0;
            } elseif (!$ignore) {
                return false;
            }
        }

        return true;
    }

    private static function qpByteCallback(array $m)
    {
        return '='.strtoupper(dechex(\ord($m[0])));
    }

    private static function pregOffset($offset)
    {
        $rx = array();
        $offset = (int) $offset;

        while ($offset > 65535) {
            $rx[] = '.{65535}';
            $offset -= 65535;
        }

        return implode('', $rx).'.{'.$offset.'}';
    }

    private static function getData($file)
    {
        if (file_exists($file = __DIR__.'/Resources/charset/'.$file.'.php')) {
            return require $file;
        }

        return false;
    }
}
PKϤ$Z�\�))polyfill-iconv/LICENSEnu�[���Copyright (c) 2015-2019 Fabien Potencier

Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is furnished
to do so, subject to the following conditions:

The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.

THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
THE SOFTWARE.
PKϤ$Z�D	�KKpolyfill-php81/README.mdnu�[���PKϤ$Z�]��7�polyfill-php81/Resources/stubs/ReturnTypeWillChange.phpnu�[���PKϤ$Z<P���polyfill-php81/bootstrap.phpnu�[���PKϤ$Z�ߐp$$�polyfill-php81/LICENSEnu�[���PKϤ$Z��$��Ppolyfill-php81/Php81.phpnu�[���PKϤ$Z�&���t�t^polyfill-intl-idn/Idn.phpnu�[���PKϤ$Z&u�{��v�polyfill-intl-idn/Info.phpnu�[���PKϤ$Z��J5����polyfill-intl-idn/README.mdnu�[���PKϤ$ZɨU�
�
�-͇polyfill-intl-idn/Resources/unidata/Regex.phpnu�[���PKϤ$ZH�}SS14polyfill-intl-idn/Resources/unidata/deviation.phpnu�[���PKϤ$Z�N��""8�polyfill-intl-idn/Resources/unidata/DisallowedRanges.phpnu�[���PKϤ$Z�u

��=S3polyfill-intl-idn/Resources/unidata/disallowed_STD3_valid.phpnu�[���PKϤ$Z�P�̭̭2�7polyfill-intl-idn/Resources/unidata/disallowed.phpnu�[���PKϤ$Z����UU.��polyfill-intl-idn/Resources/unidata/virama.phpnu�[���PKϤ$Z�d�BB>e�polyfill-intl-idn/Resources/unidata/disallowed_STD3_mapped.phpnu�[���PKϤ$Z͎��K�K�.�polyfill-intl-idn/Resources/unidata/mapped.phpnu�[���PKϤ$Z]�P*��/��polyfill-intl-idn/Resources/unidata/ignored.phpnu�[���PKϤ$Z �E���polyfill-intl-idn/bootstrap.phpnu�[���PKϤ$Z�nWWN�polyfill-intl-idn/LICENSEnu�[���PKϤ$Z.&c���*�cache-contracts/TagAwareCacheInterface.phpnu�[���PKϤ$Z�j���!5�cache-contracts/ItemInterface.phpnu�[���PKϤ$Z�Z#HHr�cache-contracts/README.mdnu�[���PKϤ$Z��msY	Y	"�cache-contracts/CacheInterface.phpnu�[���PKϤ$Z���

��cache-contracts/CacheTrait.phpnu�[���PKϤ$Zh{#��	�cache-contracts/CHANGELOG.mdnu�[���PKϤ$Z5�))��cache-contracts/LICENSEnu�[���PKϤ$Z5s��++%b�cache-contracts/CallbackInterface.phpnu�[���PKϤ$Z}�9���polyfill-php72/Php72.phpnu�[���PKϤ$Z�!>ii@polyfill-php72/README.mdnu�[���PKϤ$Z�LR��polyfill-php72/bootstrap.phpnu�[���PKϤ$Z�\�))Zpolyfill-php72/LICENSEnu�[���PKϤ$Z/��ngg�polyfill-php73/Php73.phpnu�[���PKϤ$Z	�c11xpolyfill-php73/README.mdnu�[���PKϤ$Z<F�0�polyfill-php73/Resources/stubs/JsonException.phpnu�[���PKϤ$Z?y����ipolyfill-php73/bootstrap.phpnu�[���PKϤ$Z�`e0))�polyfill-php73/LICENSEnu�[���PKϤ$Z��#O,� service-contracts/ServiceSubscriberTrait.phpnu�[���PKϤ$Z�v���$o(service-contracts/ResetInterface.phpnu�[���PKϤ$Z�!��OO-�,service-contracts/Test/ServiceLocatorTest.phpnu�[���PKϤ$Z��MNNV8service-contracts/README.mdnu�[���PKϤ$Z�mXº�.�9service-contracts/ServiceProviderInterface.phpnu�[���PKϤ$ZSR����0?service-contracts/ServiceSubscriberInterface.phpnu�[���PKϤ$Z�'�e��)-Hservice-contracts/ServiceLocatorTrait.phpnu�[���PKϤ$Z��� ��(Wservice-contracts/Attribute/Required.phpnu�[���PKϤ$Z�����Zservice-contracts/CHANGELOG.mdnu�[���PKϤ$Zi8�z))�Zservice-contracts/LICENSEnu�[���PKϤ$Z�8��m_var-exporter/README.mdnu�[���PKϤ$Z�'/IVV-�fvar-exporter/Exception/ExceptionInterface.phpnu�[���PKϤ$Zs��..7Zhvar-exporter/Exception/NotInstantiableTypeException.phpnu�[���PKϤ$Z�v_!!1�jvar-exporter/Exception/ClassNotFoundException.phpnu�[���PKϤ$Z��^��� qmvar-exporter/Internal/Values.phpnu�[���PKϤ$Z���>>"�ovar-exporter/Internal/Registry.phpnu�[���PKϤ$Z��..#6�var-exporter/Internal/Reference.phpnu�[���PKϤ$Z�*��>�>"��var-exporter/Internal/Exporter.phpnu�[���PKϤ$Z���V88"��var-exporter/Internal/Hydrator.phpnu�[���PKϤ$Z�����var-exporter/CHANGELOG.mdnu�[���PKϤ$Z5�))��var-exporter/LICENSEnu�[���PKϤ$ZZ�~J77��var-exporter/VarExporter.phpnu�[���PKϤ$ZAi@s^^r�var-exporter/Instantiator.phpnu�[���PKϤ$Zo��d�N�Nstring/AbstractString.phpnu�[���PKϤ$ZW�;e�<�<%+Pstring/Inflector/EnglishInflector.phpnu�[���PKϤ$Z!9�a��$B�string/Inflector/FrenchInflector.phpnu�[���PKϤ$ZQ�ccCC'*�string/Inflector/InflectorInterface.phpnu�[���PKϤ$Z"�O���#Ĩstring/Slugger/SluggerInterface.phpnu�[���PKϤ$Ze�����string/Slugger/AsciiSlugger.phpnu�[���PKϤ$Z�L��++$�string/README.mdnu�[���PKϤ$Z�M̿k�k ��string/AbstractUnicodeString.phpnu�[���PKϤ$Zj8��C2C2�2string/UnicodeString.phpnu�[���PKϤ$Z�5�$�8�8-)estring/Resources/data/wcswidth_table_zero.phpnu�[���PKϤ$Zܰ�O0O0-V�string/Resources/data/wcswidth_table_wide.phpnu�[���PKϤ$Z�ې]]�string/Resources/functions.phpnu�[���PKϤ$Z�I!))��string/LazyString.phpnu�[���PKϤ$Z$���QQ'�string/Exception/ExceptionInterface.phpnu�[���PKϤ$Ze�����-��string/Exception/InvalidArgumentException.phpnu�[���PKϤ$Z��0�pp%��string/Exception/RuntimeException.phpnu�[���PKϤ$Z���DDe�string/CHANGELOG.mdnu�[���PKϤ$Z�M-��;�;��string/ByteString.phpnu�[���PKϤ$Z=��))+string/LICENSEnu�[���PKϤ$Zn^t{{h/string/CodePointString.phpnu�[���PKϤ$ZUp�zz-Oyaml/Inline.phpnu�[���PKϤ$Z��6MM!o�yaml/Tests/ParseExceptionTest.phpnu�[���PKϤ$Z�ĥ�CLCL
�yaml/Tests/InlineTest.phpnu�[���PKϤ$Z�p<��	yaml/Tests/YamlTest.phpnu�[���PKϤ$ZoL�33%�!	yaml/Tests/Fixtures/YtsBasicTests.ymlnu�[���PKϤ$Z�5�R[[&i3	yaml/Tests/Fixtures/YtsAnchorAlias.ymlnu�[���PKϤ$Z�<�!7	yaml/Tests/Fixtures/sfObjects.ymlnu�[���PKϤ$Z�a9qr�r�0�8	yaml/Tests/Fixtures/YtsSpecificationExamples.ymlnu�[���PKϤ$ZB4����(Y�	yaml/Tests/Fixtures/YtsTypeTransfers.ymlnu�[���PKϤ$Z�c����,��	yaml/Tests/Fixtures/YtsDocumentSeparator.ymlnu�[���PKϤ$ZO�_}��"�	yaml/Tests/Fixtures/sfComments.ymlnu�[���PKϤ$ZZ��"�
yaml/Tests/Fixtures/embededPhp.ymlnu�[���PKϤ$ZZ{k�XX*I
yaml/Tests/Fixtures/YtsFlowCollections.ymlnu�[���PKϤ$Zz����"�

yaml/Tests/Fixtures/sfMergeKey.ymlnu�[���PKϤ$Z*��,��)E
yaml/Tests/Fixtures/escapedCharacters.ymlnu�[���PKϤ$Zګغzz(Z
yaml/Tests/Fixtures/YtsFoldedScalars.ymlnu�[���PKϤ$Z��UU!,+
yaml/Tests/Fixtures/sfCompact.ymlnu�[���PKϤ$Z//L¹	�	�6
yaml/Tests/Fixtures/sfTests.ymlnu�[���PKϤ$Z���88�@
yaml/Tests/Fixtures/index.ymlnu�[���PKϤ$Z+=��� _B
yaml/Tests/Fixtures/sfQuotes.ymlnu�[���PKϤ$Z�+/N-�E
yaml/Tests/Fixtures/unindentedCollections.ymlnu�[���PKϤ$Z�����'M
yaml/Tests/Fixtures/YtsBlockMapping.ymlnu�[���PKϤ$Z�>;���*�P
yaml/Tests/Fixtures/YtsNullsAndEmpties.ymlnu�[���PKϤ$Zt��rqq%�S
yaml/Tests/Fixtures/YtsErrorTests.ymlnu�[���PKϤ$Z�ԧ���V
yaml/Tests/DumperTest.phpnu�[���PKϤ$Z�Z%
_
_�r
yaml/Tests/ParserTest.phpnu�[���PKϤ$Z�n������
yaml/Parser.phpnu�[���PKϤ$Zn��%����yaml/Tag/TaggedValue.phpnu�[���PKϤ$Z԰�""�yaml/Unescaper.phpnu�[���PKϤ$Z���HRRj�yaml/Dumper.phpnu�[���PKϤ$ZX3� � ��yaml/Command/LintCommand.phpnu�[���PKϤ$Z�p������yaml/README.mdnu�[���PKϤ$Z�ʭ���yaml/Escaper.phpnu�[���PKϤ$Z�t�J��!3�yaml/Exception/ParseException.phpnu�[���PKϤ$Z��� l�yaml/Exception/DumpException.phpnu�[���PKϤ$ZB9���%��yaml/Exception/ExceptionInterface.phpnu�[���PKϤ$Z�_q���#��yaml/Exception/RuntimeException.phpnu�[���PKϤ$Z-z����yaml/CHANGELOG.mdnu�[���PKϤ$Z=��))�yaml/LICENSEnu�[���PKϤ$Z3JU��
5yaml/Yaml.phpnu�[���PKϤ$Z!e�*"'config/Tests/Definition/ScalarNodeTest.phpnu�[���PKϤ$Z�{5,��:�6config/Tests/Definition/Builder/EnumNodeDefinitionTest.phpnu�[���PKϤ$Z��Y11=�=config/Tests/Definition/Builder/BooleanNodeDefinitionTest.phpnu�[���PKϤ$ZB�z�
�
==Aconfig/Tests/Definition/Builder/NumericNodeDefinitionTest.phpnu�[���PKϤ$Z�,��!�!;�Oconfig/Tests/Definition/Builder/ArrayNodeDefinitionTest.phpnu�[���PKϤ$Z�#�<3�qconfig/Tests/Definition/Builder/ExprBuilderTest.phpnu�[���PKϤ$Z4�}}3:�config/Tests/Definition/Builder/TreeBuilderTest.phpnu�[���PKϤ$Z�,�1�
�
3�config/Tests/Definition/Builder/NodeBuilderTest.phpnu�[���PKϤ$Z��t�-<�config/Tests/Definition/NormalizationTest.phpnu�[���PKϤ$Z5��r��+��config/Tests/Definition/BooleanNodeTest.phpnu�[���PKϤ$Zbv�8��)��config/Tests/Definition/ArrayNodeTest.phpnu�[���PKϤ$Zz�3�
�
9��config/Tests/Definition/Dumper/XmlReferenceDumperTest.phpnu�[���PKϤ$Z����%%:��config/Tests/Definition/Dumper/YamlReferenceDumperTest.phpnu�[���PKϤ$Z����LL%_�config/Tests/Definition/MergeTest.phpnu�[���PKϤ$Z=a��-�-3
config/Tests/Definition/PrototypedArrayNodeTest.phpnu�[���PKϤ$Z�__,`@
config/Tests/Definition/FinalizationTest.phpnu�[���PKϤ$Z^�;LL(I
config/Tests/Definition/EnumNodeTest.phpnu�[���PKϤ$Zep���+�O
config/Tests/Definition/IntegerNodeTest.phpnu�[���PKϤ$Z�BN@@@)�V
config/Tests/Definition/FloatNodeTest.phpnu�[���PKϤ$Z�+���"�^
config/Tests/Loader/LoaderTest.phpnu�[���PKϤ$Zhӈ�``,�m
config/Tests/Loader/DelegatingLoaderTest.phpnu�[���PKϤ$Z�sܶ&sy
config/Tests/Loader/FileLoaderTest.phpnu�[���PKϤ$Z���*܈
config/Tests/Loader/LoaderResolverTest.phpnu�[���PKϤ$Zf���'B�
config/Tests/ConfigCacheFactoryTest.phpnu�[���PKϤ$Z�H�]��"��
config/Tests/Util/XmlUtilsTest.phpnu�[���PKϤ$Z"XB���/h�
config/Tests/ResourceCheckerConfigCacheTest.phpnu�[���PKϤ$Z��_��3��
config/Tests/Resource/FileExistenceResourceTest.phpnu�[���PKϤ$Z;��A

*��
config/Tests/Resource/FileResourceTest.phpnu�[���PKϤ$Z*�#��&��
config/Tests/Resource/ResourceStub.phpnu�[���PKϤ$Z��PP4�
config/Tests/Resource/ClassExistenceResourceTest.phpnu�[���PKϤ$Z��W��/��
config/Tests/Resource/DirectoryResourceTest.phpnu�[���PKϤ$Z��
config/Tests/Fixtures/foo.xmlnu�[���PKϤ$Z!U��zz!C�
config/Tests/Fixtures/BarNode.phpnu�[���PKϤ$Z�?�..3�
config/Tests/Fixtures/Builder/BarNodeDefinition.phpnu�[���PKϤ$Z��@��8�config/Tests/Fixtures/Builder/VariableNodeDefinition.phpnu�[���PKϤ$Z�u�;ss-�config/Tests/Fixtures/Builder/NodeBuilder.phpnu�[���PKϤ$Z�&�%�config/Tests/Fixtures/Util/schema.xsdnu�[���PKϤ$Z\�XX$config/Tests/Fixtures/Util/valid.xmlnu�[���PKϤ$Zc=���,�config/Tests/Fixtures/Util/document_type.xmlnu�[���PKϤ$Z�b�..&�	config/Tests/Fixtures/Util/invalid.xmlnu�[���PKϤ$ZGɩ�SS-6
config/Tests/Fixtures/Util/invalid_schema.xmlnu�[���PKϤ$Z�Qø�<�
config/Tests/Fixtures/Configuration/ExampleConfiguration.phpnu�[���PKϤ$Z#
config/Tests/Fixtures/Again/foo.xmlnu�[���PKϤ$Z@��� ]config/Tests/FileLocatorTest.phpnu�[���PKϤ$Z�>�u))6�+config/Tests/Exception/FileLoaderLoadExceptionTest.phpnu�[���PKϤ$Z�6M�	�	 W8config/Tests/ConfigCacheTest.phpnu�[���PKϤ$Z���ss!?Bconfig/Definition/NumericNode.phpnu�[���PKϤ$Z�bB,B,)Jconfig/Definition/PrototypedArrayNode.phpnu�[���PKϤ$Z��@@�vconfig/Definition/BaseNode.phpnu�[���PKϤ$Z�uee,��config/Definition/ConfigurationInterface.phpnu�[���PKϤ$Zo�`���)��config/Definition/Builder/ExprBuilder.phpnu�[���PKϤ$Z�.�1��config/Definition/Builder/FloatNodeDefinition.phpnu�[���PKϤ$ZCP

3`�config/Definition/Builder/BooleanNodeDefinition.phpnu�[���PKϤ$Z����*��config/Definition/Builder/MergeBuilder.phpnu�[���PKϤ$Z�,���0��config/Definition/Builder/EnumNodeDefinition.phpnu�[���PKϤ$ZH]>Ԙ�;3�config/Definition/Builder/ParentNodeDefinitionInterface.phpnu�[���PKϤ$ZرV�"�",6�config/Definition/Builder/NodeDefinition.phpnu�[���PKϤ$Z�i����/6
config/Definition/Builder/ValidationBuilder.phpnu�[���PKϤ$Z�.ΦC?C?1Zconfig/Definition/Builder/ArrayNodeDefinition.phpnu�[���PKϤ$ZK�p�)�Mconfig/Definition/Builder/TreeBuilder.phpnu�[���PKϤ$ZB��}CC3[Tconfig/Definition/Builder/BuilderAwareInterface.phpnu�[���PKϤ$Z#��994Wconfig/Definition/Builder/VariableNodeDefinition.phpnu�[���PKϤ$Z��)�^config/Definition/Builder/NodeBuilder.phpnu�[���PKϤ$ZY��ӿ�1�rconfig/Definition/Builder/NodeParentInterface.phpnu�[���PKϤ$Z/@-��2uconfig/Definition/Builder/NormalizationBuilder.phpnu�[���PKϤ$Z6�l���3{config/Definition/Builder/NumericNodeDefinition.phpnu�[���PKϤ$Z�f3�config/Definition/Builder/IntegerNodeDefinition.phpnu�[���PKϤ$Z�_e���2z�config/Definition/Builder/ScalarNodeDefinition.phpnu�[���PKϤ$Z�x��
�
"ljconfig/Definition/VariableNode.phpnu�[���PKϤ$ZD�����config/Definition/EnumNode.phpnu�[���PKϤ$Z��nlq(q(/�config/Definition/Dumper/XmlReferenceDumper.phpnu�[���PKϤ$Z�^ZƘ � 0��config/Definition/Dumper/YamlReferenceDumper.phpnu�[���PKϤ$Zh�v��!��config/Definition/BooleanNode.phpnu�[���PKϤ$Zzԉ��� ��config/Definition/ScalarNode.phpnu�[���PKϤ$ZP,EeV	V	#��config/Definition/NodeInterface.phpnu�[���PKϤ$Z������config/Definition/FloatNode.phpnu�[���PKϤ$Z�� t.t.�config/Definition/ArrayNode.phpnu�[���PKϤ$Z��7�

�2config/Definition/Processor.phpnu�[���PKϤ$Z�p��>>=�<config/Definition/Exception/InvalidConfigurationException.phpnu�[���PKϤ$Z�po:��){Aconfig/Definition/Exception/Exception.phpnu�[���PKϤ$Z]F4���:�Cconfig/Definition/Exception/InvalidDefinitionException.phpnu�[���PKϤ$Z��@��4�Econfig/Definition/Exception/InvalidTypeException.phpnu�[���PKϤ$Z�|�EE54Hconfig/Definition/Exception/DuplicateKeyException.phpnu�[���PKϤ$Z�:2&QQ;�Jconfig/Definition/Exception/ForbiddenOverwriteException.phpnu�[���PKϤ$Z����1�Mconfig/Definition/Exception/UnsetKeyException.phpnu�[���PKϤ$Z��M�GG,Pconfig/Definition/PrototypeNodeInterface.phpnu�[���PKϤ$Z;	�YY!�Rconfig/Definition/IntegerNode.phpnu�[���PKϤ$Z���ww!dWconfig/Loader/LoaderInterface.phpnu�[���PKϤ$Z{>�c",\config/Loader/DelegatingLoader.phpnu�[���PKϤ$Z1�.��)~aconfig/Loader/LoaderResolverInterface.phpnu�[���PKϤ$Z�'�� �dconfig/Loader/LoaderResolver.phpnu�[���PKϤ$Z�@9b��  kconfig/Loader/GlobFileLoader.phpnu�[���PKϤ$ZK_�%%Hnconfig/Loader/FileLoader.phpnu�[���PKϤ$Z-�c����config/Loader/Loader.phpnu�[���PKϤ$Z�h�YY#��config/Loader/ParamConfigurator.phpnu�[���PKϤ$Z�$c��)`�config/Builder/ConfigBuilderInterface.phpnu�[���PKϤ$Z��Ƕttw�config/Builder/Method.phpnu�[���PKϤ$Z�w�H�H)4�config/Builder/ConfigBuilderGenerator.phpnu�[���PKϤ$Z;��-��m�config/Builder/Property.phpnu�[���PKϤ$Z�_&8��2��config/Builder/ConfigBuilderGeneratorInterface.phpnu�[���PKϤ$Z�0{G^^��config/Builder/ClassBuilder.phpnu�[���PKϤ$Z��e1��&L�config/ConfigCacheFactoryInterface.phpnu�[���PKϤ$Z%�&�&`config/Util/XmlUtils.phpnu�[���PKϤ$Z��_���-Q(config/Util/Exception/XmlParsingException.phpnu�[���PKϤ$ZCh&&-�*config/Util/Exception/InvalidXmlException.phpnu�[���PKϤ$ZrX31-config/Resource/SelfCheckingResourceInterface.phpnu�[���PKϤ$Z����
�
%o0config/Resource/DirectoryResource.phpnu�[���PKϤ$Z�N1��%X;config/Resource/ResourceInterface.phpnu�[���PKϤ$ZU�j i?config/Resource/GlobResource.phpnu�[���PKϤ$Z���>$>$+�^config/Resource/ReflectionClassResource.phpnu�[���PKϤ$Z��``/^�config/Resource/SelfCheckingResourceChecker.phpnu�[���PKϤ$ZdΌ
��*�config/Resource/ClassExistenceResource.phpnu�[���PKϤ$Zo��00$
�config/Resource/ComposerResource.phpnu�[���PKϤ$ZԎ|�� ��config/Resource/FileResource.phpnu�[���PKϤ$Z��1���)��config/Resource/FileExistenceResource.phpnu�[���PKϤ$ZR�b.�config/ConfigCacheInterface.phpnu�[���PKϤ$Z��TT3�config/README.mdnu�[���PKϤ$ZT�&�//,Ǿconfig/ResourceCheckerConfigCacheFactory.phpnu�[���PKϤ$Z=y�&R�config/ConfigCache.phpnu�[���PKϤ$Z�u1LL(��config/Exception/LoaderLoadException.phpnu�[���PKϤ$Z����
�
,@�config/Exception/FileLoaderLoadException.phpnu�[���PKϤ$Z3	��5��config/Exception/FileLocatorFileNotFoundException.phpnu�[���PKϤ$Z4z��?��config/Exception/FileLoaderImportCircularReferenceException.phpnu�[���PKϤ$ZJXN�!!��config/FileLocatorInterface.phpnu�[���PKϤ$ZQyȋ���config/CHANGELOG.mdnu�[���PKϤ$Za�x))�config/LICENSEnu�[���PKϤ$ZC{H ��%%
config/ResourceCheckerConfigCache.phpnu�[���PKϤ$Z9t6QQQ config/ConfigCacheFactory.phpnu�[���PKϤ$ZXѥ;�	�	�$config/FileLocator.phpnu�[���PKϤ$Zι7��# /config/ResourceCheckerInterface.phpnu�[���PKϤ$Z���"A4polyfill-intl-normalizer/README.mdnu�[���PKϤ$Z�ݮ�QQ7E6polyfill-intl-normalizer/Resources/stubs/Normalizer.phpnu�[���PKϤ$Zc�,�ooI�7polyfill-intl-normalizer/Resources/unidata/compatibilityDecomposition.phpnu�[���PKϤ$Z'�C��D�DC�=polyfill-intl-normalizer/Resources/unidata/canonicalComposition.phpnu�[���PKϤ$Z�je�{�{�E;�polyfill-intl-normalizer/Resources/unidata/canonicalDecomposition.phpnu�[���PKϤ$Z���D5D5=+polyfill-intl-normalizer/Resources/unidata/combiningClass.phpnu�[���PKϤ$Z�Kwii&�Qpolyfill-intl-normalizer/bootstrap.phpnu�[���PKϤ$Z�\�)) �Tpolyfill-intl-normalizer/LICENSEnu�[���PKϤ$Z�e�"�$�$'Ypolyfill-intl-normalizer/Normalizer.phpnu�[���PKϤ$Zj���``T~polyfill-ctype/README.mdnu�[���PKϤ$Z\��}}�polyfill-ctype/Ctype.phpnu�[���PKϤ$Z-�������polyfill-ctype/bootstrap.phpnu�[���PKϤ$Z�`e0))��polyfill-ctype/LICENSEnu�[���PKϤ$Z�6�GGj�polyfill-php55/Php55.phpnu�[���PKϤ$Z~`��#��polyfill-php55/Php55ArrayColumn.phpnu�[���PKϤ$Z9��rrӳpolyfill-php55/README.mdnu�[���PKϤ$Z��/�����polyfill-php55/bootstrap.phpnu�[���PKϤ$Z�*L))��polyfill-php55/LICENSEnu�[���PKϤ$Z��o�	�	�#/�filesystem/Tests/FilesystemTest.phpnu�[���PKϤ$Z'œ ��3��filesystem/Tests/Fixtures/MockStream/MockStream.phpnu�[���PKϤ$Z����'��filesystem/Tests/FilesystemTestCase.phpnu�[���PKϤ$Z�%`�@@$��filesystem/Tests/LockHandlerTest.phpnu�[���PKϤ$Z`9|��"0�filesystem/Tests/ExceptionTest.phpnu�[���PKϤ$Z�|�7

�filesystem/LockHandler.phpnu�[���PKϤ$Z��-J��u�filesystem/README.mdnu�[���PKϤ$Z���jmjm��filesystem/Filesystem.phpnu�[���PKϤ$Z
n�j��+^4filesystem/Exception/ExceptionInterface.phpnu�[���PKϤ$Z�*����1�6filesystem/Exception/InvalidArgumentException.phpnu�[���PKϤ$ZHD���$�8filesystem/Exception/IOException.phpnu�[���PKϤ$Z��i���-�<filesystem/Exception/IOExceptionInterface.phpnu�[���PKϤ$ZFʹ��.�?filesystem/Exception/FileNotFoundException.phpnu�[���PKϤ$Z���[���Cfilesystem/CHANGELOG.mdnu�[���PKϤ$Z=��))�Ifilesystem/LICENSEnu�[���PKϤ$Z��w"w" *Ntranslation/MessageCatalogue.phpnu�[���PKϤ$Z��߄��,�ptranslation/Tests/IdentityTranslatorTest.phpnu�[���PKϤ$Z;.�BB%(~translation/Tests/fixtures/plurals.ponu�[���PKϤ$Z��W44'�~translation/Tests/fixtures/resources.monu�[���PKϤ$Z$Jtranslation/Tests/fixtures/empty.csvnu�[���PKϤ$Z:&�݊�'�translation/Tests/fixtures/withnote.xlfnu�[���PKϤ$Z#]9ӱ�2�translation/Tests/fixtures/resources-2.0-clean.xlfnu�[���PKϤ$Z�@-��.��translation/Tests/fixtures/with-attributes.xlfnu�[���PKϤ$Z�D��``(�translation/Tests/fixtures/resources.csvnu�[���PKϤ$Z���		(��translation/Tests/fixtures/resources.ymlnu�[���PKϤ$Z�.�zz(�translation/Tests/fixtures/resources.xlfnu�[���PKϤ$Z� TT(Ռtranslation/Tests/fixtures/non-valid.xlfnu�[���PKϤ$Zd��2��,��translation/Tests/fixtures/resources-2.0.xlfnu�[���PKϤ$Zl�d��2f�translation/Tests/fixtures/resources-tool-info.xlfnu�[���PKϤ$Z$��translation/Tests/fixtures/empty.ininu�[���PKϤ$Z+�L�TT4�translation/Tests/fixtures/resourcebundle/res/en.resnu�[���PKϤ$Z��<�A͕translation/Tests/fixtures/resourcebundle/corrupted/resources.datnu�[���PKϤ$Z�M�Rxx4A�translation/Tests/fixtures/resourcebundle/dat/en.resnu�[���PKϤ$Z���L((4�translation/Tests/fixtures/resourcebundle/dat/fr.txtnu�[���PKϤ$ZrQ�``;��translation/Tests/fixtures/resourcebundle/dat/resources.datnu�[���PKϤ$Z���+%%4t�translation/Tests/fixtures/resourcebundle/dat/en.txtnu�[���PKϤ$Z�g.�=��translation/Tests/fixtures/resourcebundle/dat/packagelist.txtnu�[���PKϤ$Zw˦(||4x�translation/Tests/fixtures/resourcebundle/dat/fr.resnu�[���PKϤ$Zo
�j'''X�translation/Tests/fixtures/messages.ymlnu�[���PKϤ$Z#֛translation/Tests/fixtures/empty.ponu�[���PKϤ$Zh�Ƙ.)�translation/Tests/fixtures/resources.dump.jsonnu�[���PKϤ$Z%��translation/Tests/fixtures/empty.jsonnu�[���PKϤ$Z$��translation/Tests/fixtures/empty.ymlnu�[���PKϤ$Z�:�++(I�translation/Tests/fixtures/resources.phpnu�[���PKϤ$Z�B��0̝translation/Tests/fixtures/escaped-id-plurals.ponu�[���PKϤ$Z��111/�translation/Tests/fixtures/empty-translation.monu�[���PKϤ$Z�C(���'��translation/Tests/fixtures/resources.tsnu�[���PKϤ$Z�e2~(��translation/Tests/fixtures/non-valid.ymlnu�[���PKϤ$Z�B$$$�translation/Tests/fixtures/valid.csvnu�[���PKϤ$Z����)��translation/Tests/fixtures/resources.jsonnu�[���PKϤ$Z���n��'��translation/Tests/fixtures/encoding.xlfnu�[���PKϤ$Z=Bs/:�translation/Tests/fixtures/empty-translation.ponu�[���PKϤ$Z&�S��.��translation/Tests/fixtures/resources-clean.xlfnu�[���PKϤ$Z!f����'��translation/Tests/fixtures/resources.ponu�[���PKϤ$Z�<�S)��translation/Tests/fixtures/malformed.jsonnu�[���PKϤ$Z1@'||0��translation/Tests/fixtures/fuzzy-translations.ponu�[���PKϤ$Zj5)���(Ѫtranslation/Tests/fixtures/escaped-id.ponu�[���PKϤ$Z���\"".ϫtranslation/Tests/fixtures/messages_linear.ymlnu�[���PKϤ$Z��jj*O�translation/Tests/fixtures/withdoctype.xlfnu�[���PKϤ$Z*֔�JJ%�translation/Tests/fixtures/plurals.monu�[���PKϤ$Zd֥��:��translation/Tests/fixtures/resources-target-attributes.xlfnu�[���PKϤ$ZY���44&�translation/Tests/fixtures/resname.xlfnu�[���PKϤ$Z$��translation/Tests/fixtures/empty.xlfnu�[���PKϤ$Z#�translation/Tests/fixtures/empty.monu�[���PKϤ$Z�'�F

(B�translation/Tests/fixtures/resources.ininu�[���PKϤ$Z/�
��4��translation/Tests/fixtures/invalid-xml-resources.xlfnu�[���PKϤ$ZdZ%�	�	-��translation/Tests/Loader/MoFileLoaderTest.phpnu�[���PKϤ$Z��|=��-�translation/Tests/Loader/QtFileLoaderTest.phpnu�[���PKϤ$Z���YY0��translation/Tests/Loader/XliffFileLoaderTest.phpnu�[���PKϤ$Z���.��translation/Tests/Loader/PhpFileLoaderTest.phpnu�[���PKϤ$ZF��bb	b	1�translation/Tests/Loader/IcuDatFileLoaderTest.phpnu�[���PKϤ$Z���F��-��translation/Tests/Loader/PoFileLoaderTest.phpnu�[���PKϤ$Z����<<1�translation/Tests/Loader/IcuResFileLoaderTest.phpnu�[���PKϤ$Z��:�.Ttranslation/Tests/Loader/LocalizedTestCase.phpnu�[���PKϤ$Z~�		/�
translation/Tests/Loader/YamlFileLoaderTest.phpnu�[���PKϤ$Z[����.;translation/Tests/Loader/CsvFileLoaderTest.phpnu�[���PKϤ$Zx��""/Stranslation/Tests/Loader/JsonFileLoaderTest.phpnu�[���PKϤ$Z/�݂�.�'translation/Tests/Loader/IniFileLoaderTest.phpnu�[���PKϤ$Z0�u^��-�.translation/Tests/Util/ArrayConverterTest.phpnu�[���PKϤ$Z���ڟ�1�6translation/Tests/Catalogue/DiffOperationTest.phpnu�[���PKϤ$Z�T%<��2�9translation/Tests/Catalogue/MergeOperationTest.phpnu�[���PKϤ$Zײ�))5�Etranslation/Tests/Catalogue/AbstractOperationTest.phpnu�[���PKϤ$Z��SS3�Ntranslation/Tests/Catalogue/TargetOperationTest.phpnu�[���PKϤ$Z<�-=Ztranslation/Tests/Dumper/QtFileDumperTest.phpnu�[���PKϤ$Z���/�]translation/Tests/Dumper/JsonFileDumperTest.phpnu�[���PKϤ$Z`����01ctranslation/Tests/Dumper/XliffFileDumperTest.phpnu�[���PKϤ$Z��ԙGG/aotranslation/Tests/Dumper/YamlFileDumperTest.phpnu�[���PKϤ$ZR��

-utranslation/Tests/Dumper/PoFileDumperTest.phpnu�[���PKϤ$Z\p�55.qxtranslation/Tests/Dumper/CsvFileDumperTest.phpnu�[���PKϤ$Z� k.|translation/Tests/Dumper/IniFileDumperTest.phpnu�[���PKϤ$Z����

-stranslation/Tests/Dumper/MoFileDumperTest.phpnu�[���PKϤ$Z݈�n.݂translation/Tests/Dumper/PhpFileDumperTest.phpnu�[���PKϤ$Z��M��+L�translation/Tests/Dumper/FileDumperTest.phpnu�[���PKϤ$ZA�~C&&1f�translation/Tests/Dumper/IcuResFileDumperTest.phpnu�[���PKϤ$Zr��ݢ�1�translation/Tests/DataCollectorTranslatorTest.phpnu�[���PKϤ$Z1J��+�translation/Tests/LoggingTranslatorTest.phpnu�[���PKϤ$ZH8#|+|+)��translation/Tests/TranslatorCacheTest.phpnu�[���PKϤ$Zo���((,��translation/Tests/PluralizationRulesTest.phpnu�[���PKϤ$Z�Cr��)Q�translation/Tests/MessageSelectorTest.phpnu�[���PKϤ$Z�� � *[translation/Tests/MessageCatalogueTest.phpnu�[���PKϤ$Zd�,�__@P"translation/Tests/DataCollector/TranslationDataCollectorTest.phpnu�[���PKϤ$Zi"l3��28translation/Tests/Writer/TranslationWriterTest.phpnu�[���PKϤ$Z0�2��"c?translation/Tests/IntervalTest.phpnu�[���PKϤ$Z,����^�^$XDtranslation/Tests/TranslatorTest.phpnu�[���PKϤ$Z&���]]"��translation/PluralizationRules.phpnu�[���PKϤ$Z�B��))&S�translation/TranslatorBagInterface.phpnu�[���PKϤ$Z[Q3��"ҿtranslation/IdentityTranslator.phpnu�[���PKϤ$Z�Ř�a5a5��translation/Translator.phpnu�[���PKϤ$ZpuA���)d�translation/MessageCatalogueInterface.phpnu�[���PKϤ$Z?�9���%�translation/Loader/JsonFileLoader.phpnu�[���PKϤ$Z�q���#xtranslation/Loader/MoFileLoader.phpnu�[���PKϤ$Z����dd&xtranslation/Loader/LoaderInterface.phpnu�[���PKϤ$Z"@�"�"02$translation/Loader/schema/dic/xliff-core/xml.xsdnu�[���PKϤ$ZD���lAlA;"Gtranslation/Loader/schema/dic/xliff-core/xliff-core-2.0.xsdnu�[���PKϤ$Z�xO��B��translation/Loader/schema/dic/xliff-core/xliff-core-1.2-strict.xsdnu�[���PKϤ$ZDo�E��$otranslation/Loader/CsvFileLoader.phpnu�[���PKϤ$ZI#�sI
I
#�$translation/Loader/QtFileLoader.phpnu�[���PKϤ$Z�j�S��"#/translation/Loader/ArrayLoader.phpnu�[���PKϤ$Z~v;�GG%�4translation/Loader/YamlFileLoader.phpnu�[���PKϤ$ZyR��QQ'�;translation/Loader/IcuDatFileLoader.phpnu�[���PKϤ$Zu��'��#@Ctranslation/Loader/PoFileLoader.phpnu�[���PKϤ$Z������$�Wtranslation/Loader/PhpFileLoader.phpnu�[���PKϤ$Z���00$h\translation/Loader/IniFileLoader.phpnu�[���PKϤ$Z�X���&�^translation/Loader/XliffFileLoader.phpnu�[���PKϤ$Zk�C�!}translation/Loader/FileLoader.phpnu�[���PKϤ$Z�[\�DD'h�translation/Loader/IcuResFileLoader.phpnu�[���PKϤ$Z�o&l�translation/Util/XliffUtils.phpnu�[���PKϤ$Z|�E 00#W�translation/Util/ArrayConverter.phpnu�[���PKϤ$Z��ڶ'ڰtranslation/DataCollectorTranslator.phpnu�[���PKϤ$Z�ꪴ\\.F�translation/Extractor/PhpStringTokenParser.phpnu�[���PKϤ$Zxp:CC(�translation/Extractor/ChainExtractor.phpnu�[���PKϤ$Z/�*��,��translation/Extractor/ExtractorInterface.phpnu�[���PKϤ$Z*u5��&��translation/Extractor/PhpExtractor.phpnu�[���PKϤ$Zq�dD��/�translation/Extractor/AbstractFileExtractor.phpnu�[���PKϤ$Z_:U&��+�translation/Catalogue/AbstractOperation.phpnu�[���PKϤ$Z�)�??(�translation/Catalogue/MergeOperation.phpnu�[���PKϤ$Z�C� ��,[translation/Catalogue/OperationInterface.phpnu�[���PKϤ$ZQ���PP)a#translation/Catalogue/TargetOperation.phpnu�[���PKϤ$Z��WW'
0translation/Catalogue/DiffOperation.phpnu�[���PKϤ$Z|���$�$(�4translation/Command/XliffLintCommand.phpnu�[���PKϤ$Z�0h3  &Ztranslation/Dumper/XliffFileDumper.phpnu�[���PKϤ$ZƗ�yFF%zztranslation/Dumper/YamlFileDumper.phpnu�[���PKϤ$Zݥ�$�translation/Dumper/CsvFileDumper.phpnu�[���PKϤ$Z�0H�#	#	#�translation/Dumper/MoFileDumper.phpnu�[���PKϤ$Zvu���'^�translation/Dumper/IcuResFileDumper.phpnu�[���PKϤ$Z�L����$k�translation/Dumper/IniFileDumper.phpnu�[���PKϤ$Z�7��&��translation/Dumper/DumperInterface.phpnu�[���PKϤ$Z�:���#�translation/Dumper/PoFileDumper.phpnu�[���PKϤ$Z�,&~~%�translation/Dumper/JsonFileDumper.phpnu�[���PKϤ$Z�+_hh!ķtranslation/Dumper/FileDumper.phpnu�[���PKϤ$Z;�Ɩ�#}�translation/Dumper/QtFileDumper.phpnu�[���PKϤ$Z��RR$f�translation/Dumper/PhpFileDumper.phpnu�[���PKϤ$Z��X�AA�translation/README.mdnu�[���PKϤ$ZL =���0��translation/Resources/bin/translation-status.phpnu�[���PKϤ$Z��>

'��translation/Resources/data/parents.jsonnu�[���PKϤ$Z"@�"�"%�translation/Resources/schemas/xml.xsdnu�[���PKϤ$ZD���lAlA0�translation/Resources/schemas/xliff-core-2.0.xsdnu�[���PKϤ$Z�a����7�^translation/Resources/schemas/xliff-core-1.2-strict.xsdnu�[���PKϤ$Z�|�FF+�translation/MessageSelector.phpnu�[���PKϤ$ZN���
�
2��translation/DependencyInjection/TranslatorPass.phpnu�[���PKϤ$Zeʱ��<�
translation/DependencyInjection/TranslationExtractorPass.phpnu�[���PKϤ$ZI�*OO9�translation/DependencyInjection/TranslationDumperPass.phpnu�[���PKϤ$Z{����7�translation/DependencyInjection/TranslatorPathsPass.phpnu�[���PKϤ$Z�Ы�
�
�/translation/Interval.phpnu�[���PKϤ$Z�R�99&;translation/MetadataAwareInterface.phpnu�[���PKϤ$Z�c|:��1�Atranslation/Reader/TranslationReaderInterface.phpnu�[���PKϤ$Zȳ}��(�Dtranslation/Reader/TranslationReader.phpnu�[���PKϤ$ZCa����(�Ktranslation/Exception/LogicException.phpnu�[���PKϤ$ZGP����3Ntranslation/Exception/NotFoundResourceException.phpnu�[���PKϤ$Z?�[��,UPtranslation/Exception/ExceptionInterface.phpnu�[���PKϤ$Z>O�		2�Rtranslation/Exception/InvalidArgumentException.phpnu�[���PKϤ$Z ����2�Ttranslation/Exception/InvalidResourceException.phpnu�[���PKϤ$Z[��N��*@Wtranslation/Exception/RuntimeException.phpnu�[���PKϤ$Z+v��bb�Ytranslation/CHANGELOG.mdnu�[���PKϤ$Z=��))5otranslation/LICENSEnu�[���PKϤ$ZǤ���6�stranslation/DataCollector/TranslationDataCollector.phpnu�[���PKϤ$Z��8"NN(��translation/Writer/TranslationWriter.phpnu�[���PKϤ$Z�,�8��1\�translation/Writer/TranslationWriterInterface.phpnu�[���PKϤ$Z���ϲ�0j�translation/Formatter/IntlFormatterInterface.phpnu�[���PKϤ$Z�t{*��'|�translation/Formatter/IntlFormatter.phpnu�[���PKϤ$Zh�
kk3X�translation/Formatter/MessageFormatterInterface.phpnu�[���PKϤ$Z��!{{*&�translation/Formatter/MessageFormatter.phpnu�[���PKϤ$Z���t::!��translation/LoggingTranslator.phpnu�[���PKϤ$Zj|��7&7&#��polyfill-intl-grapheme/Grapheme.phpnu�[���PKϤ$ZC�>KK �polyfill-intl-grapheme/README.mdnu�[���PKϤ$Z����$��polyfill-intl-grapheme/bootstrap.phpnu�[���PKϤ$Z�\�))��polyfill-intl-grapheme/LICENSEnu�[���PKϤ$Z��E{g
g
&[�polyfill-intl-grapheme/bootstrap80.phpnu�[���PKϤ$Z���))%�http-foundation/ResponseHeaderBag.phpnu�[���PKϤ$Z�"T�� http-foundation/UrlHelper.phpnu�[���PKϤ$Z�Ϡ!gg#�) http-foundation/Session/Session.phpnu�[���PKϤ$Z\Ȣ��*�B http-foundation/Session/SessionFactory.phpnu�[���PKϤ$Z��<<,�G http-foundation/Session/SessionInterface.phpnu�[���PKϤ$Z�6�))+BW http-foundation/Session/SessionBagProxy.phpnu�[���PKϤ$Z�n$�QQ/�_ http-foundation/Session/SessionBagInterface.phpnu�[���PKϤ$Z�Et+RR3vc http-foundation/Session/Flash/FlashBagInterface.phpnu�[���PKϤ$Z`�D�
�
*+k http-foundation/Session/Flash/FlashBag.phpnu�[���PKϤ$Z�X��
�
49v http-foundation/Session/Flash/AutoExpireFlashBag.phpnu�[���PKϤ$Z�g���B*� http-foundation/Session/Storage/PhpBridgeSessionStorageFactory.phpnu�[���PKϤ$Z 2CW��;�� http-foundation/Session/Storage/MockArraySessionStorage.phpnu�[���PKϤ$Z�w���:� http-foundation/Session/Storage/MockFileSessionStorage.phpnu�[���PKϤ$Z\�
,FF/� http-foundation/Session/Storage/MetadataBag.phpnu�[���PKϤ$ZM�k�FF?�� http-foundation/Session/Storage/NativeSessionStorageFactory.phpnu�[���PKϤ$ZP-gC��5M� http-foundation/Session/Storage/Proxy/NativeProxy.phpnu�[���PKϤ$Z�x��	�	=X� http-foundation/Session/Storage/Proxy/SessionHandlerProxy.phpnu�[���PKϤ$Z����7�� http-foundation/Session/Storage/Proxy/AbstractProxy.phpnu�[���PKϤ$Z.�ľ��>� http-foundation/Session/Storage/Handler/IdentityMarshaller.phpnu�[���PKϤ$Zx�BO� http-foundation/Session/Storage/Handler/AbstractSessionHandler.phpnu�[���PKϤ$Z����ܒܒ=�� http-foundation/Session/Storage/Handler/PdoSessionHandler.phpnu�[���PKϤ$Z��Zֶ	�	@(�!http-foundation/Session/Storage/Handler/StrictSessionHandler.phpnu�[���PKϤ$Z<[	[	EN�!http-foundation/Session/Storage/Handler/MarshallingSessionHandler.phpnu�[���PKϤ$Zkί���A�!http-foundation/Session/Storage/Handler/MongoDbSessionHandler.phpnu�[���PKϤ$Z��]v$$@z�!http-foundation/Session/Storage/Handler/NativeSessionHandler.phpnu�[���PKϤ$Z��W��
�
B�!http-foundation/Session/Storage/Handler/MemcacheSessionHandler.phpnu�[���PKϤ$Z�	�Ɩ�C^�!http-foundation/Session/Storage/Handler/MemcachedSessionHandler.phpnu�[���PKϤ$Z�n�ttAg�!http-foundation/Session/Storage/Handler/SessionHandlerFactory.phpnu�[���PKϤ$Z4tkb�
�
CL�!http-foundation/Session/Storage/Handler/MigratingSessionHandler.phpnu�[���PKϤ$Z;9����DQ�!http-foundation/Session/Storage/Handler/WriteCheckSessionHandler.phpnu�[���PKϤ$Z���S��>��!http-foundation/Session/Storage/Handler/NullSessionHandler.phpnu�[���PKϤ$Z�E�
(
(C��!http-foundation/Session/Storage/Handler/LegacyPdoSessionHandler.phpnu�[���PKϤ$Z+�8##D."http-foundation/Session/Storage/Handler/NativeFileSessionHandler.phpnu�[���PKϤ$Z>�B9PP?�%"http-foundation/Session/Storage/Handler/RedisSessionHandler.phpnu�[���PKϤ$Z#���9�4"http-foundation/Session/Storage/ServiceSessionFactory.phpnu�[���PKϤ$Z����ZZB�8"http-foundation/Session/Storage/SessionStorageFactoryInterface.phpnu�[���PKϤ$Z4�ٜ�;z;"http-foundation/Session/Storage/SessionStorageInterface.phpnu�[���PKϤ$Z=S*c��;�K"http-foundation/Session/Storage/PhpBridgeSessionStorage.phpnu�[���PKϤ$Z����ddA�Q"http-foundation/Session/Storage/MockFileSessionStorageFactory.phpnu�[���PKϤ$Z�X��7�78�V"http-foundation/Session/Storage/NativeSessionStorage.phpnu�[���PKϤ$Z	��\]](��"http-foundation/Session/SessionUtils.phpnu�[���PKϤ$ZY$p��<7�"http-foundation/Session/Attribute/NamespacedAttributeBag.phpnu�[���PKϤ$Z6Z$y;J�"http-foundation/Session/Attribute/AttributeBagInterface.phpnu�[���PKϤ$Z1%�)��2ϫ"http-foundation/Session/Attribute/AttributeBag.phpnu�[���PKϤ$Z^�v�$�$�"http-foundation/HeaderUtils.phpnu�[���PKϤ$Z�hT);(;(%
�"http-foundation/File/UploadedFile.phpnu�[���PKϤ$Z�ˇ1�	�	2�#http-foundation/File/MimeType/ExtensionGuesser.phpnu�[���PKϤ$Z��f���;�#http-foundation/File/MimeType/ExtensionGuesserInterface.phpnu�[���PKϤ$Z�>O��:�#http-foundation/File/MimeType/MimeTypeGuesserInterface.phpnu�[���PKϤ$Zp�'��1�#http-foundation/File/MimeType/MimeTypeGuesser.phpnu�[���PKϤ$Z�b�o����:!'#http-foundation/File/MimeType/MimeTypeExtensionGuesser.phpnu�[���PKϤ$Z9`;9�#http-foundation/File/MimeType/FileinfoMimeTypeGuesser.phpnu�[���PKϤ$Z���Ձ�;�#http-foundation/File/MimeType/FileBinaryMimeTypeGuesser.phpnu�[���PKϤ$Z n�/66��#http-foundation/File/Stream.phpnu�[���PKϤ$Z��4��0q�#http-foundation/File/Exception/FileException.phpnu�[���PKϤ$Z�_���2��#http-foundation/File/Exception/NoFileException.phpnu�[���PKϤ$Z�[���2��#http-foundation/File/Exception/UploadException.phpnu�[���PKϤ$Z��t���7�#http-foundation/File/Exception/IniSizeFileException.phpnu�[���PKϤ$Z�{��##:Y�#http-foundation/File/Exception/UnexpectedTypeException.phpnu�[���PKϤ$Z��j@��8��#http-foundation/File/Exception/NoTmpDirFileException.phpnu�[���PKϤ$Z����;3�#http-foundation/File/Exception/CannotWriteFileException.phpnu�[���PKϤ$Z�2����7��#http-foundation/File/Exception/PartialFileException.phpnu�[���PKϤ$Z��e���9��#http-foundation/File/Exception/ExtensionFileException.phpnu�[���PKϤ$ZPu��JJ8�#http-foundation/File/Exception/FileNotFoundException.phpnu�[���PKϤ$Zu�ZZ8��#http-foundation/File/Exception/AccessDeniedException.phpnu�[���PKϤ$Z�{���8��#http-foundation/File/Exception/FormSizeFileException.phpnu�[���PKϤ$Z��11��#http-foundation/File/File.phpnu�[���PKϤ$Z��w�nn.Z�#http-foundation/Tests/StreamedResponseTest.phpnu�[���PKϤ$ZQ�08��-&$http-foundation/Tests/Session/SessionTest.phpnu�[���PKϤ$Z\�)�444;$http-foundation/Tests/Session/Flash/FlashBagTest.phpnu�[���PKϤ$Z�ۈ���>�0$http-foundation/Tests/Session/Flash/AutoExpireFlashBagTest.phpnu�[���PKϤ$Z$�pɴ�E�B$http-foundation/Tests/Session/Storage/PhpBridgeSessionStorageTest.phpnu�[���PKϤ$Z9����GR$http-foundation/Tests/Session/Storage/Proxy/SessionHandlerProxyTest.phpnu�[���PKϤ$Z1�\���Aw^$http-foundation/Tests/Session/Storage/Proxy/AbstractProxyTest.phpnu�[���PKϤ$Z�@|B``?�q$http-foundation/Tests/Session/Storage/Proxy/NativeProxyTest.phpnu�[���PKϤ$Z�@=\&&9�u$http-foundation/Tests/Session/Storage/MetadataBagTest.phpnu�[���PKϤ$ZW�4��H*�$http-foundation/Tests/Session/Storage/Handler/NullSessionHandlerTest.phpnu�[���PKϤ$Z���[eeMF�$http-foundation/Tests/Session/Storage/Handler/MemcachedSessionHandlerTest.phpnu�[���PKϤ$ZL�&�"�"K(�$http-foundation/Tests/Session/Storage/Handler/MongoDbSessionHandlerTest.phpnu�[���PKϤ$Z�r^aaN/�$http-foundation/Tests/Session/Storage/Handler/WriteCheckSessionHandlerTest.phpnu�[���PKϤ$ZӭJz00L�$http-foundation/Tests/Session/Storage/Handler/MemcacheSessionHandlerTest.phpnu�[���PKϤ$Z(���J��$http-foundation/Tests/Session/Storage/Handler/NativeSessionHandlerTest.phpnu�[���PKϤ$Z>�M��$http-foundation/Tests/Session/Storage/Handler/LegacyPdoSessionHandlerTest.phpnu�[���PKϤ$Z���!
!
N��$http-foundation/Tests/Session/Storage/Handler/NativeFileSessionHandlerTest.phpnu�[���PKϤ$Z�0(��.�.G/�$http-foundation/Tests/Session/Storage/Handler/PdoSessionHandlerTest.phpnu�[���PKϤ$Zh]�
D�'%http-foundation/Tests/Session/Storage/MockFileSessionStorageTest.phpnu�[���PKϤ$Z"F~�T&T&B7%http-foundation/Tests/Session/Storage/NativeSessionStorageTest.phpnu�[���PKϤ$Z�����E�]%http-foundation/Tests/Session/Storage/MockArraySessionStorageTest.phpnu�[���PKϤ$Z(��vF-j%http-foundation/Tests/Session/Attribute/NamespacedAttributeBagTest.phpnu�[���PKϤ$Z9`Lv<�%http-foundation/Tests/Session/Attribute/AttributeBagTest.phpnu�[���PKϤ$Z6�-��,.�%http-foundation/Tests/RequestMatcherTest.phpnu�[���PKϤ$ZY�up55/;�%http-foundation/Tests/File/UploadedFileTest.phpnu�[���PKϤ$Z��4c00'��%http-foundation/Tests/File/FileTest.phpnu�[���PKϤ$Z�n+�@@'V�%http-foundation/Tests/File/FakeFile.phpnu�[���PKϤ$Z�/#��4��%http-foundation/Tests/File/MimeType/MimeTypeTest.phpnu�[���PKϤ$Z�+�v5��%http-foundation/Tests/File/Fixtures/.unknownextensionnu�[���PKϤ$Z��܏##,d�%http-foundation/Tests/File/Fixtures/test.gifnu�[���PKϤ$Z6��%http-foundation/Tests/File/Fixtures/other-file.examplenu�[���PKϤ$Z4I�%http-foundation/Tests/File/Fixtures/directory/.emptynu�[���PKϤ$Z�y���'��%http-foundation/Tests/HeaderBagTest.phpnu�[���PKϤ$Z�+߶� � *�&http-foundation/Tests/ParameterBagTest.phpnu�[���PKϤ$Z�&���%$*&http-foundation/Tests/IpUtilsTest.phpnu�[���PKϤ$ZZV�K~K~&i6&http-foundation/Tests/ResponseTest.phpnu�[���PKϤ$Zw<�%%'
�&http-foundation/Tests/ServerBagTest.phpnu�[���PKϤ$Z���cDD$��&http-foundation/Tests/CookieTest.phpnu�[���PKϤ$Z��lOD
D
*�&http-foundation/Tests/ResponseTestCase.phpnu�[���PKϤ$Z��fUU%��&http-foundation/Tests/FileBagTest.phpnu�[���PKϤ$Z��*f�&http-foundation/Tests/RequestStackTest.phpnu�[���PKϤ$Z��)<i7i7%�'http-foundation/Tests/RequestTest.phpnu�[���PKϤ$Z�D�:�
�
+�=(http-foundation/Tests/ApacheRequestTest.phpnu�[���PKϤ$Z%6h�xx*�H(http-foundation/Tests/JsonResponseTest.phpnu�[���PKϤ$Z�k	�
�
.if(http-foundation/Tests/AcceptHeaderItemTest.phpnu�[���PKϤ$Z�q�H��.�t(http-foundation/Tests/RedirectResponseTest.phpnu�[���PKϤ$Z�����-�-0�}(http-foundation/Tests/BinaryFileResponseTest.phpnu�[���PKϤ$Zqr��



6	�(http-foundation/Tests/ExpressionRequestMatcherTest.phpnu�[���PKϤ$Z�1r�
�
*y�(http-foundation/Tests/AcceptHeaderTest.phpnu�[���PKϤ$ZL���-�-/_�(http-foundation/Tests/ResponseHeaderBagTest.phpnu�[���PKϤ$Z#���AA$��(http-foundation/StreamedResponse.phpnu�[���PKϤ$Z��k��-�-D�(http-foundation/Cookie.phpnu�[���PKϤ$Z�/	���-)http-foundation/ServerBag.phpnu�[���PKϤ$Zw4�mP
P
$=)http-foundation/AcceptHeaderItem.phpnu�[���PKϤ$ZvZ�]���J)http-foundation/IpUtils.phpnu�[���PKϤ$ZƜ`��� �`)http-foundation/ParameterBag.phpnu�[���PKϤ$Z�K>��!�x)http-foundation/ApacheRequest.phpnu�[���PKϤ$Z�j��0�0&�|)http-foundation/BinaryFileResponse.phpnu�[���PKϤ$Zƅg�hh;ح)http-foundation/Test/Constraint/ResponseCookieValueSame.phpnu�[���PKϤ$ZD�j�ww5��)http-foundation/Test/Constraint/ResponseHasCookie.phpnu�[���PKϤ$Z���l

6��)http-foundation/Test/Constraint/ResponseHeaderSame.phpnu�[���PKϤ$Z�C�yy8��)http-foundation/Test/Constraint/ResponseIsSuccessful.phpnu�[���PKϤ$Z0��'':��)http-foundation/Test/Constraint/ResponseStatusCodeSame.phpnu�[���PKϤ$Z���|ee5l�)http-foundation/Test/Constraint/ResponseHasHeader.phpnu�[���PKϤ$Z:O��%%66�)http-foundation/Test/Constraint/ResponseFormatSame.phpnu�[���PKϤ$Z�(1ww8��)http-foundation/Test/Constraint/ResponseIsRedirected.phpnu�[���PKϤ$ZO�\��=��)http-foundation/Test/Constraint/RequestAttributeValueSame.phpnu�[���PKϤ$Z*��g"��)http-foundation/RequestMatcher.phpnu�[���PKϤ$Z�[Ū.�.�5�)http-foundation/Response.phpnu�[���PKϤ$Z�&����*http-foundation/README.mdnu�[���PKϤ$Z@g�{rr:�*http-foundation/RateLimiter/AbstractRequestRateLimiter.phpnu�[���PKϤ$Z�_uI��;�*http-foundation/RateLimiter/RequestRateLimiterInterface.phpnu�[���PKϤ$ZfL5�((F�*http-foundation/InputBag.phpnu�[���PKϤ$Z ����+��*http-foundation/RequestMatcherInterface.phpnu�[���PKϤ$Z�5���ī*http-foundation/FileBag.phpnu�[���PKϤ$Z��(7ZZ��*http-foundation/Request.phpnu�[���PKϤ$Z'_.79?�+http-foundation/Exception/ConflictingHeadersException.phpnu�[���PKϤ$Za7�:��+http-foundation/Exception/SuspiciousOperationException.phpnu�[���PKϤ$Z���+2�+http-foundation/Exception/JsonException.phpnu�[���PKϤ$Z"37��7��+http-foundation/Exception/RequestExceptionInterface.phpnu�[���PKϤ$Zk&�gKK6��+http-foundation/Exception/SessionNotFoundException.phpnu�[���PKϤ$Z,l���1��+http-foundation/Exception/BadRequestException.phpnu�[���PKϤ$Z��F��;�;��+http-foundation/CHANGELOG.mdnu�[���PKϤ$Z�7�0$�,http-foundation/RedirectResponse.phpnu�[���PKϤ$Z}��
77 I,http-foundation/AcceptHeader.phpnu�[���PKϤ$Z�
��))�-,http-foundation/LICENSEnu�[���PKϤ$Z�`!-�� @2,http-foundation/JsonResponse.phpnu�[���PKϤ$Z�)
NN 5P,http-foundation/RequestStack.phpnu�[���PKϤ$Z�ǫ|JJ,�\,http-foundation/ExpressionRequestMatcher.phpnu�[���PKϤ$ZXpa�

yb,http-foundation/HeaderBag.phpnu�[���PKϤ$Z3	��,polyfill-php80/README.mdnu�[���PKϤ$Zy4%336"�,polyfill-php80/Resources/stubs/UnhandledMatchError.phpnu�[���PKϤ$Z��7�hh-��,polyfill-php80/Resources/stubs/Stringable.phpnu�[���PKϤ$Z���***-��,polyfill-php80/Resources/stubs/ValueError.phpnu�[���PKϤ$Z��5-
-
�,polyfill-php80/Php80.phpnu�[���PKϤ$Zu�^"��|�,polyfill-php80/bootstrap.phpnu�[���PKϤ$ZLO!
$$��,polyfill-php80/LICENSEnu�[���PKϤ$Z |��$�,finder/Comparator/DateComparator.phpnu�[���PKϤ$Z�3�#
#
&�,finder/Comparator/NumberComparator.phpnu�[���PKϤ$Zu���}} d�,finder/Comparator/Comparator.phpnu�[���PKϤ$Z��qq1�,finder/Adapter/PhpAdapter.phpnu�[���PKϤ$ZmT�A��#�,finder/Adapter/AdapterInterface.phpnu�[���PKϤ$Z�f!���!�,finder/Adapter/GnuFindAdapter.phpnu�[���PKϤ$ZO��H��!J�,finder/Adapter/BsdFindAdapter.phpnu�[���PKϤ$Z*�+�*�*&��,finder/Adapter/AbstractFindAdapter.phpnu�[���PKϤ$Z�����"_-finder/Adapter/AbstractAdapter.phpnu�[���PKϤ$ZW�W-�	�	.s$-finder/Tests/Comparator/DateComparatorTest.phpnu�[���PKϤ$ZaU�HH0T.-finder/Tests/Comparator/NumberComparatorTest.phpnu�[���PKϤ$Z��Ŗ�*�<-finder/Tests/Comparator/ComparatorTest.phpnu�[���PKϤ$Z0�B���"�D-finder/Tests/Shell/CommandTest.phpnu�[���PKϤ$Z-��u8U-finder/Tests/Iterator/RecursiveDirectoryIteratorTest.phpnu�[���PKϤ$Zg��5�[-finder/Tests/Iterator/SizeRangeFilterIteratorTest.phpnu�[���PKϤ$Z%s�uf
f
*b-finder/Tests/Iterator/IteratorTestCase.phpnu�[���PKϤ$ZYuG
vv.�o-finder/Tests/Iterator/SortableIteratorTest.phpnu�[���PKϤ$Z��j7��2��-finder/Tests/Iterator/CustomFilterIteratorTest.phpnu�[���PKϤ$Z3HUU,�-finder/Tests/Iterator/FilterIteratorTest.phpnu�[���PKϤ$Z����gg4��-finder/Tests/Iterator/FileTypeFilterIteratorTest.phpnu�[���PKϤ$Z�b�m
m
)_�-finder/Tests/Iterator/MockSplFileInfo.phpnu�[���PKϤ$Z�c�Ŕ�<%�-finder/Tests/Iterator/ExcludeDirectoryFilterIteratorTest.phpnu�[���PKϤ$Zd����8%�-finder/Tests/Iterator/MultiplePcreFilterIteratorTest.phpnu�[���PKϤ$ZE�>>/��-finder/Tests/Iterator/FilePathsIteratorTest.phpnu�[���PKϤ$Z��]ss6$�-finder/Tests/Iterator/DepthRangeFilterIteratorTest.phpnu�[���PKϤ$Z�7���4��-finder/Tests/Iterator/FilenameFilterIteratorTest.phpnu�[���PKϤ$Z�S�"Y�-finder/Tests/Iterator/Iterator.phpnu�[���PKϤ$Z��v�r
r
7��-finder/Tests/Iterator/FilecontentFilterIteratorTest.phpnu�[���PKϤ$Z`"����0��-finder/Tests/Iterator/PathFilterIteratorTest.phpnu�[���PKϤ$Z�y^	��.��-finder/Tests/Iterator/RealIteratorTestCase.phpnu�[���PKϤ$Z�'�cnn5�-finder/Tests/Iterator/DateRangeFilterIteratorTest.phpnu�[���PKϤ$Z�[+((.�.finder/Tests/Iterator/MockFileListIterator.phpnu�[���PKϤ$Z�h{��*.finder/Tests/Expression/ExpressionTest.phpnu�[���PKϤ$Z��u���%".finder/Tests/Expression/RegexTest.phpnu�[���PKϤ$Z����$-.finder/Tests/Expression/GlobTest.phpnu�[���PKϤ$Z��55".finder/Tests/Fixtures/lorem.txtnu�[���PKϤ$Z1�".finder/Tests/Fixtures/r+e.gex[c]a(r)s/dir/bar.datnu�[���PKϤ$Z(�".finder/Tests/Fixtures/with space/foo.txtnu�[���PKϤ$Z'���))K#.finder/Tests/Fixtures/ipsum.txtnu�[���PKϤ$Zo�5|�#.finder/Tests/Fixtures/dolor.txtnu�[���PKϤ$Z/$.finder/Tests/Fixtures/A/a.datnu�[���PKϤ$Z |$.finder/Tests/Fixtures/A/B/ab.datnu�[���PKϤ$Z#�$.finder/Tests/Fixtures/A/B/C/abc.datnu�[���PKϤ$Z%.finder/Tests/Fixtures/one/anu�[���PKϤ$Z"j%.finder/Tests/Fixtures/one/b/d.neonnu�[���PKϤ$Z"�%.finder/Tests/Fixtures/one/b/c.neonnu�[���PKϤ$Z*&.finder/Tests/Fixtures/copy/A/B/ab.dat.copynu�[���PKϤ$Z-h&.finder/Tests/Fixtures/copy/A/B/C/abc.dat.copynu�[���PKϤ$Z'�&.finder/Tests/Fixtures/copy/A/a.dat.copynu�[���PKϤ$Z`�2��)'.finder/Tests/FakeAdapter/NamedAdapter.phpnu�[���PKϤ$Z/��00/O+.finder/Tests/FakeAdapter/UnsupportedAdapter.phpnu�[���PKϤ$Z��mm+�..finder/Tests/FakeAdapter/FailingAdapter.phpnu�[���PKϤ$ZI����)�2.finder/Tests/FakeAdapter/DummyAdapter.phpnu�[���PKϤ$Z�; ���6.finder/Tests/BsdFinderTest.phpnu�[���PKϤ$Zn��=AA0:.finder/Tests/PhpFinderTest.phpnu�[���PKϤ$ZIPP�|m|m�@.finder/Tests/FinderTest.phpnu�[���PKϤ$Z��2�����.finder/Tests/GnuFinderTest.phpnu�[���PKϤ$Z������˱.finder/Tests/GlobTest.phpnu�[���PKϤ$Z���5KK�.finder/Shell/Shell.phpnu�[���PKϤ$Z
�Q+ss{�.finder/Shell/Command.phpnu�[���PKϤ$Z�Z����&6�.finder/Iterator/PathFilterIterator.phpnu�[���PKϤ$ZOI{���.[�.finder/Iterator/RecursiveDirectoryIterator.phpnu�[���PKϤ$Z�?�nn*|�.finder/Iterator/FileTypeFilterIterator.phpnu�[���PKϤ$Z�dٝ�$D�.finder/Iterator/SortableIterator.phpnu�[���PKϤ$Z���PP%5/finder/Iterator/FilePathsIterator.phpnu�[���PKϤ$Z���g��.�/finder/Iterator/MultiplePcreFilterIterator.phpnu�[���PKϤ$Z�ّ�� �/finder/Iterator/LazyIterator.phpnu�[���PKϤ$ZrpF7��+�/finder/Iterator/DateRangeFilterIterator.phpnu�[���PKϤ$ZN��-��*�#/finder/Iterator/FilenameFilterIterator.phpnu�[���PKϤ$Z�\X2
2
2)/finder/Iterator/ExcludeDirectoryFilterIterator.phpnu�[���PKϤ$Z#���,�3/finder/Iterator/DepthRangeFilterIterator.phpnu�[���PKϤ$Z�y����(�8/finder/Iterator/CustomFilterIterator.phpnu�[���PKϤ$Z����-7?/finder/Iterator/FilecontentFilterIterator.phpnu�[���PKϤ$ZP-����+^E/finder/Iterator/SizeRangeFilterIterator.phpnu�[���PKϤ$Z�A�;��"YK/finder/Iterator/FilterIterator.phpnu�[���PKϤ$Zh�N֋
�
>R/finder/Gitignore.phpnu�[���PKϤ$ZU�=O&Y&Y
]/finder/Finder.phpnu�[���PKϤ$Z�FHt�/finder/Expression/Regex.phpnu�[���PKϤ$Zv�V���$>�/finder/Expression/ValueInterface.phpnu�[���PKϤ$Z^�bDDl�/finder/Expression/Glob.phpnu�[���PKϤ$Z�\Aݯ
�
 ��/finder/Expression/Expression.phpnu�[���PKϤ$Z�C����/finder/README.mdnu�[���PKϤ$Z�b�(�/finder/SplFileInfo.phpnu�[���PKϤ$Z�RI��/��/finder/Exception/DirectoryNotFoundException.phpnu�[���PKϤ$Z|^�KK,��/finder/Exception/AdapterFailureException.phpnu�[���PKϤ$Z�7��'-�/finder/Exception/ExceptionInterface.phpnu�[���PKϤ$Zc
��rr2s�/finder/Exception/OperationNotPermitedException.phpnu�[���PKϤ$Z~�1G0finder/Exception/ShellCommandFailureException.phpnu�[���PKϤ$Z�cWޫ�*�0finder/Exception/AccessDeniedException.phpnu�[���PKϤ$Z�s1ɩ��0finder/CHANGELOG.mdnu�[���PKϤ$Z�t��$$�0finder/Glob.phpnu�[���PKϤ$Z�
��))0finder/LICENSEnu�[���PKϤ$Z��SHttk"0polyfill-mbstring/README.mdnu�[���PKϤ$ZZ����_�_1*$0polyfill-mbstring/Resources/unidata/lowerCase.phpnu�[���PKϤ$Z�S��`�`1d�0polyfill-mbstring/Resources/unidata/upperCase.phpnu�[���PKϤ$Z>|zK997��0polyfill-mbstring/Resources/unidata/titleCaseRegexp.phpnu�[���PKϤ$Z)~�ί�W�0polyfill-mbstring/bootstrap.phpnu�[���PKϤ$Z�\�))U1polyfill-mbstring/LICENSEnu�[���PKϤ$Z��'�m�m�1polyfill-mbstring/Mbstring.phpnu�[���PKϤ$Z$�!mm�1cache/Adapter/Psr16Adapter.phpnu�[���PKϤ$Zh5�)*��1cache/Adapter/TagAwareAdapterInterface.phpnu�[���PKϤ$Z'�.1.1!,�1cache/Adapter/PhpArrayAdapter.phpnu�[���PKϤ$Z�@2d

!��1cache/Adapter/DoctrineAdapter.phpnu�[���PKϤ$Z�����"�1cache/Adapter/AdapterInterface.phpnu�[���PKϤ$Z_���b+b+@�1cache/Adapter/ArrayAdapter.phpnu�[���PKϤ$ZY� ��+�2cache/Adapter/FilesystemTagAwareAdapter.phpnu�[���PKϤ$Zd���#�2cache/Adapter/FilesystemAdapter.phpnu�[���PKϤ$Z6�t�0�0)�#2cache/Adapter/AbstractTagAwareAdapter.phpnu�[���PKϤ$Z�/�r r /U2cache/Adapter/ProxyAdapter.phpnu�[���PKϤ$Z��,,,,&�u2cache/Adapter/RedisTagAwareAdapter.phpnu�[���PKϤ$Z����"q�2cache/Adapter/TraceableAdapter.phpnu�[���PKϤ$Zc~�ʽ2cache/Adapter/RedisAdapter.phpnu�[���PKϤ$Z���@(�2cache/Adapter/CouchbaseBucketAdapter.phpnu�[���PKϤ$Z��:�5�5"��2cache/Adapter/MemcachedAdapter.phpnu�[���PKϤ$ZiTď�"�"�3cache/Adapter/ChainAdapter.phpnu�[���PKϤ$Z�:v����93cache/Adapter/ApcuAdapter.phpnu�[���PKϤ$Z�)瞞�*�F3cache/Adapter/TraceableTagAwareAdapter.phpnu�[���PKϤ$Z*��--!�J3cache/Adapter/TagAwareAdapter.phpnu�[���PKϤ$Z�2�
�
x3cache/Adapter/NullAdapter.phpnu�[���PKϤ$ZH���0V0V�3cache/Adapter/PdoAdapter.phpnu�[���PKϤ$Z��I((!��3cache/Adapter/PhpFilesAdapter.phpnu�[���PKϤ$Z|�����!�4cache/Adapter/AbstractAdapter.phpnu�[���PKϤ$Z�3Y���!4cache/PruneableInterface.phpnu�[���PKϤ$Z:j[���$4cache/CacheItem.phpnu�[���PKϤ$Z�i����94cache/ResettableInterface.phpnu�[���PKϤ$ZRL$���;4cache/README.mdnu�[���PKϤ$Z^w�S S �>4cache/Psr16Cache.phpnu�[���PKϤ$Z����_4cache/DoctrineProvider.phpnu�[���PKϤ$Z�����vh4cache/LockRegistry.phpnu�[���PKϤ$Z͔#��0��4cache/DependencyInjection/CacheCollectorPass.phpnu�[���PKϤ$Z/̶�$$+��4cache/DependencyInjection/CachePoolPass.phpnu�[���PKϤ$Zd"�e��1�4cache/DependencyInjection/CachePoolPrunerPass.phpnu�[���PKϤ$Z1���2j�4cache/DependencyInjection/CachePoolClearerPass.phpnu�[���PKϤ$Z��H���"M�4cache/Exception/LogicException.phpnu�[���PKϤ$Z#���,8�4cache/Exception/InvalidArgumentException.phpnu�[���PKϤ$Z򹃏�"i�4cache/Exception/CacheException.phpnu�[���PKϤ$Zc� o��J�4cache/CHANGELOG.mdnu�[���PKϤ$Zt"?))
�4cache/LICENSEnu�[���PKϤ$Z��)33&y�4cache/Traits/FilesystemCommonTrait.phpnu�[���PKϤ$Z�\e..%�4cache/Traits/AbstractAdapterTrait.phpnu�[���PKϤ$Z��W|�2�2X"5cache/Traits/MemcachedTrait.phpnu�[���PKϤ$Z�^�f�� uU5cache/Traits/FilesystemTrait.phpnu�[���PKϤ$Z����
�
{a5cache/Traits/ContractsTrait.phpnu�[���PKϤ$Z���no5cache/Traits/RedisProxy.phpnu�[���PKϤ$Z���-11�v5cache/Traits/ProxyTrait.phpnu�[���PKϤ$ZT%4��"Sz5cache/Traits/RedisClusterProxy.phpnu�[���PKϤ$ZHGJ�RRRRO�5cache/Traits/RedisTrait.phpnu�[���PKϤ$Z'�	���*��5cache/DataCollector/CacheDataCollector.phpnu�[���PKϤ$Z$fş��&�5cache/Marshaller/DeflateMarshaller.phpnu�[���PKϤ$Z��cv
v
&0�5cache/Marshaller/DefaultMarshaller.phpnu�[���PKϤ$ZA�lx##'��5cache/Marshaller/TagAwareMarshaller.phpnu�[���PKϤ$ZF���99(v
6cache/Marshaller/MarshallerInterface.phpnu�[���PKϤ$Z���]	]	%6cache/Marshaller/SodiumMarshaller.phpnu�[���PKϤ$Z&�jC(�6mime/Encoder/Base64MimeHeaderEncoder.phpnu�[���PKϤ$Z�'�!6mime/Encoder/QpContentEncoder.phpnu�[���PKϤ$Z�D���"�%6mime/Encoder/IdnAddressEncoder.phpnu�[���PKϤ$Z͒����(�+6mime/Encoder/ContentEncoderInterface.phpnu�[���PKϤ$Z��`//%�.6mime/Encoder/Base64ContentEncoder.phpnu�[���PKϤ$Z�"�z33$846mime/Encoder/QpMimeHeaderEncoder.phpnu�[���PKϤ$Z�iq
��+�86mime/Encoder/MimeHeaderEncoderInterface.phpnu�[���PKϤ$Z��%��(�:6mime/Encoder/AddressEncoderInterface.phpnu�[���PKϤ$ZƑ}�=6mime/Encoder/Base64Encoder.phpnu�[���PKϤ$Z�{�5BB'EC6mime/Encoder/EightBitContentEncoder.phpnu�[���PKϤ$ZC����!�F6mime/Encoder/EncoderInterface.phpnu�[���PKϤ$Z�����I6mime/Encoder/QpEncoder.phpnu�[���PKϤ$Z����i6mime/Encoder/Rfc2231Encoder.phpnu�[���PKϤ$Z�#��<<o6mime/Message.phpnu�[���PKϤ$Zc:٤55�6mime/MimeTypesInterface.phpnu�[���PKϤ$Z1D����6mime/Crypto/SMime.phpnu�[���PKϤ$Z�U)��
�6mime/Crypto/SMimeEncrypter.phpnu�[���PKϤ$Z��K�
�
��6mime/Crypto/SMimeSigner.phpnu�[���PKϤ$Z�����ʣ6mime/Address.phpnu�[���PKϤ$ZOZ���ֲ6mime/RawMessage.phpnu�[���PKϤ$Z9o��!��6mime/MimeTypeGuesserInterface.phpnu�[���PKϤ$Z��6dd�6mime/MessageConverter.phpnu�[���PKϤ$Z}��T��'��6mime/Test/Constraint/EmailHasHeader.phpnu�[���PKϤ$Zq����.�6mime/Test/Constraint/EmailHtmlBodyContains.phpnu�[���PKϤ$Z]5�5cc-��6mime/Test/Constraint/EmailAddressContains.phpnu�[���PKϤ$Z�єn��.��6mime/Test/Constraint/EmailTextBodyContains.phpnu�[���PKϤ$Z��5#��(��6mime/Test/Constraint/EmailHeaderSame.phpnu�[���PKϤ$ZD`���-��6mime/Test/Constraint/EmailAttachmentCount.phpnu�[���PKϤ$Z�BxH�v�v�6mime/MimeTypes.phpnu�[���PKϤ$Z|�|����q9mime/README.mdnu�[���PKϤ$Z0��M??(�s9mime/Resources/bin/update_mime_types.phpnu�[���PKϤ$Zd�:{����9mime/Part/MessagePart.phpnu�[���PKϤ$ZaT)	)	#��9mime/Part/AbstractMultipartPart.phpnu�[���PKϤ$Z_����
�
9�9mime/Part/SMimePart.phpnu�[���PKϤ$Z��FFW�9mime/Part/TextPart.phpnu�[���PKϤ$Z�����9mime/Part/AbstractPart.phpnu�[���PKϤ$ZI�
���9mime/Part/DataPart.phpnu�[���PKϤ$Z��S�'''��9mime/Part/Multipart/AlternativePart.phpnu�[���PKϤ$Z'�?!{�9mime/Part/Multipart/MixedPart.phpnu�[���PKϤ$Z;��c��"��9mime/Part/Multipart/DigestPart.phpnu�[���PKϤ$Zz�~�kk#��9mime/Part/Multipart/RelatedPart.phpnu�[���PKϤ$Z94�B�
�
$��9mime/Part/Multipart/FormDataPart.phpnu�[���PKϤ$Z�@K#_(_(��9mime/Header/AbstractHeader.phpnu�[���PKϤ$Z.6�!<<#�:mime/Header/ParameterizedHeader.phpnu�[���PKϤ$ZK��1<	<	$9):mime/Header/IdentificationHeader.phpnu�[���PKϤ$Z��{���2:mime/Header/DateHeader.phpnu�[���PKϤ$Z6CzCC!�8:mime/Header/MailboxListHeader.phpnu�[���PKϤ$ZX��"�E:mime/Header/UnstructuredHeader.phpnu�[���PKϤ$ZysK����J:mime/Header/PathHeader.phpnu�[���PKϤ$Z�fhw���O:mime/Header/MailboxHeader.phpnu�[���PKϤ$ZA�$���W:mime/Header/Headers.phpnu�[���PKϤ$Z8�|���v:mime/Header/HeaderInterface.phpnu�[���PKϤ$Zl�h�6%6%�{:mime/CharacterStream.phpnu�[���PKϤ$Z�'��3}�:mime/DependencyInjection/AddMimeTypeGuesserPass.phpnu�[���PKϤ$Z�ӆ)��r�:mime/BodyRendererInterface.phpnu�[���PKϤ$Z�5AVV b�:mime/FileinfoMimeTypeGuesser.phpnu�[���PKϤ$Zk��H��!�:mime/Exception/LogicException.phpnu�[���PKϤ$Z��Е�*��:mime/Exception/AddressEncoderException.phpnu�[���PKϤ$Z�Fz��)�:mime/Exception/RfcComplianceException.phpnu�[���PKϤ$Z���{��%��:mime/Exception/ExceptionInterface.phpnu�[���PKϤ$Z�'���+ָ:mime/Exception/InvalidArgumentException.phpnu�[���PKϤ$Zr)�#�:mime/Exception/RuntimeException.phpnu�[���PKϤ$Z��\\�:mime/CHANGELOG.mdnu�[���PKϤ$Z���))�:mime/LICENSEnu�[���PKϤ$Z��
�:�:��:mime/Email.phpnu�[���PKϤ$Z,GiJ�	�	"��:mime/FileBinaryMimeTypeGuesser.phpnu�[���PKϤ$Z~6�~~�;console/ConsoleEvents.phpnu�[���PKϤ$Z�x0mBB*�;console/Tests/Tester/CommandTesterTest.phpnu�[���PKϤ$ZQ��d	d	.D;console/Tests/Tester/ApplicationTesterTest.phpnu�[���PKϤ$Z���66.&;console/Tests/Descriptor/XmlDescriptorTest.phpnu�[���PKϤ$Z%�%H/�(;console/Tests/Descriptor/JsonDescriptorTest.phpnu�[���PKϤ$Z�����,	-;console/Tests/Descriptor/ObjectsProvider.phpnu�[���PKϤ$ZK� 99/D:;console/Tests/Descriptor/TextDescriptorTest.phpnu�[���PKϤ$Z1H�DDD3�<;console/Tests/Descriptor/MarkdownDescriptorTest.phpnu�[���PKϤ$Z�aV���3�?;console/Tests/Descriptor/AbstractDescriptorTest.phpnu�[���PKϤ$Zb?�}��(�N;console/Tests/Style/SymfonyStyleTest.phpnu�[���PKϤ$Z]HY�����!�[;console/Tests/ApplicationTest.phpnu�[���PKϤ$Z�q��55)�%<console/Tests/Command/HelpCommandTest.phpnu�[���PKϤ$Z[�qf)34<console/Tests/Command/ListCommandTest.phpnu�[���PKϤ$Z�
�5�@�@%�D<console/Tests/Command/CommandTest.phpnu�[���PKϤ$Z��[���,u�<console/Tests/Fixtures/input_definition_2.mdnu�[���PKϤ$Z��I��*U�<console/Tests/Fixtures/input_option_3.jsonnu�[���PKϤ$Z a���*K�<console/Tests/Fixtures/input_option_4.jsonnu�[���PKϤ$Z6cp��%?�<console/Tests/Fixtures/command_1.jsonnu�[���PKϤ$ZD
0@��)P�<console/Tests/Fixtures/command_astext.txtnu�[���PKϤ$Z;�e^DD#x�<console/Tests/Fixtures/command_2.mdnu�[���PKϤ$Z�e�d��&�<console/Tests/Fixtures/Foo4Command.phpnu�[���PKϤ$Z��tt*�<console/Tests/Fixtures/input_argument_1.mdnu�[���PKϤ$Z�|�MCC(�<console/Tests/Fixtures/application_2.txtnu�[���PKϤ$Z��c��(��<console/Tests/Fixtures/input_option_3.mdnu�[���PKϤ$Z�v�--+��<console/Tests/Fixtures/application_run2.txtnu�[���PKϤ$Z���0AA7�<console/Tests/Fixtures/application_renderexception2.txtnu�[���PKϤ$Z�hqq)��<console/Tests/Fixtures/input_option_2.txtnu�[���PKϤ$Z*�q��.��<console/Tests/Fixtures/input_definition_3.jsonnu�[���PKϤ$Z3�P���-��<console/Tests/Fixtures/input_definition_2.xmlnu�[���PKϤ$Z�n<m;;-�<console/Tests/Fixtures/input_definition_2.txtnu�[���PKϤ$Z���33+~�<console/Tests/Fixtures/input_argument_2.txtnu�[���PKϤ$Z[�p��&�<console/Tests/Fixtures/Foo6Command.phpnu�[���PKϤ$Z�R�;;)7�<console/Tests/Fixtures/application_2.jsonnu�[���PKϤ$Z<|�4UU&˾<console/Tests/Fixtures/Foo1Command.phpnu�[���PKϤ$Zo��r��+v�<console/Tests/Fixtures/application_run3.txtnu�[���PKϤ$Z%��6XX$��<console/Tests/Fixtures/command_2.txtnu�[���PKϤ$Z8�UT

+4�<console/Tests/Fixtures/application_run4.txtnu�[���PKϤ$ZW��،�*��<console/Tests/Fixtures/input_argument_3.mdnu�[���PKϤ$Z��X��*��<console/Tests/Fixtures/input_option_1.jsonnu�[���PKϤ$Z�: 8��+i�<console/Tests/Fixtures/input_argument_3.xmlnu�[���PKϤ$Z1"8MM1��<console/Tests/Fixtures/DescriptorApplication2.phpnu�[���PKϤ$Z8Ǡ7T�<console/Tests/Fixtures/application_renderexception1.txtnu�[���PKϤ$Z�v��(��<console/Tests/Fixtures/command_asxml.txtnu�[���PKϤ$Z�_�n��+��<console/Tests/Fixtures/input_argument_1.xmlnu�[���PKϤ$Z�eo�&��<console/Tests/Fixtures/DummyOutput.phpnu�[���PKϤ$Z�|5!!)_�<console/Tests/Fixtures/input_option_1.txtnu�[���PKϤ$Z۴�2��*��<console/Tests/Fixtures/input_option_2.jsonnu�[���PKϤ$Z�|��?��<console/Tests/Fixtures/Style/SymfonyStyle/command/command_4.phpnu�[���PKϤ$Z�z�RR?�<console/Tests/Fixtures/Style/SymfonyStyle/command/command_6.phpnu�[���PKϤ$Z��~O��@��<console/Tests/Fixtures/Style/SymfonyStyle/command/command_11.phpnu�[���PKϤ$Z�ժ��?��<console/Tests/Fixtures/Style/SymfonyStyle/command/command_0.phpnu�[���PKϤ$Z]�a6aa?�<console/Tests/Fixtures/Style/SymfonyStyle/command/command_2.phpnu�[���PKϤ$Z�3-���?��<console/Tests/Fixtures/Style/SymfonyStyle/command/command_1.phpnu�[���PKϤ$Z������@F�<console/Tests/Fixtures/Style/SymfonyStyle/command/command_10.phpnu�[���PKϤ$Z�$��?��<console/Tests/Fixtures/Style/SymfonyStyle/command/command_9.phpnu�[���PKϤ$Z_����?
�<console/Tests/Fixtures/Style/SymfonyStyle/command/command_3.phpnu�[���PKϤ$ZҜӤpp?>�<console/Tests/Fixtures/Style/SymfonyStyle/command/command_8.phpnu�[���PKϤ$Z��T��?�<console/Tests/Fixtures/Style/SymfonyStyle/command/command_7.phpnu�[���PKϤ$Z��m��?T�<console/Tests/Fixtures/Style/SymfonyStyle/command/command_5.phpnu�[���PKϤ$Z���__>D=console/Tests/Fixtures/Style/SymfonyStyle/output/output_10.txtnu�[���PKϤ$Zsg�DD==console/Tests/Fixtures/Style/SymfonyStyle/output/output_4.txtnu�[���PKϤ$Z3�*N��=�=console/Tests/Fixtures/Style/SymfonyStyle/output/output_6.txtnu�[���PKϤ$Z?�*I��=�=console/Tests/Fixtures/Style/SymfonyStyle/output/output_1.txtnu�[���PKϤ$Z�9����=�	=console/Tests/Fixtures/Style/SymfonyStyle/output/output_8.txtnu�[���PKϤ$Z�t
��> =console/Tests/Fixtures/Style/SymfonyStyle/output/output_11.txtnu�[���PKϤ$Z��'555=t=console/Tests/Fixtures/Style/SymfonyStyle/output/output_3.txtnu�[���PKϤ$Z� �mm==console/Tests/Fixtures/Style/SymfonyStyle/output/output_9.txtnu�[���PKϤ$Z5#%
��=�=console/Tests/Fixtures/Style/SymfonyStyle/output/output_2.txtnu�[���PKϤ$Z��DENN=:=console/Tests/Fixtures/Style/SymfonyStyle/output/output_7.txtnu�[���PKϤ$Z�x
��=�=console/Tests/Fixtures/Style/SymfonyStyle/output/output_5.txtnu�[���PKϤ$Z�':�{{=�=console/Tests/Fixtures/Style/SymfonyStyle/output/output_0.txtnu�[���PKϤ$ZrA�#jj.�=console/Tests/Fixtures/application_astext1.txtnu�[���PKϤ$Zt��$$,�=console/Tests/Fixtures/definition_astext.txtnu�[���PKϤ$Z�����.! =console/Tests/Fixtures/input_definition_2.jsonnu�[���PKϤ$Z-	!=console/Tests/Fixtures/input_definition_1.txtnu�[���PKϤ$Z��ψ��7f!=console/Tests/Fixtures/application_renderexception3.txtnu�[���PKϤ$ZH�VK#K#(_#=console/Tests/Fixtures/application_2.xmlnu�[���PKϤ$Z��϶�CG=console/Tests/Fixtures/application_renderexception_doublewidth2.txtnu�[���PKϤ$Zia����++H=console/Tests/Fixtures/definition_asxml.txtnu�[���PKϤ$Z���(mM=console/Tests/Fixtures/BarBucCommand.phpnu�[���PKϤ$Zlc����(vN=console/Tests/Fixtures/application_1.xmlnu�[���PKϤ$Z��y$$'�a=console/Tests/Fixtures/application_2.mdnu�[���PKϤ$Z�F:c-7~=console/Tests/Fixtures/input_definition_3.xmlnu�[���PKϤ$Z`jn`ccC�=console/Tests/Fixtures/application_renderexception_doublewidth1.txtnu�[���PKϤ$Z,k�=console/Tests/Fixtures/input_definition_1.mdnu�[���PKϤ$Z��l�AA&ǀ=console/Tests/Fixtures/Foo3Command.phpnu�[���PKϤ$Z��G��)^�=console/Tests/Fixtures/input_option_1.xmlnu�[���PKϤ$Zs�,�[[+i�=console/Tests/Fixtures/input_argument_4.txtnu�[���PKϤ$Z��\��#�=console/Tests/Fixtures/command_1.mdnu�[���PKϤ$Zi����)�=console/Tests/Fixtures/input_option_5.xmlnu�[���PKϤ$ZCQu��-C�=console/Tests/Fixtures/input_definition_4.xmlnu�[���PKϤ$Zٙ���'4�=console/Tests/Fixtures/application_1.mdnu�[���PKϤ$Z󚲱}},-�=console/Tests/Fixtures/input_argument_3.jsonnu�[���PKϤ$ZTg�ll$�=console/Tests/Fixtures/command_1.txtnu�[���PKϤ$Z�ơ��)ƚ=console/Tests/Fixtures/application_1.jsonnu�[���PKϤ$Z���oo,�=console/Tests/Fixtures/input_argument_2.jsonnu�[���PKϤ$Z*[Ǿ44,Ѫ=console/Tests/Fixtures/input_definition_4.mdnu�[���PKϤ$ZP����(a�=console/Tests/Fixtures/input_option_4.mdnu�[���PKϤ$ZZ���*k�=console/Tests/Fixtures/input_option_6.jsonnu�[���PKϤ$Z9p��OO$p�=console/Tests/Fixtures/command_1.xmlnu�[���PKϤ$Z�I���)�=console/Tests/Fixtures/input_option_4.xmlnu�[���PKϤ$Z����.>�=console/Tests/Fixtures/input_definition_1.jsonnu�[���PKϤ$Z`]�AA)��=console/Tests/Fixtures/input_option_3.txtnu�[���PKϤ$Zp�����,T�=console/Tests/Fixtures/input_definition_3.mdnu�[���PKϤ$Z�JhMOO)_�=console/Tests/Fixtures/input_option_6.txtnu�[���PKϤ$Z�J�2)�=console/Tests/Fixtures/input_option_2.xmlnu�[���PKϤ$Z1G~"//(d�=console/Tests/Fixtures/FoobarCommand.phpnu�[���PKϤ$Z̳��99+�=console/Tests/Fixtures/application_run1.txtnu�[���PKϤ$Zz�Ռ��*�=console/Tests/Fixtures/input_argument_2.mdnu�[���PKϤ$Z^ſ�._�=console/Tests/Fixtures/application_gethelp.txtnu�[���PKϤ$Z9�*A��&ֻ=console/Tests/Fixtures/TestCommand.phpnu�[���PKϤ$Z�L���*�=console/Tests/Fixtures/input_option_5.jsonnu�[���PKϤ$Z�W�yy)�=console/Tests/Fixtures/input_option_5.txtnu�[���PKϤ$Z��ڭQQ7��=console/Tests/Fixtures/application_renderexception4.txtnu�[���PKϤ$Z�	���&p�=console/Tests/Fixtures/Foo2Command.phpnu�[���PKϤ$Z	�Ӹ�(��=console/Tests/Fixtures/input_option_2.mdnu�[���PKϤ$Z��<]],��=console/Tests/Fixtures/input_argument_1.jsonnu�[���PKϤ$Z��*J��@|�=console/Tests/Fixtures/application_renderexception3decorated.txtnu�[���PKϤ$Z��f���+��=console/Tests/Fixtures/input_argument_2.xmlnu�[���PKϤ$Z��

$��=console/Tests/Fixtures/command_2.xmlnu�[���PKϤ$Z
�h�==-+�=console/Tests/Fixtures/input_definition_3.txtnu�[���PKϤ$Zǰ@���.��=console/Tests/Fixtures/application_astext2.txtnu�[���PKϤ$Z��8Cii3�=console/Tests/Fixtures/FooSubnamespaced1Command.phpnu�[���PKϤ$Zl᯿pp)��=console/Tests/Fixtures/input_option_4.txtnu�[���PKϤ$Z�^t�^^-��=console/Tests/Fixtures/input_definition_1.xmlnu�[���PKϤ$Z�)J��)V�=console/Tests/Fixtures/input_option_6.xmlnu�[���PKϤ$Z�އ-��=console/Tests/Fixtures/input_definition_4.txtnu�[���PKϤ$ZEb��aa+{�=console/Tests/Fixtures/input_argument_3.txtnu�[���PKϤ$Z���5+7�=console/Tests/Fixtures/input_argument_1.txtnu�[���PKϤ$Z�%?���(��=console/Tests/Fixtures/input_option_5.mdnu�[���PKϤ$Z�
c�%��=console/Tests/Fixtures/FooCommand.phpnu�[���PKϤ$Z���$$.�=console/Tests/Fixtures/input_definition_4.jsonnu�[���PKϤ$ZY'�A��-��=console/Tests/Fixtures/DescriptorCommand1.phpnu�[���PKϤ$Z�;hc��+{�=console/Tests/Fixtures/input_argument_4.xmlnu�[���PKϤ$Z�Zjgg3��=console/Tests/Fixtures/FooSubnamespaced2Command.phpnu�[���PKϤ$ZSG�X55%Z�=console/Tests/Fixtures/command_2.jsonnu�[���PKϤ$Z�3�{{,��=console/Tests/Fixtures/input_argument_4.jsonnu�[���PKϤ$Z��XX��)��=console/Tests/Fixtures/input_option_3.xmlnu�[���PKϤ$Z^�p���L��=console/Tests/Fixtures/application_renderexception_doublewidth1decorated.txtnu�[���PKϤ$Z#�U��*�=console/Tests/Fixtures/input_argument_4.mdnu�[���PKϤ$ZAW�\��-��=console/Tests/Fixtures/DescriptorCommand2.phpnu�[���PKϤ$Z�Y-͡�(��=console/Tests/Fixtures/input_option_1.mdnu�[���PKϤ$Z��!��-��=console/Tests/Fixtures/application_asxml2.txtnu�[���PKϤ$Z�-/��(B�=console/Tests/Fixtures/application_1.txtnu�[���PKϤ$Z�/""��&��=console/Tests/Fixtures/Foo5Command.phpnu�[���PKϤ$Z��׊��-o�=console/Tests/Fixtures/application_asxml1.txtnu�[���PKϤ$Z�q+��1�>console/Tests/Fixtures/DescriptorApplication1.phpnu�[���PKϤ$Za=J��(�>console/Tests/Fixtures/input_option_6.mdnu�[���PKϤ$Z�+??*�>console/Tests/Logger/ConsoleLoggerTest.phpnu�[���PKϤ$Z����)F!>console/Tests/Output/StreamOutputTest.phpnu�[���PKϤ$Z;�!��'�(>console/Tests/Output/NullOutputTest.phpnu�[���PKϤ$Z���IPP#�->console/Tests/Output/OutputTest.phpnu�[���PKϤ$Z)3͐cc*�G>console/Tests/Output/ConsoleOutputTest.phpnu�[���PKϤ$Z�BB?##&RK>console/Tests/Input/ArrayInputTest.phpnu�[���PKϤ$Z���ȸ�)�`>console/Tests/Input/InputArgumentTest.phpnu�[���PKϤ$Z�t7��!�q>console/Tests/Input/InputTest.phpnu�[���PKϤ$Zh��oo'̉>console/Tests/Input/StringInputTest.phpnu�[���PKϤ$Z�&;l�I�I+��>console/Tests/Input/InputDefinitionTest.phpnu�[���PKϤ$Z}ܑ�#�#'��>console/Tests/Input/InputOptionTest.phpnu�[���PKϤ$Zźgp;p;%�?console/Tests/Input/ArgvInputTest.phpnu�[���PKϤ$Z�TF�*�*.�G?console/Tests/Helper/LegacyTableHelperTest.phpnu�[���PKϤ$Z���PtFtF+s?console/Tests/Helper/QuestionHelperTest.phpnu�[���PKϤ$Z��J��1Թ?console/Tests/Helper/LegacyProgressHelperTest.phpnu�[���PKϤ$Z���	IZIZ(��?console/Tests/Helper/ProgressBarTest.phpnu�[���PKϤ$Z��F���'�3@console/Tests/Helper/TableStyleTest.phpnu�[���PKϤ$Z���$��*�6@console/Tests/Helper/ProcessHelperTest.phpnu�[���PKϤ$Z�#���#�I@console/Tests/Helper/HelperTest.phpnu�[���PKϤ$Z�APk-k-/�O@console/Tests/Helper/LegacyDialogHelperTest.phpnu�[���PKϤ$ZK�;���.�}@console/Tests/Helper/ProgressIndicatorTest.phpnu�[���PKϤ$Z�I}]  ,ؒ@console/Tests/Helper/FormatterHelperTest.phpnu�[���PKϤ$Z�~�[�["T�@console/Tests/Helper/TableTest.phpnu�[���PKϤ$Z
c�>��&(�@console/Tests/Helper/HelperSetTest.phpnu�[���PKϤ$Z{�D��4IAconsole/Tests/Formatter/OutputFormatterStyleTest.phpnu�[���PKϤ$Z� R�ww95"Aconsole/Tests/Formatter/OutputFormatterStyleStackTest.phpnu�[���PKϤ$Zp�®� � /+Aconsole/Tests/Formatter/OutputFormatterTest.phpnu�[���PKϤ$Z��+,��LAconsole/Shell.phpnu�[���PKϤ$Z�t5N*3fAconsole/Tester/CommandCompletionTester.phpnu�[���PKϤ$Z7)a�:	:	 �lAconsole/Tester/CommandTester.phpnu�[���PKϤ$Zz1�W��vAconsole/Tester/TesterTrait.phpnu�[���PKϤ$Zѧز��1�Aconsole/Tester/Constraint/CommandIsSuccessful.phpnu�[���PKϤ$Z�!t\
\
$�Aconsole/Tester/ApplicationTester.phpnu�[���PKϤ$Z�p������Aconsole/Application.phpnu�[���PKϤ$Z[
�&�&$KBconsole/Descriptor/XmlDescriptor.phpnu�[���PKϤ$Z-����-*rBconsole/Descriptor/ApplicationDescription.phpnu�[���PKϤ$Z�ቜL1L1%n�Bconsole/Descriptor/TextDescriptor.phpnu�[���PKϤ$Z��4{��)�Bconsole/Descriptor/MarkdownDescriptor.phpnu�[���PKϤ$Z�j��%�Bconsole/Descriptor/JsonDescriptor.phpnu�[���PKϤ$Z0�M$--*4�Bconsole/Descriptor/DescriptorInterface.phpnu�[���PKϤ$Z�k%9��!��Bconsole/Descriptor/Descriptor.phpnu�[���PKϤ$Z#���
 
 &��Bconsole/Completion/CompletionInput.phpnu�[���PKϤ$Zb�ۋ��!�Cconsole/Completion/Suggestion.phpnu�[���PKϤ$Z��(NN,�Cconsole/Completion/CompletionSuggestions.phpnu�[���PKϤ$Z3��O��7� Cconsole/Completion/Output/CompletionOutputInterface.phpnu�[���PKϤ$Z�S���2�#Cconsole/Completion/Output/BashCompletionOutput.phpnu�[���PKϤ$Zv�.�11)�'Cconsole/SignalRegistry/SignalRegistry.phpnu�[���PKϤ$Z?u��)�.Cconsole/Question/ConfirmationQuestion.phpnu�[���PKϤ$ZM?|dWW�4Cconsole/Question/Question.phpnu�[���PKϤ$Z����#�PCconsole/Question/ChoiceQuestion.phpnu�[���PKϤ$Zі�""�dCconsole/Cursor.phpnu�[���PKϤ$Z�"l??#%uCconsole/CI/GithubActionReporter.phpnu�[���PKϤ$Z��������Cconsole/Style/OutputStyle.phpnu�[���PKϤ$Z���)M
M
 �Cconsole/Style/StyleInterface.phpnu�[���PKϤ$Z��ͨ 9 9��Cconsole/Style/SymfonyStyle.phpnu�[���PKϤ$Z\q%;'
�Cconsole/EventListener/ErrorListener.phpnu�[���PKϤ$Z*<�!��g�Cconsole/Color.phpnu�[���PKϤ$Z��0w��0��Cconsole/CommandLoader/ContainerCommandLoader.phpnu�[���PKϤ$Z=H��EE.�Cconsole/CommandLoader/FactoryCommandLoader.phpnu�[���PKϤ$Z��d5MM0u�Cconsole/CommandLoader/CommandLoaderInterface.phpnu�[���PKϤ$ZZ$FBB"Dconsole/Command/ListCommand.phpnu�[���PKϤ$Z���n!n!#�
Dconsole/Command/CompleteCommand.phpnu�[���PKϤ$Z��͚((t/Dconsole/Command/HelpCommand.phpnu�[���PKϤ$ZGe�M��.�;Dconsole/Command/SignalableCommandInterface.phpnu�[���PKϤ$Z�?���!�>Dconsole/Command/LockableTrait.phpnu�[���PKϤ$Z�:���)�EDconsole/Command/DumpCompletionCommand.phpnu�[���PKϤ$Z�?��		#XDconsole/Command/LazyCommand.phpnu�[���PKϤ$Zڽ�WPP{mDconsole/Command/Command.phpnu�[���PKϤ$Z�=NP��ֽDconsole/README.mdnu�[���PKϤ$Z���v$$%��Dconsole/Resources/bin/hiddeninput.exenu�[���PKϤ$Z�bm
X
X
!<�Dconsole/Resources/completion.bashnu�[���PKϤ$Z䪴�""5��Dconsole/DependencyInjection/AddConsoleCommandPass.phpnu�[���PKϤ$ZU���� l	Econsole/Logger/ConsoleLogger.phpnu�[���PKϤ$Z֚�]]�Econsole/Attribute/AsCommand.phpnu�[���PKϤ$Z�t����$6Econsole/SingleCommandApplication.phpnu�[���PKϤ$ZSML���$w%Econsole/Exception/LogicException.phpnu�[���PKϤ$ZBL�H��0u'Econsole/Exception/NamespaceNotFoundException.phpnu�[���PKϤ$ZQ�g;��+�)Econsole/Exception/MissingInputException.phpnu�[���PKϤ$Z�l��(�+Econsole/Exception/ExceptionInterface.phpnu�[���PKϤ$Z����.�-Econsole/Exception/CommandNotFoundException.phpnu�[���PKϤ$Z�u i��.3Econsole/Exception/InvalidArgumentException.phpnu�[���PKϤ$Z�;��,25Econsole/Exception/InvalidOptionException.phpnu�[���PKϤ$Z�*b��&�7Econsole/Exception/RuntimeException.phpnu�[���PKϤ$Z�P��� � �9Econsole/CHANGELOG.mdnu�[���PKϤ$Z���		�ZEconsole/Output/NullOutput.phpnu�[���PKϤ$Z_�  )!dEconsole/Output/ConsoleOutputInterface.phpnu�[���PKϤ$Z��66 �gEconsole/Output/ConsoleOutput.phpnu�[���PKϤ$Z�$?.�
�
 {Econsole/Output/StreamOutput.phpnu�[���PKϤ$ZBE$�UU!1�Econsole/Output/BufferedOutput.phpnu�[���PKϤ$Z���mWW'׌Econsole/Output/ConsoleSectionOutput.phpnu�[���PKϤ$Z�<�);;&��Econsole/Output/TrimmedBufferOutput.phpnu�[���PKϤ$Z��t�\\"�Econsole/Output/OutputInterface.phpnu�[���PKϤ$Z1���==įEconsole/Output/Output.phpnu�[���PKϤ$Za�x))J�Econsole/LICENSEnu�[���PKϤ$Z� '�::%��Econsole/Input/InputAwareInterface.phpnu�[���PKϤ$Z�.�'��A�Econsole/Input/ArrayInput.phpnu�[���PKϤ$ZK�~U}0}0�Econsole/Input/ArgvInput.phpnu�[���PKϤ$Z���Fconsole/Input/Input.phpnu�[���PKϤ$Z���.�.!8%Fconsole/Input/InputDefinition.phpnu�[���PKϤ$Z���U
U
)TFconsole/Input/InputArgument.phpnu�[���PKϤ$ZT�UU�aFconsole/Input/InputOption.phpnu�[���PKϤ$ZH�?�
�
o|Fconsole/Input/StringInput.phpnu�[���PKϤ$Z���ii*?�Fconsole/Input/StreamableInputInterface.phpnu�[���PKϤ$Z�Ӿ}mm �Fconsole/Input/InputInterface.phpnu�[���PKϤ$ZF�(rr��Fconsole/Terminal.phpnu�[���PKϤ$Z	���44$u�Fconsole/Helper/ProgressIndicator.phpnu�[���PKϤ$Z��uu ��Fconsole/Helper/ProcessHelper.phpnu�[���PKϤ$Z@���

��Fconsole/Helper/HelperSet.phpnu�[���PKϤ$ZWH��s�s$�Fconsole/Helper/Table.phpnu�[���PKϤ$Z-��L�L!b_Gconsole/Helper/QuestionHelper.phpnu�[���PKϤ$Z���o�1�1X�Gconsole/Helper/TableStyle.phpnu�[���PKϤ$Z��a�EE,�Gconsole/Helper/TableRows.phpnu�[���PKϤ$Z+'�f����Gconsole/Helper/Dumper.phpnu�[���PKϤ$Z-7����!��Gconsole/Helper/TableCellStyle.phpnu�[���PKϤ$Z�Nc\II �Gconsole/Helper/ProgressBar.phpnu�[���PKϤ$Z����#o;Hconsole/Helper/InputAwareHelper.phpnu�[���PKϤ$Z�3T��(�>Hconsole/Helper/SymfonyQuestionHelper.phpnu�[���PKϤ$Zd��8MM"�KHconsole/Helper/HelperInterface.phpnu�[���PKϤ$Z���sOHconsole/Helper/Helper.phpnu�[���PKϤ$Z&��
!}cHconsole/Helper/TableSeparator.phpnu�[���PKϤ$Z��.�eHconsole/Helper/TableCell.phpnu�[���PKϤ$ZG�(�J
J
'>mHconsole/Helper/DebugFormatterHelper.phpnu�[���PKϤ$Z��sRo1o1!�zHconsole/Helper/ProgressHelper.phpnu�[���PKϤ$Zu�wYX	X	"��Hconsole/Helper/FormatterHelper.phpnu�[���PKϤ$Z�3�ooI�Hconsole/Helper/TableHelper.phpnu�[���PKϤ$ZX^}߼	�	#�Hconsole/Helper/DescriptorHelper.phpnu�[���PKϤ$Z����D�D�Hconsole/Helper/DialogHelper.phpnu�[���PKϤ$Z�*���	�	/+Iconsole/Formatter/OutputFormatterStyleStack.phpnu�[���PKϤ$Z{=X���.�(Iconsole/Formatter/NullOutputFormatterStyle.phpnu�[���PKϤ$Z}z���7�-Iconsole/Formatter/WrappableOutputFormatterInterface.phpnu�[���PKϤ$ZpbdPP*�0Iconsole/Formatter/OutputFormatterStyle.phpnu�[���PKϤ$Z ��``%F<Iconsole/Formatter/OutputFormatter.phpnu�[���PKϤ$Z?�V�77.�[Iconsole/Formatter/OutputFormatterInterface.phpnu�[���PKϤ$Zs���ZZ3�aIconsole/Formatter/OutputFormatterStyleInterface.phpnu�[���PKϤ$Z��p�YY)MfIconsole/Formatter/NullOutputFormatter.phpnu�[���PKϤ$ZT�����#�kIconsole/Event/ConsoleErrorEvent.phpnu�[���PKϤ$Z���=='+rIconsole/Event/ConsoleExceptionEvent.phpnu�[���PKϤ$Z�q��""'�xIconsole/Event/ConsoleTerminateEvent.phpnu�[���PKϤ$Zb���$8}Iconsole/Event/ConsoleSignalEvent.phpnu�[���PKϤ$Z:�[&tt�Iconsole/Event/ConsoleEvent.phpnu�[���PKϤ$Z����%ކIconsole/Event/ConsoleCommandEvent.phpnu�[���PKϤ$Z���b��Ipolyfill-php54/README.mdnu�[���PKϤ$Z拝�9T�Ipolyfill-php54/Resources/stubs/CallbackFilterIterator.phpnu�[���PKϤ$Z
�(;;:Z�Ipolyfill-php54/Resources/stubs/SessionHandlerInterface.phpnu�[���PKϤ$ZT��--B��Ipolyfill-php54/Resources/stubs/RecursiveCallbackFilterIterator.phpnu�[���PKϤ$Zl�f���Ipolyfill-php54/bootstrap.phpnu�[���PKϤ$Z�*L))�Ipolyfill-php54/LICENSEnu�[���PKϤ$Zۻ_��w�Ipolyfill-php54/Php54.phpnu�[���PKϤ$Z�Q�m9m9-��Itranslation-contracts/Test/TranslatorTest.phpnu�[���PKϤ$Z\�=4�	�	-M�Itranslation-contracts/TranslatorInterface.phpnu�[���PKϤ$Z��.p��/x�Itranslation-contracts/TranslatableInterface.phpnu�[���PKϤ$ZVNK�VV��Itranslation-contracts/README.mdnu�[���PKϤ$Z�����"E�Itranslation-contracts/CHANGELOG.mdnu�[���PKϤ$Z��� � )6�Itranslation-contracts/TranslatorTrait.phpnu�[���PKϤ$Zi8�z)),Jtranslation-contracts/LICENSEnu�[���PKϤ$Z8"=��.�Jtranslation-contracts/LocaleAwareInterface.phpnu�[���PKϤ$Z��3���Jdeprecation-contracts/README.mdnu�[���PKϤ$Zrg����"�#Jdeprecation-contracts/function.phpnu�[���PKϤ$Z�����"�'Jdeprecation-contracts/CHANGELOG.mdnu�[���PKϤ$ZLO!
$$�(Jdeprecation-contracts/LICENSEnu�[���PKϤ$Z��R�	�	G-Jprocess/PhpProcess.phpnu�[���PKϤ$Zf�#�� +7Jprocess/Tests/SignalListener.phpnu�[���PKϤ$Z�y$^��)	9Jprocess/Tests/PhpExecutableFinderTest.phpnu�[���PKϤ$Z��¨��5�AJprocess/Tests/PipeStdinInStdoutStdErrStreamSelect.phpnu�[���PKϤ$ZI+sL��$/IJprocess/Tests/ProcessBuilderTest.phpnu�[���PKϤ$ZS��{��"odJprocess/Tests/ProcessUtilsTest.phpnu�[���PKϤ$Z��f�&�jJprocess/Tests/ExecutableFinderTest.phpnu�[���PKϤ$Z�"+<��yJprocess/Tests/ProcessTest.phpnu�[���PKϤ$Z?9�_%%$r8Kprocess/Tests/NonStopableProcess.phpnu�[���PKϤ$Z�;,�<Kprocess/Tests/ProcessFailedExceptionTest.phpnu�[���PKϤ$Zи ePKprocess/Tests/PhpProcessTest.phpnu�[���PKϤ$Z`�*����UKprocess/ProcessBuilder.phpnu�[���PKϤ$Z��X

�pKprocess/PhpExecutableFinder.phpnu�[���PKϤ$Z\3$���H{Kprocess/README.mdnu�[���PKϤ$Zkm�:

a}Kprocess/ExecutableFinder.phpnu�[���PKϤ$Z|�%�MM��Kprocess/ProcessUtils.phpnu�[���PKϤ$Z^1�M��U�Kprocess/Process.phpnu�[���PKϤ$Z�����.�_Lprocess/Exception/ProcessSignaledException.phpnu�[���PKϤ$Z��W��$�cLprocess/Exception/LogicException.phpnu�[���PKϤ$Z���+��(�eLprocess/Exception/ExceptionInterface.phpnu�[���PKϤ$ZP��5��,hLprocess/Exception/ProcessFailedException.phpnu�[���PKϤ$Z˅����.�mLprocess/Exception/InvalidArgumentException.phpnu�[���PKϤ$Z{0���.9pLprocess/Exception/ProcessTimedOutException.phpnu�[���PKϤ$Z>H����&$wLprocess/Exception/RuntimeException.phpnu�[���PKϤ$Z(�C��[yLprocess/CHANGELOG.mdnu�[���PKϤ$Z�
��))s�Lprocess/LICENSEnu�[���PKϤ$Z��^#	#	ۍLprocess/InputStream.phpnu�[���PKϤ$Z���� E�Lprocess/Pipes/PipesInterface.phpnu�[���PKϤ$Za�vddm�Lprocess/Pipes/UnixPipes.phpnu�[���PKϤ$Zvg0���Lprocess/Pipes/AbstractPipes.phpnu�[���PKϤ$Z�OA���Lprocess/Pipes/WindowsPipes.phpnu�[���PKϤ$Z��AR��'�Ldependency-injection/TypedReference.phpnu�[���PKϤ$Z��F��5A�Ldependency-injection/ResettableContainerInterface.phpnu�[���PKϤ$Z����(((m�Ldependency-injection/EnvVarProcessor.phpnu�[���PKϤ$Z����6�
Mdependency-injection/Tests/DefinitionDecoratorTest.phpnu�[���PKϤ$Z^'`�5�5-�Mdependency-injection/Tests/DefinitionTest.phpnu�[���PKϤ$Z�!�1��-PMdependency-injection/Tests/CrossCheckTest.phpnu�[���PKϤ$Z��2�{{,\]Mdependency-injection/Tests/ParameterTest.phpnu�[���PKϤ$Za��`�	�	63`Mdependency-injection/Tests/Extension/ExtensionTest.phpnu�[���PKϤ$Z-r�5��7�jMdependency-injection/Tests/Loader/PhpFileLoaderTest.phpnu�[���PKϤ$Z��͐|�|7�oMdependency-injection/Tests/Loader/XmlFileLoaderTest.phpnu�[���PKϤ$ZI����7��Mdependency-injection/Tests/Loader/ClosureLoaderTest.phpnu�[���PKϤ$Zw���E�E8��Mdependency-injection/Tests/Loader/YamlFileLoaderTest.phpnu�[���PKϤ$Z�Op�		9�7Ndependency-injection/Tests/Loader/DirectoryLoaderTest.phpnu�[���PKϤ$Z�ߛHH7DNdependency-injection/Tests/Loader/IniFileLoaderTest.phpnu�[���PKϤ$Z�%���
�
A�LNdependency-injection/Tests/Config/AutowireServiceResourceTest.phpnu�[���PKϤ$Z��=)��3�ZNdependency-injection/Tests/Dumper/XmlDumperTest.phpnu�[���PKϤ$Z�&h��<�<3vNdependency-injection/Tests/Dumper/PhpDumperTest.phpnu�[���PKϤ$Zm@4�
�
8�Ndependency-injection/Tests/Dumper/GraphvizDumperTest.phpnu�[���PKϤ$Z��5N��4��Ndependency-injection/Tests/Dumper/YamlDumperTest.phpnu�[���PKϤ$Z4[�ZWZW8��Ndependency-injection/Tests/Compiler/AutowirePassTest.phpnu�[���PKϤ$Z™H�X
X
G�$Odependency-injection/Tests/Compiler/RemoveUnusedDefinitionsPassTest.phpnu�[���PKϤ$ZfAe��<r2Odependency-injection/Tests/Compiler/OptionalServiceClass.phpnu�[���PKϤ$ZD���Hb4Odependency-injection/Tests/Compiler/InlineServiceDefinitionsPassTest.phpnu�[���PKϤ$Z�D�^��L~POdependency-injection/Tests/Compiler/ResolveParameterPlaceHoldersPassTest.phpnu�[���PKϤ$Z��� ``J�]Odependency-injection/Tests/Compiler/ResolveReferencesToAliasesPassTest.phpnu�[���PKϤ$Z��LK�iOdependency-injection/Tests/Compiler/MergeExtensionConfigurationPassTest.phpnu�[���PKϤ$Z鍁��X)rOdependency-injection/Tests/Compiler/CheckExceptionOnInvalidReferenceBehaviorPassTest.phpnu�[���PKϤ$Z�܀��HezOdependency-injection/Tests/Compiler/ResolveInvalidReferencesPassTest.phpnu�[���PKϤ$Za�l��GȉOdependency-injection/Tests/Compiler/CheckCircularReferencesPassTest.phpnu�[���PKϤ$Z�
�M

G�Odependency-injection/Tests/Compiler/CheckDefinitionValidityPassTest.phpnu�[���PKϤ$ZV�Y���7m�Odependency-injection/Tests/Compiler/IntegrationTest.phpnu�[���PKϤ$Z⬼���A��Odependency-injection/Tests/Compiler/ExtensionCompilerPassTest.phpnu�[���PKϤ$Z_Ix�+�+J��Odependency-injection/Tests/Compiler/ResolveDefinitionTemplatesPassTest.phpnu�[���PKϤ$Z�B��N�Odependency-injection/Tests/Compiler/ReplaceAliasByActualDefinitionPassTest.phpnu�[���PKϤ$ZP��!mmH��Odependency-injection/Tests/Compiler/AnalyzeServiceReferencesPassTest.phpnu�[���PKϤ$Z�ڨ�FePdependency-injection/Tests/Compiler/CheckReferenceValidityPassTest.phpnu�[���PKϤ$Z��@�@�Pdependency-injection/Tests/Compiler/AutoAliasServicePassTest.phpnu�[���PKϤ$Z����@~Pdependency-injection/Tests/Compiler/DecoratorServicePassTest.phpnu�[���PKϤ$Z�١���6.Pdependency-injection/Tests/Fixtures/php/services13.phpnu�[���PKϤ$Zm"!mm6`4Pdependency-injection/Tests/Fixtures/php/services12.phpnu�[���PKϤ$Z�5���53APdependency-injection/Tests/Fixtures/php/services1.phpnu�[���PKϤ$Zp�#���6�DPdependency-injection/Tests/Fixtures/php/services10.phpnu�[���PKϤ$Z7�l�,�,>�QPdependency-injection/Tests/Fixtures/php/services9_compiled.phpnu�[���PKϤ$Z�B�	�7�75�~Pdependency-injection/Tests/Fixtures/php/services9.phpnu�[���PKϤ$Z���//2�Pdependency-injection/Tests/Fixtures/php/simple.phpnu�[���PKϤ$Z�*�E7��Pdependency-injection/Tests/Fixtures/php/services1-1.phpnu�[���PKϤ$Z�BɅ�6.�Pdependency-injection/Tests/Fixtures/php/services19.phpnu�[���PKϤ$Z��666�Pdependency-injection/Tests/Fixtures/php/services24.phpnu�[���PKϤ$Z�\�%��5��Pdependency-injection/Tests/Fixtures/php/services8.phpnu�[���PKϤ$Z�*�f��7��Pdependency-injection/Tests/Fixtures/yaml/services22.ymlnu�[���PKϤ$Z�aV+;��Pdependency-injection/Tests/Fixtures/yaml/bad_parameters.ymlnu�[���PKϤ$Zzb��nn4C�Pdependency-injection/Tests/Fixtures/yaml/badtag1.ymlnu�[���PKϤ$ZZ�\6�Pdependency-injection/Tests/Fixtures/yaml/services6.ymlnu�[���PKϤ$Z�+�4AAF��Pdependency-injection/Tests/Fixtures/yaml/legacy_invalid_definition.ymlnu�[���PKϤ$Z�7{��6K�Pdependency-injection/Tests/Fixtures/yaml/services2.ymlnu�[���PKϤ$Z#�&#6{�Pdependency-injection/Tests/Fixtures/yaml/nonvalid1.ymlnu�[���PKϤ$Z���7��Pdependency-injection/Tests/Fixtures/yaml/services10.ymlnu�[���PKϤ$Z{��_��B��Pdependency-injection/Tests/Fixtures/yaml/tag_name_empty_string.ymlnu�[���PKϤ$Z��MM7��Pdependency-injection/Tests/Fixtures/yaml/services23.ymlnu�[���PKϤ$ZO_Q�7��Pdependency-injection/Tests/Fixtures/yaml/bad_import.ymlnu�[���PKϤ$Z�OOL�Pdependency-injection/Tests/Fixtures/yaml/legacy_invalid_alias_definition.ymlnu�[���PKϤ$Z�l���:��Pdependency-injection/Tests/Fixtures/yaml/bad_decorates.ymlnu�[���PKϤ$Zղ��==7��Pdependency-injection/Tests/Fixtures/yaml/services21.ymlnu�[���PKϤ$Zy��??Aw�Pdependency-injection/Tests/Fixtures/yaml/services4_bad_import.ymlnu�[���PKϤ$Z}�>���4'�Pdependency-injection/Tests/Fixtures/yaml/badtag2.ymlnu�[���PKϤ$Z����GG7�Pdependency-injection/Tests/Fixtures/yaml/services13.ymlnu�[���PKϤ$Z�[�zz7��Pdependency-injection/Tests/Fixtures/yaml/bad_types1.ymlnu�[���PKϤ$ZW�%6��Pdependency-injection/Tests/Fixtures/yaml/nonvalid2.ymlnu�[���PKϤ$Z3�Ĉ8�Pdependency-injection/Tests/Fixtures/yaml/bad_imports.ymlnu�[���PKϤ$Z�|��DD6��Pdependency-injection/Tests/Fixtures/yaml/services3.ymlnu�[���PKϤ$ZV�v�==6;�Pdependency-injection/Tests/Fixtures/yaml/services4.ymlnu�[���PKϤ$ZW:���7��Pdependency-injection/Tests/Fixtures/yaml/services14.ymlnu�[���PKϤ$Z#����6��Pdependency-injection/Tests/Fixtures/yaml/services9.ymlnu�[���PKϤ$ZT4��GG6��Pdependency-injection/Tests/Fixtures/yaml/bad_calls.ymlnu�[���PKϤ$ZJ�Y��7��Pdependency-injection/Tests/Fixtures/yaml/bad_types2.ymlnu�[���PKϤ$Z���{tt4��Pdependency-injection/Tests/Fixtures/yaml/badtag4.ymlnu�[���PKϤ$Z��26X�Pdependency-injection/Tests/Fixtures/yaml/services1.ymlnu�[���PKϤ$Z�*_6��4��Pdependency-injection/Tests/Fixtures/yaml/badtag3.ymlnu�[���PKϤ$Z��TD8�Pdependency-injection/Tests/Fixtures/yaml/bad_service.ymlnu�[���PKϤ$ZFN�9G�Pdependency-injection/Tests/Fixtures/yaml/bad_services.ymlnu�[���PKϤ$Z����6��Pdependency-injection/Tests/Fixtures/yaml/services8.ymlnu�[���PKϤ$Z����''6�Pdependency-injection/Tests/Fixtures/yaml/services7.ymlnu�[���PKϤ$Z�MuA7U�Pdependency-injection/Tests/Fixtures/yaml/services11.ymlnu�[���PKϤ$ZS�,��?�Pdependency-injection/Tests/Fixtures/yaml/tag_name_no_string.ymlnu�[���PKϤ$Z�,p�7�Pdependency-injection/Tests/Fixtures/yaml/bad_format.ymlnu�[���PKϤ$Z�u�xx7E�Pdependency-injection/Tests/Fixtures/yaml/services24.ymlnu�[���PKϤ$Z5l%%7$�Pdependency-injection/Tests/Fixtures/ini/parameters1.ininu�[���PKϤ$Z۴)�++4��Pdependency-injection/Tests/Fixtures/ini/nonvalid.ininu�[���PKϤ$Zs4��''6?�Pdependency-injection/Tests/Fixtures/ini/parameters.ininu�[���PKϤ$Zpu��((7�Pdependency-injection/Tests/Fixtures/ini/parameters2.ininu�[���PKϤ$Z����8[Qdependency-injection/Tests/Fixtures/CustomDefinition.phpnu�[���PKϤ$Z�䪍qq8WQdependency-injection/Tests/Fixtures/includes/classes.phpnu�[���PKϤ$Z��[[H0	Qdependency-injection/Tests/Fixtures/includes/ProjectWithXsdExtension.phpnu�[���PKϤ$Z�J��AQdependency-injection/Tests/Fixtures/includes/ProjectExtension.phpnu�[���PKϤ$ZRK:��CQdependency-injection/Tests/Fixtures/includes/schema/project-1.0.xsdnu�[���PKϤ$Z�mX;2Qdependency-injection/Tests/Fixtures/includes/createphar.phpnu�[���PKϤ$Z6xB ��4�Qdependency-injection/Tests/Fixtures/includes/foo.phpnu�[���PKϤ$ZS�x<�Qdependency-injection/Tests/Fixtures/includes/FooVariadic.phpnu�[���PKϤ$Zv�a���OpQdependency-injection/Tests/Fixtures/includes/ProjectWithXsdExtensionInPhar.pharnu�[���PKϤ$Zv�&��:x!Qdependency-injection/Tests/Fixtures/graphviz/services9.dotnu�[���PKϤ$Z�����;�1Qdependency-injection/Tests/Fixtures/graphviz/services18.dotnu�[���PKϤ$ZŏD�;;;�3Qdependency-injection/Tests/Fixtures/graphviz/services13.dotnu�[���PKϤ$ZՁ1*,,=j6Qdependency-injection/Tests/Fixtures/graphviz/services10-1.dotnu�[���PKϤ$Z��8BB;9Qdependency-injection/Tests/Fixtures/graphviz/services14.dotnu�[���PKϤ$Z&�WW:�:Qdependency-injection/Tests/Fixtures/graphviz/services1.dotnu�[���PKϤ$Z�cw��;q<Qdependency-injection/Tests/Fixtures/graphviz/services17.dotnu�[���PKϤ$Z��33;�>Qdependency-injection/Tests/Fixtures/graphviz/services10.dotnu�[���PKϤ$ZLC8O��5-AQdependency-injection/Tests/Fixtures/xml/services2.xmlnu�[���PKϤ$Z˕n%%4lFQdependency-injection/Tests/Fixtures/xml/nonvalid.xmlnu�[���PKϤ$ZͶZD��?�FQdependency-injection/Tests/Fixtures/xml/tag_with_empty_name.xmlnu�[���PKϤ$Z���5�HQdependency-injection/Tests/Fixtures/xml/services9.xmlnu�[���PKϤ$Z]2�
��?r]Qdependency-injection/Tests/Fixtures/xml/extension2/services.xmlnu�[���PKϤ$Z��Uگ�G�_Qdependency-injection/Tests/Fixtures/xml/with_key_outside_collection.xmlnu�[���PKϤ$Z\����6�aQdependency-injection/Tests/Fixtures/xml/services24.xmlnu�[���PKϤ$Z�Z	[[6dQdependency-injection/Tests/Fixtures/xml/services14.xmlnu�[���PKϤ$Z2�X8��?�gQdependency-injection/Tests/Fixtures/xml/services_deprecated.xmlnu�[���PKϤ$Z*��58jQdependency-injection/Tests/Fixtures/xml/services5.xmlnu�[���PKϤ$Z�![�6�mQdependency-injection/Tests/Fixtures/xml/services10.xmlnu�[���PKϤ$Z���<ii6&pQdependency-injection/Tests/Fixtures/xml/services13.xmlnu�[���PKϤ$Zx'�	117�qQdependency-injection/Tests/Fixtures/xml/withdoctype.xmlnu�[���PKϤ$Zu�

5�rQdependency-injection/Tests/Fixtures/xml/services4.xmlnu�[���PKϤ$Z�e<xx5�tQdependency-injection/Tests/Fixtures/xml/services8.xmlnu�[���PKϤ$Z
�T`��6�xQdependency-injection/Tests/Fixtures/xml/services22.xmlnu�[���PKϤ$Zq����6{Qdependency-injection/Tests/Fixtures/xml/namespaces.xmlnu�[���PKϤ$Z6�S��<N~Qdependency-injection/Tests/Fixtures/xml/tag_without_name.xmlnu�[���PKϤ$Z����6H�Qdependency-injection/Tests/Fixtures/xml/services21.xmlnu�[���PKϤ$Z�}��@ǃQdependency-injection/Tests/Fixtures/xml/extensions/services2.xmlnu�[���PKϤ$ZŃ����@ކQdependency-injection/Tests/Fixtures/xml/extensions/services5.xmlnu�[���PKϤ$Zҗ'y��@<�Qdependency-injection/Tests/Fixtures/xml/extensions/services4.xmlnu�[���PKϤ$Z>U���@i�Qdependency-injection/Tests/Fixtures/xml/extensions/services3.xmlnu�[���PKϤ$Z��	@��Qdependency-injection/Tests/Fixtures/xml/extensions/services7.xmlnu�[���PKϤ$Z�^����@�Qdependency-injection/Tests/Fixtures/xml/extensions/services1.xmlnu�[���PKϤ$Zix�C��@E�Qdependency-injection/Tests/Fixtures/xml/extensions/services6.xmlnu�[���PKϤ$Z��Pgg@��Qdependency-injection/Tests/Fixtures/xml/services4_bad_import.xmlnu�[���PKϤ$Z
��qq6��Qdependency-injection/Tests/Fixtures/xml/services23.xmlnu�[���PKϤ$Z\_���5`�Qdependency-injection/Tests/Fixtures/xml/services3.xmlnu�[���PKϤ$Z�_�+WW5��Qdependency-injection/Tests/Fixtures/xml/services7.xmlnu�[���PKϤ$Z�(]

5`�Qdependency-injection/Tests/Fixtures/xml/services1.xmlnu�[���PKϤ$Z'���+
+
5ҝQdependency-injection/Tests/Fixtures/xml/services6.xmlnu�[���PKϤ$ZV�Y���Kb�Qdependency-injection/Tests/Fixtures/xml/legacy_invalid_alias_definition.xmlnu�[���PKϤ$Z������?ɪQdependency-injection/Tests/Fixtures/xml/extension1/services.xmlnu�[���PKϤ$Z�v��//8�Qdependency-injection/Tests/Fixtures/directory/simple.phpnu�[���PKϤ$Z��}@��Qdependency-injection/Tests/Fixtures/directory/recurse/simple.ymlnu�[���PKϤ$Z>�us@3�Qdependency-injection/Tests/Fixtures/directory/recurse/simple.ininu�[���PKϤ$Z�r;�))?��Qdependency-injection/Tests/Fixtures/directory/import/import.ymlnu�[���PKϤ$ZC�ݲ;;>T�Qdependency-injection/Tests/Fixtures/containers/container10.phpnu�[���PKϤ$Z
�ť��>��Qdependency-injection/Tests/Fixtures/containers/container24.phpnu�[���PKϤ$Z�?���=f�Qdependency-injection/Tests/Fixtures/containers/container8.phpnu�[���PKϤ$Z�]��>e�Qdependency-injection/Tests/Fixtures/containers/container16.phpnu�[���PKϤ$ZBreOO>��Qdependency-injection/Tests/Fixtures/containers/container13.phpnu�[���PKϤ$Z���33>b�Qdependency-injection/Tests/Fixtures/containers/container11.phpnu�[���PKϤ$Z����^^B�Qdependency-injection/Tests/Fixtures/containers/CustomContainer.phpnu�[���PKϤ$Zb���>ӺQdependency-injection/Tests/Fixtures/containers/container15.phpnu�[���PKϤ$Zܓ�> �Qdependency-injection/Tests/Fixtures/containers/container12.phpnu�[���PKϤ$Z�����>��Qdependency-injection/Tests/Fixtures/containers/container19.phpnu�[���PKϤ$Z��g���=��Qdependency-injection/Tests/Fixtures/containers/container9.phpnu�[���PKϤ$Z�cЯ�>�Qdependency-injection/Tests/Fixtures/containers/container17.phpnu�[���PKϤ$Z�"�U"">+�Qdependency-injection/Tests/Fixtures/containers/container21.phpnu�[���PKϤ$Z��i��>��Qdependency-injection/Tests/Fixtures/containers/container14.phpnu�[���PKϤ$Z#�����B��Qdependency-injection/Tests/ParameterBag/FrozenParameterBagTest.phpnu�[���PKϤ$ZVI�<5<5<0�Qdependency-injection/Tests/ParameterBag/ParameterBagTest.phpnu�[���PKϤ$Z�r
8�;�;,�Rdependency-injection/Tests/ContainerTest.phpnu�[���PKϤ$ZpY����A,QRdependency-injection/Tests/LazyProxy/PhpDumper/NullDumperTest.phpnu�[���PKϤ$Z
aȘ��QURdependency-injection/Tests/LazyProxy/Instantiator/RealServiceInstantiatorTest.phpnu�[���PKϤ$Z��KMM,�ZRdependency-injection/Tests/ReferenceTest.phpnu�[���PKϤ$ZZ�H�H�H�34^Rdependency-injection/Tests/ContainerBuilderTest.phpnu�[���PKϤ$Z��W��9�9"��Rdependency-injection/Container.phpnu�[���PKϤ$Z
VjWW,!#Sdependency-injection/ContainerAwareTrait.phpnu�[���PKϤ$Z�����"�%Sdependency-injection/Parameter.phpnu�[���PKϤ$Zpn����!�(Sdependency-injection/Variable.phpnu�[���PKϤ$Z�-3D���+Sdependency-injection/Alias.phpnu�[���PKϤ$ZW}dAA,�>Sdependency-injection/Extension/Extension.phpnu�[���PKϤ$Zk²5�OSdependency-injection/Extension/ExtensionInterface.phpnu�[���PKϤ$Z��H�BBBUSdependency-injection/Extension/ConfigurationExtensionInterface.phpnu�[���PKϤ$Z���<�XSdependency-injection/Extension/PrependExtensionInterface.phpnu�[���PKϤ$Z�&O?""/M[Sdependency-injection/Loader/DirectoryLoader.phpnu�[���PKϤ$Z�Q�]?6?6@�`Sdependency-injection/Loader/schema/dic/services/services-1.0.xsdnu�[���PKϤ$Z�HM"��A}�Sdependency-injection/Loader/Configurator/DefaultsConfigurator.phpnu�[���PKϤ$Z�;��	�	B��Sdependency-injection/Loader/Configurator/PrototypeConfigurator.phpnu�[���PKϤ$Z%�j�DDC�Sdependency-injection/Loader/Configurator/ParametersConfigurator.phpnu�[���PKϤ$Z* ���F��Sdependency-injection/Loader/Configurator/InlineServiceConfigurator.phpnu�[���PKϤ$Z �E��
�
H�Sdependency-injection/Loader/Configurator/AbstractServiceConfigurator.phpnu�[���PKϤ$Z>���>T�Sdependency-injection/Loader/Configurator/AliasConfigurator.phpnu�[���PKϤ$Zω'6��B��Sdependency-injection/Loader/Configurator/Traits/SyntheticTrait.phpnu�[���PKϤ$Z��;�..=��Sdependency-injection/Loader/Configurator/Traits/CallTrait.phpnu�[���PKϤ$Z�s��yy<5�Sdependency-injection/Loader/Configurator/Traits/TagTrait.phpnu�[���PKϤ$Z��5Z��A�Sdependency-injection/Loader/Configurator/Traits/ArgumentTrait.phpnu�[���PKϤ$Z�=r���Ag�Sdependency-injection/Loader/Configurator/Traits/AbstractTrait.phpnu�[���PKϤ$ZJ��''=a�Sdependency-injection/Loader/Configurator/Traits/LazyTrait.phpnu�[���PKϤ$Z�*=��Sdependency-injection/Loader/Configurator/Traits/BindTrait.phpnu�[���PKϤ$Z�MMAe�Sdependency-injection/Loader/Configurator/Traits/DecorateTrait.phpnu�[���PKϤ$Z��[���E#�Sdependency-injection/Loader/Configurator/Traits/ConfiguratorTrait.phpnu�[���PKϤ$Z%0�O��?e�Sdependency-injection/Loader/Configurator/Traits/PublicTrait.phpnu�[���PKϤ$Z�X�;;>b�Sdependency-injection/Loader/Configurator/Traits/ShareTrait.phpnu�[���PKϤ$Z��l��?�Sdependency-injection/Loader/Configurator/Traits/ParentTrait.phpnu�[���PKϤ$Zʊy�<<A*�Sdependency-injection/Loader/Configurator/Traits/AutowireTrait.phpnu�[���PKϤ$Zͮ�RR@�Sdependency-injection/Loader/Configurator/Traits/FactoryTrait.phpnu�[���PKϤ$Z��a�77=��Sdependency-injection/Loader/Configurator/Traits/FileTrait.phpnu�[���PKϤ$Z��KooB=�Sdependency-injection/Loader/Configurator/Traits/DeprecateTrait.phpnu�[���PKϤ$Z39.�!!>Tdependency-injection/Loader/Configurator/Traits/ClassTrait.phpnu�[���PKϤ$Z`�KqUUA�Tdependency-injection/Loader/Configurator/Traits/PropertyTrait.phpnu�[���PKϤ$ZdR(u&&FsTdependency-injection/Loader/Configurator/Traits/AutoconfigureTrait.phpnu�[���PKϤ$Z��d��ATdependency-injection/Loader/Configurator/ServicesConfigurator.phpnu�[���PKϤ$Zj?��B *Tdependency-injection/Loader/Configurator/ReferenceConfigurator.phpnu�[���PKϤ$Z�����A60Tdependency-injection/Loader/Configurator/AbstractConfigurator.phpnu�[���PKϤ$Z�DECjj@�=Tdependency-injection/Loader/Configurator/ServiceConfigurator.phpnu�[���PKϤ$ZXg�bbBlETdependency-injection/Loader/Configurator/ContainerConfigurator.phpnu�[���PKϤ$ZP{��C@ZTdependency-injection/Loader/Configurator/InstanceofConfigurator.phpnu�[���PKϤ$Z��Z|�|�.�_Tdependency-injection/Loader/YamlFileLoader.phpnu�[���PKϤ$Z��+���-`�Tdependency-injection/Loader/PhpFileLoader.phpnu�[���PKϤ$Z���uu-fUdependency-injection/Loader/IniFileLoader.phpnu�[���PKϤ$Z(0�x�x-8Udependency-injection/Loader/XmlFileLoader.phpnu�[���PKϤ$Z6�kk.�Udependency-injection/Loader/GlobFileLoader.phpnu�[���PKϤ$Z&��---ތUdependency-injection/Loader/ClosureLoader.phpnu�[���PKϤ$ZC�@��#�#*h�Udependency-injection/Loader/FileLoader.phpnu�[���PKϤ$Z���"N�Udependency-injection/Reference.phpnu�[���PKϤ$Z%�z&&;��Udependency-injection/Config/ContainerParametersResource.phpnu�[���PKϤ$Zn�L���7!�Udependency-injection/Config/AutowireServiceResource.phpnu�[���PKϤ$Zf��==B1�Udependency-injection/Config/ContainerParametersResourceChecker.phpnu�[���PKϤ$Z��?��3��Udependency-injection/ExpressionLanguageProvider.phpnu�[���PKϤ$Z���*�
�
8!�Udependency-injection/Argument/TaggedIteratorArgument.phpnu�[���PKϤ$Z�b��((87�Udependency-injection/Argument/ServiceLocatorArgument.phpnu�[���PKϤ$Z��*���2��Udependency-injection/Argument/AbstractArgument.phpnu�[���PKϤ$Z��8�::3��Udependency-injection/Argument/ArgumentInterface.phpnu�[���PKϤ$Z�Ѿ{��8c�Udependency-injection/Argument/ServiceClosureArgument.phpnu�[���PKϤ$Z�S%T33;v�Udependency-injection/Argument/ReferenceSetArgumentTrait.phpnu�[���PKϤ$Z�jv2�Udependency-injection/Argument/IteratorArgument.phpnu�[���PKϤ$Z=X��/x�Udependency-injection/Argument/BoundArgument.phpnu�[���PKϤ$Z�x)>��5��Udependency-injection/Argument/RewindableGenerator.phpnu�[���PKϤ$Z������0��Udependency-injection/Argument/ServiceLocator.phpnu�[���PKϤ$Z#��>3>3*�Vdependency-injection/Dumper/YamlDumper.phpnu�[���PKϤ$Z2�gU��&�8Vdependency-injection/Dumper/Dumper.phpnu�[���PKϤ$Z��ٵ��/w;Vdependency-injection/Dumper/DumperInterface.phpnu�[���PKϤ$Zƈֲ>�>)^>Vdependency-injection/Dumper/XmlDumper.phpnu�[���PKϤ$Z��m|�$�$.i}Vdependency-injection/Dumper/GraphvizDumper.phpnu�[���PKϤ$Z$��[[)��Vdependency-injection/Dumper/PhpDumper.phpnu�[���PKϤ$Z���b88)!�Wdependency-injection/Dumper/Preloader.phpnu�[���PKϤ$Z����77+�
Xdependency-injection/ExpressionLanguage.phpnu�[���PKϤ$Z��E�HHDXdependency-injection/README.mdnu�[���PKϤ$Zy$�f��?�Xdependency-injection/Compiler/RemoveAbstractDefinitionsPass.phpnu�[���PKϤ$Zʶ�]];�Xdependency-injection/Compiler/ResolveDecoratorStackPass.phpnu�[���PKϤ$Zj�����5�*Xdependency-injection/Compiler/ResolvePrivatesPass.phpnu�[���PKϤ$Z� ^^6�.Xdependency-injection/Compiler/AutoAliasServicePass.phpnu�[���PKϤ$Z��y���,�4Xdependency-injection/Compiler/PassConfig.phpnu�[���PKϤ$ZFZ�W	W	;�QXdependency-injection/Compiler/ServiceReferenceGraphNode.phpnu�[���PKϤ$Z�;/�ee?�[Xdependency-injection/Compiler/ResolveServiceSubscribersPass.phpnu�[���PKϤ$Z�vu��C|bXdependency-injection/Compiler/ResolveTaggedIteratorArgumentPass.phpnu�[���PKϤ$Z^����>�fXdependency-injection/Compiler/ResolveInvalidReferencesPass.phpnu�[���PKϤ$Z�s�B B 7�{Xdependency-injection/Compiler/AbstractRecursivePass.phpnu�[���PKϤ$Z}I!NN>��Xdependency-injection/Compiler/DefinitionErrorExceptionPass.phpnu�[���PKϤ$ZY�GQIQI.N�Xdependency-injection/Compiler/AutowirePass.phpnu�[���PKϤ$Z��|F��<��Xdependency-injection/Compiler/CheckArgumentsValidityPass.phpnu�[���PKϤ$Z��q��;K�Xdependency-injection/Compiler/ServiceReferenceGraphEdge.phpnu�[���PKϤ$Z����MM=>Ydependency-injection/Compiler/CheckDefinitionValidityPass.phpnu�[���PKϤ$Z\���TT=�Ydependency-injection/Compiler/ResolveChildDefinitionsPass.phpnu�[���PKϤ$Zϛ�?--=�3Ydependency-injection/Compiler/ValidateEnvPlaceholdersPass.phpnu�[���PKϤ$Z���||7SCYdependency-injection/Compiler/ExtensionCompilerPass.phpnu�[���PKϤ$Z���MM<6GYdependency-injection/Compiler/ResolveEnvPlaceholdersPass.phpnu�[���PKϤ$Z�,҈

7�LYdependency-injection/Compiler/ServiceReferenceGraph.phpnu�[���PKϤ$Zm����@kWYdependency-injection/Compiler/ResolveDefinitionTemplatesPass.phpnu�[���PKϤ$Z�I���"�"5�vYdependency-injection/Compiler/ResolveBindingsPass.phpnu�[���PKϤ$Zw�(���>+�Ydependency-injection/Compiler/AnalyzeServiceReferencesPass.phpnu�[���PKϤ$ZB��_��7,�Ydependency-injection/Compiler/CompilerPassInterface.phpnu�[���PKϤ$Zz��>/�Ydependency-injection/Compiler/RegisterEnvVarProcessorsPass.phpnu�[���PKϤ$ZӉ���9Z�Ydependency-injection/Compiler/ResolveFactoryClassPass.phpnu�[���PKϤ$Z��
�	�	C��Ydependency-injection/Compiler/AliasDeprecatedPublicServicesPass.phpnu�[���PKϤ$ZW�-��2��Ydependency-injection/Compiler/LoggingFormatter.phpnu�[���PKϤ$Z���2��Ydependency-injection/Compiler/ResolveClassPass.phpnu�[���PKϤ$Z��u
u
=_�Ydependency-injection/Compiler/AutowireRequiredMethodsPass.phpnu�[���PKϤ$Z��.6``CA�Ydependency-injection/Compiler/ResolveInstanceofConditionalsPass.phpnu�[���PKϤ$ZW�g!��BZdependency-injection/Compiler/ResolveParameterPlaceHoldersPass.phpnu�[���PKϤ$Z�<M��.Zdependency-injection/Compiler/RepeatedPass.phpnu�[���PKϤ$Z��*DT	T	4rZdependency-injection/Compiler/ResolveHotPathPass.phpnu�[���PKϤ$ZéN�~~@*$Zdependency-injection/Compiler/AutowireRequiredPropertiesPass.phpnu�[���PKϤ$Zܖ�S��<-Zdependency-injection/Compiler/PriorityTaggedServiceTrait.phpnu�[���PKϤ$Z��Eų�9HIZdependency-injection/Compiler/RepeatablePassInterface.phpnu�[���PKϤ$Z���!�!AdLZdependency-injection/Compiler/MergeExtensionConfigurationPass.phpnu�[���PKϤ$Z�\�ZZ:lnZdependency-injection/Compiler/RemovePrivateAliasesPass.phpnu�[���PKϤ$Z��>60sZdependency-injection/Compiler/ResolveNoPreloadPass.phpnu�[���PKϤ$Z��R%��<�Zdependency-injection/Compiler/CheckReferenceValidityPass.phpnu�[���PKϤ$Z�v�""NF�Zdependency-injection/Compiler/CheckExceptionOnInvalidReferenceBehaviorPass.phpnu�[���PKϤ$Z��(��*�Zdependency-injection/Compiler/Compiler.phpnu�[���PKϤ$Z�__@ٞZdependency-injection/Compiler/RegisterServiceSubscribersPass.phpnu�[���PKϤ$Z���,,=��Zdependency-injection/Compiler/RemoveUnusedDefinitionsPass.phpnu�[���PKϤ$Z���h�	�	@A�Zdependency-injection/Compiler/ResolveReferencesToAliasesPass.phpnu�[���PKϤ$Z;>�,,7��Zdependency-injection/Compiler/ServiceLocatorTagPass.phpnu�[���PKϤ$Z$�;���>1�Zdependency-injection/Compiler/RegisterReverseContainerPass.phpnu�[���PKϤ$Z$�Ő	�	=p�Zdependency-injection/Compiler/CheckCircularReferencesPass.phpnu�[���PKϤ$Z`2,c�
�
Dm�Zdependency-injection/Compiler/ReplaceAliasByActualDefinitionPass.phpnu�[���PKϤ$Z�@�r>�[dependency-injection/Compiler/InlineServiceDefinitionsPass.phpnu�[���PKϤ$Z}H�w--;;![dependency-injection/Compiler/CheckTypeDeclarationsPass.phpnu�[���PKϤ$Z{>H��;�N[dependency-injection/Compiler/ResolveNamedArgumentsPass.phpnu�[���PKϤ$Z��5�ww6�d[dependency-injection/Compiler/DecoratorServicePass.phpnu�[���PKϤ$Z�A���1�w[dependency-injection/TaggedContainerInterface.phpnu�[���PKϤ$Z����1	{[dependency-injection/EnvVarProcessorInterface.phpnu�[���PKϤ$Z���_��2�[dependency-injection/ParameterBag/ParameterBag.phpnu�[���PKϤ$Z�`ff;M�[dependency-injection/ParameterBag/ContainerBagInterface.phpnu�[���PKϤ$Z��K��@�[dependency-injection/ParameterBag/EnvPlaceholderParameterBag.phpnu�[���PKϤ$Zn�k�r
r
;1�[dependency-injection/ParameterBag/ParameterBagInterface.phpnu�[���PKϤ$Z�I.eFF8�[dependency-injection/ParameterBag/FrozenParameterBag.phpnu�[���PKϤ$Z�G��2��[dependency-injection/ParameterBag/ContainerBag.phpnu�[���PKϤ$Z���((+�[dependency-injection/ContainerInterface.phpnu�[���PKϤ$Z��GXNN0��[dependency-injection/ContainerAwareInterface.phpnu�[���PKϤ$ZvBk���DN�[dependency-injection/Exception/ServiceCircularReferenceException.phpnu�[���PKϤ$Zl.��1��[dependency-injection/Exception/LogicException.phpnu�[���PKϤ$Zt�o���F��[dependency-injection/Exception/ParameterCircularReferenceException.phpnu�[���PKϤ$Z�-�_8��[dependency-injection/Exception/EnvParameterException.phpnu�[���PKϤ$Z�dg݋�@e�[dependency-injection/Exception/InvalidParameterTypeException.phpnu�[���PKϤ$Z�>��bb5`�[dependency-injection/Exception/ExceptionInterface.phpnu�[���PKϤ$Z�ǁ

='�[dependency-injection/Exception/ParameterNotFoundException.phpnu�[���PKϤ$Z��;�\dependency-injection/Exception/InvalidArgumentException.phpnu�[���PKϤ$Z��tB��<#\dependency-injection/Exception/AutowiringFailedException.phpnu�[���PKϤ$Z.��Y;4\dependency-injection/Exception/ServiceNotFoundException.phpnu�[���PKϤ$Z���>��7�\dependency-injection/Exception/EnvNotFoundException.phpnu�[���PKϤ$Z�{����7�\dependency-injection/Exception/OutOfBoundsException.phpnu�[���PKϤ$Z
O�,��9(\dependency-injection/Exception/BadMethodCallException.phpnu�[���PKϤ$Z�
+��3e\dependency-injection/Exception/RuntimeException.phpnu�[���PKϤ$Z�!�L�3�3!�\dependency-injection/CHANGELOG.mdnu�[���PKϤ$Z��.t��.�P\dependency-injection/LazyProxy/ProxyHelper.phpnu�[���PKϤ$Z��{{<�X\dependency-injection/LazyProxy/PhpDumper/DumperInterface.phpnu�[���PKϤ$Z�?Q��7�]\dependency-injection/LazyProxy/PhpDumper/NullDumper.phpnu�[���PKϤ$Z@#�MME�a\dependency-injection/LazyProxy/Instantiator/InstantiatorInterface.phpnu�[���PKϤ$Z�<�iiG�f\dependency-injection/LazyProxy/Instantiator/RealServiceInstantiator.phpnu�[���PKϤ$Z=��))�j\dependency-injection/LICENSEnu�[���PKϤ$Z�u�dd'o\dependency-injection/ServiceLocator.phpnu�[���PKϤ$Z����0
0
)Ѓ\dependency-injection/ReverseContainer.phpnu�[���PKϤ$Z�=w�
�
(Y�\dependency-injection/ChildDefinition.phpnu�[���PKϤ$Z�W>O}}.��\dependency-injection/EnvVarLoaderInterface.phpnu�[���PKϤ$Z��䎫X�X#��\dependency-injection/Definition.phpnu�[���PKϤ$Z"�L+����)��\dependency-injection/ContainerBuilder.phpnu�[���PKϤ$ZL�EY,��]dependency-injection/DefinitionDecorator.phpnu�[���PKϤ$Z��c���1�]polyfill-iconv/README.mdnu�[���PKϤ$Z�b|��/!�]polyfill-iconv/Resources/charset/from.cp855.phpnu�[���PKϤ$Z
�����6a�]polyfill-iconv/Resources/charset/from.windows-1250.phpnu�[���PKϤ$Z�K��\\/P�]polyfill-iconv/Resources/charset/from.cp869.phpnu�[���PKϤ$Z�JT��6^polyfill-iconv/Resources/charset/from.windows-1256.phpnu�[���PKϤ$Z#�����0I^polyfill-iconv/Resources/charset/from.cp1026.phpnu�[���PKϤ$Z?��*/l*^polyfill-iconv/Resources/charset/from.cp865.phpnu�[���PKϤ$Z���|/�9^polyfill-iconv/Resources/charset/from.cp862.phpnu�[���PKϤ$Z����/,I^polyfill-iconv/Resources/charset/from.cp424.phpnu�[���PKϤ$Zd�lAll4V^polyfill-iconv/Resources/charset/from.iso-8859-7.phpnu�[���PKϤ$ZŬ�/�d^polyfill-iconv/Resources/charset/from.cp863.phpnu�[���PKϤ$Z��c�ZZ4Et^polyfill-iconv/Resources/charset/from.iso-8859-3.phpnu�[���PKϤ$Z�����4�^polyfill-iconv/Resources/charset/from.iso-8859-2.phpnu�[���PKϤ$ZK��W/*�^polyfill-iconv/Resources/charset/from.cp861.phpnu�[���PKϤ$Z���@~
~
6��^polyfill-iconv/Resources/charset/from.windows-1255.phpnu�[���PKϤ$Z�>��/n�^polyfill-iconv/Resources/charset/from.cp860.phpnu�[���PKϤ$Z�>2�!�!-;^polyfill-iconv/Resources/charset/translit.phpnu�[���PKϤ$Z0pIq��/��_polyfill-iconv/Resources/charset/from.cp500.phpnu�[���PKϤ$Z�D�H;�;�/�_polyfill-iconv/Resources/charset/from.cp936.phpnu�[���PKϤ$Z�`i���/��epolyfill-iconv/Resources/charset/from.cp852.phpnu�[���PKϤ$ZxB
�0�epolyfill-iconv/Resources/charset/from.cp1006.phpnu�[���PKϤ$Z	uň��0]�epolyfill-iconv/Resources/charset/from.koi8-r.phpnu�[���PKϤ$Z\���  4��epolyfill-iconv/Resources/charset/from.iso-8859-6.phpnu�[���PKϤ$ZXQ����5<�epolyfill-iconv/Resources/charset/from.iso-8859-15.phpnu�[���PKϤ$Z��D;��/e�epolyfill-iconv/Resources/charset/from.cp866.phpnu�[���PKϤ$Z0��/��/��epolyfill-iconv/Resources/charset/from.cp850.phpnu�[���PKϤ$Z��kk6�fpolyfill-iconv/Resources/charset/from.windows-1254.phpnu�[���PKϤ$ZOP�gCC2�fpolyfill-iconv/Resources/charset/from.us-ascii.phpnu�[���PKϤ$Z�R��5qfpolyfill-iconv/Resources/charset/from.iso-8859-10.phpnu�[���PKϤ$ZB4���0�,fpolyfill-iconv/Resources/charset/from.koi8-u.phpnu�[���PKϤ$Z��U(/�;fpolyfill-iconv/Resources/charset/from.cp437.phpnu�[���PKϤ$Z�r�P��/MKfpolyfill-iconv/Resources/charset/from.cp857.phpnu�[���PKϤ$Z�~V��/_Zfpolyfill-iconv/Resources/charset/from.cp950.phpnu�[���PKϤ$Zz;�7��4��ipolyfill-iconv/Resources/charset/from.iso-8859-1.phpnu�[���PKϤ$Zg�CG��/��ipolyfill-iconv/Resources/charset/from.cp932.phpnu�[���PKϤ$Z�*��/�kpolyfill-iconv/Resources/charset/from.cp875.phpnu�[���PKϤ$Z��i�R
R
/>
lpolyfill-iconv/Resources/charset/from.cp874.phpnu�[���PKϤ$Z��&��4�lpolyfill-iconv/Resources/charset/from.iso-8859-5.phpnu�[���PKϤ$Z�O�NN6*lpolyfill-iconv/Resources/charset/from.windows-1258.phpnu�[���PKϤ$Zͩ�Ū�4�8lpolyfill-iconv/Resources/charset/from.iso-8859-8.phpnu�[���PKϤ$Zl����5�Elpolyfill-iconv/Resources/charset/from.iso-8859-14.phpnu�[���PKϤ$ZZ�����6Ulpolyfill-iconv/Resources/charset/from.windows-1251.phpnu�[���PKϤ$ZL�tw��/Cdlpolyfill-iconv/Resources/charset/from.cp864.phpnu�[���PKϤ$Zȫ�ˉ�6eslpolyfill-iconv/Resources/charset/from.windows-1252.phpnu�[���PKϤ$Z�꣎��.T�lpolyfill-iconv/Resources/charset/from.big5.phpnu�[���PKϤ$Z1M���5Uppolyfill-iconv/Resources/charset/from.iso-8859-16.phpnu�[���PKϤ$Zs1
���/� ppolyfill-iconv/Resources/charset/from.cp037.phpnu�[���PKϤ$Z�94|��5�/ppolyfill-iconv/Resources/charset/from.iso-8859-13.phpnu�[���PKϤ$Z2���5�>ppolyfill-iconv/Resources/charset/from.iso-8859-11.phpnu�[���PKϤ$Z�wg���/�Mppolyfill-iconv/Resources/charset/from.cp775.phpnu�[���PKϤ$ZU���zz/]ppolyfill-iconv/Resources/charset/from.cp856.phpnu�[���PKϤ$Z,�  6�ippolyfill-iconv/Resources/charset/from.windows-1257.phpnu�[���PKϤ$Zx�z���4zxppolyfill-iconv/Resources/charset/from.iso-8859-9.phpnu�[���PKϤ$Z�C��
�
6��ppolyfill-iconv/Resources/charset/from.windows-1253.phpnu�[���PKϤ$Zj� ���4ݕppolyfill-iconv/Resources/charset/from.iso-8859-4.phpnu�[���PKϤ$Z
��r�r/�ppolyfill-iconv/Resources/charset/from.cp949.phpnu�[���PKϤ$Z�A���/upolyfill-iconv/Resources/charset/from.cp737.phpnu�[���PKϤ$Z���sl'upolyfill-iconv/bootstrap.phpnu�[���PKϤ$Z~�Ʊ�X�X�5upolyfill-iconv/Iconv.phpnu�[���PKϤ$Z�\�))��upolyfill-iconv/LICENSEnu�[���PK  ���u