Repository: zendframework/zend-validator Branch: master Commit: 63dd0fe5d89f Files: 273 Total size: 2.9 MB Directory structure: gitextract_70x1ddz0/ ├── .coveralls.yml ├── .gitattributes ├── .gitignore ├── .travis.yml ├── CHANGELOG.md ├── LICENSE.md ├── README.md ├── bin/ │ └── update_hostname_validator.php ├── composer.json ├── docs/ │ ├── CODE_OF_CONDUCT.md │ ├── CONTRIBUTING.md │ ├── ISSUE_TEMPLATE.md │ ├── PULL_REQUEST_TEMPLATE.md │ ├── SUPPORT.md │ └── book/ │ ├── index.md │ ├── intro.md │ ├── messages.md │ ├── set.md │ ├── validator-chains.md │ ├── validators/ │ │ ├── barcode.md │ │ ├── between.md │ │ ├── callback.md │ │ ├── credit-card.md │ │ ├── date.md │ │ ├── db.md │ │ ├── digits.md │ │ ├── email-address.md │ │ ├── explode.md │ │ ├── file/ │ │ │ ├── count.md │ │ │ ├── crc32.md │ │ │ ├── exclude-extension.md │ │ │ ├── exclude-mime-type.md │ │ │ ├── exists.md │ │ │ ├── extension.md │ │ │ ├── files-size.md │ │ │ ├── hash.md │ │ │ ├── image-size.md │ │ │ ├── intro.md │ │ │ ├── is-compressed.md │ │ │ ├── is-image.md │ │ │ ├── md5.md │ │ │ ├── mime-type.md │ │ │ ├── not-exists.md │ │ │ ├── sha1.md │ │ │ ├── size.md │ │ │ ├── upload-file.md │ │ │ ├── upload.md │ │ │ └── word-count.md │ │ ├── greater-than.md │ │ ├── hex.md │ │ ├── hostname.md │ │ ├── iban.md │ │ ├── identical.md │ │ ├── in-array.md │ │ ├── ip.md │ │ ├── is-countable.md │ │ ├── isbn.md │ │ ├── isinstanceof.md │ │ ├── less-than.md │ │ ├── not-empty.md │ │ ├── regex.md │ │ ├── sitemap.md │ │ ├── step.md │ │ ├── string-length.md │ │ ├── timezone.md │ │ ├── undisclosed-password.md │ │ ├── uri.md │ │ └── uuid.md │ └── writing-validators.md ├── mkdocs.yml ├── phpcs.xml ├── phpunit.xml.dist ├── src/ │ ├── AbstractValidator.php │ ├── Barcode/ │ │ ├── AbstractAdapter.php │ │ ├── AdapterInterface.php │ │ ├── Codabar.php │ │ ├── Code128.php │ │ ├── Code25.php │ │ ├── Code25interleaved.php │ │ ├── Code39.php │ │ ├── Code39ext.php │ │ ├── Code93.php │ │ ├── Code93ext.php │ │ ├── Ean12.php │ │ ├── Ean13.php │ │ ├── Ean14.php │ │ ├── Ean18.php │ │ ├── Ean2.php │ │ ├── Ean5.php │ │ ├── Ean8.php │ │ ├── Gtin12.php │ │ ├── Gtin13.php │ │ ├── Gtin14.php │ │ ├── Identcode.php │ │ ├── Intelligentmail.php │ │ ├── Issn.php │ │ ├── Itf14.php │ │ ├── Leitcode.php │ │ ├── Planet.php │ │ ├── Postnet.php │ │ ├── Royalmail.php │ │ ├── Sscc.php │ │ ├── Upca.php │ │ └── Upce.php │ ├── Barcode.php │ ├── Between.php │ ├── Bitwise.php │ ├── Callback.php │ ├── ConfigProvider.php │ ├── CreditCard.php │ ├── Csrf.php │ ├── Date.php │ ├── DateStep.php │ ├── Db/ │ │ ├── AbstractDb.php │ │ ├── NoRecordExists.php │ │ └── RecordExists.php │ ├── Digits.php │ ├── EmailAddress.php │ ├── Exception/ │ │ ├── BadMethodCallException.php │ │ ├── ExceptionInterface.php │ │ ├── ExtensionNotLoadedException.php │ │ ├── InvalidArgumentException.php │ │ ├── InvalidMagicMimeFileException.php │ │ └── RuntimeException.php │ ├── Explode.php │ ├── File/ │ │ ├── Count.php │ │ ├── Crc32.php │ │ ├── ExcludeExtension.php │ │ ├── ExcludeMimeType.php │ │ ├── Exists.php │ │ ├── Extension.php │ │ ├── FileInformationTrait.php │ │ ├── FilesSize.php │ │ ├── Hash.php │ │ ├── ImageSize.php │ │ ├── IsCompressed.php │ │ ├── IsImage.php │ │ ├── Md5.php │ │ ├── MimeType.php │ │ ├── NotExists.php │ │ ├── Sha1.php │ │ ├── Size.php │ │ ├── Upload.php │ │ ├── UploadFile.php │ │ └── WordCount.php │ ├── GpsPoint.php │ ├── GreaterThan.php │ ├── Hex.php │ ├── Hostname/ │ │ ├── Biz.php │ │ ├── Cn.php │ │ ├── Com.php │ │ └── Jp.php │ ├── Hostname.php │ ├── Iban.php │ ├── Identical.php │ ├── InArray.php │ ├── Ip.php │ ├── IsCountable.php │ ├── IsInstanceOf.php │ ├── Isbn/ │ │ ├── Isbn10.php │ │ └── Isbn13.php │ ├── Isbn.php │ ├── LessThan.php │ ├── Module.php │ ├── NotEmpty.php │ ├── Regex.php │ ├── Sitemap/ │ │ ├── Changefreq.php │ │ ├── Lastmod.php │ │ ├── Loc.php │ │ └── Priority.php │ ├── StaticValidator.php │ ├── Step.php │ ├── StringLength.php │ ├── Timezone.php │ ├── Translator/ │ │ ├── TranslatorAwareInterface.php │ │ └── TranslatorInterface.php │ ├── UndisclosedPassword.php │ ├── Uri.php │ ├── Uuid.php │ ├── ValidatorChain.php │ ├── ValidatorInterface.php │ ├── ValidatorPluginManager.php │ ├── ValidatorPluginManagerAwareInterface.php │ ├── ValidatorPluginManagerFactory.php │ └── ValidatorProviderInterface.php └── test/ ├── AbstractTest.php ├── BarcodeTest.php ├── BetweenTest.php ├── BitwiseTest.php ├── CallbackTest.php ├── CreditCardTest.php ├── CsrfTest.php ├── DateStepTest.php ├── DateTest.php ├── Db/ │ ├── AbstractDbTest.php │ ├── NoRecordExistsTest.php │ ├── RecordExistsTest.php │ └── TestAsset/ │ ├── ConcreteDbValidator.php │ └── TrustingSql92Platform.php ├── DigitsTest.php ├── EmailAddressTest.php ├── ExplodeTest.php ├── File/ │ ├── CountTest.php │ ├── Crc32Test.php │ ├── ExcludeExtensionTest.php │ ├── ExcludeMimeTypeTest.php │ ├── ExistsTest.php │ ├── ExtensionTest.php │ ├── FileInformationTraitTest.php │ ├── FilesSizeTest.php │ ├── HashTest.php │ ├── ImageSizeTest.php │ ├── IsCompressedTest.php │ ├── IsImageTest.php │ ├── Md5Test.php │ ├── MimeTypeTest.php │ ├── NotExistsTest.php │ ├── Sha1Test.php │ ├── SizeTest.php │ ├── TestAsset/ │ │ └── FileInformation.php │ ├── UploadFileTest.php │ ├── UploadTest.php │ ├── WordCountTest.php │ └── _files/ │ ├── magic.7.mime │ ├── magic.lte.5.3.10.mime │ ├── magic.mime │ ├── testsize.mo │ ├── testsize2.mo │ ├── testsize3.mo │ ├── testsize4.mo │ └── wordcount.txt ├── GPSPointTest.php ├── GreaterThanTest.php ├── HexTest.php ├── HostnameTest.php ├── IbanTest.php ├── IdenticalTest.php ├── InArrayTest.php ├── IpTest.php ├── IsCountableTest.php ├── IsInstanceOfTest.php ├── IsbnTest.php ├── LessThanTest.php ├── MessageTest.php ├── NotEmptyTest.php ├── RegexTest.php ├── Sitemap/ │ ├── ChangefreqTest.php │ ├── LastmodTest.php │ ├── LocTest.php │ └── PriorityTest.php ├── StaticValidatorTest.php ├── StepTest.php ├── StringLengthTest.php ├── TestAsset/ │ ├── ArrayTranslator.php │ ├── ConcreteValidator.php │ ├── CreditCardValidatorExtension.php │ ├── EmailValidatorWithExposedIsReserved.php │ ├── HttpClientException.php │ ├── SessionManager.php │ └── Translator.php ├── TimezoneTest.php ├── UndisclosedPasswordTest.php ├── UriTest.php ├── UuidTest.php ├── ValidatorChainTest.php ├── ValidatorPluginManagerCompatibilityTest.php ├── ValidatorPluginManagerFactoryTest.php ├── ValidatorPluginManagerTest.php └── _files/ ├── MyBarcode1.php ├── MyBarcode2.php ├── MyBarcode3.php ├── MyBarcode4.php └── MyBarcode5.php ================================================ FILE CONTENTS ================================================ ================================================ FILE: .coveralls.yml ================================================ coverage_clover: clover.xml json_path: coveralls-upload.json ================================================ FILE: .gitattributes ================================================ /.coveralls.yml export-ignore /.gitattributes export-ignore /.gitignore export-ignore /.travis.yml export-ignore /composer.lock export-ignore /docs/ export-ignore /mkdocs.yml export-ignore /phpcs.xml export-ignore /phpunit.xml.dist export-ignore /test/ export-ignore ================================================ FILE: .gitignore ================================================ /clover.xml /coveralls-upload.json /docs/html/ /phpunit.xml /vendor/ /zf-mkdoc-theme.tgz /zf-mkdoc-theme/ ================================================ FILE: .travis.yml ================================================ language: php branches: except: - /^release-.*$/ - /^ghgfk-.*$/ cache: directories: - $HOME/.composer/ env: global: - COMPOSER_ARGS="--no-interaction" - COVERAGE_DEPS="php-coveralls/php-coveralls" - LEGACY_DEPS="phpunit/phpunit" - TESTS_ZEND_VALIDATOR_ONLINE_ENABLED=true matrix: include: - php: 7.1 env: - DEPS=lowest - php: 7.1 env: - DEPS=locked - EXECUTE_HOSTNAME_CHECK=true - TEST_COVERAGE=true - php: 7.1 env: - DEPS=latest - php: 7.2 env: - DEPS=lowest - php: 7.2 env: - DEPS=locked - php: 7.2 env: - DEPS=latest - php: 7.3 env: - DEPS=lowest - php: 7.3 env: - DEPS=locked - php: 7.3 env: - DEPS=latest - php: 7.4 env: - DEPS=lowest - php: 7.4 env: - DEPS=locked - php: 7.4 env: - DEPS=latest before_install: - if [[ $TEST_COVERAGE != 'true' ]]; then phpenv config-rm xdebug.ini || return 0 ; fi - travis_retry composer self-update install: - travis_retry composer install $COMPOSER_ARGS --ignore-platform-reqs - if [[ $TRAVIS_PHP_VERSION =~ ^5.6 ]]; then travis_retry composer update $COMPOSER_ARGS --with-dependencies $LEGACY_DEPS ; fi - if [[ $DEPS == 'latest' ]]; then travis_retry composer update $COMPOSER_ARGS ; fi - if [[ $DEPS == 'lowest' ]]; then travis_retry composer update --prefer-lowest --prefer-stable $COMPOSER_ARGS ; fi - if [[ $TEST_COVERAGE == 'true' ]]; then travis_retry composer require --dev $COMPOSER_ARGS $COVERAGE_DEPS ; fi - stty cols 120 - COLUMNS=120 composer show script: - if [[ $TEST_COVERAGE == 'true' ]]; then composer test-coverage ; else composer test ; fi - if [[ $CS_CHECK == 'true' ]]; then composer cs-check ; fi - if [[ $EXECUTE_HOSTNAME_CHECK == "true" && $TRAVIS_PULL_REQUEST == "false" ]]; then php bin/update_hostname_validator.php --check-only; fi after_script: - if [[ $TEST_COVERAGE == 'true' ]]; then travis_retry php vendor/bin/php-coveralls -v ; fi notifications: email: false ================================================ FILE: CHANGELOG.md ================================================ # Changelog All notable changes to this project will be documented in this file, in reverse chronological order by release. ## 2.13.0 - 2019-12-27 ### Added - [#275](https://github.com/zendframework/zend-validator/pull/275) adds a new `strict` option to `Zend\Validator\Date`; when `true`, the value being validated must both be a date AND in the same format as provided via the `format` option. - [#264](https://github.com/zendframework/zend-validator/pull/264) adds `Zend\Validator\UndisclosedPassword`, which can be used to determine if a password has been exposed in a known data breach as reported on the [Have I Been Pwned?](https://www.haveibeenpwned.com) website. [Documentation](https://docs.zendframework.com/zend-validator/validators/undisclosed-password/) - [#266](https://github.com/zendframework/zend-validator/pull/266) adds a new option to the `File\Extension` and `File\ExcludeExtension` validators, `allowNonExistentFile`. When set to `true`, the validators will continue validating the extension of the filename given even if the file does not exist. The default is `false`, to preserve backwards compatibility with previous versions. ### Changed - [#264](https://github.com/zendframework/zend-validator/pull/264) bumps the minimum supported PHP version to 7.1.0. - [#279](https://github.com/zendframework/zend-validator/pull/279) updates the `magic.mime` file used for file validations. ### Deprecated - Nothing. ### Removed - [#264](https://github.com/zendframework/zend-validator/pull/264) removes support for PHP versions prior to 7.1.0. ### Fixed - Nothing. ## 2.12.2 - 2019-10-29 ### Added - Nothing. ### Changed - Nothing. ### Deprecated - Nothing. ### Removed - Nothing. ### Fixed - [#277](https://github.com/zendframework/zend-validator/pull/277) fixes `File\Hash` validator in case when the file hash contains only digits. - [#277](https://github.com/zendframework/zend-validator/pull/277) fixes `File\Hash` validator to match hash with the given hashing algorithm. ## 2.12.1 - 2019-10-12 ### Added - Nothing. ### Changed - Nothing. ### Deprecated - Nothing. ### Removed - Nothing. ### Fixed - [#272](https://github.com/zendframework/zend-validator/pull/272) changes curly braces in array and string offset access to square brackets in order to prevent issues under the upcoming PHP 7.4 release. - [#231](https://github.com/zendframework/zend-validator/pull/231) fixes validation of input hashes in `Zend\Validator\File\Hash` validator when provided as array. Only string hashes are allowed. If different type is provided `Zend\Validator\Exception\InvalidArgumentException` is thrown. ## 2.12.0 - 2019-01-30 ### Added - [#250](https://github.com/zendframework/zend-validator/pull/250) adds support for PHP 7.3. ### Changed - [#251](https://github.com/zendframework/zend-validator/pull/251) updates the logic of each of the various `Zend\Validator\File` validators to allow validating against PSR-7 `UploadedFileInterface` instances, expanding the support originally provided in version 2.11.0. ### Deprecated - Nothing. ### Removed - [#250](https://github.com/zendframework/zend-validator/pull/250) removes support for zend-stdlib v2 releases. ### Fixed - Nothing. ## 2.11.1 - 2019-01-29 ### Added - [#249](https://github.com/zendframework/zend-validator/pull/249) adds support in the hostname validator for the `.rs` TLD. ### Changed - [#253](https://github.com/zendframework/zend-validator/pull/253) updates the list of allowed characters for a `DE` domain name to match those published by IDN. ### Deprecated - Nothing. ### Removed - Nothing. ### Fixed - [#256](https://github.com/zendframework/zend-validator/pull/256) fixes hostname validation when omitting the TLD from verification, ensuring validation of the domain segment considers all URI criteria. ## 2.11.0 - 2018-12-13 ### Added - [#237](https://github.com/zendframework/zend-validator/pull/237) adds support for the [PSR-7 UploadedFileInterface](https://www.php-fig.org/psr/psr-7/#uploadedfileinterface) to each of the `Upload` and `UploadFile` validators. - [#220](https://github.com/zendframework/zend-validator/pull/220) adds image/webp to the list of known image types for the `IsImage` validator. ### Changed - Nothing. ### Deprecated - Nothing. ### Removed - Nothing. ### Fixed - Nothing. ## 2.10.3 - 2018-12-13 ### Added - Nothing. ### Changed - Nothing. ### Deprecated - Nothing. ### Removed - Nothing. ### Fixed - [#241](https://github.com/zendframework/zend-validator/pull/241) has the `Hostname` validator return an invalid result early when an empty domain segment is detected. - [#232](https://github.com/zendframework/zend-validator/pull/232) updates the `Hostname` validator to allow underscores in subdomains. - [#218](https://github.com/zendframework/zend-validator/pull/218) fixes a precision issue with the `Step` validator. ## 2.10.2 - 2018-02-01 ### Added - [#202](https://github.com/zendframework/zend-validator/pull/202) adds the ability to use custom constant types in extensions of `Zend\Validator\CreditCard`, fixing an issue where users were unable to add new brands as they are created. - [#203](https://github.com/zendframework/zend-validator/pull/203) adds support for the new Russian bank card "Mir". - [#204](https://github.com/zendframework/zend-validator/pull/204) adds support to the IBAN validator for performing SEPA validation against Croatia and San Marino. - [#209](https://github.com/zendframework/zend-validator/pull/209) adds documentation for the `Explode` validator. ### Changed - Nothing. ### Deprecated - Nothing. ### Removed - Nothing. ### Fixed - [#195](https://github.com/zendframework/zend-validator/pull/195) adds missing `GpsPoint` validator entries to the `ValidatorPluginManager`, ensuring they may be retrieved from it correctly. - [#212](https://github.com/zendframework/zend-validator/pull/212) updates the `CSRF` validator to automatically mark any non-string values as invalid, preventing errors such as array to string conversion. ## 2.10.1 - 2017-08-22 ### Added - Nothing. ### Changed - Nothing. ### Deprecated - Nothing. ### Removed - Nothing. ### Fixed - [#194](https://github.com/zendframework/zend-validator/pull/194) modifies the `EmailAddress` validator to omit the `INTL_IDNA_VARIANT_UTS46` flag to `idn_to_utf8()` if the constant is not defined, fixing an issue on systems using pre-2012 releases of libicu. ## 2.10.0 - 2017-08-14 ### Added - [#175](https://github.com/zendframework/zend-validator/pull/175) adds support for PHP 7.2 (conditionally, as PHP 7.2 is currently in beta1). - [#157](https://github.com/zendframework/zend-validator/pull/157) adds a new validator, `IsCountable`, which allows validating: - if a value is countable - if a countable value exactly matches a configured count - if a countable value is greater than a configured minimum count - if a countable value is less than a configured maximum count - if a countable value is between configured minimum and maximum counts ### Changed - [#169](https://github.com/zendframework/zend-validator/pull/169) modifies how the various `File` validators check for readable files. Previously, they used `stream_resolve_include_path`, which led to false negative checks when the files did not exist within an `include_path` (which is often the case within a web application). These now use `is_readable()` instead. - [#185](https://github.com/zendframework/zend-validator/pull/185) updates the zend-session requirement (during development, and in the suggestions) to 2.8+, to ensure compatibility with the upcoming PHP 7.2 release. - [#187](https://github.com/zendframework/zend-validator/pull/187) updates the `Between` validator to **require** that both a `min` and a `max` value are provided to the constructor, and that both are of the same type (both integer/float values and/or both string values). This fixes issues that could previously occur when one or the other was not set, but means an exception will now be raised during instantiation (versus runtime during `isValid()`). - [#188](https://github.com/zendframework/zend-validator/pull/188) updates the `ConfigProvider` to alias the service name `ValidatorManager` to the class `Zend\Validator\ValidatorPluginManager`, and now maps the the latter class to the `ValidatorPluginManagerFactory`. Previously, we mapped the service name directly to the factory. Usage should not change for anybody at this point. ### Deprecated - Nothing. ### Removed - [#175](https://github.com/zendframework/zend-validator/pull/175) removes support for HHVM. ### Fixed - [#160](https://github.com/zendframework/zend-validator/pull/160) fixes how the `EmailAddress` validator handles the local part of an address, allowing it to support unicode. ## 2.9.2 - 2017-07-20 ### Added - Nothing. ### Deprecated - Nothing. ### Removed - Nothing. ### Fixed - [#180](https://github.com/zendframework/zend-validator/pull/180) fixes how `Zend\Validator\File\MimeType` "closes" the open FileInfo handle for the file being validated, using `unset()` instead of `finfo_close()`; this resolves a segfault that occurs on older PHP versions. - [#174](https://github.com/zendframework/zend-validator/pull/174) fixes how `Zend\Validator\Between` handles two situations: (1) when a non-numeric value is validated against numeric min/max values, and (2) when a numeric value is validated against non-numeric min/max values. Previously, these incorrectly validated as true; now they are marked invalid. ## 2.9.1 - 2017-05-17 ### Added - Nothing. ### Changes - [#154](https://github.com/zendframework/zend-validator/pull/154) updates the `CreditCard` validator to allow 19 digit Discover card values, and 13 and 19 digit Visa card values, which are now allowed (see https://en.wikipedia.org/wiki/Payment_card_number). - [#162](https://github.com/zendframework/zend-validator/pull/162) updates the `Hostname` validator to support `.hr` (Croatia) IDN domains. - [#163](https://github.com/zendframework/zend-validator/pull/163) updates the `Iban` validator to support Belarus. ### Deprecated - Nothing. ### Removed - Nothing. ### Fixed - [#168](https://github.com/zendframework/zend-validator/pull/168) fixes how the `ValidatorPluginManagerFactory` factory initializes the plugin manager instance, ensuring it is injecting the relevant configuration from the `config` service and thus seeding it with configured validator services. This means that the `validators` configuration will now be honored in non-zend-mvc contexts. ## 2.9.0 - 2017-03-17 ### Added - [#78](https://github.com/zendframework/zend-validator/pull/78) added `%length%` as an optional message variable in StringLength validator ### Deprecated - Nothing. ### Removed - [#151](https://github.com/zendframework/zend-validator/pull/151) dropped php 5.5 support ### Fixed - [#147](https://github.com/zendframework/zend-validator/issues/147) [#148](https://github.com/zendframework/zend-validator/pull/148) adds further `"suggest"` clauses in `composer.json`, since some dependencies are not always required, and may lead to runtime failures. - [#66](https://github.com/zendframework/zend-validator/pull/66) fixed EmailAddress validator applying IDNA conversion to local part - [#88](https://github.com/zendframework/zend-validator/pull/88) fixed NotEmpty validator incorrectly applying types bitmaps - [#150](https://github.com/zendframework/zend-validator/pull/150) fixed Hostname validator not allowing some characters in .dk IDN ## 2.8.2 - 2017-01-29 ### Added - [#110](https://github.com/zendframework/zend-validator/pull/110) adds new Mastercard 2-series BINs ### Deprecated - Nothing. ### Removed - Nothing. ### Fixed - [#81](https://github.com/zendframework/zend-validator/pull/81) registers the Uuid validator into ValidatorPluginManager. ## 2.8.1 - 2016-06-23 ### Added - Nothing. ### Deprecated - Nothing. ### Removed - Nothing. ### Fixed - [#92](https://github.com/zendframework/zend-validator/pull/92) adds message templates to the `ExcludeMimeType` validator, to allow differentiating validation error messages from the `MimeType` validator. ## 2.8.0 - 2016-05-16 ### Added - [#58](https://github.com/zendframework/zend-validator/pull/58) adds a new `Uuid` validator, capable of validating if Versions 1-5 UUIDs are well-formed. - [#64](https://github.com/zendframework/zend-validator/pull/64) ports `Zend\ModuleManager\Feature\ValidatorProviderInterface` to `Zend\Validator\ValidatorProviderInterface`, and updates the `Module::init()` to typehint against the new interface instead of the one from zend-modulemanager. Applications targeting zend-mvc v3 can start updating their code to implement the new interface, or simply duck-type against it. ### Deprecated - Nothing. ### Removed - Nothing. ### Fixed - Nothing. ## 2.7.3 - 2016-05-16 ### Added - [#67](https://github.com/zendframework/zend-validator/pull/67) adds support for Punycoded top-level domains in the `Hostname` validator. - [#79](https://github.com/zendframework/zend-validator/pull/79) adds and publishes the documentation to https://zendframework.github.io/zend-validator/ ### Deprecated - Nothing. ### Removed - Nothing. ### Fixed - Nothing. ## 2.7.2 - 2016-04-18 ### Added - Nothing. ### Deprecated - Nothing. ### Removed - Nothing. ### Fixed - [#65](https://github.com/zendframework/zend-validator/pull/65) fixes the `Module::init()` method to properly receive a `ModuleManager` instance, and not expect a `ModuleEvent`. ## 2.7.1 - 2016-04-06 ### Added - Nothing. ### Deprecated - Nothing. ### Removed - Nothing. ### Fixed - This release updates the TLD list to the latest version from the IANA. ## 2.7.0 - 2016-04-06 ### Added - [#63](https://github.com/zendframework/zend-validator/pull/63) exposes the package as a ZF component and/or generic configuration provider, by adding the following: - `ValidatorPluginManagerFactory`, which can be consumed by container-interop / zend-servicemanager to create and return a `ValidatorPluginManager` instance. - `ConfigProvider`, which maps the service `ValidatorManager` to the above factory. - `Module`, which does the same as `ConfigProvider`, but specifically for zend-mvc applications. It also provices a specification to `Zend\ModuleManager\Listener\ServiceListener` to allow modules to provide validator configuration. ### Deprecated - Nothing. ### Removed - Nothing. ### Fixed - Nothing. ## 2.6.0 - 2016-02-17 ### Added - [#18](https://github.com/zendframework/zend-validator/pull/18) adds a `GpsPoint` validator for validating GPS coordinates. - [#47](https://github.com/zendframework/zend-validator/pull/47) adds two new classes, `Zend\Validator\Isbn\Isbn10` and `Isbn13`; these classes are the result of an extract class refactoring, and contain the logic specific to calcualting the checksum for each ISBN style. `Zend\Validator\Isbn` now instantiates the appropriate one and invokes it. - [#46](https://github.com/zendframework/zend-validator/pull/46) updates `Zend\Validator\Db\AbstractDb` to implement `Zend\Db\Adapter\AdapterAwareInterface`, by composing `Zend\Db\Adapter\AdapterAwareTrait`. ### Deprecated - Nothing. ### Removed - [#55](https://github.com/zendframework/zend-validator/pull/55) removes some checks for `safe_mode` within the `MimeType` validator, as `safe_mode` became obsolete starting with PHP 5.4. ### Fixed - [#45](https://github.com/zendframework/zend-validator/pull/45) fixes aliases mapping the deprecated `Float` and `Int` validators to their `Is*` counterparts. - [#49](https://github.com/zendframework/zend-validator/pull/49) [#50](https://github.com/zendframework/zend-validator/pull/50), and [#51](https://github.com/zendframework/zend-validator/pull/51) update the code to be forwards-compatible with zend-servicemanager and zend-stdlib v3. - [#56](https://github.com/zendframework/zend-validator/pull/56) fixes the regex in the `Ip` validator to escape `.` characters used as IP delimiters. ## 2.5.4 - 2016-02-17 ### Added - Nothing. ### Deprecated - Nothing. ### Removed - Nothing. ### Fixed - [#44](https://github.com/zendframework/zend-validator/pull/44) corrects the grammar on the `NOT_GREATER_INCLUSIVE` validation error message. - [#45](https://github.com/zendframework/zend-validator/pull/45) adds normalized aliases for the i18n isfloat/isint validators. - Updates the hostname validator regexes per the canonical service on which they are based. - [#52](https://github.com/zendframework/zend-validator/pull/52) updates the `Barcode` validator to cast empty options passed to the constructor to an empty array, fixing type mismatch errors. - [#54](https://github.com/zendframework/zend-validator/pull/54) fixes the IP address detection in the `Hostname` validator to ensure that IPv6 is detected correctly. - [#56](https://github.com/zendframework/zend-validator/pull/56) updates the regexes used by the `IP` validator when comparing ipv4 addresses to ensure a literal `.` is tested between network segments. ## 2.5.3 - 2015-09-03 ### Added - [#30](https://github.com/zendframework/zend-validator/pull/30) adds tooling to ensure that the Hostname TLD list stays up-to-date as changes are pushed for the repository. ### Deprecated - Nothing. ### Removed - Nothing. ### Fixed - [#17](https://github.com/zendframework/zend-validator/pull/17) and [#29](https://github.com/zendframework/zend-validator/pull/29) provide more test coverage, and fix a number of edge cases, primarily in validator option verifications. - [#26](https://github.com/zendframework/zend-validator/pull/26) fixes tests for `StaticValidator` such that they make correct assertions now. In doing so, we determined that it was possible to pass an indexed array of options, which could lead to unexpected results, often leading to false positives when validating. To correct this situation, `StaticValidator::execute()` now raises an `InvalidArgumentException` when an indexed array is detected for the `$options` argument. - [#35](https://github.com/zendframework/zend-validator/pull/35) modifies the `NotEmpty` validator to no longer treat the float `0.0` as an empty value for purposes of validation. - [#25](https://github.com/zendframework/zend-validator/pull/25) fixes the `Date` validator to check against `DateTimeImmutable` and not `DateTimeInterface` (as PHP has restrictions currently on how the latter can be used). ## 2.5.2 - 2015-07-16 ### Added - [#8](https://github.com/zendframework/zend-validator/pull/8) adds a "strict" configuration option; when enabled (the default), the length of the address is checked to ensure it follows the specification. ### Deprecated - Nothing. ### Removed - Nothing. ### Fixed - [#8](https://github.com/zendframework/zend-validator/pull/8) fixes bad behavior on the part of the `idn_to_utf8()` function, returning the original address in the case that the function fails. - [#11](https://github.com/zendframework/zend-validator/pull/11) fixes `ValidatorChain::prependValidator()` so that it works on HHVM. - [#12](https://github.com/zendframework/zend-validator/pull/12) adds "6772" to the Maestro range of the `CreditCard` validator. ================================================ FILE: LICENSE.md ================================================ Copyright (c) 2005-2019, Zend Technologies USA, Inc. All 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. - Neither the name of Zend Technologies USA, Inc. nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. ================================================ FILE: README.md ================================================ # zend-validator > ## Repository abandoned 2019-12-31 > > This repository has moved to [laminas/laminas-validator](https://github.com/laminas/laminas-validator). [![Build Status](https://secure.travis-ci.org/zendframework/zend-validator.svg?branch=master)](https://secure.travis-ci.org/zendframework/zend-validator) [![Coverage Status](https://coveralls.io/repos/github/zendframework/zend-validator/badge.svg?branch=master)](https://coveralls.io/github/zendframework/zend-validator?branch=master) zend-validator provides a set of commonly needed validators. It also provides a simple validator chaining mechanism by which multiple validators may be applied to a single datum in a user-defined order. ## Installation Run the following to install this library: ```bash $ composer require zendframework/zend-validator ``` ## Documentation Browse the documentation online at https://docs.zendframework.com/zend-validator/ ## Support * [Issues](https://github.com/zendframework/zend-validator/issues/) * [Chat](https://zendframework-slack.herokuapp.com/) * [Forum](https://discourse.zendframework.com/) ================================================ FILE: bin/update_hostname_validator.php ================================================ getBody(), "\n")); $validatorVersion = getVersionFromString('IanaVersion', file_get_contents(ZF2_HOSTNAME_VALIDATOR_FILE)); if ($checkOnly && $ianaVersion > $validatorVersion) { printf( 'TLDs must be updated, please run `php bin/update_hostname_validator.php` and push your changes%s', PHP_EOL ); exit(1); } if ($checkOnly) { printf('TLDs are up-to-date%s', PHP_EOL); exit(0); } foreach (file(ZF2_HOSTNAME_VALIDATOR_FILE) as $line) { // Replace old version number with new one if (preg_match('/\*\s+IanaVersion\s+\d+/', $line, $matches)) { $newFileContent[] = sprintf(" * IanaVersion %s\n", $ianaVersion); continue; } if ($insertDone === $insertFinish) { // Outside of $validTlds definition; keep line as-is $newFileContent[] = $line; } if ($insertFinish) { continue; } if ($insertDone) { // Detect where the $validTlds declaration ends if (preg_match('/^\s+\];\s*$/', $line)) { $newFileContent[] = $line; $insertFinish = true; } continue; } // Detect where the $validTlds declaration begins if (preg_match('/^\s+protected\s+\$validTlds\s+=\s+\[\s*$/', $line)) { $newFileContent = array_merge($newFileContent, getNewValidTlds($response->getBody())); $insertDone = true; } } if (! $insertDone) { printf('Error: cannot find line with "protected $validTlds"%s', PHP_EOL); exit(1); } if (!$insertFinish) { printf('Error: cannot find end of $validTlds declaration%s', PHP_EOL); exit(1); } if (false === @file_put_contents(ZF2_HOSTNAME_VALIDATOR_FILE, $newFileContent)) { printf('Error: cannot write info file "%s"%s', ZF2_HOSTNAME_VALIDATOR_FILE, PHP_EOL); exit(1); } printf('Validator TLD file updated.%s', PHP_EOL); exit(0); /** * Get Official TLDs * * @return \Zend\Http\Response * @throws Exception */ function getOfficialTLDs() { $client = new Client(); $client->setOptions([ 'adapter' => 'Zend\Http\Client\Adapter\Curl', ]); $client->setUri(IANA_URL); $client->setMethod('GET'); $response = $client->send(); if (! $response->isSuccess()) { throw new \Exception(sprintf("Error: cannot get '%s'%s", IANA_URL, PHP_EOL)); } return $response; } /** * Extract the first match of a string like * "Version 2015072300" from the given string * * @param string $prefix * @param string $string * @return string * @throws Exception */ function getVersionFromString($prefix, $string) { $matches = []; if (! preg_match(sprintf('/%s\s+((\d+)?)/', $prefix), $string, $matches)) { throw new Exception('Error: cannot get last update date'); } return $matches[1]; } /** * Extract new Valid TLDs from a string containing one per line. * * @param string $string * @return array */ function getNewValidTlds($string) { $decodePunycode = getPunycodeDecoder(); // Get new TLDs from the list previously fetched $newValidTlds = []; foreach (preg_grep('/^[^#]/', preg_split("#\r?\n#", $string)) as $line) { $newValidTlds []= sprintf( "%s'%s',\n", str_repeat(' ', 8), $decodePunycode(strtolower($line)) ); } return $newValidTlds; } /** * Retrieve and return a punycode decoder. * * TLDs are puny encoded. * * We need a decodePunycode function to translate TLDs to UTF-8: * * - use idn_to_utf8 if available * - otherwise, use Hostname::decodePunycode() * * @return callable */ function getPunycodeDecoder() { if (function_exists('idn_to_utf8')) { return function ($domain) { return idn_to_utf8($domain, 0, INTL_IDNA_VARIANT_UTS46); }; } $hostnameValidator = new Hostname(); $reflection = new ReflectionClass(get_class($hostnameValidator)); $decodePunyCode = $reflection->getMethod('decodePunycode'); $decodePunyCode->setAccessible(true); return function ($encode) use ($hostnameValidator, $decodePunyCode) { if (strpos($encode, 'xn--') === 0) { return $decodePunyCode->invokeArgs($hostnameValidator, [substr($encode, 4)]); } return $encode; }; } ================================================ FILE: composer.json ================================================ { "name": "zendframework/zend-validator", "description": "Validation classes for a wide range of domains, and the ability to chain validators to create complex validation criteria", "license": "BSD-3-Clause", "keywords": [ "zendframework", "zf", "validator" ], "support": { "docs": "https://docs.zendframework.com/zend-validator/", "issues": "https://github.com/zendframework/zend-validator/issues", "source": "https://github.com/zendframework/zend-validator", "rss": "https://github.com/zendframework/zend-validator/releases.atom", "chat": "https://zendframework-slack.herokuapp.com", "forum": "https://discourse.zendframework.com/c/questions/components" }, "require": { "php": "^7.1", "zendframework/zend-stdlib": "^3.2.1", "container-interop/container-interop": "^1.1" }, "require-dev": { "phpunit/phpunit": "^6.0.8 || ^5.7.15", "psr/http-message": "^1.0", "psr/http-client": "^1.0", "psr/http-factory": "^1.0", "zendframework/zend-cache": "^2.6.1", "zendframework/zend-coding-standard": "~1.0.0", "zendframework/zend-config": "^2.6", "zendframework/zend-db": "^2.7", "zendframework/zend-filter": "^2.6", "zendframework/zend-http": "^2.5.4", "zendframework/zend-i18n": "^2.6", "zendframework/zend-math": "^2.6", "zendframework/zend-servicemanager": "^2.7.5 || ^3.0.3", "zendframework/zend-session": "^2.8", "zendframework/zend-uri": "^2.5" }, "suggest": { "psr/http-message": "psr/http-message, required when validating PSR-7 UploadedFileInterface instances via the Upload and UploadFile validators", "zendframework/zend-db": "Zend\\Db component, required by the (No)RecordExists validator", "zendframework/zend-filter": "Zend\\Filter component, required by the Digits validator", "zendframework/zend-i18n": "Zend\\I18n component to allow translation of validation error messages", "zendframework/zend-math": "Zend\\Math component, required by the Csrf validator", "zendframework/zend-i18n-resources": "Translations of validator messages", "zendframework/zend-servicemanager": "Zend\\ServiceManager component to allow using the ValidatorPluginManager and validator chains", "zendframework/zend-session": "Zend\\Session component, ^2.8; required by the Csrf validator", "zendframework/zend-uri": "Zend\\Uri component, required by the Uri and Sitemap\\Loc validators" }, "autoload": { "psr-4": { "Zend\\Validator\\": "src/" } }, "autoload-dev": { "psr-4": { "ZendTest\\Validator\\": "test/" } }, "config": { "sort-packages": true }, "extra": { "branch-alias": { "dev-master": "2.13.x-dev", "dev-develop": "2.14.x-dev" }, "zf": { "component": "Zend\\Validator", "config-provider": "Zend\\Validator\\ConfigProvider" } }, "scripts": { "check": [ "@cs-check", "@test" ], "cs-check": "phpcs", "cs-fix": "phpcbf", "test": "phpunit --colors=always", "test-coverage": "phpunit --colors=always --coverage-clover clover.xml" } } ================================================ FILE: docs/CODE_OF_CONDUCT.md ================================================ # Contributor Code of Conduct This project adheres to [The Code Manifesto](http://codemanifesto.com) as its guidelines for contributor interactions. ## The Code Manifesto We want to work in an ecosystem that empowers developers to reach their potential — one that encourages growth and effective collaboration. A space that is safe for all. A space such as this benefits everyone that participates in it. It encourages new developers to enter our field. It is through discussion and collaboration that we grow, and through growth that we improve. In the effort to create such a place, we hold to these values: 1. **Discrimination limits us.** This includes discrimination on the basis of race, gender, sexual orientation, gender identity, age, nationality, technology and any other arbitrary exclusion of a group of people. 2. **Boundaries honor us.** Your comfort levels are not everyone’s comfort levels. Remember that, and if brought to your attention, heed it. 3. **We are our biggest assets.** None of us were born masters of our trade. Each of us has been helped along the way. Return that favor, when and where you can. 4. **We are resources for the future.** As an extension of #3, share what you know. Make yourself a resource to help those that come after you. 5. **Respect defines us.** Treat others as you wish to be treated. Make your discussions, criticisms and debates from a position of respectfulness. Ask yourself, is it true? Is it necessary? Is it constructive? Anything less is unacceptable. 6. **Reactions require grace.** Angry responses are valid, but abusive language and vindictive actions are toxic. When something happens that offends you, handle it assertively, but be respectful. Escalate reasonably, and try to allow the offender an opportunity to explain themselves, and possibly correct the issue. 7. **Opinions are just that: opinions.** Each and every one of us, due to our background and upbringing, have varying opinions. The fact of the matter, is that is perfectly acceptable. Remember this: if you respect your own opinions, you should respect the opinions of others. 8. **To err is human.** You might not intend it, but mistakes do happen and contribute to build experience. Tolerate honest mistakes, and don't hesitate to apologize if you make one yourself. ================================================ FILE: docs/CONTRIBUTING.md ================================================ # CONTRIBUTING ## RESOURCES If you wish to contribute to this project, please be sure to read/subscribe to the following resources: - [Coding Standards](https://github.com/zendframework/zend-coding-standard) - [Forums](https://discourse.zendframework.com/c/contributors) - [Chat](https://zendframework-slack.herokuapp.com) - [Code of Conduct](CODE_OF_CONDUCT.md) If you are working on new features or refactoring [create a proposal](https://github.com/zendframework/zend-validator/issues/new). ## RUNNING TESTS To run tests: - Clone the repository: ```console $ git clone git://github.com/zendframework/zend-validator.git $ cd zend-validator ``` - Install dependencies via composer: ```console $ composer install ``` If you don't have `composer` installed, please download it from https://getcomposer.org/download/ - Run the tests using the "test" command shipped in the `composer.json`: ```console $ composer test ``` You can turn on conditional tests with the `phpunit.xml` file. To do so: - Copy `phpunit.xml.dist` file to `phpunit.xml` - Edit `phpunit.xml` to enable any specific functionality you want to test, as well as to provide test values to utilize. ## Running Coding Standards Checks First, ensure you've installed dependencies via composer, per the previous section on running tests. To run CS checks only: ```console $ composer cs-check ``` To attempt to automatically fix common CS issues: ```console $ composer cs-fix ``` If the above fixes any CS issues, please re-run the tests to ensure they pass, and make sure you add and commit the changes after verification. ## Recommended Workflow for Contributions Your first step is to establish a public repository from which we can pull your work into the master repository. We recommend using [GitHub](https://github.com), as that is where the component is already hosted. 1. Setup a [GitHub account](https://github.com/), if you haven't yet 2. Fork the repository (https://github.com/zendframework/zend-validator) 3. Clone the canonical repository locally and enter it. ```console $ git clone git://github.com/zendframework/zend-validator.git $ cd zend-validator ``` 4. Add a remote to your fork; substitute your GitHub username in the command below. ```console $ git remote add {username} git@github.com:{username}/zend-validator.git $ git fetch {username} ``` ### Keeping Up-to-Date Periodically, you should update your fork or personal repository to match the canonical ZF repository. Assuming you have setup your local repository per the instructions above, you can do the following: ```console $ git checkout master $ git fetch origin $ git rebase origin/master # OPTIONALLY, to keep your remote up-to-date - $ git push {username} master:master ``` If you're tracking other branches -- for example, the "develop" branch, where new feature development occurs -- you'll want to do the same operations for that branch; simply substitute "develop" for "master". ### Working on a patch We recommend you do each new feature or bugfix in a new branch. This simplifies the task of code review as well as the task of merging your changes into the canonical repository. A typical workflow will then consist of the following: 1. Create a new local branch based off either your master or develop branch. 2. Switch to your new local branch. (This step can be combined with the previous step with the use of `git checkout -b`.) 3. Do some work, commit, repeat as necessary. 4. Push the local branch to your remote repository. 5. Send a pull request. The mechanics of this process are actually quite trivial. Below, we will create a branch for fixing an issue in the tracker. ```console $ git checkout -b hotfix/9295 Switched to a new branch 'hotfix/9295' ``` ... do some work ... ```console $ git commit ``` ... write your log message ... ```console $ git push {username} hotfix/9295:hotfix/9295 Counting objects: 38, done. Delta compression using up to 2 threads. Compression objects: 100% (18/18), done. Writing objects: 100% (20/20), 8.19KiB, done. Total 20 (delta 12), reused 0 (delta 0) To ssh://git@github.com/{username}/zend-validator.git b5583aa..4f51698 HEAD -> master ``` To send a pull request, you have two options. If using GitHub, you can do the pull request from there. Navigate to your repository, select the branch you just created, and then select the "Pull Request" button in the upper right. Select the user/organization "zendframework" (or whatever the upstream organization is) as the recipient. #### What branch to issue the pull request against? Which branch should you issue a pull request against? - For fixes against the stable release, issue the pull request against the "master" branch. - For new features, or fixes that introduce new elements to the public API (such as new public methods or properties), issue the pull request against the "develop" branch. ### Branch Cleanup As you might imagine, if you are a frequent contributor, you'll start to get a ton of branches both locally and on your remote. Once you know that your changes have been accepted to the master repository, we suggest doing some cleanup of these branches. - Local branch cleanup ```console $ git branch -d ``` - Remote branch removal ```console $ git push {username} : ``` ================================================ FILE: docs/ISSUE_TEMPLATE.md ================================================ - [ ] I was not able to find an [open](https://github.com/zendframework/zend-validator/issues?q=is%3Aopen) or [closed](https://github.com/zendframework/zend-validator/issues?q=is%3Aclosed) issue matching what I'm seeing. - [ ] This is not a question. (Questions should be asked on [chat](https://zendframework.slack.com/) ([Signup here](https://zendframework-slack.herokuapp.com/)) or our [forums](https://discourse.zendframework.com/).) Provide a narrative description of what you are trying to accomplish. ### Code to reproduce the issue ```php ``` ### Expected results ### Actual results ================================================ FILE: docs/PULL_REQUEST_TEMPLATE.md ================================================ Provide a narrative description of what you are trying to accomplish: - [ ] Are you fixing a bug? - [ ] Detail how the bug is invoked currently. - [ ] Detail the original, incorrect behavior. - [ ] Detail the new, expected behavior. - [ ] Base your feature on the `master` branch, and submit against that branch. - [ ] Add a regression test that demonstrates the bug, and proves the fix. - [ ] Add a `CHANGELOG.md` entry for the fix. - [ ] Are you creating a new feature? - [ ] Why is the new feature needed? What purpose does it serve? - [ ] How will users use the new feature? - [ ] Base your feature on the `develop` branch, and submit against that branch. - [ ] Add only one feature per pull request; split multiple features over multiple pull requests - [ ] Add tests for the new feature. - [ ] Add documentation for the new feature. - [ ] Add a `CHANGELOG.md` entry for the new feature. - [ ] Is this related to quality assurance? - [ ] Is this related to documentation? ================================================ FILE: docs/SUPPORT.md ================================================ # Getting Support Zend Framework offers three support channels: - For real-time questions, use our [chat](https://zendframework-slack.herokuapp.com) - For detailed questions (e.g., those requiring examples) use our [forums](https://discourse.zendframework.com/c/questions/components) - To report issues, use this repository's [issue tracker](https://github.com/zendframework/zend-validator/issues/new) **DO NOT** use the issue tracker to ask questions; use chat or the forums for that. Questions posed to the issue tracker will be closed. When reporting an issue, please include the following details: - A narrative description of what you are trying to accomplish. - The minimum code necessary to reproduce the issue. - The expected results of exercising that code. - The actual results received. We may ask for additional details: what version of the library you are using, and what PHP version was used to reproduce the issue. You may also submit a failing test case as a pull request. ================================================ FILE: docs/book/index.md ================================================ ../../README.md ================================================ FILE: docs/book/intro.md ================================================ # Introduction zend-validator provides a set of commonly needed validators. It also provides a simple validator chaining mechanism by which multiple validators may be applied to a single datum in a user-defined order. ## What is a validator? A validator examines its input with respect to some requirements and produces a boolean result indicating whether the input successfully validates against the requirements. If the input does not meet the requirements, a validator may additionally provide information about which requirement(s) the input does not meet. For example, a web application might require that a username be between six and twelve characters in length, and may only contain alphanumeric characters. A validator can be used for ensuring that a username meets these requirements. If a chosen username does not meet one or both of the requirements, it would be useful to know which of the requirements the username fails to meet. ## Basic usage of validators Having defined validation in this way provides the foundation for `Zend\Validator\ValidatorInterface`, which defines two methods, `isValid()` and `getMessages()`. The `isValid()` method performs validation upon the provided value, returning `true` if and only if the value passes against the validation criteria. If `isValid()` returns `false`, the `getMessages()` method will return an array of messages explaining the reason(s) for validation failure. The array keys are short strings that identify the reasons for validation failure, and the array values are the corresponding human-readable string messages. The keys and values are class-dependent; each validation class defines its own set of validation failure messages and the unique keys that identify them. Each class also has a `const` definition that matches each identifier for a validation failure cause. > ### Stateful validators > > The `getMessages()` methods return validation failure information only for the > most recent `isValid()` call. Each call to `isValid()` clears any messages and > errors caused by a previous `isValid()` call, because it's likely that each > call to `isValid()` is made for a different input value. The following example illustrates validation of an e-mail address: ```php use Zend\Validator\EmailAddress; $validator = new EmailAddress(); if ($validator->isValid($email)) { // email appears to be valid } else { // email is invalid; print the reasons foreach ($validator->getMessages() as $messageId => $message) { printf("Validation failure '%s': %s\n", $messageId, $message); } } ``` ## Customizing messages Validator classes provide a `setMessage()` method with which you can specify the format of a message returned by `getMessages()` in case of validation failure. The first argument of this method is a string containing the error message. You can include tokens in this string which will be substituted with data relevant to the validator. The token `%value%` is supported by all validators; this is substituted with the value you passed to `isValid()`. Other tokens may be supported on a case-by-case basis in each validation class. For example, `%max%` is a token supported by `Zend\Validator\LessThan`. The `getMessageVariables()` method returns an array of variable tokens supported by the validator. The second optional argument is a string that identifies the validation failure message template to be set, which is useful when a validation class defines more than one cause for failure. If you omit the second argument, `setMessage()` assumes the message you specify should be used for the first message template declared in the validation class. Many validation classes only have one error message template defined, so there is no need to specify which message template you are changing. ```php use Zend\Validator\StringLength; $validator = new StringLength(8); $validator->setMessage( 'The string \'%value%\' is too short; it must be at least %min% characters', StringLength::TOO_SHORT ); if (! $validator->isValid('word')) { $messages = $validator->getMessages(); echo current($messages); // "The string 'word' is too short; it must be at least 8 characters" } ``` You can set multiple messages using the `setMessages()` method. Its argument is an array containing key/message pairs. ```php use Zend\Validator\StringLength; $validator = new StringLength(['min' => 8, 'max' => 12]); $validator->setMessages([ StringLength::TOO_SHORT => 'The string \'%value%\' is too short', StringLength::TOO_LONG => 'The string \'%value%\' is too long', ]); ``` If your application requires even greater flexibility with which it reports validation failures, you can access properties by the same name as the message tokens supported by a given validation class. The `value` property is always available in a validator; it is the value you specified as the argument of `isValid()`. Other properties may be supported on a case-by-case basis in each validation class. ```php use Zend\Validator\StringLength; $validator = new StringLength(['min' => 8, 'max' => 12]); if (! $validator->isValid('word')) { printf( "Word failed: %s; its length is not between %d and %d\n", $validator->value, $validator->min, $validator->max ); } ``` ## Translating messages > ### Installation requirements > > The translation of validator messages depends on the zend-i18n component, so > be sure to have it installed before getting started: > > ```bash > $ composer require zendframework/zend-i18n > ``` Validator classes provide a `setTranslator()` method with which you can specify an instance of `Zend\Validator\Translator\TranslatorInterface` which will translate the messages in case of a validation failure. The `getTranslator()` method returns the translator instance. `Zend\Mvc\I18n\Translator` provides an implementation compatible with the validator component. ```php use Zend\Mvc\I18n\Translator; use Zend\Validator\StringLength; $validator = new StringLength(['min' => 8, 'max' => 12]); $translate = new Translator(); // configure the translator... $validator->setTranslator($translate); ``` With the static `AbstractValidator::setDefaultTranslator()` method you can set a instance of `Zend\Validator\Translator\TranslatorInterface` which will be used for all validation classes, and can be retrieved with `getDefaultTranslator()`. This prevents the need for setting a translator manually with each validator. ```php use Zend\Mvc\I18n\Translator; use Zend\Validator\AbstractValidator; $translate = new Translator(); // configure the translator... AbstractValidator::setDefaultTranslator($translate); ``` Sometimes it is necessary to disable the translator within a validator. To achieve this you can use the `setDisableTranslator()` method, which accepts a boolean parameter, and `isTranslatorDisabled()` to get the set value. ```php use Zend\Validator\StringLength; $validator = new StringLength(['min' => 8, 'max' => 12]); if (! $validator->isTranslatorDisabled()) { $validator->setDisableTranslator(); } ``` It is also possible to use a translator instead of setting own messages with `setMessage()`. But doing so, you should keep in mind, that the translator works also on messages you set your own. > ### Translation compatibility > > In versions 2.0 - 2.1, `Zend\Validator\AbstractValidator` implemented > `Zend\I18n\Translator\TranslatorAwareInterface` and accepted instances of > `Zend\I18n\Translator\Translator`. Starting in version 2.2.0, zend-validator > now defines a translator interface, > `Zend\Validator\Translator\TranslatorInterface`, > as well as it's own -aware variant, > `Zend\Validator\Translator\TranslatorAwareInterface`. > This was done to reduce dependencies for the component, and follows the > principal of Separated Interfaces. > > The upshot is that if you are migrating from a pre-2.2 version, and receiving > errors indicating that the translator provided does not implement > `Zend\Validator\Translator\TranslatorInterface`, you will need to make a > change to your code. > > An implementation of `Zend\Validator\Translator\TranslatorInterface` is > provided in `Zend\Mvc\I18n\Translator`, which also extends > `Zend\I18n\Translator\Translator`. This version can be instantiated and used > just as the original `Zend\I18n` version. > > A new service has also been registered with the MVC, `MvcTranslator`, which > will return this specialized, bridge instance. > > Most users should see no issues, as `Zend\Validator\ValidatorPluginManager` > has been modified to use the `MvcTranslator` service internally, which is how > most developers were getting the translator instance into validators in the > first place. You will only need to change code if you were manually injecting > the instance previously. ================================================ FILE: docs/book/messages.md ================================================ # Validation Messages Each validator based on `Zend\Validator\ValidatorInterface` provides one or multiple messages in the case of a failed validation. You can use this information to set your own messages, or to translate existing messages which a validator could return to something different. Validation messages are defined as constant/template pairs, with the constant representing a translation key. Such constants are defined per-class. Let's look into `Zend\Validator\GreaterThan` for a descriptive example: ```php protected $messageTemplates = [ self::NOT_GREATER => "'%value%' is not greater than '%min%'", ]; ``` The constant `self::NOT_GREATER` refers to the failure and is used as the message key, and the message template itself is used as the value within the message array. You can retrieve all message templates from a validator by using the `getMessageTemplates()` method. It returns the above array containing all messages a validator could return in the case of a failed validation. ```php $validator = new Zend\Validator\GreaterThan(); $messages = $validator->getMessageTemplates(); ``` Using the `setMessage()` method you can set another message to be returned in case of the specified failure. ```php use Zend\Validator\GreaterThan; $validator = new GreaterThan(); $validator->setMessage('Please enter a lower value', GreaterThan::NOT_GREATER); ``` The second parameter defines the failure which will be overridden. When you omit this parameter, then the given message will be set for all possible failures of this validator. ## Using pre-translated validation messages zend-validator is shipped with more than 45 different validators with more than 200 failure messages. It can be a tedious task to translate all of these messages. For your convenience, pre-translated messages are provided in the [zendframework/zend-i18n-resources](https://docs.zendframework.com/zend-i18n-resources/) package: ```bash $ composer require zendframework/zend-i18n-resources ``` To translate all validation messages to German for example, attach a translator to `Zend\Validator\AbstractValidator` using these resource files. ```php use Zend\I18n\Translator\Resources; use Zend\Mvc\I18n\Translator; use Zend\Validator\AbstractValidator; $translator = new Zend\Mvc\I18n\Translator(); $translator->addTranslationFilePattern( 'phpArray', Resources::getBasePath(), Resources::getPatternForValidator() ); AbstractValidator::setDefaultTranslator($translator); ``` > ### Supported languages > > The supported languages may not be complete. New languages will be added with > each release. Additionally feel free to use the existing resource files to > make your own translations. > > You could also use these resource files to rewrite existing translations. So > you are not in need to create these files manually yourself. ## Limit the size of a validation message Sometimes it is necessary to limit the maximum size a validation message can have; as an example, when your view allows a maximum size of 100 chars to be rendered on one line. To enable this, `Zend\Validator\AbstractValidator` is able to automatically limit the maximum returned size of a validation message. To get the actual set size use `Zend\Validator\AbstractValidator::getMessageLength()`. If it is `-1`, then the returned message will not be truncated. This is default behaviour. To limit the returned message size, use `Zend\Validator\AbstractValidator::setMessageLength()`. Set it to any integer size you need. When the returned message exceeds the set size, then the message will be truncated and the string `**...**` will be added instead of the rest of the message. ```php Zend\Validator\AbstractValidator::setMessageLength(100); ``` > ### Where is this parameter used? > > The set message length is used for all validators, even for self defined ones, > as long as they extend `Zend\Validator\AbstractValidator`. ================================================ FILE: docs/book/set.md ================================================ # Standard Validation Classes The following validators come with the zend-validator distribution. - [Barcode](validators/barcode.md) - [Between](validators/between.md) - [Callback](validators/callback.md) - [CreditCard](validators/credit-card.md) - [Date](validators/date.md) - [RecordExists and NoRecordExists (database)](validators/db.md) - [Digits](validators/digits.md) - [EmailAddress](validators/email-address.md) - [Explode](validators/explode.md) - [File Validation Classes](validators/file/intro.md) - [GreaterThan](validators/greater-than.md) - [Hex](validators/hex.md) - [Hostname](validators/hostname.md) - [Iban](validators/iban.md) - [Identical](validators/identical.md) - [InArray](validators/in-array.md) - [Ip](validators/ip.md) - [Isbn](validators/isbn.md) - [IsCountable](validators/is-countable.md) - [IsInstanceOf](validators/isinstanceof.md) - [LessThan](validators/less-than.md) - [NotEmpty](validators/not-empty.md) - [Regex](validators/regex.md) - [Sitemap](validators/sitemap.md) - [Step](validators/step.md) - [StringLength](validators/string-length.md) - [Timezone](validators/timezone.md) - [Uri](validators/uri.md) - [Uuid](validators/uuid.md) ## Additional validators Several other components offer validators as well: - [zend-i18n](https://docs.zendframework.com/zend-i18n/validators/) ## Deprecated Validators ### Ccnum The `Ccnum` validator has been deprecated in favor of the `CreditCard` validator. For security reasons you should use `CreditCard` instead of `Ccnum`. ================================================ FILE: docs/book/validator-chains.md ================================================ # Validator Chains ## Basic Usage > ### Installation requirements > > The validator chain depends on the zend-servicemanager component, so be sure > to have it installed before getting started: > > ```bash > $ composer require zendframework/zend-servicemanager > ``` Often, multiple validations should be applied to some value in a particular order. The following code demonstrates a way to solve the example from the [introduction](intro.md), where a username must be between 6 and 12 alphanumeric characters: ```php use Zend\I18n\Validator\Alnum; use Zend\Validator\StringLength; use Zend\Validator\ValidatorChain; // Create a validator chain and add validators to it $validatorChain = new ValidatorChain(); $validatorChain->attach(new StringLength(['min' => 6, 'max' => 12])); $validatorChain->attach(new Alnum()); // Validate the username if ($validatorChain->isValid($username)) { // username passed validation } else { // username failed validation; print reasons foreach ($validatorChain->getMessages() as $message) { echo "$message\n"; } } ``` Validators are run in the order they were added to the `ValidatorChain`. In the above example, the username is first checked to ensure that its length is between 6 and 12 characters, and then it is checked to ensure that it contains only alphanumeric characters. The second validation, for alphanumeric characters, is performed regardless of whether the first validation, for length between 6 and 12 characters, succeeds. This means that if both validations fail, `getMessages()` will return failure messages from both validators. In some cases, it makes sense to have a validator *break the chain* if its validation process fails. `ValidatorChain` supports such use cases with the second parameter to the `attach()` method. By setting `$breakChainOnFailure` to `true`, if the validator fails, it will short-circuit execution of the chain, preventing subsequent validators from executing. If the above example were written as follows, then the alphanumeric validation would not occur if the string length validation fails: ```php $chain->attach(new StringLength(['min' => 6, 'max' => 12]), true); $chain->attach(new Alnum()); ``` Any object that implements `Zend\Validator\ValidatorInterface` may be used in a validator chain. ## Setting Validator Chain Order For each validator added to the `ValidatorChain`, you can set a *priority* to define the chain order. The default value is `1`. Higher values indicate earlier execution, while lower values execute later; use negative values to force late execution. In the following example, the username is first checked to ensure that its length is between 7 and 9 characters, and then it is checked to ensure that its length is between 3 and 5 characters. ```php use Zend\I18n\Validator\Alnum; use Zend\Validator\StringLength; use Zend\Validator\ValidatorChain; $username = 'ABCDFE'; // Create a validator chain and add validators to it $validatorChain = new ValidatorChain(); $validatorChain->attach( new StringLength(['min' => 3, 'max' => 5]), true, // break chain on failure 1 ); $validatorChain->attach( new StringLength(['min' => 7, 'max' => 9]), true, // break chain on failure 2 // higher priority! ); // Validate the username if ($validatorChain->isValid($username)) { // username passed validation echo "Success"; } else { // username failed validation; print reasons foreach ($validatorChain->getMessages() as $message) { echo "$message\n"; } } // This first example will display: The input is less than 7 characters long ``` ================================================ FILE: docs/book/validators/barcode.md ================================================ # Barcode Validator `Zend\Validator\Barcode` allows you to check if a given value can be represented as a barcode. ## Supported barcodes `Zend\Validator\Barcode` supports multiple barcode standards and can be extended with proprietary barcode implementations. The following barcode standards are supported: ### CODABAR Also known as Code-a-bar. This barcode has no length limitation. It supports only digits, and 6 special chars. Codabar is a self-checking barcode. This standard is very old. Common use cases are within airbills or photo labs where multi-part forms are used with dot-matrix printers. ### CODE128 CODE128 is a high density barcode. This barcode has no length limitation. It supports the first 128 ascii characters. When used with printing characters it has an checksum which is calculated modulo 103. This standard is used worldwide as it supports upper and lowercase characters. ### CODE25 Often called "two of five" or "Code25 Industrial". This barcode has no length limitation. It supports only digits, and the last digit can be an optional checksum which is calculated with modulo 10. This standard is very old and nowadays not often used. Common use cases are within the industry. ### CODE25INTERLEAVED Often called "Code 2 of 5 Interleaved". This standard is a variant of CODE25. It has no length limitation, but it must contain an even amount of characters. It supports only digits, and the last digit can be an optional checksum which is calculated with modulo 10. It is used worldwide and common on the market. ### CODE39 CODE39 is one of the oldest available codes. This barcode has a variable length. It supports digits, upper cased alphabetical characters and 7 special characters like whitespace, point and dollar sign. It can have an optional checksum which is calculated with modulo 43. This standard is used worldwide and common within the industry. ### CODE39EXT CODE39EXT is an extension of CODE39. This barcode has the same properties as CODE39. Additionally it allows the usage of all 128 ASCII characters. This standard is used worldwide and common within the industry. ### CODE93 CODE93 is the successor of CODE39. This barcode has a variable length. It supports digits, alphabetical characters and 7 special characters. It has an optional checksum which is calculated with modulo 47 and contains 2 characters. This standard produces a denser code than CODE39 and is more secure. ### CODE93EXT CODE93EXT is an extension of CODE93. This barcode has the same properties as CODE93. Additionally it allows the usage of all 128 ASCII characters. This standard is used worldwide and common within the industry. ### EAN2 EAN is the shortcut for "European Article Number". These barcode must have 2 characters. It supports only digits and does not have a checksum. This standard is mainly used as addition to EAN13 (ISBN) when printed on books. ### EAN5 EAN is the shortcut for "European Article Number". These barcode must have 5 characters. It supports only digits and does not have a checksum. This standard is mainly used as addition to EAN13 (ISBN) when printed on books. ### EAN8 EAN is the shortcut for "European Article Number". These barcode can have 7 or 8 characters. It supports only digits. When it has a length of 8 characters it includes a checksum. This standard is used worldwide but has a very limited range. It can be found on small articles where a longer barcode could not be printed. ### EAN12 EAN is the shortcut for "European Article Number". This barcode must have a length of 12 characters. It supports only digits, and the last digit is always a checksum which is calculated with modulo 10. This standard is used within the USA and common on the market. It has been superseded by EAN13. ### EAN13 EAN is the shortcut for "European Article Number". This barcode must have a length of 13 characters. It supports only digits, and the last digit is always a checksum which is calculated with modulo 10. This standard is used worldwide and common on the market. ### EAN14 EAN is the shortcut for "European Article Number". This barcode must have a length of 14 characters. It supports only digits, and the last digit is always a checksum which is calculated with modulo 10. This standard is used worldwide and common on the market. It is the successor for EAN13. ### EAN18 EAN is the shortcut for "European Article Number". This barcode must have a length of 18 characters. It support only digits. The last digit is always a checksum digit which is calculated with modulo 10. This code is often used for the identification of shipping containers. ### GTIN12 GTIN is the shortcut for "Global Trade Item Number". This barcode uses the same standard as EAN12 and is its successor. It's commonly used within the USA. ### GTIN13 GTIN is the shortcut for "Global Trade Item Number". This barcode uses the same standard as EAN13 and is its successor. It is used worldwide by industry. ### GTIN14 GTIN is the shortcut for "Global Trade Item Number". This barcode uses the same standard as EAN14 and is its successor. It is used worldwide and common on the market. ### IDENTCODE Identcode is used by Deutsche Post and DHL. It's an specialized implementation of Code25. This barcode must have a length of 12 characters. It supports only digits, and the last digit is always a checksum which is calculated with modulo 10. This standard is mainly used by the companies DP and DHL. ### INTELLIGENTMAIL Intelligent Mail is a postal barcode. This barcode can have a length of 20, 25, 29 or 31 characters. It supports only digits, and contains no checksum. This standard is the successor of PLANET and POSTNET. It is mainly used by the United States Postal Services. ### ISSN ISSN is the abbreviation for International Standard Serial Number. This barcode can have a length of 8 or 13 characters. It supports only digits, and the last digit must be a checksum digit which is calculated with modulo 11. It is used worldwide for printed publications. ### ITF14 ITF14 is the GS1 implementation of an Interleaved Two of Five bar code. This barcode is a special variant of Interleaved 2 of 5. It must have a length of 14 characters and is based on GTIN14. It supports only digits, and the last digit must be a checksum digit which is calculated with modulo 10. It is used worldwide and common within the market. ### LEITCODE Leitcode is used by Deutsche Post and DHL. It's an specialized implementation of Code25. This barcode must have a length of 14 characters. It supports only digits, and the last digit is always a checksum which is calculated with modulo 10. This standard is mainly used by the companies DP and DHL. ### PLANET Planet is the abbreviation for Postal Alpha Numeric Encoding Technique. This barcode can have a length of 12 or 14 characters. It supports only digits, and the last digit is always a checksum. This standard is mainly used by the United States Postal Services. ### POSTNET Postnet is used by the US Postal Service. This barcode can have a length of 6, 7, 10 or 12 characters. It supports only digits, and the last digit is always a checksum. This standard is mainly used by the United States Postal Services. ### ROYALMAIL Royalmail is used by Royal Mail. This barcode has no defined length. It supports digits, uppercase letters, and the last digit is always a checksum. This standard is mainly used by Royal Mail for their Cleanmail Service. It is also called RM4SCC. ### SSCC SSCC is the shortcut for "Serial Shipping Container Code". This barcode is a variant of EAN barcode. It must have a length of 18 characters and supports only digits. The last digit must be a checksum digit which is calculated with modulo 10. It is commonly used by the transport industry. ### UPCA UPC is the shortcut for "Universal Product Code". This barcode preceded EAN13. It must have a length of 12 characters and supports only digits. The last digit must be a checksum digit which is calculated with modulo 10. It is commonly used within the USA. ### UPCE UPCE is the short variant from UPCA. This barcode is a smaller variant of UPCA. It can have a length of 6, 7 or 8 characters and supports only digits. When the barcode is 8 chars long it includes a checksum which is calculated with modulo 10. It is commonly used with small products where a UPCA barcode would not fit. ## Supported options The following options are supported for `Zend\Validator\Barcode`: - `adapter`: Sets the barcode adapter which will be used. Supported are all above noted adapters. When using a self defined adapter, then you have to set the complete class name. - `checksum`: `TRUE` when the barcode should contain a checksum. The default value depends on the used adapter. Note that some adapters don't allow to set this option. - `options`: Defines optional options for a self written adapters. ## Basic usage To validate if a given string is a barcode you must know its type. See the following example for an EAN13 barcode: ```php $valid = new Zend\Validator\Barcode('EAN13'); if ($valid->isValid($input)) { // input appears to be valid } else { // input is invalid } ``` ## Optional checksum Some barcodes can be provided with an optional checksum. These barcodes would be valid even without checksum. Still, when you provide a checksum, then you should also validate it. By default, these barcode types perform no checksum validation. By using the `checksum` option you can define if the checksum will be validated or ignored. ```php $valid = new Zend\Validator\Barcode([ 'adapter' => 'EAN13', 'checksum' => false, ]); if ($valid->isValid($input)) { // input appears to be valid } else { // input is invalid } ``` > ### Reduced security by disabling checksum validation > > By switching off checksum validation you will also reduce the security of the > used barcodes. Additionally you should note that you can also turn off the > checksum validation for those barcode types which must contain a checksum > value. Barcodes which would not be valid could then be returned as valid even > if they are not. ## Writing custom adapters You may write custom barcode validators for usage with `Zend\Validator\Barcode`; this is often necessary when dealing with proprietary barcode types. To write your own barcode validator, you need the following information. - `Length`: The length your barcode must have. It can have one of the following values: - `Integer`: A value greater 0, which means that the barcode must have this length. - `-1`: There is no limitation for the length of this barcode. - `"even"`: The length of this barcode must have a even amount of digits. - `"odd"`: The length of this barcode must have a odd amount of digits. - `array`: An array of integer values. The length of this barcode must have one of the set array values. - `Characters`: A string which contains all allowed characters for this barcode. Also the integer value 128 is allowed, which means the first 128 characters of the ASCII table. - `Checksum`: A string which will be used as callback for a method which does the checksum validation. Your custom barcode validator must extend `Zend\Validator\Barcode\AbstractAdapter` or implement `Zend\Validator\Barcode\AdapterInterface`. As an example, let's create a validator that expects an even number of characters that include all digits and the letters 'ABCDE', and which requires a checksum. ```php namespace My\Barcode; use Zend\Validator\Barcode; use Zend\Validator\Barcode\AbstractAdapter; class MyBar extends AbstractAdapter { protected $length = 'even'; protected $characters = '0123456789ABCDE'; protected $checksum = 'mod66'; protected function mod66($barcode) { // do some validations and return a boolean } } $valid = Barcode(MyBar::class); if ($valid->isValid($input)) { // input appears to be valid } else { // input is invalid } ``` ================================================ FILE: docs/book/validators/between.md ================================================ # Between Validator `Zend\Validator\Between` allows you to validate if a given value is between two other values. > ### Only supports number validation > > `Zend\Validator\Between` supports only the validation of numbers. Strings or > dates can not be validated with this validator. ## Supported options The following options are supported for `Zend\Validator\Between`: - `inclusive`: Defines if the validation is inclusive of the minimum and maximum border values, or exclusive. It defaults to `true`. - `max`: Sets the maximum border for the validation. - `min`: Sets the minimum border for the validation. ## Default behaviour Per default, this validator checks if a value is between `min` and `max` where both border values are allowed as value. ```php $valid = new Zend\Validator\Between(['min' => 0, 'max' => 10]); $value = 10; $result = $valid->isValid($value); // returns true ``` In the above example, the result is `true` due to the reason that the default search is inclusive of the border values. This means in our case that any value from '0' to '10' is allowed; values like '-1' and '11' will return `false`. ## Excluding border values Sometimes it is useful to validate a value by excluding the border values. See the following example: ```php $valid = new Zend\Validator\Between([ 'min' => 0, 'max' => 10, 'inclusive' => false, ]); $value = 10; $result = $valid->isValid($value); // returns false ``` The example above is almost identical to our first example, but we now exclue the border values; as such, the values '0' and '10' are no longer allowed and will return `false`. ================================================ FILE: docs/book/validators/callback.md ================================================ # Callback Validator `Zend\Validator\Callback` allows you to provide a callback with which to validate a given value. ## Supported options The following options are supported for `Zend\Validator\Callback`: - `callback`: Sets the callback which will be called for the validation. - `options`: Sets the additional options which will be given to the validator and/or callback. ## Basic usage The simplest use case is to pass a function as a callback. Consider the following function: ```php function myMethod($value) { // some validation return true; } ``` To use it within `Zend\Validator\Callback`, pass it to the constructor ```php $valid = new Zend\Validator\Callback('myMethod'); if ($valid->isValid($input)) { // input appears to be valid } else { // input is invalid } ``` ## Usage with closures The `Callback` validator supports any PHP callable, including PHP [closures](http://php.net/functions.anonymous). ```php $valid = new Zend\Validator\Callback(function($value) { // some validation return true; }); if ($valid->isValid($input)) { // input appears to be valid } else { // input is invalid } ``` ## Usage with class-based callbacks Of course it's also possible to use a class method as callback. Consider the following class definition: ```php class MyClass { public function myMethod($value) { // some validation return true; } } ``` To use it with the `Callback` validator, pass a callable using an instance of the class: ```php $valid = new Zend\Validator\Callback([new MyClass, 'myMethod']); if ($valid->isValid($input)) { // input appears to be valid } else { // input is invalid } ``` You may also define a static method as a callback. Consider the following class definition and validator usage: ```php class MyClass { public static function test($value) { // some validation return true; } } $valid = new Zend\Validator\Callback(MyClass::class, 'test']); if ($valid->isValid($input)) { // input appears to be valid } else { // input is invalid } ``` Finally, you may define the magic method `__invoke()` in your class. If you do so, you can provide a class instance itself as the callback: ```php class MyClass { public function __invoke($value) { // some validation return true; } } $valid = new Zend\Validator\Callback(new MyClass()); if ($valid->isValid($input)) { // input appears to be valid } else { // input is invalid } ``` ## Adding options `Zend\Validator\Callback` also allows the usage of options which are provided as additional arguments to the callback. Consider the following class and method definition: ```php class MyClass { public static function myMethod($value, $option) { // some validation return true; } /** * Or, to use with contextual validation */ public static function myMethod($value, $context, $option) { // some validation return true; } } ``` There are two ways to inform the validator of additional options: pass them in the constructor, or pass them to the `setOptions()` method. To pass them to the constructor, you would need to pass an array containing two keys, `callback` and `callbackOptions`: ```php $valid = new Zend\Validator\Callback([ 'callback' => [MyClass::class, 'myMethod'], 'callbackOptions' => $options, ]); if ($valid->isValid($input)) { // input appears to be valid } else { // input is invalid } ``` Otherwise, you may pass them to the validator after instantiation: ```php $valid = new Zend\Validator\Callback([MyClass::class, 'myMethod']); $valid->setOptions($options); if ($valid->isValid($input)) { // input appears to be valid } else { // input is invalid } ``` When there are additional values given to `isValid()`, then these values will be passed as an additional argument: ```php $valid = new Zend\Validator\Callback([MyClass::class, 'myMethod']); $valid->setOptions($options); if ($valid->isValid($input, $context)) { // input appears to be valid } else { // input is invalid } ``` When making the call to the callback, the value to be validated will always be passed as the first argument to the callback followed by all other values given to `isValid()`; all other options will follow it. The amount and type of options which can be used is not limited. ================================================ FILE: docs/book/validators/credit-card.md ================================================ # CreditCard Validator `Zend\Validator\CreditCard` allows you to validate if a given value could be a credit card number. A credit card contains several items of metadata, including a hologram, account number, logo, expiration date, security code, and the card holder name. The algorithms for verifying the combination of metadata are only known to the issuing company, and should be verified with them for purposes of payment. However, it's often useful to know whether or not a given number actually falls within the ranges of possible numbers **prior** to performing such verification, and, as such, `Zend\Validator\CreditCard` verifies that the credit card number provided is well-formed. For those cases where you have a service that can perform comprehensive verification, `Zend\Validator\CreditCard` also provides the ability to attach a service callback to trigger once the credit card number has been deemed valid; this callback will then be triggered, and its return value will determine overall validity. The following issuing institutes are accepted: - American Express - China UnionPay - Diners Club Card Blanche - Diners Club International - Diners Club US and Canada - Discover Card - JCB - Laser - Maestro - MasterCard - Solo - Visa - Visa Electron - Russia Mir > ### Invalid institutes > > The institutes **Bankcard** and **Diners Club enRoute** no longer exist, and > are treated as invalid. > > **Switch** has been rebranded to **Visa** and is therefore also treated as > invalid. ## Supported options The following options are supported for `Zend\Validator\CreditCard`: - `service`: A callback to an online service which will additionally be used for the validation. - `type`: The type of credit card which will be validated. See the below list of institutes for details. ## Basic usage There are several credit card institutes which can be validated by `Zend\Validator\CreditCard`. Per default, all known institutes will be accepted. See the following example: ```php $valid = new Zend\Validator\CreditCard(); if ($valid->isValid($input)) { // input appears to be valid } else { // input is invalid } ``` The above example would validate against all known credit card institutes. ## Accepting only specific credit cards Sometimes it is necessary to accept only specific credit card institutes instead of all; e.g., when you have a webshop which accepts only Visa and American Express cards. `Zend\Validator\CreditCard` allows you to do exactly this by limiting it to exactly these institutes. To use a limitation you can either provide specific institutes at initiation, or afterwards by using `setType()`. Each can take several arguments. You can provide a single institute: ```php use Zend\Validator\CreditCard; $valid = new CreditCard(CreditCard::AMERICAN_EXPRESS); ``` When you want to allow multiple institutes, then you can provide them as array: ```php use Zend\Validator\CreditCard; $valid = new CreditCard([ CreditCard::AMERICAN_EXPRESS, CreditCard::VISA ]); ``` And, as with all validators, you can also pass an associative array of options or an instance of `Traversable`. In this case you have to provide the institutes with the `type` array key as demostrated here: ```php use Zend\Validator\CreditCard; $valid = new CreditCard([ 'type' => [CreditCard::AMERICAN_EXPRESS] ]); ``` You can also manipulate institutes after instantiation by using the methods `setType()`, `addType()`, and `getType()`. ```php use Zend\Validator\CreditCard; $valid = new CreditCard(); $valid->setType([ CreditCard::AMERICAN_EXPRESS, CreditCard::VISA ]); ``` > ### Default institute > > When no institute is given at initiation then `ALL` will be used, which sets > all institutes at once. > > In this case the usage of `addType()` is useless because all institutes are > already added. ## Validation using APIs As said before `Zend\Validator\CreditCard` will only validate the credit card number. Fortunately, some institutes provide online APIs which can validate a credit card number by using algorithms which are not available to the public. Most of these services are paid services. Therefore, this check is deactivated per default. When you have access to such an API, then you can use it as an add on for `Zend\Validator\CreditCard` and increase the security of the validation. To do so, provide a callback to invoke when generic validation has passed. This prevents the API from being called for invalid numbers, which increases the performance of the application. `setService()` sets a new service, and `getService()` returns the set service. As a configuration option, you can give the array key `service` at instantiatio. For details about possible options, read the [Callback validator documentation](callback.md). ```php use Zend\Validator\CreditCard; // Your service class class CcService { public function checkOnline($cardnumber, $types) { // some online validation } } // The validation $service = new CcService(); $valid = new CreditCard(CreditCard::VISA); $valid->setService([$service, 'checkOnline']); ``` The callback method will be called with the credit card number as the first parameter, and the accepted types as the second parameter. ================================================ FILE: docs/book/validators/date.md ================================================ # Date Validator `Zend\Validator\Date` allows you to validate if a given value contains a date. ## Supported options The following options are supported for `Zend\Validator\Date`: - `format`: Sets the format which is used to write the date. - `locale`: Sets the locale which will be used to validate date values. ## Default date validation The easiest way to validate a date is by using the default date format, `Y-m-d`. ```php $validator = new Zend\Validator\Date(); $validator->isValid('2000-10-10'); // returns true $validator->isValid('10.10.2000'); // returns false ``` ## Specifying a date format `Zend\Validator\Date` also supports custom date formats. When you want to validate such a date, use the `format` option. This option accepts any format allowed by the PHP [DateTime::createFromFormat()](http://php.net/manual/en/datetime.createfromformat.php#refsect1-datetime.createfromformat-parameters) method. ```php $validator = new Zend\Validator\Date(['format' => 'Y']); $validator->isValid('2010'); // returns true $validator->isValid('May'); // returns false ``` ## Strict mode - **Since 2.13.0** By default, `Zend\Validator\Date` only validates that it can convert the provided value to a valid `DateTime` value. If you want to require that the date is specified in a specific format, you can provide both the [date format](#specifying-a-date-format) and the `strict` options. In such a scenario, the value must both be covertable to a `DateTime` value **and** be in the same format as provided to the validator. (Generally, this will mean the value must be a string.) ```php $validator = new Zend\Validator\Date(['format' => 'Y-m-d', 'strict' => true]); $validator->isValid('2010-10-10'); // returns true $validator->isValid(new DateTime('2010-10-10)); // returns false; value is not a string $validator->isValid('2010.10.10'); // returns false; format differs ``` ================================================ FILE: docs/book/validators/db.md ================================================ # Db\\RecordExists and Db\\NoRecordExists Validators `Zend\Validator\Db\RecordExists` and `Zend\Validator\Db\NoRecordExists` provide a means to test whether a record exists in a given table of a database, with a given value. > ### Installation requirements > > `Zend\Validator\Db\NoRecordExists` and `Zend\Validator\Db\RecordExists` > depends on the zend-db component, so be sure to have it installed before > getting started: > > ```bash > $ composer require zendframework/zend-db > ``` ## Supported options The following options are supported for `Zend\Validator\Db\NoRecordExists` and `Zend\Validator\Db\RecordExists`: - `adapter`: The database adapter that will be used for the search. - `exclude`: Sets records that will be excluded from the search. - `field`: The database field within this table that will be searched for the record. - `schema`: Sets the schema that will be used for the search. - `table`: The table that will be searched for the record. ## Basic usage An example of basic usage of the validators: ```php // Check that the email address exists in the database $validator = new Zend\Validator\Db\RecordExists([ 'table' => 'users', 'field' => 'emailaddress', 'adapter' => $dbAdapter, ]); if ($validator->isValid($emailaddress)) { // email address appears to be valid } else { // email address is invalid; print the reasons foreach ($validator->getMessages() as $message) { echo "$message\n"; } } ``` The above will test that a given email address is in the database table. If no record is found containing the value of `$emailaddress` in the specified column, then an error message is displayed. ```php // Check that the username is not present in the database $validator = new Zend\Validator\Db\NoRecordExists([ 'table' => 'users', 'field' => 'username', 'adapter' => $dbAdapter, ]); if ($validator->isValid($username)) { // username appears to be valid } else { // username is invalid; print the reason $messages = $validator->getMessages(); foreach ($messages as $message) { echo "$message\n"; } } ``` The above will test that a given username is *not* in the database table. If a record is found containing the value of `$username` in the specified column, then an error message is displayed. ## Excluding records `Zend\Validator\Db\RecordExists` and `Zend\Validator\Db\NoRecordExists` also provide a means to test the database, excluding a part of the table, either by providing a `WHERE` clause as a string, or an array with the keys `field` and `value`. When providing an array for the exclude clause, the `!=` operator is used, so you can check the rest of a table for a value before altering a record (for example on a user profile form) ```php // Check no other users have the username $user_id = $user->getId(); $validator = new Zend\Validator\Db\NoRecordExists([ 'table' => 'users', 'field' => 'username', 'exclude' => [ 'field' => 'id', 'value' => $user_id, ], ]); if ($validator->isValid($username)) { // username appears to be valid } else { // username is invalid; print the reason $messages = $validator->getMessages(); foreach ($messages as $message) { echo "$message\n"; } } ``` The above example will check the table to ensure no records other than the one where `id = $user_id` contains the value `$username`. You can also provide a string to the exclude clause so you can use an operator other than `!=`. This can be useful for testing against composite keys. ```php $email = 'user@example.com'; $clause = $dbAdapter->quoteIdentifier('email') . ' = ' . $dbAdapter->quoteValue($email); $validator = new Zend\Validator\Db\RecordExists([ 'table' => 'users', 'field' => 'username', 'adapter' => $dbAdapter, 'exclude' => $clause, ]); if ($validator->isValid($username)) { // username appears to be valid } else { // username is invalid; print the reason $messages = $validator->getMessages(); foreach ($messages as $message) { echo "$message\n"; } } ``` The above example will check the `users` table to ensure that only a record with both the username `$username` and with the email `$email` is valid. ## Database Schemas You can specify a schema within your database for adapters such as PostgreSQL and DB/2 by supplying an array with `table` and `schema` keys, as demonstrated below: ```php $validator = new Zend\Validator\Db\RecordExists([ 'table' => 'users', 'schema' => 'my', 'field' => 'id', ]); ``` ## Using a Select object It is also possible to supply the validators with a `Zend\Db\Sql\Select` object in place of options. The validator then uses this object instead of building its own. This allows for greater flexibility with selection of records used for validation. ```php use Zend\Db\Sql\Select; use Zend\Validator\Db\RecordExists; $select = new Select(); $select ->from('users') ->where->equalTo('id', $user_id) ->where->equalTo('email', $email); $validator = new RecordExists($select); // We still need to set our database adapter $validator->setAdapter($dbAdapter); // Validation is then performed as usual if ($validator->isValid($username)) { // username appears to be valid } else { // username is invalid; print the reason $messages = $validator->getMessages(); foreach ($messages as $message) { echo "$message\n"; } } ``` The above example will check the `users` table to ensure that only a record with both the username `$username` and with the email `$email` is valid. ================================================ FILE: docs/book/validators/digits.md ================================================ # Digits Validator `Zend\Validator\Digits` validates if a given value contains only digits. > ### Installation requirements > > `Zend\Validator\Digits` depends on the zend-filter component, so be sure to > have it installed before getting started: > > ```bash > $ composer require zendframework/zend-filter > ``` ## Supported options There are no additional options for `Zend\Validator\Digits`: ## Validating digits To validate if a given value contains only digits and no other characters, call the validator as shown below: ```php $validator = new Zend\Validator\Digits(); $validator->isValid("1234567890"); // returns true $validator->isValid(1234); // returns true $validator->isValid('1a234'); // returns false ``` > ### Validating numbers > > When you want to validate numbers or numeric values, be aware that this > validator only validates *digits*. This means that any other sign like a > thousand separator or a comma will not pass this validator. In this case you > should use `Zend\I18n\Validator\IsInt` or `Zend\I18n\Validator\IsFloat`. ================================================ FILE: docs/book/validators/email-address.md ================================================ # EmailAddress Validator `Zend\Validator\EmailAddress` allows you to validate an email address. The validator first splits the email address on `local-part @ hostname` and attempts to match these against known specifications for email addresses and hostnames. ## Basic usage A basic example of usage is below: ```php $validator = new Zend\Validator\EmailAddress(); if ($validator->isValid($email)) { // email appears to be valid } else { // email is invalid; print the reasons foreach ($validator->getMessages() as $message) { echo "$message\n"; } } ``` This will match the email address `$email` and on failure populate `getMessages()` with useful error messages. ## Supported Options `Zend\Validator\EmailAddress` supports several options which can either be set at instantiation, by giving an array with the related options, or afterwards, by using `setOptions()`. The following options are supported: - `allow`: Defines which type of domain names are accepted. This option is used in conjunction with the hostnameValidator option to set the hostname validator. Possible values of this option defined in [Hostname](hostname.md) validator's `ALLOW_*` constants: - `ALLOW_DNS` (default) - Allows Internet domain names _(e.g. example.com)_ - `ALLOW_IP` - Allows IP addresses _(e.g. 192.168.0.1)_ - `ALLOW_LOCAL` - Allows local network such as _localhost_ or _www.localdomain_ - `ALLOW_URI` - Allows hostnames in URI generic syntax. See [RFC 3986](https://www.ietf.org/rfc/rfc3986.txt) - `ALLOW_ALL` - Allows all types of hostnames - `useDeepMxCheck`: Defines if the servers MX records should be verified by a deep check. When this option is set to `true` then additionally to MX records also the `A`, `A6` and `AAAA` records are used to verify if the server accepts emails. This option defaults to `false`. - `useDomainCheck`: Defines if the domain part should be checked. When this option is set to `false`, then only the local part of the email address will be checked. In this case the hostname validator will not be called. This option defaults to `true`. - `hostnameValidator`: Sets the hostname validator object instance with which the domain part of the email address will be validated. - `useMxCheck`: Defines if the MX records from the server should be detected. If this option is defined to `true` then the MX records are used to verify if the server accepts emails. This option defaults to `false`. ## Complex local parts `Zend\Validator\EmailAddress` will match any valid email address according to RFC2822. For example, valid emails include `bob@domain.com`, `bob+jones@domain.us`, `"bob@jones"@domain.com*` and `"bob jones"@domain.com` Some obsolete email formats will not currently validate (e.g. carriage returns or a `\\` character in an email address). ## Validating only the local part If you need `Zend\Validator\EmailAddress` to check only the local part of an email address, and want to disable validation of the hostname, you can set the `domain` option to `false`. This forces `Zend\Validator\EmailAddress` not to validate the hostname part of the email address. ```php $validator = new Zend\Validator\EmailAddress(); $validator->setOptions(['domain' => FALSE]); ``` ## Validating different types of hostnames The hostname part of an email address is validated against the [Hostname validator](hostname.md). By default only DNS hostnames of the form `domain.com` are accepted, though if you wish you can accept IP addresses and Local hostnames too. To do this you need to instantiate `Zend\Validator\EmailAddress` passing a parameter to indicate the type of hostnames you want to accept. More details are included in `Zend\Validator\Hostname`, though an example of how to accept both DNS and Local hostnames appears below: ```php use Zend\Validator\EmailAddress; use Zend\Validator\Hostname; $validator = new EmailAddress( Hostname::ALLOW_DNS | Hostname::ALLOW_LOCAL); if ($validator->isValid($email)) { // email appears to be valid } else { // email is invalid; print the reasons foreach ($validator->getMessages() as $message) { echo "$message\n"; } } ``` ## Checking if the hostname actually accepts email Just because an email address is in the correct format, it doesn't necessarily mean that email address actually exists. To help solve this problem, you can use MX validation to check whether an MX (email) entry exists in the DNS record for the email's hostname. This tells you that the hostname accepts email, but doesn't tell you the exact email address itself is valid. MX checking is not enabled by default. To enable MX checking you can pass a second parameter to the `Zend\Validator\EmailAddress` constructor. ```php $validator = new Zend\Validator\EmailAddress([ 'allow' => Zend\Validator\Hostname::ALLOW_DNS, 'useMxCheck' => true, ]); ``` Alternatively you can either pass `true` or `false` to `setValidateMx()` to enable or disable MX validation. By enabling this setting, network functions will be used to check for the presence of an MX record on the hostname of the email address you wish to validate. Please be aware this will likely slow your script down. Sometimes validation for MX records returns `false`, even if emails are accepted. The reason behind this behaviour is, that servers can accept emails even if they do not provide a MX record. In this case they can provide `A`, `A6`, or `AAAA` records. To allow `Zend\Validator\EmailAddress` to check also for these other records, you need to set deep MX validation. This can be done at initiation by setting the `deep` option or by using `setOptions()`. ```php $validator = new Zend\Validator\EmailAddress([ 'allow' => Zend\Validator\Hostname::ALLOW_DNS, 'useMxCheck' => true, 'useDeepMxCheck' => true, ]); ``` Sometimes it can be useful to get the server's MX information which have been used to do further processing. Simply use `getMXRecord()` after validation. This method returns the received MX record including weight and sorted by it. > ### Performance warning** > > You should be aware that enabling MX check will slow down you script because > of the used network functions. Enabling deep check will slow down your script > even more as it searches the given server for 3 additional types. > ### Disallowed IP addresses > > You should note that MX validation is only accepted for external servers. When > deep MX validation is enabled, then local IP addresses like `192.168.*` or > `169.254.*` are not accepted. ## Validating International Domains Names `Zend\Validator\EmailAddress` will also match international characters that exist in some domains. This is known as International Domain Name (IDN) support. This is enabled by default, though you can disable this by changing the setting via the internal `Zend\Validator\Hostname` object that exists within `Zend\Validator\EmailAddress`. ```php $validator->getHostnameValidator()->setValidateIdn(false); ``` More information on the usage of `setValidateIdn()` appears in the [Hostname documentation](hostname.md). Please note IDNs are only validated if you allow DNS hostnames to be validated. ## Validating Top Level Domains By default a hostname will be checked against a list of known TLDs. This is enabled by default, though you can disable this by changing the setting via the internal `Zend\Validator\Hostname` object that exists within `Zend\Validator\EmailAddress`. ```php $validator->getHostnameValidator()->setValidateTld(false); ``` More information on the usage of `setValidateTld()` appears in the [Hostname documentation](hostname.md). Please note TLDs are only validated if you allow DNS hostnames to be validated. ## Setting messages `Zend\Validator\EmailAddress` makes also use of `Zend\Validator\Hostname` to check the hostname part of a given email address. You can specify messages for `Zend\Validator\Hostname` from within `Zend\Validator\EmailAddress`. ```php $validator = new Zend\Validator\EmailAddress(); $validator->setMessages([ Zend\Validator\Hostname::UNKNOWN_TLD => 'I don\'t know the TLD you gave' ]); ``` ================================================ FILE: docs/book/validators/explode.md ================================================ # Explode Validator `Zend\Validator\Explode` executes a validator for each item exploded from an array. ## Supported options The following options are supported for `Zend\Validator\Explode`: - `valueDelimiter`: Defines the delimiter used to explode values from an array. It defaults to `,`. If the given value is an array, this option isn't used. - `validator`: Sets the validator that will be executed on each exploded item. This may be a validator instance, or a validator service name. ## Basic usage To validate if every item in an array is in a specified haystack: ```php $inArrayValidator = new Zend\Validator\InArray([ 'haystack' => [1, 2, 3, 4, 5, 6], ]); $explodeValidator = new Zend\Validator\Explode([ 'validator' => $inArrayValidator ]); $explodeValidator->isValid([1, 4, 6]); // returns true $explodeValidator->isValid([1, 4, 6, 8]); // returns false ``` ## Exploding strings To validate if every e-mail in a string is contained in a list of names: ```php $inEmailListValidator = new Zend\Validator\InArray([ 'haystack' => ['joseph@test.com', 'mark@test.com', 'lucia@test.com'], ]); $explodeValidator = new Zend\Validator\Explode([ 'validator' => $inEmailListValidator, 'valueDelimiter' => ',' ]); $explodeValidator->isValid('joseph@test.com,mark@test.com'); // returns true $explodeValidator->isValid('lucia@test.com,maria@test.com'); // returns false ``` ================================================ FILE: docs/book/validators/file/count.md ================================================ # Count `Zend\Validator\File\Count` allows you to validate that the number of files uploaded matches criteria, including a minimum number of files and/or a maximum number of files. ## Supported Options The following options are supported: - `min`: The minimum number of uploaded files acceptable; `null` is equivalent to `0`, indicating no minimum. - `max`: The maximum number of uploaded files acceptable; `null` is equivalent to no maximum. ## Basic Usage ```php $validator = new Zend\Validator\File\Count([ 'min' => 1, 'max' => 5, ]); // Setting to the $_FILES superglobal; could also use the zend-http // request's `getFiles()` or PSR-7 ServerRequest's `getUploadedFiles()`. $files = $_FILES; if ($validator->isValid($files)) { // Received between 1 and 5 files! } ``` ================================================ FILE: docs/book/validators/file/crc32.md ================================================ # Crc32 `Zend\Validator\File\Crc32` allows you to validate if a given file's hashed contents matches the supplied crc32 hash(es). It is subclassed from the [Hash validator](hash.md) to provide a validator that only supports the `crc32` algorithm. > ### Requires the hash extension > > This validator requires the PHP [Hash extension](http://php.net/hash) with the > `crc32` algorithm. ## Supported Options The following options are supported: - `hash`: Single string hash to test the file against, or array of filename/hash pairs. ## Usage Examples ```php // Does file have the given hash? $validator = new \Zend\Validator\File\Crc32('3b3652f'); // Or, check file against multiple hashes $validator = new \Zend\Validator\File\Crc32(['3b3652f', 'e612b69']); // Perform validation with file path if ($validator->isValid('./myfile.txt')) { // file is valid } ``` ## Public Methods ### getCrc32 ```php getCrc32() : array ``` Returns an array of all currently registered hashes to test against. ### addCrc32 ```php addCrc32(string|array $options) : void ``` Add a single hash to test against, or a set of filename/hash pairs to test against. ### setCrc32 ```php setCrc32(string|array $options): void ``` Overwrite the current list of registered hashes with the one(s) provided. ================================================ FILE: docs/book/validators/file/exclude-extension.md ================================================ # ExcludeExtension `Zend\Validator\File\ExcludeExtension` checks the extension of files. It will assert `false` when a given file matches any of the defined extensions. This validator is inversely related to the [Extension validator](extension.md); please refer to that validator for full options and usage examples. ================================================ FILE: docs/book/validators/file/exclude-mime-type.md ================================================ ExcludeMimeType =============== `Zend\Validator\File\ExcludeMimeType` checks the MIME type of files. It will assert `false` when a given file matches any of the defined MIME types. This validator is inversely related to the [MimeType validator](mime-type.md); please refer to that validator's documentation for full options and usage examples. ================================================ FILE: docs/book/validators/file/exists.md ================================================ # Exists `Zend\Validator\File\Exists` checks for the existence of files in specified directories. This validator is inversely related to the [NotExists validator](not-exists.md). ## Supported Options The following set of options are supported: - `directory`: Array of directories, or comma-delimited string of directories. ## Usage Examples ```php use Zend\Validator\File\Exists; // Only allow files that exist in ~both~ directories $validator = new Exists('/tmp,/var/tmp'); // ...or with array notation $validator = new Exists(['/tmp', '/var/tmp']); // Perform validation if ($validator->isValid('/tmp/myfile.txt')) { // file is valid } ``` > ### Checks against all directories > > This validator checks whether the specified file exists in **all** of the > given directories; validation will fail if the file does not exist in one > or more of them. ================================================ FILE: docs/book/validators/file/extension.md ================================================ # Extension `Zend\Validator\File\Extension` checks the extension of files. It will assert `true` when a given file matches any of the defined extensions. This validator is inversely related to the [ExcludeExtension validator](exclude-extension.md). ## Supported Options The following set of options are supported: - `extension`: Array of extensions, or comma-delimited string of extensions, against which to test. - `case`: Boolean indicating whether or not extensions should match case sensitively; defaults to `false` (case-insensitive). - `allowNonExistentFile`: (**Since 2.13.0**) Boolean indicating whether or not to allow validating a filename for a non-existent file. Defaults to `false` (will not validate non-existent files). ## Usage Examples ```php use Zend\Validator\File\Extension; // Allow files with 'php' or 'exe' extensions $validator = new Extension('php,exe'); // ...or with array notation $validator = new Extension(['php', 'exe']); // Test with case-sensitivity on $validator = new Extension(['php', 'exe'], true); // Using an options array: $validator = new Extension([ 'extension' => ['php', 'exe'], 'case' => true, ]); // Perform validation if ($validator->isValid('./myfile.php')) { // file is valid } ``` ## Public Methods ### addExtension ```php addExtension(string|array $options) : void ``` Add one or more extensions as a comma-separated list, or as an array. ================================================ FILE: docs/book/validators/file/files-size.md ================================================ # FilesSize `Zend\Validator\File\FilesSize` allows validating the total size of all file uploads in aggregate, allowing specifying a minimum upload size and/or a maximum upload size. Only use this validator if you will be expecting multiple file uploads in a single payload, and want to ensure the aggregate size falls within a specific range. ## Supported Options `Zend\Validator\File\FilesSize` supports the following options: - `min`: The minimum aggregate size of all file uploads. May be specified as an integer or using SI units. `null` indicates no minimum size is required. - `max`: The maximum aggregate size of all file uploads. May be specified as an integer or using SI units. `null` indicates no maximum size is required. - `useByteString`: A flag indicating whether sizes should be reported as integers or using SI units when reporting validation errors. See the [Size validator](size.md#supported-options) for details on supported SI units. ## Basic Usage ```php use Zend\Validator\File\FilesSize; $validator = new FilesSize([ 'min' => '1kB`, // minimum of 1kB 'max' => `10MB', // maximum of 10MB ]); if ($validator->isValid($_FILES)) { // > 1kB, < 10MB in aggregate } ``` ================================================ FILE: docs/book/validators/file/hash.md ================================================ # Hash `Zend\Validator\File\Hash` allows you to validate if a given file's hashed contents matches the supplied hash(es) and algorithm(s). > ### Requires the hash extension > > This validator requires the PHP [Hash extension](http://php.net/hash). A list > of supported hash algorithms can be found with the > [hash\_algos() function](http://php.net/hash_algos). ## Supported Options The following set of options are supported: - `hash`: String hash or array of hashes against which to test. - `algorithm`: String hashing algorithm to use; defaults to `crc32` ## Basic Usage ```php use Zend\Validator\File\Hash; // Does file have the given hash? $validator = new Hash('3b3652f', 'crc32'); // Or, check file against multiple hashes $validator = new Hash(['3b3652f', 'e612b69'], 'crc32'); // Or use options notation: $validator = new Hash([ 'hash' => ['3b3652f', 'e612b69'], 'algorithm' => 'crc32', ]); // Perform validation with file path if ($validator->isValid('./myfile.txt')) { // file is valid } ``` ## Public Methods ### getHash ```php getHash() : array ``` Returns an array containing the set of hashes against which to validate. ### addHash ```php addHash(string|array $options) : void ``` Add one or more hashes against which to validate. ### setHash ```php setHash(string|array $options) : void ``` Overwrite the current set of hashes with those provided to the method. ================================================ FILE: docs/book/validators/file/image-size.md ================================================ # ImageSize `Zend\Validator\File\ImageSize` checks the size of image files. Minimum and/or maximum dimensions can be set to validate against. ## Supported Options The following set of options are supported: - `minWidth`: Set the minimum image width as an integer; `null` (the default) indicates no minimum. - `minHeight`: Set the minimum image height as an integer; `null` (the default) indicates no minimum. - `maxWidth`: Set the maximum image width as an integer; `null` (the default) indicates no maximum. - `maxHeight`: Set the maximum image height as an integer; `null` (the default) indicates no maximum. ## Basic Usage ```php use Zend\Validator\File\ImageSize; // Is image size between 320x200 (min) and 640x480 (max)? $validator = new ImageSize(320, 200, 640, 480); // ...or with array notation $validator = new ImageSize([ 'minWidth' => 320, 'minHeight' => 200, 'maxWidth' => 640, 'maxHeight' => 480, ]); // Is image size equal to or larger than 320x200? $validator = new ImageSize([ 'minWidth' => 320, 'minHeight' => 200, ]); // Is image size equal to or smaller than 640x480? $validator = new ImageSize([ 'maxWidth' => 640, 'maxHeight' => 480, ]); // Perform validation with file path if ($validator->isValid('./myfile.jpg')) { // file is valid } ``` ## Public Methods ### getImageMin ```php getImageMin() : array ``` Returns the minimum valid dimensions as an array with the keys `width` and `height`. ### getImageMax ```php getImageMax() : array ``` Returns the maximum valid dimensions as an array with the keys `width` and `height`. ================================================ FILE: docs/book/validators/file/intro.md ================================================ # File Validation Classes Zend Framework comes with a set of classes for validating both files and uploaded files, such as file size validation and CRC checking. - [Count](count.md) - [crc32](crc32.md) - [ExcludeExtension](exclude-extension.md) - [ExcludeMimeType](exclude-mime-type.md) - [Exists](exists.md) - [Extension](extension.md) - [FilesSize](files-size.md) - [Hash](hash.md) - [ImageSize](image-size.md) - [IsCompressed](is-compressed.md) - [IsImage](is-image.md) - [Md5](md5.md) - [MimeType](mime-type.md) - [NotExists](not-exists.md) - [Sha1](sha1.md) - [Size](size.md) - [Upload](upload.md) - [UploadFile](upload-file.md) - [WordCount](word-count.md) > ### Validation argument > > All of the File validators' `isValid()` methods support both a file path > `string` *or* a `$_FILES` array as the supplied argument. When a `$_FILES` > array is passed in, the `tmp_name` is used for the file path. ================================================ FILE: docs/book/validators/file/is-compressed.md ================================================ # IsCompressed `Zend\Validator\File\IsCompressed` checks if a file is a compressed archive, such as zip or gzip. This validator is based on the [MimeType validator](mime-type.md), and supports the same methods and options. The default list of [compressed file MIME types](https://github.com/zendframework/zend-validator/blob/master/src/File/IsCompressed.php#L45) can be found in the source code. Please refer to the [MimeType validator](mime-type.md) for options and public methods. ## Basic Usage ```php $validator = new \Zend\Validator\File\IsCompressed(); if ($validator->isValid('./myfile.zip')) { // file is valid } ``` ================================================ FILE: docs/book/validators/file/is-image.md ================================================ # IsImage `Zend\Validator\File\IsImage` checks if a file is an image, such as jpg or png. This validator is based on the [MimeType validator](mime-type.md) and supports the same methods and options. The default list of [image file MIME types](https://github.com/zendframework/zend-validator/blob/master/src/File/IsImage.php#L44) can be found in the source code. Please refer to the [MimeType validator](mime-type.md) for options and public methods. ## Basic Usage ```php $validator = new Zend\Validator\File\IsImage(); if ($validator->isValid('./myfile.jpg')) { // file is valid } ``` ================================================ FILE: docs/book/validators/file/md5.md ================================================ # Md5 `Zend\Validator\File\Md5` allows you to validate if a given file's hashed contents matches the supplied md5 hash(es). It is subclassed from the [Hash validator](hash.md) to provide a validator that supports only the MD5 algorithm. > ### Requires the hash extension > > This validator requires the PHP [Hash extension](http://php.net/hash) PHP with > the `md5` algorithm. ## Supported Options The following set of options are supported: - `hash`: String hash or array of hashes against which to validate. ## Basic Usage ```php use Zend\Validator\File\Md5; // Does file have the given hash? $validator = new Md5('3b3652f336522365223'); // Or, check file against multiple hashes $validator = new Md5([ '3b3652f336522365223', 'eb3365f3365ddc65365' ]); // Or use options notation: $validator = new Md5(['hash' => [ '3b3652f336522365223', 'eb3365f3365ddc65365' ]]); // Perform validation with file path if ($validator->isValid('./myfile.txt')) { // file is valid } ``` ## Public Methods ### getMd5 ```php getMd5() : array ``` Returns an array of MD5 hashes against which to validate. ### addMd5 ```php addMd5(string|array $options) : void ``` Add one or more hashes to validate against. ### setMd5 ```php setMd5(string|array $options) : void ``` Overwrite any previously set hashes with those specified. ================================================ FILE: docs/book/validators/file/mime-type.md ================================================ # MimeType `Zend\Validator\File\MimeType` checks the MIME type of files. It will assert `true` when a given file matches any defined MIME type. This validator is inversely related to the [ExcludeMimeType validator](exclude-mime-type.md) > ### Compatibility > > This component will use the `FileInfo` extension if it is available. If it's > not, it will degrade to the `mime_content_type()` function. And if the > function call fails, it will use the MIME type which is given by HTTP. You > should be aware of possible security problems when you do not have `FileInfo` > or `mime_content_type()` available; the MIME type given by HTTP is not secure > and can be easily manipulated. ## Supported Options The following set of options are supported: - `mimeType`: Comma-delimited string of MIME types, or array of MIME types, against which to test. Types can be specific (e.g., `image/jpeg`), or refer only to the group (e.g., `image`). - `magicFile`: Location of the magicfile to use for MIME type comparisons; defaults to the value of the `MAGIC` constant. - `enableHeaderCheck`: Boolean flag indicating whether or not to use HTTP headers when determining the MIME type if neither the `FileInfo` nor `mime_magic` extensions are available; defaults to `false`. ## Basic Usage ```php use Zend\Validator\File\MimeType; // Only allow 'gif' or 'jpg' files $validator = new MimeType('image/gif,image/jpeg'); // ... or with array notation: $validator = new MimeType(['image/gif', 'image/jpeg']); // ... or restrict to entire group of types: $validator = new MimeType(['image', 'audio']); // Specify a different magicFile: $validator = new MimeType([ 'mimeType' => ['image/gif', 'image/jpeg'], 'magicFile' => '/path/to/magicfile.mgx', ]); // Enable HTTP header scanning (do not do this!): $validator = new MimeType([ 'mimeType' => ['image/gif', 'image/jpeg'], 'enableHeaderCheck' => true, ]); // Perform validation if ($validator->isValid('./myfile.jpg')) { // file is valid } ``` > ### Validating MIME groups is potentially dangerous > > Allowing "groups" of MIME types will accept **all** members of this group, even > if your application does not support them. For instance, When you allow > `image` you also allow `image/xpixmap` and `image/vasa`, both of which could > be problematic. ================================================ FILE: docs/book/validators/file/not-exists.md ================================================ # NotExists `Zend\Validator\File\NotExists` checks for the existence of files in specified directories. This validator is inversely related to the [Exists validator](exists.md). ## Supported Options The following set of options are supported: - `directory`: Array of directories or comma-delimited string of directories against which to validate. ## Basic Usage ```php use Zend\Validator\File\NotExists; // Only allow files that do not exist in ~either~ directories $validator = new NotExists('/tmp,/var/tmp'); // ... or with array notation: $validator = new NotExists(['/tmp', '/var/tmp']); // ... or using options notation: $validator = new NotExists(['directory' => [ '/tmp', '/var/tmp', ]]); // Perform validation if ($validator->isValid('/home/myfile.txt')) { // file is valid } ``` > ### Checks against all directories > > This validator checks whether the specified file does not exist in **any** of > the given directories; validation will fail if the file exists in one (or > more) of the given directories. ================================================ FILE: docs/book/validators/file/sha1.md ================================================ # Sha1 `Zend\Validator\File\Sha1` allows you to validate if a given file's hashed contents matches the supplied sha1 hash(es). It is subclassed from the [Hash validator](hash.md) to provide a validator that only supports the `sha1` algorithm. > ### Requires the hash extension > > This validator requires the PHP [Hash extension](http://php.net/hash) with the > `sha1` algorithm. ## Supported Options The following set of options are supported: - `hash`: String hash or array of hashes against which to validate. ## Basic Usage ```php use Zend\Validator\File\Sha1; // Does file have the given hash? $validator = new Sha1('3b3652f336522365223'); // Or check file against multiple hashes: $validator = new Sha1([ '3b3652f336522365223', 'eb3365f3365ddc65365', ]); // Or using options notation: $validator = new Sha1(['hash' => [ '3b3652f336522365223', 'eb3365f3365ddc65365', ]]); // Perform validation with file path if ($validator->isValid('./myfile.txt')) { // file is valid } ``` ## Public Methods ### getSha1 ```php getSha1() : array ``` Returns an array of sha1 hashes against which to validate. ### addSha1 ```php addSha1(string|array $options) : void ``` Add one or more hashes to validate against. ### setSha1 ```php setSha1(string|array $options) : void ``` Overwrite any previously set hashes with those specified. ================================================ FILE: docs/book/validators/file/size.md ================================================ # Size `Zend\Validator\File\Size` checks for the size of a file. ## Supported Options The following set of options are supported: - `min`: Minimum file size in integer bytes, or in string SI notation; `null` indicates no minimum required. - `max`: maximum file size in integer bytes, or in string SI notation; `null` indicates no maximum required. - `useByteString`: Boolean flag indicating whether to dispaly error messages using SI notation (default, `true`), or in bytes (`false`). SI units supported are: kB, MB, GB, TB, PB, and EB. All sizes are converted using 1024 as the base value (ie. 1kB == 1024 bytes, 1MB == 1024kB). ## Basic Usage ```php use Zend\Validator\File\Size; // Limit the file size to 40000 bytes $validator = new Size(40000); // Limit the file size to between 10kB and 4MB $validator = new Size([ 'min' => '10kB', 'max' => '4MB', ]); // Perform validation with file path if ($validator->isValid('./myfile.txt')) { // file is valid } ``` ================================================ FILE: docs/book/validators/file/upload-file.md ================================================ # UploadFile `Zend\Validator\File\UploadFile` checks whether a single file has been uploaded via a form `POST` and will return descriptive messages for any upload errors. ## Basic Usage ```php use Zend\Http\PhpEnvironment\Request; use Zend\Validator\File\UploadFile; $request = new Request(); $files = $request->getFiles(); // i.e. $files['my-upload']['error'] == 0 $validator = new UploadFile(); if ($validator->isValid($files['my-upload'])) { // file is valid } ``` ## PSR-7 Support - Since 2.11.0 Starting in 2.11.0, you can also pass [PSR-7 UploadedFileInterface](https://www.php-fig.org/psr/psr-7/#uploadedfileinterface) instances as values to the validator. When valid, `getValue()` will return the instance validated verbatim: ```php $validator = new UploadFile(); // @var Psr\Http\Message\UploadedFileInterface $uploadedFile if ($validator->isValid($uploadedFile)) { // file is valid $validInstance = $validator->getValue(); // === $uploadedFile } ``` ## Usage with zend-inputfilter When using zend-inputfilter's [FileInput](https://docs.zendframework.com/zend-inputfilter/file-input/), this validator will be automatically prepended to the validator chain. ================================================ FILE: docs/book/validators/file/upload.md ================================================ # Upload `Zend\Validator\File\Upload` validates that a file upload operation was successful. ## Supported Options `Zend\Validator\File\Upload` supports the following options: - `files`: array of file uploads. This is generally the `$_FILES` array, but should be normalized per the details in [PSR-7](http://www.php-fig.org/psr/psr-7/#16-uploaded-files) (which is also how [the zend-http Request](https://docs.zendframework.com/zend-http) normalizes the array). ## Basic Usage ```php use Zend\Validator\File\Upload; // Using zend-http's request: $validator = new Upload($request->getFiles()); // Or using options notation: $validator = new Upload(['files' => $request->getFiles()]); // Validate: if ($validator->isValid('foo')) { // "foo" file upload was successful } ``` ## PSR-7 Support - Since 2.11.0 Starting in 2.11.0, you can also pass an array of [PSR-7 UploadedFileInterface](https://www.php-fig.org/psr/psr-7/#uploadedfileinterface) instances to the constructor, the `setFiles()` method, or the `isValid()` method (in the latter case, you are validating that _all_ uploaded files were valid). ```php use Zend\Validator\File\Upload; // @var Psr\Http\Message\ServerRequestInterface $request $validator = new Upload($request->getUploadedFiles()); // Or using options notation: $validator = new Upload([ 'files' => $request->getUploadedFiles(), ]); // Validate: if ($validator->isValid('foo')) { // "foo" file upload was successful } ``` ================================================ FILE: docs/book/validators/file/word-count.md ================================================ # WordCount `Zend\Validator\File\WordCount` validates that the number of words within a file match the specified criteria. ## Supported Options The following set of options are supported: - `min`: the minimum number of words required; `null` indicates no minimum. - `max`: the maximum number of words required; `null` indicates no maximum. ## Basic Usage ```php use Zend\Validator\File\WordCount; // Limit the amount of words to a maximum of 2000: $validator = new WordCount(2000); // Limit the amount of words to between 100 and 5000: $validator = new WordCount(100, 5000); // ... or use options notation: $validator = new WordCount([ 'min' => 1000, 'max' => 5000, ]); // Perform validation with file path if ($validator->isValid('./myfile.txt')) { // file is valid } ``` ================================================ FILE: docs/book/validators/greater-than.md ================================================ # GreaterThan Validator `Zend\Validator\GreaterThan` allows you to validate if a given value is greater than a minimum border value. > ### Only supports numbers > > `Zend\Validator\GreaterThan` supports only the validation of numbers. Strings > or dates can not be validated with this validator. ## Supported options The following options are supported for `Zend\Validator\GreaterThan`: - `inclusive`: Defines if the validation is inclusive of the minimum value, or exclusive. It defaults to `false`. - `min`: Sets the minimum allowed value. ## Basic usage To validate if a given value is greater than a defined minimum: ```php $valid = new Zend\Validator\GreaterThan(['min' => 10]); $value = 8; $return = $valid->isValid($value); // returns false ``` The above example returns `true` for all values which are greater than 10. ## Inclusive validation Sometimes it is useful to validate a value by including the minimum value. ```php $valid = new Zend\Validator\GreaterThan([ 'min' => 10, 'inclusive' => true, ]); $value = 10; $result = $valid->isValid($value); // returns true ``` The example is identical to our first example, with the exception that we included the minimum value. Now the value '10' is allowed and will return `true`. ================================================ FILE: docs/book/validators/hex.md ================================================ # Hex Validator `Zend\Validator\Hex` allows you to validate if a given value contains only hexadecimal characters. These are all characters from **0 to 9** and **A to F**, case insensitive. There is no length limitation for the input you want to validate. ```php $validator = new Zend\Validator\Hex(); if ($validator->isValid('123ABC')) { // value contains only hex chars } else { // false } ``` > ### Invalid characters > > All other characters will return false, including whitespace and decimal > points. Additionally, unicode zeros and numbers from other scripts than latin > will not be treated as valid. ## Supported options There are no additional options for `Zend\Validator\Hex`. ================================================ FILE: docs/book/validators/hostname.md ================================================ # Hostname Validator `Zend\Validator\Hostname` allows you to validate a hostname against a set of known specifications. It is possible to check for three different types of hostnames: a DNS Hostname (i.e. `domain.com`), IP address (i.e. 1.2.3.4), and Local hostnames (i.e. localhost). By default, only DNS hostnames are matched. ## Supported options The following options are supported for `Zend\Validator\Hostname`: - `allow`: Defines the sort of hostname which is allowed to be used. [See below](#validating-different-types-of-hostnames) for details. - `idn`: Defines if IDN domains are allowed or not. This option defaults to `true`. - `ip`: Allows defining a custom IP validator. This option defaults to a new instance of `Zend\Validator\Ip`. - `tld`: Defines if TLDs are validated. This option defaults to `true`. ## Basic usage ```php $validator = new Zend\Validator\Hostname(); if ($validator->isValid($hostname)) { // hostname appears to be valid } else { // hostname is invalid; print the reasons foreach ($validator->getMessages() as $message) { echo "$message\n"; } } ``` This will match the hostname `$hostname` and on failure populate `getMessages()` with useful error messages. ## Validating different types of hostnames You may find you also want to match IP addresses, Local hostnames, or a combination of all allowed types. This can be done by passing a parameter to `Zend\Validator\Hostname` when you instantiate it. The parameter should be an integer which determines what types of hostnames are allowed. You are encouraged to use the `Zend\Validator\Hostname` constants to do this. The `Zend\Validator\Hostname` constants are: - `ALLOW_DNS`, to allow only DNS hostnames - `ALLOW_IP` to allow IP addresses - `ALLOW_LOCAL` to allow local network names - `ALLOW_URI` to allow [RFC3986](http://tools.ietf.org/html/rfc3986)-compliant addresses - `ALLOW_ALL` to allow all four above types > ### Additional Information on `ALLOW_URI` > > `ALLOW_URI` allows checking hostnames according to > [RFC3986](http://tools.ietf.org/html/rfc3986). These are registered names > which are used by WINS, NetInfo and also local hostnames like those defined > within your `hosts` file. To check for IP addresses only, you can use the example below: ```php use Zend\Validator\Hostname; $validator = new Hostname(Hostname::ALLOW_IP); if ($validator->isValid($hostname)) { // hostname appears to be valid } else { // hostname is invalid; print the reasons foreach ($validator->getMessages() as $message) { echo "$message\n"; } } ``` As well as using `ALLOW_ALL` to accept all common hostnames types, you can combine these types to allow for combinations. For example, to accept DNS and Local hostnames: ```php use Zend\Validator\Hostname; $validator = new Hostname(Hostname::ALLOW_DNS | Hostname::ALLOW_IP); ``` ## Validating International Domains Names Some Country Code Top Level Domains (ccTLDs), such as 'de' (Germany), support international characters in domain names. These are known as International Domain Names (IDN). These domains can be matched by `Zend\Validator\Hostname` via extended characters that are used in the validation process. At the time of writing, more than 50 ccTLDs support IDN domains. The `Hostname` validator matches IDN domains by default. If you wish to disable IDN validation, either pass a parameter to the `Zend\Validator\Hostname` constructor or call the `setValidateIdn()` method. You can disable IDN validation by passing a second parameter to the `Zend\Validator\Hostname` constructor in the following way. ```php $validator = new Zend\Validator\Hostname([ 'allow' => Zend\Validator\Hostname::ALLOW_DNS, 'useIdnCheck' => false, ]); ``` Alternatively you can either pass `true` or `false` to `setValidateIdn()` to enable or disable IDN validation. If you are trying to match an IDN hostname which isn't currently supported, it is likely it will fail validation if it has any international characters in it. Where a ccTLD file doesn't exist in `Zend/Validator/Hostname` specifying the additional characters, a normal hostname validation is performed. Please note that IDNs are only validated if you allow DNS hostnames to be validated. ## Validating Top Level Domains By default, a hostname will be verified against a list of known TLDs. If this functionality is not required, it can be disabled in much the same way as disabling IDN support. You can disable TLD validation by passing a third parameter to the `Zend\Validator\Hostname` constructor. In the example below we are supporting IDN validation via the second parameter. ```php use Zend\Validator\Hostname; $validator = new Hostname([ 'allow' => Hostname::ALLOW_DNS, 'useIdnCheck' => true, 'useTldCheck' => false, ]); ``` Alternatively you can either pass `true` or `false` to `setValidateTld()` to enable or disable TLD validation. Please note, TLDs are only validated if you allow DNS hostnames to be validated. ================================================ FILE: docs/book/validators/iban.md ================================================ # Iban Validator `Zend\Validator\Iban` validates if a given value could be a IBAN number. IBAN is the abbreviation for "International Bank Account Number". ## Supported options The following options are supported for `Zend\Validator\Iban`: - `country_code`: Sets the country code which is used to get the IBAN format for validation. ## IBAN validation IBAN numbers are always related to a country. This means that different countries use different formats for their IBAN numbers. This is the reason why IBAN numbers always need a country code. By knowing this we already know how to use `Zend\Validator\Iban`. ### Ungreedy IBAN validation Sometime it is useful just to validate if the given value is a IBAN number or not. This means that you don't want to validate it against a defined country. This can be done by using `false` as locale. ```php $validator = new Zend\Validator\Iban(['country_code' => false]); // Note: you can also provide FALSE as the sole parameter if ($validator->isValid('AT611904300234573201')) { // IBAN appears to be valid } else { // IBAN is not valid } ``` In this situation, any IBAN number from any country will considered valid. Note that this should not be done when you accept only accounts from a single country! ### Region aware IBAN validation To validate against a defined country, you just provide a country code. You can do this during instaniation via the option `country_code`, or afterwards by using `setCountryCode()`. ```php $validator = new Zend\Validator\Iban(['country_code' => 'AT']); if ($validator->isValid('AT611904300234573201')) { // IBAN appears to be valid } else { // IBAN is not valid } ``` ================================================ FILE: docs/book/validators/identical.md ================================================ # Identical Validator `Zend\Validator\Identical` allows you to validate if a given value is identical with a set token. ## Supported options The following options are supported for `Zend\Validator\Identical`: - `strict`: Defines if the validation should be strict (i.e., if types should also be considered). The default value is `true`. - `token`: Sets the token against which the input will be validated. - `literal`: If set to `true`, the validation will skip the lookup for elements in the form context, and validate the token just the way it was provided. The default value is `false`. ## Basic usage To validate if two values are identical, you need to set the original value as the token, as demonstrated in the following example: token. ```php $valid = new Zend\Validator\Identical('origin'); if ($valid->isValid($value)) { return true; } ``` The validation will only then return `true` when both values are 100% identical. In our example, when `$value` is `'origin'`. You can set the token after instantiation by using the method `setToken()`. ## Identical objects `Zend\Validator\Identical` can validate not only strings, but any other variable type, such as booleans, integers, floats, arrays, or even objects. As already noted, the token and value must be identical. ```php $valid = new Zend\Validator\Identical(123); if ($valid->isValid($input)) { // input appears to be valid } else { // input is invalid } ``` > ### Type comparison > > You should be aware of the variable type used for validation. This means that > the string `'3'` is not identical to integer `3`. When you want non-strict > validation, you must set the `strict` option to `false`. ## Form elements `Zend\Validator\Identical` supports the comparison of form elements. This can be done by using the element's name as the `token`: ```php $form->add([ 'name' => 'elementOne', 'type' => 'Password', ]); $form->add([ 'name' => 'elementTwo', 'type' => 'Password', 'validators' => [ [ 'name' => 'Identical', 'options' => [ 'token' => 'elementOne', ], ], ], ]); ``` By using the element's name from the first element as the `token` for the second element, the validator validates if the second element is equal with the first element. In the case your user does not enter two identical values, you will get a validation error. ### Validating a Value From a Fieldset Sometimes you will need to validate an input that lives inside a fieldset, and this can be accomplished as follows: ```php use Zend\Form\Element; use Zend\Form\Fieldset; use Zend\Form\Form; use Zend\InputFilter\Input; use Zend\InputFilter\InputFilter; $userFieldset = new Fieldset('user'); // (1) $userFieldset->add([ 'name' => 'email', // (2) 'type' => 'Email', ]); // Let's add one fieldset inside the 'user' fieldset, // so we can see how to manage the token in a different deepness $deeperFieldset = new Fieldset('deeperFieldset'); // (3) $deeperFieldset->add([ 'name' => 'deeperFieldsetInput', // (4) 'type' => 'Text', 'options' => [ 'label' => 'What validator are we testing?', ], ]); $userFieldset->add($deeperFieldset); $signUpForm = new Form('signUp'); $signUpForm->add($userFieldset); // Add an input that will validate the 'email' input from 'user' fieldset $signUpForm->add([ 'name' => 'confirmEmail', // (5) 'type' => 'Email', ]); // Add an input that will validate the 'deeperFieldsetInput' from // 'deeperFieldset' that lives inside the 'user' fieldset $signUpForm->add([ 'name' => 'confirmTestingValidator', // (6) 'type' => 'Text', ]); // This will ensure the user enter the same email in 'email' (2) and // 'confirmEmail' (5) $inputFilter = new InputFilter(); $inputFilter->add([ 'name' => 'confirmEmail', // references (5) 'validators' => [ [ 'name' => 'Identical', 'options' => [ // 'user' key references 'user' fieldset (1), and 'email' // references 'email' element inside 'user' fieldset (2) 'token' => ['user' => 'email'], ], ], ], ]); // This will ensure the user enter the same string in 'deeperFieldsetInput' (4) // and 'confirmTestingValidator' (6) $inputFilter->add([ 'name' => 'confirmTestingValidator', // references (6) 'validators' => [ [ 'name' => 'Identical', 'options' => [ 'token' => [ 'user' => [ // references 'user' fieldset (1) // 'deeperFieldset' key references 'deeperFieldset' // fieldset (3); 'deeperFieldsetInput' references // 'deeperFieldsetInput' element (4) 'deeperFieldset' => 'deeperFieldsetInput', ], ], ], ], ], ]); $signUpForm->setInputFilter($inputFilter); ``` > #### Use one token per leaf > > Aways make sure that your token array have just one key per level all the way > till the leaf, otherwise you can end up with unexpected results. ## Strict validation As mentioned before, `Zend\Validator\Identical` validates tokens using strict typing. You can change this behaviour by using the `strict` option. The default value for this property is `true`. ```php $valid = new Zend\Validator\Identical(['token' => 123, 'strict' => false]); $input = '123'; if ($valid->isValid($input)) { // input appears to be valid } else { // input is invalid } ``` The difference to the previous example is that the validation returns in this case `true`, even if you compare a integer with string value as long as the content is identical but not the type. For convenience you can also use `setStrict()` and `getStrict()`. ## Configuration As all other validators, `Zend\Validator\Identical` also supports the usage of configuration settings during instantiation. This means that you can configure this validator with a `Traversable` object. There is a case which you should be aware of. If you are using an array as token, and it contains a `token` key, you should wrap it within another `token` key. See the examples below to understand this situation. ```php // This will not validate ['token' => 123], it will actually validate the // integer 123 $valid = new Zend\Validator\Identical(['token' => 123]); if ($valid->isValid($input)) { // input appears to be valid } else { // input is invalid } ``` The reason for this special case is that you can configure the token which has to be used by giving the `token` key. So, when you are using an array as the token, and it contains one element with a `token` key, then you have to wrap it as shown in the example below: ```php // Unlike the previous example, this will validate ['token' => 123] $valid = new Zend\Validator\Identical(['token' => ['token' => 123]]); if ($valid->isValid($input)) { // input appears to be valid } else { // input is invalid } ``` If the array you are willing to validate does not have a `token` key, you do not need to wrap it. ================================================ FILE: docs/book/validators/in-array.md ================================================ # InArray Validator `Zend\Validator\InArray` allows you to validate if a given value is contained within an array. It is also able to validate multidimensional arrays. ## Supported options The following options are supported for `Zend\Validator\InArray`: - `haystack`: Sets the haystack for the validation. - `recursive`: Defines if the validation should be done recursively. This option defaults to `false`. - `strict`: Three modes of comparison are offered owing to an often overlooked, and potentially dangerous security issue when validating string input from user input. - `InArray::COMPARE_STRICT`: This is a normal `in_array()` strict comparison that checks value and type. - `InArray::COMPARE_NOT_STRICT`: This is a normal `in_array()` non-strict comparison that checks value only, but not type. - `InArray::COMPARE_NOT_STRICT_AND_PREVENT_STR_TO_INT_VULNERABILTY`: This operates in essentially the same way as `InArray::COMPARE_NOT_STRICT`, but ensures that strings are not cast to integer during comparison, preventing `0 == 'foo43'` types of false positives. > ### Use non-strict carefully > > Non-strict mode (`InArray::COMPARE_NOT_STRICT`) may give false positives when > strings are compared against ints or floats owing to `in_array()`'s behaviour > of converting strings to int in such cases. Therefore, `'foo'` would become > `0`, `'43foo'` would become `43`, while `foo43'` would also become `0`. ## Array validation Basic usage is to provide an array during instantiation: ```php $validator = new Zend\Validator\InArray([ 'haystack' => ['value1', 'value2',...'valueN'], ]); if ($validator->isValid('value')) { // value found } else { // no value found } ``` This will behave exactly like PHP's `in_array()` method when passed only a needle and haystack. > ### Non-strict by default > > By default, this validation is not strict, nor can it validate > multidimensional arrays. Alternately, you can define the array to validate against after object construction by using the `setHaystack()` method. `getHaystack()` returns the actual set haystack array. ```php $validator = new Zend\Validator\InArray(); $validator->setHaystack(['value1', 'value2',...'valueN']); if ($validator->isValid('value')) { // value found } else { // no value found } ``` ## Array validation modes As previously mentioned, there are possible security issues when using the default non-strict comparison mode, so rather than restricting the developer, we've chosen to offer both strict and non-strict comparisons, and add a safer middle-ground. It's possible to set the strict mode at initialisation and afterwards with the `setStrict` method. `InArray::COMPARE_STRICT` equates to `true` and `InArray::COMPARE_NOT_STRICT_AND_PREVENT_STR_TO_INT_VULNERABILITY` equates to `false`. ```php // defaults to InArray::COMPARE_NOT_STRICT_AND_PREVENT_STR_TO_INT_VULNERABILITY $validator = new Zend\Validator\InArray([ 'haystack' => ['value1', 'value2', /* ... */ 'valueN'], ]); // set strict mode $validator = new Zend\Validator\InArray([ 'haystack' => ['value1', 'value2', /* ... */ 'valueN'], 'strict' => InArray::COMPARE_STRICT, // equates to ``true`` ]); // set non-strict mode $validator = new Zend\Validator\InArray([ 'haystack' => ['value1', 'value2', /* ... */ 'valueN'], 'strict' => InArray:COMPARE_NOT_STRICT, // equates to ``false`` ]); // or $validator->setStrict(InArray::COMPARE_STRICT); $validator->setStrict(InArray::COMPARE_NOT_STRICT); $validator->setStrict(InArray::COMPARE_NOT_STRICT_AND_PREVENT_STR_TO_INT_VULNERABILITY); ``` > ### Non-strict safe-mode by default > > Note that the `strict` setting is per default `false`. ## Recursive array validation In addition to PHP's `in_array()` method, this validator can also be used to validate multidimensional arrays. To validate multidimensional arrays you have to set the `recursive` option. ```php $validator = new Zend\Validator\InArray([ 'haystack' => [ 'firstDimension' => ['value1', 'value2', / ... */ 'valueN'], 'secondDimension' => ['foo1', 'foo2', /* ... */ 'fooN'], ], 'recursive' => true, ]); if ($validator->isValid('value')) { // value found } else { // no value found } ``` Your array will then be validated recursively to see if the given value is contained. Additionally you could use `setRecursive()` to set this option afterwards and `getRecursive()` to retrieve it. ```php $validator = new Zend\Validator\InArray([ 'firstDimension' => ['value1', 'value2', /* ... */ 'valueN'], 'secondDimension' => ['foo1', 'foo2', /* ... */ 'fooN'], ]); $validator->setRecursive(true); if ($validator->isValid('value')) { // value found } else { // no value found } ``` > ### Default setting for recursion > > By default, the recursive validation is turned off. > ### Option keys within the haystack > > When you are using the keys `haystack`, `strict`, or `recursive` within > your haystack, then you must wrap the `haystack` key. ================================================ FILE: docs/book/validators/ip.md ================================================ # Ip Validator `Zend\Validator\Ip` allows you to validate if a given value is an IP address. It supports the IPv4, IPv6, and IPvFuture definitions. ## Supported options The following options are supported for `Zend\Validator\Ip`: - `allowipv4`: Defines if the validator allows IPv4 addresses. This option defaults to `true`. - `allowipv6`: Defines if the validator allows IPv6 addresses. This option defaults to `true`. - `allowipvfuture`: Defines if the validator allows IPvFuture addresses. This option defaults to `false`. - `allowliteral`: Defines if the validator allows IPv6 or IPvFuture with URI literal style (the IP surrounded by brackets). This option defaults to `true`. ## Basic usage ```php $validator = new Zend\Validator\Ip(); if ($validator->isValid($ip)) { // ip appears to be valid } else { // ip is invalid; print the reasons } ``` > ### Invalid IP addresses > > Keep in mind that `Zend\Validator\Ip` only validates IP addresses. Addresses > like '`mydomain.com`' or '`192.168.50.1/index.html`' are not valid IP > addresses. They are either hostnames or valid URLs but not IP addresses. > ### IPv6/IPvFuture validation > > `Zend\Validator\Ip` validates IPv6/IPvFuture addresses using a regex. The > reason is that the filters and methods from PHP itself don't follow the RFC. > Many other available classes also don't follow it. ## Validate IPv4 or IPV6 alone Sometimes it's useful to validate only one of the supported formats; e.g., when your network only supports IPv4. In this case it would be useless to allow IPv6 within this validator. To limit `Zend\Validator\Ip` to one protocol, you can set the options `allowipv4` or `allowipv6` to `false`. You can do this either by giving the option to the constructor or by using `setOptions()` afterwards. ```php $validator = new Zend\Validator\Ip(['allowipv6' => false]); if ($validator->isValid($ip)) { // ip appears to be valid ipv4 address } else { // ip is not an ipv4 address } ``` > ### Default behaviour > > The default behaviour which `Zend\Validator\Ip` follows is to allow both > standards. ================================================ FILE: docs/book/validators/is-countable.md ================================================ # IsCountable Validator - **Since 2.10.0** `Zend\Validator\IsCountable` allows you to validate that a value can be counted (i.e., it's an array or implements `Countable`), and, optionally: - the exact count of the value - the minimum count of the value - the maximum count of the value Specifying either of the latter two is inconsistent with the first, and, as such, the validator does not allow setting both a count and a minimum or maximum value. You may, however specify both minimum and maximum values, in which case the validator operates similar to the [Between validator](between.md). ## Supported options The following options are supported for `Zend\Validator\IsCountable`: - `count`: Defines if the validation should look for a specific, exact count for the value provided. - `max`: Sets the maximum value for the validation; if the count of the value is greater than the maximum, validation fails.. - `min`: Sets the minimum value for the validation; if the count of the value is lower than the minimum, validation fails. ## Default behaviour Given no options, the validator simply tests to see that the value may be counted (i.e., it's an array or `Countable` instance): ```php $validator = new Zend\Validator\IsCountable(); $validator->isValid(10); // false; not an array or Countable $validator->isValid([10]); // true; value is an array $validator->isValid(new ArrayObject([10])); // true; value is Countable $validator->isValid(new stdClass); // false; value is not Countable ``` ## Specifying an exact count You can also specify an exact count; if the value is countable, and its count matches, the the value is valid. ```php $validator = new Zend\Validator\IsCountable(['count' => 3]); $validator->isValid([1, 2, 3]); // true; countable, and count is 3 $validator->isValid(new ArrayObject([1, 2, 3])); // true; countable, and count is 3 $validator->isValid([1]); // false; countable, but count is 1 $validator->isValid(new ArrayObject([1])); // false; countable, but count is 1 ``` ## Specifying a minimum count You may specify a minimum count. When you do, the value must be countable, and greater than or equal to the minimum count you specify in order to be valid. ```php $validator = new Zend\Validator\IsCountable(['min' => 2]); $validator->isValid([1, 2, 3]); // true; countable, and count is 3 $validator->isValid(new ArrayObject([1, 2, 3])); // true; countable, and count is 3 $validator->isValid([1, 2]); // true; countable, and count is 2 $validator->isValid(new ArrayObject([1, 2])); // true; countable, and count is 2 $validator->isValid([1]); // false; countable, but count is 1 $validator->isValid(new ArrayObject([1])); // false; countable, but count is 1 ``` ## Specifying a maximum count You may specify a maximum count. When you do, the value must be countable, and less than or equal to the maximum count you specify in order to be valid. ```php $validator = new Zend\Validator\IsCountable(['max' => 2]); $validator->isValid([1, 2, 3]); // false; countable, but count is 3 $validator->isValid(new ArrayObject([1, 2, 3])); // false; countable, but count is 3 $validator->isValid([1, 2]); // true; countable, and count is 2 $validator->isValid(new ArrayObject([1, 2])); // true; countable, and count is 2 $validator->isValid([1]); // true; countable, and count is 1 $validator->isValid(new ArrayObject([1])); // true; countable, and count is 1 ``` ## Specifying both minimum and maximum If you specify both a minimum and maximum, the count must be _between_ the two, inclusively (i.e., it may be the minimum or maximum, and any value between). ```php $validator = new Zend\Validator\IsCountable([ 'min' => 3, 'max' => 5, ]); $validator->isValid([1, 2, 3]); // true; countable, and count is 3 $validator->isValid(new ArrayObject([1, 2, 3])); // true; countable, and count is 3 $validator->isValid(range(1, 5)); // true; countable, and count is 5 $validator->isValid(new ArrayObject(range(1, 5))); // true; countable, and count is 5 $validator->isValid([1, 2]); // false; countable, and count is 2 $validator->isValid(new ArrayObject([1, 2])); // false; countable, and count is 2 $validator->isValid(range(1, 6)); // false; countable, and count is 6 $validator->isValid(new ArrayObject(range(1, 6))); // false; countable, and count is 6 ``` ================================================ FILE: docs/book/validators/isbn.md ================================================ # Isbn Validator `Zend\Validator\Isbn` allows you to validate an ISBN-10 or ISBN-13 value. ## Supported options The following options are supported for `Zend\Validator\Isbn`: - `separator`: Defines the allowed separator for the ISBN number. It defaults to an empty string. - `type`: Defines the allowed ISBN types. It defaults to `Zend\Validator\Isbn::AUTO`. For details, take a look at the section on [explicit types](#setting-an-explicit-isbn-validation-type). ## Basic usage A basic example of usage is below: ```php $validator = new Zend\Validator\Isbn(); if ($validator->isValid($isbn)) { // isbn is valid } else { // isbn is not valid } ``` This will validate any ISBN-10 and ISBN-13 without separator. ## Setting an explicit ISBN validation type An example of an ISBN type restriction follows: ```php use Zend\Validator\Isbn; $validator = new Isbn(); $validator->setType(Isbn::ISBN13); // OR $validator = new Isbn([ 'type' => Isbn::ISBN13]); if ($validator->isValid($isbn)) { // this is a valid ISBN-13 value } else { // this is an invalid ISBN-13 value } ``` The above will validate only ISBN-13 values. Valid types include: - `Zend\Validator\Isbn::AUTO` (default) - `Zend\Validator\Isbn::ISBN10` - `Zend\Validator\Isbn::ISBN13` ## Specifying a separator restriction An example of separator restriction: ```php $validator = new Zend\Validator\Isbn(); $validator->setSeparator('-'); // OR $validator = new Zend\Validator\Isbn(['separator' => '-']); if ($validator->isValid($isbn)) { // this is a valid ISBN with separator } else { // this is an invalid ISBN with separator } ``` > ### Values without separators > > This will return `false` if `$isbn` doesn't contain a separator **or** if it's > an invalid *ISBN* value. Valid separators include: - `` (empty) (default) - `-` (hyphen) - ` ` (space) ================================================ FILE: docs/book/validators/isinstanceof.md ================================================ # IsInstanceOf Validator `Zend\Validator\IsInstanceOf` allows you to validate whether a given object is an instance of a specific class or interface. ## Supported options The following options are supported for `Zend\Validator\IsInstanceOf`: - `className`: Defines the fully-qualified class name which objects must be an instance of. ## Basic usage ```php $validator = new Zend\Validator\IsInstanceOf([ 'className' => 'Zend\Validator\Digits' ]); $object = new Zend\Validator\Digits(); if ($validator->isValid($object)) { // $object is an instance of Zend\Validator\Digits } else { // false. You can use $validator->getMessages() to retrieve error messages } ``` If a string argument is passed to the constructor of `Zend\Validator\IsInstanceOf`, then that value will be used as the class name: ```php use Zend\Validator\Digits; use Zend\Validator\IsInstanceOf; $validator = new IsInstanceOf(Digits::class); $object = new Digits(); if ($validator->isValid($object)) { // $object is an instance of Zend\Validator\Digits } else { // false. You can use $validator->getMessages() to retrieve error messages } ``` ================================================ FILE: docs/book/validators/less-than.md ================================================ # LessThan Validator `Zend\Validator\LessThan` allows you to validate if a given value is less than a maximum value. > Supports only number validation > > `Zend\Validator\LessThan` supports only the validation of numbers. Strings or > dates can not be validated with this validator. ## Supported options The following options are supported for `Zend\Validator\LessThan`: - `inclusive`: Defines if the validation is inclusive the maximum value or exclusive. It defaults to `false`. - `max`: Sets the maximum allowed value. ## Basic usage To validate if a given value is less than a defined maximum: ```php $valid = new Zend\Validator\LessThan(['max' => 10]); $value = 12; $return = $valid->isValid($value); // returns false ``` The above example returns `true` for all values lower than 10. ## Inclusive validation Sometimes it is useful to validate a value by including the maximum value: ```php $valid = new Zend\Validator\LessThan([ 'max' => 10, 'inclusive' => true, ]); $value = 10; $result = $valid->isValid($value); // returns true ``` The example is identical to our first example, with the exception that we've specified that the maximum is inclusive. Now the value '10' is allowed and will return `true`. ================================================ FILE: docs/book/validators/not-empty.md ================================================ # NotEmpty Validator This validator allows you to validate if a given value is not empty. This is often useful when working with form elements or other user input, where you can use it to ensure required elements have values associated with them. ## Supported options The following options are supported for `Zend\Validator\NotEmpty`: - `type`: Sets the type of validation which will be processed; for details, see the section on [specifying empty behavior](#specifying-empty-behavior). ## Default behaviour By default, this validator works differently than you would expect when you've worked with PHP's `empty()` operator. In particular, this validator will evaluate both the integer `0` and string `'0'` as empty. ```php $valid = new Zend\Validator\NotEmpty(); $value = ''; $result = $valid->isValid($value); // returns false ``` ## Specifying empty behavior Some projects have differing opinions of what is considered an "empty" value: a string with only whitespace might be considered empty, or `0` may be considered non-empty (particularly for boolean sequences). To accommodate differing needs, `Zend\Validator\NotEmpty` allows you to configure which types should be validated as empty and which not. The following types can be handled: - `boolean`: Returns `false` when the boolean value is `false`. - `integer`: Returns `false` when an integer `0` value is given. By default, this validation is not activate and returns `true` for any integer values. - `float`: Returns `false` when a float `0.0` value is given. By default, this validation is not activate and returns `true` on any float values. - `string`: Returns `false` when an empty string `''` is given. - `zero`: Returns `false` when the single character zero (`'0'`) is given. - `empty_array`: Returns `false` when an empty `array` is given. - `null`: Returns `false` when a `null` value is given. - `php`: Returns `false` on wherever PHP's `empty()` would return `true`. - `space`: Returns `false` when an string is given which contains only whitespace. - `object`: Returns `true`. `false` will be returned when `object` is not allowed but an object is given. - `object_string`: Returns `false` when an object is given and its `__toString()` method returns an empty string. - `object_count`: Returns `false` when an object is given, it implements `Countable`, and its count is 0. - `all`: Returns `false` on all above types. All other given values will return `true` per default. There are several ways to select which of the above types are validated. You can give one or multiple types and add them, you can provide an array, you can use constants, or you can provide a textual string. See the following examples: ```php use Zend\Validator\NotEmpty; // Returns false on 0 $validator = new NotEmpty(NotEmpty::INTEGER); // Returns false on 0 or '0' $validator = new NotEmpty( NotEmpty::INTEGER | NotEmpty::ZERO); // Returns false on 0 or '0' $validator = new NotEmpty([ NotEmpty::INTEGER, NotEmpty::ZERO ]); // Returns false on 0 or '0' $validator = new NotEmpty(['integer', 'zero']); ``` You can also provide an instance of `Traversable` to set the desired types. To set types after instantiation, use the `setType()` method. ================================================ FILE: docs/book/validators/regex.md ================================================ # Regex Validator This validator allows you to validate if a given string conforms a defined regular expression. ## Supported options The following options are supported for `Zend\Validator\Regex`: - `pattern`: Sets the regular expression pattern for this validator. ## Usage Validation with regular expressions allows complex validations without writing a custom validator. ```php $validator = new Zend\Validator\Regex(['pattern' => '/^Test/']); $validator->isValid("Test"); // returns true $validator->isValid("Testing"); // returns true $validator->isValid("Pest"); // returns false ``` The pattern uses the same syntax as `preg_match()`. For details about regular expressions take a look into [PHP's manual about PCRE pattern syntax](http://php.net/reference.pcre.pattern.syntax). ## Pattern handling It is also possible to set a different pattern afterwards by using `setPattern()` and to get the actual set pattern with `getPattern()`. ```php $validator = new Zend\Validator\Regex(['pattern' => '/^Test/']); $validator->setPattern('ing$/'); $validator->isValid("Test"); // returns false $validator->isValid("Testing"); // returns true $validator->isValid("Pest"); // returns false ``` ================================================ FILE: docs/book/validators/sitemap.md ================================================ # Sitemap Validators The following validators conform to the [Sitemap XML protocol](http://www.sitemaps.org/protocol.php). ## Supported options There are no additional supported options for any of the `Sitemap` validators. ## Changefreq `Zend\Validator\Sitemap\Changefreq` validates whether a string is valid for using as a 'changefreq' element in a Sitemap XML document. Valid values are: 'always', 'hourly', 'daily', 'weekly', 'monthly', 'yearly', or 'never'. Returns `true` if and only if the value is a string and is equal to one of the frequencies specified above. ## Sitemap\\Lastmod `Zend\Validator\Sitemap\Lastmod` validates whether a string is valid for using as a 'lastmod' element in a Sitemap XML document. The lastmod element should contain a W3C date string, optionally discarding information about time. Returns `true` if and only if the given value is a string and is valid according to the protocol. ```php $validator = new Zend\Validator\Sitemap\Lastmod(); $validator->isValid('1999-11-11T22:23:52-02:00'); // true $validator->isValid('2008-05-12T00:42:52+02:00'); // true $validator->isValid('1999-11-11'); // true $validator->isValid('2008-05-12'); // true $validator->isValid('1999-11-11t22:23:52-02:00'); // false $validator->isValid('2008-05-12T00:42:60+02:00'); // false $validator->isValid('1999-13-11'); // false $validator->isValid('2008-05-32'); // false $validator->isValid('yesterday'); // false ``` ## Loc `Zend\Validator\Sitemap\Loc` validates whether a string is valid for using as a 'loc' element in a Sitemap XML document. This uses [Zend\\Uri\\Uri::isValid()](https://docs.zendframework.com/zend-uri/usage/#validating-the-uri) internally. > ### Installation requirements > > `Zend\Validator\Sitemap\Loc` depends on the zend-uri component, so be sure to > have it installed before getting started: > > ```bash > $ composer require zendframework/zend-uri > ``` ## Priority `Zend\Validator\Sitemap\Priority` validates whether a value is valid for using as a 'priority' element in a Sitemap XML document. The value should be a decimal between 0.0 and 1.0. This validator accepts both numeric values and string values. ```php $validator = new Zend\Validator\Sitemap\Priority(); $validator->isValid('0.1'); // true $validator->isValid('0.789'); // true $validator->isValid(0.8); // true $validator->isValid(1.0); // true $validator->isValid('1.1'); // false $validator->isValid('-0.4'); // false $validator->isValid(1.00001); // false $validator->isValid(0xFF); // false $validator->isValid('foo'); // false ``` ================================================ FILE: docs/book/validators/step.md ================================================ # Step Validator `Zend\Validator\Step` allows you to validate if a given value is a valid step value. This validator requires the value to be a numeric value (either string, int or float). ## Supported options The following options are supported for `Zend\Validator\Step`: - `baseValue`: This is the base value from which the step should be computed. This option defaults to `0` - `step`: This is the step value. This option defaults to `1` ## Basic usage ```php $validator = new Zend\Validator\Step(); if ($validator->isValid(1)) { // value is a valid step value } else { // false } ``` ## Using floating-point values The `Step` validator also supports floating-point base and step values: ```php $validator = new Zend\Validator\Step([ 'baseValue' => 1.1, 'step' => 2.2, ]); echo $validator->isValid(1.1); // prints true echo $validator->isValid(3.3); // prints true echo $validator->isValid(3.35); // prints false echo $validator->isValid(2.2); // prints false ``` ================================================ FILE: docs/book/validators/string-length.md ================================================ # StringLength Validator This validator allows you to validate if a given string is between a defined length. > ### Supports only string validation > > `Zend\Validator\StringLength` supports only the validation of strings. > Integers, floats, dates or objects can not be validated with this validator. ## Supported options The following options are supported for `Zend\Validator\StringLength`: - `encoding`: Sets the `ICONV` encoding to use with the string. - `min`: Sets the minimum allowed length for a string. - `max`: Sets the maximum allowed length for a string. ## Default behaviour By default, this validator checks if a value is between `min` and `max` using a default `min` value of `0` and default `max` value of `NULL` (meaning unlimited). As such, without any options, the validator only checks that the input is a string. ## Limiting the maximum string length To limit the maximum allowed length of a string you need to set the `max` property. It accepts an integer value as input. ```php $validator = new Zend\Validator\StringLength(['max' => 6]); $validator->isValid("Test"); // returns true $validator->isValid("Testing"); // returns false ``` You can set the maximum allowed length after instantiation by using the `setMax()` method; `getMax()` retrieves the value. ```php $validator = new Zend\Validator\StringLength(); $validator->setMax(6); $validator->isValid("Test"); // returns true $validator->isValid("Testing"); // returns false ``` ## Limiting the minimum string length To limit the minimal required string length, set the `min` property using an integer value: ```php $validator = new Zend\Validator\StringLength(['min' => 5]); $validator->isValid("Test"); // returns false $validator->isValid("Testing"); // returns true ``` You can set the value after instantiation using the `setMin()` method; `getMin()` retrieves the value. ```php $validator = new Zend\Validator\StringLength(); $validator->setMin(5); $validator->isValid("Test"); // returns false $validator->isValid("Testing"); // returns true ``` ## Limiting both minimum and maximum string length Sometimes you will need to set both a minimum and a maximum string length; as an example, in a username input, you may want to limit the name to a maximum of 30 characters, but require at least three charcters: ```php $validator = new Zend\Validator\StringLength(['min' => 3, 'max' => 30]); $validator->isValid("."); // returns false $validator->isValid("Test"); // returns true $validator->isValid("Testing"); // returns true ``` ## Limiting to a strict length If you need a strict length, then set the `min` and `max` properties to the same value: ```php $validator = new Zend\Validator\StringLength(['min' => 4, 'max' => 4]); $validator->isValid('Tes'); // returns false $validator->isValid('Test'); // returns true $validator->isValid('Testi'); // returns false ``` > ### Setting a maximum lower than the minimum > > When you try to set a lower maximum value than the specified minimum value, or > a higher minimum value as the actual maximum value, the validator will raise > an exception. ## Encoding of values Strings are always using a encoding. Even when you don't set the encoding explicitly, PHP uses one. When your application is using a different encoding than PHP itself, you should set an encoding manually. You can set an encoding at instantiation with the `encoding` option, or by using the `setEncoding()` method. We assume that your installation uses ISO and your application it set to ISO. In this case you will see the below behaviour. ```php $validator = new Zend\Validator\StringLength(['min' => 6]); $validator->isValid("Ärger"); // returns false $validator->setEncoding("UTF-8"); $validator->isValid("Ärger"); // returns true $validator2 = new Zend\Validator\StringLength([ 'min' => 6, 'encoding' => 'UTF-8', ]); $validator2->isValid("Ärger"); // returns true ``` When your installation and your application are using different encodings, then you should always set an encoding manually. ## Validation Messages Using the setMessage() method you can set another message to be returned in case of the specified failure. ```php $validator = new Zend\Validator\StringLength(['min' => 3, 'max' => 30]); $validator->setMessage('Youre string is too long. You typed '%length%' chars.', Zend\Validator\StringLength::TOO_LONG); ``` ================================================ FILE: docs/book/validators/timezone.md ================================================ # Timezone Validator `Zend\Validator\Timezone` allows validating if an input string represents a timezone. ## Supported validation types The `Zend\Validator\Timezone` validator is capable of validating the abbreviation (e.g. `ewt`) as well as the location string (e.g. `America/Los_Angeles`). These options are stored in the validator as `LOCATION`, `ABBREVIATION`, and `ALL` class constants. ## Basic Usage The default validation type will check against abbreviations as well as the location string. ```php $validator = new Zend\Validator\Timezone(); $validator->isValid('America/Los_Angeles'); // returns true $validator->isValid('ewt'); // returns true $validator->isValid('Foobar'); // returns false ``` To validate against only the location string you can set the type: ```php use Zend\Validator\Timezone; $validator = new Timezone(); $validator->setType(Timezone::LOCATION); $validator->isValid('America/Los_Angeles'); // returns true $validator->isValid('ewt'); // returns false $validator->isValid('Foobar'); // returns false ``` ================================================ FILE: docs/book/validators/undisclosed-password.md ================================================ # Undisclosed Password Validator - **Since 2.13.0** `Zend\Validator\UndisclosedPassword` allows you to validate if a given password was found in data breaches using the service [Have I Been Pwned?](https://www.haveibeenpwned.com), in a secure, anonymous way using [K-Anonymity](https://www.troyhunt.com/ive-just-launched-pwned-passwords-version-2) to ensure passwords are not send in full over the wire. > ### Installation requirements > > This validator needs to make a request over HTTP; therefore it requires an HTTP client. The validator provides support only for HTTP clients implementing [PSR-18](https://www.php-fig.org/psr/psr-18/) and [PSR-17](https://www.php-fig.org/psr/psr-17/) request and response factories. > > To ensure you have these installed before using this validator, run the following: > > ```bash > $ composer require psr/http-client > $ composer require psr/http-factory > ``` ## Basic usage The validator has three required constructor arguments: - an HTTP Client that implements `Psr\Http\Client\ClientInterface` - a `Psr\Http\Message\RequestFactoryInterface` instance - a `Psr\Http\Message\ResponseFactoryInterface` instance Once you have an instance, you can then pass a password to its `isValid()` method to determine if it has been disclosed in a known data breach. If the password was found via the service, `isValid()` will return `false`. If the password was not found, `isValid()` will return `true`. ```php $validator = new Zend\Validator\UndisclosedPassword( $httpClient, // a PSR-18 HttpClientInterface $requestFactory, // a PSR-17 RequestFactoryInterface $responseFactory // a PSR-17 ResponseFactoryInterface ); $result = $validator->isValid('password'); // $result is FALSE because "password" was found in a data breach $result = $validator->isValid('8aDk=XiW2E.77tLfuAcB'); // $result is TRUE because "8aDk=XiW2E.77tLfuAcB" was not found in a data breach ``` ## A simple command line example In this example, I'm using `zendframework/zend-diactoros` to provide HTTP messages, and `php-http/curl-client` as the HTTP client. Let's begin with installation of all required packages: ```bash $ composer require \ php-http/message \ php-http/message-factory \ php-http/discovery \ php-http/curl-client \ zendframework/zend-diactoros \ zendframework/zend-validator ``` Next, I create a file, `undisclosed.php`, where I put my code: ```php isValid('password') ? 'not disclosed' : 'disclosed') . PHP_EOL; echo 'Password "NVt3MpvQ" is ' . ($undisclosedPassword->isValid('NVt3MpvQ') ? 'not disclosed' : 'disclosed') . PHP_EOL; ``` To run it, I use the PHP command line interpreter: ```bash $ php undisclosed.php ``` And it gives me the following output: ```bash Password "password" is disclosed Password "NVt3MpvQ" is not disclosed ``` ================================================ FILE: docs/book/validators/uri.md ================================================ # Uri Validator `Zend\Validator\Uri` allows you to validate a URI using the `Zend\Uri\Uri` handler to parse the URI. The validator allows for both validation of absolute and/or relative URIs. There is the possibility to exchange the handler for another one in case the parsing of the uri should be done differently. ## Supported options The following options are supported for `Zend\Validator\Uri`: - `uriHandler`: Defines the handler to be used to parse the uri. This options defaults to a new instance of `Zend\Uri\Uri`. - `allowRelative`: Defines if relative paths are allowed. This option defaults to `true`. - `allowAbsolute`: Defines if absolute paths are allowed. This option defaults to `true`. ## Basic usage ```php $validator = new Zend\Validator\Uri(); $uri = 'http://framework.zend.com/manual'; if ($validator->isValid($uri)) { // $uri was valid } else { // false. You can use $validator->getMessages() to retrieve error messages } ``` ================================================ FILE: docs/book/validators/uuid.md ================================================ # UUID Validator `Zend\Validator\Uuid` allows validating [Universally Unique IDentifiers](https://en.wikipedia.org/wiki/Universally_unique_identifier) (UUIDs). UUIDs are 128-bit values that are guaranteed to be "practically unique" in order to help prevent identifier conflicts. Five separate UUID versions exist: - Version 1, which uses a combination of date-time and hardware MAC addresses to generate the hash. - Version 2, which uses a combination of date-time and system user/group identifiers. - Version 3, which uses an MD5sum of a URI or distinguished name to generate the hash. - Version 4, which uses a CSPRNG to generate the hash. - Version 5, which uses the same idea as Version 3, but using SHA-1 for hashing. The `Uuid` validator is capable of validating whether a string is a valid UUID of any version. It does not validate that the UUID exists in your system, however, only that it is well-formed. > ### Introduced in 2.8.0 > > `Zend\Validator\Uuid` was introduced with version 2.8.0. ## Supported options The `Uuid` validator has no additional options. ## Basic usage ```php $validator = new Zend\Validator\Uuid(); if ($validator->isValid($uuid)) { // UUID was valid } else { // Invalid/mal-formed UUID; use $validator->getMessages() for more detail } ``` ================================================ FILE: docs/book/writing-validators.md ================================================ # Writing Validators zend-validator supplies a set of commonly needed validators, but many applications have needs for custom validators. The component allows this via implementations of `Zend\Validator\ValidatorInterface`. `Zend\Validator\ValidatorInterface` defines two methods: `isValid()` and `getMessages()`. An object that implements the interface may be added to a validator chain using `Zend\Validator\ValidatorChain::addValidator()`. Such objects may also be used with [zend-inputfilter](https://docs.zendframework.com/zend-inputfilter). Validators will return a boolean value from `isValid()`, and report information regarding **why** a value failed validation via `getMessages()`. The availability of the reasons for validation failures may be valuable to an application for various purposes, such as providing statistics for usability analysis. Basic validation failure message functionality is implemented in `Zend\Validator\AbstractValidator`, which you may extend for your custom validators. Extending class you would implement the `isValid()` method logic and define the message variables and message templates that correspond to the types of validation failures that can occur. If a value fails your validation tests, then `isValid()` should return `false`. If the value passes your validation tests, then `isValid()` should return `true`. In general, the `isValid()` method should not throw any exceptions, except where it is impossible to determine whether or not the input value is valid. A few examples of reasonable cases for throwing an exception might be if a file cannot be opened, an LDAP server could not be contacted, or a database connection is unavailable, where such a thing may be required for validation success or failure to be determined. ## Creating a Validation Class The following example demonstrates how a custom validator might be written. In this case, the validator tests that a value is a floating point value. ```php namespace MyValid; use Zend\Validator\AbstractValidator; class Float extends AbstractValidator { const FLOAT = 'float'; protected $messageTemplates = [ self::FLOAT => "'%value%' is not a floating point value", ]; public function isValid($value) { $this->setValue($value); if (! is_float($value)) { $this->error(self::FLOAT); return false; } return true; } } ``` The class defines a template for its single validation failure message, which includes the built-in magic parameter, `%value%`. The call to `setValue()` prepares the object to insert the tested value into the failure message automatically, should the value fail validation. The call to `error()` tracks a reason for validation failure. Since this class only defines one failure message, it is not necessary to provide `error()` with the name of the failure message template. ## Writing a Validation Class having Dependent Conditions The following example demonstrates a more complex set of validation rules: - The input must be numeric. - The input must fall within a range of boundary values. An input value would fail validation for exactly one of the following reasons: - The input value is not numeric. - The input value is less than the minimum allowed value. - The input value is more than the maximum allowed value. These validation failure reasons are then translated to definitions in the class: ```php namespace MyValid; use Zend\Validator\AbstractValidator; class NumericBetween extends AbstractValidator { const MSG_NUMERIC = 'msgNumeric'; const MSG_MINIMUM = 'msgMinimum'; const MSG_MAXIMUM = 'msgMaximum'; public $minimum = 0; public $maximum = 100; protected $messageVariables = [ 'min' => 'minimum', 'max' => 'maximum', ]; protected $messageTemplates = [ self::MSG_NUMERIC => "'%value%' is not numeric", self::MSG_MINIMUM => "'%value%' must be at least '%min%'", self::MSG_MAXIMUM => "'%value%' must be no more than '%max%'", ]; public function isValid($value) { $this->setValue($value); if (! is_numeric($value)) { $this->error(self::MSG_NUMERIC); return false; } if ($value < $this->minimum) { $this->error(self::MSG_MINIMUM); return false; } if ($value > $this->maximum) { $this->error(self::MSG_MAXIMUM); return false; } return true; } } ``` The public properties `$minimum` and `$maximum` have been established to provide the minimum and maximum boundaries, respectively, for a value to successfully validate. The class also defines two message variables that correspond to the public properties and allow `min` and `max` to be used in message templates as magic parameters, just as with `value`. Note that if any one of the validation checks in `isValid()` fails, an appropriate failure message is prepared, and the method immediately returns `false`. These validation rules are therefore sequentially dependent; that is, if one test should fail, there is no need to test any subsequent validation rules. This need not be the case, however. The following example illustrates how to write a class having independent validation rules, where the validation object may return multiple reasons why a particular validation attempt failed. ## Validation with Independent Conditions, Multiple Reasons for Failure Consider writing a validation class for password strength enforcement - when a user is required to choose a password that meets certain criteria for helping secure user accounts. Let us assume that the password security criteria enforce that the password: - is at least 8 characters in length, - contains at least one uppercase letter, - contains at least one lowercase letter, - and contains at least one digit character. The following class implements these validation criteria: ```php namespace MyValid; use Zend\Validator\AbstractValidator; class PasswordStrength extends AbstractValidator { const LENGTH = 'length'; const UPPER = 'upper'; const LOWER = 'lower'; const DIGIT = 'digit'; protected $messageTemplates = [ self::LENGTH => "'%value%' must be at least 8 characters in length", self::UPPER => "'%value%' must contain at least one uppercase letter", self::LOWER => "'%value%' must contain at least one lowercase letter", self::DIGIT => "'%value%' must contain at least one digit character", ]; public function isValid($value) { $this->setValue($value); $isValid = true; if (strlen($value) < 8) { $this->error(self::LENGTH); $isValid = false; } if (! preg_match('/[A-Z]/', $value)) { $this->error(self::UPPER); $isValid = false; } if (! preg_match('/[a-z]/', $value)) { $this->error(self::LOWER); $isValid = false; } if (! preg_match('/\d/', $value)) { $this->error(self::DIGIT); $isValid = false; } return $isValid; } } ``` Note that the four criteria tests in `isValid()` do not immediately return `false`. This allows the validation class to provide **all** of the reasons that the input password failed to meet the validation requirements. If, for example, a user were to input the string `#$%` as a password, `isValid()` would cause all four validation failure messages to be returned by a subsequent call to `getMessages()`. ================================================ FILE: mkdocs.yml ================================================ docs_dir: docs/book site_dir: docs/html nav: - Home: index.md - Introduction: intro.md - Reference: - "Validator Chains": validator-chains.md - "Writing Validators": writing-validators.md - "Validation Messages": messages.md - "Standard Validation Classes": set.md - Validators: - Barcode: validators/barcode.md - Between: validators/between.md - Callback: validators/callback.md - CreditCard: validators/credit-card.md - Date: validators/date.md - "Db\\RecordExists and Db\\NoRecordExists": validators/db.md - Digits: validators/digits.md - EmailAddress: validators/email-address.md - Explode: validators/explode.md - GreaterThan: validators/greater-than.md - Hex: validators/hex.md - Hostname: validators/hostname.md - Iban: validators/iban.md - Identical: validators/identical.md - InArray: validators/in-array.md - Ip: validators/ip.md - Isbn: validators/isbn.md - IsCountable: validators/is-countable.md - IsInstanceOf: validators/isinstanceof.md - LessThan: validators/less-than.md - NotEmpty: validators/not-empty.md - Regex: validators/regex.md - Sitemap: validators/sitemap.md - Step: validators/step.md - StringLength: validators/string-length.md - Timezone: validators/timezone.md - UndisclosedPassword: validators/undisclosed-password.md - Uri: validators/uri.md - Uuid: validators/uuid.md - "File Validators": - Introduction: validators/file/intro.md - Count: validators/file/count.md - Crc32: validators/file/crc32.md - ExcludeExtension: validators/file/exclude-extension.md - ExcludeMimeType: validators/file/exclude-mime-type.md - Exists: validators/file/exists.md - Extension: validators/file/extension.md - FilesSize: validators/file/files-size.md - Hash: validators/file/hash.md - ImageSize: validators/file/image-size.md - IsCompressed: validators/file/is-compressed.md - IsImage: validators/file/is-image.md - Md5: validators/file/md5.md - MimeType: validators/file/mime-type.md - NotExists: validators/file/not-exists.md - Sha1: validators/file/sha1.md - Size: validators/file/size.md - Upload: validators/file/upload.md - UploadFile: validators/file/upload-file.md - WordCount: validators/file/word-count.md site_name: zend-validator site_description: "Validation classes for a wide range of domains, and the ability to chain validators to create complex validation criteria." repo_url: 'https://github.com/zendframework/zend-validator' ================================================ FILE: phpcs.xml ================================================  src test ================================================ FILE: phpunit.xml.dist ================================================ ./test/ disable ./src ================================================ FILE: src/AbstractValidator.php ================================================ [], // Array of validation failure messages 'messageTemplates' => [], // Array of validation failure message templates 'messageVariables' => [], // Array of additional variables available for validation failure messages 'translator' => null, // Translation object to used -> Translator\TranslatorInterface 'translatorTextDomain' => null, // Translation text domain 'translatorEnabled' => true, // Is translation enabled? 'valueObscured' => false, // Flag indicating whether or not value should be obfuscated // in error messages ]; /** * Abstract constructor for all validators * A validator should accept following parameters: * - nothing f.e. Validator() * - one or multiple scalar values f.e. Validator($first, $second, $third) * - an array f.e. Validator(array($first => 'first', $second => 'second', $third => 'third')) * - an instance of Traversable f.e. Validator($config_instance) * * @param array|Traversable $options */ public function __construct($options = null) { // The abstract constructor allows no scalar values if ($options instanceof Traversable) { $options = ArrayUtils::iteratorToArray($options); } if (isset($this->messageTemplates)) { $this->abstractOptions['messageTemplates'] = $this->messageTemplates; } if (isset($this->messageVariables)) { $this->abstractOptions['messageVariables'] = $this->messageVariables; } if (is_array($options)) { $this->setOptions($options); } } /** * Returns an option * * @param string $option Option to be returned * @return mixed Returned option * @throws Exception\InvalidArgumentException */ public function getOption($option) { if (array_key_exists($option, $this->abstractOptions)) { return $this->abstractOptions[$option]; } if (isset($this->options) && array_key_exists($option, $this->options)) { return $this->options[$option]; } throw new Exception\InvalidArgumentException("Invalid option '$option'"); } /** * Returns all available options * * @return array Array with all available options */ public function getOptions() { $result = $this->abstractOptions; if (isset($this->options)) { $result += $this->options; } return $result; } /** * Sets one or multiple options * * @param array|Traversable $options Options to set * @throws Exception\InvalidArgumentException If $options is not an array or Traversable * @return AbstractValidator Provides fluid interface */ public function setOptions($options = []) { if (! is_array($options) && ! $options instanceof Traversable) { throw new Exception\InvalidArgumentException(__METHOD__ . ' expects an array or Traversable'); } foreach ($options as $name => $option) { $fname = 'set' . ucfirst($name); $fname2 = 'is' . ucfirst($name); if (($name !== 'setOptions') && method_exists($this, $name)) { $this->{$name}($option); } elseif (($fname !== 'setOptions') && method_exists($this, $fname)) { $this->{$fname}($option); } elseif (method_exists($this, $fname2)) { $this->{$fname2}($option); } elseif (isset($this->options)) { $this->options[$name] = $option; } else { $this->abstractOptions[$name] = $option; } } return $this; } /** * Returns array of validation failure messages * * @return array */ public function getMessages() { return array_unique($this->abstractOptions['messages'], SORT_REGULAR); } /** * Invoke as command * * @param mixed $value * @return bool */ public function __invoke($value) { return $this->isValid($value); } /** * Returns an array of the names of variables that are used in constructing validation failure messages * * @return array */ public function getMessageVariables() { return array_keys($this->abstractOptions['messageVariables']); } /** * Returns the message templates from the validator * * @return array */ public function getMessageTemplates() { return $this->abstractOptions['messageTemplates']; } /** * Sets the validation failure message template for a particular key * * @param string $messageString * @param string $messageKey OPTIONAL * @return AbstractValidator Provides a fluent interface * @throws Exception\InvalidArgumentException */ public function setMessage($messageString, $messageKey = null) { if ($messageKey === null) { $keys = array_keys($this->abstractOptions['messageTemplates']); foreach ($keys as $key) { $this->setMessage($messageString, $key); } return $this; } if (! isset($this->abstractOptions['messageTemplates'][$messageKey])) { throw new Exception\InvalidArgumentException("No message template exists for key '$messageKey'"); } $this->abstractOptions['messageTemplates'][$messageKey] = $messageString; return $this; } /** * Sets validation failure message templates given as an array, where the array keys are the message keys, * and the array values are the message template strings. * * @param array $messages * @return AbstractValidator */ public function setMessages(array $messages) { foreach ($messages as $key => $message) { $this->setMessage($message, $key); } return $this; } /** * Magic function returns the value of the requested property, if and only if it is the value or a * message variable. * * @param string $property * @return mixed * @throws Exception\InvalidArgumentException */ public function __get($property) { if ($property == 'value') { return $this->value; } if (array_key_exists($property, $this->abstractOptions['messageVariables'])) { $result = $this->abstractOptions['messageVariables'][$property]; if (is_array($result)) { return $this->{key($result)}[current($result)]; } return $this->{$result}; } if (isset($this->messageVariables) && array_key_exists($property, $this->messageVariables)) { $result = $this->{$this->messageVariables[$property]}; if (is_array($result)) { return $this->{key($result)}[current($result)]; } return $this->{$result}; } throw new Exception\InvalidArgumentException("No property exists by the name '$property'"); } /** * Constructs and returns a validation failure message with the given message key and value. * * Returns null if and only if $messageKey does not correspond to an existing template. * * If a translator is available and a translation exists for $messageKey, * the translation will be used. * * @param string $messageKey * @param string|array|object $value * @return string */ protected function createMessage($messageKey, $value) { if (! isset($this->abstractOptions['messageTemplates'][$messageKey])) { return; } $message = $this->abstractOptions['messageTemplates'][$messageKey]; $message = $this->translateMessage($messageKey, $message); if (is_object($value) && ! in_array('__toString', get_class_methods($value)) ) { $value = get_class($value) . ' object'; } elseif (is_array($value)) { $value = var_export($value, 1); } else { $value = (string) $value; } if ($this->isValueObscured()) { $value = str_repeat('*', strlen($value)); } $message = str_replace('%value%', (string) $value, $message); foreach ($this->abstractOptions['messageVariables'] as $ident => $property) { if (is_array($property)) { $value = $this->{key($property)}[current($property)]; if (is_array($value)) { $value = '[' . implode(', ', $value) . ']'; } } else { $value = $this->$property; } $message = str_replace("%$ident%", (string) $value, $message); } $length = self::getMessageLength(); if (($length > -1) && (strlen($message) > $length)) { $message = substr($message, 0, ($length - 3)) . '...'; } return $message; } /** * @param string $messageKey * @param string $value OPTIONAL * @return void */ protected function error($messageKey, $value = null) { if ($messageKey === null) { $keys = array_keys($this->abstractOptions['messageTemplates']); $messageKey = current($keys); } if ($value === null) { $value = $this->value; } $this->abstractOptions['messages'][$messageKey] = $this->createMessage($messageKey, $value); } /** * Returns the validation value * * @return mixed Value to be validated */ protected function getValue() { return $this->value; } /** * Sets the value to be validated and clears the messages and errors arrays * * @param mixed $value * @return void */ protected function setValue($value) { $this->value = $value; $this->abstractOptions['messages'] = []; } /** * Set flag indicating whether or not value should be obfuscated in messages * * @param bool $flag * @return AbstractValidator */ public function setValueObscured($flag) { $this->abstractOptions['valueObscured'] = (bool) $flag; return $this; } /** * Retrieve flag indicating whether or not value should be obfuscated in * messages * * @return bool */ public function isValueObscured() { return $this->abstractOptions['valueObscured']; } /** * Set translation object * * @param Translator\TranslatorInterface|null $translator * @param string $textDomain (optional) * @return AbstractValidator * @throws Exception\InvalidArgumentException */ public function setTranslator(Translator\TranslatorInterface $translator = null, $textDomain = null) { $this->abstractOptions['translator'] = $translator; if (null !== $textDomain) { $this->setTranslatorTextDomain($textDomain); } return $this; } /** * Return translation object * * @return Translator\TranslatorInterface|null */ public function getTranslator() { if (! $this->isTranslatorEnabled()) { return; } if (null === $this->abstractOptions['translator']) { $this->abstractOptions['translator'] = self::getDefaultTranslator(); } return $this->abstractOptions['translator']; } /** * Does this validator have its own specific translator? * * @return bool */ public function hasTranslator() { return (bool) $this->abstractOptions['translator']; } /** * Set translation text domain * * @param string $textDomain * @return AbstractValidator */ public function setTranslatorTextDomain($textDomain = 'default') { $this->abstractOptions['translatorTextDomain'] = $textDomain; return $this; } /** * Return the translation text domain * * @return string */ public function getTranslatorTextDomain() { if (null === $this->abstractOptions['translatorTextDomain']) { $this->abstractOptions['translatorTextDomain'] = self::getDefaultTranslatorTextDomain(); } return $this->abstractOptions['translatorTextDomain']; } /** * Set default translation object for all validate objects * * @param Translator\TranslatorInterface|null $translator * @param string $textDomain (optional) * @return void * @throws Exception\InvalidArgumentException */ public static function setDefaultTranslator(Translator\TranslatorInterface $translator = null, $textDomain = null) { static::$defaultTranslator = $translator; if (null !== $textDomain) { self::setDefaultTranslatorTextDomain($textDomain); } } /** * Get default translation object for all validate objects * * @return Translator\TranslatorInterface|null */ public static function getDefaultTranslator() { return static::$defaultTranslator; } /** * Is there a default translation object set? * * @return bool */ public static function hasDefaultTranslator() { return (bool) static::$defaultTranslator; } /** * Set default translation text domain for all validate objects * * @param string $textDomain * @return void */ public static function setDefaultTranslatorTextDomain($textDomain = 'default') { static::$defaultTranslatorTextDomain = $textDomain; } /** * Get default translation text domain for all validate objects * * @return string */ public static function getDefaultTranslatorTextDomain() { return static::$defaultTranslatorTextDomain; } /** * Indicate whether or not translation should be enabled * * @param bool $flag * @return AbstractValidator */ public function setTranslatorEnabled($flag = true) { $this->abstractOptions['translatorEnabled'] = (bool) $flag; return $this; } /** * Is translation enabled? * * @return bool */ public function isTranslatorEnabled() { return $this->abstractOptions['translatorEnabled']; } /** * Returns the maximum allowed message length * * @return int */ public static function getMessageLength() { return static::$messageLength; } /** * Sets the maximum allowed message length * * @param int $length */ public static function setMessageLength($length = -1) { static::$messageLength = $length; } /** * Translate a validation message * * @param string $messageKey * @param string $message * @return string */ protected function translateMessage($messageKey, $message) { $translator = $this->getTranslator(); if (! $translator) { return $message; } return $translator->translate($message, $this->getTranslatorTextDomain()); } } ================================================ FILE: src/Barcode/AbstractAdapter.php ================================================ null, // Allowed barcode lengths, integer, array, string 'characters' => null, // Allowed barcode characters 'checksum' => null, // Callback to checksum function 'useChecksum' => true, // Is a checksum value included?, boolean ]; /** * Checks the length of a barcode * * @param string $value The barcode to check for proper length * @return bool */ public function hasValidLength($value) { if (! is_string($value)) { return false; } $fixum = strlen($value); $found = false; $length = $this->getLength(); if (is_array($length)) { foreach ($length as $value) { if ($fixum == $value) { $found = true; } if ($value == -1) { $found = true; } } } elseif ($fixum == $length) { $found = true; } elseif ($length == -1) { $found = true; } elseif ($length == 'even') { $count = $fixum % 2; $found = (0 == $count); } elseif ($length == 'odd') { $count = $fixum % 2; $found = (1 == $count); } return $found; } /** * Checks for allowed characters within the barcode * * @param string $value The barcode to check for allowed characters * @return bool */ public function hasValidCharacters($value) { if (! is_string($value)) { return false; } $characters = $this->getCharacters(); if ($characters == 128) { for ($x = 0; $x < 128; ++$x) { $value = str_replace(chr($x), '', $value); } } else { $chars = str_split($characters); foreach ($chars as $char) { $value = str_replace($char, '', $value); } } if (strlen($value) > 0) { return false; } return true; } /** * Validates the checksum * * @param string $value The barcode to check the checksum for * @return bool */ public function hasValidChecksum($value) { $checksum = $this->getChecksum(); if (! empty($checksum)) { if (method_exists($this, $checksum)) { return $this->$checksum($value); } } return false; } /** * Returns the allowed barcode length * * @return int|array */ public function getLength() { return $this->options['length']; } /** * Returns the allowed characters * * @return int|string|array */ public function getCharacters() { return $this->options['characters']; } /** * Returns the checksum function name * */ public function getChecksum() { return $this->options['checksum']; } /** * Sets the checksum validation method * * @param callable $checksum Checksum method to call * @return AbstractAdapter */ protected function setChecksum($checksum) { $this->options['checksum'] = $checksum; return $this; } /** * Sets the checksum validation, if no value is given, the actual setting is returned * * @param bool $check * @return AbstractAdapter|bool */ public function useChecksum($check = null) { if ($check === null) { return $this->options['useChecksum']; } $this->options['useChecksum'] = (bool) $check; return $this; } /** * Sets the length of this barcode * * @param int|array $length * @return AbstractAdapter */ protected function setLength($length) { $this->options['length'] = $length; return $this; } /** * Sets the allowed characters of this barcode * * @param int $characters * @return AbstractAdapter */ protected function setCharacters($characters) { $this->options['characters'] = $characters; return $this; } /** * Validates the checksum (Modulo 10) * GTIN implementation factor 3 * * @param string $value The barcode to validate * @return bool */ protected function gtin($value) { $barcode = substr($value, 0, -1); $sum = 0; $length = strlen($barcode) - 1; for ($i = 0; $i <= $length; $i++) { if (($i % 2) === 0) { $sum += $barcode[$length - $i] * 3; } else { $sum += $barcode[$length - $i]; } } $calc = $sum % 10; $checksum = ($calc === 0) ? 0 : (10 - $calc); if ($value[$length + 1] != $checksum) { return false; } return true; } /** * Validates the checksum (Modulo 10) * IDENTCODE implementation factors 9 and 4 * * @param string $value The barcode to validate * @return bool */ protected function identcode($value) { $barcode = substr($value, 0, -1); $sum = 0; $length = strlen($value) - 2; for ($i = 0; $i <= $length; $i++) { if (($i % 2) === 0) { $sum += $barcode[$length - $i] * 4; } else { $sum += $barcode[$length - $i] * 9; } } $calc = $sum % 10; $checksum = ($calc === 0) ? 0 : (10 - $calc); if ($value[$length + 1] != $checksum) { return false; } return true; } /** * Validates the checksum (Modulo 10) * CODE25 implementation factor 3 * * @param string $value The barcode to validate * @return bool */ protected function code25($value) { $barcode = substr($value, 0, -1); $sum = 0; $length = strlen($barcode) - 1; for ($i = 0; $i <= $length; $i++) { if (($i % 2) === 0) { $sum += $barcode[$i] * 3; } else { $sum += $barcode[$i]; } } $calc = $sum % 10; $checksum = ($calc === 0) ? 0 : (10 - $calc); if ($value[$length + 1] != $checksum) { return false; } return true; } /** * Validates the checksum () * POSTNET implementation * * @param string $value The barcode to validate * @return bool */ protected function postnet($value) { $checksum = substr($value, -1, 1); $values = str_split(substr($value, 0, -1)); $check = 0; foreach ($values as $row) { $check += $row; } $check %= 10; $check = 10 - $check; if ($check == $checksum) { return true; } return false; } } ================================================ FILE: src/Barcode/AdapterInterface.php ================================================ setLength(-1); $this->setCharacters('0123456789-$:/.+ABCDTN*E'); $this->useChecksum(false); } /** * Checks for allowed characters * @see Zend\Validator\Barcode.AbstractAdapter::checkChars() */ public function hasValidCharacters($value) { if (strpbrk($value, 'ABCD')) { $first = $value[0]; if (! strpbrk($first, 'ABCD')) { // Missing start char return false; } $last = substr($value, -1, 1); if (! strpbrk($last, 'ABCD')) { // Missing stop char return false; } $value = substr($value, 1, -1); } elseif (strpbrk($value, 'TN*E')) { $first = $value[0]; if (! strpbrk($first, 'TN*E')) { // Missing start char return false; } $last = substr($value, -1, 1); if (! strpbrk($last, 'TN*E')) { // Missing stop char return false; } $value = substr($value, 1, -1); } $chars = $this->getCharacters(); $this->setCharacters('0123456789-$:/.+'); $result = parent::hasValidCharacters($value); $this->setCharacters($chars); return $result; } } ================================================ FILE: src/Barcode/Code128.php ================================================ setLength(-1); $this->setCharacters([ 'A' => [ 0 => ' ', 1 => '!', 2 => '"', 3 => '#', 4 => '$', 5 => '%', 6 => '&', 7 => "'", 8 => '(', 9 => ')', 10 => '*', 11 => '+', 12 => ',', 13 => '-', 14 => '.', 15 => '/', 16 => '0', 17 => '1', 18 => '2', 19 => '3', 20 => '4', 21 => '5', 22 => '6', 23 => '7', 24 => '8', 25 => '9', 26 => ':', 27 => ';', 28 => '<', 29 => '=', 30 => '>', 31 => '?', 32 => '@', 33 => 'A', 34 => 'B', 35 => 'C', 36 => 'D', 37 => 'E', 38 => 'F', 39 => 'G', 40 => 'H', 41 => 'I', 42 => 'J', 43 => 'K', 44 => 'L', 45 => 'M', 46 => 'N', 47 => 'O', 48 => 'P', 49 => 'Q', 50 => 'R', 51 => 'S', 52 => 'T', 53 => 'U', 54 => 'V', 55 => 'W', 56 => 'X', 57 => 'Y', 58 => 'Z', 59 => '[', 60 => '\\', 61 => ']', 62 => '^', 63 => '_', 64 => 0x00, 65 => 0x01, 66 => 0x02, 67 => 0x03, 68 => 0x04, 69 => 0x05, 70 => 0x06, 71 => 0x07, 72 => 0x08, 73 => 0x09, 74 => 0x0A, 75 => 0x0B, 76 => 0x0C, 77 => 0x0D, 78 => 0x0E, 79 => 0x0F, 80 => 0x10, 81 => 0x11, 82 => 0x12, 83 => 0x13, 84 => 0x14, 85 => 0x15, 86 => 0x16, 87 => 0x17, 88 => 0x18, 89 => 0x19, 90 => 0x1A, 91 => 0x1B, 92 => 0x1C, 93 => 0x1D, 94 => 0x1E, 95 => 0x1F, 96 => 'Ç', 97 => 'ü', 98 => 'é', 99 => 'â', 100 => 'ä', 101 => 'à', 102 => 'å', 103 => '‡', 104 => 'ˆ', 105 => '‰', 106 => 'Š'], 'B' => [ 0 => ' ', 1 => '!', 2 => '"', 3 => '#', 4 => '$', 5 => '%', 6 => '&', 7 => "'", 8 => '(', 9 => ')', 10 => '*', 11 => '+', 12 => ',', 13 => '-', 14 => '.', 15 => '/', 16 => '0', 17 => '1', 18 => '2', 19 => '3', 20 => '4', 21 => '5', 22 => '6', 23 => '7', 24 => '8', 25 => '9', 26 => ':', 27 => ';', 28 => '<', 29 => '=', 30 => '>', 31 => '?', 32 => '@', 33 => 'A', 34 => 'B', 35 => 'C', 36 => 'D', 37 => 'E', 38 => 'F', 39 => 'G', 40 => 'H', 41 => 'I', 42 => 'J', 43 => 'K', 44 => 'L', 45 => 'M', 46 => 'N', 47 => 'O', 48 => 'P', 49 => 'Q', 50 => 'R', 51 => 'S', 52 => 'T', 53 => 'U', 54 => 'V', 55 => 'W', 56 => 'X', 57 => 'Y', 58 => 'Z', 59 => '[', 60 => '\\', 61 => ']', 62 => '^', 63 => '_', 64 => '`', 65 => 'a', 66 => 'b', 67 => 'c', 68 => 'd', 69 => 'e', 70 => 'f', 71 => 'g', 72 => 'h', 73 => 'i', 74 => 'j', 75 => 'k', 76 => 'l', 77 => 'm', 78 => 'n', 79 => 'o', 80 => 'p', 81 => 'q', 82 => 'r', 83 => 's', 84 => 't', 85 => 'u', 86 => 'v', 87 => 'w', 88 => 'x', 89 => 'y', 90 => 'z', 91 => '{', 92 => '|', 93 => '}', 94 => '~', 95 => 0x7F, 96 => 'Ç', 97 => 'ü', 98 => 'é', 99 => 'â', 100 => 'ä', 101 => 'à', 102 => 'å', 103 => '‡', 104 => 'ˆ', 105 => '‰', 106 => 'Š'], 'C' => [ 0 => '00', 1 => '01', 2 => '02', 3 => '03', 4 => '04', 5 => '05', 6 => '06', 7 => '07', 8 => '08', 9 => '09', 10 => '10', 11 => '11', 12 => '12', 13 => '13', 14 => '14', 15 => '15', 16 => '16', 17 => '17', 18 => '18', 19 => '19', 20 => '20', 21 => '21', 22 => '22', 23 => '23', 24 => '24', 25 => '25', 26 => '26', 27 => '27', 28 => '28', 29 => '29', 30 => '30', 31 => '31', 32 => '32', 33 => '33', 34 => '34', 35 => '35', 36 => '36', 37 => '37', 38 => '38', 39 => '39', 40 => '40', 41 => '41', 42 => '42', 43 => '43', 44 => '44', 45 => '45', 46 => '46', 47 => '47', 48 => '48', 49 => '49', 50 => '50', 51 => '51', 52 => '52', 53 => '53', 54 => '54', 55 => '55', 56 => '56', 57 => '57', 58 => '58', 59 => '59', 60 => '60', 61 => '61', 62 => '62', 63 => '63', 64 => '64', 65 => '65', 66 => '66', 67 => '67', 68 => '68', 69 => '69', 70 => '70', 71 => '71', 72 => '72', 73 => '73', 74 => '74', 75 => '75', 76 => '76', 77 => '77', 78 => '78', 79 => '79', 80 => '80', 81 => '81', 82 => '82', 83 => '83', 84 => '84', 85 => '85', 86 => '86', 87 => '87', 88 => '88', 89 => '89', 90 => '90', 91 => '91', 92 => '92', 93 => '93', 94 => '94', 95 => '95', 96 => '96', 97 => '97', 98 => '98', 99 => '99', 100 => 'ä', 101 => 'à', 102 => 'å', 103 => '‡', 104 => 'ˆ', 105 => '‰', 106 => 'Š'] ]); $this->setChecksum('code128'); } public function setUtf8StringWrapper(StringWrapperInterface $utf8StringWrapper) { if (! $utf8StringWrapper->isSupported('UTF-8')) { throw new Exception\InvalidArgumentException( "The string wrapper needs to support UTF-8 character encoding" ); } $this->utf8StringWrapper = $utf8StringWrapper; } /** * Get the string wrapper supporting UTF-8 character encoding * * @return StringWrapperInterface */ public function getUtf8StringWrapper() { if (! $this->utf8StringWrapper) { $this->utf8StringWrapper = StringUtils::getWrapper('UTF-8'); } return $this->utf8StringWrapper; } /** * Checks for allowed characters within the barcode * * @param string $value The barcode to check for allowed characters * @return bool */ public function hasValidCharacters($value) { if (! is_string($value)) { return false; } // get used string wrapper for UTF-8 character encoding $strWrapper = $this->getUtf8StringWrapper(); // detect starting charset $set = $this->getCodingSet($value); $read = $set; if ($set != '') { $value = $strWrapper->substr($value, 1, null); } // process barcode while ($value != '') { $char = $strWrapper->substr($value, 0, 1); switch ($char) { // Function definition case 'Ç': case 'ü': case 'å': break; // Switch 1 char between A and B case 'é': if ($set == 'A') { $read = 'B'; } elseif ($set == 'B') { $read = 'A'; } break; // Switch to C case 'â': $set = 'C'; $read = 'C'; break; // Switch to B case 'ä': $set = 'B'; $read = 'B'; break; // Switch to A case 'à': $set = 'A'; $read = 'A'; break; // Doubled start character case '‡': case 'ˆ': case '‰': return false; // Chars after the stop character case 'Š': break 2; default: // Does the char exist within the charset to read? if ($this->ord128($char, $read) == -1) { return false; } break; } $value = $strWrapper->substr($value, 1, null); $read = $set; } if (($value != '') && ($strWrapper->strlen($value) != 1)) { return false; } return true; } /** * Validates the checksum () * * @param string $value The barcode to validate * @return bool */ protected function code128($value) { $sum = 0; $pos = 1; $set = $this->getCodingSet($value); $read = $set; $usecheck = $this->useChecksum(null); $strWrapper = $this->getUtf8StringWrapper(); $char = $strWrapper->substr($value, 0, 1); if ($char == '‡') { $sum = 103; } elseif ($char == 'ˆ') { $sum = 104; } elseif ($char == '‰') { $sum = 105; } elseif ($usecheck == true) { // no start value, unable to detect a proper checksum return false; } $value = $strWrapper->substr($value, 1, null); while ($strWrapper->strpos($value, 'Š') || ($value != '')) { $char = $strWrapper->substr($value, 0, 1); if ($read == 'C') { $char = $strWrapper->substr($value, 0, 2); } switch ($char) { // Function definition case 'Ç': case 'ü': case 'å': $sum += ($pos * $this->ord128($char, $set)); break; case 'é': $sum += ($pos * $this->ord128($char, $set)); if ($set == 'A') { $read = 'B'; } elseif ($set == 'B') { $read = 'A'; } break; // Switch to C case 'â': $sum += ($pos * $this->ord128($char, $set)); $set = 'C'; $read = 'C'; break; // Switch to B case 'ä': $sum += ($pos * $this->ord128($char, $set)); $set = 'B'; $read = 'B'; break; // Switch to A case 'à': $sum += ($pos * $this->ord128($char, $set)); $set = 'A'; $read = 'A'; break; case '‡': case 'ˆ': case '‰': return false; break; default: // Does the char exist within the charset to read? if ($this->ord128($char, $read) == -1) { return false; } $sum += ($pos * $this->ord128($char, $set)); break; } $value = $strWrapper->substr($value, 1); ++$pos; if (($strWrapper->strpos($value, 'Š') == 1) && ($strWrapper->strlen($value) == 2)) { // break by stop and checksum char break; } $read = $set; } if (($strWrapper->strpos($value, 'Š') != 1) || ($strWrapper->strlen($value) != 2)) { // return false if checksum is not readable and true if no startvalue is detected return (! $usecheck); } $mod = $sum % 103; if ($strWrapper->substr($value, 0, 1) == $this->chr128($mod, $set)) { return true; } return false; } /** * Returns the coding set for a barcode * * @param string $value Barcode * @return string */ protected function getCodingSet($value) { $value = $this->getUtf8StringWrapper()->substr($value, 0, 1); switch ($value) { case '‡': return 'A'; break; case 'ˆ': return 'B'; break; case '‰': return 'C'; break; } return ''; } /** * Internal method to return the code128 integer from an ascii value * * Table A * ASCII CODE128 * 32 to 95 == 0 to 63 * 0 to 31 == 64 to 95 * 128 to 138 == 96 to 106 * * Table B * ASCII CODE128 * 32 to 138 == 0 to 106 * * Table C * ASCII CODE128 * "00" to "99" == 0 to 99 * 132 to 138 == 100 to 106 * * @param string $value * @param string $set * @return int */ protected function ord128($value, $set) { $ord = ord($value); if ($set == 'A') { if ($ord < 32) { return ($ord + 64); } elseif ($ord < 96) { return ($ord - 32); } elseif ($ord > 138) { return -1; } else { return ($ord - 32); } } elseif ($set == 'B') { if ($ord < 32) { return -1; } elseif ($ord <= 138) { return ($ord - 32); } else { return -1; } } elseif ($set == 'C') { $val = (int) $value; if (($val >= 0) && ($val <= 99)) { return $val; } elseif (($ord >= 132) && ($ord <= 138)) { return ($ord - 32); } else { return -1; } } else { if ($ord < 32) { return ($ord + 64); } elseif ($ord <= 138) { return ($ord - 32); } else { return -1; } } } /** * Internal Method to return the ascii value from a code128 integer * * Table A * ASCII CODE128 * 32 to 95 == 0 to 63 * 0 to 31 == 64 to 95 * 128 to 138 == 96 to 106 * * Table B * ASCII CODE128 * 32 to 138 == 0 to 106 * * Table C * ASCII CODE128 * "00" to "99" == 0 to 99 * 132 to 138 == 100 to 106 * * @param int $value * @param string $set * @return string */ protected function chr128($value, $set) { if ($set == 'A') { if ($value < 64) { return chr($value + 32); } elseif ($value < 96) { return chr($value - 64); } elseif ($value > 106) { return -1; } else { return chr($value + 32); } } elseif ($set == 'B') { if ($value > 106) { return -1; } else { return chr($value + 32); } } elseif ($set == 'C') { if (($value >= 0) && ($value <= 9)) { return "0" . (string) $value; } elseif ($value <= 99) { return (string) $value; } elseif ($value <= 106) { return chr($value + 32); } else { return -1; } } else { if ($value <= 106) { return ($value + 32); } else { return -1; } } } } ================================================ FILE: src/Barcode/Code25.php ================================================ setLength(-1); $this->setCharacters('0123456789'); $this->setChecksum('code25'); $this->useChecksum(false); } } ================================================ FILE: src/Barcode/Code25interleaved.php ================================================ setLength('even'); $this->setCharacters('0123456789'); $this->setChecksum('code25'); $this->useChecksum(false); } } ================================================ FILE: src/Barcode/Code39.php ================================================ 0, '1' => 1, '2' => 2, '3' => 3, '4' => 4, '5' => 5, '6' => 6, '7' => 7, '8' => 8, '9' => 9, 'A' => 10, 'B' => 11, 'C' => 12, 'D' => 13, 'E' => 14, 'F' => 15, 'G' => 16, 'H' => 17, 'I' => 18, 'J' => 19, 'K' => 20, 'L' => 21, 'M' => 22, 'N' => 23, 'O' => 24, 'P' => 25, 'Q' => 26, 'R' => 27, 'S' => 28, 'T' => 29, 'U' => 30, 'V' => 31, 'W' => 32, 'X' => 33, 'Y' => 34, 'Z' => 35, '-' => 36, '.' => 37, ' ' => 38, '$' => 39, '/' => 40, '+' => 41, '%' => 42, ]; /** * Constructor for this barcode adapter */ public function __construct() { $this->setLength(-1); $this->setCharacters('0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ -.$/+%'); $this->setChecksum('code39'); $this->useChecksum(false); } /** * Validates the checksum (Modulo 43) * * @param string $value The barcode to validate * @return bool */ protected function code39($value) { $checksum = substr($value, -1, 1); $value = str_split(substr($value, 0, -1)); $count = 0; foreach ($value as $char) { $count += $this->check[$char]; } $mod = $count % 43; if ($mod == $this->check[$checksum]) { return true; } return false; } } ================================================ FILE: src/Barcode/Code39ext.php ================================================ setLength(-1); $this->setCharacters(128); $this->useChecksum(false); } } ================================================ FILE: src/Barcode/Code93.php ================================================ 0, '1' => 1, '2' => 2, '3' => 3, '4' => 4, '5' => 5, '6' => 6, '7' => 7, '8' => 8, '9' => 9, 'A' => 10, 'B' => 11, 'C' => 12, 'D' => 13, 'E' => 14, 'F' => 15, 'G' => 16, 'H' => 17, 'I' => 18, 'J' => 19, 'K' => 20, 'L' => 21, 'M' => 22, 'N' => 23, 'O' => 24, 'P' => 25, 'Q' => 26, 'R' => 27, 'S' => 28, 'T' => 29, 'U' => 30, 'V' => 31, 'W' => 32, 'X' => 33, 'Y' => 34, 'Z' => 35, '-' => 36, '.' => 37, ' ' => 38, '$' => 39, '/' => 40, '+' => 41, '%' => 42, '!' => 43, '"' => 44, '§' => 45, '&' => 46, ]; /** * Constructor for this barcode adapter */ public function __construct() { $this->setLength(-1); $this->setCharacters('0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ -.$/+%'); $this->setChecksum('code93'); $this->useChecksum(false); } /** * Validates the checksum (Modulo CK) * * @param string $value The barcode to validate * @return bool */ protected function code93($value) { $checksum = substr($value, -2, 2); $value = str_split(substr($value, 0, -2)); $count = 0; $length = count($value) % 20; foreach ($value as $char) { if ($length == 0) { $length = 20; } $count += $this->check[$char] * $length; --$length; } $check = array_search(($count % 47), $this->check); $value[] = $check; $count = 0; $length = count($value) % 15; foreach ($value as $char) { if ($length == 0) { $length = 15; } $count += $this->check[$char] * $length; --$length; } $check .= array_search(($count % 47), $this->check); if ($check == $checksum) { return true; } return false; } } ================================================ FILE: src/Barcode/Code93ext.php ================================================ setLength(-1); $this->setCharacters(128); $this->useChecksum(false); } } ================================================ FILE: src/Barcode/Ean12.php ================================================ setLength(12); $this->setCharacters('0123456789'); $this->setChecksum('gtin'); } } ================================================ FILE: src/Barcode/Ean13.php ================================================ setLength(13); $this->setCharacters('0123456789'); $this->setChecksum('gtin'); } } ================================================ FILE: src/Barcode/Ean14.php ================================================ setLength(14); $this->setCharacters('0123456789'); $this->setChecksum('gtin'); } } ================================================ FILE: src/Barcode/Ean18.php ================================================ setLength(18); $this->setCharacters('0123456789'); $this->setChecksum('gtin'); } } ================================================ FILE: src/Barcode/Ean2.php ================================================ setLength(2); $this->setCharacters('0123456789'); $this->useChecksum(false); } } ================================================ FILE: src/Barcode/Ean5.php ================================================ setLength(5); $this->setCharacters('0123456789'); $this->useChecksum(false); } } ================================================ FILE: src/Barcode/Ean8.php ================================================ setLength([7, 8]); $this->setCharacters('0123456789'); $this->setChecksum('gtin'); } /** * Overrides parent checkLength * * @param string $value Value * @return bool */ public function hasValidLength($value) { if (strlen($value) == 7) { $this->useChecksum(false); } else { $this->useChecksum(true); } return parent::hasValidLength($value); } } ================================================ FILE: src/Barcode/Gtin12.php ================================================ setLength(12); $this->setCharacters('0123456789'); $this->setChecksum('gtin'); } } ================================================ FILE: src/Barcode/Gtin13.php ================================================ setLength(13); $this->setCharacters('0123456789'); $this->setChecksum('gtin'); } } ================================================ FILE: src/Barcode/Gtin14.php ================================================ setLength(14); $this->setCharacters('0123456789'); $this->setChecksum('gtin'); } } ================================================ FILE: src/Barcode/Identcode.php ================================================ setLength(12); $this->setCharacters('0123456789'); $this->setChecksum('identcode'); } } ================================================ FILE: src/Barcode/Intelligentmail.php ================================================ setLength([20, 25, 29, 31]); $this->setCharacters('0123456789'); $this->useChecksum(false); } } ================================================ FILE: src/Barcode/Issn.php ================================================ setLength([8, 13]); $this->setCharacters('0123456789X'); $this->setChecksum('gtin'); } /** * Allows X on length of 8 chars * * @param string $value The barcode to check for allowed characters * @return bool */ public function hasValidCharacters($value) { if (strlen($value) != 8) { if (strpos($value, 'X') !== false) { return false; } } return parent::hasValidCharacters($value); } /** * Validates the checksum * * @param string $value The barcode to check the checksum for * @return bool */ public function hasValidChecksum($value) { if (strlen($value) == 8) { $this->setChecksum('issn'); } else { $this->setChecksum('gtin'); } return parent::hasValidChecksum($value); } /** * Validates the checksum () * ISSN implementation (reversed mod11) * * @param string $value The barcode to validate * @return bool */ protected function issn($value) { $checksum = substr($value, -1, 1); $values = str_split(substr($value, 0, -1)); $check = 0; $multi = 8; foreach ($values as $token) { if ($token == 'X') { $token = 10; } $check += ($token * $multi); --$multi; } $check %= 11; $check = ($check === 0 ? 0 : (11 - $check)); if ($check == $checksum) { return true; } elseif (($check == 10) && ($checksum == 'X')) { return true; } return false; } } ================================================ FILE: src/Barcode/Itf14.php ================================================ setLength(14); $this->setCharacters('0123456789'); $this->setChecksum('gtin'); } } ================================================ FILE: src/Barcode/Leitcode.php ================================================ setLength(14); $this->setCharacters('0123456789'); $this->setChecksum('identcode'); } } ================================================ FILE: src/Barcode/Planet.php ================================================ setLength([12, 14]); $this->setCharacters('0123456789'); $this->setChecksum('postnet'); } } ================================================ FILE: src/Barcode/Postnet.php ================================================ setLength([6, 7, 10, 12]); $this->setCharacters('0123456789'); $this->setChecksum('postnet'); } } ================================================ FILE: src/Barcode/Royalmail.php ================================================ 1, '1' => 1, '2' => 1, '3' => 1, '4' => 1, '5' => 1, '6' => 2, '7' => 2, '8' => 2, '9' => 2, 'A' => 2, 'B' => 2, 'C' => 3, 'D' => 3, 'E' => 3, 'F' => 3, 'G' => 3, 'H' => 3, 'I' => 4, 'J' => 4, 'K' => 4, 'L' => 4, 'M' => 4, 'N' => 4, 'O' => 5, 'P' => 5, 'Q' => 5, 'R' => 5, 'S' => 5, 'T' => 5, 'U' => 0, 'V' => 0, 'W' => 0, 'X' => 0, 'Y' => 0, 'Z' => 0, ]; protected $columns = [ '0' => 1, '1' => 2, '2' => 3, '3' => 4, '4' => 5, '5' => 0, '6' => 1, '7' => 2, '8' => 3, '9' => 4, 'A' => 5, 'B' => 0, 'C' => 1, 'D' => 2, 'E' => 3, 'F' => 4, 'G' => 5, 'H' => 0, 'I' => 1, 'J' => 2, 'K' => 3, 'L' => 4, 'M' => 5, 'N' => 0, 'O' => 1, 'P' => 2, 'Q' => 3, 'R' => 4, 'S' => 5, 'T' => 0, 'U' => 1, 'V' => 2, 'W' => 3, 'X' => 4, 'Y' => 5, 'Z' => 0, ]; /** * Constructor for this barcode adapter */ public function __construct() { $this->setLength(-1); $this->setCharacters('0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ'); $this->setChecksum('royalmail'); } /** * Validates the checksum () * * @param string $value The barcode to validate * @return bool */ protected function royalmail($value) { $checksum = substr($value, -1, 1); $values = str_split(substr($value, 0, -1)); $rowvalue = 0; $colvalue = 0; foreach ($values as $row) { $rowvalue += $this->rows[$row]; $colvalue += $this->columns[$row]; } $rowvalue %= 6; $colvalue %= 6; $rowchkvalue = array_keys($this->rows, $rowvalue); $colchkvalue = array_keys($this->columns, $colvalue); $intersect = array_intersect($rowchkvalue, $colchkvalue); $chkvalue = current($intersect); if ($chkvalue == $checksum) { return true; } return false; } /** * Allows start and stop tag within checked chars * * @param string $value The barcode to check for allowed characters * @return bool */ public function hasValidCharacters($value) { if ($value[0] == '(') { $value = substr($value, 1); if ($value[strlen($value) - 1] == ')') { $value = substr($value, 0, -1); } else { return false; } } return parent::hasValidCharacters($value); } } ================================================ FILE: src/Barcode/Sscc.php ================================================ setLength(18); $this->setCharacters('0123456789'); $this->setChecksum('gtin'); } } ================================================ FILE: src/Barcode/Upca.php ================================================ setLength(12); $this->setCharacters('0123456789'); $this->setChecksum('gtin'); } } ================================================ FILE: src/Barcode/Upce.php ================================================ setLength([6, 7, 8]); $this->setCharacters('0123456789'); $this->setChecksum('gtin'); } /** * Overrides parent checkLength * * @param string $value Value * @return bool */ public function hasValidLength($value) { if (strlen($value) != 8) { $this->useChecksum(false); } else { $this->useChecksum(true); } return parent::hasValidLength($value); } } ================================================ FILE: src/Barcode.php ================================================ "The input failed checksum validation", self::INVALID_CHARS => "The input contains invalid characters", self::INVALID_LENGTH => "The input should have a length of %length% characters", self::INVALID => "Invalid type given. String expected", ]; /** * Additional variables available for validation failure messages * * @var array */ protected $messageVariables = [ 'length' => ['options' => 'length'], ]; protected $options = [ 'adapter' => null, // Barcode adapter Zend\Validator\Barcode\AbstractAdapter 'options' => null, // Options for this adapter 'length' => null, 'useChecksum' => null, ]; /** * Constructor for barcodes * * @param array|string $options Options to use */ public function __construct($options = null) { if ($options === null) { $options = []; } if (! is_array($options) && ! ($options instanceof Traversable)) { $options = ['adapter' => $options]; } if (array_key_exists('options', $options)) { $options['options'] = ['options' => $options['options']]; } parent::__construct($options); } /** * Returns the set adapter * * @return Barcode\AbstractAdapter */ public function getAdapter() { if (! ($this->options['adapter'] instanceof Barcode\AdapterInterface)) { $this->setAdapter('Ean13'); } return $this->options['adapter']; } /** * Sets a new barcode adapter * * @param string|Barcode\AbstractAdapter $adapter Barcode adapter to use * @param array $options Options for this adapter * @return Barcode * @throws Exception\InvalidArgumentException */ public function setAdapter($adapter, $options = null) { if (is_string($adapter)) { $adapter = ucfirst(strtolower($adapter)); $adapter = 'Zend\\Validator\\Barcode\\' . $adapter; if (! class_exists($adapter)) { throw new Exception\InvalidArgumentException('Barcode adapter matching "' . $adapter . '" not found'); } $adapter = new $adapter($options); } if (! $adapter instanceof Barcode\AdapterInterface) { throw new Exception\InvalidArgumentException( sprintf( "Adapter %s does not implement Zend\\Validator\\Barcode\\AdapterInterface", (is_object($adapter) ? get_class($adapter) : gettype($adapter)) ) ); } $this->options['adapter'] = $adapter; return $this; } /** * Returns the checksum option * * @return string */ public function getChecksum() { return $this->getAdapter()->getChecksum(); } /** * Sets if checksum should be validated, if no value is given the actual setting is returned * * @param bool $checksum * @return bool */ public function useChecksum($checksum = null) { return $this->getAdapter()->useChecksum($checksum); } /** * Defined by Zend\Validator\ValidatorInterface * * Returns true if and only if $value contains a valid barcode * * @param string $value * @return bool */ public function isValid($value) { if (! is_string($value)) { $this->error(self::INVALID); return false; } $this->setValue($value); $adapter = $this->getAdapter(); $this->options['length'] = $adapter->getLength(); $result = $adapter->hasValidLength($value); if (! $result) { if (is_array($this->options['length'])) { $temp = $this->options['length']; $this->options['length'] = ""; foreach ($temp as $length) { $this->options['length'] .= "/"; $this->options['length'] .= $length; } $this->options['length'] = substr($this->options['length'], 1); } $this->error(self::INVALID_LENGTH); return false; } $result = $adapter->hasValidCharacters($value); if (! $result) { $this->error(self::INVALID_CHARS); return false; } if ($this->useChecksum(null)) { $result = $adapter->hasValidChecksum($value); if (! $result) { $this->error(self::FAILED); return false; } } return true; } } ================================================ FILE: src/Between.php ================================================ "The input is not between '%min%' and '%max%', inclusively", self::NOT_BETWEEN_STRICT => "The input is not strictly between '%min%' and '%max%'", self::VALUE_NOT_NUMERIC => "The min ('%min%') and max ('%max%') values are numeric, but the input is not", self::VALUE_NOT_STRING => "The min ('%min%') and max ('%max%') values are non-numeric strings, " . "but the input is not a string", ]; /** * Additional variables available for validation failure messages * * @var array */ protected $messageVariables = [ 'min' => ['options' => 'min'], 'max' => ['options' => 'max'], ]; /** * Options for the between validator * * @var array */ protected $options = [ 'inclusive' => true, // Whether to do inclusive comparisons, allowing equivalence to min and/or max 'min' => 0, 'max' => PHP_INT_MAX, ]; /** * Sets validator options * Accepts the following option keys: * 'min' => scalar, minimum border * 'max' => scalar, maximum border * 'inclusive' => boolean, inclusive border values * * @param array|Traversable $options * * @throws Exception\InvalidArgumentException */ public function __construct($options = null) { if ($options instanceof Traversable) { $options = ArrayUtils::iteratorToArray($options); } if (! is_array($options)) { $options = func_get_args(); $temp['min'] = array_shift($options); if (! empty($options)) { $temp['max'] = array_shift($options); } if (! empty($options)) { $temp['inclusive'] = array_shift($options); } $options = $temp; } if (! array_key_exists('min', $options) || ! array_key_exists('max', $options)) { throw new Exception\InvalidArgumentException("Missing option: 'min' and 'max' have to be given"); } if ((isset($options['min']) && is_numeric($options['min'])) && (isset($options['max']) && is_numeric($options['max'])) ) { $this->numeric = true; } elseif ((isset($options['min']) && is_string($options['min'])) && (isset($options['max']) && is_string($options['max'])) ) { $this->numeric = false; } else { throw new Exception\InvalidArgumentException( "Invalid options: 'min' and 'max' should be of the same scalar type" ); } parent::__construct($options); } /** * Returns the min option * * @return mixed */ public function getMin() { return $this->options['min']; } /** * Sets the min option * * @param mixed $min * @return Between Provides a fluent interface */ public function setMin($min) { $this->options['min'] = $min; return $this; } /** * Returns the max option * * @return mixed */ public function getMax() { return $this->options['max']; } /** * Sets the max option * * @param mixed $max * @return Between Provides a fluent interface */ public function setMax($max) { $this->options['max'] = $max; return $this; } /** * Returns the inclusive option * * @return bool */ public function getInclusive() { return $this->options['inclusive']; } /** * Sets the inclusive option * * @param bool $inclusive * @return Between Provides a fluent interface */ public function setInclusive($inclusive) { $this->options['inclusive'] = $inclusive; return $this; } /** * Returns true if and only if $value is between min and max options, inclusively * if inclusive option is true. * * @param mixed $value * @return bool */ public function isValid($value) { $this->setValue($value); if ($this->numeric && ! is_numeric($value)) { $this->error(self::VALUE_NOT_NUMERIC); return false; } if (! $this->numeric && ! is_string($value)) { $this->error(self::VALUE_NOT_STRING); return false; } if ($this->getInclusive()) { if ($this->getMin() > $value || $value > $this->getMax()) { $this->error(self::NOT_BETWEEN); return false; } } else { if ($this->getMin() >= $value || $value >= $this->getMax()) { $this->error(self::NOT_BETWEEN_STRICT); return false; } } return true; } } ================================================ FILE: src/Bitwise.php ================================================ "The input has no common bit set with '%control%'", self::NOT_AND_STRICT => "The input doesn't have the same bits set as '%control%'", self::NOT_XOR => "The input has common bit set with '%control%'", ]; /** * Additional variables available for validation failure messages * * @var array */ protected $messageVariables = [ 'control' => 'control', ]; /** * @var integer */ protected $operator; /** * @var boolean */ protected $strict = false; /** * Sets validator options * Accepts the following option keys: * 'control' => integer * 'operator' => * 'strict' => boolean * * @param array|Traversable $options */ public function __construct($options = null) { if ($options instanceof Traversable) { $options = iterator_to_array($options); } if (! is_array($options)) { $options = func_get_args(); $temp['control'] = array_shift($options); if (! empty($options)) { $temp['operator'] = array_shift($options); } if (! empty($options)) { $temp['strict'] = array_shift($options); } $options = $temp; } parent::__construct($options); } /** * Returns the control parameter. * * @return integer */ public function getControl() { return $this->control; } /** * Returns the operator parameter. * * @return string */ public function getOperator() { return $this->operator; } /** * Returns the strict parameter. * * @return boolean */ public function getStrict() { return $this->strict; } /** * Returns true if and only if $value is between min and max options, inclusively * if inclusive option is true. * * @param mixed $value * @return bool */ public function isValid($value) { $this->setValue($value); if (self::OP_AND === $this->operator) { if ($this->strict) { // All the bits set in value must be set in control $this->error(self::NOT_AND_STRICT); return (bool) (($this->control & $value) == $value); } else { // At least one of the bits must be common between value and control $this->error(self::NOT_AND); return (bool) ($this->control & $value); } } elseif (self::OP_XOR === $this->operator) { $this->error(self::NOT_XOR); return (bool) (($this->control ^ $value) === ($this->control | $value)); } return false; } /** * Sets the control parameter. * * @param integer $control * @return Bitwise */ public function setControl($control) { $this->control = (int) $control; return $this; } /** * Sets the operator parameter. * * @param string $operator * @return Bitwise */ public function setOperator($operator) { $this->operator = $operator; return $this; } /** * Sets the strict parameter. * * @param boolean $strict * @return Bitwise */ public function setStrict($strict) { $this->strict = (bool) $strict; return $this; } } ================================================ FILE: src/Callback.php ================================================ "The input is not valid", self::INVALID_CALLBACK => "An exception has been raised within the callback", ]; /** * Default options to set for the validator * * @var mixed */ protected $options = [ 'callback' => null, // Callback in a call_user_func format, string || array 'callbackOptions' => [], // Options for the callback ]; /** * Constructor * * @param array|callable $options */ public function __construct($options = null) { if (is_callable($options)) { $options = ['callback' => $options]; } parent::__construct($options); } /** * Returns the set callback * * @return mixed */ public function getCallback() { return $this->options['callback']; } /** * Sets the callback * * @param string|array|callable $callback * @return Callback Provides a fluent interface * @throws Exception\InvalidArgumentException */ public function setCallback($callback) { if (! is_callable($callback)) { throw new Exception\InvalidArgumentException('Invalid callback given'); } $this->options['callback'] = $callback; return $this; } /** * Returns the set options for the callback * * @return mixed */ public function getCallbackOptions() { return $this->options['callbackOptions']; } /** * Sets options for the callback * * @param mixed $options * @return Callback Provides a fluent interface */ public function setCallbackOptions($options) { $this->options['callbackOptions'] = (array) $options; return $this; } /** * Returns true if and only if the set callback returns * for the provided $value * * @param mixed $value * @param mixed $context Additional context to provide to the callback * @return bool * @throws Exception\InvalidArgumentException */ public function isValid($value, $context = null) { $this->setValue($value); $options = $this->getCallbackOptions(); $callback = $this->getCallback(); if (empty($callback)) { throw new Exception\InvalidArgumentException('No callback given'); } $args = [$value]; if (empty($options) && ! empty($context)) { $args[] = $context; } if (! empty($options) && empty($context)) { $args = array_merge($args, $options); } if (! empty($options) && ! empty($context)) { $args[] = $context; $args = array_merge($args, $options); } try { if (! call_user_func_array($callback, $args)) { $this->error(self::INVALID_VALUE); return false; } } catch (\Exception $e) { $this->error(self::INVALID_CALLBACK); return false; } return true; } } ================================================ FILE: src/ConfigProvider.php ================================================ $this->getDependencyConfig(), ]; } /** * Return dependency mappings for this component. * * @return array */ public function getDependencyConfig() { return [ 'aliases' => [ 'ValidatorManager' => ValidatorPluginManager::class, ], 'factories' => [ ValidatorPluginManager::class => ValidatorPluginManagerFactory::class, ], ]; } } ================================================ FILE: src/CreditCard.php ================================================ "The input seems to contain an invalid checksum", self::CONTENT => "The input must contain only digits", self::INVALID => "Invalid type given. String expected", self::LENGTH => "The input contains an invalid amount of digits", self::PREFIX => "The input is not from an allowed institute", self::SERVICE => "The input seems to be an invalid credit card number", self::SERVICEFAILURE => "An exception has been raised while validating the input", ]; /** * List of CCV names * * @var array */ protected $cardName = [ 0 => self::AMERICAN_EXPRESS, 1 => self::DINERS_CLUB, 2 => self::DINERS_CLUB_US, 3 => self::DISCOVER, 4 => self::JCB, 5 => self::LASER, 6 => self::MAESTRO, 7 => self::MASTERCARD, 8 => self::SOLO, 9 => self::UNIONPAY, 10 => self::VISA, 11 => self::MIR, ]; /** * List of allowed CCV lengths * * @var array */ protected $cardLength = [ self::AMERICAN_EXPRESS => [15], self::DINERS_CLUB => [14], self::DINERS_CLUB_US => [16], self::DISCOVER => [16, 19], self::JCB => [15, 16], self::LASER => [16, 17, 18, 19], self::MAESTRO => [12, 13, 14, 15, 16, 17, 18, 19], self::MASTERCARD => [16], self::SOLO => [16, 18, 19], self::UNIONPAY => [16, 17, 18, 19], self::VISA => [13, 16, 19], self::MIR => [13, 16], ]; /** * List of accepted CCV provider tags * * @var array */ protected $cardType = [ self::AMERICAN_EXPRESS => ['34', '37'], self::DINERS_CLUB => ['300', '301', '302', '303', '304', '305', '36'], self::DINERS_CLUB_US => ['54', '55'], self::DISCOVER => ['6011', '622126', '622127', '622128', '622129', '62213', '62214', '62215', '62216', '62217', '62218', '62219', '6222', '6223', '6224', '6225', '6226', '6227', '6228', '62290', '62291', '622920', '622921', '622922', '622923', '622924', '622925', '644', '645', '646', '647', '648', '649', '65'], self::JCB => ['1800', '2131', '3528', '3529', '353', '354', '355', '356', '357', '358'], self::LASER => ['6304', '6706', '6771', '6709'], self::MAESTRO => ['5018', '5020', '5038', '6304', '6759', '6761', '6762', '6763', '6764', '6765', '6766', '6772'], self::MASTERCARD => ['2221', '2222', '2223', '2224', '2225', '2226', '2227', '2228', '2229', '223', '224', '225', '226', '227', '228', '229', '23', '24', '25', '26', '271', '2720', '51', '52', '53', '54', '55'], self::SOLO => ['6334', '6767'], self::UNIONPAY => ['622126', '622127', '622128', '622129', '62213', '62214', '62215', '62216', '62217', '62218', '62219', '6222', '6223', '6224', '6225', '6226', '6227', '6228', '62290', '62291', '622920', '622921', '622922', '622923', '622924', '622925'], self::VISA => ['4'], self::MIR => ['2200', '2201', '2202', '2203', '2204'], ]; /** * Options for this validator * * @var array */ protected $options = [ 'service' => null, // Service callback for additional validation 'type' => [], // CCIs which are accepted by validation ]; /** * Constructor * * @param string|array|Traversable $options OPTIONAL Type of CCI to allow */ public function __construct($options = []) { if ($options instanceof Traversable) { $options = ArrayUtils::iteratorToArray($options); } elseif (! is_array($options)) { $options = func_get_args(); $temp['type'] = array_shift($options); if (! empty($options)) { $temp['service'] = array_shift($options); } $options = $temp; } if (! array_key_exists('type', $options)) { $options['type'] = self::ALL; } $this->setType($options['type']); unset($options['type']); if (array_key_exists('service', $options)) { $this->setService($options['service']); unset($options['service']); } parent::__construct($options); } /** * Returns a list of accepted CCIs * * @return array */ public function getType() { return $this->options['type']; } /** * Sets CCIs which are accepted by validation * * @param string|array $type Type to allow for validation * @return CreditCard Provides a fluid interface */ public function setType($type) { $this->options['type'] = []; return $this->addType($type); } /** * Adds a CCI to be accepted by validation * * @param string|array $type Type to allow for validation * @return CreditCard Provides a fluid interface */ public function addType($type) { if (is_string($type)) { $type = [$type]; } foreach ($type as $typ) { if (($typ == self::ALL)) { $this->options['type'] = array_keys($this->cardLength); continue; } if (in_array($typ, $this->options['type'])) { continue; } $constant = 'static::' . strtoupper($typ); if (! defined($constant) || in_array(constant($constant), $this->options['type'])) { continue; } $this->options['type'][] = constant($constant); } return $this; } /** * Returns the actual set service * * @return callable */ public function getService() { return $this->options['service']; } /** * Sets a new callback for service validation * * @param callable $service * @return CreditCard * @throws Exception\InvalidArgumentException on invalid service callback */ public function setService($service) { if (! is_callable($service)) { throw new Exception\InvalidArgumentException('Invalid callback given'); } $this->options['service'] = $service; return $this; } /** * Returns true if and only if $value follows the Luhn algorithm (mod-10 checksum) * * @param string $value * @return bool */ public function isValid($value) { $this->setValue($value); if (! is_string($value)) { $this->error(self::INVALID, $value); return false; } if (! ctype_digit($value)) { $this->error(self::CONTENT, $value); return false; } $length = strlen($value); $types = $this->getType(); $foundp = false; $foundl = false; foreach ($types as $type) { foreach ($this->cardType[$type] as $prefix) { if (0 === strpos($value, $prefix)) { $foundp = true; if (in_array($length, $this->cardLength[$type])) { $foundl = true; break 2; } } } } if ($foundp == false) { $this->error(self::PREFIX, $value); return false; } if ($foundl == false) { $this->error(self::LENGTH, $value); return false; } $sum = 0; $weight = 2; for ($i = $length - 2; $i >= 0; $i--) { $digit = $weight * $value[$i]; $sum += floor($digit / 10) + $digit % 10; $weight = $weight % 2 + 1; } if ((10 - $sum % 10) % 10 != $value[$length - 1]) { $this->error(self::CHECKSUM, $value); return false; } $service = $this->getService(); if (! empty($service)) { try { $callback = new Callback($service); $callback->setOptions($this->getType()); if (! $callback->isValid($value)) { $this->error(self::SERVICE, $value); return false; } } catch (\Exception $e) { $this->error(self::SERVICEFAILURE, $value); return false; } } return true; } } ================================================ FILE: src/Csrf.php ================================================ "The form submitted did not originate from the expected site", ]; /** * Actual hash used. * * @var mixed */ protected $hash; /** * Static cache of the session names to generated hashes * @todo unused, left here to avoid BC breaks * * @var array */ protected static $hashCache; /** * Name of CSRF element (used to create non-colliding hashes) * * @var string */ protected $name = 'csrf'; /** * Salt for CSRF token * @var string */ protected $salt = 'salt'; /** * @var SessionContainer */ protected $session; /** * TTL for CSRF token * @var int|null */ protected $timeout = 300; /** * Constructor * * @param array|Traversable $options */ public function __construct($options = []) { parent::__construct($options); if ($options instanceof Traversable) { $options = ArrayUtils::iteratorToArray($options); } if (! is_array($options)) { $options = (array) $options; } foreach ($options as $key => $value) { switch (strtolower($key)) { case 'name': $this->setName($value); break; case 'salt': $this->setSalt($value); break; case 'session': $this->setSession($value); break; case 'timeout': $this->setTimeout($value); break; default: // ignore unknown options break; } } } /** * Does the provided token match the one generated? * * @param string $value * @param mixed $context * @return bool */ public function isValid($value, $context = null) { if (! is_string($value)) { return false; } $this->setValue($value); $tokenId = $this->getTokenIdFromHash($value); $hash = $this->getValidationToken($tokenId); $tokenFromValue = $this->getTokenFromHash($value); $tokenFromHash = $this->getTokenFromHash($hash); if (! $tokenFromValue || ! $tokenFromHash || ($tokenFromValue !== $tokenFromHash)) { $this->error(self::NOT_SAME); return false; } return true; } /** * Set CSRF name * * @param string $name * @return Csrf */ public function setName($name) { $this->name = (string) $name; return $this; } /** * Get CSRF name * * @return string */ public function getName() { return $this->name; } /** * Set session container * * @param SessionContainer $session * @return Csrf */ public function setSession(SessionContainer $session) { $this->session = $session; if ($this->hash) { $this->initCsrfToken(); } return $this; } /** * Get session container * * Instantiate session container if none currently exists * * @return SessionContainer */ public function getSession() { if (null === $this->session) { // Using fully qualified name, to ensure polyfill class alias is used $this->session = new SessionContainer($this->getSessionName()); } return $this->session; } /** * Salt for CSRF token * * @param string $salt * @return Csrf */ public function setSalt($salt) { $this->salt = (string) $salt; return $this; } /** * Retrieve salt for CSRF token * * @return string */ public function getSalt() { return $this->salt; } /** * Retrieve CSRF token * * If no CSRF token currently exists, or should be regenerated, * generates one. * * @param bool $regenerate default false * @return string */ public function getHash($regenerate = false) { if ((null === $this->hash) || $regenerate) { $this->generateHash(); } return $this->hash; } /** * Get session namespace for CSRF token * * Generates a session namespace based on salt, element name, and class. * * @return string */ public function getSessionName() { return str_replace('\\', '_', __CLASS__) . '_' . $this->getSalt() . '_' . strtr($this->getName(), ['[' => '_', ']' => '']); } /** * Set timeout for CSRF session token * * @param int|null $ttl * @return Csrf */ public function setTimeout($ttl) { $this->timeout = ($ttl !== null) ? (int) $ttl : null; return $this; } /** * Get CSRF session token timeout * * @return int */ public function getTimeout() { return $this->timeout; } /** * Initialize CSRF token in session * * @return void */ protected function initCsrfToken() { $session = $this->getSession(); $timeout = $this->getTimeout(); if (null !== $timeout) { $session->setExpirationSeconds($timeout); } $hash = $this->getHash(); $token = $this->getTokenFromHash($hash); $tokenId = $this->getTokenIdFromHash($hash); if (! $session->tokenList) { $session->tokenList = []; } $session->tokenList[$tokenId] = $token; $session->hash = $hash; // @todo remove this, left for BC } /** * Generate CSRF token * * Generates CSRF token and stores both in {@link $hash} and element * value. * * @return void */ protected function generateHash() { $token = md5($this->getSalt() . Rand::getBytes(32) . $this->getName()); $this->hash = $this->formatHash($token, $this->generateTokenId()); $this->setValue($this->hash); $this->initCsrfToken(); } /** * @return string */ protected function generateTokenId() { return md5(Rand::getBytes(32)); } /** * Get validation token * * Retrieve token from session, if it exists. * * @param string $tokenId * @return null|string */ protected function getValidationToken($tokenId = null) { $session = $this->getSession(); /** * if no tokenId is passed we revert to the old behaviour * @todo remove, here for BC */ if (! $tokenId && isset($session->hash)) { return $session->hash; } if ($tokenId && isset($session->tokenList[$tokenId])) { return $this->formatHash($session->tokenList[$tokenId], $tokenId); } return; } /** * @param $token * @param $tokenId * @return string */ protected function formatHash($token, $tokenId) { return sprintf('%s-%s', $token, $tokenId); } /** * @param $hash * @return string */ protected function getTokenFromHash($hash) { $data = explode('-', $hash); return $data[0] ?: null; } /** * @param $hash * @return string */ protected function getTokenIdFromHash($hash) { $data = explode('-', $hash); if (! isset($data[1])) { return; } return $data[1]; } } ================================================ FILE: src/Date.php ================================================ "Invalid type given. String, integer, array or DateTime expected", self::INVALID_DATE => "The input does not appear to be a valid date", self::FALSEFORMAT => "The input does not fit the date format '%format%'", ]; /** * @var array */ protected $messageVariables = [ 'format' => 'format', ]; /** * @var string */ protected $format = self::FORMAT_DEFAULT; /** * @var bool */ protected $strict = false; /** * Sets validator options * * @param string|array|Traversable $options OPTIONAL */ public function __construct($options = []) { if ($options instanceof Traversable) { $options = iterator_to_array($options); } elseif (! is_array($options)) { $options = func_get_args(); $temp['format'] = array_shift($options); $options = $temp; } parent::__construct($options); } /** * Returns the format option * * @return string|null */ public function getFormat() { return $this->format; } /** * Sets the format option * * Format cannot be null. It will always default to 'Y-m-d', even * if null is provided. * * @param string $format * @return Date provides a fluent interface * @todo validate the format */ public function setFormat($format = self::FORMAT_DEFAULT) { $this->format = (empty($format)) ? self::FORMAT_DEFAULT : $format; return $this; } public function setStrict(bool $strict) : self { $this->strict = $strict; return $this; } public function isStrict() : bool { return $this->strict; } /** * Returns true if $value is a DateTime instance or can be converted into one. * * @param string|array|int|DateTime $value * @return bool */ public function isValid($value) { $this->setValue($value); $date = $this->convertToDateTime($value); if (! $date) { $this->error(self::INVALID_DATE); return false; } if ($this->isStrict() && $date->format($this->getFormat()) !== $value) { $this->error(self::FALSEFORMAT); return false; } return true; } /** * Attempts to convert an int, string, or array to a DateTime object * * @param string|int|array $param * @param bool $addErrors * @return bool|DateTime */ protected function convertToDateTime($param, $addErrors = true) { if ($param instanceof DateTime || $param instanceof DateTimeImmutable) { return $param; } $type = gettype($param); if (! in_array($type, ['string', 'integer', 'double', 'array'])) { if ($addErrors) { $this->error(self::INVALID); } return false; } $convertMethod = 'convert' . ucfirst($type); return $this->{$convertMethod}($param, $addErrors); } /** * Attempts to convert an integer into a DateTime object * * @param integer $value * @return bool|DateTime */ protected function convertInteger($value) { return date_create("@$value"); } /** * Attempts to convert an double into a DateTime object * * @param double $value * @return bool|DateTime */ protected function convertDouble($value) { return DateTime::createFromFormat('U', $value); } /** * Attempts to convert a string into a DateTime object * * @param string $value * @param bool $addErrors * @return bool|DateTime */ protected function convertString($value, $addErrors = true) { $date = DateTime::createFromFormat($this->format, $value); // Invalid dates can show up as warnings (ie. "2007-02-99") // and still return a DateTime object. $errors = DateTime::getLastErrors(); if ($errors['warning_count'] > 0) { if ($addErrors) { $this->error(self::FALSEFORMAT); } return false; } return $date; } /** * Implodes the array into a string and proxies to {@link convertString()}. * * @param array $value * @param bool $addErrors * @return bool|DateTime * @todo enhance the implosion */ protected function convertArray(array $value, $addErrors = true) { return $this->convertString(implode('-', $value), $addErrors); } } ================================================ FILE: src/DateStep.php ================================================ "Invalid type given. String, integer, array or DateTime expected", self::INVALID_DATE => "The input does not appear to be a valid date", self::FALSEFORMAT => "The input does not fit the date format '%format%'", self::NOT_STEP => "The input is not a valid step", ]; /** * Optional base date value * * @var string|int|\DateTime */ protected $baseValue = '1970-01-01T00:00:00Z'; /** * Date step interval (defaults to 1 day). * Uses the DateInterval specification. * * @var DateInterval */ protected $step; /** * Optional timezone to be used when the baseValue * and validation values do not contain timezone info * * @var DateTimeZone */ protected $timezone; /** * Set default options for this instance * * @param array $options */ public function __construct($options = []) { if ($options instanceof Traversable) { $options = ArrayUtils::iteratorToArray($options); } elseif (! is_array($options)) { $options = func_get_args(); $temp['baseValue'] = array_shift($options); if (! empty($options)) { $temp['step'] = array_shift($options); } if (! empty($options)) { $temp['format'] = array_shift($options); } if (! empty($options)) { $temp['timezone'] = array_shift($options); } $options = $temp; } if (! isset($options['step'])) { $options['step'] = new DateInterval('P1D'); } if (! isset($options['timezone'])) { $options['timezone'] = new DateTimeZone(date_default_timezone_get()); } parent::__construct($options); } /** * Sets the base value from which the step should be computed * * @param string|int|\DateTime $baseValue * @return DateStep */ public function setBaseValue($baseValue) { $this->baseValue = $baseValue; return $this; } /** * Returns the base value from which the step should be computed * * @return string|int|\DateTime */ public function getBaseValue() { return $this->baseValue; } /** * Sets the step date interval * * @param DateInterval $step * @return DateStep */ public function setStep(DateInterval $step) { $this->step = $step; return $this; } /** * Returns the step date interval * * @return DateInterval */ public function getStep() { return $this->step; } /** * Returns the timezone option * * @return DateTimeZone */ public function getTimezone() { return $this->timezone; } /** * Sets the timezone option * * @param DateTimeZone $timezone * @return DateStep */ public function setTimezone(DateTimeZone $timezone) { $this->timezone = $timezone; return $this; } /** * Supports formats with ISO week (W) definitions * * @see Date::convertString() */ protected function convertString($value, $addErrors = true) { // Custom week format support if (strpos($this->format, 'Y-\WW') === 0 && preg_match('/^([0-9]{4})\-W([0-9]{2})/', $value, $matches) ) { $date = new DateTime(); $date->setISODate($matches[1], $matches[2]); } else { $date = DateTime::createFromFormat($this->format, $value, new DateTimeZone('UTC')); } // Invalid dates can show up as warnings (ie. "2007-02-99") // and still return a DateTime object. $errors = DateTime::getLastErrors(); if ($errors['warning_count'] > 0) { if ($addErrors) { $this->error(self::FALSEFORMAT); } return false; } return $date; } /** * Returns true if a date is within a valid step * * @param string|int|\DateTime $value * @return bool * @throws Exception\InvalidArgumentException */ public function isValid($value) { if (! parent::isValid($value)) { return false; } $valueDate = $this->convertToDateTime($value, false); // avoid duplicate errors $baseDate = $this->convertToDateTime($this->baseValue, false); $step = $this->getStep(); // Same date? if ($valueDate == $baseDate) { return true; } // Optimization for simple intervals. // Handle intervals of just one date or time unit. $intervalParts = explode('|', $step->format('%y|%m|%d|%h|%i|%s')); $partCounts = array_count_values($intervalParts); $unitKeys = ['years', 'months', 'days', 'hours', 'minutes', 'seconds']; $intervalParts = array_combine($unitKeys, $intervalParts); // Get absolute time difference to avoid special cases of missing/added time $absoluteValueDate = new DateTime($valueDate->format('Y-m-d H:i:s'), new DateTimeZone('UTC')); $absoluteBaseDate = new DateTime($baseDate->format('Y-m-d H:i:s'), new DateTimeZone('UTC')); $timeDiff = $absoluteValueDate->diff($absoluteBaseDate, 1); $diffParts = array_combine($unitKeys, explode('|', $timeDiff->format('%y|%m|%d|%h|%i|%s'))); if (5 === $partCounts["0"]) { // Find the unit with the non-zero interval $intervalUnit = null; $stepValue = null; foreach ($intervalParts as $key => $value) { if (0 != $value) { $intervalUnit = $key; $stepValue = (int) $value; break; } } // Check date units if (in_array($intervalUnit, ['years', 'months', 'days'])) { switch ($intervalUnit) { case 'years': if (0 == $diffParts['months'] && 0 == $diffParts['days'] && 0 == $diffParts['hours'] && 0 == $diffParts['minutes'] && 0 == $diffParts['seconds'] ) { if (($diffParts['years'] % $stepValue) === 0) { return true; } } break; case 'months': if (0 == $diffParts['days'] && 0 == $diffParts['hours'] && 0 == $diffParts['minutes'] && 0 == $diffParts['seconds'] ) { $months = ($diffParts['years'] * 12) + $diffParts['months']; if (($months % $stepValue) === 0) { return true; } } break; case 'days': if (0 == $diffParts['hours'] && 0 == $diffParts['minutes'] && 0 == $diffParts['seconds'] ) { $days = $timeDiff->format('%a'); // Total days if (($days % $stepValue) === 0) { return true; } } break; } $this->error(self::NOT_STEP); return false; } // Check time units if (in_array($intervalUnit, ['hours', 'minutes', 'seconds'])) { // Simple test if $stepValue is 1. if (1 == $stepValue) { if ('hours' === $intervalUnit && 0 == $diffParts['minutes'] && 0 == $diffParts['seconds'] ) { return true; } elseif ('minutes' === $intervalUnit && 0 == $diffParts['seconds']) { return true; } elseif ('seconds' === $intervalUnit) { return true; } $this->error(self::NOT_STEP); return false; } // Simple test for same day, when using default baseDate if ($baseDate->format('Y-m-d') == $valueDate->format('Y-m-d') && $baseDate->format('Y-m-d') == '1970-01-01' ) { switch ($intervalUnit) { case 'hours': if (0 == $diffParts['minutes'] && 0 == $diffParts['seconds']) { if (($diffParts['hours'] % $stepValue) === 0) { return true; } } break; case 'minutes': if (0 == $diffParts['seconds']) { $minutes = ($diffParts['hours'] * 60) + $diffParts['minutes']; if (($minutes % $stepValue) === 0) { return true; } } break; case 'seconds': $seconds = ($diffParts['hours'] * 60 * 60) + ($diffParts['minutes'] * 60) + $diffParts['seconds']; if (($seconds % $stepValue) === 0) { return true; } break; } $this->error(self::NOT_STEP); return false; } } } return $this->fallbackIncrementalIterationLogic($baseDate, $valueDate, $intervalParts, $diffParts, $step); } /** * Fall back to slower (but accurate) method for complex intervals. * Keep adding steps to the base date until a match is found * or until the value is exceeded. * * This is really slow if the interval is small, especially if the * default base date of 1/1/1970 is used. We can skip a chunk of * iterations by starting at the lower bound of steps needed to reach * the target * * @param DateTime $baseDate * @param DateTime $valueDate * @param int[] $intervalParts * @param int[] $diffParts * @param DateInterval $step * * @return bool */ private function fallbackIncrementalIterationLogic( DateTime $baseDate, DateTime $valueDate, array $intervalParts, array $diffParts, DateInterval $step ) { list($minSteps, $requiredIterations) = $this->computeMinStepAndRequiredIterations($intervalParts, $diffParts); $minimumInterval = $this->computeMinimumInterval($intervalParts, $minSteps); $isIncrementalStepping = $baseDate < $valueDate; $dateModificationOperation = $isIncrementalStepping ? 'add' : 'sub'; for ($offsetIterations = 0; $offsetIterations < $requiredIterations; $offsetIterations += 1) { $baseDate->{$dateModificationOperation}($minimumInterval); } while (($isIncrementalStepping && $baseDate < $valueDate) || (! $isIncrementalStepping && $baseDate > $valueDate) ) { $baseDate->{$dateModificationOperation}($step); if ($baseDate == $valueDate) { return true; } } $this->error(self::NOT_STEP); return false; } /** * Computes minimum interval to use for iterations while checking steps * * @param int[] $intervalParts * @param int $minSteps * * @return DateInterval */ private function computeMinimumInterval(array $intervalParts, $minSteps) { return new DateInterval(sprintf( 'P%dY%dM%dDT%dH%dM%dS', $intervalParts['years'] * $minSteps, $intervalParts['months'] * $minSteps, $intervalParts['days'] * $minSteps, $intervalParts['hours'] * $minSteps, $intervalParts['minutes'] * $minSteps, $intervalParts['seconds'] * $minSteps )); } /** * @param int[] $intervalParts * @param int[] $diffParts * * @return int[] (ordered tuple containing minimum steps and required step iterations */ private function computeMinStepAndRequiredIterations(array $intervalParts, array $diffParts) { $minSteps = $this->computeMinSteps($intervalParts, $diffParts); // If we use PHP_INT_MAX DateInterval::__construct falls over with a bad format error // before we reach the max on 64 bit machines $maxInteger = min(pow(2, 31), PHP_INT_MAX); // check for integer overflow and split $minimum interval if needed $maximumInterval = max($intervalParts); $requiredStepIterations = 1; if (($minSteps * $maximumInterval) > $maxInteger) { $requiredStepIterations = ceil(($minSteps * $maximumInterval) / $maxInteger); $minSteps = floor($minSteps / $requiredStepIterations); } return [$minSteps, $minSteps ? $requiredStepIterations : 0]; } /** * Multiply the step interval by the lower bound of steps to reach the target * * @param int[] $intervalParts * @param int[] $diffParts * * @return int */ private function computeMinSteps(array $intervalParts, array $diffParts) { $intervalMaxSeconds = $this->computeIntervalMaxSeconds($intervalParts); return (0 == $intervalMaxSeconds) ? 0 : max(floor($this->computeDiffMinSeconds($diffParts) / $intervalMaxSeconds) - 1, 0); } /** * Get upper bound of the given interval in seconds * Converts a given `$intervalParts` array into seconds * * @param int[] $intervalParts * * @return int */ private function computeIntervalMaxSeconds(array $intervalParts) { return ($intervalParts['years'] * 60 * 60 * 24 * 366) + ($intervalParts['months'] * 60 * 60 * 24 * 31) + ($intervalParts['days'] * 60 * 60 * 24) + ($intervalParts['hours'] * 60 * 60) + ($intervalParts['minutes'] * 60) + $intervalParts['seconds']; } /** * Get lower bound of difference in secondss * Converts a given `$diffParts` array into seconds * * @param int[] $diffParts * * @return int */ private function computeDiffMinSeconds(array $diffParts) { return ($diffParts['years'] * 60 * 60 * 24 * 365) + ($diffParts['months'] * 60 * 60 * 24 * 28) + ($diffParts['days'] * 60 * 60 * 24) + ($diffParts['hours'] * 60 * 60) + ($diffParts['minutes'] * 60) + $diffParts['seconds']; } } ================================================ FILE: src/Db/AbstractDb.php ================================================ "No record matching the input was found", self::ERROR_RECORD_FOUND => "A record matching the input was found", ]; /** * Select object to use. can be set, or will be auto-generated * * @var Select */ protected $select; /** * @var string */ protected $schema = null; /** * @var string */ protected $table = ''; /** * @var string */ protected $field = ''; /** * @var mixed */ protected $exclude = null; /** * Provides basic configuration for use with Zend\Validator\Db Validators * Setting $exclude allows a single record to be excluded from matching. * Exclude can either be a String containing a where clause, or an array with `field` and `value` keys * to define the where clause added to the sql. * A database adapter may optionally be supplied to avoid using the registered default adapter. * * The following option keys are supported: * 'table' => The database table to validate against * 'schema' => The schema keys * 'field' => The field to check for a match * 'exclude' => An optional where clause or field/value pair to exclude from the query * 'adapter' => An optional database adapter to use * * @param array|Traversable|Select $options Options to use for this validator * @throws \Zend\Validator\Exception\InvalidArgumentException */ public function __construct($options = null) { parent::__construct($options); if ($options instanceof Select) { $this->setSelect($options); return; } if ($options instanceof Traversable) { $options = ArrayUtils::iteratorToArray($options); } elseif (func_num_args() > 1) { $options = func_get_args(); $firstArgument = array_shift($options); if (is_array($firstArgument)) { $temp = ArrayUtils::iteratorToArray($firstArgument); } else { $temp['table'] = $firstArgument; } $temp['field'] = array_shift($options); if (! empty($options)) { $temp['exclude'] = array_shift($options); } if (! empty($options)) { $temp['adapter'] = array_shift($options); } $options = $temp; } if (! array_key_exists('table', $options) && ! array_key_exists('schema', $options)) { throw new Exception\InvalidArgumentException('Table or Schema option missing!'); } if (! array_key_exists('field', $options)) { throw new Exception\InvalidArgumentException('Field option missing!'); } if (array_key_exists('adapter', $options)) { $this->setAdapter($options['adapter']); } if (array_key_exists('exclude', $options)) { $this->setExclude($options['exclude']); } $this->setField($options['field']); if (array_key_exists('table', $options)) { $this->setTable($options['table']); } if (array_key_exists('schema', $options)) { $this->setSchema($options['schema']); } } /** * Returns the set adapter * * @throws \Zend\Validator\Exception\RuntimeException When no database adapter is defined * @return DbAdapter */ public function getAdapter() { return $this->adapter; } /** * Sets a new database adapter * * @param DbAdapter $adapter * @return self Provides a fluent interface */ public function setAdapter(DbAdapter $adapter) { return $this->setDbAdapter($adapter); } /** * Returns the set exclude clause * * @return string|array */ public function getExclude() { return $this->exclude; } /** * Sets a new exclude clause * * @param string|array $exclude * @return self Provides a fluent interface */ public function setExclude($exclude) { $this->exclude = $exclude; $this->select = null; return $this; } /** * Returns the set field * * @return string|array */ public function getField() { return $this->field; } /** * Sets a new field * * @param string $field * @return AbstractDb */ public function setField($field) { $this->field = (string) $field; $this->select = null; return $this; } /** * Returns the set table * * @return string */ public function getTable() { return $this->table; } /** * Sets a new table * * @param string $table * @return self Provides a fluent interface */ public function setTable($table) { $this->table = (string) $table; $this->select = null; return $this; } /** * Returns the set schema * * @return string */ public function getSchema() { return $this->schema; } /** * Sets a new schema * * @param string $schema * @return self Provides a fluent interface */ public function setSchema($schema) { $this->schema = $schema; $this->select = null; return $this; } /** * Sets the select object to be used by the validator * * @param Select $select * @return self Provides a fluent interface */ public function setSelect(Select $select) { $this->select = $select; return $this; } /** * Gets the select object to be used by the validator. * If no select object was supplied to the constructor, * then it will auto-generate one from the given table, * schema, field, and adapter options. * * @return Select The Select object which will be used */ public function getSelect() { if ($this->select instanceof Select) { return $this->select; } // Build select object $select = new Select(); $tableIdentifier = new TableIdentifier($this->table, $this->schema); $select->from($tableIdentifier)->columns([$this->field]); $select->where->equalTo($this->field, null); if ($this->exclude !== null) { if (is_array($this->exclude)) { $select->where->notEqualTo( $this->exclude['field'], $this->exclude['value'] ); } else { $select->where($this->exclude); } } $this->select = $select; return $this->select; } /** * Run query and returns matches, or null if no matches are found. * * @param string $value * @return array when matches are found. */ protected function query($value) { $sql = new Sql($this->getAdapter()); $select = $this->getSelect(); $statement = $sql->prepareStatementForSqlObject($select); $parameters = $statement->getParameterContainer(); $parameters['where1'] = $value; $result = $statement->execute(); return $result->current(); } } ================================================ FILE: src/Db/NoRecordExists.php ================================================ adapter) { throw new Exception\RuntimeException('No database adapter present'); } $valid = true; $this->setValue($value); $result = $this->query($value); if ($result) { $valid = false; $this->error(self::ERROR_RECORD_FOUND); } return $valid; } } ================================================ FILE: src/Db/RecordExists.php ================================================ adapter) { throw new Exception\RuntimeException('No database adapter present'); } $valid = true; $this->setValue($value); $result = $this->query($value); if (! $result) { $valid = false; $this->error(self::ERROR_NO_RECORD_FOUND); } return $valid; } } ================================================ FILE: src/Digits.php ================================================ "The input must contain only digits", self::STRING_EMPTY => "The input is an empty string", self::INVALID => "Invalid type given. String, integer or float expected", ]; /** * Returns true if and only if $value only contains digit characters * * @param string $value * @return bool */ public function isValid($value) { if (! is_string($value) && ! is_int($value) && ! is_float($value)) { $this->error(self::INVALID); return false; } $this->setValue((string) $value); if ('' === $this->getValue()) { $this->error(self::STRING_EMPTY); return false; } if (null === static::$filter) { static::$filter = new DigitsFilter(); } if ($this->getValue() !== static::$filter->filter($this->getValue())) { $this->error(self::NOT_DIGITS); return false; } return true; } } ================================================ FILE: src/EmailAddress.php ================================================ "Invalid type given. String expected", self::INVALID_FORMAT => "The input is not a valid email address. Use the basic format local-part@hostname", self::INVALID_HOSTNAME => "'%hostname%' is not a valid hostname for the email address", self::INVALID_MX_RECORD => "'%hostname%' does not appear to have any valid MX or A records for the email address", self::INVALID_SEGMENT => "'%hostname%' is not in a routable network segment. The email address should not be resolved from public network", self::DOT_ATOM => "'%localPart%' can not be matched against dot-atom format", self::QUOTED_STRING => "'%localPart%' can not be matched against quoted-string format", self::INVALID_LOCAL_PART => "'%localPart%' is not a valid local part for the email address", self::LENGTH_EXCEEDED => "The input exceeds the allowed length", ]; // @codingStandardsIgnoreEnd /** * @var array */ protected $messageVariables = [ 'hostname' => 'hostname', 'localPart' => 'localPart' ]; /** * @var string */ protected $hostname; /** * @var string */ protected $localPart; /** * Returns the found mx record informations * * @var array */ protected $mxRecord = []; /** * Internal options array */ protected $options = [ 'useMxCheck' => false, 'useDeepMxCheck' => false, 'useDomainCheck' => true, 'allow' => Hostname::ALLOW_DNS, 'strict' => true, 'hostnameValidator' => null, ]; /** * Instantiates hostname validator for local use * * The following additional option keys are supported: * 'hostnameValidator' => A hostname validator, see Zend\Validator\Hostname * 'allow' => Options for the hostname validator, see Zend\Validator\Hostname::ALLOW_* * 'strict' => Whether to adhere to strictest requirements in the spec * 'useMxCheck' => If MX check should be enabled, boolean * 'useDeepMxCheck' => If a deep MX check should be done, boolean * * @param array|\Traversable $options OPTIONAL */ public function __construct($options = []) { if (! is_array($options)) { $options = func_get_args(); $temp['allow'] = array_shift($options); if (! empty($options)) { $temp['useMxCheck'] = array_shift($options); } if (! empty($options)) { $temp['hostnameValidator'] = array_shift($options); } $options = $temp; } parent::__construct($options); } /** * Sets the validation failure message template for a particular key * Adds the ability to set messages to the attached hostname validator * * @param string $messageString * @param string $messageKey OPTIONAL * @return AbstractValidator Provides a fluent interface */ public function setMessage($messageString, $messageKey = null) { if ($messageKey === null) { $this->getHostnameValidator()->setMessage($messageString); parent::setMessage($messageString); return $this; } if (! isset($this->messageTemplates[$messageKey])) { $this->getHostnameValidator()->setMessage($messageString, $messageKey); } else { parent::setMessage($messageString, $messageKey); } return $this; } /** * Returns the set hostname validator * * If was not previously set then lazy load a new one * * @return Hostname */ public function getHostnameValidator() { if (! isset($this->options['hostnameValidator'])) { $this->options['hostnameValidator'] = new Hostname($this->getAllow()); } return $this->options['hostnameValidator']; } /** * @param Hostname $hostnameValidator OPTIONAL * @return EmailAddress Provides a fluent interface */ public function setHostnameValidator(Hostname $hostnameValidator = null) { $this->options['hostnameValidator'] = $hostnameValidator; return $this; } /** * Returns the allow option of the attached hostname validator * * @return int */ public function getAllow() { return $this->options['allow']; } /** * Sets the allow option of the hostname validator to use * * @param int $allow * @return EmailAddress Provides a fluent interface */ public function setAllow($allow) { $this->options['allow'] = $allow; if (isset($this->options['hostnameValidator'])) { $this->options['hostnameValidator']->setAllow($allow); } return $this; } /** * Whether MX checking via getmxrr is supported or not * * @return bool */ public function isMxSupported() { return function_exists('getmxrr'); } /** * Returns the set validateMx option * * @return bool */ public function getMxCheck() { return $this->options['useMxCheck']; } /** * Set whether we check for a valid MX record via DNS * * This only applies when DNS hostnames are validated * * @param bool $mx Set allowed to true to validate for MX records, and false to not validate them * @return EmailAddress Fluid Interface */ public function useMxCheck($mx) { $this->options['useMxCheck'] = (bool) $mx; return $this; } /** * Returns the set deepMxCheck option * * @return bool */ public function getDeepMxCheck() { return $this->options['useDeepMxCheck']; } /** * Use deep validation for MX records * * @param bool $deep Set deep to true to perform a deep validation process for MX records * @return EmailAddress Fluid Interface */ public function useDeepMxCheck($deep) { $this->options['useDeepMxCheck'] = (bool) $deep; return $this; } /** * Returns the set domainCheck option * * @return bool */ public function getDomainCheck() { return $this->options['useDomainCheck']; } /** * Sets if the domain should also be checked * or only the local part of the email address * * @param bool $domain * @return EmailAddress Fluid Interface */ public function useDomainCheck($domain = true) { $this->options['useDomainCheck'] = (bool) $domain; return $this; } /** * Returns if the given host is reserved * * The following addresses are seen as reserved * '0.0.0.0/8', '10.0.0.0/8', '127.0.0.0/8' * '100.64.0.0/10' * '172.16.0.0/12' * '198.18.0.0/15' * '169.254.0.0/16', '192.168.0.0/16' * '192.0.2.0/24', '192.88.99.0/24', '198.51.100.0/24', '203.0.113.0/24' * '224.0.0.0/4', '240.0.0.0/4' * @see http://en.wikipedia.org/wiki/Reserved_IP_addresses * * As of RFC5753 (JAN 2010), the following blocks are no longer reserved: * - 128.0.0.0/16 * - 191.255.0.0/16 * - 223.255.255.0/24 * @see http://tools.ietf.org/html/rfc5735#page-6 * * As of RFC6598 (APR 2012), the following blocks are now reserved: * - 100.64.0.0/10 * @see http://tools.ietf.org/html/rfc6598#section-7 * * @param string $host * @return bool Returns false when minimal one of the given addresses is not reserved */ protected function isReserved($host) { if (! preg_match('/^([0-9]{1,3}\.){3}[0-9]{1,3}$/', $host)) { $host = gethostbynamel($host); } else { $host = [$host]; } if (empty($host)) { return false; } foreach ($host as $server) { // @codingStandardsIgnoreStart // Search for 0.0.0.0/8, 10.0.0.0/8, 127.0.0.0/8 if (!preg_match('/^(0|10|127)(\.([0-9]|[1-9][0-9]|1([0-9][0-9])|2([0-4][0-9]|5[0-5]))){3}$/', $server) && // Search for 100.64.0.0/10 !preg_match('/^100\.(6[0-4]|[7-9][0-9]|1[0-1][0-9]|12[0-7])(\.([0-9]|[1-9][0-9]|1([0-9][0-9])|2([0-4][0-9]|5[0-5]))){2}$/', $server) && // Search for 172.16.0.0/12 !preg_match('/^172\.(1[6-9]|2[0-9]|3[0-1])(\.([0-9]|[1-9][0-9]|1([0-9][0-9])|2([0-4][0-9]|5[0-5]))){2}$/', $server) && // Search for 198.18.0.0/15 !preg_match('/^198\.(1[8-9])(\.([0-9]|[1-9][0-9]|1([0-9][0-9])|2([0-4][0-9]|5[0-5]))){2}$/', $server) && // Search for 169.254.0.0/16, 192.168.0.0/16 !preg_match('/^(169\.254|192\.168)(\.([0-9]|[1-9][0-9]|1([0-9][0-9])|2([0-4][0-9]|5[0-5]))){2}$/', $server) && // Search for 192.0.2.0/24, 192.88.99.0/24, 198.51.100.0/24, 203.0.113.0/24 !preg_match('/^(192\.0\.2|192\.88\.99|198\.51\.100|203\.0\.113)\.([0-9]|[1-9][0-9]|1([0-9][0-9])|2([0-4][0-9]|5[0-5]))$/', $server) && // Search for 224.0.0.0/4, 240.0.0.0/4 !preg_match('/^(2(2[4-9]|[3-4][0-9]|5[0-5]))(\.([0-9]|[1-9][0-9]|1([0-9][0-9])|2([0-4][0-9]|5[0-5]))){3}$/', $server) ) { return false; } // @codingStandardsIgnoreEnd } return true; } /** * Internal method to validate the local part of the email address * * @return bool */ protected function validateLocalPart() { // First try to match the local part on the common dot-atom format $result = false; // Dot-atom characters are: 1*atext *("." 1*atext) // atext: ALPHA / DIGIT / and "!", "#", "$", "%", "&", "'", "*", // "+", "-", "/", "=", "?", "^", "_", "`", "{", "|", "}", "~" $atext = 'a-zA-Z0-9\x21\x23\x24\x25\x26\x27\x2a\x2b\x2d\x2f\x3d\x3f\x5e\x5f\x60\x7b\x7c\x7d\x7e'; if (preg_match('/^[' . $atext . ']+(\x2e+[' . $atext . ']+)*$/', $this->localPart)) { $result = true; } elseif ($this->validateInternationalizedLocalPart($this->localPart)) { $result = true; } else { // Try quoted string format (RFC 5321 Chapter 4.1.2) // Quoted-string characters are: DQUOTE *(qtext/quoted-pair) DQUOTE $qtext = '\x20-\x21\x23-\x5b\x5d-\x7e'; // %d32-33 / %d35-91 / %d93-126 $quotedPair = '\x20-\x7e'; // %d92 %d32-126 if (preg_match('/^"(['. $qtext .']|\x5c[' . $quotedPair . '])*"$/', $this->localPart)) { $result = true; } else { $this->error(self::DOT_ATOM); $this->error(self::QUOTED_STRING); $this->error(self::INVALID_LOCAL_PART); } } return $result; } /** * @param string $localPart Address local part to validate. * @return bool */ protected function validateInternationalizedLocalPart($localPart) { if (extension_loaded('intl') && false === UConverter::transcode($localPart, 'UTF-8', 'UTF-8') ) { // invalid utf? return false; } $atext = 'a-zA-Z0-9\x21\x23\x24\x25\x26\x27\x2a\x2b\x2d\x2f\x3d\x3f\x5e\x5f\x60\x7b\x7c\x7d\x7e'; // RFC 6532 extends atext to include non-ascii utf // @see https://tools.ietf.org/html/rfc6532#section-3.1 $uatext = $atext . '\x{80}-\x{FFFF}'; return (bool) preg_match('/^[' . $uatext . ']+(\x2e+[' . $uatext . ']+)*$/u', $localPart); } /** * Returns the found MX Record information after validation including weight for further processing * * @return array */ public function getMXRecord() { return $this->mxRecord; } /** * Internal method to validate the servers MX records * * @return bool */ protected function validateMXRecords() { $mxHosts = []; $weight = []; $result = getmxrr($this->hostname, $mxHosts, $weight); if (! empty($mxHosts) && ! empty($weight)) { $this->mxRecord = array_combine($mxHosts, $weight) ?: []; } else { $this->mxRecord = []; } arsort($this->mxRecord); // Fallback to IPv4 hosts if no MX record found (RFC 2821 SS 5). if (! $result) { $result = gethostbynamel($this->hostname); if (is_array($result)) { $this->mxRecord = array_flip($result); } } if (! $result) { $this->error(self::INVALID_MX_RECORD); return $result; } if (! $this->options['useDeepMxCheck']) { return $result; } $validAddress = false; $reserved = true; foreach ($this->mxRecord as $hostname => $weight) { $res = $this->isReserved($hostname); if (! $res) { $reserved = false; } if (! $res && (checkdnsrr($hostname, "A") || checkdnsrr($hostname, "AAAA") || checkdnsrr($hostname, "A6")) ) { $validAddress = true; break; } } if (! $validAddress) { $result = false; $error = ($reserved) ? self::INVALID_SEGMENT : self::INVALID_MX_RECORD; $this->error($error); } return $result; } /** * Internal method to validate the hostname part of the email address * * @return bool */ protected function validateHostnamePart() { $hostname = $this->getHostnameValidator()->setTranslator($this->getTranslator()) ->isValid($this->hostname); if (! $hostname) { $this->error(self::INVALID_HOSTNAME); // Get messages and errors from hostnameValidator foreach ($this->getHostnameValidator()->getMessages() as $code => $message) { $this->abstractOptions['messages'][$code] = $message; } } elseif ($this->options['useMxCheck']) { // MX check on hostname $hostname = $this->validateMXRecords(); } return $hostname; } /** * Splits the given value in hostname and local part of the email address * * @param string $value Email address to be split * @return bool Returns false when the email can not be split */ protected function splitEmailParts($value) { $value = is_string($value) ? $value : ''; // Split email address up and disallow '..' if (strpos($value, '..') !== false || ! preg_match('/^(.+)@([^@]+)$/', $value, $matches) ) { return false; } $this->localPart = $matches[1]; $this->hostname = $this->idnToAscii($matches[2]); return true; } /** * Defined by Zend\Validator\ValidatorInterface * * Returns true if and only if $value is a valid email address * according to RFC2822 * * @link http://www.ietf.org/rfc/rfc2822.txt RFC2822 * @link http://www.columbia.edu/kermit/ascii.html US-ASCII characters * @param string $value * @return bool */ public function isValid($value) { if (! is_string($value)) { $this->error(self::INVALID); return false; } $length = true; $this->setValue($value); // Split email address up and disallow '..' if (! $this->splitEmailParts($this->getValue())) { $this->error(self::INVALID_FORMAT); return false; } if ($this->getOption('strict') && (strlen($this->localPart) > 64) || (strlen($this->hostname) > 255)) { $length = false; $this->error(self::LENGTH_EXCEEDED); } // Match hostname part $hostname = false; if ($this->options['useDomainCheck']) { $hostname = $this->validateHostnamePart(); } $local = $this->validateLocalPart(); // If both parts valid, return true return ($local && $length) && (! $this->options['useDomainCheck'] || $hostname); } /** * Safely convert UTF-8 encoded domain name to ASCII * @param string $email the UTF-8 encoded email * @return string */ protected function idnToAscii($email) { if (extension_loaded('intl')) { if (defined('INTL_IDNA_VARIANT_UTS46')) { return (idn_to_ascii($email, 0, INTL_IDNA_VARIANT_UTS46) ?: $email); } return (idn_to_ascii($email) ?: $email); } return $email; } /** * Safely convert ASCII encoded domain name to UTF-8 * @param string $email the ASCII encoded email * @return string */ protected function idnToUtf8($email) { if (strlen($email) == 0) { return $email; } if (extension_loaded('intl')) { // The documentation does not clarify what kind of failure // can happen in idn_to_utf8. One can assume if the source // is not IDN encoded, it would fail, but it usually returns // the source string in those cases. // But not when the source string is long enough. // Thus we default to source string ourselves. if (defined('INTL_IDNA_VARIANT_UTS46')) { return idn_to_utf8($email, 0, INTL_IDNA_VARIANT_UTS46) ?: $email; } return idn_to_utf8($email) ?: $email; } return $email; } } ================================================ FILE: src/Exception/BadMethodCallException.php ================================================ "Invalid type given", ]; /** * @var array */ protected $messageVariables = []; /** * @var string */ protected $valueDelimiter = ','; /** * @var ValidatorInterface */ protected $validator; /** * @var bool */ protected $breakOnFirstFailure = false; /** * Sets the delimiter string that the values will be split upon * * @param string $delimiter * @return Explode */ public function setValueDelimiter($delimiter) { $this->valueDelimiter = $delimiter; return $this; } /** * Returns the delimiter string that the values will be split upon * * @return string */ public function getValueDelimiter() { return $this->valueDelimiter; } /** * Set validator plugin manager * * @param ValidatorPluginManager $pluginManager */ public function setValidatorPluginManager(ValidatorPluginManager $pluginManager) { $this->pluginManager = $pluginManager; } /** * Get validator plugin manager * * @return ValidatorPluginManager */ public function getValidatorPluginManager() { if (! $this->pluginManager) { $this->setValidatorPluginManager(new ValidatorPluginManager(new ServiceManager)); } return $this->pluginManager; } /** * Sets the Validator for validating each value * * @param ValidatorInterface|array $validator * @throws Exception\RuntimeException * @return Explode */ public function setValidator($validator) { if (is_array($validator)) { if (! isset($validator['name'])) { throw new Exception\RuntimeException( 'Invalid validator specification provided; does not include "name" key' ); } $name = $validator['name']; $options = isset($validator['options']) ? $validator['options'] : []; $validator = $this->getValidatorPluginManager()->get($name, $options); } if (! $validator instanceof ValidatorInterface) { throw new Exception\RuntimeException( 'Invalid validator given' ); } $this->validator = $validator; return $this; } /** * Gets the Validator for validating each value * * @return ValidatorInterface */ public function getValidator() { return $this->validator; } /** * Set break on first failure setting * * @param bool $break * @return Explode */ public function setBreakOnFirstFailure($break) { $this->breakOnFirstFailure = (bool) $break; return $this; } /** * Get break on first failure setting * * @return bool */ public function isBreakOnFirstFailure() { return $this->breakOnFirstFailure; } /** * Defined by Zend\Validator\ValidatorInterface * * Returns true if all values validate true * * @param mixed $value * @param mixed $context Extra "context" to provide the composed validator * @return bool * @throws Exception\RuntimeException */ public function isValid($value, $context = null) { $this->setValue($value); if ($value instanceof Traversable) { $value = ArrayUtils::iteratorToArray($value); } if (is_array($value)) { $values = $value; } elseif (is_string($value)) { $delimiter = $this->getValueDelimiter(); // Skip explode if delimiter is null, // used when value is expected to be either an // array when multiple values and a string for // single values (ie. MultiCheckbox form behavior) $values = (null !== $delimiter) ? explode($this->valueDelimiter, $value) : [$value]; } else { $values = [$value]; } $validator = $this->getValidator(); if (! $validator) { throw new Exception\RuntimeException(sprintf( '%s expects a validator to be set; none given', __METHOD__ )); } foreach ($values as $value) { if (! $validator->isValid($value, $context)) { $this->abstractOptions['messages'][] = $validator->getMessages(); if ($this->isBreakOnFirstFailure()) { return false; } } } return ! $this->abstractOptions['messages']; } } ================================================ FILE: src/File/Count.php ================================================ "Too many files, maximum '%max%' are allowed but '%count%' are given", self::TOO_FEW => "Too few files, minimum '%min%' are expected but '%count%' are given", ]; /** * @var array Error message template variables */ protected $messageVariables = [ 'min' => ['options' => 'min'], 'max' => ['options' => 'max'], 'count' => 'count' ]; /** * Actual filecount * * @var int */ protected $count; /** * Internal file array * @var array */ protected $files; /** * Options for this validator * * @var array */ protected $options = [ 'min' => null, // Minimum file count, if null there is no minimum file count 'max' => null, // Maximum file count, if null there is no maximum file count ]; /** * Sets validator options * * Min limits the file count, when used with max=null it is the maximum file count * It also accepts an array with the keys 'min' and 'max' * * If $options is an integer, it will be used as maximum file count * As Array is accepts the following keys: * 'min': Minimum filecount * 'max': Maximum filecount * * @param int|array|\Traversable $options Options for the adapter */ public function __construct($options = null) { if (1 < func_num_args()) { $args = func_get_args(); $options = [ 'min' => array_shift($args), 'max' => array_shift($args), ]; } if (is_string($options) || is_numeric($options)) { $options = ['max' => $options]; } parent::__construct($options); } /** * Returns the minimum file count * * @return int */ public function getMin() { return $this->options['min']; } /** * Sets the minimum file count * * @param int|array $min The minimum file count * @return Count Provides a fluent interface * @throws Exception\InvalidArgumentException When min is greater than max */ public function setMin($min) { if (is_array($min) && isset($min['min'])) { $min = $min['min']; } if (! is_numeric($min)) { throw new Exception\InvalidArgumentException('Invalid options to validator provided'); } $min = (int) $min; if (($this->getMax() !== null) && ($min > $this->getMax())) { throw new Exception\InvalidArgumentException( "The minimum must be less than or equal to the maximum file count, but {$min} > {$this->getMax()}" ); } $this->options['min'] = $min; return $this; } /** * Returns the maximum file count * * @return int */ public function getMax() { return $this->options['max']; } /** * Sets the maximum file count * * @param int|array $max The maximum file count * @return Count Provides a fluent interface * @throws Exception\InvalidArgumentException When max is smaller than min */ public function setMax($max) { if (is_array($max) && isset($max['max'])) { $max = $max['max']; } if (! is_numeric($max)) { throw new Exception\InvalidArgumentException('Invalid options to validator provided'); } $max = (int) $max; if (($this->getMin() !== null) && ($max < $this->getMin())) { throw new Exception\InvalidArgumentException( "The maximum must be greater than or equal to the minimum file count, but {$max} < {$this->getMin()}" ); } $this->options['max'] = $max; return $this; } /** * Adds a file for validation * * @param string|array $file * @return Count */ public function addFile($file) { if (is_string($file)) { $file = [$file]; } if (is_array($file)) { foreach ($file as $name) { if (! isset($this->files[$name]) && ! empty($name)) { $this->files[$name] = $name; } } } return $this; } /** * Returns true if and only if the file count of all checked files is at least min and * not bigger than max (when max is not null). Attention: When checking with set min you * must give all files with the first call, otherwise you will get a false. * * @param string|array $value Filenames to check for count * @param array $file File data from \Zend\File\Transfer\Transfer * @return bool */ public function isValid($value, $file = null) { if (($file !== null) && ! array_key_exists('destination', $file)) { $file['destination'] = dirname($value); } if (($file !== null) && array_key_exists('tmp_name', $file)) { $value = $file['destination'] . DIRECTORY_SEPARATOR . $file['name']; } if (($file === null) || ! empty($file['tmp_name'])) { $this->addFile($value); } $this->count = count($this->files); if (($this->getMax() !== null) && ($this->count > $this->getMax())) { return $this->throwError($file, self::TOO_MANY); } if (($this->getMin() !== null) && ($this->count < $this->getMin())) { return $this->throwError($file, self::TOO_FEW); } return true; } /** * Throws an error of the given type * * @param string $file * @param string $errorType * @return false */ protected function throwError($file, $errorType) { if ($file !== null) { if (is_array($file)) { if (array_key_exists('name', $file)) { $this->value = $file['name']; } } elseif (is_string($file)) { $this->value = $file; } } $this->error($errorType); return false; } } ================================================ FILE: src/File/Crc32.php ================================================ "File does not match the given crc32 hashes", self::NOT_DETECTED => "A crc32 hash could not be evaluated for the given file", self::NOT_FOUND => "File is not readable or does not exist", ]; /** * Options for this validator * * @var string */ protected $options = [ 'algorithm' => 'crc32', 'hash' => null, ]; /** * Returns all set crc32 hashes * * @return array */ public function getCrc32() { return $this->getHash(); } /** * Sets the crc32 hash for one or multiple files * * @param string|array $options * @return self Provides a fluent interface */ public function setCrc32($options) { $this->setHash($options); return $this; } /** * Adds the crc32 hash for one or multiple files * * @param string|array $options * @return self Provides a fluent interface */ public function addCrc32($options) { $this->addHash($options); return $this; } /** * Returns true if and only if the given file confirms the set hash * * @param string|array $value Filename to check for hash * @param array $file File data from \Zend\File\Transfer\Transfer (optional) * @return bool */ public function isValid($value, $file = null) { $fileInfo = $this->getFileInfo($value, $file); $this->setValue($fileInfo['filename']); // Is file readable ? if (empty($fileInfo['file']) || false === is_readable($fileInfo['file'])) { $this->error(self::NOT_FOUND); return false; } $hashes = array_unique(array_keys($this->getHash())); $filehash = hash_file('crc32', $fileInfo['file']); if ($filehash === false) { $this->error(self::NOT_DETECTED); return false; } foreach ($hashes as $hash) { if ($filehash === $hash) { return true; } } $this->error(self::DOES_NOT_MATCH); return false; } } ================================================ FILE: src/File/ExcludeExtension.php ================================================ "File has an incorrect extension", self::NOT_FOUND => "File is not readable or does not exist", ]; /** * Returns true if and only if the file extension of $value is not included in the * set extension list * * @param string|array $value Real file to check for extension * @param array $file File data from \Zend\File\Transfer\Transfer (optional) * @return bool */ public function isValid($value, $file = null) { $fileInfo = $this->getFileInfo($value, $file); // Is file readable ? if (! $this->getAllowNonExistentFile() && (empty($fileInfo['file']) || false === is_readable($fileInfo['file'])) ) { if (preg_match('/nofile\.mo$/', $fileInfo['file'])) { } $this->error(self::NOT_FOUND); return false; } $this->setValue($fileInfo['filename']); $extension = substr($fileInfo['filename'], strrpos($fileInfo['filename'], '.') + 1); $extensions = $this->getExtension(); if ($this->getCase() && (! in_array($extension, $extensions))) { return true; } elseif (! $this->getCase()) { foreach ($extensions as $ext) { if (strtolower($ext) == strtolower($extension)) { if (preg_match('/nofile\.mo$/', $fileInfo['file'])) { } $this->error(self::FALSE_EXTENSION); return false; } } return true; } $this->error(self::FALSE_EXTENSION); return false; } } ================================================ FILE: src/File/ExcludeMimeType.php ================================================ "File has an incorrect mimetype of '%type%'", self::NOT_DETECTED => "The mimetype could not be detected from the file", self::NOT_READABLE => "File is not readable or does not exist", ]; /** * Returns true if the mimetype of the file does not matche the given ones. Also parts * of mimetypes can be checked. If you give for example "image" all image * mime types will not be accepted like "image/gif", "image/jpeg" and so on. * * @param string|array $value Real file to check for mimetype * @param array $file File data from \Zend\File\Transfer\Transfer (optional) * @return bool */ public function isValid($value, $file = null) { $fileInfo = $this->getFileInfo($value, $file, true); $this->setValue($fileInfo['filename']); // Is file readable ? if (empty($fileInfo['file']) || false === is_readable($fileInfo['file'])) { $this->error(self::NOT_READABLE); return false; } $mimefile = $this->getMagicFile(); if (class_exists('finfo', false)) { if (! $this->isMagicFileDisabled() && (! empty($mimefile) && empty($this->finfo))) { $this->finfo = finfo_open(FILEINFO_MIME_TYPE, $mimefile); } if (empty($this->finfo)) { $this->finfo = finfo_open(FILEINFO_MIME_TYPE); } $this->type = null; if (! empty($this->finfo)) { $this->type = finfo_file($this->finfo, $fileInfo['file']); } } if (empty($this->type) && $this->getHeaderCheck()) { $this->type = $fileInfo['filetype']; } if (empty($this->type)) { $this->error(self::NOT_DETECTED); return false; } $mimetype = $this->getMimeType(true); if (in_array($this->type, $mimetype)) { $this->error(self::FALSE_TYPE); return false; } $types = explode('/', $this->type); $types = array_merge($types, explode('-', $this->type)); $types = array_merge($types, explode(';', $this->type)); foreach ($mimetype as $mime) { if (in_array($mime, $types)) { $this->error(self::FALSE_TYPE); return false; } } return true; } } ================================================ FILE: src/File/Exists.php ================================================ "File does not exist", ]; /** * Options for this validator * * @var array */ protected $options = [ 'directory' => null, // internal list of directories ]; /** * @var array Error message template variables */ protected $messageVariables = [ 'directory' => ['options' => 'directory'], ]; /** * Sets validator options * * @param string|array|\Traversable $options */ public function __construct($options = null) { if (is_string($options)) { $options = explode(',', $options); } if (is_array($options) && ! array_key_exists('directory', $options)) { $options = ['directory' => $options]; } parent::__construct($options); } /** * Returns the set file directories which are checked * * @param bool $asArray Returns the values as array; when false, a concatenated string is returned * @return string|null */ public function getDirectory($asArray = false) { $asArray = (bool) $asArray; $directory = $this->options['directory']; if ($asArray && isset($directory)) { $directory = explode(',', (string) $directory); } return $directory; } /** * Sets the file directory which will be checked * * @param string|array $directory The directories to validate * @return Extension Provides a fluent interface */ public function setDirectory($directory) { $this->options['directory'] = null; $this->addDirectory($directory); return $this; } /** * Adds the file directory which will be checked * * @param string|array $directory The directory to add for validation * @return Extension Provides a fluent interface * @throws Exception\InvalidArgumentException */ public function addDirectory($directory) { $directories = $this->getDirectory(true); if (! isset($directories)) { $directories = []; } if (is_string($directory)) { $directory = explode(',', $directory); } elseif (! is_array($directory)) { throw new Exception\InvalidArgumentException('Invalid options to validator provided'); } foreach ($directory as $content) { if (empty($content) || ! is_string($content)) { continue; } $directories[] = trim($content); } $directories = array_unique($directories); // Sanity check to ensure no empty values foreach ($directories as $key => $dir) { if (empty($dir)) { unset($directories[$key]); } } $this->options['directory'] = (! empty($directory)) ? implode(',', $directories) : null; return $this; } /** * Returns true if and only if the file already exists in the set directories * * @param string|array $value Real file to check for existence * @param array $file File data from \Zend\File\Transfer\Transfer (optional) * @return bool */ public function isValid($value, $file = null) { $fileInfo = $this->getFileInfo($value, $file, false, true); $this->setValue($fileInfo['filename']); $check = false; $directories = $this->getDirectory(true); if (! isset($directories)) { $check = true; if (! file_exists($fileInfo['file'])) { $this->error(self::DOES_NOT_EXIST); return false; } } else { foreach ($directories as $directory) { if (! isset($directory) || '' === $directory) { continue; } $check = true; if (! file_exists($directory . DIRECTORY_SEPARATOR . $fileInfo['basename'])) { $this->error(self::DOES_NOT_EXIST); return false; } } } if (! $check) { $this->error(self::DOES_NOT_EXIST); return false; } return true; } } ================================================ FILE: src/File/Extension.php ================================================ "File has an incorrect extension", self::NOT_FOUND => "File is not readable or does not exist", ]; /** * Options for this validator * * @var array */ protected $options = [ 'case' => false, // Validate case sensitive 'extension' => '', // List of extensions 'allowNonExistentFile' => false, // Allow validation even if file does not exist ]; /** * @var array Error message template variables */ protected $messageVariables = [ 'extension' => ['options' => 'extension'], ]; /** * Sets validator options * * @param string|array|Traversable $options */ public function __construct($options = null) { if ($options instanceof Traversable) { $options = ArrayUtils::iteratorToArray($options); } $case = null; if (1 < func_num_args()) { $case = func_get_arg(1); } if (is_array($options)) { if (isset($options['case'])) { $case = $options['case']; unset($options['case']); } if (! array_key_exists('extension', $options)) { $options = ['extension' => $options]; } } else { $options = ['extension' => $options]; } if ($case !== null) { $options['case'] = $case; } parent::__construct($options); } /** * Returns the case option * * @return bool */ public function getCase() { return $this->options['case']; } /** * Sets the case to use * * @param bool $case * @return self Provides a fluent interface */ public function setCase($case) { $this->options['case'] = (bool) $case; return $this; } /** * Returns the set file extension * * @return array */ public function getExtension() { $extension = explode(',', $this->options['extension']); return $extension; } /** * Sets the file extensions * * @param string|array $extension The extensions to validate * @return self Provides a fluent interface */ public function setExtension($extension) { $this->options['extension'] = null; $this->addExtension($extension); return $this; } /** * Adds the file extensions * * @param string|array $extension The extensions to add for validation * @return self Provides a fluent interface */ public function addExtension($extension) { $extensions = $this->getExtension(); if (is_string($extension)) { $extension = explode(',', $extension); } foreach ($extension as $content) { if (empty($content) || ! is_string($content)) { continue; } $extensions[] = trim($content); } $extensions = array_unique($extensions); // Sanity check to ensure no empty values foreach ($extensions as $key => $ext) { if (empty($ext)) { unset($extensions[$key]); } } $this->options['extension'] = implode(',', $extensions); return $this; } /** * Returns whether or not to allow validation of non-existent files. * * @return bool */ public function getAllowNonExistentFile() { return $this->options['allowNonExistentFile']; } /** * Sets the flag indicating whether or not to allow validation of non-existent files. * * @param bool $flag Whether or not to allow validation of non-existent files. * @return self Provides a fluent interface */ public function setAllowNonExistentFile($flag) { $this->options['allowNonExistentFile'] = (bool) $flag; return $this; } /** * Returns true if and only if the file extension of $value is included in the * set extension list * * @param string|array $value Real file to check for extension * @param array $file File data from \Zend\File\Transfer\Transfer (optional) * @return bool */ public function isValid($value, $file = null) { $fileInfo = $this->getFileInfo($value, $file); // Is file readable ? if (! $this->getAllowNonExistentFile() && (empty($fileInfo['file']) || false === is_readable($fileInfo['file'])) ) { $this->error(self::NOT_FOUND); return false; } $this->setValue($fileInfo['filename']); $extension = substr($fileInfo['filename'], strrpos($fileInfo['filename'], '.') + 1); $extensions = $this->getExtension(); if ($this->getCase() && (in_array($extension, $extensions))) { return true; } elseif (! $this->getCase()) { foreach ($extensions as $ext) { if (strtolower($ext) == strtolower($extension)) { return true; } } } $this->error(self::FALSE_EXTENSION); return false; } } ================================================ FILE: src/File/FileInformationTrait.php ================================================ getLegacyFileInfo($file, $hasType, $hasBasename); } if (is_array($value)) { return $this->getSapiFileInfo($value, $hasType, $hasBasename); } if ($value instanceof UploadedFileInterface) { return $this->getPsr7FileInfo($value, $hasType, $hasBasename); } return $this->getFileBasedFileInfo($value, $hasType, $hasBasename); } /** * Generate file information array with legacy Zend_File_Transfer API * * @param array $file File data * @param bool $hasType Return with filetype * @param bool $hasBasename Basename is calculated from location path * @return array */ private function getLegacyFileInfo( array $file, $hasType = false, $hasBasename = false ) { $fileInfo = []; $fileInfo['filename'] = $file['name']; $fileInfo['file'] = $file['tmp_name']; if ($hasBasename) { $fileInfo['basename'] = basename($fileInfo['file']); } if ($hasType) { $fileInfo['filetype'] = $file['type']; } return $fileInfo; } /** * Generate file information array with SAPI * * @param array $file File data from SAPI * @param bool $hasType Return with filetype * @param bool $hasBasename Filename is calculated from location path * @return array */ private function getSapiFileInfo( array $file, $hasType = false, $hasBasename = false ) { if (! isset($file['tmp_name']) || ! isset($file['name'])) { throw new Exception\InvalidArgumentException( 'Value array must be in $_FILES format' ); } $fileInfo = []; $fileInfo['file'] = $file['tmp_name']; $fileInfo['filename'] = $file['name']; if ($hasBasename) { $fileInfo['basename'] = basename($fileInfo['file']); } if ($hasType) { $fileInfo['filetype'] = $file['type']; } return $fileInfo; } /** * Generate file information array with PSR-7 UploadedFileInterface * * @param UploadedFileInterface $file * @param bool $hasType Return with filetype * @param bool $hasBasename Filename is calculated from location path * @return array */ private function getPsr7FileInfo( UploadedFileInterface $file, $hasType = false, $hasBasename = false ) { $fileInfo = []; $fileInfo['file'] = $file->getStream()->getMetadata('uri'); $fileInfo['filename'] = $file->getClientFilename(); if ($hasBasename) { $fileInfo['basename'] = basename($fileInfo['file']); } if ($hasType) { $fileInfo['filetype'] = $file->getClientMediaType(); } return $fileInfo; } /** * Generate file information array with base method * * @param string $file File path * @param bool $hasType Return with filetype * @param bool $hasBasename Filename is calculated from location path * @return array */ private function getFileBasedFileInfo( $file, $hasType = false, $hasBasename = false ) { $fileInfo = []; $fileInfo['file'] = $file; $fileInfo['filename'] = basename($fileInfo['file']); if ($hasBasename) { $fileInfo['basename'] = basename($fileInfo['file']); } if ($hasType) { $fileInfo['filetype'] = null; } return $fileInfo; } } ================================================ FILE: src/File/FilesSize.php ================================================ "All files in sum should have a maximum size of '%max%' but '%size%' were detected", self::TOO_SMALL => "All files in sum should have a minimum size of '%min%' but '%size%' were detected", self::NOT_READABLE => "One or more files can not be read", ]; /** * Internal file array * * @var array */ protected $files; /** * Sets validator options * * Min limits the used disk space for all files, when used with max=null it is the maximum file size * It also accepts an array with the keys 'min' and 'max' * * @param int|array|Traversable $options Options for this validator * @throws \Zend\Validator\Exception\InvalidArgumentException */ public function __construct($options = null) { $this->files = []; $this->setSize(0); if ($options instanceof Traversable) { $options = ArrayUtils::iteratorToArray($options); } elseif (is_scalar($options)) { $options = ['max' => $options]; } elseif (! is_array($options)) { throw new Exception\InvalidArgumentException('Invalid options to validator provided'); } if (1 < func_num_args()) { $argv = func_get_args(); array_shift($argv); $options['max'] = array_shift($argv); if (! empty($argv)) { $options['useByteString'] = array_shift($argv); } } parent::__construct($options); } /** * Returns true if and only if the disk usage of all files is at least min and * not bigger than max (when max is not null). * * @param string|array $value Real file to check for size * @param array $file File data from \Zend\File\Transfer\Transfer * @return bool */ public function isValid($value, $file = null) { if (is_string($value)) { $value = [$value]; } elseif (is_array($value) && isset($value['tmp_name'])) { $value = [$value]; } $min = $this->getMin(true); $max = $this->getMax(true); $size = $this->getSize(); foreach ($value as $files) { if (is_array($files)) { if (! isset($files['tmp_name']) || ! isset($files['name'])) { throw new Exception\InvalidArgumentException( 'Value array must be in $_FILES format' ); } $file = $files; $files = $files['tmp_name']; } // Is file readable ? if (empty($files) || false === is_readable($files)) { $this->throwError($file, self::NOT_READABLE); continue; } if (! isset($this->files[$files])) { $this->files[$files] = $files; } else { // file already counted... do not count twice continue; } // limited to 2GB files ErrorHandler::start(); $size += filesize($files); ErrorHandler::stop(); $this->size = $size; if (($max !== null) && ($max < $size)) { if ($this->getByteString()) { $this->options['max'] = $this->toByteString($max); $this->size = $this->toByteString($size); $this->throwError($file, self::TOO_BIG); $this->options['max'] = $max; $this->size = $size; } else { $this->throwError($file, self::TOO_BIG); } } } // Check that aggregate files are >= minimum size if (($min !== null) && ($size < $min)) { if ($this->getByteString()) { $this->options['min'] = $this->toByteString($min); $this->size = $this->toByteString($size); $this->throwError($file, self::TOO_SMALL); $this->options['min'] = $min; $this->size = $size; } else { $this->throwError($file, self::TOO_SMALL); } } if ($this->getMessages()) { return false; } return true; } /** * Throws an error of the given type * * @param string $file * @param string $errorType * @return false */ protected function throwError($file, $errorType) { if ($file !== null) { if (is_array($file)) { if (array_key_exists('name', $file)) { $this->value = $file['name']; } } elseif (is_string($file)) { $this->value = $file; } } $this->error($errorType); return false; } } ================================================ FILE: src/File/Hash.php ================================================ "File does not match the given hashes", self::NOT_DETECTED => "A hash could not be evaluated for the given file", self::NOT_FOUND => "File is not readable or does not exist" ]; /** * Options for this validator * * @var string */ protected $options = [ 'algorithm' => 'crc32', 'hash' => null, ]; /** * Sets validator options * * @param string|array $options */ public function __construct($options = null) { if (is_scalar($options) || (is_array($options) && ! array_key_exists('hash', $options))) { $options = ['hash' => $options]; } if (1 < func_num_args()) { $options['algorithm'] = func_get_arg(1); } parent::__construct($options); } /** * Returns the set hash values as array, the hash as key and the algorithm the value * * @return array */ public function getHash() { return $this->options['hash']; } /** * Sets the hash for one or multiple files * * @param string|array $options * @return self Provides a fluent interface */ public function setHash($options) { $this->options['hash'] = null; $this->addHash($options); return $this; } /** * Adds the hash for one or multiple files * * @param string|array $options * @throws Exception\InvalidArgumentException * @return self Provides a fluent interface */ public function addHash($options) { if (is_string($options)) { $options = [$options]; } elseif (! is_array($options)) { throw new Exception\InvalidArgumentException("False parameter given"); } $known = hash_algos(); if (! isset($options['algorithm'])) { $algorithm = $this->options['algorithm']; } else { $algorithm = $options['algorithm']; unset($options['algorithm']); } if (! in_array($algorithm, $known)) { throw new Exception\InvalidArgumentException("Unknown algorithm '{$algorithm}'"); } foreach ($options as $value) { if (! is_string($value)) { throw new Exception\InvalidArgumentException(sprintf( 'Hash must be a string, %s received', is_object($value) ? get_class($value) : gettype($value) )); } $this->options['hash'][$value] = $algorithm; } return $this; } /** * Returns true if and only if the given file confirms the set hash * * @param string|array $value File to check for hash * @param array $file File data from \Zend\File\Transfer\Transfer (optional) * @return bool */ public function isValid($value, $file = null) { $fileInfo = $this->getFileInfo($value, $file); $this->setValue($fileInfo['filename']); // Is file readable ? if (empty($fileInfo['file']) || false === is_readable($fileInfo['file'])) { $this->error(self::NOT_FOUND); return false; } $algos = array_unique(array_values($this->getHash())); foreach ($algos as $algorithm) { $filehash = hash_file($algorithm, $fileInfo['file']); if ($filehash === false) { $this->error(self::NOT_DETECTED); return false; } if (isset($this->getHash()[$filehash]) && $this->getHash()[$filehash] === $algorithm) { return true; } } $this->error(self::DOES_NOT_MATCH); return false; } } ================================================ FILE: src/File/ImageSize.php ================================================ "Maximum allowed width for image should be '%maxwidth%' but '%width%' detected", self::WIDTH_TOO_SMALL => "Minimum expected width for image should be '%minwidth%' but '%width%' detected", self::HEIGHT_TOO_BIG => "Maximum allowed height for image should be '%maxheight%' but '%height%' detected", self::HEIGHT_TOO_SMALL => "Minimum expected height for image should be '%minheight%' but '%height%' detected", self::NOT_DETECTED => "The size of image could not be detected", self::NOT_READABLE => "File is not readable or does not exist", ]; /** * @var array Error message template variables */ protected $messageVariables = [ 'minwidth' => ['options' => 'minWidth'], 'maxwidth' => ['options' => 'maxWidth'], 'minheight' => ['options' => 'minHeight'], 'maxheight' => ['options' => 'maxHeight'], 'width' => 'width', 'height' => 'height' ]; /** * Detected width * * @var int */ protected $width; /** * Detected height * * @var int */ protected $height; /** * Options for this validator * * @var array */ protected $options = [ 'minWidth' => null, // Minimum image width 'maxWidth' => null, // Maximum image width 'minHeight' => null, // Minimum image height 'maxHeight' => null, // Maximum image height ]; /** * Sets validator options * * Accepts the following option keys: * - minheight * - minwidth * - maxheight * - maxwidth * * @param array|\Traversable $options */ public function __construct($options = null) { if (1 < func_num_args()) { if (! is_array($options)) { $options = ['minWidth' => $options]; } $argv = func_get_args(); array_shift($argv); $options['minHeight'] = array_shift($argv); if (! empty($argv)) { $options['maxWidth'] = array_shift($argv); if (! empty($argv)) { $options['maxHeight'] = array_shift($argv); } } } parent::__construct($options); } /** * Returns the minimum allowed width * * @return int */ public function getMinWidth() { return $this->options['minWidth']; } /** * Sets the minimum allowed width * * @param int $minWidth * @throws Exception\InvalidArgumentException When minwidth is greater than maxwidth * @return self Provides a fluid interface */ public function setMinWidth($minWidth) { if (($this->getMaxWidth() !== null) && ($minWidth > $this->getMaxWidth())) { throw new Exception\InvalidArgumentException( "The minimum image width must be less than or equal to the " . " maximum image width, but {$minWidth} > {$this->getMaxWidth()}" ); } $this->options['minWidth'] = (int) $minWidth; return $this; } /** * Returns the maximum allowed width * * @return int */ public function getMaxWidth() { return $this->options['maxWidth']; } /** * Sets the maximum allowed width * * @param int $maxWidth * @throws Exception\InvalidArgumentException When maxwidth is less than minwidth * @return self Provides a fluid interface */ public function setMaxWidth($maxWidth) { if (($this->getMinWidth() !== null) && ($maxWidth < $this->getMinWidth())) { throw new Exception\InvalidArgumentException( "The maximum image width must be greater than or equal to the " . "minimum image width, but {$maxWidth} < {$this->getMinWidth()}" ); } $this->options['maxWidth'] = (int) $maxWidth; return $this; } /** * Returns the minimum allowed height * * @return int */ public function getMinHeight() { return $this->options['minHeight']; } /** * Sets the minimum allowed height * * @param int $minHeight * @throws Exception\InvalidArgumentException When minheight is greater than maxheight * @return self Provides a fluid interface */ public function setMinHeight($minHeight) { if (($this->getMaxHeight() !== null) && ($minHeight > $this->getMaxHeight())) { throw new Exception\InvalidArgumentException( "The minimum image height must be less than or equal to the " . " maximum image height, but {$minHeight} > {$this->getMaxHeight()}" ); } $this->options['minHeight'] = (int) $minHeight; return $this; } /** * Returns the maximum allowed height * * @return int */ public function getMaxHeight() { return $this->options['maxHeight']; } /** * Sets the maximum allowed height * * @param int $maxHeight * @throws Exception\InvalidArgumentException When maxheight is less than minheight * @return self Provides a fluid interface */ public function setMaxHeight($maxHeight) { if (($this->getMinHeight() !== null) && ($maxHeight < $this->getMinHeight())) { throw new Exception\InvalidArgumentException( "The maximum image height must be greater than or equal to the " . "minimum image height, but {$maxHeight} < {$this->getMinHeight()}" ); } $this->options['maxHeight'] = (int) $maxHeight; return $this; } /** * Returns the set minimum image sizes * * @return array */ public function getImageMin() { return ['minWidth' => $this->getMinWidth(), 'minHeight' => $this->getMinHeight()]; } /** * Returns the set maximum image sizes * * @return array */ public function getImageMax() { return ['maxWidth' => $this->getMaxWidth(), 'maxHeight' => $this->getMaxHeight()]; } /** * Returns the set image width sizes * * @return array */ public function getImageWidth() { return ['minWidth' => $this->getMinWidth(), 'maxWidth' => $this->getMaxWidth()]; } /** * Returns the set image height sizes * * @return array */ public function getImageHeight() { return ['minHeight' => $this->getMinHeight(), 'maxHeight' => $this->getMaxHeight()]; } /** * Sets the minimum image size * * @param array $options The minimum image dimensions * @return self Provides a fluent interface */ public function setImageMin($options) { $this->setOptions($options); return $this; } /** * Sets the maximum image size * * @param array|\Traversable $options The maximum image dimensions * @return self Provides a fluent interface */ public function setImageMax($options) { $this->setOptions($options); return $this; } /** * Sets the minimum and maximum image width * * @param array $options The image width dimensions * @return self Provides a fluent interface */ public function setImageWidth($options) { $this->setImageMin($options); $this->setImageMax($options); return $this; } /** * Sets the minimum and maximum image height * * @param array $options The image height dimensions * @return self Provides a fluent interface */ public function setImageHeight($options) { $this->setImageMin($options); $this->setImageMax($options); return $this; } /** * Returns true if and only if the image size of $value is at least min and * not bigger than max * * @param string|array $value Real file to check for image size * @param array $file File data from \Zend\File\Transfer\Transfer (optional) * @return bool */ public function isValid($value, $file = null) { $fileInfo = $this->getFileInfo($value, $file); $this->setValue($fileInfo['filename']); // Is file readable ? if (empty($fileInfo['file']) || false === is_readable($fileInfo['file'])) { $this->error(self::NOT_READABLE); return false; } ErrorHandler::start(); $size = getimagesize($fileInfo['file']); ErrorHandler::stop(); if (empty($size) || ($size[0] === 0) || ($size[1] === 0)) { $this->error(self::NOT_DETECTED); return false; } $this->width = $size[0]; $this->height = $size[1]; if ($this->width < $this->getMinWidth()) { $this->error(self::WIDTH_TOO_SMALL); } if (($this->getMaxWidth() !== null) && ($this->getMaxWidth() < $this->width)) { $this->error(self::WIDTH_TOO_BIG); } if ($this->height < $this->getMinHeight()) { $this->error(self::HEIGHT_TOO_SMALL); } if (($this->getMaxHeight() !== null) && ($this->getMaxHeight() < $this->height)) { $this->error(self::HEIGHT_TOO_BIG); } if ($this->getMessages()) { return false; } return true; } } ================================================ FILE: src/File/IsCompressed.php ================================================ "File is not compressed, '%type%' detected", self::NOT_DETECTED => "The mimetype could not be detected from the file", self::NOT_READABLE => "File is not readable or does not exist", ]; /** * Sets validator options * * @param string|array|Traversable $options */ public function __construct($options = []) { // http://hul.harvard.edu/ois/systems/wax/wax-public-help/mimetypes.htm $default = [ 'application/arj', 'application/gnutar', 'application/lha', 'application/lzx', 'application/vnd.ms-cab-compressed', 'application/x-ace-compressed', 'application/x-arc', 'application/x-archive', 'application/x-arj', 'application/x-bzip', 'application/x-bzip2', 'application/x-cab-compressed', 'application/x-compress', 'application/x-compressed', 'application/x-cpio', 'application/x-debian-package', 'application/x-eet', 'application/x-gzip', 'application/x-java-pack200', 'application/x-lha', 'application/x-lharc', 'application/x-lzh', 'application/x-lzma', 'application/x-lzx', 'application/x-rar', 'application/x-sit', 'application/x-stuffit', 'application/x-tar', 'application/zip', 'application/x-zip', 'application/zoo', 'multipart/x-gzip', ]; if ($options instanceof Traversable) { $options = ArrayUtils::iteratorToArray($options); } if ($options === null) { $options = []; } parent::__construct($options); if (! $this->getMimeType()) { $this->setMimeType($default); } } } ================================================ FILE: src/File/IsImage.php ================================================ "File is no image, '%type%' detected", self::NOT_DETECTED => "The mimetype could not be detected from the file", self::NOT_READABLE => "File is not readable or does not exist", ]; /** * Sets validator options * * @param array|Traversable|string $options */ public function __construct($options = []) { // http://www.iana.org/assignments/media-types/media-types.xhtml#image $default = [ 'application/cdf', 'application/dicom', 'application/fractals', 'application/postscript', 'application/vnd.hp-hpgl', 'application/vnd.oasis.opendocument.graphics', 'application/x-cdf', 'application/x-cmu-raster', 'application/x-ima', 'application/x-inventor', 'application/x-koan', 'application/x-portable-anymap', 'application/x-world-x-3dmf', 'image/bmp', 'image/c', 'image/cgm', 'image/fif', 'image/gif', 'image/jpeg', 'image/jpm', 'image/jpx', 'image/jp2', 'image/naplps', 'image/pjpeg', 'image/png', 'image/svg', 'image/svg+xml', 'image/tiff', 'image/vnd.adobe.photoshop', 'image/vnd.djvu', 'image/vnd.fpx', 'image/vnd.net-fpx', 'image/webp', 'image/x-cmu-raster', 'image/x-cmx', 'image/x-coreldraw', 'image/x-cpi', 'image/x-emf', 'image/x-ico', 'image/x-icon', 'image/x-jg', 'image/x-ms-bmp', 'image/x-niff', 'image/x-pict', 'image/x-pcx', 'image/x-png', 'image/x-portable-anymap', 'image/x-portable-bitmap', 'image/x-portable-greymap', 'image/x-portable-pixmap', 'image/x-quicktime', 'image/x-rgb', 'image/x-tiff', 'image/x-unknown', 'image/x-windows-bmp', 'image/x-xpmi', ]; if ($options instanceof Traversable) { $options = ArrayUtils::iteratorToArray($options); } if ($options === null) { $options = []; } parent::__construct($options); if (! $this->getMimeType()) { $this->setMimeType($default); } } } ================================================ FILE: src/File/Md5.php ================================================ "File does not match the given md5 hashes", self::NOT_DETECTED => "An md5 hash could not be evaluated for the given file", self::NOT_FOUND => "File is not readable or does not exist", ]; /** * Options for this validator * * @var string */ protected $options = [ 'algorithm' => 'md5', 'hash' => null, ]; /** * Returns all set md5 hashes * * @return array */ public function getMd5() { return $this->getHash(); } /** * Sets the md5 hash for one or multiple files * * @param string|array $options * @return Hash Provides a fluent interface */ public function setMd5($options) { $this->setHash($options); return $this; } /** * Adds the md5 hash for one or multiple files * * @param string|array $options * @return Hash Provides a fluent interface */ public function addMd5($options) { $this->addHash($options); return $this; } /** * Returns true if and only if the given file confirms the set hash * * @param string|array $value Filename to check for hash * @param array $file File data from \Zend\File\Transfer\Transfer (optional) * @return bool */ public function isValid($value, $file = null) { $fileInfo = $this->getFileInfo($value, $file); $this->setValue($fileInfo['filename']); // Is file readable ? if (empty($fileInfo['file']) || false === is_readable($fileInfo['file'])) { $this->error(self::NOT_FOUND); return false; } $hashes = array_unique(array_keys($this->getHash())); $filehash = hash_file('md5', $fileInfo['file']); if ($filehash === false) { $this->error(self::NOT_DETECTED); return false; } foreach ($hashes as $hash) { if ($filehash === $hash) { return true; } } $this->error(self::DOES_NOT_MATCH); return false; } } ================================================ FILE: src/File/MimeType.php ================================================ "File has an incorrect mimetype of '%type%'", self::NOT_DETECTED => "The mimetype could not be detected from the file", self::NOT_READABLE => "File is not readable or does not exist", ]; /** * @var array */ protected $messageVariables = [ 'type' => 'type' ]; /** * @var string */ protected $type; /** * Finfo object to use * * @var resource */ protected $finfo; /** * If no environment variable 'MAGIC' is set, try and autodiscover it based on common locations * @var array */ protected $magicFiles = [ '/usr/share/misc/magic', '/usr/share/misc/magic.mime', '/usr/share/misc/magic.mgc', '/usr/share/mime/magic', '/usr/share/mime/magic.mime', '/usr/share/mime/magic.mgc', '/usr/share/file/magic', '/usr/share/file/magic.mime', '/usr/share/file/magic.mgc', ]; /** * Options for this validator * * @var array */ protected $options = [ 'enableHeaderCheck' => false, // Allow header check 'disableMagicFile' => false, // Disable usage of magicfile 'magicFile' => null, // Magicfile to use 'mimeType' => null, // Mimetype to allow ]; /** * Sets validator options * * Mimetype to accept * - NULL means default PHP usage by using the environment variable 'magic' * - FALSE means disabling searching for mimetype, should be used for PHP 5.3 * - A string is the mimetype file to use * * @param string|array|Traversable $options */ public function __construct($options = null) { if ($options instanceof Traversable) { $options = ArrayUtils::iteratorToArray($options); } elseif (is_string($options)) { $this->setMimeType($options); $options = []; } elseif (is_array($options)) { if (isset($options['magicFile'])) { $this->setMagicFile($options['magicFile']); unset($options['magicFile']); } if (isset($options['enableHeaderCheck'])) { $this->enableHeaderCheck($options['enableHeaderCheck']); unset($options['enableHeaderCheck']); } if (array_key_exists('mimeType', $options)) { $this->setMimeType($options['mimeType']); unset($options['mimeType']); } // Handle cases where mimetypes are interspersed with options, or // options are simply an array of mime types foreach (array_keys($options) as $key) { if (! is_int($key)) { continue; } $this->addMimeType($options[$key]); unset($options[$key]); } } parent::__construct($options); } /** * Returns the actual set magicfile * * @return string */ public function getMagicFile() { if (null === $this->options['magicFile']) { $magic = getenv('magic'); if (! empty($magic)) { $this->setMagicFile($magic); if ($this->options['magicFile'] === null) { $this->options['magicFile'] = false; } return $this->options['magicFile']; } foreach ($this->magicFiles as $file) { try { $this->setMagicFile($file); } catch (Exception\ExceptionInterface $e) { // suppressing errors which are thrown due to open_basedir restrictions continue; } if ($this->options['magicFile'] !== null) { return $this->options['magicFile']; } } if ($this->options['magicFile'] === null) { $this->options['magicFile'] = false; } } return $this->options['magicFile']; } /** * Sets the magicfile to use * if null, the MAGIC constant from php is used * if the MAGIC file is erroneous, no file will be set * if false, the default MAGIC file from PHP will be used * * @param string $file * @throws Exception\RuntimeException When finfo can not read the magicfile * @throws Exception\InvalidArgumentException * @throws Exception\InvalidMagicMimeFileException * @return self Provides fluid interface */ public function setMagicFile($file) { if ($file === false) { $this->options['magicFile'] = false; } elseif (empty($file)) { $this->options['magicFile'] = null; } elseif (! (class_exists('finfo', false))) { $this->options['magicFile'] = null; throw new Exception\RuntimeException('Magicfile can not be set; there is no finfo extension installed'); } elseif (! is_file($file) || ! is_readable($file)) { throw new Exception\InvalidArgumentException(sprintf( 'The given magicfile ("%s") could not be read', $file )); } else { ErrorHandler::start(E_NOTICE | E_WARNING); $this->finfo = finfo_open(FILEINFO_MIME_TYPE, $file); $error = ErrorHandler::stop(); if (empty($this->finfo)) { $this->finfo = null; throw new Exception\InvalidMagicMimeFileException(sprintf( 'The given magicfile ("%s") could not be used by ext/finfo', $file ), 0, $error); } $this->options['magicFile'] = $file; } return $this; } /** * Disables usage of MagicFile * * @param $disable boolean False disables usage of magic file * @return self Provides fluid interface */ public function disableMagicFile($disable) { $this->options['disableMagicFile'] = (bool) $disable; return $this; } /** * Is usage of MagicFile disabled? * * @return bool */ public function isMagicFileDisabled() { return $this->options['disableMagicFile']; } /** * Returns the Header Check option * * @return bool */ public function getHeaderCheck() { return $this->options['enableHeaderCheck']; } /** * Defines if the http header should be used * Note that this is unsafe and therefor the default value is false * * @param bool $headerCheck * @return self Provides fluid interface */ public function enableHeaderCheck($headerCheck = true) { $this->options['enableHeaderCheck'] = (bool) $headerCheck; return $this; } /** * Returns the set mimetypes * * @param bool $asArray Returns the values as array, when false a concatenated string is returned * @return string|array */ public function getMimeType($asArray = false) { $asArray = (bool) $asArray; $mimetype = (string) $this->options['mimeType']; if ($asArray) { $mimetype = explode(',', $mimetype); } return $mimetype; } /** * Sets the mimetypes * * @param string|array $mimetype The mimetypes to validate * @return self Provides a fluent interface */ public function setMimeType($mimetype) { $this->options['mimeType'] = null; $this->addMimeType($mimetype); return $this; } /** * Adds the mimetypes * * @param string|array $mimetype The mimetypes to add for validation * @throws Exception\InvalidArgumentException * @return self Provides a fluent interface */ public function addMimeType($mimetype) { $mimetypes = $this->getMimeType(true); if (is_string($mimetype)) { $mimetype = explode(',', $mimetype); } elseif (! is_array($mimetype)) { throw new Exception\InvalidArgumentException("Invalid options to validator provided"); } if (isset($mimetype['magicFile'])) { unset($mimetype['magicFile']); } foreach ($mimetype as $content) { if (empty($content) || ! is_string($content)) { continue; } $mimetypes[] = trim($content); } $mimetypes = array_unique($mimetypes); // Sanity check to ensure no empty values foreach ($mimetypes as $key => $mt) { if (empty($mt)) { unset($mimetypes[$key]); } } $this->options['mimeType'] = implode(',', $mimetypes); return $this; } /** * Defined by Zend\Validator\ValidatorInterface * * Returns true if the mimetype of the file matches the given ones. Also parts * of mimetypes can be checked. If you give for example "image" all image * mime types will be accepted like "image/gif", "image/jpeg" and so on. * * @param string|array $value Real file to check for mimetype * @param array $file File data from \Zend\File\Transfer\Transfer (optional) * @return bool */ public function isValid($value, $file = null) { $fileInfo = $this->getFileInfo($value, $file, true); $this->setValue($fileInfo['filename']); // Is file readable ? if (empty($fileInfo['file']) || false === is_readable($fileInfo['file'])) { $this->error(static::NOT_READABLE); return false; } $mimefile = $this->getMagicFile(); if (class_exists('finfo', false)) { if (! $this->isMagicFileDisabled() && (! empty($mimefile) && empty($this->finfo))) { ErrorHandler::start(E_NOTICE | E_WARNING); $this->finfo = finfo_open(FILEINFO_MIME_TYPE, $mimefile); ErrorHandler::stop(); } if (empty($this->finfo)) { ErrorHandler::start(E_NOTICE | E_WARNING); $this->finfo = finfo_open(FILEINFO_MIME_TYPE); ErrorHandler::stop(); } $this->type = null; if (! empty($this->finfo)) { $this->type = finfo_file($this->finfo, $fileInfo['file']); unset($this->finfo); } } if (empty($this->type) && $this->getHeaderCheck()) { $this->type = $fileInfo['filetype']; } if (empty($this->type)) { $this->error(static::NOT_DETECTED); return false; } $mimetype = $this->getMimeType(true); if (in_array($this->type, $mimetype)) { return true; } $types = explode('/', $this->type); $types = array_merge($types, explode('-', $this->type)); $types = array_merge($types, explode(';', $this->type)); foreach ($mimetype as $mime) { if (in_array($mime, $types)) { return true; } } $this->error(static::FALSE_TYPE); return false; } } ================================================ FILE: src/File/NotExists.php ================================================ "File exists", ]; /** * Returns true if and only if the file does not exist in the set destinations * * @param string|array $value Real file to check for existence * @param array $file File data from \Zend\File\Transfer\Transfer (optional) * @return bool */ public function isValid($value, $file = null) { $fileInfo = $this->getFileInfo($value, $file, false, true); $this->setValue($fileInfo['filename']); $check = false; $directories = $this->getDirectory(true); if (! isset($directories)) { $check = true; if (file_exists($fileInfo['file'])) { $this->error(self::DOES_EXIST); return false; } } else { foreach ($directories as $directory) { if (! isset($directory) || '' === $directory) { continue; } $check = true; if (file_exists($directory . DIRECTORY_SEPARATOR . $fileInfo['basename'])) { $this->error(self::DOES_EXIST); return false; } } } if (! $check) { $this->error(self::DOES_EXIST); return false; } return true; } } ================================================ FILE: src/File/Sha1.php ================================================ "File does not match the given sha1 hashes", self::NOT_DETECTED => "A sha1 hash could not be evaluated for the given file", self::NOT_FOUND => "File is not readable or does not exist", ]; /** * Options for this validator * * @var string */ protected $options = [ 'algorithm' => 'sha1', 'hash' => null, ]; /** * Returns all set sha1 hashes * * @return array */ public function getSha1() { return $this->getHash(); } /** * Sets the sha1 hash for one or multiple files * * @param string|array $options * @return Hash Provides a fluent interface */ public function setSha1($options) { $this->setHash($options); return $this; } /** * Adds the sha1 hash for one or multiple files * * @param string|array $options * @return Hash Provides a fluent interface */ public function addSha1($options) { $this->addHash($options); return $this; } /** * Returns true if and only if the given file confirms the set hash * * @param string $value|array Filename to check for hash * @param array $file File data from \Zend\File\Transfer\Transfer (optional) * @return bool */ public function isValid($value, $file = null) { $fileInfo = $this->getFileInfo($value, $file); $this->setValue($fileInfo['filename']); // Is file readable ? if (empty($fileInfo['file']) || false === is_readable($fileInfo['file'])) { $this->error(self::NOT_FOUND); return false; } $hashes = array_unique(array_keys($this->getHash())); $filehash = hash_file('sha1', $fileInfo['file']); if ($filehash === false) { $this->error(self::NOT_DETECTED); return false; } foreach ($hashes as $hash) { if ($filehash === $hash) { return true; } } $this->error(self::DOES_NOT_MATCH); return false; } } ================================================ FILE: src/File/Size.php ================================================ "Maximum allowed size for file is '%max%' but '%size%' detected", self::TOO_SMALL => "Minimum expected size for file is '%min%' but '%size%' detected", self::NOT_FOUND => "File is not readable or does not exist", ]; /** * @var array Error message template variables */ protected $messageVariables = [ 'min' => ['options' => 'min'], 'max' => ['options' => 'max'], 'size' => 'size', ]; /** * Detected size * * @var int */ protected $size; /** * Options for this validator * * @var array */ protected $options = [ 'min' => null, // Minimum file size, if null there is no minimum 'max' => null, // Maximum file size, if null there is no maximum 'useByteString' => true, // Use byte string? ]; /** * Sets validator options * * If $options is an integer, it will be used as maximum file size * As Array is accepts the following keys: * 'min': Minimum file size * 'max': Maximum file size * 'useByteString': Use bytestring or real size for messages * * @param int|array|\Traversable $options Options for the adapter */ public function __construct($options = null) { if (is_string($options) || is_numeric($options)) { $options = ['max' => $options]; } if (1 < func_num_args()) { $argv = func_get_args(); array_shift($argv); $options['max'] = array_shift($argv); if (! empty($argv)) { $options['useByteString'] = array_shift($argv); } } parent::__construct($options); } /** * Should messages return bytes as integer or as string in SI notation * * @param bool $byteString Use bytestring ? * @return int */ public function useByteString($byteString = true) { $this->options['useByteString'] = (bool) $byteString; return $this; } /** * Will bytestring be used? * * @return bool */ public function getByteString() { return $this->options['useByteString']; } /** * Returns the minimum file size * * @param bool $raw Whether or not to force return of the raw value (defaults off) * @return int|string */ public function getMin($raw = false) { $min = $this->options['min']; if (! $raw && $this->getByteString()) { $min = $this->toByteString($min); } return $min; } /** * Sets the minimum file size * * File size can be an integer or a byte string * This includes 'B', 'kB', 'MB', 'GB', 'TB', 'PB', 'EB', 'ZB', 'YB' * For example: 2000, 2MB, 0.2GB * * @param int|string $min The minimum file size * @throws Exception\InvalidArgumentException When min is greater than max * @return self Provides a fluent interface */ public function setMin($min) { if (! is_string($min) && ! is_numeric($min)) { throw new Exception\InvalidArgumentException('Invalid options to validator provided'); } $min = (int) $this->fromByteString($min); $max = $this->getMax(true); if (($max !== null) && ($min > $max)) { throw new Exception\InvalidArgumentException( "The minimum must be less than or equal to the maximum file size, but $min > $max" ); } $this->options['min'] = $min; return $this; } /** * Returns the maximum file size * * @param bool $raw Whether or not to force return of the raw value (defaults off) * @return int|string */ public function getMax($raw = false) { $max = $this->options['max']; if (! $raw && $this->getByteString()) { $max = $this->toByteString($max); } return $max; } /** * Sets the maximum file size * * File size can be an integer or a byte string * This includes 'B', 'kB', 'MB', 'GB', 'TB', 'PB', 'EB', 'ZB', 'YB' * For example: 2000, 2MB, 0.2GB * * @param int|string $max The maximum file size * @throws Exception\InvalidArgumentException When max is smaller than min * @return self Provides a fluent interface */ public function setMax($max) { if (! is_string($max) && ! is_numeric($max)) { throw new Exception\InvalidArgumentException('Invalid options to validator provided'); } $max = (int) $this->fromByteString($max); $min = $this->getMin(true); if (($min !== null) && ($max < $min)) { throw new Exception\InvalidArgumentException( "The maximum must be greater than or equal to the minimum file size, but $max < $min" ); } $this->options['max'] = $max; return $this; } /** * Retrieve current detected file size * * @return int */ protected function getSize() { return $this->size; } /** * Set current size * * @param int $size * @return self */ protected function setSize($size) { $this->size = $size; return $this; } /** * Returns true if and only if the file size of $value is at least min and * not bigger than max (when max is not null). * * @param string|array $value File to check for size * @param array $file File data from \Zend\File\Transfer\Transfer (optional) * @return bool */ public function isValid($value, $file = null) { $fileInfo = $this->getFileInfo($value, $file); $this->setValue($fileInfo['filename']); // Is file readable ? if (empty($fileInfo['file']) || false === is_readable($fileInfo['file'])) { $this->error(self::NOT_FOUND); return false; } // limited to 4GB files ErrorHandler::start(); $size = sprintf("%u", filesize($fileInfo['file'])); ErrorHandler::stop(); $this->size = $size; // Check to see if it's smaller than min size $min = $this->getMin(true); $max = $this->getMax(true); if (($min !== null) && ($size < $min)) { if ($this->getByteString()) { $this->options['min'] = $this->toByteString($min); $this->size = $this->toByteString($size); $this->error(self::TOO_SMALL); $this->options['min'] = $min; $this->size = $size; } else { $this->error(self::TOO_SMALL); } } // Check to see if it's larger than max size if (($max !== null) && ($max < $size)) { if ($this->getByteString()) { $this->options['max'] = $this->toByteString($max); $this->size = $this->toByteString($size); $this->error(self::TOO_BIG); $this->options['max'] = $max; $this->size = $size; } else { $this->error(self::TOO_BIG); } } if ($this->getMessages()) { return false; } return true; } /** * Returns the formatted size * * @param int $size * @return string */ protected function toByteString($size) { $sizes = ['B', 'kB', 'MB', 'GB', 'TB', 'PB', 'EB', 'ZB', 'YB']; for ($i = 0; $size >= 1024 && $i < 9; $i++) { $size /= 1024; } return round($size, 2) . $sizes[$i]; } /** * Returns the unformatted size * * @param string $size * @return int */ protected function fromByteString($size) { if (is_numeric($size)) { return (int) $size; } $type = trim(substr($size, -2, 1)); $value = substr($size, 0, -1); if (! is_numeric($value)) { $value = trim(substr($value, 0, -1)); } switch (strtoupper($type)) { case 'Y': $value *= (1024 * 1024 * 1024 * 1024 * 1024 * 1024 * 1024 * 1024); break; case 'Z': $value *= (1024 * 1024 * 1024 * 1024 * 1024 * 1024 * 1024); break; case 'E': $value *= (1024 * 1024 * 1024 * 1024 * 1024 * 1024); break; case 'P': $value *= (1024 * 1024 * 1024 * 1024 * 1024); break; case 'T': $value *= (1024 * 1024 * 1024 * 1024); break; case 'G': $value *= (1024 * 1024 * 1024); break; case 'M': $value *= (1024 * 1024); break; case 'K': $value *= 1024; break; default: break; } return $value; } } ================================================ FILE: src/File/Upload.php ================================================ "File '%value%' exceeds upload_max_filesize directive in php.ini", self::FORM_SIZE => "File '%value%' exceeds the MAX_FILE_SIZE directive that was " . 'specified in the HTML form', self::PARTIAL => "File '%value%' was only partially uploaded", self::NO_FILE => "File '%value%' was not uploaded", self::NO_TMP_DIR => "Missing a temporary folder to store '%value%'", self::CANT_WRITE => "Failed to write file '%value%' to disk", self::EXTENSION => "A PHP extension stopped uploading the file '%value%'", self::ATTACK => "File '%value%' was illegally uploaded. This could be a possible attack", self::FILE_NOT_FOUND => "File '%value%' was not found", self::UNKNOWN => "Unknown error while uploading file '%value%'" ]; protected $options = [ 'files' => [], ]; /** * Sets validator options * * The array $files must be given in syntax of Zend\File\Transfer\Transfer to be checked * If no files are given the $_FILES array will be used automatically. * NOTE: This validator will only work with HTTP POST uploads! * * @param array|\Traversable $options Array of files in syntax of \Zend\File\Transfer\Transfer */ public function __construct($options = []) { if (is_array($options) && ! array_key_exists('files', $options)) { $options = ['files' => $options]; } parent::__construct($options); } /** * Returns the array of set files * * @param string $file (Optional) The file to return in detail * @return array * @throws Exception\InvalidArgumentException If file is not found */ public function getFiles($file = null) { if ($file !== null) { $return = []; foreach ($this->options['files'] as $name => $content) { if ($name === $file) { $return[$file] = $this->options['files'][$name]; } if ($content instanceof UploadedFileInterface) { if ($content->getClientFilename() === $file) { $return[$name] = $this->options['files'][$name]; } } elseif ($content['name'] === $file) { $return[$name] = $this->options['files'][$name]; } } if (! $return) { throw new Exception\InvalidArgumentException("The file '$file' was not found"); } return $return; } return $this->options['files']; } /** * Sets the files to be checked * * @param array $files The files to check in syntax of \Zend\File\Transfer\Transfer * @return Upload Provides a fluent interface */ public function setFiles($files = []) { if (null === $files || ((is_array($files) || $files instanceof Countable) && count($files) === 0) ) { $this->options['files'] = $_FILES; } else { $this->options['files'] = $files; } if ($this->options['files'] === null) { $this->options['files'] = []; } foreach ($this->options['files'] as $file => $content) { if (! $content instanceof UploadedFileInterface && ! isset($content['error']) ) { unset($this->options['files'][$file]); } } return $this; } /** * Returns true if and only if the file was uploaded without errors * * @param string $value Single file to check for upload errors, when giving null the $_FILES array * from initialization will be used * @param mixed $file * @return bool */ public function isValid($value, $file = null) { $files = []; $this->setValue($value); if (array_key_exists($value, $this->getFiles())) { $files = array_merge($files, $this->getFiles($value)); } else { foreach ($this->getFiles() as $file => $content) { if ($content instanceof UploadedFileInterface) { if ($content->getClientFilename() === $value) { $files = array_merge($files, $this->getFiles($file)); } // PSR cannot search by tmp_name because it does not have // a public interface to get it, only user defined name // from form field. continue; } if (isset($content['name']) && ($content['name'] === $value)) { $files = array_merge($files, $this->getFiles($file)); } if (isset($content['tmp_name']) && ($content['tmp_name'] === $value)) { $files = array_merge($files, $this->getFiles($file)); } } } if (empty($files)) { return $this->throwError($file, self::FILE_NOT_FOUND); } foreach ($files as $file => $content) { $this->value = $file; $error = $content instanceof UploadedFileInterface ? $content->getError() : $content['error']; switch ($error) { case 0: if ($content instanceof UploadedFileInterface) { // done! break; } // For standard SAPI environments, check that the upload // was valid if (! is_uploaded_file($content['tmp_name'])) { $this->throwError($content, self::ATTACK); } break; case 1: $this->throwError($content, self::INI_SIZE); break; case 2: $this->throwError($content, self::FORM_SIZE); break; case 3: $this->throwError($content, self::PARTIAL); break; case 4: $this->throwError($content, self::NO_FILE); break; case 6: $this->throwError($content, self::NO_TMP_DIR); break; case 7: $this->throwError($content, self::CANT_WRITE); break; case 8: $this->throwError($content, self::EXTENSION); break; default: $this->throwError($content, self::UNKNOWN); break; } } if ($this->getMessages()) { return false; } return true; } /** * Throws an error of the given type * * @param array|string|UploadedFileInterface $file * @param string $errorType * @return false */ protected function throwError($file, $errorType) { if ($file !== null) { if (is_array($file)) { if (array_key_exists('name', $file)) { $this->value = $file['name']; } } elseif (is_string($file)) { $this->value = $file; } elseif ($file instanceof UploadedFileInterface) { $this->value = $file->getClientFilename(); } } $this->error($errorType); return false; } } ================================================ FILE: src/File/UploadFile.php ================================================ 'The uploaded file exceeds the upload_max_filesize directive in php.ini', self::FORM_SIZE => 'The uploaded file exceeds the MAX_FILE_SIZE directive that was ' . 'specified in the HTML form', self::PARTIAL => 'The uploaded file was only partially uploaded', self::NO_FILE => 'No file was uploaded', self::NO_TMP_DIR => 'Missing a temporary folder', self::CANT_WRITE => 'Failed to write file to disk', self::EXTENSION => 'A PHP extension stopped the file upload', self::ATTACK => 'File was illegally uploaded. This could be a possible attack', self::FILE_NOT_FOUND => 'File was not found', self::UNKNOWN => 'Unknown error while uploading file', ]; /** * Returns true if and only if the file was uploaded without errors * * @param string|array|UploadedFileInterface $value File to check for upload errors * @return bool * @throws Exception\InvalidArgumentException */ public function isValid($value) { if (is_array($value)) { if (! isset($value['tmp_name']) || ! isset($value['name']) || ! isset($value['error'])) { throw new Exception\InvalidArgumentException( 'Value array must be in $_FILES format' ); } return $this->validateUploadedFile( $value['error'], $value['name'], $value['tmp_name'] ); } if ($value instanceof UploadedFileInterface) { return $this->validatePsr7UploadedFile($value); } if (is_string($value)) { return $this->validateUploadedFile(0, basename($value), $value); } $this->error(self::UNKNOWN); return false; } /** * @param int $error UPLOAD_ERR_* constant value * @return bool */ private function validateFileFromErrorCode($error) { switch ($error) { case UPLOAD_ERR_OK: return true; case UPLOAD_ERR_INI_SIZE: $this->error(self::INI_SIZE); return false; case UPLOAD_ERR_FORM_SIZE: $this->error(self::FORM_SIZE); return false; case UPLOAD_ERR_PARTIAL: $this->error(self::PARTIAL); return false; case UPLOAD_ERR_NO_FILE: $this->error(self::NO_FILE); return false; case UPLOAD_ERR_NO_TMP_DIR: $this->error(self::NO_TMP_DIR); return false; case UPLOAD_ERR_CANT_WRITE: $this->error(self::CANT_WRITE); return false; case UPLOAD_ERR_EXTENSION: $this->error(self::EXTENSION); return false; default: $this->error(self::UNKNOWN); return false; } } /** * @param int $error UPLOAD_ERR_* constant * @param string $filename * @param string $uploadedFile Name of uploaded file (gen tmp_name) * @return bool */ private function validateUploadedFile($error, $filename, $uploadedFile) { $this->setValue($filename); // Normal errors can be validated normally if ($error !== UPLOAD_ERR_OK) { return $this->validateFileFromErrorCode($error); } // Did we get no name? Is the file missing? if (empty($uploadedFile) || false === is_file($uploadedFile)) { $this->error(self::FILE_NOT_FOUND); return false; } // Do we have an invalid upload? if (! is_uploaded_file($uploadedFile)) { $this->error(self::ATTACK); return false; } return true; } /** * @return bool */ private function validatePsr7UploadedFile(UploadedFileInterface $uploadedFile) { $this->setValue($uploadedFile); return $this->validateFileFromErrorCode($uploadedFile->getError()); } } ================================================ FILE: src/File/WordCount.php ================================================ "Too many words, maximum '%max%' are allowed but '%count%' were counted", self::TOO_LESS => "Too few words, minimum '%min%' are expected but '%count%' were counted", self::NOT_FOUND => "File is not readable or does not exist", ]; /** * @var array Error message template variables */ protected $messageVariables = [ 'min' => ['options' => 'min'], 'max' => ['options' => 'max'], 'count' => 'count' ]; /** * Word count * * @var int */ protected $count; /** * Options for this validator * * @var array */ protected $options = [ 'min' => null, // Minimum word count, if null there is no minimum word count 'max' => null, // Maximum word count, if null there is no maximum word count ]; /** * Sets validator options * * Min limits the word count, when used with max=null it is the maximum word count * It also accepts an array with the keys 'min' and 'max' * * If $options is an integer, it will be used as maximum word count * As Array is accepts the following keys: * 'min': Minimum word count * 'max': Maximum word count * * @param int|array|\Traversable $options Options for the adapter */ public function __construct($options = null) { if (1 < func_num_args()) { $args = func_get_args(); $options = [ 'min' => array_shift($args), 'max' => array_shift($args), ]; } if (is_string($options) || is_numeric($options)) { $options = ['max' => $options]; } parent::__construct($options); } /** * Returns the minimum word count * * @return int */ public function getMin() { return $this->options['min']; } /** * Sets the minimum word count * * @param int|array $min The minimum word count * @throws Exception\InvalidArgumentException When min is greater than max * @return self Provides a fluent interface */ public function setMin($min) { if (is_array($min) and isset($min['min'])) { $min = $min['min']; } if (! is_numeric($min)) { throw new Exception\InvalidArgumentException('Invalid options to validator provided'); } $min = (int) $min; if (($this->getMax() !== null) && ($min > $this->getMax())) { throw new Exception\InvalidArgumentException( "The minimum must be less than or equal to the maximum word count, but $min > {$this->getMax()}" ); } $this->options['min'] = $min; return $this; } /** * Returns the maximum word count * * @return int */ public function getMax() { return $this->options['max']; } /** * Sets the maximum file count * * @param int|array $max The maximum word count * @throws Exception\InvalidArgumentException When max is smaller than min * @return self Provides a fluent interface */ public function setMax($max) { if (is_array($max) and isset($max['max'])) { $max = $max['max']; } if (! is_numeric($max)) { throw new Exception\InvalidArgumentException('Invalid options to validator provided'); } $max = (int) $max; if (($this->getMin() !== null) && ($max < $this->getMin())) { throw new Exception\InvalidArgumentException( "The maximum must be greater than or equal to the minimum word count, but $max < {$this->getMin()}" ); } $this->options['max'] = $max; return $this; } /** * Returns true if and only if the counted words are at least min and * not bigger than max (when max is not null). * * @param string|array $value Filename to check for word count * @param array $file File data from \Zend\File\Transfer\Transfer (optional) * @return bool */ public function isValid($value, $file = null) { $fileInfo = $this->getFileInfo($value, $file); $this->setValue($fileInfo['filename']); // Is file readable ? if (empty($fileInfo['file']) || false === is_readable($fileInfo['file'])) { $this->error(self::NOT_FOUND); return false; } $content = file_get_contents($fileInfo['file']); $this->count = str_word_count($content); if (($this->getMax() !== null) && ($this->count > $this->getMax())) { $this->error(self::TOO_MUCH); return false; } if (($this->getMin() !== null) && ($this->count < $this->getMin())) { $this->error(self::TOO_LESS); return false; } return true; } } ================================================ FILE: src/GpsPoint.php ================================================ '%value% is out of Bounds.', 'gpsPointConvertError' => '%value% can not converted into a Decimal Degree Value.', 'gpsPointIncompleteCoordinate' => '%value% did not provided a complete Coordinate', ]; /** * Returns true if and only if $value meets the validation requirements * * If $value fails validation, then this method returns false, and * getMessages() will return an array of messages that explain why the * validation failed. * * @param mixed $value * @return bool * @throws Exception\RuntimeException If validation of $value is impossible */ public function isValid($value) { if (strpos($value, ',') === false) { $this->error(GpsPoint::INCOMPLETE_COORDINATE, $value); return false; } list($lat, $long) = explode(',', $value); if ($this->isValidCoordinate($lat, 90.0000) && $this->isValidCoordinate($long, 180.000)) { return true; } return false; } /** * @param string $value * @param $maxBoundary * @return bool */ private function isValidCoordinate($value, $maxBoundary) { $this->value = $value; $value = $this->removeWhiteSpace($value); if ($this->isDMSValue($value)) { $value = $this->convertValue($value); } else { $value = $this->removeDegreeSign($value); } if ($value === false || $value === null) { $this->error(self::CONVERT_ERROR); return false; } $doubleLatitude = (double)$value; if ($doubleLatitude <= $maxBoundary && $doubleLatitude >= $maxBoundary * -1) { return true; } $this->error(self::OUT_OF_BOUNDS); return false; } /** * Determines if the give value is a Degrees Minutes Second Definition * * @param $value * @return bool */ private function isDMSValue($value) { return preg_match('/([°\'"]+[NESW])/', $value) > 0; } /** * @param string $value * @return bool|string */ private function convertValue($value) { $matches = []; $result = preg_match_all('/(\d{1,3})°(\d{1,2})\'(\d{1,2}[\.\d]{0,6})"[NESW]/i', $value, $matches); if ($result === false || $result === 0) { return false; } return $matches[1][0] + $matches[2][0] / 60 + ((double)$matches[3][0]) / 3600; } /** * @param string $value * @return string */ private function removeWhiteSpace($value) { return preg_replace('/\s/', '', $value); } /** * @param string $value * @return string */ private function removeDegreeSign($value) { return str_replace('°', '', $value); } } ================================================ FILE: src/GreaterThan.php ================================================ "The input is not greater than '%min%'", self::NOT_GREATER_INCLUSIVE => "The input is not greater than or equal to '%min%'" ]; /** * @var array */ protected $messageVariables = [ 'min' => 'min' ]; /** * Minimum value * * @var mixed */ protected $min; /** * Whether to do inclusive comparisons, allowing equivalence to max * * If false, then strict comparisons are done, and the value may equal * the min option * * @var bool */ protected $inclusive; /** * Sets validator options * * @param array|Traversable $options * @throws Exception\InvalidArgumentException */ public function __construct($options = null) { if ($options instanceof Traversable) { $options = ArrayUtils::iteratorToArray($options); } if (! is_array($options)) { $options = func_get_args(); $temp['min'] = array_shift($options); if (! empty($options)) { $temp['inclusive'] = array_shift($options); } $options = $temp; } if (! array_key_exists('min', $options)) { throw new Exception\InvalidArgumentException("Missing option 'min'"); } if (! array_key_exists('inclusive', $options)) { $options['inclusive'] = false; } $this->setMin($options['min']) ->setInclusive($options['inclusive']); parent::__construct($options); } /** * Returns the min option * * @return mixed */ public function getMin() { return $this->min; } /** * Sets the min option * * @param mixed $min * @return GreaterThan Provides a fluent interface */ public function setMin($min) { $this->min = $min; return $this; } /** * Returns the inclusive option * * @return bool */ public function getInclusive() { return $this->inclusive; } /** * Sets the inclusive option * * @param bool $inclusive * @return GreaterThan Provides a fluent interface */ public function setInclusive($inclusive) { $this->inclusive = $inclusive; return $this; } /** * Returns true if and only if $value is greater than min option * * @param mixed $value * @return bool */ public function isValid($value) { $this->setValue($value); if ($this->inclusive) { if ($this->min > $value) { $this->error(self::NOT_GREATER_INCLUSIVE); return false; } } else { if ($this->min >= $value) { $this->error(self::NOT_GREATER); return false; } } return true; } } ================================================ FILE: src/Hex.php ================================================ "Invalid type given. String expected", self::NOT_HEX => "The input contains non-hexadecimal characters", ]; /** * Returns true if and only if $value contains only hexadecimal digit characters * * @param string $value * @return bool */ public function isValid($value) { if (! is_string($value) && ! is_int($value)) { $this->error(self::INVALID); return false; } $this->setValue($value); if (! ctype_xdigit((string) $value)) { $this->error(self::NOT_HEX); return false; } return true; } } ================================================ FILE: src/Hostname/Biz.php ================================================ '/^[\x{002d}0-9a-zäåæéöøü]{1,63}$/iu', 2 => '/^[\x{002d}0-9a-záéíñóúü]{1,63}$/iu', 3 => '/^[\x{002d}0-9a-záéíóöúüőű]{1,63}$/iu', 4 => '/^[\x{002d}0-9a-záæéíðóöúýþ]{1,63}$/iu', 5 => '/^[\x{AC00}-\x{D7A3}]{1,17}$/iu', 6 => '/^[\x{002d}0-9a-ząčėęįšūųž]{1,63}$/iu', 7 => '/^[\x{002d}0-9a-zāčēģīķļņōŗšūž]{1,63}$/iu', 8 => '/^[\x{002d}0-9a-zàáä-éêñ-ôöøüčđńŋšŧž]{1,63}$/iu', 9 => '/^[\x{002d}0-9a-zóąćęłńśźż]{1,63}$/iu', 10 => '/^[\x{002d}0-9a-záàâãçéêíóôõú]{1,63}$/iu', 11 => '/^[\x{002d}0-9a-z\x{3005}-\x{3007}\x{3041}-\x{3093}\x{309D}\x{309E}\x{30A1}-\x{30F6}\x{30FC}' . '\x{30FD}\x{30FE}\x{4E00}\x{4E01}\x{4E03}\x{4E07}\x{4E08}\x{4E09}\x{4E0A}' . '\x{4E0B}\x{4E0D}\x{4E0E}\x{4E10}\x{4E11}\x{4E14}\x{4E15}\x{4E16}\x{4E17}' . '\x{4E18}\x{4E19}\x{4E1E}\x{4E21}\x{4E26}\x{4E2A}\x{4E2D}\x{4E31}\x{4E32}' . '\x{4E36}\x{4E38}\x{4E39}\x{4E3B}\x{4E3C}\x{4E3F}\x{4E42}\x{4E43}\x{4E45}' . '\x{4E4B}\x{4E4D}\x{4E4E}\x{4E4F}\x{4E55}\x{4E56}\x{4E57}\x{4E58}\x{4E59}' . '\x{4E5D}\x{4E5E}\x{4E5F}\x{4E62}\x{4E71}\x{4E73}\x{4E7E}\x{4E80}\x{4E82}' . '\x{4E85}\x{4E86}\x{4E88}\x{4E89}\x{4E8A}\x{4E8B}\x{4E8C}\x{4E8E}\x{4E91}' . '\x{4E92}\x{4E94}\x{4E95}\x{4E98}\x{4E99}\x{4E9B}\x{4E9C}\x{4E9E}\x{4E9F}' . '\x{4EA0}\x{4EA1}\x{4EA2}\x{4EA4}\x{4EA5}\x{4EA6}\x{4EA8}\x{4EAB}\x{4EAC}' . '\x{4EAD}\x{4EAE}\x{4EB0}\x{4EB3}\x{4EB6}\x{4EBA}\x{4EC0}\x{4EC1}\x{4EC2}' . '\x{4EC4}\x{4EC6}\x{4EC7}\x{4ECA}\x{4ECB}\x{4ECD}\x{4ECE}\x{4ECF}\x{4ED4}' . '\x{4ED5}\x{4ED6}\x{4ED7}\x{4ED8}\x{4ED9}\x{4EDD}\x{4EDE}\x{4EDF}\x{4EE3}' . '\x{4EE4}\x{4EE5}\x{4EED}\x{4EEE}\x{4EF0}\x{4EF2}\x{4EF6}\x{4EF7}\x{4EFB}' . '\x{4F01}\x{4F09}\x{4F0A}\x{4F0D}\x{4F0E}\x{4F0F}\x{4F10}\x{4F11}\x{4F1A}' . '\x{4F1C}\x{4F1D}\x{4F2F}\x{4F30}\x{4F34}\x{4F36}\x{4F38}\x{4F3A}\x{4F3C}' . '\x{4F3D}\x{4F43}\x{4F46}\x{4F47}\x{4F4D}\x{4F4E}\x{4F4F}\x{4F50}\x{4F51}' . '\x{4F53}\x{4F55}\x{4F57}\x{4F59}\x{4F5A}\x{4F5B}\x{4F5C}\x{4F5D}\x{4F5E}' . '\x{4F69}\x{4F6F}\x{4F70}\x{4F73}\x{4F75}\x{4F76}\x{4F7B}\x{4F7C}\x{4F7F}' . '\x{4F83}\x{4F86}\x{4F88}\x{4F8B}\x{4F8D}\x{4F8F}\x{4F91}\x{4F96}\x{4F98}' . '\x{4F9B}\x{4F9D}\x{4FA0}\x{4FA1}\x{4FAB}\x{4FAD}\x{4FAE}\x{4FAF}\x{4FB5}' . '\x{4FB6}\x{4FBF}\x{4FC2}\x{4FC3}\x{4FC4}\x{4FCA}\x{4FCE}\x{4FD0}\x{4FD1}' . '\x{4FD4}\x{4FD7}\x{4FD8}\x{4FDA}\x{4FDB}\x{4FDD}\x{4FDF}\x{4FE1}\x{4FE3}' . '\x{4FE4}\x{4FE5}\x{4FEE}\x{4FEF}\x{4FF3}\x{4FF5}\x{4FF6}\x{4FF8}\x{4FFA}' . '\x{4FFE}\x{5005}\x{5006}\x{5009}\x{500B}\x{500D}\x{500F}\x{5011}\x{5012}' . '\x{5014}\x{5016}\x{5019}\x{501A}\x{501F}\x{5021}\x{5023}\x{5024}\x{5025}' . '\x{5026}\x{5028}\x{5029}\x{502A}\x{502B}\x{502C}\x{502D}\x{5036}\x{5039}' . '\x{5043}\x{5047}\x{5048}\x{5049}\x{504F}\x{5050}\x{5055}\x{5056}\x{505A}' . '\x{505C}\x{5065}\x{506C}\x{5072}\x{5074}\x{5075}\x{5076}\x{5078}\x{507D}' . '\x{5080}\x{5085}\x{508D}\x{5091}\x{5098}\x{5099}\x{509A}\x{50AC}\x{50AD}' . '\x{50B2}\x{50B3}\x{50B4}\x{50B5}\x{50B7}\x{50BE}\x{50C2}\x{50C5}\x{50C9}' . '\x{50CA}\x{50CD}\x{50CF}\x{50D1}\x{50D5}\x{50D6}\x{50DA}\x{50DE}\x{50E3}' . '\x{50E5}\x{50E7}\x{50ED}\x{50EE}\x{50F5}\x{50F9}\x{50FB}\x{5100}\x{5101}' . '\x{5102}\x{5104}\x{5109}\x{5112}\x{5114}\x{5115}\x{5116}\x{5118}\x{511A}' . '\x{511F}\x{5121}\x{512A}\x{5132}\x{5137}\x{513A}\x{513B}\x{513C}\x{513F}' . '\x{5140}\x{5141}\x{5143}\x{5144}\x{5145}\x{5146}\x{5147}\x{5148}\x{5149}' . '\x{514B}\x{514C}\x{514D}\x{514E}\x{5150}\x{5152}\x{5154}\x{515A}\x{515C}' . '\x{5162}\x{5165}\x{5168}\x{5169}\x{516A}\x{516B}\x{516C}\x{516D}\x{516E}' . '\x{5171}\x{5175}\x{5176}\x{5177}\x{5178}\x{517C}\x{5180}\x{5182}\x{5185}' . '\x{5186}\x{5189}\x{518A}\x{518C}\x{518D}\x{518F}\x{5190}\x{5191}\x{5192}' . '\x{5193}\x{5195}\x{5196}\x{5197}\x{5199}\x{51A0}\x{51A2}\x{51A4}\x{51A5}' . '\x{51A6}\x{51A8}\x{51A9}\x{51AA}\x{51AB}\x{51AC}\x{51B0}\x{51B1}\x{51B2}' . '\x{51B3}\x{51B4}\x{51B5}\x{51B6}\x{51B7}\x{51BD}\x{51C4}\x{51C5}\x{51C6}' . '\x{51C9}\x{51CB}\x{51CC}\x{51CD}\x{51D6}\x{51DB}\x{51DC}\x{51DD}\x{51E0}' . '\x{51E1}\x{51E6}\x{51E7}\x{51E9}\x{51EA}\x{51ED}\x{51F0}\x{51F1}\x{51F5}' . '\x{51F6}\x{51F8}\x{51F9}\x{51FA}\x{51FD}\x{51FE}\x{5200}\x{5203}\x{5204}' . '\x{5206}\x{5207}\x{5208}\x{520A}\x{520B}\x{520E}\x{5211}\x{5214}\x{5217}' . '\x{521D}\x{5224}\x{5225}\x{5227}\x{5229}\x{522A}\x{522E}\x{5230}\x{5233}' . '\x{5236}\x{5237}\x{5238}\x{5239}\x{523A}\x{523B}\x{5243}\x{5244}\x{5247}' . '\x{524A}\x{524B}\x{524C}\x{524D}\x{524F}\x{5254}\x{5256}\x{525B}\x{525E}' . '\x{5263}\x{5264}\x{5265}\x{5269}\x{526A}\x{526F}\x{5270}\x{5271}\x{5272}' . '\x{5273}\x{5274}\x{5275}\x{527D}\x{527F}\x{5283}\x{5287}\x{5288}\x{5289}' . '\x{528D}\x{5291}\x{5292}\x{5294}\x{529B}\x{529F}\x{52A0}\x{52A3}\x{52A9}' . '\x{52AA}\x{52AB}\x{52AC}\x{52AD}\x{52B1}\x{52B4}\x{52B5}\x{52B9}\x{52BC}' . '\x{52BE}\x{52C1}\x{52C3}\x{52C5}\x{52C7}\x{52C9}\x{52CD}\x{52D2}\x{52D5}' . '\x{52D7}\x{52D8}\x{52D9}\x{52DD}\x{52DE}\x{52DF}\x{52E0}\x{52E2}\x{52E3}' . '\x{52E4}\x{52E6}\x{52E7}\x{52F2}\x{52F3}\x{52F5}\x{52F8}\x{52F9}\x{52FA}' . '\x{52FE}\x{52FF}\x{5301}\x{5302}\x{5305}\x{5306}\x{5308}\x{530D}\x{530F}' . '\x{5310}\x{5315}\x{5316}\x{5317}\x{5319}\x{531A}\x{531D}\x{5320}\x{5321}' . '\x{5323}\x{532A}\x{532F}\x{5331}\x{5333}\x{5338}\x{5339}\x{533A}\x{533B}' . '\x{533F}\x{5340}\x{5341}\x{5343}\x{5345}\x{5346}\x{5347}\x{5348}\x{5349}' . '\x{534A}\x{534D}\x{5351}\x{5352}\x{5353}\x{5354}\x{5357}\x{5358}\x{535A}' . '\x{535C}\x{535E}\x{5360}\x{5366}\x{5369}\x{536E}\x{536F}\x{5370}\x{5371}' . '\x{5373}\x{5374}\x{5375}\x{5377}\x{5378}\x{537B}\x{537F}\x{5382}\x{5384}' . '\x{5396}\x{5398}\x{539A}\x{539F}\x{53A0}\x{53A5}\x{53A6}\x{53A8}\x{53A9}' . '\x{53AD}\x{53AE}\x{53B0}\x{53B3}\x{53B6}\x{53BB}\x{53C2}\x{53C3}\x{53C8}' . '\x{53C9}\x{53CA}\x{53CB}\x{53CC}\x{53CD}\x{53CE}\x{53D4}\x{53D6}\x{53D7}' . '\x{53D9}\x{53DB}\x{53DF}\x{53E1}\x{53E2}\x{53E3}\x{53E4}\x{53E5}\x{53E8}' . '\x{53E9}\x{53EA}\x{53EB}\x{53EC}\x{53ED}\x{53EE}\x{53EF}\x{53F0}\x{53F1}' . '\x{53F2}\x{53F3}\x{53F6}\x{53F7}\x{53F8}\x{53FA}\x{5401}\x{5403}\x{5404}' . '\x{5408}\x{5409}\x{540A}\x{540B}\x{540C}\x{540D}\x{540E}\x{540F}\x{5410}' . '\x{5411}\x{541B}\x{541D}\x{541F}\x{5420}\x{5426}\x{5429}\x{542B}\x{542C}' . '\x{542D}\x{542E}\x{5436}\x{5438}\x{5439}\x{543B}\x{543C}\x{543D}\x{543E}' . '\x{5440}\x{5442}\x{5446}\x{5448}\x{5449}\x{544A}\x{544E}\x{5451}\x{545F}' . '\x{5468}\x{546A}\x{5470}\x{5471}\x{5473}\x{5475}\x{5476}\x{5477}\x{547B}' . '\x{547C}\x{547D}\x{5480}\x{5484}\x{5486}\x{548B}\x{548C}\x{548E}\x{548F}' . '\x{5490}\x{5492}\x{54A2}\x{54A4}\x{54A5}\x{54A8}\x{54AB}\x{54AC}\x{54AF}' . '\x{54B2}\x{54B3}\x{54B8}\x{54BC}\x{54BD}\x{54BE}\x{54C0}\x{54C1}\x{54C2}' . '\x{54C4}\x{54C7}\x{54C8}\x{54C9}\x{54D8}\x{54E1}\x{54E2}\x{54E5}\x{54E6}' . '\x{54E8}\x{54E9}\x{54ED}\x{54EE}\x{54F2}\x{54FA}\x{54FD}\x{5504}\x{5506}' . '\x{5507}\x{550F}\x{5510}\x{5514}\x{5516}\x{552E}\x{552F}\x{5531}\x{5533}' . '\x{5538}\x{5539}\x{553E}\x{5540}\x{5544}\x{5545}\x{5546}\x{554C}\x{554F}' . '\x{5553}\x{5556}\x{5557}\x{555C}\x{555D}\x{5563}\x{557B}\x{557C}\x{557E}' . '\x{5580}\x{5583}\x{5584}\x{5587}\x{5589}\x{558A}\x{558B}\x{5598}\x{5599}' . '\x{559A}\x{559C}\x{559D}\x{559E}\x{559F}\x{55A7}\x{55A8}\x{55A9}\x{55AA}' . '\x{55AB}\x{55AC}\x{55AE}\x{55B0}\x{55B6}\x{55C4}\x{55C5}\x{55C7}\x{55D4}' . '\x{55DA}\x{55DC}\x{55DF}\x{55E3}\x{55E4}\x{55F7}\x{55F9}\x{55FD}\x{55FE}' . '\x{5606}\x{5609}\x{5614}\x{5616}\x{5617}\x{5618}\x{561B}\x{5629}\x{562F}' . '\x{5631}\x{5632}\x{5634}\x{5636}\x{5638}\x{5642}\x{564C}\x{564E}\x{5650}' . '\x{565B}\x{5664}\x{5668}\x{566A}\x{566B}\x{566C}\x{5674}\x{5678}\x{567A}' . '\x{5680}\x{5686}\x{5687}\x{568A}\x{568F}\x{5694}\x{56A0}\x{56A2}\x{56A5}' . '\x{56AE}\x{56B4}\x{56B6}\x{56BC}\x{56C0}\x{56C1}\x{56C2}\x{56C3}\x{56C8}' . '\x{56CE}\x{56D1}\x{56D3}\x{56D7}\x{56D8}\x{56DA}\x{56DB}\x{56DE}\x{56E0}' . '\x{56E3}\x{56EE}\x{56F0}\x{56F2}\x{56F3}\x{56F9}\x{56FA}\x{56FD}\x{56FF}' . '\x{5700}\x{5703}\x{5704}\x{5708}\x{5709}\x{570B}\x{570D}\x{570F}\x{5712}' . '\x{5713}\x{5716}\x{5718}\x{571C}\x{571F}\x{5726}\x{5727}\x{5728}\x{572D}' . '\x{5730}\x{5737}\x{5738}\x{573B}\x{5740}\x{5742}\x{5747}\x{574A}\x{574E}' . '\x{574F}\x{5750}\x{5751}\x{5761}\x{5764}\x{5766}\x{5769}\x{576A}\x{577F}' . '\x{5782}\x{5788}\x{5789}\x{578B}\x{5793}\x{57A0}\x{57A2}\x{57A3}\x{57A4}' . '\x{57AA}\x{57B0}\x{57B3}\x{57C0}\x{57C3}\x{57C6}\x{57CB}\x{57CE}\x{57D2}' . '\x{57D3}\x{57D4}\x{57D6}\x{57DC}\x{57DF}\x{57E0}\x{57E3}\x{57F4}\x{57F7}' . '\x{57F9}\x{57FA}\x{57FC}\x{5800}\x{5802}\x{5805}\x{5806}\x{580A}\x{580B}' . '\x{5815}\x{5819}\x{581D}\x{5821}\x{5824}\x{582A}\x{582F}\x{5830}\x{5831}' . '\x{5834}\x{5835}\x{583A}\x{583D}\x{5840}\x{5841}\x{584A}\x{584B}\x{5851}' . '\x{5852}\x{5854}\x{5857}\x{5858}\x{5859}\x{585A}\x{585E}\x{5862}\x{5869}' . '\x{586B}\x{5870}\x{5872}\x{5875}\x{5879}\x{587E}\x{5883}\x{5885}\x{5893}' . '\x{5897}\x{589C}\x{589F}\x{58A8}\x{58AB}\x{58AE}\x{58B3}\x{58B8}\x{58B9}' . '\x{58BA}\x{58BB}\x{58BE}\x{58C1}\x{58C5}\x{58C7}\x{58CA}\x{58CC}\x{58D1}' . '\x{58D3}\x{58D5}\x{58D7}\x{58D8}\x{58D9}\x{58DC}\x{58DE}\x{58DF}\x{58E4}' . '\x{58E5}\x{58EB}\x{58EC}\x{58EE}\x{58EF}\x{58F0}\x{58F1}\x{58F2}\x{58F7}' . '\x{58F9}\x{58FA}\x{58FB}\x{58FC}\x{58FD}\x{5902}\x{5909}\x{590A}\x{590F}' . '\x{5910}\x{5915}\x{5916}\x{5918}\x{5919}\x{591A}\x{591B}\x{591C}\x{5922}' . '\x{5925}\x{5927}\x{5929}\x{592A}\x{592B}\x{592C}\x{592D}\x{592E}\x{5931}' . '\x{5932}\x{5937}\x{5938}\x{593E}\x{5944}\x{5947}\x{5948}\x{5949}\x{594E}' . '\x{594F}\x{5950}\x{5951}\x{5954}\x{5955}\x{5957}\x{5958}\x{595A}\x{5960}' . '\x{5962}\x{5965}\x{5967}\x{5968}\x{5969}\x{596A}\x{596C}\x{596E}\x{5973}' . '\x{5974}\x{5978}\x{597D}\x{5981}\x{5982}\x{5983}\x{5984}\x{598A}\x{598D}' . '\x{5993}\x{5996}\x{5999}\x{599B}\x{599D}\x{59A3}\x{59A5}\x{59A8}\x{59AC}' . '\x{59B2}\x{59B9}\x{59BB}\x{59BE}\x{59C6}\x{59C9}\x{59CB}\x{59D0}\x{59D1}' . '\x{59D3}\x{59D4}\x{59D9}\x{59DA}\x{59DC}\x{59E5}\x{59E6}\x{59E8}\x{59EA}' . '\x{59EB}\x{59F6}\x{59FB}\x{59FF}\x{5A01}\x{5A03}\x{5A09}\x{5A11}\x{5A18}' . '\x{5A1A}\x{5A1C}\x{5A1F}\x{5A20}\x{5A25}\x{5A29}\x{5A2F}\x{5A35}\x{5A36}' . '\x{5A3C}\x{5A40}\x{5A41}\x{5A46}\x{5A49}\x{5A5A}\x{5A62}\x{5A66}\x{5A6A}' . '\x{5A6C}\x{5A7F}\x{5A92}\x{5A9A}\x{5A9B}\x{5ABC}\x{5ABD}\x{5ABE}\x{5AC1}' . '\x{5AC2}\x{5AC9}\x{5ACB}\x{5ACC}\x{5AD0}\x{5AD6}\x{5AD7}\x{5AE1}\x{5AE3}' . '\x{5AE6}\x{5AE9}\x{5AFA}\x{5AFB}\x{5B09}\x{5B0B}\x{5B0C}\x{5B16}\x{5B22}' . '\x{5B2A}\x{5B2C}\x{5B30}\x{5B32}\x{5B36}\x{5B3E}\x{5B40}\x{5B43}\x{5B45}' . '\x{5B50}\x{5B51}\x{5B54}\x{5B55}\x{5B57}\x{5B58}\x{5B5A}\x{5B5B}\x{5B5C}' . '\x{5B5D}\x{5B5F}\x{5B63}\x{5B64}\x{5B65}\x{5B66}\x{5B69}\x{5B6B}\x{5B70}' . '\x{5B71}\x{5B73}\x{5B75}\x{5B78}\x{5B7A}\x{5B80}\x{5B83}\x{5B85}\x{5B87}' . '\x{5B88}\x{5B89}\x{5B8B}\x{5B8C}\x{5B8D}\x{5B8F}\x{5B95}\x{5B97}\x{5B98}' . '\x{5B99}\x{5B9A}\x{5B9B}\x{5B9C}\x{5B9D}\x{5B9F}\x{5BA2}\x{5BA3}\x{5BA4}' . '\x{5BA5}\x{5BA6}\x{5BAE}\x{5BB0}\x{5BB3}\x{5BB4}\x{5BB5}\x{5BB6}\x{5BB8}' . '\x{5BB9}\x{5BBF}\x{5BC2}\x{5BC3}\x{5BC4}\x{5BC5}\x{5BC6}\x{5BC7}\x{5BC9}' . '\x{5BCC}\x{5BD0}\x{5BD2}\x{5BD3}\x{5BD4}\x{5BDB}\x{5BDD}\x{5BDE}\x{5BDF}' . '\x{5BE1}\x{5BE2}\x{5BE4}\x{5BE5}\x{5BE6}\x{5BE7}\x{5BE8}\x{5BE9}\x{5BEB}' . '\x{5BEE}\x{5BF0}\x{5BF3}\x{5BF5}\x{5BF6}\x{5BF8}\x{5BFA}\x{5BFE}\x{5BFF}' . '\x{5C01}\x{5C02}\x{5C04}\x{5C05}\x{5C06}\x{5C07}\x{5C08}\x{5C09}\x{5C0A}' . '\x{5C0B}\x{5C0D}\x{5C0E}\x{5C0F}\x{5C11}\x{5C13}\x{5C16}\x{5C1A}\x{5C20}' . '\x{5C22}\x{5C24}\x{5C28}\x{5C2D}\x{5C31}\x{5C38}\x{5C39}\x{5C3A}\x{5C3B}' . '\x{5C3C}\x{5C3D}\x{5C3E}\x{5C3F}\x{5C40}\x{5C41}\x{5C45}\x{5C46}\x{5C48}' . '\x{5C4A}\x{5C4B}\x{5C4D}\x{5C4E}\x{5C4F}\x{5C50}\x{5C51}\x{5C53}\x{5C55}' . '\x{5C5E}\x{5C60}\x{5C61}\x{5C64}\x{5C65}\x{5C6C}\x{5C6E}\x{5C6F}\x{5C71}' . '\x{5C76}\x{5C79}\x{5C8C}\x{5C90}\x{5C91}\x{5C94}\x{5CA1}\x{5CA8}\x{5CA9}' . '\x{5CAB}\x{5CAC}\x{5CB1}\x{5CB3}\x{5CB6}\x{5CB7}\x{5CB8}\x{5CBB}\x{5CBC}' . '\x{5CBE}\x{5CC5}\x{5CC7}\x{5CD9}\x{5CE0}\x{5CE1}\x{5CE8}\x{5CE9}\x{5CEA}' . '\x{5CED}\x{5CEF}\x{5CF0}\x{5CF6}\x{5CFA}\x{5CFB}\x{5CFD}\x{5D07}\x{5D0B}' . '\x{5D0E}\x{5D11}\x{5D14}\x{5D15}\x{5D16}\x{5D17}\x{5D18}\x{5D19}\x{5D1A}' . '\x{5D1B}\x{5D1F}\x{5D22}\x{5D29}\x{5D4B}\x{5D4C}\x{5D4E}\x{5D50}\x{5D52}' . '\x{5D5C}\x{5D69}\x{5D6C}\x{5D6F}\x{5D73}\x{5D76}\x{5D82}\x{5D84}\x{5D87}' . '\x{5D8B}\x{5D8C}\x{5D90}\x{5D9D}\x{5DA2}\x{5DAC}\x{5DAE}\x{5DB7}\x{5DBA}' . '\x{5DBC}\x{5DBD}\x{5DC9}\x{5DCC}\x{5DCD}\x{5DD2}\x{5DD3}\x{5DD6}\x{5DDB}' . '\x{5DDD}\x{5DDE}\x{5DE1}\x{5DE3}\x{5DE5}\x{5DE6}\x{5DE7}\x{5DE8}\x{5DEB}' . '\x{5DEE}\x{5DF1}\x{5DF2}\x{5DF3}\x{5DF4}\x{5DF5}\x{5DF7}\x{5DFB}\x{5DFD}' . '\x{5DFE}\x{5E02}\x{5E03}\x{5E06}\x{5E0B}\x{5E0C}\x{5E11}\x{5E16}\x{5E19}' . '\x{5E1A}\x{5E1B}\x{5E1D}\x{5E25}\x{5E2B}\x{5E2D}\x{5E2F}\x{5E30}\x{5E33}' . '\x{5E36}\x{5E37}\x{5E38}\x{5E3D}\x{5E40}\x{5E43}\x{5E44}\x{5E45}\x{5E47}' . '\x{5E4C}\x{5E4E}\x{5E54}\x{5E55}\x{5E57}\x{5E5F}\x{5E61}\x{5E62}\x{5E63}' . '\x{5E64}\x{5E72}\x{5E73}\x{5E74}\x{5E75}\x{5E76}\x{5E78}\x{5E79}\x{5E7A}' . '\x{5E7B}\x{5E7C}\x{5E7D}\x{5E7E}\x{5E7F}\x{5E81}\x{5E83}\x{5E84}\x{5E87}' . '\x{5E8A}\x{5E8F}\x{5E95}\x{5E96}\x{5E97}\x{5E9A}\x{5E9C}\x{5EA0}\x{5EA6}' . '\x{5EA7}\x{5EAB}\x{5EAD}\x{5EB5}\x{5EB6}\x{5EB7}\x{5EB8}\x{5EC1}\x{5EC2}' . '\x{5EC3}\x{5EC8}\x{5EC9}\x{5ECA}\x{5ECF}\x{5ED0}\x{5ED3}\x{5ED6}\x{5EDA}' . '\x{5EDB}\x{5EDD}\x{5EDF}\x{5EE0}\x{5EE1}\x{5EE2}\x{5EE3}\x{5EE8}\x{5EE9}' . '\x{5EEC}\x{5EF0}\x{5EF1}\x{5EF3}\x{5EF4}\x{5EF6}\x{5EF7}\x{5EF8}\x{5EFA}' . '\x{5EFB}\x{5EFC}\x{5EFE}\x{5EFF}\x{5F01}\x{5F03}\x{5F04}\x{5F09}\x{5F0A}' . '\x{5F0B}\x{5F0C}\x{5F0D}\x{5F0F}\x{5F10}\x{5F11}\x{5F13}\x{5F14}\x{5F15}' . '\x{5F16}\x{5F17}\x{5F18}\x{5F1B}\x{5F1F}\x{5F25}\x{5F26}\x{5F27}\x{5F29}' . '\x{5F2D}\x{5F2F}\x{5F31}\x{5F35}\x{5F37}\x{5F38}\x{5F3C}\x{5F3E}\x{5F41}' . '\x{5F48}\x{5F4A}\x{5F4C}\x{5F4E}\x{5F51}\x{5F53}\x{5F56}\x{5F57}\x{5F59}' . '\x{5F5C}\x{5F5D}\x{5F61}\x{5F62}\x{5F66}\x{5F69}\x{5F6A}\x{5F6B}\x{5F6C}' . '\x{5F6D}\x{5F70}\x{5F71}\x{5F73}\x{5F77}\x{5F79}\x{5F7C}\x{5F7F}\x{5F80}' . '\x{5F81}\x{5F82}\x{5F83}\x{5F84}\x{5F85}\x{5F87}\x{5F88}\x{5F8A}\x{5F8B}' . '\x{5F8C}\x{5F90}\x{5F91}\x{5F92}\x{5F93}\x{5F97}\x{5F98}\x{5F99}\x{5F9E}' . '\x{5FA0}\x{5FA1}\x{5FA8}\x{5FA9}\x{5FAA}\x{5FAD}\x{5FAE}\x{5FB3}\x{5FB4}' . '\x{5FB9}\x{5FBC}\x{5FBD}\x{5FC3}\x{5FC5}\x{5FCC}\x{5FCD}\x{5FD6}\x{5FD7}' . '\x{5FD8}\x{5FD9}\x{5FDC}\x{5FDD}\x{5FE0}\x{5FE4}\x{5FEB}\x{5FF0}\x{5FF1}' . '\x{5FF5}\x{5FF8}\x{5FFB}\x{5FFD}\x{5FFF}\x{600E}\x{600F}\x{6010}\x{6012}' . '\x{6015}\x{6016}\x{6019}\x{601B}\x{601C}\x{601D}\x{6020}\x{6021}\x{6025}' . '\x{6026}\x{6027}\x{6028}\x{6029}\x{602A}\x{602B}\x{602F}\x{6031}\x{603A}' . '\x{6041}\x{6042}\x{6043}\x{6046}\x{604A}\x{604B}\x{604D}\x{6050}\x{6052}' . '\x{6055}\x{6059}\x{605A}\x{605F}\x{6060}\x{6062}\x{6063}\x{6064}\x{6065}' . '\x{6068}\x{6069}\x{606A}\x{606B}\x{606C}\x{606D}\x{606F}\x{6070}\x{6075}' . '\x{6077}\x{6081}\x{6083}\x{6084}\x{6089}\x{608B}\x{608C}\x{608D}\x{6092}' . '\x{6094}\x{6096}\x{6097}\x{609A}\x{609B}\x{609F}\x{60A0}\x{60A3}\x{60A6}' . '\x{60A7}\x{60A9}\x{60AA}\x{60B2}\x{60B3}\x{60B4}\x{60B5}\x{60B6}\x{60B8}' . '\x{60BC}\x{60BD}\x{60C5}\x{60C6}\x{60C7}\x{60D1}\x{60D3}\x{60D8}\x{60DA}' . '\x{60DC}\x{60DF}\x{60E0}\x{60E1}\x{60E3}\x{60E7}\x{60E8}\x{60F0}\x{60F1}' . '\x{60F3}\x{60F4}\x{60F6}\x{60F7}\x{60F9}\x{60FA}\x{60FB}\x{6100}\x{6101}' . '\x{6103}\x{6106}\x{6108}\x{6109}\x{610D}\x{610E}\x{610F}\x{6115}\x{611A}' . '\x{611B}\x{611F}\x{6121}\x{6127}\x{6128}\x{612C}\x{6134}\x{613C}\x{613D}' . '\x{613E}\x{613F}\x{6142}\x{6144}\x{6147}\x{6148}\x{614A}\x{614B}\x{614C}' . '\x{614D}\x{614E}\x{6153}\x{6155}\x{6158}\x{6159}\x{615A}\x{615D}\x{615F}' . '\x{6162}\x{6163}\x{6165}\x{6167}\x{6168}\x{616B}\x{616E}\x{616F}\x{6170}' . '\x{6171}\x{6173}\x{6174}\x{6175}\x{6176}\x{6177}\x{617E}\x{6182}\x{6187}' . '\x{618A}\x{618E}\x{6190}\x{6191}\x{6194}\x{6196}\x{6199}\x{619A}\x{61A4}' . '\x{61A7}\x{61A9}\x{61AB}\x{61AC}\x{61AE}\x{61B2}\x{61B6}\x{61BA}\x{61BE}' . '\x{61C3}\x{61C6}\x{61C7}\x{61C8}\x{61C9}\x{61CA}\x{61CB}\x{61CC}\x{61CD}' . '\x{61D0}\x{61E3}\x{61E6}\x{61F2}\x{61F4}\x{61F6}\x{61F7}\x{61F8}\x{61FA}' . '\x{61FC}\x{61FD}\x{61FE}\x{61FF}\x{6200}\x{6208}\x{6209}\x{620A}\x{620C}' . '\x{620D}\x{620E}\x{6210}\x{6211}\x{6212}\x{6214}\x{6216}\x{621A}\x{621B}' . '\x{621D}\x{621E}\x{621F}\x{6221}\x{6226}\x{622A}\x{622E}\x{622F}\x{6230}' . '\x{6232}\x{6233}\x{6234}\x{6238}\x{623B}\x{623F}\x{6240}\x{6241}\x{6247}' . '\x{6248}\x{6249}\x{624B}\x{624D}\x{624E}\x{6253}\x{6255}\x{6258}\x{625B}' . '\x{625E}\x{6260}\x{6263}\x{6268}\x{626E}\x{6271}\x{6276}\x{6279}\x{627C}' . '\x{627E}\x{627F}\x{6280}\x{6282}\x{6283}\x{6284}\x{6289}\x{628A}\x{6291}' . '\x{6292}\x{6293}\x{6294}\x{6295}\x{6296}\x{6297}\x{6298}\x{629B}\x{629C}' . '\x{629E}\x{62AB}\x{62AC}\x{62B1}\x{62B5}\x{62B9}\x{62BB}\x{62BC}\x{62BD}' . '\x{62C2}\x{62C5}\x{62C6}\x{62C7}\x{62C8}\x{62C9}\x{62CA}\x{62CC}\x{62CD}' . '\x{62CF}\x{62D0}\x{62D1}\x{62D2}\x{62D3}\x{62D4}\x{62D7}\x{62D8}\x{62D9}' . '\x{62DB}\x{62DC}\x{62DD}\x{62E0}\x{62E1}\x{62EC}\x{62ED}\x{62EE}\x{62EF}' . '\x{62F1}\x{62F3}\x{62F5}\x{62F6}\x{62F7}\x{62FE}\x{62FF}\x{6301}\x{6302}' . '\x{6307}\x{6308}\x{6309}\x{630C}\x{6311}\x{6319}\x{631F}\x{6327}\x{6328}' . '\x{632B}\x{632F}\x{633A}\x{633D}\x{633E}\x{633F}\x{6349}\x{634C}\x{634D}' . '\x{634F}\x{6350}\x{6355}\x{6357}\x{635C}\x{6367}\x{6368}\x{6369}\x{636B}' . '\x{636E}\x{6372}\x{6376}\x{6377}\x{637A}\x{637B}\x{6380}\x{6383}\x{6388}' . '\x{6389}\x{638C}\x{638E}\x{638F}\x{6392}\x{6396}\x{6398}\x{639B}\x{639F}' . '\x{63A0}\x{63A1}\x{63A2}\x{63A3}\x{63A5}\x{63A7}\x{63A8}\x{63A9}\x{63AA}' . '\x{63AB}\x{63AC}\x{63B2}\x{63B4}\x{63B5}\x{63BB}\x{63BE}\x{63C0}\x{63C3}' . '\x{63C4}\x{63C6}\x{63C9}\x{63CF}\x{63D0}\x{63D2}\x{63D6}\x{63DA}\x{63DB}' . '\x{63E1}\x{63E3}\x{63E9}\x{63EE}\x{63F4}\x{63F6}\x{63FA}\x{6406}\x{640D}' . '\x{640F}\x{6413}\x{6416}\x{6417}\x{641C}\x{6426}\x{6428}\x{642C}\x{642D}' . '\x{6434}\x{6436}\x{643A}\x{643E}\x{6442}\x{644E}\x{6458}\x{6467}\x{6469}' . '\x{646F}\x{6476}\x{6478}\x{647A}\x{6483}\x{6488}\x{6492}\x{6493}\x{6495}' . '\x{649A}\x{649E}\x{64A4}\x{64A5}\x{64A9}\x{64AB}\x{64AD}\x{64AE}\x{64B0}' . '\x{64B2}\x{64B9}\x{64BB}\x{64BC}\x{64C1}\x{64C2}\x{64C5}\x{64C7}\x{64CD}' . '\x{64D2}\x{64D4}\x{64D8}\x{64DA}\x{64E0}\x{64E1}\x{64E2}\x{64E3}\x{64E6}' . '\x{64E7}\x{64EC}\x{64EF}\x{64F1}\x{64F2}\x{64F4}\x{64F6}\x{64FA}\x{64FD}' . '\x{64FE}\x{6500}\x{6505}\x{6518}\x{651C}\x{651D}\x{6523}\x{6524}\x{652A}' . '\x{652B}\x{652C}\x{652F}\x{6534}\x{6535}\x{6536}\x{6537}\x{6538}\x{6539}' . '\x{653B}\x{653E}\x{653F}\x{6545}\x{6548}\x{654D}\x{654F}\x{6551}\x{6555}' . '\x{6556}\x{6557}\x{6558}\x{6559}\x{655D}\x{655E}\x{6562}\x{6563}\x{6566}' . '\x{656C}\x{6570}\x{6572}\x{6574}\x{6575}\x{6577}\x{6578}\x{6582}\x{6583}' . '\x{6587}\x{6588}\x{6589}\x{658C}\x{658E}\x{6590}\x{6591}\x{6597}\x{6599}' . '\x{659B}\x{659C}\x{659F}\x{65A1}\x{65A4}\x{65A5}\x{65A7}\x{65AB}\x{65AC}' . '\x{65AD}\x{65AF}\x{65B0}\x{65B7}\x{65B9}\x{65BC}\x{65BD}\x{65C1}\x{65C3}' . '\x{65C4}\x{65C5}\x{65C6}\x{65CB}\x{65CC}\x{65CF}\x{65D2}\x{65D7}\x{65D9}' . '\x{65DB}\x{65E0}\x{65E1}\x{65E2}\x{65E5}\x{65E6}\x{65E7}\x{65E8}\x{65E9}' . '\x{65EC}\x{65ED}\x{65F1}\x{65FA}\x{65FB}\x{6602}\x{6603}\x{6606}\x{6607}' . '\x{660A}\x{660C}\x{660E}\x{660F}\x{6613}\x{6614}\x{661C}\x{661F}\x{6620}' . '\x{6625}\x{6627}\x{6628}\x{662D}\x{662F}\x{6634}\x{6635}\x{6636}\x{663C}' . '\x{663F}\x{6641}\x{6642}\x{6643}\x{6644}\x{6649}\x{664B}\x{664F}\x{6652}' . '\x{665D}\x{665E}\x{665F}\x{6662}\x{6664}\x{6666}\x{6667}\x{6668}\x{6669}' . '\x{666E}\x{666F}\x{6670}\x{6674}\x{6676}\x{667A}\x{6681}\x{6683}\x{6684}' . '\x{6687}\x{6688}\x{6689}\x{668E}\x{6691}\x{6696}\x{6697}\x{6698}\x{669D}' . '\x{66A2}\x{66A6}\x{66AB}\x{66AE}\x{66B4}\x{66B8}\x{66B9}\x{66BC}\x{66BE}' . '\x{66C1}\x{66C4}\x{66C7}\x{66C9}\x{66D6}\x{66D9}\x{66DA}\x{66DC}\x{66DD}' . '\x{66E0}\x{66E6}\x{66E9}\x{66F0}\x{66F2}\x{66F3}\x{66F4}\x{66F5}\x{66F7}' . '\x{66F8}\x{66F9}\x{66FC}\x{66FD}\x{66FE}\x{66FF}\x{6700}\x{6703}\x{6708}' . '\x{6709}\x{670B}\x{670D}\x{670F}\x{6714}\x{6715}\x{6716}\x{6717}\x{671B}' . '\x{671D}\x{671E}\x{671F}\x{6726}\x{6727}\x{6728}\x{672A}\x{672B}\x{672C}' . '\x{672D}\x{672E}\x{6731}\x{6734}\x{6736}\x{6737}\x{6738}\x{673A}\x{673D}' . '\x{673F}\x{6741}\x{6746}\x{6749}\x{674E}\x{674F}\x{6750}\x{6751}\x{6753}' . '\x{6756}\x{6759}\x{675C}\x{675E}\x{675F}\x{6760}\x{6761}\x{6762}\x{6763}' . '\x{6764}\x{6765}\x{676A}\x{676D}\x{676F}\x{6770}\x{6771}\x{6772}\x{6773}' . '\x{6775}\x{6777}\x{677C}\x{677E}\x{677F}\x{6785}\x{6787}\x{6789}\x{678B}' . '\x{678C}\x{6790}\x{6795}\x{6797}\x{679A}\x{679C}\x{679D}\x{67A0}\x{67A1}' . '\x{67A2}\x{67A6}\x{67A9}\x{67AF}\x{67B3}\x{67B4}\x{67B6}\x{67B7}\x{67B8}' . '\x{67B9}\x{67C1}\x{67C4}\x{67C6}\x{67CA}\x{67CE}\x{67CF}\x{67D0}\x{67D1}' . '\x{67D3}\x{67D4}\x{67D8}\x{67DA}\x{67DD}\x{67DE}\x{67E2}\x{67E4}\x{67E7}' . '\x{67E9}\x{67EC}\x{67EE}\x{67EF}\x{67F1}\x{67F3}\x{67F4}\x{67F5}\x{67FB}' . '\x{67FE}\x{67FF}\x{6802}\x{6803}\x{6804}\x{6813}\x{6816}\x{6817}\x{681E}' . '\x{6821}\x{6822}\x{6829}\x{682A}\x{682B}\x{6832}\x{6834}\x{6838}\x{6839}' . '\x{683C}\x{683D}\x{6840}\x{6841}\x{6842}\x{6843}\x{6846}\x{6848}\x{684D}' . '\x{684E}\x{6850}\x{6851}\x{6853}\x{6854}\x{6859}\x{685C}\x{685D}\x{685F}' . '\x{6863}\x{6867}\x{6874}\x{6876}\x{6877}\x{687E}\x{687F}\x{6881}\x{6883}' . '\x{6885}\x{688D}\x{688F}\x{6893}\x{6894}\x{6897}\x{689B}\x{689D}\x{689F}' . '\x{68A0}\x{68A2}\x{68A6}\x{68A7}\x{68A8}\x{68AD}\x{68AF}\x{68B0}\x{68B1}' . '\x{68B3}\x{68B5}\x{68B6}\x{68B9}\x{68BA}\x{68BC}\x{68C4}\x{68C6}\x{68C9}' . '\x{68CA}\x{68CB}\x{68CD}\x{68D2}\x{68D4}\x{68D5}\x{68D7}\x{68D8}\x{68DA}' . '\x{68DF}\x{68E0}\x{68E1}\x{68E3}\x{68E7}\x{68EE}\x{68EF}\x{68F2}\x{68F9}' . '\x{68FA}\x{6900}\x{6901}\x{6904}\x{6905}\x{6908}\x{690B}\x{690C}\x{690D}' . '\x{690E}\x{690F}\x{6912}\x{6919}\x{691A}\x{691B}\x{691C}\x{6921}\x{6922}' . '\x{6923}\x{6925}\x{6926}\x{6928}\x{692A}\x{6930}\x{6934}\x{6936}\x{6939}' . '\x{693D}\x{693F}\x{694A}\x{6953}\x{6954}\x{6955}\x{6959}\x{695A}\x{695C}' . '\x{695D}\x{695E}\x{6960}\x{6961}\x{6962}\x{696A}\x{696B}\x{696D}\x{696E}' . '\x{696F}\x{6973}\x{6974}\x{6975}\x{6977}\x{6978}\x{6979}\x{697C}\x{697D}' . '\x{697E}\x{6981}\x{6982}\x{698A}\x{698E}\x{6991}\x{6994}\x{6995}\x{699B}' . '\x{699C}\x{69A0}\x{69A7}\x{69AE}\x{69B1}\x{69B2}\x{69B4}\x{69BB}\x{69BE}' . '\x{69BF}\x{69C1}\x{69C3}\x{69C7}\x{69CA}\x{69CB}\x{69CC}\x{69CD}\x{69CE}' . '\x{69D0}\x{69D3}\x{69D8}\x{69D9}\x{69DD}\x{69DE}\x{69E7}\x{69E8}\x{69EB}' . '\x{69ED}\x{69F2}\x{69F9}\x{69FB}\x{69FD}\x{69FF}\x{6A02}\x{6A05}\x{6A0A}' . '\x{6A0B}\x{6A0C}\x{6A12}\x{6A13}\x{6A14}\x{6A17}\x{6A19}\x{6A1B}\x{6A1E}' . '\x{6A1F}\x{6A21}\x{6A22}\x{6A23}\x{6A29}\x{6A2A}\x{6A2B}\x{6A2E}\x{6A35}' . '\x{6A36}\x{6A38}\x{6A39}\x{6A3A}\x{6A3D}\x{6A44}\x{6A47}\x{6A48}\x{6A4B}' . '\x{6A58}\x{6A59}\x{6A5F}\x{6A61}\x{6A62}\x{6A66}\x{6A72}\x{6A78}\x{6A7F}' . '\x{6A80}\x{6A84}\x{6A8D}\x{6A8E}\x{6A90}\x{6A97}\x{6A9C}\x{6AA0}\x{6AA2}' . '\x{6AA3}\x{6AAA}\x{6AAC}\x{6AAE}\x{6AB3}\x{6AB8}\x{6ABB}\x{6AC1}\x{6AC2}' . '\x{6AC3}\x{6AD1}\x{6AD3}\x{6ADA}\x{6ADB}\x{6ADE}\x{6ADF}\x{6AE8}\x{6AEA}' . '\x{6AFA}\x{6AFB}\x{6B04}\x{6B05}\x{6B0A}\x{6B12}\x{6B16}\x{6B1D}\x{6B1F}' . '\x{6B20}\x{6B21}\x{6B23}\x{6B27}\x{6B32}\x{6B37}\x{6B38}\x{6B39}\x{6B3A}' . '\x{6B3D}\x{6B3E}\x{6B43}\x{6B47}\x{6B49}\x{6B4C}\x{6B4E}\x{6B50}\x{6B53}' . '\x{6B54}\x{6B59}\x{6B5B}\x{6B5F}\x{6B61}\x{6B62}\x{6B63}\x{6B64}\x{6B66}' . '\x{6B69}\x{6B6A}\x{6B6F}\x{6B73}\x{6B74}\x{6B78}\x{6B79}\x{6B7B}\x{6B7F}' . '\x{6B80}\x{6B83}\x{6B84}\x{6B86}\x{6B89}\x{6B8A}\x{6B8B}\x{6B8D}\x{6B95}' . '\x{6B96}\x{6B98}\x{6B9E}\x{6BA4}\x{6BAA}\x{6BAB}\x{6BAF}\x{6BB1}\x{6BB2}' . '\x{6BB3}\x{6BB4}\x{6BB5}\x{6BB7}\x{6BBA}\x{6BBB}\x{6BBC}\x{6BBF}\x{6BC0}' . '\x{6BC5}\x{6BC6}\x{6BCB}\x{6BCD}\x{6BCE}\x{6BD2}\x{6BD3}\x{6BD4}\x{6BD8}' . '\x{6BDB}\x{6BDF}\x{6BEB}\x{6BEC}\x{6BEF}\x{6BF3}\x{6C08}\x{6C0F}\x{6C11}' . '\x{6C13}\x{6C14}\x{6C17}\x{6C1B}\x{6C23}\x{6C24}\x{6C34}\x{6C37}\x{6C38}' . '\x{6C3E}\x{6C40}\x{6C41}\x{6C42}\x{6C4E}\x{6C50}\x{6C55}\x{6C57}\x{6C5A}' . '\x{6C5D}\x{6C5E}\x{6C5F}\x{6C60}\x{6C62}\x{6C68}\x{6C6A}\x{6C70}\x{6C72}' . '\x{6C73}\x{6C7A}\x{6C7D}\x{6C7E}\x{6C81}\x{6C82}\x{6C83}\x{6C88}\x{6C8C}' . '\x{6C8D}\x{6C90}\x{6C92}\x{6C93}\x{6C96}\x{6C99}\x{6C9A}\x{6C9B}\x{6CA1}' . '\x{6CA2}\x{6CAB}\x{6CAE}\x{6CB1}\x{6CB3}\x{6CB8}\x{6CB9}\x{6CBA}\x{6CBB}' . '\x{6CBC}\x{6CBD}\x{6CBE}\x{6CBF}\x{6CC1}\x{6CC4}\x{6CC5}\x{6CC9}\x{6CCA}' . '\x{6CCC}\x{6CD3}\x{6CD5}\x{6CD7}\x{6CD9}\x{6CDB}\x{6CDD}\x{6CE1}\x{6CE2}' . '\x{6CE3}\x{6CE5}\x{6CE8}\x{6CEA}\x{6CEF}\x{6CF0}\x{6CF1}\x{6CF3}\x{6D0B}' . '\x{6D0C}\x{6D12}\x{6D17}\x{6D19}\x{6D1B}\x{6D1E}\x{6D1F}\x{6D25}\x{6D29}' . '\x{6D2A}\x{6D2B}\x{6D32}\x{6D33}\x{6D35}\x{6D36}\x{6D38}\x{6D3B}\x{6D3D}' . '\x{6D3E}\x{6D41}\x{6D44}\x{6D45}\x{6D59}\x{6D5A}\x{6D5C}\x{6D63}\x{6D64}' . '\x{6D66}\x{6D69}\x{6D6A}\x{6D6C}\x{6D6E}\x{6D74}\x{6D77}\x{6D78}\x{6D79}' . '\x{6D85}\x{6D88}\x{6D8C}\x{6D8E}\x{6D93}\x{6D95}\x{6D99}\x{6D9B}\x{6D9C}' . '\x{6DAF}\x{6DB2}\x{6DB5}\x{6DB8}\x{6DBC}\x{6DC0}\x{6DC5}\x{6DC6}\x{6DC7}' . '\x{6DCB}\x{6DCC}\x{6DD1}\x{6DD2}\x{6DD5}\x{6DD8}\x{6DD9}\x{6DDE}\x{6DE1}' . '\x{6DE4}\x{6DE6}\x{6DE8}\x{6DEA}\x{6DEB}\x{6DEC}\x{6DEE}\x{6DF1}\x{6DF3}' . '\x{6DF5}\x{6DF7}\x{6DF9}\x{6DFA}\x{6DFB}\x{6E05}\x{6E07}\x{6E08}\x{6E09}' . '\x{6E0A}\x{6E0B}\x{6E13}\x{6E15}\x{6E19}\x{6E1A}\x{6E1B}\x{6E1D}\x{6E1F}' . '\x{6E20}\x{6E21}\x{6E23}\x{6E24}\x{6E25}\x{6E26}\x{6E29}\x{6E2B}\x{6E2C}' . '\x{6E2D}\x{6E2E}\x{6E2F}\x{6E38}\x{6E3A}\x{6E3E}\x{6E43}\x{6E4A}\x{6E4D}' . '\x{6E4E}\x{6E56}\x{6E58}\x{6E5B}\x{6E5F}\x{6E67}\x{6E6B}\x{6E6E}\x{6E6F}' . '\x{6E72}\x{6E76}\x{6E7E}\x{6E7F}\x{6E80}\x{6E82}\x{6E8C}\x{6E8F}\x{6E90}' . '\x{6E96}\x{6E98}\x{6E9C}\x{6E9D}\x{6E9F}\x{6EA2}\x{6EA5}\x{6EAA}\x{6EAF}' . '\x{6EB2}\x{6EB6}\x{6EB7}\x{6EBA}\x{6EBD}\x{6EC2}\x{6EC4}\x{6EC5}\x{6EC9}' . '\x{6ECB}\x{6ECC}\x{6ED1}\x{6ED3}\x{6ED4}\x{6ED5}\x{6EDD}\x{6EDE}\x{6EEC}' . '\x{6EEF}\x{6EF2}\x{6EF4}\x{6EF7}\x{6EF8}\x{6EFE}\x{6EFF}\x{6F01}\x{6F02}' . '\x{6F06}\x{6F09}\x{6F0F}\x{6F11}\x{6F13}\x{6F14}\x{6F15}\x{6F20}\x{6F22}' . '\x{6F23}\x{6F2B}\x{6F2C}\x{6F31}\x{6F32}\x{6F38}\x{6F3E}\x{6F3F}\x{6F41}' . '\x{6F45}\x{6F54}\x{6F58}\x{6F5B}\x{6F5C}\x{6F5F}\x{6F64}\x{6F66}\x{6F6D}' . '\x{6F6E}\x{6F6F}\x{6F70}\x{6F74}\x{6F78}\x{6F7A}\x{6F7C}\x{6F80}\x{6F81}' . '\x{6F82}\x{6F84}\x{6F86}\x{6F8E}\x{6F91}\x{6F97}\x{6FA1}\x{6FA3}\x{6FA4}' . '\x{6FAA}\x{6FB1}\x{6FB3}\x{6FB9}\x{6FC0}\x{6FC1}\x{6FC2}\x{6FC3}\x{6FC6}' . '\x{6FD4}\x{6FD5}\x{6FD8}\x{6FDB}\x{6FDF}\x{6FE0}\x{6FE1}\x{6FE4}\x{6FEB}' . '\x{6FEC}\x{6FEE}\x{6FEF}\x{6FF1}\x{6FF3}\x{6FF6}\x{6FFA}\x{6FFE}\x{7001}' . '\x{7009}\x{700B}\x{700F}\x{7011}\x{7015}\x{7018}\x{701A}\x{701B}\x{701D}' . '\x{701E}\x{701F}\x{7026}\x{7027}\x{702C}\x{7030}\x{7032}\x{703E}\x{704C}' . '\x{7051}\x{7058}\x{7063}\x{706B}\x{706F}\x{7070}\x{7078}\x{707C}\x{707D}' . '\x{7089}\x{708A}\x{708E}\x{7092}\x{7099}\x{70AC}\x{70AD}\x{70AE}\x{70AF}' . '\x{70B3}\x{70B8}\x{70B9}\x{70BA}\x{70C8}\x{70CB}\x{70CF}\x{70D9}\x{70DD}' . '\x{70DF}\x{70F1}\x{70F9}\x{70FD}\x{7109}\x{7114}\x{7119}\x{711A}\x{711C}' . '\x{7121}\x{7126}\x{7136}\x{713C}\x{7149}\x{714C}\x{714E}\x{7155}\x{7156}' . '\x{7159}\x{7162}\x{7164}\x{7165}\x{7166}\x{7167}\x{7169}\x{716C}\x{716E}' . '\x{717D}\x{7184}\x{7188}\x{718A}\x{718F}\x{7194}\x{7195}\x{7199}\x{719F}' . '\x{71A8}\x{71AC}\x{71B1}\x{71B9}\x{71BE}\x{71C3}\x{71C8}\x{71C9}\x{71CE}' . '\x{71D0}\x{71D2}\x{71D4}\x{71D5}\x{71D7}\x{71DF}\x{71E0}\x{71E5}\x{71E6}' . '\x{71E7}\x{71EC}\x{71ED}\x{71EE}\x{71F5}\x{71F9}\x{71FB}\x{71FC}\x{71FF}' . '\x{7206}\x{720D}\x{7210}\x{721B}\x{7228}\x{722A}\x{722C}\x{722D}\x{7230}' . '\x{7232}\x{7235}\x{7236}\x{723A}\x{723B}\x{723C}\x{723D}\x{723E}\x{723F}' . '\x{7240}\x{7246}\x{7247}\x{7248}\x{724B}\x{724C}\x{7252}\x{7258}\x{7259}' . '\x{725B}\x{725D}\x{725F}\x{7261}\x{7262}\x{7267}\x{7269}\x{7272}\x{7274}' . '\x{7279}\x{727D}\x{727E}\x{7280}\x{7281}\x{7282}\x{7287}\x{7292}\x{7296}' . '\x{72A0}\x{72A2}\x{72A7}\x{72AC}\x{72AF}\x{72B2}\x{72B6}\x{72B9}\x{72C2}' . '\x{72C3}\x{72C4}\x{72C6}\x{72CE}\x{72D0}\x{72D2}\x{72D7}\x{72D9}\x{72DB}' . '\x{72E0}\x{72E1}\x{72E2}\x{72E9}\x{72EC}\x{72ED}\x{72F7}\x{72F8}\x{72F9}' . '\x{72FC}\x{72FD}\x{730A}\x{7316}\x{7317}\x{731B}\x{731C}\x{731D}\x{731F}' . '\x{7325}\x{7329}\x{732A}\x{732B}\x{732E}\x{732F}\x{7334}\x{7336}\x{7337}' . '\x{733E}\x{733F}\x{7344}\x{7345}\x{734E}\x{734F}\x{7357}\x{7363}\x{7368}' . '\x{736A}\x{7370}\x{7372}\x{7375}\x{7378}\x{737A}\x{737B}\x{7384}\x{7387}' . '\x{7389}\x{738B}\x{7396}\x{73A9}\x{73B2}\x{73B3}\x{73BB}\x{73C0}\x{73C2}' . '\x{73C8}\x{73CA}\x{73CD}\x{73CE}\x{73DE}\x{73E0}\x{73E5}\x{73EA}\x{73ED}' . '\x{73EE}\x{73F1}\x{73F8}\x{73FE}\x{7403}\x{7405}\x{7406}\x{7409}\x{7422}' . '\x{7425}\x{7432}\x{7433}\x{7434}\x{7435}\x{7436}\x{743A}\x{743F}\x{7441}' . '\x{7455}\x{7459}\x{745A}\x{745B}\x{745C}\x{745E}\x{745F}\x{7460}\x{7463}' . '\x{7464}\x{7469}\x{746A}\x{746F}\x{7470}\x{7473}\x{7476}\x{747E}\x{7483}' . '\x{748B}\x{749E}\x{74A2}\x{74A7}\x{74B0}\x{74BD}\x{74CA}\x{74CF}\x{74D4}' . '\x{74DC}\x{74E0}\x{74E2}\x{74E3}\x{74E6}\x{74E7}\x{74E9}\x{74EE}\x{74F0}' . '\x{74F1}\x{74F2}\x{74F6}\x{74F7}\x{74F8}\x{7503}\x{7504}\x{7505}\x{750C}' . '\x{750D}\x{750E}\x{7511}\x{7513}\x{7515}\x{7518}\x{751A}\x{751C}\x{751E}' . '\x{751F}\x{7523}\x{7525}\x{7526}\x{7528}\x{752B}\x{752C}\x{7530}\x{7531}' . '\x{7532}\x{7533}\x{7537}\x{7538}\x{753A}\x{753B}\x{753C}\x{7544}\x{7546}' . '\x{7549}\x{754A}\x{754B}\x{754C}\x{754D}\x{754F}\x{7551}\x{7554}\x{7559}' . '\x{755A}\x{755B}\x{755C}\x{755D}\x{7560}\x{7562}\x{7564}\x{7565}\x{7566}' . '\x{7567}\x{7569}\x{756A}\x{756B}\x{756D}\x{7570}\x{7573}\x{7574}\x{7576}' . '\x{7577}\x{7578}\x{757F}\x{7582}\x{7586}\x{7587}\x{7589}\x{758A}\x{758B}' . '\x{758E}\x{758F}\x{7591}\x{7594}\x{759A}\x{759D}\x{75A3}\x{75A5}\x{75AB}' . '\x{75B1}\x{75B2}\x{75B3}\x{75B5}\x{75B8}\x{75B9}\x{75BC}\x{75BD}\x{75BE}' . '\x{75C2}\x{75C3}\x{75C5}\x{75C7}\x{75CA}\x{75CD}\x{75D2}\x{75D4}\x{75D5}' . '\x{75D8}\x{75D9}\x{75DB}\x{75DE}\x{75E2}\x{75E3}\x{75E9}\x{75F0}\x{75F2}' . '\x{75F3}\x{75F4}\x{75FA}\x{75FC}\x{75FE}\x{75FF}\x{7601}\x{7609}\x{760B}' . '\x{760D}\x{761F}\x{7620}\x{7621}\x{7622}\x{7624}\x{7627}\x{7630}\x{7634}' . '\x{763B}\x{7642}\x{7646}\x{7647}\x{7648}\x{764C}\x{7652}\x{7656}\x{7658}' . '\x{765C}\x{7661}\x{7662}\x{7667}\x{7668}\x{7669}\x{766A}\x{766C}\x{7670}' . '\x{7672}\x{7676}\x{7678}\x{767A}\x{767B}\x{767C}\x{767D}\x{767E}\x{7680}' . '\x{7683}\x{7684}\x{7686}\x{7687}\x{7688}\x{768B}\x{768E}\x{7690}\x{7693}' . '\x{7696}\x{7699}\x{769A}\x{76AE}\x{76B0}\x{76B4}\x{76B7}\x{76B8}\x{76B9}' . '\x{76BA}\x{76BF}\x{76C2}\x{76C3}\x{76C6}\x{76C8}\x{76CA}\x{76CD}\x{76D2}' . '\x{76D6}\x{76D7}\x{76DB}\x{76DC}\x{76DE}\x{76DF}\x{76E1}\x{76E3}\x{76E4}' . '\x{76E5}\x{76E7}\x{76EA}\x{76EE}\x{76F2}\x{76F4}\x{76F8}\x{76FB}\x{76FE}' . '\x{7701}\x{7704}\x{7707}\x{7708}\x{7709}\x{770B}\x{770C}\x{771B}\x{771E}' . '\x{771F}\x{7720}\x{7724}\x{7725}\x{7726}\x{7729}\x{7737}\x{7738}\x{773A}' . '\x{773C}\x{7740}\x{7747}\x{775A}\x{775B}\x{7761}\x{7763}\x{7765}\x{7766}' . '\x{7768}\x{776B}\x{7779}\x{777E}\x{777F}\x{778B}\x{778E}\x{7791}\x{779E}' . '\x{77A0}\x{77A5}\x{77AC}\x{77AD}\x{77B0}\x{77B3}\x{77B6}\x{77B9}\x{77BB}' . '\x{77BC}\x{77BD}\x{77BF}\x{77C7}\x{77CD}\x{77D7}\x{77DA}\x{77DB}\x{77DC}' . '\x{77E2}\x{77E3}\x{77E5}\x{77E7}\x{77E9}\x{77ED}\x{77EE}\x{77EF}\x{77F3}' . '\x{77FC}\x{7802}\x{780C}\x{7812}\x{7814}\x{7815}\x{7820}\x{7825}\x{7826}' . '\x{7827}\x{7832}\x{7834}\x{783A}\x{783F}\x{7845}\x{785D}\x{786B}\x{786C}' . '\x{786F}\x{7872}\x{7874}\x{787C}\x{7881}\x{7886}\x{7887}\x{788C}\x{788D}' . '\x{788E}\x{7891}\x{7893}\x{7895}\x{7897}\x{789A}\x{78A3}\x{78A7}\x{78A9}' . '\x{78AA}\x{78AF}\x{78B5}\x{78BA}\x{78BC}\x{78BE}\x{78C1}\x{78C5}\x{78C6}' . '\x{78CA}\x{78CB}\x{78D0}\x{78D1}\x{78D4}\x{78DA}\x{78E7}\x{78E8}\x{78EC}' . '\x{78EF}\x{78F4}\x{78FD}\x{7901}\x{7907}\x{790E}\x{7911}\x{7912}\x{7919}' . '\x{7926}\x{792A}\x{792B}\x{792C}\x{793A}\x{793C}\x{793E}\x{7940}\x{7941}' . '\x{7947}\x{7948}\x{7949}\x{7950}\x{7953}\x{7955}\x{7956}\x{7957}\x{795A}' . '\x{795D}\x{795E}\x{795F}\x{7960}\x{7962}\x{7965}\x{7968}\x{796D}\x{7977}' . '\x{797A}\x{797F}\x{7980}\x{7981}\x{7984}\x{7985}\x{798A}\x{798D}\x{798E}' . '\x{798F}\x{799D}\x{79A6}\x{79A7}\x{79AA}\x{79AE}\x{79B0}\x{79B3}\x{79B9}' . '\x{79BA}\x{79BD}\x{79BE}\x{79BF}\x{79C0}\x{79C1}\x{79C9}\x{79CB}\x{79D1}' . '\x{79D2}\x{79D5}\x{79D8}\x{79DF}\x{79E1}\x{79E3}\x{79E4}\x{79E6}\x{79E7}' . '\x{79E9}\x{79EC}\x{79F0}\x{79FB}\x{7A00}\x{7A08}\x{7A0B}\x{7A0D}\x{7A0E}' . '\x{7A14}\x{7A17}\x{7A18}\x{7A19}\x{7A1A}\x{7A1C}\x{7A1F}\x{7A20}\x{7A2E}' . '\x{7A31}\x{7A32}\x{7A37}\x{7A3B}\x{7A3C}\x{7A3D}\x{7A3E}\x{7A3F}\x{7A40}' . '\x{7A42}\x{7A43}\x{7A46}\x{7A49}\x{7A4D}\x{7A4E}\x{7A4F}\x{7A50}\x{7A57}' . '\x{7A61}\x{7A62}\x{7A63}\x{7A69}\x{7A6B}\x{7A70}\x{7A74}\x{7A76}\x{7A79}' . '\x{7A7A}\x{7A7D}\x{7A7F}\x{7A81}\x{7A83}\x{7A84}\x{7A88}\x{7A92}\x{7A93}' . '\x{7A95}\x{7A96}\x{7A97}\x{7A98}\x{7A9F}\x{7AA9}\x{7AAA}\x{7AAE}\x{7AAF}' . '\x{7AB0}\x{7AB6}\x{7ABA}\x{7ABF}\x{7AC3}\x{7AC4}\x{7AC5}\x{7AC7}\x{7AC8}' . '\x{7ACA}\x{7ACB}\x{7ACD}\x{7ACF}\x{7AD2}\x{7AD3}\x{7AD5}\x{7AD9}\x{7ADA}' . '\x{7ADC}\x{7ADD}\x{7ADF}\x{7AE0}\x{7AE1}\x{7AE2}\x{7AE3}\x{7AE5}\x{7AE6}' . '\x{7AEA}\x{7AED}\x{7AEF}\x{7AF0}\x{7AF6}\x{7AF8}\x{7AF9}\x{7AFA}\x{7AFF}' . '\x{7B02}\x{7B04}\x{7B06}\x{7B08}\x{7B0A}\x{7B0B}\x{7B0F}\x{7B11}\x{7B18}' . '\x{7B19}\x{7B1B}\x{7B1E}\x{7B20}\x{7B25}\x{7B26}\x{7B28}\x{7B2C}\x{7B33}' . '\x{7B35}\x{7B36}\x{7B39}\x{7B45}\x{7B46}\x{7B48}\x{7B49}\x{7B4B}\x{7B4C}' . '\x{7B4D}\x{7B4F}\x{7B50}\x{7B51}\x{7B52}\x{7B54}\x{7B56}\x{7B5D}\x{7B65}' . '\x{7B67}\x{7B6C}\x{7B6E}\x{7B70}\x{7B71}\x{7B74}\x{7B75}\x{7B7A}\x{7B86}' . '\x{7B87}\x{7B8B}\x{7B8D}\x{7B8F}\x{7B92}\x{7B94}\x{7B95}\x{7B97}\x{7B98}' . '\x{7B99}\x{7B9A}\x{7B9C}\x{7B9D}\x{7B9F}\x{7BA1}\x{7BAA}\x{7BAD}\x{7BB1}' . '\x{7BB4}\x{7BB8}\x{7BC0}\x{7BC1}\x{7BC4}\x{7BC6}\x{7BC7}\x{7BC9}\x{7BCB}' . '\x{7BCC}\x{7BCF}\x{7BDD}\x{7BE0}\x{7BE4}\x{7BE5}\x{7BE6}\x{7BE9}\x{7BED}' . '\x{7BF3}\x{7BF6}\x{7BF7}\x{7C00}\x{7C07}\x{7C0D}\x{7C11}\x{7C12}\x{7C13}' . '\x{7C14}\x{7C17}\x{7C1F}\x{7C21}\x{7C23}\x{7C27}\x{7C2A}\x{7C2B}\x{7C37}' . '\x{7C38}\x{7C3D}\x{7C3E}\x{7C3F}\x{7C40}\x{7C43}\x{7C4C}\x{7C4D}\x{7C4F}' . '\x{7C50}\x{7C54}\x{7C56}\x{7C58}\x{7C5F}\x{7C60}\x{7C64}\x{7C65}\x{7C6C}' . '\x{7C73}\x{7C75}\x{7C7E}\x{7C81}\x{7C82}\x{7C83}\x{7C89}\x{7C8B}\x{7C8D}' . '\x{7C90}\x{7C92}\x{7C95}\x{7C97}\x{7C98}\x{7C9B}\x{7C9F}\x{7CA1}\x{7CA2}' . '\x{7CA4}\x{7CA5}\x{7CA7}\x{7CA8}\x{7CAB}\x{7CAD}\x{7CAE}\x{7CB1}\x{7CB2}' . '\x{7CB3}\x{7CB9}\x{7CBD}\x{7CBE}\x{7CC0}\x{7CC2}\x{7CC5}\x{7CCA}\x{7CCE}' . '\x{7CD2}\x{7CD6}\x{7CD8}\x{7CDC}\x{7CDE}\x{7CDF}\x{7CE0}\x{7CE2}\x{7CE7}' . '\x{7CEF}\x{7CF2}\x{7CF4}\x{7CF6}\x{7CF8}\x{7CFA}\x{7CFB}\x{7CFE}\x{7D00}' . '\x{7D02}\x{7D04}\x{7D05}\x{7D06}\x{7D0A}\x{7D0B}\x{7D0D}\x{7D10}\x{7D14}' . '\x{7D15}\x{7D17}\x{7D18}\x{7D19}\x{7D1A}\x{7D1B}\x{7D1C}\x{7D20}\x{7D21}' . '\x{7D22}\x{7D2B}\x{7D2C}\x{7D2E}\x{7D2F}\x{7D30}\x{7D32}\x{7D33}\x{7D35}' . '\x{7D39}\x{7D3A}\x{7D3F}\x{7D42}\x{7D43}\x{7D44}\x{7D45}\x{7D46}\x{7D4B}' . '\x{7D4C}\x{7D4E}\x{7D4F}\x{7D50}\x{7D56}\x{7D5B}\x{7D5E}\x{7D61}\x{7D62}' . '\x{7D63}\x{7D66}\x{7D68}\x{7D6E}\x{7D71}\x{7D72}\x{7D73}\x{7D75}\x{7D76}' . '\x{7D79}\x{7D7D}\x{7D89}\x{7D8F}\x{7D93}\x{7D99}\x{7D9A}\x{7D9B}\x{7D9C}' . '\x{7D9F}\x{7DA2}\x{7DA3}\x{7DAB}\x{7DAC}\x{7DAD}\x{7DAE}\x{7DAF}\x{7DB0}' . '\x{7DB1}\x{7DB2}\x{7DB4}\x{7DB5}\x{7DB8}\x{7DBA}\x{7DBB}\x{7DBD}\x{7DBE}' . '\x{7DBF}\x{7DC7}\x{7DCA}\x{7DCB}\x{7DCF}\x{7DD1}\x{7DD2}\x{7DD5}\x{7DD8}' . '\x{7DDA}\x{7DDC}\x{7DDD}\x{7DDE}\x{7DE0}\x{7DE1}\x{7DE4}\x{7DE8}\x{7DE9}' . '\x{7DEC}\x{7DEF}\x{7DF2}\x{7DF4}\x{7DFB}\x{7E01}\x{7E04}\x{7E05}\x{7E09}' . '\x{7E0A}\x{7E0B}\x{7E12}\x{7E1B}\x{7E1E}\x{7E1F}\x{7E21}\x{7E22}\x{7E23}' . '\x{7E26}\x{7E2B}\x{7E2E}\x{7E31}\x{7E32}\x{7E35}\x{7E37}\x{7E39}\x{7E3A}' . '\x{7E3B}\x{7E3D}\x{7E3E}\x{7E41}\x{7E43}\x{7E46}\x{7E4A}\x{7E4B}\x{7E4D}' . '\x{7E54}\x{7E55}\x{7E56}\x{7E59}\x{7E5A}\x{7E5D}\x{7E5E}\x{7E66}\x{7E67}' . '\x{7E69}\x{7E6A}\x{7E6D}\x{7E70}\x{7E79}\x{7E7B}\x{7E7C}\x{7E7D}\x{7E7F}' . '\x{7E82}\x{7E83}\x{7E88}\x{7E89}\x{7E8C}\x{7E8E}\x{7E8F}\x{7E90}\x{7E92}' . '\x{7E93}\x{7E94}\x{7E96}\x{7E9B}\x{7E9C}\x{7F36}\x{7F38}\x{7F3A}\x{7F45}' . '\x{7F4C}\x{7F4D}\x{7F4E}\x{7F50}\x{7F51}\x{7F54}\x{7F55}\x{7F58}\x{7F5F}' . '\x{7F60}\x{7F67}\x{7F68}\x{7F69}\x{7F6A}\x{7F6B}\x{7F6E}\x{7F70}\x{7F72}' . '\x{7F75}\x{7F77}\x{7F78}\x{7F79}\x{7F82}\x{7F83}\x{7F85}\x{7F86}\x{7F87}' . '\x{7F88}\x{7F8A}\x{7F8C}\x{7F8E}\x{7F94}\x{7F9A}\x{7F9D}\x{7F9E}\x{7FA3}' . '\x{7FA4}\x{7FA8}\x{7FA9}\x{7FAE}\x{7FAF}\x{7FB2}\x{7FB6}\x{7FB8}\x{7FB9}' . '\x{7FBD}\x{7FC1}\x{7FC5}\x{7FC6}\x{7FCA}\x{7FCC}\x{7FD2}\x{7FD4}\x{7FD5}' . '\x{7FE0}\x{7FE1}\x{7FE6}\x{7FE9}\x{7FEB}\x{7FF0}\x{7FF3}\x{7FF9}\x{7FFB}' . '\x{7FFC}\x{8000}\x{8001}\x{8003}\x{8004}\x{8005}\x{8006}\x{800B}\x{800C}' . '\x{8010}\x{8012}\x{8015}\x{8017}\x{8018}\x{8019}\x{801C}\x{8021}\x{8028}' . '\x{8033}\x{8036}\x{803B}\x{803D}\x{803F}\x{8046}\x{804A}\x{8052}\x{8056}' . '\x{8058}\x{805A}\x{805E}\x{805F}\x{8061}\x{8062}\x{8068}\x{806F}\x{8070}' . '\x{8072}\x{8073}\x{8074}\x{8076}\x{8077}\x{8079}\x{807D}\x{807E}\x{807F}' . '\x{8084}\x{8085}\x{8086}\x{8087}\x{8089}\x{808B}\x{808C}\x{8093}\x{8096}' . '\x{8098}\x{809A}\x{809B}\x{809D}\x{80A1}\x{80A2}\x{80A5}\x{80A9}\x{80AA}' . '\x{80AC}\x{80AD}\x{80AF}\x{80B1}\x{80B2}\x{80B4}\x{80BA}\x{80C3}\x{80C4}' . '\x{80C6}\x{80CC}\x{80CE}\x{80D6}\x{80D9}\x{80DA}\x{80DB}\x{80DD}\x{80DE}' . '\x{80E1}\x{80E4}\x{80E5}\x{80EF}\x{80F1}\x{80F4}\x{80F8}\x{80FC}\x{80FD}' . '\x{8102}\x{8105}\x{8106}\x{8107}\x{8108}\x{8109}\x{810A}\x{811A}\x{811B}' . '\x{8123}\x{8129}\x{812F}\x{8131}\x{8133}\x{8139}\x{813E}\x{8146}\x{814B}' . '\x{814E}\x{8150}\x{8151}\x{8153}\x{8154}\x{8155}\x{815F}\x{8165}\x{8166}' . '\x{816B}\x{816E}\x{8170}\x{8171}\x{8174}\x{8178}\x{8179}\x{817A}\x{817F}' . '\x{8180}\x{8182}\x{8183}\x{8188}\x{818A}\x{818F}\x{8193}\x{8195}\x{819A}' . '\x{819C}\x{819D}\x{81A0}\x{81A3}\x{81A4}\x{81A8}\x{81A9}\x{81B0}\x{81B3}' . '\x{81B5}\x{81B8}\x{81BA}\x{81BD}\x{81BE}\x{81BF}\x{81C0}\x{81C2}\x{81C6}' . '\x{81C8}\x{81C9}\x{81CD}\x{81D1}\x{81D3}\x{81D8}\x{81D9}\x{81DA}\x{81DF}' . '\x{81E0}\x{81E3}\x{81E5}\x{81E7}\x{81E8}\x{81EA}\x{81ED}\x{81F3}\x{81F4}' . '\x{81FA}\x{81FB}\x{81FC}\x{81FE}\x{8201}\x{8202}\x{8205}\x{8207}\x{8208}' . '\x{8209}\x{820A}\x{820C}\x{820D}\x{820E}\x{8210}\x{8212}\x{8216}\x{8217}' . '\x{8218}\x{821B}\x{821C}\x{821E}\x{821F}\x{8229}\x{822A}\x{822B}\x{822C}' . '\x{822E}\x{8233}\x{8235}\x{8236}\x{8237}\x{8238}\x{8239}\x{8240}\x{8247}' . '\x{8258}\x{8259}\x{825A}\x{825D}\x{825F}\x{8262}\x{8264}\x{8266}\x{8268}' . '\x{826A}\x{826B}\x{826E}\x{826F}\x{8271}\x{8272}\x{8276}\x{8277}\x{8278}' . '\x{827E}\x{828B}\x{828D}\x{8292}\x{8299}\x{829D}\x{829F}\x{82A5}\x{82A6}' . '\x{82AB}\x{82AC}\x{82AD}\x{82AF}\x{82B1}\x{82B3}\x{82B8}\x{82B9}\x{82BB}' . '\x{82BD}\x{82C5}\x{82D1}\x{82D2}\x{82D3}\x{82D4}\x{82D7}\x{82D9}\x{82DB}' . '\x{82DC}\x{82DE}\x{82DF}\x{82E1}\x{82E3}\x{82E5}\x{82E6}\x{82E7}\x{82EB}' . '\x{82F1}\x{82F3}\x{82F4}\x{82F9}\x{82FA}\x{82FB}\x{8302}\x{8303}\x{8304}' . '\x{8305}\x{8306}\x{8309}\x{830E}\x{8316}\x{8317}\x{8318}\x{831C}\x{8323}' . '\x{8328}\x{832B}\x{832F}\x{8331}\x{8332}\x{8334}\x{8335}\x{8336}\x{8338}' . '\x{8339}\x{8340}\x{8345}\x{8349}\x{834A}\x{834F}\x{8350}\x{8352}\x{8358}' . '\x{8373}\x{8375}\x{8377}\x{837B}\x{837C}\x{8385}\x{8387}\x{8389}\x{838A}' . '\x{838E}\x{8393}\x{8396}\x{839A}\x{839E}\x{839F}\x{83A0}\x{83A2}\x{83A8}' . '\x{83AA}\x{83AB}\x{83B1}\x{83B5}\x{83BD}\x{83C1}\x{83C5}\x{83CA}\x{83CC}' . '\x{83CE}\x{83D3}\x{83D6}\x{83D8}\x{83DC}\x{83DF}\x{83E0}\x{83E9}\x{83EB}' . '\x{83EF}\x{83F0}\x{83F1}\x{83F2}\x{83F4}\x{83F7}\x{83FB}\x{83FD}\x{8403}' . '\x{8404}\x{8407}\x{840B}\x{840C}\x{840D}\x{840E}\x{8413}\x{8420}\x{8422}' . '\x{8429}\x{842A}\x{842C}\x{8431}\x{8435}\x{8438}\x{843C}\x{843D}\x{8446}' . '\x{8449}\x{844E}\x{8457}\x{845B}\x{8461}\x{8462}\x{8463}\x{8466}\x{8469}' . '\x{846B}\x{846C}\x{846D}\x{846E}\x{846F}\x{8471}\x{8475}\x{8477}\x{8479}' . '\x{847A}\x{8482}\x{8484}\x{848B}\x{8490}\x{8494}\x{8499}\x{849C}\x{849F}' . '\x{84A1}\x{84AD}\x{84B2}\x{84B8}\x{84B9}\x{84BB}\x{84BC}\x{84BF}\x{84C1}' . '\x{84C4}\x{84C6}\x{84C9}\x{84CA}\x{84CB}\x{84CD}\x{84D0}\x{84D1}\x{84D6}' . '\x{84D9}\x{84DA}\x{84EC}\x{84EE}\x{84F4}\x{84FC}\x{84FF}\x{8500}\x{8506}' . '\x{8511}\x{8513}\x{8514}\x{8515}\x{8517}\x{8518}\x{851A}\x{851F}\x{8521}' . '\x{8526}\x{852C}\x{852D}\x{8535}\x{853D}\x{8540}\x{8541}\x{8543}\x{8548}' . '\x{8549}\x{854A}\x{854B}\x{854E}\x{8555}\x{8557}\x{8558}\x{855A}\x{8563}' . '\x{8568}\x{8569}\x{856A}\x{856D}\x{8577}\x{857E}\x{8580}\x{8584}\x{8587}' . '\x{8588}\x{858A}\x{8590}\x{8591}\x{8594}\x{8597}\x{8599}\x{859B}\x{859C}' . '\x{85A4}\x{85A6}\x{85A8}\x{85A9}\x{85AA}\x{85AB}\x{85AC}\x{85AE}\x{85AF}' . '\x{85B9}\x{85BA}\x{85C1}\x{85C9}\x{85CD}\x{85CF}\x{85D0}\x{85D5}\x{85DC}' . '\x{85DD}\x{85E4}\x{85E5}\x{85E9}\x{85EA}\x{85F7}\x{85F9}\x{85FA}\x{85FB}' . '\x{85FE}\x{8602}\x{8606}\x{8607}\x{860A}\x{860B}\x{8613}\x{8616}\x{8617}' . '\x{861A}\x{8622}\x{862D}\x{862F}\x{8630}\x{863F}\x{864D}\x{864E}\x{8650}' . '\x{8654}\x{8655}\x{865A}\x{865C}\x{865E}\x{865F}\x{8667}\x{866B}\x{8671}' . '\x{8679}\x{867B}\x{868A}\x{868B}\x{868C}\x{8693}\x{8695}\x{86A3}\x{86A4}' . '\x{86A9}\x{86AA}\x{86AB}\x{86AF}\x{86B0}\x{86B6}\x{86C4}\x{86C6}\x{86C7}' . '\x{86C9}\x{86CB}\x{86CD}\x{86CE}\x{86D4}\x{86D9}\x{86DB}\x{86DE}\x{86DF}' . '\x{86E4}\x{86E9}\x{86EC}\x{86ED}\x{86EE}\x{86EF}\x{86F8}\x{86F9}\x{86FB}' . '\x{86FE}\x{8700}\x{8702}\x{8703}\x{8706}\x{8708}\x{8709}\x{870A}\x{870D}' . '\x{8711}\x{8712}\x{8718}\x{871A}\x{871C}\x{8725}\x{8729}\x{8734}\x{8737}' . '\x{873B}\x{873F}\x{8749}\x{874B}\x{874C}\x{874E}\x{8753}\x{8755}\x{8757}' . '\x{8759}\x{875F}\x{8760}\x{8763}\x{8766}\x{8768}\x{876A}\x{876E}\x{8774}' . '\x{8776}\x{8778}\x{877F}\x{8782}\x{878D}\x{879F}\x{87A2}\x{87AB}\x{87AF}' . '\x{87B3}\x{87BA}\x{87BB}\x{87BD}\x{87C0}\x{87C4}\x{87C6}\x{87C7}\x{87CB}' . '\x{87D0}\x{87D2}\x{87E0}\x{87EF}\x{87F2}\x{87F6}\x{87F7}\x{87F9}\x{87FB}' . '\x{87FE}\x{8805}\x{880D}\x{880E}\x{880F}\x{8811}\x{8815}\x{8816}\x{8821}' . '\x{8822}\x{8823}\x{8827}\x{8831}\x{8836}\x{8839}\x{883B}\x{8840}\x{8842}' . '\x{8844}\x{8846}\x{884C}\x{884D}\x{8852}\x{8853}\x{8857}\x{8859}\x{885B}' . '\x{885D}\x{885E}\x{8861}\x{8862}\x{8863}\x{8868}\x{886B}\x{8870}\x{8872}' . '\x{8875}\x{8877}\x{887D}\x{887E}\x{887F}\x{8881}\x{8882}\x{8888}\x{888B}' . '\x{888D}\x{8892}\x{8896}\x{8897}\x{8899}\x{889E}\x{88A2}\x{88A4}\x{88AB}' . '\x{88AE}\x{88B0}\x{88B1}\x{88B4}\x{88B5}\x{88B7}\x{88BF}\x{88C1}\x{88C2}' . '\x{88C3}\x{88C4}\x{88C5}\x{88CF}\x{88D4}\x{88D5}\x{88D8}\x{88D9}\x{88DC}' . '\x{88DD}\x{88DF}\x{88E1}\x{88E8}\x{88F2}\x{88F3}\x{88F4}\x{88F8}\x{88F9}' . '\x{88FC}\x{88FD}\x{88FE}\x{8902}\x{8904}\x{8907}\x{890A}\x{890C}\x{8910}' . '\x{8912}\x{8913}\x{891D}\x{891E}\x{8925}\x{892A}\x{892B}\x{8936}\x{8938}' . '\x{893B}\x{8941}\x{8943}\x{8944}\x{894C}\x{894D}\x{8956}\x{895E}\x{895F}' . '\x{8960}\x{8964}\x{8966}\x{896A}\x{896D}\x{896F}\x{8972}\x{8974}\x{8977}' . '\x{897E}\x{897F}\x{8981}\x{8983}\x{8986}\x{8987}\x{8988}\x{898A}\x{898B}' . '\x{898F}\x{8993}\x{8996}\x{8997}\x{8998}\x{899A}\x{89A1}\x{89A6}\x{89A7}' . '\x{89A9}\x{89AA}\x{89AC}\x{89AF}\x{89B2}\x{89B3}\x{89BA}\x{89BD}\x{89BF}' . '\x{89C0}\x{89D2}\x{89DA}\x{89DC}\x{89DD}\x{89E3}\x{89E6}\x{89E7}\x{89F4}' . '\x{89F8}\x{8A00}\x{8A02}\x{8A03}\x{8A08}\x{8A0A}\x{8A0C}\x{8A0E}\x{8A10}' . '\x{8A13}\x{8A16}\x{8A17}\x{8A18}\x{8A1B}\x{8A1D}\x{8A1F}\x{8A23}\x{8A25}' . '\x{8A2A}\x{8A2D}\x{8A31}\x{8A33}\x{8A34}\x{8A36}\x{8A3A}\x{8A3B}\x{8A3C}' . '\x{8A41}\x{8A46}\x{8A48}\x{8A50}\x{8A51}\x{8A52}\x{8A54}\x{8A55}\x{8A5B}' . '\x{8A5E}\x{8A60}\x{8A62}\x{8A63}\x{8A66}\x{8A69}\x{8A6B}\x{8A6C}\x{8A6D}' . '\x{8A6E}\x{8A70}\x{8A71}\x{8A72}\x{8A73}\x{8A7C}\x{8A82}\x{8A84}\x{8A85}' . '\x{8A87}\x{8A89}\x{8A8C}\x{8A8D}\x{8A91}\x{8A93}\x{8A95}\x{8A98}\x{8A9A}' . '\x{8A9E}\x{8AA0}\x{8AA1}\x{8AA3}\x{8AA4}\x{8AA5}\x{8AA6}\x{8AA8}\x{8AAC}' . '\x{8AAD}\x{8AB0}\x{8AB2}\x{8AB9}\x{8ABC}\x{8ABF}\x{8AC2}\x{8AC4}\x{8AC7}' . '\x{8ACB}\x{8ACC}\x{8ACD}\x{8ACF}\x{8AD2}\x{8AD6}\x{8ADA}\x{8ADB}\x{8ADC}' . '\x{8ADE}\x{8AE0}\x{8AE1}\x{8AE2}\x{8AE4}\x{8AE6}\x{8AE7}\x{8AEB}\x{8AED}' . '\x{8AEE}\x{8AF1}\x{8AF3}\x{8AF7}\x{8AF8}\x{8AFA}\x{8AFE}\x{8B00}\x{8B01}' . '\x{8B02}\x{8B04}\x{8B07}\x{8B0C}\x{8B0E}\x{8B10}\x{8B14}\x{8B16}\x{8B17}' . '\x{8B19}\x{8B1A}\x{8B1B}\x{8B1D}\x{8B20}\x{8B21}\x{8B26}\x{8B28}\x{8B2B}' . '\x{8B2C}\x{8B33}\x{8B39}\x{8B3E}\x{8B41}\x{8B49}\x{8B4C}\x{8B4E}\x{8B4F}' . '\x{8B56}\x{8B58}\x{8B5A}\x{8B5B}\x{8B5C}\x{8B5F}\x{8B66}\x{8B6B}\x{8B6C}' . '\x{8B6F}\x{8B70}\x{8B71}\x{8B72}\x{8B74}\x{8B77}\x{8B7D}\x{8B80}\x{8B83}' . '\x{8B8A}\x{8B8C}\x{8B8E}\x{8B90}\x{8B92}\x{8B93}\x{8B96}\x{8B99}\x{8B9A}' . '\x{8C37}\x{8C3A}\x{8C3F}\x{8C41}\x{8C46}\x{8C48}\x{8C4A}\x{8C4C}\x{8C4E}' . '\x{8C50}\x{8C55}\x{8C5A}\x{8C61}\x{8C62}\x{8C6A}\x{8C6B}\x{8C6C}\x{8C78}' . '\x{8C79}\x{8C7A}\x{8C7C}\x{8C82}\x{8C85}\x{8C89}\x{8C8A}\x{8C8C}\x{8C8D}' . '\x{8C8E}\x{8C94}\x{8C98}\x{8C9D}\x{8C9E}\x{8CA0}\x{8CA1}\x{8CA2}\x{8CA7}' . '\x{8CA8}\x{8CA9}\x{8CAA}\x{8CAB}\x{8CAC}\x{8CAD}\x{8CAE}\x{8CAF}\x{8CB0}' . '\x{8CB2}\x{8CB3}\x{8CB4}\x{8CB6}\x{8CB7}\x{8CB8}\x{8CBB}\x{8CBC}\x{8CBD}' . '\x{8CBF}\x{8CC0}\x{8CC1}\x{8CC2}\x{8CC3}\x{8CC4}\x{8CC7}\x{8CC8}\x{8CCA}' . '\x{8CCD}\x{8CCE}\x{8CD1}\x{8CD3}\x{8CDA}\x{8CDB}\x{8CDC}\x{8CDE}\x{8CE0}' . '\x{8CE2}\x{8CE3}\x{8CE4}\x{8CE6}\x{8CEA}\x{8CED}\x{8CFA}\x{8CFB}\x{8CFC}' . '\x{8CFD}\x{8D04}\x{8D05}\x{8D07}\x{8D08}\x{8D0A}\x{8D0B}\x{8D0D}\x{8D0F}' . '\x{8D10}\x{8D13}\x{8D14}\x{8D16}\x{8D64}\x{8D66}\x{8D67}\x{8D6B}\x{8D6D}' . '\x{8D70}\x{8D71}\x{8D73}\x{8D74}\x{8D77}\x{8D81}\x{8D85}\x{8D8A}\x{8D99}' . '\x{8DA3}\x{8DA8}\x{8DB3}\x{8DBA}\x{8DBE}\x{8DC2}\x{8DCB}\x{8DCC}\x{8DCF}' . '\x{8DD6}\x{8DDA}\x{8DDB}\x{8DDD}\x{8DDF}\x{8DE1}\x{8DE3}\x{8DE8}\x{8DEA}' . '\x{8DEB}\x{8DEF}\x{8DF3}\x{8DF5}\x{8DFC}\x{8DFF}\x{8E08}\x{8E09}\x{8E0A}' . '\x{8E0F}\x{8E10}\x{8E1D}\x{8E1E}\x{8E1F}\x{8E2A}\x{8E30}\x{8E34}\x{8E35}' . '\x{8E42}\x{8E44}\x{8E47}\x{8E48}\x{8E49}\x{8E4A}\x{8E4C}\x{8E50}\x{8E55}' . '\x{8E59}\x{8E5F}\x{8E60}\x{8E63}\x{8E64}\x{8E72}\x{8E74}\x{8E76}\x{8E7C}' . '\x{8E81}\x{8E84}\x{8E85}\x{8E87}\x{8E8A}\x{8E8B}\x{8E8D}\x{8E91}\x{8E93}' . '\x{8E94}\x{8E99}\x{8EA1}\x{8EAA}\x{8EAB}\x{8EAC}\x{8EAF}\x{8EB0}\x{8EB1}' . '\x{8EBE}\x{8EC5}\x{8EC6}\x{8EC8}\x{8ECA}\x{8ECB}\x{8ECC}\x{8ECD}\x{8ED2}' . '\x{8EDB}\x{8EDF}\x{8EE2}\x{8EE3}\x{8EEB}\x{8EF8}\x{8EFB}\x{8EFC}\x{8EFD}' . '\x{8EFE}\x{8F03}\x{8F05}\x{8F09}\x{8F0A}\x{8F0C}\x{8F12}\x{8F13}\x{8F14}' . '\x{8F15}\x{8F19}\x{8F1B}\x{8F1C}\x{8F1D}\x{8F1F}\x{8F26}\x{8F29}\x{8F2A}' . '\x{8F2F}\x{8F33}\x{8F38}\x{8F39}\x{8F3B}\x{8F3E}\x{8F3F}\x{8F42}\x{8F44}' . '\x{8F45}\x{8F46}\x{8F49}\x{8F4C}\x{8F4D}\x{8F4E}\x{8F57}\x{8F5C}\x{8F5F}' . '\x{8F61}\x{8F62}\x{8F63}\x{8F64}\x{8F9B}\x{8F9C}\x{8F9E}\x{8F9F}\x{8FA3}' . '\x{8FA7}\x{8FA8}\x{8FAD}\x{8FAE}\x{8FAF}\x{8FB0}\x{8FB1}\x{8FB2}\x{8FB7}' . '\x{8FBA}\x{8FBB}\x{8FBC}\x{8FBF}\x{8FC2}\x{8FC4}\x{8FC5}\x{8FCE}\x{8FD1}' . '\x{8FD4}\x{8FDA}\x{8FE2}\x{8FE5}\x{8FE6}\x{8FE9}\x{8FEA}\x{8FEB}\x{8FED}' . '\x{8FEF}\x{8FF0}\x{8FF4}\x{8FF7}\x{8FF8}\x{8FF9}\x{8FFA}\x{8FFD}\x{9000}' . '\x{9001}\x{9003}\x{9005}\x{9006}\x{900B}\x{900D}\x{900E}\x{900F}\x{9010}' . '\x{9011}\x{9013}\x{9014}\x{9015}\x{9016}\x{9017}\x{9019}\x{901A}\x{901D}' . '\x{901E}\x{901F}\x{9020}\x{9021}\x{9022}\x{9023}\x{9027}\x{902E}\x{9031}' . '\x{9032}\x{9035}\x{9036}\x{9038}\x{9039}\x{903C}\x{903E}\x{9041}\x{9042}' . '\x{9045}\x{9047}\x{9049}\x{904A}\x{904B}\x{904D}\x{904E}\x{904F}\x{9050}' . '\x{9051}\x{9052}\x{9053}\x{9054}\x{9055}\x{9056}\x{9058}\x{9059}\x{905C}' . '\x{905E}\x{9060}\x{9061}\x{9063}\x{9065}\x{9068}\x{9069}\x{906D}\x{906E}' . '\x{906F}\x{9072}\x{9075}\x{9076}\x{9077}\x{9078}\x{907A}\x{907C}\x{907D}' . '\x{907F}\x{9080}\x{9081}\x{9082}\x{9083}\x{9084}\x{9087}\x{9089}\x{908A}' . '\x{908F}\x{9091}\x{90A3}\x{90A6}\x{90A8}\x{90AA}\x{90AF}\x{90B1}\x{90B5}' . '\x{90B8}\x{90C1}\x{90CA}\x{90CE}\x{90DB}\x{90E1}\x{90E2}\x{90E4}\x{90E8}' . '\x{90ED}\x{90F5}\x{90F7}\x{90FD}\x{9102}\x{9112}\x{9119}\x{912D}\x{9130}' . '\x{9132}\x{9149}\x{914A}\x{914B}\x{914C}\x{914D}\x{914E}\x{9152}\x{9154}' . '\x{9156}\x{9158}\x{9162}\x{9163}\x{9165}\x{9169}\x{916A}\x{916C}\x{9172}' . '\x{9173}\x{9175}\x{9177}\x{9178}\x{9182}\x{9187}\x{9189}\x{918B}\x{918D}' . '\x{9190}\x{9192}\x{9197}\x{919C}\x{91A2}\x{91A4}\x{91AA}\x{91AB}\x{91AF}' . '\x{91B4}\x{91B5}\x{91B8}\x{91BA}\x{91C0}\x{91C1}\x{91C6}\x{91C7}\x{91C8}' . '\x{91C9}\x{91CB}\x{91CC}\x{91CD}\x{91CE}\x{91CF}\x{91D0}\x{91D1}\x{91D6}' . '\x{91D8}\x{91DB}\x{91DC}\x{91DD}\x{91DF}\x{91E1}\x{91E3}\x{91E6}\x{91E7}' . '\x{91F5}\x{91F6}\x{91FC}\x{91FF}\x{920D}\x{920E}\x{9211}\x{9214}\x{9215}' . '\x{921E}\x{9229}\x{922C}\x{9234}\x{9237}\x{923F}\x{9244}\x{9245}\x{9248}' . '\x{9249}\x{924B}\x{9250}\x{9257}\x{925A}\x{925B}\x{925E}\x{9262}\x{9264}' . '\x{9266}\x{9271}\x{927E}\x{9280}\x{9283}\x{9285}\x{9291}\x{9293}\x{9295}' . '\x{9296}\x{9298}\x{929A}\x{929B}\x{929C}\x{92AD}\x{92B7}\x{92B9}\x{92CF}' . '\x{92D2}\x{92E4}\x{92E9}\x{92EA}\x{92ED}\x{92F2}\x{92F3}\x{92F8}\x{92FA}' . '\x{92FC}\x{9306}\x{930F}\x{9310}\x{9318}\x{9319}\x{931A}\x{9320}\x{9322}' . '\x{9323}\x{9326}\x{9328}\x{932B}\x{932C}\x{932E}\x{932F}\x{9332}\x{9335}' . '\x{933A}\x{933B}\x{9344}\x{934B}\x{934D}\x{9354}\x{9356}\x{935B}\x{935C}' . '\x{9360}\x{936C}\x{936E}\x{9375}\x{937C}\x{937E}\x{938C}\x{9394}\x{9396}' . '\x{9397}\x{939A}\x{93A7}\x{93AC}\x{93AD}\x{93AE}\x{93B0}\x{93B9}\x{93C3}' . '\x{93C8}\x{93D0}\x{93D1}\x{93D6}\x{93D7}\x{93D8}\x{93DD}\x{93E1}\x{93E4}' . '\x{93E5}\x{93E8}\x{9403}\x{9407}\x{9410}\x{9413}\x{9414}\x{9418}\x{9419}' . '\x{941A}\x{9421}\x{942B}\x{9435}\x{9436}\x{9438}\x{943A}\x{9441}\x{9444}' . '\x{9451}\x{9452}\x{9453}\x{945A}\x{945B}\x{945E}\x{9460}\x{9462}\x{946A}' . '\x{9470}\x{9475}\x{9477}\x{947C}\x{947D}\x{947E}\x{947F}\x{9481}\x{9577}' . '\x{9580}\x{9582}\x{9583}\x{9587}\x{9589}\x{958A}\x{958B}\x{958F}\x{9591}' . '\x{9593}\x{9594}\x{9596}\x{9598}\x{9599}\x{95A0}\x{95A2}\x{95A3}\x{95A4}' . '\x{95A5}\x{95A7}\x{95A8}\x{95AD}\x{95B2}\x{95B9}\x{95BB}\x{95BC}\x{95BE}' . '\x{95C3}\x{95C7}\x{95CA}\x{95CC}\x{95CD}\x{95D4}\x{95D5}\x{95D6}\x{95D8}' . '\x{95DC}\x{95E1}\x{95E2}\x{95E5}\x{961C}\x{9621}\x{9628}\x{962A}\x{962E}' . '\x{962F}\x{9632}\x{963B}\x{963F}\x{9640}\x{9642}\x{9644}\x{964B}\x{964C}' . '\x{964D}\x{964F}\x{9650}\x{965B}\x{965C}\x{965D}\x{965E}\x{965F}\x{9662}' . '\x{9663}\x{9664}\x{9665}\x{9666}\x{966A}\x{966C}\x{9670}\x{9672}\x{9673}' . '\x{9675}\x{9676}\x{9677}\x{9678}\x{967A}\x{967D}\x{9685}\x{9686}\x{9688}' . '\x{968A}\x{968B}\x{968D}\x{968E}\x{968F}\x{9694}\x{9695}\x{9697}\x{9698}' . '\x{9699}\x{969B}\x{969C}\x{96A0}\x{96A3}\x{96A7}\x{96A8}\x{96AA}\x{96B0}' . '\x{96B1}\x{96B2}\x{96B4}\x{96B6}\x{96B7}\x{96B8}\x{96B9}\x{96BB}\x{96BC}' . '\x{96C0}\x{96C1}\x{96C4}\x{96C5}\x{96C6}\x{96C7}\x{96C9}\x{96CB}\x{96CC}' . '\x{96CD}\x{96CE}\x{96D1}\x{96D5}\x{96D6}\x{96D9}\x{96DB}\x{96DC}\x{96E2}' . '\x{96E3}\x{96E8}\x{96EA}\x{96EB}\x{96F0}\x{96F2}\x{96F6}\x{96F7}\x{96F9}' . '\x{96FB}\x{9700}\x{9704}\x{9706}\x{9707}\x{9708}\x{970A}\x{970D}\x{970E}' . '\x{970F}\x{9711}\x{9713}\x{9716}\x{9719}\x{971C}\x{971E}\x{9724}\x{9727}' . '\x{972A}\x{9730}\x{9732}\x{9738}\x{9739}\x{973D}\x{973E}\x{9742}\x{9744}' . '\x{9746}\x{9748}\x{9749}\x{9752}\x{9756}\x{9759}\x{975C}\x{975E}\x{9760}' . '\x{9761}\x{9762}\x{9764}\x{9766}\x{9768}\x{9769}\x{976B}\x{976D}\x{9771}' . '\x{9774}\x{9779}\x{977A}\x{977C}\x{9781}\x{9784}\x{9785}\x{9786}\x{978B}' . '\x{978D}\x{978F}\x{9790}\x{9798}\x{979C}\x{97A0}\x{97A3}\x{97A6}\x{97A8}' . '\x{97AB}\x{97AD}\x{97B3}\x{97B4}\x{97C3}\x{97C6}\x{97C8}\x{97CB}\x{97D3}' . '\x{97DC}\x{97ED}\x{97EE}\x{97F2}\x{97F3}\x{97F5}\x{97F6}\x{97FB}\x{97FF}' . '\x{9801}\x{9802}\x{9803}\x{9805}\x{9806}\x{9808}\x{980C}\x{980F}\x{9810}' . '\x{9811}\x{9812}\x{9813}\x{9817}\x{9818}\x{981A}\x{9821}\x{9824}\x{982C}' . '\x{982D}\x{9834}\x{9837}\x{9838}\x{983B}\x{983C}\x{983D}\x{9846}\x{984B}' . '\x{984C}\x{984D}\x{984E}\x{984F}\x{9854}\x{9855}\x{9858}\x{985B}\x{985E}' . '\x{9867}\x{986B}\x{986F}\x{9870}\x{9871}\x{9873}\x{9874}\x{98A8}\x{98AA}' . '\x{98AF}\x{98B1}\x{98B6}\x{98C3}\x{98C4}\x{98C6}\x{98DB}\x{98DC}\x{98DF}' . '\x{98E2}\x{98E9}\x{98EB}\x{98ED}\x{98EE}\x{98EF}\x{98F2}\x{98F4}\x{98FC}' . '\x{98FD}\x{98FE}\x{9903}\x{9905}\x{9909}\x{990A}\x{990C}\x{9910}\x{9912}' . '\x{9913}\x{9914}\x{9918}\x{991D}\x{991E}\x{9920}\x{9921}\x{9924}\x{9928}' . '\x{992C}\x{992E}\x{993D}\x{993E}\x{9942}\x{9945}\x{9949}\x{994B}\x{994C}' . '\x{9950}\x{9951}\x{9952}\x{9955}\x{9957}\x{9996}\x{9997}\x{9998}\x{9999}' . '\x{99A5}\x{99A8}\x{99AC}\x{99AD}\x{99AE}\x{99B3}\x{99B4}\x{99BC}\x{99C1}' . '\x{99C4}\x{99C5}\x{99C6}\x{99C8}\x{99D0}\x{99D1}\x{99D2}\x{99D5}\x{99D8}' . '\x{99DB}\x{99DD}\x{99DF}\x{99E2}\x{99ED}\x{99EE}\x{99F1}\x{99F2}\x{99F8}' . '\x{99FB}\x{99FF}\x{9A01}\x{9A05}\x{9A0E}\x{9A0F}\x{9A12}\x{9A13}\x{9A19}' . '\x{9A28}\x{9A2B}\x{9A30}\x{9A37}\x{9A3E}\x{9A40}\x{9A42}\x{9A43}\x{9A45}' . '\x{9A4D}\x{9A55}\x{9A57}\x{9A5A}\x{9A5B}\x{9A5F}\x{9A62}\x{9A64}\x{9A65}' . '\x{9A69}\x{9A6A}\x{9A6B}\x{9AA8}\x{9AAD}\x{9AB0}\x{9AB8}\x{9ABC}\x{9AC0}' . '\x{9AC4}\x{9ACF}\x{9AD1}\x{9AD3}\x{9AD4}\x{9AD8}\x{9ADE}\x{9ADF}\x{9AE2}' . '\x{9AE3}\x{9AE6}\x{9AEA}\x{9AEB}\x{9AED}\x{9AEE}\x{9AEF}\x{9AF1}\x{9AF4}' . '\x{9AF7}\x{9AFB}\x{9B06}\x{9B18}\x{9B1A}\x{9B1F}\x{9B22}\x{9B23}\x{9B25}' . '\x{9B27}\x{9B28}\x{9B29}\x{9B2A}\x{9B2E}\x{9B2F}\x{9B31}\x{9B32}\x{9B3B}' . '\x{9B3C}\x{9B41}\x{9B42}\x{9B43}\x{9B44}\x{9B45}\x{9B4D}\x{9B4E}\x{9B4F}' . '\x{9B51}\x{9B54}\x{9B58}\x{9B5A}\x{9B6F}\x{9B74}\x{9B83}\x{9B8E}\x{9B91}' . '\x{9B92}\x{9B93}\x{9B96}\x{9B97}\x{9B9F}\x{9BA0}\x{9BA8}\x{9BAA}\x{9BAB}' . '\x{9BAD}\x{9BAE}\x{9BB4}\x{9BB9}\x{9BC0}\x{9BC6}\x{9BC9}\x{9BCA}\x{9BCF}' . '\x{9BD1}\x{9BD2}\x{9BD4}\x{9BD6}\x{9BDB}\x{9BE1}\x{9BE2}\x{9BE3}\x{9BE4}' . '\x{9BE8}\x{9BF0}\x{9BF1}\x{9BF2}\x{9BF5}\x{9C04}\x{9C06}\x{9C08}\x{9C09}' . '\x{9C0A}\x{9C0C}\x{9C0D}\x{9C10}\x{9C12}\x{9C13}\x{9C14}\x{9C15}\x{9C1B}' . '\x{9C21}\x{9C24}\x{9C25}\x{9C2D}\x{9C2E}\x{9C2F}\x{9C30}\x{9C32}\x{9C39}' . '\x{9C3A}\x{9C3B}\x{9C3E}\x{9C46}\x{9C47}\x{9C48}\x{9C52}\x{9C57}\x{9C5A}' . '\x{9C60}\x{9C67}\x{9C76}\x{9C78}\x{9CE5}\x{9CE7}\x{9CE9}\x{9CEB}\x{9CEC}' . '\x{9CF0}\x{9CF3}\x{9CF4}\x{9CF6}\x{9D03}\x{9D06}\x{9D07}\x{9D08}\x{9D09}' . '\x{9D0E}\x{9D12}\x{9D15}\x{9D1B}\x{9D1F}\x{9D23}\x{9D26}\x{9D28}\x{9D2A}' . '\x{9D2B}\x{9D2C}\x{9D3B}\x{9D3E}\x{9D3F}\x{9D41}\x{9D44}\x{9D46}\x{9D48}' . '\x{9D50}\x{9D51}\x{9D59}\x{9D5C}\x{9D5D}\x{9D5E}\x{9D60}\x{9D61}\x{9D64}' . '\x{9D6C}\x{9D6F}\x{9D72}\x{9D7A}\x{9D87}\x{9D89}\x{9D8F}\x{9D9A}\x{9DA4}' . '\x{9DA9}\x{9DAB}\x{9DAF}\x{9DB2}\x{9DB4}\x{9DB8}\x{9DBA}\x{9DBB}\x{9DC1}' . '\x{9DC2}\x{9DC4}\x{9DC6}\x{9DCF}\x{9DD3}\x{9DD9}\x{9DE6}\x{9DED}\x{9DEF}' . '\x{9DF2}\x{9DF8}\x{9DF9}\x{9DFA}\x{9DFD}\x{9E1A}\x{9E1B}\x{9E1E}\x{9E75}' . '\x{9E78}\x{9E79}\x{9E7D}\x{9E7F}\x{9E81}\x{9E88}\x{9E8B}\x{9E8C}\x{9E91}' . '\x{9E92}\x{9E93}\x{9E95}\x{9E97}\x{9E9D}\x{9E9F}\x{9EA5}\x{9EA6}\x{9EA9}' . '\x{9EAA}\x{9EAD}\x{9EB8}\x{9EB9}\x{9EBA}\x{9EBB}\x{9EBC}\x{9EBE}\x{9EBF}' . '\x{9EC4}\x{9ECC}\x{9ECD}\x{9ECE}\x{9ECF}\x{9ED0}\x{9ED2}\x{9ED4}\x{9ED8}' . '\x{9ED9}\x{9EDB}\x{9EDC}\x{9EDD}\x{9EDE}\x{9EE0}\x{9EE5}\x{9EE8}\x{9EEF}' . '\x{9EF4}\x{9EF6}\x{9EF7}\x{9EF9}\x{9EFB}\x{9EFC}\x{9EFD}\x{9F07}\x{9F08}' . '\x{9F0E}\x{9F13}\x{9F15}\x{9F20}\x{9F21}\x{9F2C}\x{9F3B}\x{9F3E}\x{9F4A}' . '\x{9F4B}\x{9F4E}\x{9F4F}\x{9F52}\x{9F54}\x{9F5F}\x{9F60}\x{9F61}\x{9F62}' . '\x{9F63}\x{9F66}\x{9F67}\x{9F6A}\x{9F6C}\x{9F72}\x{9F76}\x{9F77}\x{9F8D}' . '\x{9F95}\x{9F9C}\x{9F9D}\x{9FA0}]{1,15}$/iu', 12 => '/^[\x{002d}0-9a-z\x{3447}\x{3473}\x{359E}\x{360E}\x{361A}\x{3918}\x{396E}\x{39CF}\x{39D0}' . '\x{39DF}\x{3A73}\x{3B4E}\x{3C6E}\x{3CE0}\x{4056}\x{415F}\x{4337}\x{43AC}' . '\x{43B1}\x{43DD}\x{44D6}\x{464C}\x{4661}\x{4723}\x{4729}\x{477C}\x{478D}' . '\x{4947}\x{497A}\x{497D}\x{4982}\x{4983}\x{4985}\x{4986}\x{499B}\x{499F}' . '\x{49B6}\x{49B7}\x{4C77}\x{4C9F}\x{4CA0}\x{4CA1}\x{4CA2}\x{4CA3}\x{4D13}' . '\x{4D14}\x{4D15}\x{4D16}\x{4D17}\x{4D18}\x{4D19}\x{4DAE}\x{4E00}\x{4E01}' . '\x{4E02}\x{4E03}\x{4E04}\x{4E05}\x{4E06}\x{4E07}\x{4E08}\x{4E09}\x{4E0A}' . '\x{4E0B}\x{4E0C}\x{4E0D}\x{4E0E}\x{4E0F}\x{4E10}\x{4E11}\x{4E13}\x{4E14}' . '\x{4E15}\x{4E16}\x{4E17}\x{4E18}\x{4E19}\x{4E1A}\x{4E1B}\x{4E1C}\x{4E1D}' . '\x{4E1E}\x{4E1F}\x{4E20}\x{4E21}\x{4E22}\x{4E23}\x{4E24}\x{4E25}\x{4E26}' . '\x{4E27}\x{4E28}\x{4E2A}\x{4E2B}\x{4E2C}\x{4E2D}\x{4E2E}\x{4E2F}\x{4E30}' . '\x{4E31}\x{4E32}\x{4E33}\x{4E34}\x{4E35}\x{4E36}\x{4E37}\x{4E38}\x{4E39}' . '\x{4E3A}\x{4E3B}\x{4E3C}\x{4E3D}\x{4E3E}\x{4E3F}\x{4E40}\x{4E41}\x{4E42}' . '\x{4E43}\x{4E44}\x{4E45}\x{4E46}\x{4E47}\x{4E48}\x{4E49}\x{4E4A}\x{4E4B}' . '\x{4E4C}\x{4E4D}\x{4E4E}\x{4E4F}\x{4E50}\x{4E51}\x{4E52}\x{4E53}\x{4E54}' . '\x{4E56}\x{4E57}\x{4E58}\x{4E59}\x{4E5A}\x{4E5B}\x{4E5C}\x{4E5D}\x{4E5E}' . '\x{4E5F}\x{4E60}\x{4E61}\x{4E62}\x{4E63}\x{4E64}\x{4E65}\x{4E66}\x{4E67}' . '\x{4E69}\x{4E6A}\x{4E6B}\x{4E6C}\x{4E6D}\x{4E6E}\x{4E6F}\x{4E70}\x{4E71}' . '\x{4E72}\x{4E73}\x{4E74}\x{4E75}\x{4E76}\x{4E77}\x{4E78}\x{4E7A}\x{4E7B}' . '\x{4E7C}\x{4E7D}\x{4E7E}\x{4E7F}\x{4E80}\x{4E81}\x{4E82}\x{4E83}\x{4E84}' . '\x{4E85}\x{4E86}\x{4E87}\x{4E88}\x{4E89}\x{4E8B}\x{4E8C}\x{4E8D}\x{4E8E}' . '\x{4E8F}\x{4E90}\x{4E91}\x{4E92}\x{4E93}\x{4E94}\x{4E95}\x{4E97}\x{4E98}' . '\x{4E99}\x{4E9A}\x{4E9B}\x{4E9C}\x{4E9D}\x{4E9E}\x{4E9F}\x{4EA0}\x{4EA1}' . '\x{4EA2}\x{4EA4}\x{4EA5}\x{4EA6}\x{4EA7}\x{4EA8}\x{4EA9}\x{4EAA}\x{4EAB}' . '\x{4EAC}\x{4EAD}\x{4EAE}\x{4EAF}\x{4EB0}\x{4EB1}\x{4EB2}\x{4EB3}\x{4EB4}' . '\x{4EB5}\x{4EB6}\x{4EB7}\x{4EB8}\x{4EB9}\x{4EBA}\x{4EBB}\x{4EBD}\x{4EBE}' . '\x{4EBF}\x{4EC0}\x{4EC1}\x{4EC2}\x{4EC3}\x{4EC4}\x{4EC5}\x{4EC6}\x{4EC7}' . '\x{4EC8}\x{4EC9}\x{4ECA}\x{4ECB}\x{4ECD}\x{4ECE}\x{4ECF}\x{4ED0}\x{4ED1}' . '\x{4ED2}\x{4ED3}\x{4ED4}\x{4ED5}\x{4ED6}\x{4ED7}\x{4ED8}\x{4ED9}\x{4EDA}' . '\x{4EDB}\x{4EDC}\x{4EDD}\x{4EDE}\x{4EDF}\x{4EE0}\x{4EE1}\x{4EE2}\x{4EE3}' . '\x{4EE4}\x{4EE5}\x{4EE6}\x{4EE8}\x{4EE9}\x{4EEA}\x{4EEB}\x{4EEC}\x{4EEF}' . '\x{4EF0}\x{4EF1}\x{4EF2}\x{4EF3}\x{4EF4}\x{4EF5}\x{4EF6}\x{4EF7}\x{4EFB}' . '\x{4EFD}\x{4EFF}\x{4F00}\x{4F01}\x{4F02}\x{4F03}\x{4F04}\x{4F05}\x{4F06}' . '\x{4F08}\x{4F09}\x{4F0A}\x{4F0B}\x{4F0C}\x{4F0D}\x{4F0E}\x{4F0F}\x{4F10}' . '\x{4F11}\x{4F12}\x{4F13}\x{4F14}\x{4F15}\x{4F17}\x{4F18}\x{4F19}\x{4F1A}' . '\x{4F1B}\x{4F1C}\x{4F1D}\x{4F1E}\x{4F1F}\x{4F20}\x{4F21}\x{4F22}\x{4F23}' . '\x{4F24}\x{4F25}\x{4F26}\x{4F27}\x{4F29}\x{4F2A}\x{4F2B}\x{4F2C}\x{4F2D}' . '\x{4F2E}\x{4F2F}\x{4F30}\x{4F32}\x{4F33}\x{4F34}\x{4F36}\x{4F38}\x{4F39}' . '\x{4F3A}\x{4F3B}\x{4F3C}\x{4F3D}\x{4F3E}\x{4F3F}\x{4F41}\x{4F42}\x{4F43}' . '\x{4F45}\x{4F46}\x{4F47}\x{4F48}\x{4F49}\x{4F4A}\x{4F4B}\x{4F4C}\x{4F4D}' . '\x{4F4E}\x{4F4F}\x{4F50}\x{4F51}\x{4F52}\x{4F53}\x{4F54}\x{4F55}\x{4F56}' . '\x{4F57}\x{4F58}\x{4F59}\x{4F5A}\x{4F5B}\x{4F5C}\x{4F5D}\x{4F5E}\x{4F5F}' . '\x{4F60}\x{4F61}\x{4F62}\x{4F63}\x{4F64}\x{4F65}\x{4F66}\x{4F67}\x{4F68}' . '\x{4F69}\x{4F6A}\x{4F6B}\x{4F6C}\x{4F6D}\x{4F6E}\x{4F6F}\x{4F70}\x{4F72}' . '\x{4F73}\x{4F74}\x{4F75}\x{4F76}\x{4F77}\x{4F78}\x{4F79}\x{4F7A}\x{4F7B}' . '\x{4F7C}\x{4F7D}\x{4F7E}\x{4F7F}\x{4F80}\x{4F81}\x{4F82}\x{4F83}\x{4F84}' . '\x{4F85}\x{4F86}\x{4F87}\x{4F88}\x{4F89}\x{4F8A}\x{4F8B}\x{4F8D}\x{4F8F}' . '\x{4F90}\x{4F91}\x{4F92}\x{4F93}\x{4F94}\x{4F95}\x{4F96}\x{4F97}\x{4F98}' . '\x{4F99}\x{4F9A}\x{4F9B}\x{4F9C}\x{4F9D}\x{4F9E}\x{4F9F}\x{4FA0}\x{4FA1}' . '\x{4FA3}\x{4FA4}\x{4FA5}\x{4FA6}\x{4FA7}\x{4FA8}\x{4FA9}\x{4FAA}\x{4FAB}' . '\x{4FAC}\x{4FAE}\x{4FAF}\x{4FB0}\x{4FB1}\x{4FB2}\x{4FB3}\x{4FB4}\x{4FB5}' . '\x{4FB6}\x{4FB7}\x{4FB8}\x{4FB9}\x{4FBA}\x{4FBB}\x{4FBC}\x{4FBE}\x{4FBF}' . '\x{4FC0}\x{4FC1}\x{4FC2}\x{4FC3}\x{4FC4}\x{4FC5}\x{4FC7}\x{4FC9}\x{4FCA}' . '\x{4FCB}\x{4FCD}\x{4FCE}\x{4FCF}\x{4FD0}\x{4FD1}\x{4FD2}\x{4FD3}\x{4FD4}' . '\x{4FD5}\x{4FD6}\x{4FD7}\x{4FD8}\x{4FD9}\x{4FDA}\x{4FDB}\x{4FDC}\x{4FDD}' . '\x{4FDE}\x{4FDF}\x{4FE0}\x{4FE1}\x{4FE3}\x{4FE4}\x{4FE5}\x{4FE6}\x{4FE7}' . '\x{4FE8}\x{4FE9}\x{4FEA}\x{4FEB}\x{4FEC}\x{4FED}\x{4FEE}\x{4FEF}\x{4FF0}' . '\x{4FF1}\x{4FF2}\x{4FF3}\x{4FF4}\x{4FF5}\x{4FF6}\x{4FF7}\x{4FF8}\x{4FF9}' . '\x{4FFA}\x{4FFB}\x{4FFE}\x{4FFF}\x{5000}\x{5001}\x{5002}\x{5003}\x{5004}' . '\x{5005}\x{5006}\x{5007}\x{5008}\x{5009}\x{500A}\x{500B}\x{500C}\x{500D}' . '\x{500E}\x{500F}\x{5011}\x{5012}\x{5013}\x{5014}\x{5015}\x{5016}\x{5017}' . '\x{5018}\x{5019}\x{501A}\x{501B}\x{501C}\x{501D}\x{501E}\x{501F}\x{5020}' . '\x{5021}\x{5022}\x{5023}\x{5024}\x{5025}\x{5026}\x{5027}\x{5028}\x{5029}' . '\x{502A}\x{502B}\x{502C}\x{502D}\x{502E}\x{502F}\x{5030}\x{5031}\x{5032}' . '\x{5033}\x{5035}\x{5036}\x{5037}\x{5039}\x{503A}\x{503B}\x{503C}\x{503E}' . '\x{503F}\x{5040}\x{5041}\x{5043}\x{5044}\x{5045}\x{5046}\x{5047}\x{5048}' . '\x{5049}\x{504A}\x{504B}\x{504C}\x{504D}\x{504E}\x{504F}\x{5051}\x{5053}' . '\x{5054}\x{5055}\x{5056}\x{5057}\x{5059}\x{505A}\x{505B}\x{505C}\x{505D}' . '\x{505E}\x{505F}\x{5060}\x{5061}\x{5062}\x{5063}\x{5064}\x{5065}\x{5066}' . '\x{5067}\x{5068}\x{5069}\x{506A}\x{506B}\x{506C}\x{506D}\x{506E}\x{506F}' . '\x{5070}\x{5071}\x{5072}\x{5073}\x{5074}\x{5075}\x{5076}\x{5077}\x{5078}' . '\x{5079}\x{507A}\x{507B}\x{507D}\x{507E}\x{507F}\x{5080}\x{5082}\x{5083}' . '\x{5084}\x{5085}\x{5086}\x{5087}\x{5088}\x{5089}\x{508A}\x{508B}\x{508C}' . '\x{508D}\x{508E}\x{508F}\x{5090}\x{5091}\x{5092}\x{5094}\x{5095}\x{5096}' . '\x{5098}\x{5099}\x{509A}\x{509B}\x{509C}\x{509D}\x{509E}\x{50A2}\x{50A3}' . '\x{50A4}\x{50A5}\x{50A6}\x{50A7}\x{50A8}\x{50A9}\x{50AA}\x{50AB}\x{50AC}' . '\x{50AD}\x{50AE}\x{50AF}\x{50B0}\x{50B1}\x{50B2}\x{50B3}\x{50B4}\x{50B5}' . '\x{50B6}\x{50B7}\x{50B8}\x{50BA}\x{50BB}\x{50BC}\x{50BD}\x{50BE}\x{50BF}' . '\x{50C0}\x{50C1}\x{50C2}\x{50C4}\x{50C5}\x{50C6}\x{50C7}\x{50C8}\x{50C9}' . '\x{50CA}\x{50CB}\x{50CC}\x{50CD}\x{50CE}\x{50CF}\x{50D0}\x{50D1}\x{50D2}' . '\x{50D3}\x{50D4}\x{50D5}\x{50D6}\x{50D7}\x{50D9}\x{50DA}\x{50DB}\x{50DC}' . '\x{50DD}\x{50DE}\x{50E0}\x{50E3}\x{50E4}\x{50E5}\x{50E6}\x{50E7}\x{50E8}' . '\x{50E9}\x{50EA}\x{50EC}\x{50ED}\x{50EE}\x{50EF}\x{50F0}\x{50F1}\x{50F2}' . '\x{50F3}\x{50F5}\x{50F6}\x{50F8}\x{50F9}\x{50FA}\x{50FB}\x{50FC}\x{50FD}' . '\x{50FE}\x{50FF}\x{5100}\x{5101}\x{5102}\x{5103}\x{5104}\x{5105}\x{5106}' . '\x{5107}\x{5108}\x{5109}\x{510A}\x{510B}\x{510C}\x{510D}\x{510E}\x{510F}' . '\x{5110}\x{5111}\x{5112}\x{5113}\x{5114}\x{5115}\x{5116}\x{5117}\x{5118}' . '\x{5119}\x{511A}\x{511C}\x{511D}\x{511E}\x{511F}\x{5120}\x{5121}\x{5122}' . '\x{5123}\x{5124}\x{5125}\x{5126}\x{5127}\x{5129}\x{512A}\x{512C}\x{512D}' . '\x{512E}\x{512F}\x{5130}\x{5131}\x{5132}\x{5133}\x{5134}\x{5135}\x{5136}' . '\x{5137}\x{5138}\x{5139}\x{513A}\x{513B}\x{513C}\x{513D}\x{513E}\x{513F}' . '\x{5140}\x{5141}\x{5143}\x{5144}\x{5145}\x{5146}\x{5147}\x{5148}\x{5149}' . '\x{514B}\x{514C}\x{514D}\x{514E}\x{5150}\x{5151}\x{5152}\x{5154}\x{5155}' . '\x{5156}\x{5157}\x{5159}\x{515A}\x{515B}\x{515C}\x{515D}\x{515E}\x{515F}' . '\x{5161}\x{5162}\x{5163}\x{5165}\x{5166}\x{5167}\x{5168}\x{5169}\x{516A}' . '\x{516B}\x{516C}\x{516D}\x{516E}\x{516F}\x{5170}\x{5171}\x{5173}\x{5174}' . '\x{5175}\x{5176}\x{5177}\x{5178}\x{5179}\x{517A}\x{517B}\x{517C}\x{517D}' . '\x{517F}\x{5180}\x{5181}\x{5182}\x{5185}\x{5186}\x{5187}\x{5188}\x{5189}' . '\x{518A}\x{518B}\x{518C}\x{518D}\x{518F}\x{5190}\x{5191}\x{5192}\x{5193}' . '\x{5194}\x{5195}\x{5196}\x{5197}\x{5198}\x{5199}\x{519A}\x{519B}\x{519C}' . '\x{519D}\x{519E}\x{519F}\x{51A0}\x{51A2}\x{51A4}\x{51A5}\x{51A6}\x{51A7}' . '\x{51A8}\x{51AA}\x{51AB}\x{51AC}\x{51AE}\x{51AF}\x{51B0}\x{51B1}\x{51B2}' . '\x{51B3}\x{51B5}\x{51B6}\x{51B7}\x{51B9}\x{51BB}\x{51BC}\x{51BD}\x{51BE}' . '\x{51BF}\x{51C0}\x{51C1}\x{51C3}\x{51C4}\x{51C5}\x{51C6}\x{51C7}\x{51C8}' . '\x{51C9}\x{51CA}\x{51CB}\x{51CC}\x{51CD}\x{51CE}\x{51CF}\x{51D0}\x{51D1}' . '\x{51D4}\x{51D5}\x{51D6}\x{51D7}\x{51D8}\x{51D9}\x{51DA}\x{51DB}\x{51DC}' . '\x{51DD}\x{51DE}\x{51E0}\x{51E1}\x{51E2}\x{51E3}\x{51E4}\x{51E5}\x{51E7}' . '\x{51E8}\x{51E9}\x{51EA}\x{51EB}\x{51ED}\x{51EF}\x{51F0}\x{51F1}\x{51F3}' . '\x{51F4}\x{51F5}\x{51F6}\x{51F7}\x{51F8}\x{51F9}\x{51FA}\x{51FB}\x{51FC}' . '\x{51FD}\x{51FE}\x{51FF}\x{5200}\x{5201}\x{5202}\x{5203}\x{5204}\x{5205}' . '\x{5206}\x{5207}\x{5208}\x{5209}\x{520A}\x{520B}\x{520C}\x{520D}\x{520E}' . '\x{520F}\x{5210}\x{5211}\x{5212}\x{5213}\x{5214}\x{5215}\x{5216}\x{5217}' . '\x{5218}\x{5219}\x{521A}\x{521B}\x{521C}\x{521D}\x{521E}\x{521F}\x{5220}' . '\x{5221}\x{5222}\x{5223}\x{5224}\x{5225}\x{5226}\x{5228}\x{5229}\x{522A}' . '\x{522B}\x{522C}\x{522D}\x{522E}\x{522F}\x{5230}\x{5231}\x{5232}\x{5233}' . '\x{5234}\x{5235}\x{5236}\x{5237}\x{5238}\x{5239}\x{523A}\x{523B}\x{523C}' . '\x{523D}\x{523E}\x{523F}\x{5240}\x{5241}\x{5242}\x{5243}\x{5244}\x{5245}' . '\x{5246}\x{5247}\x{5248}\x{5249}\x{524A}\x{524B}\x{524C}\x{524D}\x{524E}' . '\x{5250}\x{5251}\x{5252}\x{5254}\x{5255}\x{5256}\x{5257}\x{5258}\x{5259}' . '\x{525A}\x{525B}\x{525C}\x{525D}\x{525E}\x{525F}\x{5260}\x{5261}\x{5262}' . '\x{5263}\x{5264}\x{5265}\x{5267}\x{5268}\x{5269}\x{526A}\x{526B}\x{526C}' . '\x{526D}\x{526E}\x{526F}\x{5270}\x{5272}\x{5273}\x{5274}\x{5275}\x{5276}' . '\x{5277}\x{5278}\x{527A}\x{527B}\x{527C}\x{527D}\x{527E}\x{527F}\x{5280}' . '\x{5281}\x{5282}\x{5283}\x{5284}\x{5286}\x{5287}\x{5288}\x{5289}\x{528A}' . '\x{528B}\x{528C}\x{528D}\x{528F}\x{5290}\x{5291}\x{5292}\x{5293}\x{5294}' . '\x{5295}\x{5296}\x{5297}\x{5298}\x{5299}\x{529A}\x{529B}\x{529C}\x{529D}' . '\x{529E}\x{529F}\x{52A0}\x{52A1}\x{52A2}\x{52A3}\x{52A5}\x{52A6}\x{52A7}' . '\x{52A8}\x{52A9}\x{52AA}\x{52AB}\x{52AC}\x{52AD}\x{52AE}\x{52AF}\x{52B0}' . '\x{52B1}\x{52B2}\x{52B3}\x{52B4}\x{52B5}\x{52B6}\x{52B7}\x{52B8}\x{52B9}' . '\x{52BA}\x{52BB}\x{52BC}\x{52BD}\x{52BE}\x{52BF}\x{52C0}\x{52C1}\x{52C2}' . '\x{52C3}\x{52C6}\x{52C7}\x{52C9}\x{52CA}\x{52CB}\x{52CD}\x{52CF}\x{52D0}' . '\x{52D2}\x{52D3}\x{52D5}\x{52D6}\x{52D7}\x{52D8}\x{52D9}\x{52DA}\x{52DB}' . '\x{52DC}\x{52DD}\x{52DE}\x{52DF}\x{52E0}\x{52E2}\x{52E3}\x{52E4}\x{52E6}' . '\x{52E7}\x{52E8}\x{52E9}\x{52EA}\x{52EB}\x{52EC}\x{52ED}\x{52EF}\x{52F0}' . '\x{52F1}\x{52F2}\x{52F3}\x{52F4}\x{52F5}\x{52F6}\x{52F7}\x{52F8}\x{52F9}' . '\x{52FA}\x{52FB}\x{52FC}\x{52FD}\x{52FE}\x{52FF}\x{5300}\x{5301}\x{5302}' . '\x{5305}\x{5306}\x{5307}\x{5308}\x{5309}\x{530A}\x{530B}\x{530C}\x{530D}' . '\x{530E}\x{530F}\x{5310}\x{5311}\x{5312}\x{5313}\x{5314}\x{5315}\x{5316}' . '\x{5317}\x{5319}\x{531A}\x{531C}\x{531D}\x{531F}\x{5320}\x{5321}\x{5322}' . '\x{5323}\x{5324}\x{5325}\x{5326}\x{5328}\x{532A}\x{532B}\x{532C}\x{532D}' . '\x{532E}\x{532F}\x{5330}\x{5331}\x{5333}\x{5334}\x{5337}\x{5339}\x{533A}' . '\x{533B}\x{533C}\x{533D}\x{533E}\x{533F}\x{5340}\x{5341}\x{5343}\x{5344}' . '\x{5345}\x{5346}\x{5347}\x{5348}\x{5349}\x{534A}\x{534B}\x{534C}\x{534D}' . '\x{534E}\x{534F}\x{5350}\x{5351}\x{5352}\x{5353}\x{5354}\x{5355}\x{5356}' . '\x{5357}\x{5358}\x{5359}\x{535A}\x{535C}\x{535E}\x{535F}\x{5360}\x{5361}' . '\x{5362}\x{5363}\x{5364}\x{5365}\x{5366}\x{5367}\x{5369}\x{536B}\x{536C}' . '\x{536E}\x{536F}\x{5370}\x{5371}\x{5372}\x{5373}\x{5374}\x{5375}\x{5376}' . '\x{5377}\x{5378}\x{5379}\x{537A}\x{537B}\x{537C}\x{537D}\x{537E}\x{537F}' . '\x{5381}\x{5382}\x{5383}\x{5384}\x{5385}\x{5386}\x{5387}\x{5388}\x{5389}' . '\x{538A}\x{538B}\x{538C}\x{538D}\x{538E}\x{538F}\x{5390}\x{5391}\x{5392}' . '\x{5393}\x{5394}\x{5395}\x{5396}\x{5397}\x{5398}\x{5399}\x{539A}\x{539B}' . '\x{539C}\x{539D}\x{539E}\x{539F}\x{53A0}\x{53A2}\x{53A3}\x{53A4}\x{53A5}' . '\x{53A6}\x{53A7}\x{53A8}\x{53A9}\x{53AC}\x{53AD}\x{53AE}\x{53B0}\x{53B1}' . '\x{53B2}\x{53B3}\x{53B4}\x{53B5}\x{53B6}\x{53B7}\x{53B8}\x{53B9}\x{53BB}' . '\x{53BC}\x{53BD}\x{53BE}\x{53BF}\x{53C0}\x{53C1}\x{53C2}\x{53C3}\x{53C4}' . '\x{53C6}\x{53C7}\x{53C8}\x{53C9}\x{53CA}\x{53CB}\x{53CC}\x{53CD}\x{53CE}' . '\x{53D0}\x{53D1}\x{53D2}\x{53D3}\x{53D4}\x{53D5}\x{53D6}\x{53D7}\x{53D8}' . '\x{53D9}\x{53DB}\x{53DC}\x{53DF}\x{53E0}\x{53E1}\x{53E2}\x{53E3}\x{53E4}' . '\x{53E5}\x{53E6}\x{53E8}\x{53E9}\x{53EA}\x{53EB}\x{53EC}\x{53ED}\x{53EE}' . '\x{53EF}\x{53F0}\x{53F1}\x{53F2}\x{53F3}\x{53F4}\x{53F5}\x{53F6}\x{53F7}' . '\x{53F8}\x{53F9}\x{53FA}\x{53FB}\x{53FC}\x{53FD}\x{53FE}\x{5401}\x{5402}' . '\x{5403}\x{5404}\x{5405}\x{5406}\x{5407}\x{5408}\x{5409}\x{540A}\x{540B}' . '\x{540C}\x{540D}\x{540E}\x{540F}\x{5410}\x{5411}\x{5412}\x{5413}\x{5414}' . '\x{5415}\x{5416}\x{5417}\x{5418}\x{5419}\x{541B}\x{541C}\x{541D}\x{541E}' . '\x{541F}\x{5420}\x{5421}\x{5423}\x{5424}\x{5425}\x{5426}\x{5427}\x{5428}' . '\x{5429}\x{542A}\x{542B}\x{542C}\x{542D}\x{542E}\x{542F}\x{5430}\x{5431}' . '\x{5432}\x{5433}\x{5434}\x{5435}\x{5436}\x{5437}\x{5438}\x{5439}\x{543A}' . '\x{543B}\x{543C}\x{543D}\x{543E}\x{543F}\x{5440}\x{5441}\x{5442}\x{5443}' . '\x{5444}\x{5445}\x{5446}\x{5447}\x{5448}\x{5449}\x{544A}\x{544B}\x{544D}' . '\x{544E}\x{544F}\x{5450}\x{5451}\x{5452}\x{5453}\x{5454}\x{5455}\x{5456}' . '\x{5457}\x{5458}\x{5459}\x{545A}\x{545B}\x{545C}\x{545E}\x{545F}\x{5460}' . '\x{5461}\x{5462}\x{5463}\x{5464}\x{5465}\x{5466}\x{5467}\x{5468}\x{546A}' . '\x{546B}\x{546C}\x{546D}\x{546E}\x{546F}\x{5470}\x{5471}\x{5472}\x{5473}' . '\x{5474}\x{5475}\x{5476}\x{5477}\x{5478}\x{5479}\x{547A}\x{547B}\x{547C}' . '\x{547D}\x{547E}\x{547F}\x{5480}\x{5481}\x{5482}\x{5483}\x{5484}\x{5485}' . '\x{5486}\x{5487}\x{5488}\x{5489}\x{548B}\x{548C}\x{548D}\x{548E}\x{548F}' . '\x{5490}\x{5491}\x{5492}\x{5493}\x{5494}\x{5495}\x{5496}\x{5497}\x{5498}' . '\x{5499}\x{549A}\x{549B}\x{549C}\x{549D}\x{549E}\x{549F}\x{54A0}\x{54A1}' . '\x{54A2}\x{54A3}\x{54A4}\x{54A5}\x{54A6}\x{54A7}\x{54A8}\x{54A9}\x{54AA}' . '\x{54AB}\x{54AC}\x{54AD}\x{54AE}\x{54AF}\x{54B0}\x{54B1}\x{54B2}\x{54B3}' . '\x{54B4}\x{54B6}\x{54B7}\x{54B8}\x{54B9}\x{54BA}\x{54BB}\x{54BC}\x{54BD}' . '\x{54BE}\x{54BF}\x{54C0}\x{54C1}\x{54C2}\x{54C3}\x{54C4}\x{54C5}\x{54C6}' . '\x{54C7}\x{54C8}\x{54C9}\x{54CA}\x{54CB}\x{54CC}\x{54CD}\x{54CE}\x{54CF}' . '\x{54D0}\x{54D1}\x{54D2}\x{54D3}\x{54D4}\x{54D5}\x{54D6}\x{54D7}\x{54D8}' . '\x{54D9}\x{54DA}\x{54DB}\x{54DC}\x{54DD}\x{54DE}\x{54DF}\x{54E0}\x{54E1}' . '\x{54E2}\x{54E3}\x{54E4}\x{54E5}\x{54E6}\x{54E7}\x{54E8}\x{54E9}\x{54EA}' . '\x{54EB}\x{54EC}\x{54ED}\x{54EE}\x{54EF}\x{54F0}\x{54F1}\x{54F2}\x{54F3}' . '\x{54F4}\x{54F5}\x{54F7}\x{54F8}\x{54F9}\x{54FA}\x{54FB}\x{54FC}\x{54FD}' . '\x{54FE}\x{54FF}\x{5500}\x{5501}\x{5502}\x{5503}\x{5504}\x{5505}\x{5506}' . '\x{5507}\x{5508}\x{5509}\x{550A}\x{550B}\x{550C}\x{550D}\x{550E}\x{550F}' . '\x{5510}\x{5511}\x{5512}\x{5513}\x{5514}\x{5516}\x{5517}\x{551A}\x{551B}' . '\x{551C}\x{551D}\x{551E}\x{551F}\x{5520}\x{5521}\x{5522}\x{5523}\x{5524}' . '\x{5525}\x{5526}\x{5527}\x{5528}\x{5529}\x{552A}\x{552B}\x{552C}\x{552D}' . '\x{552E}\x{552F}\x{5530}\x{5531}\x{5532}\x{5533}\x{5534}\x{5535}\x{5536}' . '\x{5537}\x{5538}\x{5539}\x{553A}\x{553B}\x{553C}\x{553D}\x{553E}\x{553F}' . '\x{5540}\x{5541}\x{5542}\x{5543}\x{5544}\x{5545}\x{5546}\x{5548}\x{5549}' . '\x{554A}\x{554B}\x{554C}\x{554D}\x{554E}\x{554F}\x{5550}\x{5551}\x{5552}' . '\x{5553}\x{5554}\x{5555}\x{5556}\x{5557}\x{5558}\x{5559}\x{555A}\x{555B}' . '\x{555C}\x{555D}\x{555E}\x{555F}\x{5561}\x{5562}\x{5563}\x{5564}\x{5565}' . '\x{5566}\x{5567}\x{5568}\x{5569}\x{556A}\x{556B}\x{556C}\x{556D}\x{556E}' . '\x{556F}\x{5570}\x{5571}\x{5572}\x{5573}\x{5574}\x{5575}\x{5576}\x{5577}' . '\x{5578}\x{5579}\x{557B}\x{557C}\x{557D}\x{557E}\x{557F}\x{5580}\x{5581}' . '\x{5582}\x{5583}\x{5584}\x{5585}\x{5586}\x{5587}\x{5588}\x{5589}\x{558A}' . '\x{558B}\x{558C}\x{558D}\x{558E}\x{558F}\x{5590}\x{5591}\x{5592}\x{5593}' . '\x{5594}\x{5595}\x{5596}\x{5597}\x{5598}\x{5599}\x{559A}\x{559B}\x{559C}' . '\x{559D}\x{559E}\x{559F}\x{55A0}\x{55A1}\x{55A2}\x{55A3}\x{55A4}\x{55A5}' . '\x{55A6}\x{55A7}\x{55A8}\x{55A9}\x{55AA}\x{55AB}\x{55AC}\x{55AD}\x{55AE}' . '\x{55AF}\x{55B0}\x{55B1}\x{55B2}\x{55B3}\x{55B4}\x{55B5}\x{55B6}\x{55B7}' . '\x{55B8}\x{55B9}\x{55BA}\x{55BB}\x{55BC}\x{55BD}\x{55BE}\x{55BF}\x{55C0}' . '\x{55C1}\x{55C2}\x{55C3}\x{55C4}\x{55C5}\x{55C6}\x{55C7}\x{55C8}\x{55C9}' . '\x{55CA}\x{55CB}\x{55CC}\x{55CD}\x{55CE}\x{55CF}\x{55D0}\x{55D1}\x{55D2}' . '\x{55D3}\x{55D4}\x{55D5}\x{55D6}\x{55D7}\x{55D8}\x{55D9}\x{55DA}\x{55DB}' . '\x{55DC}\x{55DD}\x{55DE}\x{55DF}\x{55E1}\x{55E2}\x{55E3}\x{55E4}\x{55E5}' . '\x{55E6}\x{55E7}\x{55E8}\x{55E9}\x{55EA}\x{55EB}\x{55EC}\x{55ED}\x{55EE}' . '\x{55EF}\x{55F0}\x{55F1}\x{55F2}\x{55F3}\x{55F4}\x{55F5}\x{55F6}\x{55F7}' . '\x{55F9}\x{55FA}\x{55FB}\x{55FC}\x{55FD}\x{55FE}\x{55FF}\x{5600}\x{5601}' . '\x{5602}\x{5603}\x{5604}\x{5606}\x{5607}\x{5608}\x{5609}\x{560C}\x{560D}' . '\x{560E}\x{560F}\x{5610}\x{5611}\x{5612}\x{5613}\x{5614}\x{5615}\x{5616}' . '\x{5617}\x{5618}\x{5619}\x{561A}\x{561B}\x{561C}\x{561D}\x{561E}\x{561F}' . '\x{5621}\x{5622}\x{5623}\x{5624}\x{5625}\x{5626}\x{5627}\x{5628}\x{5629}' . '\x{562A}\x{562C}\x{562D}\x{562E}\x{562F}\x{5630}\x{5631}\x{5632}\x{5633}' . '\x{5634}\x{5635}\x{5636}\x{5638}\x{5639}\x{563A}\x{563B}\x{563D}\x{563E}' . '\x{563F}\x{5640}\x{5641}\x{5642}\x{5643}\x{5645}\x{5646}\x{5647}\x{5648}' . '\x{5649}\x{564A}\x{564C}\x{564D}\x{564E}\x{564F}\x{5650}\x{5652}\x{5653}' . '\x{5654}\x{5655}\x{5657}\x{5658}\x{5659}\x{565A}\x{565B}\x{565C}\x{565D}' . '\x{565E}\x{5660}\x{5662}\x{5663}\x{5664}\x{5665}\x{5666}\x{5667}\x{5668}' . '\x{5669}\x{566A}\x{566B}\x{566C}\x{566D}\x{566E}\x{566F}\x{5670}\x{5671}' . '\x{5672}\x{5673}\x{5674}\x{5676}\x{5677}\x{5678}\x{5679}\x{567A}\x{567B}' . '\x{567C}\x{567E}\x{567F}\x{5680}\x{5681}\x{5682}\x{5683}\x{5684}\x{5685}' . '\x{5686}\x{5687}\x{568A}\x{568C}\x{568D}\x{568E}\x{568F}\x{5690}\x{5691}' . '\x{5692}\x{5693}\x{5694}\x{5695}\x{5697}\x{5698}\x{5699}\x{569A}\x{569B}' . '\x{569C}\x{569D}\x{569F}\x{56A0}\x{56A1}\x{56A3}\x{56A4}\x{56A5}\x{56A6}' . '\x{56A7}\x{56A8}\x{56A9}\x{56AA}\x{56AB}\x{56AC}\x{56AD}\x{56AE}\x{56AF}' . '\x{56B0}\x{56B1}\x{56B2}\x{56B3}\x{56B4}\x{56B5}\x{56B6}\x{56B7}\x{56B8}' . '\x{56B9}\x{56BB}\x{56BC}\x{56BD}\x{56BE}\x{56BF}\x{56C0}\x{56C1}\x{56C2}' . '\x{56C3}\x{56C4}\x{56C5}\x{56C6}\x{56C7}\x{56C8}\x{56C9}\x{56CA}\x{56CB}' . '\x{56CC}\x{56CD}\x{56CE}\x{56D0}\x{56D1}\x{56D2}\x{56D3}\x{56D4}\x{56D5}' . '\x{56D6}\x{56D7}\x{56D8}\x{56DA}\x{56DB}\x{56DC}\x{56DD}\x{56DE}\x{56DF}' . '\x{56E0}\x{56E1}\x{56E2}\x{56E3}\x{56E4}\x{56E5}\x{56E7}\x{56E8}\x{56E9}' . '\x{56EA}\x{56EB}\x{56EC}\x{56ED}\x{56EE}\x{56EF}\x{56F0}\x{56F1}\x{56F2}' . '\x{56F3}\x{56F4}\x{56F5}\x{56F7}\x{56F9}\x{56FA}\x{56FD}\x{56FE}\x{56FF}' . '\x{5700}\x{5701}\x{5702}\x{5703}\x{5704}\x{5706}\x{5707}\x{5708}\x{5709}' . '\x{570A}\x{570B}\x{570C}\x{570D}\x{570E}\x{570F}\x{5710}\x{5712}\x{5713}' . '\x{5714}\x{5715}\x{5716}\x{5718}\x{5719}\x{571A}\x{571B}\x{571C}\x{571D}' . '\x{571E}\x{571F}\x{5720}\x{5722}\x{5723}\x{5725}\x{5726}\x{5727}\x{5728}' . '\x{5729}\x{572A}\x{572B}\x{572C}\x{572D}\x{572E}\x{572F}\x{5730}\x{5731}' . '\x{5732}\x{5733}\x{5734}\x{5735}\x{5736}\x{5737}\x{5738}\x{5739}\x{573A}' . '\x{573B}\x{573C}\x{573E}\x{573F}\x{5740}\x{5741}\x{5742}\x{5744}\x{5745}' . '\x{5746}\x{5747}\x{5749}\x{574A}\x{574B}\x{574C}\x{574D}\x{574E}\x{574F}' . '\x{5750}\x{5751}\x{5752}\x{5753}\x{5754}\x{5757}\x{5759}\x{575A}\x{575B}' . '\x{575C}\x{575D}\x{575E}\x{575F}\x{5760}\x{5761}\x{5762}\x{5764}\x{5765}' . '\x{5766}\x{5767}\x{5768}\x{5769}\x{576A}\x{576B}\x{576C}\x{576D}\x{576F}' . '\x{5770}\x{5771}\x{5772}\x{5773}\x{5774}\x{5775}\x{5776}\x{5777}\x{5779}' . '\x{577A}\x{577B}\x{577C}\x{577D}\x{577E}\x{577F}\x{5780}\x{5782}\x{5783}' . '\x{5784}\x{5785}\x{5786}\x{5788}\x{5789}\x{578A}\x{578B}\x{578C}\x{578D}' . '\x{578E}\x{578F}\x{5790}\x{5791}\x{5792}\x{5793}\x{5794}\x{5795}\x{5797}' . '\x{5798}\x{5799}\x{579A}\x{579B}\x{579C}\x{579D}\x{579E}\x{579F}\x{57A0}' . '\x{57A1}\x{57A2}\x{57A3}\x{57A4}\x{57A5}\x{57A6}\x{57A7}\x{57A9}\x{57AA}' . '\x{57AB}\x{57AC}\x{57AD}\x{57AE}\x{57AF}\x{57B0}\x{57B1}\x{57B2}\x{57B3}' . '\x{57B4}\x{57B5}\x{57B6}\x{57B7}\x{57B8}\x{57B9}\x{57BA}\x{57BB}\x{57BC}' . '\x{57BD}\x{57BE}\x{57BF}\x{57C0}\x{57C1}\x{57C2}\x{57C3}\x{57C4}\x{57C5}' . '\x{57C6}\x{57C7}\x{57C8}\x{57C9}\x{57CB}\x{57CC}\x{57CD}\x{57CE}\x{57CF}' . '\x{57D0}\x{57D2}\x{57D3}\x{57D4}\x{57D5}\x{57D6}\x{57D8}\x{57D9}\x{57DA}' . '\x{57DC}\x{57DD}\x{57DF}\x{57E0}\x{57E1}\x{57E2}\x{57E3}\x{57E4}\x{57E5}' . '\x{57E6}\x{57E7}\x{57E8}\x{57E9}\x{57EA}\x{57EB}\x{57EC}\x{57ED}\x{57EE}' . '\x{57EF}\x{57F0}\x{57F1}\x{57F2}\x{57F3}\x{57F4}\x{57F5}\x{57F6}\x{57F7}' . '\x{57F8}\x{57F9}\x{57FA}\x{57FB}\x{57FC}\x{57FD}\x{57FE}\x{57FF}\x{5800}' . '\x{5801}\x{5802}\x{5803}\x{5804}\x{5805}\x{5806}\x{5807}\x{5808}\x{5809}' . '\x{580A}\x{580B}\x{580C}\x{580D}\x{580E}\x{580F}\x{5810}\x{5811}\x{5812}' . '\x{5813}\x{5814}\x{5815}\x{5816}\x{5819}\x{581A}\x{581B}\x{581C}\x{581D}' . '\x{581E}\x{581F}\x{5820}\x{5821}\x{5822}\x{5823}\x{5824}\x{5825}\x{5826}' . '\x{5827}\x{5828}\x{5829}\x{582A}\x{582B}\x{582C}\x{582D}\x{582E}\x{582F}' . '\x{5830}\x{5831}\x{5832}\x{5833}\x{5834}\x{5835}\x{5836}\x{5837}\x{5838}' . '\x{5839}\x{583A}\x{583B}\x{583C}\x{583D}\x{583E}\x{583F}\x{5840}\x{5842}' . '\x{5843}\x{5844}\x{5845}\x{5846}\x{5847}\x{5848}\x{5849}\x{584A}\x{584B}' . '\x{584C}\x{584D}\x{584E}\x{584F}\x{5851}\x{5852}\x{5853}\x{5854}\x{5855}' . '\x{5857}\x{5858}\x{5859}\x{585A}\x{585B}\x{585C}\x{585D}\x{585E}\x{585F}' . '\x{5861}\x{5862}\x{5863}\x{5864}\x{5865}\x{5868}\x{5869}\x{586A}\x{586B}' . '\x{586C}\x{586D}\x{586E}\x{586F}\x{5870}\x{5871}\x{5872}\x{5873}\x{5874}' . '\x{5875}\x{5876}\x{5878}\x{5879}\x{587A}\x{587B}\x{587C}\x{587D}\x{587E}' . '\x{587F}\x{5880}\x{5881}\x{5882}\x{5883}\x{5884}\x{5885}\x{5886}\x{5887}' . '\x{5888}\x{5889}\x{588A}\x{588B}\x{588C}\x{588D}\x{588E}\x{588F}\x{5890}' . '\x{5891}\x{5892}\x{5893}\x{5894}\x{5896}\x{5897}\x{5898}\x{5899}\x{589A}' . '\x{589B}\x{589C}\x{589D}\x{589E}\x{589F}\x{58A0}\x{58A1}\x{58A2}\x{58A3}' . '\x{58A4}\x{58A5}\x{58A6}\x{58A7}\x{58A8}\x{58A9}\x{58AB}\x{58AC}\x{58AD}' . '\x{58AE}\x{58AF}\x{58B0}\x{58B1}\x{58B2}\x{58B3}\x{58B4}\x{58B7}\x{58B8}' . '\x{58B9}\x{58BA}\x{58BB}\x{58BC}\x{58BD}\x{58BE}\x{58BF}\x{58C1}\x{58C2}' . '\x{58C5}\x{58C6}\x{58C7}\x{58C8}\x{58C9}\x{58CA}\x{58CB}\x{58CE}\x{58CF}' . '\x{58D1}\x{58D2}\x{58D3}\x{58D4}\x{58D5}\x{58D6}\x{58D7}\x{58D8}\x{58D9}' . '\x{58DA}\x{58DB}\x{58DD}\x{58DE}\x{58DF}\x{58E0}\x{58E2}\x{58E3}\x{58E4}' . '\x{58E5}\x{58E7}\x{58E8}\x{58E9}\x{58EA}\x{58EB}\x{58EC}\x{58ED}\x{58EE}' . '\x{58EF}\x{58F0}\x{58F1}\x{58F2}\x{58F3}\x{58F4}\x{58F6}\x{58F7}\x{58F8}' . '\x{58F9}\x{58FA}\x{58FB}\x{58FC}\x{58FD}\x{58FE}\x{58FF}\x{5900}\x{5902}' . '\x{5903}\x{5904}\x{5906}\x{5907}\x{5909}\x{590A}\x{590B}\x{590C}\x{590D}' . '\x{590E}\x{590F}\x{5910}\x{5912}\x{5914}\x{5915}\x{5916}\x{5917}\x{5918}' . '\x{5919}\x{591A}\x{591B}\x{591C}\x{591D}\x{591E}\x{591F}\x{5920}\x{5921}' . '\x{5922}\x{5924}\x{5925}\x{5926}\x{5927}\x{5928}\x{5929}\x{592A}\x{592B}' . '\x{592C}\x{592D}\x{592E}\x{592F}\x{5930}\x{5931}\x{5932}\x{5934}\x{5935}' . '\x{5937}\x{5938}\x{5939}\x{593A}\x{593B}\x{593C}\x{593D}\x{593E}\x{593F}' . '\x{5940}\x{5941}\x{5942}\x{5943}\x{5944}\x{5945}\x{5946}\x{5947}\x{5948}' . '\x{5949}\x{594A}\x{594B}\x{594C}\x{594D}\x{594E}\x{594F}\x{5950}\x{5951}' . '\x{5952}\x{5953}\x{5954}\x{5955}\x{5956}\x{5957}\x{5958}\x{595A}\x{595C}' . '\x{595D}\x{595E}\x{595F}\x{5960}\x{5961}\x{5962}\x{5963}\x{5964}\x{5965}' . '\x{5966}\x{5967}\x{5968}\x{5969}\x{596A}\x{596B}\x{596C}\x{596D}\x{596E}' . '\x{596F}\x{5970}\x{5971}\x{5972}\x{5973}\x{5974}\x{5975}\x{5976}\x{5977}' . '\x{5978}\x{5979}\x{597A}\x{597B}\x{597C}\x{597D}\x{597E}\x{597F}\x{5980}' . '\x{5981}\x{5982}\x{5983}\x{5984}\x{5985}\x{5986}\x{5987}\x{5988}\x{5989}' . '\x{598A}\x{598B}\x{598C}\x{598D}\x{598E}\x{598F}\x{5990}\x{5991}\x{5992}' . '\x{5993}\x{5994}\x{5995}\x{5996}\x{5997}\x{5998}\x{5999}\x{599A}\x{599C}' . '\x{599D}\x{599E}\x{599F}\x{59A0}\x{59A1}\x{59A2}\x{59A3}\x{59A4}\x{59A5}' . '\x{59A6}\x{59A7}\x{59A8}\x{59A9}\x{59AA}\x{59AB}\x{59AC}\x{59AD}\x{59AE}' . '\x{59AF}\x{59B0}\x{59B1}\x{59B2}\x{59B3}\x{59B4}\x{59B5}\x{59B6}\x{59B8}' . '\x{59B9}\x{59BA}\x{59BB}\x{59BC}\x{59BD}\x{59BE}\x{59BF}\x{59C0}\x{59C1}' . '\x{59C2}\x{59C3}\x{59C4}\x{59C5}\x{59C6}\x{59C7}\x{59C8}\x{59C9}\x{59CA}' . '\x{59CB}\x{59CC}\x{59CD}\x{59CE}\x{59CF}\x{59D0}\x{59D1}\x{59D2}\x{59D3}' . '\x{59D4}\x{59D5}\x{59D6}\x{59D7}\x{59D8}\x{59D9}\x{59DA}\x{59DB}\x{59DC}' . '\x{59DD}\x{59DE}\x{59DF}\x{59E0}\x{59E1}\x{59E2}\x{59E3}\x{59E4}\x{59E5}' . '\x{59E6}\x{59E8}\x{59E9}\x{59EA}\x{59EB}\x{59EC}\x{59ED}\x{59EE}\x{59EF}' . '\x{59F0}\x{59F1}\x{59F2}\x{59F3}\x{59F4}\x{59F5}\x{59F6}\x{59F7}\x{59F8}' . '\x{59F9}\x{59FA}\x{59FB}\x{59FC}\x{59FD}\x{59FE}\x{59FF}\x{5A00}\x{5A01}' . '\x{5A02}\x{5A03}\x{5A04}\x{5A05}\x{5A06}\x{5A07}\x{5A08}\x{5A09}\x{5A0A}' . '\x{5A0B}\x{5A0C}\x{5A0D}\x{5A0E}\x{5A0F}\x{5A10}\x{5A11}\x{5A12}\x{5A13}' . '\x{5A14}\x{5A15}\x{5A16}\x{5A17}\x{5A18}\x{5A19}\x{5A1A}\x{5A1B}\x{5A1C}' . '\x{5A1D}\x{5A1E}\x{5A1F}\x{5A20}\x{5A21}\x{5A22}\x{5A23}\x{5A25}\x{5A27}' . '\x{5A28}\x{5A29}\x{5A2A}\x{5A2B}\x{5A2D}\x{5A2E}\x{5A2F}\x{5A31}\x{5A32}' . '\x{5A33}\x{5A34}\x{5A35}\x{5A36}\x{5A37}\x{5A38}\x{5A39}\x{5A3A}\x{5A3B}' . '\x{5A3C}\x{5A3D}\x{5A3E}\x{5A3F}\x{5A40}\x{5A41}\x{5A42}\x{5A43}\x{5A44}' . '\x{5A45}\x{5A46}\x{5A47}\x{5A48}\x{5A49}\x{5A4A}\x{5A4B}\x{5A4C}\x{5A4D}' . '\x{5A4E}\x{5A4F}\x{5A50}\x{5A51}\x{5A52}\x{5A53}\x{5A55}\x{5A56}\x{5A57}' . '\x{5A58}\x{5A5A}\x{5A5B}\x{5A5C}\x{5A5D}\x{5A5E}\x{5A5F}\x{5A60}\x{5A61}' . '\x{5A62}\x{5A63}\x{5A64}\x{5A65}\x{5A66}\x{5A67}\x{5A68}\x{5A69}\x{5A6A}' . '\x{5A6B}\x{5A6C}\x{5A6D}\x{5A6E}\x{5A70}\x{5A72}\x{5A73}\x{5A74}\x{5A75}' . '\x{5A76}\x{5A77}\x{5A78}\x{5A79}\x{5A7A}\x{5A7B}\x{5A7C}\x{5A7D}\x{5A7E}' . '\x{5A7F}\x{5A80}\x{5A81}\x{5A82}\x{5A83}\x{5A84}\x{5A85}\x{5A86}\x{5A88}' . '\x{5A89}\x{5A8A}\x{5A8B}\x{5A8C}\x{5A8E}\x{5A8F}\x{5A90}\x{5A91}\x{5A92}' . '\x{5A93}\x{5A94}\x{5A95}\x{5A96}\x{5A97}\x{5A98}\x{5A99}\x{5A9A}\x{5A9B}' . '\x{5A9C}\x{5A9D}\x{5A9E}\x{5A9F}\x{5AA0}\x{5AA1}\x{5AA2}\x{5AA3}\x{5AA4}' . '\x{5AA5}\x{5AA6}\x{5AA7}\x{5AA8}\x{5AA9}\x{5AAA}\x{5AAC}\x{5AAD}\x{5AAE}' . '\x{5AAF}\x{5AB0}\x{5AB1}\x{5AB2}\x{5AB3}\x{5AB4}\x{5AB5}\x{5AB6}\x{5AB7}' . '\x{5AB8}\x{5AB9}\x{5ABA}\x{5ABB}\x{5ABC}\x{5ABD}\x{5ABE}\x{5ABF}\x{5AC0}' . '\x{5AC1}\x{5AC2}\x{5AC3}\x{5AC4}\x{5AC5}\x{5AC6}\x{5AC7}\x{5AC8}\x{5AC9}' . '\x{5ACA}\x{5ACB}\x{5ACC}\x{5ACD}\x{5ACE}\x{5ACF}\x{5AD1}\x{5AD2}\x{5AD4}' . '\x{5AD5}\x{5AD6}\x{5AD7}\x{5AD8}\x{5AD9}\x{5ADA}\x{5ADB}\x{5ADC}\x{5ADD}' . '\x{5ADE}\x{5ADF}\x{5AE0}\x{5AE1}\x{5AE2}\x{5AE3}\x{5AE4}\x{5AE5}\x{5AE6}' . '\x{5AE7}\x{5AE8}\x{5AE9}\x{5AEA}\x{5AEB}\x{5AEC}\x{5AED}\x{5AEE}\x{5AF1}' . '\x{5AF2}\x{5AF3}\x{5AF4}\x{5AF5}\x{5AF6}\x{5AF7}\x{5AF8}\x{5AF9}\x{5AFA}' . '\x{5AFB}\x{5AFC}\x{5AFD}\x{5AFE}\x{5AFF}\x{5B00}\x{5B01}\x{5B02}\x{5B03}' . '\x{5B04}\x{5B05}\x{5B06}\x{5B07}\x{5B08}\x{5B09}\x{5B0B}\x{5B0C}\x{5B0E}' . '\x{5B0F}\x{5B10}\x{5B11}\x{5B12}\x{5B13}\x{5B14}\x{5B15}\x{5B16}\x{5B17}' . '\x{5B18}\x{5B19}\x{5B1A}\x{5B1B}\x{5B1C}\x{5B1D}\x{5B1E}\x{5B1F}\x{5B20}' . '\x{5B21}\x{5B22}\x{5B23}\x{5B24}\x{5B25}\x{5B26}\x{5B27}\x{5B28}\x{5B29}' . '\x{5B2A}\x{5B2B}\x{5B2C}\x{5B2D}\x{5B2E}\x{5B2F}\x{5B30}\x{5B31}\x{5B32}' . '\x{5B33}\x{5B34}\x{5B35}\x{5B36}\x{5B37}\x{5B38}\x{5B3A}\x{5B3B}\x{5B3C}' . '\x{5B3D}\x{5B3E}\x{5B3F}\x{5B40}\x{5B41}\x{5B42}\x{5B43}\x{5B44}\x{5B45}' . '\x{5B47}\x{5B48}\x{5B49}\x{5B4A}\x{5B4B}\x{5B4C}\x{5B4D}\x{5B4E}\x{5B50}' . '\x{5B51}\x{5B53}\x{5B54}\x{5B55}\x{5B56}\x{5B57}\x{5B58}\x{5B59}\x{5B5A}' . '\x{5B5B}\x{5B5C}\x{5B5D}\x{5B5E}\x{5B5F}\x{5B62}\x{5B63}\x{5B64}\x{5B65}' . '\x{5B66}\x{5B67}\x{5B68}\x{5B69}\x{5B6A}\x{5B6B}\x{5B6C}\x{5B6D}\x{5B6E}' . '\x{5B70}\x{5B71}\x{5B72}\x{5B73}\x{5B74}\x{5B75}\x{5B76}\x{5B77}\x{5B78}' . '\x{5B7A}\x{5B7B}\x{5B7C}\x{5B7D}\x{5B7F}\x{5B80}\x{5B81}\x{5B82}\x{5B83}' . '\x{5B84}\x{5B85}\x{5B87}\x{5B88}\x{5B89}\x{5B8A}\x{5B8B}\x{5B8C}\x{5B8D}' . '\x{5B8E}\x{5B8F}\x{5B91}\x{5B92}\x{5B93}\x{5B94}\x{5B95}\x{5B96}\x{5B97}' . '\x{5B98}\x{5B99}\x{5B9A}\x{5B9B}\x{5B9C}\x{5B9D}\x{5B9E}\x{5B9F}\x{5BA0}' . '\x{5BA1}\x{5BA2}\x{5BA3}\x{5BA4}\x{5BA5}\x{5BA6}\x{5BA7}\x{5BA8}\x{5BAA}' . '\x{5BAB}\x{5BAC}\x{5BAD}\x{5BAE}\x{5BAF}\x{5BB0}\x{5BB1}\x{5BB3}\x{5BB4}' . '\x{5BB5}\x{5BB6}\x{5BB8}\x{5BB9}\x{5BBA}\x{5BBB}\x{5BBD}\x{5BBE}\x{5BBF}' . '\x{5BC0}\x{5BC1}\x{5BC2}\x{5BC3}\x{5BC4}\x{5BC5}\x{5BC6}\x{5BC7}\x{5BCA}' . '\x{5BCB}\x{5BCC}\x{5BCD}\x{5BCE}\x{5BCF}\x{5BD0}\x{5BD1}\x{5BD2}\x{5BD3}' . '\x{5BD4}\x{5BD5}\x{5BD6}\x{5BD8}\x{5BD9}\x{5BDB}\x{5BDC}\x{5BDD}\x{5BDE}' . '\x{5BDF}\x{5BE0}\x{5BE1}\x{5BE2}\x{5BE3}\x{5BE4}\x{5BE5}\x{5BE6}\x{5BE7}' . '\x{5BE8}\x{5BE9}\x{5BEA}\x{5BEB}\x{5BEC}\x{5BED}\x{5BEE}\x{5BEF}\x{5BF0}' . '\x{5BF1}\x{5BF2}\x{5BF3}\x{5BF4}\x{5BF5}\x{5BF6}\x{5BF7}\x{5BF8}\x{5BF9}' . '\x{5BFA}\x{5BFB}\x{5BFC}\x{5BFD}\x{5BFF}\x{5C01}\x{5C03}\x{5C04}\x{5C05}' . '\x{5C06}\x{5C07}\x{5C08}\x{5C09}\x{5C0A}\x{5C0B}\x{5C0C}\x{5C0D}\x{5C0E}' . '\x{5C0F}\x{5C10}\x{5C11}\x{5C12}\x{5C13}\x{5C14}\x{5C15}\x{5C16}\x{5C17}' . '\x{5C18}\x{5C19}\x{5C1A}\x{5C1C}\x{5C1D}\x{5C1E}\x{5C1F}\x{5C20}\x{5C21}' . '\x{5C22}\x{5C24}\x{5C25}\x{5C27}\x{5C28}\x{5C2A}\x{5C2B}\x{5C2C}\x{5C2D}' . '\x{5C2E}\x{5C2F}\x{5C30}\x{5C31}\x{5C32}\x{5C33}\x{5C34}\x{5C35}\x{5C37}' . '\x{5C38}\x{5C39}\x{5C3A}\x{5C3B}\x{5C3C}\x{5C3D}\x{5C3E}\x{5C3F}\x{5C40}' . '\x{5C41}\x{5C42}\x{5C43}\x{5C44}\x{5C45}\x{5C46}\x{5C47}\x{5C48}\x{5C49}' . '\x{5C4A}\x{5C4B}\x{5C4C}\x{5C4D}\x{5C4E}\x{5C4F}\x{5C50}\x{5C51}\x{5C52}' . '\x{5C53}\x{5C54}\x{5C55}\x{5C56}\x{5C57}\x{5C58}\x{5C59}\x{5C5B}\x{5C5C}' . '\x{5C5D}\x{5C5E}\x{5C5F}\x{5C60}\x{5C61}\x{5C62}\x{5C63}\x{5C64}\x{5C65}' . '\x{5C66}\x{5C67}\x{5C68}\x{5C69}\x{5C6A}\x{5C6B}\x{5C6C}\x{5C6D}\x{5C6E}' . '\x{5C6F}\x{5C70}\x{5C71}\x{5C72}\x{5C73}\x{5C74}\x{5C75}\x{5C76}\x{5C77}' . '\x{5C78}\x{5C79}\x{5C7A}\x{5C7B}\x{5C7C}\x{5C7D}\x{5C7E}\x{5C7F}\x{5C80}' . '\x{5C81}\x{5C82}\x{5C83}\x{5C84}\x{5C86}\x{5C87}\x{5C88}\x{5C89}\x{5C8A}' . '\x{5C8B}\x{5C8C}\x{5C8D}\x{5C8E}\x{5C8F}\x{5C90}\x{5C91}\x{5C92}\x{5C93}' . '\x{5C94}\x{5C95}\x{5C96}\x{5C97}\x{5C98}\x{5C99}\x{5C9A}\x{5C9B}\x{5C9C}' . '\x{5C9D}\x{5C9E}\x{5C9F}\x{5CA0}\x{5CA1}\x{5CA2}\x{5CA3}\x{5CA4}\x{5CA5}' . '\x{5CA6}\x{5CA7}\x{5CA8}\x{5CA9}\x{5CAA}\x{5CAB}\x{5CAC}\x{5CAD}\x{5CAE}' . '\x{5CAF}\x{5CB0}\x{5CB1}\x{5CB2}\x{5CB3}\x{5CB5}\x{5CB6}\x{5CB7}\x{5CB8}' . '\x{5CBA}\x{5CBB}\x{5CBC}\x{5CBD}\x{5CBE}\x{5CBF}\x{5CC1}\x{5CC2}\x{5CC3}' . '\x{5CC4}\x{5CC5}\x{5CC6}\x{5CC7}\x{5CC8}\x{5CC9}\x{5CCA}\x{5CCB}\x{5CCC}' . '\x{5CCD}\x{5CCE}\x{5CCF}\x{5CD0}\x{5CD1}\x{5CD2}\x{5CD3}\x{5CD4}\x{5CD6}' . '\x{5CD7}\x{5CD8}\x{5CD9}\x{5CDA}\x{5CDB}\x{5CDC}\x{5CDE}\x{5CDF}\x{5CE0}' . '\x{5CE1}\x{5CE2}\x{5CE3}\x{5CE4}\x{5CE5}\x{5CE6}\x{5CE7}\x{5CE8}\x{5CE9}' . '\x{5CEA}\x{5CEB}\x{5CEC}\x{5CED}\x{5CEE}\x{5CEF}\x{5CF0}\x{5CF1}\x{5CF2}' . '\x{5CF3}\x{5CF4}\x{5CF6}\x{5CF7}\x{5CF8}\x{5CF9}\x{5CFA}\x{5CFB}\x{5CFC}' . '\x{5CFD}\x{5CFE}\x{5CFF}\x{5D00}\x{5D01}\x{5D02}\x{5D03}\x{5D04}\x{5D05}' . '\x{5D06}\x{5D07}\x{5D08}\x{5D09}\x{5D0A}\x{5D0B}\x{5D0C}\x{5D0D}\x{5D0E}' . '\x{5D0F}\x{5D10}\x{5D11}\x{5D12}\x{5D13}\x{5D14}\x{5D15}\x{5D16}\x{5D17}' . '\x{5D18}\x{5D19}\x{5D1A}\x{5D1B}\x{5D1C}\x{5D1D}\x{5D1E}\x{5D1F}\x{5D20}' . '\x{5D21}\x{5D22}\x{5D23}\x{5D24}\x{5D25}\x{5D26}\x{5D27}\x{5D28}\x{5D29}' . '\x{5D2A}\x{5D2C}\x{5D2D}\x{5D2E}\x{5D30}\x{5D31}\x{5D32}\x{5D33}\x{5D34}' . '\x{5D35}\x{5D36}\x{5D37}\x{5D38}\x{5D39}\x{5D3A}\x{5D3C}\x{5D3D}\x{5D3E}' . '\x{5D3F}\x{5D40}\x{5D41}\x{5D42}\x{5D43}\x{5D44}\x{5D45}\x{5D46}\x{5D47}' . '\x{5D48}\x{5D49}\x{5D4A}\x{5D4B}\x{5D4C}\x{5D4D}\x{5D4E}\x{5D4F}\x{5D50}' . '\x{5D51}\x{5D52}\x{5D54}\x{5D55}\x{5D56}\x{5D58}\x{5D59}\x{5D5A}\x{5D5B}' . '\x{5D5D}\x{5D5E}\x{5D5F}\x{5D61}\x{5D62}\x{5D63}\x{5D64}\x{5D65}\x{5D66}' . '\x{5D67}\x{5D68}\x{5D69}\x{5D6A}\x{5D6B}\x{5D6C}\x{5D6D}\x{5D6E}\x{5D6F}' . '\x{5D70}\x{5D71}\x{5D72}\x{5D73}\x{5D74}\x{5D75}\x{5D76}\x{5D77}\x{5D78}' . '\x{5D79}\x{5D7A}\x{5D7B}\x{5D7C}\x{5D7D}\x{5D7E}\x{5D7F}\x{5D80}\x{5D81}' . '\x{5D82}\x{5D84}\x{5D85}\x{5D86}\x{5D87}\x{5D88}\x{5D89}\x{5D8A}\x{5D8B}' . '\x{5D8C}\x{5D8D}\x{5D8E}\x{5D8F}\x{5D90}\x{5D91}\x{5D92}\x{5D93}\x{5D94}' . '\x{5D95}\x{5D97}\x{5D98}\x{5D99}\x{5D9A}\x{5D9B}\x{5D9C}\x{5D9D}\x{5D9E}' . '\x{5D9F}\x{5DA0}\x{5DA1}\x{5DA2}\x{5DA5}\x{5DA6}\x{5DA7}\x{5DA8}\x{5DA9}' . '\x{5DAA}\x{5DAC}\x{5DAD}\x{5DAE}\x{5DAF}\x{5DB0}\x{5DB1}\x{5DB2}\x{5DB4}' . '\x{5DB5}\x{5DB6}\x{5DB7}\x{5DB8}\x{5DBA}\x{5DBB}\x{5DBC}\x{5DBD}\x{5DBE}' . '\x{5DBF}\x{5DC0}\x{5DC1}\x{5DC2}\x{5DC3}\x{5DC5}\x{5DC6}\x{5DC7}\x{5DC8}' . '\x{5DC9}\x{5DCA}\x{5DCB}\x{5DCC}\x{5DCD}\x{5DCE}\x{5DCF}\x{5DD0}\x{5DD1}' . '\x{5DD2}\x{5DD3}\x{5DD4}\x{5DD5}\x{5DD6}\x{5DD8}\x{5DD9}\x{5DDB}\x{5DDD}' . '\x{5DDE}\x{5DDF}\x{5DE0}\x{5DE1}\x{5DE2}\x{5DE3}\x{5DE4}\x{5DE5}\x{5DE6}' . '\x{5DE7}\x{5DE8}\x{5DE9}\x{5DEA}\x{5DEB}\x{5DEC}\x{5DED}\x{5DEE}\x{5DEF}' . '\x{5DF0}\x{5DF1}\x{5DF2}\x{5DF3}\x{5DF4}\x{5DF5}\x{5DF7}\x{5DF8}\x{5DF9}' . '\x{5DFA}\x{5DFB}\x{5DFC}\x{5DFD}\x{5DFE}\x{5DFF}\x{5E00}\x{5E01}\x{5E02}' . '\x{5E03}\x{5E04}\x{5E05}\x{5E06}\x{5E07}\x{5E08}\x{5E09}\x{5E0A}\x{5E0B}' . '\x{5E0C}\x{5E0D}\x{5E0E}\x{5E0F}\x{5E10}\x{5E11}\x{5E13}\x{5E14}\x{5E15}' . '\x{5E16}\x{5E17}\x{5E18}\x{5E19}\x{5E1A}\x{5E1B}\x{5E1C}\x{5E1D}\x{5E1E}' . '\x{5E1F}\x{5E20}\x{5E21}\x{5E22}\x{5E23}\x{5E24}\x{5E25}\x{5E26}\x{5E27}' . '\x{5E28}\x{5E29}\x{5E2A}\x{5E2B}\x{5E2C}\x{5E2D}\x{5E2E}\x{5E2F}\x{5E30}' . '\x{5E31}\x{5E32}\x{5E33}\x{5E34}\x{5E35}\x{5E36}\x{5E37}\x{5E38}\x{5E39}' . '\x{5E3A}\x{5E3B}\x{5E3C}\x{5E3D}\x{5E3E}\x{5E40}\x{5E41}\x{5E42}\x{5E43}' . '\x{5E44}\x{5E45}\x{5E46}\x{5E47}\x{5E49}\x{5E4A}\x{5E4B}\x{5E4C}\x{5E4D}' . '\x{5E4E}\x{5E4F}\x{5E50}\x{5E52}\x{5E53}\x{5E54}\x{5E55}\x{5E56}\x{5E57}' . '\x{5E58}\x{5E59}\x{5E5A}\x{5E5B}\x{5E5C}\x{5E5D}\x{5E5E}\x{5E5F}\x{5E60}' . '\x{5E61}\x{5E62}\x{5E63}\x{5E64}\x{5E65}\x{5E66}\x{5E67}\x{5E68}\x{5E69}' . '\x{5E6A}\x{5E6B}\x{5E6C}\x{5E6D}\x{5E6E}\x{5E6F}\x{5E70}\x{5E71}\x{5E72}' . '\x{5E73}\x{5E74}\x{5E75}\x{5E76}\x{5E77}\x{5E78}\x{5E79}\x{5E7A}\x{5E7B}' . '\x{5E7C}\x{5E7D}\x{5E7E}\x{5E7F}\x{5E80}\x{5E81}\x{5E82}\x{5E83}\x{5E84}' . '\x{5E85}\x{5E86}\x{5E87}\x{5E88}\x{5E89}\x{5E8A}\x{5E8B}\x{5E8C}\x{5E8D}' . '\x{5E8E}\x{5E8F}\x{5E90}\x{5E91}\x{5E93}\x{5E94}\x{5E95}\x{5E96}\x{5E97}' . '\x{5E98}\x{5E99}\x{5E9A}\x{5E9B}\x{5E9C}\x{5E9D}\x{5E9E}\x{5E9F}\x{5EA0}' . '\x{5EA1}\x{5EA2}\x{5EA3}\x{5EA4}\x{5EA5}\x{5EA6}\x{5EA7}\x{5EA8}\x{5EA9}' . '\x{5EAA}\x{5EAB}\x{5EAC}\x{5EAD}\x{5EAE}\x{5EAF}\x{5EB0}\x{5EB1}\x{5EB2}' . '\x{5EB3}\x{5EB4}\x{5EB5}\x{5EB6}\x{5EB7}\x{5EB8}\x{5EB9}\x{5EBB}\x{5EBC}' . '\x{5EBD}\x{5EBE}\x{5EBF}\x{5EC1}\x{5EC2}\x{5EC3}\x{5EC4}\x{5EC5}\x{5EC6}' . '\x{5EC7}\x{5EC8}\x{5EC9}\x{5ECA}\x{5ECB}\x{5ECC}\x{5ECD}\x{5ECE}\x{5ECF}' . '\x{5ED0}\x{5ED1}\x{5ED2}\x{5ED3}\x{5ED4}\x{5ED5}\x{5ED6}\x{5ED7}\x{5ED8}' . '\x{5ED9}\x{5EDA}\x{5EDB}\x{5EDC}\x{5EDD}\x{5EDE}\x{5EDF}\x{5EE0}\x{5EE1}' . '\x{5EE2}\x{5EE3}\x{5EE4}\x{5EE5}\x{5EE6}\x{5EE7}\x{5EE8}\x{5EE9}\x{5EEA}' . '\x{5EEC}\x{5EED}\x{5EEE}\x{5EEF}\x{5EF0}\x{5EF1}\x{5EF2}\x{5EF3}\x{5EF4}' . '\x{5EF5}\x{5EF6}\x{5EF7}\x{5EF8}\x{5EFA}\x{5EFB}\x{5EFC}\x{5EFD}\x{5EFE}' . '\x{5EFF}\x{5F00}\x{5F01}\x{5F02}\x{5F03}\x{5F04}\x{5F05}\x{5F06}\x{5F07}' . '\x{5F08}\x{5F0A}\x{5F0B}\x{5F0C}\x{5F0D}\x{5F0F}\x{5F11}\x{5F12}\x{5F13}' . '\x{5F14}\x{5F15}\x{5F16}\x{5F17}\x{5F18}\x{5F19}\x{5F1A}\x{5F1B}\x{5F1C}' . '\x{5F1D}\x{5F1E}\x{5F1F}\x{5F20}\x{5F21}\x{5F22}\x{5F23}\x{5F24}\x{5F25}' . '\x{5F26}\x{5F27}\x{5F28}\x{5F29}\x{5F2A}\x{5F2B}\x{5F2C}\x{5F2D}\x{5F2E}' . '\x{5F2F}\x{5F30}\x{5F31}\x{5F32}\x{5F33}\x{5F34}\x{5F35}\x{5F36}\x{5F37}' . '\x{5F38}\x{5F39}\x{5F3A}\x{5F3C}\x{5F3E}\x{5F3F}\x{5F40}\x{5F41}\x{5F42}' . '\x{5F43}\x{5F44}\x{5F45}\x{5F46}\x{5F47}\x{5F48}\x{5F49}\x{5F4A}\x{5F4B}' . '\x{5F4C}\x{5F4D}\x{5F4E}\x{5F4F}\x{5F50}\x{5F51}\x{5F52}\x{5F53}\x{5F54}' . '\x{5F55}\x{5F56}\x{5F57}\x{5F58}\x{5F59}\x{5F5A}\x{5F5B}\x{5F5C}\x{5F5D}' . '\x{5F5E}\x{5F5F}\x{5F60}\x{5F61}\x{5F62}\x{5F63}\x{5F64}\x{5F65}\x{5F66}' . '\x{5F67}\x{5F68}\x{5F69}\x{5F6A}\x{5F6B}\x{5F6C}\x{5F6D}\x{5F6E}\x{5F6F}' . '\x{5F70}\x{5F71}\x{5F72}\x{5F73}\x{5F74}\x{5F75}\x{5F76}\x{5F77}\x{5F78}' . '\x{5F79}\x{5F7A}\x{5F7B}\x{5F7C}\x{5F7D}\x{5F7E}\x{5F7F}\x{5F80}\x{5F81}' . '\x{5F82}\x{5F83}\x{5F84}\x{5F85}\x{5F86}\x{5F87}\x{5F88}\x{5F89}\x{5F8A}' . '\x{5F8B}\x{5F8C}\x{5F8D}\x{5F8E}\x{5F90}\x{5F91}\x{5F92}\x{5F93}\x{5F94}' . '\x{5F95}\x{5F96}\x{5F97}\x{5F98}\x{5F99}\x{5F9B}\x{5F9C}\x{5F9D}\x{5F9E}' . '\x{5F9F}\x{5FA0}\x{5FA1}\x{5FA2}\x{5FA5}\x{5FA6}\x{5FA7}\x{5FA8}\x{5FA9}' . '\x{5FAA}\x{5FAB}\x{5FAC}\x{5FAD}\x{5FAE}\x{5FAF}\x{5FB1}\x{5FB2}\x{5FB3}' . '\x{5FB4}\x{5FB5}\x{5FB6}\x{5FB7}\x{5FB8}\x{5FB9}\x{5FBA}\x{5FBB}\x{5FBC}' . '\x{5FBD}\x{5FBE}\x{5FBF}\x{5FC0}\x{5FC1}\x{5FC3}\x{5FC4}\x{5FC5}\x{5FC6}' . '\x{5FC7}\x{5FC8}\x{5FC9}\x{5FCA}\x{5FCB}\x{5FCC}\x{5FCD}\x{5FCF}\x{5FD0}' . '\x{5FD1}\x{5FD2}\x{5FD3}\x{5FD4}\x{5FD5}\x{5FD6}\x{5FD7}\x{5FD8}\x{5FD9}' . '\x{5FDA}\x{5FDC}\x{5FDD}\x{5FDE}\x{5FE0}\x{5FE1}\x{5FE3}\x{5FE4}\x{5FE5}' . '\x{5FE6}\x{5FE7}\x{5FE8}\x{5FE9}\x{5FEA}\x{5FEB}\x{5FED}\x{5FEE}\x{5FEF}' . '\x{5FF0}\x{5FF1}\x{5FF2}\x{5FF3}\x{5FF4}\x{5FF5}\x{5FF6}\x{5FF7}\x{5FF8}' . '\x{5FF9}\x{5FFA}\x{5FFB}\x{5FFD}\x{5FFE}\x{5FFF}\x{6000}\x{6001}\x{6002}' . '\x{6003}\x{6004}\x{6005}\x{6006}\x{6007}\x{6008}\x{6009}\x{600A}\x{600B}' . '\x{600C}\x{600D}\x{600E}\x{600F}\x{6010}\x{6011}\x{6012}\x{6013}\x{6014}' . '\x{6015}\x{6016}\x{6017}\x{6018}\x{6019}\x{601A}\x{601B}\x{601C}\x{601D}' . '\x{601E}\x{601F}\x{6020}\x{6021}\x{6022}\x{6024}\x{6025}\x{6026}\x{6027}' . '\x{6028}\x{6029}\x{602A}\x{602B}\x{602C}\x{602D}\x{602E}\x{602F}\x{6030}' . '\x{6031}\x{6032}\x{6033}\x{6034}\x{6035}\x{6036}\x{6037}\x{6038}\x{6039}' . '\x{603A}\x{603B}\x{603C}\x{603D}\x{603E}\x{603F}\x{6040}\x{6041}\x{6042}' . '\x{6043}\x{6044}\x{6045}\x{6046}\x{6047}\x{6048}\x{6049}\x{604A}\x{604B}' . '\x{604C}\x{604D}\x{604E}\x{604F}\x{6050}\x{6051}\x{6052}\x{6053}\x{6054}' . '\x{6055}\x{6057}\x{6058}\x{6059}\x{605A}\x{605B}\x{605C}\x{605D}\x{605E}' . '\x{605F}\x{6062}\x{6063}\x{6064}\x{6065}\x{6066}\x{6067}\x{6068}\x{6069}' . '\x{606A}\x{606B}\x{606C}\x{606D}\x{606E}\x{606F}\x{6070}\x{6072}\x{6073}' . '\x{6075}\x{6076}\x{6077}\x{6078}\x{6079}\x{607A}\x{607B}\x{607C}\x{607D}' . '\x{607E}\x{607F}\x{6080}\x{6081}\x{6082}\x{6083}\x{6084}\x{6085}\x{6086}' . '\x{6087}\x{6088}\x{6089}\x{608A}\x{608B}\x{608C}\x{608D}\x{608E}\x{608F}' . '\x{6090}\x{6092}\x{6094}\x{6095}\x{6096}\x{6097}\x{6098}\x{6099}\x{609A}' . '\x{609B}\x{609C}\x{609D}\x{609E}\x{609F}\x{60A0}\x{60A1}\x{60A2}\x{60A3}' . '\x{60A4}\x{60A6}\x{60A7}\x{60A8}\x{60AA}\x{60AB}\x{60AC}\x{60AD}\x{60AE}' . '\x{60AF}\x{60B0}\x{60B1}\x{60B2}\x{60B3}\x{60B4}\x{60B5}\x{60B6}\x{60B7}' . '\x{60B8}\x{60B9}\x{60BA}\x{60BB}\x{60BC}\x{60BD}\x{60BE}\x{60BF}\x{60C0}' . '\x{60C1}\x{60C2}\x{60C3}\x{60C4}\x{60C5}\x{60C6}\x{60C7}\x{60C8}\x{60C9}' . '\x{60CA}\x{60CB}\x{60CC}\x{60CD}\x{60CE}\x{60CF}\x{60D0}\x{60D1}\x{60D3}' . '\x{60D4}\x{60D5}\x{60D7}\x{60D8}\x{60D9}\x{60DA}\x{60DB}\x{60DC}\x{60DD}' . '\x{60DF}\x{60E0}\x{60E1}\x{60E2}\x{60E4}\x{60E6}\x{60E7}\x{60E8}\x{60E9}' . '\x{60EA}\x{60EB}\x{60EC}\x{60ED}\x{60EE}\x{60EF}\x{60F0}\x{60F1}\x{60F2}' . '\x{60F3}\x{60F4}\x{60F5}\x{60F6}\x{60F7}\x{60F8}\x{60F9}\x{60FA}\x{60FB}' . '\x{60FC}\x{60FE}\x{60FF}\x{6100}\x{6101}\x{6103}\x{6104}\x{6105}\x{6106}' . '\x{6108}\x{6109}\x{610A}\x{610B}\x{610C}\x{610D}\x{610E}\x{610F}\x{6110}' . '\x{6112}\x{6113}\x{6114}\x{6115}\x{6116}\x{6117}\x{6118}\x{6119}\x{611A}' . '\x{611B}\x{611C}\x{611D}\x{611F}\x{6120}\x{6122}\x{6123}\x{6124}\x{6125}' . '\x{6126}\x{6127}\x{6128}\x{6129}\x{612A}\x{612B}\x{612C}\x{612D}\x{612E}' . '\x{612F}\x{6130}\x{6132}\x{6134}\x{6136}\x{6137}\x{613A}\x{613B}\x{613C}' . '\x{613D}\x{613E}\x{613F}\x{6140}\x{6141}\x{6142}\x{6143}\x{6144}\x{6145}' . '\x{6146}\x{6147}\x{6148}\x{6149}\x{614A}\x{614B}\x{614C}\x{614D}\x{614E}' . '\x{614F}\x{6150}\x{6151}\x{6152}\x{6153}\x{6154}\x{6155}\x{6156}\x{6157}' . '\x{6158}\x{6159}\x{615A}\x{615B}\x{615C}\x{615D}\x{615E}\x{615F}\x{6161}' . '\x{6162}\x{6163}\x{6164}\x{6165}\x{6166}\x{6167}\x{6168}\x{6169}\x{616A}' . '\x{616B}\x{616C}\x{616D}\x{616E}\x{6170}\x{6171}\x{6172}\x{6173}\x{6174}' . '\x{6175}\x{6176}\x{6177}\x{6178}\x{6179}\x{617A}\x{617C}\x{617E}\x{6180}' . '\x{6181}\x{6182}\x{6183}\x{6184}\x{6185}\x{6187}\x{6188}\x{6189}\x{618A}' . '\x{618B}\x{618C}\x{618D}\x{618E}\x{618F}\x{6190}\x{6191}\x{6192}\x{6193}' . '\x{6194}\x{6195}\x{6196}\x{6198}\x{6199}\x{619A}\x{619B}\x{619D}\x{619E}' . '\x{619F}\x{61A0}\x{61A1}\x{61A2}\x{61A3}\x{61A4}\x{61A5}\x{61A6}\x{61A7}' . '\x{61A8}\x{61A9}\x{61AA}\x{61AB}\x{61AC}\x{61AD}\x{61AE}\x{61AF}\x{61B0}' . '\x{61B1}\x{61B2}\x{61B3}\x{61B4}\x{61B5}\x{61B6}\x{61B7}\x{61B8}\x{61BA}' . '\x{61BC}\x{61BD}\x{61BE}\x{61BF}\x{61C0}\x{61C1}\x{61C2}\x{61C3}\x{61C4}' . '\x{61C5}\x{61C6}\x{61C7}\x{61C8}\x{61C9}\x{61CA}\x{61CB}\x{61CC}\x{61CD}' . '\x{61CE}\x{61CF}\x{61D0}\x{61D1}\x{61D2}\x{61D4}\x{61D6}\x{61D7}\x{61D8}' . '\x{61D9}\x{61DA}\x{61DB}\x{61DC}\x{61DD}\x{61DE}\x{61DF}\x{61E0}\x{61E1}' . '\x{61E2}\x{61E3}\x{61E4}\x{61E5}\x{61E6}\x{61E7}\x{61E8}\x{61E9}\x{61EA}' . '\x{61EB}\x{61ED}\x{61EE}\x{61F0}\x{61F1}\x{61F2}\x{61F3}\x{61F5}\x{61F6}' . '\x{61F7}\x{61F8}\x{61F9}\x{61FA}\x{61FB}\x{61FC}\x{61FD}\x{61FE}\x{61FF}' . '\x{6200}\x{6201}\x{6202}\x{6203}\x{6204}\x{6206}\x{6207}\x{6208}\x{6209}' . '\x{620A}\x{620B}\x{620C}\x{620D}\x{620E}\x{620F}\x{6210}\x{6211}\x{6212}' . '\x{6213}\x{6214}\x{6215}\x{6216}\x{6217}\x{6218}\x{6219}\x{621A}\x{621B}' . '\x{621C}\x{621D}\x{621E}\x{621F}\x{6220}\x{6221}\x{6222}\x{6223}\x{6224}' . '\x{6225}\x{6226}\x{6227}\x{6228}\x{6229}\x{622A}\x{622B}\x{622C}\x{622D}' . '\x{622E}\x{622F}\x{6230}\x{6231}\x{6232}\x{6233}\x{6234}\x{6236}\x{6237}' . '\x{6238}\x{623A}\x{623B}\x{623C}\x{623D}\x{623E}\x{623F}\x{6240}\x{6241}' . '\x{6242}\x{6243}\x{6244}\x{6245}\x{6246}\x{6247}\x{6248}\x{6249}\x{624A}' . '\x{624B}\x{624C}\x{624D}\x{624E}\x{624F}\x{6250}\x{6251}\x{6252}\x{6253}' . '\x{6254}\x{6255}\x{6256}\x{6258}\x{6259}\x{625A}\x{625B}\x{625C}\x{625D}' . '\x{625E}\x{625F}\x{6260}\x{6261}\x{6262}\x{6263}\x{6264}\x{6265}\x{6266}' . '\x{6267}\x{6268}\x{6269}\x{626A}\x{626B}\x{626C}\x{626D}\x{626E}\x{626F}' . '\x{6270}\x{6271}\x{6272}\x{6273}\x{6274}\x{6275}\x{6276}\x{6277}\x{6278}' . '\x{6279}\x{627A}\x{627B}\x{627C}\x{627D}\x{627E}\x{627F}\x{6280}\x{6281}' . '\x{6283}\x{6284}\x{6285}\x{6286}\x{6287}\x{6288}\x{6289}\x{628A}\x{628B}' . '\x{628C}\x{628E}\x{628F}\x{6290}\x{6291}\x{6292}\x{6293}\x{6294}\x{6295}' . '\x{6296}\x{6297}\x{6298}\x{6299}\x{629A}\x{629B}\x{629C}\x{629E}\x{629F}' . '\x{62A0}\x{62A1}\x{62A2}\x{62A3}\x{62A4}\x{62A5}\x{62A7}\x{62A8}\x{62A9}' . '\x{62AA}\x{62AB}\x{62AC}\x{62AD}\x{62AE}\x{62AF}\x{62B0}\x{62B1}\x{62B2}' . '\x{62B3}\x{62B4}\x{62B5}\x{62B6}\x{62B7}\x{62B8}\x{62B9}\x{62BA}\x{62BB}' . '\x{62BC}\x{62BD}\x{62BE}\x{62BF}\x{62C0}\x{62C1}\x{62C2}\x{62C3}\x{62C4}' . '\x{62C5}\x{62C6}\x{62C7}\x{62C8}\x{62C9}\x{62CA}\x{62CB}\x{62CC}\x{62CD}' . '\x{62CE}\x{62CF}\x{62D0}\x{62D1}\x{62D2}\x{62D3}\x{62D4}\x{62D5}\x{62D6}' . '\x{62D7}\x{62D8}\x{62D9}\x{62DA}\x{62DB}\x{62DC}\x{62DD}\x{62DF}\x{62E0}' . '\x{62E1}\x{62E2}\x{62E3}\x{62E4}\x{62E5}\x{62E6}\x{62E7}\x{62E8}\x{62E9}' . '\x{62EB}\x{62EC}\x{62ED}\x{62EE}\x{62EF}\x{62F0}\x{62F1}\x{62F2}\x{62F3}' . '\x{62F4}\x{62F5}\x{62F6}\x{62F7}\x{62F8}\x{62F9}\x{62FA}\x{62FB}\x{62FC}' . '\x{62FD}\x{62FE}\x{62FF}\x{6300}\x{6301}\x{6302}\x{6303}\x{6304}\x{6305}' . '\x{6306}\x{6307}\x{6308}\x{6309}\x{630B}\x{630C}\x{630D}\x{630E}\x{630F}' . '\x{6310}\x{6311}\x{6312}\x{6313}\x{6314}\x{6315}\x{6316}\x{6318}\x{6319}' . '\x{631A}\x{631B}\x{631C}\x{631D}\x{631E}\x{631F}\x{6320}\x{6321}\x{6322}' . '\x{6323}\x{6324}\x{6325}\x{6326}\x{6327}\x{6328}\x{6329}\x{632A}\x{632B}' . '\x{632C}\x{632D}\x{632E}\x{632F}\x{6330}\x{6332}\x{6333}\x{6334}\x{6336}' . '\x{6338}\x{6339}\x{633A}\x{633B}\x{633C}\x{633D}\x{633E}\x{6340}\x{6341}' . '\x{6342}\x{6343}\x{6344}\x{6345}\x{6346}\x{6347}\x{6348}\x{6349}\x{634A}' . '\x{634B}\x{634C}\x{634D}\x{634E}\x{634F}\x{6350}\x{6351}\x{6352}\x{6353}' . '\x{6354}\x{6355}\x{6356}\x{6357}\x{6358}\x{6359}\x{635A}\x{635C}\x{635D}' . '\x{635E}\x{635F}\x{6360}\x{6361}\x{6362}\x{6363}\x{6364}\x{6365}\x{6366}' . '\x{6367}\x{6368}\x{6369}\x{636A}\x{636B}\x{636C}\x{636D}\x{636E}\x{636F}' . '\x{6370}\x{6371}\x{6372}\x{6373}\x{6374}\x{6375}\x{6376}\x{6377}\x{6378}' . '\x{6379}\x{637A}\x{637B}\x{637C}\x{637D}\x{637E}\x{6380}\x{6381}\x{6382}' . '\x{6383}\x{6384}\x{6385}\x{6386}\x{6387}\x{6388}\x{6389}\x{638A}\x{638C}' . '\x{638D}\x{638E}\x{638F}\x{6390}\x{6391}\x{6392}\x{6394}\x{6395}\x{6396}' . '\x{6397}\x{6398}\x{6399}\x{639A}\x{639B}\x{639C}\x{639D}\x{639E}\x{639F}' . '\x{63A0}\x{63A1}\x{63A2}\x{63A3}\x{63A4}\x{63A5}\x{63A6}\x{63A7}\x{63A8}' . '\x{63A9}\x{63AA}\x{63AB}\x{63AC}\x{63AD}\x{63AE}\x{63AF}\x{63B0}\x{63B1}' . '\x{63B2}\x{63B3}\x{63B4}\x{63B5}\x{63B6}\x{63B7}\x{63B8}\x{63B9}\x{63BA}' . '\x{63BC}\x{63BD}\x{63BE}\x{63BF}\x{63C0}\x{63C1}\x{63C2}\x{63C3}\x{63C4}' . '\x{63C5}\x{63C6}\x{63C7}\x{63C8}\x{63C9}\x{63CA}\x{63CB}\x{63CC}\x{63CD}' . '\x{63CE}\x{63CF}\x{63D0}\x{63D2}\x{63D3}\x{63D4}\x{63D5}\x{63D6}\x{63D7}' . '\x{63D8}\x{63D9}\x{63DA}\x{63DB}\x{63DC}\x{63DD}\x{63DE}\x{63DF}\x{63E0}' . '\x{63E1}\x{63E2}\x{63E3}\x{63E4}\x{63E5}\x{63E6}\x{63E7}\x{63E8}\x{63E9}' . '\x{63EA}\x{63EB}\x{63EC}\x{63ED}\x{63EE}\x{63EF}\x{63F0}\x{63F1}\x{63F2}' . '\x{63F3}\x{63F4}\x{63F5}\x{63F6}\x{63F7}\x{63F8}\x{63F9}\x{63FA}\x{63FB}' . '\x{63FC}\x{63FD}\x{63FE}\x{63FF}\x{6400}\x{6401}\x{6402}\x{6403}\x{6404}' . '\x{6405}\x{6406}\x{6408}\x{6409}\x{640A}\x{640B}\x{640C}\x{640D}\x{640E}' . '\x{640F}\x{6410}\x{6411}\x{6412}\x{6413}\x{6414}\x{6415}\x{6416}\x{6417}' . '\x{6418}\x{6419}\x{641A}\x{641B}\x{641C}\x{641D}\x{641E}\x{641F}\x{6420}' . '\x{6421}\x{6422}\x{6423}\x{6424}\x{6425}\x{6426}\x{6427}\x{6428}\x{6429}' . '\x{642A}\x{642B}\x{642C}\x{642D}\x{642E}\x{642F}\x{6430}\x{6431}\x{6432}' . '\x{6433}\x{6434}\x{6435}\x{6436}\x{6437}\x{6438}\x{6439}\x{643A}\x{643D}' . '\x{643E}\x{643F}\x{6440}\x{6441}\x{6443}\x{6444}\x{6445}\x{6446}\x{6447}' . '\x{6448}\x{644A}\x{644B}\x{644C}\x{644D}\x{644E}\x{644F}\x{6450}\x{6451}' . '\x{6452}\x{6453}\x{6454}\x{6455}\x{6456}\x{6457}\x{6458}\x{6459}\x{645B}' . '\x{645C}\x{645D}\x{645E}\x{645F}\x{6460}\x{6461}\x{6462}\x{6463}\x{6464}' . '\x{6465}\x{6466}\x{6467}\x{6468}\x{6469}\x{646A}\x{646B}\x{646C}\x{646D}' . '\x{646E}\x{646F}\x{6470}\x{6471}\x{6472}\x{6473}\x{6474}\x{6475}\x{6476}' . '\x{6477}\x{6478}\x{6479}\x{647A}\x{647B}\x{647C}\x{647D}\x{647F}\x{6480}' . '\x{6481}\x{6482}\x{6483}\x{6484}\x{6485}\x{6487}\x{6488}\x{6489}\x{648A}' . '\x{648B}\x{648C}\x{648D}\x{648E}\x{648F}\x{6490}\x{6491}\x{6492}\x{6493}' . '\x{6494}\x{6495}\x{6496}\x{6497}\x{6498}\x{6499}\x{649A}\x{649B}\x{649C}' . '\x{649D}\x{649E}\x{649F}\x{64A0}\x{64A2}\x{64A3}\x{64A4}\x{64A5}\x{64A6}' . '\x{64A7}\x{64A8}\x{64A9}\x{64AA}\x{64AB}\x{64AC}\x{64AD}\x{64AE}\x{64B0}' . '\x{64B1}\x{64B2}\x{64B3}\x{64B4}\x{64B5}\x{64B7}\x{64B8}\x{64B9}\x{64BA}' . '\x{64BB}\x{64BC}\x{64BD}\x{64BE}\x{64BF}\x{64C0}\x{64C1}\x{64C2}\x{64C3}' . '\x{64C4}\x{64C5}\x{64C6}\x{64C7}\x{64C9}\x{64CA}\x{64CB}\x{64CC}\x{64CD}' . '\x{64CE}\x{64CF}\x{64D0}\x{64D1}\x{64D2}\x{64D3}\x{64D4}\x{64D6}\x{64D7}' . '\x{64D8}\x{64D9}\x{64DA}\x{64DB}\x{64DC}\x{64DD}\x{64DE}\x{64DF}\x{64E0}' . '\x{64E2}\x{64E3}\x{64E4}\x{64E6}\x{64E7}\x{64E8}\x{64E9}\x{64EA}\x{64EB}' . '\x{64EC}\x{64ED}\x{64EF}\x{64F0}\x{64F1}\x{64F2}\x{64F3}\x{64F4}\x{64F6}' . '\x{64F7}\x{64F8}\x{64FA}\x{64FB}\x{64FC}\x{64FD}\x{64FE}\x{64FF}\x{6500}' . '\x{6501}\x{6503}\x{6504}\x{6505}\x{6506}\x{6507}\x{6508}\x{6509}\x{650B}' . '\x{650C}\x{650D}\x{650E}\x{650F}\x{6510}\x{6511}\x{6512}\x{6513}\x{6514}' . '\x{6515}\x{6516}\x{6517}\x{6518}\x{6519}\x{651A}\x{651B}\x{651C}\x{651D}' . '\x{651E}\x{6520}\x{6521}\x{6522}\x{6523}\x{6524}\x{6525}\x{6526}\x{6527}' . '\x{6529}\x{652A}\x{652B}\x{652C}\x{652D}\x{652E}\x{652F}\x{6530}\x{6531}' . '\x{6532}\x{6533}\x{6534}\x{6535}\x{6536}\x{6537}\x{6538}\x{6539}\x{653A}' . '\x{653B}\x{653C}\x{653D}\x{653E}\x{653F}\x{6541}\x{6543}\x{6544}\x{6545}' . '\x{6546}\x{6547}\x{6548}\x{6549}\x{654A}\x{654B}\x{654C}\x{654D}\x{654E}' . '\x{654F}\x{6550}\x{6551}\x{6552}\x{6553}\x{6554}\x{6555}\x{6556}\x{6557}' . '\x{6558}\x{6559}\x{655B}\x{655C}\x{655D}\x{655E}\x{6560}\x{6561}\x{6562}' . '\x{6563}\x{6564}\x{6565}\x{6566}\x{6567}\x{6568}\x{6569}\x{656A}\x{656B}' . '\x{656C}\x{656E}\x{656F}\x{6570}\x{6571}\x{6572}\x{6573}\x{6574}\x{6575}' . '\x{6576}\x{6577}\x{6578}\x{6579}\x{657A}\x{657B}\x{657C}\x{657E}\x{657F}' . '\x{6580}\x{6581}\x{6582}\x{6583}\x{6584}\x{6585}\x{6586}\x{6587}\x{6588}' . '\x{6589}\x{658B}\x{658C}\x{658D}\x{658E}\x{658F}\x{6590}\x{6591}\x{6592}' . '\x{6593}\x{6594}\x{6595}\x{6596}\x{6597}\x{6598}\x{6599}\x{659B}\x{659C}' . '\x{659D}\x{659E}\x{659F}\x{65A0}\x{65A1}\x{65A2}\x{65A3}\x{65A4}\x{65A5}' . '\x{65A6}\x{65A7}\x{65A8}\x{65A9}\x{65AA}\x{65AB}\x{65AC}\x{65AD}\x{65AE}' . '\x{65AF}\x{65B0}\x{65B1}\x{65B2}\x{65B3}\x{65B4}\x{65B6}\x{65B7}\x{65B8}' . '\x{65B9}\x{65BA}\x{65BB}\x{65BC}\x{65BD}\x{65BF}\x{65C0}\x{65C1}\x{65C2}' . '\x{65C3}\x{65C4}\x{65C5}\x{65C6}\x{65C7}\x{65CA}\x{65CB}\x{65CC}\x{65CD}' . '\x{65CE}\x{65CF}\x{65D0}\x{65D2}\x{65D3}\x{65D4}\x{65D5}\x{65D6}\x{65D7}' . '\x{65DA}\x{65DB}\x{65DD}\x{65DE}\x{65DF}\x{65E0}\x{65E1}\x{65E2}\x{65E3}' . '\x{65E5}\x{65E6}\x{65E7}\x{65E8}\x{65E9}\x{65EB}\x{65EC}\x{65ED}\x{65EE}' . '\x{65EF}\x{65F0}\x{65F1}\x{65F2}\x{65F3}\x{65F4}\x{65F5}\x{65F6}\x{65F7}' . '\x{65F8}\x{65FA}\x{65FB}\x{65FC}\x{65FD}\x{6600}\x{6601}\x{6602}\x{6603}' . '\x{6604}\x{6605}\x{6606}\x{6607}\x{6608}\x{6609}\x{660A}\x{660B}\x{660C}' . '\x{660D}\x{660E}\x{660F}\x{6610}\x{6611}\x{6612}\x{6613}\x{6614}\x{6615}' . '\x{6616}\x{6618}\x{6619}\x{661A}\x{661B}\x{661C}\x{661D}\x{661F}\x{6620}' . '\x{6621}\x{6622}\x{6623}\x{6624}\x{6625}\x{6626}\x{6627}\x{6628}\x{6629}' . '\x{662A}\x{662B}\x{662D}\x{662E}\x{662F}\x{6630}\x{6631}\x{6632}\x{6633}' . '\x{6634}\x{6635}\x{6636}\x{6639}\x{663A}\x{663C}\x{663D}\x{663E}\x{6640}' . '\x{6641}\x{6642}\x{6643}\x{6644}\x{6645}\x{6646}\x{6647}\x{6649}\x{664A}' . '\x{664B}\x{664C}\x{664E}\x{664F}\x{6650}\x{6651}\x{6652}\x{6653}\x{6654}' . '\x{6655}\x{6656}\x{6657}\x{6658}\x{6659}\x{665A}\x{665B}\x{665C}\x{665D}' . '\x{665E}\x{665F}\x{6661}\x{6662}\x{6664}\x{6665}\x{6666}\x{6668}\x{6669}' . '\x{666A}\x{666B}\x{666C}\x{666D}\x{666E}\x{666F}\x{6670}\x{6671}\x{6672}' . '\x{6673}\x{6674}\x{6675}\x{6676}\x{6677}\x{6678}\x{6679}\x{667A}\x{667B}' . '\x{667C}\x{667D}\x{667E}\x{667F}\x{6680}\x{6681}\x{6682}\x{6683}\x{6684}' . '\x{6685}\x{6686}\x{6687}\x{6688}\x{6689}\x{668A}\x{668B}\x{668C}\x{668D}' . '\x{668E}\x{668F}\x{6690}\x{6691}\x{6693}\x{6694}\x{6695}\x{6696}\x{6697}' . '\x{6698}\x{6699}\x{669A}\x{669B}\x{669D}\x{669F}\x{66A0}\x{66A1}\x{66A2}' . '\x{66A3}\x{66A4}\x{66A5}\x{66A6}\x{66A7}\x{66A8}\x{66A9}\x{66AA}\x{66AB}' . '\x{66AE}\x{66AF}\x{66B0}\x{66B1}\x{66B2}\x{66B3}\x{66B4}\x{66B5}\x{66B6}' . '\x{66B7}\x{66B8}\x{66B9}\x{66BA}\x{66BB}\x{66BC}\x{66BD}\x{66BE}\x{66BF}' . '\x{66C0}\x{66C1}\x{66C2}\x{66C3}\x{66C4}\x{66C5}\x{66C6}\x{66C7}\x{66C8}' . '\x{66C9}\x{66CA}\x{66CB}\x{66CC}\x{66CD}\x{66CE}\x{66CF}\x{66D1}\x{66D2}' . '\x{66D4}\x{66D5}\x{66D6}\x{66D8}\x{66D9}\x{66DA}\x{66DB}\x{66DC}\x{66DD}' . '\x{66DE}\x{66E0}\x{66E1}\x{66E2}\x{66E3}\x{66E4}\x{66E5}\x{66E6}\x{66E7}' . '\x{66E8}\x{66E9}\x{66EA}\x{66EB}\x{66EC}\x{66ED}\x{66EE}\x{66F0}\x{66F1}' . '\x{66F2}\x{66F3}\x{66F4}\x{66F5}\x{66F6}\x{66F7}\x{66F8}\x{66F9}\x{66FA}' . '\x{66FB}\x{66FC}\x{66FE}\x{66FF}\x{6700}\x{6701}\x{6703}\x{6704}\x{6705}' . '\x{6706}\x{6708}\x{6709}\x{670A}\x{670B}\x{670C}\x{670D}\x{670E}\x{670F}' . '\x{6710}\x{6711}\x{6712}\x{6713}\x{6714}\x{6715}\x{6716}\x{6717}\x{6718}' . '\x{671A}\x{671B}\x{671C}\x{671D}\x{671E}\x{671F}\x{6720}\x{6721}\x{6722}' . '\x{6723}\x{6725}\x{6726}\x{6727}\x{6728}\x{672A}\x{672B}\x{672C}\x{672D}' . '\x{672E}\x{672F}\x{6730}\x{6731}\x{6732}\x{6733}\x{6734}\x{6735}\x{6736}' . '\x{6737}\x{6738}\x{6739}\x{673A}\x{673B}\x{673C}\x{673D}\x{673E}\x{673F}' . '\x{6740}\x{6741}\x{6742}\x{6743}\x{6744}\x{6745}\x{6746}\x{6747}\x{6748}' . '\x{6749}\x{674A}\x{674B}\x{674C}\x{674D}\x{674E}\x{674F}\x{6750}\x{6751}' . '\x{6752}\x{6753}\x{6754}\x{6755}\x{6756}\x{6757}\x{6758}\x{6759}\x{675A}' . '\x{675B}\x{675C}\x{675D}\x{675E}\x{675F}\x{6760}\x{6761}\x{6762}\x{6763}' . '\x{6764}\x{6765}\x{6766}\x{6768}\x{6769}\x{676A}\x{676B}\x{676C}\x{676D}' . '\x{676E}\x{676F}\x{6770}\x{6771}\x{6772}\x{6773}\x{6774}\x{6775}\x{6776}' . '\x{6777}\x{6778}\x{6779}\x{677A}\x{677B}\x{677C}\x{677D}\x{677E}\x{677F}' . '\x{6780}\x{6781}\x{6782}\x{6783}\x{6784}\x{6785}\x{6786}\x{6787}\x{6789}' . '\x{678A}\x{678B}\x{678C}\x{678D}\x{678E}\x{678F}\x{6790}\x{6791}\x{6792}' . '\x{6793}\x{6794}\x{6795}\x{6797}\x{6798}\x{6799}\x{679A}\x{679B}\x{679C}' . '\x{679D}\x{679E}\x{679F}\x{67A0}\x{67A1}\x{67A2}\x{67A3}\x{67A4}\x{67A5}' . '\x{67A6}\x{67A7}\x{67A8}\x{67AA}\x{67AB}\x{67AC}\x{67AD}\x{67AE}\x{67AF}' . '\x{67B0}\x{67B1}\x{67B2}\x{67B3}\x{67B4}\x{67B5}\x{67B6}\x{67B7}\x{67B8}' . '\x{67B9}\x{67BA}\x{67BB}\x{67BC}\x{67BE}\x{67C0}\x{67C1}\x{67C2}\x{67C3}' . '\x{67C4}\x{67C5}\x{67C6}\x{67C7}\x{67C8}\x{67C9}\x{67CA}\x{67CB}\x{67CC}' . '\x{67CD}\x{67CE}\x{67CF}\x{67D0}\x{67D1}\x{67D2}\x{67D3}\x{67D4}\x{67D6}' . '\x{67D8}\x{67D9}\x{67DA}\x{67DB}\x{67DC}\x{67DD}\x{67DE}\x{67DF}\x{67E0}' . '\x{67E1}\x{67E2}\x{67E3}\x{67E4}\x{67E5}\x{67E6}\x{67E7}\x{67E8}\x{67E9}' . '\x{67EA}\x{67EB}\x{67EC}\x{67ED}\x{67EE}\x{67EF}\x{67F0}\x{67F1}\x{67F2}' . '\x{67F3}\x{67F4}\x{67F5}\x{67F6}\x{67F7}\x{67F8}\x{67FA}\x{67FB}\x{67FC}' . '\x{67FD}\x{67FE}\x{67FF}\x{6800}\x{6802}\x{6803}\x{6804}\x{6805}\x{6806}' . '\x{6807}\x{6808}\x{6809}\x{680A}\x{680B}\x{680C}\x{680D}\x{680E}\x{680F}' . '\x{6810}\x{6811}\x{6812}\x{6813}\x{6814}\x{6816}\x{6817}\x{6818}\x{6819}' . '\x{681A}\x{681B}\x{681C}\x{681D}\x{681F}\x{6820}\x{6821}\x{6822}\x{6823}' . '\x{6824}\x{6825}\x{6826}\x{6828}\x{6829}\x{682A}\x{682B}\x{682C}\x{682D}' . '\x{682E}\x{682F}\x{6831}\x{6832}\x{6833}\x{6834}\x{6835}\x{6836}\x{6837}' . '\x{6838}\x{6839}\x{683A}\x{683B}\x{683C}\x{683D}\x{683E}\x{683F}\x{6840}' . '\x{6841}\x{6842}\x{6843}\x{6844}\x{6845}\x{6846}\x{6847}\x{6848}\x{6849}' . '\x{684A}\x{684B}\x{684C}\x{684D}\x{684E}\x{684F}\x{6850}\x{6851}\x{6852}' . '\x{6853}\x{6854}\x{6855}\x{6856}\x{6857}\x{685B}\x{685D}\x{6860}\x{6861}' . '\x{6862}\x{6863}\x{6864}\x{6865}\x{6866}\x{6867}\x{6868}\x{6869}\x{686A}' . '\x{686B}\x{686C}\x{686D}\x{686E}\x{686F}\x{6870}\x{6871}\x{6872}\x{6873}' . '\x{6874}\x{6875}\x{6876}\x{6877}\x{6878}\x{6879}\x{687B}\x{687C}\x{687D}' . '\x{687E}\x{687F}\x{6880}\x{6881}\x{6882}\x{6883}\x{6884}\x{6885}\x{6886}' . '\x{6887}\x{6888}\x{6889}\x{688A}\x{688B}\x{688C}\x{688D}\x{688E}\x{688F}' . '\x{6890}\x{6891}\x{6892}\x{6893}\x{6894}\x{6896}\x{6897}\x{6898}\x{689A}' . '\x{689B}\x{689C}\x{689D}\x{689E}\x{689F}\x{68A0}\x{68A1}\x{68A2}\x{68A3}' . '\x{68A4}\x{68A6}\x{68A7}\x{68A8}\x{68A9}\x{68AA}\x{68AB}\x{68AC}\x{68AD}' . '\x{68AE}\x{68AF}\x{68B0}\x{68B1}\x{68B2}\x{68B3}\x{68B4}\x{68B5}\x{68B6}' . '\x{68B7}\x{68B9}\x{68BB}\x{68BC}\x{68BD}\x{68BE}\x{68BF}\x{68C0}\x{68C1}' . '\x{68C2}\x{68C4}\x{68C6}\x{68C7}\x{68C8}\x{68C9}\x{68CA}\x{68CB}\x{68CC}' . '\x{68CD}\x{68CE}\x{68CF}\x{68D0}\x{68D1}\x{68D2}\x{68D3}\x{68D4}\x{68D5}' . '\x{68D6}\x{68D7}\x{68D8}\x{68DA}\x{68DB}\x{68DC}\x{68DD}\x{68DE}\x{68DF}' . '\x{68E0}\x{68E1}\x{68E3}\x{68E4}\x{68E6}\x{68E7}\x{68E8}\x{68E9}\x{68EA}' . '\x{68EB}\x{68EC}\x{68ED}\x{68EE}\x{68EF}\x{68F0}\x{68F1}\x{68F2}\x{68F3}' . '\x{68F4}\x{68F5}\x{68F6}\x{68F7}\x{68F8}\x{68F9}\x{68FA}\x{68FB}\x{68FC}' . '\x{68FD}\x{68FE}\x{68FF}\x{6901}\x{6902}\x{6903}\x{6904}\x{6905}\x{6906}' . '\x{6907}\x{6908}\x{690A}\x{690B}\x{690C}\x{690D}\x{690E}\x{690F}\x{6910}' . '\x{6911}\x{6912}\x{6913}\x{6914}\x{6915}\x{6916}\x{6917}\x{6918}\x{6919}' . '\x{691A}\x{691B}\x{691C}\x{691D}\x{691E}\x{691F}\x{6920}\x{6921}\x{6922}' . '\x{6923}\x{6924}\x{6925}\x{6926}\x{6927}\x{6928}\x{6929}\x{692A}\x{692B}' . '\x{692C}\x{692D}\x{692E}\x{692F}\x{6930}\x{6931}\x{6932}\x{6933}\x{6934}' . '\x{6935}\x{6936}\x{6937}\x{6938}\x{6939}\x{693A}\x{693B}\x{693C}\x{693D}' . '\x{693F}\x{6940}\x{6941}\x{6942}\x{6943}\x{6944}\x{6945}\x{6946}\x{6947}' . '\x{6948}\x{6949}\x{694A}\x{694B}\x{694C}\x{694E}\x{694F}\x{6950}\x{6951}' . '\x{6952}\x{6953}\x{6954}\x{6955}\x{6956}\x{6957}\x{6958}\x{6959}\x{695A}' . '\x{695B}\x{695C}\x{695D}\x{695E}\x{695F}\x{6960}\x{6961}\x{6962}\x{6963}' . '\x{6964}\x{6965}\x{6966}\x{6967}\x{6968}\x{6969}\x{696A}\x{696B}\x{696C}' . '\x{696D}\x{696E}\x{696F}\x{6970}\x{6971}\x{6972}\x{6973}\x{6974}\x{6975}' . '\x{6976}\x{6977}\x{6978}\x{6979}\x{697A}\x{697B}\x{697C}\x{697D}\x{697E}' . '\x{697F}\x{6980}\x{6981}\x{6982}\x{6983}\x{6984}\x{6985}\x{6986}\x{6987}' . '\x{6988}\x{6989}\x{698A}\x{698B}\x{698C}\x{698D}\x{698E}\x{698F}\x{6990}' . '\x{6991}\x{6992}\x{6993}\x{6994}\x{6995}\x{6996}\x{6997}\x{6998}\x{6999}' . '\x{699A}\x{699B}\x{699C}\x{699D}\x{699E}\x{69A0}\x{69A1}\x{69A3}\x{69A4}' . '\x{69A5}\x{69A6}\x{69A7}\x{69A8}\x{69A9}\x{69AA}\x{69AB}\x{69AC}\x{69AD}' . '\x{69AE}\x{69AF}\x{69B0}\x{69B1}\x{69B2}\x{69B3}\x{69B4}\x{69B5}\x{69B6}' . '\x{69B7}\x{69B8}\x{69B9}\x{69BA}\x{69BB}\x{69BC}\x{69BD}\x{69BE}\x{69BF}' . '\x{69C1}\x{69C2}\x{69C3}\x{69C4}\x{69C5}\x{69C6}\x{69C7}\x{69C8}\x{69C9}' . '\x{69CA}\x{69CB}\x{69CC}\x{69CD}\x{69CE}\x{69CF}\x{69D0}\x{69D3}\x{69D4}' . '\x{69D8}\x{69D9}\x{69DA}\x{69DB}\x{69DC}\x{69DD}\x{69DE}\x{69DF}\x{69E0}' . '\x{69E1}\x{69E2}\x{69E3}\x{69E4}\x{69E5}\x{69E6}\x{69E7}\x{69E8}\x{69E9}' . '\x{69EA}\x{69EB}\x{69EC}\x{69ED}\x{69EE}\x{69EF}\x{69F0}\x{69F1}\x{69F2}' . '\x{69F3}\x{69F4}\x{69F5}\x{69F6}\x{69F7}\x{69F8}\x{69FA}\x{69FB}\x{69FC}' . '\x{69FD}\x{69FE}\x{69FF}\x{6A00}\x{6A01}\x{6A02}\x{6A04}\x{6A05}\x{6A06}' . '\x{6A07}\x{6A08}\x{6A09}\x{6A0A}\x{6A0B}\x{6A0D}\x{6A0E}\x{6A0F}\x{6A10}' . '\x{6A11}\x{6A12}\x{6A13}\x{6A14}\x{6A15}\x{6A16}\x{6A17}\x{6A18}\x{6A19}' . '\x{6A1A}\x{6A1B}\x{6A1D}\x{6A1E}\x{6A1F}\x{6A20}\x{6A21}\x{6A22}\x{6A23}' . '\x{6A25}\x{6A26}\x{6A27}\x{6A28}\x{6A29}\x{6A2A}\x{6A2B}\x{6A2C}\x{6A2D}' . '\x{6A2E}\x{6A2F}\x{6A30}\x{6A31}\x{6A32}\x{6A33}\x{6A34}\x{6A35}\x{6A36}' . '\x{6A38}\x{6A39}\x{6A3A}\x{6A3B}\x{6A3C}\x{6A3D}\x{6A3E}\x{6A3F}\x{6A40}' . '\x{6A41}\x{6A42}\x{6A43}\x{6A44}\x{6A45}\x{6A46}\x{6A47}\x{6A48}\x{6A49}' . '\x{6A4B}\x{6A4C}\x{6A4D}\x{6A4E}\x{6A4F}\x{6A50}\x{6A51}\x{6A52}\x{6A54}' . '\x{6A55}\x{6A56}\x{6A57}\x{6A58}\x{6A59}\x{6A5A}\x{6A5B}\x{6A5D}\x{6A5E}' . '\x{6A5F}\x{6A60}\x{6A61}\x{6A62}\x{6A63}\x{6A64}\x{6A65}\x{6A66}\x{6A67}' . '\x{6A68}\x{6A69}\x{6A6A}\x{6A6B}\x{6A6C}\x{6A6D}\x{6A6F}\x{6A71}\x{6A72}' . '\x{6A73}\x{6A74}\x{6A75}\x{6A76}\x{6A77}\x{6A78}\x{6A79}\x{6A7A}\x{6A7B}' . '\x{6A7C}\x{6A7D}\x{6A7E}\x{6A7F}\x{6A80}\x{6A81}\x{6A82}\x{6A83}\x{6A84}' . '\x{6A85}\x{6A87}\x{6A88}\x{6A89}\x{6A8B}\x{6A8C}\x{6A8D}\x{6A8E}\x{6A90}' . '\x{6A91}\x{6A92}\x{6A93}\x{6A94}\x{6A95}\x{6A96}\x{6A97}\x{6A98}\x{6A9A}' . '\x{6A9B}\x{6A9C}\x{6A9E}\x{6A9F}\x{6AA0}\x{6AA1}\x{6AA2}\x{6AA3}\x{6AA4}' . '\x{6AA5}\x{6AA6}\x{6AA7}\x{6AA8}\x{6AA9}\x{6AAB}\x{6AAC}\x{6AAD}\x{6AAE}' . '\x{6AAF}\x{6AB0}\x{6AB2}\x{6AB3}\x{6AB4}\x{6AB5}\x{6AB6}\x{6AB7}\x{6AB8}' . '\x{6AB9}\x{6ABA}\x{6ABB}\x{6ABC}\x{6ABD}\x{6ABF}\x{6AC1}\x{6AC2}\x{6AC3}' . '\x{6AC5}\x{6AC6}\x{6AC7}\x{6ACA}\x{6ACB}\x{6ACC}\x{6ACD}\x{6ACE}\x{6ACF}' . '\x{6AD0}\x{6AD1}\x{6AD2}\x{6AD3}\x{6AD4}\x{6AD5}\x{6AD6}\x{6AD7}\x{6AD9}' . '\x{6ADA}\x{6ADB}\x{6ADC}\x{6ADD}\x{6ADE}\x{6ADF}\x{6AE0}\x{6AE1}\x{6AE2}' . '\x{6AE3}\x{6AE4}\x{6AE5}\x{6AE6}\x{6AE7}\x{6AE8}\x{6AEA}\x{6AEB}\x{6AEC}' . '\x{6AED}\x{6AEE}\x{6AEF}\x{6AF0}\x{6AF1}\x{6AF2}\x{6AF3}\x{6AF4}\x{6AF5}' . '\x{6AF6}\x{6AF7}\x{6AF8}\x{6AF9}\x{6AFA}\x{6AFB}\x{6AFC}\x{6AFD}\x{6AFE}' . '\x{6AFF}\x{6B00}\x{6B01}\x{6B02}\x{6B03}\x{6B04}\x{6B05}\x{6B06}\x{6B07}' . '\x{6B08}\x{6B09}\x{6B0A}\x{6B0B}\x{6B0C}\x{6B0D}\x{6B0F}\x{6B10}\x{6B11}' . '\x{6B12}\x{6B13}\x{6B14}\x{6B15}\x{6B16}\x{6B17}\x{6B18}\x{6B19}\x{6B1A}' . '\x{6B1C}\x{6B1D}\x{6B1E}\x{6B1F}\x{6B20}\x{6B21}\x{6B22}\x{6B23}\x{6B24}' . '\x{6B25}\x{6B26}\x{6B27}\x{6B28}\x{6B29}\x{6B2A}\x{6B2B}\x{6B2C}\x{6B2D}' . '\x{6B2F}\x{6B30}\x{6B31}\x{6B32}\x{6B33}\x{6B34}\x{6B36}\x{6B37}\x{6B38}' . '\x{6B39}\x{6B3A}\x{6B3B}\x{6B3C}\x{6B3D}\x{6B3E}\x{6B3F}\x{6B41}\x{6B42}' . '\x{6B43}\x{6B44}\x{6B45}\x{6B46}\x{6B47}\x{6B48}\x{6B49}\x{6B4A}\x{6B4B}' . '\x{6B4C}\x{6B4D}\x{6B4E}\x{6B4F}\x{6B50}\x{6B51}\x{6B52}\x{6B53}\x{6B54}' . '\x{6B55}\x{6B56}\x{6B59}\x{6B5A}\x{6B5B}\x{6B5C}\x{6B5E}\x{6B5F}\x{6B60}' . '\x{6B61}\x{6B62}\x{6B63}\x{6B64}\x{6B65}\x{6B66}\x{6B67}\x{6B69}\x{6B6A}' . '\x{6B6B}\x{6B6D}\x{6B6F}\x{6B70}\x{6B72}\x{6B73}\x{6B74}\x{6B76}\x{6B77}' . '\x{6B78}\x{6B79}\x{6B7A}\x{6B7B}\x{6B7C}\x{6B7E}\x{6B7F}\x{6B80}\x{6B81}' . '\x{6B82}\x{6B83}\x{6B84}\x{6B85}\x{6B86}\x{6B87}\x{6B88}\x{6B89}\x{6B8A}' . '\x{6B8B}\x{6B8C}\x{6B8D}\x{6B8E}\x{6B8F}\x{6B90}\x{6B91}\x{6B92}\x{6B93}' . '\x{6B94}\x{6B95}\x{6B96}\x{6B97}\x{6B98}\x{6B99}\x{6B9A}\x{6B9B}\x{6B9C}' . '\x{6B9D}\x{6B9E}\x{6B9F}\x{6BA0}\x{6BA1}\x{6BA2}\x{6BA3}\x{6BA4}\x{6BA5}' . '\x{6BA6}\x{6BA7}\x{6BA8}\x{6BA9}\x{6BAA}\x{6BAB}\x{6BAC}\x{6BAD}\x{6BAE}' . '\x{6BAF}\x{6BB0}\x{6BB2}\x{6BB3}\x{6BB4}\x{6BB5}\x{6BB6}\x{6BB7}\x{6BB9}' . '\x{6BBA}\x{6BBB}\x{6BBC}\x{6BBD}\x{6BBE}\x{6BBF}\x{6BC0}\x{6BC1}\x{6BC2}' . '\x{6BC3}\x{6BC4}\x{6BC5}\x{6BC6}\x{6BC7}\x{6BC8}\x{6BC9}\x{6BCA}\x{6BCB}' . '\x{6BCC}\x{6BCD}\x{6BCE}\x{6BCF}\x{6BD0}\x{6BD1}\x{6BD2}\x{6BD3}\x{6BD4}' . '\x{6BD5}\x{6BD6}\x{6BD7}\x{6BD8}\x{6BD9}\x{6BDA}\x{6BDB}\x{6BDC}\x{6BDD}' . '\x{6BDE}\x{6BDF}\x{6BE0}\x{6BE1}\x{6BE2}\x{6BE3}\x{6BE4}\x{6BE5}\x{6BE6}' . '\x{6BE7}\x{6BE8}\x{6BEA}\x{6BEB}\x{6BEC}\x{6BED}\x{6BEE}\x{6BEF}\x{6BF0}' . '\x{6BF2}\x{6BF3}\x{6BF5}\x{6BF6}\x{6BF7}\x{6BF8}\x{6BF9}\x{6BFB}\x{6BFC}' . '\x{6BFD}\x{6BFE}\x{6BFF}\x{6C00}\x{6C01}\x{6C02}\x{6C03}\x{6C04}\x{6C05}' . '\x{6C06}\x{6C07}\x{6C08}\x{6C09}\x{6C0B}\x{6C0C}\x{6C0D}\x{6C0E}\x{6C0F}' . '\x{6C10}\x{6C11}\x{6C12}\x{6C13}\x{6C14}\x{6C15}\x{6C16}\x{6C18}\x{6C19}' . '\x{6C1A}\x{6C1B}\x{6C1D}\x{6C1E}\x{6C1F}\x{6C20}\x{6C21}\x{6C22}\x{6C23}' . '\x{6C24}\x{6C25}\x{6C26}\x{6C27}\x{6C28}\x{6C29}\x{6C2A}\x{6C2B}\x{6C2C}' . '\x{6C2E}\x{6C2F}\x{6C30}\x{6C31}\x{6C32}\x{6C33}\x{6C34}\x{6C35}\x{6C36}' . '\x{6C37}\x{6C38}\x{6C3A}\x{6C3B}\x{6C3D}\x{6C3E}\x{6C3F}\x{6C40}\x{6C41}' . '\x{6C42}\x{6C43}\x{6C44}\x{6C46}\x{6C47}\x{6C48}\x{6C49}\x{6C4A}\x{6C4B}' . '\x{6C4C}\x{6C4D}\x{6C4E}\x{6C4F}\x{6C50}\x{6C51}\x{6C52}\x{6C53}\x{6C54}' . '\x{6C55}\x{6C56}\x{6C57}\x{6C58}\x{6C59}\x{6C5A}\x{6C5B}\x{6C5C}\x{6C5D}' . '\x{6C5E}\x{6C5F}\x{6C60}\x{6C61}\x{6C62}\x{6C63}\x{6C64}\x{6C65}\x{6C66}' . '\x{6C67}\x{6C68}\x{6C69}\x{6C6A}\x{6C6B}\x{6C6D}\x{6C6F}\x{6C70}\x{6C71}' . '\x{6C72}\x{6C73}\x{6C74}\x{6C75}\x{6C76}\x{6C77}\x{6C78}\x{6C79}\x{6C7A}' . '\x{6C7B}\x{6C7C}\x{6C7D}\x{6C7E}\x{6C7F}\x{6C80}\x{6C81}\x{6C82}\x{6C83}' . '\x{6C84}\x{6C85}\x{6C86}\x{6C87}\x{6C88}\x{6C89}\x{6C8A}\x{6C8B}\x{6C8C}' . '\x{6C8D}\x{6C8E}\x{6C8F}\x{6C90}\x{6C91}\x{6C92}\x{6C93}\x{6C94}\x{6C95}' . '\x{6C96}\x{6C97}\x{6C98}\x{6C99}\x{6C9A}\x{6C9B}\x{6C9C}\x{6C9D}\x{6C9E}' . '\x{6C9F}\x{6CA1}\x{6CA2}\x{6CA3}\x{6CA4}\x{6CA5}\x{6CA6}\x{6CA7}\x{6CA8}' . '\x{6CA9}\x{6CAA}\x{6CAB}\x{6CAC}\x{6CAD}\x{6CAE}\x{6CAF}\x{6CB0}\x{6CB1}' . '\x{6CB2}\x{6CB3}\x{6CB4}\x{6CB5}\x{6CB6}\x{6CB7}\x{6CB8}\x{6CB9}\x{6CBA}' . '\x{6CBB}\x{6CBC}\x{6CBD}\x{6CBE}\x{6CBF}\x{6CC0}\x{6CC1}\x{6CC2}\x{6CC3}' . '\x{6CC4}\x{6CC5}\x{6CC6}\x{6CC7}\x{6CC8}\x{6CC9}\x{6CCA}\x{6CCB}\x{6CCC}' . '\x{6CCD}\x{6CCE}\x{6CCF}\x{6CD0}\x{6CD1}\x{6CD2}\x{6CD3}\x{6CD4}\x{6CD5}' . '\x{6CD6}\x{6CD7}\x{6CD9}\x{6CDA}\x{6CDB}\x{6CDC}\x{6CDD}\x{6CDE}\x{6CDF}' . '\x{6CE0}\x{6CE1}\x{6CE2}\x{6CE3}\x{6CE4}\x{6CE5}\x{6CE6}\x{6CE7}\x{6CE8}' . '\x{6CE9}\x{6CEA}\x{6CEB}\x{6CEC}\x{6CED}\x{6CEE}\x{6CEF}\x{6CF0}\x{6CF1}' . '\x{6CF2}\x{6CF3}\x{6CF5}\x{6CF6}\x{6CF7}\x{6CF8}\x{6CF9}\x{6CFA}\x{6CFB}' . '\x{6CFC}\x{6CFD}\x{6CFE}\x{6CFF}\x{6D00}\x{6D01}\x{6D03}\x{6D04}\x{6D05}' . '\x{6D06}\x{6D07}\x{6D08}\x{6D09}\x{6D0A}\x{6D0B}\x{6D0C}\x{6D0D}\x{6D0E}' . '\x{6D0F}\x{6D10}\x{6D11}\x{6D12}\x{6D13}\x{6D14}\x{6D15}\x{6D16}\x{6D17}' . '\x{6D18}\x{6D19}\x{6D1A}\x{6D1B}\x{6D1D}\x{6D1E}\x{6D1F}\x{6D20}\x{6D21}' . '\x{6D22}\x{6D23}\x{6D25}\x{6D26}\x{6D27}\x{6D28}\x{6D29}\x{6D2A}\x{6D2B}' . '\x{6D2C}\x{6D2D}\x{6D2E}\x{6D2F}\x{6D30}\x{6D31}\x{6D32}\x{6D33}\x{6D34}' . '\x{6D35}\x{6D36}\x{6D37}\x{6D38}\x{6D39}\x{6D3A}\x{6D3B}\x{6D3C}\x{6D3D}' . '\x{6D3E}\x{6D3F}\x{6D40}\x{6D41}\x{6D42}\x{6D43}\x{6D44}\x{6D45}\x{6D46}' . '\x{6D47}\x{6D48}\x{6D49}\x{6D4A}\x{6D4B}\x{6D4C}\x{6D4D}\x{6D4E}\x{6D4F}' . '\x{6D50}\x{6D51}\x{6D52}\x{6D53}\x{6D54}\x{6D55}\x{6D56}\x{6D57}\x{6D58}' . '\x{6D59}\x{6D5A}\x{6D5B}\x{6D5C}\x{6D5D}\x{6D5E}\x{6D5F}\x{6D60}\x{6D61}' . '\x{6D62}\x{6D63}\x{6D64}\x{6D65}\x{6D66}\x{6D67}\x{6D68}\x{6D69}\x{6D6A}' . '\x{6D6B}\x{6D6C}\x{6D6D}\x{6D6E}\x{6D6F}\x{6D70}\x{6D72}\x{6D73}\x{6D74}' . '\x{6D75}\x{6D76}\x{6D77}\x{6D78}\x{6D79}\x{6D7A}\x{6D7B}\x{6D7C}\x{6D7D}' . '\x{6D7E}\x{6D7F}\x{6D80}\x{6D82}\x{6D83}\x{6D84}\x{6D85}\x{6D86}\x{6D87}' . '\x{6D88}\x{6D89}\x{6D8A}\x{6D8B}\x{6D8C}\x{6D8D}\x{6D8E}\x{6D8F}\x{6D90}' . '\x{6D91}\x{6D92}\x{6D93}\x{6D94}\x{6D95}\x{6D97}\x{6D98}\x{6D99}\x{6D9A}' . '\x{6D9B}\x{6D9D}\x{6D9E}\x{6D9F}\x{6DA0}\x{6DA1}\x{6DA2}\x{6DA3}\x{6DA4}' . '\x{6DA5}\x{6DA6}\x{6DA7}\x{6DA8}\x{6DA9}\x{6DAA}\x{6DAB}\x{6DAC}\x{6DAD}' . '\x{6DAE}\x{6DAF}\x{6DB2}\x{6DB3}\x{6DB4}\x{6DB5}\x{6DB7}\x{6DB8}\x{6DB9}' . '\x{6DBA}\x{6DBB}\x{6DBC}\x{6DBD}\x{6DBE}\x{6DBF}\x{6DC0}\x{6DC1}\x{6DC2}' . '\x{6DC3}\x{6DC4}\x{6DC5}\x{6DC6}\x{6DC7}\x{6DC8}\x{6DC9}\x{6DCA}\x{6DCB}' . '\x{6DCC}\x{6DCD}\x{6DCE}\x{6DCF}\x{6DD0}\x{6DD1}\x{6DD2}\x{6DD3}\x{6DD4}' . '\x{6DD5}\x{6DD6}\x{6DD7}\x{6DD8}\x{6DD9}\x{6DDA}\x{6DDB}\x{6DDC}\x{6DDD}' . '\x{6DDE}\x{6DDF}\x{6DE0}\x{6DE1}\x{6DE2}\x{6DE3}\x{6DE4}\x{6DE5}\x{6DE6}' . '\x{6DE7}\x{6DE8}\x{6DE9}\x{6DEA}\x{6DEB}\x{6DEC}\x{6DED}\x{6DEE}\x{6DEF}' . '\x{6DF0}\x{6DF1}\x{6DF2}\x{6DF3}\x{6DF4}\x{6DF5}\x{6DF6}\x{6DF7}\x{6DF8}' . '\x{6DF9}\x{6DFA}\x{6DFB}\x{6DFC}\x{6DFD}\x{6E00}\x{6E03}\x{6E04}\x{6E05}' . '\x{6E07}\x{6E08}\x{6E09}\x{6E0A}\x{6E0B}\x{6E0C}\x{6E0D}\x{6E0E}\x{6E0F}' . '\x{6E10}\x{6E11}\x{6E14}\x{6E15}\x{6E16}\x{6E17}\x{6E19}\x{6E1A}\x{6E1B}' . '\x{6E1C}\x{6E1D}\x{6E1E}\x{6E1F}\x{6E20}\x{6E21}\x{6E22}\x{6E23}\x{6E24}' . '\x{6E25}\x{6E26}\x{6E27}\x{6E28}\x{6E29}\x{6E2B}\x{6E2C}\x{6E2D}\x{6E2E}' . '\x{6E2F}\x{6E30}\x{6E31}\x{6E32}\x{6E33}\x{6E34}\x{6E35}\x{6E36}\x{6E37}' . '\x{6E38}\x{6E39}\x{6E3A}\x{6E3B}\x{6E3C}\x{6E3D}\x{6E3E}\x{6E3F}\x{6E40}' . '\x{6E41}\x{6E42}\x{6E43}\x{6E44}\x{6E45}\x{6E46}\x{6E47}\x{6E48}\x{6E49}' . '\x{6E4A}\x{6E4B}\x{6E4D}\x{6E4E}\x{6E4F}\x{6E50}\x{6E51}\x{6E52}\x{6E53}' . '\x{6E54}\x{6E55}\x{6E56}\x{6E57}\x{6E58}\x{6E59}\x{6E5A}\x{6E5B}\x{6E5C}' . '\x{6E5D}\x{6E5E}\x{6E5F}\x{6E60}\x{6E61}\x{6E62}\x{6E63}\x{6E64}\x{6E65}' . '\x{6E66}\x{6E67}\x{6E68}\x{6E69}\x{6E6A}\x{6E6B}\x{6E6D}\x{6E6E}\x{6E6F}' . '\x{6E70}\x{6E71}\x{6E72}\x{6E73}\x{6E74}\x{6E75}\x{6E77}\x{6E78}\x{6E79}' . '\x{6E7E}\x{6E7F}\x{6E80}\x{6E81}\x{6E82}\x{6E83}\x{6E84}\x{6E85}\x{6E86}' . '\x{6E87}\x{6E88}\x{6E89}\x{6E8A}\x{6E8D}\x{6E8E}\x{6E8F}\x{6E90}\x{6E91}' . '\x{6E92}\x{6E93}\x{6E94}\x{6E96}\x{6E97}\x{6E98}\x{6E99}\x{6E9A}\x{6E9B}' . '\x{6E9C}\x{6E9D}\x{6E9E}\x{6E9F}\x{6EA0}\x{6EA1}\x{6EA2}\x{6EA3}\x{6EA4}' . '\x{6EA5}\x{6EA6}\x{6EA7}\x{6EA8}\x{6EA9}\x{6EAA}\x{6EAB}\x{6EAC}\x{6EAD}' . '\x{6EAE}\x{6EAF}\x{6EB0}\x{6EB1}\x{6EB2}\x{6EB3}\x{6EB4}\x{6EB5}\x{6EB6}' . '\x{6EB7}\x{6EB8}\x{6EB9}\x{6EBA}\x{6EBB}\x{6EBC}\x{6EBD}\x{6EBE}\x{6EBF}' . '\x{6EC0}\x{6EC1}\x{6EC2}\x{6EC3}\x{6EC4}\x{6EC5}\x{6EC6}\x{6EC7}\x{6EC8}' . '\x{6EC9}\x{6ECA}\x{6ECB}\x{6ECC}\x{6ECD}\x{6ECE}\x{6ECF}\x{6ED0}\x{6ED1}' . '\x{6ED2}\x{6ED3}\x{6ED4}\x{6ED5}\x{6ED6}\x{6ED7}\x{6ED8}\x{6ED9}\x{6EDA}' . '\x{6EDC}\x{6EDE}\x{6EDF}\x{6EE0}\x{6EE1}\x{6EE2}\x{6EE4}\x{6EE5}\x{6EE6}' . '\x{6EE7}\x{6EE8}\x{6EE9}\x{6EEA}\x{6EEB}\x{6EEC}\x{6EED}\x{6EEE}\x{6EEF}' . '\x{6EF0}\x{6EF1}\x{6EF2}\x{6EF3}\x{6EF4}\x{6EF5}\x{6EF6}\x{6EF7}\x{6EF8}' . '\x{6EF9}\x{6EFA}\x{6EFB}\x{6EFC}\x{6EFD}\x{6EFE}\x{6EFF}\x{6F00}\x{6F01}' . '\x{6F02}\x{6F03}\x{6F05}\x{6F06}\x{6F07}\x{6F08}\x{6F09}\x{6F0A}\x{6F0C}' . '\x{6F0D}\x{6F0E}\x{6F0F}\x{6F10}\x{6F11}\x{6F12}\x{6F13}\x{6F14}\x{6F15}' . '\x{6F16}\x{6F17}\x{6F18}\x{6F19}\x{6F1A}\x{6F1B}\x{6F1C}\x{6F1D}\x{6F1E}' . '\x{6F1F}\x{6F20}\x{6F21}\x{6F22}\x{6F23}\x{6F24}\x{6F25}\x{6F26}\x{6F27}' . '\x{6F28}\x{6F29}\x{6F2A}\x{6F2B}\x{6F2C}\x{6F2D}\x{6F2E}\x{6F2F}\x{6F30}' . '\x{6F31}\x{6F32}\x{6F33}\x{6F34}\x{6F35}\x{6F36}\x{6F37}\x{6F38}\x{6F39}' . '\x{6F3A}\x{6F3B}\x{6F3C}\x{6F3D}\x{6F3E}\x{6F3F}\x{6F40}\x{6F41}\x{6F43}' . '\x{6F44}\x{6F45}\x{6F46}\x{6F47}\x{6F49}\x{6F4B}\x{6F4C}\x{6F4D}\x{6F4E}' . '\x{6F4F}\x{6F50}\x{6F51}\x{6F52}\x{6F53}\x{6F54}\x{6F55}\x{6F56}\x{6F57}' . '\x{6F58}\x{6F59}\x{6F5A}\x{6F5B}\x{6F5C}\x{6F5D}\x{6F5E}\x{6F5F}\x{6F60}' . '\x{6F61}\x{6F62}\x{6F63}\x{6F64}\x{6F65}\x{6F66}\x{6F67}\x{6F68}\x{6F69}' . '\x{6F6A}\x{6F6B}\x{6F6C}\x{6F6D}\x{6F6E}\x{6F6F}\x{6F70}\x{6F71}\x{6F72}' . '\x{6F73}\x{6F74}\x{6F75}\x{6F76}\x{6F77}\x{6F78}\x{6F7A}\x{6F7B}\x{6F7C}' . '\x{6F7D}\x{6F7E}\x{6F7F}\x{6F80}\x{6F81}\x{6F82}\x{6F83}\x{6F84}\x{6F85}' . '\x{6F86}\x{6F87}\x{6F88}\x{6F89}\x{6F8A}\x{6F8B}\x{6F8C}\x{6F8D}\x{6F8E}' . '\x{6F8F}\x{6F90}\x{6F91}\x{6F92}\x{6F93}\x{6F94}\x{6F95}\x{6F96}\x{6F97}' . '\x{6F99}\x{6F9B}\x{6F9C}\x{6F9D}\x{6F9E}\x{6FA0}\x{6FA1}\x{6FA2}\x{6FA3}' . '\x{6FA4}\x{6FA5}\x{6FA6}\x{6FA7}\x{6FA8}\x{6FA9}\x{6FAA}\x{6FAB}\x{6FAC}' . '\x{6FAD}\x{6FAE}\x{6FAF}\x{6FB0}\x{6FB1}\x{6FB2}\x{6FB3}\x{6FB4}\x{6FB5}' . '\x{6FB6}\x{6FB8}\x{6FB9}\x{6FBA}\x{6FBB}\x{6FBC}\x{6FBD}\x{6FBE}\x{6FBF}' . '\x{6FC0}\x{6FC1}\x{6FC2}\x{6FC3}\x{6FC4}\x{6FC6}\x{6FC7}\x{6FC8}\x{6FC9}' . '\x{6FCA}\x{6FCB}\x{6FCC}\x{6FCD}\x{6FCE}\x{6FCF}\x{6FD1}\x{6FD2}\x{6FD4}' . '\x{6FD5}\x{6FD6}\x{6FD7}\x{6FD8}\x{6FD9}\x{6FDA}\x{6FDB}\x{6FDC}\x{6FDD}' . '\x{6FDE}\x{6FDF}\x{6FE0}\x{6FE1}\x{6FE2}\x{6FE3}\x{6FE4}\x{6FE5}\x{6FE6}' . '\x{6FE7}\x{6FE8}\x{6FE9}\x{6FEA}\x{6FEB}\x{6FEC}\x{6FED}\x{6FEE}\x{6FEF}' . '\x{6FF0}\x{6FF1}\x{6FF2}\x{6FF3}\x{6FF4}\x{6FF6}\x{6FF7}\x{6FF8}\x{6FF9}' . '\x{6FFA}\x{6FFB}\x{6FFC}\x{6FFE}\x{6FFF}\x{7000}\x{7001}\x{7002}\x{7003}' . '\x{7004}\x{7005}\x{7006}\x{7007}\x{7008}\x{7009}\x{700A}\x{700B}\x{700C}' . '\x{700D}\x{700E}\x{700F}\x{7011}\x{7012}\x{7014}\x{7015}\x{7016}\x{7017}' . '\x{7018}\x{7019}\x{701A}\x{701B}\x{701C}\x{701D}\x{701F}\x{7020}\x{7021}' . '\x{7022}\x{7023}\x{7024}\x{7025}\x{7026}\x{7027}\x{7028}\x{7029}\x{702A}' . '\x{702B}\x{702C}\x{702D}\x{702E}\x{702F}\x{7030}\x{7031}\x{7032}\x{7033}' . '\x{7034}\x{7035}\x{7036}\x{7037}\x{7038}\x{7039}\x{703A}\x{703B}\x{703C}' . '\x{703D}\x{703E}\x{703F}\x{7040}\x{7041}\x{7042}\x{7043}\x{7044}\x{7045}' . '\x{7046}\x{7048}\x{7049}\x{704A}\x{704C}\x{704D}\x{704F}\x{7050}\x{7051}' . '\x{7052}\x{7053}\x{7054}\x{7055}\x{7056}\x{7057}\x{7058}\x{7059}\x{705A}' . '\x{705B}\x{705C}\x{705D}\x{705E}\x{705F}\x{7060}\x{7061}\x{7062}\x{7063}' . '\x{7064}\x{7065}\x{7066}\x{7067}\x{7068}\x{7069}\x{706A}\x{706B}\x{706C}' . '\x{706D}\x{706E}\x{706F}\x{7070}\x{7071}\x{7074}\x{7075}\x{7076}\x{7077}' . '\x{7078}\x{7079}\x{707A}\x{707C}\x{707D}\x{707E}\x{707F}\x{7080}\x{7082}' . '\x{7083}\x{7084}\x{7085}\x{7086}\x{7087}\x{7088}\x{7089}\x{708A}\x{708B}' . '\x{708C}\x{708E}\x{708F}\x{7090}\x{7091}\x{7092}\x{7093}\x{7094}\x{7095}' . '\x{7096}\x{7098}\x{7099}\x{709A}\x{709C}\x{709D}\x{709E}\x{709F}\x{70A0}' . '\x{70A1}\x{70A2}\x{70A3}\x{70A4}\x{70A5}\x{70A6}\x{70A7}\x{70A8}\x{70A9}' . '\x{70AB}\x{70AC}\x{70AD}\x{70AE}\x{70AF}\x{70B0}\x{70B1}\x{70B3}\x{70B4}' . '\x{70B5}\x{70B7}\x{70B8}\x{70B9}\x{70BA}\x{70BB}\x{70BC}\x{70BD}\x{70BE}' . '\x{70BF}\x{70C0}\x{70C1}\x{70C2}\x{70C3}\x{70C4}\x{70C5}\x{70C6}\x{70C7}' . '\x{70C8}\x{70C9}\x{70CA}\x{70CB}\x{70CC}\x{70CD}\x{70CE}\x{70CF}\x{70D0}' . '\x{70D1}\x{70D2}\x{70D3}\x{70D4}\x{70D6}\x{70D7}\x{70D8}\x{70D9}\x{70DA}' . '\x{70DB}\x{70DC}\x{70DD}\x{70DE}\x{70DF}\x{70E0}\x{70E1}\x{70E2}\x{70E3}' . '\x{70E4}\x{70E5}\x{70E6}\x{70E7}\x{70E8}\x{70E9}\x{70EA}\x{70EB}\x{70EC}' . '\x{70ED}\x{70EE}\x{70EF}\x{70F0}\x{70F1}\x{70F2}\x{70F3}\x{70F4}\x{70F5}' . '\x{70F6}\x{70F7}\x{70F8}\x{70F9}\x{70FA}\x{70FB}\x{70FC}\x{70FD}\x{70FF}' . '\x{7100}\x{7101}\x{7102}\x{7103}\x{7104}\x{7105}\x{7106}\x{7107}\x{7109}' . '\x{710A}\x{710B}\x{710C}\x{710D}\x{710E}\x{710F}\x{7110}\x{7111}\x{7112}' . '\x{7113}\x{7115}\x{7116}\x{7117}\x{7118}\x{7119}\x{711A}\x{711B}\x{711C}' . '\x{711D}\x{711E}\x{711F}\x{7120}\x{7121}\x{7122}\x{7123}\x{7125}\x{7126}' . '\x{7127}\x{7128}\x{7129}\x{712A}\x{712B}\x{712C}\x{712D}\x{712E}\x{712F}' . '\x{7130}\x{7131}\x{7132}\x{7135}\x{7136}\x{7137}\x{7138}\x{7139}\x{713A}' . '\x{713B}\x{713D}\x{713E}\x{713F}\x{7140}\x{7141}\x{7142}\x{7143}\x{7144}' . '\x{7145}\x{7146}\x{7147}\x{7148}\x{7149}\x{714A}\x{714B}\x{714C}\x{714D}' . '\x{714E}\x{714F}\x{7150}\x{7151}\x{7152}\x{7153}\x{7154}\x{7156}\x{7158}' . '\x{7159}\x{715A}\x{715B}\x{715C}\x{715D}\x{715E}\x{715F}\x{7160}\x{7161}' . '\x{7162}\x{7163}\x{7164}\x{7165}\x{7166}\x{7167}\x{7168}\x{7169}\x{716A}' . '\x{716C}\x{716E}\x{716F}\x{7170}\x{7171}\x{7172}\x{7173}\x{7174}\x{7175}' . '\x{7176}\x{7177}\x{7178}\x{7179}\x{717A}\x{717B}\x{717C}\x{717D}\x{717E}' . '\x{717F}\x{7180}\x{7181}\x{7182}\x{7183}\x{7184}\x{7185}\x{7186}\x{7187}' . '\x{7188}\x{7189}\x{718A}\x{718B}\x{718C}\x{718E}\x{718F}\x{7190}\x{7191}' . '\x{7192}\x{7193}\x{7194}\x{7195}\x{7197}\x{7198}\x{7199}\x{719A}\x{719B}' . '\x{719C}\x{719D}\x{719E}\x{719F}\x{71A0}\x{71A1}\x{71A2}\x{71A3}\x{71A4}' . '\x{71A5}\x{71A7}\x{71A8}\x{71A9}\x{71AA}\x{71AC}\x{71AD}\x{71AE}\x{71AF}' . '\x{71B0}\x{71B1}\x{71B2}\x{71B3}\x{71B4}\x{71B5}\x{71B7}\x{71B8}\x{71B9}' . '\x{71BA}\x{71BB}\x{71BC}\x{71BD}\x{71BE}\x{71BF}\x{71C0}\x{71C1}\x{71C2}' . '\x{71C3}\x{71C4}\x{71C5}\x{71C6}\x{71C7}\x{71C8}\x{71C9}\x{71CA}\x{71CB}' . '\x{71CD}\x{71CE}\x{71CF}\x{71D0}\x{71D1}\x{71D2}\x{71D4}\x{71D5}\x{71D6}' . '\x{71D7}\x{71D8}\x{71D9}\x{71DA}\x{71DB}\x{71DC}\x{71DD}\x{71DE}\x{71DF}' . '\x{71E0}\x{71E1}\x{71E2}\x{71E3}\x{71E4}\x{71E5}\x{71E6}\x{71E7}\x{71E8}' . '\x{71E9}\x{71EA}\x{71EB}\x{71EC}\x{71ED}\x{71EE}\x{71EF}\x{71F0}\x{71F1}' . '\x{71F2}\x{71F4}\x{71F5}\x{71F6}\x{71F7}\x{71F8}\x{71F9}\x{71FB}\x{71FC}' . '\x{71FD}\x{71FE}\x{71FF}\x{7201}\x{7202}\x{7203}\x{7204}\x{7205}\x{7206}' . '\x{7207}\x{7208}\x{7209}\x{720A}\x{720C}\x{720D}\x{720E}\x{720F}\x{7210}' . '\x{7212}\x{7213}\x{7214}\x{7216}\x{7218}\x{7219}\x{721A}\x{721B}\x{721C}' . '\x{721D}\x{721E}\x{721F}\x{7221}\x{7222}\x{7223}\x{7226}\x{7227}\x{7228}' . '\x{7229}\x{722A}\x{722B}\x{722C}\x{722D}\x{722E}\x{7230}\x{7231}\x{7232}' . '\x{7233}\x{7235}\x{7236}\x{7237}\x{7238}\x{7239}\x{723A}\x{723B}\x{723C}' . '\x{723D}\x{723E}\x{723F}\x{7240}\x{7241}\x{7242}\x{7243}\x{7244}\x{7246}' . '\x{7247}\x{7248}\x{7249}\x{724A}\x{724B}\x{724C}\x{724D}\x{724F}\x{7251}' . '\x{7252}\x{7253}\x{7254}\x{7256}\x{7257}\x{7258}\x{7259}\x{725A}\x{725B}' . '\x{725C}\x{725D}\x{725E}\x{725F}\x{7260}\x{7261}\x{7262}\x{7263}\x{7264}' . '\x{7265}\x{7266}\x{7267}\x{7268}\x{7269}\x{726A}\x{726B}\x{726C}\x{726D}' . '\x{726E}\x{726F}\x{7270}\x{7271}\x{7272}\x{7273}\x{7274}\x{7275}\x{7276}' . '\x{7277}\x{7278}\x{7279}\x{727A}\x{727B}\x{727C}\x{727D}\x{727E}\x{727F}' . '\x{7280}\x{7281}\x{7282}\x{7283}\x{7284}\x{7285}\x{7286}\x{7287}\x{7288}' . '\x{7289}\x{728A}\x{728B}\x{728C}\x{728D}\x{728E}\x{728F}\x{7290}\x{7291}' . '\x{7292}\x{7293}\x{7294}\x{7295}\x{7296}\x{7297}\x{7298}\x{7299}\x{729A}' . '\x{729B}\x{729C}\x{729D}\x{729E}\x{729F}\x{72A1}\x{72A2}\x{72A3}\x{72A4}' . '\x{72A5}\x{72A6}\x{72A7}\x{72A8}\x{72A9}\x{72AA}\x{72AC}\x{72AD}\x{72AE}' . '\x{72AF}\x{72B0}\x{72B1}\x{72B2}\x{72B3}\x{72B4}\x{72B5}\x{72B6}\x{72B7}' . '\x{72B8}\x{72B9}\x{72BA}\x{72BB}\x{72BC}\x{72BD}\x{72BF}\x{72C0}\x{72C1}' . '\x{72C2}\x{72C3}\x{72C4}\x{72C5}\x{72C6}\x{72C7}\x{72C8}\x{72C9}\x{72CA}' . '\x{72CB}\x{72CC}\x{72CD}\x{72CE}\x{72CF}\x{72D0}\x{72D1}\x{72D2}\x{72D3}' . '\x{72D4}\x{72D5}\x{72D6}\x{72D7}\x{72D8}\x{72D9}\x{72DA}\x{72DB}\x{72DC}' . '\x{72DD}\x{72DE}\x{72DF}\x{72E0}\x{72E1}\x{72E2}\x{72E3}\x{72E4}\x{72E5}' . '\x{72E6}\x{72E7}\x{72E8}\x{72E9}\x{72EA}\x{72EB}\x{72EC}\x{72ED}\x{72EE}' . '\x{72EF}\x{72F0}\x{72F1}\x{72F2}\x{72F3}\x{72F4}\x{72F5}\x{72F6}\x{72F7}' . '\x{72F8}\x{72F9}\x{72FA}\x{72FB}\x{72FC}\x{72FD}\x{72FE}\x{72FF}\x{7300}' . '\x{7301}\x{7303}\x{7304}\x{7305}\x{7306}\x{7307}\x{7308}\x{7309}\x{730A}' . '\x{730B}\x{730C}\x{730D}\x{730E}\x{730F}\x{7311}\x{7312}\x{7313}\x{7314}' . '\x{7315}\x{7316}\x{7317}\x{7318}\x{7319}\x{731A}\x{731B}\x{731C}\x{731D}' . '\x{731E}\x{7320}\x{7321}\x{7322}\x{7323}\x{7324}\x{7325}\x{7326}\x{7327}' . '\x{7329}\x{732A}\x{732B}\x{732C}\x{732D}\x{732E}\x{7330}\x{7331}\x{7332}' . '\x{7333}\x{7334}\x{7335}\x{7336}\x{7337}\x{7338}\x{7339}\x{733A}\x{733B}' . '\x{733C}\x{733D}\x{733E}\x{733F}\x{7340}\x{7341}\x{7342}\x{7343}\x{7344}' . '\x{7345}\x{7346}\x{7347}\x{7348}\x{7349}\x{734A}\x{734B}\x{734C}\x{734D}' . '\x{734E}\x{7350}\x{7351}\x{7352}\x{7354}\x{7355}\x{7356}\x{7357}\x{7358}' . '\x{7359}\x{735A}\x{735B}\x{735C}\x{735D}\x{735E}\x{735F}\x{7360}\x{7361}' . '\x{7362}\x{7364}\x{7365}\x{7366}\x{7367}\x{7368}\x{7369}\x{736A}\x{736B}' . '\x{736C}\x{736D}\x{736E}\x{736F}\x{7370}\x{7371}\x{7372}\x{7373}\x{7374}' . '\x{7375}\x{7376}\x{7377}\x{7378}\x{7379}\x{737A}\x{737B}\x{737C}\x{737D}' . '\x{737E}\x{737F}\x{7380}\x{7381}\x{7382}\x{7383}\x{7384}\x{7385}\x{7386}' . '\x{7387}\x{7388}\x{7389}\x{738A}\x{738B}\x{738C}\x{738D}\x{738E}\x{738F}' . '\x{7390}\x{7391}\x{7392}\x{7393}\x{7394}\x{7395}\x{7396}\x{7397}\x{7398}' . '\x{7399}\x{739A}\x{739B}\x{739D}\x{739E}\x{739F}\x{73A0}\x{73A1}\x{73A2}' . '\x{73A3}\x{73A4}\x{73A5}\x{73A6}\x{73A7}\x{73A8}\x{73A9}\x{73AA}\x{73AB}' . '\x{73AC}\x{73AD}\x{73AE}\x{73AF}\x{73B0}\x{73B1}\x{73B2}\x{73B3}\x{73B4}' . '\x{73B5}\x{73B6}\x{73B7}\x{73B8}\x{73B9}\x{73BA}\x{73BB}\x{73BC}\x{73BD}' . '\x{73BE}\x{73BF}\x{73C0}\x{73C2}\x{73C3}\x{73C4}\x{73C5}\x{73C6}\x{73C7}' . '\x{73C8}\x{73C9}\x{73CA}\x{73CB}\x{73CC}\x{73CD}\x{73CE}\x{73CF}\x{73D0}' . '\x{73D1}\x{73D2}\x{73D3}\x{73D4}\x{73D5}\x{73D6}\x{73D7}\x{73D8}\x{73D9}' . '\x{73DA}\x{73DB}\x{73DC}\x{73DD}\x{73DE}\x{73DF}\x{73E0}\x{73E2}\x{73E3}' . '\x{73E5}\x{73E6}\x{73E7}\x{73E8}\x{73E9}\x{73EA}\x{73EB}\x{73EC}\x{73ED}' . '\x{73EE}\x{73EF}\x{73F0}\x{73F1}\x{73F2}\x{73F4}\x{73F5}\x{73F6}\x{73F7}' . '\x{73F8}\x{73F9}\x{73FA}\x{73FC}\x{73FD}\x{73FE}\x{73FF}\x{7400}\x{7401}' . '\x{7402}\x{7403}\x{7404}\x{7405}\x{7406}\x{7407}\x{7408}\x{7409}\x{740A}' . '\x{740B}\x{740C}\x{740D}\x{740E}\x{740F}\x{7410}\x{7411}\x{7412}\x{7413}' . '\x{7414}\x{7415}\x{7416}\x{7417}\x{7419}\x{741A}\x{741B}\x{741C}\x{741D}' . '\x{741E}\x{741F}\x{7420}\x{7421}\x{7422}\x{7423}\x{7424}\x{7425}\x{7426}' . '\x{7427}\x{7428}\x{7429}\x{742A}\x{742B}\x{742C}\x{742D}\x{742E}\x{742F}' . '\x{7430}\x{7431}\x{7432}\x{7433}\x{7434}\x{7435}\x{7436}\x{7437}\x{7438}' . '\x{743A}\x{743B}\x{743C}\x{743D}\x{743F}\x{7440}\x{7441}\x{7442}\x{7443}' . '\x{7444}\x{7445}\x{7446}\x{7448}\x{744A}\x{744B}\x{744C}\x{744D}\x{744E}' . '\x{744F}\x{7450}\x{7451}\x{7452}\x{7453}\x{7454}\x{7455}\x{7456}\x{7457}' . '\x{7459}\x{745A}\x{745B}\x{745C}\x{745D}\x{745E}\x{745F}\x{7461}\x{7462}' . '\x{7463}\x{7464}\x{7465}\x{7466}\x{7467}\x{7468}\x{7469}\x{746A}\x{746B}' . '\x{746C}\x{746D}\x{746E}\x{746F}\x{7470}\x{7471}\x{7472}\x{7473}\x{7474}' . '\x{7475}\x{7476}\x{7477}\x{7478}\x{7479}\x{747A}\x{747C}\x{747D}\x{747E}' . '\x{747F}\x{7480}\x{7481}\x{7482}\x{7483}\x{7485}\x{7486}\x{7487}\x{7488}' . '\x{7489}\x{748A}\x{748B}\x{748C}\x{748D}\x{748E}\x{748F}\x{7490}\x{7491}' . '\x{7492}\x{7493}\x{7494}\x{7495}\x{7497}\x{7498}\x{7499}\x{749A}\x{749B}' . '\x{749C}\x{749E}\x{749F}\x{74A0}\x{74A1}\x{74A3}\x{74A4}\x{74A5}\x{74A6}' . '\x{74A7}\x{74A8}\x{74A9}\x{74AA}\x{74AB}\x{74AC}\x{74AD}\x{74AE}\x{74AF}' . '\x{74B0}\x{74B1}\x{74B2}\x{74B3}\x{74B4}\x{74B5}\x{74B6}\x{74B7}\x{74B8}' . '\x{74B9}\x{74BA}\x{74BB}\x{74BC}\x{74BD}\x{74BE}\x{74BF}\x{74C0}\x{74C1}' . '\x{74C2}\x{74C3}\x{74C4}\x{74C5}\x{74C6}\x{74CA}\x{74CB}\x{74CD}\x{74CE}' . '\x{74CF}\x{74D0}\x{74D1}\x{74D2}\x{74D3}\x{74D4}\x{74D5}\x{74D6}\x{74D7}' . '\x{74D8}\x{74D9}\x{74DA}\x{74DB}\x{74DC}\x{74DD}\x{74DE}\x{74DF}\x{74E0}' . '\x{74E1}\x{74E2}\x{74E3}\x{74E4}\x{74E5}\x{74E6}\x{74E7}\x{74E8}\x{74E9}' . '\x{74EA}\x{74EC}\x{74ED}\x{74EE}\x{74EF}\x{74F0}\x{74F1}\x{74F2}\x{74F3}' . '\x{74F4}\x{74F5}\x{74F6}\x{74F7}\x{74F8}\x{74F9}\x{74FA}\x{74FB}\x{74FC}' . '\x{74FD}\x{74FE}\x{74FF}\x{7500}\x{7501}\x{7502}\x{7503}\x{7504}\x{7505}' . '\x{7506}\x{7507}\x{7508}\x{7509}\x{750A}\x{750B}\x{750C}\x{750D}\x{750F}' . '\x{7510}\x{7511}\x{7512}\x{7513}\x{7514}\x{7515}\x{7516}\x{7517}\x{7518}' . '\x{7519}\x{751A}\x{751B}\x{751C}\x{751D}\x{751E}\x{751F}\x{7521}\x{7522}' . '\x{7523}\x{7524}\x{7525}\x{7526}\x{7527}\x{7528}\x{7529}\x{752A}\x{752B}' . '\x{752C}\x{752D}\x{752E}\x{752F}\x{7530}\x{7531}\x{7532}\x{7533}\x{7535}' . '\x{7536}\x{7537}\x{7538}\x{7539}\x{753A}\x{753B}\x{753C}\x{753D}\x{753E}' . '\x{753F}\x{7540}\x{7542}\x{7543}\x{7544}\x{7545}\x{7546}\x{7547}\x{7548}' . '\x{7549}\x{754B}\x{754C}\x{754D}\x{754E}\x{754F}\x{7550}\x{7551}\x{7553}' . '\x{7554}\x{7556}\x{7557}\x{7558}\x{7559}\x{755A}\x{755B}\x{755C}\x{755D}' . '\x{755F}\x{7560}\x{7562}\x{7563}\x{7564}\x{7565}\x{7566}\x{7567}\x{7568}' . '\x{7569}\x{756A}\x{756B}\x{756C}\x{756D}\x{756E}\x{756F}\x{7570}\x{7572}' . '\x{7574}\x{7575}\x{7576}\x{7577}\x{7578}\x{7579}\x{757C}\x{757D}\x{757E}' . '\x{757F}\x{7580}\x{7581}\x{7582}\x{7583}\x{7584}\x{7586}\x{7587}\x{7588}' . '\x{7589}\x{758A}\x{758B}\x{758C}\x{758D}\x{758F}\x{7590}\x{7591}\x{7592}' . '\x{7593}\x{7594}\x{7595}\x{7596}\x{7597}\x{7598}\x{7599}\x{759A}\x{759B}' . '\x{759C}\x{759D}\x{759E}\x{759F}\x{75A0}\x{75A1}\x{75A2}\x{75A3}\x{75A4}' . '\x{75A5}\x{75A6}\x{75A7}\x{75A8}\x{75AA}\x{75AB}\x{75AC}\x{75AD}\x{75AE}' . '\x{75AF}\x{75B0}\x{75B1}\x{75B2}\x{75B3}\x{75B4}\x{75B5}\x{75B6}\x{75B8}' . '\x{75B9}\x{75BA}\x{75BB}\x{75BC}\x{75BD}\x{75BE}\x{75BF}\x{75C0}\x{75C1}' . '\x{75C2}\x{75C3}\x{75C4}\x{75C5}\x{75C6}\x{75C7}\x{75C8}\x{75C9}\x{75CA}' . '\x{75CB}\x{75CC}\x{75CD}\x{75CE}\x{75CF}\x{75D0}\x{75D1}\x{75D2}\x{75D3}' . '\x{75D4}\x{75D5}\x{75D6}\x{75D7}\x{75D8}\x{75D9}\x{75DA}\x{75DB}\x{75DD}' . '\x{75DE}\x{75DF}\x{75E0}\x{75E1}\x{75E2}\x{75E3}\x{75E4}\x{75E5}\x{75E6}' . '\x{75E7}\x{75E8}\x{75EA}\x{75EB}\x{75EC}\x{75ED}\x{75EF}\x{75F0}\x{75F1}' . '\x{75F2}\x{75F3}\x{75F4}\x{75F5}\x{75F6}\x{75F7}\x{75F8}\x{75F9}\x{75FA}' . '\x{75FB}\x{75FC}\x{75FD}\x{75FE}\x{75FF}\x{7600}\x{7601}\x{7602}\x{7603}' . '\x{7604}\x{7605}\x{7606}\x{7607}\x{7608}\x{7609}\x{760A}\x{760B}\x{760C}' . '\x{760D}\x{760E}\x{760F}\x{7610}\x{7611}\x{7612}\x{7613}\x{7614}\x{7615}' . '\x{7616}\x{7617}\x{7618}\x{7619}\x{761A}\x{761B}\x{761C}\x{761D}\x{761E}' . '\x{761F}\x{7620}\x{7621}\x{7622}\x{7623}\x{7624}\x{7625}\x{7626}\x{7627}' . '\x{7628}\x{7629}\x{762A}\x{762B}\x{762D}\x{762E}\x{762F}\x{7630}\x{7631}' . '\x{7632}\x{7633}\x{7634}\x{7635}\x{7636}\x{7637}\x{7638}\x{7639}\x{763A}' . '\x{763B}\x{763C}\x{763D}\x{763E}\x{763F}\x{7640}\x{7641}\x{7642}\x{7643}' . '\x{7646}\x{7647}\x{7648}\x{7649}\x{764A}\x{764B}\x{764C}\x{764D}\x{764F}' . '\x{7650}\x{7652}\x{7653}\x{7654}\x{7656}\x{7657}\x{7658}\x{7659}\x{765A}' . '\x{765B}\x{765C}\x{765D}\x{765E}\x{765F}\x{7660}\x{7661}\x{7662}\x{7663}' . '\x{7664}\x{7665}\x{7666}\x{7667}\x{7668}\x{7669}\x{766A}\x{766B}\x{766C}' . '\x{766D}\x{766E}\x{766F}\x{7670}\x{7671}\x{7672}\x{7674}\x{7675}\x{7676}' . '\x{7677}\x{7678}\x{7679}\x{767B}\x{767C}\x{767D}\x{767E}\x{767F}\x{7680}' . '\x{7681}\x{7682}\x{7683}\x{7684}\x{7685}\x{7686}\x{7687}\x{7688}\x{7689}' . '\x{768A}\x{768B}\x{768C}\x{768E}\x{768F}\x{7690}\x{7691}\x{7692}\x{7693}' . '\x{7694}\x{7695}\x{7696}\x{7697}\x{7698}\x{7699}\x{769A}\x{769B}\x{769C}' . '\x{769D}\x{769E}\x{769F}\x{76A0}\x{76A3}\x{76A4}\x{76A6}\x{76A7}\x{76A9}' . '\x{76AA}\x{76AB}\x{76AC}\x{76AD}\x{76AE}\x{76AF}\x{76B0}\x{76B1}\x{76B2}' . '\x{76B4}\x{76B5}\x{76B7}\x{76B8}\x{76BA}\x{76BB}\x{76BC}\x{76BD}\x{76BE}' . '\x{76BF}\x{76C0}\x{76C2}\x{76C3}\x{76C4}\x{76C5}\x{76C6}\x{76C7}\x{76C8}' . '\x{76C9}\x{76CA}\x{76CD}\x{76CE}\x{76CF}\x{76D0}\x{76D1}\x{76D2}\x{76D3}' . '\x{76D4}\x{76D5}\x{76D6}\x{76D7}\x{76D8}\x{76DA}\x{76DB}\x{76DC}\x{76DD}' . '\x{76DE}\x{76DF}\x{76E0}\x{76E1}\x{76E2}\x{76E3}\x{76E4}\x{76E5}\x{76E6}' . '\x{76E7}\x{76E8}\x{76E9}\x{76EA}\x{76EC}\x{76ED}\x{76EE}\x{76EF}\x{76F0}' . '\x{76F1}\x{76F2}\x{76F3}\x{76F4}\x{76F5}\x{76F6}\x{76F7}\x{76F8}\x{76F9}' . '\x{76FA}\x{76FB}\x{76FC}\x{76FD}\x{76FE}\x{76FF}\x{7701}\x{7703}\x{7704}' . '\x{7705}\x{7706}\x{7707}\x{7708}\x{7709}\x{770A}\x{770B}\x{770C}\x{770D}' . '\x{770F}\x{7710}\x{7711}\x{7712}\x{7713}\x{7714}\x{7715}\x{7716}\x{7717}' . '\x{7718}\x{7719}\x{771A}\x{771B}\x{771C}\x{771D}\x{771E}\x{771F}\x{7720}' . '\x{7722}\x{7723}\x{7725}\x{7726}\x{7727}\x{7728}\x{7729}\x{772A}\x{772C}' . '\x{772D}\x{772E}\x{772F}\x{7730}\x{7731}\x{7732}\x{7733}\x{7734}\x{7735}' . '\x{7736}\x{7737}\x{7738}\x{7739}\x{773A}\x{773B}\x{773C}\x{773D}\x{773E}' . '\x{7740}\x{7741}\x{7743}\x{7744}\x{7745}\x{7746}\x{7747}\x{7748}\x{7749}' . '\x{774A}\x{774B}\x{774C}\x{774D}\x{774E}\x{774F}\x{7750}\x{7751}\x{7752}' . '\x{7753}\x{7754}\x{7755}\x{7756}\x{7757}\x{7758}\x{7759}\x{775A}\x{775B}' . '\x{775C}\x{775D}\x{775E}\x{775F}\x{7760}\x{7761}\x{7762}\x{7763}\x{7765}' . '\x{7766}\x{7767}\x{7768}\x{7769}\x{776A}\x{776B}\x{776C}\x{776D}\x{776E}' . '\x{776F}\x{7770}\x{7771}\x{7772}\x{7773}\x{7774}\x{7775}\x{7776}\x{7777}' . '\x{7778}\x{7779}\x{777A}\x{777B}\x{777C}\x{777D}\x{777E}\x{777F}\x{7780}' . '\x{7781}\x{7782}\x{7783}\x{7784}\x{7785}\x{7786}\x{7787}\x{7788}\x{7789}' . '\x{778A}\x{778B}\x{778C}\x{778D}\x{778E}\x{778F}\x{7790}\x{7791}\x{7792}' . '\x{7793}\x{7794}\x{7795}\x{7797}\x{7798}\x{7799}\x{779A}\x{779B}\x{779C}' . '\x{779D}\x{779E}\x{779F}\x{77A0}\x{77A1}\x{77A2}\x{77A3}\x{77A5}\x{77A6}' . '\x{77A7}\x{77A8}\x{77A9}\x{77AA}\x{77AB}\x{77AC}\x{77AD}\x{77AE}\x{77AF}' . '\x{77B0}\x{77B1}\x{77B2}\x{77B3}\x{77B4}\x{77B5}\x{77B6}\x{77B7}\x{77B8}' . '\x{77B9}\x{77BA}\x{77BB}\x{77BC}\x{77BD}\x{77BF}\x{77C0}\x{77C2}\x{77C3}' . '\x{77C4}\x{77C5}\x{77C6}\x{77C7}\x{77C8}\x{77C9}\x{77CA}\x{77CB}\x{77CC}' . '\x{77CD}\x{77CE}\x{77CF}\x{77D0}\x{77D1}\x{77D3}\x{77D4}\x{77D5}\x{77D6}' . '\x{77D7}\x{77D8}\x{77D9}\x{77DA}\x{77DB}\x{77DC}\x{77DE}\x{77DF}\x{77E0}' . '\x{77E1}\x{77E2}\x{77E3}\x{77E5}\x{77E7}\x{77E8}\x{77E9}\x{77EA}\x{77EB}' . '\x{77EC}\x{77ED}\x{77EE}\x{77EF}\x{77F0}\x{77F1}\x{77F2}\x{77F3}\x{77F6}' . '\x{77F7}\x{77F8}\x{77F9}\x{77FA}\x{77FB}\x{77FC}\x{77FD}\x{77FE}\x{77FF}' . '\x{7800}\x{7801}\x{7802}\x{7803}\x{7804}\x{7805}\x{7806}\x{7808}\x{7809}' . '\x{780A}\x{780B}\x{780C}\x{780D}\x{780E}\x{780F}\x{7810}\x{7811}\x{7812}' . '\x{7813}\x{7814}\x{7815}\x{7816}\x{7817}\x{7818}\x{7819}\x{781A}\x{781B}' . '\x{781C}\x{781D}\x{781E}\x{781F}\x{7820}\x{7821}\x{7822}\x{7823}\x{7825}' . '\x{7826}\x{7827}\x{7828}\x{7829}\x{782A}\x{782B}\x{782C}\x{782D}\x{782E}' . '\x{782F}\x{7830}\x{7831}\x{7832}\x{7833}\x{7834}\x{7835}\x{7837}\x{7838}' . '\x{7839}\x{783A}\x{783B}\x{783C}\x{783D}\x{783E}\x{7840}\x{7841}\x{7843}' . '\x{7844}\x{7845}\x{7847}\x{7848}\x{7849}\x{784A}\x{784C}\x{784D}\x{784E}' . '\x{7850}\x{7851}\x{7852}\x{7853}\x{7854}\x{7855}\x{7856}\x{7857}\x{7858}' . '\x{7859}\x{785A}\x{785B}\x{785C}\x{785D}\x{785E}\x{785F}\x{7860}\x{7861}' . '\x{7862}\x{7863}\x{7864}\x{7865}\x{7866}\x{7867}\x{7868}\x{7869}\x{786A}' . '\x{786B}\x{786C}\x{786D}\x{786E}\x{786F}\x{7870}\x{7871}\x{7872}\x{7873}' . '\x{7874}\x{7875}\x{7877}\x{7878}\x{7879}\x{787A}\x{787B}\x{787C}\x{787D}' . '\x{787E}\x{787F}\x{7880}\x{7881}\x{7882}\x{7883}\x{7884}\x{7885}\x{7886}' . '\x{7887}\x{7889}\x{788A}\x{788B}\x{788C}\x{788D}\x{788E}\x{788F}\x{7890}' . '\x{7891}\x{7892}\x{7893}\x{7894}\x{7895}\x{7896}\x{7897}\x{7898}\x{7899}' . '\x{789A}\x{789B}\x{789C}\x{789D}\x{789E}\x{789F}\x{78A0}\x{78A1}\x{78A2}' . '\x{78A3}\x{78A4}\x{78A5}\x{78A6}\x{78A7}\x{78A8}\x{78A9}\x{78AA}\x{78AB}' . '\x{78AC}\x{78AD}\x{78AE}\x{78AF}\x{78B0}\x{78B1}\x{78B2}\x{78B3}\x{78B4}' . '\x{78B5}\x{78B6}\x{78B7}\x{78B8}\x{78B9}\x{78BA}\x{78BB}\x{78BC}\x{78BD}' . '\x{78BE}\x{78BF}\x{78C0}\x{78C1}\x{78C3}\x{78C4}\x{78C5}\x{78C6}\x{78C8}' . '\x{78C9}\x{78CA}\x{78CB}\x{78CC}\x{78CD}\x{78CE}\x{78CF}\x{78D0}\x{78D1}' . '\x{78D3}\x{78D4}\x{78D5}\x{78D6}\x{78D7}\x{78D8}\x{78D9}\x{78DA}\x{78DB}' . '\x{78DC}\x{78DD}\x{78DE}\x{78DF}\x{78E0}\x{78E1}\x{78E2}\x{78E3}\x{78E4}' . '\x{78E5}\x{78E6}\x{78E7}\x{78E8}\x{78E9}\x{78EA}\x{78EB}\x{78EC}\x{78ED}' . '\x{78EE}\x{78EF}\x{78F1}\x{78F2}\x{78F3}\x{78F4}\x{78F5}\x{78F6}\x{78F7}' . '\x{78F9}\x{78FA}\x{78FB}\x{78FC}\x{78FD}\x{78FE}\x{78FF}\x{7901}\x{7902}' . '\x{7903}\x{7904}\x{7905}\x{7906}\x{7907}\x{7909}\x{790A}\x{790B}\x{790C}' . '\x{790E}\x{790F}\x{7910}\x{7911}\x{7912}\x{7913}\x{7914}\x{7916}\x{7917}' . '\x{7918}\x{7919}\x{791A}\x{791B}\x{791C}\x{791D}\x{791E}\x{7921}\x{7922}' . '\x{7923}\x{7924}\x{7925}\x{7926}\x{7927}\x{7928}\x{7929}\x{792A}\x{792B}' . '\x{792C}\x{792D}\x{792E}\x{792F}\x{7930}\x{7931}\x{7933}\x{7934}\x{7935}' . '\x{7937}\x{7938}\x{7939}\x{793A}\x{793B}\x{793C}\x{793D}\x{793E}\x{793F}' . '\x{7940}\x{7941}\x{7942}\x{7943}\x{7944}\x{7945}\x{7946}\x{7947}\x{7948}' . '\x{7949}\x{794A}\x{794B}\x{794C}\x{794D}\x{794E}\x{794F}\x{7950}\x{7951}' . '\x{7952}\x{7953}\x{7954}\x{7955}\x{7956}\x{7957}\x{7958}\x{795A}\x{795B}' . '\x{795C}\x{795D}\x{795E}\x{795F}\x{7960}\x{7961}\x{7962}\x{7963}\x{7964}' . '\x{7965}\x{7966}\x{7967}\x{7968}\x{7969}\x{796A}\x{796B}\x{796D}\x{796F}' . '\x{7970}\x{7971}\x{7972}\x{7973}\x{7974}\x{7977}\x{7978}\x{7979}\x{797A}' . '\x{797B}\x{797C}\x{797D}\x{797E}\x{797F}\x{7980}\x{7981}\x{7982}\x{7983}' . '\x{7984}\x{7985}\x{7988}\x{7989}\x{798A}\x{798B}\x{798C}\x{798D}\x{798E}' . '\x{798F}\x{7990}\x{7991}\x{7992}\x{7993}\x{7994}\x{7995}\x{7996}\x{7997}' . '\x{7998}\x{7999}\x{799A}\x{799B}\x{799C}\x{799F}\x{79A0}\x{79A1}\x{79A2}' . '\x{79A3}\x{79A4}\x{79A5}\x{79A6}\x{79A7}\x{79A8}\x{79AA}\x{79AB}\x{79AC}' . '\x{79AD}\x{79AE}\x{79AF}\x{79B0}\x{79B1}\x{79B2}\x{79B3}\x{79B4}\x{79B5}' . '\x{79B6}\x{79B7}\x{79B8}\x{79B9}\x{79BA}\x{79BB}\x{79BD}\x{79BE}\x{79BF}' . '\x{79C0}\x{79C1}\x{79C2}\x{79C3}\x{79C5}\x{79C6}\x{79C8}\x{79C9}\x{79CA}' . '\x{79CB}\x{79CD}\x{79CE}\x{79CF}\x{79D0}\x{79D1}\x{79D2}\x{79D3}\x{79D5}' . '\x{79D6}\x{79D8}\x{79D9}\x{79DA}\x{79DB}\x{79DC}\x{79DD}\x{79DE}\x{79DF}' . '\x{79E0}\x{79E1}\x{79E2}\x{79E3}\x{79E4}\x{79E5}\x{79E6}\x{79E7}\x{79E8}' . '\x{79E9}\x{79EA}\x{79EB}\x{79EC}\x{79ED}\x{79EE}\x{79EF}\x{79F0}\x{79F1}' . '\x{79F2}\x{79F3}\x{79F4}\x{79F5}\x{79F6}\x{79F7}\x{79F8}\x{79F9}\x{79FA}' . '\x{79FB}\x{79FC}\x{79FD}\x{79FE}\x{79FF}\x{7A00}\x{7A02}\x{7A03}\x{7A04}' . '\x{7A05}\x{7A06}\x{7A08}\x{7A0A}\x{7A0B}\x{7A0C}\x{7A0D}\x{7A0E}\x{7A0F}' . '\x{7A10}\x{7A11}\x{7A12}\x{7A13}\x{7A14}\x{7A15}\x{7A16}\x{7A17}\x{7A18}' . '\x{7A19}\x{7A1A}\x{7A1B}\x{7A1C}\x{7A1D}\x{7A1E}\x{7A1F}\x{7A20}\x{7A21}' . '\x{7A22}\x{7A23}\x{7A24}\x{7A25}\x{7A26}\x{7A27}\x{7A28}\x{7A29}\x{7A2A}' . '\x{7A2B}\x{7A2D}\x{7A2E}\x{7A2F}\x{7A30}\x{7A31}\x{7A32}\x{7A33}\x{7A34}' . '\x{7A35}\x{7A37}\x{7A39}\x{7A3B}\x{7A3C}\x{7A3D}\x{7A3E}\x{7A3F}\x{7A40}' . '\x{7A41}\x{7A42}\x{7A43}\x{7A44}\x{7A45}\x{7A46}\x{7A47}\x{7A48}\x{7A49}' . '\x{7A4A}\x{7A4B}\x{7A4C}\x{7A4D}\x{7A4E}\x{7A50}\x{7A51}\x{7A52}\x{7A53}' . '\x{7A54}\x{7A55}\x{7A56}\x{7A57}\x{7A58}\x{7A59}\x{7A5A}\x{7A5B}\x{7A5C}' . '\x{7A5D}\x{7A5E}\x{7A5F}\x{7A60}\x{7A61}\x{7A62}\x{7A65}\x{7A66}\x{7A67}' . '\x{7A68}\x{7A69}\x{7A6B}\x{7A6C}\x{7A6D}\x{7A6E}\x{7A70}\x{7A71}\x{7A72}' . '\x{7A73}\x{7A74}\x{7A75}\x{7A76}\x{7A77}\x{7A78}\x{7A79}\x{7A7A}\x{7A7B}' . '\x{7A7C}\x{7A7D}\x{7A7E}\x{7A7F}\x{7A80}\x{7A81}\x{7A83}\x{7A84}\x{7A85}' . '\x{7A86}\x{7A87}\x{7A88}\x{7A89}\x{7A8A}\x{7A8B}\x{7A8C}\x{7A8D}\x{7A8E}' . '\x{7A8F}\x{7A90}\x{7A91}\x{7A92}\x{7A93}\x{7A94}\x{7A95}\x{7A96}\x{7A97}' . '\x{7A98}\x{7A99}\x{7A9C}\x{7A9D}\x{7A9E}\x{7A9F}\x{7AA0}\x{7AA1}\x{7AA2}' . '\x{7AA3}\x{7AA4}\x{7AA5}\x{7AA6}\x{7AA7}\x{7AA8}\x{7AA9}\x{7AAA}\x{7AAB}' . '\x{7AAC}\x{7AAD}\x{7AAE}\x{7AAF}\x{7AB0}\x{7AB1}\x{7AB2}\x{7AB3}\x{7AB4}' . '\x{7AB5}\x{7AB6}\x{7AB7}\x{7AB8}\x{7ABA}\x{7ABE}\x{7ABF}\x{7AC0}\x{7AC1}' . '\x{7AC4}\x{7AC5}\x{7AC7}\x{7AC8}\x{7AC9}\x{7ACA}\x{7ACB}\x{7ACC}\x{7ACD}' . '\x{7ACE}\x{7ACF}\x{7AD0}\x{7AD1}\x{7AD2}\x{7AD3}\x{7AD4}\x{7AD5}\x{7AD6}' . '\x{7AD8}\x{7AD9}\x{7ADB}\x{7ADC}\x{7ADD}\x{7ADE}\x{7ADF}\x{7AE0}\x{7AE1}' . '\x{7AE2}\x{7AE3}\x{7AE4}\x{7AE5}\x{7AE6}\x{7AE7}\x{7AE8}\x{7AEA}\x{7AEB}' . '\x{7AEC}\x{7AED}\x{7AEE}\x{7AEF}\x{7AF0}\x{7AF1}\x{7AF2}\x{7AF3}\x{7AF4}' . '\x{7AF6}\x{7AF7}\x{7AF8}\x{7AF9}\x{7AFA}\x{7AFB}\x{7AFD}\x{7AFE}\x{7AFF}' . '\x{7B00}\x{7B01}\x{7B02}\x{7B03}\x{7B04}\x{7B05}\x{7B06}\x{7B08}\x{7B09}' . '\x{7B0A}\x{7B0B}\x{7B0C}\x{7B0D}\x{7B0E}\x{7B0F}\x{7B10}\x{7B11}\x{7B12}' . '\x{7B13}\x{7B14}\x{7B15}\x{7B16}\x{7B17}\x{7B18}\x{7B19}\x{7B1A}\x{7B1B}' . '\x{7B1C}\x{7B1D}\x{7B1E}\x{7B20}\x{7B21}\x{7B22}\x{7B23}\x{7B24}\x{7B25}' . '\x{7B26}\x{7B28}\x{7B2A}\x{7B2B}\x{7B2C}\x{7B2D}\x{7B2E}\x{7B2F}\x{7B30}' . '\x{7B31}\x{7B32}\x{7B33}\x{7B34}\x{7B35}\x{7B36}\x{7B37}\x{7B38}\x{7B39}' . '\x{7B3A}\x{7B3B}\x{7B3C}\x{7B3D}\x{7B3E}\x{7B3F}\x{7B40}\x{7B41}\x{7B43}' . '\x{7B44}\x{7B45}\x{7B46}\x{7B47}\x{7B48}\x{7B49}\x{7B4A}\x{7B4B}\x{7B4C}' . '\x{7B4D}\x{7B4E}\x{7B4F}\x{7B50}\x{7B51}\x{7B52}\x{7B54}\x{7B55}\x{7B56}' . '\x{7B57}\x{7B58}\x{7B59}\x{7B5A}\x{7B5B}\x{7B5C}\x{7B5D}\x{7B5E}\x{7B5F}' . '\x{7B60}\x{7B61}\x{7B62}\x{7B63}\x{7B64}\x{7B65}\x{7B66}\x{7B67}\x{7B68}' . '\x{7B69}\x{7B6A}\x{7B6B}\x{7B6C}\x{7B6D}\x{7B6E}\x{7B70}\x{7B71}\x{7B72}' . '\x{7B73}\x{7B74}\x{7B75}\x{7B76}\x{7B77}\x{7B78}\x{7B79}\x{7B7B}\x{7B7C}' . '\x{7B7D}\x{7B7E}\x{7B7F}\x{7B80}\x{7B81}\x{7B82}\x{7B83}\x{7B84}\x{7B85}' . '\x{7B87}\x{7B88}\x{7B89}\x{7B8A}\x{7B8B}\x{7B8C}\x{7B8D}\x{7B8E}\x{7B8F}' . '\x{7B90}\x{7B91}\x{7B93}\x{7B94}\x{7B95}\x{7B96}\x{7B97}\x{7B98}\x{7B99}' . '\x{7B9A}\x{7B9B}\x{7B9C}\x{7B9D}\x{7B9E}\x{7B9F}\x{7BA0}\x{7BA1}\x{7BA2}' . '\x{7BA4}\x{7BA6}\x{7BA7}\x{7BA8}\x{7BA9}\x{7BAA}\x{7BAB}\x{7BAC}\x{7BAD}' . '\x{7BAE}\x{7BAF}\x{7BB1}\x{7BB3}\x{7BB4}\x{7BB5}\x{7BB6}\x{7BB7}\x{7BB8}' . '\x{7BB9}\x{7BBA}\x{7BBB}\x{7BBC}\x{7BBD}\x{7BBE}\x{7BBF}\x{7BC0}\x{7BC1}' . '\x{7BC2}\x{7BC3}\x{7BC4}\x{7BC5}\x{7BC6}\x{7BC7}\x{7BC8}\x{7BC9}\x{7BCA}' . '\x{7BCB}\x{7BCC}\x{7BCD}\x{7BCE}\x{7BD0}\x{7BD1}\x{7BD2}\x{7BD3}\x{7BD4}' . '\x{7BD5}\x{7BD6}\x{7BD7}\x{7BD8}\x{7BD9}\x{7BDA}\x{7BDB}\x{7BDC}\x{7BDD}' . '\x{7BDE}\x{7BDF}\x{7BE0}\x{7BE1}\x{7BE2}\x{7BE3}\x{7BE4}\x{7BE5}\x{7BE6}' . '\x{7BE7}\x{7BE8}\x{7BE9}\x{7BEA}\x{7BEB}\x{7BEC}\x{7BED}\x{7BEE}\x{7BEF}' . '\x{7BF0}\x{7BF1}\x{7BF2}\x{7BF3}\x{7BF4}\x{7BF5}\x{7BF6}\x{7BF7}\x{7BF8}' . '\x{7BF9}\x{7BFB}\x{7BFC}\x{7BFD}\x{7BFE}\x{7BFF}\x{7C00}\x{7C01}\x{7C02}' . '\x{7C03}\x{7C04}\x{7C05}\x{7C06}\x{7C07}\x{7C08}\x{7C09}\x{7C0A}\x{7C0B}' . '\x{7C0C}\x{7C0D}\x{7C0E}\x{7C0F}\x{7C10}\x{7C11}\x{7C12}\x{7C13}\x{7C15}' . '\x{7C16}\x{7C17}\x{7C18}\x{7C19}\x{7C1A}\x{7C1C}\x{7C1D}\x{7C1E}\x{7C1F}' . '\x{7C20}\x{7C21}\x{7C22}\x{7C23}\x{7C24}\x{7C25}\x{7C26}\x{7C27}\x{7C28}' . '\x{7C29}\x{7C2A}\x{7C2B}\x{7C2C}\x{7C2D}\x{7C30}\x{7C31}\x{7C32}\x{7C33}' . '\x{7C34}\x{7C35}\x{7C36}\x{7C37}\x{7C38}\x{7C39}\x{7C3A}\x{7C3B}\x{7C3C}' . '\x{7C3D}\x{7C3E}\x{7C3F}\x{7C40}\x{7C41}\x{7C42}\x{7C43}\x{7C44}\x{7C45}' . '\x{7C46}\x{7C47}\x{7C48}\x{7C49}\x{7C4A}\x{7C4B}\x{7C4C}\x{7C4D}\x{7C4E}' . '\x{7C50}\x{7C51}\x{7C53}\x{7C54}\x{7C56}\x{7C57}\x{7C58}\x{7C59}\x{7C5A}' . '\x{7C5B}\x{7C5C}\x{7C5E}\x{7C5F}\x{7C60}\x{7C61}\x{7C62}\x{7C63}\x{7C64}' . '\x{7C65}\x{7C66}\x{7C67}\x{7C68}\x{7C69}\x{7C6A}\x{7C6B}\x{7C6C}\x{7C6D}' . '\x{7C6E}\x{7C6F}\x{7C70}\x{7C71}\x{7C72}\x{7C73}\x{7C74}\x{7C75}\x{7C77}' . '\x{7C78}\x{7C79}\x{7C7A}\x{7C7B}\x{7C7C}\x{7C7D}\x{7C7E}\x{7C7F}\x{7C80}' . '\x{7C81}\x{7C82}\x{7C84}\x{7C85}\x{7C86}\x{7C88}\x{7C89}\x{7C8A}\x{7C8B}' . '\x{7C8C}\x{7C8D}\x{7C8E}\x{7C8F}\x{7C90}\x{7C91}\x{7C92}\x{7C94}\x{7C95}' . '\x{7C96}\x{7C97}\x{7C98}\x{7C99}\x{7C9B}\x{7C9C}\x{7C9D}\x{7C9E}\x{7C9F}' . '\x{7CA0}\x{7CA1}\x{7CA2}\x{7CA3}\x{7CA4}\x{7CA5}\x{7CA6}\x{7CA7}\x{7CA8}' . '\x{7CA9}\x{7CAA}\x{7CAD}\x{7CAE}\x{7CAF}\x{7CB0}\x{7CB1}\x{7CB2}\x{7CB3}' . '\x{7CB4}\x{7CB5}\x{7CB6}\x{7CB7}\x{7CB8}\x{7CB9}\x{7CBA}\x{7CBB}\x{7CBC}' . '\x{7CBD}\x{7CBE}\x{7CBF}\x{7CC0}\x{7CC1}\x{7CC2}\x{7CC3}\x{7CC4}\x{7CC5}' . '\x{7CC6}\x{7CC7}\x{7CC8}\x{7CC9}\x{7CCA}\x{7CCB}\x{7CCC}\x{7CCD}\x{7CCE}' . '\x{7CCF}\x{7CD0}\x{7CD1}\x{7CD2}\x{7CD4}\x{7CD5}\x{7CD6}\x{7CD7}\x{7CD8}' . '\x{7CD9}\x{7CDC}\x{7CDD}\x{7CDE}\x{7CDF}\x{7CE0}\x{7CE2}\x{7CE4}\x{7CE7}' . '\x{7CE8}\x{7CE9}\x{7CEA}\x{7CEB}\x{7CEC}\x{7CED}\x{7CEE}\x{7CEF}\x{7CF0}' . '\x{7CF1}\x{7CF2}\x{7CF3}\x{7CF4}\x{7CF5}\x{7CF6}\x{7CF7}\x{7CF8}\x{7CF9}' . '\x{7CFA}\x{7CFB}\x{7CFD}\x{7CFE}\x{7D00}\x{7D01}\x{7D02}\x{7D03}\x{7D04}' . '\x{7D05}\x{7D06}\x{7D07}\x{7D08}\x{7D09}\x{7D0A}\x{7D0B}\x{7D0C}\x{7D0D}' . '\x{7D0E}\x{7D0F}\x{7D10}\x{7D11}\x{7D12}\x{7D13}\x{7D14}\x{7D15}\x{7D16}' . '\x{7D17}\x{7D18}\x{7D19}\x{7D1A}\x{7D1B}\x{7D1C}\x{7D1D}\x{7D1E}\x{7D1F}' . '\x{7D20}\x{7D21}\x{7D22}\x{7D24}\x{7D25}\x{7D26}\x{7D27}\x{7D28}\x{7D29}' . '\x{7D2B}\x{7D2C}\x{7D2E}\x{7D2F}\x{7D30}\x{7D31}\x{7D32}\x{7D33}\x{7D34}' . '\x{7D35}\x{7D36}\x{7D37}\x{7D38}\x{7D39}\x{7D3A}\x{7D3B}\x{7D3C}\x{7D3D}' . '\x{7D3E}\x{7D3F}\x{7D40}\x{7D41}\x{7D42}\x{7D43}\x{7D44}\x{7D45}\x{7D46}' . '\x{7D47}\x{7D49}\x{7D4A}\x{7D4B}\x{7D4C}\x{7D4E}\x{7D4F}\x{7D50}\x{7D51}' . '\x{7D52}\x{7D53}\x{7D54}\x{7D55}\x{7D56}\x{7D57}\x{7D58}\x{7D59}\x{7D5B}' . '\x{7D5C}\x{7D5D}\x{7D5E}\x{7D5F}\x{7D60}\x{7D61}\x{7D62}\x{7D63}\x{7D65}' . '\x{7D66}\x{7D67}\x{7D68}\x{7D69}\x{7D6A}\x{7D6B}\x{7D6C}\x{7D6D}\x{7D6E}' . '\x{7D6F}\x{7D70}\x{7D71}\x{7D72}\x{7D73}\x{7D74}\x{7D75}\x{7D76}\x{7D77}' . '\x{7D79}\x{7D7A}\x{7D7B}\x{7D7C}\x{7D7D}\x{7D7E}\x{7D7F}\x{7D80}\x{7D81}' . '\x{7D83}\x{7D84}\x{7D85}\x{7D86}\x{7D87}\x{7D88}\x{7D89}\x{7D8A}\x{7D8B}' . '\x{7D8C}\x{7D8D}\x{7D8E}\x{7D8F}\x{7D90}\x{7D91}\x{7D92}\x{7D93}\x{7D94}' . '\x{7D96}\x{7D97}\x{7D99}\x{7D9B}\x{7D9C}\x{7D9D}\x{7D9E}\x{7D9F}\x{7DA0}' . '\x{7DA1}\x{7DA2}\x{7DA3}\x{7DA5}\x{7DA6}\x{7DA7}\x{7DA9}\x{7DAA}\x{7DAB}' . '\x{7DAC}\x{7DAD}\x{7DAE}\x{7DAF}\x{7DB0}\x{7DB1}\x{7DB2}\x{7DB3}\x{7DB4}' . '\x{7DB5}\x{7DB6}\x{7DB7}\x{7DB8}\x{7DB9}\x{7DBA}\x{7DBB}\x{7DBC}\x{7DBD}' . '\x{7DBE}\x{7DBF}\x{7DC0}\x{7DC1}\x{7DC2}\x{7DC3}\x{7DC4}\x{7DC5}\x{7DC6}' . '\x{7DC7}\x{7DC8}\x{7DC9}\x{7DCA}\x{7DCB}\x{7DCC}\x{7DCE}\x{7DCF}\x{7DD0}' . '\x{7DD1}\x{7DD2}\x{7DD4}\x{7DD5}\x{7DD6}\x{7DD7}\x{7DD8}\x{7DD9}\x{7DDA}' . '\x{7DDB}\x{7DDD}\x{7DDE}\x{7DDF}\x{7DE0}\x{7DE1}\x{7DE2}\x{7DE3}\x{7DE6}' . '\x{7DE7}\x{7DE8}\x{7DE9}\x{7DEA}\x{7DEC}\x{7DED}\x{7DEE}\x{7DEF}\x{7DF0}' . '\x{7DF1}\x{7DF2}\x{7DF3}\x{7DF4}\x{7DF5}\x{7DF6}\x{7DF7}\x{7DF8}\x{7DF9}' . '\x{7DFA}\x{7DFB}\x{7DFC}\x{7E00}\x{7E01}\x{7E02}\x{7E03}\x{7E04}\x{7E05}' . '\x{7E06}\x{7E07}\x{7E08}\x{7E09}\x{7E0A}\x{7E0B}\x{7E0C}\x{7E0D}\x{7E0E}' . '\x{7E0F}\x{7E10}\x{7E11}\x{7E12}\x{7E13}\x{7E14}\x{7E15}\x{7E16}\x{7E17}' . '\x{7E19}\x{7E1A}\x{7E1B}\x{7E1C}\x{7E1D}\x{7E1E}\x{7E1F}\x{7E20}\x{7E21}' . '\x{7E22}\x{7E23}\x{7E24}\x{7E25}\x{7E26}\x{7E27}\x{7E28}\x{7E29}\x{7E2A}' . '\x{7E2B}\x{7E2C}\x{7E2D}\x{7E2E}\x{7E2F}\x{7E30}\x{7E31}\x{7E32}\x{7E33}' . '\x{7E34}\x{7E35}\x{7E36}\x{7E37}\x{7E38}\x{7E39}\x{7E3A}\x{7E3B}\x{7E3C}' . '\x{7E3D}\x{7E3E}\x{7E3F}\x{7E40}\x{7E41}\x{7E42}\x{7E43}\x{7E44}\x{7E45}' . '\x{7E46}\x{7E47}\x{7E48}\x{7E49}\x{7E4C}\x{7E4D}\x{7E4E}\x{7E4F}\x{7E50}' . '\x{7E51}\x{7E52}\x{7E53}\x{7E54}\x{7E55}\x{7E56}\x{7E57}\x{7E58}\x{7E59}' . '\x{7E5A}\x{7E5C}\x{7E5D}\x{7E5E}\x{7E5F}\x{7E60}\x{7E61}\x{7E62}\x{7E63}' . '\x{7E65}\x{7E66}\x{7E67}\x{7E68}\x{7E69}\x{7E6A}\x{7E6B}\x{7E6C}\x{7E6D}' . '\x{7E6E}\x{7E6F}\x{7E70}\x{7E71}\x{7E72}\x{7E73}\x{7E74}\x{7E75}\x{7E76}' . '\x{7E77}\x{7E78}\x{7E79}\x{7E7A}\x{7E7B}\x{7E7C}\x{7E7D}\x{7E7E}\x{7E7F}' . '\x{7E80}\x{7E81}\x{7E82}\x{7E83}\x{7E84}\x{7E85}\x{7E86}\x{7E87}\x{7E88}' . '\x{7E89}\x{7E8A}\x{7E8B}\x{7E8C}\x{7E8D}\x{7E8E}\x{7E8F}\x{7E90}\x{7E91}' . '\x{7E92}\x{7E93}\x{7E94}\x{7E95}\x{7E96}\x{7E97}\x{7E98}\x{7E99}\x{7E9A}' . '\x{7E9B}\x{7E9C}\x{7E9E}\x{7E9F}\x{7EA0}\x{7EA1}\x{7EA2}\x{7EA3}\x{7EA4}' . '\x{7EA5}\x{7EA6}\x{7EA7}\x{7EA8}\x{7EA9}\x{7EAA}\x{7EAB}\x{7EAC}\x{7EAD}' . '\x{7EAE}\x{7EAF}\x{7EB0}\x{7EB1}\x{7EB2}\x{7EB3}\x{7EB4}\x{7EB5}\x{7EB6}' . '\x{7EB7}\x{7EB8}\x{7EB9}\x{7EBA}\x{7EBB}\x{7EBC}\x{7EBD}\x{7EBE}\x{7EBF}' . '\x{7EC0}\x{7EC1}\x{7EC2}\x{7EC3}\x{7EC4}\x{7EC5}\x{7EC6}\x{7EC7}\x{7EC8}' . '\x{7EC9}\x{7ECA}\x{7ECB}\x{7ECC}\x{7ECD}\x{7ECE}\x{7ECF}\x{7ED0}\x{7ED1}' . '\x{7ED2}\x{7ED3}\x{7ED4}\x{7ED5}\x{7ED6}\x{7ED7}\x{7ED8}\x{7ED9}\x{7EDA}' . '\x{7EDB}\x{7EDC}\x{7EDD}\x{7EDE}\x{7EDF}\x{7EE0}\x{7EE1}\x{7EE2}\x{7EE3}' . '\x{7EE4}\x{7EE5}\x{7EE6}\x{7EE7}\x{7EE8}\x{7EE9}\x{7EEA}\x{7EEB}\x{7EEC}' . '\x{7EED}\x{7EEE}\x{7EEF}\x{7EF0}\x{7EF1}\x{7EF2}\x{7EF3}\x{7EF4}\x{7EF5}' . '\x{7EF6}\x{7EF7}\x{7EF8}\x{7EF9}\x{7EFA}\x{7EFB}\x{7EFC}\x{7EFD}\x{7EFE}' . '\x{7EFF}\x{7F00}\x{7F01}\x{7F02}\x{7F03}\x{7F04}\x{7F05}\x{7F06}\x{7F07}' . '\x{7F08}\x{7F09}\x{7F0A}\x{7F0B}\x{7F0C}\x{7F0D}\x{7F0E}\x{7F0F}\x{7F10}' . '\x{7F11}\x{7F12}\x{7F13}\x{7F14}\x{7F15}\x{7F16}\x{7F17}\x{7F18}\x{7F19}' . '\x{7F1A}\x{7F1B}\x{7F1C}\x{7F1D}\x{7F1E}\x{7F1F}\x{7F20}\x{7F21}\x{7F22}' . '\x{7F23}\x{7F24}\x{7F25}\x{7F26}\x{7F27}\x{7F28}\x{7F29}\x{7F2A}\x{7F2B}' . '\x{7F2C}\x{7F2D}\x{7F2E}\x{7F2F}\x{7F30}\x{7F31}\x{7F32}\x{7F33}\x{7F34}' . '\x{7F35}\x{7F36}\x{7F37}\x{7F38}\x{7F39}\x{7F3A}\x{7F3D}\x{7F3E}\x{7F3F}' . '\x{7F40}\x{7F42}\x{7F43}\x{7F44}\x{7F45}\x{7F47}\x{7F48}\x{7F49}\x{7F4A}' . '\x{7F4B}\x{7F4C}\x{7F4D}\x{7F4E}\x{7F4F}\x{7F50}\x{7F51}\x{7F52}\x{7F53}' . '\x{7F54}\x{7F55}\x{7F56}\x{7F57}\x{7F58}\x{7F5A}\x{7F5B}\x{7F5C}\x{7F5D}' . '\x{7F5E}\x{7F5F}\x{7F60}\x{7F61}\x{7F62}\x{7F63}\x{7F64}\x{7F65}\x{7F66}' . '\x{7F67}\x{7F68}\x{7F69}\x{7F6A}\x{7F6B}\x{7F6C}\x{7F6D}\x{7F6E}\x{7F6F}' . '\x{7F70}\x{7F71}\x{7F72}\x{7F73}\x{7F74}\x{7F75}\x{7F76}\x{7F77}\x{7F78}' . '\x{7F79}\x{7F7A}\x{7F7B}\x{7F7C}\x{7F7D}\x{7F7E}\x{7F7F}\x{7F80}\x{7F81}' . '\x{7F82}\x{7F83}\x{7F85}\x{7F86}\x{7F87}\x{7F88}\x{7F89}\x{7F8A}\x{7F8B}' . '\x{7F8C}\x{7F8D}\x{7F8E}\x{7F8F}\x{7F91}\x{7F92}\x{7F93}\x{7F94}\x{7F95}' . '\x{7F96}\x{7F98}\x{7F9A}\x{7F9B}\x{7F9C}\x{7F9D}\x{7F9E}\x{7F9F}\x{7FA0}' . '\x{7FA1}\x{7FA2}\x{7FA3}\x{7FA4}\x{7FA5}\x{7FA6}\x{7FA7}\x{7FA8}\x{7FA9}' . '\x{7FAA}\x{7FAB}\x{7FAC}\x{7FAD}\x{7FAE}\x{7FAF}\x{7FB0}\x{7FB1}\x{7FB2}' . '\x{7FB3}\x{7FB5}\x{7FB6}\x{7FB7}\x{7FB8}\x{7FB9}\x{7FBA}\x{7FBB}\x{7FBC}' . '\x{7FBD}\x{7FBE}\x{7FBF}\x{7FC0}\x{7FC1}\x{7FC2}\x{7FC3}\x{7FC4}\x{7FC5}' . '\x{7FC6}\x{7FC7}\x{7FC8}\x{7FC9}\x{7FCA}\x{7FCB}\x{7FCC}\x{7FCD}\x{7FCE}' . '\x{7FCF}\x{7FD0}\x{7FD1}\x{7FD2}\x{7FD3}\x{7FD4}\x{7FD5}\x{7FD7}\x{7FD8}' . '\x{7FD9}\x{7FDA}\x{7FDB}\x{7FDC}\x{7FDE}\x{7FDF}\x{7FE0}\x{7FE1}\x{7FE2}' . '\x{7FE3}\x{7FE5}\x{7FE6}\x{7FE7}\x{7FE8}\x{7FE9}\x{7FEA}\x{7FEB}\x{7FEC}' . '\x{7FED}\x{7FEE}\x{7FEF}\x{7FF0}\x{7FF1}\x{7FF2}\x{7FF3}\x{7FF4}\x{7FF5}' . '\x{7FF6}\x{7FF7}\x{7FF8}\x{7FF9}\x{7FFA}\x{7FFB}\x{7FFC}\x{7FFD}\x{7FFE}' . '\x{7FFF}\x{8000}\x{8001}\x{8002}\x{8003}\x{8004}\x{8005}\x{8006}\x{8007}' . '\x{8008}\x{8009}\x{800B}\x{800C}\x{800D}\x{800E}\x{800F}\x{8010}\x{8011}' . '\x{8012}\x{8013}\x{8014}\x{8015}\x{8016}\x{8017}\x{8018}\x{8019}\x{801A}' . '\x{801B}\x{801C}\x{801D}\x{801E}\x{801F}\x{8020}\x{8021}\x{8022}\x{8023}' . '\x{8024}\x{8025}\x{8026}\x{8027}\x{8028}\x{8029}\x{802A}\x{802B}\x{802C}' . '\x{802D}\x{802E}\x{8030}\x{8031}\x{8032}\x{8033}\x{8034}\x{8035}\x{8036}' . '\x{8037}\x{8038}\x{8039}\x{803A}\x{803B}\x{803D}\x{803E}\x{803F}\x{8041}' . '\x{8042}\x{8043}\x{8044}\x{8045}\x{8046}\x{8047}\x{8048}\x{8049}\x{804A}' . '\x{804B}\x{804C}\x{804D}\x{804E}\x{804F}\x{8050}\x{8051}\x{8052}\x{8053}' . '\x{8054}\x{8055}\x{8056}\x{8057}\x{8058}\x{8059}\x{805A}\x{805B}\x{805C}' . '\x{805D}\x{805E}\x{805F}\x{8060}\x{8061}\x{8062}\x{8063}\x{8064}\x{8065}' . '\x{8067}\x{8068}\x{8069}\x{806A}\x{806B}\x{806C}\x{806D}\x{806E}\x{806F}' . '\x{8070}\x{8071}\x{8072}\x{8073}\x{8074}\x{8075}\x{8076}\x{8077}\x{8078}' . '\x{8079}\x{807A}\x{807B}\x{807C}\x{807D}\x{807E}\x{807F}\x{8080}\x{8081}' . '\x{8082}\x{8083}\x{8084}\x{8085}\x{8086}\x{8087}\x{8089}\x{808A}\x{808B}' . '\x{808C}\x{808D}\x{808F}\x{8090}\x{8091}\x{8092}\x{8093}\x{8095}\x{8096}' . '\x{8097}\x{8098}\x{8099}\x{809A}\x{809B}\x{809C}\x{809D}\x{809E}\x{809F}' . '\x{80A0}\x{80A1}\x{80A2}\x{80A3}\x{80A4}\x{80A5}\x{80A9}\x{80AA}\x{80AB}' . '\x{80AD}\x{80AE}\x{80AF}\x{80B0}\x{80B1}\x{80B2}\x{80B4}\x{80B5}\x{80B6}' . '\x{80B7}\x{80B8}\x{80BA}\x{80BB}\x{80BC}\x{80BD}\x{80BE}\x{80BF}\x{80C0}' . '\x{80C1}\x{80C2}\x{80C3}\x{80C4}\x{80C5}\x{80C6}\x{80C7}\x{80C8}\x{80C9}' . '\x{80CA}\x{80CB}\x{80CC}\x{80CD}\x{80CE}\x{80CF}\x{80D0}\x{80D1}\x{80D2}' . '\x{80D3}\x{80D4}\x{80D5}\x{80D6}\x{80D7}\x{80D8}\x{80D9}\x{80DA}\x{80DB}' . '\x{80DC}\x{80DD}\x{80DE}\x{80E0}\x{80E1}\x{80E2}\x{80E3}\x{80E4}\x{80E5}' . '\x{80E6}\x{80E7}\x{80E8}\x{80E9}\x{80EA}\x{80EB}\x{80EC}\x{80ED}\x{80EE}' . '\x{80EF}\x{80F0}\x{80F1}\x{80F2}\x{80F3}\x{80F4}\x{80F5}\x{80F6}\x{80F7}' . '\x{80F8}\x{80F9}\x{80FA}\x{80FB}\x{80FC}\x{80FD}\x{80FE}\x{80FF}\x{8100}' . '\x{8101}\x{8102}\x{8105}\x{8106}\x{8107}\x{8108}\x{8109}\x{810A}\x{810B}' . '\x{810C}\x{810D}\x{810E}\x{810F}\x{8110}\x{8111}\x{8112}\x{8113}\x{8114}' . '\x{8115}\x{8116}\x{8118}\x{8119}\x{811A}\x{811B}\x{811C}\x{811D}\x{811E}' . '\x{811F}\x{8120}\x{8121}\x{8122}\x{8123}\x{8124}\x{8125}\x{8126}\x{8127}' . '\x{8128}\x{8129}\x{812A}\x{812B}\x{812C}\x{812D}\x{812E}\x{812F}\x{8130}' . '\x{8131}\x{8132}\x{8136}\x{8137}\x{8138}\x{8139}\x{813A}\x{813B}\x{813C}' . '\x{813D}\x{813E}\x{813F}\x{8140}\x{8141}\x{8142}\x{8143}\x{8144}\x{8145}' . '\x{8146}\x{8147}\x{8148}\x{8149}\x{814A}\x{814B}\x{814C}\x{814D}\x{814E}' . '\x{814F}\x{8150}\x{8151}\x{8152}\x{8153}\x{8154}\x{8155}\x{8156}\x{8157}' . '\x{8158}\x{8159}\x{815A}\x{815B}\x{815C}\x{815D}\x{815E}\x{8160}\x{8161}' . '\x{8162}\x{8163}\x{8164}\x{8165}\x{8166}\x{8167}\x{8168}\x{8169}\x{816A}' . '\x{816B}\x{816C}\x{816D}\x{816E}\x{816F}\x{8170}\x{8171}\x{8172}\x{8173}' . '\x{8174}\x{8175}\x{8176}\x{8177}\x{8178}\x{8179}\x{817A}\x{817B}\x{817C}' . '\x{817D}\x{817E}\x{817F}\x{8180}\x{8181}\x{8182}\x{8183}\x{8185}\x{8186}' . '\x{8187}\x{8188}\x{8189}\x{818A}\x{818B}\x{818C}\x{818D}\x{818E}\x{818F}' . '\x{8191}\x{8192}\x{8193}\x{8194}\x{8195}\x{8197}\x{8198}\x{8199}\x{819A}' . '\x{819B}\x{819C}\x{819D}\x{819E}\x{819F}\x{81A0}\x{81A1}\x{81A2}\x{81A3}' . '\x{81A4}\x{81A5}\x{81A6}\x{81A7}\x{81A8}\x{81A9}\x{81AA}\x{81AB}\x{81AC}' . '\x{81AD}\x{81AE}\x{81AF}\x{81B0}\x{81B1}\x{81B2}\x{81B3}\x{81B4}\x{81B5}' . '\x{81B6}\x{81B7}\x{81B8}\x{81B9}\x{81BA}\x{81BB}\x{81BC}\x{81BD}\x{81BE}' . '\x{81BF}\x{81C0}\x{81C1}\x{81C2}\x{81C3}\x{81C4}\x{81C5}\x{81C6}\x{81C7}' . '\x{81C8}\x{81C9}\x{81CA}\x{81CC}\x{81CD}\x{81CE}\x{81CF}\x{81D0}\x{81D1}' . '\x{81D2}\x{81D4}\x{81D5}\x{81D6}\x{81D7}\x{81D8}\x{81D9}\x{81DA}\x{81DB}' . '\x{81DC}\x{81DD}\x{81DE}\x{81DF}\x{81E0}\x{81E1}\x{81E2}\x{81E3}\x{81E5}' . '\x{81E6}\x{81E7}\x{81E8}\x{81E9}\x{81EA}\x{81EB}\x{81EC}\x{81ED}\x{81EE}' . '\x{81F1}\x{81F2}\x{81F3}\x{81F4}\x{81F5}\x{81F6}\x{81F7}\x{81F8}\x{81F9}' . '\x{81FA}\x{81FB}\x{81FC}\x{81FD}\x{81FE}\x{81FF}\x{8200}\x{8201}\x{8202}' . '\x{8203}\x{8204}\x{8205}\x{8206}\x{8207}\x{8208}\x{8209}\x{820A}\x{820B}' . '\x{820C}\x{820D}\x{820E}\x{820F}\x{8210}\x{8211}\x{8212}\x{8214}\x{8215}' . '\x{8216}\x{8218}\x{8219}\x{821A}\x{821B}\x{821C}\x{821D}\x{821E}\x{821F}' . '\x{8220}\x{8221}\x{8222}\x{8223}\x{8225}\x{8226}\x{8227}\x{8228}\x{8229}' . '\x{822A}\x{822B}\x{822C}\x{822D}\x{822F}\x{8230}\x{8231}\x{8232}\x{8233}' . '\x{8234}\x{8235}\x{8236}\x{8237}\x{8238}\x{8239}\x{823A}\x{823B}\x{823C}' . '\x{823D}\x{823E}\x{823F}\x{8240}\x{8242}\x{8243}\x{8244}\x{8245}\x{8246}' . '\x{8247}\x{8248}\x{8249}\x{824A}\x{824B}\x{824C}\x{824D}\x{824E}\x{824F}' . '\x{8250}\x{8251}\x{8252}\x{8253}\x{8254}\x{8255}\x{8256}\x{8257}\x{8258}' . '\x{8259}\x{825A}\x{825B}\x{825C}\x{825D}\x{825E}\x{825F}\x{8260}\x{8261}' . '\x{8263}\x{8264}\x{8266}\x{8267}\x{8268}\x{8269}\x{826A}\x{826B}\x{826C}' . '\x{826D}\x{826E}\x{826F}\x{8270}\x{8271}\x{8272}\x{8273}\x{8274}\x{8275}' . '\x{8276}\x{8277}\x{8278}\x{8279}\x{827A}\x{827B}\x{827C}\x{827D}\x{827E}' . '\x{827F}\x{8280}\x{8281}\x{8282}\x{8283}\x{8284}\x{8285}\x{8286}\x{8287}' . '\x{8288}\x{8289}\x{828A}\x{828B}\x{828D}\x{828E}\x{828F}\x{8290}\x{8291}' . '\x{8292}\x{8293}\x{8294}\x{8295}\x{8296}\x{8297}\x{8298}\x{8299}\x{829A}' . '\x{829B}\x{829C}\x{829D}\x{829E}\x{829F}\x{82A0}\x{82A1}\x{82A2}\x{82A3}' . '\x{82A4}\x{82A5}\x{82A6}\x{82A7}\x{82A8}\x{82A9}\x{82AA}\x{82AB}\x{82AC}' . '\x{82AD}\x{82AE}\x{82AF}\x{82B0}\x{82B1}\x{82B3}\x{82B4}\x{82B5}\x{82B6}' . '\x{82B7}\x{82B8}\x{82B9}\x{82BA}\x{82BB}\x{82BC}\x{82BD}\x{82BE}\x{82BF}' . '\x{82C0}\x{82C1}\x{82C2}\x{82C3}\x{82C4}\x{82C5}\x{82C6}\x{82C7}\x{82C8}' . '\x{82C9}\x{82CA}\x{82CB}\x{82CC}\x{82CD}\x{82CE}\x{82CF}\x{82D0}\x{82D1}' . '\x{82D2}\x{82D3}\x{82D4}\x{82D5}\x{82D6}\x{82D7}\x{82D8}\x{82D9}\x{82DA}' . '\x{82DB}\x{82DC}\x{82DD}\x{82DE}\x{82DF}\x{82E0}\x{82E1}\x{82E3}\x{82E4}' . '\x{82E5}\x{82E6}\x{82E7}\x{82E8}\x{82E9}\x{82EA}\x{82EB}\x{82EC}\x{82ED}' . '\x{82EE}\x{82EF}\x{82F0}\x{82F1}\x{82F2}\x{82F3}\x{82F4}\x{82F5}\x{82F6}' . '\x{82F7}\x{82F8}\x{82F9}\x{82FA}\x{82FB}\x{82FD}\x{82FE}\x{82FF}\x{8300}' . '\x{8301}\x{8302}\x{8303}\x{8304}\x{8305}\x{8306}\x{8307}\x{8308}\x{8309}' . '\x{830B}\x{830C}\x{830D}\x{830E}\x{830F}\x{8311}\x{8312}\x{8313}\x{8314}' . '\x{8315}\x{8316}\x{8317}\x{8318}\x{8319}\x{831A}\x{831B}\x{831C}\x{831D}' . '\x{831E}\x{831F}\x{8320}\x{8321}\x{8322}\x{8323}\x{8324}\x{8325}\x{8326}' . '\x{8327}\x{8328}\x{8329}\x{832A}\x{832B}\x{832C}\x{832D}\x{832E}\x{832F}' . '\x{8331}\x{8332}\x{8333}\x{8334}\x{8335}\x{8336}\x{8337}\x{8338}\x{8339}' . '\x{833A}\x{833B}\x{833C}\x{833D}\x{833E}\x{833F}\x{8340}\x{8341}\x{8342}' . '\x{8343}\x{8344}\x{8345}\x{8346}\x{8347}\x{8348}\x{8349}\x{834A}\x{834B}' . '\x{834C}\x{834D}\x{834E}\x{834F}\x{8350}\x{8351}\x{8352}\x{8353}\x{8354}' . '\x{8356}\x{8357}\x{8358}\x{8359}\x{835A}\x{835B}\x{835C}\x{835D}\x{835E}' . '\x{835F}\x{8360}\x{8361}\x{8362}\x{8363}\x{8364}\x{8365}\x{8366}\x{8367}' . '\x{8368}\x{8369}\x{836A}\x{836B}\x{836C}\x{836D}\x{836E}\x{836F}\x{8370}' . '\x{8371}\x{8372}\x{8373}\x{8374}\x{8375}\x{8376}\x{8377}\x{8378}\x{8379}' . '\x{837A}\x{837B}\x{837C}\x{837D}\x{837E}\x{837F}\x{8380}\x{8381}\x{8382}' . '\x{8383}\x{8384}\x{8385}\x{8386}\x{8387}\x{8388}\x{8389}\x{838A}\x{838B}' . '\x{838C}\x{838D}\x{838E}\x{838F}\x{8390}\x{8391}\x{8392}\x{8393}\x{8394}' . '\x{8395}\x{8396}\x{8397}\x{8398}\x{8399}\x{839A}\x{839B}\x{839C}\x{839D}' . '\x{839E}\x{83A0}\x{83A1}\x{83A2}\x{83A3}\x{83A4}\x{83A5}\x{83A6}\x{83A7}' . '\x{83A8}\x{83A9}\x{83AA}\x{83AB}\x{83AC}\x{83AD}\x{83AE}\x{83AF}\x{83B0}' . '\x{83B1}\x{83B2}\x{83B3}\x{83B4}\x{83B6}\x{83B7}\x{83B8}\x{83B9}\x{83BA}' . '\x{83BB}\x{83BC}\x{83BD}\x{83BF}\x{83C0}\x{83C1}\x{83C2}\x{83C3}\x{83C4}' . '\x{83C5}\x{83C6}\x{83C7}\x{83C8}\x{83C9}\x{83CA}\x{83CB}\x{83CC}\x{83CD}' . '\x{83CE}\x{83CF}\x{83D0}\x{83D1}\x{83D2}\x{83D3}\x{83D4}\x{83D5}\x{83D6}' . '\x{83D7}\x{83D8}\x{83D9}\x{83DA}\x{83DB}\x{83DC}\x{83DD}\x{83DE}\x{83DF}' . '\x{83E0}\x{83E1}\x{83E2}\x{83E3}\x{83E4}\x{83E5}\x{83E7}\x{83E8}\x{83E9}' . '\x{83EA}\x{83EB}\x{83EC}\x{83EE}\x{83EF}\x{83F0}\x{83F1}\x{83F2}\x{83F3}' . '\x{83F4}\x{83F5}\x{83F6}\x{83F7}\x{83F8}\x{83F9}\x{83FA}\x{83FB}\x{83FC}' . '\x{83FD}\x{83FE}\x{83FF}\x{8400}\x{8401}\x{8402}\x{8403}\x{8404}\x{8405}' . '\x{8406}\x{8407}\x{8408}\x{8409}\x{840A}\x{840B}\x{840C}\x{840D}\x{840E}' . '\x{840F}\x{8410}\x{8411}\x{8412}\x{8413}\x{8415}\x{8418}\x{8419}\x{841A}' . '\x{841B}\x{841C}\x{841D}\x{841E}\x{8421}\x{8422}\x{8423}\x{8424}\x{8425}' . '\x{8426}\x{8427}\x{8428}\x{8429}\x{842A}\x{842B}\x{842C}\x{842D}\x{842E}' . '\x{842F}\x{8430}\x{8431}\x{8432}\x{8433}\x{8434}\x{8435}\x{8436}\x{8437}' . '\x{8438}\x{8439}\x{843A}\x{843B}\x{843C}\x{843D}\x{843E}\x{843F}\x{8440}' . '\x{8441}\x{8442}\x{8443}\x{8444}\x{8445}\x{8446}\x{8447}\x{8448}\x{8449}' . '\x{844A}\x{844B}\x{844C}\x{844D}\x{844E}\x{844F}\x{8450}\x{8451}\x{8452}' . '\x{8453}\x{8454}\x{8455}\x{8456}\x{8457}\x{8459}\x{845A}\x{845B}\x{845C}' . '\x{845D}\x{845E}\x{845F}\x{8460}\x{8461}\x{8462}\x{8463}\x{8464}\x{8465}' . '\x{8466}\x{8467}\x{8468}\x{8469}\x{846A}\x{846B}\x{846C}\x{846D}\x{846E}' . '\x{846F}\x{8470}\x{8471}\x{8472}\x{8473}\x{8474}\x{8475}\x{8476}\x{8477}' . '\x{8478}\x{8479}\x{847A}\x{847B}\x{847C}\x{847D}\x{847E}\x{847F}\x{8480}' . '\x{8481}\x{8482}\x{8484}\x{8485}\x{8486}\x{8487}\x{8488}\x{8489}\x{848A}' . '\x{848B}\x{848C}\x{848D}\x{848E}\x{848F}\x{8490}\x{8491}\x{8492}\x{8493}' . '\x{8494}\x{8496}\x{8497}\x{8498}\x{8499}\x{849A}\x{849B}\x{849C}\x{849D}' . '\x{849E}\x{849F}\x{84A0}\x{84A1}\x{84A2}\x{84A3}\x{84A4}\x{84A5}\x{84A6}' . '\x{84A7}\x{84A8}\x{84A9}\x{84AA}\x{84AB}\x{84AC}\x{84AE}\x{84AF}\x{84B0}' . '\x{84B1}\x{84B2}\x{84B3}\x{84B4}\x{84B5}\x{84B6}\x{84B8}\x{84B9}\x{84BA}' . '\x{84BB}\x{84BC}\x{84BD}\x{84BE}\x{84BF}\x{84C0}\x{84C1}\x{84C2}\x{84C4}' . '\x{84C5}\x{84C6}\x{84C7}\x{84C8}\x{84C9}\x{84CA}\x{84CB}\x{84CC}\x{84CD}' . '\x{84CE}\x{84CF}\x{84D0}\x{84D1}\x{84D2}\x{84D3}\x{84D4}\x{84D5}\x{84D6}' . '\x{84D7}\x{84D8}\x{84D9}\x{84DB}\x{84DC}\x{84DD}\x{84DE}\x{84DF}\x{84E0}' . '\x{84E1}\x{84E2}\x{84E3}\x{84E4}\x{84E5}\x{84E6}\x{84E7}\x{84E8}\x{84E9}' . '\x{84EA}\x{84EB}\x{84EC}\x{84EE}\x{84EF}\x{84F0}\x{84F1}\x{84F2}\x{84F3}' . '\x{84F4}\x{84F5}\x{84F6}\x{84F7}\x{84F8}\x{84F9}\x{84FA}\x{84FB}\x{84FC}' . '\x{84FD}\x{84FE}\x{84FF}\x{8500}\x{8501}\x{8502}\x{8503}\x{8504}\x{8506}' . '\x{8507}\x{8508}\x{8509}\x{850A}\x{850B}\x{850C}\x{850D}\x{850E}\x{850F}' . '\x{8511}\x{8512}\x{8513}\x{8514}\x{8515}\x{8516}\x{8517}\x{8518}\x{8519}' . '\x{851A}\x{851B}\x{851C}\x{851D}\x{851E}\x{851F}\x{8520}\x{8521}\x{8522}' . '\x{8523}\x{8524}\x{8525}\x{8526}\x{8527}\x{8528}\x{8529}\x{852A}\x{852B}' . '\x{852C}\x{852D}\x{852E}\x{852F}\x{8530}\x{8531}\x{8534}\x{8535}\x{8536}' . '\x{8537}\x{8538}\x{8539}\x{853A}\x{853B}\x{853C}\x{853D}\x{853E}\x{853F}' . '\x{8540}\x{8541}\x{8542}\x{8543}\x{8544}\x{8545}\x{8546}\x{8547}\x{8548}' . '\x{8549}\x{854A}\x{854B}\x{854D}\x{854E}\x{854F}\x{8551}\x{8552}\x{8553}' . '\x{8554}\x{8555}\x{8556}\x{8557}\x{8558}\x{8559}\x{855A}\x{855B}\x{855C}' . '\x{855D}\x{855E}\x{855F}\x{8560}\x{8561}\x{8562}\x{8563}\x{8564}\x{8565}' . '\x{8566}\x{8567}\x{8568}\x{8569}\x{856A}\x{856B}\x{856C}\x{856D}\x{856E}' . '\x{856F}\x{8570}\x{8571}\x{8572}\x{8573}\x{8574}\x{8575}\x{8576}\x{8577}' . '\x{8578}\x{8579}\x{857A}\x{857B}\x{857C}\x{857D}\x{857E}\x{8580}\x{8581}' . '\x{8582}\x{8583}\x{8584}\x{8585}\x{8586}\x{8587}\x{8588}\x{8589}\x{858A}' . '\x{858B}\x{858C}\x{858D}\x{858E}\x{858F}\x{8590}\x{8591}\x{8592}\x{8594}' . '\x{8595}\x{8596}\x{8598}\x{8599}\x{859A}\x{859B}\x{859C}\x{859D}\x{859E}' . '\x{859F}\x{85A0}\x{85A1}\x{85A2}\x{85A3}\x{85A4}\x{85A5}\x{85A6}\x{85A7}' . '\x{85A8}\x{85A9}\x{85AA}\x{85AB}\x{85AC}\x{85AD}\x{85AE}\x{85AF}\x{85B0}' . '\x{85B1}\x{85B3}\x{85B4}\x{85B5}\x{85B6}\x{85B7}\x{85B8}\x{85B9}\x{85BA}' . '\x{85BC}\x{85BD}\x{85BE}\x{85BF}\x{85C0}\x{85C1}\x{85C2}\x{85C3}\x{85C4}' . '\x{85C5}\x{85C6}\x{85C7}\x{85C8}\x{85C9}\x{85CA}\x{85CB}\x{85CD}\x{85CE}' . '\x{85CF}\x{85D0}\x{85D1}\x{85D2}\x{85D3}\x{85D4}\x{85D5}\x{85D6}\x{85D7}' . '\x{85D8}\x{85D9}\x{85DA}\x{85DB}\x{85DC}\x{85DD}\x{85DE}\x{85DF}\x{85E0}' . '\x{85E1}\x{85E2}\x{85E3}\x{85E4}\x{85E5}\x{85E6}\x{85E7}\x{85E8}\x{85E9}' . '\x{85EA}\x{85EB}\x{85EC}\x{85ED}\x{85EF}\x{85F0}\x{85F1}\x{85F2}\x{85F4}' . '\x{85F5}\x{85F6}\x{85F7}\x{85F8}\x{85F9}\x{85FA}\x{85FB}\x{85FD}\x{85FE}' . '\x{85FF}\x{8600}\x{8601}\x{8602}\x{8604}\x{8605}\x{8606}\x{8607}\x{8608}' . '\x{8609}\x{860A}\x{860B}\x{860C}\x{860F}\x{8611}\x{8612}\x{8613}\x{8614}' . '\x{8616}\x{8617}\x{8618}\x{8619}\x{861A}\x{861B}\x{861C}\x{861E}\x{861F}' . '\x{8620}\x{8621}\x{8622}\x{8623}\x{8624}\x{8625}\x{8626}\x{8627}\x{8628}' . '\x{8629}\x{862A}\x{862B}\x{862C}\x{862D}\x{862E}\x{862F}\x{8630}\x{8631}' . '\x{8632}\x{8633}\x{8634}\x{8635}\x{8636}\x{8638}\x{8639}\x{863A}\x{863B}' . '\x{863C}\x{863D}\x{863E}\x{863F}\x{8640}\x{8641}\x{8642}\x{8643}\x{8644}' . '\x{8645}\x{8646}\x{8647}\x{8648}\x{8649}\x{864A}\x{864B}\x{864C}\x{864D}' . '\x{864E}\x{864F}\x{8650}\x{8651}\x{8652}\x{8653}\x{8654}\x{8655}\x{8656}' . '\x{8658}\x{8659}\x{865A}\x{865B}\x{865C}\x{865D}\x{865E}\x{865F}\x{8660}' . '\x{8661}\x{8662}\x{8663}\x{8664}\x{8665}\x{8666}\x{8667}\x{8668}\x{8669}' . '\x{866A}\x{866B}\x{866C}\x{866D}\x{866E}\x{866F}\x{8670}\x{8671}\x{8672}' . '\x{8673}\x{8674}\x{8676}\x{8677}\x{8678}\x{8679}\x{867A}\x{867B}\x{867C}' . '\x{867D}\x{867E}\x{867F}\x{8680}\x{8681}\x{8682}\x{8683}\x{8684}\x{8685}' . '\x{8686}\x{8687}\x{8688}\x{868A}\x{868B}\x{868C}\x{868D}\x{868E}\x{868F}' . '\x{8690}\x{8691}\x{8693}\x{8694}\x{8695}\x{8696}\x{8697}\x{8698}\x{8699}' . '\x{869A}\x{869B}\x{869C}\x{869D}\x{869E}\x{869F}\x{86A1}\x{86A2}\x{86A3}' . '\x{86A4}\x{86A5}\x{86A7}\x{86A8}\x{86A9}\x{86AA}\x{86AB}\x{86AC}\x{86AD}' . '\x{86AE}\x{86AF}\x{86B0}\x{86B1}\x{86B2}\x{86B3}\x{86B4}\x{86B5}\x{86B6}' . '\x{86B7}\x{86B8}\x{86B9}\x{86BA}\x{86BB}\x{86BC}\x{86BD}\x{86BE}\x{86BF}' . '\x{86C0}\x{86C1}\x{86C2}\x{86C3}\x{86C4}\x{86C5}\x{86C6}\x{86C7}\x{86C8}' . '\x{86C9}\x{86CA}\x{86CB}\x{86CC}\x{86CE}\x{86CF}\x{86D0}\x{86D1}\x{86D2}' . '\x{86D3}\x{86D4}\x{86D6}\x{86D7}\x{86D8}\x{86D9}\x{86DA}\x{86DB}\x{86DC}' . '\x{86DD}\x{86DE}\x{86DF}\x{86E1}\x{86E2}\x{86E3}\x{86E4}\x{86E5}\x{86E6}' . '\x{86E8}\x{86E9}\x{86EA}\x{86EB}\x{86EC}\x{86ED}\x{86EE}\x{86EF}\x{86F0}' . '\x{86F1}\x{86F2}\x{86F3}\x{86F4}\x{86F5}\x{86F6}\x{86F7}\x{86F8}\x{86F9}' . '\x{86FA}\x{86FB}\x{86FC}\x{86FE}\x{86FF}\x{8700}\x{8701}\x{8702}\x{8703}' . '\x{8704}\x{8705}\x{8706}\x{8707}\x{8708}\x{8709}\x{870A}\x{870B}\x{870C}' . '\x{870D}\x{870E}\x{870F}\x{8710}\x{8711}\x{8712}\x{8713}\x{8714}\x{8715}' . '\x{8716}\x{8717}\x{8718}\x{8719}\x{871A}\x{871B}\x{871C}\x{871E}\x{871F}' . '\x{8720}\x{8721}\x{8722}\x{8723}\x{8724}\x{8725}\x{8726}\x{8727}\x{8728}' . '\x{8729}\x{872A}\x{872B}\x{872C}\x{872D}\x{872E}\x{8730}\x{8731}\x{8732}' . '\x{8733}\x{8734}\x{8735}\x{8736}\x{8737}\x{8738}\x{8739}\x{873A}\x{873B}' . '\x{873C}\x{873E}\x{873F}\x{8740}\x{8741}\x{8742}\x{8743}\x{8744}\x{8746}' . '\x{8747}\x{8748}\x{8749}\x{874A}\x{874C}\x{874D}\x{874E}\x{874F}\x{8750}' . '\x{8751}\x{8752}\x{8753}\x{8754}\x{8755}\x{8756}\x{8757}\x{8758}\x{8759}' . '\x{875A}\x{875B}\x{875C}\x{875D}\x{875E}\x{875F}\x{8760}\x{8761}\x{8762}' . '\x{8763}\x{8764}\x{8765}\x{8766}\x{8767}\x{8768}\x{8769}\x{876A}\x{876B}' . '\x{876C}\x{876D}\x{876E}\x{876F}\x{8770}\x{8772}\x{8773}\x{8774}\x{8775}' . '\x{8776}\x{8777}\x{8778}\x{8779}\x{877A}\x{877B}\x{877C}\x{877D}\x{877E}' . '\x{8780}\x{8781}\x{8782}\x{8783}\x{8784}\x{8785}\x{8786}\x{8787}\x{8788}' . '\x{8789}\x{878A}\x{878B}\x{878C}\x{878D}\x{878F}\x{8790}\x{8791}\x{8792}' . '\x{8793}\x{8794}\x{8795}\x{8796}\x{8797}\x{8798}\x{879A}\x{879B}\x{879C}' . '\x{879D}\x{879E}\x{879F}\x{87A0}\x{87A1}\x{87A2}\x{87A3}\x{87A4}\x{87A5}' . '\x{87A6}\x{87A7}\x{87A8}\x{87A9}\x{87AA}\x{87AB}\x{87AC}\x{87AD}\x{87AE}' . '\x{87AF}\x{87B0}\x{87B1}\x{87B2}\x{87B3}\x{87B4}\x{87B5}\x{87B6}\x{87B7}' . '\x{87B8}\x{87B9}\x{87BA}\x{87BB}\x{87BC}\x{87BD}\x{87BE}\x{87BF}\x{87C0}' . '\x{87C1}\x{87C2}\x{87C3}\x{87C4}\x{87C5}\x{87C6}\x{87C7}\x{87C8}\x{87C9}' . '\x{87CA}\x{87CB}\x{87CC}\x{87CD}\x{87CE}\x{87CF}\x{87D0}\x{87D1}\x{87D2}' . '\x{87D3}\x{87D4}\x{87D5}\x{87D6}\x{87D7}\x{87D8}\x{87D9}\x{87DB}\x{87DC}' . '\x{87DD}\x{87DE}\x{87DF}\x{87E0}\x{87E1}\x{87E2}\x{87E3}\x{87E4}\x{87E5}' . '\x{87E6}\x{87E7}\x{87E8}\x{87E9}\x{87EA}\x{87EB}\x{87EC}\x{87ED}\x{87EE}' . '\x{87EF}\x{87F1}\x{87F2}\x{87F3}\x{87F4}\x{87F5}\x{87F6}\x{87F7}\x{87F8}' . '\x{87F9}\x{87FA}\x{87FB}\x{87FC}\x{87FD}\x{87FE}\x{87FF}\x{8800}\x{8801}' . '\x{8802}\x{8803}\x{8804}\x{8805}\x{8806}\x{8808}\x{8809}\x{880A}\x{880B}' . '\x{880C}\x{880D}\x{880E}\x{880F}\x{8810}\x{8811}\x{8813}\x{8814}\x{8815}' . '\x{8816}\x{8817}\x{8818}\x{8819}\x{881A}\x{881B}\x{881C}\x{881D}\x{881E}' . '\x{881F}\x{8820}\x{8821}\x{8822}\x{8823}\x{8824}\x{8825}\x{8826}\x{8827}' . '\x{8828}\x{8829}\x{882A}\x{882B}\x{882C}\x{882E}\x{882F}\x{8830}\x{8831}' . '\x{8832}\x{8833}\x{8834}\x{8835}\x{8836}\x{8837}\x{8838}\x{8839}\x{883B}' . '\x{883C}\x{883D}\x{883E}\x{883F}\x{8840}\x{8841}\x{8842}\x{8843}\x{8844}' . '\x{8845}\x{8846}\x{8848}\x{8849}\x{884A}\x{884B}\x{884C}\x{884D}\x{884E}' . '\x{884F}\x{8850}\x{8851}\x{8852}\x{8853}\x{8854}\x{8855}\x{8856}\x{8857}' . '\x{8859}\x{885A}\x{885B}\x{885D}\x{885E}\x{8860}\x{8861}\x{8862}\x{8863}' . '\x{8864}\x{8865}\x{8866}\x{8867}\x{8868}\x{8869}\x{886A}\x{886B}\x{886C}' . '\x{886D}\x{886E}\x{886F}\x{8870}\x{8871}\x{8872}\x{8873}\x{8874}\x{8875}' . '\x{8876}\x{8877}\x{8878}\x{8879}\x{887B}\x{887C}\x{887D}\x{887E}\x{887F}' . '\x{8880}\x{8881}\x{8882}\x{8883}\x{8884}\x{8885}\x{8886}\x{8887}\x{8888}' . '\x{8889}\x{888A}\x{888B}\x{888C}\x{888D}\x{888E}\x{888F}\x{8890}\x{8891}' . '\x{8892}\x{8893}\x{8894}\x{8895}\x{8896}\x{8897}\x{8898}\x{8899}\x{889A}' . '\x{889B}\x{889C}\x{889D}\x{889E}\x{889F}\x{88A0}\x{88A1}\x{88A2}\x{88A3}' . '\x{88A4}\x{88A5}\x{88A6}\x{88A7}\x{88A8}\x{88A9}\x{88AA}\x{88AB}\x{88AC}' . '\x{88AD}\x{88AE}\x{88AF}\x{88B0}\x{88B1}\x{88B2}\x{88B3}\x{88B4}\x{88B6}' . '\x{88B7}\x{88B8}\x{88B9}\x{88BA}\x{88BB}\x{88BC}\x{88BD}\x{88BE}\x{88BF}' . '\x{88C0}\x{88C1}\x{88C2}\x{88C3}\x{88C4}\x{88C5}\x{88C6}\x{88C7}\x{88C8}' . '\x{88C9}\x{88CA}\x{88CB}\x{88CC}\x{88CD}\x{88CE}\x{88CF}\x{88D0}\x{88D1}' . '\x{88D2}\x{88D3}\x{88D4}\x{88D5}\x{88D6}\x{88D7}\x{88D8}\x{88D9}\x{88DA}' . '\x{88DB}\x{88DC}\x{88DD}\x{88DE}\x{88DF}\x{88E0}\x{88E1}\x{88E2}\x{88E3}' . '\x{88E4}\x{88E5}\x{88E7}\x{88E8}\x{88EA}\x{88EB}\x{88EC}\x{88EE}\x{88EF}' . '\x{88F0}\x{88F1}\x{88F2}\x{88F3}\x{88F4}\x{88F5}\x{88F6}\x{88F7}\x{88F8}' . '\x{88F9}\x{88FA}\x{88FB}\x{88FC}\x{88FD}\x{88FE}\x{88FF}\x{8900}\x{8901}' . '\x{8902}\x{8904}\x{8905}\x{8906}\x{8907}\x{8908}\x{8909}\x{890A}\x{890B}' . '\x{890C}\x{890D}\x{890E}\x{8910}\x{8911}\x{8912}\x{8913}\x{8914}\x{8915}' . '\x{8916}\x{8917}\x{8918}\x{8919}\x{891A}\x{891B}\x{891C}\x{891D}\x{891E}' . '\x{891F}\x{8920}\x{8921}\x{8922}\x{8923}\x{8925}\x{8926}\x{8927}\x{8928}' . '\x{8929}\x{892A}\x{892B}\x{892C}\x{892D}\x{892E}\x{892F}\x{8930}\x{8931}' . '\x{8932}\x{8933}\x{8934}\x{8935}\x{8936}\x{8937}\x{8938}\x{8939}\x{893A}' . '\x{893B}\x{893C}\x{893D}\x{893E}\x{893F}\x{8940}\x{8941}\x{8942}\x{8943}' . '\x{8944}\x{8945}\x{8946}\x{8947}\x{8948}\x{8949}\x{894A}\x{894B}\x{894C}' . '\x{894E}\x{894F}\x{8950}\x{8951}\x{8952}\x{8953}\x{8954}\x{8955}\x{8956}' . '\x{8957}\x{8958}\x{8959}\x{895A}\x{895B}\x{895C}\x{895D}\x{895E}\x{895F}' . '\x{8960}\x{8961}\x{8962}\x{8963}\x{8964}\x{8966}\x{8967}\x{8968}\x{8969}' . '\x{896A}\x{896B}\x{896C}\x{896D}\x{896E}\x{896F}\x{8970}\x{8971}\x{8972}' . '\x{8973}\x{8974}\x{8976}\x{8977}\x{8978}\x{8979}\x{897A}\x{897B}\x{897C}' . '\x{897E}\x{897F}\x{8980}\x{8981}\x{8982}\x{8983}\x{8984}\x{8985}\x{8986}' . '\x{8987}\x{8988}\x{8989}\x{898A}\x{898B}\x{898C}\x{898E}\x{898F}\x{8991}' . '\x{8992}\x{8993}\x{8995}\x{8996}\x{8997}\x{8998}\x{899A}\x{899B}\x{899C}' . '\x{899D}\x{899E}\x{899F}\x{89A0}\x{89A1}\x{89A2}\x{89A3}\x{89A4}\x{89A5}' . '\x{89A6}\x{89A7}\x{89A8}\x{89AA}\x{89AB}\x{89AC}\x{89AD}\x{89AE}\x{89AF}' . '\x{89B1}\x{89B2}\x{89B3}\x{89B5}\x{89B6}\x{89B7}\x{89B8}\x{89B9}\x{89BA}' . '\x{89BD}\x{89BE}\x{89BF}\x{89C0}\x{89C1}\x{89C2}\x{89C3}\x{89C4}\x{89C5}' . '\x{89C6}\x{89C7}\x{89C8}\x{89C9}\x{89CA}\x{89CB}\x{89CC}\x{89CD}\x{89CE}' . '\x{89CF}\x{89D0}\x{89D1}\x{89D2}\x{89D3}\x{89D4}\x{89D5}\x{89D6}\x{89D7}' . '\x{89D8}\x{89D9}\x{89DA}\x{89DB}\x{89DC}\x{89DD}\x{89DE}\x{89DF}\x{89E0}' . '\x{89E1}\x{89E2}\x{89E3}\x{89E4}\x{89E5}\x{89E6}\x{89E7}\x{89E8}\x{89E9}' . '\x{89EA}\x{89EB}\x{89EC}\x{89ED}\x{89EF}\x{89F0}\x{89F1}\x{89F2}\x{89F3}' . '\x{89F4}\x{89F6}\x{89F7}\x{89F8}\x{89FA}\x{89FB}\x{89FC}\x{89FE}\x{89FF}' . '\x{8A00}\x{8A01}\x{8A02}\x{8A03}\x{8A04}\x{8A07}\x{8A08}\x{8A09}\x{8A0A}' . '\x{8A0B}\x{8A0C}\x{8A0D}\x{8A0E}\x{8A0F}\x{8A10}\x{8A11}\x{8A12}\x{8A13}' . '\x{8A15}\x{8A16}\x{8A17}\x{8A18}\x{8A1A}\x{8A1B}\x{8A1C}\x{8A1D}\x{8A1E}' . '\x{8A1F}\x{8A22}\x{8A23}\x{8A24}\x{8A25}\x{8A26}\x{8A27}\x{8A28}\x{8A29}' . '\x{8A2A}\x{8A2C}\x{8A2D}\x{8A2E}\x{8A2F}\x{8A30}\x{8A31}\x{8A32}\x{8A34}' . '\x{8A35}\x{8A36}\x{8A37}\x{8A38}\x{8A39}\x{8A3A}\x{8A3B}\x{8A3C}\x{8A3E}' . '\x{8A3F}\x{8A40}\x{8A41}\x{8A42}\x{8A43}\x{8A44}\x{8A45}\x{8A46}\x{8A47}' . '\x{8A48}\x{8A49}\x{8A4A}\x{8A4C}\x{8A4D}\x{8A4E}\x{8A4F}\x{8A50}\x{8A51}' . '\x{8A52}\x{8A53}\x{8A54}\x{8A55}\x{8A56}\x{8A57}\x{8A58}\x{8A59}\x{8A5A}' . '\x{8A5B}\x{8A5C}\x{8A5D}\x{8A5E}\x{8A5F}\x{8A60}\x{8A61}\x{8A62}\x{8A63}' . '\x{8A65}\x{8A66}\x{8A67}\x{8A68}\x{8A69}\x{8A6A}\x{8A6B}\x{8A6C}\x{8A6D}' . '\x{8A6E}\x{8A6F}\x{8A70}\x{8A71}\x{8A72}\x{8A73}\x{8A74}\x{8A75}\x{8A76}' . '\x{8A77}\x{8A79}\x{8A7A}\x{8A7B}\x{8A7C}\x{8A7E}\x{8A7F}\x{8A80}\x{8A81}' . '\x{8A82}\x{8A83}\x{8A84}\x{8A85}\x{8A86}\x{8A87}\x{8A89}\x{8A8A}\x{8A8B}' . '\x{8A8C}\x{8A8D}\x{8A8E}\x{8A8F}\x{8A90}\x{8A91}\x{8A92}\x{8A93}\x{8A94}' . '\x{8A95}\x{8A96}\x{8A97}\x{8A98}\x{8A99}\x{8A9A}\x{8A9B}\x{8A9C}\x{8A9D}' . '\x{8A9E}\x{8AA0}\x{8AA1}\x{8AA2}\x{8AA3}\x{8AA4}\x{8AA5}\x{8AA6}\x{8AA7}' . '\x{8AA8}\x{8AA9}\x{8AAA}\x{8AAB}\x{8AAC}\x{8AAE}\x{8AB0}\x{8AB1}\x{8AB2}' . '\x{8AB3}\x{8AB4}\x{8AB5}\x{8AB6}\x{8AB8}\x{8AB9}\x{8ABA}\x{8ABB}\x{8ABC}' . '\x{8ABD}\x{8ABE}\x{8ABF}\x{8AC0}\x{8AC1}\x{8AC2}\x{8AC3}\x{8AC4}\x{8AC5}' . '\x{8AC6}\x{8AC7}\x{8AC8}\x{8AC9}\x{8ACA}\x{8ACB}\x{8ACC}\x{8ACD}\x{8ACE}' . '\x{8ACF}\x{8AD1}\x{8AD2}\x{8AD3}\x{8AD4}\x{8AD5}\x{8AD6}\x{8AD7}\x{8AD8}' . '\x{8AD9}\x{8ADA}\x{8ADB}\x{8ADC}\x{8ADD}\x{8ADE}\x{8ADF}\x{8AE0}\x{8AE1}' . '\x{8AE2}\x{8AE3}\x{8AE4}\x{8AE5}\x{8AE6}\x{8AE7}\x{8AE8}\x{8AE9}\x{8AEA}' . '\x{8AEB}\x{8AED}\x{8AEE}\x{8AEF}\x{8AF0}\x{8AF1}\x{8AF2}\x{8AF3}\x{8AF4}' . '\x{8AF5}\x{8AF6}\x{8AF7}\x{8AF8}\x{8AF9}\x{8AFA}\x{8AFB}\x{8AFC}\x{8AFD}' . '\x{8AFE}\x{8AFF}\x{8B00}\x{8B01}\x{8B02}\x{8B03}\x{8B04}\x{8B05}\x{8B06}' . '\x{8B07}\x{8B08}\x{8B09}\x{8B0A}\x{8B0B}\x{8B0D}\x{8B0E}\x{8B0F}\x{8B10}' . '\x{8B11}\x{8B12}\x{8B13}\x{8B14}\x{8B15}\x{8B16}\x{8B17}\x{8B18}\x{8B19}' . '\x{8B1A}\x{8B1B}\x{8B1C}\x{8B1D}\x{8B1E}\x{8B1F}\x{8B20}\x{8B21}\x{8B22}' . '\x{8B23}\x{8B24}\x{8B25}\x{8B26}\x{8B27}\x{8B28}\x{8B2A}\x{8B2B}\x{8B2C}' . '\x{8B2D}\x{8B2E}\x{8B2F}\x{8B30}\x{8B31}\x{8B33}\x{8B34}\x{8B35}\x{8B36}' . '\x{8B37}\x{8B39}\x{8B3A}\x{8B3B}\x{8B3C}\x{8B3D}\x{8B3E}\x{8B40}\x{8B41}' . '\x{8B42}\x{8B43}\x{8B44}\x{8B45}\x{8B46}\x{8B47}\x{8B48}\x{8B49}\x{8B4A}' . '\x{8B4B}\x{8B4C}\x{8B4D}\x{8B4E}\x{8B4F}\x{8B50}\x{8B51}\x{8B52}\x{8B53}' . '\x{8B54}\x{8B55}\x{8B56}\x{8B57}\x{8B58}\x{8B59}\x{8B5A}\x{8B5B}\x{8B5C}' . '\x{8B5D}\x{8B5E}\x{8B5F}\x{8B60}\x{8B63}\x{8B64}\x{8B65}\x{8B66}\x{8B67}' . '\x{8B68}\x{8B6A}\x{8B6B}\x{8B6C}\x{8B6D}\x{8B6E}\x{8B6F}\x{8B70}\x{8B71}' . '\x{8B73}\x{8B74}\x{8B76}\x{8B77}\x{8B78}\x{8B79}\x{8B7A}\x{8B7B}\x{8B7D}' . '\x{8B7E}\x{8B7F}\x{8B80}\x{8B82}\x{8B83}\x{8B84}\x{8B85}\x{8B86}\x{8B88}' . '\x{8B89}\x{8B8A}\x{8B8B}\x{8B8C}\x{8B8E}\x{8B90}\x{8B91}\x{8B92}\x{8B93}' . '\x{8B94}\x{8B95}\x{8B96}\x{8B97}\x{8B98}\x{8B99}\x{8B9A}\x{8B9C}\x{8B9D}' . '\x{8B9E}\x{8B9F}\x{8BA0}\x{8BA1}\x{8BA2}\x{8BA3}\x{8BA4}\x{8BA5}\x{8BA6}' . '\x{8BA7}\x{8BA8}\x{8BA9}\x{8BAA}\x{8BAB}\x{8BAC}\x{8BAD}\x{8BAE}\x{8BAF}' . '\x{8BB0}\x{8BB1}\x{8BB2}\x{8BB3}\x{8BB4}\x{8BB5}\x{8BB6}\x{8BB7}\x{8BB8}' . '\x{8BB9}\x{8BBA}\x{8BBB}\x{8BBC}\x{8BBD}\x{8BBE}\x{8BBF}\x{8BC0}\x{8BC1}' . '\x{8BC2}\x{8BC3}\x{8BC4}\x{8BC5}\x{8BC6}\x{8BC7}\x{8BC8}\x{8BC9}\x{8BCA}' . '\x{8BCB}\x{8BCC}\x{8BCD}\x{8BCE}\x{8BCF}\x{8BD0}\x{8BD1}\x{8BD2}\x{8BD3}' . '\x{8BD4}\x{8BD5}\x{8BD6}\x{8BD7}\x{8BD8}\x{8BD9}\x{8BDA}\x{8BDB}\x{8BDC}' . '\x{8BDD}\x{8BDE}\x{8BDF}\x{8BE0}\x{8BE1}\x{8BE2}\x{8BE3}\x{8BE4}\x{8BE5}' . '\x{8BE6}\x{8BE7}\x{8BE8}\x{8BE9}\x{8BEA}\x{8BEB}\x{8BEC}\x{8BED}\x{8BEE}' . '\x{8BEF}\x{8BF0}\x{8BF1}\x{8BF2}\x{8BF3}\x{8BF4}\x{8BF5}\x{8BF6}\x{8BF7}' . '\x{8BF8}\x{8BF9}\x{8BFA}\x{8BFB}\x{8BFC}\x{8BFD}\x{8BFE}\x{8BFF}\x{8C00}' . '\x{8C01}\x{8C02}\x{8C03}\x{8C04}\x{8C05}\x{8C06}\x{8C07}\x{8C08}\x{8C09}' . '\x{8C0A}\x{8C0B}\x{8C0C}\x{8C0D}\x{8C0E}\x{8C0F}\x{8C10}\x{8C11}\x{8C12}' . '\x{8C13}\x{8C14}\x{8C15}\x{8C16}\x{8C17}\x{8C18}\x{8C19}\x{8C1A}\x{8C1B}' . '\x{8C1C}\x{8C1D}\x{8C1E}\x{8C1F}\x{8C20}\x{8C21}\x{8C22}\x{8C23}\x{8C24}' . '\x{8C25}\x{8C26}\x{8C27}\x{8C28}\x{8C29}\x{8C2A}\x{8C2B}\x{8C2C}\x{8C2D}' . '\x{8C2E}\x{8C2F}\x{8C30}\x{8C31}\x{8C32}\x{8C33}\x{8C34}\x{8C35}\x{8C36}' . '\x{8C37}\x{8C39}\x{8C3A}\x{8C3B}\x{8C3C}\x{8C3D}\x{8C3E}\x{8C3F}\x{8C41}' . '\x{8C42}\x{8C43}\x{8C45}\x{8C46}\x{8C47}\x{8C48}\x{8C49}\x{8C4A}\x{8C4B}' . '\x{8C4C}\x{8C4D}\x{8C4E}\x{8C4F}\x{8C50}\x{8C54}\x{8C55}\x{8C56}\x{8C57}' . '\x{8C59}\x{8C5A}\x{8C5B}\x{8C5C}\x{8C5D}\x{8C5E}\x{8C5F}\x{8C60}\x{8C61}' . '\x{8C62}\x{8C63}\x{8C64}\x{8C65}\x{8C66}\x{8C67}\x{8C68}\x{8C69}\x{8C6A}' . '\x{8C6B}\x{8C6C}\x{8C6D}\x{8C6E}\x{8C6F}\x{8C70}\x{8C71}\x{8C72}\x{8C73}' . '\x{8C75}\x{8C76}\x{8C77}\x{8C78}\x{8C79}\x{8C7A}\x{8C7B}\x{8C7D}\x{8C7E}' . '\x{8C80}\x{8C81}\x{8C82}\x{8C84}\x{8C85}\x{8C86}\x{8C88}\x{8C89}\x{8C8A}' . '\x{8C8C}\x{8C8D}\x{8C8F}\x{8C90}\x{8C91}\x{8C92}\x{8C93}\x{8C94}\x{8C95}' . '\x{8C96}\x{8C97}\x{8C98}\x{8C99}\x{8C9A}\x{8C9C}\x{8C9D}\x{8C9E}\x{8C9F}' . '\x{8CA0}\x{8CA1}\x{8CA2}\x{8CA3}\x{8CA4}\x{8CA5}\x{8CA7}\x{8CA8}\x{8CA9}' . '\x{8CAA}\x{8CAB}\x{8CAC}\x{8CAD}\x{8CAE}\x{8CAF}\x{8CB0}\x{8CB1}\x{8CB2}' . '\x{8CB3}\x{8CB4}\x{8CB5}\x{8CB6}\x{8CB7}\x{8CB8}\x{8CB9}\x{8CBA}\x{8CBB}' . '\x{8CBC}\x{8CBD}\x{8CBE}\x{8CBF}\x{8CC0}\x{8CC1}\x{8CC2}\x{8CC3}\x{8CC4}' . '\x{8CC5}\x{8CC6}\x{8CC7}\x{8CC8}\x{8CC9}\x{8CCA}\x{8CCC}\x{8CCE}\x{8CCF}' . '\x{8CD0}\x{8CD1}\x{8CD2}\x{8CD3}\x{8CD4}\x{8CD5}\x{8CD7}\x{8CD9}\x{8CDA}' . '\x{8CDB}\x{8CDC}\x{8CDD}\x{8CDE}\x{8CDF}\x{8CE0}\x{8CE1}\x{8CE2}\x{8CE3}' . '\x{8CE4}\x{8CE5}\x{8CE6}\x{8CE7}\x{8CE8}\x{8CEA}\x{8CEB}\x{8CEC}\x{8CED}' . '\x{8CEE}\x{8CEF}\x{8CF0}\x{8CF1}\x{8CF2}\x{8CF3}\x{8CF4}\x{8CF5}\x{8CF6}' . '\x{8CF8}\x{8CF9}\x{8CFA}\x{8CFB}\x{8CFC}\x{8CFD}\x{8CFE}\x{8CFF}\x{8D00}' . '\x{8D02}\x{8D03}\x{8D04}\x{8D05}\x{8D06}\x{8D07}\x{8D08}\x{8D09}\x{8D0A}' . '\x{8D0B}\x{8D0C}\x{8D0D}\x{8D0E}\x{8D0F}\x{8D10}\x{8D13}\x{8D14}\x{8D15}' . '\x{8D16}\x{8D17}\x{8D18}\x{8D19}\x{8D1A}\x{8D1B}\x{8D1C}\x{8D1D}\x{8D1E}' . '\x{8D1F}\x{8D20}\x{8D21}\x{8D22}\x{8D23}\x{8D24}\x{8D25}\x{8D26}\x{8D27}' . '\x{8D28}\x{8D29}\x{8D2A}\x{8D2B}\x{8D2C}\x{8D2D}\x{8D2E}\x{8D2F}\x{8D30}' . '\x{8D31}\x{8D32}\x{8D33}\x{8D34}\x{8D35}\x{8D36}\x{8D37}\x{8D38}\x{8D39}' . '\x{8D3A}\x{8D3B}\x{8D3C}\x{8D3D}\x{8D3E}\x{8D3F}\x{8D40}\x{8D41}\x{8D42}' . '\x{8D43}\x{8D44}\x{8D45}\x{8D46}\x{8D47}\x{8D48}\x{8D49}\x{8D4A}\x{8D4B}' . '\x{8D4C}\x{8D4D}\x{8D4E}\x{8D4F}\x{8D50}\x{8D51}\x{8D52}\x{8D53}\x{8D54}' . '\x{8D55}\x{8D56}\x{8D57}\x{8D58}\x{8D59}\x{8D5A}\x{8D5B}\x{8D5C}\x{8D5D}' . '\x{8D5E}\x{8D5F}\x{8D60}\x{8D61}\x{8D62}\x{8D63}\x{8D64}\x{8D65}\x{8D66}' . '\x{8D67}\x{8D68}\x{8D69}\x{8D6A}\x{8D6B}\x{8D6C}\x{8D6D}\x{8D6E}\x{8D6F}' . '\x{8D70}\x{8D71}\x{8D72}\x{8D73}\x{8D74}\x{8D75}\x{8D76}\x{8D77}\x{8D78}' . '\x{8D79}\x{8D7A}\x{8D7B}\x{8D7D}\x{8D7E}\x{8D7F}\x{8D80}\x{8D81}\x{8D82}' . '\x{8D83}\x{8D84}\x{8D85}\x{8D86}\x{8D87}\x{8D88}\x{8D89}\x{8D8A}\x{8D8B}' . '\x{8D8C}\x{8D8D}\x{8D8E}\x{8D8F}\x{8D90}\x{8D91}\x{8D92}\x{8D93}\x{8D94}' . '\x{8D95}\x{8D96}\x{8D97}\x{8D98}\x{8D99}\x{8D9A}\x{8D9B}\x{8D9C}\x{8D9D}' . '\x{8D9E}\x{8D9F}\x{8DA0}\x{8DA1}\x{8DA2}\x{8DA3}\x{8DA4}\x{8DA5}\x{8DA7}' . '\x{8DA8}\x{8DA9}\x{8DAA}\x{8DAB}\x{8DAC}\x{8DAD}\x{8DAE}\x{8DAF}\x{8DB0}' . '\x{8DB1}\x{8DB2}\x{8DB3}\x{8DB4}\x{8DB5}\x{8DB6}\x{8DB7}\x{8DB8}\x{8DB9}' . '\x{8DBA}\x{8DBB}\x{8DBC}\x{8DBD}\x{8DBE}\x{8DBF}\x{8DC1}\x{8DC2}\x{8DC3}' . '\x{8DC4}\x{8DC5}\x{8DC6}\x{8DC7}\x{8DC8}\x{8DC9}\x{8DCA}\x{8DCB}\x{8DCC}' . '\x{8DCD}\x{8DCE}\x{8DCF}\x{8DD0}\x{8DD1}\x{8DD2}\x{8DD3}\x{8DD4}\x{8DD5}' . '\x{8DD6}\x{8DD7}\x{8DD8}\x{8DD9}\x{8DDA}\x{8DDB}\x{8DDC}\x{8DDD}\x{8DDE}' . '\x{8DDF}\x{8DE0}\x{8DE1}\x{8DE2}\x{8DE3}\x{8DE4}\x{8DE6}\x{8DE7}\x{8DE8}' . '\x{8DE9}\x{8DEA}\x{8DEB}\x{8DEC}\x{8DED}\x{8DEE}\x{8DEF}\x{8DF0}\x{8DF1}' . '\x{8DF2}\x{8DF3}\x{8DF4}\x{8DF5}\x{8DF6}\x{8DF7}\x{8DF8}\x{8DF9}\x{8DFA}' . '\x{8DFB}\x{8DFC}\x{8DFD}\x{8DFE}\x{8DFF}\x{8E00}\x{8E02}\x{8E03}\x{8E04}' . '\x{8E05}\x{8E06}\x{8E07}\x{8E08}\x{8E09}\x{8E0A}\x{8E0C}\x{8E0D}\x{8E0E}' . '\x{8E0F}\x{8E10}\x{8E11}\x{8E12}\x{8E13}\x{8E14}\x{8E15}\x{8E16}\x{8E17}' . '\x{8E18}\x{8E19}\x{8E1A}\x{8E1B}\x{8E1C}\x{8E1D}\x{8E1E}\x{8E1F}\x{8E20}' . '\x{8E21}\x{8E22}\x{8E23}\x{8E24}\x{8E25}\x{8E26}\x{8E27}\x{8E28}\x{8E29}' . '\x{8E2A}\x{8E2B}\x{8E2C}\x{8E2D}\x{8E2E}\x{8E2F}\x{8E30}\x{8E31}\x{8E33}' . '\x{8E34}\x{8E35}\x{8E36}\x{8E37}\x{8E38}\x{8E39}\x{8E3A}\x{8E3B}\x{8E3C}' . '\x{8E3D}\x{8E3E}\x{8E3F}\x{8E40}\x{8E41}\x{8E42}\x{8E43}\x{8E44}\x{8E45}' . '\x{8E47}\x{8E48}\x{8E49}\x{8E4A}\x{8E4B}\x{8E4C}\x{8E4D}\x{8E4E}\x{8E50}' . '\x{8E51}\x{8E52}\x{8E53}\x{8E54}\x{8E55}\x{8E56}\x{8E57}\x{8E58}\x{8E59}' . '\x{8E5A}\x{8E5B}\x{8E5C}\x{8E5D}\x{8E5E}\x{8E5F}\x{8E60}\x{8E61}\x{8E62}' . '\x{8E63}\x{8E64}\x{8E65}\x{8E66}\x{8E67}\x{8E68}\x{8E69}\x{8E6A}\x{8E6B}' . '\x{8E6C}\x{8E6D}\x{8E6F}\x{8E70}\x{8E71}\x{8E72}\x{8E73}\x{8E74}\x{8E76}' . '\x{8E78}\x{8E7A}\x{8E7B}\x{8E7C}\x{8E7D}\x{8E7E}\x{8E7F}\x{8E80}\x{8E81}' . '\x{8E82}\x{8E83}\x{8E84}\x{8E85}\x{8E86}\x{8E87}\x{8E88}\x{8E89}\x{8E8A}' . '\x{8E8B}\x{8E8C}\x{8E8D}\x{8E8E}\x{8E8F}\x{8E90}\x{8E91}\x{8E92}\x{8E93}' . '\x{8E94}\x{8E95}\x{8E96}\x{8E97}\x{8E98}\x{8E9A}\x{8E9C}\x{8E9D}\x{8E9E}' . '\x{8E9F}\x{8EA0}\x{8EA1}\x{8EA3}\x{8EA4}\x{8EA5}\x{8EA6}\x{8EA7}\x{8EA8}' . '\x{8EA9}\x{8EAA}\x{8EAB}\x{8EAC}\x{8EAD}\x{8EAE}\x{8EAF}\x{8EB0}\x{8EB1}' . '\x{8EB2}\x{8EB4}\x{8EB5}\x{8EB8}\x{8EB9}\x{8EBA}\x{8EBB}\x{8EBC}\x{8EBD}' . '\x{8EBE}\x{8EBF}\x{8EC0}\x{8EC2}\x{8EC3}\x{8EC5}\x{8EC6}\x{8EC7}\x{8EC8}' . '\x{8EC9}\x{8ECA}\x{8ECB}\x{8ECC}\x{8ECD}\x{8ECE}\x{8ECF}\x{8ED0}\x{8ED1}' . '\x{8ED2}\x{8ED3}\x{8ED4}\x{8ED5}\x{8ED6}\x{8ED7}\x{8ED8}\x{8EDA}\x{8EDB}' . '\x{8EDC}\x{8EDD}\x{8EDE}\x{8EDF}\x{8EE0}\x{8EE1}\x{8EE4}\x{8EE5}\x{8EE6}' . '\x{8EE7}\x{8EE8}\x{8EE9}\x{8EEA}\x{8EEB}\x{8EEC}\x{8EED}\x{8EEE}\x{8EEF}' . '\x{8EF1}\x{8EF2}\x{8EF3}\x{8EF4}\x{8EF5}\x{8EF6}\x{8EF7}\x{8EF8}\x{8EF9}' . '\x{8EFA}\x{8EFB}\x{8EFC}\x{8EFD}\x{8EFE}\x{8EFF}\x{8F00}\x{8F01}\x{8F02}' . '\x{8F03}\x{8F04}\x{8F05}\x{8F06}\x{8F07}\x{8F08}\x{8F09}\x{8F0A}\x{8F0B}' . '\x{8F0D}\x{8F0E}\x{8F10}\x{8F11}\x{8F12}\x{8F13}\x{8F14}\x{8F15}\x{8F16}' . '\x{8F17}\x{8F18}\x{8F1A}\x{8F1B}\x{8F1C}\x{8F1D}\x{8F1E}\x{8F1F}\x{8F20}' . '\x{8F21}\x{8F22}\x{8F23}\x{8F24}\x{8F25}\x{8F26}\x{8F27}\x{8F28}\x{8F29}' . '\x{8F2A}\x{8F2B}\x{8F2C}\x{8F2E}\x{8F2F}\x{8F30}\x{8F31}\x{8F32}\x{8F33}' . '\x{8F34}\x{8F35}\x{8F36}\x{8F37}\x{8F38}\x{8F39}\x{8F3B}\x{8F3C}\x{8F3D}' . '\x{8F3E}\x{8F3F}\x{8F40}\x{8F42}\x{8F43}\x{8F44}\x{8F45}\x{8F46}\x{8F47}' . '\x{8F48}\x{8F49}\x{8F4A}\x{8F4B}\x{8F4C}\x{8F4D}\x{8F4E}\x{8F4F}\x{8F50}' . '\x{8F51}\x{8F52}\x{8F53}\x{8F54}\x{8F55}\x{8F56}\x{8F57}\x{8F58}\x{8F59}' . '\x{8F5A}\x{8F5B}\x{8F5D}\x{8F5E}\x{8F5F}\x{8F60}\x{8F61}\x{8F62}\x{8F63}' . '\x{8F64}\x{8F65}\x{8F66}\x{8F67}\x{8F68}\x{8F69}\x{8F6A}\x{8F6B}\x{8F6C}' . '\x{8F6D}\x{8F6E}\x{8F6F}\x{8F70}\x{8F71}\x{8F72}\x{8F73}\x{8F74}\x{8F75}' . '\x{8F76}\x{8F77}\x{8F78}\x{8F79}\x{8F7A}\x{8F7B}\x{8F7C}\x{8F7D}\x{8F7E}' . '\x{8F7F}\x{8F80}\x{8F81}\x{8F82}\x{8F83}\x{8F84}\x{8F85}\x{8F86}\x{8F87}' . '\x{8F88}\x{8F89}\x{8F8A}\x{8F8B}\x{8F8C}\x{8F8D}\x{8F8E}\x{8F8F}\x{8F90}' . '\x{8F91}\x{8F92}\x{8F93}\x{8F94}\x{8F95}\x{8F96}\x{8F97}\x{8F98}\x{8F99}' . '\x{8F9A}\x{8F9B}\x{8F9C}\x{8F9E}\x{8F9F}\x{8FA0}\x{8FA1}\x{8FA2}\x{8FA3}' . '\x{8FA5}\x{8FA6}\x{8FA7}\x{8FA8}\x{8FA9}\x{8FAA}\x{8FAB}\x{8FAC}\x{8FAD}' . '\x{8FAE}\x{8FAF}\x{8FB0}\x{8FB1}\x{8FB2}\x{8FB4}\x{8FB5}\x{8FB6}\x{8FB7}' . '\x{8FB8}\x{8FB9}\x{8FBB}\x{8FBC}\x{8FBD}\x{8FBE}\x{8FBF}\x{8FC0}\x{8FC1}' . '\x{8FC2}\x{8FC4}\x{8FC5}\x{8FC6}\x{8FC7}\x{8FC8}\x{8FC9}\x{8FCB}\x{8FCC}' . '\x{8FCD}\x{8FCE}\x{8FCF}\x{8FD0}\x{8FD1}\x{8FD2}\x{8FD3}\x{8FD4}\x{8FD5}' . '\x{8FD6}\x{8FD7}\x{8FD8}\x{8FD9}\x{8FDA}\x{8FDB}\x{8FDC}\x{8FDD}\x{8FDE}' . '\x{8FDF}\x{8FE0}\x{8FE1}\x{8FE2}\x{8FE3}\x{8FE4}\x{8FE5}\x{8FE6}\x{8FE8}' . '\x{8FE9}\x{8FEA}\x{8FEB}\x{8FEC}\x{8FED}\x{8FEE}\x{8FEF}\x{8FF0}\x{8FF1}' . '\x{8FF2}\x{8FF3}\x{8FF4}\x{8FF5}\x{8FF6}\x{8FF7}\x{8FF8}\x{8FF9}\x{8FFA}' . '\x{8FFB}\x{8FFC}\x{8FFD}\x{8FFE}\x{8FFF}\x{9000}\x{9001}\x{9002}\x{9003}' . '\x{9004}\x{9005}\x{9006}\x{9007}\x{9008}\x{9009}\x{900A}\x{900B}\x{900C}' . '\x{900D}\x{900F}\x{9010}\x{9011}\x{9012}\x{9013}\x{9014}\x{9015}\x{9016}' . '\x{9017}\x{9018}\x{9019}\x{901A}\x{901B}\x{901C}\x{901D}\x{901E}\x{901F}' . '\x{9020}\x{9021}\x{9022}\x{9023}\x{9024}\x{9025}\x{9026}\x{9027}\x{9028}' . '\x{9029}\x{902B}\x{902D}\x{902E}\x{902F}\x{9030}\x{9031}\x{9032}\x{9033}' . '\x{9034}\x{9035}\x{9036}\x{9038}\x{903A}\x{903B}\x{903C}\x{903D}\x{903E}' . '\x{903F}\x{9041}\x{9042}\x{9043}\x{9044}\x{9045}\x{9047}\x{9048}\x{9049}' . '\x{904A}\x{904B}\x{904C}\x{904D}\x{904E}\x{904F}\x{9050}\x{9051}\x{9052}' . '\x{9053}\x{9054}\x{9055}\x{9056}\x{9057}\x{9058}\x{9059}\x{905A}\x{905B}' . '\x{905C}\x{905D}\x{905E}\x{905F}\x{9060}\x{9061}\x{9062}\x{9063}\x{9064}' . '\x{9065}\x{9066}\x{9067}\x{9068}\x{9069}\x{906A}\x{906B}\x{906C}\x{906D}' . '\x{906E}\x{906F}\x{9070}\x{9071}\x{9072}\x{9073}\x{9074}\x{9075}\x{9076}' . '\x{9077}\x{9078}\x{9079}\x{907A}\x{907B}\x{907C}\x{907D}\x{907E}\x{907F}' . '\x{9080}\x{9081}\x{9082}\x{9083}\x{9084}\x{9085}\x{9086}\x{9087}\x{9088}' . '\x{9089}\x{908A}\x{908B}\x{908C}\x{908D}\x{908E}\x{908F}\x{9090}\x{9091}' . '\x{9092}\x{9093}\x{9094}\x{9095}\x{9096}\x{9097}\x{9098}\x{9099}\x{909A}' . '\x{909B}\x{909C}\x{909D}\x{909E}\x{909F}\x{90A0}\x{90A1}\x{90A2}\x{90A3}' . '\x{90A4}\x{90A5}\x{90A6}\x{90A7}\x{90A8}\x{90A9}\x{90AA}\x{90AC}\x{90AD}' . '\x{90AE}\x{90AF}\x{90B0}\x{90B1}\x{90B2}\x{90B3}\x{90B4}\x{90B5}\x{90B6}' . '\x{90B7}\x{90B8}\x{90B9}\x{90BA}\x{90BB}\x{90BC}\x{90BD}\x{90BE}\x{90BF}' . '\x{90C0}\x{90C1}\x{90C2}\x{90C3}\x{90C4}\x{90C5}\x{90C6}\x{90C7}\x{90C8}' . '\x{90C9}\x{90CA}\x{90CB}\x{90CE}\x{90CF}\x{90D0}\x{90D1}\x{90D3}\x{90D4}' . '\x{90D5}\x{90D6}\x{90D7}\x{90D8}\x{90D9}\x{90DA}\x{90DB}\x{90DC}\x{90DD}' . '\x{90DE}\x{90DF}\x{90E0}\x{90E1}\x{90E2}\x{90E3}\x{90E4}\x{90E5}\x{90E6}' . '\x{90E7}\x{90E8}\x{90E9}\x{90EA}\x{90EB}\x{90EC}\x{90ED}\x{90EE}\x{90EF}' . '\x{90F0}\x{90F1}\x{90F2}\x{90F3}\x{90F4}\x{90F5}\x{90F7}\x{90F8}\x{90F9}' . '\x{90FA}\x{90FB}\x{90FC}\x{90FD}\x{90FE}\x{90FF}\x{9100}\x{9101}\x{9102}' . '\x{9103}\x{9104}\x{9105}\x{9106}\x{9107}\x{9108}\x{9109}\x{910B}\x{910C}' . '\x{910D}\x{910E}\x{910F}\x{9110}\x{9111}\x{9112}\x{9113}\x{9114}\x{9115}' . '\x{9116}\x{9117}\x{9118}\x{9119}\x{911A}\x{911B}\x{911C}\x{911D}\x{911E}' . '\x{911F}\x{9120}\x{9121}\x{9122}\x{9123}\x{9124}\x{9125}\x{9126}\x{9127}' . '\x{9128}\x{9129}\x{912A}\x{912B}\x{912C}\x{912D}\x{912E}\x{912F}\x{9130}' . '\x{9131}\x{9132}\x{9133}\x{9134}\x{9135}\x{9136}\x{9137}\x{9138}\x{9139}' . '\x{913A}\x{913B}\x{913E}\x{913F}\x{9140}\x{9141}\x{9142}\x{9143}\x{9144}' . '\x{9145}\x{9146}\x{9147}\x{9148}\x{9149}\x{914A}\x{914B}\x{914C}\x{914D}' . '\x{914E}\x{914F}\x{9150}\x{9151}\x{9152}\x{9153}\x{9154}\x{9155}\x{9156}' . '\x{9157}\x{9158}\x{915A}\x{915B}\x{915C}\x{915D}\x{915E}\x{915F}\x{9160}' . '\x{9161}\x{9162}\x{9163}\x{9164}\x{9165}\x{9166}\x{9167}\x{9168}\x{9169}' . '\x{916A}\x{916B}\x{916C}\x{916D}\x{916E}\x{916F}\x{9170}\x{9171}\x{9172}' . '\x{9173}\x{9174}\x{9175}\x{9176}\x{9177}\x{9178}\x{9179}\x{917A}\x{917C}' . '\x{917D}\x{917E}\x{917F}\x{9180}\x{9181}\x{9182}\x{9183}\x{9184}\x{9185}' . '\x{9186}\x{9187}\x{9188}\x{9189}\x{918A}\x{918B}\x{918C}\x{918D}\x{918E}' . '\x{918F}\x{9190}\x{9191}\x{9192}\x{9193}\x{9194}\x{9196}\x{9199}\x{919A}' . '\x{919B}\x{919C}\x{919D}\x{919E}\x{919F}\x{91A0}\x{91A1}\x{91A2}\x{91A3}' . '\x{91A5}\x{91A6}\x{91A7}\x{91A8}\x{91AA}\x{91AB}\x{91AC}\x{91AD}\x{91AE}' . '\x{91AF}\x{91B0}\x{91B1}\x{91B2}\x{91B3}\x{91B4}\x{91B5}\x{91B6}\x{91B7}' . '\x{91B9}\x{91BA}\x{91BB}\x{91BC}\x{91BD}\x{91BE}\x{91C0}\x{91C1}\x{91C2}' . '\x{91C3}\x{91C5}\x{91C6}\x{91C7}\x{91C9}\x{91CA}\x{91CB}\x{91CC}\x{91CD}' . '\x{91CE}\x{91CF}\x{91D0}\x{91D1}\x{91D2}\x{91D3}\x{91D4}\x{91D5}\x{91D7}' . '\x{91D8}\x{91D9}\x{91DA}\x{91DB}\x{91DC}\x{91DD}\x{91DE}\x{91DF}\x{91E2}' . '\x{91E3}\x{91E4}\x{91E5}\x{91E6}\x{91E7}\x{91E8}\x{91E9}\x{91EA}\x{91EB}' . '\x{91EC}\x{91ED}\x{91EE}\x{91F0}\x{91F1}\x{91F2}\x{91F3}\x{91F4}\x{91F5}' . '\x{91F7}\x{91F8}\x{91F9}\x{91FA}\x{91FB}\x{91FD}\x{91FE}\x{91FF}\x{9200}' . '\x{9201}\x{9202}\x{9203}\x{9204}\x{9205}\x{9206}\x{9207}\x{9208}\x{9209}' . '\x{920A}\x{920B}\x{920C}\x{920D}\x{920E}\x{920F}\x{9210}\x{9211}\x{9212}' . '\x{9214}\x{9215}\x{9216}\x{9217}\x{9218}\x{9219}\x{921A}\x{921B}\x{921C}' . '\x{921D}\x{921E}\x{9220}\x{9221}\x{9223}\x{9224}\x{9225}\x{9226}\x{9227}' . '\x{9228}\x{9229}\x{922A}\x{922B}\x{922D}\x{922E}\x{922F}\x{9230}\x{9231}' . '\x{9232}\x{9233}\x{9234}\x{9235}\x{9236}\x{9237}\x{9238}\x{9239}\x{923A}' . '\x{923B}\x{923C}\x{923D}\x{923E}\x{923F}\x{9240}\x{9241}\x{9242}\x{9245}' . '\x{9246}\x{9247}\x{9248}\x{9249}\x{924A}\x{924B}\x{924C}\x{924D}\x{924E}' . '\x{924F}\x{9250}\x{9251}\x{9252}\x{9253}\x{9254}\x{9255}\x{9256}\x{9257}' . '\x{9258}\x{9259}\x{925A}\x{925B}\x{925C}\x{925D}\x{925E}\x{925F}\x{9260}' . '\x{9261}\x{9262}\x{9263}\x{9264}\x{9265}\x{9266}\x{9267}\x{9268}\x{926B}' . '\x{926C}\x{926D}\x{926E}\x{926F}\x{9270}\x{9272}\x{9273}\x{9274}\x{9275}' . '\x{9276}\x{9277}\x{9278}\x{9279}\x{927A}\x{927B}\x{927C}\x{927D}\x{927E}' . '\x{927F}\x{9280}\x{9282}\x{9283}\x{9285}\x{9286}\x{9287}\x{9288}\x{9289}' . '\x{928A}\x{928B}\x{928C}\x{928D}\x{928E}\x{928F}\x{9290}\x{9291}\x{9292}' . '\x{9293}\x{9294}\x{9295}\x{9296}\x{9297}\x{9298}\x{9299}\x{929A}\x{929B}' . '\x{929C}\x{929D}\x{929F}\x{92A0}\x{92A1}\x{92A2}\x{92A3}\x{92A4}\x{92A5}' . '\x{92A6}\x{92A7}\x{92A8}\x{92A9}\x{92AA}\x{92AB}\x{92AC}\x{92AD}\x{92AE}' . '\x{92AF}\x{92B0}\x{92B1}\x{92B2}\x{92B3}\x{92B4}\x{92B5}\x{92B6}\x{92B7}' . '\x{92B8}\x{92B9}\x{92BA}\x{92BB}\x{92BC}\x{92BE}\x{92BF}\x{92C0}\x{92C1}' . '\x{92C2}\x{92C3}\x{92C4}\x{92C5}\x{92C6}\x{92C7}\x{92C8}\x{92C9}\x{92CA}' . '\x{92CB}\x{92CC}\x{92CD}\x{92CE}\x{92CF}\x{92D0}\x{92D1}\x{92D2}\x{92D3}' . '\x{92D5}\x{92D6}\x{92D7}\x{92D8}\x{92D9}\x{92DA}\x{92DC}\x{92DD}\x{92DE}' . '\x{92DF}\x{92E0}\x{92E1}\x{92E3}\x{92E4}\x{92E5}\x{92E6}\x{92E7}\x{92E8}' . '\x{92E9}\x{92EA}\x{92EB}\x{92EC}\x{92ED}\x{92EE}\x{92EF}\x{92F0}\x{92F1}' . '\x{92F2}\x{92F3}\x{92F4}\x{92F5}\x{92F6}\x{92F7}\x{92F8}\x{92F9}\x{92FA}' . '\x{92FB}\x{92FC}\x{92FD}\x{92FE}\x{92FF}\x{9300}\x{9301}\x{9302}\x{9303}' . '\x{9304}\x{9305}\x{9306}\x{9307}\x{9308}\x{9309}\x{930A}\x{930B}\x{930C}' . '\x{930D}\x{930E}\x{930F}\x{9310}\x{9311}\x{9312}\x{9313}\x{9314}\x{9315}' . '\x{9316}\x{9317}\x{9318}\x{9319}\x{931A}\x{931B}\x{931D}\x{931E}\x{931F}' . '\x{9320}\x{9321}\x{9322}\x{9323}\x{9324}\x{9325}\x{9326}\x{9327}\x{9328}' . '\x{9329}\x{932A}\x{932B}\x{932D}\x{932E}\x{932F}\x{9332}\x{9333}\x{9334}' . '\x{9335}\x{9336}\x{9337}\x{9338}\x{9339}\x{933A}\x{933B}\x{933C}\x{933D}' . '\x{933E}\x{933F}\x{9340}\x{9341}\x{9342}\x{9343}\x{9344}\x{9345}\x{9346}' . '\x{9347}\x{9348}\x{9349}\x{934A}\x{934B}\x{934C}\x{934D}\x{934E}\x{934F}' . '\x{9350}\x{9351}\x{9352}\x{9353}\x{9354}\x{9355}\x{9356}\x{9357}\x{9358}' . '\x{9359}\x{935A}\x{935B}\x{935C}\x{935D}\x{935E}\x{935F}\x{9360}\x{9361}' . '\x{9363}\x{9364}\x{9365}\x{9366}\x{9367}\x{9369}\x{936A}\x{936C}\x{936D}' . '\x{936E}\x{9370}\x{9371}\x{9372}\x{9374}\x{9375}\x{9376}\x{9377}\x{9379}' . '\x{937A}\x{937B}\x{937C}\x{937D}\x{937E}\x{9380}\x{9382}\x{9383}\x{9384}' . '\x{9385}\x{9386}\x{9387}\x{9388}\x{9389}\x{938A}\x{938C}\x{938D}\x{938E}' . '\x{938F}\x{9390}\x{9391}\x{9392}\x{9393}\x{9394}\x{9395}\x{9396}\x{9397}' . '\x{9398}\x{9399}\x{939A}\x{939B}\x{939D}\x{939E}\x{939F}\x{93A1}\x{93A2}' . '\x{93A3}\x{93A4}\x{93A5}\x{93A6}\x{93A7}\x{93A8}\x{93A9}\x{93AA}\x{93AC}' . '\x{93AD}\x{93AE}\x{93AF}\x{93B0}\x{93B1}\x{93B2}\x{93B3}\x{93B4}\x{93B5}' . '\x{93B6}\x{93B7}\x{93B8}\x{93B9}\x{93BA}\x{93BC}\x{93BD}\x{93BE}\x{93BF}' . '\x{93C0}\x{93C1}\x{93C2}\x{93C3}\x{93C4}\x{93C5}\x{93C6}\x{93C7}\x{93C8}' . '\x{93C9}\x{93CA}\x{93CB}\x{93CC}\x{93CD}\x{93CE}\x{93CF}\x{93D0}\x{93D1}' . '\x{93D2}\x{93D3}\x{93D4}\x{93D5}\x{93D6}\x{93D7}\x{93D8}\x{93D9}\x{93DA}' . '\x{93DB}\x{93DC}\x{93DD}\x{93DE}\x{93DF}\x{93E1}\x{93E2}\x{93E3}\x{93E4}' . '\x{93E6}\x{93E7}\x{93E8}\x{93E9}\x{93EA}\x{93EB}\x{93EC}\x{93ED}\x{93EE}' . '\x{93EF}\x{93F0}\x{93F1}\x{93F2}\x{93F4}\x{93F5}\x{93F6}\x{93F7}\x{93F8}' . '\x{93F9}\x{93FA}\x{93FB}\x{93FC}\x{93FD}\x{93FE}\x{93FF}\x{9400}\x{9401}' . '\x{9403}\x{9404}\x{9405}\x{9406}\x{9407}\x{9408}\x{9409}\x{940A}\x{940B}' . '\x{940C}\x{940D}\x{940E}\x{940F}\x{9410}\x{9411}\x{9412}\x{9413}\x{9414}' . '\x{9415}\x{9416}\x{9418}\x{9419}\x{941B}\x{941D}\x{9420}\x{9422}\x{9423}' . '\x{9425}\x{9426}\x{9427}\x{9428}\x{9429}\x{942A}\x{942B}\x{942C}\x{942D}' . '\x{942E}\x{942F}\x{9430}\x{9431}\x{9432}\x{9433}\x{9434}\x{9435}\x{9436}' . '\x{9437}\x{9438}\x{9439}\x{943A}\x{943B}\x{943C}\x{943D}\x{943E}\x{943F}' . '\x{9440}\x{9441}\x{9442}\x{9444}\x{9445}\x{9446}\x{9447}\x{9448}\x{9449}' . '\x{944A}\x{944B}\x{944C}\x{944D}\x{944F}\x{9450}\x{9451}\x{9452}\x{9453}' . '\x{9454}\x{9455}\x{9456}\x{9457}\x{9458}\x{9459}\x{945B}\x{945C}\x{945D}' . '\x{945E}\x{945F}\x{9460}\x{9461}\x{9462}\x{9463}\x{9464}\x{9465}\x{9466}' . '\x{9467}\x{9468}\x{9469}\x{946A}\x{946B}\x{946D}\x{946E}\x{946F}\x{9470}' . '\x{9471}\x{9472}\x{9473}\x{9474}\x{9475}\x{9476}\x{9477}\x{9478}\x{9479}' . '\x{947A}\x{947C}\x{947D}\x{947E}\x{947F}\x{9480}\x{9481}\x{9482}\x{9483}' . '\x{9484}\x{9485}\x{9486}\x{9487}\x{9488}\x{9489}\x{948A}\x{948B}\x{948C}' . '\x{948D}\x{948E}\x{948F}\x{9490}\x{9491}\x{9492}\x{9493}\x{9494}\x{9495}' . '\x{9496}\x{9497}\x{9498}\x{9499}\x{949A}\x{949B}\x{949C}\x{949D}\x{949E}' . '\x{949F}\x{94A0}\x{94A1}\x{94A2}\x{94A3}\x{94A4}\x{94A5}\x{94A6}\x{94A7}' . '\x{94A8}\x{94A9}\x{94AA}\x{94AB}\x{94AC}\x{94AD}\x{94AE}\x{94AF}\x{94B0}' . '\x{94B1}\x{94B2}\x{94B3}\x{94B4}\x{94B5}\x{94B6}\x{94B7}\x{94B8}\x{94B9}' . '\x{94BA}\x{94BB}\x{94BC}\x{94BD}\x{94BE}\x{94BF}\x{94C0}\x{94C1}\x{94C2}' . '\x{94C3}\x{94C4}\x{94C5}\x{94C6}\x{94C7}\x{94C8}\x{94C9}\x{94CA}\x{94CB}' . '\x{94CC}\x{94CD}\x{94CE}\x{94CF}\x{94D0}\x{94D1}\x{94D2}\x{94D3}\x{94D4}' . '\x{94D5}\x{94D6}\x{94D7}\x{94D8}\x{94D9}\x{94DA}\x{94DB}\x{94DC}\x{94DD}' . '\x{94DE}\x{94DF}\x{94E0}\x{94E1}\x{94E2}\x{94E3}\x{94E4}\x{94E5}\x{94E6}' . '\x{94E7}\x{94E8}\x{94E9}\x{94EA}\x{94EB}\x{94EC}\x{94ED}\x{94EE}\x{94EF}' . '\x{94F0}\x{94F1}\x{94F2}\x{94F3}\x{94F4}\x{94F5}\x{94F6}\x{94F7}\x{94F8}' . '\x{94F9}\x{94FA}\x{94FB}\x{94FC}\x{94FD}\x{94FE}\x{94FF}\x{9500}\x{9501}' . '\x{9502}\x{9503}\x{9504}\x{9505}\x{9506}\x{9507}\x{9508}\x{9509}\x{950A}' . '\x{950B}\x{950C}\x{950D}\x{950E}\x{950F}\x{9510}\x{9511}\x{9512}\x{9513}' . '\x{9514}\x{9515}\x{9516}\x{9517}\x{9518}\x{9519}\x{951A}\x{951B}\x{951C}' . '\x{951D}\x{951E}\x{951F}\x{9520}\x{9521}\x{9522}\x{9523}\x{9524}\x{9525}' . '\x{9526}\x{9527}\x{9528}\x{9529}\x{952A}\x{952B}\x{952C}\x{952D}\x{952E}' . '\x{952F}\x{9530}\x{9531}\x{9532}\x{9533}\x{9534}\x{9535}\x{9536}\x{9537}' . '\x{9538}\x{9539}\x{953A}\x{953B}\x{953C}\x{953D}\x{953E}\x{953F}\x{9540}' . '\x{9541}\x{9542}\x{9543}\x{9544}\x{9545}\x{9546}\x{9547}\x{9548}\x{9549}' . '\x{954A}\x{954B}\x{954C}\x{954D}\x{954E}\x{954F}\x{9550}\x{9551}\x{9552}' . '\x{9553}\x{9554}\x{9555}\x{9556}\x{9557}\x{9558}\x{9559}\x{955A}\x{955B}' . '\x{955C}\x{955D}\x{955E}\x{955F}\x{9560}\x{9561}\x{9562}\x{9563}\x{9564}' . '\x{9565}\x{9566}\x{9567}\x{9568}\x{9569}\x{956A}\x{956B}\x{956C}\x{956D}' . '\x{956E}\x{956F}\x{9570}\x{9571}\x{9572}\x{9573}\x{9574}\x{9575}\x{9576}' . '\x{9577}\x{957A}\x{957B}\x{957C}\x{957D}\x{957F}\x{9580}\x{9581}\x{9582}' . '\x{9583}\x{9584}\x{9586}\x{9587}\x{9588}\x{9589}\x{958A}\x{958B}\x{958C}' . '\x{958D}\x{958E}\x{958F}\x{9590}\x{9591}\x{9592}\x{9593}\x{9594}\x{9595}' . '\x{9596}\x{9598}\x{9599}\x{959A}\x{959B}\x{959C}\x{959D}\x{959E}\x{959F}' . '\x{95A1}\x{95A2}\x{95A3}\x{95A4}\x{95A5}\x{95A6}\x{95A7}\x{95A8}\x{95A9}' . '\x{95AA}\x{95AB}\x{95AC}\x{95AD}\x{95AE}\x{95AF}\x{95B0}\x{95B1}\x{95B2}' . '\x{95B5}\x{95B6}\x{95B7}\x{95B9}\x{95BA}\x{95BB}\x{95BC}\x{95BD}\x{95BE}' . '\x{95BF}\x{95C0}\x{95C2}\x{95C3}\x{95C4}\x{95C5}\x{95C6}\x{95C7}\x{95C8}' . '\x{95C9}\x{95CA}\x{95CB}\x{95CC}\x{95CD}\x{95CE}\x{95CF}\x{95D0}\x{95D1}' . '\x{95D2}\x{95D3}\x{95D4}\x{95D5}\x{95D6}\x{95D7}\x{95D8}\x{95DA}\x{95DB}' . '\x{95DC}\x{95DE}\x{95DF}\x{95E0}\x{95E1}\x{95E2}\x{95E3}\x{95E4}\x{95E5}' . '\x{95E6}\x{95E7}\x{95E8}\x{95E9}\x{95EA}\x{95EB}\x{95EC}\x{95ED}\x{95EE}' . '\x{95EF}\x{95F0}\x{95F1}\x{95F2}\x{95F3}\x{95F4}\x{95F5}\x{95F6}\x{95F7}' . '\x{95F8}\x{95F9}\x{95FA}\x{95FB}\x{95FC}\x{95FD}\x{95FE}\x{95FF}\x{9600}' . '\x{9601}\x{9602}\x{9603}\x{9604}\x{9605}\x{9606}\x{9607}\x{9608}\x{9609}' . '\x{960A}\x{960B}\x{960C}\x{960D}\x{960E}\x{960F}\x{9610}\x{9611}\x{9612}' . '\x{9613}\x{9614}\x{9615}\x{9616}\x{9617}\x{9618}\x{9619}\x{961A}\x{961B}' . '\x{961C}\x{961D}\x{961E}\x{961F}\x{9620}\x{9621}\x{9622}\x{9623}\x{9624}' . '\x{9627}\x{9628}\x{962A}\x{962B}\x{962C}\x{962D}\x{962E}\x{962F}\x{9630}' . '\x{9631}\x{9632}\x{9633}\x{9634}\x{9635}\x{9636}\x{9637}\x{9638}\x{9639}' . '\x{963A}\x{963B}\x{963C}\x{963D}\x{963F}\x{9640}\x{9641}\x{9642}\x{9643}' . '\x{9644}\x{9645}\x{9646}\x{9647}\x{9648}\x{9649}\x{964A}\x{964B}\x{964C}' . '\x{964D}\x{964E}\x{964F}\x{9650}\x{9651}\x{9652}\x{9653}\x{9654}\x{9655}' . '\x{9658}\x{9659}\x{965A}\x{965B}\x{965C}\x{965D}\x{965E}\x{965F}\x{9660}' . '\x{9661}\x{9662}\x{9663}\x{9664}\x{9666}\x{9667}\x{9668}\x{9669}\x{966A}' . '\x{966B}\x{966C}\x{966D}\x{966E}\x{966F}\x{9670}\x{9671}\x{9672}\x{9673}' . '\x{9674}\x{9675}\x{9676}\x{9677}\x{9678}\x{967C}\x{967D}\x{967E}\x{9680}' . '\x{9683}\x{9684}\x{9685}\x{9686}\x{9687}\x{9688}\x{9689}\x{968A}\x{968B}' . '\x{968D}\x{968E}\x{968F}\x{9690}\x{9691}\x{9692}\x{9693}\x{9694}\x{9695}' . '\x{9697}\x{9698}\x{9699}\x{969B}\x{969C}\x{969E}\x{96A0}\x{96A1}\x{96A2}' . '\x{96A3}\x{96A4}\x{96A5}\x{96A6}\x{96A7}\x{96A8}\x{96A9}\x{96AA}\x{96AC}' . '\x{96AD}\x{96AE}\x{96B0}\x{96B1}\x{96B3}\x{96B4}\x{96B6}\x{96B7}\x{96B8}' . '\x{96B9}\x{96BA}\x{96BB}\x{96BC}\x{96BD}\x{96BE}\x{96BF}\x{96C0}\x{96C1}' . '\x{96C2}\x{96C3}\x{96C4}\x{96C5}\x{96C6}\x{96C7}\x{96C8}\x{96C9}\x{96CA}' . '\x{96CB}\x{96CC}\x{96CD}\x{96CE}\x{96CF}\x{96D0}\x{96D1}\x{96D2}\x{96D3}' . '\x{96D4}\x{96D5}\x{96D6}\x{96D7}\x{96D8}\x{96D9}\x{96DA}\x{96DB}\x{96DC}' . '\x{96DD}\x{96DE}\x{96DF}\x{96E0}\x{96E1}\x{96E2}\x{96E3}\x{96E5}\x{96E8}' . '\x{96E9}\x{96EA}\x{96EB}\x{96EC}\x{96ED}\x{96EE}\x{96EF}\x{96F0}\x{96F1}' . '\x{96F2}\x{96F3}\x{96F4}\x{96F5}\x{96F6}\x{96F7}\x{96F8}\x{96F9}\x{96FA}' . '\x{96FB}\x{96FD}\x{96FE}\x{96FF}\x{9700}\x{9701}\x{9702}\x{9703}\x{9704}' . '\x{9705}\x{9706}\x{9707}\x{9708}\x{9709}\x{970A}\x{970B}\x{970C}\x{970D}' . '\x{970E}\x{970F}\x{9710}\x{9711}\x{9712}\x{9713}\x{9715}\x{9716}\x{9718}' . '\x{9719}\x{971C}\x{971D}\x{971E}\x{971F}\x{9720}\x{9721}\x{9722}\x{9723}' . '\x{9724}\x{9725}\x{9726}\x{9727}\x{9728}\x{9729}\x{972A}\x{972B}\x{972C}' . '\x{972D}\x{972E}\x{972F}\x{9730}\x{9731}\x{9732}\x{9735}\x{9736}\x{9738}' . '\x{9739}\x{973A}\x{973B}\x{973C}\x{973D}\x{973E}\x{973F}\x{9742}\x{9743}' . '\x{9744}\x{9745}\x{9746}\x{9747}\x{9748}\x{9749}\x{974A}\x{974B}\x{974C}' . '\x{974E}\x{974F}\x{9750}\x{9751}\x{9752}\x{9753}\x{9754}\x{9755}\x{9756}' . '\x{9758}\x{9759}\x{975A}\x{975B}\x{975C}\x{975D}\x{975E}\x{975F}\x{9760}' . '\x{9761}\x{9762}\x{9765}\x{9766}\x{9767}\x{9768}\x{9769}\x{976A}\x{976B}' . '\x{976C}\x{976D}\x{976E}\x{976F}\x{9770}\x{9772}\x{9773}\x{9774}\x{9776}' . '\x{9777}\x{9778}\x{9779}\x{977A}\x{977B}\x{977C}\x{977D}\x{977E}\x{977F}' . '\x{9780}\x{9781}\x{9782}\x{9783}\x{9784}\x{9785}\x{9786}\x{9788}\x{978A}' . '\x{978B}\x{978C}\x{978D}\x{978E}\x{978F}\x{9790}\x{9791}\x{9792}\x{9793}' . '\x{9794}\x{9795}\x{9796}\x{9797}\x{9798}\x{9799}\x{979A}\x{979C}\x{979D}' . '\x{979E}\x{979F}\x{97A0}\x{97A1}\x{97A2}\x{97A3}\x{97A4}\x{97A5}\x{97A6}' . '\x{97A7}\x{97A8}\x{97AA}\x{97AB}\x{97AC}\x{97AD}\x{97AE}\x{97AF}\x{97B2}' . '\x{97B3}\x{97B4}\x{97B6}\x{97B7}\x{97B8}\x{97B9}\x{97BA}\x{97BB}\x{97BC}' . '\x{97BD}\x{97BF}\x{97C1}\x{97C2}\x{97C3}\x{97C4}\x{97C5}\x{97C6}\x{97C7}' . '\x{97C8}\x{97C9}\x{97CA}\x{97CB}\x{97CC}\x{97CD}\x{97CE}\x{97CF}\x{97D0}' . '\x{97D1}\x{97D3}\x{97D4}\x{97D5}\x{97D6}\x{97D7}\x{97D8}\x{97D9}\x{97DA}' . '\x{97DB}\x{97DC}\x{97DD}\x{97DE}\x{97DF}\x{97E0}\x{97E1}\x{97E2}\x{97E3}' . '\x{97E4}\x{97E5}\x{97E6}\x{97E7}\x{97E8}\x{97E9}\x{97EA}\x{97EB}\x{97EC}' . '\x{97ED}\x{97EE}\x{97EF}\x{97F0}\x{97F1}\x{97F2}\x{97F3}\x{97F4}\x{97F5}' . '\x{97F6}\x{97F7}\x{97F8}\x{97F9}\x{97FA}\x{97FB}\x{97FD}\x{97FE}\x{97FF}' . '\x{9800}\x{9801}\x{9802}\x{9803}\x{9804}\x{9805}\x{9806}\x{9807}\x{9808}' . '\x{9809}\x{980A}\x{980B}\x{980C}\x{980D}\x{980E}\x{980F}\x{9810}\x{9811}' . '\x{9812}\x{9813}\x{9814}\x{9815}\x{9816}\x{9817}\x{9818}\x{9819}\x{981A}' . '\x{981B}\x{981C}\x{981D}\x{981E}\x{9820}\x{9821}\x{9822}\x{9823}\x{9824}' . '\x{9826}\x{9827}\x{9828}\x{9829}\x{982B}\x{982D}\x{982E}\x{982F}\x{9830}' . '\x{9831}\x{9832}\x{9834}\x{9835}\x{9836}\x{9837}\x{9838}\x{9839}\x{983B}' . '\x{983C}\x{983D}\x{983F}\x{9840}\x{9841}\x{9843}\x{9844}\x{9845}\x{9846}' . '\x{9848}\x{9849}\x{984A}\x{984C}\x{984D}\x{984E}\x{984F}\x{9850}\x{9851}' . '\x{9852}\x{9853}\x{9854}\x{9855}\x{9857}\x{9858}\x{9859}\x{985A}\x{985B}' . '\x{985C}\x{985D}\x{985E}\x{985F}\x{9860}\x{9861}\x{9862}\x{9863}\x{9864}' . '\x{9865}\x{9867}\x{9869}\x{986A}\x{986B}\x{986C}\x{986D}\x{986E}\x{986F}' . '\x{9870}\x{9871}\x{9872}\x{9873}\x{9874}\x{9875}\x{9876}\x{9877}\x{9878}' . '\x{9879}\x{987A}\x{987B}\x{987C}\x{987D}\x{987E}\x{987F}\x{9880}\x{9881}' . '\x{9882}\x{9883}\x{9884}\x{9885}\x{9886}\x{9887}\x{9888}\x{9889}\x{988A}' . '\x{988B}\x{988C}\x{988D}\x{988E}\x{988F}\x{9890}\x{9891}\x{9892}\x{9893}' . '\x{9894}\x{9895}\x{9896}\x{9897}\x{9898}\x{9899}\x{989A}\x{989B}\x{989C}' . '\x{989D}\x{989E}\x{989F}\x{98A0}\x{98A1}\x{98A2}\x{98A3}\x{98A4}\x{98A5}' . '\x{98A6}\x{98A7}\x{98A8}\x{98A9}\x{98AA}\x{98AB}\x{98AC}\x{98AD}\x{98AE}' . '\x{98AF}\x{98B0}\x{98B1}\x{98B2}\x{98B3}\x{98B4}\x{98B5}\x{98B6}\x{98B8}' . '\x{98B9}\x{98BA}\x{98BB}\x{98BC}\x{98BD}\x{98BE}\x{98BF}\x{98C0}\x{98C1}' . '\x{98C2}\x{98C3}\x{98C4}\x{98C5}\x{98C6}\x{98C8}\x{98C9}\x{98CB}\x{98CC}' . '\x{98CD}\x{98CE}\x{98CF}\x{98D0}\x{98D1}\x{98D2}\x{98D3}\x{98D4}\x{98D5}' . '\x{98D6}\x{98D7}\x{98D8}\x{98D9}\x{98DA}\x{98DB}\x{98DC}\x{98DD}\x{98DE}' . '\x{98DF}\x{98E0}\x{98E2}\x{98E3}\x{98E5}\x{98E6}\x{98E7}\x{98E8}\x{98E9}' . '\x{98EA}\x{98EB}\x{98ED}\x{98EF}\x{98F0}\x{98F2}\x{98F3}\x{98F4}\x{98F5}' . '\x{98F6}\x{98F7}\x{98F9}\x{98FA}\x{98FC}\x{98FD}\x{98FE}\x{98FF}\x{9900}' . '\x{9901}\x{9902}\x{9903}\x{9904}\x{9905}\x{9906}\x{9907}\x{9908}\x{9909}' . '\x{990A}\x{990B}\x{990C}\x{990D}\x{990E}\x{990F}\x{9910}\x{9911}\x{9912}' . '\x{9913}\x{9914}\x{9915}\x{9916}\x{9917}\x{9918}\x{991A}\x{991B}\x{991C}' . '\x{991D}\x{991E}\x{991F}\x{9920}\x{9921}\x{9922}\x{9923}\x{9924}\x{9925}' . '\x{9926}\x{9927}\x{9928}\x{9929}\x{992A}\x{992B}\x{992C}\x{992D}\x{992E}' . '\x{992F}\x{9930}\x{9931}\x{9932}\x{9933}\x{9934}\x{9935}\x{9936}\x{9937}' . '\x{9938}\x{9939}\x{993A}\x{993C}\x{993D}\x{993E}\x{993F}\x{9940}\x{9941}' . '\x{9942}\x{9943}\x{9945}\x{9946}\x{9947}\x{9948}\x{9949}\x{994A}\x{994B}' . '\x{994C}\x{994E}\x{994F}\x{9950}\x{9951}\x{9952}\x{9953}\x{9954}\x{9955}' . '\x{9956}\x{9957}\x{9958}\x{9959}\x{995B}\x{995C}\x{995E}\x{995F}\x{9960}' . '\x{9961}\x{9962}\x{9963}\x{9964}\x{9965}\x{9966}\x{9967}\x{9968}\x{9969}' . '\x{996A}\x{996B}\x{996C}\x{996D}\x{996E}\x{996F}\x{9970}\x{9971}\x{9972}' . '\x{9973}\x{9974}\x{9975}\x{9976}\x{9977}\x{9978}\x{9979}\x{997A}\x{997B}' . '\x{997C}\x{997D}\x{997E}\x{997F}\x{9980}\x{9981}\x{9982}\x{9983}\x{9984}' . '\x{9985}\x{9986}\x{9987}\x{9988}\x{9989}\x{998A}\x{998B}\x{998C}\x{998D}' . '\x{998E}\x{998F}\x{9990}\x{9991}\x{9992}\x{9993}\x{9994}\x{9995}\x{9996}' . '\x{9997}\x{9998}\x{9999}\x{999A}\x{999B}\x{999C}\x{999D}\x{999E}\x{999F}' . '\x{99A0}\x{99A1}\x{99A2}\x{99A3}\x{99A4}\x{99A5}\x{99A6}\x{99A7}\x{99A8}' . '\x{99A9}\x{99AA}\x{99AB}\x{99AC}\x{99AD}\x{99AE}\x{99AF}\x{99B0}\x{99B1}' . '\x{99B2}\x{99B3}\x{99B4}\x{99B5}\x{99B6}\x{99B7}\x{99B8}\x{99B9}\x{99BA}' . '\x{99BB}\x{99BC}\x{99BD}\x{99BE}\x{99C0}\x{99C1}\x{99C2}\x{99C3}\x{99C4}' . '\x{99C6}\x{99C7}\x{99C8}\x{99C9}\x{99CA}\x{99CB}\x{99CC}\x{99CD}\x{99CE}' . '\x{99CF}\x{99D0}\x{99D1}\x{99D2}\x{99D3}\x{99D4}\x{99D5}\x{99D6}\x{99D7}' . '\x{99D8}\x{99D9}\x{99DA}\x{99DB}\x{99DC}\x{99DD}\x{99DE}\x{99DF}\x{99E1}' . '\x{99E2}\x{99E3}\x{99E4}\x{99E5}\x{99E7}\x{99E8}\x{99E9}\x{99EA}\x{99EC}' . '\x{99ED}\x{99EE}\x{99EF}\x{99F0}\x{99F1}\x{99F2}\x{99F3}\x{99F4}\x{99F6}' . '\x{99F7}\x{99F8}\x{99F9}\x{99FA}\x{99FB}\x{99FC}\x{99FD}\x{99FE}\x{99FF}' . '\x{9A00}\x{9A01}\x{9A02}\x{9A03}\x{9A04}\x{9A05}\x{9A06}\x{9A07}\x{9A08}' . '\x{9A09}\x{9A0A}\x{9A0B}\x{9A0C}\x{9A0D}\x{9A0E}\x{9A0F}\x{9A11}\x{9A14}' . '\x{9A15}\x{9A16}\x{9A19}\x{9A1A}\x{9A1B}\x{9A1C}\x{9A1D}\x{9A1E}\x{9A1F}' . '\x{9A20}\x{9A21}\x{9A22}\x{9A23}\x{9A24}\x{9A25}\x{9A26}\x{9A27}\x{9A29}' . '\x{9A2A}\x{9A2B}\x{9A2C}\x{9A2D}\x{9A2E}\x{9A2F}\x{9A30}\x{9A31}\x{9A32}' . '\x{9A33}\x{9A34}\x{9A35}\x{9A36}\x{9A37}\x{9A38}\x{9A39}\x{9A3A}\x{9A3C}' . '\x{9A3D}\x{9A3E}\x{9A3F}\x{9A40}\x{9A41}\x{9A42}\x{9A43}\x{9A44}\x{9A45}' . '\x{9A46}\x{9A47}\x{9A48}\x{9A49}\x{9A4A}\x{9A4B}\x{9A4C}\x{9A4D}\x{9A4E}' . '\x{9A4F}\x{9A50}\x{9A52}\x{9A53}\x{9A54}\x{9A55}\x{9A56}\x{9A57}\x{9A59}' . '\x{9A5A}\x{9A5B}\x{9A5C}\x{9A5E}\x{9A5F}\x{9A60}\x{9A61}\x{9A62}\x{9A64}' . '\x{9A65}\x{9A66}\x{9A67}\x{9A68}\x{9A69}\x{9A6A}\x{9A6B}\x{9A6C}\x{9A6D}' . '\x{9A6E}\x{9A6F}\x{9A70}\x{9A71}\x{9A72}\x{9A73}\x{9A74}\x{9A75}\x{9A76}' . '\x{9A77}\x{9A78}\x{9A79}\x{9A7A}\x{9A7B}\x{9A7C}\x{9A7D}\x{9A7E}\x{9A7F}' . '\x{9A80}\x{9A81}\x{9A82}\x{9A83}\x{9A84}\x{9A85}\x{9A86}\x{9A87}\x{9A88}' . '\x{9A89}\x{9A8A}\x{9A8B}\x{9A8C}\x{9A8D}\x{9A8E}\x{9A8F}\x{9A90}\x{9A91}' . '\x{9A92}\x{9A93}\x{9A94}\x{9A95}\x{9A96}\x{9A97}\x{9A98}\x{9A99}\x{9A9A}' . '\x{9A9B}\x{9A9C}\x{9A9D}\x{9A9E}\x{9A9F}\x{9AA0}\x{9AA1}\x{9AA2}\x{9AA3}' . '\x{9AA4}\x{9AA5}\x{9AA6}\x{9AA7}\x{9AA8}\x{9AAA}\x{9AAB}\x{9AAC}\x{9AAD}' . '\x{9AAE}\x{9AAF}\x{9AB0}\x{9AB1}\x{9AB2}\x{9AB3}\x{9AB4}\x{9AB5}\x{9AB6}' . '\x{9AB7}\x{9AB8}\x{9AB9}\x{9ABA}\x{9ABB}\x{9ABC}\x{9ABE}\x{9ABF}\x{9AC0}' . '\x{9AC1}\x{9AC2}\x{9AC3}\x{9AC4}\x{9AC5}\x{9AC6}\x{9AC7}\x{9AC9}\x{9ACA}' . '\x{9ACB}\x{9ACC}\x{9ACD}\x{9ACE}\x{9ACF}\x{9AD0}\x{9AD1}\x{9AD2}\x{9AD3}' . '\x{9AD4}\x{9AD5}\x{9AD6}\x{9AD8}\x{9AD9}\x{9ADA}\x{9ADB}\x{9ADC}\x{9ADD}' . '\x{9ADE}\x{9ADF}\x{9AE1}\x{9AE2}\x{9AE3}\x{9AE5}\x{9AE6}\x{9AE7}\x{9AEA}' . '\x{9AEB}\x{9AEC}\x{9AED}\x{9AEE}\x{9AEF}\x{9AF1}\x{9AF2}\x{9AF3}\x{9AF4}' . '\x{9AF5}\x{9AF6}\x{9AF7}\x{9AF8}\x{9AF9}\x{9AFA}\x{9AFB}\x{9AFC}\x{9AFD}' . '\x{9AFE}\x{9AFF}\x{9B01}\x{9B03}\x{9B04}\x{9B05}\x{9B06}\x{9B07}\x{9B08}' . '\x{9B0A}\x{9B0B}\x{9B0C}\x{9B0D}\x{9B0E}\x{9B0F}\x{9B10}\x{9B11}\x{9B12}' . '\x{9B13}\x{9B15}\x{9B16}\x{9B17}\x{9B18}\x{9B19}\x{9B1A}\x{9B1C}\x{9B1D}' . '\x{9B1E}\x{9B1F}\x{9B20}\x{9B21}\x{9B22}\x{9B23}\x{9B24}\x{9B25}\x{9B26}' . '\x{9B27}\x{9B28}\x{9B29}\x{9B2A}\x{9B2B}\x{9B2C}\x{9B2D}\x{9B2E}\x{9B2F}' . '\x{9B30}\x{9B31}\x{9B32}\x{9B33}\x{9B35}\x{9B36}\x{9B37}\x{9B38}\x{9B39}' . '\x{9B3A}\x{9B3B}\x{9B3C}\x{9B3E}\x{9B3F}\x{9B41}\x{9B42}\x{9B43}\x{9B44}' . '\x{9B45}\x{9B46}\x{9B47}\x{9B48}\x{9B49}\x{9B4A}\x{9B4B}\x{9B4C}\x{9B4D}' . '\x{9B4E}\x{9B4F}\x{9B51}\x{9B52}\x{9B53}\x{9B54}\x{9B55}\x{9B56}\x{9B58}' . '\x{9B59}\x{9B5A}\x{9B5B}\x{9B5C}\x{9B5D}\x{9B5E}\x{9B5F}\x{9B60}\x{9B61}' . '\x{9B63}\x{9B64}\x{9B65}\x{9B66}\x{9B67}\x{9B68}\x{9B69}\x{9B6A}\x{9B6B}' . '\x{9B6C}\x{9B6D}\x{9B6E}\x{9B6F}\x{9B70}\x{9B71}\x{9B73}\x{9B74}\x{9B75}' . '\x{9B76}\x{9B77}\x{9B78}\x{9B79}\x{9B7A}\x{9B7B}\x{9B7C}\x{9B7D}\x{9B7E}' . '\x{9B7F}\x{9B80}\x{9B81}\x{9B82}\x{9B83}\x{9B84}\x{9B85}\x{9B86}\x{9B87}' . '\x{9B88}\x{9B8A}\x{9B8B}\x{9B8D}\x{9B8E}\x{9B8F}\x{9B90}\x{9B91}\x{9B92}' . '\x{9B93}\x{9B94}\x{9B95}\x{9B96}\x{9B97}\x{9B98}\x{9B9A}\x{9B9B}\x{9B9C}' . '\x{9B9D}\x{9B9E}\x{9B9F}\x{9BA0}\x{9BA1}\x{9BA2}\x{9BA3}\x{9BA4}\x{9BA5}' . '\x{9BA6}\x{9BA7}\x{9BA8}\x{9BA9}\x{9BAA}\x{9BAB}\x{9BAC}\x{9BAD}\x{9BAE}' . '\x{9BAF}\x{9BB0}\x{9BB1}\x{9BB2}\x{9BB3}\x{9BB4}\x{9BB5}\x{9BB6}\x{9BB7}' . '\x{9BB8}\x{9BB9}\x{9BBA}\x{9BBB}\x{9BBC}\x{9BBD}\x{9BBE}\x{9BBF}\x{9BC0}' . '\x{9BC1}\x{9BC3}\x{9BC4}\x{9BC5}\x{9BC6}\x{9BC7}\x{9BC8}\x{9BC9}\x{9BCA}' . '\x{9BCB}\x{9BCC}\x{9BCD}\x{9BCE}\x{9BCF}\x{9BD0}\x{9BD1}\x{9BD2}\x{9BD3}' . '\x{9BD4}\x{9BD5}\x{9BD6}\x{9BD7}\x{9BD8}\x{9BD9}\x{9BDA}\x{9BDB}\x{9BDC}' . '\x{9BDD}\x{9BDE}\x{9BDF}\x{9BE0}\x{9BE1}\x{9BE2}\x{9BE3}\x{9BE4}\x{9BE5}' . '\x{9BE6}\x{9BE7}\x{9BE8}\x{9BE9}\x{9BEA}\x{9BEB}\x{9BEC}\x{9BED}\x{9BEE}' . '\x{9BEF}\x{9BF0}\x{9BF1}\x{9BF2}\x{9BF3}\x{9BF4}\x{9BF5}\x{9BF7}\x{9BF8}' . '\x{9BF9}\x{9BFA}\x{9BFB}\x{9BFC}\x{9BFD}\x{9BFE}\x{9BFF}\x{9C02}\x{9C05}' . '\x{9C06}\x{9C07}\x{9C08}\x{9C09}\x{9C0A}\x{9C0B}\x{9C0C}\x{9C0D}\x{9C0E}' . '\x{9C0F}\x{9C10}\x{9C11}\x{9C12}\x{9C13}\x{9C14}\x{9C15}\x{9C16}\x{9C17}' . '\x{9C18}\x{9C19}\x{9C1A}\x{9C1B}\x{9C1C}\x{9C1D}\x{9C1E}\x{9C1F}\x{9C20}' . '\x{9C21}\x{9C22}\x{9C23}\x{9C24}\x{9C25}\x{9C26}\x{9C27}\x{9C28}\x{9C29}' . '\x{9C2A}\x{9C2B}\x{9C2C}\x{9C2D}\x{9C2F}\x{9C30}\x{9C31}\x{9C32}\x{9C33}' . '\x{9C34}\x{9C35}\x{9C36}\x{9C37}\x{9C38}\x{9C39}\x{9C3A}\x{9C3B}\x{9C3C}' . '\x{9C3D}\x{9C3E}\x{9C3F}\x{9C40}\x{9C41}\x{9C43}\x{9C44}\x{9C45}\x{9C46}' . '\x{9C47}\x{9C48}\x{9C49}\x{9C4A}\x{9C4B}\x{9C4C}\x{9C4D}\x{9C4E}\x{9C50}' . '\x{9C52}\x{9C53}\x{9C54}\x{9C55}\x{9C56}\x{9C57}\x{9C58}\x{9C59}\x{9C5A}' . '\x{9C5B}\x{9C5C}\x{9C5D}\x{9C5E}\x{9C5F}\x{9C60}\x{9C62}\x{9C63}\x{9C65}' . '\x{9C66}\x{9C67}\x{9C68}\x{9C69}\x{9C6A}\x{9C6B}\x{9C6C}\x{9C6D}\x{9C6E}' . '\x{9C6F}\x{9C70}\x{9C71}\x{9C72}\x{9C73}\x{9C74}\x{9C75}\x{9C77}\x{9C78}' . '\x{9C79}\x{9C7A}\x{9C7C}\x{9C7D}\x{9C7E}\x{9C7F}\x{9C80}\x{9C81}\x{9C82}' . '\x{9C83}\x{9C84}\x{9C85}\x{9C86}\x{9C87}\x{9C88}\x{9C89}\x{9C8A}\x{9C8B}' . '\x{9C8C}\x{9C8D}\x{9C8E}\x{9C8F}\x{9C90}\x{9C91}\x{9C92}\x{9C93}\x{9C94}' . '\x{9C95}\x{9C96}\x{9C97}\x{9C98}\x{9C99}\x{9C9A}\x{9C9B}\x{9C9C}\x{9C9D}' . '\x{9C9E}\x{9C9F}\x{9CA0}\x{9CA1}\x{9CA2}\x{9CA3}\x{9CA4}\x{9CA5}\x{9CA6}' . '\x{9CA7}\x{9CA8}\x{9CA9}\x{9CAA}\x{9CAB}\x{9CAC}\x{9CAD}\x{9CAE}\x{9CAF}' . '\x{9CB0}\x{9CB1}\x{9CB2}\x{9CB3}\x{9CB4}\x{9CB5}\x{9CB6}\x{9CB7}\x{9CB8}' . '\x{9CB9}\x{9CBA}\x{9CBB}\x{9CBC}\x{9CBD}\x{9CBE}\x{9CBF}\x{9CC0}\x{9CC1}' . '\x{9CC2}\x{9CC3}\x{9CC4}\x{9CC5}\x{9CC6}\x{9CC7}\x{9CC8}\x{9CC9}\x{9CCA}' . '\x{9CCB}\x{9CCC}\x{9CCD}\x{9CCE}\x{9CCF}\x{9CD0}\x{9CD1}\x{9CD2}\x{9CD3}' . '\x{9CD4}\x{9CD5}\x{9CD6}\x{9CD7}\x{9CD8}\x{9CD9}\x{9CDA}\x{9CDB}\x{9CDC}' . '\x{9CDD}\x{9CDE}\x{9CDF}\x{9CE0}\x{9CE1}\x{9CE2}\x{9CE3}\x{9CE4}\x{9CE5}' . '\x{9CE6}\x{9CE7}\x{9CE8}\x{9CE9}\x{9CEA}\x{9CEB}\x{9CEC}\x{9CED}\x{9CEE}' . '\x{9CEF}\x{9CF0}\x{9CF1}\x{9CF2}\x{9CF3}\x{9CF4}\x{9CF5}\x{9CF6}\x{9CF7}' . '\x{9CF8}\x{9CF9}\x{9CFA}\x{9CFB}\x{9CFC}\x{9CFD}\x{9CFE}\x{9CFF}\x{9D00}' . '\x{9D01}\x{9D02}\x{9D03}\x{9D04}\x{9D05}\x{9D06}\x{9D07}\x{9D08}\x{9D09}' . '\x{9D0A}\x{9D0B}\x{9D0F}\x{9D10}\x{9D12}\x{9D13}\x{9D14}\x{9D15}\x{9D16}' . '\x{9D17}\x{9D18}\x{9D19}\x{9D1A}\x{9D1B}\x{9D1C}\x{9D1D}\x{9D1E}\x{9D1F}' . '\x{9D20}\x{9D21}\x{9D22}\x{9D23}\x{9D24}\x{9D25}\x{9D26}\x{9D28}\x{9D29}' . '\x{9D2B}\x{9D2D}\x{9D2E}\x{9D2F}\x{9D30}\x{9D31}\x{9D32}\x{9D33}\x{9D34}' . '\x{9D36}\x{9D37}\x{9D38}\x{9D39}\x{9D3A}\x{9D3B}\x{9D3D}\x{9D3E}\x{9D3F}' . '\x{9D40}\x{9D41}\x{9D42}\x{9D43}\x{9D45}\x{9D46}\x{9D47}\x{9D48}\x{9D49}' . '\x{9D4A}\x{9D4B}\x{9D4C}\x{9D4D}\x{9D4E}\x{9D4F}\x{9D50}\x{9D51}\x{9D52}' . '\x{9D53}\x{9D54}\x{9D55}\x{9D56}\x{9D57}\x{9D58}\x{9D59}\x{9D5A}\x{9D5B}' . '\x{9D5C}\x{9D5D}\x{9D5E}\x{9D5F}\x{9D60}\x{9D61}\x{9D62}\x{9D63}\x{9D64}' . '\x{9D65}\x{9D66}\x{9D67}\x{9D68}\x{9D69}\x{9D6A}\x{9D6B}\x{9D6C}\x{9D6E}' . '\x{9D6F}\x{9D70}\x{9D71}\x{9D72}\x{9D73}\x{9D74}\x{9D75}\x{9D76}\x{9D77}' . '\x{9D78}\x{9D79}\x{9D7A}\x{9D7B}\x{9D7C}\x{9D7D}\x{9D7E}\x{9D7F}\x{9D80}' . '\x{9D81}\x{9D82}\x{9D83}\x{9D84}\x{9D85}\x{9D86}\x{9D87}\x{9D88}\x{9D89}' . '\x{9D8A}\x{9D8B}\x{9D8C}\x{9D8D}\x{9D8E}\x{9D90}\x{9D91}\x{9D92}\x{9D93}' . '\x{9D94}\x{9D96}\x{9D97}\x{9D98}\x{9D99}\x{9D9A}\x{9D9B}\x{9D9C}\x{9D9D}' . '\x{9D9E}\x{9D9F}\x{9DA0}\x{9DA1}\x{9DA2}\x{9DA3}\x{9DA4}\x{9DA5}\x{9DA6}' . '\x{9DA7}\x{9DA8}\x{9DA9}\x{9DAA}\x{9DAB}\x{9DAC}\x{9DAD}\x{9DAF}\x{9DB0}' . '\x{9DB1}\x{9DB2}\x{9DB3}\x{9DB4}\x{9DB5}\x{9DB6}\x{9DB7}\x{9DB8}\x{9DB9}' . '\x{9DBA}\x{9DBB}\x{9DBC}\x{9DBE}\x{9DBF}\x{9DC1}\x{9DC2}\x{9DC3}\x{9DC4}' . '\x{9DC5}\x{9DC7}\x{9DC8}\x{9DC9}\x{9DCA}\x{9DCB}\x{9DCC}\x{9DCD}\x{9DCE}' . '\x{9DCF}\x{9DD0}\x{9DD1}\x{9DD2}\x{9DD3}\x{9DD4}\x{9DD5}\x{9DD6}\x{9DD7}' . '\x{9DD8}\x{9DD9}\x{9DDA}\x{9DDB}\x{9DDC}\x{9DDD}\x{9DDE}\x{9DDF}\x{9DE0}' . '\x{9DE1}\x{9DE2}\x{9DE3}\x{9DE4}\x{9DE5}\x{9DE6}\x{9DE7}\x{9DE8}\x{9DE9}' . '\x{9DEB}\x{9DEC}\x{9DED}\x{9DEE}\x{9DEF}\x{9DF0}\x{9DF1}\x{9DF2}\x{9DF3}' . '\x{9DF4}\x{9DF5}\x{9DF6}\x{9DF7}\x{9DF8}\x{9DF9}\x{9DFA}\x{9DFB}\x{9DFD}' . '\x{9DFE}\x{9DFF}\x{9E00}\x{9E01}\x{9E02}\x{9E03}\x{9E04}\x{9E05}\x{9E06}' . '\x{9E07}\x{9E08}\x{9E09}\x{9E0A}\x{9E0B}\x{9E0C}\x{9E0D}\x{9E0F}\x{9E10}' . '\x{9E11}\x{9E12}\x{9E13}\x{9E14}\x{9E15}\x{9E17}\x{9E18}\x{9E19}\x{9E1A}' . '\x{9E1B}\x{9E1D}\x{9E1E}\x{9E1F}\x{9E20}\x{9E21}\x{9E22}\x{9E23}\x{9E24}' . '\x{9E25}\x{9E26}\x{9E27}\x{9E28}\x{9E29}\x{9E2A}\x{9E2B}\x{9E2C}\x{9E2D}' . '\x{9E2E}\x{9E2F}\x{9E30}\x{9E31}\x{9E32}\x{9E33}\x{9E34}\x{9E35}\x{9E36}' . '\x{9E37}\x{9E38}\x{9E39}\x{9E3A}\x{9E3B}\x{9E3C}\x{9E3D}\x{9E3E}\x{9E3F}' . '\x{9E40}\x{9E41}\x{9E42}\x{9E43}\x{9E44}\x{9E45}\x{9E46}\x{9E47}\x{9E48}' . '\x{9E49}\x{9E4A}\x{9E4B}\x{9E4C}\x{9E4D}\x{9E4E}\x{9E4F}\x{9E50}\x{9E51}' . '\x{9E52}\x{9E53}\x{9E54}\x{9E55}\x{9E56}\x{9E57}\x{9E58}\x{9E59}\x{9E5A}' . '\x{9E5B}\x{9E5C}\x{9E5D}\x{9E5E}\x{9E5F}\x{9E60}\x{9E61}\x{9E62}\x{9E63}' . '\x{9E64}\x{9E65}\x{9E66}\x{9E67}\x{9E68}\x{9E69}\x{9E6A}\x{9E6B}\x{9E6C}' . '\x{9E6D}\x{9E6E}\x{9E6F}\x{9E70}\x{9E71}\x{9E72}\x{9E73}\x{9E74}\x{9E75}' . '\x{9E76}\x{9E77}\x{9E79}\x{9E7A}\x{9E7C}\x{9E7D}\x{9E7E}\x{9E7F}\x{9E80}' . '\x{9E81}\x{9E82}\x{9E83}\x{9E84}\x{9E85}\x{9E86}\x{9E87}\x{9E88}\x{9E89}' . '\x{9E8A}\x{9E8B}\x{9E8C}\x{9E8D}\x{9E8E}\x{9E91}\x{9E92}\x{9E93}\x{9E94}' . '\x{9E96}\x{9E97}\x{9E99}\x{9E9A}\x{9E9B}\x{9E9C}\x{9E9D}\x{9E9F}\x{9EA0}' . '\x{9EA1}\x{9EA3}\x{9EA4}\x{9EA5}\x{9EA6}\x{9EA7}\x{9EA8}\x{9EA9}\x{9EAA}' . '\x{9EAD}\x{9EAE}\x{9EAF}\x{9EB0}\x{9EB2}\x{9EB3}\x{9EB4}\x{9EB5}\x{9EB6}' . '\x{9EB7}\x{9EB8}\x{9EBB}\x{9EBC}\x{9EBD}\x{9EBE}\x{9EBF}\x{9EC0}\x{9EC1}' . '\x{9EC2}\x{9EC3}\x{9EC4}\x{9EC5}\x{9EC6}\x{9EC7}\x{9EC8}\x{9EC9}\x{9ECA}' . '\x{9ECB}\x{9ECC}\x{9ECD}\x{9ECE}\x{9ECF}\x{9ED0}\x{9ED1}\x{9ED2}\x{9ED3}' . '\x{9ED4}\x{9ED5}\x{9ED6}\x{9ED7}\x{9ED8}\x{9ED9}\x{9EDA}\x{9EDB}\x{9EDC}' . '\x{9EDD}\x{9EDE}\x{9EDF}\x{9EE0}\x{9EE1}\x{9EE2}\x{9EE3}\x{9EE4}\x{9EE5}' . '\x{9EE6}\x{9EE7}\x{9EE8}\x{9EE9}\x{9EEA}\x{9EEB}\x{9EED}\x{9EEE}\x{9EEF}' . '\x{9EF0}\x{9EF2}\x{9EF3}\x{9EF4}\x{9EF5}\x{9EF6}\x{9EF7}\x{9EF8}\x{9EF9}' . '\x{9EFA}\x{9EFB}\x{9EFC}\x{9EFD}\x{9EFE}\x{9EFF}\x{9F00}\x{9F01}\x{9F02}' . '\x{9F04}\x{9F05}\x{9F06}\x{9F07}\x{9F08}\x{9F09}\x{9F0A}\x{9F0B}\x{9F0C}' . '\x{9F0D}\x{9F0E}\x{9F0F}\x{9F10}\x{9F12}\x{9F13}\x{9F15}\x{9F16}\x{9F17}' . '\x{9F18}\x{9F19}\x{9F1A}\x{9F1B}\x{9F1C}\x{9F1D}\x{9F1E}\x{9F1F}\x{9F20}' . '\x{9F22}\x{9F23}\x{9F24}\x{9F25}\x{9F27}\x{9F28}\x{9F29}\x{9F2A}\x{9F2B}' . '\x{9F2C}\x{9F2D}\x{9F2E}\x{9F2F}\x{9F30}\x{9F31}\x{9F32}\x{9F33}\x{9F34}' . '\x{9F35}\x{9F36}\x{9F37}\x{9F38}\x{9F39}\x{9F3A}\x{9F3B}\x{9F3C}\x{9F3D}' . '\x{9F3E}\x{9F3F}\x{9F40}\x{9F41}\x{9F42}\x{9F43}\x{9F44}\x{9F46}\x{9F47}' . '\x{9F48}\x{9F49}\x{9F4A}\x{9F4B}\x{9F4C}\x{9F4D}\x{9F4E}\x{9F4F}\x{9F50}' . '\x{9F51}\x{9F52}\x{9F54}\x{9F55}\x{9F56}\x{9F57}\x{9F58}\x{9F59}\x{9F5A}' . '\x{9F5B}\x{9F5C}\x{9F5D}\x{9F5E}\x{9F5F}\x{9F60}\x{9F61}\x{9F63}\x{9F64}' . '\x{9F65}\x{9F66}\x{9F67}\x{9F68}\x{9F69}\x{9F6A}\x{9F6B}\x{9F6C}\x{9F6E}' . '\x{9F6F}\x{9F70}\x{9F71}\x{9F72}\x{9F73}\x{9F74}\x{9F75}\x{9F76}\x{9F77}' . '\x{9F78}\x{9F79}\x{9F7A}\x{9F7B}\x{9F7C}\x{9F7D}\x{9F7E}\x{9F7F}\x{9F80}' . '\x{9F81}\x{9F82}\x{9F83}\x{9F84}\x{9F85}\x{9F86}\x{9F87}\x{9F88}\x{9F89}' . '\x{9F8A}\x{9F8B}\x{9F8C}\x{9F8D}\x{9F8E}\x{9F8F}\x{9F90}\x{9F91}\x{9F92}' . '\x{9F93}\x{9F94}\x{9F95}\x{9F96}\x{9F97}\x{9F98}\x{9F99}\x{9F9A}\x{9F9B}' . '\x{9F9C}\x{9F9D}\x{9F9E}\x{9F9F}\x{9FA0}\x{9FA2}\x{9FA4}\x{9FA5}]{1,20}$/iu', ]; ================================================ FILE: src/Hostname/Cn.php ================================================ '/^[\x{002d}0-9a-z\x{3447}\x{3473}\x{359E}\x{360E}\x{361A}\x{3918}\x{396E}\x{39CF}\x{39D0}' . '\x{39DF}\x{3A73}\x{3B4E}\x{3C6E}\x{3CE0}\x{4056}\x{415F}\x{4337}\x{43AC}' . '\x{43B1}\x{43DD}\x{44D6}\x{464C}\x{4661}\x{4723}\x{4729}\x{477C}\x{478D}' . '\x{4947}\x{497A}\x{497D}\x{4982}\x{4983}\x{4985}\x{4986}\x{499B}\x{499F}' . '\x{49B6}\x{49B7}\x{4C77}\x{4C9F}\x{4CA0}\x{4CA1}\x{4CA2}\x{4CA3}\x{4D13}' . '\x{4D14}\x{4D15}\x{4D16}\x{4D17}\x{4D18}\x{4D19}\x{4DAE}\x{4E00}\x{4E01}' . '\x{4E02}\x{4E03}\x{4E04}\x{4E05}\x{4E06}\x{4E07}\x{4E08}\x{4E09}\x{4E0A}' . '\x{4E0B}\x{4E0C}\x{4E0D}\x{4E0E}\x{4E0F}\x{4E10}\x{4E11}\x{4E13}\x{4E14}' . '\x{4E15}\x{4E16}\x{4E17}\x{4E18}\x{4E19}\x{4E1A}\x{4E1B}\x{4E1C}\x{4E1D}' . '\x{4E1E}\x{4E1F}\x{4E20}\x{4E21}\x{4E22}\x{4E23}\x{4E24}\x{4E25}\x{4E26}' . '\x{4E27}\x{4E28}\x{4E2A}\x{4E2B}\x{4E2C}\x{4E2D}\x{4E2E}\x{4E2F}\x{4E30}' . '\x{4E31}\x{4E32}\x{4E33}\x{4E34}\x{4E35}\x{4E36}\x{4E37}\x{4E38}\x{4E39}' . '\x{4E3A}\x{4E3B}\x{4E3C}\x{4E3D}\x{4E3E}\x{4E3F}\x{4E40}\x{4E41}\x{4E42}' . '\x{4E43}\x{4E44}\x{4E45}\x{4E46}\x{4E47}\x{4E48}\x{4E49}\x{4E4A}\x{4E4B}' . '\x{4E4C}\x{4E4D}\x{4E4E}\x{4E4F}\x{4E50}\x{4E51}\x{4E52}\x{4E53}\x{4E54}' . '\x{4E56}\x{4E57}\x{4E58}\x{4E59}\x{4E5A}\x{4E5B}\x{4E5C}\x{4E5D}\x{4E5E}' . '\x{4E5F}\x{4E60}\x{4E61}\x{4E62}\x{4E63}\x{4E64}\x{4E65}\x{4E66}\x{4E67}' . '\x{4E69}\x{4E6A}\x{4E6B}\x{4E6C}\x{4E6D}\x{4E6E}\x{4E6F}\x{4E70}\x{4E71}' . '\x{4E72}\x{4E73}\x{4E74}\x{4E75}\x{4E76}\x{4E77}\x{4E78}\x{4E7A}\x{4E7B}' . '\x{4E7C}\x{4E7D}\x{4E7E}\x{4E7F}\x{4E80}\x{4E81}\x{4E82}\x{4E83}\x{4E84}' . '\x{4E85}\x{4E86}\x{4E87}\x{4E88}\x{4E89}\x{4E8B}\x{4E8C}\x{4E8D}\x{4E8E}' . '\x{4E8F}\x{4E90}\x{4E91}\x{4E92}\x{4E93}\x{4E94}\x{4E95}\x{4E97}\x{4E98}' . '\x{4E99}\x{4E9A}\x{4E9B}\x{4E9C}\x{4E9D}\x{4E9E}\x{4E9F}\x{4EA0}\x{4EA1}' . '\x{4EA2}\x{4EA4}\x{4EA5}\x{4EA6}\x{4EA7}\x{4EA8}\x{4EA9}\x{4EAA}\x{4EAB}' . '\x{4EAC}\x{4EAD}\x{4EAE}\x{4EAF}\x{4EB0}\x{4EB1}\x{4EB2}\x{4EB3}\x{4EB4}' . '\x{4EB5}\x{4EB6}\x{4EB7}\x{4EB8}\x{4EB9}\x{4EBA}\x{4EBB}\x{4EBD}\x{4EBE}' . '\x{4EBF}\x{4EC0}\x{4EC1}\x{4EC2}\x{4EC3}\x{4EC4}\x{4EC5}\x{4EC6}\x{4EC7}' . '\x{4EC8}\x{4EC9}\x{4ECA}\x{4ECB}\x{4ECD}\x{4ECE}\x{4ECF}\x{4ED0}\x{4ED1}' . '\x{4ED2}\x{4ED3}\x{4ED4}\x{4ED5}\x{4ED6}\x{4ED7}\x{4ED8}\x{4ED9}\x{4EDA}' . '\x{4EDB}\x{4EDC}\x{4EDD}\x{4EDE}\x{4EDF}\x{4EE0}\x{4EE1}\x{4EE2}\x{4EE3}' . '\x{4EE4}\x{4EE5}\x{4EE6}\x{4EE8}\x{4EE9}\x{4EEA}\x{4EEB}\x{4EEC}\x{4EEF}' . '\x{4EF0}\x{4EF1}\x{4EF2}\x{4EF3}\x{4EF4}\x{4EF5}\x{4EF6}\x{4EF7}\x{4EFB}' . '\x{4EFD}\x{4EFF}\x{4F00}\x{4F01}\x{4F02}\x{4F03}\x{4F04}\x{4F05}\x{4F06}' . '\x{4F08}\x{4F09}\x{4F0A}\x{4F0B}\x{4F0C}\x{4F0D}\x{4F0E}\x{4F0F}\x{4F10}' . '\x{4F11}\x{4F12}\x{4F13}\x{4F14}\x{4F15}\x{4F17}\x{4F18}\x{4F19}\x{4F1A}' . '\x{4F1B}\x{4F1C}\x{4F1D}\x{4F1E}\x{4F1F}\x{4F20}\x{4F21}\x{4F22}\x{4F23}' . '\x{4F24}\x{4F25}\x{4F26}\x{4F27}\x{4F29}\x{4F2A}\x{4F2B}\x{4F2C}\x{4F2D}' . '\x{4F2E}\x{4F2F}\x{4F30}\x{4F32}\x{4F33}\x{4F34}\x{4F36}\x{4F38}\x{4F39}' . '\x{4F3A}\x{4F3B}\x{4F3C}\x{4F3D}\x{4F3E}\x{4F3F}\x{4F41}\x{4F42}\x{4F43}' . '\x{4F45}\x{4F46}\x{4F47}\x{4F48}\x{4F49}\x{4F4A}\x{4F4B}\x{4F4C}\x{4F4D}' . '\x{4F4E}\x{4F4F}\x{4F50}\x{4F51}\x{4F52}\x{4F53}\x{4F54}\x{4F55}\x{4F56}' . '\x{4F57}\x{4F58}\x{4F59}\x{4F5A}\x{4F5B}\x{4F5C}\x{4F5D}\x{4F5E}\x{4F5F}' . '\x{4F60}\x{4F61}\x{4F62}\x{4F63}\x{4F64}\x{4F65}\x{4F66}\x{4F67}\x{4F68}' . '\x{4F69}\x{4F6A}\x{4F6B}\x{4F6C}\x{4F6D}\x{4F6E}\x{4F6F}\x{4F70}\x{4F72}' . '\x{4F73}\x{4F74}\x{4F75}\x{4F76}\x{4F77}\x{4F78}\x{4F79}\x{4F7A}\x{4F7B}' . '\x{4F7C}\x{4F7D}\x{4F7E}\x{4F7F}\x{4F80}\x{4F81}\x{4F82}\x{4F83}\x{4F84}' . '\x{4F85}\x{4F86}\x{4F87}\x{4F88}\x{4F89}\x{4F8A}\x{4F8B}\x{4F8D}\x{4F8F}' . '\x{4F90}\x{4F91}\x{4F92}\x{4F93}\x{4F94}\x{4F95}\x{4F96}\x{4F97}\x{4F98}' . '\x{4F99}\x{4F9A}\x{4F9B}\x{4F9C}\x{4F9D}\x{4F9E}\x{4F9F}\x{4FA0}\x{4FA1}' . '\x{4FA3}\x{4FA4}\x{4FA5}\x{4FA6}\x{4FA7}\x{4FA8}\x{4FA9}\x{4FAA}\x{4FAB}' . '\x{4FAC}\x{4FAE}\x{4FAF}\x{4FB0}\x{4FB1}\x{4FB2}\x{4FB3}\x{4FB4}\x{4FB5}' . '\x{4FB6}\x{4FB7}\x{4FB8}\x{4FB9}\x{4FBA}\x{4FBB}\x{4FBC}\x{4FBE}\x{4FBF}' . '\x{4FC0}\x{4FC1}\x{4FC2}\x{4FC3}\x{4FC4}\x{4FC5}\x{4FC7}\x{4FC9}\x{4FCA}' . '\x{4FCB}\x{4FCD}\x{4FCE}\x{4FCF}\x{4FD0}\x{4FD1}\x{4FD2}\x{4FD3}\x{4FD4}' . '\x{4FD5}\x{4FD6}\x{4FD7}\x{4FD8}\x{4FD9}\x{4FDA}\x{4FDB}\x{4FDC}\x{4FDD}' . '\x{4FDE}\x{4FDF}\x{4FE0}\x{4FE1}\x{4FE3}\x{4FE4}\x{4FE5}\x{4FE6}\x{4FE7}' . '\x{4FE8}\x{4FE9}\x{4FEA}\x{4FEB}\x{4FEC}\x{4FED}\x{4FEE}\x{4FEF}\x{4FF0}' . '\x{4FF1}\x{4FF2}\x{4FF3}\x{4FF4}\x{4FF5}\x{4FF6}\x{4FF7}\x{4FF8}\x{4FF9}' . '\x{4FFA}\x{4FFB}\x{4FFE}\x{4FFF}\x{5000}\x{5001}\x{5002}\x{5003}\x{5004}' . '\x{5005}\x{5006}\x{5007}\x{5008}\x{5009}\x{500A}\x{500B}\x{500C}\x{500D}' . '\x{500E}\x{500F}\x{5011}\x{5012}\x{5013}\x{5014}\x{5015}\x{5016}\x{5017}' . '\x{5018}\x{5019}\x{501A}\x{501B}\x{501C}\x{501D}\x{501E}\x{501F}\x{5020}' . '\x{5021}\x{5022}\x{5023}\x{5024}\x{5025}\x{5026}\x{5027}\x{5028}\x{5029}' . '\x{502A}\x{502B}\x{502C}\x{502D}\x{502E}\x{502F}\x{5030}\x{5031}\x{5032}' . '\x{5033}\x{5035}\x{5036}\x{5037}\x{5039}\x{503A}\x{503B}\x{503C}\x{503E}' . '\x{503F}\x{5040}\x{5041}\x{5043}\x{5044}\x{5045}\x{5046}\x{5047}\x{5048}' . '\x{5049}\x{504A}\x{504B}\x{504C}\x{504D}\x{504E}\x{504F}\x{5051}\x{5053}' . '\x{5054}\x{5055}\x{5056}\x{5057}\x{5059}\x{505A}\x{505B}\x{505C}\x{505D}' . '\x{505E}\x{505F}\x{5060}\x{5061}\x{5062}\x{5063}\x{5064}\x{5065}\x{5066}' . '\x{5067}\x{5068}\x{5069}\x{506A}\x{506B}\x{506C}\x{506D}\x{506E}\x{506F}' . '\x{5070}\x{5071}\x{5072}\x{5073}\x{5074}\x{5075}\x{5076}\x{5077}\x{5078}' . '\x{5079}\x{507A}\x{507B}\x{507D}\x{507E}\x{507F}\x{5080}\x{5082}\x{5083}' . '\x{5084}\x{5085}\x{5086}\x{5087}\x{5088}\x{5089}\x{508A}\x{508B}\x{508C}' . '\x{508D}\x{508E}\x{508F}\x{5090}\x{5091}\x{5092}\x{5094}\x{5095}\x{5096}' . '\x{5098}\x{5099}\x{509A}\x{509B}\x{509C}\x{509D}\x{509E}\x{50A2}\x{50A3}' . '\x{50A4}\x{50A5}\x{50A6}\x{50A7}\x{50A8}\x{50A9}\x{50AA}\x{50AB}\x{50AC}' . '\x{50AD}\x{50AE}\x{50AF}\x{50B0}\x{50B1}\x{50B2}\x{50B3}\x{50B4}\x{50B5}' . '\x{50B6}\x{50B7}\x{50B8}\x{50BA}\x{50BB}\x{50BC}\x{50BD}\x{50BE}\x{50BF}' . '\x{50C0}\x{50C1}\x{50C2}\x{50C4}\x{50C5}\x{50C6}\x{50C7}\x{50C8}\x{50C9}' . '\x{50CA}\x{50CB}\x{50CC}\x{50CD}\x{50CE}\x{50CF}\x{50D0}\x{50D1}\x{50D2}' . '\x{50D3}\x{50D4}\x{50D5}\x{50D6}\x{50D7}\x{50D9}\x{50DA}\x{50DB}\x{50DC}' . '\x{50DD}\x{50DE}\x{50E0}\x{50E3}\x{50E4}\x{50E5}\x{50E6}\x{50E7}\x{50E8}' . '\x{50E9}\x{50EA}\x{50EC}\x{50ED}\x{50EE}\x{50EF}\x{50F0}\x{50F1}\x{50F2}' . '\x{50F3}\x{50F5}\x{50F6}\x{50F8}\x{50F9}\x{50FA}\x{50FB}\x{50FC}\x{50FD}' . '\x{50FE}\x{50FF}\x{5100}\x{5101}\x{5102}\x{5103}\x{5104}\x{5105}\x{5106}' . '\x{5107}\x{5108}\x{5109}\x{510A}\x{510B}\x{510C}\x{510D}\x{510E}\x{510F}' . '\x{5110}\x{5111}\x{5112}\x{5113}\x{5114}\x{5115}\x{5116}\x{5117}\x{5118}' . '\x{5119}\x{511A}\x{511C}\x{511D}\x{511E}\x{511F}\x{5120}\x{5121}\x{5122}' . '\x{5123}\x{5124}\x{5125}\x{5126}\x{5127}\x{5129}\x{512A}\x{512C}\x{512D}' . '\x{512E}\x{512F}\x{5130}\x{5131}\x{5132}\x{5133}\x{5134}\x{5135}\x{5136}' . '\x{5137}\x{5138}\x{5139}\x{513A}\x{513B}\x{513C}\x{513D}\x{513E}\x{513F}' . '\x{5140}\x{5141}\x{5143}\x{5144}\x{5145}\x{5146}\x{5147}\x{5148}\x{5149}' . '\x{514B}\x{514C}\x{514D}\x{514E}\x{5150}\x{5151}\x{5152}\x{5154}\x{5155}' . '\x{5156}\x{5157}\x{5159}\x{515A}\x{515B}\x{515C}\x{515D}\x{515E}\x{515F}' . '\x{5161}\x{5162}\x{5163}\x{5165}\x{5166}\x{5167}\x{5168}\x{5169}\x{516A}' . '\x{516B}\x{516C}\x{516D}\x{516E}\x{516F}\x{5170}\x{5171}\x{5173}\x{5174}' . '\x{5175}\x{5176}\x{5177}\x{5178}\x{5179}\x{517A}\x{517B}\x{517C}\x{517D}' . '\x{517F}\x{5180}\x{5181}\x{5182}\x{5185}\x{5186}\x{5187}\x{5188}\x{5189}' . '\x{518A}\x{518B}\x{518C}\x{518D}\x{518F}\x{5190}\x{5191}\x{5192}\x{5193}' . '\x{5194}\x{5195}\x{5196}\x{5197}\x{5198}\x{5199}\x{519A}\x{519B}\x{519C}' . '\x{519D}\x{519E}\x{519F}\x{51A0}\x{51A2}\x{51A4}\x{51A5}\x{51A6}\x{51A7}' . '\x{51A8}\x{51AA}\x{51AB}\x{51AC}\x{51AE}\x{51AF}\x{51B0}\x{51B1}\x{51B2}' . '\x{51B3}\x{51B5}\x{51B6}\x{51B7}\x{51B9}\x{51BB}\x{51BC}\x{51BD}\x{51BE}' . '\x{51BF}\x{51C0}\x{51C1}\x{51C3}\x{51C4}\x{51C5}\x{51C6}\x{51C7}\x{51C8}' . '\x{51C9}\x{51CA}\x{51CB}\x{51CC}\x{51CD}\x{51CE}\x{51CF}\x{51D0}\x{51D1}' . '\x{51D4}\x{51D5}\x{51D6}\x{51D7}\x{51D8}\x{51D9}\x{51DA}\x{51DB}\x{51DC}' . '\x{51DD}\x{51DE}\x{51E0}\x{51E1}\x{51E2}\x{51E3}\x{51E4}\x{51E5}\x{51E7}' . '\x{51E8}\x{51E9}\x{51EA}\x{51EB}\x{51ED}\x{51EF}\x{51F0}\x{51F1}\x{51F3}' . '\x{51F4}\x{51F5}\x{51F6}\x{51F7}\x{51F8}\x{51F9}\x{51FA}\x{51FB}\x{51FC}' . '\x{51FD}\x{51FE}\x{51FF}\x{5200}\x{5201}\x{5202}\x{5203}\x{5204}\x{5205}' . '\x{5206}\x{5207}\x{5208}\x{5209}\x{520A}\x{520B}\x{520C}\x{520D}\x{520E}' . '\x{520F}\x{5210}\x{5211}\x{5212}\x{5213}\x{5214}\x{5215}\x{5216}\x{5217}' . '\x{5218}\x{5219}\x{521A}\x{521B}\x{521C}\x{521D}\x{521E}\x{521F}\x{5220}' . '\x{5221}\x{5222}\x{5223}\x{5224}\x{5225}\x{5226}\x{5228}\x{5229}\x{522A}' . '\x{522B}\x{522C}\x{522D}\x{522E}\x{522F}\x{5230}\x{5231}\x{5232}\x{5233}' . '\x{5234}\x{5235}\x{5236}\x{5237}\x{5238}\x{5239}\x{523A}\x{523B}\x{523C}' . '\x{523D}\x{523E}\x{523F}\x{5240}\x{5241}\x{5242}\x{5243}\x{5244}\x{5245}' . '\x{5246}\x{5247}\x{5248}\x{5249}\x{524A}\x{524B}\x{524C}\x{524D}\x{524E}' . '\x{5250}\x{5251}\x{5252}\x{5254}\x{5255}\x{5256}\x{5257}\x{5258}\x{5259}' . '\x{525A}\x{525B}\x{525C}\x{525D}\x{525E}\x{525F}\x{5260}\x{5261}\x{5262}' . '\x{5263}\x{5264}\x{5265}\x{5267}\x{5268}\x{5269}\x{526A}\x{526B}\x{526C}' . '\x{526D}\x{526E}\x{526F}\x{5270}\x{5272}\x{5273}\x{5274}\x{5275}\x{5276}' . '\x{5277}\x{5278}\x{527A}\x{527B}\x{527C}\x{527D}\x{527E}\x{527F}\x{5280}' . '\x{5281}\x{5282}\x{5283}\x{5284}\x{5286}\x{5287}\x{5288}\x{5289}\x{528A}' . '\x{528B}\x{528C}\x{528D}\x{528F}\x{5290}\x{5291}\x{5292}\x{5293}\x{5294}' . '\x{5295}\x{5296}\x{5297}\x{5298}\x{5299}\x{529A}\x{529B}\x{529C}\x{529D}' . '\x{529E}\x{529F}\x{52A0}\x{52A1}\x{52A2}\x{52A3}\x{52A5}\x{52A6}\x{52A7}' . '\x{52A8}\x{52A9}\x{52AA}\x{52AB}\x{52AC}\x{52AD}\x{52AE}\x{52AF}\x{52B0}' . '\x{52B1}\x{52B2}\x{52B3}\x{52B4}\x{52B5}\x{52B6}\x{52B7}\x{52B8}\x{52B9}' . '\x{52BA}\x{52BB}\x{52BC}\x{52BD}\x{52BE}\x{52BF}\x{52C0}\x{52C1}\x{52C2}' . '\x{52C3}\x{52C6}\x{52C7}\x{52C9}\x{52CA}\x{52CB}\x{52CD}\x{52CF}\x{52D0}' . '\x{52D2}\x{52D3}\x{52D5}\x{52D6}\x{52D7}\x{52D8}\x{52D9}\x{52DA}\x{52DB}' . '\x{52DC}\x{52DD}\x{52DE}\x{52DF}\x{52E0}\x{52E2}\x{52E3}\x{52E4}\x{52E6}' . '\x{52E7}\x{52E8}\x{52E9}\x{52EA}\x{52EB}\x{52EC}\x{52ED}\x{52EF}\x{52F0}' . '\x{52F1}\x{52F2}\x{52F3}\x{52F4}\x{52F5}\x{52F6}\x{52F7}\x{52F8}\x{52F9}' . '\x{52FA}\x{52FB}\x{52FC}\x{52FD}\x{52FE}\x{52FF}\x{5300}\x{5301}\x{5302}' . '\x{5305}\x{5306}\x{5307}\x{5308}\x{5309}\x{530A}\x{530B}\x{530C}\x{530D}' . '\x{530E}\x{530F}\x{5310}\x{5311}\x{5312}\x{5313}\x{5314}\x{5315}\x{5316}' . '\x{5317}\x{5319}\x{531A}\x{531C}\x{531D}\x{531F}\x{5320}\x{5321}\x{5322}' . '\x{5323}\x{5324}\x{5325}\x{5326}\x{5328}\x{532A}\x{532B}\x{532C}\x{532D}' . '\x{532E}\x{532F}\x{5330}\x{5331}\x{5333}\x{5334}\x{5337}\x{5339}\x{533A}' . '\x{533B}\x{533C}\x{533D}\x{533E}\x{533F}\x{5340}\x{5341}\x{5343}\x{5344}' . '\x{5345}\x{5346}\x{5347}\x{5348}\x{5349}\x{534A}\x{534B}\x{534C}\x{534D}' . '\x{534E}\x{534F}\x{5350}\x{5351}\x{5352}\x{5353}\x{5354}\x{5355}\x{5356}' . '\x{5357}\x{5358}\x{5359}\x{535A}\x{535C}\x{535E}\x{535F}\x{5360}\x{5361}' . '\x{5362}\x{5363}\x{5364}\x{5365}\x{5366}\x{5367}\x{5369}\x{536B}\x{536C}' . '\x{536E}\x{536F}\x{5370}\x{5371}\x{5372}\x{5373}\x{5374}\x{5375}\x{5376}' . '\x{5377}\x{5378}\x{5379}\x{537A}\x{537B}\x{537C}\x{537D}\x{537E}\x{537F}' . '\x{5381}\x{5382}\x{5383}\x{5384}\x{5385}\x{5386}\x{5387}\x{5388}\x{5389}' . '\x{538A}\x{538B}\x{538C}\x{538D}\x{538E}\x{538F}\x{5390}\x{5391}\x{5392}' . '\x{5393}\x{5394}\x{5395}\x{5396}\x{5397}\x{5398}\x{5399}\x{539A}\x{539B}' . '\x{539C}\x{539D}\x{539E}\x{539F}\x{53A0}\x{53A2}\x{53A3}\x{53A4}\x{53A5}' . '\x{53A6}\x{53A7}\x{53A8}\x{53A9}\x{53AC}\x{53AD}\x{53AE}\x{53B0}\x{53B1}' . '\x{53B2}\x{53B3}\x{53B4}\x{53B5}\x{53B6}\x{53B7}\x{53B8}\x{53B9}\x{53BB}' . '\x{53BC}\x{53BD}\x{53BE}\x{53BF}\x{53C0}\x{53C1}\x{53C2}\x{53C3}\x{53C4}' . '\x{53C6}\x{53C7}\x{53C8}\x{53C9}\x{53CA}\x{53CB}\x{53CC}\x{53CD}\x{53CE}' . '\x{53D0}\x{53D1}\x{53D2}\x{53D3}\x{53D4}\x{53D5}\x{53D6}\x{53D7}\x{53D8}' . '\x{53D9}\x{53DB}\x{53DC}\x{53DF}\x{53E0}\x{53E1}\x{53E2}\x{53E3}\x{53E4}' . '\x{53E5}\x{53E6}\x{53E8}\x{53E9}\x{53EA}\x{53EB}\x{53EC}\x{53ED}\x{53EE}' . '\x{53EF}\x{53F0}\x{53F1}\x{53F2}\x{53F3}\x{53F4}\x{53F5}\x{53F6}\x{53F7}' . '\x{53F8}\x{53F9}\x{53FA}\x{53FB}\x{53FC}\x{53FD}\x{53FE}\x{5401}\x{5402}' . '\x{5403}\x{5404}\x{5405}\x{5406}\x{5407}\x{5408}\x{5409}\x{540A}\x{540B}' . '\x{540C}\x{540D}\x{540E}\x{540F}\x{5410}\x{5411}\x{5412}\x{5413}\x{5414}' . '\x{5415}\x{5416}\x{5417}\x{5418}\x{5419}\x{541B}\x{541C}\x{541D}\x{541E}' . '\x{541F}\x{5420}\x{5421}\x{5423}\x{5424}\x{5425}\x{5426}\x{5427}\x{5428}' . '\x{5429}\x{542A}\x{542B}\x{542C}\x{542D}\x{542E}\x{542F}\x{5430}\x{5431}' . '\x{5432}\x{5433}\x{5434}\x{5435}\x{5436}\x{5437}\x{5438}\x{5439}\x{543A}' . '\x{543B}\x{543C}\x{543D}\x{543E}\x{543F}\x{5440}\x{5441}\x{5442}\x{5443}' . '\x{5444}\x{5445}\x{5446}\x{5447}\x{5448}\x{5449}\x{544A}\x{544B}\x{544D}' . '\x{544E}\x{544F}\x{5450}\x{5451}\x{5452}\x{5453}\x{5454}\x{5455}\x{5456}' . '\x{5457}\x{5458}\x{5459}\x{545A}\x{545B}\x{545C}\x{545E}\x{545F}\x{5460}' . '\x{5461}\x{5462}\x{5463}\x{5464}\x{5465}\x{5466}\x{5467}\x{5468}\x{546A}' . '\x{546B}\x{546C}\x{546D}\x{546E}\x{546F}\x{5470}\x{5471}\x{5472}\x{5473}' . '\x{5474}\x{5475}\x{5476}\x{5477}\x{5478}\x{5479}\x{547A}\x{547B}\x{547C}' . '\x{547D}\x{547E}\x{547F}\x{5480}\x{5481}\x{5482}\x{5483}\x{5484}\x{5485}' . '\x{5486}\x{5487}\x{5488}\x{5489}\x{548B}\x{548C}\x{548D}\x{548E}\x{548F}' . '\x{5490}\x{5491}\x{5492}\x{5493}\x{5494}\x{5495}\x{5496}\x{5497}\x{5498}' . '\x{5499}\x{549A}\x{549B}\x{549C}\x{549D}\x{549E}\x{549F}\x{54A0}\x{54A1}' . '\x{54A2}\x{54A3}\x{54A4}\x{54A5}\x{54A6}\x{54A7}\x{54A8}\x{54A9}\x{54AA}' . '\x{54AB}\x{54AC}\x{54AD}\x{54AE}\x{54AF}\x{54B0}\x{54B1}\x{54B2}\x{54B3}' . '\x{54B4}\x{54B6}\x{54B7}\x{54B8}\x{54B9}\x{54BA}\x{54BB}\x{54BC}\x{54BD}' . '\x{54BE}\x{54BF}\x{54C0}\x{54C1}\x{54C2}\x{54C3}\x{54C4}\x{54C5}\x{54C6}' . '\x{54C7}\x{54C8}\x{54C9}\x{54CA}\x{54CB}\x{54CC}\x{54CD}\x{54CE}\x{54CF}' . '\x{54D0}\x{54D1}\x{54D2}\x{54D3}\x{54D4}\x{54D5}\x{54D6}\x{54D7}\x{54D8}' . '\x{54D9}\x{54DA}\x{54DB}\x{54DC}\x{54DD}\x{54DE}\x{54DF}\x{54E0}\x{54E1}' . '\x{54E2}\x{54E3}\x{54E4}\x{54E5}\x{54E6}\x{54E7}\x{54E8}\x{54E9}\x{54EA}' . '\x{54EB}\x{54EC}\x{54ED}\x{54EE}\x{54EF}\x{54F0}\x{54F1}\x{54F2}\x{54F3}' . '\x{54F4}\x{54F5}\x{54F7}\x{54F8}\x{54F9}\x{54FA}\x{54FB}\x{54FC}\x{54FD}' . '\x{54FE}\x{54FF}\x{5500}\x{5501}\x{5502}\x{5503}\x{5504}\x{5505}\x{5506}' . '\x{5507}\x{5508}\x{5509}\x{550A}\x{550B}\x{550C}\x{550D}\x{550E}\x{550F}' . '\x{5510}\x{5511}\x{5512}\x{5513}\x{5514}\x{5516}\x{5517}\x{551A}\x{551B}' . '\x{551C}\x{551D}\x{551E}\x{551F}\x{5520}\x{5521}\x{5522}\x{5523}\x{5524}' . '\x{5525}\x{5526}\x{5527}\x{5528}\x{5529}\x{552A}\x{552B}\x{552C}\x{552D}' . '\x{552E}\x{552F}\x{5530}\x{5531}\x{5532}\x{5533}\x{5534}\x{5535}\x{5536}' . '\x{5537}\x{5538}\x{5539}\x{553A}\x{553B}\x{553C}\x{553D}\x{553E}\x{553F}' . '\x{5540}\x{5541}\x{5542}\x{5543}\x{5544}\x{5545}\x{5546}\x{5548}\x{5549}' . '\x{554A}\x{554B}\x{554C}\x{554D}\x{554E}\x{554F}\x{5550}\x{5551}\x{5552}' . '\x{5553}\x{5554}\x{5555}\x{5556}\x{5557}\x{5558}\x{5559}\x{555A}\x{555B}' . '\x{555C}\x{555D}\x{555E}\x{555F}\x{5561}\x{5562}\x{5563}\x{5564}\x{5565}' . '\x{5566}\x{5567}\x{5568}\x{5569}\x{556A}\x{556B}\x{556C}\x{556D}\x{556E}' . '\x{556F}\x{5570}\x{5571}\x{5572}\x{5573}\x{5574}\x{5575}\x{5576}\x{5577}' . '\x{5578}\x{5579}\x{557B}\x{557C}\x{557D}\x{557E}\x{557F}\x{5580}\x{5581}' . '\x{5582}\x{5583}\x{5584}\x{5585}\x{5586}\x{5587}\x{5588}\x{5589}\x{558A}' . '\x{558B}\x{558C}\x{558D}\x{558E}\x{558F}\x{5590}\x{5591}\x{5592}\x{5593}' . '\x{5594}\x{5595}\x{5596}\x{5597}\x{5598}\x{5599}\x{559A}\x{559B}\x{559C}' . '\x{559D}\x{559E}\x{559F}\x{55A0}\x{55A1}\x{55A2}\x{55A3}\x{55A4}\x{55A5}' . '\x{55A6}\x{55A7}\x{55A8}\x{55A9}\x{55AA}\x{55AB}\x{55AC}\x{55AD}\x{55AE}' . '\x{55AF}\x{55B0}\x{55B1}\x{55B2}\x{55B3}\x{55B4}\x{55B5}\x{55B6}\x{55B7}' . '\x{55B8}\x{55B9}\x{55BA}\x{55BB}\x{55BC}\x{55BD}\x{55BE}\x{55BF}\x{55C0}' . '\x{55C1}\x{55C2}\x{55C3}\x{55C4}\x{55C5}\x{55C6}\x{55C7}\x{55C8}\x{55C9}' . '\x{55CA}\x{55CB}\x{55CC}\x{55CD}\x{55CE}\x{55CF}\x{55D0}\x{55D1}\x{55D2}' . '\x{55D3}\x{55D4}\x{55D5}\x{55D6}\x{55D7}\x{55D8}\x{55D9}\x{55DA}\x{55DB}' . '\x{55DC}\x{55DD}\x{55DE}\x{55DF}\x{55E1}\x{55E2}\x{55E3}\x{55E4}\x{55E5}' . '\x{55E6}\x{55E7}\x{55E8}\x{55E9}\x{55EA}\x{55EB}\x{55EC}\x{55ED}\x{55EE}' . '\x{55EF}\x{55F0}\x{55F1}\x{55F2}\x{55F3}\x{55F4}\x{55F5}\x{55F6}\x{55F7}' . '\x{55F9}\x{55FA}\x{55FB}\x{55FC}\x{55FD}\x{55FE}\x{55FF}\x{5600}\x{5601}' . '\x{5602}\x{5603}\x{5604}\x{5606}\x{5607}\x{5608}\x{5609}\x{560C}\x{560D}' . '\x{560E}\x{560F}\x{5610}\x{5611}\x{5612}\x{5613}\x{5614}\x{5615}\x{5616}' . '\x{5617}\x{5618}\x{5619}\x{561A}\x{561B}\x{561C}\x{561D}\x{561E}\x{561F}' . '\x{5621}\x{5622}\x{5623}\x{5624}\x{5625}\x{5626}\x{5627}\x{5628}\x{5629}' . '\x{562A}\x{562C}\x{562D}\x{562E}\x{562F}\x{5630}\x{5631}\x{5632}\x{5633}' . '\x{5634}\x{5635}\x{5636}\x{5638}\x{5639}\x{563A}\x{563B}\x{563D}\x{563E}' . '\x{563F}\x{5640}\x{5641}\x{5642}\x{5643}\x{5645}\x{5646}\x{5647}\x{5648}' . '\x{5649}\x{564A}\x{564C}\x{564D}\x{564E}\x{564F}\x{5650}\x{5652}\x{5653}' . '\x{5654}\x{5655}\x{5657}\x{5658}\x{5659}\x{565A}\x{565B}\x{565C}\x{565D}' . '\x{565E}\x{5660}\x{5662}\x{5663}\x{5664}\x{5665}\x{5666}\x{5667}\x{5668}' . '\x{5669}\x{566A}\x{566B}\x{566C}\x{566D}\x{566E}\x{566F}\x{5670}\x{5671}' . '\x{5672}\x{5673}\x{5674}\x{5676}\x{5677}\x{5678}\x{5679}\x{567A}\x{567B}' . '\x{567C}\x{567E}\x{567F}\x{5680}\x{5681}\x{5682}\x{5683}\x{5684}\x{5685}' . '\x{5686}\x{5687}\x{568A}\x{568C}\x{568D}\x{568E}\x{568F}\x{5690}\x{5691}' . '\x{5692}\x{5693}\x{5694}\x{5695}\x{5697}\x{5698}\x{5699}\x{569A}\x{569B}' . '\x{569C}\x{569D}\x{569F}\x{56A0}\x{56A1}\x{56A3}\x{56A4}\x{56A5}\x{56A6}' . '\x{56A7}\x{56A8}\x{56A9}\x{56AA}\x{56AB}\x{56AC}\x{56AD}\x{56AE}\x{56AF}' . '\x{56B0}\x{56B1}\x{56B2}\x{56B3}\x{56B4}\x{56B5}\x{56B6}\x{56B7}\x{56B8}' . '\x{56B9}\x{56BB}\x{56BC}\x{56BD}\x{56BE}\x{56BF}\x{56C0}\x{56C1}\x{56C2}' . '\x{56C3}\x{56C4}\x{56C5}\x{56C6}\x{56C7}\x{56C8}\x{56C9}\x{56CA}\x{56CB}' . '\x{56CC}\x{56CD}\x{56CE}\x{56D0}\x{56D1}\x{56D2}\x{56D3}\x{56D4}\x{56D5}' . '\x{56D6}\x{56D7}\x{56D8}\x{56DA}\x{56DB}\x{56DC}\x{56DD}\x{56DE}\x{56DF}' . '\x{56E0}\x{56E1}\x{56E2}\x{56E3}\x{56E4}\x{56E5}\x{56E7}\x{56E8}\x{56E9}' . '\x{56EA}\x{56EB}\x{56EC}\x{56ED}\x{56EE}\x{56EF}\x{56F0}\x{56F1}\x{56F2}' . '\x{56F3}\x{56F4}\x{56F5}\x{56F7}\x{56F9}\x{56FA}\x{56FD}\x{56FE}\x{56FF}' . '\x{5700}\x{5701}\x{5702}\x{5703}\x{5704}\x{5706}\x{5707}\x{5708}\x{5709}' . '\x{570A}\x{570B}\x{570C}\x{570D}\x{570E}\x{570F}\x{5710}\x{5712}\x{5713}' . '\x{5714}\x{5715}\x{5716}\x{5718}\x{5719}\x{571A}\x{571B}\x{571C}\x{571D}' . '\x{571E}\x{571F}\x{5720}\x{5722}\x{5723}\x{5725}\x{5726}\x{5727}\x{5728}' . '\x{5729}\x{572A}\x{572B}\x{572C}\x{572D}\x{572E}\x{572F}\x{5730}\x{5731}' . '\x{5732}\x{5733}\x{5734}\x{5735}\x{5736}\x{5737}\x{5738}\x{5739}\x{573A}' . '\x{573B}\x{573C}\x{573E}\x{573F}\x{5740}\x{5741}\x{5742}\x{5744}\x{5745}' . '\x{5746}\x{5747}\x{5749}\x{574A}\x{574B}\x{574C}\x{574D}\x{574E}\x{574F}' . '\x{5750}\x{5751}\x{5752}\x{5753}\x{5754}\x{5757}\x{5759}\x{575A}\x{575B}' . '\x{575C}\x{575D}\x{575E}\x{575F}\x{5760}\x{5761}\x{5762}\x{5764}\x{5765}' . '\x{5766}\x{5767}\x{5768}\x{5769}\x{576A}\x{576B}\x{576C}\x{576D}\x{576F}' . '\x{5770}\x{5771}\x{5772}\x{5773}\x{5774}\x{5775}\x{5776}\x{5777}\x{5779}' . '\x{577A}\x{577B}\x{577C}\x{577D}\x{577E}\x{577F}\x{5780}\x{5782}\x{5783}' . '\x{5784}\x{5785}\x{5786}\x{5788}\x{5789}\x{578A}\x{578B}\x{578C}\x{578D}' . '\x{578E}\x{578F}\x{5790}\x{5791}\x{5792}\x{5793}\x{5794}\x{5795}\x{5797}' . '\x{5798}\x{5799}\x{579A}\x{579B}\x{579C}\x{579D}\x{579E}\x{579F}\x{57A0}' . '\x{57A1}\x{57A2}\x{57A3}\x{57A4}\x{57A5}\x{57A6}\x{57A7}\x{57A9}\x{57AA}' . '\x{57AB}\x{57AC}\x{57AD}\x{57AE}\x{57AF}\x{57B0}\x{57B1}\x{57B2}\x{57B3}' . '\x{57B4}\x{57B5}\x{57B6}\x{57B7}\x{57B8}\x{57B9}\x{57BA}\x{57BB}\x{57BC}' . '\x{57BD}\x{57BE}\x{57BF}\x{57C0}\x{57C1}\x{57C2}\x{57C3}\x{57C4}\x{57C5}' . '\x{57C6}\x{57C7}\x{57C8}\x{57C9}\x{57CB}\x{57CC}\x{57CD}\x{57CE}\x{57CF}' . '\x{57D0}\x{57D2}\x{57D3}\x{57D4}\x{57D5}\x{57D6}\x{57D8}\x{57D9}\x{57DA}' . '\x{57DC}\x{57DD}\x{57DF}\x{57E0}\x{57E1}\x{57E2}\x{57E3}\x{57E4}\x{57E5}' . '\x{57E6}\x{57E7}\x{57E8}\x{57E9}\x{57EA}\x{57EB}\x{57EC}\x{57ED}\x{57EE}' . '\x{57EF}\x{57F0}\x{57F1}\x{57F2}\x{57F3}\x{57F4}\x{57F5}\x{57F6}\x{57F7}' . '\x{57F8}\x{57F9}\x{57FA}\x{57FB}\x{57FC}\x{57FD}\x{57FE}\x{57FF}\x{5800}' . '\x{5801}\x{5802}\x{5803}\x{5804}\x{5805}\x{5806}\x{5807}\x{5808}\x{5809}' . '\x{580A}\x{580B}\x{580C}\x{580D}\x{580E}\x{580F}\x{5810}\x{5811}\x{5812}' . '\x{5813}\x{5814}\x{5815}\x{5816}\x{5819}\x{581A}\x{581B}\x{581C}\x{581D}' . '\x{581E}\x{581F}\x{5820}\x{5821}\x{5822}\x{5823}\x{5824}\x{5825}\x{5826}' . '\x{5827}\x{5828}\x{5829}\x{582A}\x{582B}\x{582C}\x{582D}\x{582E}\x{582F}' . '\x{5830}\x{5831}\x{5832}\x{5833}\x{5834}\x{5835}\x{5836}\x{5837}\x{5838}' . '\x{5839}\x{583A}\x{583B}\x{583C}\x{583D}\x{583E}\x{583F}\x{5840}\x{5842}' . '\x{5843}\x{5844}\x{5845}\x{5846}\x{5847}\x{5848}\x{5849}\x{584A}\x{584B}' . '\x{584C}\x{584D}\x{584E}\x{584F}\x{5851}\x{5852}\x{5853}\x{5854}\x{5855}' . '\x{5857}\x{5858}\x{5859}\x{585A}\x{585B}\x{585C}\x{585D}\x{585E}\x{585F}' . '\x{5861}\x{5862}\x{5863}\x{5864}\x{5865}\x{5868}\x{5869}\x{586A}\x{586B}' . '\x{586C}\x{586D}\x{586E}\x{586F}\x{5870}\x{5871}\x{5872}\x{5873}\x{5874}' . '\x{5875}\x{5876}\x{5878}\x{5879}\x{587A}\x{587B}\x{587C}\x{587D}\x{587E}' . '\x{587F}\x{5880}\x{5881}\x{5882}\x{5883}\x{5884}\x{5885}\x{5886}\x{5887}' . '\x{5888}\x{5889}\x{588A}\x{588B}\x{588C}\x{588D}\x{588E}\x{588F}\x{5890}' . '\x{5891}\x{5892}\x{5893}\x{5894}\x{5896}\x{5897}\x{5898}\x{5899}\x{589A}' . '\x{589B}\x{589C}\x{589D}\x{589E}\x{589F}\x{58A0}\x{58A1}\x{58A2}\x{58A3}' . '\x{58A4}\x{58A5}\x{58A6}\x{58A7}\x{58A8}\x{58A9}\x{58AB}\x{58AC}\x{58AD}' . '\x{58AE}\x{58AF}\x{58B0}\x{58B1}\x{58B2}\x{58B3}\x{58B4}\x{58B7}\x{58B8}' . '\x{58B9}\x{58BA}\x{58BB}\x{58BC}\x{58BD}\x{58BE}\x{58BF}\x{58C1}\x{58C2}' . '\x{58C5}\x{58C6}\x{58C7}\x{58C8}\x{58C9}\x{58CA}\x{58CB}\x{58CE}\x{58CF}' . '\x{58D1}\x{58D2}\x{58D3}\x{58D4}\x{58D5}\x{58D6}\x{58D7}\x{58D8}\x{58D9}' . '\x{58DA}\x{58DB}\x{58DD}\x{58DE}\x{58DF}\x{58E0}\x{58E2}\x{58E3}\x{58E4}' . '\x{58E5}\x{58E7}\x{58E8}\x{58E9}\x{58EA}\x{58EB}\x{58EC}\x{58ED}\x{58EE}' . '\x{58EF}\x{58F0}\x{58F1}\x{58F2}\x{58F3}\x{58F4}\x{58F6}\x{58F7}\x{58F8}' . '\x{58F9}\x{58FA}\x{58FB}\x{58FC}\x{58FD}\x{58FE}\x{58FF}\x{5900}\x{5902}' . '\x{5903}\x{5904}\x{5906}\x{5907}\x{5909}\x{590A}\x{590B}\x{590C}\x{590D}' . '\x{590E}\x{590F}\x{5910}\x{5912}\x{5914}\x{5915}\x{5916}\x{5917}\x{5918}' . '\x{5919}\x{591A}\x{591B}\x{591C}\x{591D}\x{591E}\x{591F}\x{5920}\x{5921}' . '\x{5922}\x{5924}\x{5925}\x{5926}\x{5927}\x{5928}\x{5929}\x{592A}\x{592B}' . '\x{592C}\x{592D}\x{592E}\x{592F}\x{5930}\x{5931}\x{5932}\x{5934}\x{5935}' . '\x{5937}\x{5938}\x{5939}\x{593A}\x{593B}\x{593C}\x{593D}\x{593E}\x{593F}' . '\x{5940}\x{5941}\x{5942}\x{5943}\x{5944}\x{5945}\x{5946}\x{5947}\x{5948}' . '\x{5949}\x{594A}\x{594B}\x{594C}\x{594D}\x{594E}\x{594F}\x{5950}\x{5951}' . '\x{5952}\x{5953}\x{5954}\x{5955}\x{5956}\x{5957}\x{5958}\x{595A}\x{595C}' . '\x{595D}\x{595E}\x{595F}\x{5960}\x{5961}\x{5962}\x{5963}\x{5964}\x{5965}' . '\x{5966}\x{5967}\x{5968}\x{5969}\x{596A}\x{596B}\x{596C}\x{596D}\x{596E}' . '\x{596F}\x{5970}\x{5971}\x{5972}\x{5973}\x{5974}\x{5975}\x{5976}\x{5977}' . '\x{5978}\x{5979}\x{597A}\x{597B}\x{597C}\x{597D}\x{597E}\x{597F}\x{5980}' . '\x{5981}\x{5982}\x{5983}\x{5984}\x{5985}\x{5986}\x{5987}\x{5988}\x{5989}' . '\x{598A}\x{598B}\x{598C}\x{598D}\x{598E}\x{598F}\x{5990}\x{5991}\x{5992}' . '\x{5993}\x{5994}\x{5995}\x{5996}\x{5997}\x{5998}\x{5999}\x{599A}\x{599C}' . '\x{599D}\x{599E}\x{599F}\x{59A0}\x{59A1}\x{59A2}\x{59A3}\x{59A4}\x{59A5}' . '\x{59A6}\x{59A7}\x{59A8}\x{59A9}\x{59AA}\x{59AB}\x{59AC}\x{59AD}\x{59AE}' . '\x{59AF}\x{59B0}\x{59B1}\x{59B2}\x{59B3}\x{59B4}\x{59B5}\x{59B6}\x{59B8}' . '\x{59B9}\x{59BA}\x{59BB}\x{59BC}\x{59BD}\x{59BE}\x{59BF}\x{59C0}\x{59C1}' . '\x{59C2}\x{59C3}\x{59C4}\x{59C5}\x{59C6}\x{59C7}\x{59C8}\x{59C9}\x{59CA}' . '\x{59CB}\x{59CC}\x{59CD}\x{59CE}\x{59CF}\x{59D0}\x{59D1}\x{59D2}\x{59D3}' . '\x{59D4}\x{59D5}\x{59D6}\x{59D7}\x{59D8}\x{59D9}\x{59DA}\x{59DB}\x{59DC}' . '\x{59DD}\x{59DE}\x{59DF}\x{59E0}\x{59E1}\x{59E2}\x{59E3}\x{59E4}\x{59E5}' . '\x{59E6}\x{59E8}\x{59E9}\x{59EA}\x{59EB}\x{59EC}\x{59ED}\x{59EE}\x{59EF}' . '\x{59F0}\x{59F1}\x{59F2}\x{59F3}\x{59F4}\x{59F5}\x{59F6}\x{59F7}\x{59F8}' . '\x{59F9}\x{59FA}\x{59FB}\x{59FC}\x{59FD}\x{59FE}\x{59FF}\x{5A00}\x{5A01}' . '\x{5A02}\x{5A03}\x{5A04}\x{5A05}\x{5A06}\x{5A07}\x{5A08}\x{5A09}\x{5A0A}' . '\x{5A0B}\x{5A0C}\x{5A0D}\x{5A0E}\x{5A0F}\x{5A10}\x{5A11}\x{5A12}\x{5A13}' . '\x{5A14}\x{5A15}\x{5A16}\x{5A17}\x{5A18}\x{5A19}\x{5A1A}\x{5A1B}\x{5A1C}' . '\x{5A1D}\x{5A1E}\x{5A1F}\x{5A20}\x{5A21}\x{5A22}\x{5A23}\x{5A25}\x{5A27}' . '\x{5A28}\x{5A29}\x{5A2A}\x{5A2B}\x{5A2D}\x{5A2E}\x{5A2F}\x{5A31}\x{5A32}' . '\x{5A33}\x{5A34}\x{5A35}\x{5A36}\x{5A37}\x{5A38}\x{5A39}\x{5A3A}\x{5A3B}' . '\x{5A3C}\x{5A3D}\x{5A3E}\x{5A3F}\x{5A40}\x{5A41}\x{5A42}\x{5A43}\x{5A44}' . '\x{5A45}\x{5A46}\x{5A47}\x{5A48}\x{5A49}\x{5A4A}\x{5A4B}\x{5A4C}\x{5A4D}' . '\x{5A4E}\x{5A4F}\x{5A50}\x{5A51}\x{5A52}\x{5A53}\x{5A55}\x{5A56}\x{5A57}' . '\x{5A58}\x{5A5A}\x{5A5B}\x{5A5C}\x{5A5D}\x{5A5E}\x{5A5F}\x{5A60}\x{5A61}' . '\x{5A62}\x{5A63}\x{5A64}\x{5A65}\x{5A66}\x{5A67}\x{5A68}\x{5A69}\x{5A6A}' . '\x{5A6B}\x{5A6C}\x{5A6D}\x{5A6E}\x{5A70}\x{5A72}\x{5A73}\x{5A74}\x{5A75}' . '\x{5A76}\x{5A77}\x{5A78}\x{5A79}\x{5A7A}\x{5A7B}\x{5A7C}\x{5A7D}\x{5A7E}' . '\x{5A7F}\x{5A80}\x{5A81}\x{5A82}\x{5A83}\x{5A84}\x{5A85}\x{5A86}\x{5A88}' . '\x{5A89}\x{5A8A}\x{5A8B}\x{5A8C}\x{5A8E}\x{5A8F}\x{5A90}\x{5A91}\x{5A92}' . '\x{5A93}\x{5A94}\x{5A95}\x{5A96}\x{5A97}\x{5A98}\x{5A99}\x{5A9A}\x{5A9B}' . '\x{5A9C}\x{5A9D}\x{5A9E}\x{5A9F}\x{5AA0}\x{5AA1}\x{5AA2}\x{5AA3}\x{5AA4}' . '\x{5AA5}\x{5AA6}\x{5AA7}\x{5AA8}\x{5AA9}\x{5AAA}\x{5AAC}\x{5AAD}\x{5AAE}' . '\x{5AAF}\x{5AB0}\x{5AB1}\x{5AB2}\x{5AB3}\x{5AB4}\x{5AB5}\x{5AB6}\x{5AB7}' . '\x{5AB8}\x{5AB9}\x{5ABA}\x{5ABB}\x{5ABC}\x{5ABD}\x{5ABE}\x{5ABF}\x{5AC0}' . '\x{5AC1}\x{5AC2}\x{5AC3}\x{5AC4}\x{5AC5}\x{5AC6}\x{5AC7}\x{5AC8}\x{5AC9}' . '\x{5ACA}\x{5ACB}\x{5ACC}\x{5ACD}\x{5ACE}\x{5ACF}\x{5AD1}\x{5AD2}\x{5AD4}' . '\x{5AD5}\x{5AD6}\x{5AD7}\x{5AD8}\x{5AD9}\x{5ADA}\x{5ADB}\x{5ADC}\x{5ADD}' . '\x{5ADE}\x{5ADF}\x{5AE0}\x{5AE1}\x{5AE2}\x{5AE3}\x{5AE4}\x{5AE5}\x{5AE6}' . '\x{5AE7}\x{5AE8}\x{5AE9}\x{5AEA}\x{5AEB}\x{5AEC}\x{5AED}\x{5AEE}\x{5AF1}' . '\x{5AF2}\x{5AF3}\x{5AF4}\x{5AF5}\x{5AF6}\x{5AF7}\x{5AF8}\x{5AF9}\x{5AFA}' . '\x{5AFB}\x{5AFC}\x{5AFD}\x{5AFE}\x{5AFF}\x{5B00}\x{5B01}\x{5B02}\x{5B03}' . '\x{5B04}\x{5B05}\x{5B06}\x{5B07}\x{5B08}\x{5B09}\x{5B0B}\x{5B0C}\x{5B0E}' . '\x{5B0F}\x{5B10}\x{5B11}\x{5B12}\x{5B13}\x{5B14}\x{5B15}\x{5B16}\x{5B17}' . '\x{5B18}\x{5B19}\x{5B1A}\x{5B1B}\x{5B1C}\x{5B1D}\x{5B1E}\x{5B1F}\x{5B20}' . '\x{5B21}\x{5B22}\x{5B23}\x{5B24}\x{5B25}\x{5B26}\x{5B27}\x{5B28}\x{5B29}' . '\x{5B2A}\x{5B2B}\x{5B2C}\x{5B2D}\x{5B2E}\x{5B2F}\x{5B30}\x{5B31}\x{5B32}' . '\x{5B33}\x{5B34}\x{5B35}\x{5B36}\x{5B37}\x{5B38}\x{5B3A}\x{5B3B}\x{5B3C}' . '\x{5B3D}\x{5B3E}\x{5B3F}\x{5B40}\x{5B41}\x{5B42}\x{5B43}\x{5B44}\x{5B45}' . '\x{5B47}\x{5B48}\x{5B49}\x{5B4A}\x{5B4B}\x{5B4C}\x{5B4D}\x{5B4E}\x{5B50}' . '\x{5B51}\x{5B53}\x{5B54}\x{5B55}\x{5B56}\x{5B57}\x{5B58}\x{5B59}\x{5B5A}' . '\x{5B5B}\x{5B5C}\x{5B5D}\x{5B5E}\x{5B5F}\x{5B62}\x{5B63}\x{5B64}\x{5B65}' . '\x{5B66}\x{5B67}\x{5B68}\x{5B69}\x{5B6A}\x{5B6B}\x{5B6C}\x{5B6D}\x{5B6E}' . '\x{5B70}\x{5B71}\x{5B72}\x{5B73}\x{5B74}\x{5B75}\x{5B76}\x{5B77}\x{5B78}' . '\x{5B7A}\x{5B7B}\x{5B7C}\x{5B7D}\x{5B7F}\x{5B80}\x{5B81}\x{5B82}\x{5B83}' . '\x{5B84}\x{5B85}\x{5B87}\x{5B88}\x{5B89}\x{5B8A}\x{5B8B}\x{5B8C}\x{5B8D}' . '\x{5B8E}\x{5B8F}\x{5B91}\x{5B92}\x{5B93}\x{5B94}\x{5B95}\x{5B96}\x{5B97}' . '\x{5B98}\x{5B99}\x{5B9A}\x{5B9B}\x{5B9C}\x{5B9D}\x{5B9E}\x{5B9F}\x{5BA0}' . '\x{5BA1}\x{5BA2}\x{5BA3}\x{5BA4}\x{5BA5}\x{5BA6}\x{5BA7}\x{5BA8}\x{5BAA}' . '\x{5BAB}\x{5BAC}\x{5BAD}\x{5BAE}\x{5BAF}\x{5BB0}\x{5BB1}\x{5BB3}\x{5BB4}' . '\x{5BB5}\x{5BB6}\x{5BB8}\x{5BB9}\x{5BBA}\x{5BBB}\x{5BBD}\x{5BBE}\x{5BBF}' . '\x{5BC0}\x{5BC1}\x{5BC2}\x{5BC3}\x{5BC4}\x{5BC5}\x{5BC6}\x{5BC7}\x{5BCA}' . '\x{5BCB}\x{5BCC}\x{5BCD}\x{5BCE}\x{5BCF}\x{5BD0}\x{5BD1}\x{5BD2}\x{5BD3}' . '\x{5BD4}\x{5BD5}\x{5BD6}\x{5BD8}\x{5BD9}\x{5BDB}\x{5BDC}\x{5BDD}\x{5BDE}' . '\x{5BDF}\x{5BE0}\x{5BE1}\x{5BE2}\x{5BE3}\x{5BE4}\x{5BE5}\x{5BE6}\x{5BE7}' . '\x{5BE8}\x{5BE9}\x{5BEA}\x{5BEB}\x{5BEC}\x{5BED}\x{5BEE}\x{5BEF}\x{5BF0}' . '\x{5BF1}\x{5BF2}\x{5BF3}\x{5BF4}\x{5BF5}\x{5BF6}\x{5BF7}\x{5BF8}\x{5BF9}' . '\x{5BFA}\x{5BFB}\x{5BFC}\x{5BFD}\x{5BFF}\x{5C01}\x{5C03}\x{5C04}\x{5C05}' . '\x{5C06}\x{5C07}\x{5C08}\x{5C09}\x{5C0A}\x{5C0B}\x{5C0C}\x{5C0D}\x{5C0E}' . '\x{5C0F}\x{5C10}\x{5C11}\x{5C12}\x{5C13}\x{5C14}\x{5C15}\x{5C16}\x{5C17}' . '\x{5C18}\x{5C19}\x{5C1A}\x{5C1C}\x{5C1D}\x{5C1E}\x{5C1F}\x{5C20}\x{5C21}' . '\x{5C22}\x{5C24}\x{5C25}\x{5C27}\x{5C28}\x{5C2A}\x{5C2B}\x{5C2C}\x{5C2D}' . '\x{5C2E}\x{5C2F}\x{5C30}\x{5C31}\x{5C32}\x{5C33}\x{5C34}\x{5C35}\x{5C37}' . '\x{5C38}\x{5C39}\x{5C3A}\x{5C3B}\x{5C3C}\x{5C3D}\x{5C3E}\x{5C3F}\x{5C40}' . '\x{5C41}\x{5C42}\x{5C43}\x{5C44}\x{5C45}\x{5C46}\x{5C47}\x{5C48}\x{5C49}' . '\x{5C4A}\x{5C4B}\x{5C4C}\x{5C4D}\x{5C4E}\x{5C4F}\x{5C50}\x{5C51}\x{5C52}' . '\x{5C53}\x{5C54}\x{5C55}\x{5C56}\x{5C57}\x{5C58}\x{5C59}\x{5C5B}\x{5C5C}' . '\x{5C5D}\x{5C5E}\x{5C5F}\x{5C60}\x{5C61}\x{5C62}\x{5C63}\x{5C64}\x{5C65}' . '\x{5C66}\x{5C67}\x{5C68}\x{5C69}\x{5C6A}\x{5C6B}\x{5C6C}\x{5C6D}\x{5C6E}' . '\x{5C6F}\x{5C70}\x{5C71}\x{5C72}\x{5C73}\x{5C74}\x{5C75}\x{5C76}\x{5C77}' . '\x{5C78}\x{5C79}\x{5C7A}\x{5C7B}\x{5C7C}\x{5C7D}\x{5C7E}\x{5C7F}\x{5C80}' . '\x{5C81}\x{5C82}\x{5C83}\x{5C84}\x{5C86}\x{5C87}\x{5C88}\x{5C89}\x{5C8A}' . '\x{5C8B}\x{5C8C}\x{5C8D}\x{5C8E}\x{5C8F}\x{5C90}\x{5C91}\x{5C92}\x{5C93}' . '\x{5C94}\x{5C95}\x{5C96}\x{5C97}\x{5C98}\x{5C99}\x{5C9A}\x{5C9B}\x{5C9C}' . '\x{5C9D}\x{5C9E}\x{5C9F}\x{5CA0}\x{5CA1}\x{5CA2}\x{5CA3}\x{5CA4}\x{5CA5}' . '\x{5CA6}\x{5CA7}\x{5CA8}\x{5CA9}\x{5CAA}\x{5CAB}\x{5CAC}\x{5CAD}\x{5CAE}' . '\x{5CAF}\x{5CB0}\x{5CB1}\x{5CB2}\x{5CB3}\x{5CB5}\x{5CB6}\x{5CB7}\x{5CB8}' . '\x{5CBA}\x{5CBB}\x{5CBC}\x{5CBD}\x{5CBE}\x{5CBF}\x{5CC1}\x{5CC2}\x{5CC3}' . '\x{5CC4}\x{5CC5}\x{5CC6}\x{5CC7}\x{5CC8}\x{5CC9}\x{5CCA}\x{5CCB}\x{5CCC}' . '\x{5CCD}\x{5CCE}\x{5CCF}\x{5CD0}\x{5CD1}\x{5CD2}\x{5CD3}\x{5CD4}\x{5CD6}' . '\x{5CD7}\x{5CD8}\x{5CD9}\x{5CDA}\x{5CDB}\x{5CDC}\x{5CDE}\x{5CDF}\x{5CE0}' . '\x{5CE1}\x{5CE2}\x{5CE3}\x{5CE4}\x{5CE5}\x{5CE6}\x{5CE7}\x{5CE8}\x{5CE9}' . '\x{5CEA}\x{5CEB}\x{5CEC}\x{5CED}\x{5CEE}\x{5CEF}\x{5CF0}\x{5CF1}\x{5CF2}' . '\x{5CF3}\x{5CF4}\x{5CF6}\x{5CF7}\x{5CF8}\x{5CF9}\x{5CFA}\x{5CFB}\x{5CFC}' . '\x{5CFD}\x{5CFE}\x{5CFF}\x{5D00}\x{5D01}\x{5D02}\x{5D03}\x{5D04}\x{5D05}' . '\x{5D06}\x{5D07}\x{5D08}\x{5D09}\x{5D0A}\x{5D0B}\x{5D0C}\x{5D0D}\x{5D0E}' . '\x{5D0F}\x{5D10}\x{5D11}\x{5D12}\x{5D13}\x{5D14}\x{5D15}\x{5D16}\x{5D17}' . '\x{5D18}\x{5D19}\x{5D1A}\x{5D1B}\x{5D1C}\x{5D1D}\x{5D1E}\x{5D1F}\x{5D20}' . '\x{5D21}\x{5D22}\x{5D23}\x{5D24}\x{5D25}\x{5D26}\x{5D27}\x{5D28}\x{5D29}' . '\x{5D2A}\x{5D2C}\x{5D2D}\x{5D2E}\x{5D30}\x{5D31}\x{5D32}\x{5D33}\x{5D34}' . '\x{5D35}\x{5D36}\x{5D37}\x{5D38}\x{5D39}\x{5D3A}\x{5D3C}\x{5D3D}\x{5D3E}' . '\x{5D3F}\x{5D40}\x{5D41}\x{5D42}\x{5D43}\x{5D44}\x{5D45}\x{5D46}\x{5D47}' . '\x{5D48}\x{5D49}\x{5D4A}\x{5D4B}\x{5D4C}\x{5D4D}\x{5D4E}\x{5D4F}\x{5D50}' . '\x{5D51}\x{5D52}\x{5D54}\x{5D55}\x{5D56}\x{5D58}\x{5D59}\x{5D5A}\x{5D5B}' . '\x{5D5D}\x{5D5E}\x{5D5F}\x{5D61}\x{5D62}\x{5D63}\x{5D64}\x{5D65}\x{5D66}' . '\x{5D67}\x{5D68}\x{5D69}\x{5D6A}\x{5D6B}\x{5D6C}\x{5D6D}\x{5D6E}\x{5D6F}' . '\x{5D70}\x{5D71}\x{5D72}\x{5D73}\x{5D74}\x{5D75}\x{5D76}\x{5D77}\x{5D78}' . '\x{5D79}\x{5D7A}\x{5D7B}\x{5D7C}\x{5D7D}\x{5D7E}\x{5D7F}\x{5D80}\x{5D81}' . '\x{5D82}\x{5D84}\x{5D85}\x{5D86}\x{5D87}\x{5D88}\x{5D89}\x{5D8A}\x{5D8B}' . '\x{5D8C}\x{5D8D}\x{5D8E}\x{5D8F}\x{5D90}\x{5D91}\x{5D92}\x{5D93}\x{5D94}' . '\x{5D95}\x{5D97}\x{5D98}\x{5D99}\x{5D9A}\x{5D9B}\x{5D9C}\x{5D9D}\x{5D9E}' . '\x{5D9F}\x{5DA0}\x{5DA1}\x{5DA2}\x{5DA5}\x{5DA6}\x{5DA7}\x{5DA8}\x{5DA9}' . '\x{5DAA}\x{5DAC}\x{5DAD}\x{5DAE}\x{5DAF}\x{5DB0}\x{5DB1}\x{5DB2}\x{5DB4}' . '\x{5DB5}\x{5DB6}\x{5DB7}\x{5DB8}\x{5DBA}\x{5DBB}\x{5DBC}\x{5DBD}\x{5DBE}' . '\x{5DBF}\x{5DC0}\x{5DC1}\x{5DC2}\x{5DC3}\x{5DC5}\x{5DC6}\x{5DC7}\x{5DC8}' . '\x{5DC9}\x{5DCA}\x{5DCB}\x{5DCC}\x{5DCD}\x{5DCE}\x{5DCF}\x{5DD0}\x{5DD1}' . '\x{5DD2}\x{5DD3}\x{5DD4}\x{5DD5}\x{5DD6}\x{5DD8}\x{5DD9}\x{5DDB}\x{5DDD}' . '\x{5DDE}\x{5DDF}\x{5DE0}\x{5DE1}\x{5DE2}\x{5DE3}\x{5DE4}\x{5DE5}\x{5DE6}' . '\x{5DE7}\x{5DE8}\x{5DE9}\x{5DEA}\x{5DEB}\x{5DEC}\x{5DED}\x{5DEE}\x{5DEF}' . '\x{5DF0}\x{5DF1}\x{5DF2}\x{5DF3}\x{5DF4}\x{5DF5}\x{5DF7}\x{5DF8}\x{5DF9}' . '\x{5DFA}\x{5DFB}\x{5DFC}\x{5DFD}\x{5DFE}\x{5DFF}\x{5E00}\x{5E01}\x{5E02}' . '\x{5E03}\x{5E04}\x{5E05}\x{5E06}\x{5E07}\x{5E08}\x{5E09}\x{5E0A}\x{5E0B}' . '\x{5E0C}\x{5E0D}\x{5E0E}\x{5E0F}\x{5E10}\x{5E11}\x{5E13}\x{5E14}\x{5E15}' . '\x{5E16}\x{5E17}\x{5E18}\x{5E19}\x{5E1A}\x{5E1B}\x{5E1C}\x{5E1D}\x{5E1E}' . '\x{5E1F}\x{5E20}\x{5E21}\x{5E22}\x{5E23}\x{5E24}\x{5E25}\x{5E26}\x{5E27}' . '\x{5E28}\x{5E29}\x{5E2A}\x{5E2B}\x{5E2C}\x{5E2D}\x{5E2E}\x{5E2F}\x{5E30}' . '\x{5E31}\x{5E32}\x{5E33}\x{5E34}\x{5E35}\x{5E36}\x{5E37}\x{5E38}\x{5E39}' . '\x{5E3A}\x{5E3B}\x{5E3C}\x{5E3D}\x{5E3E}\x{5E40}\x{5E41}\x{5E42}\x{5E43}' . '\x{5E44}\x{5E45}\x{5E46}\x{5E47}\x{5E49}\x{5E4A}\x{5E4B}\x{5E4C}\x{5E4D}' . '\x{5E4E}\x{5E4F}\x{5E50}\x{5E52}\x{5E53}\x{5E54}\x{5E55}\x{5E56}\x{5E57}' . '\x{5E58}\x{5E59}\x{5E5A}\x{5E5B}\x{5E5C}\x{5E5D}\x{5E5E}\x{5E5F}\x{5E60}' . '\x{5E61}\x{5E62}\x{5E63}\x{5E64}\x{5E65}\x{5E66}\x{5E67}\x{5E68}\x{5E69}' . '\x{5E6A}\x{5E6B}\x{5E6C}\x{5E6D}\x{5E6E}\x{5E6F}\x{5E70}\x{5E71}\x{5E72}' . '\x{5E73}\x{5E74}\x{5E75}\x{5E76}\x{5E77}\x{5E78}\x{5E79}\x{5E7A}\x{5E7B}' . '\x{5E7C}\x{5E7D}\x{5E7E}\x{5E7F}\x{5E80}\x{5E81}\x{5E82}\x{5E83}\x{5E84}' . '\x{5E85}\x{5E86}\x{5E87}\x{5E88}\x{5E89}\x{5E8A}\x{5E8B}\x{5E8C}\x{5E8D}' . '\x{5E8E}\x{5E8F}\x{5E90}\x{5E91}\x{5E93}\x{5E94}\x{5E95}\x{5E96}\x{5E97}' . '\x{5E98}\x{5E99}\x{5E9A}\x{5E9B}\x{5E9C}\x{5E9D}\x{5E9E}\x{5E9F}\x{5EA0}' . '\x{5EA1}\x{5EA2}\x{5EA3}\x{5EA4}\x{5EA5}\x{5EA6}\x{5EA7}\x{5EA8}\x{5EA9}' . '\x{5EAA}\x{5EAB}\x{5EAC}\x{5EAD}\x{5EAE}\x{5EAF}\x{5EB0}\x{5EB1}\x{5EB2}' . '\x{5EB3}\x{5EB4}\x{5EB5}\x{5EB6}\x{5EB7}\x{5EB8}\x{5EB9}\x{5EBB}\x{5EBC}' . '\x{5EBD}\x{5EBE}\x{5EBF}\x{5EC1}\x{5EC2}\x{5EC3}\x{5EC4}\x{5EC5}\x{5EC6}' . '\x{5EC7}\x{5EC8}\x{5EC9}\x{5ECA}\x{5ECB}\x{5ECC}\x{5ECD}\x{5ECE}\x{5ECF}' . '\x{5ED0}\x{5ED1}\x{5ED2}\x{5ED3}\x{5ED4}\x{5ED5}\x{5ED6}\x{5ED7}\x{5ED8}' . '\x{5ED9}\x{5EDA}\x{5EDB}\x{5EDC}\x{5EDD}\x{5EDE}\x{5EDF}\x{5EE0}\x{5EE1}' . '\x{5EE2}\x{5EE3}\x{5EE4}\x{5EE5}\x{5EE6}\x{5EE7}\x{5EE8}\x{5EE9}\x{5EEA}' . '\x{5EEC}\x{5EED}\x{5EEE}\x{5EEF}\x{5EF0}\x{5EF1}\x{5EF2}\x{5EF3}\x{5EF4}' . '\x{5EF5}\x{5EF6}\x{5EF7}\x{5EF8}\x{5EFA}\x{5EFB}\x{5EFC}\x{5EFD}\x{5EFE}' . '\x{5EFF}\x{5F00}\x{5F01}\x{5F02}\x{5F03}\x{5F04}\x{5F05}\x{5F06}\x{5F07}' . '\x{5F08}\x{5F0A}\x{5F0B}\x{5F0C}\x{5F0D}\x{5F0F}\x{5F11}\x{5F12}\x{5F13}' . '\x{5F14}\x{5F15}\x{5F16}\x{5F17}\x{5F18}\x{5F19}\x{5F1A}\x{5F1B}\x{5F1C}' . '\x{5F1D}\x{5F1E}\x{5F1F}\x{5F20}\x{5F21}\x{5F22}\x{5F23}\x{5F24}\x{5F25}' . '\x{5F26}\x{5F27}\x{5F28}\x{5F29}\x{5F2A}\x{5F2B}\x{5F2C}\x{5F2D}\x{5F2E}' . '\x{5F2F}\x{5F30}\x{5F31}\x{5F32}\x{5F33}\x{5F34}\x{5F35}\x{5F36}\x{5F37}' . '\x{5F38}\x{5F39}\x{5F3A}\x{5F3C}\x{5F3E}\x{5F3F}\x{5F40}\x{5F41}\x{5F42}' . '\x{5F43}\x{5F44}\x{5F45}\x{5F46}\x{5F47}\x{5F48}\x{5F49}\x{5F4A}\x{5F4B}' . '\x{5F4C}\x{5F4D}\x{5F4E}\x{5F4F}\x{5F50}\x{5F51}\x{5F52}\x{5F53}\x{5F54}' . '\x{5F55}\x{5F56}\x{5F57}\x{5F58}\x{5F59}\x{5F5A}\x{5F5B}\x{5F5C}\x{5F5D}' . '\x{5F5E}\x{5F5F}\x{5F60}\x{5F61}\x{5F62}\x{5F63}\x{5F64}\x{5F65}\x{5F66}' . '\x{5F67}\x{5F68}\x{5F69}\x{5F6A}\x{5F6B}\x{5F6C}\x{5F6D}\x{5F6E}\x{5F6F}' . '\x{5F70}\x{5F71}\x{5F72}\x{5F73}\x{5F74}\x{5F75}\x{5F76}\x{5F77}\x{5F78}' . '\x{5F79}\x{5F7A}\x{5F7B}\x{5F7C}\x{5F7D}\x{5F7E}\x{5F7F}\x{5F80}\x{5F81}' . '\x{5F82}\x{5F83}\x{5F84}\x{5F85}\x{5F86}\x{5F87}\x{5F88}\x{5F89}\x{5F8A}' . '\x{5F8B}\x{5F8C}\x{5F8D}\x{5F8E}\x{5F90}\x{5F91}\x{5F92}\x{5F93}\x{5F94}' . '\x{5F95}\x{5F96}\x{5F97}\x{5F98}\x{5F99}\x{5F9B}\x{5F9C}\x{5F9D}\x{5F9E}' . '\x{5F9F}\x{5FA0}\x{5FA1}\x{5FA2}\x{5FA5}\x{5FA6}\x{5FA7}\x{5FA8}\x{5FA9}' . '\x{5FAA}\x{5FAB}\x{5FAC}\x{5FAD}\x{5FAE}\x{5FAF}\x{5FB1}\x{5FB2}\x{5FB3}' . '\x{5FB4}\x{5FB5}\x{5FB6}\x{5FB7}\x{5FB8}\x{5FB9}\x{5FBA}\x{5FBB}\x{5FBC}' . '\x{5FBD}\x{5FBE}\x{5FBF}\x{5FC0}\x{5FC1}\x{5FC3}\x{5FC4}\x{5FC5}\x{5FC6}' . '\x{5FC7}\x{5FC8}\x{5FC9}\x{5FCA}\x{5FCB}\x{5FCC}\x{5FCD}\x{5FCF}\x{5FD0}' . '\x{5FD1}\x{5FD2}\x{5FD3}\x{5FD4}\x{5FD5}\x{5FD6}\x{5FD7}\x{5FD8}\x{5FD9}' . '\x{5FDA}\x{5FDC}\x{5FDD}\x{5FDE}\x{5FE0}\x{5FE1}\x{5FE3}\x{5FE4}\x{5FE5}' . '\x{5FE6}\x{5FE7}\x{5FE8}\x{5FE9}\x{5FEA}\x{5FEB}\x{5FED}\x{5FEE}\x{5FEF}' . '\x{5FF0}\x{5FF1}\x{5FF2}\x{5FF3}\x{5FF4}\x{5FF5}\x{5FF6}\x{5FF7}\x{5FF8}' . '\x{5FF9}\x{5FFA}\x{5FFB}\x{5FFD}\x{5FFE}\x{5FFF}\x{6000}\x{6001}\x{6002}' . '\x{6003}\x{6004}\x{6005}\x{6006}\x{6007}\x{6008}\x{6009}\x{600A}\x{600B}' . '\x{600C}\x{600D}\x{600E}\x{600F}\x{6010}\x{6011}\x{6012}\x{6013}\x{6014}' . '\x{6015}\x{6016}\x{6017}\x{6018}\x{6019}\x{601A}\x{601B}\x{601C}\x{601D}' . '\x{601E}\x{601F}\x{6020}\x{6021}\x{6022}\x{6024}\x{6025}\x{6026}\x{6027}' . '\x{6028}\x{6029}\x{602A}\x{602B}\x{602C}\x{602D}\x{602E}\x{602F}\x{6030}' . '\x{6031}\x{6032}\x{6033}\x{6034}\x{6035}\x{6036}\x{6037}\x{6038}\x{6039}' . '\x{603A}\x{603B}\x{603C}\x{603D}\x{603E}\x{603F}\x{6040}\x{6041}\x{6042}' . '\x{6043}\x{6044}\x{6045}\x{6046}\x{6047}\x{6048}\x{6049}\x{604A}\x{604B}' . '\x{604C}\x{604D}\x{604E}\x{604F}\x{6050}\x{6051}\x{6052}\x{6053}\x{6054}' . '\x{6055}\x{6057}\x{6058}\x{6059}\x{605A}\x{605B}\x{605C}\x{605D}\x{605E}' . '\x{605F}\x{6062}\x{6063}\x{6064}\x{6065}\x{6066}\x{6067}\x{6068}\x{6069}' . '\x{606A}\x{606B}\x{606C}\x{606D}\x{606E}\x{606F}\x{6070}\x{6072}\x{6073}' . '\x{6075}\x{6076}\x{6077}\x{6078}\x{6079}\x{607A}\x{607B}\x{607C}\x{607D}' . '\x{607E}\x{607F}\x{6080}\x{6081}\x{6082}\x{6083}\x{6084}\x{6085}\x{6086}' . '\x{6087}\x{6088}\x{6089}\x{608A}\x{608B}\x{608C}\x{608D}\x{608E}\x{608F}' . '\x{6090}\x{6092}\x{6094}\x{6095}\x{6096}\x{6097}\x{6098}\x{6099}\x{609A}' . '\x{609B}\x{609C}\x{609D}\x{609E}\x{609F}\x{60A0}\x{60A1}\x{60A2}\x{60A3}' . '\x{60A4}\x{60A6}\x{60A7}\x{60A8}\x{60AA}\x{60AB}\x{60AC}\x{60AD}\x{60AE}' . '\x{60AF}\x{60B0}\x{60B1}\x{60B2}\x{60B3}\x{60B4}\x{60B5}\x{60B6}\x{60B7}' . '\x{60B8}\x{60B9}\x{60BA}\x{60BB}\x{60BC}\x{60BD}\x{60BE}\x{60BF}\x{60C0}' . '\x{60C1}\x{60C2}\x{60C3}\x{60C4}\x{60C5}\x{60C6}\x{60C7}\x{60C8}\x{60C9}' . '\x{60CA}\x{60CB}\x{60CC}\x{60CD}\x{60CE}\x{60CF}\x{60D0}\x{60D1}\x{60D3}' . '\x{60D4}\x{60D5}\x{60D7}\x{60D8}\x{60D9}\x{60DA}\x{60DB}\x{60DC}\x{60DD}' . '\x{60DF}\x{60E0}\x{60E1}\x{60E2}\x{60E4}\x{60E6}\x{60E7}\x{60E8}\x{60E9}' . '\x{60EA}\x{60EB}\x{60EC}\x{60ED}\x{60EE}\x{60EF}\x{60F0}\x{60F1}\x{60F2}' . '\x{60F3}\x{60F4}\x{60F5}\x{60F6}\x{60F7}\x{60F8}\x{60F9}\x{60FA}\x{60FB}' . '\x{60FC}\x{60FE}\x{60FF}\x{6100}\x{6101}\x{6103}\x{6104}\x{6105}\x{6106}' . '\x{6108}\x{6109}\x{610A}\x{610B}\x{610C}\x{610D}\x{610E}\x{610F}\x{6110}' . '\x{6112}\x{6113}\x{6114}\x{6115}\x{6116}\x{6117}\x{6118}\x{6119}\x{611A}' . '\x{611B}\x{611C}\x{611D}\x{611F}\x{6120}\x{6122}\x{6123}\x{6124}\x{6125}' . '\x{6126}\x{6127}\x{6128}\x{6129}\x{612A}\x{612B}\x{612C}\x{612D}\x{612E}' . '\x{612F}\x{6130}\x{6132}\x{6134}\x{6136}\x{6137}\x{613A}\x{613B}\x{613C}' . '\x{613D}\x{613E}\x{613F}\x{6140}\x{6141}\x{6142}\x{6143}\x{6144}\x{6145}' . '\x{6146}\x{6147}\x{6148}\x{6149}\x{614A}\x{614B}\x{614C}\x{614D}\x{614E}' . '\x{614F}\x{6150}\x{6151}\x{6152}\x{6153}\x{6154}\x{6155}\x{6156}\x{6157}' . '\x{6158}\x{6159}\x{615A}\x{615B}\x{615C}\x{615D}\x{615E}\x{615F}\x{6161}' . '\x{6162}\x{6163}\x{6164}\x{6165}\x{6166}\x{6167}\x{6168}\x{6169}\x{616A}' . '\x{616B}\x{616C}\x{616D}\x{616E}\x{6170}\x{6171}\x{6172}\x{6173}\x{6174}' . '\x{6175}\x{6176}\x{6177}\x{6178}\x{6179}\x{617A}\x{617C}\x{617E}\x{6180}' . '\x{6181}\x{6182}\x{6183}\x{6184}\x{6185}\x{6187}\x{6188}\x{6189}\x{618A}' . '\x{618B}\x{618C}\x{618D}\x{618E}\x{618F}\x{6190}\x{6191}\x{6192}\x{6193}' . '\x{6194}\x{6195}\x{6196}\x{6198}\x{6199}\x{619A}\x{619B}\x{619D}\x{619E}' . '\x{619F}\x{61A0}\x{61A1}\x{61A2}\x{61A3}\x{61A4}\x{61A5}\x{61A6}\x{61A7}' . '\x{61A8}\x{61A9}\x{61AA}\x{61AB}\x{61AC}\x{61AD}\x{61AE}\x{61AF}\x{61B0}' . '\x{61B1}\x{61B2}\x{61B3}\x{61B4}\x{61B5}\x{61B6}\x{61B7}\x{61B8}\x{61BA}' . '\x{61BC}\x{61BD}\x{61BE}\x{61BF}\x{61C0}\x{61C1}\x{61C2}\x{61C3}\x{61C4}' . '\x{61C5}\x{61C6}\x{61C7}\x{61C8}\x{61C9}\x{61CA}\x{61CB}\x{61CC}\x{61CD}' . '\x{61CE}\x{61CF}\x{61D0}\x{61D1}\x{61D2}\x{61D4}\x{61D6}\x{61D7}\x{61D8}' . '\x{61D9}\x{61DA}\x{61DB}\x{61DC}\x{61DD}\x{61DE}\x{61DF}\x{61E0}\x{61E1}' . '\x{61E2}\x{61E3}\x{61E4}\x{61E5}\x{61E6}\x{61E7}\x{61E8}\x{61E9}\x{61EA}' . '\x{61EB}\x{61ED}\x{61EE}\x{61F0}\x{61F1}\x{61F2}\x{61F3}\x{61F5}\x{61F6}' . '\x{61F7}\x{61F8}\x{61F9}\x{61FA}\x{61FB}\x{61FC}\x{61FD}\x{61FE}\x{61FF}' . '\x{6200}\x{6201}\x{6202}\x{6203}\x{6204}\x{6206}\x{6207}\x{6208}\x{6209}' . '\x{620A}\x{620B}\x{620C}\x{620D}\x{620E}\x{620F}\x{6210}\x{6211}\x{6212}' . '\x{6213}\x{6214}\x{6215}\x{6216}\x{6217}\x{6218}\x{6219}\x{621A}\x{621B}' . '\x{621C}\x{621D}\x{621E}\x{621F}\x{6220}\x{6221}\x{6222}\x{6223}\x{6224}' . '\x{6225}\x{6226}\x{6227}\x{6228}\x{6229}\x{622A}\x{622B}\x{622C}\x{622D}' . '\x{622E}\x{622F}\x{6230}\x{6231}\x{6232}\x{6233}\x{6234}\x{6236}\x{6237}' . '\x{6238}\x{623A}\x{623B}\x{623C}\x{623D}\x{623E}\x{623F}\x{6240}\x{6241}' . '\x{6242}\x{6243}\x{6244}\x{6245}\x{6246}\x{6247}\x{6248}\x{6249}\x{624A}' . '\x{624B}\x{624C}\x{624D}\x{624E}\x{624F}\x{6250}\x{6251}\x{6252}\x{6253}' . '\x{6254}\x{6255}\x{6256}\x{6258}\x{6259}\x{625A}\x{625B}\x{625C}\x{625D}' . '\x{625E}\x{625F}\x{6260}\x{6261}\x{6262}\x{6263}\x{6264}\x{6265}\x{6266}' . '\x{6267}\x{6268}\x{6269}\x{626A}\x{626B}\x{626C}\x{626D}\x{626E}\x{626F}' . '\x{6270}\x{6271}\x{6272}\x{6273}\x{6274}\x{6275}\x{6276}\x{6277}\x{6278}' . '\x{6279}\x{627A}\x{627B}\x{627C}\x{627D}\x{627E}\x{627F}\x{6280}\x{6281}' . '\x{6283}\x{6284}\x{6285}\x{6286}\x{6287}\x{6288}\x{6289}\x{628A}\x{628B}' . '\x{628C}\x{628E}\x{628F}\x{6290}\x{6291}\x{6292}\x{6293}\x{6294}\x{6295}' . '\x{6296}\x{6297}\x{6298}\x{6299}\x{629A}\x{629B}\x{629C}\x{629E}\x{629F}' . '\x{62A0}\x{62A1}\x{62A2}\x{62A3}\x{62A4}\x{62A5}\x{62A7}\x{62A8}\x{62A9}' . '\x{62AA}\x{62AB}\x{62AC}\x{62AD}\x{62AE}\x{62AF}\x{62B0}\x{62B1}\x{62B2}' . '\x{62B3}\x{62B4}\x{62B5}\x{62B6}\x{62B7}\x{62B8}\x{62B9}\x{62BA}\x{62BB}' . '\x{62BC}\x{62BD}\x{62BE}\x{62BF}\x{62C0}\x{62C1}\x{62C2}\x{62C3}\x{62C4}' . '\x{62C5}\x{62C6}\x{62C7}\x{62C8}\x{62C9}\x{62CA}\x{62CB}\x{62CC}\x{62CD}' . '\x{62CE}\x{62CF}\x{62D0}\x{62D1}\x{62D2}\x{62D3}\x{62D4}\x{62D5}\x{62D6}' . '\x{62D7}\x{62D8}\x{62D9}\x{62DA}\x{62DB}\x{62DC}\x{62DD}\x{62DF}\x{62E0}' . '\x{62E1}\x{62E2}\x{62E3}\x{62E4}\x{62E5}\x{62E6}\x{62E7}\x{62E8}\x{62E9}' . '\x{62EB}\x{62EC}\x{62ED}\x{62EE}\x{62EF}\x{62F0}\x{62F1}\x{62F2}\x{62F3}' . '\x{62F4}\x{62F5}\x{62F6}\x{62F7}\x{62F8}\x{62F9}\x{62FA}\x{62FB}\x{62FC}' . '\x{62FD}\x{62FE}\x{62FF}\x{6300}\x{6301}\x{6302}\x{6303}\x{6304}\x{6305}' . '\x{6306}\x{6307}\x{6308}\x{6309}\x{630B}\x{630C}\x{630D}\x{630E}\x{630F}' . '\x{6310}\x{6311}\x{6312}\x{6313}\x{6314}\x{6315}\x{6316}\x{6318}\x{6319}' . '\x{631A}\x{631B}\x{631C}\x{631D}\x{631E}\x{631F}\x{6320}\x{6321}\x{6322}' . '\x{6323}\x{6324}\x{6325}\x{6326}\x{6327}\x{6328}\x{6329}\x{632A}\x{632B}' . '\x{632C}\x{632D}\x{632E}\x{632F}\x{6330}\x{6332}\x{6333}\x{6334}\x{6336}' . '\x{6338}\x{6339}\x{633A}\x{633B}\x{633C}\x{633D}\x{633E}\x{6340}\x{6341}' . '\x{6342}\x{6343}\x{6344}\x{6345}\x{6346}\x{6347}\x{6348}\x{6349}\x{634A}' . '\x{634B}\x{634C}\x{634D}\x{634E}\x{634F}\x{6350}\x{6351}\x{6352}\x{6353}' . '\x{6354}\x{6355}\x{6356}\x{6357}\x{6358}\x{6359}\x{635A}\x{635C}\x{635D}' . '\x{635E}\x{635F}\x{6360}\x{6361}\x{6362}\x{6363}\x{6364}\x{6365}\x{6366}' . '\x{6367}\x{6368}\x{6369}\x{636A}\x{636B}\x{636C}\x{636D}\x{636E}\x{636F}' . '\x{6370}\x{6371}\x{6372}\x{6373}\x{6374}\x{6375}\x{6376}\x{6377}\x{6378}' . '\x{6379}\x{637A}\x{637B}\x{637C}\x{637D}\x{637E}\x{6380}\x{6381}\x{6382}' . '\x{6383}\x{6384}\x{6385}\x{6386}\x{6387}\x{6388}\x{6389}\x{638A}\x{638C}' . '\x{638D}\x{638E}\x{638F}\x{6390}\x{6391}\x{6392}\x{6394}\x{6395}\x{6396}' . '\x{6397}\x{6398}\x{6399}\x{639A}\x{639B}\x{639C}\x{639D}\x{639E}\x{639F}' . '\x{63A0}\x{63A1}\x{63A2}\x{63A3}\x{63A4}\x{63A5}\x{63A6}\x{63A7}\x{63A8}' . '\x{63A9}\x{63AA}\x{63AB}\x{63AC}\x{63AD}\x{63AE}\x{63AF}\x{63B0}\x{63B1}' . '\x{63B2}\x{63B3}\x{63B4}\x{63B5}\x{63B6}\x{63B7}\x{63B8}\x{63B9}\x{63BA}' . '\x{63BC}\x{63BD}\x{63BE}\x{63BF}\x{63C0}\x{63C1}\x{63C2}\x{63C3}\x{63C4}' . '\x{63C5}\x{63C6}\x{63C7}\x{63C8}\x{63C9}\x{63CA}\x{63CB}\x{63CC}\x{63CD}' . '\x{63CE}\x{63CF}\x{63D0}\x{63D2}\x{63D3}\x{63D4}\x{63D5}\x{63D6}\x{63D7}' . '\x{63D8}\x{63D9}\x{63DA}\x{63DB}\x{63DC}\x{63DD}\x{63DE}\x{63DF}\x{63E0}' . '\x{63E1}\x{63E2}\x{63E3}\x{63E4}\x{63E5}\x{63E6}\x{63E7}\x{63E8}\x{63E9}' . '\x{63EA}\x{63EB}\x{63EC}\x{63ED}\x{63EE}\x{63EF}\x{63F0}\x{63F1}\x{63F2}' . '\x{63F3}\x{63F4}\x{63F5}\x{63F6}\x{63F7}\x{63F8}\x{63F9}\x{63FA}\x{63FB}' . '\x{63FC}\x{63FD}\x{63FE}\x{63FF}\x{6400}\x{6401}\x{6402}\x{6403}\x{6404}' . '\x{6405}\x{6406}\x{6408}\x{6409}\x{640A}\x{640B}\x{640C}\x{640D}\x{640E}' . '\x{640F}\x{6410}\x{6411}\x{6412}\x{6413}\x{6414}\x{6415}\x{6416}\x{6417}' . '\x{6418}\x{6419}\x{641A}\x{641B}\x{641C}\x{641D}\x{641E}\x{641F}\x{6420}' . '\x{6421}\x{6422}\x{6423}\x{6424}\x{6425}\x{6426}\x{6427}\x{6428}\x{6429}' . '\x{642A}\x{642B}\x{642C}\x{642D}\x{642E}\x{642F}\x{6430}\x{6431}\x{6432}' . '\x{6433}\x{6434}\x{6435}\x{6436}\x{6437}\x{6438}\x{6439}\x{643A}\x{643D}' . '\x{643E}\x{643F}\x{6440}\x{6441}\x{6443}\x{6444}\x{6445}\x{6446}\x{6447}' . '\x{6448}\x{644A}\x{644B}\x{644C}\x{644D}\x{644E}\x{644F}\x{6450}\x{6451}' . '\x{6452}\x{6453}\x{6454}\x{6455}\x{6456}\x{6457}\x{6458}\x{6459}\x{645B}' . '\x{645C}\x{645D}\x{645E}\x{645F}\x{6460}\x{6461}\x{6462}\x{6463}\x{6464}' . '\x{6465}\x{6466}\x{6467}\x{6468}\x{6469}\x{646A}\x{646B}\x{646C}\x{646D}' . '\x{646E}\x{646F}\x{6470}\x{6471}\x{6472}\x{6473}\x{6474}\x{6475}\x{6476}' . '\x{6477}\x{6478}\x{6479}\x{647A}\x{647B}\x{647C}\x{647D}\x{647F}\x{6480}' . '\x{6481}\x{6482}\x{6483}\x{6484}\x{6485}\x{6487}\x{6488}\x{6489}\x{648A}' . '\x{648B}\x{648C}\x{648D}\x{648E}\x{648F}\x{6490}\x{6491}\x{6492}\x{6493}' . '\x{6494}\x{6495}\x{6496}\x{6497}\x{6498}\x{6499}\x{649A}\x{649B}\x{649C}' . '\x{649D}\x{649E}\x{649F}\x{64A0}\x{64A2}\x{64A3}\x{64A4}\x{64A5}\x{64A6}' . '\x{64A7}\x{64A8}\x{64A9}\x{64AA}\x{64AB}\x{64AC}\x{64AD}\x{64AE}\x{64B0}' . '\x{64B1}\x{64B2}\x{64B3}\x{64B4}\x{64B5}\x{64B7}\x{64B8}\x{64B9}\x{64BA}' . '\x{64BB}\x{64BC}\x{64BD}\x{64BE}\x{64BF}\x{64C0}\x{64C1}\x{64C2}\x{64C3}' . '\x{64C4}\x{64C5}\x{64C6}\x{64C7}\x{64C9}\x{64CA}\x{64CB}\x{64CC}\x{64CD}' . '\x{64CE}\x{64CF}\x{64D0}\x{64D1}\x{64D2}\x{64D3}\x{64D4}\x{64D6}\x{64D7}' . '\x{64D8}\x{64D9}\x{64DA}\x{64DB}\x{64DC}\x{64DD}\x{64DE}\x{64DF}\x{64E0}' . '\x{64E2}\x{64E3}\x{64E4}\x{64E6}\x{64E7}\x{64E8}\x{64E9}\x{64EA}\x{64EB}' . '\x{64EC}\x{64ED}\x{64EF}\x{64F0}\x{64F1}\x{64F2}\x{64F3}\x{64F4}\x{64F6}' . '\x{64F7}\x{64F8}\x{64FA}\x{64FB}\x{64FC}\x{64FD}\x{64FE}\x{64FF}\x{6500}' . '\x{6501}\x{6503}\x{6504}\x{6505}\x{6506}\x{6507}\x{6508}\x{6509}\x{650B}' . '\x{650C}\x{650D}\x{650E}\x{650F}\x{6510}\x{6511}\x{6512}\x{6513}\x{6514}' . '\x{6515}\x{6516}\x{6517}\x{6518}\x{6519}\x{651A}\x{651B}\x{651C}\x{651D}' . '\x{651E}\x{6520}\x{6521}\x{6522}\x{6523}\x{6524}\x{6525}\x{6526}\x{6527}' . '\x{6529}\x{652A}\x{652B}\x{652C}\x{652D}\x{652E}\x{652F}\x{6530}\x{6531}' . '\x{6532}\x{6533}\x{6534}\x{6535}\x{6536}\x{6537}\x{6538}\x{6539}\x{653A}' . '\x{653B}\x{653C}\x{653D}\x{653E}\x{653F}\x{6541}\x{6543}\x{6544}\x{6545}' . '\x{6546}\x{6547}\x{6548}\x{6549}\x{654A}\x{654B}\x{654C}\x{654D}\x{654E}' . '\x{654F}\x{6550}\x{6551}\x{6552}\x{6553}\x{6554}\x{6555}\x{6556}\x{6557}' . '\x{6558}\x{6559}\x{655B}\x{655C}\x{655D}\x{655E}\x{6560}\x{6561}\x{6562}' . '\x{6563}\x{6564}\x{6565}\x{6566}\x{6567}\x{6568}\x{6569}\x{656A}\x{656B}' . '\x{656C}\x{656E}\x{656F}\x{6570}\x{6571}\x{6572}\x{6573}\x{6574}\x{6575}' . '\x{6576}\x{6577}\x{6578}\x{6579}\x{657A}\x{657B}\x{657C}\x{657E}\x{657F}' . '\x{6580}\x{6581}\x{6582}\x{6583}\x{6584}\x{6585}\x{6586}\x{6587}\x{6588}' . '\x{6589}\x{658B}\x{658C}\x{658D}\x{658E}\x{658F}\x{6590}\x{6591}\x{6592}' . '\x{6593}\x{6594}\x{6595}\x{6596}\x{6597}\x{6598}\x{6599}\x{659B}\x{659C}' . '\x{659D}\x{659E}\x{659F}\x{65A0}\x{65A1}\x{65A2}\x{65A3}\x{65A4}\x{65A5}' . '\x{65A6}\x{65A7}\x{65A8}\x{65A9}\x{65AA}\x{65AB}\x{65AC}\x{65AD}\x{65AE}' . '\x{65AF}\x{65B0}\x{65B1}\x{65B2}\x{65B3}\x{65B4}\x{65B6}\x{65B7}\x{65B8}' . '\x{65B9}\x{65BA}\x{65BB}\x{65BC}\x{65BD}\x{65BF}\x{65C0}\x{65C1}\x{65C2}' . '\x{65C3}\x{65C4}\x{65C5}\x{65C6}\x{65C7}\x{65CA}\x{65CB}\x{65CC}\x{65CD}' . '\x{65CE}\x{65CF}\x{65D0}\x{65D2}\x{65D3}\x{65D4}\x{65D5}\x{65D6}\x{65D7}' . '\x{65DA}\x{65DB}\x{65DD}\x{65DE}\x{65DF}\x{65E0}\x{65E1}\x{65E2}\x{65E3}' . '\x{65E5}\x{65E6}\x{65E7}\x{65E8}\x{65E9}\x{65EB}\x{65EC}\x{65ED}\x{65EE}' . '\x{65EF}\x{65F0}\x{65F1}\x{65F2}\x{65F3}\x{65F4}\x{65F5}\x{65F6}\x{65F7}' . '\x{65F8}\x{65FA}\x{65FB}\x{65FC}\x{65FD}\x{6600}\x{6601}\x{6602}\x{6603}' . '\x{6604}\x{6605}\x{6606}\x{6607}\x{6608}\x{6609}\x{660A}\x{660B}\x{660C}' . '\x{660D}\x{660E}\x{660F}\x{6610}\x{6611}\x{6612}\x{6613}\x{6614}\x{6615}' . '\x{6616}\x{6618}\x{6619}\x{661A}\x{661B}\x{661C}\x{661D}\x{661F}\x{6620}' . '\x{6621}\x{6622}\x{6623}\x{6624}\x{6625}\x{6626}\x{6627}\x{6628}\x{6629}' . '\x{662A}\x{662B}\x{662D}\x{662E}\x{662F}\x{6630}\x{6631}\x{6632}\x{6633}' . '\x{6634}\x{6635}\x{6636}\x{6639}\x{663A}\x{663C}\x{663D}\x{663E}\x{6640}' . '\x{6641}\x{6642}\x{6643}\x{6644}\x{6645}\x{6646}\x{6647}\x{6649}\x{664A}' . '\x{664B}\x{664C}\x{664E}\x{664F}\x{6650}\x{6651}\x{6652}\x{6653}\x{6654}' . '\x{6655}\x{6656}\x{6657}\x{6658}\x{6659}\x{665A}\x{665B}\x{665C}\x{665D}' . '\x{665E}\x{665F}\x{6661}\x{6662}\x{6664}\x{6665}\x{6666}\x{6668}\x{6669}' . '\x{666A}\x{666B}\x{666C}\x{666D}\x{666E}\x{666F}\x{6670}\x{6671}\x{6672}' . '\x{6673}\x{6674}\x{6675}\x{6676}\x{6677}\x{6678}\x{6679}\x{667A}\x{667B}' . '\x{667C}\x{667D}\x{667E}\x{667F}\x{6680}\x{6681}\x{6682}\x{6683}\x{6684}' . '\x{6685}\x{6686}\x{6687}\x{6688}\x{6689}\x{668A}\x{668B}\x{668C}\x{668D}' . '\x{668E}\x{668F}\x{6690}\x{6691}\x{6693}\x{6694}\x{6695}\x{6696}\x{6697}' . '\x{6698}\x{6699}\x{669A}\x{669B}\x{669D}\x{669F}\x{66A0}\x{66A1}\x{66A2}' . '\x{66A3}\x{66A4}\x{66A5}\x{66A6}\x{66A7}\x{66A8}\x{66A9}\x{66AA}\x{66AB}' . '\x{66AE}\x{66AF}\x{66B0}\x{66B1}\x{66B2}\x{66B3}\x{66B4}\x{66B5}\x{66B6}' . '\x{66B7}\x{66B8}\x{66B9}\x{66BA}\x{66BB}\x{66BC}\x{66BD}\x{66BE}\x{66BF}' . '\x{66C0}\x{66C1}\x{66C2}\x{66C3}\x{66C4}\x{66C5}\x{66C6}\x{66C7}\x{66C8}' . '\x{66C9}\x{66CA}\x{66CB}\x{66CC}\x{66CD}\x{66CE}\x{66CF}\x{66D1}\x{66D2}' . '\x{66D4}\x{66D5}\x{66D6}\x{66D8}\x{66D9}\x{66DA}\x{66DB}\x{66DC}\x{66DD}' . '\x{66DE}\x{66E0}\x{66E1}\x{66E2}\x{66E3}\x{66E4}\x{66E5}\x{66E6}\x{66E7}' . '\x{66E8}\x{66E9}\x{66EA}\x{66EB}\x{66EC}\x{66ED}\x{66EE}\x{66F0}\x{66F1}' . '\x{66F2}\x{66F3}\x{66F4}\x{66F5}\x{66F6}\x{66F7}\x{66F8}\x{66F9}\x{66FA}' . '\x{66FB}\x{66FC}\x{66FE}\x{66FF}\x{6700}\x{6701}\x{6703}\x{6704}\x{6705}' . '\x{6706}\x{6708}\x{6709}\x{670A}\x{670B}\x{670C}\x{670D}\x{670E}\x{670F}' . '\x{6710}\x{6711}\x{6712}\x{6713}\x{6714}\x{6715}\x{6716}\x{6717}\x{6718}' . '\x{671A}\x{671B}\x{671C}\x{671D}\x{671E}\x{671F}\x{6720}\x{6721}\x{6722}' . '\x{6723}\x{6725}\x{6726}\x{6727}\x{6728}\x{672A}\x{672B}\x{672C}\x{672D}' . '\x{672E}\x{672F}\x{6730}\x{6731}\x{6732}\x{6733}\x{6734}\x{6735}\x{6736}' . '\x{6737}\x{6738}\x{6739}\x{673A}\x{673B}\x{673C}\x{673D}\x{673E}\x{673F}' . '\x{6740}\x{6741}\x{6742}\x{6743}\x{6744}\x{6745}\x{6746}\x{6747}\x{6748}' . '\x{6749}\x{674A}\x{674B}\x{674C}\x{674D}\x{674E}\x{674F}\x{6750}\x{6751}' . '\x{6752}\x{6753}\x{6754}\x{6755}\x{6756}\x{6757}\x{6758}\x{6759}\x{675A}' . '\x{675B}\x{675C}\x{675D}\x{675E}\x{675F}\x{6760}\x{6761}\x{6762}\x{6763}' . '\x{6764}\x{6765}\x{6766}\x{6768}\x{6769}\x{676A}\x{676B}\x{676C}\x{676D}' . '\x{676E}\x{676F}\x{6770}\x{6771}\x{6772}\x{6773}\x{6774}\x{6775}\x{6776}' . '\x{6777}\x{6778}\x{6779}\x{677A}\x{677B}\x{677C}\x{677D}\x{677E}\x{677F}' . '\x{6780}\x{6781}\x{6782}\x{6783}\x{6784}\x{6785}\x{6786}\x{6787}\x{6789}' . '\x{678A}\x{678B}\x{678C}\x{678D}\x{678E}\x{678F}\x{6790}\x{6791}\x{6792}' . '\x{6793}\x{6794}\x{6795}\x{6797}\x{6798}\x{6799}\x{679A}\x{679B}\x{679C}' . '\x{679D}\x{679E}\x{679F}\x{67A0}\x{67A1}\x{67A2}\x{67A3}\x{67A4}\x{67A5}' . '\x{67A6}\x{67A7}\x{67A8}\x{67AA}\x{67AB}\x{67AC}\x{67AD}\x{67AE}\x{67AF}' . '\x{67B0}\x{67B1}\x{67B2}\x{67B3}\x{67B4}\x{67B5}\x{67B6}\x{67B7}\x{67B8}' . '\x{67B9}\x{67BA}\x{67BB}\x{67BC}\x{67BE}\x{67C0}\x{67C1}\x{67C2}\x{67C3}' . '\x{67C4}\x{67C5}\x{67C6}\x{67C7}\x{67C8}\x{67C9}\x{67CA}\x{67CB}\x{67CC}' . '\x{67CD}\x{67CE}\x{67CF}\x{67D0}\x{67D1}\x{67D2}\x{67D3}\x{67D4}\x{67D6}' . '\x{67D8}\x{67D9}\x{67DA}\x{67DB}\x{67DC}\x{67DD}\x{67DE}\x{67DF}\x{67E0}' . '\x{67E1}\x{67E2}\x{67E3}\x{67E4}\x{67E5}\x{67E6}\x{67E7}\x{67E8}\x{67E9}' . '\x{67EA}\x{67EB}\x{67EC}\x{67ED}\x{67EE}\x{67EF}\x{67F0}\x{67F1}\x{67F2}' . '\x{67F3}\x{67F4}\x{67F5}\x{67F6}\x{67F7}\x{67F8}\x{67FA}\x{67FB}\x{67FC}' . '\x{67FD}\x{67FE}\x{67FF}\x{6800}\x{6802}\x{6803}\x{6804}\x{6805}\x{6806}' . '\x{6807}\x{6808}\x{6809}\x{680A}\x{680B}\x{680C}\x{680D}\x{680E}\x{680F}' . '\x{6810}\x{6811}\x{6812}\x{6813}\x{6814}\x{6816}\x{6817}\x{6818}\x{6819}' . '\x{681A}\x{681B}\x{681C}\x{681D}\x{681F}\x{6820}\x{6821}\x{6822}\x{6823}' . '\x{6824}\x{6825}\x{6826}\x{6828}\x{6829}\x{682A}\x{682B}\x{682C}\x{682D}' . '\x{682E}\x{682F}\x{6831}\x{6832}\x{6833}\x{6834}\x{6835}\x{6836}\x{6837}' . '\x{6838}\x{6839}\x{683A}\x{683B}\x{683C}\x{683D}\x{683E}\x{683F}\x{6840}' . '\x{6841}\x{6842}\x{6843}\x{6844}\x{6845}\x{6846}\x{6847}\x{6848}\x{6849}' . '\x{684A}\x{684B}\x{684C}\x{684D}\x{684E}\x{684F}\x{6850}\x{6851}\x{6852}' . '\x{6853}\x{6854}\x{6855}\x{6856}\x{6857}\x{685B}\x{685D}\x{6860}\x{6861}' . '\x{6862}\x{6863}\x{6864}\x{6865}\x{6866}\x{6867}\x{6868}\x{6869}\x{686A}' . '\x{686B}\x{686C}\x{686D}\x{686E}\x{686F}\x{6870}\x{6871}\x{6872}\x{6873}' . '\x{6874}\x{6875}\x{6876}\x{6877}\x{6878}\x{6879}\x{687B}\x{687C}\x{687D}' . '\x{687E}\x{687F}\x{6880}\x{6881}\x{6882}\x{6883}\x{6884}\x{6885}\x{6886}' . '\x{6887}\x{6888}\x{6889}\x{688A}\x{688B}\x{688C}\x{688D}\x{688E}\x{688F}' . '\x{6890}\x{6891}\x{6892}\x{6893}\x{6894}\x{6896}\x{6897}\x{6898}\x{689A}' . '\x{689B}\x{689C}\x{689D}\x{689E}\x{689F}\x{68A0}\x{68A1}\x{68A2}\x{68A3}' . '\x{68A4}\x{68A6}\x{68A7}\x{68A8}\x{68A9}\x{68AA}\x{68AB}\x{68AC}\x{68AD}' . '\x{68AE}\x{68AF}\x{68B0}\x{68B1}\x{68B2}\x{68B3}\x{68B4}\x{68B5}\x{68B6}' . '\x{68B7}\x{68B9}\x{68BB}\x{68BC}\x{68BD}\x{68BE}\x{68BF}\x{68C0}\x{68C1}' . '\x{68C2}\x{68C4}\x{68C6}\x{68C7}\x{68C8}\x{68C9}\x{68CA}\x{68CB}\x{68CC}' . '\x{68CD}\x{68CE}\x{68CF}\x{68D0}\x{68D1}\x{68D2}\x{68D3}\x{68D4}\x{68D5}' . '\x{68D6}\x{68D7}\x{68D8}\x{68DA}\x{68DB}\x{68DC}\x{68DD}\x{68DE}\x{68DF}' . '\x{68E0}\x{68E1}\x{68E3}\x{68E4}\x{68E6}\x{68E7}\x{68E8}\x{68E9}\x{68EA}' . '\x{68EB}\x{68EC}\x{68ED}\x{68EE}\x{68EF}\x{68F0}\x{68F1}\x{68F2}\x{68F3}' . '\x{68F4}\x{68F5}\x{68F6}\x{68F7}\x{68F8}\x{68F9}\x{68FA}\x{68FB}\x{68FC}' . '\x{68FD}\x{68FE}\x{68FF}\x{6901}\x{6902}\x{6903}\x{6904}\x{6905}\x{6906}' . '\x{6907}\x{6908}\x{690A}\x{690B}\x{690C}\x{690D}\x{690E}\x{690F}\x{6910}' . '\x{6911}\x{6912}\x{6913}\x{6914}\x{6915}\x{6916}\x{6917}\x{6918}\x{6919}' . '\x{691A}\x{691B}\x{691C}\x{691D}\x{691E}\x{691F}\x{6920}\x{6921}\x{6922}' . '\x{6923}\x{6924}\x{6925}\x{6926}\x{6927}\x{6928}\x{6929}\x{692A}\x{692B}' . '\x{692C}\x{692D}\x{692E}\x{692F}\x{6930}\x{6931}\x{6932}\x{6933}\x{6934}' . '\x{6935}\x{6936}\x{6937}\x{6938}\x{6939}\x{693A}\x{693B}\x{693C}\x{693D}' . '\x{693F}\x{6940}\x{6941}\x{6942}\x{6943}\x{6944}\x{6945}\x{6946}\x{6947}' . '\x{6948}\x{6949}\x{694A}\x{694B}\x{694C}\x{694E}\x{694F}\x{6950}\x{6951}' . '\x{6952}\x{6953}\x{6954}\x{6955}\x{6956}\x{6957}\x{6958}\x{6959}\x{695A}' . '\x{695B}\x{695C}\x{695D}\x{695E}\x{695F}\x{6960}\x{6961}\x{6962}\x{6963}' . '\x{6964}\x{6965}\x{6966}\x{6967}\x{6968}\x{6969}\x{696A}\x{696B}\x{696C}' . '\x{696D}\x{696E}\x{696F}\x{6970}\x{6971}\x{6972}\x{6973}\x{6974}\x{6975}' . '\x{6976}\x{6977}\x{6978}\x{6979}\x{697A}\x{697B}\x{697C}\x{697D}\x{697E}' . '\x{697F}\x{6980}\x{6981}\x{6982}\x{6983}\x{6984}\x{6985}\x{6986}\x{6987}' . '\x{6988}\x{6989}\x{698A}\x{698B}\x{698C}\x{698D}\x{698E}\x{698F}\x{6990}' . '\x{6991}\x{6992}\x{6993}\x{6994}\x{6995}\x{6996}\x{6997}\x{6998}\x{6999}' . '\x{699A}\x{699B}\x{699C}\x{699D}\x{699E}\x{69A0}\x{69A1}\x{69A3}\x{69A4}' . '\x{69A5}\x{69A6}\x{69A7}\x{69A8}\x{69A9}\x{69AA}\x{69AB}\x{69AC}\x{69AD}' . '\x{69AE}\x{69AF}\x{69B0}\x{69B1}\x{69B2}\x{69B3}\x{69B4}\x{69B5}\x{69B6}' . '\x{69B7}\x{69B8}\x{69B9}\x{69BA}\x{69BB}\x{69BC}\x{69BD}\x{69BE}\x{69BF}' . '\x{69C1}\x{69C2}\x{69C3}\x{69C4}\x{69C5}\x{69C6}\x{69C7}\x{69C8}\x{69C9}' . '\x{69CA}\x{69CB}\x{69CC}\x{69CD}\x{69CE}\x{69CF}\x{69D0}\x{69D3}\x{69D4}' . '\x{69D8}\x{69D9}\x{69DA}\x{69DB}\x{69DC}\x{69DD}\x{69DE}\x{69DF}\x{69E0}' . '\x{69E1}\x{69E2}\x{69E3}\x{69E4}\x{69E5}\x{69E6}\x{69E7}\x{69E8}\x{69E9}' . '\x{69EA}\x{69EB}\x{69EC}\x{69ED}\x{69EE}\x{69EF}\x{69F0}\x{69F1}\x{69F2}' . '\x{69F3}\x{69F4}\x{69F5}\x{69F6}\x{69F7}\x{69F8}\x{69FA}\x{69FB}\x{69FC}' . '\x{69FD}\x{69FE}\x{69FF}\x{6A00}\x{6A01}\x{6A02}\x{6A04}\x{6A05}\x{6A06}' . '\x{6A07}\x{6A08}\x{6A09}\x{6A0A}\x{6A0B}\x{6A0D}\x{6A0E}\x{6A0F}\x{6A10}' . '\x{6A11}\x{6A12}\x{6A13}\x{6A14}\x{6A15}\x{6A16}\x{6A17}\x{6A18}\x{6A19}' . '\x{6A1A}\x{6A1B}\x{6A1D}\x{6A1E}\x{6A1F}\x{6A20}\x{6A21}\x{6A22}\x{6A23}' . '\x{6A25}\x{6A26}\x{6A27}\x{6A28}\x{6A29}\x{6A2A}\x{6A2B}\x{6A2C}\x{6A2D}' . '\x{6A2E}\x{6A2F}\x{6A30}\x{6A31}\x{6A32}\x{6A33}\x{6A34}\x{6A35}\x{6A36}' . '\x{6A38}\x{6A39}\x{6A3A}\x{6A3B}\x{6A3C}\x{6A3D}\x{6A3E}\x{6A3F}\x{6A40}' . '\x{6A41}\x{6A42}\x{6A43}\x{6A44}\x{6A45}\x{6A46}\x{6A47}\x{6A48}\x{6A49}' . '\x{6A4B}\x{6A4C}\x{6A4D}\x{6A4E}\x{6A4F}\x{6A50}\x{6A51}\x{6A52}\x{6A54}' . '\x{6A55}\x{6A56}\x{6A57}\x{6A58}\x{6A59}\x{6A5A}\x{6A5B}\x{6A5D}\x{6A5E}' . '\x{6A5F}\x{6A60}\x{6A61}\x{6A62}\x{6A63}\x{6A64}\x{6A65}\x{6A66}\x{6A67}' . '\x{6A68}\x{6A69}\x{6A6A}\x{6A6B}\x{6A6C}\x{6A6D}\x{6A6F}\x{6A71}\x{6A72}' . '\x{6A73}\x{6A74}\x{6A75}\x{6A76}\x{6A77}\x{6A78}\x{6A79}\x{6A7A}\x{6A7B}' . '\x{6A7C}\x{6A7D}\x{6A7E}\x{6A7F}\x{6A80}\x{6A81}\x{6A82}\x{6A83}\x{6A84}' . '\x{6A85}\x{6A87}\x{6A88}\x{6A89}\x{6A8B}\x{6A8C}\x{6A8D}\x{6A8E}\x{6A90}' . '\x{6A91}\x{6A92}\x{6A93}\x{6A94}\x{6A95}\x{6A96}\x{6A97}\x{6A98}\x{6A9A}' . '\x{6A9B}\x{6A9C}\x{6A9E}\x{6A9F}\x{6AA0}\x{6AA1}\x{6AA2}\x{6AA3}\x{6AA4}' . '\x{6AA5}\x{6AA6}\x{6AA7}\x{6AA8}\x{6AA9}\x{6AAB}\x{6AAC}\x{6AAD}\x{6AAE}' . '\x{6AAF}\x{6AB0}\x{6AB2}\x{6AB3}\x{6AB4}\x{6AB5}\x{6AB6}\x{6AB7}\x{6AB8}' . '\x{6AB9}\x{6ABA}\x{6ABB}\x{6ABC}\x{6ABD}\x{6ABF}\x{6AC1}\x{6AC2}\x{6AC3}' . '\x{6AC5}\x{6AC6}\x{6AC7}\x{6ACA}\x{6ACB}\x{6ACC}\x{6ACD}\x{6ACE}\x{6ACF}' . '\x{6AD0}\x{6AD1}\x{6AD2}\x{6AD3}\x{6AD4}\x{6AD5}\x{6AD6}\x{6AD7}\x{6AD9}' . '\x{6ADA}\x{6ADB}\x{6ADC}\x{6ADD}\x{6ADE}\x{6ADF}\x{6AE0}\x{6AE1}\x{6AE2}' . '\x{6AE3}\x{6AE4}\x{6AE5}\x{6AE6}\x{6AE7}\x{6AE8}\x{6AEA}\x{6AEB}\x{6AEC}' . '\x{6AED}\x{6AEE}\x{6AEF}\x{6AF0}\x{6AF1}\x{6AF2}\x{6AF3}\x{6AF4}\x{6AF5}' . '\x{6AF6}\x{6AF7}\x{6AF8}\x{6AF9}\x{6AFA}\x{6AFB}\x{6AFC}\x{6AFD}\x{6AFE}' . '\x{6AFF}\x{6B00}\x{6B01}\x{6B02}\x{6B03}\x{6B04}\x{6B05}\x{6B06}\x{6B07}' . '\x{6B08}\x{6B09}\x{6B0A}\x{6B0B}\x{6B0C}\x{6B0D}\x{6B0F}\x{6B10}\x{6B11}' . '\x{6B12}\x{6B13}\x{6B14}\x{6B15}\x{6B16}\x{6B17}\x{6B18}\x{6B19}\x{6B1A}' . '\x{6B1C}\x{6B1D}\x{6B1E}\x{6B1F}\x{6B20}\x{6B21}\x{6B22}\x{6B23}\x{6B24}' . '\x{6B25}\x{6B26}\x{6B27}\x{6B28}\x{6B29}\x{6B2A}\x{6B2B}\x{6B2C}\x{6B2D}' . '\x{6B2F}\x{6B30}\x{6B31}\x{6B32}\x{6B33}\x{6B34}\x{6B36}\x{6B37}\x{6B38}' . '\x{6B39}\x{6B3A}\x{6B3B}\x{6B3C}\x{6B3D}\x{6B3E}\x{6B3F}\x{6B41}\x{6B42}' . '\x{6B43}\x{6B44}\x{6B45}\x{6B46}\x{6B47}\x{6B48}\x{6B49}\x{6B4A}\x{6B4B}' . '\x{6B4C}\x{6B4D}\x{6B4E}\x{6B4F}\x{6B50}\x{6B51}\x{6B52}\x{6B53}\x{6B54}' . '\x{6B55}\x{6B56}\x{6B59}\x{6B5A}\x{6B5B}\x{6B5C}\x{6B5E}\x{6B5F}\x{6B60}' . '\x{6B61}\x{6B62}\x{6B63}\x{6B64}\x{6B65}\x{6B66}\x{6B67}\x{6B69}\x{6B6A}' . '\x{6B6B}\x{6B6D}\x{6B6F}\x{6B70}\x{6B72}\x{6B73}\x{6B74}\x{6B76}\x{6B77}' . '\x{6B78}\x{6B79}\x{6B7A}\x{6B7B}\x{6B7C}\x{6B7E}\x{6B7F}\x{6B80}\x{6B81}' . '\x{6B82}\x{6B83}\x{6B84}\x{6B85}\x{6B86}\x{6B87}\x{6B88}\x{6B89}\x{6B8A}' . '\x{6B8B}\x{6B8C}\x{6B8D}\x{6B8E}\x{6B8F}\x{6B90}\x{6B91}\x{6B92}\x{6B93}' . '\x{6B94}\x{6B95}\x{6B96}\x{6B97}\x{6B98}\x{6B99}\x{6B9A}\x{6B9B}\x{6B9C}' . '\x{6B9D}\x{6B9E}\x{6B9F}\x{6BA0}\x{6BA1}\x{6BA2}\x{6BA3}\x{6BA4}\x{6BA5}' . '\x{6BA6}\x{6BA7}\x{6BA8}\x{6BA9}\x{6BAA}\x{6BAB}\x{6BAC}\x{6BAD}\x{6BAE}' . '\x{6BAF}\x{6BB0}\x{6BB2}\x{6BB3}\x{6BB4}\x{6BB5}\x{6BB6}\x{6BB7}\x{6BB9}' . '\x{6BBA}\x{6BBB}\x{6BBC}\x{6BBD}\x{6BBE}\x{6BBF}\x{6BC0}\x{6BC1}\x{6BC2}' . '\x{6BC3}\x{6BC4}\x{6BC5}\x{6BC6}\x{6BC7}\x{6BC8}\x{6BC9}\x{6BCA}\x{6BCB}' . '\x{6BCC}\x{6BCD}\x{6BCE}\x{6BCF}\x{6BD0}\x{6BD1}\x{6BD2}\x{6BD3}\x{6BD4}' . '\x{6BD5}\x{6BD6}\x{6BD7}\x{6BD8}\x{6BD9}\x{6BDA}\x{6BDB}\x{6BDC}\x{6BDD}' . '\x{6BDE}\x{6BDF}\x{6BE0}\x{6BE1}\x{6BE2}\x{6BE3}\x{6BE4}\x{6BE5}\x{6BE6}' . '\x{6BE7}\x{6BE8}\x{6BEA}\x{6BEB}\x{6BEC}\x{6BED}\x{6BEE}\x{6BEF}\x{6BF0}' . '\x{6BF2}\x{6BF3}\x{6BF5}\x{6BF6}\x{6BF7}\x{6BF8}\x{6BF9}\x{6BFB}\x{6BFC}' . '\x{6BFD}\x{6BFE}\x{6BFF}\x{6C00}\x{6C01}\x{6C02}\x{6C03}\x{6C04}\x{6C05}' . '\x{6C06}\x{6C07}\x{6C08}\x{6C09}\x{6C0B}\x{6C0C}\x{6C0D}\x{6C0E}\x{6C0F}' . '\x{6C10}\x{6C11}\x{6C12}\x{6C13}\x{6C14}\x{6C15}\x{6C16}\x{6C18}\x{6C19}' . '\x{6C1A}\x{6C1B}\x{6C1D}\x{6C1E}\x{6C1F}\x{6C20}\x{6C21}\x{6C22}\x{6C23}' . '\x{6C24}\x{6C25}\x{6C26}\x{6C27}\x{6C28}\x{6C29}\x{6C2A}\x{6C2B}\x{6C2C}' . '\x{6C2E}\x{6C2F}\x{6C30}\x{6C31}\x{6C32}\x{6C33}\x{6C34}\x{6C35}\x{6C36}' . '\x{6C37}\x{6C38}\x{6C3A}\x{6C3B}\x{6C3D}\x{6C3E}\x{6C3F}\x{6C40}\x{6C41}' . '\x{6C42}\x{6C43}\x{6C44}\x{6C46}\x{6C47}\x{6C48}\x{6C49}\x{6C4A}\x{6C4B}' . '\x{6C4C}\x{6C4D}\x{6C4E}\x{6C4F}\x{6C50}\x{6C51}\x{6C52}\x{6C53}\x{6C54}' . '\x{6C55}\x{6C56}\x{6C57}\x{6C58}\x{6C59}\x{6C5A}\x{6C5B}\x{6C5C}\x{6C5D}' . '\x{6C5E}\x{6C5F}\x{6C60}\x{6C61}\x{6C62}\x{6C63}\x{6C64}\x{6C65}\x{6C66}' . '\x{6C67}\x{6C68}\x{6C69}\x{6C6A}\x{6C6B}\x{6C6D}\x{6C6F}\x{6C70}\x{6C71}' . '\x{6C72}\x{6C73}\x{6C74}\x{6C75}\x{6C76}\x{6C77}\x{6C78}\x{6C79}\x{6C7A}' . '\x{6C7B}\x{6C7C}\x{6C7D}\x{6C7E}\x{6C7F}\x{6C80}\x{6C81}\x{6C82}\x{6C83}' . '\x{6C84}\x{6C85}\x{6C86}\x{6C87}\x{6C88}\x{6C89}\x{6C8A}\x{6C8B}\x{6C8C}' . '\x{6C8D}\x{6C8E}\x{6C8F}\x{6C90}\x{6C91}\x{6C92}\x{6C93}\x{6C94}\x{6C95}' . '\x{6C96}\x{6C97}\x{6C98}\x{6C99}\x{6C9A}\x{6C9B}\x{6C9C}\x{6C9D}\x{6C9E}' . '\x{6C9F}\x{6CA1}\x{6CA2}\x{6CA3}\x{6CA4}\x{6CA5}\x{6CA6}\x{6CA7}\x{6CA8}' . '\x{6CA9}\x{6CAA}\x{6CAB}\x{6CAC}\x{6CAD}\x{6CAE}\x{6CAF}\x{6CB0}\x{6CB1}' . '\x{6CB2}\x{6CB3}\x{6CB4}\x{6CB5}\x{6CB6}\x{6CB7}\x{6CB8}\x{6CB9}\x{6CBA}' . '\x{6CBB}\x{6CBC}\x{6CBD}\x{6CBE}\x{6CBF}\x{6CC0}\x{6CC1}\x{6CC2}\x{6CC3}' . '\x{6CC4}\x{6CC5}\x{6CC6}\x{6CC7}\x{6CC8}\x{6CC9}\x{6CCA}\x{6CCB}\x{6CCC}' . '\x{6CCD}\x{6CCE}\x{6CCF}\x{6CD0}\x{6CD1}\x{6CD2}\x{6CD3}\x{6CD4}\x{6CD5}' . '\x{6CD6}\x{6CD7}\x{6CD9}\x{6CDA}\x{6CDB}\x{6CDC}\x{6CDD}\x{6CDE}\x{6CDF}' . '\x{6CE0}\x{6CE1}\x{6CE2}\x{6CE3}\x{6CE4}\x{6CE5}\x{6CE6}\x{6CE7}\x{6CE8}' . '\x{6CE9}\x{6CEA}\x{6CEB}\x{6CEC}\x{6CED}\x{6CEE}\x{6CEF}\x{6CF0}\x{6CF1}' . '\x{6CF2}\x{6CF3}\x{6CF5}\x{6CF6}\x{6CF7}\x{6CF8}\x{6CF9}\x{6CFA}\x{6CFB}' . '\x{6CFC}\x{6CFD}\x{6CFE}\x{6CFF}\x{6D00}\x{6D01}\x{6D03}\x{6D04}\x{6D05}' . '\x{6D06}\x{6D07}\x{6D08}\x{6D09}\x{6D0A}\x{6D0B}\x{6D0C}\x{6D0D}\x{6D0E}' . '\x{6D0F}\x{6D10}\x{6D11}\x{6D12}\x{6D13}\x{6D14}\x{6D15}\x{6D16}\x{6D17}' . '\x{6D18}\x{6D19}\x{6D1A}\x{6D1B}\x{6D1D}\x{6D1E}\x{6D1F}\x{6D20}\x{6D21}' . '\x{6D22}\x{6D23}\x{6D25}\x{6D26}\x{6D27}\x{6D28}\x{6D29}\x{6D2A}\x{6D2B}' . '\x{6D2C}\x{6D2D}\x{6D2E}\x{6D2F}\x{6D30}\x{6D31}\x{6D32}\x{6D33}\x{6D34}' . '\x{6D35}\x{6D36}\x{6D37}\x{6D38}\x{6D39}\x{6D3A}\x{6D3B}\x{6D3C}\x{6D3D}' . '\x{6D3E}\x{6D3F}\x{6D40}\x{6D41}\x{6D42}\x{6D43}\x{6D44}\x{6D45}\x{6D46}' . '\x{6D47}\x{6D48}\x{6D49}\x{6D4A}\x{6D4B}\x{6D4C}\x{6D4D}\x{6D4E}\x{6D4F}' . '\x{6D50}\x{6D51}\x{6D52}\x{6D53}\x{6D54}\x{6D55}\x{6D56}\x{6D57}\x{6D58}' . '\x{6D59}\x{6D5A}\x{6D5B}\x{6D5C}\x{6D5D}\x{6D5E}\x{6D5F}\x{6D60}\x{6D61}' . '\x{6D62}\x{6D63}\x{6D64}\x{6D65}\x{6D66}\x{6D67}\x{6D68}\x{6D69}\x{6D6A}' . '\x{6D6B}\x{6D6C}\x{6D6D}\x{6D6E}\x{6D6F}\x{6D70}\x{6D72}\x{6D73}\x{6D74}' . '\x{6D75}\x{6D76}\x{6D77}\x{6D78}\x{6D79}\x{6D7A}\x{6D7B}\x{6D7C}\x{6D7D}' . '\x{6D7E}\x{6D7F}\x{6D80}\x{6D82}\x{6D83}\x{6D84}\x{6D85}\x{6D86}\x{6D87}' . '\x{6D88}\x{6D89}\x{6D8A}\x{6D8B}\x{6D8C}\x{6D8D}\x{6D8E}\x{6D8F}\x{6D90}' . '\x{6D91}\x{6D92}\x{6D93}\x{6D94}\x{6D95}\x{6D97}\x{6D98}\x{6D99}\x{6D9A}' . '\x{6D9B}\x{6D9D}\x{6D9E}\x{6D9F}\x{6DA0}\x{6DA1}\x{6DA2}\x{6DA3}\x{6DA4}' . '\x{6DA5}\x{6DA6}\x{6DA7}\x{6DA8}\x{6DA9}\x{6DAA}\x{6DAB}\x{6DAC}\x{6DAD}' . '\x{6DAE}\x{6DAF}\x{6DB2}\x{6DB3}\x{6DB4}\x{6DB5}\x{6DB7}\x{6DB8}\x{6DB9}' . '\x{6DBA}\x{6DBB}\x{6DBC}\x{6DBD}\x{6DBE}\x{6DBF}\x{6DC0}\x{6DC1}\x{6DC2}' . '\x{6DC3}\x{6DC4}\x{6DC5}\x{6DC6}\x{6DC7}\x{6DC8}\x{6DC9}\x{6DCA}\x{6DCB}' . '\x{6DCC}\x{6DCD}\x{6DCE}\x{6DCF}\x{6DD0}\x{6DD1}\x{6DD2}\x{6DD3}\x{6DD4}' . '\x{6DD5}\x{6DD6}\x{6DD7}\x{6DD8}\x{6DD9}\x{6DDA}\x{6DDB}\x{6DDC}\x{6DDD}' . '\x{6DDE}\x{6DDF}\x{6DE0}\x{6DE1}\x{6DE2}\x{6DE3}\x{6DE4}\x{6DE5}\x{6DE6}' . '\x{6DE7}\x{6DE8}\x{6DE9}\x{6DEA}\x{6DEB}\x{6DEC}\x{6DED}\x{6DEE}\x{6DEF}' . '\x{6DF0}\x{6DF1}\x{6DF2}\x{6DF3}\x{6DF4}\x{6DF5}\x{6DF6}\x{6DF7}\x{6DF8}' . '\x{6DF9}\x{6DFA}\x{6DFB}\x{6DFC}\x{6DFD}\x{6E00}\x{6E03}\x{6E04}\x{6E05}' . '\x{6E07}\x{6E08}\x{6E09}\x{6E0A}\x{6E0B}\x{6E0C}\x{6E0D}\x{6E0E}\x{6E0F}' . '\x{6E10}\x{6E11}\x{6E14}\x{6E15}\x{6E16}\x{6E17}\x{6E19}\x{6E1A}\x{6E1B}' . '\x{6E1C}\x{6E1D}\x{6E1E}\x{6E1F}\x{6E20}\x{6E21}\x{6E22}\x{6E23}\x{6E24}' . '\x{6E25}\x{6E26}\x{6E27}\x{6E28}\x{6E29}\x{6E2B}\x{6E2C}\x{6E2D}\x{6E2E}' . '\x{6E2F}\x{6E30}\x{6E31}\x{6E32}\x{6E33}\x{6E34}\x{6E35}\x{6E36}\x{6E37}' . '\x{6E38}\x{6E39}\x{6E3A}\x{6E3B}\x{6E3C}\x{6E3D}\x{6E3E}\x{6E3F}\x{6E40}' . '\x{6E41}\x{6E42}\x{6E43}\x{6E44}\x{6E45}\x{6E46}\x{6E47}\x{6E48}\x{6E49}' . '\x{6E4A}\x{6E4B}\x{6E4D}\x{6E4E}\x{6E4F}\x{6E50}\x{6E51}\x{6E52}\x{6E53}' . '\x{6E54}\x{6E55}\x{6E56}\x{6E57}\x{6E58}\x{6E59}\x{6E5A}\x{6E5B}\x{6E5C}' . '\x{6E5D}\x{6E5E}\x{6E5F}\x{6E60}\x{6E61}\x{6E62}\x{6E63}\x{6E64}\x{6E65}' . '\x{6E66}\x{6E67}\x{6E68}\x{6E69}\x{6E6A}\x{6E6B}\x{6E6D}\x{6E6E}\x{6E6F}' . '\x{6E70}\x{6E71}\x{6E72}\x{6E73}\x{6E74}\x{6E75}\x{6E77}\x{6E78}\x{6E79}' . '\x{6E7E}\x{6E7F}\x{6E80}\x{6E81}\x{6E82}\x{6E83}\x{6E84}\x{6E85}\x{6E86}' . '\x{6E87}\x{6E88}\x{6E89}\x{6E8A}\x{6E8D}\x{6E8E}\x{6E8F}\x{6E90}\x{6E91}' . '\x{6E92}\x{6E93}\x{6E94}\x{6E96}\x{6E97}\x{6E98}\x{6E99}\x{6E9A}\x{6E9B}' . '\x{6E9C}\x{6E9D}\x{6E9E}\x{6E9F}\x{6EA0}\x{6EA1}\x{6EA2}\x{6EA3}\x{6EA4}' . '\x{6EA5}\x{6EA6}\x{6EA7}\x{6EA8}\x{6EA9}\x{6EAA}\x{6EAB}\x{6EAC}\x{6EAD}' . '\x{6EAE}\x{6EAF}\x{6EB0}\x{6EB1}\x{6EB2}\x{6EB3}\x{6EB4}\x{6EB5}\x{6EB6}' . '\x{6EB7}\x{6EB8}\x{6EB9}\x{6EBA}\x{6EBB}\x{6EBC}\x{6EBD}\x{6EBE}\x{6EBF}' . '\x{6EC0}\x{6EC1}\x{6EC2}\x{6EC3}\x{6EC4}\x{6EC5}\x{6EC6}\x{6EC7}\x{6EC8}' . '\x{6EC9}\x{6ECA}\x{6ECB}\x{6ECC}\x{6ECD}\x{6ECE}\x{6ECF}\x{6ED0}\x{6ED1}' . '\x{6ED2}\x{6ED3}\x{6ED4}\x{6ED5}\x{6ED6}\x{6ED7}\x{6ED8}\x{6ED9}\x{6EDA}' . '\x{6EDC}\x{6EDE}\x{6EDF}\x{6EE0}\x{6EE1}\x{6EE2}\x{6EE4}\x{6EE5}\x{6EE6}' . '\x{6EE7}\x{6EE8}\x{6EE9}\x{6EEA}\x{6EEB}\x{6EEC}\x{6EED}\x{6EEE}\x{6EEF}' . '\x{6EF0}\x{6EF1}\x{6EF2}\x{6EF3}\x{6EF4}\x{6EF5}\x{6EF6}\x{6EF7}\x{6EF8}' . '\x{6EF9}\x{6EFA}\x{6EFB}\x{6EFC}\x{6EFD}\x{6EFE}\x{6EFF}\x{6F00}\x{6F01}' . '\x{6F02}\x{6F03}\x{6F05}\x{6F06}\x{6F07}\x{6F08}\x{6F09}\x{6F0A}\x{6F0C}' . '\x{6F0D}\x{6F0E}\x{6F0F}\x{6F10}\x{6F11}\x{6F12}\x{6F13}\x{6F14}\x{6F15}' . '\x{6F16}\x{6F17}\x{6F18}\x{6F19}\x{6F1A}\x{6F1B}\x{6F1C}\x{6F1D}\x{6F1E}' . '\x{6F1F}\x{6F20}\x{6F21}\x{6F22}\x{6F23}\x{6F24}\x{6F25}\x{6F26}\x{6F27}' . '\x{6F28}\x{6F29}\x{6F2A}\x{6F2B}\x{6F2C}\x{6F2D}\x{6F2E}\x{6F2F}\x{6F30}' . '\x{6F31}\x{6F32}\x{6F33}\x{6F34}\x{6F35}\x{6F36}\x{6F37}\x{6F38}\x{6F39}' . '\x{6F3A}\x{6F3B}\x{6F3C}\x{6F3D}\x{6F3E}\x{6F3F}\x{6F40}\x{6F41}\x{6F43}' . '\x{6F44}\x{6F45}\x{6F46}\x{6F47}\x{6F49}\x{6F4B}\x{6F4C}\x{6F4D}\x{6F4E}' . '\x{6F4F}\x{6F50}\x{6F51}\x{6F52}\x{6F53}\x{6F54}\x{6F55}\x{6F56}\x{6F57}' . '\x{6F58}\x{6F59}\x{6F5A}\x{6F5B}\x{6F5C}\x{6F5D}\x{6F5E}\x{6F5F}\x{6F60}' . '\x{6F61}\x{6F62}\x{6F63}\x{6F64}\x{6F65}\x{6F66}\x{6F67}\x{6F68}\x{6F69}' . '\x{6F6A}\x{6F6B}\x{6F6C}\x{6F6D}\x{6F6E}\x{6F6F}\x{6F70}\x{6F71}\x{6F72}' . '\x{6F73}\x{6F74}\x{6F75}\x{6F76}\x{6F77}\x{6F78}\x{6F7A}\x{6F7B}\x{6F7C}' . '\x{6F7D}\x{6F7E}\x{6F7F}\x{6F80}\x{6F81}\x{6F82}\x{6F83}\x{6F84}\x{6F85}' . '\x{6F86}\x{6F87}\x{6F88}\x{6F89}\x{6F8A}\x{6F8B}\x{6F8C}\x{6F8D}\x{6F8E}' . '\x{6F8F}\x{6F90}\x{6F91}\x{6F92}\x{6F93}\x{6F94}\x{6F95}\x{6F96}\x{6F97}' . '\x{6F99}\x{6F9B}\x{6F9C}\x{6F9D}\x{6F9E}\x{6FA0}\x{6FA1}\x{6FA2}\x{6FA3}' . '\x{6FA4}\x{6FA5}\x{6FA6}\x{6FA7}\x{6FA8}\x{6FA9}\x{6FAA}\x{6FAB}\x{6FAC}' . '\x{6FAD}\x{6FAE}\x{6FAF}\x{6FB0}\x{6FB1}\x{6FB2}\x{6FB3}\x{6FB4}\x{6FB5}' . '\x{6FB6}\x{6FB8}\x{6FB9}\x{6FBA}\x{6FBB}\x{6FBC}\x{6FBD}\x{6FBE}\x{6FBF}' . '\x{6FC0}\x{6FC1}\x{6FC2}\x{6FC3}\x{6FC4}\x{6FC6}\x{6FC7}\x{6FC8}\x{6FC9}' . '\x{6FCA}\x{6FCB}\x{6FCC}\x{6FCD}\x{6FCE}\x{6FCF}\x{6FD1}\x{6FD2}\x{6FD4}' . '\x{6FD5}\x{6FD6}\x{6FD7}\x{6FD8}\x{6FD9}\x{6FDA}\x{6FDB}\x{6FDC}\x{6FDD}' . '\x{6FDE}\x{6FDF}\x{6FE0}\x{6FE1}\x{6FE2}\x{6FE3}\x{6FE4}\x{6FE5}\x{6FE6}' . '\x{6FE7}\x{6FE8}\x{6FE9}\x{6FEA}\x{6FEB}\x{6FEC}\x{6FED}\x{6FEE}\x{6FEF}' . '\x{6FF0}\x{6FF1}\x{6FF2}\x{6FF3}\x{6FF4}\x{6FF6}\x{6FF7}\x{6FF8}\x{6FF9}' . '\x{6FFA}\x{6FFB}\x{6FFC}\x{6FFE}\x{6FFF}\x{7000}\x{7001}\x{7002}\x{7003}' . '\x{7004}\x{7005}\x{7006}\x{7007}\x{7008}\x{7009}\x{700A}\x{700B}\x{700C}' . '\x{700D}\x{700E}\x{700F}\x{7011}\x{7012}\x{7014}\x{7015}\x{7016}\x{7017}' . '\x{7018}\x{7019}\x{701A}\x{701B}\x{701C}\x{701D}\x{701F}\x{7020}\x{7021}' . '\x{7022}\x{7023}\x{7024}\x{7025}\x{7026}\x{7027}\x{7028}\x{7029}\x{702A}' . '\x{702B}\x{702C}\x{702D}\x{702E}\x{702F}\x{7030}\x{7031}\x{7032}\x{7033}' . '\x{7034}\x{7035}\x{7036}\x{7037}\x{7038}\x{7039}\x{703A}\x{703B}\x{703C}' . '\x{703D}\x{703E}\x{703F}\x{7040}\x{7041}\x{7042}\x{7043}\x{7044}\x{7045}' . '\x{7046}\x{7048}\x{7049}\x{704A}\x{704C}\x{704D}\x{704F}\x{7050}\x{7051}' . '\x{7052}\x{7053}\x{7054}\x{7055}\x{7056}\x{7057}\x{7058}\x{7059}\x{705A}' . '\x{705B}\x{705C}\x{705D}\x{705E}\x{705F}\x{7060}\x{7061}\x{7062}\x{7063}' . '\x{7064}\x{7065}\x{7066}\x{7067}\x{7068}\x{7069}\x{706A}\x{706B}\x{706C}' . '\x{706D}\x{706E}\x{706F}\x{7070}\x{7071}\x{7074}\x{7075}\x{7076}\x{7077}' . '\x{7078}\x{7079}\x{707A}\x{707C}\x{707D}\x{707E}\x{707F}\x{7080}\x{7082}' . '\x{7083}\x{7084}\x{7085}\x{7086}\x{7087}\x{7088}\x{7089}\x{708A}\x{708B}' . '\x{708C}\x{708E}\x{708F}\x{7090}\x{7091}\x{7092}\x{7093}\x{7094}\x{7095}' . '\x{7096}\x{7098}\x{7099}\x{709A}\x{709C}\x{709D}\x{709E}\x{709F}\x{70A0}' . '\x{70A1}\x{70A2}\x{70A3}\x{70A4}\x{70A5}\x{70A6}\x{70A7}\x{70A8}\x{70A9}' . '\x{70AB}\x{70AC}\x{70AD}\x{70AE}\x{70AF}\x{70B0}\x{70B1}\x{70B3}\x{70B4}' . '\x{70B5}\x{70B7}\x{70B8}\x{70B9}\x{70BA}\x{70BB}\x{70BC}\x{70BD}\x{70BE}' . '\x{70BF}\x{70C0}\x{70C1}\x{70C2}\x{70C3}\x{70C4}\x{70C5}\x{70C6}\x{70C7}' . '\x{70C8}\x{70C9}\x{70CA}\x{70CB}\x{70CC}\x{70CD}\x{70CE}\x{70CF}\x{70D0}' . '\x{70D1}\x{70D2}\x{70D3}\x{70D4}\x{70D6}\x{70D7}\x{70D8}\x{70D9}\x{70DA}' . '\x{70DB}\x{70DC}\x{70DD}\x{70DE}\x{70DF}\x{70E0}\x{70E1}\x{70E2}\x{70E3}' . '\x{70E4}\x{70E5}\x{70E6}\x{70E7}\x{70E8}\x{70E9}\x{70EA}\x{70EB}\x{70EC}' . '\x{70ED}\x{70EE}\x{70EF}\x{70F0}\x{70F1}\x{70F2}\x{70F3}\x{70F4}\x{70F5}' . '\x{70F6}\x{70F7}\x{70F8}\x{70F9}\x{70FA}\x{70FB}\x{70FC}\x{70FD}\x{70FF}' . '\x{7100}\x{7101}\x{7102}\x{7103}\x{7104}\x{7105}\x{7106}\x{7107}\x{7109}' . '\x{710A}\x{710B}\x{710C}\x{710D}\x{710E}\x{710F}\x{7110}\x{7111}\x{7112}' . '\x{7113}\x{7115}\x{7116}\x{7117}\x{7118}\x{7119}\x{711A}\x{711B}\x{711C}' . '\x{711D}\x{711E}\x{711F}\x{7120}\x{7121}\x{7122}\x{7123}\x{7125}\x{7126}' . '\x{7127}\x{7128}\x{7129}\x{712A}\x{712B}\x{712C}\x{712D}\x{712E}\x{712F}' . '\x{7130}\x{7131}\x{7132}\x{7135}\x{7136}\x{7137}\x{7138}\x{7139}\x{713A}' . '\x{713B}\x{713D}\x{713E}\x{713F}\x{7140}\x{7141}\x{7142}\x{7143}\x{7144}' . '\x{7145}\x{7146}\x{7147}\x{7148}\x{7149}\x{714A}\x{714B}\x{714C}\x{714D}' . '\x{714E}\x{714F}\x{7150}\x{7151}\x{7152}\x{7153}\x{7154}\x{7156}\x{7158}' . '\x{7159}\x{715A}\x{715B}\x{715C}\x{715D}\x{715E}\x{715F}\x{7160}\x{7161}' . '\x{7162}\x{7163}\x{7164}\x{7165}\x{7166}\x{7167}\x{7168}\x{7169}\x{716A}' . '\x{716C}\x{716E}\x{716F}\x{7170}\x{7171}\x{7172}\x{7173}\x{7174}\x{7175}' . '\x{7176}\x{7177}\x{7178}\x{7179}\x{717A}\x{717B}\x{717C}\x{717D}\x{717E}' . '\x{717F}\x{7180}\x{7181}\x{7182}\x{7183}\x{7184}\x{7185}\x{7186}\x{7187}' . '\x{7188}\x{7189}\x{718A}\x{718B}\x{718C}\x{718E}\x{718F}\x{7190}\x{7191}' . '\x{7192}\x{7193}\x{7194}\x{7195}\x{7197}\x{7198}\x{7199}\x{719A}\x{719B}' . '\x{719C}\x{719D}\x{719E}\x{719F}\x{71A0}\x{71A1}\x{71A2}\x{71A3}\x{71A4}' . '\x{71A5}\x{71A7}\x{71A8}\x{71A9}\x{71AA}\x{71AC}\x{71AD}\x{71AE}\x{71AF}' . '\x{71B0}\x{71B1}\x{71B2}\x{71B3}\x{71B4}\x{71B5}\x{71B7}\x{71B8}\x{71B9}' . '\x{71BA}\x{71BB}\x{71BC}\x{71BD}\x{71BE}\x{71BF}\x{71C0}\x{71C1}\x{71C2}' . '\x{71C3}\x{71C4}\x{71C5}\x{71C6}\x{71C7}\x{71C8}\x{71C9}\x{71CA}\x{71CB}' . '\x{71CD}\x{71CE}\x{71CF}\x{71D0}\x{71D1}\x{71D2}\x{71D4}\x{71D5}\x{71D6}' . '\x{71D7}\x{71D8}\x{71D9}\x{71DA}\x{71DB}\x{71DC}\x{71DD}\x{71DE}\x{71DF}' . '\x{71E0}\x{71E1}\x{71E2}\x{71E3}\x{71E4}\x{71E5}\x{71E6}\x{71E7}\x{71E8}' . '\x{71E9}\x{71EA}\x{71EB}\x{71EC}\x{71ED}\x{71EE}\x{71EF}\x{71F0}\x{71F1}' . '\x{71F2}\x{71F4}\x{71F5}\x{71F6}\x{71F7}\x{71F8}\x{71F9}\x{71FB}\x{71FC}' . '\x{71FD}\x{71FE}\x{71FF}\x{7201}\x{7202}\x{7203}\x{7204}\x{7205}\x{7206}' . '\x{7207}\x{7208}\x{7209}\x{720A}\x{720C}\x{720D}\x{720E}\x{720F}\x{7210}' . '\x{7212}\x{7213}\x{7214}\x{7216}\x{7218}\x{7219}\x{721A}\x{721B}\x{721C}' . '\x{721D}\x{721E}\x{721F}\x{7221}\x{7222}\x{7223}\x{7226}\x{7227}\x{7228}' . '\x{7229}\x{722A}\x{722B}\x{722C}\x{722D}\x{722E}\x{7230}\x{7231}\x{7232}' . '\x{7233}\x{7235}\x{7236}\x{7237}\x{7238}\x{7239}\x{723A}\x{723B}\x{723C}' . '\x{723D}\x{723E}\x{723F}\x{7240}\x{7241}\x{7242}\x{7243}\x{7244}\x{7246}' . '\x{7247}\x{7248}\x{7249}\x{724A}\x{724B}\x{724C}\x{724D}\x{724F}\x{7251}' . '\x{7252}\x{7253}\x{7254}\x{7256}\x{7257}\x{7258}\x{7259}\x{725A}\x{725B}' . '\x{725C}\x{725D}\x{725E}\x{725F}\x{7260}\x{7261}\x{7262}\x{7263}\x{7264}' . '\x{7265}\x{7266}\x{7267}\x{7268}\x{7269}\x{726A}\x{726B}\x{726C}\x{726D}' . '\x{726E}\x{726F}\x{7270}\x{7271}\x{7272}\x{7273}\x{7274}\x{7275}\x{7276}' . '\x{7277}\x{7278}\x{7279}\x{727A}\x{727B}\x{727C}\x{727D}\x{727E}\x{727F}' . '\x{7280}\x{7281}\x{7282}\x{7283}\x{7284}\x{7285}\x{7286}\x{7287}\x{7288}' . '\x{7289}\x{728A}\x{728B}\x{728C}\x{728D}\x{728E}\x{728F}\x{7290}\x{7291}' . '\x{7292}\x{7293}\x{7294}\x{7295}\x{7296}\x{7297}\x{7298}\x{7299}\x{729A}' . '\x{729B}\x{729C}\x{729D}\x{729E}\x{729F}\x{72A1}\x{72A2}\x{72A3}\x{72A4}' . '\x{72A5}\x{72A6}\x{72A7}\x{72A8}\x{72A9}\x{72AA}\x{72AC}\x{72AD}\x{72AE}' . '\x{72AF}\x{72B0}\x{72B1}\x{72B2}\x{72B3}\x{72B4}\x{72B5}\x{72B6}\x{72B7}' . '\x{72B8}\x{72B9}\x{72BA}\x{72BB}\x{72BC}\x{72BD}\x{72BF}\x{72C0}\x{72C1}' . '\x{72C2}\x{72C3}\x{72C4}\x{72C5}\x{72C6}\x{72C7}\x{72C8}\x{72C9}\x{72CA}' . '\x{72CB}\x{72CC}\x{72CD}\x{72CE}\x{72CF}\x{72D0}\x{72D1}\x{72D2}\x{72D3}' . '\x{72D4}\x{72D5}\x{72D6}\x{72D7}\x{72D8}\x{72D9}\x{72DA}\x{72DB}\x{72DC}' . '\x{72DD}\x{72DE}\x{72DF}\x{72E0}\x{72E1}\x{72E2}\x{72E3}\x{72E4}\x{72E5}' . '\x{72E6}\x{72E7}\x{72E8}\x{72E9}\x{72EA}\x{72EB}\x{72EC}\x{72ED}\x{72EE}' . '\x{72EF}\x{72F0}\x{72F1}\x{72F2}\x{72F3}\x{72F4}\x{72F5}\x{72F6}\x{72F7}' . '\x{72F8}\x{72F9}\x{72FA}\x{72FB}\x{72FC}\x{72FD}\x{72FE}\x{72FF}\x{7300}' . '\x{7301}\x{7303}\x{7304}\x{7305}\x{7306}\x{7307}\x{7308}\x{7309}\x{730A}' . '\x{730B}\x{730C}\x{730D}\x{730E}\x{730F}\x{7311}\x{7312}\x{7313}\x{7314}' . '\x{7315}\x{7316}\x{7317}\x{7318}\x{7319}\x{731A}\x{731B}\x{731C}\x{731D}' . '\x{731E}\x{7320}\x{7321}\x{7322}\x{7323}\x{7324}\x{7325}\x{7326}\x{7327}' . '\x{7329}\x{732A}\x{732B}\x{732C}\x{732D}\x{732E}\x{7330}\x{7331}\x{7332}' . '\x{7333}\x{7334}\x{7335}\x{7336}\x{7337}\x{7338}\x{7339}\x{733A}\x{733B}' . '\x{733C}\x{733D}\x{733E}\x{733F}\x{7340}\x{7341}\x{7342}\x{7343}\x{7344}' . '\x{7345}\x{7346}\x{7347}\x{7348}\x{7349}\x{734A}\x{734B}\x{734C}\x{734D}' . '\x{734E}\x{7350}\x{7351}\x{7352}\x{7354}\x{7355}\x{7356}\x{7357}\x{7358}' . '\x{7359}\x{735A}\x{735B}\x{735C}\x{735D}\x{735E}\x{735F}\x{7360}\x{7361}' . '\x{7362}\x{7364}\x{7365}\x{7366}\x{7367}\x{7368}\x{7369}\x{736A}\x{736B}' . '\x{736C}\x{736D}\x{736E}\x{736F}\x{7370}\x{7371}\x{7372}\x{7373}\x{7374}' . '\x{7375}\x{7376}\x{7377}\x{7378}\x{7379}\x{737A}\x{737B}\x{737C}\x{737D}' . '\x{737E}\x{737F}\x{7380}\x{7381}\x{7382}\x{7383}\x{7384}\x{7385}\x{7386}' . '\x{7387}\x{7388}\x{7389}\x{738A}\x{738B}\x{738C}\x{738D}\x{738E}\x{738F}' . '\x{7390}\x{7391}\x{7392}\x{7393}\x{7394}\x{7395}\x{7396}\x{7397}\x{7398}' . '\x{7399}\x{739A}\x{739B}\x{739D}\x{739E}\x{739F}\x{73A0}\x{73A1}\x{73A2}' . '\x{73A3}\x{73A4}\x{73A5}\x{73A6}\x{73A7}\x{73A8}\x{73A9}\x{73AA}\x{73AB}' . '\x{73AC}\x{73AD}\x{73AE}\x{73AF}\x{73B0}\x{73B1}\x{73B2}\x{73B3}\x{73B4}' . '\x{73B5}\x{73B6}\x{73B7}\x{73B8}\x{73B9}\x{73BA}\x{73BB}\x{73BC}\x{73BD}' . '\x{73BE}\x{73BF}\x{73C0}\x{73C2}\x{73C3}\x{73C4}\x{73C5}\x{73C6}\x{73C7}' . '\x{73C8}\x{73C9}\x{73CA}\x{73CB}\x{73CC}\x{73CD}\x{73CE}\x{73CF}\x{73D0}' . '\x{73D1}\x{73D2}\x{73D3}\x{73D4}\x{73D5}\x{73D6}\x{73D7}\x{73D8}\x{73D9}' . '\x{73DA}\x{73DB}\x{73DC}\x{73DD}\x{73DE}\x{73DF}\x{73E0}\x{73E2}\x{73E3}' . '\x{73E5}\x{73E6}\x{73E7}\x{73E8}\x{73E9}\x{73EA}\x{73EB}\x{73EC}\x{73ED}' . '\x{73EE}\x{73EF}\x{73F0}\x{73F1}\x{73F2}\x{73F4}\x{73F5}\x{73F6}\x{73F7}' . '\x{73F8}\x{73F9}\x{73FA}\x{73FC}\x{73FD}\x{73FE}\x{73FF}\x{7400}\x{7401}' . '\x{7402}\x{7403}\x{7404}\x{7405}\x{7406}\x{7407}\x{7408}\x{7409}\x{740A}' . '\x{740B}\x{740C}\x{740D}\x{740E}\x{740F}\x{7410}\x{7411}\x{7412}\x{7413}' . '\x{7414}\x{7415}\x{7416}\x{7417}\x{7419}\x{741A}\x{741B}\x{741C}\x{741D}' . '\x{741E}\x{741F}\x{7420}\x{7421}\x{7422}\x{7423}\x{7424}\x{7425}\x{7426}' . '\x{7427}\x{7428}\x{7429}\x{742A}\x{742B}\x{742C}\x{742D}\x{742E}\x{742F}' . '\x{7430}\x{7431}\x{7432}\x{7433}\x{7434}\x{7435}\x{7436}\x{7437}\x{7438}' . '\x{743A}\x{743B}\x{743C}\x{743D}\x{743F}\x{7440}\x{7441}\x{7442}\x{7443}' . '\x{7444}\x{7445}\x{7446}\x{7448}\x{744A}\x{744B}\x{744C}\x{744D}\x{744E}' . '\x{744F}\x{7450}\x{7451}\x{7452}\x{7453}\x{7454}\x{7455}\x{7456}\x{7457}' . '\x{7459}\x{745A}\x{745B}\x{745C}\x{745D}\x{745E}\x{745F}\x{7461}\x{7462}' . '\x{7463}\x{7464}\x{7465}\x{7466}\x{7467}\x{7468}\x{7469}\x{746A}\x{746B}' . '\x{746C}\x{746D}\x{746E}\x{746F}\x{7470}\x{7471}\x{7472}\x{7473}\x{7474}' . '\x{7475}\x{7476}\x{7477}\x{7478}\x{7479}\x{747A}\x{747C}\x{747D}\x{747E}' . '\x{747F}\x{7480}\x{7481}\x{7482}\x{7483}\x{7485}\x{7486}\x{7487}\x{7488}' . '\x{7489}\x{748A}\x{748B}\x{748C}\x{748D}\x{748E}\x{748F}\x{7490}\x{7491}' . '\x{7492}\x{7493}\x{7494}\x{7495}\x{7497}\x{7498}\x{7499}\x{749A}\x{749B}' . '\x{749C}\x{749E}\x{749F}\x{74A0}\x{74A1}\x{74A3}\x{74A4}\x{74A5}\x{74A6}' . '\x{74A7}\x{74A8}\x{74A9}\x{74AA}\x{74AB}\x{74AC}\x{74AD}\x{74AE}\x{74AF}' . '\x{74B0}\x{74B1}\x{74B2}\x{74B3}\x{74B4}\x{74B5}\x{74B6}\x{74B7}\x{74B8}' . '\x{74B9}\x{74BA}\x{74BB}\x{74BC}\x{74BD}\x{74BE}\x{74BF}\x{74C0}\x{74C1}' . '\x{74C2}\x{74C3}\x{74C4}\x{74C5}\x{74C6}\x{74CA}\x{74CB}\x{74CD}\x{74CE}' . '\x{74CF}\x{74D0}\x{74D1}\x{74D2}\x{74D3}\x{74D4}\x{74D5}\x{74D6}\x{74D7}' . '\x{74D8}\x{74D9}\x{74DA}\x{74DB}\x{74DC}\x{74DD}\x{74DE}\x{74DF}\x{74E0}' . '\x{74E1}\x{74E2}\x{74E3}\x{74E4}\x{74E5}\x{74E6}\x{74E7}\x{74E8}\x{74E9}' . '\x{74EA}\x{74EC}\x{74ED}\x{74EE}\x{74EF}\x{74F0}\x{74F1}\x{74F2}\x{74F3}' . '\x{74F4}\x{74F5}\x{74F6}\x{74F7}\x{74F8}\x{74F9}\x{74FA}\x{74FB}\x{74FC}' . '\x{74FD}\x{74FE}\x{74FF}\x{7500}\x{7501}\x{7502}\x{7503}\x{7504}\x{7505}' . '\x{7506}\x{7507}\x{7508}\x{7509}\x{750A}\x{750B}\x{750C}\x{750D}\x{750F}' . '\x{7510}\x{7511}\x{7512}\x{7513}\x{7514}\x{7515}\x{7516}\x{7517}\x{7518}' . '\x{7519}\x{751A}\x{751B}\x{751C}\x{751D}\x{751E}\x{751F}\x{7521}\x{7522}' . '\x{7523}\x{7524}\x{7525}\x{7526}\x{7527}\x{7528}\x{7529}\x{752A}\x{752B}' . '\x{752C}\x{752D}\x{752E}\x{752F}\x{7530}\x{7531}\x{7532}\x{7533}\x{7535}' . '\x{7536}\x{7537}\x{7538}\x{7539}\x{753A}\x{753B}\x{753C}\x{753D}\x{753E}' . '\x{753F}\x{7540}\x{7542}\x{7543}\x{7544}\x{7545}\x{7546}\x{7547}\x{7548}' . '\x{7549}\x{754B}\x{754C}\x{754D}\x{754E}\x{754F}\x{7550}\x{7551}\x{7553}' . '\x{7554}\x{7556}\x{7557}\x{7558}\x{7559}\x{755A}\x{755B}\x{755C}\x{755D}' . '\x{755F}\x{7560}\x{7562}\x{7563}\x{7564}\x{7565}\x{7566}\x{7567}\x{7568}' . '\x{7569}\x{756A}\x{756B}\x{756C}\x{756D}\x{756E}\x{756F}\x{7570}\x{7572}' . '\x{7574}\x{7575}\x{7576}\x{7577}\x{7578}\x{7579}\x{757C}\x{757D}\x{757E}' . '\x{757F}\x{7580}\x{7581}\x{7582}\x{7583}\x{7584}\x{7586}\x{7587}\x{7588}' . '\x{7589}\x{758A}\x{758B}\x{758C}\x{758D}\x{758F}\x{7590}\x{7591}\x{7592}' . '\x{7593}\x{7594}\x{7595}\x{7596}\x{7597}\x{7598}\x{7599}\x{759A}\x{759B}' . '\x{759C}\x{759D}\x{759E}\x{759F}\x{75A0}\x{75A1}\x{75A2}\x{75A3}\x{75A4}' . '\x{75A5}\x{75A6}\x{75A7}\x{75A8}\x{75AA}\x{75AB}\x{75AC}\x{75AD}\x{75AE}' . '\x{75AF}\x{75B0}\x{75B1}\x{75B2}\x{75B3}\x{75B4}\x{75B5}\x{75B6}\x{75B8}' . '\x{75B9}\x{75BA}\x{75BB}\x{75BC}\x{75BD}\x{75BE}\x{75BF}\x{75C0}\x{75C1}' . '\x{75C2}\x{75C3}\x{75C4}\x{75C5}\x{75C6}\x{75C7}\x{75C8}\x{75C9}\x{75CA}' . '\x{75CB}\x{75CC}\x{75CD}\x{75CE}\x{75CF}\x{75D0}\x{75D1}\x{75D2}\x{75D3}' . '\x{75D4}\x{75D5}\x{75D6}\x{75D7}\x{75D8}\x{75D9}\x{75DA}\x{75DB}\x{75DD}' . '\x{75DE}\x{75DF}\x{75E0}\x{75E1}\x{75E2}\x{75E3}\x{75E4}\x{75E5}\x{75E6}' . '\x{75E7}\x{75E8}\x{75EA}\x{75EB}\x{75EC}\x{75ED}\x{75EF}\x{75F0}\x{75F1}' . '\x{75F2}\x{75F3}\x{75F4}\x{75F5}\x{75F6}\x{75F7}\x{75F8}\x{75F9}\x{75FA}' . '\x{75FB}\x{75FC}\x{75FD}\x{75FE}\x{75FF}\x{7600}\x{7601}\x{7602}\x{7603}' . '\x{7604}\x{7605}\x{7606}\x{7607}\x{7608}\x{7609}\x{760A}\x{760B}\x{760C}' . '\x{760D}\x{760E}\x{760F}\x{7610}\x{7611}\x{7612}\x{7613}\x{7614}\x{7615}' . '\x{7616}\x{7617}\x{7618}\x{7619}\x{761A}\x{761B}\x{761C}\x{761D}\x{761E}' . '\x{761F}\x{7620}\x{7621}\x{7622}\x{7623}\x{7624}\x{7625}\x{7626}\x{7627}' . '\x{7628}\x{7629}\x{762A}\x{762B}\x{762D}\x{762E}\x{762F}\x{7630}\x{7631}' . '\x{7632}\x{7633}\x{7634}\x{7635}\x{7636}\x{7637}\x{7638}\x{7639}\x{763A}' . '\x{763B}\x{763C}\x{763D}\x{763E}\x{763F}\x{7640}\x{7641}\x{7642}\x{7643}' . '\x{7646}\x{7647}\x{7648}\x{7649}\x{764A}\x{764B}\x{764C}\x{764D}\x{764F}' . '\x{7650}\x{7652}\x{7653}\x{7654}\x{7656}\x{7657}\x{7658}\x{7659}\x{765A}' . '\x{765B}\x{765C}\x{765D}\x{765E}\x{765F}\x{7660}\x{7661}\x{7662}\x{7663}' . '\x{7664}\x{7665}\x{7666}\x{7667}\x{7668}\x{7669}\x{766A}\x{766B}\x{766C}' . '\x{766D}\x{766E}\x{766F}\x{7670}\x{7671}\x{7672}\x{7674}\x{7675}\x{7676}' . '\x{7677}\x{7678}\x{7679}\x{767B}\x{767C}\x{767D}\x{767E}\x{767F}\x{7680}' . '\x{7681}\x{7682}\x{7683}\x{7684}\x{7685}\x{7686}\x{7687}\x{7688}\x{7689}' . '\x{768A}\x{768B}\x{768C}\x{768E}\x{768F}\x{7690}\x{7691}\x{7692}\x{7693}' . '\x{7694}\x{7695}\x{7696}\x{7697}\x{7698}\x{7699}\x{769A}\x{769B}\x{769C}' . '\x{769D}\x{769E}\x{769F}\x{76A0}\x{76A3}\x{76A4}\x{76A6}\x{76A7}\x{76A9}' . '\x{76AA}\x{76AB}\x{76AC}\x{76AD}\x{76AE}\x{76AF}\x{76B0}\x{76B1}\x{76B2}' . '\x{76B4}\x{76B5}\x{76B7}\x{76B8}\x{76BA}\x{76BB}\x{76BC}\x{76BD}\x{76BE}' . '\x{76BF}\x{76C0}\x{76C2}\x{76C3}\x{76C4}\x{76C5}\x{76C6}\x{76C7}\x{76C8}' . '\x{76C9}\x{76CA}\x{76CD}\x{76CE}\x{76CF}\x{76D0}\x{76D1}\x{76D2}\x{76D3}' . '\x{76D4}\x{76D5}\x{76D6}\x{76D7}\x{76D8}\x{76DA}\x{76DB}\x{76DC}\x{76DD}' . '\x{76DE}\x{76DF}\x{76E0}\x{76E1}\x{76E2}\x{76E3}\x{76E4}\x{76E5}\x{76E6}' . '\x{76E7}\x{76E8}\x{76E9}\x{76EA}\x{76EC}\x{76ED}\x{76EE}\x{76EF}\x{76F0}' . '\x{76F1}\x{76F2}\x{76F3}\x{76F4}\x{76F5}\x{76F6}\x{76F7}\x{76F8}\x{76F9}' . '\x{76FA}\x{76FB}\x{76FC}\x{76FD}\x{76FE}\x{76FF}\x{7701}\x{7703}\x{7704}' . '\x{7705}\x{7706}\x{7707}\x{7708}\x{7709}\x{770A}\x{770B}\x{770C}\x{770D}' . '\x{770F}\x{7710}\x{7711}\x{7712}\x{7713}\x{7714}\x{7715}\x{7716}\x{7717}' . '\x{7718}\x{7719}\x{771A}\x{771B}\x{771C}\x{771D}\x{771E}\x{771F}\x{7720}' . '\x{7722}\x{7723}\x{7725}\x{7726}\x{7727}\x{7728}\x{7729}\x{772A}\x{772C}' . '\x{772D}\x{772E}\x{772F}\x{7730}\x{7731}\x{7732}\x{7733}\x{7734}\x{7735}' . '\x{7736}\x{7737}\x{7738}\x{7739}\x{773A}\x{773B}\x{773C}\x{773D}\x{773E}' . '\x{7740}\x{7741}\x{7743}\x{7744}\x{7745}\x{7746}\x{7747}\x{7748}\x{7749}' . '\x{774A}\x{774B}\x{774C}\x{774D}\x{774E}\x{774F}\x{7750}\x{7751}\x{7752}' . '\x{7753}\x{7754}\x{7755}\x{7756}\x{7757}\x{7758}\x{7759}\x{775A}\x{775B}' . '\x{775C}\x{775D}\x{775E}\x{775F}\x{7760}\x{7761}\x{7762}\x{7763}\x{7765}' . '\x{7766}\x{7767}\x{7768}\x{7769}\x{776A}\x{776B}\x{776C}\x{776D}\x{776E}' . '\x{776F}\x{7770}\x{7771}\x{7772}\x{7773}\x{7774}\x{7775}\x{7776}\x{7777}' . '\x{7778}\x{7779}\x{777A}\x{777B}\x{777C}\x{777D}\x{777E}\x{777F}\x{7780}' . '\x{7781}\x{7782}\x{7783}\x{7784}\x{7785}\x{7786}\x{7787}\x{7788}\x{7789}' . '\x{778A}\x{778B}\x{778C}\x{778D}\x{778E}\x{778F}\x{7790}\x{7791}\x{7792}' . '\x{7793}\x{7794}\x{7795}\x{7797}\x{7798}\x{7799}\x{779A}\x{779B}\x{779C}' . '\x{779D}\x{779E}\x{779F}\x{77A0}\x{77A1}\x{77A2}\x{77A3}\x{77A5}\x{77A6}' . '\x{77A7}\x{77A8}\x{77A9}\x{77AA}\x{77AB}\x{77AC}\x{77AD}\x{77AE}\x{77AF}' . '\x{77B0}\x{77B1}\x{77B2}\x{77B3}\x{77B4}\x{77B5}\x{77B6}\x{77B7}\x{77B8}' . '\x{77B9}\x{77BA}\x{77BB}\x{77BC}\x{77BD}\x{77BF}\x{77C0}\x{77C2}\x{77C3}' . '\x{77C4}\x{77C5}\x{77C6}\x{77C7}\x{77C8}\x{77C9}\x{77CA}\x{77CB}\x{77CC}' . '\x{77CD}\x{77CE}\x{77CF}\x{77D0}\x{77D1}\x{77D3}\x{77D4}\x{77D5}\x{77D6}' . '\x{77D7}\x{77D8}\x{77D9}\x{77DA}\x{77DB}\x{77DC}\x{77DE}\x{77DF}\x{77E0}' . '\x{77E1}\x{77E2}\x{77E3}\x{77E5}\x{77E7}\x{77E8}\x{77E9}\x{77EA}\x{77EB}' . '\x{77EC}\x{77ED}\x{77EE}\x{77EF}\x{77F0}\x{77F1}\x{77F2}\x{77F3}\x{77F6}' . '\x{77F7}\x{77F8}\x{77F9}\x{77FA}\x{77FB}\x{77FC}\x{77FD}\x{77FE}\x{77FF}' . '\x{7800}\x{7801}\x{7802}\x{7803}\x{7804}\x{7805}\x{7806}\x{7808}\x{7809}' . '\x{780A}\x{780B}\x{780C}\x{780D}\x{780E}\x{780F}\x{7810}\x{7811}\x{7812}' . '\x{7813}\x{7814}\x{7815}\x{7816}\x{7817}\x{7818}\x{7819}\x{781A}\x{781B}' . '\x{781C}\x{781D}\x{781E}\x{781F}\x{7820}\x{7821}\x{7822}\x{7823}\x{7825}' . '\x{7826}\x{7827}\x{7828}\x{7829}\x{782A}\x{782B}\x{782C}\x{782D}\x{782E}' . '\x{782F}\x{7830}\x{7831}\x{7832}\x{7833}\x{7834}\x{7835}\x{7837}\x{7838}' . '\x{7839}\x{783A}\x{783B}\x{783C}\x{783D}\x{783E}\x{7840}\x{7841}\x{7843}' . '\x{7844}\x{7845}\x{7847}\x{7848}\x{7849}\x{784A}\x{784C}\x{784D}\x{784E}' . '\x{7850}\x{7851}\x{7852}\x{7853}\x{7854}\x{7855}\x{7856}\x{7857}\x{7858}' . '\x{7859}\x{785A}\x{785B}\x{785C}\x{785D}\x{785E}\x{785F}\x{7860}\x{7861}' . '\x{7862}\x{7863}\x{7864}\x{7865}\x{7866}\x{7867}\x{7868}\x{7869}\x{786A}' . '\x{786B}\x{786C}\x{786D}\x{786E}\x{786F}\x{7870}\x{7871}\x{7872}\x{7873}' . '\x{7874}\x{7875}\x{7877}\x{7878}\x{7879}\x{787A}\x{787B}\x{787C}\x{787D}' . '\x{787E}\x{787F}\x{7880}\x{7881}\x{7882}\x{7883}\x{7884}\x{7885}\x{7886}' . '\x{7887}\x{7889}\x{788A}\x{788B}\x{788C}\x{788D}\x{788E}\x{788F}\x{7890}' . '\x{7891}\x{7892}\x{7893}\x{7894}\x{7895}\x{7896}\x{7897}\x{7898}\x{7899}' . '\x{789A}\x{789B}\x{789C}\x{789D}\x{789E}\x{789F}\x{78A0}\x{78A1}\x{78A2}' . '\x{78A3}\x{78A4}\x{78A5}\x{78A6}\x{78A7}\x{78A8}\x{78A9}\x{78AA}\x{78AB}' . '\x{78AC}\x{78AD}\x{78AE}\x{78AF}\x{78B0}\x{78B1}\x{78B2}\x{78B3}\x{78B4}' . '\x{78B5}\x{78B6}\x{78B7}\x{78B8}\x{78B9}\x{78BA}\x{78BB}\x{78BC}\x{78BD}' . '\x{78BE}\x{78BF}\x{78C0}\x{78C1}\x{78C3}\x{78C4}\x{78C5}\x{78C6}\x{78C8}' . '\x{78C9}\x{78CA}\x{78CB}\x{78CC}\x{78CD}\x{78CE}\x{78CF}\x{78D0}\x{78D1}' . '\x{78D3}\x{78D4}\x{78D5}\x{78D6}\x{78D7}\x{78D8}\x{78D9}\x{78DA}\x{78DB}' . '\x{78DC}\x{78DD}\x{78DE}\x{78DF}\x{78E0}\x{78E1}\x{78E2}\x{78E3}\x{78E4}' . '\x{78E5}\x{78E6}\x{78E7}\x{78E8}\x{78E9}\x{78EA}\x{78EB}\x{78EC}\x{78ED}' . '\x{78EE}\x{78EF}\x{78F1}\x{78F2}\x{78F3}\x{78F4}\x{78F5}\x{78F6}\x{78F7}' . '\x{78F9}\x{78FA}\x{78FB}\x{78FC}\x{78FD}\x{78FE}\x{78FF}\x{7901}\x{7902}' . '\x{7903}\x{7904}\x{7905}\x{7906}\x{7907}\x{7909}\x{790A}\x{790B}\x{790C}' . '\x{790E}\x{790F}\x{7910}\x{7911}\x{7912}\x{7913}\x{7914}\x{7916}\x{7917}' . '\x{7918}\x{7919}\x{791A}\x{791B}\x{791C}\x{791D}\x{791E}\x{7921}\x{7922}' . '\x{7923}\x{7924}\x{7925}\x{7926}\x{7927}\x{7928}\x{7929}\x{792A}\x{792B}' . '\x{792C}\x{792D}\x{792E}\x{792F}\x{7930}\x{7931}\x{7933}\x{7934}\x{7935}' . '\x{7937}\x{7938}\x{7939}\x{793A}\x{793B}\x{793C}\x{793D}\x{793E}\x{793F}' . '\x{7940}\x{7941}\x{7942}\x{7943}\x{7944}\x{7945}\x{7946}\x{7947}\x{7948}' . '\x{7949}\x{794A}\x{794B}\x{794C}\x{794D}\x{794E}\x{794F}\x{7950}\x{7951}' . '\x{7952}\x{7953}\x{7954}\x{7955}\x{7956}\x{7957}\x{7958}\x{795A}\x{795B}' . '\x{795C}\x{795D}\x{795E}\x{795F}\x{7960}\x{7961}\x{7962}\x{7963}\x{7964}' . '\x{7965}\x{7966}\x{7967}\x{7968}\x{7969}\x{796A}\x{796B}\x{796D}\x{796F}' . '\x{7970}\x{7971}\x{7972}\x{7973}\x{7974}\x{7977}\x{7978}\x{7979}\x{797A}' . '\x{797B}\x{797C}\x{797D}\x{797E}\x{797F}\x{7980}\x{7981}\x{7982}\x{7983}' . '\x{7984}\x{7985}\x{7988}\x{7989}\x{798A}\x{798B}\x{798C}\x{798D}\x{798E}' . '\x{798F}\x{7990}\x{7991}\x{7992}\x{7993}\x{7994}\x{7995}\x{7996}\x{7997}' . '\x{7998}\x{7999}\x{799A}\x{799B}\x{799C}\x{799F}\x{79A0}\x{79A1}\x{79A2}' . '\x{79A3}\x{79A4}\x{79A5}\x{79A6}\x{79A7}\x{79A8}\x{79AA}\x{79AB}\x{79AC}' . '\x{79AD}\x{79AE}\x{79AF}\x{79B0}\x{79B1}\x{79B2}\x{79B3}\x{79B4}\x{79B5}' . '\x{79B6}\x{79B7}\x{79B8}\x{79B9}\x{79BA}\x{79BB}\x{79BD}\x{79BE}\x{79BF}' . '\x{79C0}\x{79C1}\x{79C2}\x{79C3}\x{79C5}\x{79C6}\x{79C8}\x{79C9}\x{79CA}' . '\x{79CB}\x{79CD}\x{79CE}\x{79CF}\x{79D0}\x{79D1}\x{79D2}\x{79D3}\x{79D5}' . '\x{79D6}\x{79D8}\x{79D9}\x{79DA}\x{79DB}\x{79DC}\x{79DD}\x{79DE}\x{79DF}' . '\x{79E0}\x{79E1}\x{79E2}\x{79E3}\x{79E4}\x{79E5}\x{79E6}\x{79E7}\x{79E8}' . '\x{79E9}\x{79EA}\x{79EB}\x{79EC}\x{79ED}\x{79EE}\x{79EF}\x{79F0}\x{79F1}' . '\x{79F2}\x{79F3}\x{79F4}\x{79F5}\x{79F6}\x{79F7}\x{79F8}\x{79F9}\x{79FA}' . '\x{79FB}\x{79FC}\x{79FD}\x{79FE}\x{79FF}\x{7A00}\x{7A02}\x{7A03}\x{7A04}' . '\x{7A05}\x{7A06}\x{7A08}\x{7A0A}\x{7A0B}\x{7A0C}\x{7A0D}\x{7A0E}\x{7A0F}' . '\x{7A10}\x{7A11}\x{7A12}\x{7A13}\x{7A14}\x{7A15}\x{7A16}\x{7A17}\x{7A18}' . '\x{7A19}\x{7A1A}\x{7A1B}\x{7A1C}\x{7A1D}\x{7A1E}\x{7A1F}\x{7A20}\x{7A21}' . '\x{7A22}\x{7A23}\x{7A24}\x{7A25}\x{7A26}\x{7A27}\x{7A28}\x{7A29}\x{7A2A}' . '\x{7A2B}\x{7A2D}\x{7A2E}\x{7A2F}\x{7A30}\x{7A31}\x{7A32}\x{7A33}\x{7A34}' . '\x{7A35}\x{7A37}\x{7A39}\x{7A3B}\x{7A3C}\x{7A3D}\x{7A3E}\x{7A3F}\x{7A40}' . '\x{7A41}\x{7A42}\x{7A43}\x{7A44}\x{7A45}\x{7A46}\x{7A47}\x{7A48}\x{7A49}' . '\x{7A4A}\x{7A4B}\x{7A4C}\x{7A4D}\x{7A4E}\x{7A50}\x{7A51}\x{7A52}\x{7A53}' . '\x{7A54}\x{7A55}\x{7A56}\x{7A57}\x{7A58}\x{7A59}\x{7A5A}\x{7A5B}\x{7A5C}' . '\x{7A5D}\x{7A5E}\x{7A5F}\x{7A60}\x{7A61}\x{7A62}\x{7A65}\x{7A66}\x{7A67}' . '\x{7A68}\x{7A69}\x{7A6B}\x{7A6C}\x{7A6D}\x{7A6E}\x{7A70}\x{7A71}\x{7A72}' . '\x{7A73}\x{7A74}\x{7A75}\x{7A76}\x{7A77}\x{7A78}\x{7A79}\x{7A7A}\x{7A7B}' . '\x{7A7C}\x{7A7D}\x{7A7E}\x{7A7F}\x{7A80}\x{7A81}\x{7A83}\x{7A84}\x{7A85}' . '\x{7A86}\x{7A87}\x{7A88}\x{7A89}\x{7A8A}\x{7A8B}\x{7A8C}\x{7A8D}\x{7A8E}' . '\x{7A8F}\x{7A90}\x{7A91}\x{7A92}\x{7A93}\x{7A94}\x{7A95}\x{7A96}\x{7A97}' . '\x{7A98}\x{7A99}\x{7A9C}\x{7A9D}\x{7A9E}\x{7A9F}\x{7AA0}\x{7AA1}\x{7AA2}' . '\x{7AA3}\x{7AA4}\x{7AA5}\x{7AA6}\x{7AA7}\x{7AA8}\x{7AA9}\x{7AAA}\x{7AAB}' . '\x{7AAC}\x{7AAD}\x{7AAE}\x{7AAF}\x{7AB0}\x{7AB1}\x{7AB2}\x{7AB3}\x{7AB4}' . '\x{7AB5}\x{7AB6}\x{7AB7}\x{7AB8}\x{7ABA}\x{7ABE}\x{7ABF}\x{7AC0}\x{7AC1}' . '\x{7AC4}\x{7AC5}\x{7AC7}\x{7AC8}\x{7AC9}\x{7ACA}\x{7ACB}\x{7ACC}\x{7ACD}' . '\x{7ACE}\x{7ACF}\x{7AD0}\x{7AD1}\x{7AD2}\x{7AD3}\x{7AD4}\x{7AD5}\x{7AD6}' . '\x{7AD8}\x{7AD9}\x{7ADB}\x{7ADC}\x{7ADD}\x{7ADE}\x{7ADF}\x{7AE0}\x{7AE1}' . '\x{7AE2}\x{7AE3}\x{7AE4}\x{7AE5}\x{7AE6}\x{7AE7}\x{7AE8}\x{7AEA}\x{7AEB}' . '\x{7AEC}\x{7AED}\x{7AEE}\x{7AEF}\x{7AF0}\x{7AF1}\x{7AF2}\x{7AF3}\x{7AF4}' . '\x{7AF6}\x{7AF7}\x{7AF8}\x{7AF9}\x{7AFA}\x{7AFB}\x{7AFD}\x{7AFE}\x{7AFF}' . '\x{7B00}\x{7B01}\x{7B02}\x{7B03}\x{7B04}\x{7B05}\x{7B06}\x{7B08}\x{7B09}' . '\x{7B0A}\x{7B0B}\x{7B0C}\x{7B0D}\x{7B0E}\x{7B0F}\x{7B10}\x{7B11}\x{7B12}' . '\x{7B13}\x{7B14}\x{7B15}\x{7B16}\x{7B17}\x{7B18}\x{7B19}\x{7B1A}\x{7B1B}' . '\x{7B1C}\x{7B1D}\x{7B1E}\x{7B20}\x{7B21}\x{7B22}\x{7B23}\x{7B24}\x{7B25}' . '\x{7B26}\x{7B28}\x{7B2A}\x{7B2B}\x{7B2C}\x{7B2D}\x{7B2E}\x{7B2F}\x{7B30}' . '\x{7B31}\x{7B32}\x{7B33}\x{7B34}\x{7B35}\x{7B36}\x{7B37}\x{7B38}\x{7B39}' . '\x{7B3A}\x{7B3B}\x{7B3C}\x{7B3D}\x{7B3E}\x{7B3F}\x{7B40}\x{7B41}\x{7B43}' . '\x{7B44}\x{7B45}\x{7B46}\x{7B47}\x{7B48}\x{7B49}\x{7B4A}\x{7B4B}\x{7B4C}' . '\x{7B4D}\x{7B4E}\x{7B4F}\x{7B50}\x{7B51}\x{7B52}\x{7B54}\x{7B55}\x{7B56}' . '\x{7B57}\x{7B58}\x{7B59}\x{7B5A}\x{7B5B}\x{7B5C}\x{7B5D}\x{7B5E}\x{7B5F}' . '\x{7B60}\x{7B61}\x{7B62}\x{7B63}\x{7B64}\x{7B65}\x{7B66}\x{7B67}\x{7B68}' . '\x{7B69}\x{7B6A}\x{7B6B}\x{7B6C}\x{7B6D}\x{7B6E}\x{7B70}\x{7B71}\x{7B72}' . '\x{7B73}\x{7B74}\x{7B75}\x{7B76}\x{7B77}\x{7B78}\x{7B79}\x{7B7B}\x{7B7C}' . '\x{7B7D}\x{7B7E}\x{7B7F}\x{7B80}\x{7B81}\x{7B82}\x{7B83}\x{7B84}\x{7B85}' . '\x{7B87}\x{7B88}\x{7B89}\x{7B8A}\x{7B8B}\x{7B8C}\x{7B8D}\x{7B8E}\x{7B8F}' . '\x{7B90}\x{7B91}\x{7B93}\x{7B94}\x{7B95}\x{7B96}\x{7B97}\x{7B98}\x{7B99}' . '\x{7B9A}\x{7B9B}\x{7B9C}\x{7B9D}\x{7B9E}\x{7B9F}\x{7BA0}\x{7BA1}\x{7BA2}' . '\x{7BA4}\x{7BA6}\x{7BA7}\x{7BA8}\x{7BA9}\x{7BAA}\x{7BAB}\x{7BAC}\x{7BAD}' . '\x{7BAE}\x{7BAF}\x{7BB1}\x{7BB3}\x{7BB4}\x{7BB5}\x{7BB6}\x{7BB7}\x{7BB8}' . '\x{7BB9}\x{7BBA}\x{7BBB}\x{7BBC}\x{7BBD}\x{7BBE}\x{7BBF}\x{7BC0}\x{7BC1}' . '\x{7BC2}\x{7BC3}\x{7BC4}\x{7BC5}\x{7BC6}\x{7BC7}\x{7BC8}\x{7BC9}\x{7BCA}' . '\x{7BCB}\x{7BCC}\x{7BCD}\x{7BCE}\x{7BD0}\x{7BD1}\x{7BD2}\x{7BD3}\x{7BD4}' . '\x{7BD5}\x{7BD6}\x{7BD7}\x{7BD8}\x{7BD9}\x{7BDA}\x{7BDB}\x{7BDC}\x{7BDD}' . '\x{7BDE}\x{7BDF}\x{7BE0}\x{7BE1}\x{7BE2}\x{7BE3}\x{7BE4}\x{7BE5}\x{7BE6}' . '\x{7BE7}\x{7BE8}\x{7BE9}\x{7BEA}\x{7BEB}\x{7BEC}\x{7BED}\x{7BEE}\x{7BEF}' . '\x{7BF0}\x{7BF1}\x{7BF2}\x{7BF3}\x{7BF4}\x{7BF5}\x{7BF6}\x{7BF7}\x{7BF8}' . '\x{7BF9}\x{7BFB}\x{7BFC}\x{7BFD}\x{7BFE}\x{7BFF}\x{7C00}\x{7C01}\x{7C02}' . '\x{7C03}\x{7C04}\x{7C05}\x{7C06}\x{7C07}\x{7C08}\x{7C09}\x{7C0A}\x{7C0B}' . '\x{7C0C}\x{7C0D}\x{7C0E}\x{7C0F}\x{7C10}\x{7C11}\x{7C12}\x{7C13}\x{7C15}' . '\x{7C16}\x{7C17}\x{7C18}\x{7C19}\x{7C1A}\x{7C1C}\x{7C1D}\x{7C1E}\x{7C1F}' . '\x{7C20}\x{7C21}\x{7C22}\x{7C23}\x{7C24}\x{7C25}\x{7C26}\x{7C27}\x{7C28}' . '\x{7C29}\x{7C2A}\x{7C2B}\x{7C2C}\x{7C2D}\x{7C30}\x{7C31}\x{7C32}\x{7C33}' . '\x{7C34}\x{7C35}\x{7C36}\x{7C37}\x{7C38}\x{7C39}\x{7C3A}\x{7C3B}\x{7C3C}' . '\x{7C3D}\x{7C3E}\x{7C3F}\x{7C40}\x{7C41}\x{7C42}\x{7C43}\x{7C44}\x{7C45}' . '\x{7C46}\x{7C47}\x{7C48}\x{7C49}\x{7C4A}\x{7C4B}\x{7C4C}\x{7C4D}\x{7C4E}' . '\x{7C50}\x{7C51}\x{7C53}\x{7C54}\x{7C56}\x{7C57}\x{7C58}\x{7C59}\x{7C5A}' . '\x{7C5B}\x{7C5C}\x{7C5E}\x{7C5F}\x{7C60}\x{7C61}\x{7C62}\x{7C63}\x{7C64}' . '\x{7C65}\x{7C66}\x{7C67}\x{7C68}\x{7C69}\x{7C6A}\x{7C6B}\x{7C6C}\x{7C6D}' . '\x{7C6E}\x{7C6F}\x{7C70}\x{7C71}\x{7C72}\x{7C73}\x{7C74}\x{7C75}\x{7C77}' . '\x{7C78}\x{7C79}\x{7C7A}\x{7C7B}\x{7C7C}\x{7C7D}\x{7C7E}\x{7C7F}\x{7C80}' . '\x{7C81}\x{7C82}\x{7C84}\x{7C85}\x{7C86}\x{7C88}\x{7C89}\x{7C8A}\x{7C8B}' . '\x{7C8C}\x{7C8D}\x{7C8E}\x{7C8F}\x{7C90}\x{7C91}\x{7C92}\x{7C94}\x{7C95}' . '\x{7C96}\x{7C97}\x{7C98}\x{7C99}\x{7C9B}\x{7C9C}\x{7C9D}\x{7C9E}\x{7C9F}' . '\x{7CA0}\x{7CA1}\x{7CA2}\x{7CA3}\x{7CA4}\x{7CA5}\x{7CA6}\x{7CA7}\x{7CA8}' . '\x{7CA9}\x{7CAA}\x{7CAD}\x{7CAE}\x{7CAF}\x{7CB0}\x{7CB1}\x{7CB2}\x{7CB3}' . '\x{7CB4}\x{7CB5}\x{7CB6}\x{7CB7}\x{7CB8}\x{7CB9}\x{7CBA}\x{7CBB}\x{7CBC}' . '\x{7CBD}\x{7CBE}\x{7CBF}\x{7CC0}\x{7CC1}\x{7CC2}\x{7CC3}\x{7CC4}\x{7CC5}' . '\x{7CC6}\x{7CC7}\x{7CC8}\x{7CC9}\x{7CCA}\x{7CCB}\x{7CCC}\x{7CCD}\x{7CCE}' . '\x{7CCF}\x{7CD0}\x{7CD1}\x{7CD2}\x{7CD4}\x{7CD5}\x{7CD6}\x{7CD7}\x{7CD8}' . '\x{7CD9}\x{7CDC}\x{7CDD}\x{7CDE}\x{7CDF}\x{7CE0}\x{7CE2}\x{7CE4}\x{7CE7}' . '\x{7CE8}\x{7CE9}\x{7CEA}\x{7CEB}\x{7CEC}\x{7CED}\x{7CEE}\x{7CEF}\x{7CF0}' . '\x{7CF1}\x{7CF2}\x{7CF3}\x{7CF4}\x{7CF5}\x{7CF6}\x{7CF7}\x{7CF8}\x{7CF9}' . '\x{7CFA}\x{7CFB}\x{7CFD}\x{7CFE}\x{7D00}\x{7D01}\x{7D02}\x{7D03}\x{7D04}' . '\x{7D05}\x{7D06}\x{7D07}\x{7D08}\x{7D09}\x{7D0A}\x{7D0B}\x{7D0C}\x{7D0D}' . '\x{7D0E}\x{7D0F}\x{7D10}\x{7D11}\x{7D12}\x{7D13}\x{7D14}\x{7D15}\x{7D16}' . '\x{7D17}\x{7D18}\x{7D19}\x{7D1A}\x{7D1B}\x{7D1C}\x{7D1D}\x{7D1E}\x{7D1F}' . '\x{7D20}\x{7D21}\x{7D22}\x{7D24}\x{7D25}\x{7D26}\x{7D27}\x{7D28}\x{7D29}' . '\x{7D2B}\x{7D2C}\x{7D2E}\x{7D2F}\x{7D30}\x{7D31}\x{7D32}\x{7D33}\x{7D34}' . '\x{7D35}\x{7D36}\x{7D37}\x{7D38}\x{7D39}\x{7D3A}\x{7D3B}\x{7D3C}\x{7D3D}' . '\x{7D3E}\x{7D3F}\x{7D40}\x{7D41}\x{7D42}\x{7D43}\x{7D44}\x{7D45}\x{7D46}' . '\x{7D47}\x{7D49}\x{7D4A}\x{7D4B}\x{7D4C}\x{7D4E}\x{7D4F}\x{7D50}\x{7D51}' . '\x{7D52}\x{7D53}\x{7D54}\x{7D55}\x{7D56}\x{7D57}\x{7D58}\x{7D59}\x{7D5B}' . '\x{7D5C}\x{7D5D}\x{7D5E}\x{7D5F}\x{7D60}\x{7D61}\x{7D62}\x{7D63}\x{7D65}' . '\x{7D66}\x{7D67}\x{7D68}\x{7D69}\x{7D6A}\x{7D6B}\x{7D6C}\x{7D6D}\x{7D6E}' . '\x{7D6F}\x{7D70}\x{7D71}\x{7D72}\x{7D73}\x{7D74}\x{7D75}\x{7D76}\x{7D77}' . '\x{7D79}\x{7D7A}\x{7D7B}\x{7D7C}\x{7D7D}\x{7D7E}\x{7D7F}\x{7D80}\x{7D81}' . '\x{7D83}\x{7D84}\x{7D85}\x{7D86}\x{7D87}\x{7D88}\x{7D89}\x{7D8A}\x{7D8B}' . '\x{7D8C}\x{7D8D}\x{7D8E}\x{7D8F}\x{7D90}\x{7D91}\x{7D92}\x{7D93}\x{7D94}' . '\x{7D96}\x{7D97}\x{7D99}\x{7D9B}\x{7D9C}\x{7D9D}\x{7D9E}\x{7D9F}\x{7DA0}' . '\x{7DA1}\x{7DA2}\x{7DA3}\x{7DA5}\x{7DA6}\x{7DA7}\x{7DA9}\x{7DAA}\x{7DAB}' . '\x{7DAC}\x{7DAD}\x{7DAE}\x{7DAF}\x{7DB0}\x{7DB1}\x{7DB2}\x{7DB3}\x{7DB4}' . '\x{7DB5}\x{7DB6}\x{7DB7}\x{7DB8}\x{7DB9}\x{7DBA}\x{7DBB}\x{7DBC}\x{7DBD}' . '\x{7DBE}\x{7DBF}\x{7DC0}\x{7DC1}\x{7DC2}\x{7DC3}\x{7DC4}\x{7DC5}\x{7DC6}' . '\x{7DC7}\x{7DC8}\x{7DC9}\x{7DCA}\x{7DCB}\x{7DCC}\x{7DCE}\x{7DCF}\x{7DD0}' . '\x{7DD1}\x{7DD2}\x{7DD4}\x{7DD5}\x{7DD6}\x{7DD7}\x{7DD8}\x{7DD9}\x{7DDA}' . '\x{7DDB}\x{7DDD}\x{7DDE}\x{7DDF}\x{7DE0}\x{7DE1}\x{7DE2}\x{7DE3}\x{7DE6}' . '\x{7DE7}\x{7DE8}\x{7DE9}\x{7DEA}\x{7DEC}\x{7DED}\x{7DEE}\x{7DEF}\x{7DF0}' . '\x{7DF1}\x{7DF2}\x{7DF3}\x{7DF4}\x{7DF5}\x{7DF6}\x{7DF7}\x{7DF8}\x{7DF9}' . '\x{7DFA}\x{7DFB}\x{7DFC}\x{7E00}\x{7E01}\x{7E02}\x{7E03}\x{7E04}\x{7E05}' . '\x{7E06}\x{7E07}\x{7E08}\x{7E09}\x{7E0A}\x{7E0B}\x{7E0C}\x{7E0D}\x{7E0E}' . '\x{7E0F}\x{7E10}\x{7E11}\x{7E12}\x{7E13}\x{7E14}\x{7E15}\x{7E16}\x{7E17}' . '\x{7E19}\x{7E1A}\x{7E1B}\x{7E1C}\x{7E1D}\x{7E1E}\x{7E1F}\x{7E20}\x{7E21}' . '\x{7E22}\x{7E23}\x{7E24}\x{7E25}\x{7E26}\x{7E27}\x{7E28}\x{7E29}\x{7E2A}' . '\x{7E2B}\x{7E2C}\x{7E2D}\x{7E2E}\x{7E2F}\x{7E30}\x{7E31}\x{7E32}\x{7E33}' . '\x{7E34}\x{7E35}\x{7E36}\x{7E37}\x{7E38}\x{7E39}\x{7E3A}\x{7E3B}\x{7E3C}' . '\x{7E3D}\x{7E3E}\x{7E3F}\x{7E40}\x{7E41}\x{7E42}\x{7E43}\x{7E44}\x{7E45}' . '\x{7E46}\x{7E47}\x{7E48}\x{7E49}\x{7E4C}\x{7E4D}\x{7E4E}\x{7E4F}\x{7E50}' . '\x{7E51}\x{7E52}\x{7E53}\x{7E54}\x{7E55}\x{7E56}\x{7E57}\x{7E58}\x{7E59}' . '\x{7E5A}\x{7E5C}\x{7E5D}\x{7E5E}\x{7E5F}\x{7E60}\x{7E61}\x{7E62}\x{7E63}' . '\x{7E65}\x{7E66}\x{7E67}\x{7E68}\x{7E69}\x{7E6A}\x{7E6B}\x{7E6C}\x{7E6D}' . '\x{7E6E}\x{7E6F}\x{7E70}\x{7E71}\x{7E72}\x{7E73}\x{7E74}\x{7E75}\x{7E76}' . '\x{7E77}\x{7E78}\x{7E79}\x{7E7A}\x{7E7B}\x{7E7C}\x{7E7D}\x{7E7E}\x{7E7F}' . '\x{7E80}\x{7E81}\x{7E82}\x{7E83}\x{7E84}\x{7E85}\x{7E86}\x{7E87}\x{7E88}' . '\x{7E89}\x{7E8A}\x{7E8B}\x{7E8C}\x{7E8D}\x{7E8E}\x{7E8F}\x{7E90}\x{7E91}' . '\x{7E92}\x{7E93}\x{7E94}\x{7E95}\x{7E96}\x{7E97}\x{7E98}\x{7E99}\x{7E9A}' . '\x{7E9B}\x{7E9C}\x{7E9E}\x{7E9F}\x{7EA0}\x{7EA1}\x{7EA2}\x{7EA3}\x{7EA4}' . '\x{7EA5}\x{7EA6}\x{7EA7}\x{7EA8}\x{7EA9}\x{7EAA}\x{7EAB}\x{7EAC}\x{7EAD}' . '\x{7EAE}\x{7EAF}\x{7EB0}\x{7EB1}\x{7EB2}\x{7EB3}\x{7EB4}\x{7EB5}\x{7EB6}' . '\x{7EB7}\x{7EB8}\x{7EB9}\x{7EBA}\x{7EBB}\x{7EBC}\x{7EBD}\x{7EBE}\x{7EBF}' . '\x{7EC0}\x{7EC1}\x{7EC2}\x{7EC3}\x{7EC4}\x{7EC5}\x{7EC6}\x{7EC7}\x{7EC8}' . '\x{7EC9}\x{7ECA}\x{7ECB}\x{7ECC}\x{7ECD}\x{7ECE}\x{7ECF}\x{7ED0}\x{7ED1}' . '\x{7ED2}\x{7ED3}\x{7ED4}\x{7ED5}\x{7ED6}\x{7ED7}\x{7ED8}\x{7ED9}\x{7EDA}' . '\x{7EDB}\x{7EDC}\x{7EDD}\x{7EDE}\x{7EDF}\x{7EE0}\x{7EE1}\x{7EE2}\x{7EE3}' . '\x{7EE4}\x{7EE5}\x{7EE6}\x{7EE7}\x{7EE8}\x{7EE9}\x{7EEA}\x{7EEB}\x{7EEC}' . '\x{7EED}\x{7EEE}\x{7EEF}\x{7EF0}\x{7EF1}\x{7EF2}\x{7EF3}\x{7EF4}\x{7EF5}' . '\x{7EF6}\x{7EF7}\x{7EF8}\x{7EF9}\x{7EFA}\x{7EFB}\x{7EFC}\x{7EFD}\x{7EFE}' . '\x{7EFF}\x{7F00}\x{7F01}\x{7F02}\x{7F03}\x{7F04}\x{7F05}\x{7F06}\x{7F07}' . '\x{7F08}\x{7F09}\x{7F0A}\x{7F0B}\x{7F0C}\x{7F0D}\x{7F0E}\x{7F0F}\x{7F10}' . '\x{7F11}\x{7F12}\x{7F13}\x{7F14}\x{7F15}\x{7F16}\x{7F17}\x{7F18}\x{7F19}' . '\x{7F1A}\x{7F1B}\x{7F1C}\x{7F1D}\x{7F1E}\x{7F1F}\x{7F20}\x{7F21}\x{7F22}' . '\x{7F23}\x{7F24}\x{7F25}\x{7F26}\x{7F27}\x{7F28}\x{7F29}\x{7F2A}\x{7F2B}' . '\x{7F2C}\x{7F2D}\x{7F2E}\x{7F2F}\x{7F30}\x{7F31}\x{7F32}\x{7F33}\x{7F34}' . '\x{7F35}\x{7F36}\x{7F37}\x{7F38}\x{7F39}\x{7F3A}\x{7F3D}\x{7F3E}\x{7F3F}' . '\x{7F40}\x{7F42}\x{7F43}\x{7F44}\x{7F45}\x{7F47}\x{7F48}\x{7F49}\x{7F4A}' . '\x{7F4B}\x{7F4C}\x{7F4D}\x{7F4E}\x{7F4F}\x{7F50}\x{7F51}\x{7F52}\x{7F53}' . '\x{7F54}\x{7F55}\x{7F56}\x{7F57}\x{7F58}\x{7F5A}\x{7F5B}\x{7F5C}\x{7F5D}' . '\x{7F5E}\x{7F5F}\x{7F60}\x{7F61}\x{7F62}\x{7F63}\x{7F64}\x{7F65}\x{7F66}' . '\x{7F67}\x{7F68}\x{7F69}\x{7F6A}\x{7F6B}\x{7F6C}\x{7F6D}\x{7F6E}\x{7F6F}' . '\x{7F70}\x{7F71}\x{7F72}\x{7F73}\x{7F74}\x{7F75}\x{7F76}\x{7F77}\x{7F78}' . '\x{7F79}\x{7F7A}\x{7F7B}\x{7F7C}\x{7F7D}\x{7F7E}\x{7F7F}\x{7F80}\x{7F81}' . '\x{7F82}\x{7F83}\x{7F85}\x{7F86}\x{7F87}\x{7F88}\x{7F89}\x{7F8A}\x{7F8B}' . '\x{7F8C}\x{7F8D}\x{7F8E}\x{7F8F}\x{7F91}\x{7F92}\x{7F93}\x{7F94}\x{7F95}' . '\x{7F96}\x{7F98}\x{7F9A}\x{7F9B}\x{7F9C}\x{7F9D}\x{7F9E}\x{7F9F}\x{7FA0}' . '\x{7FA1}\x{7FA2}\x{7FA3}\x{7FA4}\x{7FA5}\x{7FA6}\x{7FA7}\x{7FA8}\x{7FA9}' . '\x{7FAA}\x{7FAB}\x{7FAC}\x{7FAD}\x{7FAE}\x{7FAF}\x{7FB0}\x{7FB1}\x{7FB2}' . '\x{7FB3}\x{7FB5}\x{7FB6}\x{7FB7}\x{7FB8}\x{7FB9}\x{7FBA}\x{7FBB}\x{7FBC}' . '\x{7FBD}\x{7FBE}\x{7FBF}\x{7FC0}\x{7FC1}\x{7FC2}\x{7FC3}\x{7FC4}\x{7FC5}' . '\x{7FC6}\x{7FC7}\x{7FC8}\x{7FC9}\x{7FCA}\x{7FCB}\x{7FCC}\x{7FCD}\x{7FCE}' . '\x{7FCF}\x{7FD0}\x{7FD1}\x{7FD2}\x{7FD3}\x{7FD4}\x{7FD5}\x{7FD7}\x{7FD8}' . '\x{7FD9}\x{7FDA}\x{7FDB}\x{7FDC}\x{7FDE}\x{7FDF}\x{7FE0}\x{7FE1}\x{7FE2}' . '\x{7FE3}\x{7FE5}\x{7FE6}\x{7FE7}\x{7FE8}\x{7FE9}\x{7FEA}\x{7FEB}\x{7FEC}' . '\x{7FED}\x{7FEE}\x{7FEF}\x{7FF0}\x{7FF1}\x{7FF2}\x{7FF3}\x{7FF4}\x{7FF5}' . '\x{7FF6}\x{7FF7}\x{7FF8}\x{7FF9}\x{7FFA}\x{7FFB}\x{7FFC}\x{7FFD}\x{7FFE}' . '\x{7FFF}\x{8000}\x{8001}\x{8002}\x{8003}\x{8004}\x{8005}\x{8006}\x{8007}' . '\x{8008}\x{8009}\x{800B}\x{800C}\x{800D}\x{800E}\x{800F}\x{8010}\x{8011}' . '\x{8012}\x{8013}\x{8014}\x{8015}\x{8016}\x{8017}\x{8018}\x{8019}\x{801A}' . '\x{801B}\x{801C}\x{801D}\x{801E}\x{801F}\x{8020}\x{8021}\x{8022}\x{8023}' . '\x{8024}\x{8025}\x{8026}\x{8027}\x{8028}\x{8029}\x{802A}\x{802B}\x{802C}' . '\x{802D}\x{802E}\x{8030}\x{8031}\x{8032}\x{8033}\x{8034}\x{8035}\x{8036}' . '\x{8037}\x{8038}\x{8039}\x{803A}\x{803B}\x{803D}\x{803E}\x{803F}\x{8041}' . '\x{8042}\x{8043}\x{8044}\x{8045}\x{8046}\x{8047}\x{8048}\x{8049}\x{804A}' . '\x{804B}\x{804C}\x{804D}\x{804E}\x{804F}\x{8050}\x{8051}\x{8052}\x{8053}' . '\x{8054}\x{8055}\x{8056}\x{8057}\x{8058}\x{8059}\x{805A}\x{805B}\x{805C}' . '\x{805D}\x{805E}\x{805F}\x{8060}\x{8061}\x{8062}\x{8063}\x{8064}\x{8065}' . '\x{8067}\x{8068}\x{8069}\x{806A}\x{806B}\x{806C}\x{806D}\x{806E}\x{806F}' . '\x{8070}\x{8071}\x{8072}\x{8073}\x{8074}\x{8075}\x{8076}\x{8077}\x{8078}' . '\x{8079}\x{807A}\x{807B}\x{807C}\x{807D}\x{807E}\x{807F}\x{8080}\x{8081}' . '\x{8082}\x{8083}\x{8084}\x{8085}\x{8086}\x{8087}\x{8089}\x{808A}\x{808B}' . '\x{808C}\x{808D}\x{808F}\x{8090}\x{8091}\x{8092}\x{8093}\x{8095}\x{8096}' . '\x{8097}\x{8098}\x{8099}\x{809A}\x{809B}\x{809C}\x{809D}\x{809E}\x{809F}' . '\x{80A0}\x{80A1}\x{80A2}\x{80A3}\x{80A4}\x{80A5}\x{80A9}\x{80AA}\x{80AB}' . '\x{80AD}\x{80AE}\x{80AF}\x{80B0}\x{80B1}\x{80B2}\x{80B4}\x{80B5}\x{80B6}' . '\x{80B7}\x{80B8}\x{80BA}\x{80BB}\x{80BC}\x{80BD}\x{80BE}\x{80BF}\x{80C0}' . '\x{80C1}\x{80C2}\x{80C3}\x{80C4}\x{80C5}\x{80C6}\x{80C7}\x{80C8}\x{80C9}' . '\x{80CA}\x{80CB}\x{80CC}\x{80CD}\x{80CE}\x{80CF}\x{80D0}\x{80D1}\x{80D2}' . '\x{80D3}\x{80D4}\x{80D5}\x{80D6}\x{80D7}\x{80D8}\x{80D9}\x{80DA}\x{80DB}' . '\x{80DC}\x{80DD}\x{80DE}\x{80E0}\x{80E1}\x{80E2}\x{80E3}\x{80E4}\x{80E5}' . '\x{80E6}\x{80E7}\x{80E8}\x{80E9}\x{80EA}\x{80EB}\x{80EC}\x{80ED}\x{80EE}' . '\x{80EF}\x{80F0}\x{80F1}\x{80F2}\x{80F3}\x{80F4}\x{80F5}\x{80F6}\x{80F7}' . '\x{80F8}\x{80F9}\x{80FA}\x{80FB}\x{80FC}\x{80FD}\x{80FE}\x{80FF}\x{8100}' . '\x{8101}\x{8102}\x{8105}\x{8106}\x{8107}\x{8108}\x{8109}\x{810A}\x{810B}' . '\x{810C}\x{810D}\x{810E}\x{810F}\x{8110}\x{8111}\x{8112}\x{8113}\x{8114}' . '\x{8115}\x{8116}\x{8118}\x{8119}\x{811A}\x{811B}\x{811C}\x{811D}\x{811E}' . '\x{811F}\x{8120}\x{8121}\x{8122}\x{8123}\x{8124}\x{8125}\x{8126}\x{8127}' . '\x{8128}\x{8129}\x{812A}\x{812B}\x{812C}\x{812D}\x{812E}\x{812F}\x{8130}' . '\x{8131}\x{8132}\x{8136}\x{8137}\x{8138}\x{8139}\x{813A}\x{813B}\x{813C}' . '\x{813D}\x{813E}\x{813F}\x{8140}\x{8141}\x{8142}\x{8143}\x{8144}\x{8145}' . '\x{8146}\x{8147}\x{8148}\x{8149}\x{814A}\x{814B}\x{814C}\x{814D}\x{814E}' . '\x{814F}\x{8150}\x{8151}\x{8152}\x{8153}\x{8154}\x{8155}\x{8156}\x{8157}' . '\x{8158}\x{8159}\x{815A}\x{815B}\x{815C}\x{815D}\x{815E}\x{8160}\x{8161}' . '\x{8162}\x{8163}\x{8164}\x{8165}\x{8166}\x{8167}\x{8168}\x{8169}\x{816A}' . '\x{816B}\x{816C}\x{816D}\x{816E}\x{816F}\x{8170}\x{8171}\x{8172}\x{8173}' . '\x{8174}\x{8175}\x{8176}\x{8177}\x{8178}\x{8179}\x{817A}\x{817B}\x{817C}' . '\x{817D}\x{817E}\x{817F}\x{8180}\x{8181}\x{8182}\x{8183}\x{8185}\x{8186}' . '\x{8187}\x{8188}\x{8189}\x{818A}\x{818B}\x{818C}\x{818D}\x{818E}\x{818F}' . '\x{8191}\x{8192}\x{8193}\x{8194}\x{8195}\x{8197}\x{8198}\x{8199}\x{819A}' . '\x{819B}\x{819C}\x{819D}\x{819E}\x{819F}\x{81A0}\x{81A1}\x{81A2}\x{81A3}' . '\x{81A4}\x{81A5}\x{81A6}\x{81A7}\x{81A8}\x{81A9}\x{81AA}\x{81AB}\x{81AC}' . '\x{81AD}\x{81AE}\x{81AF}\x{81B0}\x{81B1}\x{81B2}\x{81B3}\x{81B4}\x{81B5}' . '\x{81B6}\x{81B7}\x{81B8}\x{81B9}\x{81BA}\x{81BB}\x{81BC}\x{81BD}\x{81BE}' . '\x{81BF}\x{81C0}\x{81C1}\x{81C2}\x{81C3}\x{81C4}\x{81C5}\x{81C6}\x{81C7}' . '\x{81C8}\x{81C9}\x{81CA}\x{81CC}\x{81CD}\x{81CE}\x{81CF}\x{81D0}\x{81D1}' . '\x{81D2}\x{81D4}\x{81D5}\x{81D6}\x{81D7}\x{81D8}\x{81D9}\x{81DA}\x{81DB}' . '\x{81DC}\x{81DD}\x{81DE}\x{81DF}\x{81E0}\x{81E1}\x{81E2}\x{81E3}\x{81E5}' . '\x{81E6}\x{81E7}\x{81E8}\x{81E9}\x{81EA}\x{81EB}\x{81EC}\x{81ED}\x{81EE}' . '\x{81F1}\x{81F2}\x{81F3}\x{81F4}\x{81F5}\x{81F6}\x{81F7}\x{81F8}\x{81F9}' . '\x{81FA}\x{81FB}\x{81FC}\x{81FD}\x{81FE}\x{81FF}\x{8200}\x{8201}\x{8202}' . '\x{8203}\x{8204}\x{8205}\x{8206}\x{8207}\x{8208}\x{8209}\x{820A}\x{820B}' . '\x{820C}\x{820D}\x{820E}\x{820F}\x{8210}\x{8211}\x{8212}\x{8214}\x{8215}' . '\x{8216}\x{8218}\x{8219}\x{821A}\x{821B}\x{821C}\x{821D}\x{821E}\x{821F}' . '\x{8220}\x{8221}\x{8222}\x{8223}\x{8225}\x{8226}\x{8227}\x{8228}\x{8229}' . '\x{822A}\x{822B}\x{822C}\x{822D}\x{822F}\x{8230}\x{8231}\x{8232}\x{8233}' . '\x{8234}\x{8235}\x{8236}\x{8237}\x{8238}\x{8239}\x{823A}\x{823B}\x{823C}' . '\x{823D}\x{823E}\x{823F}\x{8240}\x{8242}\x{8243}\x{8244}\x{8245}\x{8246}' . '\x{8247}\x{8248}\x{8249}\x{824A}\x{824B}\x{824C}\x{824D}\x{824E}\x{824F}' . '\x{8250}\x{8251}\x{8252}\x{8253}\x{8254}\x{8255}\x{8256}\x{8257}\x{8258}' . '\x{8259}\x{825A}\x{825B}\x{825C}\x{825D}\x{825E}\x{825F}\x{8260}\x{8261}' . '\x{8263}\x{8264}\x{8266}\x{8267}\x{8268}\x{8269}\x{826A}\x{826B}\x{826C}' . '\x{826D}\x{826E}\x{826F}\x{8270}\x{8271}\x{8272}\x{8273}\x{8274}\x{8275}' . '\x{8276}\x{8277}\x{8278}\x{8279}\x{827A}\x{827B}\x{827C}\x{827D}\x{827E}' . '\x{827F}\x{8280}\x{8281}\x{8282}\x{8283}\x{8284}\x{8285}\x{8286}\x{8287}' . '\x{8288}\x{8289}\x{828A}\x{828B}\x{828D}\x{828E}\x{828F}\x{8290}\x{8291}' . '\x{8292}\x{8293}\x{8294}\x{8295}\x{8296}\x{8297}\x{8298}\x{8299}\x{829A}' . '\x{829B}\x{829C}\x{829D}\x{829E}\x{829F}\x{82A0}\x{82A1}\x{82A2}\x{82A3}' . '\x{82A4}\x{82A5}\x{82A6}\x{82A7}\x{82A8}\x{82A9}\x{82AA}\x{82AB}\x{82AC}' . '\x{82AD}\x{82AE}\x{82AF}\x{82B0}\x{82B1}\x{82B3}\x{82B4}\x{82B5}\x{82B6}' . '\x{82B7}\x{82B8}\x{82B9}\x{82BA}\x{82BB}\x{82BC}\x{82BD}\x{82BE}\x{82BF}' . '\x{82C0}\x{82C1}\x{82C2}\x{82C3}\x{82C4}\x{82C5}\x{82C6}\x{82C7}\x{82C8}' . '\x{82C9}\x{82CA}\x{82CB}\x{82CC}\x{82CD}\x{82CE}\x{82CF}\x{82D0}\x{82D1}' . '\x{82D2}\x{82D3}\x{82D4}\x{82D5}\x{82D6}\x{82D7}\x{82D8}\x{82D9}\x{82DA}' . '\x{82DB}\x{82DC}\x{82DD}\x{82DE}\x{82DF}\x{82E0}\x{82E1}\x{82E3}\x{82E4}' . '\x{82E5}\x{82E6}\x{82E7}\x{82E8}\x{82E9}\x{82EA}\x{82EB}\x{82EC}\x{82ED}' . '\x{82EE}\x{82EF}\x{82F0}\x{82F1}\x{82F2}\x{82F3}\x{82F4}\x{82F5}\x{82F6}' . '\x{82F7}\x{82F8}\x{82F9}\x{82FA}\x{82FB}\x{82FD}\x{82FE}\x{82FF}\x{8300}' . '\x{8301}\x{8302}\x{8303}\x{8304}\x{8305}\x{8306}\x{8307}\x{8308}\x{8309}' . '\x{830B}\x{830C}\x{830D}\x{830E}\x{830F}\x{8311}\x{8312}\x{8313}\x{8314}' . '\x{8315}\x{8316}\x{8317}\x{8318}\x{8319}\x{831A}\x{831B}\x{831C}\x{831D}' . '\x{831E}\x{831F}\x{8320}\x{8321}\x{8322}\x{8323}\x{8324}\x{8325}\x{8326}' . '\x{8327}\x{8328}\x{8329}\x{832A}\x{832B}\x{832C}\x{832D}\x{832E}\x{832F}' . '\x{8331}\x{8332}\x{8333}\x{8334}\x{8335}\x{8336}\x{8337}\x{8338}\x{8339}' . '\x{833A}\x{833B}\x{833C}\x{833D}\x{833E}\x{833F}\x{8340}\x{8341}\x{8342}' . '\x{8343}\x{8344}\x{8345}\x{8346}\x{8347}\x{8348}\x{8349}\x{834A}\x{834B}' . '\x{834C}\x{834D}\x{834E}\x{834F}\x{8350}\x{8351}\x{8352}\x{8353}\x{8354}' . '\x{8356}\x{8357}\x{8358}\x{8359}\x{835A}\x{835B}\x{835C}\x{835D}\x{835E}' . '\x{835F}\x{8360}\x{8361}\x{8362}\x{8363}\x{8364}\x{8365}\x{8366}\x{8367}' . '\x{8368}\x{8369}\x{836A}\x{836B}\x{836C}\x{836D}\x{836E}\x{836F}\x{8370}' . '\x{8371}\x{8372}\x{8373}\x{8374}\x{8375}\x{8376}\x{8377}\x{8378}\x{8379}' . '\x{837A}\x{837B}\x{837C}\x{837D}\x{837E}\x{837F}\x{8380}\x{8381}\x{8382}' . '\x{8383}\x{8384}\x{8385}\x{8386}\x{8387}\x{8388}\x{8389}\x{838A}\x{838B}' . '\x{838C}\x{838D}\x{838E}\x{838F}\x{8390}\x{8391}\x{8392}\x{8393}\x{8394}' . '\x{8395}\x{8396}\x{8397}\x{8398}\x{8399}\x{839A}\x{839B}\x{839C}\x{839D}' . '\x{839E}\x{83A0}\x{83A1}\x{83A2}\x{83A3}\x{83A4}\x{83A5}\x{83A6}\x{83A7}' . '\x{83A8}\x{83A9}\x{83AA}\x{83AB}\x{83AC}\x{83AD}\x{83AE}\x{83AF}\x{83B0}' . '\x{83B1}\x{83B2}\x{83B3}\x{83B4}\x{83B6}\x{83B7}\x{83B8}\x{83B9}\x{83BA}' . '\x{83BB}\x{83BC}\x{83BD}\x{83BF}\x{83C0}\x{83C1}\x{83C2}\x{83C3}\x{83C4}' . '\x{83C5}\x{83C6}\x{83C7}\x{83C8}\x{83C9}\x{83CA}\x{83CB}\x{83CC}\x{83CD}' . '\x{83CE}\x{83CF}\x{83D0}\x{83D1}\x{83D2}\x{83D3}\x{83D4}\x{83D5}\x{83D6}' . '\x{83D7}\x{83D8}\x{83D9}\x{83DA}\x{83DB}\x{83DC}\x{83DD}\x{83DE}\x{83DF}' . '\x{83E0}\x{83E1}\x{83E2}\x{83E3}\x{83E4}\x{83E5}\x{83E7}\x{83E8}\x{83E9}' . '\x{83EA}\x{83EB}\x{83EC}\x{83EE}\x{83EF}\x{83F0}\x{83F1}\x{83F2}\x{83F3}' . '\x{83F4}\x{83F5}\x{83F6}\x{83F7}\x{83F8}\x{83F9}\x{83FA}\x{83FB}\x{83FC}' . '\x{83FD}\x{83FE}\x{83FF}\x{8400}\x{8401}\x{8402}\x{8403}\x{8404}\x{8405}' . '\x{8406}\x{8407}\x{8408}\x{8409}\x{840A}\x{840B}\x{840C}\x{840D}\x{840E}' . '\x{840F}\x{8410}\x{8411}\x{8412}\x{8413}\x{8415}\x{8418}\x{8419}\x{841A}' . '\x{841B}\x{841C}\x{841D}\x{841E}\x{8421}\x{8422}\x{8423}\x{8424}\x{8425}' . '\x{8426}\x{8427}\x{8428}\x{8429}\x{842A}\x{842B}\x{842C}\x{842D}\x{842E}' . '\x{842F}\x{8430}\x{8431}\x{8432}\x{8433}\x{8434}\x{8435}\x{8436}\x{8437}' . '\x{8438}\x{8439}\x{843A}\x{843B}\x{843C}\x{843D}\x{843E}\x{843F}\x{8440}' . '\x{8441}\x{8442}\x{8443}\x{8444}\x{8445}\x{8446}\x{8447}\x{8448}\x{8449}' . '\x{844A}\x{844B}\x{844C}\x{844D}\x{844E}\x{844F}\x{8450}\x{8451}\x{8452}' . '\x{8453}\x{8454}\x{8455}\x{8456}\x{8457}\x{8459}\x{845A}\x{845B}\x{845C}' . '\x{845D}\x{845E}\x{845F}\x{8460}\x{8461}\x{8462}\x{8463}\x{8464}\x{8465}' . '\x{8466}\x{8467}\x{8468}\x{8469}\x{846A}\x{846B}\x{846C}\x{846D}\x{846E}' . '\x{846F}\x{8470}\x{8471}\x{8472}\x{8473}\x{8474}\x{8475}\x{8476}\x{8477}' . '\x{8478}\x{8479}\x{847A}\x{847B}\x{847C}\x{847D}\x{847E}\x{847F}\x{8480}' . '\x{8481}\x{8482}\x{8484}\x{8485}\x{8486}\x{8487}\x{8488}\x{8489}\x{848A}' . '\x{848B}\x{848C}\x{848D}\x{848E}\x{848F}\x{8490}\x{8491}\x{8492}\x{8493}' . '\x{8494}\x{8496}\x{8497}\x{8498}\x{8499}\x{849A}\x{849B}\x{849C}\x{849D}' . '\x{849E}\x{849F}\x{84A0}\x{84A1}\x{84A2}\x{84A3}\x{84A4}\x{84A5}\x{84A6}' . '\x{84A7}\x{84A8}\x{84A9}\x{84AA}\x{84AB}\x{84AC}\x{84AE}\x{84AF}\x{84B0}' . '\x{84B1}\x{84B2}\x{84B3}\x{84B4}\x{84B5}\x{84B6}\x{84B8}\x{84B9}\x{84BA}' . '\x{84BB}\x{84BC}\x{84BD}\x{84BE}\x{84BF}\x{84C0}\x{84C1}\x{84C2}\x{84C4}' . '\x{84C5}\x{84C6}\x{84C7}\x{84C8}\x{84C9}\x{84CA}\x{84CB}\x{84CC}\x{84CD}' . '\x{84CE}\x{84CF}\x{84D0}\x{84D1}\x{84D2}\x{84D3}\x{84D4}\x{84D5}\x{84D6}' . '\x{84D7}\x{84D8}\x{84D9}\x{84DB}\x{84DC}\x{84DD}\x{84DE}\x{84DF}\x{84E0}' . '\x{84E1}\x{84E2}\x{84E3}\x{84E4}\x{84E5}\x{84E6}\x{84E7}\x{84E8}\x{84E9}' . '\x{84EA}\x{84EB}\x{84EC}\x{84EE}\x{84EF}\x{84F0}\x{84F1}\x{84F2}\x{84F3}' . '\x{84F4}\x{84F5}\x{84F6}\x{84F7}\x{84F8}\x{84F9}\x{84FA}\x{84FB}\x{84FC}' . '\x{84FD}\x{84FE}\x{84FF}\x{8500}\x{8501}\x{8502}\x{8503}\x{8504}\x{8506}' . '\x{8507}\x{8508}\x{8509}\x{850A}\x{850B}\x{850C}\x{850D}\x{850E}\x{850F}' . '\x{8511}\x{8512}\x{8513}\x{8514}\x{8515}\x{8516}\x{8517}\x{8518}\x{8519}' . '\x{851A}\x{851B}\x{851C}\x{851D}\x{851E}\x{851F}\x{8520}\x{8521}\x{8522}' . '\x{8523}\x{8524}\x{8525}\x{8526}\x{8527}\x{8528}\x{8529}\x{852A}\x{852B}' . '\x{852C}\x{852D}\x{852E}\x{852F}\x{8530}\x{8531}\x{8534}\x{8535}\x{8536}' . '\x{8537}\x{8538}\x{8539}\x{853A}\x{853B}\x{853C}\x{853D}\x{853E}\x{853F}' . '\x{8540}\x{8541}\x{8542}\x{8543}\x{8544}\x{8545}\x{8546}\x{8547}\x{8548}' . '\x{8549}\x{854A}\x{854B}\x{854D}\x{854E}\x{854F}\x{8551}\x{8552}\x{8553}' . '\x{8554}\x{8555}\x{8556}\x{8557}\x{8558}\x{8559}\x{855A}\x{855B}\x{855C}' . '\x{855D}\x{855E}\x{855F}\x{8560}\x{8561}\x{8562}\x{8563}\x{8564}\x{8565}' . '\x{8566}\x{8567}\x{8568}\x{8569}\x{856A}\x{856B}\x{856C}\x{856D}\x{856E}' . '\x{856F}\x{8570}\x{8571}\x{8572}\x{8573}\x{8574}\x{8575}\x{8576}\x{8577}' . '\x{8578}\x{8579}\x{857A}\x{857B}\x{857C}\x{857D}\x{857E}\x{8580}\x{8581}' . '\x{8582}\x{8583}\x{8584}\x{8585}\x{8586}\x{8587}\x{8588}\x{8589}\x{858A}' . '\x{858B}\x{858C}\x{858D}\x{858E}\x{858F}\x{8590}\x{8591}\x{8592}\x{8594}' . '\x{8595}\x{8596}\x{8598}\x{8599}\x{859A}\x{859B}\x{859C}\x{859D}\x{859E}' . '\x{859F}\x{85A0}\x{85A1}\x{85A2}\x{85A3}\x{85A4}\x{85A5}\x{85A6}\x{85A7}' . '\x{85A8}\x{85A9}\x{85AA}\x{85AB}\x{85AC}\x{85AD}\x{85AE}\x{85AF}\x{85B0}' . '\x{85B1}\x{85B3}\x{85B4}\x{85B5}\x{85B6}\x{85B7}\x{85B8}\x{85B9}\x{85BA}' . '\x{85BC}\x{85BD}\x{85BE}\x{85BF}\x{85C0}\x{85C1}\x{85C2}\x{85C3}\x{85C4}' . '\x{85C5}\x{85C6}\x{85C7}\x{85C8}\x{85C9}\x{85CA}\x{85CB}\x{85CD}\x{85CE}' . '\x{85CF}\x{85D0}\x{85D1}\x{85D2}\x{85D3}\x{85D4}\x{85D5}\x{85D6}\x{85D7}' . '\x{85D8}\x{85D9}\x{85DA}\x{85DB}\x{85DC}\x{85DD}\x{85DE}\x{85DF}\x{85E0}' . '\x{85E1}\x{85E2}\x{85E3}\x{85E4}\x{85E5}\x{85E6}\x{85E7}\x{85E8}\x{85E9}' . '\x{85EA}\x{85EB}\x{85EC}\x{85ED}\x{85EF}\x{85F0}\x{85F1}\x{85F2}\x{85F4}' . '\x{85F5}\x{85F6}\x{85F7}\x{85F8}\x{85F9}\x{85FA}\x{85FB}\x{85FD}\x{85FE}' . '\x{85FF}\x{8600}\x{8601}\x{8602}\x{8604}\x{8605}\x{8606}\x{8607}\x{8608}' . '\x{8609}\x{860A}\x{860B}\x{860C}\x{860F}\x{8611}\x{8612}\x{8613}\x{8614}' . '\x{8616}\x{8617}\x{8618}\x{8619}\x{861A}\x{861B}\x{861C}\x{861E}\x{861F}' . '\x{8620}\x{8621}\x{8622}\x{8623}\x{8624}\x{8625}\x{8626}\x{8627}\x{8628}' . '\x{8629}\x{862A}\x{862B}\x{862C}\x{862D}\x{862E}\x{862F}\x{8630}\x{8631}' . '\x{8632}\x{8633}\x{8634}\x{8635}\x{8636}\x{8638}\x{8639}\x{863A}\x{863B}' . '\x{863C}\x{863D}\x{863E}\x{863F}\x{8640}\x{8641}\x{8642}\x{8643}\x{8644}' . '\x{8645}\x{8646}\x{8647}\x{8648}\x{8649}\x{864A}\x{864B}\x{864C}\x{864D}' . '\x{864E}\x{864F}\x{8650}\x{8651}\x{8652}\x{8653}\x{8654}\x{8655}\x{8656}' . '\x{8658}\x{8659}\x{865A}\x{865B}\x{865C}\x{865D}\x{865E}\x{865F}\x{8660}' . '\x{8661}\x{8662}\x{8663}\x{8664}\x{8665}\x{8666}\x{8667}\x{8668}\x{8669}' . '\x{866A}\x{866B}\x{866C}\x{866D}\x{866E}\x{866F}\x{8670}\x{8671}\x{8672}' . '\x{8673}\x{8674}\x{8676}\x{8677}\x{8678}\x{8679}\x{867A}\x{867B}\x{867C}' . '\x{867D}\x{867E}\x{867F}\x{8680}\x{8681}\x{8682}\x{8683}\x{8684}\x{8685}' . '\x{8686}\x{8687}\x{8688}\x{868A}\x{868B}\x{868C}\x{868D}\x{868E}\x{868F}' . '\x{8690}\x{8691}\x{8693}\x{8694}\x{8695}\x{8696}\x{8697}\x{8698}\x{8699}' . '\x{869A}\x{869B}\x{869C}\x{869D}\x{869E}\x{869F}\x{86A1}\x{86A2}\x{86A3}' . '\x{86A4}\x{86A5}\x{86A7}\x{86A8}\x{86A9}\x{86AA}\x{86AB}\x{86AC}\x{86AD}' . '\x{86AE}\x{86AF}\x{86B0}\x{86B1}\x{86B2}\x{86B3}\x{86B4}\x{86B5}\x{86B6}' . '\x{86B7}\x{86B8}\x{86B9}\x{86BA}\x{86BB}\x{86BC}\x{86BD}\x{86BE}\x{86BF}' . '\x{86C0}\x{86C1}\x{86C2}\x{86C3}\x{86C4}\x{86C5}\x{86C6}\x{86C7}\x{86C8}' . '\x{86C9}\x{86CA}\x{86CB}\x{86CC}\x{86CE}\x{86CF}\x{86D0}\x{86D1}\x{86D2}' . '\x{86D3}\x{86D4}\x{86D6}\x{86D7}\x{86D8}\x{86D9}\x{86DA}\x{86DB}\x{86DC}' . '\x{86DD}\x{86DE}\x{86DF}\x{86E1}\x{86E2}\x{86E3}\x{86E4}\x{86E5}\x{86E6}' . '\x{86E8}\x{86E9}\x{86EA}\x{86EB}\x{86EC}\x{86ED}\x{86EE}\x{86EF}\x{86F0}' . '\x{86F1}\x{86F2}\x{86F3}\x{86F4}\x{86F5}\x{86F6}\x{86F7}\x{86F8}\x{86F9}' . '\x{86FA}\x{86FB}\x{86FC}\x{86FE}\x{86FF}\x{8700}\x{8701}\x{8702}\x{8703}' . '\x{8704}\x{8705}\x{8706}\x{8707}\x{8708}\x{8709}\x{870A}\x{870B}\x{870C}' . '\x{870D}\x{870E}\x{870F}\x{8710}\x{8711}\x{8712}\x{8713}\x{8714}\x{8715}' . '\x{8716}\x{8717}\x{8718}\x{8719}\x{871A}\x{871B}\x{871C}\x{871E}\x{871F}' . '\x{8720}\x{8721}\x{8722}\x{8723}\x{8724}\x{8725}\x{8726}\x{8727}\x{8728}' . '\x{8729}\x{872A}\x{872B}\x{872C}\x{872D}\x{872E}\x{8730}\x{8731}\x{8732}' . '\x{8733}\x{8734}\x{8735}\x{8736}\x{8737}\x{8738}\x{8739}\x{873A}\x{873B}' . '\x{873C}\x{873E}\x{873F}\x{8740}\x{8741}\x{8742}\x{8743}\x{8744}\x{8746}' . '\x{8747}\x{8748}\x{8749}\x{874A}\x{874C}\x{874D}\x{874E}\x{874F}\x{8750}' . '\x{8751}\x{8752}\x{8753}\x{8754}\x{8755}\x{8756}\x{8757}\x{8758}\x{8759}' . '\x{875A}\x{875B}\x{875C}\x{875D}\x{875E}\x{875F}\x{8760}\x{8761}\x{8762}' . '\x{8763}\x{8764}\x{8765}\x{8766}\x{8767}\x{8768}\x{8769}\x{876A}\x{876B}' . '\x{876C}\x{876D}\x{876E}\x{876F}\x{8770}\x{8772}\x{8773}\x{8774}\x{8775}' . '\x{8776}\x{8777}\x{8778}\x{8779}\x{877A}\x{877B}\x{877C}\x{877D}\x{877E}' . '\x{8780}\x{8781}\x{8782}\x{8783}\x{8784}\x{8785}\x{8786}\x{8787}\x{8788}' . '\x{8789}\x{878A}\x{878B}\x{878C}\x{878D}\x{878F}\x{8790}\x{8791}\x{8792}' . '\x{8793}\x{8794}\x{8795}\x{8796}\x{8797}\x{8798}\x{879A}\x{879B}\x{879C}' . '\x{879D}\x{879E}\x{879F}\x{87A0}\x{87A1}\x{87A2}\x{87A3}\x{87A4}\x{87A5}' . '\x{87A6}\x{87A7}\x{87A8}\x{87A9}\x{87AA}\x{87AB}\x{87AC}\x{87AD}\x{87AE}' . '\x{87AF}\x{87B0}\x{87B1}\x{87B2}\x{87B3}\x{87B4}\x{87B5}\x{87B6}\x{87B7}' . '\x{87B8}\x{87B9}\x{87BA}\x{87BB}\x{87BC}\x{87BD}\x{87BE}\x{87BF}\x{87C0}' . '\x{87C1}\x{87C2}\x{87C3}\x{87C4}\x{87C5}\x{87C6}\x{87C7}\x{87C8}\x{87C9}' . '\x{87CA}\x{87CB}\x{87CC}\x{87CD}\x{87CE}\x{87CF}\x{87D0}\x{87D1}\x{87D2}' . '\x{87D3}\x{87D4}\x{87D5}\x{87D6}\x{87D7}\x{87D8}\x{87D9}\x{87DB}\x{87DC}' . '\x{87DD}\x{87DE}\x{87DF}\x{87E0}\x{87E1}\x{87E2}\x{87E3}\x{87E4}\x{87E5}' . '\x{87E6}\x{87E7}\x{87E8}\x{87E9}\x{87EA}\x{87EB}\x{87EC}\x{87ED}\x{87EE}' . '\x{87EF}\x{87F1}\x{87F2}\x{87F3}\x{87F4}\x{87F5}\x{87F6}\x{87F7}\x{87F8}' . '\x{87F9}\x{87FA}\x{87FB}\x{87FC}\x{87FD}\x{87FE}\x{87FF}\x{8800}\x{8801}' . '\x{8802}\x{8803}\x{8804}\x{8805}\x{8806}\x{8808}\x{8809}\x{880A}\x{880B}' . '\x{880C}\x{880D}\x{880E}\x{880F}\x{8810}\x{8811}\x{8813}\x{8814}\x{8815}' . '\x{8816}\x{8817}\x{8818}\x{8819}\x{881A}\x{881B}\x{881C}\x{881D}\x{881E}' . '\x{881F}\x{8820}\x{8821}\x{8822}\x{8823}\x{8824}\x{8825}\x{8826}\x{8827}' . '\x{8828}\x{8829}\x{882A}\x{882B}\x{882C}\x{882E}\x{882F}\x{8830}\x{8831}' . '\x{8832}\x{8833}\x{8834}\x{8835}\x{8836}\x{8837}\x{8838}\x{8839}\x{883B}' . '\x{883C}\x{883D}\x{883E}\x{883F}\x{8840}\x{8841}\x{8842}\x{8843}\x{8844}' . '\x{8845}\x{8846}\x{8848}\x{8849}\x{884A}\x{884B}\x{884C}\x{884D}\x{884E}' . '\x{884F}\x{8850}\x{8851}\x{8852}\x{8853}\x{8854}\x{8855}\x{8856}\x{8857}' . '\x{8859}\x{885A}\x{885B}\x{885D}\x{885E}\x{8860}\x{8861}\x{8862}\x{8863}' . '\x{8864}\x{8865}\x{8866}\x{8867}\x{8868}\x{8869}\x{886A}\x{886B}\x{886C}' . '\x{886D}\x{886E}\x{886F}\x{8870}\x{8871}\x{8872}\x{8873}\x{8874}\x{8875}' . '\x{8876}\x{8877}\x{8878}\x{8879}\x{887B}\x{887C}\x{887D}\x{887E}\x{887F}' . '\x{8880}\x{8881}\x{8882}\x{8883}\x{8884}\x{8885}\x{8886}\x{8887}\x{8888}' . '\x{8889}\x{888A}\x{888B}\x{888C}\x{888D}\x{888E}\x{888F}\x{8890}\x{8891}' . '\x{8892}\x{8893}\x{8894}\x{8895}\x{8896}\x{8897}\x{8898}\x{8899}\x{889A}' . '\x{889B}\x{889C}\x{889D}\x{889E}\x{889F}\x{88A0}\x{88A1}\x{88A2}\x{88A3}' . '\x{88A4}\x{88A5}\x{88A6}\x{88A7}\x{88A8}\x{88A9}\x{88AA}\x{88AB}\x{88AC}' . '\x{88AD}\x{88AE}\x{88AF}\x{88B0}\x{88B1}\x{88B2}\x{88B3}\x{88B4}\x{88B6}' . '\x{88B7}\x{88B8}\x{88B9}\x{88BA}\x{88BB}\x{88BC}\x{88BD}\x{88BE}\x{88BF}' . '\x{88C0}\x{88C1}\x{88C2}\x{88C3}\x{88C4}\x{88C5}\x{88C6}\x{88C7}\x{88C8}' . '\x{88C9}\x{88CA}\x{88CB}\x{88CC}\x{88CD}\x{88CE}\x{88CF}\x{88D0}\x{88D1}' . '\x{88D2}\x{88D3}\x{88D4}\x{88D5}\x{88D6}\x{88D7}\x{88D8}\x{88D9}\x{88DA}' . '\x{88DB}\x{88DC}\x{88DD}\x{88DE}\x{88DF}\x{88E0}\x{88E1}\x{88E2}\x{88E3}' . '\x{88E4}\x{88E5}\x{88E7}\x{88E8}\x{88EA}\x{88EB}\x{88EC}\x{88EE}\x{88EF}' . '\x{88F0}\x{88F1}\x{88F2}\x{88F3}\x{88F4}\x{88F5}\x{88F6}\x{88F7}\x{88F8}' . '\x{88F9}\x{88FA}\x{88FB}\x{88FC}\x{88FD}\x{88FE}\x{88FF}\x{8900}\x{8901}' . '\x{8902}\x{8904}\x{8905}\x{8906}\x{8907}\x{8908}\x{8909}\x{890A}\x{890B}' . '\x{890C}\x{890D}\x{890E}\x{8910}\x{8911}\x{8912}\x{8913}\x{8914}\x{8915}' . '\x{8916}\x{8917}\x{8918}\x{8919}\x{891A}\x{891B}\x{891C}\x{891D}\x{891E}' . '\x{891F}\x{8920}\x{8921}\x{8922}\x{8923}\x{8925}\x{8926}\x{8927}\x{8928}' . '\x{8929}\x{892A}\x{892B}\x{892C}\x{892D}\x{892E}\x{892F}\x{8930}\x{8931}' . '\x{8932}\x{8933}\x{8934}\x{8935}\x{8936}\x{8937}\x{8938}\x{8939}\x{893A}' . '\x{893B}\x{893C}\x{893D}\x{893E}\x{893F}\x{8940}\x{8941}\x{8942}\x{8943}' . '\x{8944}\x{8945}\x{8946}\x{8947}\x{8948}\x{8949}\x{894A}\x{894B}\x{894C}' . '\x{894E}\x{894F}\x{8950}\x{8951}\x{8952}\x{8953}\x{8954}\x{8955}\x{8956}' . '\x{8957}\x{8958}\x{8959}\x{895A}\x{895B}\x{895C}\x{895D}\x{895E}\x{895F}' . '\x{8960}\x{8961}\x{8962}\x{8963}\x{8964}\x{8966}\x{8967}\x{8968}\x{8969}' . '\x{896A}\x{896B}\x{896C}\x{896D}\x{896E}\x{896F}\x{8970}\x{8971}\x{8972}' . '\x{8973}\x{8974}\x{8976}\x{8977}\x{8978}\x{8979}\x{897A}\x{897B}\x{897C}' . '\x{897E}\x{897F}\x{8980}\x{8981}\x{8982}\x{8983}\x{8984}\x{8985}\x{8986}' . '\x{8987}\x{8988}\x{8989}\x{898A}\x{898B}\x{898C}\x{898E}\x{898F}\x{8991}' . '\x{8992}\x{8993}\x{8995}\x{8996}\x{8997}\x{8998}\x{899A}\x{899B}\x{899C}' . '\x{899D}\x{899E}\x{899F}\x{89A0}\x{89A1}\x{89A2}\x{89A3}\x{89A4}\x{89A5}' . '\x{89A6}\x{89A7}\x{89A8}\x{89AA}\x{89AB}\x{89AC}\x{89AD}\x{89AE}\x{89AF}' . '\x{89B1}\x{89B2}\x{89B3}\x{89B5}\x{89B6}\x{89B7}\x{89B8}\x{89B9}\x{89BA}' . '\x{89BD}\x{89BE}\x{89BF}\x{89C0}\x{89C1}\x{89C2}\x{89C3}\x{89C4}\x{89C5}' . '\x{89C6}\x{89C7}\x{89C8}\x{89C9}\x{89CA}\x{89CB}\x{89CC}\x{89CD}\x{89CE}' . '\x{89CF}\x{89D0}\x{89D1}\x{89D2}\x{89D3}\x{89D4}\x{89D5}\x{89D6}\x{89D7}' . '\x{89D8}\x{89D9}\x{89DA}\x{89DB}\x{89DC}\x{89DD}\x{89DE}\x{89DF}\x{89E0}' . '\x{89E1}\x{89E2}\x{89E3}\x{89E4}\x{89E5}\x{89E6}\x{89E7}\x{89E8}\x{89E9}' . '\x{89EA}\x{89EB}\x{89EC}\x{89ED}\x{89EF}\x{89F0}\x{89F1}\x{89F2}\x{89F3}' . '\x{89F4}\x{89F6}\x{89F7}\x{89F8}\x{89FA}\x{89FB}\x{89FC}\x{89FE}\x{89FF}' . '\x{8A00}\x{8A01}\x{8A02}\x{8A03}\x{8A04}\x{8A07}\x{8A08}\x{8A09}\x{8A0A}' . '\x{8A0B}\x{8A0C}\x{8A0D}\x{8A0E}\x{8A0F}\x{8A10}\x{8A11}\x{8A12}\x{8A13}' . '\x{8A15}\x{8A16}\x{8A17}\x{8A18}\x{8A1A}\x{8A1B}\x{8A1C}\x{8A1D}\x{8A1E}' . '\x{8A1F}\x{8A22}\x{8A23}\x{8A24}\x{8A25}\x{8A26}\x{8A27}\x{8A28}\x{8A29}' . '\x{8A2A}\x{8A2C}\x{8A2D}\x{8A2E}\x{8A2F}\x{8A30}\x{8A31}\x{8A32}\x{8A34}' . '\x{8A35}\x{8A36}\x{8A37}\x{8A38}\x{8A39}\x{8A3A}\x{8A3B}\x{8A3C}\x{8A3E}' . '\x{8A3F}\x{8A40}\x{8A41}\x{8A42}\x{8A43}\x{8A44}\x{8A45}\x{8A46}\x{8A47}' . '\x{8A48}\x{8A49}\x{8A4A}\x{8A4C}\x{8A4D}\x{8A4E}\x{8A4F}\x{8A50}\x{8A51}' . '\x{8A52}\x{8A53}\x{8A54}\x{8A55}\x{8A56}\x{8A57}\x{8A58}\x{8A59}\x{8A5A}' . '\x{8A5B}\x{8A5C}\x{8A5D}\x{8A5E}\x{8A5F}\x{8A60}\x{8A61}\x{8A62}\x{8A63}' . '\x{8A65}\x{8A66}\x{8A67}\x{8A68}\x{8A69}\x{8A6A}\x{8A6B}\x{8A6C}\x{8A6D}' . '\x{8A6E}\x{8A6F}\x{8A70}\x{8A71}\x{8A72}\x{8A73}\x{8A74}\x{8A75}\x{8A76}' . '\x{8A77}\x{8A79}\x{8A7A}\x{8A7B}\x{8A7C}\x{8A7E}\x{8A7F}\x{8A80}\x{8A81}' . '\x{8A82}\x{8A83}\x{8A84}\x{8A85}\x{8A86}\x{8A87}\x{8A89}\x{8A8A}\x{8A8B}' . '\x{8A8C}\x{8A8D}\x{8A8E}\x{8A8F}\x{8A90}\x{8A91}\x{8A92}\x{8A93}\x{8A94}' . '\x{8A95}\x{8A96}\x{8A97}\x{8A98}\x{8A99}\x{8A9A}\x{8A9B}\x{8A9C}\x{8A9D}' . '\x{8A9E}\x{8AA0}\x{8AA1}\x{8AA2}\x{8AA3}\x{8AA4}\x{8AA5}\x{8AA6}\x{8AA7}' . '\x{8AA8}\x{8AA9}\x{8AAA}\x{8AAB}\x{8AAC}\x{8AAE}\x{8AB0}\x{8AB1}\x{8AB2}' . '\x{8AB3}\x{8AB4}\x{8AB5}\x{8AB6}\x{8AB8}\x{8AB9}\x{8ABA}\x{8ABB}\x{8ABC}' . '\x{8ABD}\x{8ABE}\x{8ABF}\x{8AC0}\x{8AC1}\x{8AC2}\x{8AC3}\x{8AC4}\x{8AC5}' . '\x{8AC6}\x{8AC7}\x{8AC8}\x{8AC9}\x{8ACA}\x{8ACB}\x{8ACC}\x{8ACD}\x{8ACE}' . '\x{8ACF}\x{8AD1}\x{8AD2}\x{8AD3}\x{8AD4}\x{8AD5}\x{8AD6}\x{8AD7}\x{8AD8}' . '\x{8AD9}\x{8ADA}\x{8ADB}\x{8ADC}\x{8ADD}\x{8ADE}\x{8ADF}\x{8AE0}\x{8AE1}' . '\x{8AE2}\x{8AE3}\x{8AE4}\x{8AE5}\x{8AE6}\x{8AE7}\x{8AE8}\x{8AE9}\x{8AEA}' . '\x{8AEB}\x{8AED}\x{8AEE}\x{8AEF}\x{8AF0}\x{8AF1}\x{8AF2}\x{8AF3}\x{8AF4}' . '\x{8AF5}\x{8AF6}\x{8AF7}\x{8AF8}\x{8AF9}\x{8AFA}\x{8AFB}\x{8AFC}\x{8AFD}' . '\x{8AFE}\x{8AFF}\x{8B00}\x{8B01}\x{8B02}\x{8B03}\x{8B04}\x{8B05}\x{8B06}' . '\x{8B07}\x{8B08}\x{8B09}\x{8B0A}\x{8B0B}\x{8B0D}\x{8B0E}\x{8B0F}\x{8B10}' . '\x{8B11}\x{8B12}\x{8B13}\x{8B14}\x{8B15}\x{8B16}\x{8B17}\x{8B18}\x{8B19}' . '\x{8B1A}\x{8B1B}\x{8B1C}\x{8B1D}\x{8B1E}\x{8B1F}\x{8B20}\x{8B21}\x{8B22}' . '\x{8B23}\x{8B24}\x{8B25}\x{8B26}\x{8B27}\x{8B28}\x{8B2A}\x{8B2B}\x{8B2C}' . '\x{8B2D}\x{8B2E}\x{8B2F}\x{8B30}\x{8B31}\x{8B33}\x{8B34}\x{8B35}\x{8B36}' . '\x{8B37}\x{8B39}\x{8B3A}\x{8B3B}\x{8B3C}\x{8B3D}\x{8B3E}\x{8B40}\x{8B41}' . '\x{8B42}\x{8B43}\x{8B44}\x{8B45}\x{8B46}\x{8B47}\x{8B48}\x{8B49}\x{8B4A}' . '\x{8B4B}\x{8B4C}\x{8B4D}\x{8B4E}\x{8B4F}\x{8B50}\x{8B51}\x{8B52}\x{8B53}' . '\x{8B54}\x{8B55}\x{8B56}\x{8B57}\x{8B58}\x{8B59}\x{8B5A}\x{8B5B}\x{8B5C}' . '\x{8B5D}\x{8B5E}\x{8B5F}\x{8B60}\x{8B63}\x{8B64}\x{8B65}\x{8B66}\x{8B67}' . '\x{8B68}\x{8B6A}\x{8B6B}\x{8B6C}\x{8B6D}\x{8B6E}\x{8B6F}\x{8B70}\x{8B71}' . '\x{8B73}\x{8B74}\x{8B76}\x{8B77}\x{8B78}\x{8B79}\x{8B7A}\x{8B7B}\x{8B7D}' . '\x{8B7E}\x{8B7F}\x{8B80}\x{8B82}\x{8B83}\x{8B84}\x{8B85}\x{8B86}\x{8B88}' . '\x{8B89}\x{8B8A}\x{8B8B}\x{8B8C}\x{8B8E}\x{8B90}\x{8B91}\x{8B92}\x{8B93}' . '\x{8B94}\x{8B95}\x{8B96}\x{8B97}\x{8B98}\x{8B99}\x{8B9A}\x{8B9C}\x{8B9D}' . '\x{8B9E}\x{8B9F}\x{8BA0}\x{8BA1}\x{8BA2}\x{8BA3}\x{8BA4}\x{8BA5}\x{8BA6}' . '\x{8BA7}\x{8BA8}\x{8BA9}\x{8BAA}\x{8BAB}\x{8BAC}\x{8BAD}\x{8BAE}\x{8BAF}' . '\x{8BB0}\x{8BB1}\x{8BB2}\x{8BB3}\x{8BB4}\x{8BB5}\x{8BB6}\x{8BB7}\x{8BB8}' . '\x{8BB9}\x{8BBA}\x{8BBB}\x{8BBC}\x{8BBD}\x{8BBE}\x{8BBF}\x{8BC0}\x{8BC1}' . '\x{8BC2}\x{8BC3}\x{8BC4}\x{8BC5}\x{8BC6}\x{8BC7}\x{8BC8}\x{8BC9}\x{8BCA}' . '\x{8BCB}\x{8BCC}\x{8BCD}\x{8BCE}\x{8BCF}\x{8BD0}\x{8BD1}\x{8BD2}\x{8BD3}' . '\x{8BD4}\x{8BD5}\x{8BD6}\x{8BD7}\x{8BD8}\x{8BD9}\x{8BDA}\x{8BDB}\x{8BDC}' . '\x{8BDD}\x{8BDE}\x{8BDF}\x{8BE0}\x{8BE1}\x{8BE2}\x{8BE3}\x{8BE4}\x{8BE5}' . '\x{8BE6}\x{8BE7}\x{8BE8}\x{8BE9}\x{8BEA}\x{8BEB}\x{8BEC}\x{8BED}\x{8BEE}' . '\x{8BEF}\x{8BF0}\x{8BF1}\x{8BF2}\x{8BF3}\x{8BF4}\x{8BF5}\x{8BF6}\x{8BF7}' . '\x{8BF8}\x{8BF9}\x{8BFA}\x{8BFB}\x{8BFC}\x{8BFD}\x{8BFE}\x{8BFF}\x{8C00}' . '\x{8C01}\x{8C02}\x{8C03}\x{8C04}\x{8C05}\x{8C06}\x{8C07}\x{8C08}\x{8C09}' . '\x{8C0A}\x{8C0B}\x{8C0C}\x{8C0D}\x{8C0E}\x{8C0F}\x{8C10}\x{8C11}\x{8C12}' . '\x{8C13}\x{8C14}\x{8C15}\x{8C16}\x{8C17}\x{8C18}\x{8C19}\x{8C1A}\x{8C1B}' . '\x{8C1C}\x{8C1D}\x{8C1E}\x{8C1F}\x{8C20}\x{8C21}\x{8C22}\x{8C23}\x{8C24}' . '\x{8C25}\x{8C26}\x{8C27}\x{8C28}\x{8C29}\x{8C2A}\x{8C2B}\x{8C2C}\x{8C2D}' . '\x{8C2E}\x{8C2F}\x{8C30}\x{8C31}\x{8C32}\x{8C33}\x{8C34}\x{8C35}\x{8C36}' . '\x{8C37}\x{8C39}\x{8C3A}\x{8C3B}\x{8C3C}\x{8C3D}\x{8C3E}\x{8C3F}\x{8C41}' . '\x{8C42}\x{8C43}\x{8C45}\x{8C46}\x{8C47}\x{8C48}\x{8C49}\x{8C4A}\x{8C4B}' . '\x{8C4C}\x{8C4D}\x{8C4E}\x{8C4F}\x{8C50}\x{8C54}\x{8C55}\x{8C56}\x{8C57}' . '\x{8C59}\x{8C5A}\x{8C5B}\x{8C5C}\x{8C5D}\x{8C5E}\x{8C5F}\x{8C60}\x{8C61}' . '\x{8C62}\x{8C63}\x{8C64}\x{8C65}\x{8C66}\x{8C67}\x{8C68}\x{8C69}\x{8C6A}' . '\x{8C6B}\x{8C6C}\x{8C6D}\x{8C6E}\x{8C6F}\x{8C70}\x{8C71}\x{8C72}\x{8C73}' . '\x{8C75}\x{8C76}\x{8C77}\x{8C78}\x{8C79}\x{8C7A}\x{8C7B}\x{8C7D}\x{8C7E}' . '\x{8C80}\x{8C81}\x{8C82}\x{8C84}\x{8C85}\x{8C86}\x{8C88}\x{8C89}\x{8C8A}' . '\x{8C8C}\x{8C8D}\x{8C8F}\x{8C90}\x{8C91}\x{8C92}\x{8C93}\x{8C94}\x{8C95}' . '\x{8C96}\x{8C97}\x{8C98}\x{8C99}\x{8C9A}\x{8C9C}\x{8C9D}\x{8C9E}\x{8C9F}' . '\x{8CA0}\x{8CA1}\x{8CA2}\x{8CA3}\x{8CA4}\x{8CA5}\x{8CA7}\x{8CA8}\x{8CA9}' . '\x{8CAA}\x{8CAB}\x{8CAC}\x{8CAD}\x{8CAE}\x{8CAF}\x{8CB0}\x{8CB1}\x{8CB2}' . '\x{8CB3}\x{8CB4}\x{8CB5}\x{8CB6}\x{8CB7}\x{8CB8}\x{8CB9}\x{8CBA}\x{8CBB}' . '\x{8CBC}\x{8CBD}\x{8CBE}\x{8CBF}\x{8CC0}\x{8CC1}\x{8CC2}\x{8CC3}\x{8CC4}' . '\x{8CC5}\x{8CC6}\x{8CC7}\x{8CC8}\x{8CC9}\x{8CCA}\x{8CCC}\x{8CCE}\x{8CCF}' . '\x{8CD0}\x{8CD1}\x{8CD2}\x{8CD3}\x{8CD4}\x{8CD5}\x{8CD7}\x{8CD9}\x{8CDA}' . '\x{8CDB}\x{8CDC}\x{8CDD}\x{8CDE}\x{8CDF}\x{8CE0}\x{8CE1}\x{8CE2}\x{8CE3}' . '\x{8CE4}\x{8CE5}\x{8CE6}\x{8CE7}\x{8CE8}\x{8CEA}\x{8CEB}\x{8CEC}\x{8CED}' . '\x{8CEE}\x{8CEF}\x{8CF0}\x{8CF1}\x{8CF2}\x{8CF3}\x{8CF4}\x{8CF5}\x{8CF6}' . '\x{8CF8}\x{8CF9}\x{8CFA}\x{8CFB}\x{8CFC}\x{8CFD}\x{8CFE}\x{8CFF}\x{8D00}' . '\x{8D02}\x{8D03}\x{8D04}\x{8D05}\x{8D06}\x{8D07}\x{8D08}\x{8D09}\x{8D0A}' . '\x{8D0B}\x{8D0C}\x{8D0D}\x{8D0E}\x{8D0F}\x{8D10}\x{8D13}\x{8D14}\x{8D15}' . '\x{8D16}\x{8D17}\x{8D18}\x{8D19}\x{8D1A}\x{8D1B}\x{8D1C}\x{8D1D}\x{8D1E}' . '\x{8D1F}\x{8D20}\x{8D21}\x{8D22}\x{8D23}\x{8D24}\x{8D25}\x{8D26}\x{8D27}' . '\x{8D28}\x{8D29}\x{8D2A}\x{8D2B}\x{8D2C}\x{8D2D}\x{8D2E}\x{8D2F}\x{8D30}' . '\x{8D31}\x{8D32}\x{8D33}\x{8D34}\x{8D35}\x{8D36}\x{8D37}\x{8D38}\x{8D39}' . '\x{8D3A}\x{8D3B}\x{8D3C}\x{8D3D}\x{8D3E}\x{8D3F}\x{8D40}\x{8D41}\x{8D42}' . '\x{8D43}\x{8D44}\x{8D45}\x{8D46}\x{8D47}\x{8D48}\x{8D49}\x{8D4A}\x{8D4B}' . '\x{8D4C}\x{8D4D}\x{8D4E}\x{8D4F}\x{8D50}\x{8D51}\x{8D52}\x{8D53}\x{8D54}' . '\x{8D55}\x{8D56}\x{8D57}\x{8D58}\x{8D59}\x{8D5A}\x{8D5B}\x{8D5C}\x{8D5D}' . '\x{8D5E}\x{8D5F}\x{8D60}\x{8D61}\x{8D62}\x{8D63}\x{8D64}\x{8D65}\x{8D66}' . '\x{8D67}\x{8D68}\x{8D69}\x{8D6A}\x{8D6B}\x{8D6C}\x{8D6D}\x{8D6E}\x{8D6F}' . '\x{8D70}\x{8D71}\x{8D72}\x{8D73}\x{8D74}\x{8D75}\x{8D76}\x{8D77}\x{8D78}' . '\x{8D79}\x{8D7A}\x{8D7B}\x{8D7D}\x{8D7E}\x{8D7F}\x{8D80}\x{8D81}\x{8D82}' . '\x{8D83}\x{8D84}\x{8D85}\x{8D86}\x{8D87}\x{8D88}\x{8D89}\x{8D8A}\x{8D8B}' . '\x{8D8C}\x{8D8D}\x{8D8E}\x{8D8F}\x{8D90}\x{8D91}\x{8D92}\x{8D93}\x{8D94}' . '\x{8D95}\x{8D96}\x{8D97}\x{8D98}\x{8D99}\x{8D9A}\x{8D9B}\x{8D9C}\x{8D9D}' . '\x{8D9E}\x{8D9F}\x{8DA0}\x{8DA1}\x{8DA2}\x{8DA3}\x{8DA4}\x{8DA5}\x{8DA7}' . '\x{8DA8}\x{8DA9}\x{8DAA}\x{8DAB}\x{8DAC}\x{8DAD}\x{8DAE}\x{8DAF}\x{8DB0}' . '\x{8DB1}\x{8DB2}\x{8DB3}\x{8DB4}\x{8DB5}\x{8DB6}\x{8DB7}\x{8DB8}\x{8DB9}' . '\x{8DBA}\x{8DBB}\x{8DBC}\x{8DBD}\x{8DBE}\x{8DBF}\x{8DC1}\x{8DC2}\x{8DC3}' . '\x{8DC4}\x{8DC5}\x{8DC6}\x{8DC7}\x{8DC8}\x{8DC9}\x{8DCA}\x{8DCB}\x{8DCC}' . '\x{8DCD}\x{8DCE}\x{8DCF}\x{8DD0}\x{8DD1}\x{8DD2}\x{8DD3}\x{8DD4}\x{8DD5}' . '\x{8DD6}\x{8DD7}\x{8DD8}\x{8DD9}\x{8DDA}\x{8DDB}\x{8DDC}\x{8DDD}\x{8DDE}' . '\x{8DDF}\x{8DE0}\x{8DE1}\x{8DE2}\x{8DE3}\x{8DE4}\x{8DE6}\x{8DE7}\x{8DE8}' . '\x{8DE9}\x{8DEA}\x{8DEB}\x{8DEC}\x{8DED}\x{8DEE}\x{8DEF}\x{8DF0}\x{8DF1}' . '\x{8DF2}\x{8DF3}\x{8DF4}\x{8DF5}\x{8DF6}\x{8DF7}\x{8DF8}\x{8DF9}\x{8DFA}' . '\x{8DFB}\x{8DFC}\x{8DFD}\x{8DFE}\x{8DFF}\x{8E00}\x{8E02}\x{8E03}\x{8E04}' . '\x{8E05}\x{8E06}\x{8E07}\x{8E08}\x{8E09}\x{8E0A}\x{8E0C}\x{8E0D}\x{8E0E}' . '\x{8E0F}\x{8E10}\x{8E11}\x{8E12}\x{8E13}\x{8E14}\x{8E15}\x{8E16}\x{8E17}' . '\x{8E18}\x{8E19}\x{8E1A}\x{8E1B}\x{8E1C}\x{8E1D}\x{8E1E}\x{8E1F}\x{8E20}' . '\x{8E21}\x{8E22}\x{8E23}\x{8E24}\x{8E25}\x{8E26}\x{8E27}\x{8E28}\x{8E29}' . '\x{8E2A}\x{8E2B}\x{8E2C}\x{8E2D}\x{8E2E}\x{8E2F}\x{8E30}\x{8E31}\x{8E33}' . '\x{8E34}\x{8E35}\x{8E36}\x{8E37}\x{8E38}\x{8E39}\x{8E3A}\x{8E3B}\x{8E3C}' . '\x{8E3D}\x{8E3E}\x{8E3F}\x{8E40}\x{8E41}\x{8E42}\x{8E43}\x{8E44}\x{8E45}' . '\x{8E47}\x{8E48}\x{8E49}\x{8E4A}\x{8E4B}\x{8E4C}\x{8E4D}\x{8E4E}\x{8E50}' . '\x{8E51}\x{8E52}\x{8E53}\x{8E54}\x{8E55}\x{8E56}\x{8E57}\x{8E58}\x{8E59}' . '\x{8E5A}\x{8E5B}\x{8E5C}\x{8E5D}\x{8E5E}\x{8E5F}\x{8E60}\x{8E61}\x{8E62}' . '\x{8E63}\x{8E64}\x{8E65}\x{8E66}\x{8E67}\x{8E68}\x{8E69}\x{8E6A}\x{8E6B}' . '\x{8E6C}\x{8E6D}\x{8E6F}\x{8E70}\x{8E71}\x{8E72}\x{8E73}\x{8E74}\x{8E76}' . '\x{8E78}\x{8E7A}\x{8E7B}\x{8E7C}\x{8E7D}\x{8E7E}\x{8E7F}\x{8E80}\x{8E81}' . '\x{8E82}\x{8E83}\x{8E84}\x{8E85}\x{8E86}\x{8E87}\x{8E88}\x{8E89}\x{8E8A}' . '\x{8E8B}\x{8E8C}\x{8E8D}\x{8E8E}\x{8E8F}\x{8E90}\x{8E91}\x{8E92}\x{8E93}' . '\x{8E94}\x{8E95}\x{8E96}\x{8E97}\x{8E98}\x{8E9A}\x{8E9C}\x{8E9D}\x{8E9E}' . '\x{8E9F}\x{8EA0}\x{8EA1}\x{8EA3}\x{8EA4}\x{8EA5}\x{8EA6}\x{8EA7}\x{8EA8}' . '\x{8EA9}\x{8EAA}\x{8EAB}\x{8EAC}\x{8EAD}\x{8EAE}\x{8EAF}\x{8EB0}\x{8EB1}' . '\x{8EB2}\x{8EB4}\x{8EB5}\x{8EB8}\x{8EB9}\x{8EBA}\x{8EBB}\x{8EBC}\x{8EBD}' . '\x{8EBE}\x{8EBF}\x{8EC0}\x{8EC2}\x{8EC3}\x{8EC5}\x{8EC6}\x{8EC7}\x{8EC8}' . '\x{8EC9}\x{8ECA}\x{8ECB}\x{8ECC}\x{8ECD}\x{8ECE}\x{8ECF}\x{8ED0}\x{8ED1}' . '\x{8ED2}\x{8ED3}\x{8ED4}\x{8ED5}\x{8ED6}\x{8ED7}\x{8ED8}\x{8EDA}\x{8EDB}' . '\x{8EDC}\x{8EDD}\x{8EDE}\x{8EDF}\x{8EE0}\x{8EE1}\x{8EE4}\x{8EE5}\x{8EE6}' . '\x{8EE7}\x{8EE8}\x{8EE9}\x{8EEA}\x{8EEB}\x{8EEC}\x{8EED}\x{8EEE}\x{8EEF}' . '\x{8EF1}\x{8EF2}\x{8EF3}\x{8EF4}\x{8EF5}\x{8EF6}\x{8EF7}\x{8EF8}\x{8EF9}' . '\x{8EFA}\x{8EFB}\x{8EFC}\x{8EFD}\x{8EFE}\x{8EFF}\x{8F00}\x{8F01}\x{8F02}' . '\x{8F03}\x{8F04}\x{8F05}\x{8F06}\x{8F07}\x{8F08}\x{8F09}\x{8F0A}\x{8F0B}' . '\x{8F0D}\x{8F0E}\x{8F10}\x{8F11}\x{8F12}\x{8F13}\x{8F14}\x{8F15}\x{8F16}' . '\x{8F17}\x{8F18}\x{8F1A}\x{8F1B}\x{8F1C}\x{8F1D}\x{8F1E}\x{8F1F}\x{8F20}' . '\x{8F21}\x{8F22}\x{8F23}\x{8F24}\x{8F25}\x{8F26}\x{8F27}\x{8F28}\x{8F29}' . '\x{8F2A}\x{8F2B}\x{8F2C}\x{8F2E}\x{8F2F}\x{8F30}\x{8F31}\x{8F32}\x{8F33}' . '\x{8F34}\x{8F35}\x{8F36}\x{8F37}\x{8F38}\x{8F39}\x{8F3B}\x{8F3C}\x{8F3D}' . '\x{8F3E}\x{8F3F}\x{8F40}\x{8F42}\x{8F43}\x{8F44}\x{8F45}\x{8F46}\x{8F47}' . '\x{8F48}\x{8F49}\x{8F4A}\x{8F4B}\x{8F4C}\x{8F4D}\x{8F4E}\x{8F4F}\x{8F50}' . '\x{8F51}\x{8F52}\x{8F53}\x{8F54}\x{8F55}\x{8F56}\x{8F57}\x{8F58}\x{8F59}' . '\x{8F5A}\x{8F5B}\x{8F5D}\x{8F5E}\x{8F5F}\x{8F60}\x{8F61}\x{8F62}\x{8F63}' . '\x{8F64}\x{8F65}\x{8F66}\x{8F67}\x{8F68}\x{8F69}\x{8F6A}\x{8F6B}\x{8F6C}' . '\x{8F6D}\x{8F6E}\x{8F6F}\x{8F70}\x{8F71}\x{8F72}\x{8F73}\x{8F74}\x{8F75}' . '\x{8F76}\x{8F77}\x{8F78}\x{8F79}\x{8F7A}\x{8F7B}\x{8F7C}\x{8F7D}\x{8F7E}' . '\x{8F7F}\x{8F80}\x{8F81}\x{8F82}\x{8F83}\x{8F84}\x{8F85}\x{8F86}\x{8F87}' . '\x{8F88}\x{8F89}\x{8F8A}\x{8F8B}\x{8F8C}\x{8F8D}\x{8F8E}\x{8F8F}\x{8F90}' . '\x{8F91}\x{8F92}\x{8F93}\x{8F94}\x{8F95}\x{8F96}\x{8F97}\x{8F98}\x{8F99}' . '\x{8F9A}\x{8F9B}\x{8F9C}\x{8F9E}\x{8F9F}\x{8FA0}\x{8FA1}\x{8FA2}\x{8FA3}' . '\x{8FA5}\x{8FA6}\x{8FA7}\x{8FA8}\x{8FA9}\x{8FAA}\x{8FAB}\x{8FAC}\x{8FAD}' . '\x{8FAE}\x{8FAF}\x{8FB0}\x{8FB1}\x{8FB2}\x{8FB4}\x{8FB5}\x{8FB6}\x{8FB7}' . '\x{8FB8}\x{8FB9}\x{8FBB}\x{8FBC}\x{8FBD}\x{8FBE}\x{8FBF}\x{8FC0}\x{8FC1}' . '\x{8FC2}\x{8FC4}\x{8FC5}\x{8FC6}\x{8FC7}\x{8FC8}\x{8FC9}\x{8FCB}\x{8FCC}' . '\x{8FCD}\x{8FCE}\x{8FCF}\x{8FD0}\x{8FD1}\x{8FD2}\x{8FD3}\x{8FD4}\x{8FD5}' . '\x{8FD6}\x{8FD7}\x{8FD8}\x{8FD9}\x{8FDA}\x{8FDB}\x{8FDC}\x{8FDD}\x{8FDE}' . '\x{8FDF}\x{8FE0}\x{8FE1}\x{8FE2}\x{8FE3}\x{8FE4}\x{8FE5}\x{8FE6}\x{8FE8}' . '\x{8FE9}\x{8FEA}\x{8FEB}\x{8FEC}\x{8FED}\x{8FEE}\x{8FEF}\x{8FF0}\x{8FF1}' . '\x{8FF2}\x{8FF3}\x{8FF4}\x{8FF5}\x{8FF6}\x{8FF7}\x{8FF8}\x{8FF9}\x{8FFA}' . '\x{8FFB}\x{8FFC}\x{8FFD}\x{8FFE}\x{8FFF}\x{9000}\x{9001}\x{9002}\x{9003}' . '\x{9004}\x{9005}\x{9006}\x{9007}\x{9008}\x{9009}\x{900A}\x{900B}\x{900C}' . '\x{900D}\x{900F}\x{9010}\x{9011}\x{9012}\x{9013}\x{9014}\x{9015}\x{9016}' . '\x{9017}\x{9018}\x{9019}\x{901A}\x{901B}\x{901C}\x{901D}\x{901E}\x{901F}' . '\x{9020}\x{9021}\x{9022}\x{9023}\x{9024}\x{9025}\x{9026}\x{9027}\x{9028}' . '\x{9029}\x{902B}\x{902D}\x{902E}\x{902F}\x{9030}\x{9031}\x{9032}\x{9033}' . '\x{9034}\x{9035}\x{9036}\x{9038}\x{903A}\x{903B}\x{903C}\x{903D}\x{903E}' . '\x{903F}\x{9041}\x{9042}\x{9043}\x{9044}\x{9045}\x{9047}\x{9048}\x{9049}' . '\x{904A}\x{904B}\x{904C}\x{904D}\x{904E}\x{904F}\x{9050}\x{9051}\x{9052}' . '\x{9053}\x{9054}\x{9055}\x{9056}\x{9057}\x{9058}\x{9059}\x{905A}\x{905B}' . '\x{905C}\x{905D}\x{905E}\x{905F}\x{9060}\x{9061}\x{9062}\x{9063}\x{9064}' . '\x{9065}\x{9066}\x{9067}\x{9068}\x{9069}\x{906A}\x{906B}\x{906C}\x{906D}' . '\x{906E}\x{906F}\x{9070}\x{9071}\x{9072}\x{9073}\x{9074}\x{9075}\x{9076}' . '\x{9077}\x{9078}\x{9079}\x{907A}\x{907B}\x{907C}\x{907D}\x{907E}\x{907F}' . '\x{9080}\x{9081}\x{9082}\x{9083}\x{9084}\x{9085}\x{9086}\x{9087}\x{9088}' . '\x{9089}\x{908A}\x{908B}\x{908C}\x{908D}\x{908E}\x{908F}\x{9090}\x{9091}' . '\x{9092}\x{9093}\x{9094}\x{9095}\x{9096}\x{9097}\x{9098}\x{9099}\x{909A}' . '\x{909B}\x{909C}\x{909D}\x{909E}\x{909F}\x{90A0}\x{90A1}\x{90A2}\x{90A3}' . '\x{90A4}\x{90A5}\x{90A6}\x{90A7}\x{90A8}\x{90A9}\x{90AA}\x{90AC}\x{90AD}' . '\x{90AE}\x{90AF}\x{90B0}\x{90B1}\x{90B2}\x{90B3}\x{90B4}\x{90B5}\x{90B6}' . '\x{90B7}\x{90B8}\x{90B9}\x{90BA}\x{90BB}\x{90BC}\x{90BD}\x{90BE}\x{90BF}' . '\x{90C0}\x{90C1}\x{90C2}\x{90C3}\x{90C4}\x{90C5}\x{90C6}\x{90C7}\x{90C8}' . '\x{90C9}\x{90CA}\x{90CB}\x{90CE}\x{90CF}\x{90D0}\x{90D1}\x{90D3}\x{90D4}' . '\x{90D5}\x{90D6}\x{90D7}\x{90D8}\x{90D9}\x{90DA}\x{90DB}\x{90DC}\x{90DD}' . '\x{90DE}\x{90DF}\x{90E0}\x{90E1}\x{90E2}\x{90E3}\x{90E4}\x{90E5}\x{90E6}' . '\x{90E7}\x{90E8}\x{90E9}\x{90EA}\x{90EB}\x{90EC}\x{90ED}\x{90EE}\x{90EF}' . '\x{90F0}\x{90F1}\x{90F2}\x{90F3}\x{90F4}\x{90F5}\x{90F7}\x{90F8}\x{90F9}' . '\x{90FA}\x{90FB}\x{90FC}\x{90FD}\x{90FE}\x{90FF}\x{9100}\x{9101}\x{9102}' . '\x{9103}\x{9104}\x{9105}\x{9106}\x{9107}\x{9108}\x{9109}\x{910B}\x{910C}' . '\x{910D}\x{910E}\x{910F}\x{9110}\x{9111}\x{9112}\x{9113}\x{9114}\x{9115}' . '\x{9116}\x{9117}\x{9118}\x{9119}\x{911A}\x{911B}\x{911C}\x{911D}\x{911E}' . '\x{911F}\x{9120}\x{9121}\x{9122}\x{9123}\x{9124}\x{9125}\x{9126}\x{9127}' . '\x{9128}\x{9129}\x{912A}\x{912B}\x{912C}\x{912D}\x{912E}\x{912F}\x{9130}' . '\x{9131}\x{9132}\x{9133}\x{9134}\x{9135}\x{9136}\x{9137}\x{9138}\x{9139}' . '\x{913A}\x{913B}\x{913E}\x{913F}\x{9140}\x{9141}\x{9142}\x{9143}\x{9144}' . '\x{9145}\x{9146}\x{9147}\x{9148}\x{9149}\x{914A}\x{914B}\x{914C}\x{914D}' . '\x{914E}\x{914F}\x{9150}\x{9151}\x{9152}\x{9153}\x{9154}\x{9155}\x{9156}' . '\x{9157}\x{9158}\x{915A}\x{915B}\x{915C}\x{915D}\x{915E}\x{915F}\x{9160}' . '\x{9161}\x{9162}\x{9163}\x{9164}\x{9165}\x{9166}\x{9167}\x{9168}\x{9169}' . '\x{916A}\x{916B}\x{916C}\x{916D}\x{916E}\x{916F}\x{9170}\x{9171}\x{9172}' . '\x{9173}\x{9174}\x{9175}\x{9176}\x{9177}\x{9178}\x{9179}\x{917A}\x{917C}' . '\x{917D}\x{917E}\x{917F}\x{9180}\x{9181}\x{9182}\x{9183}\x{9184}\x{9185}' . '\x{9186}\x{9187}\x{9188}\x{9189}\x{918A}\x{918B}\x{918C}\x{918D}\x{918E}' . '\x{918F}\x{9190}\x{9191}\x{9192}\x{9193}\x{9194}\x{9196}\x{9199}\x{919A}' . '\x{919B}\x{919C}\x{919D}\x{919E}\x{919F}\x{91A0}\x{91A1}\x{91A2}\x{91A3}' . '\x{91A5}\x{91A6}\x{91A7}\x{91A8}\x{91AA}\x{91AB}\x{91AC}\x{91AD}\x{91AE}' . '\x{91AF}\x{91B0}\x{91B1}\x{91B2}\x{91B3}\x{91B4}\x{91B5}\x{91B6}\x{91B7}' . '\x{91B9}\x{91BA}\x{91BB}\x{91BC}\x{91BD}\x{91BE}\x{91C0}\x{91C1}\x{91C2}' . '\x{91C3}\x{91C5}\x{91C6}\x{91C7}\x{91C9}\x{91CA}\x{91CB}\x{91CC}\x{91CD}' . '\x{91CE}\x{91CF}\x{91D0}\x{91D1}\x{91D2}\x{91D3}\x{91D4}\x{91D5}\x{91D7}' . '\x{91D8}\x{91D9}\x{91DA}\x{91DB}\x{91DC}\x{91DD}\x{91DE}\x{91DF}\x{91E2}' . '\x{91E3}\x{91E4}\x{91E5}\x{91E6}\x{91E7}\x{91E8}\x{91E9}\x{91EA}\x{91EB}' . '\x{91EC}\x{91ED}\x{91EE}\x{91F0}\x{91F1}\x{91F2}\x{91F3}\x{91F4}\x{91F5}' . '\x{91F7}\x{91F8}\x{91F9}\x{91FA}\x{91FB}\x{91FD}\x{91FE}\x{91FF}\x{9200}' . '\x{9201}\x{9202}\x{9203}\x{9204}\x{9205}\x{9206}\x{9207}\x{9208}\x{9209}' . '\x{920A}\x{920B}\x{920C}\x{920D}\x{920E}\x{920F}\x{9210}\x{9211}\x{9212}' . '\x{9214}\x{9215}\x{9216}\x{9217}\x{9218}\x{9219}\x{921A}\x{921B}\x{921C}' . '\x{921D}\x{921E}\x{9220}\x{9221}\x{9223}\x{9224}\x{9225}\x{9226}\x{9227}' . '\x{9228}\x{9229}\x{922A}\x{922B}\x{922D}\x{922E}\x{922F}\x{9230}\x{9231}' . '\x{9232}\x{9233}\x{9234}\x{9235}\x{9236}\x{9237}\x{9238}\x{9239}\x{923A}' . '\x{923B}\x{923C}\x{923D}\x{923E}\x{923F}\x{9240}\x{9241}\x{9242}\x{9245}' . '\x{9246}\x{9247}\x{9248}\x{9249}\x{924A}\x{924B}\x{924C}\x{924D}\x{924E}' . '\x{924F}\x{9250}\x{9251}\x{9252}\x{9253}\x{9254}\x{9255}\x{9256}\x{9257}' . '\x{9258}\x{9259}\x{925A}\x{925B}\x{925C}\x{925D}\x{925E}\x{925F}\x{9260}' . '\x{9261}\x{9262}\x{9263}\x{9264}\x{9265}\x{9266}\x{9267}\x{9268}\x{926B}' . '\x{926C}\x{926D}\x{926E}\x{926F}\x{9270}\x{9272}\x{9273}\x{9274}\x{9275}' . '\x{9276}\x{9277}\x{9278}\x{9279}\x{927A}\x{927B}\x{927C}\x{927D}\x{927E}' . '\x{927F}\x{9280}\x{9282}\x{9283}\x{9285}\x{9286}\x{9287}\x{9288}\x{9289}' . '\x{928A}\x{928B}\x{928C}\x{928D}\x{928E}\x{928F}\x{9290}\x{9291}\x{9292}' . '\x{9293}\x{9294}\x{9295}\x{9296}\x{9297}\x{9298}\x{9299}\x{929A}\x{929B}' . '\x{929C}\x{929D}\x{929F}\x{92A0}\x{92A1}\x{92A2}\x{92A3}\x{92A4}\x{92A5}' . '\x{92A6}\x{92A7}\x{92A8}\x{92A9}\x{92AA}\x{92AB}\x{92AC}\x{92AD}\x{92AE}' . '\x{92AF}\x{92B0}\x{92B1}\x{92B2}\x{92B3}\x{92B4}\x{92B5}\x{92B6}\x{92B7}' . '\x{92B8}\x{92B9}\x{92BA}\x{92BB}\x{92BC}\x{92BE}\x{92BF}\x{92C0}\x{92C1}' . '\x{92C2}\x{92C3}\x{92C4}\x{92C5}\x{92C6}\x{92C7}\x{92C8}\x{92C9}\x{92CA}' . '\x{92CB}\x{92CC}\x{92CD}\x{92CE}\x{92CF}\x{92D0}\x{92D1}\x{92D2}\x{92D3}' . '\x{92D5}\x{92D6}\x{92D7}\x{92D8}\x{92D9}\x{92DA}\x{92DC}\x{92DD}\x{92DE}' . '\x{92DF}\x{92E0}\x{92E1}\x{92E3}\x{92E4}\x{92E5}\x{92E6}\x{92E7}\x{92E8}' . '\x{92E9}\x{92EA}\x{92EB}\x{92EC}\x{92ED}\x{92EE}\x{92EF}\x{92F0}\x{92F1}' . '\x{92F2}\x{92F3}\x{92F4}\x{92F5}\x{92F6}\x{92F7}\x{92F8}\x{92F9}\x{92FA}' . '\x{92FB}\x{92FC}\x{92FD}\x{92FE}\x{92FF}\x{9300}\x{9301}\x{9302}\x{9303}' . '\x{9304}\x{9305}\x{9306}\x{9307}\x{9308}\x{9309}\x{930A}\x{930B}\x{930C}' . '\x{930D}\x{930E}\x{930F}\x{9310}\x{9311}\x{9312}\x{9313}\x{9314}\x{9315}' . '\x{9316}\x{9317}\x{9318}\x{9319}\x{931A}\x{931B}\x{931D}\x{931E}\x{931F}' . '\x{9320}\x{9321}\x{9322}\x{9323}\x{9324}\x{9325}\x{9326}\x{9327}\x{9328}' . '\x{9329}\x{932A}\x{932B}\x{932D}\x{932E}\x{932F}\x{9332}\x{9333}\x{9334}' . '\x{9335}\x{9336}\x{9337}\x{9338}\x{9339}\x{933A}\x{933B}\x{933C}\x{933D}' . '\x{933E}\x{933F}\x{9340}\x{9341}\x{9342}\x{9343}\x{9344}\x{9345}\x{9346}' . '\x{9347}\x{9348}\x{9349}\x{934A}\x{934B}\x{934C}\x{934D}\x{934E}\x{934F}' . '\x{9350}\x{9351}\x{9352}\x{9353}\x{9354}\x{9355}\x{9356}\x{9357}\x{9358}' . '\x{9359}\x{935A}\x{935B}\x{935C}\x{935D}\x{935E}\x{935F}\x{9360}\x{9361}' . '\x{9363}\x{9364}\x{9365}\x{9366}\x{9367}\x{9369}\x{936A}\x{936C}\x{936D}' . '\x{936E}\x{9370}\x{9371}\x{9372}\x{9374}\x{9375}\x{9376}\x{9377}\x{9379}' . '\x{937A}\x{937B}\x{937C}\x{937D}\x{937E}\x{9380}\x{9382}\x{9383}\x{9384}' . '\x{9385}\x{9386}\x{9387}\x{9388}\x{9389}\x{938A}\x{938C}\x{938D}\x{938E}' . '\x{938F}\x{9390}\x{9391}\x{9392}\x{9393}\x{9394}\x{9395}\x{9396}\x{9397}' . '\x{9398}\x{9399}\x{939A}\x{939B}\x{939D}\x{939E}\x{939F}\x{93A1}\x{93A2}' . '\x{93A3}\x{93A4}\x{93A5}\x{93A6}\x{93A7}\x{93A8}\x{93A9}\x{93AA}\x{93AC}' . '\x{93AD}\x{93AE}\x{93AF}\x{93B0}\x{93B1}\x{93B2}\x{93B3}\x{93B4}\x{93B5}' . '\x{93B6}\x{93B7}\x{93B8}\x{93B9}\x{93BA}\x{93BC}\x{93BD}\x{93BE}\x{93BF}' . '\x{93C0}\x{93C1}\x{93C2}\x{93C3}\x{93C4}\x{93C5}\x{93C6}\x{93C7}\x{93C8}' . '\x{93C9}\x{93CA}\x{93CB}\x{93CC}\x{93CD}\x{93CE}\x{93CF}\x{93D0}\x{93D1}' . '\x{93D2}\x{93D3}\x{93D4}\x{93D5}\x{93D6}\x{93D7}\x{93D8}\x{93D9}\x{93DA}' . '\x{93DB}\x{93DC}\x{93DD}\x{93DE}\x{93DF}\x{93E1}\x{93E2}\x{93E3}\x{93E4}' . '\x{93E6}\x{93E7}\x{93E8}\x{93E9}\x{93EA}\x{93EB}\x{93EC}\x{93ED}\x{93EE}' . '\x{93EF}\x{93F0}\x{93F1}\x{93F2}\x{93F4}\x{93F5}\x{93F6}\x{93F7}\x{93F8}' . '\x{93F9}\x{93FA}\x{93FB}\x{93FC}\x{93FD}\x{93FE}\x{93FF}\x{9400}\x{9401}' . '\x{9403}\x{9404}\x{9405}\x{9406}\x{9407}\x{9408}\x{9409}\x{940A}\x{940B}' . '\x{940C}\x{940D}\x{940E}\x{940F}\x{9410}\x{9411}\x{9412}\x{9413}\x{9414}' . '\x{9415}\x{9416}\x{9418}\x{9419}\x{941B}\x{941D}\x{9420}\x{9422}\x{9423}' . '\x{9425}\x{9426}\x{9427}\x{9428}\x{9429}\x{942A}\x{942B}\x{942C}\x{942D}' . '\x{942E}\x{942F}\x{9430}\x{9431}\x{9432}\x{9433}\x{9434}\x{9435}\x{9436}' . '\x{9437}\x{9438}\x{9439}\x{943A}\x{943B}\x{943C}\x{943D}\x{943E}\x{943F}' . '\x{9440}\x{9441}\x{9442}\x{9444}\x{9445}\x{9446}\x{9447}\x{9448}\x{9449}' . '\x{944A}\x{944B}\x{944C}\x{944D}\x{944F}\x{9450}\x{9451}\x{9452}\x{9453}' . '\x{9454}\x{9455}\x{9456}\x{9457}\x{9458}\x{9459}\x{945B}\x{945C}\x{945D}' . '\x{945E}\x{945F}\x{9460}\x{9461}\x{9462}\x{9463}\x{9464}\x{9465}\x{9466}' . '\x{9467}\x{9468}\x{9469}\x{946A}\x{946B}\x{946D}\x{946E}\x{946F}\x{9470}' . '\x{9471}\x{9472}\x{9473}\x{9474}\x{9475}\x{9476}\x{9477}\x{9478}\x{9479}' . '\x{947A}\x{947C}\x{947D}\x{947E}\x{947F}\x{9480}\x{9481}\x{9482}\x{9483}' . '\x{9484}\x{9485}\x{9486}\x{9487}\x{9488}\x{9489}\x{948A}\x{948B}\x{948C}' . '\x{948D}\x{948E}\x{948F}\x{9490}\x{9491}\x{9492}\x{9493}\x{9494}\x{9495}' . '\x{9496}\x{9497}\x{9498}\x{9499}\x{949A}\x{949B}\x{949C}\x{949D}\x{949E}' . '\x{949F}\x{94A0}\x{94A1}\x{94A2}\x{94A3}\x{94A4}\x{94A5}\x{94A6}\x{94A7}' . '\x{94A8}\x{94A9}\x{94AA}\x{94AB}\x{94AC}\x{94AD}\x{94AE}\x{94AF}\x{94B0}' . '\x{94B1}\x{94B2}\x{94B3}\x{94B4}\x{94B5}\x{94B6}\x{94B7}\x{94B8}\x{94B9}' . '\x{94BA}\x{94BB}\x{94BC}\x{94BD}\x{94BE}\x{94BF}\x{94C0}\x{94C1}\x{94C2}' . '\x{94C3}\x{94C4}\x{94C5}\x{94C6}\x{94C7}\x{94C8}\x{94C9}\x{94CA}\x{94CB}' . '\x{94CC}\x{94CD}\x{94CE}\x{94CF}\x{94D0}\x{94D1}\x{94D2}\x{94D3}\x{94D4}' . '\x{94D5}\x{94D6}\x{94D7}\x{94D8}\x{94D9}\x{94DA}\x{94DB}\x{94DC}\x{94DD}' . '\x{94DE}\x{94DF}\x{94E0}\x{94E1}\x{94E2}\x{94E3}\x{94E4}\x{94E5}\x{94E6}' . '\x{94E7}\x{94E8}\x{94E9}\x{94EA}\x{94EB}\x{94EC}\x{94ED}\x{94EE}\x{94EF}' . '\x{94F0}\x{94F1}\x{94F2}\x{94F3}\x{94F4}\x{94F5}\x{94F6}\x{94F7}\x{94F8}' . '\x{94F9}\x{94FA}\x{94FB}\x{94FC}\x{94FD}\x{94FE}\x{94FF}\x{9500}\x{9501}' . '\x{9502}\x{9503}\x{9504}\x{9505}\x{9506}\x{9507}\x{9508}\x{9509}\x{950A}' . '\x{950B}\x{950C}\x{950D}\x{950E}\x{950F}\x{9510}\x{9511}\x{9512}\x{9513}' . '\x{9514}\x{9515}\x{9516}\x{9517}\x{9518}\x{9519}\x{951A}\x{951B}\x{951C}' . '\x{951D}\x{951E}\x{951F}\x{9520}\x{9521}\x{9522}\x{9523}\x{9524}\x{9525}' . '\x{9526}\x{9527}\x{9528}\x{9529}\x{952A}\x{952B}\x{952C}\x{952D}\x{952E}' . '\x{952F}\x{9530}\x{9531}\x{9532}\x{9533}\x{9534}\x{9535}\x{9536}\x{9537}' . '\x{9538}\x{9539}\x{953A}\x{953B}\x{953C}\x{953D}\x{953E}\x{953F}\x{9540}' . '\x{9541}\x{9542}\x{9543}\x{9544}\x{9545}\x{9546}\x{9547}\x{9548}\x{9549}' . '\x{954A}\x{954B}\x{954C}\x{954D}\x{954E}\x{954F}\x{9550}\x{9551}\x{9552}' . '\x{9553}\x{9554}\x{9555}\x{9556}\x{9557}\x{9558}\x{9559}\x{955A}\x{955B}' . '\x{955C}\x{955D}\x{955E}\x{955F}\x{9560}\x{9561}\x{9562}\x{9563}\x{9564}' . '\x{9565}\x{9566}\x{9567}\x{9568}\x{9569}\x{956A}\x{956B}\x{956C}\x{956D}' . '\x{956E}\x{956F}\x{9570}\x{9571}\x{9572}\x{9573}\x{9574}\x{9575}\x{9576}' . '\x{9577}\x{957A}\x{957B}\x{957C}\x{957D}\x{957F}\x{9580}\x{9581}\x{9582}' . '\x{9583}\x{9584}\x{9586}\x{9587}\x{9588}\x{9589}\x{958A}\x{958B}\x{958C}' . '\x{958D}\x{958E}\x{958F}\x{9590}\x{9591}\x{9592}\x{9593}\x{9594}\x{9595}' . '\x{9596}\x{9598}\x{9599}\x{959A}\x{959B}\x{959C}\x{959D}\x{959E}\x{959F}' . '\x{95A1}\x{95A2}\x{95A3}\x{95A4}\x{95A5}\x{95A6}\x{95A7}\x{95A8}\x{95A9}' . '\x{95AA}\x{95AB}\x{95AC}\x{95AD}\x{95AE}\x{95AF}\x{95B0}\x{95B1}\x{95B2}' . '\x{95B5}\x{95B6}\x{95B7}\x{95B9}\x{95BA}\x{95BB}\x{95BC}\x{95BD}\x{95BE}' . '\x{95BF}\x{95C0}\x{95C2}\x{95C3}\x{95C4}\x{95C5}\x{95C6}\x{95C7}\x{95C8}' . '\x{95C9}\x{95CA}\x{95CB}\x{95CC}\x{95CD}\x{95CE}\x{95CF}\x{95D0}\x{95D1}' . '\x{95D2}\x{95D3}\x{95D4}\x{95D5}\x{95D6}\x{95D7}\x{95D8}\x{95DA}\x{95DB}' . '\x{95DC}\x{95DE}\x{95DF}\x{95E0}\x{95E1}\x{95E2}\x{95E3}\x{95E4}\x{95E5}' . '\x{95E6}\x{95E7}\x{95E8}\x{95E9}\x{95EA}\x{95EB}\x{95EC}\x{95ED}\x{95EE}' . '\x{95EF}\x{95F0}\x{95F1}\x{95F2}\x{95F3}\x{95F4}\x{95F5}\x{95F6}\x{95F7}' . '\x{95F8}\x{95F9}\x{95FA}\x{95FB}\x{95FC}\x{95FD}\x{95FE}\x{95FF}\x{9600}' . '\x{9601}\x{9602}\x{9603}\x{9604}\x{9605}\x{9606}\x{9607}\x{9608}\x{9609}' . '\x{960A}\x{960B}\x{960C}\x{960D}\x{960E}\x{960F}\x{9610}\x{9611}\x{9612}' . '\x{9613}\x{9614}\x{9615}\x{9616}\x{9617}\x{9618}\x{9619}\x{961A}\x{961B}' . '\x{961C}\x{961D}\x{961E}\x{961F}\x{9620}\x{9621}\x{9622}\x{9623}\x{9624}' . '\x{9627}\x{9628}\x{962A}\x{962B}\x{962C}\x{962D}\x{962E}\x{962F}\x{9630}' . '\x{9631}\x{9632}\x{9633}\x{9634}\x{9635}\x{9636}\x{9637}\x{9638}\x{9639}' . '\x{963A}\x{963B}\x{963C}\x{963D}\x{963F}\x{9640}\x{9641}\x{9642}\x{9643}' . '\x{9644}\x{9645}\x{9646}\x{9647}\x{9648}\x{9649}\x{964A}\x{964B}\x{964C}' . '\x{964D}\x{964E}\x{964F}\x{9650}\x{9651}\x{9652}\x{9653}\x{9654}\x{9655}' . '\x{9658}\x{9659}\x{965A}\x{965B}\x{965C}\x{965D}\x{965E}\x{965F}\x{9660}' . '\x{9661}\x{9662}\x{9663}\x{9664}\x{9666}\x{9667}\x{9668}\x{9669}\x{966A}' . '\x{966B}\x{966C}\x{966D}\x{966E}\x{966F}\x{9670}\x{9671}\x{9672}\x{9673}' . '\x{9674}\x{9675}\x{9676}\x{9677}\x{9678}\x{967C}\x{967D}\x{967E}\x{9680}' . '\x{9683}\x{9684}\x{9685}\x{9686}\x{9687}\x{9688}\x{9689}\x{968A}\x{968B}' . '\x{968D}\x{968E}\x{968F}\x{9690}\x{9691}\x{9692}\x{9693}\x{9694}\x{9695}' . '\x{9697}\x{9698}\x{9699}\x{969B}\x{969C}\x{969E}\x{96A0}\x{96A1}\x{96A2}' . '\x{96A3}\x{96A4}\x{96A5}\x{96A6}\x{96A7}\x{96A8}\x{96A9}\x{96AA}\x{96AC}' . '\x{96AD}\x{96AE}\x{96B0}\x{96B1}\x{96B3}\x{96B4}\x{96B6}\x{96B7}\x{96B8}' . '\x{96B9}\x{96BA}\x{96BB}\x{96BC}\x{96BD}\x{96BE}\x{96BF}\x{96C0}\x{96C1}' . '\x{96C2}\x{96C3}\x{96C4}\x{96C5}\x{96C6}\x{96C7}\x{96C8}\x{96C9}\x{96CA}' . '\x{96CB}\x{96CC}\x{96CD}\x{96CE}\x{96CF}\x{96D0}\x{96D1}\x{96D2}\x{96D3}' . '\x{96D4}\x{96D5}\x{96D6}\x{96D7}\x{96D8}\x{96D9}\x{96DA}\x{96DB}\x{96DC}' . '\x{96DD}\x{96DE}\x{96DF}\x{96E0}\x{96E1}\x{96E2}\x{96E3}\x{96E5}\x{96E8}' . '\x{96E9}\x{96EA}\x{96EB}\x{96EC}\x{96ED}\x{96EE}\x{96EF}\x{96F0}\x{96F1}' . '\x{96F2}\x{96F3}\x{96F4}\x{96F5}\x{96F6}\x{96F7}\x{96F8}\x{96F9}\x{96FA}' . '\x{96FB}\x{96FD}\x{96FE}\x{96FF}\x{9700}\x{9701}\x{9702}\x{9703}\x{9704}' . '\x{9705}\x{9706}\x{9707}\x{9708}\x{9709}\x{970A}\x{970B}\x{970C}\x{970D}' . '\x{970E}\x{970F}\x{9710}\x{9711}\x{9712}\x{9713}\x{9715}\x{9716}\x{9718}' . '\x{9719}\x{971C}\x{971D}\x{971E}\x{971F}\x{9720}\x{9721}\x{9722}\x{9723}' . '\x{9724}\x{9725}\x{9726}\x{9727}\x{9728}\x{9729}\x{972A}\x{972B}\x{972C}' . '\x{972D}\x{972E}\x{972F}\x{9730}\x{9731}\x{9732}\x{9735}\x{9736}\x{9738}' . '\x{9739}\x{973A}\x{973B}\x{973C}\x{973D}\x{973E}\x{973F}\x{9742}\x{9743}' . '\x{9744}\x{9745}\x{9746}\x{9747}\x{9748}\x{9749}\x{974A}\x{974B}\x{974C}' . '\x{974E}\x{974F}\x{9750}\x{9751}\x{9752}\x{9753}\x{9754}\x{9755}\x{9756}' . '\x{9758}\x{9759}\x{975A}\x{975B}\x{975C}\x{975D}\x{975E}\x{975F}\x{9760}' . '\x{9761}\x{9762}\x{9765}\x{9766}\x{9767}\x{9768}\x{9769}\x{976A}\x{976B}' . '\x{976C}\x{976D}\x{976E}\x{976F}\x{9770}\x{9772}\x{9773}\x{9774}\x{9776}' . '\x{9777}\x{9778}\x{9779}\x{977A}\x{977B}\x{977C}\x{977D}\x{977E}\x{977F}' . '\x{9780}\x{9781}\x{9782}\x{9783}\x{9784}\x{9785}\x{9786}\x{9788}\x{978A}' . '\x{978B}\x{978C}\x{978D}\x{978E}\x{978F}\x{9790}\x{9791}\x{9792}\x{9793}' . '\x{9794}\x{9795}\x{9796}\x{9797}\x{9798}\x{9799}\x{979A}\x{979C}\x{979D}' . '\x{979E}\x{979F}\x{97A0}\x{97A1}\x{97A2}\x{97A3}\x{97A4}\x{97A5}\x{97A6}' . '\x{97A7}\x{97A8}\x{97AA}\x{97AB}\x{97AC}\x{97AD}\x{97AE}\x{97AF}\x{97B2}' . '\x{97B3}\x{97B4}\x{97B6}\x{97B7}\x{97B8}\x{97B9}\x{97BA}\x{97BB}\x{97BC}' . '\x{97BD}\x{97BF}\x{97C1}\x{97C2}\x{97C3}\x{97C4}\x{97C5}\x{97C6}\x{97C7}' . '\x{97C8}\x{97C9}\x{97CA}\x{97CB}\x{97CC}\x{97CD}\x{97CE}\x{97CF}\x{97D0}' . '\x{97D1}\x{97D3}\x{97D4}\x{97D5}\x{97D6}\x{97D7}\x{97D8}\x{97D9}\x{97DA}' . '\x{97DB}\x{97DC}\x{97DD}\x{97DE}\x{97DF}\x{97E0}\x{97E1}\x{97E2}\x{97E3}' . '\x{97E4}\x{97E5}\x{97E6}\x{97E7}\x{97E8}\x{97E9}\x{97EA}\x{97EB}\x{97EC}' . '\x{97ED}\x{97EE}\x{97EF}\x{97F0}\x{97F1}\x{97F2}\x{97F3}\x{97F4}\x{97F5}' . '\x{97F6}\x{97F7}\x{97F8}\x{97F9}\x{97FA}\x{97FB}\x{97FD}\x{97FE}\x{97FF}' . '\x{9800}\x{9801}\x{9802}\x{9803}\x{9804}\x{9805}\x{9806}\x{9807}\x{9808}' . '\x{9809}\x{980A}\x{980B}\x{980C}\x{980D}\x{980E}\x{980F}\x{9810}\x{9811}' . '\x{9812}\x{9813}\x{9814}\x{9815}\x{9816}\x{9817}\x{9818}\x{9819}\x{981A}' . '\x{981B}\x{981C}\x{981D}\x{981E}\x{9820}\x{9821}\x{9822}\x{9823}\x{9824}' . '\x{9826}\x{9827}\x{9828}\x{9829}\x{982B}\x{982D}\x{982E}\x{982F}\x{9830}' . '\x{9831}\x{9832}\x{9834}\x{9835}\x{9836}\x{9837}\x{9838}\x{9839}\x{983B}' . '\x{983C}\x{983D}\x{983F}\x{9840}\x{9841}\x{9843}\x{9844}\x{9845}\x{9846}' . '\x{9848}\x{9849}\x{984A}\x{984C}\x{984D}\x{984E}\x{984F}\x{9850}\x{9851}' . '\x{9852}\x{9853}\x{9854}\x{9855}\x{9857}\x{9858}\x{9859}\x{985A}\x{985B}' . '\x{985C}\x{985D}\x{985E}\x{985F}\x{9860}\x{9861}\x{9862}\x{9863}\x{9864}' . '\x{9865}\x{9867}\x{9869}\x{986A}\x{986B}\x{986C}\x{986D}\x{986E}\x{986F}' . '\x{9870}\x{9871}\x{9872}\x{9873}\x{9874}\x{9875}\x{9876}\x{9877}\x{9878}' . '\x{9879}\x{987A}\x{987B}\x{987C}\x{987D}\x{987E}\x{987F}\x{9880}\x{9881}' . '\x{9882}\x{9883}\x{9884}\x{9885}\x{9886}\x{9887}\x{9888}\x{9889}\x{988A}' . '\x{988B}\x{988C}\x{988D}\x{988E}\x{988F}\x{9890}\x{9891}\x{9892}\x{9893}' . '\x{9894}\x{9895}\x{9896}\x{9897}\x{9898}\x{9899}\x{989A}\x{989B}\x{989C}' . '\x{989D}\x{989E}\x{989F}\x{98A0}\x{98A1}\x{98A2}\x{98A3}\x{98A4}\x{98A5}' . '\x{98A6}\x{98A7}\x{98A8}\x{98A9}\x{98AA}\x{98AB}\x{98AC}\x{98AD}\x{98AE}' . '\x{98AF}\x{98B0}\x{98B1}\x{98B2}\x{98B3}\x{98B4}\x{98B5}\x{98B6}\x{98B8}' . '\x{98B9}\x{98BA}\x{98BB}\x{98BC}\x{98BD}\x{98BE}\x{98BF}\x{98C0}\x{98C1}' . '\x{98C2}\x{98C3}\x{98C4}\x{98C5}\x{98C6}\x{98C8}\x{98C9}\x{98CB}\x{98CC}' . '\x{98CD}\x{98CE}\x{98CF}\x{98D0}\x{98D1}\x{98D2}\x{98D3}\x{98D4}\x{98D5}' . '\x{98D6}\x{98D7}\x{98D8}\x{98D9}\x{98DA}\x{98DB}\x{98DC}\x{98DD}\x{98DE}' . '\x{98DF}\x{98E0}\x{98E2}\x{98E3}\x{98E5}\x{98E6}\x{98E7}\x{98E8}\x{98E9}' . '\x{98EA}\x{98EB}\x{98ED}\x{98EF}\x{98F0}\x{98F2}\x{98F3}\x{98F4}\x{98F5}' . '\x{98F6}\x{98F7}\x{98F9}\x{98FA}\x{98FC}\x{98FD}\x{98FE}\x{98FF}\x{9900}' . '\x{9901}\x{9902}\x{9903}\x{9904}\x{9905}\x{9906}\x{9907}\x{9908}\x{9909}' . '\x{990A}\x{990B}\x{990C}\x{990D}\x{990E}\x{990F}\x{9910}\x{9911}\x{9912}' . '\x{9913}\x{9914}\x{9915}\x{9916}\x{9917}\x{9918}\x{991A}\x{991B}\x{991C}' . '\x{991D}\x{991E}\x{991F}\x{9920}\x{9921}\x{9922}\x{9923}\x{9924}\x{9925}' . '\x{9926}\x{9927}\x{9928}\x{9929}\x{992A}\x{992B}\x{992C}\x{992D}\x{992E}' . '\x{992F}\x{9930}\x{9931}\x{9932}\x{9933}\x{9934}\x{9935}\x{9936}\x{9937}' . '\x{9938}\x{9939}\x{993A}\x{993C}\x{993D}\x{993E}\x{993F}\x{9940}\x{9941}' . '\x{9942}\x{9943}\x{9945}\x{9946}\x{9947}\x{9948}\x{9949}\x{994A}\x{994B}' . '\x{994C}\x{994E}\x{994F}\x{9950}\x{9951}\x{9952}\x{9953}\x{9954}\x{9955}' . '\x{9956}\x{9957}\x{9958}\x{9959}\x{995B}\x{995C}\x{995E}\x{995F}\x{9960}' . '\x{9961}\x{9962}\x{9963}\x{9964}\x{9965}\x{9966}\x{9967}\x{9968}\x{9969}' . '\x{996A}\x{996B}\x{996C}\x{996D}\x{996E}\x{996F}\x{9970}\x{9971}\x{9972}' . '\x{9973}\x{9974}\x{9975}\x{9976}\x{9977}\x{9978}\x{9979}\x{997A}\x{997B}' . '\x{997C}\x{997D}\x{997E}\x{997F}\x{9980}\x{9981}\x{9982}\x{9983}\x{9984}' . '\x{9985}\x{9986}\x{9987}\x{9988}\x{9989}\x{998A}\x{998B}\x{998C}\x{998D}' . '\x{998E}\x{998F}\x{9990}\x{9991}\x{9992}\x{9993}\x{9994}\x{9995}\x{9996}' . '\x{9997}\x{9998}\x{9999}\x{999A}\x{999B}\x{999C}\x{999D}\x{999E}\x{999F}' . '\x{99A0}\x{99A1}\x{99A2}\x{99A3}\x{99A4}\x{99A5}\x{99A6}\x{99A7}\x{99A8}' . '\x{99A9}\x{99AA}\x{99AB}\x{99AC}\x{99AD}\x{99AE}\x{99AF}\x{99B0}\x{99B1}' . '\x{99B2}\x{99B3}\x{99B4}\x{99B5}\x{99B6}\x{99B7}\x{99B8}\x{99B9}\x{99BA}' . '\x{99BB}\x{99BC}\x{99BD}\x{99BE}\x{99C0}\x{99C1}\x{99C2}\x{99C3}\x{99C4}' . '\x{99C6}\x{99C7}\x{99C8}\x{99C9}\x{99CA}\x{99CB}\x{99CC}\x{99CD}\x{99CE}' . '\x{99CF}\x{99D0}\x{99D1}\x{99D2}\x{99D3}\x{99D4}\x{99D5}\x{99D6}\x{99D7}' . '\x{99D8}\x{99D9}\x{99DA}\x{99DB}\x{99DC}\x{99DD}\x{99DE}\x{99DF}\x{99E1}' . '\x{99E2}\x{99E3}\x{99E4}\x{99E5}\x{99E7}\x{99E8}\x{99E9}\x{99EA}\x{99EC}' . '\x{99ED}\x{99EE}\x{99EF}\x{99F0}\x{99F1}\x{99F2}\x{99F3}\x{99F4}\x{99F6}' . '\x{99F7}\x{99F8}\x{99F9}\x{99FA}\x{99FB}\x{99FC}\x{99FD}\x{99FE}\x{99FF}' . '\x{9A00}\x{9A01}\x{9A02}\x{9A03}\x{9A04}\x{9A05}\x{9A06}\x{9A07}\x{9A08}' . '\x{9A09}\x{9A0A}\x{9A0B}\x{9A0C}\x{9A0D}\x{9A0E}\x{9A0F}\x{9A11}\x{9A14}' . '\x{9A15}\x{9A16}\x{9A19}\x{9A1A}\x{9A1B}\x{9A1C}\x{9A1D}\x{9A1E}\x{9A1F}' . '\x{9A20}\x{9A21}\x{9A22}\x{9A23}\x{9A24}\x{9A25}\x{9A26}\x{9A27}\x{9A29}' . '\x{9A2A}\x{9A2B}\x{9A2C}\x{9A2D}\x{9A2E}\x{9A2F}\x{9A30}\x{9A31}\x{9A32}' . '\x{9A33}\x{9A34}\x{9A35}\x{9A36}\x{9A37}\x{9A38}\x{9A39}\x{9A3A}\x{9A3C}' . '\x{9A3D}\x{9A3E}\x{9A3F}\x{9A40}\x{9A41}\x{9A42}\x{9A43}\x{9A44}\x{9A45}' . '\x{9A46}\x{9A47}\x{9A48}\x{9A49}\x{9A4A}\x{9A4B}\x{9A4C}\x{9A4D}\x{9A4E}' . '\x{9A4F}\x{9A50}\x{9A52}\x{9A53}\x{9A54}\x{9A55}\x{9A56}\x{9A57}\x{9A59}' . '\x{9A5A}\x{9A5B}\x{9A5C}\x{9A5E}\x{9A5F}\x{9A60}\x{9A61}\x{9A62}\x{9A64}' . '\x{9A65}\x{9A66}\x{9A67}\x{9A68}\x{9A69}\x{9A6A}\x{9A6B}\x{9A6C}\x{9A6D}' . '\x{9A6E}\x{9A6F}\x{9A70}\x{9A71}\x{9A72}\x{9A73}\x{9A74}\x{9A75}\x{9A76}' . '\x{9A77}\x{9A78}\x{9A79}\x{9A7A}\x{9A7B}\x{9A7C}\x{9A7D}\x{9A7E}\x{9A7F}' . '\x{9A80}\x{9A81}\x{9A82}\x{9A83}\x{9A84}\x{9A85}\x{9A86}\x{9A87}\x{9A88}' . '\x{9A89}\x{9A8A}\x{9A8B}\x{9A8C}\x{9A8D}\x{9A8E}\x{9A8F}\x{9A90}\x{9A91}' . '\x{9A92}\x{9A93}\x{9A94}\x{9A95}\x{9A96}\x{9A97}\x{9A98}\x{9A99}\x{9A9A}' . '\x{9A9B}\x{9A9C}\x{9A9D}\x{9A9E}\x{9A9F}\x{9AA0}\x{9AA1}\x{9AA2}\x{9AA3}' . '\x{9AA4}\x{9AA5}\x{9AA6}\x{9AA7}\x{9AA8}\x{9AAA}\x{9AAB}\x{9AAC}\x{9AAD}' . '\x{9AAE}\x{9AAF}\x{9AB0}\x{9AB1}\x{9AB2}\x{9AB3}\x{9AB4}\x{9AB5}\x{9AB6}' . '\x{9AB7}\x{9AB8}\x{9AB9}\x{9ABA}\x{9ABB}\x{9ABC}\x{9ABE}\x{9ABF}\x{9AC0}' . '\x{9AC1}\x{9AC2}\x{9AC3}\x{9AC4}\x{9AC5}\x{9AC6}\x{9AC7}\x{9AC9}\x{9ACA}' . '\x{9ACB}\x{9ACC}\x{9ACD}\x{9ACE}\x{9ACF}\x{9AD0}\x{9AD1}\x{9AD2}\x{9AD3}' . '\x{9AD4}\x{9AD5}\x{9AD6}\x{9AD8}\x{9AD9}\x{9ADA}\x{9ADB}\x{9ADC}\x{9ADD}' . '\x{9ADE}\x{9ADF}\x{9AE1}\x{9AE2}\x{9AE3}\x{9AE5}\x{9AE6}\x{9AE7}\x{9AEA}' . '\x{9AEB}\x{9AEC}\x{9AED}\x{9AEE}\x{9AEF}\x{9AF1}\x{9AF2}\x{9AF3}\x{9AF4}' . '\x{9AF5}\x{9AF6}\x{9AF7}\x{9AF8}\x{9AF9}\x{9AFA}\x{9AFB}\x{9AFC}\x{9AFD}' . '\x{9AFE}\x{9AFF}\x{9B01}\x{9B03}\x{9B04}\x{9B05}\x{9B06}\x{9B07}\x{9B08}' . '\x{9B0A}\x{9B0B}\x{9B0C}\x{9B0D}\x{9B0E}\x{9B0F}\x{9B10}\x{9B11}\x{9B12}' . '\x{9B13}\x{9B15}\x{9B16}\x{9B17}\x{9B18}\x{9B19}\x{9B1A}\x{9B1C}\x{9B1D}' . '\x{9B1E}\x{9B1F}\x{9B20}\x{9B21}\x{9B22}\x{9B23}\x{9B24}\x{9B25}\x{9B26}' . '\x{9B27}\x{9B28}\x{9B29}\x{9B2A}\x{9B2B}\x{9B2C}\x{9B2D}\x{9B2E}\x{9B2F}' . '\x{9B30}\x{9B31}\x{9B32}\x{9B33}\x{9B35}\x{9B36}\x{9B37}\x{9B38}\x{9B39}' . '\x{9B3A}\x{9B3B}\x{9B3C}\x{9B3E}\x{9B3F}\x{9B41}\x{9B42}\x{9B43}\x{9B44}' . '\x{9B45}\x{9B46}\x{9B47}\x{9B48}\x{9B49}\x{9B4A}\x{9B4B}\x{9B4C}\x{9B4D}' . '\x{9B4E}\x{9B4F}\x{9B51}\x{9B52}\x{9B53}\x{9B54}\x{9B55}\x{9B56}\x{9B58}' . '\x{9B59}\x{9B5A}\x{9B5B}\x{9B5C}\x{9B5D}\x{9B5E}\x{9B5F}\x{9B60}\x{9B61}' . '\x{9B63}\x{9B64}\x{9B65}\x{9B66}\x{9B67}\x{9B68}\x{9B69}\x{9B6A}\x{9B6B}' . '\x{9B6C}\x{9B6D}\x{9B6E}\x{9B6F}\x{9B70}\x{9B71}\x{9B73}\x{9B74}\x{9B75}' . '\x{9B76}\x{9B77}\x{9B78}\x{9B79}\x{9B7A}\x{9B7B}\x{9B7C}\x{9B7D}\x{9B7E}' . '\x{9B7F}\x{9B80}\x{9B81}\x{9B82}\x{9B83}\x{9B84}\x{9B85}\x{9B86}\x{9B87}' . '\x{9B88}\x{9B8A}\x{9B8B}\x{9B8D}\x{9B8E}\x{9B8F}\x{9B90}\x{9B91}\x{9B92}' . '\x{9B93}\x{9B94}\x{9B95}\x{9B96}\x{9B97}\x{9B98}\x{9B9A}\x{9B9B}\x{9B9C}' . '\x{9B9D}\x{9B9E}\x{9B9F}\x{9BA0}\x{9BA1}\x{9BA2}\x{9BA3}\x{9BA4}\x{9BA5}' . '\x{9BA6}\x{9BA7}\x{9BA8}\x{9BA9}\x{9BAA}\x{9BAB}\x{9BAC}\x{9BAD}\x{9BAE}' . '\x{9BAF}\x{9BB0}\x{9BB1}\x{9BB2}\x{9BB3}\x{9BB4}\x{9BB5}\x{9BB6}\x{9BB7}' . '\x{9BB8}\x{9BB9}\x{9BBA}\x{9BBB}\x{9BBC}\x{9BBD}\x{9BBE}\x{9BBF}\x{9BC0}' . '\x{9BC1}\x{9BC3}\x{9BC4}\x{9BC5}\x{9BC6}\x{9BC7}\x{9BC8}\x{9BC9}\x{9BCA}' . '\x{9BCB}\x{9BCC}\x{9BCD}\x{9BCE}\x{9BCF}\x{9BD0}\x{9BD1}\x{9BD2}\x{9BD3}' . '\x{9BD4}\x{9BD5}\x{9BD6}\x{9BD7}\x{9BD8}\x{9BD9}\x{9BDA}\x{9BDB}\x{9BDC}' . '\x{9BDD}\x{9BDE}\x{9BDF}\x{9BE0}\x{9BE1}\x{9BE2}\x{9BE3}\x{9BE4}\x{9BE5}' . '\x{9BE6}\x{9BE7}\x{9BE8}\x{9BE9}\x{9BEA}\x{9BEB}\x{9BEC}\x{9BED}\x{9BEE}' . '\x{9BEF}\x{9BF0}\x{9BF1}\x{9BF2}\x{9BF3}\x{9BF4}\x{9BF5}\x{9BF7}\x{9BF8}' . '\x{9BF9}\x{9BFA}\x{9BFB}\x{9BFC}\x{9BFD}\x{9BFE}\x{9BFF}\x{9C02}\x{9C05}' . '\x{9C06}\x{9C07}\x{9C08}\x{9C09}\x{9C0A}\x{9C0B}\x{9C0C}\x{9C0D}\x{9C0E}' . '\x{9C0F}\x{9C10}\x{9C11}\x{9C12}\x{9C13}\x{9C14}\x{9C15}\x{9C16}\x{9C17}' . '\x{9C18}\x{9C19}\x{9C1A}\x{9C1B}\x{9C1C}\x{9C1D}\x{9C1E}\x{9C1F}\x{9C20}' . '\x{9C21}\x{9C22}\x{9C23}\x{9C24}\x{9C25}\x{9C26}\x{9C27}\x{9C28}\x{9C29}' . '\x{9C2A}\x{9C2B}\x{9C2C}\x{9C2D}\x{9C2F}\x{9C30}\x{9C31}\x{9C32}\x{9C33}' . '\x{9C34}\x{9C35}\x{9C36}\x{9C37}\x{9C38}\x{9C39}\x{9C3A}\x{9C3B}\x{9C3C}' . '\x{9C3D}\x{9C3E}\x{9C3F}\x{9C40}\x{9C41}\x{9C43}\x{9C44}\x{9C45}\x{9C46}' . '\x{9C47}\x{9C48}\x{9C49}\x{9C4A}\x{9C4B}\x{9C4C}\x{9C4D}\x{9C4E}\x{9C50}' . '\x{9C52}\x{9C53}\x{9C54}\x{9C55}\x{9C56}\x{9C57}\x{9C58}\x{9C59}\x{9C5A}' . '\x{9C5B}\x{9C5C}\x{9C5D}\x{9C5E}\x{9C5F}\x{9C60}\x{9C62}\x{9C63}\x{9C65}' . '\x{9C66}\x{9C67}\x{9C68}\x{9C69}\x{9C6A}\x{9C6B}\x{9C6C}\x{9C6D}\x{9C6E}' . '\x{9C6F}\x{9C70}\x{9C71}\x{9C72}\x{9C73}\x{9C74}\x{9C75}\x{9C77}\x{9C78}' . '\x{9C79}\x{9C7A}\x{9C7C}\x{9C7D}\x{9C7E}\x{9C7F}\x{9C80}\x{9C81}\x{9C82}' . '\x{9C83}\x{9C84}\x{9C85}\x{9C86}\x{9C87}\x{9C88}\x{9C89}\x{9C8A}\x{9C8B}' . '\x{9C8C}\x{9C8D}\x{9C8E}\x{9C8F}\x{9C90}\x{9C91}\x{9C92}\x{9C93}\x{9C94}' . '\x{9C95}\x{9C96}\x{9C97}\x{9C98}\x{9C99}\x{9C9A}\x{9C9B}\x{9C9C}\x{9C9D}' . '\x{9C9E}\x{9C9F}\x{9CA0}\x{9CA1}\x{9CA2}\x{9CA3}\x{9CA4}\x{9CA5}\x{9CA6}' . '\x{9CA7}\x{9CA8}\x{9CA9}\x{9CAA}\x{9CAB}\x{9CAC}\x{9CAD}\x{9CAE}\x{9CAF}' . '\x{9CB0}\x{9CB1}\x{9CB2}\x{9CB3}\x{9CB4}\x{9CB5}\x{9CB6}\x{9CB7}\x{9CB8}' . '\x{9CB9}\x{9CBA}\x{9CBB}\x{9CBC}\x{9CBD}\x{9CBE}\x{9CBF}\x{9CC0}\x{9CC1}' . '\x{9CC2}\x{9CC3}\x{9CC4}\x{9CC5}\x{9CC6}\x{9CC7}\x{9CC8}\x{9CC9}\x{9CCA}' . '\x{9CCB}\x{9CCC}\x{9CCD}\x{9CCE}\x{9CCF}\x{9CD0}\x{9CD1}\x{9CD2}\x{9CD3}' . '\x{9CD4}\x{9CD5}\x{9CD6}\x{9CD7}\x{9CD8}\x{9CD9}\x{9CDA}\x{9CDB}\x{9CDC}' . '\x{9CDD}\x{9CDE}\x{9CDF}\x{9CE0}\x{9CE1}\x{9CE2}\x{9CE3}\x{9CE4}\x{9CE5}' . '\x{9CE6}\x{9CE7}\x{9CE8}\x{9CE9}\x{9CEA}\x{9CEB}\x{9CEC}\x{9CED}\x{9CEE}' . '\x{9CEF}\x{9CF0}\x{9CF1}\x{9CF2}\x{9CF3}\x{9CF4}\x{9CF5}\x{9CF6}\x{9CF7}' . '\x{9CF8}\x{9CF9}\x{9CFA}\x{9CFB}\x{9CFC}\x{9CFD}\x{9CFE}\x{9CFF}\x{9D00}' . '\x{9D01}\x{9D02}\x{9D03}\x{9D04}\x{9D05}\x{9D06}\x{9D07}\x{9D08}\x{9D09}' . '\x{9D0A}\x{9D0B}\x{9D0F}\x{9D10}\x{9D12}\x{9D13}\x{9D14}\x{9D15}\x{9D16}' . '\x{9D17}\x{9D18}\x{9D19}\x{9D1A}\x{9D1B}\x{9D1C}\x{9D1D}\x{9D1E}\x{9D1F}' . '\x{9D20}\x{9D21}\x{9D22}\x{9D23}\x{9D24}\x{9D25}\x{9D26}\x{9D28}\x{9D29}' . '\x{9D2B}\x{9D2D}\x{9D2E}\x{9D2F}\x{9D30}\x{9D31}\x{9D32}\x{9D33}\x{9D34}' . '\x{9D36}\x{9D37}\x{9D38}\x{9D39}\x{9D3A}\x{9D3B}\x{9D3D}\x{9D3E}\x{9D3F}' . '\x{9D40}\x{9D41}\x{9D42}\x{9D43}\x{9D45}\x{9D46}\x{9D47}\x{9D48}\x{9D49}' . '\x{9D4A}\x{9D4B}\x{9D4C}\x{9D4D}\x{9D4E}\x{9D4F}\x{9D50}\x{9D51}\x{9D52}' . '\x{9D53}\x{9D54}\x{9D55}\x{9D56}\x{9D57}\x{9D58}\x{9D59}\x{9D5A}\x{9D5B}' . '\x{9D5C}\x{9D5D}\x{9D5E}\x{9D5F}\x{9D60}\x{9D61}\x{9D62}\x{9D63}\x{9D64}' . '\x{9D65}\x{9D66}\x{9D67}\x{9D68}\x{9D69}\x{9D6A}\x{9D6B}\x{9D6C}\x{9D6E}' . '\x{9D6F}\x{9D70}\x{9D71}\x{9D72}\x{9D73}\x{9D74}\x{9D75}\x{9D76}\x{9D77}' . '\x{9D78}\x{9D79}\x{9D7A}\x{9D7B}\x{9D7C}\x{9D7D}\x{9D7E}\x{9D7F}\x{9D80}' . '\x{9D81}\x{9D82}\x{9D83}\x{9D84}\x{9D85}\x{9D86}\x{9D87}\x{9D88}\x{9D89}' . '\x{9D8A}\x{9D8B}\x{9D8C}\x{9D8D}\x{9D8E}\x{9D90}\x{9D91}\x{9D92}\x{9D93}' . '\x{9D94}\x{9D96}\x{9D97}\x{9D98}\x{9D99}\x{9D9A}\x{9D9B}\x{9D9C}\x{9D9D}' . '\x{9D9E}\x{9D9F}\x{9DA0}\x{9DA1}\x{9DA2}\x{9DA3}\x{9DA4}\x{9DA5}\x{9DA6}' . '\x{9DA7}\x{9DA8}\x{9DA9}\x{9DAA}\x{9DAB}\x{9DAC}\x{9DAD}\x{9DAF}\x{9DB0}' . '\x{9DB1}\x{9DB2}\x{9DB3}\x{9DB4}\x{9DB5}\x{9DB6}\x{9DB7}\x{9DB8}\x{9DB9}' . '\x{9DBA}\x{9DBB}\x{9DBC}\x{9DBE}\x{9DBF}\x{9DC1}\x{9DC2}\x{9DC3}\x{9DC4}' . '\x{9DC5}\x{9DC7}\x{9DC8}\x{9DC9}\x{9DCA}\x{9DCB}\x{9DCC}\x{9DCD}\x{9DCE}' . '\x{9DCF}\x{9DD0}\x{9DD1}\x{9DD2}\x{9DD3}\x{9DD4}\x{9DD5}\x{9DD6}\x{9DD7}' . '\x{9DD8}\x{9DD9}\x{9DDA}\x{9DDB}\x{9DDC}\x{9DDD}\x{9DDE}\x{9DDF}\x{9DE0}' . '\x{9DE1}\x{9DE2}\x{9DE3}\x{9DE4}\x{9DE5}\x{9DE6}\x{9DE7}\x{9DE8}\x{9DE9}' . '\x{9DEB}\x{9DEC}\x{9DED}\x{9DEE}\x{9DEF}\x{9DF0}\x{9DF1}\x{9DF2}\x{9DF3}' . '\x{9DF4}\x{9DF5}\x{9DF6}\x{9DF7}\x{9DF8}\x{9DF9}\x{9DFA}\x{9DFB}\x{9DFD}' . '\x{9DFE}\x{9DFF}\x{9E00}\x{9E01}\x{9E02}\x{9E03}\x{9E04}\x{9E05}\x{9E06}' . '\x{9E07}\x{9E08}\x{9E09}\x{9E0A}\x{9E0B}\x{9E0C}\x{9E0D}\x{9E0F}\x{9E10}' . '\x{9E11}\x{9E12}\x{9E13}\x{9E14}\x{9E15}\x{9E17}\x{9E18}\x{9E19}\x{9E1A}' . '\x{9E1B}\x{9E1D}\x{9E1E}\x{9E1F}\x{9E20}\x{9E21}\x{9E22}\x{9E23}\x{9E24}' . '\x{9E25}\x{9E26}\x{9E27}\x{9E28}\x{9E29}\x{9E2A}\x{9E2B}\x{9E2C}\x{9E2D}' . '\x{9E2E}\x{9E2F}\x{9E30}\x{9E31}\x{9E32}\x{9E33}\x{9E34}\x{9E35}\x{9E36}' . '\x{9E37}\x{9E38}\x{9E39}\x{9E3A}\x{9E3B}\x{9E3C}\x{9E3D}\x{9E3E}\x{9E3F}' . '\x{9E40}\x{9E41}\x{9E42}\x{9E43}\x{9E44}\x{9E45}\x{9E46}\x{9E47}\x{9E48}' . '\x{9E49}\x{9E4A}\x{9E4B}\x{9E4C}\x{9E4D}\x{9E4E}\x{9E4F}\x{9E50}\x{9E51}' . '\x{9E52}\x{9E53}\x{9E54}\x{9E55}\x{9E56}\x{9E57}\x{9E58}\x{9E59}\x{9E5A}' . '\x{9E5B}\x{9E5C}\x{9E5D}\x{9E5E}\x{9E5F}\x{9E60}\x{9E61}\x{9E62}\x{9E63}' . '\x{9E64}\x{9E65}\x{9E66}\x{9E67}\x{9E68}\x{9E69}\x{9E6A}\x{9E6B}\x{9E6C}' . '\x{9E6D}\x{9E6E}\x{9E6F}\x{9E70}\x{9E71}\x{9E72}\x{9E73}\x{9E74}\x{9E75}' . '\x{9E76}\x{9E77}\x{9E79}\x{9E7A}\x{9E7C}\x{9E7D}\x{9E7E}\x{9E7F}\x{9E80}' . '\x{9E81}\x{9E82}\x{9E83}\x{9E84}\x{9E85}\x{9E86}\x{9E87}\x{9E88}\x{9E89}' . '\x{9E8A}\x{9E8B}\x{9E8C}\x{9E8D}\x{9E8E}\x{9E91}\x{9E92}\x{9E93}\x{9E94}' . '\x{9E96}\x{9E97}\x{9E99}\x{9E9A}\x{9E9B}\x{9E9C}\x{9E9D}\x{9E9F}\x{9EA0}' . '\x{9EA1}\x{9EA3}\x{9EA4}\x{9EA5}\x{9EA6}\x{9EA7}\x{9EA8}\x{9EA9}\x{9EAA}' . '\x{9EAD}\x{9EAE}\x{9EAF}\x{9EB0}\x{9EB2}\x{9EB3}\x{9EB4}\x{9EB5}\x{9EB6}' . '\x{9EB7}\x{9EB8}\x{9EBB}\x{9EBC}\x{9EBD}\x{9EBE}\x{9EBF}\x{9EC0}\x{9EC1}' . '\x{9EC2}\x{9EC3}\x{9EC4}\x{9EC5}\x{9EC6}\x{9EC7}\x{9EC8}\x{9EC9}\x{9ECA}' . '\x{9ECB}\x{9ECC}\x{9ECD}\x{9ECE}\x{9ECF}\x{9ED0}\x{9ED1}\x{9ED2}\x{9ED3}' . '\x{9ED4}\x{9ED5}\x{9ED6}\x{9ED7}\x{9ED8}\x{9ED9}\x{9EDA}\x{9EDB}\x{9EDC}' . '\x{9EDD}\x{9EDE}\x{9EDF}\x{9EE0}\x{9EE1}\x{9EE2}\x{9EE3}\x{9EE4}\x{9EE5}' . '\x{9EE6}\x{9EE7}\x{9EE8}\x{9EE9}\x{9EEA}\x{9EEB}\x{9EED}\x{9EEE}\x{9EEF}' . '\x{9EF0}\x{9EF2}\x{9EF3}\x{9EF4}\x{9EF5}\x{9EF6}\x{9EF7}\x{9EF8}\x{9EF9}' . '\x{9EFA}\x{9EFB}\x{9EFC}\x{9EFD}\x{9EFE}\x{9EFF}\x{9F00}\x{9F01}\x{9F02}' . '\x{9F04}\x{9F05}\x{9F06}\x{9F07}\x{9F08}\x{9F09}\x{9F0A}\x{9F0B}\x{9F0C}' . '\x{9F0D}\x{9F0E}\x{9F0F}\x{9F10}\x{9F12}\x{9F13}\x{9F15}\x{9F16}\x{9F17}' . '\x{9F18}\x{9F19}\x{9F1A}\x{9F1B}\x{9F1C}\x{9F1D}\x{9F1E}\x{9F1F}\x{9F20}' . '\x{9F22}\x{9F23}\x{9F24}\x{9F25}\x{9F27}\x{9F28}\x{9F29}\x{9F2A}\x{9F2B}' . '\x{9F2C}\x{9F2D}\x{9F2E}\x{9F2F}\x{9F30}\x{9F31}\x{9F32}\x{9F33}\x{9F34}' . '\x{9F35}\x{9F36}\x{9F37}\x{9F38}\x{9F39}\x{9F3A}\x{9F3B}\x{9F3C}\x{9F3D}' . '\x{9F3E}\x{9F3F}\x{9F40}\x{9F41}\x{9F42}\x{9F43}\x{9F44}\x{9F46}\x{9F47}' . '\x{9F48}\x{9F49}\x{9F4A}\x{9F4B}\x{9F4C}\x{9F4D}\x{9F4E}\x{9F4F}\x{9F50}' . '\x{9F51}\x{9F52}\x{9F54}\x{9F55}\x{9F56}\x{9F57}\x{9F58}\x{9F59}\x{9F5A}' . '\x{9F5B}\x{9F5C}\x{9F5D}\x{9F5E}\x{9F5F}\x{9F60}\x{9F61}\x{9F63}\x{9F64}' . '\x{9F65}\x{9F66}\x{9F67}\x{9F68}\x{9F69}\x{9F6A}\x{9F6B}\x{9F6C}\x{9F6E}' . '\x{9F6F}\x{9F70}\x{9F71}\x{9F72}\x{9F73}\x{9F74}\x{9F75}\x{9F76}\x{9F77}' . '\x{9F78}\x{9F79}\x{9F7A}\x{9F7B}\x{9F7C}\x{9F7D}\x{9F7E}\x{9F7F}\x{9F80}' . '\x{9F81}\x{9F82}\x{9F83}\x{9F84}\x{9F85}\x{9F86}\x{9F87}\x{9F88}\x{9F89}' . '\x{9F8A}\x{9F8B}\x{9F8C}\x{9F8D}\x{9F8E}\x{9F8F}\x{9F90}\x{9F91}\x{9F92}' . '\x{9F93}\x{9F94}\x{9F95}\x{9F96}\x{9F97}\x{9F98}\x{9F99}\x{9F9A}\x{9F9B}' . '\x{9F9C}\x{9F9D}\x{9F9E}\x{9F9F}\x{9FA0}\x{9FA2}\x{9FA4}\x{9FA5}]{1,20}$/iu', ]; ================================================ FILE: src/Hostname/Com.php ================================================ '/^[\x{002d}0-9\x{0400}-\x{052f}]{1,63}$/iu', 2 => '/^[\x{002d}0-9\x{0370}-\x{03ff}]{1,63}$/iu', 3 => '/^[\x{002d}0-9a-z\x{ac00}-\x{d7a3}]{1,17}$/iu', // @codingStandardsIgnoreStart 4 => '/^[\x{002d}0-9a-z·à-öø-ÿāăąćĉċčďđēĕėęěĝğġģĥħĩīĭįıĵķĸĺļľłńņňŋōŏőœŕŗřśŝşšţťŧũūŭůűųŵŷźżž]{1,63}$/iu', // @codingStandardsIgnoreEnd 5 => '/^[\x{002d}0-9A-Za-z\x{3400}-\x{3401}\x{3404}-\x{3406}\x{340C}\x{3416}\x{341C}' . '\x{3421}\x{3424}\x{3428}-\x{3429}\x{342B}-\x{342E}\x{3430}-\x{3434}\x{3436}' . '\x{3438}-\x{343C}\x{343E}\x{3441}-\x{3445}\x{3447}\x{3449}-\x{3451}\x{3453}' . '\x{3457}-\x{345F}\x{3463}-\x{3467}\x{346E}-\x{3471}\x{3473}-\x{3477}\x{3479}-\x{348E}\x{3491}-\x{3497}' . '\x{3499}-\x{34A1}\x{34A4}-\x{34AD}\x{34AF}-\x{34B0}\x{34B2}-\x{34BF}\x{34C2}-\x{34C5}\x{34C7}-\x{34CC}' . '\x{34CE}-\x{34D1}\x{34D3}-\x{34D8}\x{34DA}-\x{34E4}\x{34E7}-\x{34E9}\x{34EC}-\x{34EF}\x{34F1}-\x{34FE}' . '\x{3500}-\x{3507}\x{350A}-\x{3513}\x{3515}\x{3517}-\x{351A}\x{351C}-\x{351E}\x{3520}-\x{352A}' . '\x{352C}-\x{3552}\x{3554}-\x{355C}\x{355E}-\x{3567}\x{3569}-\x{3573}\x{3575}-\x{357C}\x{3580}-\x{3588}' . '\x{358F}-\x{3598}\x{359E}-\x{35AB}\x{35B4}-\x{35CD}\x{35D0}\x{35D3}-\x{35DC}\x{35E2}-\x{35ED}' . '\x{35F0}-\x{35F6}\x{35FB}-\x{3602}\x{3605}-\x{360E}\x{3610}-\x{3611}\x{3613}-\x{3616}\x{3619}-\x{362D}' . '\x{362F}-\x{3634}\x{3636}-\x{363B}\x{363F}-\x{3645}\x{3647}-\x{364B}\x{364D}-\x{3653}\x{3655}' . '\x{3659}-\x{365E}\x{3660}-\x{3665}\x{3667}-\x{367C}\x{367E}\x{3680}-\x{3685}\x{3687}' . '\x{3689}-\x{3690}\x{3692}-\x{3698}\x{369A}\x{369C}-\x{36AE}\x{36B0}-\x{36BF}\x{36C1}-\x{36C5}' . '\x{36C9}-\x{36CA}\x{36CD}-\x{36DE}\x{36E1}-\x{36E2}\x{36E5}-\x{36FE}\x{3701}-\x{3713}\x{3715}-\x{371E}' . '\x{3720}-\x{372C}\x{372E}-\x{3745}\x{3747}-\x{3748}\x{374A}\x{374C}-\x{3759}\x{375B}-\x{3760}' . '\x{3762}-\x{3767}\x{3769}-\x{3772}\x{3774}-\x{378C}\x{378F}-\x{379C}\x{379F}\x{37A1}-\x{37AD}' . '\x{37AF}-\x{37B7}\x{37B9}-\x{37C1}\x{37C3}-\x{37C5}\x{37C7}-\x{37D4}\x{37D6}-\x{37E0}\x{37E2}' . '\x{37E5}-\x{37ED}\x{37EF}-\x{37F6}\x{37F8}-\x{3802}\x{3804}-\x{381D}\x{3820}-\x{3822}\x{3825}-\x{382A}' . '\x{382D}-\x{382F}\x{3831}-\x{3832}\x{3834}-\x{384C}\x{384E}-\x{3860}\x{3862}-\x{3863}\x{3865}-\x{386B}' . '\x{386D}-\x{3886}\x{3888}-\x{38A1}\x{38A3}\x{38A5}-\x{38AA}\x{38AC}\x{38AE}-\x{38B0}' . '\x{38B2}-\x{38B6}\x{38B8}\x{38BA}-\x{38BE}\x{38C0}-\x{38C9}\x{38CB}-\x{38D4}\x{38D8}-\x{38E0}' . '\x{38E2}-\x{38E6}\x{38EB}-\x{38ED}\x{38EF}-\x{38F2}\x{38F5}-\x{38F7}\x{38FA}-\x{38FF}\x{3901}-\x{392A}' . '\x{392C}\x{392E}-\x{393B}\x{393E}-\x{3956}\x{395A}-\x{3969}\x{396B}-\x{397A}\x{397C}-\x{3987}' . '\x{3989}-\x{3998}\x{399A}-\x{39B0}\x{39B2}\x{39B4}-\x{39D0}\x{39D2}-\x{39DA}\x{39DE}-\x{39DF}' . '\x{39E1}-\x{39EF}\x{39F1}-\x{3A17}\x{3A19}-\x{3A2A}\x{3A2D}-\x{3A40}\x{3A43}-\x{3A4E}\x{3A50}' . '\x{3A52}-\x{3A5E}\x{3A60}-\x{3A6D}\x{3A6F}-\x{3A77}\x{3A79}-\x{3A82}\x{3A84}-\x{3A85}\x{3A87}-\x{3A89}' . '\x{3A8B}-\x{3A8F}\x{3A91}-\x{3A93}\x{3A95}-\x{3A96}\x{3A9A}\x{3A9C}-\x{3AA6}\x{3AA8}-\x{3AA9}' . '\x{3AAB}-\x{3AB1}\x{3AB4}-\x{3ABC}\x{3ABE}-\x{3AC5}\x{3ACA}-\x{3ACB}\x{3ACD}-\x{3AD5}\x{3AD7}-\x{3AE1}' . '\x{3AE4}-\x{3AE7}\x{3AE9}-\x{3AEC}\x{3AEE}-\x{3AFD}\x{3B01}-\x{3B10}\x{3B12}-\x{3B15}\x{3B17}-\x{3B1E}' . '\x{3B20}-\x{3B23}\x{3B25}-\x{3B27}\x{3B29}-\x{3B36}\x{3B38}-\x{3B39}\x{3B3B}-\x{3B3C}\x{3B3F}' . '\x{3B41}-\x{3B44}\x{3B47}-\x{3B4C}\x{3B4E}\x{3B51}-\x{3B55}\x{3B58}-\x{3B62}\x{3B68}-\x{3B72}' . '\x{3B78}-\x{3B88}\x{3B8B}-\x{3B9F}\x{3BA1}\x{3BA3}-\x{3BBA}\x{3BBC}\x{3BBF}-\x{3BD0}' . '\x{3BD3}-\x{3BE6}\x{3BEA}-\x{3BFB}\x{3BFE}-\x{3C12}\x{3C14}-\x{3C1B}\x{3C1D}-\x{3C37}\x{3C39}-\x{3C4F}' . '\x{3C52}\x{3C54}-\x{3C5C}\x{3C5E}-\x{3C68}\x{3C6A}-\x{3C76}\x{3C78}-\x{3C8F}\x{3C91}-\x{3CA8}' . '\x{3CAA}-\x{3CAD}\x{3CAF}-\x{3CBE}\x{3CC0}-\x{3CC8}\x{3CCA}-\x{3CD3}\x{3CD6}-\x{3CE0}\x{3CE4}-\x{3CEE}' . '\x{3CF3}-\x{3D0A}\x{3D0E}-\x{3D1E}\x{3D20}-\x{3D21}\x{3D25}-\x{3D38}\x{3D3B}-\x{3D46}\x{3D4A}-\x{3D59}' . '\x{3D5D}-\x{3D7B}\x{3D7D}-\x{3D81}\x{3D84}-\x{3D88}\x{3D8C}-\x{3D8F}\x{3D91}-\x{3D98}\x{3D9A}-\x{3D9C}' . '\x{3D9E}-\x{3DA1}\x{3DA3}-\x{3DB0}\x{3DB2}-\x{3DB5}\x{3DB9}-\x{3DBC}\x{3DBE}-\x{3DCB}\x{3DCD}-\x{3DDB}' . '\x{3DDF}-\x{3DE8}\x{3DEB}-\x{3DF0}\x{3DF3}-\x{3DF9}\x{3DFB}-\x{3DFC}\x{3DFE}-\x{3E05}\x{3E08}-\x{3E33}' . '\x{3E35}-\x{3E3E}\x{3E40}-\x{3E47}\x{3E49}-\x{3E67}\x{3E6B}-\x{3E6F}\x{3E71}-\x{3E85}\x{3E87}-\x{3E8C}' . '\x{3E8E}-\x{3E98}\x{3E9A}-\x{3EA1}\x{3EA3}-\x{3EAE}\x{3EB0}-\x{3EB5}\x{3EB7}-\x{3EBA}\x{3EBD}' . '\x{3EBF}-\x{3EC4}\x{3EC7}-\x{3ECE}\x{3ED1}-\x{3ED7}\x{3ED9}-\x{3EDA}\x{3EDD}-\x{3EE3}\x{3EE7}-\x{3EE8}' . '\x{3EEB}-\x{3EF2}\x{3EF5}-\x{3EFF}\x{3F01}-\x{3F02}\x{3F04}-\x{3F07}\x{3F09}-\x{3F44}\x{3F46}-\x{3F4E}' . '\x{3F50}-\x{3F53}\x{3F55}-\x{3F72}\x{3F74}-\x{3F75}\x{3F77}-\x{3F7B}\x{3F7D}-\x{3FB0}\x{3FB6}-\x{3FBF}' . '\x{3FC1}-\x{3FCF}\x{3FD1}-\x{3FD3}\x{3FD5}-\x{3FDF}\x{3FE1}-\x{400B}\x{400D}-\x{401C}\x{401E}-\x{4024}' . '\x{4027}-\x{403F}\x{4041}-\x{4060}\x{4062}-\x{4069}\x{406B}-\x{408A}\x{408C}-\x{40A7}\x{40A9}-\x{40B4}' . '\x{40B6}-\x{40C2}\x{40C7}-\x{40CF}\x{40D1}-\x{40DE}\x{40E0}-\x{40E7}\x{40E9}-\x{40EE}\x{40F0}-\x{40FB}' . '\x{40FD}-\x{4109}\x{410B}-\x{4115}\x{4118}-\x{411D}\x{411F}-\x{4122}\x{4124}-\x{4133}\x{4136}-\x{4138}' . '\x{413A}-\x{4148}\x{414A}-\x{4169}\x{416C}-\x{4185}\x{4188}-\x{418B}\x{418D}-\x{41AD}\x{41AF}-\x{41B3}' . '\x{41B5}-\x{41C3}\x{41C5}-\x{41C9}\x{41CB}-\x{41F2}\x{41F5}-\x{41FE}\x{4200}-\x{4227}\x{422A}-\x{4246}' . '\x{4248}-\x{4263}\x{4265}-\x{428B}\x{428D}-\x{42A1}\x{42A3}-\x{42C4}\x{42C8}-\x{42DC}\x{42DE}-\x{430A}' . '\x{430C}-\x{4335}\x{4337}\x{4342}-\x{435F}\x{4361}-\x{439A}\x{439C}-\x{439D}\x{439F}-\x{43A4}' . '\x{43A6}-\x{43EC}\x{43EF}-\x{4405}\x{4407}-\x{4429}\x{442B}-\x{4455}\x{4457}-\x{4468}\x{446A}-\x{446D}' . '\x{446F}-\x{4476}\x{4479}-\x{447D}\x{447F}-\x{4486}\x{4488}-\x{4490}\x{4492}-\x{4498}\x{449A}-\x{44AD}' . '\x{44B0}-\x{44BD}\x{44C1}-\x{44D3}\x{44D6}-\x{44E7}\x{44EA}\x{44EC}-\x{44FA}\x{44FC}-\x{4541}' . '\x{4543}-\x{454F}\x{4551}-\x{4562}\x{4564}-\x{4575}\x{4577}-\x{45AB}\x{45AD}-\x{45BD}\x{45BF}-\x{45D5}' . '\x{45D7}-\x{45EC}\x{45EE}-\x{45F2}\x{45F4}-\x{45FA}\x{45FC}-\x{461A}\x{461C}-\x{461D}\x{461F}-\x{4631}' . '\x{4633}-\x{4649}\x{464C}\x{464E}-\x{4652}\x{4654}-\x{466A}\x{466C}-\x{4675}\x{4677}-\x{467A}' . '\x{467C}-\x{4694}\x{4696}-\x{46A3}\x{46A5}-\x{46AB}\x{46AD}-\x{46D2}\x{46D4}-\x{4723}\x{4729}-\x{4732}' . '\x{4734}-\x{4758}\x{475A}\x{475C}-\x{478B}\x{478D}\x{4791}-\x{47B1}\x{47B3}-\x{47F1}' . '\x{47F3}-\x{480B}\x{480D}-\x{4815}\x{4817}-\x{4839}\x{483B}-\x{4870}\x{4872}-\x{487A}\x{487C}-\x{487F}' . '\x{4883}-\x{488E}\x{4890}-\x{4896}\x{4899}-\x{48A2}\x{48A4}-\x{48B9}\x{48BB}-\x{48C8}\x{48CA}-\x{48D1}' . '\x{48D3}-\x{48E5}\x{48E7}-\x{48F2}\x{48F4}-\x{48FF}\x{4901}-\x{4922}\x{4924}-\x{4928}\x{492A}-\x{4931}' . '\x{4933}-\x{495B}\x{495D}-\x{4978}\x{497A}\x{497D}\x{4982}-\x{4983}\x{4985}-\x{49A8}' . '\x{49AA}-\x{49AF}\x{49B1}-\x{49B7}\x{49B9}-\x{49BD}\x{49C1}-\x{49C7}\x{49C9}-\x{49CE}\x{49D0}-\x{49E8}' . '\x{49EA}\x{49EC}\x{49EE}-\x{4A19}\x{4A1B}-\x{4A43}\x{4A45}-\x{4A4D}\x{4A4F}-\x{4A9E}' . '\x{4AA0}-\x{4AA9}\x{4AAB}-\x{4B4E}\x{4B50}-\x{4B5B}\x{4B5D}-\x{4B69}\x{4B6B}-\x{4BC2}\x{4BC6}-\x{4BE8}' . '\x{4BEA}-\x{4BFA}\x{4BFC}-\x{4C06}\x{4C08}-\x{4C2D}\x{4C2F}-\x{4C32}\x{4C34}-\x{4C35}\x{4C37}-\x{4C69}' . '\x{4C6B}-\x{4C73}\x{4C75}-\x{4C86}\x{4C88}-\x{4C97}\x{4C99}-\x{4C9C}\x{4C9F}-\x{4CA3}\x{4CA5}-\x{4CB5}' . '\x{4CB7}-\x{4CF8}\x{4CFA}-\x{4D27}\x{4D29}-\x{4DAC}\x{4DAE}-\x{4DB1}\x{4DB3}-\x{4DB5}\x{4E00}-\x{4E54}' . '\x{4E56}-\x{4E89}\x{4E8B}-\x{4EEC}\x{4EEE}-\x{4FAC}\x{4FAE}-\x{503C}\x{503E}-\x{51E5}\x{51E7}-\x{5270}' . '\x{5272}-\x{56A1}\x{56A3}-\x{5840}\x{5842}-\x{58B5}\x{58B7}-\x{58CB}\x{58CD}-\x{5BC8}\x{5BCA}-\x{5C01}' . '\x{5C03}-\x{5C25}\x{5C27}-\x{5D5B}\x{5D5D}-\x{5F08}\x{5F0A}-\x{61F3}\x{61F5}-\x{63BA}\x{63BC}-\x{6441}' . '\x{6443}-\x{657C}\x{657E}-\x{663E}\x{6640}-\x{66FC}\x{66FE}-\x{6728}\x{672A}-\x{6766}\x{6768}-\x{67A8}' . '\x{67AA}-\x{685B}\x{685D}-\x{685E}\x{6860}-\x{68B9}\x{68BB}-\x{6AC8}\x{6ACA}-\x{6BB0}\x{6BB2}-\x{6C16}' . '\x{6C18}-\x{6D9B}\x{6D9D}-\x{6E12}\x{6E14}-\x{6E8B}\x{6E8D}-\x{704D}\x{704F}-\x{7113}\x{7115}-\x{713B}' . '\x{713D}-\x{7154}\x{7156}-\x{729F}\x{72A1}-\x{731E}\x{7320}-\x{7362}\x{7364}-\x{7533}\x{7535}-\x{7551}' . '\x{7553}-\x{7572}\x{7574}-\x{75E8}\x{75EA}-\x{7679}\x{767B}-\x{783E}\x{7840}-\x{7A62}\x{7A64}-\x{7AC2}' . '\x{7AC4}-\x{7B06}\x{7B08}-\x{7B79}\x{7B7B}-\x{7BCE}\x{7BD0}-\x{7D99}\x{7D9B}-\x{7E49}\x{7E4C}-\x{8132}' . '\x{8134}\x{8136}-\x{81D2}\x{81D4}-\x{8216}\x{8218}-\x{822D}\x{822F}-\x{83B4}\x{83B6}-\x{841F}' . '\x{8421}-\x{86CC}\x{86CE}-\x{874A}\x{874C}-\x{877E}\x{8780}-\x{8A32}\x{8A34}-\x{8B71}\x{8B73}-\x{8B8E}' . '\x{8B90}-\x{8DE4}\x{8DE6}-\x{8E9A}\x{8E9C}-\x{8EE1}\x{8EE4}-\x{8F0B}\x{8F0D}-\x{8FB9}\x{8FBB}-\x{9038}' . '\x{903A}-\x{9196}\x{9198}-\x{91A3}\x{91A5}-\x{91B7}\x{91B9}-\x{91C7}\x{91C9}-\x{91E0}\x{91E2}-\x{91FB}' . '\x{91FD}-\x{922B}\x{922D}-\x{9270}\x{9272}-\x{9420}\x{9422}-\x{9664}\x{9666}-\x{9679}\x{967B}-\x{9770}' . '\x{9772}-\x{982B}\x{982D}-\x{98ED}\x{98EF}-\x{99C4}\x{99C6}-\x{9A11}\x{9A14}-\x{9A27}\x{9A29}-\x{9D0D}' . '\x{9D0F}-\x{9D2B}\x{9D2D}-\x{9D8E}\x{9D90}-\x{9DC5}\x{9DC7}-\x{9E77}\x{9E79}-\x{9EB8}\x{9EBB}-\x{9F20}' . '\x{9F22}-\x{9F61}\x{9F63}-\x{9FA5}\x{FA28}]{1,20}$/iu', 6 => '/^[\x{002d}0-9A-Za-z]{1,63}$/iu', 7 => '/^[\x{00A1}-\x{00FF}]{1,63}$/iu', 8 => '/^[\x{0100}-\x{017f}]{1,63}$/iu', 9 => '/^[\x{0180}-\x{024f}]{1,63}$/iu', 10 => '/^[\x{0250}-\x{02af}]{1,63}$/iu', 11 => '/^[\x{02b0}-\x{02ff}]{1,63}$/iu', 12 => '/^[\x{0300}-\x{036f}]{1,63}$/iu', 13 => '/^[\x{0370}-\x{03ff}]{1,63}$/iu', 14 => '/^[\x{0400}-\x{04ff}]{1,63}$/iu', 15 => '/^[\x{0500}-\x{052f}]{1,63}$/iu', 16 => '/^[\x{0530}-\x{058F}]{1,63}$/iu', 17 => '/^[\x{0590}-\x{05FF}]{1,63}$/iu', 18 => '/^[\x{0600}-\x{06FF}]{1,63}$/iu', 19 => '/^[\x{0700}-\x{074F}]{1,63}$/iu', 20 => '/^[\x{0780}-\x{07BF}]{1,63}$/iu', 21 => '/^[\x{0900}-\x{097F}]{1,63}$/iu', 22 => '/^[\x{0980}-\x{09FF}]{1,63}$/iu', 23 => '/^[\x{0A00}-\x{0A7F}]{1,63}$/iu', 24 => '/^[\x{0A80}-\x{0AFF}]{1,63}$/iu', 25 => '/^[\x{0B00}-\x{0B7F}]{1,63}$/iu', 26 => '/^[\x{0B80}-\x{0BFF}]{1,63}$/iu', 27 => '/^[\x{0C00}-\x{0C7F}]{1,63}$/iu', 28 => '/^[\x{0C80}-\x{0CFF}]{1,63}$/iu', 29 => '/^[\x{0D00}-\x{0D7F}]{1,63}$/iu', 30 => '/^[\x{0D80}-\x{0DFF}]{1,63}$/iu', 31 => '/^[\x{0E00}-\x{0E7F}]{1,63}$/iu', 32 => '/^[\x{0E80}-\x{0EFF}]{1,63}$/iu', 33 => '/^[\x{0F00}-\x{0FFF}]{1,63}$/iu', 34 => '/^[\x{1000}-\x{109F}]{1,63}$/iu', 35 => '/^[\x{10A0}-\x{10FF}]{1,63}$/iu', 36 => '/^[\x{1100}-\x{11FF}]{1,63}$/iu', 37 => '/^[\x{1200}-\x{137F}]{1,63}$/iu', 38 => '/^[\x{13A0}-\x{13FF}]{1,63}$/iu', 39 => '/^[\x{1400}-\x{167F}]{1,63}$/iu', 40 => '/^[\x{1680}-\x{169F}]{1,63}$/iu', 41 => '/^[\x{16A0}-\x{16FF}]{1,63}$/iu', 42 => '/^[\x{1700}-\x{171F}]{1,63}$/iu', 43 => '/^[\x{1720}-\x{173F}]{1,63}$/iu', 44 => '/^[\x{1740}-\x{175F}]{1,63}$/iu', 45 => '/^[\x{1760}-\x{177F}]{1,63}$/iu', 46 => '/^[\x{1780}-\x{17FF}]{1,63}$/iu', 47 => '/^[\x{1800}-\x{18AF}]{1,63}$/iu', 48 => '/^[\x{1E00}-\x{1EFF}]{1,63}$/iu', 49 => '/^[\x{1F00}-\x{1FFF}]{1,63}$/iu', 50 => '/^[\x{2070}-\x{209F}]{1,63}$/iu', 51 => '/^[\x{2100}-\x{214F}]{1,63}$/iu', 52 => '/^[\x{2150}-\x{218F}]{1,63}$/iu', 53 => '/^[\x{2460}-\x{24FF}]{1,63}$/iu', 54 => '/^[\x{2E80}-\x{2EFF}]{1,63}$/iu', 55 => '/^[\x{2F00}-\x{2FDF}]{1,63}$/iu', 56 => '/^[\x{2FF0}-\x{2FFF}]{1,63}$/iu', 57 => '/^[\x{3040}-\x{309F}]{1,63}$/iu', 58 => '/^[\x{30A0}-\x{30FF}]{1,63}$/iu', 59 => '/^[\x{3100}-\x{312F}]{1,63}$/iu', 60 => '/^[\x{3130}-\x{318F}]{1,63}$/iu', 61 => '/^[\x{3190}-\x{319F}]{1,63}$/iu', 62 => '/^[\x{31A0}-\x{31BF}]{1,63}$/iu', 63 => '/^[\x{31F0}-\x{31FF}]{1,63}$/iu', 64 => '/^[\x{3200}-\x{32FF}]{1,63}$/iu', 65 => '/^[\x{3300}-\x{33FF}]{1,63}$/iu', 66 => '/^[\x{3400}-\x{4DBF}]{1,63}$/iu', 67 => '/^[\x{4E00}-\x{9FFF}]{1,63}$/iu', 68 => '/^[\x{A000}-\x{A48F}]{1,63}$/iu', 69 => '/^[\x{A490}-\x{A4CF}]{1,63}$/iu', 70 => '/^[\x{AC00}-\x{D7AF}]{1,63}$/iu', 73 => '/^[\x{F900}-\x{FAFF}]{1,63}$/iu', 74 => '/^[\x{FB00}-\x{FB4F}]{1,63}$/iu', 75 => '/^[\x{FB50}-\x{FDFF}]{1,63}$/iu', 76 => '/^[\x{FE20}-\x{FE2F}]{1,63}$/iu', 77 => '/^[\x{FE70}-\x{FEFF}]{1,63}$/iu', 78 => '/^[\x{FF00}-\x{FFEF}]{1,63}$/iu', 79 => '/^[\x{20000}-\x{2A6DF}]{1,63}$/iu', 80 => '/^[\x{2F800}-\x{2FA1F}]{1,63}$/iu', ]; ================================================ FILE: src/Hostname/Jp.php ================================================ '/^[\x{002d}0-9a-z\x{3005}-\x{3007}\x{3041}-\x{3093}\x{309D}\x{309E}' . '\x{30A1}-\x{30F6}\x{30FC}' . '\x{30FD}\x{30FE}\x{4E00}\x{4E01}\x{4E03}\x{4E07}\x{4E08}\x{4E09}\x{4E0A}' . '\x{4E0B}\x{4E0D}\x{4E0E}\x{4E10}\x{4E11}\x{4E14}\x{4E15}\x{4E16}\x{4E17}' . '\x{4E18}\x{4E19}\x{4E1E}\x{4E21}\x{4E26}\x{4E2A}\x{4E2D}\x{4E31}\x{4E32}' . '\x{4E36}\x{4E38}\x{4E39}\x{4E3B}\x{4E3C}\x{4E3F}\x{4E42}\x{4E43}\x{4E45}' . '\x{4E4B}\x{4E4D}\x{4E4E}\x{4E4F}\x{4E55}\x{4E56}\x{4E57}\x{4E58}\x{4E59}' . '\x{4E5D}\x{4E5E}\x{4E5F}\x{4E62}\x{4E71}\x{4E73}\x{4E7E}\x{4E80}\x{4E82}' . '\x{4E85}\x{4E86}\x{4E88}\x{4E89}\x{4E8A}\x{4E8B}\x{4E8C}\x{4E8E}\x{4E91}' . '\x{4E92}\x{4E94}\x{4E95}\x{4E98}\x{4E99}\x{4E9B}\x{4E9C}\x{4E9E}\x{4E9F}' . '\x{4EA0}\x{4EA1}\x{4EA2}\x{4EA4}\x{4EA5}\x{4EA6}\x{4EA8}\x{4EAB}\x{4EAC}' . '\x{4EAD}\x{4EAE}\x{4EB0}\x{4EB3}\x{4EB6}\x{4EBA}\x{4EC0}\x{4EC1}\x{4EC2}' . '\x{4EC4}\x{4EC6}\x{4EC7}\x{4ECA}\x{4ECB}\x{4ECD}\x{4ECE}\x{4ECF}\x{4ED4}' . '\x{4ED5}\x{4ED6}\x{4ED7}\x{4ED8}\x{4ED9}\x{4EDD}\x{4EDE}\x{4EDF}\x{4EE3}' . '\x{4EE4}\x{4EE5}\x{4EED}\x{4EEE}\x{4EF0}\x{4EF2}\x{4EF6}\x{4EF7}\x{4EFB}' . '\x{4F01}\x{4F09}\x{4F0A}\x{4F0D}\x{4F0E}\x{4F0F}\x{4F10}\x{4F11}\x{4F1A}' . '\x{4F1C}\x{4F1D}\x{4F2F}\x{4F30}\x{4F34}\x{4F36}\x{4F38}\x{4F3A}\x{4F3C}' . '\x{4F3D}\x{4F43}\x{4F46}\x{4F47}\x{4F4D}\x{4F4E}\x{4F4F}\x{4F50}\x{4F51}' . '\x{4F53}\x{4F55}\x{4F57}\x{4F59}\x{4F5A}\x{4F5B}\x{4F5C}\x{4F5D}\x{4F5E}' . '\x{4F69}\x{4F6F}\x{4F70}\x{4F73}\x{4F75}\x{4F76}\x{4F7B}\x{4F7C}\x{4F7F}' . '\x{4F83}\x{4F86}\x{4F88}\x{4F8B}\x{4F8D}\x{4F8F}\x{4F91}\x{4F96}\x{4F98}' . '\x{4F9B}\x{4F9D}\x{4FA0}\x{4FA1}\x{4FAB}\x{4FAD}\x{4FAE}\x{4FAF}\x{4FB5}' . '\x{4FB6}\x{4FBF}\x{4FC2}\x{4FC3}\x{4FC4}\x{4FCA}\x{4FCE}\x{4FD0}\x{4FD1}' . '\x{4FD4}\x{4FD7}\x{4FD8}\x{4FDA}\x{4FDB}\x{4FDD}\x{4FDF}\x{4FE1}\x{4FE3}' . '\x{4FE4}\x{4FE5}\x{4FEE}\x{4FEF}\x{4FF3}\x{4FF5}\x{4FF6}\x{4FF8}\x{4FFA}' . '\x{4FFE}\x{5005}\x{5006}\x{5009}\x{500B}\x{500D}\x{500F}\x{5011}\x{5012}' . '\x{5014}\x{5016}\x{5019}\x{501A}\x{501F}\x{5021}\x{5023}\x{5024}\x{5025}' . '\x{5026}\x{5028}\x{5029}\x{502A}\x{502B}\x{502C}\x{502D}\x{5036}\x{5039}' . '\x{5043}\x{5047}\x{5048}\x{5049}\x{504F}\x{5050}\x{5055}\x{5056}\x{505A}' . '\x{505C}\x{5065}\x{506C}\x{5072}\x{5074}\x{5075}\x{5076}\x{5078}\x{507D}' . '\x{5080}\x{5085}\x{508D}\x{5091}\x{5098}\x{5099}\x{509A}\x{50AC}\x{50AD}' . '\x{50B2}\x{50B3}\x{50B4}\x{50B5}\x{50B7}\x{50BE}\x{50C2}\x{50C5}\x{50C9}' . '\x{50CA}\x{50CD}\x{50CF}\x{50D1}\x{50D5}\x{50D6}\x{50DA}\x{50DE}\x{50E3}' . '\x{50E5}\x{50E7}\x{50ED}\x{50EE}\x{50F5}\x{50F9}\x{50FB}\x{5100}\x{5101}' . '\x{5102}\x{5104}\x{5109}\x{5112}\x{5114}\x{5115}\x{5116}\x{5118}\x{511A}' . '\x{511F}\x{5121}\x{512A}\x{5132}\x{5137}\x{513A}\x{513B}\x{513C}\x{513F}' . '\x{5140}\x{5141}\x{5143}\x{5144}\x{5145}\x{5146}\x{5147}\x{5148}\x{5149}' . '\x{514B}\x{514C}\x{514D}\x{514E}\x{5150}\x{5152}\x{5154}\x{515A}\x{515C}' . '\x{5162}\x{5165}\x{5168}\x{5169}\x{516A}\x{516B}\x{516C}\x{516D}\x{516E}' . '\x{5171}\x{5175}\x{5176}\x{5177}\x{5178}\x{517C}\x{5180}\x{5182}\x{5185}' . '\x{5186}\x{5189}\x{518A}\x{518C}\x{518D}\x{518F}\x{5190}\x{5191}\x{5192}' . '\x{5193}\x{5195}\x{5196}\x{5197}\x{5199}\x{51A0}\x{51A2}\x{51A4}\x{51A5}' . '\x{51A6}\x{51A8}\x{51A9}\x{51AA}\x{51AB}\x{51AC}\x{51B0}\x{51B1}\x{51B2}' . '\x{51B3}\x{51B4}\x{51B5}\x{51B6}\x{51B7}\x{51BD}\x{51C4}\x{51C5}\x{51C6}' . '\x{51C9}\x{51CB}\x{51CC}\x{51CD}\x{51D6}\x{51DB}\x{51DC}\x{51DD}\x{51E0}' . '\x{51E1}\x{51E6}\x{51E7}\x{51E9}\x{51EA}\x{51ED}\x{51F0}\x{51F1}\x{51F5}' . '\x{51F6}\x{51F8}\x{51F9}\x{51FA}\x{51FD}\x{51FE}\x{5200}\x{5203}\x{5204}' . '\x{5206}\x{5207}\x{5208}\x{520A}\x{520B}\x{520E}\x{5211}\x{5214}\x{5217}' . '\x{521D}\x{5224}\x{5225}\x{5227}\x{5229}\x{522A}\x{522E}\x{5230}\x{5233}' . '\x{5236}\x{5237}\x{5238}\x{5239}\x{523A}\x{523B}\x{5243}\x{5244}\x{5247}' . '\x{524A}\x{524B}\x{524C}\x{524D}\x{524F}\x{5254}\x{5256}\x{525B}\x{525E}' . '\x{5263}\x{5264}\x{5265}\x{5269}\x{526A}\x{526F}\x{5270}\x{5271}\x{5272}' . '\x{5273}\x{5274}\x{5275}\x{527D}\x{527F}\x{5283}\x{5287}\x{5288}\x{5289}' . '\x{528D}\x{5291}\x{5292}\x{5294}\x{529B}\x{529F}\x{52A0}\x{52A3}\x{52A9}' . '\x{52AA}\x{52AB}\x{52AC}\x{52AD}\x{52B1}\x{52B4}\x{52B5}\x{52B9}\x{52BC}' . '\x{52BE}\x{52C1}\x{52C3}\x{52C5}\x{52C7}\x{52C9}\x{52CD}\x{52D2}\x{52D5}' . '\x{52D7}\x{52D8}\x{52D9}\x{52DD}\x{52DE}\x{52DF}\x{52E0}\x{52E2}\x{52E3}' . '\x{52E4}\x{52E6}\x{52E7}\x{52F2}\x{52F3}\x{52F5}\x{52F8}\x{52F9}\x{52FA}' . '\x{52FE}\x{52FF}\x{5301}\x{5302}\x{5305}\x{5306}\x{5308}\x{530D}\x{530F}' . '\x{5310}\x{5315}\x{5316}\x{5317}\x{5319}\x{531A}\x{531D}\x{5320}\x{5321}' . '\x{5323}\x{532A}\x{532F}\x{5331}\x{5333}\x{5338}\x{5339}\x{533A}\x{533B}' . '\x{533F}\x{5340}\x{5341}\x{5343}\x{5345}\x{5346}\x{5347}\x{5348}\x{5349}' . '\x{534A}\x{534D}\x{5351}\x{5352}\x{5353}\x{5354}\x{5357}\x{5358}\x{535A}' . '\x{535C}\x{535E}\x{5360}\x{5366}\x{5369}\x{536E}\x{536F}\x{5370}\x{5371}' . '\x{5373}\x{5374}\x{5375}\x{5377}\x{5378}\x{537B}\x{537F}\x{5382}\x{5384}' . '\x{5396}\x{5398}\x{539A}\x{539F}\x{53A0}\x{53A5}\x{53A6}\x{53A8}\x{53A9}' . '\x{53AD}\x{53AE}\x{53B0}\x{53B3}\x{53B6}\x{53BB}\x{53C2}\x{53C3}\x{53C8}' . '\x{53C9}\x{53CA}\x{53CB}\x{53CC}\x{53CD}\x{53CE}\x{53D4}\x{53D6}\x{53D7}' . '\x{53D9}\x{53DB}\x{53DF}\x{53E1}\x{53E2}\x{53E3}\x{53E4}\x{53E5}\x{53E8}' . '\x{53E9}\x{53EA}\x{53EB}\x{53EC}\x{53ED}\x{53EE}\x{53EF}\x{53F0}\x{53F1}' . '\x{53F2}\x{53F3}\x{53F6}\x{53F7}\x{53F8}\x{53FA}\x{5401}\x{5403}\x{5404}' . '\x{5408}\x{5409}\x{540A}\x{540B}\x{540C}\x{540D}\x{540E}\x{540F}\x{5410}' . '\x{5411}\x{541B}\x{541D}\x{541F}\x{5420}\x{5426}\x{5429}\x{542B}\x{542C}' . '\x{542D}\x{542E}\x{5436}\x{5438}\x{5439}\x{543B}\x{543C}\x{543D}\x{543E}' . '\x{5440}\x{5442}\x{5446}\x{5448}\x{5449}\x{544A}\x{544E}\x{5451}\x{545F}' . '\x{5468}\x{546A}\x{5470}\x{5471}\x{5473}\x{5475}\x{5476}\x{5477}\x{547B}' . '\x{547C}\x{547D}\x{5480}\x{5484}\x{5486}\x{548B}\x{548C}\x{548E}\x{548F}' . '\x{5490}\x{5492}\x{54A2}\x{54A4}\x{54A5}\x{54A8}\x{54AB}\x{54AC}\x{54AF}' . '\x{54B2}\x{54B3}\x{54B8}\x{54BC}\x{54BD}\x{54BE}\x{54C0}\x{54C1}\x{54C2}' . '\x{54C4}\x{54C7}\x{54C8}\x{54C9}\x{54D8}\x{54E1}\x{54E2}\x{54E5}\x{54E6}' . '\x{54E8}\x{54E9}\x{54ED}\x{54EE}\x{54F2}\x{54FA}\x{54FD}\x{5504}\x{5506}' . '\x{5507}\x{550F}\x{5510}\x{5514}\x{5516}\x{552E}\x{552F}\x{5531}\x{5533}' . '\x{5538}\x{5539}\x{553E}\x{5540}\x{5544}\x{5545}\x{5546}\x{554C}\x{554F}' . '\x{5553}\x{5556}\x{5557}\x{555C}\x{555D}\x{5563}\x{557B}\x{557C}\x{557E}' . '\x{5580}\x{5583}\x{5584}\x{5587}\x{5589}\x{558A}\x{558B}\x{5598}\x{5599}' . '\x{559A}\x{559C}\x{559D}\x{559E}\x{559F}\x{55A7}\x{55A8}\x{55A9}\x{55AA}' . '\x{55AB}\x{55AC}\x{55AE}\x{55B0}\x{55B6}\x{55C4}\x{55C5}\x{55C7}\x{55D4}' . '\x{55DA}\x{55DC}\x{55DF}\x{55E3}\x{55E4}\x{55F7}\x{55F9}\x{55FD}\x{55FE}' . '\x{5606}\x{5609}\x{5614}\x{5616}\x{5617}\x{5618}\x{561B}\x{5629}\x{562F}' . '\x{5631}\x{5632}\x{5634}\x{5636}\x{5638}\x{5642}\x{564C}\x{564E}\x{5650}' . '\x{565B}\x{5664}\x{5668}\x{566A}\x{566B}\x{566C}\x{5674}\x{5678}\x{567A}' . '\x{5680}\x{5686}\x{5687}\x{568A}\x{568F}\x{5694}\x{56A0}\x{56A2}\x{56A5}' . '\x{56AE}\x{56B4}\x{56B6}\x{56BC}\x{56C0}\x{56C1}\x{56C2}\x{56C3}\x{56C8}' . '\x{56CE}\x{56D1}\x{56D3}\x{56D7}\x{56D8}\x{56DA}\x{56DB}\x{56DE}\x{56E0}' . '\x{56E3}\x{56EE}\x{56F0}\x{56F2}\x{56F3}\x{56F9}\x{56FA}\x{56FD}\x{56FF}' . '\x{5700}\x{5703}\x{5704}\x{5708}\x{5709}\x{570B}\x{570D}\x{570F}\x{5712}' . '\x{5713}\x{5716}\x{5718}\x{571C}\x{571F}\x{5726}\x{5727}\x{5728}\x{572D}' . '\x{5730}\x{5737}\x{5738}\x{573B}\x{5740}\x{5742}\x{5747}\x{574A}\x{574E}' . '\x{574F}\x{5750}\x{5751}\x{5761}\x{5764}\x{5766}\x{5769}\x{576A}\x{577F}' . '\x{5782}\x{5788}\x{5789}\x{578B}\x{5793}\x{57A0}\x{57A2}\x{57A3}\x{57A4}' . '\x{57AA}\x{57B0}\x{57B3}\x{57C0}\x{57C3}\x{57C6}\x{57CB}\x{57CE}\x{57D2}' . '\x{57D3}\x{57D4}\x{57D6}\x{57DC}\x{57DF}\x{57E0}\x{57E3}\x{57F4}\x{57F7}' . '\x{57F9}\x{57FA}\x{57FC}\x{5800}\x{5802}\x{5805}\x{5806}\x{580A}\x{580B}' . '\x{5815}\x{5819}\x{581D}\x{5821}\x{5824}\x{582A}\x{582F}\x{5830}\x{5831}' . '\x{5834}\x{5835}\x{583A}\x{583D}\x{5840}\x{5841}\x{584A}\x{584B}\x{5851}' . '\x{5852}\x{5854}\x{5857}\x{5858}\x{5859}\x{585A}\x{585E}\x{5862}\x{5869}' . '\x{586B}\x{5870}\x{5872}\x{5875}\x{5879}\x{587E}\x{5883}\x{5885}\x{5893}' . '\x{5897}\x{589C}\x{589F}\x{58A8}\x{58AB}\x{58AE}\x{58B3}\x{58B8}\x{58B9}' . '\x{58BA}\x{58BB}\x{58BE}\x{58C1}\x{58C5}\x{58C7}\x{58CA}\x{58CC}\x{58D1}' . '\x{58D3}\x{58D5}\x{58D7}\x{58D8}\x{58D9}\x{58DC}\x{58DE}\x{58DF}\x{58E4}' . '\x{58E5}\x{58EB}\x{58EC}\x{58EE}\x{58EF}\x{58F0}\x{58F1}\x{58F2}\x{58F7}' . '\x{58F9}\x{58FA}\x{58FB}\x{58FC}\x{58FD}\x{5902}\x{5909}\x{590A}\x{590F}' . '\x{5910}\x{5915}\x{5916}\x{5918}\x{5919}\x{591A}\x{591B}\x{591C}\x{5922}' . '\x{5925}\x{5927}\x{5929}\x{592A}\x{592B}\x{592C}\x{592D}\x{592E}\x{5931}' . '\x{5932}\x{5937}\x{5938}\x{593E}\x{5944}\x{5947}\x{5948}\x{5949}\x{594E}' . '\x{594F}\x{5950}\x{5951}\x{5954}\x{5955}\x{5957}\x{5958}\x{595A}\x{5960}' . '\x{5962}\x{5965}\x{5967}\x{5968}\x{5969}\x{596A}\x{596C}\x{596E}\x{5973}' . '\x{5974}\x{5978}\x{597D}\x{5981}\x{5982}\x{5983}\x{5984}\x{598A}\x{598D}' . '\x{5993}\x{5996}\x{5999}\x{599B}\x{599D}\x{59A3}\x{59A5}\x{59A8}\x{59AC}' . '\x{59B2}\x{59B9}\x{59BB}\x{59BE}\x{59C6}\x{59C9}\x{59CB}\x{59D0}\x{59D1}' . '\x{59D3}\x{59D4}\x{59D9}\x{59DA}\x{59DC}\x{59E5}\x{59E6}\x{59E8}\x{59EA}' . '\x{59EB}\x{59F6}\x{59FB}\x{59FF}\x{5A01}\x{5A03}\x{5A09}\x{5A11}\x{5A18}' . '\x{5A1A}\x{5A1C}\x{5A1F}\x{5A20}\x{5A25}\x{5A29}\x{5A2F}\x{5A35}\x{5A36}' . '\x{5A3C}\x{5A40}\x{5A41}\x{5A46}\x{5A49}\x{5A5A}\x{5A62}\x{5A66}\x{5A6A}' . '\x{5A6C}\x{5A7F}\x{5A92}\x{5A9A}\x{5A9B}\x{5ABC}\x{5ABD}\x{5ABE}\x{5AC1}' . '\x{5AC2}\x{5AC9}\x{5ACB}\x{5ACC}\x{5AD0}\x{5AD6}\x{5AD7}\x{5AE1}\x{5AE3}' . '\x{5AE6}\x{5AE9}\x{5AFA}\x{5AFB}\x{5B09}\x{5B0B}\x{5B0C}\x{5B16}\x{5B22}' . '\x{5B2A}\x{5B2C}\x{5B30}\x{5B32}\x{5B36}\x{5B3E}\x{5B40}\x{5B43}\x{5B45}' . '\x{5B50}\x{5B51}\x{5B54}\x{5B55}\x{5B57}\x{5B58}\x{5B5A}\x{5B5B}\x{5B5C}' . '\x{5B5D}\x{5B5F}\x{5B63}\x{5B64}\x{5B65}\x{5B66}\x{5B69}\x{5B6B}\x{5B70}' . '\x{5B71}\x{5B73}\x{5B75}\x{5B78}\x{5B7A}\x{5B80}\x{5B83}\x{5B85}\x{5B87}' . '\x{5B88}\x{5B89}\x{5B8B}\x{5B8C}\x{5B8D}\x{5B8F}\x{5B95}\x{5B97}\x{5B98}' . '\x{5B99}\x{5B9A}\x{5B9B}\x{5B9C}\x{5B9D}\x{5B9F}\x{5BA2}\x{5BA3}\x{5BA4}' . '\x{5BA5}\x{5BA6}\x{5BAE}\x{5BB0}\x{5BB3}\x{5BB4}\x{5BB5}\x{5BB6}\x{5BB8}' . '\x{5BB9}\x{5BBF}\x{5BC2}\x{5BC3}\x{5BC4}\x{5BC5}\x{5BC6}\x{5BC7}\x{5BC9}' . '\x{5BCC}\x{5BD0}\x{5BD2}\x{5BD3}\x{5BD4}\x{5BDB}\x{5BDD}\x{5BDE}\x{5BDF}' . '\x{5BE1}\x{5BE2}\x{5BE4}\x{5BE5}\x{5BE6}\x{5BE7}\x{5BE8}\x{5BE9}\x{5BEB}' . '\x{5BEE}\x{5BF0}\x{5BF3}\x{5BF5}\x{5BF6}\x{5BF8}\x{5BFA}\x{5BFE}\x{5BFF}' . '\x{5C01}\x{5C02}\x{5C04}\x{5C05}\x{5C06}\x{5C07}\x{5C08}\x{5C09}\x{5C0A}' . '\x{5C0B}\x{5C0D}\x{5C0E}\x{5C0F}\x{5C11}\x{5C13}\x{5C16}\x{5C1A}\x{5C20}' . '\x{5C22}\x{5C24}\x{5C28}\x{5C2D}\x{5C31}\x{5C38}\x{5C39}\x{5C3A}\x{5C3B}' . '\x{5C3C}\x{5C3D}\x{5C3E}\x{5C3F}\x{5C40}\x{5C41}\x{5C45}\x{5C46}\x{5C48}' . '\x{5C4A}\x{5C4B}\x{5C4D}\x{5C4E}\x{5C4F}\x{5C50}\x{5C51}\x{5C53}\x{5C55}' . '\x{5C5E}\x{5C60}\x{5C61}\x{5C64}\x{5C65}\x{5C6C}\x{5C6E}\x{5C6F}\x{5C71}' . '\x{5C76}\x{5C79}\x{5C8C}\x{5C90}\x{5C91}\x{5C94}\x{5CA1}\x{5CA8}\x{5CA9}' . '\x{5CAB}\x{5CAC}\x{5CB1}\x{5CB3}\x{5CB6}\x{5CB7}\x{5CB8}\x{5CBB}\x{5CBC}' . '\x{5CBE}\x{5CC5}\x{5CC7}\x{5CD9}\x{5CE0}\x{5CE1}\x{5CE8}\x{5CE9}\x{5CEA}' . '\x{5CED}\x{5CEF}\x{5CF0}\x{5CF6}\x{5CFA}\x{5CFB}\x{5CFD}\x{5D07}\x{5D0B}' . '\x{5D0E}\x{5D11}\x{5D14}\x{5D15}\x{5D16}\x{5D17}\x{5D18}\x{5D19}\x{5D1A}' . '\x{5D1B}\x{5D1F}\x{5D22}\x{5D29}\x{5D4B}\x{5D4C}\x{5D4E}\x{5D50}\x{5D52}' . '\x{5D5C}\x{5D69}\x{5D6C}\x{5D6F}\x{5D73}\x{5D76}\x{5D82}\x{5D84}\x{5D87}' . '\x{5D8B}\x{5D8C}\x{5D90}\x{5D9D}\x{5DA2}\x{5DAC}\x{5DAE}\x{5DB7}\x{5DBA}' . '\x{5DBC}\x{5DBD}\x{5DC9}\x{5DCC}\x{5DCD}\x{5DD2}\x{5DD3}\x{5DD6}\x{5DDB}' . '\x{5DDD}\x{5DDE}\x{5DE1}\x{5DE3}\x{5DE5}\x{5DE6}\x{5DE7}\x{5DE8}\x{5DEB}' . '\x{5DEE}\x{5DF1}\x{5DF2}\x{5DF3}\x{5DF4}\x{5DF5}\x{5DF7}\x{5DFB}\x{5DFD}' . '\x{5DFE}\x{5E02}\x{5E03}\x{5E06}\x{5E0B}\x{5E0C}\x{5E11}\x{5E16}\x{5E19}' . '\x{5E1A}\x{5E1B}\x{5E1D}\x{5E25}\x{5E2B}\x{5E2D}\x{5E2F}\x{5E30}\x{5E33}' . '\x{5E36}\x{5E37}\x{5E38}\x{5E3D}\x{5E40}\x{5E43}\x{5E44}\x{5E45}\x{5E47}' . '\x{5E4C}\x{5E4E}\x{5E54}\x{5E55}\x{5E57}\x{5E5F}\x{5E61}\x{5E62}\x{5E63}' . '\x{5E64}\x{5E72}\x{5E73}\x{5E74}\x{5E75}\x{5E76}\x{5E78}\x{5E79}\x{5E7A}' . '\x{5E7B}\x{5E7C}\x{5E7D}\x{5E7E}\x{5E7F}\x{5E81}\x{5E83}\x{5E84}\x{5E87}' . '\x{5E8A}\x{5E8F}\x{5E95}\x{5E96}\x{5E97}\x{5E9A}\x{5E9C}\x{5EA0}\x{5EA6}' . '\x{5EA7}\x{5EAB}\x{5EAD}\x{5EB5}\x{5EB6}\x{5EB7}\x{5EB8}\x{5EC1}\x{5EC2}' . '\x{5EC3}\x{5EC8}\x{5EC9}\x{5ECA}\x{5ECF}\x{5ED0}\x{5ED3}\x{5ED6}\x{5EDA}' . '\x{5EDB}\x{5EDD}\x{5EDF}\x{5EE0}\x{5EE1}\x{5EE2}\x{5EE3}\x{5EE8}\x{5EE9}' . '\x{5EEC}\x{5EF0}\x{5EF1}\x{5EF3}\x{5EF4}\x{5EF6}\x{5EF7}\x{5EF8}\x{5EFA}' . '\x{5EFB}\x{5EFC}\x{5EFE}\x{5EFF}\x{5F01}\x{5F03}\x{5F04}\x{5F09}\x{5F0A}' . '\x{5F0B}\x{5F0C}\x{5F0D}\x{5F0F}\x{5F10}\x{5F11}\x{5F13}\x{5F14}\x{5F15}' . '\x{5F16}\x{5F17}\x{5F18}\x{5F1B}\x{5F1F}\x{5F25}\x{5F26}\x{5F27}\x{5F29}' . '\x{5F2D}\x{5F2F}\x{5F31}\x{5F35}\x{5F37}\x{5F38}\x{5F3C}\x{5F3E}\x{5F41}' . '\x{5F48}\x{5F4A}\x{5F4C}\x{5F4E}\x{5F51}\x{5F53}\x{5F56}\x{5F57}\x{5F59}' . '\x{5F5C}\x{5F5D}\x{5F61}\x{5F62}\x{5F66}\x{5F69}\x{5F6A}\x{5F6B}\x{5F6C}' . '\x{5F6D}\x{5F70}\x{5F71}\x{5F73}\x{5F77}\x{5F79}\x{5F7C}\x{5F7F}\x{5F80}' . '\x{5F81}\x{5F82}\x{5F83}\x{5F84}\x{5F85}\x{5F87}\x{5F88}\x{5F8A}\x{5F8B}' . '\x{5F8C}\x{5F90}\x{5F91}\x{5F92}\x{5F93}\x{5F97}\x{5F98}\x{5F99}\x{5F9E}' . '\x{5FA0}\x{5FA1}\x{5FA8}\x{5FA9}\x{5FAA}\x{5FAD}\x{5FAE}\x{5FB3}\x{5FB4}' . '\x{5FB9}\x{5FBC}\x{5FBD}\x{5FC3}\x{5FC5}\x{5FCC}\x{5FCD}\x{5FD6}\x{5FD7}' . '\x{5FD8}\x{5FD9}\x{5FDC}\x{5FDD}\x{5FE0}\x{5FE4}\x{5FEB}\x{5FF0}\x{5FF1}' . '\x{5FF5}\x{5FF8}\x{5FFB}\x{5FFD}\x{5FFF}\x{600E}\x{600F}\x{6010}\x{6012}' . '\x{6015}\x{6016}\x{6019}\x{601B}\x{601C}\x{601D}\x{6020}\x{6021}\x{6025}' . '\x{6026}\x{6027}\x{6028}\x{6029}\x{602A}\x{602B}\x{602F}\x{6031}\x{603A}' . '\x{6041}\x{6042}\x{6043}\x{6046}\x{604A}\x{604B}\x{604D}\x{6050}\x{6052}' . '\x{6055}\x{6059}\x{605A}\x{605F}\x{6060}\x{6062}\x{6063}\x{6064}\x{6065}' . '\x{6068}\x{6069}\x{606A}\x{606B}\x{606C}\x{606D}\x{606F}\x{6070}\x{6075}' . '\x{6077}\x{6081}\x{6083}\x{6084}\x{6089}\x{608B}\x{608C}\x{608D}\x{6092}' . '\x{6094}\x{6096}\x{6097}\x{609A}\x{609B}\x{609F}\x{60A0}\x{60A3}\x{60A6}' . '\x{60A7}\x{60A9}\x{60AA}\x{60B2}\x{60B3}\x{60B4}\x{60B5}\x{60B6}\x{60B8}' . '\x{60BC}\x{60BD}\x{60C5}\x{60C6}\x{60C7}\x{60D1}\x{60D3}\x{60D8}\x{60DA}' . '\x{60DC}\x{60DF}\x{60E0}\x{60E1}\x{60E3}\x{60E7}\x{60E8}\x{60F0}\x{60F1}' . '\x{60F3}\x{60F4}\x{60F6}\x{60F7}\x{60F9}\x{60FA}\x{60FB}\x{6100}\x{6101}' . '\x{6103}\x{6106}\x{6108}\x{6109}\x{610D}\x{610E}\x{610F}\x{6115}\x{611A}' . '\x{611B}\x{611F}\x{6121}\x{6127}\x{6128}\x{612C}\x{6134}\x{613C}\x{613D}' . '\x{613E}\x{613F}\x{6142}\x{6144}\x{6147}\x{6148}\x{614A}\x{614B}\x{614C}' . '\x{614D}\x{614E}\x{6153}\x{6155}\x{6158}\x{6159}\x{615A}\x{615D}\x{615F}' . '\x{6162}\x{6163}\x{6165}\x{6167}\x{6168}\x{616B}\x{616E}\x{616F}\x{6170}' . '\x{6171}\x{6173}\x{6174}\x{6175}\x{6176}\x{6177}\x{617E}\x{6182}\x{6187}' . '\x{618A}\x{618E}\x{6190}\x{6191}\x{6194}\x{6196}\x{6199}\x{619A}\x{61A4}' . '\x{61A7}\x{61A9}\x{61AB}\x{61AC}\x{61AE}\x{61B2}\x{61B6}\x{61BA}\x{61BE}' . '\x{61C3}\x{61C6}\x{61C7}\x{61C8}\x{61C9}\x{61CA}\x{61CB}\x{61CC}\x{61CD}' . '\x{61D0}\x{61E3}\x{61E6}\x{61F2}\x{61F4}\x{61F6}\x{61F7}\x{61F8}\x{61FA}' . '\x{61FC}\x{61FD}\x{61FE}\x{61FF}\x{6200}\x{6208}\x{6209}\x{620A}\x{620C}' . '\x{620D}\x{620E}\x{6210}\x{6211}\x{6212}\x{6214}\x{6216}\x{621A}\x{621B}' . '\x{621D}\x{621E}\x{621F}\x{6221}\x{6226}\x{622A}\x{622E}\x{622F}\x{6230}' . '\x{6232}\x{6233}\x{6234}\x{6238}\x{623B}\x{623F}\x{6240}\x{6241}\x{6247}' . '\x{6248}\x{6249}\x{624B}\x{624D}\x{624E}\x{6253}\x{6255}\x{6258}\x{625B}' . '\x{625E}\x{6260}\x{6263}\x{6268}\x{626E}\x{6271}\x{6276}\x{6279}\x{627C}' . '\x{627E}\x{627F}\x{6280}\x{6282}\x{6283}\x{6284}\x{6289}\x{628A}\x{6291}' . '\x{6292}\x{6293}\x{6294}\x{6295}\x{6296}\x{6297}\x{6298}\x{629B}\x{629C}' . '\x{629E}\x{62AB}\x{62AC}\x{62B1}\x{62B5}\x{62B9}\x{62BB}\x{62BC}\x{62BD}' . '\x{62C2}\x{62C5}\x{62C6}\x{62C7}\x{62C8}\x{62C9}\x{62CA}\x{62CC}\x{62CD}' . '\x{62CF}\x{62D0}\x{62D1}\x{62D2}\x{62D3}\x{62D4}\x{62D7}\x{62D8}\x{62D9}' . '\x{62DB}\x{62DC}\x{62DD}\x{62E0}\x{62E1}\x{62EC}\x{62ED}\x{62EE}\x{62EF}' . '\x{62F1}\x{62F3}\x{62F5}\x{62F6}\x{62F7}\x{62FE}\x{62FF}\x{6301}\x{6302}' . '\x{6307}\x{6308}\x{6309}\x{630C}\x{6311}\x{6319}\x{631F}\x{6327}\x{6328}' . '\x{632B}\x{632F}\x{633A}\x{633D}\x{633E}\x{633F}\x{6349}\x{634C}\x{634D}' . '\x{634F}\x{6350}\x{6355}\x{6357}\x{635C}\x{6367}\x{6368}\x{6369}\x{636B}' . '\x{636E}\x{6372}\x{6376}\x{6377}\x{637A}\x{637B}\x{6380}\x{6383}\x{6388}' . '\x{6389}\x{638C}\x{638E}\x{638F}\x{6392}\x{6396}\x{6398}\x{639B}\x{639F}' . '\x{63A0}\x{63A1}\x{63A2}\x{63A3}\x{63A5}\x{63A7}\x{63A8}\x{63A9}\x{63AA}' . '\x{63AB}\x{63AC}\x{63B2}\x{63B4}\x{63B5}\x{63BB}\x{63BE}\x{63C0}\x{63C3}' . '\x{63C4}\x{63C6}\x{63C9}\x{63CF}\x{63D0}\x{63D2}\x{63D6}\x{63DA}\x{63DB}' . '\x{63E1}\x{63E3}\x{63E9}\x{63EE}\x{63F4}\x{63F6}\x{63FA}\x{6406}\x{640D}' . '\x{640F}\x{6413}\x{6416}\x{6417}\x{641C}\x{6426}\x{6428}\x{642C}\x{642D}' . '\x{6434}\x{6436}\x{643A}\x{643E}\x{6442}\x{644E}\x{6458}\x{6467}\x{6469}' . '\x{646F}\x{6476}\x{6478}\x{647A}\x{6483}\x{6488}\x{6492}\x{6493}\x{6495}' . '\x{649A}\x{649E}\x{64A4}\x{64A5}\x{64A9}\x{64AB}\x{64AD}\x{64AE}\x{64B0}' . '\x{64B2}\x{64B9}\x{64BB}\x{64BC}\x{64C1}\x{64C2}\x{64C5}\x{64C7}\x{64CD}' . '\x{64D2}\x{64D4}\x{64D8}\x{64DA}\x{64E0}\x{64E1}\x{64E2}\x{64E3}\x{64E6}' . '\x{64E7}\x{64EC}\x{64EF}\x{64F1}\x{64F2}\x{64F4}\x{64F6}\x{64FA}\x{64FD}' . '\x{64FE}\x{6500}\x{6505}\x{6518}\x{651C}\x{651D}\x{6523}\x{6524}\x{652A}' . '\x{652B}\x{652C}\x{652F}\x{6534}\x{6535}\x{6536}\x{6537}\x{6538}\x{6539}' . '\x{653B}\x{653E}\x{653F}\x{6545}\x{6548}\x{654D}\x{654F}\x{6551}\x{6555}' . '\x{6556}\x{6557}\x{6558}\x{6559}\x{655D}\x{655E}\x{6562}\x{6563}\x{6566}' . '\x{656C}\x{6570}\x{6572}\x{6574}\x{6575}\x{6577}\x{6578}\x{6582}\x{6583}' . '\x{6587}\x{6588}\x{6589}\x{658C}\x{658E}\x{6590}\x{6591}\x{6597}\x{6599}' . '\x{659B}\x{659C}\x{659F}\x{65A1}\x{65A4}\x{65A5}\x{65A7}\x{65AB}\x{65AC}' . '\x{65AD}\x{65AF}\x{65B0}\x{65B7}\x{65B9}\x{65BC}\x{65BD}\x{65C1}\x{65C3}' . '\x{65C4}\x{65C5}\x{65C6}\x{65CB}\x{65CC}\x{65CF}\x{65D2}\x{65D7}\x{65D9}' . '\x{65DB}\x{65E0}\x{65E1}\x{65E2}\x{65E5}\x{65E6}\x{65E7}\x{65E8}\x{65E9}' . '\x{65EC}\x{65ED}\x{65F1}\x{65FA}\x{65FB}\x{6602}\x{6603}\x{6606}\x{6607}' . '\x{660A}\x{660C}\x{660E}\x{660F}\x{6613}\x{6614}\x{661C}\x{661F}\x{6620}' . '\x{6625}\x{6627}\x{6628}\x{662D}\x{662F}\x{6634}\x{6635}\x{6636}\x{663C}' . '\x{663F}\x{6641}\x{6642}\x{6643}\x{6644}\x{6649}\x{664B}\x{664F}\x{6652}' . '\x{665D}\x{665E}\x{665F}\x{6662}\x{6664}\x{6666}\x{6667}\x{6668}\x{6669}' . '\x{666E}\x{666F}\x{6670}\x{6674}\x{6676}\x{667A}\x{6681}\x{6683}\x{6684}' . '\x{6687}\x{6688}\x{6689}\x{668E}\x{6691}\x{6696}\x{6697}\x{6698}\x{669D}' . '\x{66A2}\x{66A6}\x{66AB}\x{66AE}\x{66B4}\x{66B8}\x{66B9}\x{66BC}\x{66BE}' . '\x{66C1}\x{66C4}\x{66C7}\x{66C9}\x{66D6}\x{66D9}\x{66DA}\x{66DC}\x{66DD}' . '\x{66E0}\x{66E6}\x{66E9}\x{66F0}\x{66F2}\x{66F3}\x{66F4}\x{66F5}\x{66F7}' . '\x{66F8}\x{66F9}\x{66FC}\x{66FD}\x{66FE}\x{66FF}\x{6700}\x{6703}\x{6708}' . '\x{6709}\x{670B}\x{670D}\x{670F}\x{6714}\x{6715}\x{6716}\x{6717}\x{671B}' . '\x{671D}\x{671E}\x{671F}\x{6726}\x{6727}\x{6728}\x{672A}\x{672B}\x{672C}' . '\x{672D}\x{672E}\x{6731}\x{6734}\x{6736}\x{6737}\x{6738}\x{673A}\x{673D}' . '\x{673F}\x{6741}\x{6746}\x{6749}\x{674E}\x{674F}\x{6750}\x{6751}\x{6753}' . '\x{6756}\x{6759}\x{675C}\x{675E}\x{675F}\x{6760}\x{6761}\x{6762}\x{6763}' . '\x{6764}\x{6765}\x{676A}\x{676D}\x{676F}\x{6770}\x{6771}\x{6772}\x{6773}' . '\x{6775}\x{6777}\x{677C}\x{677E}\x{677F}\x{6785}\x{6787}\x{6789}\x{678B}' . '\x{678C}\x{6790}\x{6795}\x{6797}\x{679A}\x{679C}\x{679D}\x{67A0}\x{67A1}' . '\x{67A2}\x{67A6}\x{67A9}\x{67AF}\x{67B3}\x{67B4}\x{67B6}\x{67B7}\x{67B8}' . '\x{67B9}\x{67C1}\x{67C4}\x{67C6}\x{67CA}\x{67CE}\x{67CF}\x{67D0}\x{67D1}' . '\x{67D3}\x{67D4}\x{67D8}\x{67DA}\x{67DD}\x{67DE}\x{67E2}\x{67E4}\x{67E7}' . '\x{67E9}\x{67EC}\x{67EE}\x{67EF}\x{67F1}\x{67F3}\x{67F4}\x{67F5}\x{67FB}' . '\x{67FE}\x{67FF}\x{6802}\x{6803}\x{6804}\x{6813}\x{6816}\x{6817}\x{681E}' . '\x{6821}\x{6822}\x{6829}\x{682A}\x{682B}\x{6832}\x{6834}\x{6838}\x{6839}' . '\x{683C}\x{683D}\x{6840}\x{6841}\x{6842}\x{6843}\x{6846}\x{6848}\x{684D}' . '\x{684E}\x{6850}\x{6851}\x{6853}\x{6854}\x{6859}\x{685C}\x{685D}\x{685F}' . '\x{6863}\x{6867}\x{6874}\x{6876}\x{6877}\x{687E}\x{687F}\x{6881}\x{6883}' . '\x{6885}\x{688D}\x{688F}\x{6893}\x{6894}\x{6897}\x{689B}\x{689D}\x{689F}' . '\x{68A0}\x{68A2}\x{68A6}\x{68A7}\x{68A8}\x{68AD}\x{68AF}\x{68B0}\x{68B1}' . '\x{68B3}\x{68B5}\x{68B6}\x{68B9}\x{68BA}\x{68BC}\x{68C4}\x{68C6}\x{68C9}' . '\x{68CA}\x{68CB}\x{68CD}\x{68D2}\x{68D4}\x{68D5}\x{68D7}\x{68D8}\x{68DA}' . '\x{68DF}\x{68E0}\x{68E1}\x{68E3}\x{68E7}\x{68EE}\x{68EF}\x{68F2}\x{68F9}' . '\x{68FA}\x{6900}\x{6901}\x{6904}\x{6905}\x{6908}\x{690B}\x{690C}\x{690D}' . '\x{690E}\x{690F}\x{6912}\x{6919}\x{691A}\x{691B}\x{691C}\x{6921}\x{6922}' . '\x{6923}\x{6925}\x{6926}\x{6928}\x{692A}\x{6930}\x{6934}\x{6936}\x{6939}' . '\x{693D}\x{693F}\x{694A}\x{6953}\x{6954}\x{6955}\x{6959}\x{695A}\x{695C}' . '\x{695D}\x{695E}\x{6960}\x{6961}\x{6962}\x{696A}\x{696B}\x{696D}\x{696E}' . '\x{696F}\x{6973}\x{6974}\x{6975}\x{6977}\x{6978}\x{6979}\x{697C}\x{697D}' . '\x{697E}\x{6981}\x{6982}\x{698A}\x{698E}\x{6991}\x{6994}\x{6995}\x{699B}' . '\x{699C}\x{69A0}\x{69A7}\x{69AE}\x{69B1}\x{69B2}\x{69B4}\x{69BB}\x{69BE}' . '\x{69BF}\x{69C1}\x{69C3}\x{69C7}\x{69CA}\x{69CB}\x{69CC}\x{69CD}\x{69CE}' . '\x{69D0}\x{69D3}\x{69D8}\x{69D9}\x{69DD}\x{69DE}\x{69E7}\x{69E8}\x{69EB}' . '\x{69ED}\x{69F2}\x{69F9}\x{69FB}\x{69FD}\x{69FF}\x{6A02}\x{6A05}\x{6A0A}' . '\x{6A0B}\x{6A0C}\x{6A12}\x{6A13}\x{6A14}\x{6A17}\x{6A19}\x{6A1B}\x{6A1E}' . '\x{6A1F}\x{6A21}\x{6A22}\x{6A23}\x{6A29}\x{6A2A}\x{6A2B}\x{6A2E}\x{6A35}' . '\x{6A36}\x{6A38}\x{6A39}\x{6A3A}\x{6A3D}\x{6A44}\x{6A47}\x{6A48}\x{6A4B}' . '\x{6A58}\x{6A59}\x{6A5F}\x{6A61}\x{6A62}\x{6A66}\x{6A72}\x{6A78}\x{6A7F}' . '\x{6A80}\x{6A84}\x{6A8D}\x{6A8E}\x{6A90}\x{6A97}\x{6A9C}\x{6AA0}\x{6AA2}' . '\x{6AA3}\x{6AAA}\x{6AAC}\x{6AAE}\x{6AB3}\x{6AB8}\x{6ABB}\x{6AC1}\x{6AC2}' . '\x{6AC3}\x{6AD1}\x{6AD3}\x{6ADA}\x{6ADB}\x{6ADE}\x{6ADF}\x{6AE8}\x{6AEA}' . '\x{6AFA}\x{6AFB}\x{6B04}\x{6B05}\x{6B0A}\x{6B12}\x{6B16}\x{6B1D}\x{6B1F}' . '\x{6B20}\x{6B21}\x{6B23}\x{6B27}\x{6B32}\x{6B37}\x{6B38}\x{6B39}\x{6B3A}' . '\x{6B3D}\x{6B3E}\x{6B43}\x{6B47}\x{6B49}\x{6B4C}\x{6B4E}\x{6B50}\x{6B53}' . '\x{6B54}\x{6B59}\x{6B5B}\x{6B5F}\x{6B61}\x{6B62}\x{6B63}\x{6B64}\x{6B66}' . '\x{6B69}\x{6B6A}\x{6B6F}\x{6B73}\x{6B74}\x{6B78}\x{6B79}\x{6B7B}\x{6B7F}' . '\x{6B80}\x{6B83}\x{6B84}\x{6B86}\x{6B89}\x{6B8A}\x{6B8B}\x{6B8D}\x{6B95}' . '\x{6B96}\x{6B98}\x{6B9E}\x{6BA4}\x{6BAA}\x{6BAB}\x{6BAF}\x{6BB1}\x{6BB2}' . '\x{6BB3}\x{6BB4}\x{6BB5}\x{6BB7}\x{6BBA}\x{6BBB}\x{6BBC}\x{6BBF}\x{6BC0}' . '\x{6BC5}\x{6BC6}\x{6BCB}\x{6BCD}\x{6BCE}\x{6BD2}\x{6BD3}\x{6BD4}\x{6BD8}' . '\x{6BDB}\x{6BDF}\x{6BEB}\x{6BEC}\x{6BEF}\x{6BF3}\x{6C08}\x{6C0F}\x{6C11}' . '\x{6C13}\x{6C14}\x{6C17}\x{6C1B}\x{6C23}\x{6C24}\x{6C34}\x{6C37}\x{6C38}' . '\x{6C3E}\x{6C40}\x{6C41}\x{6C42}\x{6C4E}\x{6C50}\x{6C55}\x{6C57}\x{6C5A}' . '\x{6C5D}\x{6C5E}\x{6C5F}\x{6C60}\x{6C62}\x{6C68}\x{6C6A}\x{6C70}\x{6C72}' . '\x{6C73}\x{6C7A}\x{6C7D}\x{6C7E}\x{6C81}\x{6C82}\x{6C83}\x{6C88}\x{6C8C}' . '\x{6C8D}\x{6C90}\x{6C92}\x{6C93}\x{6C96}\x{6C99}\x{6C9A}\x{6C9B}\x{6CA1}' . '\x{6CA2}\x{6CAB}\x{6CAE}\x{6CB1}\x{6CB3}\x{6CB8}\x{6CB9}\x{6CBA}\x{6CBB}' . '\x{6CBC}\x{6CBD}\x{6CBE}\x{6CBF}\x{6CC1}\x{6CC4}\x{6CC5}\x{6CC9}\x{6CCA}' . '\x{6CCC}\x{6CD3}\x{6CD5}\x{6CD7}\x{6CD9}\x{6CDB}\x{6CDD}\x{6CE1}\x{6CE2}' . '\x{6CE3}\x{6CE5}\x{6CE8}\x{6CEA}\x{6CEF}\x{6CF0}\x{6CF1}\x{6CF3}\x{6D0B}' . '\x{6D0C}\x{6D12}\x{6D17}\x{6D19}\x{6D1B}\x{6D1E}\x{6D1F}\x{6D25}\x{6D29}' . '\x{6D2A}\x{6D2B}\x{6D32}\x{6D33}\x{6D35}\x{6D36}\x{6D38}\x{6D3B}\x{6D3D}' . '\x{6D3E}\x{6D41}\x{6D44}\x{6D45}\x{6D59}\x{6D5A}\x{6D5C}\x{6D63}\x{6D64}' . '\x{6D66}\x{6D69}\x{6D6A}\x{6D6C}\x{6D6E}\x{6D74}\x{6D77}\x{6D78}\x{6D79}' . '\x{6D85}\x{6D88}\x{6D8C}\x{6D8E}\x{6D93}\x{6D95}\x{6D99}\x{6D9B}\x{6D9C}' . '\x{6DAF}\x{6DB2}\x{6DB5}\x{6DB8}\x{6DBC}\x{6DC0}\x{6DC5}\x{6DC6}\x{6DC7}' . '\x{6DCB}\x{6DCC}\x{6DD1}\x{6DD2}\x{6DD5}\x{6DD8}\x{6DD9}\x{6DDE}\x{6DE1}' . '\x{6DE4}\x{6DE6}\x{6DE8}\x{6DEA}\x{6DEB}\x{6DEC}\x{6DEE}\x{6DF1}\x{6DF3}' . '\x{6DF5}\x{6DF7}\x{6DF9}\x{6DFA}\x{6DFB}\x{6E05}\x{6E07}\x{6E08}\x{6E09}' . '\x{6E0A}\x{6E0B}\x{6E13}\x{6E15}\x{6E19}\x{6E1A}\x{6E1B}\x{6E1D}\x{6E1F}' . '\x{6E20}\x{6E21}\x{6E23}\x{6E24}\x{6E25}\x{6E26}\x{6E29}\x{6E2B}\x{6E2C}' . '\x{6E2D}\x{6E2E}\x{6E2F}\x{6E38}\x{6E3A}\x{6E3E}\x{6E43}\x{6E4A}\x{6E4D}' . '\x{6E4E}\x{6E56}\x{6E58}\x{6E5B}\x{6E5F}\x{6E67}\x{6E6B}\x{6E6E}\x{6E6F}' . '\x{6E72}\x{6E76}\x{6E7E}\x{6E7F}\x{6E80}\x{6E82}\x{6E8C}\x{6E8F}\x{6E90}' . '\x{6E96}\x{6E98}\x{6E9C}\x{6E9D}\x{6E9F}\x{6EA2}\x{6EA5}\x{6EAA}\x{6EAF}' . '\x{6EB2}\x{6EB6}\x{6EB7}\x{6EBA}\x{6EBD}\x{6EC2}\x{6EC4}\x{6EC5}\x{6EC9}' . '\x{6ECB}\x{6ECC}\x{6ED1}\x{6ED3}\x{6ED4}\x{6ED5}\x{6EDD}\x{6EDE}\x{6EEC}' . '\x{6EEF}\x{6EF2}\x{6EF4}\x{6EF7}\x{6EF8}\x{6EFE}\x{6EFF}\x{6F01}\x{6F02}' . '\x{6F06}\x{6F09}\x{6F0F}\x{6F11}\x{6F13}\x{6F14}\x{6F15}\x{6F20}\x{6F22}' . '\x{6F23}\x{6F2B}\x{6F2C}\x{6F31}\x{6F32}\x{6F38}\x{6F3E}\x{6F3F}\x{6F41}' . '\x{6F45}\x{6F54}\x{6F58}\x{6F5B}\x{6F5C}\x{6F5F}\x{6F64}\x{6F66}\x{6F6D}' . '\x{6F6E}\x{6F6F}\x{6F70}\x{6F74}\x{6F78}\x{6F7A}\x{6F7C}\x{6F80}\x{6F81}' . '\x{6F82}\x{6F84}\x{6F86}\x{6F8E}\x{6F91}\x{6F97}\x{6FA1}\x{6FA3}\x{6FA4}' . '\x{6FAA}\x{6FB1}\x{6FB3}\x{6FB9}\x{6FC0}\x{6FC1}\x{6FC2}\x{6FC3}\x{6FC6}' . '\x{6FD4}\x{6FD5}\x{6FD8}\x{6FDB}\x{6FDF}\x{6FE0}\x{6FE1}\x{6FE4}\x{6FEB}' . '\x{6FEC}\x{6FEE}\x{6FEF}\x{6FF1}\x{6FF3}\x{6FF6}\x{6FFA}\x{6FFE}\x{7001}' . '\x{7009}\x{700B}\x{700F}\x{7011}\x{7015}\x{7018}\x{701A}\x{701B}\x{701D}' . '\x{701E}\x{701F}\x{7026}\x{7027}\x{702C}\x{7030}\x{7032}\x{703E}\x{704C}' . '\x{7051}\x{7058}\x{7063}\x{706B}\x{706F}\x{7070}\x{7078}\x{707C}\x{707D}' . '\x{7089}\x{708A}\x{708E}\x{7092}\x{7099}\x{70AC}\x{70AD}\x{70AE}\x{70AF}' . '\x{70B3}\x{70B8}\x{70B9}\x{70BA}\x{70C8}\x{70CB}\x{70CF}\x{70D9}\x{70DD}' . '\x{70DF}\x{70F1}\x{70F9}\x{70FD}\x{7109}\x{7114}\x{7119}\x{711A}\x{711C}' . '\x{7121}\x{7126}\x{7136}\x{713C}\x{7149}\x{714C}\x{714E}\x{7155}\x{7156}' . '\x{7159}\x{7162}\x{7164}\x{7165}\x{7166}\x{7167}\x{7169}\x{716C}\x{716E}' . '\x{717D}\x{7184}\x{7188}\x{718A}\x{718F}\x{7194}\x{7195}\x{7199}\x{719F}' . '\x{71A8}\x{71AC}\x{71B1}\x{71B9}\x{71BE}\x{71C3}\x{71C8}\x{71C9}\x{71CE}' . '\x{71D0}\x{71D2}\x{71D4}\x{71D5}\x{71D7}\x{71DF}\x{71E0}\x{71E5}\x{71E6}' . '\x{71E7}\x{71EC}\x{71ED}\x{71EE}\x{71F5}\x{71F9}\x{71FB}\x{71FC}\x{71FF}' . '\x{7206}\x{720D}\x{7210}\x{721B}\x{7228}\x{722A}\x{722C}\x{722D}\x{7230}' . '\x{7232}\x{7235}\x{7236}\x{723A}\x{723B}\x{723C}\x{723D}\x{723E}\x{723F}' . '\x{7240}\x{7246}\x{7247}\x{7248}\x{724B}\x{724C}\x{7252}\x{7258}\x{7259}' . '\x{725B}\x{725D}\x{725F}\x{7261}\x{7262}\x{7267}\x{7269}\x{7272}\x{7274}' . '\x{7279}\x{727D}\x{727E}\x{7280}\x{7281}\x{7282}\x{7287}\x{7292}\x{7296}' . '\x{72A0}\x{72A2}\x{72A7}\x{72AC}\x{72AF}\x{72B2}\x{72B6}\x{72B9}\x{72C2}' . '\x{72C3}\x{72C4}\x{72C6}\x{72CE}\x{72D0}\x{72D2}\x{72D7}\x{72D9}\x{72DB}' . '\x{72E0}\x{72E1}\x{72E2}\x{72E9}\x{72EC}\x{72ED}\x{72F7}\x{72F8}\x{72F9}' . '\x{72FC}\x{72FD}\x{730A}\x{7316}\x{7317}\x{731B}\x{731C}\x{731D}\x{731F}' . '\x{7325}\x{7329}\x{732A}\x{732B}\x{732E}\x{732F}\x{7334}\x{7336}\x{7337}' . '\x{733E}\x{733F}\x{7344}\x{7345}\x{734E}\x{734F}\x{7357}\x{7363}\x{7368}' . '\x{736A}\x{7370}\x{7372}\x{7375}\x{7378}\x{737A}\x{737B}\x{7384}\x{7387}' . '\x{7389}\x{738B}\x{7396}\x{73A9}\x{73B2}\x{73B3}\x{73BB}\x{73C0}\x{73C2}' . '\x{73C8}\x{73CA}\x{73CD}\x{73CE}\x{73DE}\x{73E0}\x{73E5}\x{73EA}\x{73ED}' . '\x{73EE}\x{73F1}\x{73F8}\x{73FE}\x{7403}\x{7405}\x{7406}\x{7409}\x{7422}' . '\x{7425}\x{7432}\x{7433}\x{7434}\x{7435}\x{7436}\x{743A}\x{743F}\x{7441}' . '\x{7455}\x{7459}\x{745A}\x{745B}\x{745C}\x{745E}\x{745F}\x{7460}\x{7463}' . '\x{7464}\x{7469}\x{746A}\x{746F}\x{7470}\x{7473}\x{7476}\x{747E}\x{7483}' . '\x{748B}\x{749E}\x{74A2}\x{74A7}\x{74B0}\x{74BD}\x{74CA}\x{74CF}\x{74D4}' . '\x{74DC}\x{74E0}\x{74E2}\x{74E3}\x{74E6}\x{74E7}\x{74E9}\x{74EE}\x{74F0}' . '\x{74F1}\x{74F2}\x{74F6}\x{74F7}\x{74F8}\x{7503}\x{7504}\x{7505}\x{750C}' . '\x{750D}\x{750E}\x{7511}\x{7513}\x{7515}\x{7518}\x{751A}\x{751C}\x{751E}' . '\x{751F}\x{7523}\x{7525}\x{7526}\x{7528}\x{752B}\x{752C}\x{7530}\x{7531}' . '\x{7532}\x{7533}\x{7537}\x{7538}\x{753A}\x{753B}\x{753C}\x{7544}\x{7546}' . '\x{7549}\x{754A}\x{754B}\x{754C}\x{754D}\x{754F}\x{7551}\x{7554}\x{7559}' . '\x{755A}\x{755B}\x{755C}\x{755D}\x{7560}\x{7562}\x{7564}\x{7565}\x{7566}' . '\x{7567}\x{7569}\x{756A}\x{756B}\x{756D}\x{7570}\x{7573}\x{7574}\x{7576}' . '\x{7577}\x{7578}\x{757F}\x{7582}\x{7586}\x{7587}\x{7589}\x{758A}\x{758B}' . '\x{758E}\x{758F}\x{7591}\x{7594}\x{759A}\x{759D}\x{75A3}\x{75A5}\x{75AB}' . '\x{75B1}\x{75B2}\x{75B3}\x{75B5}\x{75B8}\x{75B9}\x{75BC}\x{75BD}\x{75BE}' . '\x{75C2}\x{75C3}\x{75C5}\x{75C7}\x{75CA}\x{75CD}\x{75D2}\x{75D4}\x{75D5}' . '\x{75D8}\x{75D9}\x{75DB}\x{75DE}\x{75E2}\x{75E3}\x{75E9}\x{75F0}\x{75F2}' . '\x{75F3}\x{75F4}\x{75FA}\x{75FC}\x{75FE}\x{75FF}\x{7601}\x{7609}\x{760B}' . '\x{760D}\x{761F}\x{7620}\x{7621}\x{7622}\x{7624}\x{7627}\x{7630}\x{7634}' . '\x{763B}\x{7642}\x{7646}\x{7647}\x{7648}\x{764C}\x{7652}\x{7656}\x{7658}' . '\x{765C}\x{7661}\x{7662}\x{7667}\x{7668}\x{7669}\x{766A}\x{766C}\x{7670}' . '\x{7672}\x{7676}\x{7678}\x{767A}\x{767B}\x{767C}\x{767D}\x{767E}\x{7680}' . '\x{7683}\x{7684}\x{7686}\x{7687}\x{7688}\x{768B}\x{768E}\x{7690}\x{7693}' . '\x{7696}\x{7699}\x{769A}\x{76AE}\x{76B0}\x{76B4}\x{76B7}\x{76B8}\x{76B9}' . '\x{76BA}\x{76BF}\x{76C2}\x{76C3}\x{76C6}\x{76C8}\x{76CA}\x{76CD}\x{76D2}' . '\x{76D6}\x{76D7}\x{76DB}\x{76DC}\x{76DE}\x{76DF}\x{76E1}\x{76E3}\x{76E4}' . '\x{76E5}\x{76E7}\x{76EA}\x{76EE}\x{76F2}\x{76F4}\x{76F8}\x{76FB}\x{76FE}' . '\x{7701}\x{7704}\x{7707}\x{7708}\x{7709}\x{770B}\x{770C}\x{771B}\x{771E}' . '\x{771F}\x{7720}\x{7724}\x{7725}\x{7726}\x{7729}\x{7737}\x{7738}\x{773A}' . '\x{773C}\x{7740}\x{7747}\x{775A}\x{775B}\x{7761}\x{7763}\x{7765}\x{7766}' . '\x{7768}\x{776B}\x{7779}\x{777E}\x{777F}\x{778B}\x{778E}\x{7791}\x{779E}' . '\x{77A0}\x{77A5}\x{77AC}\x{77AD}\x{77B0}\x{77B3}\x{77B6}\x{77B9}\x{77BB}' . '\x{77BC}\x{77BD}\x{77BF}\x{77C7}\x{77CD}\x{77D7}\x{77DA}\x{77DB}\x{77DC}' . '\x{77E2}\x{77E3}\x{77E5}\x{77E7}\x{77E9}\x{77ED}\x{77EE}\x{77EF}\x{77F3}' . '\x{77FC}\x{7802}\x{780C}\x{7812}\x{7814}\x{7815}\x{7820}\x{7825}\x{7826}' . '\x{7827}\x{7832}\x{7834}\x{783A}\x{783F}\x{7845}\x{785D}\x{786B}\x{786C}' . '\x{786F}\x{7872}\x{7874}\x{787C}\x{7881}\x{7886}\x{7887}\x{788C}\x{788D}' . '\x{788E}\x{7891}\x{7893}\x{7895}\x{7897}\x{789A}\x{78A3}\x{78A7}\x{78A9}' . '\x{78AA}\x{78AF}\x{78B5}\x{78BA}\x{78BC}\x{78BE}\x{78C1}\x{78C5}\x{78C6}' . '\x{78CA}\x{78CB}\x{78D0}\x{78D1}\x{78D4}\x{78DA}\x{78E7}\x{78E8}\x{78EC}' . '\x{78EF}\x{78F4}\x{78FD}\x{7901}\x{7907}\x{790E}\x{7911}\x{7912}\x{7919}' . '\x{7926}\x{792A}\x{792B}\x{792C}\x{793A}\x{793C}\x{793E}\x{7940}\x{7941}' . '\x{7947}\x{7948}\x{7949}\x{7950}\x{7953}\x{7955}\x{7956}\x{7957}\x{795A}' . '\x{795D}\x{795E}\x{795F}\x{7960}\x{7962}\x{7965}\x{7968}\x{796D}\x{7977}' . '\x{797A}\x{797F}\x{7980}\x{7981}\x{7984}\x{7985}\x{798A}\x{798D}\x{798E}' . '\x{798F}\x{799D}\x{79A6}\x{79A7}\x{79AA}\x{79AE}\x{79B0}\x{79B3}\x{79B9}' . '\x{79BA}\x{79BD}\x{79BE}\x{79BF}\x{79C0}\x{79C1}\x{79C9}\x{79CB}\x{79D1}' . '\x{79D2}\x{79D5}\x{79D8}\x{79DF}\x{79E1}\x{79E3}\x{79E4}\x{79E6}\x{79E7}' . '\x{79E9}\x{79EC}\x{79F0}\x{79FB}\x{7A00}\x{7A08}\x{7A0B}\x{7A0D}\x{7A0E}' . '\x{7A14}\x{7A17}\x{7A18}\x{7A19}\x{7A1A}\x{7A1C}\x{7A1F}\x{7A20}\x{7A2E}' . '\x{7A31}\x{7A32}\x{7A37}\x{7A3B}\x{7A3C}\x{7A3D}\x{7A3E}\x{7A3F}\x{7A40}' . '\x{7A42}\x{7A43}\x{7A46}\x{7A49}\x{7A4D}\x{7A4E}\x{7A4F}\x{7A50}\x{7A57}' . '\x{7A61}\x{7A62}\x{7A63}\x{7A69}\x{7A6B}\x{7A70}\x{7A74}\x{7A76}\x{7A79}' . '\x{7A7A}\x{7A7D}\x{7A7F}\x{7A81}\x{7A83}\x{7A84}\x{7A88}\x{7A92}\x{7A93}' . '\x{7A95}\x{7A96}\x{7A97}\x{7A98}\x{7A9F}\x{7AA9}\x{7AAA}\x{7AAE}\x{7AAF}' . '\x{7AB0}\x{7AB6}\x{7ABA}\x{7ABF}\x{7AC3}\x{7AC4}\x{7AC5}\x{7AC7}\x{7AC8}' . '\x{7ACA}\x{7ACB}\x{7ACD}\x{7ACF}\x{7AD2}\x{7AD3}\x{7AD5}\x{7AD9}\x{7ADA}' . '\x{7ADC}\x{7ADD}\x{7ADF}\x{7AE0}\x{7AE1}\x{7AE2}\x{7AE3}\x{7AE5}\x{7AE6}' . '\x{7AEA}\x{7AED}\x{7AEF}\x{7AF0}\x{7AF6}\x{7AF8}\x{7AF9}\x{7AFA}\x{7AFF}' . '\x{7B02}\x{7B04}\x{7B06}\x{7B08}\x{7B0A}\x{7B0B}\x{7B0F}\x{7B11}\x{7B18}' . '\x{7B19}\x{7B1B}\x{7B1E}\x{7B20}\x{7B25}\x{7B26}\x{7B28}\x{7B2C}\x{7B33}' . '\x{7B35}\x{7B36}\x{7B39}\x{7B45}\x{7B46}\x{7B48}\x{7B49}\x{7B4B}\x{7B4C}' . '\x{7B4D}\x{7B4F}\x{7B50}\x{7B51}\x{7B52}\x{7B54}\x{7B56}\x{7B5D}\x{7B65}' . '\x{7B67}\x{7B6C}\x{7B6E}\x{7B70}\x{7B71}\x{7B74}\x{7B75}\x{7B7A}\x{7B86}' . '\x{7B87}\x{7B8B}\x{7B8D}\x{7B8F}\x{7B92}\x{7B94}\x{7B95}\x{7B97}\x{7B98}' . '\x{7B99}\x{7B9A}\x{7B9C}\x{7B9D}\x{7B9F}\x{7BA1}\x{7BAA}\x{7BAD}\x{7BB1}' . '\x{7BB4}\x{7BB8}\x{7BC0}\x{7BC1}\x{7BC4}\x{7BC6}\x{7BC7}\x{7BC9}\x{7BCB}' . '\x{7BCC}\x{7BCF}\x{7BDD}\x{7BE0}\x{7BE4}\x{7BE5}\x{7BE6}\x{7BE9}\x{7BED}' . '\x{7BF3}\x{7BF6}\x{7BF7}\x{7C00}\x{7C07}\x{7C0D}\x{7C11}\x{7C12}\x{7C13}' . '\x{7C14}\x{7C17}\x{7C1F}\x{7C21}\x{7C23}\x{7C27}\x{7C2A}\x{7C2B}\x{7C37}' . '\x{7C38}\x{7C3D}\x{7C3E}\x{7C3F}\x{7C40}\x{7C43}\x{7C4C}\x{7C4D}\x{7C4F}' . '\x{7C50}\x{7C54}\x{7C56}\x{7C58}\x{7C5F}\x{7C60}\x{7C64}\x{7C65}\x{7C6C}' . '\x{7C73}\x{7C75}\x{7C7E}\x{7C81}\x{7C82}\x{7C83}\x{7C89}\x{7C8B}\x{7C8D}' . '\x{7C90}\x{7C92}\x{7C95}\x{7C97}\x{7C98}\x{7C9B}\x{7C9F}\x{7CA1}\x{7CA2}' . '\x{7CA4}\x{7CA5}\x{7CA7}\x{7CA8}\x{7CAB}\x{7CAD}\x{7CAE}\x{7CB1}\x{7CB2}' . '\x{7CB3}\x{7CB9}\x{7CBD}\x{7CBE}\x{7CC0}\x{7CC2}\x{7CC5}\x{7CCA}\x{7CCE}' . '\x{7CD2}\x{7CD6}\x{7CD8}\x{7CDC}\x{7CDE}\x{7CDF}\x{7CE0}\x{7CE2}\x{7CE7}' . '\x{7CEF}\x{7CF2}\x{7CF4}\x{7CF6}\x{7CF8}\x{7CFA}\x{7CFB}\x{7CFE}\x{7D00}' . '\x{7D02}\x{7D04}\x{7D05}\x{7D06}\x{7D0A}\x{7D0B}\x{7D0D}\x{7D10}\x{7D14}' . '\x{7D15}\x{7D17}\x{7D18}\x{7D19}\x{7D1A}\x{7D1B}\x{7D1C}\x{7D20}\x{7D21}' . '\x{7D22}\x{7D2B}\x{7D2C}\x{7D2E}\x{7D2F}\x{7D30}\x{7D32}\x{7D33}\x{7D35}' . '\x{7D39}\x{7D3A}\x{7D3F}\x{7D42}\x{7D43}\x{7D44}\x{7D45}\x{7D46}\x{7D4B}' . '\x{7D4C}\x{7D4E}\x{7D4F}\x{7D50}\x{7D56}\x{7D5B}\x{7D5E}\x{7D61}\x{7D62}' . '\x{7D63}\x{7D66}\x{7D68}\x{7D6E}\x{7D71}\x{7D72}\x{7D73}\x{7D75}\x{7D76}' . '\x{7D79}\x{7D7D}\x{7D89}\x{7D8F}\x{7D93}\x{7D99}\x{7D9A}\x{7D9B}\x{7D9C}' . '\x{7D9F}\x{7DA2}\x{7DA3}\x{7DAB}\x{7DAC}\x{7DAD}\x{7DAE}\x{7DAF}\x{7DB0}' . '\x{7DB1}\x{7DB2}\x{7DB4}\x{7DB5}\x{7DB8}\x{7DBA}\x{7DBB}\x{7DBD}\x{7DBE}' . '\x{7DBF}\x{7DC7}\x{7DCA}\x{7DCB}\x{7DCF}\x{7DD1}\x{7DD2}\x{7DD5}\x{7DD8}' . '\x{7DDA}\x{7DDC}\x{7DDD}\x{7DDE}\x{7DE0}\x{7DE1}\x{7DE4}\x{7DE8}\x{7DE9}' . '\x{7DEC}\x{7DEF}\x{7DF2}\x{7DF4}\x{7DFB}\x{7E01}\x{7E04}\x{7E05}\x{7E09}' . '\x{7E0A}\x{7E0B}\x{7E12}\x{7E1B}\x{7E1E}\x{7E1F}\x{7E21}\x{7E22}\x{7E23}' . '\x{7E26}\x{7E2B}\x{7E2E}\x{7E31}\x{7E32}\x{7E35}\x{7E37}\x{7E39}\x{7E3A}' . '\x{7E3B}\x{7E3D}\x{7E3E}\x{7E41}\x{7E43}\x{7E46}\x{7E4A}\x{7E4B}\x{7E4D}' . '\x{7E54}\x{7E55}\x{7E56}\x{7E59}\x{7E5A}\x{7E5D}\x{7E5E}\x{7E66}\x{7E67}' . '\x{7E69}\x{7E6A}\x{7E6D}\x{7E70}\x{7E79}\x{7E7B}\x{7E7C}\x{7E7D}\x{7E7F}' . '\x{7E82}\x{7E83}\x{7E88}\x{7E89}\x{7E8C}\x{7E8E}\x{7E8F}\x{7E90}\x{7E92}' . '\x{7E93}\x{7E94}\x{7E96}\x{7E9B}\x{7E9C}\x{7F36}\x{7F38}\x{7F3A}\x{7F45}' . '\x{7F4C}\x{7F4D}\x{7F4E}\x{7F50}\x{7F51}\x{7F54}\x{7F55}\x{7F58}\x{7F5F}' . '\x{7F60}\x{7F67}\x{7F68}\x{7F69}\x{7F6A}\x{7F6B}\x{7F6E}\x{7F70}\x{7F72}' . '\x{7F75}\x{7F77}\x{7F78}\x{7F79}\x{7F82}\x{7F83}\x{7F85}\x{7F86}\x{7F87}' . '\x{7F88}\x{7F8A}\x{7F8C}\x{7F8E}\x{7F94}\x{7F9A}\x{7F9D}\x{7F9E}\x{7FA3}' . '\x{7FA4}\x{7FA8}\x{7FA9}\x{7FAE}\x{7FAF}\x{7FB2}\x{7FB6}\x{7FB8}\x{7FB9}' . '\x{7FBD}\x{7FC1}\x{7FC5}\x{7FC6}\x{7FCA}\x{7FCC}\x{7FD2}\x{7FD4}\x{7FD5}' . '\x{7FE0}\x{7FE1}\x{7FE6}\x{7FE9}\x{7FEB}\x{7FF0}\x{7FF3}\x{7FF9}\x{7FFB}' . '\x{7FFC}\x{8000}\x{8001}\x{8003}\x{8004}\x{8005}\x{8006}\x{800B}\x{800C}' . '\x{8010}\x{8012}\x{8015}\x{8017}\x{8018}\x{8019}\x{801C}\x{8021}\x{8028}' . '\x{8033}\x{8036}\x{803B}\x{803D}\x{803F}\x{8046}\x{804A}\x{8052}\x{8056}' . '\x{8058}\x{805A}\x{805E}\x{805F}\x{8061}\x{8062}\x{8068}\x{806F}\x{8070}' . '\x{8072}\x{8073}\x{8074}\x{8076}\x{8077}\x{8079}\x{807D}\x{807E}\x{807F}' . '\x{8084}\x{8085}\x{8086}\x{8087}\x{8089}\x{808B}\x{808C}\x{8093}\x{8096}' . '\x{8098}\x{809A}\x{809B}\x{809D}\x{80A1}\x{80A2}\x{80A5}\x{80A9}\x{80AA}' . '\x{80AC}\x{80AD}\x{80AF}\x{80B1}\x{80B2}\x{80B4}\x{80BA}\x{80C3}\x{80C4}' . '\x{80C6}\x{80CC}\x{80CE}\x{80D6}\x{80D9}\x{80DA}\x{80DB}\x{80DD}\x{80DE}' . '\x{80E1}\x{80E4}\x{80E5}\x{80EF}\x{80F1}\x{80F4}\x{80F8}\x{80FC}\x{80FD}' . '\x{8102}\x{8105}\x{8106}\x{8107}\x{8108}\x{8109}\x{810A}\x{811A}\x{811B}' . '\x{8123}\x{8129}\x{812F}\x{8131}\x{8133}\x{8139}\x{813E}\x{8146}\x{814B}' . '\x{814E}\x{8150}\x{8151}\x{8153}\x{8154}\x{8155}\x{815F}\x{8165}\x{8166}' . '\x{816B}\x{816E}\x{8170}\x{8171}\x{8174}\x{8178}\x{8179}\x{817A}\x{817F}' . '\x{8180}\x{8182}\x{8183}\x{8188}\x{818A}\x{818F}\x{8193}\x{8195}\x{819A}' . '\x{819C}\x{819D}\x{81A0}\x{81A3}\x{81A4}\x{81A8}\x{81A9}\x{81B0}\x{81B3}' . '\x{81B5}\x{81B8}\x{81BA}\x{81BD}\x{81BE}\x{81BF}\x{81C0}\x{81C2}\x{81C6}' . '\x{81C8}\x{81C9}\x{81CD}\x{81D1}\x{81D3}\x{81D8}\x{81D9}\x{81DA}\x{81DF}' . '\x{81E0}\x{81E3}\x{81E5}\x{81E7}\x{81E8}\x{81EA}\x{81ED}\x{81F3}\x{81F4}' . '\x{81FA}\x{81FB}\x{81FC}\x{81FE}\x{8201}\x{8202}\x{8205}\x{8207}\x{8208}' . '\x{8209}\x{820A}\x{820C}\x{820D}\x{820E}\x{8210}\x{8212}\x{8216}\x{8217}' . '\x{8218}\x{821B}\x{821C}\x{821E}\x{821F}\x{8229}\x{822A}\x{822B}\x{822C}' . '\x{822E}\x{8233}\x{8235}\x{8236}\x{8237}\x{8238}\x{8239}\x{8240}\x{8247}' . '\x{8258}\x{8259}\x{825A}\x{825D}\x{825F}\x{8262}\x{8264}\x{8266}\x{8268}' . '\x{826A}\x{826B}\x{826E}\x{826F}\x{8271}\x{8272}\x{8276}\x{8277}\x{8278}' . '\x{827E}\x{828B}\x{828D}\x{8292}\x{8299}\x{829D}\x{829F}\x{82A5}\x{82A6}' . '\x{82AB}\x{82AC}\x{82AD}\x{82AF}\x{82B1}\x{82B3}\x{82B8}\x{82B9}\x{82BB}' . '\x{82BD}\x{82C5}\x{82D1}\x{82D2}\x{82D3}\x{82D4}\x{82D7}\x{82D9}\x{82DB}' . '\x{82DC}\x{82DE}\x{82DF}\x{82E1}\x{82E3}\x{82E5}\x{82E6}\x{82E7}\x{82EB}' . '\x{82F1}\x{82F3}\x{82F4}\x{82F9}\x{82FA}\x{82FB}\x{8302}\x{8303}\x{8304}' . '\x{8305}\x{8306}\x{8309}\x{830E}\x{8316}\x{8317}\x{8318}\x{831C}\x{8323}' . '\x{8328}\x{832B}\x{832F}\x{8331}\x{8332}\x{8334}\x{8335}\x{8336}\x{8338}' . '\x{8339}\x{8340}\x{8345}\x{8349}\x{834A}\x{834F}\x{8350}\x{8352}\x{8358}' . '\x{8373}\x{8375}\x{8377}\x{837B}\x{837C}\x{8385}\x{8387}\x{8389}\x{838A}' . '\x{838E}\x{8393}\x{8396}\x{839A}\x{839E}\x{839F}\x{83A0}\x{83A2}\x{83A8}' . '\x{83AA}\x{83AB}\x{83B1}\x{83B5}\x{83BD}\x{83C1}\x{83C5}\x{83CA}\x{83CC}' . '\x{83CE}\x{83D3}\x{83D6}\x{83D8}\x{83DC}\x{83DF}\x{83E0}\x{83E9}\x{83EB}' . '\x{83EF}\x{83F0}\x{83F1}\x{83F2}\x{83F4}\x{83F7}\x{83FB}\x{83FD}\x{8403}' . '\x{8404}\x{8407}\x{840B}\x{840C}\x{840D}\x{840E}\x{8413}\x{8420}\x{8422}' . '\x{8429}\x{842A}\x{842C}\x{8431}\x{8435}\x{8438}\x{843C}\x{843D}\x{8446}' . '\x{8449}\x{844E}\x{8457}\x{845B}\x{8461}\x{8462}\x{8463}\x{8466}\x{8469}' . '\x{846B}\x{846C}\x{846D}\x{846E}\x{846F}\x{8471}\x{8475}\x{8477}\x{8479}' . '\x{847A}\x{8482}\x{8484}\x{848B}\x{8490}\x{8494}\x{8499}\x{849C}\x{849F}' . '\x{84A1}\x{84AD}\x{84B2}\x{84B8}\x{84B9}\x{84BB}\x{84BC}\x{84BF}\x{84C1}' . '\x{84C4}\x{84C6}\x{84C9}\x{84CA}\x{84CB}\x{84CD}\x{84D0}\x{84D1}\x{84D6}' . '\x{84D9}\x{84DA}\x{84EC}\x{84EE}\x{84F4}\x{84FC}\x{84FF}\x{8500}\x{8506}' . '\x{8511}\x{8513}\x{8514}\x{8515}\x{8517}\x{8518}\x{851A}\x{851F}\x{8521}' . '\x{8526}\x{852C}\x{852D}\x{8535}\x{853D}\x{8540}\x{8541}\x{8543}\x{8548}' . '\x{8549}\x{854A}\x{854B}\x{854E}\x{8555}\x{8557}\x{8558}\x{855A}\x{8563}' . '\x{8568}\x{8569}\x{856A}\x{856D}\x{8577}\x{857E}\x{8580}\x{8584}\x{8587}' . '\x{8588}\x{858A}\x{8590}\x{8591}\x{8594}\x{8597}\x{8599}\x{859B}\x{859C}' . '\x{85A4}\x{85A6}\x{85A8}\x{85A9}\x{85AA}\x{85AB}\x{85AC}\x{85AE}\x{85AF}' . '\x{85B9}\x{85BA}\x{85C1}\x{85C9}\x{85CD}\x{85CF}\x{85D0}\x{85D5}\x{85DC}' . '\x{85DD}\x{85E4}\x{85E5}\x{85E9}\x{85EA}\x{85F7}\x{85F9}\x{85FA}\x{85FB}' . '\x{85FE}\x{8602}\x{8606}\x{8607}\x{860A}\x{860B}\x{8613}\x{8616}\x{8617}' . '\x{861A}\x{8622}\x{862D}\x{862F}\x{8630}\x{863F}\x{864D}\x{864E}\x{8650}' . '\x{8654}\x{8655}\x{865A}\x{865C}\x{865E}\x{865F}\x{8667}\x{866B}\x{8671}' . '\x{8679}\x{867B}\x{868A}\x{868B}\x{868C}\x{8693}\x{8695}\x{86A3}\x{86A4}' . '\x{86A9}\x{86AA}\x{86AB}\x{86AF}\x{86B0}\x{86B6}\x{86C4}\x{86C6}\x{86C7}' . '\x{86C9}\x{86CB}\x{86CD}\x{86CE}\x{86D4}\x{86D9}\x{86DB}\x{86DE}\x{86DF}' . '\x{86E4}\x{86E9}\x{86EC}\x{86ED}\x{86EE}\x{86EF}\x{86F8}\x{86F9}\x{86FB}' . '\x{86FE}\x{8700}\x{8702}\x{8703}\x{8706}\x{8708}\x{8709}\x{870A}\x{870D}' . '\x{8711}\x{8712}\x{8718}\x{871A}\x{871C}\x{8725}\x{8729}\x{8734}\x{8737}' . '\x{873B}\x{873F}\x{8749}\x{874B}\x{874C}\x{874E}\x{8753}\x{8755}\x{8757}' . '\x{8759}\x{875F}\x{8760}\x{8763}\x{8766}\x{8768}\x{876A}\x{876E}\x{8774}' . '\x{8776}\x{8778}\x{877F}\x{8782}\x{878D}\x{879F}\x{87A2}\x{87AB}\x{87AF}' . '\x{87B3}\x{87BA}\x{87BB}\x{87BD}\x{87C0}\x{87C4}\x{87C6}\x{87C7}\x{87CB}' . '\x{87D0}\x{87D2}\x{87E0}\x{87EF}\x{87F2}\x{87F6}\x{87F7}\x{87F9}\x{87FB}' . '\x{87FE}\x{8805}\x{880D}\x{880E}\x{880F}\x{8811}\x{8815}\x{8816}\x{8821}' . '\x{8822}\x{8823}\x{8827}\x{8831}\x{8836}\x{8839}\x{883B}\x{8840}\x{8842}' . '\x{8844}\x{8846}\x{884C}\x{884D}\x{8852}\x{8853}\x{8857}\x{8859}\x{885B}' . '\x{885D}\x{885E}\x{8861}\x{8862}\x{8863}\x{8868}\x{886B}\x{8870}\x{8872}' . '\x{8875}\x{8877}\x{887D}\x{887E}\x{887F}\x{8881}\x{8882}\x{8888}\x{888B}' . '\x{888D}\x{8892}\x{8896}\x{8897}\x{8899}\x{889E}\x{88A2}\x{88A4}\x{88AB}' . '\x{88AE}\x{88B0}\x{88B1}\x{88B4}\x{88B5}\x{88B7}\x{88BF}\x{88C1}\x{88C2}' . '\x{88C3}\x{88C4}\x{88C5}\x{88CF}\x{88D4}\x{88D5}\x{88D8}\x{88D9}\x{88DC}' . '\x{88DD}\x{88DF}\x{88E1}\x{88E8}\x{88F2}\x{88F3}\x{88F4}\x{88F8}\x{88F9}' . '\x{88FC}\x{88FD}\x{88FE}\x{8902}\x{8904}\x{8907}\x{890A}\x{890C}\x{8910}' . '\x{8912}\x{8913}\x{891D}\x{891E}\x{8925}\x{892A}\x{892B}\x{8936}\x{8938}' . '\x{893B}\x{8941}\x{8943}\x{8944}\x{894C}\x{894D}\x{8956}\x{895E}\x{895F}' . '\x{8960}\x{8964}\x{8966}\x{896A}\x{896D}\x{896F}\x{8972}\x{8974}\x{8977}' . '\x{897E}\x{897F}\x{8981}\x{8983}\x{8986}\x{8987}\x{8988}\x{898A}\x{898B}' . '\x{898F}\x{8993}\x{8996}\x{8997}\x{8998}\x{899A}\x{89A1}\x{89A6}\x{89A7}' . '\x{89A9}\x{89AA}\x{89AC}\x{89AF}\x{89B2}\x{89B3}\x{89BA}\x{89BD}\x{89BF}' . '\x{89C0}\x{89D2}\x{89DA}\x{89DC}\x{89DD}\x{89E3}\x{89E6}\x{89E7}\x{89F4}' . '\x{89F8}\x{8A00}\x{8A02}\x{8A03}\x{8A08}\x{8A0A}\x{8A0C}\x{8A0E}\x{8A10}' . '\x{8A13}\x{8A16}\x{8A17}\x{8A18}\x{8A1B}\x{8A1D}\x{8A1F}\x{8A23}\x{8A25}' . '\x{8A2A}\x{8A2D}\x{8A31}\x{8A33}\x{8A34}\x{8A36}\x{8A3A}\x{8A3B}\x{8A3C}' . '\x{8A41}\x{8A46}\x{8A48}\x{8A50}\x{8A51}\x{8A52}\x{8A54}\x{8A55}\x{8A5B}' . '\x{8A5E}\x{8A60}\x{8A62}\x{8A63}\x{8A66}\x{8A69}\x{8A6B}\x{8A6C}\x{8A6D}' . '\x{8A6E}\x{8A70}\x{8A71}\x{8A72}\x{8A73}\x{8A7C}\x{8A82}\x{8A84}\x{8A85}' . '\x{8A87}\x{8A89}\x{8A8C}\x{8A8D}\x{8A91}\x{8A93}\x{8A95}\x{8A98}\x{8A9A}' . '\x{8A9E}\x{8AA0}\x{8AA1}\x{8AA3}\x{8AA4}\x{8AA5}\x{8AA6}\x{8AA8}\x{8AAC}' . '\x{8AAD}\x{8AB0}\x{8AB2}\x{8AB9}\x{8ABC}\x{8ABF}\x{8AC2}\x{8AC4}\x{8AC7}' . '\x{8ACB}\x{8ACC}\x{8ACD}\x{8ACF}\x{8AD2}\x{8AD6}\x{8ADA}\x{8ADB}\x{8ADC}' . '\x{8ADE}\x{8AE0}\x{8AE1}\x{8AE2}\x{8AE4}\x{8AE6}\x{8AE7}\x{8AEB}\x{8AED}' . '\x{8AEE}\x{8AF1}\x{8AF3}\x{8AF7}\x{8AF8}\x{8AFA}\x{8AFE}\x{8B00}\x{8B01}' . '\x{8B02}\x{8B04}\x{8B07}\x{8B0C}\x{8B0E}\x{8B10}\x{8B14}\x{8B16}\x{8B17}' . '\x{8B19}\x{8B1A}\x{8B1B}\x{8B1D}\x{8B20}\x{8B21}\x{8B26}\x{8B28}\x{8B2B}' . '\x{8B2C}\x{8B33}\x{8B39}\x{8B3E}\x{8B41}\x{8B49}\x{8B4C}\x{8B4E}\x{8B4F}' . '\x{8B56}\x{8B58}\x{8B5A}\x{8B5B}\x{8B5C}\x{8B5F}\x{8B66}\x{8B6B}\x{8B6C}' . '\x{8B6F}\x{8B70}\x{8B71}\x{8B72}\x{8B74}\x{8B77}\x{8B7D}\x{8B80}\x{8B83}' . '\x{8B8A}\x{8B8C}\x{8B8E}\x{8B90}\x{8B92}\x{8B93}\x{8B96}\x{8B99}\x{8B9A}' . '\x{8C37}\x{8C3A}\x{8C3F}\x{8C41}\x{8C46}\x{8C48}\x{8C4A}\x{8C4C}\x{8C4E}' . '\x{8C50}\x{8C55}\x{8C5A}\x{8C61}\x{8C62}\x{8C6A}\x{8C6B}\x{8C6C}\x{8C78}' . '\x{8C79}\x{8C7A}\x{8C7C}\x{8C82}\x{8C85}\x{8C89}\x{8C8A}\x{8C8C}\x{8C8D}' . '\x{8C8E}\x{8C94}\x{8C98}\x{8C9D}\x{8C9E}\x{8CA0}\x{8CA1}\x{8CA2}\x{8CA7}' . '\x{8CA8}\x{8CA9}\x{8CAA}\x{8CAB}\x{8CAC}\x{8CAD}\x{8CAE}\x{8CAF}\x{8CB0}' . '\x{8CB2}\x{8CB3}\x{8CB4}\x{8CB6}\x{8CB7}\x{8CB8}\x{8CBB}\x{8CBC}\x{8CBD}' . '\x{8CBF}\x{8CC0}\x{8CC1}\x{8CC2}\x{8CC3}\x{8CC4}\x{8CC7}\x{8CC8}\x{8CCA}' . '\x{8CCD}\x{8CCE}\x{8CD1}\x{8CD3}\x{8CDA}\x{8CDB}\x{8CDC}\x{8CDE}\x{8CE0}' . '\x{8CE2}\x{8CE3}\x{8CE4}\x{8CE6}\x{8CEA}\x{8CED}\x{8CFA}\x{8CFB}\x{8CFC}' . '\x{8CFD}\x{8D04}\x{8D05}\x{8D07}\x{8D08}\x{8D0A}\x{8D0B}\x{8D0D}\x{8D0F}' . '\x{8D10}\x{8D13}\x{8D14}\x{8D16}\x{8D64}\x{8D66}\x{8D67}\x{8D6B}\x{8D6D}' . '\x{8D70}\x{8D71}\x{8D73}\x{8D74}\x{8D77}\x{8D81}\x{8D85}\x{8D8A}\x{8D99}' . '\x{8DA3}\x{8DA8}\x{8DB3}\x{8DBA}\x{8DBE}\x{8DC2}\x{8DCB}\x{8DCC}\x{8DCF}' . '\x{8DD6}\x{8DDA}\x{8DDB}\x{8DDD}\x{8DDF}\x{8DE1}\x{8DE3}\x{8DE8}\x{8DEA}' . '\x{8DEB}\x{8DEF}\x{8DF3}\x{8DF5}\x{8DFC}\x{8DFF}\x{8E08}\x{8E09}\x{8E0A}' . '\x{8E0F}\x{8E10}\x{8E1D}\x{8E1E}\x{8E1F}\x{8E2A}\x{8E30}\x{8E34}\x{8E35}' . '\x{8E42}\x{8E44}\x{8E47}\x{8E48}\x{8E49}\x{8E4A}\x{8E4C}\x{8E50}\x{8E55}' . '\x{8E59}\x{8E5F}\x{8E60}\x{8E63}\x{8E64}\x{8E72}\x{8E74}\x{8E76}\x{8E7C}' . '\x{8E81}\x{8E84}\x{8E85}\x{8E87}\x{8E8A}\x{8E8B}\x{8E8D}\x{8E91}\x{8E93}' . '\x{8E94}\x{8E99}\x{8EA1}\x{8EAA}\x{8EAB}\x{8EAC}\x{8EAF}\x{8EB0}\x{8EB1}' . '\x{8EBE}\x{8EC5}\x{8EC6}\x{8EC8}\x{8ECA}\x{8ECB}\x{8ECC}\x{8ECD}\x{8ED2}' . '\x{8EDB}\x{8EDF}\x{8EE2}\x{8EE3}\x{8EEB}\x{8EF8}\x{8EFB}\x{8EFC}\x{8EFD}' . '\x{8EFE}\x{8F03}\x{8F05}\x{8F09}\x{8F0A}\x{8F0C}\x{8F12}\x{8F13}\x{8F14}' . '\x{8F15}\x{8F19}\x{8F1B}\x{8F1C}\x{8F1D}\x{8F1F}\x{8F26}\x{8F29}\x{8F2A}' . '\x{8F2F}\x{8F33}\x{8F38}\x{8F39}\x{8F3B}\x{8F3E}\x{8F3F}\x{8F42}\x{8F44}' . '\x{8F45}\x{8F46}\x{8F49}\x{8F4C}\x{8F4D}\x{8F4E}\x{8F57}\x{8F5C}\x{8F5F}' . '\x{8F61}\x{8F62}\x{8F63}\x{8F64}\x{8F9B}\x{8F9C}\x{8F9E}\x{8F9F}\x{8FA3}' . '\x{8FA7}\x{8FA8}\x{8FAD}\x{8FAE}\x{8FAF}\x{8FB0}\x{8FB1}\x{8FB2}\x{8FB7}' . '\x{8FBA}\x{8FBB}\x{8FBC}\x{8FBF}\x{8FC2}\x{8FC4}\x{8FC5}\x{8FCE}\x{8FD1}' . '\x{8FD4}\x{8FDA}\x{8FE2}\x{8FE5}\x{8FE6}\x{8FE9}\x{8FEA}\x{8FEB}\x{8FED}' . '\x{8FEF}\x{8FF0}\x{8FF4}\x{8FF7}\x{8FF8}\x{8FF9}\x{8FFA}\x{8FFD}\x{9000}' . '\x{9001}\x{9003}\x{9005}\x{9006}\x{900B}\x{900D}\x{900E}\x{900F}\x{9010}' . '\x{9011}\x{9013}\x{9014}\x{9015}\x{9016}\x{9017}\x{9019}\x{901A}\x{901D}' . '\x{901E}\x{901F}\x{9020}\x{9021}\x{9022}\x{9023}\x{9027}\x{902E}\x{9031}' . '\x{9032}\x{9035}\x{9036}\x{9038}\x{9039}\x{903C}\x{903E}\x{9041}\x{9042}' . '\x{9045}\x{9047}\x{9049}\x{904A}\x{904B}\x{904D}\x{904E}\x{904F}\x{9050}' . '\x{9051}\x{9052}\x{9053}\x{9054}\x{9055}\x{9056}\x{9058}\x{9059}\x{905C}' . '\x{905E}\x{9060}\x{9061}\x{9063}\x{9065}\x{9068}\x{9069}\x{906D}\x{906E}' . '\x{906F}\x{9072}\x{9075}\x{9076}\x{9077}\x{9078}\x{907A}\x{907C}\x{907D}' . '\x{907F}\x{9080}\x{9081}\x{9082}\x{9083}\x{9084}\x{9087}\x{9089}\x{908A}' . '\x{908F}\x{9091}\x{90A3}\x{90A6}\x{90A8}\x{90AA}\x{90AF}\x{90B1}\x{90B5}' . '\x{90B8}\x{90C1}\x{90CA}\x{90CE}\x{90DB}\x{90E1}\x{90E2}\x{90E4}\x{90E8}' . '\x{90ED}\x{90F5}\x{90F7}\x{90FD}\x{9102}\x{9112}\x{9119}\x{912D}\x{9130}' . '\x{9132}\x{9149}\x{914A}\x{914B}\x{914C}\x{914D}\x{914E}\x{9152}\x{9154}' . '\x{9156}\x{9158}\x{9162}\x{9163}\x{9165}\x{9169}\x{916A}\x{916C}\x{9172}' . '\x{9173}\x{9175}\x{9177}\x{9178}\x{9182}\x{9187}\x{9189}\x{918B}\x{918D}' . '\x{9190}\x{9192}\x{9197}\x{919C}\x{91A2}\x{91A4}\x{91AA}\x{91AB}\x{91AF}' . '\x{91B4}\x{91B5}\x{91B8}\x{91BA}\x{91C0}\x{91C1}\x{91C6}\x{91C7}\x{91C8}' . '\x{91C9}\x{91CB}\x{91CC}\x{91CD}\x{91CE}\x{91CF}\x{91D0}\x{91D1}\x{91D6}' . '\x{91D8}\x{91DB}\x{91DC}\x{91DD}\x{91DF}\x{91E1}\x{91E3}\x{91E6}\x{91E7}' . '\x{91F5}\x{91F6}\x{91FC}\x{91FF}\x{920D}\x{920E}\x{9211}\x{9214}\x{9215}' . '\x{921E}\x{9229}\x{922C}\x{9234}\x{9237}\x{923F}\x{9244}\x{9245}\x{9248}' . '\x{9249}\x{924B}\x{9250}\x{9257}\x{925A}\x{925B}\x{925E}\x{9262}\x{9264}' . '\x{9266}\x{9271}\x{927E}\x{9280}\x{9283}\x{9285}\x{9291}\x{9293}\x{9295}' . '\x{9296}\x{9298}\x{929A}\x{929B}\x{929C}\x{92AD}\x{92B7}\x{92B9}\x{92CF}' . '\x{92D2}\x{92E4}\x{92E9}\x{92EA}\x{92ED}\x{92F2}\x{92F3}\x{92F8}\x{92FA}' . '\x{92FC}\x{9306}\x{930F}\x{9310}\x{9318}\x{9319}\x{931A}\x{9320}\x{9322}' . '\x{9323}\x{9326}\x{9328}\x{932B}\x{932C}\x{932E}\x{932F}\x{9332}\x{9335}' . '\x{933A}\x{933B}\x{9344}\x{934B}\x{934D}\x{9354}\x{9356}\x{935B}\x{935C}' . '\x{9360}\x{936C}\x{936E}\x{9375}\x{937C}\x{937E}\x{938C}\x{9394}\x{9396}' . '\x{9397}\x{939A}\x{93A7}\x{93AC}\x{93AD}\x{93AE}\x{93B0}\x{93B9}\x{93C3}' . '\x{93C8}\x{93D0}\x{93D1}\x{93D6}\x{93D7}\x{93D8}\x{93DD}\x{93E1}\x{93E4}' . '\x{93E5}\x{93E8}\x{9403}\x{9407}\x{9410}\x{9413}\x{9414}\x{9418}\x{9419}' . '\x{941A}\x{9421}\x{942B}\x{9435}\x{9436}\x{9438}\x{943A}\x{9441}\x{9444}' . '\x{9451}\x{9452}\x{9453}\x{945A}\x{945B}\x{945E}\x{9460}\x{9462}\x{946A}' . '\x{9470}\x{9475}\x{9477}\x{947C}\x{947D}\x{947E}\x{947F}\x{9481}\x{9577}' . '\x{9580}\x{9582}\x{9583}\x{9587}\x{9589}\x{958A}\x{958B}\x{958F}\x{9591}' . '\x{9593}\x{9594}\x{9596}\x{9598}\x{9599}\x{95A0}\x{95A2}\x{95A3}\x{95A4}' . '\x{95A5}\x{95A7}\x{95A8}\x{95AD}\x{95B2}\x{95B9}\x{95BB}\x{95BC}\x{95BE}' . '\x{95C3}\x{95C7}\x{95CA}\x{95CC}\x{95CD}\x{95D4}\x{95D5}\x{95D6}\x{95D8}' . '\x{95DC}\x{95E1}\x{95E2}\x{95E5}\x{961C}\x{9621}\x{9628}\x{962A}\x{962E}' . '\x{962F}\x{9632}\x{963B}\x{963F}\x{9640}\x{9642}\x{9644}\x{964B}\x{964C}' . '\x{964D}\x{964F}\x{9650}\x{965B}\x{965C}\x{965D}\x{965E}\x{965F}\x{9662}' . '\x{9663}\x{9664}\x{9665}\x{9666}\x{966A}\x{966C}\x{9670}\x{9672}\x{9673}' . '\x{9675}\x{9676}\x{9677}\x{9678}\x{967A}\x{967D}\x{9685}\x{9686}\x{9688}' . '\x{968A}\x{968B}\x{968D}\x{968E}\x{968F}\x{9694}\x{9695}\x{9697}\x{9698}' . '\x{9699}\x{969B}\x{969C}\x{96A0}\x{96A3}\x{96A7}\x{96A8}\x{96AA}\x{96B0}' . '\x{96B1}\x{96B2}\x{96B4}\x{96B6}\x{96B7}\x{96B8}\x{96B9}\x{96BB}\x{96BC}' . '\x{96C0}\x{96C1}\x{96C4}\x{96C5}\x{96C6}\x{96C7}\x{96C9}\x{96CB}\x{96CC}' . '\x{96CD}\x{96CE}\x{96D1}\x{96D5}\x{96D6}\x{96D9}\x{96DB}\x{96DC}\x{96E2}' . '\x{96E3}\x{96E8}\x{96EA}\x{96EB}\x{96F0}\x{96F2}\x{96F6}\x{96F7}\x{96F9}' . '\x{96FB}\x{9700}\x{9704}\x{9706}\x{9707}\x{9708}\x{970A}\x{970D}\x{970E}' . '\x{970F}\x{9711}\x{9713}\x{9716}\x{9719}\x{971C}\x{971E}\x{9724}\x{9727}' . '\x{972A}\x{9730}\x{9732}\x{9738}\x{9739}\x{973D}\x{973E}\x{9742}\x{9744}' . '\x{9746}\x{9748}\x{9749}\x{9752}\x{9756}\x{9759}\x{975C}\x{975E}\x{9760}' . '\x{9761}\x{9762}\x{9764}\x{9766}\x{9768}\x{9769}\x{976B}\x{976D}\x{9771}' . '\x{9774}\x{9779}\x{977A}\x{977C}\x{9781}\x{9784}\x{9785}\x{9786}\x{978B}' . '\x{978D}\x{978F}\x{9790}\x{9798}\x{979C}\x{97A0}\x{97A3}\x{97A6}\x{97A8}' . '\x{97AB}\x{97AD}\x{97B3}\x{97B4}\x{97C3}\x{97C6}\x{97C8}\x{97CB}\x{97D3}' . '\x{97DC}\x{97ED}\x{97EE}\x{97F2}\x{97F3}\x{97F5}\x{97F6}\x{97FB}\x{97FF}' . '\x{9801}\x{9802}\x{9803}\x{9805}\x{9806}\x{9808}\x{980C}\x{980F}\x{9810}' . '\x{9811}\x{9812}\x{9813}\x{9817}\x{9818}\x{981A}\x{9821}\x{9824}\x{982C}' . '\x{982D}\x{9834}\x{9837}\x{9838}\x{983B}\x{983C}\x{983D}\x{9846}\x{984B}' . '\x{984C}\x{984D}\x{984E}\x{984F}\x{9854}\x{9855}\x{9858}\x{985B}\x{985E}' . '\x{9867}\x{986B}\x{986F}\x{9870}\x{9871}\x{9873}\x{9874}\x{98A8}\x{98AA}' . '\x{98AF}\x{98B1}\x{98B6}\x{98C3}\x{98C4}\x{98C6}\x{98DB}\x{98DC}\x{98DF}' . '\x{98E2}\x{98E9}\x{98EB}\x{98ED}\x{98EE}\x{98EF}\x{98F2}\x{98F4}\x{98FC}' . '\x{98FD}\x{98FE}\x{9903}\x{9905}\x{9909}\x{990A}\x{990C}\x{9910}\x{9912}' . '\x{9913}\x{9914}\x{9918}\x{991D}\x{991E}\x{9920}\x{9921}\x{9924}\x{9928}' . '\x{992C}\x{992E}\x{993D}\x{993E}\x{9942}\x{9945}\x{9949}\x{994B}\x{994C}' . '\x{9950}\x{9951}\x{9952}\x{9955}\x{9957}\x{9996}\x{9997}\x{9998}\x{9999}' . '\x{99A5}\x{99A8}\x{99AC}\x{99AD}\x{99AE}\x{99B3}\x{99B4}\x{99BC}\x{99C1}' . '\x{99C4}\x{99C5}\x{99C6}\x{99C8}\x{99D0}\x{99D1}\x{99D2}\x{99D5}\x{99D8}' . '\x{99DB}\x{99DD}\x{99DF}\x{99E2}\x{99ED}\x{99EE}\x{99F1}\x{99F2}\x{99F8}' . '\x{99FB}\x{99FF}\x{9A01}\x{9A05}\x{9A0E}\x{9A0F}\x{9A12}\x{9A13}\x{9A19}' . '\x{9A28}\x{9A2B}\x{9A30}\x{9A37}\x{9A3E}\x{9A40}\x{9A42}\x{9A43}\x{9A45}' . '\x{9A4D}\x{9A55}\x{9A57}\x{9A5A}\x{9A5B}\x{9A5F}\x{9A62}\x{9A64}\x{9A65}' . '\x{9A69}\x{9A6A}\x{9A6B}\x{9AA8}\x{9AAD}\x{9AB0}\x{9AB8}\x{9ABC}\x{9AC0}' . '\x{9AC4}\x{9ACF}\x{9AD1}\x{9AD3}\x{9AD4}\x{9AD8}\x{9ADE}\x{9ADF}\x{9AE2}' . '\x{9AE3}\x{9AE6}\x{9AEA}\x{9AEB}\x{9AED}\x{9AEE}\x{9AEF}\x{9AF1}\x{9AF4}' . '\x{9AF7}\x{9AFB}\x{9B06}\x{9B18}\x{9B1A}\x{9B1F}\x{9B22}\x{9B23}\x{9B25}' . '\x{9B27}\x{9B28}\x{9B29}\x{9B2A}\x{9B2E}\x{9B2F}\x{9B31}\x{9B32}\x{9B3B}' . '\x{9B3C}\x{9B41}\x{9B42}\x{9B43}\x{9B44}\x{9B45}\x{9B4D}\x{9B4E}\x{9B4F}' . '\x{9B51}\x{9B54}\x{9B58}\x{9B5A}\x{9B6F}\x{9B74}\x{9B83}\x{9B8E}\x{9B91}' . '\x{9B92}\x{9B93}\x{9B96}\x{9B97}\x{9B9F}\x{9BA0}\x{9BA8}\x{9BAA}\x{9BAB}' . '\x{9BAD}\x{9BAE}\x{9BB4}\x{9BB9}\x{9BC0}\x{9BC6}\x{9BC9}\x{9BCA}\x{9BCF}' . '\x{9BD1}\x{9BD2}\x{9BD4}\x{9BD6}\x{9BDB}\x{9BE1}\x{9BE2}\x{9BE3}\x{9BE4}' . '\x{9BE8}\x{9BF0}\x{9BF1}\x{9BF2}\x{9BF5}\x{9C04}\x{9C06}\x{9C08}\x{9C09}' . '\x{9C0A}\x{9C0C}\x{9C0D}\x{9C10}\x{9C12}\x{9C13}\x{9C14}\x{9C15}\x{9C1B}' . '\x{9C21}\x{9C24}\x{9C25}\x{9C2D}\x{9C2E}\x{9C2F}\x{9C30}\x{9C32}\x{9C39}' . '\x{9C3A}\x{9C3B}\x{9C3E}\x{9C46}\x{9C47}\x{9C48}\x{9C52}\x{9C57}\x{9C5A}' . '\x{9C60}\x{9C67}\x{9C76}\x{9C78}\x{9CE5}\x{9CE7}\x{9CE9}\x{9CEB}\x{9CEC}' . '\x{9CF0}\x{9CF3}\x{9CF4}\x{9CF6}\x{9D03}\x{9D06}\x{9D07}\x{9D08}\x{9D09}' . '\x{9D0E}\x{9D12}\x{9D15}\x{9D1B}\x{9D1F}\x{9D23}\x{9D26}\x{9D28}\x{9D2A}' . '\x{9D2B}\x{9D2C}\x{9D3B}\x{9D3E}\x{9D3F}\x{9D41}\x{9D44}\x{9D46}\x{9D48}' . '\x{9D50}\x{9D51}\x{9D59}\x{9D5C}\x{9D5D}\x{9D5E}\x{9D60}\x{9D61}\x{9D64}' . '\x{9D6C}\x{9D6F}\x{9D72}\x{9D7A}\x{9D87}\x{9D89}\x{9D8F}\x{9D9A}\x{9DA4}' . '\x{9DA9}\x{9DAB}\x{9DAF}\x{9DB2}\x{9DB4}\x{9DB8}\x{9DBA}\x{9DBB}\x{9DC1}' . '\x{9DC2}\x{9DC4}\x{9DC6}\x{9DCF}\x{9DD3}\x{9DD9}\x{9DE6}\x{9DED}\x{9DEF}' . '\x{9DF2}\x{9DF8}\x{9DF9}\x{9DFA}\x{9DFD}\x{9E1A}\x{9E1B}\x{9E1E}\x{9E75}' . '\x{9E78}\x{9E79}\x{9E7D}\x{9E7F}\x{9E81}\x{9E88}\x{9E8B}\x{9E8C}\x{9E91}' . '\x{9E92}\x{9E93}\x{9E95}\x{9E97}\x{9E9D}\x{9E9F}\x{9EA5}\x{9EA6}\x{9EA9}' . '\x{9EAA}\x{9EAD}\x{9EB8}\x{9EB9}\x{9EBA}\x{9EBB}\x{9EBC}\x{9EBE}\x{9EBF}' . '\x{9EC4}\x{9ECC}\x{9ECD}\x{9ECE}\x{9ECF}\x{9ED0}\x{9ED2}\x{9ED4}\x{9ED8}' . '\x{9ED9}\x{9EDB}\x{9EDC}\x{9EDD}\x{9EDE}\x{9EE0}\x{9EE5}\x{9EE8}\x{9EEF}' . '\x{9EF4}\x{9EF6}\x{9EF7}\x{9EF9}\x{9EFB}\x{9EFC}\x{9EFD}\x{9F07}\x{9F08}' . '\x{9F0E}\x{9F13}\x{9F15}\x{9F20}\x{9F21}\x{9F2C}\x{9F3B}\x{9F3E}\x{9F4A}' . '\x{9F4B}\x{9F4E}\x{9F4F}\x{9F52}\x{9F54}\x{9F5F}\x{9F60}\x{9F61}\x{9F62}' . '\x{9F63}\x{9F66}\x{9F67}\x{9F6A}\x{9F6C}\x{9F72}\x{9F76}\x{9F77}\x{9F8D}' . '\x{9F95}\x{9F9C}\x{9F9D}\x{9FA0}]{1,15}$/iu', ]; ================================================ FILE: src/Hostname.php ================================================ "The input appears to be a DNS hostname but the given punycode notation cannot be decoded", self::INVALID => "Invalid type given. String expected", self::INVALID_DASH => "The input appears to be a DNS hostname but contains a dash in an invalid position", self::INVALID_HOSTNAME => "The input does not match the expected structure for a DNS hostname", self::INVALID_HOSTNAME_SCHEMA => "The input appears to be a DNS hostname but cannot match against hostname schema for TLD '%tld%'", self::INVALID_LOCAL_NAME => "The input does not appear to be a valid local network name", self::INVALID_URI => "The input does not appear to be a valid URI hostname", self::IP_ADDRESS_NOT_ALLOWED => "The input appears to be an IP address, but IP addresses are not allowed", self::LOCAL_NAME_NOT_ALLOWED => "The input appears to be a local network name but local network names are not allowed", self::UNDECIPHERABLE_TLD => "The input appears to be a DNS hostname but cannot extract TLD part", self::UNKNOWN_TLD => "The input appears to be a DNS hostname but cannot match TLD against known list", ]; // @codingStandardsIgnoreEnd /** * @var array */ protected $messageVariables = [ 'tld' => 'tld', ]; const ALLOW_DNS = 1; // Allows Internet domain names (e.g., example.com) const ALLOW_IP = 2; // Allows IP addresses const ALLOW_LOCAL = 4; // Allows local network names (e.g., localhost, www.localdomain) const ALLOW_URI = 8; // Allows URI hostnames const ALLOW_ALL = 15; // Allows all types of hostnames /** * Array of valid top-level-domains * IanaVersion 2019122700 * * @see ftp://data.iana.org/TLD/tlds-alpha-by-domain.txt List of all TLDs by domain * @see http://www.iana.org/domains/root/db/ Official list of supported TLDs * @var array */ protected $validTlds = [ 'aaa', 'aarp', 'abarth', 'abb', 'abbott', 'abbvie', 'abc', 'able', 'abogado', 'abudhabi', 'ac', 'academy', 'accenture', 'accountant', 'accountants', 'aco', 'actor', 'ad', 'adac', 'ads', 'adult', 'ae', 'aeg', 'aero', 'aetna', 'af', 'afamilycompany', 'afl', 'africa', 'ag', 'agakhan', 'agency', 'ai', 'aig', 'aigo', 'airbus', 'airforce', 'airtel', 'akdn', 'al', 'alfaromeo', 'alibaba', 'alipay', 'allfinanz', 'allstate', 'ally', 'alsace', 'alstom', 'am', 'americanexpress', 'americanfamily', 'amex', 'amfam', 'amica', 'amsterdam', 'analytics', 'android', 'anquan', 'anz', 'ao', 'aol', 'apartments', 'app', 'apple', 'aq', 'aquarelle', 'ar', 'arab', 'aramco', 'archi', 'army', 'arpa', 'art', 'arte', 'as', 'asda', 'asia', 'associates', 'at', 'athleta', 'attorney', 'au', 'auction', 'audi', 'audible', 'audio', 'auspost', 'author', 'auto', 'autos', 'avianca', 'aw', 'aws', 'ax', 'axa', 'az', 'azure', 'ba', 'baby', 'baidu', 'banamex', 'bananarepublic', 'band', 'bank', 'bar', 'barcelona', 'barclaycard', 'barclays', 'barefoot', 'bargains', 'baseball', 'basketball', 'bauhaus', 'bayern', 'bb', 'bbc', 'bbt', 'bbva', 'bcg', 'bcn', 'bd', 'be', 'beats', 'beauty', 'beer', 'bentley', 'berlin', 'best', 'bestbuy', 'bet', 'bf', 'bg', 'bh', 'bharti', 'bi', 'bible', 'bid', 'bike', 'bing', 'bingo', 'bio', 'biz', 'bj', 'black', 'blackfriday', 'blockbuster', 'blog', 'bloomberg', 'blue', 'bm', 'bms', 'bmw', 'bn', 'bnpparibas', 'bo', 'boats', 'boehringer', 'bofa', 'bom', 'bond', 'boo', 'book', 'booking', 'bosch', 'bostik', 'boston', 'bot', 'boutique', 'box', 'br', 'bradesco', 'bridgestone', 'broadway', 'broker', 'brother', 'brussels', 'bs', 'bt', 'budapest', 'bugatti', 'build', 'builders', 'business', 'buy', 'buzz', 'bv', 'bw', 'by', 'bz', 'bzh', 'ca', 'cab', 'cafe', 'cal', 'call', 'calvinklein', 'cam', 'camera', 'camp', 'cancerresearch', 'canon', 'capetown', 'capital', 'capitalone', 'car', 'caravan', 'cards', 'care', 'career', 'careers', 'cars', 'casa', 'case', 'caseih', 'cash', 'casino', 'cat', 'catering', 'catholic', 'cba', 'cbn', 'cbre', 'cbs', 'cc', 'cd', 'ceb', 'center', 'ceo', 'cern', 'cf', 'cfa', 'cfd', 'cg', 'ch', 'chanel', 'channel', 'charity', 'chase', 'chat', 'cheap', 'chintai', 'christmas', 'chrome', 'church', 'ci', 'cipriani', 'circle', 'cisco', 'citadel', 'citi', 'citic', 'city', 'cityeats', 'ck', 'cl', 'claims', 'cleaning', 'click', 'clinic', 'clinique', 'clothing', 'cloud', 'club', 'clubmed', 'cm', 'cn', 'co', 'coach', 'codes', 'coffee', 'college', 'cologne', 'com', 'comcast', 'commbank', 'community', 'company', 'compare', 'computer', 'comsec', 'condos', 'construction', 'consulting', 'contact', 'contractors', 'cooking', 'cookingchannel', 'cool', 'coop', 'corsica', 'country', 'coupon', 'coupons', 'courses', 'cpa', 'cr', 'credit', 'creditcard', 'creditunion', 'cricket', 'crown', 'crs', 'cruise', 'cruises', 'csc', 'cu', 'cuisinella', 'cv', 'cw', 'cx', 'cy', 'cymru', 'cyou', 'cz', 'dabur', 'dad', 'dance', 'data', 'date', 'dating', 'datsun', 'day', 'dclk', 'dds', 'de', 'deal', 'dealer', 'deals', 'degree', 'delivery', 'dell', 'deloitte', 'delta', 'democrat', 'dental', 'dentist', 'desi', 'design', 'dev', 'dhl', 'diamonds', 'diet', 'digital', 'direct', 'directory', 'discount', 'discover', 'dish', 'diy', 'dj', 'dk', 'dm', 'dnp', 'do', 'docs', 'doctor', 'dog', 'domains', 'dot', 'download', 'drive', 'dtv', 'dubai', 'duck', 'dunlop', 'dupont', 'durban', 'dvag', 'dvr', 'dz', 'earth', 'eat', 'ec', 'eco', 'edeka', 'edu', 'education', 'ee', 'eg', 'email', 'emerck', 'energy', 'engineer', 'engineering', 'enterprises', 'epson', 'equipment', 'er', 'ericsson', 'erni', 'es', 'esq', 'estate', 'esurance', 'et', 'etisalat', 'eu', 'eurovision', 'eus', 'events', 'exchange', 'expert', 'exposed', 'express', 'extraspace', 'fage', 'fail', 'fairwinds', 'faith', 'family', 'fan', 'fans', 'farm', 'farmers', 'fashion', 'fast', 'fedex', 'feedback', 'ferrari', 'ferrero', 'fi', 'fiat', 'fidelity', 'fido', 'film', 'final', 'finance', 'financial', 'fire', 'firestone', 'firmdale', 'fish', 'fishing', 'fit', 'fitness', 'fj', 'fk', 'flickr', 'flights', 'flir', 'florist', 'flowers', 'fly', 'fm', 'fo', 'foo', 'food', 'foodnetwork', 'football', 'ford', 'forex', 'forsale', 'forum', 'foundation', 'fox', 'fr', 'free', 'fresenius', 'frl', 'frogans', 'frontdoor', 'frontier', 'ftr', 'fujitsu', 'fujixerox', 'fun', 'fund', 'furniture', 'futbol', 'fyi', 'ga', 'gal', 'gallery', 'gallo', 'gallup', 'game', 'games', 'gap', 'garden', 'gay', 'gb', 'gbiz', 'gd', 'gdn', 'ge', 'gea', 'gent', 'genting', 'george', 'gf', 'gg', 'ggee', 'gh', 'gi', 'gift', 'gifts', 'gives', 'giving', 'gl', 'glade', 'glass', 'gle', 'global', 'globo', 'gm', 'gmail', 'gmbh', 'gmo', 'gmx', 'gn', 'godaddy', 'gold', 'goldpoint', 'golf', 'goo', 'goodyear', 'goog', 'google', 'gop', 'got', 'gov', 'gp', 'gq', 'gr', 'grainger', 'graphics', 'gratis', 'green', 'gripe', 'grocery', 'group', 'gs', 'gt', 'gu', 'guardian', 'gucci', 'guge', 'guide', 'guitars', 'guru', 'gw', 'gy', 'hair', 'hamburg', 'hangout', 'haus', 'hbo', 'hdfc', 'hdfcbank', 'health', 'healthcare', 'help', 'helsinki', 'here', 'hermes', 'hgtv', 'hiphop', 'hisamitsu', 'hitachi', 'hiv', 'hk', 'hkt', 'hm', 'hn', 'hockey', 'holdings', 'holiday', 'homedepot', 'homegoods', 'homes', 'homesense', 'honda', 'horse', 'hospital', 'host', 'hosting', 'hot', 'hoteles', 'hotels', 'hotmail', 'house', 'how', 'hr', 'hsbc', 'ht', 'hu', 'hughes', 'hyatt', 'hyundai', 'ibm', 'icbc', 'ice', 'icu', 'id', 'ie', 'ieee', 'ifm', 'ikano', 'il', 'im', 'imamat', 'imdb', 'immo', 'immobilien', 'in', 'inc', 'industries', 'infiniti', 'info', 'ing', 'ink', 'institute', 'insurance', 'insure', 'int', 'intel', 'international', 'intuit', 'investments', 'io', 'ipiranga', 'iq', 'ir', 'irish', 'is', 'ismaili', 'ist', 'istanbul', 'it', 'itau', 'itv', 'iveco', 'jaguar', 'java', 'jcb', 'jcp', 'je', 'jeep', 'jetzt', 'jewelry', 'jio', 'jll', 'jm', 'jmp', 'jnj', 'jo', 'jobs', 'joburg', 'jot', 'joy', 'jp', 'jpmorgan', 'jprs', 'juegos', 'juniper', 'kaufen', 'kddi', 'ke', 'kerryhotels', 'kerrylogistics', 'kerryproperties', 'kfh', 'kg', 'kh', 'ki', 'kia', 'kim', 'kinder', 'kindle', 'kitchen', 'kiwi', 'km', 'kn', 'koeln', 'komatsu', 'kosher', 'kp', 'kpmg', 'kpn', 'kr', 'krd', 'kred', 'kuokgroup', 'kw', 'ky', 'kyoto', 'kz', 'la', 'lacaixa', 'lamborghini', 'lamer', 'lancaster', 'lancia', 'land', 'landrover', 'lanxess', 'lasalle', 'lat', 'latino', 'latrobe', 'law', 'lawyer', 'lb', 'lc', 'lds', 'lease', 'leclerc', 'lefrak', 'legal', 'lego', 'lexus', 'lgbt', 'li', 'liaison', 'lidl', 'life', 'lifeinsurance', 'lifestyle', 'lighting', 'like', 'lilly', 'limited', 'limo', 'lincoln', 'linde', 'link', 'lipsy', 'live', 'living', 'lixil', 'lk', 'llc', 'llp', 'loan', 'loans', 'locker', 'locus', 'loft', 'lol', 'london', 'lotte', 'lotto', 'love', 'lpl', 'lplfinancial', 'lr', 'ls', 'lt', 'ltd', 'ltda', 'lu', 'lundbeck', 'lupin', 'luxe', 'luxury', 'lv', 'ly', 'ma', 'macys', 'madrid', 'maif', 'maison', 'makeup', 'man', 'management', 'mango', 'map', 'market', 'marketing', 'markets', 'marriott', 'marshalls', 'maserati', 'mattel', 'mba', 'mc', 'mckinsey', 'md', 'me', 'med', 'media', 'meet', 'melbourne', 'meme', 'memorial', 'men', 'menu', 'merckmsd', 'metlife', 'mg', 'mh', 'miami', 'microsoft', 'mil', 'mini', 'mint', 'mit', 'mitsubishi', 'mk', 'ml', 'mlb', 'mls', 'mm', 'mma', 'mn', 'mo', 'mobi', 'mobile', 'moda', 'moe', 'moi', 'mom', 'monash', 'money', 'monster', 'mormon', 'mortgage', 'moscow', 'moto', 'motorcycles', 'mov', 'movie', 'mp', 'mq', 'mr', 'ms', 'msd', 'mt', 'mtn', 'mtr', 'mu', 'museum', 'mutual', 'mv', 'mw', 'mx', 'my', 'mz', 'na', 'nab', 'nadex', 'nagoya', 'name', 'nationwide', 'natura', 'navy', 'nba', 'nc', 'ne', 'nec', 'net', 'netbank', 'netflix', 'network', 'neustar', 'new', 'newholland', 'news', 'next', 'nextdirect', 'nexus', 'nf', 'nfl', 'ng', 'ngo', 'nhk', 'ni', 'nico', 'nike', 'nikon', 'ninja', 'nissan', 'nissay', 'nl', 'no', 'nokia', 'northwesternmutual', 'norton', 'now', 'nowruz', 'nowtv', 'np', 'nr', 'nra', 'nrw', 'ntt', 'nu', 'nyc', 'nz', 'obi', 'observer', 'off', 'office', 'okinawa', 'olayan', 'olayangroup', 'oldnavy', 'ollo', 'om', 'omega', 'one', 'ong', 'onl', 'online', 'onyourside', 'ooo', 'open', 'oracle', 'orange', 'org', 'organic', 'origins', 'osaka', 'otsuka', 'ott', 'ovh', 'pa', 'page', 'panasonic', 'paris', 'pars', 'partners', 'parts', 'party', 'passagens', 'pay', 'pccw', 'pe', 'pet', 'pf', 'pfizer', 'pg', 'ph', 'pharmacy', 'phd', 'philips', 'phone', 'photo', 'photography', 'photos', 'physio', 'pics', 'pictet', 'pictures', 'pid', 'pin', 'ping', 'pink', 'pioneer', 'pizza', 'pk', 'pl', 'place', 'play', 'playstation', 'plumbing', 'plus', 'pm', 'pn', 'pnc', 'pohl', 'poker', 'politie', 'porn', 'post', 'pr', 'pramerica', 'praxi', 'press', 'prime', 'pro', 'prod', 'productions', 'prof', 'progressive', 'promo', 'properties', 'property', 'protection', 'pru', 'prudential', 'ps', 'pt', 'pub', 'pw', 'pwc', 'py', 'qa', 'qpon', 'quebec', 'quest', 'qvc', 'racing', 'radio', 'raid', 're', 'read', 'realestate', 'realtor', 'realty', 'recipes', 'red', 'redstone', 'redumbrella', 'rehab', 'reise', 'reisen', 'reit', 'reliance', 'ren', 'rent', 'rentals', 'repair', 'report', 'republican', 'rest', 'restaurant', 'review', 'reviews', 'rexroth', 'rich', 'richardli', 'ricoh', 'rightathome', 'ril', 'rio', 'rip', 'rmit', 'ro', 'rocher', 'rocks', 'rodeo', 'rogers', 'room', 'rs', 'rsvp', 'ru', 'rugby', 'ruhr', 'run', 'rw', 'rwe', 'ryukyu', 'sa', 'saarland', 'safe', 'safety', 'sakura', 'sale', 'salon', 'samsclub', 'samsung', 'sandvik', 'sandvikcoromant', 'sanofi', 'sap', 'sarl', 'sas', 'save', 'saxo', 'sb', 'sbi', 'sbs', 'sc', 'sca', 'scb', 'schaeffler', 'schmidt', 'scholarships', 'school', 'schule', 'schwarz', 'science', 'scjohnson', 'scor', 'scot', 'sd', 'se', 'search', 'seat', 'secure', 'security', 'seek', 'select', 'sener', 'services', 'ses', 'seven', 'sew', 'sex', 'sexy', 'sfr', 'sg', 'sh', 'shangrila', 'sharp', 'shaw', 'shell', 'shia', 'shiksha', 'shoes', 'shop', 'shopping', 'shouji', 'show', 'showtime', 'shriram', 'si', 'silk', 'sina', 'singles', 'site', 'sj', 'sk', 'ski', 'skin', 'sky', 'skype', 'sl', 'sling', 'sm', 'smart', 'smile', 'sn', 'sncf', 'so', 'soccer', 'social', 'softbank', 'software', 'sohu', 'solar', 'solutions', 'song', 'sony', 'soy', 'space', 'sport', 'spot', 'spreadbetting', 'sr', 'srl', 'ss', 'st', 'stada', 'staples', 'star', 'statebank', 'statefarm', 'stc', 'stcgroup', 'stockholm', 'storage', 'store', 'stream', 'studio', 'study', 'style', 'su', 'sucks', 'supplies', 'supply', 'support', 'surf', 'surgery', 'suzuki', 'sv', 'swatch', 'swiftcover', 'swiss', 'sx', 'sy', 'sydney', 'symantec', 'systems', 'sz', 'tab', 'taipei', 'talk', 'taobao', 'target', 'tatamotors', 'tatar', 'tattoo', 'tax', 'taxi', 'tc', 'tci', 'td', 'tdk', 'team', 'tech', 'technology', 'tel', 'temasek', 'tennis', 'teva', 'tf', 'tg', 'th', 'thd', 'theater', 'theatre', 'tiaa', 'tickets', 'tienda', 'tiffany', 'tips', 'tires', 'tirol', 'tj', 'tjmaxx', 'tjx', 'tk', 'tkmaxx', 'tl', 'tm', 'tmall', 'tn', 'to', 'today', 'tokyo', 'tools', 'top', 'toray', 'toshiba', 'total', 'tours', 'town', 'toyota', 'toys', 'tr', 'trade', 'trading', 'training', 'travel', 'travelchannel', 'travelers', 'travelersinsurance', 'trust', 'trv', 'tt', 'tube', 'tui', 'tunes', 'tushu', 'tv', 'tvs', 'tw', 'tz', 'ua', 'ubank', 'ubs', 'ug', 'uk', 'unicom', 'university', 'uno', 'uol', 'ups', 'us', 'uy', 'uz', 'va', 'vacations', 'vana', 'vanguard', 'vc', 've', 'vegas', 'ventures', 'verisign', 'versicherung', 'vet', 'vg', 'vi', 'viajes', 'video', 'vig', 'viking', 'villas', 'vin', 'vip', 'virgin', 'visa', 'vision', 'vistaprint', 'viva', 'vivo', 'vlaanderen', 'vn', 'vodka', 'volkswagen', 'volvo', 'vote', 'voting', 'voto', 'voyage', 'vu', 'vuelos', 'wales', 'walmart', 'walter', 'wang', 'wanggou', 'watch', 'watches', 'weather', 'weatherchannel', 'webcam', 'weber', 'website', 'wed', 'wedding', 'weibo', 'weir', 'wf', 'whoswho', 'wien', 'wiki', 'williamhill', 'win', 'windows', 'wine', 'winners', 'wme', 'wolterskluwer', 'woodside', 'work', 'works', 'world', 'wow', 'ws', 'wtc', 'wtf', 'xbox', 'xerox', 'xfinity', 'xihuan', 'xin', 'कॉम', 'セール', '佛山', 'ಭಾರತ', '慈善', '集团', '在线', '한국', 'ଭାରତ', '大众汽车', '点看', 'คอม', 'ভাৰত', 'ভারত', '八卦', 'موقع', 'বাংলা', '公益', '公司', '香格里拉', '网站', '移动', '我爱你', 'москва', 'қаз', 'католик', 'онлайн', 'сайт', '联通', 'срб', 'бг', 'бел', 'קום', '时尚', '微博', '淡马锡', 'ファッション', 'орг', 'नेट', 'ストア', '삼성', 'சிங்கப்பூர்', '商标', '商店', '商城', 'дети', 'мкд', 'ею', 'ポイント', '新闻', '工行', '家電', 'كوم', '中文网', '中信', '中国', '中國', '娱乐', '谷歌', 'భారత్', 'ලංකා', '電訊盈科', '购物', 'クラウド', 'ભારત', '通販', 'भारतम्', 'भारत', 'भारोत', '网店', 'संगठन', '餐厅', '网络', 'ком', 'укр', '香港', '诺基亚', '食品', '飞利浦', '台湾', '台灣', '手表', '手机', 'мон', 'الجزائر', 'عمان', 'ارامكو', 'ایران', 'العليان', 'اتصالات', 'امارات', 'بازار', 'موريتانيا', 'پاکستان', 'الاردن', 'بارت', 'بھارت', 'المغرب', 'ابوظبي', 'السعودية', 'ڀارت', 'كاثوليك', 'سودان', 'همراه', 'عراق', 'مليسيا', '澳門', '닷컴', '政府', 'شبكة', 'بيتك', 'عرب', 'გე', '机构', '组织机构', '健康', 'ไทย', 'سورية', '招聘', 'рус', 'рф', '珠宝', 'تونس', '大拿', 'みんな', 'グーグル', 'ευ', 'ελ', '世界', '書籍', 'ഭാരതം', 'ਭਾਰਤ', '网址', '닷넷', 'コム', '天主教', '游戏', 'vermögensberater', 'vermögensberatung', '企业', '信息', '嘉里大酒店', '嘉里', 'مصر', 'قطر', '广东', 'இலங்கை', 'இந்தியா', 'հայ', '新加坡', 'فلسطين', '政务', 'xxx', 'xyz', 'yachts', 'yahoo', 'yamaxun', 'yandex', 'ye', 'yodobashi', 'yoga', 'yokohama', 'you', 'youtube', 'yt', 'yun', 'za', 'zappos', 'zara', 'zero', 'zip', 'zm', 'zone', 'zuerich', 'zw', ]; // @codingStandardsIgnoreStart /** * Array for valid Idns * @see http://www.iana.org/domains/idn-tables/ Official list of supported IDN Chars * (.AC) Ascension Island http://www.nic.ac/pdf/AC-IDN-Policy.pdf * (.AR) Argentina http://www.nic.ar/faqidn.html * (.AS) American Samoa http://www.nic.as/idn/chars.cfm * (.AT) Austria http://www.nic.at/en/service/technical_information/idn/charset_converter/ * (.BIZ) International http://www.iana.org/domains/idn-tables/ * (.BR) Brazil http://registro.br/faq/faq6.html * (.BV) Bouvett Island http://www.norid.no/domeneregistrering/idn/idn_nyetegn.en.html * (.CAT) Catalan http://www.iana.org/domains/idn-tables/tables/cat_ca_1.0.html * (.CH) Switzerland https://nic.switch.ch/reg/ocView.action?res=EF6GW2JBPVTG67DLNIQXU234MN6SC33JNQQGI7L6#anhang1 * (.CL) Chile http://www.iana.org/domains/idn-tables/tables/cl_latn_1.0.html * (.COM) International http://www.verisign.com/information-services/naming-services/internationalized-domain-names/index.html * (.DE) Germany https://www.denic.de/en/know-how/idn-domains/idn-character-list/ * (.DK) Danmark http://www.dk-hostmaster.dk/index.php?id=151 * (.EE) Estonia https://www.iana.org/domains/idn-tables/tables/pl_et-pl_1.0.html * (.ES) Spain https://www.nic.es/media/2008-05/1210147705287.pdf * (.FI) Finland http://www.ficora.fi/en/index/palvelut/fiverkkotunnukset/aakkostenkaytto.html * (.GR) Greece https://grweb.ics.forth.gr/CharacterTable1_en.jsp * (.HR) Croatia https://www.dns.hr/en/portal/files/Odluka-1,2alfanum-dijak.pdf * (.HU) Hungary http://www.domain.hu/domain/English/szabalyzat/szabalyzat.html * (.IL) Israel http://www.isoc.org.il/domains/il-domain-rules.html * (.INFO) International http://www.nic.info/info/idn * (.IO) British Indian Ocean Territory http://www.nic.io/IO-IDN-Policy.pdf * (.IR) Iran http://www.nic.ir/Allowable_Characters_dot-iran * (.IS) Iceland https://www.isnic.is/en/domain/rules#2 * (.KR) Korea http://www.iana.org/domains/idn-tables/tables/kr_ko-kr_1.0.html * (.LI) Liechtenstein https://nic.switch.ch/reg/ocView.action?res=EF6GW2JBPVTG67DLNIQXU234MN6SC33JNQQGI7L6#anhang1 * (.LT) Lithuania http://www.domreg.lt/static/doc/public/idn_symbols-en.pdf * (.MD) Moldova http://www.register.md/ * (.MUSEUM) International http://www.iana.org/domains/idn-tables/tables/museum_latn_1.0.html * (.NET) International http://www.verisign.com/information-services/naming-services/internationalized-domain-names/index.html * (.NO) Norway http://www.norid.no/domeneregistrering/idn/idn_nyetegn.en.html * (.NU) Niue http://www.worldnames.net/ * (.ORG) International http://www.pir.org/index.php?db=content/FAQs&tbl=FAQs_Registrant&id=2 * (.PE) Peru https://www.nic.pe/nuevas_politicas_faq_2.php * (.PL) Poland http://www.dns.pl/IDN/allowed_character_sets.pdf * (.PR) Puerto Rico http://www.nic.pr/idn_rules.asp * (.PT) Portugal https://online.dns.pt/dns_2008/do?com=DS;8216320233;111;+PAGE(4000058)+K-CAT-CODIGO(C.125)+RCNT(100); * (.RU) Russia http://www.iana.org/domains/idn-tables/tables/ru_ru-ru_1.0.html * (.SA) Saudi Arabia http://www.iana.org/domains/idn-tables/tables/sa_ar_1.0.html * (.SE) Sweden http://www.iis.se/english/IDN_campaignsite.shtml?lang=en * (.SH) Saint Helena http://www.nic.sh/SH-IDN-Policy.pdf * (.SJ) Svalbard and Jan Mayen http://www.norid.no/domeneregistrering/idn/idn_nyetegn.en.html * (.TH) Thailand http://www.iana.org/domains/idn-tables/tables/th_th-th_1.0.html * (.TM) Turkmenistan http://www.nic.tm/TM-IDN-Policy.pdf * (.TR) Turkey https://www.nic.tr/index.php * (.UA) Ukraine http://www.iana.org/domains/idn-tables/tables/ua_cyrl_1.2.html * (.VE) Venice http://www.iana.org/domains/idn-tables/tables/ve_es_1.0.html * (.VN) Vietnam http://www.vnnic.vn/english/5-6-300-2-2-04-20071115.htm#1.%20Introduction * * @var array */ protected $validIdns = [ 'AC' => [1 => '/^[\x{002d}0-9a-zà-öø-ÿāăąćĉċčďđēėęěĝġģĥħīįĵķĺļľŀłńņňŋőœŕŗřśŝşšţťŧūŭůűųŵŷźżž]{1,63}$/iu'], 'AR' => [1 => '/^[\x{002d}0-9a-zà-ãç-êìíñ-õü]{1,63}$/iu'], 'AS' => [1 => '/^[\x{002d}0-9a-zà-öø-ÿāăąćĉċčďđēĕėęěĝğġģĥħĩīĭįıĵķĸĺļľłńņňŋōŏőœŕŗřśŝşšţťŧũūŭůűųŵŷźż]{1,63}$/iu'], 'AT' => [1 => '/^[\x{002d}0-9a-zà-öø-ÿœšž]{1,63}$/iu'], 'BIZ' => 'Hostname/Biz.php', 'BR' => [1 => '/^[\x{002d}0-9a-zà-ãçéíó-õúü]{1,63}$/iu'], 'BV' => [1 => '/^[\x{002d}0-9a-zàáä-éêñ-ôöøüčđńŋšŧž]{1,63}$/iu'], 'CAT' => [1 => '/^[\x{002d}0-9a-z·àç-éíïòóúü]{1,63}$/iu'], 'CH' => [1 => '/^[\x{002d}0-9a-zà-öø-ÿœ]{1,63}$/iu'], 'CL' => [1 => '/^[\x{002d}0-9a-záéíñóúü]{1,63}$/iu'], 'CN' => 'Hostname/Cn.php', 'COM' => 'Hostname/Com.php', 'DE' => [1 => '/^[\x{002d}0-9a-záàăâåäãąāæćĉčċçďđéèĕêěëėęēğĝġģĥħíìĭîïĩįīıĵķĺľļłńňñņŋóòŏôöőõøōœĸŕřŗśŝšşßťţŧúùŭûůüűũųūŵýŷÿźžżðþ]{1,63}$/iu'], 'DK' => [1 => '/^[\x{002d}0-9a-zäåæéöøü]{1,63}$/iu'], 'EE' => [1 => '/^[\x{002d}0-9a-zäõöüšž]{1,63}$/iu'], 'ES' => [1 => '/^[\x{002d}0-9a-zàáçèéíïñòóúü·]{1,63}$/iu'], 'EU' => [1 => '/^[\x{002d}0-9a-zà-öø-ÿ]{1,63}$/iu', 2 => '/^[\x{002d}0-9a-zāăąćĉċčďđēĕėęěĝğġģĥħĩīĭįıĵķĺļľŀłńņňʼnŋōŏőœŕŗřśŝšťŧũūŭůűųŵŷźżž]{1,63}$/iu', 3 => '/^[\x{002d}0-9a-zșț]{1,63}$/iu', 4 => '/^[\x{002d}0-9a-zΐάέήίΰαβγδεζηθικλμνξοπρςστυφχψωϊϋόύώ]{1,63}$/iu', 5 => '/^[\x{002d}0-9a-zабвгдежзийклмнопрстуфхцчшщъыьэюя]{1,63}$/iu', 6 => '/^[\x{002d}0-9a-zἀ-ἇἐ-ἕἠ-ἧἰ-ἷὀ-ὅὐ-ὗὠ-ὧὰ-ὼώᾀ-ᾇᾐ-ᾗᾠ-ᾧᾰ-ᾴᾶᾷῂῃῄῆῇῐ-ῒΐῖῗῠ-ῧῲῳῴῶῷ]{1,63}$/iu'], 'FI' => [1 => '/^[\x{002d}0-9a-zäåö]{1,63}$/iu'], 'GR' => [1 => '/^[\x{002d}0-9a-zΆΈΉΊΌΎ-ΡΣ-ώἀ-ἕἘ-Ἕἠ-ὅὈ-Ὅὐ-ὗὙὛὝὟ-ώᾀ-ᾴᾶ-ᾼῂῃῄῆ-ῌῐ-ΐῖ-Ίῠ-Ῥῲῳῴῶ-ῼ]{1,63}$/iu'], 'HK' => 'Hostname/Cn.php', 'HR' => [1 => '/^[\x{002d}0-9a-zžćčđš]{1,63}$/iu'], 'HU' => [1 => '/^[\x{002d}0-9a-záéíóöúüőű]{1,63}$/iu'], 'IL' => [1 => '/^[\x{002d}0-9\x{05D0}-\x{05EA}]{1,63}$/iu', 2 => '/^[\x{002d}0-9a-z]{1,63}$/i'], 'INFO' => [1 => '/^[\x{002d}0-9a-zäåæéöøü]{1,63}$/iu', 2 => '/^[\x{002d}0-9a-záéíóöúüőű]{1,63}$/iu', 3 => '/^[\x{002d}0-9a-záæéíðóöúýþ]{1,63}$/iu', 4 => '/^[\x{AC00}-\x{D7A3}]{1,17}$/iu', 5 => '/^[\x{002d}0-9a-zāčēģīķļņōŗšūž]{1,63}$/iu', 6 => '/^[\x{002d}0-9a-ząčėęįšūųž]{1,63}$/iu', 7 => '/^[\x{002d}0-9a-zóąćęłńśźż]{1,63}$/iu', 8 => '/^[\x{002d}0-9a-záéíñóúü]{1,63}$/iu'], 'IO' => [1 => '/^[\x{002d}0-9a-zà-öø-ÿăąāćĉčċďđĕěėęēğĝġģĥħĭĩįīıĵķĺľļłńňņŋŏőōœĸŕřŗśŝšşťţŧŭůűũųūŵŷźžż]{1,63}$/iu'], 'IS' => [1 => '/^[\x{002d}0-9a-záéýúíóþæöð]{1,63}$/iu'], 'IT' => [1 => '/^[\x{002d}0-9a-zàâäèéêëìîïòôöùûüæœçÿß-]{1,63}$/iu'], 'JP' => 'Hostname/Jp.php', 'KR' => [1 => '/^[\x{AC00}-\x{D7A3}]{1,17}$/iu'], 'LI' => [1 => '/^[\x{002d}0-9a-zà-öø-ÿœ]{1,63}$/iu'], 'LT' => [1 => '/^[\x{002d}0-9ąčęėįšųūž]{1,63}$/iu'], 'MD' => [1 => '/^[\x{002d}0-9ăâîşţ]{1,63}$/iu'], 'MUSEUM' => [1 => '/^[\x{002d}0-9a-zà-öø-ÿāăąćċčďđēėęěğġģħīįıķĺļľłńņňŋōőœŕŗřśşšţťŧūůűųŵŷźżžǎǐǒǔ\x{01E5}\x{01E7}\x{01E9}\x{01EF}ə\x{0292}ẁẃẅỳ]{1,63}$/iu'], 'NET' => 'Hostname/Com.php', 'NO' => [1 => '/^[\x{002d}0-9a-zàáä-éêñ-ôöøüčđńŋšŧž]{1,63}$/iu'], 'NU' => 'Hostname/Com.php', 'ORG' => [1 => '/^[\x{002d}0-9a-záéíñóúü]{1,63}$/iu', 2 => '/^[\x{002d}0-9a-zóąćęłńśźż]{1,63}$/iu', 3 => '/^[\x{002d}0-9a-záäåæéëíðóöøúüýþ]{1,63}$/iu', 4 => '/^[\x{002d}0-9a-záéíóöúüőű]{1,63}$/iu', 5 => '/^[\x{002d}0-9a-ząčėęįšūųž]{1,63}$/iu', 6 => '/^[\x{AC00}-\x{D7A3}]{1,17}$/iu', 7 => '/^[\x{002d}0-9a-zāčēģīķļņōŗšūž]{1,63}$/iu'], 'PE' => [1 => '/^[\x{002d}0-9a-zñáéíóúü]{1,63}$/iu'], 'PL' => [1 => '/^[\x{002d}0-9a-zāčēģīķļņōŗšūž]{1,63}$/iu', 2 => '/^[\x{002d}а-ик-ш\x{0450}ѓѕјљњќџ]{1,63}$/iu', 3 => '/^[\x{002d}0-9a-zâîăşţ]{1,63}$/iu', 4 => '/^[\x{002d}0-9а-яё\x{04C2}]{1,63}$/iu', 5 => '/^[\x{002d}0-9a-zàáâèéêìíîòóôùúûċġħż]{1,63}$/iu', 6 => '/^[\x{002d}0-9a-zàäåæéêòóôöøü]{1,63}$/iu', 7 => '/^[\x{002d}0-9a-zóąćęłńśźż]{1,63}$/iu', 8 => '/^[\x{002d}0-9a-zàáâãçéêíòóôõúü]{1,63}$/iu', 9 => '/^[\x{002d}0-9a-zâîăşţ]{1,63}$/iu', 10 => '/^[\x{002d}0-9a-záäéíóôúýčďĺľňŕšťž]{1,63}$/iu', 11 => '/^[\x{002d}0-9a-zçë]{1,63}$/iu', 12 => '/^[\x{002d}0-9а-ик-шђјљњћџ]{1,63}$/iu', 13 => '/^[\x{002d}0-9a-zćčđšž]{1,63}$/iu', 14 => '/^[\x{002d}0-9a-zâçöûüğış]{1,63}$/iu', 15 => '/^[\x{002d}0-9a-záéíñóúü]{1,63}$/iu', 16 => '/^[\x{002d}0-9a-zäõöüšž]{1,63}$/iu', 17 => '/^[\x{002d}0-9a-zĉĝĥĵŝŭ]{1,63}$/iu', 18 => '/^[\x{002d}0-9a-zâäéëîô]{1,63}$/iu', 19 => '/^[\x{002d}0-9a-zàáâäåæçèéêëìíîïðñòôöøùúûüýćčłńřśš]{1,63}$/iu', 20 => '/^[\x{002d}0-9a-zäåæõöøüšž]{1,63}$/iu', 21 => '/^[\x{002d}0-9a-zàáçèéìíòóùú]{1,63}$/iu', 22 => '/^[\x{002d}0-9a-zàáéíóöúüőű]{1,63}$/iu', 23 => '/^[\x{002d}0-9ΐά-ώ]{1,63}$/iu', 24 => '/^[\x{002d}0-9a-zàáâåæçèéêëðóôöøüþœ]{1,63}$/iu', 25 => '/^[\x{002d}0-9a-záäéíóöúüýčďěňřšťůž]{1,63}$/iu', 26 => '/^[\x{002d}0-9a-z·àçèéíïòóúü]{1,63}$/iu', 27 => '/^[\x{002d}0-9а-ъьюя\x{0450}\x{045D}]{1,63}$/iu', 28 => '/^[\x{002d}0-9а-яёіў]{1,63}$/iu', 29 => '/^[\x{002d}0-9a-ząčėęįšūųž]{1,63}$/iu', 30 => '/^[\x{002d}0-9a-záäåæéëíðóöøúüýþ]{1,63}$/iu', 31 => '/^[\x{002d}0-9a-zàâæçèéêëîïñôùûüÿœ]{1,63}$/iu', 32 => '/^[\x{002d}0-9а-щъыьэюяёєіїґ]{1,63}$/iu', 33 => '/^[\x{002d}0-9א-ת]{1,63}$/iu'], 'PR' => [1 => '/^[\x{002d}0-9a-záéíóúñäëïüöâêîôûàèùæçœãõ]{1,63}$/iu'], 'PT' => [1 => '/^[\x{002d}0-9a-záàâãçéêíóôõú]{1,63}$/iu'], 'RS' => [1 => '/^[\x{002d}0-9a-zßáâäçéëíîóôöúüýăąćčďđęěĺľłńňőŕřśşšţťůűźżž]{1,63}$/iu'], 'RU' => [1 => '/^[\x{002d}0-9а-яё]{1,63}$/iu'], 'SA' => [1 => '/^[\x{002d}.0-9\x{0621}-\x{063A}\x{0641}-\x{064A}\x{0660}-\x{0669}]{1,63}$/iu'], 'SE' => [1 => '/^[\x{002d}0-9a-zäåéöü]{1,63}$/iu'], 'SH' => [1 => '/^[\x{002d}0-9a-zà-öø-ÿăąāćĉčċďđĕěėęēğĝġģĥħĭĩįīıĵķĺľļłńňņŋŏőōœĸŕřŗśŝšşťţŧŭůűũųūŵŷźžż]{1,63}$/iu'], 'SI' => [ 1 => '/^[\x{002d}0-9a-zà-öø-ÿ]{1,63}$/iu', 2 => '/^[\x{002d}0-9a-zāăąćĉċčďđēĕėęěĝğġģĥħĩīĭįıĵķĺļľŀłńņňʼnŋōŏőœŕŗřśŝšťŧũūŭůűųŵŷźżž]{1,63}$/iu', 3 => '/^[\x{002d}0-9a-zșț]{1,63}$/iu'], 'SJ' => [1 => '/^[\x{002d}0-9a-zàáä-éêñ-ôöøüčđńŋšŧž]{1,63}$/iu'], 'TH' => [1 => '/^[\x{002d}0-9a-z\x{0E01}-\x{0E3A}\x{0E40}-\x{0E4D}\x{0E50}-\x{0E59}]{1,63}$/iu'], 'TM' => [1 => '/^[\x{002d}0-9a-zà-öø-ÿāăąćĉċčďđēėęěĝġģĥħīįĵķĺļľŀłńņňŋőœŕŗřśŝşšţťŧūŭůűųŵŷźżž]{1,63}$/iu'], 'TW' => 'Hostname/Cn.php', 'TR' => [1 => '/^[\x{002d}0-9a-zğıüşöç]{1,63}$/iu'], 'UA' => [1 => '/^[\x{002d}0-9a-zабвгдежзийклмнопрстуфхцчшщъыьэюяѐёђѓєѕіїјљњћќѝўџґӂʼ]{1,63}$/iu'], 'VE' => [1 => '/^[\x{002d}0-9a-záéíóúüñ]{1,63}$/iu'], 'VN' => [1 => '/^[ÀÁÂÃÈÉÊÌÍÒÓÔÕÙÚÝàáâãèéêìíòóôõùúýĂăĐđĨĩŨũƠơƯư\x{1EA0}-\x{1EF9}]{1,63}$/iu'], 'мон' => [1 => '/^[\x{002d}0-9\x{0430}-\x{044F}]{1,63}$/iu'], 'срб' => [1 => '/^[\x{002d}0-9а-ик-шђјљњћџ]{1,63}$/iu'], 'сайт' => [1 => '/^[\x{002d}0-9а-яёіїѝйўґг]{1,63}$/iu'], 'онлайн' => [1 => '/^[\x{002d}0-9а-яёіїѝйўґг]{1,63}$/iu'], '中国' => 'Hostname/Cn.php', '中國' => 'Hostname/Cn.php', 'ලංකා' => [1 => '/^[\x{0d80}-\x{0dff}]{1,63}$/iu'], '香港' => 'Hostname/Cn.php', '台湾' => 'Hostname/Cn.php', '台灣' => 'Hostname/Cn.php', 'امارات' => [1 => '/^[\x{0621}-\x{0624}\x{0626}-\x{063A}\x{0641}\x{0642}\x{0644}-\x{0648}\x{067E}\x{0686}\x{0698}\x{06A9}\x{06AF}\x{06CC}\x{06F0}-\x{06F9}]{1,30}$/iu'], 'الاردن' => [1 => '/^[\x{0621}-\x{0624}\x{0626}-\x{063A}\x{0641}\x{0642}\x{0644}-\x{0648}\x{067E}\x{0686}\x{0698}\x{06A9}\x{06AF}\x{06CC}\x{06F0}-\x{06F9}]{1,30}$/iu'], 'السعودية' => [1 => '/^[\x{0621}-\x{0624}\x{0626}-\x{063A}\x{0641}\x{0642}\x{0644}-\x{0648}\x{067E}\x{0686}\x{0698}\x{06A9}\x{06AF}\x{06CC}\x{06F0}-\x{06F9}]{1,30}$/iu'], 'ไทย' => [1 => '/^[\x{002d}0-9a-z\x{0E01}-\x{0E3A}\x{0E40}-\x{0E4D}\x{0E50}-\x{0E59}]{1,63}$/iu'], 'рф' => [1 => '/^[\x{002d}0-9а-яё]{1,63}$/iu'], 'تونس' => [1 => '/^[\x{0621}-\x{0624}\x{0626}-\x{063A}\x{0641}\x{0642}\x{0644}-\x{0648}\x{067E}\x{0686}\x{0698}\x{06A9}\x{06AF}\x{06CC}\x{06F0}-\x{06F9}]{1,30}$/iu'], 'مصر' => [1 => '/^[\x{0621}-\x{0624}\x{0626}-\x{063A}\x{0641}\x{0642}\x{0644}-\x{0648}\x{067E}\x{0686}\x{0698}\x{06A9}\x{06AF}\x{06CC}\x{06F0}-\x{06F9}]{1,30}$/iu'], 'இலங்கை' => [1 => '/^[\x{0b80}-\x{0bff}]{1,63}$/iu'], 'فلسطين' => [1 => '/^[\x{0621}-\x{0624}\x{0626}-\x{063A}\x{0641}\x{0642}\x{0644}-\x{0648}\x{067E}\x{0686}\x{0698}\x{06A9}\x{06AF}\x{06CC}\x{06F0}-\x{06F9}]{1,30}$/iu'], 'شبكة' => [1 => '/^[\x{0621}-\x{0624}\x{0626}-\x{063A}\x{0641}\x{0642}\x{0644}-\x{0648}\x{067E}\x{0686}\x{0698}\x{06A9}\x{06AF}\x{06CC}\x{06F0}-\x{06F9}]{1,30}$/iu'], ]; // @codingStandardsIgnoreEnd protected $idnLength = [ 'BIZ' => [5 => 17, 11 => 15, 12 => 20], 'CN' => [1 => 20], 'COM' => [3 => 17, 5 => 20], 'HK' => [1 => 15], 'INFO' => [4 => 17], 'KR' => [1 => 17], 'NET' => [3 => 17, 5 => 20], 'ORG' => [6 => 17], 'TW' => [1 => 20], 'امارات' => [1 => 30], 'الاردن' => [1 => 30], 'السعودية' => [1 => 30], 'تونس' => [1 => 30], 'مصر' => [1 => 30], 'فلسطين' => [1 => 30], 'شبكة' => [1 => 30], '中国' => [1 => 20], '中國' => [1 => 20], '香港' => [1 => 20], '台湾' => [1 => 20], '台灣' => [1 => 20], ]; protected $tld; /** * Options for the hostname validator * * @var array */ protected $options = [ 'allow' => self::ALLOW_DNS, // Allow these hostnames 'useIdnCheck' => true, // Check IDN domains 'useTldCheck' => true, // Check TLD elements 'ipValidator' => null, // IP validator to use ]; /** * Sets validator options. * * @param int $allow OPTIONAL Set what types of hostname to allow (default ALLOW_DNS) * @param bool $useIdnCheck OPTIONAL Set whether IDN domains are validated (default true) * @param bool $useTldCheck Set whether the TLD element of a hostname is validated (default true) * @param Ip $ipValidator OPTIONAL * @see http://www.iana.org/cctld/specifications-policies-cctlds-01apr02.htm Technical Specifications for ccTLDs */ public function __construct($options = []) { if (! is_array($options)) { $options = func_get_args(); $temp['allow'] = array_shift($options); if (! empty($options)) { $temp['useIdnCheck'] = array_shift($options); } if (! empty($options)) { $temp['useTldCheck'] = array_shift($options); } if (! empty($options)) { $temp['ipValidator'] = array_shift($options); } $options = $temp; } if (! array_key_exists('ipValidator', $options)) { $options['ipValidator'] = null; } parent::__construct($options); } /** * Returns the set ip validator * * @return Ip */ public function getIpValidator() { return $this->options['ipValidator']; } /** * * @param Ip $ipValidator OPTIONAL * @return Hostname; */ public function setIpValidator(Ip $ipValidator = null) { if ($ipValidator === null) { $ipValidator = new Ip(); } $this->options['ipValidator'] = $ipValidator; return $this; } /** * Returns the allow option * * @return int */ public function getAllow() { return $this->options['allow']; } /** * Sets the allow option * * @param int $allow * @return Hostname Provides a fluent interface */ public function setAllow($allow) { $this->options['allow'] = $allow; return $this; } /** * Returns the set idn option * * @return bool */ public function getIdnCheck() { return $this->options['useIdnCheck']; } /** * Set whether IDN domains are validated * * This only applies when DNS hostnames are validated * * @param bool $useIdnCheck Set to true to validate IDN domains * @return Hostname */ public function useIdnCheck($useIdnCheck) { $this->options['useIdnCheck'] = (bool) $useIdnCheck; return $this; } /** * Returns the set tld option * * @return bool */ public function getTldCheck() { return $this->options['useTldCheck']; } /** * Set whether the TLD element of a hostname is validated * * This only applies when DNS hostnames are validated * * @param bool $useTldCheck Set to true to validate TLD elements * @return Hostname */ public function useTldCheck($useTldCheck) { $this->options['useTldCheck'] = (bool) $useTldCheck; return $this; } /** * Defined by Interface * * Returns true if and only if the $value is a valid hostname with respect to the current allow option * * @param string $value * @return bool */ public function isValid($value) { if (! is_string($value)) { $this->error(self::INVALID); return false; } $this->setValue($value); // Check input against IP address schema if (((preg_match('/^[0-9.]*$/', $value) && strpos($value, '.') !== false) || (preg_match('/^[0-9a-f:.]*$/i', $value) && strpos($value, ':') !== false)) && $this->getIpValidator()->setTranslator($this->getTranslator())->isValid($value) ) { if (! ($this->getAllow() & self::ALLOW_IP)) { $this->error(self::IP_ADDRESS_NOT_ALLOWED); return false; } return true; } // Local hostnames are allowed to be partial (ending '.') if ($this->getAllow() & self::ALLOW_LOCAL) { if (substr($value, -1) === '.') { $value = substr($value, 0, -1); if (substr($value, -1) === '.') { // Empty hostnames (ending '..') are not allowed $this->error(self::INVALID_LOCAL_NAME); return false; } } } $domainParts = explode('.', $value); // Prevent partial IP V4 addresses (ending '.') if (count($domainParts) == 4 && preg_match('/^[0-9.a-e:.]*$/i', $value) && $this->getIpValidator()->setTranslator($this->getTranslator())->isValid($value) ) { $this->error(self::INVALID_LOCAL_NAME); } $utf8StrWrapper = StringUtils::getWrapper('UTF-8'); // Check input against DNS hostname schema if (count($domainParts) > 1 && $utf8StrWrapper->strlen($value) >= 4 && $utf8StrWrapper->strlen($value) <= 254 ) { $status = false; do { // First check TLD $matches = []; if (preg_match('/([^.]{2,63})$/u', end($domainParts), $matches) || (array_key_exists(end($domainParts), $this->validIdns)) ) { reset($domainParts); // Hostname characters are: *(label dot)(label dot label); max 254 chars // label: id-prefix [*ldh{61} id-prefix]; max 63 chars // id-prefix: alpha / digit // ldh: alpha / digit / dash $this->tld = $matches[1]; // Decode Punycode TLD to IDN if (strpos($this->tld, 'xn--') === 0) { $this->tld = $this->decodePunycode(substr($this->tld, 4)); if ($this->tld === false) { return false; } } else { $this->tld = strtoupper($this->tld); } // Match TLD against known list $removedTld = false; if ($this->getTldCheck()) { if (! in_array(strtolower($this->tld), $this->validTlds) && ! in_array($this->tld, $this->validTlds)) { $this->error(self::UNKNOWN_TLD); $status = false; break; } // We have already validated that the TLD is fine. We don't want it to go through the below // checks as new UTF-8 TLDs will incorrectly fail if there is no IDN regex for it. array_pop($domainParts); $removedTld = true; } /** * Match against IDN hostnames * Note: Keep label regex short to avoid issues with long patterns when matching IDN hostnames * * @see Hostname\Interface */ $regexChars = [0 => '/^[a-z0-9\x2d]{1,63}$/i']; if ($this->getIdnCheck() && isset($this->validIdns[$this->tld])) { if (is_string($this->validIdns[$this->tld])) { $regexChars += include __DIR__ . '/' . $this->validIdns[$this->tld]; } else { $regexChars += $this->validIdns[$this->tld]; } } // Check each hostname part $check = 0; $lastDomainPart = end($domainParts); if (! $removedTld) { $lastDomainPart = prev($domainParts); } foreach ($domainParts as $domainPart) { // Decode Punycode domain names to IDN if (strpos($domainPart, 'xn--') === 0) { $domainPart = $this->decodePunycode(substr($domainPart, 4)); if ($domainPart === false) { return false; } } // Skip following checks if domain part is empty, as it definitely is not a valid hostname then if ($domainPart === '') { $this->error(self::INVALID_HOSTNAME); $status = false; break 2; } // Check dash (-) does not start, end or appear in 3rd and 4th positions if ($utf8StrWrapper->strpos($domainPart, '-') === 0 || ($utf8StrWrapper->strlen($domainPart) > 2 && $utf8StrWrapper->strpos($domainPart, '-', 2) == 2 && $utf8StrWrapper->strpos($domainPart, '-', 3) == 3 ) || ( $utf8StrWrapper->strpos($domainPart, '-') === ( $utf8StrWrapper->strlen($domainPart) - 1 ) ) ) { $this->error(self::INVALID_DASH); $status = false; break 2; } // Check each domain part $checked = false; $isSubDomain = $domainPart != $lastDomainPart; $partRegexChars = $isSubDomain ? ['/^[a-z0-9_\x2d]{1,63}$/i'] + $regexChars : $regexChars; foreach ($partRegexChars as $regexKey => $regexChar) { $status = preg_match($regexChar, $domainPart); if ($status > 0) { $length = 63; if (array_key_exists($this->tld, $this->idnLength) && array_key_exists($regexKey, $this->idnLength[$this->tld]) ) { $length = $this->idnLength[$this->tld]; } if ($utf8StrWrapper->strlen($domainPart) > $length) { $this->error(self::INVALID_HOSTNAME); $status = false; } else { $checked = true; break; } } } if ($checked) { ++$check; } } // If one of the labels doesn't match, the hostname is invalid if ($check !== count($domainParts)) { $this->error(self::INVALID_HOSTNAME_SCHEMA); $status = false; } } else { // Hostname not long enough $this->error(self::UNDECIPHERABLE_TLD); $status = false; } } while (false); // If the input passes as an Internet domain name, and domain names are allowed, then the hostname // passes validation if ($status && ($this->getAllow() & self::ALLOW_DNS)) { return true; } } elseif ($this->getAllow() & self::ALLOW_DNS) { $this->error(self::INVALID_HOSTNAME); } // Check for URI Syntax (RFC3986) if ($this->getAllow() & self::ALLOW_URI) { if (preg_match("/^([a-zA-Z0-9-._~!$&\'()*+,;=]|%[[:xdigit:]]{2}){1,254}$/i", $value)) { return true; } $this->error(self::INVALID_URI); } // Check input against local network name schema; last chance to pass validation $regexLocal = '/^(([a-zA-Z0-9\x2d]{1,63}\x2e)*[a-zA-Z0-9\x2d]{1,63}[\x2e]{0,1}){1,254}$/'; $status = preg_match($regexLocal, $value); // If the input passes as a local network name, and local network names are allowed, then the // hostname passes validation $allowLocal = $this->getAllow() & self::ALLOW_LOCAL; if ($status && $allowLocal) { return true; } // If the input does not pass as a local network name, add a message if (! $status) { $this->error(self::INVALID_LOCAL_NAME); } // If local network names are not allowed, add a message if ($status && ! $allowLocal) { $this->error(self::LOCAL_NAME_NOT_ALLOWED); } return false; } /** * Decodes a punycode encoded string to it's original utf8 string * Returns false in case of a decoding failure. * * @param string $encoded Punycode encoded string to decode * @return string|false */ protected function decodePunycode($encoded) { if (! preg_match('/^[a-z0-9-]+$/i', $encoded)) { // no punycode encoded string $this->error(self::CANNOT_DECODE_PUNYCODE); return false; } $decoded = []; $separator = strrpos($encoded, '-'); if ($separator > 0) { for ($x = 0; $x < $separator; ++$x) { // prepare decoding matrix $decoded[] = ord($encoded[$x]); } } $lengthd = count($decoded); $lengthe = strlen($encoded); // decoding $init = true; $base = 72; $index = 0; $char = 0x80; for ($indexe = ($separator) ? ($separator + 1) : 0; $indexe < $lengthe; ++$lengthd) { for ($oldIndex = $index, $pos = 1, $key = 36; 1; $key += 36) { $hex = ord($encoded[$indexe++]); $digit = ($hex - 48 < 10) ? $hex - 22 : (($hex - 65 < 26) ? $hex - 65 : (($hex - 97 < 26) ? $hex - 97 : 36)); $index += $digit * $pos; $tag = ($key <= $base) ? 1 : (($key >= $base + 26) ? 26 : ($key - $base)); if ($digit < $tag) { break; } $pos = (int) ($pos * (36 - $tag)); } $delta = intval($init ? (($index - $oldIndex) / 700) : (($index - $oldIndex) / 2)); $delta += intval($delta / ($lengthd + 1)); for ($key = 0; $delta > 910 / 2; $key += 36) { $delta = intval($delta / 35); } $base = intval($key + 36 * $delta / ($delta + 38)); $init = false; $char += (int) ($index / ($lengthd + 1)); $index %= ($lengthd + 1); if ($lengthd > 0) { for ($i = $lengthd; $i > $index; $i--) { $decoded[$i] = $decoded[($i - 1)]; } } $decoded[$index++] = $char; } // convert decoded ucs4 to utf8 string foreach ($decoded as $key => $value) { if ($value < 128) { $decoded[$key] = chr($value); } elseif ($value < (1 << 11)) { $decoded[$key] = chr(192 + ($value >> 6)); $decoded[$key] .= chr(128 + ($value & 63)); } elseif ($value < (1 << 16)) { $decoded[$key] = chr(224 + ($value >> 12)); $decoded[$key] .= chr(128 + (($value >> 6) & 63)); $decoded[$key] .= chr(128 + ($value & 63)); } elseif ($value < (1 << 21)) { $decoded[$key] = chr(240 + ($value >> 18)); $decoded[$key] .= chr(128 + (($value >> 12) & 63)); $decoded[$key] .= chr(128 + (($value >> 6) & 63)); $decoded[$key] .= chr(128 + ($value & 63)); } else { $this->error(self::CANNOT_DECODE_PUNYCODE); return false; } } return implode($decoded); } } ================================================ FILE: src/Iban.php ================================================ "Unknown country within the IBAN", self::SEPANOTSUPPORTED => "Countries outside the Single Euro Payments Area (SEPA) are not supported", self::FALSEFORMAT => "The input has a false IBAN format", self::CHECKFAILED => "The input has failed the IBAN check", ]; /** * Optional country code by ISO 3166-1 * * @var string|null */ protected $countryCode; /** * Optionally allow IBAN codes from non-SEPA countries. Defaults to true * * @var bool */ protected $allowNonSepa = true; /** * The SEPA country codes * * @var array */ protected static $sepaCountries = [ 'AT', 'BE', 'BG', 'CY', 'CZ', 'DK', 'FO', 'GL', 'EE', 'FI', 'FR', 'DE', 'GI', 'GR', 'HU', 'IS', 'IE', 'IT', 'LV', 'LI', 'LT', 'LU', 'MT', 'MC', 'NL', 'NO', 'PL', 'PT', 'RO', 'SK', 'SI', 'ES', 'SE', 'CH', 'GB', 'SM', 'HR', ]; /** * IBAN regexes by country code * * @var array */ protected static $ibanRegex = [ 'AD' => 'AD[0-9]{2}[0-9]{4}[0-9]{4}[A-Z0-9]{12}', 'AE' => 'AE[0-9]{2}[0-9]{3}[0-9]{16}', 'AL' => 'AL[0-9]{2}[0-9]{8}[A-Z0-9]{16}', 'AT' => 'AT[0-9]{2}[0-9]{5}[0-9]{11}', 'AZ' => 'AZ[0-9]{2}[A-Z]{4}[A-Z0-9]{20}', 'BA' => 'BA[0-9]{2}[0-9]{3}[0-9]{3}[0-9]{8}[0-9]{2}', 'BE' => 'BE[0-9]{2}[0-9]{3}[0-9]{7}[0-9]{2}', 'BG' => 'BG[0-9]{2}[A-Z]{4}[0-9]{4}[0-9]{2}[A-Z0-9]{8}', 'BH' => 'BH[0-9]{2}[A-Z]{4}[A-Z0-9]{14}', 'BR' => 'BR[0-9]{2}[0-9]{8}[0-9]{5}[0-9]{10}[A-Z][A-Z0-9]', 'BY' => 'BY[0-9]{2}[A-Z0-9]{4}[0-9]{4}[A-Z0-9]{16}', 'CH' => 'CH[0-9]{2}[0-9]{5}[A-Z0-9]{12}', 'CR' => 'CR[0-9]{2}[0-9]{3}[0-9]{14}', 'CY' => 'CY[0-9]{2}[0-9]{3}[0-9]{5}[A-Z0-9]{16}', 'CZ' => 'CZ[0-9]{2}[0-9]{20}', 'DE' => 'DE[0-9]{2}[0-9]{8}[0-9]{10}', 'DO' => 'DO[0-9]{2}[A-Z0-9]{4}[0-9]{20}', 'DK' => 'DK[0-9]{2}[0-9]{14}', 'EE' => 'EE[0-9]{2}[0-9]{2}[0-9]{2}[0-9]{11}[0-9]{1}', 'ES' => 'ES[0-9]{2}[0-9]{4}[0-9]{4}[0-9]{1}[0-9]{1}[0-9]{10}', 'FI' => 'FI[0-9]{2}[0-9]{6}[0-9]{7}[0-9]{1}', 'FO' => 'FO[0-9]{2}[0-9]{4}[0-9]{9}[0-9]{1}', 'FR' => 'FR[0-9]{2}[0-9]{5}[0-9]{5}[A-Z0-9]{11}[0-9]{2}', 'GB' => 'GB[0-9]{2}[A-Z]{4}[0-9]{6}[0-9]{8}', 'GE' => 'GE[0-9]{2}[A-Z]{2}[0-9]{16}', 'GI' => 'GI[0-9]{2}[A-Z]{4}[A-Z0-9]{15}', 'GL' => 'GL[0-9]{2}[0-9]{4}[0-9]{9}[0-9]{1}', 'GR' => 'GR[0-9]{2}[0-9]{3}[0-9]{4}[A-Z0-9]{16}', 'GT' => 'GT[0-9]{2}[A-Z0-9]{4}[A-Z0-9]{20}', 'HR' => 'HR[0-9]{2}[0-9]{7}[0-9]{10}', 'HU' => 'HU[0-9]{2}[0-9]{3}[0-9]{4}[0-9]{1}[0-9]{15}[0-9]{1}', 'IE' => 'IE[0-9]{2}[A-Z]{4}[0-9]{6}[0-9]{8}', 'IL' => 'IL[0-9]{2}[0-9]{3}[0-9]{3}[0-9]{13}', 'IS' => 'IS[0-9]{2}[0-9]{4}[0-9]{2}[0-9]{6}[0-9]{10}', 'IT' => 'IT[0-9]{2}[A-Z]{1}[0-9]{5}[0-9]{5}[A-Z0-9]{12}', 'KW' => 'KW[0-9]{2}[A-Z]{4}[0-9]{22}', 'KZ' => 'KZ[0-9]{2}[0-9]{3}[A-Z0-9]{13}', 'LB' => 'LB[0-9]{2}[0-9]{4}[A-Z0-9]{20}', 'LI' => 'LI[0-9]{2}[0-9]{5}[A-Z0-9]{12}', 'LT' => 'LT[0-9]{2}[0-9]{5}[0-9]{11}', 'LU' => 'LU[0-9]{2}[0-9]{3}[A-Z0-9]{13}', 'LV' => 'LV[0-9]{2}[A-Z]{4}[A-Z0-9]{13}', 'MC' => 'MC[0-9]{2}[0-9]{5}[0-9]{5}[A-Z0-9]{11}[0-9]{2}', 'MD' => 'MD[0-9]{2}[A-Z0-9]{20}', 'ME' => 'ME[0-9]{2}[0-9]{3}[0-9]{13}[0-9]{2}', 'MK' => 'MK[0-9]{2}[0-9]{3}[A-Z0-9]{10}[0-9]{2}', 'MR' => 'MR13[0-9]{5}[0-9]{5}[0-9]{11}[0-9]{2}', 'MT' => 'MT[0-9]{2}[A-Z]{4}[0-9]{5}[A-Z0-9]{18}', 'MU' => 'MU[0-9]{2}[A-Z]{4}[0-9]{2}[0-9]{2}[0-9]{12}[0-9]{3}[A-Z]{3}', 'NL' => 'NL[0-9]{2}[A-Z]{4}[0-9]{10}', 'NO' => 'NO[0-9]{2}[0-9]{4}[0-9]{6}[0-9]{1}', 'PK' => 'PK[0-9]{2}[A-Z]{4}[A-Z0-9]{16}', 'PL' => 'PL[0-9]{2}[0-9]{8}[0-9]{16}', 'PS' => 'PS[0-9]{2}[A-Z]{4}[A-Z0-9]{21}', 'PT' => 'PT[0-9]{2}[0-9]{4}[0-9]{4}[0-9]{11}[0-9]{2}', 'RO' => 'RO[0-9]{2}[A-Z]{4}[A-Z0-9]{16}', 'RS' => 'RS[0-9]{2}[0-9]{3}[0-9]{13}[0-9]{2}', 'SA' => 'SA[0-9]{2}[0-9]{2}[A-Z0-9]{18}', 'SE' => 'SE[0-9]{2}[0-9]{3}[0-9]{16}[0-9]{1}', 'SI' => 'SI[0-9]{2}[0-9]{5}[0-9]{8}[0-9]{2}', 'SK' => 'SK[0-9]{2}[0-9]{4}[0-9]{6}[0-9]{10}', 'SM' => 'SM[0-9]{2}[A-Z]{1}[0-9]{5}[0-9]{5}[A-Z0-9]{12}', 'TN' => 'TN59[0-9]{2}[0-9]{3}[0-9]{13}[0-9]{2}', 'TR' => 'TR[0-9]{2}[0-9]{5}[A-Z0-9]{1}[A-Z0-9]{16}', 'VG' => 'VG[0-9]{2}[A-Z]{4}[0-9]{16}', ]; /** * Sets validator options * * @param array|Traversable $options OPTIONAL */ public function __construct($options = []) { if ($options instanceof Traversable) { $options = ArrayUtils::iteratorToArray($options); } if (array_key_exists('country_code', $options)) { $this->setCountryCode($options['country_code']); } if (array_key_exists('allow_non_sepa', $options)) { $this->setAllowNonSepa($options['allow_non_sepa']); } parent::__construct($options); } /** * Returns the optional country code by ISO 3166-1 * * @return string|null */ public function getCountryCode() { return $this->countryCode; } /** * Sets an optional country code by ISO 3166-1 * * @param string|null $countryCode * @return Iban provides a fluent interface * @throws Exception\InvalidArgumentException */ public function setCountryCode($countryCode = null) { if ($countryCode !== null) { $countryCode = (string) $countryCode; if (! isset(static::$ibanRegex[$countryCode])) { throw new Exception\InvalidArgumentException( "Country code '{$countryCode}' invalid by ISO 3166-1 or not supported" ); } } $this->countryCode = $countryCode; return $this; } /** * Returns the optional allow non-sepa countries setting * * @return bool */ public function allowNonSepa() { return $this->allowNonSepa; } /** * Sets the optional allow non-sepa countries setting * * @param bool $allowNonSepa * @return Iban provides a fluent interface */ public function setAllowNonSepa($allowNonSepa) { $this->allowNonSepa = (bool) $allowNonSepa; return $this; } /** * Returns true if $value is a valid IBAN * * @param string $value * @return bool */ public function isValid($value) { if (! is_string($value)) { $this->error(self::FALSEFORMAT); return false; } $value = str_replace(' ', '', strtoupper($value)); $this->setValue($value); $countryCode = $this->getCountryCode(); if ($countryCode === null) { $countryCode = substr($value, 0, 2); } if (! array_key_exists($countryCode, static::$ibanRegex)) { $this->setValue($countryCode); $this->error(self::NOTSUPPORTED); return false; } if (! $this->allowNonSepa && ! in_array($countryCode, static::$sepaCountries)) { $this->setValue($countryCode); $this->error(self::SEPANOTSUPPORTED); return false; } if (! preg_match('/^' . static::$ibanRegex[$countryCode] . '$/', $value)) { $this->error(self::FALSEFORMAT); return false; } $format = substr($value, 4) . substr($value, 0, 4); $format = str_replace( ['A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'I', 'J', 'K', 'L', 'M', 'N', 'O', 'P', 'Q', 'R', 'S', 'T', 'U', 'V', 'W', 'X', 'Y', 'Z'], ['10', '11', '12', '13', '14', '15', '16', '17', '18', '19', '20', '21', '22', '23', '24', '25', '26', '27', '28', '29', '30', '31', '32', '33', '34', '35'], $format ); $temp = intval(substr($format, 0, 1)); $len = strlen($format); for ($x = 1; $x < $len; ++$x) { $temp *= 10; $temp += intval(substr($format, $x, 1)); $temp %= 97; } if ($temp != 1) { $this->error(self::CHECKFAILED); return false; } return true; } } ================================================ FILE: src/Identical.php ================================================ "The two given tokens do not match", self::MISSING_TOKEN => 'No token was provided to match against', ]; /** * @var array */ protected $messageVariables = [ 'token' => 'tokenString' ]; /** * Original token against which to validate * @var string */ protected $tokenString; protected $token; protected $strict = true; protected $literal = false; /** * Sets validator options * * @param mixed $token */ public function __construct($token = null) { if ($token instanceof Traversable) { $token = ArrayUtils::iteratorToArray($token); } if (is_array($token) && array_key_exists('token', $token)) { if (array_key_exists('strict', $token)) { $this->setStrict($token['strict']); } if (array_key_exists('literal', $token)) { $this->setLiteral($token['literal']); } $this->setToken($token['token']); } elseif (null !== $token) { $this->setToken($token); } parent::__construct(is_array($token) ? $token : null); } /** * Retrieve token * * @return mixed */ public function getToken() { return $this->token; } /** * Set token against which to compare * * @param mixed $token * @return Identical */ public function setToken($token) { $this->tokenString = (is_array($token) ? var_export($token, true) : (string) $token); $this->token = $token; return $this; } /** * Returns the strict parameter * * @return bool */ public function getStrict() { return $this->strict; } /** * Sets the strict parameter * * @param bool $strict * @return Identical */ public function setStrict($strict) { $this->strict = (bool) $strict; return $this; } /** * Returns the literal parameter * * @return bool */ public function getLiteral() { return $this->literal; } /** * Sets the literal parameter * * @param bool $literal * @return Identical */ public function setLiteral($literal) { $this->literal = (bool) $literal; return $this; } /** * Returns true if and only if a token has been set and the provided value * matches that token. * * @param mixed $value * @param array|ArrayAccess $context * @throws Exception\InvalidArgumentException If context is not array or ArrayObject * @return bool */ public function isValid($value, $context = null) { $this->setValue($value); $token = $this->getToken(); if (! $this->getLiteral() && $context !== null) { if (! is_array($context) && ! ($context instanceof ArrayAccess)) { throw new Exception\InvalidArgumentException(sprintf( 'Context passed to %s must be array, ArrayObject or null; received "%s"', __METHOD__, is_object($context) ? get_class($context) : gettype($context) )); } if (is_array($token)) { while (is_array($token)) { $key = key($token); if (! isset($context[$key])) { break; } $context = $context[$key]; $token = $token[$key]; } } // if $token is an array it means the above loop didn't went all the way down to the leaf, // so the $token structure doesn't match the $context structure if (is_array($token) || ! isset($context[$token])) { $token = $this->getToken(); } else { $token = $context[$token]; } } if ($token === null) { $this->error(self::MISSING_TOKEN); return false; } $strict = $this->getStrict(); if (($strict && ($value !== $token)) || (! $strict && ($value != $token))) { $this->error(self::NOT_SAME); return false; } return true; } } ================================================ FILE: src/InArray.php ================================================ 'The input was not found in the haystack', ]; /** * Haystack of possible values * * @var array */ protected $haystack; /** * Type of strict check to be used. Due to "foo" == 0 === TRUE with in_array when strict = false, * an option has been added to prevent this. When $strict = 0/false, the most * secure non-strict check is implemented. if $strict = -1, the default in_array non-strict * behaviour is used * * @var int */ protected $strict = self::COMPARE_NOT_STRICT_AND_PREVENT_STR_TO_INT_VULNERABILITY; /** * Whether a recursive search should be done * * @var bool */ protected $recursive = false; /** * Returns the haystack option * * @return mixed * @throws Exception\RuntimeException if haystack option is not set */ public function getHaystack() { if ($this->haystack === null) { throw new Exception\RuntimeException('haystack option is mandatory'); } return $this->haystack; } /** * Sets the haystack option * * @param mixed $haystack * @return InArray Provides a fluent interface */ public function setHaystack(array $haystack) { $this->haystack = $haystack; return $this; } /** * Returns the strict option * * @return bool|int */ public function getStrict() { // To keep BC with new strict modes if ($this->strict == self::COMPARE_NOT_STRICT_AND_PREVENT_STR_TO_INT_VULNERABILITY || $this->strict == self::COMPARE_STRICT ) { return (bool) $this->strict; } return $this->strict; } /** * Sets the strict option mode * InArray::COMPARE_STRICT * InArray::COMPARE_NOT_STRICT_AND_PREVENT_STR_TO_INT_VULNERABILITY * InArray::COMPARE_NOT_STRICT * * @param int $strict * @return InArray Provides a fluent interface * @throws Exception\InvalidArgumentException */ public function setStrict($strict) { $checkTypes = [ self::COMPARE_NOT_STRICT_AND_PREVENT_STR_TO_INT_VULNERABILITY, // 0 self::COMPARE_STRICT, // 1 self::COMPARE_NOT_STRICT // -1 ]; // validate strict value if (! in_array($strict, $checkTypes)) { throw new Exception\InvalidArgumentException('Strict option must be one of the COMPARE_ constants'); } $this->strict = $strict; return $this; } /** * Returns the recursive option * * @return bool */ public function getRecursive() { return $this->recursive; } /** * Sets the recursive option * * @param bool $recursive * @return InArray Provides a fluent interface */ public function setRecursive($recursive) { $this->recursive = (bool) $recursive; return $this; } /** * Returns true if and only if $value is contained in the haystack option. If the strict * option is true, then the type of $value is also checked. * * @param mixed $value * See {@link http://php.net/manual/function.in-array.php#104501} * @return bool */ public function isValid($value) { // we create a copy of the haystack in case we need to modify it $haystack = $this->getHaystack(); // if the input is a string or float, and vulnerability protection is on // we type cast the input to a string if (self::COMPARE_NOT_STRICT_AND_PREVENT_STR_TO_INT_VULNERABILITY == $this->strict && (is_int($value) || is_float($value))) { $value = (string) $value; } $this->setValue($value); if ($this->getRecursive()) { $iterator = new RecursiveIteratorIterator(new RecursiveArrayIterator($haystack)); foreach ($iterator as $element) { if (self::COMPARE_STRICT == $this->strict) { if ($element === $value) { return true; } } else { // add protection to prevent string to int vuln's $el = $element; if (self::COMPARE_NOT_STRICT_AND_PREVENT_STR_TO_INT_VULNERABILITY == $this->strict && is_string($value) && (is_int($el) || is_float($el)) ) { $el = (string) $el; } if ($el == $value) { return true; } } } } else { /** * If the check is not strict, then, to prevent "asdf" being converted to 0 * and returning a false positive if 0 is in haystack, we type cast * the haystack to strings. To prevent "56asdf" == 56 === TRUE we also * type cast values like 56 to strings as well. * * This occurs only if the input is a string and a haystack member is an int */ if (self::COMPARE_NOT_STRICT_AND_PREVENT_STR_TO_INT_VULNERABILITY == $this->strict && is_string($value) ) { foreach ($haystack as &$h) { if (is_int($h) || is_float($h)) { $h = (string) $h; } } } if (in_array($value, $haystack, self::COMPARE_STRICT == $this->strict)) { return true; } } $this->error(self::NOT_IN_ARRAY); return false; } } ================================================ FILE: src/Ip.php ================================================ 'Invalid type given. String expected', self::NOT_IP_ADDRESS => "The input does not appear to be a valid IP address", ]; /** * Internal options * * @var array */ protected $options = [ 'allowipv4' => true, // Enable IPv4 Validation 'allowipv6' => true, // Enable IPv6 Validation 'allowipvfuture' => false, // Enable IPvFuture Validation 'allowliteral' => true, // Enable IPs in literal format (only IPv6 and IPvFuture) ]; /** * Sets the options for this validator * * @param array|Traversable $options * @throws Exception\InvalidArgumentException If there is any kind of IP allowed or $options is not an array * or Traversable. * @return AbstractValidator */ public function setOptions($options = []) { parent::setOptions($options); if (! $this->options['allowipv4'] && ! $this->options['allowipv6'] && ! $this->options['allowipvfuture']) { throw new Exception\InvalidArgumentException('Nothing to validate. Check your options'); } return $this; } /** * Returns true if and only if $value is a valid IP address * * @param mixed $value * @return bool */ public function isValid($value) { if (! is_string($value)) { $this->error(self::INVALID); return false; } $this->setValue($value); if ($this->options['allowipv4'] && $this->validateIPv4($value)) { return true; } else { if ((bool) $this->options['allowliteral']) { static $regex = '/^\[(.*)\]$/'; if ((bool) preg_match($regex, $value, $matches)) { $value = $matches[1]; } } if (($this->options['allowipv6'] && $this->validateIPv6($value)) || ($this->options['allowipvfuture'] && $this->validateIPvFuture($value)) ) { return true; } } $this->error(self::NOT_IP_ADDRESS); return false; } /** * Validates an IPv4 address * * @param string $value * @return bool */ protected function validateIPv4($value) { if (preg_match('/^([01]{8}\.){3}[01]{8}\z/i', $value)) { // binary format 00000000.00000000.00000000.00000000 $value = bindec(substr($value, 0, 8)) . '.' . bindec(substr($value, 9, 8)) . '.' . bindec(substr($value, 18, 8)) . '.' . bindec(substr($value, 27, 8)); } elseif (preg_match('/^([0-9]{3}\.){3}[0-9]{3}\z/i', $value)) { // octet format 777.777.777.777 $value = (int) substr($value, 0, 3) . '.' . (int) substr($value, 4, 3) . '.' . (int) substr($value, 8, 3) . '.' . (int) substr($value, 12, 3); } elseif (preg_match('/^([0-9a-f]{2}\.){3}[0-9a-f]{2}\z/i', $value)) { // hex format ff.ff.ff.ff $value = hexdec(substr($value, 0, 2)) . '.' . hexdec(substr($value, 3, 2)) . '.' . hexdec(substr($value, 6, 2)) . '.' . hexdec(substr($value, 9, 2)); } $ip2long = ip2long($value); if ($ip2long === false) { return false; } return ($value == long2ip($ip2long)); } /** * Validates an IPv6 address * * @param string $value Value to check against * @return bool True when $value is a valid ipv6 address * False otherwise */ protected function validateIPv6($value) { if (strlen($value) < 3) { return $value == '::'; } if (strpos($value, '.')) { $lastcolon = strrpos($value, ':'); if (! ($lastcolon && $this->validateIPv4(substr($value, $lastcolon + 1)))) { return false; } $value = substr($value, 0, $lastcolon) . ':0:0'; } if (strpos($value, '::') === false) { return preg_match('/\A(?:[a-f0-9]{1,4}:){7}[a-f0-9]{1,4}\z/i', $value); } $colonCount = substr_count($value, ':'); if ($colonCount < 8) { return preg_match('/\A(?::|(?:[a-f0-9]{1,4}:)+):(?:(?:[a-f0-9]{1,4}:)*[a-f0-9]{1,4})?\z/i', $value); } // special case with ending or starting double colon if ($colonCount == 8) { return preg_match('/\A(?:::)?(?:[a-f0-9]{1,4}:){6}[a-f0-9]{1,4}(?:::)?\z/i', $value); } return false; } /** * Validates an IPvFuture address. * * IPvFuture is loosely defined in the Section 3.2.2 of RFC 3986 * * @param string $value Value to check against * @return bool True when $value is a valid IPvFuture address * False otherwise */ protected function validateIPvFuture($value) { /* * ABNF: * IPvFuture = "v" 1*HEXDIG "." 1*( unreserved / sub-delims / ":" ) * unreserved = ALPHA / DIGIT / "-" / "." / "_" / "~" * sub-delims = "!" / "$" / "&" / "'" / "(" / ")" / "*" / "+" / "," * / ";" / "=" */ static $regex = '/^v([[:xdigit:]]+)\.[[:alnum:]\-\._~!\$&\'\(\)\*\+,;=:]+$/'; $result = (bool) preg_match($regex, $value, $matches); /* * "As such, implementations must not provide the version flag for the * existing IPv4 and IPv6 literal address forms described below." */ return ($result && $matches[1] != 4 && $matches[1] != 6); } } ================================================ FILE: src/IsCountable.php ================================================ "The input must be an array or an instance of \\Countable", self::NOT_EQUALS => "The input count must equal '%count%'", self::GREATER_THAN => "The input count must be less than '%max%', inclusively", self::LESS_THAN => "The input count must be greater than '%min%', inclusively", ]; /** * Additional variables available for validation failure messages * * @var array */ protected $messageVariables = [ 'count' => ['options' => 'count'], 'min' => ['options' => 'min'], 'max' => ['options' => 'max'], ]; /** * Options for the between validator * * @var array */ protected $options = [ 'count' => null, 'min' => null, 'max' => null, ]; public function setOptions($options = []) { foreach (['count', 'min', 'max'] as $option) { if (! is_array($options) || ! isset($options[$option])) { continue; } $method = sprintf('set%s', ucfirst($option)); $this->$method($options[$option]); unset($options[$option]); } return parent::setOptions($options); } /** * Returns true if and only if $value is countable (and the count validates against optional values). * * @param iterable $value * @return bool */ public function isValid($value) { if (! (is_array($value) || $value instanceof Countable)) { $this->error(self::NOT_COUNTABLE); return false; } $count = count($value); if (is_numeric($this->getCount())) { if ($count != $this->getCount()) { $this->error(self::NOT_EQUALS); return false; } return true; } if (is_numeric($this->getMax()) && $count > $this->getMax()) { $this->error(self::GREATER_THAN); return false; } if (is_numeric($this->getMin()) && $count < $this->getMin()) { $this->error(self::LESS_THAN); return false; } return true; } /** * Returns the count option * * @return mixed */ public function getCount() { return $this->options['count']; } /** * Returns the min option * * @return mixed */ public function getMin() { return $this->options['min']; } /** * Returns the max option * * @return mixed */ public function getMax() { return $this->options['max']; } /** * @param mixed $value * @return void * @throws Exception\InvalidArgumentException if either a min or max option * was previously set. */ private function setCount($value) { if (isset($this->options['min']) || isset($this->options['max'])) { throw new Exception\InvalidArgumentException( 'Cannot set count; conflicts with either a min or max option previously set' ); } $this->options['count'] = $value; } /** * @param mixed $value * @return void * @throws Exception\InvalidArgumentException if either a count or max option * was previously set. */ private function setMin($value) { if (isset($this->options['count'])) { throw new Exception\InvalidArgumentException( 'Cannot set count; conflicts with either a count option previously set' ); } $this->options['min'] = $value; } /** * @param mixed $value * @return void * @throws Exception\InvalidArgumentException if either a count or min option * was previously set. */ private function setMax($value) { if (isset($this->options['count'])) { throw new Exception\InvalidArgumentException( 'Cannot set count; conflicts with either a count option previously set' ); } $this->options['max'] = $value; } } ================================================ FILE: src/IsInstanceOf.php ================================================ "The input is not an instance of '%className%'", ]; /** * Additional variables available for validation failure messages * * @var array */ protected $messageVariables = [ 'className' => 'className' ]; /** * Class name * * @var string */ protected $className; /** * Sets validator options * * @param array|Traversable $options * @throws Exception\InvalidArgumentException */ public function __construct($options = null) { if ($options instanceof Traversable) { $options = iterator_to_array($options); } // If argument is not an array, consider first argument as class name if (! is_array($options)) { $options = func_get_args(); $tmpOptions = []; $tmpOptions['className'] = array_shift($options); $options = $tmpOptions; } if (! array_key_exists('className', $options)) { throw new Exception\InvalidArgumentException('Missing option "className"'); } parent::__construct($options); } /** * Get class name * * @return string */ public function getClassName() { return $this->className; } /** * Set class name * * @param string $className * @return self */ public function setClassName($className) { $this->className = $className; return $this; } /** * Returns true if $value is instance of $this->className * * @param mixed $value * @return bool */ public function isValid($value) { if ($value instanceof $this->className) { return true; } $this->error(self::NOT_INSTANCE_OF); return false; } } ================================================ FILE: src/Isbn/Isbn10.php ================================================ sum($value); return $this->checksum($sum); } /** * Calculate the value sum. * * @param int|string $value * @return int */ private function sum($value) { $sum = 0; for ($i = 0; $i < 9; $i++) { $sum += (10 - $i) * $value[$i]; } return $sum; } /** * Calculate the checksum for the value's sum. * * @param int $sum * @return int|string */ private function checksum($sum) { $checksum = 11 - ($sum % 11); if ($checksum == 11) { return '0'; } if ($checksum == 10) { return 'X'; } return $checksum; } } ================================================ FILE: src/Isbn/Isbn13.php ================================================ sum($value); return $this->checksum($sum); } /** * Calculate the value sum. * * @param int|string $value * @return int */ private function sum($value) { $sum = 0; for ($i = 0; $i < 12; $i++) { if ($i % 2 == 0) { $sum += $value[$i]; continue; } $sum += 3 * $value[$i]; } return $sum; } /** * Calculate the checksum for the value's sum. * * @param int $sum * @return int|string */ private function checksum($sum) { $checksum = 10 - ($sum % 10); if ($checksum == 10) { return '0'; } return $checksum; } } ================================================ FILE: src/Isbn.php ================================================ "Invalid type given. String or integer expected", self::NO_ISBN => "The input is not a valid ISBN number", ]; protected $options = [ 'type' => self::AUTO, // Allowed type 'separator' => '', // Separator character ]; /** * Detect input format. * * @return string */ protected function detectFormat() { // prepare separator and pattern list $sep = quotemeta($this->getSeparator()); $patterns = []; $lengths = []; $type = $this->getType(); // check for ISBN-10 if ($type == self::ISBN10 || $type == self::AUTO) { if (empty($sep)) { $pattern = '/^[0-9]{9}[0-9X]{1}$/'; $length = 10; } else { $pattern = "/^[0-9]{1,7}[{$sep}]{1}[0-9]{1,7}[{$sep}]{1}[0-9]{1,7}[{$sep}]{1}[0-9X]{1}$/"; $length = 13; } $patterns[$pattern] = self::ISBN10; $lengths[$pattern] = $length; } // check for ISBN-13 if ($type == self::ISBN13 || $type == self::AUTO) { if (empty($sep)) { $pattern = '/^[0-9]{13}$/'; $length = 13; } else { // @codingStandardsIgnoreStart $pattern = "/^[0-9]{1,9}[{$sep}]{1}[0-9]{1,5}[{$sep}]{1}[0-9]{1,9}[{$sep}]{1}[0-9]{1,9}[{$sep}]{1}[0-9]{1}$/"; // @codingStandardsIgnoreEnd $length = 17; } $patterns[$pattern] = self::ISBN13; $lengths[$pattern] = $length; } // check pattern list foreach ($patterns as $pattern => $type) { if ((strlen($this->getValue()) == $lengths[$pattern]) && preg_match($pattern, $this->getValue())) { return $type; } } return; } /** * Returns true if and only if $value is a valid ISBN. * * @param string $value * @return bool */ public function isValid($value) { if (! is_string($value) && ! is_int($value)) { $this->error(self::INVALID); return false; } $value = (string) $value; $this->setValue($value); switch ($this->detectFormat()) { case self::ISBN10: $isbn = new Isbn\Isbn10(); break; case self::ISBN13: $isbn = new Isbn\Isbn13(); break; default: $this->error(self::NO_ISBN); return false; } $value = str_replace($this->getSeparator(), '', $value); $checksum = $isbn->getChecksum($value); // validate if (substr($this->getValue(), -1) != $checksum) { $this->error(self::NO_ISBN); return false; } return true; } /** * Set separator characters. * * It is allowed only empty string, hyphen and space. * * @param string $separator * @throws Exception\InvalidArgumentException When $separator is not valid * @return Isbn Provides a fluent interface */ public function setSeparator($separator) { // check separator if (! in_array($separator, ['-', ' ', ''])) { throw new Exception\InvalidArgumentException('Invalid ISBN separator.'); } $this->options['separator'] = $separator; return $this; } /** * Get separator characters. * * @return string */ public function getSeparator() { return $this->options['separator']; } /** * Set allowed ISBN type. * * @param string $type * @throws Exception\InvalidArgumentException When $type is not valid * @return Isbn Provides a fluent interface */ public function setType($type) { // check type if (! in_array($type, [self::AUTO, self::ISBN10, self::ISBN13])) { throw new Exception\InvalidArgumentException('Invalid ISBN type'); } $this->options['type'] = $type; return $this; } /** * Get allowed ISBN type. * * @return string */ public function getType() { return $this->options['type']; } } ================================================ FILE: src/LessThan.php ================================================ "The input is not less than '%max%'", self::NOT_LESS_INCLUSIVE => "The input is not less or equal than '%max%'" ]; /** * Additional variables available for validation failure messages * * @var array */ protected $messageVariables = [ 'max' => 'max' ]; /** * Maximum value * * @var mixed */ protected $max; /** * Whether to do inclusive comparisons, allowing equivalence to max * * If false, then strict comparisons are done, and the value may equal * the max option * * @var bool */ protected $inclusive; /** * Sets validator options * * @param array|Traversable $options * @throws Exception\InvalidArgumentException */ public function __construct($options = null) { if ($options instanceof Traversable) { $options = ArrayUtils::iteratorToArray($options); } if (! is_array($options)) { $options = func_get_args(); $temp['max'] = array_shift($options); if (! empty($options)) { $temp['inclusive'] = array_shift($options); } $options = $temp; } if (! array_key_exists('max', $options)) { throw new Exception\InvalidArgumentException("Missing option 'max'"); } if (! array_key_exists('inclusive', $options)) { $options['inclusive'] = false; } $this->setMax($options['max']) ->setInclusive($options['inclusive']); parent::__construct($options); } /** * Returns the max option * * @return mixed */ public function getMax() { return $this->max; } /** * Sets the max option * * @param mixed $max * @return LessThan Provides a fluent interface */ public function setMax($max) { $this->max = $max; return $this; } /** * Returns the inclusive option * * @return bool */ public function getInclusive() { return $this->inclusive; } /** * Sets the inclusive option * * @param bool $inclusive * @return LessThan Provides a fluent interface */ public function setInclusive($inclusive) { $this->inclusive = $inclusive; return $this; } /** * Returns true if and only if $value is less than max option, inclusively * when the inclusive option is true * * @param mixed $value * @return bool */ public function isValid($value) { $this->setValue($value); if ($this->inclusive) { if ($value > $this->max) { $this->error(self::NOT_LESS_INCLUSIVE); return false; } } else { if ($value >= $this->max) { $this->error(self::NOT_LESS); return false; } } return true; } } ================================================ FILE: src/Module.php ================================================ $provider->getDependencyConfig(), ]; } /** * Register a specification for the ValidatorManager with the ServiceListener. * * @param \Zend\ModuleManager\ModuleManager $moduleManager * @return void */ public function init($moduleManager) { $event = $moduleManager->getEvent(); $container = $event->getParam('ServiceManager'); $serviceListener = $container->get('ServiceListener'); $serviceListener->addServiceManager( 'ValidatorManager', 'validators', ValidatorProviderInterface::class, 'getValidatorConfig' ); } } ================================================ FILE: src/NotEmpty.php ================================================ 'boolean', self::INTEGER => 'integer', self::FLOAT => 'float', self::STRING => 'string', self::ZERO => 'zero', self::EMPTY_ARRAY => 'array', self::NULL => 'null', self::PHP => 'php', self::SPACE => 'space', self::OBJECT => 'object', self::OBJECT_STRING => 'objectstring', self::OBJECT_COUNT => 'objectcount', self::ALL => 'all', ]; /** * Default value for types; value = 0b000111101001 * * @var array */ protected $defaultType = [ self::OBJECT, self::SPACE, self::NULL, self::EMPTY_ARRAY, self::STRING, self::BOOLEAN ]; /** * @var array */ protected $messageTemplates = [ self::IS_EMPTY => "Value is required and can't be empty", self::INVALID => "Invalid type given. String, integer, float, boolean or array expected", ]; /** * Options for this validator * * @var array */ protected $options = []; /** * Constructor * * @param array|Traversable|int $options OPTIONAL */ public function __construct($options = null) { if ($options instanceof Traversable) { $options = ArrayUtils::iteratorToArray($options); } if (! is_array($options)) { $options = func_get_args(); $temp = []; if (! empty($options)) { $temp['type'] = array_shift($options); } $options = $temp; } if (! isset($options['type'])) { if (($type = $this->calculateTypeValue($options)) != 0) { $options['type'] = $type; } else { $options['type'] = $this->defaultType; } } parent::__construct($options); } /** * Returns the set types * * @return array */ public function getType() { return $this->options['type']; } /** * @return int */ public function getDefaultType() { return $this->calculateTypeValue($this->defaultType); } /** * @param array|int|string $type * @return int */ protected function calculateTypeValue($type) { if (is_array($type)) { $detected = 0; foreach ($type as $value) { if (is_int($value)) { $detected |= $value; } elseif (in_array($value, $this->constants, true)) { $detected |= array_search($value, $this->constants, true); } } $type = $detected; } elseif (is_string($type) && in_array($type, $this->constants, true)) { $type = array_search($type, $this->constants, true); } return $type; } /** * Set the types * * @param int|array $type * @throws Exception\InvalidArgumentException * @return NotEmpty */ public function setType($type = null) { $type = $this->calculateTypeValue($type); if (! is_int($type) || ($type < 0) || ($type > self::ALL)) { throw new Exception\InvalidArgumentException('Unknown type'); } $this->options['type'] = $type; return $this; } /** * Returns true if and only if $value is not an empty value. * * @param string $value * @return bool */ public function isValid($value) { if ($value !== null && ! is_string($value) && ! is_int($value) && ! is_float($value) && ! is_bool($value) && ! is_array($value) && ! is_object($value) ) { $this->error(self::INVALID); return false; } $type = $this->getType(); $this->setValue($value); $object = false; // OBJECT_COUNT (countable object) if ($type & self::OBJECT_COUNT) { $object = true; if (is_object($value) && ($value instanceof \Countable) && (count($value) == 0)) { $this->error(self::IS_EMPTY); return false; } } // OBJECT_STRING (object's toString) if ($type & self::OBJECT_STRING) { $object = true; if ((is_object($value) && (! method_exists($value, '__toString'))) || (is_object($value) && (method_exists($value, '__toString')) && (((string) $value) == ""))) { $this->error(self::IS_EMPTY); return false; } } // OBJECT (object) if ($type & self::OBJECT) { // fall trough, objects are always not empty } elseif ($object === false) { // object not allowed but object given -> return false if (is_object($value)) { $this->error(self::IS_EMPTY); return false; } } // SPACE (' ') if ($type & self::SPACE) { if (is_string($value) && (preg_match('/^\s+$/s', $value))) { $this->error(self::IS_EMPTY); return false; } } // NULL (null) if ($type & self::NULL) { if ($value === null) { $this->error(self::IS_EMPTY); return false; } } // EMPTY_ARRAY (array()) if ($type & self::EMPTY_ARRAY) { if (is_array($value) && ($value == [])) { $this->error(self::IS_EMPTY); return false; } } // ZERO ('0') if ($type & self::ZERO) { if (is_string($value) && ($value == '0')) { $this->error(self::IS_EMPTY); return false; } } // STRING ('') if ($type & self::STRING) { if (is_string($value) && ($value == '')) { $this->error(self::IS_EMPTY); return false; } } // FLOAT (0.0) if ($type & self::FLOAT) { if (is_float($value) && ($value == 0.0)) { $this->error(self::IS_EMPTY); return false; } } // INTEGER (0) if ($type & self::INTEGER) { if (is_int($value) && ($value == 0)) { $this->error(self::IS_EMPTY); return false; } } // BOOLEAN (false) if ($type & self::BOOLEAN) { if (is_bool($value) && ($value == false)) { $this->error(self::IS_EMPTY); return false; } } return true; } } ================================================ FILE: src/Regex.php ================================================ "Invalid type given. String, integer or float expected", self::NOT_MATCH => "The input does not match against pattern '%pattern%'", self::ERROROUS => "There was an internal error while using the pattern '%pattern%'", ]; /** * @var array */ protected $messageVariables = [ 'pattern' => 'pattern' ]; /** * Regular expression pattern * * @var string */ protected $pattern; /** * Sets validator options * * @param string|array|Traversable $pattern * @throws Exception\InvalidArgumentException On missing 'pattern' parameter */ public function __construct($pattern) { if (is_string($pattern)) { $this->setPattern($pattern); parent::__construct([]); return; } if ($pattern instanceof Traversable) { $pattern = ArrayUtils::iteratorToArray($pattern); } if (! is_array($pattern)) { throw new Exception\InvalidArgumentException('Invalid options provided to constructor'); } if (! array_key_exists('pattern', $pattern)) { throw new Exception\InvalidArgumentException("Missing option 'pattern'"); } $this->setPattern($pattern['pattern']); unset($pattern['pattern']); parent::__construct($pattern); } /** * Returns the pattern option * * @return string */ public function getPattern() { return $this->pattern; } /** * Sets the pattern option * * @param string $pattern * @throws Exception\InvalidArgumentException if there is a fatal error in pattern matching * @return Regex Provides a fluent interface */ public function setPattern($pattern) { ErrorHandler::start(); $this->pattern = (string) $pattern; $status = preg_match($this->pattern, "Test"); $error = ErrorHandler::stop(); if (false === $status) { throw new Exception\InvalidArgumentException( "Internal error parsing the pattern '{$this->pattern}'", 0, $error ); } return $this; } /** * Returns true if and only if $value matches against the pattern option * * @param string $value * @return bool */ public function isValid($value) { if (! is_string($value) && ! is_int($value) && ! is_float($value)) { $this->error(self::INVALID); return false; } $this->setValue($value); ErrorHandler::start(); $status = preg_match($this->pattern, $value); ErrorHandler::stop(); if (false === $status) { $this->error(self::ERROROUS); return false; } if (! $status) { $this->error(self::NOT_MATCH); return false; } return true; } } ================================================ FILE: src/Sitemap/Changefreq.php ================================================ value * * @link http://www.sitemaps.org/protocol.php Sitemaps XML format */ class Changefreq extends AbstractValidator { /** * Validation key for not valid * */ const NOT_VALID = 'sitemapChangefreqNotValid'; const INVALID = 'sitemapChangefreqInvalid'; /** * Validation failure message template definitions * * @var array */ protected $messageTemplates = [ self::NOT_VALID => "The input is not a valid sitemap changefreq", self::INVALID => "Invalid type given. String expected", ]; /** * Valid change frequencies * * @var array */ protected $changeFreqs = [ 'always', 'hourly', 'daily', 'weekly', 'monthly', 'yearly', 'never' ]; /** * Validates if a string is valid as a sitemap changefreq * * @link http://www.sitemaps.org/protocol.php#changefreqdef * * @param string $value value to validate * @return bool */ public function isValid($value) { if (! is_string($value)) { $this->error(self::INVALID); return false; } $this->setValue($value); if (! is_string($value)) { return false; } if (! in_array($value, $this->changeFreqs, true)) { $this->error(self::NOT_VALID); return false; } return true; } } ================================================ FILE: src/Sitemap/Lastmod.php ================================================ value * * @link http://www.sitemaps.org/protocol.php Sitemaps XML format */ class Lastmod extends AbstractValidator { /** * Regular expression to use when validating * */ // @codingStandardsIgnoreStart const LASTMOD_REGEX = '/^[0-9]{4}-(0[1-9]|1[0-2])-(0[1-9]|[1-2][0-9]|3[0-1])(T([0-1][0-9]|2[0-3])(:[0-5][0-9])(:[0-5][0-9])?(\\+|-)([0-1][0-9]|2[0-3]):[0-5][0-9])?$/'; // @codingStandardsIgnoreEnd /** * Validation key for not valid * */ const NOT_VALID = 'sitemapLastmodNotValid'; const INVALID = 'sitemapLastmodInvalid'; /** * Validation failure message template definitions * * @var array */ protected $messageTemplates = [ self::NOT_VALID => "The input is not a valid sitemap lastmod", self::INVALID => "Invalid type given. String expected", ]; /** * Validates if a string is valid as a sitemap lastmod * * @link http://www.sitemaps.org/protocol.php#lastmoddef * * @param string $value value to validate * @return bool */ public function isValid($value) { if (! is_string($value)) { $this->error(self::INVALID); return false; } $this->setValue($value); ErrorHandler::start(); $result = preg_match(self::LASTMOD_REGEX, $value); ErrorHandler::stop(); if ($result != 1) { $this->error(self::NOT_VALID); return false; } return true; } } ================================================ FILE: src/Sitemap/Loc.php ================================================ value * * @link http://www.sitemaps.org/protocol.php Sitemaps XML format * * @see Zend\Uri\Uri */ class Loc extends AbstractValidator { /** * Validation key for not valid * */ const NOT_VALID = 'sitemapLocNotValid'; const INVALID = 'sitemapLocInvalid'; /** * Validation failure message template definitions * * @var array */ protected $messageTemplates = [ self::NOT_VALID => "The input is not a valid sitemap location", self::INVALID => "Invalid type given. String expected", ]; /** * Validates if a string is valid as a sitemap location * * @link http://www.sitemaps.org/protocol.php#locdef * * @param string $value value to validate * @return bool */ public function isValid($value) { if (! is_string($value)) { $this->error(self::INVALID); return false; } $this->setValue($value); $uri = Uri\UriFactory::factory($value); if (! $uri->isValid()) { $this->error(self::NOT_VALID); return false; } return true; } } ================================================ FILE: src/Sitemap/Priority.php ================================================ value * * @link http://www.sitemaps.org/protocol.php Sitemaps XML format */ class Priority extends AbstractValidator { /** * Validation key for not valid * */ const NOT_VALID = 'sitemapPriorityNotValid'; const INVALID = 'sitemapPriorityInvalid'; /** * Validation failure message template definitions * * @var array */ protected $messageTemplates = [ self::NOT_VALID => "The input is not a valid sitemap priority", self::INVALID => "Invalid type given. Numeric string, integer or float expected", ]; /** * Validates if a string is valid as a sitemap priority * * @link http://www.sitemaps.org/protocol.php#prioritydef * * @param string $value value to validate * @return bool */ public function isValid($value) { if (! is_numeric($value)) { $this->error(self::INVALID); return false; } $this->setValue($value); $value = (float) $value; if ($value < 0 || $value > 1) { $this->error(self::NOT_VALID); return false; } return true; } } ================================================ FILE: src/StaticValidator.php ================================================ configure(['shared_by_default' => false]); } else { $plugins->setShareByDefault(false); } } static::$plugins = $plugins; } /** * Get plugin manager for locating validators * * @return ValidatorPluginManager */ public static function getPluginManager() { if (null === static::$plugins) { static::setPluginManager(new ValidatorPluginManager(new ServiceManager)); } return static::$plugins; } /** * @param mixed $value * @param string $classBaseName * @param array $options OPTIONAL associative array of options to pass as * the sole argument to the validator constructor. * @return bool * @throws Exception\InvalidArgumentException for an invalid $options argument. */ public static function execute($value, $classBaseName, array $options = []) { if ($options && array_values($options) === $options) { throw new Exception\InvalidArgumentException( 'Invalid options provided via $options argument; must be an associative array' ); } $plugins = static::getPluginManager(); $validator = $plugins->get($classBaseName, $options); return $validator->isValid($value); } } ================================================ FILE: src/Step.php ================================================ "Invalid value given. Scalar expected", self::NOT_STEP => "The input is not a valid step" ]; /** * @var mixed */ protected $baseValue = 0; /** * @var mixed */ protected $step = 1; /** * Set default options for this instance * * @param array $options */ public function __construct($options = []) { if ($options instanceof Traversable) { $options = iterator_to_array($options); } elseif (! is_array($options)) { $options = func_get_args(); $temp['baseValue'] = array_shift($options); if (! empty($options)) { $temp['step'] = array_shift($options); } $options = $temp; } if (isset($options['baseValue'])) { $this->setBaseValue($options['baseValue']); } if (isset($options['step'])) { $this->setStep($options['step']); } parent::__construct($options); } /** * Sets the base value from which the step should be computed * * @param mixed $baseValue * @return Step */ public function setBaseValue($baseValue) { $this->baseValue = $baseValue; return $this; } /** * Returns the base value from which the step should be computed * * @return string */ public function getBaseValue() { return $this->baseValue; } /** * Sets the step value * * @param mixed $step * @return Step */ public function setStep($step) { $this->step = (float) $step; return $this; } /** * Returns the step value * * @return string */ public function getStep() { return $this->step; } /** * Returns true if $value is a scalar and a valid step value * * @param mixed $value * @return bool */ public function isValid($value) { if (! is_numeric($value)) { $this->error(self::INVALID); return false; } $this->setValue($value); $substract = $this->sub($value, $this->baseValue); $fmod = $this->fmod($substract, $this->step); if ($fmod !== 0.0 && $fmod !== $this->step) { $this->error(self::NOT_STEP); return false; } return true; } /** * replaces the internal fmod function which give wrong results on many cases * * @param float $x * @param float $y * @return float */ protected function fmod($x, $y) { if ($y == 0.0) { return 1.0; } //find the maximum precision from both input params to give accurate results $precision = $this->getPrecision($x) + $this->getPrecision($y); return round($x - $y * floor($x / $y), $precision); } /** * replaces the internal substraction operation which give wrong results on some cases * * @param float $x * @param float $y * @return float */ private function sub($x, $y) { $precision = $this->getPrecision($x) + $this->getPrecision($y); return round($x - $y, $precision); } /** * @param float $float * @return int */ private function getPrecision($float) { $segment = substr($float, strpos($float, '.') + 1); return $segment ? strlen($segment) : 0; } } ================================================ FILE: src/StringLength.php ================================================ "Invalid type given. String expected", self::TOO_SHORT => "The input is less than %min% characters long", self::TOO_LONG => "The input is more than %max% characters long", ]; /** * @var array */ protected $messageVariables = [ 'min' => ['options' => 'min'], 'max' => ['options' => 'max'], 'length' => ['options' => 'length'] ]; protected $options = [ 'min' => 0, // Minimum length 'max' => null, // Maximum length, null if there is no length limitation 'encoding' => 'UTF-8', // Encoding to use 'length' => 0 // Actual length ]; protected $stringWrapper; /** * Sets validator options * * @param int|array|\Traversable $options */ public function __construct($options = []) { if (! is_array($options)) { $options = func_get_args(); $temp['min'] = array_shift($options); if (! empty($options)) { $temp['max'] = array_shift($options); } if (! empty($options)) { $temp['encoding'] = array_shift($options); } $options = $temp; } parent::__construct($options); } /** * Returns the min option * * @return int */ public function getMin() { return $this->options['min']; } /** * Sets the min option * * @param int $min * @throws Exception\InvalidArgumentException * @return StringLength Provides a fluent interface */ public function setMin($min) { if (null !== $this->getMax() && $min > $this->getMax()) { throw new Exception\InvalidArgumentException( "The minimum must be less than or equal to the maximum length, but {$min} > {$this->getMax()}" ); } $this->options['min'] = max(0, (int) $min); return $this; } /** * Returns the max option * * @return int|null */ public function getMax() { return $this->options['max']; } /** * Sets the max option * * @param int|null $max * @throws Exception\InvalidArgumentException * @return StringLength Provides a fluent interface */ public function setMax($max) { if (null === $max) { $this->options['max'] = null; } elseif ($max < $this->getMin()) { throw new Exception\InvalidArgumentException( "The maximum must be greater than or equal to the minimum length, but {$max} < {$this->getMin()}" ); } else { $this->options['max'] = (int) $max; } return $this; } /** * Get the string wrapper to detect the string length * * @return StringWrapper */ public function getStringWrapper() { if (! $this->stringWrapper) { $this->stringWrapper = StringUtils::getWrapper($this->getEncoding()); } return $this->stringWrapper; } /** * Set the string wrapper to detect the string length * * @param StringWrapper $stringWrapper * @return StringLength */ public function setStringWrapper(StringWrapper $stringWrapper) { $stringWrapper->setEncoding($this->getEncoding()); $this->stringWrapper = $stringWrapper; } /** * Returns the actual encoding * * @return string */ public function getEncoding() { return $this->options['encoding']; } /** * Sets a new encoding to use * * @param string $encoding * @return StringLength * @throws Exception\InvalidArgumentException */ public function setEncoding($encoding) { $this->stringWrapper = StringUtils::getWrapper($encoding); $this->options['encoding'] = $encoding; return $this; } /** * Returns the length option * * @return int */ private function getLength() { return $this->options['length']; } /** * Sets the length option * * @param int $length * @return StringLength Provides a fluent interface */ private function setLength($length) { $this->options['length'] = (int) $length; return $this; } /** * Returns true if and only if the string length of $value is at least the min option and * no greater than the max option (when the max option is not null). * * @param string $value * @return bool */ public function isValid($value) { if (! is_string($value)) { $this->error(self::INVALID); return false; } $this->setValue($value); $this->setLength($this->getStringWrapper()->strlen($value)); if ($this->getLength() < $this->getMin()) { $this->error(self::TOO_SHORT); } if (null !== $this->getMax() && $this->getMax() < $this->getLength()) { $this->error(self::TOO_LONG); } if ($this->getMessages()) { return false; } return true; } } ================================================ FILE: src/Timezone.php ================================================ 'location', self::ABBREVIATION => 'abbreviation', ]; /** * Default value for types; value = 3 * * @var array */ protected $defaultType = [ self::LOCATION, self::ABBREVIATION, ]; /** * @var array */ protected $messageTemplates = [ self::INVALID => 'Invalid timezone given.', self::INVALID_TIMEZONE_LOCATION => 'Invalid timezone location given.', self::INVALID_TIMEZONE_ABBREVIATION => 'Invalid timezone abbreviation given.', ]; /** * Options for this validator * * @var array */ protected $options = []; /** * Constructor * * @param array|int $options OPTIONAL */ public function __construct($options = []) { $opts['type'] = $this->defaultType; if (is_array($options)) { if (array_key_exists('type', $options)) { $opts['type'] = $options['type']; } } elseif (! empty($options)) { $opts['type'] = $options; } // setType called by parent constructor then setOptions method parent::__construct($opts); } /** * Set the types * * @param int|array $type * * @throws Exception\InvalidArgumentException */ public function setType($type = null) { $type = $this->calculateTypeValue($type); if (! is_int($type) || ($type < 1) || ($type > self::ALL)) { throw new Exception\InvalidArgumentException(sprintf( 'Unknown type "%s" provided', (is_string($type) || is_int($type)) ? $type : (is_object($type) ? get_class($type) : gettype($type)) )); } $this->options['type'] = $type; } /** * Returns true if timezone location or timezone abbreviations is correct. * * @param mixed $value * @return bool */ public function isValid($value) { if ($value !== null && ! is_string($value)) { $this->error(self::INVALID); return false; } $type = $this->options['type']; $this->setValue($value); switch (true) { // Check in locations and abbreviations case (($type & self::LOCATION) && ($type & self::ABBREVIATION)): $abbrs = DateTimeZone::listAbbreviations(); $locations = DateTimeZone::listIdentifiers(); if (! array_key_exists($value, $abbrs) && ! in_array($value, $locations)) { $this->error(self::INVALID); return false; } break; // Check only in locations case ($type & self::LOCATION): $locations = DateTimeZone::listIdentifiers(); if (! in_array($value, $locations)) { $this->error(self::INVALID_TIMEZONE_LOCATION); return false; } break; // Check only in abbreviations case ($type & self::ABBREVIATION): $abbrs = DateTimeZone::listAbbreviations(); if (! array_key_exists($value, $abbrs)) { $this->error(self::INVALID_TIMEZONE_ABBREVIATION); return false; } break; } return true; } /** * @param array|int|string $type * * @return int */ protected function calculateTypeValue($type) { $types = (array) $type; $detected = 0; foreach ($types as $value) { if (is_int($value)) { $detected |= $value; } elseif (false !== ($position = array_search($value, $this->constants))) { $detected |= array_search($value, $this->constants); } } return $detected; } } ================================================ FILE: src/Translator/TranslatorAwareInterface.php ================================================ 'The provided password was found in previous breaches, please create another password', self::NOT_A_STRING => 'The provided password is not a string, please provide a correct password', ]; /** * @var ClientInterface */ private $httpClient; /** * @var RequestFactoryInterface */ private $makeHttpRequest; /** * @var ResponseFactoryInterface */ private $makeHttpResponse; /** * PasswordBreach constructor. */ public function __construct( ClientInterface $httpClient, RequestFactoryInterface $makeHttpRequest, ResponseFactoryInterface $makeHttpResponse ) { $this->httpClient = $httpClient; $this->makeHttpRequest = $makeHttpRequest; $this->makeHttpResponse = $makeHttpResponse; } /** * @inheritDoc */ public function isValid($value) { if (! is_string($value)) { $this->error(self::NOT_A_STRING); return false; } if ($this->isPwnedPassword($value)) { $this->error(self::PASSWORD_BREACHED); return false; } return true; } private function isPwnedPassword(string $password) : bool { $sha1Hash = $this->hashPassword($password); $rangeHash = $this->getRangeHash($sha1Hash); $hashList = $this->retrieveHashList($rangeHash); return $this->hashInResponse($sha1Hash, $hashList); } /** * We use a SHA1 hashed password for checking it against * the breached data set of HIBP. * * @param string $password * @return string */ private function hashPassword(string $password) : string { $hashedPassword = \sha1($password); return strtoupper($hashedPassword); } /** * Creates a hash range that will be send to HIBP API * applying K-Anonymity * * @param string $passwordHash * @return string * @see https://www.troyhunt.com/enhancing-pwned-passwords-privacy-by-exclusively-supporting-anonymity/ */ private function getRangeHash(string $passwordHash) : string { return substr($passwordHash, self::HIBP_K_ANONYMITY_HASH_RANGE_BASE, self::HIBP_K_ANONYMITY_HASH_RANGE_LENGTH); } /** * Making a connection to the HIBP API to retrieve a * list of hashes that all have the same range as we * provided. * * @param string $passwordRange * @return string * @throws ClientExceptionInterface */ private function retrieveHashList(string $passwordRange) : string { $request = $this->makeHttpRequest->createRequest( 'GET', self::HIBP_API_URI . '/range/' . $passwordRange ); $response = $this->httpClient->sendRequest($request); return (string) $response->getBody(); } /** * Checks if the password is in the response from HIBP * * @param string $sha1Hash * @param string $resultStream * @return bool */ private function hashInResponse(string $sha1Hash, string $resultStream) : bool { $data = explode("\r\n", $resultStream); $hashes = array_filter($data, function ($value) use ($sha1Hash) { list($hash, $count) = explode(':', $value); if (0 === strcmp($hash, substr($sha1Hash, self::HIBP_K_ANONYMITY_HASH_RANGE_LENGTH))) { return true; } return false; }); if ([] === $hashes) { return false; } return true; } } ================================================ FILE: src/Uri.php ================================================ "Invalid type given. String expected", self::NOT_URI => "The input does not appear to be a valid Uri", ]; /** * @var UriHandler */ protected $uriHandler; /** * @var bool */ protected $allowRelative = true; /** * @var bool */ protected $allowAbsolute = true; /** * Sets default option values for this instance * * @param array|Traversable $options */ public function __construct($options = []) { if ($options instanceof Traversable) { $options = iterator_to_array($options); } elseif (! is_array($options)) { $options = func_get_args(); $temp['uriHandler'] = array_shift($options); if (! empty($options)) { $temp['allowRelative'] = array_shift($options); } if (! empty($options)) { $temp['allowAbsolute'] = array_shift($options); } $options = $temp; } if (isset($options['uriHandler'])) { $this->setUriHandler($options['uriHandler']); } if (isset($options['allowRelative'])) { $this->setAllowRelative($options['allowRelative']); } if (isset($options['allowAbsolute'])) { $this->setAllowAbsolute($options['allowAbsolute']); } parent::__construct($options); } /** * @throws InvalidArgumentException * @return UriHandler */ public function getUriHandler() { if (null === $this->uriHandler) { // Lazy load the base Uri handler $this->uriHandler = new UriHandler(); } elseif (is_string($this->uriHandler) && class_exists($this->uriHandler)) { // Instantiate string Uri handler that references a class $this->uriHandler = new $this->uriHandler; } if (! $this->uriHandler instanceof UriHandler) { throw new InvalidArgumentException('URI handler is expected to be a Zend\Uri\Uri object'); } return $this->uriHandler; } /** * @param UriHandler $uriHandler * @throws InvalidArgumentException * @return Uri */ public function setUriHandler($uriHandler) { if (! is_subclass_of($uriHandler, 'Zend\Uri\Uri')) { throw new InvalidArgumentException('Expecting a subclass name or instance of Zend\Uri\Uri as $uriHandler'); } $this->uriHandler = $uriHandler; return $this; } /** * Returns the allowAbsolute option * * @return bool */ public function getAllowAbsolute() { return $this->allowAbsolute; } /** * Sets the allowAbsolute option * * @param bool $allowAbsolute * @return Uri */ public function setAllowAbsolute($allowAbsolute) { $this->allowAbsolute = (bool) $allowAbsolute; return $this; } /** * Returns the allowRelative option * * @return bool */ public function getAllowRelative() { return $this->allowRelative; } /** * Sets the allowRelative option * * @param bool $allowRelative * @return Uri */ public function setAllowRelative($allowRelative) { $this->allowRelative = (bool) $allowRelative; return $this; } /** * Returns true if and only if $value validates as a Uri * * @param string $value * @return bool */ public function isValid($value) { if (! is_string($value)) { $this->error(self::INVALID); return false; } $uriHandler = $this->getUriHandler(); try { $uriHandler->parse($value); if ($uriHandler->isValid()) { // It will either be a valid absolute or relative URI if (($this->allowRelative && $this->allowAbsolute) || ($this->allowAbsolute && $uriHandler->isAbsolute()) || ($this->allowRelative && $uriHandler->isValidRelative()) ) { return true; } } } catch (UriException $ex) { // Error parsing URI, it must be invalid } $this->error(self::NOT_URI); return false; } } ================================================ FILE: src/Uuid.php ================================================ 'Invalid type given; string expected', self::INVALID => 'Invalid UUID format', ]; /** * Returns true if and only if $value meets the validation requirements. * * If $value fails validation, then this method returns false, and * getMessages() will return an array of messages that explain why the * validation failed. * * @param mixed $value * * @return bool * * @throws Exception\RuntimeException If validation of $value is impossible */ public function isValid($value) { if (! is_string($value)) { $this->error(self::NOT_STRING); return false; } $this->setValue($value); if (empty($value) || $value !== '00000000-0000-0000-0000-000000000000' && ! preg_match(self::REGEX_UUID, $value) ) { $this->error(self::INVALID); return false; } return true; } } ================================================ FILE: src/ValidatorChain.php ================================================ validators = new PriorityQueue(); } /** * Return the count of attached validators * * @return int */ public function count() { return count($this->validators); } /** * Get plugin manager instance * * @return ValidatorPluginManager */ public function getPluginManager() { if (! $this->plugins) { $this->setPluginManager(new ValidatorPluginManager(new ServiceManager)); } return $this->plugins; } /** * Set plugin manager instance * * @param ValidatorPluginManager $plugins Plugin manager * @return ValidatorChain */ public function setPluginManager(ValidatorPluginManager $plugins) { $this->plugins = $plugins; return $this; } /** * Retrieve a validator by name * * @param string $name Name of validator to return * @param null|array $options Options to pass to validator constructor (if not already instantiated) * @return ValidatorInterface */ public function plugin($name, array $options = null) { $plugins = $this->getPluginManager(); return $plugins->get($name, $options); } /** * Attach a validator to the end of the chain * * If $breakChainOnFailure is true, then if the validator fails, the next validator in the chain, * if one exists, will not be executed. * * @param ValidatorInterface $validator * @param bool $breakChainOnFailure * @param int $priority Priority at which to enqueue validator; defaults to * 1 (higher executes earlier) * * @throws Exception\InvalidArgumentException * * @return self */ public function attach( ValidatorInterface $validator, $breakChainOnFailure = false, $priority = self::DEFAULT_PRIORITY ) { $this->validators->insert( [ 'instance' => $validator, 'breakChainOnFailure' => (bool) $breakChainOnFailure, ], $priority ); return $this; } /** * Proxy to attach() to keep BC * * @deprecated Please use attach() * @param ValidatorInterface $validator * @param bool $breakChainOnFailure * @param int $priority * @return ValidatorChain Provides a fluent interface */ public function addValidator( ValidatorInterface $validator, $breakChainOnFailure = false, $priority = self::DEFAULT_PRIORITY ) { return $this->attach($validator, $breakChainOnFailure, $priority); } /** * Adds a validator to the beginning of the chain * * If $breakChainOnFailure is true, then if the validator fails, the next validator in the chain, * if one exists, will not be executed. * * @param ValidatorInterface $validator * @param bool $breakChainOnFailure * @return ValidatorChain Provides a fluent interface */ public function prependValidator(ValidatorInterface $validator, $breakChainOnFailure = false) { $priority = self::DEFAULT_PRIORITY; if (! $this->validators->isEmpty()) { $extractedNodes = $this->validators->toArray(PriorityQueue::EXTR_PRIORITY); rsort($extractedNodes, SORT_NUMERIC); $priority = $extractedNodes[0] + 1; } $this->validators->insert( [ 'instance' => $validator, 'breakChainOnFailure' => (bool) $breakChainOnFailure, ], $priority ); return $this; } /** * Use the plugin manager to add a validator by name * * @param string $name * @param array $options * @param bool $breakChainOnFailure * @param int $priority * @return ValidatorChain */ public function attachByName($name, $options = [], $breakChainOnFailure = false, $priority = self::DEFAULT_PRIORITY) { if (isset($options['break_chain_on_failure'])) { $breakChainOnFailure = (bool) $options['break_chain_on_failure']; } if (isset($options['breakchainonfailure'])) { $breakChainOnFailure = (bool) $options['breakchainonfailure']; } $this->attach($this->plugin($name, $options), $breakChainOnFailure, $priority); return $this; } /** * Proxy to attachByName() to keep BC * * @deprecated Please use attachByName() * @param string $name * @param array $options * @param bool $breakChainOnFailure * @return ValidatorChain */ public function addByName($name, $options = [], $breakChainOnFailure = false) { return $this->attachByName($name, $options, $breakChainOnFailure); } /** * Use the plugin manager to prepend a validator by name * * @param string $name * @param array $options * @param bool $breakChainOnFailure * @return ValidatorChain */ public function prependByName($name, $options = [], $breakChainOnFailure = false) { $validator = $this->plugin($name, $options); $this->prependValidator($validator, $breakChainOnFailure); return $this; } /** * Returns true if and only if $value passes all validations in the chain * * Validators are run in the order in which they were added to the chain (FIFO). * * @param mixed $value * @param mixed $context Extra "context" to provide the validator * @return bool */ public function isValid($value, $context = null) { $this->messages = []; $result = true; foreach ($this->validators as $element) { $validator = $element['instance']; if ($validator->isValid($value, $context)) { continue; } $result = false; $messages = $validator->getMessages(); $this->messages = array_replace_recursive($this->messages, $messages); if ($element['breakChainOnFailure']) { break; } } return $result; } /** * Merge the validator chain with the one given in parameter * * @param ValidatorChain $validatorChain * @return ValidatorChain */ public function merge(ValidatorChain $validatorChain) { foreach ($validatorChain->validators->toArray(PriorityQueue::EXTR_BOTH) as $item) { $this->attach($item['data']['instance'], $item['data']['breakChainOnFailure'], $item['priority']); } return $this; } /** * Returns array of validation failure messages * * @return array */ public function getMessages() { return $this->messages; } /** * Get all the validators * * @return array */ public function getValidators() { return $this->validators->toArray(PriorityQueue::EXTR_DATA); } /** * Invoke chain as command * * @param mixed $value * @return bool */ public function __invoke($value) { return $this->isValid($value); } /** * Deep clone handling */ public function __clone() { $this->validators = clone $this->validators; } /** * Prepare validator chain for serialization * * Plugin manager (property 'plugins') cannot * be serialized. On wakeup the property remains unset * and next invocation to getPluginManager() sets * the default plugin manager instance (ValidatorPluginManager). * * @return array */ public function __sleep() { return ['validators', 'messages']; } } ================================================ FILE: src/ValidatorInterface.php ================================================ I18nValidator\Alnum::class, 'Alnum' => I18nValidator\Alnum::class, 'alpha' => I18nValidator\Alpha::class, 'Alpha' => I18nValidator\Alpha::class, 'barcode' => Barcode::class, 'Barcode' => Barcode::class, 'between' => Between::class, 'Between' => Between::class, 'bitwise' => Bitwise::class, 'Bitwise' => Bitwise::class, 'callback' => Callback::class, 'Callback' => Callback::class, 'creditcard' => CreditCard::class, 'creditCard' => CreditCard::class, 'CreditCard' => CreditCard::class, 'csrf' => Csrf::class, 'Csrf' => Csrf::class, 'date' => Date::class, 'Date' => Date::class, 'datestep' => DateStep::class, 'dateStep' => DateStep::class, 'DateStep' => DateStep::class, 'datetime' => I18nValidator\DateTime::class, 'dateTime' => I18nValidator\DateTime::class, 'DateTime' => I18nValidator\DateTime::class, 'dbnorecordexists' => Db\NoRecordExists::class, 'dbNoRecordExists' => Db\NoRecordExists::class, 'DbNoRecordExists' => Db\NoRecordExists::class, 'dbrecordexists' => Db\RecordExists::class, 'dbRecordExists' => Db\RecordExists::class, 'DbRecordExists' => Db\RecordExists::class, 'digits' => Digits::class, 'Digits' => Digits::class, 'emailaddress' => EmailAddress::class, 'emailAddress' => EmailAddress::class, 'EmailAddress' => EmailAddress::class, 'explode' => Explode::class, 'Explode' => Explode::class, 'filecount' => File\Count::class, 'fileCount' => File\Count::class, 'FileCount' => File\Count::class, 'filecrc32' => File\Crc32::class, 'fileCrc32' => File\Crc32::class, 'FileCrc32' => File\Crc32::class, 'fileexcludeextension' => File\ExcludeExtension::class, 'fileExcludeExtension' => File\ExcludeExtension::class, 'FileExcludeExtension' => File\ExcludeExtension::class, 'fileexcludemimetype' => File\ExcludeMimeType::class, 'fileExcludeMimeType' => File\ExcludeMimeType::class, 'FileExcludeMimeType' => File\ExcludeMimeType::class, 'fileexists' => File\Exists::class, 'fileExists' => File\Exists::class, 'FileExists' => File\Exists::class, 'fileextension' => File\Extension::class, 'fileExtension' => File\Extension::class, 'FileExtension' => File\Extension::class, 'filefilessize' => File\FilesSize::class, 'fileFilesSize' => File\FilesSize::class, 'FileFilesSize' => File\FilesSize::class, 'filehash' => File\Hash::class, 'fileHash' => File\Hash::class, 'FileHash' => File\Hash::class, 'fileimagesize' => File\ImageSize::class, 'fileImageSize' => File\ImageSize::class, 'FileImageSize' => File\ImageSize::class, 'fileiscompressed' => File\IsCompressed::class, 'fileIsCompressed' => File\IsCompressed::class, 'FileIsCompressed' => File\IsCompressed::class, 'fileisimage' => File\IsImage::class, 'fileIsImage' => File\IsImage::class, 'FileIsImage' => File\IsImage::class, 'filemd5' => File\Md5::class, 'fileMd5' => File\Md5::class, 'FileMd5' => File\Md5::class, 'filemimetype' => File\MimeType::class, 'fileMimeType' => File\MimeType::class, 'FileMimeType' => File\MimeType::class, 'filenotexists' => File\NotExists::class, 'fileNotExists' => File\NotExists::class, 'FileNotExists' => File\NotExists::class, 'filesha1' => File\Sha1::class, 'fileSha1' => File\Sha1::class, 'FileSha1' => File\Sha1::class, 'filesize' => File\Size::class, 'fileSize' => File\Size::class, 'FileSize' => File\Size::class, 'fileupload' => File\Upload::class, 'fileUpload' => File\Upload::class, 'FileUpload' => File\Upload::class, 'fileuploadfile' => File\UploadFile::class, 'fileUploadFile' => File\UploadFile::class, 'FileUploadFile' => File\UploadFile::class, 'filewordcount' => File\WordCount::class, 'fileWordCount' => File\WordCount::class, 'FileWordCount' => File\WordCount::class, 'float' => I18nValidator\IsFloat::class, 'Float' => I18nValidator\IsFloat::class, 'gpspoint' => GpsPoint::class, 'gpsPoint' => GpsPoint::class, 'GpsPoint' => GpsPoint::class, 'greaterthan' => GreaterThan::class, 'greaterThan' => GreaterThan::class, 'GreaterThan' => GreaterThan::class, 'hex' => Hex::class, 'Hex' => Hex::class, 'hostname' => Hostname::class, 'Hostname' => Hostname::class, 'iban' => Iban::class, 'Iban' => Iban::class, 'identical' => Identical::class, 'Identical' => Identical::class, 'inarray' => InArray::class, 'inArray' => InArray::class, 'InArray' => InArray::class, 'int' => I18nValidator\IsInt::class, 'Int' => I18nValidator\IsInt::class, 'ip' => Ip::class, 'Ip' => Ip::class, 'isbn' => Isbn::class, 'Isbn' => Isbn::class, 'isfloat' => I18nValidator\IsFloat::class, 'isFloat' => I18nValidator\IsFloat::class, 'IsFloat' => I18nValidator\IsFloat::class, 'isinstanceof' => IsInstanceOf::class, 'isInstanceOf' => IsInstanceOf::class, 'IsInstanceOf' => IsInstanceOf::class, 'isint' => I18nValidator\IsInt::class, 'isInt' => I18nValidator\IsInt::class, 'IsInt' => I18nValidator\IsInt::class, 'lessthan' => LessThan::class, 'lessThan' => LessThan::class, 'LessThan' => LessThan::class, 'notempty' => NotEmpty::class, 'notEmpty' => NotEmpty::class, 'NotEmpty' => NotEmpty::class, 'phonenumber' => I18nValidator\PhoneNumber::class, 'phoneNumber' => I18nValidator\PhoneNumber::class, 'PhoneNumber' => I18nValidator\PhoneNumber::class, 'postcode' => I18nValidator\PostCode::class, 'postCode' => I18nValidator\PostCode::class, 'PostCode' => I18nValidator\PostCode::class, 'regex' => Regex::class, 'Regex' => Regex::class, 'sitemapchangefreq' => Sitemap\Changefreq::class, 'sitemapChangefreq' => Sitemap\Changefreq::class, 'SitemapChangefreq' => Sitemap\Changefreq::class, 'sitemaplastmod' => Sitemap\Lastmod::class, 'sitemapLastmod' => Sitemap\Lastmod::class, 'SitemapLastmod' => Sitemap\Lastmod::class, 'sitemaploc' => Sitemap\Loc::class, 'sitemapLoc' => Sitemap\Loc::class, 'SitemapLoc' => Sitemap\Loc::class, 'sitemappriority' => Sitemap\Priority::class, 'sitemapPriority' => Sitemap\Priority::class, 'SitemapPriority' => Sitemap\Priority::class, 'stringlength' => StringLength::class, 'stringLength' => StringLength::class, 'StringLength' => StringLength::class, 'step' => Step::class, 'Step' => Step::class, 'timezone' => Timezone::class, 'Timezone' => Timezone::class, 'uri' => Uri::class, 'Uri' => Uri::class, 'uuid' => Uuid::class, 'Uuid' => Uuid::class, ]; /** * Default set of factories * * @var array */ protected $factories = [ I18nValidator\Alnum::class => InvokableFactory::class, I18nValidator\Alpha::class => InvokableFactory::class, Barcode::class => InvokableFactory::class, Between::class => InvokableFactory::class, Bitwise::class => InvokableFactory::class, Callback::class => InvokableFactory::class, CreditCard::class => InvokableFactory::class, Csrf::class => InvokableFactory::class, DateStep::class => InvokableFactory::class, Date::class => InvokableFactory::class, I18nValidator\DateTime::class => InvokableFactory::class, Db\NoRecordExists::class => InvokableFactory::class, Db\RecordExists::class => InvokableFactory::class, Digits::class => InvokableFactory::class, EmailAddress::class => InvokableFactory::class, Explode::class => InvokableFactory::class, File\Count::class => InvokableFactory::class, File\Crc32::class => InvokableFactory::class, File\ExcludeExtension::class => InvokableFactory::class, File\ExcludeMimeType::class => InvokableFactory::class, File\Exists::class => InvokableFactory::class, File\Extension::class => InvokableFactory::class, File\FilesSize::class => InvokableFactory::class, File\Hash::class => InvokableFactory::class, File\ImageSize::class => InvokableFactory::class, File\IsCompressed::class => InvokableFactory::class, File\IsImage::class => InvokableFactory::class, File\Md5::class => InvokableFactory::class, File\MimeType::class => InvokableFactory::class, File\NotExists::class => InvokableFactory::class, File\Sha1::class => InvokableFactory::class, File\Size::class => InvokableFactory::class, File\Upload::class => InvokableFactory::class, File\UploadFile::class => InvokableFactory::class, File\WordCount::class => InvokableFactory::class, I18nValidator\IsFloat::class => InvokableFactory::class, GpsPoint::class => InvokableFactory::class, GreaterThan::class => InvokableFactory::class, Hex::class => InvokableFactory::class, Hostname::class => InvokableFactory::class, Iban::class => InvokableFactory::class, Identical::class => InvokableFactory::class, InArray::class => InvokableFactory::class, I18nValidator\IsInt::class => InvokableFactory::class, Ip::class => InvokableFactory::class, Isbn::class => InvokableFactory::class, I18nValidator\IsFloat::class => InvokableFactory::class, IsInstanceOf::class => InvokableFactory::class, I18nValidator\IsInt::class => InvokableFactory::class, LessThan::class => InvokableFactory::class, NotEmpty::class => InvokableFactory::class, I18nValidator\PhoneNumber::class => InvokableFactory::class, I18nValidator\PostCode::class => InvokableFactory::class, Regex::class => InvokableFactory::class, Sitemap\Changefreq::class => InvokableFactory::class, Sitemap\Lastmod::class => InvokableFactory::class, Sitemap\Loc::class => InvokableFactory::class, Sitemap\Priority::class => InvokableFactory::class, StringLength::class => InvokableFactory::class, Step::class => InvokableFactory::class, Timezone::class => InvokableFactory::class, Uri::class => InvokableFactory::class, Uuid::class => InvokableFactory::class, // v2 canonical FQCNs 'zendvalidatorbarcodecode25interleaved' => InvokableFactory::class, 'zendvalidatorbarcodecode25' => InvokableFactory::class, 'zendvalidatorbarcodecode39ext' => InvokableFactory::class, 'zendvalidatorbarcodecode39' => InvokableFactory::class, 'zendvalidatorbarcodecode93ext' => InvokableFactory::class, 'zendvalidatorbarcodecode93' => InvokableFactory::class, 'zendvalidatorbarcodeean12' => InvokableFactory::class, 'zendvalidatorbarcodeean13' => InvokableFactory::class, 'zendvalidatorbarcodeean14' => InvokableFactory::class, 'zendvalidatorbarcodeean18' => InvokableFactory::class, 'zendvalidatorbarcodeean2' => InvokableFactory::class, 'zendvalidatorbarcodeean5' => InvokableFactory::class, 'zendvalidatorbarcodeean8' => InvokableFactory::class, 'zendvalidatorbarcodegtin12' => InvokableFactory::class, 'zendvalidatorbarcodegtin13' => InvokableFactory::class, 'zendvalidatorbarcodegtin14' => InvokableFactory::class, 'zendvalidatorbarcodeidentcode' => InvokableFactory::class, 'zendvalidatorbarcodeintelligentmail' => InvokableFactory::class, 'zendvalidatorbarcodeissn' => InvokableFactory::class, 'zendvalidatorbarcodeitf14' => InvokableFactory::class, 'zendvalidatorbarcodeleitcode' => InvokableFactory::class, 'zendvalidatorbarcodeplanet' => InvokableFactory::class, 'zendvalidatorbarcodepostnet' => InvokableFactory::class, 'zendvalidatorbarcoderoyalmail' => InvokableFactory::class, 'zendvalidatorbarcodesscc' => InvokableFactory::class, 'zendvalidatorbarcodeupca' => InvokableFactory::class, 'zendvalidatorbarcodeupce' => InvokableFactory::class, 'zendvalidatorbarcode' => InvokableFactory::class, 'zendvalidatorbetween' => InvokableFactory::class, 'zendvalidatorbitwise' => InvokableFactory::class, 'zendvalidatorcallback' => InvokableFactory::class, 'zendvalidatorcreditcard' => InvokableFactory::class, 'zendvalidatorcsrf' => InvokableFactory::class, 'zendvalidatordatestep' => InvokableFactory::class, 'zendvalidatordate' => InvokableFactory::class, 'zendvalidatordbnorecordexists' => InvokableFactory::class, 'zendvalidatordbrecordexists' => InvokableFactory::class, 'zendvalidatordigits' => InvokableFactory::class, 'zendvalidatoremailaddress' => InvokableFactory::class, 'zendvalidatorexplode' => InvokableFactory::class, 'zendvalidatorfilecount' => InvokableFactory::class, 'zendvalidatorfilecrc32' => InvokableFactory::class, 'zendvalidatorfileexcludeextension' => InvokableFactory::class, 'zendvalidatorfileexcludemimetype' => InvokableFactory::class, 'zendvalidatorfileexists' => InvokableFactory::class, 'zendvalidatorfileextension' => InvokableFactory::class, 'zendvalidatorfilefilessize' => InvokableFactory::class, 'zendvalidatorfilehash' => InvokableFactory::class, 'zendvalidatorfileimagesize' => InvokableFactory::class, 'zendvalidatorfileiscompressed' => InvokableFactory::class, 'zendvalidatorfileisimage' => InvokableFactory::class, 'zendvalidatorfilemd5' => InvokableFactory::class, 'zendvalidatorfilemimetype' => InvokableFactory::class, 'zendvalidatorfilenotexists' => InvokableFactory::class, 'zendvalidatorfilesha1' => InvokableFactory::class, 'zendvalidatorfilesize' => InvokableFactory::class, 'zendvalidatorfileupload' => InvokableFactory::class, 'zendvalidatorfileuploadfile' => InvokableFactory::class, 'zendvalidatorfilewordcount' => InvokableFactory::class, 'zendvalidatorgpspoint' => InvokableFactory::class, 'zendvalidatorgreaterthan' => InvokableFactory::class, 'zendvalidatorhex' => InvokableFactory::class, 'zendvalidatorhostname' => InvokableFactory::class, 'zendi18nvalidatoralnum' => InvokableFactory::class, 'zendi18nvalidatoralpha' => InvokableFactory::class, 'zendi18nvalidatordatetime' => InvokableFactory::class, 'zendi18nvalidatorisfloat' => InvokableFactory::class, 'zendi18nvalidatorisint' => InvokableFactory::class, 'zendi18nvalidatorphonenumber' => InvokableFactory::class, 'zendi18nvalidatorpostcode' => InvokableFactory::class, 'zendvalidatoriban' => InvokableFactory::class, 'zendvalidatoridentical' => InvokableFactory::class, 'zendvalidatorinarray' => InvokableFactory::class, 'zendvalidatorip' => InvokableFactory::class, 'zendvalidatorisbn' => InvokableFactory::class, 'zendvalidatorisinstanceof' => InvokableFactory::class, 'zendvalidatorlessthan' => InvokableFactory::class, 'zendvalidatornotempty' => InvokableFactory::class, 'zendvalidatorregex' => InvokableFactory::class, 'zendvalidatorsitemapchangefreq' => InvokableFactory::class, 'zendvalidatorsitemaplastmod' => InvokableFactory::class, 'zendvalidatorsitemaploc' => InvokableFactory::class, 'zendvalidatorsitemappriority' => InvokableFactory::class, 'zendvalidatorstringlength' => InvokableFactory::class, 'zendvalidatorstep' => InvokableFactory::class, 'zendvalidatortimezone' => InvokableFactory::class, 'zendvalidatoruri' => InvokableFactory::class, 'zendvalidatoruuid' => InvokableFactory::class, ]; /** * Whether or not to share by default; default to false (v2) * * @var bool */ protected $shareByDefault = false; /** * Whether or not to share by default; default to false (v3) * * @var bool */ protected $sharedByDefault = false; /** * Default instance type * * @var string */ protected $instanceOf = ValidatorInterface::class; /** * Constructor * * After invoking parent constructor, add an initializer to inject the * attached translator, if any, to the currently requested helper. * * {@inheritDoc} */ public function __construct($configOrContainerInstance = null, array $v3config = []) { parent::__construct($configOrContainerInstance, $v3config); $this->addInitializer([$this, 'injectTranslator']); $this->addInitializer([$this, 'injectValidatorPluginManager']); } /** * Validate plugin instance * * {@inheritDoc} */ public function validate($plugin) { if (! $plugin instanceof $this->instanceOf) { throw new InvalidServiceException(sprintf( '%s expects only to create instances of %s; %s is invalid', get_class($this), $this->instanceOf, (is_object($plugin) ? get_class($plugin) : gettype($plugin)) )); } } /** * For v2 compatibility: validate plugin instance. * * Proxies to `validate()`. * * @param mixed $plugin * @throws Exception\RuntimeException */ public function validatePlugin($plugin) { try { $this->validate($plugin); } catch (InvalidServiceException $e) { throw new Exception\RuntimeException(sprintf( 'Plugin of type %s is invalid; must implement %s', (is_object($plugin) ? get_class($plugin) : gettype($plugin)), ValidatorInterface::class ), $e->getCode(), $e); } } /** * Inject a validator instance with the registered translator * * @param ContainerInterface|object $first * @param ContainerInterface|object $second * @return void */ public function injectTranslator($first, $second) { if ($first instanceof ContainerInterface) { $container = $first; $validator = $second; } else { $container = $second; $validator = $first; } // V2 means we pull it from the parent container if ($container === $this && method_exists($container, 'getServiceLocator') && $container->getServiceLocator()) { $container = $container->getServiceLocator(); } if ($validator instanceof Translator\TranslatorAwareInterface) { if ($container && $container->has('MvcTranslator')) { $validator->setTranslator($container->get('MvcTranslator')); } } } /** * Inject a validator plugin manager * * @param ContainerInterface|object $first * @param ContainerInterface|object $second * @return void */ public function injectValidatorPluginManager($first, $second) { if ($first instanceof ContainerInterface) { $container = $first; $validator = $second; } else { $container = $second; $validator = $first; } if ($validator instanceof ValidatorPluginManagerAwareInterface) { $validator->setValidatorPluginManager($this); } } } ================================================ FILE: src/ValidatorPluginManagerAwareInterface.php ================================================ has('ServiceListener')) { return $pluginManager; } // If we do not have a config service, nothing more to do if (! $container->has('config')) { return $pluginManager; } $config = $container->get('config'); // If we do not have validators configuration, nothing more to do if (! isset($config['validators']) || ! is_array($config['validators'])) { return $pluginManager; } // Wire service configuration for validators (new Config($config['validators']))->configureServiceManager($pluginManager); return $pluginManager; } /** * {@inheritDoc} * * @return ValidatorPluginManager */ public function createService(ServiceLocatorInterface $container, $name = null, $requestedName = null) { return $this($container, $requestedName ?: ValidatorPluginManager::class, $this->creationOptions); } /** * zend-servicemanager v2 support for invocation options. * * @param array $options * @return void */ public function setCreationOptions(array $options) { $this->creationOptions = $options; } } ================================================ FILE: src/ValidatorProviderInterface.php ================================================ validator = new TestAsset\ConcreteValidator(); } public function tearDown() { AbstractValidator::setDefaultTranslator(null, 'default'); } public function testTranslatorNullByDefault() { $this->assertNull($this->validator->getTranslator()); } public function testCanSetTranslator() { $this->testTranslatorNullByDefault(); set_error_handler([$this, 'errorHandlerIgnore']); $translator = new TestAsset\Translator(); restore_error_handler(); $this->validator->setTranslator($translator); $this->assertSame($translator, $this->validator->getTranslator()); } public function testCanSetTranslatorToNull() { $this->testCanSetTranslator(); set_error_handler([$this, 'errorHandlerIgnore']); $this->validator->setTranslator(null); restore_error_handler(); $this->assertNull($this->validator->getTranslator()); } public function testErrorMessagesAreTranslatedWhenTranslatorPresent() { if (! extension_loaded('intl')) { $this->markTestSkipped('ext/intl not enabled'); } $loader = new TestAsset\ArrayTranslator(); $loader->translations = [ '%value% was passed' => 'This is the translated message for %value%', ]; $translator = new TestAsset\Translator(); $translator->getPluginManager()->setService('default', $loader); $translator->addTranslationFile('default', null); $this->validator->setTranslator($translator); $this->assertFalse($this->validator->isValid('bar')); $messages = $this->validator->getMessages(); $this->assertArrayHasKey('fooMessage', $messages); $this->assertContains('bar', $messages['fooMessage'], var_export($messages, 1)); $this->assertContains('This is the translated message for ', $messages['fooMessage']); } public function testObscureValueFlagFalseByDefault() { $this->assertFalse($this->validator->isValueObscured()); } public function testCanSetValueObscuredFlag() { $this->testObscureValueFlagFalseByDefault(); $this->validator->setValueObscured(true); $this->assertTrue($this->validator->isValueObscured()); $this->validator->setValueObscured(false); $this->assertFalse($this->validator->isValueObscured()); } public function testValueIsObfuscatedWheObscureValueFlagIsTrue() { $this->validator->setValueObscured(true); $this->assertFalse($this->validator->isValid('foobar')); $messages = $this->validator->getMessages(); $this->assertTrue(isset($messages['fooMessage'])); $message = $messages['fooMessage']; $this->assertNotContains('foobar', $message); $this->assertContains('******', $message); } /** * @group ZF-4463 */ public function testDoesNotFailOnObjectInput() { $this->assertFalse($this->validator->isValid(new \stdClass())); $messages = $this->validator->getMessages(); $this->assertArrayHasKey('fooMessage', $messages); } public function testTranslatorEnabledPerDefault() { set_error_handler([$this, 'errorHandlerIgnore']); $translator = new TestAsset\Translator(); $this->validator->setTranslator($translator); $this->assertTrue($this->validator->isTranslatorEnabled()); } public function testCanDisableTranslator() { if (! extension_loaded('intl')) { $this->markTestSkipped('ext/intl not enabled'); } $loader = new TestAsset\ArrayTranslator(); $loader->translations = [ '%value% was passed' => 'This is the translated message for %value%', ]; $translator = new TestAsset\Translator(); $translator->getPluginManager()->setService('default', $loader); $translator->addTranslationFile('default', null); $this->validator->setTranslator($translator); $this->assertFalse($this->validator->isValid('bar')); $messages = $this->validator->getMessages(); $this->assertArrayHasKey('fooMessage', $messages); $this->assertContains('bar', $messages['fooMessage']); $this->assertContains('This is the translated message for ', $messages['fooMessage']); $this->validator->setTranslatorEnabled(false); $this->assertFalse($this->validator->isTranslatorEnabled()); $this->assertFalse($this->validator->isValid('bar')); $messages = $this->validator->getMessages(); $this->assertArrayHasKey('fooMessage', $messages); $this->assertContains('bar', $messages['fooMessage']); $this->assertContains('bar was passed', $messages['fooMessage']); } public function testGetMessageTemplates() { $messages = $this->validator->getMessageTemplates(); $this->assertEquals([ 'fooMessage' => '%value% was passed', 'barMessage' => '%value% was wrong' ], $messages); $this->assertEquals([ TestAsset\ConcreteValidator::FOO_MESSAGE => '%value% was passed', TestAsset\ConcreteValidator::BAR_MESSAGE => '%value% was wrong' ], $messages); } public function testInvokeProxiesToIsValid() { $validator = new TestAsset\ConcreteValidator; $this->assertFalse($validator('foo')); $this->assertContains("foo was passed", $validator->getMessages()); } public function testTranslatorMethods() { $translatorMock = $this->createMock(TestAsset\Translator::class); $this->validator->setTranslator($translatorMock, 'foo'); $this->assertEquals($translatorMock, $this->validator->getTranslator()); $this->assertEquals('foo', $this->validator->getTranslatorTextDomain()); $this->assertTrue($this->validator->hasTranslator()); $this->assertTrue($this->validator->isTranslatorEnabled()); $this->validator->setTranslatorEnabled(false); $this->assertFalse($this->validator->isTranslatorEnabled()); } public function testDefaultTranslatorMethods() { $this->assertFalse(AbstractValidator::hasDefaultTranslator()); $this->assertNull(AbstractValidator::getDefaultTranslator()); $this->assertEquals('default', AbstractValidator::getDefaultTranslatorTextDomain()); $this->assertFalse($this->validator->hasTranslator()); $translatorMock = $this->createMock(TestAsset\Translator::class); AbstractValidator::setDefaultTranslator($translatorMock, 'foo'); $this->assertEquals($translatorMock, AbstractValidator::getDefaultTranslator()); $this->assertEquals($translatorMock, $this->validator->getTranslator()); $this->assertEquals('foo', AbstractValidator::getDefaultTranslatorTextDomain()); $this->assertEquals('foo', $this->validator->getTranslatorTextDomain()); $this->assertTrue(AbstractValidator::hasDefaultTranslator()); } public function testMessageCreationWithNestedArrayValueDoesNotRaiseNotice() { $r = new ReflectionMethod($this->validator, 'createMessage'); $r->setAccessible(true); $message = $r->invoke($this->validator, 'fooMessage', ['foo' => ['bar' => 'baz']]); $this->assertContains('foo', $message); $this->assertContains('bar', $message); $this->assertContains('baz', $message); } public function testNonIdenticalMessagesAllReturned() { $this->assertFalse($this->validator->isValid('invalid')); $messages = $this->validator->getMessages(); $this->assertCount(2, $messages); $this->assertEquals([ TestAsset\ConcreteValidator::FOO_MESSAGE => 'invalid was passed', TestAsset\ConcreteValidator::BAR_MESSAGE => 'invalid was wrong' ], $messages); } public function testIdenticalMessagesNotReturned() { $this->validator->setMessage('Default error message'); $this->assertFalse($this->validator->isValid('invalid')); $messages = $this->validator->getMessages(); $this->assertCount(1, $messages); $this->assertEquals('Default error message', reset($messages)); } public function testIdenticalAndNonIdenticalMessagesReturned() { $validator = new EmailAddress(); $this->assertFalse($validator->isValid('invalid@email.coma')); $this->assertCount(3, $validator->getMessages()); $this->assertArrayHasKey(EmailAddress::INVALID_HOSTNAME, $validator->getMessages()); $this->assertArrayHasKey(Hostname::UNKNOWN_TLD, $validator->getMessages()); $this->assertArrayHasKey(Hostname::LOCAL_NAME_NOT_ALLOWED, $validator->getMessages()); $validator->setMessages([ EmailAddress::INVALID_HOSTNAME => 'This is the same error message', Hostname::UNKNOWN_TLD => 'This is the same error message' ]); $this->assertFalse($validator->isValid('invalid@email.coma')); $this->assertCount(2, $validator->getMessages()); $this->assertArrayHasKey(EmailAddress::INVALID_HOSTNAME, $validator->getMessages()); $this->assertArrayHasKey(Hostname::LOCAL_NAME_NOT_ALLOWED, $validator->getMessages()); } /** * Ignores a raised PHP error when in effect, but throws a flag to indicate an error occurred * * @param integer $errno * @param string $errstr * @param string $errfile * @param integer $errline * @param array $errcontext * @return void */ public function errorHandlerIgnore($errno, $errstr, $errfile, $errline, array $errcontext) { $this->errorOccurred = true; } public function testRetrievingUnknownOptionRaisesException() { $option = 'foo'; $this->expectException(InvalidArgumentException::class); $this->expectExceptionMessage(sprintf("Invalid option '%s'", $option)); $this->validator->getOption($option); } public function invalidOptionsArguments() { return [ 'null' => [null], 'true' => [true], 'false' => [false], 'zero' => [0], 'int' => [1], 'zero-float' => [0.0], 'float' => [1.1], 'string' => ['string'], 'object' => [(object) []], ]; } /** * @dataProvider invalidOptionsArguments */ public function testSettingOptionsWithNonTraversableRaisesException($options) { $this->expectException(InvalidArgumentException::class); $this->expectExceptionMessage('setOptions expects an array or Traversable'); $this->validator->setOptions($options); } } ================================================ FILE: test/BarcodeTest.php ================================================ [null, Barcode\Ean13::class], 'empty-array' => [[], Barcode\Ean13::class], ]; } /** * @dataProvider provideBarcodeConstructor */ public function testBarcodeConstructor($options, $expectedInstance) { $barcode = new Barcode($options); $this->assertInstanceOf($expectedInstance, $barcode->getAdapter()); } public function testNoneExisting() { $this->expectException(InvalidArgumentException::class); $this->expectExceptionMessage('not found'); $barcode = new Barcode('\Zend\Validate\BarcodeTest\NonExistentClassName'); } public function testSetAdapter() { $barcode = new Barcode('upca'); $this->assertTrue($barcode->isValid('065100004327')); $barcode->setAdapter('ean13'); $this->assertTrue($barcode->isValid('0075678164125')); } public function testSetCustomAdapter() { $barcode = new Barcode([ 'adapter' => $this->createMock(AdapterInterface::class) ]); $this->assertInstanceOf(AdapterInterface::class, $barcode->getAdapter()); } /** * @ZF-4352 */ public function testNonStringValidation() { $barcode = new Barcode('upca'); $this->assertFalse($barcode->isValid(106510000.4327)); $this->assertFalse($barcode->isValid(['065100004327'])); $barcode = new Barcode('ean13'); $this->assertFalse($barcode->isValid(06510000.4327)); $this->assertFalse($barcode->isValid(['065100004327'])); } public function testInvalidChecksumAdapter() { require_once __DIR__ . "/_files/MyBarcode1.php"; $barcode = new Barcode('MyBarcode1'); $this->assertFalse($barcode->isValid('0000000')); $this->assertArrayHasKey('barcodeFailed', $barcode->getMessages()); $this->assertFalse($barcode->getAdapter()->hasValidChecksum('0000000')); } public function testInvalidCharAdapter() { require_once __DIR__ . "/_files/MyBarcode1.php"; $barcode = new Barcode('MyBarcode1'); $this->assertFalse($barcode->getAdapter()->hasValidCharacters(123)); } public function testAscii128CharacterAdapter() { require_once __DIR__ . "/_files/MyBarcode2.php"; $barcode = new Barcode('MyBarcode2'); $this->assertTrue($barcode->getAdapter()->hasValidCharacters('1234QW!"')); } public function testInvalidLengthAdapter() { require_once __DIR__ . "/_files/MyBarcode2.php"; $barcode = new Barcode('MyBarcode2'); $this->assertFalse($barcode->getAdapter()->hasValidLength(123)); } public function testArrayLengthAdapter() { require_once __DIR__ . "/_files/MyBarcode2.php"; $barcode = new Barcode('MyBarcode2'); $this->assertTrue($barcode->getAdapter()->hasValidLength('1')); $this->assertFalse($barcode->getAdapter()->hasValidLength('12')); $this->assertTrue($barcode->getAdapter()->hasValidLength('123')); $this->assertFalse($barcode->getAdapter()->hasValidLength('1234')); } public function testArrayLengthAdapter2() { require_once __DIR__ . "/_files/MyBarcode3.php"; $barcode = new Barcode('MyBarcode3'); $this->assertTrue($barcode->getAdapter()->hasValidLength('1')); $this->assertTrue($barcode->getAdapter()->hasValidLength('12')); $this->assertTrue($barcode->getAdapter()->hasValidLength('123')); $this->assertTrue($barcode->getAdapter()->hasValidLength('1234')); } public function testOddLengthAdapter() { require_once __DIR__ . "/_files/MyBarcode4.php"; $barcode = new Barcode('MyBarcode4'); $this->assertTrue($barcode->getAdapter()->hasValidLength('1')); $this->assertFalse($barcode->getAdapter()->hasValidLength('12')); $this->assertTrue($barcode->getAdapter()->hasValidLength('123')); $this->assertFalse($barcode->getAdapter()->hasValidLength('1234')); } public function testInvalidAdapter() { $barcode = new Barcode('Ean13'); $this->expectException(InvalidArgumentException::class); $this->expectExceptionMessage('does not implement'); require_once __DIR__ . "/_files/MyBarcode5.php"; $barcode->setAdapter('MyBarcode5'); } public function testArrayConstructAdapter() { $barcode = new Barcode(['adapter' => 'Ean13', 'options' => 'unknown', 'useChecksum' => false]); $this->assertInstanceOf(Ean13::class, $barcode->getAdapter()); $this->assertFalse($barcode->useChecksum()); } public function testDefaultArrayConstructWithMissingAdapter() { $barcode = new Barcode(['options' => 'unknown', 'checksum' => false]); $this->assertTrue($barcode->isValid('0075678164125')); } public function testConfigConstructAdapter() { $array = ['adapter' => 'Ean13', 'options' => 'unknown', 'useChecksum' => false]; $config = new \Zend\Config\Config($array); $barcode = new Barcode($config); $this->assertTrue($barcode->isValid('0075678164125')); } public function testCODE25() { $barcode = new Barcode('code25'); $this->assertTrue($barcode->isValid('0123456789101213')); $this->assertTrue($barcode->isValid('123')); $this->assertFalse($barcode->isValid('123a')); $barcode->useChecksum(true); $this->assertTrue($barcode->isValid('0123456789101214')); $this->assertFalse($barcode->isValid('0123456789101213')); } public function testCODE25INTERLEAVED() { $barcode = new Barcode('code25interleaved'); $this->assertTrue($barcode->isValid('0123456789101213')); $this->assertFalse($barcode->isValid('123')); $barcode->useChecksum(true); $this->assertTrue($barcode->isValid('0123456789101214')); $this->assertFalse($barcode->isValid('0123456789101213')); } public function testCODE39() { $barcode = new Barcode('code39'); $this->assertTrue($barcode->isValid('TEST93TEST93TEST93TEST93Y+')); $this->assertTrue($barcode->isValid('00075678164124')); $this->assertFalse($barcode->isValid('Test93Test93Test')); $barcode->useChecksum(true); $this->assertTrue($barcode->isValid('159AZH')); $this->assertFalse($barcode->isValid('159AZG')); } public function testCODE39EXT() { $barcode = new Barcode('code39ext'); $this->assertTrue($barcode->isValid('TEST93TEST93TEST93TEST93Y+')); $this->assertTrue($barcode->isValid('00075678164124')); $this->assertTrue($barcode->isValid('Test93Test93Test')); // @TODO: CODE39 EXTENDED CHECKSUM VALIDATION MISSING // $barcode->useChecksum(true); // $this->assertTrue($barcode->isValid('159AZH')); // $this->assertFalse($barcode->isValid('159AZG')); } public function testCODE93() { $barcode = new Barcode('code93'); $this->assertTrue($barcode->isValid('TEST93+')); $this->assertFalse($barcode->isValid('Test93+')); $barcode->useChecksum(true); $this->assertTrue($barcode->isValid('CODE 93E0')); $this->assertFalse($barcode->isValid('CODE 93E1')); } public function testCODE93EXT() { $barcode = new Barcode('code93ext'); $this->assertTrue($barcode->isValid('TEST93+')); $this->assertTrue($barcode->isValid('Test93+')); // @TODO: CODE93 EXTENDED CHECKSUM VALIDATION MISSING // $barcode->useChecksum(true); // $this->assertTrue($barcode->isValid('CODE 93E0')); // $this->assertFalse($barcode->isValid('CODE 93E1')); } public function testEAN2() { $barcode = new Barcode('ean2'); $this->assertTrue($barcode->isValid('12')); $this->assertFalse($barcode->isValid('1')); $this->assertFalse($barcode->isValid('123')); } public function testEAN5() { $barcode = new Barcode('ean5'); $this->assertTrue($barcode->isValid('12345')); $this->assertFalse($barcode->isValid('1234')); $this->assertFalse($barcode->isValid('123456')); } public function testEAN8() { $barcode = new Barcode('ean8'); $this->assertTrue($barcode->isValid('12345670')); $this->assertFalse($barcode->isValid('123')); $this->assertFalse($barcode->isValid('12345671')); $this->assertTrue($barcode->isValid('1234567')); } public function testEAN12() { $barcode = new Barcode('ean12'); $this->assertTrue($barcode->isValid('123456789012')); $this->assertFalse($barcode->isValid('123')); $this->assertFalse($barcode->isValid('123456789013')); } public function testEAN13() { $barcode = new Barcode('ean13'); $this->assertTrue($barcode->isValid('1234567890128')); $this->assertFalse($barcode->isValid('123')); $this->assertFalse($barcode->isValid('1234567890127')); } public function testEAN14() { $barcode = new Barcode('ean14'); $this->assertTrue($barcode->isValid('12345678901231')); $this->assertFalse($barcode->isValid('123')); $this->assertFalse($barcode->isValid('12345678901232')); } public function testEAN18() { $barcode = new Barcode('ean18'); $this->assertTrue($barcode->isValid('123456789012345675')); $this->assertFalse($barcode->isValid('123')); $this->assertFalse($barcode->isValid('123456789012345676')); } public function testGTIN12() { $barcode = new Barcode('gtin12'); $this->assertTrue($barcode->isValid('123456789012')); $this->assertFalse($barcode->isValid('123')); $this->assertFalse($barcode->isValid('123456789013')); } public function testGTIN13() { $barcode = new Barcode('gtin13'); $this->assertTrue($barcode->isValid('1234567890128')); $this->assertFalse($barcode->isValid('123')); $this->assertFalse($barcode->isValid('1234567890127')); } public function testGTIN14() { $barcode = new Barcode('gtin14'); $this->assertTrue($barcode->isValid('12345678901231')); $this->assertFalse($barcode->isValid('123')); $this->assertFalse($barcode->isValid('12345678901232')); } public function testIDENTCODE() { $barcode = new Barcode('identcode'); $this->assertTrue($barcode->isValid('564000000050')); $this->assertFalse($barcode->isValid('123')); $this->assertFalse($barcode->isValid('0563102430313')); $this->assertFalse($barcode->isValid('564000000051')); } public function testINTELLIGENTMAIL() { $barcode = new Barcode('intelligentmail'); $this->assertTrue($barcode->isValid('01234567094987654321')); $this->assertFalse($barcode->isValid('123')); $this->assertFalse($barcode->isValid('5555512371')); } public function testISSN() { $barcode = new Barcode('issn'); $this->assertTrue($barcode->isValid('1144875X')); $this->assertFalse($barcode->isValid('123')); $this->assertFalse($barcode->isValid('1144874X')); $this->assertTrue($barcode->isValid('9771144875007')); $this->assertFalse($barcode->isValid('97711448750X7')); } public function testITF14() { $barcode = new Barcode('itf14'); $this->assertTrue($barcode->isValid('00075678164125')); $this->assertFalse($barcode->isValid('123')); $this->assertFalse($barcode->isValid('00075678164124')); } public function testLEITCODE() { $barcode = new Barcode('leitcode'); $this->assertTrue($barcode->isValid('21348075016401')); $this->assertFalse($barcode->isValid('123')); $this->assertFalse($barcode->isValid('021348075016401')); $this->assertFalse($barcode->isValid('21348075016402')); } public function testPLANET() { $barcode = new Barcode('planet'); $this->assertTrue($barcode->isValid('401234567891')); $this->assertFalse($barcode->isValid('123')); $this->assertFalse($barcode->isValid('401234567892')); } public function testPOSTNET() { $barcode = new Barcode('postnet'); $this->assertTrue($barcode->isValid('5555512372')); $this->assertFalse($barcode->isValid('123')); $this->assertFalse($barcode->isValid('5555512371')); } public function testROYALMAIL() { $barcode = new Barcode('royalmail'); $this->assertTrue($barcode->isValid('SN34RD1AK')); $this->assertFalse($barcode->isValid('123')); $this->assertFalse($barcode->isValid('SN34RD1AW')); $this->assertTrue($barcode->isValid('012345W')); $this->assertTrue($barcode->isValid('06CIOUH')); } public function testSSCC() { $barcode = new Barcode('sscc'); $this->assertTrue($barcode->isValid('123456789012345675')); $this->assertFalse($barcode->isValid('123')); $this->assertFalse($barcode->isValid('123456789012345676')); } public function testUPCA() { $barcode = new Barcode('upca'); $this->assertTrue($barcode->isValid('123456789012')); $this->assertFalse($barcode->isValid('123')); $this->assertFalse($barcode->isValid('123456789013')); } public function testUPCE() { $barcode = new Barcode('upce'); $this->assertTrue($barcode->isValid('02345673')); $this->assertFalse($barcode->isValid('02345672')); $this->assertFalse($barcode->isValid('123')); $this->assertTrue($barcode->isValid('123456')); $this->assertTrue($barcode->isValid('0234567')); } /** * @group ZF-10116 */ public function testArrayLengthMessage() { $barcode = new Barcode('ean8'); $this->assertFalse($barcode->isValid('123')); $message = $barcode->getMessages(); $this->assertArrayHasKey('barcodeInvalidLength', $message); $this->assertContains("length of 7/8 characters", $message['barcodeInvalidLength']); } /** * @group ZF-8673 */ public function testCODABAR() { $barcode = new Barcode('codabar'); $this->assertTrue($barcode->isValid('123456789')); $this->assertTrue($barcode->isValid('A123A')); $this->assertTrue($barcode->isValid('A123C')); $this->assertFalse($barcode->isValid('A123E')); $this->assertFalse($barcode->isValid('A1A23C')); $this->assertTrue($barcode->isValid('T123*')); $this->assertFalse($barcode->isValid('*123A')); } /** * @group ZF-11532 */ public function testIssnWithMod0() { $barcode = new Barcode('issn'); $this->assertTrue($barcode->isValid('18710360')); } /** * @group ZF-8674 */ public function testCODE128() { if (! extension_loaded('iconv')) { $this->markTestSkipped('Missing ext/iconv'); } $barcode = new Barcode('code128'); $this->assertTrue($barcode->isValid('ˆCODE128:Š')); $this->assertTrue($barcode->isValid('‡01231[Š')); $barcode->useChecksum(false); $this->assertTrue($barcode->isValid('012345')); $this->assertTrue($barcode->isValid('ABCDEF')); $this->assertFalse($barcode->isValid('01234Ê')); } /** * Test if EAN-13 contains only numeric characters * * @group ZF-3297 */ public function testEan13ContainsOnlyNumeric() { $barcode = new Barcode('ean13'); $this->assertFalse($barcode->isValid('3RH1131-1BB40')); } public function testEqualsMessageTemplates() { $validator = new Barcode('code25'); $this->assertAttributeEquals( $validator->getOption('messageTemplates'), 'messageTemplates', $validator ); } public function testEqualsMessageVariables() { $validator = new Barcode('code25'); $this->assertAttributeEquals( $validator->getOption('messageVariables'), 'messageVariables', $validator ); } } ================================================ FILE: test/BetweenTest.php ================================================ [ 'min' => 1, 'max' => 100, 'inclusive' => true, 'expected' => true, 'value' => 1, ], 'inclusive-int-valid-between' => [ 'min' => 1, 'max' => 100, 'inclusive' => true, 'expected' => true, 'value' => 10, ], 'inclusive-int-valid-ceiling' => [ 'min' => 1, 'max' => 100, 'inclusive' => true, 'expected' => true, 'value' => 100, ], 'inclusive-int-invaild-below' => [ 'min' => 1, 'max' => 100, 'inclusive' => true, 'expected' => false, 'value' => 0, ], 'inclusive-int-invalid-below-fractional' => [ 'min' => 1, 'max' => 100, 'inclusive' => true, 'expected' => false, 'value' => 0.99, ], 'inclusive-int-invalid-above-fractional' => [ 'min' => 1, 'max' => 100, 'inclusive' => true, 'expected' => false, 'value' => 100.01, ], 'inclusive-int-invalid-above' => [ 'min' => 1, 'max' => 100, 'inclusive' => true, 'expected' => false, 'value' => 101, ], 'exclusive-int-invalid-below' => [ 'min' => 1, 'max' => 100, 'inclusive' => false, 'expected' => false, 'value' => 0, ], 'exclusive-int-invalid-floor' => [ 'min' => 1, 'max' => 100, 'inclusive' => false, 'expected' => false, 'value' => 1, ], 'exclusive-int-invalid-ceiling' => [ 'min' => 1, 'max' => 100, 'inclusive' => false, 'expected' => false, 'value' => 100, ], 'exclusive-int-invalid-above' => [ 'min' => 1, 'max' => 100, 'inclusive' => false, 'expected' => false, 'value' => 101, ], 'inclusive-string-valid-floor' => [ 'min' => 'a', 'max' => 'z', 'inclusive' => true, 'expected' => true, 'value' => 'a', ], 'inclusive-string-valid-between' => [ 'min' => 'a', 'max' => 'z', 'inclusive' => true, 'expected' => true, 'value' => 'm', ], 'inclusive-string-valid-ceiling' => [ 'min' => 'a', 'max' => 'z', 'inclusive' => true, 'expected' => true, 'value' => 'z', ], 'exclusive-string-invalid-out-of-range' => [ 'min' => 'a', 'max' => 'z', 'inclusive' => false, 'expected' => false, 'value' => '!', ], 'exclusive-string-invalid-floor' => [ 'min' => 'a', 'max' => 'z', 'inclusive' => false, 'expected' => false, 'value' => 'a', ], 'exclusive-string-invalid-ceiling' => [ 'min' => 'a', 'max' => 'z', 'inclusive' => false, 'expected' => false, 'value' => 'z', ], 'inclusive-int-invalid-string' => [ 'min' => 0, 'max' => 99999999, 'inclusive' => true, 'expected' => false, 'value' => 'asdasd', ], 'inclusive-int-invalid-char' => [ 'min' => 0, 'max' => 99999999, 'inclusive' => true, 'expected' => false, 'value' => 'q', ], 'inclusive-string-invalid-zero' => [ 'min' => 'a', 'max' => 'zzzzz', 'inclusive' => true, 'expected' => false, 'value' => 0, ], 'inclusive-string-invalid-non-zero' => [ 'min' => 'a', 'max' => 'zzzzz', 'inclusive' => true, 'expected' => false, 'value' => 10, ], ]; } /** * Ensures that the validator follows expected behavior * * @dataProvider providerBasic * @param int|float|string $min * @param int|float|string $max * @param bool $inclusive * @param bool $expected * @param mixed $value * @return void */ public function testBasic($min, $max, $inclusive, $expected, $value) { $validator = new Between(['min' => $min, 'max' => $max, 'inclusive' => $inclusive]); $this->assertSame( $expected, $validator->isValid($value), 'Failed value: ' . $value . ':' . implode("\n", $validator->getMessages()) ); } /** * Ensures that getMessages() returns expected default value * * @return void */ public function testGetMessages() { $validator = new Between(['min' => 1, 'max' => 10]); $this->assertEquals([], $validator->getMessages()); } /** * Ensures that getMin() returns expected value * * @return void */ public function testGetMin() { $validator = new Between(['min' => 1, 'max' => 10]); $this->assertEquals(1, $validator->getMin()); } /** * Ensures that getMax() returns expected value * * @return void */ public function testGetMax() { $validator = new Between(['min' => 1, 'max' => 10]); $this->assertEquals(10, $validator->getMax()); } /** * Ensures that getInclusive() returns expected default value * * @return void */ public function testGetInclusive() { $validator = new Between(['min' => 1, 'max' => 10]); $this->assertEquals(true, $validator->getInclusive()); } public function testEqualsMessageTemplates() { $validator = new Between(['min' => 1, 'max' => 10]); $this->assertAttributeEquals($validator->getOption('messageTemplates'), 'messageTemplates', $validator); } public function testEqualsMessageVariables() { $validator = new Between(['min' => 1, 'max' => 10]); $this->assertAttributeEquals($validator->getOption('messageVariables'), 'messageVariables', $validator); } /** * @covers Zend\Validator\Between::__construct() * @dataProvider constructBetweenValidatorInvalidDataProvider * * @param array $args */ public function testMissingMinOrMax(array $args) { $this->expectException(InvalidArgumentException::class); $this->expectExceptionMessage("Missing option: 'min' and 'max' have to be given"); new Between($args); } public function constructBetweenValidatorInvalidDataProvider() { return [ 'only-min' => [['min' => 1]], 'only-max' => [['max' => 5]], 'min-inclusive' => [['min' => 0, 'inclusive' => true]], 'max-inclusive' => [['max' => 5, 'inclusive' => true]], 'min-undefined' => [['min' => 0, 'foo' => 'bar']], 'max-undefined' => [['max' => 5, 'foo' => 'bar']], 'no-min-or-max' => [['bar' => 'foo', 'foo' => 'bar']], ]; } public function testConstructorCanAcceptInclusiveParameter() { $validator = new Between(1, 10, false); $this->assertFalse($validator->getInclusive()); } public function testConstructWithTraversableOptions() { $options = new \ArrayObject(['min' => 1, 'max' => 10, 'inclusive' => false]); $validator = new Between($options); $this->assertTrue($validator->isValid(5)); $this->assertFalse($validator->isValid(10)); } public function testStringValidatedAgainstNumericMinAndMaxIsInvalidAndReturnsAFailureMessage() { $validator = new Between(['min' => 1, 'max' => 10]); $this->assertFalse($validator->isValid('a')); $messages = $validator->getMessages(); $this->assertContains( 'The min (\'1\') and max (\'10\') values are numeric, but the input is not', $messages ); } public function testNumericValidatedAgainstStringMinAndMaxIsInvalidAndReturnsAFailureMessage() { $validator = new Between(['min' => 'a', 'max' => 'z']); $this->assertFalse($validator->isValid(10)); $messages = $validator->getMessages(); $this->assertContains( 'The min (\'a\') and max (\'z\') values are non-numeric strings, but the input is not a string', $messages ); } } ================================================ FILE: test/BitwiseTest.php ================================================ validator = new Bitwise(); } /** * @covers \Zend\Validator\Bitwise::__construct() * @dataProvider constructDataProvider * * @param array $args * @param array $options */ public function testConstruct(array $args, array $options) { $validator = new Bitwise($args); $this->assertSame($options['control'], $validator->getControl()); $this->assertSame($options['operator'], $validator->getOperator()); $this->assertSame($options['strict'], $validator->getStrict()); } /** * @covers \Zend\Validator\Bitwise::__construct() * @dataProvider constructDataProvider * * @param array $args * @param array $options */ public function testConstructWithTravesableOptions(array $args, array $options) { $validator = new Bitwise( new \ArrayObject($args) ); $this->assertSame($options['control'], $validator->getControl()); $this->assertSame($options['operator'], $validator->getOperator()); $this->assertSame($options['strict'], $validator->getStrict()); } public function constructDataProvider() { return [ [ [], ['control' => null, 'operator' => null, 'strict' => false], ], [ ['control' => 0x1], ['control' => 0x1, 'operator' => null, 'strict' => false], ], [ ['control' => 0x1, 'operator' => Bitwise::OP_AND], ['control' => 0x1, 'operator' => Bitwise::OP_AND, 'strict' => false], ], [ ['control' => 0x1, 'operator' => Bitwise::OP_AND, 'strict' => true], ['control' => 0x1, 'operator' => Bitwise::OP_AND, 'strict' => true], ], ]; } /** * @covers \Zend\Validator\Bitwise::isvalid() */ public function testBitwiseAndNotStrict() { $controlSum = 0x7; // (0x1 | 0x2 | 0x4) === 0x7 $validator = new Bitwise(); $validator->setControl($controlSum); $validator->setOperator(Bitwise::OP_AND); $this->assertTrue($validator->isValid(0x1)); $this->assertTrue($validator->isValid(0x2)); $this->assertTrue($validator->isValid(0x4)); $this->assertFalse($validator->isValid(0x8)); $validator->isValid(0x8); $messages = $validator->getMessages(); $this->assertArrayHasKey($validator::NOT_AND, $messages); $this->assertSame("The input has no common bit set with '$controlSum'", $messages[$validator::NOT_AND]); $this->assertTrue($validator->isValid(0x1 | 0x2)); $this->assertTrue($validator->isValid(0x1 | 0x2 | 0x4)); $this->assertTrue($validator->isValid(0x1 | 0x8)); } /** * @covers \Zend\Validator\Bitwise::isvalid() */ public function testBitwiseAndStrict() { $controlSum = 0x7; // (0x1 | 0x2 | 0x4) === 0x7 $validator = new Bitwise(); $validator->setControl($controlSum); $validator->setOperator(Bitwise::OP_AND); $validator->setStrict(true); $this->assertTrue($validator->isValid(0x1)); $this->assertTrue($validator->isValid(0x2)); $this->assertTrue($validator->isValid(0x4)); $this->assertFalse($validator->isValid(0x8)); $validator->isValid(0x8); $messages = $validator->getMessages(); $this->assertArrayHasKey($validator::NOT_AND_STRICT, $messages); $this->assertSame( "The input doesn't have the same bits set as '$controlSum'", $messages[$validator::NOT_AND_STRICT] ); $this->assertTrue($validator->isValid(0x1 | 0x2)); $this->assertTrue($validator->isValid(0x1 | 0x2 | 0x4)); $this->assertFalse($validator->isValid(0x1 | 0x8)); } /** * @covers \Zend\Validator\Bitwise::isvalid() */ public function testBitwiseXor() { $controlSum = 0x5; // (0x1 | 0x4) === 0x5 $validator = new Bitwise(); $validator->setControl($controlSum); $validator->setOperator(Bitwise::OP_XOR); $this->assertTrue($validator->isValid(0x2)); $this->assertTrue($validator->isValid(0x8)); $this->assertTrue($validator->isValid(0x10)); $this->assertFalse($validator->isValid(0x1)); $this->assertFalse($validator->isValid(0x4)); $validator->isValid(0x4); $messages = $validator->getMessages(); $this->assertArrayHasKey($validator::NOT_XOR, $messages); $this->assertSame("The input has common bit set with '$controlSum'", $messages[$validator::NOT_XOR]); $this->assertTrue($validator->isValid(0x8 | 0x10)); $this->assertFalse($validator->isValid(0x1 | 0x4)); $this->assertFalse($validator->isValid(0x1 | 0x8)); $this->assertFalse($validator->isValid(0x4 | 0x8)); } /** * @covers \Zend\Validator\Bitwise::setOperator() */ public function testSetOperator() { $validator = new Bitwise(); $validator->setOperator(Bitwise::OP_AND); $this->assertSame(Bitwise::OP_AND, $validator->getOperator()); $validator->setOperator(Bitwise::OP_XOR); $this->assertSame(Bitwise::OP_XOR, $validator->getOperator()); } /** * @covers \Zend\Validator\Bitwise::setStrict() */ public function testSetStrict() { $validator = new Bitwise(); $this->assertFalse($validator->getStrict(), 'Strict false by default'); $validator->setStrict(false); $this->assertFalse($validator->getStrict()); $validator->setStrict(true); $this->assertTrue($validator->getStrict()); $validator = new Bitwise(0x1, Bitwise::OP_AND, false); $this->assertFalse($validator->getStrict()); $validator = new Bitwise(0x1, Bitwise::OP_AND, true); $this->assertTrue($validator->getStrict()); } public function testConstructorCanAcceptAllOptionsAsDiscreteArguments() { $control = 0x1; $operator = Bitwise::OP_AND; $strict = true; $validator = new Bitwise($control, $operator, $strict); $this->assertSame($control, $validator->getControl()); $this->assertSame($operator, $validator->getOperator()); $this->assertSame($strict, $validator->getStrict()); } public function testCanRetrieveControlValue() { $control = 0x1; $validator = new Bitwise($control, Bitwise::OP_AND, false); $this->assertSame($control, $validator->getControl()); } public function testCanRetrieveOperatorValue() { $operator = Bitwise::OP_AND; $validator = new Bitwise(0x1, $operator, false); $this->assertSame($operator, $validator->getOperator()); } public function testCanRetrieveStrictValue() { $strict = true; $validator = new Bitwise(0x1, Bitwise::OP_AND, $strict); $this->assertSame($strict, $validator->getStrict()); } public function testIsValidReturnsFalseWithInvalidOperator() { $validator = new Bitwise(0x1, 'or', false); $expectedResult = false; $this->assertEquals($expectedResult, $validator->isValid(0x2)); } public function testCanSetControlValue() { $validator = new Bitwise(); $control = 0x2; $validator->setControl($control); $this->assertSame($control, $validator->getControl()); } } ================================================ FILE: test/CallbackTest.php ================================================ assertTrue($valid->isValid('test')); } public function testStaticCallback() { $valid = new Callback( [CallbackTest::class, 'staticCallback'] ); $this->assertTrue($valid->isValid('test')); } public function testSettingDefaultOptionsAfterwards() { $valid = new Callback([$this, 'objectCallback']); $valid->setCallbackOptions('options'); $this->assertEquals(['options'], $valid->getCallbackOptions()); $this->assertTrue($valid->isValid('test')); } public function testSettingDefaultOptions() { $valid = new Callback(['callback' => [$this, 'objectCallback'], 'callbackOptions' => 'options']); $this->assertEquals(['options'], $valid->getCallbackOptions()); $this->assertTrue($valid->isValid('test')); } public function testGettingCallback() { $valid = new Callback([$this, 'objectCallback']); $this->assertEquals([$this, 'objectCallback'], $valid->getCallback()); } public function testInvalidCallback() { $valid = new Callback([$this, 'objectCallback']); $this->expectException(InvalidArgumentException::class); $this->expectExceptionMessage('Invalid callback given'); $valid->setCallback('invalidcallback'); } public function testAddingValueOptions() { $valid = new Callback(['callback' => [$this, 'optionsCallback'], 'callbackOptions' => 'options']); $this->assertEquals(['options'], $valid->getCallbackOptions()); $this->assertTrue($valid->isValid('test', 'something')); } public function testEqualsMessageTemplates() { $validator = new Callback([$this, 'objectCallback']); $this->assertAttributeEquals( $validator->getOption('messageTemplates'), 'messageTemplates', $validator ); } public function testCanAcceptContextWithoutOptions() { $value = 'bar'; $context = ['foo' => 'bar', 'bar' => 'baz']; $validator = new Callback(function ($v, $c) use ($value, $context) { return (($value == $v) && ($context == $c)); }); $this->assertTrue($validator->isValid($value, $context)); } public function testCanAcceptContextWithOptions() { $value = 'bar'; $context = ['foo' => 'bar', 'bar' => 'baz']; $options = ['baz' => 'bat']; $validator = new Callback(function ($v, $c, $baz) use ($value, $context, $options) { return (($value == $v) && ($context == $c) && ($options['baz'] == $baz)); }); $validator->setCallbackOptions($options); $this->assertTrue($validator->isValid($value, $context)); } public function objectCallback($value) { return true; } public static function staticCallback($value) { return true; } public function optionsCallback($value) { $args = func_get_args(); $this->assertContains('something', $args); return $args; } public function testIsValidRaisesExceptionWhenNoCallbackPresent() { $validator = new Callback(); $r = new ReflectionProperty($validator, 'options'); $r->setAccessible(true); $options = $r->getValue($validator); $options['callback'] = []; $r->setValue($validator, $options); $this->expectException(InvalidArgumentException::class); $this->expectExceptionMessage('No callback given'); $validator->isValid('test'); } } ================================================ FILE: test/CreditCardTest.php ================================================ assertEquals($expected, $validator->isValid($input)); } /** * Ensures that getMessages() returns expected default value * * @return void */ public function testGetMessages() { $validator = new CreditCard(); $this->assertEquals([], $validator->getMessages()); } /** * Ensures that get and setType works as expected * * @return void */ public function testGetSetType() { $validator = new CreditCard(); $this->assertEquals(12, count($validator->getType())); $validator->setType(CreditCard::MAESTRO); $this->assertEquals([CreditCard::MAESTRO], $validator->getType()); $validator->setType( [ CreditCard::AMERICAN_EXPRESS, CreditCard::MAESTRO ] ); $this->assertEquals( [ CreditCard::AMERICAN_EXPRESS, CreditCard::MAESTRO ], $validator->getType() ); $validator->addType( CreditCard::MASTERCARD ); $this->assertEquals( [ CreditCard::AMERICAN_EXPRESS, CreditCard::MAESTRO, CreditCard::MASTERCARD ], $validator->getType() ); } public static function visaValues() { return [ ['4111111111111111', true], ['5404000000000001', false], ['374200000000004', false], ['4444555566667777', false], ['ABCDEF', false], ]; } /** * Test specific provider * * @dataProvider visaValues */ public function testProvider($input, $expected) { $validator = new CreditCard(CreditCard::VISA); $this->assertEquals($expected, $validator->isValid($input)); } /** * Test non string input * * @return void */ public function testIsValidWithNonString() { $validator = new CreditCard(CreditCard::VISA); $this->assertFalse($validator->isValid(['something'])); } public static function serviceValues() { return [ ['4111111111111111', false], ['5404000000000001', false], ['374200000000004', false], ['4444555566667777', false], ['ABCDEF', false], ]; } /** * Test service class with invalid validation * * @dataProvider serviceValues */ public function testServiceClass($input, $expected) { $validator = new CreditCard(); $this->assertEquals(null, $validator->getService()); $validator->setService([CreditCardTest::class, 'staticCallback']); $this->assertEquals($expected, $validator->isValid($input)); } public static function optionsValues() { return [ ['4111111111111111', false], ['5404000000000001', false], ['374200000000004', false], ['4444555566667777', false], ['ABCDEF', false], ]; } /** * Test non string input * * @dataProvider optionsValues */ public function testConstructionWithOptions($input, $expected) { $validator = new CreditCard( [ 'type' => CreditCard::VISA, 'service' => [CreditCardTest::class, 'staticCallback'] ] ); $this->assertEquals($expected, $validator->isValid($input)); } /** * Data provider * * @return string[][]|bool[][] */ public function jcbValues() { return [ ['3566003566003566', true], ['3528000000000007', true], ['3528000000000007', true], ['3528000000000007', true], ['3088185545477406', false], ['3158854390756173', false], ['3088936920428541', false], ['213193692042852', true], ['180012362524156', true], ]; } /** * Test JCB number validity * * @dataProvider jcbValues * * @param string $input * @param bool $expected * * @group 6278 * @group 6927 */ public function testJcbCard($input, $expected) { $validator = new CreditCard(['type' => CreditCard::JCB]); $this->assertEquals($expected, $validator->isValid($input)); } /** * Data provider * * @return string[][]|bool[][] */ public function mastercardValues() { return [ ['4111111111111111', false], ['5011642326344731', false], ['5130982099822729', true], ['2220993834549400', false], ['2221006548643366', true], ['2222007329134574', true], ['2393923057923090', true], ['2484350479254492', true], ['2518224476613101', true], ['2659969950495289', true], ['2720992392889757', true], ['2721008996056187', false], ]; } /** * Test mastercard number validity * * @dataProvider mastercardValues * * @param string $input * @param bool $expected */ public function testMastercardCard($input, $expected) { $validator = new CreditCard(['type' => CreditCard::MASTERCARD]); $this->assertEquals($expected, $validator->isValid($input)); } /** * Data provider * * @return string[][]|bool[][] */ public function mirValues() { return [ ['3011111111111000', false], ['2031343323344731', false], ['2200312032822721', true], ['2209993834549400', false], ['2204001882200999', true], ['2202000312124573', true], ['2203921957923012', true], ['2204150479254495', true], ['2201123406612104', true], ['2900008996056', false], ['2201969950494', true], ['2201342387927', true], ['2205969950494', false], ]; } /** * Test mir card number validity * * @dataProvider mirValues * * @param string $input * @param bool $expected */ public function testMirCard($input, $expected) { $validator = new CreditCard(['type' => CreditCard::MIR]); $this->assertEquals($expected, $validator->isValid($input)); } /** * Test an invalid service class * * @return void */ public function testInvalidServiceClass() { $validator = new CreditCard(); $this->assertEquals(null, $validator->getService()); $this->expectException(InvalidArgumentException::class); $this->expectExceptionMessage('Invalid callback given'); $validator->setService([CreditCardTest::class, 'nocallback']); } /** * Test a config object * * @return void */ public function testConfigObject() { $options = ['type' => 'Visa']; $config = new Config\Config($options, false); $validator = new CreditCard($config); $this->assertEquals(['Visa'], $validator->getType()); } /** * Test optional parameters with config object * * @return void */ public function testOptionalConstructorParameterByConfigObject() { $config = new Config\Config( ['type' => 'Visa', 'service' => [CreditCardTest::class, 'staticCallback']] ); $validator = new CreditCard($config); $this->assertEquals(['Visa'], $validator->getType()); $this->assertEquals([CreditCardTest::class, 'staticCallback'], $validator->getService()); } /** * Test optional constructor parameters * * @return void */ public function testOptionalConstructorParameter() { $validator = new CreditCard('Visa', [CreditCardTest::class, 'staticCallback']); $this->assertEquals(['Visa'], $validator->getType()); $this->assertEquals([CreditCardTest::class, 'staticCallback'], $validator->getService()); } /** * @group ZF-9477 */ public function testMultiInstitute() { $validator = new CreditCard(['type' => CreditCard::MASTERCARD]); $this->assertFalse($validator->isValid('4111111111111111')); $message = $validator->getMessages(); $this->assertContains('not from an allowed institute', current($message)); } public function testEqualsMessageTemplates() { $validator = new CreditCard(); $this->assertAttributeEquals( $validator->getOption('messageTemplates'), 'messageTemplates', $validator ); } /** * @see https://github.com/zendframework/zend-validator/pull/202 */ public function testValidatorAllowsExtensionsToDefineAdditionalTypesViaConstants() { $validator = new TestAsset\CreditCardValidatorExtension(); $this->assertSame($validator, $validator->addType('test_type')); $this->assertContains(TestAsset\CreditCardValidatorExtension::TEST_TYPE, $validator->getType()); } public static function staticCallback($value) { return false; } } ================================================ FILE: test/CsrfTest.php ================================================ ArrayStorage::class, ]); $sessionManager = new TestAsset\SessionManager($sessionConfig); $this->sessionManager = $sessionManager; Container::setDefaultManager($sessionManager); $this->validator = new Csrf; } public function tearDown() { if (! class_exists(Container::class)) { return; } $_SESSION = []; Container::setDefaultManager(null); } public function testSaltHasDefaultValueIfNotSet() { $this->assertEquals('salt', $this->validator->getSalt()); } public function testSaltIsMutable() { $this->validator->setSalt('pepper'); $this->assertEquals('pepper', $this->validator->getSalt()); } public function testSessionContainerIsLazyLoadedIfNotSet() { $container = $this->validator->getSession(); $this->assertInstanceOf(Container::class, $container); } public function testSessionContainerIsMutable() { $container = new Container('foo', $this->sessionManager); $this->validator->setSession($container); $this->assertSame($container, $this->validator->getSession()); } public function testNameHasDefaultValue() { $this->assertEquals('csrf', $this->validator->getName()); } public function testNameIsMutable() { $this->validator->setName('foo'); $this->assertEquals('foo', $this->validator->getName()); } public function testTimeoutHasDefaultValue() { $this->assertEquals(300, $this->validator->getTimeout()); } public function timeoutValuesDataProvider() { return [ // timeout expected [600, 600], [null, null], ["0", 0], ["100", 100], ]; } /** * @dataProvider timeoutValuesDataProvider */ public function testTimeoutIsMutable($timeout, $expected) { $this->validator->setTimeout($timeout); $this->assertEquals($expected, $this->validator->getTimeout()); } public function testAllOptionsMayBeSetViaConstructor() { $container = new Container('foo', $this->sessionManager); $options = [ 'name' => 'hash', 'salt' => 'hashful', 'session' => $container, 'timeout' => 600, ]; $validator = new Csrf($options); foreach ($options as $key => $value) { if ($key == 'session') { $this->assertSame($container, $value); continue; } $method = 'get' . $key; $this->assertEquals($value, $validator->$method()); } } public function testHashIsGeneratedOnFirstRetrieval() { $hash = $this->validator->getHash(); $this->assertNotEmpty($hash); $test = $this->validator->getHash(); $this->assertEquals($hash, $test); } public function testSessionNameIsDerivedFromClassSaltAndName() { $class = get_class($this->validator); $class = str_replace('\\', '_', $class); $expected = sprintf('%s_%s_%s', $class, $this->validator->getSalt(), $this->validator->getName()); $this->assertEquals($expected, $this->validator->getSessionName()); } public function testSessionNameRemainsValidForElementBelongingToFieldset() { $this->validator->setName('fieldset[csrf]'); $class = get_class($this->validator); $class = str_replace('\\', '_', $class); $name = strtr($this->validator->getName(), ['[' => '_', ']' => '']); $expected = sprintf('%s_%s_%s', $class, $this->validator->getSalt(), $name); $this->assertEquals($expected, $this->validator->getSessionName()); } public function testIsValidReturnsFalseWhenValueDoesNotMatchHash() { $this->assertFalse($this->validator->isValid('foo')); } public function testValidationErrorMatchesNotSameConstantAndRelatedMessage() { $this->validator->isValid('foo'); $messages = $this->validator->getMessages(); $this->assertArrayHasKey(Csrf::NOT_SAME, $messages); $this->assertEquals("The form submitted did not originate from the expected site", $messages[Csrf::NOT_SAME]); } public function testIsValidReturnsTrueWhenValueMatchesHash() { $hash = $this->validator->getHash(); $this->assertTrue($this->validator->isValid($hash)); } public function testSessionContainerContainsHashAfterHashHasBeenGenerated() { $hash = $this->validator->getHash(); $container = $this->validator->getSession(); $test = $container->hash; // Doing this, as expiration hops are 1; have to grab on first access $this->assertEquals($hash, $test); } public function testSettingNewSessionContainerSetsHashInNewContainer() { $hash = $this->validator->getHash(); $container = new Container('foo', $this->sessionManager); $this->validator->setSession($container); $test = $container->hash; // Doing this, as expiration hops are 1; have to grab on first access $this->assertEquals($hash, $test); } public function testMultipleValidatorsSharingContainerGenerateDifferentHashes() { $validatorOne = new Csrf(); $validatorTwo = new Csrf(); $containerOne = $validatorOne->getSession(); $containerTwo = $validatorOne->getSession(); $this->assertSame($containerOne, $containerTwo); $hashOne = $validatorOne->getHash(); $hashTwo = $validatorTwo->getHash(); $this->assertNotEquals($hashOne, $hashTwo); } public function testCanValidateAnyHashWithinTheSameContainer() { $validatorOne = new Csrf(); $validatorTwo = new Csrf(); $hashOne = $validatorOne->getHash(); $hashTwo = $validatorTwo->getHash(); $this->assertTrue($validatorOne->isValid($hashOne)); $this->assertTrue($validatorOne->isValid($hashTwo)); $this->assertTrue($validatorTwo->isValid($hashOne)); $this->assertTrue($validatorTwo->isValid($hashTwo)); } public function testCannotValidateHashesOfOtherContainers() { $validatorOne = new Csrf(); $validatorTwo = new Csrf(['name' => 'foo']); $containerOne = $validatorOne->getSession(); $containerTwo = $validatorTwo->getSession(); $this->assertNotSame($containerOne, $containerTwo); $hashOne = $validatorOne->getHash(); $hashTwo = $validatorTwo->getHash(); $this->assertTrue($validatorOne->isValid($hashOne)); $this->assertFalse($validatorOne->isValid($hashTwo)); $this->assertFalse($validatorTwo->isValid($hashOne)); $this->assertTrue($validatorTwo->isValid($hashTwo)); } public function testCannotReValidateAnExpiredHash() { $hash = $this->validator->getHash(); $this->assertTrue($this->validator->isValid($hash)); $this->sessionManager->getStorage()->setMetadata( $this->validator->getSession()->getName(), ['EXPIRE' => $_SERVER['REQUEST_TIME'] - 18600] ); $this->assertFalse($this->validator->isValid($hash)); } public function testCanValidateHasheWithoutId() { $method = new \ReflectionMethod(get_class($this->validator), 'getTokenFromHash'); $method->setAccessible(true); $hash = $this->validator->getHash(); $bareToken = $method->invoke($this->validator, $hash); $this->assertTrue($this->validator->isValid($bareToken)); } public function testCanRejectArrayValues() { $this->assertFalse($this->validator->isValid([])); } public function fakeValuesDataProvider() { return [ [''], ['-fakeTokenId'], ['fakeTokenId-fakeTokenId'], ['fakeTokenId-'], ['fakeTokenId'], [md5(uniqid()) . '-'], [md5(uniqid()) . '-' . md5(uniqid())], ['-' . md5(uniqid())], ]; } /** * @dataProvider fakeValuesDataProvider */ public function testWithFakeValues($value) { $validator = new Csrf(); $this->assertFalse($validator->isValid($value)); } } ================================================ FILE: test/DateStepTest.php ================================================ $format, 'baseValue' => $baseValue, 'step' => new DateInterval($interval), ]); $this->assertEquals($isValid, $validator->isValid($value)); } public function testGetMessagesReturnsDefaultValue() { $validator = new Validator\DateStep(); $this->assertEquals([], $validator->getMessages()); } public function testEqualsMessageTemplates() { $validator = new Validator\DateStep([]); $this->assertObjectHasAttribute('messageTemplates', $validator); $this->assertAttributeEquals($validator->getOption('messageTemplates'), 'messageTemplates', $validator); } public function testStepError() { $validator = new Validator\DateStep([ 'format' => 'Y-m-d', 'baseValue' => '2012-01-23', 'step' => new DateInterval("P10D"), ]); $this->assertFalse($validator->isValid('2012-02-23')); } public function moscowWinterTimeDataProvider() { // dates before during and after Moscow's wintertime return [ ['26-03-1999'], ['26-03-2011'], ['27-03-2011'], ['26-03-2015'], ]; } /** * @dataProvider moscowWinterTimeDataProvider */ public function testMoscowWinterTime($dateToValidate) { $validator = new Validator\DateStep([ 'format' => 'd-m-Y', 'baseValue' => date('d-m-Y', 0), 'step' => new DateInterval("P1D"), 'timezone' => new DateTimeZone('Europe/Moscow'), ]); $this->assertTrue($validator->isValid($dateToValidate)); } public function testCanSetBaseValue() { $validator = new Validator\DateStep(); $newBaseValue = '2013-01-23'; $validator->setBaseValue($newBaseValue); $retrievedBaseValue = $validator->getBaseValue(); $this->assertSame($newBaseValue, $retrievedBaseValue); } public function testCanRetrieveTimezone() { $validator = new Validator\DateStep(); $newTimezone = new DateTimeZone("Europe/Vienna"); $validator->setTimezone($newTimezone); $retrievedTimezone = $validator->getTimezone(); $this->assertSame($newTimezone, $retrievedTimezone); } public function testCanProvideOptionsToConstructorAsDiscreteArguments() { $baseValue = '2012-01-23'; $step = new DateInterval("P1D"); $format = 'd-m-Y'; $timezone = new DateTimeZone("Europe/Vienna"); $validator = new Validator\DateStep($baseValue, $step, $format, $timezone); $retrievedBaseValue = $validator->getBaseValue(); $retrievedStep = $validator->getStep(); $retrievedFormat = $validator->getFormat(); $retrievedTimezone = $validator->getTimezone(); $this->assertSame($baseValue, $retrievedBaseValue); $this->assertSame($step, $retrievedStep); $this->assertSame($format, $retrievedFormat); $this->assertSame($timezone, $retrievedTimezone); } public function testConvertStringDoesNotRaiseErrorOnInvalidValue() { $validator = new Validator\DateStep([ 'format' => 'Y-m-d', 'baseValue' => '2012-01-23', 'step' => new DateInterval("P10D"), ]); $r = new ReflectionMethod($validator, 'convertString'); $r->setAccessible(true); $invalidValue = '20-20-20'; // Verify that the value returns false for an invalid value $this->assertFalse($r->invoke($validator, $invalidValue, false)); // Verify that no message was set. $this->assertEquals([], $validator->getMessages()); } } ================================================ FILE: test/DateTest.php ================================================ validator = new Validator\Date(); } public function testSetFormatIgnoresNull() { $this->validator->setFormat(null); $this->assertEquals(Validator\Date::FORMAT_DEFAULT, $this->validator->getFormat()); } public function datesDataProvider() { return [ // date format isValid isValid Strict ['2007-01-01', null, true, true], ['2007-02-28', null, true, true], ['2007-02-29', null, false, false], ['2008-02-29', null, true, true], ['2007-02-30', null, false, false], ['2007-02-99', null, false, false], ['2007-02-99', 'Y-m-d', false, false], ['9999-99-99', null, false, false], ['9999-99-99', 'Y-m-d', false, false], ['Jan 1 2007', null, false, false], ['Jan 1 2007', 'M j Y', true, true], ['asdasda', null, false, false], ['sdgsdg', null, false, false], ['2007-01-01something', null, false, false], ['something2007-01-01', null, false, false], ['10.01.2008', 'd.m.Y', true, true], ['01 2010', 'm Y', true, true], ['2008/10/22', 'd/m/Y', false, false], ['22/10/08', 'd/m/y', true, true], ['22/10', 'd/m/Y', false, false], // time ['2007-01-01T12:02:55Z', DateTime::ISO8601, true, false], ['2007-01-01T12:02:55+0000', DateTime::ISO8601, true, true], ['12:02:55', 'H:i:s', true, true], ['25:02:55', 'H:i:s', false, false], // int [0, null, true, false], [6, 'd', true, false], ['6', 'd', true, false], ['06', 'd', true, true], [123, null, true, false], [1340677235, null, true, false], [1340677235, 'U', true, false], ['1340677235', 'U', true, true], // 32bit version of php will convert this to double [999999999999, null, true, false], // double [12.12, null, false, false], // array [['2012', '06', '25'], null, true, false], // 0012-06-25 is a valid date, if you want 2012, use 'y' instead of 'Y' [['12', '06', '25'], null, true, false], [['2012', '06', '33'], null, false, false], [[1 => 1], null, false, false], // DateTime [new DateTime(), null, true, false], // invalid obj [new stdClass(), null, false, false], ]; } /** * Ensures that the validator follows expected behavior * * @dataProvider datesDataProvider */ public function testBasic($input, $format, $result) { $this->validator->setFormat($format); $this->assertEquals($result, $this->validator->isValid($input)); } /** * @dataProvider datesDataProvider * * @param mixed $input */ public function testBasicStrictMode($input, ?string $format, bool $result, bool $resultStrict) : void { $this->validator->setStrict(true); $this->validator->setFormat($format); $this->assertSame($resultStrict, $this->validator->isValid($input)); } public function testDateTimeImmutable() { $this->assertTrue($this->validator->isValid(new DateTimeImmutable())); } /** * Ensures that getMessages() returns expected default value * * @return void */ public function testGetMessages() { $this->assertEquals([], $this->validator->getMessages()); } /** * Ensures that the validator can handle different manual dateformats * * @group ZF-2003 * @return void */ public function testUseManualFormat() { $this->assertTrue( $this->validator->setFormat('d.m.Y')->isValid('10.01.2008'), var_export(date_get_last_errors(), 1) ); $this->assertEquals('d.m.Y', $this->validator->getFormat()); $this->assertTrue($this->validator->setFormat('m Y')->isValid('01 2010')); $this->assertFalse($this->validator->setFormat('d/m/Y')->isValid('2008/10/22')); $this->assertTrue($this->validator->setFormat('d/m/Y')->isValid('22/10/08')); $this->assertFalse($this->validator->setFormat('d/m/Y')->isValid('22/10')); // Omitting the following assertion, as it varies from 5.3.3 to 5.3.11, // and there is no indication in the PHP changelog as to when or why it // may have changed. Leaving for posterity, to indicate original expectation. // $this->assertFalse($this->validator->setFormat('s')->isValid(0)); } public function testEqualsMessageTemplates() { $validator = $this->validator; $this->assertAttributeEquals( $validator->getOption('messageTemplates'), 'messageTemplates', $validator ); } public function testEqualsMessageVariables() { $validator = $this->validator; $this->assertAttributeEquals( $validator->getOption('messageVariables'), 'messageVariables', $validator ); } public function testConstructorWithFormatParameter() { $format = 'd/m/Y'; $validator = new Validator\Date($format); $this->assertEquals($format, $validator->getFormat()); } } ================================================ FILE: test/Db/AbstractDbTest.php ================================================ validator = new ConcreteDbValidator([ 'table' => 'table', 'field' => 'field', 'schema' => 'schema', ]); } public function testConstructorWithNoTableAndSchemaKey() { $this->expectException(InvalidArgumentException::class); $this->expectExceptionMessage('Table or Schema option missing!'); $this->validator = new ConcreteDbValidator([ 'field' => 'field', ]); } public function testConstructorWithNoFieldKey() { $this->expectException(InvalidArgumentException::class); $this->expectExceptionMessage('Field option missing!'); $validator = new ConcreteDbValidator([ 'schema' => 'schema', 'table' => 'table', ]); } public function testSetSelect() { $select = new Select(); $this->validator->setSelect($select); $this->assertSame($select, $this->validator->getSelect()); } public function testGetSchema() { $schema = 'test_db'; $this->validator->setSchema($schema); $this->assertEquals($schema, $this->validator->getSchema()); } public function testGetTable() { $table = 'test_table'; $this->validator->setTable($table); $this->assertEquals($table, $this->validator->getTable()); } public function testGetField() { $field = 'test_field'; $this->validator->setField($field); $this->assertEquals($field, $this->validator->getField()); } public function testGetExclude() { $field = 'test_field'; $this->validator->setField($field); $this->assertEquals($field, $this->validator->getField()); } /** * @group #46 */ public function testImplementationsAreDbAdapterAware() { $this->assertInstanceOf(AdapterAwareInterface::class, $this->validator); } /** * @group #46 */ public function testSetAdapterIsEquivalentToSetDbAdapter() { $adapterFirst = $this->prophesize(Adapter::class)->reveal(); $adapterSecond = $this->prophesize(Adapter::class)->reveal(); $this->validator->setAdapter($adapterFirst); $this->assertAttributeSame($adapterFirst, 'adapter', $this->validator); $this->validator->setDbAdapter($adapterSecond); $this->assertAttributeSame($adapterSecond, 'adapter', $this->validator); } } ================================================ FILE: test/Db/NoRecordExistsTest.php ================================================ createMock(ConnectionInterface::class); // Mock has result $mockHasResultRow = new ArrayObject(); $mockHasResultRow->one = 'one'; $mockHasResult = $this->createMock(ResultInterface::class); $mockHasResult->expects($this->any()) ->method('current') ->will($this->returnValue($mockHasResultRow)); $mockHasResultStatement = $this->createMock(StatementInterface::class); $mockHasResultStatement->expects($this->any()) ->method('execute') ->will($this->returnValue($mockHasResult)); $mockHasResultStatement->expects($this->any()) ->method('getParameterContainer') ->will($this->returnValue(new ParameterContainer())); $mockHasResultDriver = $this->createMock(DriverInterface::class); $mockHasResultDriver->expects($this->any()) ->method('createStatement') ->will($this->returnValue($mockHasResultStatement)); $mockHasResultDriver->expects($this->any()) ->method('getConnection') ->will($this->returnValue($mockConnection)); return $this->getMockBuilder(Adapter::class) ->setMethods(null) ->setConstructorArgs([$mockHasResultDriver]) ->getMock(); } /** * Return a Mock object for a Db result without rows * * @return \Zend\Db\Adapter\Adapter */ protected function getMockNoResult() { // mock the adapter, driver, and parts $mockConnection = $this->createMock(ConnectionInterface::class); $mockNoResult = $this->createMock(ResultInterface::class); $mockNoResult->expects($this->any()) ->method('current') ->will($this->returnValue(null)); $mockNoResultStatement = $this->createMock(StatementInterface::class); $mockNoResultStatement->expects($this->any()) ->method('execute') ->will($this->returnValue($mockNoResult)); $mockNoResultStatement->expects($this->any()) ->method('getParameterContainer') ->will($this->returnValue(new ParameterContainer())); $mockNoResultDriver = $this->createMock(DriverInterface::class); $mockNoResultDriver->expects($this->any()) ->method('createStatement') ->will($this->returnValue($mockNoResultStatement)); $mockNoResultDriver->expects($this->any()) ->method('getConnection') ->will($this->returnValue($mockConnection)); return $this->getMockBuilder(Adapter::class) ->setMethods(null) ->setConstructorArgs([$mockNoResultDriver]) ->getMock(); } /** * Test basic function of RecordExists (no exclusion) * * @return void */ public function testBasicFindsRecord() { $validator = new NoRecordExists('users', 'field1', null, $this->getMockHasResult()); $this->assertFalse($validator->isValid('value1')); } /** * Test basic function of RecordExists (no exclusion) * * @return void */ public function testBasicFindsNoRecord() { $validator = new NoRecordExists('users', 'field1', null, $this->getMockNoResult()); $this->assertTrue($validator->isValid('nosuchvalue')); } /** * Test the exclusion function * * @return void */ public function testExcludeWithArray() { $validator = new NoRecordExists( 'users', 'field1', ['field' => 'id', 'value' => 1], $this->getMockHasResult() ); $this->assertFalse($validator->isValid('value3')); } /** * Test the exclusion function * with an array * * @return void */ public function testExcludeWithArrayNoRecord() { $validator = new NoRecordExists( 'users', 'field1', ['field' => 'id', 'value' => 1], $this->getMockNoResult() ); $this->assertTrue($validator->isValid('nosuchvalue')); } /** * Test the exclusion function * with a string * * @return void */ public function testExcludeWithString() { $validator = new NoRecordExists('users', 'field1', 'id != 1', $this->getMockHasResult()); $this->assertFalse($validator->isValid('value3')); } /** * Test the exclusion function * with a string * * @return void */ public function testExcludeWithStringNoRecord() { $validator = new NoRecordExists('users', 'field1', 'id != 1', $this->getMockNoResult()); $this->assertTrue($validator->isValid('nosuchvalue')); } /** * Test that the class throws an exception if no adapter is provided * and no default is set. * * @return void */ public function testThrowsExceptionWithNoAdapter() { $validator = new NoRecordExists('users', 'field1', 'id != 1'); $this->expectException(RuntimeException::class); $this->expectExceptionMessage('No database adapter present'); $validator->isValid('nosuchvalue'); } /** * Test that schemas are supported and run without error * * @return void */ public function testWithSchema() { $validator = new NoRecordExists([ 'table' => 'users', 'schema' => 'my' ], 'field1', null, $this->getMockHasResult()); $this->assertFalse($validator->isValid('value1')); } /** * Test that schemas are supported and run without error * * @return void */ public function testWithSchemaNoResult() { $validator = new NoRecordExists([ 'table' => 'users', 'schema' => 'my' ], 'field1', null, $this->getMockNoResult()); $this->assertTrue($validator->isValid('value1')); } public function testEqualsMessageTemplates() { $validator = new NoRecordExists('users', 'field1'); $this->assertAttributeEquals( $validator->getOption('messageTemplates'), 'messageTemplates', $validator ); } } ================================================ FILE: test/Db/RecordExistsTest.php ================================================ createMock(ConnectionInterface::class); // Mock has result $mockHasResultRow = new ArrayObject(); $mockHasResultRow->one = 'one'; $mockHasResult = $this->createMock(ResultInterface::class); $mockHasResult->expects($this->any()) ->method('current') ->will($this->returnValue($mockHasResultRow)); $mockHasResultStatement = $this->createMock(StatementInterface::class); $mockHasResultStatement->expects($this->any()) ->method('execute') ->will($this->returnValue($mockHasResult)); $mockHasResultStatement->expects($this->any()) ->method('getParameterContainer') ->will($this->returnValue(new ParameterContainer())); $mockHasResultDriver = $this->createMock(DriverInterface::class); $mockHasResultDriver->expects($this->any()) ->method('createStatement') ->will($this->returnValue($mockHasResultStatement)); $mockHasResultDriver->expects($this->any()) ->method('getConnection') ->will($this->returnValue($mockConnection)); return $this->getMockBuilder(Adapter::class) ->setMethods(null) ->setConstructorArgs([$mockHasResultDriver]) ->getMock(); } /** * Return a Mock object for a Db result without rows * * @return \Zend\Db\Adapter\Adapter */ protected function getMockNoResult() { // mock the adapter, driver, and parts $mockConnection = $this->createMock(ConnectionInterface::class); $mockNoResult = $this->createMock(ResultInterface::class); $mockNoResult->expects($this->any()) ->method('current') ->will($this->returnValue(null)); $mockNoResultStatement = $this->createMock(StatementInterface::class); $mockNoResultStatement->expects($this->any()) ->method('execute') ->will($this->returnValue($mockNoResult)); $mockNoResultStatement->expects($this->any()) ->method('getParameterContainer') ->will($this->returnValue(new ParameterContainer())); $mockNoResultDriver = $this->createMock(DriverInterface::class); $mockNoResultDriver->expects($this->any()) ->method('createStatement') ->will($this->returnValue($mockNoResultStatement)); $mockNoResultDriver->expects($this->any()) ->method('getConnection') ->will($this->returnValue($mockConnection)); return $this->getMockBuilder(Adapter::class) ->setMethods(null) ->setConstructorArgs([$mockNoResultDriver]) ->getMock(); } /** * Test basic function of RecordExists (no exclusion) * * @return void */ public function testBasicFindsRecord() { $validator = new RecordExists([ 'table' => 'users', 'field' => 'field1', 'adapter' => $this->getMockHasResult() ]); $this->assertTrue($validator->isValid('value1')); } /** * Test basic function of RecordExists (no exclusion) * * @return void */ public function testBasicFindsNoRecord() { $validator = new RecordExists(['table' => 'users', 'field' => 'field1', 'adapter' => $this->getMockNoResult()]); $this->assertFalse($validator->isValid('nosuchvalue')); } /** * Test the exclusion function * * @return void */ public function testExcludeWithArray() { $validator = new RecordExists(['table' => 'users', 'field' => 'field1', 'exclude' => ['field' => 'id', 'value' => 1], 'adapter' => $this->getMockHasResult()]); $this->assertTrue($validator->isValid('value3')); } /** * Test the exclusion function * with an array * * @return void */ public function testExcludeWithArrayNoRecord() { $validator = new RecordExists(['table' => 'users', 'field' => 'field1', 'exclude' => ['field' => 'id', 'value' => 1], 'adapter' => $this->getMockNoResult()]); $this->assertFalse($validator->isValid('nosuchvalue')); } /** * Test the exclusion function * with a string * * @return void */ public function testExcludeWithString() { $validator = new RecordExists(['table' => 'users', 'field' => 'field1', 'exclude' => 'id != 1', 'adapter' => $this->getMockHasResult()]); $this->assertTrue($validator->isValid('value3')); } /** * Test the exclusion function * with a string * * @return void */ public function testExcludeWithStringNoRecord() { $validator = new RecordExists('users', 'field1', 'id != 1', $this->getMockNoResult()); $this->assertFalse($validator->isValid('nosuchvalue')); } /** * @group ZF-8863 */ public function testExcludeConstructor() { $validator = new RecordExists('users', 'field1', 'id != 1', $this->getMockHasResult()); $this->assertTrue($validator->isValid('value3')); } /** * Test that the class throws an exception if no adapter is provided * and no default is set. * * @return void */ public function testThrowsExceptionWithNoAdapter() { $validator = new RecordExists('users', 'field1', 'id != 1'); $this->expectException(RuntimeException::class); $this->expectExceptionMessage('No database adapter present'); $validator->isValid('nosuchvalue'); } /** * Test that schemas are supported and run without error * * @return void */ public function testWithSchema() { $validator = new RecordExists([ 'table' => 'users', 'schema' => 'my' ], 'field1', null, $this->getMockHasResult()); $this->assertTrue($validator->isValid('value1')); } /** * Test that schemas are supported and run without error * * @return void */ public function testWithSchemaNoResult() { $validator = new RecordExists([ 'table' => 'users', 'schema' => 'my' ], 'field1', null, $this->getMockNoResult()); $this->assertFalse($validator->isValid('value1')); } /** * Test that the supplied table and schema are successfully passed to the select * statement */ public function testSelectAcknowledgesTableAndSchema() { $validator = new RecordExists([ 'table' => 'users', 'schema' => 'my' ], 'field1', null, $this->getMockHasResult()); $table = $validator->getSelect()->getRawState('table'); $this->assertInstanceOf(TableIdentifier::class, $table); $this->assertEquals(['users', 'my'], $table->getTableAndSchema()); } public function testEqualsMessageTemplates() { $validator = new RecordExists('users', 'field1'); $this->assertAttributeEquals( $validator->getOption('messageTemplates'), 'messageTemplates', $validator ); } /** * @testdox Zend\Validator\Db\RecordExists::getSelect */ public function testGetSelect() { $validator = new RecordExists( [ 'table' => 'users', 'schema' => 'my' ], 'field1', [ 'field' => 'foo', 'value' => 'bar' ], $this->getMockHasResult() ); $select = $validator->getSelect(); $this->assertInstanceOf(Select::class, $select); $this->assertEquals( 'SELECT "my"."users"."field1" AS "field1" FROM "my"."users" WHERE "field1" = \'\' AND "foo" != \'bar\'', $select->getSqlString(new TrustingSql92Platform()) ); $sql = new Sql($this->getMockHasResult()); $statement = $sql->prepareStatementForSqlObject($select); $parameters = $statement->getParameterContainer(); $this->assertNull($parameters['where1']); $this->assertEquals($parameters['where2'], 'bar'); } /** * @cover Zend\Validator\Db\RecordExists::getSelect * @group ZF2-4521 */ public function testGetSelectWithSameValidatorTwice() { $validator = new RecordExists( [ 'table' => 'users', 'schema' => 'my' ], 'field1', [ 'field' => 'foo', 'value' => 'bar' ], $this->getMockHasResult() ); $select = $validator->getSelect(); $this->assertInstanceOf(Select::class, $select); $this->assertEquals( 'SELECT "my"."users"."field1" AS "field1" FROM "my"."users" WHERE "field1" = \'\' AND "foo" != \'bar\'', $select->getSqlString(new TrustingSql92Platform()) ); // same validator instance with changing properties $validator->setTable('othertable'); $validator->setSchema('otherschema'); $validator->setField('fieldother'); $validator->setExclude([ 'field' => 'fieldexclude', 'value' => 'fieldvalueexclude', ]); $select = $validator->getSelect(); $this->assertInstanceOf(Select::class, $select); $this->assertEquals( 'SELECT "otherschema"."othertable"."fieldother" AS "fieldother" FROM "otherschema"."othertable" ' . 'WHERE "fieldother" = \'\' AND "fieldexclude" != \'fieldvalueexclude\'', $select->getSqlString(new TrustingSql92Platform()) ); } } ================================================ FILE: test/Db/TestAsset/ConcreteDbValidator.php ================================================ '%value% was passed', 'barMessage' => '%value% was wrong' ]; public function isValid($value) { $this->setValue($value); $this->error(self::FOO_MESSAGE); $this->error(self::BAR_MESSAGE); return false; } } ================================================ FILE: test/Db/TestAsset/TrustingSql92Platform.php ================================================ quoteTrustedValue($value); } } ================================================ FILE: test/DigitsTest.php ================================================ validator = new Digits(); } /** * Ensures that the validator follows expected behavior for basic input values * * @return void */ public function testExpectedResultsWithBasicInputValues() { $valuesExpected = [ 'abc123' => false, 'abc 123' => false, 'abcxyz' => false, 'AZ@#4.3' => false, '1.23' => false, '0x9f' => false, '123' => true, '09' => true, '' => false ]; foreach ($valuesExpected as $input => $result) { $this->assertEquals($result, $this->validator->isValid($input)); } } /** * Ensures that getMessages() returns expected initial value * * @return void */ public function testMessagesEmptyInitially() { $this->assertEquals([], $this->validator->getMessages()); } /** * @return void */ public function testEmptyStringValueResultsInProperValidationFailureMessages() { $this->assertFalse($this->validator->isValid('')); $messages = $this->validator->getMessages(); $arrayExpected = [ Digits::STRING_EMPTY => 'The input is an empty string' ]; $this->assertThat($messages, $this->identicalTo($arrayExpected)); } /** * @return void */ public function testInvalidValueResultsInProperValidationFailureMessages() { $this->assertFalse($this->validator->isValid('#')); $messages = $this->validator->getMessages(); $arrayExpected = [ Digits::NOT_DIGITS => 'The input must contain only digits' ]; $this->assertThat($messages, $this->identicalTo($arrayExpected)); } /** * @ZF-4352 */ public function testNonStringValidation() { $this->assertFalse($this->validator->isValid([1 => 1])); } public function testEqualsMessageTemplates() { $validator = $this->validator; $this->assertAttributeEquals( $validator->getOption('messageTemplates'), 'messageTemplates', $validator ); } } ================================================ FILE: test/EmailAddressTest.php ================================================ validator = new EmailAddress(); } /** * Ensures that a basic valid e-mail address passes validation * * @return void */ public function testBasic() { $this->assertTrue($this->validator->isValid('username@example.com')); } /** * Ensures that localhost address is valid * * @return void */ public function testLocalhostAllowed() { $validator = new EmailAddress(Hostname::ALLOW_ALL); $this->assertTrue($validator->isValid('username@localhost')); } /** * Ensures that local domain names are valid * * @return void */ public function testLocaldomainAllowed() { $validator = new EmailAddress(Hostname::ALLOW_ALL); $this->assertTrue($validator->isValid('username@localhost.localdomain')); } /** * Ensures that IP hostnames are valid * * @return void */ public function testIPAllowed() { $validator = new EmailAddress(Hostname::ALLOW_DNS | Hostname::ALLOW_IP); $valuesExpected = [ [Hostname::ALLOW_DNS, true, ['bob@212.212.20.4']], [Hostname::ALLOW_DNS, false, ['bob@localhost']] ]; foreach ($valuesExpected as $element) { foreach ($element[2] as $input) { $this->assertEquals($element[1], $validator->isValid($input), implode("\n", $validator->getMessages())); } } } /** * Ensures that validation fails when the local part is missing * * @return void */ public function testLocalPartMissing() { $this->assertFalse($this->validator->isValid('@example.com')); $messages = $this->validator->getMessages(); $this->assertEquals(1, count($messages)); $this->assertContains('local-part@hostname', current($messages)); } /** * Ensures that validation fails and produces the expected messages when the local part is invalid * * @return void */ public function testLocalPartInvalid() { $this->assertFalse($this->validator->isValid('Some User@example.com')); $messages = $this->validator->getMessages(); $this->assertEquals(3, count($messages)); $this->assertContains('Some User', current($messages)); $this->assertContains('dot-atom', current($messages)); $this->assertContains('Some User', next($messages)); $this->assertContains('quoted-string', current($messages)); $this->assertContains('Some User', next($messages)); $this->assertContains('not a valid local part', current($messages)); } /** * Ensures that no validation failure message is produced when the local part follows the quoted-string format * * @return void */ public function testLocalPartQuotedString() { $this->assertTrue($this->validator->isValid('"Some User"@example.com')); $messages = $this->validator->getMessages(); $this->assertInternalType('array', $messages); $this->assertEquals(0, count($messages)); } /** * Ensures that validation fails when the hostname is invalid * * @return void */ public function testHostnameInvalid() { $this->assertFalse($this->validator->isValid('username@ example . com')); $messages = $this->validator->getMessages(); $this->assertThat(count($messages), $this->greaterThanOrEqual(1)); $this->assertContains('not a valid hostname', current($messages)); } /** * Ensures that quoted-string local part is considered valid * * @return void */ public function testQuotedString() { $emailAddresses = [ '""@domain.com', // Optional '" "@domain.com', // x20 '"!"@domain.com', // x21 '"\""@domain.com', // \" (escaped x22) '"#"@domain.com', // x23 '"$"@domain.com', // x24 '"Z"@domain.com', // x5A '"["@domain.com', // x5B '"\\\"@domain.com', // \\ (escaped x5C) '"]"@domain.com', // x5D '"^"@domain.com', // x5E '"}"@domain.com', // x7D '"~"@domain.com', // x7E '"username"@example.com', '"bob%jones"@domain.com', '"bob jones"@domain.com', '"bob@jones"@domain.com', '"[[ bob ]]"@domain.com', '"jones"@domain.com' ]; foreach ($emailAddresses as $input) { $this->assertTrue($this->validator->isValid($input), "$input failed to pass validation:\n" . implode("\n", $this->validator->getMessages())); } } /** * Ensures that quoted-string local part is considered invalid * * @return void */ public function testInvalidQuotedString() { $emailAddresses = [ "\"\x00\"@example.com", "\"\x01\"@example.com", "\"\x1E\"@example.com", "\"\x1F\"@example.com", '"""@example.com', // x22 (not escaped) '"\"@example.com', // x5C (not escaped) "\"\x7F\"@example.com", ]; foreach ($emailAddresses as $input) { $this->assertFalse($this->validator->isValid($input), "$input failed to pass validation:\n" . implode("\n", $this->validator->getMessages())); } } /** * Ensures that validation fails when the e-mail is given as for display, * with angle brackets around the actual address * * @return void */ public function testEmailDisplay() { $this->assertFalse($this->validator->isValid('User Name ')); $messages = $this->validator->getMessages(); $this->assertThat(count($messages), $this->greaterThanOrEqual(3)); $this->assertContains('not a valid hostname', current($messages)); $this->assertContains('cannot match TLD', next($messages)); $this->assertContains('does not appear to be a valid local network name', next($messages)); } public function validEmailAddresses() { // @codingStandardsIgnoreStart $return = [ 'bob@domain.com' => ['bob@domain.com'], 'bob.jones@domain.co.uk' => ['bob.jones@domain.co.uk'], 'bob.jones.smythe@domain.co.uk' => ['bob.jones.smythe@domain.co.uk'], 'BoB@domain.museum' => ['BoB@domain.museum'], 'bobjones@domain.info' => ['bobjones@domain.info'], 'bob+jones@domain.us' => ['bob+jones@domain.us'], 'bob+jones@domain.co.uk' => ['bob+jones@domain.co.uk'], 'bob@some.domain.uk.com' => ['bob@some.domain.uk.com'], 'bob@verylongdomainsupercalifragilisticexpialidociousspoonfulofsugar.com' => ['bob@verylongdomainsupercalifragilisticexpialidociousspoonfulofsugar.com'], "B.O'Callaghan@domain.com" => ["B.O'Callaghan@domain.com"], ]; if (extension_loaded('intl')) { $return['иван@письмо.рф'] = ['иван@письмо.рф']; $return['öäü@ä-umlaut.de'] = ['öäü@ä-umlaut.de']; $return['frédéric@domain.com'] = ['frédéric@domain.com']; $return['bob@тест.рф'] = ['bob@тест.рф']; $return['bob@xn--e1aybc.xn--p1ai'] = ['bob@xn--e1aybc.xn--p1ai']; } return $return; // @codingStandardsIgnoreEnd } /** * Ensures that the validator follows expected behavior for valid email addresses * * @dataProvider validEmailAddresses */ public function testBasicValid($value) { $this->assertTrue( $this->validator->isValid($value), sprintf( '%s failed validation: %s', $value, implode("\n", $this->validator->getMessages()) ) ); } public function invalidEmailAddresses() { // @codingStandardsIgnoreStart return [ '[empty]' => [''], 'bob jones@domain.com' => ['bob jones@domain.com'], '.bobJones@studio24.com' => ['.bobJones@studio24.com'], 'bobJones.@studio24.com' => ['bobJones.@studio24.com'], 'bob.Jones.@studio24.com' => ['bob.Jones.@studio24.com'], 'bob@verylongdomainsupercalifragilisticexpialidociousaspoonfulofsugar.com' => ['bob@verylongdomainsupercalifragilisticexpialidociousaspoonfulofsugar.com'], 'bob+domain.com' => ['bob+domain.com'], 'bob.domain.com' => ['bob.domain.com'], 'bob @domain.com' => ['bob @domain.com'], 'bob@ domain.com' => ['bob@ domain.com'], 'bob @ domain.com' => ['bob @ domain.com'], 'Abc..123@example.com' => ['Abc..123@example.com'], '"bob%jones@domain.com' => ['"bob%jones@domain.com'], 'multiline' => ['bob @domain.com'], ]; // @codingStandardsIgnoreEnd } /** * Ensures that the validator follows expected behavior for invalid email addresses * * @dataProvider invalidEmailAddresses */ public function testBasicInvalid($value) { $this->assertFalse($this->validator->isValid($value)); } /** * Ensures that the validator follows expected behavior for valid email addresses with complex local parts * * @return void */ public function testComplexLocalValid() { $emailAddresses = [ 'Bob.Jones@domain.com', 'Bob.Jones!@domain.com', 'Bob&Jones@domain.com', '/Bob.Jones@domain.com', '#Bob.Jones@domain.com', 'Bob.Jones?@domain.com', 'Bob~Jones@domain.com' ]; foreach ($emailAddresses as $input) { $this->assertTrue($this->validator->isValid($input)); } } /** * Ensures that the validator follows expected behavior for valid email addresses with the non-strict option * * @return void */ public function testNonStrict() { $validator = new EmailAddress(['strict' => false]); $emailAddresses = [ // RFC 5321 does mention a limit of 64 for the username, // but it also states "To the maximum extent possible, // implementation techniques that impose no limits on the // length of these objects should be used.". // http://tools.ietf.org/html/rfc5321#section-4.5.3.1 'line length 320' => str_repeat('x', 309).'@domain.com', 'line length 321' => str_repeat('x', 310).'@domain.com', 'line length 911' => str_repeat('x', 900).'@domain.com', ]; foreach ($emailAddresses as $input) { $this->assertTrue($validator->isValid($input)); } } /** * Ensures that the validator follows expected behavior for checking MX records * * @return void */ public function testMXRecords() { $this->skipIfOnlineTestsDisabled(); $validator = new EmailAddress(Hostname::ALLOW_DNS, true); // Are MX checks supported by this system? if (! $validator->isMxSupported()) { $this->markTestSkipped('Testing MX records is not supported with this configuration'); } $valuesExpected = [ [true, ['Bob.Jones@zend.com', 'Bob.Jones@php.net']], [false, ['Bob.Jones@bad.example.com', 'Bob.Jones@anotherbad.example.com']] ]; foreach ($valuesExpected as $element) { foreach ($element[1] as $input) { $this->assertEquals($element[0], $validator->isValid($input), implode("\n", $validator->getMessages())); } } // Try a check via setting the option via a method unset($validator); $validator = new EmailAddress(); $validator->useMxCheck(true); foreach ($valuesExpected as $element) { foreach ($element[1] as $input) { $this->assertEquals($element[0], $validator->isValid($input), implode("\n", $validator->getMessages())); } } } /** * Ensures that the validator follows expected behavior for checking MX records with A record fallback. * This behavior is documented in RFC 2821, section 5: "If no MX records are found, but an A RR is * found, the A RR is treated as if it was associated with an implicit MX RR, with a preference of 0, * pointing to that host. * * @return void */ public function testNoMxRecordARecordFallback() { $this->skipIfOnlineTestsDisabled(); $validator = new EmailAddress(Hostname::ALLOW_DNS, true); // Are MX checks supported by this system? if (! $validator->isMxSupported()) { $this->markTestSkipped('Testing MX records is not supported with this configuration'); } $email = 'good@example.com'; $host = preg_replace('/.*@/', null, $email); //Assert that email host contains no MX records. $this->assertFalse(checkdnsrr($host, 'MX'), 'Email host contains MX records'); //Asert that email host contains at least one A record. $this->assertTrue(checkdnsrr($host, 'A'), 'Email host contains no A records'); //Assert that validtor falls back to A record. $this->assertTrue($validator->isValid($email), implode("\n", $validator->getMessages())); } /** * Test changing hostname settings via EmailAddress object * * @return void */ public function testHostnameSettings() { $validator = new EmailAddress(); // Check no IDN matching $validator->getHostnameValidator()->useIdnCheck(false); $valuesExpected = [ [false, ['name@b�rger.de', 'name@h�llo.de', 'name@h�llo.se']] ]; foreach ($valuesExpected as $element) { foreach ($element[1] as $input) { $this->assertEquals($element[0], $validator->isValid($input), implode("\n", $validator->getMessages())); } } // Check no TLD matching $validator->getHostnameValidator()->useTldCheck(false); $valuesExpected = [ [true, ['name@domain.xx', 'name@domain.zz', 'name@domain.madeup']] ]; foreach ($valuesExpected as $element) { foreach ($element[1] as $input) { $this->assertEquals($element[0], $validator->isValid($input), implode("\n", $validator->getMessages())); } } } /** * Ensures that getMessages() returns expected default value (an empty array) * * @return void */ public function testGetMessages() { $this->assertEquals([], $this->validator->getMessages()); } /** * @group ZF-2861 */ public function testHostnameValidatorMessagesShouldBeTranslated() { if (! extension_loaded('intl')) { $this->markTestSkipped('ext/intl not enabled'); } $hostnameValidator = new Hostname(); $translations = [ 'hostnameIpAddressNotAllowed' => 'hostnameIpAddressNotAllowed translation', 'hostnameUnknownTld' => 'The input appears to be a DNS hostname ' . 'but cannot match TLD against known list', 'hostnameDashCharacter' => 'hostnameDashCharacter translation', 'hostnameInvalidHostnameSchema' => 'hostnameInvalidHostnameSchema translation', 'hostnameUndecipherableTld' => 'hostnameUndecipherableTld translation', 'hostnameInvalidHostname' => 'hostnameInvalidHostname translation', 'hostnameInvalidLocalName' => 'hostnameInvalidLocalName translation', 'hostnameLocalNameNotAllowed' => 'hostnameLocalNameNotAllowed translation', ]; $loader = new TestAsset\ArrayTranslator(); $loader->translations = $translations; $translator = new TestAsset\Translator(); $translator->getPluginManager()->setService('test', $loader); $translator->addTranslationFile('test', null); $this->validator->setTranslator($translator)->setHostnameValidator($hostnameValidator); $this->validator->isValid('_XX.!!3xx@0.239,512.777'); $messages = $hostnameValidator->getMessages(); $found = false; foreach ($messages as $code => $message) { if (array_key_exists($code, $translations)) { $this->assertEquals($translations[$code], $message); $found = true; break; } } $this->assertTrue($found); } /** * @group ZF-4888 */ public function testEmailsExceedingLength() { // @codingStandardsIgnoreStart $emailAddresses = [ 'thislocalpathoftheemailadressislongerthantheallowedsizeof64characters@domain.com', 'bob@verylongdomainsupercalifragilisticexpialidociousspoonfulofsugarverylongdomainsupercalifragilisticexpialidociousspoonfulofsugarverylongdomainsupercalifragilisticexpialidociousspoonfulofsugarverylongdomainsupercalifragilisticexpialidociousspoonfulofsugarexpialidociousspoonfulofsugar.com', ]; // @codingStandardsIgnoreEnd foreach ($emailAddresses as $input) { $this->assertFalse($this->validator->isValid($input)); } } /** * @group ZF-4352 */ public function testNonStringValidation() { $this->assertFalse($this->validator->isValid([1 => 1])); } /** * @group ZF-7490 */ public function testSettingHostnameMessagesThroughEmailValidator() { $translations = [ 'hostnameIpAddressNotAllowed' => 'hostnameIpAddressNotAllowed translation', 'hostnameUnknownTld' => 'hostnameUnknownTld translation', 'hostnameDashCharacter' => 'hostnameDashCharacter translation', 'hostnameInvalidHostnameSchema' => 'hostnameInvalidHostnameSchema translation', 'hostnameUndecipherableTld' => 'hostnameUndecipherableTld translation', 'hostnameInvalidHostname' => 'hostnameInvalidHostname translation', 'hostnameInvalidLocalName' => 'hostnameInvalidLocalName translation', 'hostnameLocalNameNotAllowed' => 'hostnameLocalNameNotAllowed translation', ]; $this->validator->setMessages($translations); $this->validator->isValid('_XX.!!3xx@0.239,512.777'); $messages = $this->validator->getMessages(); $found = false; foreach ($messages as $code => $message) { if (array_key_exists($code, $translations)) { $this->assertEquals($translations[$code], $message); $found = true; break; } } $this->assertTrue($found); } /** * Testing initializing with several options */ public function testInstanceWithOldOptions() { $handler = set_error_handler([$this, 'errorHandler'], E_USER_NOTICE); $validator = new EmailAddress(); $options = $validator->getOptions(); $this->assertEquals(Hostname::ALLOW_DNS, $options['allow']); $this->assertFalse($options['useMxCheck']); try { $validator = new EmailAddress(Hostname::ALLOW_ALL, true, new Hostname(Hostname::ALLOW_ALL)); $options = $validator->getOptions(); $this->assertEquals(Hostname::ALLOW_ALL, $options['allow']); $this->assertTrue($options['useMxCheck']); set_error_handler($handler); } catch (\Zend\Validator\Exception\InvalidArgumentException $e) { $this->markTestSkipped('MX not available on this system'); } } /** * Testing setOptions */ public function testSetOptions() { $this->validator->setOptions(['messages' => [EmailAddress::INVALID => 'TestMessage']]); $messages = $this->validator->getMessageTemplates(); $this->assertEquals('TestMessage', $messages[EmailAddress::INVALID]); $oldHostname = $this->validator->getHostnameValidator(); $this->validator->setOptions(['hostnameValidator' => new Hostname(Hostname::ALLOW_ALL)]); $hostname = $this->validator->getHostnameValidator(); $this->assertNotEquals($oldHostname, $hostname); } /** * Testing setMessage */ public function testSetSingleMessage() { $messages = $this->validator->getMessageTemplates(); $this->assertNotEquals('TestMessage', $messages[EmailAddress::INVALID]); $this->validator->setMessage('TestMessage', EmailAddress::INVALID); $messages = $this->validator->getMessageTemplates(); $this->assertEquals('TestMessage', $messages[EmailAddress::INVALID]); } public function testSetSingleMessageViaOptions() { $validator = new EmailAddress(['message' => 'TestMessage']); foreach ($validator->getMessageTemplates() as $message) { $this->assertEquals('TestMessage', $message); } foreach ($validator->getHostnameValidator()->getMessageTemplates() as $message) { $this->assertEquals('TestMessage', $message); } } public function testSetMultipleMessageViaOptions() { $validator = new EmailAddress(['messages' => [EmailAddress::INVALID => 'TestMessage']]); $messages = $validator->getMessageTemplates(); $this->assertEquals('TestMessage', $messages[EmailAddress::INVALID]); } /** * Testing getValidateMx */ public function testGetValidateMx() { $this->assertFalse($this->validator->getMxCheck()); } /** * Testing getDeepMxCheck */ public function testGetDeepMxCheck() { $this->assertFalse($this->validator->getDeepMxCheck()); } /** * Testing setMessage for all messages * * @group ZF-10690 */ public function testSetMultipleMessages() { $messages = $this->validator->getMessageTemplates(); $this->assertNotEquals('TestMessage', $messages[EmailAddress::INVALID]); $this->validator->setMessage('TestMessage'); foreach ($this->validator->getMessageTemplates() as $message) { $this->assertEquals('TestMessage', $message); } foreach ($this->validator->getHostnameValidator()->getMessageTemplates() as $message) { $this->assertEquals('TestMessage', $message); } } /** * Testing getDomainCheck */ public function testGetDomainCheck() { $this->assertTrue($this->validator->getDomainCheck()); } public function errorHandler($errno, $errstr) { if (strstr($errstr, 'deprecated')) { $this->multipleOptionsDetected = true; } } /** * @group ZF-11222 * @group ZF-11451 */ public function testEmailAddressesWithTrailingDotInHostPartAreRejected() { $this->assertFalse($this->validator->isValid('example@gmail.com.')); $this->assertFalse($this->validator->isValid('test@test.co.')); $this->assertFalse($this->validator->isValid('test@test.co.za.')); } /** * @group ZF-11239 */ public function testNotSetHostnameValidator() { $hostname = $this->validator->getHostnameValidator(); $this->assertInstanceOf(Hostname::class, $hostname); } public function testIsMxSupported() { $validator = new EmailAddress(['useMxCheck' => true, 'allow' => Hostname::ALLOW_ALL]); $this->assertInternalType('bool', $validator->isMxSupported()); } /** * Test getMXRecord */ public function testGetMXRecord() { $this->skipIfOnlineTestsDisabled(); $validator = new EmailAddress(['useMxCheck' => true, 'allow' => Hostname::ALLOW_ALL]); if (! $validator->isMxSupported()) { $this->markTestSkipped('Testing MX records is not supported with this configuration'); } $this->assertTrue($validator->isValid('john.doe@gmail.com')); $result = $validator->getMXRecord(); $this->assertNotEmpty($result); } public function testEqualsMessageTemplates() { $validator = $this->validator; $this->assertAttributeEquals( $validator->getOption('messageTemplates'), 'messageTemplates', $validator ); } public function testEqualsMessageVariables() { $validator = $this->validator; $this->assertAttributeEquals( $validator->getOption('messageVariables'), 'messageVariables', $validator ); } /** * @group ZF2-130 */ public function testUseMxCheckBasicValid() { $this->skipIfOnlineTestsDisabled(); $validator = new EmailAddress([ 'useMxCheck' => true, 'useDeepMxCheck' => true ]); $emailAddresses = [ 'bob@gmail.com', 'bob.jones@bbc.co.uk', 'bob.jones.smythe@bbc.co.uk', 'BoB@aol.com', 'bobjones@nist.gov', "B.O'Callaghan@usmc.mil", 'bob+jones@nic.us', 'bob+jones@dailymail.co.uk', 'bob@teaparty.uk.com', 'bob@thelongestdomainnameintheworldandthensomeandthensomemoreandmore.com' ]; if (extension_loaded('intl')) { $emailAddresses[] = 'test@письмо.рф'; $emailAddresses[] = 'test@xn--h1aigbl0e.xn--p1ai'; } foreach ($emailAddresses as $input) { $this->assertTrue($validator->isValid($input), "$input failed to pass validation:\n" . implode("\n", $validator->getMessages())); } } /** * @group ZF2-130 */ public function testUseMxRecordsBasicInvalid() { $validator = new EmailAddress([ 'useMxCheck' => true, 'useDeepMxCheck' => true ]); $emailAddresses = [ '', 'bob @domain.com', 'bob jones@domain.com', '.bobJones@studio24.com', 'bobJones.@studio24.com', 'bob.Jones.@studio24.com', '"bob%jones@domain.com', 'bob@verylongdomainsupercalifragilisticexpialidociousaspoonfulofsugar.com', 'bob+domain.com', 'bob.domain.com', 'bob @domain.com', 'bob@ domain.com', 'bob @ domain.com', 'Abc..123@example.com' ]; if (! extension_loaded('intl')) { $emailAddresses[] = 'иван@письмо.рф'; $emailAddresses[] = 'xn--@-7sbfxdyelgv5j.xn--p1ai'; } foreach ($emailAddresses as $input) { $this->assertFalse($validator->isValid($input), implode("\n", $this->validator->getMessages()) . $input); } } /** * @group ZF-12349 */ public function testReservedIpRangeValidation() { $validator = new TestAsset\EmailValidatorWithExposedIsReserved(); // 0.0.0.0/8 $this->assertTrue($validator->isReserved('0.0.0.0')); $this->assertTrue($validator->isReserved('0.255.255.255')); // 10.0.0.0/8 $this->assertTrue($validator->isReserved('10.0.0.0')); $this->assertTrue($validator->isReserved('10.255.255.255')); // 127.0.0.0/8 $this->assertTrue($validator->isReserved('127.0.0.0')); $this->assertTrue($validator->isReserved('127.255.255.255')); // 100.64.0.0/10 $this->assertTrue($validator->isReserved('100.64.0.0')); $this->assertTrue($validator->isReserved('100.127.255.255')); // 172.16.0.0/12 $this->assertTrue($validator->isReserved('172.16.0.0')); $this->assertTrue($validator->isReserved('172.31.255.255')); // 198.18.0.0./15 $this->assertTrue($validator->isReserved('198.18.0.0')); $this->assertTrue($validator->isReserved('198.19.255.255')); // 169.254.0.0/16 $this->assertTrue($validator->isReserved('169.254.0.0')); $this->assertTrue($validator->isReserved('169.254.255.255')); // 192.168.0.0/16 $this->assertTrue($validator->isReserved('192.168.0.0')); $this->assertTrue($validator->isReserved('192.168.255.25')); // 192.0.2.0/24 $this->assertTrue($validator->isReserved('192.0.2.0')); $this->assertTrue($validator->isReserved('192.0.2.255')); // 192.88.99.0/24 $this->assertTrue($validator->isReserved('192.88.99.0')); $this->assertTrue($validator->isReserved('192.88.99.255')); // 198.51.100.0/24 $this->assertTrue($validator->isReserved('198.51.100.0')); $this->assertTrue($validator->isReserved('198.51.100.255')); // 203.0.113.0/24 $this->assertTrue($validator->isReserved('203.0.113.0')); $this->assertTrue($validator->isReserved('203.0.113.255')); // 224.0.0.0/4 $this->assertTrue($validator->isReserved('224.0.0.0')); $this->assertTrue($validator->isReserved('239.255.255.255')); // 240.0.0.0/4 $this->assertTrue($validator->isReserved('240.0.0.0')); $this->assertTrue($validator->isReserved('255.255.255.254')); // 255.255.255.255/32 $this->assertTrue($validator->isReserved('255.255.55.255')); } /** * @group ZF-12349 */ public function testIpRangeValidationOnRangesNoLongerMarkedAsReserved() { $validator = new TestAsset\EmailValidatorWithExposedIsReserved(); // 128.0.0.0/16 $this->assertFalse($validator->isReserved('128.0.0.0')); $this->assertFalse($validator->isReserved('128.0.255.255')); // 191.255.0.0/16 $this->assertFalse($validator->isReserved('191.255.0.0')); $this->assertFalse($validator->isReserved('191.255.255.255')); // 223.255.255.0/24 $this->assertFalse($validator->isReserved('223.255.255.0')); $this->assertFalse($validator->isReserved('223.255.255.255')); } /** * @throws \PHPUnit_Framework_SkippedTestError * * @return void */ private function skipIfOnlineTestsDisabled() { if (! getenv('TESTS_ZEND_VALIDATOR_ONLINE_ENABLED')) { $this->markTestSkipped('Testing MX records has been disabled'); } } public function testCanSetDomainCheckFlag() { $validator = new EmailAddress(); $validator->useDomainCheck(false); $this->assertFalse($validator->getDomainCheck()); } } ================================================ FILE: test/ExplodeTest.php ================================================ expectException(RuntimeException::class); $this->expectExceptionMessage('validator'); $validator->isValid('foo,bar'); } public function getExpectedData() { return [ // value delim break N valid messages expects ['foo,bar,dev,null', ',', false, 4, true, [], true], ['foo,bar,dev,null', ',', true, 1, false, ['X'], false], ['foo,bar,dev,null', ',', false, 4, false, ['X'], false], ['foo,bar,dev,null', ';', false, 1, true, [], true], ['foo;bar,dev;null', ',', false, 2, true, [], true], ['foo;bar,dev;null', ',', false, 2, false, ['X'], false], ['foo;bar;dev;null', ';', false, 4, true, [], true], ['foo', ',', false, 1, true, [], true], ['foo', ',', false, 1, false, ['X'], false], ['foo', ',', true, 1, false, ['X'], false], [['a', 'b'], null, false, 2, true, [], true], [['a', 'b'], null, false, 2, false, ['X'], false], ['foo', null, false, 1, true, [], true], [1, ',', false, 1, true, [], true], [null, ',', false, 1, true, [], true], [new \stdClass(), ',', false, 1, true, [], true], [new \ArrayObject(['a', 'b']), null, false, 2, true, [], true], ]; } /** * @dataProvider getExpectedData */ public function testExpectedBehavior( $value, $delimiter, $breakOnFirst, $numIsValidCalls, $isValidReturn, $messages, $expects ) { $mockValidator = $this->createMock(ValidatorInterface::class); $mockValidator->expects( $this->exactly($numIsValidCalls) )->method('isValid')->will($this->returnValue($isValidReturn)); $mockValidator->expects($this->any())->method('getMessages')->will($this->returnValue('X')); $validator = new Explode([ 'validator' => $mockValidator, 'valueDelimiter' => $delimiter, 'breakOnFirstFailure' => $breakOnFirst, ]); $this->assertEquals($expects, $validator->isValid($value)); $this->assertEquals($messages, $validator->getMessages()); } public function testGetMessagesReturnsDefaultValue() { $validator = new Explode(); $this->assertEquals([], $validator->getMessages()); } public function testEqualsMessageTemplates() { $validator = new Explode([]); $this->assertAttributeEquals( $validator->getOption('messageTemplates'), 'messageTemplates', $validator ); } public function testEqualsMessageVariables() { $validator = new Explode([]); $this->assertAttributeEquals( $validator->getOption('messageVariables'), 'messageVariables', $validator ); } public function testSetValidatorAsArray() { $validator = new Explode(); $validator->setValidator( [ 'name' => 'inarray', 'options' => [ 'haystack' => [ 'a', 'b', 'c' ] ] ] ); /** @var $inArrayValidator \Zend\Validator\InArray */ $inArrayValidator = $validator->getValidator(); $this->assertInstanceOf(InArray::class, $inArrayValidator); $this->assertSame( ['a', 'b', 'c'], $inArrayValidator->getHaystack() ); } public function testSetValidatorMissingName() { $validator = new Explode(); $this->expectException(RuntimeException::class); $validator->setValidator( [ 'options' => [] ] ); } public function testSetValidatorInvalidParam() { $validator = new Explode(); $this->expectException(RuntimeException::class); $validator->setValidator('inarray'); } /** * @group ZF2-5796 */ public function testGetMessagesMultipleInvalid() { $validator = new Explode([ 'validator' => new Regex( '/^[a-zA-Z0-9.!#$%&\'*+\/=?^_`{|}~-]+@[a-zA-Z0-9-]+(?:\.[a-zA-Z0-9-]+)*$/' ), 'valueDelimiter' => ',', 'breakOnFirstFailure' => false, ]); $messages = [ 0 => [ 'regexNotMatch' => "The input does not match against pattern " . "'/^[a-zA-Z0-9.!#$%&'*+\/=?^_`{|}~-]+@[a-zA-Z0-9-]+(?:\.[a-zA-Z0-9-]+)*$/'", ], ]; $this->assertFalse($validator->isValid('zf-devteam@zend.com,abc,defghij')); $this->assertEquals($messages, $validator->getMessages()); } /** * Assert context is passed to composed validator */ public function testIsValidPassContext() { $context = 'context'; $contextSame = false; $validator = new Explode([ 'validator' => new Callback(function ($v, $c) use ($context, &$contextSame) { $contextSame = ($context === $c); return true; }), 'valueDelimiter' => ',', 'breakOnFirstFailure' => false, ]); $this->assertTrue($validator->isValid('a,b,c', $context)); $this->assertTrue($contextSame); } } ================================================ FILE: test/File/CountTest.php ================================================ 0, 'max' => 3], true, true, true, false], [['min' => 2, 'max' => 3], false, true, true, false], [['min' => 2], false, true, true, true], [['max' => 5], true, true, true, true], ]; foreach ($valuesExpected as $element) { $validator = new File\Count($element[0]); $this->assertEquals( $element[1], $validator->isValid(__DIR__ . '/_files/testsize.mo'), "Tested with " . var_export($element, 1) ); $this->assertEquals( $element[2], $validator->isValid(__DIR__ . '/_files/testsize2.mo'), "Tested with " . var_export($element, 1) ); $this->assertEquals( $element[3], $validator->isValid(__DIR__ . '/_files/testsize3.mo'), "Tested with " . var_export($element, 1) ); $this->assertEquals( $element[4], $validator->isValid(__DIR__ . '/_files/testsize4.mo'), "Tested with " . var_export($element, 1) ); } } /** * Ensures that getMin() returns expected value * * @return void */ public function testGetMin() { $validator = new File\Count(['min' => 1, 'max' => 5]); $this->assertEquals(1, $validator->getMin()); } public function testGetMinGreaterThanOrEqualThrowsException() { $this->expectException(InvalidArgumentException::class); $this->expectExceptionMessage('greater than or equal'); $validator = new File\Count(['min' => 5, 'max' => 1]); } /** * Ensures that setMin() returns expected value * * @return void */ public function testSetMin() { $validator = new File\Count(['min' => 1000, 'max' => 10000]); $validator->setMin(100); $this->assertEquals(100, $validator->getMin()); $this->expectException(InvalidArgumentException::class); $this->expectExceptionMessage('less than or equal'); $validator->setMin(20000); } /** * Ensures that getMax() returns expected value * * @return void */ public function testGetMax() { $validator = new File\Count(['min' => 1, 'max' => 100]); $this->assertEquals(100, $validator->getMax()); $this->expectException(InvalidArgumentException::class); $this->expectExceptionMessage('greater than or equal'); $validator = new File\Count(['min' => 5, 'max' => 1]); } /** * Ensures that setMax() returns expected value * * @return void */ public function testSetMax() { $validator = new File\Count(['min' => 1000, 'max' => 10000]); $validator->setMax(1000000); $this->assertEquals(1000000, $validator->getMax()); $validator->setMin(100); $this->assertEquals(1000000, $validator->getMax()); } public function testCanSetMaxValueUsingAnArrayWithMaxKey() { $validator = new File\Count(['min' => 1000, 'max' => 10000]); $maxValue = 33333333; $setMaxArray = ['max' => $maxValue]; $validator->setMax($setMaxArray); $this->assertSame($maxValue, $validator->getMax()); } public function invalidMinMaxValues() { return [ 'null' => [null], 'true' => [true], 'false' => [false], 'invalid-string' => ['will-not-work'], 'invalid-array' => [[100]], 'object' => [(object) []], ]; } /** * @dataProvider invalidMinMaxValues */ public function testSettingMaxWithInvalidArgumentRaisesException($max) { $validator = new File\Count(['min' => 1000, 'max' => 10000]); $this->expectException(InvalidArgumentException::class); $this->expectExceptionMessage('Invalid options to validator provided'); $validator->setMax($max); } public function testCanSetMinUsingAnArrayWithAMinKey() { $validator = new File\Count(['min' => 1000, 'max' => 10000]); $minValue = 33; $setMinArray = ['min' => $minValue]; $validator->setMin($setMinArray); $this->assertEquals($minValue, $validator->getMin()); } /** * @dataProvider invalidMinMaxValues */ public function testSettingMinWithInvalidArgumentRaisesException($min) { $validator = new File\Count(['min' => 1000, 'max' => 10000]); $this->expectException(InvalidArgumentException::class); $this->expectExceptionMessage('Invalid options to validator provided'); $validator->setMin($min); } public function testThrowErrorReturnsFalseAndSetsMessageWhenProvidedWithArrayRepresentingTooFewFiles() { $validator = new File\Count(['min' => 1000, 'max' => 10000]); $filename = 'test.txt'; $fileArray = ['name' => $filename]; $reflection = new ReflectionClass($validator); $method = $reflection->getMethod('throwError'); $method->setAccessible(true); $property = $reflection->getProperty('value'); $property->setAccessible(true); $result = $method->invoke($validator, $fileArray, File\Count::TOO_FEW); $this->assertFalse($result); $this->assertEquals($filename, $property->getValue($validator)); } public function testThrowErrorReturnsFalseAndSetsMessageWhenProvidedWithASingleFilename() { $validator = new File\Count(['min' => 1000, 'max' => 10000]); $filename = 'test.txt'; $reflection = new ReflectionClass($validator); $method = $reflection->getMethod('throwError'); $method->setAccessible(true); $property = $reflection->getProperty('value'); $property->setAccessible(true); $result = $method->invoke($validator, $filename, File\Count::TOO_FEW); $this->assertFalse($result); $this->assertEquals($filename, $property->getValue($validator)); } public function testCanProvideMinAndMaxAsDiscreteConstructorArguments() { $min = 1000; $max = 10000; $validator = new File\Count($min, $max); $this->assertSame($min, $validator->getMin()); $this->assertSame($max, $validator->getMax()); } } ================================================ FILE: test/File/Crc32Test.php ================================================ $data[1], 'name' => basename($data[1]), 'size' => 200, 'error' => 0, 'type' => 'text' ]; $testData[] = [$data[0], $fileUpload, $data[2], $data[3]]; } return $testData; } /** * Ensures that the validator follows expected behavior * * @dataProvider basicBehaviorDataProvider * @return void */ public function testBasic($options, $isValidParam, $expected, $messageKey) { $validator = new File\Crc32($options); $this->assertEquals($expected, $validator->isValid($isValidParam)); if (! $expected) { $this->assertArrayHasKey($messageKey, $validator->getMessages()); } } /** * Ensures that the validator follows expected behavior for legacy Zend\Transfer API * * @dataProvider basicBehaviorDataProvider * @return void */ public function testLegacy($options, $isValidParam, $expected, $messageKey) { if (is_array($isValidParam)) { $validator = new File\Crc32($options); $this->assertEquals($expected, $validator->isValid($isValidParam['tmp_name'], $isValidParam)); if (! $expected) { $this->assertArrayHasKey($messageKey, $validator->getMessages()); } } } /** * Ensures that getCrc32() returns expected value * * @return void */ public function testgetCrc32() { $validator = new File\Crc32('12345'); $this->assertEquals(['12345' => 'crc32'], $validator->getCrc32()); $validator = new File\Crc32(['12345', '12333', '12344']); $this->assertEquals(['12345' => 'crc32', '12333' => 'crc32', '12344' => 'crc32'], $validator->getCrc32()); } /** * Ensures that getHash() returns expected value * * @return void */ public function testgetHash() { $validator = new File\Crc32('12345'); $this->assertEquals(['12345' => 'crc32'], $validator->getHash()); $validator = new File\Crc32(['12345', '12333', '12344']); $this->assertEquals(['12345' => 'crc32', '12333' => 'crc32', '12344' => 'crc32'], $validator->getHash()); } /** * Ensures that setCrc32() returns expected value * * @return void */ public function testSetCrc32() { $validator = new File\Crc32('12345'); $validator->setCrc32('12333'); $this->assertEquals(['12333' => 'crc32'], $validator->getCrc32()); $validator->setCrc32(['12321', '12121']); $this->assertEquals(['12321' => 'crc32', '12121' => 'crc32'], $validator->getCrc32()); } /** * Ensures that setHash() returns expected value * * @return void */ public function testSetHash() { $validator = new File\Crc32('12345'); $validator->setHash('12333'); $this->assertEquals(['12333' => 'crc32'], $validator->getCrc32()); $validator->setHash(['12321', '12121']); $this->assertEquals(['12321' => 'crc32', '12121' => 'crc32'], $validator->getCrc32()); } /** * Ensures that addCrc32() returns expected value * * @return void */ public function testAddCrc32() { $validator = new File\Crc32('12345'); $validator->addCrc32('12344'); $this->assertEquals(['12345' => 'crc32', '12344' => 'crc32'], $validator->getCrc32()); $validator->addCrc32(['12321', '12121']); $this->assertEquals( ['12345' => 'crc32', '12344' => 'crc32', '12321' => 'crc32', '12121' => 'crc32'], $validator->getCrc32() ); } /** * Ensures that addHash() returns expected value * * @return void */ public function testAddHash() { $validator = new File\Crc32('12345'); $validator->addHash('12344'); $this->assertEquals(['12345' => 'crc32', '12344' => 'crc32'], $validator->getCrc32()); $validator->addHash(['12321', '12121']); $this->assertEquals( ['12345' => 'crc32', '12344' => 'crc32', '12321' => 'crc32', '12121' => 'crc32'], $validator->getCrc32() ); } /** * @group ZF-11258 */ public function testZF11258() { $validator = new File\Crc32('3f8d07e2'); $this->assertFalse($validator->isValid(__DIR__ . '/_files/nofile.mo')); $this->assertArrayHasKey('fileCrc32NotFound', $validator->getMessages()); $this->assertContains("does not exist", current($validator->getMessages())); } public function testEmptyFileShouldReturnFalseAndDisplayNotFoundMessage() { $validator = new File\Crc32(); $this->assertFalse($validator->isValid('')); $this->assertArrayHasKey(File\Crc32::NOT_FOUND, $validator->getMessages()); $filesArray = [ 'name' => '', 'size' => 0, 'tmp_name' => '', 'error' => UPLOAD_ERR_NO_FILE, 'type' => '', ]; $this->assertFalse($validator->isValid($filesArray)); $this->assertArrayHasKey(File\Crc32::NOT_FOUND, $validator->getMessages()); } public function testShouldThrowInvalidArgumentExceptionForArrayValueNotInFilesFormat() { $validator = new File\Crc32(); $invalidArray = ['foo' => 'bar']; $this->expectException(InvalidArgumentException::class); $validator->isValid($invalidArray); } } ================================================ FILE: test/File/ExcludeExtensionTest.php ================================================ 'gif', 'allowNonExistentFile' => true], $testFile, true, ''], ]; // Dupe data in File Upload format $testData = array_merge($pictureTests, $noFileTests); foreach ($testData as $data) { $fileUpload = [ 'tmp_name' => $data[1], 'name' => basename($data[1]), 'size' => 200, 'error' => 0, 'type' => 'text' ]; $testData[] = [$data[0], $fileUpload, $data[2], $data[3]]; } return $testData; } /** * Ensures that the validator follows expected behavior * * @dataProvider basicBehaviorDataProvider * @return void */ public function testBasic($options, $isValidParam, $expected, $messageKey) { $validator = new File\ExcludeExtension($options); $this->assertEquals($expected, $validator->isValid($isValidParam)); if (! $expected) { $this->assertArrayHasKey($messageKey, $validator->getMessages()); } } /** * Ensures that the validator follows expected behavior for legacy Zend\Transfer API * * @dataProvider basicBehaviorDataProvider * @return void */ public function testLegacy($options, $isValidParam, $expected, $messageKey) { if (is_array($isValidParam)) { $validator = new File\ExcludeExtension($options); $this->assertEquals($expected, $validator->isValid($isValidParam['tmp_name'], $isValidParam)); if (! $expected) { $this->assertArrayHasKey($messageKey, $validator->getMessages()); } } } public function testCaseTesting() { $files = [ 'name' => 'testsize.mo', 'type' => 'text', 'size' => 200, 'tmp_name' => __DIR__ . '/_files/testsize.mo', 'error' => 0 ]; $validator = new File\ExcludeExtension(['MO', 'case' => true]); $this->assertEquals(true, $validator->isValid(__DIR__ . '/_files/testsize.mo', $files)); $validator = new File\ExcludeExtension(['MO', 'case' => false]); $this->assertEquals(false, $validator->isValid(__DIR__ . '/_files/testsize.mo', $files)); } /** * Ensures that getExtension() returns expected value * * @return void */ public function testGetExtension() { $validator = new File\ExcludeExtension('mo'); $this->assertEquals(['mo'], $validator->getExtension()); $validator = new File\ExcludeExtension(['mo', 'gif', 'jpg']); $this->assertEquals(['mo', 'gif', 'jpg'], $validator->getExtension()); } /** * Ensures that setExtension() returns expected value * * @return void */ public function testSetExtension() { $validator = new File\ExcludeExtension('mo'); $validator->setExtension('gif'); $this->assertEquals(['gif'], $validator->getExtension()); $validator->setExtension('jpg, mo'); $this->assertEquals(['jpg', 'mo'], $validator->getExtension()); $validator->setExtension(['zip', 'ti']); $this->assertEquals(['zip', 'ti'], $validator->getExtension()); } /** * Ensures that addExtension() returns expected value * * @return void */ public function testAddExtension() { $validator = new File\ExcludeExtension('mo'); $validator->addExtension('gif'); $this->assertEquals(['mo', 'gif'], $validator->getExtension()); $validator->addExtension('jpg, to'); $this->assertEquals(['mo', 'gif', 'jpg', 'to'], $validator->getExtension()); $validator->addExtension(['zip', 'ti']); $this->assertEquals(['mo', 'gif', 'jpg', 'to', 'zip', 'ti'], $validator->getExtension()); $validator->addExtension(''); $this->assertEquals(['mo', 'gif', 'jpg', 'to', 'zip', 'ti'], $validator->getExtension()); } /** * @group ZF-11258 */ public function testZF11258() { $validator = new File\ExcludeExtension('mo'); $this->assertEquals(false, $validator->isValid(__DIR__ . '/_files/nofile.mo')); $this->assertArrayHasKey('fileExcludeExtensionNotFound', $validator->getMessages()); $this->assertContains("does not exist", current($validator->getMessages())); } public function testEmptyFileShouldReturnFalseAndDisplayNotFoundMessage() { $validator = new File\ExcludeExtension('12345'); $this->assertFalse($validator->isValid('')); $this->assertArrayHasKey(File\ExcludeExtension::NOT_FOUND, $validator->getMessages()); $filesArray = [ 'name' => '', 'size' => 0, 'tmp_name' => '', 'error' => UPLOAD_ERR_NO_FILE, 'type' => '', ]; $this->assertFalse($validator->isValid($filesArray)); $this->assertArrayHasKey(File\ExcludeExtension::NOT_FOUND, $validator->getMessages()); } public function testIsValidRaisesExceptionWithArrayNotInFilesFormat() { $validator = new File\ExcludeExtension('12345'); $value = ['foo' => 'bar']; $this->expectException(InvalidArgumentException::class); $this->expectExceptionMessage('Value array must be in $_FILES format'); $validator->isValid($value); } } ================================================ FILE: test/File/ExcludeMimeTypeTest.php ================================================ $testFile, 'name' => basename($testFile), 'size' => 200, 'error' => 0, 'type' => 'image/jpeg', ]; $falseTypeMessage = [ExcludeMimeType::FALSE_TYPE => "File has an incorrect mimetype of 'image/jpeg'"]; return [ // Options, isValid Param, Expected value, messages ['image/gif', $fileUpload, true, []], ['image', $fileUpload, false, $falseTypeMessage], ['test/notype', $fileUpload, true, []], ['image/gif, image/jpeg', $fileUpload, false, $falseTypeMessage], [['image/vasa', 'image/gif'], $fileUpload, true, []], [['image/gif', 'jpeg'], $fileUpload, false, $falseTypeMessage], [['image/gif', 'gif'], $fileUpload, true, []], ]; } /** * Ensures that the validator follows expected behavior * * @dataProvider basicBehaviorDataProvider * * @param string|array $options * @param array $isValidParam * @param bool $expected * @param array $messages */ public function testBasic($options, array $isValidParam, $expected, array $messages) { $validator = new ExcludeMimeType($options); $validator->enableHeaderCheck(); $this->assertEquals($expected, $validator->isValid($isValidParam)); $this->assertEquals($messages, $validator->getMessages()); } /** * Ensures that the validator follows expected behavior for legacy Zend\Transfer API * * @dataProvider basicBehaviorDataProvider * @return void */ public function testLegacy($options, $isValidParam, $expected) { if (is_array($isValidParam)) { $validator = new ExcludeMimeType($options); $validator->enableHeaderCheck(); $this->assertEquals($expected, $validator->isValid($isValidParam['tmp_name'], $isValidParam)); } } /** * Ensures that getMimeType() returns expected value * * @return void */ public function testGetMimeType() { $validator = new ExcludeMimeType('image/gif'); $this->assertEquals('image/gif', $validator->getMimeType()); $validator = new ExcludeMimeType(['image/gif', 'video', 'text/test']); $this->assertEquals('image/gif,video,text/test', $validator->getMimeType()); $validator = new ExcludeMimeType(['image/gif', 'video', 'text/test']); $this->assertEquals(['image/gif', 'video', 'text/test'], $validator->getMimeType(true)); } /** * Ensures that setMimeType() returns expected value * * @return void */ public function testSetMimeType() { $validator = new ExcludeMimeType('image/gif'); $validator->setMimeType('image/jpeg'); $this->assertEquals('image/jpeg', $validator->getMimeType()); $this->assertEquals(['image/jpeg'], $validator->getMimeType(true)); $validator->setMimeType('image/gif, text/test'); $this->assertEquals('image/gif,text/test', $validator->getMimeType()); $this->assertEquals(['image/gif', 'text/test'], $validator->getMimeType(true)); $validator->setMimeType(['video/mpeg', 'gif']); $this->assertEquals('video/mpeg,gif', $validator->getMimeType()); $this->assertEquals(['video/mpeg', 'gif'], $validator->getMimeType(true)); } /** * Ensures that addMimeType() returns expected value * * @return void */ public function testAddMimeType() { $validator = new ExcludeMimeType('image/gif'); $validator->addMimeType('text'); $this->assertEquals('image/gif,text', $validator->getMimeType()); $this->assertEquals(['image/gif', 'text'], $validator->getMimeType(true)); $validator->addMimeType('jpg, to'); $this->assertEquals('image/gif,text,jpg,to', $validator->getMimeType()); $this->assertEquals(['image/gif', 'text', 'jpg', 'to'], $validator->getMimeType(true)); $validator->addMimeType(['zip', 'ti']); $this->assertEquals('image/gif,text,jpg,to,zip,ti', $validator->getMimeType()); $this->assertEquals(['image/gif', 'text', 'jpg', 'to', 'zip', 'ti'], $validator->getMimeType(true)); $validator->addMimeType(''); $this->assertEquals('image/gif,text,jpg,to,zip,ti', $validator->getMimeType()); $this->assertEquals(['image/gif', 'text', 'jpg', 'to', 'zip', 'ti'], $validator->getMimeType(true)); } public function testEmptyFileShouldReturnFalseAndDisplayNotFoundMessage() { $validator = new ExcludeMimeType(); $this->assertFalse($validator->isValid('')); $this->assertArrayHasKey(ExcludeMimeType::NOT_READABLE, $validator->getMessages()); $this->assertNotEmpty($validator->getMessages()[ExcludeMimeType::NOT_READABLE]); } public function testEmptyArrayFileShouldReturnFalseAdnDisplayNotFoundMessage() { $validator = new ExcludeMimeType(); $filesArray = [ 'name' => '', 'size' => 0, 'tmp_name' => '', 'error' => UPLOAD_ERR_NO_FILE, 'type' => '', ]; $this->assertFalse($validator->isValid($filesArray)); $this->assertArrayHasKey(ExcludeMimeType::NOT_READABLE, $validator->getMessages()); $this->assertNotEmpty($validator->getMessages()[ExcludeMimeType::NOT_READABLE]); } public function testIsValidRaisesExceptionWithArrayNotInFilesFormat() { $validator = new ExcludeMimeType('image\gif'); $value = ['foo' => 'bar']; $this->expectException(InvalidArgumentException::class); $this->expectExceptionMessage('Value array must be in $_FILES format'); $validator->isValid($value); } } ================================================ FILE: test/File/ExistsTest.php ================================================ $testFile, 'name' => basename($testFile), 'size' => 200, 'error' => 0, 'type' => 'text' ]; return [ // Options, isValid Param, Expected value [dirname($baseDir), $baseName, false], [$baseDir, $baseName, true], [$baseDir, $testFile, true], [dirname($baseDir), $fileUpload, false], [$baseDir, $fileUpload, true], ]; } /** * Ensures that the validator follows expected behavior * * @dataProvider basicBehaviorDataProvider * @return void */ public function testBasic($options, $isValidParam, $expected) { $validator = new File\Exists($options); $this->assertEquals($expected, $validator->isValid($isValidParam)); } /** * Ensures that the validator follows expected behavior for legacy Zend\Transfer API * * @dataProvider basicBehaviorDataProvider * @return void */ public function testLegacy($options, $isValidParam, $expected) { if (is_array($isValidParam)) { $validator = new File\Exists($options); $this->assertEquals($expected, $validator->isValid($isValidParam['tmp_name'], $isValidParam)); } } /** * Ensures that getDirectory() returns expected value * * @return void */ public function testGetDirectory() { $validator = new File\Exists('C:/temp'); $this->assertEquals('C:/temp', $validator->getDirectory()); $validator = new File\Exists(['temp', 'dir', 'jpg']); $this->assertEquals('temp,dir,jpg', $validator->getDirectory()); $validator = new File\Exists(['temp', 'dir', 'jpg']); $this->assertEquals(['temp', 'dir', 'jpg'], $validator->getDirectory(true)); } /** * Ensures that setDirectory() returns expected value * * @return void */ public function testSetDirectory() { $validator = new File\Exists('temp'); $validator->setDirectory('gif'); $this->assertEquals('gif', $validator->getDirectory()); $this->assertEquals(['gif'], $validator->getDirectory(true)); $validator->setDirectory('jpg, temp'); $this->assertEquals('jpg,temp', $validator->getDirectory()); $this->assertEquals(['jpg', 'temp'], $validator->getDirectory(true)); $validator->setDirectory(['zip', 'ti']); $this->assertEquals('zip,ti', $validator->getDirectory()); $this->assertEquals(['zip', 'ti'], $validator->getDirectory(true)); } /** * Ensures that addDirectory() returns expected value * * @return void */ public function testAddDirectory() { $validator = new File\Exists('temp'); $validator->addDirectory('gif'); $this->assertEquals('temp,gif', $validator->getDirectory()); $this->assertEquals(['temp', 'gif'], $validator->getDirectory(true)); $validator->addDirectory('jpg, to'); $this->assertEquals('temp,gif,jpg,to', $validator->getDirectory()); $this->assertEquals(['temp', 'gif', 'jpg', 'to'], $validator->getDirectory(true)); $validator->addDirectory(['zip', 'ti']); $this->assertEquals('temp,gif,jpg,to,zip,ti', $validator->getDirectory()); $this->assertEquals(['temp', 'gif', 'jpg', 'to', 'zip', 'ti'], $validator->getDirectory(true)); $validator->addDirectory(''); $this->assertEquals('temp,gif,jpg,to,zip,ti', $validator->getDirectory()); $this->assertEquals(['temp', 'gif', 'jpg', 'to', 'zip', 'ti'], $validator->getDirectory(true)); } /** * @group ZF-11258 */ public function testZF11258() { $validator = new File\Exists(__DIR__); $this->assertFalse($validator->isValid('nofile.mo')); $this->assertArrayHasKey('fileExistsDoesNotExist', $validator->getMessages()); $this->assertContains("does not exist", current($validator->getMessages())); } public function testEmptyFileArrayShouldReturnFalse() { $validator = new File\Exists(); $this->assertFalse($validator->isValid('')); $this->assertArrayHasKey(File\Exists::DOES_NOT_EXIST, $validator->getMessages()); $filesArray = [ 'name' => '', 'size' => 0, 'tmp_name' => '', 'error' => UPLOAD_ERR_NO_FILE, 'type' => '', ]; $this->assertFalse($validator->isValid($filesArray)); $this->assertArrayHasKey(File\Exists::DOES_NOT_EXIST, $validator->getMessages()); } public function testIsValidShouldThrowInvalidArgumentExceptionForArrayNotInFilesFormat() { $validator = new File\Exists(); $value = ['foo' => 'bar']; $this->expectException(InvalidArgumentException::class); $this->expectExceptionMessage('Value array must be in $_FILES format'); $validator->isValid($value); } public function invalidDirectoryArguments() { return [ 'null' => [null], 'true' => [true], 'false' => [false], 'zero' => [0], 'int' => [1], 'zero-float' => [0.0], 'float' => [1.1], 'object' => [(object) []], ]; } /** * @dataProvider invalidDirectoryArguments */ public function testAddDirectoryShouldRaiseExceptionForInvalidArgument($value) { $validator = new File\Exists(); $this->expectException(InvalidArgumentException::class); $this->expectExceptionMessage('Invalid options to validator provided'); $validator->addDirectory($value); } } ================================================ FILE: test/File/ExtensionTest.php ================================================ 'mo', 'allowNonExistentFile' => true], $testFile, true, ''], ]; // Dupe data in File Upload format $testData = array_merge($pictureTests, $noFileTests); foreach ($testData as $data) { $fileUpload = [ 'tmp_name' => $data[1], 'name' => basename($data[1]), 'size' => 200, 'error' => 0, 'type' => 'text' ]; $testData[] = [$data[0], $fileUpload, $data[2], $data[3]]; } return $testData; } /** * Ensures that the validator follows expected behavior * * @dataProvider basicBehaviorDataProvider * @return void */ public function testBasic($options, $isValidParam, $expected, $messageKey) { $validator = new File\Extension($options); $this->assertEquals($expected, $validator->isValid($isValidParam)); if (! $expected) { $this->assertArrayHasKey($messageKey, $validator->getMessages()); } } /** * Ensures that the validator follows expected behavior for legacy Zend\Transfer API * * @dataProvider basicBehaviorDataProvider * @return void */ public function testLegacy($options, $isValidParam, $expected, $messageKey) { if (is_array($isValidParam)) { $validator = new File\Extension($options); $this->assertEquals($expected, $validator->isValid($isValidParam['tmp_name'], $isValidParam)); if (! $expected) { $this->assertArrayHasKey($messageKey, $validator->getMessages()); } } } /** * @return void */ public function testZF3891() { $files = [ 'name' => 'testsize.mo', 'type' => 'text', 'size' => 200, 'tmp_name' => __DIR__ . '/_files/testsize.mo', 'error' => 0 ]; $validator = new File\Extension(['MO', 'case' => true]); $this->assertEquals(false, $validator->isValid(__DIR__ . '/_files/testsize.mo', $files)); $validator = new File\Extension(['MO', 'case' => false]); $this->assertEquals(true, $validator->isValid(__DIR__ . '/_files/testsize.mo', $files)); } /** * Ensures that getExtension() returns expected value * * @return void */ public function testGetExtension() { $validator = new File\Extension('mo'); $this->assertEquals(['mo'], $validator->getExtension()); $validator = new File\Extension(['mo', 'gif', 'jpg']); $this->assertEquals(['mo', 'gif', 'jpg'], $validator->getExtension()); } /** * Ensures that setExtension() returns expected value * * @return void */ public function testSetExtension() { $validator = new File\Extension('mo'); $validator->setExtension('gif'); $this->assertEquals(['gif'], $validator->getExtension()); $validator->setExtension('jpg, mo'); $this->assertEquals(['jpg', 'mo'], $validator->getExtension()); $validator->setExtension(['zip', 'ti']); $this->assertEquals(['zip', 'ti'], $validator->getExtension()); } /** * Ensures that addExtension() returns expected value * * @return void */ public function testAddExtension() { $validator = new File\Extension('mo'); $validator->addExtension('gif'); $this->assertEquals(['mo', 'gif'], $validator->getExtension()); $validator->addExtension('jpg, to'); $this->assertEquals(['mo', 'gif', 'jpg', 'to'], $validator->getExtension()); $validator->addExtension(['zip', 'ti']); $this->assertEquals(['mo', 'gif', 'jpg', 'to', 'zip', 'ti'], $validator->getExtension()); $validator->addExtension(''); $this->assertEquals(['mo', 'gif', 'jpg', 'to', 'zip', 'ti'], $validator->getExtension()); } /** * @group ZF-11258 */ public function testZF11258() { $validator = new File\Extension('gif'); $this->assertFalse($validator->isValid(__DIR__ . '/_files/nofile.mo')); $this->assertArrayHasKey('fileExtensionNotFound', $validator->getMessages()); $this->assertContains("does not exist", current($validator->getMessages())); } public function testEmptyFileShouldReturnFalseAndDisplayNotFoundMessage() { $validator = new File\Extension('foo'); $this->assertFalse($validator->isValid('')); $this->assertArrayHasKey(File\Extension::NOT_FOUND, $validator->getMessages()); $filesArray = [ 'name' => '', 'size' => 0, 'tmp_name' => '', 'error' => UPLOAD_ERR_NO_FILE, 'type' => '', ]; $this->assertFalse($validator->isValid($filesArray)); $this->assertArrayHasKey(File\Extension::NOT_FOUND, $validator->getMessages()); } public function testIsValidRaisesExceptionForArrayNotInFilesFormat() { $validator = new File\Extension('foo'); $value = ['foo' => 'bar']; $this->expectException(InvalidArgumentException::class); $this->expectExceptionMessage('Value array must be in $_FILES format'); $validator->isValid($value); } } ================================================ FILE: test/File/FileInformationTraitTest.php ================================================ stream = $this->prophesize(StreamInterface::class); $this->upload = $this->prophesize(UploadedFileInterface::class); } public function testLegacyFileInfoBasic() { $testFile = __DIR__ . '/_files/testsize.mo'; $basename = basename($testFile); $file = [ 'name' => $basename, 'tmp_name' => $testFile ]; $fileInformation = new FileInformation(); $fileInfo = $fileInformation->checkFileInformation( $basename, $file ); $this->assertEquals($fileInfo, [ 'filename' => $file['name'], 'file' => $file['tmp_name'], ]); } public function testLegacyFileInfoWithFiletype() { $testFile = __DIR__ . '/_files/testsize.mo'; $basename = basename($testFile); $file = [ 'name' => $basename, 'tmp_name' => $testFile, 'type' => 'mo', ]; $fileInformation = new FileInformation(); $fileInfo = $fileInformation->checkFileInformation( $basename, $file, true ); $this->assertEquals($fileInfo, [ 'filename' => $file['name'], 'file' => $file['tmp_name'], 'filetype' => $file['type'], ]); } public function testLegacyFileInfoWithBasename() { $testFile = __DIR__ . '/_files/testsize.mo'; $basename = basename($testFile); $file = [ 'name' => $basename, 'tmp_name' => $testFile, ]; $fileInformation = new FileInformation(); $fileInfo = $fileInformation->checkFileInformation( $basename, $file, false, true ); $this->assertEquals($fileInfo, [ 'filename' => $file['name'], 'file' => $file['tmp_name'], 'basename' => basename($file['tmp_name']), ]); } public function testSapiFileInfoBasic() { $testFile = __DIR__ . '/_files/testsize.mo'; $file = [ 'name' => basename($testFile), 'tmp_name' => $testFile ]; $fileInformation = new FileInformation(); $fileInfo = $fileInformation->checkFileInformation( $file ); $this->assertEquals($fileInfo, [ 'filename' => $file['name'], 'file' => $file['tmp_name'], ]); } public function testSapiFileInfoWithFiletype() { $testFile = __DIR__ . '/_files/testsize.mo'; $file = [ 'name' => basename($testFile), 'tmp_name' => $testFile, 'type' => 'mo', ]; $fileInformation = new FileInformation(); $fileInfo = $fileInformation->checkFileInformation( $file, null, true ); $this->assertEquals($fileInfo, [ 'filename' => $file['name'], 'file' => $file['tmp_name'], 'filetype' => $file['type'], ]); } public function testSapiFileInfoWithBasename() { $testFile = __DIR__ . '/_files/testsize.mo'; $file = [ 'name' => basename($testFile), 'tmp_name' => $testFile, ]; $fileInformation = new FileInformation(); $fileInfo = $fileInformation->checkFileInformation( $file, null, false, true ); $this->assertEquals($fileInfo, [ 'filename' => $file['name'], 'file' => $file['tmp_name'], 'basename' => basename($file['tmp_name']), ]); } public function testPsr7FileInfoBasic() { $testFile = __DIR__ . '/_files/testsize.mo'; $this->stream->getMetadata('uri')->willReturn($testFile); $this->upload->getClientFilename()->willReturn(basename($testFile)); $this->upload->getClientMediaType()->willReturn(mime_content_type($testFile)); $this->upload->getStream()->willReturn($this->stream->reveal()); $fileInformation = new FileInformation(); $fileInfo = $fileInformation->checkFileInformation( $this->upload->reveal() ); $this->assertEquals($fileInfo, [ 'filename' => basename($testFile), 'file' => $testFile, ]); } public function testPsr7FileInfoBasicWithFiletype() { $testFile = __DIR__ . '/_files/testsize.mo'; $this->stream->getMetadata('uri')->willReturn($testFile); $this->upload->getClientFilename()->willReturn(basename($testFile)); $this->upload->getClientMediaType()->willReturn(mime_content_type($testFile)); $this->upload->getStream()->willReturn($this->stream->reveal()); $fileInformation = new FileInformation(); $fileInfo = $fileInformation->checkFileInformation( $this->upload->reveal(), null, true ); $this->assertEquals($fileInfo, [ 'filename' => basename($testFile), 'file' => $testFile, 'filetype' => mime_content_type($testFile), ]); } public function testPsr7FileInfoBasicWithBasename() { $testFile = __DIR__ . '/_files/testsize.mo'; $this->stream->getMetadata('uri')->willReturn($testFile); $this->upload->getClientFilename()->willReturn(basename($testFile)); $this->upload->getClientMediaType()->willReturn(mime_content_type($testFile)); $this->upload->getStream()->willReturn($this->stream->reveal()); $fileInformation = new FileInformation(); $fileInfo = $fileInformation->checkFileInformation( $this->upload->reveal(), null, false, true ); $this->assertEquals($fileInfo, [ 'filename' => basename($testFile), 'file' => $testFile, 'basename' => basename($testFile), ]); } public function testFileBasedFileInfoBasic() { $testFile = __DIR__ . '/_files/testsize.mo'; $fileInformation = new FileInformation(); $fileInfo = $fileInformation->checkFileInformation( $testFile ); $this->assertEquals($fileInfo, [ 'filename' => basename($testFile), 'file' => $testFile, ]); } public function testFileBasedFileInfoBasicWithFiletype() { $testFile = __DIR__ . '/_files/testsize.mo'; $fileInformation = new FileInformation(); $fileInfo = $fileInformation->checkFileInformation( $testFile, null, true ); $this->assertEquals($fileInfo, [ 'filename' => basename($testFile), 'file' => $testFile, 'filetype' => null ]); } public function testFileBasedFileInfoBasicWithBasename() { $testFile = __DIR__ . '/_files/testsize.mo'; $fileInformation = new FileInformation(); $fileInfo = $fileInformation->checkFileInformation( $testFile, null, false, true ); $this->assertEquals($fileInfo, [ 'filename' => basename($testFile), 'file' => $testFile, 'basename' => basename($testFile) ]); } } ================================================ FILE: test/File/FilesSizeTest.php ================================================ multipleOptionsDetected = false; } /** * Ensures that the validator follows expected behavior * * @return void */ public function testBasic() { $valuesExpected = [ [['min' => 0, 'max' => 2000], true, true, false], [['min' => 0, 'max' => '2 MB'], true, true, true], [['min' => 0, 'max' => '2MB'], true, true, true], [['min' => 0, 'max' => '2 MB'], true, true, true], [2000, true, true, false], [['min' => 0, 'max' => 500], false, false, false], [500, false, false, false] ]; foreach ($valuesExpected as $element) { $validator = new File\FilesSize($element[0]); $this->assertEquals( $element[1], $validator->isValid(__DIR__ . '/_files/testsize.mo'), "Tested with " . var_export($element, 1) ); $this->assertEquals( $element[2], $validator->isValid(__DIR__ . '/_files/testsize2.mo'), "Tested with " . var_export($element, 1) ); $this->assertEquals( $element[3], $validator->isValid(__DIR__ . '/_files/testsize3.mo'), "Tested with " . var_export($element, 1) ); } $validator = new File\FilesSize(['min' => 0, 'max' => 200]); $this->assertEquals(false, $validator->isValid(__DIR__ . '/_files/nofile.mo')); $this->assertArrayHasKey('fileFilesSizeNotReadable', $validator->getMessages()); $validator = new File\FilesSize(['min' => 0, 'max' => 500000]); $this->assertEquals(true, $validator->isValid([ __DIR__ . '/_files/testsize.mo', __DIR__ . '/_files/testsize.mo', __DIR__ . '/_files/testsize2.mo'])); $this->assertEquals(true, $validator->isValid(__DIR__ . '/_files/testsize.mo')); } /** * Ensures that getMin() returns expected value * * @return void */ public function testGetMin() { $validator = new File\FilesSize(['min' => 1, 'max' => 100]); $this->assertEquals('1B', $validator->getMin()); $validator = new File\FilesSize(['min' => 1, 'max' => 100]); $this->assertEquals('1B', $validator->getMin()); $this->expectException(InvalidArgumentException::class); $this->expectExceptionMessage('greater than or equal'); $validator = new File\FilesSize(['min' => 100, 'max' => 1]); } /** * Ensures that setMin() returns expected value * * @return void */ public function testSetMin() { $validator = new File\FilesSize(['min' => 1000, 'max' => 10000]); $validator->setMin(100); $this->assertEquals('100B', $validator->getMin()); $this->expectException(InvalidArgumentException::class); $this->expectExceptionMessage('less than or equal'); $validator->setMin(20000); } /** * Ensures that getMax() returns expected value * * @return void */ public function testGetMax() { $validator = new File\FilesSize(['min' => 1, 'max' => 100]); $this->assertEquals('100B', $validator->getMax()); $validator = new File\FilesSize(['min' => 1, 'max' => 100000]); $this->assertEquals('97.66kB', $validator->getMax()); $validator = new File\FilesSize(2000); $validator->useByteString(false); $test = $validator->getMax(); $this->assertEquals('2000', $test); $this->expectException(InvalidArgumentException::class); $this->expectExceptionMessage('greater than or equal'); $validator = new File\FilesSize(['min' => 100, 'max' => 1]); } /** * Ensures that setMax() returns expected value * * @return void */ public function testSetMax() { $validator = new File\FilesSize(['min' => 1000, 'max' => 10000]); $validator->setMax(1000000); $this->assertEquals('976.56kB', $validator->getMax()); $validator->setMin(100); $this->assertEquals('976.56kB', $validator->getMax()); } public function testConstructorShouldRaiseErrorWhenPassedMultipleOptions() { $handler = set_error_handler([$this, 'errorHandler'], E_USER_NOTICE); $validator = new File\FilesSize(1000, 10000); restore_error_handler(); } /** * Ensures that the validator returns size infos * * @return void */ public function testFailureMessage() { $validator = new File\FilesSize(['min' => 9999, 'max' => 10000]); $this->assertFalse($validator->isValid([ __DIR__ . '/_files/testsize.mo', __DIR__ . '/_files/testsize.mo', __DIR__ . '/_files/testsize2.mo', ])); $messages = $validator->getMessages(); $this->assertContains('9.76kB', current($messages)); $this->assertContains('1.55kB', current($messages)); $validator = new File\FilesSize(['min' => 9999, 'max' => 10000, 'useByteString' => false]); $this->assertFalse($validator->isValid([ __DIR__ . '/_files/testsize.mo', __DIR__ . '/_files/testsize.mo', __DIR__ . '/_files/testsize2.mo', ])); $messages = $validator->getMessages(); $this->assertContains('9999', current($messages)); $this->assertContains('1588', current($messages)); } public function errorHandler($errno, $errstr) { if (strstr($errstr, 'deprecated')) { $this->multipleOptionsDetected = true; } } public function testEmptyFileShouldReturnFalseAndDisplayNotFoundMessage() { $validator = new File\FilesSize(0); $this->assertFalse($validator->isValid('')); $this->assertArrayHasKey(File\FilesSize::NOT_READABLE, $validator->getMessages()); $filesArray = [ 'name' => '', 'size' => 0, 'tmp_name' => '', 'error' => UPLOAD_ERR_NO_FILE, 'type' => '', ]; $this->assertFalse($validator->isValid($filesArray)); $this->assertArrayHasKey(File\FilesSize::NOT_READABLE, $validator->getMessages()); } public function testFilesFormat() { $validator = new File\FilesSize(['min' => 0, 'max' => 2000]); $this->assertTrue( $validator->isValid($this->createFileInfo(__DIR__ . '/_files/testsize.mo')) ); $this->assertTrue( $validator->isValid($this->createFileInfo(__DIR__ . '/_files/testsize2.mo')) ); $this->assertFalse( $validator->isValid($this->createFileInfo(__DIR__ . '/_files/testsize3.mo')) ); $validator = new File\FilesSize(['min' => 0, 'max' => 500000]); $this->assertTrue($validator->isValid([ $this->createFileInfo(__DIR__ . '/_files/testsize.mo'), $this->createFileInfo(__DIR__ . '/_files/testsize.mo'), $this->createFileInfo(__DIR__ . '/_files/testsize2.mo'), ])); } public function testIllegalFilesFormat() { $validator = new File\FilesSize(['min' => 0, 'max' => 2000]); $this->expectException(InvalidArgumentException::class); $validator->isValid([ [ 'error' => 0 ], ]); } private function createFileInfo($file) { return [ 'tmp_name' => $file, 'name' => basename($file), 'error' => 0, 'type' => '', 'size' => filesize($file), ]; } public function testConstructorCanAcceptAllOptionsAsDiscreteArguments() { $min = 0; $max = 10; $useBytesAsString = false; $validator = new File\FilesSize($min, $max, $useBytesAsString); $this->assertEquals($min, $validator->getMin(true)); $this->assertEquals($max, $validator->getMax(true)); $this->assertSame($useBytesAsString, $validator->getByteString()); } public function testIsValidRaisesExceptionForArrayValueNotInFilesFormat() { $validator = new File\FilesSize(['min' => 0, 'max' => 2000]); $value = [['foo' => 'bar']]; $this->expectException(InvalidArgumentException::class); $this->expectExceptionMessage('Value array must be in $_FILES format'); $validator->isValid($value); } } ================================================ FILE: test/File/HashTest.php ================================================ 'md5'], $testFile, true, '' ], [ ['4d74c22109fe9f110579f77b053b8bc3', 'algorithm' => 'md5'], $testFile, false, 'fileHashDoesNotMatch' ], [ ['4d74c22109fe9f110579f77b053b8bc3', 'ed74c22109fe9f110579f77b053b8bc3', 'algorithm' => 'md5'], $testFile, true, '' ], [ ['4d74c22109fe9f110579f77b053b8bc3', '7d74c22109fe9f110579f77b053b8bc3', 'algorithm' => 'md5'], $testFile, false, 'fileHashDoesNotMatch' ], ]; $testFile = __DIR__ . '/_files/nofile.mo'; $noFileTests = [ // Options, isValid Param, Expected value, message ['3f8d07e2', $testFile, false, 'fileHashNotFound'], ]; $testFile = __DIR__ . '/_files/testsize.mo'; $sizeFileTests = [ // Options, isValid Param, Expected value, message ['ffeb8d5d', $testFile, true, ''], ['9f8d07e2', $testFile, false, 'fileHashDoesNotMatch'], ]; // Dupe data in File Upload format $testData = array_merge($pictureTests, $noFileTests, $sizeFileTests); foreach ($testData as $data) { $fileUpload = [ 'tmp_name' => $data[1], 'name' => basename($data[1]), 'size' => 200, 'error' => 0, 'type' => 'text' ]; $testData[] = [$data[0], $fileUpload, $data[2], $data[3]]; } return $testData; } /** * Ensures that the validator follows expected behavior * * @dataProvider basicBehaviorDataProvider * @return void */ public function testBasic($options, $isValidParam, $expected, $messageKey) { $validator = new File\Hash($options); $this->assertEquals($expected, $validator->isValid($isValidParam)); if (! $expected) { $this->assertArrayHasKey($messageKey, $validator->getMessages()); } } /** * Ensures that the validator follows expected behavior for legacy Zend\Transfer API * * @dataProvider basicBehaviorDataProvider * @return void */ public function testLegacy($options, $isValidParam, $expected, $messageKey) { if (is_array($isValidParam)) { $validator = new File\Hash($options); $this->assertEquals($expected, $validator->isValid($isValidParam['tmp_name'], $isValidParam)); if (! $expected) { $this->assertArrayHasKey($messageKey, $validator->getMessages()); } } } /** * Ensures that getHash() returns expected value * * @return void */ public function testgetHash() { $validator = new File\Hash('12345'); $this->assertEquals(['12345' => 'crc32'], $validator->getHash()); $validator = new File\Hash(['12345', '12333', '12344']); $this->assertEquals(['12345' => 'crc32', '12333' => 'crc32', '12344' => 'crc32'], $validator->getHash()); } /** * Ensures that setHash() returns expected value * * @return void */ public function testSetHash() { $validator = new File\Hash('12345'); $validator->setHash('12333'); $this->assertEquals(['12333' => 'crc32'], $validator->getHash()); $validator->setHash(['12321', '12121']); $this->assertEquals(['12321' => 'crc32', '12121' => 'crc32'], $validator->getHash()); } /** * Ensures that addHash() returns expected value * * @return void */ public function testAddHash() { $validator = new File\Hash('12345'); $validator->addHash('12344'); $this->assertEquals(['12345' => 'crc32', '12344' => 'crc32'], $validator->getHash()); $validator->addHash(['12321', '12121']); $this->assertEquals( ['12345' => 'crc32', '12344' => 'crc32', '12321' => 'crc32', '12121' => 'crc32'], $validator->getHash() ); } /** * @group ZF-11258 */ public function testZF11258() { $validator = new File\Hash('3f8d07e2'); $this->assertFalse($validator->isValid(__DIR__ . '/_files/nofile.mo')); $this->assertArrayHasKey('fileHashNotFound', $validator->getMessages()); $this->assertContains("does not exist", current($validator->getMessages())); } public function testEmptyFileShouldReturnFalseAndDisplayNotFoundMessage() { $validator = new File\Hash(); $this->assertFalse($validator->isValid('')); $this->assertArrayHasKey(File\Hash::NOT_FOUND, $validator->getMessages()); $filesArray = [ 'name' => '', 'size' => 0, 'tmp_name' => '', 'error' => UPLOAD_ERR_NO_FILE, 'type' => '', ]; $this->assertFalse($validator->isValid($filesArray)); $this->assertArrayHasKey(File\Hash::NOT_FOUND, $validator->getMessages()); } public function invalidHashTypes() { return [ 'null' => [null], 'true' => [true], 'false' => [false], 'zero' => [0], 'int' => [1], 'zero-float' => [0.0], 'float' => [1.1], 'object' => [(object) []], ]; } /** * @dataProvider invalidHashTypes */ public function testAddHashRaisesExceptionForInvalidType($value) { $validator = new File\Hash('12345'); $this->expectException(InvalidArgumentException::class); $this->expectExceptionMessage('False parameter given'); $validator->addHash($value); } public function testAddHashRaisesExceptionWithInvalidAlgorithm() { $validator = new File\Hash('12345'); $algorithm = 'foobar123'; $options = ['algorithm' => $algorithm]; $this->expectException(InvalidArgumentException::class); $this->expectExceptionMessage(sprintf("Unknown algorithm '%s'", $algorithm)); $validator->addHash($options); } public function testIsValidRaisesExceptionForArrayValueNotInFilesFormat() { $validator = new File\Hash('12345'); $value = ['foo' => 'bar']; $this->expectException(InvalidArgumentException::class); $this->expectExceptionMessage('Value array must be in $_FILES format'); $validator->isValid($value); } public function testConstructorCanAcceptAllOptionsAsDiscreteArguments() { $algorithm = 'md5'; $validator = new File\Hash('12345', $algorithm); $r = new ReflectionProperty($validator, 'options'); $r->setAccessible(true); $options = $r->getValue($validator); $this->assertSame($algorithm, $options['algorithm']); } /** * @dataProvider invalidHashTypes * * @param mixed $hash */ public function testInvalidHashProvidedInArrayFormat($hash) { $validator = new File\Hash('12345'); $this->expectException(InvalidArgumentException::class); $this->expectExceptionMessage('Hash must be a string'); $validator->addHash([$hash]); } public function testIntHash() { $validator = new File\Hash('10713230'); self::assertTrue($validator->isValid(__DIR__ . '/_files/crc32-int.pdf')); } public function testHashMustMatchWithTheAlgorithm() { $validator = new File\Hash(); // swapped hashes for given algorithms $validator->addHash(['6507f172bceb9ed0cc59246d41569c4d', 'algorithm' => 'crc32']); $validator->addHash(['10713230', 'algorithm' => 'md5']); self::assertFalse($validator->isValid(__DIR__ . '/_files/crc32-int.pdf')); } } ================================================ FILE: test/File/ImageSizeTest.php ================================================ 0, 'minHeight' => 10, 'maxWidth' => 1000, 'maxHeight' => 2000], $testFile, true, '' ], [ ['minWidth' => 0, 'minHeight' => 0, 'maxWidth' => 200, 'maxHeight' => 200], $testFile, true, '' ], [ ['minWidth' => 150, 'minHeight' => 150, 'maxWidth' => 200, 'maxHeight' => 200], $testFile, false, ['fileImageSizeWidthTooSmall', 'fileImageSizeHeightTooSmall'] ], [ ['minWidth' => 80, 'minHeight' => 0, 'maxWidth' => 80, 'maxHeight' => 200], $testFile, true, '' ], [ ['minWidth' => 0, 'minHeight' => 0, 'maxWidth' => 60, 'maxHeight' => 200], $testFile, false, 'fileImageSizeWidthTooBig' ], [ ['minWidth' => 90, 'minHeight' => 0, 'maxWidth' => 200, 'maxHeight' => 200], $testFile, false, 'fileImageSizeWidthTooSmall' ], [ ['minWidth' => 0, 'minHeight' => 0, 'maxWidth' => 200, 'maxHeight' => 80], $testFile, false, 'fileImageSizeHeightTooBig' ], [ ['minWidth' => 0, 'minHeight' => 110, 'maxWidth' => 200, 'maxHeight' => 140], $testFile, false, 'fileImageSizeHeightTooSmall' ], ]; $testFile = __DIR__ . '/_files/nofile.mo'; $noFileTests = [ // Options, isValid Param, Expected value, message [ ['minWidth' => 0, 'minHeight' => 10, 'maxWidth' => 1000, 'maxHeight' => 2000], $testFile, false, 'fileImageSizeNotReadable' ], ]; $testFile = __DIR__ . '/_files/badpicture.jpg'; $badPicTests = [ // Options, isValid Param, Expected value, message [ ['minWidth' => 0, 'minHeight' => 10, 'maxWidth' => 1000, 'maxHeight' => 2000], $testFile, false, 'fileImageSizeNotDetected' ], ]; // Dupe data in File Upload format $testData = array_merge($pictureTests, $noFileTests, $badPicTests); foreach ($testData as $data) { $fileUpload = [ 'tmp_name' => $data[1], 'name' => basename($data[1]), 'size' => 200, 'error' => 0, 'type' => 'text' ]; $testData[] = [$data[0], $fileUpload, $data[2], $data[3]]; } return $testData; } /** * Ensures that the validator follows expected behavior * * @dataProvider basicBehaviorDataProvider * @return void */ public function testBasic($options, $isValidParam, $expected, $messageKeys) { $validator = new File\ImageSize($options); $this->assertEquals($expected, $validator->isValid($isValidParam)); if (! $expected) { if (! is_array($messageKeys)) { $messageKeys = [$messageKeys]; } foreach ($messageKeys as $messageKey) { $this->assertArrayHasKey($messageKey, $validator->getMessages()); } } } /** * Ensures that the validator follows expected behavior for legacy Zend\Transfer API * * @dataProvider basicBehaviorDataProvider * @return void */ public function testLegacy($options, $isValidParam, $expected, $messageKeys) { // Test legacy Zend\Transfer API if (is_array($isValidParam)) { $validator = new File\ImageSize($options); $this->assertEquals($expected, $validator->isValid($isValidParam['tmp_name'], $isValidParam)); if (! $expected) { if (! is_array($messageKeys)) { $messageKeys = [$messageKeys]; } foreach ($messageKeys as $messageKey) { $this->assertArrayHasKey($messageKey, $validator->getMessages()); } } } } /** * Ensures that getImageMin() returns expected value * * @return void */ public function testGetImageMin() { $validator = new File\ImageSize(['minWidth' => 1, 'minHeight' => 10, 'maxWidth' => 100, 'maxHeight' => 1000]); $this->assertEquals(['minWidth' => 1, 'minHeight' => 10], $validator->getImageMin()); $this->expectException(InvalidArgumentException::class); $this->expectExceptionMessage('greater than or equal'); $validator = new File\ImageSize(['minWidth' => 1000, 'minHeight' => 100, 'maxWidth' => 10, 'maxHeight' => 1]); } /** * Ensures that setImageMin() returns expected value * * @return void */ public function testSetImageMin() { $validator = new File\ImageSize([ 'minWidth' => 100, 'minHeight' => 1000, 'maxWidth' => 10000, 'maxHeight' => 100000, ]); $validator->setImageMin(['minWidth' => 10, 'minHeight' => 10]); $this->assertEquals(['minWidth' => 10, 'minHeight' => 10], $validator->getImageMin()); $validator->setImageMin(['minWidth' => 9, 'minHeight' => 100]); $this->assertEquals(['minWidth' => 9, 'minHeight' => 100], $validator->getImageMin()); $this->expectException(InvalidArgumentException::class); $this->expectExceptionMessage('less than or equal'); $validator->setImageMin(['minWidth' => 20000, 'minHeight' => 20000]); } /** * Ensures that getImageMax() returns expected value * * @return void */ public function testGetImageMax() { $validator = new File\ImageSize([ 'minWidth' => 10, 'minHeight' => 100, 'maxWidth' => 1000, 'maxHeight' => 10000, ]); $this->assertEquals(['maxWidth' => 1000, 'maxHeight' => 10000], $validator->getImageMax()); $this->expectException(InvalidArgumentException::class); $this->expectExceptionMessage('greater than or equal'); $validator = new File\ImageSize([ 'minWidth' => 10000, 'minHeight' => 1000, 'maxWidth' => 100, 'maxHeight' => 10, ]); } /** * Ensures that setImageMax() returns expected value * * @return void */ public function testSetImageMax() { $validator = new File\ImageSize([ 'minWidth' => 10, 'minHeight' => 100, 'maxWidth' => 1000, 'maxHeight' => 10000, ]); $validator->setImageMax(['maxWidth' => 100, 'maxHeight' => 100]); $this->assertEquals(['maxWidth' => 100, 'maxHeight' => 100], $validator->getImageMax()); $validator->setImageMax(['maxWidth' => 110, 'maxHeight' => 1000]); $this->assertEquals(['maxWidth' => 110, 'maxHeight' => 1000], $validator->getImageMax()); $validator->setImageMax(['maxHeight' => 1100]); $this->assertEquals(['maxWidth' => 110, 'maxHeight' => 1100], $validator->getImageMax()); $validator->setImageMax(['maxWidth' => 120]); $this->assertEquals(['maxWidth' => 120, 'maxHeight' => 1100], $validator->getImageMax()); $this->expectException(InvalidArgumentException::class); $this->expectExceptionMessage('greater than or equal'); $validator->setImageMax(['maxWidth' => 10000, 'maxHeight' => 1]); } /** * Ensures that getImageWidth() returns expected value * * @return void */ public function testGetImageWidth() { $validator = new File\ImageSize(['minWidth' => 1, 'minHeight' => 10, 'maxWidth' => 100, 'maxHeight' => 1000]); $this->assertEquals(['minWidth' => 1, 'maxWidth' => 100], $validator->getImageWidth()); } /** * Ensures that setImageWidth() returns expected value * * @return void */ public function testSetImageWidth() { $validator = new File\ImageSize([ 'minWidth' => 100, 'minHeight' => 1000, 'maxWidth' => 10000, 'maxHeight' => 100000, ]); $validator->setImageWidth(['minWidth' => 2000, 'maxWidth' => 2200]); $this->assertEquals(['minWidth' => 2000, 'maxWidth' => 2200], $validator->getImageWidth()); $this->expectException(InvalidArgumentException::class); $this->expectExceptionMessage('less than or equal'); $validator->setImageWidth(['minWidth' => 20000, 'maxWidth' => 200]); } /** * Ensures that getImageHeight() returns expected value * * @return void */ public function testGetImageHeight() { $validator = new File\ImageSize(['minWidth' => 1, 'minHeight' => 10, 'maxWidth' => 100, 'maxHeight' => 1000]); $this->assertEquals(['minHeight' => 10, 'maxHeight' => 1000], $validator->getImageHeight()); } /** * Ensures that setImageHeight() returns expected value * * @return void */ public function testSetImageHeight() { $validator = new File\ImageSize([ 'minWidth' => 100, 'minHeight' => 1000, 'maxWidth' => 10000, 'maxHeight' => 100000, ]); $validator->setImageHeight(['minHeight' => 2000, 'maxHeight' => 2200]); $this->assertEquals(['minHeight' => 2000, 'maxHeight' => 2200], $validator->getImageHeight()); $this->expectException(InvalidArgumentException::class); $this->expectExceptionMessage('less than or equal'); $validator->setImageHeight(['minHeight' => 20000, 'maxHeight' => 200]); } /** * @group ZF-11258 */ public function testZF11258() { $validator = new File\ImageSize([ 'minWidth' => 100, 'minHeight' => 1000, 'maxWidth' => 10000, 'maxHeight' => 100000, ]); $this->assertFalse($validator->isValid(__DIR__ . '/_files/nofile.mo')); $this->assertArrayHasKey('fileImageSizeNotReadable', $validator->getMessages()); $this->assertContains("does not exist", current($validator->getMessages())); } public function testEmptyFileShouldReturnFalseAndDisplayNotFoundMessage() { $validator = new File\ImageSize(); $this->assertFalse($validator->isValid('')); $this->assertArrayHasKey(File\ImageSize::NOT_READABLE, $validator->getMessages()); $filesArray = [ 'name' => '', 'size' => 0, 'tmp_name' => '', 'error' => UPLOAD_ERR_NO_FILE, 'type' => '', ]; $this->assertFalse($validator->isValid($filesArray)); $this->assertArrayHasKey(File\ImageSize::NOT_READABLE, $validator->getMessages()); } public function testConstructorCanAcceptAllOptionsAsDiscreteArguments() { $minWidth = 20; $minHeight = 10; $maxWidth = 200; $maxHeight = 100; $validator = new File\ImageSize($minWidth, $minHeight, $maxWidth, $maxHeight); $this->assertSame($minWidth, $validator->getMinWidth()); $this->assertSame($minHeight, $validator->getMinHeight()); $this->assertSame($maxWidth, $validator->getMaxWidth()); $this->assertSame($maxHeight, $validator->getMaxHeight()); } public function testIsValidRaisesExceptionForArrayNotInFilesFormat() { $validator = new File\ImageSize([ 'minWidth' => 100, 'minHeight' => 1000, 'maxWidth' => 10000, 'maxHeight' => 100000, ]); $value = ['foo' => 'bar']; $this->expectException(InvalidArgumentException::class); $this->expectExceptionMessage('Value array must be in $_FILES format'); $validator->isValid($value); } } ================================================ FILE: test/File/IsCompressedTest.php ================================================ =')) { return __DIR__ . '/_files/magic.7.mime'; } // As of PHP >= 5.3.11 and >= 5.4.1 the magic database format has changed. // http://doc.php.net/downloads/pdf/split/de/File-Information.pdf (page 11) if (version_compare(PHP_VERSION, '5.4', '>=') && version_compare(PHP_VERSION, '5.4.1', '<') ) { return __DIR__ . '/_files/magic.lte.5.3.10.mime'; } return __DIR__ . '/_files/magic.mime'; } /** * @return array */ public function basicBehaviorDataProvider() { $testFile = __DIR__ . '/_files/test.zip'; // Sometimes finfo gives application/zip and sometimes // application/x-zip ... $expectedMimeType = finfo_file(finfo_open(FILEINFO_MIME_TYPE), $testFile); $allowed = ['application/zip', 'application/x-zip']; $fileUpload = [ 'tmp_name' => $testFile, 'name' => basename($testFile), 'size' => 200, 'error' => 0, 'type' => in_array($expectedMimeType, $allowed) ? $expectedMimeType : 'application/zip', ]; return [ // Options, isValid Param, Expected value [null, $fileUpload, true], ['zip', $fileUpload, true], ['test/notype', $fileUpload, false], ['application/x-zip, application/zip, application/x-tar', $fileUpload, true], [['application/x-zip', 'application/zip', 'application/x-tar'], $fileUpload, true], [['zip', 'tar'], $fileUpload, true], [['tar', 'arj'], $fileUpload, false], ]; } /** * Skip a test if the file info extension is missing */ protected function skipIfNoFileInfoExtension() { if (! extension_loaded('fileinfo')) { $this->markTestSkipped( 'This PHP Version has no finfo extension' ); } } /** * Skip a test if finfo returns buggy information */ protected function skipIfBuggyMimeContentType($options) { if (! is_array($options)) { $options = (array) $options; } if (! in_array('application/zip', $options)) { // finfo does not play a role; no need to skip return; } // Sometimes finfo gives application/zip and sometimes // application/x-zip ... $expectedMimeType = finfo_file(finfo_open(FILEINFO_MIME_TYPE), __DIR__ . '/_files/test.zip'); if (! in_array($expectedMimeType, ['application/zip', 'application/x-zip'])) { $this->markTestSkipped('finfo exhibits buggy behavior on this system!'); } } /** * Ensures that the validator follows expected behavior * * @dataProvider basicBehaviorDataProvider * @return void */ public function testBasic($options, $isValidParam, $expected) { $this->skipIfNoFileInfoExtension(); $this->skipIfBuggyMimeContentType($options); $validator = new File\IsCompressed($options); $validator->enableHeaderCheck(); $this->assertEquals($expected, $validator->isValid($isValidParam)); } /** * Ensures that the validator follows expected behavior for legacy Zend\Transfer API * * @dataProvider basicBehaviorDataProvider */ public function testLegacy($options, $isValidParam, $expected) { if (! is_array($isValidParam)) { // nothing to test return; } $this->skipIfNoFileInfoExtension(); $this->skipIfBuggyMimeContentType($options); $validator = new File\IsCompressed($options); $validator->enableHeaderCheck(); $this->assertEquals($expected, $validator->isValid($isValidParam['tmp_name'], $isValidParam)); } /** * Ensures that getMimeType() returns expected value * * @return void */ public function testGetMimeType() { $validator = new File\IsCompressed('image/gif'); $this->assertEquals('image/gif', $validator->getMimeType()); $validator = new File\IsCompressed(['image/gif', 'video', 'text/test']); $this->assertEquals('image/gif,video,text/test', $validator->getMimeType()); $validator = new File\IsCompressed(['image/gif', 'video', 'text/test']); $this->assertEquals(['image/gif', 'video', 'text/test'], $validator->getMimeType(true)); } /** * Ensures that setMimeType() returns expected value * * @return void */ public function testSetMimeType() { $validator = new File\IsCompressed('image/gif'); $validator->setMimeType('image/jpeg'); $this->assertEquals('image/jpeg', $validator->getMimeType()); $this->assertEquals(['image/jpeg'], $validator->getMimeType(true)); $validator->setMimeType('image/gif, text/test'); $this->assertEquals('image/gif,text/test', $validator->getMimeType()); $this->assertEquals(['image/gif', 'text/test'], $validator->getMimeType(true)); $validator->setMimeType(['video/mpeg', 'gif']); $this->assertEquals('video/mpeg,gif', $validator->getMimeType()); $this->assertEquals(['video/mpeg', 'gif'], $validator->getMimeType(true)); } /** * Ensures that addMimeType() returns expected value * * @return void */ public function testAddMimeType() { $validator = new File\IsCompressed('image/gif'); $validator->addMimeType('text'); $this->assertEquals('image/gif,text', $validator->getMimeType()); $this->assertEquals(['image/gif', 'text'], $validator->getMimeType(true)); $validator->addMimeType('jpg, to'); $this->assertEquals('image/gif,text,jpg,to', $validator->getMimeType()); $this->assertEquals(['image/gif', 'text', 'jpg', 'to'], $validator->getMimeType(true)); $validator->addMimeType(['zip', 'ti']); $this->assertEquals('image/gif,text,jpg,to,zip,ti', $validator->getMimeType()); $this->assertEquals(['image/gif', 'text', 'jpg', 'to', 'zip', 'ti'], $validator->getMimeType(true)); $validator->addMimeType(''); $this->assertEquals('image/gif,text,jpg,to,zip,ti', $validator->getMimeType()); $this->assertEquals(['image/gif', 'text', 'jpg', 'to', 'zip', 'ti'], $validator->getMimeType(true)); } /** * @ZF-8111 */ public function testErrorMessages() { $files = [ 'name' => 'picture.jpg', 'type' => 'image/jpeg', 'size' => 200, 'tmp_name' => __DIR__ . '/_files/picture.jpg', 'error' => 0 ]; $validator = new File\IsCompressed('test/notype'); $validator->enableHeaderCheck(); $this->assertFalse($validator->isValid(__DIR__ . '/_files/picture.jpg', $files)); $error = $validator->getMessages(); $this->assertArrayHasKey('fileIsCompressedFalseType', $error); } public function testOptionsAtConstructor() { if (! extension_loaded('fileinfo')) { $this->markTestSkipped('This PHP Version has no finfo installed'); } $magicFile = $this->getMagicMime(); $validator = new File\IsCompressed([ 'image/gif', 'image/jpg', 'magicFile' => $magicFile, 'enableHeaderCheck' => true]); $this->assertEquals($magicFile, $validator->getMagicFile()); $this->assertTrue($validator->getHeaderCheck()); $this->assertEquals('image/gif,image/jpg', $validator->getMimeType()); } public function testNonMimeOptionsAtConstructorStillSetsDefaults() { $validator = new File\IsCompressed([ 'enableHeaderCheck' => true, ]); $this->assertNotEmpty($validator->getMimeType()); } /** * @group ZF-11258 */ public function testZF11258() { $validator = new File\IsCompressed(); $this->assertFalse($validator->isValid(__DIR__ . '/_files/nofile.mo')); $this->assertArrayHasKey('fileIsCompressedNotReadable', $validator->getMessages()); $this->assertContains("does not exist", current($validator->getMessages())); } } ================================================ FILE: test/File/IsImageTest.php ================================================ =')) { return __DIR__ . '/_files/magic.7.mime'; } // As of PHP >= 5.3.11 and >= 5.4.1 the magic database format has changed. // http://doc.php.net/downloads/pdf/split/de/File-Information.pdf (page 11) if (version_compare(PHP_VERSION, '5.4', '>=') && version_compare(PHP_VERSION, '5.4.1', '<') ) { return __DIR__ . '/_files/magic.lte.5.3.10.mime'; } return __DIR__ . '/_files/magic.mime'; } /** * @return array */ public function basicBehaviorDataProvider() { $testFile = __DIR__ . '/_files/picture.jpg'; $fileUpload = [ 'tmp_name' => $testFile, 'name' => basename($testFile), 'size' => 200, 'error' => 0, 'type' => 'image/jpeg' ]; return [ // Options, isValid Param, Expected value [null, $fileUpload, true], ['jpeg', $fileUpload, true], ['test/notype', $fileUpload, false], ['image/gif, image/jpeg', $fileUpload, true], [['image/vasa', 'image/jpeg'], $fileUpload, true], [['image/jpeg', 'gif'], $fileUpload, true], [['image/gif', 'gif'], $fileUpload, false], ['image/jp', $fileUpload, false], ['image/jpg2000', $fileUpload, false], ['image/jpeg2000', $fileUpload, false], ]; } /** * Ensures that the validator follows expected behavior * * @dataProvider basicBehaviorDataProvider * @return void */ public function testBasic($options, $isValidParam, $expected) { $validator = new File\IsImage($options); $validator->enableHeaderCheck(); $this->assertEquals($expected, $validator->isValid($isValidParam)); } /** * Ensures that the validator follows expected behavior for legacy Zend\Transfer API * * @dataProvider basicBehaviorDataProvider * @return void */ public function testLegacy($options, $isValidParam, $expected) { if (is_array($isValidParam)) { $validator = new File\IsImage($options); $validator->enableHeaderCheck(); $this->assertEquals($expected, $validator->isValid($isValidParam['tmp_name'], $isValidParam)); } } /** * Ensures that getMimeType() returns expected value * * @return void */ public function testGetMimeType() { $validator = new File\IsImage('image/gif'); $this->assertEquals('image/gif', $validator->getMimeType()); $validator = new File\IsImage(['image/gif', 'video', 'text/test']); $this->assertEquals('image/gif,video,text/test', $validator->getMimeType()); $validator = new File\IsImage(['image/gif', 'video', 'text/test']); $this->assertEquals(['image/gif', 'video', 'text/test'], $validator->getMimeType(true)); } /** * Ensures that setMimeType() returns expected value * * @return void */ public function testSetMimeType() { $validator = new File\IsImage('image/gif'); $validator->setMimeType('image/jpeg'); $this->assertEquals('image/jpeg', $validator->getMimeType()); $this->assertEquals(['image/jpeg'], $validator->getMimeType(true)); $validator->setMimeType('image/gif, text/test'); $this->assertEquals('image/gif,text/test', $validator->getMimeType()); $this->assertEquals(['image/gif', 'text/test'], $validator->getMimeType(true)); $validator->setMimeType(['video/mpeg', 'gif']); $this->assertEquals('video/mpeg,gif', $validator->getMimeType()); $this->assertEquals(['video/mpeg', 'gif'], $validator->getMimeType(true)); } /** * Ensures that addMimeType() returns expected value * * @return void */ public function testAddMimeType() { $validator = new File\IsImage('image/gif'); $validator->addMimeType('text'); $this->assertEquals('image/gif,text', $validator->getMimeType()); $this->assertEquals(['image/gif', 'text'], $validator->getMimeType(true)); $validator->addMimeType('jpg, to'); $this->assertEquals('image/gif,text,jpg,to', $validator->getMimeType()); $this->assertEquals(['image/gif', 'text', 'jpg', 'to'], $validator->getMimeType(true)); $validator->addMimeType(['zip', 'ti']); $this->assertEquals('image/gif,text,jpg,to,zip,ti', $validator->getMimeType()); $this->assertEquals(['image/gif', 'text', 'jpg', 'to', 'zip', 'ti'], $validator->getMimeType(true)); $validator->addMimeType(''); $this->assertEquals('image/gif,text,jpg,to,zip,ti', $validator->getMimeType()); $this->assertEquals(['image/gif', 'text', 'jpg', 'to', 'zip', 'ti'], $validator->getMimeType(true)); } /** * @ZF-8111 */ public function testErrorMessages() { $files = [ 'name' => 'picture.jpg', 'type' => 'image/jpeg', 'size' => 200, 'tmp_name' => __DIR__ . '/_files/picture.jpg', 'error' => 0 ]; $validator = new File\IsImage('test/notype'); $validator->enableHeaderCheck(); $this->assertFalse($validator->isValid(__DIR__ . '/_files/picture.jpg', $files)); $error = $validator->getMessages(); $this->assertArrayHasKey('fileIsImageFalseType', $error); } public function testOptionsAtConstructor() { if (! extension_loaded('fileinfo')) { $this->markTestSkipped('This PHP Version has no finfo installed'); } $magicFile = $this->getMagicMime(); $validator = new File\IsImage([ 'image/gif', 'image/jpg', 'magicFile' => $magicFile, 'enableHeaderCheck' => true]); $this->assertEquals($magicFile, $validator->getMagicFile()); $this->assertTrue($validator->getHeaderCheck()); $this->assertEquals('image/gif,image/jpg', $validator->getMimeType()); } public function testNonMimeOptionsAtConstructorStillSetsDefaults() { $validator = new File\IsImage([ 'enableHeaderCheck' => true, ]); $this->assertNotEmpty($validator->getMimeType()); } /** * @group ZF-11258 */ public function testZF11258() { $validator = new File\IsImage(); $this->assertFalse($validator->isValid(__DIR__ . '/_files/nofile.mo')); $this->assertArrayHasKey('fileIsImageNotReadable', $validator->getMessages()); $this->assertContains("does not exist", current($validator->getMessages())); } } ================================================ FILE: test/File/Md5Test.php ================================================ $data[1], 'name' => basename($data[1]), 'size' => 200, 'error' => 0, 'type' => 'text' ]; $testData[] = [$data[0], $fileUpload, $data[2], $data[3]]; } return $testData; } /** * Ensures that the validator follows expected behavior * * @dataProvider basicBehaviorDataProvider * @return void */ public function testBasic($options, $isValidParam, $expected, $messageKey) { $validator = new File\Md5($options); $this->assertEquals($expected, $validator->isValid($isValidParam)); if (! $expected) { $this->assertArrayHasKey($messageKey, $validator->getMessages()); } } /** * Ensures that the validator follows expected behavior for legacy Zend\Transfer API * * @dataProvider basicBehaviorDataProvider * @return void */ public function testLegacy($options, $isValidParam, $expected, $messageKey) { if (is_array($isValidParam)) { $validator = new File\Md5($options); $this->assertEquals($expected, $validator->isValid($isValidParam['tmp_name'], $isValidParam)); if (! $expected) { $this->assertArrayHasKey($messageKey, $validator->getMessages()); } } } /** * Ensures that getMd5() returns expected value * * @return void */ public function testgetMd5() { $validator = new File\Md5('12345'); $this->assertEquals(['12345' => 'md5'], $validator->getMd5()); $validator = new File\Md5(['12345', '12333', '12344']); $this->assertEquals(['12345' => 'md5', '12333' => 'md5', '12344' => 'md5'], $validator->getMd5()); } /** * Ensures that getHash() returns expected value * * @return void */ public function testgetHash() { $validator = new File\Md5('12345'); $this->assertEquals(['12345' => 'md5'], $validator->getHash()); $validator = new File\Md5(['12345', '12333', '12344']); $this->assertEquals(['12345' => 'md5', '12333' => 'md5', '12344' => 'md5'], $validator->getHash()); } /** * Ensures that setMd5() returns expected value * * @return void */ public function testSetMd5() { $validator = new File\Md5('12345'); $validator->setMd5('12333'); $this->assertEquals(['12333' => 'md5'], $validator->getMd5()); $validator->setMd5(['12321', '12121']); $this->assertEquals(['12321' => 'md5', '12121' => 'md5'], $validator->getMd5()); } /** * Ensures that setHash() returns expected value * * @return void */ public function testSetHash() { $validator = new File\Md5('12345'); $validator->setHash('12333'); $this->assertEquals(['12333' => 'md5'], $validator->getMd5()); $validator->setHash(['12321', '12121']); $this->assertEquals(['12321' => 'md5', '12121' => 'md5'], $validator->getMd5()); } /** * Ensures that addMd5() returns expected value * * @return void */ public function testAddMd5() { $validator = new File\Md5('12345'); $validator->addMd5('12344'); $this->assertEquals(['12345' => 'md5', '12344' => 'md5'], $validator->getMd5()); $validator->addMd5(['12321', '12121']); $this->assertEquals( ['12345' => 'md5', '12344' => 'md5', '12321' => 'md5', '12121' => 'md5'], $validator->getMd5() ); } /** * Ensures that addHash() returns expected value * * @return void */ public function testAddHash() { $validator = new File\Md5('12345'); $validator->addHash('12344'); $this->assertEquals(['12345' => 'md5', '12344' => 'md5'], $validator->getMd5()); $validator->addHash(['12321', '12121']); $this->assertEquals( ['12345' => 'md5', '12344' => 'md5', '12321' => 'md5', '12121' => 'md5'], $validator->getMd5() ); } /** * @group ZF-11258 */ public function testZF11258() { $validator = new File\Md5('12345'); $this->assertFalse($validator->isValid(__DIR__ . '/_files/nofile.mo')); $this->assertArrayHasKey('fileMd5NotFound', $validator->getMessages()); $this->assertContains("does not exist", current($validator->getMessages())); } public function testEmptyFileShouldReturnFalseAndDisplayNotFoundMessage() { $validator = new File\Md5(); $this->assertFalse($validator->isValid('')); $this->assertArrayHasKey(File\Md5::NOT_FOUND, $validator->getMessages()); $filesArray = [ 'name' => '', 'size' => 0, 'tmp_name' => '', 'error' => UPLOAD_ERR_NO_FILE, 'type' => '', ]; $this->assertFalse($validator->isValid($filesArray)); $this->assertArrayHasKey(File\Md5::NOT_FOUND, $validator->getMessages()); } public function testIsValidShouldThrowInvalidArgumentExceptionForArrayNotInFilesFormat() { $validator = new File\Md5(); $value = ['foo' => 'bar']; $this->expectException(InvalidArgumentException::class); $validator->isValid($value); } } ================================================ FILE: test/File/MimeTypeTest.php ================================================ $testFile, 'name' => basename($testFile), 'size' => 200, 'error' => 0, 'type' => 'image/jpg' ]; return [ // Options, isValid Param, Expected value [['image/jpg', 'image/jpeg'], $fileUpload, true], ['image', $fileUpload, true], ['test/notype', $fileUpload, false], ['image/gif, image/jpg, image/jpeg', $fileUpload, true], [['image/vasa', 'image/jpg', 'image/jpeg'], $fileUpload, true], [['image/jpg', 'image/jpeg', 'gif'], $fileUpload, true], [['image/gif', 'gif'], $fileUpload, false], ['image/jp', $fileUpload, false], ['image/jpg2000', $fileUpload, false], ['image/jpeg2000', $fileUpload, false], ]; } /** * Ensures that the validator follows expected behavior * * @dataProvider basicBehaviorDataProvider * @return void */ public function testBasic($options, $isValidParam, $expected) { $validator = new File\MimeType($options); $validator->enableHeaderCheck(); $this->assertEquals($expected, $validator->isValid($isValidParam)); } /** * Ensures that the validator follows expected behavior for legacy Zend\Transfer API * * @dataProvider basicBehaviorDataProvider * @return void */ public function testLegacy($options, $isValidParam, $expected) { if (is_array($isValidParam)) { $validator = new File\MimeType($options); $validator->enableHeaderCheck(); $this->assertEquals($expected, $validator->isValid($isValidParam['tmp_name'], $isValidParam)); } } /** * Ensures that getMimeType() returns expected value * * @return void */ public function testGetMimeType() { $validator = new File\MimeType('image/gif'); $this->assertEquals('image/gif', $validator->getMimeType()); $validator = new File\MimeType(['image/gif', 'video', 'text/test']); $this->assertEquals('image/gif,video,text/test', $validator->getMimeType()); $validator = new File\MimeType(['image/gif', 'video', 'text/test']); $this->assertEquals(['image/gif', 'video', 'text/test'], $validator->getMimeType(true)); } /** * Ensures that setMimeType() returns expected value * * @return void */ public function testSetMimeType() { $validator = new File\MimeType('image/gif'); $validator->setMimeType('image/jpeg'); $this->assertEquals('image/jpeg', $validator->getMimeType()); $this->assertEquals(['image/jpeg'], $validator->getMimeType(true)); $validator->setMimeType('image/gif, text/test'); $this->assertEquals('image/gif,text/test', $validator->getMimeType()); $this->assertEquals(['image/gif', 'text/test'], $validator->getMimeType(true)); $validator->setMimeType(['video/mpeg', 'gif']); $this->assertEquals('video/mpeg,gif', $validator->getMimeType()); $this->assertEquals(['video/mpeg', 'gif'], $validator->getMimeType(true)); } /** * Ensures that addMimeType() returns expected value * * @return void */ public function testAddMimeType() { $validator = new File\MimeType('image/gif'); $validator->addMimeType('text'); $this->assertEquals('image/gif,text', $validator->getMimeType()); $this->assertEquals(['image/gif', 'text'], $validator->getMimeType(true)); $validator->addMimeType('jpg, to'); $this->assertEquals('image/gif,text,jpg,to', $validator->getMimeType()); $this->assertEquals(['image/gif', 'text', 'jpg', 'to'], $validator->getMimeType(true)); $validator->addMimeType(['zip', 'ti']); $this->assertEquals('image/gif,text,jpg,to,zip,ti', $validator->getMimeType()); $this->assertEquals(['image/gif', 'text', 'jpg', 'to', 'zip', 'ti'], $validator->getMimeType(true)); $validator->addMimeType(''); $this->assertEquals('image/gif,text,jpg,to,zip,ti', $validator->getMimeType()); $this->assertEquals(['image/gif', 'text', 'jpg', 'to', 'zip', 'ti'], $validator->getMimeType(true)); } public function testSetAndGetMagicFile() { if (! extension_loaded('fileinfo')) { $this->markTestSkipped('This PHP Version has no finfo installed'); } $validator = new File\MimeType('image/gif'); $magic = getenv('magic'); if (! empty($magic)) { $mimetype = $validator->getMagicFile(); $this->assertEquals($magic, $mimetype); } $this->expectException(InvalidArgumentException::class); $this->expectExceptionMessage('could not be'); $validator->setMagicFile('/unknown/magic/file'); } public function testSetMagicFileWithinConstructor() { if (! extension_loaded('fileinfo')) { $this->markTestSkipped('This PHP Version has no finfo installed'); } $this->expectException(InvalidMagicMimeFileException::class); $this->expectExceptionMessage('could not be used by ext/finfo'); $validator = new File\MimeType(['image/gif', 'magicFile' => __FILE__]); } public function testOptionsAtConstructor() { $validator = new File\MimeType([ 'image/gif', 'image/jpg', 'enableHeaderCheck' => true]); $this->assertTrue($validator->getHeaderCheck()); $this->assertEquals('image/gif,image/jpg', $validator->getMimeType()); } /** * @group ZF-11258 */ public function testZF11258() { $validator = new File\MimeType([ 'image/gif', 'image/jpg', 'headerCheck' => true]); $this->assertFalse($validator->isValid(__DIR__ . '/_files/nofile.mo')); $this->assertArrayHasKey('fileMimeTypeNotReadable', $validator->getMessages()); $this->assertContains("does not exist", current($validator->getMessages())); } public function testDisableMagicFile() { $validator = new File\MimeType('image/gif'); $magic = getenv('magic'); if (! empty($magic)) { $mimetype = $validator->getMagicFile(); $this->assertEquals($magic, $mimetype); } $validator->disableMagicFile(true); $this->assertTrue($validator->isMagicFileDisabled()); if (! empty($magic)) { $mimetype = $validator->getMagicFile(); $this->assertEquals($magic, $mimetype); } } /** * @group ZF-10461 */ public function testDisablingMagicFileByConstructor() { $files = [ 'name' => 'picture.jpg', 'size' => 200, 'tmp_name' => dirname(__FILE__) . '/_files/picture.jpg', 'error' => 0, 'magicFile' => false, ]; $validator = new File\MimeType($files); $this->assertFalse($validator->getMagicFile()); } public function testEmptyFileShouldReturnFalseAndDisplayNotFoundMessage() { if (! extension_loaded('fileinfo')) { $this->markTestSkipped('This PHP Version has no finfo installed'); } $validator = new File\MimeType(); $this->assertFalse($validator->isValid('')); $filesArray = [ 'name' => '', 'size' => 0, 'tmp_name' => '', 'error' => UPLOAD_ERR_NO_FILE, 'type' => '', ]; $this->assertFalse($validator->isValid($filesArray)); } public function testConstructorCanAcceptOptionsArray() { $mimeType = 'image/gif'; $options = ['mimeType' => $mimeType]; $validator = new File\MimeType($options); $this->assertSame($mimeType, $validator->getMimeType()); } public function testSettingMagicFileWithEmptyArrayNullifiesValue() { $validator = new File\MimeType(); $validator->setMagicFile([]); $r = new ReflectionProperty($validator, 'options'); $r->setAccessible(true); $options = $r->getValue($validator); $this->assertNull($options['magicFile']); } public function invalidMimeTypeTypes() { return [ 'null' => [null], 'true' => [true], 'false' => [false], 'zero' => [0], 'int' => [1], 'zero-float' => [0.0], 'float' => [1.1], 'object' => [(object) []], ]; } /** * @dataProvider invalidMimeTypeTypes */ public function testAddingMimeTypeWithInvalidTypeRaisesException($type) { $validator = new File\MimeType(); $this->expectException(InvalidArgumentException::class); $this->expectExceptionMessage('Invalid options to validator provided'); $validator->addMimeType($type); } public function testAddingMimeTypeUsingMagicFileArrayKeyIgnoresKey() { $validator = new File\MimeType('image/gif'); $mimeTypeArray = [ 'magicFile' => 'test.txt', 'gif' => 'text', ]; $validator->addMimeType($mimeTypeArray); $this->assertSame('image/gif,text', $validator->getMimeType()); $this->assertSame(['image/gif', 'text'], $validator->getMimeType(true)); } public function testIsValidRaisesExceptionWithArrayNotInFilesFormat() { $validator = new File\MimeType('image\gif'); $value = ['foo' => 'bar']; $this->expectException(InvalidArgumentException::class); $this->expectExceptionMessage('Value array must be in $_FILES format'); $validator->isValid($value); } } ================================================ FILE: test/File/NotExistsTest.php ================================================ $testFile, 'name' => basename($testFile), 'size' => 200, 'error' => 0, 'type' => 'text' ]; return [ // Options, isValid Param, Expected value [dirname($baseDir), $baseName, true], [$baseDir, $baseName, false], [$baseDir, $testFile, false], [dirname($baseDir), $fileUpload, true], [$baseDir, $fileUpload, false], ]; } /** * Ensures that the validator follows expected behavior * * @dataProvider basicBehaviorDataProvider * @return void */ public function testBasic($options, $isValidParam, $expected) { $validator = new File\NotExists($options); $this->assertEquals($expected, $validator->isValid($isValidParam)); } /** * Ensures that the validator follows expected behavior for legacy Zend\Transfer API * * @dataProvider basicBehaviorDataProvider * @return void */ public function testLegacy($options, $isValidParam, $expected) { if (is_array($isValidParam)) { $validator = new File\NotExists($options); $this->assertEquals($expected, $validator->isValid($isValidParam['tmp_name'], $isValidParam)); } } /** * Ensures that getDirectory() returns expected value * * @return void */ public function testGetDirectory() { $validator = new File\NotExists('C:/temp'); $this->assertEquals('C:/temp', $validator->getDirectory()); $validator = new File\NotExists(['temp', 'dir', 'jpg']); $this->assertEquals('temp,dir,jpg', $validator->getDirectory()); $validator = new File\NotExists(['temp', 'dir', 'jpg']); $this->assertEquals(['temp', 'dir', 'jpg'], $validator->getDirectory(true)); } /** * Ensures that setDirectory() returns expected value * * @return void */ public function testSetDirectory() { $validator = new File\NotExists('temp'); $validator->setDirectory('gif'); $this->assertEquals('gif', $validator->getDirectory()); $this->assertEquals(['gif'], $validator->getDirectory(true)); $validator->setDirectory('jpg, temp'); $this->assertEquals('jpg,temp', $validator->getDirectory()); $this->assertEquals(['jpg', 'temp'], $validator->getDirectory(true)); $validator->setDirectory(['zip', 'ti']); $this->assertEquals('zip,ti', $validator->getDirectory()); $this->assertEquals(['zip', 'ti'], $validator->getDirectory(true)); } /** * Ensures that addDirectory() returns expected value * * @return void */ public function testAddDirectory() { $validator = new File\NotExists('temp'); $validator->addDirectory('gif'); $this->assertEquals('temp,gif', $validator->getDirectory()); $this->assertEquals(['temp', 'gif'], $validator->getDirectory(true)); $validator->addDirectory('jpg, to'); $this->assertEquals('temp,gif,jpg,to', $validator->getDirectory()); $this->assertEquals(['temp', 'gif', 'jpg', 'to'], $validator->getDirectory(true)); $validator->addDirectory(['zip', 'ti']); $this->assertEquals('temp,gif,jpg,to,zip,ti', $validator->getDirectory()); $this->assertEquals(['temp', 'gif', 'jpg', 'to', 'zip', 'ti'], $validator->getDirectory(true)); $validator->addDirectory(''); $this->assertEquals('temp,gif,jpg,to,zip,ti', $validator->getDirectory()); $this->assertEquals(['temp', 'gif', 'jpg', 'to', 'zip', 'ti'], $validator->getDirectory(true)); } /** * @group ZF-11258 */ public function testZF11258() { $validator = new File\NotExists(); $this->assertFalse($validator->isValid(__DIR__ . '/_files/testsize.mo')); $this->assertArrayHasKey('fileNotExistsDoesExist', $validator->getMessages()); $this->assertContains("File exists", current($validator->getMessages())); } public function testIsValidShouldThrowInvalidArgumentExceptionForArrayNotInFilesFormat() { $validator = new File\NotExists(); $value = ['foo' => 'bar']; $this->expectException(InvalidArgumentException::class); $this->expectExceptionMessage('Value array must be in $_FILES format'); $validator->isValid($value); } public function invalidDirectoryArguments() { return [ 'null' => [null], 'true' => [true], 'false' => [false], 'zero' => [0], 'int' => [1], 'zero-float' => [0.0], 'float' => [1.1], 'object' => [(object) []], ]; } /** * @dataProvider invalidDirectoryArguments */ public function testAddingDirectoryUsingInvalidTypeRaisesException($value) { $validator = new File\NotExists(); $this->expectException(InvalidArgumentException::class); $validator->addDirectory($value); } } ================================================ FILE: test/File/Sha1Test.php ================================================ $data[1], 'name' => basename($data[1]), 'size' => 200, 'error' => 0, 'type' => 'text' ]; $testData[] = [$data[0], $fileUpload, $data[2], $data[3]]; } return $testData; } /** * Ensures that the validator follows expected behavior * * @dataProvider basicBehaviorDataProvider * @return void */ public function testBasic($options, $isValidParam, $expected, $messageKey) { $validator = new File\Sha1($options); $this->assertEquals($expected, $validator->isValid($isValidParam)); if (! $expected) { $this->assertArrayHasKey($messageKey, $validator->getMessages()); } } /** * Ensures that the validator follows expected behavior for legacy Zend\Transfer API * * @dataProvider basicBehaviorDataProvider * @return void */ public function testLegacy($options, $isValidParam, $expected, $messageKey) { if (is_array($isValidParam)) { $validator = new File\Sha1($options); $this->assertEquals($expected, $validator->isValid($isValidParam['tmp_name'], $isValidParam)); if (! $expected) { $this->assertArrayHasKey($messageKey, $validator->getMessages()); } } } /** * Ensures that getSha1() returns expected value * * @return void */ public function testgetSha1() { $validator = new File\Sha1('12345'); $this->assertEquals(['12345' => 'sha1'], $validator->getSha1()); $validator = new File\Sha1(['12345', '12333', '12344']); $this->assertEquals(['12345' => 'sha1', '12333' => 'sha1', '12344' => 'sha1'], $validator->getSha1()); } /** * Ensures that getHash() returns expected value * * @return void */ public function testgetHash() { $validator = new File\Sha1('12345'); $this->assertEquals(['12345' => 'sha1'], $validator->getHash()); $validator = new File\Sha1(['12345', '12333', '12344']); $this->assertEquals(['12345' => 'sha1', '12333' => 'sha1', '12344' => 'sha1'], $validator->getHash()); } /** * Ensures that setSha1() returns expected value * * @return void */ public function testSetSha1() { $validator = new File\Sha1('12345'); $validator->setSha1('12333'); $this->assertEquals(['12333' => 'sha1'], $validator->getSha1()); $validator->setSha1(['12321', '12121']); $this->assertEquals(['12321' => 'sha1', '12121' => 'sha1'], $validator->getSha1()); } /** * Ensures that setHash() returns expected value * * @return void */ public function testSetHash() { $validator = new File\Sha1('12345'); $validator->setHash('12333'); $this->assertEquals(['12333' => 'sha1'], $validator->getSha1()); $validator->setHash(['12321', '12121']); $this->assertEquals(['12321' => 'sha1', '12121' => 'sha1'], $validator->getSha1()); } /** * Ensures that addSha1() returns expected value * * @return void */ public function testAddSha1() { $validator = new File\Sha1('12345'); $validator->addSha1('12344'); $this->assertEquals(['12345' => 'sha1', '12344' => 'sha1'], $validator->getSha1()); $validator->addSha1(['12321', '12121']); $this->assertEquals( ['12345' => 'sha1', '12344' => 'sha1', '12321' => 'sha1', '12121' => 'sha1'], $validator->getSha1() ); } /** * Ensures that addHash() returns expected value * * @return void */ public function testAddHash() { $validator = new File\Sha1('12345'); $validator->addHash('12344'); $this->assertEquals(['12345' => 'sha1', '12344' => 'sha1'], $validator->getSha1()); $validator->addHash(['12321', '12121']); $this->assertEquals( ['12345' => 'sha1', '12344' => 'sha1', '12321' => 'sha1', '12121' => 'sha1'], $validator->getSha1() ); } /** * @group ZF-11258 */ public function testZF11258() { $validator = new File\Sha1('12345'); $this->assertFalse($validator->isValid(__DIR__ . '/_files/nofile.mo')); $this->assertArrayHasKey('fileSha1NotFound', $validator->getMessages()); $this->assertContains("does not exist", current($validator->getMessages())); } public function testEmptyFileShouldReturnFalseAndDisplayNotFoundMessage() { $validator = new File\Sha1(); $this->assertFalse($validator->isValid('')); $this->assertArrayHasKey(File\Sha1::NOT_FOUND, $validator->getMessages()); $filesArray = [ 'name' => '', 'size' => 0, 'tmp_name' => '', 'error' => UPLOAD_ERR_NO_FILE, 'type' => '', ]; $this->assertFalse($validator->isValid($filesArray)); $this->assertArrayHasKey(File\Sha1::NOT_FOUND, $validator->getMessages()); } public function testIsValidShouldThrowInvalidArgumentExceptionForArrayNotInFilesFormat() { $validator = new File\Sha1(); $value = ['foo' => 'bar']; $this->expectException(InvalidArgumentException::class); $this->expectExceptionMessage('Value array must be in $_FILES format'); $validator->isValid($value); } } ================================================ FILE: test/File/SizeTest.php ================================================ 0, 'max' => 10000], $testFile, true], [['min' => 0, 'max' => '10 MB'], $testFile, true], [['min' => '4B', 'max' => '10 MB'], $testFile, true], [['min' => 0, 'max' => '10MB'], $testFile, true], [['min' => 0, 'max' => '10 MB'], $testFile, true], [['min' => 794], $testFile, true], [['min' => 0, 'max' => 500], $testFile, false], ]; // Dupe data in File Upload format foreach ($testData as $data) { $fileUpload = [ 'tmp_name' => $data[1], 'name' => basename($data[1]), 'size' => 200, 'error' => 0, 'type' => 'text' ]; $testData[] = [$data[0], $fileUpload, $data[2]]; } return $testData; } /** * Ensures that the validator follows expected behavior * * @dataProvider basicBehaviorDataProvider * @return void */ public function testBasic($options, $isValidParam, $expected) { $validator = new File\Size($options); $this->assertEquals($expected, $validator->isValid($isValidParam)); } /** * Ensures that the validator follows expected behavior for legacy Zend\Transfer API * * @dataProvider basicBehaviorDataProvider * @return void */ public function testLegacy($options, $isValidParam, $expected) { if (is_array($isValidParam)) { $validator = new File\Size($options); $this->assertEquals($expected, $validator->isValid($isValidParam['tmp_name'], $isValidParam)); } } /** * Ensures that getMin() returns expected value * * @return void */ public function testGetMin() { $validator = new File\Size(['min' => 1, 'max' => 100]); $this->assertEquals('1B', $validator->getMin()); $validator = new File\Size(['min' => 1, 'max' => 100, 'useByteString' => false]); $this->assertEquals(1, $validator->getMin()); $this->expectException(InvalidArgumentException::class); $this->expectExceptionMessage('greater than or equal'); $validator = new File\Size(['min' => 100, 'max' => 1]); } /** * Ensures that setMin() returns expected value * * @return void */ public function testSetMin() { $validator = new File\Size(['min' => 1000, 'max' => 10000]); $validator->setMin(100); $this->assertEquals('100B', $validator->getMin()); $validator = new File\Size(['min' => 1000, 'max' => 10000, 'useByteString' => false]); $validator->setMin(100); $this->assertEquals(100, $validator->getMin()); $this->expectException(InvalidArgumentException::class); $this->expectExceptionMessage('less than or equal'); $validator->setMin(20000); } /** * Ensures that getMax() returns expected value * * @return void */ public function testGetMax() { $validator = new File\Size(['min' => 1, 'max' => 100, 'useByteString' => false]); $this->assertEquals(100, $validator->getMax()); $validator = new File\Size(['min' => 1, 'max' => 100000]); $this->assertEquals('97.66kB', $validator->getMax()); $validator = new File\Size(2000); $this->assertEquals('1.95kB', $validator->getMax()); $this->expectException(InvalidArgumentException::class); $this->expectExceptionMessage('greater than or equal'); $validator = new File\Size(['min' => 100, 'max' => 1]); } /** * Ensures that setMax() returns expected value * * @return void */ public function testSetMax() { $validator = new File\Size(['max' => 0, 'useByteString' => true]); $this->assertEquals('0B', $validator->getMax()); $validator->setMax(1000000); $this->assertEquals('976.56kB', $validator->getMax()); $validator->setMin(100); $this->assertEquals('976.56kB', $validator->getMax()); $validator->setMax('100 AB'); $this->assertEquals('100B', $validator->getMax()); $validator->setMax('100 kB'); $this->assertEquals('100kB', $validator->getMax()); $validator->setMax('100 MB'); $this->assertEquals('100MB', $validator->getMax()); $validator->setMax('1 GB'); $this->assertEquals('1GB', $validator->getMax()); $validator->setMax('0.001 TB'); $this->assertEquals('1.02GB', $validator->getMax()); $validator->setMax('0.000001 PB'); $this->assertEquals('1.05GB', $validator->getMax()); $validator->setMax('0.000000001 EB'); $this->assertEquals('1.07GB', $validator->getMax()); $validator->setMax('0.000000000001 ZB'); $this->assertEquals('1.1GB', $validator->getMax()); $validator->setMax('0.000000000000001 YB'); $this->assertEquals('1.13GB', $validator->getMax()); } /** * Ensures that the validator returns size infos * * @return void */ public function testFailureMessage() { $validator = new File\Size(['min' => 9999, 'max' => 10000]); $this->assertFalse($validator->isValid(__DIR__ . '/_files/testsize.mo')); $messages = $validator->getMessages(); $this->assertContains('9.76kB', current($messages)); $this->assertContains('794B', current($messages)); $validator = new File\Size(['min' => 9999, 'max' => 10000, 'useByteString' => false]); $this->assertFalse($validator->isValid(__DIR__ . '/_files/testsize.mo')); $messages = $validator->getMessages(); $this->assertContains('9999', current($messages)); $this->assertContains('794', current($messages)); } /** * @group ZF-11258 */ public function testZF11258() { $validator = new File\Size(['min' => 1, 'max' => 10000]); $this->assertFalse($validator->isValid(__DIR__ . '/_files/nofile.mo')); $this->assertArrayHasKey('fileSizeNotFound', $validator->getMessages()); $this->assertContains("does not exist", current($validator->getMessages())); } public function testEmptyFileShouldReturnFalseAndDisplayNotFoundMessage() { $validator = new File\Size(); $this->assertFalse($validator->isValid('')); $this->assertArrayHasKey(File\Size::NOT_FOUND, $validator->getMessages()); $filesArray = [ 'name' => '', 'size' => 0, 'tmp_name' => '', 'error' => UPLOAD_ERR_NO_FILE, 'type' => '', ]; $this->assertFalse($validator->isValid($filesArray)); $this->assertArrayHasKey(File\Size::NOT_FOUND, $validator->getMessages()); } public function invalidMinMaxValues() { return [ 'null' => [null], 'true' => [true], 'false' => [false], 'array' => [[100]], 'object' => [(object) []], ]; } /** * @dataProvider invalidMinMaxValues */ public function testSetMinWithInvalidArgument($value) { $validator = new File\FilesSize(['min' => 0, 'max' => 2000]); $this->expectException(InvalidArgumentException::class); $this->expectExceptionMessage('Invalid options to validator provided'); $validator->setMin($value); } /** * @dataProvider invalidMinMaxValues */ public function testSetMaxWithInvalidArgument($value) { $validator = new File\FilesSize(['min' => 0, 'max' => 2000]); $this->expectException(InvalidArgumentException::class); $this->expectExceptionMessage('Invalid options to validator provided'); $validator->setMax($value); } } ================================================ FILE: test/File/TestAsset/FileInformation.php ================================================ getFileInfo($value, $file, $hasType, $hasBasename); } } ================================================ FILE: test/File/UploadFileTest.php ================================================ 'fileUploadFileErrorAttack', 1 => 'fileUploadFileErrorIniSize', 2 => 'fileUploadFileErrorFormSize', 3 => 'fileUploadFileErrorPartial', 4 => 'fileUploadFileErrorNoFile', 5 => 'fileUploadFileErrorUnknown', 6 => 'fileUploadFileErrorNoTmpDir', 7 => 'fileUploadFileErrorCantWrite', 8 => 'fileUploadFileErrorExtension', 9 => 'fileUploadFileErrorUnknown', ]; $testSizeFile = __DIR__ . '/_files/testsize.mo'; foreach ($errorTypes as $errorCode => $errorType) { $name = sprintf('SAPI - %s', $errorType); $data[$name] = [ // fileInfo [ 'name' => 'test' . $errorCode, 'type' => 'text', 'size' => 200 + $errorCode, 'tmp_name' => $testSizeFile, 'error' => $errorCode, ], // messageKey $errorType, ]; } // Diactoros does not have UNKNOWN error type. unset($errorTypes[9]); foreach ($errorTypes as $errorCode => $errorType) { if ($errorCode === UPLOAD_ERR_OK) { // Unable to get to this vector continue; } $name = sprintf('PSR-7 - %s', $errorType); $upload = $this->prophesize(UploadedFileInterface::class); $upload->getClientFilename()->willReturn('test' . $errorCode); $upload->getError()->willReturn($errorCode); $data[$name] = [$upload->reveal(), $errorType]; } return $data; } /** * Ensures that the validator follows expected behavior * * @dataProvider uploadErrorsTestDataProvider * @return void */ public function testBasic($fileInfo, $messageKey) { $validator = new File\UploadFile(); $this->assertFalse($validator->isValid($fileInfo)); $this->assertArrayHasKey($messageKey, $validator->getMessages()); } /** * @return void */ public function testRaisesExceptionWhenValueArrayIsBad() { $validator = new File\UploadFile(); $this->expectException(InvalidArgumentException::class); $this->expectExceptionMessage('$_FILES format'); $validator->isValid(['foo', 'bar']); } /** * @group ZF-11258 */ public function testZF11258() { $validator = new File\UploadFile(); $this->assertFalse($validator->isValid(__DIR__ . '/_files/nofile.mo')); $this->assertArrayHasKey('fileUploadFileErrorFileNotFound', $validator->getMessages()); $this->assertContains("not found", current($validator->getMessages())); } public function testEmptyFileShouldReturnFalseAndDisplayNotFoundMessage() { $validator = new File\UploadFile(); $this->assertFalse($validator->isValid('')); $this->assertArrayHasKey(File\UploadFile::FILE_NOT_FOUND, $validator->getMessages()); } public function testUploadErrorCodeShouldPrecedeEmptyFileCheck() { $validator = new File\UploadFile(); $filesArray = [ 'name' => '', 'size' => 0, 'tmp_name' => '', 'error' => UPLOAD_ERR_NO_FILE, 'type' => '', ]; $this->assertFalse($validator->isValid($filesArray)); $this->assertArrayHasKey(File\UploadFile::NO_FILE, $validator->getMessages()); $this->assertArrayNotHasKey(File\UploadFile::FILE_NOT_FOUND, $validator->getMessages()); } } ================================================ FILE: test/File/UploadTest.php ================================================ [ 'name' => 'test1', 'type' => 'text', 'size' => 200, 'tmp_name' => 'tmp_test1', 'error' => 0], 'test2' => [ 'name' => 'test2', 'type' => 'text2', 'size' => 202, 'tmp_name' => 'tmp_test2', 'error' => 1], 'test3' => [ 'name' => 'test3', 'type' => 'text3', 'size' => 203, 'tmp_name' => 'tmp_test3', 'error' => 2], 'test4' => [ 'name' => 'test4', 'type' => 'text4', 'size' => 204, 'tmp_name' => 'tmp_test4', 'error' => 3], 'test5' => [ 'name' => 'test5', 'type' => 'text5', 'size' => 205, 'tmp_name' => 'tmp_test5', 'error' => 4], 'test6' => [ 'name' => 'test6', 'type' => 'text6', 'size' => 206, 'tmp_name' => 'tmp_test6', 'error' => 5], 'test7' => [ 'name' => 'test7', 'type' => 'text7', 'size' => 207, 'tmp_name' => 'tmp_test7', 'error' => 6], 'test8' => [ 'name' => 'test8', 'type' => 'text8', 'size' => 208, 'tmp_name' => 'tmp_test8', 'error' => 7], 'test9' => [ 'name' => 'test9', 'type' => 'text9', 'size' => 209, 'tmp_name' => 'tmp_test9', 'error' => 8] ]; $validator = new File\Upload(); $this->assertFalse($validator->isValid('test')); $this->assertArrayHasKey('fileUploadErrorAttack', $validator->getMessages()); $validator = new File\Upload(); $this->assertFalse($validator->isValid('test2')); $this->assertArrayHasKey('fileUploadErrorIniSize', $validator->getMessages()); $validator = new File\Upload(); $this->assertFalse($validator->isValid('test3')); $this->assertArrayHasKey('fileUploadErrorFormSize', $validator->getMessages()); $validator = new File\Upload(); $this->assertFalse($validator->isValid('test4')); $this->assertArrayHasKey('fileUploadErrorPartial', $validator->getMessages()); $validator = new File\Upload(); $this->assertFalse($validator->isValid('test5')); $this->assertArrayHasKey('fileUploadErrorNoFile', $validator->getMessages()); $validator = new File\Upload(); $this->assertFalse($validator->isValid('test6')); $this->assertArrayHasKey('fileUploadErrorUnknown', $validator->getMessages()); $validator = new File\Upload(); $this->assertFalse($validator->isValid('test7')); $this->assertArrayHasKey('fileUploadErrorNoTmpDir', $validator->getMessages()); $validator = new File\Upload(); $this->assertFalse($validator->isValid('test8')); $this->assertArrayHasKey('fileUploadErrorCantWrite', $validator->getMessages()); $validator = new File\Upload(); $this->assertFalse($validator->isValid('test9')); $this->assertArrayHasKey('fileUploadErrorExtension', $validator->getMessages()); $validator = new File\Upload(); $this->assertFalse($validator->isValid('test1')); $this->assertArrayHasKey('fileUploadErrorAttack', $validator->getMessages()); $validator = new File\Upload(); $this->assertFalse($validator->isValid('tmp_test1')); $this->assertArrayHasKey('fileUploadErrorAttack', $validator->getMessages()); $validator = new File\Upload(); $this->assertFalse($validator->isValid('test000')); $this->assertArrayHasKey('fileUploadErrorFileNotFound', $validator->getMessages()); } public function invalidPsr7UploadedFiles() { $uploads = []; $upload = $this->prophesize(UploadedFileInterface::class); $upload->getClientFilename()->willReturn('test2'); $upload->getError()->willReturn(1); yield 'size' => [['test2' => $upload->reveal()], 'test2', 'fileUploadErrorIniSize']; $uploads['test2'] = $upload->reveal(); $upload = $this->prophesize(UploadedFileInterface::class); $upload->getClientFilename()->willReturn('test3'); $upload->getError()->willReturn(2); yield 'form-size' => [['test3' => $upload->reveal()], 'test3', 'fileUploadErrorFormSize']; $uploads['test3'] = $upload->reveal(); $upload = $this->prophesize(UploadedFileInterface::class); $upload->getClientFilename()->willReturn('test4'); $upload->getError()->willReturn(3); yield 'partial' => [['test4' => $upload->reveal()], 'test4', 'fileUploadErrorPartial']; $uploads['test4'] = $upload->reveal(); $upload = $this->prophesize(UploadedFileInterface::class); $upload->getClientFilename()->willReturn('test5'); $upload->getError()->willReturn(4); yield 'no-file' => [['test5' => $upload->reveal()], 'test5', 'fileUploadErrorNoFile']; $uploads['test5'] = $upload->reveal(); $upload = $this->prophesize(UploadedFileInterface::class); $upload->getClientFilename()->willReturn('test6'); $upload->getError()->willReturn(5); yield 'unknown' => [['test6' => $upload->reveal()], 'test6', 'fileUploadErrorUnknown']; $uploads['test6'] = $upload->reveal(); $upload = $this->prophesize(UploadedFileInterface::class); $upload->getClientFilename()->willReturn('test7'); $upload->getError()->willReturn(6); yield 'no-tmp-dir' => [['test7' => $upload->reveal()], 'test7', 'fileUploadErrorNoTmpDir']; $uploads['test7'] = $upload->reveal(); $upload = $this->prophesize(UploadedFileInterface::class); $upload->getClientFilename()->willReturn('test8'); $upload->getError()->willReturn(7); yield 'cannot write' => [['test8' => $upload->reveal()], 'test8', 'fileUploadErrorCantWrite']; $uploads['test8'] = $upload->reveal(); $upload = $this->prophesize(UploadedFileInterface::class); $upload->getClientFilename()->willReturn('test9'); $upload->getError()->willReturn(8); yield 'cannot write' => [['test9' => $upload->reveal()], 'test9', 'fileUploadErrorExtension']; $uploads['test9'] = $upload->reveal(); yield 'not-found' => [$uploads, 'test000', 'fileUploadErrorFileNotFound']; } /** * Validate invalid PSR-7 file uploads * * Not testing lookup by temp file name since PSR does not expose it. * * @dataProvider invalidPsr7UploadedFiles * @param UploadedFileInterface[] $files * @param string $fileName * @param string $expectedErrorKey * @return void */ public function testRaisesExpectedErrorsForInvalidPsr7UploadedFileInput($files, $fileName, $expectedErrorKey) { $validator = new File\Upload(); $validator->setFiles($files); $this->assertFalse($validator->isValid($fileName)); $this->assertArrayHasKey($expectedErrorKey, $validator->getMessages()); } public function testCanValidateCorrectlyFormedPsr7UploadedFiles() { $upload = $this->prophesize(UploadedFileInterface::class); $upload->getClientFilename()->willReturn('test'); $upload->getError()->willReturn(0); $validator = new File\Upload(); $validator->setFiles(['upload' => $upload->reveal()]); $this->assertTrue($validator->isValid('test')); } /** * Ensures that getFiles() returns expected value * * @return void */ public function testGetFiles() { $_FILES = [ 'test' => [ 'name' => 'test1', 'type' => 'text', 'size' => 200, 'tmp_name' => 'tmp_test1', 'error' => 0], 'test2' => [ 'name' => 'test3', 'type' => 'text2', 'size' => 202, 'tmp_name' => 'tmp_test2', 'error' => 1]]; $files = [ 'test' => [ 'name' => 'test1', 'type' => 'text', 'size' => 200, 'tmp_name' => 'tmp_test1', 'error' => 0]]; $files1 = [ 'test2' => [ 'name' => 'test3', 'type' => 'text2', 'size' => 202, 'tmp_name' => 'tmp_test2', 'error' => 1]]; $validator = new File\Upload(); $this->assertEquals($files, $validator->getFiles('test')); $this->assertEquals($files, $validator->getFiles('test1')); $this->assertEquals($files1, $validator->getFiles('test3')); $this->expectException(InvalidArgumentException::class); $this->expectExceptionMessage('was not found'); $this->assertEquals([], $validator->getFiles('test5')); } public function testGetFilesReturnsArtifactsFromPsr7UploadedFiles() { $upload1 = $this->prophesize(UploadedFileInterface::class); $upload1->getClientFilename()->willReturn('test1'); $upload2 = $this->prophesize(UploadedFileInterface::class); $upload2->getClientFilename()->willReturn('test3'); $files = [ 'test' => $upload1->reveal(), 'test2' => $upload2->reveal(), ]; $validator = new File\Upload(); $validator->setFiles($files); // Retrieve by index $this->assertEquals(['test' => $files['test']], $validator->getFiles('test')); $this->assertEquals(['test2' => $files['test2']], $validator->getFiles('test2')); // Retrieve by client filename $this->assertEquals(['test' => $files['test']], $validator->getFiles('test1')); $this->assertEquals(['test2' => $files['test2']], $validator->getFiles('test3')); return $validator; } /** * @depends testGetFilesReturnsArtifactsFromPsr7UploadedFiles */ public function testGetFilesRaisesExceptionWhenPsr7UploadedFilesArrayDoesNotContainGivenFilename( File\Upload $validator ) { $this->expectException(InvalidArgumentException::class); $this->expectExceptionMessage('was not found'); $validator->getFiles('test5'); } /** * Ensures that setFiles() returns expected value * * @return void */ public function testSetFiles() { $files = [ 'test' => [ 'name' => 'test1', 'type' => 'text', 'size' => 200, 'tmp_name' => 'tmp_test1', 'error' => 0], 'test2' => [ 'name' => 'test2', 'type' => 'text2', 'size' => 202, 'tmp_name' => 'tmp_test2', 'error' => 1]]; $_FILES = [ 'test' => [ 'name' => 'test3', 'type' => 'text3', 'size' => 203, 'tmp_name' => 'tmp_test3', 'error' => 2]]; $validator = new File\Upload(); $validator->setFiles([]); $this->assertEquals($_FILES, $validator->getFiles()); $validator->setFiles(); $this->assertEquals($_FILES, $validator->getFiles()); $validator->setFiles($files); $this->assertEquals($files, $validator->getFiles()); } public function testCanPopulateFilesFromArrayOfPsr7UploadedFiles() { $upload1 = $this->prophesize(UploadedFileInterface::class); $upload2 = $this->prophesize(UploadedFileInterface::class); $psrFiles = [ 'test4' => $upload1->reveal(), 'test5' => $upload2->reveal(), ]; $validator = new File\Upload(); $validator->setFiles($psrFiles); $this->assertSame($psrFiles, $validator->getFiles()); } /** * @group ZF-10738 */ public function testGetFilesReturnsEmptyArrayWhenFilesSuperglobalIsNull() { $_FILES = null; $validator = new File\Upload(); $validator->setFiles(); $this->assertEquals([], $validator->getFiles()); } /** * @group ZF-10738 */ public function testGetFilesReturnsEmptyArrayAfterSetFilesIsCalledWithNull() { $validator = new File\Upload(); $validator->setFiles(null); $this->assertEquals([], $validator->getFiles()); } /** * @group ZF-11258 */ public function testZF11258() { $validator = new File\Upload(); $this->assertFalse($validator->isValid(__DIR__ . '/_files/nofile.mo')); $this->assertArrayHasKey('fileUploadErrorFileNotFound', $validator->getMessages()); $this->assertContains("nofile.mo'", current($validator->getMessages())); } /** * @group ZF-12128 */ public function testErrorMessage() { $_FILES = [ 'foo' => [ 'name' => 'bar', 'type' => 'text', 'size' => 100, 'tmp_name' => 'tmp_bar', 'error' => 7, ] ]; $validator = new File\Upload; $validator->isValid('foo'); $this->assertEquals( [ 'fileUploadErrorCantWrite' => "Failed to write file 'bar' to disk", ], $validator->getMessages() ); } } ================================================ FILE: test/File/WordCountTest.php ================================================ 0, 'max' => 10], $testFile, true], [['min' => 10, 'max' => 15], $testFile, false], ]; // Dupe data in File Upload format foreach ($testData as $data) { $fileUpload = [ 'tmp_name' => $data[1], 'name' => basename($data[1]), 'size' => 200, 'error' => 0, 'type' => 'text' ]; $testData[] = [$data[0], $fileUpload, $data[2]]; } return $testData; } /** * Ensures that the validator follows expected behavior * * @dataProvider basicBehaviorDataProvider * @return void */ public function testBasic($options, $isValidParam, $expected) { $validator = new File\WordCount($options); $this->assertEquals($expected, $validator->isValid($isValidParam)); } /** * Ensures that the validator follows expected behavior for legacy Zend\Transfer API * * @dataProvider basicBehaviorDataProvider * @return void */ public function testLegacy($options, $isValidParam, $expected) { if (is_array($isValidParam)) { $validator = new File\WordCount($options); $this->assertEquals($expected, $validator->isValid($isValidParam['tmp_name'], $isValidParam)); } } /** * Ensures that getMin() returns expected value * * @return void */ public function testGetMin() { $validator = new File\WordCount(['min' => 1, 'max' => 5]); $this->assertEquals(1, $validator->getMin()); $this->expectException(InvalidArgumentException::class); $this->expectExceptionMessage('greater than or equal'); $validator = new File\WordCount(['min' => 5, 'max' => 1]); } /** * Ensures that setMin() returns expected value * * @return void */ public function testSetMin() { $validator = new File\WordCount(['min' => 1000, 'max' => 10000]); $validator->setMin(100); $this->assertEquals(100, $validator->getMin()); $this->expectException(InvalidArgumentException::class); $this->expectExceptionMessage('less than or equal'); $validator->setMin(20000); } /** * Ensures that getMax() returns expected value * * @return void */ public function testGetMax() { $validator = new File\WordCount(['min' => 1, 'max' => 100]); $this->assertEquals(100, $validator->getMax()); $this->expectException(InvalidArgumentException::class); $this->expectExceptionMessage('greater than or equal'); $validator = new File\WordCount(['min' => 5, 'max' => 1]); } /** * Ensures that setMax() returns expected value * * @return void */ public function testSetMax() { $validator = new File\WordCount(['min' => 1000, 'max' => 10000]); $validator->setMax(1000000); $this->assertEquals(1000000, $validator->getMax()); $validator->setMin(100); $this->assertEquals(1000000, $validator->getMax()); } /** * @group ZF-11258 */ public function testZF11258() { $validator = new File\WordCount(['min' => 1, 'max' => 10000]); $this->assertFalse($validator->isValid(__DIR__ . '/_files/nofile.mo')); $this->assertArrayHasKey('fileWordCountNotFound', $validator->getMessages()); $this->assertContains("does not exist", current($validator->getMessages())); } public function testEmptyFileShouldReturnFalseAndDisplayNotFoundMessage() { $validator = new File\WordCount(); $this->assertFalse($validator->isValid('')); $this->assertArrayHasKey(File\WordCount::NOT_FOUND, $validator->getMessages()); $filesArray = [ 'name' => '', 'size' => 0, 'tmp_name' => '', 'error' => UPLOAD_ERR_NO_FILE, 'type' => '', ]; $this->assertFalse($validator->isValid($filesArray)); $this->assertArrayHasKey(File\WordCount::NOT_FOUND, $validator->getMessages()); } public function testCanSetMinValueUsingOptionsArray() { $validator = new File\WordCount(['min' => 1000, 'max' => 10000]); $minValue = 33; $options = ['min' => $minValue]; $validator->setMin($options); $this->assertSame($minValue, $validator->getMin()); } public function invalidMinMaxValues() { return [ 'null' => [null], 'true' => [true], 'false' => [false], 'non-numeric-string' => ['not-a-good-value'], 'array-without-keys' => [[100]], 'object' => [(object) []], ]; } /** * @dataProvider invalidMinMaxValues */ public function testSettingMinValueRaisesExceptionForInvalidType($value) { $validator = new File\WordCount(['min' => 1000, 'max' => 10000]); $this->expectException(InvalidArgumentException::class); $this->expectExceptionMessage('Invalid options to validator provided'); $validator->setMin($value); } public function testCanSetMaxValueUsingOptionsArray() { $validator = new File\WordCount(['min' => 1000, 'max' => 10000]); $maxValue = 33333333; $options = ['max' => $maxValue]; $validator->setMax($options); $this->assertSame($maxValue, $validator->getMax()); } /** * @dataProvider invalidMinMaxValues */ public function testSettingMaxValueRaisesExceptionForInvalidType($value) { $validator = new File\WordCount(['min' => 1000, 'max' => 10000]); $this->expectException(InvalidArgumentException::class); $this->expectExceptionMessage('Invalid options to validator provided'); $validator->setMax($value); } public function testIsValidShouldThrowInvalidArgumentExceptionForArrayNotInFilesFormat() { $validator = new File\WordCount(['min' => 1, 'max' => 10000]); $value = ['foo' => 'bar']; $this->expectException(InvalidArgumentException::class); $this->expectExceptionMessage('Value array must be in $_FILES format'); $validator->isValid($value); } public function testConstructCanAcceptAllOptionsAsDiscreteArguments() { $min = 1; $max = 10000; $validator = new File\WordCount($min, $max); $this->assertSame($min, $validator->getMin()); $this->assertSame($max, $validator->getMax()); } } ================================================ FILE: test/File/_files/magic.7.mime ================================================ # Magic data for file(1) command. # Format is described in magic(files), where: # files is 5 on V7 and BSD, 4 on SV, and ?? on SVID. # Don't edit this file, edit /etc/magic or send your magic improvements # to the maintainers, at file@mx.gw.com #------------------------------------------------------------------------------ # Localstuff: file(1) magic for locally observed files # # $File: Localstuff,v 1.4 2003/03/23 04:17:27 christos Exp $ # Add any locally observed files here. Remember: # text if readable, executable if runnable binary, data if unreadable. #------------------------------------------------------------------------------ # $File$ # acorn: file(1) magic for files found on Acorn systems # # RISC OS Chunk File Format # From RISC OS Programmer's Reference Manual, Appendix D # We guess the file type from the type of the first chunk. 0 lelong 0xc3cbc6c5 RISC OS Chunk data >12 string OBJ_ \b, AOF object >12 string LIB_ \b, ALF library # RISC OS AIF, contains "SWI OS_Exit" at offset 16. 16 lelong 0xef000011 RISC OS AIF executable # RISC OS Draw files # From RISC OS Programmer's Reference Manual, Appendix E 0 string Draw RISC OS Draw file data # RISC OS new format font files # From RISC OS Programmer's Reference Manual, Appendix E 0 string FONT\0 RISC OS outline font data, >5 byte x version %d 0 string FONT\1 RISC OS 1bpp font data, >5 byte x version %d 0 string FONT\4 RISC OS 4bpp font data >5 byte x version %d # RISC OS Music files # From RISC OS Programmer's Reference Manual, Appendix E 0 string Maestro\r RISC OS music file >8 byte x version %d >8 byte x type %d # Digital Symphony data files # From: Bernard Jungen (bern8817@euphonynet.be) 0 string \x02\x01\x13\x13\x13\x01\x0d\x10 Digital Symphony sound sample (RISC OS), >8 byte x version %d, >9 pstring x named "%s", >(9.b+19) byte =0 8-bit logarithmic >(9.b+19) byte =1 LZW-compressed linear >(9.b+19) byte =2 8-bit linear signed >(9.b+19) byte =3 16-bit linear signed >(9.b+19) byte =4 SigmaDelta-compressed linear >(9.b+19) byte =5 SigmaDelta-compressed logarithmic >(9.b+19) byte >5 unknown format 0 string \x02\x01\x13\x13\x14\x12\x01\x0b Digital Symphony song (RISC OS), >8 byte x version %d, >9 byte =1 1 voice, >9 byte !1 %d voices, >10 leshort =1 1 track, >10 leshort !1 %d tracks, >12 leshort =1 1 pattern >12 leshort !1 %d patterns 0 string \x02\x01\x13\x13\x10\x14\x12\x0e >9 byte =0 Digital Symphony sequence (RISC OS), >>8 byte x version %d, >>10 byte =1 1 line, >>10 byte !1 %d lines, >>11 leshort =1 1 position >>11 leshort !1 %d positions >9 byte =1 Digital Symphony pattern data (RISC OS), >>8 byte x version %d, >>10 leshort =1 1 pattern >>10 leshort !1 %d patterns #------------------------------------------------------------------------------ # $File$ # adi: file(1) magic for ADi's objects # From Gregory McGarry # 0 leshort 0x521c COFF DSP21k >18 lelong &02 executable, >18 lelong ^02 >>18 lelong &01 static object, >>18 lelong ^01 relocatable object, >18 lelong &010 stripped >18 lelong ^010 not stripped #------------------------------------------------------------------------------ # $File: adventure,v 1.13 2010/12/31 16:32:54 christos Exp $ # adventure: file(1) magic for Adventure game files # # from Allen Garvin # Edited by Dave Chapeskie Jun 28, 1998 # Edited by Chris Chittleborough , March 2002 # # ALAN # I assume there are other, lower versions, but these are the only ones I # saw in the archive. 0 beshort 0x0206 ALAN game data >2 byte <10 version 2.6%d # Infocom (see z-machine) #------------------------------------------------------------------------------ # Z-machine: file(1) magic for Z-machine binaries. # Updated by Adam Buchbinder # #http://www.gnelson.demon.co.uk/zspec/sect11.html #http://www.jczorkmid.net/~jpenney/ZSpec11-latest.txt #http://en.wikipedia.org/wiki/Z-machine # The first byte is the Z-machine revision; it is always between 1 and 8. We # had false matches (for instance, inbig5.ocp from the Omega TeX extension as # well as an occasional MP3 file), so we sanity-check the version number. # # It might be possible to sanity-check the release number as well, as it seems # (at least in classic Infocom games) to always be a relatively small number, # always under 150 or so, but as this isn't rigorous, we'll wait on that until # it becomes clear that it's needed. # 0 ubyte >0 >0 ubyte <9 >>16 belong&0xfe00f0f0 0x3030 >>>0 ubyte < 10 >>>>2 ubeshort < 10 >>>>>18 regex [0-9][0-9][0-9][0-9][0-9][0-9] >>>>>>0 ubyte < 10 Infocom (Z-machine %d, >>>>>>>2 ubeshort < 10 Release %d / >>>>>>>>18 string >\0 Serial %.6s) !:strength + 40 #------------------------------------------------------------------------------ # Glulx: file(1) magic for Glulx binaries. # # I haven't checked for false matches yet. # 0 string Glul Glulx game data >4 beshort x (Version %d >>6 byte x \b.%d >>8 byte x \b.%d) >36 string Info Compiled by Inform # For Quetzal and blorb magic see iff # TADS (Text Adventure Development System) version 2 # All files are machine-independent (games compile to byte-code) and are tagged # with a version string of the form "V2..\0". # Game files start with "TADS2 bin\n\r\032\0" then the compiler version. 0 string TADS2\ bin TADS >9 belong !0x0A0D1A00 game data, CORRUPTED >9 belong 0x0A0D1A00 >>13 string >\0 %s game data # Resource files start with "TADS2 rsc\n\r\032\0" then the compiler version. 0 string TADS2\ rsc TADS >9 belong !0x0A0D1A00 resource data, CORRUPTED >9 belong 0x0A0D1A00 >>13 string >\0 %s resource data # Some saved game files start with "TADS2 save/g\n\r\032\0", a little-endian # 2-byte length N, the N-char name of the game file *without* a NUL (darn!), # "TADS2 save\n\r\032\0" and the interpreter version. 0 string TADS2\ save/g TADS >12 belong !0x0A0D1A00 saved game data, CORRUPTED >12 belong 0x0A0D1A00 >>(16.s+32) string >\0 %s saved game data # Other saved game files start with "TADS2 save\n\r\032\0" and the interpreter # version. 0 string TADS2\ save TADS >10 belong !0x0A0D1A00 saved game data, CORRUPTED >10 belong 0x0A0D1A00 >>14 string >\0 %s saved game data # TADS (Text Adventure Development System) version 3 # Game files start with "T3-image\015\012\032" 0 string T3-image\015\012\032 >11 leshort x TADS 3 game data (format version %d) # Saved game files start with "T3-state-v####\015\012\032" # where #### is a format version number 0 string T3-state-v >14 string \015\012\032 TADS 3 saved game data (format version >>10 byte x %c >>11 byte x \b%c >>12 byte x \b%c >>13 byte x \b%c) # Danny Milosavljevic # this are adrift (adventure game standard) game files, extension .taf # depending on version magic continues with 0x93453E6139FA (V 4.0) # 0x9445376139FA (V 3.90) # 0x9445366139FA (V 3.80) # this is from source (http://www.adrift.org.uk/) and I have some taf # files, and checked them. #0 belong 0x3C423FC9 #>4 belong 0x6A87C2CF Adrift game file #!:mime application/x-adrift #------------------------------------------------------------------------------ # $File$ # allegro: file(1) magic for Allegro datafiles # Toby Deshane # 0 belong 0x736C6821 Allegro datafile (packed) 0 belong 0x736C682E Allegro datafile (not packed/autodetect) 0 belong 0x736C682B Allegro datafile (appended exe data) #------------------------------------------------------------------------------ # $File$ # alliant: file(1) magic for Alliant FX series a.out files # # If the FX series is the one that had a processor with a 68K-derived # instruction set, the "short" should probably become "beshort" and the # "long" should probably become "belong". # If it's the i860-based one, they should probably become either the # big-endian or little-endian versions, depending on the mode they ran # the 860 in.... # 0 short 0420 0420 Alliant virtual executable >2 short &0x0020 common library >16 long >0 not stripped 0 short 0421 0421 Alliant compact executable >2 short &0x0020 common library >16 long >0 not stripped #------------------------------------------------------------------------------ # $File$ # alpha architecture description # 0 leshort 0603 COFF format alpha >22 leshort&030000 !020000 executable >24 leshort 0410 pure >24 leshort 0413 paged >22 leshort&020000 !0 dynamically linked >16 lelong !0 not stripped >16 lelong 0 stripped >22 leshort&030000 020000 shared library >24 leshort 0407 object >27 byte x - version %d >26 byte x .%d >28 byte x -%d # Basic recognition of Digital UNIX core dumps - Mike Bremford # # The actual magic number is just "Core", followed by a 2-byte version # number; however, treating any file that begins with "Core" as a Digital # UNIX core dump file may produce too many false hits, so we include one # byte of the version number as well; DU 5.0 appears only to be up to # version 2. # 0 string Core\001 Alpha COFF format core dump (Digital UNIX) >24 string >\0 \b, from '%s' 0 string Core\002 Alpha COFF format core dump (Digital UNIX) >24 string >\0 \b, from '%s' #------------------------------------------------------------------------------ # $File$ # amanda: file(1) magic for amanda file format # 0 string AMANDA:\ AMANDA >8 string TAPESTART\ DATE tape header file, >>23 string X >>>25 string >\ Unused %s >>23 string >\ DATE %s >8 string FILE\ dump file, >>13 string >\ DATE %s #------------------------------------------------------------------------------ # $File: amigaos,v 1.14 2009/09/19 16:28:07 christos Exp $ # amigaos: file(1) magic for AmigaOS binary formats: # # From ignatios@cs.uni-bonn.de (Ignatios Souvatzis) # 0 belong 0x000003fa AmigaOS shared library 0 belong 0x000003f3 AmigaOS loadseg()ble executable/binary 0 belong 0x000003e7 AmigaOS object/library data # 0 beshort 0xe310 Amiga Workbench >2 beshort 1 >>48 byte 1 disk icon >>48 byte 2 drawer icon >>48 byte 3 tool icon >>48 byte 4 project icon >>48 byte 5 garbage icon >>48 byte 6 device icon >>48 byte 7 kickstart icon >>48 byte 8 workbench application icon >2 beshort >1 icon, vers. %d # # various sound formats from the Amiga # G=F6tz Waschk # 0 string FC14 Future Composer 1.4 Module sound file 0 string SMOD Future Composer 1.3 Module sound file 0 string AON4artofnoise Art Of Noise Module sound file 1 string MUGICIAN/SOFTEYES Mugician Module sound file 58 string SIDMON\ II\ -\ THE Sidmon 2.0 Module sound file 0 string Synth4.0 Synthesis Module sound file 0 string ARP. The Holy Noise Module sound file 0 string BeEp\0 JamCracker Module sound file 0 string COSO\0 Hippel-COSO Module sound file # Too simple (short, pure ASCII, deep), MPi #26 string V.3 Brian Postma's Soundmon Module sound file v3 #26 string BPSM Brian Postma's Soundmon Module sound file v3 #26 string V.2 Brian Postma's Soundmon Module sound file v2 # The following are from: "Stefan A. Haubenthal" 0 beshort 0x0f00 AmigaOS bitmap font 0 beshort 0x0f03 AmigaOS outline font 0 belong 0x80001001 AmigaOS outline tag 0 string ##\ version catalog translation 0 string EMOD\0 Amiga E module 8 string ECXM\0 ECX module 0 string/c @database AmigaGuide file # Amiga disk types # 0 string RDSK Rigid Disk Block >160 string x on %.24s 0 string DOS\0 Amiga DOS disk 0 string DOS\1 Amiga FFS disk 0 string DOS\2 Amiga Inter DOS disk 0 string DOS\3 Amiga Inter FFS disk 0 string DOS\4 Amiga Fastdir DOS disk 0 string DOS\5 Amiga Fastdir FFS disk 0 string KICK Kickstart disk # From: Alex Beregszaszi 0 string LZX LZX compressed archive (Amiga) # From: Przemek Kramarczyk 0 string .KEY AmigaDOS script 0 string .key AmigaDOS script #------------------------------------------------------------ # $File: android,v 1.6 2014/08/04 06:00:36 christos Exp $ # Various android related magic entries #------------------------------------------------------------ # Dalvik .dex format. http://retrodev.com/android/dexformat.html # From "Mike Fleming" # Fixed to avoid regexec 17 errors on some dex files # From "Tim Strazzere" 0 string dex\n >0 regex dex\n[0-9]{2}\0 Dalvik dex file >4 string >000 version %s 0 string dey\n >0 regex dey\n[0-9]{2}\0 Dalvik dex file (optimized for host) >4 string >000 version %s # Android bootimg format # From https://android.googlesource.com/\ # platform/system/core/+/master/mkbootimg/bootimg.h 0 string ANDROID! Android bootimg >1024 string LOKI\01 \b, LOKI'd >8 lelong >0 \b, kernel >>12 lelong >0 \b (0x%x) >16 lelong >0 \b, ramdisk >>20 lelong >0 \b (0x%x) >24 lelong >0 \b, second stage >>28 lelong >0 \b (0x%x) >36 lelong >0 \b, page size: %d >38 string >0 \b, name: %s >64 string >0 \b, cmdline (%s) # Android Backup archive # From: Ariel Shkedi # File extension: .ab # No mime-type defined # URL: https://github.com/android/platform_frameworks_base/blob/\ # 0bacfd2ba68d21a68a3df345b830bc2a1e515b5a/services/java/com/\ # android/server/BackupManagerService.java#L2367 # After the header comes a tar file # If compressed, the entire tar file is compressed with JAVA deflate # # Include the version number hardcoded with the magic string to avoid # false positives 0 string/b ANDROID\ BACKUP\n1\n Android Backup >17 string 0\n \b, Not-Compressed >17 string 1\n \b, Compressed # any string as long as it's not the word none (which is matched below) >>19 regex/1l \^([^n\n]|n[^o]|no[^n]|non[^e]|none.+).* \b, Encrypted (%s) >>19 string none\n \b, Not-Encrypted # Commented out because they don't seem useful to print # (but they are part of the header - the tar file comes after them): #>>>&1 regex/1l .* \b, Password salt: %s #>>>>&1 regex/1l .* \b, Master salt: %s #>>>>>&1 regex/1l .* \b, PBKDF2 rounds: %s #>>>>>>&1 regex/1l .* \b, IV: %s #>>>>>>>&1 regex/1l .* \b, Key: %s # *.pit files by Joerg Jenderek # http://forum.xda-developers.com/showthread.php?p=9122369 # http://forum.xda-developers.com/showthread.php?t=816449 # Partition Information Table for Samsung's smartphone with Android # used by flash software Odin 0 ulelong 0x12349876 # 1st pit entry marker >0x01C ulequad&0xFFFFFFFCFFFFFFFC =0x0000000000000000 # minimal 13 and maximal 18 PIT entries found >>4 ulelong <128 Partition Information Table for Samsung smartphone >>>4 ulelong x \b, %d entries # 1. pit entry >>>4 ulelong >0 \b; #1 >>>0x01C use PIT-entry >>>4 ulelong >1 \b; #2 >>>0x0A0 use PIT-entry >>>4 ulelong >2 \b; #3 >>>0x124 use PIT-entry >>>4 ulelong >3 \b; #4 >>>0x1A8 use PIT-entry >>>4 ulelong >4 \b; #5 >>>0x22C use PIT-entry >>>4 ulelong >5 \b; #6 >>>0x2B0 use PIT-entry >>>4 ulelong >6 \b; #7 >>>0x334 use PIT-entry >>>4 ulelong >7 \b; #8 >>>0x3B8 use PIT-entry >>>4 ulelong >8 \b; #9 >>>0x43C use PIT-entry >>>4 ulelong >9 \b; #10 >>>0x4C0 use PIT-entry >>>4 ulelong >10 \b; #11 >>>0x544 use PIT-entry >>>4 ulelong >11 \b; #12 >>>0x5C8 use PIT-entry >>>4 ulelong >12 \b; #13 >>>>0x64C use PIT-entry # 14. pit entry >>>4 ulelong >13 \b; #14 >>>>0x6D0 use PIT-entry >>>4 ulelong >14 \b; #15 >>>0x754 use PIT-entry >>>4 ulelong >15 \b; #16 >>>0x7D8 use PIT-entry >>>4 ulelong >16 \b; #17 >>>0x85C use PIT-entry # 18. pit entry >>>4 ulelong >17 \b; #18 >>>0x8E0 use PIT-entry 0 name PIT-entry # garbage value implies end of pit entries >0x00 ulequad&0xFFFFFFFCFFFFFFFC =0x0000000000000000 # skip empty partition name >>0x24 ubyte !0 # partition name >>>0x24 string >\0 %-.32s # flags >>>0x0C ulelong&0x00000002 2 \b+RW # partition ID: # 0~IPL,MOVINAND,GANG;1~PIT,GPT;2~HIDDEN;3~SBL,HIDDEN;4~SBL2,HIDDEN;5~BOOT;6~KENREl,RECOVER,misc;7~RECOVER # ;11~MODEM;20~efs;21~PARAM;22~FACTORY,SYSTEM;23~DBDATAFS,USERDATA;24~CACHE;80~BOOTLOADER;81~TZSW >>>0x08 ulelong x (0x%x) # filename >>>0x44 string >\0 "%-.64s" #>>>0x18 ulelong >0 # blocksize in 512 byte units ? #>>>>0x18 ulelong x \b, %db # partition size in blocks ? #>>>>0x22 ulelong x \b*%d # Android bootimg format # From https://android.googlesource.com/\ # platform/system/core/+/master/libsparse/sparse_format.h 0 lelong 0xed26ff3a Android sparse image >4 leshort x \b, version: %d >6 leshort x \b.%d >16 lelong x \b, Total of %d >12 lelong x \b %d-byte output blocks in >20 lelong x \b %d input chunks. #------------------------------------------------------------------------------ # $File: animation,v 1.55 2014/09/13 14:29:51 christos Exp $ # animation: file(1) magic for animation/movie formats # # animation formats # MPEG, FLI, DL originally from vax@ccwf.cc.utexas.edu (VaX#n8) # FLC, SGI, Apple originally from Daniel Quinlan (quinlan@yggdrasil.com) # SGI and Apple formats 0 string MOVI Silicon Graphics movie file !:mime video/x-sgi-movie 4 string moov Apple QuickTime !:mime video/quicktime >12 string mvhd \b movie (fast start) >12 string mdra \b URL >12 string cmov \b movie (fast start, compressed header) >12 string rmra \b multiple URLs 4 string mdat Apple QuickTime movie (unoptimized) !:mime video/quicktime #4 string wide Apple QuickTime movie (unoptimized) #!:mime video/quicktime #4 string skip Apple QuickTime movie (modified) #!:mime video/quicktime #4 string free Apple QuickTime movie (modified) #!:mime video/quicktime 4 string idsc Apple QuickTime image (fast start) !:mime image/x-quicktime #4 string idat Apple QuickTime image (unoptimized) #!:mime image/x-quicktime 4 string pckg Apple QuickTime compressed archive !:mime application/x-quicktime-player 4 string/W jP JPEG 2000 image !:mime image/jp2 # http://www.ftyps.com/ with local additions 4 string ftyp ISO Media >8 string 3g2 \b, MPEG v4 system, 3GPP2 !:mime video/3gpp2 >>11 byte 4 \b v4 (H.263/AMR GSM 6.10) >>11 byte 5 \b v5 (H.263/AMR GSM 6.10) >>11 byte 6 \b v6 (ITU H.264/AMR GSM 6.10) >>11 byte a \b C.S0050-0 V1.0 >>11 byte b \b C.S0050-0-A V1.0.0 >>11 byte c \b C.S0050-0-B V1.0 >8 string 3ge \b, MPEG v4 system, 3GPP !:mime video/3gpp >>11 byte 6 \b, Release 6 MBMS Extended Presentations >>11 byte 7 \b, Release 7 MBMS Extended Presentations >8 string 3gg \b, MPEG v4 system, 3GPP >11 byte 6 \b, Release 6 General Profile !:mime video/3gpp >8 string 3gp \b, MPEG v4 system, 3GPP >11 byte 1 \b, Release %d (non existent) >11 byte 2 \b, Release %d (non existent) >11 byte 3 \b, Release %d (non existent) >11 byte 4 \b, Release %d >11 byte 5 \b, Release %d >11 byte 6 \b, Release %d >11 byte 7 \b, Release %d Streaming Servers !:mime video/3gpp >8 string 3gs \b, MPEG v4 system, 3GPP >11 byte 7 \b, Release %d Streaming Servers !:mime video/3gpp >8 string avc1 \b, MPEG v4 system, 3GPP JVT AVC [ISO 14496-12:2005] !:mime video/mp4 >8 string/W qt \b, Apple QuickTime movie !:mime video/quicktime >8 string CAEP \b, Canon Digital Camera >8 string caqv \b, Casio Digital Camera >8 string CDes \b, Convergent Design >8 string da0a \b, DMB MAF w/ MPEG Layer II aud, MOT slides, DLS, JPG/PNG/MNG >8 string da0b \b, DMB MAF, ext DA0A, with 3GPP timed text, DID, TVA, REL, IPMP >8 string da1a \b, DMB MAF audio with ER-BSAC audio, JPG/PNG/MNG images >8 string da1b \b, DMB MAF, ext da1a, with 3GPP timed text, DID, TVA, REL, IPMP >8 string da2a \b, DMB MAF aud w/ HE-AAC v2 aud, MOT slides, DLS, JPG/PNG/MNG >8 string da2b \b, DMB MAF, ext da2a, with 3GPP timed text, DID, TVA, REL, IPMP >8 string da3a \b, DMB MAF aud with HE-AAC aud, JPG/PNG/MNG images >8 string da3b \b, DMB MAF, ext da3a w/ BIFS, 3GPP, DID, TVA, REL, IPMP >8 string dmb1 \b, DMB MAF supporting all the components defined in the spec >8 string dmpf \b, Digital Media Project >8 string drc1 \b, Dirac (wavelet compression), encap in ISO base media (MP4) >8 string dv1a \b, DMB MAF vid w/ AVC vid, ER-BSAC aud, BIFS, JPG/PNG/MNG, TS >8 string dv1b \b, DMB MAF, ext dv1a, with 3GPP timed text, DID, TVA, REL, IPMP >8 string dv2a \b, DMB MAF vid w/ AVC vid, HE-AAC v2 aud, BIFS, JPG/PNG/MNG, TS >8 string dv2b \b, DMB MAF, ext dv2a, with 3GPP timed text, DID, TVA, REL, IPMP >8 string dv3a \b, DMB MAF vid w/ AVC vid, HE-AAC aud, BIFS, JPG/PNG/MNG, TS >8 string dv3b \b, DMB MAF, ext dv3a, with 3GPP timed text, DID, TVA, REL, IPMP >8 string dvr1 \b, DVB (.DVB) over RTP !:mime video/vnd.dvb.file >8 string dvt1 \b, DVB (.DVB) over MPEG-2 Transport Stream !:mime video/vnd.dvb.file >8 string F4V \b, Video for Adobe Flash Player 9+ (.F4V) !:mime video/mp4 >8 string F4P \b, Protected Video for Adobe Flash Player 9+ (.F4P) !:mime video/mp4 >8 string F4A \b, Audio for Adobe Flash Player 9+ (.F4A) !:mime audio/mp4 >8 string F4B \b, Audio Book for Adobe Flash Player 9+ (.F4B) !:mime audio/mp4 >8 string isc2 \b, ISMACryp 2.0 Encrypted File # ?/enc-isoff-generic >8 string iso2 \b, MP4 Base Media v2 [ISO 14496-12:2005] !:mime video/mp4 >8 string isom \b, MP4 Base Media v1 [IS0 14496-12:2003] !:mime video/mp4 >8 string/W jp2 \b, JPEG 2000 !:mime image/jp2 >8 string JP2 \b, JPEG 2000 Image (.JP2) [ISO 15444-1 ?] !:mime image/jp2 >8 string JP20 \b, Unknown, from GPAC samples (prob non-existent) >8 string jpm \b, JPEG 2000 Compound Image (.JPM) [ISO 15444-6] !:mime image/jpm >8 string jpx \b, JPEG 2000 w/ extensions (.JPX) [ISO 15444-2] !:mime image/jpx >8 string KDDI \b, 3GPP2 EZmovie for KDDI 3G cellphones !:mime video/3gpp2 >8 string M4A \b, Apple iTunes ALAC/AAC-LC (.M4A) Audio !:mime audio/x-m4a >8 string M4B \b, Apple iTunes ALAC/AAC-LC (.M4B) Audio Book !:mime audio/mp4 >8 string M4P \b, Apple iTunes ALAC/AAC-LC (.M4P) AES Protected Audio !:mime video/mp4 >8 string M4V \b, Apple iTunes Video (.M4V) Video !:mime video/x-m4v >8 string M4VH \b, Apple TV (.M4V) !:mime video/x-m4v >8 string M4VP \b, Apple iPhone (.M4V) !:mime video/x-m4v >8 string mj2s \b, Motion JPEG 2000 [ISO 15444-3] Simple Profile !:mime video/mj2 >8 string mjp2 \b, Motion JPEG 2000 [ISO 15444-3] General Profile !:mime video/mj2 >8 string mmp4 \b, MPEG-4/3GPP Mobile Profile (.MP4 / .3GP) (for NTT) !:mime video/mp4 >8 string mobi \b, MPEG-4, MOBI format !:mime video/mp4 >8 string mp21 \b, MPEG-21 [ISO/IEC 21000-9] >8 string mp41 \b, MP4 v1 [ISO 14496-1:ch13] !:mime video/mp4 >8 string mp42 \b, MP4 v2 [ISO 14496-14] !:mime video/mp4 >8 string mp71 \b, MP4 w/ MPEG-7 Metadata [per ISO 14496-12] >8 string mp7t \b, MPEG v4 system, MPEG v7 XML >8 string mp7b \b, MPEG v4 system, MPEG v7 binary XML >8 string mmp4 \b, MPEG v4 system, 3GPP Mobile !:mime video/mp4 >8 string MPPI \b, Photo Player, MAF [ISO/IEC 23000-3] >8 string mqt \b, Sony / Mobile QuickTime (.MQV) US Pat 7,477,830 !:mime video/quicktime >8 string MSNV \b, MPEG-4 (.MP4) for SonyPSP !:mime audio/mp4 >8 string NDAS \b, MP4 v2 [ISO 14496-14] Nero Digital AAC Audio !:mime audio/mp4 >8 string NDSC \b, MPEG-4 (.MP4) Nero Cinema Profile !:mime video/mp4 >8 string NDSH \b, MPEG-4 (.MP4) Nero HDTV Profile !:mime video/mp4 >8 string NDSM \b, MPEG-4 (.MP4) Nero Mobile Profile !:mime video/mp4 >8 string NDSP \b, MPEG-4 (.MP4) Nero Portable Profile !:mime video/mp4 >8 string NDSS \b, MPEG-4 (.MP4) Nero Standard Profile !:mime video/mp4 >8 string NDXC \b, H.264/MPEG-4 AVC (.MP4) Nero Cinema Profile !:mime video/mp4 >8 string NDXH \b, H.264/MPEG-4 AVC (.MP4) Nero HDTV Profile !:mime video/mp4 >8 string NDXM \b, H.264/MPEG-4 AVC (.MP4) Nero Mobile Profile !:mime video/mp4 >8 string NDXP \b, H.264/MPEG-4 AVC (.MP4) Nero Portable Profile !:mime video/mp4 >8 string NDXS \b, H.264/MPEG-4 AVC (.MP4) Nero Standard Profile !:mime video/mp4 >8 string odcf \b, OMA DCF DRM Format 2.0 (OMA-TS-DRM-DCF-V2_0-20060303-A) >8 string opf2 \b, OMA PDCF DRM Format 2.1 (OMA-TS-DRM-DCF-V2_1-20070724-C) >8 string opx2 \b, OMA PDCF DRM + XBS ext (OMA-TS-DRM_XBS-V1_0-20070529-C) >8 string pana \b, Panasonic Digital Camera >8 string qt \b, Apple QuickTime (.MOV/QT) !:mime video/quicktime >8 string ROSS \b, Ross Video >8 string sdv \b, SD Memory Card Video >8 string ssc1 \b, Samsung stereo, single stream (patent pending) >8 string ssc2 \b, Samsung stereo, dual stream (patent pending) # MPEG sequences # Scans for all common MPEG header start codes 0 belong 0x00000001 >4 byte&0x1F 0x07 JVT NAL sequence, H.264 video >>5 byte 66 \b, baseline >>5 byte 77 \b, main >>5 byte 88 \b, extended >>7 byte x \b @ L %u 0 belong&0xFFFFFF00 0x00000100 >3 byte 0xBA MPEG sequence !:mime video/mpeg >>4 byte &0x40 \b, v2, program multiplex >>4 byte ^0x40 \b, v1, system multiplex >3 byte 0xBB MPEG sequence, v1/2, multiplex (missing pack header) >3 byte&0x1F 0x07 MPEG sequence, H.264 video >>4 byte 66 \b, baseline >>4 byte 77 \b, main >>4 byte 88 \b, extended >>6 byte x \b @ L %u # GRR too general as it catches also FoxPro Memo example NG.FPT >3 byte 0xB0 MPEG sequence, v4 # TODO: maybe this extra line exclude FoxPro Memo example NG.FPT starting with 000001b0 00000100 00000000 #>>4 byte !0 MPEG sequence, v4 !:mime video/mpeg4-generic >>5 belong 0x000001B5 >>>9 byte &0x80 >>>>10 byte&0xF0 16 \b, video >>>>10 byte&0xF0 32 \b, still texture >>>>10 byte&0xF0 48 \b, mesh >>>>10 byte&0xF0 64 \b, face >>>9 byte&0xF8 8 \b, video >>>9 byte&0xF8 16 \b, still texture >>>9 byte&0xF8 24 \b, mesh >>>9 byte&0xF8 32 \b, face >>4 byte 1 \b, simple @ L1 >>4 byte 2 \b, simple @ L2 >>4 byte 3 \b, simple @ L3 >>4 byte 4 \b, simple @ L0 >>4 byte 17 \b, simple scalable @ L1 >>4 byte 18 \b, simple scalable @ L2 >>4 byte 33 \b, core @ L1 >>4 byte 34 \b, core @ L2 >>4 byte 50 \b, main @ L2 >>4 byte 51 \b, main @ L3 >>4 byte 53 \b, main @ L4 >>4 byte 66 \b, n-bit @ L2 >>4 byte 81 \b, scalable texture @ L1 >>4 byte 97 \b, simple face animation @ L1 >>4 byte 98 \b, simple face animation @ L2 >>4 byte 99 \b, simple face basic animation @ L1 >>4 byte 100 \b, simple face basic animation @ L2 >>4 byte 113 \b, basic animation text @ L1 >>4 byte 114 \b, basic animation text @ L2 >>4 byte 129 \b, hybrid @ L1 >>4 byte 130 \b, hybrid @ L2 >>4 byte 145 \b, advanced RT simple @ L! >>4 byte 146 \b, advanced RT simple @ L2 >>4 byte 147 \b, advanced RT simple @ L3 >>4 byte 148 \b, advanced RT simple @ L4 >>4 byte 161 \b, core scalable @ L1 >>4 byte 162 \b, core scalable @ L2 >>4 byte 163 \b, core scalable @ L3 >>4 byte 177 \b, advanced coding efficiency @ L1 >>4 byte 178 \b, advanced coding efficiency @ L2 >>4 byte 179 \b, advanced coding efficiency @ L3 >>4 byte 180 \b, advanced coding efficiency @ L4 >>4 byte 193 \b, advanced core @ L1 >>4 byte 194 \b, advanced core @ L2 >>4 byte 209 \b, advanced scalable texture @ L1 >>4 byte 210 \b, advanced scalable texture @ L2 >>4 byte 211 \b, advanced scalable texture @ L3 >>4 byte 225 \b, simple studio @ L1 >>4 byte 226 \b, simple studio @ L2 >>4 byte 227 \b, simple studio @ L3 >>4 byte 228 \b, simple studio @ L4 >>4 byte 229 \b, core studio @ L1 >>4 byte 230 \b, core studio @ L2 >>4 byte 231 \b, core studio @ L3 >>4 byte 232 \b, core studio @ L4 >>4 byte 240 \b, advanced simple @ L0 >>4 byte 241 \b, advanced simple @ L1 >>4 byte 242 \b, advanced simple @ L2 >>4 byte 243 \b, advanced simple @ L3 >>4 byte 244 \b, advanced simple @ L4 >>4 byte 245 \b, advanced simple @ L5 >>4 byte 247 \b, advanced simple @ L3b >>4 byte 248 \b, FGS @ L0 >>4 byte 249 \b, FGS @ L1 >>4 byte 250 \b, FGS @ L2 >>4 byte 251 \b, FGS @ L3 >>4 byte 252 \b, FGS @ L4 >>4 byte 253 \b, FGS @ L5 >3 byte 0xB5 MPEG sequence, v4 !:mime video/mpeg4-generic >>4 byte &0x80 >>>5 byte&0xF0 16 \b, video (missing profile header) >>>5 byte&0xF0 32 \b, still texture (missing profile header) >>>5 byte&0xF0 48 \b, mesh (missing profile header) >>>5 byte&0xF0 64 \b, face (missing profile header) >>4 byte&0xF8 8 \b, video (missing profile header) >>4 byte&0xF8 16 \b, still texture (missing profile header) >>4 byte&0xF8 24 \b, mesh (missing profile header) >>4 byte&0xF8 32 \b, face (missing profile header) >3 byte 0xB3 MPEG sequence !:mime video/mpeg >>12 belong 0x000001B8 \b, v1, progressive Y'CbCr 4:2:0 video >>12 belong 0x000001B2 \b, v1, progressive Y'CbCr 4:2:0 video >>12 belong 0x000001B5 \b, v2, >>>16 byte&0x0F 1 \b HP >>>16 byte&0x0F 2 \b Spt >>>16 byte&0x0F 3 \b SNR >>>16 byte&0x0F 4 \b MP >>>16 byte&0x0F 5 \b SP >>>17 byte&0xF0 64 \b@HL >>>17 byte&0xF0 96 \b@H-14 >>>17 byte&0xF0 128 \b@ML >>>17 byte&0xF0 160 \b@LL >>>17 byte &0x08 \b progressive >>>17 byte ^0x08 \b interlaced >>>17 byte&0x06 2 \b Y'CbCr 4:2:0 video >>>17 byte&0x06 4 \b Y'CbCr 4:2:2 video >>>17 byte&0x06 6 \b Y'CbCr 4:4:4 video >>11 byte &0x02 >>>75 byte &0x01 >>>>140 belong 0x000001B8 \b, v1, progressive Y'CbCr 4:2:0 video >>>>140 belong 0x000001B2 \b, v1, progressive Y'CbCr 4:2:0 video >>>>140 belong 0x000001B5 \b, v2, >>>>>144 byte&0x0F 1 \b HP >>>>>144 byte&0x0F 2 \b Spt >>>>>144 byte&0x0F 3 \b SNR >>>>>144 byte&0x0F 4 \b MP >>>>>144 byte&0x0F 5 \b SP >>>>>145 byte&0xF0 64 \b@HL >>>>>145 byte&0xF0 96 \b@H-14 >>>>>145 byte&0xF0 128 \b@ML >>>>>145 byte&0xF0 160 \b@LL >>>>>145 byte &0x08 \b progressive >>>>>145 byte ^0x08 \b interlaced >>>>>145 byte&0x06 2 \b Y'CbCr 4:2:0 video >>>>>145 byte&0x06 4 \b Y'CbCr 4:2:2 video >>>>>145 byte&0x06 6 \b Y'CbCr 4:4:4 video >>76 belong 0x000001B8 \b, v1, progressive Y'CbCr 4:2:0 video >>76 belong 0x000001B2 \b, v1, progressive Y'CbCr 4:2:0 video >>76 belong 0x000001B5 \b, v2, >>>80 byte&0x0F 1 \b HP >>>80 byte&0x0F 2 \b Spt >>>80 byte&0x0F 3 \b SNR >>>80 byte&0x0F 4 \b MP >>>80 byte&0x0F 5 \b SP >>>81 byte&0xF0 64 \b@HL >>>81 byte&0xF0 96 \b@H-14 >>>81 byte&0xF0 128 \b@ML >>>81 byte&0xF0 160 \b@LL >>>81 byte &0x08 \b progressive >>>81 byte ^0x08 \b interlaced >>>81 byte&0x06 2 \b Y'CbCr 4:2:0 video >>>81 byte&0x06 4 \b Y'CbCr 4:2:2 video >>>81 byte&0x06 6 \b Y'CbCr 4:4:4 video >>4 belong&0xFFFFFF00 0x78043800 \b, HD-TV 1920P >>>7 byte&0xF0 0x10 \b, 16:9 >>4 belong&0xFFFFFF00 0x50002D00 \b, SD-TV 1280I >>>7 byte&0xF0 0x10 \b, 16:9 >>4 belong&0xFFFFFF00 0x30024000 \b, PAL Capture >>>7 byte&0xF0 0x10 \b, 4:3 >>4 beshort&0xFFF0 0x2C00 \b, 4CIF >>>5 beshort&0x0FFF 0x01E0 \b NTSC >>>5 beshort&0x0FFF 0x0240 \b PAL >>>7 byte&0xF0 0x20 \b, 4:3 >>>7 byte&0xF0 0x30 \b, 16:9 >>>7 byte&0xF0 0x40 \b, 11:5 >>>7 byte&0xF0 0x80 \b, PAL 4:3 >>>7 byte&0xF0 0xC0 \b, NTSC 4:3 >>4 belong&0xFFFFFF00 0x2801E000 \b, LD-TV 640P >>>7 byte&0xF0 0x10 \b, 4:3 >>4 belong&0xFFFFFF00 0x1400F000 \b, 320x240 >>>7 byte&0xF0 0x10 \b, 4:3 >>4 belong&0xFFFFFF00 0x0F00A000 \b, 240x160 >>>7 byte&0xF0 0x10 \b, 4:3 >>4 belong&0xFFFFFF00 0x0A007800 \b, 160x120 >>>7 byte&0xF0 0x10 \b, 4:3 >>4 beshort&0xFFF0 0x1600 \b, CIF >>>5 beshort&0x0FFF 0x00F0 \b NTSC >>>5 beshort&0x0FFF 0x0120 \b PAL >>>7 byte&0xF0 0x20 \b, 4:3 >>>7 byte&0xF0 0x30 \b, 16:9 >>>7 byte&0xF0 0x40 \b, 11:5 >>>7 byte&0xF0 0x80 \b, PAL 4:3 >>>7 byte&0xF0 0xC0 \b, NTSC 4:3 >>>5 beshort&0x0FFF 0x0240 \b PAL 625 >>>>7 byte&0xF0 0x20 \b, 4:3 >>>>7 byte&0xF0 0x30 \b, 16:9 >>>>7 byte&0xF0 0x40 \b, 11:5 >>4 beshort&0xFFF0 0x2D00 \b, CCIR/ITU >>>5 beshort&0x0FFF 0x01E0 \b NTSC 525 >>>5 beshort&0x0FFF 0x0240 \b PAL 625 >>>7 byte&0xF0 0x20 \b, 4:3 >>>7 byte&0xF0 0x30 \b, 16:9 >>>7 byte&0xF0 0x40 \b, 11:5 >>4 beshort&0xFFF0 0x1E00 \b, SVCD >>>5 beshort&0x0FFF 0x01E0 \b NTSC 525 >>>5 beshort&0x0FFF 0x0240 \b PAL 625 >>>7 byte&0xF0 0x20 \b, 4:3 >>>7 byte&0xF0 0x30 \b, 16:9 >>>7 byte&0xF0 0x40 \b, 11:5 >>7 byte&0x0F 1 \b, 23.976 fps >>7 byte&0x0F 2 \b, 24 fps >>7 byte&0x0F 3 \b, 25 fps >>7 byte&0x0F 4 \b, 29.97 fps >>7 byte&0x0F 5 \b, 30 fps >>7 byte&0x0F 6 \b, 50 fps >>7 byte&0x0F 7 \b, 59.94 fps >>7 byte&0x0F 8 \b, 60 fps >>11 byte &0x04 \b, Constrained # MPEG ADTS Audio (*.mpx/mxa/aac) # from dreesen@math.fu-berlin.de # modified to fully support MPEG ADTS # MP3, M1A # modified by Joerg Jenderek # GRR the original test are too common for many DOS files # so don't accept as MP3 until we've tested the rate 0 beshort&0xFFFE 0xFFFA # rates >2 byte&0xF0 0x10 MPEG ADTS, layer III, v1, 32 kbps !:mime audio/mpeg >2 byte&0xF0 0x20 MPEG ADTS, layer III, v1, 40 kbps !:mime audio/mpeg >2 byte&0xF0 0x30 MPEG ADTS, layer III, v1, 48 kbps !:mime audio/mpeg >2 byte&0xF0 0x40 MPEG ADTS, layer III, v1, 56 kbps !:mime audio/mpeg >2 byte&0xF0 0x50 MPEG ADTS, layer III, v1, 64 kbps !:mime audio/mpeg >2 byte&0xF0 0x60 MPEG ADTS, layer III, v1, 80 kbps !:mime audio/mpeg >2 byte&0xF0 0x70 MPEG ADTS, layer III, v1, 96 kbps !:mime audio/mpeg >2 byte&0xF0 0x80 MPEG ADTS, layer III, v1, 112 kbps !:mime audio/mpeg >2 byte&0xF0 0x90 MPEG ADTS, layer III, v1, 128 kbps !:mime audio/mpeg >2 byte&0xF0 0xA0 MPEG ADTS, layer III, v1, 160 kbps !:mime audio/mpeg >2 byte&0xF0 0xB0 MPEG ADTS, layer III, v1, 192 kbps !:mime audio/mpeg >2 byte&0xF0 0xC0 MPEG ADTS, layer III, v1, 224 kbps !:mime audio/mpeg >2 byte&0xF0 0xD0 MPEG ADTS, layer III, v1, 256 kbps !:mime audio/mpeg >2 byte&0xF0 0xE0 MPEG ADTS, layer III, v1, 320 kbps !:mime audio/mpeg # timing >2 byte&0x0C 0x00 \b, 44.1 kHz >2 byte&0x0C 0x04 \b, 48 kHz >2 byte&0x0C 0x08 \b, 32 kHz # channels/options >3 byte&0xC0 0x00 \b, Stereo >3 byte&0xC0 0x40 \b, JntStereo >3 byte&0xC0 0x80 \b, 2x Monaural >3 byte&0xC0 0xC0 \b, Monaural #>1 byte ^0x01 \b, Data Verify #>2 byte &0x02 \b, Packet Pad #>2 byte &0x01 \b, Custom Flag #>3 byte &0x08 \b, Copyrighted #>3 byte &0x04 \b, Original Source #>3 byte&0x03 1 \b, NR: 50/15 ms #>3 byte&0x03 3 \b, NR: CCIT J.17 # MP2, M1A 0 beshort&0xFFFE 0xFFFC MPEG ADTS, layer II, v1 !:mime audio/mpeg # rates >2 byte&0xF0 0x10 \b, 32 kbps >2 byte&0xF0 0x20 \b, 48 kbps >2 byte&0xF0 0x30 \b, 56 kbps >2 byte&0xF0 0x40 \b, 64 kbps >2 byte&0xF0 0x50 \b, 80 kbps >2 byte&0xF0 0x60 \b, 96 kbps >2 byte&0xF0 0x70 \b, 112 kbps >2 byte&0xF0 0x80 \b, 128 kbps >2 byte&0xF0 0x90 \b, 160 kbps >2 byte&0xF0 0xA0 \b, 192 kbps >2 byte&0xF0 0xB0 \b, 224 kbps >2 byte&0xF0 0xC0 \b, 256 kbps >2 byte&0xF0 0xD0 \b, 320 kbps >2 byte&0xF0 0xE0 \b, 384 kbps # timing >2 byte&0x0C 0x00 \b, 44.1 kHz >2 byte&0x0C 0x04 \b, 48 kHz >2 byte&0x0C 0x08 \b, 32 kHz # channels/options >3 byte&0xC0 0x00 \b, Stereo >3 byte&0xC0 0x40 \b, JntStereo >3 byte&0xC0 0x80 \b, 2x Monaural >3 byte&0xC0 0xC0 \b, Monaural #>1 byte ^0x01 \b, Data Verify #>2 byte &0x02 \b, Packet Pad #>2 byte &0x01 \b, Custom Flag #>3 byte &0x08 \b, Copyrighted #>3 byte &0x04 \b, Original Source #>3 byte&0x03 1 \b, NR: 50/15 ms #>3 byte&0x03 3 \b, NR: CCIT J.17 # MPA, M1A # updated by Joerg Jenderek # GRR the original test are too common for many DOS files, so test 32 <= kbits <= 448 # GRR this test is still too general as it catches a BOM of UTF-16 files (0xFFFE) # FIXME: Almost all little endian UTF-16 text with BOM are clobbered by these entries #0 beshort&0xFFFE 0xFFFE #>2 ubyte&0xF0 >0x0F #>>2 ubyte&0xF0 <0xE1 MPEG ADTS, layer I, v1 ## rate #>>>2 byte&0xF0 0x10 \b, 32 kbps #>>>2 byte&0xF0 0x20 \b, 64 kbps #>>>2 byte&0xF0 0x30 \b, 96 kbps #>>>2 byte&0xF0 0x40 \b, 128 kbps #>>>2 byte&0xF0 0x50 \b, 160 kbps #>>>2 byte&0xF0 0x60 \b, 192 kbps #>>>2 byte&0xF0 0x70 \b, 224 kbps #>>>2 byte&0xF0 0x80 \b, 256 kbps #>>>2 byte&0xF0 0x90 \b, 288 kbps #>>>2 byte&0xF0 0xA0 \b, 320 kbps #>>>2 byte&0xF0 0xB0 \b, 352 kbps #>>>2 byte&0xF0 0xC0 \b, 384 kbps #>>>2 byte&0xF0 0xD0 \b, 416 kbps #>>>2 byte&0xF0 0xE0 \b, 448 kbps ## timing #>>>2 byte&0x0C 0x00 \b, 44.1 kHz #>>>2 byte&0x0C 0x04 \b, 48 kHz #>>>2 byte&0x0C 0x08 \b, 32 kHz ## channels/options #>>>3 byte&0xC0 0x00 \b, Stereo #>>>3 byte&0xC0 0x40 \b, JntStereo #>>>3 byte&0xC0 0x80 \b, 2x Monaural #>>>3 byte&0xC0 0xC0 \b, Monaural ##>1 byte ^0x01 \b, Data Verify ##>2 byte &0x02 \b, Packet Pad ##>2 byte &0x01 \b, Custom Flag ##>3 byte &0x08 \b, Copyrighted ##>3 byte &0x04 \b, Original Source ##>3 byte&0x03 1 \b, NR: 50/15 ms ##>3 byte&0x03 3 \b, NR: CCIT J.17 # MP3, M2A 0 beshort&0xFFFE 0xFFF2 MPEG ADTS, layer III, v2 !:mime audio/mpeg # rate >2 byte&0xF0 0x10 \b, 8 kbps >2 byte&0xF0 0x20 \b, 16 kbps >2 byte&0xF0 0x30 \b, 24 kbps >2 byte&0xF0 0x40 \b, 32 kbps >2 byte&0xF0 0x50 \b, 40 kbps >2 byte&0xF0 0x60 \b, 48 kbps >2 byte&0xF0 0x70 \b, 56 kbps >2 byte&0xF0 0x80 \b, 64 kbps >2 byte&0xF0 0x90 \b, 80 kbps >2 byte&0xF0 0xA0 \b, 96 kbps >2 byte&0xF0 0xB0 \b, 112 kbps >2 byte&0xF0 0xC0 \b, 128 kbps >2 byte&0xF0 0xD0 \b, 144 kbps >2 byte&0xF0 0xE0 \b, 160 kbps # timing >2 byte&0x0C 0x00 \b, 22.05 kHz >2 byte&0x0C 0x04 \b, 24 kHz >2 byte&0x0C 0x08 \b, 16 kHz # channels/options >3 byte&0xC0 0x00 \b, Stereo >3 byte&0xC0 0x40 \b, JntStereo >3 byte&0xC0 0x80 \b, 2x Monaural >3 byte&0xC0 0xC0 \b, Monaural #>1 byte ^0x01 \b, Data Verify #>2 byte &0x02 \b, Packet Pad #>2 byte &0x01 \b, Custom Flag #>3 byte &0x08 \b, Copyrighted #>3 byte &0x04 \b, Original Source #>3 byte&0x03 1 \b, NR: 50/15 ms #>3 byte&0x03 3 \b, NR: CCIT J.17 # MP2, M2A 0 beshort&0xFFFE 0xFFF4 MPEG ADTS, layer II, v2 !:mime audio/mpeg # rate >2 byte&0xF0 0x10 \b, 8 kbps >2 byte&0xF0 0x20 \b, 16 kbps >2 byte&0xF0 0x30 \b, 24 kbps >2 byte&0xF0 0x40 \b, 32 kbps >2 byte&0xF0 0x50 \b, 40 kbps >2 byte&0xF0 0x60 \b, 48 kbps >2 byte&0xF0 0x70 \b, 56 kbps >2 byte&0xF0 0x80 \b, 64 kbps >2 byte&0xF0 0x90 \b, 80 kbps >2 byte&0xF0 0xA0 \b, 96 kbps >2 byte&0xF0 0xB0 \b, 112 kbps >2 byte&0xF0 0xC0 \b, 128 kbps >2 byte&0xF0 0xD0 \b, 144 kbps >2 byte&0xF0 0xE0 \b, 160 kbps # timing >2 byte&0x0C 0x00 \b, 22.05 kHz >2 byte&0x0C 0x04 \b, 24 kHz >2 byte&0x0C 0x08 \b, 16 kHz # channels/options >3 byte&0xC0 0x00 \b, Stereo >3 byte&0xC0 0x40 \b, JntStereo >3 byte&0xC0 0x80 \b, 2x Monaural >3 byte&0xC0 0xC0 \b, Monaural #>1 byte ^0x01 \b, Data Verify #>2 byte &0x02 \b, Packet Pad #>2 byte &0x01 \b, Custom Flag #>3 byte &0x08 \b, Copyrighted #>3 byte &0x04 \b, Original Source #>3 byte&0x03 1 \b, NR: 50/15 ms #>3 byte&0x03 3 \b, NR: CCIT J.17 # MPA, M2A 0 beshort&0xFFFE 0xFFF6 MPEG ADTS, layer I, v2 !:mime audio/mpeg # rate >2 byte&0xF0 0x10 \b, 32 kbps >2 byte&0xF0 0x20 \b, 48 kbps >2 byte&0xF0 0x30 \b, 56 kbps >2 byte&0xF0 0x40 \b, 64 kbps >2 byte&0xF0 0x50 \b, 80 kbps >2 byte&0xF0 0x60 \b, 96 kbps >2 byte&0xF0 0x70 \b, 112 kbps >2 byte&0xF0 0x80 \b, 128 kbps >2 byte&0xF0 0x90 \b, 144 kbps >2 byte&0xF0 0xA0 \b, 160 kbps >2 byte&0xF0 0xB0 \b, 176 kbps >2 byte&0xF0 0xC0 \b, 192 kbps >2 byte&0xF0 0xD0 \b, 224 kbps >2 byte&0xF0 0xE0 \b, 256 kbps # timing >2 byte&0x0C 0x00 \b, 22.05 kHz >2 byte&0x0C 0x04 \b, 24 kHz >2 byte&0x0C 0x08 \b, 16 kHz # channels/options >3 byte&0xC0 0x00 \b, Stereo >3 byte&0xC0 0x40 \b, JntStereo >3 byte&0xC0 0x80 \b, 2x Monaural >3 byte&0xC0 0xC0 \b, Monaural #>1 byte ^0x01 \b, Data Verify #>2 byte &0x02 \b, Packet Pad #>2 byte &0x01 \b, Custom Flag #>3 byte &0x08 \b, Copyrighted #>3 byte &0x04 \b, Original Source #>3 byte&0x03 1 \b, NR: 50/15 ms #>3 byte&0x03 3 \b, NR: CCIT J.17 # MP3, M25A 0 beshort&0xFFFE 0xFFE2 MPEG ADTS, layer III, v2.5 !:mime audio/mpeg # rate >2 byte&0xF0 0x10 \b, 8 kbps >2 byte&0xF0 0x20 \b, 16 kbps >2 byte&0xF0 0x30 \b, 24 kbps >2 byte&0xF0 0x40 \b, 32 kbps >2 byte&0xF0 0x50 \b, 40 kbps >2 byte&0xF0 0x60 \b, 48 kbps >2 byte&0xF0 0x70 \b, 56 kbps >2 byte&0xF0 0x80 \b, 64 kbps >2 byte&0xF0 0x90 \b, 80 kbps >2 byte&0xF0 0xA0 \b, 96 kbps >2 byte&0xF0 0xB0 \b, 112 kbps >2 byte&0xF0 0xC0 \b, 128 kbps >2 byte&0xF0 0xD0 \b, 144 kbps >2 byte&0xF0 0xE0 \b, 160 kbps # timing >2 byte&0x0C 0x00 \b, 11.025 kHz >2 byte&0x0C 0x04 \b, 12 kHz >2 byte&0x0C 0x08 \b, 8 kHz # channels/options >3 byte&0xC0 0x00 \b, Stereo >3 byte&0xC0 0x40 \b, JntStereo >3 byte&0xC0 0x80 \b, 2x Monaural >3 byte&0xC0 0xC0 \b, Monaural #>1 byte ^0x01 \b, Data Verify #>2 byte &0x02 \b, Packet Pad #>2 byte &0x01 \b, Custom Flag #>3 byte &0x08 \b, Copyrighted #>3 byte &0x04 \b, Original Source #>3 byte&0x03 1 \b, NR: 50/15 ms #>3 byte&0x03 3 \b, NR: CCIT J.17 # AAC (aka MPEG-2 NBC audio) and MPEG-4 audio # Stored AAC streams (instead of the MP4 format) 0 string ADIF MPEG ADIF, AAC !:mime audio/x-hx-aac-adif >4 byte &0x80 >>13 byte &0x10 \b, VBR >>13 byte ^0x10 \b, CBR >>16 byte&0x1E 0x02 \b, single stream >>16 byte&0x1E 0x04 \b, 2 streams >>16 byte&0x1E 0x06 \b, 3 streams >>16 byte &0x08 \b, 4 or more streams >>16 byte &0x10 \b, 8 or more streams >>4 byte &0x80 \b, Copyrighted >>13 byte &0x40 \b, Original Source >>13 byte &0x20 \b, Home Flag >4 byte ^0x80 >>4 byte &0x10 \b, VBR >>4 byte ^0x10 \b, CBR >>7 byte&0x1E 0x02 \b, single stream >>7 byte&0x1E 0x04 \b, 2 streams >>7 byte&0x1E 0x06 \b, 3 streams >>7 byte &0x08 \b, 4 or more streams >>7 byte &0x10 \b, 8 or more streams >>4 byte &0x40 \b, Original Stream(s) >>4 byte &0x20 \b, Home Source # Live or stored single AAC stream (used with MPEG-2 systems) 0 beshort&0xFFF6 0xFFF0 MPEG ADTS, AAC !:mime audio/x-hx-aac-adts >1 byte &0x08 \b, v2 >1 byte ^0x08 \b, v4 # profile >>2 byte &0xC0 \b LTP >2 byte&0xc0 0x00 \b Main >2 byte&0xc0 0x40 \b LC >2 byte&0xc0 0x80 \b SSR # timing >2 byte&0x3c 0x00 \b, 96 kHz >2 byte&0x3c 0x04 \b, 88.2 kHz >2 byte&0x3c 0x08 \b, 64 kHz >2 byte&0x3c 0x0c \b, 48 kHz >2 byte&0x3c 0x10 \b, 44.1 kHz >2 byte&0x3c 0x14 \b, 32 kHz >2 byte&0x3c 0x18 \b, 24 kHz >2 byte&0x3c 0x1c \b, 22.05 kHz >2 byte&0x3c 0x20 \b, 16 kHz >2 byte&0x3c 0x24 \b, 12 kHz >2 byte&0x3c 0x28 \b, 11.025 kHz >2 byte&0x3c 0x2c \b, 8 kHz # channels >2 beshort&0x01c0 0x0040 \b, monaural >2 beshort&0x01c0 0x0080 \b, stereo >2 beshort&0x01c0 0x00c0 \b, stereo + center >2 beshort&0x01c0 0x0100 \b, stereo+center+LFE >2 beshort&0x01c0 0x0140 \b, surround >2 beshort&0x01c0 0x0180 \b, surround + LFE >2 beshort &0x01C0 \b, surround + side #>1 byte ^0x01 \b, Data Verify #>2 byte &0x02 \b, Custom Flag #>3 byte &0x20 \b, Original Stream #>3 byte &0x10 \b, Home Source #>3 byte &0x08 \b, Copyrighted # Live MPEG-4 audio streams (instead of RTP FlexMux) 0 beshort&0xFFE0 0x56E0 MPEG-4 LOAS !:mime audio/x-mp4a-latm #>1 beshort&0x1FFF x \b, %hu byte packet >3 byte&0xE0 0x40 >>4 byte&0x3C 0x04 \b, single stream >>4 byte&0x3C 0x08 \b, 2 streams >>4 byte&0x3C 0x0C \b, 3 streams >>4 byte &0x08 \b, 4 or more streams >>4 byte &0x20 \b, 8 or more streams >3 byte&0xC0 0 >>4 byte&0x78 0x08 \b, single stream >>4 byte&0x78 0x10 \b, 2 streams >>4 byte&0x78 0x18 \b, 3 streams >>4 byte &0x20 \b, 4 or more streams >>4 byte &0x40 \b, 8 or more streams # This magic isn't strong enough (matches plausible ISO-8859-1 text) #0 beshort 0x4DE1 MPEG-4 LO-EP audio stream #!:mime audio/x-mp4a-latm # Summary: FLI animation format # Created by: Daniel Quinlan # Modified by (1): Abel Cheung (avoid over-generic detection) 4 leshort 0xAF11 # standard FLI always has 320x200 resolution and 8 bit color >8 leshort 320 >>10 leshort 200 >>>12 leshort 8 FLI animation, 320x200x8 !:mime video/x-fli >>>>6 leshort x \b, %d frames # frame speed is multiple of 1/70s >>>>16 leshort x \b, %d/70s per frame # Summary: FLC animation format # Created by: Daniel Quinlan # Modified by (1): Abel Cheung (avoid over-generic detection) 4 leshort 0xAF12 # standard FLC always use 8 bit color >12 leshort 8 FLC animation !:mime video/x-flc >>8 leshort x \b, %d >>10 leshort x \bx%dx8 >>6 uleshort x \b, %d frames >>16 uleshort x \b, %dms per frame # DL animation format # XXX - collision with most `mips' magic # # I couldn't find a real magic number for these, however, this # -appears- to work. Note that it might catch other files, too, so be # careful! # # Note that title and author appear in the two 20-byte chunks # at decimal offsets 2 and 22, respectively, but they are XOR'ed with # 255 (hex FF)! The DL format is really bad. # #0 byte 1 DL version 1, medium format (160x100, 4 images/screen) #!:mime video/x-unknown #>42 byte x - %d screens, #>43 byte x %d commands #0 byte 2 DL version 2 #!:mime video/x-unknown #>1 byte 1 - large format (320x200,1 image/screen), #>1 byte 2 - medium format (160x100,4 images/screen), #>1 byte >2 - unknown format, #>42 byte x %d screens, #>43 byte x %d commands # Based on empirical evidence, DL version 3 have several nulls following the # \003. Most of them start with non-null values at hex offset 0x34 or so. #0 string \3\0\0\0\0\0\0\0\0\0\0\0 DL version 3 # iso 13818 transport stream # # from Oskar Schirmer Feb 3, 2001 (ISO 13818.1) # syncbyte 8 bit 0x47 # error_ind 1 bit - # payload_start 1 bit 1 # priority 1 bit - # PID 13 bit 0x0000 # scrambling 2 bit - # adaptfld_ctrl 2 bit 1 or 3 # conti_count 4 bit - 0 belong&0xFF5FFF10 0x47400010 >188 byte 0x47 MPEG transport stream data # DIF digital video file format 0 belong&0xffffff00 0x1f070000 DIF >4 byte &0x01 (DVCPRO) movie file >4 byte ^0x01 (DV) movie file >3 byte &0x80 (PAL) >3 byte ^0x80 (NTSC) # Microsoft Advanced Streaming Format (ASF) 0 belong 0x3026b275 Microsoft ASF !:mime video/x-ms-asf # MNG Video Format, 0 string \x8aMNG MNG video data, !:mime video/x-mng >4 belong !0x0d0a1a0a CORRUPTED, >4 belong 0x0d0a1a0a >>16 belong x %d x >>20 belong x %d # JNG Video Format, 0 string \x8bJNG JNG video data, !:mime video/x-jng >4 belong !0x0d0a1a0a CORRUPTED, >4 belong 0x0d0a1a0a >>16 belong x %d x >>20 belong x %d # Vivo video (Wolfram Kleff) 3 string \x0D\x0AVersion:Vivo Vivo video data # VRML (Virtual Reality Modelling Language) 0 string/w #VRML\ V1.0\ ascii VRML 1 file !:mime model/vrml 0 string/w #VRML\ V2.0\ utf8 ISO/IEC 14772 VRML 97 file !:mime model/vrml # X3D (Extensible 3D) [http://www.web3d.org/specifications/x3d-3.0.dtd] # From Michel Briand 0 string/t \20 search/1000/cw \, 2002-10-03 # 0 string HVQM4 %s >6 string >\0 v%s >0 byte x GameCube movie, >0x34 ubeshort x %d x >0x36 ubeshort x %d, >0x26 ubeshort x %dus, >0x42 ubeshort 0 no audio >0x42 ubeshort >0 %dHz audio # From: "Stefan A. Haubenthal" 0 string DVDVIDEO-VTS Video title set, >0x21 byte x v%x 0 string DVDVIDEO-VMG Video manager, >0x21 byte x v%x # From: Behan Webster # NuppelVideo used by Mythtv (*.nuv) # Note: there are two identical stanzas here differing only in the # initial string matched. It used to be done with a regex, but we're # trying to get rid of those. 0 string NuppelVideo MythTV NuppelVideo >12 string x v%s >20 lelong x (%d >24 lelong x \bx%d), >36 string P \bprogressive, >36 string I \binterlaced, >40 ledouble x \baspect:%.2f, >48 ledouble x \bfps:%.2f 0 string MythTV MythTV NuppelVideo >12 string x v%s >20 lelong x (%d >24 lelong x \bx%d), >36 string P \bprogressive, >36 string I \binterlaced, >40 ledouble x \baspect:%.2f, >48 ledouble x \bfps:%.2f # MPEG file # MPEG sequences # FIXME: This section is from the old magic.mime file and needs # integrating with the rest #0 belong 0x000001BA #>4 byte &0x40 #!:mime video/mp2p #>4 byte ^0x40 #!:mime video/mpeg #0 belong 0x000001BB #!:mime video/mpeg #0 belong 0x000001B0 #!:mime video/mp4v-es #0 belong 0x000001B5 #!:mime video/mp4v-es #0 belong 0x000001B3 #!:mime video/mpv #0 belong&0xFF5FFF10 0x47400010 #!:mime video/mp2t #0 belong 0x00000001 #>4 byte&0x1F 0x07 #!:mime video/h264 # Type: Bink Video # Extension: .bik # URL: http://wiki.multimedia.cx/index.php?title=Bink_Container # From: 2008-07-18 0 string BIK Bink Video >3 regex =[a-z] rev.%s #>4 ulelong x size %d >20 ulelong x \b, %d >24 ulelong x \bx%d >8 ulelong x \b, %d frames >32 ulelong x at rate %d/ >28 ulelong >1 \b%d >40 ulelong =0 \b, no audio >40 ulelong !0 \b, %d audio track >>40 ulelong !1 \bs # follow properties of the first audio track only >>48 uleshort x %dHz >>51 byte&0x20 0 mono >>51 byte&0x20 !0 stereo #>>51 byte&0x10 0 FFT #>>51 byte&0x10 !0 DCT # Type: NUT Container # URL: http://wiki.multimedia.cx/index.php?title=NUT # From: Adam Buchbinder 0 string nut/multimedia\ container\0 NUT multimedia container # Type: Nullsoft Video (NSV) # URL: http://wiki.multimedia.cx/index.php?title=Nullsoft_Video # From: Mike Melanson 0 string NSVf Nullsoft Video # Type: REDCode Video # URL: http://www.red.com/ ; http://wiki.multimedia.cx/index.php?title=REDCode # From: Mike Melanson 4 string RED1 REDCode Video # Type: MTV Multimedia File # URL: http://wiki.multimedia.cx/index.php?title=MTV # From: Mike Melanson 0 string AMVS MTV Multimedia File # Type: ARMovie # URL: http://wiki.multimedia.cx/index.php?title=ARMovie # From: Mike Melanson 0 string ARMovie\012 ARMovie # Type: Interplay MVE Movie # URL: http://wiki.multimedia.cx/index.php?title=Interplay_MVE # From: Mike Melanson 0 string Interplay\040MVE\040File\032 Interplay MVE Movie # Type: Windows Television DVR File # URL: http://wiki.multimedia.cx/index.php?title=WTV # From: Mike Melanson # This takes the form of a Windows-style GUID 0 bequad 0xB7D800203749DA11 >8 bequad 0xA64E0007E95EAD8D Windows Television DVR Media # Type: Sega FILM/CPK Multimedia # URL: http://wiki.multimedia.cx/index.php?title=Sega_FILM # From: Mike Melanson 0 string FILM Sega FILM/CPK Multimedia, >32 belong x %d x >28 belong x %d # Type: Nintendo THP Multimedia # URL: http://wiki.multimedia.cx/index.php?title=THP # From: Mike Melanson 0 string THP\0 Nintendo THP Multimedia # Type: BBC Dirac Video # URL: http://wiki.multimedia.cx/index.php?title=Dirac # From: Mike Melanson 0 string BBCD BBC Dirac Video # Type: RAD Game Tools Smacker Multimedia # URL: http://wiki.multimedia.cx/index.php?title=Smacker # From: Mike Melanson 0 string SMK RAD Game Tools Smacker Multimedia >3 byte x version %c, >4 lelong x %d x >8 lelong x %d, >12 lelong x %d frames #------------------------------------------------------------------------------ # $File$ # aout: file(1) magic for a.out executable/object/etc entries that # handle executables on multiple platforms. # # # Little-endian 32-bit-int a.out, merged from bsdi (for BSD/OS, from # BSDI), netbsd, and vax (for UNIX/32V and BSD) # # XXX - is there anything we can look at to distinguish BSD/OS 386 from # NetBSD 386 from various VAX binaries? The BSD/OS shared library flag # works only for binaries using shared libraries. Grabbing the entry # point from the a.out header, using it to find the first code executed # in the program, and looking at that might help. # 0 lelong 0407 a.out little-endian 32-bit executable >16 lelong >0 not stripped >32 byte 0x6a (uses BSD/OS shared libs) 0 lelong 0410 a.out little-endian 32-bit pure executable >16 lelong >0 not stripped >32 byte 0x6a (uses BSD/OS shared libs) 0 lelong 0413 a.out little-endian 32-bit demand paged pure executable >16 lelong >0 not stripped >32 byte 0x6a (uses BSD/OS shared libs) # # Big-endian 32-bit-int a.out, merged from sun (for old 68010 SunOS a.out), # mips (for old 68020(!) SGI a.out), and netbsd (for old big-endian a.out). # # XXX - is there anything we can look at to distinguish old SunOS 68010 # from old 68020 IRIX from old NetBSD? Again, I guess we could look at # the first instruction or instructions in the program. # 0 belong 0407 a.out big-endian 32-bit executable >16 belong >0 not stripped 0 belong 0410 a.out big-endian 32-bit pure executable >16 belong >0 not stripped 0 belong 0413 a.out big-endian 32-bit demand paged executable >16 belong >0 not stripped #------------------------------------------------------------------------------ # $File$ # apl: file(1) magic for APL (see also "pdp" and "vax" for other APL # workspaces) # 0 long 0100554 APL workspace (Ken's original?) #------------------------------------------------------------------------------ # $File: apple,v 1.28 2014/04/28 12:04:50 christos Exp $ # apple: file(1) magic for Apple file formats # 0 search/1/t FiLeStArTfIlEsTaRt binscii (apple ][) text 0 string \x0aGL Binary II (apple ][) data 0 string \x76\xff Squeezed (apple ][) data 0 string NuFile NuFile archive (apple ][) data 0 string N\xf5F\xe9l\xe5 NuFile archive (apple ][) data 0 belong 0x00051600 AppleSingle encoded Macintosh file 0 belong 0x00051607 AppleDouble encoded Macintosh file # Type: Apple Emulator 2IMG format # From: Radek Vokal 0 string 2IMG Apple ][ 2IMG Disk Image >4 string XGS! \b, XGS >4 string CTKG \b, Catakig >4 string ShIm \b, Sheppy's ImageMaker >4 string WOOF \b, Sweet 16 >4 string B2TR \b, Bernie ][ the Rescue >4 string !nfc \b, ASIMOV2 >4 string x \b, Unknown Format >0xc byte 00 \b, DOS 3.3 sector order >>0x10 byte 00 \b, Volume 254 >>0x10 byte&0x7f x \b, Volume %u >0xc byte 01 \b, ProDOS sector order >>0x14 short x \b, %u Blocks >0xc byte 02 \b, NIB data # magic for Newton PDA package formats # from Ruda Moura 0 string package0 Newton package, NOS 1.x, >12 belong &0x80000000 AutoRemove, >12 belong &0x40000000 CopyProtect, >12 belong &0x10000000 NoCompression, >12 belong &0x04000000 Relocation, >12 belong &0x02000000 UseFasterCompression, >16 belong x version %d 0 string package1 Newton package, NOS 2.x, >12 belong &0x80000000 AutoRemove, >12 belong &0x40000000 CopyProtect, >12 belong &0x10000000 NoCompression, >12 belong &0x04000000 Relocation, >12 belong &0x02000000 UseFasterCompression, >16 belong x version %d 0 string package4 Newton package, >8 byte 8 NOS 1.x, >8 byte 9 NOS 2.x, >12 belong &0x80000000 AutoRemove, >12 belong &0x40000000 CopyProtect, >12 belong &0x10000000 NoCompression, # The following entries for the Apple II are for files that have # been transferred as raw binary data from an Apple, without having # been encapsulated by any of the above archivers. # # In general, Apple II formats are hard to identify because Apple DOS # and especially Apple ProDOS have strong typing in the file system and # therefore programmers never felt much need to include type information # in the files themselves. # # Eric Fischer # AppleWorks word processor: # # This matches the standard tab stops for an AppleWorks file, but if # a file has a tab stop set in the first four columns this will fail. # # The "O" is really the magic number, but that's so common that it's # necessary to check the tab stops that follow it to avoid false positives. 4 string O==== AppleWorks word processor data >85 byte&0x01 >0 \b, zoomed >90 byte&0x01 >0 \b, paginated >92 byte&0x01 >0 \b, with mail merge #>91 byte x \b, left margin %d # AppleWorks database: # # This isn't really a magic number, but it's the closest thing to one # that I could find. The 1 and 2 really mean "order in which you defined # categories" and "left to right, top to bottom," respectively; the D and R # mean that the cursor should move either down or right when you press Return. #30 string \x01D AppleWorks database data #30 string \x02D AppleWorks database data #30 string \x01R AppleWorks database data #30 string \x02R AppleWorks database data # AppleWorks spreadsheet: # # Likewise, this isn't really meant as a magic number. The R or C means # row- or column-order recalculation; the A or M means automatic or manual # recalculation. #131 string RA AppleWorks spreadsheet data #131 string RM AppleWorks spreadsheet data #131 string CA AppleWorks spreadsheet data #131 string CM AppleWorks spreadsheet data # Applesoft BASIC: # # This is incredibly sloppy, but will be true if the program was # written at its usual memory location of 2048 and its first line # number is less than 256. Yuck. # update by Joerg Jenderek at Feb 2013 # GRR: this test is still too general as it catches also Gujin BOOT144.SYS (0xfa080000) #0 belong&0xff00ff 0x80000 Applesoft BASIC program data 0 belong&0x00ff00ff 0x00080000 # assuming that line number must be positive >2 leshort >0 Applesoft BASIC program data, first line number %d #>2 leshort x \b, first line number %d # ORCA/EZ assembler: # # This will not identify ORCA/M source files, since those have # some sort of date code instead of the two zero bytes at 6 and 7 # XXX Conflicts with ELF #4 belong&0xff00ffff 0x01000000 ORCA/EZ assembler source data #>5 byte x \b, build number %d # Broderbund Fantavision # # I don't know what these values really mean, but they seem to recur. # Will they cause too many conflicts? # Probably :-) #2 belong&0xFF00FF 0x040008 Fantavision movie data # Some attempts at images. # # These are actually just bit-for-bit dumps of the frame buffer, so # there's really no reasonably way to distinguish them except for their # address (if preserved) -- 8192 or 16384 -- and their length -- 8192 # or, occasionally, 8184. # # Nevertheless this will manage to catch a lot of images that happen # to have a solid-colored line at the bottom of the screen. # GRR: Magic too weak #8144 string \x7F\x7F\x7F\x7F\x7F\x7F\x7F\x7F Apple II image with white background #8144 string \x55\x2A\x55\x2A\x55\x2A\x55\x2A Apple II image with purple background #8144 string \x2A\x55\x2A\x55\x2A\x55\x2A\x55 Apple II image with green background #8144 string \xD5\xAA\xD5\xAA\xD5\xAA\xD5\xAA Apple II image with blue background #8144 string \xAA\xD5\xAA\xD5\xAA\xD5\xAA\xD5 Apple II image with orange background # Beagle Bros. Apple Mechanic fonts 0 belong&0xFF00FFFF 0x6400D000 Apple Mechanic font # Apple Universal Disk Image Format (UDIF) - dmg files. # From Johan Gade. # These entries are disabled for now until we fix the following issues. # # Note there might be some problems with the "VAX COFF executable" # entry. Note this entry should be placed before the mac filesystem section, # particularly the "Apple Partition data" entry. # # The intended meaning of these tests is, that the file is only of the # specified type if both of the lines are correct - i.e. if the first # line matches and the second doesn't then it is not of that type. # #0 long 0x7801730d #>4 long 0x62626060 UDIF read-only zlib-compressed image (UDZO) # # Note that this entry is recognized correctly by the "Apple Partition # data" entry - however since this entry is more specific - this # information seems to be more useful. #0 long 0x45520200 #>0x410 string disk\ image UDIF read/write image (UDRW) # From: Toby Peterson 0 string bplist00 Apple binary property list # Apple binary property list (bplist) # Assumes version bytes are hex. # Provides content hints for version 0 files. Assumes that the root # object is the first object (true for CoreFoundation implementation). # From: David Remahl 0 string bplist >6 byte x \bCoreFoundation binary property list data, version 0x%c >>7 byte x \b%c >6 string 00 \b >>8 byte&0xF0 0x00 \b >>>8 byte&0x0F 0x00 \b, root type: null >>>8 byte&0x0F 0x08 \b, root type: false boolean >>>8 byte&0x0F 0x09 \b, root type: true boolean >>8 byte&0xF0 0x10 \b, root type: integer >>8 byte&0xF0 0x20 \b, root type: real >>8 byte&0xF0 0x30 \b, root type: date >>8 byte&0xF0 0x40 \b, root type: data >>8 byte&0xF0 0x50 \b, root type: ascii string >>8 byte&0xF0 0x60 \b, root type: unicode string >>8 byte&0xF0 0x80 \b, root type: uid (CORRUPT) >>8 byte&0xF0 0xa0 \b, root type: array >>8 byte&0xF0 0xd0 \b, root type: dictionary # Apple/NeXT typedstream data # Serialization format used by NeXT and Apple for various # purposes in YellowStep/Cocoa, including some nib files. # From: David Remahl 2 string typedstream NeXT/Apple typedstream data, big endian >0 byte x \b, version %d >0 byte <5 \b >>13 byte 0x81 \b >>>14 ubeshort x \b, system %d 2 string streamtyped NeXT/Apple typedstream data, little endian >0 byte x \b, version %d >0 byte <5 \b >>13 byte 0x81 \b >>>14 uleshort x \b, system %d #------------------------------------------------------------------------------ # CAF: Apple CoreAudio File Format # # Container format for high-end audio purposes. # From: David Remahl # 0 string caff CoreAudio Format audio file >4 beshort <10 version %d >6 beshort x #------------------------------------------------------------------------------ # Keychain database files 0 string kych Mac OS X Keychain File #------------------------------------------------------------------------------ # Code Signing related file types 0 belong 0xfade0c00 Mac OS X Code Requirement >8 belong 1 (opExpr) >4 belong x - %d bytes 0 belong 0xfade0c01 Mac OS X Code Requirement Set >8 belong >1 containing %d items >4 belong x - %d bytes 0 belong 0xfade0c02 Mac OS X Code Directory >8 belong x version %x >12 belong >0 flags 0x%x >4 belong x - %d bytes 0 belong 0xfade0cc0 Mac OS X Detached Code Signature (non-executable) >4 belong x - %d bytes 0 belong 0xfade0cc1 Mac OS X Detached Code Signature >8 belong >1 (%d elements) >4 belong x - %d bytes # From: "Nelson A. de Oliveira" # .vdi 4 string innotek\ VirtualBox\ Disk\ Image %s # Apple disk partition stuff, strengthen the magic using byte 4 0 beshort 0x4552 >4 byte 0 Apple Driver Map >>2 beshort x \b, blocksize %d >>4 belong x \b, blockcount %d >>10 beshort x \b, devtype %d >>12 beshort x \b, devid %d >>20 beshort x \b, descriptors %d # Assume 8 partitions each at a multiple of the sector size. # We could glean this from the partition descriptors, but they are empty!?!? >>(2.S*1) indirect \b, contains[@0x%x]: >>(2.S*2) indirect \b, contains[@0x%x]: >>(2.S*3) indirect \b, contains[@0x%x]: >>(2.S*4) indirect \b, contains[@0x%x]: >>(2.S*5) indirect \b, contains[@0x%x]: >>(2.S*6) indirect \b, contains[@0x%x]: >>(2.S*7) indirect \b, contains[@0x%x]: >>(2.S*8) indirect \b, contains[@0x%x]: # Yes, the 3rd and 4th bytes are reserved, but we use them to make the # magic stronger. 0 belong 0x504d0000 Apple Partition Map >4 belong x \b, map block count %d >8 belong x \b, start block %d >12 belong x \b, block count %d >16 string >0 \b, name %s >48 string >0 \b, type %s >124 string >0 \b, processor %s >140 string >0 \b, boot arguments %s >92 belong & 1 \b, valid >92 belong & 2 \b, allocated >92 belong & 4 \b, in use >92 belong & 8 \b, has boot info >92 belong & 16 \b, readable >92 belong & 32 \b, writable >92 belong & 64 \b, pic boot code >92 belong & 128 \b, chain compatible driver >92 belong & 256 \b, real driver >92 belong & 512 \b, chain driver >92 belong & 1024 \b, mount at startup >92 belong & 2048 \b, is the startup partition #http://wiki.mozilla.org/DS_Store_File_Format` #http://en.wikipedia.org/wiki/.DS_Store 0 string \0\0\0\1Bud1\0 Apple Desktop Services Store #------------------------------------------------------------------------------ # $File$ # applix: file(1) magic for Applixware # From: Peter Soos # 0 string *BEGIN Applixware >7 string WORDS Words Document >7 string GRAPHICS Graphic >7 string RASTER Bitmap >7 string SPREADSHEETS Spreadsheet >7 string MACRO Macro >7 string BUILDER Builder Object #------------------------------------------------------------------------------ # $File: archive,v 1.87 2014/06/03 19:15:58 christos Exp $ # archive: file(1) magic for archive formats (see also "msdos" for self- # extracting compressed archives) # # cpio, ar, arc, arj, hpack, lha/lharc, rar, squish, uc2, zip, zoo, etc. # pre-POSIX "tar" archives are handled in the C code. # POSIX tar archives 257 string ustar\0 POSIX tar archive !:mime application/x-tar # encoding: posix 257 string ustar\040\040\0 GNU tar archive !:mime application/x-tar # encoding: gnu # Incremental snapshot gnu-tar format from: # http://www.gnu.org/software/tar/manual/html_node/Snapshot-Files.html 0 string GNU\ tar- GNU tar incremental snapshot data >&0 regex [0-9]\.[0-9]+-[0-9]+ version %s # cpio archives # # Yes, the top two "cpio archive" formats *are* supposed to just be "short". # The idea is to indicate archives produced on machines with the same # byte order as the machine running "file" with "cpio archive", and # to indicate archives produced on machines with the opposite byte order # from the machine running "file" with "byte-swapped cpio archive". # # The SVR4 "cpio(4)" hints that there are additional formats, but they # are defined as "short"s; I think all the new formats are # character-header formats and thus are strings, not numbers. 0 short 070707 cpio archive !:mime application/x-cpio 0 short 0143561 byte-swapped cpio archive !:mime application/x-cpio # encoding: swapped 0 string 070707 ASCII cpio archive (pre-SVR4 or odc) 0 string 070701 ASCII cpio archive (SVR4 with no CRC) 0 string 070702 ASCII cpio archive (SVR4 with CRC) # # Various archive formats used by various versions of the "ar" # command. # # # Original UNIX archive formats. # They were written with binary values in host byte order, and # the magic number was a host "int", which might have been 16 bits # or 32 bits. We don't say "PDP-11" or "VAX", as there might have # been ports to little-endian 16-bit-int or 32-bit-int platforms # (x86?) using some of those formats; if none existed, feel free # to use "PDP-11" for little-endian 16-bit and "VAX" for little-endian # 32-bit. There might have been big-endian ports of that sort as # well. # 0 leshort 0177555 very old 16-bit-int little-endian archive 0 beshort 0177555 very old 16-bit-int big-endian archive 0 lelong 0177555 very old 32-bit-int little-endian archive 0 belong 0177555 very old 32-bit-int big-endian archive 0 leshort 0177545 old 16-bit-int little-endian archive >2 string __.SYMDEF random library 0 beshort 0177545 old 16-bit-int big-endian archive >2 string __.SYMDEF random library 0 lelong 0177545 old 32-bit-int little-endian archive >4 string __.SYMDEF random library 0 belong 0177545 old 32-bit-int big-endian archive >4 string __.SYMDEF random library # # From "pdp" (but why a 4-byte quantity?) # 0 lelong 0x39bed PDP-11 old archive 0 lelong 0x39bee PDP-11 4.0 archive # # XXX - what flavor of APL used this, and was it a variant of # some ar archive format? It's similar to, but not the same # as, the APL workspace magic numbers in pdp. # 0 long 0100554 apl workspace # # System V Release 1 portable(?) archive format. # 0 string = System V Release 1 ar archive !:mime application/x-archive # # Debian package; it's in the portable archive format, and needs to go # before the entry for regular portable archives, as it's recognized as # a portable archive whose first member has a name beginning with # "debian". # 0 string =!\ndebian >8 string debian-split part of multipart Debian package !:mime application/vnd.debian.binary-package >8 string debian-binary Debian binary package !:mime application/vnd.debian.binary-package >8 string !debian >68 string >\0 (format %s) # These next two lines do not work, because a bzip2 Debian archive # still uses gzip for the control.tar (first in the archive). Only # data.tar varies, and the location of its filename varies too. # file/libmagic does not current have support for ascii-string based # (offsets) as of 2005-09-15. #>81 string bz2 \b, uses bzip2 compression #>84 string gz \b, uses gzip compression #>136 ledate x created: %s # # MIPS archive; they're in the portable archive format, and need to go # before the entry for regular portable archives, as it's recognized as # a portable archive whose first member has a name beginning with # "__________E". # 0 string =!\n__________E MIPS archive !:mime application/x-archive >20 string U with MIPS Ucode members >21 string L with MIPSEL members >21 string B with MIPSEB members >19 string L and an EL hash table >19 string B and an EB hash table >22 string X -- out of date 0 search/1 -h- Software Tools format archive text # # BSD/SVR2-and-later portable archive formats. # 0 string =! current ar archive !:mime application/x-archive >8 string __.SYMDEF random library >68 string __.SYMDEF\ SORTED random library # # "Thin" archive, as can be produced by GNU ar. # 0 string =!\n thin archive with >68 belong 0 no symbol entries >68 belong 1 %d symbol entry >68 belong >1 %d symbol entries # ARC archiver, from Daniel Quinlan (quinlan@yggdrasil.com) # # The first byte is the magic (0x1a), byte 2 is the compression type for # the first file (0x01 through 0x09), and bytes 3 to 15 are the MS-DOS # filename of the first file (null terminated). Since some types collide # we only test some types on basis of frequency: 0x08 (83%), 0x09 (5%), # 0x02 (5%), 0x03 (3%), 0x04 (2%), 0x06 (2%). 0x01 collides with terminfo. 0 lelong&0x8080ffff 0x0000081a ARC archive data, dynamic LZW !:mime application/x-arc 0 lelong&0x8080ffff 0x0000091a ARC archive data, squashed !:mime application/x-arc 0 lelong&0x8080ffff 0x0000021a ARC archive data, uncompressed !:mime application/x-arc 0 lelong&0x8080ffff 0x0000031a ARC archive data, packed !:mime application/x-arc 0 lelong&0x8080ffff 0x0000041a ARC archive data, squeezed !:mime application/x-arc 0 lelong&0x8080ffff 0x0000061a ARC archive data, crunched !:mime application/x-arc # [JW] stuff taken from idarc, obviously ARC successors: 0 lelong&0x8080ffff 0x00000a1a PAK archive data !:mime application/x-arc 0 lelong&0x8080ffff 0x0000141a ARC+ archive data !:mime application/x-arc 0 lelong&0x8080ffff 0x0000481a HYP archive data !:mime application/x-arc # Acorn archive formats (Disaster prone simpleton, m91dps@ecs.ox.ac.uk) # I can't create either SPARK or ArcFS archives so I have not tested this stuff # [GRR: the original entries collide with ARC, above; replaced with combined # version (not tested)] #0 byte 0x1a RISC OS archive (spark format) 0 string \032archive RISC OS archive (ArcFS format) 0 string Archive\000 RISC OS archive (ArcFS format) # All these were taken from idarc, many could not be verified. Unfortunately, # there were many low-quality sigs, i.e. easy to trigger false positives. # Please notify me of any real-world fishy/ambiguous signatures and I'll try # to get my hands on the actual archiver and see if I find something better. [JW] # probably many can be enhanced by finding some 0-byte or control char near the start # idarc calls this Crush/Uncompressed... *shrug* 0 string CRUSH Crush archive data # Squeeze It (.sqz) 0 string HLSQZ Squeeze It archive data # SQWEZ 0 string SQWEZ SQWEZ archive data # HPack (.hpk) 0 string HPAK HPack archive data # HAP 0 string \x91\x33HF HAP archive data # MD/MDCD 0 string MDmd MDCD archive data # LIM 0 string LIM\x1a LIM archive data # SAR 3 string LH5 SAR archive data # BSArc/BS2 0 string \212\3SB\020\0 BSArc/BS2 archive data # Bethesda Softworks Archive (Oblivion) 0 string BSA\0 BSArc archive data >4 lelong x version %d # MAR 2 string =-ah MAR archive data # ACB #0 belong&0x00f800ff 0x00800000 ACB archive data # CPZ # TODO, this is what idarc says: 0 string \0\0\0 CPZ archive data # JRC 0 string JRchive JRC archive data # Quantum 0 string DS\0 Quantum archive data # ReSOF 0 string PK\3\6 ReSOF archive data # QuArk 0 string 7\4 QuArk archive data # YAC 14 string YC YAC archive data # X1 0 string X1 X1 archive data 0 string XhDr X1 archive data # CDC Codec (.dqt) 0 belong&0xffffe000 0x76ff2000 CDC Codec archive data # AMGC 0 string \xad6" AMGC archive data # NuLIB 0 string N\xc3\xb5F\xc3\xa9lx\xc3\xa5 NuLIB archive data # PakLeo 0 string LEOLZW PAKLeo archive data # ChArc 0 string SChF ChArc archive data # PSA 0 string PSA PSA archive data # CrossePAC 0 string DSIGDCC CrossePAC archive data # Freeze 0 string \x1f\x9f\x4a\x10\x0a Freeze archive data # KBoom 0 string \xc2\xa8MP\xc2\xa8 KBoom archive data # NSQ, must go after CDC Codec 0 string \x76\xff NSQ archive data # DPA 0 string Dirk\ Paehl DPA archive data # BA # TODO: idarc says "bytes 0-2 == bytes 3-5" # TTComp 0 string \0\6 TTComp archive data # ESP, could this conflict with Easy Software Products' (e.g.ESP ghostscript) documentation? 0 string ESP ESP archive data # ZPack 0 string \1ZPK\1 ZPack archive data # Sky 0 string \xbc\x40 Sky archive data # UFA 0 string UFA UFA archive data # Dry 0 string =-H2O DRY archive data # FoxSQZ 0 string FOXSQZ FoxSQZ archive data # AR7 0 string ,AR7 AR7 archive data # PPMZ 0 string PPMZ PPMZ archive data # MS Compress 4 string \x88\xf0\x27 MS Compress archive data # updated by Joerg Jenderek >9 string \0 >>0 string KWAJ >>>7 string \321\003 MS Compress archive data >>>>14 ulong >0 \b, original size: %d bytes >>>>18 ubyte >0x65 >>>>>18 string x \b, was %.8s >>>>>(10.b-4) string x \b.%.3s # MP3 (archiver, not lossy audio compression) 0 string MP3\x1a MP3-Archiver archive data # ZET 0 string OZ\xc3\x9d ZET archive data # TSComp 0 string \x65\x5d\x13\x8c\x08\x01\x03\x00 TSComp archive data # ARQ 0 string gW\4\1 ARQ archive data # Squash 3 string OctSqu Squash archive data # Terse 0 string \5\1\1\0 Terse archive data # PUCrunch 0 string \x01\x08\x0b\x08\xef\x00\x9e\x32\x30\x36\x31 PUCrunch archive data # UHarc 0 string UHA UHarc archive data # ABComp 0 string \2AB ABComp archive data 0 string \3AB2 ABComp archive data # CMP 0 string CO\0 CMP archive data # Splint 0 string \x93\xb9\x06 Splint archive data # InstallShield 0 string \x13\x5d\x65\x8c InstallShield Z archive Data # Gather 1 string GTH Gather archive data # BOA 0 string BOA BOA archive data # RAX 0 string ULEB\xa RAX archive data # Xtreme 0 string ULEB\0 Xtreme archive data # Pack Magic 0 string @\xc3\xa2\1\0 Pack Magic archive data # BTS 0 belong&0xfeffffff 0x1a034465 BTS archive data # ELI 5750 0 string Ora\ ELI 5750 archive data # QFC 0 string \x1aFC\x1a QFC archive data 0 string \x1aQF\x1a QFC archive data # PRO-PACK 0 string RNC PRO-PACK archive data # 777 0 string 777 777 archive data # LZS221 0 string sTaC LZS221 archive data # HPA 0 string HPA HPA archive data # Arhangel 0 string LG Arhangel archive data # EXP1, uses bzip2 0 string 0123456789012345BZh EXP1 archive data # IMP 0 string IMP\xa IMP archive data # NRV 0 string \x00\x9E\x6E\x72\x76\xFF NRV archive data # Squish 0 string \x73\xb2\x90\xf4 Squish archive data # Par 0 string PHILIPP Par archive data 0 string PAR Par archive data # HIT 0 string UB HIT archive data # SBX 0 belong&0xfffff000 0x53423000 SBX archive data # NaShrink 0 string NSK NaShrink archive data # SAPCAR 0 string #\ CAR\ archive\ header SAPCAR archive data 0 string CAR\ 2.00RG SAPCAR archive data # Disintegrator 0 string DST Disintegrator archive data # ASD 0 string ASD ASD archive data # InstallShield CAB 0 string ISc( InstallShield CAB # TOP4 0 string T4\x1a TOP4 archive data # BatComp left out: sig looks like COM executable # so TODO: get real 4dos batcomp file and find sig # BlakHole 0 string BH\5\7 BlakHole archive data # BIX 0 string BIX0 BIX archive data # ChiefLZA 0 string ChfLZ ChiefLZA archive data # Blink 0 string Blink Blink archive data # Logitech Compress 0 string \xda\xfa Logitech Compress archive data # ARS-Sfx (FIXME: really a SFX? then goto COM/EXE) 1 string (C)\ STEPANYUK ARS-Sfx archive data # AKT/AKT32 0 string AKT32 AKT32 archive data 0 string AKT AKT archive data # NPack 0 string MSTSM NPack archive data # PFT 0 string \0\x50\0\x14 PFT archive data # SemOne 0 string SEM SemOne archive data # PPMD 0 string \x8f\xaf\xac\x84 PPMD archive data # FIZ 0 string FIZ FIZ archive data # MSXiE 0 belong&0xfffff0f0 0x4d530000 MSXiE archive data # DeepFreezer 0 belong&0xfffffff0 0x797a3030 DeepFreezer archive data # DC 0 string =2 byte x \b, version %i >3 byte x \b.%i # ZZip archiver (.zz) 0 string ZZ\ \0\0 ZZip archive data 0 string ZZ0 ZZip archive data # PAQ archiver (.paq) 0 string \xaa\x40\x5f\x77\x1f\xe5\x82\x0d PAQ archive data 0 string PAQ PAQ archive data >3 byte&0xf0 0x30 >>3 byte x (v%c) # JAR archiver (.j), this is the successor to ARJ, not Java's JAR (which is essentially ZIP) 0xe string \x1aJar\x1b JAR (ARJ Software, Inc.) archive data 0 string JARCS JAR (ARJ Software, Inc.) archive data # ARJ archiver (jason@jarthur.Claremont.EDU) 0 leshort 0xea60 ARJ archive data !:mime application/x-arj >5 byte x \b, v%d, >8 byte &0x04 multi-volume, >8 byte &0x10 slash-switched, >8 byte &0x20 backup, >34 string x original name: %s, >7 byte 0 os: MS-DOS >7 byte 1 os: PRIMOS >7 byte 2 os: Unix >7 byte 3 os: Amiga >7 byte 4 os: Macintosh >7 byte 5 os: OS/2 >7 byte 6 os: Apple ][ GS >7 byte 7 os: Atari ST >7 byte 8 os: NeXT >7 byte 9 os: VAX/VMS >3 byte >0 %d] # [JW] idarc says this is also possible 2 leshort 0xea60 ARJ archive data # HA archiver (Greg Roelofs, newt@uchicago.edu) # This is a really bad format. A file containing HAWAII will match this... #0 string HA HA archive data, #>2 leshort =1 1 file, #>2 leshort >1 %hu files, #>4 byte&0x0f =0 first is type CPY #>4 byte&0x0f =1 first is type ASC #>4 byte&0x0f =2 first is type HSC #>4 byte&0x0f =0x0e first is type DIR #>4 byte&0x0f =0x0f first is type SPECIAL # suggestion: at least identify small archives (<1024 files) 0 belong&0xffff00fc 0x48410000 HA archive data >2 leshort =1 1 file, >2 leshort >1 %u files, >4 byte&0x0f =0 first is type CPY >4 byte&0x0f =1 first is type ASC >4 byte&0x0f =2 first is type HSC >4 byte&0x0f =0x0e first is type DIR >4 byte&0x0f =0x0f first is type SPECIAL # HPACK archiver (Peter Gutmann, pgut1@cs.aukuni.ac.nz) 0 string HPAK HPACK archive data # JAM Archive volume format, by Dmitry.Kohmanyuk@UA.net 0 string \351,\001JAM\ JAM archive, >7 string >\0 version %.4s >0x26 byte =0x27 - >>0x2b string >\0 label %.11s, >>0x27 lelong x serial %08x, >>0x36 string >\0 fstype %.8s # LHARC/LHA archiver (Greg Roelofs, newt@uchicago.edu) 2 string -lh0- LHarc 1.x/ARX archive data [lh0] !:mime application/x-lharc 2 string -lh1- LHarc 1.x/ARX archive data [lh1] !:mime application/x-lharc 2 string -lz4- LHarc 1.x archive data [lz4] !:mime application/x-lharc 2 string -lz5- LHarc 1.x archive data [lz5] !:mime application/x-lharc # [never seen any but the last; -lh4- reported in comp.compression:] 2 string -lzs- LHa/LZS archive data [lzs] !:mime application/x-lha 2 string -lh\40- LHa 2.x? archive data [lh ] !:mime application/x-lha 2 string -lhd- LHa 2.x? archive data [lhd] !:mime application/x-lha 2 string -lh2- LHa 2.x? archive data [lh2] !:mime application/x-lha 2 string -lh3- LHa 2.x? archive data [lh3] !:mime application/x-lha 2 string -lh4- LHa (2.x) archive data [lh4] !:mime application/x-lha 2 string -lh5- LHa (2.x) archive data [lh5] !:mime application/x-lha 2 string -lh6- LHa (2.x) archive data [lh6] !:mime application/x-lha 2 string -lh7- LHa (2.x)/LHark archive data [lh7] !:mime application/x-lha >20 byte x - header level %d # taken from idarc [JW] 2 string -lZ PUT archive data 2 string -lz LZS archive data 2 string -sw1- Swag archive data # RAR archiver (Greg Roelofs, newt@uchicago.edu) 0 string Rar! RAR archive data, !:mime application/x-rar >44 byte x v%0x, >10 byte >0 flags: >>10 byte &0x01 Archive volume, >>10 byte &0x02 Commented, >>10 byte &0x04 Locked, >>10 byte &0x08 Solid, >>10 byte &0x20 Authenticated, >35 byte 0 os: MS-DOS >35 byte 1 os: OS/2 >35 byte 2 os: Win32 >35 byte 3 os: Unix # some old version? idarc says: 0 string RE\x7e\x5e RAR archive data # SQUISH archiver (Greg Roelofs, newt@uchicago.edu) 0 string SQSH squished archive data (Acorn RISCOS) # UC2 archiver (Greg Roelofs, newt@uchicago.edu) # [JW] see exe section for self-extracting version 0 string UC2\x1a UC2 archive data # PKZIP multi-volume archive 0 string PK\x07\x08PK\x03\x04 Zip multi-volume archive data, at least PKZIP v2.50 to extract !:mime application/zip # Zip archives (Greg Roelofs, c/o zip-bugs@wkuvx1.wku.edu) 0 string PK\005\006 Zip archive data (empty) 0 string PK\003\004 # Specialised zip formats which start with a member named 'mimetype' # (stored uncompressed, with no 'extra field') containing the file's MIME type. # Check for have 8-byte name, 0-byte extra field, name "mimetype", and # contents starting with "application/": >26 string \x8\0\0\0mimetypeapplication/ # KOffice / OpenOffice & StarOffice / OpenDocument formats # From: Abel Cheung # KOffice (1.2 or above) formats # (mimetype contains "application/vnd.kde.") >>50 string vnd.kde. KOffice (>=1.2) >>>58 string karbon Karbon document >>>58 string kchart KChart document >>>58 string kformula KFormula document >>>58 string kivio Kivio document >>>58 string kontour Kontour document >>>58 string kpresenter KPresenter document >>>58 string kspread KSpread document >>>58 string kword KWord document # OpenOffice formats (for OpenOffice 1.x / StarOffice 6/7) # (mimetype contains "application/vnd.sun.xml.") >>50 string vnd.sun.xml. OpenOffice.org 1.x >>>62 string writer Writer >>>>68 byte !0x2e document >>>>68 string .template template >>>>68 string .global global document >>>62 string calc Calc >>>>66 byte !0x2e spreadsheet >>>>66 string .template template >>>62 string draw Draw >>>>66 byte !0x2e document >>>>66 string .template template >>>62 string impress Impress >>>>69 byte !0x2e presentation >>>>69 string .template template >>>62 string math Math document >>>62 string base Database file # OpenDocument formats (for OpenOffice 2.x / StarOffice >= 8) # http://lists.oasis-open.org/archives/office/200505/msg00006.html # (mimetype contains "application/vnd.oasis.opendocument.") >>50 string vnd.oasis.opendocument. OpenDocument >>>73 string text >>>>77 byte !0x2d Text !:mime application/vnd.oasis.opendocument.text >>>>77 string -template Text Template !:mime application/vnd.oasis.opendocument.text-template >>>>77 string -web HTML Document Template !:mime application/vnd.oasis.opendocument.text-web >>>>77 string -master Master Document !:mime application/vnd.oasis.opendocument.text-master >>>73 string graphics >>>>81 byte !0x2d Drawing !:mime application/vnd.oasis.opendocument.graphics >>>>81 string -template Template !:mime application/vnd.oasis.opendocument.graphics-template >>>73 string presentation >>>>85 byte !0x2d Presentation !:mime application/vnd.oasis.opendocument.presentation >>>>85 string -template Template !:mime application/vnd.oasis.opendocument.presentation-template >>>73 string spreadsheet >>>>84 byte !0x2d Spreadsheet !:mime application/vnd.oasis.opendocument.spreadsheet >>>>84 string -template Template !:mime application/vnd.oasis.opendocument.spreadsheet-template >>>73 string chart >>>>78 byte !0x2d Chart !:mime application/vnd.oasis.opendocument.chart >>>>78 string -template Template !:mime application/vnd.oasis.opendocument.chart-template >>>73 string formula >>>>80 byte !0x2d Formula !:mime application/vnd.oasis.opendocument.formula >>>>80 string -template Template !:mime application/vnd.oasis.opendocument.formula-template >>>73 string database Database !:mime application/vnd.oasis.opendocument.database >>>73 string image >>>>78 byte !0x2d Image !:mime application/vnd.oasis.opendocument.image >>>>78 string -template Template !:mime application/vnd.oasis.opendocument.image-template # EPUB (OEBPS) books using OCF (OEBPS Container Format) # http://www.idpf.org/ocf/ocf1.0/download/ocf10.htm, section 4. # From: Ralf Brown >>50 string epub+zip EPUB document !:mime application/epub+zip # Catch other ZIP-with-mimetype formats # In a ZIP file, the bytes immediately after a member's contents are # always "PK". The 2 regex rules here print the "mimetype" member's # contents up to the first 'P'. Luckily, most MIME types don't contain # any capital 'P's. This is a kludge. # (mimetype contains "application/") >>50 string !epub+zip >>>50 string !vnd.oasis.opendocument. >>>>50 string !vnd.sun.xml. >>>>>50 string !vnd.kde. >>>>>>38 regex [!-OQ-~]+ Zip data (MIME type "%s"?) !:mime application/zip # (mimetype contents other than "application/*") >26 string \x8\0\0\0mimetype >>38 string !application/ >>>38 regex [!-OQ-~]+ Zip data (MIME type "%s"?) !:mime application/zip # Java Jar files >(26.s+30) leshort 0xcafe Java archive data (JAR) !:mime application/java-archive # Generic zip archives (Greg Roelofs, c/o zip-bugs@wkuvx1.wku.edu) # Next line excludes specialized formats: >(26.s+30) leshort !0xcafe >>26 string !\x8\0\0\0mimetype Zip archive data !:mime application/zip >>>4 byte 0x09 \b, at least v0.9 to extract >>>4 byte 0x0a \b, at least v1.0 to extract >>>4 byte 0x0b \b, at least v1.1 to extract >>>4 byte 0x14 \b, at least v2.0 to extract >>>4 byte 0x2d \b, at least v3.0 to extract >>>0x161 string WINZIP \b, WinZIP self-extracting # StarView Metafile # From Pierre Ducroquet 0 string VCLMTF StarView MetaFile >6 beshort x \b, version %d >8 belong x \b, size %d # Zoo archiver 20 lelong 0xfdc4a7dc Zoo archive data !:mime application/x-zoo >4 byte >48 \b, v%c. >>6 byte >47 \b%c >>>7 byte >47 \b%c >32 byte >0 \b, modify: v%d >>33 byte x \b.%d+ >42 lelong 0xfdc4a7dc \b, >>70 byte >0 extract: v%d >>>71 byte x \b.%d+ # Shell archives 10 string #\ This\ is\ a\ shell\ archive shell archive text !:mime application/octet-stream # # LBR. NB: May conflict with the questionable # "binary Computer Graphics Metafile" format. # 0 string \0\ \ \ \ \ \ \ \ \ \ \ \0\0 LBR archive data # # PMA (CP/M derivative of LHA) # 2 string -pm0- PMarc archive data [pm0] 2 string -pm1- PMarc archive data [pm1] 2 string -pm2- PMarc archive data [pm2] 2 string -pms- PMarc SFX archive (CP/M, DOS) 5 string -pc1- PopCom compressed executable (CP/M) # From Rafael Laboissiere # The Project Revision Control System (see # http://prcs.sourceforge.net) generates a packaged project # file which is recognized by the following entry: 0 leshort 0xeb81 PRCS packaged project # Microsoft cabinets # by David Necas (Yeti) #0 string MSCF\0\0\0\0 Microsoft cabinet file data, #>25 byte x v%d #>24 byte x \b.%d # MPi: All CABs have version 1.3, so this is pointless. # Better magic in debian-additions. # GTKtalog catalogs # by David Necas (Yeti) 4 string gtktalog\ GTKtalog catalog data, >13 string 3 version 3 >>14 beshort 0x677a (gzipped) >>14 beshort !0x677a (not gzipped) >13 string >3 version %s ############################################################################ # Parity archive reconstruction file, the 'par' file format now used on Usenet. 0 string PAR\0 PARity archive data >48 leshort =0 - Index file >48 leshort >0 - file number %d # Felix von Leitner 0 string d8:announce BitTorrent file !:mime application/x-bittorrent # Atari MSA archive - Teemu Hukkanen 0 beshort 0x0e0f Atari MSA archive data >2 beshort x \b, %d sectors per track >4 beshort 0 \b, 1 sided >4 beshort 1 \b, 2 sided >6 beshort x \b, starting track: %d >8 beshort x \b, ending track: %d # Alternate ZIP string (amc@arwen.cs.berkeley.edu) 0 string PK00PK\003\004 Zip archive data # ACE archive (from http://www.wotsit.org/download.asp?f=ace) # by Stefan `Sec` Zehl 7 string **ACE** ACE archive data >15 byte >0 version %d >16 byte =0x00 \b, from MS-DOS >16 byte =0x01 \b, from OS/2 >16 byte =0x02 \b, from Win/32 >16 byte =0x03 \b, from Unix >16 byte =0x04 \b, from MacOS >16 byte =0x05 \b, from WinNT >16 byte =0x06 \b, from Primos >16 byte =0x07 \b, from AppleGS >16 byte =0x08 \b, from Atari >16 byte =0x09 \b, from Vax/VMS >16 byte =0x0A \b, from Amiga >16 byte =0x0B \b, from Next >14 byte x \b, version %d to extract >5 leshort &0x0080 \b, multiple volumes, >>17 byte x \b (part %d), >5 leshort &0x0002 \b, contains comment >5 leshort &0x0200 \b, sfx >5 leshort &0x0400 \b, small dictionary >5 leshort &0x0800 \b, multi-volume >5 leshort &0x1000 \b, contains AV-String >>30 string \x16*UNREGISTERED\x20VERSION* (unregistered) >5 leshort &0x2000 \b, with recovery record >5 leshort &0x4000 \b, locked >5 leshort &0x8000 \b, solid # Date in MS-DOS format (whatever that is) #>18 lelong x Created on # sfArk : compression program for Soundfonts (sf2) by Dirk Jagdmann # 0x1A string sfArk sfArk compressed Soundfont >0x15 string 2 >>0x1 string >\0 Version %s >>0x2A string >\0 : %s # DR-DOS 7.03 Packed File *.??_ 0 string Packed\ File\ Personal NetWare Packed File >12 string x \b, was "%.12s" # EET archive # From: Tilman Sauerbeck 0 belong 0x1ee7ff00 EET archive !:mime application/x-eet # rzip archives 0 string RZIP rzip compressed data >4 byte x - version %d >5 byte x \b.%d >6 belong x (%d bytes) # From: "Robert Dale" 0 belong 123 dar archive, >4 belong x label "%.8x >>8 belong x %.8x >>>12 beshort x %.4x" >14 byte 0x54 end slice >14 beshort 0x4e4e multi-part >14 beshort 0x4e53 multi-part, with -S # Symbian installation files # http://www.thouky.co.uk/software/psifs/sis.html # http://developer.symbian.com/main/downloads/papers/SymbianOSv91/softwareinstallsis.pdf 8 lelong 0x10000419 Symbian installation file !:mime application/vnd.symbian.install >4 lelong 0x1000006D (EPOC release 3/4/5) >4 lelong 0x10003A12 (EPOC release 6) 0 lelong 0x10201A7A Symbian installation file (Symbian OS 9.x) !:mime x-epoc/x-sisx-app # From "Nelson A. de Oliveira" 0 string MPQ\032 MoPaQ (MPQ) archive # From: Dirk Jagdmann # xar archive format: http://code.google.com/p/xar/ 0 string xar! xar archive >6 beshort x - version %d # From: "Nelson A. de Oliveira" # .kgb 0 string KGB_arch KGB Archiver file >10 string x with compression level %.1s # xar (eXtensible ARchiver) archive # From: "David Remahl" 0 string xar! xar archive #>4 beshort x header size %d >6 beshort x version %d, #>8 quad x compressed TOC: %d, #>16 quad x uncompressed TOC: %d, >24 belong 0 no checksum >24 belong 1 SHA-1 checksum >24 belong 2 MD5 checksum # Type: Parity Archive # From: Daniel van Eeden 0 string PAR2 Parity Archive Volume Set # Bacula volume format. (Volumes always start with a block header.) # URL: http://bacula.org/3.0.x-manuals/en/developers/developers/Block_Header.html # From: Adam Buchbinder 12 string BB02 Bacula volume >20 bedate x \b, started %s # ePub is XHTML + XML inside a ZIP archive. The first member of the # archive must be an uncompressed file called 'mimetype' with contents # 'application/epub+zip' # From: "Michael Gorny" # ZPAQ: http://mattmahoney.net/dc/zpaq.html 0 string zPQ ZPAQ stream >3 byte x \b, level %d # BBeB ebook, unencrypted (LRF format) # URL: http://www.sven.de/librie/Librie/LrfFormat # From: Adam Buchbinder 0 string L\0R\0F\0\0\0 BBeB ebook data, unencrypted >8 beshort x \b, version %d >36 byte 1 \b, front-to-back >36 byte 16 \b, back-to-front >42 beshort x \b, (%dx, >44 beshort x %d) # Symantec GHOST image by Joerg Jenderek at May 2014 # http://us.norton.com/ghost/ # http://www.garykessler.net/library/file_sigs.html 0 ubelong&0xFFFFf7f0 0xFEEF0100 Norton GHost image # *.GHO >2 ubyte&0x08 0x00 \b, first file # *.GHS or *.[0-9] with cns program option >2 ubyte&0x08 0x08 \b, split file # part of split index interesting for *.ghs >>4 ubyte x id=0x%x # compression tag minus one equals numeric compression command line switch z[1-9] >3 ubyte 0 \b, no compression >3 ubyte 2 \b, fast compression (Z1) >3 ubyte 3 \b, medium compression (Z2) >3 ubyte >3 >>3 ubyte <11 \b, compression (Z%d-1) >2 ubyte&0x08 0x00 # ~ 30 byte password field only for *.gho >>12 ubequad !0 \b, password protected >>44 ubyte !1 # 1~Image All, sector-by-sector only for *.gho >>>10 ubyte 1 \b, sector copy # 1~Image Boot track only for *.gho >>>43 ubyte 1 \b, boot track # 1~Image Disc only for *.gho implies Image Boot track and sector copy >>44 ubyte 1 \b, disc sector copy # optional image description only *.gho >>0xff string >\0 "%-.254s" # look for DOS sector end sequence >0xE08 search/7776 \x55\xAA >>&-512 indirect x \b; contains #------------------------------------------------------------------------------ # $File: assembler,v 1.5 2013/09/17 17:33:36 christos Exp $ # make: file(1) magic for assembler source # 0 regex \^[\040\t]{0,50}\\.asciiz assembler source text !:mime text/x-asm 0 regex \^[\040\t]{0,50}\\.byte assembler source text !:mime text/x-asm 0 regex \^[\040\t]{0,50}\\.even assembler source text !:mime text/x-asm 0 regex \^[\040\t]{0,50}\\.globl assembler source text !:mime text/x-asm 0 regex \^[\040\t]{0,50}\\.text assembler source text !:mime text/x-asm 0 regex \^[\040\t]{0,50}\\.file assembler source text !:mime text/x-asm 0 regex \^[\040\t]{0,50}\\.type assembler source text !:mime text/x-asm #------------------------------------------------------------------------------ # $File$ # asterix: file(1) magic for Aster*x; SunOS 5.5.1 gave the 4-character # strings as "long" - we assume they're just strings: # From: guy@netapp.com (Guy Harris) # 0 string *STA Aster*x >7 string WORD Words Document >7 string GRAP Graphic >7 string SPRE Spreadsheet >7 string MACR Macro 0 string 2278 Aster*x Version 2 >29 byte 0x36 Words Document >29 byte 0x35 Graphic >29 byte 0x32 Spreadsheet >29 byte 0x38 Macro #------------------------------------------------------------------------------ # $File: att3b,v 1.8 2009/09/19 16:28:08 christos Exp $ # att3b: file(1) magic for AT&T 3B machines # # The `versions' should be un-commented if they work for you. # (Was the problem just one of endianness?) # # 3B20 # # The 3B20 conflicts with SCCS. #0 beshort 0550 3b20 COFF executable #>12 belong >0 not stripped #>22 beshort >0 - version %d #0 beshort 0551 3b20 COFF executable (TV) #>12 belong >0 not stripped #>22 beshort >0 - version %d # # WE32K # 0 beshort 0560 WE32000 COFF >18 beshort ^00000020 object >18 beshort &00000020 executable >12 belong >0 not stripped >18 beshort ^00010000 N/A on 3b2/300 w/paging >18 beshort &00020000 32100 required >18 beshort &00040000 and MAU hardware required >20 beshort 0407 (impure) >20 beshort 0410 (pure) >20 beshort 0413 (demand paged) >20 beshort 0443 (target shared library) >22 beshort >0 - version %d 0 beshort 0561 WE32000 COFF executable (TV) >12 belong >0 not stripped #>18 beshort &00020000 - 32100 required #>18 beshort &00040000 and MAU hardware required #>22 beshort >0 - version %d # # core file for 3b2 0 string \000\004\036\212\200 3b2 core file >364 string >\0 of '%s' #------------------------------------------------------------------------------ # $File: audio,v 1.71 2014/05/14 23:30:28 christos Exp $ # audio: file(1) magic for sound formats (see also "iff") # # Jan Nicolai Langfeldt (janl@ifi.uio.no), Dan Quinlan (quinlan@yggdrasil.com), # and others # # Sun/NeXT audio data 0 string .snd Sun/NeXT audio data: >12 belong 1 8-bit ISDN mu-law, !:mime audio/basic >12 belong 2 8-bit linear PCM [REF-PCM], !:mime audio/basic >12 belong 3 16-bit linear PCM, !:mime audio/basic >12 belong 4 24-bit linear PCM, !:mime audio/basic >12 belong 5 32-bit linear PCM, !:mime audio/basic >12 belong 6 32-bit IEEE floating point, !:mime audio/basic >12 belong 7 64-bit IEEE floating point, !:mime audio/basic >12 belong 8 Fragmented sample data, >12 belong 10 DSP program, >12 belong 11 8-bit fixed point, >12 belong 12 16-bit fixed point, >12 belong 13 24-bit fixed point, >12 belong 14 32-bit fixed point, >12 belong 18 16-bit linear with emphasis, >12 belong 19 16-bit linear compressed, >12 belong 20 16-bit linear with emphasis and compression, >12 belong 21 Music kit DSP commands, >12 belong 23 8-bit ISDN mu-law compressed (CCITT G.721 ADPCM voice enc.), !:mime audio/x-adpcm >12 belong 24 compressed (8-bit CCITT G.722 ADPCM) >12 belong 25 compressed (3-bit CCITT G.723.3 ADPCM), >12 belong 26 compressed (5-bit CCITT G.723.5 ADPCM), >12 belong 27 8-bit A-law (CCITT G.711), >20 belong 1 mono, >20 belong 2 stereo, >20 belong 4 quad, >16 belong >0 %d Hz # DEC systems (e.g. DECstation 5000) use a variant of the Sun/NeXT format # that uses little-endian encoding and has a different magic number 0 lelong 0x0064732E DEC audio data: >12 lelong 1 8-bit ISDN mu-law, !:mime audio/x-dec-basic >12 lelong 2 8-bit linear PCM [REF-PCM], !:mime audio/x-dec-basic >12 lelong 3 16-bit linear PCM, !:mime audio/x-dec-basic >12 lelong 4 24-bit linear PCM, !:mime audio/x-dec-basic >12 lelong 5 32-bit linear PCM, !:mime audio/x-dec-basic >12 lelong 6 32-bit IEEE floating point, !:mime audio/x-dec-basic >12 lelong 7 64-bit IEEE floating point, !:mime audio/x-dec-basic >12 belong 8 Fragmented sample data, >12 belong 10 DSP program, >12 belong 11 8-bit fixed point, >12 belong 12 16-bit fixed point, >12 belong 13 24-bit fixed point, >12 belong 14 32-bit fixed point, >12 belong 18 16-bit linear with emphasis, >12 belong 19 16-bit linear compressed, >12 belong 20 16-bit linear with emphasis and compression, >12 belong 21 Music kit DSP commands, >12 lelong 23 8-bit ISDN mu-law compressed (CCITT G.721 ADPCM voice enc.), !:mime audio/x-dec-basic >12 belong 24 compressed (8-bit CCITT G.722 ADPCM) >12 belong 25 compressed (3-bit CCITT G.723.3 ADPCM), >12 belong 26 compressed (5-bit CCITT G.723.5 ADPCM), >12 belong 27 8-bit A-law (CCITT G.711), >20 lelong 1 mono, >20 lelong 2 stereo, >20 lelong 4 quad, >16 lelong >0 %d Hz # Creative Labs AUDIO stuff 0 string MThd Standard MIDI data !:mime audio/midi >8 beshort x (format %d) >10 beshort x using %d track >10 beshort >1 \bs >12 beshort&0x7fff x at 1/%d >12 beshort&0x8000 >0 SMPTE 0 string CTMF Creative Music (CMF) data !:mime audio/x-unknown 0 string SBI SoundBlaster instrument data !:mime audio/x-unknown 0 string Creative\ Voice\ File Creative Labs voice data !:mime audio/x-unknown # is this next line right? it came this way... >19 byte 0x1A >23 byte >0 - version %d >22 byte >0 \b.%d # first entry is also the string "NTRK" 0 belong 0x4e54524b MultiTrack sound data >4 belong x - version %d # Extended MOD format (*.emd) (Greg Roelofs, newt@uchicago.edu); NOT TESTED # [based on posting 940824 by "Dirk/Elastik", husberg@lehtori.cc.tut.fi] 0 string EMOD Extended MOD sound data, >4 byte&0xf0 x version %d >4 byte&0x0f x \b.%d, >45 byte x %d instruments >83 byte 0 (module) >83 byte 1 (song) # Real Audio (Magic .ra\0375) 0 belong 0x2e7261fd RealAudio sound file !:mime audio/x-pn-realaudio 0 string .RMF\0\0\0 RealMedia file !:mime application/vnd.rn-realmedia #video/x-pn-realvideo #video/vnd.rn-realvideo #application/vnd.rn-realmedia # sigh, there are many mimes for that but the above are the most common. # MTM/669/FAR/S3M/ULT/XM format checking [Aaron Eppert, aeppert@dialin.ind.net] # Oct 31, 1995 # fixed by 2003-06-24 # Too short... #0 string MTM MultiTracker Module sound file #0 string if Composer 669 Module sound data #0 string JN Composer 669 Module sound data (extended format) 0 string MAS_U ULT(imate) Module sound data #0 string FAR Module sound data #>4 string >\15 Title: "%s" 0x2c string SCRM ScreamTracker III Module sound data >0 string >\0 Title: "%s" # Gravis UltraSound patches # From 0 string GF1PATCH110\0ID#000002\0 GUS patch 0 string GF1PATCH100\0ID#000002\0 Old GUS patch # mime types according to http://www.geocities.com/nevilo/mod.htm: # audio/it .it # audio/x-zipped-it .itz # audio/xm fasttracker modules # audio/x-s3m screamtracker modules # audio/s3m screamtracker modules # audio/x-zipped-mod mdz # audio/mod mod # audio/x-mod All modules (mod, s3m, 669, mtm, med, xm, it, mdz, stm, itz, xmz, s3z) # # Taken from loader code from mikmod version 2.14 # by Steve McIntyre (stevem@chiark.greenend.org.uk) # added title printing on 2003-06-24 0 string MAS_UTrack_V00 >14 string >/0 ultratracker V1.%.1s module sound data !:mime audio/x-mod #audio/x-tracker-module 0 string UN05 MikMod UNI format module sound data 0 string Extended\ Module: Fasttracker II module sound data !:mime audio/x-mod #audio/x-tracker-module >17 string >\0 Title: "%s" 21 string/c =!SCREAM! Screamtracker 2 module sound data !:mime audio/x-mod #audio/x-screamtracker-module 21 string BMOD2STM Screamtracker 2 module sound data !:mime audio/x-mod #audio/x-screamtracker-module 1080 string M.K. 4-channel Protracker module sound data !:mime audio/x-mod #audio/x-protracker-module >0 string >\0 Title: "%s" 1080 string M!K! 4-channel Protracker module sound data !:mime audio/x-mod #audio/x-protracker-module >0 string >\0 Title: "%s" 1080 string FLT4 4-channel Startracker module sound data !:mime audio/x-mod #audio/x-startracker-module >0 string >\0 Title: "%s" 1080 string FLT8 8-channel Startracker module sound data !:mime audio/x-mod #audio/x-startracker-module >0 string >\0 Title: "%s" 1080 string 4CHN 4-channel Fasttracker module sound data !:mime audio/x-mod #audio/x-fasttracker-module >0 string >\0 Title: "%s" 1080 string 6CHN 6-channel Fasttracker module sound data !:mime audio/x-mod #audio/x-fasttracker-module >0 string >\0 Title: "%s" 1080 string 8CHN 8-channel Fasttracker module sound data !:mime audio/x-mod #audio/x-fasttracker-module >0 string >\0 Title: "%s" 1080 string CD81 8-channel Octalyser module sound data !:mime audio/x-mod #audio/x-octalysertracker-module >0 string >\0 Title: "%s" 1080 string OKTA 8-channel Octalyzer module sound data !:mime audio/x-mod #audio/x-octalysertracker-module >0 string >\0 Title: "%s" # Not good enough. #1082 string CH #>1080 string >/0 %.2s-channel Fasttracker "oktalyzer" module sound data 1080 string 16CN 16-channel Taketracker module sound data !:mime audio/x-mod #audio/x-taketracker-module >0 string >\0 Title: "%s" 1080 string 32CN 32-channel Taketracker module sound data !:mime audio/x-mod #audio/x-taketracker-module >0 string >\0 Title: "%s" # TOC sound files -Trevor Johnson # 0 string TOC TOC sound file # sidfiles # added name,author,(c) and new RSID type by 2003-06-24 0 string SIDPLAY\ INFOFILE Sidplay info file 0 string PSID PlaySID v2.2+ (AMIGA) sidtune >4 beshort >0 w/ header v%d, >14 beshort =1 single song, >14 beshort >1 %d songs, >16 beshort >0 default song: %d >0x16 string >\0 name: "%s" >0x36 string >\0 author: "%s" >0x56 string >\0 copyright: "%s" 0 string RSID RSID sidtune PlaySID compatible >4 beshort >0 w/ header v%d, >14 beshort =1 single song, >14 beshort >1 %d songs, >16 beshort >0 default song: %d >0x16 string >\0 name: "%s" >0x36 string >\0 author: "%s" >0x56 string >\0 copyright: "%s" # IRCAM sound files - Michael Pruett # http://www-mmsp.ece.mcgill.ca/documents/AudioFormats/IRCAM/IRCAM.html 0 belong 0x64a30100 IRCAM file (VAX little-endian) 0 belong 0x0001a364 IRCAM file (VAX big-endian) 0 belong 0x64a30200 IRCAM file (Sun big-endian) 0 belong 0x0002a364 IRCAM file (Sun little-endian) 0 belong 0x64a30300 IRCAM file (MIPS little-endian) 0 belong 0x0003a364 IRCAM file (MIPS big-endian) 0 belong 0x64a30400 IRCAM file (NeXT big-endian) 0 belong 0x64a30400 IRCAM file (NeXT big-endian) 0 belong 0x0004a364 IRCAM file (NeXT little-endian) # NIST SPHERE 0 string NIST_1A\n\ \ \ 1024\n NIST SPHERE file # Sample Vision 0 string SOUND\ SAMPLE\ DATA\ Sample Vision file # Audio Visual Research 0 string 2BIT Audio Visual Research file, >12 beshort =0 mono, >12 beshort =-1 stereo, >14 beshort x %d bits >16 beshort =0 unsigned, >16 beshort =-1 signed, >22 belong&0x00ffffff x %d Hz, >18 beshort =0 no loop, >18 beshort =-1 loop, >21 ubyte <128 note %d, >22 byte =0 replay 5.485 KHz >22 byte =1 replay 8.084 KHz >22 byte =2 replay 10.971 KHz >22 byte =3 replay 16.168 KHz >22 byte =4 replay 21.942 KHz >22 byte =5 replay 32.336 KHz >22 byte =6 replay 43.885 KHz >22 byte =7 replay 47.261 KHz # SGI SoundTrack 0 string _SGI_SoundTrack SGI SoundTrack project file # ID3 version 2 tags 0 string ID3 Audio file with ID3 version 2 >3 byte x \b.%d >4 byte x \b.%d >>5 byte &0x80 \b, unsynchronized frames >>5 byte &0x40 \b, extended header >>5 byte &0x20 \b, experimental >>5 byte &0x10 \b, footer present >(6.I+10) indirect x \b, contains: # NSF (NES sound file) magic 0 string NESM\x1a NES Sound File >14 string >\0 ("%s" by >46 string >\0 %s, copyright >78 string >\0 %s), >5 byte x version %d, >6 byte x %d tracks, >122 byte&0x2 =1 dual PAL/NTSC >122 byte&0x1 =1 PAL >122 byte&0x1 =0 NTSC # Type: SNES SPC700 sound files # From: Josh Triplett 0 string SNES-SPC700\ Sound\ File\ Data\ v SNES SPC700 sound file >&0 string 0.30 \b, version %s >>0x23 byte 0x1B \b, without ID666 tag >>0x23 byte 0x1A \b, with ID666 tag >>>0x2E string >\0 \b, song "%.32s" >>>0x4E string >\0 \b, game "%.32s" # Impulse tracker module (audio/x-it) 0 string IMPM Impulse Tracker module sound data - !:mime audio/x-mod >4 string >\0 "%s" >40 leshort !0 compatible w/ITv%x >42 leshort !0 created w/ITv%x # Imago Orpheus module (audio/x-imf) 60 string IM10 Imago Orpheus module sound data - >0 string >\0 "%s" # From # These are the /etc/magic entries to decode modules, instruments, and # samples in Impulse Tracker's native format. 0 string IMPS Impulse Tracker Sample >18 byte &2 16 bit >18 byte ^2 8 bit >18 byte &4 stereo >18 byte ^4 mono 0 string IMPI Impulse Tracker Instrument >28 leshort !0 ITv%x >30 byte !0 %d samples # Yamaha TX Wave: file(1) magic for Yamaha TX Wave audio files # From 0 string LM8953 Yamaha TX Wave >22 byte 0x49 looped >22 byte 0xC9 non-looped >23 byte 1 33kHz >23 byte 2 50kHz >23 byte 3 16kHz # scream tracker: file(1) magic for Scream Tracker sample files # # From 76 string SCRS Scream Tracker Sample >0 byte 1 sample >0 byte 2 adlib melody >0 byte >2 adlib drum >31 byte &2 stereo >31 byte ^2 mono >31 byte &4 16bit little endian >31 byte ^4 8bit >30 byte 0 unpacked >30 byte 1 packed # audio # From: Cory Dikkers 0 string MMD0 MED music file, version 0 0 string MMD1 OctaMED Pro music file, version 1 0 string MMD3 OctaMED Soundstudio music file, version 3 0 string OctaMEDCmpr OctaMED Soundstudio compressed file 0 string MED MED_Song 0 string SymM Symphonie SymMOD music file # 0 string THX AHX version >3 byte =0 1 module data >3 byte =1 2 module data # 0 string OKTASONG Oktalyzer module data # 0 string DIGI\ Booster\ module\0 %s >20 byte >0 %c >>21 byte >0 \b%c >>>22 byte >0 \b%c >>>>23 byte >0 \b%c >610 string >\0 \b, "%s" # 0 string DBM0 DIGI Booster Pro Module >4 byte >0 V%X. >>5 byte x \b%02X >16 string >\0 \b, "%s" # 0 string FTMN FaceTheMusic module >16 string >\0d \b, "%s" # From: 2003-06-24 0 string AMShdr\32 Velvet Studio AMS Module v2.2 0 string Extreme Extreme Tracker AMS Module v1.3 0 string DDMF Xtracker DMF Module >4 byte x v%i >0xD string >\0 Title: "%s" >0x2B string >\0 Composer: "%s" 0 string DSM\32 Dynamic Studio Module DSM 0 string SONG DigiTrekker DTM Module 0 string DMDL DigiTrakker MDL Module 0 string PSM\32 Protracker Studio PSM Module 44 string PTMF Poly Tracker PTM Module >0 string >\32 Title: "%s" 0 string MT20 MadTracker 2.0 Module MT2 0 string RAD\40by\40REALiTY!! RAD Adlib Tracker Module RAD 0 string RTMM RTM Module 0x426 string MaDoKaN96 XMS Adlib Module >0 string >\0 Composer: "%s" 0 string AMF AMF Module >4 string >\0 Title: "%s" 0 string MODINFO1 Open Cubic Player Module Inforation MDZ 0 string Extended\40Instrument: Fast Tracker II Instrument # From: Takeshi Hamasaki # NOA Nancy Codec file 0 string \210NOA\015\012\032 NOA Nancy Codec Movie file # Yamaha SMAF format 0 string MMMD Yamaha SMAF file # Sharp Jisaku Melody format for PDC 0 string \001Sharp\040JisakuMelody SHARP Cell-Phone ringing Melody >20 string Ver01.00 Ver. 1.00 >>32 byte x , %d tracks # Free lossless audio codec # From: Przemyslaw Augustyniak 0 string fLaC FLAC audio bitstream data !:mime audio/x-flac >4 byte&0x7f >0 \b, unknown version >4 byte&0x7f 0 \b # some common bits/sample values >>20 beshort&0x1f0 0x030 \b, 4 bit >>20 beshort&0x1f0 0x050 \b, 6 bit >>20 beshort&0x1f0 0x070 \b, 8 bit >>20 beshort&0x1f0 0x0b0 \b, 12 bit >>20 beshort&0x1f0 0x0f0 \b, 16 bit >>20 beshort&0x1f0 0x170 \b, 24 bit >>20 byte&0xe 0x0 \b, mono >>20 byte&0xe 0x2 \b, stereo >>20 byte&0xe 0x4 \b, 3 channels >>20 byte&0xe 0x6 \b, 4 channels >>20 byte&0xe 0x8 \b, 5 channels >>20 byte&0xe 0xa \b, 6 channels >>20 byte&0xe 0xc \b, 7 channels >>20 byte&0xe 0xe \b, 8 channels # some common sample rates >>17 belong&0xfffff0 0x0ac440 \b, 44.1 kHz >>17 belong&0xfffff0 0x0bb800 \b, 48 kHz >>17 belong&0xfffff0 0x07d000 \b, 32 kHz >>17 belong&0xfffff0 0x056220 \b, 22.05 kHz >>17 belong&0xfffff0 0x05dc00 \b, 24 kHz >>17 belong&0xfffff0 0x03e800 \b, 16 kHz >>17 belong&0xfffff0 0x02b110 \b, 11.025 kHz >>17 belong&0xfffff0 0x02ee00 \b, 12 kHz >>17 belong&0xfffff0 0x01f400 \b, 8 kHz >>17 belong&0xfffff0 0x177000 \b, 96 kHz >>17 belong&0xfffff0 0x0fa000 \b, 64 kHz >>21 byte&0xf >0 \b, >4G samples >>21 byte&0xf 0 \b >>>22 belong >0 \b, %u samples >>>22 belong 0 \b, length unknown # (ISDN) VBOX voice message file (Wolfram Kleff) 0 string VBOX VBOX voice message data # ReBorn Song Files (.rbs) # David J. Singer 8 string RB40 RBS Song file >29 string ReBorn created by ReBorn >37 string Propellerhead created by ReBirth # Synthesizer Generator and Kimwitu share their file format 0 string A#S#C#S#S#L#V#3 Synthesizer Generator or Kimwitu data # Kimwitu++ uses a slightly different magic 0 string A#S#C#S#S#L#HUB Kimwitu++ data # From "Simon Hosie 0 string TFMX-SONG TFMX module sound data # Monkey's Audio compressed audio format (.ape) # From danny.milo@gmx.net (Danny Milosavljevic) # New version from Abel Cheung 0 string MAC\040 Monkey's Audio compressed format !:mime audio/x-ape >4 uleshort >0x0F8B version %d >>(0x08.l) uleshort =1000 with fast compression >>(0x08.l) uleshort =2000 with normal compression >>(0x08.l) uleshort =3000 with high compression >>(0x08.l) uleshort =4000 with extra high compression >>(0x08.l) uleshort =5000 with insane compression >>(0x08.l+18) uleshort =1 \b, mono >>(0x08.l+18) uleshort =2 \b, stereo >>(0x08.l+20) ulelong x \b, sample rate %d >4 uleshort <0x0F8C version %d >>6 uleshort =1000 with fast compression >>6 uleshort =2000 with normal compression >>6 uleshort =3000 with high compression >>6 uleshort =4000 with extra high compression >>6 uleshort =5000 with insane compression >>10 uleshort =1 \b, mono >>10 uleshort =2 \b, stereo >>12 ulelong x \b, sample rate %d # adlib sound files # From Gurkan Sengun , http://www.linuks.mine.nu 0 string RAWADATA RdosPlay RAW 1068 string RoR AMUSIC Adlib Tracker 0 string JCH EdLib 0 string mpu401tr MPU-401 Trakker 0 string SAdT Surprise! Adlib Tracker >4 byte x Version %d 0 string XAD! eXotic ADlib 0 string ofTAZ! eXtra Simple Music # Spectrum 128 tunes (.ay files). # From: Emanuel Haupt 0 string ZXAYEMUL Spectrum 128 tune 0 string \0BONK BONK, #>5 byte x version %d >14 byte x %d channel(s), >15 byte =1 lossless, >15 byte =0 lossy, >16 byte x mid-side 384 string LockStream LockStream Embedded file (mostly MP3 on old Nokia phones) # format VQF (proprietary codec for sound) # some infos on the header file available at : # http://www.twinvq.org/english/technology_format.html 0 string TWIN97012000 VQF data >27 short 0 \b, Mono >27 short 1 \b, Stereo >31 short >0 \b, %d kbit/s >35 short >0 \b, %d kHz # Nelson A. de Oliveira (naoliv@gmail.com) # .eqf 0 string Winamp\ EQ\ library\ file %s # it will match only versions like v. # Since I saw only eqf files with version v1.1 I think that it's OK >23 string x \b%.4s # .preset 0 string [Equalizer\ preset] XMMS equalizer preset # .m3u 0 search/1 #EXTM3U M3U playlist text # .pls 0 search/1 [playlist] PLS playlist text # licq.conf 1 string [licq] LICQ configuration file # Atari ST audio files by Dirk Jagdmann 0 string ICE! SNDH Atari ST music 0 string SC68\ Music-file\ /\ (c)\ (BeN)jami sc68 Atari ST music # musepak support From: "Jiri Pejchal" 0 string MP+ Musepack audio !:mime audio/x-musepack >3 byte 255 \b, SV pre8 >3 byte&0xF 0x6 \b, SV 6 >3 byte&0xF 0x8 \b, SV 8 >3 byte&0xF 0x7 \b, SV 7 >>3 byte&0xF0 0x0 \b.0 >>3 byte&0xF0 0x10 \b.1 >>3 byte&0xF0 240 \b.15 >>10 byte&0xF0 0x0 \b, no profile >>10 byte&0xF0 0x10 \b, profile 'Unstable/Experimental' >>10 byte&0xF0 0x50 \b, quality 0 >>10 byte&0xF0 0x60 \b, quality 1 >>10 byte&0xF0 0x70 \b, quality 2 (Telephone) >>10 byte&0xF0 0x80 \b, quality 3 (Thumb) >>10 byte&0xF0 0x90 \b, quality 4 (Radio) >>10 byte&0xF0 0xA0 \b, quality 5 (Standard) >>10 byte&0xF0 0xB0 \b, quality 6 (Xtreme) >>10 byte&0xF0 0xC0 \b, quality 7 (Insane) >>10 byte&0xF0 0xD0 \b, quality 8 (BrainDead) >>10 byte&0xF0 0xE0 \b, quality 9 >>10 byte&0xF0 0xF0 \b, quality 10 >>27 byte 0x0 \b, Buschmann 1.7.0-9, Klemm 0.90-1.05 >>27 byte 102 \b, Beta 1.02 >>27 byte 104 \b, Beta 1.04 >>27 byte 105 \b, Alpha 1.05 >>27 byte 106 \b, Beta 1.06 >>27 byte 110 \b, Release 1.1 >>27 byte 111 \b, Alpha 1.11 >>27 byte 112 \b, Beta 1.12 >>27 byte 113 \b, Alpha 1.13 >>27 byte 114 \b, Beta 1.14 >>27 byte 115 \b, Alpha 1.15 # IMY # from http://filext.com/detaillist.php?extdetail=IMY # http://cellphones.about.com/od/cellularfaqs/f/rf_imelody.htm # http://download.ncl.ie/doc/api/ie/ncl/media/music/IMelody.html # http://www.wx800.com/msg/download/irda/iMelody.pdf 0 string BEGIN:IMELODY iMelody Ringtone Format # From: "Mateus Caruccio" # guitar pro v3,4,5 from http://filext.com/file-extension/gp3 0 string \030FICHIER\ GUITAR\ PRO\ v3. Guitar Pro Ver. 3 Tablature # From: "Leslie P. Polzer" 60 string SONG SoundFX Module sound file # Type: Adaptive Multi-Rate Codec # URL: http://filext.com/detaillist.php?extdetail=AMR # From: Russell Coker 0 string #!AMR Adaptive Multi-Rate Codec (GSM telephony) # Type: SuperCollider 3 Synth Definition File Format # From: Mario Lang 0 string SCgf SuperCollider3 Synth Definition file, >4 belong x version %d # Type: True Audio Lossless Audio # URL: http://wiki.multimedia.cx/index.php?title=True_Audio # From: Mike Melanson 0 string TTA1 True Audio Lossless Audio # Type: WavPack Lossless Audio # URL: http://wiki.multimedia.cx/index.php?title=WavPack # From: Mike Melanson 0 string wvpk WavPack Lossless Audio # From Fabio R. Schmidlin # VGM music file 0 string Vgm\ >9 ubyte >0 VGM Video Game Music dump v >>9 ubyte/16 >0 \b%d >>9 ubyte&0x0F x \b%d >>8 ubyte/16 x \b.%d >>8 ubyte&0x0F >0 \b%d #Get soundchips >>8 ubyte x \b, soundchip(s)= >>0x0C ulelong >0 SN76489, >>0x10 ulelong >0 YM2413, >>0x2C ulelong >0 YM2612, >>0x30 ulelong >0 YM2151, >>0x38 ulelong >0 Sega PCM, >>0x34 ulelong >0xC >>>0x40 ulelong >0 RF5C68, >>0x34 ulelong >0x10 >>>0x44 ulelong >0 YM2203, >>0x34 ulelong >0x14 >>>0x48 ulelong >0 YM2608, >>0x34 ulelong >0x18 >>>0x4C lelong >0 YM2610, >>>0x4C lelong <0 YM2610B, >>0x34 ulelong >0x1C >>>0x50 ulelong >0 YM3812, >>0x34 ulelong >0x20 >>>0x54 ulelong >0 YM3526, >>0x34 ulelong >0x24 >>>0x58 ulelong >0 Y8950, >>0x34 ulelong >0x28 >>>0x5C ulelong >0 YMF262, >>0x34 ulelong >0x2C >>>0x60 ulelong >0 YMF278B, >>0x34 ulelong >0x30 >>>0x64 ulelong >0 YMF271, >>0x34 ulelong >0x34 >>>0x68 ulelong >0 YMZ280B, >>0x34 ulelong >0x38 >>>0x6C ulelong >0 RF5C164, >>0x34 ulelong >0x3C >>>0x70 ulelong >0 PWM, >>0x34 ulelong >0x40 >>>0x74 ulelong >0 >>>>0x78 ubyte 0x00 AY-3-8910, >>>>0x78 ubyte 0x01 AY-3-8912, >>>>0x78 ubyte 0x02 AY-3-8913, >>>>0x78 ubyte 0x03 AY-3-8930, >>>>0x78 ubyte 0x10 YM2149, >>>>0x78 ubyte 0x11 YM3439, # GVOX Encore file format # Since this is a proprietary file format and there is no publicly available # format specification, this is just based on induction # 0 string SCOW >4 byte 0xc4 GVOX Encore music, version 5.0 or above >4 byte 0xc2 GVOX Encore music, version < 5.0 0 string ZBOT >4 byte 0xc5 GVOX Encore music, version < 5.0 #---------------------------------------------------------------- # $File$ # basis: file(1) magic for BBx/Pro5-files # Oliver Dammer 2005/11/07 # http://www.basis.com business-basic-files. # 0 string \074\074bbx\076\076 BBx >7 string \000 indexed file >7 string \001 serial file >7 string \002 keyed file >>13 short 0 (sort) >7 string \004 program >>18 byte x (LEVEL %d) >>>23 string >\000 psaved >7 string \006 mkeyed file >>13 short 0 (sort) >>8 string \000 (mkey) #------------------------------------------------------------------------------ # $File: bflt,v 1.4 2009/09/19 16:28:08 christos Exp $ # bFLT: file(1) magic for BFLT uclinux binary files # # From Philippe De Muyter # 0 string bFLT BFLT executable >4 belong x - version %d >4 belong 4 >>36 belong&0x1 0x1 ram >>36 belong&0x2 0x2 gotpic >>36 belong&0x4 0x4 gzip >>36 belong&0x8 0x8 gzdata #------------------------------------------------------------------------------ # $File: apple,v 1.27 2013/03/09 22:36:00 christos Exp $ # blackberry: file(1) magic for BlackBerry file formats # 5 belong 0 >8 belong 010010010 BlackBerry RIM ETP file >>22 string x \b for %s # Berkeley Lab Checkpoint Restart (BLCR) checkpoint context files # http://ftg.lbl.gov/checkpoint 0 string C\0\0\0R\0\0\0 BLCR >16 lelong 1 x86 >16 lelong 3 alpha >16 lelong 5 x86-64 >16 lelong 7 ARM >8 lelong x context data (little endian, version %d) # Uncomment the following only of your "file" program supports "search" #>0 search/1024 VMA\06 for kernel #>>&1 byte x %d. #>>&2 byte x %d. #>>&3 byte x %d 0 string \0\0\0C\0\0\0R BLCR >16 belong 2 SPARC >16 belong 4 ppc >16 belong 6 ppc64 >16 belong 7 ARMEB >16 belong 8 SPARC64 >8 belong x context data (big endian, version %d) # Uncomment the following only of your "file" program supports "search" #>0 search/1024 VMA\06 for kernel #>>&1 byte x %d. #>>&2 byte x \b%d. #>>&3 byte x \b%d #------------------------------------------------------------------------------ # $File: blender,v 1.5 2009/09/19 16:28:08 christos Exp $ # blender: file(1) magic for Blender 3D related files # # Native format rule v1.2. For questions use the developers list # http://lists.blender.org/mailman/listinfo/bf-committers # GLOB chunk was moved near start and provides subversion info since 2.42 0 string =BLENDER Blender3D, >7 string =_ saved as 32-bits >>8 string =v little endian >>>9 byte x with version %c. >>>10 byte x \b%c >>>11 byte x \b%c >>>0x40 string =GLOB \b. >>>>0x58 leshort x \b%.4d >>8 string =V big endian >>>9 byte x with version %c. >>>10 byte x \b%c >>>11 byte x \b%c >>>0x40 string =GLOB \b. >>>>0x58 beshort x \b%.4d >7 string =- saved as 64-bits >>8 string =v little endian >>9 byte x with version %c. >>10 byte x \b%c >>11 byte x \b%c >>0x44 string =GLOB \b. >>>0x60 leshort x \b%.4d >>8 string =V big endian >>>9 byte x with version %c. >>>10 byte x \b%c >>>11 byte x \b%c >>>0x44 string =GLOB \b. >>>>0x60 beshort x \b%.4d # Scripts that run in the embedded Python interpreter 0 string #!BPY Blender3D BPython script #------------------------------------------------------------------------------ # $File$ # blit: file(1) magic for 68K Blit stuff as seen from 680x0 machine # # Note that this 0407 conflicts with several other a.out formats... # # XXX - should this be redone with "be" and "le", so that it works on # little-endian machines as well? If so, what's the deal with # "VAX-order" and "VAX-order2"? # #0 long 0407 68K Blit (standalone) executable #0 short 0407 VAX-order2 68K Blit (standalone) executable 0 short 03401 VAX-order 68K Blit (standalone) executable 0 long 0406 68k Blit mpx/mux executable 0 short 0406 VAX-order2 68k Blit mpx/mux executable 0 short 03001 VAX-order 68k Blit mpx/mux executable # Need more values for WE32 DMD executables. # Note that 0520 is the same as COFF #0 short 0520 tty630 layers executable #------------------------------------------------------------------------------ # $File$ # i80960 b.out objects and archives # 0 long 0x10d i960 b.out relocatable object >16 long >0 not stripped # # b.out archive (hp-rt on i960) 0 string =! b.out archive >8 string __.SYMDEF random library #------------------------------------------------------------------------------ # $File: bsdi,v 1.6 2013/01/09 22:37:24 christos Exp $ # bsdi: file(1) magic for BSD/OS (from BSDI) objects # Some object/executable formats use the same magic numbers as are used # in other OSes; those are handled by entries in aout. # 0 lelong 0314 386 compact demand paged pure executable >16 lelong >0 not stripped >32 byte 0x6a (uses shared libs) # same as in SunOS 4.x, except for static shared libraries 0 belong&077777777 0600413 SPARC demand paged >0 byte &0x80 >>20 belong <4096 shared library >>20 belong =4096 dynamically linked executable >>20 belong >4096 dynamically linked executable >0 byte ^0x80 executable >16 belong >0 not stripped >36 belong 0xb4100001 (uses shared libs) 0 belong&077777777 0600410 SPARC pure >0 byte &0x80 dynamically linked executable >0 byte ^0x80 executable >16 belong >0 not stripped >36 belong 0xb4100001 (uses shared libs) 0 belong&077777777 0600407 SPARC >0 byte &0x80 dynamically linked executable >0 byte ^0x80 executable >16 belong >0 not stripped >36 belong 0xb4100001 (uses shared libs) # Chiasmus is a encryption standard developed by the German Federal # Office for Information Security (Bundesamt fuer Sicherheit in der # Informationstechnik). # Extension: .xia 0 string XIA1 Chiasmus encrypted data # Extension: .xis 0 string XIS Chiasmus key #------------------------------------------------------------------------------ # $File$ # BTSnoop: file(1) magic for BTSnoop files # # From 0 string btsnoop\0 BTSnoop >8 belong x version %d, >12 belong 1001 Unencapsulated HCI >12 belong 1002 HCI UART (H4) >12 belong 1003 HCI BCSP >12 belong 1004 HCI Serial (H5) >>12 belong x type %d #------------------------------------------------------------------------------ # $File$ # c64: file(1) magic for various commodore 64 related files # # From: Dirk Jagdmann 0x16500 belong 0x12014100 D64 Image 0x16500 belong 0x12014180 D71 Image 0x61800 belong 0x28034400 D81 Image 0 string C64\40CARTRIDGE CCS C64 Emultar Cartridge Image 0 belong 0x43154164 X64 Image 0 string GCR-1541 GCR Image >8 byte x version: %i >9 byte x tracks: %i 9 string PSUR ARC archive (c64) 2 string -LH1- LHA archive (c64) 0 string C64File PC64 Emulator file >8 string >\0 "%s" 0 string C64Image PC64 Freezer Image 0 beshort 0x38CD C64 PCLink Image 0 string CBM\144\0\0 Power 64 C64 Emulator Snapshot 0 belong 0xFF424CFF WRAptor packer (c64) 0 string C64S\x20tape\x20file T64 tape Image >32 leshort x Version:0x%x >36 leshort !0 Entries:%i >40 string x Name:%.24s 0 string C64\x20tape\x20image\x20file\x0\x0\x0\x0\x0\x0\x0\x0\x0\x0\x0\x0 T64 tape Image >32 leshort x Version:0x%x >36 leshort !0 Entries:%i >40 string x Name:%.24s 0 string C64S\x20tape\x20image\x20file\x0\x0\x0\x0\x0\x0\x0\x0\x0\x0\x0 T64 tape Image >32 leshort x Version:0x%x >36 leshort !0 Entries:%i >40 string x Name:%.24s #------------------------------------------------------------------------------ # $File: cad,v 1.12 2013/07/04 15:24:37 christos Exp $ # autocad: file(1) magic for cad files # # Microstation DGN/CIT Files (www.bentley.com) # Last updated July 29, 2005 by Lester Hightower # DGN is the default file extension of Microstation/Intergraph CAD files. # CIT is the proprietary raster format (similar to TIFF) used to attach # raster underlays to Microstation DGN (vector) drawings. # # http://www.wotsit.org/search.asp # http://filext.com/detaillist.php?extdetail=DGN # http://filext.com/detaillist.php?extdetail=CIT # # http://www.bentley.com/products/default.cfm?objectid=97F351F5-9C35-4E5E-89C2 # 3F86C928&method=display&p_objectid=97F351F5-9C35-4E5E-89C280A93F86C928 # http://www.bentley.com/products/default.cfm?objectid=A5C2FD43-3AC9-4C71-B682 # 721C479F&method=display&p_objectid=A5C2FD43-3AC9-4C71-B682C7BE721C479F 0 string \010\011\376 Microstation >3 string \002 >>30 string \026\105 DGNFile >>30 string \034\105 DGNFile >>30 string \073\107 DGNFile >>30 string \073\110 DGNFile >>30 string \106\107 DGNFile >>30 string \110\103 DGNFile >>30 string \120\104 DGNFile >>30 string \172\104 DGNFile >>30 string \172\105 DGNFile >>30 string \172\106 DGNFile >>30 string \234\106 DGNFile >>30 string \273\105 DGNFile >>30 string \306\106 DGNFile >>30 string \310\104 DGNFile >>30 string \341\104 DGNFile >>30 string \372\103 DGNFile >>30 string \372\104 DGNFile >>30 string \372\106 DGNFile >>30 string \376\103 DGNFile >4 string \030\000\000 CITFile >4 string \030\000\003 CITFile # AutoCAD # Merge of the different contributions and updates from http://en.wikipedia.org/wiki/Dwg # and http://www.iana.org/assignments/media-types/image/vnd.dwg 0 string MC0.0 DWG AutoDesk AutoCAD Release 1.0 !:mime image/vnd.dwg 0 string AC1.2 DWG AutoDesk AutoCAD Release 1.2 !:mime image/vnd.dwg 0 string AC1.3 DWG AutoDesk AutoCAD Release 1.3 !:mime image/vnd.dwg 0 string AC1.40 DWG AutoDesk AutoCAD Release 1.40 !:mime image/vnd.dwg 0 string AC1.50 DWG AutoDesk AutoCAD Release 2.05 !:mime image/vnd.dwg 0 string AC2.10 DWG AutoDesk AutoCAD Release 2.10 !:mime image/vnd.dwg 0 string AC2.21 DWG AutoDesk AutoCAD Release 2.21 !:mime image/vnd.dwg 0 string AC2.22 DWG AutoDesk AutoCAD Release 2.22 !:mime image/vnd.dwg 0 string AC1001 DWG AutoDesk AutoCAD Release 2.22 !:mime image/vnd.dwg 0 string AC1002 DWG AutoDesk AutoCAD Release 2.50 !:mime image/vnd.dwg 0 string AC1003 DWG AutoDesk AutoCAD Release 2.60 !:mime image/vnd.dwg 0 string AC1004 DWG AutoDesk AutoCAD Release 9 !:mime image/vnd.dwg 0 string AC1006 DWG AutoDesk AutoCAD Release 10 !:mime image/vnd.dwg 0 string AC1009 DWG AutoDesk AutoCAD Release 11/12 !:mime image/vnd.dwg # AutoCAD DWG versions R13/R14 (www.autodesk.com) # Written December 01, 2003 by Lester Hightower # Based on the DWG File Format Specifications at http://www.opendwg.org/ # AutoCad, from Nahuel Greco # AutoCAD DWG versions R12/R13/R14 (www.autodesk.com) 0 string AC1012 DWG AutoDesk AutoCAD Release 13 !:mime image/vnd.dwg 0 string AC1014 DWG AutoDesk AutoCAD Release 14 !:mime image/vnd.dwg 0 string AC1015 DWG AutoDesk AutoCAD 2000/2002 !:mime image/vnd.dwg # A new version of AutoCAD DWG # Sergey Zaykov (mail_of_sergey@mail.ru, sergey_zaikov@rambler.ru, # ICQ 358572321) # From various sources like: # http://autodesk.blogs.com/between_the_lines/autocad-release-history.html 0 string AC1018 DWG AutoDesk AutoCAD 2004/2005/2006 !:mime image/vnd.dwg 0 string AC1021 DWG AutoDesk AutoCAD 2007/2008/2009 !:mime image/vnd.dwg 0 string AC1024 DWG AutoDesk AutoCAD 2010/2011/2012 !:mime image/vnd.dwg 0 string AC1027 DWG AutoDesk AutoCAD 2013/2014 !:mime image/vnd.dwg # KOMPAS 2D drawing from ASCON # This is KOMPAS 2D drawing or fragment of drawing but is not detailed nor # gathered nor specification # ASCON http://ascon.net/main/ in English, # http://ascon.ru/ main site in Russian # Extension is CDW for drawing and FRW for fragment of drawing # Sergey Zaykov (mail_of_sergey@mail.ru, sergey_zaikov@rambler.ru, # ICQ 358572321, http://vkontakte.ru/id16076543) # From: # http://sd.ascon.ru/otrs/customer.pl?Action=CustomerFAQ&CategoryID=4&ItemID=292 # (in russian) and my experiments 0 string KF >2 belong 0x4E00000C Kompas drawing 12.0 SP1 >2 belong 0x4D00000C Kompas drawing 12.0 >2 belong 0x3200000B Kompas drawing 11.0 SP1 >2 belong 0x3100000B Kompas drawing 11.0 >2 belong 0x2310000A Kompas drawing 10.0 SP1 >2 belong 0x2110000A Kompas drawing 10.0 >2 belong 0x08000009 Kompas drawing 9.0 SP1 >2 belong 0x05000009 Kompas drawing 9.0 >2 belong 0x33010008 Kompas drawing 8+ >2 belong 0x1A000008 Kompas drawing 8.0 >2 belong 0x2C010107 Kompas drawing 7+ >2 belong 0x05000007 Kompas drawing 7.0 >2 belong 0x32000006 Kompas drawing 6+ >2 belong 0x09000006 Kompas drawing 6.0 >2 belong 0x5C009005 Kompas drawing 5.11R03 >2 belong 0x54009005 Kompas drawing 5.11R02 >2 belong 0x51009005 Kompas drawing 5.11R01 >2 belong 0x22009005 Kompas drawing 5.10R03 >2 belong 0x22009005 Kompas drawing 5.10R02 mar >2 belong 0x21009005 Kompas drawing 5.10R02 febr >2 belong 0x19009005 Kompas drawing 5.10R01 >2 belong 0xF4008005 Kompas drawing 5.9R01.003 >2 belong 0x1C008005 Kompas drawing 5.9R01.002 >2 belong 0x11008005 Kompas drawing 5.8R01.003 # CAD: file(1) magic for computer aided design files # Phillip Griffith # AutoCAD magic taken from the Open Design Alliance's OpenDWG specifications. # 0 belong 0x08051700 Bentley/Intergraph MicroStation DGN cell library 0 belong 0x0809fe02 Bentley/Intergraph MicroStation DGN vector CAD 0 belong 0xc809fe02 Bentley/Intergraph MicroStation DGN vector CAD 0 beshort 0x0809 Bentley/Intergraph MicroStation >0x02 byte 0xfe >>0x04 beshort 0x1800 CIT raster CAD # 3DS (3d Studio files) Conflicts with diff output 0x3d '=' #16 beshort 0x3d3d image/x-3ds # MegaCAD 2D/3D drawing (.prt) # http://megacad.de/ # From: Markus Heidelberg 0 string MegaCad23\0 MegaCAD 2D/3D drawing #------------------------------------------------------------------------------ # $File: cafebabe,v 1.17 2015/01/01 17:07:00 christos Exp $ # Cafe Babes unite! # # Since Java bytecode and Mach-O universal binaries have the same magic number, # the test must be performed in the same "magic" sequence to get both right. # The long at offset 4 in a Mach-O universal binary tells the number of # architectures; the short at offset 4 in a Java bytecode file is the JVM minor # version and the short at offset 6 is the JVM major version. Since there are only # only 18 labeled Mach-O architectures at current, and the first released # Java class format was version 43.0, we can safely choose any number # between 18 and 39 to test the number of architectures against # (and use as a hack). Let's not use 18, because the Mach-O people # might add another one or two as time goes by... # ### JAVA START ### 0 belong 0xcafebabe >4 belong >30 compiled Java class data, !:mime application/x-java-applet >>6 beshort x version %d. >>4 beshort x \b%d # Which is which? #>>4 belong 0x032d (Java 1.0) #>>4 belong 0x032d (Java 1.1) >>4 belong 0x002e (Java 1.2) >>4 belong 0x002f (Java 1.3) >>4 belong 0x0030 (Java 1.4) >>4 belong 0x0031 (Java 1.5) >>4 belong 0x0032 (Java 1.6) >>4 belong 0x0033 (Java 1.7) >>4 belong 0x0034 (Java 1.8) 0 belong 0xcafed00d JAR compressed with pack200, >5 byte x version %d. >4 byte x \b%d !:mime application/x-java-pack200 0 belong 0xcafed00d JAR compressed with pack200, >5 byte x version %d. >4 byte x \b%d !:mime application/x-java-pack200 ### JAVA END ### ### MACH-O START ### 0 name mach-o \b [ >0 use mach-o-cpu \b >(8.L) indirect \b: >0 belong x \b] 0 belong 0xcafebabe >4 belong 1 Mach-O universal binary with 1 architecture: >>8 use mach-o \b >4 belong >1 >>4 belong <20 Mach-O universal binary with %d architectures: >>>8 use mach-o \b >>>28 use mach-o \b >>4 belong >2 >>>48 use mach-o \b >>4 belong >3 >>>68 use mach-o \b ### MACH-O END ### #------------------------------------------------------------------------------ # $File: elf,v 1.68 2014/09/19 19:05:57 christos Exp $ # cbor: file(1) magic for CBOR files as defined in RFC 7049 0 string \xd9\xd9\xf7 Concise Binary Object Representation (CBOR) container !:mime application/cbor >3 ubyte <0x20 (positive integer) >3 ubyte <0x40 >>3 ubyte >0x1f (negative integer) >3 ubyte <0x60 >>3 ubyte >0x3f (byte string) >3 ubyte <0x80 >>3 ubyte >0x5f (text string) >3 ubyte <0xa0 >3 ubyte >0x7f (array) >3 ubyte <0xc0 >>3 ubyte >0x9f (map) >3 ubyte <0xe0 >>3 ubyte >0xbf (tagged) >3 ubyte >0xdf (other) #------------------------------------------------------------------------------ # $File$ # CDDB: file(1) magic for CDDB(tm) format CD text data files # # From # # This is the /etc/magic entry to decode datafiles as used by # CDDB-enabled CD player applications. # 0 search/1/w #\040xmcd CDDB(tm) format CD text data #------------------------------------------------------------------------------ # $File: chord,v 1.4 2009/09/19 16:28:08 christos Exp $ # chord: file(1) magic for Chord music sheet typesetting utility input files # # From Philippe De Muyter # File format is actually free, but many distributed files begin with `{title' # 0 string {title Chord text file # Type: PowerTab file format # URL: http://www.power-tab.net/ # From: Jelmer Vernooij 0 string ptab\003\000 Power-Tab v3 Tablature File 0 string ptab\004\000 Power-Tab v4 Tablature File #------------------------------------------------------------------------------ # $File$ # cisco: file(1) magic for cisco Systems routers # # Most cisco file-formats are covered by the generic elf code # # Microcode files are non-ELF, 0x8501 conflicts with NetBSD/alpha. 0 belong&0xffffff00 0x85011400 cisco IOS microcode >7 string >\0 for '%s' 0 belong&0xffffff00 0x8501cb00 cisco IOS experimental microcode >7 string >\0 for '%s' #------------------------------------------------------------------------------ # $File$ # citrus locale declaration # 0 string RuneCT Citrus locale declaration for LC_CTYPE #------------------------------------------------------------------------------ # $File: c-lang,v 1.18 2013/08/14 13:06:43 christos Exp $ # c-lang: file(1) magic for C and related languages programs # # BCPL 0 search/8192 "libhdr" BCPL source text !:mime text/x-bcpl 0 search/8192 "LIBHDR" BCPL source text !:mime text/x-bcpl # C 0 regex \^#include C source text !:mime text/x-c 0 regex \^char[\ \t\n]+ C source text !:mime text/x-c 0 regex \^double[\ \t\n]+ C source text !:mime text/x-c 0 regex \^extern[\ \t\n]+ C source text !:mime text/x-c 0 regex \^float[\ \t\n]+ C source text !:mime text/x-c 0 regex \^struct[\ \t\n]+ C source text !:mime text/x-c 0 regex \^union[\ \t\n]+ C source text !:mime text/x-c 0 search/8192 main( C source text !:mime text/x-c # C++ # The strength of these rules is increased so they beat the C rules above 0 regex \^template[\ \t\n]+ C++ source text !:strength + 5 !:mime text/x-c++ 0 regex \^virtual[\ \t\n]+ C++ source text !:strength + 5 !:mime text/x-c++ 0 regex \^class[\ \t\n]+ C++ source text !:strength + 5 !:mime text/x-c++ 0 regex \^public: C++ source text !:strength + 5 !:mime text/x-c++ 0 regex \^private: C++ source text !:strength + 5 !:mime text/x-c++ # From: Mikhail Teterin 0 string cscope cscope reference data >7 string x version %.2s # We skip the path here, because it is often long (so file will # truncate it) and mostly redundant. # The inverted index functionality was added some time between # versions 11 and 15, so look for -q if version is above 14: >7 string >14 >>10 search/100 \ -q\ with inverted index >10 search/100 \ -c\ text (non-compressed) #------------------------------------------------------------------------------ # $File: clarion,v 1.4 2009/09/19 16:28:08 christos Exp $ # clarion: file(1) magic for # Clarion Personal/Professional Developer # (v2 and above) # From: Julien Blache # Database files # signature 0 leshort 0x3343 Clarion Developer (v2 and above) data file # attributes >2 leshort &0x0001 \b, locked >2 leshort &0x0004 \b, encrypted >2 leshort &0x0008 \b, memo file exists >2 leshort &0x0010 \b, compressed >2 leshort &0x0040 \b, read only # number of records >5 lelong x \b, %d records # Memo files 0 leshort 0x334d Clarion Developer (v2 and above) memo data # Key/Index files # No magic? :( # Help files 0 leshort 0x49e0 Clarion Developer (v2 and above) help data #------------------------------------------------------------------------------ # $File: claris,v 1.6 2012/06/20 21:19:05 christos Exp $ # claris: file(1) magic for claris # "H. Nanosecond" # Claris Works a word processor, etc. # Version 3.0 # .pct claris works clip art files #0000000 000 000 000 000 000 000 000 000 000 000 000 000 000 000 000 000 #* #0001000 #010 250 377 377 377 377 000 213 000 230 000 021 002 377 014 000 #null to byte 1000 octal 514 string \377\377\377\377\000 >0 string \0\0\0\0\0\0\0\0\0\0\0\0\0 Claris clip art 514 string \377\377\377\377\001 >0 string \0\0\0\0\0\0\0\0\0\0\0\0\0 Claris clip art # Claris works files # .cwk 0 string \002\000\210\003\102\117\102\117\000\001\206 Claris works document # .plt 0 string \020\341\000\000\010\010 Claris Works palette files .plt # .msp a dictionary file I am not sure about this I have only one .msp file 0 string \002\271\262\000\040\002\000\164 Claris works dictionary # .usp are user dictionary bits # I am not sure about a magic header: #0000000 001 123 160 146 070 125 104 040 136 123 015 012 160 157 144 151 # soh S p f 8 U D sp ^ S cr nl p o d i #0000020 141 164 162 151 163 164 040 136 123 015 012 144 151 166 040 043 # a t r i s t sp ^ S cr nl d i v sp # # .mth Thesaurus # starts with \0 but no magic header # .chy Hyphenation file # I am not sure: 000 210 034 000 000 # other claris files #./windows/claris/useng.ndx: data #./windows/claris/xtndtran.l32: data #./windows/claris/xtndtran.lst: data #./windows/claris/clworks.lbl: data #./windows/claris/clworks.prf: data #./windows/claris/userd.spl: data #------------------------------------------------------------------------------ # $File: clipper,v 1.6 2009/09/19 16:28:08 christos Exp $ # clipper: file(1) magic for Intergraph (formerly Fairchild) Clipper. # # XXX - what byte order does the Clipper use? # # XXX - what's the "!" stuff: # # >18 short !074000,000000 C1 R1 # >18 short !074000,004000 C2 R1 # >18 short !074000,010000 C3 R1 # >18 short !074000,074000 TEST # # I shall assume it's ANDing the field with the first value and # comparing it with the second, and rewrite it as: # # >18 short&074000 000000 C1 R1 # >18 short&074000 004000 C2 R1 # >18 short&074000 010000 C3 R1 # >18 short&074000 074000 TEST # # as SVR3.1's "file" doesn't support anything of the "!074000,000000" # sort, nor does SunOS 4.x, so either it's something Intergraph added # in CLIX, or something AT&T added in SVR3.2 or later, or something # somebody else thought was a good idea; it's not documented in the # man page for this version of "magic", nor does it appear to be # implemented (at least not after I blew off the bogus code to turn # old-style "&"s into new-style "&"s, which just didn't work at all). # 0 short 0575 CLIPPER COFF executable (VAX #) >20 short 0407 (impure) >20 short 0410 (5.2 compatible) >20 short 0411 (pure) >20 short 0413 (demand paged) >20 short 0443 (target shared library) >12 long >0 not stripped >22 short >0 - version %d 0 short 0577 CLIPPER COFF executable >18 short&074000 000000 C1 R1 >18 short&074000 004000 C2 R1 >18 short&074000 010000 C3 R1 >18 short&074000 074000 TEST >20 short 0407 (impure) >20 short 0410 (pure) >20 short 0411 (separate I&D) >20 short 0413 (paged) >20 short 0443 (target shared library) >12 long >0 not stripped >22 short >0 - version %d >48 long&01 01 alignment trap enabled >52 byte 1 -Ctnc >52 byte 2 -Ctsw >52 byte 3 -Ctpw >52 byte 4 -Ctcb >53 byte 1 -Cdnc >53 byte 2 -Cdsw >53 byte 3 -Cdpw >53 byte 4 -Cdcb >54 byte 1 -Csnc >54 byte 2 -Cssw >54 byte 3 -Cspw >54 byte 4 -Cscb 4 string pipe CLIPPER instruction trace 4 string prof CLIPPER instruction profile #------------------------------------------------------------------------------ # $File: commands,v 1.50 2014/05/30 16:48:44 christos Exp $ # commands: file(1) magic for various shells and interpreters # #0 string/w : shell archive or script for antique kernel text 0 string/wt #!\ /bin/sh POSIX shell script text executable !:mime text/x-shellscript 0 string/wb #!\ /bin/sh POSIX shell script executable (binary data) !:mime text/x-shellscript 0 string/wt #!\ /bin/csh C shell script text executable !:mime text/x-shellscript # korn shell magic, sent by George Wu, gwu@clyde.att.com 0 string/wt #!\ /bin/ksh Korn shell script text executable !:mime text/x-shellscript 0 string/wb #!\ /bin/ksh Korn shell script executable (binary data) !:mime text/x-shellscript 0 string/wt #!\ /bin/tcsh Tenex C shell script text executable !:mime text/x-shellscript 0 string/wt #!\ /usr/bin/tcsh Tenex C shell script text executable !:mime text/x-shellscript 0 string/wt #!\ /usr/local/tcsh Tenex C shell script text executable !:mime text/x-shellscript 0 string/wt #!\ /usr/local/bin/tcsh Tenex C shell script text executable !:mime text/x-shellscript # # zsh/ash/ae/nawk/gawk magic from cameron@cs.unsw.oz.au (Cameron Simpson) 0 string/wt #!\ /bin/zsh Paul Falstad's zsh script text executable !:mime text/x-shellscript 0 string/wt #!\ /usr/bin/zsh Paul Falstad's zsh script text executable !:mime text/x-shellscript 0 string/wt #!\ /usr/local/bin/zsh Paul Falstad's zsh script text executable !:mime text/x-shellscript 0 string/wt #!\ /usr/local/bin/ash Neil Brown's ash script text executable !:mime text/x-shellscript 0 string/wt #!\ /usr/local/bin/ae Neil Brown's ae script text executable !:mime text/x-shellscript 0 string/wt #!\ /bin/nawk new awk script text executable !:mime text/x-nawk 0 string/wt #!\ /usr/bin/nawk new awk script text executable !:mime text/x-nawk 0 string/wt #!\ /usr/local/bin/nawk new awk script text executable !:mime text/x-nawk 0 string/wt #!\ /bin/gawk GNU awk script text executable !:mime text/x-gawk 0 string/wt #!\ /usr/bin/gawk GNU awk script text executable !:mime text/x-gawk 0 string/wt #!\ /usr/local/bin/gawk GNU awk script text executable !:mime text/x-gawk # 0 string/wt #!\ /bin/awk awk script text executable !:mime text/x-awk 0 string/wt #!\ /usr/bin/awk awk script text executable !:mime text/x-awk 0 regex/4096 =^\\s{0,100}BEGIN\\s{0,100}[{] awk or perl script text # AT&T Bell Labs' Plan 9 shell 0 string/wt #!\ /bin/rc Plan 9 rc shell script text executable # bash shell magic, from Peter Tobias (tobias@server.et-inf.fho-emden.de) 0 string/wt #!\ /bin/bash Bourne-Again shell script text executable !:mime text/x-shellscript 0 string/wb #!\ /bin/bash Bourne-Again shell script executable (binary data) !:mime text/x-shellscript 0 string/wt #!\ /usr/bin/bash Bourne-Again shell script text executable !:mime text/x-shellscript 0 string/wb #!\ /usr/bin/bash Bourne-Again shell script executable (binary data) !:mime text/x-shellscript 0 string/wt #!\ /usr/local/bash Bourne-Again shell script text executable !:mime text/x-shellscript 0 string/wb #!\ /usr/local/bash Bourne-Again shell script executable (binary data) !:mime text/x-shellscript 0 string/wt #!\ /usr/local/bin/bash Bourne-Again shell script text executable !:mime text/x-shellscript 0 string/wb #!\ /usr/local/bin/bash Bourne-Again shell script executable (binary data) !:mime text/x-shellscript # PHP scripts # Ulf Harnhammar 0 search/1/c = 0 string =24 regex [0-9.]+ \b, version %s !:mime text/x-php 0 string Zend\x00 PHP script Zend Optimizer data 0 string/t $! DCL command file # Type: Pdmenu # URL: http://packages.debian.org/pdmenu # From: Edward Betts 0 string #!/usr/bin/pdmenu Pdmenu configuration file text #---------------------------------------------------------------------------- # $File$ # communication # TTCN is the Tree and Tabular Combined Notation described in ISO 9646-3. # It is used for conformance testing of communication protocols. # Added by W. Borgert . 0 string $Suite TTCN Abstract Test Suite >&1 string $SuiteId >>&1 string >\n %s >&2 string $SuiteId >>&1 string >\n %s >&3 string $SuiteId >>&1 string >\n %s # MSC (message sequence charts) are a formal description technique, # described in ITU-T Z.120, mainly used for communication protocols. # Added by W. Borgert . 0 string mscdocument Message Sequence Chart (document) 0 string msc Message Sequence Chart (chart) 0 string submsc Message Sequence Chart (subchart) #------------------------------------------------------------------------------ # $File: compress,v 1.61 2014/09/12 20:57:45 christos Exp $ # compress: file(1) magic for pure-compression formats (no archives) # # compress, gzip, pack, compact, huf, squeeze, crunch, freeze, yabba, etc. # # Formats for various forms of compressed data # Formats for "compress" proper have been moved into "compress.c", # because it tries to uncompress it to figure out what's inside. # standard unix compress 0 string \037\235 compress'd data !:mime application/x-compress !:apple LZIVZIVU >2 byte&0x80 >0 block compressed >2 byte&0x1f x %d bits # gzip (GNU zip, not to be confused with Info-ZIP or PKWARE zip archiver) # Edited by Chris Chittleborough , March 2002 # * Original filename is only at offset 10 if "extra field" absent # * Produce shorter output - notably, only report compression methods # other than 8 ("deflate", the only method defined in RFC 1952). 0 string \037\213 gzip compressed data !:mime application/x-gzip !:strength * 2 >2 byte <8 \b, reserved method >2 byte >8 \b, unknown method >3 byte &0x01 \b, ASCII >3 byte &0x02 \b, has CRC >3 byte &0x04 \b, extra field >3 byte&0xC =0x08 >>10 string x \b, was "%s" >3 byte &0x10 \b, has comment >3 byte &0x20 \b, encrypted >4 ledate >0 \b, last modified: %s >8 byte 2 \b, max compression >8 byte 4 \b, max speed >9 byte =0x00 \b, from FAT filesystem (MS-DOS, OS/2, NT) >9 byte =0x01 \b, from Amiga >9 byte =0x02 \b, from VMS >9 byte =0x03 \b, from Unix >9 byte =0x04 \b, from VM/CMS >9 byte =0x05 \b, from Atari >9 byte =0x06 \b, from HPFS filesystem (OS/2, NT) >9 byte =0x07 \b, from MacOS >9 byte =0x08 \b, from Z-System >9 byte =0x09 \b, from CP/M >9 byte =0x0A \b, from TOPS/20 >9 byte =0x0B \b, from NTFS filesystem (NT) >9 byte =0x0C \b, from QDOS >9 byte =0x0D \b, from Acorn RISCOS # packed data, Huffman (minimum redundancy) codes on a byte-by-byte basis 0 string \037\036 packed data !:mime application/octet-stream >2 belong >1 \b, %d characters originally >2 belong =1 \b, %d character originally # # This magic number is byte-order-independent. 0 short 0x1f1f old packed data !:mime application/octet-stream # XXX - why *two* entries for "compacted data", one of which is # byte-order independent, and one of which is byte-order dependent? # 0 short 0x1fff compacted data !:mime application/octet-stream # This string is valid for SunOS (BE) and a matching "short" is listed # in the Ultrix (LE) magic file. 0 string \377\037 compacted data !:mime application/octet-stream 0 short 0145405 huf output !:mime application/octet-stream # bzip2 0 string BZh bzip2 compressed data !:mime application/x-bzip2 >3 byte >47 \b, block size = %c00k # lzip 0 string LZIP lzip compressed data !:mime application/x-lzip >4 byte x \b, version: %d # squeeze and crunch # Michael Haardt 0 beshort 0x76FF squeezed data, >4 string x original name %s 0 beshort 0x76FE crunched data, >2 string x original name %s 0 beshort 0x76FD LZH compressed data, >2 string x original name %s # Freeze 0 string \037\237 frozen file 2.1 0 string \037\236 frozen file 1.0 (or gzip 0.5) # SCO compress -H (LZH) 0 string \037\240 SCO compress -H (LZH) data # European GSM 06.10 is a provisional standard for full-rate speech # transcoding, prI-ETS 300 036, which uses RPE/LTP (residual pulse # excitation/long term prediction) coding at 13 kbit/s. # # There's only a magic nibble (4 bits); that nibble repeats every 33 # bytes. This isn't suited for use, but maybe we can use it someday. # # This will cause very short GSM files to be declared as data and # mismatches to be declared as data too! #0 byte&0xF0 0xd0 data #>33 byte&0xF0 0xd0 #>66 byte&0xF0 0xd0 #>99 byte&0xF0 0xd0 #>132 byte&0xF0 0xd0 GSM 06.10 compressed audio # bzip a block-sorting file compressor # by Julian Seward and others # #0 string BZ bzip compressed data #>2 byte x \b, version: %c #>3 string =1 \b, compression block size 100k #>3 string =2 \b, compression block size 200k #>3 string =3 \b, compression block size 300k #>3 string =4 \b, compression block size 400k #>3 string =5 \b, compression block size 500k #>3 string =6 \b, compression block size 600k #>3 string =7 \b, compression block size 700k #>3 string =8 \b, compression block size 800k #>3 string =9 \b, compression block size 900k # lzop from 0 string \x89\x4c\x5a\x4f\x00\x0d\x0a\x1a\x0a lzop compressed data >9 beshort <0x0940 >>9 byte&0xf0 =0x00 - version 0. >>9 beshort&0x0fff x \b%03x, >>13 byte 1 LZO1X-1, >>13 byte 2 LZO1X-1(15), >>13 byte 3 LZO1X-999, ## >>22 bedate >0 last modified: %s, >>14 byte =0x00 os: MS-DOS >>14 byte =0x01 os: Amiga >>14 byte =0x02 os: VMS >>14 byte =0x03 os: Unix >>14 byte =0x05 os: Atari >>14 byte =0x06 os: OS/2 >>14 byte =0x07 os: MacOS >>14 byte =0x0A os: Tops/20 >>14 byte =0x0B os: WinNT >>14 byte =0x0E os: Win32 >9 beshort >0x0939 >>9 byte&0xf0 =0x00 - version 0. >>9 byte&0xf0 =0x10 - version 1. >>9 byte&0xf0 =0x20 - version 2. >>9 beshort&0x0fff x \b%03x, >>15 byte 1 LZO1X-1, >>15 byte 2 LZO1X-1(15), >>15 byte 3 LZO1X-999, ## >>25 bedate >0 last modified: %s, >>17 byte =0x00 os: MS-DOS >>17 byte =0x01 os: Amiga >>17 byte =0x02 os: VMS >>17 byte =0x03 os: Unix >>17 byte =0x05 os: Atari >>17 byte =0x06 os: OS/2 >>17 byte =0x07 os: MacOS >>17 byte =0x0A os: Tops/20 >>17 byte =0x0B os: WinNT >>17 byte =0x0E os: Win32 # 4.3BSD-Quasijarus Strong Compression # http://minnie.tuhs.org/Quasijarus/compress.html 0 string \037\241 Quasijarus strong compressed data # From: Cory Dikkers 0 string XPKF Amiga xpkf.library compressed data 0 string PP11 Power Packer 1.1 compressed data 0 string PP20 Power Packer 2.0 compressed data, >4 belong 0x09090909 fast compression >4 belong 0x090A0A0A mediocre compression >4 belong 0x090A0B0B good compression >4 belong 0x090A0C0C very good compression >4 belong 0x090A0C0D best compression # 7-zip archiver, from Thomas Klausner (wiz@danbala.tuwien.ac.at) # http://www.7-zip.org or DOC/7zFormat.txt # 0 string 7z\274\257\047\034 7-zip archive data, >6 byte x version %d >7 byte x \b.%d !:mime application/x-7z-compressed # Type: LZMA 0 lelong&0xffffff =0x5d >12 leshort 0xff LZMA compressed data, !:mime application/x-lzma >>5 lequad =0xffffffffffffffff streamed >>5 lequad !0xffffffffffffffff non-streamed, size %lld >12 leshort 0 LZMA compressed data, >>5 lequad =0xffffffffffffffff streamed >>5 lequad !0xffffffffffffffff non-streamed, size %lld # http://tukaani.org/xz/xz-file-format.txt 0 ustring \xFD7zXZ\x00 XZ compressed data !:mime application/x-xz # https://github.com/ckolivas/lrzip/blob/master/doc/magic.header.txt 0 string LRZI LRZIP compressed data >4 byte x - version %d >5 byte x \b.%d !:mime application/x-lrzip # http://fastcompression.blogspot.fi/2013/04/lz4-streaming-format-final.html 0 lelong 0x184d2204 LZ4 compressed data (v1.4+) !:mime application/x-lz4 # Added by osm0sis@xda-developers.com 0 lelong 0x184c2103 LZ4 compressed data (v1.0-v1.3) !:mime application/x-lz4 0 lelong 0x184c2102 LZ4 compressed data (v0.1-v0.9) !:mime application/x-lz4 # AFX compressed files (Wolfram Kleff) 2 string -afx- AFX compressed file data # Supplementary magic data for the file(1) command to support # rzip(1). The format is described in magic(5). # # Copyright (C) 2003 by Andrew Tridgell. You may do whatever you want with # this file. # 0 string RZIP rzip compressed data >4 byte x - version %d >5 byte x \b.%d >6 belong x (%d bytes) 0 string ArC\x01 FreeArc archive # Type: DACT compressed files 0 long 0x444354C3 DACT compressed data >4 byte >-1 (version %i. >5 byte >-1 %i. >6 byte >-1 %i) >7 long >0 , original size: %i bytes >15 long >30 , block size: %i bytes # Valve Pack (VPK) files 0 lelong 0x55aa1234 Valve Pak file >0x4 lelong x \b, version %u >0x8 lelong x \b, %u entries # Snappy framing format # http://code.google.com/p/snappy/source/browse/trunk/framing_format.txt 0 string \377\006\0\0sNaPpY snappy framed data !:mime application/x-snappy-framed # qpress, http://www.quicklz.com/ 0 string qpress10 qpress compressed data !:mime application/x-qpress # Zlib https://www.ietf.org/rfc/rfc6713.txt 0 beshort%31 =0 >0 byte&0xf =8 >>0 byte&0x80 =0 zlib compressed data !:mime application/zlib #------------------------------------------------------------------------------ # $File: console,v 1.18 2010/09/20 19:19:17 rrt Exp $ # Console game magic # Toby Deshane # ines: file(1) magic for Marat's iNES Nintendo Entertainment System # ROM dump format 0 string NES\032 iNES ROM dump, >4 byte x %dx16k PRG >5 byte x \b, %dx8k CHR >6 byte&0x01 =0x1 \b, [Vert.] >6 byte&0x01 =0x0 \b, [Horiz.] >6 byte&0x02 =0x2 \b, [SRAM] >6 byte&0x04 =0x4 \b, [Trainer] >6 byte&0x04 =0x8 \b, [4-Scr] #------------------------------------------------------------------------------ # gameboy: file(1) magic for the Nintendo (Color) Gameboy raw ROM format # 0x104 belong 0xCEED6666 Gameboy ROM: >0x134 string >\0 "%.16s" >0x146 byte 0x03 \b,[SGB] >0x147 byte 0x00 \b, [ROM ONLY] >0x147 byte 0x01 \b, [ROM+MBC1] >0x147 byte 0x02 \b, [ROM+MBC1+RAM] >0x147 byte 0x03 \b, [ROM+MBC1+RAM+BATT] >0x147 byte 0x05 \b, [ROM+MBC2] >0x147 byte 0x06 \b, [ROM+MBC2+BATTERY] >0x147 byte 0x08 \b, [ROM+RAM] >0x147 byte 0x09 \b, [ROM+RAM+BATTERY] >0x147 byte 0x0B \b, [ROM+MMM01] >0x147 byte 0x0C \b, [ROM+MMM01+SRAM] >0x147 byte 0x0D \b, [ROM+MMM01+SRAM+BATT] >0x147 byte 0x0F \b, [ROM+MBC3+TIMER+BATT] >0x147 byte 0x10 \b, [ROM+MBC3+TIMER+RAM+BATT] >0x147 byte 0x11 \b, [ROM+MBC3] >0x147 byte 0x12 \b, [ROM+MBC3+RAM] >0x147 byte 0x13 \b, [ROM+MBC3+RAM+BATT] >0x147 byte 0x19 \b, [ROM+MBC5] >0x147 byte 0x1A \b, [ROM+MBC5+RAM] >0x147 byte 0x1B \b, [ROM+MBC5+RAM+BATT] >0x147 byte 0x1C \b, [ROM+MBC5+RUMBLE] >0x147 byte 0x1D \b, [ROM+MBC5+RUMBLE+SRAM] >0x147 byte 0x1E \b, [ROM+MBC5+RUMBLE+SRAM+BATT] >0x147 byte 0x1F \b, [Pocket Camera] >0x147 byte 0xFD \b, [Bandai TAMA5] >0x147 byte 0xFE \b, [Hudson HuC-3] >0x147 byte 0xFF \b, [Hudson HuC-1] >0x148 byte 0 \b, ROM: 256Kbit >0x148 byte 1 \b, ROM: 512Kbit >0x148 byte 2 \b, ROM: 1Mbit >0x148 byte 3 \b, ROM: 2Mbit >0x148 byte 4 \b, ROM: 4Mbit >0x148 byte 5 \b, ROM: 8Mbit >0x148 byte 6 \b, ROM: 16Mbit >0x148 byte 0x52 \b, ROM: 9Mbit >0x148 byte 0x53 \b, ROM: 10Mbit >0x148 byte 0x54 \b, ROM: 12Mbit >0x149 byte 1 \b, RAM: 16Kbit >0x149 byte 2 \b, RAM: 64Kbit >0x149 byte 3 \b, RAM: 128Kbit >0x149 byte 4 \b, RAM: 1Mbit #>0x14e long x \b, CRC: %x #------------------------------------------------------------------------------ # genesis: file(1) magic for the Sega MegaDrive/Genesis raw ROM format # 0x100 string SEGA Sega MegaDrive/Genesis raw ROM dump >0x120 string >\0 Name: "%.16s" >0x110 string >\0 %.16s >0x1B0 string RA with SRAM #------------------------------------------------------------------------------ # genesis: file(1) magic for the Super MegaDrive ROM dump format # 0x280 string EAGN Super MagicDrive ROM dump >0 byte x %dx16k blocks >2 byte 0 \b, last in series or standalone >2 byte >0 \b, split ROM >8 byte 0xAA >9 byte 0xBB #------------------------------------------------------------------------------ # genesis: file(1) alternate magic for the Super MegaDrive ROM dump format # 0x280 string EAMG Super MagicDrive ROM dump >0 byte x %dx16k blocks >2 byte x \b, last in series or standalone >8 byte 0xAA >9 byte 0xBB #------------------------------------------------------------------------------ # smsgg: file(1) magic for Sega Master System and Game Gear ROM dumps # # Does not detect all images. Very preliminary guesswork. Need more data # on format. # # FIXME: need a little more info...;P # #0 byte 0xF3 #>1 byte 0xED Sega Master System/Game Gear ROM dump #>1 byte 0x31 Sega Master System/Game Gear ROM dump #>1 byte 0xDB Sega Master System/Game Gear ROM dump #>1 byte 0xAF Sega Master System/Game Gear ROM dump #>1 byte 0xC3 Sega Master System/Game Gear ROM dump #------------------------------------------------------------------------------ # dreamcast: file(1) uncertain magic for the Sega Dreamcast VMU image format # 0 belong 0x21068028 Sega Dreamcast VMU game image 0 string LCDi Dream Animator file #------------------------------------------------------------------------------ # v64: file(1) uncertain magic for the V64 format N64 ROM dumps # 0 belong 0x37804012 V64 Nintendo 64 ROM dump # From: "Nelson A. de Oliveira" # Nintendo .nds 192 string \044\377\256Qi\232 Nintendo DS Game ROM Image # Nintendo .gba 0 string \056\000\000\352$\377\256Qi Nintendo Game Boy Advance ROM Image #------------------------------------------------------------------------------ # msx: file(1) magic for MSX game cartridge dumps # Too simple - MPi #0 beshort 0x4142 MSX game cartridge dump #------------------------------------------------------------------------------ # Sony Playstation executables (Adam Sjoegren ) : 0 string PS-X\ EXE Sony Playstation executable # Area: >113 string x (%s) #------------------------------------------------------------------------------ # Microsoft Xbox executables .xbe (Esa Hyytia ) 0 string XBEH XBE, Microsoft Xbox executable # probabilistic checks whether signed or not >0x0004 ulelong =0x0 >>&2 ulelong =0x0 >>>&2 ulelong =0x0 \b, not signed >0x0004 ulelong >0 >>&2 ulelong >0 >>>&2 ulelong >0 \b, signed # expect base address of 0x10000 >0x0104 ulelong =0x10000 >>(0x0118-0x0FF60) ulelong&0x80000007 0x80000007 \b, all regions >>(0x0118-0x0FF60) ulelong&0x80000007 !0x80000007 >>>(0x0118-0x0FF60) ulelong >0 (regions: >>>>(0x0118-0x0FF60) ulelong &0x00000001 NA >>>>(0x0118-0x0FF60) ulelong &0x00000002 Japan >>>>(0x0118-0x0FF60) ulelong &0x00000004 Rest_of_World >>>>(0x0118-0x0FF60) ulelong &0x80000000 Manufacturer >>>(0x0118-0x0FF60) ulelong >0 \b) # -------------------------------- # Microsoft Xbox data file formats 0 string XIP0 XIP, Microsoft Xbox data 0 string XTF0 XTF, Microsoft Xbox data # Atari Lynx cartridge dump (EXE/BLL header) # From: "Stefan A. Haubenthal" # Double-check that the image type matches too, 0x8008 conflicts with # 8 character OMF-86 object file headers. 0 beshort 0x8008 >6 string BS93 Lynx homebrew cartridge >>2 beshort x \b, RAM start $%04x >6 string LYNX Lynx cartridge >>2 beshort x \b, RAM start $%04x # Opera file system that is used on the 3DO console # From: Serge van den Boom 0 string \x01ZZZZZ\x01 3DO "Opera" file system # From Gurkan Sengun , www.linuks.mine.nu 0 string GBS Nintendo Gameboy Music/Audio Data 12 string GameBoy\ Music\ Module Nintendo Gameboy Music Module # Playstations Patch Files from: From: Thomas Klausner 0 string PPF30 Playstation Patch File version 3.0 >5 byte 0 \b, PPF 1.0 patch >5 byte 1 \b, PPF 2.0 patch >5 byte 2 \b, PPF 3.0 patch >>56 byte 0 \b, Imagetype BIN (any) >>56 byte 1 \b, Imagetype GI (PrimoDVD) >>57 byte 0 \b, Blockcheck disabled >>57 byte 1 \b, Blockcheck enabled >>58 byte 0 \b, Undo data not available >>58 byte 1 \b, Undo data available >6 string x \b, description: %s 0 string PPF20 Playstation Patch File version 2.0 >5 byte 0 \b, PPF 1.0 patch >5 byte 1 \b, PPF 2.0 patch >>56 lelong >0 \b, size of file to patch %d >6 string x \b, description: %s 0 string PPF10 Playstation Patch File version 1.0 >5 byte 0 \b, Simple Encoding >6 string x \b, description: %s # From: Daniel Dawson # SNES9x .smv "movie" file format. 0 string SMV\x1A SNES9x input recording >0x4 lelong x \b, version %d # version 4 is latest so far >0x4 lelong <5 >>0x8 ledate x \b, recorded at %s >>0xc lelong >0 \b, rerecorded %d times >>0x10 lelong x \b, %d frames long >>0x14 byte >0 \b, data for controller(s): >>>0x14 byte &0x1 #1 >>>0x14 byte &0x2 #2 >>>0x14 byte &0x4 #3 >>>0x14 byte &0x8 #4 >>>0x14 byte &0x10 #5 >>0x15 byte ^0x1 \b, begins from snapshot >>0x15 byte &0x1 \b, begins from reset >>0x15 byte ^0x2 \b, NTSC standard >>0x15 byte &0x2 \b, PAL standard >>0x17 byte &0x1 \b, settings: # WIP1Timing not used as of version 4 >>>0x4 lelong <4 >>>>0x17 byte &0x2 WIP1Timing >>>0x17 byte &0x4 Left+Right >>>0x17 byte &0x8 VolumeEnvX >>>0x17 byte &0x10 FakeMute >>>0x17 byte &0x20 SyncSound # New flag as of version 4 >>>0x4 lelong >3 >>>>0x17 byte &0x80 NoCPUShutdown >>0x4 lelong <4 >>>0x18 lelong >0x23 >>>>0x20 leshort !0 >>>>>0x20 lestring16 x \b, metadata: "%s" >>0x4 lelong >3 >>>0x24 byte >0 \b, port 1: >>>>0x24 byte 1 joypad >>>>0x24 byte 2 mouse >>>>0x24 byte 3 SuperScope >>>>0x24 byte 4 Justifier >>>>0x24 byte 5 multitap >>>0x24 byte >0 \b, port 2: >>>>0x25 byte 1 joypad >>>>0x25 byte 2 mouse >>>>0x25 byte 3 SuperScope >>>>0x25 byte 4 Justifier >>>>0x25 byte 5 multitap >>>0x18 lelong >0x43 >>>>0x40 leshort !0 >>>>>0x40 lestring16 x \b, metadata: "%s" >>0x17 byte &0x40 \b, ROM: >>>(0x18.l-26) lelong x CRC32 0x%08x >>>(0x18.l-23) string x "%s" # Type: scummVM savegame files # From: Sven Hartge 0 string SCVM ScummVM savegame >12 string >\0 "%s" #------------------------------------------------------------------------------ # $File: convex,v 1.7 2009/09/19 16:28:08 christos Exp $ # convex: file(1) magic for Convex boxes # # Convexes are big-endian. # # /*\ # * Below are the magic numbers and tests added for Convex. # * Added at beginning, because they are expected to be used most. # \*/ 0 belong 0507 Convex old-style object >16 belong >0 not stripped 0 belong 0513 Convex old-style demand paged executable >16 belong >0 not stripped 0 belong 0515 Convex old-style pre-paged executable >16 belong >0 not stripped 0 belong 0517 Convex old-style pre-paged, non-swapped executable >16 belong >0 not stripped 0 belong 0x011257 Core file # # The following are a series of dump format magic numbers. Each one # corresponds to a drastically different dump format. The first on is # the original dump format on a 4.1 BSD or earlier file system. The # second marks the change between the 4.1 file system and the 4.2 file # system. The Third marks the changing of the block size from 1K # to 2K to be compatible with an IDC file system. The fourth indicates # a dump that is dependent on Convex Storage Manager, because data in # secondary storage is not physically contained within the dump. # The restore program uses these number to determine how the data is # to be extracted. # 24 belong =60013 dump format, 4.2 or 4.3 BSD (IDC compatible) 24 belong =60014 dump format, Convex Storage Manager by-reference dump # # what follows is a bunch of bit-mask checks on the flags field of the opthdr. # If there is no `=' sign, assume just checking for whether the bit is set? # 0 belong 0601 Convex SOFF >88 belong&0x000f0000 =0x00000000 c1 >88 belong &0x00010000 c2 >88 belong &0x00020000 c2mp >88 belong &0x00040000 parallel >88 belong &0x00080000 intrinsic >88 belong &0x00000001 demand paged >88 belong &0x00000002 pre-paged >88 belong &0x00000004 non-swapped >88 belong &0x00000008 POSIX # >84 belong &0x80000000 executable >84 belong &0x40000000 object >84 belong&0x20000000 =0 not stripped >84 belong&0x18000000 =0x00000000 native fpmode >84 belong&0x18000000 =0x10000000 ieee fpmode >84 belong&0x18000000 =0x18000000 undefined fpmode # 0 belong 0605 Convex SOFF core # 0 belong 0607 Convex SOFF checkpoint >88 belong&0x000f0000 =0x00000000 c1 >88 belong &0x00010000 c2 >88 belong &0x00020000 c2mp >88 belong &0x00040000 parallel >88 belong &0x00080000 intrinsic >88 belong &0x00000008 POSIX # >84 belong&0x18000000 =0x00000000 native fpmode >84 belong&0x18000000 =0x10000000 ieee fpmode >84 belong&0x18000000 =0x18000000 undefined fpmode #------------------------------------------------------------------------------ # $File$ # cracklib: file (1) magic for cracklib v2.7 0 lelong 0x70775631 Cracklib password index, little endian >4 long >0 (%i words) >4 long 0 ("64-bit") >>8 long >-1 (%i words) 0 belong 0x70775631 Cracklib password index, big endian >4 belong >-1 (%i words) # really bellong 0x0000000070775631 0 search/1 \0\0\0\0pwV1 Cracklib password index, big endian ("64-bit") >12 belong >0 (%i words) # ---------------------------------------------------------------------------- # $File$ # ctags: file (1) magic for Exuberant Ctags files # From: Alexander Mai 0 search/1 =!_TAG Exuberant Ctags tag file text #-------------------------------------------------------------- # ctf: file(1) magic for CTF (Common Trace Format) trace files # # Specs. available here: #-------------------------------------------------------------- # CTF trace data 0 lelong 0xc1fc1fc1 Common Trace Format (CTF) trace data (LE) 0 belong 0xc1fc1fc1 Common Trace Format (CTF) trace data (BE) # CTF metadata (packetized) 0 lelong 0x75d11d57 Common Trace Format (CTF) packetized metadata (LE) >35 byte x \b, v%d >36 byte x \b.%d 0 belong 0x75d11d57 Common Trace Format (CTF) packetized metadata (BE) >35 byte x \b, v%d >36 byte x \b.%d # CTF metadata (plain text) 0 string /*\x20CTF\x20 Common Trace Format (CTF) plain text metadata !:strength + 5 # this is to make sure we beat C >&0 regex [0-9]+\.[0-9]+ \b, v%s #------------------------------------------------------------------------------ # $File: cubemaps,v 1.0 2011/12/22 09:01:05 christos Exp $ # file(1) magic(5) data for cubemaps Martin Erik Werner # 0 string ACMP Map file for the AssaultCube FPS game 0 string CUBE Map file for cube and cube2 engine games 0 string MAPZ) Map file for the Blood Frontier/Red Eclipse FPS games #------------------------------------------------------------------------------ # $File: cups,v 1.2 2012/11/02 21:50:29 christos Exp $ # Cups: file(1) magic for the cups raster file format # From: Laurent Martelli # http://www.cups.org/documentation.php/spec-raster.html # 0 name cups-le >280 lelong x \b, %d >284 lelong x \bx%d dpi >376 lelong x \b, %dx >380 lelong x \b%d pixels >388 lelong x %d bits/color >392 lelong x %d bits/pixel >400 lelong 0 ColorOrder=Chunky >400 lelong 1 ColorOrder=Banded >400 lelong 2 ColorOrder=Planar >404 lelong 0 ColorSpace=gray >404 lelong 1 ColorSpace=RGB >404 lelong 2 ColorSpace=RGBA >404 lelong 3 ColorSpace=black >404 lelong 4 ColorSpace=CMY >404 lelong 5 ColorSpace=YMC >404 lelong 6 ColorSpace=CMYK >404 lelong 7 ColorSpace=YMCK >404 lelong 8 ColorSpace=KCMY >404 lelong 9 ColorSpace=KCMYcm >404 lelong 10 ColorSpace=GMCK >404 lelong 11 ColorSpace=GMCS >404 lelong 12 ColorSpace=WHITE >404 lelong 13 ColorSpace=GOLD >404 lelong 14 ColorSpace=SILVER >404 lelong 15 ColorSpace=CIE XYZ >404 lelong 16 ColorSpace=CIE Lab >404 lelong 17 ColorSpace=RGBW >404 lelong 18 ColorSpace=sGray >404 lelong 19 ColorSpace=sRGB >404 lelong 20 ColorSpace=AdobeRGB # Cups Raster image format, Big Endian 0 string RaS >3 string t Cups Raster version 1, Big Endian >3 string 2 Cups Raster version 2, Big Endian >3 string 3 Cups Raster version 3, Big Endian !:mime application/vnd.cups-raster >0 use ^cups-le # Cups Raster image format, Little Endian 1 string SaR >0 string t Cups Raster version 1, Little Endian >0 string 2 Cups Raster version 2, Little Endian >0 string 3 Cups Raster version 3, Little Endian !:mime application/vnd.cups-raster >0 use cups-le #------------------------------------------------------------------------------ # $File$ # dact: file(1) magic for DACT compressed files # 0 long 0x444354C3 DACT compressed data >4 byte >-1 (version %i. >5 byte >-1 $BS%i. >6 byte >-1 $BS%i) >7 long >0 $BS, original size: %i bytes >15 long >30 $BS, block size: %i bytes #------------------------------------------------------------------------------ # $File: database,v 1.42 2014/08/19 14:18:04 christos Exp $ # database: file(1) magic for various databases # # extracted from header/code files by Graeme Wilford (eep2gw@ee.surrey.ac.uk) # # # GDBM magic numbers # Will be maintained as part of the GDBM distribution in the future. # 0 belong 0x13579acd GNU dbm 1.x or ndbm database, big endian, 32-bit !:mime application/x-gdbm 0 belong 0x13579ace GNU dbm 1.x or ndbm database, big endian, old !:mime application/x-gdbm 0 belong 0x13579acf GNU dbm 1.x or ndbm database, big endian, 64-bit !:mime application/x-gdbm 0 lelong 0x13579acd GNU dbm 1.x or ndbm database, little endian, 32-bit !:mime application/x-gdbm 0 lelong 0x13579ace GNU dbm 1.x or ndbm database, little endian, old !:mime application/x-gdbm 0 lelong 0x13579acf GNU dbm 1.x or ndbm database, little endian, 64-bit !:mime application/x-gdbm 0 string GDBM GNU dbm 2.x database !:mime application/x-gdbm # # Berkeley DB # # Ian Darwin's file /etc/magic files: big/little-endian version. # # Hash 1.85/1.86 databases store metadata in network byte order. # Btree 1.85/1.86 databases store the metadata in host byte order. # Hash and Btree 2.X and later databases store the metadata in host byte order. 0 long 0x00061561 Berkeley DB !:mime application/x-dbm >8 belong 4321 >>4 belong >2 1.86 >>4 belong <3 1.85 >>4 belong >0 (Hash, version %d, native byte-order) >8 belong 1234 >>4 belong >2 1.86 >>4 belong <3 1.85 >>4 belong >0 (Hash, version %d, little-endian) 0 belong 0x00061561 Berkeley DB >8 belong 4321 >>4 belong >2 1.86 >>4 belong <3 1.85 >>4 belong >0 (Hash, version %d, big-endian) >8 belong 1234 >>4 belong >2 1.86 >>4 belong <3 1.85 >>4 belong >0 (Hash, version %d, native byte-order) 0 long 0x00053162 Berkeley DB 1.85/1.86 >4 long >0 (Btree, version %d, native byte-order) 0 belong 0x00053162 Berkeley DB 1.85/1.86 >4 belong >0 (Btree, version %d, big-endian) 0 lelong 0x00053162 Berkeley DB 1.85/1.86 >4 lelong >0 (Btree, version %d, little-endian) 12 long 0x00061561 Berkeley DB >16 long >0 (Hash, version %d, native byte-order) 12 belong 0x00061561 Berkeley DB >16 belong >0 (Hash, version %d, big-endian) 12 lelong 0x00061561 Berkeley DB >16 lelong >0 (Hash, version %d, little-endian) 12 long 0x00053162 Berkeley DB >16 long >0 (Btree, version %d, native byte-order) 12 belong 0x00053162 Berkeley DB >16 belong >0 (Btree, version %d, big-endian) 12 lelong 0x00053162 Berkeley DB >16 lelong >0 (Btree, version %d, little-endian) 12 long 0x00042253 Berkeley DB >16 long >0 (Queue, version %d, native byte-order) 12 belong 0x00042253 Berkeley DB >16 belong >0 (Queue, version %d, big-endian) 12 lelong 0x00042253 Berkeley DB >16 lelong >0 (Queue, version %d, little-endian) # From Max Bowsher. 12 long 0x00040988 Berkeley DB >16 long >0 (Log, version %d, native byte-order) 12 belong 0x00040988 Berkeley DB >16 belong >0 (Log, version %d, big-endian) 12 lelong 0x00040988 Berkeley DB >16 lelong >0 (Log, version %d, little-endian) # # # Round Robin Database Tool by Tobias Oetiker 0 string/b RRD\0 RRDTool DB >4 string/b x version %s >>10 short !0 16bit aligned >>>10 bedouble 8.642135e+130 big-endian >>>>18 short x 32bit long (m68k) >>10 short 0 >>>12 long !0 32bit aligned >>>>12 bedouble 8.642135e+130 big-endian >>>>>20 long 0 64bit long >>>>>20 long !0 32bit long >>>>12 ledouble 8.642135e+130 little-endian >>>>>24 long 0 64bit long >>>>>24 long !0 32bit long (i386) >>>>12 string \x43\x2b\x1f\x5b\x2f\x25\xc0\xc7 middle-endian >>>>>24 short !0 32bit long (arm) >>8 quad 0 64bit aligned >>>16 bedouble 8.642135e+130 big-endian >>>>24 long 0 64bit long (s390x) >>>>24 long !0 32bit long (hppa/mips/ppc/s390/SPARC) >>>16 ledouble 8.642135e+130 little-endian >>>>28 long 0 64bit long (alpha/amd64/ia64) >>>>28 long !0 32bit long (armel/mipsel) #---------------------------------------------------------------------- # ROOT: file(1) magic for ROOT databases # 0 string root\0 ROOT file >4 belong x Version %d >33 belong x (Compression: %d) # XXX: Weak magic. # Alex Ott ## Paradox file formats #2 leshort 0x0800 Paradox #>0x39 byte 3 v. 3.0 #>0x39 byte 4 v. 3.5 #>0x39 byte 9 v. 4.x #>0x39 byte 10 v. 5.x #>0x39 byte 11 v. 5.x #>0x39 byte 12 v. 7.x #>>0x04 byte 0 indexed .DB data file #>>0x04 byte 1 primary index .PX file #>>0x04 byte 2 non-indexed .DB data file #>>0x04 byte 3 non-incrementing secondary index .Xnn file #>>0x04 byte 4 secondary index .Ynn file #>>0x04 byte 5 incrementing secondary index .Xnn file #>>0x04 byte 6 non-incrementing secondary index .XGn file #>>0x04 byte 7 secondary index .YGn file #>>>0x04 byte 8 incrementing secondary index .XGn file ## XBase database files # updated by Joerg Jenderek at Feb 2013 # http://www.dbase.com/Knowledgebase/INT/db7_file_fmt.htm # http://www.clicketyclick.dk/databases/xbase/format/dbf.html # http://home.f1.htw-berlin.de/scheibl/db/intern/dBase.htm # inspect VVYYMMDD , where 1<= MM <= 12 and 1<= DD <= 31 0 ubelong&0x0000FFFF <0x00000C20 # skip Infocom game Z-machine >2 ubyte >0 # skip Androids *.xml >>3 ubyte >0 >>>3 ubyte <32 # 1 < version VV >>>>0 ubyte >1 # skip HELP.CA3 by test for reserved byte ( NULL ) >>>>>27 ubyte 0 # reserved bytes not always 0 ; also found 0x3901 (T4.DBF) ,0x7101 (T5.DBF,T6.DBF) #>>>>>30 ubeshort x 30NULL?%x # possible production flag,tag numbers(<=0x30),tag length(<=0x20), reserved (NULL) >>>>>>24 ubelong&0xffFFFFff >0x01302000 # .DBF or .MDX >>>>>>24 ubelong&0xffFFFFff <0x01302001 # for Xbase Database file (*.DBF) reserved (NULL) for multi-user >>>>>>>24 ubelong&0xffFFFFff =0 # test for 2 reserved NULL bytes,transaction and encryption byte flag >>>>>>>>12 ubelong&0xFFFFfEfE 0 # test for MDX flag >>>>>>>>>28 ubyte x >>>>>>>>>28 ubyte&0xf8 0 # header size >= 32 >>>>>>>>>>8 uleshort >31 # skip PIC15736.PCX by test for language driver name or field name >>>>>>>>>>>32 ubyte >0 #!:mime application/x-dbf; charset=unknown-8bit ?? #!:mime application/x-dbase >>>>>>>>>>>>0 use xbase-type # database file >>>>>>>>>>>>0 ubyte x \b DBF >>>>>>>>>>>>4 lelong 0 \b, no records >>>>>>>>>>>>4 lelong >0 \b, %d record # plural s appended >>>>>>>>>>>>>4 lelong >1 \bs # http://www.clicketyclick.dk/databases/xbase/format/dbf_check.html#CHECK_DBF # 1 <= record size <= 4000 (dBase 3,4) or 32 * KB (=0x8000) >>>>>>>>>>>>10 uleshort x * %d # file size = records * record size + header size >>>>>>>>>>>>1 ubyte x \b, update-date >>>>>>>>>>>>1 use xbase-date # http://msdn.microsoft.com/de-de/library/cc483186(v=vs.71).aspx #>>>>>>>>>>>>29 ubyte =0 \b, codepage ID=0x%x # 2~cp850 , 3~cp1252 , 0x1b~?? ; what code page is 0x1b ? >>>>>>>>>>>>29 ubyte >0 \b, codepage ID=0x%x #>>>>>>>>>>>>28 ubyte&0x01 0 \b, no index file >>>>>>>>>>>>28 ubyte&0x01 1 \b, with index file .MDX >>>>>>>>>>>>28 ubyte&0x02 2 \b, with memo .FPT >>>>>>>>>>>>28 ubyte&0x04 4 \b, DataBaseContainer # 1st record offset + 1 = header size >>>>>>>>>>>>8 uleshort >0 >>>>>>>>>>>>(8.s+1) ubyte >0 >>>>>>>>>>>>>8 uleshort >0 \b, at offset %d >>>>>>>>>>>>>(8.s+1) ubyte >0 >>>>>>>>>>>>>>&-1 string >\0 1st record "%s" # for multiple index files (*.MDX) Production flag,tag numbers(<=0x30),tag length(<=0x20), reserverd (NULL) >>>>>>>24 ubelong&0x0133f7ff >0 # test for reserved NULL byte >>>>>>>>47 ubyte 0 # test for valid TAG key format (0x10 or 0) >>>>>>>>>559 ubyte&0xeF 0 # test MM <= 12 >>>>>>>>>>45 ubeshort <0x0C20 >>>>>>>>>>>45 ubyte >0 >>>>>>>>>>>>46 ubyte <32 >>>>>>>>>>>>>46 ubyte >0 #!:mime application/x-mdx >>>>>>>>>>>>>>0 use xbase-type >>>>>>>>>>>>>>0 ubyte x \b MDX >>>>>>>>>>>>>>1 ubyte x \b, creation-date >>>>>>>>>>>>>>1 use xbase-date >>>>>>>>>>>>>>44 ubyte x \b, update-date >>>>>>>>>>>>>>44 use xbase-date # No.of tags in use (1,2,5,12) >>>>>>>>>>>>>>28 uleshort x \b, %d # No. of entries in tag (0x30) >>>>>>>>>>>>>>25 ubyte x \b/%d tags # Length of tag >>>>>>>>>>>>>>26 ubyte x * %d # 1st tag name_ >>>>>>>>>>>>>548 string x \b, 1st tag "%.11s" # 2nd tag name #>>>>>>>>>>>>(26.b+548) string x \b, 2nd tag "%.11s" # # Print the xBase names of different version variants 0 name xbase-type >0 ubyte <2 # 1 < version >0 ubyte >1 >>0 ubyte 0x02 FoxBase # FoxBase+/dBaseIII+, no memo >>0 ubyte 0x03 FoxBase+/dBase III !:mime application/x-dbf # dBASE IV no memo file >>0 ubyte 0x04 dBase IV !:mime application/x-dbf # dBASE V no memo file >>0 ubyte 0x05 dBase V !:mime application/x-dbf >>0 ubyte 0x30 Visual FoxPro !:mime application/x-dbf >>0 ubyte 0x31 Visual FoxPro, autoincrement !:mime application/x-dbf # Visual FoxPro, with field type Varchar or Varbinary >>0 ubyte 0x32 Visual FoxPro, with field type Varchar !:mime application/x-dbf # dBASE IV SQL, no memo;dbv memo var size (Flagship) >>0 ubyte 0x43 dBase IV, with SQL table !:mime application/x-dbf # http://msdn.microsoft.com/en-US/library/st4a0s68(v=vs.80).aspx #>>0 ubyte 0x62 dBase IV, with SQL table #!:mime application/x-dbf # dBASE IV, with memo!! >>0 ubyte 0x7b dBase IV, with memo !:mime application/x-dbf # http://msdn.microsoft.com/en-US/library/st4a0s68(v=vs.80).aspx #>>0 ubyte 0x82 dBase IV, with SQL system #!:mime application/x-dbf # FoxBase+/dBaseIII+ with memo .DBT! >>0 ubyte 0x83 FoxBase+/dBase III, with memo .DBT !:mime application/x-dbf # VISUAL OBJECTS (first 1.0 versions) for the Dbase III files (NTX clipper driver); memo file >>0 ubyte 0x87 VISUAL OBJECTS, with memo file !:mime application/x-dbf # http://msdn.microsoft.com/en-US/library/st4a0s68(v=vs.80).aspx #>>0 ubyte 0x8A FoxBase+/dBase III, with memo .DBT #!:mime application/x-dbf # dBASE IV with memo! >>0 ubyte 0x8B dBase IV, with memo .DBT !:mime application/x-dbf # dBase IV with SQL Table,no memo? >>0 ubyte 0x8E dBase IV, with SQL table !:mime application/x-dbf # .dbv and .dbt memo (Flagship)? >>0 ubyte 0xB3 Flagship # http://msdn.microsoft.com/en-US/library/st4a0s68(v=vs.80).aspx #>>0 ubyte 0xCA dBase IV with memo .DBT #!:mime application/x-dbf # dBASE IV with SQL table, with memo .DBT >>0 ubyte 0xCB dBase IV with SQL table, with memo .DBT !:mime application/x-dbf # HiPer-Six format;Clipper SIX, with SMT memo file >>0 ubyte 0xE5 Clipper SIX with memo !:mime application/x-dbf # http://msdn.microsoft.com/en-US/library/st4a0s68(v=vs.80).aspx #>>0 ubyte 0xF4 dBase IV, with SQL table, with memo #!:mime application/x-dbf >>0 ubyte 0xF5 FoxPro with memo !:mime application/x-dbf # http://msdn.microsoft.com/en-US/library/st4a0s68(v=vs.80).aspx #>>0 ubyte 0xFA FoxPro 2.x, with memo #!:mime application/x-dbf # unknown version (should not happen) >>0 default x xBase !:mime application/x-dbf >>>0 ubyte x (0x%x) # flags in version byte # DBT flag (with dBASE III memo .DBT)!! # >>0 ubyte&0x80 >0 DBT_FLAG=%x # memo flag ?? # >>0 ubyte&0x08 >0 MEMO_FLAG=%x # SQL flag ?? # >>0 ubyte&0x70 >0 SQL_FLAG=%x # test and print the date of xBase .DBF .MDX 0 name xbase-date # inspect YYMMDD , where 1<= MM <= 12 and 1<= DD <= 31 >0 ubelong x >1 ubyte <13 >>1 ubyte >0 >>>2 ubyte >0 >>>>2 ubyte <32 >>>>>0 ubyte x # YY is interpreted as 20YY or 19YY >>>>>>0 ubyte <100 \b %.2d # YY is interpreted 1900+YY; TODO: display yy or 20yy instead 1YY >>>>>>0 ubyte >99 \b %d >>>>>1 ubyte x \b-%d >>>>>2 ubyte x \b-%d # dBase memo files .DBT or .FPT # http://msdn.microsoft.com/en-us/library/8599s21w(v=vs.80).aspx 16 ubyte <4 >16 ubyte !2 >>16 ubyte !1 # next free block index is positive >>>0 ulelong >0 # skip many JPG. ZIP, BZ2 by test for reserved bytes NULL , 0|2 , 0|1 , low byte of block size >>>>17 ubelong&0xFFfdFE00 0x00000000 # skip many RAR by test for low byte 0 ,high byte 0|2|even of block size, 0|a|e|d7 , 0|64h >>>>>20 ubelong&0xFF01209B 0x00000000 # dBASE III >>>>>>16 ubyte 3 # dBASE III DBT >>>>>>>0 use dbase3-memo-print # dBASE III DBT without version, dBASE IV DBT , FoxPro FPT , or many ZIP , DBF garbage >>>>>>16 ubyte 0 # unusual dBASE III DBT like angest.dbt, dBASE IV DBT with block size 0 , FoxPro FPT , or garbage PCX DBF >>>>>>>20 uleshort 0 # FoxPro FPT , unusual dBASE III DBT like biblio.dbt or garbage >>>>>>>>8 ulong =0 >>>>>>>>>6 ubeshort >0 # skip emacs.PIF >>>>>>>>>>4 ushort 0 >>>>>>>>>>>0 use foxpro-memo-print # dBASE III DBT , garbage >>>>>>>>>6 ubeshort 0 # skip MM*DD*.bin by test for for reserved NULL byte >>>>>>>>>>510 ubeshort 0 # skip TK-DOS11.img image by looking for memo text >>>>>>>>>>>512 ubelong <0xfeffff03 # skip EFI executables by looking for memo text >>>>>>>>>>>>512 ubelong >0x1F202020 >>>>>>>>>>>>>513 ubyte >0 # unusual dBASE III DBT like adressen.dbt >>>>>>>>>>>>>>0 use dbase3-memo-print # dBASE III DBT like angest.dbt, or garbage PCX DBF >>>>>>>>8 ubelong !0 # skip PCX and some DBF by test for for reserved NULL bytes >>>>>>>>>510 ubeshort 0 # skip some DBF by test of invalid version >>>>>>>>>>0 ubyte >5 >>>>>>>>>>>0 ubyte <48 >>>>>>>>>>>>0 use dbase3-memo-print # dBASE IV DBT with positive block size >>>>>>>20 uleshort >0 >>>>>>>>0 use dbase4-memo-print # Print the information of dBase III DBT memo file 0 name dbase3-memo-print >0 ubyte x dBase III DBT # instead 3 as version number 0 for unusual examples like biblio.dbt >16 ubyte !3 \b, version number %u # Number of next available block for appending data #>0 lelong =0 \b, next free block index %u >0 lelong !0 \b, next free block index %u # no positiv block length #>20 uleshort =0 \b, block length %u >20 uleshort !0 \b, block length %u # dBase III memo field terminated by \032\032 >512 string >\0 \b, 1st item "%s" # Print the information of dBase IV DBT memo file 0 name dbase4-memo-print >0 lelong x dBase IV DBT # 8 character shorted main name of coresponding dBASE IV DBF file >8 ubelong >0x20000000 # skip unusual like for angest.dbt >>20 uleshort >0 >>>8 string >\0 \b of %-.8s.DBF # value 0 implies 512 as size #>4 ulelong =0 \b, blocks size %u # size of blocks not reliable like 0x2020204C in angest.dbt >4 ulelong !0 >>4 ulelong&0x0000003f 0 \b, blocks size %u # dBase IV DBT with positive block length (found 512 , 1024) >20 uleshort >0 \b, block length %u # next available block #>0 lelong =0 \b, next free block index %u >0 lelong !0 \b, next free block index %u >20 uleshort >0 >>(20.s) ubelong x >>>&-4 use dbase4-memofield-print # unusual dBase IV DBT without block length (implies 512 as length) >20 uleshort =0 >>512 ubelong x >>>&-4 use dbase4-memofield-print # Print the information of dBase IV memo field 0 name dbase4-memofield-print # free dBase IV memo field >0 ubelong !0xFFFF0800 >>0 lelong x \b, next free block %u >>4 lelong x \b, next used block %u # used dBase IV memo field >0 ubelong =0xFFFF0800 # length of memo field >>4 lelong x \b, field length %d >>>8 string >\0 \b, 1st used item "%s" # Print the information of FoxPro FPT memo file 0 name foxpro-memo-print >0 belong x FoxPro FPT # Size of blocks for FoxPro ( 64,256 ) >6 ubeshort x \b, blocks size %u # next available block #>0 belong =0 \b, next free block index %u >0 belong !0 \b, next free block index %u # field type ( 0~picture, 1~memo, 2~object ) >512 ubelong <3 \b, field type %u # length of memo field >512 ubelong 1 >>516 belong >0 \b, field length %d >>>520 string >\0 \b, 1st item "%s" # TODO: # DBASE index file *.NDX # DBASE Compound Index file *.CDX # dBASE IV Printer Driver *.PRF ## End of XBase database stuff # MS Access database 4 string Standard\ Jet\ DB Microsoft Access Database !:mime application/x-msaccess 4 string Standard\ ACE\ DB Microsoft Access Database !:mime application/x-msaccess # TDB database from Samba et al - Martin Pool 0 string TDB\ file TDB database >32 lelong 0x2601196D version 6, little-endian >>36 lelong x hash size %d bytes # SE Linux policy database 0 lelong 0xf97cff8c SE Linux policy >16 lelong x v%d >20 lelong 1 MLS >24 lelong x %d symbols >28 lelong x %d ocons # ICE authority file data (Wolfram Kleff) 2 string ICE ICE authority data # X11 Xauthority file (Wolfram Kleff) 10 string MIT-MAGIC-COOKIE-1 X11 Xauthority data 11 string MIT-MAGIC-COOKIE-1 X11 Xauthority data 12 string MIT-MAGIC-COOKIE-1 X11 Xauthority data 13 string MIT-MAGIC-COOKIE-1 X11 Xauthority data 14 string MIT-MAGIC-COOKIE-1 X11 Xauthority data 15 string MIT-MAGIC-COOKIE-1 X11 Xauthority data 16 string MIT-MAGIC-COOKIE-1 X11 Xauthority data 17 string MIT-MAGIC-COOKIE-1 X11 Xauthority data 18 string MIT-MAGIC-COOKIE-1 X11 Xauthority data # From: Maxime Henrion # PostgreSQL's custom dump format, Maxime Henrion 0 string PGDMP PostgreSQL custom database dump >5 byte x - v%d >6 byte x \b.%d >5 beshort <0x101 \b-0 >5 beshort >0x100 >>7 byte x \b-%d # Type: Advanced Data Format (ADF) database # URL: http://www.grc.nasa.gov/WWW/cgns/adf/ # From: Nicolas Chauvat 0 string @(#)ADF\ Database CGNS Advanced Data Format # Tokyo Cabinet magic data # http://tokyocabinet.sourceforge.net/index.html 0 string ToKyO\ CaBiNeT\n Tokyo Cabinet >14 string x \b (%s) >32 byte 0 \b, Hash !:mime application/x-tokyocabinet-hash >32 byte 1 \b, B+ tree !:mime application/x-tokyocabinet-btree >32 byte 2 \b, Fixed-length !:mime application/x-tokyocabinet-fixed >32 byte 3 \b, Table !:mime application/x-tokyocabinet-table >33 byte &1 \b, [open] >33 byte &2 \b, [fatal] >34 byte x \b, apow=%d >35 byte x \b, fpow=%d >36 byte &0x01 \b, [large] >36 byte &0x02 \b, [deflate] >36 byte &0x04 \b, [bzip] >36 byte &0x08 \b, [tcbs] >36 byte &0x10 \b, [excodec] >40 lequad x \b, bnum=%lld >48 lequad x \b, rnum=%lld >56 lequad x \b, fsiz=%lld # Type: QDBM Quick Database Manager # From: Benoit Sibaud 0 string \\[depot\\]\n\f Quick Database Manager, little endian 0 string \\[DEPOT\\]\n\f Quick Database Manager, big endian # Type: TokyoCabinet database # URL: http://tokyocabinet.sourceforge.net/ # From: Benoit Sibaud 0 string ToKyO\ CaBiNeT\n TokyoCabinet database >14 string x (version %s) # From: Stephane Blondon http://www.yaal.fr # Database file for Zope (done by FileStorage) 0 string FS21 Zope Object Database File Storage (data) # Cache file for the database of Zope (done by ClientStorage) 0 string ZEC3 Zope Object Database Client Cache File (data) # IDA (Interactive Disassembler) database 0 string IDA1 IDA (Interactive Disassembler) database #------------------------------------------------------------------------------ # $File$ # diamond: file(1) magic for Diamond system # # ... diamond is a multi-media mail and electronic conferencing system.... # # XXX - I think it was either renamed Slate, or replaced by Slate.... # # The full deal is too long... #0 string \n Diamond Multimedia Document 0 string =\n&0 search/1024 \n >>&0 search/1 +++\ >>>&0 search/1024 \n >>>>&0 search/1 @@ unified diff output text !:mime text/x-diff !:strength + 90 # librsync -- the library for network deltas # # Copyright (C) 2001 by Martin Pool. You may do whatever you want with # this file. # 0 belong 0x72730236 rdiff network-delta data 0 belong 0x72730136 rdiff network-delta signature data >4 belong x (block length=%d, >8 belong x signature strength=%d) #------------------------------------------------------------------------------ # $File: digital,v 1.10 2011/05/03 01:44:17 christos Exp $ # Digital UNIX - Info # 0 string =!\n________64E Alpha archive >22 string X -- out of date # 0 leshort 0603 >24 leshort 0410 COFF format alpha pure >24 leshort 0413 COFF format alpha demand paged >>22 leshort&030000 !020000 executable >>22 leshort&020000 !0 dynamically linked >>16 lelong !0 not stripped >>16 lelong 0 stripped >>27 byte x - version %d >>26 byte x \b.%d >>28 byte x \b-%d >24 leshort 0407 COFF format alpha object >>22 leshort&030000 020000 shared library >>27 byte x - version %d >>26 byte x \b.%d >>28 byte x \b-%d # Basic recognition of Digital UNIX core dumps - Mike Bremford # # The actual magic number is just "Core", followed by a 2-byte version # number; however, treating any file that begins with "Core" as a Digital # UNIX core dump file may produce too many false hits, so we include one # byte of the version number as well; DU 5.0 appears only to be up to # version 2. # 0 string Core\001 Alpha COFF format core dump (Digital UNIX) >24 string >\0 \b, from '%s' 0 string Core\002 Alpha COFF format core dump (Digital UNIX) >24 string >\0 \b, from '%s' # # The next is incomplete, we could tell more about this format, # but its not worth it. 0 leshort 0x188 Alpha compressed COFF 0 leshort 0x18f Alpha u-code object # # # Some other interesting Digital formats, 0 string \377\377\177 ddis/ddif 0 string \377\377\174 ddis/dots archive 0 string \377\377\176 ddis/dtif table data 0 string \033c\033 LN03 output 0 long 04553207 X image # 0 string =!!\n profiling data file # # Locale data tables (MIPS and Alpha). # 0 short 0x0501 locale data table >6 short 0x24 for MIPS >6 short 0x40 for Alpha #------------------------------------------------------------------------------ # $File: dolby,v 1.6 2012/10/31 13:39:42 christos Exp $ # ATSC A/53 aka AC-3 aka Dolby Digital # from http://www.atsc.org/standards/a_52a.pdf # corrections, additions, etc. are always welcome! # # syncword 0 beshort 0x0b77 ATSC A/52 aka AC-3 aka Dolby Digital stream, # Proposed audio/ac3 RFC/4184 !:mime audio/vnd.dolby.dd-raw # fscod >4 byte&0xc0 = 0x00 48 kHz, >4 byte&0xc0 = 0x40 44.1 kHz, >4 byte&0xc0 = 0x80 32 kHz, # is this one used for 96 kHz? >4 byte&0xc0 = 0xc0 reserved frequency, # >5 byte&0x07 = 0x00 \b, complete main (CM) >5 byte&0x07 = 0x01 \b, music and effects (ME) >5 byte&0x07 = 0x02 \b, visually impaired (VI) >5 byte&0x07 = 0x03 \b, hearing impaired (HI) >5 byte&0x07 = 0x04 \b, dialogue (D) >5 byte&0x07 = 0x05 \b, commentary (C) >5 byte&0x07 = 0x06 \b, emergency (E) >5 beshort&0x07e0 0x0720 \b, voiceover (VO) >5 beshort&0x07e0 >0x0720 \b, karaoke # acmod >6 byte&0xe0 = 0x00 1+1 front, >>6 byte&0x10 = 0x10 LFE on, >6 byte&0xe0 = 0x20 1 front/0 rear, >>6 byte&0x10 = 0x10 LFE on, >6 byte&0xe0 = 0x40 2 front/0 rear, # dsurmod (for stereo only) >>6 byte&0x18 = 0x00 Dolby Surround not indicated >>6 byte&0x18 = 0x08 not Dolby Surround encoded >>6 byte&0x18 = 0x10 Dolby Surround encoded >>6 byte&0x18 = 0x18 reserved Dolby Surround mode >>6 byte&0x04 = 0x04 LFE on, >6 byte&0xe0 = 0x60 3 front/0 rear, >>6 byte&0x04 = 0x04 LFE on, >6 byte&0xe0 = 0x80 2 front/1 rear, >>6 byte&0x04 = 0x04 LFE on, >6 byte&0xe0 = 0xa0 3 front/1 rear, >>6 byte&0x01 = 0x01 LFE on, >6 byte&0xe0 = 0xc0 2 front/2 rear, >>6 byte&0x04 = 0x04 LFE on, >6 byte&0xe0 = 0xe0 3 front/2 rear, >>6 byte&0x01 = 0x01 LFE on, # >4 byte&0x3e = 0x00 \b, 32 kbit/s >4 byte&0x3e = 0x02 \b, 40 kbit/s >4 byte&0x3e = 0x04 \b, 48 kbit/s >4 byte&0x3e = 0x06 \b, 56 kbit/s >4 byte&0x3e = 0x08 \b, 64 kbit/s >4 byte&0x3e = 0x0a \b, 80 kbit/s >4 byte&0x3e = 0x0c \b, 96 kbit/s >4 byte&0x3e = 0x0e \b, 112 kbit/s >4 byte&0x3e = 0x10 \b, 128 kbit/s >4 byte&0x3e = 0x12 \b, 160 kbit/s >4 byte&0x3e = 0x14 \b, 192 kbit/s >4 byte&0x3e = 0x16 \b, 224 kbit/s >4 byte&0x3e = 0x18 \b, 256 kbit/s >4 byte&0x3e = 0x1a \b, 320 kbit/s >4 byte&0x3e = 0x1c \b, 384 kbit/s >4 byte&0x3e = 0x1e \b, 448 kbit/s >4 byte&0x3e = 0x20 \b, 512 kbit/s >4 byte&0x3e = 0x22 \b, 576 kbit/s >4 byte&0x3e = 0x24 \b, 640 kbit/s #------------------------------------------------------------------------------ # $File: dump,v 1.12 2012/11/01 04:26:40 christos Exp $ # dump: file(1) magic for dump file format--for new and old dump filesystems # # We specify both byte orders in order to recognize byte-swapped dumps. # 0 name new-dump-be >4 bedate x Previous dump %s, >8 bedate x This dump %s, >12 belong >0 Volume %d, >692 belong 0 Level zero, type: >692 belong >0 Level %d, type: >0 belong 1 tape header, >0 belong 2 beginning of file record, >0 belong 3 map of inodes on tape, >0 belong 4 continuation of file record, >0 belong 5 end of volume, >0 belong 6 map of inodes deleted, >0 belong 7 end of medium (for floppy), >676 string >\0 Label %s, >696 string >\0 Filesystem %s, >760 string >\0 Device %s, >824 string >\0 Host %s, >888 belong >0 Flags %x 0 name old-dump-be #>4 bedate x Previous dump %s, #>8 bedate x This dump %s, >12 belong >0 Volume %d, >692 belong 0 Level zero, type: >692 belong >0 Level %d, type: >0 belong 1 tape header, >0 belong 2 beginning of file record, >0 belong 3 map of inodes on tape, >0 belong 4 continuation of file record, >0 belong 5 end of volume, >0 belong 6 map of inodes deleted, >0 belong 7 end of medium (for floppy), >676 string >\0 Label %s, >696 string >\0 Filesystem %s, >760 string >\0 Device %s, >824 string >\0 Host %s, >888 belong >0 Flags %x 0 name ufs2-dump-be >896 beqdate x Previous dump %s, >904 beqdate x This dump %s, >12 belong >0 Volume %d, >692 belong 0 Level zero, type: >692 belong >0 Level %d, type: >0 belong 1 tape header, >0 belong 2 beginning of file record, >0 belong 3 map of inodes on tape, >0 belong 4 continuation of file record, >0 belong 5 end of volume, >0 belong 6 map of inodes deleted, >0 belong 7 end of medium (for floppy), >676 string >\0 Label %s, >696 string >\0 Filesystem %s, >760 string >\0 Device %s, >824 string >\0 Host %s, >888 belong >0 Flags %x 24 belong 60012 new-fs dump file (big endian), >0 use new-dump-be 24 belong 60011 old-fs dump file (big endian), >0 use old-dump-be 24 lelong 60012 new-fs dump file (little endian), >0 use \^new-dump-be 24 lelong 60011 old-fs dump file (little endian), >0 use \^old-dump-be 24 belong 0x19540119 new-fs dump file (ufs2, big endian), >0 use ufs2-dump-be 24 lelong 0x19540119 new-fs dump file (ufs2, little endian), >0 use \^ufs2-dump-be 18 leshort 60011 old-fs dump file (16-bit, assuming PDP-11 endianness), >2 medate x Previous dump %s, >6 medate x This dump %s, >10 leshort >0 Volume %d, >0 leshort 1 tape header. >0 leshort 2 beginning of file record. >0 leshort 3 map of inodes on tape. >0 leshort 4 continuation of file record. >0 leshort 5 end of volume. >0 leshort 6 map of inodes deleted. >0 leshort 7 end of medium (for floppy). #------------------------------------------------------------------------------ # $File: dyadic,v 1.5 2010/09/20 18:55:20 rrt Exp $ # Dyadic: file(1) magic for Dyalog APL. # # updated by Joerg Jenderek at Oct 2013 # http://en.wikipedia.org/wiki/Dyalog_APL # http://www.dyalog.com/ # .DXV Dyalog APL External Variable # .DIN Dyalog APL Input Table # .DOT Dyalog APL Output Table # .DFT Dyalog APL Format File 0 ubeshort&0xFF60 0xaa00 # skip biblio.dbt >1 byte !4 # real Dyalog APL have non zero version numbers like 7.3 or 13.4 >>2 ubeshort >0x0000 Dyalog APL >>>1 byte 0x00 aplcore #>>>1 byte 0x00 incomplete workspace # *.DCF Dyalog APL Component File >>>1 byte 0x01 component file 32-bit non-journaled non-checksummed #>>>1 byte 0x01 component file >>>1 byte 0x02 external variable exclusive #>>>1 byte 0x02 external variable # *.DWS Dyalog APL Workspace >>>1 byte 0x03 workspace >>>>7 byte&0x28 0x00 32-bit >>>>7 byte&0x28 0x20 64-bit >>>>7 byte&0x0c 0x00 classic >>>>7 byte&0x0c 0x04 unicode >>>>7 byte&0x88 0x00 big-endian >>>>7 byte&0x88 0x80 little-endian >>>1 byte 0x06 external variable shared # *.DSE Dyalog APL Session , *.DLF Dyalog APL Session Log File >>>1 byte 0x07 session >>>1 byte 0x08 mapped file 32-bit >>>1 byte 0x09 component file 64-bit non-journaled non-checksummed >>>1 byte 0x0a mapped file 64-bit >>>1 byte 0x0b component file 32-bit level 1 journaled non-checksummed >>>1 byte 0x0c component file 64-bit level 1 journaled non-checksummed >>>1 byte 0x0d component file 32-bit level 1 journaled checksummed >>>1 byte 0x0e component file 64-bit level 1 journaled checksummed >>>1 byte 0x0f component file 32-bit level 2 journaled checksummed >>>1 byte 0x10 component file 64-bit level 2 journaled checksummed >>>1 byte 0x11 component file 32-bit level 3 journaled checksummed >>>1 byte 0x12 component file 64-bit level 3 journaled checksummed >>>1 byte 0x13 component file 32-bit non-journaled checksummed >>>1 byte 0x14 component file 64-bit non-journaled checksummed >>>1 byte 0x80 DDB >>>2 byte x version %d >>>3 byte x \b.%d #>>>2 byte x type %d #>>>3 byte x subtype %d # *.DXF Dyalog APL Transfer File 0 short 0x6060 Dyalog APL transfer #------------------------------------------------------------------------------ # $File$ # ebml: file(1) magic for various Extensible Binary Meta Language # http://www.matroska.org/technical/specs/index.html#track 0 belong 0x1a45dfa3 EBML file >4 search/b/100 \102\202 >>&1 string x \b, creator %.8s #------------------------------------------------------------------------------ # $File$ # T602 editor documents # by David Necas 0 string @CT\ T602 document data, >4 string 0 Kamenicky >4 string 1 CP 852 >4 string 2 KOI8-CS >4 string >2 unknown encoding # Vi IMproved Encrypted file # by David Necas 0 string VimCrypt~ Vim encrypted file data # Vi IMproved Swap file # by Sven Wegener 0 string b0VIM\ Vim swap file >&0 string >\0 \b, version %s #------------------------------------------------------------------------------ # $File: efi,v 1.4 2009/09/19 16:28:09 christos Exp $ # efi: file(1) magic for Universal EFI binaries 0 lelong 0x0ef1fab9 >4 lelong 1 Universal EFI binary with 1 architecture >>&0 lelong 7 \b, i386 >>&0 lelong 0x01000007 \b, x86_64 >4 lelong 2 Universal EFI binary with 2 architectures >>&0 lelong 7 \b, i386 >>&0 lelong 0x01000007 \b, x86_64 >>&20 lelong 7 \b, i386 >>&20 lelong 0x01000007 \b, x86_64 >4 lelong >2 Universal EFI binary with %d architectures #------------------------------------------------------------------------------ # $File: elf,v 1.67 2014/06/12 13:52:48 christos Exp $ # elf: file(1) magic for ELF executables # # We have to check the byte order flag to see what byte order all the # other stuff in the header is in. # # What're the correct byte orders for the nCUBE and the Fujitsu VPP500? # # Created by: unknown # Modified by (1): Daniel Quinlan # Modified by (2): Peter Tobias (core support) # Modified by (3): Christian 'Dr. Disk' Hechelmann (fix of core support) # Modified by (4): (VMS Itanium) # Modified by (5): Matthias Urlichs (Listing of many architectures) 0 name elf-le >16 leshort 0 no file type, !:mime application/octet-stream >16 leshort 1 relocatable, !:mime application/x-object >16 leshort 2 executable, !:mime application/x-executable >16 leshort 3 shared object, !:mime application/x-sharedlib >16 leshort 4 core file !:mime application/x-coredump # Core file detection is not reliable. #>>>(0x38+0xcc) string >\0 of '%s' #>>>(0x38+0x10) lelong >0 (signal %d), >16 leshort &0xff00 processor-specific, >18 clear x >18 leshort 0 no machine, >18 leshort 1 AT&T WE32100, >18 leshort 2 SPARC, >18 leshort 3 Intel 80386, >18 leshort 4 Motorola m68k, >>4 byte 1 >>>36 lelong &0x01000000 68000, >>>36 lelong &0x00810000 CPU32, >>>36 lelong 0 68020, >18 leshort 5 Motorola m88k, >18 leshort 6 Intel 80486, >18 leshort 7 Intel 80860, # The official e_machine number for MIPS is now #8, regardless of endianness. # The second number (#10) will be deprecated later. For now, we still # say something if #10 is encountered, but only gory details for #8. >18 leshort 8 MIPS, >>4 byte 1 >>>36 lelong &0x20 N32 >18 leshort 10 MIPS, >>4 byte 1 >>>36 lelong &0x20 N32 >18 leshort 8 # only for 32-bit >>4 byte 1 >>>36 lelong&0xf0000000 0x00000000 MIPS-I >>>36 lelong&0xf0000000 0x10000000 MIPS-II >>>36 lelong&0xf0000000 0x20000000 MIPS-III >>>36 lelong&0xf0000000 0x30000000 MIPS-IV >>>36 lelong&0xf0000000 0x40000000 MIPS-V >>>36 lelong&0xf0000000 0x50000000 MIPS32 >>>36 lelong&0xf0000000 0x60000000 MIPS64 >>>36 lelong&0xf0000000 0x70000000 MIPS32 rel2 >>>36 lelong&0xf0000000 0x80000000 MIPS64 rel2 # only for 64-bit >>4 byte 2 >>>48 lelong&0xf0000000 0x00000000 MIPS-I >>>48 lelong&0xf0000000 0x10000000 MIPS-II >>>48 lelong&0xf0000000 0x20000000 MIPS-III >>>48 lelong&0xf0000000 0x30000000 MIPS-IV >>>48 lelong&0xf0000000 0x40000000 MIPS-V >>>48 lelong&0xf0000000 0x50000000 MIPS32 >>>48 lelong&0xf0000000 0x60000000 MIPS64 >>>48 lelong&0xf0000000 0x70000000 MIPS32 rel2 >>>48 lelong&0xf0000000 0x80000000 MIPS64 rel2 >18 leshort 9 Amdahl, >18 leshort 10 MIPS (deprecated), >18 leshort 11 RS6000, >18 leshort 15 PA-RISC, # only for 32-bit >>4 byte 1 >>>38 leshort 0x0214 2.0 >>>36 leshort &0x0008 (LP64) # only for 64-bit >>4 byte 2 >>>50 leshort 0x0214 2.0 >>>48 leshort &0x0008 (LP64) >18 leshort 16 nCUBE, >18 leshort 17 Fujitsu VPP500, >18 leshort 18 SPARC32PLUS, # only for 32-bit >>4 byte 1 >>>36 lelong&0xffff00 0x000100 V8+ Required, >>>36 lelong&0xffff00 0x000200 Sun UltraSPARC1 Extensions Required, >>>36 lelong&0xffff00 0x000400 HaL R1 Extensions Required, >>>36 lelong&0xffff00 0x000800 Sun UltraSPARC3 Extensions Required, >18 leshort 19 Intel 80960, >18 leshort 20 PowerPC or cisco 4500, >18 leshort 21 64-bit PowerPC or cisco 7500, >18 leshort 22 IBM S/390, >18 leshort 23 Cell SPU, >18 leshort 24 cisco SVIP, >18 leshort 25 cisco 7200, >18 leshort 36 NEC V800 or cisco 12000, >18 leshort 37 Fujitsu FR20, >18 leshort 38 TRW RH-32, >18 leshort 39 Motorola RCE, >18 leshort 40 ARM, >>4 byte 1 >>>36 lelong&0xff000000 0x04000000 EABI4 >>>36 lelong&0xff000000 0x05000000 EABI5 >>>36 lelong &0x00800000 BE8 >>>36 lelong &0x00400000 LE8 >18 leshort 41 Alpha, >18 leshort 42 Renesas SH, >18 leshort 43 SPARC V9, >>4 byte 2 >>>48 lelong&0xffff00 0x000200 Sun UltraSPARC1 Extensions Required, >>>48 lelong&0xffff00 0x000400 HaL R1 Extensions Required, >>>48 lelong&0xffff00 0x000800 Sun UltraSPARC3 Extensions Required, >>>48 lelong&0x3 0 total store ordering, >>>48 lelong&0x3 1 partial store ordering, >>>48 lelong&0x3 2 relaxed memory ordering, >18 leshort 44 Siemens Tricore Embedded Processor, >18 leshort 45 Argonaut RISC Core, Argonaut Technologies Inc., >18 leshort 46 Renesas H8/300, >18 leshort 47 Renesas H8/300H, >18 leshort 48 Renesas H8S, >18 leshort 49 Renesas H8/500, >18 leshort 50 IA-64, >18 leshort 51 Stanford MIPS-X, >18 leshort 52 Motorola Coldfire, >18 leshort 53 Motorola M68HC12, >18 leshort 54 Fujitsu MMA, >18 leshort 55 Siemens PCP, >18 leshort 56 Sony nCPU, >18 leshort 57 Denso NDR1, >18 leshort 58 Start*Core, >18 leshort 59 Toyota ME16, >18 leshort 60 ST100, >18 leshort 61 Tinyj emb., >18 leshort 62 x86-64, >18 leshort 63 Sony DSP, >18 leshort 64 DEC PDP-10, >18 leshort 65 DEC PDP-11, >18 leshort 66 FX66, >18 leshort 67 ST9+ 8/16 bit, >18 leshort 68 ST7 8 bit, >18 leshort 69 MC68HC16, >18 leshort 70 MC68HC11, >18 leshort 71 MC68HC08, >18 leshort 72 MC68HC05, >18 leshort 73 SGI SVx or Cray NV1, >18 leshort 74 ST19 8 bit, >18 leshort 75 Digital VAX, >18 leshort 76 Axis cris, >18 leshort 77 Infineon 32-bit embedded, >18 leshort 78 Element 14 64-bit DSP, >18 leshort 79 LSI Logic 16-bit DSP, >18 leshort 80 MMIX, >18 leshort 81 Harvard machine-independent, >18 leshort 82 SiTera Prism, >18 leshort 83 Atmel AVR 8-bit, >18 leshort 84 Fujitsu FR30, >18 leshort 85 Mitsubishi D10V, >18 leshort 86 Mitsubishi D30V, >18 leshort 87 NEC v850, >18 leshort 88 Renesas M32R, >18 leshort 89 Matsushita MN10300, >18 leshort 90 Matsushita MN10200, >18 leshort 91 picoJava, >18 leshort 92 OpenRISC, >18 leshort 93 ARC Cores Tangent-A5, >18 leshort 94 Tensilica Xtensa, >18 leshort 95 Alphamosaic VideoCore, >18 leshort 96 Thompson Multimedia, >18 leshort 97 NatSemi 32k, >18 leshort 98 Tenor Network TPC, >18 leshort 99 Trebia SNP 1000, >18 leshort 100 STMicroelectronics ST200, >18 leshort 101 Ubicom IP2022, >18 leshort 102 MAX Processor, >18 leshort 103 NatSemi CompactRISC, >18 leshort 104 Fujitsu F2MC16, >18 leshort 105 TI msp430, >18 leshort 106 Analog Devices Blackfin, >18 leshort 107 S1C33 Family of Seiko Epson, >18 leshort 108 Sharp embedded, >18 leshort 109 Arca RISC, >18 leshort 110 PKU-Unity Ltd., >18 leshort 111 eXcess: 16/32/64-bit, >18 leshort 112 Icera Deep Execution Processor, >18 leshort 113 Altera Nios II, >18 leshort 114 NatSemi CRX, >18 leshort 115 Motorola XGATE, >18 leshort 116 Infineon C16x/XC16x, >18 leshort 117 Renesas M16C series, >18 leshort 118 Microchip dsPIC30F, >18 leshort 119 Freescale RISC core, >18 leshort 120 Renesas M32C series, >18 leshort 131 Altium TSK3000 core, >18 leshort 132 Freescale RS08, >18 leshort 134 Cyan Technology eCOG2, >18 leshort 135 Sunplus S+core7 RISC, >18 leshort 136 New Japan Radio (NJR) 24-bit DSP, >18 leshort 137 Broadcom VideoCore III, >18 leshort 138 LatticeMico32, >18 leshort 139 Seiko Epson C17 family, >18 leshort 140 TI TMS320C6000 DSP family, >18 leshort 141 TI TMS320C2000 DSP family, >18 leshort 142 TI TMS320C55x DSP family, >18 leshort 160 STMicroelectronics 64bit VLIW DSP, >18 leshort 161 Cypress M8C, >18 leshort 162 Renesas R32C series, >18 leshort 163 NXP TriMedia family, >18 leshort 164 QUALCOMM DSP6, >18 leshort 165 Intel 8051 and variants, >18 leshort 166 STMicroelectronics STxP7x family, >18 leshort 167 Andes embedded RISC, >18 leshort 168 Cyan eCOG1X family, >18 leshort 169 Dallas MAXQ30, >18 leshort 170 New Japan Radio (NJR) 16-bit DSP, >18 leshort 171 M2000 Reconfigurable RISC, >18 leshort 172 Cray NV2 vector architecture, >18 leshort 173 Renesas RX family, >18 leshort 174 META, >18 leshort 175 MCST Elbrus, >18 leshort 176 Cyan Technology eCOG16 family, >18 leshort 177 NatSemi CompactRISC, >18 leshort 178 Freescale Extended Time Processing Unit, >18 leshort 179 Infineon SLE9X, >18 leshort 180 Intel L1OM, >18 leshort 181 Intel K1OM, >18 leshort 183 ARM aarch64, >18 leshort 185 Atmel 32-bit family, >18 leshort 186 STMicroeletronics STM8 8-bit, >18 leshort 187 Tilera TILE64, >18 leshort 188 Tilera TILEPro, >18 leshort 189 Xilinx MicroBlaze 32-bit RISC, >18 leshort 190 NVIDIA CUDA architecture, >18 leshort 191 Tilera TILE-Gx, >18 leshort 197 Renesas RL78 family, >18 leshort 199 Renesas 78K0R, >18 leshort 200 Freescale 56800EX, >18 leshort 201 Beyond BA1, >18 leshort 202 Beyond BA2, >18 leshort 203 XMOS xCORE, >18 leshort 204 Microchip 8-bit PIC(r), >18 leshort 210 KM211 KM32, >18 leshort 211 KM211 KMX32, >18 leshort 212 KM211 KMX16, >18 leshort 213 KM211 KMX8, >18 leshort 214 KM211 KVARC, >18 leshort 215 Paneve CDP, >18 leshort 216 Cognitive Smart Memory, >18 leshort 217 iCelero CoolEngine, >18 leshort 218 Nanoradio Optimized RISC, >18 leshort 243 UCB RISC-V, >18 leshort 0x1057 AVR (unofficial), >18 leshort 0x1059 MSP430 (unofficial), >18 leshort 0x1223 Adapteva Epiphany (unofficial), >18 leshort 0x2530 Morpho MT (unofficial), >18 leshort 0x3330 FR30 (unofficial), >18 leshort 0x3426 OpenRISC (obsolete), >18 leshort 0x4688 Infineon C166 (unofficial), >18 leshort 0x5441 Cygnus FRV (unofficial), >18 leshort 0x5aa5 DLX (unofficial), >18 leshort 0x7650 Cygnus D10V (unofficial), >18 leshort 0x7676 Cygnus D30V (unofficial), >18 leshort 0x8217 Ubicom IP2xxx (unofficial), >18 leshort 0x8472 OpenRISC (obsolete), >18 leshort 0x9025 Cygnus PowerPC (unofficial), >18 leshort 0x9026 Alpha (unofficial), >18 leshort 0x9041 Cygnus M32R (unofficial), >18 leshort 0x9080 Cygnus V850 (unofficial), >18 leshort 0xa390 IBM S/390 (obsolete), >18 leshort 0xabc7 Old Xtensa (unofficial), >18 leshort 0xad45 xstormy16 (unofficial), >18 leshort 0xbaab Old MicroBlaze (unofficial),, >18 leshort 0xbeef Cygnus MN10300 (unofficial), >18 leshort 0xdead Cygnus MN10200 (unofficial), >18 leshort 0xf00d Toshiba MeP (unofficial), >18 leshort 0xfeb0 Renesas M32C (unofficial), >18 leshort 0xfeba Vitesse IQ2000 (unofficial), >18 leshort 0xfebb NIOS (unofficial), >18 leshort 0xfeed Moxie (unofficial), >18 default x >>18 leshort x *unknown arch 0x%x* >20 lelong 0 invalid version >20 lelong 1 version 1 0 string \177ELF ELF !:strength *2 >4 byte 0 invalid class >4 byte 1 32-bit >4 byte 2 64-bit >5 byte 0 invalid byte order >5 byte 1 LSB >>0 use elf-le >5 byte 2 MSB >>0 use \^elf-le # Up to now only 0, 1 and 2 are defined; I've seen a file with 0x83, it seemed # like proper ELF, but extracting the string had bad results. >4 byte <0x80 >>8 string >\0 (%s) >8 string \0 >>7 byte 0 (SYSV) >>7 byte 1 (HP-UX) >>7 byte 2 (NetBSD) >>7 byte 3 (GNU/Linux) >>7 byte 4 (GNU/Hurd) >>7 byte 5 (86Open) >>7 byte 6 (Solaris) >>7 byte 7 (Monterey) >>7 byte 8 (IRIX) >>7 byte 9 (FreeBSD) >>7 byte 10 (Tru64) >>7 byte 11 (Novell Modesto) >>7 byte 12 (OpenBSD) >8 string \2 >>7 byte 13 (OpenVMS) >>7 byte 97 (ARM) >>7 byte 255 (embedded) #------------------------------------------------------------------------------ # $File: encore,v 1.6 2009/09/19 16:28:09 christos Exp $ # encore: file(1) magic for Encore machines # # XXX - needs to have the byte order specified (NS32K was little-endian, # dunno whether they run the 88K in little-endian mode or not). # 0 short 0x154 Encore >20 short 0x107 executable >20 short 0x108 pure executable >20 short 0x10b demand-paged executable >20 short 0x10f unsupported executable >12 long >0 not stripped >22 short >0 - version %d >22 short 0 - #>4 date x stamp %s 0 short 0x155 Encore unsupported executable >12 long >0 not stripped >22 short >0 - version %d >22 short 0 - #>4 date x stamp %s #------------------------------------------------------------------------------ # $File: epoc,v 1.8 2012/06/16 14:43:36 christos Exp $ # EPOC : file(1) magic for EPOC documents [Psion Series 5/Osaris/Geofox 1] # Stefan Praszalowicz and Peter Breitenlohner # Useful information for improving this file can be found at: # http://software.frodo.looijaard.name/psiconv/formats/Index.html #------------------------------------------------------------------------------ 0 lelong 0x10000037 Psion Series 5 >4 lelong 0x10000039 font file >4 lelong 0x1000003A printer driver >4 lelong 0x1000003B clipboard >4 lelong 0x10000042 multi-bitmap image !:mime image/x-epoc-mbm >4 lelong 0x1000006A application information file >4 lelong 0x1000006D >>8 lelong 0x1000007D Sketch image !:mime image/x-epoc-sketch >>8 lelong 0x1000007E voice note >>8 lelong 0x1000007F Word file !:mime application/x-epoc-word >>8 lelong 0x10000085 OPL program (TextEd) !:mime application/x-epoc-opl >>8 lelong 0x10000087 Comms settings >>8 lelong 0x10000088 Sheet file !:mime application/x-epoc-sheet >>8 lelong 0x100001C4 EasyFax initialisation file >4 lelong 0x10000073 OPO module !:mime application/x-epoc-opo >4 lelong 0x10000074 OPL application !:mime application/x-epoc-app >4 lelong 0x1000008A exported multi-bitmap image >4 lelong 0x1000016D >>8 lelong 0x10000087 Comms names 0 lelong 0x10000041 Psion Series 5 ROM multi-bitmap image 0 lelong 0x10000050 Psion Series 5 >4 lelong 0x1000006D database >>8 lelong 0x10000084 Agenda file !:mime application/x-epoc-agenda >>8 lelong 0x10000086 Data file !:mime application/x-epoc-data >>8 lelong 0x10000CEA Jotter file !:mime application/x-epoc-jotter >4 lelong 0x100000E4 ini file 0 lelong 0x10000079 Psion Series 5 binary: >4 lelong 0x00000000 DLL >4 lelong 0x10000049 comms hardware library >4 lelong 0x1000004A comms protocol library >4 lelong 0x1000005D OPX >4 lelong 0x1000006C application >4 lelong 0x1000008D DLL >4 lelong 0x100000AC logical device driver >4 lelong 0x100000AD physical device driver >4 lelong 0x100000E5 file transfer protocol >4 lelong 0x100000E5 file transfer protocol >4 lelong 0x10000140 printer definition >4 lelong 0x10000141 printer definition 0 lelong 0x1000007A Psion Series 5 executable #------------------------------------------------------------------------------ # $File: erlang,v 1.5 2009/09/19 16:28:09 christos Exp $ # erlang: file(1) magic for Erlang JAM and BEAM files # URL: http://www.erlang.org/faq/x779.html#AEN812 # OTP R3-R4 0 string \0177BEAM! Old Erlang BEAM file >6 short >0 - version %d # OTP R5 and onwards 0 string FOR1 >8 string BEAM Erlang BEAM file # 4.2 version may have a copyright notice! 4 string Tue\ Jan\ 22\ 14:32:44\ MET\ 1991 Erlang JAM file - version 4.2 79 string Tue\ Jan\ 22\ 14:32:44\ MET\ 1991 Erlang JAM file - version 4.2 4 string 1.0\ Fri\ Feb\ 3\ 09:55:56\ MET\ 1995 Erlang JAM file - version 4.3 0 bequad 0x0000000000ABCDEF Erlang DETS file #------------------------------------------------------------------------------ # $File$ # ESRI Shapefile format (.shp .shx .dbf=DBaseIII) # Based on info from # 0 belong 9994 ESRI Shapefile >4 belong =0 >8 belong =0 >12 belong =0 >16 belong =0 >20 belong =0 >28 lelong x version %d >24 belong x length %d >32 lelong =0 type Null Shape >32 lelong =1 type Point >32 lelong =3 type PolyLine >32 lelong =5 type Polygon >32 lelong =8 type MultiPoint >32 lelong =11 type PointZ >32 lelong =13 type PolyLineZ >32 lelong =15 type PolygonZ >32 lelong =18 type MultiPointZ >32 lelong =21 type PointM >32 lelong =23 type PolyLineM >32 lelong =25 type PolygonM >32 lelong =28 type MultiPointM >32 lelong =31 type MultiPatch #------------------------------------------------------------------------------ # $File$ # fcs: file(1) magic for FCS (Flow Cytometry Standard) data files # From Roger Leigh 0 string FCS1.0 Flow Cytometry Standard (FCS) data, version 1.0 0 string FCS2.0 Flow Cytometry Standard (FCS) data, version 2.0 0 string FCS3.0 Flow Cytometry Standard (FCS) data, version 3.0 #------------------------------------------------------------------------------ # $File: filesystems,v 1.108 2015/01/01 17:43:47 christos Exp $ # filesystems: file(1) magic for different filesystems # 0 name partid >0 ubyte 0x00 Unused >0 ubyte 0x01 12-bit FAT >0 ubyte 0x02 XENIX / >0 ubyte 0x03 XENIX /usr >0 ubyte 0x04 16-bit FAT, less than 32M >0 ubyte 0x05 extended partition >0 ubyte 0x06 16-bit FAT, more than 32M >0 ubyte 0x07 OS/2 HPFS, NTFS, QNX2, Adv. UNIX >0 ubyte 0x08 AIX or os, or etc. >0 ubyte 0x09 AIX boot partition or Coherent >0 ubyte 0x0a O/2 boot manager or Coherent swap >0 ubyte 0x0b 32-bit FAT >0 ubyte 0x0c 32-bit FAT, LBA-mapped >0 ubyte 0x0d 7XXX, LBA-mapped >0 ubyte 0x0e 16-bit FAT, LBA-mapped >0 ubyte 0x0f extended partition, LBA-mapped >0 ubyte 0x10 OPUS >0 ubyte 0x11 OS/2 DOS 12-bit FAT >0 ubyte 0x12 Compaq diagnostics >0 ubyte 0x14 OS/2 DOS 16-bit FAT <32M >0 ubyte 0x16 OS/2 DOS 16-bit FAT >=32M >0 ubyte 0x17 OS/2 hidden IFS >0 ubyte 0x18 AST Windows swapfile >0 ubyte 0x19 Willowtech Photon coS >0 ubyte 0x1b hidden win95 fat 32 >0 ubyte 0x1c hidden win95 fat 32 lba >0 ubyte 0x1d hidden win95 fat 16 lba >0 ubyte 0x20 Willowsoft OFS1 >0 ubyte 0x21 reserved >0 ubyte 0x23 reserved >0 ubyte 0x24 NEC DOS >0 ubyte 0x26 reserved >0 ubyte 0x31 reserved >0 ubyte 0x32 Alien Internet Services NOS >0 ubyte 0x33 reserved >0 ubyte 0x34 reserved >0 ubyte 0x35 JFS on OS2 >0 ubyte 0x36 reserved >0 ubyte 0x38 Theos >0 ubyte 0x39 Plan 9, or Theos spanned >0 ubyte 0x3a Theos ver 4 4gb partition >0 ubyte 0x3b Theos ve 4 extended partition >0 ubyte 0x3c PartitionMagic recovery >0 ubyte 0x3d Hidden Netware >0 ubyte 0x40 VENIX 286 or LynxOS >0 ubyte 0x41 PReP >0 ubyte 0x42 linux swap sharing DRDOS disk >0 ubyte 0x43 linux sharing DRDOS disk >0 ubyte 0x44 GoBack change utility >0 ubyte 0x45 Boot US Boot manager >0 ubyte 0x46 EUMEL/Elan or Ergos 3 >0 ubyte 0x47 EUMEL/Elan or Ergos 3 >0 ubyte 0x48 EUMEL/Elan or Ergos 3 >0 ubyte 0x4a ALFX/THIN filesystem for DOS >0 ubyte 0x4c Oberon partition >0 ubyte 0x4d QNX4.x >0 ubyte 0x4e QNX4.x 2nd part >0 ubyte 0x4f QNX4.x 3rd part >0 ubyte 0x50 DM (disk manager) >0 ubyte 0x51 DM6 Aux1 (or Novell) >0 ubyte 0x52 CP/M or Microport SysV/AT >0 ubyte 0x53 DM6 Aux3 >0 ubyte 0x54 DM6 DDO >0 ubyte 0x55 EZ-Drive (disk manager) >0 ubyte 0x56 Golden Bow (disk manager) >0 ubyte 0x57 Drive PRO >0 ubyte 0x5c Priam Edisk (disk manager) >0 ubyte 0x61 SpeedStor >0 ubyte 0x63 GNU HURD or Mach or Sys V/386 >0 ubyte 0x64 Novell Netware 2.xx or Speedstore >0 ubyte 0x65 Novell Netware 3.xx >0 ubyte 0x66 Novell 386 Netware >0 ubyte 0x67 Novell >0 ubyte 0x68 Novell >0 ubyte 0x69 Novell >0 ubyte 0x70 DiskSecure Multi-Boot >0 ubyte 0x71 reserved >0 ubyte 0x73 reserved >0 ubyte 0x74 reserved >0 ubyte 0x75 PC/IX >0 ubyte 0x76 reserved >0 ubyte 0x77 M2FS/M2CS partition >0 ubyte 0x78 XOSL boot loader filesystem >0 ubyte 0x80 MINIX until 1.4a >0 ubyte 0x81 MINIX since 1.4b >0 ubyte 0x82 Linux swap or Solaris >0 ubyte 0x83 Linux native >0 ubyte 0x84 OS/2 hidden C: drive >0 ubyte 0x85 Linux extended partition >0 ubyte 0x86 NT FAT volume set >0 ubyte 0x87 NTFS volume set or HPFS mirrored >0 ubyte 0x8a Linux Kernel AiR-BOOT partition >0 ubyte 0x8b Legacy Fault tolerant FAT32 >0 ubyte 0x8c Legacy Fault tolerant FAT32 ext >0 ubyte 0x8d Hidden free FDISK FAT12 >0 ubyte 0x8e Linux Logical Volume Manager >0 ubyte 0x90 Hidden free FDISK FAT16 >0 ubyte 0x91 Hidden free FDISK DOS EXT >0 ubyte 0x92 Hidden free FDISK FAT16 Big >0 ubyte 0x93 Amoeba filesystem >0 ubyte 0x94 Amoeba bad block table >0 ubyte 0x95 MIT EXOPC native partitions >0 ubyte 0x97 Hidden free FDISK FAT32 >0 ubyte 0x98 Datalight ROM-DOS Super-Boot >0 ubyte 0x99 Mylex EISA SCSI >0 ubyte 0x9a Hidden free FDISK FAT16 LBA >0 ubyte 0x9b Hidden free FDISK EXT LBA >0 ubyte 0x9f BSDI? >0 ubyte 0xa0 IBM Thinkpad hibernation >0 ubyte 0xa1 HP Volume expansion (SpeedStor) >0 ubyte 0xa3 HP Volume expansion (SpeedStor) >0 ubyte 0xa4 HP Volume expansion (SpeedStor) >0 ubyte 0xa5 386BSD partition type >0 ubyte 0xa6 OpenBSD partition type >0 ubyte 0xa7 NeXTSTEP 486 >0 ubyte 0xa8 Apple UFS >0 ubyte 0xa9 NetBSD partition type >0 ubyte 0xaa Olivetty Fat12 1.44MB Service part >0 ubyte 0xab Apple Boot >0 ubyte 0xae SHAG OS filesystem >0 ubyte 0xaf Apple HFS >0 ubyte 0xb0 BootStar Dummy >0 ubyte 0xb1 reserved >0 ubyte 0xb3 reserved >0 ubyte 0xb4 reserved >0 ubyte 0xb6 reserved >0 ubyte 0xb7 BSDI BSD/386 filesystem >0 ubyte 0xb8 BSDI BSD/386 swap >0 ubyte 0xbb Boot Wizard Hidden >0 ubyte 0xbe Solaris 8 partition type >0 ubyte 0xbf Solaris partition type >0 ubyte 0xc0 CTOS >0 ubyte 0xc1 DRDOS/sec (FAT-12) >0 ubyte 0xc2 Hidden Linux >0 ubyte 0xc3 Hidden Linux swap >0 ubyte 0xc4 DRDOS/sec (FAT-16, < 32M) >0 ubyte 0xc5 DRDOS/sec (EXT) >0 ubyte 0xc6 DRDOS/sec (FAT-16, >= 32M) >0 ubyte 0xc7 Syrinx (Cyrnix?) or HPFS disabled >0 ubyte 0xc8 Reserved for DR-DOS 8.0+ >0 ubyte 0xc9 Reserved for DR-DOS 8.0+ >0 ubyte 0xca Reserved for DR-DOS 8.0+ >0 ubyte 0xcb DR-DOS 7.04+ Secured FAT32 CHS >0 ubyte 0xcc DR-DOS 7.04+ Secured FAT32 LBA >0 ubyte 0xcd CTOS Memdump >0 ubyte 0xce DR-DOS 7.04+ FAT16X LBA >0 ubyte 0xcf DR-DOS 7.04+ EXT LBA >0 ubyte 0xd0 REAL/32 secure big partition >0 ubyte 0xd1 Old Multiuser DOS FAT12 >0 ubyte 0xd4 Old Multiuser DOS FAT16 Small >0 ubyte 0xd5 Old Multiuser DOS Extended >0 ubyte 0xd6 Old Multiuser DOS FAT16 Big >0 ubyte 0xd8 CP/M 86 >0 ubyte 0xdb CP/M or Concurrent CP/M >0 ubyte 0xdd Hidden CTOS Memdump >0 ubyte 0xde Dell PowerEdge Server utilities >0 ubyte 0xdf DG/UX virtual disk manager >0 ubyte 0xe0 STMicroelectronics ST AVFS >0 ubyte 0xe1 DOS access or SpeedStor 12-bit >0 ubyte 0xe3 DOS R/O or Storage Dimensions >0 ubyte 0xe4 SpeedStor 16-bit FAT < 1024 cyl. >0 ubyte 0xe5 reserved >0 ubyte 0xe6 reserved >0 ubyte 0xeb BeOS >0 ubyte 0xee GPT Protective MBR >0 ubyte 0xef EFI system partition >0 ubyte 0xf0 Linux PA-RISC boot loader >0 ubyte 0xf1 SpeedStor or Storage Dimensions >0 ubyte 0xf2 DOS 3.3+ Secondary >0 ubyte 0xf3 reserved >0 ubyte 0xf4 SpeedStor large partition >0 ubyte 0xf5 Prologue multi-volumen partition >0 ubyte 0xf6 reserved >0 ubyte 0xf9 pCache: ext2/ext3 persistent cache >0 ubyte 0xfa Bochs x86 emulator >0 ubyte 0xfb VMware File System >0 ubyte 0xfc VMware Swap >0 ubyte 0xfd Linux RAID partition persistent sb >0 ubyte 0xfe LANstep or IBM PS/2 IML >0 ubyte 0xff Xenix Bad Block Table 0 string \366\366\366\366 PC formatted floppy with no filesystem # Sun disk labels # From /usr/include/sun/dklabel.h: 0774 beshort 0xdabe # modified by Joerg Jenderek, because original test # succeeds for Cabinet archive dao360.dl_ with negative blocks >0770 long >0 Sun disk label >>0 string x '%s >>>31 string >\0 \b%s >>>>63 string >\0 \b%s >>>>>95 string >\0 \b%s >>0 string x \b' >>0734 short >0 %d rpm, >>0736 short >0 %d phys cys, >>0740 short >0 %d alts/cyl, >>0746 short >0 %d interleave, >>0750 short >0 %d data cyls, >>0752 short >0 %d alt cyls, >>0754 short >0 %d heads/partition, >>0756 short >0 %d sectors/track, >>0764 long >0 start cyl %d, >>0770 long x %d blocks # Is there a boot block written 1 sector in? >512 belong&077777777 0600407 \b, boot block present # Joerg Jenderek: Smart Boot Manager backup file is 25 (MSDOS) or 41 (LINUX) byte header + first sectors of disk # (http://btmgr.sourceforge.net/docs/user-guide-3.html) 0 string SBMBAKUP_ Smart Boot Manager backup file >9 string x \b, version %-5.5s >>14 string =_ >>>15 string x %-.1s >>>>16 string =_ \b. >>>>>17 string x \b%-.1s >>>>>>18 string =_ \b. >>>>>>>19 string x \b%-.1s >>>22 ubyte 0 >>>>21 ubyte x \b, from drive 0x%x >>>22 ubyte >0 >>>>21 string x \b, from drive %s >>>535 search/17 \x55\xAA >>>>&-512 indirect x \b; contains # updated by Joerg Jenderek at Nov 2012 # DOS Emulator image is 128 byte, null right padded header + harddisc image 0 string DOSEMU\0 >0x27E leshort 0xAA55 #offset is 128 >>19 ubyte 128 >>>(19.b-1) ubyte 0x0 DOS Emulator image >>>>7 ulelong >0 \b, %u heads >>>>11 ulelong >0 \b, %d sectors/track >>>>15 ulelong >0 \b, %d cylinders >>>>128 indirect x \b; contains # added by Joerg Jenderek at Nov 2012 # http://www.thenakedpc.com/articles/v04/08/0408-05.html # Symantec (Peter Norton) Image.dat file consists of variable header, bootrecord, part of FAT and root directory data 0 string PNCIHISK\0 Norton Utilities disc image data # real x86 boot sector with jump instruction >509 search/1026 \x55\xAA\xeb >>&-1 indirect x \b; contains # http://file-extension.net/seeker/file_extension_dat 0 string PNCIUNDO Norton Disk Doctor UnDo file # # DOS/MBR boot sector updated by Joerg Jenderek at Sep 2007,May 2011,2013 # for any allowed sector sizes 30 search/481 \x55\xAA # to display DOS/MBR boot sector (40) before old one (strength=50+21),Syslinux bootloader (71),SYSLINUX MBR (37+36),NetBSD mbr (110),AdvanceMAME mbr (111) # DOS BPB information (70) and after DOS floppy (120) like in previous file version !:strength +65 # for sector sizes < 512 Bytes >11 uleshort <512 >>(11.s-2) uleshort 0xAA55 DOS/MBR boot sector # for sector sizes with 512 or more Bytes >0x1FE leshort 0xAA55 DOS/MBR boot sector # keep old DOS/MBR boot sector as dummy for mbr and bootloader displaying # only for sector sizes with 512 or more Bytes 0x1FE leshort 0xAA55 DOS/MBR boot sector # # to display information (50) before DOS BPB (strength=70) and after DOS floppy (120) like in old file version !:strength +65 >2 string OSBS OS/BS MBR # added by Joerg Jenderek at Feb 2013 according to http://thestarman.pcministry.com/asm/mbr/ # and http://en.wikipedia.org/wiki/Master_Boot_Record # test for nearly all MS-DOS Master Boot Record initial program loader (IPL) is now done by # characteristic assembler instructions: xor ax,ax;mov ss,ax;mov sp,7c00 >0 search/2 \x33\xc0\x8e\xd0\xbc\x00\x7c MS-MBR # Microsoft Windows 95A and early ( http://thestarman.pcministry.com/asm/mbr/STDMBR.htm ) # assembler instructions: mov si,sp;push ax;pop es;push ax;pop ds;sti;cld >>8 ubequad 0x8bf45007501ffbfc # http://thestarman.pcministry.com/asm/mbr/200MBR.htm >>>0x16 ubyte 0xF3 \b,DOS 2 >>>>219 regex Author\ -\ Author: # found "David Litton" , "A Pehrsson " >>>>>&0 string x "%s" >>>0x16 ubyte 0xF2 # NEC MS-DOS 3.30 Rev. 3 . See http://thestarman.pcministry.com/asm/mbr/DOS33MBR.htm # assembler instructions: mov di,077c;cmp word ptrl[di],a55a;jnz >>>>0x22 ubequad 0xbf7c07813d5aa575 \b,NEC 3.3 # version MS-DOS 3.30 til MS-Windows 95A (WinVer=4.00.1111) >>>>0x22 default x \b,D0S version 3.3-7.0 # error messages are printed by assembler instructions: mov si,06nn;...;int 10 (0xBEnn06;...) # where nn is string offset varying for different languages # "Invalid partition table" nn=0x8b for english version >>>>>(0x49.b) string Invalid\ partition\ table english >>>>>(0x49.b) string Ung\201ltige\ Partitionstabelle german >>>>>(0x49.b) string Table\ de\ partition\ invalide french >>>>>(0x49.b) string Tabela\ de\ parti\207ao\ inv\240lida portuguese >>>>>(0x49.b) string Tabla\ de\ partici\242n\ no\ v\240lida spanish >>>>>(0x49.b) string Tavola\ delle\ partizioni\ non\ valida italian >>>>>0x49 ubyte >0 at offset 0x%x >>>>>>(0x49.b) string >\0 "%s" # "Error loading operating system" nn=0xa3 for english version # "Fehler beim Laden des Betriebssystems" nn=0xa7 for german version # "Erreur en chargeant syst\212me d'exploitation" nn=0xa7 for french version # "Erro na inicializa\207ao do sistema operacional" nn=0xa7 for portuguese Brazilian version # "Error al cargar sistema operativo" nn=0xa8 for spanish version # "Errore durante il caricamento del sistema operativo" nn=0xae for italian version >>>>>0x74 ubyte >0 at offset 0x%x >>>>>>(0x74.b) string >\0 "%s" # "Missing operating system" nn=0xc2 for english version # "Betriebssystem fehlt" nn=0xcd for german version # "Syst\212me d'exploitation absent" nn=0xd2 for french version # "Sistema operacional nao encontrado" nn=0xd4 for portuguese Brazilian version # "Falta sistema operativo" nn=0xca for spanish version # "Sistema operativo mancante" nn=0xe2 for italian version >>>>>0x79 ubyte >0 at offset 0x%x >>>>>>(0x79.b) string >\0 "%s" # Microsoft Windows 95B to XP (http://thestarman.pcministry.com/asm/mbr/95BMEMBR.htm) # assembler instructions: push ax;pop es;push ax;pop ds;cld;mov si,7c1b >>8 ubequad 0x5007501ffcbe1b7c # assembler instructions: rep;movsb;retf;mov si,07be;mov cl,04 >>>24 ubequad 0xf3a4cbbebe07b104 9M # "Invalid partition table" nn=0x10F for english version # "Ung\201ltige Partitionstabelle" nn=0x10F for german version # "Table de partition erron\202e" nn=0x10F for french version # "\216\257\245\340\240\346\250\256\255\255\240\357 \341\250\341\342\245\254\240 \255\245 \255\240\251\244\245\255\240" nn=0x10F for russian version >>>>(0x3C.b+0x0FF) string Invalid\ partition\ table english >>>>(0x3C.b+0x0FF) string Ung\201ltige\ Partitionstabelle german >>>>(0x3C.b+0x0FF) string Table\ de\ partition\ erron\202e french >>>>(0x3C.b+0x0FF) string \215\245\257\340\240\242\250\253\354\255\240\357\ \342\240\241\253\250\346\240 russian >>>>0x3C ubyte x at offset 0x%x+0xFF >>>>(0x3C.b+0x0FF) string >\0 "%s" # "Error loading operating system" nn=0x127 for english version # "Fehler beim Laden des Betriebssystems" nn=0x12b for german version # "Erreur lors du chargement du syst\212me d'exploitation" nn=0x12a for french version # "\216\350\250\241\252\240 \257\340\250 \247\240\243\340\343\247\252\245 \256\257\245\340\240\346\250\256\255\255\256\251 \341\250\341\342\245\254\353" nn=0x12d for russian version >>>>0xBD ubyte x at offset 0x1%x >>>>(0xBD.b+0x100) string >\0 "%s" # "Missing operating system" nn=0x146 for english version # "Betriebssystem fehlt" nn=0x151 for german version # "Syst\212me d'exploitation manquant" nn=0x15e for french version # "\216\257\245\340\240\346\250\256\255\255\240\357 \341\250\341\342\245\254\240 \255\245 \255\240\251\244\245\255\240" nn=0x156 for russian version >>>>0xA9 ubyte x at offset 0x1%x >>>>(0xA9.b+0x100) string >\0 "%s" # http://thestarman.pcministry.com/asm/mbr/Win2kmbr.htm # assembler instructions: rep;movsb;retf;mov BP,07be;mov cl,04 >>>24 ubequad 0xf3a4cbbdbe07b104 XP # where xxyyzz are lower bits from offsets of error messages varying for different languages >>>>0x1B4 ubelong&0x00FFFFFF 0x002c4463 english >>>>0x1B4 ubelong&0x00FFFFFF 0x002c486e german # "Invalid partition table" xx=0x12C for english version # "Ung\201ltige Partitionstabelle" xx=0x12C for german version >>>>0x1b5 ubyte >0 at offset 0x1%x >>>>(0x1b5.b+0x100) string >\0 "%s" # "Error loading operating system" yy=0x144 for english version # "Fehler beim Laden des Betriebssystems" yy=0x148 for german version >>>>0x1b6 ubyte >0 at offset 0x1%x >>>>(0x1b6.b+0x100) string >\0 "%s" # "Missing operating system" zz=0x163 for english version # "Betriebssystem nicht vorhanden" zz=0x16e for german version >>>>0x1b7 ubyte >0 at offset 0x1%x >>>>(0x1b7.b+0x100) string >\0 "%s" # Microsoft Windows Vista or 7 # assembler instructions: ..;mov ds,ax;mov si,7c00;mov di,..00 >>8 ubequad 0xc08ed8be007cbf00 # Microsoft Windows Vista (http://thestarman.pcministry.com/asm/mbr/VistaMBR.htm) # assembler instructions: jnz 0729;cmp ebx,"TCPA" >>>0xEC ubequad 0x753b6681fb544350 Vista # where xxyyzz are lower bits from offsets of error messages varying for different languages >>>>0x1B4 ubelong&0x00FFFFFF 0x00627a99 english #>>>>0x1B4 ubelong&0x00FFFFFF ? german # "Invalid partition table" xx=0x162 for english version # "Ung\201ltige Partitionstabelle" xx=0x1?? for german version >>>>0x1b5 ubyte >0 at offset 0x1%x >>>>(0x1b5.b+0x100) string >\0 "%s" # "Error loading operating system" yy=0x17a for english version # "Fehler beim Laden des Betriebssystems" yy= 0x1?? for german version >>>>0x1b6 ubyte >0 at offset 0x1%x >>>>(0x1b6.b+0x100) string >\0 "%s" # "Missing operating system" zz=0x199 for english version # "Betriebssystem nicht vorhanden" zz=0x1?? for german version >>>>0x1b7 ubyte >0 at offset 0x1%x >>>>(0x1b7.b+0x100) string >\0 "%s" # Microsoft Windows 7 (http://thestarman.pcministry.com/asm/mbr/W7MBR.htm) # assembler instructions: cmp ebx,"TCPA";cmp >>>0xEC ubequad 0x6681fb5443504175 Windows 7 # where xxyyzz are lower bits from offsets of error messages varying for different languages >>>>0x1B4 ubelong&0x00FFFFFF 0x00637b9a english #>>>>0x1B4 ubelong&0x00FFFFFF ? german # "Invalid partition table" xx=0x163 for english version # "Ung\201ltige Partitionstabelle" xx=0x1?? for german version >>>>0x1b5 ubyte >0 at offset 0x1%x >>>>(0x1b5.b+0x100) string >\0 "%s" # "Error loading operating system" yy=0x17b for english version # "Fehler beim Laden des Betriebssystems" yy=0x1?? for german version >>>>0x1b6 ubyte >0 at offset 0x1%x >>>>(0x1b6.b+0x100) string >\0 "%s" # "Missing operating system" zz=0x19a for english version # "Betriebssystem nicht vorhanden" zz=0x1?? for german version >>>>0x1b7 ubyte >0 at offset 0x1%x >>>>(0x1b7.b+0x100) string >\0 "%s" # http://thestarman.pcministry.com/asm/mbr/Win2kmbr.htm#DiskSigs # http://en.wikipedia.org/wiki/MBR_disk_signature#ID >>0x1b8 ulelong >0 \b, disk signature 0x%-.4x # driveID/timestamp for Win 95B,98,98SE and ME. See http://thestarman.pcministry.com/asm/mbr/mystery.htm >>0xDA uleshort 0 >>>0xDC ulelong >0 \b, created # physical drive number (0x80-0xFF) when the Windows wrote that byte to the drive >>>>0xDC ubyte x with driveID 0x%x # hours, minutes and seconds >>>>0xDf ubyte x at %x >>>>0xDe ubyte x \b:%x >>>>0xDd ubyte x \b:%x # special case for Microsoft MS-DOS 3.21 spanish # assembler instructions: cli;mov $0x30,%ax;mov %ax,%ss;mov >0 ubequad 0xfab830008ed0bc00 # assembler instructions: $0x1f00,%sp;mov $0x80cb,%di;add %cl,(%bx,%si);in (%dx),%ax;mov >>8 ubequad 0x1fbfcb800008ed8 MS-MBR,D0S version 3.21 spanish # Microsoft MBR IPL end # dr-dos with some upper-, lowercase variants >0x9D string Invalid\ partition\ table$ >>181 string No\ Operating\ System$ >>>201 string Operating\ System\ load\ error$ \b, DR-DOS MBR, Version 7.01 to 7.03 >0x9D string Invalid\ partition\ table$ >>181 string No\ operating\ system$ >>>201 string Operating\ system\ load\ error$ \b, DR-DOS MBR, Version 7.01 to 7.03 >342 string Invalid\ partition\ table$ >>366 string No\ operating\ system$ >>>386 string Operating\ system\ load\ error$ \b, DR-DOS MBR, version 7.01 to 7.03 >295 string NEWLDR\0 >>302 string Bad\ PT\ $ >>>310 string No\ OS\ $ >>>>317 string OS\ load\ err$ >>>>>329 string Moved\ or\ missing\ IBMBIO.LDR\n\r >>>>>>358 string Press\ any\ key\ to\ continue.\n\r$ >>>>>>>387 string Copyright\ (c)\ 1984,1998 >>>>>>>>411 string Caldera\ Inc.\0 \b, DR-DOS MBR (IBMBIO.LDR) # # tests for different MS-DOS Master Boot Records (MBR) moved and merged # #>0x145 string Default:\ F \b, FREE-DOS MBR #>0x14B string Default:\ F \b, FREE-DOS 1.0 MBR >0x145 search/7 Default:\ F \b, FREE-DOS MBR #>>313 string F0\ .\ .\ . #>>>322 string disk\ 1 #>>>>382 string FAT3 >64 string no\ active\ partition\ found >>96 string read\ error\ while\ reading\ drive \b, FREE-DOS Beta 0.9 MBR # Ranish Partition Manager http://www.ranish.com/part/ >387 search/4 \0\ Error!\r >>378 search/7 Virus! >>>397 search/4 Booting\ >>>>408 search/4 HD1/\0 \b, Ranish MBR ( >>>>>416 string Writing\ changes... \b2.37 >>>>>>438 ubyte x \b,0x%x dots >>>>>>440 ubyte >0 \b,virus check >>>>>>441 ubyte >0 \b,partition %c #2.38,2.42,2.44 >>>>>416 string !Writing\ changes... \b >>>>>>418 ubyte 1 \bvirus check, >>>>>>419 ubyte x \b0x%x seconds >>>>>>420 ubyte&0x0F >0 \b,partition >>>>>>>420 ubyte&0x0F <5 \b %x >>>>>>>420 ubyte&0x0F 0Xf \b ask >>>>>420 ubyte x \b) # # SYSLINUX MBR moved # http://www.acronis.de/ >362 string MBR\ Error\ \0\r >>376 string ress\ any\ key\ to\ >>>392 string boot\ from\ floppy...\0 \b, Acronis MBR # added by Joerg Jenderek # http://www.visopsys.org/ # http://partitionlogic.org.uk/ >309 string No\ bootable\ partition\ found\r >>339 string I/O\ Error\ reading\ boot\ sector\r \b, Visopsys MBR >349 string No\ bootable\ partition\ found\r >>379 string I/O\ Error\ reading\ boot\ sector\r \b, simple Visopsys MBR # bootloader, bootmanager >0x40 string SBML # label with 11 characters of FAT 12 bit filesystem >>43 string SMART\ BTMGR >>>430 string SBMK\ Bad!\r \b, Smart Boot Manager # OEM-ID not always "SBM" #>>>>3 strings SBM >>>>6 string >\0 \b, version %s >382 string XOSLLOADXCF \b, eXtended Operating System Loader >6 string LILO \b, LInux i386 boot LOader >>120 string LILO \b, version 22.3.4 SuSe >>172 string LILO \b, version 22.5.8 Debian # updated by Joerg Jenderek at Oct 2008 # variables according to grub-0.97/stage1/stage1.S or # http://www.gnu.org/software/grub/manual/grub.html#Embedded-data # usual values are marked with comments to get only informations of strange GRUB loaders >342 search/60 \0Geom\0 #>0 ulelong x %x=0x009048EB , 0x2a9048EB 0 >>0x41 ubyte <2 >>>0x3E ubyte >2 \b; GRand Unified Bootloader # 0x3 for 0.5.95,0.93,0.94,0.96 0x4 for 1.90 >>>>0x3E ubyte x \b, stage1 version 0x%x #If it is 0xFF, use a drive passed by BIOS >>>>0x40 ubyte <0xFF \b, boot drive 0x%x # in most case 0,1,0x2e for GRUB 0.5.95 >>>>0x41 ubyte >0 \b, LBA flag 0x%x >>>>0x42 uleshort <0x8000 \b, stage2 address 0x%x #>>>>0x42 uleshort =0x8000 \b, stage2 address 0x%x (usual) >>>>0x42 uleshort >0x8000 \b, stage2 address 0x%x #>>>>0x44 ulelong =1 \b, 1st sector stage2 0x%x (default) >>>>0x44 ulelong >1 \b, 1st sector stage2 0x%x >>>>0x48 uleshort <0x800 \b, stage2 segment 0x%x #>>>>0x48 uleshort =0x800 \b, stage2 segment 0x%x (usual) >>>>0x48 uleshort >0x800 \b, stage2 segment 0x%x >>>>402 string Geom\0Hard\ Disk\0Read\0\ Error\0 >>>>>394 string stage1 \b, GRUB version 0.5.95 >>>>382 string Geom\0Hard\ Disk\0Read\0\ Error\0 >>>>>376 string GRUB\ \0 \b, GRUB version 0.93 or 1.94 >>>>383 string Geom\0Hard\ Disk\0Read\0\ Error\0 >>>>>377 string GRUB\ \0 \b, GRUB version 0.94 >>>>385 string Geom\0Hard\ Disk\0Read\0\ Error\0 >>>>>379 string GRUB\ \0 \b, GRUB version 0.95 or 0.96 >>>>391 string Geom\0Hard\ Disk\0Read\0\ Error\0 >>>>>385 string GRUB\ \0 \b, GRUB version 0.97 # unknown version >>>343 string Geom\0Read\0\ Error\0 >>>>321 string Loading\ stage1.5 \b, GRUB version x.y >>>380 string Geom\0Hard\ Disk\0Read\0\ Error\0 >>>>374 string GRUB\ \0 \b, GRUB version n.m # SYSLINUX bootloader moved >395 string chksum\0\ ERROR!\0 \b, Gujin bootloader # http://www.bcdwb.de/bcdw/index_e.htm >3 string BCDL >>498 string BCDL\ \ \ \ BIN \b, Bootable CD Loader (1.50Z) # mbr partition table entries updated by Joerg Jenderek at Sep 2013 # skip Norton Utilities disc image data >3 string !IHISK # skip Linux style boot sector starting with assember instructions mov 0x7c0,ax; >>0 belong !0xb8c0078e # not Linux kernel >>>514 string !HdrS # not BeOS >>>>422 string !Be\ Boot\ Loader >>>>>32769 string CD001 >>>>>>0 use cdrom # jump over BPB instruction implies DOS bootsector or AdvanceMAME mbr >>>>>0 ubelong&0xFD000000 =0xE9000000 # AdvanceMAME mbr >>>>>>(1.b+2) ubequad 0xfa31c08ed88ec08e >>>>>>>446 use partition-table # mbr, Norton Utilities disc image data, or 2nd,etc. sector of x86 bootloader >>>>>0 ubelong&0xFD000000 !0xE9000000 # skip FSInfosector >>>>>>0 string !RRaA # skip 3rd sector of MS x86 bootloader with assember instructions cli;MOVZX EAX,BYTE PTR [BP+10];MOV ECX, # http://thestarman.pcministry.com/asm/mbr/MSWIN41.htm >>>>>>>0 ubequad !0xfa660fb64610668b # skip 13rd sector of MS x86 bootloader >>>>>>>>0 ubequad !0x660fb64610668b4e # skip sector starting with DOS new line >>>>>>>>>0 string !\r\n # allowed active flag 0,80h-FFh >>>>>>>>>>446 ubyte 0 >>>>>>>>>>>446 use partition-table >>>>>>>>>>446 ubyte >0x7F >>>>>>>>>>>446 use partition-table # TODO: test for extended bootrecord (ebr) moved and merged with mbr partition table entries # mbr partition table entries end # http://www.acronis.de/ #FAT label=ACRONIS\ SZ #OEM-ID=BOOTWIZ0 >442 string Non-system\ disk,\ >>459 string press\ any\ key...\x7\0 \b, Acronis Startup Recovery Loader # updated by Joerg Jenderek at Nov 2012, Sep 2013 # DOS names like F11.SYS or BOOTWIZ.SYS are 8 right space padded bytes+3 bytes # display 1 space >>>447 ubyte x \b >>>477 use DOS-filename # >185 string FDBOOT\ Version\ >>204 string \rNo\ Systemdisk.\ >>>220 string Booting\ from\ harddisk.\n\r >>>245 string Cannot\ load\ from\ harddisk.\n\r >>>>273 string Insert\ Systemdisk\ >>>>>291 string and\ press\ any\ key.\n\r \b, FDBOOT harddisk Bootloader >>>>>>200 string >\0 \b, version %-3s >242 string Bootsector\ from\ C.H.\ Hochst\204 # http://freecode.com/projects/dosfstools dosfstools-n.m/src/mkdosfs.c # updated by Joerg Jenderek at Nov 2012. Use search directive with offset instead of string # skip name "C.H. Hochstaetter" partly because it is sometimes written without umlaut >242 search/127 Bootsector\ from\ C.H.\ Hochst >>278 search/127 No\ Systemdisk.\ Booting\ from\ harddisk # followed by variants with point,CR-NL or NL-CR >>>208 search/261 Cannot\ load\ from\ harddisk. # followed by variants CR-NL or NL-CR >>>>236 search/235 Insert\ Systemdisk\ and\ press\ any\ key. # followed by variants with point,CR-NL or NL-CR >>>>>180 search/96 Disk\ formatted\ with\ WinImage\ \b, WinImage harddisk Bootloader # followed by string like "6.50 (c) 1993-2004 Gilles Vollant" >>>>>>&0 string x \b, version %-4.4s >(1.b+2) ubyte 0xe >>(1.b+3) ubyte 0x1f >>>(1.b+4) ubyte 0xbe # message offset found at (1.b+5) is 0x77 for FAT32 or 0x5b for others >>>>(1.b+5) ubyte&0xd3 0x53 >>>>>(1.b+6) ubyte 0x7c # assembler instructions: lodsb;and al,al;jz 0xb;push si;mov ah, >>>>>>(1.b+7) ubyte 0xac >>>>>>>(1.b+8) ubyte 0x22 >>>>>>>>(1.b+9) ubyte 0xc0 >>>>>>>>>(1.b+10) ubyte 0x74 >>>>>>>>>>(1.b+11) ubyte 0x0b >>>>>>>>>>>(1.b+12) ubyte 0x56 >>>>>>>>>>>>(1.b+13) ubyte 0xb4 \b, mkdosfs boot message display # FAT1X version >>>>>>>>>>>>>(1.b+5) ubyte 0x5b >>>>>>>>>>>>>>0x5b string >\0 "%-s" # FAT32 version >>>>>>>>>>>>>(1.b+5) ubyte 0x77 >>>>>>>>>>>>>>0x77 string >\0 "%-s" >214 string Please\ try\ to\ install\ FreeDOS\ \b, DOS Emulator boot message display #>>244 string from\ dosemu-freedos-*-bin.tgz\r #>>>170 string Sorry,\ could\ not\ load\ an\ #>>>>195 string operating\ system.\r\n # >103 string This\ is\ not\ a\ bootable\ disk.\ >>132 string Please\ insert\ a\ bootable\ >>>157 string floppy\ and\r\n >>>>169 string press\ any\ key\ to\ try\ again...\r \b, FREE-DOS message display # >66 string Solaris\ Boot\ Sector >>99 string Incomplete\ MDBoot\ load. >>>89 string Version \b, Sun Solaris Bootloader >>>>97 byte x version %c # >408 string OS/2\ !!\ SYS01475\r\0 >>429 string OS/2\ !!\ SYS02025\r\0 >>>450 string OS/2\ !!\ SYS02027\r\0 >>>469 string OS2BOOT\ \ \ \ \b, IBM OS/2 Warp bootloader # >409 string OS/2\ !!\ SYS01475\r\0 >>430 string OS/2\ !!\ SYS02025\r\0 >>>451 string OS/2\ !!\ SYS02027\r\0 >>>470 string OS2BOOT\ \ \ \ \b, IBM OS/2 Warp Bootloader >112 string This\ disk\ is\ not\ bootable\r >>142 string If\ you\ wish\ to\ make\ it\ bootable >>>176 string run\ the\ DOS\ program\ SYS\ >>>200 string after\ the\r >>>>216 string system\ has\ been\ loaded\r\n >>>>>242 string Please\ insert\ a\ DOS\ diskette\ >>>>>271 string into\r\n\ the\ drive\ and\ >>>>>>292 string strike\ any\ key...\0 \b, IBM OS/2 Warp message display # XP >430 string NTLDR\ is\ missing\xFF\r\n >>449 string Disk\ error\xFF\r\n >>>462 string Press\ any\ key\ to\ restart\r \b, Microsoft Windows XP Bootloader # DOS names like NTLDR,CMLDR,$LDR$ are 8 right space padded bytes+3 bytes >>>>417 ubyte&0xDF >0 >>>>>417 string x %-.5s >>>>>>422 ubyte&0xDF >0 >>>>>>>422 string x \b%-.3s >>>>>425 ubyte&0xDF >0 >>>>>>425 string >\ \b.%-.3s # >>>>371 ubyte >0x20 >>>>>368 ubyte&0xDF >0 >>>>>>368 string x %-.5s >>>>>>>373 ubyte&0xDF >0 >>>>>>>>373 string x \b%-.3s >>>>>>376 ubyte&0xDF >0 >>>>>>>376 string x \b.%-.3s # >430 string NTLDR\ nicht\ gefunden\xFF\r\n >>453 string Datentr\204gerfehler\xFF\r\n >>>473 string Neustart\ mit\ beliebiger\ Taste\r \b, Microsoft Windows XP Bootloader (german) >>>>417 ubyte&0xDF >0 >>>>>417 string x %-.5s >>>>>>422 ubyte&0xDF >0 >>>>>>>422 string x \b%-.3s >>>>>425 ubyte&0xDF >0 >>>>>>425 string >\ \b.%-.3s # offset variant >>>>379 string \0 >>>>>368 ubyte&0xDF >0 >>>>>>368 string x %-.5s >>>>>>>373 ubyte&0xDF >0 >>>>>>>>373 string x \b%-.3s # >430 string NTLDR\ fehlt\xFF\r\n >>444 string Datentr\204gerfehler\xFF\r\n >>>464 string Neustart\ mit\ beliebiger\ Taste\r \b, Microsoft Windows XP Bootloader (2.german) >>>>417 ubyte&0xDF >0 >>>>>417 string x %-.5s >>>>>>422 ubyte&0xDF >0 >>>>>>>422 string x \b%-.3s >>>>>425 ubyte&0xDF >0 >>>>>>425 string >\ \b.%-.3s # variant >>>>371 ubyte >0x20 >>>>>368 ubyte&0xDF >0 >>>>>>368 string x %-.5s >>>>>>>373 ubyte&0xDF >0 >>>>>>>>373 string x \b%-.3s >>>>>>376 ubyte&0xDF >0 >>>>>>>376 string x \b.%-.3s # >430 string NTLDR\ fehlt\xFF\r\n >>444 string Medienfehler\xFF\r\n >>>459 string Neustart:\ Taste\ dr\201cken\r \b, Microsoft Windows XP Bootloader (3.german) >>>>371 ubyte >0x20 >>>>>368 ubyte&0xDF >0 >>>>>>368 string x %-.5s >>>>>>>373 ubyte&0xDF >0 >>>>>>>>373 string x \b%-.3s >>>>>>376 ubyte&0xDF >0 >>>>>>>376 string x \b.%-.3s # variant >>>>417 ubyte&0xDF >0 >>>>>417 string x %-.5s >>>>>>422 ubyte&0xDF >0 >>>>>>>422 string x \b%-.3s >>>>>425 ubyte&0xDF >0 >>>>>>425 string >\ \b.%-.3s # >430 string Datentr\204ger\ entfernen\xFF\r\n >>454 string Medienfehler\xFF\r\n >>>469 string Neustart:\ Taste\ dr\201cken\r \b, Microsoft Windows XP Bootloader (4.german) >>>>379 string \0 >>>>>368 ubyte&0xDF >0 >>>>>>368 string x %-.5s >>>>>>>373 ubyte&0xDF >0 >>>>>>>>373 string x \b%-.3s >>>>>>376 ubyte&0xDF >0 >>>>>>>376 string x \b.%-.3s # variant >>>>417 ubyte&0xDF >0 >>>>>417 string x %-.5s >>>>>>422 ubyte&0xDF >0 >>>>>>>422 string x \b%-.3s >>>>>425 ubyte&0xDF >0 >>>>>>425 string >\ \b.%-.3s # #>3 string NTFS\ \ \ \ >389 string Fehler\ beim\ Lesen\ >>407 string des\ Datentr\204gers >>>426 string NTLDR\ fehlt >>>>440 string NTLDR\ ist\ komprimiert >>>>>464 string Neustart\ mit\ Strg+Alt+Entf\r \b, Microsoft Windows XP Bootloader NTFS (german) #>3 string NTFS\ \ \ \ >313 string A\ disk\ read\ error\ occurred.\r >>345 string A\ kernel\ file\ is\ missing\ >>>370 string from\ the\ disk.\r >>>>484 string NTLDR\ is\ compressed >>>>>429 string Insert\ a\ system\ diskette\ >>>>>>454 string and\ restart\r\nthe\ system.\r \b, Microsoft Windows XP Bootloader NTFS # DOS loader variants different languages,offsets >472 ubyte&0xDF >0 >>389 string Invalid\ system\ disk\xFF\r\n >>>411 string Disk\ I/O\ error >>>>428 string Replace\ the\ disk,\ and\ >>>>>455 string press\ any\ key \b, Microsoft Windows 98 Bootloader #IO.SYS >>>>>>472 ubyte&0xDF >0 >>>>>>>472 string x \b %-.2s >>>>>>>>474 ubyte&0xDF >0 >>>>>>>>>474 string x \b%-.5s >>>>>>>>>>479 ubyte&0xDF >0 >>>>>>>>>>>479 string x \b%-.1s >>>>>>>480 ubyte&0xDF >0 >>>>>>>>480 string x \b.%-.3s #MSDOS.SYS >>>>>>>483 ubyte&0xDF >0 \b+ >>>>>>>>483 string x \b%-.5s >>>>>>>>>488 ubyte&0xDF >0 >>>>>>>>>>488 string x \b%-.3s >>>>>>>>491 ubyte&0xDF >0 >>>>>>>>>491 string x \b.%-.3s # >>390 string Invalid\ system\ disk\xFF\r\n >>>412 string Disk\ I/O\ error\xFF\r\n >>>>429 string Replace\ the\ disk,\ and\ >>>>>451 string then\ press\ any\ key\r \b, Microsoft Windows 98 Bootloader >>388 string Ungueltiges\ System\ \xFF\r\n >>>410 string E/A-Fehler\ \ \ \ \xFF\r\n >>>>427 string Datentraeger\ wechseln\ und\ >>>>>453 string Taste\ druecken\r \b, Microsoft Windows 95/98/ME Bootloader (german) #WINBOOT.SYS only not spaces (0xDF) >>>>>>497 ubyte&0xDF >0 >>>>>>>497 string x %-.5s >>>>>>>>502 ubyte&0xDF >0 >>>>>>>>>502 string x \b%-.1s >>>>>>>>>>503 ubyte&0xDF >0 >>>>>>>>>>>503 string x \b%-.1s >>>>>>>>>>>>504 ubyte&0xDF >0 >>>>>>>>>>>>>504 string x \b%-.1s >>>>>>505 ubyte&0xDF >0 >>>>>>>505 string x \b.%-.3s #IO.SYS >>>>>>472 ubyte&0xDF >0 or >>>>>>>472 string x \b %-.2s >>>>>>>>474 ubyte&0xDF >0 >>>>>>>>>474 string x \b%-.5s >>>>>>>>>>479 ubyte&0xDF >0 >>>>>>>>>>>479 string x \b%-.1s >>>>>>>480 ubyte&0xDF >0 >>>>>>>>480 string x \b.%-.3s #MSDOS.SYS >>>>>>>483 ubyte&0xDF >0 \b+ >>>>>>>>483 string x \b%-.5s >>>>>>>>>488 ubyte&0xDF >0 >>>>>>>>>>488 string x \b%-.3s >>>>>>>>491 ubyte&0xDF >0 >>>>>>>>>491 string x \b.%-.3s # >>390 string Ungueltiges\ System\ \xFF\r\n >>>412 string E/A-Fehler\ \ \ \ \xFF\r\n >>>>429 string Datentraeger\ wechseln\ und\ >>>>>455 string Taste\ druecken\r \b, Microsoft Windows 95/98/ME Bootloader (German) #WINBOOT.SYS only not spaces (0xDF) >>>>>>497 ubyte&0xDF >0 >>>>>>>497 string x %-.7s >>>>>>>>504 ubyte&0xDF >0 >>>>>>>>>504 string x \b%-.1s >>>>>>505 ubyte&0xDF >0 >>>>>>>505 string x \b.%-.3s #IO.SYS >>>>>>472 ubyte&0xDF >0 or >>>>>>>472 string x \b %-.2s >>>>>>>>474 ubyte&0xDF >0 >>>>>>>>>474 string x \b%-.6s >>>>>>>480 ubyte&0xDF >0 >>>>>>>>480 string x \b.%-.3s #MSDOS.SYS >>>>>>>483 ubyte&0xDF >0 \b+ >>>>>>>>483 string x \b%-.5s >>>>>>>>>488 ubyte&0xDF >0 >>>>>>>>>>488 string x \b%-.3s >>>>>>>>491 ubyte&0xDF >0 >>>>>>>>>491 string x \b.%-.3s # >>389 string Ungueltiges\ System\ \xFF\r\n >>>411 string E/A-Fehler\ \ \ \ \xFF\r\n >>>>428 string Datentraeger\ wechseln\ und\ >>>>>454 string Taste\ druecken\r \b, Microsoft Windows 95/98/ME Bootloader (GERMAN) # DOS names like IO.SYS,WINBOOT.SYS,MSDOS.SYS,WINBOOT.INI are 8 right space padded bytes+3 bytes >>>>>>472 string x %-.2s >>>>>>>474 ubyte&0xDF >0 >>>>>>>>474 string x \b%-.5s >>>>>>>>479 ubyte&0xDF >0 >>>>>>>>>479 string x \b%-.1s >>>>>>480 ubyte&0xDF >0 >>>>>>>480 string x \b.%-.3s >>>>>>483 ubyte&0xDF >0 \b+ >>>>>>>483 string x \b%-.5s >>>>>>>488 ubyte&0xDF >0 >>>>>>>>488 string x \b%-.2s >>>>>>>>490 ubyte&0xDF >0 >>>>>>>>>490 string x \b%-.1s >>>>>>>491 ubyte&0xDF >0 >>>>>>>>491 string x \b.%-.3s >479 ubyte&0xDF >0 >>416 string Kein\ System\ oder\ >>>433 string Laufwerksfehler >>>>450 string Wechseln\ und\ Taste\ dr\201cken \b, Microsoft DOS Bootloader (german) #IO.SYS >>>>>479 string x \b %-.2s >>>>>>481 ubyte&0xDF >0 >>>>>>>481 string x \b%-.6s >>>>>487 ubyte&0xDF >0 >>>>>>487 string x \b.%-.3s #MSDOS.SYS >>>>>>490 ubyte&0xDF >0 \b+ >>>>>>>490 string x \b%-.5s >>>>>>>>495 ubyte&0xDF >0 >>>>>>>>>495 string x \b%-.3s >>>>>>>498 ubyte&0xDF >0 >>>>>>>>498 string x \b.%-.3s # >376 search/41 Non-System\ disk\ or\ >>395 search/41 disk\ error\r >>>407 search/41 Replace\ and\ >>>>419 search/41 press\ \b, >>>>419 search/41 strike\ \b, old >>>>426 search/41 any\ key\ when\ ready\r MS or PC-DOS bootloader #449 Disk\ Boot\ failure\r MS 3.21 #466 Boot\ Failure\r MS 3.30 >>>>>468 search/18 \0 #IO.SYS,IBMBIO.COM >>>>>>&0 string x \b %-.2s >>>>>>>&-20 ubyte&0xDF >0 >>>>>>>>&-1 string x \b%-.4s >>>>>>>>>&-16 ubyte&0xDF >0 >>>>>>>>>>&-1 string x \b%-.2s >>>>>>&8 ubyte&0xDF >0 \b. >>>>>>>&-1 string x \b%-.3s #MSDOS.SYS,IBMDOS.COM >>>>>>&11 ubyte&0xDF >0 \b+ >>>>>>>&-1 string x \b%-.5s >>>>>>>>&-6 ubyte&0xDF >0 >>>>>>>>>&-1 string x \b%-.1s >>>>>>>>>>&-5 ubyte&0xDF >0 >>>>>>>>>>>&-1 string x \b%-.2s >>>>>>>&7 ubyte&0xDF >0 \b. >>>>>>>>&-1 string x \b%-.3s >441 string Cannot\ load\ from\ harddisk.\n\r >>469 string Insert\ Systemdisk\ >>>487 string and\ press\ any\ key.\n\r \b, MS (2.11) DOS bootloader #>43 string \224R-LOADER\ \ SYS =label >54 string SYS >>324 string VASKK >>>495 string NEWLDR\0 \b, DR-DOS Bootloader (LOADER.SYS) # >98 string Press\ a\ key\ to\ retry\0\r >>120 string Cannot\ find\ file\ \0\r >>>139 string Disk\ read\ error\0\r >>>>156 string Loading\ ...\0 \b, DR-DOS (3.41) Bootloader #DRBIOS.SYS >>>>>44 ubyte&0xDF >0 >>>>>>44 string x \b %-.6s >>>>>>>50 ubyte&0xDF >0 >>>>>>>>50 string x \b%-.2s >>>>>>52 ubyte&0xDF >0 >>>>>>>52 string x \b.%-.3s # >70 string IBMBIO\ \ COM >>472 string Cannot\ load\ DOS!\ >>>489 string Any\ key\ to\ retry \b, DR-DOS Bootloader >>471 string Cannot\ load\ DOS\ >>487 string press\ key\ to\ retry \b, Open-DOS Bootloader #?? >444 string KERNEL\ \ SYS >>314 string BOOT\ error! \b, FREE-DOS Bootloader >499 string KERNEL\ \ SYS >>305 string BOOT\ err!\0 \b, Free-DOS Bootloader >449 string KERNEL\ \ SYS >>319 string BOOT\ error! \b, FREE-DOS 0.5 Bootloader # >449 string Loading\ FreeDOS >>0x1AF ulelong >0 \b, FREE-DOS 0.95,1.0 Bootloader >>>497 ubyte&0xDF >0 >>>>497 string x \b %-.6s >>>>>503 ubyte&0xDF >0 >>>>>>503 string x \b%-.1s >>>>>>>504 ubyte&0xDF >0 >>>>>>>>504 string x \b%-.1s >>>>505 ubyte&0xDF >0 >>>>>505 string x \b.%-.3s # >331 string Error!.0 \b, FREE-DOS 1.0 bootloader # >125 string Loading\ FreeDOS...\r >>311 string BOOT\ error!\r \b, FREE-DOS bootloader >>>441 ubyte&0xDF >0 >>>>441 string x \b %-.6s >>>>>447 ubyte&0xDF >0 >>>>>>447 string x \b%-.1s >>>>>>>448 ubyte&0xDF >0 >>>>>>>>448 string x \b%-.1s >>>>449 ubyte&0xDF >0 >>>>>449 string x \b.%-.3s >124 string FreeDOS\0 >>331 string \ err\0 \b, FREE-DOS BETa 0.9 Bootloader # DOS names like KERNEL.SYS,KERNEL16.SYS,KERNEL32.SYS,METAKERN.SYS are 8 right space padded bytes+3 bytes >>>497 ubyte&0xDF >0 >>>>497 string x \b %-.6s >>>>>503 ubyte&0xDF >0 >>>>>>503 string x \b%-.1s >>>>>>>504 ubyte&0xDF >0 >>>>>>>>504 string x \b%-.1s >>>>505 ubyte&0xDF >0 >>>>>505 string x \b.%-.3s >>333 string \ err\0 \b, FREE-DOS BEta 0.9 Bootloader >>>497 ubyte&0xDF >0 >>>>497 string x \b %-.6s >>>>>503 ubyte&0xDF >0 >>>>>>503 string x \b%-.1s >>>>>>>504 ubyte&0xDF >0 >>>>>>>>504 string x \b%-.1s >>>>505 ubyte&0xDF >0 >>>>>505 string x \b.%-.3s >>334 string \ err\0 \b, FREE-DOS Beta 0.9 Bootloader >>>497 ubyte&0xDF >0 >>>>497 string x \b %-.6s >>>>>503 ubyte&0xDF >0 >>>>>>503 string x \b%-.1s >>>>>>>504 ubyte&0xDF >0 >>>>>>>>504 string x \b%-.1s >>>>505 ubyte&0xDF >0 >>>>>505 string x \b.%-.3s >336 string Error!\ >>343 string Hit\ a\ key\ to\ reboot. \b, FREE-DOS Beta 0.9sr1 Bootloader >>>497 ubyte&0xDF >0 >>>>497 string x \b %-.6s >>>>>503 ubyte&0xDF >0 >>>>>>503 string x \b%-.1s >>>>>>>504 ubyte&0xDF >0 >>>>>>>>504 string x \b%-.1s >>>>505 ubyte&0xDF >0 >>>>>505 string x \b.%-.3s # added by Joerg Jenderek # http://www.visopsys.org/ # http://partitionlogic.org.uk/ # OEM-ID=Visopsys >478 ulelong 0 >>(1.b+326) string I/O\ Error\ reading\ >>>(1.b+344) string Visopsys\ loader\r >>>>(1.b+361) string Press\ any\ key\ to\ continue.\r \b, Visopsys loader # http://alexfru.chat.ru/epm.html#bootprog >494 ubyte >0x4D >>495 string >E >>>495 string >>>3 string BootProg # It just looks for a program file name at the root directory # and loads corresponding file with following execution. # DOS names like STARTUP.BIN,STARTUPC.COM,STARTUPE.EXE are 8 right space padded bytes+3 bytes >>>>499 ubyte&0xDF >0 \b, COM/EXE Bootloader >>>>>499 use DOS-filename #If the boot sector fails to read any other sector, #it prints a very short message ("RE") to the screen and hangs the computer. #If the boot sector fails to find needed program in the root directory, #it also hangs with another message ("NF"). >>>>>492 string RENF \b, FAT (12 bit) >>>>>495 string RENF \b, FAT (16 bit) #If the boot sector fails to read any other sector, #it prints a very short message ("RE") to the screen and hangs the computer. # x86 bootloader end # added by Joerg Jenderek at Feb 2013 according to http://thestarman.pcministry.com/asm/mbr/MSWIN41.htm#FSINFO # and http://en.wikipedia.org/wiki/File_Allocation_Table#FS_Information_Sector >0 string RRaA >>0x1E4 string rrAa \b, FSInfosector #>>0x1FC uleshort =0 SHOULD BE ZERO >>>0x1E8 ulelong <0xffffffff \b, %u free clusters >>>0x1EC ulelong <0xffffffff \b, last allocated cluster %u # updated by Joerg Jenderek at Sep 2007 >3 ubyte 0 #no active flag >>446 ubyte 0 # partition 1 not empty >>>450 ubyte >0 # partitions 3,4 empty >>>>482 ubyte 0 >>>>>498 ubyte 0 # partition 2 ID=0,5,15 >>>>>>466 ubyte <0x10 >>>>>>>466 ubyte 0x05 \b, extended partition table >>>>>>>466 ubyte 0x0F \b, extended partition table (LBA) >>>>>>>466 ubyte 0x0 \b, extended partition table (last) # DOS x86 sector separated and moved from "DOS/MBR boot sector" by Joerg Jenderek at May 2011 >0x200 lelong 0x82564557 \b, BSD disklabel # by Joerg Jenderek at Apr 2013 # Print the DOS filenames from directory entry form with 8 right space padded bytes + 3 bytes for extension # like IO.SYS. MSDOS.SYS , KERNEL.SYS , DRBIO.SYS 0 name DOS-filename # space=0x20 (00100000b) means empty >0 ubyte&0xDF >0 >>0 ubyte x \b%c >>>1 ubyte&0xDF >0 >>>>1 ubyte x \b%c >>>>>2 ubyte&0xDF >0 >>>>>>2 ubyte x \b%c >>>>>>>3 ubyte&0xDF >0 >>>>>>>>3 ubyte x \b%c >>>>>>>>>4 ubyte&0xDF >0 >>>>>>>>>>4 ubyte x \b%c >>>>>>>>>>>5 ubyte&0xDF >0 >>>>>>>>>>>>5 ubyte x \b%c >>>>>>>>>>>>>6 ubyte&0xDF >0 >>>>>>>>>>>>>>6 ubyte x \b%c >>>>>>>>>>>>>>>7 ubyte&0xDF >0 >>>>>>>>>>>>>>>>7 ubyte x \b%c # DOS filename extension >>8 ubyte&0xDF >0 \b. >>>8 ubyte x \b%c >>>>9 ubyte&0xDF >0 >>>>>9 ubyte x \b%c >>>>>>10 ubyte&0xDF >0 >>>>>>>10 ubyte x \b%c # Print 2 following DOS filenames from directory entry form # like IO.SYS+MSDOS.SYS or ibmbio.com+ibmdos.com 0 name 2xDOS-filename # display 1 space >0 ubyte x \b >0 use DOS-filename >11 ubyte x \b+ >11 use DOS-filename # http://en.wikipedia.org/wiki/Master_boot_record#PTE # display standard partition table 0 name partition-table #>0 ubyte x PARTITION-TABLE # test and display 1st til 4th partition table entry >0 use partition-entry-test >16 use partition-entry-test >32 use partition-entry-test >48 use partition-entry-test # test for entry of partition table 0 name partition-entry-test # partition type ID > 0 >4 ubyte >0 # active flag 0 >>0 ubyte 0 >>>0 use partition-entry # active flag 0x80, 0x81, ... >>0 ubyte >0x7F >>>0 use partition-entry # Print entry of partition table 0 name partition-entry # partition type ID > 0 >4 ubyte >0 \b; partition >>64 leshort 0xAA55 1 >>48 leshort 0xAA55 2 >>32 leshort 0xAA55 3 >>16 leshort 0xAA55 4 >>4 ubyte x : ID=0x%x >>0 ubyte&0x80 0x80 \b, active >>0 ubyte >0x80 0x%x >>1 ubyte x \b, start-CHS ( >>1 use partition-chs >>5 ubyte x \b), end-CHS ( >>5 use partition-chs >>8 ulelong x \b), startsector %u >>12 ulelong x \b, %u sectors # Print cylinder,head,sector (CHS) of partition entry 0 name partition-chs # cylinder >1 ubyte x \b0x >1 ubyte&0xC0 0x40 \b1 >1 ubyte&0xC0 0x80 \b2 >1 ubyte&0xC0 0xC0 \b3 >2 ubyte x \b%x # head >0 ubyte x \b,%u # sector >1 ubyte&0x3F x \b,%u # FATX 0 string FATX FATX filesystem data # romfs filesystems - Juan Cespedes 0 string -rom1fs- romfs filesystem, version 1 >8 belong x %d bytes, >16 string x named %s. # netboot image - Juan Cespedes 0 lelong 0x1b031336L Netboot image, >4 lelong&0xFFFFFF00 0 >>4 lelong&0x100 0x000 mode 2 >>4 lelong&0x100 0x100 mode 3 >4 lelong&0xFFFFFF00 !0 unknown mode 0x18b string OS/2 OS/2 Boot Manager # updated by Joerg Jenderek at Oct 2008 and Sep 2012 # http://syslinux.zytor.com/iso.php # tested with versions 1.47,1.48,1.49,1.50,1.62,1.76,2.00,2.10;3.00,3.11,3.31,;3.70,3.71,3.73,3.75,3.80,3.82,3.84,3.86,4.01,4.03 and 4.05 # assembler instructions: cli;jmp 0:7Cyy (yy=0x40,0x5e,0x6c,0x6e,0x77);nop;nop 0 ulequad&0x909000007cc0eafa 0x909000007c40eafa >631 search/689 ISOLINUX\ isolinux Loader >>&0 string x (version %-4.4s) # http://syslinux.zytor.com/pxe.php # assembler instructions: jmp 7C05 0 ulelong 0x007c05ea pxelinux loader (version 2.13 or older) # assembler instructions: pushfd;pushad 0 ulelong 0x60669c66 pxelinux loader # assembler instructions: jmp 05 0 ulelong 0xc00005ea pxelinux loader (version 3.70 or newer) # http://syslinux.zytor.com/wiki/index.php/SYSLINUX 0 string LDLINUX\ SYS\ SYSLINUX loader >12 string x (older version %-4.4s) 0 string \r\nSYSLINUX\ SYSLINUX loader >11 string x (version %-4.4s) # syslinux updated and separated from "DOS/MBR boot sector" by Joerg Jenderek at Sep 2012 # assembler instructions: jmp yy (yy=0x3c,0x58);nop;"SYSLINUX" 0 ulelong&0x80909bEB 0x009018EB # OEM-ID not always "SYSLINUX" >434 search/47 Boot\ failed # followed by \r\n\0 or :\ >>482 search/132 \0LDLINUX\ SYS Syslinux bootloader (version 2.13 or older) >>1 ubyte 0x58 Syslinux bootloader (version 3.0-3.9) >459 search/30 Boot\ error\r\n\0 >>1 ubyte 0x58 Syslinux bootloader (version 3.10 or newer) # SYSLINUX MBR updated and separated from "DOS/MBR boot sector" by Joerg Jenderek at Sep 2012 # assembler instructions: mov di,0600h;mov cx,0100h 16 search/4 \xbf\x00\x06\xb9\x00\x01 # to display SYSLINUX MBR (36) before old DOS/MBR boot sector one with partition table (strength=50+21) !:strength +36 >94 search/249 Missing\ operating\ system # followed by \r for versions older 3.35 , .\r for versions newer 3.52 and point for other # skip Ranish MBR >>408 search/4 HD1/\0 >>408 default x >>>250 search/118 \0Operating\ system\ load SYSLINUX MBR # followed by "ing " or space >>>>292 search/98 error >>>>>&0 string \r (version 3.35 or older) >>>>>&0 string .\r (version 3.52 or newer) >>>>>&0 default x (version 3.36-3.51 ) >368 search/106 \0Disk\ error\ on\ boot\r\n SYSLINUX GPT-MBR >>156 search/10 \0Boot\ partition\ not\ found\r\n >>>270 search/10 \0OS\ not\ bootable\r\n (version 3.86 or older) >>174 search/10 \0Missing\ OS\r\n >>>189 search/10 \0Multiple\ active\ partitions\r\n (version 4.00 or newer) # SYSLINUX END # NetBSD mbr variants (master-boot-code version 1.22) added by Joerg Jenderek at Nov 2012 # assembler instructions: xor ax,ax;mov ax,ss;mov sp,0x7c00;mov ax, 0 ubequad 0x31c08ed0bc007c8e # mbr_bootsel magic before partition table not reliable with small ipl fragments #>444 uleshort 0xb5e1 >0004 uleshort x # ERRorTeXT >>181 search/166 Error\ \0\r\n NetBSD mbr # NT Drive Serial Number http://thestarman.pcministry.com/asm/mbr/Win2kmbr.htm#DS >>>0x1B8 ubelong >0 \b,Serial 0x%-.8x # BOOTSEL definitions contains assembler instructions: int 0x13;pop dx;push dx;push dx >>>0xbb search/71 \xcd\x13\x5a\x52\x52 \b,bootselector # BOOT_EXTENDED definitions contains assembler instructions: # xchg ecx,edx;addl ecx,edx;movw lba_info,si;movb 0x42,ah;pop dx;push dx;int 0x13 >>>0x96 search/1 \x66\x87\xca\x66\x01\xca\x66\x89\x16\x3a\x07\xbe\x32\x07\xb4\x42\x5a\x52\xcd\x13 \b,boot extended # COM_PORT_VAL definitions contains assembler instructions: outb al,dx;add 5,dl;inb %dx;test 0x40,al >>>0x130 search/55 \xee\x80\xc2\x05\xec\xa8\x40 \b,serial IO # not TERSE_ERROR >>>196 search/106 No\ active\ partition\0 >>>>&0 string Disk\ read\ error\0 >>>>>&0 string No\ operating\ system\0 \b,verbose # not NO_CHS definitions contains assembler instructions: pop dx;push dx;movb $8,ah;int0x13 >>>0x7d search/7 \x5a\x52\xb4\x08\xcd\x13 \b,CHS # not NO_LBA_CHECK definitions contains assembler instructions: movw 0x55aa,bx;movb 0x41,ah;pop dx;push dx;int 0x13 >>>0xa4 search/84 \xbb\xaa\x55\xb4\x41\x5a\x52\xcd\x13 \b,LBA-check # assembler instructions: movw nametab,bx >>>0x26 search/21 \xBB\x94\x07 # not NO_BANNER definitions contains assembler instructions: mov banner,si;call message_crlf >>>>&-9 ubequad&0xBE00f0E800febb94 0xBE0000E80000bb94 >>>>>181 search/166 Error\ \0 # "a: disk" , "Fn: diskn" or "NetBSD MBR boot" >>>>>>&3 string x \b,"%s" >>>446 use partition-table # Andrea Mazzoleni AdvanceCD mbr loader of http://advancemame.sourceforge.net/boot-readme.html # added by Joerg Jenderek at Nov 2012 for versions 1.3 - 1.4 # assembler instructions: jmp short 0x58;nop;ASCII 0 ubequad&0xeb58908000000000 0xeb58900000000000 # assembler instructions: cli;xor ax,ax;mov ds,ax;mov es,ax;mov ss, >(1.b+2) ubequad 0xfa31c08ed88ec08e # Error messages at end of code >>376 string No\ operating\ system\r\n\0 >>>398 string Disk\ error\r\n\0FDD\0HDD\0 >>>>419 string \ EBIOS\r\n\0 AdvanceMAME mbr # Neil Turton mbr loader variant of http://www.chiark.greenend.org.uk/~neilt/mbr/ # added by Joerg Jenderek at Mar 2011 for versions 1.0.0 - 1.1.11 # for 1st version assembler instructions: cld;xor ax,ax;mov DS,ax;MOV ES,AX;mov SI, # or cld;xor ax,ax;mov SS,ax;XOR SP,SP;mov DS, 0 ulequad&0xcE1b40D48EC031FC 0x8E0000D08EC031FC # pointer to the data starting with Neil Turton signature string >(0x1BC.s) string NDTmbr >>&-14 string 1234F\0 Turton mbr ( # parameters also viewed by install-mbr --list >>>(0x1BC.s+7) ubyte x \b%u<= >>>(0x1BC.s+9) ubyte x \bVersion<=%u #>>>(0x1BC.s+8) ubyte x asm_flag_%x >>>(0x1BC.s+8) ubyte&1 1 \b,Y2K-Fix # variant used by testdisk of http://www.cgsecurity.org/wiki/Menu_MBRCode >>>(0x1BC.s+8) ubyte&2 2 \b,TestDisk #0x1~1,..,0x8~4,0x10~F,0x80~A enabled #>>>(0x1BC.s+10) ubyte x \b,flags 0x%x #0x0~1,0x1~2,...,0x3~4,0x4~F,0x7~D default boot #>>>(0x1BC.s+11) ubyte x \b,cfg_def 0x%x # for older versions >>>(0x1BC.s+9) ubyte <2 #>>>>(0x1BC.s+12) ubyte 18 \b,%hhu/18 seconds >>>>(0x1BC.s+12) ubyte !18 \b,%u/18 seconds # floppy A: or B: >>>>(0x1BC.s+13) ubyte <2 \b,floppy 0x%x >>>>(0x1BC.s+13) ubyte >1 # 1st hard disc #>>>>>(0x1BC.s+13) ubyte 0x80 \b,drive 0x%x # not 1st hard disc >>>>>(0x1BC.s+13) ubyte !0x80 \b,drive 0x%x # for version >= 2 maximal timeout can be 65534 >>>(0x1BC.s+9) ubyte >1 #>>>>(0x1BC.s+12) uleshort 18 \b,%u/18 seconds >>>>(0x1BC.s+12) uleshort !18 \b,%u/18 seconds # floppy A: or B: >>>>(0x1BC.s+14) ubyte <2 \b,floppy 0x%x >>>>(0x1BC.s+14) ubyte >1 # 1st hard disc #>>>>>(0x1BC.s+14) ubyte 0x80 \b,drive 0x%x # not 1st hard disc >>>>>(0x1BC.s+14) ubyte !0x80 \b,drive 0x%x >>>0 ubyte x \b) # added by Joerg Jenderek # In the second sector (+0x200) are variables according to grub-0.97/stage2/asm.S or # grub-1.94/kern/i386/pc/startup.S # http://www.gnu.org/software/grub/manual/grub.html#Embedded-data # usual values are marked with comments to get only informations of strange GRUB loaders 0x200 uleshort 0x70EA # found only version 3.{1,2} >0x206 ubeshort >0x0300 # GRUB version (0.5.)95,0.93,0.94,0.96,0.97 > "00" >>0x212 ubyte >0x29 >>>0x213 ubyte >0x29 # not iso9660_stage1_5 #>>>0 ulelong&0x00BE5652 0x00BE5652 >>>>0x213 ubyte >0x29 GRand Unified Bootloader # config_file for stage1_5 is 0xffffffff + default "/boot/grub/stage2" >>>>0x217 ubyte 0xFF stage1_5 >>>>0x217 ubyte <0xFF stage2 >>>>0x206 ubyte x \b version %u >>>>0x207 ubyte x \b.%u # module_size for 1.94 >>>>0x208 ulelong <0xffffff \b, installed partition %u #>>>>0x208 ulelong =0xffffff \b, %lu (default) >>>>0x208 ulelong >0xffffff \b, installed partition %u # GRUB 0.5.95 unofficial >>>>0x20C ulelong&0x2E300000 0x2E300000 # 0=stage2 1=ffs 2=e2fs 3=fat 4=minix 5=reiserfs >>>>>0x20C ubyte x \b, identifier 0x%x #>>>>>0x20D ubyte =0 \b, LBA flag 0x%x (default) >>>>>0x20D ubyte >0 \b, LBA flag 0x%x # GRUB version as string >>>>>0x20E string >\0 \b, GRUB version %-s # for stage1_5 is 0xffffffff + config_file "/boot/grub/stage2" default >>>>>>0x215 ulong 0xffffffff >>>>>>>0x219 string >\0 \b, configuration file %-s >>>>>>0x215 ulong !0xffffffff >>>>>>>0x215 string >\0 \b, configuration file %-s # newer GRUB versions >>>>0x20C ulelong&0x2E300000 !0x2E300000 ##>>>>>0x20C ulelong =0 \b, saved entry %d (usual) >>>>>0x20C ulelong >0 \b, saved entry %d # for 1.94 contains kernel image size # for 0.93,0.94,0.96,0.97 # 0=stage2 1=ffs 2=e2fs 3=fat 4=minix 5=reiserfs 6=vstafs 7=jfs 8=xfs 9=iso9660 a=ufs2 >>>>>0x210 ubyte x \b, identifier 0x%x # The flag for LBA forcing is in most cases 0 #>>>>>0x211 ubyte =0 \b, LBA flag 0x%x (default) >>>>>0x211 ubyte >0 \b, LBA flag 0x%x # GRUB version as string >>>>>0x212 string >\0 \b, GRUB version %-s # for stage1_5 is 0xffffffff + config_file "/boot/grub/stage2" default >>>>>0x217 ulong 0xffffffff >>>>>>0x21b string >\0 \b, configuration file %-s >>>>>0x217 ulong !0xffffffff >>>>>>0x217 string >\0 \b, configuration file %-s # DOS x86 sector updated and separated from "DOS/MBR boot sector" by Joerg Jenderek at May 2011 # JuMP short bootcodeoffset NOP assembler instructions will usually be EB xx 90 # over BIOS parameter block (BPB) # http://thestarman.pcministry.com/asm/2bytejumps.htm#FWD # older drives may use Near JuMP instruction E9 xx xx # minimal short forward jump found 0x29 for bootloaders or 0x0 # maximal short forward jump is 0x7f # OEM-ID is empty or contain readable bytes 0 ulelong&0x804000E9 0x000000E9 !:strength +60 # mtools-3.9.8/msdos.h # usual values are marked with comments to get only informations of strange FAT systems # valid sectorsize must be a power of 2 from 32 to 32768 >11 uleshort&0x001f 0 >>11 uleshort <32769 >>>11 uleshort >31 >>>>21 ubyte&0xf0 0xF0 >>>>>0 ubyte 0xEB DOS/MBR boot sector >>>>>>1 ubyte x \b, code offset 0x%x+2 >>>>>0 ubyte 0xE9 >>>>>>1 uleshort x \b, code offset 0x%x+3 >>>>>3 string >\0 \b, OEM-ID "%-.8s" #http://mirror.href.com/thestarman/asm/debug/debug2.htm#IHC >>>>>>8 string IHC \b cached by Windows 9M >>>>>11 uleshort >512 \b, Bytes/sector %u #>>>>>11 uleshort =512 \b, Bytes/sector %u=512 (usual) >>>>>11 uleshort <512 \b, Bytes/sector %u >>>>>13 ubyte >1 \b, sectors/cluster %u #>>>>>13 ubyte =1 \b, sectors/cluster %u (usual on Floppies) # for lazy FAT32 implementation like Transcend digital photo frame PF830 >>>>>82 string/c fat32 >>>>>>14 uleshort !32 \b, reserved sectors %u #>>>>>>14 uleshort =32 \b, reserved sectors %u (usual Fat32) >>>>>82 string/c !fat32 >>>>>>14 uleshort >1 \b, reserved sectors %u #>>>>>>14 uleshort =1 \b, reserved sectors %u (usual FAT12,FAT16) #>>>>>>14 uleshort 0 \b, reserved sectors %u (usual NTFS) >>>>>16 ubyte >2 \b, FATs %u #>>>>>16 ubyte =2 \b, FATs %u (usual) >>>>>16 ubyte =1 \b, FAT %u >>>>>16 ubyte >0 >>>>>17 uleshort >0 \b, root entries %u #>>>>>17 uleshort =0 \b, root entries %hu=0 (usual Fat32) >>>>>19 uleshort >0 \b, sectors %u (volumes <=32 MB) #>>>>>19 uleshort =0 \b, sectors %hu=0 (usual Fat32) >>>>>21 ubyte >0xF0 \b, Media descriptor 0x%x #>>>>>21 ubyte =0xF0 \b, Media descriptor 0x%x (usual floppy) >>>>>21 ubyte <0xF0 \b, Media descriptor 0x%x >>>>>22 uleshort >0 \b, sectors/FAT %u #>>>>>22 uleshort =0 \b, sectors/FAT %hu=0 (usual Fat32) >>>>>24 uleshort x \b, sectors/track %u >>>>>26 ubyte >2 \b, heads %u #>>>>>26 ubyte =2 \b, heads %u (usual floppy) >>>>>26 ubyte =1 \b, heads %u # valid only for sector sizes with more then 32 Bytes >>>>>11 uleshort >32 # http://en.wikipedia.org/wiki/Design_of_the_FAT_file_system#Extended_BIOS_Parameter_Block # skip for values 2,2Ah,70h,73h,DFh # and continue for extended boot signature values 0,28h,29h,80h >>>>>>38 ubyte&0x56 =0 >>>>>>>28 ulelong >0 \b, hidden sectors %u #>>>>>>>28 ulelong =0 \b, hidden sectors %u (usual floppy) >>>>>>>32 ulelong >0 \b, sectors %u (volumes > 32 MB) #>>>>>>>32 ulelong =0 \b, sectors %u (volumes > 32 MB) # FAT<32 bit specific >>>>>>>82 string/c !fat32 #>>>>>>>>36 ubyte 0x80 \b, physical drive 0x%x=0x80 (usual harddisk) #>>>>>>>>36 ubyte 0 \b, physical drive 0x%x=0 (usual floppy) >>>>>>>>36 ubyte !0x80 >>>>>>>>>36 ubyte !0 \b, physical drive 0x%x # VGA-copy CRC or # in Windows NT bit 0 is a dirty flag to request chkdsk at boot time. bit 1 requests surface scan too >>>>>>>>37 ubyte >0 \b, reserved 0x%x #>>>>>>>>37 ubyte =0 \b, reserved 0x%x # extended boot signatur value is 0x80 for NTFS, 0x28 or 0x29 for others >>>>>>>>38 ubyte !0x29 \b, dos < 4.0 BootSector (0x%x) >>>>>>>>38 ubyte&0xFE =0x28 >>>>>>>>>39 ulelong x \b, serial number 0x%x >>>>>>>>38 ubyte =0x29 >>>>>>>>>43 string >>>>>>>>43 string >NO\ NAME \b, label: "%11.11s" >>>>>>>>>43 string =NO\ NAME \b, unlabeled # there exist some old floppies without word FAT at offset 54 # a word like "FATnm " is only a hint for a FAT size on nm-bits # Normally the number of clusters is calculated by the values of BPP. # if it is small enough FAT is 12 bit, if it is too big enough FAT is 32 bit, # otherwise FAT is 16 bit. # http://homepage.ntlworld.com/jonathan.deboynepollard/FGA/determining-fat-widths.html >>>>>82 string/c !fat32 >>>>>>54 string FAT12 \b, FAT (12 bit) >>>>>>54 string FAT16 \b, FAT (16 bit) >>>>>>54 default x # determinate FAT bit size by media descriptor # small floppies implies FAT12 >>>>>>>21 ubyte <0xF0 \b, FAT (12 bit by descriptor) # with media descriptor F0h floppy or maybe superfloppy with FAT16 >>>>>>>21 ubyte =0xF0 # superfloppy (many sectors) implies FAT16 >>>>>>>>32 ulelong >0xFFFF \b, FAT (16 bit by descriptor+sectors) # no superfloppy with media descriptor F0h implies FAT12 >>>>>>>>32 default x \b, FAT (12 bit by descriptor+sectors) # with media descriptor F8h floppy or hard disc with FAT12 or FAT16 >>>>>>>21 ubyte =0xF8 # 360 KiB with media descriptor F8h, 9 sectors per track ,single sided floppy implies FAT12 >>>>>>>>19 ubequad 0xd002f80300090001 \b, FAT (12 bit by descriptor+geometry) # hard disc with FAT12 or FAT16 >>>>>>>>19 default x \b, FAT (1Y bit by descriptor) # with media descriptor FAh floppy, RAM disc with FAT12 or FAT16 or Tandy hard disc >>>>>>>21 ubyte =0xFA # 320 KiB with media descriptor FAh, 8 sectors per track ,single sided floppy implies FAT12 >>>>>>>>19 ubequad 0x8002fa0200080001 \b, FAT (12 bit by descriptor+geometry) # RAM disc with FAT12 or FAT16 or Tandy hard disc >>>>>>>>19 default x \b, FAT (1Y bit by descriptor) # others are floppy >>>>>>>21 default x \b, FAT (12 bit by descriptor) # FAT32 bit specific >>>>>82 string/c fat32 \b, FAT (32 bit) >>>>>>36 ulelong x \b, sectors/FAT %u # http://technet.microsoft.com/en-us/library/cc977221.aspx >>>>>>40 uleshort >0 \b, extension flags 0x%x #>>>>>>40 uleshort =0 \b, extension flags %hu >>>>>>42 uleshort >0 \b, fsVersion %u #>>>>>>42 uleshort =0 \b, fsVersion %u (usual) >>>>>>44 ulelong >2 \b, rootdir cluster %u #>>>>>>44 ulelong =2 \b, rootdir cluster %u #>>>>>>44 ulelong =1 \b, rootdir cluster %u >>>>>>48 uleshort >1 \b, infoSector %u #>>>>>>48 uleshort =1 \b, infoSector %u (usual) >>>>>>48 uleshort <1 \b, infoSector %u # 0 or 0xFFFF instead of usual 6 means no backup sector >>>>>>50 uleshort =0xFFFF \b, no Backup boot sector >>>>>>50 uleshort =0 \b, no Backup boot sector #>>>>>>50 uleshort =6 \b, Backup boot sector %u (usual) >>>>>>50 default x >>>>>>>50 uleshort x \b, Backup boot sector %u # corrected by Joerg Jenderek at Feb 2011 according to http://thestarman.pcministry.com/asm/mbr/MSWIN41.htm#FSINFO >>>>>>52 ulelong >0 \b, reserved1 0x%x >>>>>>56 ulelong >0 \b, reserved2 0x%x >>>>>>60 ulelong >0 \b, reserved3 0x%x # same structure as FAT1X #>>>>>>64 ubyte =0x80 \b, physical drive 0x%x=80 (usual harddisk) #>>>>>>64 ubyte =0 \b, physical drive 0x%x=0 (usual floppy) >>>>>>64 ubyte !0x80 >>>>>>>64 ubyte >0 \b, physical drive 0x%x # in Windows NT bit 0 is a dirty flag to request chkdsk at boot time. bit 1 requests surface scan too >>>>>>65 ubyte >0 \b, reserved 0x%x >>>>>>66 ubyte !0x29 \b, dos < 4.0 BootSector (0x%x) >>>>>>66 ubyte =0x29 >>>>>>>67 ulelong x \b, serial number 0x%x >>>>>>>71 string >>>>>>71 string >NO\ NAME \b, label: "%11.11s" >>>>>>>71 string =NO\ NAME \b, unlabeled # additional tests for floppy image added by Joerg Jenderek # no fixed disk >>>>>21 ubyte !0xF8 # floppy media with 12 bit FAT >>>>>>54 string !FAT16 # test for FAT after bootsector >>>>>>>(11.s) ulelong&0x00ffffF0 0x00ffffF0 \b, followed by FAT # floppy image !:mime application/x-ima # NTFS specific added by Joerg Jenderek at Mar 2011 according to http://thestarman.pcministry.com/asm/mbr/NTFSBR.htm # and http://homepage.ntlworld.com/jonathan.deboynepollard/FGA/bios-parameter-block.html # 0 FATs >>>>>16 ubyte =0 # 0 root entries >>>>>>17 uleshort =0 # 0 DOS sectors >>>>>>>19 uleshort =0 # 0 sectors/FAT # dos < 4.0 BootSector value found is 0x80 #38 ubyte =0x80 \b, dos < 4.0 BootSector (0x%x) >>>>>>>>22 uleshort =0 \b; NTFS >>>>>>>>>24 uleshort >0 \b, sectors/track %u >>>>>>>>>36 ulelong !0x800080 \b, physical drive 0x%x >>>>>>>>>40 ulequad >0 \b, sectors %lld >>>>>>>>>48 ulequad >0 \b, $MFT start cluster %lld >>>>>>>>>56 ulequad >0 \b, $MFTMirror start cluster %lld # Values 0 to 127 represent MFT record sizes of 0 to 127 clusters. # Values 128 to 255 represent MFT record sizes of 2^(256-N) bytes. >>>>>>>>>64 lelong <256 >>>>>>>>>>64 lelong <128 \b, clusters/RecordSegment %d >>>>>>>>>>64 ubyte >127 \b, bytes/RecordSegment 2^(-1*%i) # Values 0 to 127 represent index block sizes of 0 to 127 clusters. # Values 128 to 255 represent index block sizes of 2^(256-N) byte >>>>>>>>>68 ulelong <256 >>>>>>>>>>68 ulelong <128 \b, clusters/index block %d #>>>>>>>>>>68 ulelong >127 \b, bytes/index block 2^(256-%d) >>>>>>>>>>68 ubyte >127 \b, bytes/index block 2^(-1*%i) >>>>>>>>>72 ulequad x \b, serial number 0%llx >>>>>>>>>80 ulelong >0 \b, checksum 0x%x #>>>>>>>>>80 ulelong =0 \b, checksum 0x%x=0 (usual) >>>>>>>>>0x258 ulelong&0x00009090 =0x00009090 >>>>>>>>>>&-92 indirect x \b; contains # For 2nd NTFS sector added by Joerg Jenderek at Jan 2013 # http://thestarman.pcministry.com/asm/mbr/NTFSbrHexEd.htm # unused assembler instructions JMP y2;NOP;NOP 0x056 ulelong&0xFFFF0FFF 0x909002EB # unicode loadername terminated by CTRL-D >(0.s*2) ulelong&0xFFFFFF00 0x00040000 # loadernames are NTLDR,CMLDR,PELDR,$LDR$ or BOOTMGR >>0x002 lestring16 x Microsoft Windows XP/VISTA bootloader %-5.5s >>0x12 string $ >>>0x0c lestring16 x \b%-2.2s ### DOS,NTFS boot sectors end 9564 lelong 0x00011954 Unix Fast File system [v1] (little-endian), >8404 string x last mounted on %s, #>9504 ledate x last checked at %s, >8224 ledate x last written at %s, >8401 byte x clean flag %d, >8228 lelong x number of blocks %d, >8232 lelong x number of data blocks %d, >8236 lelong x number of cylinder groups %d, >8240 lelong x block size %d, >8244 lelong x fragment size %d, >8252 lelong x minimum percentage of free blocks %d, >8256 lelong x rotational delay %dms, >8260 lelong x disk rotational speed %drps, >8320 lelong 0 TIME optimization >8320 lelong 1 SPACE optimization 42332 lelong 0x19540119 Unix Fast File system [v2] (little-endian) >&-1164 string x last mounted on %s, >&-696 string >\0 volume name %s, >&-304 leqldate x last written at %s, >&-1167 byte x clean flag %d, >&-1168 byte x readonly flag %d, >&-296 lequad x number of blocks %lld, >&-288 lequad x number of data blocks %lld, >&-1332 lelong x number of cylinder groups %d, >&-1328 lelong x block size %d, >&-1324 lelong x fragment size %d, >&-180 lelong x average file size %d, >&-176 lelong x average number of files in dir %d, >&-272 lequad x pending blocks to free %lld, >&-264 lelong x pending inodes to free %d, >&-664 lequad x system-wide uuid %0llx, >&-1316 lelong x minimum percentage of free blocks %d, >&-1248 lelong 0 TIME optimization >&-1248 lelong 1 SPACE optimization 66908 lelong 0x19540119 Unix Fast File system [v2] (little-endian) >&-1164 string x last mounted on %s, >&-696 string >\0 volume name %s, >&-304 leqldate x last written at %s, >&-1167 byte x clean flag %d, >&-1168 byte x readonly flag %d, >&-296 lequad x number of blocks %lld, >&-288 lequad x number of data blocks %lld, >&-1332 lelong x number of cylinder groups %d, >&-1328 lelong x block size %d, >&-1324 lelong x fragment size %d, >&-180 lelong x average file size %d, >&-176 lelong x average number of files in dir %d, >&-272 lequad x pending blocks to free %lld, >&-264 lelong x pending inodes to free %d, >&-664 lequad x system-wide uuid %0llx, >&-1316 lelong x minimum percentage of free blocks %d, >&-1248 lelong 0 TIME optimization >&-1248 lelong 1 SPACE optimization 9564 belong 0x00011954 Unix Fast File system [v1] (big-endian), >7168 belong 0x4c41424c Apple UFS Volume >>7186 string x named %s, >>7176 belong x volume label version %d, >>7180 bedate x created on %s, >8404 string x last mounted on %s, #>9504 bedate x last checked at %s, >8224 bedate x last written at %s, >8401 byte x clean flag %d, >8228 belong x number of blocks %d, >8232 belong x number of data blocks %d, >8236 belong x number of cylinder groups %d, >8240 belong x block size %d, >8244 belong x fragment size %d, >8252 belong x minimum percentage of free blocks %d, >8256 belong x rotational delay %dms, >8260 belong x disk rotational speed %drps, >8320 belong 0 TIME optimization >8320 belong 1 SPACE optimization 42332 belong 0x19540119 Unix Fast File system [v2] (big-endian) >&-1164 string x last mounted on %s, >&-696 string >\0 volume name %s, >&-304 beqldate x last written at %s, >&-1167 byte x clean flag %d, >&-1168 byte x readonly flag %d, >&-296 bequad x number of blocks %lld, >&-288 bequad x number of data blocks %lld, >&-1332 belong x number of cylinder groups %d, >&-1328 belong x block size %d, >&-1324 belong x fragment size %d, >&-180 belong x average file size %d, >&-176 belong x average number of files in dir %d, >&-272 bequad x pending blocks to free %lld, >&-264 belong x pending inodes to free %d, >&-664 bequad x system-wide uuid %0llx, >&-1316 belong x minimum percentage of free blocks %d, >&-1248 belong 0 TIME optimization >&-1248 belong 1 SPACE optimization 66908 belong 0x19540119 Unix Fast File system [v2] (big-endian) >&-1164 string x last mounted on %s, >&-696 string >\0 volume name %s, >&-304 beqldate x last written at %s, >&-1167 byte x clean flag %d, >&-1168 byte x readonly flag %d, >&-296 bequad x number of blocks %lld, >&-288 bequad x number of data blocks %lld, >&-1332 belong x number of cylinder groups %d, >&-1328 belong x block size %d, >&-1324 belong x fragment size %d, >&-180 belong x average file size %d, >&-176 belong x average number of files in dir %d, >&-272 bequad x pending blocks to free %lld, >&-264 belong x pending inodes to free %d, >&-664 bequad x system-wide uuid %0llx, >&-1316 belong x minimum percentage of free blocks %d, >&-1248 belong 0 TIME optimization >&-1248 belong 1 SPACE optimization # ext2/ext3 filesystems - Andreas Dilger # ext4 filesystem - Eric Sandeen # volume label and UUID Russell Coker # http://etbe.coker.com.au/2008/07/08/label-vs-uuid-vs-device/ 0x438 leshort 0xEF53 Linux >0x44c lelong x rev %d >0x43e leshort x \b.%d # No journal? ext2 >0x45c lelong ^0x0000004 ext2 filesystem data >>0x43a leshort ^0x0000001 (mounted or unclean) # Has a journal? ext3 or ext4 >0x45c lelong &0x0000004 # and small INCOMPAT? >>0x460 lelong <0x0000040 # and small RO_COMPAT? >>>0x464 lelong <0x0000008 ext3 filesystem data # else large RO_COMPAT? >>>0x464 lelong >0x0000007 ext4 filesystem data # else large INCOMPAT? >>0x460 lelong >0x000003f ext4 filesystem data >0x468 belong x \b, UUID=%08x >0x46c beshort x \b-%04x >0x46e beshort x \b-%04x >0x470 beshort x \b-%04x >0x472 belong x \b-%08x >0x476 beshort x \b%04x >0x478 string >0 \b, volume name "%s" # General flags for any ext* fs >0x460 lelong &0x0000004 (needs journal recovery) >0x43a leshort &0x0000002 (errors) # INCOMPAT flags >0x460 lelong &0x0000001 (compressed) #>0x460 lelong &0x0000002 (filetype) #>0x460 lelong &0x0000010 (meta bg) >0x460 lelong &0x0000040 (extents) >0x460 lelong &0x0000080 (64bit) #>0x460 lelong &0x0000100 (mmp) #>0x460 lelong &0x0000200 (flex bg) # RO_INCOMPAT flags #>0x464 lelong &0x0000001 (sparse super) >0x464 lelong &0x0000002 (large files) >0x464 lelong &0x0000008 (huge files) #>0x464 lelong &0x0000010 (gdt checksum) #>0x464 lelong &0x0000020 (many subdirs) #>0x463 lelong &0x0000040 (extra isize) # Minix filesystems - Juan Cespedes 0x410 leshort 0x137f !:strength / 2 >0x402 beshort < 100 >0x402 beshort > -1 Minix filesystem, V1, %d zones >0x1e string minix \b, bootable 0x410 beshort 0x137f !:strength / 2 >0x402 beshort < 100 >0x402 beshort > -1 Minix filesystem, V1 (big endian), %d zones >0x1e string minix \b, bootable 0x410 leshort 0x138f !:strength / 2 >0x402 beshort < 100 >0x402 beshort > -1 Minix filesystem, V1, 30 char names, %d zones >0x1e string minix \b, bootable 0x410 beshort 0x138f !:strength / 2 >0x402 beshort < 100 >0x402 beshort > -1 Minix filesystem, V1, 30 char names (big endian), %d zones >0x1e string minix \b, bootable 0x410 leshort 0x2468 >0x402 beshort < 100 >>0x402 beshort > -1 Minix filesystem, V2, %d zones >0x1e string minix \b, bootable 0x410 beshort 0x2468 >0x402 beshort < 100 >0x402 beshort > -1 Minix filesystem, V2 (big endian), %d zones >0x1e string minix \b, bootable 0x410 leshort 0x2478 >0x402 beshort < 100 >0x402 beshort > -1 Minix filesystem, V2, 30 char names, %d zones >0x1e string minix \b, bootable 0x410 leshort 0x2478 >0x402 beshort < 100 >0x402 beshort > -1 Minix filesystem, V2, 30 char names, %d zones >0x1e string minix \b, bootable 0x410 beshort 0x2478 >0x402 beshort !0 Minix filesystem, V2, 30 char names (big endian), %d zones >0x1e string minix \b, bootable 0x410 leshort 0x4d5a >0x402 beshort !0 Minix filesystem, V3, %d zones >0x1e string minix \b, bootable # SGI disk labels - Nathan Scott 0 belong 0x0BE5A941 SGI disk label (volume header) # SGI XFS filesystem - Nathan Scott 0 belong 0x58465342 SGI XFS filesystem data >0x4 belong x (blksz %d, >0x68 beshort x inosz %d, >0x64 beshort ^0x2004 v1 dirs) >0x64 beshort &0x2004 v2 dirs) ############################################################################ # Minix-ST kernel floppy 0x800 belong 0x46fc2700 Atari-ST Minix kernel image # http://en.wikipedia.org/wiki/BIOS_parameter_block # floppies with valid BPB and any instruction at beginning >19 string \240\005\371\005\0\011\0\2\0 \b, 720k floppy >19 string \320\002\370\005\0\011\0\1\0 \b, 360k floppy ############################################################################ # Hmmm, is this a better way of detecting _standard_ floppy images ? 19 string \320\002\360\003\0\011\0\1\0 DOS floppy 360k >0x1FE leshort 0xAA55 \b, DOS/MBR hard disk boot sector 19 string \240\005\371\003\0\011\0\2\0 DOS floppy 720k >0x1FE leshort 0xAA55 \b, DOS/MBR hard disk boot sector 19 string \100\013\360\011\0\022\0\2\0 DOS floppy 1440k >0x1FE leshort 0xAA55 \b, DOS/MBR hard disk boot sector 19 string \240\005\371\005\0\011\0\2\0 DOS floppy 720k, IBM >0x1FE leshort 0xAA55 \b, DOS/MBR hard disk boot sector 19 string \100\013\371\005\0\011\0\2\0 DOS floppy 1440k, mkdosfs >0x1FE leshort 0xAA55 \b, DOS/MBR hard disk boot sector 19 string \320\002\370\005\0\011\0\1\0 Atari-ST floppy 360k 19 string \240\005\371\005\0\011\0\2\0 Atari-ST floppy 720k # | | | | | # | | | | heads # | | | sectors/track # | | sectors/FAT # | media descriptor # BPB: sectors # Valid media descriptor bytes for MS-DOS: # # Byte Capacity Media Size and Type # ------------------------------------------------- # # F0 2.88 MB 3.5-inch, 2-sided, 36-sector # F0 1.44 MB 3.5-inch, 2-sided, 18-sector # F9 720K 3.5-inch, 2-sided, 9-sector # F9 1.2 MB 5.25-inch, 2-sided, 15-sector # FD 360K 5.25-inch, 2-sided, 9-sector # FF 320K 5.25-inch, 2-sided, 8-sector # FC 180K 5.25-inch, 1-sided, 9-sector # FE 160K 5.25-inch, 1-sided, 8-sector # FE 250K 8-inch, 1-sided, single-density # FD 500K 8-inch, 2-sided, single-density # FE 1.2 MB 8-inch, 2-sided, double-density # F8 ----- Fixed disk # # FC xxxK Apricot 70x1x9 boot disk. # # Originally a bitmap: # xxxxxxx0 Not two sided # xxxxxxx1 Double sided # xxxxxx0x Not 8 SPT # xxxxxx1x 8 SPT # xxxxx0xx Not Removable drive # xxxxx1xx Removable drive # 11111xxx Must be one. # # But now it's rather random: # 111111xx Low density disk # 00 SS, Not 8 SPT # 01 DS, Not 8 SPT # 10 SS, 8 SPT # 11 DS, 8 SPT # # 11111001 Double density 3 1/2 floppy disk, high density 5 1/4 # 11110000 High density 3 1/2 floppy disk # 11111000 Hard disk any format # # all FAT12 (strength=70) floppies with sectorsize 512 added by Joerg Jenderek at Jun 2013 # http://en.wikipedia.org/wiki/File_Allocation_Table#Exceptions # Too Weak. #512 ubelong&0xE0ffff00 0xE0ffff00 # without valid Media descriptor in place of BPB, cases with are done at other places #>21 ubyte <0xE5 floppy with old FAT filesystem # but valid Media descriptor at begin of FAT #>>512 ubyte =0xed 720k #>>512 ubyte =0xf0 1440k #>>512 ubyte =0xf8 720k #>>512 ubyte =0xf9 1220k #>>512 ubyte =0xfa 320k #>>512 ubyte =0xfb 640k #>>512 ubyte =0xfc 180k # look like an an old DOS directory entry #>>>0xA0E ubequad 0 #>>>>0xA00 ubequad !0 #!:mime application/x-ima #>>512 ubyte =0xfd # look for 2nd FAT at different location to distinguish between 360k and 500k #>>>0x600 ubelong&0xE0ffff00 0xE0ffff00 360k #>>>0x500 ubelong&0xE0ffff00 0xE0ffff00 500k #>>>0xA0E ubequad 0 #!:mime application/x-ima #>>512 ubyte =0xfe #>>>0x400 ubelong&0xE0ffff00 0xE0ffff00 160k #>>>>0x60E ubequad 0 #>>>>>0x600 ubequad !0 #!:mime application/x-ima #>>>0xC00 ubelong&0xE0ffff00 0xE0ffff00 1200k #>>512 ubyte =0xff 320k #>>>0x60E ubequad 0 #>>>>0x600 ubequad !0 #!:mime application/x-ima #>>512 ubyte x \b, Media descriptor 0x%x # without x86 jump instruction #>>0 ulelong&0x804000E9 !0x000000E9 # assembler instructions: CLI;MOV SP,1E7;MOV AX;07c0;MOV #>>>0 ubequad 0xfabce701b8c0078e \b, MS-DOS 1.12 bootloader # IOSYS.COM+MSDOS.COM #>>>>0xc4 use 2xDOS-filename #>>0 ulelong&0x804000E9 =0x000000E9 # only x86 short jump instruction found #>>>0 ubyte =0xEB #>>>>1 ubyte x \b, code offset 0x%x+2 # http://thestarman.pcministry.com/DOS/ibm100/Boot.htm # assembler instructions: CLI;MOV AX,CS;MOV DS,AX;MOV DX,0 #>>>>(1.b+2) ubequad 0xfa8cc88ed8ba0000 \b, PC-DOS 1.0 bootloader # ibmbio.com+ibmdos.com #>>>>>0x176 use DOS-filename #>>>>>0x181 ubyte x \b+ #>>>>>0x182 use DOS-filename # http://thestarman.pcministry.com/DOS/ibm110/Boot.htm # assembler instructions: CLI;MOV AX,CS;MOV DS,AX;XOR DX,DX;MOV #>>>>(1.b+2) ubequad 0xfa8cc88ed833d28e \b, PC-DOS 1.1 bootloader # ibmbio.com+ibmdos.com #>>>>>0x18b use DOS-filename #>>>>>0x196 ubyte x \b+ #>>>>>0x197 use DOS-filename # http://en.wikipedia.org/wiki/Zenith_Data_Systems # assembler instructions: MOV BX,07c0;MOV SS,BX;MOV SP,01c6 #>>>>(1.b+2) ubequad 0xbbc0078ed3bcc601 \b, Zenith Data Systems MS-DOS 1.25 bootloader # IO.SYS+MSDOS.SYS #>>>>>0x20 use 2xDOS-filename # http://en.wikipedia.org/wiki/Corona_Data_Systems # assembler instructions: MOV AX,CS;MOV DS,AX;CLI;MOV SS,AX; #>>>>(1.b+2) ubequad 0x8cc88ed8fa8ed0bc \b, MS-DOS 1.25 bootloader # IO.SYS+MSDOS.SYS #>>>>>0x69 use 2xDOS-filename # assembler instructions: CLI;PUSH CS;POP SS;MOV SP,7c00; #>>>>(1.b+2) ubequad 0xfa0e17bc007cb860 \b, MS-DOS 2.11 bootloader # defect IO.SYS+MSDOS.SYS ? #>>>>>0x162 use 2xDOS-filename 0 name cdrom >38913 string !NSR0 ISO 9660 CD-ROM filesystem data !:mime application/x-iso9660-image >38913 string NSR0 UDF filesystem data !:mime application/x-iso9660-image >>38917 string 1 (version 1.0) >>38917 string 2 (version 1.5) >>38917 string 3 (version 2.0) >>38917 byte >0x33 (unknown version, ID 0x%X) >>38917 byte <0x31 (unknown version, ID 0x%X) >0x1FE leshort 0xAA55 (DOS/MBR boot sector) # "application id" which appears to be used as a volume label >32808 string/T >\0 '%s' >34816 string \000CD001\001EL\ TORITO\ SPECIFICATION (bootable) 37633 string CD001 ISO 9660 CD-ROM filesystem data (raw 2352 byte sectors) !:mime application/x-iso9660-image 32777 string CDROM High Sierra CD-ROM filesystem data # CDROM Filesystems # https://en.wikipedia.org/wiki/ISO_9660 # Modified for UDF by gerardo.cacciari@gmail.com 32769 string CD001 # mime line at that position does not work # to display CD-ROM (70=81-11) after MBR (113=40+72+1), partition-table (71=50+21) and before Apple Driver Map (51) !:strength -11 # to display CD-ROM (114=81+33) before MBR (113=40+72+1), partition-table (71=50+21) and Apple Driver Map (51) # does not work #!:strength +33 >0 use cdrom # .cso files 0 string CISO Compressed ISO CD image # cramfs filesystem - russell@coker.com.au 0 lelong 0x28cd3d45 Linux Compressed ROM File System data, little endian >4 lelong x size %u >8 lelong &1 version #2 >8 lelong &2 sorted_dirs >8 lelong &4 hole_support >32 lelong x CRC 0x%x, >36 lelong x edition %u, >40 lelong x %u blocks, >44 lelong x %u files 0 belong 0x28cd3d45 Linux Compressed ROM File System data, big endian >4 belong x size %u >8 belong &1 version #2 >8 belong &2 sorted_dirs >8 belong &4 hole_support >32 belong x CRC 0x%x, >36 belong x edition %u, >40 belong x %u blocks, >44 belong x %u files # reiserfs - russell@coker.com.au 0x10034 string ReIsErFs ReiserFS V3.5 0x10034 string ReIsEr2Fs ReiserFS V3.6 0x10034 string ReIsEr3Fs ReiserFS V3.6.19 >0x1002c leshort x block size %d >0x10032 leshort &2 (mounted or unclean) >0x10000 lelong x num blocks %d >0x10040 lelong 1 tea hash >0x10040 lelong 2 yura hash >0x10040 lelong 3 r5 hash # JFFS - russell@coker.com.au 0 lelong 0x34383931 Linux Journalled Flash File system, little endian 0 belong 0x34383931 Linux Journalled Flash File system, big endian # EST flat binary format (which isn't, but anyway) # From: Mark Brown 0 string ESTFBINR EST flat binary # Aculab VoIP firmware # From: Mark Brown 0 string VoIP\ Startup\ and Aculab VoIP firmware >35 string x format %s # From: Mark Brown [old] # From: Behan Webster 0 belong 0x27051956 u-boot legacy uImage, >32 string x %s, >28 byte 0 Invalid os/ >28 byte 1 OpenBSD/ >28 byte 2 NetBSD/ >28 byte 3 FreeBSD/ >28 byte 4 4.4BSD/ >28 byte 5 Linux/ >28 byte 6 SVR4/ >28 byte 7 Esix/ >28 byte 8 Solaris/ >28 byte 9 Irix/ >28 byte 10 SCO/ >28 byte 11 Dell/ >28 byte 12 NCR/ >28 byte 13 LynxOS/ >28 byte 14 VxWorks/ >28 byte 15 pSOS/ >28 byte 16 QNX/ >28 byte 17 Firmware/ >28 byte 18 RTEMS/ >28 byte 19 ARTOS/ >28 byte 20 Unity OS/ >28 byte 21 INTEGRITY/ >29 byte 0 \bInvalid CPU, >29 byte 1 \bAlpha, >29 byte 2 \bARM, >29 byte 3 \bIntel x86, >29 byte 4 \bIA64, >29 byte 5 \bMIPS, >29 byte 6 \bMIPS 64-bit, >29 byte 7 \bPowerPC, >29 byte 8 \bIBM S390, >29 byte 9 \bSuperH, >29 byte 10 \bSparc, >29 byte 11 \bSparc 64-bit, >29 byte 12 \bM68K, >29 byte 13 \bNios-32, >29 byte 14 \bMicroBlaze, >29 byte 15 \bNios-II, >29 byte 16 \bBlackfin, >29 byte 17 \bAVR32, >29 byte 18 \bSTMicroelectronics ST200, >30 byte 0 Invalid Image >30 byte 1 Standalone Program >30 byte 2 OS Kernel Image >30 byte 3 RAMDisk Image >30 byte 4 Multi-File Image >30 byte 5 Firmware Image >30 byte 6 Script File >30 byte 7 Filesystem Image (any type) >30 byte 8 Binary Flat Device Tree BLOB >31 byte 0 (Not compressed), >31 byte 1 (gzip), >31 byte 2 (bzip2), >31 byte 3 (lzma), >12 belong x %d bytes, >8 bedate x %s, >16 belong x Load Address: 0x%08X, >20 belong x Entry Point: 0x%08X, >4 belong x Header CRC: 0x%08X, >24 belong x Data CRC: 0x%08X # JFFS2 file system 0 leshort 0x1984 Linux old jffs2 filesystem data little endian 0 leshort 0x1985 Linux jffs2 filesystem data little endian # Squashfs 0 string sqsh Squashfs filesystem, big endian, >28 beshort x version %d. >30 beshort x \b%d, >28 beshort <3 >>8 belong x %d bytes, >28 beshort >2 >>28 beshort <4 >>>63 bequad x %lld bytes, >>28 beshort >3 >>>40 bequad x %lld bytes, #>>67 belong x %d bytes, >4 belong x %d inodes, >28 beshort <2 >>32 beshort x blocksize: %d bytes, >28 beshort >1 >>28 beshort <4 >>>51 belong x blocksize: %d bytes, >>28 beshort >3 >>>12 belong x blocksize: %d bytes, >28 beshort <4 >>39 bedate x created: %s >28 beshort >3 >>8 bedate x created: %s 0 string hsqs Squashfs filesystem, little endian, >28 leshort x version %d. >30 leshort x \b%d, >28 leshort <3 >>8 lelong x %d bytes, >28 leshort >2 >>28 leshort <4 >>>63 lequad x %lld bytes, >>28 leshort >3 >>>40 lequad x %lld bytes, #>>63 lelong x %d bytes, >4 lelong x %d inodes, >28 leshort <2 >>32 leshort x blocksize: %d bytes, >28 leshort >1 >>28 leshort <4 >>>51 lelong x blocksize: %d bytes, >>28 leshort >3 >>>12 lelong x blocksize: %d bytes, >28 leshort <4 >>39 ledate x created: %s >28 leshort >3 >>8 ledate x created: %s # AFS Dump Magic # From: Ty Sarna 0 string \x01\xb3\xa1\x13\x22 AFS Dump >&0 belong x (v%d) >>&0 byte 0x76 >>>&0 belong x Vol %d, >>>>&0 byte 0x6e >>>>>&0 string x %s >>>>>>&1 byte 0x74 >>>>>>>&0 beshort 2 >>>>>>>>&4 bedate x on: %s >>>>>>>>&0 bedate =0 full dump >>>>>>>>&0 bedate !0 incremental since: %s #---------------------------------------------------------- #delta ISO Daniel Novotny (dnovotny@redhat.com) 0 string DISO Delta ISO data !:strength +50 >4 belong x version %d # VMS backup savesets - gerardo.cacciari@gmail.com # 4 string \x01\x00\x01\x00\x01\x00 >(0.s+16) string \x01\x01 >>&(&0.b+8) byte 0x42 OpenVMS backup saveset data >>>40 lelong x (block size %d, >>>49 string >\0 original name '%s', >>>2 short 1024 VAX generated) >>>2 short 2048 AXP generated) >>>2 short 4096 I64 generated) # Summary: Oracle Clustered Filesystem # Created by: Aaron Botsis 8 string OracleCFS Oracle Clustered Filesystem, >4 long x rev %d >0 long x \b.%d, >560 string x label: %.64s, >136 string x mountpoint: %.128s # Summary: Oracle ASM tagged volume # Created by: Aaron Botsis 32 string ORCLDISK Oracle ASM Volume, >40 string x Disk Name: %0.12s 32 string ORCLCLRD Oracle ASM Volume (cleared), >40 string x Disk Name: %0.12s # Oracle Clustered Filesystem - Aaron Botsis 8 string OracleCFS Oracle Clustered Filesystem, >4 long x rev %d >0 long x \b.%d, >560 string x label: %.64s, >136 string x mountpoint: %.128s # Oracle ASM tagged volume - Aaron Botsis 32 string ORCLDISK Oracle ASM Volume, >40 string x Disk Name: %0.12s 32 string ORCLCLRD Oracle ASM Volume (cleared), >40 string x Disk Name: %0.12s # Compaq/HP RILOE floppy image # From: Dirk Jagdmann 0 string CPQRFBLO Compaq/HP RILOE floppy image #------------------------------------------------------------------------------ # Files-11 On-Disk Structure (File system for various RSX-11 and VMS flavours). # These bits come from LBN 1 (home block) of ODS-1, ODS-2 and ODS-5 volumes, # which is mapped to VBN 2 of [000000]INDEXF.SYS;1 - gerardo.cacciari@gmail.com # 1008 string DECFILE11 Files-11 On-Disk Structure >525 byte x (ODS-%d); >1017 string A RSX-11, VAX/VMS or OpenVMS VAX file system; >1017 string B >>525 byte 2 VAX/VMS or OpenVMS file system; >>525 byte 5 OpenVMS Alpha or Itanium file system; >984 string x volume label is '%-12.12s' # From: Thomas Klausner # http://filext.com/file-extension/DAA # describes the daa file format. The magic would be: 0 string DAA\x0\x0\x0\x0\x0 PowerISO Direct-Access-Archive # From Albert Cahalan # really le32 operation,destination,payloadsize (but quite predictable) # 01 00 00 00 00 00 00 c0 00 02 00 00 0 string \1\0\0\0\0\0\0\300\0\2\0\0 Marvell Libertas firmware # From Eric Sandeen # GFS2 0x10000 belong 0x01161970 >0x10018 belong 0x0000051d GFS1 Filesystem >>0x10024 belong x (blocksize %d, >>0x10060 string >\0 lockproto %s) >0x10018 belong 0x00000709 GFS2 Filesystem >>0x10024 belong x (blocksize %d, >>0x10060 string >\0 lockproto %s) # BTRFS 0x10040 string _BHRfS_M BTRFS Filesystem >0x1012b string >\0 (label "%s", >0x10090 lelong x sectorsize %d, >0x10094 lelong x nodesize %d, >0x10098 lelong x leafsize %d) # dvdisaster's .ecc # From: "Nelson A. de Oliveira" 0 string *dvdisaster* dvdisaster error correction file # xfs metadump image # mb_magic XFSM at 0; superblock magic XFSB at 1 << mb_blocklog # but can we do the << ? For now it's always 512 (0x200) anyway. 0 string XFSM >0x200 string XFSB XFS filesystem metadump image # Type: CROM filesystem # From: Werner Fink 0 string CROMFS CROMFS >6 string >\0 \b version %2.2s, >8 ulequad >0 \b block data at %lld, >16 ulequad >0 \b fblock table at %lld, >24 ulequad >0 \b inode table at %lld, >32 ulequad >0 \b root at %lld, >40 ulelong >0 \b fblock size = %d, >44 ulelong >0 \b block size = %d, >48 ulequad >0 \b bytes = %lld # Type: xfs metadump image # From: Daniel Novotny # mb_magic XFSM at 0; superblock magic XFSB at 1 << mb_blocklog # but can we do the << ? For now it's always 512 (0x200) anyway. 0 string XFSM >0x200 string XFSB XFS filesystem metadump image # Type: delta ISO # From: Daniel Novotny 0 string DISO Delta ISO data, >4 belong x version %d # JFS2 (Journaling File System) image. (Old JFS1 has superblock at 0x1000.) # See linux/fs/jfs/jfs_superblock.h for layout; see jfs_filsys.h for flags. # From: Adam Buchbinder 0x8000 string JFS1 # Because it's text-only magic, check a binary value (version) to be sure. # Should always be 2, but mkfs.jfs writes it as 1. Needs to be 2 or 1 to be # mountable. >&0 lelong <3 JFS2 filesystem image # Label is followed by a UUID; we have to limit string length to avoid # appending the UUID in the case of a 16-byte label. >>&144 regex [\x20-\x7E]{1,16} (label "%s") >>&0 lequad x \b, %lld blocks >>&8 lelong x \b, blocksize %d >>&32 lelong&0x00000006 >0 (dirty) >>&36 lelong >0 (compressed) # LFS 0 lelong 0x070162 LFS filesystem image >4 lelong 1 version 1, >>8 lelong x \b blocks %u, >>12 lelong x \b blocks per segment %u, >4 lelong 2 version 2, >>8 lelong x \b fragments %u, >>12 lelong x \b bytes per segment %u, >16 lelong x \b disk blocks %u, >20 lelong x \b block size %u, >24 lelong x \b fragment size %u, >28 lelong x \b fragments per block %u, >32 lelong x \b start for free list %u, >36 lelong x \b number of free blocks %d, >40 lelong x \b number of files %u, >44 lelong x \b blocks available for writing %d, >48 lelong x \b inodes in cache %d, >52 lelong x \b inode file disk address 0x%x, >56 lelong x \b inode file inode number %u, >60 lelong x \b address of last segment written 0x%x, >64 lelong x \b address of next segment to write 0x%x, >68 lelong x \b address of current segment written 0x%x 0 string td\000 floppy image data (TeleDisk, compressed) 0 string TD\000 floppy image data (TeleDisk) 0 string CQ\024 floppy image data (CopyQM, >16 leshort x %d sectors, >18 leshort x %d heads.) 0 string ACT\020Apricot\020disk\020image\032\004 floppy image data (ApriDisk) 0 beshort 0xAA58 floppy image data (IBM SaveDskF, old) 0 beshort 0xAA59 floppy image data (IBM SaveDskF) 0 beshort 0xAA5A floppy image data (IBM SaveDskF, compressed) 0 string \074CPM_Disk\076 disk image data (YAZE) # ReFS # Richard W.M. Jones 0 string \0\0\0ReFS\0 ReFS filesystem image # EFW encase image file format: # Gregoire Passault # http://www.forensicswiki.org/wiki/Encase_image_file_format 0 string EVF\x09\x0d\x0a\xff\x00 EWF/Expert Witness/EnCase image file format # UBIfs # Linux kernel sources: fs/ubifs/ubifs-media.h 0 lelong 0x06101831 >0x16 leshort 0 UBIfs image >0x08 lequad x \b, sequence number %llu >0x10 leshort x \b, length %u >0x04 lelong x \b, CRC 0x%08x 0 lelong 0x23494255 >0x04 leshort <2 >0x05 string \0\0\0 >0x1c string \0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0 >0x04 leshort x UBI image, version %u # NEC PC-88 2D disk image # From Fabio R. Schmidlin 0x20 ulelong&0xFFFFFEFF 0x2A0 >0x10 string \0\0\0\0\0\0\0\0\0\0 >>0x280 string \0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0 >>>0x1A ubyte&0xEF 0 >>>>0x1B ubyte&0x8F 0 >>>>>0x1B ubyte&70 <0x40 >>>>>>0x1C ulelong >0x21 >>>>>>>0 regex [[:print:]]* NEC PC-88 disk image, name=%s >>>>>>>>0x1B ubyte 0 \b, media=2D >>>>>>>>0x1B ubyte 0x10 \b, media=2DD >>>>>>>>0x1B ubyte 0x20 \b, media=2HD >>>>>>>>0x1B ubyte 0x30 \b, media=1D >>>>>>>>0x1B ubyte 0x40 \b, media=1DD >>>>>>>>0x1A ubyte 0x10 \b, write-protected #------------------------------------------------------------------------------ # $File: flash,v 1.10 2014/03/06 16:07:24 christos Exp $ # flash: file(1) magic for Macromedia Flash file format # # See # # http://www.macromedia.com/software/flash/open/ # http://wwwimages.adobe.com/www.adobe.com/content/dam/Adobe/\ # en/devnet/swf/pdf/swf-file-format-spec.pdf page 27 # 0 name swf-details >0 string F Macromedia Flash data !:mime application/x-shockwave-flash >0 string C Macromedia Flash data (compressed) !:mime application/x-shockwave-flash >0 string Z Macromedia Flash data (lzma compressed) !:mime application/x-shockwave-flash >3 byte x \b, version %d 1 string WS >4 lelong !0 >>3 byte 255 Suspicious >>>0 use swf-details >>3 ubyte <32 >>>3 ubyte !0 >>>>0 use swf-details # From: Cal Peake 0 string FLV\x01 Macromedia Flash Video !:mime video/x-flv # # Yosu Gomez 0 string AGD2\xbe\xb8\xbb\xcd\x00 Macromedia Freehand 7 Document 0 string AGD3\xbe\xb8\xbb\xcc\x00 Macromedia Freehand 8 Document # From Dave Wilson 0 string AGD4\xbe\xb8\xbb\xcb\x00 Macromedia Freehand 9 Document #------------------------------------------------------------------------------ # $File: fonts,v 1.26 2013/03/09 22:36:00 christos Exp $ # fonts: file(1) magic for font data # 0 search/1 FONT ASCII vfont text 0 short 0436 Berkeley vfont data 0 short 017001 byte-swapped Berkeley vfont data # PostScript fonts (must precede "printer" entries), quinlan@yggdrasil.com 0 string %!PS-AdobeFont-1. PostScript Type 1 font text >20 string >\0 (%s) 6 string %!PS-AdobeFont-1. PostScript Type 1 font program data 0 string %!FontType1 PostScript Type 1 font program data 6 string %!FontType1 PostScript Type 1 font program data 0 string %!PS-Adobe-3.0\ Resource-Font PostScript Type 1 font text # X11 font files in SNF (Server Natural Format) format # updated by Joerg Jenderek at Feb 2013 # http://computer-programming-forum.com/51-perl/8f22fb96d2e34bab.htm 0 belong 00000004 X11 SNF font data, MSB first #>104 belong 00000004 X11 SNF font data, MSB first !:mime application/x-font-sfn # GRR: line below too general as it catches also Xbase index file t3-CHAR.NDX 0 lelong 00000004 >104 lelong 00000004 X11 SNF font data, LSB first !:mime application/x-font-sfn # X11 Bitmap Distribution Format, from Daniel Quinlan (quinlan@yggdrasil.com) 0 search/1 STARTFONT\ X11 BDF font text # X11 fonts, from Daniel Quinlan (quinlan@yggdrasil.com) # PCF must come before SGI additions ("MIPSEL MIPS-II COFF" collides) 0 string \001fcp X11 Portable Compiled Font data >12 byte 0x02 \b, LSB first >12 byte 0x0a \b, MSB first 0 string D1.0\015 X11 Speedo font data #------------------------------------------------------------------------------ # FIGlet fonts and controlfiles # From figmagic supplied with Figlet version 2.2 # "David E. O'Brien" 0 string flf FIGlet font >3 string >2a version %-2.2s 0 string flc FIGlet controlfile >3 string >2a version %-2.2s # libGrx graphics lib fonts, from Albert Cahalan (acahalan@cs.uml.edu) # Used with djgpp (DOS Gnu C++), sometimes Linux or Turbo C++ 0 belong 0x14025919 libGrx font data, >8 leshort x %dx >10 leshort x \b%d >40 string x %s # Misc. DOS VGA fonts, from Albert Cahalan (acahalan@cs.uml.edu) 0 belong 0xff464f4e DOS code page font data collection 7 belong 0x00454741 DOS code page font data 7 belong 0x00564944 DOS code page font data (from Linux?) 4098 string DOSFONT DOSFONT2 encrypted font data # downloadable fonts for browser (prints type) anthon@mnt.org 0 string PFR1 PFR1 font >102 string >0 \b: %s # True Type fonts 0 string \000\001\000\000\000 TrueType font data !:mime application/x-font-ttf 0 string \007\001\001\000Copyright\ (c)\ 199 Adobe Multiple Master font 0 string \012\001\001\000Copyright\ (c)\ 199 Adobe Multiple Master font # TrueType/OpenType font collections (.ttc) # http://www.microsoft.com/typography/otspec/otff.htm 0 string ttcf TrueType font collection data >4 belong 0x00010000 \b, 1.0 >>8 belong >0 \b, %d fonts >4 belong 0x00020000 \b, 2.0 >>8 belong >0 \b, %d fonts # 0x44454947 = 'DSIG' >>>16 belong 0x44534947 \b, digitally signed # Opentype font data from Avi Bercovich 0 string OTTO OpenType font data !:mime application/vnd.ms-opentype # Gurkan Sengun , www.linuks.mine.nu 0 string SplineFontDB: Spline Font Database !:mime application/vnd.font-fontforge-sfd >14 string x version %s # EOT 34 string LP Embedded OpenType (EOT) !:mime application/vnd.ms-fontobject # Web Open Font Format (.woff) # http://www.w3.org/TR/WOFF/ 0 string wOFF Web Open Font Format >4 belong x \b, flavor %d >8 belong x \b, length %d >20 beshort x \b, version %d >22 beshort x \b.%d #------------------------------------------------------------------------------ # $File: fortran,v 1.7 2012/06/21 01:55:02 christos Exp $ # FORTRAN source 0 regex/100l \^[Cc][\ \t] FORTRAN program !:mime text/x-fortran !:strength - 5 #------------------------------------------------------------------------------ # $File$ # frame: file(1) magic for FrameMaker files # # This stuff came on a FrameMaker demo tape, most of which is # copyright, but this file is "published" as witness the following: # # Note that this is the Framemaker Maker Interchange Format, not the # Normal format which would be application/vnd.framemaker. # 0 string \11 string 5.5 (5.5 >11 string 5.0 (5.0 >11 string 4.0 (4.0 >11 string 3.0 (3.0 >11 string 2.0 (2.0 >11 string 1.0 (1.0 >14 byte x %c) 0 string \9 string 4.0 (4.0) >9 string 3.0 (3.0) >9 string 2.0 (2.0) >9 string 1.0 (1.x) 0 search/1 \17 string 3.0 (3.0) >17 string 2.0 (2.0) >17 string 1.0 (1.x) 0 string \17 string 1.01 (%s) 0 string \10 string 3.0 (3.0 >10 string 2.0 (2.0 >10 string 1.0 (1.0 >13 byte x %c) # XXX - this book entry should be verified, if you find one, uncomment this #0 string \6 string 3.0 (3.0) #>6 string 2.0 (2.0) #>6 string 1.0 (1.0) 0 string \= 4096 (or >4095, same thing), then it's # an executable, and is dynamically-linked if the "has run-time # loader information" bit is set. # # On x86, NetBSD says: # # If it's neither pure nor demand-paged: # # if it has the "has run-time loader information" bit set, it's # a dynamically-linked executable; # # if it doesn't have that bit set, then: # # if it has the "is position-independent" bit set, it's # position-independent; # # if the entry point is non-zero, it's an executable, otherwise # it's an object file. # # If it's pure: # # if it has the "has run-time loader information" bit set, it's # a dynamically-linked executable, otherwise it's just an # executable. # # If it's demand-paged: # # if it has the "has run-time loader information" bit set, # then: # # if the entry point is < 4096, it's a shared library; # # if the entry point is = 4096 or > 4096 (i.e., >= 4096), # it's a dynamically-linked executable); # # if it doesn't have the "has run-time loader information" bit # set, then it's just an executable. # # (On non-x86, NetBSD does much the same thing, except that it uses # 8192 on 68K - except for "68k4k", which is presumably "68K with 4K # pages - SPARC, and MIPS, presumably because Sun-3's and Sun-4's # had 8K pages; dunno about MIPS.) # # I suspect the two will differ only in perverse and uninteresting cases # ("shared" libraries that aren't demand-paged and whose pages probably # won't actually be shared, executables with entry points <4096). # # I leave it to those more familiar with FreeBSD and NetBSD to figure out # what the right answer is (although using ">4095", FreeBSD-style, is # probably better than separately checking for "=4096" and ">4096", # NetBSD-style). (The old "netbsd" file analyzed FreeBSD demand paged # executables using the NetBSD technique.) # 0 lelong&0377777777 041400407 FreeBSD/i386 >20 lelong <4096 >>3 byte&0xC0 &0x80 shared library >>3 byte&0xC0 0x40 PIC object >>3 byte&0xC0 0x00 object >20 lelong >4095 >>3 byte&0x80 0x80 dynamically linked executable >>3 byte&0x80 0x00 executable >16 lelong >0 not stripped 0 lelong&0377777777 041400410 FreeBSD/i386 pure >20 lelong <4096 >>3 byte&0xC0 &0x80 shared library >>3 byte&0xC0 0x40 PIC object >>3 byte&0xC0 0x00 object >20 lelong >4095 >>3 byte&0x80 0x80 dynamically linked executable >>3 byte&0x80 0x00 executable >16 lelong >0 not stripped 0 lelong&0377777777 041400413 FreeBSD/i386 demand paged >20 lelong <4096 >>3 byte&0xC0 &0x80 shared library >>3 byte&0xC0 0x40 PIC object >>3 byte&0xC0 0x00 object >20 lelong >4095 >>3 byte&0x80 0x80 dynamically linked executable >>3 byte&0x80 0x00 executable >16 lelong >0 not stripped 0 lelong&0377777777 041400314 FreeBSD/i386 compact demand paged >20 lelong <4096 >>3 byte&0xC0 &0x80 shared library >>3 byte&0xC0 0x40 PIC object >>3 byte&0xC0 0x00 object >20 lelong >4095 >>3 byte&0x80 0x80 dynamically linked executable >>3 byte&0x80 0x00 executable >16 lelong >0 not stripped # XXX gross hack to identify core files # cores start with a struct tss; we take advantage of the following: # byte 7: highest byte of the kernel stack pointer, always 0xfe # 8/9: kernel (ring 0) ss value, always 0x0010 # 10 - 27: ring 1 and 2 ss/esp, unused, thus always 0 # 28: low order byte of the current PTD entry, always 0 since the # PTD is page-aligned # 7 string \357\020\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0 FreeBSD/i386 a.out core file >1039 string >\0 from '%s' # /var/run/ld.so.hints # What are you laughing about? 0 lelong 011421044151 ld.so hints file (Little Endian >4 lelong >0 \b, version %d) >4 belong <1 \b) 0 belong 011421044151 ld.so hints file (Big Endian >4 belong >0 \b, version %d) >4 belong <1 \b) # # Files generated by FreeBSD scrshot(1)/vidcontrol(1) utilities # 0 string SCRSHOT_ scrshot(1) screenshot, >8 byte x version %d, >9 byte 2 %d bytes in header, >>10 byte x %d chars wide by >>11 byte x %d chars high #------------------------------------------------------------------------------ # $File: fsav,v 1.12 2013/03/23 14:15:30 christos Exp $ # fsav: file(1) magic for datafellows fsav virus definition files # Anthon van der Neut (anthon@mnt.org) # ftp://ftp.f-prot.com/pub/{macrdef2.zip,nomacro.def} 0 beshort 0x1575 fsav macro virus signatures >8 leshort >0 (%d- >11 byte >0 \b%02d- >10 byte >0 \b%02d) # ftp://ftp.f-prot.com/pub/sign.zip #10 ubyte <12 #>9 ubyte <32 #>>8 ubyte 0x0a #>>>12 ubyte 0x07 #>>>>11 uleshort >0 fsav DOS/Windows virus signatures (%d- #>>>>10 byte 0 \b01- #>>>>10 byte 1 \b02- #>>>>10 byte 2 \b03- #>>>>10 byte 3 \b04- #>>>>10 byte 4 \b05- #>>>>10 byte 5 \b06- #>>>>10 byte 6 \b07- #>>>>10 byte 7 \b08- #>>>>10 byte 8 \b09- #>>>>10 byte 9 \b10- #>>>>10 byte 10 \b11- #>>>>10 byte 11 \b12- #>>>>9 ubyte >0 \b%02d) # ftp://ftp.f-prot.com/pub/sign2.zip #0 ubyte 0x62 #>1 ubyte 0xF5 #>>2 ubyte 0x1 #>>>3 ubyte 0x1 #>>>>4 ubyte 0x0e #>>>>>13 ubyte >0 fsav virus signatures #>>>>>>11 ubyte x size 0x%02x #>>>>>>12 ubyte x \b%02x #>>>>>>13 ubyte x \b%02x bytes # Joerg Jenderek: joerg dot jenderek at web dot de # http://www.clamav.net/doc/latest/html/node45.html # .cvd files start with a 512 bytes colon separated header # ClamAV-VDB:buildDate:version:signaturesNumbers:functionalityLevelRequired:MD5:Signature:builder:buildTime # + gzipped tarball files 0 string ClamAV-VDB: >11 string >\0 Clam AntiVirus database %-.23s >>34 string : >>>35 string !: \b, version >>>>35 string x \b%-.1s >>>>>36 string !: >>>>>>36 string x \b%-.1s >>>>>>>37 string !: >>>>>>>>37 string x \b%-.1s >>>>>>>>>38 string !: >>>>>>>>>>38 string x \b%-.1s >512 string \037\213 \b, gzipped >769 string ustar\0 \b, tarred # Type: Grisoft AVG AntiVirus # From: David Newgas 0 string AVG7_ANTIVIRUS_VAULT_FILE AVG 7 Antivirus vault file data 0 string X5O!P%@AP[4\\PZX54(P^)7CC)7}$EICAR >33 string -STANDARD-ANTIVIRUS-TEST-FILE!$H+H* EICAR virus test files #------------------------------------------------------------------------------ # $File: mcrypt,v 1.5 2009/09/19 16:28:10 christos Exp $ # fusecompress: file(1) magic for fusecompress 0 string \037\135\211 FuseCompress(ed) data >3 byte 0x00 (none format) >3 byte 0x01 (bz2 format) >3 byte 0x02 (gz format) >3 byte 0x03 (lzo format) >3 byte 0x04 (xor format) >3 byte >0x04 (unknown format) >4 long x uncompressed size: %d #------------------------------------------------------------------------------ # $File: games,v 1.13 2012/02/13 22:50:50 christos Exp $ # games: file(1) for games # Fabio Bonelli # Quake II - III data files 0 string IDP2 Quake II 3D Model file, >20 long x %u skin(s), >8 long x (%u x >12 long x %u), >40 long x %u frame(s), >16 long x Frame size %u bytes, >24 long x %u vertices/frame, >28 long x %u texture coordinates, >32 long x %u triangles/frame 0 string IBSP Quake >4 long 0x26 II Map file (BSP) >4 long 0x2E III Map file (BSP) 0 string IDS2 Quake II SP2 sprite file #--------------------------------------------------------------------------- # Doom and Quake # submitted by Nicolas Patrois 0 string \xcb\x1dBoom\xe6\xff\x03\x01 Boom or linuxdoom demo # some doom lmp files don't match, I've got one beginning with \x6d\x02\x01\x01 24 string LxD\ 203 Linuxdoom save >0 string x , name=%s >44 string x , world=%s # Quake 0 string PACK Quake I or II world or extension >8 lelong >0 \b, %d entries #0 string -1\x0a Quake I demo #>30 string x version %.4s #>61 string x level %s #0 string 5\x0a Quake I save # The levels # Quake 1 0 string 5\x0aIntroduction Quake I save: start Introduction 0 string 5\x0athe_Slipgate_Complex Quake I save: e1m1 The slipgate complex 0 string 5\x0aCastle_of_the_Damned Quake I save: e1m2 Castle of the damned 0 string 5\x0athe_Necropolis Quake I save: e1m3 The necropolis 0 string 5\x0athe_Grisly_Grotto Quake I save: e1m4 The grisly grotto 0 string 5\x0aZiggurat_Vertigo Quake I save: e1m8 Ziggurat vertigo (secret) 0 string 5\x0aGloom_Keep Quake I save: e1m5 Gloom keep 0 string 5\x0aThe_Door_To_Chthon Quake I save: e1m6 The door to Chthon 0 string 5\x0aThe_House_of_Chthon Quake I save: e1m7 The house of Chthon 0 string 5\x0athe_Installation Quake I save: e2m1 The installation 0 string 5\x0athe_Ogre_Citadel Quake I save: e2m2 The ogre citadel 0 string 5\x0athe_Crypt_of_Decay Quake I save: e2m3 The crypt of decay (dopefish lives!) 0 string 5\x0aUnderearth Quake I save: e2m7 Underearth (secret) 0 string 5\x0athe_Ebon_Fortress Quake I save: e2m4 The ebon fortress 0 string 5\x0athe_Wizard's_Manse Quake I save: e2m5 The wizard's manse 0 string 5\x0athe_Dismal_Oubliette Quake I save: e2m6 The dismal oubliette 0 string 5\x0aTermination_Central Quake I save: e3m1 Termination central 0 string 5\x0aVaults_of_Zin Quake I save: e3m2 Vaults of Zin 0 string 5\x0athe_Tomb_of_Terror Quake I save: e3m3 The tomb of terror 0 string 5\x0aSatan's_Dark_Delight Quake I save: e3m4 Satan's dark delight 0 string 5\x0athe_Haunted_Halls Quake I save: e3m7 The haunted halls (secret) 0 string 5\x0aWind_Tunnels Quake I save: e3m5 Wind tunnels 0 string 5\x0aChambers_of_Torment Quake I save: e3m6 Chambers of torment 0 string 5\x0athe_Sewage_System Quake I save: e4m1 The sewage system 0 string 5\x0aThe_Tower_of_Despair Quake I save: e4m2 The tower of despair 0 string 5\x0aThe_Elder_God_Shrine Quake I save: e4m3 The elder god shrine 0 string 5\x0athe_Palace_of_Hate Quake I save: e4m4 The palace of hate 0 string 5\x0aHell's_Atrium Quake I save: e4m5 Hell's atrium 0 string 5\x0athe_Nameless_City Quake I save: e4m8 The nameless city (secret) 0 string 5\x0aThe_Pain_Maze Quake I save: e4m6 The pain maze 0 string 5\x0aAzure_Agony Quake I save: e4m7 Azure agony 0 string 5\x0aShub-Niggurath's_Pit Quake I save: end Shub-Niggurath's pit # Quake DeathMatch levels 0 string 5\x0aPlace_of_Two_Deaths Quake I save: dm1 Place of two deaths 0 string 5\x0aClaustrophobopolis Quake I save: dm2 Claustrophobopolis 0 string 5\x0aThe_Abandoned_Base Quake I save: dm3 The abandoned base 0 string 5\x0aThe_Bad_Place Quake I save: dm4 The bad place 0 string 5\x0aThe_Cistern Quake I save: dm5 The cistern 0 string 5\x0aThe_Dark_Zone Quake I save: dm6 The dark zone # Scourge of Armagon 0 string 5\x0aCommand_HQ Quake I save: start Command HQ 0 string 5\x0aThe_Pumping_Station Quake I save: hip1m1 The pumping station 0 string 5\x0aStorage_Facility Quake I save: hip1m2 Storage facility 0 string 5\x0aMilitary_Complex Quake I save: hip1m5 Military complex (secret) 0 string 5\x0athe_Lost_Mine Quake I save: hip1m3 The lost mine 0 string 5\x0aResearch_Facility Quake I save: hip1m4 Research facility 0 string 5\x0aAncient_Realms Quake I save: hip2m1 Ancient realms 0 string 5\x0aThe_Gremlin's_Domain Quake I save: hip2m6 The gremlin's domain (secret) 0 string 5\x0aThe_Black_Cathedral Quake I save: hip2m2 The black cathedral 0 string 5\x0aThe_Catacombs Quake I save: hip2m3 The catacombs 0 string 5\x0athe_Crypt__ Quake I save: hip2m4 The crypt 0 string 5\x0aMortum's_Keep Quake I save: hip2m5 Mortum's keep 0 string 5\x0aTur_Torment Quake I save: hip3m1 Tur torment 0 string 5\x0aPandemonium Quake I save: hip3m2 Pandemonium 0 string 5\x0aLimbo Quake I save: hip3m3 Limbo 0 string 5\x0athe_Edge_of_Oblivion Quake I save: hipdm1 The edge of oblivion (secret) 0 string 5\x0aThe_Gauntlet Quake I save: hip3m4 The gauntlet 0 string 5\x0aArmagon's_Lair Quake I save: hipend Armagon's lair # Malice 0 string 5\x0aThe_Academy Quake I save: start The academy 0 string 5\x0aThe_Lab Quake I save: d1 The lab 0 string 5\x0aArea_33 Quake I save: d1b Area 33 0 string 5\x0aSECRET_MISSIONS Quake I save: d3b Secret missions 0 string 5\x0aThe_Hospital Quake I save: d10 The hospital (secret) 0 string 5\x0aThe_Genetics_Lab Quake I save: d11 The genetics lab (secret) 0 string 5\x0aBACK_2_MALICE Quake I save: d4b Back to Malice 0 string 5\x0aArea44 Quake I save: d1c Area 44 0 string 5\x0aTakahiro_Towers Quake I save: d2 Takahiro towers 0 string 5\x0aA_Rat's_Life Quake I save: d3 A rat's life 0 string 5\x0aInto_The_Flood Quake I save: d4 Into the flood 0 string 5\x0aThe_Flood Quake I save: d5 The flood 0 string 5\x0aNuclear_Plant Quake I save: d6 Nuclear plant 0 string 5\x0aThe_Incinerator_Plant Quake I save: d7 The incinerator plant 0 string 5\x0aThe_Foundry Quake I save: d7b The foundry 0 string 5\x0aThe_Underwater_Base Quake I save: d8 The underwater base 0 string 5\x0aTakahiro_Base Quake I save: d9 Takahiro base 0 string 5\x0aTakahiro_Laboratories Quake I save: d12 Takahiro laboratories 0 string 5\x0aStayin'_Alive Quake I save: d13 Stayin' alive 0 string 5\x0aB.O.S.S._HQ Quake I save: d14 B.O.S.S. HQ 0 string 5\x0aSHOWDOWN! Quake I save: d15 Showdown! # Malice DeathMatch levels 0 string 5\x0aThe_Seventh_Precinct Quake I save: ddm1 The seventh precinct 0 string 5\x0aSub_Station Quake I save: ddm2 Sub station 0 string 5\x0aCrazy_Eights! Quake I save: ddm3 Crazy eights! 0 string 5\x0aEast_Side_Invertationa Quake I save: ddm4 East side invertationa 0 string 5\x0aSlaughterhouse Quake I save: ddm5 Slaughterhouse 0 string 5\x0aDOMINO Quake I save: ddm6 Domino 0 string 5\x0aSANDRA'S_LADDER Quake I save: ddm7 Sandra's ladder 0 string MComprHD MAME CHD compressed hard disk image, >12 belong x version %u # doom - submitted by Jon Dowland 0 string =IWAD doom main IWAD data >4 lelong x containing %d lumps 0 string =PWAD doom patch PWAD data >4 lelong x containing %d lumps # Build engine group files (Duke Nukem, Shadow Warrior, ...) # Extension: .grp # Created by: "Ganael Laplanche" 0 string KenSilverman Build engine group file >12 lelong x containing %d files # Summary: Warcraft 3 save # Extension: .w3g # Created by: "Nelson A. de Oliveira" 0 string Warcraft\ III\ recorded\ game %s # Summary: Warcraft 3 map # Extension: .w3m # Created by: "Nelson A. de Oliveira" 0 string HM3W Warcraft III map file # Summary: SGF Smart Game Format # Extension: .sgf # Reference: http://www.red-bean.com/sgf/ # Created by: Eduardo Sabbatella # Modified by (1): Abel Cheung (regex, more game format) # FIXME: Some games don't have GM (game type) 0 regex \\(;.*GM\\[[0-9]{1,2}\\] Smart Game Format >2 search/0x200/b GM[ >>&0 string 1] (Go) >>&0 string 2] (Othello) >>&0 string 3] (chess) >>&0 string 4] (Gomoku+Renju) >>&0 string 5] (Nine Men's Morris) >>&0 string 6] (Backgammon) >>&0 string 7] (Chinese chess) >>&0 string 8] (Shogi) >>&0 string 9] (Lines of Action) >>&0 string 10] (Ataxx) >>&0 string 11] (Hex) >>&0 string 12] (Jungle) >>&0 string 13] (Neutron) >>&0 string 14] (Philosopher's Football) >>&0 string 15] (Quadrature) >>&0 string 16] (Trax) >>&0 string 17] (Tantrix) >>&0 string 18] (Amazons) >>&0 string 19] (Octi) >>&0 string 20] (Gess) >>&0 string 21] (Twixt) >>&0 string 22] (Zertz) >>&0 string 23] (Plateau) >>&0 string 24] (Yinsh) >>&0 string 25] (Punct) >>&0 string 26] (Gobblet) >>&0 string 27] (hive) >>&0 string 28] (Exxit) >>&0 string 29] (Hnefatal) >>&0 string 30] (Kuba) >>&0 string 31] (Tripples) >>&0 string 32] (Chase) >>&0 string 33] (Tumbling Down) >>&0 string 34] (Sahara) >>&0 string 35] (Byte) >>&0 string 36] (Focus) >>&0 string 37] (Dvonn) >>&0 string 38] (Tamsk) >>&0 string 39] (Gipf) >>&0 string 40] (Kropki) ############################################## # NetImmerse/Gamebryo game engine entries # Summary: Gamebryo game engine file # Extension: .nif, .kf # Created by: Abel Cheung 0 string Gamebryo\ File\ Format,\ Version\ Gamebryo game engine file >&0 regex [0-9a-z.]+ \b, version %s # Summary: Gamebryo game engine file # Extension: .kfm # Created by: Abel Cheung 0 string ;Gamebryo\ KFM\ File\ Version\ Gamebryo game engine animation File >&0 regex [0-9a-z.]+ \b, version %s # Summary: NetImmerse game engine file # Extension .nif # Created by: Abel Cheung 0 string NetImmerse\ File\ Format,\ Versio >&0 string n\ NetImmerse game engine file >>&0 regex [0-9a-z.]+ \b, version %s # Type: SGF Smart Game Format # URL: http://www.red-bean.com/sgf/ # From: Eduardo Sabbatella 2 regex/c \\(;.*GM\\[[0-9]{1,2}\\] Smart Game Format >2 regex/c GM\\[1\\] - Go Game >2 regex/c GM\\[6\\] - BackGammon Game >2 regex/c GM\\[11\\] - Hex Game >2 regex/c GM\\[18\\] - Amazons Game >2 regex/c GM\\[19\\] - Octi Game >2 regex/c GM\\[20\\] - Gess Game >2 regex/c GM\\[21\\] - twix Game # Epic Games/Unreal Engine Package # 0 lelong 0x9E2A83C1 Unreal Engine Package, >4 leshort x version: %i >12 lelong !0 \b, names: %i >28 lelong !0 \b, imports: %i >20 lelong !0 \b, exports: %i #------------------------------------------------------------------------------ # $File$ # gcc: file(1) magic for GCC special files # 0 string gpch GCC precompiled header # The version field is annoying. It's 3 characters, not zero-terminated. >5 byte x (version %c >6 byte x \b%c >7 byte x \b%c) # 67 = 'C', 111 = 'o', 43 = '+', 79 = 'O' >4 byte 67 for C >4 byte 111 for Objective C >4 byte 43 for C++ >4 byte 79 for Objective C++ #------------------------------------------------------------------------------ # $File: geo,v 1.2 2013/01/02 15:27:53 christos Exp $ # Geo- files from Kurt Schwehr ###################################################################### # # Acoustic Doppler Current Profilers (ADCP) # ###################################################################### 0 beshort 0x7f7f RDI Acoustic Doppler Current Profiler (ADCP) ###################################################################### # # Metadata # ###################################################################### 0 string Identification_Information FGDC ASCII metadata ###################################################################### # # Seimsic / Subbottom # ###################################################################### # Knudsen subbottom chirp profiler - Binary File Format: B9 # KEB D409-03167 V1.75 Huffman 0 string KEB\ Knudsen seismic KEL binary (KEB) - >4 regex [-A-Z0-9]* Software: %s >>&1 regex V[0-9]*\.[0-9]* version %s ###################################################################### # # LIDAR - Laser altimetry or bathy # ###################################################################### # Caris LIDAR format for LADS comes as two parts... ascii location file and binary waveform data 0 string HCA LADS Caris Ascii Format (CAF) bathymetric lidar >4 regex [0-9]*\.[0-9]* version %s 0 string HCB LADS Caris Binary Format (CBF) bathymetric lidar waveform data >3 byte x version %d . >4 byte x %d ###################################################################### # # MULTIBEAM SONARS http://www.ldeo.columbia.edu/res/pi/MB-System/formatdoc/ # ###################################################################### # GeoAcoustics - GeoSwath Plus 4 beshort 0x2002 GeoSwath RDF 0 string Start:- GeoSwatch auf text file # Seabeam 2100 # mbsystem code mb41 0 string SB2100 SeaBeam 2100 multibeam sonar 0 string SB2100DR SeaBeam 2100 DR multibeam sonar 0 string SB2100PR SeaBeam 2100 PR multibeam sonar # This corresponds to MB-System format 94, L-3/ELAC/SeaBeam XSE vendor # format. It is the format of our upgraded SeaBeam 2112 on R/V KNORR. 0 string $HSF XSE multibeam # mb121 http://www.saic.com/maritime/gsf/ 8 string GSF-v SAIC generic sensor format (GSF) sonar data, >&0 regex [0-9]*\.[0-9]* version %s # MGD77 - http://www.ngdc.noaa.gov/mgg/dat/geodas/docs/mgd77.htm # mb161 9 string MGD77 MGD77 Header, Marine Geophysical Data Exchange Format # MBSystem processing caches the mbinfo output 1 string Swath\ Data\ File: mbsystem info cache # Caris John Hughes Clark format 0 string HDCS Caris multibeam sonar related data 1 string Start/Stop\ parameter\ header: Caris ASCII project summary ###################################################################### # # Visualization and 3D modeling # ###################################################################### # IVS - IVS3d.com Tagged Data Represetation 0 string %%\ TDR\ 2.0 IVS Fledermaus TDR file # http://www.ecma-international.org/publications/standards/Ecma-363.htm # 3D in PDFs 0 string U3D ECMA-363, Universal 3D ###################################################################### # # Support files # ###################################################################### # https://midas.psi.ch/elog/ 0 string $@MID@$ elog journal entry # Geospatial Designs http://www.geospatialdesigns.com/surfer6_format.htm 0 string DSBB Surfer 6 binary grid file >4 leshort x \b, %d >6 leshort x \bx%d >8 ledouble x \b, minx=%g >16 ledouble x \b, maxx=%g >24 ledouble x \b, miny=%g >32 ledouble x \b, maxy=%g >40 ledouble x \b, minz=%g >48 ledouble x \b, maxz=%g #------------------------------------------------------------------------------ # $File$ # GEOS files (Vidar Madsen, vidar@gimp.org) # semi-commonly used in embedded and handheld systems. 0 belong 0xc745c153 GEOS >40 byte 1 executable >40 byte 2 VMFile >40 byte 3 binary >40 byte 4 directory label >40 byte <1 unknown >40 byte >4 unknown >4 string >\0 \b, name "%s" #>44 short x \b, version %d #>46 short x \b.%d #>48 short x \b, rev %d #>50 short x \b.%d #>52 short x \b, proto %d #>54 short x \br%d #>168 string >\0 \b, copyright "%s" #------------------------------------------------------------------------------ # $File: gimp,v 1.8 2013/12/21 14:29:45 christos Exp $ # GIMP Gradient: file(1) magic for the GIMP's gradient data files (.ggr) # by Federico Mena 0 string/t GIMP\ Gradient GIMP gradient data # GIMP palette (.gpl) # From: Markus Heidelberg 0 string/t GIMP\ Palette GIMP palette data #------------------------------------------------------------------------------ # XCF: file(1) magic for the XCF image format used in the GIMP (.xcf) developed # by Spencer Kimball and Peter Mattis # ('Bucky' LaDieu, nega@vt.edu) 0 string gimp\ xcf GIMP XCF image data, !:mime image/x-xcf >9 string file version 0, >9 string v version >>10 string >\0 %s, >14 belong x %u x >18 belong x %u, >22 belong 0 RGB Color >22 belong 1 Greyscale >22 belong 2 Indexed Color >22 belong >2 Unknown Image Type. #------------------------------------------------------------------------------ # XCF: file(1) magic for the patterns used in the GIMP (.pat), developed # by Spencer Kimball and Peter Mattis # ('Bucky' LaDieu, nega@vt.edu) 20 string GPAT GIMP pattern data, >24 string x %s #------------------------------------------------------------------------------ # XCF: file(1) magic for the brushes used in the GIMP (.gbr), developed # by Spencer Kimball and Peter Mattis # ('Bucky' LaDieu, nega@vt.edu) 20 string GIMP GIMP brush data # GIMP Curves File # From: "Nelson A. de Oliveira" 0 string #\040GIMP\040Curves\040File GIMP curve file #------------------------------------------------------------------------------ # $File: gnome,v 1.4 2014/04/28 12:04:50 christos Exp $ # GNOME related files # Contributed by Josh Triplett # FIXME: Could be simplified if pstring supported two-byte counts 0 string GnomeKeyring\n\r\0\n GNOME keyring >&0 ubyte 0 \b, major version 0 >>&0 ubyte 0 \b, minor version 0 >>>&0 ubyte 0 \b, crypto type 0 (AES) >>>&0 ubyte >0 \b, crypto type %u (unknown) >>>&1 ubyte 0 \b, hash type 0 (MD5) >>>&1 ubyte >0 \b, hash type %u (unknown) >>>&2 ubelong 0xFFFFFFFF \b, name NULL >>>&2 ubelong !0xFFFFFFFF >>>>&-4 ubelong >255 \b, name too long for file's pstring type >>>>&-4 ubelong <256 >>>>>&-1 pstring x \b, name "%s" >>>>>>&0 ubeqdate x \b, last modified %s >>>>>>&8 ubeqdate x \b, created %s >>>>>>&16 ubelong &1 >>>>>>>&0 ubelong x \b, locked if idle for %u seconds >>>>>>&16 ubelong ^1 \b, not locked if idle >>>>>>&24 ubelong x \b, hash iterations %u >>>>>>&28 ubequad x \b, salt %llu >>>>>>&52 ubelong x \b, %u item(s) # From: Alex Beregszaszi 4 string gtktalog GNOME Catalogue (gtktalog) >13 string >\0 version %s # Summary: GStreamer binary registry # Extension: .bin # Submitted by: Josh Triplett 0 belong 0xc0def00d GStreamer binary registry >4 string x \b, version %s # GVariant Database file # By Elan Ruusamae # https://github.com/GNOME/gvdb/blob/master/gvdb-format.h # It's always "GVariant", it's byte swapped on incompatible archs # See https://github.com/GNOME/gvdb/blob/master/gvdb-builder.c # file_builder_serialise() # http://developer.gnome.org/glib/2.34/glib-GVariant.html#GVariant 0 string GVariant GVariant Database file, # version is never filled. probably future extension >8 lelong x version %d # not sure are these usable, so commented out #>>16 lelong x start %d, #>>>20 lelong x end %d # G-IR database made by gobject-introspect toolset, # http://live.gnome.org/GObjectIntrospection 0 string GOBJ\nMETADATA\r\n\032 G-IR binary database >16 byte x \b, v%d >17 byte x \b.%d >20 leshort x \b, %d entries >22 leshort x \b/%d local #------------------------------------------------------------------------------ # $File: gnu,v 1.14 2012/10/03 23:38:12 christos Exp $ # gnu: file(1) magic for various GNU tools # # GNU nlsutils message catalog file format # # GNU message catalog (.mo and .gmo files) 0 string \336\22\4\225 GNU message catalog (little endian), >6 leshort x revision %d. >4 leshort >0 \b%d, >>8 lelong x %d messages, >>36 lelong x %d sysdep messages >4 leshort =0 \b%d, >>8 lelong x %d messages 0 string \225\4\22\336 GNU message catalog (big endian), >4 beshort x revision %d. >6 beshort >0 \b%d, >>8 belong x %d messages, >>36 belong x %d sysdep messages >6 beshort =0 \b%d, >>8 belong x %d messages # GnuPG # The format is very similar to pgp 0 string \001gpg GPG key trust database >4 byte x version %d # Note: magic.mime had 0x8501 for the next line instead of 0x8502 0 beshort 0x8502 GPG encrypted data !:mime text/PGP # encoding: data # This magic is not particularly good, as the keyrings don't have true # magic. Nevertheless, it covers many keyrings. 0 beshort 0x9901 GPG key public ring !:mime application/x-gnupg-keyring # Symmetric encryption 0 leshort 0x0d8c >4 leshort 0x0203 >>2 leshort 0x0204 GPG symmetrically encrypted data (3DES cipher) >>2 leshort 0x0304 GPG symmetrically encrypted data (CAST5 cipher) >>2 leshort 0x0404 GPG symmetrically encrypted data (BLOWFISH cipher) >>2 leshort 0x0704 GPG symmetrically encrypted data (AES cipher) >>2 leshort 0x0804 GPG symmetrically encrypted data (AES192 cipher) >>2 leshort 0x0904 GPG symmetrically encrypted data (AES256 cipher) >>2 leshort 0x0a04 GPG symmetrically encrypted data (TWOFISH cipher) >>2 leshort 0x0b04 GPG symmetrically encrypted data (CAMELLIA128 cipher) >>2 leshort 0x0c04 GPG symmetrically encrypted data (CAMELLIA192 cipher) >>2 leshort 0x0d04 GPG symmetrically encrypted data (CAMELLIA256 cipher) # GnuPG Keybox file # # From: Philipp Hahn 0 belong 32 >4 byte 1 >>8 string KBXf GPG keybox database >>>5 byte 1 version %d >>>16 bedate x \b, created-at %s >>>20 bedate x \b, last-maintained %s # Gnumeric spreadsheet # This entry is only semi-helpful, as Gnumeric compresses its files, so # they will ordinarily reported as "compressed", but at least -z helps 39 string = # gnu find magic 0 string \0LOCATE GNU findutils locate database data >7 string >\0 \b, format %s >7 string 02 \b (frcode) # Files produced by GNU gettext 0 long 0xDE120495 GNU-format message catalog data 0 long 0x950412DE GNU-format message catalog data # gettext message catalogue 0 regex \^msgid\ GNU gettext message catalogue text !:mime text/x-po #------------------------------------------------------------------------------ # $File$ # gnumeric: file(1) magic for Gnumeric spreadsheet # This entry is only semi-helpful, as Gnumeric compresses its files, so # they will ordinarily reported as "compressed", but at least -z helps 39 string =>>>>>>>422) was copied from the X86 # partition table code (aka MBR). # This is kept separate, so that MBR partitions are not reported as well. # (use -k if you do want them as well) # First, detect the MBR partiton table # If more than one GPT protective MBR partition exists, don't print anything # (the other MBR detection code will then just print the MBR partition table) 0x1FE leshort 0xAA55 >3 string !MS >>3 string !SYSLINUX >>>3 string !MTOOL >>>>3 string !NEWLDR >>>>>5 string !DOS # not FAT (32 bit) >>>>>>82 string !FAT32 #not Linux kernel >>>>>>>514 string !HdrS #not BeOS >>>>>>>>422 string !Be\ Boot\ Loader # GPT with protective MBR entry in partition 1 (only) >>>>>>>>>450 ubyte 0xee >>>>>>>>>>466 ubyte !0xee >>>>>>>>>>>482 ubyte !0xee >>>>>>>>>>>>498 ubyte !0xee #>>>>>>>>>>>>>446 use gpt-mbr-partition >>>>>>>>>>>>>(454.l*8192) string EFI\ PART GPT partition table >>>>>>>>>>>>>>0 use gpt-mbr-type >>>>>>>>>>>>>>&-8 use gpt-table >>>>>>>>>>>>>>0 ubyte x of 8192 bytes >>>>>>>>>>>>>(454.l*8192) string !EFI\ PART >>>>>>>>>>>>>>(454.l*4096) string EFI\ PART GPT partition table >>>>>>>>>>>>>>>0 use gpt-mbr-type >>>>>>>>>>>>>>>&-8 use gpt-table >>>>>>>>>>>>>>>0 ubyte x of 4096 bytes >>>>>>>>>>>>>>(454.l*4096) string !EFI\ PART >>>>>>>>>>>>>>>(454.l*2048) string EFI\ PART GPT partition table >>>>>>>>>>>>>>>>0 use gpt-mbr-type >>>>>>>>>>>>>>>>&-8 use gpt-table >>>>>>>>>>>>>>>>0 ubyte x of 2048 bytes >>>>>>>>>>>>>>>(454.l*2048) string !EFI\ PART >>>>>>>>>>>>>>>>(454.l*1024) string EFI\ PART GPT partition table >>>>>>>>>>>>>>>>>0 use gpt-mbr-type >>>>>>>>>>>>>>>>>&-8 use gpt-table >>>>>>>>>>>>>>>>>0 ubyte x of 1024 bytes >>>>>>>>>>>>>>>>(454.l*1024) string !EFI\ PART >>>>>>>>>>>>>>>>>(454.l*512) string EFI\ PART GPT partition table >>>>>>>>>>>>>>>>>>0 use gpt-mbr-type >>>>>>>>>>>>>>>>>>&-8 use gpt-table >>>>>>>>>>>>>>>>>>0 ubyte x of 512 bytes # GPT with protective MBR entry in partition 2 (only) >>>>>>>>>450 ubyte !0xee >>>>>>>>>>466 ubyte 0xee >>>>>>>>>>>482 ubyte !0xee >>>>>>>>>>>>498 ubyte !0xee #>>>>>>>>>>>>>462 use gpt-mbr-partition >>>>>>>>>>>>>(470.l*8192) string EFI\ PART GPT partition table >>>>>>>>>>>>>>0 use gpt-mbr-type >>>>>>>>>>>>>>&-8 use gpt-table >>>>>>>>>>>>>>0 ubyte x of 8192 bytes >>>>>>>>>>>>>(470.l*8192) string !EFI\ PART >>>>>>>>>>>>>>(470.l*4096) string EFI\ PART GPT partition table >>>>>>>>>>>>>>>0 use gpt-mbr-type >>>>>>>>>>>>>>>&-8 use gpt-table >>>>>>>>>>>>>>>0 ubyte x of 4096 bytes >>>>>>>>>>>>>>(470.l*4096) string !EFI\ PART >>>>>>>>>>>>>>>(470.l*2048) string EFI\ PART GPT partition table >>>>>>>>>>>>>>>>0 use gpt-mbr-type >>>>>>>>>>>>>>>>&-8 use gpt-table >>>>>>>>>>>>>>>>0 ubyte x of 2048 bytes >>>>>>>>>>>>>>>(470.l*2048) string !EFI\ PART >>>>>>>>>>>>>>>>(470.l*1024) string EFI\ PART GPT partition table >>>>>>>>>>>>>>>>>0 use gpt-mbr-type >>>>>>>>>>>>>>>>>&-8 use gpt-table >>>>>>>>>>>>>>>>>0 ubyte x of 1024 bytes >>>>>>>>>>>>>>>>(470.l*1024) string !EFI\ PART >>>>>>>>>>>>>>>>>(470.l*512) string EFI\ PART GPT partition table >>>>>>>>>>>>>>>>>>0 use gpt-mbr-type >>>>>>>>>>>>>>>>>>&-8 use gpt-table >>>>>>>>>>>>>>>>>>0 ubyte x of 512 bytes # GPT with protective MBR entry in partition 3 (only) >>>>>>>>>450 ubyte !0xee >>>>>>>>>>466 ubyte !0xee >>>>>>>>>>>482 ubyte 0xee >>>>>>>>>>>>498 ubyte !0xee #>>>>>>>>>>>>>478 use gpt-mbr-partition >>>>>>>>>>>>>(486.l*8192) string EFI\ PART GPT partition table >>>>>>>>>>>>>>0 use gpt-mbr-type >>>>>>>>>>>>>>&-8 use gpt-table >>>>>>>>>>>>>>0 ubyte x of 8192 bytes >>>>>>>>>>>>>(486.l*8192) string !EFI\ PART >>>>>>>>>>>>>>(486.l*4096) string EFI\ PART GPT partition table >>>>>>>>>>>>>>>0 use gpt-mbr-type >>>>>>>>>>>>>>>&-8 use gpt-table >>>>>>>>>>>>>>>0 ubyte x of 4096 bytes >>>>>>>>>>>>>>(486.l*4096) string !EFI\ PART >>>>>>>>>>>>>>>(486.l*2048) string EFI\ PART GPT partition table >>>>>>>>>>>>>>>>0 use gpt-mbr-type >>>>>>>>>>>>>>>>&-8 use gpt-table >>>>>>>>>>>>>>>>0 ubyte x of 2048 bytes >>>>>>>>>>>>>>>(486.l*2048) string !EFI\ PART >>>>>>>>>>>>>>>>(486.l*1024) string EFI\ PART GPT partition table >>>>>>>>>>>>>>>>>0 use gpt-mbr-type >>>>>>>>>>>>>>>>>&-8 use gpt-table >>>>>>>>>>>>>>>>>0 ubyte x of 1024 bytes >>>>>>>>>>>>>>>>(486.l*1024) string !EFI\ PART >>>>>>>>>>>>>>>>>(486.l*512) string EFI\ PART GPT partition table >>>>>>>>>>>>>>>>>>0 use gpt-mbr-type >>>>>>>>>>>>>>>>>>&-8 use gpt-table >>>>>>>>>>>>>>>>>>0 ubyte x of 512 bytes # GPT with protective MBR entry in partition 4 (only) >>>>>>>>>450 ubyte !0xee >>>>>>>>>>466 ubyte !0xee >>>>>>>>>>>482 ubyte !0xee >>>>>>>>>>>>498 ubyte 0xee #>>>>>>>>>>>>>494 use gpt-mbr-partition >>>>>>>>>>>>>(502.l*8192) string EFI\ PART GPT partition table >>>>>>>>>>>>>>0 use gpt-mbr-type >>>>>>>>>>>>>>&-8 use gpt-table >>>>>>>>>>>>>>0 ubyte x of 8192 bytes >>>>>>>>>>>>>(502.l*8192) string !EFI\ PART >>>>>>>>>>>>>>(502.l*4096) string EFI\ PART GPT partition table >>>>>>>>>>>>>>>0 use gpt-mbr-type >>>>>>>>>>>>>>>&-8 use gpt-table >>>>>>>>>>>>>>>0 ubyte x of 4096 bytes >>>>>>>>>>>>>>(502.l*4096) string !EFI\ PART >>>>>>>>>>>>>>>(502.l*2048) string EFI\ PART GPT partition table >>>>>>>>>>>>>>>>0 use gpt-mbr-type >>>>>>>>>>>>>>>>&-8 use gpt-table >>>>>>>>>>>>>>>>0 ubyte x of 2048 bytes >>>>>>>>>>>>>>>(502.l*2048) string !EFI\ PART >>>>>>>>>>>>>>>>(502.l*1024) string EFI\ PART GPT partition table >>>>>>>>>>>>>>>>>0 use gpt-mbr-type >>>>>>>>>>>>>>>>>&-8 use gpt-table >>>>>>>>>>>>>>>>>0 ubyte x of 1024 bytes >>>>>>>>>>>>>>>>(502.l*1024) string !EFI\ PART >>>>>>>>>>>>>>>>>(502.l*512) string EFI\ PART GPT partition table >>>>>>>>>>>>>>>>>>0 use gpt-mbr-type >>>>>>>>>>>>>>>>>>&-8 use gpt-table >>>>>>>>>>>>>>>>>>0 ubyte x of 512 bytes # The following code does GPT detection and processing, including # sector size detection. # It has to be duplicated above because the top-level pattern # (i.e. not called using 'use') must print *something* for file # to count it as a match. Text only printed in named patterns is # not counted, and causes file to continue, and try and match # other patterns. # # Unfortunately, when assuming sector sizes >=16k, if the sector size # happens to be 512 instead, we may find confusing data after the GPT # table... If the GPT table has less than 128 entries, this may even # happen for assumed sector sizes as small as 4k # This could be solved by checking for the presence of the backup GPT # header as well, but that makes the logic extremely complex ##0 name gpt-mbr-partition ##>(8.l*8192) string EFI\ PART ##>>(8.l*8192) use gpt-mbr-type ##>>&-8 use gpt-table ##>>0 ubyte x of 8192 bytes ##>(8.l*8192) string !EFI\ PART ##>>(8.l*4096) string EFI\ PART GPT partition table ##>>>0 use gpt-mbr-type ##>>>&-8 use gpt-table ##>>>0 ubyte x of 4096 bytes ##>>(8.l*4096) string !EFI\ PART ##>>>(8.l*2048) string EFI\ PART GPT partition table ##>>>>0 use gpt-mbr-type ##>>>>&-8 use gpt-table ##>>>>0 ubyte x of 2048 bytes ##>>>(8.l*2048) string !EFI\ PART ##>>>>(8.l*1024) string EFI\ PART GPT partition table ##>>>>>0 use gpt-mbr-type ##>>>>>&-8 use gpt-table ##>>>>>0 ubyte x of 1024 bytes ##>>>>(8.l*1024) string !EFI\ PART ##>>>>>(8.l*512) string EFI\ PART GPT partition table ##>>>>>>0 use gpt-mbr-type ##>>>>>>&-8 use gpt-table ##>>>>>>0 ubyte x of 512 bytes # Print details of MBR type for a GPT-disk # Calling code ensures that there is only one 0xee partition. 0 name gpt-mbr-type # GPT with protective MBR entry in partition 1 >450 ubyte 0xee >>454 ulelong 1 >>>462 string !\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0 \b (with hybrid MBR) >>454 ulelong !1 \b (nonstandard: not at LBA 1) # GPT with protective MBR entry in partition 2 >466 ubyte 0xee >>470 ulelong 1 >>>478 string \0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0 >>>>446 string !\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0 \b (with hybrid MBR) >>>478 string !\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0 \b (with hybrid MBR) >>470 ulelong !1 \b (nonstandard: not at LBA 1) # GPT with protective MBR entry in partition 3 >482 ubyte 0xee >>486 ulelong 1 >>>494 string \0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0 >>>>446 string !\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0 \b (with hybrid MBR) >>>494 string !\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0 \b (with hybrid MBR) >>486 ulelong !1 \b (nonstandard: not at LBA 1) # GPT with protective MBR entry in partition 4 >498 ubyte 0xee >>502 ulelong 1 >>>446 string !\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0 \b (with hybrid MBR) >>502 ulelong !1 \b (nonstandard: not at LBA 1) # Print the information from a GPT partition table structure 0 name gpt-table >10 uleshort x \b, version %u >8 uleshort x \b.%u >56 ulelong x \b, GUID: %08x >60 uleshort x \b-%04x >62 uleshort x \b-%04x >64 ubeshort x \b-%04x >66 ubeshort x \b-%04x >68 ubelong x \b%08x #>80 uleshort x \b, %d partition entries >32 ulequad+1 x \b, disk size: %lld sectors # In case a GPT data-structure is at LBA 0, report it as well # This covers systems which are not GPT-aware, and which show # and allow access to the protective partition. This code will # detect the contents of such a partition. 0 string EFI\ PART GPT data structure (nonstandard: at LBA 0) >0 use gpt-table >0 ubyte x (sector size unknown) #------------------------------------------------------------------------------ # $File$ # ACE/gr and Grace type files - PLEASE DO NOT REMOVE THIS LINE # # ACE/gr binary 0 string \000\000\0001\000\000\0000\000\000\0000\000\000\0002\000\000\0000\000\000\0000\000\000\0003 old ACE/gr binary file >39 byte >0 - version %c # ACE/gr ascii 0 string #\ xvgr\ parameter\ file ACE/gr ascii file 0 string #\ xmgr\ parameter\ file ACE/gr ascii file 0 string #\ ACE/gr\ parameter\ file ACE/gr ascii file # Grace projects 0 string #\ Grace\ project\ file Grace project file >23 string @version\ (version >>32 byte >0 %c >>33 string >\0 \b.%.2s >>35 string >\0 \b.%.2s) # ACE/gr fit description files 0 string #\ ACE/gr\ fit\ description\ ACE/gr fit description file # end of ACE/gr and Grace type files - PLEASE DO NOT REMOVE THIS LINE #------------------------------------------------------------------------------ # $File: graphviz,v 1.7 2009/09/19 16:28:09 christos Exp $ # graphviz: file(1) magic for http://www.graphviz.org/ # FIXME: These patterns match too generally. For example, the first # line matches a LaTeX file containing the word "graph" (with a { # following later) and the second line matches this file. #0 regex/100l [\r\n\t\ ]*graph[\r\n\t\ ]+.*\\{ graphviz graph text #!:mime text/vnd.graphviz #0 regex/100l [\r\n\t\ ]*digraph[\r\n\t\ ]+.*\\{ graphviz digraph text #!:mime text/vnd.graphviz #------------------------------------------------------------------------------ # $File$ # gringotts: file(1) magic for Gringotts # http://devel.pluto.linux.it/projects/Gringotts/ # author: Germano Rizzo #GRG3????Y 0 string GRG Gringotts data file #file format 1 >3 string 1 v.1, MCRYPT S2K, SERPENT crypt, SHA-256 hash, ZLib lvl.9 #file format 2 >3 string 2 v.2, MCRYPT S2K, >>8 byte&0x70 0x00 RIJNDAEL-128 crypt, >>8 byte&0x70 0x10 SERPENT crypt, >>8 byte&0x70 0x20 TWOFISH crypt, >>8 byte&0x70 0x30 CAST-256 crypt, >>8 byte&0x70 0x40 SAFER+ crypt, >>8 byte&0x70 0x50 LOKI97 crypt, >>8 byte&0x70 0x60 3DES crypt, >>8 byte&0x70 0x70 RIJNDAEL-256 crypt, >>8 byte&0x08 0x00 SHA1 hash, >>8 byte&0x08 0x08 RIPEMD-160 hash, >>8 byte&0x04 0x00 ZLib >>8 byte&0x04 0x04 BZip2 >>8 byte&0x03 0x00 lvl.0 >>8 byte&0x03 0x01 lvl.3 >>8 byte&0x03 0x02 lvl.6 >>8 byte&0x03 0x03 lvl.9 #file format 3 >3 string 3 v.3, OpenPGP S2K, >>8 byte&0x70 0x00 RIJNDAEL-128 crypt, >>8 byte&0x70 0x10 SERPENT crypt, >>8 byte&0x70 0x20 TWOFISH crypt, >>8 byte&0x70 0x30 CAST-256 crypt, >>8 byte&0x70 0x40 SAFER+ crypt, >>8 byte&0x70 0x50 LOKI97 crypt, >>8 byte&0x70 0x60 3DES crypt, >>8 byte&0x70 0x70 RIJNDAEL-256 crypt, >>8 byte&0x08 0x00 SHA1 hash, >>8 byte&0x08 0x08 RIPEMD-160 hash, >>8 byte&0x04 0x00 ZLib >>8 byte&0x04 0x04 BZip2 >>8 byte&0x03 0x00 lvl.0 >>8 byte&0x03 0x01 lvl.3 >>8 byte&0x03 0x02 lvl.6 >>8 byte&0x03 0x03 lvl.9 #file format >3 >3 string >3 v.%.1s (unknown details) #------------------------------------------------------------------------------ # $File: grace,v 1.4 2009/09/19 16:28:09 christos Exp $ # Guile file magic from # http://www.gnu.org/s/guile/ # http://git.savannah.gnu.org/gitweb/?p=guile.git;f=libguile/_scm.h;hb=HEAD#l250 0 string GOOF---- Guile Object >8 string LE \b, little endian >8 string BE \b, big endian >11 string 4 \b, 32bit >11 string 8 \b, 64bit >13 regex .\.. \b, bytecode v%s #------------------------------------------------------------------------------ # $File: hitachi-sh,v 1.5 2009/09/19 16:28:09 christos Exp $ # hitach-sh: file(1) magic for Hitachi Super-H # # Super-H COFF # # below test line conflicts with 2nd NTFS filesystem sector 0 beshort 0x0500 Hitachi SH big-endian COFF # 2nd NTFS filesystem sector often starts with 0x05004e00 for unicode string 5 NTLDR #0 ubelong&0xFFFFNMPQ 0x0500NMPQ Hitachi SH big-endian COFF >18 beshort&0x0002 =0x0000 object >18 beshort&0x0002 =0x0002 executable >18 beshort&0x0008 =0x0008 \b, stripped >18 beshort&0x0008 =0x0000 \b, not stripped # 0 leshort 0x0550 Hitachi SH little-endian COFF >18 leshort&0x0002 =0x0000 object >18 leshort&0x0002 =0x0002 executable >18 leshort&0x0008 =0x0008 \b, stripped >18 leshort&0x0008 =0x0000 \b, not stripped #------------------------------------------------------------------------------ # $File: hp,v 1.23 2009/09/19 16:28:09 christos Exp $ # hp: file(1) magic for Hewlett Packard machines (see also "printer") # # XXX - somebody should figure out whether any byte order needs to be # applied to the "TML" stuff; I'm assuming the Apollo stuff is # big-endian as it was mostly 68K-based. # # I think the 500 series was the old stack-based machines, running a # UNIX environment atop the "SUN kernel"; dunno whether it was # big-endian or little-endian. # # Daniel Quinlan (quinlan@yggdrasil.com): hp200 machines are 68010 based; # hp300 are 68020+68881 based; hp400 are also 68k. The following basic # HP magic is useful for reference, but using "long" magic is a better # practice in order to avoid collisions. # # Guy Harris (guy@netapp.com): some additions to this list came from # HP-UX 10.0's "/usr/include/sys/unistd.h" (68030, 68040, PA-RISC 1.1, # 1.2, and 2.0). The 1.2 and 2.0 stuff isn't in the HP-UX 10.0 # "/etc/magic", though, except for the "archive file relocatable library" # stuff, and the 68030 and 68040 stuff isn't there at all - are they not # used in executables, or have they just not yet updated "/etc/magic" # completely? # # 0 beshort 200 hp200 (68010) BSD binary # 0 beshort 300 hp300 (68020+68881) BSD binary # 0 beshort 0x20c hp200/300 HP-UX binary # 0 beshort 0x20d hp400 (68030) HP-UX binary # 0 beshort 0x20e hp400 (68040?) HP-UX binary # 0 beshort 0x20b PA-RISC1.0 HP-UX binary # 0 beshort 0x210 PA-RISC1.1 HP-UX binary # 0 beshort 0x211 PA-RISC1.2 HP-UX binary # 0 beshort 0x214 PA-RISC2.0 HP-UX binary # # The "misc" stuff needs a byte order; the archives look suspiciously # like the old 177545 archives (0xff65 = 0177545). # #### Old Apollo stuff 0 beshort 0627 Apollo m68k COFF executable >18 beshort ^040000 not stripped >22 beshort >0 - version %d 0 beshort 0624 apollo a88k COFF executable >18 beshort ^040000 not stripped >22 beshort >0 - version %d 0 long 01203604016 TML 0123 byte-order format 0 long 01702407010 TML 1032 byte-order format 0 long 01003405017 TML 2301 byte-order format 0 long 01602007412 TML 3210 byte-order format #### PA-RISC 1.1 0 belong 0x02100106 PA-RISC1.1 relocatable object 0 belong 0x02100107 PA-RISC1.1 executable >168 belong &0x00000004 dynamically linked >(144) belong 0x054ef630 dynamically linked >96 belong >0 - not stripped 0 belong 0x02100108 PA-RISC1.1 shared executable >168 belong&0x4 0x4 dynamically linked >(144) belong 0x054ef630 dynamically linked >96 belong >0 - not stripped 0 belong 0x0210010b PA-RISC1.1 demand-load executable >168 belong&0x4 0x4 dynamically linked >(144) belong 0x054ef630 dynamically linked >96 belong >0 - not stripped 0 belong 0x0210010e PA-RISC1.1 shared library >96 belong >0 - not stripped 0 belong 0x0210010d PA-RISC1.1 dynamic load library >96 belong >0 - not stripped #### PA-RISC 2.0 0 belong 0x02140106 PA-RISC2.0 relocatable object 0 belong 0x02140107 PA-RISC2.0 executable >168 belong &0x00000004 dynamically linked >(144) belong 0x054ef630 dynamically linked >96 belong >0 - not stripped 0 belong 0x02140108 PA-RISC2.0 shared executable >168 belong &0x00000004 dynamically linked >(144) belong 0x054ef630 dynamically linked >96 belong >0 - not stripped 0 belong 0x0214010b PA-RISC2.0 demand-load executable >168 belong &0x00000004 dynamically linked >(144) belong 0x054ef630 dynamically linked >96 belong >0 - not stripped 0 belong 0x0214010e PA-RISC2.0 shared library >96 belong >0 - not stripped 0 belong 0x0214010d PA-RISC2.0 dynamic load library >96 belong >0 - not stripped #### 800 0 belong 0x020b0106 PA-RISC1.0 relocatable object 0 belong 0x020b0107 PA-RISC1.0 executable >168 belong&0x4 0x4 dynamically linked >(144) belong 0x054ef630 dynamically linked >96 belong >0 - not stripped 0 belong 0x020b0108 PA-RISC1.0 shared executable >168 belong&0x4 0x4 dynamically linked >(144) belong 0x054ef630 dynamically linked >96 belong >0 - not stripped 0 belong 0x020b010b PA-RISC1.0 demand-load executable >168 belong&0x4 0x4 dynamically linked >(144) belong 0x054ef630 dynamically linked >96 belong >0 - not stripped 0 belong 0x020b010e PA-RISC1.0 shared library >96 belong >0 - not stripped 0 belong 0x020b010d PA-RISC1.0 dynamic load library >96 belong >0 - not stripped 0 belong 0x213c6172 archive file >68 belong 0x020b0619 - PA-RISC1.0 relocatable library >68 belong 0x02100619 - PA-RISC1.1 relocatable library >68 belong 0x02110619 - PA-RISC1.2 relocatable library >68 belong 0x02140619 - PA-RISC2.0 relocatable library #### 500 0 long 0x02080106 HP s500 relocatable executable >16 long >0 - version %d 0 long 0x02080107 HP s500 executable >16 long >0 - version %d 0 long 0x02080108 HP s500 pure executable >16 long >0 - version %d #### 200 0 belong 0x020c0108 HP s200 pure executable >4 beshort >0 - version %d >8 belong &0x80000000 save fp regs >8 belong &0x40000000 dynamically linked >8 belong &0x20000000 debuggable >36 belong >0 not stripped 0 belong 0x020c0107 HP s200 executable >4 beshort >0 - version %d >8 belong &0x80000000 save fp regs >8 belong &0x40000000 dynamically linked >8 belong &0x20000000 debuggable >36 belong >0 not stripped 0 belong 0x020c010b HP s200 demand-load executable >4 beshort >0 - version %d >8 belong &0x80000000 save fp regs >8 belong &0x40000000 dynamically linked >8 belong &0x20000000 debuggable >36 belong >0 not stripped 0 belong 0x020c0106 HP s200 relocatable executable >4 beshort >0 - version %d >6 beshort >0 - highwater %d >8 belong &0x80000000 save fp regs >8 belong &0x20000000 debuggable >8 belong &0x10000000 PIC 0 belong 0x020a0108 HP s200 (2.x release) pure executable >4 beshort >0 - version %d >36 belong >0 not stripped 0 belong 0x020a0107 HP s200 (2.x release) executable >4 beshort >0 - version %d >36 belong >0 not stripped 0 belong 0x020c010e HP s200 shared library >4 beshort >0 - version %d >6 beshort >0 - highwater %d >36 belong >0 not stripped 0 belong 0x020c010d HP s200 dynamic load library >4 beshort >0 - version %d >6 beshort >0 - highwater %d >36 belong >0 not stripped #### MISC 0 long 0x0000ff65 HP old archive 0 long 0x020aff65 HP s200 old archive 0 long 0x020cff65 HP s200 old archive 0 long 0x0208ff65 HP s500 old archive 0 long 0x015821a6 HP core file 0 long 0x4da7eee8 HP-WINDOWS font >8 byte >0 - version %d 0 string Bitmapfile HP Bitmapfile 0 string IMGfile CIS compimg HP Bitmapfile # XXX - see "lif" #0 short 0x8000 lif file 0 long 0x020c010c compiled Lisp 0 string msgcat01 HP NLS message catalog, >8 long >0 %d messages # Summary: HP-48/49 calculator # Created by: phk@data.fls.dk # Modified by (1): AMAKAWA Shuhei # Modified by (2): Samuel Thibault (HP49 support) 0 string HPHP HP >4 string 48 48 binary >4 string 49 49 binary >7 byte >64 - Rev %c >8 leshort 0x2911 (ADR) >8 leshort 0x2933 (REAL) >8 leshort 0x2955 (LREAL) >8 leshort 0x2977 (COMPLX) >8 leshort 0x299d (LCOMPLX) >8 leshort 0x29bf (CHAR) >8 leshort 0x29e8 (ARRAY) >8 leshort 0x2a0a (LNKARRAY) >8 leshort 0x2a2c (STRING) >8 leshort 0x2a4e (HXS) >8 leshort 0x2a74 (LIST) >8 leshort 0x2a96 (DIR) >8 leshort 0x2ab8 (ALG) >8 leshort 0x2ada (UNIT) >8 leshort 0x2afc (TAGGED) >8 leshort 0x2b1e (GROB) >8 leshort 0x2b40 (LIB) >8 leshort 0x2b62 (BACKUP) >8 leshort 0x2b88 (LIBDATA) >8 leshort 0x2d9d (PROG) >8 leshort 0x2dcc (CODE) >8 leshort 0x2e48 (GNAME) >8 leshort 0x2e6d (LNAME) >8 leshort 0x2e92 (XLIB) 0 string %%HP: HP text >6 string T(0) - T(0) >6 string T(1) - T(1) >6 string T(2) - T(2) >6 string T(3) - T(3) >10 string A(D) A(D) >10 string A(R) A(R) >10 string A(G) A(G) >14 string F(.) F(.); >14 string F(,) F(,); # Summary: HP-38/39 calculator # Created by: Samuel Thibault 0 string HP3 >3 string 8 HP 38 >3 string 9 HP 39 >4 string Bin binary >4 string Asc ASCII >7 string A (Directory List) >7 string B (Zaplet) >7 string C (Note) >7 string D (Program) >7 string E (Variable) >7 string F (List) >7 string G (Matrix) >7 string H (Library) >7 string I (Target List) >7 string J (ASCII Vector specification) >7 string K (wildcard) # Summary: HP-38/39 calculator # Created by: Samuel Thibault 0 string HP3 >3 string 8 HP 38 >3 string 9 HP 39 >4 string Bin binary >4 string Asc ASCII >7 string A (Directory List) >7 string B (Zaplet) >7 string C (Note) >7 string D (Program) >7 string E (Variable) >7 string F (List) >7 string G (Matrix) >7 string H (Library) >7 string I (Target List) >7 string J (ASCII Vector specification) >7 string K (wildcard) # hpBSD magic numbers 0 beshort 200 hp200 (68010) BSD >2 beshort 0407 impure binary >2 beshort 0410 read-only binary >2 beshort 0413 demand paged binary 0 beshort 300 hp300 (68020+68881) BSD >2 beshort 0407 impure binary >2 beshort 0410 read-only binary >2 beshort 0413 demand paged binary # # From David Gero # HP-UX 10.20 core file format from /usr/include/sys/core.h # Unfortunately, HP-UX uses corehead blocks without specifying the order # There are four we care about: # CORE_KERNEL, which starts with the string "HP-UX" # CORE_EXEC, which contains the name of the command # CORE_PROC, which contains the signal number that caused the core dump # CORE_FORMAT, which contains the version of the core file format (== 1) # The only observed order in real core files is KERNEL, EXEC, FORMAT, PROC # but we include all 6 variations of the order of the first 3, and # assume that PROC will always be last # Order 1: KERNEL, EXEC, FORMAT, PROC 0x10 string HP-UX >0 belong 2 >>0xC belong 0x3C >>>0x4C belong 0x100 >>>>0x58 belong 0x44 >>>>>0xA0 belong 1 >>>>>>0xAC belong 4 >>>>>>>0xB0 belong 1 >>>>>>>>0xB4 belong 4 core file >>>>>>>>>0x90 string >\0 from '%s' >>>>>>>>>0xC4 belong 3 - received SIGQUIT >>>>>>>>>0xC4 belong 4 - received SIGILL >>>>>>>>>0xC4 belong 5 - received SIGTRAP >>>>>>>>>0xC4 belong 6 - received SIGABRT >>>>>>>>>0xC4 belong 7 - received SIGEMT >>>>>>>>>0xC4 belong 8 - received SIGFPE >>>>>>>>>0xC4 belong 10 - received SIGBUS >>>>>>>>>0xC4 belong 11 - received SIGSEGV >>>>>>>>>0xC4 belong 12 - received SIGSYS >>>>>>>>>0xC4 belong 33 - received SIGXCPU >>>>>>>>>0xC4 belong 34 - received SIGXFSZ # Order 2: KERNEL, FORMAT, EXEC, PROC >>>0x4C belong 1 >>>>0x58 belong 4 >>>>>0x5C belong 1 >>>>>>0x60 belong 0x100 >>>>>>>0x6C belong 0x44 >>>>>>>>0xB4 belong 4 core file >>>>>>>>>0xA4 string >\0 from '%s' >>>>>>>>>0xC4 belong 3 - received SIGQUIT >>>>>>>>>0xC4 belong 4 - received SIGILL >>>>>>>>>0xC4 belong 5 - received SIGTRAP >>>>>>>>>0xC4 belong 6 - received SIGABRT >>>>>>>>>0xC4 belong 7 - received SIGEMT >>>>>>>>>0xC4 belong 8 - received SIGFPE >>>>>>>>>0xC4 belong 10 - received SIGBUS >>>>>>>>>0xC4 belong 11 - received SIGSEGV >>>>>>>>>0xC4 belong 12 - received SIGSYS >>>>>>>>>0xC4 belong 33 - received SIGXCPU >>>>>>>>>0xC4 belong 34 - received SIGXFSZ # Order 3: FORMAT, KERNEL, EXEC, PROC 0x24 string HP-UX >0 belong 1 >>0xC belong 4 >>>0x10 belong 1 >>>>0x14 belong 2 >>>>>0x20 belong 0x3C >>>>>>0x60 belong 0x100 >>>>>>>0x6C belong 0x44 >>>>>>>>0xB4 belong 4 core file >>>>>>>>>0xA4 string >\0 from '%s' >>>>>>>>>0xC4 belong 3 - received SIGQUIT >>>>>>>>>0xC4 belong 4 - received SIGILL >>>>>>>>>0xC4 belong 5 - received SIGTRAP >>>>>>>>>0xC4 belong 6 - received SIGABRT >>>>>>>>>0xC4 belong 7 - received SIGEMT >>>>>>>>>0xC4 belong 8 - received SIGFPE >>>>>>>>>0xC4 belong 10 - received SIGBUS >>>>>>>>>0xC4 belong 11 - received SIGSEGV >>>>>>>>>0xC4 belong 12 - received SIGSYS >>>>>>>>>0xC4 belong 33 - received SIGXCPU >>>>>>>>>0xC4 belong 34 - received SIGXFSZ # Order 4: EXEC, KERNEL, FORMAT, PROC 0x64 string HP-UX >0 belong 0x100 >>0xC belong 0x44 >>>0x54 belong 2 >>>>0x60 belong 0x3C >>>>>0xA0 belong 1 >>>>>>0xAC belong 4 >>>>>>>0xB0 belong 1 >>>>>>>>0xB4 belong 4 core file >>>>>>>>>0x44 string >\0 from '%s' >>>>>>>>>0xC4 belong 3 - received SIGQUIT >>>>>>>>>0xC4 belong 4 - received SIGILL >>>>>>>>>0xC4 belong 5 - received SIGTRAP >>>>>>>>>0xC4 belong 6 - received SIGABRT >>>>>>>>>0xC4 belong 7 - received SIGEMT >>>>>>>>>0xC4 belong 8 - received SIGFPE >>>>>>>>>0xC4 belong 10 - received SIGBUS >>>>>>>>>0xC4 belong 11 - received SIGSEGV >>>>>>>>>0xC4 belong 12 - received SIGSYS >>>>>>>>>0xC4 belong 33 - received SIGXCPU >>>>>>>>>0xC4 belong 34 - received SIGXFSZ # Order 5: FORMAT, EXEC, KERNEL, PROC 0x78 string HP-UX >0 belong 1 >>0xC belong 4 >>>0x10 belong 1 >>>>0x14 belong 0x100 >>>>>0x20 belong 0x44 >>>>>>0x68 belong 2 >>>>>>>0x74 belong 0x3C >>>>>>>>0xB4 belong 4 core file >>>>>>>>>0x58 string >\0 from '%s' >>>>>>>>>0xC4 belong 3 - received SIGQUIT >>>>>>>>>0xC4 belong 4 - received SIGILL >>>>>>>>>0xC4 belong 5 - received SIGTRAP >>>>>>>>>0xC4 belong 6 - received SIGABRT >>>>>>>>>0xC4 belong 7 - received SIGEMT >>>>>>>>>0xC4 belong 8 - received SIGFPE >>>>>>>>>0xC4 belong 10 - received SIGBUS >>>>>>>>>0xC4 belong 11 - received SIGSEGV >>>>>>>>>0xC4 belong 12 - received SIGSYS >>>>>>>>>0xC4 belong 33 - received SIGXCPU >>>>>>>>>0xC4 belong 34 - received SIGXFSZ # Order 6: EXEC, FORMAT, KERNEL, PROC >0 belong 0x100 >>0xC belong 0x44 >>>0x54 belong 1 >>>>0x60 belong 4 >>>>>0x64 belong 1 >>>>>>0x68 belong 2 >>>>>>>0x74 belong 0x2C >>>>>>>>0xB4 belong 4 core file >>>>>>>>>0x44 string >\0 from '%s' >>>>>>>>>0xC4 belong 3 - received SIGQUIT >>>>>>>>>0xC4 belong 4 - received SIGILL >>>>>>>>>0xC4 belong 5 - received SIGTRAP >>>>>>>>>0xC4 belong 6 - received SIGABRT >>>>>>>>>0xC4 belong 7 - received SIGEMT >>>>>>>>>0xC4 belong 8 - received SIGFPE >>>>>>>>>0xC4 belong 10 - received SIGBUS >>>>>>>>>0xC4 belong 11 - received SIGSEGV >>>>>>>>>0xC4 belong 12 - received SIGSYS >>>>>>>>>0xC4 belong 33 - received SIGXCPU >>>>>>>>>0xC4 belong 34 - received SIGXFSZ #------------------------------------------------------------------------------ # $File$ # human68k: file(1) magic for Human68k (X680x0 DOS) binary formats # Magic too short! #0 string HU Human68k #>68 string LZX LZX compressed #>>72 string >\0 (version %s) #>(8.L+74) string LZX LZX compressed #>>(8.L+78) string >\0 (version %s) #>60 belong >0 binded #>(8.L+66) string #HUPAIR hupair #>0 string HU X executable #>(8.L+74) string #LIBCV1 - linked PD LIBC ver 1 #>4 belong >0 - base address 0x%x #>28 belong >0 not stripped #>32 belong >0 with debug information #0 beshort 0x601a Human68k Z executable #0 beshort 0x6000 Human68k object file #0 belong 0xd1000000 Human68k ar binary archive #0 belong 0xd1010000 Human68k ar ascii archive #0 beshort 0x0068 Human68k lib archive #4 string LZX Human68k LZX compressed #>8 string >\0 (version %s) #>4 string LZX R executable #2 string #HUPAIR Human68k hupair R executable #------------------------------------------------------------------------------ # $File: ibm370,v 1.8 2009/09/19 16:28:09 christos Exp $ # ibm370: file(1) magic for IBM 370 and compatibles. # # "ibm370" said that 0x15d == 0535 was "ibm 370 pure executable". # What the heck *is* "USS/370"? # AIX 4.1's "/etc/magic" has # # 0 short 0535 370 sysV executable # >12 long >0 not stripped # >22 short >0 - version %d # >30 long >0 - 5.2 format # 0 short 0530 370 sysV pure executable # >12 long >0 not stripped # >22 short >0 - version %d # >30 long >0 - 5.2 format # # instead of the "USS/370" versions of the same magic numbers. # 0 beshort 0537 370 XA sysV executable >12 belong >0 not stripped >22 beshort >0 - version %d >30 belong >0 - 5.2 format 0 beshort 0532 370 XA sysV pure executable >12 belong >0 not stripped >22 beshort >0 - version %d >30 belong >0 - 5.2 format 0 beshort 054001 370 sysV pure executable >12 belong >0 not stripped 0 beshort 055001 370 XA sysV pure executable >12 belong >0 not stripped 0 beshort 056401 370 sysV executable >12 belong >0 not stripped 0 beshort 057401 370 XA sysV executable >12 belong >0 not stripped 0 beshort 0531 SVR2 executable (Amdahl-UTS) >12 belong >0 not stripped >24 belong >0 - version %d 0 beshort 0534 SVR2 pure executable (Amdahl-UTS) >12 belong >0 not stripped >24 belong >0 - version %d 0 beshort 0530 SVR2 pure executable (USS/370) >12 belong >0 not stripped >24 belong >0 - version %d 0 beshort 0535 SVR2 executable (USS/370) >12 belong >0 not stripped >24 belong >0 - version %d #------------------------------------------------------------------------------ # $File: ibm6000,v 1.11 2013/01/08 20:13:01 christos Exp $ # ibm6000: file(1) magic for RS/6000 and the RT PC. # 0 beshort 0x01df executable (RISC System/6000 V3.1) or obj module >12 belong >0 not stripped # Breaks sun4 statically linked execs. #0 beshort 0x0103 executable (RT Version 2) or obj module #>2 byte 0x50 pure #>28 belong >0 not stripped #>6 beshort >0 - version %ld 0 beshort 0x0104 shared library 0 beshort 0x0105 ctab data 0 beshort 0xfe04 structured file 0 string 0xabcdef AIX message catalog 0 belong 0x000001f9 AIX compiled message catalog 0 string \ archive 0 string \ archive (big format) 0 beshort 0x01f7 64-bit XCOFF executable or object module >20 belong 0 not stripped # GRR: this test is still too general as it catches also many FATs of DOS filesystems 4 belong &0x0feeddb0 # real core dump could not be 32-bit and 64-bit together >7 byte&0x03 !3 AIX core file >>1 byte &0x01 fulldump >>7 byte &0x01 32-bit >>>0x6e0 string >\0 \b, %s >>7 byte &0x02 64-bit >>>0x524 string >\0 \b, %s #------------------------------------------------------------------------------ # $File$ # icc: file(1) magic for International Color Consortium file formats # # Color profiles as per the ICC's "Image technology colour management - # Architecture, profile format, and data structure" specification. # See # # http://www.color.org/specification/ICC1v43_2010-12.pdf # # for Specification ICC.1:2010 (Profile version 4.3.0.0). # # Bytes 36 to 39 contain a generic profile file signature of "acsp"; # bytes 40 to 43 "may be used to identify the primary platform/operating # system framework for which the profile was created". # # There are other fields that might be worth dumping as well. # # This appears to be what's used for Apple ColorSync profiles. # Instead of adding that, Apple just changed the generic "acsp" entry # to be for "ColorSync ICC Color Profile" rather than "Kodak Color # Management System, ICC Profile". # Yes, it's "APPL", not "AAPL"; see the spec. 36 string acspAPPL ColorSync ICC Profile !:mime application/vnd.iccprofile # Microsoft ICM color profile 36 string acspMSFT Microsoft ICM Color Profile !:mime application/vnd.iccprofile # Yes, that's a blank after "SGI". 36 string acspSGI\ SGI ICC Profile !:mime application/vnd.iccprofile # XXX - is this what's used for the Sun KCMS or not? The standard file # uses just "acsp" for that, but Apple's file uses it for "ColorSync", # and there *is* an identified "primary platform" value of SUNW. 36 string acspSUNW Sun KCMS ICC Profile !:mime application/vnd.iccprofile # Any other profile. # XXX - should we use "acsp\0\0\0\0" for "no primary platform" profiles, # and use "acsp" for everything else and dump the "primary platform" # string in those cases? 36 string acsp ICC Profile !:mime application/vnd.iccprofile #------------------------------------------------------------------------------ # $File: iff,v 1.12 2009/09/19 16:28:09 christos Exp $ # iff: file(1) magic for Interchange File Format (see also "audio" & "images") # # Daniel Quinlan (quinlan@yggdrasil.com) -- IFF was designed by Electronic # Arts for file interchange. It has also been used by Apple, SGI, and # especially Commodore-Amiga. # # IFF files begin with an 8 byte FORM header, followed by a 4 character # FORM type, which is followed by the first chunk in the FORM. 0 string FORM IFF data #>4 belong x \b, FORM is %d bytes long # audio formats >8 string AIFF \b, AIFF audio !:mime audio/x-aiff >8 string AIFC \b, AIFF-C compressed audio !:mime audio/x-aiff >8 string 8SVX \b, 8SVX 8-bit sampled sound voice !:mime audio/x-aiff >8 string 16SV \b, 16SV 16-bit sampled sound voice >8 string SAMP \b, SAMP sampled audio >8 string MAUD \b, MAUD MacroSystem audio >8 string SMUS \b, SMUS simple music >8 string CMUS \b, CMUS complex music # image formats >8 string ILBMBMHD \b, ILBM interleaved image >>20 beshort x \b, %d x >>22 beshort x %d >8 string RGBN \b, RGBN 12-bit RGB image >8 string RGB8 \b, RGB8 24-bit RGB image >8 string DEEP \b, DEEP TVPaint/XiPaint image >8 string DR2D \b, DR2D 2-D object >8 string TDDD \b, TDDD 3-D rendering >8 string LWOB \b, LWOB 3-D object >8 string LWO2 \b, LWO2 3-D object, v2 >8 string LWLO \b, LWLO 3-D layered object >8 string REAL \b, REAL Real3D rendering >8 string MC4D \b, MC4D MaxonCinema4D rendering >8 string ANIM \b, ANIM animation >8 string YAFA \b, YAFA animation >8 string SSA\ \b, SSA super smooth animation >8 string ACBM \b, ACBM continuous image >8 string FAXX \b, FAXX fax image # other formats >8 string FTXT \b, FTXT formatted text >8 string CTLG \b, CTLG message catalog >8 string PREF \b, PREF preferences >8 string DTYP \b, DTYP datatype description >8 string PTCH \b, PTCH binary patch >8 string AMFF \b, AMFF AmigaMetaFile format >8 string WZRD \b, WZRD StormWIZARD resource >8 string DOC\ \b, DOC desktop publishing document >8 string WVQA \b, Westwood Studios VQA Multimedia, >>24 leshort x %d video frames, >>26 leshort x %d x >>28 leshort x %d >8 string MOVE \b, Wing Commander III Video >>12 string _PC_ \b, PC version >>12 string 3DO_ \b, 3DO version # These go at the end of the iff rules # # I don't see why these might collide with anything else. # # Interactive Fiction related formats # >8 string IFRS \b, Blorb Interactive Fiction >>24 string Exec with executable chunk >8 string IFZS \b, Z-machine or Glulx saved game file (Quetzal) #------------------------------------------------------------------------------ # $File: images,v 1.105 2015/02/14 17:30:03 christos Exp $ # images: file(1) magic for image formats (see also "iff", and "c-lang" for # XPM bitmaps) # # originally from jef@helios.ee.lbl.gov (Jef Poskanzer), # additions by janl@ifi.uio.no as well as others. Jan also suggested # merging several one- and two-line files into here. # # little magic: PCX (first byte is 0x0a) # Targa - matches `povray', `ppmtotga' and `xv' outputs # by Philippe De Muyter # at 2, byte ImgType must be 1, 2, 3, 9, 10 or 11 # at 1, byte CoMapType must be 1 if ImgType is 1 or 9, 0 otherwise # at 3, leshort Index is 0 for povray, ppmtotga and xv outputs # `xv' recognizes only a subset of the following (RGB with pixelsize = 24) # `tgatoppm' recognizes a superset (Index may be anything) 1 belong&0xfff7ffff 0x01010000 Targa image data - Map !:strength + 2 >2 byte&8 8 - RLE >12 leshort >0 %d x >14 leshort >0 %d 1 belong&0xfff7ffff 0x00020000 Targa image data - RGB !:strength + 2 >2 byte&8 8 - RLE >12 leshort >0 %d x >14 leshort >0 %d 1 belong&0xfff7ffff 0x00030000 Targa image data - Mono !:strength + 2 >2 byte&8 8 - RLE >12 leshort >0 %d x >14 leshort >0 %d # PBMPLUS images # The next byte following the magic is always whitespace. # strength is changed to try these patterns before "x86 boot sector" 0 name netpbm >3 regex/s =[0-9]{1,50}\ [0-9]{1,50} Netpbm PPM image data >>&0 regex =[0-9]{1,50} \b, size = %s x >>>&0 regex =[0-9]{1,50} \b %s 0 search/1 P1 >0 use netpbm >>0 string x \b, bitmap !:strength + 45 !:mime image/x-portable-bitmap 0 search/1 P2 >0 use netpbm >>0 string x \b, greymap !:strength + 45 !:mime image/x-portable-greymap 0 search/1 P3 >0 use netpbm >>0 string x \b, pixmap !:strength + 45 !:mime image/x-portable-pixmap 0 string P4 >0 use netpbm >>0 string x \b, rawbits, bitmap !:strength + 45 !:mime image/x-portable-bitmap 0 string P5 >0 use netpbm >>0 string x \b, rawbits, greymap !:strength + 45 !:mime image/x-portable-greymap 0 string P6 >0 use netpbm >>0 string x \b, rawbits, pixmap !:strength + 45 !:mime image/x-portable-pixmap 0 string P7 Netpbm PAM image file !:mime image/x-portable-pixmap # From: bryanh@giraffe-data.com (Bryan Henderson) 0 string \117\072 Solitaire Image Recorder format >4 string \013 MGI Type 11 >4 string \021 MGI Type 17 0 string .MDA MicroDesign data >21 byte 48 version 2 >21 byte 51 version 3 0 string .MDP MicroDesign page data >21 byte 48 version 2 >21 byte 51 version 3 # NIFF (Navy Interchange File Format, a modification of TIFF) images # [GRR: this *must* go before TIFF] 0 string IIN1 NIFF image data !:mime image/x-niff # Canon RAW version 1 (CRW) files are a type of Canon Image File Format # (CIFF) file. These are apparently all little-endian. # From: Adam Buchbinder # URL: http://www.sno.phy.queensu.ca/~phil/exiftool/canon_raw.html 0 string II\x1a\0\0\0HEAPCCDR Canon CIFF raw image data !:mime image/x-canon-crw >16 leshort x \b, version %d. >14 leshort x \b%d # Canon RAW version 2 (CR2) files are a kind of TIFF with an extra magic # number. Put this above the TIFF test to make sure we detect them. # These are apparently all little-endian. # From: Adam Buchbinder # URL: http://libopenraw.freedesktop.org/wiki/Canon_CR2 0 string II\x2a\0\x10\0\0\0CR Canon CR2 raw image data !:mime image/x-canon-cr2 >10 byte x \b, version %d. >11 byte x \b%d # Tag Image File Format, from Daniel Quinlan (quinlan@yggdrasil.com) # The second word of TIFF files is the TIFF version number, 42, which has # never changed. The TIFF specification recommends testing for it. 0 string MM\x00\x2a TIFF image data, big-endian !:mime image/tiff >(4.L) use \^tiff_ifd 0 string II\x2a\x00 TIFF image data, little-endian !:mime image/tiff >(4.l) use tiff_ifd 0 name tiff_ifd >0 leshort x \b, direntries=%d >2 use tiff_entry 0 name tiff_entry # NewSubFileType >0 leshort 0xfe >>12 use tiff_entry >0 leshort 0x100 >>4 lelong 1 >>>12 use tiff_entry >>>8 leshort x \b, width=%d >0 leshort 0x101 >>4 lelong 1 >>>8 leshort x \b, height=%d >>>12 use tiff_entry >0 leshort 0x102 >>8 leshort x \b, bps=%d >>12 use tiff_entry >0 leshort 0x103 >>4 lelong 1 \b, compression= >>>8 leshort 1 \bnone >>>8 leshort 2 \bhuffman >>>8 leshort 3 \bbi-level group 3 >>>8 leshort 4 \bbi-level group 4 >>>8 leshort 5 \bLZW >>>8 leshort 6 \bJPEG (old) >>>8 leshort 7 \bJPEG >>>8 leshort 8 \bdeflate >>>8 leshort 9 \bJBIG, ITU-T T.85 >>>8 leshort 0xa \bJBIG, ITU-T T.43 >>>8 leshort 0x7ffe \bNeXT RLE 2-bit >>>8 leshort 0x8005 \bPackBits (Macintosh RLE) >>>8 leshort 0x8029 \bThunderscan RLE >>>8 leshort 0x807f \bRasterPadding (CT or MP) >>>8 leshort 0x8080 \bRLE (Line Work) >>>8 leshort 0x8081 \bRLE (High-Res Cont-Tone) >>>8 leshort 0x8082 \bRLE (Binary Line Work) >>>8 leshort 0x80b2 \bDeflate (PKZIP) >>>8 leshort 0x80b3 \bKodak DCS >>>8 leshort 0x8765 \bJBIG >>>8 leshort 0x8798 \bJPEG2000 >>>8 leshort 0x8799 \bNikon NEF Compressed >>>8 default x >>>>8 leshort x \b(unknown 0x%x) >>>12 use tiff_entry >0 leshort 0x106 \b, PhotometricIntepretation= >>8 clear x >>8 leshort 0 \bWhiteIsZero >>8 leshort 1 \bBlackIsZero >>8 leshort 2 \bRGB >>8 leshort 3 \bRGB Palette >>8 leshort 4 \bTransparency Mask >>8 leshort 5 \bCMYK >>8 leshort 6 \bYCbCr >>8 leshort 8 \bCIELab >>8 default x >>>8 leshort x \b(unknown=0x%x) >>12 use tiff_entry # FillOrder >0 leshort 0x10a >>4 lelong 1 >>>12 use tiff_entry # DocumentName >0 leshort 0x10d >>(8.l) string x \b, name=%s >>>12 use tiff_entry # ImageDescription >0 leshort 0x10e >>(8.l) string x \b, description=%s >>>12 use tiff_entry # Make >0 leshort 0x10f >>(8.l) string x \b, manufacturer=%s >>>12 use tiff_entry # Model >0 leshort 0x110 >>(8.l) string x \b, model=%s >>>12 use tiff_entry # StripOffsets >0 leshort 0x111 >>12 use tiff_entry # Orientation >0 leshort 0x112 \b, orientation= >>8 leshort 1 \bupper-left >>8 leshort 3 \blower-right >>8 leshort 6 \bupper-right >>8 leshort 8 \blower-left >>8 leshort 9 \bundefined >>8 default x >>>8 leshort x \b[*%d*] >>12 use tiff_entry # XResolution >0 leshort 0x11a >>8 lelong x \b, xresolution=%d >>12 use tiff_entry # YResolution >0 leshort 0x11b >>8 lelong x \b, yresolution=%d >>12 use tiff_entry # ResolutionUnit >0 leshort 0x128 >>8 leshort x \b, resolutionunit=%d >>12 use tiff_entry # Software >0 leshort 0x131 >>(8.l) string x \b, software=%s >>12 use tiff_entry # Datetime >0 leshort 0x132 >>(8.l) string x \b, datetime=%s >>12 use tiff_entry # HostComputer >0 leshort 0x13c >>(8.l) string x \b, hostcomputer=%s >>12 use tiff_entry # WhitePoint >0 leshort 0x13e >>12 use tiff_entry # PrimaryChromaticities >0 leshort 0x13f >>12 use tiff_entry # YCbCrCoefficients >0 leshort 0x211 >>12 use tiff_entry # YCbCrPositioning >0 leshort 0x213 >>12 use tiff_entry # ReferenceBlackWhite >0 leshort 0x214 >>12 use tiff_entry # Copyright >0 leshort 0x8298 >>(8.l) string x \b, copyright=%s >>12 use tiff_entry # ExifOffset >0 leshort 0x8769 >>12 use tiff_entry # GPS IFD >0 leshort 0x8825 \b, GPS-Data >>12 use tiff_entry #>0 leshort x \b, unknown=0x%x #>>12 use tiff_entry 0 string MM\x00\x2b Big TIFF image data, big-endian !:mime image/tiff 0 string II\x2b\x00 Big TIFF image data, little-endian !:mime image/tiff # PNG [Portable Network Graphics, or "PNG's Not GIF"] images # (Greg Roelofs, newt@uchicago.edu) # (Albert Cahalan, acahalan@cs.uml.edu) # # 137 P N G \r \n ^Z \n [4-byte length] H E A D [HEAD data] [HEAD crc] ... # 0 string \x89PNG\x0d\x0a\x1a\x0a PNG image data !:mime image/png >16 belong x \b, %d x >20 belong x %d, >24 byte x %d-bit >25 byte 0 grayscale, >25 byte 2 \b/color RGB, >25 byte 3 colormap, >25 byte 4 gray+alpha, >25 byte 6 \b/color RGBA, #>26 byte 0 deflate/32K, >28 byte 0 non-interlaced >28 byte 1 interlaced # possible GIF replacements; none yet released! # (Greg Roelofs, newt@uchicago.edu) # # GRR 950115: this was mine ("Zip GIF"): 0 string GIF94z ZIF image (GIF+deflate alpha) !:mime image/x-unknown # # GRR 950115: this is Jeremy Wohl's Free Graphics Format (better): # 0 string FGF95a FGF image (GIF+deflate beta) !:mime image/x-unknown # # GRR 950115: this is Thomas Boutell's Portable Bitmap Format proposal # (best; not yet implemented): # 0 string PBF PBF image (deflate compression) !:mime image/x-unknown # GIF 0 string GIF8 GIF image data !:mime image/gif !:apple 8BIMGIFf >4 string 7a \b, version 8%s, >4 string 9a \b, version 8%s, >6 leshort >0 %d x >8 leshort >0 %d #>10 byte &0x80 color mapped, #>10 byte&0x07 =0x00 2 colors #>10 byte&0x07 =0x01 4 colors #>10 byte&0x07 =0x02 8 colors #>10 byte&0x07 =0x03 16 colors #>10 byte&0x07 =0x04 32 colors #>10 byte&0x07 =0x05 64 colors #>10 byte&0x07 =0x06 128 colors #>10 byte&0x07 =0x07 256 colors # ITC (CMU WM) raster files. It is essentially a byte-reversed Sun raster, # 1 plane, no encoding. 0 string \361\0\100\273 CMU window manager raster image data >4 lelong >0 %d x >8 lelong >0 %d, >12 lelong >0 %d-bit # Magick Image File Format 0 string id=ImageMagick MIFF image data # Artisan 0 long 1123028772 Artisan image data >4 long 1 \b, rectangular 24-bit >4 long 2 \b, rectangular 8-bit with colormap >4 long 3 \b, rectangular 32-bit (24-bit with matte) # FIG (Facility for Interactive Generation of figures), an object-based format 0 search/1 #FIG FIG image text >5 string x \b, version %.3s # PHIGS 0 string ARF_BEGARF PHIGS clear text archive 0 string @(#)SunPHIGS SunPHIGS # version number follows, in the form m.n >40 string SunBin binary >32 string archive archive # GKS (Graphics Kernel System) 0 string GKSM GKS Metafile >24 string SunGKS \b, SunGKS # CGM image files 0 string BEGMF clear text Computer Graphics Metafile # MGR bitmaps (Michael Haardt, u31b3hs@pool.informatik.rwth-aachen.de) 0 string yz MGR bitmap, modern format, 8-bit aligned 0 string zz MGR bitmap, old format, 1-bit deep, 16-bit aligned 0 string xz MGR bitmap, old format, 1-bit deep, 32-bit aligned 0 string yx MGR bitmap, modern format, squeezed # Fuzzy Bitmap (FBM) images 0 string %bitmap\0 FBM image data >30 long 0x31 \b, mono >30 long 0x33 \b, color # facsimile data 1 string PC\ Research,\ Inc group 3 fax data >29 byte 0 \b, normal resolution (204x98 DPI) >29 byte 1 \b, fine resolution (204x196 DPI) # From: Herbert Rosmanith 0 string Sfff structured fax file # From: Joerg Jenderek # most files with the extension .EPA and some with .BMP 0 string \x11\x06 Award BIOS Logo, 136 x 84 !:mime image/x-award-bioslogo 0 string \x11\x09 Award BIOS Logo, 136 x 126 !:mime image/x-award-bioslogo #0 string \x07\x1f BIOS Logo corrupted? # http://www.blackfiveservices.co.uk/awbmtools.shtml # http://biosgfx.narod.ru/v3/ # http://biosgfx.narod.ru/abr-2/ 0 string AWBM >4 leshort <1981 Award BIOS bitmap !:mime image/x-award-bmp # image width is a multiple of 4 >>4 leshort&0x0003 0 >>>4 leshort x \b, %d >>>6 leshort x x %d >>4 leshort&0x0003 >0 \b, >>>4 leshort&0x0003 =1 >>>>4 leshort x %d+3 >>>4 leshort&0x0003 =2 >>>>4 leshort x %d+2 >>>4 leshort&0x0003 =3 >>>>4 leshort x %d+1 >>>6 leshort x x %d # at offset 8 starts imagedata followed by "RGB " marker # PC bitmaps (OS/2, Windows BMP files) (Greg Roelofs, newt@uchicago.edu) # http://en.wikipedia.org/wiki/BMP_file_format#DIB_header_.\ # 28bitmap_information_header.29 0 string BM >14 leshort 12 PC bitmap, OS/2 1.x format !:mime image/x-ms-bmp >>18 leshort x \b, %d x >>20 leshort x %d >14 leshort 64 PC bitmap, OS/2 2.x format !:mime image/x-ms-bmp >>18 leshort x \b, %d x >>20 leshort x %d >14 leshort 40 PC bitmap, Windows 3.x format !:mime image/x-ms-bmp >>18 lelong x \b, %d x >>22 lelong x %d x >>28 leshort x %d >14 leshort 124 PC bitmap, Windows 98/2000 and newer format !:mime image/x-ms-bmp >>18 lelong x \b, %d x >>22 lelong x %d x >>28 leshort x %d >14 leshort 108 PC bitmap, Windows 95/NT4 and newer format !:mime image/x-ms-bmp >>18 lelong x \b, %d x >>22 lelong x %d x >>28 leshort x %d >14 leshort 128 PC bitmap, Windows NT/2000 format !:mime image/x-ms-bmp >>18 lelong x \b, %d x >>22 lelong x %d x >>28 leshort x %d # Too simple - MPi #0 string IC PC icon data #0 string PI PC pointer image data #0 string CI PC color icon data #0 string CP PC color pointer image data # Conflicts with other entries [BABYL] #0 string BA PC bitmap array data # XPM icons (Greg Roelofs, newt@uchicago.edu) 0 search/1 /*\ XPM\ */ X pixmap image text !:mime image/x-xpmi # Utah Raster Toolkit RLE images (janl@ifi.uio.no) 0 leshort 0xcc52 RLE image data, >6 leshort x %d x >8 leshort x %d >2 leshort >0 \b, lower left corner: %d >4 leshort >0 \b, lower right corner: %d >10 byte&0x1 =0x1 \b, clear first >10 byte&0x2 =0x2 \b, no background >10 byte&0x4 =0x4 \b, alpha channel >10 byte&0x8 =0x8 \b, comment >11 byte >0 \b, %d color channels >12 byte >0 \b, %d bits per pixel >13 byte >0 \b, %d color map channels # image file format (Robert Potter, potter@cs.rochester.edu) 0 string Imagefile\ version- iff image data # this adds the whole header (inc. version number), informative but longish >10 string >\0 %s # Sun raster images, from Daniel Quinlan (quinlan@yggdrasil.com) 0 belong 0x59a66a95 Sun raster image data >4 belong >0 \b, %d x >8 belong >0 %d, >12 belong >0 %d-bit, #>16 belong >0 %d bytes long, >20 belong 0 old format, #>20 belong 1 standard, >20 belong 2 compressed, >20 belong 3 RGB, >20 belong 4 TIFF, >20 belong 5 IFF, >20 belong 0xffff reserved for testing, >24 belong 0 no colormap >24 belong 1 RGB colormap >24 belong 2 raw colormap #>28 belong >0 colormap is %d bytes long # SGI image file format, from Daniel Quinlan (quinlan@yggdrasil.com) # # See # http://reality.sgi.com/grafica/sgiimage.html # 0 beshort 474 SGI image data #>2 byte 0 \b, verbatim >2 byte 1 \b, RLE #>3 byte 1 \b, normal precision >3 byte 2 \b, high precision >4 beshort x \b, %d-D >6 beshort x \b, %d x >8 beshort x %d >10 beshort x \b, %d channel >10 beshort !1 \bs >80 string >0 \b, "%s" 0 string IT01 FIT image data >4 belong x \b, %d x >8 belong x %d x >12 belong x %d # 0 string IT02 FIT image data >4 belong x \b, %d x >8 belong x %d x >12 belong x %d # 2048 string PCD_IPI Kodak Photo CD image pack file >0xe02 byte&0x03 0x00 , landscape mode >0xe02 byte&0x03 0x01 , portrait mode >0xe02 byte&0x03 0x02 , landscape mode >0xe02 byte&0x03 0x03 , portrait mode 0 string PCD_OPA Kodak Photo CD overview pack file # FITS format. Jeff Uphoff # FITS is the Flexible Image Transport System, the de facto standard for # data and image transfer, storage, etc., for the astronomical community. # (FITS floating point formats are big-endian.) 0 string SIMPLE\ \ = FITS image data >109 string 8 \b, 8-bit, character or unsigned binary integer >108 string 16 \b, 16-bit, two's complement binary integer >107 string \ 32 \b, 32-bit, two's complement binary integer >107 string -32 \b, 32-bit, floating point, single precision >107 string -64 \b, 64-bit, floating point, double precision # other images 0 string This\ is\ a\ BitMap\ file Lisp Machine bit-array-file # From SunOS 5.5.1 "/etc/magic" - appeared right before Sun raster image # stuff. # 0 beshort 0x1010 PEX Binary Archive # DICOM medical imaging data 128 string DICM DICOM medical imaging data !:mime application/dicom # XWD - X Window Dump file. # As described in /usr/X11R6/include/X11/XWDFile.h # used by the xwd program. # Bradford Castalia, idaeim, 1/01 # updated by Adam Buchbinder, 2/09 # The following assumes version 7 of the format; the first long is the length # of the header, which is at least 25 4-byte longs, and the one at offset 8 # is a constant which is always either 1 or 2. Offset 12 is the pixmap depth, # which is a maximum of 32. 0 belong >100 >8 belong <3 >>12 belong <33 >>>4 belong 7 XWD X Window Dump image data !:mime image/x-xwindowdump >>>>100 string >\0 \b, "%s" >>>>16 belong x \b, %dx >>>>20 belong x \b%dx >>>>12 belong x \b%d # PDS - Planetary Data System # These files use Parameter Value Language in the header section. # Unfortunately, there is no certain magic, but the following # strings have been found to be most likely. 0 string NJPL1I00 PDS (JPL) image data 2 string NJPL1I PDS (JPL) image data 0 string CCSD3ZF PDS (CCSD) image data 2 string CCSD3Z PDS (CCSD) image data 0 string PDS_ PDS image data 0 string LBLSIZE= PDS (VICAR) image data # pM8x: ATARI STAD compressed bitmap format # # from Oskar Schirmer Feb 2, 2001 # p M 8 5/6 xx yy zz data... # Atari ST STAD bitmap is always 640x400, bytewise runlength compressed. # bytes either run horizontally (pM85) or vertically (pM86). yy is the # most frequent byte, xx and zz are runlength escape codes, where xx is # used for runs of yy. # 0 string pM85 Atari ST STAD bitmap image data (hor) >5 byte 0x00 (white background) >5 byte 0xFF (black background) 0 string pM86 Atari ST STAD bitmap image data (vert) >5 byte 0x00 (white background) >5 byte 0xFF (black background) # Gurkan Sengun , www.linuks.mine.nu # http://www.atarimax.com/jindroush.atari.org/afmtatr.html 0 leshort 0x0296 Atari ATR image # XXX: # This is bad magic 0x5249 == 'RI' conflicts with RIFF and other # magic. # SGI RICE image file #0 beshort 0x5249 RICE image #>2 beshort x v%d #>4 beshort x (%d x #>6 beshort x %d) #>8 beshort 0 8 bit #>8 beshort 1 10 bit #>8 beshort 2 12 bit #>8 beshort 3 13 bit #>10 beshort 0 4:2:2 #>10 beshort 1 4:2:2:4 #>10 beshort 2 4:4:4 #>10 beshort 3 4:4:4:4 #>12 beshort 1 RGB #>12 beshort 2 CCIR601 #>12 beshort 3 RP175 #>12 beshort 4 YUV # PCX image files # From: Dan Fandrich # updated by Joerg Jenderek at Feb 2013 by http://de.wikipedia.org/wiki/PCX # http://web.archive.org/web/20100206055706/http://www.qzx.com/pc-gpe/pcx.txt # GRR: original test was still too general as it catches xbase examples T5.DBT,T6.DBT with 0xa000000 # test for bytes 0x0a,version byte (0,2,3,4,5),compression byte flag(0,1), bit depth (>0) of PCX or T5.DBT,T6.DBT 0 ubelong&0xffF8fe00 0x0a000000 # for PCX bit depth > 0 >3 ubyte >0 # test for valid versions >>1 ubyte <6 >>>1 ubyte !1 PCX !:mime image/x-pcx #!:mime image/pcx >>>>1 ubyte 0 ver. 2.5 image data >>>>1 ubyte 2 ver. 2.8 image data, with palette >>>>1 ubyte 3 ver. 2.8 image data, without palette >>>>1 ubyte 4 for Windows image data >>>>1 ubyte 5 ver. 3.0 image data >>>>4 uleshort x bounding box [%d, >>>>6 uleshort x %d] - >>>>8 uleshort x [%d, >>>>10 uleshort x %d], >>>>65 ubyte >1 %d planes each of >>>>3 ubyte x %d-bit >>>>68 byte 1 colour, >>>>68 byte 2 grayscale, # this should not happen >>>>68 default x image, >>>>12 leshort >0 %d x >>>>>14 uleshort x %d dpi, >>>>2 byte 0 uncompressed >>>>2 byte 1 RLE compressed # Adobe Photoshop # From: Asbjoern Sloth Toennesen 0 string 8BPS Adobe Photoshop Image !:mime image/vnd.adobe.photoshop >4 beshort 2 (PSB) >18 belong x \b, %d x >14 belong x %d, >24 beshort 0 bitmap >24 beshort 1 grayscale >>12 beshort 2 with alpha >24 beshort 2 indexed >24 beshort 3 RGB >>12 beshort 4 \bA >24 beshort 4 CMYK >>12 beshort 5 \bA >24 beshort 7 multichannel >24 beshort 8 duotone >24 beshort 9 lab >12 beshort > 1 >>12 beshort x \b, %dx >12 beshort 1 \b, >22 beshort x %d-bit channel >12 beshort > 1 \bs # XV thumbnail indicator (ThMO) 0 string P7\ 332 XV thumbnail image data # NITF is defined by United States MIL-STD-2500A 0 string NITF National Imagery Transmission Format >25 string >\0 dated %.14s # GEM Image: Version 1, Headerlen 8 (Wolfram Kleff) # Format variations from: Bernd Nuernberger # See http://fileformats.archiveteam.org/wiki/GEM_Raster # For variations, also see: # http://www.seasip.info/Gem/ff_img.html (Ventura) # http://www.atari-wiki.com/?title=IMG_file (XIMG, STTT) # http://www.fileformat.info/format/gemraster/spec/index.htm (XIMG, STTT) # http://sylvana.net/1stguide/1STGUIDE.ENG (TIMG) 0 beshort 0x0001 >2 beshort 0x0008 GEM Image data >>0 use gem_info >2 beshort 0x0009 GEM Image data (Ventura) >>0 use gem_info 16 string XIMG\0 GEM XIMG Image data >0 use gem_info 16 string STTT\0\x10 GEM STTT Image data >0 use gem_info 16 string TIMG\0 GEM TIMG Image data >0 use gem_info 0 name gem_info >12 beshort x %d x >14 beshort x %d, >4 beshort x %d planes, >8 beshort x %d x >10 beshort x %d pixelsize # GEM Metafile (Wolfram Kleff) 0 lelong 0x0018FFFF GEM Metafile data >4 leshort x version %d # # SMJPEG. A custom Motion JPEG format used by Loki Entertainment # Software Torbjorn Andersson . # 0 string \0\nSMJPEG SMJPEG >8 belong x %d.x data # According to the specification you could find any number of _TXT # headers here, but I can't think of any way of handling that. None of # the SMJPEG files I tried it on used this feature. Even if such a # file is encountered the output should still be reasonable. >16 string _SND \b, >>24 beshort >0 %d Hz >>26 byte 8 8-bit >>26 byte 16 16-bit >>28 string NONE uncompressed # >>28 string APCM ADPCM compressed >>27 byte 1 mono >>28 byte 2 stereo # Help! Isn't there any way to avoid writing this part twice? >>32 string _VID \b, # >>>48 string JFIF JPEG >>>40 belong >0 %d frames >>>44 beshort >0 (%d x >>>46 beshort >0 %d) >16 string _VID \b, # >>32 string JFIF JPEG >>24 belong >0 %d frames >>28 beshort >0 (%d x >>30 beshort >0 %d) 0 string Paint\ Shop\ Pro\ Image\ File Paint Shop Pro Image File # "thumbnail file" (icon) # descended from "xv", but in use by other applications as well (Wolfram Kleff) 0 string P7\ 332 XV "thumbnail file" (icon) data # taken from fkiss: ( ?) 0 string KiSS KISS/GS >4 byte 16 color >>5 byte x %d bit >>8 leshort x %d colors >>10 leshort x %d groups >4 byte 32 cell >>5 byte x %d bit >>8 leshort x %d x >>10 leshort x %d >>12 leshort x +%d >>14 leshort x +%d # Webshots (www.webshots.com), by John Harrison 0 string C\253\221g\230\0\0\0 Webshots Desktop .wbz file # Hercules DASD image files # From Jan Jaeger 0 string CKD_P370 Hercules CKD DASD image file >8 long x \b, %d heads per cylinder >12 long x \b, track size %d bytes >16 byte x \b, device type 33%2.2X 0 string CKD_C370 Hercules compressed CKD DASD image file >8 long x \b, %d heads per cylinder >12 long x \b, track size %d bytes >16 byte x \b, device type 33%2.2X 0 string CKD_S370 Hercules CKD DASD shadow file >8 long x \b, %d heads per cylinder >12 long x \b, track size %d bytes >16 byte x \b, device type 33%2.2X # Squeak images and programs - etoffi@softhome.net 0 string \146\031\0\0 Squeak image data 0 search/1 'From\040Squeak Squeak program text # partimage: file(1) magic for PartImage files (experimental, incomplete) # Author: Hans-Joachim Baader 0 string PaRtImAgE-VoLuMe PartImage >0x0020 string 0.6.1 file version %s >>0x0060 lelong >-1 volume %d #>>0x0064 8 byte identifier #>>0x007c reserved >>0x0200 string >\0 type %s >>0x1400 string >\0 device %s, >>0x1600 string >\0 original filename %s, # Some fields omitted >>0x2744 lelong 0 not compressed >>0x2744 lelong 1 gzip compressed >>0x2744 lelong 2 bzip2 compressed >>0x2744 lelong >2 compressed with unknown algorithm >0x0020 string >0.6.1 file version %s >0x0020 string <0.6.1 file version %s # DCX is multi-page PCX, using a simple header of up to 1024 # offsets for the respective PCX components. # From: Joerg Wunsch 0 lelong 987654321 DCX multi-page PCX image data # Simon Walton # Kodak Cineon format for scanned negatives # http://www.kodak.com/US/en/motion/support/dlad/ 0 lelong 0xd75f2a80 Cineon image data >200 belong >0 \b, %d x >204 belong >0 %d # Bio-Rad .PIC is an image format used by microscope control systems # and related image processing software used by biologists. # From: Vebjorn Ljosa # BOOL values are two-byte integers; use them to rule out false positives. # http://web.archive.org/web/20050317223257/www.cs.ubc.ca/spider/ladic/text/biorad.txt # Samples: http://www.loci.wisc.edu/software/sample-data 14 leshort <2 >62 leshort <2 >>54 leshort 12345 Bio-Rad .PIC Image File >>>0 leshort >0 %d x >>>2 leshort >0 %d, >>>4 leshort =1 1 image in file >>>4 leshort >1 %d images in file # From Jan "Yenya" Kasprzak # The description of *.mrw format can be found at # http://www.dalibor.cz/minolta/raw_file_format.htm 0 string \000MRM Minolta Dimage camera raw image data # Summary: DjVu image / document # Extension: .djvu # Reference: http://djvu.org/docs/DjVu3Spec.djvu # Submitted by: Stephane Loeuillet # Modified by (1): Abel Cheung 0 string AT&TFORM >12 string DJVM DjVu multiple page document !:mime image/vnd.djvu >12 string DJVU DjVu image or single page document !:mime image/vnd.djvu >12 string DJVI DjVu shared document !:mime image/vnd.djvu >12 string THUM DjVu page thumbnails !:mime image/vnd.djvu # Originally by Marc Espie # Modified by Robert Minsk # http://www.openexr.com/openexrfilelayout.pdf 0 lelong 20000630 OpenEXR image data, !:mime image/x-exr >4 lelong&0x000000ff x version %d, >4 lelong ^0x00000200 storage: scanline >4 lelong &0x00000200 storage: tiled >8 search/0x1000 compression\0 \b, compression: >>&16 byte 0 none >>&16 byte 1 rle >>&16 byte 2 zips >>&16 byte 3 zip >>&16 byte 4 piz >>&16 byte 5 pxr24 >>&16 byte 6 b44 >>&16 byte 7 b44a >>&16 byte >7 unknown >8 search/0x1000 dataWindow\0 \b, dataWindow: >>&10 lelong x (%d >>&14 lelong x %d)- >>&18 lelong x \b(%d >>&22 lelong x %d) >8 search/0x1000 displayWindow\0 \b, displayWindow: >>&10 lelong x (%d >>&14 lelong x %d)- >>&18 lelong x \b(%d >>&22 lelong x %d) >8 search/0x1000 lineOrder\0 \b, lineOrder: >>&14 byte 0 increasing y >>&14 byte 1 decreasing y >>&14 byte 2 random y >>&14 byte >2 unknown # SMPTE Digital Picture Exchange Format, SMPTE DPX # # ANSI/SMPTE 268M-1994, SMPTE Standard for File Format for Digital # Moving-Picture Exchange (DPX), v1.0, 18 February 1994 # Robert Minsk 0 string SDPX DPX image data, big-endian, !:mime image/x-dpx >768 beshort <4 >>772 belong x %dx >>776 belong x \b%d, >768 beshort >3 >>776 belong x %dx >>772 belong x \b%d, >768 beshort 0 left to right/top to bottom >768 beshort 1 right to left/top to bottom >768 beshort 2 left to right/bottom to top >768 beshort 3 right to left/bottom to top >768 beshort 4 top to bottom/left to right >768 beshort 5 top to bottom/right to left >768 leshort 6 bottom to top/left to right >768 leshort 7 bottom to top/right to left # From: Tom Hilinski # http://www.unidata.ucar.edu/packages/netcdf/ 0 string CDF\001 NetCDF Data Format data #----------------------------------------------------------------------- # Hierarchical Data Format, used to facilitate scientific data exchange # specifications at http://hdf.ncsa.uiuc.edu/ 0 belong 0x0e031301 Hierarchical Data Format (version 4) data !:mime application/x-hdf 0 string \211HDF\r\n\032\n Hierarchical Data Format (version 5) data !:mime application/x-hdf 512 string \211HDF\r\n\032\n Hierarchical Data Format (version 5) with 512 bytes user block !:mime application/x-hdf 1024 string \211HDF\r\n\032\n Hierarchical Data Format (version 5) with 1k user block !:mime application/x-hdf 2048 string \211HDF\r\n\032\n Hierarchical Data Format (version 5) with 2k user block !:mime application/x-hdf 4096 string \211HDF\r\n\032\n Hierarchical Data Format (version 5) with 4k user block !:mime application/x-hdf # From: Tobias Burnus # Xara (for a while: Corel Xara) is a graphic package, see # http://www.xara.com/ for Windows and as GPL application for Linux 0 string XARA\243\243 Xara graphics file # http://www.cartesianinc.com/Tech/ 0 string CPC\262 Cartesian Perceptual Compression image !:mime image/x-cpi # From Albert Cahalan # puredigital used it for the CVS disposable camcorder #8 lelong 4 ZBM bitmap image data #>4 leshort x %u x #>6 leshort x %u # From Albert Cahalan # uncompressed 5:6:5 HighColor image for OLPC XO firmware icons 0 string C565 OLPC firmware icon image data >4 leshort x %u x >6 leshort x %u # Applied Images - Image files from Cytovision # Gustavo Junior Alves 0 string \xce\xda\xde\xfa Cytovision Metaphases file 0 string \xed\xad\xef\xac Cytovision Karyotype file 0 string \x0b\x00\x03\x00 Cytovision FISH Probe file 0 string \xed\xfe\xda\xbe Cytovision FLEX file 0 string \xed\xab\xed\xfe Cytovision FLEX file 0 string \xad\xfd\xea\xad Cytovision RATS file # Wavelet Scalar Quantization format used in gray-scale fingerprint images # From Tano M Fotang 0 string \xff\xa0\xff\xa8\x00 Wavelet Scalar Quantization image data # Type: PCO B16 image files # URL: http://www.pco.de/fileadmin/user_upload/db/download/MA_CWDCOPIE_0412b.pdf # From: Florian Philipp # Extension: .b16 # Description: Pixel image format produced by PCO Camware, typically used # together with PCO cameras. # Note: Different versions exist for e.g. 8 bit and 16 bit images. # Documentation is incomplete. 0 string/b PCO- PCO B16 image data >12 lelong x \b, %dx >16 lelong x \b%d >20 lelong 0 \b, short header >20 lelong -1 \b, extended header >>24 lelong 0 \b, grayscale >>>36 lelong 0 linear LUT >>>36 lelong 1 logarithmic LUT >>>28 lelong x [%d >>>32 lelong x \b,%d] >>24 lelong 1 \b, color >>>64 lelong 0 linear LUT >>>64 lelong 1 logarithmic LUT >>>40 lelong x r[%d >>>44 lelong x \b,%d] >>>48 lelong x g[%d >>>52 lelong x \b,%d] >>>56 lelong x b[%d >>>60 lelong x \b,%d] # Polar Monitor Bitmap (.pmb) used as logo for Polar Electro watches # From: Markus Heidelberg 0 string/t [BitmapInfo2] Polar Monitor Bitmap text !:mime image/x-polar-monitor-bitmap # From: Rick Richardson 0 string GARMIN\ BITMAP\ 01 Garmin Bitmap file # Type: Ulead Photo Explorer5 (.pe5) # URL: http://www.jisyo.com/cgibin/view.cgi?EXT=pe5 (Japanese) # From: Simon Horman 0 string IIO2H Ulead Photo Explorer5 # Type: X11 cursor # URL: http://webcvs.freedesktop.org/mime/shared-mime-info/freedesktop.org.xml.in?view=markup # From: Mathias Brodala 0 string Xcur X11 cursor # Type: Olympus ORF raw images. # URL: http://libopenraw.freedesktop.org/wiki/Olympus_ORF # From: Adam Buchbinder 0 string MMOR Olympus ORF raw image data, big-endian !:mime image/x-olympus-orf 0 string IIRO Olympus ORF raw image data, little-endian !:mime image/x-olympus-orf 0 string IIRS Olympus ORF raw image data, little-endian !:mime image/x-olympus-orf # Type: files used in modern AVCHD camcoders to store clip information # Extension: .cpi # From: Alexander Danilov 0 string HDMV0100 AVCHD Clip Information # From: Adam Buchbinder # URL: http://local.wasp.uwa.edu.au/~pbourke/dataformats/pic/ # Radiance HDR; usually has .pic or .hdr extension. 0 string #?RADIANCE\n Radiance HDR image data #!mime image/vnd.radiance # From: Adam Buchbinder # URL: http://www.mpi-inf.mpg.de/resources/pfstools/pfs_format_spec.pdf # Used by the pfstools packages. The regex matches for the image size could # probably use some work. The MIME type is made up; if there's one in # actual common use, it should replace the one below. 0 string PFS1\x0a PFS HDR image data #!mime image/x-pfs >1 regex [0-9]*\ \b, %s >>1 regex \ [0-9]{4} \bx%s # Type: Foveon X3F # URL: http://www.photofo.com/downloads/x3f-raw-format.pdf # From: Adam Buchbinder # Note that the MIME type isn't defined anywhere that I can find; if # there's a canonical type for this format, it should replace this one. 0 string FOVb Foveon X3F raw image data !:mime image/x-x3f >6 leshort x \b, version %d. >4 leshort x \b%d >28 lelong x \b, %dx >32 lelong x \b%d # Paint.NET file # From Adam Buchbinder 0 string PDN3 Paint.NET image data !:mime image/x-paintnet # Not really an image. # From: "Tano M. Fotang" 0 string \x46\x4d\x52\x00 ISO/IEC 19794-2 Format Minutiae Record (FMR) # doc: http://www.shikino.co.jp/eng/products/images/FLOWER.jpg.zip # example: http://www.shikino.co.jp/eng/products/images/FLOWER.wdp.zip 90 bequad 0x574D50484F544F00 JPEG-XR Image >98 byte&0x08 =0x08 \b, hard tiling >99 byte&0x80 =0x80 \b, tiling present >99 byte&0x40 =0x40 \b, codestream present >99 byte&0x38 x \b, spatial xform= >99 byte&0x38 0x00 \bTL >99 byte&0x38 0x08 \bBL >99 byte&0x38 0x10 \bTR >99 byte&0x38 0x18 \bBR >99 byte&0x38 0x20 \bBT >99 byte&0x38 0x28 \bRB >99 byte&0x38 0x30 \bLT >99 byte&0x38 0x38 \bLB >100 byte&0x80 =0x80 \b, short header >>102 beshort+1 x \b, %d >>104 beshort+1 x \bx%d >100 byte&0x80 =0x00 \b, long header >>102 belong+1 x \b, %x >>106 belong+1 x \bx%x >101 beshort&0xf x \b, bitdepth= >>101 beshort&0xf 0x0 \b1-WHITE=1 >>101 beshort&0xf 0x1 \b8 >>101 beshort&0xf 0x2 \b16 >>101 beshort&0xf 0x3 \b16-SIGNED >>101 beshort&0xf 0x4 \b16-FLOAT >>101 beshort&0xf 0x5 \b(reserved 5) >>101 beshort&0xf 0x6 \b32-SIGNED >>101 beshort&0xf 0x7 \b32-FLOAT >>101 beshort&0xf 0x8 \b5 >>101 beshort&0xf 0x9 \b10 >>101 beshort&0xf 0xa \b5-6-5 >>101 beshort&0xf 0xb \b(reserved %d) >>101 beshort&0xf 0xc \b(reserved %d) >>101 beshort&0xf 0xd \b(reserved %d) >>101 beshort&0xf 0xe \b(reserved %d) >>101 beshort&0xf 0xf \b1-BLACK=1 >101 beshort&0xf0 x \b, colorfmt= >>101 beshort&0xf0 0x00 \bYONLY >>101 beshort&0xf0 0x10 \bYUV240 >>101 beshort&0xf0 0x20 \bYWV422 >>101 beshort&0xf0 0x30 \bYWV444 >>101 beshort&0xf0 0x40 \bCMYK >>101 beshort&0xf0 0x50 \bCMYKDIRECT >>101 beshort&0xf0 0x60 \bNCOMPONENT >>101 beshort&0xf0 0x70 \bRGB >>101 beshort&0xf0 0x80 \bRGBE >>101 beshort&0xf0 >0x80 \b(reserved 0x%x) # From: Johan van der Knijff # # BPG (Better Portable Graphics) format # http://bellard.org/bpg/ # http://fileformats.archiveteam.org/wiki/BPG # 0 string \x42\x50\x47\xFB BPG (Better Portable Graphics) !:mime image/bpg #------------------------------------------------------------------------------ # $File$ # inform: file(1) magic for Inform interactive fiction language # URL: http://www.inform-fiction.org/ # From: Reuben Thomas 0 search/100/cW constant\ story Inform source text #------------------------------------------------------------------------------ # $File: intel,v 1.11 2013/02/06 14:18:52 christos Exp $ # intel: file(1) magic for x86 Unix # # Various flavors of x86 UNIX executable/object (other than Xenix, which # is in "microsoft"). DOS is in "msdos"; the ambitious soul can do # Windows as well. # # Windows NT belongs elsewhere, as you need x86 and MIPS and Alpha and # whatever comes next (HP-PA Hummingbird?). OS/2 may also go elsewhere # as well, if, as, and when IBM makes it portable. # # The `versions' should be un-commented if they work for you. # (Was the problem just one of endianness?) # 0 leshort 0502 basic-16 executable >12 lelong >0 not stripped #>22 leshort >0 - version %d 0 leshort 0503 basic-16 executable (TV) >12 lelong >0 not stripped #>22 leshort >0 - version %d 0 leshort 0510 x86 executable >12 lelong >0 not stripped 0 leshort 0511 x86 executable (TV) >12 lelong >0 not stripped 0 leshort =0512 iAPX 286 executable small model (COFF) >12 lelong >0 not stripped #>22 leshort >0 - version %d 0 leshort =0522 iAPX 286 executable large model (COFF) >12 lelong >0 not stripped #>22 leshort >0 - version %d # SGI labeled the next entry as "iAPX 386 executable" --Dan Quinlan 0 leshort =0514 80386 COFF executable >12 lelong >0 not stripped >22 leshort >0 - version %d # rom: file(1) magic for BIOS ROM Extensions found in intel machines # mapped into memory between 0xC0000 and 0xFFFFF # From Gurkan Sengun , www.linuks.mine.nu 0 beshort 0x55AA BIOS (ia32) ROM Ext. >5 string USB USB >7 string LDR UNDI image >30 string IBM IBM comp. Video >26 string Adaptec Adaptec >28 string Adaptec Adaptec >42 string PROMISE Promise >2 byte x (%d*512) # Flash descriptors for Intel SPI flash roms. # From Dr. Jesus 0 lelong 0x0ff0a55a Intel serial flash for ICH/PCH ROM <= 5 or 3400 series A-step 16 lelong 0x0ff0a55a Intel serial flash for PCH ROM #------------------------------------------------------------------------------ # $File$ # interleaf: file(1) magic for InterLeaf TPS: # 0 string =\210OPS Interleaf saved data 0 string =5 string ,\ Version\ = \b, version >>17 string >\0 %.3s #------------------------------------------------------------------------------ # $File$ # island: file(1) magic for IslandWite/IslandDraw, from SunOS 5.5.1 # "/etc/magic": # From: guy@netapp.com (Guy Harris) # 4 string pgscriptver IslandWrite document 13 string DrawFile IslandDraw document #------------------------------------------------------------------------------ # $File$ # ispell: file(1) magic for ispell # # Ispell 3.0 has a magic of 0x9601 and ispell 3.1 has 0x9602. This magic # will match 0x9600 through 0x9603 in *both* little endian and big endian. # (No other current magic entries collide.) # # Updated by Daniel Quinlan (quinlan@yggdrasil.com) # 0 leshort&0xFFFC 0x9600 little endian ispell >0 byte 0 hash file (?), >0 byte 1 3.0 hash file, >0 byte 2 3.1 hash file, >0 byte 3 hash file (?), >2 leshort 0x00 8-bit, no capitalization, 26 flags >2 leshort 0x01 7-bit, no capitalization, 26 flags >2 leshort 0x02 8-bit, capitalization, 26 flags >2 leshort 0x03 7-bit, capitalization, 26 flags >2 leshort 0x04 8-bit, no capitalization, 52 flags >2 leshort 0x05 7-bit, no capitalization, 52 flags >2 leshort 0x06 8-bit, capitalization, 52 flags >2 leshort 0x07 7-bit, capitalization, 52 flags >2 leshort 0x08 8-bit, no capitalization, 128 flags >2 leshort 0x09 7-bit, no capitalization, 128 flags >2 leshort 0x0A 8-bit, capitalization, 128 flags >2 leshort 0x0B 7-bit, capitalization, 128 flags >2 leshort 0x0C 8-bit, no capitalization, 256 flags >2 leshort 0x0D 7-bit, no capitalization, 256 flags >2 leshort 0x0E 8-bit, capitalization, 256 flags >2 leshort 0x0F 7-bit, capitalization, 256 flags >4 leshort >0 and %d string characters 0 beshort&0xFFFC 0x9600 big endian ispell >1 byte 0 hash file (?), >1 byte 1 3.0 hash file, >1 byte 2 3.1 hash file, >1 byte 3 hash file (?), >2 beshort 0x00 8-bit, no capitalization, 26 flags >2 beshort 0x01 7-bit, no capitalization, 26 flags >2 beshort 0x02 8-bit, capitalization, 26 flags >2 beshort 0x03 7-bit, capitalization, 26 flags >2 beshort 0x04 8-bit, no capitalization, 52 flags >2 beshort 0x05 7-bit, no capitalization, 52 flags >2 beshort 0x06 8-bit, capitalization, 52 flags >2 beshort 0x07 7-bit, capitalization, 52 flags >2 beshort 0x08 8-bit, no capitalization, 128 flags >2 beshort 0x09 7-bit, no capitalization, 128 flags >2 beshort 0x0A 8-bit, capitalization, 128 flags >2 beshort 0x0B 7-bit, capitalization, 128 flags >2 beshort 0x0C 8-bit, no capitalization, 256 flags >2 beshort 0x0D 7-bit, no capitalization, 256 flags >2 beshort 0x0E 8-bit, capitalization, 256 flags >2 beshort 0x0F 7-bit, capitalization, 256 flags >4 beshort >0 and %d string characters # ispell 4.0 hash files kromJx # Ispell 4.0 0 string ISPL ispell >4 long x hash file version %d, >8 long x lexletters %d, >12 long x lexsize %d, >16 long x hashsize %d, >20 long x stblsize %d #------------------------------------------------------------------------------ # $File: isz,v 1.2 2014/04/28 12:04:50 christos Exp $ # ISO Zipped file format # http://www.ezbsystems.com/isz/iszspec.txt 0 string IsZ! ISO Zipped file >4 byte x \b, header size %u >5 byte x \b, version %u >8 lelong x \b, serial %u #12 leshort x \b, sector size %u #>16 lelong x \b, total sectors %u >17 byte >0 \b, password protected #>24 lequad x \b, segment size %llu #>32 lelong x \b, blocks %u #>36 lelong x \b, block size %u #------------------------------------------------------------ # $File: java,v 1.15 2013/08/14 09:10:36 christos Exp $ # Java ByteCode and Mach-O binaries (e.g., Mac OS X) use the # same magic number, 0xcafebabe, so they are both handled # in the entry called "cafebabe". #------------------------------------------------------------ # Java serialization # From Martin Pool (m.pool@pharos.com.au) 0 beshort 0xaced Java serialization data >2 beshort >0x0004 \b, version %d 0 belong 0xfeedfeed Java KeyStore !:mime application/x-java-keystore 0 belong 0xcececece Java JCE KeyStore !:mime application/x-java-jce-keystore # Java source 0 regex ^import.*;$ Java source !:mime text/x-java #------------------------------------------------------------------------------ # $File: $ # javascript: magic for javascript and node.js scripts. # 0 search/1/w #!/bin/node Node.js script text executable !:mime application/javascript 0 search/1/w #!/usr/bin/node Node.js script text executable !:mime application/javascript 0 search/1/w #!/bin/nodejs Node.js script text executable !:mime application/javascript 0 search/1/w #!/usr/bin/nodejs Node.js script text executable !:mime application/javascript 0 search/1 #!/usr/bin/env\ node Node.js script text executable !:mime application/javascript 0 search/1 #!/usr/bin/env\ nodejs Node.js script text executable !:mime application/javascript #------------------------------------------------------------------------------ # $File: jpeg,v 1.26 2015/01/02 22:40:27 christos Exp $ # JPEG images # SunOS 5.5.1 had # # 0 string \377\330\377\340 JPEG file # 0 string \377\330\377\356 JPG file # # both of which turn into "JPEG image data" here. # 0 beshort 0xffd8 JPEG image data !:mime image/jpeg !:apple 8BIMJPEG !:strength *3 >6 string JFIF \b, JFIF standard # The following added by Erik Rossen 1999-09-06 # in a vain attempt to add image size reporting for JFIF. Note that these # tests are not fool-proof since some perfectly valid JPEGs are currently # impossible to specify in magic(4) format. # First, a little JFIF version info: >>11 byte x \b %d. >>12 byte x \b%02d # Next, the resolution or aspect ratio of the image: >>13 byte 0 \b, aspect ratio >>13 byte 1 \b, resolution (DPI) >>13 byte 2 \b, resolution (DPCM) >>14 beshort x \b, density %dx >>16 beshort x \b%d >>4 beshort x \b, segment length %d # Next, show thumbnail info, if it exists: >>18 byte !0 \b, thumbnail %dx >>>19 byte x \b%d >6 string Exif \b, Exif standard: [ >>12 indirect/r x >>12 string x \b] # Jump to the first segment >(4.S+4) use jpeg_segment # This uses recursion... 0 name jpeg_segment >0 beshort 0xFFFE # Recursion handled by FFE0 #>>(2.S+2) use jpeg_segment >>2 pstring/HJ x \b, comment: "%s" >0 beshort 0xFFC0 >>(2.S+2) use jpeg_segment >>4 byte x \b, baseline, precision %d >>7 beshort x \b, %dx >>5 beshort x \b%d >>9 byte x \b, frames %d >0 beshort 0xFFC1 >>(2.S+2) use jpeg_segment >>4 byte x \b, extended sequential, precision %d >>7 beshort x \b, %dx >>5 beshort x \b%d >>9 byte x \b, frames %d >0 beshort 0xFFC2 >>(2.S+2) use jpeg_segment >>4 byte x \b, progressive, precision %d >>7 beshort x \b, %dx >>5 beshort x \b%d >>9 byte x \b, frames %d # Define Huffman Tables >0 beshort 0xFFC4 >>(2.S+2) use jpeg_segment >0 beshort 0xFFE1 # Recursion handled by FFE0 #>>(2.S+2) use jpeg_segment >>4 string Exif \b, Exif Standard: [ >>>10 indirect/r x >>>10 string x \b] # Application specific markers >0 beshort&0xFFE0 =0xFFE0 >>(2.S+2) use jpeg_segment # DB: Define Quantization tables # DD: Define Restart interval [XXX: wrong here, it is 4 bytes] # D8: Start of image # D9: End of image # Dn: Restart >0 beshort&0xFFD0 =0xFFD0 >>0 beshort&0xFFE0 !0xFFE0 >>>(2.S+2) use jpeg_segment #>0 beshort x unknown 0x%x #>>(2.S+2) use jpeg_segment # HSI is Handmade Software's proprietary JPEG encoding scheme 0 string hsi1 JPEG image data, HSI proprietary # From: David Santinoli 0 string \x00\x00\x00\x0C\x6A\x50\x20\x20\x0D\x0A\x87\x0A JPEG 2000 # From: Johan van der Knijff # Added sub-entries for JP2, JPX, JPM and MJ2 formats; added mimetypes # https://github.com/bitsgalore/jp2kMagic # # Now read value of 'Brand' field, which yields a few possibilities: >20 string \x6a\x70\x32\x20 Part 1 (JP2) !:mime image/jp2 >20 string \x6a\x70\x78\x20 Part 2 (JPX) !:mime image/jpx >20 string \x6a\x70\x6d\x20 Part 6 (JPM) !:mime image/jpm >20 string \x6d\x6a\x70\x32 Part 3 (MJ2) !:mime video/mj2 # Type: JPEG 2000 codesream # From: Mathieu Malaterre 0 belong 0xff4fff51 JPEG 2000 codestream 45 beshort 0xff52 #------------------------------------------------------------------------------ # $File: karma,v 1.6 2009/09/19 16:28:10 christos Exp $ # karma: file(1) magic for Karma data files # # From 0 string KarmaRHD Version Karma Data Structure Version >16 belong x %u #------------------------------------------------------------------------------ # $File: kde,v 1.4 2009/09/19 16:28:10 christos Exp $ # kde: file(1) magic for KDE 0 string/t [KDE\ Desktop\ Entry] KDE desktop entry !:mime application/x-kdelnk 0 string/t #\ KDE\ Config\ File KDE config file !:mime application/x-kdelnk 0 string/t #\ xmcd xmcd database file for kscd !:mime text/x-xmcd #------------------------------------------------------------------------------ # $File: kml,v 1.3 2010/11/25 15:00:12 christos Exp $ # keepass: file(1) magic for KeePass file # # Keepass Password Safe: # * original one: http://keepass.info/ # * *nix port: http://www.keepassx.org/ # * android port: http://code.google.com/p/keepassdroid/ 0 lelong 0x9AA2D903 Keepass password database >4 lelong 0xB54BFB65 1.x KDB >>48 lelong >0 \b, %d groups >>52 lelong >0 \b, %d entries >>8 lelong&0x0f 1 \b, SHA-256 >>8 lelong&0x0f 2 \b, AES >>8 lelong&0x0f 4 \b, RC4 >>8 lelong&0x0f 8 \b, Twofish >>120 lelong >0 \b, %d key transformation rounds >4 lelong 0xB54BFB67 2.x KDBX #------------------------------------------------------------------------------ # $File: map,v 1.1 2014/06/03 18:22:25 christos Exp $ # kerberos: MIT kerberos file binary formats # # This magic entry is for demonstration purposes and could be improved # if the following features were implemented in file: # # Strings inside [[ .. ]] in the descriptions have special meanings and # are not printed. # # - Provide some form of iteration in number of components # [[${counter}=%d]] in the description # then append # [${counter}--] in the offset of the entries # - Provide a way to round the next offset # Add [R:4] after the offset? # - Provide a way to have optional entries # XXX: Syntax: # - Provide a way to "save" entries to print them later. # if the description is [[${name}=%s]], then nothing is # printed and a subsequent entry in the same magic file # can refer to ${name} # - Provide a way to format strings as hex values # # http://www.gnu.org/software/shishi/manual/html_node/\ # The-Keytab-Binary-File-Format.html # 0 name keytab_entry #>0 beshort x \b, size=%d #>2 beshort x \b, components=%d >4 pstring/H x \b, realm=%s >>&0 pstring/H x \b, principal=%s/ >>>&0 pstring/H x \b%s >>>>&0 belong x \b, type=%d >>>>>&0 bedate x \b, date=%s >>>>>>&0 byte x \b, kvno=%u #>>>>>>>&0 pstring/H x #>>>>>>>>&0 belong x #>>>>>>>>>>&0 use keytab_entry 0 belong 0x05020000 Kerberos Keytab file >4 use keytab_entry #------------------------------------------------------------------------------ # $File: kml,v 1.2 2009/09/19 16:28:10 christos Exp $ # Type: Google KML, formerly Keyhole Markup Language # Future development of this format has been handed # over to the Open Geospatial Consortium. # http://www.opengeospatial.org/standards/kml/ # From: Asbjoern Sloth Toennesen 0 string/t \20 search/400 \ xmlns= >>&0 regex ['"]http://earth.google.com/kml Google KML document !:mime application/vnd.google-earth.kml+xml >>>&1 string 2.0' \b, version 2.0 >>>&1 string 2.1' \b, version 2.1 >>>&1 string 2.2' \b, version 2.2 #------------------------------------------------------------------------------ # Type: OpenGIS KML, formerly Keyhole Markup Language # This standard is maintained by the # Open Geospatial Consortium. # http://www.opengeospatial.org/standards/kml/ # From: Asbjoern Sloth Toennesen >>&0 regex ['"]http://www.opengis.net/kml OpenGIS KML document !:mime application/vnd.google-earth.kml+xml >>>&1 string/t 2.2 \b, version 2.2 #------------------------------------------------------------------------------ # Type: Google KML Archive (ZIP based) # http://code.google.com/apis/kml/documentation/kml_tut.html # From: Asbjoern Sloth Toennesen 0 string PK\003\004 >4 byte 0x14 >>30 string doc.kml Compressed Google KML Document, including resources. !:mime application/vnd.google-earth.kmz #------------------------------------------------------------------------------ # $File$ # DEC SRC Virtual Paper: Lectern files # Karl M. Hegbloom 0 string lect DEC SRC Virtual Paper Lectern file #------------------------------------------------------------------------------ # $File$ # lex: file(1) magic for lex # # derived empirically, your offsets may vary! 0 search/100 yyprevious C program text (from lex) >3 search/1 >\0 for %s # C program text from GNU flex, from Daniel Quinlan 0 search/100 generated\ by\ flex C program text (from flex) # lex description file, from Daniel Quinlan 0 search/1 %{ lex description text #------------------------------------------------------------------------------ # $File$ # lif: file(1) magic for lif # # (Daniel Quinlan ) # 0 beshort 0x8000 lif file #------------------------------------------------------------------------------ # $File: linux,v 1.58 2014/08/04 06:21:30 christos Exp $ # linux: file(1) magic for Linux files # # Values for Linux/i386 binaries, from Daniel Quinlan # The following basic Linux magic is useful for reference, but using # "long" magic is a better practice in order to avoid collisions. # # 2 leshort 100 Linux/i386 # >0 leshort 0407 impure executable (OMAGIC) # >0 leshort 0410 pure executable (NMAGIC) # >0 leshort 0413 demand-paged executable (ZMAGIC) # >0 leshort 0314 demand-paged executable (QMAGIC) # 0 lelong 0x00640107 Linux/i386 impure executable (OMAGIC) >16 lelong 0 \b, stripped 0 lelong 0x00640108 Linux/i386 pure executable (NMAGIC) >16 lelong 0 \b, stripped 0 lelong 0x0064010b Linux/i386 demand-paged executable (ZMAGIC) >16 lelong 0 \b, stripped 0 lelong 0x006400cc Linux/i386 demand-paged executable (QMAGIC) >16 lelong 0 \b, stripped # 0 string \007\001\000 Linux/i386 object file >20 lelong >0x1020 \b, DLL library # Linux-8086 stuff: 0 string \01\03\020\04 Linux-8086 impure executable >28 long !0 not stripped 0 string \01\03\040\04 Linux-8086 executable >28 long !0 not stripped # 0 string \243\206\001\0 Linux-8086 object file # 0 string \01\03\020\20 Minix-386 impure executable >28 long !0 not stripped 0 string \01\03\040\20 Minix-386 executable >28 long !0 not stripped 0 string \01\03\04\20 Minix-386 NSYM/GNU executable >28 long !0 not stripped # core dump file, from Bill Reynolds 216 lelong 0421 Linux/i386 core file !:strength / 2 >220 string >\0 of '%s' >200 lelong >0 (signal %d) # # LILO boot/chain loaders, from Daniel Quinlan # this can be overridden by the DOS executable (COM) entry 2 string LILO Linux/i386 LILO boot/chain loader # # Linux make config build file, from Ole Aamot # Updated by Ken Sharp 28 string make\ config Linux make config build file (old) 49 search/70 Kernel\ Configuration Linux make config build file # # PSF fonts, from H. Peter Anvin # Updated by Adam Buchbinder # See: http://www.win.tue.nl/~aeb/linux/kbd/font-formats-1.html 0 leshort 0x0436 Linux/i386 PC Screen Font v1 data, >2 byte&0x01 0 256 characters, >2 byte&0x01 !0 512 characters, >2 byte&0x02 0 no directory, >2 byte&0x02 !0 Unicode directory, >3 byte >0 8x%d 0 string \x72\xb5\x4a\x86\x00\x00 Linux/i386 PC Screen Font v2 data, >16 lelong x %d characters, >12 lelong&0x01 0 no directory, >12 lelong&0x01 !0 Unicode directory, >24 lelong x %d >28 lelong x \bx%d # Linux swap file, from Daniel Quinlan 4086 string SWAP-SPACE Linux/i386 swap file # From: Jeff Bailey # Linux swap file with swsusp1 image, from Jeff Bailey 4076 string SWAPSPACE2S1SUSPEND Linux/i386 swap file (new style) with SWSUSP1 image # From: James Hunt 4076 string SWAPSPACE2LINHIB0001 Linux/i386 swap file (new style) (compressed hibernate) # according to man page of mkswap (8) March 1999 # volume label and UUID Russell Coker # http://etbe.coker.com.au/2008/07/08/label-vs-uuid-vs-device/ 4086 string SWAPSPACE2 Linux/i386 swap file (new style), >0x400 long x version %d (4K pages), >0x404 long x size %d pages, >1052 string \0 no label, >1052 string >\0 LABEL=%s, >0x40c belong x UUID=%08x >0x410 beshort x \b-%04x >0x412 beshort x \b-%04x >0x414 beshort x \b-%04x >0x416 belong x \b-%08x >0x41a beshort x \b%04x # From Daniel Novotny # swap file for PowerPC 65526 string SWAPSPACE2 Linux/ppc swap file 16374 string SWAPSPACE2 Linux/ia64 swap file # # Linux kernel boot images, from Albert Cahalan # and others such as Axel Kohlmeyer # and Nicolas Lichtmaier # All known start with: b8 c0 07 8e d8 b8 00 90 8e c0 b9 00 01 29 f6 29 # Linux kernel boot images (i386 arch) (Wolfram Kleff) 514 string HdrS Linux kernel !:strength + 55 >510 leshort 0xAA55 x86 boot executable >>518 leshort >0x1ff >>>529 byte 0 zImage, >>>529 byte 1 bzImage, >>>526 lelong >0 >>>>(526.s+0x200) string >\0 version %s, >>498 leshort 1 RO-rootFS, >>498 leshort 0 RW-rootFS, >>508 leshort >0 root_dev 0x%X, >>502 leshort >0 swap_dev 0x%X, >>504 leshort >0 RAMdisksize %u KB, >>506 leshort 0xFFFF Normal VGA >>506 leshort 0xFFFE Extended VGA >>506 leshort 0xFFFD Prompt for Videomode >>506 leshort >0 Video mode %d # This also matches new kernels, which were caught above by "HdrS". 0 belong 0xb8c0078e Linux kernel >0x1e3 string Loading version 1.3.79 or older >0x1e9 string Loading from prehistoric times # System.map files - Nicolas Lichtmaier 8 search/1 \ A\ _text Linux kernel symbol map text # LSM entries - Nicolas Lichtmaier 0 search/1 Begin3 Linux Software Map entry text 0 search/1 Begin4 Linux Software Map entry text (new format) # From Matt Zimmerman, enhanced for v3 by Matthew Palmer 0 belong 0x4f4f4f4d User-mode Linux COW file >4 belong <3 \b, version %d >>8 string >\0 \b, backing file %s >4 belong >2 \b, version %d >>32 string >\0 \b, backing file %s ############################################################################ # Linux kernel versions 0 string \xb8\xc0\x07\x8e\xd8\xb8\x00\x90 Linux >497 leshort 0 x86 boot sector >>514 belong 0x8e of a kernel from the dawn of time! >>514 belong 0x908ed8b4 version 0.99-1.1.42 >>514 belong 0x908ed8b8 for memtest86 >497 leshort !0 x86 kernel >>504 leshort >0 RAMdisksize=%u KB >>502 leshort >0 swap=0x%X >>508 leshort >0 root=0x%X >>>498 leshort 1 \b-ro >>>498 leshort 0 \b-rw >>506 leshort 0xFFFF vga=normal >>506 leshort 0xFFFE vga=extended >>506 leshort 0xFFFD vga=ask >>506 leshort >0 vga=%d >>514 belong 0x908ed881 version 1.1.43-1.1.45 >>514 belong 0x15b281cd >>>0xa8e belong 0x55AA5a5a version 1.1.46-1.2.13,1.3.0 >>>0xa99 belong 0x55AA5a5a version 1.3.1,2 >>>0xaa3 belong 0x55AA5a5a version 1.3.3-1.3.30 >>>0xaa6 belong 0x55AA5a5a version 1.3.31-1.3.41 >>>0xb2b belong 0x55AA5a5a version 1.3.42-1.3.45 >>>0xaf7 belong 0x55AA5a5a version 1.3.46-1.3.72 >>514 string HdrS >>>518 leshort >0x1FF >>>>529 byte 0 \b, zImage >>>>529 byte 1 \b, bzImage >>>>(526.s+0x200) string >\0 \b, version %s # Linux boot sector thefts. 0 belong 0xb8c0078e Linux >0x1e6 belong 0x454c4b53 ELKS Kernel >0x1e6 belong !0x454c4b53 style boot sector ############################################################################ # Linux S390 kernel image # Created by: Jan Kaluza 8 string \x02\x00\x00\x18\x60\x00\x00\x50\x02\x00\x00\x68\x60\x00\x00\x50\x40\x40\x40\x40\x40\x40\x40\x40 Linux S390 >0x00010000 search/b/4096 \x00\x0a\x00\x00\x8b\xad\xcc\xcc # 64bit >>&0 string \xc1\x00\xef\xe3\xf0\x68\x00\x00 Z10 64bit kernel >>&0 string \xc1\x00\xef\xc3\x00\x00\x00\x00 Z9-109 64bit kernel >>&0 string \xc0\x00\x20\x00\x00\x00\x00\x00 Z990 64bit kernel >>&0 string \x00\x00\x00\x00\x00\x00\x00\x00 Z900 64bit kernel # 32bit >>&0 string \x81\x00\xc8\x80\x00\x00\x00\x00 Z10 32bit kernel >>&0 string \x81\x00\xc8\x80\x00\x00\x00\x00 Z9-109 32bit kernel >>&0 string \x80\x00\x20\x00\x00\x00\x00\x00 Z990 32bit kernel >>&0 string \x80\x00\x00\x00\x00\x00\x00\x00 Z900 32bit kernel # Linux ARM compressed kernel image # From: Kevin Cernekee 36 lelong 0x016f2818 Linux kernel ARM boot executable zImage (little-endian) 36 belong 0x016f2818 Linux kernel ARM boot executable zImage (big-endian) ############################################################################ # Linux 8086 executable 0 lelong&0xFF0000FF 0xC30000E9 Linux-Dev86 executable, headerless >5 string . >>4 string >\0 \b, libc version %s 0 lelong&0xFF00FFFF 0x4000301 Linux-8086 executable >2 byte&0x01 !0 \b, unmapped zero page >2 byte&0x20 0 \b, impure >2 byte&0x20 !0 >>2 byte&0x10 !0 \b, A_EXEC >2 byte&0x02 !0 \b, A_PAL >2 byte&0x04 !0 \b, A_NSYM >2 byte&0x08 !0 \b, A_STAND >2 byte&0x40 !0 \b, A_PURE >2 byte&0x80 !0 \b, A_TOVLY >28 long !0 \b, not stripped >37 string . >>36 string >\0 \b, libc version %s # 0 lelong&0xFF00FFFF 0x10000301 ld86 I80386 executable # 0 lelong&0xFF00FFFF 0xB000301 ld86 M68K executable # 0 lelong&0xFF00FFFF 0xC000301 ld86 NS16K executable # 0 lelong&0xFF00FFFF 0x17000301 ld86 SPARC executable # SYSLINUX boot logo files (from 'ppmtolss16' sources) # http://www.syslinux.org/wiki/index.php/SYSLINUX#Display_graphic_from_filename: # file extension .lss .16 0 lelong =0x1413f33d SYSLINUX' LSS16 image data # syslinux-4.05/mime/image/x-lss16.xml !:mime image/x-lss16 >4 leshort x \b, width %d >6 leshort x \b, height %d 0 string OOOM User-Mode-Linux's Copy-On-Write disk image >4 belong x version %d # SE Linux policy database # From: Mike Frysinger 0 lelong 0xf97cff8c SE Linux policy >16 lelong x v%d >20 lelong 1 MLS >24 lelong x %d symbols >28 lelong x %d ocons # Linux Logical Volume Manager (LVM) # Emmanuel VARAGNAT # # System ID, UUID and volume group name are 128 bytes long # but they should never be full and initialized with zeros... # # LVM1 # 0x0 string HM\001 LVM1 (Linux Logical Volume Manager), version 1 >0x12c string >\0 , System ID: %s 0x0 string HM\002 LVM1 (Linux Logical Volume Manager), version 2 >0x12c string >\0 , System ID: %s # LVM2 # # It seems that the label header can be in one the four first sector # of the disk... (from _find_labeller in lib/label/label.c of LVM2) # # 0x200 seems to be the common case 0x218 string LVM2\ 001 LVM2 PV (Linux Logical Volume Manager) # read the offset to add to the start of the header, and the header # start in 0x200 >&(&-12.l-0x21) byte x # display UUID in LVM format + display all 32 bytes (instead of max string length: 31) >>&0x0 string >\x2f \b, UUID: %.6s >>&0x6 string >\x2f \b-%.4s >>&0xa string >\x2f \b-%.4s >>&0xe string >\x2f \b-%.4s >>&0x12 string >\x2f \b-%.4s >>&0x16 string >\x2f \b-%.4s >>&0x1a string >\x2f \b-%.6s >>&0x20 lequad x \b, size: %lld 0x018 string LVM2\ 001 LVM2 PV (Linux Logical Volume Manager) >&(&-12.l-0x21) byte x # display UUID in LVM format + display all 32 bytes (instead of max string length: 31) >>&0x0 string >\x2f \b, UUID: %.6s >>&0x6 string >\x2f \b-%.4s >>&0xa string >\x2f \b-%.4s >>&0xe string >\x2f \b-%.4s >>&0x12 string >\x2f \b-%.4s >>&0x16 string >\x2f \b-%.4s >>&0x1a string >\x2f \b-%.6s >>&0x20 lequad x \b, size: %lld 0x418 string LVM2\ 001 LVM2 PV (Linux Logical Volume Manager) >&(&-12.l-0x21) byte x # display UUID in LVM format + display all 32 bytes (instead of max string length: 31) >>&0x0 string >\x2f \b, UUID: %.6s >>&0x6 string >\x2f \b-%.4s >>&0xa string >\x2f \b-%.4s >>&0xe string >\x2f \b-%.4s >>&0x12 string >\x2f \b-%.4s >>&0x16 string >\x2f \b-%.4s >>&0x1a string >\x2f \b-%.6s >>&0x20 lequad x \b, size: %lld 0x618 string LVM2\ 001 LVM2 PV (Linux Logical Volume Manager) >&(&-12.l-0x21) byte x # display UUID in LVM format + display all 32 bytes (instead of max string length: 31) >>&0x0 string >\x2f \b, UUID: %.6s >>&0x6 string >\x2f \b-%.4s >>&0xa string >\x2f \b-%.4s >>&0xe string >\x2f \b-%.4s >>&0x12 string >\x2f \b-%.4s >>&0x16 string >\x2f \b-%.4s >>&0x1a string >\x2f \b-%.6s >>&0x20 lequad x \b, size: %lld # LVM snapshot # from Jason Farrel 0 string SnAp LVM Snapshot (CopyOnWrite store) >4 lelong !0 - valid, >4 lelong 0 - invalid, >8 lelong x version %d, >12 lelong x chunk_size %d # SE Linux policy database 0 lelong 0xf97cff8c SE Linux policy >16 lelong x v%d >20 lelong 1 MLS >24 lelong x %d symbols >28 lelong x %d ocons # LUKS: Linux Unified Key Setup, On-Disk Format, http://luks.endorphin.org/spec # Anthon van der Neut (anthon@mnt.org) 0 string LUKS\xba\xbe LUKS encrypted file, >6 beshort x ver %d >8 string x [%s, >40 string x %s, >72 string x %s] >168 string x UUID: %s # Summary: Xen saved domain file # Created by: Radek Vokal 0 string LinuxGuestRecord Xen saved domain >20 search/256 (name >>&1 string x (name %s) # Type: Xen, the virtual machine monitor # From: Radek Vokal 0 string LinuxGuestRecord Xen saved domain #>2 regex \(name\ [^)]*\) %s >20 search/256 (name (name >>&1 string x %s...) # Systemd journald files # See http://www.freedesktop.org/wiki/Software/systemd/journal-files/. # From: Zbigniew Jedrzejewski-Szmek # check magic 0 string LPKSHHRH # check that state is one of known values >16 ubyte&252 0 # check that each half of three unique id128s is non-zero >>24 ubequad >0 >>>32 ubequad >0 >>>>40 ubequad >0 >>>>>48 ubequad >0 >>>>>>56 ubequad >0 >>>>>>>64 ubequad >0 Journal file !:mime application/octet-stream # provide more info >>>>>>>>184 leqdate 0 empty >>>>>>>>16 ubyte 0 \b, offline >>>>>>>>16 ubyte 1 \b, online >>>>>>>>16 ubyte 2 \b, archived >>>>>>>>8 ulelong&1 1 \b, sealed >>>>>>>>12 ulelong&1 1 \b, compressed # BCache backing and cache devices # From: Gabriel de Perthuis 0x1008 lequad 8 >0x1018 string \xc6\x85\x73\xf6\x4e\x1a\x45\xca\x82\x65\xf5\x7f\x48\xba\x6d\x81 BCache >>0x1010 ulequad 0 cache device >>0x1010 ulequad 1 backing device >>0x1010 ulequad 3 cache device >>0x1010 ulequad 4 backing device >>0x1048 string >0 \b, label "%.32s" >>0x1028 ubelong x \b, uuid %08x >>0x102c ubeshort x \b-%04x >>0x102e ubeshort x \b-%04x >>0x1030 ubeshort x \b-%04x >>0x1032 ubelong x \b-%08x >>0x1036 ubeshort x \b%04x >>0x1038 ubelong x \b, set uuid %08x >>0x103c ubeshort x \b-%04x >>0x103e ubeshort x \b-%04x >>0x1040 ubeshort x \b-%04x >>0x1042 ubelong x \b-%08x >>0x1046 ubeshort x \b%04x # Linux device tree: # File format description can be found in the Linux kernel sources at # Documentation/devicetree/booting-without-of.txt # From Christoph Biedl 0 belong 0xd00dfeed # structure and strings must be within blob >&(8.L) byte x >>&(12.L) byte x >>>20 belong >1 Device Tree Blob version %d >>>>4 belong x \b, size=%d >>>>20 belong >1 >>>>>28 belong x \b, boot CPU=%d >>>>20 belong >2 >>>>>32 belong x \b, string block size=%d >>>>20 belong >16 >>>>>36 belong x \b, DT structure block size=%d # glibc locale archive as defined in glibc locale/locarchive.h 0 lelong 0xde020109 locale archive >24 lelong x %d strings # Summary: Database file for mlocate # Description: A database file as used by mlocate, a fast implementation # of locate/updatedb. It uses merging to reuse the existing # database and avoid rereading most of the filesystem. It's # the default version of locate on Arch Linux (and others). # File path: /var/lib/mlocate/mlocate.db by default (but configurable) # Site: https://fedorahosted.org/mlocate/ # Format docs: http://linux.die.net/man/5/mlocate.db # Type: mlocate database file # URL: https://fedorahosted.org/mlocate/ # From: Wander Nauta 0 string \0mlocate mlocate database >12 byte x \b, version %d >13 byte 1 \b, require visibility >16 string x \b, root %s #------------------------------------------------------------------------------ # $File$ # lisp: file(1) magic for lisp programs # # various lisp types, from Daniel Quinlan (quinlan@yggdrasil.com) # updated by Joerg Jenderek # GRR: This lot is too weak #0 string ;; # windows INF files often begin with semicolon and use CRLF as line end # lisp files are mainly created on unix system with LF as line end #>2 search/4096 !\r Lisp/Scheme program text #>2 search/4096 \r Windows INF file 0 search/4096 (setq\ Lisp/Scheme program text !:mime text/x-lisp 0 search/4096 (defvar\ Lisp/Scheme program text !:mime text/x-lisp 0 search/4096 (defparam\ Lisp/Scheme program text !:mime text/x-lisp 0 search/4096 (defun\ Lisp/Scheme program text !:mime text/x-lisp 0 search/4096 (autoload\ Lisp/Scheme program text !:mime text/x-lisp 0 search/4096 (custom-set-variables\ Lisp/Scheme program text !:mime text/x-lisp # Emacs 18 - this is always correct, but not very magical. 0 string \012( Emacs v18 byte-compiled Lisp data !:mime application/x-elc # Emacs 19+ - ver. recognition added by Ian Springer # Also applies to XEmacs 19+ .elc files; could tell them apart with regexs # - Chris Chittleborough 0 string ;ELC >4 byte >18 >4 byte <32 Emacs/XEmacs v%d byte-compiled Lisp data !:mime application/x-elc # Files produced by CLISP Common Lisp From: Bruno Haible 0 string (SYSTEM::VERSION\040' CLISP byte-compiled Lisp program (pre 2004-03-27) 0 string (|SYSTEM|::|VERSION|\040' CLISP byte-compiled Lisp program text 0 long 0x70768BD2 CLISP memory image data 0 long 0xD28B7670 CLISP memory image data, other endian #.com and .bin for MIT scheme 0 string \372\372\372\372 MIT scheme (library?) # From: David Allouche 0 search/1 \ 0 string llvm LLVM byte-codes, uncompressed 0 string llvc0 LLVM byte-codes, null compression 0 string llvc1 LLVM byte-codes, gzip compression 0 string llvc2 LLVM byte-codes, bzip2 compression 0 lelong 0x0b17c0de LLVM bitcode, wrapper # Are these Mach-O ABI values? They appear to be. >16 lelong 0x01000007 x86_64 >16 lelong 0x00000007 i386 >16 lelong 0x00000012 ppc >16 lelong 0x01000012 ppc64 >16 lelong 0x0000000c arm 0 string BC\xc0\xde LLVM IR bitcode #------------------------------------------------------------------------------ # $File: lua,v 1.5 2009/09/19 16:28:10 christos Exp $ # lua: file(1) magic for Lua scripting language # URL: http://www.lua.org/ # From: Reuben Thomas , Seo Sanghyeon # Lua scripts 0 search/1/w #!\ /usr/bin/lua Lua script text executable !:mime text/x-lua 0 search/1/w #!\ /usr/local/bin/lua Lua script text executable !:mime text/x-lua 0 search/1 #!/usr/bin/env\ lua Lua script text executable !:mime text/x-lua 0 search/1 #!\ /usr/bin/env\ lua Lua script text executable !:mime text/x-lua # Lua bytecode 0 string \033Lua Lua bytecode, >4 byte 0x50 version 5.0 >4 byte 0x51 version 5.1 >4 byte 0x52 version 5.2 #------------------------------------------------------------------------------ # $File$ # luks: file(1) magic for Linux Unified Key Setup # URL: http://luks.endorphin.org/spec # From: Anthon van der Neut 0 string LUKS\xba\xbe LUKS encrypted file, >6 beshort x ver %d >8 string x [%s, >40 string x %s, >72 string x %s] >168 string x UUID: %s #------------------------------------------------------------------------------ # $File$ # make: file(1) magic for M4 scripts # 0 regex \^dnl\ M4 macro processor script text !:mime text/x-m4 #------------------------------------------------------------ # $File: mach,v 1.18 2014/03/29 15:40:34 christos Exp $ # Mach has two magic numbers, 0xcafebabe and 0xfeedface. # Unfortunately the first, cafebabe, is shared with # Java ByteCode, so they are both handled in the file "cafebabe". # The "feedface" ones are handled herein. #------------------------------------------------------------ # if set, it's for the 64-bit version of the architecture # yes, this is separate from the low-order magic number bit # it's also separate from the "64-bit libraries" bit in the # upper 8 bits of the CPU subtype 0 name mach-o-cpu >0 belong&0x01000000 0 # # 32-bit ABIs. # # 1 vax >>0 belong&0x00ffffff 1 >>>4 belong&0x00ffffff 0 vax >>>4 belong&0x00ffffff 1 vax11/780 >>>4 belong&0x00ffffff 2 vax11/785 >>>4 belong&0x00ffffff 3 vax11/750 >>>4 belong&0x00ffffff 4 vax11/730 >>>4 belong&0x00ffffff 5 uvaxI >>>4 belong&0x00ffffff 6 uvaxII >>>4 belong&0x00ffffff 7 vax8200 >>>4 belong&0x00ffffff 8 vax8500 >>>4 belong&0x00ffffff 9 vax8600 >>>4 belong&0x00ffffff 10 vax8650 >>>4 belong&0x00ffffff 11 vax8800 >>>4 belong&0x00ffffff 12 uvaxIII >>>4 belong&0x00ffffff >12 vax subarchitecture=%d >>0 belong&0x00ffffff 2 romp >>0 belong&0x00ffffff 3 architecture=3 >>0 belong&0x00ffffff 4 ns32032 >>0 belong&0x00ffffff 5 ns32332 >>0 belong&0x00ffffff 6 m68k # 7 x86 >>0 belong&0x00ffffff 7 >>>4 belong&0x0000000f 3 i386 >>>4 belong&0x0000000f 4 i486 >>>>4 belong&0x00fffff0 0 >>>>4 belong&0x00fffff0 0x80 \bsx >>>4 belong&0x0000000f 5 i586 >>>4 belong&0x0000000f 6 >>>>4 belong&0x00fffff0 0 p6 >>>>4 belong&0x00fffff0 0x10 pentium_pro >>>>4 belong&0x00fffff0 0x20 pentium_2_m0x20 >>>>4 belong&0x00fffff0 0x30 pentium_2_m3 >>>>4 belong&0x00fffff0 0x40 pentium_2_m0x40 >>>>4 belong&0x00fffff0 0x50 pentium_2_m5 >>>>4 belong&0x00fffff0 >0x50 pentium_2_m0x%x >>>4 belong&0x0000000f 7 celeron >>>>4 belong&0x00fffff0 0x00 \b_m0x%x >>>>4 belong&0x00fffff0 0x10 \b_m0x%x >>>>4 belong&0x00fffff0 0x20 \b_m0x%x >>>>4 belong&0x00fffff0 0x30 \b_m0x%x >>>>4 belong&0x00fffff0 0x40 \b_m0x%x >>>>4 belong&0x00fffff0 0x50 \b_m0x%x >>>>4 belong&0x00fffff0 0x60 >>>>4 belong&0x00fffff0 0x70 \b_mobile >>>>4 belong&0x00fffff0 >0x70 \b_m0x%x >>>4 belong&0x0000000f 8 pentium_3 >>>>4 belong&0x00fffff0 0x00 >>>>4 belong&0x00fffff0 0x10 \b_m >>>>4 belong&0x00fffff0 0x20 \b_xeon >>>>4 belong&0x00fffff0 >0x20 \b_m0x%x >>>4 belong&0x0000000f 9 pentiumM >>>>4 belong&0x00fffff0 0x00 >>>>4 belong&0x00fffff0 >0x00 \b_m0x%x >>>4 belong&0x0000000f 10 pentium_4 >>>>4 belong&0x00fffff0 0x00 >>>>4 belong&0x00fffff0 0x10 \b_m >>>>4 belong&0x00fffff0 >0x10 \b_m0x%x >>>4 belong&0x0000000f 11 itanium >>>>4 belong&0x00fffff0 0x00 >>>>4 belong&0x00fffff0 0x10 \b_2 >>>>4 belong&0x00fffff0 >0x10 \b_m0x%x >>>4 belong&0x0000000f 12 xeon >>>>4 belong&0x00fffff0 0x00 >>>>4 belong&0x00fffff0 0x10 \b_mp >>>>4 belong&0x00fffff0 >0x10 \b_m0x%x >>>4 belong&0x0000000f >12 ia32 family=%d >>>>4 belong&0x00fffff0 0x00 >>>>4 belong&0x00fffff0 >0x00 model=%x >>0 belong&0x00ffffff 8 mips >>>4 belong&0x00ffffff 1 R2300 >>>4 belong&0x00ffffff 2 R2600 >>>4 belong&0x00ffffff 3 R2800 >>>4 belong&0x00ffffff 4 R2000a >>>4 belong&0x00ffffff 5 R2000 >>>4 belong&0x00ffffff 6 R3000a >>>4 belong&0x00ffffff 7 R3000 >>>4 belong&0x00ffffff >7 subarchitecture=%d >>0 belong&0x00ffffff 9 ns32532 >>0 belong&0x00ffffff 10 mc98000 >>0 belong&0x00ffffff 11 hppa >>>4 belong&0x00ffffff 0 7100 >>>4 belong&0x00ffffff 1 7100LC >>>4 belong&0x00ffffff >1 subarchitecture=%d >>0 belong&0x00ffffff 12 arm >>>4 belong&0x00ffffff 0 >>>4 belong&0x00ffffff 1 subarchitecture=%d >>>4 belong&0x00ffffff 2 subarchitecture=%d >>>4 belong&0x00ffffff 3 subarchitecture=%d >>>4 belong&0x00ffffff 4 subarchitecture=%d >>>4 belong&0x00ffffff 5 \b_v4t >>>4 belong&0x00ffffff 6 \b_v6 >>>4 belong&0x00ffffff 7 \b_v5tej >>>4 belong&0x00ffffff 8 \b_xscale >>>4 belong&0x00ffffff 9 \b_v7 >>>4 belong&0x00ffffff 10 \b_v7f >>>4 belong&0x00ffffff 11 subarchitecture=%d >>>4 belong&0x00ffffff 12 \b_v7k >>>4 belong&0x00ffffff >12 subarchitecture=%d # 13 m88k >>0 belong&0x00ffffff 13 >>>4 belong&0x00ffffff 0 mc88000 >>>4 belong&0x00ffffff 1 mc88100 >>>4 belong&0x00ffffff 2 mc88110 >>>4 belong&0x00ffffff >2 mc88000 subarchitecture=%d >>0 belong&0x00ffffff 14 SPARC >>0 belong&0x00ffffff 15 i860g >>0 belong&0x00ffffff 16 alpha >>0 belong&0x00ffffff 17 rs6000 >>0 belong&0x00ffffff 18 ppc >>>4 belong&0x00ffffff 0 >>>4 belong&0x00ffffff 1 \b_601 >>>4 belong&0x00ffffff 2 \b_602 >>>4 belong&0x00ffffff 3 \b_603 >>>4 belong&0x00ffffff 4 \b_603e >>>4 belong&0x00ffffff 5 \b_603ev >>>4 belong&0x00ffffff 6 \b_604 >>>4 belong&0x00ffffff 7 \b_604e >>>4 belong&0x00ffffff 8 \b_620 >>>4 belong&0x00ffffff 9 \b_650 >>>4 belong&0x00ffffff 10 \b_7400 >>>4 belong&0x00ffffff 11 \b_7450 >>>4 belong&0x00ffffff 100 \b_970 >>>4 belong&0x00ffffff >100 subarchitecture=%d >>0 belong&0x00ffffff >18 architecture=%d >0 belong&0x01000000 0x01000000 # # 64-bit ABIs. # >>0 belong&0x00ffffff 0 64-bit architecture=%d >>0 belong&0x00ffffff 1 64-bit architecture=%d >>0 belong&0x00ffffff 2 64-bit architecture=%d >>0 belong&0x00ffffff 3 64-bit architecture=%d >>0 belong&0x00ffffff 4 64-bit architecture=%d >>0 belong&0x00ffffff 5 64-bit architecture=%d >>0 belong&0x00ffffff 6 64-bit architecture=%d >>0 belong&0x00ffffff 7 x86_64 >>>4 belong&0x00ffffff 0 subarchitecture=%d >>>4 belong&0x00ffffff 1 subarchitecture=%d >>>4 belong&0x00ffffff 2 subarchitecture=%d >>>4 belong&0x00ffffff 3 >>>4 belong&0x00ffffff 4 \b_arch1 >>>4 belong&0x00ffffff >4 subarchitecture=%d >>0 belong&0x00ffffff 8 64-bit architecture=%d >>0 belong&0x00ffffff 9 64-bit architecture=%d >>0 belong&0x00ffffff 10 64-bit architecture=%d >>0 belong&0x00ffffff 11 64-bit architecture=%d >>0 belong&0x00ffffff 12 64-bit architecture=%d >>0 belong&0x00ffffff 13 64-bit architecture=%d >>0 belong&0x00ffffff 14 64-bit architecture=%d >>0 belong&0x00ffffff 15 64-bit architecture=%d >>0 belong&0x00ffffff 16 64-bit architecture=%d >>0 belong&0x00ffffff 17 64-bit architecture=%d >>0 belong&0x00ffffff 18 ppc64 >>>4 belong&0x00ffffff 0 >>>4 belong&0x00ffffff 1 \b_601 >>>4 belong&0x00ffffff 2 \b_602 >>>4 belong&0x00ffffff 3 \b_603 >>>4 belong&0x00ffffff 4 \b_603e >>>4 belong&0x00ffffff 5 \b_603ev >>>4 belong&0x00ffffff 6 \b_604 >>>4 belong&0x00ffffff 7 \b_604e >>>4 belong&0x00ffffff 8 \b_620 >>>4 belong&0x00ffffff 9 \b_650 >>>4 belong&0x00ffffff 10 \b_7400 >>>4 belong&0x00ffffff 11 \b_7450 >>>4 belong&0x00ffffff 100 \b_970 >>>4 belong&0x00ffffff >100 subarchitecture=%d >>0 belong&0x00ffffff >18 64-bit architecture=%d 0 name mach-o-be >0 byte 0xcf 64-bit >4 use mach-o-cpu >12 belong 1 object >12 belong 2 executable >12 belong 3 fixed virtual memory shared library >12 belong 4 core >12 belong 5 preload executable >12 belong 6 dynamically linked shared library >12 belong 7 dynamic linker >12 belong 8 bundle >12 belong 9 dynamically linked shared library stub >12 belong 10 dSYM companion file >12 belong 11 kext bundle >12 belong >11 >>12 belong x filetype=%d # 0 lelong&0xfffffffe 0xfeedface Mach-O !:strength +1 >0 use \^mach-o-be 0 belong&0xfffffffe 0xfeedface Mach-O !:strength +1 >0 use mach-o-be #------------------------------------------------------------------------------ # $File: macintosh,v 1.24 2014/08/30 08:34:17 christos Exp $ # macintosh description # # BinHex is the Macintosh ASCII-encoded file format (see also "apple") # Daniel Quinlan, quinlan@yggdrasil.com 11 string must\ be\ converted\ with\ BinHex BinHex binary text !:mime application/mac-binhex40 >41 string x \b, version %.3s # Stuffit archives are the de facto standard of compression for Macintosh # files obtained from most archives. (franklsm@tuns.ca) 0 string SIT! StuffIt Archive (data) !:mime application/x-stuffit !:apple SIT!SIT! >2 string x : %s 0 string SITD StuffIt Deluxe (data) >2 string x : %s 0 string Seg StuffIt Deluxe Segment (data) >2 string x : %s # Newer StuffIt archives (grant@netbsd.org) 0 string StuffIt StuffIt Archive !:mime application/x-stuffit !:apple SIT!SIT! #>162 string >0 : %s # Macintosh Applications and Installation binaries (franklsm@tuns.ca) # GRR: Too weak #0 string APPL Macintosh Application (data) #>2 string x \b: %s # Macintosh System files (franklsm@tuns.ca) # GRR: Too weak #0 string zsys Macintosh System File (data) #0 string FNDR Macintosh Finder (data) #0 string libr Macintosh Library (data) #>2 string x : %s #0 string shlb Macintosh Shared Library (data) #>2 string x : %s #0 string cdev Macintosh Control Panel (data) #>2 string x : %s #0 string INIT Macintosh Extension (data) #>2 string x : %s #0 string FFIL Macintosh Truetype Font (data) #>2 string x : %s #0 string LWFN Macintosh Postscript Font (data) #>2 string x : %s # Additional Macintosh Files (franklsm@tuns.ca) # GRR: Too weak #0 string PACT Macintosh Compact Pro Archive (data) #>2 string x : %s #0 string ttro Macintosh TeachText File (data) #>2 string x : %s #0 string TEXT Macintosh TeachText File (data) #>2 string x : %s #0 string PDF Macintosh PDF File (data) #>2 string x : %s # MacBinary format (Eric Fischer, enf@pobox.com) # # Unfortunately MacBinary doesn't really have a magic number prior # to the MacBinary III format. The checksum is really the way to # do it, but the magic file format isn't up to the challenge. # # 0 byte 0 # 1 byte # filename length # 2 string # filename # 65 string # file type # 69 string # file creator # 73 byte # Finder flags # 74 byte 0 # 75 beshort # vertical posn in window # 77 beshort # horiz posn in window # 79 beshort # window or folder ID # 81 byte # protected? # 82 byte 0 # 83 belong # length of data segment # 87 belong # length of resource segment # 91 belong # file creation date # 95 belong # file modification date # 99 beshort # length of comment after resource # 101 byte # new Finder flags # 102 string mBIN # (only in MacBinary III) # 106 byte # char. code of file name # 107 byte # still more Finder flags # 116 belong # total file length # 120 beshort # length of add'l header # 122 byte 129 # for MacBinary II # 122 byte 130 # for MacBinary III # 123 byte 129 # minimum version that can read fmt # 124 beshort # checksum # # This attempts to use the version numbers as a magic number, requiring # that the first one be 0x80, 0x81, 0x82, or 0x83, and that the second # be 0x81. This works for the files I have, but maybe not for everyone's. # Unfortunately, this magic is quite weak - MPi #122 beshort&0xFCFF 0x8081 Macintosh MacBinary data # MacBinary I doesn't have the version number field at all, but MacBinary II # has been in use since 1987 so I hope there aren't many really old files # floating around that this will miss. The original spec calls for using # the nulls in 0, 74, and 82 as the magic number. # # Another possibility, that would also work for MacBinary I, is to use # the assumption that 65-72 will all be ASCII (0x20-0x7F), that 73 will # have bits 1 (changed), 2 (busy), 3 (bozo), and 6 (invisible) unset, # and that 74 will be 0. So something like # # 71 belong&0x80804EFF 0x00000000 Macintosh MacBinary data # # >73 byte&0x01 0x01 \b, inited # >73 byte&0x02 0x02 \b, changed # >73 byte&0x04 0x04 \b, busy # >73 byte&0x08 0x08 \b, bozo # >73 byte&0x10 0x10 \b, system # >73 byte&0x10 0x20 \b, bundle # >73 byte&0x10 0x40 \b, invisible # >73 byte&0x10 0x80 \b, locked #>65 string x \b, type "%4.4s" #>65 string 8BIM (PhotoShop) #>65 string ALB3 (PageMaker 3) #>65 string ALB4 (PageMaker 4) #>65 string ALT3 (PageMaker 3) #>65 string APPL (application) #>65 string AWWP (AppleWorks word processor) #>65 string CIRC (simulated circuit) #>65 string DRWG (MacDraw) #>65 string EPSF (Encapsulated PostScript) #>65 string FFIL (font suitcase) #>65 string FKEY (function key) #>65 string FNDR (Macintosh Finder) #>65 string GIFf (GIF image) #>65 string Gzip (GNU gzip) #>65 string INIT (system extension) #>65 string LIB\ (library) #>65 string LWFN (PostScript font) #>65 string MSBC (Microsoft BASIC) #>65 string PACT (Compact Pro archive) #>65 string PDF\ (Portable Document Format) #>65 string PICT (picture) #>65 string PNTG (MacPaint picture) #>65 string PREF (preferences) #>65 string PROJ (Think C project) #>65 string QPRJ (Think Pascal project) #>65 string SCFL (Defender scores) #>65 string SCRN (startup screen) #>65 string SITD (StuffIt Deluxe) #>65 string SPn3 (SuperPaint) #>65 string STAK (HyperCard stack) #>65 string Seg\ (StuffIt segment) #>65 string TARF (Unix tar archive) #>65 string TEXT (ASCII) #>65 string TIFF (TIFF image) #>65 string TOVF (Eudora table of contents) #>65 string WDBN (Microsoft Word word processor) #>65 string WORD (MacWrite word processor) #>65 string XLS\ (Microsoft Excel) #>65 string ZIVM (compress (.Z)) #>65 string ZSYS (Pre-System 7 system file) #>65 string acf3 (Aldus FreeHand) #>65 string cdev (control panel) #>65 string dfil (Desk Accessory suitcase) #>65 string libr (library) #>65 string nX^d (WriteNow word processor) #>65 string nX^w (WriteNow dictionary) #>65 string rsrc (resource) #>65 string scbk (Scrapbook) #>65 string shlb (shared library) #>65 string ttro (SimpleText read-only) #>65 string zsys (system file) #>69 string x \b, creator "%4.4s" # Somewhere, Apple has a repository of registered Creator IDs. These are # just the ones that I happened to have files from and was able to identify. #>69 string 8BIM (Adobe Photoshop) #>69 string ALD3 (PageMaker 3) #>69 string ALD4 (PageMaker 4) #>69 string ALFA (Alpha editor) #>69 string APLS (Apple Scanner) #>69 string APSC (Apple Scanner) #>69 string BRKL (Brickles) #>69 string BTFT (BitFont) #>69 string CCL2 (Common Lisp 2) #>69 string CCL\ (Common Lisp) #>69 string CDmo (The Talking Moose) #>69 string CPCT (Compact Pro) #>69 string CSOm (Eudora) #>69 string DMOV (Font/DA Mover) #>69 string DSIM (DigSim) #>69 string EDIT (Macintosh Edit) #>69 string ERIK (Macintosh Finder) #>69 string EXTR (self-extracting archive) #>69 string Gzip (GNU gzip) #>69 string KAHL (Think C) #>69 string LWFU (LaserWriter Utility) #>69 string LZIV (compress) #>69 string MACA (MacWrite) #>69 string MACS (Macintosh operating system) #>69 string MAcK (MacKnowledge terminal emulator) #>69 string MLND (Defender) #>69 string MPNT (MacPaint) #>69 string MSBB (Microsoft BASIC (binary)) #>69 string MSWD (Microsoft Word) #>69 string NCSA (NCSA Telnet) #>69 string PJMM (Think Pascal) #>69 string PSAL (Hunt the Wumpus) #>69 string PSI2 (Apple File Exchange) #>69 string R*ch (BBEdit) #>69 string RMKR (Resource Maker) #>69 string RSED (Resource Editor) #>69 string Rich (BBEdit) #>69 string SIT! (StuffIt) #>69 string SPNT (SuperPaint) #>69 string Unix (NeXT Mac filesystem) #>69 string VIM! (Vim editor) #>69 string WILD (HyperCard) #>69 string XCEL (Microsoft Excel) #>69 string aCa2 (Fontographer) #>69 string aca3 (Aldus FreeHand) #>69 string dosa (Macintosh MS-DOS file system) #>69 string movr (Font/DA Mover) #>69 string nX^n (WriteNow) #>69 string pdos (Apple ProDOS file system) #>69 string scbk (Scrapbook) #>69 string ttxt (SimpleText) #>69 string ufox (Foreign File Access) # Just in case... 102 string mBIN MacBinary III data with surprising version number # sas magic from Bruce Foster (bef@nwu.edu) # #0 string SAS SAS #>8 string x %s 0 string SAS SAS >24 string DATA data file >24 string CATALOG catalog >24 string INDEX data file index >24 string VIEW data view # sas 7+ magic from Reinhold Koch (reinhold.koch@roche.com) # 0x54 string SAS SAS 7+ >0x9C string DATA data file >0x9C string CATALOG catalog >0x9C string INDEX data file index >0x9C string VIEW data view # spss magic for SPSS system and portable files, # from Bruce Foster (bef@nwu.edu). 0 long 0xc1e2c3c9 SPSS Portable File >40 string x %s 0 string $FL2 SPSS System File >24 string x %s 0 string $FL3 SPSS System File >24 string x %s # Macintosh filesystem data # From "Tom N Harris" # Fixed HFS+ and Partition map magic: Ethan Benson # The MacOS epoch begins on 1 Jan 1904 instead of 1 Jan 1970, so these # entries depend on the data arithmetic added after v.35 # There's also some Pascal strings in here, ditto... # The boot block signature, according to IM:Files, is # "for HFS volumes, this field always contains the value 0x4C4B." # But if this is true for MFS or HFS+ volumes, I don't know. # Alternatively, the boot block is supposed to be zeroed if it's # unused, so a simply >0 should suffice. 0x400 beshort 0xD2D7 Macintosh MFS data >0 beshort 0x4C4B (bootable) >0x40a beshort &0x8000 (locked) >0x402 beldate-0x7C25B080 x created: %s, >0x406 beldate-0x7C25B080 >0 last backup: %s, >0x414 belong x block size: %d, >0x412 beshort x number of blocks: %d, >0x424 pstring x volume name: %s # *.hfs updated by Joerg Jenderek # http://en.wikipedia.org/wiki/Hierarchical_File_System # "BD" gives many false positives 0x400 beshort 0x4244 # ftp://ftp.mars.org/pub/hfs/hfsutils-3.2.6.tar.gz/hfsutils-3.2.6/libhfs/apple.h # first block of volume bit map (always 3) >0x40e ubeshort 0x0003 # maximal length of volume name is 27 >>0x424 ubyte <28 Macintosh HFS data #!:mime application/octet-stream # these mime and apple types are not sure !:mime application/x-apple-diskimage #!:apple hfsdINIT #!:apple MACSdisk >>>0 beshort 0x4C4B (bootable) #>>>0 beshort 0x0000 (not bootable) >>>0x40a beshort &0x8000 (locked) >>>0x40a beshort ^0x0100 (mounted) >>>0x40a beshort &0x0200 (spared blocks) >>>0x40a beshort &0x0800 (unclean) >>>0x47C beshort 0x482B (Embedded HFS+ Volume) # http://www.epochconverter.com/ # 0x7C245F00 seconds ~ 2082758400 ~ 01 Jan 2036 00:00:00 ~ 66 years to 1970 # 0x7C25B080 seconds ~ 2082844800 ~ 02 Jan 2036 00:00:00 # construct not working #>>>0x402 beldate-0x7C25B080 x created: %s, #>>>0x406 beldate-0x7C25B080 x last modified: %s, #>>>0x440 beldate-0x7C25B080 >0 last backup: %s, # found block sizes 200h,1200h,2800h >>>0x414 belong x block size: %d, >>>0x412 beshort x number of blocks: %d, >>>0x424 pstring x volume name: %s 0x400 beshort 0x482B Macintosh HFS Extended >&0 beshort x version %d data >0 beshort 0x4C4B (bootable) >0x404 belong ^0x00000100 (mounted) >&2 belong &0x00000200 (spared blocks) >&2 belong &0x00000800 (unclean) >&2 belong &0x00008000 (locked) >&6 string x last mounted by: '%.4s', # really, that should be treated as a belong and we print a string # based on the value. TN1150 only mentions '8.10' for "MacOS 8.1" >&14 beldate-0x7C25B080 x created: %s, # only the creation date is local time, all other timestamps in HFS+ are UTC. >&18 bedate-0x7C25B080 x last modified: %s, >&22 bedate-0x7C25B080 >0 last backup: %s, >&26 bedate-0x7C25B080 >0 last checked: %s, >&38 belong x block size: %d, >&42 belong x number of blocks: %d, >&46 belong x free blocks: %d ## AFAIK, only the signature is different # same as Apple Partition Map # GRR: This magic is too weak, it is just "TS" #0x200 beshort 0x5453 Apple Old Partition data #>0x2 beshort x block size: %d, #>0x230 string x first type: %s, #>0x210 string x name: %s, #>0x254 belong x number of blocks: %d, #>0x400 beshort 0x504D #>>0x430 string x second type: %s, #>>0x410 string x name: %s, #>>0x454 belong x number of blocks: %d, #>>0x800 beshort 0x504D #>>>0x830 string x third type: %s, #>>>0x810 string x name: %s, #>>>0x854 belong x number of blocks: %d, #>>>0xa00 beshort 0x504D #>>>>0xa30 string x fourth type: %s, #>>>>0xa10 string x name: %s, #>>>>0xa54 belong x number of blocks: %d # From: Remi Mommsen 0 string BOMStore Mac OS X bill of materials (BOM) file # From: Adam Buchbinder # URL: http://en.wikipedia.org/wiki/Datafork_TrueType # Derived from the 'fondu' and 'ufond' source code (fondu.sf.net). 'sfnt' is # TrueType; 'POST' is PostScript. 'FONT' and 'NFNT' sometimes appear, but I # don't know what they mean. 0 belong 0x100 >(0x4.L+24) beshort x >>&4 belong 0x73666e74 Mac OSX datafork font, TrueType >>&4 belong 0x464f4e54 Mac OSX datafork font, 'FONT' >>&4 belong 0x4e464e54 Mac OSX datafork font, 'NFNT' >>&4 belong 0x504f5354 Mac OSX datafork font, PostScript #------------------------------------------------------------------------------ # $File: cups,v 1.2 2012/11/02 21:50:29 christos Exp $ # MacOS files # 0 string book\0\0\0\0mark\0\0\0\0 MacOS Alias file #------------------------------------------------------------------------------ # $File: magic,v 1.9 2009/09/19 16:28:10 christos Exp $ # magic: file(1) magic for magic files # 0 string/t #\ Magic magic text file for file(1) cmd 0 lelong 0xF11E041C magic binary file for file(1) cmd >4 lelong x (version %d) (little endian) 0 belong 0xF11E041C magic binary file for file(1) cmd >4 belong x (version %d) (big endian) #------------------------------------------------------------------------------ # $File: mail.news,v 1.21 2012/06/21 01:44:52 christos Exp $ # mail.news: file(1) magic for mail and news # # Unfortunately, saved netnews also has From line added in some news software. #0 string From mail text 0 string/t Relay-Version: old news text !:mime message/rfc822 0 string/t #!\ rnews batched news text !:mime message/rfc822 0 string/t N#!\ rnews mailed, batched news text !:mime message/rfc822 0 string/t Forward\ to mail forwarding text !:mime message/rfc822 0 string/t Pipe\ to mail piping text !:mime message/rfc822 0 string/tc delivered-to: SMTP mail text !:mime message/rfc822 0 string/tc return-path: SMTP mail text !:mime message/rfc822 0 string/t Path: news text !:mime message/news 0 string/t Xref: news text !:mime message/news 0 string/t From: news or mail text !:mime message/rfc822 0 string/t Article saved news text !:mime message/news 0 string/t BABYL Emacs RMAIL text 0 string/t Received: RFC 822 mail text !:mime message/rfc822 0 string/t MIME-Version: MIME entity text #0 string/t Content- MIME entity text # TNEF files... 0 lelong 0x223E9F78 Transport Neutral Encapsulation Format !:mime application/vnd.ms-tnef # From: Kevin Sullivan 0 string *mbx* MBX mail folder # From: Simon Matter 0 string \241\002\213\015skiplist\ file\0\0\0 Cyrus skiplist DB # JAM(mbp) Fidonet message area databases # JHR file 0 string JAM\0 JAM message area header file >12 leshort >0 (%d messages) # Squish Fidonet message area databases # SQD file (requires at least one message in the area) # XXX: Weak magic #256 leshort 0xAFAE4453 Squish message area data file #>4 leshort >0 (%d messages) #0 string \